From bde5e8bc4bfb7dccc141f279479ca5e344ea7a84 Mon Sep 17 00:00:00 2001 From: 641i130 Date: Mon, 24 Oct 2022 21:58:17 -0500 Subject: [PATCH 1/7] Added Plaintext IMAP connection example --- examples/README.md | 17 +++++++------- examples/plaintext.rs | 54 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 examples/plaintext.rs diff --git a/examples/README.md b/examples/README.md index b4a5964..b4c9044 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,12 +1,13 @@ -Examples -======== +# Examples This directory contains examples of working with the IMAP client. Examples: - * basic - This is a very basic example of using the client. - * gmail_oauth2 - This is an example using oauth2 for logging into gmail as a secure appplication. - * idle - This is an example showing how to use IDLE to monitor a mailbox. - * rustls - This demonstrates how to use Rustls instead of Openssl for secure connections (helpful for cross compilation). - * starttls - This is an example showing how to use STARTTLS after connecting over plaintext. - * timeout - This demonstrates how to use timeouts while connecting to an IMAP server by using a custom TCP/TLS stream initialization and creating a `Client` directly instead of using the `ClientBuilder`. + +- basic - This is a very basic example of using the client. +- gmail_oauth2 - This is an example using oauth2 for logging into gmail as a secure appplication. +- idle - This is an example showing how to use IDLE to monitor a mailbox. +- rustls - This demonstrates how to use Rustls instead of Openssl for secure connections (helpful for cross compilation). +- starttls - This is an example showing how to use STARTTLS after connecting over plaintext. +- timeout - This demonstrates how to use timeouts while connecting to an IMAP server by using a custom TCP/TLS stream initialization and creating a `Client` directly instead of using the `ClientBuilder`. +- plaintext - This demonstrates how to make an unencrypted IMAP connection (usually over 143) with a `Client` using a naked TCP connection. diff --git a/examples/plaintext.rs b/examples/plaintext.rs new file mode 100644 index 0000000..39472d4 --- /dev/null +++ b/examples/plaintext.rs @@ -0,0 +1,54 @@ +use std::net::TcpStream; + +fn main() { + // REMINDER this is unsafe, the credentials are sent over the connection in CLEARTEXT + // Anyone or anything between this connection and the server can read your login creds! + // Please oh please do not use this where this is even a possibility. + match plaintext() { + Ok(conn) => { + eprintln!("Connection successful!"); + println!("{:?}",conn); + }, + Err(e) => { + eprintln!("Connection error!"); + eprintln!("{:?}",e); + } + } +} + +fn plaintext() -> imap::error::Result> { + // Make a raw TCP connection to an UNSAFE IMAP server + let stream = TcpStream::connect("imap.example.com:143").unwrap(); // This is unsafe. + let mut client = imap::Client::new(stream); + client.read_greeting()?; + eprintln!("\nUNENCRYPTED connection made!!!!\n"); + eprintln!("This is highly not recommended.\n"); + // to do anything useful with the e-mails, we need to log in + let mut imap_session = client.login("user", "pass").unwrap(); + + // we want to fetch the first email in the INBOX mailbox + imap_session.select("INBOX")?; + + // fetch message number 1 in this mailbox, along with its RFC822 field. + // RFC 822 dictates the format of the body of e-mails + let messages = imap_session.fetch("1", "RFC822")?; + let message = if let Some(m) = messages.iter().next() { + m + } else { + return Ok(None); + }; + + // extract the message's body + let mut body; + match message.body() { + Some(msg) => { + body = std::str::from_utf8(msg) + .expect("message was not valid utf-8") + .to_string(); + } + None => body = "".to_string(), + } + // be nice to the server and log out + imap_session.logout()?; + Ok(Some(body)) +} From 4b75957a7c86966f8f4ced4bb12185cfe809c19e Mon Sep 17 00:00:00 2001 From: 641i130 Date: Sun, 30 Oct 2022 12:20:32 -0500 Subject: [PATCH 2/7] Fixed README.md formatting back to original --- examples/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/README.md b/examples/README.md index b4c9044..de1cb54 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,13 +1,13 @@ -# Examples +Examples +======== This directory contains examples of working with the IMAP client. Examples: - -- basic - This is a very basic example of using the client. -- gmail_oauth2 - This is an example using oauth2 for logging into gmail as a secure appplication. -- idle - This is an example showing how to use IDLE to monitor a mailbox. -- rustls - This demonstrates how to use Rustls instead of Openssl for secure connections (helpful for cross compilation). -- starttls - This is an example showing how to use STARTTLS after connecting over plaintext. -- timeout - This demonstrates how to use timeouts while connecting to an IMAP server by using a custom TCP/TLS stream initialization and creating a `Client` directly instead of using the `ClientBuilder`. -- plaintext - This demonstrates how to make an unencrypted IMAP connection (usually over 143) with a `Client` using a naked TCP connection. + * basic - This is a very basic example of using the client. + * gmail_oauth2 - This is an example using oauth2 for logging into gmail as a secure appplication. + * idle - This is an example showing how to use IDLE to monitor a mailbox. + * rustls - This demonstrates how to use Rustls instead of Openssl for secure connections (helpful for cross compilation). + * starttls - This is an example showing how to use STARTTLS after connecting over plaintext. + * timeout - This demonstrates how to use timeouts while connecting to an IMAP server by using a custom TCP/TLS stream initialization and creating a `Client` directly instead of using the `ClientBuilder`. + * plaintext - This demonstrates how to make an unencrypted IMAP connection (usually over 143) with a `Client` using a naked TCP connection. From 1fac43882d036d7f8df906d7a891c037bb7383dc Mon Sep 17 00:00:00 2001 From: 641i130 Date: Sun, 30 Oct 2022 12:23:43 -0500 Subject: [PATCH 3/7] Reworded unsafe to dangerous/risky. Updated the body parsing bit. Moved warning comments to .login call. --- examples/plaintext.rs | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/examples/plaintext.rs b/examples/plaintext.rs index 39472d4..51bf0c6 100644 --- a/examples/plaintext.rs +++ b/examples/plaintext.rs @@ -1,29 +1,30 @@ use std::net::TcpStream; fn main() { - // REMINDER this is unsafe, the credentials are sent over the connection in CLEARTEXT + // REMINDER this is dangerous, the credentials are sent over the connection in CLEARTEXT! // Anyone or anything between this connection and the server can read your login creds! // Please oh please do not use this where this is even a possibility. match plaintext() { Ok(conn) => { eprintln!("Connection successful!"); - println!("{:?}",conn); - }, + println!("{:?}", conn); + } Err(e) => { eprintln!("Connection error!"); - eprintln!("{:?}",e); + eprintln!("{:?}", e); } } } fn plaintext() -> imap::error::Result> { - // Make a raw TCP connection to an UNSAFE IMAP server let stream = TcpStream::connect("imap.example.com:143").unwrap(); // This is unsafe. let mut client = imap::Client::new(stream); client.read_greeting()?; eprintln!("\nUNENCRYPTED connection made!!!!\n"); eprintln!("This is highly not recommended.\n"); // to do anything useful with the e-mails, we need to log in + + // Makes an unencrypted login message to the IMAP server. This is risky business! let mut imap_session = client.login("user", "pass").unwrap(); // we want to fetch the first email in the INBOX mailbox @@ -39,15 +40,11 @@ fn plaintext() -> imap::error::Result> { }; // extract the message's body - let mut body; - match message.body() { - Some(msg) => { - body = std::str::from_utf8(msg) - .expect("message was not valid utf-8") - .to_string(); - } - None => body = "".to_string(), - } + let body = message + .body() + .map(|body| String::from_utf8(body).expect("message was not valid utf-8")) + .unwrap_or_else(String::new); + // be nice to the server and log out imap_session.logout()?; Ok(Some(body)) From c0a783e05a9edf3d7bd8e6319b313febeb0f885f Mon Sep 17 00:00:00 2001 From: Galileo <46945263+641i130@users.noreply.github.com> Date: Sun, 30 Oct 2022 19:24:49 -0500 Subject: [PATCH 4/7] Update examples/plaintext.rs Co-authored-by: Jon Gjengset --- examples/plaintext.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/plaintext.rs b/examples/plaintext.rs index 51bf0c6..4e46725 100644 --- a/examples/plaintext.rs +++ b/examples/plaintext.rs @@ -23,8 +23,7 @@ fn plaintext() -> imap::error::Result> { eprintln!("\nUNENCRYPTED connection made!!!!\n"); eprintln!("This is highly not recommended.\n"); // to do anything useful with the e-mails, we need to log in - - // Makes an unencrypted login message to the IMAP server. This is risky business! + // keep in mind that this is over plain TCP, so may leak all your secrets! let mut imap_session = client.login("user", "pass").unwrap(); // we want to fetch the first email in the INBOX mailbox From 67ab1c836722de822f86ad7fa92537bb0ff42c61 Mon Sep 17 00:00:00 2001 From: 641i130 Date: Sun, 30 Oct 2022 19:26:03 -0500 Subject: [PATCH 5/7] Reworded unsafe comment --- examples/plaintext.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plaintext.rs b/examples/plaintext.rs index 4e46725..f361569 100644 --- a/examples/plaintext.rs +++ b/examples/plaintext.rs @@ -17,7 +17,7 @@ fn main() { } fn plaintext() -> imap::error::Result> { - let stream = TcpStream::connect("imap.example.com:143").unwrap(); // This is unsafe. + let stream = TcpStream::connect("imap.example.com:143").unwrap(); // This is an unencrypted connection. let mut client = imap::Client::new(stream); client.read_greeting()?; eprintln!("\nUNENCRYPTED connection made!!!!\n"); From 04d3dd9449cc1499253a6599ef87fdec4eb30e21 Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Sun, 30 Oct 2022 22:02:06 -0400 Subject: [PATCH 6/7] Update examples/plaintext.rs --- examples/plaintext.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plaintext.rs b/examples/plaintext.rs index f361569..63100d6 100644 --- a/examples/plaintext.rs +++ b/examples/plaintext.rs @@ -17,7 +17,7 @@ fn main() { } fn plaintext() -> imap::error::Result> { - let stream = TcpStream::connect("imap.example.com:143").unwrap(); // This is an unencrypted connection. + let stream = TcpStream::connect("imap.example.com:143").unwrap(); let mut client = imap::Client::new(stream); client.read_greeting()?; eprintln!("\nUNENCRYPTED connection made!!!!\n"); From 5327d75e8f219c56edec269e4944f7c858a4656e Mon Sep 17 00:00:00 2001 From: 641i130 Date: Mon, 31 Oct 2022 18:27:29 -0500 Subject: [PATCH 7/7] Fixed compiling issue --- examples/plaintext.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/plaintext.rs b/examples/plaintext.rs index f361569..14efab2 100644 --- a/examples/plaintext.rs +++ b/examples/plaintext.rs @@ -41,7 +41,7 @@ fn plaintext() -> imap::error::Result> { // extract the message's body let body = message .body() - .map(|body| String::from_utf8(body).expect("message was not valid utf-8")) + .map(|body| String::from_utf8(body.to_vec()).expect("message was not valid utf-8")) .unwrap_or_else(String::new); // be nice to the server and log out