Implement constant-time equality for delete tokens, inline alias cleanup

This commit is contained in:
asonix 2023-10-04 11:41:09 -05:00
parent 40367b65c9
commit 6c9a50a1ad
8 changed files with 22 additions and 36 deletions

18
Cargo.lock generated
View File

@ -937,12 +937,6 @@ dependencies = [
"tracing", "tracing",
] ]
[[package]]
name = "half"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.3"
@ -1649,12 +1643,12 @@ dependencies = [
"reqwest-tracing", "reqwest-tracing",
"rusty-s3", "rusty-s3",
"serde", "serde",
"serde_cbor",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"sha2", "sha2",
"sled", "sled",
"storage-path-generator", "storage-path-generator",
"subtle",
"thiserror", "thiserror",
"time", "time",
"tokio", "tokio",
@ -2128,16 +2122,6 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "serde_cbor"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
dependencies = [
"half",
"serde",
]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.188" version = "1.0.188"

View File

@ -41,12 +41,12 @@ reqwest-middleware = "0.2.2"
reqwest-tracing = { version = "0.4.5" } reqwest-tracing = { version = "0.4.5" }
rusty-s3 = "0.4.1" rusty-s3 = "0.4.1"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_cbor = "0.11.2"
serde_json = "1.0" serde_json = "1.0"
serde_urlencoded = "0.7.1" serde_urlencoded = "0.7.1"
sha2 = "0.10.0" sha2 = "0.10.0"
sled = { version = "0.34.7" } sled = { version = "0.34.7" }
storage-path-generator = "0.1.0" storage-path-generator = "0.1.0"
subtle = { version = "2.5.0", default-features = false }
thiserror = "1.0" thiserror = "1.0"
time = { version = "0.3.0", features = ["serde", "serde-well-known"] } time = { version = "0.3.0", features = ["serde", "serde-well-known"] }
tokio = { version = "1", features = ["full", "tracing"] } tokio = { version = "1", features = ["full", "tracing"] }

View File

@ -34,15 +34,15 @@ path = 'data/sled-repo-local'
cache_capacity = 67108864 cache_capacity = 67108864
export_path = "data/exports-local" export_path = "data/exports-local"
# [store]
# type = 'filesystem'
# path = 'data/files-local'
[store] [store]
type = 'object_storage' type = 'filesystem'
endpoint = 'http://localhost:3900' path = 'data/files-local'
use_path_style = true
bucket_name = 'pict-rs' # [store]
region = 'garage' # type = 'object_storage'
access_key = 'GK2182acf19c2bdb8b9c20e16e' # endpoint = 'http://localhost:3900'
secret_key = '0072105b8659adc02cce21d9135a88ebc279b3a35e170d23d31c63fb9307a168' # use_path_style = true
# bucket_name = 'pict-rs'
# region = 'garage'
# access_key = 'GK2182acf19c2bdb8b9c20e16e'
# secret_key = '0072105b8659adc02cce21d9135a88ebc279b3a35e170d23d31c63fb9307a168'

View File

@ -124,9 +124,6 @@ pub(crate) enum UploadError {
#[error("Error in json")] #[error("Error in json")]
Json(#[from] serde_json::Error), Json(#[from] serde_json::Error),
#[error("Error in cbor")]
Cbor(#[from] serde_cbor::Error),
#[error("Range header not satisfiable")] #[error("Range header not satisfiable")]
Range, Range,

View File

@ -573,7 +573,8 @@ async fn delete<R: FullRepo>(
let token = DeleteToken::from_existing(&token); let token = DeleteToken::from_existing(&token);
let alias = Alias::from_existing(&alias); let alias = Alias::from_existing(&alias);
queue::cleanup_alias(&repo, alias, token).await?; // cleanup alias inline
queue::cleanup::alias(&repo, alias, token).await?;
Ok(HttpResponse::NoContent().finish()) Ok(HttpResponse::NoContent().finish())
} }

View File

@ -12,7 +12,7 @@ use reqwest_middleware::ClientWithMiddleware;
use std::{future::Future, path::PathBuf, pin::Pin}; use std::{future::Future, path::PathBuf, pin::Pin};
use tracing::Instrument; use tracing::Instrument;
mod cleanup; pub(crate) mod cleanup;
mod process; mod process;
#[derive(Debug)] #[derive(Debug)]

View File

@ -124,13 +124,13 @@ where
} }
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
async fn alias<R>(repo: &R, alias: Alias, token: DeleteToken) -> Result<(), Error> pub(crate) async fn alias<R>(repo: &R, alias: Alias, token: DeleteToken) -> Result<(), Error>
where where
R: FullRepo, R: FullRepo,
{ {
let saved_delete_token = repo.delete_token(&alias).await?; let saved_delete_token = repo.delete_token(&alias).await?;
if saved_delete_token.is_some() && saved_delete_token != Some(token) { if !saved_delete_token.as_ref().is_some_and(|t| t.ct_eq(&token)) {
return Err(UploadError::InvalidToken.into()); return Err(UploadError::InvalidToken.into());
} }

View File

@ -851,6 +851,10 @@ impl DeleteToken {
None None
} }
} }
pub(crate) fn ct_eq(&self, rhs: &Self) -> bool {
subtle::ConstantTimeEq::ct_eq(self.id.as_bytes(), rhs.id.as_bytes()).unwrap_u8() == 1
}
} }
impl UploadId { impl UploadId {