This commit is contained in:
Alexey
2026-08-22 16:22:07 +03:00
parent bb0d3ba927
commit fb47ad149c
57 changed files with 675 additions and 710 deletions
+5 -4
View File
@@ -69,13 +69,14 @@ pub(crate) use self::tls_handshake::handle_tls_handshake_with_shared_and_options
#[cfg(test)]
pub(crate) use self::auth_probe::{
auth_probe_fail_streak_for_testing_in_shared, auth_probe_is_throttled_for_testing_in_shared,
auth_probe_record_failure_for_testing, auth_probe_saturation_is_throttled_at_for_testing_in_shared,
auth_probe_record_failure_for_testing,
auth_probe_saturation_is_throttled_at_for_testing_in_shared,
auth_probe_saturation_is_throttled_for_testing_in_shared,
auth_probe_saturation_state_for_testing_in_shared,
auth_probe_saturation_state_lock_for_testing_in_shared, auth_probe_state_for_testing_in_shared,
clear_auth_probe_state_for_testing_in_shared, clear_unknown_sni_warn_state_for_testing_in_shared,
clear_warned_secrets_for_testing_in_shared, should_emit_unknown_sni_warn_for_testing_in_shared,
warned_secrets_for_testing_in_shared,
clear_auth_probe_state_for_testing_in_shared,
clear_unknown_sni_warn_state_for_testing_in_shared, clear_warned_secrets_for_testing_in_shared,
should_emit_unknown_sni_warn_for_testing_in_shared, warned_secrets_for_testing_in_shared,
};
const ACCESS_SECRET_BYTES: usize = 16;
+19 -5
View File
@@ -44,7 +44,10 @@ pub(super) fn sticky_hint_get_by_ip(shared: &ProxySharedState, peer_ip: IpAddr)
.map(|entry| *entry)
}
pub(super) fn sticky_hint_get_by_ip_prefix(shared: &ProxySharedState, peer_ip: IpAddr) -> Option<u32> {
pub(super) fn sticky_hint_get_by_ip_prefix(
shared: &ProxySharedState,
peer_ip: IpAddr,
) -> Option<u32> {
shared
.handshake
.sticky_user_by_ip_prefix
@@ -104,7 +107,11 @@ pub(super) fn record_recent_user_success_in(shared: &ProxySharedState, user_id:
ring[idx].store(user_id.saturating_add(1), Ordering::Relaxed);
}
pub(super) fn mark_candidate_if_new(tried_user_ids: &mut [u32], tried_len: &mut usize, user_id: u32) -> bool {
pub(super) fn mark_candidate_if_new(
tried_user_ids: &mut [u32],
tried_len: &mut usize,
user_id: u32,
) -> bool {
if tried_user_ids[..*tried_len].contains(&user_id) {
return false;
}
@@ -222,7 +229,11 @@ pub(super) fn warn_invalid_secret_once_in(
}
}
pub(super) fn decode_user_secret(shared: &ProxySharedState, name: &str, secret_hex: &str) -> Option<Vec<u8>> {
pub(super) fn decode_user_secret(
shared: &ProxySharedState,
name: &str,
secret_hex: &str,
) -> Option<Vec<u8>> {
match hex::decode(secret_hex) {
Ok(bytes) if bytes.len() == ACCESS_SECRET_BYTES => Some(bytes),
Ok(bytes) => {
@@ -251,7 +262,11 @@ pub(super) fn decode_user_secret(shared: &ProxySharedState, name: &str, secret_h
// over TCP (DD). Enforcing this separation prevents an attacker from using a
// TLS-capable client to bypass the operator intent for the direct MTProto mode,
// and vice versa.
pub(super) fn mode_enabled_for_proto(config: &ProxyConfig, proto_tag: ProtoTag, is_tls: bool) -> bool {
pub(super) fn mode_enabled_for_proto(
config: &ProxyConfig,
proto_tag: ProtoTag,
is_tls: bool,
) -> bool {
match proto_tag {
ProtoTag::Secure => {
if is_tls {
@@ -289,4 +304,3 @@ pub(super) fn decode_user_secrets_in(
secrets
}
+14 -5
View File
@@ -86,7 +86,11 @@ pub(super) fn auth_probe_scan_start_offset_in(
auth_probe_eviction_offset_in(shared, peer_ip, now) % state_len
}
pub(super) fn auth_probe_is_throttled_in(shared: &ProxySharedState, peer_ip: IpAddr, now: Instant) -> bool {
pub(super) fn auth_probe_is_throttled_in(
shared: &ProxySharedState,
peer_ip: IpAddr,
now: Instant,
) -> bool {
let peer_ip = normalize_auth_probe_ip(peer_ip);
let state = &shared.handshake.auth_probe;
let Some(entry) = state.get(&peer_ip) else {
@@ -135,7 +139,10 @@ pub(super) fn auth_probe_should_apply_preauth_throttle_in(
auth_probe_saturation_grace_exhausted_in(shared, peer_ip, now)
}
pub(super) fn auth_probe_saturation_is_throttled_in(shared: &ProxySharedState, now: Instant) -> bool {
pub(super) fn auth_probe_saturation_is_throttled_in(
shared: &ProxySharedState,
now: Instant,
) -> bool {
let mut guard = shared
.handshake
.auth_probe_saturation
@@ -198,7 +205,11 @@ pub(super) fn auth_probe_note_expensive_invalid_scan_in(
auth_probe_note_saturation_in(shared, now);
}
pub(super) fn auth_probe_record_failure_in(shared: &ProxySharedState, peer_ip: IpAddr, now: Instant) {
pub(super) fn auth_probe_record_failure_in(
shared: &ProxySharedState,
peer_ip: IpAddr,
now: Instant,
) {
let peer_ip = normalize_auth_probe_ip(peer_ip);
let state = &shared.handshake.auth_probe;
auth_probe_record_failure_with_state_in(shared, state, peer_ip, now);
@@ -504,5 +515,3 @@ pub(super) async fn maybe_apply_server_hello_delay(config: &ProxyConfig) {
tokio::time::sleep(Duration::from_millis(delay_ms)).await;
}
}
-1
View File
@@ -417,4 +417,3 @@ where
debug!(peer = %peer, "MTProto handshake: no matching user found");
HandshakeResult::BadClient { reader, writer }
}
-1
View File
@@ -96,4 +96,3 @@ pub fn encrypt_tg_nonce(nonce: &[u8; HANDSHAKE_LEN]) -> Vec<u8> {
let (encrypted, _, _) = encrypt_tg_nonce_with_ciphers(nonce);
encrypted
}
-1
View File
@@ -32,4 +32,3 @@ impl Drop for HandshakeSuccess {
self.enc_iv.zeroize();
}
}
-2
View File
@@ -237,7 +237,6 @@ where
}
}
let Some(validation) = tls_validation::validate_tls_client(
handshake,
peer,
@@ -422,4 +421,3 @@ async fn write_tls_response<W: AsyncWrite + Unpin>(
writer.write_all(response).await?;
writer.flush().await
}