Bump to mail-auth 0.11

This commit is contained in:
Maurus Decimus
2026-06-30 11:53:55 +02:00
parent 5f58fdb92b
commit e3c6f95bfd
35 changed files with 992 additions and 138 deletions

View File

@@ -18,7 +18,7 @@ imap_proto = { path = "../imap-proto" }
sieve-rs = { version = "0.7", features = ["rkyv", "serde"] }
mail-parser = { version = "0.11", features = ["full_encoding"] }
mail-builder = { version = "0.4" }
mail-auth = { version = "0.10", features = ["generate"] }
mail-auth = { path = "/Users/me/code/mail-auth", features = ["generate", "arc"] }
smtp-proto = { version = "0.2", features = ["rkyv"] }
dns-update = { version = "0.5" }
calcard = { version = "0.3", features = ["rkyv"] }

View File

@@ -172,6 +172,9 @@ impl DkimSigner {
domain, signature, key,
)))
}
DkimSignature::Dkim2Ed25519Sha256(_) | DkimSignature::Dkim2RsaSha256(_) => {
todo!()
}
}
}
}

View File

@@ -21,10 +21,10 @@ pub async fn generate_dkim_private_key(
key_type: DkimSignatureType,
) -> trc::Result<Result<String, String>> {
let private_key = tokio::task::spawn_blocking(move || match key_type {
DkimSignatureType::Dkim1RsaSha256 => {
DkimSignatureType::Dkim1RsaSha256 | DkimSignatureType::Dkim2RsaSha256 => {
DkimKeyPair::generate_rsa(2048).map(|key| (key, "RSA PRIVATE KEY"))
}
DkimSignatureType::Dkim1Ed25519Sha256 => {
DkimSignatureType::Dkim1Ed25519Sha256 | DkimSignatureType::Dkim2Ed25519Sha256 => {
DkimKeyPair::generate_ed25519().map(|key| (key, "PRIVATE KEY"))
}
})
@@ -58,13 +58,18 @@ pub async fn generate_dkim_private_key(
}
pub async fn generate_dkim_public_key(key: &DkimSignature) -> trc::Result<String> {
match key {
DkimSignature::Dkim1RsaSha256(key) => key
.private_key
.secret()
.await
.map_err(|err| trc::DkimEvent::BuildError.reason(err))
.and_then(|pem| rsa_key_parse(pem.as_bytes()))
let is_rsa = matches!(
key,
DkimSignature::Dkim1RsaSha256(_) | DkimSignature::Dkim2RsaSha256(_)
);
let pem = key
.private_key()
.secret()
.await
.map_err(|err| trc::DkimEvent::BuildError.reason(err))?;
if is_rsa {
rsa_key_parse(pem.as_bytes())
.and_then(|pk| {
Document::from_pkcs1_der(&pk.public_key()).map_err(|err| {
trc::EventType::Dkim(trc::DkimEvent::BuildError)
@@ -75,18 +80,13 @@ pub async fn generate_dkim_public_key(key: &DkimSignature) -> trc::Result<String
.map(|pk| {
String::from_utf8(base64_encode(pk.as_bytes()).unwrap_or_default())
.unwrap_or_default()
}),
DkimSignature::Dkim1Ed25519Sha256(key) => key
.private_key
.secret()
.await
.map_err(|err| trc::DkimEvent::BuildError.reason(err))
.and_then(|pem| {
simple_pem_parse(&pem).ok_or_else(|| {
trc::EventType::Dkim(trc::DkimEvent::BuildError)
.into_err()
.details("Failed to parse private key PEM")
})
})
} else {
simple_pem_parse(&pem)
.ok_or_else(|| {
trc::EventType::Dkim(trc::DkimEvent::BuildError)
.into_err()
.details("Failed to parse private key PEM")
})
.and_then(|der| {
Ed25519Key::from_pkcs8_maybe_unchecked_der(&der).map_err(|err| {
@@ -98,7 +98,7 @@ pub async fn generate_dkim_public_key(key: &DkimSignature) -> trc::Result<String
.map(|pk| {
String::from_utf8(base64_encode(&pk.public_key()).unwrap_or_default())
.unwrap_or_default()
}),
})
}
}
@@ -113,10 +113,18 @@ pub async fn generate_dkim_dns_record(
&sign.selector,
format!("v=DKIM1; k=ed25519; h=sha256; p={public_key}"),
),
DkimSignature::Dkim2Ed25519Sha256(sign) => (
&sign.selector,
format!("v=DKIM1; k=ed25519; h=sha256; p={public_key}"),
),
DkimSignature::Dkim1RsaSha256(sign) => (
&sign.selector,
format!("v=DKIM1; k=rsa; h=sha256; p={public_key}"),
),
DkimSignature::Dkim2RsaSha256(sign) => (
&sign.selector,
format!("v=DKIM1; k=rsa; h=sha256; p={public_key}"),
),
};
Ok(NamedDnsRecord {

View File

@@ -19,7 +19,7 @@ impl Server {
.await
{
Ok(result) => Ok(result.rrset.iter().any(|mx| !mx.exchanges.is_empty())),
Err(Error::DnsRecordNotFound(_)) => Ok(false),
Err(Error::Dns(mail_auth::DnsError::RecordNotFound(_))) => Ok(false),
Err(err) => Err(err.into()),
}
}
@@ -40,7 +40,7 @@ impl Server {
.await
{
Ok(result) => Ok(!result.is_empty()),
Err(Error::DnsRecordNotFound(_)) => Ok(false),
Err(Error::Dns(mail_auth::DnsError::RecordNotFound(_))) => Ok(false),
Err(err) => Err(err.into()),
}
}
@@ -56,7 +56,7 @@ impl Server {
.await
{
Ok(result) => Ok(!result.rrset.is_empty()),
Err(Error::DnsRecordNotFound(_)) => Ok(false),
Err(Error::Dns(mail_auth::DnsError::RecordNotFound(_))) => Ok(false),
Err(err) => Err(err.into()),
}
} else {
@@ -74,7 +74,7 @@ impl Server {
.await
{
Ok(result) => Ok(!result.rrset.is_empty()),
Err(Error::DnsRecordNotFound(_)) => Ok(false),
Err(Error::Dns(mail_auth::DnsError::RecordNotFound(_))) => Ok(false),
Err(err) => Err(err.into()),
}
}
@@ -89,7 +89,7 @@ impl Server {
.await
{
Ok(result) => Ok(!result.rrset.is_empty()),
Err(Error::DnsRecordNotFound(_)) => Ok(false),
Err(Error::Dns(mail_auth::DnsError::RecordNotFound(_))) => Ok(false),
Err(err) => Err(err.into()),
}
}

View File

@@ -194,10 +194,10 @@ trait ShortError {
impl ShortError for mail_auth::Error {
fn short_error(&self) -> &'static str {
match self {
mail_auth::Error::DnsError(_) => "temp_fail",
mail_auth::Error::DnsRecordNotFound(_) => "not_found",
mail_auth::Error::Dns(mail_auth::DnsError::Resolver(_)) => "temp_fail",
mail_auth::Error::Dns(mail_auth::DnsError::RecordNotFound(_)) => "not_found",
mail_auth::Error::Io(_) => "io_error",
mail_auth::Error::InvalidRecordType => "invalid_record",
mail_auth::Error::Dns(mail_auth::DnsError::InvalidRecordType) => "invalid_record",
_ => "unknown_error",
}
}