const SEPARATOR: u8 = 0;
#[derive(Debug)]
pub struct PlainClient {
authzid: Option<String>,
authid: String,
password: Vec<u8>,
completed: bool,
}
impl Drop for PlainClient {
fn drop(&mut self) {
self.clear_password();
}
}
impl PlainClient {
pub fn new(authzid: Option<String>, authid: String, password: Vec<u8>) -> Self {
Self {
authzid,
authid,
password,
completed: false,
}
}
pub fn mechanism_name(&self) -> &str {
"PLAIN"
}
pub fn has_initial_response(&self) -> bool {
true
}
pub fn step(&mut self, _input: &[u8]) -> anyhow::Result<Vec<u8>> {
if self.completed {
Err(anyhow::anyhow!("PLAIN authentication already completed"))?
}
self.completed = true;
let mut output = vec![];
if let Some(authzid) = &self.authzid {
output.append(&mut authzid.as_bytes().to_owned());
}
output.push(SEPARATOR);
output.append(&mut self.authid.as_bytes().to_owned());
output.push(SEPARATOR);
output.append(&mut self.password);
self.clear_password();
Ok(output)
}
pub fn is_complete(&self) -> bool {
self.completed
}
fn clear_password(&mut self) {
for i in 0..self.password.len() {
self.password[i] = 0;
}
}
}