diff --git a/src/dashboard_new.py b/src/dashboard_new.py
index fadf2f5..dd1d868 100644
--- a/src/dashboard_new.py
+++ b/src/dashboard_new.py
@@ -99,27 +99,31 @@ class WireguardConfiguration:
def __str__(self):
return self.message
- def __init__(self, name):
- self.Name = name
- self.__parser.read(os.path.join(WG_CONF_PATH, f'{self.Name}.conf'))
- sections = self.__parser.sections()
- if "Interface" not in sections:
- raise self.InvalidConfigurationFileException(
- "[Interface] section not found in " + os.path.join(WG_CONF_PATH, f'{self.Name}.conf'))
- interfaceConfig = dict(self.__parser.items("Interface", True))
- for i in dir(self):
- if str(i) in interfaceConfig.keys():
- if isinstance(getattr(self, i), bool):
- setattr(self, i, _strToBool(interfaceConfig[i]))
- else:
- setattr(self, i, interfaceConfig[i])
+ def __init__(self, name: str = None):
+ if name is not None:
+ self.Name = name
+ self.__parser.read(os.path.join(WG_CONF_PATH, f'{self.Name}.conf'))
+ sections = self.__parser.sections()
+ if "Interface" not in sections:
+ raise self.InvalidConfigurationFileException(
+ "[Interface] section not found in " + os.path.join(WG_CONF_PATH, f'{self.Name}.conf'))
+ interfaceConfig = dict(self.__parser.items("Interface", True))
+ for i in dir(self):
+ if str(i) in interfaceConfig.keys():
+ if isinstance(getattr(self, i), bool):
+ setattr(self, i, _strToBool(interfaceConfig[i]))
+ else:
+ setattr(self, i, interfaceConfig[i])
- if self.PrivateKey:
- self.PublicKey = self.__getPublicKey()
+ if self.PrivateKey:
+ self.PublicKey = self.__getPublicKey()
- self.Status = self.__getStatus()
+ self.Status = self.__getStatus()
- # Create tables in database
+ # Create tables in database
+ self.__createDatabase()
+
+ def __createDatabase(self):
inspector = inspect(engine)
existingTable = inspector.get_table_names()
if self.Name not in existingTable:
@@ -139,6 +143,9 @@ class WireguardConfiguration:
self.Status = self.__getStatus()
return self.__dict__
+ def newConfiguration(self):
+ pass
+
def iPv46RegexCheck(ip):
return re.match(
@@ -447,7 +454,11 @@ def API_AuthenticateLogin():
resp.set_cookie("authToken", authToken)
session.permanent = True
return resp
- return ResponseObject(False, "Username, password or OTP is incorrect.")
+
+ if totpEnabled:
+ return ResponseObject(False, "Sorry, your username, password or OTP is incorrect.")
+ else:
+ return ResponseObject(False, "Sorry, your username or password is incorrect.")
@app.route('/api/signout')
@@ -463,6 +474,28 @@ def API_getWireguardConfigurations():
return ResponseObject(data=[wc.toJSON() for wc in WireguardConfigurations])
+@app.route('/api/addWireguardConfiguration', methods=["POST"])
+def API_addWireguardConfiguration():
+ data = request.get_json()
+ keys = [
+ "ConfigurationName",
+ "Address",
+ "ListenPort",
+ "PrivateKey",
+ "PublicKey",
+ "PresharedKey",
+ "PreUp",
+ "PreDown",
+ "PostUp",
+ "PostDown",
+ "UsePreSharedKey"
+ ]
+ requiredKeys = [
+ "ConfigurationName", "Address", "ListenPort", "PrivateKey"
+ ]
+
+
+
@app.route('/api/getDashboardConfiguration', methods=["GET"])
def API_getDashboardConfiguration():
return ResponseObject(data=DashboardConfig.toJSON())
diff --git a/src/static/app/package-lock.json b/src/static/app/package-lock.json
index b0c5eb5..adb34a8 100644
--- a/src/static/app/package-lock.json
+++ b/src/static/app/package-lock.json
@@ -10,6 +10,7 @@
"dependencies": {
"bootstrap": "^5.3.2",
"bootstrap-icons": "^1.11.2",
+ "cidr-tools": "^7.0.4",
"pinia": "^2.1.7",
"qrcode": "^1.5.3",
"uuid": "^9.0.1",
@@ -755,6 +756,17 @@
"node": ">=6"
}
},
+ "node_modules/cidr-tools": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cidr-tools/-/cidr-tools-7.0.4.tgz",
+ "integrity": "sha512-bKd6xC01ObuVKvJPGdV9Rz02KFO3mtHwMe/QTlcVuFAmU5n3RN/F3FgppHZaQjM+c/1i9YB9rgKNH/5iVqwCoA==",
+ "dependencies": {
+ "ip-bigint": "^8.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/cliui": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
@@ -897,6 +909,14 @@
"node": "6.* || 8.* || >= 10.*"
}
},
+ "node_modules/ip-bigint": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/ip-bigint/-/ip-bigint-8.0.2.tgz",
+ "integrity": "sha512-UMKHGx7+4O2mD/6jnpNtt4UMA0tRQ3XAiNVYlbLssFU1LegKqKwPqbqtLVW7lQU/c6rCWI1hcxxs4TP96Xa+rQ==",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
diff --git a/src/static/app/package.json b/src/static/app/package.json
index 681bbe8..23c4adb 100644
--- a/src/static/app/package.json
+++ b/src/static/app/package.json
@@ -11,6 +11,7 @@
"dependencies": {
"bootstrap": "^5.3.2",
"bootstrap-icons": "^1.11.2",
+ "cidr-tools": "^7.0.4",
"pinia": "^2.1.7",
"qrcode": "^1.5.3",
"uuid": "^9.0.1",
diff --git a/src/static/app/src/components/configurationList.vue b/src/static/app/src/components/configurationList.vue
index 243b4a2..677e3f2 100644
--- a/src/static/app/src/components/configurationList.vue
+++ b/src/static/app/src/components/configurationList.vue
@@ -17,9 +17,9 @@ export default {
Wireguard Configurations
-
-
+
Configuration
+
You don't have any WireGuard configurations yet. Please check the configuration folder or change it in "Settings". By default the folder is "/etc/wireguard".
diff --git a/src/static/app/src/utilities/wireguard.js b/src/static/app/src/utilities/wireguard.js
new file mode 100644
index 0000000..ac51a15
--- /dev/null
+++ b/src/static/app/src/utilities/wireguard.js
@@ -0,0 +1,313 @@
+/*! SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2015-2020 Jason A. Donenfeld . All Rights Reserved.
+ */
+
+(function() {
+ function gf(init) {
+ var r = new Float64Array(16);
+ if (init) {
+ for (var i = 0; i < init.length; ++i)
+ r[i] = init[i];
+ }
+ return r;
+ }
+
+ function pack(o, n) {
+ var b, m = gf(), t = gf();
+ for (var i = 0; i < 16; ++i)
+ t[i] = n[i];
+ carry(t);
+ carry(t);
+ carry(t);
+ for (var j = 0; j < 2; ++j) {
+ m[0] = t[0] - 0xffed;
+ for (var i = 1; i < 15; ++i) {
+ m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1);
+ m[i - 1] &= 0xffff;
+ }
+ m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1);
+ b = (m[15] >> 16) & 1;
+ m[14] &= 0xffff;
+ cswap(t, m, 1 - b);
+ }
+ for (var i = 0; i < 16; ++i) {
+ o[2 * i] = t[i] & 0xff;
+ o[2 * i + 1] = t[i] >> 8;
+ }
+ }
+
+ function carry(o) {
+ var c;
+ for (var i = 0; i < 16; ++i) {
+ o[(i + 1) % 16] += (i < 15 ? 1 : 38) * Math.floor(o[i] / 65536);
+ o[i] &= 0xffff;
+ }
+ }
+
+ function cswap(p, q, b) {
+ var t, c = ~(b - 1);
+ for (var i = 0; i < 16; ++i) {
+ t = c & (p[i] ^ q[i]);
+ p[i] ^= t;
+ q[i] ^= t;
+ }
+ }
+
+ function add(o, a, b) {
+ for (var i = 0; i < 16; ++i)
+ o[i] = (a[i] + b[i]) | 0;
+ }
+
+ function subtract(o, a, b) {
+ for (var i = 0; i < 16; ++i)
+ o[i] = (a[i] - b[i]) | 0;
+ }
+
+ function multmod(o, a, b) {
+ var t = new Float64Array(31);
+ for (var i = 0; i < 16; ++i) {
+ for (var j = 0; j < 16; ++j)
+ t[i + j] += a[i] * b[j];
+ }
+ for (var i = 0; i < 15; ++i)
+ t[i] += 38 * t[i + 16];
+ for (var i = 0; i < 16; ++i)
+ o[i] = t[i];
+ carry(o);
+ carry(o);
+ }
+
+ function invert(o, i) {
+ var c = gf();
+ for (var a = 0; a < 16; ++a)
+ c[a] = i[a];
+ for (var a = 253; a >= 0; --a) {
+ multmod(c, c, c);
+ if (a !== 2 && a !== 4)
+ multmod(c, c, i);
+ }
+ for (var a = 0; a < 16; ++a)
+ o[a] = c[a];
+ }
+
+ function clamp(z) {
+ z[31] = (z[31] & 127) | 64;
+ z[0] &= 248;
+ }
+
+ function generatePublicKey(privateKey) {
+ var r, z = new Uint8Array(32);
+ var a = gf([1]),
+ b = gf([9]),
+ c = gf(),
+ d = gf([1]),
+ e = gf(),
+ f = gf(),
+ _121665 = gf([0xdb41, 1]),
+ _9 = gf([9]);
+ for (var i = 0; i < 32; ++i)
+ z[i] = privateKey[i];
+ clamp(z);
+ for (var i = 254; i >= 0; --i) {
+ r = (z[i >>> 3] >>> (i & 7)) & 1;
+ cswap(a, b, r);
+ cswap(c, d, r);
+ add(e, a, c);
+ subtract(a, a, c);
+ add(c, b, d);
+ subtract(b, b, d);
+ multmod(d, e, e);
+ multmod(f, a, a);
+ multmod(a, c, a);
+ multmod(c, b, e);
+ add(e, a, c);
+ subtract(a, a, c);
+ multmod(b, a, a);
+ subtract(c, d, f);
+ multmod(a, c, _121665);
+ add(a, a, d);
+ multmod(c, c, a);
+ multmod(a, d, f);
+ multmod(d, b, _9);
+ multmod(b, e, e);
+ cswap(a, b, r);
+ cswap(c, d, r);
+ }
+ invert(c, c);
+ multmod(a, a, c);
+ pack(z, a);
+ return z;
+ }
+
+ function generatePresharedKey() {
+ var privateKey = new Uint8Array(32);
+ window.crypto.getRandomValues(privateKey);
+ return privateKey;
+ }
+
+ function generatePrivateKey() {
+ var privateKey = generatePresharedKey();
+ clamp(privateKey);
+ return privateKey;
+ }
+
+ function encodeBase64(dest, src) {
+ var input = Uint8Array.from([(src[0] >> 2) & 63, ((src[0] << 4) | (src[1] >> 4)) & 63, ((src[1] << 2) | (src[2] >> 6)) & 63, src[2] & 63]);
+ for (var i = 0; i < 4; ++i)
+ dest[i] = input[i] + 65 +
+ (((25 - input[i]) >> 8) & 6) -
+ (((51 - input[i]) >> 8) & 75) -
+ (((61 - input[i]) >> 8) & 15) +
+ (((62 - input[i]) >> 8) & 3);
+ }
+
+ function keyToBase64(key) {
+ var i, base64 = new Uint8Array(44);
+ for (i = 0; i < 32 / 3; ++i)
+ encodeBase64(base64.subarray(i * 4), key.subarray(i * 3));
+ encodeBase64(base64.subarray(i * 4), Uint8Array.from([key[i * 3 + 0], key[i * 3 + 1], 0]));
+ base64[43] = 61;
+ return String.fromCharCode.apply(null, base64);
+ }
+
+ function base64ToKey(base64) {
+ let binary_string = window.atob(base64);
+ let len = binary_string.length;
+ let bytes = new Uint8Array(len);
+ for (let i = 0; i < len; i++) {
+ bytes[i] = binary_string.charCodeAt(i);
+ }
+ let uint8 = new Uint8Array(bytes.buffer);
+ return uint8;
+ }
+
+ function putU32(b, n)
+ {
+ b.push(n & 0xff, (n >>> 8) & 0xff, (n >>> 16) & 0xff, (n >>> 24) & 0xff);
+ }
+
+ function putU16(b, n)
+ {
+ b.push(n & 0xff, (n >>> 8) & 0xff);
+ }
+
+ function putBytes(b, a)
+ {
+ for (var i = 0; i < a.length; ++i)
+ b.push(a[i] & 0xff);
+ }
+
+ function encodeString(s)
+ {
+ var utf8 = unescape(encodeURIComponent(s));
+ var b = new Uint8Array(utf8.length);
+ for (var i = 0; i < utf8.length; ++i)
+ b[i] = utf8.charCodeAt(i);
+ return b;
+ }
+
+ function crc32(b)
+ {
+ if (!crc32.table) {
+ crc32.table = [];
+ for (var c = 0, n = 0; n < 256; c = ++n) {
+ for (var k = 0; k < 8; ++k)
+ c = ((c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1));
+ crc32.table[n] = c;
+ }
+ }
+ var crc = -1;
+ for (var i = 0; i < b.length; ++i)
+ crc = (crc >>> 8) ^ crc32.table[(crc ^ b[i]) & 0xff];
+ return (crc ^ (-1)) >>> 0;
+ }
+
+ function createZipFile(files)
+ {
+ var b = [];
+ var cd = [];
+ var offset = 0;
+
+ for (var i = 0; i < files.length; ++i) {
+ var name = encodeString(files[i].filename);
+ var contents = encodeString(files[i].content);
+ var crc = crc32(contents);
+
+ putU32(b, 0x04034b50); /* signature */
+ putU16(b, 20); /* version needed */
+ putU16(b, 0); /* flags */
+ putU16(b, 0); /* compression method */
+ putU16(b, 0); /* mtime */
+ putU16(b, 0); /* mdate */
+ putU32(b, crc); /* crc32 */
+ putU32(b, contents.length); /* compressed size */
+ putU32(b, contents.length); /* uncompressed size */
+ putU16(b, name.length); /* file name length */
+ putU16(b, 0); /* extra field length */
+ putBytes(b, name);
+ putBytes(b, contents);
+
+ putU32(cd, 0x02014b50); /* signature */
+ putU16(cd, 0); /* version made */
+ putU16(cd, 20); /* version needed */
+ putU16(cd, 0); /* flags */
+ putU16(cd, 0); /* compression method */
+ putU16(cd, 0); /* mtime */
+ putU16(cd, 0); /* mdate */
+ putU32(cd, crc); /* crc32 */
+ putU32(cd, contents.length); /* compressed size */
+ putU32(cd, contents.length); /* uncompressed size */
+ putU16(cd, name.length); /* file name length */
+ putU16(cd, 0); /* extra field length */
+ putU16(cd, 0); /* file comment length */
+ putU16(cd, 0); /* disk number start */
+ putU16(cd, 0); /* internal file attributes */
+ putU32(cd, 32); /* external file attributes - 'archive' bit set (32) */
+ putU32(cd, offset); /* relative offset of local header */
+ putBytes(cd, name); /* file name */
+
+ offset += 30 + contents.length + name.length
+ }
+ putBytes(b, cd); /* central directory */
+ putU32(b, 0x06054b50); /* end of central directory signature */
+ putU16(b, 0); /* number of this disk */
+ putU16(b, 0); /* number of disk with central directory start */
+ putU16(b, files.length); /* number of entries on disk */
+ putU16(b, files.length); /* number of entries */
+ putU32(b, cd.length); /* length of central directory */
+ putU32(b, offset); /* offset to start of central directory */
+ putU16(b, 0); /* zip comment size */
+ return Uint8Array.from(b);
+ }
+
+ window.wireguard = {
+ generateKeypair: function() {
+ var privateKey = generatePrivateKey();
+ var publicKey = generatePublicKey(privateKey);
+ var presharedKey = generatePresharedKey();
+ return {
+ publicKey: keyToBase64(publicKey),
+ privateKey: keyToBase64(privateKey),
+ presharedKey: keyToBase64(presharedKey)
+ };
+ },
+ generatePublicKey: function (privateKey){
+ privateKey = base64ToKey(privateKey);
+ return keyToBase64(generatePublicKey(privateKey));
+ },
+
+ generateZipFiles: function(res){
+ var files = res.peers;
+ var zipFile = createZipFile(files);
+ var blob = new Blob([zipFile], { type: "application/zip" });
+ var a = document.createElement("a");
+ a.download = res.filename;
+ a.href = URL.createObjectURL(blob);
+ a.style.display = "none";
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ }
+ };
+})();
diff --git a/src/static/app/src/views/newConfiguration.vue b/src/static/app/src/views/newConfiguration.vue
index e9d2e0b..1886cc1 100644
--- a/src/static/app/src/views/newConfiguration.vue
+++ b/src/static/app/src/views/newConfiguration.vue
@@ -1,22 +1,250 @@
-
-
-
-
-
-
-
-
-
New Configuration
-
+
+
+
+
+
+
+
+
New Configuration
+
+
+
+
diff --git a/src/static/app2/app.js b/src/static/app2/app.js
deleted file mode 100644
index 48bb6ad..0000000
--- a/src/static/app2/app.js
+++ /dev/null
@@ -1,51 +0,0 @@
-const { createApp, ref } = Vue;
-import Index from './index.js'
-import Signin from './signin/signin.js'
-const {createPinia} = Pinia
-import {cookie} from "./cookie.js";
-
-const app = createApp({
- template: `
-
-
- `
-});
-const pinia = createPinia()
-const routes = [
- {
- path: '/',
- component: Index,
- meta: {
- requiresAuth: true
- }
- },
- {
- path: '/signin', component: Signin
- }
-]
-
-const router = VueRouter.createRouter({
- // 4. Provide the history implementation to use. We are using the hash history for simplicity here.
- history: VueRouter.createWebHashHistory(),
- routes, // short for `routes: routes`
-});
-
-router.beforeEach((to, from, next) => {
- if (to.meta.requiresAuth){
- if (cookie.getCookie("auth")){
- next()
- }else{
- next("/signin")
- }
- }else {
- next();
- }
-});
-
-app.use(router);
-app.use(pinia)
-app.mount('#app1');
\ No newline at end of file
diff --git a/src/static/app2/cookie.js b/src/static/app2/cookie.js
deleted file mode 100644
index 964df54..0000000
--- a/src/static/app2/cookie.js
+++ /dev/null
@@ -1,9 +0,0 @@
-export const cookie = {
-
- //https://stackoverflow.com/a/15724300
- getCookie(name) {
- const value = `; ${document.cookie}`;
- const parts = value.split(`; ${name}=`);
- if (parts.length === 2) return parts.pop().split(';').shift();
- }
-}
\ No newline at end of file
diff --git a/src/static/app2/index.js b/src/static/app2/index.js
deleted file mode 100644
index 98402f0..0000000
--- a/src/static/app2/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default {
- template: `
- this is idex
- `
-}
\ No newline at end of file
diff --git a/src/static/app2/signin/fetch.js b/src/static/app2/signin/fetch.js
deleted file mode 100644
index 0836721..0000000
--- a/src/static/app2/signin/fetch.js
+++ /dev/null
@@ -1,28 +0,0 @@
-export const fetchGet = async (url, params=undefined, callback=undefined) => {
- const urlSearchParams = new URLSearchParams(params);
- await fetch(`${url}?${urlSearchParams.toString()}}`, {
- headers: {
- "content-type": "application/json"
- }
- })
- .then(x => x.json())
- .then(x => callback ? callback(x) : undefined)
- .catch(() => {
- alert("Error occurred! Check console")
- });
-}
-
-export const fetchPost = async (url, body, callback) => {
- await fetch(`${url}`, {
- headers: {
- "content-type": "application/json"
- },
- method: "POST",
- body: JSON.stringify(body)
- })
- .then(x => x.json())
- .then(x => callback ? callback(x) : undefined)
- // .catch(() => {
- // alert("Error occurred! Check console")
- // });
-}
\ No newline at end of file
diff --git a/src/static/app2/signin/signin.js b/src/static/app2/signin/signin.js
deleted file mode 100644
index 0a2ae77..0000000
--- a/src/static/app2/signin/signin.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import {fetchPost} from "./fetch.js";
-
-export default {
- data(){
- return {
- username: "",
- password: ""
- }
- },
- template: `
-