replace ouroborous crate with self_cell

I picked ouroborous originally because the API was a bit nicer than that
in self_cell (we get to pick our own field names with ouroborous, but
don't in self_cell). However, ouroboros is now unmaintained and has a
soundness issue. The recommendation is to migrate, so that's what this
commit is.

refs: https://rustsec.org/advisories/RUSTSEC-2023-0042.html
refs: https://github.com/joshua-maros/ouroboros/issues/88

closes: https://github.com/KumoCorp/kumomta/security/dependabot/8
This commit is contained in:
Wez Furlong
2023-06-12 14:52:16 -07:00
parent b37c75e5e4
commit 9c0ca973c2
3 changed files with 38 additions and 87 deletions
Generated
+8 -61
View File
@@ -2,12 +2,6 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "Inflector"
version = "0.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"
[[package]]
name = "addr2line"
version = "0.19.0"
@@ -75,12 +69,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "aliasable"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd"
[[package]]
name = "amq-protocol"
version = "7.1.2"
@@ -2179,7 +2167,6 @@ dependencies = [
"mod-sqlite",
"nix 0.26.2",
"once_cell",
"ouroboros",
"ppp",
"prometheus",
"rand 0.8.5",
@@ -2187,6 +2174,7 @@ dependencies = [
"rfc5321",
"rustls 0.20.8",
"rustls-pemfile",
"self_cell 1.0.0",
"serde",
"serde_json",
"socksv5",
@@ -2677,7 +2665,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2819be6b8bd3236f0fdbf86b1ff2d1f42ef8ef939eed74f6bc3ecf2e6344cd96"
dependencies = [
"memo-map",
"self_cell",
"self_cell 0.10.2",
"serde",
]
@@ -3011,29 +2999,6 @@ dependencies = [
"num-traits",
]
[[package]]
name = "ouroboros"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db"
dependencies = [
"aliasable",
"ouroboros_macro",
]
[[package]]
name = "ouroboros_macro"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7"
dependencies = [
"Inflector",
"proc-macro-error",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "overload"
version = "0.1.1"
@@ -3358,30 +3323,6 @@ dependencies = [
"syn 2.0.18",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn 1.0.109",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.60"
@@ -4072,6 +4013,12 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ef965a420fe14fdac7dd018862966a4c14094f900e1650bbc71ddd7d580c8af"
[[package]]
name = "self_cell"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a3926e239738d36060909ffe6f511502f92149a45a1fade7fe031cb2d33e88b"
[[package]]
name = "serde"
version = "1.0.164"
+1 -1
View File
@@ -54,7 +54,6 @@ mod-redis = {path="../mod-redis"}
mod-sqlite = {path="../mod-sqlite"}
nix = {version="0.26", features=["resource"]}
once_cell = "1.17"
ouroboros = "0.15"
ppp = "2.2"
prometheus = "0.13"
rand = "0.8"
@@ -64,6 +63,7 @@ rustls = "0.20"
rustls-pemfile = "1.0"
serde = {version="1.0", features=["derive"]}
humantime-serde = "1.1"
self_cell = "1.0"
serde_json = "1.0"
socksv5 = {version="0.3", default-features=false, features=["tokio"]}
spool = {path="../spool"}
+29 -25
View File
@@ -13,8 +13,8 @@ use mail_builder::headers::HeaderType;
use mail_builder::mime::MimePart;
use message::EnvelopeAddress;
use minijinja::{Environment, Template};
use ouroboros::self_referencing;
use rfc5321::Response;
use self_cell::self_cell;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use spool::SpoolId;
@@ -97,12 +97,18 @@ pub struct Attachment {
base64: bool,
}
#[self_referencing]
type TemplateList<'a> = Vec<Template<'a>>;
self_cell!(
struct CompiledTemplates<'a> {
owner: Environment<'a>,
#[covariant]
dependent: TemplateList,
}
);
struct Compiled<'a> {
env: Environment<'a>,
#[borrows(env)]
#[covariant]
templates: Vec<Template<'this>>,
env_and_templates: CompiledTemplates<'a>,
inline: Vec<MimePart<'a>>,
attached: Vec<MimePart<'a>>,
}
@@ -135,7 +141,7 @@ impl<'a> Compiled<'a> {
let mut id = 0;
match content {
Content::Rfc822(_) => Ok(self.borrow_templates()[id].render(&subst)?),
Content::Rfc822(_) => Ok(self.env_and_templates.borrow_dependent()[id].render(&subst)?),
Content::Builder {
text_body,
html_body,
@@ -151,14 +157,14 @@ impl<'a> Compiled<'a> {
if text_body.is_some() {
text.replace(MimePart::new_text(
self.borrow_templates()[id].render(&subst)?,
self.env_and_templates.borrow_dependent()[id].render(&subst)?,
));
id += 1;
}
if html_body.is_some() {
html.replace(MimePart::new_html(
self.borrow_templates()[id].render(&subst)?,
self.env_and_templates.borrow_dependent()[id].render(&subst)?,
));
id += 1;
}
@@ -184,7 +190,7 @@ impl<'a> Compiled<'a> {
}
for (name, _value) in headers {
let expanded = self.borrow_templates()[id].render(&subst)?;
let expanded = self.env_and_templates.borrow_dependent()[id].render(&subst)?;
id += 1;
builder = builder.header(
name.to_string(),
@@ -192,9 +198,6 @@ impl<'a> Compiled<'a> {
);
}
let attached = self.borrow_attached();
let inline = self.borrow_inline();
let content_node = match (text, html) {
(Some(t), Some(h)) => {
MimePart::new_multipart("multipart/alternative", vec![t, h])
@@ -204,19 +207,19 @@ impl<'a> Compiled<'a> {
(None, None) => anyhow::bail!("refusing to send an empty message"),
};
let content_node = if !inline.is_empty() {
let mut parts = Vec::with_capacity(inline.len() + 1);
let content_node = if !self.inline.is_empty() {
let mut parts = Vec::with_capacity(self.inline.len() + 1);
parts.push(content_node);
parts.extend(inline.iter().cloned());
parts.extend(self.inline.iter().cloned());
MimePart::new_multipart("multipart/related", parts)
} else {
content_node
};
let root = if !attached.is_empty() {
let mut parts = Vec::with_capacity(attached.len() + 1);
let root = if !self.attached.is_empty() {
let mut parts = Vec::with_capacity(self.attached.len() + 1);
parts.push(content_node);
parts.extend(attached.iter().cloned());
parts.extend(self.attached.iter().cloned());
MimePart::new_multipart("multipart/mixed", parts)
} else {
@@ -301,7 +304,7 @@ impl InjectV1Request {
fn get_templates<'b>(
env: &'b Environment,
content: &Content,
) -> anyhow::Result<Vec<Template<'b>>> {
) -> anyhow::Result<TemplateList<'b>> {
let mut id = 0;
let mut templates = vec![];
match content {
@@ -338,13 +341,14 @@ impl InjectV1Request {
let (inline, attached) = self.attachment_data()?;
Ok(CompiledTryBuilder {
env,
let env_and_templates =
CompiledTemplates::try_new(env, |env: &Environment| get_templates(env, &self.content))?;
Ok(Compiled {
env_and_templates,
inline,
attached,
templates_builder: |env: &Environment| get_templates(env, &self.content),
}
.try_build()?)
})
}
fn attachment_data(&self) -> anyhow::Result<(Vec<MimePart>, Vec<MimePart>)> {