mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 12:56:30 +03:00
[wip, doesn't compile] refactor: exctract add_headers_to_encrypted_part() and set_content_type_to_encrypted() functions
This commit is contained in:
@@ -1025,35 +1025,13 @@ impl MimeFactory {
|
|||||||
.get_config_bool(Config::StdHeaderProtectionComposing)
|
.get_config_bool(Config::StdHeaderProtectionComposing)
|
||||||
.await?;
|
.await?;
|
||||||
let outer_message = if let Some(encryption_pubkeys) = self.encryption_pubkeys {
|
let outer_message = if let Some(encryption_pubkeys) = self.encryption_pubkeys {
|
||||||
// Store protected headers in the inner message.
|
let mut message = add_headers_to_encrypted_part(
|
||||||
let message = protected_headers
|
message,
|
||||||
.into_iter()
|
&unprotected_headers,
|
||||||
.fold(message, |message, (header, value)| {
|
hidden_headers,
|
||||||
message.header(header, value)
|
protected_headers,
|
||||||
});
|
use_std_header_protection,
|
||||||
|
);
|
||||||
// Add hidden headers to encrypted payload.
|
|
||||||
let mut message: MimePart<'static> = hidden_headers
|
|
||||||
.into_iter()
|
|
||||||
.fold(message, |message, (header, value)| {
|
|
||||||
message.header(header, value)
|
|
||||||
});
|
|
||||||
|
|
||||||
if use_std_header_protection {
|
|
||||||
message = unprotected_headers
|
|
||||||
.iter()
|
|
||||||
// Structural headers shouldn't be added as "HP-Outer". They are defined in
|
|
||||||
// <https://www.rfc-editor.org/rfc/rfc9787.html#structural-header-fields>.
|
|
||||||
.filter(|(name, _)| {
|
|
||||||
!(name.eq_ignore_ascii_case("mime-version")
|
|
||||||
|| name.eq_ignore_ascii_case("content-type")
|
|
||||||
|| name.eq_ignore_ascii_case("content-transfer-encoding")
|
|
||||||
|| name.eq_ignore_ascii_case("content-disposition"))
|
|
||||||
})
|
|
||||||
.fold(message, |message, (name, value)| {
|
|
||||||
message.header(format!("HP-Outer: {name}"), value.clone())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add gossip headers in chats with multiple recipients
|
// Add gossip headers in chats with multiple recipients
|
||||||
let multiple_recipients =
|
let multiple_recipients =
|
||||||
@@ -1144,21 +1122,6 @@ impl MimeFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the appropriate Content-Type for the inner message.
|
|
||||||
for (h, v) in &mut message.headers {
|
|
||||||
if h == "Content-Type"
|
|
||||||
&& let mail_builder::headers::HeaderType::ContentType(ct) = v
|
|
||||||
{
|
|
||||||
let mut ct_new = ct.clone();
|
|
||||||
ct_new = ct_new.attribute("protected-headers", "v1");
|
|
||||||
if use_std_header_protection {
|
|
||||||
ct_new = ct_new.attribute("hp", "cipher");
|
|
||||||
}
|
|
||||||
*ct = ct_new;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable compression for SecureJoin to ensure
|
// Disable compression for SecureJoin to ensure
|
||||||
// there are no compression side channels
|
// there are no compression side channels
|
||||||
// leaking information about the tokens.
|
// leaking information about the tokens.
|
||||||
@@ -1241,35 +1204,7 @@ impl MimeFactory {
|
|||||||
.await?
|
.await?
|
||||||
};
|
};
|
||||||
|
|
||||||
// XXX: additional newline is needed
|
set_content_type_to_encrypted(encrypted)
|
||||||
// to pass filtermail at
|
|
||||||
// <https://github.com/deltachat/chatmail/blob/4d915f9800435bf13057d41af8d708abd34dbfa8/chatmaild/src/chatmaild/filtermail.py#L84-L86>:
|
|
||||||
let encrypted = encrypted + "\n";
|
|
||||||
|
|
||||||
// Set the appropriate Content-Type for the outer message
|
|
||||||
MimePart::new(
|
|
||||||
"multipart/encrypted; protocol=\"application/pgp-encrypted\"",
|
|
||||||
vec![
|
|
||||||
// Autocrypt part 1
|
|
||||||
MimePart::new("application/pgp-encrypted", "Version: 1\r\n").header(
|
|
||||||
"Content-Description",
|
|
||||||
mail_builder::headers::raw::Raw::new("PGP/MIME version identification"),
|
|
||||||
),
|
|
||||||
// Autocrypt part 2
|
|
||||||
MimePart::new(
|
|
||||||
"application/octet-stream; name=\"encrypted.asc\"",
|
|
||||||
encrypted,
|
|
||||||
)
|
|
||||||
.header(
|
|
||||||
"Content-Description",
|
|
||||||
mail_builder::headers::raw::Raw::new("OpenPGP encrypted message"),
|
|
||||||
)
|
|
||||||
.header(
|
|
||||||
"Content-Disposition",
|
|
||||||
mail_builder::headers::raw::Raw::new("inline; filename=\"encrypted.asc\";"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
} else if matches!(self.loaded, Loaded::Mdn { .. }) {
|
} else if matches!(self.loaded, Loaded::Mdn { .. }) {
|
||||||
// Never add outer multipart/mixed wrapper to MDN
|
// Never add outer multipart/mixed wrapper to MDN
|
||||||
// as multipart/report Content-Type is used to recognize MDNs
|
// as multipart/report Content-Type is used to recognize MDNs
|
||||||
@@ -1976,6 +1911,93 @@ impl MimeFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the appropriate Content-Type for the outer message
|
||||||
|
fn set_content_type_to_encrypted(encrypted: String) -> MimePart<'static> {
|
||||||
|
// XXX: additional newline is needed
|
||||||
|
// to pass filtermail at
|
||||||
|
// <https://github.com/deltachat/chatmail/blob/4d915f9800435bf13057d41af8d708abd34dbfa8/chatmaild/src/chatmaild/filtermail.py#L84-L86>:
|
||||||
|
let encrypted = encrypted + "\n";
|
||||||
|
|
||||||
|
MimePart::new(
|
||||||
|
"multipart/encrypted; protocol=\"application/pgp-encrypted\"",
|
||||||
|
vec![
|
||||||
|
// Autocrypt part 1
|
||||||
|
MimePart::new("application/pgp-encrypted", "Version: 1\r\n").header(
|
||||||
|
"Content-Description",
|
||||||
|
mail_builder::headers::raw::Raw::new("PGP/MIME version identification"),
|
||||||
|
),
|
||||||
|
// Autocrypt part 2
|
||||||
|
MimePart::new(
|
||||||
|
"application/octet-stream; name=\"encrypted.asc\"",
|
||||||
|
encrypted,
|
||||||
|
)
|
||||||
|
.header(
|
||||||
|
"Content-Description",
|
||||||
|
mail_builder::headers::raw::Raw::new("OpenPGP encrypted message"),
|
||||||
|
)
|
||||||
|
.header(
|
||||||
|
"Content-Disposition",
|
||||||
|
mail_builder::headers::raw::Raw::new("inline; filename=\"encrypted.asc\";"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_headers_to_encrypted_part(
|
||||||
|
message: MimePart<'static>,
|
||||||
|
unprotected_headers: &[(&'static str, HeaderType<'static>)],
|
||||||
|
hidden_headers: Vec<(&'static str, HeaderType<'static>)>,
|
||||||
|
protected_headers: Vec<(&'static str, HeaderType<'static>)>,
|
||||||
|
use_std_header_protection: bool,
|
||||||
|
) -> MimePart<'static> {
|
||||||
|
// Store protected headers in the inner message.
|
||||||
|
let message = protected_headers
|
||||||
|
.into_iter()
|
||||||
|
.fold(message, |message, (header, value)| {
|
||||||
|
message.header(header, value)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add hidden headers to encrypted payload.
|
||||||
|
let mut message: MimePart<'static> = hidden_headers
|
||||||
|
.into_iter()
|
||||||
|
.fold(message, |message, (header, value)| {
|
||||||
|
message.header(header, value)
|
||||||
|
});
|
||||||
|
|
||||||
|
if use_std_header_protection {
|
||||||
|
message = unprotected_headers
|
||||||
|
.iter()
|
||||||
|
// Structural headers shouldn't be added as "HP-Outer". They are defined in
|
||||||
|
// <https://www.rfc-editor.org/rfc/rfc9787.html#structural-header-fields>.
|
||||||
|
.filter(|(name, _)| {
|
||||||
|
!(name.eq_ignore_ascii_case("mime-version")
|
||||||
|
|| name.eq_ignore_ascii_case("content-type")
|
||||||
|
|| name.eq_ignore_ascii_case("content-transfer-encoding")
|
||||||
|
|| name.eq_ignore_ascii_case("content-disposition"))
|
||||||
|
})
|
||||||
|
.fold(message, |message, (name, value)| {
|
||||||
|
message.header(format!("HP-Outer: {name}"), value.clone())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the appropriate Content-Type for the inner message
|
||||||
|
for (h, v) in &mut message.headers {
|
||||||
|
if h == "Content-Type"
|
||||||
|
&& let mail_builder::headers::HeaderType::ContentType(ct) = v
|
||||||
|
{
|
||||||
|
let mut ct_new = ct.clone();
|
||||||
|
ct_new = ct_new.attribute("protected-headers", "v1");
|
||||||
|
if use_std_header_protection {
|
||||||
|
ct_new = ct_new.attribute("hp", "cipher");
|
||||||
|
}
|
||||||
|
*ct = ct_new;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
message
|
||||||
|
}
|
||||||
|
|
||||||
struct HeadersByConfidentiality {
|
struct HeadersByConfidentiality {
|
||||||
/// Headers that must go into IMF header section.
|
/// Headers that must go into IMF header section.
|
||||||
///
|
///
|
||||||
@@ -2321,46 +2343,14 @@ pub(crate) async fn render_symm_encrypted_securejoin_message(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let outer_message = {
|
let outer_message = {
|
||||||
// Store protected headers in the inner message.
|
let use_std_header_protection = true;
|
||||||
let message = protected_headers
|
let mut message = add_headers_to_encrypted_part(
|
||||||
.into_iter()
|
message,
|
||||||
.fold(message, |message, (header, value)| {
|
&unprotected_headers,
|
||||||
message.header(header, value)
|
hidden_headers,
|
||||||
});
|
protected_headers,
|
||||||
|
use_std_header_protection,
|
||||||
// Add hidden headers to encrypted payload.
|
);
|
||||||
let mut message: MimePart<'static> = hidden_headers
|
|
||||||
.into_iter()
|
|
||||||
.fold(message, |message, (header, value)| {
|
|
||||||
message.header(header, value)
|
|
||||||
});
|
|
||||||
|
|
||||||
message = unprotected_headers
|
|
||||||
.iter()
|
|
||||||
// Structural headers shouldn't be added as "HP-Outer". They are defined in
|
|
||||||
// <https://www.rfc-editor.org/rfc/rfc9787.html#structural-header-fields>.
|
|
||||||
.filter(|(name, _)| {
|
|
||||||
!(name.eq_ignore_ascii_case("mime-version")
|
|
||||||
|| name.eq_ignore_ascii_case("content-type")
|
|
||||||
|| name.eq_ignore_ascii_case("content-transfer-encoding")
|
|
||||||
|| name.eq_ignore_ascii_case("content-disposition"))
|
|
||||||
})
|
|
||||||
.fold(message, |message, (name, value)| {
|
|
||||||
message.header(format!("HP-Outer: {name}"), value.clone())
|
|
||||||
});
|
|
||||||
|
|
||||||
// Set the appropriate Content-Type for the inner message.
|
|
||||||
for (h, v) in &mut message.headers {
|
|
||||||
if h == "Content-Type"
|
|
||||||
&& let mail_builder::headers::HeaderType::ContentType(ct) = v
|
|
||||||
{
|
|
||||||
let mut ct_new = ct.clone();
|
|
||||||
ct_new = ct_new.attribute("protected-headers", "v1");
|
|
||||||
ct_new = ct_new.attribute("hp", "cipher");
|
|
||||||
*ct = ct_new;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable compression for SecureJoin to ensure
|
// Disable compression for SecureJoin to ensure
|
||||||
// there are no compression side channels
|
// there are no compression side channels
|
||||||
@@ -2377,35 +2367,7 @@ pub(crate) async fn render_symm_encrypted_securejoin_message(
|
|||||||
.encrypt_symmetrically(context, auth, message, compress)
|
.encrypt_symmetrically(context, auth, message, compress)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// XXX: additional newline is needed
|
set_content_type_to_encrypted(encrypted)
|
||||||
// to pass filtermail at
|
|
||||||
// <https://github.com/deltachat/chatmail/blob/4d915f9800435bf13057d41af8d708abd34dbfa8/chatmaild/src/chatmaild/filtermail.py#L84-L86>:
|
|
||||||
let encrypted = encrypted + "\n";
|
|
||||||
|
|
||||||
// Set the appropriate Content-Type for the outer message
|
|
||||||
MimePart::new(
|
|
||||||
"multipart/encrypted; protocol=\"application/pgp-encrypted\"",
|
|
||||||
vec![
|
|
||||||
// Autocrypt part 1
|
|
||||||
MimePart::new("application/pgp-encrypted", "Version: 1\r\n").header(
|
|
||||||
"Content-Description",
|
|
||||||
mail_builder::headers::raw::Raw::new("PGP/MIME version identification"),
|
|
||||||
),
|
|
||||||
// Autocrypt part 2
|
|
||||||
MimePart::new(
|
|
||||||
"application/octet-stream; name=\"encrypted.asc\"",
|
|
||||||
encrypted,
|
|
||||||
)
|
|
||||||
.header(
|
|
||||||
"Content-Description",
|
|
||||||
mail_builder::headers::raw::Raw::new("OpenPGP encrypted message"),
|
|
||||||
)
|
|
||||||
.header(
|
|
||||||
"Content-Disposition",
|
|
||||||
mail_builder::headers::raw::Raw::new("inline; filename=\"encrypted.asc\";"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Store the unprotected headers on the outer message.
|
// Store the unprotected headers on the outer message.
|
||||||
|
|||||||
Reference in New Issue
Block a user