add signature verification module

- (the (test) signature allegedly has the wrong length?)
- add login route for main.py
This commit is contained in:
lare 2022-11-12 14:50:18 +01:00
parent 9cf41845a8
commit a1e25a9bdc
11 changed files with 215 additions and 24 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
venv venv
config.json config.json
*.pyc

12
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,12 @@
{
"configurations": [
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal",
"justMyCode": false
}
]
}

View file

@ -3,8 +3,10 @@
"<nodename>": { "<nodename>": {
"pub-endpoint": "<clearnet-fqdn/ip-address>", "pub-endpoint": "<clearnet-fqdn/ip-address>",
"api-con": "http://<node-(internal)-ip/hostname>:<port>/", "api-con": "http://<node-(internal)-ip/hostname>:<port>/",
"comment": "/* from here: data to be displayed on the webinterface */", "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-v4": "172.2x.xxx.xxx",
"internal-v6": "fdxx:...", "internal-v6": "fdxx:...",
"internal-v4ll": "169.254.xxx.xxx", "internal-v4ll": "169.254.xxx.xxx",
@ -14,6 +16,7 @@
"MNT": "YOUR-MNT", // your MNT tag "MNT": "YOUR-MNT", // your MNT tag
"listen": "0.0.0.0", "listen": "0.0.0.0",
"port": 8042, "port": 8042,
"flask-secret-key": "<secret-please-replace>", // secret key for session cookies
"flask-debug": false, // optional; default false "flask-debug": false, // optional; default false
"flask-template-dir": "../frontend/" // optional; default "../frontend" "flask-template-dir": "../frontend/" // optional; default "../frontend"
} }

View file

@ -0,0 +1,6 @@
-----BEGIN PUBLIC KEY-----
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA4DCOlR4g94udKvu9+zKbwqxV/rjg
7g/Ij91TnEqUhIBi3LBjBoykcSFnWBtXgnmrj0WxBt4vAj7YO5jCQZJMVeIALCcS
Fkn447bsp6NdQzxTMQ8UYTPX/g7AzxEDOVtXfSBo/BiZF9LYPmm0zwk+y7ZmR8Kf
02hEtJbbjN/GoD6Mq1c=
-----END PUBLIC KEY-----

View file

@ -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'

View file

@ -2,6 +2,7 @@
from flask import Flask, Response, redirect, render_template, request, session, abort from flask import Flask, Response, redirect, render_template, request, session, abort
import json, os import json, os
from functools import wraps
app = Flask(__name__) app = Flask(__name__)
@ -38,17 +39,43 @@ class Config (dict):
print(self._config) print(self._config)
config = 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("/") @app.route("/")
def index(): def index():
print(config) # print(config._config["nodes"])
return render_template("index.html", config=config) # for node in config["nodes"].values():
# print (node)
return render_template("index.html", config=config._config)
def main(): def main():
app.static_folder= config["flask-template-dir"]+"/static/" app.static_folder= config["flask-template-dir"]+"/static/"
app.template_folder=config["flask-template-dir"] 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) app.run(host=config["listen"], port=config["port"], debug=config["flask-debug"], threaded=True)

19
web/frontend/base.html Normal file
View file

@ -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> &#127279; LARE-MNT</div>
</footer>
</body>
</html>

View file

@ -1,17 +1,30 @@
<!DOCTYPE html> {% extends 'base.html' %}
<html lang="en">
<head> {% block content %}
<meta charset="UTF-8"> <div>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> </div>
<title>{{config["MNT"]}} Autopeering</title> <div>
<link rel="stylesheet" href="static/style.css">
</head> </div>
<body> <div>
<div class="content"> <table>
<div>{{config["MNT"]}}</div> <thead>
<div></div> <tr>
<div></div> <th>Country</th>
</div> <th>City</th>
</body> <th>peerings</th>
</html> <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 %}

17
web/frontend/login.html Normal file
View file

@ -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 %}

View file

@ -1,4 +1,46 @@
body { :root {
color: wheat; --bg-color: #aaa;
background-color: black; --text-color: black;
--other-background: #444;
}
body {
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;
} }

2
web/requirements.txt Normal file
View file

@ -0,0 +1,2 @@
Flask
pyopenssl