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,
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<S, N>
where
S: AsyncRead + AsyncWrite,
N: Network,
N: Networklike,
{
_network: N,
stream: S,
}
pub struct LoginInfo {
username_password: Option<UsernamePassword>,
pub username_password: Option<UsernamePassword>,
}
pub struct UsernamePassword {
@@ -45,7 +45,7 @@ pub struct UsernamePassword {
impl<S, N> SOCKSv5Client<S, N>
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<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 futures::{AsyncRead, AsyncWrite};
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 {
fn from(_: TestStackError) -> Self {
ServerResponseStatus::GeneralFailure
ServerResponseStatus::GeneralFailure
}
}