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:
parent
ba2eb75ddd
commit
7c95ae76d6
7 changed files with 95 additions and 110 deletions
|
|
@ -25,7 +25,7 @@ name = "imap"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
openssl = "0.9"
|
native-tls = "0.1"
|
||||||
regex = "0.2"
|
regex = "0.2"
|
||||||
bufstream = "0.1"
|
bufstream = "0.1"
|
||||||
|
|
||||||
|
|
|
||||||
137
appveyor.yml
137
appveyor.yml
|
|
@ -1,94 +1,67 @@
|
||||||
|
# inspired by https://github.com/starkat99/appveyor-rust/blob/master/appveyor.yml
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
||||||
global:
|
|
||||||
RUST_VERSION: stable
|
|
||||||
CRATE_NAME: imap
|
|
||||||
SSL_CERT_FILE: "C:\\OpenSSL\\cacert.pem"
|
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
|
||||||
# MinGW
|
### MSVC Toolchains ###
|
||||||
- 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
|
# Stable 64-bit MSVC
|
||||||
- TARGET: i686-pc-windows-msvc
|
- channel: stable
|
||||||
BITS: 32
|
target: x86_64-pc-windows-msvc
|
||||||
OPENSSL_VERSION: 1_0_2L
|
# Stable 32-bit MSVC
|
||||||
OPENSSL_DIR: C:\OpenSSL
|
- channel: stable
|
||||||
- TARGET: x86_64-pc-windows-msvc
|
target: i686-pc-windows-msvc
|
||||||
BITS: 64
|
# Beta 64-bit MSVC
|
||||||
OPENSSL_VERSION: 1_1_0f
|
- channel: beta
|
||||||
OPENSSL_DIR: C:\OpenSSL
|
target: x86_64-pc-windows-msvc
|
||||||
|
# Beta 32-bit MSVC
|
||||||
|
- channel: beta
|
||||||
|
target: i686-pc-windows-msvc
|
||||||
|
|
||||||
# MinGW beta
|
### GNU Toolchains ###
|
||||||
- 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
|
|
||||||
|
|
||||||
# MSVC beta
|
# Stable 64-bit GNU
|
||||||
- TARGET: i686-pc-windows-msvc
|
- channel: stable
|
||||||
BITS: 32
|
target: x86_64-pc-windows-gnu
|
||||||
MSYS2: 1
|
# Stable 32-bit GNU
|
||||||
OPENSSL_VERSION: 1_0_2L
|
- channel: stable
|
||||||
OPENSSL_DIR: C:\OpenSSL
|
target: i686-pc-windows-gnu
|
||||||
RUST_VERSION: beta
|
# Beta 64-bit GNU
|
||||||
- TARGET: x86_64-pc-windows-msvc
|
- channel: beta
|
||||||
BITS: 64
|
target: x86_64-pc-windows-gnu
|
||||||
OPENSSL_VERSION: 1_1_0f
|
# Beta 32-bit GNU
|
||||||
OPENSSL_DIR: C:\OpenSSL
|
- channel: beta
|
||||||
RUST_VERSION: 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:
|
||||||
# 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
|
# install Rust
|
||||||
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
|
- appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe
|
||||||
- rustup-init.exe -y --default-host %TARGET% --default-toolchain %RUST_VERSION%
|
- rustup-init -yv --default-toolchain %channel% --default-host %target%
|
||||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
- set PATH=%PATH%;%USERPROFILE%\.cargo\bin
|
||||||
- if defined MSYS2 set PATH=C:\msys64\mingw%BITS%\bin;%PATH%
|
- rustc -vV
|
||||||
- rustc -Vv
|
- cargo -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
|
|
||||||
|
|
||||||
# Building is done in the test phase, so we disable Appveyor's build phase.
|
# Building is done in the test phase, so we disable Appveyor's build phase.
|
||||||
build: false
|
build: false
|
||||||
|
|
||||||
|
test_script:
|
||||||
|
- cargo test
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
extern crate imap;
|
extern crate imap;
|
||||||
extern crate openssl;
|
extern crate native_tls;
|
||||||
|
|
||||||
use openssl::ssl::{SslConnectorBuilder, SslMethod};
|
use native_tls::TlsConnector;
|
||||||
use imap::client::Client;
|
use imap::client::Client;
|
||||||
|
|
||||||
// To connect to the gmail IMAP server with this you will need to allow unsecure apps access.
|
// 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 domain = "imap.gmail.com";
|
||||||
let port = 993;
|
let port = 993;
|
||||||
let socket_addr = (domain, port);
|
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();
|
let mut imap_socket = Client::secure_connect(socket_addr, domain, ssl_connector).unwrap();
|
||||||
|
|
||||||
imap_socket.login("username", "password").unwrap();
|
imap_socket.login("username", "password").unwrap();
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
extern crate base64;
|
extern crate base64;
|
||||||
extern crate imap;
|
extern crate imap;
|
||||||
extern crate openssl;
|
extern crate native_tls;
|
||||||
|
|
||||||
use openssl::ssl::{SslConnectorBuilder, SslMethod};
|
use native_tls::TlsConnector;
|
||||||
use base64::encode;
|
use base64::encode;
|
||||||
use imap::client::Client;
|
use imap::client::Client;
|
||||||
use imap::authenticator::Authenticator;
|
use imap::authenticator::Authenticator;
|
||||||
|
|
@ -33,7 +33,7 @@ fn main() {
|
||||||
let domain = "imap.gmail.com";
|
let domain = "imap.gmail.com";
|
||||||
let port = 993;
|
let port = 993;
|
||||||
let socket_addr = (domain, port);
|
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();
|
let mut imap_socket = Client::secure_connect(socket_addr, domain, ssl_connector).unwrap();
|
||||||
|
|
||||||
imap_socket.authenticate("XOAUTH2", gmail_auth).unwrap();
|
imap_socket.authenticate("XOAUTH2", gmail_auth).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use std::net::{TcpStream, ToSocketAddrs};
|
use std::net::{TcpStream, ToSocketAddrs};
|
||||||
use openssl::ssl::{SslConnector, SslStream};
|
use native_tls::{TlsConnector, TlsStream};
|
||||||
use std::io::{self, Read, Write};
|
use std::io::{self, Read, Write};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use bufstream::BufStream;
|
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<()> {
|
fn set_read_timeout(&mut self, timeout: Option<Duration>) -> Result<()> {
|
||||||
self.get_ref()
|
self.get_ref()
|
||||||
.set_read_timeout(timeout)
|
.set_read_timeout(timeout)
|
||||||
|
|
@ -196,28 +196,28 @@ impl Client<TcpStream> {
|
||||||
pub fn secure(
|
pub fn secure(
|
||||||
mut self,
|
mut self,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
ssl_connector: SslConnector,
|
ssl_connector: TlsConnector,
|
||||||
) -> Result<Client<SslStream<TcpStream>>> {
|
) -> Result<Client<TlsStream<TcpStream>>> {
|
||||||
// TODO This needs to be tested
|
// TODO This needs to be tested
|
||||||
self.run_command_and_check_ok("STARTTLS")?;
|
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(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.
|
/// Creates a client with an SSL wrapper.
|
||||||
pub fn secure_connect<A: ToSocketAddrs>(
|
pub fn secure_connect<A: ToSocketAddrs>(
|
||||||
addr: A,
|
addr: A,
|
||||||
domain: &str,
|
domain: &str,
|
||||||
ssl_connector: SslConnector,
|
ssl_connector: TlsConnector,
|
||||||
) -> Result<Client<SslStream<TcpStream>>> {
|
) -> Result<Client<TlsStream<TcpStream>>> {
|
||||||
match TcpStream::connect(addr) {
|
match TcpStream::connect(addr) {
|
||||||
Ok(stream) => {
|
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,
|
Ok(s) => s,
|
||||||
Err(e) => return Err(Error::Ssl(e)),
|
Err(e) => return Err(Error::TlsHandshake(e)),
|
||||||
};
|
};
|
||||||
let mut socket = Client::new(ssl_stream);
|
let mut socket = Client::new(ssl_stream);
|
||||||
|
|
||||||
|
|
|
||||||
30
src/error.rs
30
src/error.rs
|
|
@ -4,7 +4,8 @@ use std::fmt;
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use std::net::TcpStream;
|
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;
|
use bufstream::IntoInnerError as BufError;
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
@ -14,8 +15,10 @@ pub type Result<T> = result::Result<T, Error>;
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// An `io::Error` that occurred while trying to read or write to a network stream.
|
/// An `io::Error` that occurred while trying to read or write to a network stream.
|
||||||
Io(IoError),
|
Io(IoError),
|
||||||
/// An error from the `openssl` library.
|
/// An error from the `native_tls` library during the TLS handshake.
|
||||||
Ssl(SslError<TcpStream>),
|
TlsHandshake(TlsHandshakeError<TcpStream>),
|
||||||
|
/// An error from the `native_tls` library while managing the socket.
|
||||||
|
Tls(TlsError),
|
||||||
/// A BAD response from the IMAP server.
|
/// A BAD response from the IMAP server.
|
||||||
BadResponse(Vec<String>),
|
BadResponse(Vec<String>),
|
||||||
/// A NO response from the IMAP server.
|
/// A NO response from the IMAP server.
|
||||||
|
|
@ -40,9 +43,15 @@ impl<T> From<BufError<T>> for Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SslError<TcpStream>> for Error {
|
impl From<TlsHandshakeError<TcpStream>> for Error {
|
||||||
fn from(err: SslError<TcpStream>) -> Error {
|
fn from(err: TlsHandshakeError<TcpStream>) -> Error {
|
||||||
Error::Ssl(err)
|
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 {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Io(ref e) => fmt::Display::fmt(e, f),
|
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()),
|
ref e => f.write_str(e.description()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +70,8 @@ impl StdError for Error {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Io(ref e) => e.description(),
|
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::Parse(ref e) => e.description(),
|
||||||
Error::BadResponse(_) => "Bad Response",
|
Error::BadResponse(_) => "Bad Response",
|
||||||
Error::NoResponse(_) => "No Response",
|
Error::NoResponse(_) => "No Response",
|
||||||
|
|
@ -72,7 +83,8 @@ impl StdError for Error {
|
||||||
fn cause(&self) -> Option<&StdError> {
|
fn cause(&self) -> Option<&StdError> {
|
||||||
match *self {
|
match *self {
|
||||||
Error::Io(ref e) => Some(e),
|
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,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
//! imap is a IMAP client for Rust.
|
//! imap is a IMAP client for Rust.
|
||||||
|
|
||||||
extern crate bufstream;
|
extern crate bufstream;
|
||||||
extern crate openssl;
|
extern crate native_tls;
|
||||||
extern crate regex;
|
extern crate regex;
|
||||||
|
|
||||||
pub mod authenticator;
|
pub mod authenticator;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue