mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-28 16:07:05 +00:00
fix(protocols): return errors instead of panics for sync signatures (#2120)
Co-authored-by: houseme <housemecn@gmail.com> Co-authored-by: heihutu <30542132+heihutu@users.noreply.github.com>
This commit is contained in:
@@ -276,24 +276,27 @@ pub fn extract_target_container(sync_to: &str) -> SwiftResult<String> {
|
|||||||
/// Generate sync signature for authentication
|
/// Generate sync signature for authentication
|
||||||
///
|
///
|
||||||
/// Uses HMAC-SHA1 of the request path with shared secret
|
/// Uses HMAC-SHA1 of the request path with shared secret
|
||||||
pub fn generate_sync_signature(path: &str, key: &str) -> String {
|
pub fn generate_sync_signature(path: &str, key: &str) -> SwiftResult<String> {
|
||||||
use hmac::{Hmac, KeyInit, Mac};
|
use hmac::{Hmac, KeyInit, Mac};
|
||||||
use sha1::Sha1;
|
use sha1::Sha1;
|
||||||
|
|
||||||
type HmacSha1 = Hmac<Sha1>;
|
type HmacSha1 = Hmac<Sha1>;
|
||||||
|
|
||||||
let mut mac = HmacSha1::new_from_slice(key.as_bytes()).unwrap_or_else(|_| panic!("HMAC key error"));
|
let mut mac = HmacSha1::new_from_slice(key.as_bytes())
|
||||||
|
.map_err(|_| SwiftError::BadRequest("Invalid X-Container-Sync-Key".to_string()))?;
|
||||||
|
|
||||||
mac.update(path.as_bytes());
|
mac.update(path.as_bytes());
|
||||||
|
|
||||||
let result = mac.finalize();
|
let result = mac.finalize();
|
||||||
hex::encode(result.into_bytes())
|
Ok(hex::encode(result.into_bytes()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify sync signature
|
/// Verify sync signature
|
||||||
pub fn verify_sync_signature(path: &str, key: &str, signature: &str) -> bool {
|
pub fn verify_sync_signature(path: &str, key: &str, signature: &str) -> bool {
|
||||||
let expected = generate_sync_signature(path, key);
|
match generate_sync_signature(path, key) {
|
||||||
expected == signature
|
Ok(expected) => expected == signature,
|
||||||
|
Err(_) => false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -454,15 +457,15 @@ mod tests {
|
|||||||
let path = "/v1/AUTH_test/container/object.txt";
|
let path = "/v1/AUTH_test/container/object.txt";
|
||||||
let key = "mysecretkey";
|
let key = "mysecretkey";
|
||||||
|
|
||||||
let sig1 = generate_sync_signature(path, key);
|
let sig1 = generate_sync_signature(path, key).expect("failed to generate sync signature");
|
||||||
let sig2 = generate_sync_signature(path, key);
|
let sig2 = generate_sync_signature(path, key).expect("failed to generate sync signature");
|
||||||
|
|
||||||
// Signature should be deterministic
|
// Signature should be deterministic
|
||||||
assert_eq!(sig1, sig2);
|
assert_eq!(sig1, sig2);
|
||||||
assert_eq!(sig1.len(), 40); // SHA1 = 20 bytes = 40 hex chars
|
assert_eq!(sig1.len(), 40); // SHA1 = 20 bytes = 40 hex chars
|
||||||
|
|
||||||
// Different key produces different signature
|
// Different key produces different signature
|
||||||
let sig3 = generate_sync_signature(path, "differentkey");
|
let sig3 = generate_sync_signature(path, "differentkey").expect("failed to generate sync signature");
|
||||||
assert_ne!(sig1, sig3);
|
assert_ne!(sig1, sig3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -471,7 +474,7 @@ mod tests {
|
|||||||
let path = "/v1/AUTH_test/container/object.txt";
|
let path = "/v1/AUTH_test/container/object.txt";
|
||||||
let key = "mysecretkey";
|
let key = "mysecretkey";
|
||||||
|
|
||||||
let signature = generate_sync_signature(path, key);
|
let signature = generate_sync_signature(path, key).expect("failed to generate sync signature");
|
||||||
assert!(verify_sync_signature(path, key, &signature));
|
assert!(verify_sync_signature(path, key, &signature));
|
||||||
|
|
||||||
// Wrong signature
|
// Wrong signature
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ fn test_sync_signatures() {
|
|||||||
let path = "/v1/AUTH_test/container/object.txt";
|
let path = "/v1/AUTH_test/container/object.txt";
|
||||||
let key = "sharedsecret";
|
let key = "sharedsecret";
|
||||||
|
|
||||||
let sig1 = sync::generate_sync_signature(path, key);
|
let sig1 = sync::generate_sync_signature(path, key).expect("failed to generate sync signature");
|
||||||
let sig2 = sync::generate_sync_signature(path, key);
|
let sig2 = sync::generate_sync_signature(path, key).expect("failed to generate sync signature");
|
||||||
|
|
||||||
assert_eq!(sig1, sig2);
|
assert_eq!(sig1, sig2);
|
||||||
assert_eq!(sig1.len(), 40); // HMAC-SHA1 = 40 hex chars
|
assert_eq!(sig1.len(), 40); // HMAC-SHA1 = 40 hex chars
|
||||||
|
|||||||
Reference in New Issue
Block a user