From 297bc635e80c4e700b3988aa9e7d531677661077 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Sun, 29 Sep 2019 22:54:39 +0300 Subject: [PATCH 01/12] Add certificate check configuration options --- src/config.rs | 4 ++++ src/login_param.rs | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/config.rs b/src/config.rs index f39ba8538..90910c067 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,10 +19,12 @@ pub enum Config { MailUser, MailPw, MailPort, + MailCertificateChecks, SendServer, SendUser, SendPw, SendPort, + SendCertificateChecks, ServerFlags, #[strum(props(default = "INBOX"))] ImapFolder, @@ -52,10 +54,12 @@ pub enum Config { ConfiguredMailPw, ConfiguredMailPort, ConfiguredMailSecurity, + ConfiguredMailCertificateChecks, ConfiguredSendServer, ConfiguredSendUser, ConfiguredSendPw, ConfiguredSendPort, + ConfiguredSendCertificateChecks, ConfiguredServerFlags, ConfiguredSendSecurity, ConfiguredE2EEEnabled, diff --git a/src/login_param.rs b/src/login_param.rs index 87ecd3886..bc0553dff 100644 --- a/src/login_param.rs +++ b/src/login_param.rs @@ -4,6 +4,20 @@ use std::fmt; use crate::context::Context; use crate::error::Error; +#[derive(Debug, FromPrimitive)] +#[repr(i32)] +pub enum CertificateChecks { + Strict, + AcceptInvalidHostnames, + AcceptInvalidCertificates, +} + +impl Default for CertificateChecks { + fn default() -> Self { + Self::AcceptInvalidCertificates + } +} + #[derive(Default, Debug)] pub struct LoginParam { pub addr: String, @@ -11,10 +25,14 @@ pub struct LoginParam { pub mail_user: String, pub mail_pw: String, pub mail_port: i32, + /// IMAP TLS options: whether to allow invalid certificates and/or invalid hostnames + pub mail_certificate_checks: CertificateChecks, pub send_server: String, pub send_user: String, pub send_pw: String, pub send_port: i32, + /// SMTP TLS options: whether to allow invalid certificates and/or invalid hostnames + pub send_certificate_checks: CertificateChecks, pub server_flags: i32, } @@ -48,6 +66,14 @@ impl LoginParam { let key = format!("{}mail_pw", prefix); let mail_pw = sql.get_config(context, key).unwrap_or_default(); + let key = format!("{}mail_certificate_checks", prefix); + let mail_certificate_checks = + if let Some(certificate_checks) = sql.get_config_int(context, key) { + num_traits::FromPrimitive::from_i32(certificate_checks).unwrap_or_default() + } else { + Default::default() + }; + let key = format!("{}send_server", prefix); let send_server = sql.get_config(context, key).unwrap_or_default(); @@ -60,6 +86,14 @@ impl LoginParam { let key = format!("{}send_pw", prefix); let send_pw = sql.get_config(context, key).unwrap_or_default(); + let key = format!("{}send_certificate_checks", prefix); + let send_certificate_checks = + if let Some(certificate_checks) = sql.get_config_int(context, key) { + num_traits::FromPrimitive::from_i32(certificate_checks).unwrap_or_default() + } else { + Default::default() + }; + let key = format!("{}server_flags", prefix); let server_flags = sql.get_config_int(context, key).unwrap_or_default(); @@ -69,10 +103,12 @@ impl LoginParam { mail_user, mail_pw, mail_port, + mail_certificate_checks, send_server, send_user, send_pw, send_port, + send_certificate_checks, server_flags, } } From e222f49c9d7539375283a26c1c0b397edc108edc Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 30 Sep 2019 01:04:28 +0300 Subject: [PATCH 02/12] Use send_certificate_checks configuration --- src/smtp.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/smtp.rs b/src/smtp.rs index 5d8ba4654..34030f1a4 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -5,7 +5,7 @@ use crate::constants::*; use crate::context::Context; use crate::error::Error; use crate::events::Event; -use crate::login_param::LoginParam; +use crate::login_param::{CertificateChecks, LoginParam}; use crate::oauth2::*; #[derive(DebugStub)] @@ -68,13 +68,19 @@ impl Smtp { let domain = &lp.send_server; let port = lp.send_port as u16; - let tls = native_tls::TlsConnector::builder() - // see also: https://github.com/deltachat/deltachat-core-rust/issues/203 - .danger_accept_invalid_hostnames(true) - .danger_accept_invalid_certs(true) - .min_protocol_version(Some(DEFAULT_TLS_PROTOCOLS[0])) - .build() - .unwrap(); + let mut tls_builder = native_tls::TlsConnector::builder(); + let tls = match lp.send_certificate_checks { + CertificateChecks::Strict => &mut tls_builder, + CertificateChecks::AcceptInvalidHostnames => { + tls_builder.danger_accept_invalid_hostnames(true) + } + CertificateChecks::AcceptInvalidCertificates => tls_builder + .danger_accept_invalid_hostnames(true) + .danger_accept_invalid_certs(true), + } + .min_protocol_version(Some(DEFAULT_TLS_PROTOCOLS[0])) + .build() + .unwrap(); let tls_parameters = ClientTlsParameters::new(domain.to_string(), tls); From b8ca7b1591b5bfca509bdbb61a514d9180d8a1d7 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 30 Sep 2019 02:25:05 +0300 Subject: [PATCH 03/12] Add CertificateChecks::Automatic option and make it default It is the same as AcceptInvalidCertificates for now, but can be replaced with better heuristics later, such as a database of known providers or TOFU. --- src/login_param.rs | 3 ++- src/smtp.rs | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/login_param.rs b/src/login_param.rs index bc0553dff..e71cdee92 100644 --- a/src/login_param.rs +++ b/src/login_param.rs @@ -7,6 +7,7 @@ use crate::error::Error; #[derive(Debug, FromPrimitive)] #[repr(i32)] pub enum CertificateChecks { + Automatic, Strict, AcceptInvalidHostnames, AcceptInvalidCertificates, @@ -14,7 +15,7 @@ pub enum CertificateChecks { impl Default for CertificateChecks { fn default() -> Self { - Self::AcceptInvalidCertificates + Self::Automatic } } diff --git a/src/smtp.rs b/src/smtp.rs index 34030f1a4..e2a3d8d1c 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -70,6 +70,13 @@ impl Smtp { let mut tls_builder = native_tls::TlsConnector::builder(); let tls = match lp.send_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 => &mut tls_builder, CertificateChecks::AcceptInvalidHostnames => { tls_builder.danger_accept_invalid_hostnames(true) From 063d98922530fa55770c52e17befc7f067d292a0 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 30 Sep 2019 02:49:33 +0300 Subject: [PATCH 04/12] Use mail_certificate_checks configuration in imap.rs --- src/imap.rs | 37 +++++++++++++++++++++++++++++-------- src/login_param.rs | 2 +- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/imap.rs b/src/imap.rs index 9380421bd..b1552fd0f 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -11,7 +11,7 @@ use crate::dc_receive_imf::dc_receive_imf; use crate::error::Error; use crate::events::Event; use crate::job::{connect_to_inbox, job_add, Action}; -use crate::login_param::LoginParam; +use crate::login_param::{CertificateChecks, LoginParam}; use crate::message::{self, update_msg_move_state, update_server_uid}; use crate::oauth2::dc_get_oauth2_access_token; use crate::param::Params; @@ -108,14 +108,28 @@ impl Client { pub fn connect_secure>( addr: A, domain: S, + certificate_checks: CertificateChecks, ) -> imap::error::Result { let stream = net::TcpStream::connect(addr)?; - let tls = native_tls::TlsConnector::builder() - // see also: https://github.com/deltachat/deltachat-core-rust/issues/203 - .danger_accept_invalid_certs(true) - .danger_accept_invalid_hostnames(true) - .build() - .unwrap(); + let mut tls_builder = native_tls::TlsConnector::builder(); + let tls = 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 => &mut tls_builder, + CertificateChecks::AcceptInvalidHostnames => { + tls_builder.danger_accept_invalid_hostnames(true) + } + CertificateChecks::AcceptInvalidCertificates => tls_builder + .danger_accept_invalid_hostnames(true) + .danger_accept_invalid_certs(true), + } + .build() + .unwrap(); let s = stream.try_clone().expect("cloning the stream failed"); let tls_stream = native_tls::TlsConnector::connect(&tls, domain.as_ref(), s)?; @@ -321,6 +335,7 @@ struct ImapConfig { pub imap_port: u16, pub imap_user: String, pub imap_pw: String, + pub certificate_checks: CertificateChecks, pub server_flags: usize, pub selected_folder: Option, pub selected_mailbox: Option, @@ -339,6 +354,7 @@ impl Default for ImapConfig { imap_port: 0, imap_user: "".into(), imap_pw: "".into(), + certificate_checks: Default::default(), server_flags: 0, selected_folder: None, selected_mailbox: None, @@ -407,7 +423,11 @@ 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) + Client::connect_secure( + (imap_server, imap_port), + imap_server, + config.certificate_checks, + ) }; let login_res = match connection_res { @@ -534,6 +554,7 @@ 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.mail_certificate_checks; config.server_flags = server_flags; } diff --git a/src/login_param.rs b/src/login_param.rs index e71cdee92..c2cf0e09e 100644 --- a/src/login_param.rs +++ b/src/login_param.rs @@ -4,7 +4,7 @@ use std::fmt; use crate::context::Context; use crate::error::Error; -#[derive(Debug, FromPrimitive)] +#[derive(Copy, Clone, Debug, FromPrimitive)] #[repr(i32)] pub enum CertificateChecks { Automatic, From 641bd5eb15c113a0afdca1a5ae49e58cbc1db3a9 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Mon, 30 Sep 2019 09:02:12 +0300 Subject: [PATCH 05/12] Write configured_{mail,send}_certificate_checks to database --- src/login_param.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/login_param.rs b/src/login_param.rs index c2cf0e09e..e916d67f0 100644 --- a/src/login_param.rs +++ b/src/login_param.rs @@ -142,6 +142,9 @@ impl LoginParam { let key = format!("{}mail_pw", prefix); sql.set_config(context, key, Some(&self.mail_pw))?; + let key = format!("{}mail_certificate_checks", prefix); + sql.set_config_int(context, key, self.mail_certificate_checks as i32)?; + let key = format!("{}send_server", prefix); sql.set_config(context, key, Some(&self.send_server))?; @@ -154,6 +157,9 @@ impl LoginParam { let key = format!("{}send_pw", prefix); sql.set_config(context, key, Some(&self.send_pw))?; + let key = format!("{}send_certificate_checks", prefix); + sql.set_config_int(context, key, self.send_certificate_checks as i32)?; + let key = format!("{}server_flags", prefix); sql.set_config_int(context, key, self.server_flags)?; From 6343ae8161dd3448561b5c8f88eaab6038694e18 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Tue, 1 Oct 2019 13:24:45 +0300 Subject: [PATCH 06/12] Rename {mail,send}_certificate_checks into {imap,smtp}_certificate_checks --- src/config.rs | 8 ++++---- src/imap.rs | 2 +- src/login_param.rs | 24 ++++++++++++------------ src/smtp.rs | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/config.rs b/src/config.rs index 90910c067..a7ca2bed1 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,12 +19,12 @@ pub enum Config { MailUser, MailPw, MailPort, - MailCertificateChecks, + ImapCertificateChecks, SendServer, SendUser, SendPw, SendPort, - SendCertificateChecks, + SmtpCertificateChecks, ServerFlags, #[strum(props(default = "INBOX"))] ImapFolder, @@ -54,12 +54,12 @@ pub enum Config { ConfiguredMailPw, ConfiguredMailPort, ConfiguredMailSecurity, - ConfiguredMailCertificateChecks, + ConfiguredImapCertificateChecks, ConfiguredSendServer, ConfiguredSendUser, ConfiguredSendPw, ConfiguredSendPort, - ConfiguredSendCertificateChecks, + ConfiguredSmtpCertificateChecks, ConfiguredServerFlags, ConfiguredSendSecurity, ConfiguredE2EEEnabled, diff --git a/src/imap.rs b/src/imap.rs index b1552fd0f..ec6addb9b 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -554,7 +554,7 @@ 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.mail_certificate_checks; + config.certificate_checks = lp.imap_certificate_checks; config.server_flags = server_flags; } diff --git a/src/login_param.rs b/src/login_param.rs index e916d67f0..5fd13fd0f 100644 --- a/src/login_param.rs +++ b/src/login_param.rs @@ -27,13 +27,13 @@ pub struct LoginParam { pub mail_pw: String, pub mail_port: i32, /// IMAP TLS options: whether to allow invalid certificates and/or invalid hostnames - pub mail_certificate_checks: CertificateChecks, + pub imap_certificate_checks: CertificateChecks, pub send_server: String, pub send_user: String, pub send_pw: String, pub send_port: i32, /// SMTP TLS options: whether to allow invalid certificates and/or invalid hostnames - pub send_certificate_checks: CertificateChecks, + pub smtp_certificate_checks: CertificateChecks, pub server_flags: i32, } @@ -67,8 +67,8 @@ impl LoginParam { let key = format!("{}mail_pw", prefix); let mail_pw = sql.get_config(context, key).unwrap_or_default(); - let key = format!("{}mail_certificate_checks", prefix); - let mail_certificate_checks = + let key = format!("{}imap_certificate_checks", prefix); + let imap_certificate_checks = if let Some(certificate_checks) = sql.get_config_int(context, key) { num_traits::FromPrimitive::from_i32(certificate_checks).unwrap_or_default() } else { @@ -87,8 +87,8 @@ impl LoginParam { let key = format!("{}send_pw", prefix); let send_pw = sql.get_config(context, key).unwrap_or_default(); - let key = format!("{}send_certificate_checks", prefix); - let send_certificate_checks = + let key = format!("{}smtp_certificate_checks", prefix); + let smtp_certificate_checks = if let Some(certificate_checks) = sql.get_config_int(context, key) { num_traits::FromPrimitive::from_i32(certificate_checks).unwrap_or_default() } else { @@ -104,12 +104,12 @@ impl LoginParam { mail_user, mail_pw, mail_port, - mail_certificate_checks, + imap_certificate_checks, send_server, send_user, send_pw, send_port, - send_certificate_checks, + smtp_certificate_checks, server_flags, } } @@ -142,8 +142,8 @@ impl LoginParam { let key = format!("{}mail_pw", prefix); sql.set_config(context, key, Some(&self.mail_pw))?; - let key = format!("{}mail_certificate_checks", prefix); - sql.set_config_int(context, key, self.mail_certificate_checks as i32)?; + let key = format!("{}imap_certificate_checks", prefix); + sql.set_config_int(context, key, self.imap_certificate_checks as i32)?; let key = format!("{}send_server", prefix); sql.set_config(context, key, Some(&self.send_server))?; @@ -157,8 +157,8 @@ impl LoginParam { let key = format!("{}send_pw", prefix); sql.set_config(context, key, Some(&self.send_pw))?; - let key = format!("{}send_certificate_checks", prefix); - sql.set_config_int(context, key, self.send_certificate_checks as i32)?; + let key = format!("{}smtp_certificate_checks", prefix); + sql.set_config_int(context, key, self.smtp_certificate_checks as i32)?; let key = format!("{}server_flags", prefix); sql.set_config_int(context, key, self.server_flags)?; diff --git a/src/smtp.rs b/src/smtp.rs index e2a3d8d1c..6697a3941 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -69,7 +69,7 @@ impl Smtp { let port = lp.send_port as u16; let mut tls_builder = native_tls::TlsConnector::builder(); - let tls = match lp.send_certificate_checks { + let tls = match lp.smtp_certificate_checks { CertificateChecks::Automatic => { // Same as AcceptInvalidCertificates for now. // TODO: use provider database when it becomes available From 468651534e5e4b04ff4859792d75dc5b92e75209 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Wed, 2 Oct 2019 14:19:00 +0300 Subject: [PATCH 07/12] Manually specify values for CertificateChecks enum This is what we are doing in constants.rs --- src/login_param.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/login_param.rs b/src/login_param.rs index 5fd13fd0f..ff849f988 100644 --- a/src/login_param.rs +++ b/src/login_param.rs @@ -7,10 +7,10 @@ use crate::error::Error; #[derive(Copy, Clone, Debug, FromPrimitive)] #[repr(i32)] pub enum CertificateChecks { - Automatic, - Strict, - AcceptInvalidHostnames, - AcceptInvalidCertificates, + Automatic = 0, + Strict = 1, + AcceptInvalidHostnames = 2, + AcceptInvalidCertificates = 3, } impl Default for CertificateChecks { From 59df97944fe79e4c01dc9233d0a9c3285f73b979 Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Wed, 2 Oct 2019 14:35:01 +0300 Subject: [PATCH 08/12] Enable strict certificate checks for test online accounts --- python/tests/conftest.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/python/tests/conftest.py b/python/tests/conftest.py index ba537ca19..8ce4ebdfb 100644 --- a/python/tests/conftest.py +++ b/python/tests/conftest.py @@ -157,6 +157,11 @@ def acfactory(pytestconfig, tmpdir, request, session_liveconfig): self.live_count += 1 if "e2ee_enabled" not in configdict: configdict["e2ee_enabled"] = "1" + + # Enable strict certificate checks for online accounts + configdict["imap_certificate_checks"] = "1" + configdict["smtp_certificate_checks"] = "1" + tmpdb = tmpdir.join("livedb%d" % self.live_count) ac = self.make_account(tmpdb.strpath, logid="ac{}".format(self.live_count)) ac._evlogger.init_time = self.init_time From 41806f86ba73056ef40308ae7aec93fea2a5231a Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Thu, 3 Oct 2019 01:14:25 +0300 Subject: [PATCH 09/12] Return certificate check information from get_info() --- src/login_param.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/login_param.rs b/src/login_param.rs index ff849f988..3fc64031f 100644 --- a/src/login_param.rs +++ b/src/login_param.rs @@ -4,8 +4,9 @@ use std::fmt; use crate::context::Context; use crate::error::Error; -#[derive(Copy, Clone, Debug, FromPrimitive)] +#[derive(Copy, Clone, Debug, Display, FromPrimitive)] #[repr(i32)] +#[strum(serialize_all = "snake_case")] pub enum CertificateChecks { Automatic = 0, Strict = 1, @@ -176,16 +177,18 @@ impl fmt::Display for LoginParam { write!( f, - "{} {}:{}:{}:{} {}:{}:{}:{} {}", + "{} imap:{}:{}:{}:{}:cert_{} smtp:{}:{}:{}:{}:cert_{} {}", unset_empty(&self.addr), unset_empty(&self.mail_user), if !self.mail_pw.is_empty() { pw } else { unset }, unset_empty(&self.mail_server), self.mail_port, + self.imap_certificate_checks, unset_empty(&self.send_user), if !self.send_pw.is_empty() { pw } else { unset }, unset_empty(&self.send_server), self.send_port, + self.smtp_certificate_checks, flags_readable, ) } @@ -247,3 +250,18 @@ fn get_readable_flags(flags: i32) -> String { res } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_certificate_checks_display() { + use std::string::ToString; + + assert_eq!( + "accept_invalid_hostnames".to_string(), + CertificateChecks::AcceptInvalidHostnames.to_string() + ); + } +} From f93f3d601214fc41d04cc04977f00d3046b9910f Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Thu, 3 Oct 2019 01:19:31 +0300 Subject: [PATCH 10/12] Do not set minimal TLS version for SMTP manually --- src/smtp.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/smtp.rs b/src/smtp.rs index 6697a3941..4e8e30d6d 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -85,7 +85,6 @@ impl Smtp { .danger_accept_invalid_hostnames(true) .danger_accept_invalid_certs(true), } - .min_protocol_version(Some(DEFAULT_TLS_PROTOCOLS[0])) .build() .unwrap(); From bf1652a1be27e370fba85da4b018d8587baa0d5c Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Thu, 3 Oct 2019 01:24:55 +0300 Subject: [PATCH 11/12] Move common code for IMAP and SMTP to login_param.rs --- src/imap.rs | 22 ++-------------------- src/login_param.rs | 23 +++++++++++++++++++++++ src/smtp.rs | 23 ++--------------------- 3 files changed, 27 insertions(+), 41 deletions(-) diff --git a/src/imap.rs b/src/imap.rs index ec6addb9b..ff1c32b0e 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -11,7 +11,7 @@ use crate::dc_receive_imf::dc_receive_imf; use crate::error::Error; use crate::events::Event; use crate::job::{connect_to_inbox, job_add, Action}; -use crate::login_param::{CertificateChecks, LoginParam}; +use crate::login_param::{dc_build_tls, CertificateChecks, LoginParam}; use crate::message::{self, update_msg_move_state, update_server_uid}; use crate::oauth2::dc_get_oauth2_access_token; use crate::param::Params; @@ -111,25 +111,7 @@ impl Client { certificate_checks: CertificateChecks, ) -> imap::error::Result { let stream = net::TcpStream::connect(addr)?; - let mut tls_builder = native_tls::TlsConnector::builder(); - let tls = 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 => &mut tls_builder, - CertificateChecks::AcceptInvalidHostnames => { - tls_builder.danger_accept_invalid_hostnames(true) - } - CertificateChecks::AcceptInvalidCertificates => tls_builder - .danger_accept_invalid_hostnames(true) - .danger_accept_invalid_certs(true), - } - .build() - .unwrap(); + let tls = dc_build_tls(certificate_checks).unwrap(); let s = stream.try_clone().expect("cloning the stream failed"); let tls_stream = native_tls::TlsConnector::connect(&tls, domain.as_ref(), s)?; diff --git a/src/login_param.rs b/src/login_param.rs index 3fc64031f..01e85b32a 100644 --- a/src/login_param.rs +++ b/src/login_param.rs @@ -251,6 +251,29 @@ fn get_readable_flags(flags: i32) -> String { res } +pub fn dc_build_tls( + certificate_checks: CertificateChecks, +) -> Result { + let mut tls_builder = native_tls::TlsConnector::builder(); + 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 => &mut tls_builder, + CertificateChecks::AcceptInvalidHostnames => { + tls_builder.danger_accept_invalid_hostnames(true) + } + CertificateChecks::AcceptInvalidCertificates => tls_builder + .danger_accept_invalid_hostnames(true) + .danger_accept_invalid_certs(true), + } + .build() +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/smtp.rs b/src/smtp.rs index 4e8e30d6d..089607bc8 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -5,7 +5,7 @@ use crate::constants::*; use crate::context::Context; use crate::error::Error; use crate::events::Event; -use crate::login_param::{CertificateChecks, LoginParam}; +use crate::login_param::{dc_build_tls, LoginParam}; use crate::oauth2::*; #[derive(DebugStub)] @@ -68,26 +68,7 @@ impl Smtp { let domain = &lp.send_server; let port = lp.send_port as u16; - let mut tls_builder = native_tls::TlsConnector::builder(); - let tls = match lp.smtp_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 => &mut tls_builder, - CertificateChecks::AcceptInvalidHostnames => { - tls_builder.danger_accept_invalid_hostnames(true) - } - CertificateChecks::AcceptInvalidCertificates => tls_builder - .danger_accept_invalid_hostnames(true) - .danger_accept_invalid_certs(true), - } - .build() - .unwrap(); - + let tls = dc_build_tls(lp.smtp_certificate_checks).unwrap(); let tls_parameters = ClientTlsParameters::new(domain.to_string(), tls); let creds = if 0 != lp.server_flags & (DC_LP_AUTH_OAUTH2 as i32) { From 216266d7bfc1ac0448131aaaaab022f1d56493ee Mon Sep 17 00:00:00 2001 From: Alexander Krotov Date: Thu, 3 Oct 2019 02:02:51 +0300 Subject: [PATCH 12/12] Apply imap_certificate_checks config to StartTLS connections --- src/imap.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/imap.rs b/src/imap.rs index ff1c32b0e..753dc8a36 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -131,13 +131,14 @@ impl Client { Ok(Client::Insecure(client, stream)) } - pub fn secure>(self, domain: S) -> imap::error::Result { + pub fn secure>( + self, + domain: S, + certificate_checks: CertificateChecks, + ) -> imap::error::Result { match self { Client::Insecure(client, stream) => { - let tls = native_tls::TlsConnector::builder() - .danger_accept_invalid_hostnames(true) - .build() - .unwrap(); + let tls = dc_build_tls(certificate_checks).unwrap(); let client_sec = client.secure(domain, &tls)?; @@ -395,7 +396,7 @@ impl Imap { Client::connect_insecure((imap_server, imap_port)).and_then(|client| { if (server_flags & DC_LP_IMAP_SOCKET_STARTTLS) != 0 { - client.secure(imap_server) + client.secure(imap_server, config.certificate_checks) } else { Ok(client) }