From 7c95ae76d609eb2349a28c533d47952e4d50cd1c Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Sun, 1 Oct 2017 19:53:03 -0400 Subject: [PATCH] Swap openssl for native-tls (#43) * Replace openssl with native-tls * Add From to allow builder()? * Update AppVeyor config * No email since it's not configured --- Cargo.toml | 2 +- appveyor.yml | 137 ++++++++++++++++----------------------- examples/basic.rs | 6 +- examples/gmail_oauth2.rs | 6 +- src/client.rs | 22 +++---- src/error.rs | 30 ++++++--- src/lib.rs | 2 +- 7 files changed, 95 insertions(+), 110 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index a7dbc5f..34e13f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ name = "imap" path = "src/lib.rs" [dependencies] -openssl = "0.9" +native-tls = "0.1" regex = "0.2" bufstream = "0.1" diff --git a/appveyor.yml b/appveyor.yml index 3ae2701..463e8aa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,94 +1,67 @@ +# inspired by https://github.com/starkat99/appveyor-rust/blob/master/appveyor.yml + environment: - - global: - RUST_VERSION: stable - CRATE_NAME: imap - SSL_CERT_FILE: "C:\\OpenSSL\\cacert.pem" - matrix: - # MinGW - - TARGET: i686-pc-windows-gnu - BITS: 32 - MSYS2: 1 - OPENSSL_VERSION: 1_1_0f - - TARGET: x86_64-pc-windows-gnu - BITS: 64 - MSYS2: 1 - OPENSSL_VERSION: 1_0_2L +### MSVC Toolchains ### - # MSVC - - TARGET: i686-pc-windows-msvc - BITS: 32 - OPENSSL_VERSION: 1_0_2L - OPENSSL_DIR: C:\OpenSSL - - TARGET: x86_64-pc-windows-msvc - BITS: 64 - OPENSSL_VERSION: 1_1_0f - OPENSSL_DIR: C:\OpenSSL + # Stable 64-bit MSVC + - channel: stable + target: x86_64-pc-windows-msvc + # Stable 32-bit MSVC + - channel: stable + target: i686-pc-windows-msvc + # Beta 64-bit MSVC + - channel: beta + target: x86_64-pc-windows-msvc + # Beta 32-bit MSVC + - channel: beta + target: i686-pc-windows-msvc - # MinGW beta - - TARGET: i686-pc-windows-gnu - BITS: 32 - MSYS2: 1 - OPENSSL_VERSION: 1_1_0f - RUST_VERSION: beta - - TARGET: x86_64-pc-windows-gnu - BITS: 64 - MSYS2: 1 - OPENSSL_VERSION: 1_0_2L - RUST_VERSION: beta +### GNU Toolchains ### - # MSVC beta - - TARGET: i686-pc-windows-msvc - BITS: 32 - MSYS2: 1 - OPENSSL_VERSION: 1_0_2L - OPENSSL_DIR: C:\OpenSSL - RUST_VERSION: beta - - TARGET: x86_64-pc-windows-msvc - BITS: 64 - OPENSSL_VERSION: 1_1_0f - OPENSSL_DIR: C:\OpenSSL - RUST_VERSION: beta + # Stable 64-bit GNU + - channel: stable + target: x86_64-pc-windows-gnu + # Stable 32-bit GNU + - channel: stable + target: i686-pc-windows-gnu + # Beta 64-bit GNU + - channel: beta + target: x86_64-pc-windows-gnu + # Beta 32-bit GNU + - channel: beta + target: i686-pc-windows-gnu + +### MinGW Toolchains ### + + # Stable 64-bit MinGW + - channel: stable + target: x86_64-pc-windows-msvc + MSYS_BITS: 64 + # Stable 32-bit MinGW + - channel: stable + target: i686-pc-windows-msvc + MSYS_BITS: 32 + # Beta 64-bit MinGW + - channel: beta + target: x86_64-pc-windows-msvc + MSYS_BITS: 64 + # Beta 32-bit MinGW + - channel: beta + target: i686-pc-windows-msvc + MSYS_BITS: 32 install: - # install OpenSSL - - ps: Start-FileDownload "http://slproweb.com/download/Win${env:BITS}OpenSSL-${env:OPENSSL_VERSION}.exe" - - Win%BITS%OpenSSL-%OPENSSL_VERSION%.exe /SILENT /VERYSILENT /SP- /DIR="C:\OpenSSL" - - appveyor DownloadFile https://curl.haxx.se/ca/cacert.pem -FileName C:\OpenSSL\cacert.pem - # install Rust - - curl -sSf -o rustup-init.exe https://win.rustup.rs/ - - rustup-init.exe -y --default-host %TARGET% --default-toolchain %RUST_VERSION% - - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - - if defined MSYS2 set PATH=C:\msys64\mingw%BITS%\bin;%PATH% - - rustc -Vv - - cargo -V - - - curl -sSf -o rustup-init.exe https://win.rustup.rs/ - - rustup-init.exe -y --default-host %TARGET% - - set PATH=%PATH%;C:\Users\appveyor\.cargo\bin - - if defined MSYS2 set PATH=C:\msys64\mingw%BITS%\bin;%PATH% - - rustc -V - - cargo -V - -test_script: - # we don't run the "test phase" when doing deploys - - if [%APPVEYOR_REPO_TAG%]==[false] ( - cargo build --target %TARGET% && - cargo build --target %TARGET% --release && - cargo test --target %TARGET% && - cargo test --target %TARGET% --release - ) - -cache: - - C:\Users\appveyor\.cargo\registry - - target - -notifications: - - provider: Email - on_build_success: false + - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe + - rustup-init -yv --default-toolchain %channel% --default-host %target% + - set PATH=%PATH%;%USERPROFILE%\.cargo\bin + - rustc -vV + - cargo -vV # Building is done in the test phase, so we disable Appveyor's build phase. build: false + +test_script: + - cargo test diff --git a/examples/basic.rs b/examples/basic.rs index 2107ec2..50567e6 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -1,7 +1,7 @@ extern crate imap; -extern crate openssl; +extern crate native_tls; -use openssl::ssl::{SslConnectorBuilder, SslMethod}; +use native_tls::TlsConnector; use imap::client::Client; // To connect to the gmail IMAP server with this you will need to allow unsecure apps access. @@ -11,7 +11,7 @@ fn main() { let domain = "imap.gmail.com"; let port = 993; let socket_addr = (domain, port); - let ssl_connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap().build(); + let ssl_connector = TlsConnector::builder().unwrap().build().unwrap(); let mut imap_socket = Client::secure_connect(socket_addr, domain, ssl_connector).unwrap(); imap_socket.login("username", "password").unwrap(); diff --git a/examples/gmail_oauth2.rs b/examples/gmail_oauth2.rs index b80bfac..e2cba0b 100644 --- a/examples/gmail_oauth2.rs +++ b/examples/gmail_oauth2.rs @@ -1,8 +1,8 @@ extern crate base64; extern crate imap; -extern crate openssl; +extern crate native_tls; -use openssl::ssl::{SslConnectorBuilder, SslMethod}; +use native_tls::TlsConnector; use base64::encode; use imap::client::Client; use imap::authenticator::Authenticator; @@ -33,7 +33,7 @@ fn main() { let domain = "imap.gmail.com"; let port = 993; let socket_addr = (domain, port); - let ssl_connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap().build(); + let ssl_connector = TlsConnector::builder().unwrap().build().unwrap(); let mut imap_socket = Client::secure_connect(socket_addr, domain, ssl_connector).unwrap(); imap_socket.authenticate("XOAUTH2", gmail_auth).unwrap(); diff --git a/src/client.rs b/src/client.rs index 7f00f62..30a6738 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,5 +1,5 @@ use std::net::{TcpStream, ToSocketAddrs}; -use openssl::ssl::{SslConnector, SslStream}; +use native_tls::{TlsConnector, TlsStream}; use std::io::{self, Read, Write}; use std::time::Duration; use bufstream::BufStream; @@ -168,7 +168,7 @@ impl<'a> SetReadTimeout for TcpStream { } } -impl<'a> SetReadTimeout for SslStream { +impl<'a> SetReadTimeout for TlsStream { fn set_read_timeout(&mut self, timeout: Option) -> Result<()> { self.get_ref() .set_read_timeout(timeout) @@ -196,28 +196,28 @@ impl Client { pub fn secure( mut self, domain: &str, - ssl_connector: SslConnector, - ) -> Result>> { + ssl_connector: TlsConnector, + ) -> Result>> { // TODO This needs to be tested self.run_command_and_check_ok("STARTTLS")?; - SslConnector::connect(&ssl_connector, domain, try!(self.stream.into_inner())) + TlsConnector::connect(&ssl_connector, domain, try!(self.stream.into_inner())) .map(Client::new) - .map_err(Error::Ssl) + .map_err(Error::TlsHandshake) } } -impl Client> { +impl Client> { /// Creates a client with an SSL wrapper. pub fn secure_connect( addr: A, domain: &str, - ssl_connector: SslConnector, - ) -> Result>> { + ssl_connector: TlsConnector, + ) -> Result>> { match TcpStream::connect(addr) { Ok(stream) => { - let ssl_stream = match SslConnector::connect(&ssl_connector, domain, stream) { + let ssl_stream = match TlsConnector::connect(&ssl_connector, domain, stream) { Ok(s) => s, - Err(e) => return Err(Error::Ssl(e)), + Err(e) => return Err(Error::TlsHandshake(e)), }; let mut socket = Client::new(ssl_stream); diff --git a/src/error.rs b/src/error.rs index a653834..e72bcf6 100644 --- a/src/error.rs +++ b/src/error.rs @@ -4,7 +4,8 @@ use std::fmt; use std::error::Error as StdError; use std::net::TcpStream; -use openssl::ssl::HandshakeError as SslError; +use native_tls::HandshakeError as TlsHandshakeError; +use native_tls::Error as TlsError; use bufstream::IntoInnerError as BufError; pub type Result = result::Result; @@ -14,8 +15,10 @@ pub type Result = result::Result; pub enum Error { /// An `io::Error` that occurred while trying to read or write to a network stream. Io(IoError), - /// An error from the `openssl` library. - Ssl(SslError), + /// An error from the `native_tls` library during the TLS handshake. + TlsHandshake(TlsHandshakeError), + /// An error from the `native_tls` library while managing the socket. + Tls(TlsError), /// A BAD response from the IMAP server. BadResponse(Vec), /// A NO response from the IMAP server. @@ -40,9 +43,15 @@ impl From> for Error { } } -impl From> for Error { - fn from(err: SslError) -> Error { - Error::Ssl(err) +impl From> for Error { + fn from(err: TlsHandshakeError) -> Error { + Error::TlsHandshake(err) + } +} + +impl From for Error { + fn from(err: TlsError) -> Error { + Error::Tls(err) } } @@ -50,7 +59,8 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Error::Io(ref e) => fmt::Display::fmt(e, f), - Error::Ssl(ref e) => fmt::Display::fmt(e, f), + Error::Tls(ref e) => fmt::Display::fmt(e, f), + Error::TlsHandshake(ref e) => fmt::Display::fmt(e, f), ref e => f.write_str(e.description()), } } @@ -60,7 +70,8 @@ impl StdError for Error { fn description(&self) -> &str { match *self { Error::Io(ref e) => e.description(), - Error::Ssl(ref e) => e.description(), + Error::Tls(ref e) => e.description(), + Error::TlsHandshake(ref e) => e.description(), Error::Parse(ref e) => e.description(), Error::BadResponse(_) => "Bad Response", Error::NoResponse(_) => "No Response", @@ -72,7 +83,8 @@ impl StdError for Error { fn cause(&self) -> Option<&StdError> { match *self { Error::Io(ref e) => Some(e), - Error::Ssl(ref e) => Some(e), + Error::Tls(ref e) => Some(e), + Error::TlsHandshake(ref e) => Some(e), _ => None, } } diff --git a/src/lib.rs b/src/lib.rs index 6473674..9901de5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,7 +4,7 @@ //! imap is a IMAP client for Rust. extern crate bufstream; -extern crate openssl; +extern crate native_tls; extern crate regex; pub mod authenticator;