mirror of
https://github.com/kanidm/kanidm.git
synced 2025-05-18 15:03:54 +02:00
First step done
This commit is contained in:
parent
ad012cd6fd
commit
9b3a4ad761
server
|
@ -100,6 +100,59 @@ pub struct TlsConfiguration {
|
||||||
pub client_ca: Option<PathBuf>,
|
pub client_ca: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone, Default)]
|
||||||
|
pub enum LdapAddressInfo {
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
#[serde(rename = "proxy-v2")]
|
||||||
|
ProxyV2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LdapAddressInfo {
|
||||||
|
pub fn proxy_v2(&self) -> bool {
|
||||||
|
matches!(self, Self::ProxyV2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for LdapAddressInfo {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::None => f.write_str("none"),
|
||||||
|
Self::ProxyV2 => f.write_str("proxy-v2"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone, Default)]
|
||||||
|
pub enum HttpAddressInfo {
|
||||||
|
#[default]
|
||||||
|
None,
|
||||||
|
#[serde(rename = "x-forward-for")]
|
||||||
|
XForwardFor,
|
||||||
|
#[serde(rename = "proxy-v2")]
|
||||||
|
ProxyV2,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HttpAddressInfo {
|
||||||
|
pub fn is_x_forward_for(&self) -> bool {
|
||||||
|
matches!(self, Self::XForwardFor)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn proxy_v2(&self) -> bool {
|
||||||
|
matches!(self, Self::ProxyV2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for HttpAddressInfo {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::None => f.write_str("none"),
|
||||||
|
Self::XForwardFor => f.write_str("x-forward-for"),
|
||||||
|
Self::ProxyV2 => f.write_str("proxy-v2"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This is the Server Configuration as read from `server.toml` or environment variables.
|
/// This is the Server Configuration as read from `server.toml` or environment variables.
|
||||||
///
|
///
|
||||||
/// Fields noted as "REQUIRED" are required for the server to start, even if they show as optional due to how file parsing works.
|
/// Fields noted as "REQUIRED" are required for the server to start, even if they show as optional due to how file parsing works.
|
||||||
|
@ -217,7 +270,10 @@ pub struct ServerConfigV2 {
|
||||||
role: Option<ServerRole>,
|
role: Option<ServerRole>,
|
||||||
log_level: Option<LogLevel>,
|
log_level: Option<LogLevel>,
|
||||||
online_backup: Option<OnlineBackup>,
|
online_backup: Option<OnlineBackup>,
|
||||||
trust_x_forward_for: Option<bool>,
|
|
||||||
|
http_client_address_info: Option<HttpAddressInfo>,
|
||||||
|
ldap_client_address_info: Option<LdapAddressInfo>,
|
||||||
|
|
||||||
adminbindpath: Option<String>,
|
adminbindpath: Option<String>,
|
||||||
thread_count: Option<usize>,
|
thread_count: Option<usize>,
|
||||||
maximum_request_size_bytes: Option<usize>,
|
maximum_request_size_bytes: Option<usize>,
|
||||||
|
@ -490,7 +546,10 @@ pub struct Configuration {
|
||||||
pub db_fs_type: Option<FsType>,
|
pub db_fs_type: Option<FsType>,
|
||||||
pub db_arc_size: Option<usize>,
|
pub db_arc_size: Option<usize>,
|
||||||
pub maximum_request: usize,
|
pub maximum_request: usize,
|
||||||
pub trust_x_forward_for: bool,
|
|
||||||
|
pub http_client_address_info: HttpAddressInfo,
|
||||||
|
pub ldap_client_address_info: LdapAddressInfo,
|
||||||
|
|
||||||
pub tls_config: Option<TlsConfiguration>,
|
pub tls_config: Option<TlsConfiguration>,
|
||||||
pub integration_test_config: Option<Box<IntegrationTestConfig>>,
|
pub integration_test_config: Option<Box<IntegrationTestConfig>>,
|
||||||
pub online_backup: Option<OnlineBackup>,
|
pub online_backup: Option<OnlineBackup>,
|
||||||
|
@ -522,7 +581,8 @@ impl Configuration {
|
||||||
db_fs_type: None,
|
db_fs_type: None,
|
||||||
db_arc_size: None,
|
db_arc_size: None,
|
||||||
maximum_request: 256 * 1024, // 256k
|
maximum_request: 256 * 1024, // 256k
|
||||||
trust_x_forward_for: None,
|
http_client_address_info: HttpAddressInfo::default(),
|
||||||
|
ldap_client_address_info: LdapAddressInfo::default(),
|
||||||
tls_key: None,
|
tls_key: None,
|
||||||
tls_chain: None,
|
tls_chain: None,
|
||||||
tls_client_ca: None,
|
tls_client_ca: None,
|
||||||
|
@ -547,7 +607,8 @@ impl Configuration {
|
||||||
db_fs_type: None,
|
db_fs_type: None,
|
||||||
db_arc_size: None,
|
db_arc_size: None,
|
||||||
maximum_request: 256 * 1024, // 256k
|
maximum_request: 256 * 1024, // 256k
|
||||||
trust_x_forward_for: false,
|
http_client_address_info: HttpAddressInfo::default(),
|
||||||
|
ldap_client_address_info: LdapAddressInfo::default(),
|
||||||
tls_config: None,
|
tls_config: None,
|
||||||
integration_test_config: None,
|
integration_test_config: None,
|
||||||
online_backup: None,
|
online_backup: None,
|
||||||
|
@ -587,7 +648,17 @@ impl fmt::Display for Configuration {
|
||||||
None => write!(f, "arcsize: AUTO, "),
|
None => write!(f, "arcsize: AUTO, "),
|
||||||
}?;
|
}?;
|
||||||
write!(f, "max request size: {}b, ", self.maximum_request)?;
|
write!(f, "max request size: {}b, ", self.maximum_request)?;
|
||||||
write!(f, "trust X-Forwarded-For: {}, ", self.trust_x_forward_for)?;
|
write!(
|
||||||
|
f,
|
||||||
|
"http client address info: {}, ",
|
||||||
|
self.http_client_address_info
|
||||||
|
)?;
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"ldap client address info: {}, ",
|
||||||
|
self.ldap_client_address_info
|
||||||
|
)?;
|
||||||
|
|
||||||
write!(f, "with TLS: {}, ", self.tls_config.is_some())?;
|
write!(f, "with TLS: {}, ", self.tls_config.is_some())?;
|
||||||
match &self.online_backup {
|
match &self.online_backup {
|
||||||
Some(bck) => write!(
|
Some(bck) => write!(
|
||||||
|
@ -642,7 +713,8 @@ pub struct ConfigurationBuilder {
|
||||||
db_fs_type: Option<FsType>,
|
db_fs_type: Option<FsType>,
|
||||||
db_arc_size: Option<usize>,
|
db_arc_size: Option<usize>,
|
||||||
maximum_request: usize,
|
maximum_request: usize,
|
||||||
trust_x_forward_for: Option<bool>,
|
http_client_address_info: HttpAddressInfo,
|
||||||
|
ldap_client_address_info: LdapAddressInfo,
|
||||||
tls_key: Option<PathBuf>,
|
tls_key: Option<PathBuf>,
|
||||||
tls_chain: Option<PathBuf>,
|
tls_chain: Option<PathBuf>,
|
||||||
tls_client_ca: Option<PathBuf>,
|
tls_client_ca: Option<PathBuf>,
|
||||||
|
@ -691,8 +763,8 @@ impl ConfigurationBuilder {
|
||||||
self.db_arc_size = env_config.db_arc_size;
|
self.db_arc_size = env_config.db_arc_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if env_config.trust_x_forward_for.is_some() {
|
if env_config.trust_x_forward_for == Some(true) {
|
||||||
self.trust_x_forward_for = env_config.trust_x_forward_for;
|
self.http_client_address_info = HttpAddressInfo::XForwardFor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if env_config.tls_key.is_some() {
|
if env_config.tls_key.is_some() {
|
||||||
|
@ -813,8 +885,8 @@ impl ConfigurationBuilder {
|
||||||
self.db_arc_size = config.db_arc_size;
|
self.db_arc_size = config.db_arc_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.trust_x_forward_for.is_some() {
|
if config.trust_x_forward_for == Some(true) {
|
||||||
self.trust_x_forward_for = config.trust_x_forward_for;
|
self.http_client_address_info = HttpAddressInfo::XForwardFor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.online_backup.is_some() {
|
if config.online_backup.is_some() {
|
||||||
|
@ -893,8 +965,12 @@ impl ConfigurationBuilder {
|
||||||
self.db_arc_size = config.db_arc_size;
|
self.db_arc_size = config.db_arc_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.trust_x_forward_for.is_some() {
|
if let Some(http_client_address_info) = config.http_client_address_info {
|
||||||
self.trust_x_forward_for = config.trust_x_forward_for;
|
self.http_client_address_info = http_client_address_info
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ldap_client_address_info) = config.ldap_client_address_info {
|
||||||
|
self.ldap_client_address_info = ldap_client_address_info
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.online_backup.is_some() {
|
if config.online_backup.is_some() {
|
||||||
|
@ -930,7 +1006,8 @@ impl ConfigurationBuilder {
|
||||||
db_fs_type,
|
db_fs_type,
|
||||||
db_arc_size,
|
db_arc_size,
|
||||||
maximum_request,
|
maximum_request,
|
||||||
trust_x_forward_for,
|
http_client_address_info,
|
||||||
|
ldap_client_address_info,
|
||||||
tls_key,
|
tls_key,
|
||||||
tls_chain,
|
tls_chain,
|
||||||
tls_client_ca,
|
tls_client_ca,
|
||||||
|
@ -986,7 +1063,6 @@ impl ConfigurationBuilder {
|
||||||
let adminbindpath =
|
let adminbindpath =
|
||||||
adminbindpath.unwrap_or(env!("KANIDM_SERVER_ADMIN_BIND_PATH").to_string());
|
adminbindpath.unwrap_or(env!("KANIDM_SERVER_ADMIN_BIND_PATH").to_string());
|
||||||
let address = bindaddress.unwrap_or(DEFAULT_SERVER_ADDRESS.to_string());
|
let address = bindaddress.unwrap_or(DEFAULT_SERVER_ADDRESS.to_string());
|
||||||
let trust_x_forward_for = trust_x_forward_for.unwrap_or_default();
|
|
||||||
let output_mode = output_mode.unwrap_or_default();
|
let output_mode = output_mode.unwrap_or_default();
|
||||||
let role = role.unwrap_or(ServerRole::WriteReplica);
|
let role = role.unwrap_or(ServerRole::WriteReplica);
|
||||||
let log_level = log_level.unwrap_or_default();
|
let log_level = log_level.unwrap_or_default();
|
||||||
|
@ -1000,7 +1076,8 @@ impl ConfigurationBuilder {
|
||||||
db_fs_type,
|
db_fs_type,
|
||||||
db_arc_size,
|
db_arc_size,
|
||||||
maximum_request,
|
maximum_request,
|
||||||
trust_x_forward_for,
|
http_client_address_info,
|
||||||
|
ldap_client_address_info,
|
||||||
tls_config,
|
tls_config,
|
||||||
online_backup,
|
online_backup,
|
||||||
domain,
|
domain,
|
||||||
|
|
|
@ -211,7 +211,7 @@ pub async fn create_https_server(
|
||||||
error!(?err, "Unable to generate content security policy");
|
error!(?err, "Unable to generate content security policy");
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let trust_x_forward_for = config.trust_x_forward_for;
|
let trust_x_forward_for = config.http_client_address_info.is_x_forward_for();
|
||||||
|
|
||||||
let origin = Url::parse(&config.origin)
|
let origin = Url::parse(&config.origin)
|
||||||
// Should be impossible!
|
// Should be impossible!
|
||||||
|
|
|
@ -10,7 +10,7 @@ const ALLOWED_ATTRIBUTES: &[&str] = &[
|
||||||
"threads",
|
"threads",
|
||||||
"db_path",
|
"db_path",
|
||||||
"maximum_request",
|
"maximum_request",
|
||||||
"trust_x_forward_for",
|
"http_client_address_info",
|
||||||
"role",
|
"role",
|
||||||
"output_mode",
|
"output_mode",
|
||||||
"log_level",
|
"log_level",
|
||||||
|
|
|
@ -5,12 +5,13 @@ use std::{
|
||||||
|
|
||||||
use kanidm_client::KanidmClient;
|
use kanidm_client::KanidmClient;
|
||||||
use kanidm_proto::constants::X_FORWARDED_FOR;
|
use kanidm_proto::constants::X_FORWARDED_FOR;
|
||||||
|
use kanidmd_core::config::HttpAddressInfo;
|
||||||
|
|
||||||
const DEFAULT_IP_ADDRESS: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
|
const DEFAULT_IP_ADDRESS: IpAddr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
|
||||||
|
|
||||||
// *test where we don't trust the x-forwarded-for header
|
// *test where we don't trust the x-forwarded-for header
|
||||||
|
|
||||||
#[kanidmd_testkit::test(trust_x_forward_for = false)]
|
#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::None)]
|
||||||
async fn dont_trust_xff_send_header(rsclient: &KanidmClient) {
|
async fn dont_trust_xff_send_header(rsclient: &KanidmClient) {
|
||||||
let client = rsclient.client();
|
let client = rsclient.client();
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ async fn dont_trust_xff_send_header(rsclient: &KanidmClient) {
|
||||||
assert_eq!(ip_res, DEFAULT_IP_ADDRESS);
|
assert_eq!(ip_res, DEFAULT_IP_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kanidmd_testkit::test(trust_x_forward_for = false)]
|
#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::None)]
|
||||||
async fn dont_trust_xff_dont_send_header(rsclient: &KanidmClient) {
|
async fn dont_trust_xff_dont_send_header(rsclient: &KanidmClient) {
|
||||||
let client = rsclient.client();
|
let client = rsclient.client();
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ async fn dont_trust_xff_dont_send_header(rsclient: &KanidmClient) {
|
||||||
|
|
||||||
// *test where we trust the x-forwarded-for header
|
// *test where we trust the x-forwarded-for header
|
||||||
|
|
||||||
#[kanidmd_testkit::test(trust_x_forward_for = true)]
|
#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor)]
|
||||||
async fn trust_xff_send_invalid_header_single_value(rsclient: &KanidmClient) {
|
async fn trust_xff_send_invalid_header_single_value(rsclient: &KanidmClient) {
|
||||||
let client = rsclient.client();
|
let client = rsclient.client();
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ async fn trust_xff_send_invalid_header_single_value(rsclient: &KanidmClient) {
|
||||||
// TODO: Right now we reject the request only if the leftmost address is invalid. In the future that could change so we could also have a test
|
// TODO: Right now we reject the request only if the leftmost address is invalid. In the future that could change so we could also have a test
|
||||||
// with a valid leftmost address and an invalid address later in the list. Right now it wouldn't work.
|
// with a valid leftmost address and an invalid address later in the list. Right now it wouldn't work.
|
||||||
//
|
//
|
||||||
#[kanidmd_testkit::test(trust_x_forward_for = true)]
|
#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor)]
|
||||||
async fn trust_xff_send_invalid_header_multiple_values(rsclient: &KanidmClient) {
|
async fn trust_xff_send_invalid_header_multiple_values(rsclient: &KanidmClient) {
|
||||||
let client = rsclient.client();
|
let client = rsclient.client();
|
||||||
|
|
||||||
|
@ -94,7 +95,7 @@ async fn trust_xff_send_invalid_header_multiple_values(rsclient: &KanidmClient)
|
||||||
assert_eq!(res.status(), 400);
|
assert_eq!(res.status(), 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kanidmd_testkit::test(trust_x_forward_for = true)]
|
#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor)]
|
||||||
async fn trust_xff_send_valid_header_single_ipv4_address(rsclient: &KanidmClient) {
|
async fn trust_xff_send_valid_header_single_ipv4_address(rsclient: &KanidmClient) {
|
||||||
let ip_addr = "2001:db8:85a3:8d3:1319:8a2e:370:7348";
|
let ip_addr = "2001:db8:85a3:8d3:1319:8a2e:370:7348";
|
||||||
|
|
||||||
|
@ -114,7 +115,7 @@ async fn trust_xff_send_valid_header_single_ipv4_address(rsclient: &KanidmClient
|
||||||
assert_eq!(ip_res, IpAddr::from_str(ip_addr).unwrap());
|
assert_eq!(ip_res, IpAddr::from_str(ip_addr).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kanidmd_testkit::test(trust_x_forward_for = true)]
|
#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor)]
|
||||||
async fn trust_xff_send_valid_header_single_ipv6_address(rsclient: &KanidmClient) {
|
async fn trust_xff_send_valid_header_single_ipv6_address(rsclient: &KanidmClient) {
|
||||||
let ip_addr = "203.0.113.195";
|
let ip_addr = "203.0.113.195";
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ async fn trust_xff_send_valid_header_single_ipv6_address(rsclient: &KanidmClient
|
||||||
assert_eq!(ip_res, IpAddr::from_str(ip_addr).unwrap());
|
assert_eq!(ip_res, IpAddr::from_str(ip_addr).unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kanidmd_testkit::test(trust_x_forward_for = true)]
|
#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor)]
|
||||||
async fn trust_xff_send_valid_header_multiple_address(rsclient: &KanidmClient) {
|
async fn trust_xff_send_valid_header_multiple_address(rsclient: &KanidmClient) {
|
||||||
let first_ip_addr = "203.0.113.195, 2001:db8:85a3:8d3:1319:8a2e:370:7348";
|
let first_ip_addr = "203.0.113.195, 2001:db8:85a3:8d3:1319:8a2e:370:7348";
|
||||||
|
|
||||||
|
@ -175,7 +176,7 @@ async fn trust_xff_send_valid_header_multiple_address(rsclient: &KanidmClient) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[kanidmd_testkit::test(trust_x_forward_for = true)]
|
#[kanidmd_testkit::test(http_client_address_info = HttpAddressInfo::XForwardFor)]
|
||||||
async fn trust_xff_dont_send_header(rsclient: &KanidmClient) {
|
async fn trust_xff_dont_send_header(rsclient: &KanidmClient) {
|
||||||
let client = rsclient.client();
|
let client = rsclient.client();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue