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

View File

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

View File

@ -68,6 +68,7 @@ struct Command {
#[derive(Serialize, Deserialize)]
struct Message {
authentication: Option<String>,
uuid: Uuid,
pre_exec: Option<String>,
profile: bool,
@ -89,6 +90,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
tag: Tag::Debug,
};
let test_message = Message {
authentication: Some("test123".to_string()),
uuid: Uuid::new_v4(),
pre_exec: None,
profile: false,

View File

@ -12,4 +12,5 @@ uuid-simd.workspace = true
uuid.workspace = true
paris.workspace = true
toml.workspace = true
argon2.workspace = true
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 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<String>,
}
#[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<String>,
uuid: Uuid,
pre_exec: Option<String>,
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();