Hardening the oauth2 example for gmail

This commit is contained in:
Matt McCoy 2016-06-28 22:29:55 -04:00
parent 8a1162ada4
commit 8d39bfd343
3 changed files with 42 additions and 29 deletions

View file

@ -3,7 +3,7 @@ extern crate openssl;
extern crate base64;
use openssl::ssl::{SslContext, SslMethod};
use base64::{encode, decode};
use base64::{encode};
use imap::client::Client;
use imap::authenticator::Authenticator;
@ -13,15 +13,16 @@ struct GmailOAuth2 {
}
impl Authenticator for GmailOAuth2 {
#[allow(unused_variables)]
fn process(&self, data: String) -> String {
String::from("dXNlcj1tYXR0bWNjb3kxMTBAZ21haWwuY29tAWF1dGg9QmVhcmVyIHlhMjkuQ2k4UUEzQ1Y5SW1OQ0Z1NDNpbkZRcngtSUR0cjVFSkZHNXdEM1IySzBXdTdiM1dzVG1Md")
encode(format!("user={}\x01auth=Bearer {}\x01\x01", self.user, self.access_token).as_bytes())
}
}
fn main() {
let mut gmail_auth = GmailOAuth2{
user: String::from("email@gmail.com"),
access_token: String::from("")
let gmail_auth = GmailOAuth2{
user: String::from("sombody@gmail.com"),
access_token: String::from("<access_token>")
};
let mut imap_socket = Client::secure_connect(("imap.gmail.com", 993), SslContext::new(SslMethod::Sslv23).unwrap()).unwrap();

View file

@ -1,3 +1,4 @@
/// This will allow plugable authentication mechanisms.
pub trait Authenticator {
fn process(&self, String) -> String;
}

View file

@ -63,18 +63,17 @@ impl<T: Read+Write> Client<T> {
pub fn authenticate<A: Authenticator>(&mut self, auth_type: &str, authenticator: A) -> Result<()> {
match self.run_command(&format!("AUTHENTICATE {}", auth_type).to_string()) {
Ok(_) => {
loop {
let line = match self.readline() {
Ok(l) => l,
Err(e) => return Err(e)
};
// TODO test this for the many authentication use cases
if line.starts_with(b"+") {
let data = match parse_authenticate_response(String::from_utf8(line).unwrap()) {
Ok(d) => d,
Err(e) => return Err(e)
};
println!("Done parsing authenticating response");
let auth_response = authenticator.process(data);
println!("Writing: {}", auth_response.clone());
match self.stream.write_all(auth_response.into_bytes().as_slice()) {
Err(e) => return Err(Error::Io(e)),
_ => {}
@ -83,9 +82,22 @@ impl<T: Read+Write> Client<T> {
Err(e) => return Err(Error::Io(e)),
_ => {}
};
match self.read_response() {
Ok(_) => Ok(()),
Err(e) => Err(e)
} else if line.starts_with(format!("{}{} ", TAG_PREFIX, self.tag).as_bytes()) {
match parse_response(vec![String::from_utf8(line).unwrap()]) {
Ok(_) => return Ok(()),
Err(e) => return Err(e)
};
} else {
let mut lines = match self.read_response() {
Ok(l) => l,
Err(e) => return Err(e)
};
lines.insert(0, String::from_utf8(line).unwrap());
match parse_response(lines.clone()) {
Ok(_) => return Ok(()),
Err(e) => return Err(e)
};
}
}
},
Err(e) => Err(e)
@ -279,7 +291,6 @@ impl<T: Read+Write> Client<T> {
print!("{}", String::from_utf8_lossy(byte_buffer));
line_buffer.push(byte_buffer[0]);
}
println!("{}", String::from_utf8(line_buffer.clone()).unwrap());
Ok(line_buffer)
}