├── CODE_OF_CONDUCT.md ├── README.md ├── azure-pipelines.yml ├── ci.sh ├── ci └── test.sh ├── python26 ├── ntlm │ ├── HTTPNtlmAuthHandler.py │ ├── U32.py │ ├── __init__.py │ ├── des.py │ ├── des_c.py │ ├── des_data.py │ └── ntlm.py ├── ntlm_examples │ ├── extended.py │ ├── simple.py │ └── test_ntlmauth.py └── setup.py └── python30 ├── ntlm ├── HTTPNtlmAuthHandler.py ├── U32.py ├── __init__.py ├── des.py ├── des_c.py ├── des_data.py └── ntlm.py └── ntlm_examples ├── extended.py ├── simple.py └── test_ntlmauth.py /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at tim.gates@iress.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python-ntlm 2 | Python library that provides NTLM support, including an authentication handler for urllib2. 3 | 4 | This library allows you to retrieve content from (usually corporate) servers protected with windows authentication (NTLM) using the python urllib2. 5 | 6 | ## Python 3 Support 7 | There is work going on to port the library to python 3, you can find it in the python30 directory. (at this time it seems to work as good as the python 2 library) 8 | 9 | # Usage 10 | 11 | ## Simple example 12 | ```python 13 | import urllib2 14 | from ntlm import HTTPNtlmAuthHandler 15 | 16 | user = 'DOMAIN\User' 17 | password = "Password" 18 | url = "http://ntlmprotectedserver/securedfile.html" 19 | 20 | passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 21 | passman.add_password(None, url, user, password) 22 | # create the NTLM authentication handler 23 | auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman) 24 | 25 | # create and install the opener 26 | opener = urllib2.build_opener(auth_NTLM) 27 | urllib2.install_opener(opener) 28 | 29 | # retrieve the result 30 | response = urllib2.urlopen(url) 31 | print(response.read()) 32 | ``` 33 | 34 | ## Extended Example 35 | ```python 36 | import urllib2 37 | from urlparse import urlparse, urlunparse 38 | from ntlm import HTTPNtlmAuthHandler 39 | 40 | user = 'DOMAIN\User' 41 | password = "Password" 42 | url = "http://ntlmprotectedserver/securedfile.html" 43 | # determine a base_uri for which the username and password can be used 44 | parsed_url = urlparse(self.href) 45 | base_uri = urlunparse((parsed_url[0],parsed_url[1],"","","","")) 46 | 47 | passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 48 | passman.add_password(None, base_uri, user, password) 49 | # create the NTLM authentication handler 50 | auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman) 51 | 52 | # other authentication handlers 53 | auth_basic = urllib2.HTTPBasicAuthHandler(passman) 54 | auth_digest = urllib2.HTTPDigestAuthHandler(passman) 55 | 56 | # disable proxies (if you want to stay within the corporate network) 57 | proxy_handler = urllib2.ProxyHandler({}) 58 | 59 | # create and install the opener 60 | opener = urllib2.build_opener(proxy_handler, auth_NTLM, auth_digest, auth_basic) 61 | urllib2.install_opener(opener) 62 | 63 | # retrieve the result 64 | response = urllib2.urlopen(url) 65 | print(response.read()) 66 | ``` 67 | 68 | ## Limitations 69 | * A request using the `HTTPNtlmAuthHandler` has no HTTP status handling, for example: redirects are not handled by the opener, you must check and handle the response yourself. 70 | 71 | # Resources 72 | 73 | ## Inspired by 74 | * [http://sourceforge.net/projects/ntlmaps/ NTLM Authorization Proxy Server] 75 | (Dmitri Rozmanov kindly allowed his code to be redistributed under the LGPL) 76 | 77 | The NTLM Authorization Proxy Server can be used to make applications that do not support NTLM proxies use them anyway: "Opens up IIS Proxy Servers using NTLM to non-Microsoft browsers, etc" 78 | 79 | In contrast the python-ntlm library is used to make it possible for python code to retrieve content from an NTLM protected server. 80 | 81 | ## References 82 | * [MS-NLMP]: [http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-NLMP%5D.pdf NT LAN Manager (NTLM) Authentication Protocol Specification] 83 | * [MS-NTHT]: [http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-NTHT%5D.pdf NTLM Over HTTP Protocol Specification] 84 | * [http://www.blackhat.com/presentations/bh-asia-04/bh-jp-04-pdfs/bh-jp-04-seki.pdf Optimized Attack for NTLM2 Session Response] 85 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # Docker based build via ./ci.sh 2 | 3 | trigger: 4 | - master 5 | 6 | jobs: 7 | 8 | - job: 'Docker' 9 | pool: 10 | vmImage: 'ubuntu-16.04' 11 | 12 | steps: 13 | - script: ./ci.sh 14 | -------------------------------------------------------------------------------- /ci.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | BASEDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | 7 | CMD="${1:-test}" 8 | if ! which docker ; then 9 | echo 'Docker is missing!' >&2 10 | exit 1 11 | fi 12 | if ! which docker-compose ; then 13 | echo 'Docker-Compose is missing!' >&2 14 | exit 1 15 | fi 16 | if [[ "$CMD" =~ [^a-zA-Z0-9] ]]; then 17 | echo "Invalid Command: ${CMD}" >&2 18 | exit 1 19 | fi 20 | cd "${BASEDIR}" 21 | source "${BASEDIR}/ci/${CMD}.sh" "${@:2}" 22 | 23 | -------------------------------------------------------------------------------- /ci/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euxo pipefail 4 | 5 | THISDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | BASEDIR="$( dirname "${THISDIR}" )" 7 | 8 | true 9 | -------------------------------------------------------------------------------- /python26/ntlm/HTTPNtlmAuthHandler.py: -------------------------------------------------------------------------------- 1 | # This library is free software: you can redistribute it and/or 2 | # modify it under the terms of the GNU Lesser General Public 3 | # License as published by the Free Software Foundation, either 4 | # version 3 of the License, or (at your option) any later version. 5 | 6 | # This library is distributed in the hope that it will be useful, 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | # Lesser General Public License for more details. 10 | # 11 | # You should have received a copy of the GNU Lesser General Public 12 | # License along with this library. If not, see or . 13 | 14 | import urllib2 15 | import httplib, socket 16 | from urllib import addinfourl 17 | import ntlm 18 | import re 19 | 20 | class AbstractNtlmAuthHandler: 21 | def __init__(self, password_mgr=None, debuglevel=0): 22 | """Initialize an instance of a AbstractNtlmAuthHandler. 23 | 24 | Verify operation with all default arguments. 25 | >>> abstrct = AbstractNtlmAuthHandler() 26 | 27 | Verify "normal" operation. 28 | >>> abstrct = AbstractNtlmAuthHandler(urllib2.HTTPPasswordMgrWithDefaultRealm()) 29 | """ 30 | if password_mgr is None: 31 | password_mgr = urllib2.HTTPPasswordMgr() 32 | self.passwd = password_mgr 33 | self.add_password = self.passwd.add_password 34 | self._debuglevel = debuglevel 35 | 36 | def set_http_debuglevel(self, level): 37 | self._debuglevel = level 38 | 39 | def http_error_authentication_required(self, auth_header_field, req, fp, headers): 40 | auth_header_value = headers.get(auth_header_field, None) 41 | if auth_header_field: 42 | if auth_header_value is not None and 'ntlm' in auth_header_value.lower(): 43 | fp.close() 44 | return self.retry_using_http_NTLM_auth(req, auth_header_field, None, headers) 45 | 46 | def retry_using_http_NTLM_auth(self, req, auth_header_field, realm, headers): 47 | user, pw = self.passwd.find_user_password(realm, req.get_full_url()) 48 | if pw is not None: 49 | user_parts = user.split('\\', 1) 50 | if len(user_parts) == 1: 51 | UserName = user_parts[0] 52 | DomainName = '' 53 | type1_flags = ntlm.NTLM_TYPE1_FLAGS & ~ntlm.NTLM_NegotiateOemDomainSupplied 54 | else: 55 | DomainName = user_parts[0].upper() 56 | UserName = user_parts[1] 57 | type1_flags = ntlm.NTLM_TYPE1_FLAGS 58 | # ntlm secures a socket, so we must use the same socket for the complete handshake 59 | headers = dict(req.headers) 60 | headers.update(req.unredirected_hdrs) 61 | auth = 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(user, type1_flags) 62 | if req.headers.get(self.auth_header, None) == auth: 63 | return None 64 | headers[self.auth_header] = auth 65 | 66 | host = req.get_host() 67 | if not host: 68 | raise urllib2.URLError('no host given') 69 | h = None 70 | if req.get_full_url().startswith('https://'): 71 | h = httplib.HTTPSConnection(host) # will parse host:port 72 | else: 73 | h = httplib.HTTPConnection(host) # will parse host:port 74 | h.set_debuglevel(self._debuglevel) 75 | # we must keep the connection because NTLM authenticates the connection, not single requests 76 | headers["Connection"] = "Keep-Alive" 77 | headers = dict((name.title(), val) for name, val in headers.items()) 78 | h.request(req.get_method(), req.get_selector(), req.data, headers) 79 | r = h.getresponse() 80 | r.begin() 81 | r._safe_read(int(r.getheader('content-length'))) 82 | if r.getheader('set-cookie'): 83 | # this is important for some web applications that store authentication-related info in cookies (it took a long time to figure out) 84 | headers['Cookie'] = r.getheader('set-cookie') 85 | r.fp = None # remove the reference to the socket, so that it can not be closed by the response object (we want to keep the socket open) 86 | auth_header_value = r.getheader(auth_header_field, None) 87 | 88 | # some Exchange servers send two WWW-Authenticate headers, one with the NTLM challenge 89 | # and another with the 'Negotiate' keyword - make sure we operate on the right one 90 | m = re.match('(NTLM [A-Za-z0-9+\-/=]+)', auth_header_value) 91 | if m: 92 | auth_header_value, = m.groups() 93 | 94 | (ServerChallenge, NegotiateFlags) = ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value[5:]) 95 | auth = 'NTLM %s' % ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, UserName, DomainName, pw, NegotiateFlags) 96 | headers[self.auth_header] = auth 97 | headers["Connection"] = "Close" 98 | headers = dict((name.title(), val) for name, val in headers.items()) 99 | try: 100 | h.request(req.get_method(), req.get_selector(), req.data, headers) 101 | # none of the configured handlers are triggered, for example redirect-responses are not handled! 102 | response = h.getresponse() 103 | def notimplemented(): 104 | raise NotImplementedError 105 | response.readline = notimplemented 106 | infourl = addinfourl(response, response.msg, req.get_full_url()) 107 | infourl.code = response.status 108 | infourl.msg = response.reason 109 | return infourl 110 | except socket.error, err: 111 | raise urllib2.URLError(err) 112 | else: 113 | return None 114 | 115 | 116 | class HTTPNtlmAuthHandler(AbstractNtlmAuthHandler, urllib2.BaseHandler): 117 | 118 | auth_header = 'Authorization' 119 | 120 | def http_error_401(self, req, fp, code, msg, headers): 121 | return self.http_error_authentication_required('www-authenticate', req, fp, headers) 122 | 123 | 124 | class ProxyNtlmAuthHandler(AbstractNtlmAuthHandler, urllib2.BaseHandler): 125 | """ 126 | CAUTION: this class has NOT been tested at all!!! 127 | use at your own risk 128 | """ 129 | auth_header = 'Proxy-authorization' 130 | 131 | def http_error_407(self, req, fp, code, msg, headers): 132 | return self.http_error_authentication_required('proxy-authenticate', req, fp, headers) 133 | 134 | 135 | if __name__ == "__main__": 136 | import doctest 137 | doctest.testmod() 138 | 139 | ### TODO: Move this to the ntlm examples directory. 140 | ##if __name__ == "__main__": 141 | ## url = "http://ntlmprotectedserver/securedfile.html" 142 | ## user = u'DOMAIN\\User' 143 | ## password = 'Password' 144 | ## 145 | ## passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 146 | ## passman.add_password(None, url, user , password) 147 | ## auth_basic = urllib2.HTTPBasicAuthHandler(passman) 148 | ## auth_digest = urllib2.HTTPDigestAuthHandler(passman) 149 | ## auth_NTLM = HTTPNtlmAuthHandler(passman) 150 | ## 151 | ## # disable proxies (just for testing) 152 | ## proxy_handler = urllib2.ProxyHandler({}) 153 | ## 154 | ## opener = urllib2.build_opener(proxy_handler, auth_NTLM) #, auth_digest, auth_basic) 155 | ## 156 | ## urllib2.install_opener(opener) 157 | ## 158 | ## response = urllib2.urlopen(url) 159 | ## print(response.read()) 160 | -------------------------------------------------------------------------------- /python26/ntlm/U32.py: -------------------------------------------------------------------------------- 1 | # This file is part of 'NTLM Authorization Proxy Server' http://sourceforge.net/projects/ntlmaps/ 2 | # Copyright 2001 Dmitry A. Rozmanov 3 | # 4 | # This library is free software: you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation, either 7 | # version 3 of the License, or (at your option) any later version. 8 | 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. If not, see or . 16 | 17 | 18 | C = 0x1000000000L 19 | 20 | def norm(n): 21 | return n & 0xFFFFFFFFL 22 | 23 | 24 | class U32: 25 | v = 0L 26 | 27 | def __init__(self, value = 0): 28 | self.v = C + norm(abs(long(value))) 29 | 30 | def set(self, value = 0): 31 | self.v = C + norm(abs(long(value))) 32 | 33 | def __repr__(self): 34 | return hex(norm(self.v)) 35 | 36 | def __long__(self): return long(norm(self.v)) 37 | def __int__(self): return int(norm(self.v)) 38 | def __chr__(self): return chr(norm(self.v)) 39 | 40 | def __add__(self, b): 41 | r = U32() 42 | r.v = C + norm(self.v + b.v) 43 | return r 44 | 45 | def __sub__(self, b): 46 | r = U32() 47 | if self.v < b.v: 48 | r.v = C + norm(0x100000000L - (b.v - self.v)) 49 | else: r.v = C + norm(self.v - b.v) 50 | return r 51 | 52 | def __mul__(self, b): 53 | r = U32() 54 | r.v = C + norm(self.v * b.v) 55 | return r 56 | 57 | def __div__(self, b): 58 | r = U32() 59 | r.v = C + (norm(self.v) / norm(b.v)) 60 | return r 61 | 62 | def __mod__(self, b): 63 | r = U32() 64 | r.v = C + (norm(self.v) % norm(b.v)) 65 | return r 66 | 67 | def __neg__(self): return U32(self.v) 68 | def __pos__(self): return U32(self.v) 69 | def __abs__(self): return U32(self.v) 70 | 71 | def __invert__(self): 72 | r = U32() 73 | r.v = C + norm(~self.v) 74 | return r 75 | 76 | def __lshift__(self, b): 77 | r = U32() 78 | r.v = C + norm(self.v << b) 79 | return r 80 | 81 | def __rshift__(self, b): 82 | r = U32() 83 | r.v = C + (norm(self.v) >> b) 84 | return r 85 | 86 | def __and__(self, b): 87 | r = U32() 88 | r.v = C + norm(self.v & b.v) 89 | return r 90 | 91 | def __or__(self, b): 92 | r = U32() 93 | r.v = C + norm(self.v | b.v) 94 | return r 95 | 96 | def __xor__(self, b): 97 | r = U32() 98 | r.v = C + norm(self.v ^ b.v) 99 | return r 100 | 101 | def __not__(self): 102 | return U32(not norm(self.v)) 103 | 104 | def truth(self): 105 | return norm(self.v) 106 | 107 | def __cmp__(self, b): 108 | if norm(self.v) > norm(b.v): return 1 109 | elif norm(self.v) < norm(b.v): return -1 110 | else: return 0 111 | 112 | def __nonzero__(self): 113 | return norm(self.v) -------------------------------------------------------------------------------- /python26/ntlm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mullender/python-ntlm/14e2243e05c8b671c6eae570d670672c9613e563/python26/ntlm/__init__.py -------------------------------------------------------------------------------- /python26/ntlm/des.py: -------------------------------------------------------------------------------- 1 | # This file is part of 'NTLM Authorization Proxy Server' http://sourceforge.net/projects/ntlmaps/ 2 | # Copyright 2001 Dmitry A. Rozmanov 3 | # 4 | # This library is free software: you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation, either 7 | # version 3 of the License, or (at your option) any later version. 8 | 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. If not, see or . 16 | 17 | import des_c 18 | 19 | #--------------------------------------------------------------------- 20 | class DES: 21 | 22 | des_c_obj = None 23 | 24 | #----------------------------------------------------------------- 25 | def __init__(self, key_str): 26 | "" 27 | k = str_to_key56(key_str) 28 | k = key56_to_key64(k) 29 | key_str = '' 30 | for i in k: 31 | key_str += chr(i & 0xFF) 32 | self.des_c_obj = des_c.DES(key_str) 33 | 34 | #----------------------------------------------------------------- 35 | def encrypt(self, plain_text): 36 | "" 37 | return self.des_c_obj.encrypt(plain_text) 38 | 39 | #----------------------------------------------------------------- 40 | def decrypt(self, crypted_text): 41 | "" 42 | return self.des_c_obj.decrypt(crypted_text) 43 | 44 | #--------------------------------------------------------------------- 45 | #Some Helpers 46 | #--------------------------------------------------------------------- 47 | 48 | DESException = 'DESException' 49 | 50 | #--------------------------------------------------------------------- 51 | def str_to_key56(key_str): 52 | "" 53 | if type(key_str) != type(''): 54 | #rise DESException, 'ERROR. Wrong key type.' 55 | pass 56 | if len(key_str) < 7: 57 | key_str = key_str + '\000\000\000\000\000\000\000'[:(7 - len(key_str))] 58 | key_56 = [] 59 | for i in key_str[:7]: key_56.append(ord(i)) 60 | 61 | return key_56 62 | 63 | #--------------------------------------------------------------------- 64 | def key56_to_key64(key_56): 65 | "" 66 | key = [] 67 | for i in range(8): key.append(0) 68 | 69 | key[0] = key_56[0]; 70 | key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1); 71 | key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2); 72 | key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3); 73 | key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4); 74 | key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5); 75 | key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6); 76 | key[7] = (key_56[6] << 1) & 0xFF; 77 | 78 | key = set_key_odd_parity(key) 79 | 80 | return key 81 | 82 | #--------------------------------------------------------------------- 83 | def set_key_odd_parity(key): 84 | "" 85 | for i in range(len(key)): 86 | for k in range(7): 87 | bit = 0 88 | t = key[i] >> k 89 | bit = (t ^ bit) & 0x1 90 | key[i] = (key[i] & 0xFE) | bit 91 | 92 | return key 93 | -------------------------------------------------------------------------------- /python26/ntlm/des_c.py: -------------------------------------------------------------------------------- 1 | # This file is part of 'NTLM Authorization Proxy Server' http://sourceforge.net/projects/ntlmaps/ 2 | # Copyright 2001 Dmitry A. Rozmanov 3 | # 4 | # This library is free software: you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation, either 7 | # version 3 of the License, or (at your option) any later version. 8 | 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. If not, see or . 16 | 17 | from U32 import U32 18 | 19 | # --NON ASCII COMMENT ELIDED-- 20 | #typedef unsigned char des_cblock[8]; 21 | #define HDRSIZE 4 22 | 23 | def c2l(c): 24 | "char[4] to unsigned long" 25 | l = U32(c[0]) 26 | l = l | (U32(c[1]) << 8) 27 | l = l | (U32(c[2]) << 16) 28 | l = l | (U32(c[3]) << 24) 29 | return l 30 | 31 | def c2ln(c,l1,l2,n): 32 | "char[n] to two unsigned long???" 33 | c = c + n 34 | l1, l2 = U32(0), U32(0) 35 | 36 | f = 0 37 | if n == 8: 38 | l2 = l2 | (U32(c[7]) << 24) 39 | f = 1 40 | if f or (n == 7): 41 | l2 = l2 | (U32(c[6]) << 16) 42 | f = 1 43 | if f or (n == 6): 44 | l2 = l2 | (U32(c[5]) << 8) 45 | f = 1 46 | if f or (n == 5): 47 | l2 = l2 | U32(c[4]) 48 | f = 1 49 | if f or (n == 4): 50 | l1 = l1 | (U32(c[3]) << 24) 51 | f = 1 52 | if f or (n == 3): 53 | l1 = l1 | (U32(c[2]) << 16) 54 | f = 1 55 | if f or (n == 2): 56 | l1 = l1 | (U32(c[1]) << 8) 57 | f = 1 58 | if f or (n == 1): 59 | l1 = l1 | U32(c[0]) 60 | return (l1, l2) 61 | 62 | def l2c(l): 63 | "unsigned long to char[4]" 64 | c = [] 65 | c.append(int(l & U32(0xFF))) 66 | c.append(int((l >> 8) & U32(0xFF))) 67 | c.append(int((l >> 16) & U32(0xFF))) 68 | c.append(int((l >> 24) & U32(0xFF))) 69 | return c 70 | 71 | def n2l(c, l): 72 | "network to host long" 73 | l = U32(c[0] << 24) 74 | l = l | (U32(c[1]) << 16) 75 | l = l | (U32(c[2]) << 8) 76 | l = l | (U32(c[3])) 77 | return l 78 | 79 | def l2n(l, c): 80 | "host to network long" 81 | c = [] 82 | c.append(int((l >> 24) & U32(0xFF))) 83 | c.append(int((l >> 16) & U32(0xFF))) 84 | c.append(int((l >> 8) & U32(0xFF))) 85 | c.append(int((l ) & U32(0xFF))) 86 | return c 87 | 88 | def l2cn(l1, l2, c, n): 89 | "" 90 | for i in range(n): c.append(0x00) 91 | f = 0 92 | if f or (n == 8): 93 | c[7] = int((l2 >> 24) & U32(0xFF)) 94 | f = 1 95 | if f or (n == 7): 96 | c[6] = int((l2 >> 16) & U32(0xFF)) 97 | f = 1 98 | if f or (n == 6): 99 | c[5] = int((l2 >> 8) & U32(0xFF)) 100 | f = 1 101 | if f or (n == 5): 102 | c[4] = int((l2 ) & U32(0xFF)) 103 | f = 1 104 | if f or (n == 4): 105 | c[3] = int((l1 >> 24) & U32(0xFF)) 106 | f = 1 107 | if f or (n == 3): 108 | c[2] = int((l1 >> 16) & U32(0xFF)) 109 | f = 1 110 | if f or (n == 2): 111 | c[1] = int((l1 >> 8) & U32(0xFF)) 112 | f = 1 113 | if f or (n == 1): 114 | c[0] = int((l1 ) & U32(0xFF)) 115 | f = 1 116 | return c[:n] 117 | 118 | # array of data 119 | # static unsigned long des_SPtrans[8][64]={ 120 | # static unsigned long des_skb[8][64]={ 121 | from des_data import des_SPtrans, des_skb 122 | 123 | def D_ENCRYPT(tup, u, t, s): 124 | L, R, S = tup 125 | #print 'LRS1', L, R, S, u, t, '-->', 126 | u = (R ^ s[S]) 127 | t = R ^ s[S + 1] 128 | t = ((t >> 4) + (t << 28)) 129 | L = L ^ (des_SPtrans[1][int((t ) & U32(0x3f))] | \ 130 | des_SPtrans[3][int((t >> 8) & U32(0x3f))] | \ 131 | des_SPtrans[5][int((t >> 16) & U32(0x3f))] | \ 132 | des_SPtrans[7][int((t >> 24) & U32(0x3f))] | \ 133 | des_SPtrans[0][int((u ) & U32(0x3f))] | \ 134 | des_SPtrans[2][int((u >> 8) & U32(0x3f))] | \ 135 | des_SPtrans[4][int((u >> 16) & U32(0x3f))] | \ 136 | des_SPtrans[6][int((u >> 24) & U32(0x3f))]) 137 | #print 'LRS:', L, R, S, u, t 138 | return ((L, R, S), u, t, s) 139 | 140 | 141 | def PERM_OP (tup, n, m): 142 | "tup - (a, b, t)" 143 | a, b, t = tup 144 | t = ((a >> n) ^ b) & m 145 | b = b ^ t 146 | a = a ^ (t << n) 147 | return (a, b, t) 148 | 149 | def HPERM_OP (tup, n, m): 150 | "tup - (a, t)" 151 | a, t = tup 152 | t = ((a << (16 - n)) ^ a) & m 153 | a = a ^ t ^ (t >> (16 - n)) 154 | return (a, t) 155 | 156 | shifts2 = [0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0] 157 | 158 | class DES: 159 | KeySched = None # des_key_schedule 160 | 161 | def __init__(self, key_str): 162 | # key - UChar[8] 163 | key = [] 164 | for i in key_str: key.append(ord(i)) 165 | #print 'key:', key 166 | self.KeySched = des_set_key(key) 167 | #print 'schedule:', self.KeySched, len(self.KeySched) 168 | 169 | def decrypt(self, str): 170 | # block - UChar[] 171 | block = [] 172 | for i in str: block.append(ord(i)) 173 | #print block 174 | block = des_ecb_encrypt(block, self.KeySched, 0) 175 | res = '' 176 | for i in block: res = res + (chr(i)) 177 | return res 178 | 179 | def encrypt(self, str): 180 | # block - UChar[] 181 | block = [] 182 | for i in str: block.append(ord(i)) 183 | block = des_ecb_encrypt(block, self.KeySched, 1) 184 | res = '' 185 | for i in block: res = res + (chr(i)) 186 | return res 187 | 188 | 189 | 190 | 191 | 192 | 193 | #------------------------ 194 | def des_encript(input, ks, encrypt): 195 | # input - U32[] 196 | # output - U32[] 197 | # ks - des_key_shedule - U32[2][16] 198 | # encrypt - int 199 | # l, r, t, u - U32 200 | # i - int 201 | # s - U32[] 202 | 203 | l = input[0] 204 | r = input[1] 205 | t = U32(0) 206 | u = U32(0) 207 | 208 | r, l, t = PERM_OP((r, l, t), 4, U32(0x0f0f0f0fL)) 209 | l, r, t = PERM_OP((l, r, t), 16, U32(0x0000ffffL)) 210 | r, l, t = PERM_OP((r, l, t), 2, U32(0x33333333L)) 211 | l, r, t = PERM_OP((l, r, t), 8, U32(0x00ff00ffL)) 212 | r, l, t = PERM_OP((r, l, t), 1, U32(0x55555555L)) 213 | 214 | t = (r << 1)|(r >> 31) 215 | r = (l << 1)|(l >> 31) 216 | l = t 217 | 218 | s = ks # ??????????????? 219 | #print l, r 220 | if(encrypt): 221 | for i in range(0, 32, 4): 222 | rtup, u, t, s = D_ENCRYPT((l, r, i + 0), u, t, s) 223 | l = rtup[0] 224 | r = rtup[1] 225 | rtup, u, t, s = D_ENCRYPT((r, l, i + 2), u, t, s) 226 | r = rtup[0] 227 | l = rtup[1] 228 | else: 229 | for i in range(30, 0, -4): 230 | rtup, u, t, s = D_ENCRYPT((l, r, i - 0), u, t, s) 231 | l = rtup[0] 232 | r = rtup[1] 233 | rtup, u, t, s = D_ENCRYPT((r, l, i - 2), u, t, s) 234 | r = rtup[0] 235 | l = rtup[1] 236 | #print l, r 237 | l = (l >> 1)|(l << 31) 238 | r = (r >> 1)|(r << 31) 239 | 240 | r, l, t = PERM_OP((r, l, t), 1, U32(0x55555555L)) 241 | l, r, t = PERM_OP((l, r, t), 8, U32(0x00ff00ffL)) 242 | r, l, t = PERM_OP((r, l, t), 2, U32(0x33333333L)) 243 | l, r, t = PERM_OP((l, r, t), 16, U32(0x0000ffffL)) 244 | r, l, t = PERM_OP((r, l, t), 4, U32(0x0f0f0f0fL)) 245 | 246 | output = [l] 247 | output.append(r) 248 | l, r, t, u = U32(0), U32(0), U32(0), U32(0) 249 | return output 250 | 251 | def des_ecb_encrypt(input, ks, encrypt): 252 | # input - des_cblock - UChar[8] 253 | # output - des_cblock - UChar[8] 254 | # ks - des_key_shedule - U32[2][16] 255 | # encrypt - int 256 | 257 | #print input 258 | l0 = c2l(input[0:4]) 259 | l1 = c2l(input[4:8]) 260 | ll = [l0] 261 | ll.append(l1) 262 | #print ll 263 | ll = des_encript(ll, ks, encrypt) 264 | #print ll 265 | l0 = ll[0] 266 | l1 = ll[1] 267 | output = l2c(l0) 268 | output = output + l2c(l1) 269 | #print output 270 | l0, l1, ll[0], ll[1] = U32(0), U32(0), U32(0), U32(0) 271 | return output 272 | 273 | def des_set_key(key): 274 | # key - des_cblock - UChar[8] 275 | # schedule - des_key_schedule 276 | 277 | # register unsigned long c,d,t,s; 278 | # register unsigned char *in; 279 | # register unsigned long *k; 280 | # register int i; 281 | 282 | #k = schedule 283 | # in = key 284 | 285 | k = [] 286 | c = c2l(key[0:4]) 287 | d = c2l(key[4:8]) 288 | t = U32(0) 289 | 290 | d, c, t = PERM_OP((d, c, t), 4, U32(0x0f0f0f0fL)) 291 | c, t = HPERM_OP((c, t), -2, U32(0xcccc0000L)) 292 | d, t = HPERM_OP((d, t), -2, U32(0xcccc0000L)) 293 | d, c, t = PERM_OP((d, c, t), 1, U32(0x55555555L)) 294 | c, d, t = PERM_OP((c, d, t), 8, U32(0x00ff00ffL)) 295 | d, c, t = PERM_OP((d, c, t), 1, U32(0x55555555L)) 296 | 297 | d = (((d & U32(0x000000ffL)) << 16)|(d & U32(0x0000ff00L))|((d & U32(0x00ff0000L)) >> 16)|((c & U32(0xf0000000L)) >> 4)) 298 | c = c & U32(0x0fffffffL) 299 | 300 | for i in range(16): 301 | if (shifts2[i]): 302 | c = ((c >> 2)|(c << 26)) 303 | d = ((d >> 2)|(d << 26)) 304 | else: 305 | c = ((c >> 1)|(c << 27)) 306 | d = ((d >> 1)|(d << 27)) 307 | c = c & U32(0x0fffffffL) 308 | d = d & U32(0x0fffffffL) 309 | 310 | s= des_skb[0][int((c ) & U32(0x3f))]|\ 311 | des_skb[1][int(((c>> 6) & U32(0x03))|((c>> 7) & U32(0x3c)))]|\ 312 | des_skb[2][int(((c>>13) & U32(0x0f))|((c>>14) & U32(0x30)))]|\ 313 | des_skb[3][int(((c>>20) & U32(0x01))|((c>>21) & U32(0x06)) | ((c>>22) & U32(0x38)))] 314 | 315 | t= des_skb[4][int((d ) & U32(0x3f) )]|\ 316 | des_skb[5][int(((d>> 7) & U32(0x03))|((d>> 8) & U32(0x3c)))]|\ 317 | des_skb[6][int((d>>15) & U32(0x3f) )]|\ 318 | des_skb[7][int(((d>>21) & U32(0x0f))|((d>>22) & U32(0x30)))] 319 | #print s, t 320 | 321 | k.append(((t << 16)|(s & U32(0x0000ffffL))) & U32(0xffffffffL)) 322 | s = ((s >> 16)|(t & U32(0xffff0000L))) 323 | s = (s << 4)|(s >> 28) 324 | k.append(s & U32(0xffffffffL)) 325 | 326 | schedule = k 327 | 328 | return schedule 329 | -------------------------------------------------------------------------------- /python26/ntlm/des_data.py: -------------------------------------------------------------------------------- 1 | # This file is part of 'NTLM Authorization Proxy Server' http://sourceforge.net/projects/ntlmaps/ 2 | # Copyright 2001 Dmitry A. Rozmanov 3 | # 4 | # This library is free software: you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation, either 7 | # version 3 of the License, or (at your option) any later version. 8 | 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. If not, see or . 16 | 17 | from U32 import U32 18 | 19 | # static unsigned long des_SPtrans[8][64]={ 20 | 21 | des_SPtrans =\ 22 | [ 23 | #nibble 0 24 | [ 25 | U32(0x00820200L), U32(0x00020000L), U32(0x80800000L), U32(0x80820200L), 26 | U32(0x00800000L), U32(0x80020200L), U32(0x80020000L), U32(0x80800000L), 27 | U32(0x80020200L), U32(0x00820200L), U32(0x00820000L), U32(0x80000200L), 28 | U32(0x80800200L), U32(0x00800000L), U32(0x00000000L), U32(0x80020000L), 29 | U32(0x00020000L), U32(0x80000000L), U32(0x00800200L), U32(0x00020200L), 30 | U32(0x80820200L), U32(0x00820000L), U32(0x80000200L), U32(0x00800200L), 31 | U32(0x80000000L), U32(0x00000200L), U32(0x00020200L), U32(0x80820000L), 32 | U32(0x00000200L), U32(0x80800200L), U32(0x80820000L), U32(0x00000000L), 33 | U32(0x00000000L), U32(0x80820200L), U32(0x00800200L), U32(0x80020000L), 34 | U32(0x00820200L), U32(0x00020000L), U32(0x80000200L), U32(0x00800200L), 35 | U32(0x80820000L), U32(0x00000200L), U32(0x00020200L), U32(0x80800000L), 36 | U32(0x80020200L), U32(0x80000000L), U32(0x80800000L), U32(0x00820000L), 37 | U32(0x80820200L), U32(0x00020200L), U32(0x00820000L), U32(0x80800200L), 38 | U32(0x00800000L), U32(0x80000200L), U32(0x80020000L), U32(0x00000000L), 39 | U32(0x00020000L), U32(0x00800000L), U32(0x80800200L), U32(0x00820200L), 40 | U32(0x80000000L), U32(0x80820000L), U32(0x00000200L), U32(0x80020200L), 41 | ], 42 | 43 | #nibble 1 44 | [ 45 | U32(0x10042004L), U32(0x00000000L), U32(0x00042000L), U32(0x10040000L), 46 | U32(0x10000004L), U32(0x00002004L), U32(0x10002000L), U32(0x00042000L), 47 | U32(0x00002000L), U32(0x10040004L), U32(0x00000004L), U32(0x10002000L), 48 | U32(0x00040004L), U32(0x10042000L), U32(0x10040000L), U32(0x00000004L), 49 | U32(0x00040000L), U32(0x10002004L), U32(0x10040004L), U32(0x00002000L), 50 | U32(0x00042004L), U32(0x10000000L), U32(0x00000000L), U32(0x00040004L), 51 | U32(0x10002004L), U32(0x00042004L), U32(0x10042000L), U32(0x10000004L), 52 | U32(0x10000000L), U32(0x00040000L), U32(0x00002004L), U32(0x10042004L), 53 | U32(0x00040004L), U32(0x10042000L), U32(0x10002000L), U32(0x00042004L), 54 | U32(0x10042004L), U32(0x00040004L), U32(0x10000004L), U32(0x00000000L), 55 | U32(0x10000000L), U32(0x00002004L), U32(0x00040000L), U32(0x10040004L), 56 | U32(0x00002000L), U32(0x10000000L), U32(0x00042004L), U32(0x10002004L), 57 | U32(0x10042000L), U32(0x00002000L), U32(0x00000000L), U32(0x10000004L), 58 | U32(0x00000004L), U32(0x10042004L), U32(0x00042000L), U32(0x10040000L), 59 | U32(0x10040004L), U32(0x00040000L), U32(0x00002004L), U32(0x10002000L), 60 | U32(0x10002004L), U32(0x00000004L), U32(0x10040000L), U32(0x00042000L), 61 | ], 62 | 63 | #nibble 2 64 | [ 65 | U32(0x41000000L), U32(0x01010040L), U32(0x00000040L), U32(0x41000040L), 66 | U32(0x40010000L), U32(0x01000000L), U32(0x41000040L), U32(0x00010040L), 67 | U32(0x01000040L), U32(0x00010000L), U32(0x01010000L), U32(0x40000000L), 68 | U32(0x41010040L), U32(0x40000040L), U32(0x40000000L), U32(0x41010000L), 69 | U32(0x00000000L), U32(0x40010000L), U32(0x01010040L), U32(0x00000040L), 70 | U32(0x40000040L), U32(0x41010040L), U32(0x00010000L), U32(0x41000000L), 71 | U32(0x41010000L), U32(0x01000040L), U32(0x40010040L), U32(0x01010000L), 72 | U32(0x00010040L), U32(0x00000000L), U32(0x01000000L), U32(0x40010040L), 73 | U32(0x01010040L), U32(0x00000040L), U32(0x40000000L), U32(0x00010000L), 74 | U32(0x40000040L), U32(0x40010000L), U32(0x01010000L), U32(0x41000040L), 75 | U32(0x00000000L), U32(0x01010040L), U32(0x00010040L), U32(0x41010000L), 76 | U32(0x40010000L), U32(0x01000000L), U32(0x41010040L), U32(0x40000000L), 77 | U32(0x40010040L), U32(0x41000000L), U32(0x01000000L), U32(0x41010040L), 78 | U32(0x00010000L), U32(0x01000040L), U32(0x41000040L), U32(0x00010040L), 79 | U32(0x01000040L), U32(0x00000000L), U32(0x41010000L), U32(0x40000040L), 80 | U32(0x41000000L), U32(0x40010040L), U32(0x00000040L), U32(0x01010000L), 81 | ], 82 | 83 | #nibble 3 84 | [ 85 | U32(0x00100402L), U32(0x04000400L), U32(0x00000002L), U32(0x04100402L), 86 | U32(0x00000000L), U32(0x04100000L), U32(0x04000402L), U32(0x00100002L), 87 | U32(0x04100400L), U32(0x04000002L), U32(0x04000000L), U32(0x00000402L), 88 | U32(0x04000002L), U32(0x00100402L), U32(0x00100000L), U32(0x04000000L), 89 | U32(0x04100002L), U32(0x00100400L), U32(0x00000400L), U32(0x00000002L), 90 | U32(0x00100400L), U32(0x04000402L), U32(0x04100000L), U32(0x00000400L), 91 | U32(0x00000402L), U32(0x00000000L), U32(0x00100002L), U32(0x04100400L), 92 | U32(0x04000400L), U32(0x04100002L), U32(0x04100402L), U32(0x00100000L), 93 | U32(0x04100002L), U32(0x00000402L), U32(0x00100000L), U32(0x04000002L), 94 | U32(0x00100400L), U32(0x04000400L), U32(0x00000002L), U32(0x04100000L), 95 | U32(0x04000402L), U32(0x00000000L), U32(0x00000400L), U32(0x00100002L), 96 | U32(0x00000000L), U32(0x04100002L), U32(0x04100400L), U32(0x00000400L), 97 | U32(0x04000000L), U32(0x04100402L), U32(0x00100402L), U32(0x00100000L), 98 | U32(0x04100402L), U32(0x00000002L), U32(0x04000400L), U32(0x00100402L), 99 | U32(0x00100002L), U32(0x00100400L), U32(0x04100000L), U32(0x04000402L), 100 | U32(0x00000402L), U32(0x04000000L), U32(0x04000002L), U32(0x04100400L), 101 | ], 102 | 103 | #nibble 4 104 | [ 105 | U32(0x02000000L), U32(0x00004000L), U32(0x00000100L), U32(0x02004108L), 106 | U32(0x02004008L), U32(0x02000100L), U32(0x00004108L), U32(0x02004000L), 107 | U32(0x00004000L), U32(0x00000008L), U32(0x02000008L), U32(0x00004100L), 108 | U32(0x02000108L), U32(0x02004008L), U32(0x02004100L), U32(0x00000000L), 109 | U32(0x00004100L), U32(0x02000000L), U32(0x00004008L), U32(0x00000108L), 110 | U32(0x02000100L), U32(0x00004108L), U32(0x00000000L), U32(0x02000008L), 111 | U32(0x00000008L), U32(0x02000108L), U32(0x02004108L), U32(0x00004008L), 112 | U32(0x02004000L), U32(0x00000100L), U32(0x00000108L), U32(0x02004100L), 113 | U32(0x02004100L), U32(0x02000108L), U32(0x00004008L), U32(0x02004000L), 114 | U32(0x00004000L), U32(0x00000008L), U32(0x02000008L), U32(0x02000100L), 115 | U32(0x02000000L), U32(0x00004100L), U32(0x02004108L), U32(0x00000000L), 116 | U32(0x00004108L), U32(0x02000000L), U32(0x00000100L), U32(0x00004008L), 117 | U32(0x02000108L), U32(0x00000100L), U32(0x00000000L), U32(0x02004108L), 118 | U32(0x02004008L), U32(0x02004100L), U32(0x00000108L), U32(0x00004000L), 119 | U32(0x00004100L), U32(0x02004008L), U32(0x02000100L), U32(0x00000108L), 120 | U32(0x00000008L), U32(0x00004108L), U32(0x02004000L), U32(0x02000008L), 121 | ], 122 | 123 | #nibble 5 124 | [ 125 | U32(0x20000010L), U32(0x00080010L), U32(0x00000000L), U32(0x20080800L), 126 | U32(0x00080010L), U32(0x00000800L), U32(0x20000810L), U32(0x00080000L), 127 | U32(0x00000810L), U32(0x20080810L), U32(0x00080800L), U32(0x20000000L), 128 | U32(0x20000800L), U32(0x20000010L), U32(0x20080000L), U32(0x00080810L), 129 | U32(0x00080000L), U32(0x20000810L), U32(0x20080010L), U32(0x00000000L), 130 | U32(0x00000800L), U32(0x00000010L), U32(0x20080800L), U32(0x20080010L), 131 | U32(0x20080810L), U32(0x20080000L), U32(0x20000000L), U32(0x00000810L), 132 | U32(0x00000010L), U32(0x00080800L), U32(0x00080810L), U32(0x20000800L), 133 | U32(0x00000810L), U32(0x20000000L), U32(0x20000800L), U32(0x00080810L), 134 | U32(0x20080800L), U32(0x00080010L), U32(0x00000000L), U32(0x20000800L), 135 | U32(0x20000000L), U32(0x00000800L), U32(0x20080010L), U32(0x00080000L), 136 | U32(0x00080010L), U32(0x20080810L), U32(0x00080800L), U32(0x00000010L), 137 | U32(0x20080810L), U32(0x00080800L), U32(0x00080000L), U32(0x20000810L), 138 | U32(0x20000010L), U32(0x20080000L), U32(0x00080810L), U32(0x00000000L), 139 | U32(0x00000800L), U32(0x20000010L), U32(0x20000810L), U32(0x20080800L), 140 | U32(0x20080000L), U32(0x00000810L), U32(0x00000010L), U32(0x20080010L), 141 | ], 142 | 143 | #nibble 6 144 | [ 145 | U32(0x00001000L), U32(0x00000080L), U32(0x00400080L), U32(0x00400001L), 146 | U32(0x00401081L), U32(0x00001001L), U32(0x00001080L), U32(0x00000000L), 147 | U32(0x00400000L), U32(0x00400081L), U32(0x00000081L), U32(0x00401000L), 148 | U32(0x00000001L), U32(0x00401080L), U32(0x00401000L), U32(0x00000081L), 149 | U32(0x00400081L), U32(0x00001000L), U32(0x00001001L), U32(0x00401081L), 150 | U32(0x00000000L), U32(0x00400080L), U32(0x00400001L), U32(0x00001080L), 151 | U32(0x00401001L), U32(0x00001081L), U32(0x00401080L), U32(0x00000001L), 152 | U32(0x00001081L), U32(0x00401001L), U32(0x00000080L), U32(0x00400000L), 153 | U32(0x00001081L), U32(0x00401000L), U32(0x00401001L), U32(0x00000081L), 154 | U32(0x00001000L), U32(0x00000080L), U32(0x00400000L), U32(0x00401001L), 155 | U32(0x00400081L), U32(0x00001081L), U32(0x00001080L), U32(0x00000000L), 156 | U32(0x00000080L), U32(0x00400001L), U32(0x00000001L), U32(0x00400080L), 157 | U32(0x00000000L), U32(0x00400081L), U32(0x00400080L), U32(0x00001080L), 158 | U32(0x00000081L), U32(0x00001000L), U32(0x00401081L), U32(0x00400000L), 159 | U32(0x00401080L), U32(0x00000001L), U32(0x00001001L), U32(0x00401081L), 160 | U32(0x00400001L), U32(0x00401080L), U32(0x00401000L), U32(0x00001001L), 161 | ], 162 | 163 | #nibble 7 164 | [ 165 | U32(0x08200020L), U32(0x08208000L), U32(0x00008020L), U32(0x00000000L), 166 | U32(0x08008000L), U32(0x00200020L), U32(0x08200000L), U32(0x08208020L), 167 | U32(0x00000020L), U32(0x08000000L), U32(0x00208000L), U32(0x00008020L), 168 | U32(0x00208020L), U32(0x08008020L), U32(0x08000020L), U32(0x08200000L), 169 | U32(0x00008000L), U32(0x00208020L), U32(0x00200020L), U32(0x08008000L), 170 | U32(0x08208020L), U32(0x08000020L), U32(0x00000000L), U32(0x00208000L), 171 | U32(0x08000000L), U32(0x00200000L), U32(0x08008020L), U32(0x08200020L), 172 | U32(0x00200000L), U32(0x00008000L), U32(0x08208000L), U32(0x00000020L), 173 | U32(0x00200000L), U32(0x00008000L), U32(0x08000020L), U32(0x08208020L), 174 | U32(0x00008020L), U32(0x08000000L), U32(0x00000000L), U32(0x00208000L), 175 | U32(0x08200020L), U32(0x08008020L), U32(0x08008000L), U32(0x00200020L), 176 | U32(0x08208000L), U32(0x00000020L), U32(0x00200020L), U32(0x08008000L), 177 | U32(0x08208020L), U32(0x00200000L), U32(0x08200000L), U32(0x08000020L), 178 | U32(0x00208000L), U32(0x00008020L), U32(0x08008020L), U32(0x08200000L), 179 | U32(0x00000020L), U32(0x08208000L), U32(0x00208020L), U32(0x00000000L), 180 | U32(0x08000000L), U32(0x08200020L), U32(0x00008000L), U32(0x00208020L), 181 | ], 182 | ] 183 | 184 | #static unsigned long des_skb[8][64]={ 185 | 186 | des_skb = \ 187 | [ 188 | #for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 189 | [ 190 | U32(0x00000000L),U32(0x00000010L),U32(0x20000000L),U32(0x20000010L), 191 | U32(0x00010000L),U32(0x00010010L),U32(0x20010000L),U32(0x20010010L), 192 | U32(0x00000800L),U32(0x00000810L),U32(0x20000800L),U32(0x20000810L), 193 | U32(0x00010800L),U32(0x00010810L),U32(0x20010800L),U32(0x20010810L), 194 | U32(0x00000020L),U32(0x00000030L),U32(0x20000020L),U32(0x20000030L), 195 | U32(0x00010020L),U32(0x00010030L),U32(0x20010020L),U32(0x20010030L), 196 | U32(0x00000820L),U32(0x00000830L),U32(0x20000820L),U32(0x20000830L), 197 | U32(0x00010820L),U32(0x00010830L),U32(0x20010820L),U32(0x20010830L), 198 | U32(0x00080000L),U32(0x00080010L),U32(0x20080000L),U32(0x20080010L), 199 | U32(0x00090000L),U32(0x00090010L),U32(0x20090000L),U32(0x20090010L), 200 | U32(0x00080800L),U32(0x00080810L),U32(0x20080800L),U32(0x20080810L), 201 | U32(0x00090800L),U32(0x00090810L),U32(0x20090800L),U32(0x20090810L), 202 | U32(0x00080020L),U32(0x00080030L),U32(0x20080020L),U32(0x20080030L), 203 | U32(0x00090020L),U32(0x00090030L),U32(0x20090020L),U32(0x20090030L), 204 | U32(0x00080820L),U32(0x00080830L),U32(0x20080820L),U32(0x20080830L), 205 | U32(0x00090820L),U32(0x00090830L),U32(0x20090820L),U32(0x20090830L), 206 | ], 207 | 208 | #for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 209 | [ 210 | U32(0x00000000L),U32(0x02000000L),U32(0x00002000L),U32(0x02002000L), 211 | U32(0x00200000L),U32(0x02200000L),U32(0x00202000L),U32(0x02202000L), 212 | U32(0x00000004L),U32(0x02000004L),U32(0x00002004L),U32(0x02002004L), 213 | U32(0x00200004L),U32(0x02200004L),U32(0x00202004L),U32(0x02202004L), 214 | U32(0x00000400L),U32(0x02000400L),U32(0x00002400L),U32(0x02002400L), 215 | U32(0x00200400L),U32(0x02200400L),U32(0x00202400L),U32(0x02202400L), 216 | U32(0x00000404L),U32(0x02000404L),U32(0x00002404L),U32(0x02002404L), 217 | U32(0x00200404L),U32(0x02200404L),U32(0x00202404L),U32(0x02202404L), 218 | U32(0x10000000L),U32(0x12000000L),U32(0x10002000L),U32(0x12002000L), 219 | U32(0x10200000L),U32(0x12200000L),U32(0x10202000L),U32(0x12202000L), 220 | U32(0x10000004L),U32(0x12000004L),U32(0x10002004L),U32(0x12002004L), 221 | U32(0x10200004L),U32(0x12200004L),U32(0x10202004L),U32(0x12202004L), 222 | U32(0x10000400L),U32(0x12000400L),U32(0x10002400L),U32(0x12002400L), 223 | U32(0x10200400L),U32(0x12200400L),U32(0x10202400L),U32(0x12202400L), 224 | U32(0x10000404L),U32(0x12000404L),U32(0x10002404L),U32(0x12002404L), 225 | U32(0x10200404L),U32(0x12200404L),U32(0x10202404L),U32(0x12202404L), 226 | ], 227 | 228 | #for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 229 | [ 230 | U32(0x00000000L),U32(0x00000001L),U32(0x00040000L),U32(0x00040001L), 231 | U32(0x01000000L),U32(0x01000001L),U32(0x01040000L),U32(0x01040001L), 232 | U32(0x00000002L),U32(0x00000003L),U32(0x00040002L),U32(0x00040003L), 233 | U32(0x01000002L),U32(0x01000003L),U32(0x01040002L),U32(0x01040003L), 234 | U32(0x00000200L),U32(0x00000201L),U32(0x00040200L),U32(0x00040201L), 235 | U32(0x01000200L),U32(0x01000201L),U32(0x01040200L),U32(0x01040201L), 236 | U32(0x00000202L),U32(0x00000203L),U32(0x00040202L),U32(0x00040203L), 237 | U32(0x01000202L),U32(0x01000203L),U32(0x01040202L),U32(0x01040203L), 238 | U32(0x08000000L),U32(0x08000001L),U32(0x08040000L),U32(0x08040001L), 239 | U32(0x09000000L),U32(0x09000001L),U32(0x09040000L),U32(0x09040001L), 240 | U32(0x08000002L),U32(0x08000003L),U32(0x08040002L),U32(0x08040003L), 241 | U32(0x09000002L),U32(0x09000003L),U32(0x09040002L),U32(0x09040003L), 242 | U32(0x08000200L),U32(0x08000201L),U32(0x08040200L),U32(0x08040201L), 243 | U32(0x09000200L),U32(0x09000201L),U32(0x09040200L),U32(0x09040201L), 244 | U32(0x08000202L),U32(0x08000203L),U32(0x08040202L),U32(0x08040203L), 245 | U32(0x09000202L),U32(0x09000203L),U32(0x09040202L),U32(0x09040203L), 246 | ], 247 | 248 | #for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 249 | [ 250 | U32(0x00000000L),U32(0x00100000L),U32(0x00000100L),U32(0x00100100L), 251 | U32(0x00000008L),U32(0x00100008L),U32(0x00000108L),U32(0x00100108L), 252 | U32(0x00001000L),U32(0x00101000L),U32(0x00001100L),U32(0x00101100L), 253 | U32(0x00001008L),U32(0x00101008L),U32(0x00001108L),U32(0x00101108L), 254 | U32(0x04000000L),U32(0x04100000L),U32(0x04000100L),U32(0x04100100L), 255 | U32(0x04000008L),U32(0x04100008L),U32(0x04000108L),U32(0x04100108L), 256 | U32(0x04001000L),U32(0x04101000L),U32(0x04001100L),U32(0x04101100L), 257 | U32(0x04001008L),U32(0x04101008L),U32(0x04001108L),U32(0x04101108L), 258 | U32(0x00020000L),U32(0x00120000L),U32(0x00020100L),U32(0x00120100L), 259 | U32(0x00020008L),U32(0x00120008L),U32(0x00020108L),U32(0x00120108L), 260 | U32(0x00021000L),U32(0x00121000L),U32(0x00021100L),U32(0x00121100L), 261 | U32(0x00021008L),U32(0x00121008L),U32(0x00021108L),U32(0x00121108L), 262 | U32(0x04020000L),U32(0x04120000L),U32(0x04020100L),U32(0x04120100L), 263 | U32(0x04020008L),U32(0x04120008L),U32(0x04020108L),U32(0x04120108L), 264 | U32(0x04021000L),U32(0x04121000L),U32(0x04021100L),U32(0x04121100L), 265 | U32(0x04021008L),U32(0x04121008L),U32(0x04021108L),U32(0x04121108L), 266 | ], 267 | 268 | #for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 269 | [ 270 | U32(0x00000000L),U32(0x10000000L),U32(0x00010000L),U32(0x10010000L), 271 | U32(0x00000004L),U32(0x10000004L),U32(0x00010004L),U32(0x10010004L), 272 | U32(0x20000000L),U32(0x30000000L),U32(0x20010000L),U32(0x30010000L), 273 | U32(0x20000004L),U32(0x30000004L),U32(0x20010004L),U32(0x30010004L), 274 | U32(0x00100000L),U32(0x10100000L),U32(0x00110000L),U32(0x10110000L), 275 | U32(0x00100004L),U32(0x10100004L),U32(0x00110004L),U32(0x10110004L), 276 | U32(0x20100000L),U32(0x30100000L),U32(0x20110000L),U32(0x30110000L), 277 | U32(0x20100004L),U32(0x30100004L),U32(0x20110004L),U32(0x30110004L), 278 | U32(0x00001000L),U32(0x10001000L),U32(0x00011000L),U32(0x10011000L), 279 | U32(0x00001004L),U32(0x10001004L),U32(0x00011004L),U32(0x10011004L), 280 | U32(0x20001000L),U32(0x30001000L),U32(0x20011000L),U32(0x30011000L), 281 | U32(0x20001004L),U32(0x30001004L),U32(0x20011004L),U32(0x30011004L), 282 | U32(0x00101000L),U32(0x10101000L),U32(0x00111000L),U32(0x10111000L), 283 | U32(0x00101004L),U32(0x10101004L),U32(0x00111004L),U32(0x10111004L), 284 | U32(0x20101000L),U32(0x30101000L),U32(0x20111000L),U32(0x30111000L), 285 | U32(0x20101004L),U32(0x30101004L),U32(0x20111004L),U32(0x30111004L), 286 | ], 287 | 288 | #for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 289 | [ 290 | U32(0x00000000L),U32(0x08000000L),U32(0x00000008L),U32(0x08000008L), 291 | U32(0x00000400L),U32(0x08000400L),U32(0x00000408L),U32(0x08000408L), 292 | U32(0x00020000L),U32(0x08020000L),U32(0x00020008L),U32(0x08020008L), 293 | U32(0x00020400L),U32(0x08020400L),U32(0x00020408L),U32(0x08020408L), 294 | U32(0x00000001L),U32(0x08000001L),U32(0x00000009L),U32(0x08000009L), 295 | U32(0x00000401L),U32(0x08000401L),U32(0x00000409L),U32(0x08000409L), 296 | U32(0x00020001L),U32(0x08020001L),U32(0x00020009L),U32(0x08020009L), 297 | U32(0x00020401L),U32(0x08020401L),U32(0x00020409L),U32(0x08020409L), 298 | U32(0x02000000L),U32(0x0A000000L),U32(0x02000008L),U32(0x0A000008L), 299 | U32(0x02000400L),U32(0x0A000400L),U32(0x02000408L),U32(0x0A000408L), 300 | U32(0x02020000L),U32(0x0A020000L),U32(0x02020008L),U32(0x0A020008L), 301 | U32(0x02020400L),U32(0x0A020400L),U32(0x02020408L),U32(0x0A020408L), 302 | U32(0x02000001L),U32(0x0A000001L),U32(0x02000009L),U32(0x0A000009L), 303 | U32(0x02000401L),U32(0x0A000401L),U32(0x02000409L),U32(0x0A000409L), 304 | U32(0x02020001L),U32(0x0A020001L),U32(0x02020009L),U32(0x0A020009L), 305 | U32(0x02020401L),U32(0x0A020401L),U32(0x02020409L),U32(0x0A020409L), 306 | ], 307 | 308 | #for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 309 | [ 310 | U32(0x00000000L),U32(0x00000100L),U32(0x00080000L),U32(0x00080100L), 311 | U32(0x01000000L),U32(0x01000100L),U32(0x01080000L),U32(0x01080100L), 312 | U32(0x00000010L),U32(0x00000110L),U32(0x00080010L),U32(0x00080110L), 313 | U32(0x01000010L),U32(0x01000110L),U32(0x01080010L),U32(0x01080110L), 314 | U32(0x00200000L),U32(0x00200100L),U32(0x00280000L),U32(0x00280100L), 315 | U32(0x01200000L),U32(0x01200100L),U32(0x01280000L),U32(0x01280100L), 316 | U32(0x00200010L),U32(0x00200110L),U32(0x00280010L),U32(0x00280110L), 317 | U32(0x01200010L),U32(0x01200110L),U32(0x01280010L),U32(0x01280110L), 318 | U32(0x00000200L),U32(0x00000300L),U32(0x00080200L),U32(0x00080300L), 319 | U32(0x01000200L),U32(0x01000300L),U32(0x01080200L),U32(0x01080300L), 320 | U32(0x00000210L),U32(0x00000310L),U32(0x00080210L),U32(0x00080310L), 321 | U32(0x01000210L),U32(0x01000310L),U32(0x01080210L),U32(0x01080310L), 322 | U32(0x00200200L),U32(0x00200300L),U32(0x00280200L),U32(0x00280300L), 323 | U32(0x01200200L),U32(0x01200300L),U32(0x01280200L),U32(0x01280300L), 324 | U32(0x00200210L),U32(0x00200310L),U32(0x00280210L),U32(0x00280310L), 325 | U32(0x01200210L),U32(0x01200310L),U32(0x01280210L),U32(0x01280310L), 326 | ], 327 | 328 | #for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 329 | [ 330 | U32(0x00000000L),U32(0x04000000L),U32(0x00040000L),U32(0x04040000L), 331 | U32(0x00000002L),U32(0x04000002L),U32(0x00040002L),U32(0x04040002L), 332 | U32(0x00002000L),U32(0x04002000L),U32(0x00042000L),U32(0x04042000L), 333 | U32(0x00002002L),U32(0x04002002L),U32(0x00042002L),U32(0x04042002L), 334 | U32(0x00000020L),U32(0x04000020L),U32(0x00040020L),U32(0x04040020L), 335 | U32(0x00000022L),U32(0x04000022L),U32(0x00040022L),U32(0x04040022L), 336 | U32(0x00002020L),U32(0x04002020L),U32(0x00042020L),U32(0x04042020L), 337 | U32(0x00002022L),U32(0x04002022L),U32(0x00042022L),U32(0x04042022L), 338 | U32(0x00000800L),U32(0x04000800L),U32(0x00040800L),U32(0x04040800L), 339 | U32(0x00000802L),U32(0x04000802L),U32(0x00040802L),U32(0x04040802L), 340 | U32(0x00002800L),U32(0x04002800L),U32(0x00042800L),U32(0x04042800L), 341 | U32(0x00002802L),U32(0x04002802L),U32(0x00042802L),U32(0x04042802L), 342 | U32(0x00000820L),U32(0x04000820L),U32(0x00040820L),U32(0x04040820L), 343 | U32(0x00000822L),U32(0x04000822L),U32(0x00040822L),U32(0x04040822L), 344 | U32(0x00002820L),U32(0x04002820L),U32(0x00042820L),U32(0x04042820L), 345 | U32(0x00002822L),U32(0x04002822L),U32(0x00042822L),U32(0x04042822L), 346 | ] 347 | 348 | ] -------------------------------------------------------------------------------- /python26/ntlm/ntlm.py: -------------------------------------------------------------------------------- 1 | # This library is free software: you can redistribute it and/or 2 | # modify it under the terms of the GNU Lesser General Public 3 | # License as published by the Free Software Foundation, either 4 | # version 3 of the License, or (at your option) any later version. 5 | 6 | # This library is distributed in the hope that it will be useful, 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | # Lesser General Public License for more details. 10 | # 11 | # You should have received a copy of the GNU Lesser General Public 12 | # License along with this library. If not, see or . 13 | 14 | import struct 15 | import base64 16 | import string 17 | import des 18 | import hashlib 19 | import hmac 20 | import random 21 | import re 22 | import binascii 23 | from socket import gethostname 24 | 25 | NTLM_NegotiateUnicode = 0x00000001 26 | NTLM_NegotiateOEM = 0x00000002 27 | NTLM_RequestTarget = 0x00000004 28 | NTLM_Unknown9 = 0x00000008 29 | NTLM_NegotiateSign = 0x00000010 30 | NTLM_NegotiateSeal = 0x00000020 31 | NTLM_NegotiateDatagram = 0x00000040 32 | NTLM_NegotiateLanManagerKey = 0x00000080 33 | NTLM_Unknown8 = 0x00000100 34 | NTLM_NegotiateNTLM = 0x00000200 35 | NTLM_NegotiateNTOnly = 0x00000400 36 | NTLM_Anonymous = 0x00000800 37 | NTLM_NegotiateOemDomainSupplied = 0x00001000 38 | NTLM_NegotiateOemWorkstationSupplied = 0x00002000 39 | NTLM_Unknown6 = 0x00004000 40 | NTLM_NegotiateAlwaysSign = 0x00008000 41 | NTLM_TargetTypeDomain = 0x00010000 42 | NTLM_TargetTypeServer = 0x00020000 43 | NTLM_TargetTypeShare = 0x00040000 44 | NTLM_NegotiateExtendedSecurity = 0x00080000 45 | NTLM_NegotiateIdentify = 0x00100000 46 | NTLM_Unknown5 = 0x00200000 47 | NTLM_RequestNonNTSessionKey = 0x00400000 48 | NTLM_NegotiateTargetInfo = 0x00800000 49 | NTLM_Unknown4 = 0x01000000 50 | NTLM_NegotiateVersion = 0x02000000 51 | NTLM_Unknown3 = 0x04000000 52 | NTLM_Unknown2 = 0x08000000 53 | NTLM_Unknown1 = 0x10000000 54 | NTLM_Negotiate128 = 0x20000000 55 | NTLM_NegotiateKeyExchange = 0x40000000 56 | NTLM_Negotiate56 = 0x80000000 57 | 58 | # we send these flags with our type 1 message 59 | NTLM_TYPE1_FLAGS = (NTLM_NegotiateUnicode | \ 60 | NTLM_NegotiateOEM | \ 61 | NTLM_RequestTarget | \ 62 | NTLM_NegotiateNTLM | \ 63 | NTLM_NegotiateOemDomainSupplied | \ 64 | NTLM_NegotiateOemWorkstationSupplied | \ 65 | NTLM_NegotiateAlwaysSign | \ 66 | NTLM_NegotiateExtendedSecurity | \ 67 | NTLM_NegotiateVersion | \ 68 | NTLM_Negotiate128 | \ 69 | NTLM_Negotiate56 ) 70 | NTLM_TYPE2_FLAGS = (NTLM_NegotiateUnicode | \ 71 | NTLM_RequestTarget | \ 72 | NTLM_NegotiateNTLM | \ 73 | NTLM_NegotiateAlwaysSign | \ 74 | NTLM_NegotiateExtendedSecurity | \ 75 | NTLM_NegotiateTargetInfo | \ 76 | NTLM_NegotiateVersion | \ 77 | NTLM_Negotiate128 | \ 78 | NTLM_Negotiate56) 79 | 80 | NTLM_MsvAvEOL = 0 # Indicates that this is the last AV_PAIR in the list. AvLen MUST be 0. This type of information MUST be present in the AV pair list. 81 | NTLM_MsvAvNbComputerName = 1 # The server's NetBIOS computer name. The name MUST be in Unicode, and is not null-terminated. This type of information MUST be present in the AV_pair list. 82 | NTLM_MsvAvNbDomainName = 2 # The server's NetBIOS domain name. The name MUST be in Unicode, and is not null-terminated. This type of information MUST be present in the AV_pair list. 83 | NTLM_MsvAvDnsComputerName = 3 # The server's Active Directory DNS computer name. The name MUST be in Unicode, and is not null-terminated. 84 | NTLM_MsvAvDnsDomainName = 4 # The server's Active Directory DNS domain name. The name MUST be in Unicode, and is not null-terminated. 85 | NTLM_MsvAvDnsTreeName = 5 # The server's Active Directory (AD) DNS forest tree name. The name MUST be in Unicode, and is not null-terminated. 86 | NTLM_MsvAvFlags = 6 # A field containing a 32-bit value indicating server or client configuration. 0x00000001: indicates to the client that the account authentication is constrained. 0x00000002: indicates that the client is providing message integrity in the MIC field (section 2.2.1.3) in the AUTHENTICATE_MESSAGE. 87 | NTLM_MsvAvTimestamp = 7 # A FILETIME structure ([MS-DTYP] section 2.3.1) in little-endian byte order that contains the server local time.<12> 88 | NTLM_MsAvRestrictions = 8 #A Restriction_Encoding structure (section 2.2.2.2). The Value field contains a structure representing the integrity level of the security principal, as well as a MachineID created at computer startup to identify the calling machine. <13> 89 | 90 | 91 | """ 92 | utility functions for Microsoft NTLM authentication 93 | 94 | References: 95 | [MS-NLMP]: NT LAN Manager (NTLM) Authentication Protocol Specification 96 | http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-NLMP%5D.pdf 97 | 98 | [MS-NTHT]: NTLM Over HTTP Protocol Specification 99 | http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-NTHT%5D.pdf 100 | 101 | Cntlm Authentication Proxy 102 | http://cntlm.awk.cz/ 103 | 104 | NTLM Authorization Proxy Server 105 | http://sourceforge.net/projects/ntlmaps/ 106 | 107 | Optimized Attack for NTLM2 Session Response 108 | http://www.blackhat.com/presentations/bh-asia-04/bh-jp-04-pdfs/bh-jp-04-seki.pdf 109 | """ 110 | def dump_NegotiateFlags(NegotiateFlags): 111 | if NegotiateFlags & NTLM_NegotiateUnicode: 112 | print "NTLM_NegotiateUnicode set" 113 | if NegotiateFlags & NTLM_NegotiateOEM: 114 | print "NTLM_NegotiateOEM set" 115 | if NegotiateFlags & NTLM_RequestTarget: 116 | print "NTLM_RequestTarget set" 117 | if NegotiateFlags & NTLM_Unknown9: 118 | print "NTLM_Unknown9 set" 119 | if NegotiateFlags & NTLM_NegotiateSign: 120 | print "NTLM_NegotiateSign set" 121 | if NegotiateFlags & NTLM_NegotiateSeal: 122 | print "NTLM_NegotiateSeal set" 123 | if NegotiateFlags & NTLM_NegotiateDatagram: 124 | print "NTLM_NegotiateDatagram set" 125 | if NegotiateFlags & NTLM_NegotiateLanManagerKey: 126 | print "NTLM_NegotiateLanManagerKey set" 127 | if NegotiateFlags & NTLM_Unknown8: 128 | print "NTLM_Unknown8 set" 129 | if NegotiateFlags & NTLM_NegotiateNTLM: 130 | print "NTLM_NegotiateNTLM set" 131 | if NegotiateFlags & NTLM_NegotiateNTOnly: 132 | print "NTLM_NegotiateNTOnly set" 133 | if NegotiateFlags & NTLM_Anonymous: 134 | print "NTLM_Anonymous set" 135 | if NegotiateFlags & NTLM_NegotiateOemDomainSupplied: 136 | print "NTLM_NegotiateOemDomainSupplied set" 137 | if NegotiateFlags & NTLM_NegotiateOemWorkstationSupplied: 138 | print "NTLM_NegotiateOemWorkstationSupplied set" 139 | if NegotiateFlags & NTLM_Unknown6: 140 | print "NTLM_Unknown6 set" 141 | if NegotiateFlags & NTLM_NegotiateAlwaysSign: 142 | print "NTLM_NegotiateAlwaysSign set" 143 | if NegotiateFlags & NTLM_TargetTypeDomain: 144 | print "NTLM_TargetTypeDomain set" 145 | if NegotiateFlags & NTLM_TargetTypeServer: 146 | print "NTLM_TargetTypeServer set" 147 | if NegotiateFlags & NTLM_TargetTypeShare: 148 | print "NTLM_TargetTypeShare set" 149 | if NegotiateFlags & NTLM_NegotiateExtendedSecurity: 150 | print "NTLM_NegotiateExtendedSecurity set" 151 | if NegotiateFlags & NTLM_NegotiateIdentify: 152 | print "NTLM_NegotiateIdentify set" 153 | if NegotiateFlags & NTLM_Unknown5: 154 | print "NTLM_Unknown5 set" 155 | if NegotiateFlags & NTLM_RequestNonNTSessionKey: 156 | print "NTLM_RequestNonNTSessionKey set" 157 | if NegotiateFlags & NTLM_NegotiateTargetInfo: 158 | print "NTLM_NegotiateTargetInfo set" 159 | if NegotiateFlags & NTLM_Unknown4: 160 | print "NTLM_Unknown4 set" 161 | if NegotiateFlags & NTLM_NegotiateVersion: 162 | print "NTLM_NegotiateVersion set" 163 | if NegotiateFlags & NTLM_Unknown3: 164 | print "NTLM_Unknown3 set" 165 | if NegotiateFlags & NTLM_Unknown2: 166 | print "NTLM_Unknown2 set" 167 | if NegotiateFlags & NTLM_Unknown1: 168 | print "NTLM_Unknown1 set" 169 | if NegotiateFlags & NTLM_Negotiate128: 170 | print "NTLM_Negotiate128 set" 171 | if NegotiateFlags & NTLM_NegotiateKeyExchange: 172 | print "NTLM_NegotiateKeyExchange set" 173 | if NegotiateFlags & NTLM_Negotiate56: 174 | print "NTLM_Negotiate56 set" 175 | 176 | def create_NTLM_NEGOTIATE_MESSAGE(user, type1_flags=NTLM_TYPE1_FLAGS): 177 | BODY_LENGTH = 40 178 | Payload_start = BODY_LENGTH # in bytes 179 | protocol = 'NTLMSSP\0' #name 180 | 181 | type = struct.pack(' 3 | 4 | This downloads an NTML-protected webpage to stdout. The username is 5 | constructed from the USERDOMAIN and USERNAME environment variables. 6 | Note that the password is entered on the command line; this is almost 7 | certainly a security risk but unfortunately I know of no foolproof 8 | method in Python for prompting for a password from standard input. 9 | 10 | This script associates the password with all URLs using the same base 11 | URI. Although we only connect to a single URL, this would allow 12 | access to all resources within a single domain. This script also 13 | allows the use of basic and digest authentication as well as NTML. 14 | Finally, it disables the use of proxies, which would prevent it from 15 | leaving most corporate domains (which typically route external 16 | requests through a proxy server). 17 | """ 18 | 19 | import urllib2 20 | from urlparse import urlparse, urlunparse 21 | import inspect, os, sys 22 | 23 | try: 24 | from ntlm import HTTPNtlmAuthHandler 25 | except ImportError: 26 | # assume ntlm is in the directory "next door" 27 | ntlm_folder = os.path.realpath(os.path.join( 28 | os.path.dirname(inspect.getfile(inspect.currentframe())), 29 | '..')) 30 | sys.path.insert(0, ntlm_folder) 31 | from ntlm import HTTPNtlmAuthHandler 32 | 33 | def process(password, url): 34 | user = '%s\%s' % ( os.environ["USERDOMAIN"], os.environ["USERNAME"] ) 35 | 36 | # determine a base_uri for which the username and password can be used 37 | parsed_url = urlparse(url) 38 | base_uri = urlunparse((parsed_url[0],parsed_url[1],"","","","")) 39 | 40 | passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 41 | passman.add_password(None, base_uri, user, password) 42 | # create the NTLM authentication handler 43 | auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman) 44 | 45 | # other authentication handlers 46 | auth_basic = urllib2.HTTPBasicAuthHandler(passman) 47 | auth_digest = urllib2.HTTPDigestAuthHandler(passman) 48 | 49 | # disable proxies (if you want to stay within the corporate network) 50 | proxy_handler = urllib2.ProxyHandler({}) 51 | 52 | # create and install the opener 53 | opener = urllib2.build_opener(proxy_handler, auth_NTLM, auth_digest, auth_basic) 54 | urllib2.install_opener(opener) 55 | 56 | # retrieve the result 57 | response = urllib2.urlopen(url) 58 | print(response.read()) 59 | 60 | # The following is adapted from Guido van van Rossum's suggestion. 61 | # http://www.artima.com/weblogs/viewpost.jsp?thread=4829 62 | 63 | class Usage(Exception): 64 | def __init__(self, msg): 65 | self.msg = msg 66 | 67 | import sys 68 | import getopt 69 | 70 | def main(argv=None): 71 | if argv is None: 72 | argv = sys.argv 73 | try: 74 | try: 75 | opts, args = getopt.getopt(argv[1:], "h", ["help"]) 76 | except getopt.error, msg: 77 | raise Usage(msg) 78 | if opts: 79 | raise Usage(__doc__) 80 | if len(args) != 2: 81 | raise Usage('need exactly 2 arguments (%d given)' % len(args)) 82 | process(*args) 83 | except Usage, err: 84 | print >>sys.stderr, err.msg 85 | if err.msg is not __doc__: 86 | print >>sys.stderr, "for help use --help" 87 | return 2 88 | 89 | if __name__ == "__main__": 90 | sys.exit(main()) 91 | -------------------------------------------------------------------------------- /python26/ntlm_examples/simple.py: -------------------------------------------------------------------------------- 1 | """ 2 | Usage: simple.py 3 | 4 | This downloads an NTML-protected webpage to stdout. The username is 5 | constructed from the USERDOMAIN and USERNAME environment variables. 6 | Note that the password is entered on the command line; this is almost 7 | certainly a security risk but unfortunately I know of no foolproof 8 | method in Python for prompting for a password from standard input. 9 | 10 | This script only understands NTML authentication. 11 | """ 12 | 13 | import urllib2 14 | import inspect, os, sys 15 | 16 | try: 17 | from ntlm import HTTPNtlmAuthHandler 18 | except ImportError: 19 | # assume ntlm is in the directory "next door" 20 | ntlm_folder = os.path.realpath(os.path.join( 21 | os.path.dirname(inspect.getfile(inspect.currentframe())), 22 | '..')) 23 | sys.path.insert(0, ntlm_folder) 24 | from ntlm import HTTPNtlmAuthHandler 25 | 26 | def process(password, url): 27 | user = '%s\%s' % ( os.environ["USERDOMAIN"], os.environ["USERNAME"] ) 28 | 29 | passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 30 | passman.add_password(None, url, user, password) 31 | # create the NTLM authentication handler 32 | auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman) 33 | 34 | # create and install the opener 35 | opener = urllib2.build_opener(auth_NTLM) 36 | urllib2.install_opener(opener) 37 | 38 | # retrieve the result 39 | response = urllib2.urlopen(url) 40 | print(response.read()) 41 | 42 | # The following is adapted from Guido van van Rossum's suggestion. 43 | # http://www.artima.com/weblogs/viewpost.jsp?thread=4829 44 | 45 | class Usage(Exception): 46 | def __init__(self, msg): 47 | self.msg = msg 48 | 49 | import sys 50 | import getopt 51 | 52 | def main(argv=None): 53 | if argv is None: 54 | argv = sys.argv 55 | try: 56 | try: 57 | opts, args = getopt.getopt(argv[1:], "h", ["help"]) 58 | except getopt.error, msg: 59 | raise Usage(msg) 60 | if opts: 61 | raise Usage(__doc__) 62 | if len(args) != 2: 63 | raise Usage('need exactly 2 arguments (%d given)' % len(args)) 64 | process(*args) 65 | except Usage, err: 66 | print >>sys.stderr, err.msg 67 | if err.msg is not __doc__: 68 | print >>sys.stderr, "for help use --help" 69 | return 2 70 | 71 | if __name__ == "__main__": 72 | sys.exit(main()) 73 | -------------------------------------------------------------------------------- /python26/ntlm_examples/test_ntlmauth.py: -------------------------------------------------------------------------------- 1 | """\ 2 | Demonstrate various defects (or their repair!) in the ntml module. 3 | """ 4 | 5 | 6 | from StringIO import StringIO 7 | import httplib 8 | import inspect, os, sys 9 | import traceback 10 | import urllib2 11 | try: 12 | from ntlm import HTTPNtlmAuthHandler 13 | except ImportError: 14 | # assume ntlm is in the directory "next door" 15 | ntlm_folder = os.path.realpath(os.path.join( 16 | os.path.dirname(inspect.getfile(inspect.currentframe())), 17 | '..')) 18 | sys.path.insert(0, ntlm_folder) 19 | from ntlm import HTTPNtlmAuthHandler 20 | 21 | 22 | # The headers seen during an initial NTML rejection. 23 | initial_rejection = '''HTTP/1.1 401 Unauthorized 24 | Server: Apache-Coyote/1.1 25 | WWW-Authenticate: NTLM 26 | Connection: close 27 | Date: Tue, 03 Feb 2009 11:47:33 GMT 28 | Connection: close 29 | 30 | ''' 31 | 32 | 33 | # The headers and data seen following a successful NTML connection. 34 | eventual_success = '''HTTP/1.1 200 OK 35 | Server: Apache-Coyote/1.1 36 | WWW-Authenticate: NTLM TlRMTVNTUAACAAAABAAEADgAAAAFgomi3k7KRx+HGYQAAAAAAAAAALQAtAA8AAAABgGwHQAAAA9OAEEAAgAEAE4AQQABABYATgBBAFMAQQBOAEUAWABIAEMAMAA0AAQAHgBuAGEALgBxAHUAYQBsAGMAbwBtAG0ALgBjAG8AbQADADYAbgBhAHMAYQBuAGUAeABoAGMAMAA0AC4AbgBhAC4AcQB1AGEAbABjAG8AbQBtAC4AYwBvAG0ABQAiAGMAbwByAHAALgBxAHUAYQBsAGMAbwBtAG0ALgBjAG8AbQAHAAgADXHouNLjzAEAAAAA 37 | Date: Tue, 03 Feb 2009 11:47:33 GMT 38 | Connection: close 39 | 40 | Hello, world!''' 41 | 42 | 43 | # A collection of transactions representing various defects in NTLM 44 | # processing. Each is indexed according the the issues number recorded 45 | # for the defect at code.google.com, and consists of a series of server 46 | # responses that should be seen as a connection is attempted. 47 | issues = { 48 | 27: [ 49 | initial_rejection, 50 | '''HTTP/1.1 401 Unauthorized 51 | Server: Apache-Coyote/1.1 52 | WWW-Authenticate: NTLM TlRMTVNTUAACAAAABAAEADgAAAAFgomi3k7KRx+HGYQAAAAAAAAAALQAtAA8AAAABgGwHQAAAA9OAEEAAgAEAE4AQQABABYATgBBAFMAQQBOAEUAWABIAEMAMAA0AAQAHgBuAGEALgBxAHUAYQBsAGMAbwBtAG0ALgBjAG8AbQADADYAbgBhAHMAYQBuAGUAeABoAGMAMAA0AC4AbgBhAC4AcQB1AGEAbABjAG8AbQBtAC4AYwBvAG0ABQAiAGMAbwByAHAALgBxAHUAYQBsAGMAbwBtAG0ALgBjAG8AbQAHAAgADXHouNLjzAEAAAAA 53 | WWW-Authenticate: Negotiate 54 | Content-Length: 0 55 | Date: Tue, 03 Feb 2009 11:47:33 GMT 56 | Connection: close 57 | 58 | ''', 59 | eventual_success, 60 | ], 61 | 28: [ 62 | initial_rejection, 63 | '''HTTP/1.1 401 Unauthorized 64 | Server: Apache-Coyote/1.1 65 | WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAAAAAAAABAgAAO/AU3OJc3g0= 66 | Content-Length: 0 67 | Date: Tue, 03 Feb 2009 11:47:33 GMT 68 | Connection: close 69 | 70 | ''', 71 | eventual_success, 72 | ], 73 | } 74 | 75 | 76 | class FakeSocket(StringIO): 77 | '''Extends StringIO just enough to look like a socket.''' 78 | def makefile(self, *args, **kwds): 79 | '''The instance already looks like a file.''' 80 | return self 81 | def sendall(self, *args, **kwds): 82 | '''Ignore any data that may be sent.''' 83 | pass 84 | def close(self): 85 | '''Ignore any calls to close.''' 86 | pass 87 | 88 | 89 | class FakeHTTPConnection(httplib.HTTPConnection): 90 | '''Looks like a normal HTTPConnection, but returns a FakeSocket. 91 | The connection's port number is used to choose a set of transactions 92 | to replay to the user. A class static variable is used to track 93 | how many transactions have been replayed.''' 94 | attempt = {} 95 | def connect(self): 96 | '''Returns a FakeSocket containing the data for a single 97 | transaction.''' 98 | nbr = self.attempt.setdefault(self.port, 0) 99 | self.attempt[self.port] = nbr + 1 100 | print 'connecting to %s:%s (attempt %s)' % (self.host, self.port, nbr) 101 | self.sock = FakeSocket(issues[self.port][nbr]) 102 | 103 | 104 | class FakeHTTPHandler(urllib2.HTTPHandler): 105 | connection = FakeHTTPConnection 106 | def http_open(self, req): 107 | print 'opening', self.connection 108 | return self.do_open(self.connection, req) 109 | 110 | 111 | def process(*issue_nbrs): 112 | '''Run the specified tests, or all of them.''' 113 | 114 | if issue_nbrs: 115 | # Make sure the tests are ints. 116 | issue_nbrs = map(int, issue_nbrs) 117 | else: 118 | # If no tests were specified, run them all. 119 | issue_nbrs = issues.keys() 120 | 121 | assert all(i in issues for i in issue_nbrs) 122 | 123 | user = 'DOMAIN\User' 124 | password = "Password" 125 | url = "http://www.example.org:%s/" 126 | 127 | # Set passwords for each of the "servers" to which we will be connecting. 128 | # Each distinct port on a server requires it's own set of credentials. 129 | passman = urllib2.HTTPPasswordMgrWithDefaultRealm() 130 | for k in issue_nbrs: 131 | passman.add_password(None, url % k, user, password) 132 | 133 | # Create the NTLM authentication handler. 134 | auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman, debuglevel=0) 135 | 136 | # Create and install openers for both the NTLM Auth handler and 137 | # our fake HTTP handler. 138 | opener = urllib2.build_opener(auth_NTLM, FakeHTTPHandler) 139 | urllib2.install_opener(opener) 140 | 141 | # The following is a massive kludge; let me explain why it is needed. 142 | HTTPNtlmAuthHandler.httplib.HTTPConnection = FakeHTTPConnection 143 | # At the heart of the urllib2 module is the opener director. Whenever a 144 | # URL is opened, the director is responsible for locating the proper 145 | # handler for the protocol specified in the URL. Frequently, an existing 146 | # protocol handler will be subclassed and then added to the collection 147 | # maintained by the director. When urlopen is called, the specified 148 | # request is immediately handed off to the director's "open" method 149 | # which finds the correct handler and invokes the protocol-specific 150 | # XXX_open method. At least in the case of the HTTP protocols, if an 151 | # error occurs then the director is called again to find and invoke a 152 | # handler for the error; these handlers generally open a new connection 153 | # after adding headers to avoid the error going forward. Finally, it is 154 | # important to note that at the present time, the HTTP handlers in 155 | # urllib2 are built using a class that isn't prepared to deal with a 156 | # persistent connection, so they always add a "Connection: close" header 157 | # to the request. 158 | # 159 | # Unfortunately, NTLM only certifies the current connection, meaning 160 | # that a "Connection: keep-alive" header must be used to keep it open 161 | # throughout the authentication process. Furthermore, because the opener 162 | # director only provides a do_open method, there is no way to discover 163 | # the type of connection without also opening it. This means that the 164 | # HTTPNtlmAuthHandler cannot use the normal HTTPHandler and must 165 | # therefore must hardcode the HTTPConnection class. If a custom class is 166 | # required for whatever reason, the only way to cause it to be used is 167 | # to monkey-patch the code, as is done in the line above. 168 | 169 | for i in sorted(issue_nbrs): 170 | print '\nissue %d' % i 171 | try: 172 | f = urllib2.urlopen(url % i) 173 | except: 174 | traceback.print_exc() 175 | else: 176 | print f.read() 177 | 178 | 179 | # The following is adapted from Guido van van Rossum's suggestion. 180 | # http://www.artima.com/weblogs/viewpost.jsp?thread=4829 181 | 182 | import sys 183 | import getopt 184 | 185 | class Usage(Exception): 186 | def __init__(self, msg): 187 | self.msg = msg 188 | 189 | def main(argv=None): 190 | """Usage: %s""" 191 | if argv is None: 192 | argv = sys.argv 193 | try: 194 | try: 195 | opts, args = getopt.getopt(argv[1:], "h", ["help"]) 196 | except getopt.error, msg: 197 | raise Usage(msg) 198 | if opts: 199 | raise Usage(main.func_doc) 200 | if len(args) > 0: 201 | raise Usage('takes no arguments (%d given)' % len(args)) 202 | process(*args) 203 | except Usage, err: 204 | print >>sys.stderr, err.msg 205 | if err.msg is not main.func_doc: 206 | print >>sys.stderr, "for help use --help" 207 | return 2 208 | main.func_doc %= os.path.basename(sys.argv[0]) 209 | 210 | if __name__ == "__main__": 211 | sys.exit(main()) 212 | -------------------------------------------------------------------------------- /python26/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | import os 3 | import sys 4 | 5 | SRC_FOLDER = "src" 6 | 7 | ENTRY_POINTS = { "console_scripts":[ "ntlm_example_simple=ntlm_examples.simple:main", 8 | "ntlm_example_extended=ntlm_examples.extended:main",] } 9 | 10 | setup(name='python-ntlm', 11 | version='1.1.0', 12 | description='Python library that provides NTLM support, including an authentication handler for urllib2. Works with pass-the-hash in addition to password authentication.', 13 | long_description=""" 14 | This package allows Python clients running on any operating 15 | system to provide NTLM authentication to a supporting server. 16 | 17 | python-ntlm is probably most useful on platforms that are not 18 | Windows, since on Windows it is possible to take advantage of 19 | platform-specific NTLM support. 20 | 21 | This is also useful for passing hashes to servers requiring 22 | ntlm authentication in instances where using windows tools is 23 | not desirable.""", 24 | author='Matthijs Mullender', 25 | author_email='info@zopyx.org', 26 | maintainer='Daniel Holth', 27 | maintainer_email='dholth@gmail.com', 28 | url="http://code.google.com/p/python-ntlm", 29 | packages=["ntlm",], 30 | zip_safe=False, 31 | entry_points = ENTRY_POINTS, 32 | license="GNU Lesser GPL", 33 | # See https://pypi.python.org/pypi?%3Aaction=list_classifiers 34 | classifiers=[ 35 | "License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)" 36 | # Specify the Python versions you support here. In particular, ensure 37 | # that you indicate whether you support Python 2, Python 3 or both. 38 | 'Programming Language :: Python :: 2', 39 | 'Programming Language :: Python :: 2.6', 40 | 'Programming Language :: Python :: 2.7', 41 | ], 42 | ) 43 | -------------------------------------------------------------------------------- /python30/ntlm/HTTPNtlmAuthHandler.py: -------------------------------------------------------------------------------- 1 | # This library is free software: you can redistribute it and/or 2 | # modify it under the terms of the GNU Lesser General Public 3 | # License as published by the Free Software Foundation, either 4 | # version 3 of the License, or (at your option) any later version. 5 | 6 | # This library is distributed in the hope that it will be useful, 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | # Lesser General Public License for more details. 10 | # 11 | # You should have received a copy of the GNU Lesser General Public 12 | # License along with this library. If not, see or . 13 | 14 | import urllib.request, urllib.error 15 | import http.client, socket 16 | from urllib.response import addinfourl 17 | try: 18 | from . import ntlm 19 | except ValueError: 20 | import ntlm 21 | import re 22 | 23 | class AbstractNtlmAuthHandler: 24 | 25 | def __init__(self, password_mgr=None): 26 | if password_mgr is None: 27 | password_mgr = HTTPPasswordMgr() 28 | self.passwd = password_mgr 29 | self.add_password = self.passwd.add_password 30 | 31 | def http_error_authentication_required(self, auth_header_field, req, fp, headers): 32 | auth_header_value_list = headers.get_all(auth_header_field) 33 | if auth_header_value_list: 34 | if any([hv.lower() == 'ntlm' for hv in auth_header_value_list]): 35 | fp.close() 36 | return self.retry_using_http_NTLM_auth(req, auth_header_field, None, headers) 37 | 38 | def retry_using_http_NTLM_auth(self, req, auth_header_field, realm, headers): 39 | user, pw = self.passwd.find_user_password(realm, req.get_full_url()) 40 | if pw is not None: 41 | user_parts = user.split('\\', 1) 42 | if len(user_parts) == 1: 43 | UserName = user_parts[0] 44 | DomainName = '' 45 | type1_flags = ntlm.NTLM_TYPE1_FLAGS & ~ntlm.NTLM_NegotiateOemDomainSupplied 46 | else: 47 | DomainName = user_parts[0].upper() 48 | UserName = user_parts[1] 49 | type1_flags = ntlm.NTLM_TYPE1_FLAGS 50 | # ntlm secures a socket, so we must use the same socket for the complete handshake 51 | headers = dict(req.headers) 52 | headers.update(req.unredirected_hdrs) 53 | auth = 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE( 54 | user, type1_flags 55 | ).decode('ascii') 56 | if req.headers.get(self.auth_header, None) == auth: 57 | return None 58 | headers[self.auth_header] = auth 59 | 60 | host = req.host 61 | if not host: 62 | raise urllib.request.URLError('no host given') 63 | h = None 64 | if req.get_full_url().startswith('https://'): 65 | h = http.client.HTTPSConnection(host) # will parse host:port 66 | else: 67 | h = http.client.HTTPConnection(host) # will parse host:port 68 | # we must keep the connection because NTLM authenticates the connection, not single requests 69 | headers["Connection"] = "Keep-Alive" 70 | headers = dict((name.title(), val) for name, val in list(headers.items())) 71 | h.request(req.get_method(), req.selector, req.data, headers) 72 | r = h.getresponse() 73 | r.begin() 74 | r._safe_read(int(r.getheader('content-length'))) 75 | try: 76 | if r.getheader('set-cookie'): 77 | # this is important for some web applications that store authentication-related info in cookies (it took a long time to figure out) 78 | headers['Cookie'] = r.getheader('set-cookie') 79 | except TypeError: 80 | pass 81 | r.fp = None # remove the reference to the socket, so that it can not be closed by the response object (we want to keep the socket open) 82 | auth_header_value = r.getheader(auth_header_field, None) 83 | 84 | # some Exchange servers send two WWW-Authenticate headers, one with the NTLM challenge 85 | # and another with the 'Negotiate' keyword - make sure we operate on the right one 86 | m = re.match('(NTLM [A-Za-z0-9+\-/=]+)', auth_header_value) 87 | if m: 88 | auth_header_value, = m.groups() 89 | 90 | (ServerChallenge, NegotiateFlags) = ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value[5:]) 91 | auth = 'NTLM %s' % ntlm.create_NTLM_AUTHENTICATE_MESSAGE( 92 | ServerChallenge, UserName, DomainName, pw, NegotiateFlags 93 | ).decode('ascii') 94 | headers[self.auth_header] = auth 95 | headers["Connection"] = "Close" 96 | headers = dict((name.title(), val) for name, val in list(headers.items())) 97 | try: 98 | h.request(req.get_method(), req.selector, req.data, headers) 99 | # none of the configured handlers are triggered, for example redirect-responses are not handled! 100 | response = h.getresponse() 101 | def notimplemented(): 102 | raise NotImplementedError 103 | response.readline = notimplemented 104 | return addinfourl(response, response.msg, req.get_full_url(), response.code) 105 | except socket.error as err: 106 | raise urllib.request.URLError(err) 107 | else: 108 | return None 109 | 110 | 111 | class HTTPNtlmAuthHandler(AbstractNtlmAuthHandler, urllib.request.BaseHandler): 112 | 113 | auth_header = 'Authorization' 114 | 115 | def http_error_401(self, req, fp, code, msg, headers): 116 | return self.http_error_authentication_required('www-authenticate', req, fp, headers) 117 | 118 | 119 | class ProxyNtlmAuthHandler(AbstractNtlmAuthHandler, urllib.request.BaseHandler): 120 | """ 121 | CAUTION: this class has NOT been tested at all!!! 122 | use at your own risk 123 | """ 124 | auth_header = 'Proxy-authorization' 125 | 126 | def http_error_407(self, req, fp, code, msg, headers): 127 | return self.http_error_authentication_required('proxy-authenticate', req, fp, headers) 128 | 129 | 130 | if __name__ == "__main__": 131 | url = "http://ntlmprotectedserver/securedfile.html" 132 | user = "DOMAIN\\User" 133 | password = "Password" 134 | passman = urllib.request.HTTPPasswordMgrWithDefaultRealm() 135 | passman.add_password(None, url, user , password) 136 | auth_basic = urllib.request.HTTPBasicAuthHandler(passman) 137 | auth_digest = urllib.request.HTTPDigestAuthHandler(passman) 138 | auth_NTLM = HTTPNtlmAuthHandler(passman) 139 | 140 | # disable proxies (just for testing) 141 | proxy_handler = urllib.request.ProxyHandler({}) 142 | 143 | opener = urllib.request.build_opener(proxy_handler, auth_NTLM) #, auth_digest, auth_basic) 144 | 145 | urllib.request.install_opener(opener) 146 | 147 | response = urllib.request.urlopen(url) 148 | print((response.read())) 149 | -------------------------------------------------------------------------------- /python30/ntlm/U32.py: -------------------------------------------------------------------------------- 1 | # This file is part of 'NTLM Authorization Proxy Server' http://sourceforge.net/projects/ntlmaps/ 2 | # Copyright 2001 Dmitry A. Rozmanov 3 | # 4 | # This library is free software: you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation, either 7 | # version 3 of the License, or (at your option) any later version. 8 | 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. If not, see or . 16 | 17 | 18 | C = 0x1000000000 19 | 20 | def norm(n): 21 | return n & 0xFFFFFFFF 22 | 23 | 24 | class U32: 25 | v = 0 26 | 27 | def __init__(self, value = 0): 28 | self.v = C + norm(abs(int(value))) 29 | 30 | def set(self, value = 0): 31 | self.v = C + norm(abs(int(value))) 32 | 33 | def __repr__(self): 34 | return hex(norm(self.v)) 35 | 36 | def __long__(self): return int(norm(self.v)) 37 | def __int__(self): return int(norm(self.v)) 38 | def __chr__(self): return chr(norm(self.v)) 39 | 40 | def __add__(self, b): 41 | r = U32() 42 | r.v = C + norm(self.v + b.v) 43 | return r 44 | 45 | def __sub__(self, b): 46 | r = U32() 47 | if self.v < b.v: 48 | r.v = C + norm(0x100000000 - (b.v - self.v)) 49 | else: r.v = C + norm(self.v - b.v) 50 | return r 51 | 52 | def __mul__(self, b): 53 | r = U32() 54 | r.v = C + norm(self.v * b.v) 55 | return r 56 | 57 | def __div__(self, b): 58 | r = U32() 59 | r.v = C + (norm(self.v) / norm(b.v)) 60 | return r 61 | 62 | def __mod__(self, b): 63 | r = U32() 64 | r.v = C + (norm(self.v) % norm(b.v)) 65 | return r 66 | 67 | def __neg__(self): return U32(self.v) 68 | def __pos__(self): return U32(self.v) 69 | def __abs__(self): return U32(self.v) 70 | 71 | def __invert__(self): 72 | r = U32() 73 | r.v = C + norm(~self.v) 74 | return r 75 | 76 | def __lshift__(self, b): 77 | r = U32() 78 | r.v = C + norm(self.v << b) 79 | return r 80 | 81 | def __rshift__(self, b): 82 | r = U32() 83 | r.v = C + (norm(self.v) >> b) 84 | return r 85 | 86 | def __and__(self, b): 87 | r = U32() 88 | r.v = C + norm(self.v & b.v) 89 | return r 90 | 91 | def __or__(self, b): 92 | r = U32() 93 | r.v = C + norm(self.v | b.v) 94 | return r 95 | 96 | def __xor__(self, b): 97 | r = U32() 98 | r.v = C + norm(self.v ^ b.v) 99 | return r 100 | 101 | def __not__(self): 102 | return U32(not norm(self.v)) 103 | 104 | def truth(self): 105 | return norm(self.v) 106 | 107 | def __cmp__(self, b): 108 | if norm(self.v) > norm(b.v): return 1 109 | elif norm(self.v) < norm(b.v): return -1 110 | else: return 0 111 | 112 | def __bool__(self): 113 | return norm(self.v) -------------------------------------------------------------------------------- /python30/ntlm/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mullender/python-ntlm/14e2243e05c8b671c6eae570d670672c9613e563/python30/ntlm/__init__.py -------------------------------------------------------------------------------- /python30/ntlm/des.py: -------------------------------------------------------------------------------- 1 | # This file is part of 'NTLM Authorization Proxy Server' http://sourceforge.net/projects/ntlmaps/ 2 | # Copyright 2001 Dmitry A. Rozmanov 3 | # 4 | # This library is free software: you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation, either 7 | # version 3 of the License, or (at your option) any later version. 8 | 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. If not, see or . 16 | try: 17 | from . import des_c 18 | except ValueError: 19 | import des_c 20 | 21 | #--------------------------------------------------------------------- 22 | class DES: 23 | 24 | des_c_obj = None 25 | 26 | #----------------------------------------------------------------- 27 | def __init__(self, key_str): 28 | "" 29 | k = str_to_key56(key_str) 30 | k = key56_to_key64(k) 31 | key_str = b'' 32 | for i in k: 33 | key_str += bytes((i & 0xFF, )) 34 | self.des_c_obj = des_c.DES(key_str) 35 | 36 | #----------------------------------------------------------------- 37 | def encrypt(self, plain_text): 38 | "" 39 | return self.des_c_obj.encrypt(plain_text) 40 | 41 | #----------------------------------------------------------------- 42 | def decrypt(self, crypted_text): 43 | "" 44 | return self.des_c_obj.decrypt(crypted_text) 45 | 46 | #--------------------------------------------------------------------- 47 | #Some Helpers 48 | #--------------------------------------------------------------------- 49 | 50 | DESException = 'DESException' 51 | 52 | #--------------------------------------------------------------------- 53 | def str_to_key56(key_str): 54 | "" 55 | if type(key_str) != type(''): 56 | #rise DESException, 'ERROR. Wrong key type.' 57 | pass 58 | if len(key_str) < 7: 59 | key_str = key_str + b'\000\000\000\000\000\000\000'[:(7 - len(key_str))] 60 | key_56 = [] 61 | for i in key_str[:7]: key_56.append(i) 62 | 63 | return key_56 64 | 65 | #--------------------------------------------------------------------- 66 | def key56_to_key64(key_56): 67 | "" 68 | key = [] 69 | for i in range(8): key.append(0) 70 | 71 | key[0] = key_56[0]; 72 | key[1] = ((key_56[0] << 7) & 0xFF) | (key_56[1] >> 1); 73 | key[2] = ((key_56[1] << 6) & 0xFF) | (key_56[2] >> 2); 74 | key[3] = ((key_56[2] << 5) & 0xFF) | (key_56[3] >> 3); 75 | key[4] = ((key_56[3] << 4) & 0xFF) | (key_56[4] >> 4); 76 | key[5] = ((key_56[4] << 3) & 0xFF) | (key_56[5] >> 5); 77 | key[6] = ((key_56[5] << 2) & 0xFF) | (key_56[6] >> 6); 78 | key[7] = (key_56[6] << 1) & 0xFF; 79 | 80 | key = set_key_odd_parity(key) 81 | 82 | return key 83 | 84 | #--------------------------------------------------------------------- 85 | def set_key_odd_parity(key): 86 | "" 87 | for i in range(len(key)): 88 | for k in range(7): 89 | bit = 0 90 | t = key[i] >> k 91 | bit = (t ^ bit) & 0x1 92 | key[i] = (key[i] & 0xFE) | bit 93 | 94 | return key 95 | -------------------------------------------------------------------------------- /python30/ntlm/des_c.py: -------------------------------------------------------------------------------- 1 | # This file is part of 'NTLM Authorization Proxy Server' http://sourceforge.net/projects/ntlmaps/ 2 | # Copyright 2001 Dmitry A. Rozmanov 3 | # 4 | # This library is free software: you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation, either 7 | # version 3 of the License, or (at your option) any later version. 8 | 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. If not, see or . 16 | 17 | try: 18 | from .U32 import U32 19 | except ValueError: 20 | from U32 import U32 21 | # --NON ASCII COMMENT ELIDED-- 22 | #typedef unsigned char des_cblock[8]; 23 | #define HDRSIZE 4 24 | 25 | def c2l(c): 26 | "char[4] to unsigned long" 27 | l = U32(c[0]) 28 | l = l | (U32(c[1]) << 8) 29 | l = l | (U32(c[2]) << 16) 30 | l = l | (U32(c[3]) << 24) 31 | return l 32 | 33 | def c2ln(c,l1,l2,n): 34 | "char[n] to two unsigned long???" 35 | c = c + n 36 | l1, l2 = U32(0), U32(0) 37 | 38 | f = 0 39 | if n == 8: 40 | l2 = l2 | (U32(c[7]) << 24) 41 | f = 1 42 | if f or (n == 7): 43 | l2 = l2 | (U32(c[6]) << 16) 44 | f = 1 45 | if f or (n == 6): 46 | l2 = l2 | (U32(c[5]) << 8) 47 | f = 1 48 | if f or (n == 5): 49 | l2 = l2 | U32(c[4]) 50 | f = 1 51 | if f or (n == 4): 52 | l1 = l1 | (U32(c[3]) << 24) 53 | f = 1 54 | if f or (n == 3): 55 | l1 = l1 | (U32(c[2]) << 16) 56 | f = 1 57 | if f or (n == 2): 58 | l1 = l1 | (U32(c[1]) << 8) 59 | f = 1 60 | if f or (n == 1): 61 | l1 = l1 | U32(c[0]) 62 | return (l1, l2) 63 | 64 | def l2c(l): 65 | "unsigned long to char[4]" 66 | c = [] 67 | c.append(int(l & U32(0xFF))) 68 | c.append(int((l >> 8) & U32(0xFF))) 69 | c.append(int((l >> 16) & U32(0xFF))) 70 | c.append(int((l >> 24) & U32(0xFF))) 71 | return c 72 | 73 | def n2l(c, l): 74 | "network to host long" 75 | l = U32(c[0] << 24) 76 | l = l | (U32(c[1]) << 16) 77 | l = l | (U32(c[2]) << 8) 78 | l = l | (U32(c[3])) 79 | return l 80 | 81 | def l2n(l, c): 82 | "host to network long" 83 | c = [] 84 | c.append(int((l >> 24) & U32(0xFF))) 85 | c.append(int((l >> 16) & U32(0xFF))) 86 | c.append(int((l >> 8) & U32(0xFF))) 87 | c.append(int((l ) & U32(0xFF))) 88 | return c 89 | 90 | def l2cn(l1, l2, c, n): 91 | "" 92 | for i in range(n): c.append(0x00) 93 | f = 0 94 | if f or (n == 8): 95 | c[7] = int((l2 >> 24) & U32(0xFF)) 96 | f = 1 97 | if f or (n == 7): 98 | c[6] = int((l2 >> 16) & U32(0xFF)) 99 | f = 1 100 | if f or (n == 6): 101 | c[5] = int((l2 >> 8) & U32(0xFF)) 102 | f = 1 103 | if f or (n == 5): 104 | c[4] = int((l2 ) & U32(0xFF)) 105 | f = 1 106 | if f or (n == 4): 107 | c[3] = int((l1 >> 24) & U32(0xFF)) 108 | f = 1 109 | if f or (n == 3): 110 | c[2] = int((l1 >> 16) & U32(0xFF)) 111 | f = 1 112 | if f or (n == 2): 113 | c[1] = int((l1 >> 8) & U32(0xFF)) 114 | f = 1 115 | if f or (n == 1): 116 | c[0] = int((l1 ) & U32(0xFF)) 117 | f = 1 118 | return c[:n] 119 | 120 | # array of data 121 | # static unsigned long des_SPtrans[8][64]={ 122 | # static unsigned long des_skb[8][64]={ 123 | try: 124 | from .des_data import des_SPtrans, des_skb 125 | except ValueError: 126 | from des_data import des_SPtrans, des_skb 127 | 128 | def D_ENCRYPT(tup, u, t, s): 129 | L, R, S = tup 130 | #print 'LRS1', L, R, S, u, t, '-->', 131 | u = (R ^ s[S]) 132 | t = R ^ s[S + 1] 133 | t = ((t >> 4) + (t << 28)) 134 | L = L ^ (des_SPtrans[1][int((t ) & U32(0x3f))] | \ 135 | des_SPtrans[3][int((t >> 8) & U32(0x3f))] | \ 136 | des_SPtrans[5][int((t >> 16) & U32(0x3f))] | \ 137 | des_SPtrans[7][int((t >> 24) & U32(0x3f))] | \ 138 | des_SPtrans[0][int((u ) & U32(0x3f))] | \ 139 | des_SPtrans[2][int((u >> 8) & U32(0x3f))] | \ 140 | des_SPtrans[4][int((u >> 16) & U32(0x3f))] | \ 141 | des_SPtrans[6][int((u >> 24) & U32(0x3f))]) 142 | #print 'LRS:', L, R, S, u, t 143 | return ((L, R, S), u, t, s) 144 | 145 | 146 | def PERM_OP (tup, n, m): 147 | "tup - (a, b, t)" 148 | a, b, t = tup 149 | t = ((a >> n) ^ b) & m 150 | b = b ^ t 151 | a = a ^ (t << n) 152 | return (a, b, t) 153 | 154 | def HPERM_OP (tup, n, m): 155 | "tup - (a, t)" 156 | a, t = tup 157 | t = ((a << (16 - n)) ^ a) & m 158 | a = a ^ t ^ (t >> (16 - n)) 159 | return (a, t) 160 | 161 | shifts2 = [0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0] 162 | 163 | class DES: 164 | KeySched = None # des_key_schedule 165 | 166 | def __init__(self, key_str): 167 | # key - UChar[8] 168 | key = [] 169 | #~ for i in key_str: key.append(ord(i)) 170 | #print 'key:', key 171 | self.KeySched = des_set_key(key_str) 172 | #print 'schedule:', self.KeySched, len(self.KeySched) 173 | 174 | def decrypt(self, str): 175 | # block - UChar[] 176 | block = [] 177 | for i in str: block.append(ord(i)) 178 | #print block 179 | block = des_ecb_encrypt(block, self.KeySched, 0) 180 | res = b'' 181 | for i in block: res = res + (chr(i)) 182 | return res 183 | 184 | def encrypt(self, str): 185 | # block - UChar[] 186 | block = [] 187 | for i in str: block.append(i) 188 | block = des_ecb_encrypt(block, self.KeySched, 1) 189 | res = b'' 190 | for i in block: res = res + bytes((i,)) 191 | return res 192 | 193 | 194 | 195 | 196 | 197 | 198 | #------------------------ 199 | def des_encript(input, ks, encrypt): 200 | # input - U32[] 201 | # output - U32[] 202 | # ks - des_key_shedule - U32[2][16] 203 | # encrypt - int 204 | # l, r, t, u - U32 205 | # i - int 206 | # s - U32[] 207 | 208 | l = input[0] 209 | r = input[1] 210 | t = U32(0) 211 | u = U32(0) 212 | 213 | r, l, t = PERM_OP((r, l, t), 4, U32(0x0f0f0f0f)) 214 | l, r, t = PERM_OP((l, r, t), 16, U32(0x0000ffff)) 215 | r, l, t = PERM_OP((r, l, t), 2, U32(0x33333333)) 216 | l, r, t = PERM_OP((l, r, t), 8, U32(0x00ff00ff)) 217 | r, l, t = PERM_OP((r, l, t), 1, U32(0x55555555)) 218 | 219 | t = (r << 1)|(r >> 31) 220 | r = (l << 1)|(l >> 31) 221 | l = t 222 | 223 | s = ks # ??????????????? 224 | #print l, r 225 | if(encrypt): 226 | for i in range(0, 32, 4): 227 | rtup, u, t, s = D_ENCRYPT((l, r, i + 0), u, t, s) 228 | l = rtup[0] 229 | r = rtup[1] 230 | rtup, u, t, s = D_ENCRYPT((r, l, i + 2), u, t, s) 231 | r = rtup[0] 232 | l = rtup[1] 233 | else: 234 | for i in range(30, 0, -4): 235 | rtup, u, t, s = D_ENCRYPT((l, r, i - 0), u, t, s) 236 | l = rtup[0] 237 | r = rtup[1] 238 | rtup, u, t, s = D_ENCRYPT((r, l, i - 2), u, t, s) 239 | r = rtup[0] 240 | l = rtup[1] 241 | #print l, r 242 | l = (l >> 1)|(l << 31) 243 | r = (r >> 1)|(r << 31) 244 | 245 | r, l, t = PERM_OP((r, l, t), 1, U32(0x55555555)) 246 | l, r, t = PERM_OP((l, r, t), 8, U32(0x00ff00ff)) 247 | r, l, t = PERM_OP((r, l, t), 2, U32(0x33333333)) 248 | l, r, t = PERM_OP((l, r, t), 16, U32(0x0000ffff)) 249 | r, l, t = PERM_OP((r, l, t), 4, U32(0x0f0f0f0f)) 250 | 251 | output = [l] 252 | output.append(r) 253 | l, r, t, u = U32(0), U32(0), U32(0), U32(0) 254 | return output 255 | 256 | def des_ecb_encrypt(input, ks, encrypt): 257 | # input - des_cblock - UChar[8] 258 | # output - des_cblock - UChar[8] 259 | # ks - des_key_shedule - U32[2][16] 260 | # encrypt - int 261 | 262 | #print input 263 | l0 = c2l(input[0:4]) 264 | l1 = c2l(input[4:8]) 265 | ll = [l0] 266 | ll.append(l1) 267 | #print ll 268 | ll = des_encript(ll, ks, encrypt) 269 | #print ll 270 | l0 = ll[0] 271 | l1 = ll[1] 272 | output = l2c(l0) 273 | output = output + l2c(l1) 274 | #print output 275 | l0, l1, ll[0], ll[1] = U32(0), U32(0), U32(0), U32(0) 276 | return output 277 | 278 | def des_set_key(key): 279 | # key - des_cblock - UChar[8] 280 | # schedule - des_key_schedule 281 | 282 | # register unsigned long c,d,t,s; 283 | # register unsigned char *in; 284 | # register unsigned long *k; 285 | # register int i; 286 | 287 | #k = schedule 288 | # in = key 289 | k = [] 290 | c = c2l(key[0:4]) 291 | d = c2l(key[4:8]) 292 | t = U32(0) 293 | 294 | d, c, t = PERM_OP((d, c, t), 4, U32(0x0f0f0f0f)) 295 | c, t = HPERM_OP((c, t), -2, U32(0xcccc0000)) 296 | d, t = HPERM_OP((d, t), -2, U32(0xcccc0000)) 297 | d, c, t = PERM_OP((d, c, t), 1, U32(0x55555555)) 298 | c, d, t = PERM_OP((c, d, t), 8, U32(0x00ff00ff)) 299 | d, c, t = PERM_OP((d, c, t), 1, U32(0x55555555)) 300 | 301 | d = (((d & U32(0x000000ff)) << 16)|(d & U32(0x0000ff00))|((d & U32(0x00ff0000)) >> 16)|((c & U32(0xf0000000)) >> 4)) 302 | c = c & U32(0x0fffffff) 303 | 304 | for i in range(16): 305 | if (shifts2[i]): 306 | c = ((c >> 2)|(c << 26)) 307 | d = ((d >> 2)|(d << 26)) 308 | else: 309 | c = ((c >> 1)|(c << 27)) 310 | d = ((d >> 1)|(d << 27)) 311 | c = c & U32(0x0fffffff) 312 | d = d & U32(0x0fffffff) 313 | 314 | s= des_skb[0][int((c ) & U32(0x3f))]|\ 315 | des_skb[1][int(((c>> 6) & U32(0x03))|((c>> 7) & U32(0x3c)))]|\ 316 | des_skb[2][int(((c>>13) & U32(0x0f))|((c>>14) & U32(0x30)))]|\ 317 | des_skb[3][int(((c>>20) & U32(0x01))|((c>>21) & U32(0x06)) | ((c>>22) & U32(0x38)))] 318 | 319 | t= des_skb[4][int((d ) & U32(0x3f) )]|\ 320 | des_skb[5][int(((d>> 7) & U32(0x03))|((d>> 8) & U32(0x3c)))]|\ 321 | des_skb[6][int((d>>15) & U32(0x3f) )]|\ 322 | des_skb[7][int(((d>>21) & U32(0x0f))|((d>>22) & U32(0x30)))] 323 | #print s, t 324 | 325 | k.append(((t << 16)|(s & U32(0x0000ffff))) & U32(0xffffffff)) 326 | s = ((s >> 16)|(t & U32(0xffff0000))) 327 | s = (s << 4)|(s >> 28) 328 | k.append(s & U32(0xffffffff)) 329 | 330 | schedule = k 331 | 332 | return schedule 333 | -------------------------------------------------------------------------------- /python30/ntlm/des_data.py: -------------------------------------------------------------------------------- 1 | # This file is part of 'NTLM Authorization Proxy Server' http://sourceforge.net/projects/ntlmaps/ 2 | # Copyright 2001 Dmitry A. Rozmanov 3 | # 4 | # This library is free software: you can redistribute it and/or 5 | # modify it under the terms of the GNU Lesser General Public 6 | # License as published by the Free Software Foundation, either 7 | # version 3 of the License, or (at your option) any later version. 8 | 9 | # This library is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | # Lesser General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU Lesser General Public 15 | # License along with this library. If not, see or . 16 | try: 17 | from .U32 import U32 18 | except ValueError: 19 | from U32 import U32 20 | # static unsigned long des_SPtrans[8][64]={ 21 | 22 | des_SPtrans =\ 23 | [ 24 | #nibble 0 25 | [ 26 | U32(0x00820200), U32(0x00020000), U32(0x80800000), U32(0x80820200), 27 | U32(0x00800000), U32(0x80020200), U32(0x80020000), U32(0x80800000), 28 | U32(0x80020200), U32(0x00820200), U32(0x00820000), U32(0x80000200), 29 | U32(0x80800200), U32(0x00800000), U32(0x00000000), U32(0x80020000), 30 | U32(0x00020000), U32(0x80000000), U32(0x00800200), U32(0x00020200), 31 | U32(0x80820200), U32(0x00820000), U32(0x80000200), U32(0x00800200), 32 | U32(0x80000000), U32(0x00000200), U32(0x00020200), U32(0x80820000), 33 | U32(0x00000200), U32(0x80800200), U32(0x80820000), U32(0x00000000), 34 | U32(0x00000000), U32(0x80820200), U32(0x00800200), U32(0x80020000), 35 | U32(0x00820200), U32(0x00020000), U32(0x80000200), U32(0x00800200), 36 | U32(0x80820000), U32(0x00000200), U32(0x00020200), U32(0x80800000), 37 | U32(0x80020200), U32(0x80000000), U32(0x80800000), U32(0x00820000), 38 | U32(0x80820200), U32(0x00020200), U32(0x00820000), U32(0x80800200), 39 | U32(0x00800000), U32(0x80000200), U32(0x80020000), U32(0x00000000), 40 | U32(0x00020000), U32(0x00800000), U32(0x80800200), U32(0x00820200), 41 | U32(0x80000000), U32(0x80820000), U32(0x00000200), U32(0x80020200), 42 | ], 43 | 44 | #nibble 1 45 | [ 46 | U32(0x10042004), U32(0x00000000), U32(0x00042000), U32(0x10040000), 47 | U32(0x10000004), U32(0x00002004), U32(0x10002000), U32(0x00042000), 48 | U32(0x00002000), U32(0x10040004), U32(0x00000004), U32(0x10002000), 49 | U32(0x00040004), U32(0x10042000), U32(0x10040000), U32(0x00000004), 50 | U32(0x00040000), U32(0x10002004), U32(0x10040004), U32(0x00002000), 51 | U32(0x00042004), U32(0x10000000), U32(0x00000000), U32(0x00040004), 52 | U32(0x10002004), U32(0x00042004), U32(0x10042000), U32(0x10000004), 53 | U32(0x10000000), U32(0x00040000), U32(0x00002004), U32(0x10042004), 54 | U32(0x00040004), U32(0x10042000), U32(0x10002000), U32(0x00042004), 55 | U32(0x10042004), U32(0x00040004), U32(0x10000004), U32(0x00000000), 56 | U32(0x10000000), U32(0x00002004), U32(0x00040000), U32(0x10040004), 57 | U32(0x00002000), U32(0x10000000), U32(0x00042004), U32(0x10002004), 58 | U32(0x10042000), U32(0x00002000), U32(0x00000000), U32(0x10000004), 59 | U32(0x00000004), U32(0x10042004), U32(0x00042000), U32(0x10040000), 60 | U32(0x10040004), U32(0x00040000), U32(0x00002004), U32(0x10002000), 61 | U32(0x10002004), U32(0x00000004), U32(0x10040000), U32(0x00042000), 62 | ], 63 | 64 | #nibble 2 65 | [ 66 | U32(0x41000000), U32(0x01010040), U32(0x00000040), U32(0x41000040), 67 | U32(0x40010000), U32(0x01000000), U32(0x41000040), U32(0x00010040), 68 | U32(0x01000040), U32(0x00010000), U32(0x01010000), U32(0x40000000), 69 | U32(0x41010040), U32(0x40000040), U32(0x40000000), U32(0x41010000), 70 | U32(0x00000000), U32(0x40010000), U32(0x01010040), U32(0x00000040), 71 | U32(0x40000040), U32(0x41010040), U32(0x00010000), U32(0x41000000), 72 | U32(0x41010000), U32(0x01000040), U32(0x40010040), U32(0x01010000), 73 | U32(0x00010040), U32(0x00000000), U32(0x01000000), U32(0x40010040), 74 | U32(0x01010040), U32(0x00000040), U32(0x40000000), U32(0x00010000), 75 | U32(0x40000040), U32(0x40010000), U32(0x01010000), U32(0x41000040), 76 | U32(0x00000000), U32(0x01010040), U32(0x00010040), U32(0x41010000), 77 | U32(0x40010000), U32(0x01000000), U32(0x41010040), U32(0x40000000), 78 | U32(0x40010040), U32(0x41000000), U32(0x01000000), U32(0x41010040), 79 | U32(0x00010000), U32(0x01000040), U32(0x41000040), U32(0x00010040), 80 | U32(0x01000040), U32(0x00000000), U32(0x41010000), U32(0x40000040), 81 | U32(0x41000000), U32(0x40010040), U32(0x00000040), U32(0x01010000), 82 | ], 83 | 84 | #nibble 3 85 | [ 86 | U32(0x00100402), U32(0x04000400), U32(0x00000002), U32(0x04100402), 87 | U32(0x00000000), U32(0x04100000), U32(0x04000402), U32(0x00100002), 88 | U32(0x04100400), U32(0x04000002), U32(0x04000000), U32(0x00000402), 89 | U32(0x04000002), U32(0x00100402), U32(0x00100000), U32(0x04000000), 90 | U32(0x04100002), U32(0x00100400), U32(0x00000400), U32(0x00000002), 91 | U32(0x00100400), U32(0x04000402), U32(0x04100000), U32(0x00000400), 92 | U32(0x00000402), U32(0x00000000), U32(0x00100002), U32(0x04100400), 93 | U32(0x04000400), U32(0x04100002), U32(0x04100402), U32(0x00100000), 94 | U32(0x04100002), U32(0x00000402), U32(0x00100000), U32(0x04000002), 95 | U32(0x00100400), U32(0x04000400), U32(0x00000002), U32(0x04100000), 96 | U32(0x04000402), U32(0x00000000), U32(0x00000400), U32(0x00100002), 97 | U32(0x00000000), U32(0x04100002), U32(0x04100400), U32(0x00000400), 98 | U32(0x04000000), U32(0x04100402), U32(0x00100402), U32(0x00100000), 99 | U32(0x04100402), U32(0x00000002), U32(0x04000400), U32(0x00100402), 100 | U32(0x00100002), U32(0x00100400), U32(0x04100000), U32(0x04000402), 101 | U32(0x00000402), U32(0x04000000), U32(0x04000002), U32(0x04100400), 102 | ], 103 | 104 | #nibble 4 105 | [ 106 | U32(0x02000000), U32(0x00004000), U32(0x00000100), U32(0x02004108), 107 | U32(0x02004008), U32(0x02000100), U32(0x00004108), U32(0x02004000), 108 | U32(0x00004000), U32(0x00000008), U32(0x02000008), U32(0x00004100), 109 | U32(0x02000108), U32(0x02004008), U32(0x02004100), U32(0x00000000), 110 | U32(0x00004100), U32(0x02000000), U32(0x00004008), U32(0x00000108), 111 | U32(0x02000100), U32(0x00004108), U32(0x00000000), U32(0x02000008), 112 | U32(0x00000008), U32(0x02000108), U32(0x02004108), U32(0x00004008), 113 | U32(0x02004000), U32(0x00000100), U32(0x00000108), U32(0x02004100), 114 | U32(0x02004100), U32(0x02000108), U32(0x00004008), U32(0x02004000), 115 | U32(0x00004000), U32(0x00000008), U32(0x02000008), U32(0x02000100), 116 | U32(0x02000000), U32(0x00004100), U32(0x02004108), U32(0x00000000), 117 | U32(0x00004108), U32(0x02000000), U32(0x00000100), U32(0x00004008), 118 | U32(0x02000108), U32(0x00000100), U32(0x00000000), U32(0x02004108), 119 | U32(0x02004008), U32(0x02004100), U32(0x00000108), U32(0x00004000), 120 | U32(0x00004100), U32(0x02004008), U32(0x02000100), U32(0x00000108), 121 | U32(0x00000008), U32(0x00004108), U32(0x02004000), U32(0x02000008), 122 | ], 123 | 124 | #nibble 5 125 | [ 126 | U32(0x20000010), U32(0x00080010), U32(0x00000000), U32(0x20080800), 127 | U32(0x00080010), U32(0x00000800), U32(0x20000810), U32(0x00080000), 128 | U32(0x00000810), U32(0x20080810), U32(0x00080800), U32(0x20000000), 129 | U32(0x20000800), U32(0x20000010), U32(0x20080000), U32(0x00080810), 130 | U32(0x00080000), U32(0x20000810), U32(0x20080010), U32(0x00000000), 131 | U32(0x00000800), U32(0x00000010), U32(0x20080800), U32(0x20080010), 132 | U32(0x20080810), U32(0x20080000), U32(0x20000000), U32(0x00000810), 133 | U32(0x00000010), U32(0x00080800), U32(0x00080810), U32(0x20000800), 134 | U32(0x00000810), U32(0x20000000), U32(0x20000800), U32(0x00080810), 135 | U32(0x20080800), U32(0x00080010), U32(0x00000000), U32(0x20000800), 136 | U32(0x20000000), U32(0x00000800), U32(0x20080010), U32(0x00080000), 137 | U32(0x00080010), U32(0x20080810), U32(0x00080800), U32(0x00000010), 138 | U32(0x20080810), U32(0x00080800), U32(0x00080000), U32(0x20000810), 139 | U32(0x20000010), U32(0x20080000), U32(0x00080810), U32(0x00000000), 140 | U32(0x00000800), U32(0x20000010), U32(0x20000810), U32(0x20080800), 141 | U32(0x20080000), U32(0x00000810), U32(0x00000010), U32(0x20080010), 142 | ], 143 | 144 | #nibble 6 145 | [ 146 | U32(0x00001000), U32(0x00000080), U32(0x00400080), U32(0x00400001), 147 | U32(0x00401081), U32(0x00001001), U32(0x00001080), U32(0x00000000), 148 | U32(0x00400000), U32(0x00400081), U32(0x00000081), U32(0x00401000), 149 | U32(0x00000001), U32(0x00401080), U32(0x00401000), U32(0x00000081), 150 | U32(0x00400081), U32(0x00001000), U32(0x00001001), U32(0x00401081), 151 | U32(0x00000000), U32(0x00400080), U32(0x00400001), U32(0x00001080), 152 | U32(0x00401001), U32(0x00001081), U32(0x00401080), U32(0x00000001), 153 | U32(0x00001081), U32(0x00401001), U32(0x00000080), U32(0x00400000), 154 | U32(0x00001081), U32(0x00401000), U32(0x00401001), U32(0x00000081), 155 | U32(0x00001000), U32(0x00000080), U32(0x00400000), U32(0x00401001), 156 | U32(0x00400081), U32(0x00001081), U32(0x00001080), U32(0x00000000), 157 | U32(0x00000080), U32(0x00400001), U32(0x00000001), U32(0x00400080), 158 | U32(0x00000000), U32(0x00400081), U32(0x00400080), U32(0x00001080), 159 | U32(0x00000081), U32(0x00001000), U32(0x00401081), U32(0x00400000), 160 | U32(0x00401080), U32(0x00000001), U32(0x00001001), U32(0x00401081), 161 | U32(0x00400001), U32(0x00401080), U32(0x00401000), U32(0x00001001), 162 | ], 163 | 164 | #nibble 7 165 | [ 166 | U32(0x08200020), U32(0x08208000), U32(0x00008020), U32(0x00000000), 167 | U32(0x08008000), U32(0x00200020), U32(0x08200000), U32(0x08208020), 168 | U32(0x00000020), U32(0x08000000), U32(0x00208000), U32(0x00008020), 169 | U32(0x00208020), U32(0x08008020), U32(0x08000020), U32(0x08200000), 170 | U32(0x00008000), U32(0x00208020), U32(0x00200020), U32(0x08008000), 171 | U32(0x08208020), U32(0x08000020), U32(0x00000000), U32(0x00208000), 172 | U32(0x08000000), U32(0x00200000), U32(0x08008020), U32(0x08200020), 173 | U32(0x00200000), U32(0x00008000), U32(0x08208000), U32(0x00000020), 174 | U32(0x00200000), U32(0x00008000), U32(0x08000020), U32(0x08208020), 175 | U32(0x00008020), U32(0x08000000), U32(0x00000000), U32(0x00208000), 176 | U32(0x08200020), U32(0x08008020), U32(0x08008000), U32(0x00200020), 177 | U32(0x08208000), U32(0x00000020), U32(0x00200020), U32(0x08008000), 178 | U32(0x08208020), U32(0x00200000), U32(0x08200000), U32(0x08000020), 179 | U32(0x00208000), U32(0x00008020), U32(0x08008020), U32(0x08200000), 180 | U32(0x00000020), U32(0x08208000), U32(0x00208020), U32(0x00000000), 181 | U32(0x08000000), U32(0x08200020), U32(0x00008000), U32(0x00208020), 182 | ], 183 | ] 184 | 185 | #static unsigned long des_skb[8][64]={ 186 | 187 | des_skb = \ 188 | [ 189 | #for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 190 | [ 191 | U32(0x00000000),U32(0x00000010),U32(0x20000000),U32(0x20000010), 192 | U32(0x00010000),U32(0x00010010),U32(0x20010000),U32(0x20010010), 193 | U32(0x00000800),U32(0x00000810),U32(0x20000800),U32(0x20000810), 194 | U32(0x00010800),U32(0x00010810),U32(0x20010800),U32(0x20010810), 195 | U32(0x00000020),U32(0x00000030),U32(0x20000020),U32(0x20000030), 196 | U32(0x00010020),U32(0x00010030),U32(0x20010020),U32(0x20010030), 197 | U32(0x00000820),U32(0x00000830),U32(0x20000820),U32(0x20000830), 198 | U32(0x00010820),U32(0x00010830),U32(0x20010820),U32(0x20010830), 199 | U32(0x00080000),U32(0x00080010),U32(0x20080000),U32(0x20080010), 200 | U32(0x00090000),U32(0x00090010),U32(0x20090000),U32(0x20090010), 201 | U32(0x00080800),U32(0x00080810),U32(0x20080800),U32(0x20080810), 202 | U32(0x00090800),U32(0x00090810),U32(0x20090800),U32(0x20090810), 203 | U32(0x00080020),U32(0x00080030),U32(0x20080020),U32(0x20080030), 204 | U32(0x00090020),U32(0x00090030),U32(0x20090020),U32(0x20090030), 205 | U32(0x00080820),U32(0x00080830),U32(0x20080820),U32(0x20080830), 206 | U32(0x00090820),U32(0x00090830),U32(0x20090820),U32(0x20090830), 207 | ], 208 | 209 | #for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 210 | [ 211 | U32(0x00000000),U32(0x02000000),U32(0x00002000),U32(0x02002000), 212 | U32(0x00200000),U32(0x02200000),U32(0x00202000),U32(0x02202000), 213 | U32(0x00000004),U32(0x02000004),U32(0x00002004),U32(0x02002004), 214 | U32(0x00200004),U32(0x02200004),U32(0x00202004),U32(0x02202004), 215 | U32(0x00000400),U32(0x02000400),U32(0x00002400),U32(0x02002400), 216 | U32(0x00200400),U32(0x02200400),U32(0x00202400),U32(0x02202400), 217 | U32(0x00000404),U32(0x02000404),U32(0x00002404),U32(0x02002404), 218 | U32(0x00200404),U32(0x02200404),U32(0x00202404),U32(0x02202404), 219 | U32(0x10000000),U32(0x12000000),U32(0x10002000),U32(0x12002000), 220 | U32(0x10200000),U32(0x12200000),U32(0x10202000),U32(0x12202000), 221 | U32(0x10000004),U32(0x12000004),U32(0x10002004),U32(0x12002004), 222 | U32(0x10200004),U32(0x12200004),U32(0x10202004),U32(0x12202004), 223 | U32(0x10000400),U32(0x12000400),U32(0x10002400),U32(0x12002400), 224 | U32(0x10200400),U32(0x12200400),U32(0x10202400),U32(0x12202400), 225 | U32(0x10000404),U32(0x12000404),U32(0x10002404),U32(0x12002404), 226 | U32(0x10200404),U32(0x12200404),U32(0x10202404),U32(0x12202404), 227 | ], 228 | 229 | #for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 230 | [ 231 | U32(0x00000000),U32(0x00000001),U32(0x00040000),U32(0x00040001), 232 | U32(0x01000000),U32(0x01000001),U32(0x01040000),U32(0x01040001), 233 | U32(0x00000002),U32(0x00000003),U32(0x00040002),U32(0x00040003), 234 | U32(0x01000002),U32(0x01000003),U32(0x01040002),U32(0x01040003), 235 | U32(0x00000200),U32(0x00000201),U32(0x00040200),U32(0x00040201), 236 | U32(0x01000200),U32(0x01000201),U32(0x01040200),U32(0x01040201), 237 | U32(0x00000202),U32(0x00000203),U32(0x00040202),U32(0x00040203), 238 | U32(0x01000202),U32(0x01000203),U32(0x01040202),U32(0x01040203), 239 | U32(0x08000000),U32(0x08000001),U32(0x08040000),U32(0x08040001), 240 | U32(0x09000000),U32(0x09000001),U32(0x09040000),U32(0x09040001), 241 | U32(0x08000002),U32(0x08000003),U32(0x08040002),U32(0x08040003), 242 | U32(0x09000002),U32(0x09000003),U32(0x09040002),U32(0x09040003), 243 | U32(0x08000200),U32(0x08000201),U32(0x08040200),U32(0x08040201), 244 | U32(0x09000200),U32(0x09000201),U32(0x09040200),U32(0x09040201), 245 | U32(0x08000202),U32(0x08000203),U32(0x08040202),U32(0x08040203), 246 | U32(0x09000202),U32(0x09000203),U32(0x09040202),U32(0x09040203), 247 | ], 248 | 249 | #for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 250 | [ 251 | U32(0x00000000),U32(0x00100000),U32(0x00000100),U32(0x00100100), 252 | U32(0x00000008),U32(0x00100008),U32(0x00000108),U32(0x00100108), 253 | U32(0x00001000),U32(0x00101000),U32(0x00001100),U32(0x00101100), 254 | U32(0x00001008),U32(0x00101008),U32(0x00001108),U32(0x00101108), 255 | U32(0x04000000),U32(0x04100000),U32(0x04000100),U32(0x04100100), 256 | U32(0x04000008),U32(0x04100008),U32(0x04000108),U32(0x04100108), 257 | U32(0x04001000),U32(0x04101000),U32(0x04001100),U32(0x04101100), 258 | U32(0x04001008),U32(0x04101008),U32(0x04001108),U32(0x04101108), 259 | U32(0x00020000),U32(0x00120000),U32(0x00020100),U32(0x00120100), 260 | U32(0x00020008),U32(0x00120008),U32(0x00020108),U32(0x00120108), 261 | U32(0x00021000),U32(0x00121000),U32(0x00021100),U32(0x00121100), 262 | U32(0x00021008),U32(0x00121008),U32(0x00021108),U32(0x00121108), 263 | U32(0x04020000),U32(0x04120000),U32(0x04020100),U32(0x04120100), 264 | U32(0x04020008),U32(0x04120008),U32(0x04020108),U32(0x04120108), 265 | U32(0x04021000),U32(0x04121000),U32(0x04021100),U32(0x04121100), 266 | U32(0x04021008),U32(0x04121008),U32(0x04021108),U32(0x04121108), 267 | ], 268 | 269 | #for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 270 | [ 271 | U32(0x00000000),U32(0x10000000),U32(0x00010000),U32(0x10010000), 272 | U32(0x00000004),U32(0x10000004),U32(0x00010004),U32(0x10010004), 273 | U32(0x20000000),U32(0x30000000),U32(0x20010000),U32(0x30010000), 274 | U32(0x20000004),U32(0x30000004),U32(0x20010004),U32(0x30010004), 275 | U32(0x00100000),U32(0x10100000),U32(0x00110000),U32(0x10110000), 276 | U32(0x00100004),U32(0x10100004),U32(0x00110004),U32(0x10110004), 277 | U32(0x20100000),U32(0x30100000),U32(0x20110000),U32(0x30110000), 278 | U32(0x20100004),U32(0x30100004),U32(0x20110004),U32(0x30110004), 279 | U32(0x00001000),U32(0x10001000),U32(0x00011000),U32(0x10011000), 280 | U32(0x00001004),U32(0x10001004),U32(0x00011004),U32(0x10011004), 281 | U32(0x20001000),U32(0x30001000),U32(0x20011000),U32(0x30011000), 282 | U32(0x20001004),U32(0x30001004),U32(0x20011004),U32(0x30011004), 283 | U32(0x00101000),U32(0x10101000),U32(0x00111000),U32(0x10111000), 284 | U32(0x00101004),U32(0x10101004),U32(0x00111004),U32(0x10111004), 285 | U32(0x20101000),U32(0x30101000),U32(0x20111000),U32(0x30111000), 286 | U32(0x20101004),U32(0x30101004),U32(0x20111004),U32(0x30111004), 287 | ], 288 | 289 | #for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 290 | [ 291 | U32(0x00000000),U32(0x08000000),U32(0x00000008),U32(0x08000008), 292 | U32(0x00000400),U32(0x08000400),U32(0x00000408),U32(0x08000408), 293 | U32(0x00020000),U32(0x08020000),U32(0x00020008),U32(0x08020008), 294 | U32(0x00020400),U32(0x08020400),U32(0x00020408),U32(0x08020408), 295 | U32(0x00000001),U32(0x08000001),U32(0x00000009),U32(0x08000009), 296 | U32(0x00000401),U32(0x08000401),U32(0x00000409),U32(0x08000409), 297 | U32(0x00020001),U32(0x08020001),U32(0x00020009),U32(0x08020009), 298 | U32(0x00020401),U32(0x08020401),U32(0x00020409),U32(0x08020409), 299 | U32(0x02000000),U32(0x0A000000),U32(0x02000008),U32(0x0A000008), 300 | U32(0x02000400),U32(0x0A000400),U32(0x02000408),U32(0x0A000408), 301 | U32(0x02020000),U32(0x0A020000),U32(0x02020008),U32(0x0A020008), 302 | U32(0x02020400),U32(0x0A020400),U32(0x02020408),U32(0x0A020408), 303 | U32(0x02000001),U32(0x0A000001),U32(0x02000009),U32(0x0A000009), 304 | U32(0x02000401),U32(0x0A000401),U32(0x02000409),U32(0x0A000409), 305 | U32(0x02020001),U32(0x0A020001),U32(0x02020009),U32(0x0A020009), 306 | U32(0x02020401),U32(0x0A020401),U32(0x02020409),U32(0x0A020409), 307 | ], 308 | 309 | #for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 310 | [ 311 | U32(0x00000000),U32(0x00000100),U32(0x00080000),U32(0x00080100), 312 | U32(0x01000000),U32(0x01000100),U32(0x01080000),U32(0x01080100), 313 | U32(0x00000010),U32(0x00000110),U32(0x00080010),U32(0x00080110), 314 | U32(0x01000010),U32(0x01000110),U32(0x01080010),U32(0x01080110), 315 | U32(0x00200000),U32(0x00200100),U32(0x00280000),U32(0x00280100), 316 | U32(0x01200000),U32(0x01200100),U32(0x01280000),U32(0x01280100), 317 | U32(0x00200010),U32(0x00200110),U32(0x00280010),U32(0x00280110), 318 | U32(0x01200010),U32(0x01200110),U32(0x01280010),U32(0x01280110), 319 | U32(0x00000200),U32(0x00000300),U32(0x00080200),U32(0x00080300), 320 | U32(0x01000200),U32(0x01000300),U32(0x01080200),U32(0x01080300), 321 | U32(0x00000210),U32(0x00000310),U32(0x00080210),U32(0x00080310), 322 | U32(0x01000210),U32(0x01000310),U32(0x01080210),U32(0x01080310), 323 | U32(0x00200200),U32(0x00200300),U32(0x00280200),U32(0x00280300), 324 | U32(0x01200200),U32(0x01200300),U32(0x01280200),U32(0x01280300), 325 | U32(0x00200210),U32(0x00200310),U32(0x00280210),U32(0x00280310), 326 | U32(0x01200210),U32(0x01200310),U32(0x01280210),U32(0x01280310), 327 | ], 328 | 329 | #for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 330 | [ 331 | U32(0x00000000),U32(0x04000000),U32(0x00040000),U32(0x04040000), 332 | U32(0x00000002),U32(0x04000002),U32(0x00040002),U32(0x04040002), 333 | U32(0x00002000),U32(0x04002000),U32(0x00042000),U32(0x04042000), 334 | U32(0x00002002),U32(0x04002002),U32(0x00042002),U32(0x04042002), 335 | U32(0x00000020),U32(0x04000020),U32(0x00040020),U32(0x04040020), 336 | U32(0x00000022),U32(0x04000022),U32(0x00040022),U32(0x04040022), 337 | U32(0x00002020),U32(0x04002020),U32(0x00042020),U32(0x04042020), 338 | U32(0x00002022),U32(0x04002022),U32(0x00042022),U32(0x04042022), 339 | U32(0x00000800),U32(0x04000800),U32(0x00040800),U32(0x04040800), 340 | U32(0x00000802),U32(0x04000802),U32(0x00040802),U32(0x04040802), 341 | U32(0x00002800),U32(0x04002800),U32(0x00042800),U32(0x04042800), 342 | U32(0x00002802),U32(0x04002802),U32(0x00042802),U32(0x04042802), 343 | U32(0x00000820),U32(0x04000820),U32(0x00040820),U32(0x04040820), 344 | U32(0x00000822),U32(0x04000822),U32(0x00040822),U32(0x04040822), 345 | U32(0x00002820),U32(0x04002820),U32(0x00042820),U32(0x04042820), 346 | U32(0x00002822),U32(0x04002822),U32(0x00042822),U32(0x04042822), 347 | ] 348 | 349 | ] -------------------------------------------------------------------------------- /python30/ntlm/ntlm.py: -------------------------------------------------------------------------------- 1 | # This library is free software: you can redistribute it and/or 2 | # modify it under the terms of the GNU Lesser General Public 3 | # License as published by the Free Software Foundation, either 4 | # version 3 of the License, or (at your option) any later version. 5 | 6 | # This library is distributed in the hope that it will be useful, 7 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 8 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | # Lesser General Public License for more details. 10 | # 11 | # You should have received a copy of the GNU Lesser General Public 12 | # License along with this library. If not, see or . 13 | 14 | import struct 15 | import base64 16 | import string 17 | try: 18 | from . import des 19 | except ValueError: 20 | import des 21 | import hashlib 22 | import hmac 23 | import random 24 | import re 25 | import binascii 26 | from socket import gethostname 27 | 28 | NTLM_NegotiateUnicode = 0x00000001 29 | NTLM_NegotiateOEM = 0x00000002 30 | NTLM_RequestTarget = 0x00000004 31 | NTLM_Unknown9 = 0x00000008 32 | NTLM_NegotiateSign = 0x00000010 33 | NTLM_NegotiateSeal = 0x00000020 34 | NTLM_NegotiateDatagram = 0x00000040 35 | NTLM_NegotiateLanManagerKey = 0x00000080 36 | NTLM_Unknown8 = 0x00000100 37 | NTLM_NegotiateNTLM = 0x00000200 38 | NTLM_NegotiateNTOnly = 0x00000400 39 | NTLM_Anonymous = 0x00000800 40 | NTLM_NegotiateOemDomainSupplied = 0x00001000 41 | NTLM_NegotiateOemWorkstationSupplied = 0x00002000 42 | NTLM_Unknown6 = 0x00004000 43 | NTLM_NegotiateAlwaysSign = 0x00008000 44 | NTLM_TargettypeDomain = 0x00010000 45 | NTLM_TargettypeServer = 0x00020000 46 | NTLM_TargettypeShare = 0x00040000 47 | NTLM_NegotiateExtendedSecurity = 0x00080000 48 | NTLM_NegotiateIdentify = 0x00100000 49 | NTLM_Unknown5 = 0x00200000 50 | NTLM_RequestNonNTSessionKey = 0x00400000 51 | NTLM_NegotiateTargetInfo = 0x00800000 52 | NTLM_Unknown4 = 0x01000000 53 | NTLM_NegotiateVersion = 0x02000000 54 | NTLM_Unknown3 = 0x04000000 55 | NTLM_Unknown2 = 0x08000000 56 | NTLM_Unknown1 = 0x10000000 57 | NTLM_Negotiate128 = 0x20000000 58 | NTLM_NegotiateKeyExchange = 0x40000000 59 | NTLM_Negotiate56 = 0x80000000 60 | 61 | # we send these flags with our type 1 message 62 | NTLM_TYPE1_FLAGS = (NTLM_NegotiateUnicode | \ 63 | NTLM_NegotiateOEM | \ 64 | NTLM_RequestTarget | \ 65 | NTLM_NegotiateNTLM | \ 66 | NTLM_NegotiateOemDomainSupplied | \ 67 | NTLM_NegotiateOemWorkstationSupplied | \ 68 | NTLM_NegotiateAlwaysSign | \ 69 | NTLM_NegotiateExtendedSecurity | \ 70 | NTLM_NegotiateVersion | \ 71 | NTLM_Negotiate128 | \ 72 | NTLM_Negotiate56 ) 73 | NTLM_TYPE2_FLAGS = (NTLM_NegotiateUnicode | \ 74 | NTLM_RequestTarget | \ 75 | NTLM_NegotiateNTLM | \ 76 | NTLM_NegotiateAlwaysSign | \ 77 | NTLM_NegotiateExtendedSecurity | \ 78 | NTLM_NegotiateTargetInfo | \ 79 | NTLM_NegotiateVersion | \ 80 | NTLM_Negotiate128 | \ 81 | NTLM_Negotiate56) 82 | 83 | NTLM_MsvAvEOL = 0 # Indicates that this is the last AV_PAIR in the list. AvLen MUST be 0. This type of information MUST be present in the AV pair list. 84 | NTLM_MsvAvNbComputerName = 1 # The server's NetBIOS computer name. The name MUST be in Unicode, and is not null-terminated. This type of information MUST be present in the AV_pair list. 85 | NTLM_MsvAvNbDomainName = 2 # The server's NetBIOS domain name. The name MUST be in Unicode, and is not null-terminated. This type of information MUST be present in the AV_pair list. 86 | NTLM_MsvAvDnsComputerName = 3 # The server's Active Directory DNS computer name. The name MUST be in Unicode, and is not null-terminated. 87 | NTLM_MsvAvDnsDomainName = 4 # The server's Active Directory DNS domain name. The name MUST be in Unicode, and is not null-terminated. 88 | NTLM_MsvAvDnsTreeName = 5 # The server's Active Directory (AD) DNS forest tree name. The name MUST be in Unicode, and is not null-terminated. 89 | NTLM_MsvAvFlags = 6 # A field containing a 32-bit value indicating server or client configuration. 0x00000001: indicates to the client that the account authentication is constrained. 0x00000002: indicates that the client is providing message integrity in the MIC field (section 2.2.1.3) in the AUTHENTICATE_MESSAGE. 90 | NTLM_MsvAvTimestamp = 7 # A FILETIME structure ([MS-DTYP] section 2.3.1) in little-endian byte order that contains the server local time.<12> 91 | NTLM_MsAvRestrictions = 8 #A Restriction_Encoding structure (section 2.2.2.2). The Value field contains a structure representing the integrity level of the security principal, as well as a MachineID created at computer startup to identify the calling machine. <13> 92 | 93 | 94 | """ 95 | utility functions for Microsoft NTLM authentication 96 | 97 | References: 98 | [MS-NLMP]: NT LAN Manager (NTLM) Authentication Protocol Specification 99 | http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-NLMP%5D.pdf 100 | 101 | [MS-NTHT]: NTLM Over HTTP Protocol Specification 102 | http://download.microsoft.com/download/a/e/6/ae6e4142-aa58-45c6-8dcf-a657e5900cd3/%5BMS-NTHT%5D.pdf 103 | 104 | Cntlm Authentication Proxy 105 | http://cntlm.awk.cz/ 106 | 107 | NTLM Authorization Proxy Server 108 | http://sourceforge.net/projects/ntlmaps/ 109 | 110 | Optimized Attack for NTLM2 Session Response 111 | http://www.blackhat.com/presentations/bh-asia-04/bh-jp-04-pdfs/bh-jp-04-seki.pdf 112 | """ 113 | def dump_NegotiateFlags(NegotiateFlags): 114 | if NegotiateFlags & NTLM_NegotiateUnicode: 115 | print("NTLM_NegotiateUnicode set") 116 | if NegotiateFlags & NTLM_NegotiateOEM: 117 | print("NTLM_NegotiateOEM set") 118 | if NegotiateFlags & NTLM_RequestTarget: 119 | print("NTLM_RequestTarget set") 120 | if NegotiateFlags & NTLM_Unknown9: 121 | print("NTLM_Unknown9 set") 122 | if NegotiateFlags & NTLM_NegotiateSign: 123 | print("NTLM_NegotiateSign set") 124 | if NegotiateFlags & NTLM_NegotiateSeal: 125 | print("NTLM_NegotiateSeal set") 126 | if NegotiateFlags & NTLM_NegotiateDatagram: 127 | print("NTLM_NegotiateDatagram set") 128 | if NegotiateFlags & NTLM_NegotiateLanManagerKey: 129 | print("NTLM_NegotiateLanManagerKey set") 130 | if NegotiateFlags & NTLM_Unknown8: 131 | print("NTLM_Unknown8 set") 132 | if NegotiateFlags & NTLM_NegotiateNTLM: 133 | print("NTLM_NegotiateNTLM set") 134 | if NegotiateFlags & NTLM_NegotiateNTOnly: 135 | print("NTLM_NegotiateNTOnly set") 136 | if NegotiateFlags & NTLM_Anonymous: 137 | print("NTLM_Anonymous set") 138 | if NegotiateFlags & NTLM_NegotiateOemDomainSupplied: 139 | print("NTLM_NegotiateOemDomainSupplied set") 140 | if NegotiateFlags & NTLM_NegotiateOemWorkstationSupplied: 141 | print("NTLM_NegotiateOemWorkstationSupplied set") 142 | if NegotiateFlags & NTLM_Unknown6: 143 | print("NTLM_Unknown6 set") 144 | if NegotiateFlags & NTLM_NegotiateAlwaysSign: 145 | print("NTLM_NegotiateAlwaysSign set") 146 | if NegotiateFlags & NTLM_TargettypeDomain: 147 | print("NTLM_TargettypeDomain set") 148 | if NegotiateFlags & NTLM_TargettypeServer: 149 | print("NTLM_TargettypeServer set") 150 | if NegotiateFlags & NTLM_TargettypeShare: 151 | print("NTLM_TargettypeShare set") 152 | if NegotiateFlags & NTLM_NegotiateExtendedSecurity: 153 | print("NTLM_NegotiateExtendedSecurity set") 154 | if NegotiateFlags & NTLM_NegotiateIdentify: 155 | print("NTLM_NegotiateIdentify set") 156 | if NegotiateFlags & NTLM_Unknown5: 157 | print("NTLM_Unknown5 set") 158 | if NegotiateFlags & NTLM_RequestNonNTSessionKey: 159 | print("NTLM_RequestNonNTSessionKey set") 160 | if NegotiateFlags & NTLM_NegotiateTargetInfo: 161 | print("NTLM_NegotiateTargetInfo set") 162 | if NegotiateFlags & NTLM_Unknown4: 163 | print("NTLM_Unknown4 set") 164 | if NegotiateFlags & NTLM_NegotiateVersion: 165 | print("NTLM_NegotiateVersion set") 166 | if NegotiateFlags & NTLM_Unknown3: 167 | print("NTLM_Unknown3 set") 168 | if NegotiateFlags & NTLM_Unknown2: 169 | print("NTLM_Unknown2 set") 170 | if NegotiateFlags & NTLM_Unknown1: 171 | print("NTLM_Unknown1 set") 172 | if NegotiateFlags & NTLM_Negotiate128: 173 | print("NTLM_Negotiate128 set") 174 | if NegotiateFlags & NTLM_NegotiateKeyExchange: 175 | print("NTLM_NegotiateKeyExchange set") 176 | if NegotiateFlags & NTLM_Negotiate56: 177 | print("NTLM_Negotiate56 set") 178 | 179 | def create_NTLM_NEGOTIATE_MESSAGE(user, type1_flags=NTLM_TYPE1_FLAGS): 180 | BODY_LENGTH = 40 181 | Payload_start = BODY_LENGTH # in bytes 182 | protocol = b'NTLMSSP\0' #name 183 | 184 | type = struct.pack(' 3 | 4 | This downloads an NTML-protected webpage to stdout. The username is 5 | constructed from the USERDOMAIN and USERNAME environment variables. 6 | Note that the password is entered on the command line; this is almost 7 | certainly a security risk but unfortunately I know of no foolproof 8 | method in Python for prompting for a password from standard input. 9 | 10 | This script associates the password with all URLs using the same base 11 | URI. Although we only connect to a single URL, this would allow 12 | access to all resources within a single domain. This script also 13 | allows the use of basic and digest authentication as well as NTML. 14 | Finally, it disables the use of proxies, which would prevent it from 15 | leaving most corporate domains (which typically route external 16 | requests through a proxy server). 17 | """ 18 | 19 | import urllib.request, urllib.error, urllib.parse 20 | from urllib.parse import urlparse, urlunparse 21 | import inspect, os, sys 22 | 23 | try: 24 | from ntlm import HTTPNtlmAuthHandler 25 | except ImportError: 26 | # assume ntlm is in the directory "next door" 27 | ntlm_folder = os.path.realpath(os.path.join( 28 | os.path.dirname(inspect.getfile(inspect.currentframe())), 29 | '..')) 30 | sys.path.insert(0, ntlm_folder) 31 | from ntlm import HTTPNtlmAuthHandler 32 | 33 | def process(password, url): 34 | user = '%s\%s' % ( os.environ["USERDOMAIN"], os.environ["USERNAME"] ) 35 | 36 | # determine a base_uri for which the username and password can be used 37 | parsed_url = urlparse(url) 38 | base_uri = urlunparse((parsed_url[0],parsed_url[1],"","","","")) 39 | 40 | passman = urllib.request.HTTPPasswordMgrWithDefaultRealm() 41 | passman.add_password(None, base_uri, user, password) 42 | # create the NTLM authentication handler 43 | auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman) 44 | 45 | # other authentication handlers 46 | auth_basic = urllib.request.HTTPBasicAuthHandler(passman) 47 | auth_digest = urllib.request.HTTPDigestAuthHandler(passman) 48 | 49 | # disable proxies (if you want to stay within the corporate network) 50 | proxy_handler = urllib.request.ProxyHandler({}) 51 | 52 | # create and install the opener 53 | ## # Using auth_digest results in: 54 | ## # ValueError: AbstractDigestAuthHandler does not support the following scheme: 'NTLM' 55 | ## # See http://bugs.python.org/issue21413 56 | urllib.request.install_opener( 57 | urllib.request.build_opener( 58 | proxy_handler, 59 | auth_NTLM, 60 | ## auth_digest, 61 | auth_basic, 62 | )) 63 | 64 | # retrieve the result 65 | response = urllib.request.urlopen(url) 66 | print((response.read())) 67 | 68 | # The following is adapted from Guido van van Rossum's suggestion. 69 | # http://www.artima.com/weblogs/viewpost.jsp?thread=4829 70 | 71 | class Usage(Exception): 72 | def __init__(self, msg): 73 | self.msg = msg 74 | 75 | import sys 76 | import getopt 77 | 78 | def main(argv=None): 79 | if argv is None: 80 | argv = sys.argv 81 | try: 82 | try: 83 | opts, args = getopt.getopt(argv[1:], "h", ["help"]) 84 | except getopt.error as msg: 85 | raise Usage(msg) 86 | if opts: 87 | raise Usage(__doc__) 88 | if len(args) != 2: 89 | raise Usage('need exactly 2 arguments (%d given)' % len(args)) 90 | process(*args) 91 | except Usage as err: 92 | print(err.msg, file=sys.stderr) 93 | if err.msg is not __doc__: 94 | print("for help use --help", file=sys.stderr) 95 | return 2 96 | 97 | if __name__ == "__main__": 98 | sys.exit(main()) 99 | -------------------------------------------------------------------------------- /python30/ntlm_examples/simple.py: -------------------------------------------------------------------------------- 1 | """ 2 | Usage: simple.py 3 | 4 | This downloads an NTML-protected webpage to stdout. The username is 5 | constructed from the USERDOMAIN and USERNAME environment variables. 6 | Note that the password is entered on the command line; this is almost 7 | certainly a security risk but unfortunately I know of no foolproof 8 | method in Python for prompting for a password from standard input. 9 | 10 | This script only understands NTML authentication. 11 | """ 12 | 13 | import urllib.request, urllib.error, urllib.parse 14 | import inspect, os, sys 15 | 16 | try: 17 | from ntlm import HTTPNtlmAuthHandler 18 | except ImportError: 19 | # assume ntlm is in the directory "next door" 20 | ntlm_folder = os.path.realpath(os.path.join( 21 | os.path.dirname(inspect.getfile(inspect.currentframe())), 22 | '..')) 23 | sys.path.insert(0, ntlm_folder) 24 | from ntlm import HTTPNtlmAuthHandler 25 | 26 | def process(password, url): 27 | user = '%s\%s' % ( os.environ["USERDOMAIN"], os.environ["USERNAME"] ) 28 | 29 | passman = urllib.request.HTTPPasswordMgrWithDefaultRealm() 30 | passman.add_password(None, url, user, password) 31 | # create the NTLM authentication handler 32 | auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman) 33 | 34 | # create and install the opener 35 | opener = urllib.request.build_opener(auth_NTLM) 36 | urllib.request.install_opener(opener) 37 | 38 | # retrieve the result 39 | response = urllib.request.urlopen(url) 40 | print((response.read())) 41 | 42 | # The following is adapted from Guido van van Rossum's suggestion. 43 | # http://www.artima.com/weblogs/viewpost.jsp?thread=4829 44 | 45 | class Usage(Exception): 46 | def __init__(self, msg): 47 | self.msg = msg 48 | 49 | import sys 50 | import getopt 51 | 52 | def main(argv=None): 53 | if argv is None: 54 | argv = sys.argv 55 | try: 56 | try: 57 | opts, args = getopt.getopt(argv[1:], "h", ["help"]) 58 | except getopt.error as msg: 59 | raise Usage(msg) 60 | if opts: 61 | raise Usage(__doc__) 62 | if len(args) != 2: 63 | raise Usage('need exactly 2 arguments (%d given)' % len(args)) 64 | process(*args) 65 | except Usage as err: 66 | print(err.msg, file=sys.stderr) 67 | if err.msg is not __doc__: 68 | print("for help use --help", file=sys.stderr) 69 | return 2 70 | 71 | if __name__ == "__main__": 72 | sys.exit(main()) 73 | -------------------------------------------------------------------------------- /python30/ntlm_examples/test_ntlmauth.py: -------------------------------------------------------------------------------- 1 | """\ 2 | Demonstrate various defects (or their repair!) in the ntml module. 3 | """ 4 | 5 | 6 | from io import BytesIO 7 | import http.client 8 | import inspect, os, sys 9 | import traceback 10 | import urllib.request, urllib.error, urllib.parse 11 | try: 12 | from ntlm import HTTPNtlmAuthHandler 13 | except ImportError: 14 | # assume ntlm is in the directory "next door" 15 | ntlm_folder = os.path.realpath(os.path.join( 16 | os.path.dirname(inspect.getfile(inspect.currentframe())), 17 | '..')) 18 | sys.path.insert(0, ntlm_folder) 19 | from ntlm import HTTPNtlmAuthHandler 20 | 21 | 22 | # The headers seen during an initial NTML rejection. 23 | initial_rejection = b'''HTTP/1.1 401 Unauthorized 24 | Server: Apache-Coyote/1.1 25 | WWW-Authenticate: NTLM 26 | Connection: close 27 | Date: Tue, 03 Feb 2009 11:47:33 GMT 28 | Connection: close 29 | 30 | ''' 31 | 32 | 33 | # The headers and data seen following a successful NTML connection. 34 | eventual_success = b'''HTTP/1.1 200 OK 35 | Server: Apache-Coyote/1.1 36 | WWW-Authenticate: NTLM TlRMTVNTUAACAAAABAAEADgAAAAFgomi3k7KRx+HGYQAAAAAAAAAALQAtAA8AAAABgGwHQAAAA9OAEEAAgAEAE4AQQABABYATgBBAFMAQQBOAEUAWABIAEMAMAA0AAQAHgBuAGEALgBxAHUAYQBsAGMAbwBtAG0ALgBjAG8AbQADADYAbgBhAHMAYQBuAGUAeABoAGMAMAA0AC4AbgBhAC4AcQB1AGEAbABjAG8AbQBtAC4AYwBvAG0ABQAiAGMAbwByAHAALgBxAHUAYQBsAGMAbwBtAG0ALgBjAG8AbQAHAAgADXHouNLjzAEAAAAA 37 | Date: Tue, 03 Feb 2009 11:47:33 GMT 38 | Connection: close 39 | 40 | Hello, world!''' 41 | 42 | 43 | # A collection of transactions representing various defects in NTLM 44 | # processing. Each is indexed according the the issues number recorded 45 | # for the defect at code.google.com, and consists of a series of server 46 | # responses that should be seen as a connection is attempted. 47 | issues = { 48 | 27: [ 49 | initial_rejection, 50 | b'''HTTP/1.1 401 Unauthorized 51 | Server: Apache-Coyote/1.1 52 | WWW-Authenticate: NTLM TlRMTVNTUAACAAAABAAEADgAAAAFgomi3k7KRx+HGYQAAAAAAAAAALQAtAA8AAAABgGwHQAAAA9OAEEAAgAEAE4AQQABABYATgBBAFMAQQBOAEUAWABIAEMAMAA0AAQAHgBuAGEALgBxAHUAYQBsAGMAbwBtAG0ALgBjAG8AbQADADYAbgBhAHMAYQBuAGUAeABoAGMAMAA0AC4AbgBhAC4AcQB1AGEAbABjAG8AbQBtAC4AYwBvAG0ABQAiAGMAbwByAHAALgBxAHUAYQBsAGMAbwBtAG0ALgBjAG8AbQAHAAgADXHouNLjzAEAAAAA 53 | WWW-Authenticate: Negotiate 54 | Content-Length: 0 55 | Date: Tue, 03 Feb 2009 11:47:33 GMT 56 | Connection: close 57 | 58 | ''', 59 | eventual_success, 60 | ], 61 | 28: [ 62 | initial_rejection, 63 | b'''HTTP/1.1 401 Unauthorized 64 | Server: Apache-Coyote/1.1 65 | WWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAAAAAAAABAgAAO/AU3OJc3g0= 66 | Content-Length: 0 67 | Date: Tue, 03 Feb 2009 11:47:33 GMT 68 | Connection: close 69 | 70 | ''', 71 | eventual_success, 72 | ], 73 | } 74 | 75 | 76 | class FakeSocket(BytesIO): 77 | '''Extends BytesIO just enough to look like a socket.''' 78 | def makefile(self, *args, **kwds): 79 | '''The instance already looks like a file.''' 80 | return self 81 | def sendall(self, *args, **kwds): 82 | '''Ignore any data that may be sent.''' 83 | pass 84 | def close(self): 85 | '''Ignore any calls to close.''' 86 | pass 87 | 88 | 89 | class FakeHTTPConnection(http.client.HTTPConnection): 90 | '''Looks like a normal HTTPConnection, but returns a FakeSocket. 91 | The connection's port number is used to choose a set of transactions 92 | to replay to the user. A class static variable is used to track 93 | how many transactions have been replayed.''' 94 | attempt = {} 95 | def connect(self): 96 | '''Returns a FakeSocket containing the data for a single 97 | transaction.''' 98 | nbr = self.attempt.setdefault(self.port, 0) 99 | self.attempt[self.port] = nbr + 1 100 | print('connecting to %s:%s (attempt %s)' % (self.host, self.port, nbr)) 101 | self.sock = FakeSocket(issues[self.port][nbr]) 102 | 103 | 104 | class FakeHTTPHandler(urllib.request.HTTPHandler): 105 | connection = FakeHTTPConnection 106 | def http_open(self, req): 107 | print('opening', self.connection) 108 | return self.do_open(self.connection, req) 109 | 110 | 111 | def process(*issue_nbrs): 112 | '''Run the specified tests, or all of them.''' 113 | 114 | if issue_nbrs: 115 | # Make sure the tests are ints. 116 | issue_nbrs = list(map(int, issue_nbrs)) 117 | else: 118 | # If no tests were specified, run them all. 119 | issue_nbrs = list(issues.keys()) 120 | 121 | assert all(i in issues for i in issue_nbrs) 122 | 123 | user = 'DOMAIN\\User' 124 | password = "Password" 125 | url = "http://www.example.org:%s/" 126 | 127 | # Set passwords for each of the "servers" to which we will be connecting. 128 | # Each distinct port on a server requires it's own set of credentials. 129 | passman = urllib.request.HTTPPasswordMgrWithDefaultRealm() 130 | for k in issue_nbrs: 131 | passman.add_password(None, url % k, user, password) 132 | 133 | # Create the NTLM authentication handler. 134 | auth_NTLM = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passman) 135 | 136 | # Create and install openers for both the NTLM Auth handler and 137 | # our fake HTTP handler. 138 | opener = urllib.request.build_opener(auth_NTLM, FakeHTTPHandler) 139 | urllib.request.install_opener(opener) 140 | 141 | # The following is a massive kludge; let me explain why it is needed. 142 | HTTPNtlmAuthHandler.http.client.HTTPConnection = FakeHTTPConnection 143 | # At the heart of the urllib2 module is the opener director. Whenever a 144 | # URL is opened, the director is responsible for locating the proper 145 | # handler for the protocol specified in the URL. Frequently, an existing 146 | # protocol handler will be subclassed and then added to the collection 147 | # maintained by the director. When urlopen is called, the specified 148 | # request is immediately handed off to the director's "open" method 149 | # which finds the correct handler and invokes the protocol-specific 150 | # XXX_open method. At least in the case of the HTTP protocols, if an 151 | # error occurs then the director is called again to find and invoke a 152 | # handler for the error; these handlers generally open a new connection 153 | # after adding headers to avoid the error going forward. Finally, it is 154 | # important to note that at the present time, the HTTP handlers in 155 | # urllib2 are built using a class that isn't prepared to deal with a 156 | # persistent connection, so they always add a "Connection: close" header 157 | # to the request. 158 | # 159 | # Unfortunately, NTLM only certifies the current connection, meaning 160 | # that a "Connection: keep-alive" header must be used to keep it open 161 | # throughout the authentication process. Furthermore, because the opener 162 | # director only provides a do_open method, there is no way to discover 163 | # the type of connection without also opening it. This means that the 164 | # HTTPNtlmAuthHandler cannot use the normal HTTPHandler and must 165 | # therefore must hardcode the HTTPConnection class. If a custom class is 166 | # required for whatever reason, the only way to cause it to be used is 167 | # to monkey-patch the code, as is done in the line above. 168 | 169 | for i in sorted(issue_nbrs): 170 | print('\nissue %d' % i) 171 | try: 172 | f = urllib.request.urlopen(url % i) 173 | except: 174 | traceback.print_exc() 175 | else: 176 | print(f.read()) 177 | 178 | 179 | # The following is adapted from Guido van van Rossum's suggestion. 180 | # http://www.artima.com/weblogs/viewpost.jsp?thread=4829 181 | 182 | import sys 183 | import getopt 184 | 185 | class Usage(Exception): 186 | def __init__(self, msg): 187 | self.msg = msg 188 | 189 | def main(argv=None): 190 | """Usage: %s""" 191 | if argv is None: 192 | argv = sys.argv 193 | try: 194 | try: 195 | opts, args = getopt.getopt(argv[1:], "h", ["help"]) 196 | except getopt.error as msg: 197 | raise Usage(msg) 198 | if opts: 199 | raise Usage(main.__doc__) 200 | if len(args) > 0: 201 | raise Usage('takes no arguments (%d given)' % len(args)) 202 | process(*args) 203 | except Usage as err: 204 | print(err.msg, file=sys.stderr) 205 | if err.msg is not main.__doc__: 206 | print("for help use --help", file=sys.stderr) 207 | return 2 208 | main.__doc__ %= os.path.basename(sys.argv[0]) 209 | 210 | if __name__ == "__main__": 211 | sys.exit(main()) 212 | --------------------------------------------------------------------------------