diff --git a/.travis.yml b/.travis.yml index 2015ad18..18f70a2d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,5 +11,5 @@ before_script: - "./.travis/setup.sh" script: - cargo test -- cargo test --features "uuid rustc-serialize time unix_socket serde_json chrono openssl bit-vec eui48" +- cargo test --features "uuid rustc-serialize time unix_socket serde_json chrono with-openssl bit-vec eui48" - (test $TRAVIS_RUST_VERSION != "nightly" || cargo test --features nightly) diff --git a/.travis/server.crt b/.travis/server.crt index 8bd714ae..aa8bcf16 100644 --- a/.travis/server.crt +++ b/.travis/server.crt @@ -1,62 +1,24 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: - 9a:e5:7a:5f:05:5a:2f:e4 - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=localhost - Validity - Not Before: Dec 5 21:50:46 2015 GMT - Not After : Jan 4 21:50:46 2016 GMT - Subject: C=AU, ST=Some-State, O=Internet Widgits Pty Ltd, CN=localhost - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - RSA Public Key: (1024 bit) - Modulus (1024 bit): - 00:f1:9b:b6:24:64:66:bf:5e:da:77:2a:39:bd:39: - 93:56:28:26:f1:d7:1f:c9:60:1c:e3:82:a4:07:a2: - 0f:c8:d6:68:fc:30:2f:17:30:34:69:cd:d8:f1:e7: - c7:84:f9:c5:90:b1:2c:42:d5:23:20:d2:1d:d7:18: - 15:70:0a:a3:1d:c7:2e:df:03:c0:9f:5c:cb:02:25: - da:7d:2b:1a:09:78:e5:23:8a:c4:64:39:59:0d:4e: - 15:0b:75:7b:75:f9:8a:4c:c3:9d:f9:31:08:d5:da: - 00:a5:db:0c:df:09:e5:e4:14:d1:17:0f:bb:f6:cf: - bd:3c:5d:14:6a:cb:c1:dc:e1 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Subject Key Identifier: - 9E:09:C0:D1:1E:0E:07:B3:49:57:0A:49:47:F9:8A:5F:4E:FE:23:75 - X509v3 Authority Key Identifier: - keyid:9E:09:C0:D1:1E:0E:07:B3:49:57:0A:49:47:F9:8A:5F:4E:FE:23:75 - DirName:/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=localhost - serial:9A:E5:7A:5F:05:5A:2F:E4 - - X509v3 Basic Constraints: - CA:TRUE - Signature Algorithm: sha1WithRSAEncryption - 4c:3b:c6:42:96:75:96:a0:9b:f5:d9:b1:9b:1b:4f:bd:d2:8d: - f1:53:ed:87:80:f5:7b:5d:36:6e:38:c8:ae:1a:58:e5:39:9e: - 42:49:12:35:76:ab:0f:fa:b1:1f:4e:b1:85:f3:a3:6f:60:e3: - 6c:0e:a8:95:0d:c8:38:7f:e3:e3:ff:64:74:73:50:46:65:83: - 5f:1a:72:f9:69:44:07:cd:36:01:90:b9:b3:ed:d8:d7:bc:68: - 97:dd:11:ac:2b:ec:5d:a4:d4:d5:e8:8b:60:12:54:b9:c4:5f: - 00:f8:ce:5b:72:28:58:43:7c:d5:25:b7:dd:ec:71:da:aa:3a: - f2:6c -----BEGIN CERTIFICATE----- -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 +NmFaAhoxnXA= -----END CERTIFICATE----- diff --git a/.travis/server.der b/.travis/server.der index 4e6e4ba2..99a519c8 100644 Binary files a/.travis/server.der and b/.travis/server.der differ diff --git a/.travis/server.key b/.travis/server.key index 4157fc94..3bb6ad03 100644 --- a/.travis/server.key +++ b/.travis/server.key @@ -1,15 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDxm7YkZGa/Xtp3Kjm9OZNWKCbx1x/JYBzjgqQHog/I1mj8MC8X -MDRpzdjx58eE+cWQsSxC1SMg0h3XGBVwCqMdxy7fA8CfXMsCJdp9KxoJeOUjisRk -OVkNThULdXt1+YpMw535MQjV2gCl2wzfCeXkFNEXD7v2z708XRRqy8Hc4QIDAQAB -AoGBAIBsJuWzJFYmQfNDU4t8Fg+eqgy0LyYn21Mm9q9D+iXjqcwahH1L1yBCFUWH -0Kqi5NujAQbJKbHhXZEeMQ7r6IT8HjAW800F+M3eRLaMGVbh02L/EpEgUspb8VH+ -SZDolJvxCGmkBBgglJwYpFQG6ANXaEU0/uS+aHz0Wptip2NNAkEA+UdCmpY7whXS -5F3LrZE8qjwjEs86RxQoe7+wF7eT4CbXmxvQBwgxMO9ZUhwdUJ3Cm5T4Qu943gp/ -hiRIXunrdwJBAPgfgWNE1KpmJALr3opq+mu92D6YWk2aLFQj01kJI1lomRq/ptXB -niMPzzvauiFuNgpGtKKoxzBPM3l8Ii5E4GcCQCBTuHR5tSg3UlEhRM+ufRKKl/XR -f/pFx/Y8Zqa8vOWdw+oukizHSDHTaF74nGie/OTWTdfIXIFXFTCdNfFxHoMCQQDs -k2WT1/IJkp/tZSXnxn6Esht3+13GtiRkCVCfiRX6TsAEgA27rANynMVT5YYpD+NY -wvfCS7i4OBv1TkVs5mErAkAQmGseTKaye5ABFxBOEHT00hRtIE0yojuL6oPEDhkk -SJIBC5XE0vzmMKq9sQ7foqgPork9O4VYBo0q//BO0RWG +MIIEpAIBAAKCAQEAllItXwrj62MkxKVlz2FimJk42WWc3K82Rn2vAl6z38zQxSCj +t9uWwXWTx5YOdGiUcA+JUAruZxqN7vdfphJoYtTrcrpT4rC/FsCMImBxkj1cxdYT +q94SFn9bQBRZk7RUx4Kolt+/h0d3PpNIb4DbyQ8A0MVvNVxLpRRVwc6yQP+NkRMy +gHR+m3P8fxHEtkHCVy7HORbASvN8fRlREMHDL2hkadX0BNM72DDo+DWhPA8GF6WX +tIl1gU6GP6pSbEeMHD3f+uj7f9iSjvkrHrOt2nLUQ9Qnev2nhmU0/dOIweQ17/Fr +lL9jYDUUFNORyjRnlXXUoP5BO/LdEAAqT2A0pwIDAQABAoIBAQCIXu74XUneHuiZ +Wa+eTqwC4mZXmz6OWonzs0vU65NlgksXuv+r6ZO/2GoD1Bcy9jlL3Fxm+DPF56pB +07u7TtHSb3VWdMFrU4tYGcBH45TE5dRHSmo4LlPcgxeGb6/ANwX+pYNKtJvuHyCH +7Vf2iEFcCrdjrumv0BZ0IZmXJGxEV+7mK2Og0bZ/zbmJNaH25muuWj6BKlvLhL0N +S2LlBjKx3HqtppUgUqNFqjLs6IA1u79S5dAomOsxZtnuByaX5WFzpktU2pveZmyF +cl0dwHYZIaxR3ewYeQXGF8ANUmIx3nnxD2JOysPkitaGzeqt6dQZV14tPlDZDKat +Vf0b6BHhAoGBAMWV7rG+7nVXoQ30CIcPGklkST3mVOlrzeBbKP1SeAwoGRbfsdhp +rFMkh5UxTexnOzD4O8HPuJ6NGeWRQfqZT1nnjwHPeJWtiMHT6cnWxlzvxAZ61mio +0jRfb8flhgFKk+G9+Xa6WaYAAwGWdF062EMe2Ym92oKM9ilTPGFVRk1XAoGBAMLD +ETSQd2UqTF/y7wxMPqF3l6d1KBjwpuNuin2IjkXTOfGkDnAU3mSQlr7K1IPX8NPO +gdyMfJoysfRaBuRcNA/o/0l0wyxW4HWtTtPYI0+pRCFtRLsI1MB997QKeaGKb+me +3nBXkOksPSr9oa0Cs27z2cSoBOkpq2N/zzBseHExAoGAOyq3rKBZNehEwTHnb9I0 +8+9FA3U6zh9LKjkCIEGW00Uapj/cOMsEIG2a8DEwfW84SWS8OEBkr43fSGBkGo/Y +NDrkFw2ytVee0TQNGTTod6IQ2EPmera7I5XEml5/71kOyZWi40vQVqZAQDR2qgha +BFdzmwywJ1Hg0OUs+pSXlccCgYEAgyOVki80NYolovWQwFcWVOKR2s+oECL6PGlS +FvS714hCm9I7ZnymwlAZMJ6iOaRNJFEIX9i4jZtU95Mm0NzEsXHRc0SLpm9Y8+Oe +EEaYgCsZFOjePpHTr0kiYLgs7fipIkU2wa40hMyk4y2kjzoiV7MaDrCTnevQ205T +0+c1sgECgYBAXKcwdkh9JVSrLXFamsxiOx3MZ0n6J1d28wpdA3y4Y4AAJm4TGgFt +eG/6qHRy6CHdFtJ7a84EMe1jaVLQJYW/VrOC2bWLftkU7qaOnkXHvr4CAHsXQHcx +JhLfvh4ab3KyoK/iimifvcoS5z9gp7IBFKMyh5IeJ9Y75TgcfJ5HMg== -----END RSA PRIVATE KEY----- diff --git a/.travis/setup.sh b/.travis/setup.sh index f8f5561a..2268bd1d 100755 --- a/.travis/setup.sh +++ b/.travis/setup.sh @@ -8,5 +8,11 @@ psql -U postgres < setup.sql sudo cp pg_hba.conf $(psql -U postgres -c "SHOW hba_file" -At) DATA_DIR=$(psql -U postgres -c "SHOW data_directory" -At) -PG_PID=$(sudo head -n1 $DATA_DIR/postmaster.pid) -sudo kill -SIGHUP $PG_PID +CONFIG_FILE=$(psql -U postgres -c "SHOW config_file" -At) +sudo install -m 0600 -o postgres server.crt $DATA_DIR +sudo install -m 0600 -o postgres server.key $DATA_DIR +sudo bash -c "echo ssl_cert_file = \\'server.crt\\' >> $CONFIG_FILE" +sudo bash -c "echo ssl_key_file = \\'server.key\\' >> $CONFIG_FILE" + +sudo service postgresql stop +sudo service postgresql start 9.4 diff --git a/Cargo.toml b/Cargo.toml index 95b41b5f..168fd090 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ path = "tests/test.rs" [features] nightly = [] +with-openssl = ["openssl", "openssl-verify"] [dependencies] bufstream = "0.1" @@ -32,6 +33,7 @@ hex = "0.2" rustc-serialize = { version = "0.3", optional = true } chrono = { version = "0.2.14", optional = true } openssl = { version = ">= 0.6.4, < 0.8", optional = true } +openssl-verify = { version = "0.1", optional = true } serde_json = { version = ">= 0.6, < 0.9", optional = true } time = { version = "0.1.14", optional = true } unix_socket = { version = "0.5", optional = true } diff --git a/src/io/mod.rs b/src/io/mod.rs index 7677b04f..6824fb51 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -5,11 +5,14 @@ use std::error::Error; use std::io::prelude::*; use std::fmt; -#[cfg(feature = "openssl")] +#[cfg(feature = "with-openssl")] mod openssl; #[cfg(feature = "security-framework")] mod security_framework; +#[cfg(all(feature = "openssl", not(feature = "with-openssl")))] +const _CHECK: OpensslFeatureRenamedSeeDocs = ""; + /// A trait implemented by SSL adaptors. pub trait StreamWrapper: fmt::Debug + Read + Write + Send { /// Returns a reference to the underlying `Stream`. @@ -21,8 +24,8 @@ pub trait StreamWrapper: fmt::Debug + Read + Write + Send { /// A trait implemented by types that can negotiate SSL over a Postgres stream. /// -/// If the `openssl` Cargo feature is enabled, this trait will be implemented -/// for `openssl::ssl::SslContext`. +/// If the `with-openssl` Cargo feature is enabled, this trait will be +/// implemented for `openssl::ssl::SslContext`. /// /// If the `security-framework` Cargo feature is enabled, this trait will be /// implemented for `security_framework::secure_transport::ClientBuilder`. diff --git a/src/io/openssl.rs b/src/io/openssl.rs index 72d84a12..73ea3b6b 100644 --- a/src/io/openssl.rs +++ b/src/io/openssl.rs @@ -1,8 +1,10 @@ extern crate openssl; +extern crate openssl_verify; use std::error::Error; -use self::openssl::ssl::{SslContext, SslStream}; +use self::openssl::ssl::{IntoSsl, SslContext, SslStream, SSL_VERIFY_PEER}; +use self::openssl_verify::verify_callback; use io::{StreamWrapper, Stream, NegotiateSsl}; impl StreamWrapper for SslStream { @@ -17,10 +19,13 @@ impl StreamWrapper for SslStream { impl NegotiateSsl for SslContext { fn negotiate_ssl(&self, - _: &str, + domain: &str, stream: Stream) -> Result, Box> { - let stream = try!(SslStream::connect(self, stream)); + let domain = domain.to_owned(); + let mut ssl = try!(self.into_ssl()); + ssl.set_verify_callback(SSL_VERIFY_PEER, move |p, x| verify_callback(&domain, p, x)); + let stream = try!(SslStream::connect(ssl, stream)); Ok(Box::new(stream)) } } diff --git a/tests/test.rs b/tests/test.rs index 2a42d6ac..17f4c203 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -1,12 +1,12 @@ #[macro_use] extern crate postgres; extern crate url; -#[cfg(feature = "openssl")] +#[cfg(feature = "with-openssl")] extern crate openssl; #[cfg(feature = "security-framework")] extern crate security_framework; -#[cfg(feature = "openssl")] +#[cfg(feature = "with-openssl")] use openssl::ssl::{SslContext, SslMethod}; use std::thread; use std::io; @@ -663,18 +663,20 @@ fn test_cancel_query() { } #[test] -#[cfg(feature = "openssl")] +#[cfg(feature = "with-openssl")] fn test_require_ssl_conn() { - let ctx = SslContext::new(SslMethod::Sslv23).unwrap(); + let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap(); + ctx.set_CA_file(".travis/server.crt").unwrap(); let conn = or_panic!(Connection::connect("postgres://postgres@localhost", SslMode::Require(&ctx))); or_panic!(conn.execute("SELECT 1::VARCHAR", &[])); } #[test] -#[cfg(feature = "openssl")] +#[cfg(feature = "with-openssl")] fn test_prefer_ssl_conn() { - let ctx = SslContext::new(SslMethod::Sslv23).unwrap(); + let mut ctx = SslContext::new(SslMethod::Sslv23).unwrap(); + ctx.set_CA_file(".travis/server.crt").unwrap(); let conn = or_panic!(Connection::connect("postgres://postgres@localhost", SslMode::Prefer(&ctx))); or_panic!(conn.execute("SELECT 1::VARCHAR", &[]));