From: Shannon Sterz <s.sterz@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox 1/3] sendmail: encode non-ascii filenames to improve compatability
Date: Tue, 2 Sep 2025 16:27:15 +0200 [thread overview]
Message-ID: <20250902142720.371671-2-s.sterz@proxmox.com> (raw)
In-Reply-To: <20250902142720.371671-1-s.sterz@proxmox.com>
otherwise some mail servers that do not support utf8 properly mail not
accept the email.
Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
proxmox-sendmail/src/lib.rs | 95 ++++++++++++++++++++++++++++++++++---
1 file changed, 89 insertions(+), 6 deletions(-)
diff --git a/proxmox-sendmail/src/lib.rs b/proxmox-sendmail/src/lib.rs
index 053fc98e..ebbcfe86 100644
--- a/proxmox-sendmail/src/lib.rs
+++ b/proxmox-sendmail/src/lib.rs
@@ -81,18 +81,23 @@ impl Attachment<'_> {
let mut attachment = String::new();
+ let encoded_filename = if self.filename.is_ascii() {
+ &self.filename
+ } else {
+ &format!("=?utf-8?B?{}?=", proxmox_base64::encode(&self.filename))
+ };
+
let _ = writeln!(attachment, "\n--{file_boundary}");
let _ = writeln!(
attachment,
- "Content-Type: {}; name=\"{}\"",
- self.mime, self.filename
+ "Content-Type: {}; name=\"{encoded_filename}\"",
+ self.mime,
);
// both `filename` and `filename*` are included for additional compatability
let _ = writeln!(
attachment,
- "Content-Disposition: attachment; filename=\"{}\"; filename*=UTF-8''{}",
- self.filename,
+ "Content-Disposition: attachment; filename=\"{encoded_filename}\"; filename*=UTF-8''{}",
utf8_percent_encode(&self.filename, RFC5987SET)
);
attachment.push_str("Content-Transfer-Encoding: base64\n\n");
@@ -804,8 +809,8 @@ Content-Transfer-Encoding: base64
3q2+796tvu/erb7v3q3erb7v3q2+796tvu/erd6tvu/erb7v3q2+796t3q2+796tvu/erb7v
3q2+796tvu8=
------_=_NextPart_001_1732806251
-Content-Type: image/bmp; name="🐄💀.bin"
-Content-Disposition: attachment; filename="🐄💀.bin"; filename*=UTF-8''%F0%9F%90%84%F0%9F%92%80.bin
+Content-Type: image/bmp; name="=?utf-8?B?8J+QhPCfkoAuYmlu?="
+Content-Disposition: attachment; filename="=?utf-8?B?8J+QhPCfkoAuYmlu?="; filename*=UTF-8''%F0%9F%90%84%F0%9F%92%80.bin
Content-Transfer-Encoding: base64
3q2+796tvu/erb7v3q3erb7v3q2+796tvu/erd6tvu/erb7v3q2+796t3q2+796tvu/erb7v
@@ -855,4 +860,82 @@ Content-Transfer-Encoding: 8bit
------_=_NextPart_002_1718977850--"#,
);
}
+
+ #[test]
+ fn multipart_plain_text_html_alternative_attachments_ascii_compat() {
+ let bin: [u8; 62] = [
+ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad,
+ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad,
+ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad,
+ 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad,
+ 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef,
+ ];
+
+ let mail = Mail::new(
+ "Sender Näme",
+ "from@example.com",
+ "Subject Linë",
+ "Lorem Ipsum Dolor Sit\nAmet",
+ )
+ .with_recipient_and_name("Receiver Näme", "receiver@example.com")
+ .with_attachment("deadbeef.bin", "application/octet-stream", &bin)
+ .with_attachment("🐄💀.bin", "image/bmp", &bin)
+ .with_html_alt("<html lang=\"de-at\"><head></head><body>\n\t<pre>\n\t\tLorem Ipsum Dolor Sit Amet\n\t</pre>\n</body></html>");
+
+ let body = mail.format_mail(1732806251).expect("could not format mail");
+
+ assert!(body.is_ascii());
+
+ assert_lines_equal_ignore_date(
+ &body,
+ r#"Content-Type: multipart/mixed;
+ boundary="----_=_NextPart_001_1732806251"
+MIME-Version: 1.0
+Subject: =?utf-8?B?U3ViamVjdCBMaW7Dqw==?=
+From: =?utf-8?B?U2VuZGVyIE7DpG1l?= <from@example.com>
+To: =?utf-8?B?UmVjZWl2ZXIgTsOkbWU=?= <receiver@example.com>
+Date: Thu, 28 Nov 2024 16:04:11 +0100
+Auto-Submitted: auto-generated;
+
+This is a multi-part message in MIME format.
+
+------_=_NextPart_001_1732806251
+Content-Type: multipart/alternative; boundary="----_=_NextPart_002_1732806251"
+MIME-Version: 1.0
+
+------_=_NextPart_002_1732806251
+Content-Type: text/plain;
+ charset="UTF-8"
+Content-Transfer-Encoding: 8bit
+
+Lorem Ipsum Dolor Sit
+Amet
+------_=_NextPart_002_1732806251
+Content-Type: text/html;
+ charset="UTF-8"
+Content-Transfer-Encoding: 8bit
+
+<html lang="de-at"><head></head><body>
+ <pre>
+ Lorem Ipsum Dolor Sit Amet
+ </pre>
+</body></html>
+------_=_NextPart_002_1732806251--
+------_=_NextPart_001_1732806251
+Content-Type: application/octet-stream; name="deadbeef.bin"
+Content-Disposition: attachment; filename="deadbeef.bin"; filename*=UTF-8''deadbeef.bin
+Content-Transfer-Encoding: base64
+
+3q2+796tvu/erb7v3q3erb7v3q2+796tvu/erd6tvu/erb7v3q2+796t3q2+796tvu/erb7v
+3q2+796tvu8=
+------_=_NextPart_001_1732806251
+Content-Type: image/bmp; name="=?utf-8?B?8J+QhPCfkoAuYmlu?="
+Content-Disposition: attachment; filename="=?utf-8?B?8J+QhPCfkoAuYmlu?="; filename*=UTF-8''%F0%9F%90%84%F0%9F%92%80.bin
+Content-Transfer-Encoding: base64
+
+3q2+796tvu/erb7v3q3erb7v3q2+796tvu/erd6tvu/erb7v3q2+796t3q2+796tvu/erb7v
+3q2+796tvu8=
+------_=_NextPart_001_1732806251--"#,
+ )
+ }
}
--
2.47.2
_______________________________________________
pbs-devel mailing list
pbs-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel
next prev parent reply other threads:[~2025-09-02 14:27 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-02 14:27 [pbs-devel] [PATCH proxmox 0/3] improve mail compatability Shannon Sterz
2025-09-02 14:27 ` Shannon Sterz [this message]
2025-09-02 14:27 ` [pbs-devel] [PATCH proxmox 2/3] sendmail: encode non-ascii bodies as base64 to improve comptability Shannon Sterz
2025-09-02 14:27 ` [pbs-devel] [PATCH proxmox 3/3] sendmail: break content disposition headers for attachments Shannon Sterz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250902142720.371671-2-s.sterz@proxmox.com \
--to=s.sterz@proxmox.com \
--cc=pbs-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox