diff --git a/assets/mail-template.html b/assets/mail-template.html
index 446d229..de5faee 100644
--- a/assets/mail-template.html
+++ b/assets/mail-template.html
@@ -1,12 +1,7 @@
-
-
diff --git a/example.config.toml b/example.config.toml
index 0c46953..d0d98cc 100644
--- a/example.config.toml
+++ b/example.config.toml
@@ -2,6 +2,7 @@ variant = "Advanced"
root_folder = "data"
max_age = 900
cleanup_interval = 21600
+allowed_domains = ["example.org", "example.com"]
port = 8080
external_url = "http://localhost:8080"
diff --git a/src/errors.rs b/src/errors.rs
index e1f54b0..059eb31 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -3,32 +3,34 @@ use thiserror::Error;
#[derive(Error, Debug, Clone, Copy)]
pub enum Error {
- #[error("EC1: Cert is invalid")]
+ #[error("(0x00) Cert is invalid")]
InvalidCert,
- #[error("EP1: Error while parsing cert")]
+ #[error("(0x01) Error while parsing cert")]
ParseCert,
- #[error("EP2: Error while parsing an E-Mail address")]
+ #[error("(0x02) Error while parsing an E-Mail address")]
ParseEmail,
- #[error("EM1: There is no pending request associated to this token")]
+ #[error("(0x03) There is no pending request associated to this token")]
MissingPending,
- #[error("EM2: Requested key does not exist")]
+ #[error("(0x04) Requested key does not exist")]
MissingKey,
- #[error("EM3: No E-Mail found in the certificate")]
+ #[error("(0x05) No E-Mail found in the certificate")]
MissingMail,
- #[error("EE1: Error while sending the E-Mail")]
+ #[error("(0x06) Error while sending the E-Mail")]
SendMail,
- #[error("ES1: rror while serializing data")]
+ #[error("(0x07) rror while serializing data")]
SerializeData,
- #[error("ES2: Error while deserializing data")]
+ #[error("(0x08) Error while deserializing data")]
DeserializeData,
- #[error("ES3: The file is inaccessible")]
+ #[error("(0x09) The file is inaccessible")]
Inaccessible,
- #[error("ES4: Error while adding a key to the wkd")]
+ #[error("(0x0A) Error while adding a key to the wkd")]
AddingKey,
- #[error("EG1: Error while generating the wkd path")]
+ #[error("(0x0B) Error while generating the wkd path")]
PathGeneration,
- #[error("EG2: Error while generating the email")]
+ #[error("(0x0C) Error while generating the email")]
MailGeneration,
+ #[error("(0x0D) Wrong email domain")]
+ WrongDomain,
}
impl actix_web::ResponseError for Error {
@@ -36,6 +38,7 @@ impl actix_web::ResponseError for Error {
match self {
Self::MissingPending => StatusCode::from_u16(404).unwrap(),
Self::MissingKey => StatusCode::from_u16(404).unwrap(),
+ Self::WrongDomain => StatusCode::from_u16(401).unwrap(),
_ => StatusCode::from_u16(500).unwrap(),
}
}
diff --git a/src/main.rs b/src/main.rs
index ccc8ce0..427c032 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,6 +5,7 @@ mod settings;
mod utils;
use crate::settings::SETTINGS;
+use crate::utils::is_email_allowed;
use self::confirmation::{confirm_action, send_confirmation_email};
use self::management::{clean_stale, store_pending_addition, store_pending_deletion, Action};
@@ -69,6 +70,7 @@ async fn main() -> std::io::Result<()> {
async fn submit(pem: web::Form
) -> Result {
let cert = parse_pem(&pem.key)?;
let email = get_email_from_cert(&cert)?;
+ is_email_allowed(&email)?;
let token = gen_random_token();
store_pending_addition(pem.key.clone(), &email, &token)?;
send_confirmation_email(&email, &Action::Add, &token)?;
diff --git a/src/settings.rs b/src/settings.rs
index a5382d5..08ebc1d 100644
--- a/src/settings.rs
+++ b/src/settings.rs
@@ -13,6 +13,7 @@ pub struct Settings {
pub root_folder: String,
pub max_age: i64,
pub cleanup_interval: u64,
+ pub allowed_domains: Vec,
pub port: u16,
pub external_url: Url,
pub mail_settings: MailSettings,
diff --git a/src/utils.rs b/src/utils.rs
index 6001073..1ccce72 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -4,7 +4,7 @@ use crate::settings::SETTINGS;
use flexi_logger::{style, DeferredNow, FileSpec, FlexiLoggerError, Logger, LoggerHandle, Record};
use rand::{distributions::Alphanumeric, thread_rng, Rng};
use sequoia_net::wkd::Url;
-use sequoia_openpgp::{parse::Parse, Cert, policy::NullPolicy};
+use sequoia_openpgp::{parse::Parse, policy::StandardPolicy, Cert};
use std::path::{Path, PathBuf};
#[macro_export]
@@ -14,15 +14,26 @@ macro_rules! pending_path {
};
}
+pub fn is_email_allowed(email: &str) -> Result<(), Error> {
+ let allowed = match email.split('@').last() {
+ Some(domain) => SETTINGS.allowed_domains.contains(&domain.to_string()),
+ None => return Err(Error::ParseEmail),
+ };
+ if !allowed {
+ return Err(Error::WrongDomain);
+ }
+ Ok(())
+}
+
pub fn parse_pem(pemfile: &str) -> Result {
let cert = match sequoia_openpgp::Cert::from_bytes(pemfile.as_bytes()) {
Ok(cert) => cert,
Err(_) => return Err(Error::ParseCert),
};
- let policy = NullPolicy::new();
+ let policy = StandardPolicy::new();
if cert.with_policy(&policy, None).is_err() {
- return Err(Error::InvalidCert)
- }
+ return Err(Error::InvalidCert);
+ };
Ok(cert)
}
@@ -32,10 +43,10 @@ pub fn gen_random_token() -> String {
}
pub fn get_email_from_cert(cert: &Cert) -> Result {
- let policy = NullPolicy::new();
+ let policy = StandardPolicy::new();
let validcert = match cert.with_policy(&policy, None) {
Ok(validcert) => validcert,
- Err(_) => return Err(Error::InvalidCert)
+ Err(_) => return Err(Error::InvalidCert),
};
let userid_opt = match validcert.primary_userid() {
Ok(userid_opt) => userid_opt,