Chg: Test long-term and short-term key.
This commit is contained in:
parent
f000ef6a76
commit
95c06a4dae
13
src/auth.rs
13
src/auth.rs
@ -3,7 +3,7 @@
|
||||
use crate::config::AuthOptions;
|
||||
use crate::constants::{ATTR_NONCE, ATTR_REALM, ATTR_USERNAME};
|
||||
use crate::models::stun::StunMessage;
|
||||
use crate::stun::{find_message_integrity, validate_message_integrity};
|
||||
use crate::stun::{find_message_integrity, validate_message_integrity, validate_message_integrity_len_preserved};
|
||||
use crate::traits::CredentialStore;
|
||||
use async_trait::async_trait;
|
||||
use base64::Engine;
|
||||
@ -187,7 +187,9 @@ impl<S: CredentialStore + Clone> AuthManager<S> {
|
||||
|
||||
// Workaround: also accept short-term style (raw password as key) for test clients like turnutils_uclient.
|
||||
let short_key = password.as_bytes();
|
||||
if validate_message_integrity(msg, short_key) {
|
||||
if validate_message_integrity(msg, short_key)
|
||||
|| validate_message_integrity_len_preserved(msg, short_key)
|
||||
{
|
||||
warn!("auth accept via short-term key username={} realm={} peer={} (workaround)", username, realm, peer);
|
||||
return AuthStatus::Granted {
|
||||
username,
|
||||
@ -195,6 +197,13 @@ impl<S: CredentialStore + Clone> AuthManager<S> {
|
||||
};
|
||||
}
|
||||
|
||||
// Additional interop fallback: some clients miscompute length when adding FINGERPRINT;
|
||||
// try validation without adjusting the header length.
|
||||
if validate_message_integrity_len_preserved(msg, &key) {
|
||||
warn!("auth accept via len-preserved MI username={} realm={} peer={} (interop fallback)", username, realm, peer);
|
||||
return AuthStatus::Granted { username, key };
|
||||
}
|
||||
|
||||
let key_hex = hex::encode(&key);
|
||||
warn!("auth reject: bad credentials username={} realm={} peer={} a1_md5={} (debug)", username, realm, peer, key_hex);
|
||||
AuthStatus::Reject {
|
||||
|
||||
26
src/stun.rs
26
src/stun.rs
@ -386,6 +386,32 @@ pub fn validate_message_integrity(msg: &StunMessage, key: &[u8]) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
/// Fallback validator: compute MESSAGE-INTEGRITY without adjusting the STUN header length.
|
||||
/// Some clients incorrectly leave the header length unchanged when appending FINGERPRINT;
|
||||
/// this matches that behaviour for interop.
|
||||
pub fn validate_message_integrity_len_preserved(msg: &StunMessage, key: &[u8]) -> bool {
|
||||
if let Some(mi) = find_message_integrity(msg) {
|
||||
if mi.value.len() != HMAC_SHA1_LEN {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mi_end = mi.offset + 4 + HMAC_SHA1_LEN;
|
||||
if mi_end > msg.raw.len() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let mut signed = msg.raw[..mi_end].to_vec();
|
||||
let value_start = mi.offset + 4;
|
||||
for b in &mut signed[value_start..value_start + HMAC_SHA1_LEN] {
|
||||
*b = 0;
|
||||
}
|
||||
|
||||
let computed = crate::stun::compute_message_integrity(key, &signed);
|
||||
return &computed[..HMAC_SHA1_LEN] == mi.value.as_slice();
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn append_message_integrity(buf: &mut bytes::BytesMut, key: &[u8]) {
|
||||
// Append attribute header and placeholder; set length to end-of-MI, then compute
|
||||
// HMAC over the message slice up to end-of-MI (with the MI placeholder still zero).
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user