melib/smtp: fix test smtp server logic
parent
d679a74450
commit
39d9c2af3b
|
@ -22,57 +22,55 @@
|
|||
#![allow(clippy::just_underscores_and_digits)]
|
||||
#![allow(clippy::needless_lifetimes)]
|
||||
|
||||
/*!
|
||||
* SMTP client support
|
||||
*
|
||||
* This module implements a client for the SMTP protocol as specified by [RFC 5321 Simple Mail
|
||||
* Transfer Protocol](https://www.rfc-editor.org/rfc/rfc5321).
|
||||
*
|
||||
* The connection and methods are `async` and uses the `smol` runtime.
|
||||
*# Example
|
||||
*
|
||||
*```not_run
|
||||
*extern crate melib;
|
||||
*
|
||||
*use melib::futures;
|
||||
*use melib::smol;
|
||||
*use melib::smtp::*;
|
||||
*use melib::Result;
|
||||
*let conf = SmtpServerConf {
|
||||
* hostname: "smtp.mail.gr".into(),
|
||||
* port: 587,
|
||||
* security: SmtpSecurity::StartTLS {
|
||||
* danger_accept_invalid_certs: false,
|
||||
* },
|
||||
* extensions: SmtpExtensionSupport::default(),
|
||||
* auth: SmtpAuth::Auto {
|
||||
* username: "l15".into(),
|
||||
* password: Password::CommandEval(
|
||||
* "gpg2 --no-tty -q -d ~/.passwords/mail.gpg".into(),
|
||||
* ),
|
||||
* require_auth: true,
|
||||
* },
|
||||
*};
|
||||
*
|
||||
*std::thread::Builder::new().spawn(move || {
|
||||
* let ex = smol::Executor::new();
|
||||
* futures::executor::block_on(ex.run(futures::future::pending::<()>()));
|
||||
*}).unwrap();
|
||||
*
|
||||
*let mut conn = futures::executor::block_on(SmtpConnection::new_connection(conf)).unwrap();
|
||||
*futures::executor::block_on(conn.mail_transaction(r#"To: l10@mail.gr
|
||||
*Subject: Fwd: SMTP TEST
|
||||
*From: Me <l15@mail.gr>
|
||||
*Message-Id: <E1hSjnr-0003fN-RL@pppppp>
|
||||
*Date: Mon, 13 Jul 2020 09:02:15 +0300
|
||||
*
|
||||
*Prescriptions-R-X"#,
|
||||
* b"l15@mail.gr",
|
||||
* b"l10@mail.gr",
|
||||
*)).unwrap();
|
||||
*Ok(())
|
||||
*```
|
||||
*/
|
||||
//! SMTP client support
|
||||
//!
|
||||
//! This module implements a client for the SMTP protocol as specified by [RFC 5321 Simple Mail
|
||||
//! Transfer Protocol](https://www.rfc-editor.org/rfc/rfc5321).
|
||||
//!
|
||||
//! The connection and methods are `async` and uses the `smol` runtime.
|
||||
//!# Example
|
||||
//!
|
||||
//! ```not_run
|
||||
//! extern crate melib;
|
||||
//!
|
||||
//! use melib::futures;
|
||||
//! use melib::smol;
|
||||
//! use melib::smtp::*;
|
||||
//! use melib::Result;
|
||||
//! let conf = SmtpServerConf {
|
||||
//! hostname: "smtp.example.com".into(),
|
||||
//! port: 587,
|
||||
//! security: SmtpSecurity::StartTLS {
|
||||
//! danger_accept_invalid_certs: false,
|
||||
//! },
|
||||
//! extensions: SmtpExtensionSupport::default(),
|
||||
//! auth: SmtpAuth::Auto {
|
||||
//! username: "l15".into(),
|
||||
//! password: Password::CommandEval(
|
||||
//! "gpg2 --no-tty -q -d ~/.passwords/mail.gpg".into(),
|
||||
//! ),
|
||||
//! require_auth: true,
|
||||
//! },
|
||||
//! };
|
||||
//!
|
||||
//! std::thread::Builder::new().spawn(move || {
|
||||
//! let ex = smol::Executor::new();
|
||||
//! futures::executor::block_on(ex.run(futures::future::pending::<()>()));
|
||||
//! }).unwrap();
|
||||
//!
|
||||
//! let mut conn = futures::executor::block_on(SmtpConnection::new_connection(conf)).unwrap();
|
||||
//! futures::executor::block_on(conn.mail_transaction(r#"To: l10@example.com
|
||||
//! Subject: Fwd: SMTP TEST
|
||||
//! From: Me <l15@example.com>
|
||||
//! Message-Id: <E1hSjnr-0003fN-RL@example.com>
|
||||
//! Date: Mon, 13 Jul 2020 09:02:15 +0300
|
||||
//!
|
||||
//! Prescriptions-R-X"#,
|
||||
//! b"l15@example.com",
|
||||
//! b"l10@example.com",
|
||||
//! )).unwrap();
|
||||
//! Ok(())
|
||||
//! ```
|
||||
|
||||
use crate::connections::{lookup_ipv4, Connection};
|
||||
use crate::email::{parser::BytesExt, Address, Envelope};
|
||||
|
@ -93,17 +91,17 @@ use std::process::Command;
|
|||
pub enum SmtpSecurity {
|
||||
#[serde(alias = "starttls", alias = "STARTTLS")]
|
||||
StartTLS {
|
||||
#[serde(default = "false_val")]
|
||||
#[serde(default = "crate::conf::false_val")]
|
||||
danger_accept_invalid_certs: bool,
|
||||
},
|
||||
#[serde(alias = "auto")]
|
||||
Auto {
|
||||
#[serde(default = "false_val")]
|
||||
#[serde(default = "crate::conf::false_val")]
|
||||
danger_accept_invalid_certs: bool,
|
||||
},
|
||||
#[serde(alias = "tls", alias = "TLS")]
|
||||
Tls {
|
||||
#[serde(default = "false_val")]
|
||||
#[serde(default = "crate::conf::false_val")]
|
||||
danger_accept_invalid_certs: bool,
|
||||
},
|
||||
#[serde(alias = "none")]
|
||||
|
@ -138,7 +136,7 @@ pub enum SmtpAuth {
|
|||
Auto {
|
||||
username: String,
|
||||
password: Password,
|
||||
#[serde(default = "true_val")]
|
||||
#[serde(default = "crate::conf::true_val")]
|
||||
require_auth: bool,
|
||||
#[serde(skip_serializing, skip_deserializing, default)]
|
||||
auth_type: SmtpAuthType,
|
||||
|
@ -146,7 +144,7 @@ pub enum SmtpAuth {
|
|||
#[serde(alias = "xoauth2")]
|
||||
XOAuth2 {
|
||||
token_command: String,
|
||||
#[serde(default = "true_val")]
|
||||
#[serde(default = "crate::conf::true_val")]
|
||||
require_auth: bool,
|
||||
},
|
||||
// md5, sasl, etc
|
||||
|
@ -158,14 +156,6 @@ pub struct SmtpAuthType {
|
|||
login: bool,
|
||||
}
|
||||
|
||||
const fn true_val() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
const fn false_val() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
impl SmtpAuth {
|
||||
fn require_auth(&self) -> bool {
|
||||
use SmtpAuth::*;
|
||||
|
@ -201,17 +191,17 @@ pub struct SmtpExtensionSupport {
|
|||
/// [RFC 6152: SMTP Service Extension for 8-bit MIME Transport](https://www.rfc-editor.org/rfc/rfc6152)
|
||||
#[serde(default = "crate::conf::true_val")]
|
||||
_8bitmime: bool,
|
||||
//Essentially, the PRDR extension to SMTP allows (but does not require) an SMTP server to
|
||||
//issue multiple responses after a message has been transferred, by mutual consent of the
|
||||
//client and server. SMTP clients that support the PRDR extension then use the expanded
|
||||
//responses as supplemental data to the responses that were received during the earlier
|
||||
//envelope exchange.
|
||||
/// Essentially, the PRDR extension to SMTP allows (but does not require) an SMTP server to
|
||||
/// issue multiple responses after a message has been transferred, by mutual consent of the
|
||||
/// client and server. SMTP clients that support the PRDR extension then use the expanded
|
||||
/// responses as supplemental data to the responses that were received during the earlier
|
||||
/// envelope exchange.
|
||||
#[serde(default = "crate::conf::true_val")]
|
||||
prdr: bool,
|
||||
#[serde(default = "crate::conf::true_val")]
|
||||
binarymime: bool,
|
||||
//Resources:
|
||||
//- http://www.postfix.org/SMTPUTF8_README.html
|
||||
/// Resources:
|
||||
/// - http://www.postfix.org/SMTPUTF8_README.html
|
||||
#[serde(default = "crate::conf::true_val")]
|
||||
smtputf8: bool,
|
||||
#[serde(default = "crate::conf::true_val")]
|
||||
|
@ -239,10 +229,10 @@ impl Default for SmtpExtensionSupport {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
/// SMTP client session object.
|
||||
///
|
||||
/// See module-wide documentation.
|
||||
#[derive(Debug)]
|
||||
pub struct SmtpConnection {
|
||||
stream: AsyncWrapper<Connection>,
|
||||
read_buffer: String,
|
||||
|
@ -543,6 +533,11 @@ impl SmtpConnection {
|
|||
Ok(ret)
|
||||
}
|
||||
|
||||
/// Set a new value for `envelope_from`.
|
||||
pub fn set_envelope_from(&mut self, envelope_from: String) {
|
||||
self.server_conf.envelope_from = envelope_from;
|
||||
}
|
||||
|
||||
fn set_extension_support(&mut self, reply: Reply<'_>) {
|
||||
debug_assert_eq!(reply.code, ReplyCode::_250);
|
||||
self.server_conf.extensions.pipelining &= reply.lines.contains(&"PIPELINING");
|
||||
|
@ -1081,6 +1076,7 @@ mod test {
|
|||
.lock()
|
||||
.unwrap()
|
||||
.iter_mut()
|
||||
.rev()
|
||||
.find(|((i, d), _)| (i, d.as_str()) == (&ip, domain))
|
||||
{
|
||||
std::dbg!(&message);
|
||||
|
@ -1157,9 +1153,8 @@ mod test {
|
|||
}
|
||||
|
||||
fn data_end(&mut self) -> Response {
|
||||
eprintln!("datae_nd() ");
|
||||
if let Some(((_, _), message)) = self.mails.lock().unwrap().pop() {
|
||||
if let Message::Data { from: _, to, buf } = message {
|
||||
let last = self.mails.lock().unwrap().pop();
|
||||
if let Some(((ip, domain), Message::Data { from: _, to, buf })) = last {
|
||||
for to in to {
|
||||
match crate::Envelope::from_bytes(&buf, None) {
|
||||
Ok(env) => {
|
||||
|
@ -1172,9 +1167,13 @@ mod test {
|
|||
}
|
||||
}
|
||||
}
|
||||
self.mails
|
||||
.lock()
|
||||
.unwrap()
|
||||
.push(((ip, domain), Message::Helo));
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
eprintln!("last self.mails item was not Message::Data: {last:?}");
|
||||
INTERNAL_ERROR
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue