WebDAV is supposed to be an XML web service that goes over HTTP/HTTPS. Unfortunately Microsoft can't do anything right. DAV uses several non-standard HTTP methods, like SEARCH, PROPFIND, PROPSET...instead of the standard HTTP GET, POST, and PUT methods.
Microsoft Exchange also has a bit of a quirk called Form-Based Authentication. When you enable Outlook Web Access, this is the only way to authenticate. Without OWA you can use Basic HTTP Authentication which is pretty easy. With OWA you have to do some interesting maneuvering to get your query in. From a theoretical point of view, what you need to do is simple:
- Fake an HTTP Post to the owaauth.dll file.
- Receive the response headers and pull the cookies, store them.
- Send these cookies back to Exchange while making your "special" DAV SEARCH request.
import httplib,urllib2,cookielib,sys,getpass,Cookie
exchserv = raw_input('Exchange server: ')
loginex = raw_input('Enter Exchange Username: ')
passex = getpass.getpass('Enter Exchange Password: ')
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPSHandler(),urllib2.HTTPCookieProcessor(cj))
urllib2.install_opener(opener)
owabody = 'destination=https://'+exchserv+'/exchange/'+loginex+'/&username=main\'+loginex+'&password='+passex
owaheaders = {'Content-Type': 'application/x-www-form-urlencoded',
'Connection': 'Keep-Alive',
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.1.4322)',
'Host': exchserv}
owareq = urllib2.Request('https://'+exchserv+'/exchweb/bin/auth/owaauth.dll',owabody,owaheaders)
owa = urllib2.urlopen(owareq)
conn = httplib.HTTPSConnection(exchserv)
conn.set_debuglevel(99999999999)
#there is nothing I like better than manually constructing HTTP headers.
conn.putrequest('SEARCH','/exchange/'+loginex+'/')
conn.putheader('Content-Type','text/xml')
conn.putheader('Content-Length', len(davapptquery))
stringofdeath = ''
for i in cj:
stringofdeath += i.name+'='+i.value+';'
conn.putheader('Cookie', stringofdeath)
conn.endheaders()
conn.send(davapptquery)
resp = conn.getresponse()
Where davapptquery is an unholy string containing a SQL query wrapped in some XML.
I pretty much suck at python, but this does work. Someone better could probably more easily create a handler for exchange's DAV insanity.
No comments:
Post a Comment