Skip to content

Commit 9e313fa

Browse files
authored
Merge pull request #388 from sfackler/split-tls
Split openssl/native-tls support to separate crates
2 parents fc00193 + bdf72d6 commit 9e313fa

File tree

10 files changed

+232
-55
lines changed

10 files changed

+232
-55
lines changed

.circleci/config.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ jobs:
2727
build:
2828
working_directory: ~/build
2929
docker:
30-
- image: rust:1.20.0
31-
environment:
32-
RUSTFLAGS: -D warnings
30+
- image: rust:1.26.0
3331
- image: sfackler/rust-postgres-test:3
3432
steps:
3533
- checkout

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,7 @@ members = [
44
"postgres",
55
"postgres-protocol",
66
"postgres-shared",
7+
"postgres-openssl",
8+
"postgres-native-tls",
79
"tokio-postgres"
810
]

postgres-native-tls/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "postgres-native-tls"
3+
version = "0.1.0"
4+
authors = ["Steven Fackler <[email protected]>"]
5+
6+
[dependencies]
7+
native-tls = "0.2"
8+
9+
postgres = { version = "0.15", path = "../postgres" }

postgres-native-tls/src/lib.rs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
pub extern crate native_tls;
2+
extern crate postgres;
3+
4+
use native_tls::TlsConnector;
5+
use postgres::tls::{Stream, TlsHandshake, TlsStream};
6+
use std::error::Error;
7+
use std::fmt::{self, Debug};
8+
use std::io::{self, Read, Write};
9+
10+
#[cfg(test)]
11+
mod test;
12+
13+
pub struct NativeTls {
14+
connector: TlsConnector,
15+
}
16+
17+
impl Debug for NativeTls {
18+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
19+
fmt.debug_struct("NativeTls").finish()
20+
}
21+
}
22+
23+
impl NativeTls {
24+
pub fn new() -> Result<NativeTls, native_tls::Error> {
25+
let connector = TlsConnector::builder().build()?;
26+
Ok(NativeTls::with_connector(connector))
27+
}
28+
29+
pub fn with_connector(connector: TlsConnector) -> NativeTls {
30+
NativeTls { connector }
31+
}
32+
}
33+
34+
impl TlsHandshake for NativeTls {
35+
fn tls_handshake(
36+
&self,
37+
domain: &str,
38+
stream: Stream,
39+
) -> Result<Box<TlsStream>, Box<Error + Sync + Send>> {
40+
let stream = self.connector.connect(domain, stream)?;
41+
Ok(Box::new(NativeTlsStream(stream)))
42+
}
43+
}
44+
45+
#[derive(Debug)]
46+
struct NativeTlsStream(native_tls::TlsStream<Stream>);
47+
48+
impl Read for NativeTlsStream {
49+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
50+
self.0.read(buf)
51+
}
52+
}
53+
54+
impl Write for NativeTlsStream {
55+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
56+
self.0.write(buf)
57+
}
58+
59+
fn flush(&mut self) -> io::Result<()> {
60+
self.0.flush()
61+
}
62+
}
63+
64+
impl TlsStream for NativeTlsStream {
65+
fn get_ref(&self) -> &Stream {
66+
self.0.get_ref()
67+
}
68+
69+
fn get_mut(&mut self) -> &mut Stream {
70+
self.0.get_mut()
71+
}
72+
}

postgres-native-tls/src/test.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
use native_tls::{Certificate, TlsConnector};
2+
use postgres::{Connection, TlsMode};
3+
4+
use NativeTls;
5+
6+
#[test]
7+
fn connect() {
8+
let cert = include_bytes!("../../test/server.crt");
9+
let cert = Certificate::from_pem(cert).unwrap();
10+
11+
let mut builder = TlsConnector::builder();
12+
builder.add_root_certificate(cert);
13+
let connector = builder.build().unwrap();
14+
15+
let handshake = NativeTls::with_connector(connector);
16+
let conn = Connection::connect(
17+
"postgres://ssl_user@localhost:5433/postgres",
18+
TlsMode::Require(&handshake),
19+
).unwrap();
20+
conn.execute("SELECT 1::VARCHAR", &[]).unwrap();
21+
}

postgres-openssl/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "postgres-openssl"
3+
version = "0.1.0"
4+
authors = ["Steven Fackler <[email protected]>"]
5+
6+
[dependencies]
7+
openssl = "0.10.9"
8+
9+
postgres = { version = "0.15", path = "../postgres" }

postgres-openssl/src/lib.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
pub extern crate openssl;
2+
extern crate postgres;
3+
4+
use openssl::error::ErrorStack;
5+
use openssl::ssl::{ConnectConfiguration, SslConnector, SslMethod, SslStream};
6+
use postgres::tls::{Stream, TlsHandshake, TlsStream};
7+
use std::error::Error;
8+
use std::fmt;
9+
use std::io::{self, Read, Write};
10+
11+
#[cfg(test)]
12+
mod test;
13+
14+
pub struct OpenSsl {
15+
connector: SslConnector,
16+
config: Box<Fn(&mut ConnectConfiguration) -> Result<(), ErrorStack> + Sync + Send>,
17+
}
18+
19+
impl fmt::Debug for OpenSsl {
20+
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
21+
fmt.debug_struct("OpenSsl").finish()
22+
}
23+
}
24+
25+
impl OpenSsl {
26+
pub fn new() -> Result<OpenSsl, ErrorStack> {
27+
let connector = SslConnector::builder(SslMethod::tls())?.build();
28+
Ok(OpenSsl::with_connector(connector))
29+
}
30+
31+
pub fn with_connector(connector: SslConnector) -> OpenSsl {
32+
OpenSsl {
33+
connector,
34+
config: Box::new(|_| Ok(())),
35+
}
36+
}
37+
38+
pub fn callback<F>(&mut self, f: F)
39+
where
40+
F: Fn(&mut ConnectConfiguration) -> Result<(), ErrorStack> + 'static + Sync + Send,
41+
{
42+
self.config = Box::new(f);
43+
}
44+
}
45+
46+
impl TlsHandshake for OpenSsl {
47+
fn tls_handshake(
48+
&self,
49+
domain: &str,
50+
stream: Stream,
51+
) -> Result<Box<TlsStream>, Box<Error + Sync + Send>> {
52+
let mut ssl = self.connector.configure()?;
53+
(self.config)(&mut ssl)?;
54+
let stream = ssl.connect(domain, stream)?;
55+
56+
Ok(Box::new(OpenSslStream(stream)))
57+
}
58+
}
59+
60+
#[derive(Debug)]
61+
struct OpenSslStream(SslStream<Stream>);
62+
63+
impl Read for OpenSslStream {
64+
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
65+
self.0.read(buf)
66+
}
67+
}
68+
69+
impl Write for OpenSslStream {
70+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
71+
self.0.write(buf)
72+
}
73+
74+
fn flush(&mut self) -> io::Result<()> {
75+
self.0.flush()
76+
}
77+
}
78+
79+
impl TlsStream for OpenSslStream {
80+
fn get_ref(&self) -> &Stream {
81+
self.0.get_ref()
82+
}
83+
84+
fn get_mut(&mut self) -> &mut Stream {
85+
self.0.get_mut()
86+
}
87+
}

postgres-openssl/src/test.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use openssl::ssl::{SslConnector, SslMethod};
2+
use postgres::{Connection, TlsMode};
3+
4+
use OpenSsl;
5+
6+
#[test]
7+
fn require() {
8+
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
9+
builder.set_ca_file("../test/server.crt").unwrap();
10+
let negotiator = OpenSsl::with_connector(builder.build());
11+
let conn = Connection::connect(
12+
"postgres://ssl_user@localhost:5433/postgres",
13+
TlsMode::Require(&negotiator),
14+
).unwrap();
15+
conn.execute("SELECT 1::VARCHAR", &[]).unwrap();
16+
}
17+
18+
#[test]
19+
fn prefer() {
20+
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
21+
builder.set_ca_file("../test/server.crt").unwrap();
22+
let negotiator = OpenSsl::with_connector(builder.build());
23+
let conn = Connection::connect(
24+
"postgres://ssl_user@localhost:5433/postgres",
25+
TlsMode::Require(&negotiator),
26+
).unwrap();
27+
conn.execute("SELECT 1::VARCHAR", &[]).unwrap();
28+
}

postgres/src/tls/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
pub use priv_io::Stream;
33

44
use std::error::Error;
5-
use std::io::prelude::*;
65
use std::fmt;
6+
use std::io::prelude::*;
77

88
#[cfg(feature = "with-native-tls")]
9+
#[deprecated(since = "0.15.2", note = "use the postgres-native-tls crate")]
910
pub mod native_tls;
1011
#[cfg(feature = "with-openssl")]
12+
#[deprecated(since = "0.15.2", note = "use the postgres-openssl crate")]
1113
pub mod openssl;
1214
#[cfg(feature = "with-schannel")]
1315
pub mod schannel;

postgres/tests/test.rs

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
extern crate fallible_iterator;
2-
#[cfg(feature = "native-tls")]
3-
extern crate native_tls;
4-
#[cfg(feature = "with-openssl")]
5-
extern crate openssl;
62
extern crate postgres;
73
#[macro_use]
84
extern crate postgres_shared;
@@ -954,38 +950,6 @@ fn test_cancel_query() {
954950
t.join().unwrap();
955951
}
956952

957-
#[test]
958-
#[cfg(feature = "with-openssl")]
959-
fn test_require_ssl_conn() {
960-
use openssl::ssl::{SslConnectorBuilder, SslMethod};
961-
use postgres::tls::openssl::OpenSsl;
962-
963-
let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
964-
builder.set_ca_file("../test/server.crt").unwrap();
965-
let negotiator = OpenSsl::from(builder.build());
966-
let conn = or_panic!(Connection::connect(
967-
"postgres://postgres@localhost:5433",
968-
TlsMode::Require(&negotiator),
969-
));
970-
or_panic!(conn.execute("SELECT 1::VARCHAR", &[]));
971-
}
972-
973-
#[test]
974-
#[cfg(feature = "with-openssl")]
975-
fn test_prefer_ssl_conn() {
976-
use openssl::ssl::{SslConnectorBuilder, SslMethod};
977-
use postgres::tls::openssl::OpenSsl;
978-
979-
let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
980-
builder.set_ca_file("../test/server.crt").unwrap();
981-
let negotiator = OpenSsl::from(builder.build());
982-
let conn = or_panic!(Connection::connect(
983-
"postgres://postgres@localhost:5433",
984-
TlsMode::Require(&negotiator),
985-
));
986-
or_panic!(conn.execute("SELECT 1::VARCHAR", &[]));
987-
}
988-
989953
#[test]
990954
#[cfg(feature = "with-security-framework")]
991955
fn security_framework_ssl() {
@@ -1003,21 +967,6 @@ fn security_framework_ssl() {
1003967
or_panic!(conn.execute("SELECT 1::VARCHAR", &[]));
1004968
}
1005969

1006-
#[test]
1007-
#[ignore]
1008-
// need to ignore until native-tls supports extra root certs :(
1009-
#[cfg(feature = "with-native-tls")]
1010-
fn native_tls_ssl() {
1011-
use postgres::tls::native_tls::NativeTls;
1012-
1013-
let negotiator = NativeTls::new().unwrap();
1014-
let conn = or_panic!(Connection::connect(
1015-
"postgres://postgres@localhost:5433",
1016-
TlsMode::Require(&negotiator),
1017-
));
1018-
or_panic!(conn.execute("SELECT 1::VARCHAR", &[]));
1019-
}
1020-
1021970
#[test]
1022971
fn test_plaintext_pass() {
1023972
or_panic!(Connection::connect(

0 commit comments

Comments
 (0)