Skip to content

Commit

Permalink
chore: update server example to return the user's credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
dizda committed Jun 26, 2023
1 parent 83bdf3f commit cd59194
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
17 changes: 11 additions & 6 deletions examples/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
extern crate log;

use fast_socks5::{
server::{Authentication, Config, SimpleUserPassword, Socks5Server, Socks5Socket},
server::{Config, SimpleUserPassword, Socks5Server, Socks5Socket},
Result, SocksError,
};
use std::future::Future;
Expand Down Expand Up @@ -115,15 +115,20 @@ async fn spawn_socks_server() -> Result<()> {
Ok(())
}

fn spawn_and_log_error<F, T, A>(fut: F) -> task::JoinHandle<()>
fn spawn_and_log_error<F, T>(fut: F) -> task::JoinHandle<()>
where
F: Future<Output = Result<Socks5Socket<T, A>>> + Send + 'static,
F: Future<Output = Result<Socks5Socket<T, SimpleUserPassword>>> + Send + 'static,
T: AsyncRead + AsyncWrite + Unpin,
A: Authentication,
{
task::spawn(async move {
if let Err(e) = fut.await {
error!("{:#}", &e);
match fut.await {
Ok(mut socket) => {
// the user is validated by the trait, so it can't be null
let user = socket.take_credentials().unwrap();

info!("user logged in with `{}`", user.username);
}
Err(err) => error!("{:#}", &err),
}
})
}
17 changes: 12 additions & 5 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,32 @@ pub struct SimpleUserPassword {
pub password: String,
}

/// The struct returned when the user has successfully authenticated
pub struct AuthSucceeded {
pub username: String,
}

/// This is an example to auth via simple credentials.
/// If the auth succeed, we return the username authenticated with, for further uses.
#[async_trait::async_trait]
impl Authentication for SimpleUserPassword {
type Item = String;
type Item = AuthSucceeded;

async fn authenticate(&self, credentials: Option<(String, String)>) -> Option<Self::Item> {
if let Some((username, password)) = credentials {
// Client has supplied credentials
if username == self.username && password == self.password {
Some(self.username.to_owned())
// Some() will allow the authentication and the credentials
// will be forwarded to the socket
Some(AuthSucceeded { username })
} else {
// Credentials incorrect, we deny the auth
None
}
} else {
// The client hasn't supplied any credentials, which only happens
// when `Authentication::allow_no_auth()` is set as `true`
// when `Config::allow_no_auth()` is set as `true`
None
//TODO: put an example of if CLIENT_ADDR == 127.0.0.1 { SOME } ELSE { NONE }
}
}
}
Expand Down Expand Up @@ -383,7 +390,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin, A: Authentication> Socks5Socket<T, A> {
async fn can_accept_method(&mut self, client_methods: Vec<u8>) -> Result<u8> {
let method_supported;

if let Some(auth) = self.config.auth.as_ref() {
if let Some(_auth) = self.config.auth.as_ref() {
if client_methods.contains(&consts::SOCKS5_AUTH_METHOD_PASSWORD) {
// can auth with password
method_supported = consts::SOCKS5_AUTH_METHOD_PASSWORD;
Expand Down

0 comments on commit cd59194

Please sign in to comment.