More info on homepage, tunnel firewall rules, update password flow
This commit is contained in:
parent
8d3b3eb23c
commit
5e41063680
|
@ -164,14 +164,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "1.0.1"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "016a7f0eda7091ef24ad8562d6503ad8da47af8c432d4d3fa440eea9e89055fe"
|
||||
checksum = "38628c78a34f111c5a6b98fc87dfc056cd1590b61afe748b145be4623c56d194"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"fastrand",
|
||||
"futures-lite 1.3.0",
|
||||
"futures-lite 1.4.0",
|
||||
"libc",
|
||||
"log",
|
||||
"once_cell",
|
||||
|
@ -199,11 +199,11 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bb915df28b8309139bd9c9c700d84c20e5c21385d05378caa84912332d0f6a1"
|
||||
dependencies = [
|
||||
"async-io 1.0.1",
|
||||
"async-io 1.1.0",
|
||||
"blocking 1.0.0",
|
||||
"cfg-if",
|
||||
"event-listener",
|
||||
"futures-lite 1.3.0",
|
||||
"futures-lite 1.4.0",
|
||||
"once_cell",
|
||||
"signal-hook",
|
||||
"winapi",
|
||||
|
@ -225,7 +225,7 @@ dependencies = [
|
|||
"hmac",
|
||||
"kv-log-macro",
|
||||
"rand",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
]
|
||||
|
@ -346,7 +346,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -419,7 +419,7 @@ dependencies = [
|
|||
"async-channel",
|
||||
"atomic-waker",
|
||||
"fastrand",
|
||||
"futures-lite 1.3.0",
|
||||
"futures-lite 1.4.0",
|
||||
"once_cell",
|
||||
"waker-fn",
|
||||
]
|
||||
|
@ -489,7 +489,7 @@ checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
|
|||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits 0.2.12",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"time 0.1.44",
|
||||
]
|
||||
|
||||
|
@ -520,7 +520,7 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"nom",
|
||||
"rust-ini",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde-hjson",
|
||||
"serde_json",
|
||||
"toml",
|
||||
|
@ -552,7 +552,7 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
"rand",
|
||||
"sha2",
|
||||
"time 0.2.18",
|
||||
"time 0.2.19",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
|
@ -682,7 +682,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"js-sys",
|
||||
"log",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-bindgen",
|
||||
|
@ -737,9 +737,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fc6854fcb40c6446abf6043e82604e42567dcf3d652a5ff4e997fc36876414c"
|
||||
checksum = "ba659a67bd5ac00896b31e1f4095174134a31e448893d73256f1d51b81abbd62"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"futures-core",
|
||||
|
@ -818,9 +818,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.14"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
|
||||
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
@ -896,7 +896,7 @@ dependencies = [
|
|||
"infer",
|
||||
"pin-project-lite",
|
||||
"rand",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde_json",
|
||||
"serde_qs 0.6.1",
|
||||
"serde_urlencoded",
|
||||
|
@ -949,9 +949,9 @@ checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
|
|||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.44"
|
||||
version = "0.3.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85a7e2c92a4804dd459b86c339278d0fe87cf93757fae222c3fa3ae75458bc73"
|
||||
checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
@ -986,9 +986,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.76"
|
||||
version = "0.2.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3"
|
||||
checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235"
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
|
@ -1065,11 +1065,12 @@ checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
|||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d7559a8a40d0f97e1edea3220f698f78b1c5ab67532e49f68fde3910323b722"
|
||||
checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1299,9 +1300,9 @@ checksum = "eba180dafb9038b050a4c280019bbedf9f2467b61e5d892dcad585bb57aadc5a"
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.20"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "175c513d55719db99da20232b06cda8bab6b83ec2d04e3283edf0213c37c1a29"
|
||||
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
@ -1397,13 +1398,13 @@ dependencies = [
|
|||
"bcrypt",
|
||||
"blocking 1.0.0",
|
||||
"config",
|
||||
"futures-lite 1.3.0",
|
||||
"futures-lite 1.4.0",
|
||||
"mime",
|
||||
"once_cell",
|
||||
"rand",
|
||||
"regex",
|
||||
"ructe",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde_json",
|
||||
"serde_qs 0.7.0",
|
||||
"serde_with",
|
||||
|
@ -1508,9 +1509,9 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
|
|||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.115"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5"
|
||||
checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
@ -1530,9 +1531,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.115"
|
||||
version = "1.0.116"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48"
|
||||
checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1547,7 +1548,7 @@ checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c"
|
|||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1559,7 +1560,7 @@ dependencies = [
|
|||
"data-encoding",
|
||||
"error-chain",
|
||||
"percent-encoding",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1570,7 +1571,7 @@ checksum = "9408a61dabe404c76cec504ec510f7d92f41dc0a9362a0db8ab73d141cfbf93f"
|
|||
dependencies = [
|
||||
"data-encoding",
|
||||
"percent-encoding",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
|
@ -1591,7 +1592,7 @@ checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
|
|||
dependencies = [
|
||||
"dtoa",
|
||||
"itoa",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"url",
|
||||
]
|
||||
|
||||
|
@ -1601,7 +1602,7 @@ version = "1.4.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d3d595d64120bbbc70b7f6d5ae63298b62a3d9f373ec2f56acf5365ca8a444"
|
||||
dependencies = [
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde_with_macros",
|
||||
]
|
||||
|
||||
|
@ -1663,9 +1664,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
|||
|
||||
[[package]]
|
||||
name = "sled"
|
||||
version = "0.34.3"
|
||||
version = "0.34.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcbf56c35b0c3f9bc208fab35e45c3bc03137d3c1a4a85bdf0b8db69aecffb45"
|
||||
checksum = "f72c064e63fbca3138ad07f3588c58093f1684f3a99f60dcfa6d46b87e60fde7"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"crossbeam-epoch",
|
||||
|
@ -1685,9 +1686,9 @@ checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
|
|||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.3.12"
|
||||
version = "0.3.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918"
|
||||
checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
@ -1738,7 +1739,7 @@ checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde_derive",
|
||||
"syn",
|
||||
]
|
||||
|
@ -1752,7 +1753,7 @@ dependencies = [
|
|||
"base-x",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sha1",
|
||||
|
@ -1773,9 +1774,9 @@ checksum = "343f3f510c2915908f155e94f17220b19ccfacf2a64a2a5d8004f2c3e311e7fd"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.40"
|
||||
version = "1.0.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350"
|
||||
checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1828,7 +1829,7 @@ dependencies = [
|
|||
"kv-log-macro",
|
||||
"pin-project-lite",
|
||||
"route-recognizer",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
|
@ -1845,9 +1846,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.2.18"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12785163ae8a1cbb52a5db39af4a5baabd3fe49f07f76f952f89d7e89e5ce531"
|
||||
checksum = "80c1a1fd93112fc50b11c43a1def21f926be3c18884fad676ea879572da070a1"
|
||||
dependencies = [
|
||||
"const_fn",
|
||||
"libc",
|
||||
|
@ -1893,7 +1894,7 @@ version = "0.5.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
|
||||
dependencies = [
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1945,7 +1946,7 @@ dependencies = [
|
|||
"idna",
|
||||
"matches",
|
||||
"percent-encoding",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1986,21 +1987,21 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.67"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0563a9a4b071746dd5aedbc3a28c6fe9be4586fb3fbadb67c400d4f53c6b16c"
|
||||
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"serde 1.0.115",
|
||||
"serde 1.0.116",
|
||||
"serde_json",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.67"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc71e4c5efa60fb9e74160e89b93353bc24059999c0ae0fb03affc39770310b0"
|
||||
checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
|
@ -2013,9 +2014,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.17"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95f8d235a77f880bcef268d379810ea6c0af2eacfa90b1ad5af731776e0c4699"
|
||||
checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
|
@ -2025,9 +2026,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.67"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97c57cefa5fa80e2ba15641578b44d36e7a64279bc5ed43c6dbaf329457a2ed2"
|
||||
checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
|
@ -2035,9 +2036,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.67"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "841a6d1c35c6f596ccea1f82504a192a60378f64b3bb0261904ad8f2f5657556"
|
||||
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2048,15 +2049,15 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.67"
|
||||
version = "0.2.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93b162580e34310e5931c4b792560108b10fd14d64915d7fff8ff00180e70092"
|
||||
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.44"
|
||||
version = "0.3.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dda38f4e5ca63eda02c059d243aa25b5f35ab98451e518c51612cd0f1bd19a47"
|
||||
checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
|
@ -2064,9 +2065,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "wepoll-sys-stjepang"
|
||||
version = "1.0.6"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694"
|
||||
checksum = "1fdfbb03f290ca0b27922e8d48a0997b4ceea12df33269b9f75e713311eb178d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
|
|
@ -3,6 +3,9 @@ external = "eth[0-9]+"
|
|||
internal = [
|
||||
"enp1s0"
|
||||
]
|
||||
tunnel = [
|
||||
"wg[0-9]+"
|
||||
]
|
||||
|
||||
[network]
|
||||
shared-internal = true
|
||||
|
|
|
@ -183,6 +183,23 @@ ul {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
.interface {
|
||||
padding: 8px 0;
|
||||
border-top: 1px solid #ddd;
|
||||
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
border-top: none;
|
||||
}
|
||||
&:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
@media(max-width: 650px) {
|
||||
body {
|
||||
padding: 8px 0 48px;
|
||||
|
|
|
@ -26,12 +26,14 @@ impl fmt::Display for Proto {
|
|||
}
|
||||
|
||||
pub(crate) async fn input_accept(
|
||||
proto: Proto,
|
||||
external_interface: &str,
|
||||
external_ip: Ipv4Addr,
|
||||
external_port: u16,
|
||||
external_mask: u8,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
input(
|
||||
proto,
|
||||
external_interface,
|
||||
external_ip,
|
||||
external_port,
|
||||
|
@ -42,12 +44,14 @@ pub(crate) async fn input_accept(
|
|||
}
|
||||
|
||||
pub(crate) async fn delete_input_accept(
|
||||
proto: Proto,
|
||||
external_interface: &str,
|
||||
external_ip: Ipv4Addr,
|
||||
external_port: u16,
|
||||
external_mask: u8,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
input(
|
||||
proto,
|
||||
external_interface,
|
||||
external_ip,
|
||||
external_port,
|
||||
|
@ -58,6 +62,7 @@ pub(crate) async fn delete_input_accept(
|
|||
}
|
||||
|
||||
async fn input(
|
||||
proto: Proto,
|
||||
external_interface: &str,
|
||||
external_ip: Ipv4Addr,
|
||||
external_port: u16,
|
||||
|
@ -72,13 +77,13 @@ async fn input(
|
|||
"-i",
|
||||
external_interface,
|
||||
"-p",
|
||||
"tcp",
|
||||
proto.as_iptables_str(),
|
||||
"-m",
|
||||
"conntrack",
|
||||
"--ctstate",
|
||||
"NEW,RELATED,ESTABLISHED",
|
||||
"-m",
|
||||
"tcp",
|
||||
proto.as_iptables_str(),
|
||||
"--dport",
|
||||
&external_port.to_string(),
|
||||
"-j",
|
||||
|
@ -275,6 +280,9 @@ async fn forward_prerouting_dnat(
|
|||
.await
|
||||
}
|
||||
|
||||
/// iptables -I FORWARD -i %i -j ACCEPT
|
||||
/// iptables -I FORWARD -o %i -j ACCEPT
|
||||
|
||||
async fn iptables_nat(func: impl Fn(&mut Command) -> &mut Command) -> Result<(), anyhow::Error> {
|
||||
iptables(move |cmd| func(cmd.args(&["-t", "nat"]))).await
|
||||
}
|
||||
|
|
86
src/main.rs
86
src/main.rs
|
@ -17,7 +17,7 @@ mod session;
|
|||
mod startup;
|
||||
|
||||
use self::{
|
||||
middleware::AuthMiddleware,
|
||||
middleware::{AuthMiddleware, UserInfo},
|
||||
rules::Rule,
|
||||
startup::{Config, Interfaces, ServerState},
|
||||
templates::statics::StaticFile,
|
||||
|
@ -93,27 +93,25 @@ async fn login(mut req: tide::Request<()>) -> tide::Result {
|
|||
|
||||
let login_form: LoginForm = QS.deserialize_str(&body_string)?;
|
||||
|
||||
session::login(&DB, login_form.username, login_form.password)?;
|
||||
session::login(&DB, login_form.username.clone(), login_form.password)?;
|
||||
|
||||
let session = req.session_mut();
|
||||
|
||||
session.insert("logged_in", true)?;
|
||||
session.insert(
|
||||
"user",
|
||||
UserInfo {
|
||||
username: login_form.username,
|
||||
},
|
||||
)?;
|
||||
|
||||
if let Some(path) = session.get("return_to") {
|
||||
let path: String = path; // tell the compiler what type i want it to be
|
||||
session.remove("return_to");
|
||||
Ok(to_custom(&path))
|
||||
} else {
|
||||
Ok(to_home())
|
||||
}
|
||||
Ok(return_to(session))
|
||||
}
|
||||
|
||||
async fn login_page(req: tide::Request<()>) -> tide::Result {
|
||||
tide::log::debug!("LOGIN PAGE");
|
||||
let session = req.session();
|
||||
let logged_in: bool = session.get("logged_in").unwrap_or(false);
|
||||
|
||||
if logged_in {
|
||||
if session.get::<UserInfo>("user").is_some() {
|
||||
tide::log::debug!("TO HOME");
|
||||
return Ok(to_home());
|
||||
}
|
||||
|
@ -135,7 +133,7 @@ async fn login_page(req: tide::Request<()>) -> tide::Result {
|
|||
async fn home_page(_: tide::Request<()>) -> tide::Result {
|
||||
let mut html = Vec::new();
|
||||
|
||||
templates::home_html(&mut html, INTERFACES.external.ip.to_string())?;
|
||||
templates::home_html(&mut html, &INTERFACES)?;
|
||||
|
||||
Ok(tide::Response::builder(200)
|
||||
.body(html)
|
||||
|
@ -147,6 +145,63 @@ async fn home_page(_: tide::Request<()>) -> tide::Result {
|
|||
.build())
|
||||
}
|
||||
|
||||
async fn account_page(mut req: tide::Request<()>) -> tide::Result {
|
||||
let mut html = Vec::new();
|
||||
|
||||
let path = req.url().path().to_string();
|
||||
let session = req.session_mut();
|
||||
|
||||
let user_info = if let Some(user_info) = session.get::<UserInfo>("user") {
|
||||
user_info
|
||||
} else {
|
||||
return to_login(session, &path);
|
||||
};
|
||||
|
||||
templates::account_html(&mut html, &user_info)?;
|
||||
|
||||
Ok(tide::Response::builder(200)
|
||||
.body(html)
|
||||
.content_type(
|
||||
"text/html;charset=utf-8"
|
||||
.parse::<tide::http::Mime>()
|
||||
.unwrap(),
|
||||
)
|
||||
.build())
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
struct UpdateAccountForm {
|
||||
username: String,
|
||||
new_password: String,
|
||||
confirm_new_password: String,
|
||||
password: String,
|
||||
}
|
||||
|
||||
async fn update_account(mut req: tide::Request<()>) -> tide::Result {
|
||||
let body_string = req.body_string().await?;
|
||||
let form: UpdateAccountForm = QS.deserialize_str(&body_string)?;
|
||||
|
||||
if form.new_password != form.confirm_new_password {
|
||||
return Err(anyhow::anyhow!("Passwords do not match").into());
|
||||
}
|
||||
|
||||
session::verify(&DB, &form.username, form.password).await?;
|
||||
session::update_password(&DB, form.username, form.new_password).await?;
|
||||
|
||||
Ok(to_account())
|
||||
}
|
||||
|
||||
fn return_to(session: &mut Session) -> tide::Response {
|
||||
if let Some(path) = session.get("return_to") {
|
||||
let path: String = path; // tell the compiler what type i want it to be
|
||||
session.remove("return_to");
|
||||
to_custom(&path)
|
||||
} else {
|
||||
to_home()
|
||||
}
|
||||
}
|
||||
|
||||
fn to_custom(location: &str) -> tide::Response {
|
||||
tide::Response::builder(302)
|
||||
.header("Location", location)
|
||||
|
@ -154,6 +209,10 @@ fn to_custom(location: &str) -> tide::Response {
|
|||
.build()
|
||||
}
|
||||
|
||||
fn to_account() -> tide::Response {
|
||||
to_custom("/account")
|
||||
}
|
||||
|
||||
fn to_home() -> tide::Response {
|
||||
to_custom("/")
|
||||
}
|
||||
|
@ -201,6 +260,7 @@ fn main() -> Result<(), anyhow::Error> {
|
|||
app.with(LogMiddleware::new());
|
||||
app.at("/static/:file").get(statics);
|
||||
app.at("/login").get(login_page).post(login);
|
||||
app.at("/account").get(account_page).post(update_account);
|
||||
app.at("/rules")
|
||||
.with(AuthMiddleware)
|
||||
.get(rules_page)
|
||||
|
|
|
@ -3,6 +3,11 @@ use tide::{Middleware, Next, Request};
|
|||
|
||||
pub(crate) struct AuthMiddleware;
|
||||
|
||||
#[derive(serde::Deserialize, serde::Serialize)]
|
||||
pub struct UserInfo {
|
||||
pub(crate) username: String,
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<State> Middleware<State> for AuthMiddleware
|
||||
where
|
||||
|
@ -11,9 +16,8 @@ where
|
|||
async fn handle(&self, mut request: Request<State>, next: Next<'_, State>) -> tide::Result {
|
||||
let path = request.url().path().to_string();
|
||||
let session = request.session_mut();
|
||||
let logged_in: bool = session.get("logged_in").unwrap_or(false);
|
||||
|
||||
if logged_in {
|
||||
if session.get::<UserInfo>("user").is_some() {
|
||||
return Ok(next.run(request).await);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ pub(crate) async fn unset(interfaces: &Interfaces, rule: Rule) -> Result<(), any
|
|||
match rule.kind {
|
||||
RuleKind::Accept => {
|
||||
iptables::delete_input_accept(
|
||||
rule.proto,
|
||||
&interfaces.external.interface,
|
||||
interfaces.external.ip,
|
||||
rule.port,
|
||||
|
@ -138,6 +139,7 @@ pub(crate) async fn apply(interfaces: &Interfaces, rule: Rule) -> Result<(), any
|
|||
match rule.kind {
|
||||
RuleKind::Accept => {
|
||||
iptables::input_accept(
|
||||
rule.proto,
|
||||
&interfaces.external.interface,
|
||||
interfaces.external.ip,
|
||||
rule.port,
|
||||
|
|
|
@ -40,6 +40,48 @@ async fn add_user(db: &Db, username: String, password: String) -> Result<(), any
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn update_password(
|
||||
db: &Db,
|
||||
username: String,
|
||||
new_password: String,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let tree = user_tree(db);
|
||||
|
||||
let hash = bcrypt::hash(&new_password, bcrypt::DEFAULT_COST)?;
|
||||
|
||||
let updated = tree
|
||||
.update_and_fetch(username.as_bytes(), move |opt| {
|
||||
if opt.is_some() {
|
||||
Some(hash.clone().into_bytes())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})?
|
||||
.is_some();
|
||||
|
||||
if updated {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Err(anyhow::anyhow!("User doesn't exist"))
|
||||
}
|
||||
|
||||
pub(crate) async fn verify(db: &Db, username: &str, password: String) -> Result<(), anyhow::Error> {
|
||||
let tree = user_tree(db);
|
||||
|
||||
let hash = tree
|
||||
.get(username.as_bytes())?
|
||||
.ok_or_else(|| anyhow::anyhow!("Missing user {}", username))?;
|
||||
|
||||
let password_hash = String::from_utf8_lossy(&hash);
|
||||
|
||||
if bcrypt::verify(password, &password_hash)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Err(anyhow::anyhow!("Invalid password"))
|
||||
}
|
||||
|
||||
pub(crate) async fn create_admin(db: &Db) -> Result<(), anyhow::Error> {
|
||||
use rand::Rng;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ pub(crate) struct Config {
|
|||
struct InterfaceConfig {
|
||||
external: String,
|
||||
internal: Vec<String>,
|
||||
tunnel: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
|
@ -33,10 +34,11 @@ struct ServerConfig {
|
|||
secret: String,
|
||||
}
|
||||
|
||||
pub(crate) struct Interfaces {
|
||||
pub struct Interfaces {
|
||||
pub(crate) external: InterfaceInfo,
|
||||
pub(crate) internal: Vec<InterfaceInfo>,
|
||||
shared_internal: bool,
|
||||
pub(crate) tunnel: Vec<InterfaceInfo>,
|
||||
pub(crate) shared_internal: bool,
|
||||
}
|
||||
|
||||
pub(crate) struct InterfaceInfo {
|
||||
|
@ -85,6 +87,18 @@ impl Interfaces {
|
|||
ip: "192.168.6.1".parse()?,
|
||||
mask: 24,
|
||||
}],
|
||||
tunnel: vec![
|
||||
InterfaceInfo {
|
||||
interface: String::from("wg0"),
|
||||
ip: "192.168.5.0".parse()?,
|
||||
mask: 24,
|
||||
},
|
||||
InterfaceInfo {
|
||||
interface: String::from("wg1"),
|
||||
ip: "192.168.4.0".parse()?,
|
||||
mask: 24,
|
||||
},
|
||||
],
|
||||
shared_internal: false,
|
||||
});
|
||||
}
|
||||
|
@ -112,9 +126,16 @@ impl Interfaces {
|
|||
));
|
||||
}
|
||||
|
||||
let mut tunnel = Vec::new();
|
||||
|
||||
for iface in &config.interface.tunnel {
|
||||
tunnel.extend(parse_interface_info(&output, &iface)?);
|
||||
}
|
||||
|
||||
Ok(Interfaces {
|
||||
external,
|
||||
internal,
|
||||
tunnel,
|
||||
shared_internal: config.network.shared_internal,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -184,6 +184,18 @@ fn filter(interfaces: &Interfaces) -> String {
|
|||
|
||||
// FORWARD: Forwarding traffic across interfaces
|
||||
|
||||
// Accept packets over tunnel interfaces
|
||||
for iface in &interfaces.tunnel {
|
||||
filter += &format!(
|
||||
"-A FORWARD -i {tunface} -j ACCEPT\n",
|
||||
tunface = iface.interface,
|
||||
);
|
||||
filter += &format!(
|
||||
"-A FORWARD -o {tunface} -j ACCEPT\n",
|
||||
tunface = iface.interface,
|
||||
);
|
||||
}
|
||||
|
||||
// Accept TCP packets
|
||||
for iface in &interfaces.internal {
|
||||
filter += &format!(
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
@use crate::{
|
||||
templates::{layout_html, return_home_html},
|
||||
UserInfo,
|
||||
};
|
||||
|
||||
@(account: &UserInfo)
|
||||
|
||||
@:layout_html("Account", {
|
||||
<section>
|
||||
<h1>Update Account</h1>
|
||||
</section>
|
||||
<section>
|
||||
<form method="POST" action="/account">
|
||||
<div class="form-body">
|
||||
<input type="hidden" name="username" value="@account.username" />
|
||||
<label for="new-password">
|
||||
<h4>Update password</h4>
|
||||
<input name="new-password" type="password" />
|
||||
</label>
|
||||
<label for="confirm-new-password">
|
||||
<h4>Confirm password</h4>
|
||||
<input name="confirm-new-password" type="password" />
|
||||
</label>
|
||||
<label for="password">
|
||||
<h4>Current password</h4>
|
||||
<input name="password" type="password" />
|
||||
</label>
|
||||
</div>
|
||||
<div class="submit">
|
||||
<button type="submit">Update</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
@:return_home_html()
|
||||
})
|
|
@ -1,15 +1,47 @@
|
|||
@use crate::templates::layout_html;
|
||||
@use crate::{
|
||||
templates::layout_html,
|
||||
startup::Interfaces,
|
||||
};
|
||||
|
||||
@(ip: String)
|
||||
@(interfaces: &Interfaces)
|
||||
|
||||
@:layout_html("Router", {
|
||||
<section>
|
||||
<h1>Home</h1>
|
||||
</section>
|
||||
<section>
|
||||
<h4>Info</h4>
|
||||
<h4>Internet</h4>
|
||||
<div class="content">
|
||||
<p>IP: @ip</p>
|
||||
<div class="interface">
|
||||
<p><span class="title">IP:</span> @interfaces.external.ip</p>
|
||||
<p><span class="title">Interface:</span> @interfaces.external.interface</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h4>Internal Networks</h4>
|
||||
<div class="content">
|
||||
<ul>
|
||||
@for iface in &interfaces.internal {
|
||||
<li class="interface">
|
||||
<p><span class="title">IP:</span> @iface.ip</p>
|
||||
<p><span class="title">Interface:</span> @iface.interface</p>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h4>Tunnels</h4>
|
||||
<div class="content">
|
||||
<ul>
|
||||
@for iface in &interfaces.tunnel {
|
||||
<li class="interface">
|
||||
<p><span class="title">IP:</span> @iface.ip</p>
|
||||
<p><span class="title">Interface:</span> @iface.interface</p>
|
||||
</li>
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
|
@ -17,6 +49,7 @@
|
|||
<nav class="content">
|
||||
<ul>
|
||||
<li><a href="/rules">Add traffic rules</a></li>
|
||||
<li><a href="/account">Update account info</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
</section>
|
||||
|
|
Loading…
Reference in New Issue