From cb44497feee3938f5345f8342964aac888344402 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Sun, 11 Jul 2021 17:54:15 +0200 Subject: [PATCH] Add password to security keys --- docs/db_struct.sql | 1 + docs/migration.sql | 1 + src/api_data/admin/admin_auth_options.rs | 3 ++- src/api_data/admin/admin_keys_api.rs | 2 ++ src/controllers/admin/admin_keys_controller.rs | 14 +++++++++++++- src/data/admin.rs | 1 + src/helpers/admin_account_key_helper.rs | 5 ++++- 7 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/db_struct.sql b/docs/db_struct.sql index 4a4816f..ad3d075 100644 --- a/docs/db_struct.sql +++ b/docs/db_struct.sql @@ -288,6 +288,7 @@ CREATE TABLE `comunic_admin_key` ( `name` VARCHAR(45) NULL, `time_add` INT NULL, `credential` TEXT NULL, + `password` VARCHAR(255) NULL, PRIMARY KEY (`id`)); CREATE TABLE `comunic_admin_roles` ( diff --git a/docs/migration.sql b/docs/migration.sql index faf46e3..b824c8c 100644 --- a/docs/migration.sql +++ b/docs/migration.sql @@ -14,6 +14,7 @@ CREATE TABLE `comunic_admin_key` ( `name` VARCHAR(45) NULL, `time_add` INT NULL, `credential` TEXT NULL, + `password` VARCHAR(255) NULL, PRIMARY KEY (`id`)); CREATE TABLE `comunic_admin_roles` ( diff --git a/src/api_data/admin/admin_auth_options.rs b/src/api_data/admin/admin_auth_options.rs index d1eeec3..287d531 100644 --- a/src/api_data/admin/admin_auth_options.rs +++ b/src/api_data/admin/admin_auth_options.rs @@ -10,6 +10,7 @@ use crate::data::admin::{Admin, AdminKey}; struct AuthKey { name: String, id: u64, + password: bool, } #[derive(Serialize)] @@ -22,7 +23,7 @@ impl AdminAuthOptions { pub fn new(admin: &Admin, keys: &Vec) -> Self { Self { reset_token: admin.reset_token.is_some(), - keys: keys.iter().map(|k| AuthKey { id: k.id, name: k.name.to_string() }).collect(), + keys: keys.iter().map(|k| AuthKey { id: k.id, name: k.name.to_string(), password: k.password.is_some() }).collect(), } } } \ No newline at end of file diff --git a/src/api_data/admin/admin_keys_api.rs b/src/api_data/admin/admin_keys_api.rs index 2693118..a1f6fa1 100644 --- a/src/api_data/admin/admin_keys_api.rs +++ b/src/api_data/admin/admin_keys_api.rs @@ -10,6 +10,7 @@ pub struct AdminKeyAPI { id: u64, name: String, time_add: u64, + has_password: bool, } impl AdminKeyAPI { @@ -18,6 +19,7 @@ impl AdminKeyAPI { id: key.id, name: key.name.to_string(), time_add: key.time_add, + has_password: key.password.is_some(), } } } \ No newline at end of file diff --git a/src/controllers/admin/admin_keys_controller.rs b/src/controllers/admin/admin_keys_controller.rs index 7dbce0a..610ded0 100644 --- a/src/controllers/admin/admin_keys_controller.rs +++ b/src/controllers/admin/admin_keys_controller.rs @@ -3,6 +3,8 @@ //! @author Pierre Hubert +use bcrypt::verify; + use crate::api_data::admin::admin_auth_success::AdminAuthSuccess; use crate::api_data::admin::admin_keys_api::AdminKeyAPI; use crate::constants::admin::AdminRole; @@ -63,6 +65,7 @@ pub fn challenge_register_key(r: &mut HttpRequestHandler) -> RequestResult { /// Register key pub fn register_key(r: &mut HttpRequestHandler) -> RequestResult { let key_name = r.post_string("name")?; + let key_password = r.post_string("password")?; let creds = r.post_register_public_key_credential("key")?; let state = r.some_or_internal_error( @@ -73,7 +76,7 @@ pub fn register_key(r: &mut HttpRequestHandler) -> RequestResult { let wan = get_wan(); let key = wan.register_credential(creds, state, |_| Ok(false))?; - let key_id = admin_account_key_helper::add_key(r.admin_id()?, &key_name, key)?; + let key_id = admin_account_key_helper::add_key(r.admin_id()?, &key_name, key, key_password)?; log_admin_action(r.admin_id()?, &r.remote_ip(), AdminAction::RegisteredAdminKey { @@ -138,6 +141,15 @@ pub fn auth_with_key(r: &mut HttpRequestHandler) -> RequestResult { let state = get_wan().authenticate_credential(credentials, state)?; r.some_or_bad_request(state, "Invalid key!")?; + // Check key password (if any) + if let Some(pass_hash) = key.password { + let password = r.post_string("password")?; + + if !verify(password, &pass_hash)? { + r.forbidden("Bad key password!".to_string())?; + } + } + // Generate access token let token = admin_access_token_helper::create(key.admin_id)?; diff --git a/src/data/admin.rs b/src/data/admin.rs index ef09fe7..f3a3151 100644 --- a/src/data/admin.rs +++ b/src/data/admin.rs @@ -51,6 +51,7 @@ pub struct AdminKey { pub name: String, pub time_add: u64, pub key: Credential, + pub password: Option, } /// Admin access token diff --git a/src/helpers/admin_account_key_helper.rs b/src/helpers/admin_account_key_helper.rs index a2d0224..0543529 100644 --- a/src/helpers/admin_account_key_helper.rs +++ b/src/helpers/admin_account_key_helper.rs @@ -2,6 +2,7 @@ //! //! @author Pierre Hubert +use bcrypt::{DEFAULT_COST, hash_with_result}; use webauthn_rs::proto::Credential; use crate::constants::database_tables_names::ADMIN_KEYS_TABLE; @@ -11,12 +12,13 @@ use crate::helpers::database; use crate::utils::date_utils::time; /// Save a new key in the database -pub fn add_key(id: AdminID, name: &str, key: Credential) -> Res { +pub fn add_key(id: AdminID, name: &str, key: Credential, password: String) -> Res { database::InsertQuery::new(ADMIN_KEYS_TABLE) .add_admin_id("admin_id", id) .add_str("name", name) .add_u64("time_add", time()) .add_str("credential", &serde_json::to_string(&key)?) + .add_str("password", &hash_with_result(password, DEFAULT_COST)?.to_string()) .insert_expect_result() } @@ -42,5 +44,6 @@ fn db_to_admin_key(row: &database::RowResult) -> Res { name: row.get_str("name")?, time_add: row.get_u64("time_add")?, key: serde_json::from_str(&row.get_str("credential")?)?, + password: row.get_optional_str("password")?, }) } \ No newline at end of file