87 lines
2.5 KiB
Rust
87 lines
2.5 KiB
Rust
use crate::errors::{DeserializationError, SerializationError};
|
|
#[cfg(test)]
|
|
use crate::messages::utils::arbitrary_socks_string;
|
|
use crate::serialize::{read_string, write_string};
|
|
use crate::standard_roundtrip;
|
|
#[cfg(test)]
|
|
use async_std::task;
|
|
#[cfg(test)]
|
|
use futures::io::Cursor;
|
|
use futures::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
|
|
#[cfg(test)]
|
|
use quickcheck::{quickcheck, Arbitrary, Gen};
|
|
use std::pin::Pin;
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
pub struct ClientUsernamePassword {
|
|
pub username: String,
|
|
pub password: String,
|
|
}
|
|
|
|
impl ClientUsernamePassword {
|
|
pub async fn read<R: AsyncRead + Send + Unpin>(
|
|
r: Pin<&mut R>,
|
|
) -> Result<Self, DeserializationError> {
|
|
let mut buffer = [0; 1];
|
|
let raw_r = Pin::into_inner(r);
|
|
|
|
if raw_r.read(&mut buffer).await? == 0 {
|
|
return Err(DeserializationError::NotEnoughData);
|
|
}
|
|
|
|
if buffer[0] != 1 {
|
|
return Err(DeserializationError::InvalidVersion(1, buffer[0]));
|
|
}
|
|
|
|
let username = read_string(Pin::new(raw_r)).await?;
|
|
let password = read_string(Pin::new(raw_r)).await?;
|
|
|
|
Ok(ClientUsernamePassword { username, password })
|
|
}
|
|
|
|
pub async fn write<W: AsyncWrite + Send + Unpin>(
|
|
&self,
|
|
w: &mut W,
|
|
) -> Result<(), SerializationError> {
|
|
w.write_all(&[1]).await?;
|
|
write_string(&self.username, w).await?;
|
|
write_string(&self.password, w).await
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
impl Arbitrary for ClientUsernamePassword {
|
|
fn arbitrary(g: &mut Gen) -> Self {
|
|
let username = arbitrary_socks_string(g);
|
|
let password = arbitrary_socks_string(g);
|
|
|
|
ClientUsernamePassword { username, password }
|
|
}
|
|
}
|
|
|
|
standard_roundtrip!(username_password_roundtrips, ClientUsernamePassword);
|
|
|
|
#[test]
|
|
fn check_short_reads() {
|
|
let empty = vec![];
|
|
let mut cursor = Cursor::new(empty);
|
|
let ys = ClientUsernamePassword::read(Pin::new(&mut cursor));
|
|
assert_eq!(Err(DeserializationError::NotEnoughData), task::block_on(ys));
|
|
|
|
let user_only = vec![1, 3, 102, 111, 111];
|
|
let mut cursor = Cursor::new(user_only);
|
|
let ys = ClientUsernamePassword::read(Pin::new(&mut cursor));
|
|
assert_eq!(Err(DeserializationError::NotEnoughData), task::block_on(ys));
|
|
}
|
|
|
|
#[test]
|
|
fn check_bad_version() {
|
|
let bad_len = vec![5];
|
|
let mut cursor = Cursor::new(bad_len);
|
|
let ys = ClientUsernamePassword::read(Pin::new(&mut cursor));
|
|
assert_eq!(
|
|
Err(DeserializationError::InvalidVersion(1, 5)),
|
|
task::block_on(ys)
|
|
);
|
|
}
|