247 lines
8.0 KiB
Rust
247 lines
8.0 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
|
*/
|
|
|
|
use super::server::tls::{build_self_signed_cert, parse_certificates};
|
|
use crate::{
|
|
CacheSwap, Caches, Data, DavResource, DavResources, MailboxCache, MessageStoreCache,
|
|
MessageUidCache, TlsConnectors,
|
|
auth::{AccessToken, roles::RolePermissions},
|
|
config::{
|
|
smtp::resolver::{Policy, Tlsa},
|
|
spamfilter::SpamClassifier,
|
|
},
|
|
listener::blocked::BlockedIps,
|
|
manager::webadmin::WebAdminManager,
|
|
};
|
|
use ahash::{AHashMap, AHashSet};
|
|
use arc_swap::ArcSwap;
|
|
use mail_auth::{MX, Parameters, Txt};
|
|
use mail_send::smtp::tls::build_tls_connector;
|
|
use parking_lot::RwLock;
|
|
use std::{
|
|
net::{IpAddr, Ipv4Addr, Ipv6Addr},
|
|
sync::Arc,
|
|
};
|
|
use utils::{
|
|
cache::{Cache, CacheWithTtl},
|
|
config::Config,
|
|
snowflake::SnowflakeIdGenerator,
|
|
};
|
|
|
|
impl Data {
|
|
pub fn parse(config: &mut Config) -> Self {
|
|
// Parse certificates
|
|
let mut certificates = AHashMap::new();
|
|
let mut subject_names = AHashSet::new();
|
|
parse_certificates(config, &mut certificates, &mut subject_names);
|
|
if subject_names.is_empty() {
|
|
subject_names.insert("localhost".to_string());
|
|
}
|
|
|
|
// Build and test snowflake id generator
|
|
let node_id = config
|
|
.property::<u64>("cluster.node-id")
|
|
.unwrap_or_else(store::rand::random);
|
|
let id_generator = SnowflakeIdGenerator::with_node_id(node_id);
|
|
if !id_generator.is_valid() {
|
|
panic!("Invalid system time, panicking to avoid data corruption");
|
|
}
|
|
|
|
Data {
|
|
spam_classifier: ArcSwap::from_pointee(SpamClassifier::default()),
|
|
tls_certificates: ArcSwap::from_pointee(certificates),
|
|
tls_self_signed_cert: build_self_signed_cert(
|
|
subject_names.into_iter().collect::<Vec<_>>(),
|
|
)
|
|
.or_else(|err| {
|
|
config.new_build_error("certificate.self-signed", err);
|
|
build_self_signed_cert(vec!["localhost".to_string()])
|
|
})
|
|
.ok()
|
|
.map(Arc::new),
|
|
blocked_ips: RwLock::new(BlockedIps::parse(config).blocked_ip_addresses),
|
|
jmap_id_gen: id_generator.clone(),
|
|
queue_id_gen: id_generator.clone(),
|
|
span_id_gen: id_generator,
|
|
queue_status: true.into(),
|
|
webadmin: config
|
|
.value("webadmin.path")
|
|
.map(|path| WebAdminManager::new(path.into()))
|
|
.unwrap_or_default(),
|
|
logos: Default::default(),
|
|
smtp_connectors: TlsConnectors::default(),
|
|
asn_geo_data: Default::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Caches {
|
|
pub fn parse(config: &mut Config) -> Self {
|
|
const MB_50: u64 = 50 * 1024 * 1024;
|
|
const MB_10: u64 = 10 * 1024 * 1024;
|
|
const MB_5: u64 = 5 * 1024 * 1024;
|
|
const MB_1: u64 = 1024 * 1024;
|
|
|
|
Caches {
|
|
access_tokens: Cache::from_config(
|
|
config,
|
|
"access-token",
|
|
MB_10,
|
|
(std::mem::size_of::<AccessToken>() + 255) as u64,
|
|
),
|
|
http_auth: Cache::from_config(
|
|
config,
|
|
"http-auth",
|
|
MB_1,
|
|
(50 + std::mem::size_of::<u32>()) as u64,
|
|
),
|
|
permissions: Cache::from_config(
|
|
config,
|
|
"permission",
|
|
MB_5,
|
|
std::mem::size_of::<RolePermissions>() as u64,
|
|
),
|
|
messages: Cache::from_config(
|
|
config,
|
|
"message",
|
|
MB_50,
|
|
(std::mem::size_of::<u32>()
|
|
+ std::mem::size_of::<CacheSwap<MessageStoreCache>>()
|
|
+ (1024 * std::mem::size_of::<MessageUidCache>())
|
|
+ (15 * (std::mem::size_of::<MailboxCache>() + 60))) as u64,
|
|
),
|
|
files: Cache::from_config(
|
|
config,
|
|
"files",
|
|
MB_10,
|
|
(std::mem::size_of::<DavResources>() + (500 * std::mem::size_of::<DavResource>()))
|
|
as u64,
|
|
),
|
|
events: Cache::from_config(
|
|
config,
|
|
"events",
|
|
MB_10,
|
|
(std::mem::size_of::<DavResources>() + (500 * std::mem::size_of::<DavResource>()))
|
|
as u64,
|
|
),
|
|
contacts: Cache::from_config(
|
|
config,
|
|
"contacts",
|
|
MB_10,
|
|
(std::mem::size_of::<DavResources>() + (500 * std::mem::size_of::<DavResource>()))
|
|
as u64,
|
|
),
|
|
scheduling: Cache::from_config(
|
|
config,
|
|
"scheduling",
|
|
MB_1,
|
|
(std::mem::size_of::<DavResources>() + (500 * std::mem::size_of::<DavResource>()))
|
|
as u64,
|
|
),
|
|
dns_txt: CacheWithTtl::from_config(
|
|
config,
|
|
"dns.txt",
|
|
MB_5,
|
|
(std::mem::size_of::<Txt>() + 255) as u64,
|
|
),
|
|
dns_mx: CacheWithTtl::from_config(
|
|
config,
|
|
"dns.mx",
|
|
MB_5,
|
|
((std::mem::size_of::<MX>() + 255) * 2) as u64,
|
|
),
|
|
dns_ptr: CacheWithTtl::from_config(
|
|
config,
|
|
"dns.ptr",
|
|
MB_1,
|
|
(std::mem::size_of::<IpAddr>() + 255) as u64,
|
|
),
|
|
dns_ipv4: CacheWithTtl::from_config(
|
|
config,
|
|
"dns.ipv4",
|
|
MB_5,
|
|
((std::mem::size_of::<Ipv4Addr>() + 255) * 2) as u64,
|
|
),
|
|
dns_ipv6: CacheWithTtl::from_config(
|
|
config,
|
|
"dns.ipv6",
|
|
MB_5,
|
|
((std::mem::size_of::<Ipv6Addr>() + 255) * 2) as u64,
|
|
),
|
|
dns_tlsa: CacheWithTtl::from_config(
|
|
config,
|
|
"dns.tlsa",
|
|
MB_1,
|
|
(std::mem::size_of::<Tlsa>() + 255) as u64,
|
|
),
|
|
dbs_mta_sts: CacheWithTtl::from_config(
|
|
config,
|
|
"dns.mta-sts",
|
|
MB_1,
|
|
(std::mem::size_of::<Policy>() + 255) as u64,
|
|
),
|
|
dns_rbl: CacheWithTtl::from_config(
|
|
config,
|
|
"dns.rbl",
|
|
MB_5,
|
|
((std::mem::size_of::<Ipv4Addr>() + 255) * 2) as u64,
|
|
),
|
|
}
|
|
}
|
|
|
|
#[allow(clippy::type_complexity)]
|
|
#[inline(always)]
|
|
pub fn build_auth_parameters<T>(
|
|
&self,
|
|
params: T,
|
|
) -> Parameters<
|
|
'_,
|
|
T,
|
|
CacheWithTtl<String, Txt>,
|
|
CacheWithTtl<String, Arc<Vec<MX>>>,
|
|
CacheWithTtl<String, Arc<Vec<Ipv4Addr>>>,
|
|
CacheWithTtl<String, Arc<Vec<Ipv6Addr>>>,
|
|
CacheWithTtl<IpAddr, Arc<Vec<String>>>,
|
|
> {
|
|
Parameters {
|
|
params,
|
|
cache_txt: Some(&self.dns_txt),
|
|
cache_mx: Some(&self.dns_mx),
|
|
cache_ptr: Some(&self.dns_ptr),
|
|
cache_ipv4: Some(&self.dns_ipv4),
|
|
cache_ipv6: Some(&self.dns_ipv6),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for Data {
|
|
fn default() -> Self {
|
|
Self {
|
|
spam_classifier: Default::default(),
|
|
tls_certificates: Default::default(),
|
|
tls_self_signed_cert: Default::default(),
|
|
blocked_ips: Default::default(),
|
|
jmap_id_gen: Default::default(),
|
|
queue_id_gen: Default::default(),
|
|
span_id_gen: Default::default(),
|
|
queue_status: true.into(),
|
|
webadmin: Default::default(),
|
|
logos: Default::default(),
|
|
smtp_connectors: Default::default(),
|
|
asn_geo_data: Default::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Default for TlsConnectors {
|
|
fn default() -> Self {
|
|
TlsConnectors {
|
|
pki_verify: build_tls_connector(false),
|
|
dummy_verify: build_tls_connector(true),
|
|
}
|
|
}
|
|
}
|