diff --git a/web/backend/kioubit_verify.py b/web/backend/kioubit_verify.py index 24cb8ec..1f9d3d2 100644 --- a/web/backend/kioubit_verify.py +++ b/web/backend/kioubit_verify.py @@ -1,8 +1,8 @@ #! /usr/bin/env python3 -import base64, os -from OpenSSL.crypto import load_publickey, FILETYPE_PEM, verify, X509 +import base64, os, json, time import OpenSSL +from OpenSSL.crypto import load_publickey, FILETYPE_PEM, verify, X509 PUBKEY_FILE = os.path.dirname(__file__)+"/kioubit-auth-pubkey.pem" @@ -33,12 +33,18 @@ class AuthVerifyer (): verify(self.x509, sig, params, 'sha512') except OpenSSL.crypto.Error: return False, "Signature Failed" - #h = SHA512.new() - #h.update(base64.b64decode(params)) - #print(h.hexdigest()) - #verifier = DSS.new(self.pubkey, 'deterministic-rfc6979') - #valid = verifier.verify(h, base64.b64decode(signature)) - return True, "" + + try: + user_data = json.loads(base64.b64decode(params)) + if (time.time() - user_data["time"] )> 60: + return False, "Signature to old" + except json.decoder.JSONDecodeError: + # we shouldn't get here unless kioubit's service is misbehaving + return False, "invalid JSON" + except KeyError: + return False, "value not found in JSON" + print(user_data) + return True, user_data if __name__ == "__main__": example_com_verifier = AuthVerifyer("example.com") diff --git a/web/backend/main.py b/web/backend/main.py index 296d167..ff80c5f 100644 --- a/web/backend/main.py +++ b/web/backend/main.py @@ -47,7 +47,7 @@ def auth_required(): def wrapper(f): @wraps(f) def decorated(*args, **kwargs): - if not "logged_in" in session: + if not "login" in session: return redirect(f"login?return={request.url}") else: return f(*args, **kwargs) @@ -58,31 +58,65 @@ def auth_required(): kverifyer = kioubit_verify.AuthVerifyer(config["domain"]) @app.route("/api/auth/kverify", methods=["GET", "POST"]) def kioubit_auth(): - params = request.args["params"] - signature = request.args["signature"] - print(base64.b64decode(params)) - return str(kverifyer.verify(params, signature)) + try: + params = request.args["params"] + signature = request.args["signature"] + except KeyError: + return render_template("login.html", session=session,config=config,return_addr=session["return_url"], msg='"params" or "signature" missing') + + success, msg = kverifyer.verify(params, signature) + try: print(base64.b64decode(params)) + except: print("invalid Base64 data provided") + + + if success: + session["user-data"] = msg + session["login"] = msg['mnt'] + return redirect(session["return_url"]) + else: + return render_template("login.html", session=session,config=config,return_addr=session["return_url"], msg=msg) + +@app.route("/logout") +def logout(): + session.clear() + return redirect("/") @app.route("/login",methods=["GET","POST"]) def login(): if request.method == "GET": - session["return_url"] = request.args["return"] - return render_template("login.html", config=config, return_addr=request.args["return"]) + session["return_url"] = request.args["return"] if "return" in request.args else "" + + return render_template("login.html", session=session, config=config, return_addr=session["return_url"]) + elif request.method == "POST": + if config["domain"] == "svc.burble.dn42:8042" and request.form["logincode"] and request.form["logincode"] == "eyJhc24iOjQyNDI0MjMwMzUsImFsbG93ZWQ0IjoiMTcyLjIyLjEyNS4xMjhcLzI2LDE3Mi4yMC4wLjgxXC8zMiIsImFsbG93ZWQ2IjoiZmQ2Mzo1ZDQwOjQ3ZTU6OlwvNDgsZmQ0MjpkNDI6ZDQyOjgxOjpcLzY0IiwibW50IjoiTEFSRS1NTlQifQo=": + print("abc") + user_data = json.loads(base64.b64decode(request.form["logincode"])) + session["login"] = user_data['mnt'] + session["user-data"] = user_data + return redirect(request.args["return"]) - #elif request.method == "POST": @app.route("/peer", methods=["GET","POST"]) @auth_required() def peer(): - return request.args - + if request.method == "GET": + if "node" in request.args and request.args["node"] in config["nodes"]: + return render_template("peer.html", config=config, selected_node=request.args["node"]) + return str(config["nodes"][request.args["node"]]) + else: return render_template("peer.html", session=session,config=config) + elif request.method == "POST": + return "POST /peer" + + else: + return 405 + @app.route("/") def index(): # print(config._config["nodes"]) # for node in config["nodes"].values(): # print (node) - return render_template("index.html", config=config._config) + return render_template("index.html", session=session, config=config._config) def main(): app.static_folder= config["flask-template-dir"]+"/static/" diff --git a/web/frontend/base.html b/web/frontend/base.html index 956236b..ffd4327 100644 --- a/web/frontend/base.html +++ b/web/frontend/base.html @@ -5,11 +5,14 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{config["MNT"]}} Autopeering</title> - <link rel="stylesheet" href="static/style.css"> + <link rel="stylesheet" href="/static/style.css"> </head> <body> - <header class="flex">{{config["MNT"]}}</header> - <div class="content flex">{% block content %}{% endblock %}</div> + <header class="flex flex-row"><div></div><a href="/">{{config["MNT"]}} Autopeering</a>{% if "login" in session %}<a href="/logout">logout</a>{% else %} <a href="/login?return=/peer">login</a>{%endif%}</header> + <div class="content flex"> + {% block content %} + {% endblock %} + </div> <footer class="flex"> <div></div> <div></div> diff --git a/web/frontend/index.html b/web/frontend/index.html index cf8fbf5..02c0b1f 100644 --- a/web/frontend/index.html +++ b/web/frontend/index.html @@ -11,6 +11,7 @@ <table> <thead> <tr> + <th>NodeName</th> <th>Country</th> <th>City</th> <th>peerings</th> @@ -19,6 +20,7 @@ </thead> {% for node in config["nodes"] %} <tr> + <td>{{node}}</td> <td>{{config["nodes"][node]["country"]}}</td> <td>{{config["nodes"][node]["city"]}}</td> <td></td> diff --git a/web/frontend/login.html b/web/frontend/login.html index e5df8aa..cb176bf 100644 --- a/web/frontend/login.html +++ b/web/frontend/login.html @@ -2,6 +2,12 @@ {% block content %} +{% if msg %} +<div style="background-color: red;"> + {{msg}} +</div> +{% endif %} + <form action="https://dn42.g-load.eu/auth/"> <link rel="stylesheet" href="https://dn42.g-load.eu/auth/assets/button-font/auth.css"> <input type="hidden" id="return" name="return" value='{{"http://"+config["domain"]+"/api/auth/kverify"}}'> @@ -11,7 +17,8 @@ </form> <form action="" method="post"> - <input type=""> + <input type="text" name="logincode" id="logincode"> + <input type="submit" value="submit"> </form> {% endblock %} \ No newline at end of file diff --git a/web/frontend/peer.html b/web/frontend/peer.html new file mode 100644 index 0000000..26a236a --- /dev/null +++ b/web/frontend/peer.html @@ -0,0 +1,13 @@ +{% extends 'base.html' %} + +{% block content %} + +<form action="peer" method="post"> + <select name="node" id="node"> + {% for node in config["nodes"] %} + <option value="{{node}}" {% if selected_node %}{% if selected_node == node %}selected{% endif %}{% endif %} >{{node}}</option> + {% endfor %} + </select> +</form> + +{% endblock %} \ No newline at end of file diff --git a/web/frontend/static/style.css b/web/frontend/static/style.css index f1af515..0cf0b2c 100644 --- a/web/frontend/static/style.css +++ b/web/frontend/static/style.css @@ -2,6 +2,7 @@ --bg-color: #aaa; --text-color: black; --other-background: #444; + /* --accent-color: ; */ } body { @@ -15,16 +16,26 @@ header { background-color: var(--other-background); height: 50px; } +a { + color: var(--text-color); +} + .content { width: 100%; height: calc(100% - 55px); - margin: initial; + margin: auto; +} +.content>* { + padding: 5%; } .flex { display: flex; flex-direction: column; } +.flex-row { + flex-direction: row; +} .flex>* { flex-flow: column;