diff --git a/Cargo.lock b/Cargo.lock index a0b803d..0f6e72f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,18 +2,53 @@ # It is not intended for manual editing. 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]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "bytes" version = "1.4.0" @@ -26,6 +61,27 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "dirs" version = "5.0.0" @@ -62,6 +118,7 @@ dependencies = [ name = "forge-server" version = "0.1.0" dependencies = [ + "argon2", "dirs", "paris", "serde", @@ -82,6 +139,16 @@ dependencies = [ "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]] name = "getrandom" version = "0.2.8" @@ -222,6 +289,17 @@ dependencies = [ "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]] name = "percent-encoding" version = "2.2.0" @@ -385,6 +463,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "syn" version = "2.0.13" @@ -495,6 +579,12 @@ dependencies = [ "winnow", ] +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -550,6 +640,12 @@ dependencies = [ "vsimd", ] +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "vsimd" version = "0.8.0" diff --git a/Cargo.toml b/Cargo.toml index 55fc1df..206ccde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ uuid-simd = "0.8.0" uuid = { version = "1.3.0", features = ["v4", "fast-rng", "serde"] } paris = { version = "1.5", features = ["timestamps", "macros"] } toml = "0.7.3" +argon2 = "0.5.0" diff --git a/forge-client/src/main.rs b/forge-client/src/main.rs index d065309..48b0072 100644 --- a/forge-client/src/main.rs +++ b/forge-client/src/main.rs @@ -68,6 +68,7 @@ struct Command { #[derive(Serialize, Deserialize)] struct Message { + authentication: Option, uuid: Uuid, pre_exec: Option, profile: bool, @@ -89,6 +90,7 @@ async fn main() -> Result<(), Box> { tag: Tag::Debug, }; let test_message = Message { + authentication: Some("test123".to_string()), uuid: Uuid::new_v4(), pre_exec: None, profile: false, diff --git a/forge-server/Cargo.toml b/forge-server/Cargo.toml index fdd245b..6acb850 100644 --- a/forge-server/Cargo.toml +++ b/forge-server/Cargo.toml @@ -12,4 +12,5 @@ uuid-simd.workspace = true uuid.workspace = true paris.workspace = true toml.workspace = true +argon2.workspace = true dirs = "5.0" diff --git a/forge-server/src/main.rs b/forge-server/src/main.rs index 681f680..1acd0e0 100644 --- a/forge-server/src/main.rs +++ b/forge-server/src/main.rs @@ -1,3 +1,7 @@ +use argon2::{ + password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString}, + Argon2, +}; use paris::{error, info, success, warn}; use serde::{Deserialize, Serialize}; use serde_json::Result; @@ -14,9 +18,16 @@ struct HostConfig { port: u16, } +#[derive(Serialize, Deserialize, Clone)] +struct AuthConfig { + authenticate: bool, + password: Option, +} + #[derive(Serialize, Deserialize)] struct Config { host: HostConfig, + auth: AuthConfig, } #[derive(Serialize, Deserialize, Debug)] @@ -80,6 +91,7 @@ struct Command { #[derive(Serialize, Deserialize)] struct Message { + authentication: Option, uuid: Uuid, pre_exec: Option, 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 mut reader = BufReader::new(reader); @@ -139,9 +180,22 @@ async fn process_socket(mut socket: TcpStream, address: SocketAddr) { } }; - tokio::spawn(async move { + if auth.authenticate { + match &auth.password { + Some(pass) => { + if json.authenticate(pass.clone()).await { + tokio::spawn(async move { + build(json, address).await; + }); + } + } + None => { + error!("No password configured!"); + } + } + } else { build(json, address).await; - }); + } } } @@ -155,8 +209,9 @@ async fn main() -> io::Result<()> { loop { match listener.accept().await { Ok((socket, addr)) => { + let auth = config.auth.clone(); tokio::spawn(async move { - process_socket(socket, addr).await; + process_socket(socket, addr, auth).await; }); } Err(e) => error!("couldn't get client: {:?}", e), @@ -178,6 +233,10 @@ async fn configure() -> Config { ip: "127.0.0.1".to_string(), port: 9134, }, + auth: AuthConfig { + authenticate: false, + password: None, + }, }; let toml = toml::to_string(&config).unwrap(); default_config.pop();