mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2025-10-29 13:55:54 +08:00
Generate TLSA Records for DANE (closes #397)
This commit is contained in:
parent
ede21dbfe8
commit
3e9d0ae5d2
5 changed files with 54 additions and 0 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -2951,6 +2951,7 @@ dependencies = [
|
|||
"tracing",
|
||||
"tungstenite",
|
||||
"utils",
|
||||
"x509-parser 0.16.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
|||
|
|
@ -167,6 +167,9 @@ impl Default for QueueConfig {
|
|||
),
|
||||
invalid_certs: IfBlock::new::<()>(
|
||||
"queue.outbound.tls.allow-invalid-certs",
|
||||
#[cfg(not(feature = "test_mode"))]
|
||||
[("retry_num > 0 && last_error == 'tls'", "true")],
|
||||
#[cfg(feature = "test_mode")]
|
||||
[],
|
||||
"false",
|
||||
),
|
||||
|
|
|
|||
|
|
@ -365,6 +365,11 @@ impl TokenMap {
|
|||
V_PRIORITY,
|
||||
V_PROTOCOL,
|
||||
V_TLS,
|
||||
V_QUEUE_RETRY_NUM,
|
||||
V_QUEUE_NOTIFY_NUM,
|
||||
V_QUEUE_EXPIRES_IN,
|
||||
V_QUEUE_LAST_STATUS,
|
||||
V_QUEUE_LAST_ERROR,
|
||||
])
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ rsa = "0.9.2"
|
|||
async-trait = "0.1.68"
|
||||
lz4_flex = { version = "0.11", default-features = false }
|
||||
rev_lines = "0.3.0"
|
||||
x509-parser = "0.16.0"
|
||||
|
||||
[dev-dependencies]
|
||||
ece = "2.2"
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@ use hyper::Method;
|
|||
use jmap_proto::error::request::RequestError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use sha1::Digest;
|
||||
use store::ahash::AHashMap;
|
||||
use utils::url_params::UrlParams;
|
||||
use x509_parser::parse_x509_certificate;
|
||||
|
||||
use crate::{
|
||||
api::{
|
||||
|
|
@ -229,6 +231,48 @@ impl JMAP {
|
|||
content: format!("v=DMARC1; p=reject; rua=mailto:postmaster@{domain_name}; ruf=mailto:postmaster@{domain_name}",),
|
||||
});
|
||||
|
||||
// Add TLSA records
|
||||
for (name, key) in self.core.tls.certificates.load().iter() {
|
||||
if !name.ends_with(domain_name) {
|
||||
continue;
|
||||
}
|
||||
let cert = if let Some(cert) = key.cert.first().map(|cert| cert.as_ref()) {
|
||||
cert
|
||||
} else {
|
||||
tracing::debug!("No certificate found for domain: {}", domain_name);
|
||||
continue;
|
||||
};
|
||||
let parsed_cert = match parse_x509_certificate(cert) {
|
||||
Ok((_, parsed_cert)) => parsed_cert,
|
||||
Err(err) => {
|
||||
tracing::debug!("Failed to parse certificate: {}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let name = if !name.starts_with('.') {
|
||||
format!("_25._tcp.{name}.")
|
||||
} else {
|
||||
format!("_25._tcp.mail.{name}.")
|
||||
};
|
||||
|
||||
for (s, cert) in [cert, parsed_cert.subject_pki.raw].into_iter().enumerate() {
|
||||
for (m, hash) in [
|
||||
format!("{:x}", sha2::Sha256::digest(cert)),
|
||||
format!("{:x}", sha2::Sha512::digest(cert)),
|
||||
]
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
{
|
||||
records.push(DnsRecord {
|
||||
typ: "TLSA".to_string(),
|
||||
name: name.clone(),
|
||||
content: format!("3 {} {} {}", s, m + 1, hash),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(records)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue