Compare commits
4 Commits
0a28c04f86
...
04b4bc817a
Author | SHA1 | Date |
---|---|---|
Vincent Breitmoser | 04b4bc817a | |
Vincent Breitmoser | 5e08a7086e | |
Vincent Breitmoser | 875ab41c7d | |
Justus Winter | dc2d67d9eb |
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
10
Cargo.toml
|
@ -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"
|
||||
|
|
|
@ -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…"
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.58.1
|
||||
1.60.0
|
||||
|
|
102
src/dump.rs
102
src/dump.rs
|
@ -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(())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use handlebars::{
|
||||
use rocket_dyn_templates::handlebars::{
|
||||
Context, Handlebars, Helper, HelperDef, HelperResult, Output, RenderContext, RenderError,
|
||||
};
|
||||
|
||||
|
|
22
src/mail.rs
22
src/mail.rs
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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\
|
||||
|
|
Loading…
Reference in New Issue