Commit
+218 -22 +/-7 browse
1 | diff --git a/Cargo.lock b/Cargo.lock |
2 | index 14f2435..25f2088 100644 |
3 | --- a/Cargo.lock |
4 | +++ b/Cargo.lock |
5 | @@ -949,7 +949,9 @@ dependencies = [ |
6 | "clap", |
7 | "futures", |
8 | "maitred", |
9 | + "serde", |
10 | "tokio", |
11 | + "toml", |
12 | "tracing", |
13 | "tracing-subscriber", |
14 | ] |
15 | @@ -1306,18 +1308,18 @@ dependencies = [ |
16 | |
17 | [[package]] |
18 | name = "serde" |
19 | - version = "1.0.204" |
20 | + version = "1.0.209" |
21 | source = "registry+https://github.com/rust-lang/crates.io-index" |
22 | - checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" |
23 | + checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" |
24 | dependencies = [ |
25 | "serde_derive", |
26 | ] |
27 | |
28 | [[package]] |
29 | name = "serde_derive" |
30 | - version = "1.0.204" |
31 | + version = "1.0.209" |
32 | source = "registry+https://github.com/rust-lang/crates.io-index" |
33 | - checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" |
34 | + checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" |
35 | dependencies = [ |
36 | "proc-macro2", |
37 | "quote", |
38 | @@ -1337,6 +1339,15 @@ dependencies = [ |
39 | ] |
40 | |
41 | [[package]] |
42 | + name = "serde_spanned" |
43 | + version = "0.6.7" |
44 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
45 | + checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" |
46 | + dependencies = [ |
47 | + "serde", |
48 | + ] |
49 | + |
50 | + [[package]] |
51 | name = "sha1" |
52 | version = "0.10.6" |
53 | source = "registry+https://github.com/rust-lang/crates.io-index" |
54 | @@ -1584,6 +1595,40 @@ dependencies = [ |
55 | ] |
56 | |
57 | [[package]] |
58 | + name = "toml" |
59 | + version = "0.8.19" |
60 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
61 | + checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" |
62 | + dependencies = [ |
63 | + "serde", |
64 | + "serde_spanned", |
65 | + "toml_datetime", |
66 | + "toml_edit", |
67 | + ] |
68 | + |
69 | + [[package]] |
70 | + name = "toml_datetime" |
71 | + version = "0.6.8" |
72 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
73 | + checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" |
74 | + dependencies = [ |
75 | + "serde", |
76 | + ] |
77 | + |
78 | + [[package]] |
79 | + name = "toml_edit" |
80 | + version = "0.22.20" |
81 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
82 | + checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" |
83 | + dependencies = [ |
84 | + "indexmap", |
85 | + "serde", |
86 | + "serde_spanned", |
87 | + "toml_datetime", |
88 | + "winnow", |
89 | + ] |
90 | + |
91 | + [[package]] |
92 | name = "tracing" |
93 | version = "0.1.40" |
94 | source = "registry+https://github.com/rust-lang/crates.io-index" |
95 | @@ -1954,6 +1999,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" |
96 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" |
97 | |
98 | [[package]] |
99 | + name = "winnow" |
100 | + version = "0.6.18" |
101 | + source = "registry+https://github.com/rust-lang/crates.io-index" |
102 | + checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" |
103 | + dependencies = [ |
104 | + "memchr", |
105 | + ] |
106 | + |
107 | + [[package]] |
108 | name = "winreg" |
109 | version = "0.50.0" |
110 | source = "registry+https://github.com/rust-lang/crates.io-index" |
111 | diff --git a/cmd/maitred-debug/Cargo.toml b/cmd/maitred-debug/Cargo.toml |
112 | index 9792cd0..973dda8 100644 |
113 | --- a/cmd/maitred-debug/Cargo.toml |
114 | +++ b/cmd/maitred-debug/Cargo.toml |
115 | @@ -8,7 +8,9 @@ clap = { version = "4.5.16", features = ["derive"] } |
116 | futures = "0.3.30" |
117 | |
118 | maitred = {path = "../../maitred"} |
119 | + serde = "1.0.209" |
120 | tokio = { version = "1.39.2", features = ["full"] } |
121 | + toml = "0.8.19" |
122 | tracing = { version = "0.1.40", features = ["log"] } |
123 | tracing-subscriber = "0.3.18" |
124 | |
125 | diff --git a/cmd/maitred-debug/src/main.rs b/cmd/maitred-debug/src/main.rs |
126 | index 5a2d19b..e8e4382 100644 |
127 | --- a/cmd/maitred-debug/src/main.rs |
128 | +++ b/cmd/maitred-debug/src/main.rs |
129 | @@ -1,15 +1,13 @@ |
130 | - use std::{ |
131 | - path::{Path, PathBuf}, |
132 | - sync::Arc, |
133 | - }; |
134 | + use std::fs::read_to_string; |
135 | + use std::path::{Path, PathBuf}; |
136 | |
137 | use clap::Parser; |
138 | - use tokio::sync::{Mutex, RwLock}; |
139 | + use toml::from_str; |
140 | use tracing::Level; |
141 | |
142 | use maitred::{ |
143 | - mail_parser::Message, Delivery, DeliveryError, DeliveryFunc, Envelope, Error, Maildir, |
144 | - MilterFunc, PlainAuthFunc, Server, SessionOptions, |
145 | + mail_parser::Message, Delivery, DeliveryError, DeliveryFunc, Envelope, Maildir, MilterFunc, |
146 | + PlainAuthFunc, Server, SessionOptions, |
147 | }; |
148 | |
149 | async fn print_message(envelope: &Envelope) -> Result<(), DeliveryError> { |
150 | @@ -20,8 +18,27 @@ async fn print_message(envelope: &Envelope) -> Result<(), DeliveryError> { |
151 | Ok(()) |
152 | } |
153 | |
154 | + #[derive(Clone, serde::Deserialize)] |
155 | + struct Account { |
156 | + pub address: String, |
157 | + } |
158 | + |
159 | + #[derive(serde::Deserialize)] |
160 | + struct Config { |
161 | + pub maildir: String, |
162 | + pub accounts: Vec<Account>, |
163 | + } |
164 | + |
165 | + const LONG_ABOUT: &str = r#" |
166 | + Maitred SMTP Demo Server |
167 | + |
168 | + NOTE: This tool only exists for illustrative purposes and should not be |
169 | + considered stable or suitable for a production environment. |
170 | + "#; |
171 | + |
172 | + /// Maitred SMTP Demo Server |
173 | #[derive(Parser, Debug)] |
174 | - #[clap(author, version, about, long_about = None)] |
175 | + #[clap(author, version, about, long_about = LONG_ABOUT)] |
176 | struct Args { |
177 | /// Enable DKIM verification of incoming e-mail. |
178 | #[clap(long, default_value_t = false)] |
179 | @@ -30,24 +47,29 @@ struct Args { |
180 | #[clap(long, default_value_t = false)] |
181 | spf: bool, |
182 | /// Addresses from which to accept e-mail for |
183 | - #[clap(long)] |
184 | - addresses: Vec<String>, |
185 | - /// Path to a directory to store e-mails in the maildir format |
186 | - #[clap(long, default_value_t = String::from("mail"))] |
187 | - maildir: String, |
188 | + #[clap(long, default_value = "maitred.toml")] |
189 | + config: String, |
190 | } |
191 | |
192 | #[tokio::main] |
193 | - async fn main() -> Result<(), Error> { |
194 | + async fn main() -> Result<(), Box<dyn std::error::Error>> { |
195 | let args = Args::parse(); |
196 | + let config_str = read_to_string(Path::new(&args.config))?; |
197 | + let config: Config = from_str(&config_str)?; |
198 | // Create a subscriber that logs events to the console |
199 | tracing_subscriber::fmt() |
200 | .compact() |
201 | .with_line_number(true) |
202 | .with_max_level(Level::DEBUG) |
203 | .init(); |
204 | - let maildir_path = PathBuf::from(&args.maildir); |
205 | - let addresses = args.addresses.clone(); |
206 | + let maildir_path = PathBuf::from(&config.maildir); |
207 | + let accounts = config.accounts.clone(); |
208 | + let addresses: Vec<String> = accounts |
209 | + .iter() |
210 | + .map(|account| account.address.clone()) |
211 | + .collect(); |
212 | + // initialize maildirs before starting |
213 | + let _ = Maildir::new(maildir_path.as_path(), &addresses)?; |
214 | // Set the subscriber as the default subscriber |
215 | let mut mail_server = Server::default() |
216 | .address("127.0.0.1:2525") |
217 | @@ -61,7 +83,7 @@ async fn main() -> Result<(), Error> { |
218 | let cloned = envelope.clone(); |
219 | async move { |
220 | print_message(&cloned).await?; |
221 | - let maildir = Maildir::new(maildir_path.as_path(), addresses.as_slice())?; |
222 | + let maildir = Maildir::new(maildir_path.as_path(), &addresses)?; |
223 | maildir.deliver(&cloned).await |
224 | } |
225 | })) |
226 | diff --git a/demo/user-1.neomuttrc b/demo/user-1.neomuttrc |
227 | new file mode 100644 |
228 | index 0000000..9974613 |
229 | --- /dev/null |
230 | +++ b/demo/user-1.neomuttrc |
231 | @@ -0,0 +1,51 @@ |
232 | + # vim: set filetype=neomuttrc : |
233 | + |
234 | + set mbox_type=Maildir |
235 | + set folder="mail/demo-1@example.org" |
236 | + set spoolfile=+ |
237 | + |
238 | + set realname = 'Demo User 1' |
239 | + set from = demo-1@example.org |
240 | + |
241 | + set smtp_url=smtp://demo-1@127.0.0.1:2525 |
242 | + set ssl_starttls = no |
243 | + set ssl_force_tls = false |
244 | + |
245 | + set sidebar_visible |
246 | + set sidebar_format = "%B%<F? [%F]>%* %<N?%N/>%S" |
247 | + # set mail_check_stats |
248 | + |
249 | + color normal default default # Text is "Text" |
250 | + color index color2 default ~N # New Messages are Green |
251 | + color index color1 default ~F # Flagged messages are Red |
252 | + color index color13 default ~T # Tagged Messages are Red |
253 | + color index color1 default ~D # Messages to delete are Red |
254 | + color attachment color5 default # Attachments are Pink |
255 | + color signature color8 default # Signatures are Surface 2 |
256 | + color search color4 default # Highlighted results are Blue |
257 | + |
258 | + color indicator default color8 # currently highlighted message Surface 2=Background Text=Foreground |
259 | + color error color1 default # error messages are Red |
260 | + color status color15 default # status line "Subtext 0" |
261 | + color tree color15 default # thread tree arrows Subtext 0 |
262 | + color tilde color15 default # blank line padding Subtext 0 |
263 | + |
264 | + color hdrdefault color13 default # default headers Pink |
265 | + color header color13 default "^From:" |
266 | + color header color13 default "^Subject:" |
267 | + |
268 | + color quoted color15 default # Subtext 0 |
269 | + color quoted1 color7 default # Subtext 1 |
270 | + color quoted2 color8 default # Surface 2 |
271 | + color quoted3 color0 default # Surface 1 |
272 | + color quoted4 color0 default |
273 | + color quoted5 color0 default |
274 | + |
275 | + color body color2 default [\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+ # email addresses Green |
276 | + color body color2 default (https?|ftp)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+ # URLs Green |
277 | + color body color4 default (^|[[:space:]])\\*[^[:space:]]+\\*([[:space:]]|$) # *bold* text Blue |
278 | + color body color4 default (^|[[:space:]])_[^[:space:]]+_([[:space:]]|$) # _underlined_ text Blue |
279 | + color body color4 default (^|[[:space:]])/[^[:space:]]+/([[:space:]]|$) # /italic/ text Blue |
280 | + |
281 | + color sidebar_flagged color1 default # Mailboxes with flagged mails are Red |
282 | + color sidebar_new color10 default # Mailboxes with new mail are Green |
283 | diff --git a/demo/user-2.neomuttrc b/demo/user-2.neomuttrc |
284 | new file mode 100644 |
285 | index 0000000..fda07f0 |
286 | --- /dev/null |
287 | +++ b/demo/user-2.neomuttrc |
288 | @@ -0,0 +1,51 @@ |
289 | + # vim: set filetype=neomuttrc : |
290 | + |
291 | + set mbox_type=Maildir |
292 | + set folder="mail/demo-2@example.org" |
293 | + set spoolfile=+ |
294 | + |
295 | + set realname = 'kevin' |
296 | + set from = kevin@ayllu-dev.local |
297 | + |
298 | + set smtp_url=smtp://kevin@127.0.0.1:2525 |
299 | + set ssl_starttls = no |
300 | + set ssl_force_tls = false |
301 | + |
302 | + set sidebar_visible |
303 | + set sidebar_format = "%B%<F? [%F]>%* %<N?%N/>%S" |
304 | + # set mail_check_stats |
305 | + |
306 | + color normal default default # Text is "Text" |
307 | + color index color2 default ~N # New Messages are Green |
308 | + color index color1 default ~F # Flagged messages are Red |
309 | + color index color13 default ~T # Tagged Messages are Red |
310 | + color index color1 default ~D # Messages to delete are Red |
311 | + color attachment color5 default # Attachments are Pink |
312 | + color signature color8 default # Signatures are Surface 2 |
313 | + color search color4 default # Highlighted results are Blue |
314 | + |
315 | + color indicator default color8 # currently highlighted message Surface 2=Background Text=Foreground |
316 | + color error color1 default # error messages are Red |
317 | + color status color15 default # status line "Subtext 0" |
318 | + color tree color15 default # thread tree arrows Subtext 0 |
319 | + color tilde color15 default # blank line padding Subtext 0 |
320 | + |
321 | + color hdrdefault color13 default # default headers Pink |
322 | + color header color13 default "^From:" |
323 | + color header color13 default "^Subject:" |
324 | + |
325 | + color quoted color15 default # Subtext 0 |
326 | + color quoted1 color7 default # Subtext 1 |
327 | + color quoted2 color8 default # Surface 2 |
328 | + color quoted3 color0 default # Surface 1 |
329 | + color quoted4 color0 default |
330 | + color quoted5 color0 default |
331 | + |
332 | + color body color2 default [\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+ # email addresses Green |
333 | + color body color2 default (https?|ftp)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+ # URLs Green |
334 | + color body color4 default (^|[[:space:]])\\*[^[:space:]]+\\*([[:space:]]|$) # *bold* text Blue |
335 | + color body color4 default (^|[[:space:]])_[^[:space:]]+_([[:space:]]|$) # _underlined_ text Blue |
336 | + color body color4 default (^|[[:space:]])/[^[:space:]]+/([[:space:]]|$) # /italic/ text Blue |
337 | + |
338 | + color sidebar_flagged color1 default # Mailboxes with flagged mails are Red |
339 | + color sidebar_new color10 default # Mailboxes with new mail are Green |
340 | diff --git a/maitred.toml b/maitred.toml |
341 | new file mode 100644 |
342 | index 0000000..0fcf4e1 |
343 | --- /dev/null |
344 | +++ b/maitred.toml |
345 | @@ -0,0 +1,9 @@ |
346 | + # Path of the directory to deliver mail in the "maildir" format to |
347 | + maildir = "mail" |
348 | + |
349 | + # List of user accounts and their hard coded username / passwords |
350 | + [[accounts]] |
351 | + address = "demo-1@example.org" |
352 | + |
353 | + [[accounts]] |
354 | + address = "demo-2@example.org" |
355 | diff --git a/scripts/swaks_test.sh b/scripts/swaks_test.sh |
356 | index e73450b..78c933b 100755 |
357 | --- a/scripts/swaks_test.sh |
358 | +++ b/scripts/swaks_test.sh |
359 | @@ -3,4 +3,11 @@ |
360 | # Uses swaks: https://www.jetmore.org/john/code/swaks/ to do some basic SMTP |
361 | # verification. Make sure you install the tool first! |
362 | |
363 | - printf "Subject: Hello\nWorld\n" | swaks --to hello@example.com --server localhost:2525 --pipeline --data - |
364 | + make_email() { |
365 | + printf "From: aaaa@example.org\n" |
366 | + printf "To: hello@example.org\n" |
367 | + printf "Subject: Hello\n" |
368 | + printf "World\n" |
369 | + } |
370 | + |
371 | + make_email | swaks --to hello@example.org --server localhost:2525 --pipeline --data - |