Authentication via argon2id

status
~erin 2023-04-02 20:46:03 -04:00
parent 7552bc90a6
commit 63cce3cbc1
Signed by: erin
GPG Key ID: 9A8E308CEFA37A47
5 changed files with 163 additions and 4 deletions

96
Cargo.lock generated
View File

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

View File

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

View File

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

View File

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

View File

@ -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,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; build(json, address).await;
}); }
} }
} }
@ -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();