Authentication via argon2id
parent
7552bc90a6
commit
63cce3cbc1
|
@ -2,18 +2,53 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "argon2"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95c2fcf79ad1932ac6269a738109997a83c227c09b75842ae564dc8ede6a861c"
|
||||||
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
|
"blake2",
|
||||||
|
"password-hash",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "autocfg"
|
name = "autocfg"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64ct"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blake2"
|
||||||
|
version = "0.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
|
||||||
|
dependencies = [
|
||||||
|
"digest",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -26,6 +61,27 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.10.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"crypto-common",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "5.0.0"
|
version = "5.0.0"
|
||||||
|
@ -62,6 +118,7 @@ dependencies = [
|
||||||
name = "forge-server"
|
name = "forge-server"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"argon2",
|
||||||
"dirs",
|
"dirs",
|
||||||
"paris",
|
"paris",
|
||||||
"serde",
|
"serde",
|
||||||
|
@ -82,6 +139,16 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
|
@ -222,6 +289,17 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "password-hash"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
|
||||||
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
|
"rand_core",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
@ -385,6 +463,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle"
|
||||||
|
version = "2.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "2.0.13"
|
version = "2.0.13"
|
||||||
|
@ -495,6 +579,12 @@ dependencies = [
|
||||||
"winnow",
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.13"
|
version = "0.3.13"
|
||||||
|
@ -550,6 +640,12 @@ dependencies = [
|
||||||
"vsimd",
|
"vsimd",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vsimd"
|
name = "vsimd"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
|
@ -16,3 +16,4 @@ uuid-simd = "0.8.0"
|
||||||
uuid = { version = "1.3.0", features = ["v4", "fast-rng", "serde"] }
|
uuid = { version = "1.3.0", features = ["v4", "fast-rng", "serde"] }
|
||||||
paris = { version = "1.5", features = ["timestamps", "macros"] }
|
paris = { version = "1.5", features = ["timestamps", "macros"] }
|
||||||
toml = "0.7.3"
|
toml = "0.7.3"
|
||||||
|
argon2 = "0.5.0"
|
||||||
|
|
|
@ -68,6 +68,7 @@ struct Command {
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Message {
|
struct Message {
|
||||||
|
authentication: Option<String>,
|
||||||
uuid: Uuid,
|
uuid: Uuid,
|
||||||
pre_exec: Option<String>,
|
pre_exec: Option<String>,
|
||||||
profile: bool,
|
profile: bool,
|
||||||
|
@ -89,6 +90,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||||
tag: Tag::Debug,
|
tag: Tag::Debug,
|
||||||
};
|
};
|
||||||
let test_message = Message {
|
let test_message = Message {
|
||||||
|
authentication: Some("test123".to_string()),
|
||||||
uuid: Uuid::new_v4(),
|
uuid: Uuid::new_v4(),
|
||||||
pre_exec: None,
|
pre_exec: None,
|
||||||
profile: false,
|
profile: false,
|
||||||
|
|
|
@ -12,4 +12,5 @@ uuid-simd.workspace = true
|
||||||
uuid.workspace = true
|
uuid.workspace = true
|
||||||
paris.workspace = true
|
paris.workspace = true
|
||||||
toml.workspace = true
|
toml.workspace = true
|
||||||
|
argon2.workspace = true
|
||||||
dirs = "5.0"
|
dirs = "5.0"
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
use argon2::{
|
||||||
|
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
|
||||||
|
Argon2,
|
||||||
|
};
|
||||||
use paris::{error, info, success, warn};
|
use paris::{error, info, success, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Result;
|
use serde_json::Result;
|
||||||
|
@ -14,9 +18,16 @@ struct HostConfig {
|
||||||
port: u16,
|
port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
struct AuthConfig {
|
||||||
|
authenticate: bool,
|
||||||
|
password: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Config {
|
struct Config {
|
||||||
host: HostConfig,
|
host: HostConfig,
|
||||||
|
auth: AuthConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
@ -80,6 +91,7 @@ struct Command {
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Message {
|
struct Message {
|
||||||
|
authentication: Option<String>,
|
||||||
uuid: Uuid,
|
uuid: Uuid,
|
||||||
pre_exec: Option<String>,
|
pre_exec: Option<String>,
|
||||||
profile: bool,
|
profile: bool,
|
||||||
|
@ -119,7 +131,36 @@ async fn build(msg: Message, address: SocketAddr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_socket(mut socket: TcpStream, address: SocketAddr) {
|
impl Message {
|
||||||
|
async fn authenticate(&self, passwd: String) -> bool {
|
||||||
|
match &self.authentication {
|
||||||
|
Some(auth) => {
|
||||||
|
let salt = SaltString::generate(&mut OsRng);
|
||||||
|
let argon2 = Argon2::default();
|
||||||
|
let password_hash = argon2
|
||||||
|
.hash_password(auth.as_bytes(), &salt)
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
let parsed_hash = PasswordHash::new(&password_hash).unwrap();
|
||||||
|
match Argon2::default().verify_password(passwd.as_bytes(), &parsed_hash) {
|
||||||
|
Ok(s) => {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("{}", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
error!("No authentication provided!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn process_socket(mut socket: TcpStream, address: SocketAddr, auth: AuthConfig) {
|
||||||
let (reader, writer) = socket.split();
|
let (reader, writer) = socket.split();
|
||||||
|
|
||||||
let mut reader = BufReader::new(reader);
|
let mut reader = BufReader::new(reader);
|
||||||
|
@ -139,11 +180,24 @@ async fn process_socket(mut socket: TcpStream, address: SocketAddr) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if auth.authenticate {
|
||||||
|
match &auth.password {
|
||||||
|
Some(pass) => {
|
||||||
|
if json.authenticate(pass.clone()).await {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
build(json, address).await;
|
build(json, address).await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
None => {
|
||||||
|
error!("No password configured!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
build(json, address).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> io::Result<()> {
|
async fn main() -> io::Result<()> {
|
||||||
|
@ -155,8 +209,9 @@ async fn main() -> io::Result<()> {
|
||||||
loop {
|
loop {
|
||||||
match listener.accept().await {
|
match listener.accept().await {
|
||||||
Ok((socket, addr)) => {
|
Ok((socket, addr)) => {
|
||||||
|
let auth = config.auth.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
process_socket(socket, addr).await;
|
process_socket(socket, addr, auth).await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Err(e) => error!("couldn't get client: {:?}", e),
|
Err(e) => error!("couldn't get client: {:?}", e),
|
||||||
|
@ -178,6 +233,10 @@ async fn configure() -> Config {
|
||||||
ip: "127.0.0.1".to_string(),
|
ip: "127.0.0.1".to_string(),
|
||||||
port: 9134,
|
port: 9134,
|
||||||
},
|
},
|
||||||
|
auth: AuthConfig {
|
||||||
|
authenticate: false,
|
||||||
|
password: None,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
let toml = toml::to_string(&config).unwrap();
|
let toml = toml::to_string(&config).unwrap();
|
||||||
default_config.pop();
|
default_config.pop();
|
||||||
|
|
Loading…
Reference in New Issue