Skip to content

Commit

Permalink
fix(proxy): Fix whitelist default policy denial (#42)
Browse files Browse the repository at this point in the history
* fix(proxy): Fix whitelist default policy denial

* fix(proxy): Fix whitelist default policy denial

* fix(proxy): Fix whitelist default policy denial
  • Loading branch information
0x676e67 authored May 14, 2024
1 parent 95dfa03 commit 0a102a3
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 15 deletions.
50 changes: 50 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import ipaddress
import random
import hashlib
import string

def generate_ip_from_cidr(cidr, session_str):
# Parse the CIDR notation
network = ipaddress.IPv6Network(cidr)
network_address = int(network.network_address)
netmask = int(network.netmask)

# Combine the CIDR range string and session string
combined_str = f"{cidr}-{session_str}"

# Generate a hash value from the combined string to use as a seed
seed = int(hashlib.sha1(combined_str.encode()).hexdigest(), 16)
random.seed(seed)

# Generate a random offset within the network range
offset = random.randint(0, netmask ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)

# Calculate the IP address using the network address and offset
ip_address_int = network_address + offset
ip_address = ipaddress.IPv6Address(ip_address_int)

return ip_address

def session_generator(size, chars=string.ascii_uppercase + string.digits + string.ascii_lowercase):
random.seed(size)
return ''.join(random.choice(chars) for _ in range(size))

# Example usage
cidr = "2001:db8::/48"
session_len = 1000
sessions = []

for x in range(session_len):
sessions.append(session_generator(x))

result = []
for x in sessions:
result.append(generate_ip_from_cidr(cidr, x))

check = []
for x in sessions:
check.append(generate_ip_from_cidr(cidr, x))

for x in result:
if x not in check:
print(x)
3 changes: 3 additions & 0 deletions src/proxy/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ use std::net::IpAddr;

/// Trait for checking if an IP address is in the whitelist.
pub trait Whitelist {
/// Checks is empty.
fn is_empty(&self) -> bool;

/// Checks if the given IP address is in the whitelist.
fn contains(&self, ip: IpAddr) -> bool;
}
Expand Down
20 changes: 13 additions & 7 deletions src/proxy/http/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,24 @@ pub enum Authenticator {
}

impl Whitelist for Authenticator {
fn is_empty(&self) -> bool {
let whitelist = match self {
Authenticator::None(whitelist) => whitelist,
Authenticator::Password { whitelist, .. } => whitelist,
};

// Check if the whitelist is empty
whitelist.is_empty()
}

fn contains(&self, ip: IpAddr) -> bool {
let whitelist = match self {
Authenticator::None(whitelist) => whitelist,
Authenticator::Password { whitelist, .. } => whitelist,
};

// If whitelist is empty, allow all
if whitelist.is_empty() {
return true;
} else {
// Check if the ip is in the whitelist
return whitelist.contains(&ip);
}
whitelist.contains(&ip)
}
}

Expand All @@ -53,7 +58,8 @@ impl Authenticator {
match self {
Authenticator::None(..) => {
// If whitelist is empty, allow all
if !self.contains(socket.ip()) {
let is_equal = self.contains(socket.ip()) || self.is_empty();
if !is_equal {
tracing::warn!("Unauthorized access from {}", socket);
return Err(AuthError::Unauthorized);
}
Expand Down
25 changes: 17 additions & 8 deletions src/proxy/socks5/server/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@ impl NoAuth {
}

impl Whitelist for NoAuth {
fn is_empty(&self) -> bool {
// Check if the whitelist is empty
self.0.is_empty()
}

fn contains(&self, ip: IpAddr) -> bool {
// If whitelist is empty, allow all
if self.0.is_empty() {
return true;
} else {
// Check if the ip is in the whitelist
return self.0.contains(&ip);
}
self.0.contains(&ip)
}
}

Expand All @@ -53,8 +53,12 @@ impl Auth for NoAuth {

async fn execute(&self, stream: &mut TcpStream) -> Self::Output {
let socket = stream.peer_addr()?;
if !self.contains(socket.ip()) {
return Err(Error::new(ErrorKind::Other, "Ip is not in the whitelist"));
let is_equal = self.contains(socket.ip()) || self.is_empty();
if !is_equal {
return Err(Error::new(
ErrorKind::Other,
format!("Address {} is not in the whitelist", socket.ip()),
));
}
Ok((true, Extensions::None))
}
Expand All @@ -67,6 +71,11 @@ pub struct Password {
}

impl Whitelist for Password {
fn is_empty(&self) -> bool {
// Check if the whitelist is empty
self.whitelist.is_empty()
}

fn contains(&self, ip: IpAddr) -> bool {
// If whitelist is empty, allow all
if self.whitelist.is_empty() {
Expand Down

0 comments on commit 0a102a3

Please sign in to comment.