Error management for authentication
This commit is contained in:
@@ -16,6 +16,7 @@ use crypto::md5::Md5;
|
||||
use crypto::mac::Mac;
|
||||
|
||||
use NUL;
|
||||
use error::Error;
|
||||
|
||||
/// Returns a PLAIN mecanism response
|
||||
pub fn plain(username: &str, password: &str) -> String {
|
||||
@@ -23,14 +24,16 @@ pub fn plain(username: &str, password: &str) -> String {
|
||||
}
|
||||
|
||||
/// Returns a CRAM-MD5 mecanism response
|
||||
pub fn cram_md5(username: &str, password: &str, encoded_challenge: &str) -> String {
|
||||
// TODO manage errors
|
||||
let challenge = encoded_challenge.from_base64().unwrap();
|
||||
pub fn cram_md5(username: &str, password: &str, encoded_challenge: &str) -> Result<String, Error> {
|
||||
let challenge = match encoded_challenge.from_base64() {
|
||||
Ok(challenge) => challenge,
|
||||
Err(error) => return Err(Error::ChallengeParsingError(error)),
|
||||
};
|
||||
|
||||
let mut hmac = Hmac::new(Md5::new(), password.as_bytes());
|
||||
hmac.input(&challenge);
|
||||
|
||||
format!("{} {}", username, hmac.result().code().to_hex()).as_bytes().to_base64(base64::STANDARD)
|
||||
Ok(format!("{} {}", username, hmac.result().code().to_hex()).as_bytes().to_base64(base64::STANDARD))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -45,7 +48,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_cram_md5() {
|
||||
assert_eq!(cram_md5("alice", "wonderland",
|
||||
"PDE3ODkzLjEzMjA2NzkxMjNAdGVzc2VyYWN0LnN1c2FtLmluPg=="),
|
||||
"PDE3ODkzLjEzMjA2NzkxMjNAdGVzc2VyYWN0LnN1c2FtLmluPg==").unwrap(),
|
||||
"YWxpY2UgNjRiMmE0M2MxZjZlZDY4MDZhOTgwOTE0ZTIzZTc1ZjA=");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use std::io::{BufRead, Read, Write};
|
||||
use bufstream::BufStream;
|
||||
|
||||
use response::ResponseParser;
|
||||
use error::SmtpResult;
|
||||
use error::{Error, SmtpResult};
|
||||
use client::net::{Connector, SmtpStream};
|
||||
use client::authentication::{plain, cram_md5};
|
||||
use {CRLF, MESSAGE_ENDING};
|
||||
@@ -175,8 +175,14 @@ impl<S: Connector + Write + Read = SmtpStream> Client<S> {
|
||||
|
||||
/// Sends an AUTH command with CRAM-MD5 mecanism
|
||||
pub fn auth_cram_md5(&mut self, username: &str, password: &str) -> SmtpResult {
|
||||
let encoded_challenge = try!(self.command("AUTH CRAM-MD5")).first_word().expect("No challenge");
|
||||
self.command(&format!("AUTH CRAM-MD5 {}", cram_md5(username, password, &encoded_challenge)))
|
||||
let encoded_challenge = match try!(self.command("AUTH CRAM-MD5")).first_word() {
|
||||
Some(challenge) => challenge,
|
||||
None => return Err(Error::ResponseParsingError("Could not read CRAM challenge")),
|
||||
};
|
||||
|
||||
let cram_response = try!(cram_md5(username, password, &encoded_challenge));
|
||||
|
||||
self.command(&format!("AUTH CRAM-MD5 {}", cram_response))
|
||||
}
|
||||
|
||||
/// Sends the message content
|
||||
|
||||
Reference in New Issue
Block a user