You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-07-31 09:24:31 +03:00
Password schemes configuration
This commit is contained in:
@ -20,7 +20,7 @@ use futures_util::stream::{StreamExt, TryStreamExt};
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use mas_config::RootConfig;
|
use mas_config::RootConfig;
|
||||||
use mas_email::Mailer;
|
use mas_email::Mailer;
|
||||||
use mas_handlers::{AppState, HttpClientFactory, MatrixHomeserver};
|
use mas_handlers::{passwords::PasswordManager, AppState, HttpClientFactory, MatrixHomeserver};
|
||||||
use mas_listener::{server::Server, shutdown::ShutdownStream};
|
use mas_listener::{server::Server, shutdown::ShutdownStream};
|
||||||
use mas_policy::PolicyFactory;
|
use mas_policy::PolicyFactory;
|
||||||
use mas_router::UrlBuilder;
|
use mas_router::UrlBuilder;
|
||||||
@ -168,6 +168,24 @@ impl Options {
|
|||||||
|
|
||||||
let listeners_config = config.http.listeners.clone();
|
let listeners_config = config.http.listeners.clone();
|
||||||
|
|
||||||
|
let password_manager = config
|
||||||
|
.passwords
|
||||||
|
.load()
|
||||||
|
.await
|
||||||
|
.context("failed to load the password schemes")?
|
||||||
|
.into_iter()
|
||||||
|
.map(|(version, algorithm, secret)| {
|
||||||
|
use mas_handlers::passwords::Hasher;
|
||||||
|
let hasher = match algorithm {
|
||||||
|
mas_config::PasswordAlgorithm::Pbkdf2 => Hasher::pbkdf2(secret),
|
||||||
|
mas_config::PasswordAlgorithm::Bcrypt { cost } => Hasher::bcrypt(cost, secret),
|
||||||
|
mas_config::PasswordAlgorithm::Argon2id => Hasher::argon2id(secret),
|
||||||
|
};
|
||||||
|
|
||||||
|
(version, hasher)
|
||||||
|
});
|
||||||
|
let password_manager = PasswordManager::new(password_manager)?;
|
||||||
|
|
||||||
// Explicitely the config to properly zeroize secret keys
|
// Explicitely the config to properly zeroize secret keys
|
||||||
drop(config);
|
drop(config);
|
||||||
|
|
||||||
@ -199,6 +217,7 @@ impl Options {
|
|||||||
policy_factory,
|
policy_factory,
|
||||||
graphql_schema,
|
graphql_schema,
|
||||||
http_client_factory,
|
http_client_factory,
|
||||||
|
password_manager,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut fd_manager = listenfd::ListenFd::from_env();
|
let mut fd_manager = listenfd::ListenFd::from_env();
|
||||||
|
@ -23,6 +23,7 @@ mod database;
|
|||||||
mod email;
|
mod email;
|
||||||
mod http;
|
mod http;
|
||||||
mod matrix;
|
mod matrix;
|
||||||
|
mod passwords;
|
||||||
mod policy;
|
mod policy;
|
||||||
mod secrets;
|
mod secrets;
|
||||||
mod telemetry;
|
mod telemetry;
|
||||||
@ -38,6 +39,7 @@ pub use self::{
|
|||||||
Resource as HttpResource, TlsConfig as HttpTlsConfig, UnixOrTcp,
|
Resource as HttpResource, TlsConfig as HttpTlsConfig, UnixOrTcp,
|
||||||
},
|
},
|
||||||
matrix::MatrixConfig,
|
matrix::MatrixConfig,
|
||||||
|
passwords::{Algorithm as PasswordAlgorithm, PasswordsConfig},
|
||||||
policy::PolicyConfig,
|
policy::PolicyConfig,
|
||||||
secrets::SecretsConfig,
|
secrets::SecretsConfig,
|
||||||
telemetry::{
|
telemetry::{
|
||||||
@ -82,6 +84,10 @@ pub struct RootConfig {
|
|||||||
/// Application secrets
|
/// Application secrets
|
||||||
pub secrets: SecretsConfig,
|
pub secrets: SecretsConfig,
|
||||||
|
|
||||||
|
/// Configuration related to user passwords
|
||||||
|
#[serde(default)]
|
||||||
|
pub passwords: PasswordsConfig,
|
||||||
|
|
||||||
/// Configuration related to the homeserver
|
/// Configuration related to the homeserver
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub matrix: MatrixConfig,
|
pub matrix: MatrixConfig,
|
||||||
@ -109,6 +115,7 @@ impl ConfigurationSection<'_> for RootConfig {
|
|||||||
templates: TemplatesConfig::generate(&mut rng).await?,
|
templates: TemplatesConfig::generate(&mut rng).await?,
|
||||||
csrf: CsrfConfig::generate(&mut rng).await?,
|
csrf: CsrfConfig::generate(&mut rng).await?,
|
||||||
email: EmailConfig::generate(&mut rng).await?,
|
email: EmailConfig::generate(&mut rng).await?,
|
||||||
|
passwords: PasswordsConfig::generate(&mut rng).await?,
|
||||||
secrets: SecretsConfig::generate(&mut rng).await?,
|
secrets: SecretsConfig::generate(&mut rng).await?,
|
||||||
matrix: MatrixConfig::generate(&mut rng).await?,
|
matrix: MatrixConfig::generate(&mut rng).await?,
|
||||||
policy: PolicyConfig::generate(&mut rng).await?,
|
policy: PolicyConfig::generate(&mut rng).await?,
|
||||||
@ -122,6 +129,7 @@ impl ConfigurationSection<'_> for RootConfig {
|
|||||||
database: DatabaseConfig::test(),
|
database: DatabaseConfig::test(),
|
||||||
telemetry: TelemetryConfig::test(),
|
telemetry: TelemetryConfig::test(),
|
||||||
templates: TemplatesConfig::test(),
|
templates: TemplatesConfig::test(),
|
||||||
|
passwords: PasswordsConfig::test(),
|
||||||
csrf: CsrfConfig::test(),
|
csrf: CsrfConfig::test(),
|
||||||
email: EmailConfig::test(),
|
email: EmailConfig::test(),
|
||||||
secrets: SecretsConfig::test(),
|
secrets: SecretsConfig::test(),
|
||||||
|
@ -23,7 +23,7 @@ use mas_router::UrlBuilder;
|
|||||||
use mas_templates::Templates;
|
use mas_templates::Templates;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
|
||||||
use crate::MatrixHomeserver;
|
use crate::{passwords::PasswordManager, MatrixHomeserver};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
@ -37,6 +37,7 @@ pub struct AppState {
|
|||||||
pub policy_factory: Arc<PolicyFactory>,
|
pub policy_factory: Arc<PolicyFactory>,
|
||||||
pub graphql_schema: mas_graphql::Schema,
|
pub graphql_schema: mas_graphql::Schema,
|
||||||
pub http_client_factory: HttpClientFactory,
|
pub http_client_factory: HttpClientFactory,
|
||||||
|
pub password_manager: PasswordManager,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromRef<AppState> for PgPool {
|
impl FromRef<AppState> for PgPool {
|
||||||
@ -92,8 +93,15 @@ impl FromRef<AppState> for Arc<PolicyFactory> {
|
|||||||
input.policy_factory.clone()
|
input.policy_factory.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromRef<AppState> for HttpClientFactory {
|
impl FromRef<AppState> for HttpClientFactory {
|
||||||
fn from_ref(input: &AppState) -> Self {
|
fn from_ref(input: &AppState) -> Self {
|
||||||
input.http_client_factory.clone()
|
input.http_client_factory.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromRef<AppState> for PasswordManager {
|
||||||
|
fn from_ref(input: &AppState) -> Self {
|
||||||
|
input.password_manager.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -21,7 +21,7 @@ use pbkdf2::Pbkdf2;
|
|||||||
use rand::{CryptoRng, Rng, RngCore, SeedableRng};
|
use rand::{CryptoRng, Rng, RngCore, SeedableRng};
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|
||||||
pub type SchemeVersion = u32;
|
pub type SchemeVersion = u16;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct PasswordManager {
|
pub struct PasswordManager {
|
||||||
|
@ -128,6 +128,22 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"passwords": {
|
||||||
|
"description": "Configuration related to user passwords",
|
||||||
|
"default": {
|
||||||
|
"schemes": [
|
||||||
|
{
|
||||||
|
"algorithm": "argon2id",
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/PasswordsConfig"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"policy": {
|
"policy": {
|
||||||
"description": "Configuration related to the OPA policies",
|
"description": "Configuration related to the OPA policies",
|
||||||
"default": {
|
"default": {
|
||||||
@ -647,6 +663,74 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"HashingScheme": {
|
||||||
|
"description": "A hashing algorithm",
|
||||||
|
"type": "object",
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"description": "bcrypt",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"algorithm"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"algorithm": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"bcrypt"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"cost": {
|
||||||
|
"description": "Hashing cost",
|
||||||
|
"default": 12,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32",
|
||||||
|
"minimum": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "argon2id",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"algorithm"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"algorithm": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"argon2id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "PBKDF2",
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"algorithm"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"algorithm": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"pbkdf2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"required": [
|
||||||
|
"version"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"version": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint16",
|
||||||
|
"minimum": 0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"HttpConfig": {
|
"HttpConfig": {
|
||||||
"description": "Configuration related to the web server",
|
"description": "Configuration related to the web server",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -1209,6 +1293,24 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"PasswordsConfig": {
|
||||||
|
"description": "User password hashing config",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"schemes": {
|
||||||
|
"default": [
|
||||||
|
{
|
||||||
|
"algorithm": "argon2id",
|
||||||
|
"version": 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/HashingScheme"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"PolicyConfig": {
|
"PolicyConfig": {
|
||||||
"description": "Application secrets",
|
"description": "Application secrets",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
|
Reference in New Issue
Block a user