From aa3c0644570391caca12684ee4b4401b5e6c15d5 Mon Sep 17 00:00:00 2001 From: lare Date: Thu, 10 Nov 2022 20:38:03 +0100 Subject: [PATCH 01/42] INITIAL --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..c09534e --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# lare's autopeering implementation From ba9e5139a6b9caa7b233d008bb0e4c7c8e091dca Mon Sep 17 00:00:00 2001 From: lare Date: Thu, 10 Nov 2022 20:38:03 +0100 Subject: [PATCH 02/42] INITIAL --- README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..c09534e --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# lare's autopeering implementation From 3bddf1715f26ac40d8219dfd9c249b44f2a7186c Mon Sep 17 00:00:00 2001 From: lare Date: Thu, 10 Nov 2022 20:53:59 +0100 Subject: [PATCH 03/42] create folder structure and add READMEs --- nodes/readme.md | 3 +++ web/backend/readme.md | 6 ++++++ web/frontend/readme.md | 3 +++ web/readme.md | 3 +++ 4 files changed, 15 insertions(+) create mode 100644 nodes/readme.md create mode 100644 web/backend/readme.md create mode 100644 web/frontend/readme.md create mode 100644 web/readme.md diff --git a/nodes/readme.md b/nodes/readme.md new file mode 100644 index 0000000..10a783f --- /dev/null +++ b/nodes/readme.md @@ -0,0 +1,3 @@ +## nodes daemon: + +Daemon running on the nodes which are enrolled in auto peering to configure said peerings diff --git a/web/backend/readme.md b/web/backend/readme.md new file mode 100644 index 0000000..c1a8c06 --- /dev/null +++ b/web/backend/readme.md @@ -0,0 +1,6 @@ +### backend for autopeering: + +features: +- validate Users wanting to peer -> Kioubit Authentication services or self implemented +- allow users to add/modify/delete peerings +- communicate with nodes so they configure the peerings diff --git a/web/frontend/readme.md b/web/frontend/readme.md new file mode 100644 index 0000000..733460f --- /dev/null +++ b/web/frontend/readme.md @@ -0,0 +1,3 @@ +### frontend for auto-peering +files for webfrontend of the autopeering + diff --git a/web/readme.md b/web/readme.md new file mode 100644 index 0000000..e3ed4ff --- /dev/null +++ b/web/readme.md @@ -0,0 +1,3 @@ +## webserver and frontend for the server hosting the autopeering webinterface + + From f5bd6b5a5f304bf1d0c0190a0d62c59205607b3f Mon Sep 17 00:00:00 2001 From: lare Date: Thu, 10 Nov 2022 20:53:59 +0100 Subject: [PATCH 04/42] create folder structure and add READMEs --- nodes/readme.md | 3 +++ web/backend/readme.md | 6 ++++++ web/frontend/readme.md | 3 +++ web/readme.md | 3 +++ 4 files changed, 15 insertions(+) create mode 100644 nodes/readme.md create mode 100644 web/backend/readme.md create mode 100644 web/frontend/readme.md create mode 100644 web/readme.md diff --git a/nodes/readme.md b/nodes/readme.md new file mode 100644 index 0000000..10a783f --- /dev/null +++ b/nodes/readme.md @@ -0,0 +1,3 @@ +## nodes daemon: + +Daemon running on the nodes which are enrolled in auto peering to configure said peerings diff --git a/web/backend/readme.md b/web/backend/readme.md new file mode 100644 index 0000000..c1a8c06 --- /dev/null +++ b/web/backend/readme.md @@ -0,0 +1,6 @@ +### backend for autopeering: + +features: +- validate Users wanting to peer -> Kioubit Authentication services or self implemented +- allow users to add/modify/delete peerings +- communicate with nodes so they configure the peerings diff --git a/web/frontend/readme.md b/web/frontend/readme.md new file mode 100644 index 0000000..733460f --- /dev/null +++ b/web/frontend/readme.md @@ -0,0 +1,3 @@ +### frontend for auto-peering +files for webfrontend of the autopeering + diff --git a/web/readme.md b/web/readme.md new file mode 100644 index 0000000..e3ed4ff --- /dev/null +++ b/web/readme.md @@ -0,0 +1,3 @@ +## webserver and frontend for the server hosting the autopeering webinterface + + From 6344dbb07f9d31627f581173a1aebdcad8105835 Mon Sep 17 00:00:00 2001 From: lare Date: Fri, 11 Nov 2022 20:17:37 +0100 Subject: [PATCH 05/42] add sample config.json + working webserver --- .gitignore | 2 ++ web/backend/config.sample.json | 19 ++++++++++++ web/backend/main.py | 56 ++++++++++++++++++++++++++++++++++ web/backend/templates | 1 + web/frontend/index.html | 17 +++++++++++ web/frontend/static/style.css | 4 +++ 6 files changed, 99 insertions(+) create mode 100644 .gitignore create mode 100644 web/backend/config.sample.json create mode 100644 web/backend/main.py create mode 120000 web/backend/templates create mode 100644 web/frontend/index.html create mode 100644 web/frontend/static/style.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b0e799 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +venv +config.json \ No newline at end of file diff --git a/web/backend/config.sample.json b/web/backend/config.sample.json new file mode 100644 index 0000000..6bd54b6 --- /dev/null +++ b/web/backend/config.sample.json @@ -0,0 +1,19 @@ +{ + "nodes": { + "": { + "pub-endpoint": "", + "api-con": "http://:/", + + "comment": "/* from here: data to be displayed on the webinterface */", + "internal-v4": "172.2x.xxx.xxx", + "internal-v6": "fdxx:...", + "internal-v4ll": "169.254.xxx.xxx", + "internal-v6ll": "fe80::..." + } + }, + "MNT": "YOUR-MNT", // your MNT tag + "listen": "0.0.0.0", + "port": 8042, + "flask-debug": false, // optional; default false + "flask-template-dir": "../frontend/" // optional; default "../frontend" +} \ No newline at end of file diff --git a/web/backend/main.py b/web/backend/main.py new file mode 100644 index 0000000..648cdf3 --- /dev/null +++ b/web/backend/main.py @@ -0,0 +1,56 @@ +#! /usr/bin/env python3 + +from flask import Flask, Response, redirect, render_template, request, session, abort +import json, os + +app = Flask(__name__) + +class Config (dict): + def __init__(self, configfile:str = None): + if configfile: + self.configfile = configfile + else: + if os.path.exists("./config.json"): self.configfile = "./config.json" + elif os.path.exists("/etc/dn42-autopeer/config.json"): self.configfile = "/etc/dn42-autopeer/config,json" + else: raise FileNotFoundError("no config file found in ./config.json or /etc/dn42-autopeer/config.json") + self.load_config() + self.keys = self._config.keys + #self.__getitem__ = self._config.__getitem__ + super().__init__(self) + + def __delitem__(self, v): + raise NotImplementedError() + super().__delitem__(self,v) + def __getitem__(self, k): + return self._config[k] + def load_config(self): + with open(self.configfile) as cf: + try: + self._config = json.load(cf) + except json.decoder.JSONDecodeError: + raise SyntaxError(f"no valid JSON found in '{cf.name}'") + + if not "flask-template-dir" in self._config: + self._config["flask-template-dir"] = "../frontend" + + if not "flask-debug" in self._config: + self._config["flask-debug"] = False + + print(self._config) + + +config = Config() + +@app.route("/") +def index(): + print(config) + return render_template("index.html", config=config) + +def main(): + app.static_folder= config["flask-template-dir"]+"/static/" + app.template_folder=config["flask-template-dir"] + app.run(host=config["listen"], port=config["port"], debug=config["flask-debug"], threaded=True) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/web/backend/templates b/web/backend/templates new file mode 120000 index 0000000..af28878 --- /dev/null +++ b/web/backend/templates @@ -0,0 +1 @@ +../frontend \ No newline at end of file diff --git a/web/frontend/index.html b/web/frontend/index.html new file mode 100644 index 0000000..b3370b9 --- /dev/null +++ b/web/frontend/index.html @@ -0,0 +1,17 @@ + + + + + + + {{config["MNT"]}} Autopeering + + + +
+
{{config["MNT"]}}
+
+
+
+ + \ No newline at end of file diff --git a/web/frontend/static/style.css b/web/frontend/static/style.css new file mode 100644 index 0000000..cc56f0a --- /dev/null +++ b/web/frontend/static/style.css @@ -0,0 +1,4 @@ +body { + color: wheat; + background-color: black; +} \ No newline at end of file From 9cf41845a8580179d7abdcf549ff7eb2d6c753cf Mon Sep 17 00:00:00 2001 From: lare Date: Fri, 11 Nov 2022 20:17:37 +0100 Subject: [PATCH 06/42] add sample config.json + working webserver --- .gitignore | 2 ++ web/backend/config.sample.json | 19 ++++++++++++ web/backend/main.py | 56 ++++++++++++++++++++++++++++++++++ web/backend/templates | 1 + web/frontend/index.html | 17 +++++++++++ web/frontend/static/style.css | 4 +++ 6 files changed, 99 insertions(+) create mode 100644 .gitignore create mode 100644 web/backend/config.sample.json create mode 100644 web/backend/main.py create mode 120000 web/backend/templates create mode 100644 web/frontend/index.html create mode 100644 web/frontend/static/style.css diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b0e799 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +venv +config.json \ No newline at end of file diff --git a/web/backend/config.sample.json b/web/backend/config.sample.json new file mode 100644 index 0000000..6bd54b6 --- /dev/null +++ b/web/backend/config.sample.json @@ -0,0 +1,19 @@ +{ + "nodes": { + "": { + "pub-endpoint": "", + "api-con": "http://:/", + + "comment": "/* from here: data to be displayed on the webinterface */", + "internal-v4": "172.2x.xxx.xxx", + "internal-v6": "fdxx:...", + "internal-v4ll": "169.254.xxx.xxx", + "internal-v6ll": "fe80::..." + } + }, + "MNT": "YOUR-MNT", // your MNT tag + "listen": "0.0.0.0", + "port": 8042, + "flask-debug": false, // optional; default false + "flask-template-dir": "../frontend/" // optional; default "../frontend" +} \ No newline at end of file diff --git a/web/backend/main.py b/web/backend/main.py new file mode 100644 index 0000000..648cdf3 --- /dev/null +++ b/web/backend/main.py @@ -0,0 +1,56 @@ +#! /usr/bin/env python3 + +from flask import Flask, Response, redirect, render_template, request, session, abort +import json, os + +app = Flask(__name__) + +class Config (dict): + def __init__(self, configfile:str = None): + if configfile: + self.configfile = configfile + else: + if os.path.exists("./config.json"): self.configfile = "./config.json" + elif os.path.exists("/etc/dn42-autopeer/config.json"): self.configfile = "/etc/dn42-autopeer/config,json" + else: raise FileNotFoundError("no config file found in ./config.json or /etc/dn42-autopeer/config.json") + self.load_config() + self.keys = self._config.keys + #self.__getitem__ = self._config.__getitem__ + super().__init__(self) + + def __delitem__(self, v): + raise NotImplementedError() + super().__delitem__(self,v) + def __getitem__(self, k): + return self._config[k] + def load_config(self): + with open(self.configfile) as cf: + try: + self._config = json.load(cf) + except json.decoder.JSONDecodeError: + raise SyntaxError(f"no valid JSON found in '{cf.name}'") + + if not "flask-template-dir" in self._config: + self._config["flask-template-dir"] = "../frontend" + + if not "flask-debug" in self._config: + self._config["flask-debug"] = False + + print(self._config) + + +config = Config() + +@app.route("/") +def index(): + print(config) + return render_template("index.html", config=config) + +def main(): + app.static_folder= config["flask-template-dir"]+"/static/" + app.template_folder=config["flask-template-dir"] + app.run(host=config["listen"], port=config["port"], debug=config["flask-debug"], threaded=True) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/web/backend/templates b/web/backend/templates new file mode 120000 index 0000000..af28878 --- /dev/null +++ b/web/backend/templates @@ -0,0 +1 @@ +../frontend \ No newline at end of file diff --git a/web/frontend/index.html b/web/frontend/index.html new file mode 100644 index 0000000..b3370b9 --- /dev/null +++ b/web/frontend/index.html @@ -0,0 +1,17 @@ + + + + + + + {{config["MNT"]}} Autopeering + + + +
+
{{config["MNT"]}}
+
+
+
+ + \ No newline at end of file diff --git a/web/frontend/static/style.css b/web/frontend/static/style.css new file mode 100644 index 0000000..cc56f0a --- /dev/null +++ b/web/frontend/static/style.css @@ -0,0 +1,4 @@ +body { + color: wheat; + background-color: black; +} \ No newline at end of file From 9fa16e1ac93b63d4f2a4f95c33c43ddb4cd45181 Mon Sep 17 00:00:00 2001 From: lare Date: Sat, 12 Nov 2022 14:50:18 +0100 Subject: [PATCH 07/42] add signature verification module - (the (test) signature allegedly has the wrong length?) - add login route for main.py --- .gitignore | 3 +- .vscode/launch.json | 12 +++++++ web/backend/config.sample.json | 5 ++- web/backend/kioubit-auth-pubkey.pem | 6 ++++ web/backend/kioubit_verify.py | 49 +++++++++++++++++++++++++++++ web/backend/main.py | 33 +++++++++++++++++-- web/frontend/base.html | 19 +++++++++++ web/frontend/index.html | 47 +++++++++++++++++---------- web/frontend/login.html | 17 ++++++++++ web/frontend/static/style.css | 46 +++++++++++++++++++++++++-- web/requirements.txt | 2 ++ 11 files changed, 215 insertions(+), 24 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 web/backend/kioubit-auth-pubkey.pem create mode 100644 web/backend/kioubit_verify.py create mode 100644 web/frontend/base.html create mode 100644 web/frontend/login.html create mode 100644 web/requirements.txt 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 @@ "": { "pub-endpoint": "", "api-con": "http://:/", - "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 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 @@ + + + + + + + {{config["MNT"]}} Autopeering + + + +
{{config["MNT"]}}
+
{% block content %}{% endblock %}
+
+
+
+
🄯 LARE-MNT
+
+ + \ 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 @@ - - - - - - - {{config["MNT"]}} Autopeering - - - -
-
{{config["MNT"]}}
-
-
-
- - \ No newline at end of file +{% extends 'base.html' %} + +{% block content %} +
+ +
+
+ +
+
+ + + + + + + + + + {% for node in config["nodes"] %} + + + + + + + {% endfor %} +
CountryCitypeeringsPeer!
{{config["nodes"][node]["country"]}}{{config["nodes"][node]["city"]}}peer
+
+{% 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 %} + +
+ + + +
+ +
+ +
+ +{% 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 From a1e25a9bdc6ad5390f49ffe18b0114ce3875c699 Mon Sep 17 00:00:00 2001 From: lare Date: Sat, 12 Nov 2022 14:50:18 +0100 Subject: [PATCH 08/42] add signature verification module - (the (test) signature allegedly has the wrong length?) - add login route for main.py --- .gitignore | 3 +- .vscode/launch.json | 12 +++++++ web/backend/config.sample.json | 5 ++- web/backend/kioubit-auth-pubkey.pem | 6 ++++ web/backend/kioubit_verify.py | 49 +++++++++++++++++++++++++++++ web/backend/main.py | 33 +++++++++++++++++-- web/frontend/base.html | 19 +++++++++++ web/frontend/index.html | 47 +++++++++++++++++---------- web/frontend/login.html | 17 ++++++++++ web/frontend/static/style.css | 46 +++++++++++++++++++++++++-- web/requirements.txt | 2 ++ 11 files changed, 215 insertions(+), 24 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 web/backend/kioubit-auth-pubkey.pem create mode 100644 web/backend/kioubit_verify.py create mode 100644 web/frontend/base.html create mode 100644 web/frontend/login.html create mode 100644 web/requirements.txt 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 @@ "": { "pub-endpoint": "", "api-con": "http://:/", - "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 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 @@ + + + + + + + {{config["MNT"]}} Autopeering + + + +
{{config["MNT"]}}
+
{% block content %}{% endblock %}
+
+
+
+
🄯 LARE-MNT
+
+ + \ 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 @@ - - - - - - - {{config["MNT"]}} Autopeering - - - -
-
{{config["MNT"]}}
-
-
-
- - \ No newline at end of file +{% extends 'base.html' %} + +{% block content %} +
+ +
+
+ +
+
+ + + + + + + + + + {% for node in config["nodes"] %} + + + + + + + {% endfor %} +
CountryCitypeeringsPeer!
{{config["nodes"][node]["country"]}}{{config["nodes"][node]["city"]}}peer
+
+{% 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 %} + +
+ + + +
+ +
+ +
+ +{% 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 From e8c9c25a010ce62bfa1cb44823e09cfb27209f4e Mon Sep 17 00:00:00 2001 From: lare Date: Sat, 12 Nov 2022 17:36:11 +0100 Subject: [PATCH 09/42] add "domain" option to config.json add usages of the "domain" option --- web/backend/config.sample.json | 1 + web/backend/kioubit_verify.py | 5 +++-- web/backend/main.py | 14 +++++++++++++- web/frontend/login.html | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/web/backend/config.sample.json b/web/backend/config.sample.json index f94bf6a..be34908 100644 --- a/web/backend/config.sample.json +++ b/web/backend/config.sample.json @@ -16,6 +16,7 @@ "MNT": "YOUR-MNT", // your MNT tag "listen": "0.0.0.0", "port": 8042, + "domain": "example.org", // domain to use for kioubit verification service "flask-secret-key": "", // secret key for session cookies "flask-debug": false, // optional; default false "flask-template-dir": "../frontend/" // optional; default "../frontend" diff --git a/web/backend/kioubit_verify.py b/web/backend/kioubit_verify.py index 371cf9d..fc8a031 100644 --- a/web/backend/kioubit_verify.py +++ b/web/backend/kioubit_verify.py @@ -35,9 +35,10 @@ class AuthVerifyer (): #, base64.b64decode(params), "sha512") h = SHA512.new() h.update(base64.b64decode(params)) - print(h.hexdigest()) + #print(h.hexdigest()) verifier = DSS.new(self.pubkey, 'fips-186-3') - print(verifier.verify(h, signature)) + valid = verifier.verify(h, signature) + return valid if __name__ == "__main__": example_com_verifier = AuthVerifyer("example.com") diff --git a/web/backend/main.py b/web/backend/main.py index 1e552e9..296d167 100644 --- a/web/backend/main.py +++ b/web/backend/main.py @@ -1,9 +1,11 @@ #! /usr/bin/env python3 from flask import Flask, Response, redirect, render_template, request, session, abort -import json, os +import json, os, base64 from functools import wraps +import kioubit_verify + app = Flask(__name__) class Config (dict): @@ -40,6 +42,7 @@ class Config (dict): print(self._config) config = Config() + def auth_required(): def wrapper(f): @wraps(f) @@ -52,6 +55,15 @@ def auth_required(): return wrapper +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)) + + @app.route("/login",methods=["GET","POST"]) def login(): if request.method == "GET": diff --git a/web/frontend/login.html b/web/frontend/login.html index 631cb3b..e5df8aa 100644 --- a/web/frontend/login.html +++ b/web/frontend/login.html @@ -4,7 +4,7 @@
- + From c600c59af84dae55ecbf754ea6c78e4bedf3d2b3 Mon Sep 17 00:00:00 2001 From: lare Date: Sat, 12 Nov 2022 17:36:11 +0100 Subject: [PATCH 10/42] add "domain" option to config.json add usages of the "domain" option --- web/backend/config.sample.json | 1 + web/backend/kioubit_verify.py | 5 +++-- web/backend/main.py | 14 +++++++++++++- web/frontend/login.html | 2 +- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/web/backend/config.sample.json b/web/backend/config.sample.json index f94bf6a..be34908 100644 --- a/web/backend/config.sample.json +++ b/web/backend/config.sample.json @@ -16,6 +16,7 @@ "MNT": "YOUR-MNT", // your MNT tag "listen": "0.0.0.0", "port": 8042, + "domain": "example.org", // domain to use for kioubit verification service "flask-secret-key": "", // secret key for session cookies "flask-debug": false, // optional; default false "flask-template-dir": "../frontend/" // optional; default "../frontend" diff --git a/web/backend/kioubit_verify.py b/web/backend/kioubit_verify.py index 371cf9d..fc8a031 100644 --- a/web/backend/kioubit_verify.py +++ b/web/backend/kioubit_verify.py @@ -35,9 +35,10 @@ class AuthVerifyer (): #, base64.b64decode(params), "sha512") h = SHA512.new() h.update(base64.b64decode(params)) - print(h.hexdigest()) + #print(h.hexdigest()) verifier = DSS.new(self.pubkey, 'fips-186-3') - print(verifier.verify(h, signature)) + valid = verifier.verify(h, signature) + return valid if __name__ == "__main__": example_com_verifier = AuthVerifyer("example.com") diff --git a/web/backend/main.py b/web/backend/main.py index 1e552e9..296d167 100644 --- a/web/backend/main.py +++ b/web/backend/main.py @@ -1,9 +1,11 @@ #! /usr/bin/env python3 from flask import Flask, Response, redirect, render_template, request, session, abort -import json, os +import json, os, base64 from functools import wraps +import kioubit_verify + app = Flask(__name__) class Config (dict): @@ -40,6 +42,7 @@ class Config (dict): print(self._config) config = Config() + def auth_required(): def wrapper(f): @wraps(f) @@ -52,6 +55,15 @@ def auth_required(): return wrapper +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)) + + @app.route("/login",methods=["GET","POST"]) def login(): if request.method == "GET": diff --git a/web/frontend/login.html b/web/frontend/login.html index 631cb3b..e5df8aa 100644 --- a/web/frontend/login.html +++ b/web/frontend/login.html @@ -4,7 +4,7 @@ - + From b3051390331236da0806653bbbdf009e106559c4 Mon Sep 17 00:00:00 2001 From: lare Date: Sat, 12 Nov 2022 19:57:16 +0100 Subject: [PATCH 11/42] first (working) implementation of kioubit-auth - verify(, signature=base64decode(), ) --- web/backend/kioubit_verify.py | 46 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/web/backend/kioubit_verify.py b/web/backend/kioubit_verify.py index fc8a031..24cb8ec 100644 --- a/web/backend/kioubit_verify.py +++ b/web/backend/kioubit_verify.py @@ -1,14 +1,9 @@ #! /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 +from OpenSSL.crypto import load_publickey, FILETYPE_PEM, verify, X509 +import OpenSSL + PUBKEY_FILE = os.path.dirname(__file__)+"/kioubit-auth-pubkey.pem" @@ -21,30 +16,35 @@ class AuthVerifyer (): 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) - #) + pkey = load_publickey(FILETYPE_PEM, pk_content) + self.x509 = X509() + self.x509.set_pubkey(pkey) - print(self.pubkey) + print(self.x509) 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)) + sig = base64.b64decode(signature) + print(f"sig: {sig}") + print(f"params: {params}") + try: + 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, 'fips-186-3') - valid = verifier.verify(h, signature) - return valid + #verifier = DSS.new(self.pubkey, 'deterministic-rfc6979') + #valid = verifier.verify(h, base64.b64decode(signature)) + return True, "" if __name__ == "__main__": example_com_verifier = AuthVerifyer("example.com") - example_com_verifier.verify( - params="eyJhc24iOiI0MjQyNDIzMDM1IiwidGltZSI6MTY2ODI2NjkyNiwiYWxsb3dlZDQiOiIxNzIuMjIuMTI1LjEyOFwvMjYsMTcyLjIwLjAuODFcLzMyIiwiYWxsb3dlZDYiOiJmZDYzOjVkNDA6NDdlNTo6XC80OCxmZDQyOmQ0MjpkNDI6ODE6OlwvNjQiLCJtbnQiOiJMQVJFLU1OVCIsImF1dGh0eXBlIjoibG9naW5jb2RlIiwiZG9tYWluIjoic3ZjLmJ1cmJsZS5kbjQyIn0=", - signature="MIGIAkIBAmwz3sQ1vOkH8+8e0NJ8GsUqKSaazIWmYDp60sshlTo7gCAopZOZ6/+tD6s+oEGM1i5mKGbHgK9ROATQLHxUZecCQgCa2N828uNn76z1Yg63/c7veMVIiK4l1X9TCUepJnJ3mCto+7ogCP+2vQm6GHipSNRF4wnt6tZbir0HZvrqEnRAmA==" - ) + print (example_com_verifier.verify( + params=b"eyJhc24iOiI0MjQyNDIzMDM1IiwidGltZSI6MTY2ODI2NjkyNiwiYWxsb3dlZDQiOiIxNzIuMjIuMTI1LjEyOFwvMjYsMTcyLjIwLjAuODFcLzMyIiwiYWxsb3dlZDYiOiJmZDYzOjVkNDA6NDdlNTo6XC80OCxmZDQyOmQ0MjpkNDI6ODE6OlwvNjQiLCJtbnQiOiJMQVJFLU1OVCIsImF1dGh0eXBlIjoibG9naW5jb2RlIiwiZG9tYWluIjoic3ZjLmJ1cmJsZS5kbjQyIn0=", + signature=b"MIGIAkIBAmwz3sQ1vOkH8+8e0NJ8GsUqKSaazIWmYDp60sshlTo7gCAopZOZ6/+tD6s+oEGM1i5mKGbHgK9ROATQLHxUZecCQgCa2N828uNn76z1Yg63/c7veMVIiK4l1X9TCUepJnJ3mCto+7ogCP+2vQm6GHipSNRF4wnt6tZbir0HZvrqEnRAmA==" + ) ) #params = "eyJhc24iOiI0MjQyNDIzMDM1IiwidGltZSI6MTY2ODI1NjI5NSwiYWxsb3dlZDQiOiIxNzIuMjIuMTI1LjEyOFwvMjYsMTcyLjIwLjAuODFcLzMyIiwiYWxsb3dlZDYiOiJmZDYzOjVkNDA6NDdlNTo6XC80OCxmZDQyOmQ0MjpkNDI6ODE6OlwvNjQiLCJtbnQiOiJMQVJFLU1OVCIsImF1dGh0eXBlIjoibG9naW5jb2RlIiwiZG9tYWluIjoic3ZjLmJ1cmJsZS5kbjQyIn0=", #signature = 'MIGHAkFy1m+9ahjIc5cJk/p+RiXJbhbWT5rPSJNg9Q3c8UTAM4F7lz2OqdWHw6GZN5NQgvqm6OB3Y751djYwCd54y2Kn4wJCAcBaOrtSclxkGIleVx183PhTnSr97r2F089PsDzNXIBvH5pYUwvJX7hG0op0f5tPm7fl12HOOrr8Q6kWW+XTrgGX' From 83e411bcc3a5fd53181ab533e8d20b1459f30990 Mon Sep 17 00:00:00 2001 From: lare Date: Sat, 12 Nov 2022 19:57:16 +0100 Subject: [PATCH 12/42] first (working) implementation of kioubit-auth - verify(, signature=base64decode(), ) --- web/backend/kioubit_verify.py | 46 +++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/web/backend/kioubit_verify.py b/web/backend/kioubit_verify.py index fc8a031..24cb8ec 100644 --- a/web/backend/kioubit_verify.py +++ b/web/backend/kioubit_verify.py @@ -1,14 +1,9 @@ #! /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 +from OpenSSL.crypto import load_publickey, FILETYPE_PEM, verify, X509 +import OpenSSL + PUBKEY_FILE = os.path.dirname(__file__)+"/kioubit-auth-pubkey.pem" @@ -21,30 +16,35 @@ class AuthVerifyer (): 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) - #) + pkey = load_publickey(FILETYPE_PEM, pk_content) + self.x509 = X509() + self.x509.set_pubkey(pkey) - print(self.pubkey) + print(self.x509) 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)) + sig = base64.b64decode(signature) + print(f"sig: {sig}") + print(f"params: {params}") + try: + 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, 'fips-186-3') - valid = verifier.verify(h, signature) - return valid + #verifier = DSS.new(self.pubkey, 'deterministic-rfc6979') + #valid = verifier.verify(h, base64.b64decode(signature)) + return True, "" if __name__ == "__main__": example_com_verifier = AuthVerifyer("example.com") - example_com_verifier.verify( - params="eyJhc24iOiI0MjQyNDIzMDM1IiwidGltZSI6MTY2ODI2NjkyNiwiYWxsb3dlZDQiOiIxNzIuMjIuMTI1LjEyOFwvMjYsMTcyLjIwLjAuODFcLzMyIiwiYWxsb3dlZDYiOiJmZDYzOjVkNDA6NDdlNTo6XC80OCxmZDQyOmQ0MjpkNDI6ODE6OlwvNjQiLCJtbnQiOiJMQVJFLU1OVCIsImF1dGh0eXBlIjoibG9naW5jb2RlIiwiZG9tYWluIjoic3ZjLmJ1cmJsZS5kbjQyIn0=", - signature="MIGIAkIBAmwz3sQ1vOkH8+8e0NJ8GsUqKSaazIWmYDp60sshlTo7gCAopZOZ6/+tD6s+oEGM1i5mKGbHgK9ROATQLHxUZecCQgCa2N828uNn76z1Yg63/c7veMVIiK4l1X9TCUepJnJ3mCto+7ogCP+2vQm6GHipSNRF4wnt6tZbir0HZvrqEnRAmA==" - ) + print (example_com_verifier.verify( + params=b"eyJhc24iOiI0MjQyNDIzMDM1IiwidGltZSI6MTY2ODI2NjkyNiwiYWxsb3dlZDQiOiIxNzIuMjIuMTI1LjEyOFwvMjYsMTcyLjIwLjAuODFcLzMyIiwiYWxsb3dlZDYiOiJmZDYzOjVkNDA6NDdlNTo6XC80OCxmZDQyOmQ0MjpkNDI6ODE6OlwvNjQiLCJtbnQiOiJMQVJFLU1OVCIsImF1dGh0eXBlIjoibG9naW5jb2RlIiwiZG9tYWluIjoic3ZjLmJ1cmJsZS5kbjQyIn0=", + signature=b"MIGIAkIBAmwz3sQ1vOkH8+8e0NJ8GsUqKSaazIWmYDp60sshlTo7gCAopZOZ6/+tD6s+oEGM1i5mKGbHgK9ROATQLHxUZecCQgCa2N828uNn76z1Yg63/c7veMVIiK4l1X9TCUepJnJ3mCto+7ogCP+2vQm6GHipSNRF4wnt6tZbir0HZvrqEnRAmA==" + ) ) #params = "eyJhc24iOiI0MjQyNDIzMDM1IiwidGltZSI6MTY2ODI1NjI5NSwiYWxsb3dlZDQiOiIxNzIuMjIuMTI1LjEyOFwvMjYsMTcyLjIwLjAuODFcLzMyIiwiYWxsb3dlZDYiOiJmZDYzOjVkNDA6NDdlNTo6XC80OCxmZDQyOmQ0MjpkNDI6ODE6OlwvNjQiLCJtbnQiOiJMQVJFLU1OVCIsImF1dGh0eXBlIjoibG9naW5jb2RlIiwiZG9tYWluIjoic3ZjLmJ1cmJsZS5kbjQyIn0=", #signature = 'MIGHAkFy1m+9ahjIc5cJk/p+RiXJbhbWT5rPSJNg9Q3c8UTAM4F7lz2OqdWHw6GZN5NQgvqm6OB3Y751djYwCd54y2Kn4wJCAcBaOrtSclxkGIleVx183PhTnSr97r2F089PsDzNXIBvH5pYUwvJX7hG0op0f5tPm7fl12HOOrr8Q6kWW+XTrgGX' From 1770eeb201540cfc6816bc44f6403c5d121f6232 Mon Sep 17 00:00:00 2001 From: lare Date: Thu, 17 Nov 2022 06:43:43 +0100 Subject: [PATCH 13/42] add loading of MNT-data from kverify --- web/backend/kioubit_verify.py | 22 +++++++++----- web/backend/main.py | 56 ++++++++++++++++++++++++++++------- web/frontend/base.html | 9 ++++-- web/frontend/index.html | 2 ++ web/frontend/login.html | 9 +++++- web/frontend/peer.html | 13 ++++++++ web/frontend/static/style.css | 13 +++++++- 7 files changed, 100 insertions(+), 24 deletions(-) create mode 100644 web/frontend/peer.html 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 @@ {{config["MNT"]}} Autopeering - + -
{{config["MNT"]}}
-
{% block content %}{% endblock %}
+
{{config["MNT"]}} Autopeering{% if "login" in session %}logout{% else %} login{%endif%}
+
+ {% block content %} + {% endblock %} +