Hardening the oauth2 example for gmail
This commit is contained in:
parent
8a1162ada4
commit
8d39bfd343
3 changed files with 42 additions and 29 deletions
|
|
@ -3,7 +3,7 @@ extern crate openssl;
|
||||||
extern crate base64;
|
extern crate base64;
|
||||||
|
|
||||||
use openssl::ssl::{SslContext, SslMethod};
|
use openssl::ssl::{SslContext, SslMethod};
|
||||||
use base64::{encode, decode};
|
use base64::{encode};
|
||||||
use imap::client::Client;
|
use imap::client::Client;
|
||||||
use imap::authenticator::Authenticator;
|
use imap::authenticator::Authenticator;
|
||||||
|
|
||||||
|
|
@ -13,15 +13,16 @@ struct GmailOAuth2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Authenticator for GmailOAuth2 {
|
impl Authenticator for GmailOAuth2 {
|
||||||
|
#[allow(unused_variables)]
|
||||||
fn process(&self, data: String) -> String {
|
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() {
|
fn main() {
|
||||||
let mut gmail_auth = GmailOAuth2{
|
let gmail_auth = GmailOAuth2{
|
||||||
user: String::from("email@gmail.com"),
|
user: String::from("sombody@gmail.com"),
|
||||||
access_token: String::from("")
|
access_token: String::from("<access_token>")
|
||||||
};
|
};
|
||||||
let mut imap_socket = Client::secure_connect(("imap.gmail.com", 993), SslContext::new(SslMethod::Sslv23).unwrap()).unwrap();
|
let mut imap_socket = Client::secure_connect(("imap.gmail.com", 993), SslContext::new(SslMethod::Sslv23).unwrap()).unwrap();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
/// This will allow plugable authentication mechanisms.
|
||||||
pub trait Authenticator {
|
pub trait Authenticator {
|
||||||
fn process(&self, String) -> String;
|
fn process(&self, String) -> String;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,18 +63,17 @@ impl<T: Read+Write> Client<T> {
|
||||||
pub fn authenticate<A: Authenticator>(&mut self, auth_type: &str, authenticator: A) -> Result<()> {
|
pub fn authenticate<A: Authenticator>(&mut self, auth_type: &str, authenticator: A) -> Result<()> {
|
||||||
match self.run_command(&format!("AUTHENTICATE {}", auth_type).to_string()) {
|
match self.run_command(&format!("AUTHENTICATE {}", auth_type).to_string()) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
loop {
|
||||||
let line = match self.readline() {
|
let line = match self.readline() {
|
||||||
Ok(l) => l,
|
Ok(l) => l,
|
||||||
Err(e) => return Err(e)
|
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()) {
|
let data = match parse_authenticate_response(String::from_utf8(line).unwrap()) {
|
||||||
Ok(d) => d,
|
Ok(d) => d,
|
||||||
Err(e) => return Err(e)
|
Err(e) => return Err(e)
|
||||||
};
|
};
|
||||||
println!("Done parsing authenticating response");
|
|
||||||
let auth_response = authenticator.process(data);
|
let auth_response = authenticator.process(data);
|
||||||
println!("Writing: {}", auth_response.clone());
|
|
||||||
match self.stream.write_all(auth_response.into_bytes().as_slice()) {
|
match self.stream.write_all(auth_response.into_bytes().as_slice()) {
|
||||||
Err(e) => return Err(Error::Io(e)),
|
Err(e) => return Err(Error::Io(e)),
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
@ -83,9 +82,22 @@ impl<T: Read+Write> Client<T> {
|
||||||
Err(e) => return Err(Error::Io(e)),
|
Err(e) => return Err(Error::Io(e)),
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
match self.read_response() {
|
} else if line.starts_with(format!("{}{} ", TAG_PREFIX, self.tag).as_bytes()) {
|
||||||
Ok(_) => Ok(()),
|
match parse_response(vec![String::from_utf8(line).unwrap()]) {
|
||||||
Err(e) => Err(e)
|
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)
|
Err(e) => Err(e)
|
||||||
|
|
@ -279,7 +291,6 @@ impl<T: Read+Write> Client<T> {
|
||||||
print!("{}", String::from_utf8_lossy(byte_buffer));
|
print!("{}", String::from_utf8_lossy(byte_buffer));
|
||||||
line_buffer.push(byte_buffer[0]);
|
line_buffer.push(byte_buffer[0]);
|
||||||
}
|
}
|
||||||
println!("{}", String::from_utf8(line_buffer.clone()).unwrap());
|
|
||||||
Ok(line_buffer)
|
Ok(line_buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue