Compare commits

..

No commits in common. "73de6addc1f5370fa2d98d240bf1faaa9d62c355" and "83e411bcc3a5fd53181ab533e8d20b1459f30990" have entirely different histories.

8 changed files with 34 additions and 119 deletions

View file

@ -1,13 +1,13 @@
{ {
"nodes": { "nodes": {
"<nodename>": { "<nodename>": {
"pub-endpoint": "<clearnet-fqdn/ip-address>", //optional, recommended "pub-endpoint": "<clearnet-fqdn/ip-address>",
"api-con": "http://<node-(internal)-ip/hostname>:<port>/", // required "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 "country": "...", // Countrycode: 2 capital letters
"city": "...", "city": "...",
"wg-key": "...=", // pubkey of node; required "wg-key": "...=", // pubkey of node
"internal-v4": "172.2x.xxx.xxx", //at least one ipv{4,6} addr required "internal-v4": "172.2x.xxx.xxx",
"internal-v6": "fdxx:...", "internal-v6": "fdxx:...",
"internal-v4ll": "169.254.xxx.xxx", "internal-v4ll": "169.254.xxx.xxx",
"internal-v6ll": "fe80::..." "internal-v6ll": "fe80::..."
@ -17,8 +17,7 @@
"listen": "0.0.0.0", "listen": "0.0.0.0",
"port": 8042, "port": 8042,
"domain": "example.org", // domain to use for kioubit verification service "domain": "example.org", // domain to use for kioubit verification service
"base-dir": "/", //optional:directury for which it is reachable (if behind some sort of reverse proxy) default "/"
"debug-mode": false, // optional; whethet to enable debugging; default false
"flask-secret-key": "<secret-please-replace>", // secret key for session cookies "flask-secret-key": "<secret-please-replace>", // secret key for session cookies
"flask-debug": false, // optional; default false
"flask-template-dir": "../frontend/" // optional; default "../frontend" "flask-template-dir": "../frontend/" // optional; default "../frontend"
} }

View file

@ -1,8 +1,8 @@
#! /usr/bin/env python3 #! /usr/bin/env python3
import base64, os, json, time import base64, os
import OpenSSL
from OpenSSL.crypto import load_publickey, FILETYPE_PEM, verify, X509 from OpenSSL.crypto import load_publickey, FILETYPE_PEM, verify, X509
import OpenSSL
PUBKEY_FILE = os.path.dirname(__file__)+"/kioubit-auth-pubkey.pem" PUBKEY_FILE = os.path.dirname(__file__)+"/kioubit-auth-pubkey.pem"
@ -33,18 +33,12 @@ class AuthVerifyer ():
verify(self.x509, sig, params, 'sha512') verify(self.x509, sig, params, 'sha512')
except OpenSSL.crypto.Error: except OpenSSL.crypto.Error:
return False, "Signature Failed" return False, "Signature Failed"
#h = SHA512.new()
try: #h.update(base64.b64decode(params))
user_data = json.loads(base64.b64decode(params)) #print(h.hexdigest())
if (time.time() - user_data["time"] )> 60: #verifier = DSS.new(self.pubkey, 'deterministic-rfc6979')
return False, "Signature to old" #valid = verifier.verify(h, base64.b64decode(signature))
except json.decoder.JSONDecodeError: return True, ""
# 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__": if __name__ == "__main__":
example_com_verifier = AuthVerifyer("example.com") example_com_verifier = AuthVerifyer("example.com")

View file

@ -36,10 +36,9 @@ class Config (dict):
if not "flask-template-dir" in self._config: if not "flask-template-dir" in self._config:
self._config["flask-template-dir"] = "../frontend" self._config["flask-template-dir"] = "../frontend"
if not "debug-mode" in self._config: if not "flask-debug" in self._config:
self._config["debug-mode"] = False self._config["flask-debug"] = False
if not "base-dir" in self._config:
self._config["base-dir"] = "/"
print(self._config) print(self._config)
config = Config() config = Config()
@ -48,7 +47,7 @@ def auth_required():
def wrapper(f): def wrapper(f):
@wraps(f) @wraps(f)
def decorated(*args, **kwargs): def decorated(*args, **kwargs):
if not "login" in session: if not "logged_in" in session:
return redirect(f"login?return={request.url}") return redirect(f"login?return={request.url}")
else: else:
return f(*args, **kwargs) return f(*args, **kwargs)
@ -59,71 +58,37 @@ def auth_required():
kverifyer = kioubit_verify.AuthVerifyer(config["domain"]) kverifyer = kioubit_verify.AuthVerifyer(config["domain"])
@app.route("/api/auth/kverify", methods=["GET", "POST"]) @app.route("/api/auth/kverify", methods=["GET", "POST"])
def kioubit_auth(): def kioubit_auth():
try: params = request.args["params"]
params = request.args["params"] signature = request.args["signature"]
signature = request.args["signature"] print(base64.b64decode(params))
except KeyError: return str(kverifyer.verify(params, signature))
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"]) @app.route("/login",methods=["GET","POST"])
def login(): def login():
if request.method == "GET": if request.method == "GET":
session["return_url"] = request.args["return"] if "return" in request.args else "" session["return_url"] = request.args["return"]
return render_template("login.html", config=config, return_addr=request.args["return"])
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"]) @app.route("/peer", methods=["GET","POST"])
@auth_required() @auth_required()
def peer(): def peer():
if request.method == "GET": return request.args
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("/") @app.route("/")
def index(): def index():
# print(config._config["nodes"]) # print(config._config["nodes"])
# for node in config["nodes"].values(): # for node in config["nodes"].values():
# print (node) # print (node)
return render_template("index.html", session=session, config=config._config) 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.secret_key = config["flask-secret-key"]
app.run(host=config["listen"], port=config["port"], debug=config["debug-mode"], threaded=True) app.run(host=config["listen"], port=config["port"], debug=config["flask-debug"], threaded=True)
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -5,14 +5,11 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{config["MNT"]}} Autopeering</title> <title>{{config["MNT"]}} Autopeering</title>
<link rel="stylesheet" href="{{config['base-dir']}}static/style.css"> <link rel="stylesheet" href="static/style.css">
</head> </head>
<body> <body>
<header class="flex flex-row"><div></div><a href="{{config['base-dir']}}">{{config["MNT"]}} Autopeering</a>{% if "login" in session %}<a href="{{config['base-dir']}}logout">logout</a>{% else %} <a href="{{config['base-dir']}}login?return=/peer">login</a>{%endif%}</header> <header class="flex">{{config["MNT"]}}</header>
<div class="content flex"> <div class="content flex">{% block content %}{% endblock %}</div>
{% block content %}
{% endblock %}
</div>
<footer class="flex"> <footer class="flex">
<div></div> <div></div>
<div></div> <div></div>

View file

@ -11,7 +11,6 @@
<table> <table>
<thead> <thead>
<tr> <tr>
<th>NodeName</th>
<th>Country</th> <th>Country</th>
<th>City</th> <th>City</th>
<th>peerings</th> <th>peerings</th>
@ -20,7 +19,6 @@
</thead> </thead>
{% for node in config["nodes"] %} {% for node in config["nodes"] %}
<tr> <tr>
<td>{{node}}</td>
<td>{{config["nodes"][node]["country"]}}</td> <td>{{config["nodes"][node]["country"]}}</td>
<td>{{config["nodes"][node]["city"]}}</td> <td>{{config["nodes"][node]["city"]}}</td>
<td></td> <td></td>

View file

@ -2,12 +2,6 @@
{% block content %} {% block content %}
{% if msg %}
<div style="background-color: red;">
{{msg}}
</div>
{% endif %}
<form action="https://dn42.g-load.eu/auth/"> <form action="https://dn42.g-load.eu/auth/">
<link rel="stylesheet" href="https://dn42.g-load.eu/auth/assets/button-font/auth.css"> <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"}}'> <input type="hidden" id="return" name="return" value='{{"http://"+config["domain"]+"/api/auth/kverify"}}'>
@ -16,16 +10,8 @@
</button> </button>
</form> </form>
{% if config["debug-mode"] %} <form action="" method="post">
<form action="" method="post" class="flex"> <input type="">
<label for="debug">Debug login, if you see this in Production contact {{config["MNT"]}}</label><br>
<input type="text" name="mnt" id="mnt" placeholder="YOUR-MNT"><br>
<input type="text" name="asn" id="asn" placeholder="AS4242420000"><br>
<input type="text" name="allowed-v4" id="allowed-v4" placeholder="ipv4 subnet"><br>
<input type="text" name="allowed-v6" id="allowed-v6" placeholder="ipv6 subnet"><br>
<input type="number" name="theanswer" id="theanswer" placeholder="The answer for everything"><br>
<input type="submit" value="login">
</form> </form>
{% endif %}
{% endblock %} {% endblock %}

View file

@ -1,13 +0,0 @@
{% 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 %}

View file

@ -2,7 +2,6 @@
--bg-color: #aaa; --bg-color: #aaa;
--text-color: black; --text-color: black;
--other-background: #444; --other-background: #444;
/* --accent-color: ; */
} }
body { body {
@ -16,26 +15,16 @@ header {
background-color: var(--other-background); background-color: var(--other-background);
height: 50px; height: 50px;
} }
a {
color: var(--text-color);
}
.content { .content {
width: 100%; width: 100%;
height: calc(100% - 55px); height: calc(100% - 55px);
margin: auto; margin: initial;
}
.content>* {
padding: 5%;
} }
.flex { .flex {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.flex-row {
flex-direction: row;
}
.flex>* { .flex>* {
flex-flow: column; flex-flow: column;