Skip to content

Commit da7407f

Browse files
committed
Add a more robust wrapper for OpenSSL support
1 parent 7e48593 commit da7407f

3 files changed

Lines changed: 48 additions & 12 deletions

File tree

src/io/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::io::prelude::*;
66
use std::fmt;
77

88
#[cfg(feature = "with-openssl")]
9-
mod openssl;
9+
pub mod openssl;
1010
#[cfg(feature = "security-framework")]
1111
mod security_framework;
1212

src/io/openssl.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
//! NegotiateSsl support for OpenSSL.
12
extern crate openssl;
23
extern crate openssl_verify;
34

45
use std::error::Error;
56

6-
use self::openssl::ssl::{IntoSsl, SslContext, SslStream, SSL_VERIFY_PEER};
7+
use self::openssl::ssl::{IntoSsl, SslContext, SslStream, SslMethod, SSL_VERIFY_PEER,
8+
SSL_OP_NO_SSLV2, SSL_OP_NO_SSLV3, SSL_OP_NO_COMPRESSION};
9+
use self::openssl::ssl::error::SslError;
710
use self::openssl_verify::verify_callback;
811
use io::{StreamWrapper, Stream, NegotiateSsl};
912

@@ -17,13 +20,46 @@ impl StreamWrapper for SslStream<Stream> {
1720
}
1821
}
1922

20-
impl NegotiateSsl for SslContext {
23+
/// A `NegotiateSsl` implementation that uses OpenSSL.
24+
#[derive(Debug)]
25+
pub struct Negotiator(SslContext);
26+
27+
impl Negotiator {
28+
/// Creates a `Negotiator` with a reasonable default configuration.
29+
///
30+
/// The configuration is modeled after libcurl's and is subject to change.
31+
pub fn new() -> Result<Negotiator, SslError> {
32+
let mut ctx = try!(SslContext::new(SslMethod::Sslv23));
33+
try!(ctx.set_default_verify_paths());
34+
ctx.set_options(SSL_OP_NO_SSLV2 | SSL_OP_NO_SSLV3 | SSL_OP_NO_COMPRESSION);
35+
try!(ctx.set_cipher_list("ALL!EXPORT!EXPORT40!EXPORT56!aNULL!LOW!RC4@STRENGTH"));
36+
Ok(ctx.into())
37+
}
38+
39+
/// Returns a reference to the associated `SslContext`.
40+
pub fn context(&self) -> &SslContext {
41+
&self.0
42+
}
43+
44+
/// Returns a mutable reference to the associated `SslContext`.
45+
pub fn context_mut(&mut self) -> &mut SslContext {
46+
&mut self.0
47+
}
48+
}
49+
50+
impl From<SslContext> for Negotiator {
51+
fn from(ctx: SslContext) -> Negotiator {
52+
Negotiator(ctx)
53+
}
54+
}
55+
56+
impl NegotiateSsl for Negotiator {
2157
fn negotiate_ssl(&self,
2258
domain: &str,
2359
stream: Stream)
2460
-> Result<Box<StreamWrapper>, Box<Error + Send + Sync>> {
2561
let domain = domain.to_owned();
26-
let mut ssl = try!(self.into_ssl());
62+
let mut ssl = try!(self.0.into_ssl());
2763
ssl.set_verify_callback(SSL_VERIFY_PEER, move |p, x| verify_callback(&domain, p, x));
2864
let stream = try!(SslStream::connect(ssl, stream));
2965
Ok(Box::new(stream))

tests/test.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ extern crate openssl;
66
#[cfg(feature = "security-framework")]
77
extern crate security_framework;
88

9-
#[cfg(feature = "with-openssl")]
10-
use openssl::ssl::{SslContext, SslMethod};
119
use std::thread;
1210
use std::io;
1311
use std::io::prelude::*;
@@ -26,6 +24,8 @@ use postgres::error::SqlState::{SyntaxError,
2624
use postgres::error::ErrorPosition::Normal;
2725
use postgres::rows::RowIndex;
2826
use postgres::notification::Notification;
27+
#[cfg(feature = "with-openssl")]
28+
use postgres::io::openssl::Negotiator;
2929

3030
macro_rules! or_panic {
3131
($e:expr) => (
@@ -665,20 +665,20 @@ fn test_cancel_query() {
665665
#[test]
666666
#[cfg(feature = "with-openssl")]
667667
fn test_require_ssl_conn() {
668-
let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap();
669-
ctx.set_CA_file(".travis/server.crt").unwrap();
668+
let mut negotiator = Negotiator::new().unwrap();
669+
negotiator.context_mut().set_CA_file(".travis/server.crt").unwrap();
670670
let conn = or_panic!(Connection::connect("postgres://postgres@localhost",
671-
SslMode::Require(&ctx)));
671+
SslMode::Require(&negotiator)));
672672
or_panic!(conn.execute("SELECT 1::VARCHAR", &[]));
673673
}
674674

675675
#[test]
676676
#[cfg(feature = "with-openssl")]
677677
fn test_prefer_ssl_conn() {
678-
let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap();
679-
ctx.set_CA_file(".travis/server.crt").unwrap();
678+
let mut negotiator = Negotiator::new().unwrap();
679+
negotiator.context_mut().set_CA_file(".travis/server.crt").unwrap();
680680
let conn = or_panic!(Connection::connect("postgres://postgres@localhost",
681-
SslMode::Prefer(&ctx)));
681+
SslMode::Require(&negotiator)));
682682
or_panic!(conn.execute("SELECT 1::VARCHAR", &[]));
683683
}
684684

0 commit comments

Comments
 (0)