diff --git a/src/client.rs b/src/client.rs index dcefcbd..4fa9c89 100644 --- a/src/client.rs +++ b/src/client.rs @@ -3,9 +3,9 @@ use crate::messages::{ AuthenticationMethod, ClientConnectionCommand, ClientConnectionRequest, ClientGreeting, ClientUsernamePassword, ServerAuthResponse, ServerChoice, ServerResponse, ServerResponseStatus, }; -use crate::network::{Network, SOCKSv5Address}; -use async_std::net::IpAddr; +use crate::network::generic::Networklike; use futures::io::{AsyncRead, AsyncWrite}; +use log::{warn, trace}; use thiserror::Error; #[derive(Debug, Error)] @@ -27,14 +27,14 @@ pub enum SOCKSv5Error { pub struct SOCKSv5Client where S: AsyncRead + AsyncWrite, - N: Network, + N: Networklike, { _network: N, stream: S, } pub struct LoginInfo { - username_password: Option, + pub username_password: Option, } pub struct UsernamePassword { @@ -45,7 +45,7 @@ pub struct UsernamePassword { impl SOCKSv5Client where S: AsyncRead + AsyncWrite + Send + Unpin, - N: Network, + N: Networklike, { /// Create a new SOCKSv5 client connection over the given steam, using the given /// authentication information. @@ -56,25 +56,35 @@ where acceptable_methods.push(AuthenticationMethod::UsernameAndPassword); } + println!( + "Computed acceptable methods -- {:?} -- sending client greeting.", + acceptable_methods + ); let client_greeting = ClientGreeting { acceptable_methods }; 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 { AuthenticationMethod::None => {} AuthenticationMethod::UsernameAndPassword => { 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()) } else { + warn!("Server requested username/password, but we weren't provided one."); ("".to_string(), "".to_string()) }; let auth_request = ClientUsernamePassword { username, password }; + trace!("Writing password information."); 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 { return Err(SOCKSv5Error::AuthenticationFailed); @@ -88,45 +98,7 @@ where x => return Err(SOCKSv5Error::UnsupportedAuthMethodChosen(x)), } + trace!("Returning new SOCKSv5Client object!"); Ok(SOCKSv5Client { _network, stream }) } - - async fn connect_internal( - &mut self, - addr: SOCKSv5Address, - port: u16, - ) -> Result { - 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 { - 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 { - format!("hello {}", 'a'); - self.connect_internal(SOCKSv5Address::Name(name), port) - .await - } } diff --git a/src/network.rs b/src/network.rs index 3a277d0..abe932e 100644 --- a/src/network.rs +++ b/src/network.rs @@ -12,33 +12,3 @@ pub use crate::network::standard::Builtin; use async_trait::async_trait; use futures::{AsyncRead, AsyncWrite}; use std::fmt; - -#[async_trait] -pub trait Network { - type Stream: AsyncRead + AsyncWrite + Clone + Send + Sync + Unpin + 'static; - type Listener: SingleShotListener + Send + Sync + 'static; - type UdpSocket; - type Error: fmt::Debug + fmt::Display + Into; - - async fn connect>( - &mut self, - addr: A, - port: u16, - ) -> Result; - async fn udp_socket>( - &mut self, - addr: A, - port: Option, - ) -> Result; - async fn listen>( - &mut self, - addr: A, - port: Option, - ) -> Result; -} - -#[async_trait] -pub trait SingleShotListener { - async fn accept(self) -> Result; - fn info(&self) -> Result<(SOCKSv5Address, u16), Error>; -} diff --git a/src/network/testing.rs b/src/network/testing.rs index 55aeb78..d361fe2 100644 --- a/src/network/testing.rs +++ b/src/network/testing.rs @@ -84,7 +84,7 @@ impl fmt::Display for TestStackError { impl From for ServerResponseStatus { fn from(_: TestStackError) -> Self { - ServerResponseStatus::GeneralFailure + ServerResponseStatus::GeneralFailure } }