Advance Red Bear runtime services and tools
This commit is contained in:
@@ -8,6 +8,8 @@ name = "redbear-authd"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
redbear-login-protocol = { path = "../../redbear-login-protocol/source" }
|
||||
rust-argon2 = "3"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
# Pure-Rust SHA-256/SHA-512 crypt verifier for /etc/shadow entries.
|
||||
|
||||
@@ -10,7 +10,9 @@ use std::{
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use argon2::{self, verify_encoded};
|
||||
use redbear_login_protocol::{AuthRequest, AuthResponse};
|
||||
use serde::Serialize;
|
||||
use sha_crypt::{PasswordVerifier, ShaCrypt};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
@@ -49,51 +51,6 @@ struct RuntimeState {
|
||||
failures: Arc<Mutex<HashMap<String, FailureState>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
enum AuthRequest {
|
||||
Authenticate {
|
||||
request_id: u64,
|
||||
username: String,
|
||||
password: String,
|
||||
vt: u32,
|
||||
},
|
||||
StartSession {
|
||||
request_id: u64,
|
||||
username: String,
|
||||
session: String,
|
||||
vt: u32,
|
||||
},
|
||||
PowerAction {
|
||||
request_id: u64,
|
||||
action: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
enum AuthResponse {
|
||||
AuthenticateResult {
|
||||
request_id: u64,
|
||||
ok: bool,
|
||||
message: String,
|
||||
},
|
||||
SessionResult {
|
||||
request_id: u64,
|
||||
ok: bool,
|
||||
exit_code: Option<i32>,
|
||||
message: String,
|
||||
},
|
||||
PowerResult {
|
||||
request_id: u64,
|
||||
ok: bool,
|
||||
message: String,
|
||||
},
|
||||
Error {
|
||||
message: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
enum SessiondUpdate {
|
||||
@@ -229,6 +186,9 @@ fn verify_shadow_password(password: &str, shadow_hash: &str) -> Result<bool, Ver
|
||||
.verify_password(password.as_bytes(), shadow_hash)
|
||||
.is_ok());
|
||||
}
|
||||
if shadow_hash.starts_with("$argon2") {
|
||||
return Ok(verify_encoded(shadow_hash, password.as_bytes()).unwrap_or(false));
|
||||
}
|
||||
Err(VerifyError::UnsupportedHashFormat)
|
||||
}
|
||||
|
||||
@@ -589,6 +549,15 @@ mod tests {
|
||||
assert_eq!(verify_shadow_password("wrong", hash), Ok(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_shadow_password_accepts_argon2_hashes() {
|
||||
let config = argon2::Config::default();
|
||||
let hash = argon2::hash_encoded(b"password", b"testsalt", &config)
|
||||
.expect("argon2 hash should encode");
|
||||
assert_eq!(verify_shadow_password("password", &hash), Ok(true));
|
||||
assert_eq!(verify_shadow_password("wrong", &hash), Ok(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn verify_shadow_password_rejects_unknown_hash_prefix() {
|
||||
assert_eq!(verify_shadow_password("password", "$1$legacy$hash"), Err(VerifyError::UnsupportedHashFormat));
|
||||
|
||||
Reference in New Issue
Block a user