title: NTLM authentication in Python
body: <p>I'm trying to implement NTLM authentication on IIS (Windows Server 2003) from Windows 7 with python. LAN Manager Authentication Level: Send NTLM response only.<br>
  Client machine and server are in the same domain.<br>
  Domain controller (AD) is on another server (also running Windows Server 2003).</p>
  
  <p>I receive 401.1 - Unauthorized: Access is denied due to invalid credentials.
  Could you please help me find out what is wrong with this code and/or show me the other possible directions to solve this problem (using NTLM or Kerberos)?</p>
  
  <pre><code>import sys, httplib, base64, string
  import urllib2
  import win32api
  import sspi 
  import pywintypes
  import socket
  
  class WindoewNtlmMessageGenerator:
      def __init__(self,user=None):
          import win32api,sspi
          if not user:
              user = win32api.GetUserName()
          self.sspi_client = sspi.ClientAuth("NTLM",user)   
  
      def create_auth_req(self):
          import pywintypes
          output_buffer = None
          error_msg = None
          try:
              error_msg, output_buffer = self.sspi_client.authorize(None)            
          except pywintypes.error:
              return None
          auth_req = output_buffer[0].Buffer
          auth_req = base64.encodestring(auth_req)
          auth_req = string.replace(auth_req,'\012','')
          return auth_req 
  
      def create_challenge_response(self,challenge):
          import pywintypes
          output_buffer = None
          input_buffer = challenge
          error_msg = None        
          try:
              error_msg, output_buffer = self.sspi_client.authorize(input_buffer)
          except pywintypes.error:
              return None
          response_msg = output_buffer[0].Buffer       
          response_msg = base64.encodestring(response_msg)
          response_msg = string.replace(response_msg,'\012','')
          return response_msg 
  
  
  fname='request.xml'
  request = file(fname).read()
  ip_host = '10.0.3.112'
  
  ntlm_gen = WindoewNtlmMessageGenerator()
  auth_req_msg = ntlm_gen.create_auth_req()
  auth_req_msg_dec = base64.decodestring(auth_req_msg)
  auth_req_msg = string.replace(auth_req_msg,'\012','')
  webservice = httplib.HTTPConnection(ip_host) 
  webservice.putrequest("POST", "/idc/idcplg")
  webservice.putheader("Content-length", "%d" % len(request)) 
  webservice.putheader('Authorization', 'NTLM'+' '+auth_req_msg) 
  webservice.endheaders()
  resp = webservice.getresponse()
  resp.read()
  
  challenge = resp.msg.get('WWW-Authenticate')
  challenge_dec = base64.decodestring(challenge.split()[1])
  
  msg3 = ntlm_gen.create_challenge_response(challenge_dec)
  webservice = httplib.HTTP(ip_host) 
  webservice.putrequest("POST", "/idc/idcplg?IdcService=LOGIN&amp;Auth=Intranet")
  webservice.putheader("Host", SHOD)
  webservice.putheader("Content-length", "%d" % len(request))
  webservice.putheader('Authorization', 'NTLM'+' '+msg3) 
  webservice.putheader("Content-type", "text/xml; charset=\"UTF-8\"")
  webservice.putheader("SOAPAction", "\"\"")
  webservice.endheaders()
  webservice.send(request)
  statuscode, statusmessage, header = webservice.getreply()
  res = webservice.getfile().read()
  res_file = file('result.txt','wb')
  res_file.write(res)
  res_file.close()
  </code></pre>
  
  <p>sspi.py is available here: 
  <a href="https://ironpython.svn.codeplex.com/svn/IronPython_Main/External.LCA_RESTRICTED/Languages/IronPython/27/Lib/site-packages/win32/lib/sspi.py" rel="noreferrer">https://ironpython.svn.codeplex.com/svn/IronPython_Main/External.LCA_RESTRICTED/Languages/IronPython/27/Lib/site-packages/win32/lib/sspi.py</a></p>
  
  <p>Thanks!</p>