mirror of
https://github.com/tun2proxy/tun2proxy.git
synced 2025-04-20 13:59:10 +00:00
Use Option type for credentials
This commit applys the diff by @ssrlive from
3223ca4e22 (commitcomment-105521241)
.
This commit is contained in:
parent
8dd075a7f4
commit
2f295c3fdc
7 changed files with 40 additions and 35 deletions
|
@ -35,7 +35,7 @@ impl HttpConnection {
|
||||||
server_outbuf.extend(b" HTTP/1.1\r\nHost: ".iter());
|
server_outbuf.extend(b" HTTP/1.1\r\nHost: ".iter());
|
||||||
server_outbuf.extend(connection.dst.to_string().as_bytes());
|
server_outbuf.extend(connection.dst.to_string().as_bytes());
|
||||||
server_outbuf.extend(b"\r\n".iter());
|
server_outbuf.extend(b"\r\n".iter());
|
||||||
if credentials.authenticate {
|
if let Some(credentials) = credentials {
|
||||||
server_outbuf.extend(b"Proxy-Authorization: Basic ");
|
server_outbuf.extend(b"Proxy-Authorization: Basic ");
|
||||||
let mut auth_plain = credentials.username.clone();
|
let mut auth_plain = credentials.username.clone();
|
||||||
auth_plain.extend(b":".iter());
|
auth_plain.extend(b":".iter());
|
||||||
|
@ -165,7 +165,7 @@ impl TcpProxy for HttpConnection {
|
||||||
|
|
||||||
pub struct HttpManager {
|
pub struct HttpManager {
|
||||||
server: std::net::SocketAddr,
|
server: std::net::SocketAddr,
|
||||||
credentials: Credentials,
|
credentials: Option<Credentials>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectionManager for HttpManager {
|
impl ConnectionManager for HttpManager {
|
||||||
|
@ -192,13 +192,13 @@ impl ConnectionManager for HttpManager {
|
||||||
self.server
|
self.server
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_credentials(&self) -> &Credentials {
|
fn get_credentials(&self) -> &Option<Credentials> {
|
||||||
&self.credentials
|
&self.credentials
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HttpManager {
|
impl HttpManager {
|
||||||
pub fn new(server: SocketAddr, credentials: Credentials) -> std::rc::Rc<Self> {
|
pub fn new(server: SocketAddr, credentials: Option<Credentials>) -> std::rc::Rc<Self> {
|
||||||
std::rc::Rc::new(Self {
|
std::rc::Rc::new(Self {
|
||||||
server,
|
server,
|
||||||
credentials,
|
credentials,
|
||||||
|
|
16
src/lib.rs
16
src/lib.rs
|
@ -13,7 +13,21 @@ pub enum ProxyType {
|
||||||
Http,
|
Http,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_entry(tun: &str, addr: SocketAddr, proxy_type: ProxyType, credentials: Credentials) {
|
impl std::fmt::Display for ProxyType {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
ProxyType::Socks5 => write!(f, "socks5"),
|
||||||
|
ProxyType::Http => write!(f, "http"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main_entry(
|
||||||
|
tun: &str,
|
||||||
|
addr: SocketAddr,
|
||||||
|
proxy_type: ProxyType,
|
||||||
|
credentials: Option<Credentials>,
|
||||||
|
) {
|
||||||
let mut ttp = TunToProxy::new(tun);
|
let mut ttp = TunToProxy::new(tun);
|
||||||
match proxy_type {
|
match proxy_type {
|
||||||
ProxyType::Socks5 => {
|
ProxyType::Socks5 => {
|
||||||
|
|
21
src/main.rs
21
src/main.rs
|
@ -23,7 +23,7 @@ struct Args {
|
||||||
struct ArgProxy {
|
struct ArgProxy {
|
||||||
proxy_type: ProxyType,
|
proxy_type: ProxyType,
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
credentials: Credentials,
|
credentials: Option<Credentials>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn proxy_url_parser(s: &str) -> Result<ArgProxy, String> {
|
fn proxy_url_parser(s: &str) -> Result<ArgProxy, String> {
|
||||||
|
@ -46,12 +46,11 @@ fn proxy_url_parser(s: &str) -> Result<ArgProxy, String> {
|
||||||
.ok_or(format!("`{host}` does not resolve to a usable IP address"))?;
|
.ok_or(format!("`{host}` does not resolve to a usable IP address"))?;
|
||||||
|
|
||||||
let credentials = if url.username() == "" && url.password().is_none() {
|
let credentials = if url.username() == "" && url.password().is_none() {
|
||||||
Credentials::none()
|
None
|
||||||
} else {
|
} else {
|
||||||
Credentials::new(
|
let username = String::from(url.username());
|
||||||
String::from(url.username()),
|
let password = String::from(url.password().unwrap_or(""));
|
||||||
String::from(url.password().unwrap_or("")),
|
Some(Credentials::new(&username, &password))
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let scheme = url.scheme();
|
let scheme = url.scheme();
|
||||||
|
@ -75,12 +74,8 @@ fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let addr = args.proxy.addr;
|
let addr = args.proxy.addr;
|
||||||
log::info!("Proxy server: {addr}");
|
let proxy_type = args.proxy.proxy_type;
|
||||||
|
log::info!("Proxy {proxy_type} server: {addr}");
|
||||||
|
|
||||||
main_entry(
|
main_entry(&args.tun, addr, proxy_type, args.proxy.credentials);
|
||||||
&args.tun,
|
|
||||||
args.proxy.addr,
|
|
||||||
args.proxy.proxy_type,
|
|
||||||
args.proxy.credentials,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ impl SocksConnection {
|
||||||
|
|
||||||
fn send_client_hello(&mut self) {
|
fn send_client_hello(&mut self) {
|
||||||
let credentials = self.manager.get_credentials();
|
let credentials = self.manager.get_credentials();
|
||||||
if credentials.authenticate {
|
if credentials.is_some() {
|
||||||
self.server_outbuf.extend(&[5u8, 1, 2]);
|
self.server_outbuf.extend(&[5u8, 1, 2]);
|
||||||
} else {
|
} else {
|
||||||
self.server_outbuf.extend(&[5u8, 1, 0]);
|
self.server_outbuf.extend(&[5u8, 1, 0]);
|
||||||
|
@ -100,8 +100,8 @@ impl SocksConnection {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.server_inbuf[1] != 0 && !self.manager.get_credentials().authenticate
|
if self.server_inbuf[1] != 0 && self.manager.get_credentials().is_none()
|
||||||
|| self.server_inbuf[1] != 2 && self.manager.get_credentials().authenticate
|
|| self.server_inbuf[1] != 2 && self.manager.get_credentials().is_some()
|
||||||
{
|
{
|
||||||
return Err(ProxyError::new(
|
return Err(ProxyError::new(
|
||||||
"SOCKS server requires an unsupported authentication method.".into(),
|
"SOCKS server requires an unsupported authentication method.".into(),
|
||||||
|
@ -110,7 +110,7 @@ impl SocksConnection {
|
||||||
|
|
||||||
self.server_inbuf.drain(0..2);
|
self.server_inbuf.drain(0..2);
|
||||||
|
|
||||||
if self.manager.get_credentials().authenticate {
|
if self.manager.get_credentials().is_some() {
|
||||||
self.state = SocksState::SendAuthData;
|
self.state = SocksState::SendAuthData;
|
||||||
} else {
|
} else {
|
||||||
self.state = SocksState::SendRequest;
|
self.state = SocksState::SendRequest;
|
||||||
|
@ -119,7 +119,8 @@ impl SocksConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_auth_data(&mut self) -> Result<(), ProxyError> {
|
fn send_auth_data(&mut self) -> Result<(), ProxyError> {
|
||||||
let credentials = self.manager.get_credentials();
|
let tmp = Credentials::default();
|
||||||
|
let credentials = self.manager.get_credentials().as_ref().unwrap_or(&tmp);
|
||||||
self.server_outbuf
|
self.server_outbuf
|
||||||
.extend(&[1u8, credentials.username.len() as u8]);
|
.extend(&[1u8, credentials.username.len() as u8]);
|
||||||
self.server_outbuf.extend(&credentials.username);
|
self.server_outbuf.extend(&credentials.username);
|
||||||
|
@ -285,7 +286,7 @@ impl TcpProxy for SocksConnection {
|
||||||
|
|
||||||
pub struct Socks5Manager {
|
pub struct Socks5Manager {
|
||||||
server: std::net::SocketAddr,
|
server: std::net::SocketAddr,
|
||||||
credentials: Credentials,
|
credentials: Option<Credentials>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectionManager for Socks5Manager {
|
impl ConnectionManager for Socks5Manager {
|
||||||
|
@ -312,13 +313,13 @@ impl ConnectionManager for Socks5Manager {
|
||||||
self.server
|
self.server
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_credentials(&self) -> &Credentials {
|
fn get_credentials(&self) -> &Option<Credentials> {
|
||||||
&self.credentials
|
&self.credentials
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Socks5Manager {
|
impl Socks5Manager {
|
||||||
pub fn new(server: SocketAddr, credentials: Credentials) -> std::rc::Rc<Self> {
|
pub fn new(server: SocketAddr, credentials: Option<Credentials>) -> std::rc::Rc<Self> {
|
||||||
std::rc::Rc::new(Self {
|
std::rc::Rc::new(Self {
|
||||||
server,
|
server,
|
||||||
credentials,
|
credentials,
|
||||||
|
|
|
@ -164,23 +164,17 @@ struct ConnectionState {
|
||||||
|
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
pub struct Credentials {
|
pub struct Credentials {
|
||||||
pub(crate) authenticate: bool,
|
|
||||||
pub(crate) username: Vec<u8>,
|
pub(crate) username: Vec<u8>,
|
||||||
pub(crate) password: Vec<u8>,
|
pub(crate) password: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Credentials {
|
impl Credentials {
|
||||||
pub fn new(username: String, password: String) -> Self {
|
pub fn new(username: &str, password: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
authenticate: true,
|
|
||||||
username: username.as_bytes().to_vec(),
|
username: username.as_bytes().to_vec(),
|
||||||
password: password.as_bytes().to_vec(),
|
password: password.as_bytes().to_vec(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn none() -> Self {
|
|
||||||
Default::default()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait TcpProxy {
|
pub(crate) trait TcpProxy {
|
||||||
|
@ -199,7 +193,7 @@ pub(crate) trait ConnectionManager {
|
||||||
) -> Option<std::boxed::Box<dyn TcpProxy>>;
|
) -> Option<std::boxed::Box<dyn TcpProxy>>;
|
||||||
fn close_connection(&self, connection: &Connection);
|
fn close_connection(&self, connection: &Connection);
|
||||||
fn get_server(&self) -> SocketAddr;
|
fn get_server(&self) -> SocketAddr;
|
||||||
fn get_credentials(&self) -> &Credentials;
|
fn get_credentials(&self) -> &Option<Credentials>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct TunToProxy<'a> {
|
pub(crate) struct TunToProxy<'a> {
|
||||||
|
|
1
tests/password.secret
Normal file
1
tests/password.secret
Normal file
|
@ -0,0 +1 @@
|
||||||
|
JLFE$kz$wJf%&^StSH&D7D5s
|
|
@ -140,7 +140,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
Ok(Fork::Child) => {
|
Ok(Fork::Child) => {
|
||||||
prctl::set_death_signal(signal::SIGKILL as isize).unwrap(); // 9 == SIGKILL
|
prctl::set_death_signal(signal::SIGKILL as isize).unwrap(); // 9 == SIGKILL
|
||||||
main_entry(TUN_TEST_DEVICE, address, ProxyType::Socks5);
|
main_entry(TUN_TEST_DEVICE, address, ProxyType::Socks5, None);
|
||||||
}
|
}
|
||||||
Err(_) => assert!(false),
|
Err(_) => assert!(false),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue