Several untracked changed...
This commit is contained in:
parent
a9a10a6d52
commit
0cf00faf78
8 changed files with 119 additions and 50 deletions
63
Cargo.lock
generated
63
Cargo.lock
generated
|
|
@ -377,6 +377,17 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chacha20"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cpufeatures 0.3.0",
|
||||||
|
"rand_core 0.10.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.44"
|
version = "0.4.44"
|
||||||
|
|
@ -449,6 +460,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-utils"
|
name = "crossbeam-utils"
|
||||||
version = "0.8.21"
|
version = "0.8.21"
|
||||||
|
|
@ -462,7 +482,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
|
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"subtle",
|
"subtle",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
@ -484,7 +504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
"curve25519-dalek-derive",
|
"curve25519-dalek-derive",
|
||||||
"digest",
|
"digest",
|
||||||
"fiat-crypto",
|
"fiat-crypto",
|
||||||
|
|
@ -601,7 +621,7 @@ dependencies = [
|
||||||
"hkdf",
|
"hkdf",
|
||||||
"pem-rfc7468",
|
"pem-rfc7468",
|
||||||
"pkcs8",
|
"pkcs8",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"sec1",
|
"sec1",
|
||||||
"subtle",
|
"subtle",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
|
|
@ -683,7 +703,7 @@ version = "0.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
|
checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -815,6 +835,7 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
"r-efi 6.0.0",
|
"r-efi 6.0.0",
|
||||||
|
"rand_core 0.10.0",
|
||||||
"wasip2",
|
"wasip2",
|
||||||
"wasip3",
|
"wasip3",
|
||||||
]
|
]
|
||||||
|
|
@ -832,7 +853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
|
checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ff",
|
"ff",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1068,7 +1089,7 @@ dependencies = [
|
||||||
"p256",
|
"p256",
|
||||||
"p384",
|
"p384",
|
||||||
"pem",
|
"pem",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"rsa",
|
"rsa",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
@ -1206,7 +1227,7 @@ dependencies = [
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-iter",
|
"num-iter",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
@ -1510,7 +1531,18 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
|
||||||
|
dependencies = [
|
||||||
|
"chacha20",
|
||||||
|
"getrandom 0.4.2",
|
||||||
|
"rand_core 0.10.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1520,7 +1552,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1532,6 +1564,12 @@ dependencies = [
|
||||||
"getrandom 0.2.17",
|
"getrandom 0.2.17",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.12.3"
|
version = "1.12.3"
|
||||||
|
|
@ -1598,7 +1636,7 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"pkcs1",
|
"pkcs1",
|
||||||
"pkcs8",
|
"pkcs8",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
"signature",
|
"signature",
|
||||||
"spki",
|
"spki",
|
||||||
"subtle",
|
"subtle",
|
||||||
|
|
@ -1789,6 +1827,7 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"pam",
|
"pam",
|
||||||
|
"rand 0.10.0",
|
||||||
"rustls",
|
"rustls",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
@ -1804,7 +1843,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cpufeatures",
|
"cpufeatures 0.2.17",
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1831,7 +1870,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ bcrypt = "0.19.0"
|
||||||
chrono = "0.4.44"
|
chrono = "0.4.44"
|
||||||
jsonwebtoken = { version = "10.3.0", features = ["rust_crypto"] }
|
jsonwebtoken = { version = "10.3.0", features = ["rust_crypto"] }
|
||||||
pam = { version = "0.8.0", features = ["client"] }
|
pam = { version = "0.8.0", features = ["client"] }
|
||||||
|
rand = "0.10.0"
|
||||||
rustls = { version = "0.23.37", features = ["ring"] }
|
rustls = { version = "0.23.37", features = ["ring"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1.0.149"
|
serde_json = "1.0.149"
|
||||||
|
|
|
||||||
72
src/auth.rs
72
src/auth.rs
|
|
@ -1,18 +1,66 @@
|
||||||
use axum::response::Redirect;
|
use axum::{http::HeaderMap, http::StatusCode, response::IntoResponse, response::Json};
|
||||||
use axum::{
|
|
||||||
Router, extract::Path, http::HeaderMap, http::StatusCode, response::IntoResponse,
|
|
||||||
response::Json, routing::get, routing::post,
|
|
||||||
};
|
|
||||||
use base64::{Engine, engine::general_purpose};
|
use base64::{Engine, engine::general_purpose};
|
||||||
use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation, decode, encode};
|
use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation, decode, encode};
|
||||||
use pam::Client;
|
use pam::Client;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::path::PathBuf;
|
||||||
use sysinfo::{Components, Disks, Networks, System};
|
use std::sync::OnceLock;
|
||||||
use tokio::process::Command;
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use zbus::Connection;
|
|
||||||
|
|
||||||
const JWT_SECRET: &str = "change-me-to-a-long-random-string";
|
static JWT_SECRET: OnceLock<String> = OnceLock::new();
|
||||||
|
|
||||||
|
const ROTATION_DAYS: u64 = 7;
|
||||||
|
|
||||||
|
fn secret_path() -> PathBuf {
|
||||||
|
PathBuf::from("/home/jack/.local/share/sysapi/jwt_secret")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_secret() -> String {
|
||||||
|
format!(
|
||||||
|
"{:016x}{:016x}",
|
||||||
|
rand::random::<u64>(),
|
||||||
|
rand::random::<u64>()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn current_timestamp() -> u64 {
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn jwt_secret() -> &'static str {
|
||||||
|
JWT_SECRET.get_or_init(|| {
|
||||||
|
let path = secret_path();
|
||||||
|
std::fs::create_dir_all(path.parent().unwrap()).ok();
|
||||||
|
|
||||||
|
// file format: "timestamp:secret"
|
||||||
|
if let Ok(contents) = std::fs::read_to_string(&path) {
|
||||||
|
if let Some((ts_str, secret)) = contents.trim().split_once(':') {
|
||||||
|
if let Ok(ts) = ts_str.parse::<u64>() {
|
||||||
|
if current_timestamp() - ts < ROTATION_DAYS * 86400 {
|
||||||
|
return secret.to_string();
|
||||||
|
}
|
||||||
|
println!("JWT secret expired, rotating...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let secret = generate_secret();
|
||||||
|
let contents = format!("{}:{}", current_timestamp(), secret);
|
||||||
|
std::fs::write(&path, &contents).ok();
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::PermissionsExt;
|
||||||
|
std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600)).ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Generated new JWT secret");
|
||||||
|
secret
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Claims {
|
struct Claims {
|
||||||
|
|
@ -28,7 +76,7 @@ pub fn create_token(username: &str) -> String {
|
||||||
encode(
|
encode(
|
||||||
&Header::default(),
|
&Header::default(),
|
||||||
&claims,
|
&claims,
|
||||||
&EncodingKey::from_secret(JWT_SECRET.as_bytes()),
|
&EncodingKey::from_secret(jwt_secret().as_bytes()),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
@ -40,7 +88,7 @@ pub fn verify_token(headers: &HeaderMap) -> bool {
|
||||||
let token = val.to_str().unwrap_or("").replace("Bearer ", "");
|
let token = val.to_str().unwrap_or("").replace("Bearer ", "");
|
||||||
decode::<Claims>(
|
decode::<Claims>(
|
||||||
&token,
|
&token,
|
||||||
&DecodingKey::from_secret(JWT_SECRET.as_bytes()),
|
&DecodingKey::from_secret(jwt_secret().as_bytes()),
|
||||||
&Validation::default(),
|
&Validation::default(),
|
||||||
)
|
)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ pub const ALLOWED_SERVICES: &[&str] = &[
|
||||||
"syncthing",
|
"syncthing",
|
||||||
"caddy",
|
"caddy",
|
||||||
"sshd",
|
"sshd",
|
||||||
|
"dashboard",
|
||||||
|
"sysapi",
|
||||||
"cloudflare-dyndns.timer",
|
"cloudflare-dyndns.timer",
|
||||||
"cloudflare-dyndns",
|
"cloudflare-dyndns",
|
||||||
"docker",
|
"docker",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
use axum::response::Redirect;
|
use axum::response::Redirect;
|
||||||
use axum::{
|
use axum::{Router, routing::get, routing::post};
|
||||||
Router, extract::Path, http::HeaderMap, http::StatusCode, response::IntoResponse,
|
|
||||||
response::Json, routing::get, routing::post,
|
|
||||||
};
|
|
||||||
use tokio::process::Command;
|
|
||||||
|
|
||||||
mod auth;
|
mod auth;
|
||||||
mod config;
|
mod config;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,7 @@
|
||||||
use axum::response::Redirect;
|
|
||||||
use axum::{
|
use axum::{
|
||||||
Router, extract::Path, http::HeaderMap, http::StatusCode, response::IntoResponse,
|
extract::Path, http::HeaderMap, http::StatusCode, response::IntoResponse,
|
||||||
response::Json, routing::get, routing::post,
|
response::Json,
|
||||||
};
|
};
|
||||||
use base64::{Engine, engine::general_purpose};
|
|
||||||
use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation, decode, encode};
|
|
||||||
use pam::Client;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use sysinfo::{Components, Disks, Networks, System};
|
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,7 @@
|
||||||
use axum::response::Redirect;
|
use axum::response::Json;
|
||||||
use axum::{
|
|
||||||
Router, extract::Path, http::HeaderMap, http::StatusCode, response::IntoResponse,
|
|
||||||
response::Json, routing::get, routing::post,
|
|
||||||
};
|
|
||||||
use base64::{Engine, engine::general_purpose};
|
|
||||||
use jsonwebtoken::{DecodingKey, EncodingKey, Header, Validation, decode, encode};
|
|
||||||
use pam::Client;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use sysinfo::{Components, Disks, Networks, System};
|
use sysinfo::{Components, Disks, Networks, System};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
use zbus::Connection;
|
|
||||||
|
|
||||||
use crate::models;
|
use crate::models;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
use axum::{
|
use axum::{
|
||||||
Router, extract::Path, http::HeaderMap, http::StatusCode, response::IntoResponse,
|
http::HeaderMap, http::StatusCode, response::IntoResponse,
|
||||||
response::Json, routing::get, routing::post,
|
|
||||||
};
|
};
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue