From 7ec888f48a4b91b7593e0e683875dfca3c63d0ba Mon Sep 17 00:00:00 2001 From: holger krekel Date: Thu, 23 Jul 2026 08:59:59 +0200 Subject: [PATCH] remove hermes/aco-connexion special casing and simplify/address link2xt comments --- src/configure.rs | 39 +++++---------- src/context.rs | 3 +- src/imap.rs | 2 +- src/provider.rs | 125 +++++++++++++---------------------------------- src/smtp.rs | 2 +- src/transport.rs | 8 +-- 6 files changed, 55 insertions(+), 124 deletions(-) diff --git a/src/configure.rs b/src/configure.rs index bee801beb..fc45463fb 100644 --- a/src/configure.rs +++ b/src/configure.rs @@ -350,7 +350,12 @@ impl Context { }; self.set_config_internal(Config::NotifyAboutWrongPw, Some("1")) .await?; - apply_legacy_domain_config_defaults(self, ¶m.addr).await?; + if provider::legacy_settings_for_addr(¶m.addr)?.worse_media_quality + && !self.config_exists(Config::MediaQuality).await? + { + self.set_config_ex(Nosync, Config::MediaQuality, Some("1")) + .await?; + } Ok(()) } @@ -391,24 +396,6 @@ impl Context { } } -/// Applies a few select non-default config values that used to come from provider database. -async fn apply_legacy_domain_config_defaults(context: &Context, addr: &str) -> Result<()> { - let settings = provider::legacy_settings_for_addr(addr); - - if settings.disable_mdns && !context.config_exists(Config::MdnsEnabled).await? { - context - .set_config_ex(Nosync, Config::MdnsEnabled, Some("0")) - .await?; - } - - if settings.worse_media_quality && !context.config_exists(Config::MediaQuality).await? { - context - .set_config_ex(Nosync, Config::MediaQuality, Some("1")) - .await?; - } - Ok(()) -} - /// Retrieves data from autoconfig /// to transform user-entered login parameters into complete configuration. async fn get_configured_param( @@ -442,13 +429,11 @@ async fn get_configured_param( && param.smtp.security == Socket::Automatic && param.smtp.user.is_empty() { - // no advanced parameters entered by the user: do Autoconfig - // except for a few known legacy-domain overrides. - let legacy_servers = provider::legacy_settings_for_addr(¶m.addr).autoconfig_servers; - if legacy_servers.is_some() { - legacy_servers - } else { - get_autoconfig(ctx, param, ¶m_domain).await + // No advanced parameters entered by the user: + // do Autoconfig unless the domain has hard-coded legacy servers. + match provider::legacy_settings_for_addr(¶m.addr)?.autoconfig_servers { + Some(servers) => Some(servers), + None => get_autoconfig(ctx, param, ¶m_domain).await, } } else { None @@ -548,7 +533,7 @@ async fn configure(ctx: &Context, param: &EnteredLoginParam) -> Result<()> { let configured_param = get_configured_param(ctx, param).await?; let proxy_config = ProxyConfig::load(ctx).await?; - let strict_tls = configured_param.strict_tls(proxy_config.is_some()); + let strict_tls = configured_param.strict_tls(proxy_config.is_some())?; progress!(ctx, 550); diff --git a/src/context.rs b/src/context.rs index 25c70c95a..ed822448b 100644 --- a/src/context.rs +++ b/src/context.rs @@ -585,7 +585,8 @@ impl Context { if let Some(limit) = metadata_limit { return Ok(limit); } - if let Some(limit) = crate::provider::legacy_settings_for_addr(¶m.addr).max_smtp_rcpt_to + if let Some(limit) = + crate::provider::legacy_settings_for_addr(¶m.addr)?.max_smtp_rcpt_to { return Ok(limit); } diff --git a/src/imap.rs b/src/imap.rs index fdcdb1c32..15e362725 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -231,7 +231,7 @@ impl Imap { let lp = param.imap.clone(); let password = param.imap_password.clone(); let proxy_config = ProxyConfig::load(context).await?; - let strict_tls = param.strict_tls(proxy_config.is_some()); + let strict_tls = param.strict_tls(proxy_config.is_some())?; let folder = param .imap_folder .clone() diff --git a/src/provider.rs b/src/provider.rs index 7a65ac497..c142e4f38 100644 --- a/src/provider.rs +++ b/src/provider.rs @@ -1,5 +1,6 @@ //! Provider types. +use anyhow::Result; use deltachat_contact_tools::EmailAddress; use serde::{Deserialize, Serialize}; @@ -46,24 +47,8 @@ pub enum Socket { Plain = 3, } -/// Pattern used to construct login usernames from email addresses. -#[derive(Debug, PartialEq, Eq, Clone)] -#[repr(u8)] -pub enum UsernamePattern { - /// Whole email is used as username. - Email = 1, - - /// Part of address before `@` is used as username. - Emaillocalpart = 2, -} - -/// Returns true if `domain` is `suffix` itself or a subdomain of it. -fn is_exact_or_subdomain(domain: &str, suffix: &str) -> bool { - domain == suffix || domain.ends_with(&format!(".{suffix}")) -} - /// Non-default settings that used to be looked up in provider.db for a few domains. -#[derive(Debug, Clone, PartialEq, Default)] +#[derive(Debug, Default)] pub(crate) struct LegacyProviderSettings { /// Servers to use instead of autoconfig, if any. pub autoconfig_servers: Option>, @@ -74,63 +59,39 @@ pub(crate) struct LegacyProviderSettings { /// Whether to disable strict TLS certificate checks by default. pub disable_strict_tls: bool, - /// Whether to disable local network contact discovery (mDNS) by default. - pub disable_mdns: bool, - /// Whether to default to worse media quality (for slow/expensive connections). pub worse_media_quality: bool, } /// Returns hard-coded legacy settings for the domain of `addr`. -/// -/// Provider.db lookup was removed, but a handful of domains still need these overrides, -/// so they are hard-coded here instead. -pub(crate) fn legacy_settings_for_addr(addr: &str) -> LegacyProviderSettings { - let Ok(email) = EmailAddress::new(addr) else { - return LegacyProviderSettings::default(); - }; - let domain = email.domain.to_ascii_lowercase(); - - match domain.as_str() { - "nauta.cu" => LegacyProviderSettings { - autoconfig_servers: Some(vec![ - ServerParams { - protocol: Protocol::Imap, - socket: Socket::Starttls, - hostname: "imap.nauta.cu".to_string(), - port: 143, - username: String::new(), - }, - ServerParams { - protocol: Protocol::Smtp, - socket: Socket::Starttls, - hostname: "smtp.nauta.cu".to_string(), - port: 25, - username: String::new(), - }, - ]), - max_smtp_rcpt_to: Some(20), - disable_strict_tls: true, - worse_media_quality: true, - ..Default::default() - }, - _ if is_exact_or_subdomain(&domain, "hermes.radio") - || domain.ends_with(".aco-connexion.org") => - { - LegacyProviderSettings { - disable_strict_tls: true, - disable_mdns: true, - ..Default::default() - } - } - _ => LegacyProviderSettings { - autoconfig_servers: None, - max_smtp_rcpt_to: None, - disable_strict_tls: false, - disable_mdns: false, - worse_media_quality: false, - }, +pub(crate) fn legacy_settings_for_addr(addr: &str) -> Result { + if !EmailAddress::new(addr)? + .domain + .eq_ignore_ascii_case("nauta.cu") + { + return Ok(LegacyProviderSettings::default()); } + Ok(LegacyProviderSettings { + autoconfig_servers: Some(vec![ + ServerParams { + protocol: Protocol::Imap, + socket: Socket::Starttls, + hostname: "imap.nauta.cu".to_string(), + port: 143, + username: String::new(), + }, + ServerParams { + protocol: Protocol::Smtp, + socket: Socket::Starttls, + hostname: "smtp.nauta.cu".to_string(), + port: 25, + username: String::new(), + }, + ]), + max_smtp_rcpt_to: Some(20), + disable_strict_tls: true, + worse_media_quality: true, + }) } #[cfg(test)] @@ -138,8 +99,8 @@ mod tests { use super::*; #[test] - fn test_legacy_domain_overrides() { - let nauta = legacy_settings_for_addr("alice@nauta.cu"); + fn test_legacy_domain_overrides() -> Result<()> { + let nauta = legacy_settings_for_addr("alice@nauta.cu")?; assert_eq!(nauta.max_smtp_rcpt_to, Some(20)); assert!(nauta.disable_strict_tls); assert!(nauta.worse_media_quality); @@ -148,29 +109,13 @@ mod tests { assert_eq!(servers[0].hostname, "imap.nauta.cu"); assert_eq!(servers[1].hostname, "smtp.nauta.cu"); - let hermes = legacy_settings_for_addr("alice@foo.hermes.radio"); - assert!(hermes.disable_strict_tls); - assert!(hermes.disable_mdns); - // hermes.radio itself (not just its subdomains) is also a valid provider domain. - assert!(legacy_settings_for_addr("alice@hermes.radio").disable_strict_tls); - - let aco = legacy_settings_for_addr("alice@foo.aco-connexion.org"); - assert!(aco.disable_strict_tls); - assert!(aco.disable_mdns); - // Unlike hermes.radio, aco-connexion.org itself is not a valid provider domain, - // only its subdomains are (matching the original provider.db entries). - let not_aco = legacy_settings_for_addr("alice@aco-connexion.org"); - assert_eq!(not_aco.autoconfig_servers, None); - assert_eq!(not_aco.max_smtp_rcpt_to, None); - assert!(!not_aco.disable_strict_tls); - assert!(!not_aco.disable_mdns); - assert!(!not_aco.worse_media_quality); - - let unknown = legacy_settings_for_addr("alice@example.org"); + let unknown = legacy_settings_for_addr("alice@example.org")?; assert_eq!(unknown.autoconfig_servers, None); assert_eq!(unknown.max_smtp_rcpt_to, None); assert!(!unknown.disable_strict_tls); - assert!(!unknown.disable_mdns); assert!(!unknown.worse_media_quality); + + assert!(legacy_settings_for_addr("not-an-email").is_err()); + Ok(()) } } diff --git a/src/smtp.rs b/src/smtp.rs index 8a41d9d89..9c29fb7e5 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -99,7 +99,7 @@ impl Smtp { &lp.smtp_password, &proxy_config, &lp.addr, - lp.strict_tls(proxy_config.is_some()), + lp.strict_tls(proxy_config.is_some())?, ) .await } diff --git a/src/transport.rs b/src/transport.rs index 70d551510..1d4f54b35 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -461,17 +461,17 @@ impl ConfiguredLoginParam { Ok(serde_json::to_string(&json)?) } - pub(crate) fn strict_tls(&self, connected_through_proxy: bool) -> bool { + pub(crate) fn strict_tls(&self, connected_through_proxy: bool) -> Result { let disable_strict_tls = - crate::provider::legacy_settings_for_addr(&self.addr).disable_strict_tls; - match self.certificate_checks { + crate::provider::legacy_settings_for_addr(&self.addr)?.disable_strict_tls; + Ok(match self.certificate_checks { ConfiguredCertificateChecks::OldAutomatic if disable_strict_tls => false, ConfiguredCertificateChecks::OldAutomatic => connected_through_proxy, ConfiguredCertificateChecks::Automatic => !disable_strict_tls, ConfiguredCertificateChecks::Strict => true, ConfiguredCertificateChecks::AcceptInvalidCertificates | ConfiguredCertificateChecks::AcceptInvalidCertificates2 => false, - } + }) } }