mirror of
https://git.verdigado.com/NB-Public/simple-wkd.git
synced 2024-10-30 01:25:53 +01:00
Check if uploaded key contains secret material
This commit is contained in:
parent
1636a97e15
commit
d9b722397c
4 changed files with 17 additions and 10 deletions
|
@ -6,7 +6,7 @@ use crate::errors::SpecialErrors;
|
||||||
use crate::management::{delete_key, Action, Pending};
|
use crate::management::{delete_key, Action, Pending};
|
||||||
use crate::settings::{MAILER, SETTINGS};
|
use crate::settings::{MAILER, SETTINGS};
|
||||||
use crate::utils::{get_email_from_cert, insert_key, parse_pem, read_file};
|
use crate::utils::{get_email_from_cert, insert_key, parse_pem, read_file};
|
||||||
use crate::{log_err, pending_path};
|
use crate::{log_err, pending_path, validate_cert};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use lettre::{AsyncTransport, Message};
|
use lettre::{AsyncTransport, Message};
|
||||||
|
@ -25,8 +25,9 @@ pub fn confirm_action(token: &str) -> Result<(Action, String)> {
|
||||||
let address = match key.action() {
|
let address = match key.action() {
|
||||||
Action::Add => {
|
Action::Add => {
|
||||||
let cert = parse_pem(key.data())?;
|
let cert = parse_pem(key.data())?;
|
||||||
let email = get_email_from_cert(&cert)?;
|
let validcert = validate_cert!(cert)?;
|
||||||
log_err!(insert_key(&cert), warn)?;
|
let email = get_email_from_cert(&validcert)?;
|
||||||
|
log_err!(insert_key(&validcert), warn)?;
|
||||||
email
|
email
|
||||||
}
|
}
|
||||||
Action::Delete => {
|
Action::Delete => {
|
||||||
|
|
|
@ -36,6 +36,8 @@ macro_rules! log_err {
|
||||||
|
|
||||||
#[derive(Debug, DeriveError)]
|
#[derive(Debug, DeriveError)]
|
||||||
pub enum SpecialErrors {
|
pub enum SpecialErrors {
|
||||||
|
#[error("Uploaded certificate contains a secret key!")]
|
||||||
|
ContainsSecret,
|
||||||
#[error("Could not find any primay user email in the keyblock!")]
|
#[error("Could not find any primay user email in the keyblock!")]
|
||||||
EmailMissing,
|
EmailMissing,
|
||||||
#[error("The request had expired!")]
|
#[error("The request had expired!")]
|
||||||
|
@ -92,6 +94,7 @@ impl ResponseError for CompatErr {
|
||||||
match self {
|
match self {
|
||||||
Self::AnyhowErr(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
Self::AnyhowErr(_) => StatusCode::INTERNAL_SERVER_ERROR,
|
||||||
Self::SpecialErr(error) => match error {
|
Self::SpecialErr(error) => match error {
|
||||||
|
SpecialErrors::ContainsSecret => StatusCode::BAD_REQUEST,
|
||||||
SpecialErrors::ExpiredRequest => StatusCode::BAD_REQUEST,
|
SpecialErrors::ExpiredRequest => StatusCode::BAD_REQUEST,
|
||||||
SpecialErrors::InexistingUser => StatusCode::NOT_FOUND,
|
SpecialErrors::InexistingUser => StatusCode::NOT_FOUND,
|
||||||
SpecialErrors::InvalidCert => StatusCode::BAD_REQUEST,
|
SpecialErrors::InvalidCert => StatusCode::BAD_REQUEST,
|
||||||
|
|
|
@ -101,7 +101,11 @@ async fn index(req: HttpRequest) -> Result<HttpResponse, CompatErr> {
|
||||||
#[post("/api/submit")]
|
#[post("/api/submit")]
|
||||||
async fn submit(pem: web::Form<Key>) -> Result<HttpResponse, CompatErr> {
|
async fn submit(pem: web::Form<Key>) -> Result<HttpResponse, CompatErr> {
|
||||||
let cert = parse_pem(&pem.key)?;
|
let cert = parse_pem(&pem.key)?;
|
||||||
let email = get_email_from_cert(&cert)?;
|
let validcert = validate_cert!(cert)?;
|
||||||
|
if validcert.is_tsk() {
|
||||||
|
Err(SpecialErrors::ContainsSecret)?
|
||||||
|
}
|
||||||
|
let email = get_email_from_cert(&validcert)?;
|
||||||
debug!("Handling user {} request to add a key...", email);
|
debug!("Handling user {} request to add a key...", email);
|
||||||
is_email_allowed(&email)?;
|
is_email_allowed(&email)?;
|
||||||
let token = gen_random_token();
|
let token = gen_random_token();
|
||||||
|
|
|
@ -15,6 +15,7 @@ use flexi_logger::{style, DeferredNow, FileSpec, FlexiLoggerError, Logger, Logge
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use log::error;
|
use log::error;
|
||||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
||||||
|
use sequoia_openpgp::cert::ValidCert;
|
||||||
use sequoia_openpgp::serialize::Marshal;
|
use sequoia_openpgp::serialize::Marshal;
|
||||||
use sequoia_openpgp::types::HashAlgorithm;
|
use sequoia_openpgp::types::HashAlgorithm;
|
||||||
use sequoia_openpgp::{parse::Parse, Cert};
|
use sequoia_openpgp::{parse::Parse, Cert};
|
||||||
|
@ -59,13 +60,12 @@ pub fn email_to_file_path(email: &str) -> Result<PathBuf> {
|
||||||
Ok(PathBuf::from(ROOT_FOLDER).join(directory))
|
Ok(PathBuf::from(ROOT_FOLDER).join(directory))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_key(cert: &Cert) -> Result<()> {
|
pub fn insert_key(cert: &ValidCert) -> Result<()> {
|
||||||
let validcert = validate_cert!(cert)?;
|
|
||||||
let path = email_to_file_path(&get_email_from_cert(cert)?)?;
|
let path = email_to_file_path(&get_email_from_cert(cert)?)?;
|
||||||
|
|
||||||
fs::create_dir_all(path.parent().unwrap())?;
|
fs::create_dir_all(path.parent().unwrap())?;
|
||||||
let mut file = fs::File::create(&path)?;
|
let mut file = fs::File::create(&path)?;
|
||||||
validcert.export(&mut file)?;
|
cert.export(&mut file)?;
|
||||||
|
|
||||||
fs::OpenOptions::new()
|
fs::OpenOptions::new()
|
||||||
.write(true)
|
.write(true)
|
||||||
|
@ -115,9 +115,8 @@ pub fn gen_random_token() -> String {
|
||||||
(0..10).map(|_| rng.sample(Alphanumeric) as char).collect()
|
(0..10).map(|_| rng.sample(Alphanumeric) as char).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_email_from_cert(cert: &Cert) -> Result<String> {
|
pub fn get_email_from_cert(cert: &ValidCert) -> Result<String> {
|
||||||
let validcert = validate_cert!(cert)?;
|
let userid_opt = log_err!(cert.primary_userid(), debug)?;
|
||||||
let userid_opt = log_err!(validcert.primary_userid(), debug)?;
|
|
||||||
let email_opt = userid_opt.email()?;
|
let email_opt = userid_opt.email()?;
|
||||||
match email_opt {
|
match email_opt {
|
||||||
Some(email) => Ok(email),
|
Some(email) => Ok(email),
|
||||||
|
|
Loading…
Reference in a new issue