1
0
Fork 1
Spiegel von https://github.com/dani-garcia/vaultwarden.git synchronisiert 2025-03-12 16:47:03 +01:00

DKIM implementations

Dieser Commit ist enthalten in:
DorianCoding 2025-02-20 13:01:08 +01:00
Ursprung 359a4a088a
Commit 4fed53622f
5 geänderte Dateien mit 262 neuen und 10 gelöschten Zeilen

189
Cargo.lock generiert
Datei anzeigen

@ -561,6 +561,12 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "cookie"
version = "0.18.1"
@ -651,6 +657,33 @@ dependencies = [
"typenum",
]
[[package]]
name = "curve25519-dalek"
version = "4.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
dependencies = [
"cfg-if",
"cpufeatures",
"curve25519-dalek-derive",
"digest",
"fiat-crypto",
"rustc_version",
"subtle",
"zeroize",
]
[[package]]
name = "curve25519-dalek-derive"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "darling"
version = "0.20.10"
@ -712,6 +745,17 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
[[package]]
name = "der"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
dependencies = [
"const-oid",
"pem-rfc7468",
"zeroize",
]
[[package]]
name = "deranged"
version = "0.3.11"
@ -891,6 +935,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"const-oid",
"crypto-common",
"subtle",
]
@ -935,6 +980,30 @@ dependencies = [
"syn",
]
[[package]]
name = "ed25519"
version = "2.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
dependencies = [
"pkcs8",
"signature",
]
[[package]]
name = "ed25519-dalek"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871"
dependencies = [
"curve25519-dalek",
"ed25519",
"serde",
"sha2",
"subtle",
"zeroize",
]
[[package]]
name = "either"
version = "1.13.0"
@ -1048,6 +1117,12 @@ dependencies = [
"syslog",
]
[[package]]
name = "fiat-crypto"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
[[package]]
name = "figment"
version = "0.10.19"
@ -1925,6 +2000,9 @@ name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
dependencies = [
"spin",
]
[[package]]
name = "lettre"
@ -1936,6 +2014,7 @@ dependencies = [
"async-trait",
"base64 0.22.1",
"chumsky",
"ed25519-dalek",
"email-encoding",
"email_address",
"fastrand",
@ -1949,7 +2028,9 @@ dependencies = [
"nom",
"percent-encoding",
"quoted_printable",
"rsa",
"serde",
"sha2",
"socket2",
"tokio",
"tokio-native-tls",
@ -2236,6 +2317,23 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-bigint-dig"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
dependencies = [
"byteorder",
"lazy_static",
"libm",
"num-integer",
"num-iter",
"num-traits",
"rand 0.8.5",
"smallvec",
"zeroize",
]
[[package]]
name = "num-conv"
version = "0.1.0"
@ -2262,6 +2360,17 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-modular"
version = "0.6.1"
@ -2284,6 +2393,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
]
[[package]]
@ -2468,6 +2578,15 @@ dependencies = [
"serde",
]
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
dependencies = [
"base64ct",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -2600,6 +2719,27 @@ dependencies = [
"futures-io",
]
[[package]]
name = "pkcs1"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [
"der",
"pkcs8",
"spki",
]
[[package]]
name = "pkcs8"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
dependencies = [
"der",
"spki",
]
[[package]]
name = "pkg-config"
version = "0.3.31"
@ -3102,6 +3242,26 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "rsa"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519"
dependencies = [
"const-oid",
"digest",
"num-bigint-dig",
"num-integer",
"num-traits",
"pkcs1",
"pkcs8",
"rand_core 0.6.4",
"signature",
"spki",
"subtle",
"zeroize",
]
[[package]]
name = "rtoolbox"
version = "0.0.2"
@ -3118,6 +3278,15 @@ version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc_version"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
dependencies = [
"semver",
]
[[package]]
name = "rustix"
version = "0.38.44"
@ -3410,6 +3579,16 @@ dependencies = [
"libc",
]
[[package]]
name = "signature"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"rand_core 0.6.4",
]
[[package]]
name = "simple_asn1"
version = "0.6.3"
@ -3468,6 +3647,16 @@ dependencies = [
"lock_api",
]
[[package]]
name = "spki"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
"base64ct",
"der",
]
[[package]]
name = "stable-pattern"
version = "0.1.0"

Datei anzeigen

@ -122,7 +122,7 @@ webauthn-rs = "0.3.2"
url = "2.5.4"
# Email libraries
lettre = { version = "0.11.12", features = ["smtp-transport", "sendmail-transport", "builder", "serde", "tokio1-native-tls", "hostname", "tracing", "tokio1"], default-features = false }
lettre = { version = "0.11.12", features = ["smtp-transport", "sendmail-transport", "dkim", "builder", "serde", "tokio1-native-tls", "hostname", "tracing", "tokio1"], default-features = false }
percent-encoding = "2.3.1" # URL encoding library used for URL's in the emails
email_address = "0.2.9"

Datei anzeigen

@ -12,10 +12,10 @@ fn main() {
#[cfg(feature = "query_logger")]
println!("cargo:rustc-cfg=query_logger");
#[cfg(not(any(feature = "sqlite", feature = "mysql", feature = "postgresql")))]
/* #[cfg(not(any(feature = "sqlite", feature = "mysql", feature = "postgresql")))]
compile_error!(
"You need to enable one DB backend. To build with previous defaults do: cargo build --features sqlite"
);
); */
// Use check-cfg to let cargo know which cfg's we define,
// and avoid warnings when they are used in the code.

Datei anzeigen

@ -704,6 +704,12 @@ make_config! {
smtp_from_name: String, true, def, "Vaultwarden".to_string();
/// Username
smtp_username: String, true, option;
/// Dkim signature (type:privatekey). Private must be base64-encoded ed key or PKCS#1 format RSA key.
dkim_signature: String, true, option;
/// Dkim algo (true if RSA else ed25519)
dkim_algo: bool, true, option;
/// Dkim infos (selector:domain)
dkim_infos: String, true, option;
/// Password
smtp_password: Pass, true, option;
/// SMTP Auth mechanism |> Defaults for SSL is "Plain" and "Login" and nothing for Non-SSL connections. Possible values: ["Plain", "Login", "Xoauth2"]. Multiple options need to be separated by a comma ','.

Datei anzeigen

@ -1,14 +1,16 @@
use chrono::NaiveDateTime;
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
use std::{env::consts::EXE_SUFFIX, str::FromStr};
use lettre::{
message::{Attachment, Body, Mailbox, Message, MultiPart, SinglePart},
message::{
dkim::{DkimConfig, DkimSigningAlgorithm, DkimSigningKey},
dkim_sign, Attachment, Body, Mailbox, Message, MultiPart, SinglePart,
},
transport::smtp::authentication::{Credentials, Mechanism as SmtpAuthMechanism},
transport::smtp::client::{Tls, TlsParameters},
transport::smtp::extension::ClientId,
Address, AsyncSendmailTransport, AsyncSmtpTransport, AsyncTransport, Tokio1Executor,
};
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
use std::{env::consts::EXE_SUFFIX, io::Read, str::FromStr};
use crate::{
api::EmptyResult,
@ -641,7 +643,60 @@ async fn send_with_selected_transport(email: Message) -> EmptyResult {
async fn send_email(address: &str, subject: &str, body_html: String, body_text: String) -> EmptyResult {
let smtp_from = &CONFIG.smtp_from();
let dkim = match (CONFIG.dkim_signature(), CONFIG.dkim_infos()) {
(Some(sig), Some(infos)) => {
let config = {
let algo = match CONFIG.dkim_algo() {
Some(true) => DkimSigningAlgorithm::Rsa,
_ => DkimSigningAlgorithm::Ed25519,
};
let mut key = String::with_capacity(4096);
let sig = match std::fs::File::open(sig) {
Ok(mut f) => {
if let Err(e) = f.read_to_string(&mut key) {
debug!("Cannot read DKIM file. Err is {:?}", e);
None
} else {
key.shrink_to_fit();
match DkimSigningKey::new(&key, algo) {
Ok(d) => Some(d),
Err(e) => {
debug!("DKIM key could not be parsed. Err is {:?}", e.to_string());
None
}
}
}
},
Err(e) => {
debug!("Cannot read DKIM file. Err is {:?}", e);
None
}
};
match (sig, infos.split(':').collect::<Vec<&str>>()) {
(Some(sig), split2) if split2.len() == 2 => {
let (selector, domain, sig) =
(String::from(*split2.first().unwrap()), String::from(*split2.last().unwrap()), sig);
Some((selector, domain, sig))
}
(None,_) => None,
_ => {
debug!("DKIM issue, invalid domain, selector.");
None
}
}
};
if let Some(config) = config {
Some(DkimConfig::default_config(config.0, config.1, config.2))
} else {
None
}
}
(None, None) => None,
_ => {
warn!("DKIM setting is badly implemented. One config is missing (DKIM signature or DKIM infos).");
None
}
};
let body = if CONFIG.smtp_embed_images() {
let logo_gray_body = Body::new(crate::api::static_files("logo-gray.png").unwrap().1.to_vec());
let mail_github_body = Body::new(crate::api::static_files("mail-github.png").unwrap().1.to_vec());
@ -661,12 +716,14 @@ async fn send_email(address: &str, subject: &str, body_html: String, body_text:
MultiPart::alternative_plain_html(body_text, body_html)
};
let email = Message::builder()
let mut email = Message::builder()
.message_id(Some(format!("<{}@{}>", crate::util::get_uuid(), smtp_from.split('@').collect::<Vec<&str>>()[1])))
.to(Mailbox::new(None, Address::from_str(address)?))
.from(Mailbox::new(Some(CONFIG.smtp_from_name()), Address::from_str(smtp_from)?))
.subject(subject)
.multipart(body)?;
if let Some(sig) = dkim {
dkim_sign(&mut email, &sig);
}
send_with_selected_transport(email).await
}