Upstream commit: 3f657330c0f49a015a3a372fb59669b5cccbca6d Enterprise-only files removed or emptied: 63 Enterprise-only snippets removed: 118 in 50 files Dangling module declarations removed: 5 Edits turning enterprise off: 25 Third-party code: 14 files, 0 not in THIRD-PARTY.md Renamed identifiers: 67 in 19 files Verification: clean The same Enterprise footprint as v0.16.24. The build check is clean apart from the expected errors in the rebuilt-feature tests. A bug-fix release: DKIM rotation, IMAP failed-login answers, DNSBL multi-code scoring and negative TTLs, Pyzor on short messages, queue quotas with an empty match, RocksDB info-log rotation, and Autodiscover schema handling.
147 lines
4.5 KiB
Rust
147 lines
4.5 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <[email protected]>
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
|
*/
|
|
|
|
use common::{
|
|
Server,
|
|
config::{mailstore::spamfilter::IpResolver, smtp::resolver::Tlsa},
|
|
};
|
|
use mail_auth::{DnssecStatus, MX, RecordSet, Txt, common::resolver::ToFqdn};
|
|
use std::{
|
|
net::{IpAddr, Ipv4Addr, Ipv6Addr},
|
|
sync::Arc,
|
|
};
|
|
|
|
pub trait DnsCache {
|
|
fn txt_add(&self, name: impl ToFqdn, value: impl Into<Txt>, valid_until: std::time::Instant);
|
|
fn ipv4_add(&self, name: impl ToFqdn, value: Vec<Ipv4Addr>, valid_until: std::time::Instant);
|
|
fn ipv6_add(&self, name: impl ToFqdn, value: Vec<Ipv6Addr>, valid_until: std::time::Instant);
|
|
fn ipv4_add_dnssec(
|
|
&self,
|
|
name: impl ToFqdn,
|
|
value: Vec<Ipv4Addr>,
|
|
dnssec_status: DnssecStatus,
|
|
valid_until: std::time::Instant,
|
|
);
|
|
fn ipv6_add_dnssec(
|
|
&self,
|
|
name: impl ToFqdn,
|
|
value: Vec<Ipv6Addr>,
|
|
dnssec_status: DnssecStatus,
|
|
valid_until: std::time::Instant,
|
|
);
|
|
fn dnsbl_add(&self, name: &str, value: Vec<Ipv4Addr>, valid_until: std::time::Instant);
|
|
fn ptr_add(&self, name: IpAddr, value: Vec<String>, valid_until: std::time::Instant);
|
|
fn mx_add(
|
|
&self,
|
|
name: impl ToFqdn,
|
|
value: Vec<MX>,
|
|
dnssec_status: DnssecStatus,
|
|
valid_until: std::time::Instant,
|
|
);
|
|
fn tlsa_add(&self, name: impl ToFqdn, value: Arc<Tlsa>, valid_until: std::time::Instant);
|
|
}
|
|
|
|
impl DnsCache for Server {
|
|
fn txt_add(&self, name: impl ToFqdn, value: impl Into<Txt>, valid_until: std::time::Instant) {
|
|
self.inner.cache.dns_txt.insert_with_expiry(
|
|
name.to_fqdn().into_owned().into_boxed_str(),
|
|
value.into(),
|
|
valid_until,
|
|
);
|
|
}
|
|
|
|
fn ipv4_add(&self, name: impl ToFqdn, value: Vec<Ipv4Addr>, valid_until: std::time::Instant) {
|
|
self.ipv4_add_dnssec(name, value, DnssecStatus::Secure, valid_until);
|
|
}
|
|
|
|
fn ipv4_add_dnssec(
|
|
&self,
|
|
name: impl ToFqdn,
|
|
value: Vec<Ipv4Addr>,
|
|
dnssec_status: DnssecStatus,
|
|
valid_until: std::time::Instant,
|
|
) {
|
|
self.inner.cache.dns_ipv4.insert_with_expiry(
|
|
name.to_fqdn().into_owned().into_boxed_str(),
|
|
RecordSet {
|
|
rrset: Arc::from(value),
|
|
dnssec_status,
|
|
},
|
|
valid_until,
|
|
);
|
|
}
|
|
|
|
fn dnsbl_add(&self, name: &str, value: Vec<Ipv4Addr>, valid_until: std::time::Instant) {
|
|
self.inner.cache.dns_rbl.insert_with_expiry(
|
|
name.into(),
|
|
Some(
|
|
value
|
|
.into_iter()
|
|
.map(|ip| IpResolver::new(ip.into()))
|
|
.collect(),
|
|
),
|
|
valid_until,
|
|
);
|
|
}
|
|
|
|
fn ipv6_add(&self, name: impl ToFqdn, value: Vec<Ipv6Addr>, valid_until: std::time::Instant) {
|
|
self.ipv6_add_dnssec(name, value, DnssecStatus::Secure, valid_until);
|
|
}
|
|
|
|
fn ipv6_add_dnssec(
|
|
&self,
|
|
name: impl ToFqdn,
|
|
value: Vec<Ipv6Addr>,
|
|
dnssec_status: DnssecStatus,
|
|
valid_until: std::time::Instant,
|
|
) {
|
|
self.inner.cache.dns_ipv6.insert_with_expiry(
|
|
name.to_fqdn().into_owned().into_boxed_str(),
|
|
RecordSet {
|
|
rrset: Arc::from(value),
|
|
dnssec_status,
|
|
},
|
|
valid_until,
|
|
);
|
|
}
|
|
|
|
fn ptr_add(&self, name: IpAddr, value: Vec<String>, valid_until: std::time::Instant) {
|
|
self.inner.cache.dns_ptr.insert_with_expiry(
|
|
name,
|
|
RecordSet {
|
|
rrset: Arc::from(value.into_iter().map(Into::into).collect::<Vec<_>>()),
|
|
dnssec_status: DnssecStatus::Indeterminate,
|
|
},
|
|
valid_until,
|
|
);
|
|
}
|
|
|
|
fn mx_add(
|
|
&self,
|
|
name: impl ToFqdn,
|
|
value: Vec<MX>,
|
|
dnssec_status: DnssecStatus,
|
|
valid_until: std::time::Instant,
|
|
) {
|
|
self.inner.cache.dns_mx.insert_with_expiry(
|
|
name.to_fqdn().into_owned().into_boxed_str(),
|
|
RecordSet {
|
|
rrset: Arc::from(value),
|
|
dnssec_status,
|
|
},
|
|
valid_until,
|
|
);
|
|
}
|
|
|
|
fn tlsa_add(&self, name: impl ToFqdn, value: Arc<Tlsa>, valid_until: std::time::Instant) {
|
|
self.inner.cache.dns_tlsa.insert_with_expiry(
|
|
name.to_fqdn().into_owned().into_boxed_str(),
|
|
value,
|
|
valid_until,
|
|
);
|
|
}
|
|
}
|