diff --git a/src/api/k2v/api_server.rs b/src/api/k2v/api_server.rs index 39b6f267..7ee85bd9 100644 --- a/src/api/k2v/api_server.rs +++ b/src/api/k2v/api_server.rs @@ -91,6 +91,7 @@ impl ApiHandler for K2VApiServer { req, &mut content_sha256, &garage.config.s3_api.s3_region, + "s3", )?; let bucket_id = resolve_bucket(&garage, &bucket_name, &api_key).await?; diff --git a/src/api/s3/api_server.rs b/src/api/s3/api_server.rs index d908f84a..78a69d53 100644 --- a/src/api/s3/api_server.rs +++ b/src/api/s3/api_server.rs @@ -131,6 +131,7 @@ impl ApiHandler for S3ApiServer { req, &mut content_sha256, &garage.config.s3_api.s3_region, + "s3", )?; let bucket_name = match bucket_name { diff --git a/src/api/signature/mod.rs b/src/api/signature/mod.rs index ebdee6da..5646f4fa 100644 --- a/src/api/signature/mod.rs +++ b/src/api/signature/mod.rs @@ -42,6 +42,11 @@ pub fn signing_hmac( Ok(hmac) } -pub fn compute_scope(datetime: &DateTime, region: &str) -> String { - format!("{}/{}/s3/aws4_request", datetime.format(SHORT_DATE), region,) +pub fn compute_scope(datetime: &DateTime, region: &str, service: &str) -> String { + format!( + "{}/{}/{}/aws4_request", + datetime.format(SHORT_DATE), + region, + service + ) } diff --git a/src/api/signature/payload.rs b/src/api/signature/payload.rs index 59d7ff6a..2c7f2c01 100644 --- a/src/api/signature/payload.rs +++ b/src/api/signature/payload.rs @@ -11,8 +11,8 @@ use garage_util::data::Hash; use garage_model::garage::Garage; use garage_model::key_table::*; -use super::signing_hmac; -use super::{LONG_DATETIME, SHORT_DATE}; +use super::LONG_DATETIME; +use super::{compute_scope, signing_hmac}; use crate::encoding::uri_encode; use crate::error::*; @@ -291,12 +291,7 @@ pub async fn verify_v4( ) -> Result { let (key_id, scope) = parse_credential(credential)?; - let scope_expected = format!( - "{}/{}/{}/aws4_request", - date.format(SHORT_DATE), - garage.config.s3_api.s3_region, - service - ); + let scope_expected = compute_scope(date, &garage.config.s3_api.s3_region, service); if scope != scope_expected { return Err(Error::AuthorizationHeaderMalformed(scope.to_string())); } diff --git a/src/api/signature/streaming.rs b/src/api/signature/streaming.rs index a46db706..ded9d993 100644 --- a/src/api/signature/streaming.rs +++ b/src/api/signature/streaming.rs @@ -19,6 +19,7 @@ pub fn parse_streaming_body( req: Request, content_sha256: &mut Option, region: &str, + service: &str, ) -> Result, Error> { match req.headers().get("x-amz-content-sha256") { Some(header) if header == "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" => { @@ -41,8 +42,8 @@ pub fn parse_streaming_body( .ok_or_bad_request("Invalid date")?; let date: DateTime = DateTime::from_utc(date, Utc); - let scope = compute_scope(&date, region); - let signing_hmac = crate::signature::signing_hmac(&date, secret_key, region, "s3") + let scope = compute_scope(&date, region, service); + let signing_hmac = crate::signature::signing_hmac(&date, secret_key, region, service) .ok_or_internal_error("Unable to build signing HMAC")?; Ok(req.map(move |body| { @@ -343,7 +344,7 @@ mod tests { .with_timezone(&Utc); let secret_key = "test"; let region = "test"; - let scope = crate::signature::compute_scope(&datetime, region); + let scope = crate::signature::compute_scope(&datetime, region, "s3"); let signing_hmac = crate::signature::signing_hmac(&datetime, secret_key, region, "s3").unwrap(); diff --git a/src/garage/tests/common/custom_requester.rs b/src/garage/tests/common/custom_requester.rs index 580691a1..d517128a 100644 --- a/src/garage/tests/common/custom_requester.rs +++ b/src/garage/tests/common/custom_requester.rs @@ -32,6 +32,7 @@ impl CustomRequester { pub fn builder(&self, bucket: String) -> RequestBuilder<'_> { RequestBuilder { requester: self, + service: "s3", bucket, method: Method::GET, path: String::new(), @@ -47,6 +48,7 @@ impl CustomRequester { pub struct RequestBuilder<'a> { requester: &'a CustomRequester, + service: &'static str, bucket: String, method: Method, path: String, @@ -59,6 +61,10 @@ pub struct RequestBuilder<'a> { } impl<'a> RequestBuilder<'a> { + pub fn service(&mut self, service: &'static str) -> &mut Self { + self.service = service; + self + } pub fn method(&mut self, method: Method) -> &mut Self { self.method = method; self @@ -118,7 +124,7 @@ impl<'a> RequestBuilder<'a> { let uri = format!("{}{}", self.requester.uri, path); let now = Utc::now(); - let scope = signature::compute_scope(&now, super::REGION.as_ref()); + let scope = signature::compute_scope(&now, super::REGION.as_ref(), self.service); let mut signer = signature::signing_hmac( &now, &self.requester.key.secret,