diff --git a/.gitignore b/.gitignore index 1b0e799..c9c5d96 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ venv -config.json \ No newline at end of file +config.json +*.pyc \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6b05b4b --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,12 @@ +{ + "configurations": [ + { + "name": "Python: Current File", + "type": "python", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": false + } + ] +} diff --git a/web/backend/config.sample.json b/web/backend/config.sample.json index 6bd54b6..f94bf6a 100644 --- a/web/backend/config.sample.json +++ b/web/backend/config.sample.json @@ -3,8 +3,10 @@ "<nodename>": { "pub-endpoint": "<clearnet-fqdn/ip-address>", "api-con": "http://<node-(internal)-ip/hostname>:<port>/", - "comment": "/* from here: data to be displayed on the webinterface */", + "country": "...", // Countrycode: 2 capital letters + "city": "...", + "wg-key": "...=", // pubkey of node "internal-v4": "172.2x.xxx.xxx", "internal-v6": "fdxx:...", "internal-v4ll": "169.254.xxx.xxx", @@ -14,6 +16,7 @@ "MNT": "YOUR-MNT", // your MNT tag "listen": "0.0.0.0", "port": 8042, + "flask-secret-key": "<secret-please-replace>", // secret key for session cookies "flask-debug": false, // optional; default false "flask-template-dir": "../frontend/" // optional; default "../frontend" } \ No newline at end of file diff --git a/web/backend/kioubit-auth-pubkey.pem b/web/backend/kioubit-auth-pubkey.pem new file mode 100644 index 0000000..759b589 --- /dev/null +++ b/web/backend/kioubit-auth-pubkey.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA4DCOlR4g94udKvu9+zKbwqxV/rjg +7g/Ij91TnEqUhIBi3LBjBoykcSFnWBtXgnmrj0WxBt4vAj7YO5jCQZJMVeIALCcS +Fkn447bsp6NdQzxTMQ8UYTPX/g7AzxEDOVtXfSBo/BiZF9LYPmm0zwk+y7ZmR8Kf +02hEtJbbjN/GoD6Mq1c= +-----END PUBLIC KEY----- \ No newline at end of file diff --git a/web/backend/kioubit_verify.py b/web/backend/kioubit_verify.py new file mode 100644 index 0000000..371cf9d --- /dev/null +++ b/web/backend/kioubit_verify.py @@ -0,0 +1,49 @@ +#! /usr/bin/env python3 + +#import OpenSSL +#from OpenSSL.crypto import load_publickey, FILETYPE_PEM, X509 +#from OpenSSL.crypto import verify as OpenSSL_verify +import base64, os +#from hashlib import sha512 +from Crypto.PublicKey import ECC +from Crypto.Signature import DSS +import Crypto.Hash.SHA512 as SHA512 +#from hashlib import sha512 as SHA512 + +PUBKEY_FILE = os.path.dirname(__file__)+"/kioubit-auth-pubkey.pem" + +class AuthVerifyer (): + + def __init__(self,domain, pubkey=PUBKEY_FILE): + self.domain = domain + with open(pubkey) as pk: + pk_content = "" + for line in pk.readlines(): + pk_content += line + print(pk_content) + self.pubkey = ECC.import_key(pk_content) + #self.pubkey.set_pubkey( + # load_publickey(OpenSSL.crypto.FILETYPE_PEM, pk_content) + #) + + print(self.pubkey) + + def verify(self, params, signature): + # sig = base64.b64decode(signature) + # print(type(sig)) + #OpenSSL_verify(self.pubkey, sig + #, base64.b64decode(params), "sha512") + h = SHA512.new() + h.update(base64.b64decode(params)) + print(h.hexdigest()) + verifier = DSS.new(self.pubkey, 'fips-186-3') + print(verifier.verify(h, signature)) + +if __name__ == "__main__": + example_com_verifier = AuthVerifyer("example.com") + example_com_verifier.verify( + params="eyJhc24iOiI0MjQyNDIzMDM1IiwidGltZSI6MTY2ODI2NjkyNiwiYWxsb3dlZDQiOiIxNzIuMjIuMTI1LjEyOFwvMjYsMTcyLjIwLjAuODFcLzMyIiwiYWxsb3dlZDYiOiJmZDYzOjVkNDA6NDdlNTo6XC80OCxmZDQyOmQ0MjpkNDI6ODE6OlwvNjQiLCJtbnQiOiJMQVJFLU1OVCIsImF1dGh0eXBlIjoibG9naW5jb2RlIiwiZG9tYWluIjoic3ZjLmJ1cmJsZS5kbjQyIn0=", + signature="MIGIAkIBAmwz3sQ1vOkH8+8e0NJ8GsUqKSaazIWmYDp60sshlTo7gCAopZOZ6/+tD6s+oEGM1i5mKGbHgK9ROATQLHxUZecCQgCa2N828uNn76z1Yg63/c7veMVIiK4l1X9TCUepJnJ3mCto+7ogCP+2vQm6GHipSNRF4wnt6tZbir0HZvrqEnRAmA==" + ) +#params = "eyJhc24iOiI0MjQyNDIzMDM1IiwidGltZSI6MTY2ODI1NjI5NSwiYWxsb3dlZDQiOiIxNzIuMjIuMTI1LjEyOFwvMjYsMTcyLjIwLjAuODFcLzMyIiwiYWxsb3dlZDYiOiJmZDYzOjVkNDA6NDdlNTo6XC80OCxmZDQyOmQ0MjpkNDI6ODE6OlwvNjQiLCJtbnQiOiJMQVJFLU1OVCIsImF1dGh0eXBlIjoibG9naW5jb2RlIiwiZG9tYWluIjoic3ZjLmJ1cmJsZS5kbjQyIn0=", +#signature = 'MIGHAkFy1m+9ahjIc5cJk/p+RiXJbhbWT5rPSJNg9Q3c8UTAM4F7lz2OqdWHw6GZN5NQgvqm6OB3Y751djYwCd54y2Kn4wJCAcBaOrtSclxkGIleVx183PhTnSr97r2F089PsDzNXIBvH5pYUwvJX7hG0op0f5tPm7fl12HOOrr8Q6kWW+XTrgGX' diff --git a/web/backend/main.py b/web/backend/main.py index 648cdf3..1e552e9 100644 --- a/web/backend/main.py +++ b/web/backend/main.py @@ -2,6 +2,7 @@ from flask import Flask, Response, redirect, render_template, request, session, abort import json, os +from functools import wraps app = Flask(__name__) @@ -38,17 +39,43 @@ class Config (dict): print(self._config) - config = Config() +def auth_required(): + def wrapper(f): + @wraps(f) + def decorated(*args, **kwargs): + if not "logged_in" in session: + return redirect(f"login?return={request.url}") + else: + return f(*args, **kwargs) + return decorated + return wrapper + + +@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"]) + + #elif request.method == "POST": + +@app.route("/peer", methods=["GET","POST"]) +@auth_required() +def peer(): + return request.args @app.route("/") def index(): - print(config) - return render_template("index.html", config=config) + # print(config._config["nodes"]) + # for node in config["nodes"].values(): + # print (node) + return render_template("index.html", config=config._config) def main(): app.static_folder= config["flask-template-dir"]+"/static/" app.template_folder=config["flask-template-dir"] + app.secret_key = config["flask-secret-key"] app.run(host=config["listen"], port=config["port"], debug=config["flask-debug"], threaded=True) diff --git a/web/frontend/base.html b/web/frontend/base.html new file mode 100644 index 0000000..956236b --- /dev/null +++ b/web/frontend/base.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <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"> +</head> +<body> + <header class="flex">{{config["MNT"]}}</header> + <div class="content flex">{% block content %}{% endblock %}</div> + <footer class="flex"> + <div></div> + <div></div> + <div> 🄯 LARE-MNT</div> + </footer> +</body> +</html> \ No newline at end of file diff --git a/web/frontend/index.html b/web/frontend/index.html index b3370b9..cf8fbf5 100644 --- a/web/frontend/index.html +++ b/web/frontend/index.html @@ -1,17 +1,30 @@ -<!DOCTYPE html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <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"> -</head> -<body> - <div class="content"> - <div>{{config["MNT"]}}</div> - <div></div> - <div></div> - </div> -</body> -</html> \ No newline at end of file +{% extends 'base.html' %} + +{% block content %} +<div> + +</div> +<div> + +</div> +<div> + <table> + <thead> + <tr> + <th>Country</th> + <th>City</th> + <th>peerings</th> + <th>Peer!</th> + </tr> + </thead> + {% for node in config["nodes"] %} + <tr> + <td>{{config["nodes"][node]["country"]}}</td> + <td>{{config["nodes"][node]["city"]}}</td> + <td></td> + <td><a href="peer?node={{node}}">peer</a></td> + </tr> + {% endfor %} + </table> +</div> +{% endblock %} \ No newline at end of file diff --git a/web/frontend/login.html b/web/frontend/login.html new file mode 100644 index 0000000..631cb3b --- /dev/null +++ b/web/frontend/login.html @@ -0,0 +1,17 @@ +{% extends 'base.html' %} + +{% block content %} + +<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="{{return_addr}}"> + <button type="submit" class="kioubit-btn kioubit-btn-primary kioubit-btn-dark kioubit-btn-main"> + <span class="icon-kioubit-auth"></span>Authenticate with Kioubit.dn42 + </button> +</form> + +<form action="" method="post"> + <input type=""> +</form> + +{% endblock %} \ No newline at end of file diff --git a/web/frontend/static/style.css b/web/frontend/static/style.css index cc56f0a..f1af515 100644 --- a/web/frontend/static/style.css +++ b/web/frontend/static/style.css @@ -1,4 +1,46 @@ +:root { + --bg-color: #aaa; + --text-color: black; + --other-background: #444; +} + body { - color: wheat; - background-color: black; + margin: 0; + width: auto; + height: auto; + background-color: var(--bg-color); +} + +header { + background-color: var(--other-background); + height: 50px; +} +.content { + width: 100%; + height: calc(100% - 55px); + margin: initial; +} + +.flex { + display: flex; + flex-direction: column; +} + +.flex>* { + flex-flow: column; + /* width: 1fr; + height: 1fr; */ + /* background-color: aquamarine; */ + margin: auto; +} + +footer { + position: fixed; + bottom: 0; + width: 100%; + height: 40px; + background: var(--other-background); +} +footer.flex { + flex-direction: row; } \ No newline at end of file diff --git a/web/requirements.txt b/web/requirements.txt new file mode 100644 index 0000000..7cf74ff --- /dev/null +++ b/web/requirements.txt @@ -0,0 +1,2 @@ +Flask +pyopenssl \ No newline at end of file