Fixes for test + Rustfmt

This commit is contained in:
Alexey 2026-04-06 16:12:46 +03:00
parent 8d865a980c
commit d848e4a729
No known key found for this signature in database
4 changed files with 45 additions and 33 deletions

View File

@ -74,7 +74,11 @@ impl UserAuthSnapshot {
.entry(Self::sni_lookup_hash(user)) .entry(Self::sni_lookup_hash(user))
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
.push(user_id); .push(user_id);
if let Some(initial) = user.as_bytes().first().map(|byte| byte.to_ascii_lowercase()) { if let Some(initial) = user
.as_bytes()
.first()
.map(|byte| byte.to_ascii_lowercase())
{
sni_initial_index sni_initial_index
.entry(initial) .entry(initial)
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
@ -110,7 +114,10 @@ impl UserAuthSnapshot {
} }
pub(crate) fn sni_initial_candidates(&self, sni: &str) -> Option<&[u32]> { pub(crate) fn sni_initial_candidates(&self, sni: &str) -> Option<&[u32]> {
let initial = sni.as_bytes().first().map(|byte| byte.to_ascii_lowercase())?; let initial = sni
.as_bytes()
.first()
.map(|byte| byte.to_ascii_lowercase())?;
self.sni_initial_index.get(&initial).map(Vec::as_slice) self.sni_initial_index.get(&initial).map(Vec::as_slice)
} }

View File

@ -376,7 +376,9 @@ pub fn drop_privileges(
unistd::setuid(uid).map_err(DaemonError::PrivilegeDrop)?; unistd::setuid(uid).map_err(DaemonError::PrivilegeDrop)?;
info!(uid = uid.as_raw(), "Dropped user privileges"); info!(uid = uid.as_raw(), "Dropped user privileges");
if uid.as_raw() != 0 && let Some(pid) = pid_file { if uid.as_raw() != 0
&& let Some(pid) = pid_file
{
let parent = pid.path.parent().unwrap_or(Path::new(".")); let parent = pid.path.parent().unwrap_or(Path::new("."));
let probe_path = parent.join(format!( let probe_path = parent.join(format!(
".telemt_pid_probe_{}_{}", ".telemt_pid_probe_{}_{}",

View File

@ -7,16 +7,16 @@ use dashmap::mapref::entry::Entry;
use hmac::{Hmac, Mac}; use hmac::{Hmac, Mac};
#[cfg(test)] #[cfg(test)]
use std::collections::HashSet; use std::collections::HashSet;
use std::collections::hash_map::DefaultHasher;
#[cfg(test)] #[cfg(test)]
use std::collections::hash_map::RandomState; use std::collections::hash_map::RandomState;
use std::collections::hash_map::DefaultHasher;
use std::hash::{BuildHasher, Hash, Hasher}; use std::hash::{BuildHasher, Hash, Hasher};
use std::net::SocketAddr; use std::net::SocketAddr;
use std::net::{IpAddr, Ipv6Addr}; use std::net::{IpAddr, Ipv6Addr};
use std::sync::atomic::Ordering;
use std::sync::Arc; use std::sync::Arc;
#[cfg(test)] #[cfg(test)]
use std::sync::Mutex; use std::sync::Mutex;
use std::sync::atomic::Ordering;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt};
use tracing::{debug, info, trace, warn}; use tracing::{debug, info, trace, warn};
@ -358,11 +358,10 @@ fn validate_mtproto_secret_candidate(
config: &ProxyConfig, config: &ProxyConfig,
is_tls: bool, is_tls: bool,
) -> Option<MtprotoCandidateValidation> { ) -> Option<MtprotoCandidateValidation> {
let mut dec_key_input = [0u8; PREKEY_LEN + ACCESS_SECRET_BYTES]; let mut dec_key_input = Zeroizing::new(Vec::with_capacity(PREKEY_LEN + secret.len()));
dec_key_input[..PREKEY_LEN].copy_from_slice(dec_prekey); dec_key_input.extend_from_slice(dec_prekey);
dec_key_input[PREKEY_LEN..].copy_from_slice(secret); dec_key_input.extend_from_slice(secret);
let dec_key = sha256(&dec_key_input); let dec_key = Zeroizing::new(sha256(&dec_key_input));
dec_key_input.zeroize();
let mut decryptor = AesCtr::new(&dec_key, dec_iv); let mut decryptor = AesCtr::new(&dec_key, dec_iv);
let mut decrypted = *handshake; let mut decrypted = *handshake;
@ -381,20 +380,19 @@ fn validate_mtproto_secret_candidate(
let dc_idx = i16::from_le_bytes([decrypted[DC_IDX_POS], decrypted[DC_IDX_POS + 1]]); let dc_idx = i16::from_le_bytes([decrypted[DC_IDX_POS], decrypted[DC_IDX_POS + 1]]);
let mut enc_key_input = [0u8; PREKEY_LEN + ACCESS_SECRET_BYTES]; let mut enc_key_input = Zeroizing::new(Vec::with_capacity(PREKEY_LEN + secret.len()));
enc_key_input[..PREKEY_LEN].copy_from_slice(enc_prekey); enc_key_input.extend_from_slice(enc_prekey);
enc_key_input[PREKEY_LEN..].copy_from_slice(secret); enc_key_input.extend_from_slice(secret);
let enc_key = sha256(&enc_key_input); let enc_key = Zeroizing::new(sha256(&enc_key_input));
enc_key_input.zeroize();
let encryptor = AesCtr::new(&enc_key, enc_iv); let encryptor = AesCtr::new(&enc_key, enc_iv);
Some(MtprotoCandidateValidation { Some(MtprotoCandidateValidation {
proto_tag, proto_tag,
dc_idx, dc_idx,
dec_key, dec_key: *dec_key,
dec_iv, dec_iv,
enc_key, enc_key: *enc_key,
enc_iv, enc_iv,
decryptor, decryptor,
encryptor, encryptor,
@ -1192,7 +1190,9 @@ where
.as_deref() .as_deref()
.and_then(|sni| sticky_hint_get_by_sni(shared, sni)); .and_then(|sni| sticky_hint_get_by_sni(shared, sni));
let sticky_prefix_hint = sticky_hint_get_by_ip_prefix(shared, peer.ip()); let sticky_prefix_hint = sticky_hint_get_by_ip_prefix(shared, peer.ip());
let sni_candidates = client_sni.as_deref().and_then(|sni| snapshot.sni_candidates(sni)); let sni_candidates = client_sni
.as_deref()
.and_then(|sni| snapshot.sni_candidates(sni));
let sni_initial_candidates = client_sni let sni_initial_candidates = client_sni
.as_deref() .as_deref()
.and_then(|sni| snapshot.sni_initial_candidates(sni)); .and_then(|sni| snapshot.sni_initial_candidates(sni));
@ -1256,7 +1256,8 @@ where
matched = try_user_id!(user_id); matched = try_user_id!(user_id);
} }
if !matched && !budget_exhausted if !matched
&& !budget_exhausted
&& let Some(candidate_ids) = sni_candidates && let Some(candidate_ids) = sni_candidates
{ {
for &user_id in candidate_ids { for &user_id in candidate_ids {
@ -1270,7 +1271,8 @@ where
} }
} }
if !matched && !budget_exhausted if !matched
&& !budget_exhausted
&& let Some(candidate_ids) = sni_initial_candidates && let Some(candidate_ids) = sni_initial_candidates
{ {
for &user_id in candidate_ids { for &user_id in candidate_ids {
@ -1730,13 +1732,15 @@ where
return HandshakeResult::BadClient { reader, writer }; return HandshakeResult::BadClient { reader, writer };
} }
let dec_key = Zeroizing::new(validation.dec_key);
let enc_key = Zeroizing::new(validation.enc_key);
let success = HandshakeSuccess { let success = HandshakeSuccess {
user: matched_user.clone(), user: matched_user.clone(),
dc_idx: validation.dc_idx, dc_idx: validation.dc_idx,
proto_tag: validation.proto_tag, proto_tag: validation.proto_tag,
dec_key: validation.dec_key, dec_key: *dec_key,
dec_iv: validation.dec_iv, dec_iv: validation.dec_iv,
enc_key: validation.enc_key, enc_key: *enc_key,
enc_iv: validation.enc_iv, enc_iv: validation.enc_iv,
peer, peer,
is_tls, is_tls,
@ -1806,13 +1810,15 @@ where
return HandshakeResult::BadClient { reader, writer }; return HandshakeResult::BadClient { reader, writer };
} }
let dec_key = Zeroizing::new(validation.dec_key);
let enc_key = Zeroizing::new(validation.enc_key);
let success = HandshakeSuccess { let success = HandshakeSuccess {
user: user.clone(), user: user.clone(),
dc_idx: validation.dc_idx, dc_idx: validation.dc_idx,
proto_tag: validation.proto_tag, proto_tag: validation.proto_tag,
dec_key: validation.dec_key, dec_key: *dec_key,
dec_iv: validation.dec_iv, dec_iv: validation.dec_iv,
enc_key: validation.enc_key, enc_key: *enc_key,
enc_iv: validation.enc_iv, enc_iv: validation.enc_iv,
peer, peer,
is_tls, is_tls,

View File

@ -4,8 +4,8 @@ use dashmap::DashMap;
use rand::rngs::StdRng; use rand::rngs::StdRng;
use rand::{RngExt, SeedableRng}; use rand::{RngExt, SeedableRng};
use std::net::{IpAddr, Ipv4Addr}; use std::net::{IpAddr, Ipv4Addr};
use std::sync::atomic::Ordering;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::Ordering;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tokio::sync::Barrier; use tokio::sync::Barrier;
@ -1127,10 +1127,7 @@ async fn tls_runtime_snapshot_updates_sticky_and_recent_hints() {
"successful runtime-snapshot auth must seed sticky ip cache" "successful runtime-snapshot auth must seed sticky ip cache"
); );
assert_eq!( assert_eq!(
shared shared.handshake.sticky_user_by_ip_prefix.len(),
.handshake
.sticky_user_by_ip_prefix
.len(),
1, 1,
"successful runtime-snapshot auth must seed sticky prefix cache" "successful runtime-snapshot auth must seed sticky prefix cache"
); );
@ -1150,10 +1147,10 @@ async fn tls_overload_budget_limits_candidate_scan_depth() {
config.access.users.clear(); config.access.users.clear();
config.access.ignore_time_skew = true; config.access.ignore_time_skew = true;
for idx in 0..32u8 { for idx in 0..32u8 {
config config.access.users.insert(
.access format!("user-{idx}"),
.users format!("{:032x}", u128::from(idx) + 1),
.insert(format!("user-{idx}"), format!("{:032x}", u128::from(idx) + 1)); );
} }
config.rebuild_runtime_user_auth().unwrap(); config.rebuild_runtime_user_auth().unwrap();