diff options
Diffstat (limited to 'libmproxy/authentication.py')
-rw-r--r-- | libmproxy/authentication.py | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/libmproxy/authentication.py b/libmproxy/authentication.py new file mode 100644 index 00000000..e5383f5a --- /dev/null +++ b/libmproxy/authentication.py @@ -0,0 +1,95 @@ +import binascii +import contrib.md5crypt as md5crypt + +class NullProxyAuth(): + """ No proxy auth at all (returns empty challange headers) """ + def __init__(self, password_manager=None): + self.password_manager = password_manager + self.username = "" + + def authenticate(self, auth_value): + """ Tests that the specified user is allowed to use the proxy (stub) """ + return True + + def auth_challenge_headers(self): + """ Returns a dictionary containing the headers require to challenge the user """ + return {} + + def get_username(self): + return self.username + + +class BasicProxyAuth(NullProxyAuth): + + def __init__(self, password_manager, realm="mitmproxy"): + NullProxyAuth.__init__(self, password_manager) + self.realm = "mitmproxy" + + def authenticate(self, auth_value): + if (not auth_value) or (not auth_value[0]): + return False; + try: + scheme, username, password = self.parse_authorization_header(auth_value[0]) + except: + return False + if scheme.lower()!='basic': + return False + if not self.password_manager.test(username, password): + return False + self.username = username + return True + + def auth_challenge_headers(self): + return {'Proxy-Authenticate':'Basic realm="%s"'%self.realm} + + def parse_authorization_header(self, auth_value): + words = auth_value.split() + scheme = words[0] + user = binascii.a2b_base64(words[1]) + username, password = user.split(':') + return scheme, username, password + +class PasswordManager(): + def __init__(self): + pass + + def test(self, username, password_token): + return False + +class PermissivePasswordManager(PasswordManager): + + def __init__(self): + PasswordManager.__init__(self) + + def test(self, username, password_token): + if username: + return True + return False + +class HtpasswdPasswordManager(PasswordManager): + """ Read usernames and passwords from a file created by Apache htpasswd""" + + def __init__(self, filehandle): + PasswordManager.__init__(self) + entries = (line.strip().split(':') for line in filehandle) + valid_entries = (entry for entry in entries if len(entry)==2) + self.usernames = {username:token for username,token in valid_entries} + + + def test(self, username, password_token): + if username not in self.usernames: + return False + full_token = self.usernames[username] + dummy, magic, salt, hashed_password = full_token.split('$') + expected = md5crypt.md5crypt(password_token, salt, '$'+magic+'$') + return expected==full_token + +class SingleUserPasswordManager(PasswordManager): + + def __init__(self, username, password): + PasswordManager.__init__(self) + self.username = username + self.password = password + + def test(self, username, password_token): + return self.username==username and self.password==password_token |