Author:
Hash:
Timestamp:
+41 -18 +/-2 browse
Kevin Schoon [me@kevinschoon.com]
64e32fece4ecaf93dfd6ddb53e7775f4e3bbae79
Sun, 01 Sep 2024 21:39:46 +0000 (1.2 years ago)
| 1 | diff --git a/README.md b/README.md |
| 2 | index 0f6394c..0f79c33 100644 |
| 3 | --- a/README.md |
| 4 | +++ b/README.md |
| 5 | @@ -15,12 +15,20 @@ too complex to be reasonably packaged. |
| 6 | |
| 7 | ## Security |
| 8 | |
| 9 | + ### Relaying |
| 10 | + |
| 11 | Due to the common abuse of the SMTP protocol by nefarious internet actors the |
| 12 | default behavior of this package must _never_ allow open relaying without |
| 13 | explicit and conscious configuration from the user. Additionally the SMTP |
| 14 | server must never expose the e-mail addresses or other user data contained |
| 15 | within. |
| 16 | |
| 17 | + ### TLS |
| 18 | + |
| 19 | + This library does not implement any TLS termination nor does it allow for |
| 20 | + STARTTLS upgrades. The recommended production setting is to use an SMTP proxy |
| 21 | + server like Nginx to terminate TLS there. |
| 22 | + |
| 23 | ## Alpha Status |
| 24 | |
| 25 | NOTE: This library is at best in an "alpha" state currently and should be used |
| 26 | @@ -30,17 +38,17 @@ for _absolutely nothing_ that is important. |
| 27 | |
| 28 | ### SMTP Base server and Commands [RFC5321](rfcs/rfc5321.txt) |
| 29 | |
| 30 | - | Name | Status | Notes | |
| 31 | - |-----------|--------|----------| |
| 32 | - | HELO | ✅ | | |
| 33 | - | EHLO | ✅ | | |
| 34 | - | MAIL | ✅ | | |
| 35 | - | RCPT | ✅ | | |
| 36 | - | BDAT | ✅ | | |
| 37 | - | DATA | ✅ | | |
| 38 | - | AUTH | ❌ | No authentication mechanisms currently supported | |
| 39 | - | VRFY | ✅ | | |
| 40 | - | EXPN | ✅ | | |
| 41 | + | Name | Status | Notes | |
| 42 | + |-----------|--------|------------------------| |
| 43 | + | HELO | ✅ | | |
| 44 | + | EHLO | ✅ | | |
| 45 | + | MAIL | ✅ | | |
| 46 | + | RCPT | ✅ | | |
| 47 | + | BDAT | ✅ | | |
| 48 | + | DATA | ✅ | | |
| 49 | + | AUTH | ✅ | SASL PLAIN only | |
| 50 | + | VRFY | ✅ | | |
| 51 | + | EXPN | ✅ | | |
| 52 | | STARTTLS | ❌ | For the moment there is no plan to implement STARTTLS | |
| 53 | |
| 54 | |
| 55 | @@ -55,6 +63,9 @@ for _absolutely nothing_ that is important. |
| 56 | | SMTPUTF8 | TODO | [RFC6531](rfcs/rfc6531.txt) | |
| 57 | | CHUNKING | TODO | [RFC3030](rfcs/rfc3030.txt) | |
| 58 | | DSN | TODO | [RFC3461](rfcs/rfc3461.txt) | |
| 59 | + | ETRN | ❌ | [RFC1985](rfcs/rfc1985.txt) | |
| 60 | + | ATRN | ❌ | RFC2645 | |
| 61 | + | BURL | ❌ | RFC4468 | |
| 62 | |
| 63 | ## Attributions |
| 64 | |
| 65 | diff --git a/maitred/src/session.rs b/maitred/src/session.rs |
| 66 | index e9924e2..c5486b7 100644 |
| 67 | --- a/maitred/src/session.rs |
| 68 | +++ b/maitred/src/session.rs |
| 69 | @@ -29,7 +29,6 @@ pub const DEFAULT_MAXIMUM_MESSAGE_SIZE: u64 = 5_000_000; |
| 70 | pub const DEFAULT_GREETING: &str = "Maitred ESMTP Server"; |
| 71 | |
| 72 | // TODO: |
| 73 | - // 250-ETRN |
| 74 | // 250-8BITMIME |
| 75 | // 250-DSN |
| 76 | // 250-SMTPUTF8 |
| 77 | @@ -44,11 +43,13 @@ pub const DEFAULT_CAPABILITIES: u32 = smtp_proto::EXT_SIZE |
| 78 | /// level error that will be returned to the client. |
| 79 | pub type Result = StdResult<Vec<Response<String>>, Response<String>>; |
| 80 | |
| 81 | + /// If the session was started with HELO or ELHO. |
| 82 | enum Mode { |
| 83 | Legacy, |
| 84 | Extended, |
| 85 | } |
| 86 | |
| 87 | + /// Type of data transfer mode in use. |
| 88 | enum DataTransfer { |
| 89 | Data, |
| 90 | Bdat, |
| 91 | @@ -315,8 +316,9 @@ impl Session { |
| 92 | Ok(vec![Response::Ehlo(resp)]) |
| 93 | } |
| 94 | Request::Lhlo { host } => { |
| 95 | - self.hostname = |
| 96 | - Some(Host::parse(&parse_host(host)).map_err(|e| smtp_response!(500, 0, 0, 0, e))?); |
| 97 | + self.hostname = Some( |
| 98 | + Host::parse(&parse_host(host)).map_err(|e| smtp_response!(500, 0, 0, 0, e))?, |
| 99 | + ); |
| 100 | self.reset(); |
| 101 | self.initialized = Some(Mode::Legacy); |
| 102 | Ok(vec![smtp_response!( |
| 103 | @@ -472,10 +474,20 @@ impl Session { |
| 104 | )) |
| 105 | } |
| 106 | } |
| 107 | - Request::Etrn { name } => todo!(), |
| 108 | - Request::Atrn { domains } => todo!(), |
| 109 | - Request::Burl { uri, is_last } => todo!(), |
| 110 | - Request::StartTls => todo!(), |
| 111 | + Request::Etrn { name: _ } => Err(smtp_response!(500, 0, 0, 0, "ETRN is not supported")), |
| 112 | + Request::Atrn { domains: _ } => { |
| 113 | + Err(smtp_response!(500, 0, 0, 0, "ATRN is not supported")) |
| 114 | + } |
| 115 | + Request::Burl { uri: _, is_last: _ } => { |
| 116 | + Err(smtp_response!(500, 0, 0, 0, "BURL is not supported")) |
| 117 | + } |
| 118 | + Request::StartTls => Err(smtp_response!( |
| 119 | + 500, |
| 120 | + 0, |
| 121 | + 0, |
| 122 | + 0, |
| 123 | + format!("STARTTLS is not supported") |
| 124 | + )), |
| 125 | Request::Data => { |
| 126 | self.check_initialized()?; |
| 127 | tracing::info!("Initializing data transfer mode"); |