More info on homepage, tunnel firewall rules, update password flow

This commit is contained in:
asonix 2020-09-14 22:35:56 -05:00
parent 8d3b3eb23c
commit 5e41063680
12 changed files with 327 additions and 89 deletions

133
Cargo.lock generated
View File

@ -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",
]

View File

@ -3,6 +3,9 @@ external = "eth[0-9]+"
internal = [
"enp1s0"
]
tunnel = [
"wg[0-9]+"
]
[network]
shared-internal = true

View File

@ -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;

View File

@ -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
}

View File

@ -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)

View File

@ -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);
}

View File

@ -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,

View File

@ -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;

View File

@ -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,
})
}

View File

@ -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!(

35
templates/account.rs.html Normal file
View File

@ -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()
})

View File

@ -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>