Check pubkey

This commit is contained in:
Pascal Engélibert 2020-12-08 19:53:30 +01:00
parent bd632e3ed1
commit 7962df9ae6
6 changed files with 85 additions and 41 deletions

7
Cargo.lock generated
View File

@ -113,6 +113,12 @@ dependencies = [
"byte-tools",
]
[[package]]
name = "bs58"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3"
[[package]]
name = "buf_redux"
version = "0.8.4"
@ -436,6 +442,7 @@ name = "gmarche"
version = "0.1.0"
dependencies = [
"bincode",
"bs58",
"dirs",
"handlebars",
"hex",

View File

@ -6,6 +6,7 @@ edition = "2018"
[dependencies]
bincode = "1.3.1"
bs58 = "0.4.0"
dirs = "3.0.1"
handlebars = "3.5.1"
hex = "0.4.2"

View File

@ -6,6 +6,7 @@ mod db;
mod server;
mod static_files;
mod templates;
mod utils;
use structopt::StructOpt;

View File

@ -1,4 +1,4 @@
use super::{cli, config, db, static_files, templates};
use super::{cli, config, db, static_files, templates, utils::*};
use handlebars::to_json;
use serde::{Deserialize, Serialize};
@ -118,21 +118,28 @@ pub async fn start_server(
.and(warp::get())
.and(warp::fs::dir(opt.dir.0.join(static_files::STATIC_DIR)));
let handle_new_ad = {
let handle_index = handle_index.clone();
let dbs = dbs.clone();
let cache_ads = cache_ads.clone();
move |query: NewAdQuery| {
let mut hasher = Sha512Trunc256::new();
hasher.update(query.psw);
dbs.ads
let handle_new_ad =
{
let handle_index = handle_index.clone();
let dbs = dbs.clone();
let cache_ads = cache_ads.clone();
move |query: NewAdQuery| {
let mut hasher = Sha512Trunc256::new();
hasher.update(query.psw);
dbs.ads
.insert(
AdId::random(),
bincode::serialize(&Ad {
author: query.author,
password: hasher.finalize()[..].try_into().unwrap(),
price: query.price,
pubkey: (!query.pubkey.is_empty()).then_some(query.pubkey),
pubkey: (!query.pubkey.is_empty()).then_some(match format_pubkey(&query.pubkey) {
Ok(pubkey) => pubkey,
Err(e) => return handle_index(&[ErrorTemplate{text: match e {
PubkeyDecodeError::BadChecksum => "La somme de contrôle de la clé publique est incorrecte.",
PubkeyDecodeError::BadFormat => "Le format de la clé publique est incorrect.",
}}])
}),
quantity: query.quantity,
time: 0,
title: query.title,
@ -140,24 +147,24 @@ pub async fn start_server(
.unwrap(),
)
.unwrap();
dbs.ads.flush().unwrap();
let mut cache_ads = cache_ads.write().unwrap();
*cache_ads = to_json(
dbs.ads
.iter()
.filter_map(|x| {
let (ad_id, ad) = x.ok()?;
Some(AdWithId {
id: hex::encode(ad_id.as_ref()),
ad: bincode::deserialize::<Ad>(&ad).ok()?,
dbs.ads.flush().unwrap();
let mut cache_ads = cache_ads.write().unwrap();
*cache_ads = to_json(
dbs.ads
.iter()
.filter_map(|x| {
let (ad_id, ad) = x.ok()?;
Some(AdWithId {
id: hex::encode(ad_id.as_ref()),
ad: bincode::deserialize::<Ad>(&ad).ok()?,
})
})
})
.collect::<Vec<AdWithId>>(),
);
drop(cache_ads);
handle_index(&[])
}
};
.collect::<Vec<AdWithId>>(),
);
drop(cache_ads);
handle_index(&[])
}
};
let handle_rm_ad = {
let handle_index = handle_index.clone();
@ -259,14 +266,10 @@ pub async fn start_server(
let handle_admin_login = handle_admin_login.clone();
let config = config.clone();
move |psw, query| {
dbg!();
if config.admin_passwords.contains(&psw) {
dbg!();
let AdminQuery::RmAdQuery(query) = query;
dbg!();
handle_admin_rm_ad(query)
} else {
dbg!();
handle_admin_login(&[ErrorTemplate {
text: "Mot de passe administrateur invalide",
}])
@ -278,12 +281,9 @@ pub async fn start_server(
let handle_admin_login = handle_admin_login.clone();
let config = config.clone();
move |psw| {
dbg!();
if config.admin_passwords.contains(&psw) {
dbg!();
handle_admin(&[])
} else {
dbg!();
handle_admin_login(&[ErrorTemplate {
text: "Mot de passe administrateur invalide",
}])
@ -292,10 +292,7 @@ pub async fn start_server(
}))
.or(warp::path::end().map({
let handle_admin_login = handle_admin_login.clone();
move || {
dbg!();
handle_admin_login(&[])
}
move || handle_admin_login(&[])
})),
)
.or(warp::path("login").and(warp::path::end()).and(
@ -304,9 +301,7 @@ pub async fn start_server(
.or(warp::body::form::<AdminLoginQuery>().map({
let config = config.clone();
move |query: AdminLoginQuery| {
dbg!();
if config.admin_passwords.contains(&query.psw) {
dbg!();
warp::reply::with_header(
warp::redirect(warp::http::Uri::from_static("/admin")),
"Set-Cookie",
@ -317,7 +312,6 @@ pub async fn start_server(
)
.into_response()
} else {
dbg!();
handle_admin_login(&[ErrorTemplate {
text: "Mot de passe administrateur invalide",
}])

37
src/utils.rs Normal file
View File

@ -0,0 +1,37 @@
use sha2::{Digest, Sha256};
pub enum PubkeyDecodeError {
BadChecksum,
BadFormat,
}
/// Decode pubkey from base 58
/// Verify checksum if provided
/// Accepts any checksum length >=3
pub fn format_pubkey(raw: &str) -> Result<String, PubkeyDecodeError> {
let mut iter = raw.splitn(2, ':');
let mut pubkey = [0u8; 32];
bs58::decode(iter.next().ok_or(PubkeyDecodeError::BadFormat)?)
.into(&mut pubkey)
.map_err(|_| PubkeyDecodeError::BadFormat)?;
let mut hasher1 = Sha256::new();
hasher1.update(&pubkey.as_ref()[..32]);
let mut hasher2 = Sha256::new();
hasher2.update(hasher1.finalize());
let checksum = bs58::encode(hasher2.finalize()).into_string();
if let Some(given_checksum) = iter.next() {
if given_checksum.len() < 3 {
return Err(PubkeyDecodeError::BadFormat);
}
if !checksum.starts_with(given_checksum) {
return Err(PubkeyDecodeError::BadChecksum);
}
}
Ok(format!(
"{}:{}",
bs58::encode(pubkey).into_string(),
&checksum[..3]
))
}

View File

@ -48,6 +48,10 @@ h1, h2, h3, h4 {
width: 100%;
}
fieldset {
border: 1px dashed grey;
}
.center {
padding: 4px;
}