Fix SMB negotiate: cipher_count=1 and username case sensitivity

This commit is contained in:
Warren
2026-06-24 22:22:42 +08:00
parent dc217e8903
commit 6f223c9232
3 changed files with 10 additions and 9 deletions

View File

@@ -75,9 +75,10 @@ impl Share {
} }
/// Grant `access` to the given (already-registered) user. Multiple calls /// Grant `access` to the given (already-registered) user. Multiple calls
/// accumulate. /// accumulate. Username is normalized to lowercase for SMB case-insensitive
/// matching.
pub fn user(mut self, name: impl Into<String>, access: Access) -> Self { pub fn user(mut self, name: impl Into<String>, access: Access) -> Self {
self.users.insert(name.into(), access); self.users.insert(name.into().to_lowercase(), access);
self self
} }
@@ -163,7 +164,7 @@ impl SmbServerBuilder {
} }
pub fn user(mut self, name: impl Into<String>, password: impl Into<String>) -> Self { pub fn user(mut self, name: impl Into<String>, password: impl Into<String>) -> Self {
let n = name.into(); let n = name.into().to_lowercase();
if !self.users.contains_key(&n) { if !self.users.contains_key(&n) {
self.user_order.push(n.clone()); self.user_order.push(n.clone());
} }

View File

@@ -118,13 +118,13 @@ pub async fn handle(
data: signing_data, data: signing_data,
}; };
// ENCRYPTION_CAPABILITIES — advertise AES-128-GCM and AES-128-CCM. // ENCRYPTION_CAPABILITIES — advertise a single cipher (AES-128-GCM).
// GCM is preferred (SMB 3.1.1+), CCM is for Windows 8 compat (SMB 3.0). // Samba smbclient enforces cipher_count == 1 in the response
// (smbXcli_negprot_smb2_done: cipher_count != 1 → INVALID_NETWORK_RESPONSE).
let encryption_caps = EncryptionCapabilities { let encryption_caps = EncryptionCapabilities {
cipher_count: 2, cipher_count: 1,
ciphers: vec![ ciphers: vec![
EncryptionCapabilities::CIPHER_AES_128_GCM, EncryptionCapabilities::CIPHER_AES_128_GCM,
EncryptionCapabilities::CIPHER_AES_128_CCM,
], ],
}; };
let encryption_data = { let encryption_data = {

View File

@@ -743,7 +743,7 @@ impl NtlmServer {
Ok(AuthOutcome { Ok(AuthOutcome {
identity: Identity::User { identity: Identity::User {
user: auth.user.clone(), user: auth.user.to_lowercase(),
domain: auth.domain.clone(), domain: auth.domain.clone(),
}, },
session_key, session_key,
@@ -1008,7 +1008,7 @@ mod tests {
assert_eq!( assert_eq!(
outcome.identity, outcome.identity,
Identity::User { Identity::User {
user: "User".to_string(), user: "user".to_string(), // lowercase per SMB case-insensitive matching
domain: "Domain".to_string() domain: "Domain".to_string()
} }
); );