From 045f9bc3b68f03d88b9623a0893eeca3ff1ff372 Mon Sep 17 00:00:00 2001 From: Yves Fischer Date: Sat, 9 Jul 2016 21:36:50 +0200 Subject: implement server for nginx auth_request --- login.py | 92 ++++++---------------------------------------------------------- 1 file changed, 8 insertions(+), 84 deletions(-) (limited to 'login.py') diff --git a/login.py b/login.py index 019cbf7..24f62a1 100755 --- a/login.py +++ b/login.py @@ -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"> 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(";"))) -- cgit v1.2.1