forward 0.1.0-alpha.1

open a TCP port and foward all trafics through a proxy to another server or port
Documentation
use std::io;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};

pub async fn password_authentication<S: AsyncRead + AsyncWrite + Unpin>(
    socket: &mut S,
    username: &str,
    password: &str,
) -> io::Result<()> {
    if username.len() < 1 || username.len() > 255 {
        return Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            "invalid username",
        ));
    };
    if password.len() < 1 || password.len() > 255 {
        return Err(io::Error::new(
            io::ErrorKind::InvalidInput,
            "invalid password",
        ));
    }

    let mut packet = [0; 515];
    let packet_size = 3 + username.len() + password.len();
    packet[0] = 1; // version
    packet[1] = username.len() as u8;
    packet[2..2 + username.len()].copy_from_slice(username.as_bytes());
    packet[2 + username.len()] = password.len() as u8;
    packet[3 + username.len()..packet_size].copy_from_slice(password.as_bytes());
    socket.write_all(&packet[..packet_size]).await?;

    let mut buf = [0; 2];
    socket.read_exact(&mut buf).await?;
    if buf[0] != 1 {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            "invalid response version",
        ));
    }
    if buf[1] != 0 {
        return Err(io::Error::new(
            io::ErrorKind::PermissionDenied,
            "password authentication failed",
        ));
    }

    Ok(())
}