Merge branch 'main' into refactoring

This commit is contained in:
Donald Zou
2021-12-29 13:57:11 -05:00
committed by GitHub
6 changed files with 473 additions and 201 deletions

View File

@@ -260,7 +260,7 @@ def get_all_peers_data(config_name):
for i in conf_peer_data['Peers']:
search = db.search(peers.id == i['PublicKey'])
if not search:
db.insert({
new_data = {
"id": i['PublicKey'],
"private_key": "",
"DNS": config.get("Peers", "peer_global_DNS"),
@@ -276,8 +276,12 @@ def get_all_peers_data(config_name):
"traffic": [],
"mtu": config.get("Peers", "peer_mtu"),
"keepalive": config.get("Peers", "peer_keep_alive"),
"remote_endpoint": config.get("Peers", "remote_endpoint")
})
"remote_endpoint": config.get("Peers", "remote_endpoint"),
"preshared_key": ""
}
if "PresharedKey" in i.keys():
new_data["preshared_key"] = i["PresharedKey"]
db.insert(new_data)
else:
# Update database since V2.2
update_db = {}
@@ -294,7 +298,12 @@ def get_all_peers_data(config_name):
if "keepalive" not in search[0]:
update_db['keepalive'] = config.get("Peers", "peer_keep_alive")
if "remote_endpoint" not in search[0]:
update_db['remote_endpoint'] = config.get("Peers", "remote_endpoint")
update_db['remote_endpoint'] = config.get("Peers","remote_endpoint")
if "preshared_key" not in search[0]:
if "PresharedKey" in i.keys():
update_db['preshared_key'] = i["PresharedKey"]
else:
update_db['preshared_key'] = ""
db.update(update_db, peers.id == i['PublicKey'])
# Remove peers no longer exist in WireGuard configuration file
db_key = list(map(lambda a: a['id'], db.all()))
@@ -313,7 +322,7 @@ def get_all_peers_data(config_name):
try:
sem.release()
except RuntimeError as e:
pass
print("RuntimeError: cannot release un-acquired lock")
# Search for peers
@@ -335,7 +344,10 @@ def get_peers(config_name, search, sort_t):
else:
result = sorted(result, key=lambda d: d[sort_t])
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return result
@@ -381,7 +393,10 @@ def get_conf_total_data(config_name):
upload_total = round(upload_total, 4)
download_total = round(download_total, 4)
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return [total, upload_total, download_total]
@@ -411,13 +426,17 @@ def get_conf_list():
# Generate private key
def gen_private_key():
gen = subprocess.check_output('wg genkey > private_key.txt && wg pubkey < private_key.txt > public_key.txt',
shell=True)
gen_psk = subprocess.check_output('wg genpsk', shell=True)
preshare_key = gen_psk.decode("UTF-8").strip()
with open('private_key.txt', encoding='utf-8') as file_object:
private_key = file_object.readline().strip()
with open('public_key.txt', encoding='utf-8') as file_object:
public_key = file_object.readline().strip()
data = {"private_key": private_key, "public_key": public_key}
os.remove('private_key.txt')
os.remove('public_key.txt')
data = {"private_key": private_key, "public_key": public_key, "preshared_key": preshare_key}
private.close()
public.close()
return data
@@ -441,20 +460,25 @@ def f_check_key_match(private_key, public_key, config_name):
result = gen_public_key(private_key)
if result['status'] == 'failed':
return result
sem.acquire(timeout=1)
db = TinyDB(os.path.join(db_path, config_name + ".json"))
peers = Query()
match = db.search(peers.id == result['data'])
if len(match) != 1 or result['data'] != public_key:
db.close()
sem.release()
return {'status': 'failed', 'msg': 'Please check your private key, it does not match with the public key.'}
db.close()
sem.release()
return {'status': 'success'}
else:
sem.acquire(timeout=1)
db = TinyDB(os.path.join(db_path, config_name + ".json"))
peers = Query()
match = db.search(peers.id == result['data'])
if len(match) != 1 or result['data'] != public_key:
db.close()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return {'status': 'failed', 'msg': 'Please check your private key, it does not match with the public key.'}
else:
db.close()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return {'status': 'success'}
# Check if there is repeated allowed IP
def check_repeat_allowed_ip(public_key, ip, config_name):
@@ -464,16 +488,22 @@ def check_repeat_allowed_ip(public_key, ip, config_name):
peer = db.search(peers.id == public_key)
if len(peer) != 1:
return {'status': 'failed', 'msg': 'Peer does not exist'}
existed_ip = db.search((peers.id != public_key) & (peers.allowed_ip == ip))
if len(existed_ip) != 0:
db.close()
sem.release()
return {'status': 'failed', 'msg': "Allowed IP already taken by another peer."}
db.close()
sem.release()
return {'status': 'success'}
else:
existed_ip = db.search((peers.id != public_key) & (peers.allowed_ip == ip))
if len(existed_ip) != 0:
db.close()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return {'status': 'failed', 'msg': "Allowed IP already taken by another peer."}
else:
db.close()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return {'status': 'success'}
"""
@@ -759,13 +789,17 @@ def update_dashbaord_sort():
# Update configuration refresh interval
@app.route('/update_dashboard_refresh_interval', methods=['POST'])
def update_dashboard_refresh_interval():
config = configparser.ConfigParser(strict=False)
config.read(DASHBOARD_CONF)
config.set("Server", "dashboard_refresh_interval", str(request.form['interval']))
with open(DASHBOARD_CONF, "w", encoding='utf-8') as config_object:
config.write(config_object)
config.clear()
return "true"
preset_interval = ["5000", "10000", "30000", "60000"]
if request.form["interval"] in preset_interval:
config = configparser.ConfigParser(strict=False)
config.read(dashboard_conf)
config.set("Server", "dashboard_refresh_interval", str(request.form['interval']))
with open(DASHBOARD_CONF, "w", encoding='utf-8') as config_object:
config.write(config_object)
config.clear()
return "true"
else:
return "false"
# Configuration Page
@@ -868,55 +902,92 @@ def add_peer(config_name):
public_key = data['public_key']
allowed_ips = data['allowed_ips']
endpoint_allowed_ip = data['endpoint_allowed_ip']
dns_addresses = data['DNS']
DNS = data['DNS']
enable_preshared_key = data["enable_preshared_key"]
keys = get_conf_peer_key(config_name)
if len(public_key) == 0 or len(dns_addresses) == 0 or len(allowed_ips) == 0 or len(endpoint_allowed_ip) == 0:
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return "Please fill in all required box."
if not isinstance(keys, list):
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return config_name + " is not running."
if public_key in keys:
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return "Public key already exist."
if len(db.search(peers.allowed_ip.matches(allowed_ips))) != 0:
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return "Allowed IP already taken by another peer."
if not check_DNS(dns_addresses):
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return "DNS formate is incorrect. Example: 1.1.1.1"
if not check_Allowed_IPs(endpoint_allowed_ip):
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return "Endpoint Allowed IPs format is incorrect."
if len(data['MTU']) == 0 or not data['MTU'].isdigit():
db.close()
sem.release()
return "MTU format is not correct."
db.close()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return "MTU format is not correct."
if len(data['keep_alive']) == 0 or not data['keep_alive'].isdigit():
db.close()
sem.release()
return "Persistent Keepalive format is not correct."
db.close()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return "Persistent Keepalive format is not correct."
try:
subprocess.run(f"wg set {config_name} peer {public_key} allowed-ips {allowed_ips}",
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
subprocess.run("wg-quick save " + config_name,
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
if enable_preshared_key == True:
key = subprocess.check_output("wg genpsk > tmp_psk.txt", shell=True)
status = subprocess.check_output(f"wg set {config_name} peer {public_key} allowed-ips {allowed_ips} preshared-key tmp_psk.txt",
shell=True, stderr=subprocess.STDOUT)
os.remove("tmp_psk.txt")
elif enable_preshared_key == False:
status = subprocess.check_output(f"wg set {config_name} peer {public_key} allowed-ips {allowed_ips}",
shell=True, stderr=subprocess.STDOUT)
status = subprocess.check_output("wg-quick save " + config_name, shell=True, stderr=subprocess.STDOUT)
get_all_peers_data(config_name)
db.update({"name": data['name'], "private_key": data['private_key'], "DNS": data['DNS'],
"endpoint_allowed_ip": endpoint_allowed_ip},
peers.id == public_key)
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return "true"
except subprocess.CalledProcessError as exc:
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return exc.output.strip()
@@ -936,21 +1007,26 @@ def remove_peer(config_name):
if delete_key not in keys:
db.close()
return "This key does not exist"
try:
subprocess.run(f"wg set {config_name} peer {delete_key} remove",
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
subprocess.run("wg-quick save " + config_name,
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
db.remove(peers.id == delete_key)
db.close()
sem.release()
return "true"
except subprocess.CalledProcessError as exc:
db.close()
sem.release()
return exc.output.strip()
else:
try:
remove_wg = subprocess.check_output(f"wg set {config_name} peer {delete_key} remove",
shell=True, stderr=subprocess.STDOUT)
save_wg = subprocess.check_output(f"wg-quick save {config_name}",
shell=True, stderr=subprocess.STDOUT)
db.remove(peers.id == delete_key)
db.close()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return "true"
except subprocess.CalledProcessError as exc:
db.close()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return exc.output.strip()
# Save peer settings
@app.route('/save_peer_setting/<config_name>', methods=['POST'])
@@ -962,6 +1038,7 @@ def save_peer_setting(config_name):
dns_addresses = data['DNS']
allowed_ip = data['allowed_ip']
endpoint_allowed_ip = data['endpoint_allowed_ip']
preshared_key = data['preshared_key']
sem.acquire(timeout=1)
db = TinyDB(os.path.join(db_path, config_name + ".json"))
peers = Query()
@@ -969,31 +1046,60 @@ def save_peer_setting(config_name):
check_ip = check_repeat_allowed_ip(id, allowed_ip, config_name)
if not check_IP_with_range(endpoint_allowed_ip):
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify({"status": "failed", "msg": "Endpoint Allowed IPs format is incorrect."})
if not check_DNS(dns_addresses):
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify({"status": "failed", "msg": "DNS format is incorrect."})
if len(data['MTU']) == 0 or not data['MTU'].isdigit():
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify({"status": "failed", "msg": "MTU format is not correct."})
if len(data['keep_alive']) == 0 or not data['keep_alive'].isdigit():
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify({"status": "failed", "msg": "Persistent Keepalive format is not correct."})
if private_key != "":
check_key = f_check_key_match(private_key, id, config_name)
if check_key['status'] == "failed":
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify(check_key)
if check_ip['status'] == "failed":
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify(check_ip)
try:
tmp_psk = open("tmp_edit_psk.txt", "w+")
tmp_psk.write(preshared_key)
tmp_psk.close()
change_psk = subprocess.check_output("wg set " + config_name + " peer " + id + " preshared-key tmp_edit_psk.txt", shell=True, stderr=subprocess.STDOUT)
if change_psk.decode("UTF-8") != "":
db.close()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify({"status": "failed", "msg": change_psk.decode("UTF-8")})
if allowed_ip == "":
allowed_ip = '""'
allowed_ip = allowed_ip.replace(" ", "")
@@ -1003,24 +1109,39 @@ def save_peer_setting(config_name):
check=True, shell=True, capture_output=True, stderr=subprocess.STDOUT)
if change_ip.decode("UTF-8") != "":
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify({"status": "failed", "msg": change_ip.decode("UTF-8")})
db.update(
{"name": name, "private_key": private_key,
"DNS": dns_addresses, "endpoint_allowed_ip": endpoint_allowed_ip,
"mtu": data['MTU'],
"keepalive": data['keep_alive']},
peers.id == id)
{
"name": name,
"private_key": private_key,
"DNS": dns_addresses,
"endpoint_allowed_ip": endpoint_allowed_ip,
"mtu": data['MTU'],
"keepalive":data['keep_alive'], "preshared_key": preshared_key
}, peers.id == id)
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify({"status": "success", "msg": ""})
except subprocess.CalledProcessError as exc:
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify({"status": "failed", "msg": str(exc.output.decode("UTF-8").strip())})
else:
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify({"status": "failed", "msg": "This peer does not exist."})
@@ -1036,8 +1157,12 @@ def get_peer_name(config_name):
db.close()
data = {"name": result[0]['name'], "allowed_ip": result[0]['allowed_ip'], "DNS": result[0]['DNS'],
"private_key": result[0]['private_key'], "endpoint_allowed_ip": result[0]['endpoint_allowed_ip'],
"mtu": result[0]['mtu'], "keep_alive": result[0]['keepalive']}
sem.release()
"mtu": result[0]['mtu'], "keep_alive": result[0]['keepalive'], "preshared_key": result[0]["preshared_key"]}
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return jsonify(data)
@@ -1084,6 +1209,7 @@ def generate_qrcode(config_name):
mtu_value = peer['mtu']
endpoint_allowed_ip = peer['endpoint_allowed_ip']
keepalive = peer['keepalive']
preshared_key = peer["preshared_key"]
conf = {
"public_key": public_key,
"listen_port": listen_port,
@@ -1094,18 +1220,31 @@ def generate_qrcode(config_name):
"mtu": mtu_value,
"endpoint_allowed_ip": endpoint_allowed_ip,
"keepalive": keepalive,
"preshared_key": preshared_key
}
db.close()
sem.release()
return render_template("qrcode.html", i=conf)
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
result = "[Interface]\nPrivateKey = "+conf['private_key']+"\nAddress = "+conf['allowed_ip']+"\nMTU = "+conf['mtu']+"\nDNS = "+conf['DNS']\
+"\n\n[Peer]\nPublicKey = "+conf['public_key']+"\nAllowedIPs = "+conf['endpoint_allowed_ip']+"\nPersistentKeepalive = "+conf['keepalive']+"\nEndpoint = "+conf['endpoint']
if preshared_key != "":
result += "\nPresharedKey = "+preshared_key
return render_template("qrcode.html", i=result)
else:
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return redirect("/configuration/" + config_name)
# Download configuration file
@app.route('/<config_name>', methods=['GET'])
@app.route('/download/<config_name>', methods=['GET'])
def download(config_name):
print(request.headers.get('User-Agent'))
id = request.args.get('id')
@@ -1127,6 +1266,7 @@ def download(config_name):
endpoint_allowed_ip = peer['endpoint_allowed_ip']
keepalive = peer['keepalive']
filename = peer['name']
preshared_key = peer["preshared_key"]
if len(filename) == 0:
filename = "Untitled_Peers"
else:
@@ -1141,23 +1281,24 @@ def download(config_name):
filename = "Untitled_Peer"
filename = "".join(filename.split(' '))
filename = filename + "_" + config_name
psk = ""
if preshared_key != "":
psk = "\nPresharedKey = "+preshared_key
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
result = "[Interface]\nPrivateKey = " + private_key + "\nAddress = " + allowed_ip + "\nDNS = " + \
dns_addresses + "\nMTU = " + mtu_value + "\n\n[Peer]\nPublicKey = " + \
public_key + "\nAllowedIPs = " + endpoint_allowed_ip + "\nEndpoint = " + \
endpoint + "\nPersistentKeepalive = " + keepalive
return app.response_class((yield result),
mimetype='text/conf',
headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
endpoint + "\nPersistentKeepalive = " + keepalive + psk
return app.response_class((yield result), mimetype='text/conf', headers={"Content-Disposition": "attachment;filename=" + filename + ".conf"})
db.close()
return redirect("/configuration/" + config_name)
# Switch peer displate mode
# Switch peer display mode
@app.route('/switch_display_mode/<mode>', methods=['GET'])
def switch_display_mode(mode):
if mode in ['list', 'grid']:
@@ -1181,7 +1322,7 @@ Dashboard Tools Related
def get_ping_ip():
config_name = request.form['config']
sem.acquire(timeout=1)
db = TinyDB(os.path.join(db_path, config_name + ".json"))
db = TinyDB(os.path.join(db_path, config + ".json"))
html = ""
for i in db.all():
@@ -1196,7 +1337,10 @@ def get_ping_ip():
html += "<option value=" + endpoint[0] + ">" + endpoint[0] + "</option>"
html += "</optgroup>"
db.close()
sem.release()
try:
sem.release()
except RuntimeError as e:
print("RuntimeError: cannot release un-acquired lock")
return html
@@ -1326,13 +1470,4 @@ if __name__ == "__main__":
app_port = configuration_settings.get("Server", "app_port")
wg_conf_path = configuration_settings.get("Server", "wg_conf_path")
configuration_settings.clear()
app.run(host=app_ip, debug=False, port=app_port)
else:
init_dashboard()
UPDATE = check_update()
configuration_settings = configparser.ConfigParser(strict=False)
configuration_settings.read(DASHBOARD_CONF)
app_ip = configuration_settings.get("Server", "app_ip")
app_port = configuration_settings.get("Server", "app_port")
wg_conf_path = configuration_settings.get("Server", "wg_conf_path")
configuration_settings.clear()
app.run(host=app_ip, debug=False, port=app_port)