From 20f8017355e8b9038c2df11b6bbf0f631e7b4a6c Mon Sep 17 00:00:00 2001 From: Khan Thompson Date: Thu, 31 Aug 2023 18:08:06 +1000 Subject: [PATCH 1/3] Use a single TLS implementation * Use cfg-if to select a single implementation * Add a note in the README that macOS needs to select an implementation. --- Cargo.toml | 1 + README.md | 2 ++ src/client/tls_stream.rs | 75 +++++++++++++++++++--------------------- 3 files changed, 38 insertions(+), 40 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4f96e962..314c5ecb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ async-trait = "0.1" connection-string = "0.2" num-traits = "0.2" uuid = "1.0" +cfg-if = "1.0" [target.'cfg(windows)'.dependencies] winauth = { version = "0.0.4", optional = true } diff --git a/README.md b/README.md index 44398dc5..5b8ad09d 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ A native Microsoft SQL Server (TDS) client for Rust. | `sql-browser-smol` | SQL Browser implementation for the `TcpStream` of smol. | `disabled` | | `integrated-auth-gssapi` | Support for using Integrated Auth via GSSAPI | `disabled` | +Note: if you get a timeout on macOS you will need to use either `rustls` or `vendored-openssl`. + ### Supported protocols Tiberius does not rely on any protocol when connecting to an SQL Server instance. Instead the `Client` takes a socket that implements the `AsyncRead` and `AsyncWrite` traits from the [futures-rs](https://crates.io/crates/futures) crate. diff --git a/src/client/tls_stream.rs b/src/client/tls_stream.rs index 9eba1060..939a420f 100644 --- a/src/client/tls_stream.rs +++ b/src/client/tls_stream.rs @@ -1,44 +1,39 @@ use crate::Config; use futures_util::io::{AsyncRead, AsyncWrite}; -#[cfg(feature = "native-tls")] -mod native_tls_stream; - -#[cfg(feature = "rustls")] -mod rustls_tls_stream; - -#[cfg(feature = "vendored-openssl")] -mod opentls_tls_stream; - -#[cfg(feature = "native-tls")] -pub(crate) use native_tls_stream::TlsStream; - -#[cfg(feature = "rustls")] -pub(crate) use rustls_tls_stream::TlsStream; - -#[cfg(feature = "vendored-openssl")] -pub(crate) use opentls_tls_stream::TlsStream; - -#[cfg(feature = "rustls")] -pub(crate) async fn create_tls_stream( - config: &Config, - stream: S, -) -> crate::Result> { - TlsStream::new(config, stream).await -} - -#[cfg(feature = "native-tls")] -pub(crate) async fn create_tls_stream( - config: &Config, - stream: S, -) -> crate::Result> { - native_tls_stream::create_tls_stream(config, stream).await -} - -#[cfg(feature = "vendored-openssl")] -pub(crate) async fn create_tls_stream( - config: &Config, - stream: S, -) -> crate::Result> { - opentls_tls_stream::create_tls_stream(config, stream).await +cfg_if::cfg_if! { + if #[cfg(feature = "rustls")] { + mod rustls_tls_stream; + + pub(crate) use rustls_tls_stream::TlsStream; + + pub(crate) async fn create_tls_stream( + config: &Config, + stream: S, + ) -> crate::Result> { + TlsStream::new(config, stream).await + } + } else if #[cfg(feature = "vendored-openssl")] { + mod opentls_tls_stream; + + pub(crate) use opentls_tls_stream::TlsStream; + + pub(crate) async fn create_tls_stream( + config: &Config, + stream: S, + ) -> crate::Result> { + opentls_tls_stream::create_tls_stream(config, stream).await + } + } else { + mod native_tls_stream; + + pub(crate) use native_tls_stream::TlsStream; + + pub(crate) async fn create_tls_stream( + config: &Config, + stream: S, + ) -> crate::Result> { + native_tls_stream::create_tls_stream(config, stream).await + } + } } From 1ef6051fdcc60befc94b001936d06c867624fa9f Mon Sep 17 00:00:00 2001 From: Khan Thompson Date: Thu, 31 Aug 2023 22:50:43 +1000 Subject: [PATCH 2/3] Update docs and explicitly require native-tls --- README.md | 9 ++++++++- src/client/tls_stream.rs | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5b8ad09d..f3a63b4d 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,14 @@ A native Microsoft SQL Server (TDS) client for Rust. | `sql-browser-smol` | SQL Browser implementation for the `TcpStream` of smol. | `disabled` | | `integrated-auth-gssapi` | Support for using Integrated Auth via GSSAPI | `disabled` | -Note: if you get a timeout on macOS you will need to use either `rustls` or `vendored-openssl`. +#### TLS feature flags + +There are three TLS feature flags: `native-tls` which uses system libraries; `rustls` which is a pure rust solution; and `vendored-openssl` which uses a prepackaged binary. By default this library will use `native-tls`. Because of the way default features +currently work with cargo, if you select another TLS implementation, you will get that implementation *and* the `native-tls` implementation. + +To avoid duplication of implementations, this library will use any specified TLS feature in preference of `native-tls`. This means that by default the library will use `native-tls`, but in the case of either `rustls` or `vendored-openssl` being supplied, those choices will take preference. + +If you experience issues with TLS handshake, simply add `tiberius = {version = "*", features = ["rustls"]}` to your cargo file. ### Supported protocols diff --git a/src/client/tls_stream.rs b/src/client/tls_stream.rs index 939a420f..f534f80c 100644 --- a/src/client/tls_stream.rs +++ b/src/client/tls_stream.rs @@ -24,7 +24,7 @@ cfg_if::cfg_if! { ) -> crate::Result> { opentls_tls_stream::create_tls_stream(config, stream).await } - } else { + } else if #[cfg(feature = "native-tls")] { mod native_tls_stream; pub(crate) use native_tls_stream::TlsStream; From b94e44415ca9aef606b1b3aa27945fa9292b4107 Mon Sep 17 00:00:00 2001 From: Khan Thompson Date: Fri, 1 Sep 2023 09:26:01 +1000 Subject: [PATCH 3/3] Change use of deprecated methods in chrono --- src/tds/time/chrono.rs | 4 ++-- tests/query.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/tds/time/chrono.rs b/src/tds/time/chrono.rs index 4bdb59a5..b448f8d4 100644 --- a/src/tds/time/chrono.rs +++ b/src/tds/time/chrono.rs @@ -81,7 +81,7 @@ from_sql!( let offset = chrono::Duration::minutes(dto.offset as i64); let naive = NaiveDateTime::new(date, time).sub(offset); - chrono::DateTime::from_utc(naive, Utc) + chrono::DateTime::from_naive_utc_and_offset(naive, Utc) }); chrono::DateTime: ColumnData::DateTimeOffset(ref dto) => dto.map(|dto| { let date = from_days(dto.datetime2.date.days() as i64, 1); @@ -91,7 +91,7 @@ from_sql!( let offset = FixedOffset::east_opt((dto.offset as i32) * 60).unwrap(); let naive = NaiveDateTime::new(date, time); - chrono::DateTime::from_utc(naive, offset) + chrono::DateTime::from_naive_utc_and_offset(naive, offset) }) ); diff --git a/tests/query.rs b/tests/query.rs index 527ab025..f2177ea2 100644 --- a/tests/query.rs +++ b/tests/query.rs @@ -2237,7 +2237,7 @@ where .unwrap() .and_hms_opt(16, 20, 0) .unwrap(); - let dt: DateTime = DateTime::from_utc(naive, Utc); + let dt: DateTime = DateTime::from_naive_utc_and_offset(naive, Utc); let row = conn .query("SELECT @P1", &[&dt]) @@ -2276,7 +2276,7 @@ where .unwrap(); let fixed = FixedOffset::east_opt(3600 * 3).unwrap(); - let dt: DateTime = DateTime::from_utc(naive, fixed); + let dt: DateTime = DateTime::from_naive_utc_and_offset(naive, fixed); let row = conn .query("SELECT @P1", &[&dt]) @@ -2314,7 +2314,7 @@ where .and_hms_opt(16, 20, 0) .unwrap(); let fixed = FixedOffset::east_opt(3600 * 3).unwrap(); - let dt: DateTime = DateTime::from_utc(naive, fixed); + let dt: DateTime = DateTime::from_naive_utc_and_offset(naive, fixed); let row = conn .query(format!("SELECT CAST('{}' AS datetimeoffset(7))", dt), &[])