mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2024-09-20 15:26:17 +08:00
Fixed DKIM public key format
This commit is contained in:
parent
44f531ecf9
commit
23edd40fd0
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -2884,6 +2884,7 @@ dependencies = [
|
||||||
"mime",
|
"mime",
|
||||||
"nlp",
|
"nlp",
|
||||||
"p256",
|
"p256",
|
||||||
|
"pkcs8",
|
||||||
"rand",
|
"rand",
|
||||||
"rasn",
|
"rasn",
|
||||||
"rasn-cms",
|
"rasn-cms",
|
||||||
|
|
|
@ -185,8 +185,8 @@ async fn oauth(url: &str) -> Credentials {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum Response<T> {
|
pub enum Response<T> {
|
||||||
Data { data: T },
|
|
||||||
Error(ManagementApiError),
|
Error(ManagementApiError),
|
||||||
|
Data { data: T },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -283,11 +283,11 @@ impl Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match serde_json::from_slice::<Response<R>>(
|
let bytes = response.bytes().await.unwrap_result("fetch bytes");
|
||||||
&response.bytes().await.unwrap_result("fetch bytes"),
|
match serde_json::from_slice::<Response<R>>(&bytes).unwrap_result(&format!(
|
||||||
)
|
"deserialize response {}",
|
||||||
.unwrap_result("deserialize response")
|
String::from_utf8_lossy(bytes.as_ref())
|
||||||
{
|
)) {
|
||||||
Response::Data { data } => Some(data),
|
Response::Data { data } => Some(data),
|
||||||
Response::Error(error) => {
|
Response::Error(error) => {
|
||||||
eprintln!("Request failed: {error})");
|
eprintln!("Request failed: {error})");
|
||||||
|
|
|
@ -27,6 +27,8 @@ use prettytable::{Attr, Cell, Row, Table};
|
||||||
use reqwest::Method;
|
use reqwest::Method;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
|
use crate::modules::List;
|
||||||
|
|
||||||
use super::cli::{Client, DomainCommands};
|
use super::cli::{Client, DomainCommands};
|
||||||
|
|
||||||
impl DomainCommands {
|
impl DomainCommands {
|
||||||
|
@ -70,15 +72,15 @@ impl DomainCommands {
|
||||||
};
|
};
|
||||||
|
|
||||||
let domains = client
|
let domains = client
|
||||||
.http_request::<Vec<String>, String>(Method::GET, query.as_ref(), None)
|
.http_request::<List<String>, String>(Method::GET, query.as_ref(), None)
|
||||||
.await;
|
.await;
|
||||||
if !domains.is_empty() {
|
if !domains.items.is_empty() {
|
||||||
let mut table = Table::new();
|
let mut table = Table::new();
|
||||||
table.add_row(Row::new(vec![
|
table.add_row(Row::new(vec![
|
||||||
Cell::new("Domain Name").with_style(Attr::Bold)
|
Cell::new("Domain Name").with_style(Attr::Bold)
|
||||||
]));
|
]));
|
||||||
|
|
||||||
for domain in &domains {
|
for domain in &domains.items {
|
||||||
table.add_row(Row::new(vec![Cell::new(domain)]));
|
table.add_row(Row::new(vec![Cell::new(domain)]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,8 +91,8 @@ impl DomainCommands {
|
||||||
|
|
||||||
eprintln!(
|
eprintln!(
|
||||||
"\n\n{} domain{} found.\n",
|
"\n\n{} domain{} found.\n",
|
||||||
domains.len(),
|
domains.total,
|
||||||
if domains.len() == 1 { "" } else { "s" }
|
if domains.total == 1 { "" } else { "s" }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,8 +93,8 @@ impl Tracers {
|
||||||
level,
|
level,
|
||||||
appender,
|
appender,
|
||||||
ansi: config
|
ansi: config
|
||||||
.property_or_default(("tracer", id, "ansi"), "true")
|
.property_or_default(("tracer", id, "ansi"), "false")
|
||||||
.unwrap_or(true),
|
.unwrap_or(false),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@ impl WebAdminManager {
|
||||||
{
|
{
|
||||||
"html" => "text/html",
|
"html" => "text/html",
|
||||||
"css" => "text/css",
|
"css" => "text/css",
|
||||||
|
"wasm" => "application/wasm",
|
||||||
"js" => "application/javascript",
|
"js" => "application/javascript",
|
||||||
"json" => "application/json",
|
"json" => "application/json",
|
||||||
"png" => "image/png",
|
"png" => "image/png",
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl<T: SessionStream> Session<T> {
|
||||||
// Send continuation response
|
// Send continuation response
|
||||||
self.write_bytes(b"+ Idling, send 'DONE' to stop.\r\n".to_vec())
|
self.write_bytes(b"+ Idling, send 'DONE' to stop.\r\n".to_vec())
|
||||||
.await?;
|
.await?;
|
||||||
tracing::debug!(parent: &self.span, event = "stat", context = "idle", "Starting IDLE.");
|
tracing::debug!(parent: &self.span, event = "start", context = "idle", "Starting IDLE.");
|
||||||
let mut buf = vec![0; 1024];
|
let mut buf = vec![0; 1024];
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
|
|
|
@ -47,6 +47,7 @@ aes = "0.8.3"
|
||||||
cbc = { version = "0.1.2", features = ["alloc"] }
|
cbc = { version = "0.1.2", features = ["alloc"] }
|
||||||
sequoia-openpgp = { version = "1.16", default-features = false, features = ["crypto-rust", "allow-experimental-crypto", "allow-variable-time-crypto"] }
|
sequoia-openpgp = { version = "1.16", default-features = false, features = ["crypto-rust", "allow-experimental-crypto", "allow-variable-time-crypto"] }
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
pkcs8 = { version = "0.10.2", features = ["alloc", "std"] }
|
||||||
rasn = "0.10"
|
rasn = "0.10"
|
||||||
rasn-cms = "0.10"
|
rasn-cms = "0.10"
|
||||||
rasn-pkix = "0.10"
|
rasn-pkix = "0.10"
|
||||||
|
|
|
@ -32,6 +32,12 @@ use mail_auth::{
|
||||||
};
|
};
|
||||||
use mail_builder::encoders::base64::base64_encode;
|
use mail_builder::encoders::base64::base64_encode;
|
||||||
use mail_parser::DateTime;
|
use mail_parser::DateTime;
|
||||||
|
use pkcs8::{
|
||||||
|
der::{asn1::BitString, Encode},
|
||||||
|
spki::{AlgorithmIdentifier, SubjectPublicKeyInfoOwned},
|
||||||
|
Document,
|
||||||
|
};
|
||||||
|
use rsa::pkcs1::DecodeRsaPublicKey;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use store::write::now;
|
use store::write::now;
|
||||||
|
@ -238,20 +244,44 @@ impl JMAP {
|
||||||
pub fn obtain_dkim_public_key(algo: Algorithm, pk: &str) -> Result<String, &'static str> {
|
pub fn obtain_dkim_public_key(algo: Algorithm, pk: &str) -> Result<String, &'static str> {
|
||||||
match simple_pem_parse(pk) {
|
match simple_pem_parse(pk) {
|
||||||
Some(der) => match algo {
|
Some(der) => match algo {
|
||||||
Algorithm::Rsa => match RsaKey::<Sha256>::from_der(&der) {
|
Algorithm::Rsa => match RsaKey::<Sha256>::from_der(&der).and_then(|key| {
|
||||||
Ok(pk) => Ok(String::from_utf8(
|
Document::from_pkcs1_der(&key.public_key())
|
||||||
base64_encode(&pk.public_key()).unwrap_or_default(),
|
.map_err(|err| mail_auth::Error::CryptoError(err.to_string()))
|
||||||
)
|
}) {
|
||||||
.unwrap_or_default()),
|
Ok(pk) => Ok(
|
||||||
Err(_) => Err("Failed to read RSA DER"),
|
String::from_utf8(base64_encode(pk.as_bytes()).unwrap_or_default())
|
||||||
},
|
.unwrap_or_default(),
|
||||||
Algorithm::Ed25519 => match Ed25519Key::from_pkcs8_der(&der) {
|
),
|
||||||
Ok(pk) => Ok(String::from_utf8(
|
Err(err) => {
|
||||||
base64_encode(&pk.public_key()).unwrap_or_default(),
|
tracing::debug!("Failed to read RSA DER: {err}");
|
||||||
)
|
|
||||||
.unwrap_or_default()),
|
Err("Failed to read RSA DER")
|
||||||
Err(_) => Err("Failed to read ED25519 PKCS#8 DER"),
|
}
|
||||||
},
|
},
|
||||||
|
Algorithm::Ed25519 => {
|
||||||
|
match Ed25519Key::from_pkcs8_maybe_unchecked_der(&der).and_then(|key| {
|
||||||
|
BitString::from_bytes(&key.public_key())
|
||||||
|
.and_then(|subject_public_key| {
|
||||||
|
SubjectPublicKeyInfoOwned {
|
||||||
|
algorithm: AlgorithmIdentifier {
|
||||||
|
oid: "1.3.101.112".parse().unwrap(),
|
||||||
|
parameters: None,
|
||||||
|
},
|
||||||
|
subject_public_key,
|
||||||
|
}
|
||||||
|
.to_der()
|
||||||
|
})
|
||||||
|
.map_err(|err| mail_auth::Error::CryptoError(err.to_string()))
|
||||||
|
}) {
|
||||||
|
Ok(pk) => Ok(String::from_utf8(base64_encode(&pk).unwrap_or_default())
|
||||||
|
.unwrap_or_default()),
|
||||||
|
Err(err) => {
|
||||||
|
tracing::debug!("Failed to read ED25519 DER: {err}");
|
||||||
|
|
||||||
|
Err("Failed to read ED25519 DER")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
None => Err("Failed to decode private key"),
|
None => Err("Failed to decode private key"),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue