Giter Club home page Giter Club logo

requests-ntlm's Introduction

requests-ntlm

This package allows for HTTP NTLM authentication using the requests library.

Usage

HttpNtlmAuth extends requests AuthBase, so usage is simple:

import requests
from requests_ntlm import HttpNtlmAuth

requests.get("http://ntlm_protected_site.com",auth=HttpNtlmAuth('domain\\username','password'))

HttpNtlmAuth can be used in conjunction with a Session in order to make use of connection pooling. Since NTLM authenticates connections, this is more efficient. Otherwise, each request will go through a new NTLM challenge-response.

import requests
from requests_ntlm import HttpNtlmAuth

session = requests.Session()
session.auth = HttpNtlmAuth('domain\\username','password')
session.get('http://ntlm_protected_site.com')

Installation

pip install requests_ntlm

Requirements

Authors

requests-ntlm's People

Contributors

adrianvollmer avatar alanxz avatar btoews avatar carsonyl avatar clubby789 avatar davidfischer avatar ebnull avatar ecederstrand avatar exvito avatar f30 avatar glisha avatar hickford avatar jborean93 avatar keith-gray-powereng avatar lukasa avatar mastahyeti avatar nitzmahone avatar oliparcol avatar rekcahpassyla avatar sigmavirus24 avatar t-8ch avatar waldyrious avatar zitrax avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

requests-ntlm's Issues

Issue with https and auth

So it's actually a couple of issues. The first one that when I use ntlm auth with https I keep getting 407

so I have:
session.proxies = {'http': 'http://ip:port', 'https': 'https://ip:port'}
session.auth = HttpNtlmAuth('domain\user', 'password', session)

and when I try:
session.get('https://www.google.com') I get:
ConnectionError: HTTPSConnectionPool(host='www.google.com', port=443): Max retries exceeded with url: / (Caused by ProxyError('Cannot connect to proxy.', error('Tunnel connection failed: 407 Unauthorized',)))

I'm pretty sure this is due to the reason explained in here: https://lukasa.co.uk/2013/07/Python_Requests_And_Proxies/
and indeed, if I remove the https entry from the proxy list, I get a 200 response. Now, this only works when I turn the firewall off, otherwise I get:
ConnectionError: ('Connection aborted.', error(10013, 'An attempt was made to access a socket in a way forbidden by its access permissions'))
http is the only way I can get through the ntlm proxy with the firewall on

The real issue is when I try to use auth on a resource. Like I have a cloudant db and I use requests to query it, using session.auth to store the cloudant username and password. But if I want to use nltm auth session.auth is taken up by HttpNtlmAuth for the ntlm proxy so I can't authenticate into cloudant.

I've tried sending the cloudant creds as payload in the session data with no luck and I've looked as best as I could in the requests_ntlm code to see if there's any way of sending the credentials for the resource I'm trying to access, but again no luck.

Incorrect Padding

import requests
from requests_ntlm import HttpNtlmAuth
 requests.get("http://moss.company.com",auth=HttpNtlmAuth('domain\\user_name','removed password'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/site-packages/requests/api.py", line 55, in get
    return request('get', url, **kwargs)
  File "/usr/lib/python2.6/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.6/site-packages/requests/sessions.py", line 383, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.6/site-packages/requests/sessions.py", line 491, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "/usr/lib/python2.6/site-packages/requests/hooks.py", line 41, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
  File "/usr/lib/python2.6/site-packages/requests_ntlm/requests_ntlm.py", line 76, in response_hook
    'Authorization', r, kwargs)
  File "/usr/lib/python2.6/site-packages/requests_ntlm/requests_ntlm.py", line 56, in retry_using_http_NTLM_auth
    ServerChallenge, NegotiateFlags = ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value[5:])
  File "/usr/lib/python2.6/site-packages/ntlm/ntlm.py", line 217, in parse_NTLM_CHALLENGE_MESSAGE
    msg2 = base64.decodestring(msg2)
  File "/usr/lib64/python2.6/base64.py", line 321, in decodestring
    return binascii.a2b_base64(s)
binascii.Error: Incorrect padding

I can run this requests get and get a proper response

requests.get("http://ntlm_protected_site.com",auth=HttpNtlmAuth('domain\\username','password'))
<Response [502]>

as soon as i change the site to the correct one and put in the correct username and password for my domain i get the incorrect padding error.

Here's the installed python info it's python 2.6

argparse (1.1)
Flask (0.10.1)
haufe.sharepoint (0.1.9)
iniparse (0.3.1)
itsdangerous (0.24)
Jinja2 (2.7.2)
kerberos (1.1.1)
MarkupSafe (0.19)
pip (1.5.4)
pycurl (7.19.0)
pygpgme (0.1)
python-ntlm (1.0.1)
requests (2.2.1)
requests-kerberos (0.4)
requests-ntlm (0.0.2.3)
setuptools (3.4.1)
suds (0.4)
urlgrabber (3.9.1)
Werkzeug (0.9.4)
yum-metadata-parser (1.1.2)

Running CentOs 6.5 Minimal

SSPI authentication

I have a requirement for SSPI authentication. Would there be interest in having this added (and is this the right place to add it)? If so, I have an idea how to implement it and a current rough sketch.

file-like objects in PUT requests are consumed too early, resulting in bad content-length

The script below uses a file object (StringIO) as the 'data' argument to a PUT request. When you run this script, your server is likely to tell you that the final request (actually putting the payload) has an incorrect HTTP method. This is because the content-length is set to 5, but the file-like object has already been read (it was included with the first PUT, which was not yet authorized). An incorrect content-length can break the server's http parsing altogether. With IIS you get "The request verb is invalid" because "PUT" plus a few more bytes get consumed, the path ends up getting treated as the verb, and "HTTP/1.1" ends up getting treated as the path.

A hacky way to fix this would be to seek(0) on the request.data before doing the final request. But that would suck for large files (which would still be needlessly sent on the first request). And it would be impossible for dynamically-produced file-like objects that don't support seek().

The better way to fix this would be for requests to offer a pre-send hook where requests-ntlm could alter the request on the way out if it doesn't yet have a NTLM Authorization header. Maybe that could be done today with a transport adapter.

#!/usr/bin/env python

import requests
from StringIO import StringIO

from requests_ntlm import HttpNtlmAuth


username = 'set user here'
password = 'set password here'
domain = 'set domain here'
url = 'https://my.webdav.server/path/to/blah.txt'

auth = HttpNtlmAuth('%s\\%s' % (domain, username), password)

# use an in-memory file so this script can easily be tested elsewhere.
local_file = StringIO('hello')

resp = requests.request(method='put',
                        url=url,
                        data=local_file,
                        auth=auth)

try:
    resp.raise_for_status()
except requests.exceptions.HTTPError as e:
    print resp.content
    raise

Running that script with an IIS server results in output like this:

brent.tubbs veronica tmp $ python davtest.py 
Username: brent.tubbs
Password: 
Windows Domain: YG
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Verb</h2>
<hr><p>HTTP Error 400. The request verb is invalid.</p>
</BODY></HTML>

Traceback (most recent call last):
  File "davtest.py", line 32, in <module>
    resp.raise_for_status()
  File "/Library/Python/2.7/site-packages/requests/models.py", line 773, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request

Edit: more idiomatic StringIO usage.

Retry not working for 401 Unauthorized

I am using requests 1.1.0 and the requests-ntlm library to authenticate to a sharepoint server. I am watching the traffic in ZAP and I can see the request to server and the response showing a 401 Unauthorized along with WWW-Authenticate: NTLM but I do not see the rest of the authentication attempt. Any thoughts.

About multiple independent connections to same host

Hi,

First of all, thanks for sharing the package which works great in a single-connection-at-a-time scenario. :)

I'm in a scenario where I need two (or more) NTLM authenticated independent connections to the same host. These are requests to a REST interface with different URLs, say http://host/url_A?q_A and http://host/url_B?q_B.

My testing shows that these somewhat parallel requests sometimes work and other times get 401s. Following some investigation and digging through the code (both requests-ntlm and requests) I learned that:

  • NTLM authentication is done on a per-connection basis.
  • The auth process is completed after three request/responses on the connection.
  • The currently published code does not ensure the same connection is reused (but pull request #51 does).
  • The underlying requests (urllib3 actually) pool manager only returns connections from the pool on a hostname basis and not on a full-url basis.

This results in connections A (say for http://host/url_A?q_A) and B (for http://host/url_B?q_B) being switched along the three request/responses and, of course, leading to a failure.

If this is correct, would you have any suggestion on how to address my challenge? (I tried to investigate the possibility of providing an alternate pool manager implementation to urllib3 and did not find it... is there any?)

If my understanding is wrong, would you please point out my mistakes?

Thanks in advance for your feedback.

traceback on line 136

hello,

i got the following traceback:
...
r=self.sess.post(url, data=login_data, headers=headers_data)#, proxies=self.proxies)
File "C:\bin\Python27\lib\site-packages\requests\sessions.py", line 518, in post
return self.request('POST', url, data=data, json=json, *_kwargs)
File "C:\bin\Python27\lib\site-packages\requests\sessions.py", line 475, in request
resp = self.send(prep, *_send_kwargs)
File "C:\bin\Python27\lib\site-packages\requests\sessions.py", line 591, in send
r = dispatch_hook('response', hooks, r, *_kwargs)
File "C:\bin\Python27\lib\site-packages\requests\hooks.py", line 31, in dispatch_hook
_hook_data = hook(hook_data, *_kwargs)
File "C:\bin\Python27\lib\site-packages\requests_ntlm\requests_ntlm.py", line 136, in response_hook
kwargs)
TypeError: retry_using_http_NTLM_auth() takes exactly 6 arguments (5 given)

adding
'NTLM',
at the end of line 137 solved the issue for me.

Traceback occurred

For version 0.3.0 traceback occurred (for 0.2.0 works as expected)

Headers:
Status code: 401 Unauthorized
WWW-Authenticate:"Basic realm="data""

  File "/env/lib/python2.7/site-packages/requests/api.py", line 71, in get
    return request('get', url, params=params, **kwargs)
  File "/env/lib/python2.7/site-packages/requests/api.py", line 57, in request
    return session.request(method=method, url=url, **kwargs)
  File "/env/lib/python2.7/site-packages/requests/sessions.py", line 475, in request
    resp = self.send(prep, **send_kwargs)
  File "/env/lib/python2.7/site-packages/requests/sessions.py", line 591, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "/env/lib/python2.7/site-packages/requests/hooks.py", line 31, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
  File "/env/lib/python2.7/site-packages/requests_ntlm/requests_ntlm.py", line 130, in response_hook
    'Authorization', r, auth_type, kwargs)
UnboundLocalError: local variable 'auth_type' referenced before assignment

Special characters in password

Authenticating with a user that has a password with special characters in it ("!" in my case), won't work. The auth will fail.

Package for pip

Please could you package this library for Pip? So it's easy to install

pip install requests-ntlm

This helps users who want to use this library, and developers of applications that rely on this library.

Afterwards, add pip installation instructions to the readme.

401 error

I am authentification against https://east.exch029.serverdata.net/EWS/Exchange.asmx server. I've got 401 error. When I tried with curl --ntlm then I've got 200 response.
What could be different in curl and requests_ntml NTLM protocol realization?
I can give additional information and creadentials if needed.

Something going wrong with authentication

There is some problem when I try to use this module to authenticate. My authentication is rejected and I get a 401 status from my HTTP requests. I tried doing the exact same thing in urllib2 and it worked flawlessly.

I captured the traffic in Wireshark and Wireshark makes it look like the username, hostname, etc are being truncated to one character. This doesn't completely make sense to me, though, since I can see in the raw data panel that the full username, 'opsretrievaluser', is there.
capture

Closing connection is wrong?

requests_ntlm.py line 62 requests the connection to be closed:

62 request.headers["Connection"] = "Close"

I have a hard time seeing why it's correct to request the same connection to be closed that we just worked hard to authenticate. I was getting lots of 401's talking to an Exchange server before removing this line. Any comments?

KeyError: 'proxy-authenticate' - response2 gives real content instead of challenge

TLDR: Response2 gives real content instead of challenge. Not sure if broken proxy or false assumption.

Possibly related with #36

I'm behind evil corporate NTLM proxy. While within session I would request a page (successfully), grab it's content to get form postdata and finally send new request which would end up with this error:

res = s.post(url, data=formdata, stream=True)
File "C:\Python2\lib\site-packages\requests\sessions.py", line 498, in post
return self.request('POST', url, data=data, **kwargs)
File "C:\Python2\lib\site-packages\requests\sessions.py", line 456, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python2\lib\site-packages\requests\sessions.py", line 565, in send
r = dispatch_hook('response', hooks, r, **kwargs)
File "C:\Python2\lib\site-packages\requests\hooks.py", line 41, in dispatch_hook
_hook_data = hook(hook_data, **kwargs)
File "C:\Python2\lib\site-packages\requests_ntlm\requests_ntlm.py", line 126, in response_hook
kwargs)
File "C:\Python2\lib\site-packages\requests_ntlm\requests_ntlm.py", line 91, in retry_using_http_NTLM_auth
auth_header_value = response2.headers[auth_header_field]
File "C:\Python2\lib\site-packages\requests\structures.py", line 77, in __getitem__
return self._store[key.lower()][1]
KeyError: 'proxy-authenticate'

With the help of a friend I digged into it and found out, that request gets 407 response, hook is dispatched and caught by response_hook to call retry_using_http_NTLM_auth(). That function makes assumption that it needs to first send NTLM negotiate message, receives challenge in response2, builds new request with NTLM authenticate and finally gets real content in response3.

Instead of challenge, what I really got in response2 was real content. Response2.header thus did not contain any key 'proxy-authenticate' (auth_header_value) hence the error. I made a dirty but working workaround and changed + added code from line 91:

auth_header_value = response2.headers.get(auth_header_field) 
if not auth_header_value:
    return response2

I'm really unsure why our proxy behaves like this - could be just bad implementation that breaks some NTLM protocol rule (please let me know, if it does, so I can yell at our IT) or just wrong assumption from the author/s. I'm not very good programmer hence why I created issue and not pull request. Hopefully you can dig into this and create better patch (or tell me to yell at our IT instead).

SSL Cert verify option incorrectly handled

Description: When attempting to use requests and requests-ntlm to authenticate to a server with a self-signed certificate, the verify=False kwarg is not honored.

Code: https://gist.github.com/george2/6526922

Expected resuts: The certificate is not verified, and the request goes through.
Actual results: Requests attempts to verify the certificate, fails, and throws an SSLError.

Versions:
python 2.7
python-ntlm 1.0.1
requests_ntlm 0.0.2.3
requests 1.1.0

Additional information:
I added some print statements for debugging to a few of the relevant files, and generated the following information when running example.py.

DEBUG: 'kwargs' {'verify': False, 'allow_redirects': True, 'auth': <requests_ntlm.requests_ntlm.HttpNtlmAuth object at 0x292ff10>} /usr/lib/python2.7/site-packages/requests/api.py
DEBUG: 'verify' False /usr/lib/python2.7/site-packages/requests/adapters.py
DEBUG: 'kwargs' {} /usr/lib/python2.7/site-packages/requests_ntlm-0.0.2.3-py2.7.egg/requests_ntlm/requests_ntlm.py
DEBUG: 'args' {} /usr/lib/python2.7/site-packages/requests_ntlm-0.0.2.3-py2.7.egg/requests_ntlm/requests_ntlm.py
DEBUG: 'verify' True /usr/lib/python2.7/site-packages/requests/adapters.py
Traceback (most recent call last):
  File "example.py", line 34, in <module>
    main(sys.argv)
  File "example.py", line 28, in main
    auth=HttpNtlmAuth('DOMAIN\\%s' % username,'%s' % password))
  File "/usr/lib/python2.7/site-packages/requests/api.py", line 56, in get
    return request('get', url, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 279, in request
    resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
  File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 374, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 220, in send
    r = self.build_response(request, resp)
  File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 113, in build_response
    response = dispatch_hook('response', req.hooks, response)
  File "/usr/lib/python2.7/site-packages/requests/hooks.py", line 39, in dispatch_hook
    _hook_data = hook(hook_data)
  File "/usr/lib/python2.7/site-packages/requests_ntlm-0.0.2.3-py2.7.egg/requests_ntlm/requests_ntlm.py", line 79, in response_hook
    'Authorization', r, kwargs)
  File "/usr/lib/python2.7/site-packages/requests_ntlm-0.0.2.3-py2.7.egg/requests_ntlm/requests_ntlm.py", line 49, in retry_using_http_NTLM_auth
    response2 = self.adapter.send(request, **args_nostream)
  File "/usr/lib/python2.7/site-packages/requests/adapters.py", line 214, in send
    raise SSLError(e)
requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

If the send() function in adapters.py is modified to set verify=False as the default option, example.py works as expected. Somewhere in there, the verify option is getting lost.

TypeError: response_hook() got an unexpected keyword argument 'verify'

Newer versions of requests send additional keyword arguments to response hooks, resulting in this error when I run the README example:

File "example.py", line 4, in <module>
    requests.get("https://mail.example.com/EWS/Exchange.asmx",auth=HttpNtlmAuth('foo','bar'))
  File "/usr/home/erik/.virtualenv/webuntis_api/lib/python2.7/site-packages/requests/api.py", line 55, in get
    return request('get', url, **kwargs)
  File "/usr/home/erik/.virtualenv/webuntis_api/lib/python2.7/site-packages/requests/api.py", line 44, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/home/erik/.virtualenv/webuntis_api/lib/python2.7/site-packages/requests/sessions.py", line 354, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/home/erik/.virtualenv/webuntis_api/lib/python2.7/site-packages/requests/sessions.py", line 465, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "/usr/home/erik/.virtualenv/webuntis_api/lib/python2.7/site-packages/requests/hooks.py", line 41, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
TypeError: response_hook() got an unexpected keyword argument 'verify'

The below patch is a quick fix, but probably the additional keywords should be passed on to the HTTPAdapter.

--- a/requests_ntlm/requests_ntlm.py
+++ b/requests_ntlm/requests_ntlm.py
@@ -56,7 +56,7 @@ class HttpNtlmAuth(AuthBase):
         return response


-    def response_hook(self,r):
+    def response_hook(self,r,**kwargs):

         if r.status_code == 401 and 'ntlm' in r.headers.get('www-authenticate','').lower():
             return self.retry_using_http_NTLM_auth('www-authenticate', 'Authorization', r)

IndexError: list index out of range

Hi!

Installed:
user@note:~> pip freeze
python-ntlm3==1.0.2
requests==2.7.0
requests-ntlm==0.1.0

My company use web-filter "Websense" with proxy connection and I wrote script for NTLM authentication on "websense":

#!/usr/bin/python

import requests
from requests_ntlm import HttpNtlmAuth

ip = x.x.x.x
host = 'hostname'
username = 'domain\user'
password = 'password'
session = requests.Session()
session.auth = HttpNtlmAuth(username,password,session)
session.get('http://x.x.x.x:15880/websense?action=login&hostname='+host+'&persistent=1&domain=DOMAIN&ip='+ip+'&ntlm_sess_sec=1')

But when launch the script I get following error:
user@note:~> ./websense.py
Traceback (most recent call last):
File "./websense.py", line 12, in <module> session.get('http://x.x.x.x:15880/websense?action=login&hostname='+host+'&persistent=1&domain=DOMAIN&ip='+ip+'&ntlm_sess_sec=1')
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 477, in get return self.request('GET', url, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 465, in request resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/site-packages/requests/sessions.py", line 579, in send r = dispatch_hook('response', hooks, r, **kwargs)
File "/usr/lib/python2.7/site-packages/requests/hooks.py", line 41, in dispatch_hook _hook_data = hook(hook_data, **kwargs)
File "/usr/lib/python2.7/site-packages/requests_ntlm/requests_ntlm.py", line 125, in response_hook 'Authorization', r, kwargs)
File "/usr/lib/python2.7/site-packages/requests_ntlm/requests_ntlm.py", line 97, in retry_using_http_NTLM_auth
))[0].strip()
IndexError: list index out of range

Note, when I have installed this configuration:
python-ntlm3==1.0.2
requests==2.2.1
requests-ntlm==0.1.0
it works fine

Support for Strict CbtHardeningLevel

Hi

I am trying to use Ansible with pywinrm to connect to your Windows hosts and have come across an issue with my company's environment. By default all our region's GPO policy's set the CbtHardeningLevel to Strict expect for our development region. Unfortunately python-ntlm3 requests-ntlm and pywinrm do not support this feature making it a no go for me and others that use Windows in our environment.

I've had a very brief play with editing python-ntlm3 to support this going by what I read on a ruby project that has added support for this security feature WinRb/rubyntlm#27 but I am fairly new to Python and this is largely out of my depth. I also don't know if this library is still active and in development.

There is a library by @ianclegg https://github.com/ianclegg/ntlmlib that says supports CBT but the code for this seems to not be fully there (https://github.com/ianclegg/ntlmlib/blob/master/ntlmlib/authentication.py line 181) so I am not sure on the status.

Is there anyone that would be able to help me get this added as I feel like this would be a importance feature for large to enterprise companies to adopt Ansible. I apologise in advanced wiht my lack of skills but I am happy to help out where I can.

Extra Notes:
Channel Binding Tokens Info - https://msdn.microsoft.com/en-us/library/dd639324.aspx

www-authenticate

Hi there, I tried using your library and I am also trying to use your library within a different github project https://github.com/Crypt0s/python-webdav
I get the following error:
File "<corporate_path_here>/python-webdav/requests-ntlm/requests_ntlm/requests_ntlm.py", line 57, in retry_using_http_NTLM_auth
auth_header_value = response2.headers[auth_header_field]
File "<corporate_path_here>/python-webdav/requests/requests/structures.py", line 77, in getitem
return self._store[key.lower()][1]
KeyError: 'www-authenticate'

Any ideas what this error means?

tests

figure out how to do tests

Push new release

The current release available on PyPI doesn't work with the current version of Requests. I'm pretty sure we have the needed fixes in the master branch, so after we resolve #15 I think we should release a new version of this library.

Import error

Attempting to import requests_ntlm on Python 2.7.9 raises a TypeError. This renders the module unusable.

See also this StackOverflow question about a very similar error: http://stackoverflow.com/questions/27660034/python-requests-ntlm-import-error . (The user in that post got a 'long' object is not subscriptable error. I had also experienced that error before updating Python to latest.)

PS C:\Users\lws> python
Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests_ntlm
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\site-packages\requests_ntlm\__init__.py", line 1, in <module>
    from .requests_ntlm import HttpNtlmAuth
  File "C:\Python27\lib\site-packages\requests_ntlm\requests_ntlm.py", line 4, in <module>
    from ntlm3 import ntlm
  File "C:\Python27\lib\site-packages\ntlm3\__init__.py", line 2, in <module>
    from . import HTTPNtlmAuthHandler  # noqa
  File "C:\Python27\lib\site-packages\ntlm3\HTTPNtlmAuthHandler.py", line 20, in <module>
    from . import ntlm
  File "C:\Python27\lib\site-packages\ntlm3\ntlm.py", line 25, in <module>
    from . import des
  File "C:\Python27\lib\site-packages\ntlm3\des.py", line 19, in <module>
    from . import des_c
  File "C:\Python27\lib\site-packages\ntlm3\des_c.py", line 19, in <module>
    from .des_data import des_SPtrans, des_skb
  File "C:\Python27\lib\site-packages\ntlm3\des_data.py", line 25, in <module>
    U32(0x00820200), U32(0x00020000), U32(0x80800000), U32(0x80820200),
  File "C:\Python27\lib\site-packages\ntlm3\U32.py", line 32, in __init__
    value = six.byte2int(value)
  File "C:\Python27\lib\site-packages\six.py", line 625, in byte2int
    return ord(bs[0])
TypeError: 'long' object has no attribute '__getitem__'
>>>

Package versions in use:

PS C:\Users\lws> pip show requests-ntlm requests python-ntlm3 six

---
Name: requests-ntlm
Version: 0.1.0
Location: c:\python27\lib\site-packages
Requires: requests, python-ntlm3

---
Name: requests
Version: 2.5.1
Location: c:\python27\lib\site-packages
Requires:

---
Name: python-ntlm3
Version: 1.0.1
Location: c:\python27\lib\site-packages
Requires: six

---
Name: six
Version: 1.9.0
Location: c:\python27\lib\site-packages
Requires:

Error 401

I have an error 401 when I try to connect to https://xxxxx.fr/ews/exchange.asmx. It works with curl (or pycurl) but not with requests-ntlm. Thank you for your answer!

$ pip freeze | grep requests
requests==2.8.1
requests-ntlm==0.2.0

Curl:

#$DATA contains the xml in the python code
curl -s -u USERNAME:XXXX:XXXX -L https://xxxxx.fr/ews/exchange.asmx -d "$DATA" -H "Content-Type:text/xml" --ntlm

Python:

import requests
from requests_ntlm import HttpNtlmAuth

url = 'https://xxxxx.fr/ews/exchange.asmx'
username = 'DOMAIN.fr\\USERNAME'
password = 'XXXX:XXXX'

headers = {'Content-Type': 'text/xml'}

data = '''<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
               xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
  <soap:Body>
    <ResolveNames xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
                  xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
                  ReturnFullContactData="true">
      <UnresolvedEntry>USERNAME</UnresolvedEntry>
    </ResolveNames>
  </soap:Body>
</soap:Envelope>
'''

response = requests.get(url, data=data, headers=headers, auth=HttpNtlmAuth(username, password))
print response

Python output:

<Response [401]>

TCPdump output:

sudo tcpdump -q
18:04:46.885156 IP home.54023 > xxxxx.fr.https: tcp 0
18:04:46.933064 IP xxxxx.fr.https > home.54023: tcp 0
18:04:46.933192 IP home.54023 > xxxxx.fr.https: tcp 0
18:04:46.946482 IP home.54023 > xxxxx.fr.https: tcp 517
18:04:46.982548 IP xxxxx.fr.https > home.54023: tcp 0
18:04:46.987380 IP xxxxx.fr.https > home.54023: tcp 1440
18:04:46.989147 IP xxxxx.fr.https > home.54023: tcp 1440
18:04:46.989217 IP home.54023 > xxxxx.fr.https: tcp 0
18:04:46.989381 IP ixxxxx.fr.https > home.54023: tcp 1151
18:04:46.989442 IP home.54023 > xxxxx.fr.https: tcp 0
18:04:46.993091 IP home.54023 > xxxxx.fr.https: tcp 214
18:04:47.035220 IP xxxxx.fr.https > home.54023: tcp 107
18:04:47.035350 IP home.54023 > xxxxx.fr.https: tcp 0
18:04:47.035999 IP home.54023 > xxxxx.fr.https: tcp 949
18:04:47.075558 IP xxxxx.fr.https > home.54023: tcp 533
18:04:47.075653 IP home.54023 > xxxxx.fr.https: tcp 0
18:04:47.077615 IP home.54023 > xxxxx.fr.https: tcp 1045
18:04:47.117239 IP xxxxx.fr.https > home.54023: tcp 789
18:04:47.117317 IP home.54023 > xxxxx.fr.https: tcp 0
18:04:47.180575 IP home.54023 > xxxxx.fr.https: tcp 1301
18:04:47.221738 IP xxxxx.fr.https > home.54023: tcp 341
18:04:47.221816 IP home.54023 > xxxxx.fr.https: tcp 0
18:04:47.223726 IP home.54023 > xxxxx.fr.https: tcp 0
18:04:47.260520 IP xxxxx.fr.https > home.54023: tcp 0
18:04:47.260641 IP home.54023 > xxxxx.fr.https: tcp 0

Streaming upload does not work

It seems that streaming upload does not work, most likely because the file is reset only once. This is related to #87, because the data is sent three times.

For example code similar to this snippet does not work, it's always stuck:

session = Session(auth=HttpNtlmAuth(username, password))
with open("blabla.txt") as file:
    session.put(url="https://webdav-server/", data=file, timeout=10)

pip freeze says:

requests==2.11.1
requests-ntlm==1.0.0

requests dependency v1.0.x breaks requests-ntlm

I tried out requests-ntlm today for the first time and got the error below.

My environment:
Python 2.7
requests-ntlm v0.0.1
python-ntlm v1.0.1
requests v1.0.4

Code:

r = requests.get(url, auth=HttpNtlmAuth(user, password))

Traceback:

Traceback (most recent call last):
  File "C:/Users/vye/repos/test/test.py", line 22, in <module>
    r = requests.get(url, auth=HttpNtlmAuth(user, password))
  File "C:\Users\vye\venv\test\lib\site-packages\requests\api.py", line 49, in get
    return request('get', url, **kwargs)
  File "C:\Users\vye\venv\test\lib\site-packages\requests\api.py", line 38, in request
    return session.request(method=method, url=url, **kwargs)
  File "C:\Users\vye\venv\test\lib\site-packages\requests\sessions.py", line 256, in request
    resp = self.send(prep, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies)
  File "C:\Users\vye\venv\test\lib\site-packages\requests\sessions.py", line 347, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\vye\venv\test\lib\site-packages\requests\adapters.py", line 181, in send
    r = self.build_response(request, resp)
  File "C:\Users\vye\venv\test\lib\site-packages\requests\adapters.py", line 121, in build_response
    response = dispatch_hook('response', req.hooks, response)
  File "C:\Users\vye\venv\test\lib\site-packages\requests\hooks.py", line 39, in dispatch_hook
    _hook_data = hook(hook_data)
  File "C:\Users\vye\venv\test\lib\site-packages\requests_ntlm\requests_ntlm.py", line 61, in response_hook
    return self.retry_using_http_NTLM_auth('www-authenticate', 'Authorization', r)
  File "C:\Users\vye\venv\test\lib\site-packages\requests_ntlm\requests_ntlm.py", line 37, in retry_using_http_NTLM_auth
    request.send(anyway=True)
AttributeError: 'PreparedRequest' object has no attribute 'send'

The first thing I did was run your test suite, which showed the same error. I rolled back requests one release at a time running your tests on each one and found that I started getting a different error on v0.14.2. I re-ran the code snippet above and it worked.

What is required to modify requests-ntlm to support the 1.0.x requests tree? Would it make sense to update your requirements.txt file to specify tested versions of the required libraries?

Thanks!

UPN (kerberos-style) usernames and domain

Hi,

I have to connect to a mail server (Exchange) where emails are used as usernames. At the moment HttpNtlmAuth constructor finds @ in my username here and splits it into a domain and username pair.

This was added in @nitzmahone's pull request #68.

In this particular case this is incorrect as domain should be empty. But it may also be incorrect in the general case. According to this, domain should always be empty when username is in kerberos-style format.

It is easy to work around this as I can change domain after HttpNtlmAuth was constructed. But should we add optional domain parameter to the constructor and/or not split usernames?

Regards,
Srdan

λ pip freeze | grep ntlm
ntlm-auth==1.0.2
requests-ntlm==1.0.0

using currently logged in user's credentials?

Is there a way to authenticate with currently logged user's credentials instead of providing login/password directly inside the script?

Thank you for this package, it works beautifully.

pass the hash

Comments in the source code says this supports pass the hash... however, I have had a look through the source code and cannot find this functionality.

Am I missing something?

Traceback occurred

Trying to authenticate to Sharepoint via NTLM, and I'm getting the following Traceback:

Traceback (most recent call last):
File "", line 1, in
File "/Library/Python/2.7/site-packages/requests-2.2.0-py2.7.egg/requests/api.py", line 55, in get
return request('get', url, **kwargs)
File "/Library/Python/2.7/site-packages/requests-2.2.0-py2.7.egg/requests/api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "/Library/Python/2.7/site-packages/requests-2.2.0-py2.7.egg/requests/sessions.py", line 383, in request
resp = self.send(prep, **send_kwargs)
File "/Library/Python/2.7/site-packages/requests-2.2.0-py2.7.egg/requests/sessions.py", line 491, in send
r = dispatch_hook('response', hooks, r, **kwargs)
File "/Library/Python/2.7/site-packages/requests-2.2.0-py2.7.egg/requests/hooks.py", line 41, in dispatch_hook
_hook_data = hook(hook_data, **kwargs)
File "/Library/Python/2.7/site-packages/requests_ntlm/requests_ntlm.py", line 146, in response_hook
kwargs
File "/Library/Python/2.7/site-packages/requests_ntlm/requests_ntlm.py", line 47, in retry_using_http_NTLM_auth
server_certificate_hash = _get_server_cert(response)
File "/Library/Python/2.7/site-packages/requests_ntlm/requests_ntlm.py", line 205, in _get_server_cert
socket = raw_response._fp.fp._sock
AttributeError: 'NoneType' object has no attribute '_sock'

Upload to pypi

Let's upload this to pypi. Everything seems to be in place. If I can help somehow, I'm happy to help.

NTLM auth always returns 401 Unauthorized when using requests-2.3.0

Hi,

I have been using requests-ntlm (post-version 0.0.2.2) in conjunction with requests 2.2.1. Recently I upgraded to requests 2.3.0 and found that NTLM authentication no longer worked; every request was rejected with 401 Unauthorized.

Side-by-side debugging of 2.2.1 vs 2.3.0 yielded the result that this deletion causes a connection not to be put into the pool.

If I add the line

response2.content

right after this line, the requests then return 200 as I expect.

I'm happy to provide debug logs or further details, please let me know what would be most helpful.

Many thanks

v0.0.2 pypi package can't find LICENSE file during setup

Thanks for the effort getting version 0.0.2 out.

The pypi package that was created for this update (v0.0.2) can't find the LICENSE file during setup.

Downloading from URL http://pypi.python.org/packages/source/r/requests_ntlm/requests_ntlm-0.0.2.tar.gz#md5=2ccdd3af381d93f3a6fe4e3b730570c2 (from http://pypi.python.org/simple/requests_ntlm/)
  Running setup.py egg_info for package requests-ntlm

Traceback (most recent call last):
      File "<string>", line 14, in <module>
      File "C:\Users\vye\venv\test\build\requests-ntlm\setup.py", line 6, in <module>
        with open('LICENSE','r') as f:
    IOError: [Errno 2] No such file or directory: 'LICENSE'
    Complete output from command python setup.py egg_info:

    Traceback (most recent call last):
  File "<string>", line 14, in <module>
  File "C:\Users\vye\venv\test\build\requests-ntlm\setup.py", line 6, in <module>
    with open('LICENSE','r') as f:
IOError: [Errno 2] No such file or directory: 'LICENSE'

NTLM Auth Over SSL

Hi
I have tried to connect to website using this package over ssl and used below code.

from urllib3.contrib import pyopenssl
import requests.packages.urllib3
from requests_ntlm import HttpNtlmAuth
...
requests.packages.urllib3.disable_warnings()
pyopenssl.inject_into_urllib3()
....
...
session = requests.Session()
					session.headers.update({'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)'})
					session.auth = HttpNtlmAuth(userFile[unum],passFile[pnum], session)
					resp = session.get(addr , verify = False)

but I get below error.
bad handshake: SysCallError(-1, 'Unexpected EOF')

also I tried with custom HTTPAdapter and again that error
Any suggestion?

IndexError

I am using 0.2.0 and I am getting this:

Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\requests\api.py", line 69, in get
    return request('get', url, params=params, **kwargs)
  File "C:\Python27\lib\site-packages\requests\api.py", line 50, in request
    response = session.request(method=method, url=url, **kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 465, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Python27\lib\site-packages\requests\sessions.py", line 579, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "C:\Python27\lib\site-packages\requests\hooks.py", line 41, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
  File "C:\Python27\lib\site-packages\requests_ntlm\requests_ntlm.py", line 119, in response_hook
    'Authorization', r, kwargs)
  File "C:\Python27\lib\site-packages\requests_ntlm\requests_ntlm.py", line 91, in retry_using_http_NTLM_auth
    ))[0].strip()
IndexError: list index out of range

And inspecting auth_header_value I can see it starts with "Negotiate, NTLM " and the code is splitting on ',' and then using `startswith('NTLM '). But after the split the value starts with ' NTLM '.

I verified that it works on my side is I split on ', ' instead, but that's not the proper fix ofc.

Fix versioning

Rather than going from 0.0.2.4 to 0.0.2.5, I'd like to bump to 0.0.3. Then moving forward we can do proper semver. Does that sound legit?

/cc @sigmavirus24 @Lukasa

pass the hash is not working

Hi,
I'm trying to pass the hash and i saw the following comment in your code: "Supports pass-the-hash". so how it works? i tried to just pass password equals to the ntlm hash but it doesnt work.

Repo structure

So, we should try to make sure that all of the repositories under this org are of the same form. The easiest way to do this is to make sure they all conform to Kenneth's suggested repo structure.

For those who aren't bothered about clicking through and reading, the things we need here are:

  • LICENSE(we should license under the same license as Requests) DONE
  • requirements.txt (self explanatory) DONE
  • docs/ (this will be pretty short, but worth having anyway)
  • tests/ (obviously this is covered in #1, but noted here for completeness).

There's some low-hanging fruit here: LICENSE and requirements.txt are both pretty easy. Probably wouldn't hurt to have an AUTHORS file as well, seeing as we can easily keep track of any authors there are: this is also easy.

Docs isn't hard, but is obviously less fun than the other stuff. ;)

Tests is covered in #1.

Error: Incorrect Padding

I'm getting an error (Error: Incorrect Padding) which occurred in python-ntlm but was later corrected. The below link describes the same issue I'm having and you'll find at the bottom it notes that the issue was corrected in a later release.

I made the changes to HTTPNtlmAuthHandler.py as described in the second link and no longer had the issue with python-ntlm.

https://code.google.com/p/python-ntlm/issues/detail?id=17

https://code.google.com/p/python-ntlm/source/detail?r=89

I believe that these changes need to be implemented into requests-ntlm in order to correct the issue I'm having with the "Error: Incorrect Padding" message I receive.

System: Windows 7 x64
Python: Version 2.7.6 (also received error in 2.7.5)
Use: Requesting data from corporate Sharepoint site which utilizes NTLM authenticaton

Let me know if you need any further information.

Thanks!
J

requests-ntlm sends POST/PUT data three times

HttpNtlmAuth sends data three times for POST and PUT.

The flow is following:

  • a program sends a POST/PUT request
  • before the request is send, HttpNtlmAuth prepares the request, sets a hook on response
  • the whole request is sent, data included
  • server returns 401
  • HttpNtlmAuth recognizes 401 and does retry_using_http_NTLM_auth
  • sends the data again
  • sends the data again, this time 200 is expected

This is quite fragile and slow, especially when you try to send a huge request - hundreds of MBs to a webdav server.

Add python-ntlm to setup.py

Currently when you run pip install requests-ntlm, you don't get python-ntlm. This is because setup.py doesn't include it. We should update setup.py to do that.

Change NTLM dependency

Hi

I have had a pull request open for around 18 days to update python-ntlm3 to support the extra security features of NTLM that were missing but it so far hasn't been looked at. This pull request will fix the issues raised #71 and #75.

After trying to get in contact with the maintainer and also talking to @sigmavirus24 I haven't been able to get some traction with the maintainer. I am proposing I or someone else create a new repository based on my changes of python-ntlm3 and create a new pypi package for requests-ntlm to use. Currently without any modifications to my changes it is a drop dead replacement but I would prefer to remove some deprecated methods if we go this route and update requests-ntlm to support the new method which brings NTLMv2, Channel Binding Tokens and SPEGNO encryption support.

Thanks

Jordan

NTLMv2 support

Hello,

Thanks for your efforts but I believe NTLMv2 is still not supported in python-ntlm3 and python-ntlm as appears from traffic captures and from reported issues in respective repositories:

rachelsanders/python-ntlm3#10
mullender/python-ntlm#47

Issues were reported since quite a while so I hope there's some sort of an alternative as many projects are depending on it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.