diff options
author | Yves Fischer <yvesf-git@xapek.org> | 2016-07-09 21:36:50 +0200 |
---|---|---|
committer | Yves Fischer <yvesf-git@xapek.org> | 2016-07-09 21:48:26 +0200 |
commit | 045f9bc3b68f03d88b9623a0893eeca3ff1ff372 (patch) | |
tree | 043d0b4e261f8f41ae74938f210e5aa542652f9a /login.py | |
parent | 5d6a8c8939382c4c6fb9f3205a865606a28c9b42 (diff) | |
download | auth-xmppmessage-045f9bc3b68f03d88b9623a0893eeca3ff1ff372.tar.gz auth-xmppmessage-045f9bc3b68f03d88b9623a0893eeca3ff1ff372.zip |
implement server for nginx auth_request
Diffstat (limited to 'login.py')
-rwxr-xr-x | login.py | 92 |
1 files changed, 8 insertions, 84 deletions
@@ -1,78 +1,7 @@ #!/usr/bin/env python3.4 import os -import re import sys -import time -import struct -import hashlib -from urllib.parse import quote as urlencode - -# To speed up start time load some modules only as needed - -if sys.version_info < (3, 0): - raise Exception("Require python3+") - - -def file_lock(lock_file): - from contextlib import contextmanager - - @contextmanager - def file_lock(): - try: - with open(lock_file, "x") as fh: - try: - yield - except: - raise - finally: - fh.close() - os.remove(lock_file) - except FileExistsError: - raise Exception("Locking failed on {}".format(lock_file)) - return file_lock() - - -def send_message(jid, password, recipient, message): - import sleekxmpp - - def start(event): - cl.send_message(mto=recipient, mtype='chat', mbody=message) - cl.disconnect(wait=True) - - cl = sleekxmpp.ClientXMPP(jid, password) - cl.add_event_handler("session_start", start, threaded=True) - if cl.connect(): - cl.process(block=True) - else: - raise Exception("Unable to connect to xmpp server") - - -def generate_token(username, secret, time): - input = "{}{}{}".format(secret, username, time).encode('utf-8') - output = struct.unpack(b"<L", hashlib.md5(input).digest()[:4])[0] - token = "{:02X}-{:02X}-{:02X}".format( - (output >> 16) & 0xff, (output >> 8) & 0xff, output & 0xff) - return token - - -def token_message(username, secret, validsec): - time_now = int(time.time()) - time_now_start = int(time_now - time_now % validsec) - time_next_end = time_now_start + 2 * validsec - token = generate_token(username, secret, time_now_start) - message = "Username: {} Token: {}".format(username, token) - message += "\nValid from: {} to: {}".format( - time.strftime("%c %Z(%z)", time.gmtime(time_now_start)), - time.strftime("%c %Z(%z)", time.gmtime(time_next_end))) - message += "\nRequested by: {} for: {} on: {}".format( - os.getenv("IP"), ascii(os.getenv("URI")), os.getenv("HTTP_HOST")) - message += "\nhttps://{}:{}@{}{}".format(urlencode(username), - token, os.getenv("HTTP_HOST"), urlencode(os.getenv("URI"))) - return message - - -def normalize_token(token): - return re.sub(r"[^A-F0-9]", "", token.upper()) +import functions def run(config): @@ -89,25 +18,20 @@ def run(config): if password == "" and username in conf_users: # avoid spamming by allowing only one message sent at a time lockfile = os.path.basename(__file__) - with file_lock("/tmp/lock." + lockfile): - message = token_message(username, conf_secret, conf_validsec) + with functions.file_lock("/tmp/lock." + lockfile): + message = functions.token_message(username, conf_secret, conf_validsec, + os.getenv("URI"), os.getenv("HTTP_HOST")) if os.getenv("SKIP_XMPP"): # used for testing print(message) else: - send_message(conf_jid, conf_jid_pw, username, message) + functions.send_message(conf_jid, conf_jid_pw, username, message) elif username in conf_users: - time_now = int(time.time()) - time_now_start = int(time_now - time_now % conf_validsec) - time_prev_start = time_now_start - conf_validsec - valid_tokens = list(map(normalize_token, ( - generate_token(username, conf_secret, time_now_start), - generate_token(username, conf_secret, time_prev_start) - ))) - if normalize_token(password) in valid_tokens: - return os.EX_OK # grant access + if functions.verify_token(username, password, conf_secret, conf_validsec): + return os.EX_OK return os.EX_NOPERM # fail by default + if __name__ == "__main__": config = dict(map(lambda kv: kv.split("="), os.getenv("CONTEXT").split(";"))) |