diff --git a/src/imap/client.rs b/src/imap/client.rs index e93b273b8..2ee8165d1 100644 --- a/src/imap/client.rs +++ b/src/imap/client.rs @@ -7,7 +7,7 @@ use async_imap::{ use async_std::net::{self, TcpStream}; use super::session::Session; -use crate::login_param::{dc_build_tls, CertificateChecks}; +use crate::login_param::dc_build_tls; use super::session::SessionStream; @@ -78,10 +78,10 @@ impl Client { pub async fn connect_secure>( addr: A, domain: S, - certificate_checks: CertificateChecks, + strict_tls: bool, ) -> ImapResult { let stream = TcpStream::connect(addr).await?; - let tls = dc_build_tls(certificate_checks); + let tls = dc_build_tls(strict_tls); let tls_stream: Box = Box::new(tls.connect(domain.as_ref(), stream).await?); let mut client = ImapClient::new(tls_stream); @@ -118,16 +118,12 @@ impl Client { }) } - pub async fn secure>( - self, - domain: S, - certificate_checks: CertificateChecks, - ) -> ImapResult { + pub async fn secure>(self, domain: S, strict_tls: bool) -> ImapResult { if self.is_secure { Ok(self) } else { let Client { mut inner, .. } = self; - let tls = dc_build_tls(certificate_checks); + let tls = dc_build_tls(strict_tls); inner.run_command_and_check_ok("STARTTLS", None).await?; let stream = inner.into_inner(); diff --git a/src/imap/mod.rs b/src/imap/mod.rs index 3bf9a706a..8fb864a6c 100644 --- a/src/imap/mod.rs +++ b/src/imap/mod.rs @@ -27,6 +27,7 @@ use crate::message::{self, update_server_uid}; use crate::mimeparser; use crate::oauth2::dc_get_oauth2_access_token; use crate::param::Params; +use crate::provider::get_provider_info; use crate::{scheduler::InterruptInfo, stock::StockMessage}; mod client; @@ -149,7 +150,7 @@ struct ImapConfig { pub imap_port: u16, pub imap_user: String, pub imap_pw: String, - pub certificate_checks: CertificateChecks, + pub strict_tls: bool, pub server_flags: usize, pub selected_folder: Option, pub selected_mailbox: Option, @@ -169,7 +170,7 @@ impl Default for ImapConfig { imap_port: 0, imap_user: "".into(), imap_pw: "".into(), - certificate_checks: Default::default(), + strict_tls: false, server_flags: 0, selected_folder: None, selected_mailbox: None, @@ -228,7 +229,7 @@ impl Imap { match Client::connect_insecure((imap_server, imap_port)).await { Ok(client) => { if (server_flags & DC_LP_IMAP_SOCKET_STARTTLS) != 0 { - client.secure(imap_server, config.certificate_checks).await + client.secure(imap_server, config.strict_tls).await } else { Ok(client) } @@ -240,12 +241,8 @@ impl Imap { let imap_server: &str = config.imap_server.as_ref(); let imap_port = config.imap_port; - Client::connect_secure( - (imap_server, imap_port), - imap_server, - config.certificate_checks, - ) - .await + Client::connect_secure((imap_server, imap_port), imap_server, config.strict_tls) + .await }; let login_res = match connection_res { @@ -379,7 +376,15 @@ impl Imap { config.imap_port = imap_port; config.imap_user = imap_user.to_string(); config.imap_pw = imap_pw.to_string(); - config.certificate_checks = lp.imap_certificate_checks; + let provider = get_provider_info(&lp.addr); + config.strict_tls = match lp.imap_certificate_checks { + CertificateChecks::Automatic => { + provider.map_or(false, |provider| provider.strict_tls) + } + CertificateChecks::Strict => true, + CertificateChecks::AcceptInvalidCertificates + | CertificateChecks::AcceptInvalidCertificates2 => false, + }; config.server_flags = server_flags; } diff --git a/src/login_param.rs b/src/login_param.rs index 7309a90ad..01e66caa9 100644 --- a/src/login_param.rs +++ b/src/login_param.rs @@ -277,21 +277,15 @@ fn get_readable_flags(flags: i32) -> String { res } -pub fn dc_build_tls(certificate_checks: CertificateChecks) -> async_native_tls::TlsConnector { +pub fn dc_build_tls(strict_tls: bool) -> async_native_tls::TlsConnector { let tls_builder = async_native_tls::TlsConnector::new(); - match certificate_checks { - CertificateChecks::Automatic => { - // Same as AcceptInvalidCertificates for now. - // TODO: use provider database when it becomes available - tls_builder - .danger_accept_invalid_hostnames(true) - .danger_accept_invalid_certs(true) - } - CertificateChecks::Strict => tls_builder, - CertificateChecks::AcceptInvalidCertificates - | CertificateChecks::AcceptInvalidCertificates2 => tls_builder + + if strict_tls { + tls_builder + } else { + tls_builder .danger_accept_invalid_hostnames(true) - .danger_accept_invalid_certs(true), + .danger_accept_invalid_certs(true) } } diff --git a/src/provider/data.rs b/src/provider/data.rs index 3f5fbb058..f8abe83f4 100644 --- a/src/provider/data.rs +++ b/src/provider/data.rs @@ -19,6 +19,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "newyear.aktivix.org", port: 25, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; // aol.md: aol.com @@ -30,6 +31,7 @@ lazy_static::lazy_static! { server: vec![ ], config_defaults: None, + strict_tls: false, }; // autistici.org.md: autistici.org @@ -43,6 +45,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: SSL, hostname: "smtp.autistici.org", port: 465, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; // bluewin.ch.md: bluewin.ch @@ -56,6 +59,21 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: SSL, hostname: "smtpauths.bluewin.ch", port: 465, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, + }; + + // chello.at.md: chello.at + static ref P_CHELLO_AT: Provider = Provider { + status: Status::OK, + before_login_hint: "", + after_login_hint: "", + overview_page: "https://providers.delta.chat/chello-at", + server: vec![ + Server { protocol: IMAP, socket: SSL, hostname: "mail.mymagenta.at", port: 993, username_pattern: EMAIL }, + Server { protocol: SMTP, socket: SSL, hostname: "mail.mymagenta.at", port: 465, username_pattern: EMAIL }, + ], + config_defaults: None, + strict_tls: false, }; // comcast.md: xfinity.com, comcast.net @@ -65,7 +83,16 @@ lazy_static::lazy_static! { // - skipping provider with status OK and no special things to do // disroot.md: disroot.org - // - skipping provider with status OK and no special things to do + static ref P_DISROOT: Provider = Provider { + status: Status::OK, + before_login_hint: "", + after_login_hint: "", + overview_page: "https://providers.delta.chat/disroot", + server: vec![ + ], + config_defaults: None, + strict_tls: true, + }; // example.com.md: example.com, example.org static ref P_EXAMPLE_COM: Provider = Provider { @@ -78,6 +105,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "smtp.example.com", port: 1337, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; // fastmail.md: fastmail.com @@ -89,6 +117,19 @@ lazy_static::lazy_static! { server: vec![ ], config_defaults: None, + strict_tls: false, + }; + + // five.chat.md: five.chat + static ref P_FIVE_CHAT: Provider = Provider { + status: Status::OK, + before_login_hint: "", + after_login_hint: "", + overview_page: "https://providers.delta.chat/five-chat", + server: vec![ + ], + config_defaults: None, + strict_tls: true, }; // freenet.de.md: freenet.de @@ -102,6 +143,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "mx.freenet.de", port: 587, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; // gmail.md: gmail.com, googlemail.com @@ -115,6 +157,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: SSL, hostname: "smtp.gmail.com", port: 465, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: true, }; // gmx.net.md: gmx.net, gmx.de, gmx.at, gmx.ch, gmx.org, gmx.eu, gmx.info, gmx.biz, gmx.com @@ -129,6 +172,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "mail.gmx.net", port: 587, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; // i.ua.md: i.ua @@ -145,6 +189,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "smtp.mail.me.com", port: 587, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; // kolst.com.md: kolst.com @@ -157,7 +202,16 @@ lazy_static::lazy_static! { // - skipping provider with status OK and no special things to do // mailbox.org.md: mailbox.org, secure.mailbox.org - // - skipping provider with status OK and no special things to do + static ref P_MAILBOX_ORG: Provider = Provider { + status: Status::OK, + before_login_hint: "", + after_login_hint: "", + overview_page: "https://providers.delta.chat/mailbox-org", + server: vec![ + ], + config_defaults: None, + strict_tls: true, + }; // nauta.cu.md: nauta.cu static ref P_NAUTA_CU: Provider = Provider { @@ -178,6 +232,7 @@ lazy_static::lazy_static! { ConfigDefault { key: Config::E2eeEnabled, value: "0" }, ConfigDefault { key: Config::MediaQuality, value: "1" }, ]), + strict_tls: false, }; // outlook.com.md: hotmail.com, outlook.com, office365.com, outlook.com.tr, live.com @@ -191,9 +246,10 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "smtp-mail.outlook.com", port: 587, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; - // posteo.md: posteo.de + // posteo.md: posteo.de, posteo.af, posteo.at, posteo.be, posteo.ch, posteo.cl, posteo.co, posteo.co.uk, posteo.com.br, posteo.cr, posteo.cz, posteo.dk, posteo.ee, posteo.es, posteo.eu, posteo.fi, posteo.gl, posteo.gr, posteo.hn, posteo.hr, posteo.hu, posteo.ie, posteo.in, posteo.is, posteo.jp, posteo.la, posteo.li, posteo.lt, posteo.lu, posteo.me, posteo.mx, posteo.my, posteo.net, posteo.nl, posteo.no, posteo.nz, posteo.org, posteo.pe, posteo.pl, posteo.pm, posteo.pt, posteo.ro, posteo.ru, posteo.se, posteo.sg, posteo.si, posteo.tn, posteo.uk, posteo.us static ref P_POSTEO: Provider = Provider { status: Status::OK, before_login_hint: "", @@ -204,6 +260,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "posteo.de", port: 587, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: true, }; // protonmail.md: protonmail.com, protonmail.ch @@ -215,16 +272,35 @@ lazy_static::lazy_static! { server: vec![ ], config_defaults: None, + strict_tls: false, }; // riseup.net.md: riseup.net - // - skipping provider with status OK and no special things to do + static ref P_RISEUP_NET: Provider = Provider { + status: Status::OK, + before_login_hint: "", + after_login_hint: "", + overview_page: "https://providers.delta.chat/riseup-net", + server: vec![ + ], + config_defaults: None, + strict_tls: true, + }; // rogers.com.md: rogers.com // - skipping provider with status OK and no special things to do // systemli.org.md: systemli.org - // - skipping provider with status OK and no special things to do + static ref P_SYSTEMLI_ORG: Provider = Provider { + status: Status::OK, + before_login_hint: "", + after_login_hint: "", + overview_page: "https://providers.delta.chat/systemli-org", + server: vec![ + ], + config_defaults: None, + strict_tls: true, + }; // t-online.md: t-online.de, magenta.de static ref P_T_ONLINE: Provider = Provider { @@ -235,6 +311,7 @@ lazy_static::lazy_static! { server: vec![ ], config_defaults: None, + strict_tls: false, }; // testrun.md: testrun.org @@ -249,6 +326,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "testrun.org", port: 587, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: true, }; // tiscali.it.md: tiscali.it @@ -262,6 +340,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: SSL, hostname: "smtp.tiscali.it", port: 465, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; // ukr.net.md: ukr.net @@ -282,12 +361,13 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "smtp.web.de", port: 587, username_pattern: EMAILLOCALPART }, ], config_defaults: None, + strict_tls: false, }; // yahoo.md: yahoo.com, yahoo.de, yahoo.it, yahoo.fr, yahoo.es, yahoo.se, yahoo.co.uk, yahoo.co.nz, yahoo.com.au, yahoo.com.ar, yahoo.com.br, yahoo.com.mx, ymail.com, rocketmail.com, yahoodns.net static ref P_YAHOO: Provider = Provider { status: Status::PREPARATION, - before_login_hint: "To use Delta Chat with your Yahoo email address you have to allow \"less secure apps\" in the Yahoo webinterface.", + before_login_hint: "To use Delta Chat with your Yahoo email address you have to create an \"App-Password\" in the account security screen.", after_login_hint: "", overview_page: "https://providers.delta.chat/yahoo", server: vec![ @@ -295,6 +375,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: SSL, hostname: "smtp.mail.yahoo.com", port: 465, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; // yandex.ru.md: yandex.ru, yandex.com @@ -306,6 +387,7 @@ lazy_static::lazy_static! { server: vec![ ], config_defaults: None, + strict_tls: true, }; // ziggo.nl.md: ziggo.nl @@ -319,6 +401,7 @@ lazy_static::lazy_static! { Server { protocol: SMTP, socket: STARTTLS, hostname: "smtp.ziggo.nl", port: 587, username_pattern: EMAIL }, ], config_defaults: None, + strict_tls: false, }; pub static ref PROVIDER_DATA: HashMap<&'static str, &'static Provider> = [ @@ -326,9 +409,12 @@ lazy_static::lazy_static! { ("aol.com", &*P_AOL), ("autistici.org", &*P_AUTISTICI_ORG), ("bluewin.ch", &*P_BLUEWIN_CH), + ("chello.at", &*P_CHELLO_AT), + ("disroot.org", &*P_DISROOT), ("example.com", &*P_EXAMPLE_COM), ("example.org", &*P_EXAMPLE_COM), ("fastmail.com", &*P_FASTMAIL), + ("five.chat", &*P_FIVE_CHAT), ("freenet.de", &*P_FREENET_DE), ("gmail.com", &*P_GMAIL), ("googlemail.com", &*P_GMAIL), @@ -344,6 +430,8 @@ lazy_static::lazy_static! { ("icloud.com", &*P_ICLOUD), ("me.com", &*P_ICLOUD), ("mac.com", &*P_ICLOUD), + ("mailbox.org", &*P_MAILBOX_ORG), + ("secure.mailbox.org", &*P_MAILBOX_ORG), ("nauta.cu", &*P_NAUTA_CU), ("hotmail.com", &*P_OUTLOOK_COM), ("outlook.com", &*P_OUTLOOK_COM), @@ -351,8 +439,58 @@ lazy_static::lazy_static! { ("outlook.com.tr", &*P_OUTLOOK_COM), ("live.com", &*P_OUTLOOK_COM), ("posteo.de", &*P_POSTEO), + ("posteo.af", &*P_POSTEO), + ("posteo.at", &*P_POSTEO), + ("posteo.be", &*P_POSTEO), + ("posteo.ch", &*P_POSTEO), + ("posteo.cl", &*P_POSTEO), + ("posteo.co", &*P_POSTEO), + ("posteo.co.uk", &*P_POSTEO), + ("posteo.com.br", &*P_POSTEO), + ("posteo.cr", &*P_POSTEO), + ("posteo.cz", &*P_POSTEO), + ("posteo.dk", &*P_POSTEO), + ("posteo.ee", &*P_POSTEO), + ("posteo.es", &*P_POSTEO), + ("posteo.eu", &*P_POSTEO), + ("posteo.fi", &*P_POSTEO), + ("posteo.gl", &*P_POSTEO), + ("posteo.gr", &*P_POSTEO), + ("posteo.hn", &*P_POSTEO), + ("posteo.hr", &*P_POSTEO), + ("posteo.hu", &*P_POSTEO), + ("posteo.ie", &*P_POSTEO), + ("posteo.in", &*P_POSTEO), + ("posteo.is", &*P_POSTEO), + ("posteo.jp", &*P_POSTEO), + ("posteo.la", &*P_POSTEO), + ("posteo.li", &*P_POSTEO), + ("posteo.lt", &*P_POSTEO), + ("posteo.lu", &*P_POSTEO), + ("posteo.me", &*P_POSTEO), + ("posteo.mx", &*P_POSTEO), + ("posteo.my", &*P_POSTEO), + ("posteo.net", &*P_POSTEO), + ("posteo.nl", &*P_POSTEO), + ("posteo.no", &*P_POSTEO), + ("posteo.nz", &*P_POSTEO), + ("posteo.org", &*P_POSTEO), + ("posteo.pe", &*P_POSTEO), + ("posteo.pl", &*P_POSTEO), + ("posteo.pm", &*P_POSTEO), + ("posteo.pt", &*P_POSTEO), + ("posteo.ro", &*P_POSTEO), + ("posteo.ru", &*P_POSTEO), + ("posteo.se", &*P_POSTEO), + ("posteo.sg", &*P_POSTEO), + ("posteo.si", &*P_POSTEO), + ("posteo.tn", &*P_POSTEO), + ("posteo.uk", &*P_POSTEO), + ("posteo.us", &*P_POSTEO), ("protonmail.com", &*P_PROTONMAIL), ("protonmail.ch", &*P_PROTONMAIL), + ("riseup.net", &*P_RISEUP_NET), + ("systemli.org", &*P_SYSTEMLI_ORG), ("t-online.de", &*P_T_ONLINE), ("magenta.de", &*P_T_ONLINE), ("testrun.org", &*P_TESTRUN), diff --git a/src/provider/mod.rs b/src/provider/mod.rs index fc414968f..f74819180 100644 --- a/src/provider/mod.rs +++ b/src/provider/mod.rs @@ -72,6 +72,7 @@ pub struct Provider { pub overview_page: &'static str, pub server: Vec, pub config_defaults: Option>, + pub strict_tls: bool, } impl Provider { diff --git a/src/provider/update.py b/src/provider/update.py index eb0a9e02b..60edeb238 100755 --- a/src/provider/update.py +++ b/src/provider/update.py @@ -100,6 +100,9 @@ def process_data(data, file): config_defaults = process_config_defaults(data) + strict_tls = data.get("strict_tls", False) + strict_tls = "true" if strict_tls else "false" + provider = "" before_login_hint = cleanstr(data.get("before_login_hint", "")) after_login_hint = cleanstr(data.get("after_login_hint", "")) @@ -111,6 +114,7 @@ def process_data(data, file): provider += " overview_page: \"" + file2url(file) + "\",\n" provider += " server: vec![\n" + server + " ],\n" provider += " config_defaults: " + config_defaults + ",\n" + provider += " strict_tls: " + strict_tls + ",\n" provider += " };\n\n" else: raise TypeError("SMTP and IMAP must be specified together or left out both") @@ -121,7 +125,7 @@ def process_data(data, file): # finally, add the provider global out_all, out_domains out_all += " // " + file[file.rindex("/")+1:] + ": " + comment.strip(", ") + "\n" - if status == "OK" and before_login_hint == "" and after_login_hint == "" and server == "" and config_defaults == "None": + if status == "OK" and before_login_hint == "" and after_login_hint == "" and server == "" and config_defaults == "None" and strict_tls == "false": out_all += " // - skipping provider with status OK and no special things to do\n\n" else: out_all += provider diff --git a/src/smtp/mod.rs b/src/smtp/mod.rs index 3a4188d6a..3bde05730 100644 --- a/src/smtp/mod.rs +++ b/src/smtp/mod.rs @@ -10,8 +10,9 @@ use async_smtp::*; use crate::constants::*; use crate::context::Context; use crate::events::Event; -use crate::login_param::{dc_build_tls, LoginParam}; +use crate::login_param::{dc_build_tls, CertificateChecks, LoginParam}; use crate::oauth2::*; +use crate::provider::get_provider_info; use crate::stock::StockMessage; /// SMTP write and read timeout in seconds. @@ -113,7 +114,14 @@ impl Smtp { let domain = &lp.send_server; let port = lp.send_port as u16; - let tls_config = dc_build_tls(lp.smtp_certificate_checks); + let provider = get_provider_info(&lp.addr); + let strict_tls = match lp.smtp_certificate_checks { + CertificateChecks::Automatic => provider.map_or(false, |provider| provider.strict_tls), + CertificateChecks::Strict => true, + CertificateChecks::AcceptInvalidCertificates + | CertificateChecks::AcceptInvalidCertificates2 => false, + }; + let tls_config = dc_build_tls(strict_tls); let tls_parameters = ClientTlsParameters::new(domain.to_string(), tls_config); let (creds, mechanism) = if 0 != lp.server_flags & (DC_LP_AUTH_OAUTH2 as i32) {