Reorganize and refactor, adding integration test for common library stuff
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
use std::io::{Error, ErrorKind, Read, Write};
|
||||
|
||||
/// The saslauthd protocol transmits strings as
|
||||
/// 16-bit unsigned network-byte-order lengths followed
|
||||
/// by the string itself.
|
||||
///
|
||||
pub fn read_string(stream: &mut impl Read) -> Result<String, Error> {
|
||||
let mut length_buffer = [0u8, 0u8];
|
||||
|
||||
stream.read_exact(&mut length_buffer)?;
|
||||
let length = u16::from_be_bytes(length_buffer);
|
||||
|
||||
let mut string_buffer = vec![0u8; length as usize];
|
||||
|
||||
stream.read_exact(&mut string_buffer)?;
|
||||
|
||||
match String::from_utf8(string_buffer) {
|
||||
Ok(str) => Ok(str),
|
||||
Err(_err) => Err(Error::new(ErrorKind::Other, "Invalid UTF-8 sent")),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_string(stream: &mut impl Write, s: &str) -> Result<(), Error> {
|
||||
let length = s.len();
|
||||
|
||||
if length > 0xffff {
|
||||
return Err(Error::new(ErrorKind::Other, "String too long to write"));
|
||||
}
|
||||
|
||||
let length_buffer = [(length >> 8) as u8, (length & 0xff) as u8];
|
||||
|
||||
stream.write_all(&length_buffer)?;
|
||||
stream.write_all(s.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+2
-71
@@ -1,71 +1,2 @@
|
||||
use std::io::{Error, ErrorKind, Read, Write};
|
||||
|
||||
pub const RESPONSE_NO: [u8; 4] = [0x0, 0x2, b'N', b'O'];
|
||||
pub const RESPONSE_OK: [u8; 4] = [0x0, 0x2, b'O', b'K'];
|
||||
|
||||
pub struct Request {
|
||||
pub userid: String,
|
||||
pub password: String,
|
||||
pub service: String,
|
||||
pub realm: String,
|
||||
}
|
||||
|
||||
/// The saslauthd protocol transmits strings as
|
||||
/// 16-bit unsigned network-byte-order lengths followed
|
||||
/// by the string itself.
|
||||
///
|
||||
pub fn read_string(stream: &mut impl Read) -> Result<String, Error> {
|
||||
let mut length_buffer = [0u8, 0u8];
|
||||
|
||||
stream.read_exact(&mut length_buffer)?;
|
||||
let length = u16::from_be_bytes(length_buffer);
|
||||
|
||||
let mut string_buffer = vec![0u8; length as usize];
|
||||
|
||||
stream.read_exact(&mut string_buffer)?;
|
||||
|
||||
match String::from_utf8(string_buffer) {
|
||||
Ok(str) => Ok(str),
|
||||
Err(_err) => Err(Error::new(ErrorKind::Other, "Invalid UTF-8 sent")),
|
||||
}
|
||||
}
|
||||
|
||||
fn write_string(stream: &mut impl Write, s: &str) -> Result<(), Error> {
|
||||
let length = s.len();
|
||||
|
||||
if length > 0xffff {
|
||||
return Err(Error::new(ErrorKind::Other, "String too long to write"));
|
||||
}
|
||||
|
||||
let length_buffer = [(length >> 8) as u8, (length & 0xff) as u8];
|
||||
|
||||
stream.write_all(&length_buffer)?;
|
||||
stream.write_all(s.as_bytes())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Request {
|
||||
pub fn from_stream(stream: &mut impl Read) -> Result<Self, Error> {
|
||||
let userid = read_string(stream)?;
|
||||
let password = read_string(stream)?;
|
||||
let service = read_string(stream)?;
|
||||
let realm = read_string(stream)?;
|
||||
|
||||
Ok(Request {
|
||||
userid,
|
||||
password,
|
||||
service,
|
||||
realm,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn write_to_stream(&self, stream: &mut impl Write) -> Result<(), Error> {
|
||||
write_string(stream, &self.userid)?;
|
||||
write_string(stream, &self.password)?;
|
||||
write_string(stream, &self.service)?;
|
||||
write_string(stream, &self.realm)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub mod io;
|
||||
pub mod request;
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
use crate::io::{read_string, write_string};
|
||||
use std::io::{Error, Read, Write};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Request {
|
||||
pub userid: String,
|
||||
pub password: String,
|
||||
pub service: String,
|
||||
pub realm: String,
|
||||
}
|
||||
|
||||
impl Request {
|
||||
pub fn new(userid: &str, password: &str, service: &str, realm: &str) -> Self {
|
||||
Request {
|
||||
userid: userid.to_string(),
|
||||
password: password.to_string(),
|
||||
service: service.to_string(),
|
||||
realm: realm.to_string(),
|
||||
}
|
||||
}
|
||||
pub fn from_stream(stream: &mut impl Read) -> Result<Self, Error> {
|
||||
let userid = read_string(stream)?;
|
||||
let password = read_string(stream)?;
|
||||
let service = read_string(stream)?;
|
||||
let realm = read_string(stream)?;
|
||||
|
||||
Ok(Request {
|
||||
userid,
|
||||
password,
|
||||
service,
|
||||
realm,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn write_to_stream(&self, stream: &mut impl Write) -> Result<(), Error> {
|
||||
write_string(stream, &self.userid)?;
|
||||
write_string(stream, &self.password)?;
|
||||
write_string(stream, &self.service)?;
|
||||
write_string(stream, &self.realm)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user