Rid ourselves of the old Network trait.

This commit is contained in:
2021-10-09 15:24:51 -07:00
parent 0d35f1cdb3
commit 748dc33a36
3 changed files with 19 additions and 77 deletions

View File

@@ -3,9 +3,9 @@ use crate::messages::{
AuthenticationMethod, ClientConnectionCommand, ClientConnectionRequest, ClientGreeting, AuthenticationMethod, ClientConnectionCommand, ClientConnectionRequest, ClientGreeting,
ClientUsernamePassword, ServerAuthResponse, ServerChoice, ServerResponse, ServerResponseStatus, ClientUsernamePassword, ServerAuthResponse, ServerChoice, ServerResponse, ServerResponseStatus,
}; };
use crate::network::{Network, SOCKSv5Address}; use crate::network::generic::Networklike;
use async_std::net::IpAddr;
use futures::io::{AsyncRead, AsyncWrite}; use futures::io::{AsyncRead, AsyncWrite};
use log::{warn, trace};
use thiserror::Error; use thiserror::Error;
#[derive(Debug, Error)] #[derive(Debug, Error)]
@@ -27,14 +27,14 @@ pub enum SOCKSv5Error {
pub struct SOCKSv5Client<S, N> pub struct SOCKSv5Client<S, N>
where where
S: AsyncRead + AsyncWrite, S: AsyncRead + AsyncWrite,
N: Network, N: Networklike,
{ {
_network: N, _network: N,
stream: S, stream: S,
} }
pub struct LoginInfo { pub struct LoginInfo {
username_password: Option<UsernamePassword>, pub username_password: Option<UsernamePassword>,
} }
pub struct UsernamePassword { pub struct UsernamePassword {
@@ -45,7 +45,7 @@ pub struct UsernamePassword {
impl<S, N> SOCKSv5Client<S, N> impl<S, N> SOCKSv5Client<S, N>
where where
S: AsyncRead + AsyncWrite + Send + Unpin, S: AsyncRead + AsyncWrite + Send + Unpin,
N: Network, N: Networklike,
{ {
/// Create a new SOCKSv5 client connection over the given steam, using the given /// Create a new SOCKSv5 client connection over the given steam, using the given
/// authentication information. /// authentication information.
@@ -56,25 +56,35 @@ where
acceptable_methods.push(AuthenticationMethod::UsernameAndPassword); acceptable_methods.push(AuthenticationMethod::UsernameAndPassword);
} }
println!(
"Computed acceptable methods -- {:?} -- sending client greeting.",
acceptable_methods
);
let client_greeting = ClientGreeting { acceptable_methods }; let client_greeting = ClientGreeting { acceptable_methods };
client_greeting.write(&mut stream).await?; client_greeting.write(&mut stream).await?;
let server_choice = ServerChoice::read(Pin::new(&mut stream)).await?; trace!("Write client greeting, waiting for server's choice.");
let server_choice = ServerChoice::read(&mut stream).await?;
trace!("Received server's choice: {}", server_choice.chosen_method);
match server_choice.chosen_method { match server_choice.chosen_method {
AuthenticationMethod::None => {} AuthenticationMethod::None => {}
AuthenticationMethod::UsernameAndPassword => { AuthenticationMethod::UsernameAndPassword => {
let (username, password) = if let Some(ref linfo) = login.username_password { let (username, password) = if let Some(ref linfo) = login.username_password {
trace!("Server requested username/password, getting data from login info.");
(linfo.username.clone(), linfo.password.clone()) (linfo.username.clone(), linfo.password.clone())
} else { } else {
warn!("Server requested username/password, but we weren't provided one.");
("".to_string(), "".to_string()) ("".to_string(), "".to_string())
}; };
let auth_request = ClientUsernamePassword { username, password }; let auth_request = ClientUsernamePassword { username, password };
trace!("Writing password information.");
auth_request.write(&mut stream).await?; auth_request.write(&mut stream).await?;
let server_response = ServerAuthResponse::read(Pin::new(&mut stream)).await?; let server_response = ServerAuthResponse::read(&mut stream).await?;
trace!("Got server response: {}", server_response.success);
if !server_response.success { if !server_response.success {
return Err(SOCKSv5Error::AuthenticationFailed); return Err(SOCKSv5Error::AuthenticationFailed);
@@ -88,45 +98,7 @@ where
x => return Err(SOCKSv5Error::UnsupportedAuthMethodChosen(x)), x => return Err(SOCKSv5Error::UnsupportedAuthMethodChosen(x)),
} }
trace!("Returning new SOCKSv5Client object!");
Ok(SOCKSv5Client { _network, stream }) Ok(SOCKSv5Client { _network, stream })
} }
async fn connect_internal(
&mut self,
addr: SOCKSv5Address,
port: u16,
) -> Result<N::Stream, SOCKSv5Error> {
let request = ClientConnectionRequest {
command_code: ClientConnectionCommand::EstablishTCPStream,
destination_address: addr,
destination_port: port,
};
request.write(&mut self.stream).await?;
let response = ServerResponse::read(Pin::new(&mut self.stream)).await?;
if response.status == ServerResponseStatus::RequestGranted {
unimplemented!()
} else {
Err(SOCKSv5Error::from(response.status))
}
}
pub async fn connect(&mut self, addr: IpAddr, port: u16) -> Result<N::Stream, SOCKSv5Error> {
assert!(port != 0);
match addr {
IpAddr::V4(a) => self.connect_internal(SOCKSv5Address::IP4(a), port).await,
IpAddr::V6(a) => self.connect_internal(SOCKSv5Address::IP6(a), port).await,
}
}
pub async fn connect_name(
&mut self,
name: String,
port: u16,
) -> Result<N::Stream, SOCKSv5Error> {
format!("hello {}", 'a');
self.connect_internal(SOCKSv5Address::Name(name), port)
.await
}
} }

View File

@@ -12,33 +12,3 @@ pub use crate::network::standard::Builtin;
use async_trait::async_trait; use async_trait::async_trait;
use futures::{AsyncRead, AsyncWrite}; use futures::{AsyncRead, AsyncWrite};
use std::fmt; use std::fmt;
#[async_trait]
pub trait Network {
type Stream: AsyncRead + AsyncWrite + Clone + Send + Sync + Unpin + 'static;
type Listener: SingleShotListener<Self::Stream, Self::Error> + Send + Sync + 'static;
type UdpSocket;
type Error: fmt::Debug + fmt::Display + Into<ServerResponseStatus>;
async fn connect<A: Into<SOCKSv5Address>>(
&mut self,
addr: A,
port: u16,
) -> Result<Self::Stream, Self::Error>;
async fn udp_socket<A: Into<SOCKSv5Address>>(
&mut self,
addr: A,
port: Option<u16>,
) -> Result<Self::UdpSocket, Self::Error>;
async fn listen<A: Into<SOCKSv5Address>>(
&mut self,
addr: A,
port: Option<u16>,
) -> Result<Self::Listener, Self::Error>;
}
#[async_trait]
pub trait SingleShotListener<Stream, Error> {
async fn accept(self) -> Result<Stream, Error>;
fn info(&self) -> Result<(SOCKSv5Address, u16), Error>;
}

View File

@@ -84,7 +84,7 @@ impl fmt::Display for TestStackError {
impl From<TestStackError> for ServerResponseStatus { impl From<TestStackError> for ServerResponseStatus {
fn from(_: TestStackError) -> Self { fn from(_: TestStackError) -> Self {
ServerResponseStatus::GeneralFailure ServerResponseStatus::GeneralFailure
} }
} }