Compare commits

...

4 Commits

Author SHA1 Message Date
Vincent Breitmoser 04b4bc817a i18n: update some fuzzily misdetected strings 2022-12-10 17:42:56 +01:00
Vincent Breitmoser 5e08a7086e cargo: cargo update and fix for some deps 2022-12-10 17:42:50 +01:00
Vincent Breitmoser 875ab41c7d cargo: apply cargo fmt --all 2022-12-10 15:29:58 +01:00
Justus Winter dc2d67d9eb
Bump sequoia-openpgp to 1.11 and synchronize src/dump.rs. 2022-12-09 12:59:42 +01:00
9 changed files with 883 additions and 826 deletions

1553
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -16,9 +16,9 @@ members = [
hagrid-database = { path = "database" }
chrono = "0.4.10"
anyhow = "1"
rocket = { version = "0.5.0-rc.1", features = [ "json" ] }
rocket_dyn_templates = { version = "0.1.0-rc.1", features = ["handlebars"] }
rocket_codegen = "0.5.0-rc.1"
rocket = { version = "0.5.0-rc.2", features = [ "json" ] }
rocket_dyn_templates = { version = "0.1.0-rc.2", features = ["handlebars"] }
rocket_codegen = "0.5.0-rc.2"
sequoia-openpgp = { version = "1", default-features = false, features = ["crypto-nettle"] }
multipart = "0"
serde = "1.0"
@ -28,7 +28,6 @@ time = "0.1"
tempfile = "3.0"
structopt = "0.2"
url = "1.6"
handlebars = "3"
num_cpus = "1.0"
ring = "0.13"
base64 = "0.10"
@ -40,7 +39,8 @@ gettext-utils = "0.1"
gettext = "0.4"
glob = "0.3"
hyperx = "1.4"
lettre = { version = "0.10.0-rc.5", default-features = false, features = ["builder", "file-transport", "sendmail-transport"] }
# this is a slightly annoying update, so keeping this back for now
lettre = { version = "=0.10.0-rc.5", default-features = false, features = ["builder", "file-transport", "sendmail-transport"] }
[dependencies.rocket_i18n]
git = "https://github.com/Plume-org/rocket_i18n"

View File

@ -353,10 +353,10 @@ msgid ""
msgstr "To let others find this key from your email address \"{{userid}}\","
msgid "No key found for fingerprint {}"
msgstr ""
msgstr "No key found for fingerprint {}"
msgid "No key found for key id {}"
msgstr ""
msgstr "No key found for key id {}"
msgid "No key found for email address {}"
msgstr "Verifying your email address…"

View File

@ -1 +1 @@
1.58.1
1.60.0

View File

@ -1,7 +1,7 @@
use std::io::{self, Read};
use self::openpgp::crypto::mpi;
use self::openpgp::crypto::{SessionKey, S2K};
use self::openpgp::crypto::S2K;
use self::openpgp::fmt::hex;
use self::openpgp::packet::header::CTB;
use self::openpgp::packet::prelude::*;
@ -12,6 +12,38 @@ use self::openpgp::types::{Duration, SymmetricAlgorithm, Timestamp};
use self::openpgp::{Packet, Result};
use sequoia_openpgp as openpgp;
pub struct SessionKey {
pub session_key: openpgp::crypto::SessionKey,
pub symmetric_algo: Option<SymmetricAlgorithm>,
}
impl SessionKey {
/// Returns an object that implements Display for explicitly opting into
/// printing a `SessionKey`.
pub fn display_sensitive(&self) -> SessionKeyDisplay {
SessionKeyDisplay { csk: self }
}
}
/// Helper struct for intentionally printing session keys with format! and {}.
///
/// This struct implements the `Display` trait to print the session key. This
/// construct requires the user to explicitly call
/// [`SessionKey::display_sensitive`]. By requiring the user to opt-in, this
/// will hopefully reduce that the chance that the session key is inadvertently
/// leaked, e.g., in a log that may be publicly posted.
pub struct SessionKeyDisplay<'a> {
csk: &'a SessionKey,
}
/// Print the session key without prefix in hexadecimal representation.
impl<'a> std::fmt::Display for SessionKeyDisplay<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let sk = self.csk;
write!(f, "{}", hex::encode(&sk.session_key))
}
}
#[derive(Debug)]
pub enum Kind {
Message { encrypted: bool },
@ -86,29 +118,28 @@ where
}
Packet::SEIP(_) if sk.is_some() => {
message_encrypted = true;
let sk = sk.as_ref().unwrap();
let mut decrypted_with = None;
for algo in 1..20 {
let algo = SymmetricAlgorithm::from(algo);
if let Ok(size) = algo.key_size() {
if size != sk.len() {
continue;
}
} else {
continue;
}
let sk = sk.unwrap();
let decrypted_with = if let Some(algo) = sk.symmetric_algo {
// We know which algorithm to use, so only try decrypting
// with that one.
pp.decrypt(algo, &sk.session_key).is_ok().then(|| algo)
} else {
// We don't know which algorithm to use,
// try to find one that decrypts the message.
(1u8..=19)
.map(SymmetricAlgorithm::from)
.find(|algo| pp.decrypt(*algo, &sk.session_key).is_ok())
};
if let Ok(_) = pp.decrypt(algo, sk) {
decrypted_with = Some(algo);
break;
}
}
let mut fields = Vec::new();
fields.push(format!("Session key: {}", hex::encode(sk)));
fields.push(format!("Session key: {}", &sk.display_sensitive()));
if let Some(algo) = decrypted_with {
fields.push(format!("Symmetric algo: {}", algo));
fields.push("Decryption successful".into());
} else {
if let Some(algo) = sk.symmetric_algo {
fields.push(format!("Indicated Symmetric algo: {}", algo));
};
fields.push("Decryption failed".into());
}
Some(fields)
@ -126,14 +157,14 @@ where
unreachable!()
};
let _ = pp.decrypt(algo, sk);
let _ = pp.decrypt(algo, &sk.session_key);
let mut fields = Vec::new();
fields.push(format!("Session key: {}", hex::encode(sk)));
if pp.encrypted() {
fields.push("Decryption failed".into());
} else {
fields.push(format!("Session key: {}", sk.display_sensitive()));
if pp.processed() {
fields.push("Decryption successful".into());
} else {
fields.push("Decryption failed".into());
}
Some(fields)
}
@ -403,8 +434,8 @@ impl PacketDumper {
sym,
} => {
writeln!(output, "{} Curve: {}", ii, curve)?;
writeln!(output, "{} Hash algo: {}", ii, hash)?;
writeln!(output, "{} Symmetric algo: {}", ii, sym)?;
writeln!(output, "{} KDF hash algo: {}", ii, hash)?;
writeln!(output, "{} KEK symmetric algo: {}", ii, sym)?;
pd.dump_mpis(output, &ii, &[q.value()], &["q"])?;
}
mpi::PublicKey::Unknown { mpis, rest } => {
@ -465,17 +496,11 @@ impl PacketDumper {
let keys: Vec<String> =
(0..mpis.len()).map(|i| format!("mpi{}", i)).collect();
pd.dump_mpis(
output,
&ii,
&mpis
.iter()
.map(|m| {
m.value().iter().as_slice()
})
.collect::<Vec<_>>()[..],
&keys
.iter()
.map(|k| k.as_str())
output, &ii,
&mpis.iter().map(|m| {
m.value().iter().as_slice()
}).collect::<Vec<_>>()[..],
&keys.iter().map(|k| k.as_str())
.collect::<Vec<_>>()[..],
)?;
@ -787,8 +812,9 @@ impl PacketDumper {
}
}
writeln!(output, "{}", i)?;
if let Some(map) = map {
writeln!(output, "{}", i)?;
let mut hd = hex::Dumper::new(
output,
self.indentation_for_hexdump(
@ -816,8 +842,6 @@ impl PacketDumper {
let output = hd.into_inner();
writeln!(output, "{}", i)?;
} else {
writeln!(output, "{}", i)?;
}
Ok(())

View File

@ -1,4 +1,4 @@
use handlebars::{
use rocket_dyn_templates::handlebars::{
Context, Handlebars, Helper, HelperDef, HelperResult, Output, RenderContext, RenderError,
};

View File

@ -1,9 +1,9 @@
use std::path::{Path, PathBuf};
use crate::counters;
use handlebars::Handlebars;
use lettre::message::{Mailbox, MultiPart, SinglePart, header};
use lettre::message::{header, Mailbox, MultiPart, SinglePart};
use lettre::{FileTransport, SendmailTransport, Transport as LettreTransport};
use rocket_dyn_templates::handlebars::Handlebars;
use serde::Serialize;
use uuid::Uuid;
@ -79,7 +79,9 @@ impl Service {
.host_str()
.ok_or_else(|| anyhow!("No host in base-URI"))?
.to_string();
let from = from.parse().map_err(|_| anyhow!("From must be valid email address"))?;
let from = from
.parse()
.map_err(|_| anyhow!("From must be valid email address"))?;
Ok(Self {
from,
domain,
@ -233,12 +235,14 @@ impl Service {
SinglePart::builder()
.header(header::ContentTransferEncoding::EightBit)
.header(header::ContentType::TEXT_PLAIN)
.body(txt)
.body(txt),
)
.singlepart(SinglePart::builder()
.singlepart(
SinglePart::builder()
.header(header::ContentTransferEncoding::EightBit)
.header(header::ContentType::TEXT_HTML)
.body(html)),
.body(html),
),
)?;
match self.transport {
@ -448,9 +452,9 @@ mod test {
assert!(mail_content.contains("testtoken"));
assert!(mail_content.contains("test/about"));
assert!(mail_content.contains("この鍵の掲示されたア"));
assert!(mail_content.contains(
"Subject: =?utf-8?b?bG9jYWxob3N044Gu6Y2144KS566h55CG44GZ44KL?="
));
assert!(
mail_content.contains("Subject: =?utf-8?b?bG9jYWxob3N044Gu6Y2144KS566h55CG44GZ44KL?=")
);
}
#[test]

View File

@ -1,7 +1,7 @@
use std::collections::HashSet;
use std::path::{Path, PathBuf};
use handlebars::Handlebars;
use rocket_dyn_templates::handlebars::Handlebars;
use crate::i18n::I18NHelper;
use crate::web::get_i18n;

View File

@ -1412,14 +1412,10 @@ pub mod tests {
}
fn vks_publish_submit_response<'a>(client: &'a Client, data: &[u8]) -> LocalResponse<'a> {
let ct = ContentType::with_params(
"multipart",
"form-data",
(
"boundary",
"---------------------------14733842173518794281682249499",
),
);
let ct = ContentType::new("multipart", "form-data").with_params((
"boundary",
"---------------------------14733842173518794281682249499",
));
let header = b"-----------------------------14733842173518794281682249499\r\n\
Content-Disposition: form-data; name=\"csrf\"\r\n\