socks5_impl/server/
auth.rs1use crate::protocol::{AsyncStreamOperation, AuthMethod, UserKey, handshake::password_method};
2use std::sync::Arc;
3use tokio::net::TcpStream;
4
5#[async_trait::async_trait]
35pub trait AuthExecutor {
36 type Output;
37 fn auth_method(&self) -> AuthMethod;
38 async fn execute(&self, stream: &mut TcpStream) -> Self::Output;
39}
40
41pub type AuthAdaptor<O> = Arc<dyn AuthExecutor<Output = O> + Send + Sync>;
42
43#[derive(Debug, Default)]
45pub struct NoAuth;
46
47#[async_trait::async_trait]
48impl AuthExecutor for NoAuth {
49 type Output = ();
50 fn auth_method(&self) -> AuthMethod {
51 AuthMethod::NoAuth
52 }
53
54 async fn execute(&self, _: &mut TcpStream) -> Self::Output {}
55}
56
57pub struct UserKeyAuth {
59 user_key: UserKey,
60}
61
62impl UserKeyAuth {
63 pub fn new(username: &str, password: &str) -> Self {
64 let user_key = UserKey::new(username, password);
65 Self { user_key }
66 }
67}
68
69#[async_trait::async_trait]
70impl AuthExecutor for UserKeyAuth {
71 type Output = std::io::Result<bool>;
72
73 fn auth_method(&self) -> AuthMethod {
74 AuthMethod::UserPass
75 }
76
77 async fn execute(&self, stream: &mut TcpStream) -> Self::Output {
78 use password_method::{Request, Response, Status::*};
79 let req = Request::retrieve_from_async_stream(stream).await?;
80
81 let is_equal = req.user_key == self.user_key;
82 let resp = Response::new(if is_equal { Succeeded } else { Failed });
83 resp.write_to_async_stream(stream).await?;
84 if is_equal {
85 Ok(true)
86 } else {
87 Err(std::io::Error::other("username or password is incorrect"))
88 }
89 }
90}