Swap openssl for native-tls (#43)

* Replace openssl with native-tls

* Add From<TlsError> to allow builder()?

* Update AppVeyor config

* No email since it's not configured
This commit is contained in:
Jon Gjengset 2017-10-01 19:53:03 -04:00 committed by Matt McCoy
parent ba2eb75ddd
commit 7c95ae76d6
7 changed files with 95 additions and 110 deletions

View file

@ -25,7 +25,7 @@ name = "imap"
path = "src/lib.rs"
[dependencies]
openssl = "0.9"
native-tls = "0.1"
regex = "0.2"
bufstream = "0.1"

View file

@ -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

View file

@ -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();

View file

@ -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();

View file

@ -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<TcpStream> {
impl<'a> SetReadTimeout for TlsStream<TcpStream> {
fn set_read_timeout(&mut self, timeout: Option<Duration>) -> Result<()> {
self.get_ref()
.set_read_timeout(timeout)
@ -196,28 +196,28 @@ impl Client<TcpStream> {
pub fn secure(
mut self,
domain: &str,
ssl_connector: SslConnector,
) -> Result<Client<SslStream<TcpStream>>> {
ssl_connector: TlsConnector,
) -> Result<Client<TlsStream<TcpStream>>> {
// 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<SslStream<TcpStream>> {
impl Client<TlsStream<TcpStream>> {
/// Creates a client with an SSL wrapper.
pub fn secure_connect<A: ToSocketAddrs>(
addr: A,
domain: &str,
ssl_connector: SslConnector,
) -> Result<Client<SslStream<TcpStream>>> {
ssl_connector: TlsConnector,
) -> Result<Client<TlsStream<TcpStream>>> {
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);

View file

@ -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<T> = result::Result<T, Error>;
@ -14,8 +15,10 @@ pub type Result<T> = result::Result<T, Error>;
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<TcpStream>),
/// An error from the `native_tls` library during the TLS handshake.
TlsHandshake(TlsHandshakeError<TcpStream>),
/// An error from the `native_tls` library while managing the socket.
Tls(TlsError),
/// A BAD response from the IMAP server.
BadResponse(Vec<String>),
/// A NO response from the IMAP server.
@ -40,9 +43,15 @@ impl<T> From<BufError<T>> for Error {
}
}
impl From<SslError<TcpStream>> for Error {
fn from(err: SslError<TcpStream>) -> Error {
Error::Ssl(err)
impl From<TlsHandshakeError<TcpStream>> for Error {
fn from(err: TlsHandshakeError<TcpStream>) -> Error {
Error::TlsHandshake(err)
}
}
impl From<TlsError> 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,
}
}

View file

@ -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;