mirror of
https://github.com/chatmail/core.git
synced 2026-04-17 13:36:30 +03:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
495337743a | ||
|
|
775edab7b1 | ||
|
|
fe9fa17005 | ||
|
|
0d0f556f21 | ||
|
|
0e365395bf | ||
|
|
8538a3c148 | ||
|
|
cb4b992204 | ||
|
|
af4d54ab50 | ||
|
|
1faff84905 | ||
|
|
62fde21d9a | ||
|
|
6f3729a00f | ||
|
|
fbf66ba02b |
36
CHANGELOG.md
36
CHANGELOG.md
@@ -1,5 +1,38 @@
|
||||
# Changelog
|
||||
|
||||
## [1.142.9] - 2024-08-24
|
||||
|
||||
### Fixes
|
||||
|
||||
- Fix reading of multiline SMTP greetings ([#5911](https://github.com/deltachat/deltachat-core-rust/pull/5911)).
|
||||
|
||||
### Features / Changes
|
||||
|
||||
- Update preloaded DNS cache.
|
||||
|
||||
## [1.142.8] - 2024-08-21
|
||||
|
||||
### Fixes
|
||||
|
||||
- Do not panic on unknown CertificateChecks values.
|
||||
|
||||
## [1.142.7] - 2024-08-17
|
||||
|
||||
### Fixes
|
||||
|
||||
- Do not save "Automatic" into configured_imap_certificate_checks. **This fixes regression introduced in core 1.142.4. Versions 1.142.4..1.142.6 should not be used in releases.**
|
||||
- Create a group unblocked for bot even if 1:1 chat is blocked ([#5514](https://github.com/deltachat/deltachat-core-rust/pull/5514)).
|
||||
- Update rpgp from 0.13.1 to 0.13.2 to fix "unable to decrypt" errors when sending messages to old Delta Chat clients and using Ed25519 keys to encrypt.
|
||||
- Do not request ALPN on standard ports and when using STARTTLS.
|
||||
|
||||
### Features / Changes
|
||||
|
||||
- jsonrpc: Add ContactObject::e2ee_avail.
|
||||
|
||||
### Tests
|
||||
|
||||
- Protected group for bot is auto-accepted.
|
||||
|
||||
## [1.142.6] - 2024-08-15
|
||||
|
||||
### Fixes
|
||||
@@ -4749,3 +4782,6 @@ https://github.com/deltachat/deltachat-core-rust/pulls?q=is%3Apr+is%3Aclosed
|
||||
[1.142.4]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.3...v1.142.4
|
||||
[1.142.5]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.4...v1.142.5
|
||||
[1.142.6]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.5...v1.142.6
|
||||
[1.142.7]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.6...v1.142.7
|
||||
[1.142.8]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.7...v1.142.8
|
||||
[1.142.9]: https://github.com/deltachat/deltachat-core-rust/compare/v1.142.8...v1.142.9
|
||||
|
||||
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -1353,7 +1353,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"anyhow",
|
||||
@@ -1444,7 +1444,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-jsonrpc"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-channel 2.3.1",
|
||||
@@ -1469,7 +1469,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-repl"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"anyhow",
|
||||
@@ -1484,7 +1484,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat-rpc-server"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deltachat",
|
||||
@@ -1513,7 +1513,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deltachat_ffi"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"deltachat",
|
||||
@@ -3080,7 +3080,7 @@ dependencies = [
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"windows-core 0.52.0",
|
||||
"windows-core 0.51.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4428,9 +4428,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pgp"
|
||||
version = "0.13.1"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aeab6e08a63a51a29a65e461d0b6fd0f8d350914712ec43773ca22ed51d5501c"
|
||||
checksum = "4a6c842436d5fa2b59eac1e9b3d142b50bfff99c1744c816b1f4c2ac55a20754"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"aes-gcm",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
edition = "2021"
|
||||
license = "MPL-2.0"
|
||||
rust-version = "1.77"
|
||||
@@ -73,7 +73,7 @@ num-traits = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
percent-encoding = "2.3"
|
||||
parking_lot = "0.12"
|
||||
pgp = { version = "0.13", default-features = false }
|
||||
pgp = { version = "0.13.2", default-features = false }
|
||||
qrcodegen = "1.7.0"
|
||||
quick-xml = "0.36"
|
||||
quoted_printable = "0.5"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat_ffi"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
description = "Deltachat FFI"
|
||||
edition = "2018"
|
||||
readme = "README.md"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat-jsonrpc"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
description = "DeltaChat JSON-RPC API"
|
||||
edition = "2021"
|
||||
default-run = "deltachat-jsonrpc-server"
|
||||
|
||||
@@ -19,6 +19,7 @@ pub struct ContactObject {
|
||||
profile_image: Option<String>, // BLOBS
|
||||
name_and_addr: String,
|
||||
is_blocked: bool,
|
||||
e2ee_avail: bool,
|
||||
|
||||
/// True if the contact can be added to verified groups.
|
||||
///
|
||||
@@ -79,6 +80,7 @@ impl ContactObject {
|
||||
profile_image, //BLOBS
|
||||
name_and_addr: contact.get_name_n_addr(),
|
||||
is_blocked: contact.is_blocked(),
|
||||
e2ee_avail: contact.e2ee_avail(context).await?,
|
||||
is_verified,
|
||||
is_profile_verified,
|
||||
verifier_id,
|
||||
|
||||
@@ -58,5 +58,5 @@
|
||||
},
|
||||
"type": "module",
|
||||
"types": "dist/deltachat.d.ts",
|
||||
"version": "1.142.6"
|
||||
"version": "1.142.9"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat-repl"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
license = "MPL-2.0"
|
||||
edition = "2021"
|
||||
repository = "https://github.com/deltachat/deltachat-core-rust"
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "deltachat-rpc-client"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
description = "Python client for Delta Chat core JSON-RPC interface"
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
|
||||
@@ -635,3 +635,24 @@ def test_get_http_response(acfactory):
|
||||
http_response = alice._rpc.get_http_response(alice.id, "https://example.org")
|
||||
assert http_response["mimetype"] == "text/html"
|
||||
assert b"<title>Example Domain</title>" in base64.b64decode((http_response["blob"] + "==").encode())
|
||||
|
||||
|
||||
def test_configured_imap_certificate_checks(acfactory):
|
||||
alice = acfactory.new_configured_account()
|
||||
configured_certificate_checks = alice.get_config("configured_imap_certificate_checks")
|
||||
|
||||
# Certificate checks should be configured (not None)
|
||||
assert configured_certificate_checks
|
||||
|
||||
# 0 is the value old Delta Chat core versions used
|
||||
# to mean user entered "imap_certificate_checks=0" (Automatic)
|
||||
# and configuration failed to use strict TLS checks
|
||||
# so it switched strict TLS checks off.
|
||||
#
|
||||
# New versions of Delta Chat are not disabling TLS checks
|
||||
# unless users explicitly disables them
|
||||
# or provider database says provider has invalid certificates.
|
||||
#
|
||||
# Core 1.142.4, 1.142.5 and 1.142.6 saved this value due to bug.
|
||||
# This test is a regression test to prevent this happening again.
|
||||
assert configured_certificate_checks != "0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "deltachat-rpc-server"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
description = "DeltaChat JSON-RPC server"
|
||||
edition = "2021"
|
||||
readme = "README.md"
|
||||
|
||||
@@ -15,5 +15,5 @@
|
||||
},
|
||||
"type": "module",
|
||||
"types": "index.d.ts",
|
||||
"version": "1.142.6"
|
||||
"version": "1.142.9"
|
||||
}
|
||||
|
||||
@@ -55,5 +55,5 @@
|
||||
"test:mocha": "mocha node/test/test.mjs --growl --reporter=spec --bail --exit"
|
||||
},
|
||||
"types": "node/dist/index.d.ts",
|
||||
"version": "1.142.6"
|
||||
"version": "1.142.9"
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "deltachat"
|
||||
version = "1.142.6"
|
||||
version = "1.142.9"
|
||||
description = "Python bindings for the Delta Chat Core library using CFFI against the Rust-implemented libdeltachat"
|
||||
readme = "README.rst"
|
||||
requires-python = ">=3.7"
|
||||
|
||||
@@ -1 +1 @@
|
||||
2024-08-15
|
||||
2024-08-24
|
||||
@@ -27,7 +27,7 @@ use crate::config::{self, Config};
|
||||
use crate::context::Context;
|
||||
use crate::imap::{session::Session as ImapSession, Imap};
|
||||
use crate::log::LogExt;
|
||||
use crate::login_param::{LoginParam, ServerLoginParam};
|
||||
use crate::login_param::{CertificateChecks, LoginParam, ServerLoginParam};
|
||||
use crate::message::{Message, Viewtype};
|
||||
use crate::oauth2::get_oauth2_addr;
|
||||
use crate::provider::{Protocol, Socket, UsernamePattern};
|
||||
@@ -280,7 +280,21 @@ async fn configure(ctx: &Context, param: &mut LoginParam) -> Result<()> {
|
||||
param_autoconfig = None;
|
||||
}
|
||||
|
||||
let strict_tls = param.strict_tls();
|
||||
let user_strict_tls = match param.certificate_checks {
|
||||
CertificateChecks::Automatic => None,
|
||||
CertificateChecks::Strict => Some(true),
|
||||
CertificateChecks::AcceptInvalidCertificates
|
||||
| CertificateChecks::AcceptInvalidCertificates2 => Some(false),
|
||||
};
|
||||
let provider_strict_tls = param.provider.map(|provider| provider.opt.strict_tls);
|
||||
let strict_tls = user_strict_tls.or(provider_strict_tls).unwrap_or(true);
|
||||
|
||||
// Do not save `CertificateChecks::Automatic` into `configured_imap_certificate_checks`.
|
||||
param.certificate_checks = if strict_tls {
|
||||
CertificateChecks::Strict
|
||||
} else {
|
||||
CertificateChecks::AcceptInvalidCertificates
|
||||
};
|
||||
|
||||
progress!(ctx, 500);
|
||||
|
||||
|
||||
@@ -1402,6 +1402,17 @@ impl Contact {
|
||||
self.status.as_str()
|
||||
}
|
||||
|
||||
/// Returns whether end-to-end encryption to the contact is available.
|
||||
pub async fn e2ee_avail(&self, context: &Context) -> Result<bool> {
|
||||
if self.id == ContactId::SELF {
|
||||
return Ok(true);
|
||||
}
|
||||
let Some(peerstate) = Peerstate::from_addr(context, &self.addr).await? else {
|
||||
return Ok(false);
|
||||
};
|
||||
Ok(peerstate.peek_key(false).is_some())
|
||||
}
|
||||
|
||||
/// Returns true if the contact
|
||||
/// can be added to verified chats,
|
||||
/// i.e. has a verified key
|
||||
@@ -2673,6 +2684,8 @@ mod tests {
|
||||
|
||||
let encrinfo = Contact::get_encrinfo(&alice, contact_bob_id).await?;
|
||||
assert_eq!(encrinfo, "No encryption");
|
||||
let contact = Contact::get_by_id(&alice, contact_bob_id).await?;
|
||||
assert!(!contact.e2ee_avail(&alice).await?);
|
||||
|
||||
let bob = TestContext::new_bob().await;
|
||||
let chat_alice = bob
|
||||
@@ -2696,6 +2709,8 @@ bob@example.net:
|
||||
CCCB 5AA9 F6E1 141C 9431
|
||||
65F1 DB18 B18C BCF7 0487"
|
||||
);
|
||||
let contact = Contact::get_by_id(&alice, contact_bob_id).await?;
|
||||
assert!(contact.e2ee_avail(&alice).await?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,16 @@ impl DerefMut for Client {
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts port number to ALPN list.
|
||||
fn alpn(port: u16) -> &'static [&'static str] {
|
||||
if port == 993 {
|
||||
// Do not request ALPN on standard port.
|
||||
&[]
|
||||
} else {
|
||||
&["imap"]
|
||||
}
|
||||
}
|
||||
|
||||
/// Determine server capabilities.
|
||||
///
|
||||
/// If server supports ID capability, send our client ID.
|
||||
@@ -157,7 +167,7 @@ impl Client {
|
||||
}
|
||||
|
||||
async fn connect_secure(addr: SocketAddr, hostname: &str, strict_tls: bool) -> Result<Self> {
|
||||
let tls_stream = connect_tls_inner(addr, hostname, strict_tls, "imap").await?;
|
||||
let tls_stream = connect_tls_inner(addr, hostname, strict_tls, alpn(addr.port())).await?;
|
||||
let buffered_stream = BufWriter::new(tls_stream);
|
||||
let session_stream: Box<dyn SessionStream> = Box::new(buffered_stream);
|
||||
let mut client = Client::new(session_stream);
|
||||
@@ -197,7 +207,7 @@ impl Client {
|
||||
let buffered_tcp_stream = client.into_inner();
|
||||
let tcp_stream = buffered_tcp_stream.into_inner();
|
||||
|
||||
let tls_stream = wrap_tls(strict_tls, host, "imap", tcp_stream)
|
||||
let tls_stream = wrap_tls(strict_tls, host, &[], tcp_stream)
|
||||
.await
|
||||
.context("STARTTLS upgrade failed")?;
|
||||
|
||||
@@ -217,7 +227,7 @@ impl Client {
|
||||
let socks5_stream = socks5_config
|
||||
.connect(context, domain, port, strict_tls)
|
||||
.await?;
|
||||
let tls_stream = wrap_tls(strict_tls, domain, "imap", socks5_stream).await?;
|
||||
let tls_stream = wrap_tls(strict_tls, domain, alpn(port), socks5_stream).await?;
|
||||
let buffered_stream = BufWriter::new(tls_stream);
|
||||
let session_stream: Box<dyn SessionStream> = Box::new(buffered_stream);
|
||||
let mut client = Client::new(session_stream);
|
||||
@@ -270,7 +280,7 @@ impl Client {
|
||||
let buffered_socks5_stream = client.into_inner();
|
||||
let socks5_stream: Socks5Stream<_> = buffered_socks5_stream.into_inner();
|
||||
|
||||
let tls_stream = wrap_tls(strict_tls, hostname, "imap", socks5_stream)
|
||||
let tls_stream = wrap_tls(strict_tls, hostname, &[], socks5_stream)
|
||||
.await
|
||||
.context("STARTTLS upgrade failed")?;
|
||||
let buffered_stream = BufWriter::new(tls_stream);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use anyhow::{ensure, Result};
|
||||
use anyhow::{ensure, Context as _, Result};
|
||||
|
||||
use crate::constants::{DC_LP_AUTH_FLAGS, DC_LP_AUTH_NORMAL, DC_LP_AUTH_OAUTH2};
|
||||
use crate::context::Context;
|
||||
@@ -132,7 +132,8 @@ impl LoginParam {
|
||||
let key = &format!("{prefix}imap_certificate_checks");
|
||||
let certificate_checks =
|
||||
if let Some(certificate_checks) = sql.get_raw_config_int(key).await? {
|
||||
num_traits::FromPrimitive::from_i32(certificate_checks).unwrap()
|
||||
num_traits::FromPrimitive::from_i32(certificate_checks)
|
||||
.with_context(|| format!("Invalid {key} value"))?
|
||||
} else {
|
||||
Default::default()
|
||||
};
|
||||
@@ -265,7 +266,9 @@ impl LoginParam {
|
||||
| CertificateChecks::AcceptInvalidCertificates2 => Some(false),
|
||||
};
|
||||
let provider_strict_tls = self.provider.map(|provider| provider.opt.strict_tls);
|
||||
user_strict_tls.or(provider_strict_tls).unwrap_or(true)
|
||||
user_strict_tls
|
||||
.or(provider_strict_tls)
|
||||
.unwrap_or(self.socks5_config.is_some())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ pub(crate) async fn connect_tls_inner(
|
||||
addr: SocketAddr,
|
||||
host: &str,
|
||||
strict_tls: bool,
|
||||
alpn: &str,
|
||||
alpn: &[&str],
|
||||
) -> Result<TlsStream<Pin<Box<TimeoutStream<TcpStream>>>>> {
|
||||
let tcp_stream = connect_tcp_inner(addr).await?;
|
||||
let tls_stream = wrap_tls(strict_tls, host, alpn, tcp_stream).await?;
|
||||
|
||||
454
src/net/dns.rs
454
src/net/dns.rs
@@ -1,6 +1,7 @@
|
||||
//! DNS resolution and cache.
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
use std::collections::HashMap;
|
||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
|
||||
use std::str::FromStr;
|
||||
use tokio::net::lookup_host;
|
||||
@@ -9,6 +10,7 @@ use tokio::time::timeout;
|
||||
use super::load_connection_timestamp;
|
||||
use crate::context::Context;
|
||||
use crate::tools::time;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
/// Inserts entry into DNS cache
|
||||
/// or updates existing one with a new timestamp.
|
||||
@@ -106,6 +108,399 @@ pub(crate) async fn update_connect_timestamp(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
static DNS_PRELOAD: Lazy<HashMap<&'static str, Vec<IpAddr>>> = Lazy::new(|| {
|
||||
HashMap::from([
|
||||
(
|
||||
"mail.sangham.net",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(159, 69, 186, 85)),
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a01, 0x4f8, 0xc17, 0x798c, 0, 0, 0, 1)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"nine.testrun.org",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(116, 202, 233, 236)),
|
||||
IpAddr::V4(Ipv4Addr::new(128, 140, 126, 197)),
|
||||
IpAddr::V4(Ipv4Addr::new(49, 12, 116, 128)),
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a01, 0x4f8, 0x241, 0x4ce8, 0, 0, 0, 2)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"disroot.org",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(178, 21, 23, 139))],
|
||||
),
|
||||
(
|
||||
"imap.gmail.com",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(142, 250, 110, 108)),
|
||||
IpAddr::V4(Ipv4Addr::new(142, 250, 110, 109)),
|
||||
IpAddr::V4(Ipv4Addr::new(66, 102, 1, 108)),
|
||||
IpAddr::V4(Ipv4Addr::new(66, 102, 1, 109)),
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a00, 0x1450, 0x400c, 0xc1f, 0, 0, 0, 0x6c)),
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a00, 0x1450, 0x400c, 0xc1f, 0, 0, 0, 0x6d)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"smtp.gmail.com",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(142, 250, 110, 109)),
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a00, 0x1450, 0x4013, 0xc04, 0, 0, 0, 0x6c)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"mail.autistici.org",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(198, 167, 222, 108)),
|
||||
IpAddr::V4(Ipv4Addr::new(82, 94, 249, 234)),
|
||||
IpAddr::V4(Ipv4Addr::new(93, 190, 126, 19)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"smtp.autistici.org",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(198, 167, 222, 108)),
|
||||
IpAddr::V4(Ipv4Addr::new(82, 94, 249, 234)),
|
||||
IpAddr::V4(Ipv4Addr::new(93, 190, 126, 19)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"daleth.cafe",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(37, 27, 6, 204))],
|
||||
),
|
||||
(
|
||||
"imap.163.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(111, 124, 203, 45))],
|
||||
),
|
||||
(
|
||||
"smtp.163.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(103, 129, 252, 45))],
|
||||
),
|
||||
(
|
||||
"imap.aol.com",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(212, 82, 101, 33)),
|
||||
IpAddr::V4(Ipv4Addr::new(87, 248, 98, 69)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"smtp.aol.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(87, 248, 97, 31))],
|
||||
),
|
||||
(
|
||||
"mail.arcor.de",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(2, 207, 150, 234))],
|
||||
),
|
||||
(
|
||||
"imap.arcor.de",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(2, 207, 150, 230))],
|
||||
),
|
||||
(
|
||||
"imap.fastmail.com",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(103, 168, 172, 43)),
|
||||
IpAddr::V4(Ipv4Addr::new(103, 168, 172, 58)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"smtp.fastmail.com",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(103, 168, 172, 45)),
|
||||
IpAddr::V4(Ipv4Addr::new(103, 168, 172, 60)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"imap.gmx.net",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(212, 227, 17, 170)),
|
||||
IpAddr::V4(Ipv4Addr::new(212, 227, 17, 186)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"imap.mail.de",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(62, 201, 172, 16))],
|
||||
),
|
||||
(
|
||||
"smtp.mailbox.org",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(185, 97, 174, 196))],
|
||||
),
|
||||
(
|
||||
"imap.mailbox.org",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(185, 97, 174, 199))],
|
||||
),
|
||||
(
|
||||
"imap.naver.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(125, 209, 238, 153))],
|
||||
),
|
||||
(
|
||||
"imap.ouvaton.coop",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(194, 36, 166, 20))],
|
||||
),
|
||||
(
|
||||
"imap.purelymail.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(18, 204, 123, 63))],
|
||||
),
|
||||
(
|
||||
"imap.tiscali.it",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(213, 205, 33, 10))],
|
||||
),
|
||||
(
|
||||
"smtp.tiscali.it",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(213, 205, 33, 13))],
|
||||
),
|
||||
(
|
||||
"imap.web.de",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(212, 227, 17, 162)),
|
||||
IpAddr::V4(Ipv4Addr::new(212, 227, 17, 178)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"imap.ziggo.nl",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(84, 116, 6, 3))],
|
||||
),
|
||||
(
|
||||
"imap.zoho.eu",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(185, 230, 214, 25))],
|
||||
),
|
||||
(
|
||||
"imaps.bluewin.ch",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(16, 62, 253, 42)),
|
||||
IpAddr::V4(Ipv4Addr::new(16, 63, 141, 244)),
|
||||
IpAddr::V4(Ipv4Addr::new(16, 63, 146, 183)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"mail.buzon.uy",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(185, 101, 93, 79))],
|
||||
),
|
||||
(
|
||||
"mail.ecloud.global",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(95, 217, 246, 96))],
|
||||
),
|
||||
(
|
||||
"mail.ende.in.net",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(95, 217, 5, 72))],
|
||||
),
|
||||
(
|
||||
"mail.gmx.net",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(212, 227, 17, 168)),
|
||||
IpAddr::V4(Ipv4Addr::new(212, 227, 17, 190)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"mail.infomaniak.com",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(83, 166, 143, 44)),
|
||||
IpAddr::V4(Ipv4Addr::new(83, 166, 143, 45)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"mail.mymagenta.at",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(80, 109, 253, 241))],
|
||||
),
|
||||
(
|
||||
"mail.nubo.coop",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(79, 99, 201, 10))],
|
||||
),
|
||||
(
|
||||
"mail.riseup.net",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(198, 252, 153, 70)),
|
||||
IpAddr::V4(Ipv4Addr::new(198, 252, 153, 71)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"mail.systemausfall.org",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(51, 75, 71, 249)),
|
||||
IpAddr::V4(Ipv4Addr::new(80, 153, 252, 42)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"mail.systemli.org",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(93, 190, 126, 36))],
|
||||
),
|
||||
(
|
||||
"mehl.cloud",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(95, 217, 223, 172))],
|
||||
),
|
||||
(
|
||||
"mx.freenet.de",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(195, 4, 92, 210)),
|
||||
IpAddr::V4(Ipv4Addr::new(195, 4, 92, 211)),
|
||||
IpAddr::V4(Ipv4Addr::new(195, 4, 92, 212)),
|
||||
IpAddr::V4(Ipv4Addr::new(195, 4, 92, 213)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"newyear.aktivix.org",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(162, 247, 75, 192))],
|
||||
),
|
||||
(
|
||||
"pimap.schulon.org",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(194, 77, 246, 20))],
|
||||
),
|
||||
(
|
||||
"posteo.de",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(185, 67, 36, 168)),
|
||||
IpAddr::V4(Ipv4Addr::new(185, 67, 36, 169)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"psmtp.schulon.org",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(194, 77, 246, 20))],
|
||||
),
|
||||
(
|
||||
"secureimap.t-online.de",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(194, 25, 134, 114)),
|
||||
IpAddr::V4(Ipv4Addr::new(194, 25, 134, 115)),
|
||||
IpAddr::V4(Ipv4Addr::new(194, 25, 134, 50)),
|
||||
IpAddr::V4(Ipv4Addr::new(194, 25, 134, 51)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"securesmtp.t-online.de",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(194, 25, 134, 110)),
|
||||
IpAddr::V4(Ipv4Addr::new(194, 25, 134, 46)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"smtp.aliyun.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(47, 246, 136, 232))],
|
||||
),
|
||||
(
|
||||
"smtp.mail.de",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(62, 201, 172, 21))],
|
||||
),
|
||||
(
|
||||
"smtp.mail.ru",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(217, 69, 139, 160)),
|
||||
IpAddr::V4(Ipv4Addr::new(94, 100, 180, 160)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"imap.mail.yahoo.com",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(87, 248, 103, 8)),
|
||||
IpAddr::V4(Ipv4Addr::new(212, 82, 101, 24)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"smtp.mail.yahoo.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(87, 248, 97, 36))],
|
||||
),
|
||||
(
|
||||
"imap.mailo.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(213, 182, 54, 20))],
|
||||
),
|
||||
(
|
||||
"smtp.mailo.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(213, 182, 54, 20))],
|
||||
),
|
||||
(
|
||||
"smtp.naver.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(125, 209, 238, 155))],
|
||||
),
|
||||
(
|
||||
"smtp.ouvaton.coop",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(194, 36, 166, 20))],
|
||||
),
|
||||
(
|
||||
"smtp.purelymail.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(18, 204, 123, 63))],
|
||||
),
|
||||
(
|
||||
"imap.qq.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(43, 129, 255, 54))],
|
||||
),
|
||||
(
|
||||
"smtp.qq.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(43, 129, 255, 54))],
|
||||
),
|
||||
(
|
||||
"imap.rambler.ru",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(81, 19, 77, 169)),
|
||||
IpAddr::V4(Ipv4Addr::new(81, 19, 77, 171)),
|
||||
IpAddr::V4(Ipv4Addr::new(81, 19, 77, 168)),
|
||||
IpAddr::V4(Ipv4Addr::new(81, 19, 77, 170)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"smtp.rambler.ru",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(81, 19, 77, 165)),
|
||||
IpAddr::V4(Ipv4Addr::new(81, 19, 77, 167)),
|
||||
IpAddr::V4(Ipv4Addr::new(81, 19, 77, 166)),
|
||||
IpAddr::V4(Ipv4Addr::new(81, 19, 77, 164)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"imap.vivaldi.net",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(31, 209, 137, 15))],
|
||||
),
|
||||
(
|
||||
"smtp.vivaldi.net",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(31, 209, 137, 12))],
|
||||
),
|
||||
(
|
||||
"imap.vodafonemail.de",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(2, 207, 150, 230))],
|
||||
),
|
||||
(
|
||||
"smtp.vodafonemail.de",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(2, 207, 150, 234))],
|
||||
),
|
||||
(
|
||||
"smtp.web.de",
|
||||
vec![
|
||||
IpAddr::V4(Ipv4Addr::new(213, 165, 67, 108)),
|
||||
IpAddr::V4(Ipv4Addr::new(213, 165, 67, 124)),
|
||||
],
|
||||
),
|
||||
(
|
||||
"imap.yandex.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(77, 88, 21, 125))],
|
||||
),
|
||||
(
|
||||
"smtp.yandex.com",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(77, 88, 21, 158))],
|
||||
),
|
||||
(
|
||||
"smtp.ziggo.nl",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(84, 116, 6, 3))],
|
||||
),
|
||||
(
|
||||
"smtp.zoho.eu",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(185, 230, 212, 164))],
|
||||
),
|
||||
(
|
||||
"smtpauths.bluewin.ch",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(195, 186, 120, 54))],
|
||||
),
|
||||
(
|
||||
"stinpriza.net",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(5, 9, 122, 184))],
|
||||
),
|
||||
(
|
||||
"undernet.uy",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(167, 62, 254, 153))],
|
||||
),
|
||||
(
|
||||
"webbox222.server-home.org",
|
||||
vec![IpAddr::V4(Ipv4Addr::new(91, 203, 111, 88))],
|
||||
),
|
||||
])
|
||||
});
|
||||
|
||||
/// Load hardcoded cache if everything else fails.
|
||||
///
|
||||
/// See <https://support.delta.chat/t/no-dns-resolution-result/2778> and
|
||||
@@ -114,61 +509,10 @@ pub(crate) async fn update_connect_timestamp(
|
||||
/// In the future we may pre-resolve all provider database addresses
|
||||
/// and build them in.
|
||||
fn load_hardcoded_cache(hostname: &str, port: u16) -> Vec<SocketAddr> {
|
||||
match hostname {
|
||||
"mail.sangham.net" => {
|
||||
vec![
|
||||
SocketAddr::new(
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a01, 0x4f8, 0xc17, 0x798c, 0, 0, 0, 1)),
|
||||
port,
|
||||
),
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(159, 69, 186, 85)), port),
|
||||
]
|
||||
}
|
||||
"nine.testrun.org" => {
|
||||
vec![
|
||||
SocketAddr::new(
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a01, 0x4f8, 0x241, 0x4ce8, 0, 0, 0, 2)),
|
||||
port,
|
||||
),
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(116, 202, 233, 236)), port),
|
||||
]
|
||||
}
|
||||
"disroot.org" => {
|
||||
vec![SocketAddr::new(
|
||||
IpAddr::V4(Ipv4Addr::new(178, 21, 23, 139)),
|
||||
port,
|
||||
)]
|
||||
}
|
||||
"mail.riseup.net" => {
|
||||
vec![
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(198, 252, 153, 70)), port),
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(198, 252, 153, 71)), port),
|
||||
]
|
||||
}
|
||||
"imap.gmail.com" => {
|
||||
vec![
|
||||
SocketAddr::new(
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a00, 0x1450, 0x400c, 0xc1f, 0, 0, 0, 0x6c)),
|
||||
port,
|
||||
),
|
||||
SocketAddr::new(
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a00, 0x1450, 0x400c, 0xc1f, 0, 0, 0, 0x6d)),
|
||||
port,
|
||||
),
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(142, 250, 110, 109)), port),
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(142, 250, 110, 108)), port),
|
||||
]
|
||||
}
|
||||
"smtp.gmail.com" => {
|
||||
vec![
|
||||
SocketAddr::new(
|
||||
IpAddr::V6(Ipv6Addr::new(0x2a00, 0x1450, 0x4013, 0xc04, 0, 0, 0, 0x6c)),
|
||||
port,
|
||||
),
|
||||
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(142, 250, 110, 109)), port),
|
||||
]
|
||||
}
|
||||
_ => Vec::new(),
|
||||
if let Some(ips) = DNS_PRELOAD.get(hostname) {
|
||||
ips.iter().map(|ip| SocketAddr::new(*ip, port)).collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,10 +32,10 @@ pub fn build_tls(strict_tls: bool, alpns: &[&str]) -> TlsConnector {
|
||||
pub async fn wrap_tls<T: AsyncRead + AsyncWrite + Unpin>(
|
||||
strict_tls: bool,
|
||||
hostname: &str,
|
||||
alpn: &str,
|
||||
alpn: &[&str],
|
||||
stream: T,
|
||||
) -> Result<TlsStream<T>> {
|
||||
let tls = build_tls(strict_tls, &[alpn]);
|
||||
let tls = build_tls(strict_tls, alpn);
|
||||
let tls_stream = tls.connect(hostname, stream).await?;
|
||||
Ok(tls_stream)
|
||||
}
|
||||
|
||||
@@ -807,7 +807,7 @@ async fn add_parts(
|
||||
// 1:1 chat is blocked, but the contact is not.
|
||||
// This happens when 1:1 chat is hidden
|
||||
// during scanning of a group invitation code.
|
||||
Blocked::Request
|
||||
create_blocked_default
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use crate::contact;
|
||||
use crate::download::MIN_DOWNLOAD_LIMIT;
|
||||
use crate::imap::prefetch_should_download;
|
||||
use crate::imex::{imex, ImexMode};
|
||||
use crate::securejoin::get_securejoin_qr;
|
||||
use crate::test_utils::{get_chat_msg, mark_as_verified, TestContext, TestContextManager};
|
||||
use crate::tools::{time, SystemTime};
|
||||
|
||||
@@ -3275,6 +3276,46 @@ async fn test_auto_accept_group_for_bots() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_auto_accept_protected_group_for_bots() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
bob.set_config(Config::Bot, Some("1")).await.unwrap();
|
||||
mark_as_verified(alice, bob).await;
|
||||
mark_as_verified(bob, alice).await;
|
||||
let group_id = alice
|
||||
.create_group_with_members(ProtectionStatus::Protected, "Group", &[bob])
|
||||
.await;
|
||||
let sent = alice.send_text(group_id, "Hello!").await;
|
||||
let msg = bob.recv_msg(&sent).await;
|
||||
let chat = chat::Chat::load_from_db(bob, msg.chat_id).await?;
|
||||
assert!(!chat.is_contact_request());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_bot_accepts_another_group_after_qr_scan() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
let alice = &tcm.alice().await;
|
||||
let bob = &tcm.bob().await;
|
||||
bob.set_config(Config::Bot, Some("1")).await?;
|
||||
|
||||
let group_id = chat::create_group_chat(alice, ProtectionStatus::Protected, "Group").await?;
|
||||
let qr = get_securejoin_qr(alice, Some(group_id)).await?;
|
||||
tcm.exec_securejoin_qr(bob, alice, &qr).await;
|
||||
|
||||
let group_id = alice
|
||||
.create_group_with_members(ProtectionStatus::Protected, "Group", &[bob])
|
||||
.await;
|
||||
let sent = alice.send_text(group_id, "Hello!").await;
|
||||
let msg = bob.recv_msg(&sent).await;
|
||||
let chat = chat::Chat::load_from_db(bob, msg.chat_id).await?;
|
||||
assert!(!chat.is_contact_request());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_send_as_bot() -> Result<()> {
|
||||
let mut tcm = TestContextManager::new();
|
||||
|
||||
@@ -16,6 +16,16 @@ use crate::provider::Socket;
|
||||
use crate::socks::Socks5Config;
|
||||
use crate::tools::time;
|
||||
|
||||
/// Converts port number to ALPN list.
|
||||
fn alpn(port: u16) -> &'static [&'static str] {
|
||||
if port == 465 {
|
||||
// Do not request ALPN on standard port.
|
||||
&[]
|
||||
} else {
|
||||
&["smtp"]
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns TLS, STARTTLS or plaintext connection
|
||||
/// using SOCKS5 or direct connection depending on the given configuration.
|
||||
///
|
||||
@@ -89,11 +99,12 @@ pub(crate) async fn connect_stream(
|
||||
async fn skip_smtp_greeting<R: tokio::io::AsyncBufReadExt + Unpin>(stream: &mut R) -> Result<()> {
|
||||
let mut line = String::with_capacity(512);
|
||||
loop {
|
||||
line.clear();
|
||||
let read = stream.read_line(&mut line).await?;
|
||||
if read == 0 {
|
||||
bail!("Unexpected EOF while reading SMTP greeting.");
|
||||
}
|
||||
if line.starts_with("220- ") {
|
||||
if line.starts_with("220-") {
|
||||
continue;
|
||||
} else if line.starts_with("220 ") {
|
||||
return Ok(());
|
||||
@@ -113,7 +124,7 @@ async fn connect_secure_socks5(
|
||||
let socks5_stream = socks5_config
|
||||
.connect(context, hostname, port, strict_tls)
|
||||
.await?;
|
||||
let tls_stream = wrap_tls(strict_tls, hostname, "smtp", socks5_stream).await?;
|
||||
let tls_stream = wrap_tls(strict_tls, hostname, alpn(port), socks5_stream).await?;
|
||||
let mut buffered_stream = BufStream::new(tls_stream);
|
||||
skip_smtp_greeting(&mut buffered_stream).await?;
|
||||
let session_stream: Box<dyn SessionBufStream> = Box::new(buffered_stream);
|
||||
@@ -135,7 +146,7 @@ async fn connect_starttls_socks5(
|
||||
let client = SmtpClient::new().smtp_utf8(true);
|
||||
let transport = SmtpTransport::new(client, BufStream::new(socks5_stream)).await?;
|
||||
let tcp_stream = transport.starttls().await?.into_inner();
|
||||
let tls_stream = wrap_tls(strict_tls, hostname, "smtp", tcp_stream)
|
||||
let tls_stream = wrap_tls(strict_tls, hostname, &[], tcp_stream)
|
||||
.await
|
||||
.context("STARTTLS upgrade failed")?;
|
||||
let buffered_stream = BufStream::new(tls_stream);
|
||||
@@ -163,7 +174,7 @@ async fn connect_secure(
|
||||
hostname: &str,
|
||||
strict_tls: bool,
|
||||
) -> Result<Box<dyn SessionBufStream>> {
|
||||
let tls_stream = connect_tls_inner(addr, hostname, strict_tls, "smtp").await?;
|
||||
let tls_stream = connect_tls_inner(addr, hostname, strict_tls, alpn(addr.port())).await?;
|
||||
let mut buffered_stream = BufStream::new(tls_stream);
|
||||
skip_smtp_greeting(&mut buffered_stream).await?;
|
||||
let session_stream: Box<dyn SessionBufStream> = Box::new(buffered_stream);
|
||||
@@ -181,7 +192,7 @@ async fn connect_starttls(
|
||||
let client = async_smtp::SmtpClient::new().smtp_utf8(true);
|
||||
let transport = async_smtp::SmtpTransport::new(client, BufStream::new(tcp_stream)).await?;
|
||||
let tcp_stream = transport.starttls().await?.into_inner();
|
||||
let tls_stream = wrap_tls(strict_tls, host, "smtp", tcp_stream)
|
||||
let tls_stream = wrap_tls(strict_tls, host, &[], tcp_stream)
|
||||
.await
|
||||
.context("STARTTLS upgrade failed")?;
|
||||
|
||||
@@ -197,3 +208,19 @@ async fn connect_insecure(addr: SocketAddr) -> Result<Box<dyn SessionBufStream>>
|
||||
let session_stream: Box<dyn SessionBufStream> = Box::new(buffered_stream);
|
||||
Ok(session_stream)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use tokio::io::BufReader;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn test_skip_smtp_greeting() -> Result<()> {
|
||||
let greeting = b"220-server261.web-hosting.com ESMTP Exim 4.96.2 #2 Sat, 24 Aug 2024 12:25:53 -0400 \r\n\
|
||||
220-We do not authorize the use of this system to transport unsolicited,\r\n\
|
||||
220 and/or bulk e-mail.\r\n";
|
||||
let mut buffered_stream = BufReader::new(&greeting[..]);
|
||||
skip_smtp_greeting(&mut buffered_stream).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +175,12 @@ impl TestContextManager {
|
||||
));
|
||||
|
||||
let qr = get_securejoin_qr(&scanned.ctx, None).await.unwrap();
|
||||
join_securejoin(&scanner.ctx, &qr).await.unwrap();
|
||||
self.exec_securejoin_qr(scanner, scanned, &qr).await;
|
||||
}
|
||||
|
||||
/// Executes SecureJoin initiated by `scanner` scanning `qr` generated by `scanned`.
|
||||
pub async fn exec_securejoin_qr(&self, scanner: &TestContext, scanned: &TestContext, qr: &str) {
|
||||
join_securejoin(&scanner.ctx, qr).await.unwrap();
|
||||
|
||||
loop {
|
||||
if let Some(sent) = scanner.pop_sent_msg_opt(Duration::ZERO).await {
|
||||
|
||||
Reference in New Issue
Block a user