2014-07-22 12 views

답변

1

사용자 이름이 도메인의 일부가 아닌 한 작동합니다. 경우에 따라 Negotiate 대신 ntlm='NTLM'을 전달해야 할 수도 있습니다.

def ntlm_authenticate_message(nonce, username, password): 
    # http://davenport.sourceforge.net/ntlm.html#theLmv2Response 
    import hashlib 
    import hmac 
    import os 
    ntlm_hash = hashlib.new('md4', password.encode('utf-16le')).digest() 
    ntlm_v2 = hmac.new(ntlm_hash, username.upper().encode('utf-16le')).digest() 
    rand = os.urandom(8) 
    lm = hmac.new(ntlm_v2, nonce + rand).digest() + rand 
    return ('NTLMSSP\0\3\0\0\0' + '\x18\0\x18\0\x40\0\0\0' + '\0' * 8 + '\0' * 8 + 
      chr(len(username)) + '\0' + chr(len(username)) + '\0' + '\x58\0\0\0' + 
      '\0' * 8 + '\0' * 8 + '\0' * 4 + lm + username).encode('base64').replace('\n', '') 


def http_ntlm_auth(url, data, headers, username, password, ntlm='Negotiate'): 
    # http://davenport.sourceforge.net/ntlm.html#ntlmHttpAuthentication 
    u = urlparse(url) 
    h = HTTPSConnection(u.netloc) 
    # h.set_debuglevel(1) 
    h.request('GET', u.path, None, {'Authorization': ntlm + ' ' + 'NTLMSSP\0\1\0\0\0\2\0\0\0'.encode('base64')}) # 1 
    resp = h.getresponse() 
    error = resp.read() 
    assert resp.status == 401 and not error, (resp.status, resp.reason, error) 
    nonce = resp.getheader('WWW-Authenticate').split()[1].decode('base64')[24:32] # type 2 
    headers['Authorization'] = ntlm + ' ' + ntlm_authenticate_message(nonce, username, password) # type 3 
    h.request('POST' if data else 'GET', u.path, data, headers) 
    return h.getresponse()