Former-commit-id: 2c8d8ac3845be86db0032025a127865f1f6d4ee7 [formerly 7550a9453455a95cb7583d582b5ac36d5a2c4e85] [formerly 39ce55e6191ae0f82e97708165be5fb27bffad51 [formerly e6c8f9d061578f0aad10fd974fb30bba6fb980d2]]
Former-commit-id: 29b3ac95435e35e66a93aada96692dde1d5d6213 [formerly afaaf09642072cec135a9fe451510be3ec2196e1]
Former-commit-id: 6ea160887038963bc34a6fb0b93baa318286f068
Former-commit-id: 40d8cad8790877c1d0712dfcd828939f4585dd38
Former-commit-id: a3de18cc4ac432e9aac64c30b05fc86f6fcf6b42
Former-commit-id: 7193a47d510ecd22b43a001b8b128b24643f6e42 [formerly 5a0575a31f03fe2754ed3a2c784f6181bc654456]
Former-commit-id: 9aef01bbe49921a4e0cc3eda2ecf929e476eacff
This commit is contained in:
Σrebe - Romain GERARD 2023-10-16 19:26:32 +02:00
parent ef112495ae
commit a15e8a2548
5 changed files with 169 additions and 12 deletions

73
Cargo.lock generated
View file

@ -92,6 +92,17 @@ version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "async-trait"
version = "0.1.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "atomic"
version = "0.5.3"
@ -267,6 +278,20 @@ dependencies = [
"crypto-common",
]
[[package]]
name = "fast-socks5"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa6a4a9ab1f87e2d8e9345ce944de7c45d065ee89f5942512f32698e48a8429a"
dependencies = [
"anyhow",
"async-trait",
"log",
"thiserror",
"tokio",
"tokio-stream",
]
[[package]]
name = "fastwebsockets"
version = "0.4.4"
@ -467,12 +492,12 @@ dependencies = [
[[package]]
name = "jsonwebtoken"
version = "8.3.0"
version = "9.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378"
checksum = "1e863f95209c79b9b8b001c4b03463385f890a765dbc4e0802cb8d4177e3e410"
dependencies = [
"base64",
"ring",
"ring 0.17.4",
"serde",
"serde_json",
]
@ -779,12 +804,26 @@ dependencies = [
"cc",
"libc",
"once_cell",
"spin",
"untrusted",
"spin 0.5.2",
"untrusted 0.7.1",
"web-sys",
"winapi",
]
[[package]]
name = "ring"
version = "0.17.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fce3045ffa7c981a6ee93f640b538952e155f1ae3a1a02b84547fc7a56b7059a"
dependencies = [
"cc",
"getrandom",
"libc",
"spin 0.9.8",
"untrusted 0.9.0",
"windows-sys",
]
[[package]]
name = "rustc-demangle"
version = "0.1.23"
@ -798,7 +837,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8"
dependencies = [
"log",
"ring",
"ring 0.16.20",
"rustls-webpki",
"sct",
]
@ -830,8 +869,8 @@ version = "0.101.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe"
dependencies = [
"ring",
"untrusted",
"ring 0.16.20",
"untrusted 0.7.1",
]
[[package]]
@ -861,8 +900,8 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [
"ring",
"untrusted",
"ring 0.16.20",
"untrusted 0.7.1",
]
[[package]]
@ -995,6 +1034,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "strsim"
version = "0.10.0"
@ -1257,6 +1302,12 @@ version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.4.1"
@ -1478,11 +1529,13 @@ dependencies = [
"anyhow",
"base64",
"clap",
"fast-socks5",
"fastwebsockets",
"futures-util",
"hyper",
"jsonwebtoken",
"libc",
"log",
"once_cell",
"pin-project",
"rustls-native-certs",

View file

@ -19,19 +19,21 @@ ahash = { version = "0.8.3", features = []}
pin-project = "1"
scopeguard = "1.2.0"
uuid = { version = "1.4.1", features = ["v7", "serde"] }
jsonwebtoken = { version = "8.3.0", default-features = false }
jsonwebtoken = { version = "9.0.0", default-features = false }
rustls-pemfile = { version = "1.0.3", features = [] }
rustls-native-certs = { version = "0.6.3", features = [] }
tokio = { version = "1.32.0", features = ["full"] }
tokio-rustls = { version = "0.24.1", features = ["tls12", "dangerous_configuration", "early-data"] }
tokio-stream = { version = "0.1.14", features = ["net"] }
fast-socks5 = { version = "0.9.1", features = [] }
futures-util = { version = "0.3.28" }
tracing = { version = "0.1.37", features = ["log"] }
tracing-subscriber = { version = "0.3.17", features = ["env-filter", "fmt", "local-time"] }
base64 = "0.21.4"
serde = { version = "1.0.188", features = ["derive"] }
log = "0.4.20"
[target.'cfg(target_family = "unix")'.dependencies]
tokio-fd = "0.3.0"

View file

@ -1,4 +1,5 @@
mod embedded_certificate;
mod socks5;
#[cfg(target_family = "unix")]
mod stdio;
mod tcp;

101
src/socks5.rs Normal file
View file

@ -0,0 +1,101 @@
use anyhow::Context;
use fast_socks5::server::{Config, DenyAuthentication, Socks5Server};
use fast_socks5::util::target_addr::TargetAddr;
use futures_util::{stream, Stream, StreamExt};
use std::net::SocketAddr;
use std::pin::Pin;
use std::task::Poll;
use tokio::net::TcpStream;
use log::warn;
use tracing::{info, warn};
use url::Host;
pub struct Socks5Listener {
stream: Pin<Box<dyn Stream<Item = anyhow::Result<(TcpStream, Host, u16)>>>>,
}
impl Stream for Socks5Listener {
type Item = anyhow::Result<(TcpStream, Host, u16)>;
fn poll_next(
self: Pin<&mut Self>,
cx: &mut std::task::Context<'_>,
) -> Poll<Option<Self::Item>> {
unsafe { self.map_unchecked_mut(|x| &mut x.stream) }.poll_next(cx)
}
}
pub async fn run_server(bind: SocketAddr) -> Result<Socks5Listener, anyhow::Error> {
info!("Starting TCP server listening cnx on {}", bind);
let server = Socks5Server::<DenyAuthentication>::bind(bind)
.await
.with_context(|| format!("Cannot create socks5 server {:?}", bind))?;
let mut cfg = Config::<DenyAuthentication>::default();
cfg.set_allow_no_auth(true);
cfg.set_dns_resolve(false);
cfg.set_execute_command(false);
let server = server.with_config(cfg);
let stream = stream::unfold(server, move |server| async {
let mut acceptor = server.incoming();
loop {
let cnx = match acceptor.next().await {
None => return None,
Some(Err(err)) => {
drop(acceptor);
return Some((Err(anyhow::Error::new(err)), server));
}
Some(Ok(cnx)) => cnx,
};
let cnx = match cnx.upgrade_to_socks5().await {
Ok(cnx) => cnx,
Err(err) => {
warn!("Rejecting socks5 cnx: {}", err);
continue;
}
};
let Some(target) = cnx.target_addr() else {
warn!("Rejecting socks5 cnx: no target addr");
continue;
};
let (host, port) = match target {
TargetAddr::Ip(SocketAddr::V4(ip)) => (Host::Ipv4(*ip.ip()), ip.port()),
TargetAddr::Ip(SocketAddr::V6(ip)) => (Host::Ipv6(*ip.ip()), ip.port()),
TargetAddr::Domain(host, port) => (Host::Domain(host.clone()), *port),
};
drop(acceptor);
return Some((Ok((cnx.into_inner(), host, port)), server));
}
});
let listener = Socks5Listener {
stream: Box::pin(stream),
};
Ok(listener)
}
#[cfg(test)]
mod test {
use super::*;
use futures_util::StreamExt;
use std::str::FromStr;
#[tokio::test]
async fn socks5_server() {
let mut x = run_server(SocketAddr::from_str("[::]:4343").unwrap())
.await
.unwrap();
loop {
let cnx = x.next().await.unwrap().unwrap();
eprintln!("{:?}", cnx);
}
}
}

View file

@ -10,7 +10,7 @@ use anyhow::Context;
use fastwebsockets::{
Frame, OpCode, Payload, WebSocket, WebSocketError, WebSocketRead, WebSocketWrite,
};
use futures_util::{pin_mut};
use futures_util::pin_mut;
use hyper::header::{AUTHORIZATION, SEC_WEBSOCKET_VERSION, UPGRADE};
use hyper::header::{CONNECTION, HOST, SEC_WEBSOCKET_KEY};
use hyper::server::conn::Http;