add signature verification module
- (the (test) signature allegedly has the wrong length?) - add login route for main.py
This commit is contained in:
parent
9cf41845a8
commit
a1e25a9bdc
11 changed files with 215 additions and 24 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
venv
|
venv
|
||||||
config.json
|
config.json
|
||||||
|
*.pyc
|
12
.vscode/launch.json
vendored
Normal file
12
.vscode/launch.json
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Python: Current File",
|
||||||
|
"type": "python",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${file}",
|
||||||
|
"console": "integratedTerminal",
|
||||||
|
"justMyCode": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -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"
|
||||||
}
|
}
|
6
web/backend/kioubit-auth-pubkey.pem
Normal file
6
web/backend/kioubit-auth-pubkey.pem
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQA4DCOlR4g94udKvu9+zKbwqxV/rjg
|
||||||
|
7g/Ij91TnEqUhIBi3LBjBoykcSFnWBtXgnmrj0WxBt4vAj7YO5jCQZJMVeIALCcS
|
||||||
|
Fkn447bsp6NdQzxTMQ8UYTPX/g7AzxEDOVtXfSBo/BiZF9LYPmm0zwk+y7ZmR8Kf
|
||||||
|
02hEtJbbjN/GoD6Mq1c=
|
||||||
|
-----END PUBLIC KEY-----
|
49
web/backend/kioubit_verify.py
Normal file
49
web/backend/kioubit_verify.py
Normal 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'
|
|
@ -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
19
web/frontend/base.html
Normal 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> 🄯 LARE-MNT</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -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
17
web/frontend/login.html
Normal 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 %}
|
|
@ -1,4 +1,46 @@
|
||||||
|
:root {
|
||||||
|
--bg-color: #aaa;
|
||||||
|
--text-color: black;
|
||||||
|
--other-background: #444;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: wheat;
|
margin: 0;
|
||||||
background-color: black;
|
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
2
web/requirements.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Flask
|
||||||
|
pyopenssl
|
Loading…
Add table
Reference in a new issue