From a4e1551b69f98ee732a2a1dd5a395b7f21b7b980 Mon Sep 17 00:00:00 2001 From: Niclas Klugmann Date: Thu, 14 Aug 2025 10:47:33 +0200 Subject: [PATCH 1/3] fix documentation for rustls native root certificates --- sqlx-postgres/src/options/doc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sqlx-postgres/src/options/doc.md b/sqlx-postgres/src/options/doc.md index 15c2459c81..33dd63b7a8 100644 --- a/sqlx-postgres/src/options/doc.md +++ b/sqlx-postgres/src/options/doc.md @@ -86,7 +86,7 @@ See `default_host()` in the same source file as this method for the current beha If `sslrootcert` is not set, the default root certificates used depends on Cargo features: * If `tls-native-tls` is enabled, the system root certificates are used. -* If `tls-rustls-native-roots` is enabled, the system root certificates are used. +* If `tls-rustls-ring-native-roots` is enabled, the system root certificates are used. * Otherwise, TLS roots are populated using the [`webpki-roots`] crate. ## Environment Variables From 2bd3a502a9ccf54cb2c3684a15f2ff47a775b614 Mon Sep 17 00:00:00 2001 From: Niclas Klugmann Date: Tue, 16 Sep 2025 13:08:46 +0200 Subject: [PATCH 2/3] postgres kerberos compatibility --- Cargo.lock | 181 +++++++++++++++++++- sqlx-core/src/error.rs | 3 + sqlx-postgres/Cargo.toml | 1 + sqlx-postgres/src/connection/establish.rs | 5 + sqlx-postgres/src/connection/gssapi.rs | 45 +++++ sqlx-postgres/src/connection/mod.rs | 1 + sqlx-postgres/src/message/authentication.rs | 13 ++ sqlx-postgres/src/message/gssapi.rs | 20 +++ sqlx-postgres/src/message/mod.rs | 4 +- sqlx-postgres/src/options/mod.rs | 8 + 10 files changed, 276 insertions(+), 5 deletions(-) create mode 100644 sqlx-postgres/src/connection/gssapi.rs create mode 100644 sqlx-postgres/src/message/gssapi.rs diff --git a/Cargo.lock b/Cargo.lock index 79906bb607..a5f7355fb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,7 +337,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "923ded50f602b3007e5e63e3f094c479d9c8a9b42d7f4034e4afe456aa48bfd2" dependencies = [ - "bindgen", + "bindgen 0.69.5", "cc", "cmake", "dunce", @@ -482,12 +482,32 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 1.1.0", "shlex", "syn 2.0.96", "which", ] +[[package]] +name = "bindgen" +version = "0.71.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" +dependencies = [ + "bitflags 2.7.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 2.1.1", + "shlex", + "syn 2.0.96", +] + [[package]] name = "bit-vec" version = "0.6.3" @@ -991,6 +1011,19 @@ dependencies = [ "itertools 0.10.5", ] +[[package]] +name = "cross-krb5" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d4ddf7139e64dc916b11d434421031bcc5ba02e521a49a011652a0f68775188" +dependencies = [ + "anyhow", + "bitflags 2.7.0", + "bytes", + "libgssapi", + "windows", +] + [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -1716,7 +1749,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -2039,6 +2072,28 @@ version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +[[package]] +name = "libgssapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "834339e86b2561169d45d3b01741967fee3e5716c7d0b6e33cd4e3b34c9558cd" +dependencies = [ + "bitflags 2.7.0", + "bytes", + "lazy_static", + "libgssapi-sys", +] + +[[package]] +name = "libgssapi-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7518e6902e94f92e7c7271232684b60988b4bd813529b4ef9d97aead96956ae8" +dependencies = [ + "bindgen 0.71.1", + "pkg-config", +] + [[package]] name = "libloading" version = "0.8.6" @@ -2072,7 +2127,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ - "bindgen", + "bindgen 0.69.5", "cc", "pkg-config", "vcpkg", @@ -2989,6 +3044,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustix" version = "0.38.43" @@ -3814,6 +3875,7 @@ dependencies = [ "byteorder", "chrono", "crc", + "cross-krb5", "dotenvy", "etcetera", "futures-channel", @@ -4832,6 +4894,28 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -4841,6 +4925,86 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -4899,6 +5063,15 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" diff --git a/sqlx-core/src/error.rs b/sqlx-core/src/error.rs index c6652aef75..69036f5d37 100644 --- a/sqlx-core/src/error.rs +++ b/sqlx-core/src/error.rs @@ -52,6 +52,9 @@ pub enum Error { #[error("error occurred while attempting to establish a TLS connection: {0}")] Tls(#[source] BoxDynError), + #[error("error occured during gssapi negotiation: {0}")] + GssApi(#[from] BoxDynError), + /// Unexpected or invalid data encountered while communicating with the database. /// /// This should indicate there is a programming error in a SQLx driver or there diff --git a/sqlx-postgres/Cargo.toml b/sqlx-postgres/Cargo.toml index a70fb37d72..e3c22239cb 100644 --- a/sqlx-postgres/Cargo.toml +++ b/sqlx-postgres/Cargo.toml @@ -71,6 +71,7 @@ whoami = { version = "1.2.1", default-features = false } serde = { version = "1.0.144", features = ["derive"] } serde_json = { version = "1.0.85", features = ["raw_value"] } +cross-krb5 = { version = "0.4.2" } [dependencies.sqlx-core] workspace = true diff --git a/sqlx-postgres/src/connection/establish.rs b/sqlx-postgres/src/connection/establish.rs index 634b71de4b..cdacf3333e 100644 --- a/sqlx-postgres/src/connection/establish.rs +++ b/sqlx-postgres/src/connection/establish.rs @@ -1,3 +1,4 @@ +use crate::connection::gssapi; use crate::HashMap; use crate::common::StatementCache; @@ -97,6 +98,10 @@ impl PgConnection { .await?; } + Authentication::Gss => { + gssapi::authenticate(&mut stream, options).await?; + } + Authentication::Sasl(body) => { sasl::authenticate(&mut stream, options, body).await?; } diff --git a/sqlx-postgres/src/connection/gssapi.rs b/sqlx-postgres/src/connection/gssapi.rs new file mode 100644 index 0000000000..4f33dfc080 --- /dev/null +++ b/sqlx-postgres/src/connection/gssapi.rs @@ -0,0 +1,45 @@ +use std::borrow::Cow; + +use crate::error::Error; +use cross_krb5::InitiateFlags; + +use crate::{ + connection::PgStream, + message::{Authentication, AuthenticationGss, GssResponse}, + PgConnectOptions, +}; + +pub async fn authenticate(stream: &mut PgStream, options: &PgConnectOptions) -> Result<(), Error> { + let PgConnectOptions { + host, + gssapi_target_principal: gssapi_principal, + .. + } = options; + let principal = gssapi_principal + .as_ref() + .map(Cow::Borrowed) + .unwrap_or(Cow::Owned(format!("postgres/{host}"))); + let (mut ctx, token) = + cross_krb5::ClientCtx::new(InitiateFlags::empty(), None, &principal, None) + .map_err(|e| Error::GssApi(e.into()))?; + let msg = GssResponse { token: &token }; + stream.send(msg).await?; + loop { + let token = match stream.recv_expect().await? { + Authentication::GssContinue(AuthenticationGss { token }) => token, + other => return Err(err_protocol!("expected GssContinue but receiver {other:?}")), + }; + match ctx.step(&token).map_err(|e| Error::GssApi(e.into()))? { + cross_krb5::Step::Finished((_context, last_token)) => { + if let Some(last_token) = last_token { + stream.send(GssResponse { token: &last_token }).await?; + } + return Ok(()); + } + cross_krb5::Step::Continue((pending, token)) => { + ctx = pending; + stream.send(GssResponse { token: &token }).await?; + } + } + } +} diff --git a/sqlx-postgres/src/connection/mod.rs b/sqlx-postgres/src/connection/mod.rs index 4e05cd867b..8ef916467c 100644 --- a/sqlx-postgres/src/connection/mod.rs +++ b/sqlx-postgres/src/connection/mod.rs @@ -26,6 +26,7 @@ pub use self::stream::PgStream; pub(crate) mod describe; mod establish; mod executor; +mod gssapi; mod sasl; mod stream; mod tls; diff --git a/sqlx-postgres/src/message/authentication.rs b/sqlx-postgres/src/message/authentication.rs index 3a3cf7ff6e..6e071762fb 100644 --- a/sqlx-postgres/src/message/authentication.rs +++ b/sqlx-postgres/src/message/authentication.rs @@ -36,6 +36,12 @@ pub enum Authentication { /// again using the 4-byte random salt. Md5Password(AuthenticationMd5Password), + /// The frontend must initiate GSSAPI negotiation + Gss, + + /// GSSAPI token reponse for continuing the security context + GssContinue(AuthenticationGss), + /// The frontend must now initiate a SASL negotiation, /// using one of the SASL mechanisms listed in the message. /// @@ -75,6 +81,8 @@ impl BackendMessage for Authentication { Authentication::Md5Password(AuthenticationMd5Password { salt }) } + 7 => Authentication::Gss, + 8 => Authentication::GssContinue(AuthenticationGss { token: buf }), 10 => Authentication::Sasl(AuthenticationSasl(buf)), 11 => Authentication::SaslContinue(AuthenticationSaslContinue::decode(buf)?), @@ -191,3 +199,8 @@ impl ProtocolDecode<'_> for AuthenticationSaslFinal { Ok(Self { verifier }) } } + +#[derive(Debug)] +pub struct AuthenticationGss { + pub token: Bytes, +} diff --git a/sqlx-postgres/src/message/gssapi.rs b/sqlx-postgres/src/message/gssapi.rs new file mode 100644 index 0000000000..6076c6b928 --- /dev/null +++ b/sqlx-postgres/src/message/gssapi.rs @@ -0,0 +1,20 @@ +use crate::message::{FrontendMessage, FrontendMessageFormat}; + +pub struct GssResponse<'g> { + pub(crate) token: &'g [u8], +} +impl<'g> FrontendMessage for GssResponse<'g> { + const FORMAT: FrontendMessageFormat = FrontendMessageFormat::PasswordPolymorphic; + + fn body_size_hint(&self) -> std::num::Saturating { + let mut size = std::num::Saturating(0); + size += 4; + size += self.token.len(); + size + } + + fn encode_body(&self, buf: &mut Vec) -> Result<(), sqlx_core::Error> { + buf.extend_from_slice(&self.token); + Ok(()) + } +} diff --git a/sqlx-postgres/src/message/mod.rs b/sqlx-postgres/src/message/mod.rs index e62f9bebb3..5aaab1efa8 100644 --- a/sqlx-postgres/src/message/mod.rs +++ b/sqlx-postgres/src/message/mod.rs @@ -14,6 +14,7 @@ mod data_row; mod describe; mod execute; mod flush; +mod gssapi; mod notification; mod parameter_description; mod parameter_status; @@ -30,7 +31,7 @@ mod startup; mod sync; mod terminate; -pub use authentication::{Authentication, AuthenticationSasl}; +pub use authentication::{Authentication, AuthenticationGss, AuthenticationSasl}; pub use backend_key_data::BackendKeyData; pub use bind::Bind; pub use close::Close; @@ -41,6 +42,7 @@ pub use describe::Describe; pub use execute::Execute; #[allow(unused_imports)] pub use flush::Flush; +pub use gssapi::GssResponse; pub use notification::Notification; pub use parameter_description::ParameterDescription; pub use parameter_status::ParameterStatus; diff --git a/sqlx-postgres/src/options/mod.rs b/sqlx-postgres/src/options/mod.rs index efbc43989b..de616e1b4d 100644 --- a/sqlx-postgres/src/options/mod.rs +++ b/sqlx-postgres/src/options/mod.rs @@ -21,6 +21,7 @@ pub struct PgConnectOptions { pub(crate) username: String, pub(crate) password: Option, pub(crate) database: Option, + pub(crate) gssapi_target_principal: Option, pub(crate) ssl_mode: PgSslMode, pub(crate) ssl_root_cert: Option, pub(crate) ssl_client_cert: Option, @@ -75,6 +76,7 @@ impl PgConnectOptions { username, password: var("PGPASSWORD").ok(), database, + gssapi_target_principal: var("PGPRINCIPAL").ok(), ssl_root_cert: var("PGSSLROOTCERT").ok().map(CertificateInput::from), ssl_client_cert: var("PGSSLCERT").ok().map(CertificateInput::from), // As of writing, the implementation of `From` only looks for @@ -336,6 +338,12 @@ impl PgConnectOptions { self } + /// Sets the targeted principal in case of attempted Kerberos negotiation + /// If left out and Kerberos is challenged, uses 'postgres/' + pub fn gssapi_target_principal(mut self, target_principal: &str) -> Self { + self.gssapi_target_principal = Some(target_principal.to_owned()); + self + } /// Sets the capacity of the connection's statement cache in a number of stored /// distinct statements. Caching is handled using LRU, meaning when the /// amount of queries hits the defined limit, the oldest statement will get From 83e26150726eb827dbf10541cfaaed97db411952 Mon Sep 17 00:00:00 2001 From: Niclas Klugmann Date: Tue, 16 Sep 2025 13:37:33 +0200 Subject: [PATCH 3/3] fix lockfile --- Cargo.lock | 90 ++++++++++++------------------------------------------ 1 file changed, 20 insertions(+), 70 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4f402784ab..0ba2a3bd78 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -567,7 +567,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.1", "cexpr", "clang-sys", "itertools 0.13.0", @@ -578,7 +578,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.96", + "syn 2.0.104", ] [[package]] @@ -1085,7 +1085,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d4ddf7139e64dc916b11d434421031bcc5ba02e521a49a011652a0f68775188" dependencies = [ "anyhow", - "bitflags 2.7.0", + "bitflags 2.9.1", "bytes", "libgssapi", "windows", @@ -1813,7 +1813,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core", ] [[package]] @@ -2143,7 +2143,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "834339e86b2561169d45d3b01741967fee3e5716c7d0b6e33cd4e3b34c9558cd" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.1", "bytes", "lazy_static", "libgssapi-sys", @@ -4925,7 +4925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", - "windows-core 0.61.2", + "windows-core", "windows-future", "windows-link", "windows-numerics", @@ -4937,66 +4937,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core 0.61.2", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "windows-interface" -version = "0.59.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.104", -] - -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link", + "windows-core", ] [[package]] @@ -5018,7 +4959,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core 0.61.2", + "windows-core", "windows-link", "windows-threading", ] @@ -5031,7 +4972,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.104", ] [[package]] @@ -5042,7 +4983,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.104", ] [[package]] @@ -5057,7 +4998,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core 0.61.2", + "windows-core", "windows-link", ] @@ -5162,6 +5103,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5"