diff --git a/CHANGELOG.md b/CHANGELOG.md index 93eb8c4569..00ebd4a643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 0.6.28 + +- Add sqlx version information to pre-login message in mssql +- Add support for encrypted Microsoft SQL server connections (using TLS) +- Add support for the `SSLKEYLOGFILE` environment variable for TLS decryption in Wireshark + ## 0.6.27 - Fix pg i8 decode diff --git a/Cargo.lock b/Cargo.lock index bd24b7aaa1..ca6ba38522 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" @@ -125,9 +125,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "argon2" @@ -142,9 +142,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "async-attributes" @@ -181,14 +181,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7ebdfa2ebdab6b1760375fa7d6f382b9f486eac35fc994625a00e89280bdbb7" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ "async-task", "concurrent-queue", - "fastrand 2.1.0", - "futures-lite 2.3.0", + "fastrand", + "futures-lite", "slab", ] @@ -200,61 +200,32 @@ checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ "async-channel 2.3.1", "async-executor", - "async-io 2.3.4", - "async-lock 3.4.0", + "async-io", + "async-lock", "blocking", - "futures-lite 2.3.0", + "futures-lite", "once_cell", ] -[[package]] -name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite 1.13.0", - "log", - "parking", - "polling 2.8.0", - "rustix 0.37.27", - "slab", - "socket2 0.4.10", - "waker-fn", -] - [[package]] name = "async-io" version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" dependencies = [ - "async-lock 3.4.0", + "async-lock", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.3.0", + "futures-lite", "parking", - "polling 3.7.3", - "rustix 0.38.34", + "polling", + "rustix", "slab", "tracing", "windows-sys 0.59.0", ] -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", -] - [[package]] name = "async-lock" version = "3.4.0" @@ -280,19 +251,21 @@ dependencies = [ [[package]] name = "async-process" -version = "1.8.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", + "async-channel 2.3.1", + "async-io", + "async-lock", "async-signal", + "async-task", "blocking", "cfg-if", - "event-listener 3.1.0", - "futures-lite 1.13.0", - "rustix 0.38.34", - "windows-sys 0.48.0", + "event-listener 5.3.1", + "futures-lite", + "rustix", + "tracing", ] [[package]] @@ -301,13 +274,13 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "async-io 2.3.4", - "async-lock 3.4.0", + "async-io", + "async-lock", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.34", + "rustix", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -315,21 +288,21 @@ dependencies = [ [[package]] name = "async-std" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" dependencies = [ "async-attributes", "async-channel 1.9.0", "async-global-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io", + "async-lock", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 1.13.0", + "futures-lite", "gloo-timers", "kv-log-macro", "log", @@ -349,13 +322,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -386,9 +359,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" @@ -466,17 +439,17 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -570,7 +543,7 @@ dependencies = [ "async-channel 2.3.1", "async-task", "futures-io", - "futures-lite 2.3.0", + "futures-lite", "piper", ] @@ -594,7 +567,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "syn_derive", ] @@ -644,15 +617,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "camino" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3054fea8a20d8ff3968d5b22cc27501d2b08dc4decdb31b184323f00c5ef23bb" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] @@ -687,9 +660,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.13" +version = "1.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" dependencies = [ "jobserver", "libc", @@ -846,9 +819,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -990,7 +963,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1001,7 +974,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1216,18 +1189,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fd-lock" @@ -1236,7 +1200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" dependencies = [ "cfg-if", - "rustix 0.38.34", + "rustix", "windows-sys 0.48.0", ] @@ -1252,9 +1216,9 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -1389,28 +1353,13 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-lite" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" dependencies = [ - "fastrand 2.1.0", + "fastrand", "futures-core", "futures-io", "parking", @@ -1425,7 +1374,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1492,9 +1441,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "git2" @@ -1517,9 +1466,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "gloo-timers" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ "futures-channel", "futures-core", @@ -1551,6 +1500,12 @@ dependencies = [ "ahash 0.8.11", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + [[package]] name = "hashlink" version = "0.9.1" @@ -1656,9 +1611,9 @@ checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -1688,7 +1643,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "socket2", "tokio", "tower-service", "tracing", @@ -1697,9 +1652,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1763,12 +1718,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", ] [[package]] @@ -1780,17 +1735,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnetwork" version = "0.20.0" @@ -1870,9 +1814,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.156" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libgit2-sys" @@ -1900,7 +1844,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", - "redox_syscall 0.5.3", + "redox_syscall", ] [[package]] @@ -1917,9 +1861,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.19" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" dependencies = [ "cc", "libc", @@ -1927,12 +1871,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -2022,11 +1960,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -2211,18 +2149,21 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] [[package]] name = "oorandom" @@ -2253,7 +2194,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -2264,9 +2205,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.3.1+3.3.1" +version = "300.3.2+3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" +checksum = "a211a18d945ef7e648cc6e0058f4c548ee46aab922ea203e0d30e966ea23647b" dependencies = [ "cc", ] @@ -2298,9 +2239,9 @@ checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -2320,7 +2261,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -2374,7 +2315,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -2396,7 +2337,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.1.0", + "fastrand", "futures-io", ] @@ -2423,15 +2364,15 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "plotters" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15b6eccb8484002195a3e44fe65a4ce8e93a625797a063735536fd59cb01cf3" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -2442,35 +2383,19 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "414cec62c6634ae900ea1c56128dfe87cf63e7caece0852ec76aba307cebadb7" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b30686a7d9c3e010b84284bdd26a29f2138574f52f5eb6f794fc0ad924e705" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys 0.48.0", -] - [[package]] name = "polling" version = "3.7.3" @@ -2481,11 +2406,17 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix 0.38.34", + "rustix", "tracing", "windows-sys 0.59.0", ] +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + [[package]] name = "powerfmt" version = "0.2.0" @@ -2533,11 +2464,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] @@ -2604,9 +2535,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -2725,27 +2656,18 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", @@ -2754,9 +2676,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", @@ -2766,9 +2688,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", @@ -2777,9 +2699,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "remove_dir_all" @@ -2829,9 +2751,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", @@ -2847,9 +2769,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.44" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ "proc-macro2", "quote", @@ -2878,9 +2800,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" dependencies = [ "arrayvec", "borsh", @@ -2900,28 +2822,14 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.37.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - -[[package]] -name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", "libc", - "linux-raw-sys 0.4.14", + "linux-raw-sys", "windows-sys 0.52.0", ] @@ -2941,25 +2849,24 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -3007,11 +2914,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3041,9 +2948,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -3060,9 +2967,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -3079,20 +2986,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -3102,9 +3009,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -3146,7 +3053,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3198,9 +3105,9 @@ dependencies = [ [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" [[package]] name = "slab" @@ -3217,16 +3124,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.7" @@ -3258,9 +3155,9 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" +checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790" dependencies = [ "nom", "unicode_categories", @@ -3280,7 +3177,7 @@ dependencies = [ [[package]] name = "sqlx-cli" -version = "0.6.27" +version = "0.6.28" dependencies = [ "anyhow", "async-trait", @@ -3305,7 +3202,7 @@ dependencies = [ [[package]] name = "sqlx-core-oldapi" -version = "0.6.27" +version = "0.6.28" dependencies = [ "ahash 0.8.11", "atoi", @@ -3336,7 +3233,7 @@ dependencies = [ "hex", "hkdf", "hmac", - "indexmap 2.4.0", + "indexmap 2.6.0", "ipnetwork", "itoa", "libc", @@ -3368,6 +3265,7 @@ dependencies = [ "time", "tokio", "tokio-stream", + "tokio-util", "url", "uuid", "webpki-roots", @@ -3466,7 +3364,7 @@ dependencies = [ [[package]] name = "sqlx-macros-oldapi" -version = "0.6.27" +version = "0.6.28" dependencies = [ "dotenvy", "either", @@ -3486,7 +3384,7 @@ dependencies = [ [[package]] name = "sqlx-oldapi" -version = "0.6.27" +version = "0.6.28" dependencies = [ "anyhow", "async-std", @@ -3513,7 +3411,7 @@ dependencies = [ [[package]] name = "sqlx-rt-oldapi" -version = "0.6.27" +version = "0.6.28" dependencies = [ "async-native-tls", "async-std", @@ -3615,9 +3513,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -3633,7 +3531,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3660,14 +3558,14 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if", - "fastrand 2.1.0", + "fastrand", "once_cell", - "rustix 0.38.34", + "rustix", "windows-sys 0.59.0", ] @@ -3703,22 +3601,22 @@ checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3779,9 +3677,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.2" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -3790,7 +3688,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2", "tokio-macros", "windows-sys 0.52.0", ] @@ -3803,7 +3701,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3829,11 +3727,25 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ + "bytes", "futures-core", + "futures-io", + "futures-sink", "pin-project-lite", "tokio", ] @@ -3847,7 +3759,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.20", + "toml_edit", ] [[package]] @@ -3861,26 +3773,15 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap 2.4.0", - "toml_datetime", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.4.0", + "indexmap 2.6.0", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.18", + "winnow", ] [[package]] @@ -3950,7 +3851,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3990,42 +3891,42 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.15" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-properties" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode_categories" @@ -4131,12 +4032,6 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" -[[package]] -name = "waker-fn" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" - [[package]] name = "walkdir" version = "2.5.0" @@ -4190,7 +4085,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "wasm-bindgen-shared", ] @@ -4224,7 +4119,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4247,20 +4142,20 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.3" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" dependencies = [ "rustls-pki-types", ] [[package]] name = "whoami" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "redox_syscall 0.4.1", + "redox_syscall", "wasite", "web-sys", ] @@ -4455,18 +4350,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -4498,7 +4384,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index e4fc593690..828cc66aa9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ members = [ [package] name = "sqlx-oldapi" -version = "0.6.27" +version = "0.6.28" license = "MIT OR Apache-2.0" readme = "README.md" repository = "https://github.com/lovasoa/sqlx" @@ -125,8 +125,8 @@ bstr = ["sqlx-core/bstr"] git2 = ["sqlx-core/git2"] [dependencies] -sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.27", path = "sqlx-core", default-features = false } -sqlx-macros = { package = "sqlx-macros-oldapi", version = "0.6.27", path = "sqlx-macros", default-features = false, optional = true } +sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.28", path = "sqlx-core", default-features = false } +sqlx-macros = { package = "sqlx-macros-oldapi", version = "0.6.28", path = "sqlx-macros", default-features = false, optional = true } [dev-dependencies] anyhow = "1.0.52" diff --git a/examples/postgres/axum-social-with-tests/Cargo.toml b/examples/postgres/axum-social-with-tests/Cargo.toml index 7be73eeb3a..55567d2fb2 100644 --- a/examples/postgres/axum-social-with-tests/Cargo.toml +++ b/examples/postgres/axum-social-with-tests/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] # Primary crates axum = { version = "0.5.13", features = ["macros"] } -sqlx = { package = "sqlx-oldapi", version = "0.6.27", path = "../../../", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] } +sqlx = { package = "sqlx-oldapi", version = "0.6.28", path = "../../../", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] } tokio = { version = "1.20.1", features = ["rt-multi-thread", "macros"] } # Important secondary crates diff --git a/sqlx-cli/Cargo.toml b/sqlx-cli/Cargo.toml index 115670b04b..dc38a98fd4 100644 --- a/sqlx-cli/Cargo.toml +++ b/sqlx-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sqlx-cli" -version = "0.6.27" +version = "0.6.28" description = "Command-line utility for SQLx, the Rust SQL toolkit." edition = "2021" readme = "README.md" diff --git a/sqlx-core/Cargo.toml b/sqlx-core/Cargo.toml index 06fba08178..b672153bfd 100644 --- a/sqlx-core/Cargo.toml +++ b/sqlx-core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sqlx-core-oldapi" -version = "0.6.27" +version = "0.6.28" repository = "https://github.com/lovasoa/sqlx" description = "Core of SQLx, the rust SQL toolkit. Not intended to be used directly." license = "MIT OR Apache-2.0" @@ -90,7 +90,7 @@ runtime-tokio-rustls = [ # for conditional compilation _rt-async-std = [] -_rt-tokio = ["tokio-stream"] +_rt-tokio = ["tokio-stream", "tokio-util"] _tls-native-tls = [] _tls-rustls = ["rustls", "rustls-pemfile", "webpki-roots"] @@ -101,7 +101,7 @@ offline = ["serde", "either/serde"] paste = "1.0.6" ahash = "0.8.3" atoi = "2.0.0" -sqlx-rt = { path = "../sqlx-rt", version = "0.6.27", package = "sqlx-rt-oldapi" } +sqlx-rt = { path = "../sqlx-rt", version = "0.6.28", package = "sqlx-rt-oldapi" } base64 = { version = "0.22", default-features = false, optional = true, features = ["std"] } bigdecimal_ = { version = "0.4.1", optional = true, package = "bigdecimal" } rust_decimal = { version = "1.19.0", optional = true } @@ -119,7 +119,7 @@ either = "1.6.1" futures-channel = { version = "0.3.19", default-features = false, features = ["sink", "alloc", "std"] } futures-core = { version = "0.3.19", default-features = false } futures-intrusive = "0.5.0" -futures-util = { version = "0.3.19", default-features = false, features = ["alloc", "sink"] } +futures-util = { version = "0.3.19", default-features = false, features = ["alloc", "sink", "io"] } # used by the SQLite worker thread to block on the async mutex that locks the database handle futures-executor = { version = "0.3.19", optional = true } flume = { version = "0.11.0", optional = true, default-features = false, features = ["async"] } @@ -154,6 +154,7 @@ sqlformat = "0.2.0" thiserror = "1.0.30" time = { version = "0.3.2", features = ["macros", "formatting", "parsing"], optional = true } tokio-stream = { version = "0.1.8", features = ["fs"], optional = true } +tokio-util = { version = "0.7.0", features = ["compat"], default-features = false, optional = true } smallvec = "1.7.0" url = { version = "2.2.2", default-features = false } uuid = { version = "1.0", default-features = false, optional = true, features = ["std"] } diff --git a/sqlx-core/src/mssql/connection/establish.rs b/sqlx-core/src/mssql/connection/establish.rs index bbab710f12..e3dca05ded 100644 --- a/sqlx-core/src/mssql/connection/establish.rs +++ b/sqlx-core/src/mssql/connection/establish.rs @@ -18,45 +18,62 @@ impl MssqlConnection { // TODO: Encryption // TODO: Send the version of SQLx over - stream.write_packet( - PacketType::PreLogin, - PreLogin { - version: Version::default(), - encryption: Encrypt::NOT_SUPPORTED, - instance: options.instance.clone(), - - ..Default::default() - }, + log::debug!( + "Sending T-SQL PRELOGIN with encryption: {:?}", + options.encrypt ); - stream.flush().await?; + stream + .write_packet_and_flush( + PacketType::PreLogin, + PreLogin { + version: Version::default(), + encryption: options.encrypt, + instance: options.instance.clone(), + + ..Default::default() + }, + ) + .await?; let (_, packet) = stream.recv_packet().await?; - let _ = PreLogin::decode(packet)?; + let prelogin_response = PreLogin::decode(packet)?; + + if matches!( + prelogin_response.encryption, + Encrypt::Required | Encrypt::On + ) { + stream.setup_encryption().await?; + } else if options.encrypt == Encrypt::Required { + return Err(Error::Tls(Box::new(std::io::Error::new( + std::io::ErrorKind::Other, + "TLS encryption required but not supported by server", + )))); + } // LOGIN7 defines the authentication rules for use between client and server - stream.write_packet( - PacketType::Tds7Login, - Login7 { - // FIXME: use a version constant - version: 0x74000004, // SQL Server 2012 - SQL Server 2019 - client_program_version: options.client_program_version, - client_pid: options.client_pid, - packet_size: options.requested_packet_size, // max allowed size of TDS packet - hostname: &options.hostname, - username: &options.username, - password: options.password.as_deref().unwrap_or_default(), - app_name: &options.app_name, - server_name: &options.server_name, - client_interface_name: &options.client_interface_name, - language: &options.language, - database: &*options.database, - client_id: [0; 6], - }, - ); - - stream.flush().await?; + stream + .write_packet_and_flush( + PacketType::Tds7Login, + Login7 { + // FIXME: use a version constant + version: 0x74000004, // SQL Server 2012 - SQL Server 2019 + client_program_version: options.client_program_version, + client_pid: options.client_pid, + packet_size: options.requested_packet_size, // max allowed size of TDS packet + hostname: &options.hostname, + username: &options.username, + password: options.password.as_deref().unwrap_or_default(), + app_name: &options.app_name, + server_name: &options.server_name, + client_interface_name: &options.client_interface_name, + language: &options.language, + database: &*options.database, + client_id: [0; 6], + }, + ) + .await?; loop { // NOTE: we should receive an [Error] message if something goes wrong, otherwise, diff --git a/sqlx-core/src/mssql/connection/executor.rs b/sqlx-core/src/mssql/connection/executor.rs index 0c8a2f064d..25e1480d05 100644 --- a/sqlx-core/src/mssql/connection/executor.rs +++ b/sqlx-core/src/mssql/connection/executor.rs @@ -41,27 +41,29 @@ impl MssqlConnection { proc_args.append(&mut arguments); } - self.stream.write_packet( - PacketType::Rpc, - RpcRequest { - transaction_descriptor: self.stream.transaction_descriptor, - arguments: &proc_args, - procedure: proc, - options: OptionFlags::empty(), - }, - ); + self.stream + .write_packet_and_flush( + PacketType::Rpc, + RpcRequest { + transaction_descriptor: self.stream.transaction_descriptor, + arguments: &proc_args, + procedure: proc, + options: OptionFlags::empty(), + }, + ) + .await?; } else { - self.stream.write_packet( - PacketType::SqlBatch, - SqlBatch { - transaction_descriptor: self.stream.transaction_descriptor, - sql: query, - }, - ); + self.stream + .write_packet_and_flush( + PacketType::SqlBatch, + SqlBatch { + transaction_descriptor: self.stream.transaction_descriptor, + sql: query, + }, + ) + .await?; } - self.stream.flush().await?; - Ok(()) } } diff --git a/sqlx-core/src/mssql/connection/mod.rs b/sqlx-core/src/mssql/connection/mod.rs index 8585f7cf99..f21ecb6b0a 100644 --- a/sqlx-core/src/mssql/connection/mod.rs +++ b/sqlx-core/src/mssql/connection/mod.rs @@ -15,6 +15,7 @@ mod establish; mod executor; mod prepare; mod stream; +mod tls_prelogin_stream_wrapper; pub struct MssqlConnection { pub(crate) stream: MssqlStream, @@ -28,6 +29,8 @@ impl Debug for MssqlConnection { } } +use std::ops::DerefMut; + impl Connection for MssqlConnection { type Database = Mssql; diff --git a/sqlx-core/src/mssql/connection/prepare.rs b/sqlx-core/src/mssql/connection/prepare.rs index ef96dadc5f..50d33983dd 100644 --- a/sqlx-core/src/mssql/connection/prepare.rs +++ b/sqlx-core/src/mssql/connection/prepare.rs @@ -52,21 +52,22 @@ pub(crate) async fn prepare( args.add_unnamed(sql); args.add_unnamed(0x0001_i32); // 1 = SEND_METADATA - conn.stream.write_packet( - PacketType::Rpc, - RpcRequest { - transaction_descriptor: conn.stream.transaction_descriptor, - arguments: &args, - // [sp_prepare] will emit the column meta data - // small issue is that we need to declare all the used placeholders with a "fallback" type - // we currently use regex to collect them; false positives are *okay* but false - // negatives would break the query - procedure: Either::Right(Procedure::Prepare), - options: OptionFlags::empty(), - }, - ); - - conn.stream.flush().await?; + conn.stream + .write_packet_and_flush( + PacketType::Rpc, + RpcRequest { + transaction_descriptor: conn.stream.transaction_descriptor, + arguments: &args, + // [sp_prepare] will emit the column meta data + // small issue is that we need to declare all the used placeholders with a "fallback" type + // we currently use regex to collect them; false positives are *okay* but false + // negatives would break the query + procedure: Either::Right(Procedure::Prepare), + options: OptionFlags::empty(), + }, + ) + .await?; + conn.stream.wait_until_ready().await?; conn.stream.pending_done_count += 1; @@ -100,17 +101,18 @@ pub(crate) async fn prepare( let mut args = MssqlArguments::default(); args.add_unnamed(id); - conn.stream.write_packet( - PacketType::Rpc, - RpcRequest { - transaction_descriptor: conn.stream.transaction_descriptor, - arguments: &args, - procedure: Either::Right(Procedure::Unprepare), - options: OptionFlags::empty(), - }, - ); + conn.stream + .write_packet_and_flush( + PacketType::Rpc, + RpcRequest { + transaction_descriptor: conn.stream.transaction_descriptor, + arguments: &args, + procedure: Either::Right(Procedure::Unprepare), + options: OptionFlags::empty(), + }, + ) + .await?; - conn.stream.flush().await?; conn.stream.wait_until_ready().await?; conn.stream.pending_done_count += 1; diff --git a/sqlx-core/src/mssql/connection/stream.rs b/sqlx-core/src/mssql/connection/stream.rs index e8bfe70fc2..0a830fd4b8 100644 --- a/sqlx-core/src/mssql/connection/stream.rs +++ b/sqlx-core/src/mssql/connection/stream.rs @@ -1,11 +1,12 @@ use std::ops::{Deref, DerefMut}; use bytes::{Bytes, BytesMut}; -use sqlx_rt::TcpStream; +use sqlx_rt::{AsyncWriteExt, TcpStream}; use crate::error::Error; use crate::ext::ustr::UStr; use crate::io::{BufStream, Encode}; +use crate::mssql::connection::tls_prelogin_stream_wrapper::TlsPreloginWrapper; use crate::mssql::protocol::col_meta_data::ColMetaData; use crate::mssql::protocol::done::{Done, Status as DoneStatus}; use crate::mssql::protocol::env_change::EnvChange; @@ -19,12 +20,12 @@ use crate::mssql::protocol::return_status::ReturnStatus; use crate::mssql::protocol::return_value::ReturnValue; use crate::mssql::protocol::row::Row; use crate::mssql::{MssqlColumn, MssqlConnectOptions, MssqlDatabaseError}; -use crate::net::MaybeTlsStream; +use crate::net::{MaybeTlsStream, TlsConfig}; use crate::HashMap; use std::sync::Arc; pub(crate) struct MssqlStream { - inner: BufStream>, + inner: BufStream>>, // how many Done (or Error) we are currently waiting for pub(crate) pending_done_count: usize, @@ -44,13 +45,15 @@ pub(crate) struct MssqlStream { // Maximum size of packets to send to the server pub(crate) max_packet_size: usize, + + options: MssqlConnectOptions, } impl MssqlStream { pub(super) async fn connect(options: &MssqlConnectOptions) -> Result { - let inner = BufStream::new(MaybeTlsStream::Raw( - TcpStream::connect((&*options.host, options.port)).await?, - )); + let tcp_stream = TcpStream::connect((&*options.host, options.port)).await?; + let wrapped_stream = TlsPreloginWrapper::new(tcp_stream); + let inner = BufStream::new(MaybeTlsStream::Raw(wrapped_stream)); Ok(Self { inner, @@ -64,14 +67,46 @@ impl MssqlStream { .requested_packet_size .try_into() .unwrap_or(usize::MAX), + options: options.clone(), }) } - // writes the packet out to the write buffer + // writes the packet out to the write buffer, but does not flush + // WARNING: if the packet is large, and we are over an encrypted connection, this will fail, since we would + // need to flush each packet individually to the encryption layer pub(crate) fn write_packet<'en, T: Encode<'en>>(&mut self, ty: PacketType, payload: T) { write_packets(&mut self.inner.wbuf, self.max_packet_size, ty, payload) } + // writes the packet out to the write buffer, splitting it if neccessary, and flushing TDS packets one at a time + pub(crate) async fn write_packet_and_flush<'en, T: Encode<'en>>( + &mut self, + ty: PacketType, + payload: T, + ) -> Result<(), Error> { + if !self.inner.wbuf.is_empty() { + self.flush().await?; + } + self.write_packet(ty, payload); + self.flush().await?; + Ok(()) + } + + // writes the packet out to the write buffer, splitting it if neccessary, and flushing TDS packets one at a time + pub(crate) async fn flush(&mut self) -> Result<(), Error> { + // flush self.max_packet_size bytes at a time + if self.inner.wbuf.len() > self.max_packet_size { + for chunk in self.inner.wbuf.chunks(self.max_packet_size) { + self.inner.stream.write_all(chunk).await?; + self.inner.stream.flush().await?; + } + self.inner.wbuf.clear(); + } else { + self.inner.flush().await?; + } + Ok(()) + } + // receive the next packet from the database // blocks until a packet is available pub(super) async fn recv_packet(&mut self) -> Result<(PacketHeader, Bytes), Error> { @@ -206,10 +241,29 @@ impl MssqlStream { Ok(()) } + + pub(crate) async fn setup_encryption(&mut self) -> Result<(), Error> { + let tls_config = TlsConfig { + accept_invalid_certs: self.options.trust_server_certificate, + hostname: self + .options + .hostname_in_certificate + .as_deref() + .unwrap_or(&self.options.host), + accept_invalid_hostnames: self.options.hostname_in_certificate.is_none(), + root_cert_path: self.options.ssl_root_cert.as_ref(), + client_cert_path: None, + client_key_path: None, + }; + self.inner.deref_mut().start_handshake(); + self.inner.upgrade(tls_config).await?; + self.inner.deref_mut().handshake_complete(); + Ok(()) + } } // writes the packet out to the write buffer -fn write_packets<'en, T: Encode<'en>>( +pub(crate) fn write_packets<'en, T: Encode<'en>>( buffer: &mut Vec, max_packet_size: usize, ty: PacketType, @@ -313,7 +367,7 @@ fn test_write_packets() { } impl Deref for MssqlStream { - type Target = BufStream>; + type Target = BufStream>>; fn deref(&self) -> &Self::Target { &self.inner diff --git a/sqlx-core/src/mssql/connection/tls_prelogin_stream_wrapper.rs b/sqlx-core/src/mssql/connection/tls_prelogin_stream_wrapper.rs new file mode 100644 index 0000000000..04f52e2802 --- /dev/null +++ b/sqlx-core/src/mssql/connection/tls_prelogin_stream_wrapper.rs @@ -0,0 +1,263 @@ +// Original implementation from tiberius: https://github.com/prisma/tiberius/blob/main/src/client/tls.rs + +use crate::mssql::protocol::packet::{PacketHeader, PacketType}; + +use super::stream::write_packets; + +use crate::io::Decode; +use bytes::Bytes; +use sqlx_rt::{AsyncRead, AsyncWrite}; + +#[cfg(feature = "_rt-tokio")] +use sqlx_rt::ReadBuf; + +use std::cmp; +use std::io; +use std::pin::Pin; +use std::task::{self, ready, Poll}; + +/// This wrapper handles TDS (Tabular Data Stream) packet encapsulation during the TLS handshake phase +/// of a connection to a Microsoft SQL Server. +/// +/// In the PRELOGIN phase of the TDS protocol, all communication must be wrapped in TDS packets, +/// even during TLS negotiation. This presents a challenge when using standard TLS libraries, +/// which expect to work with raw TCP streams. +/// +/// This wrapper solves the problem by: +/// 1. During handshake: +/// - For writes: It buffers outgoing data and wraps it in TDS packets before sending. +/// Each packet starts with an 8-byte header containing type (0x12 for PRELOGIN), +/// status flags, length, and other metadata. +/// - For reads: It strips the TDS packet headers from incoming data before passing +/// it to the TLS library. +/// 2. After handshake: +/// - It becomes transparent, directly passing through all reads and writes to the +/// underlying stream without modification. +/// +/// This allows us to use standard TLS libraries while still conforming to the TDS protocol +/// requirements for the PRELOGIN phase. + +const HEADER_BYTES: usize = 8; + +pub(crate) struct TlsPreloginWrapper { + stream: S, + pending_handshake: bool, + + header_buf: [u8; HEADER_BYTES], + header_pos: usize, + read_remaining: usize, + + wr_buf: Vec, + header_written: bool, +} + +impl TlsPreloginWrapper { + pub fn new(stream: S) -> Self { + TlsPreloginWrapper { + stream, + pending_handshake: false, + + header_buf: [0u8; HEADER_BYTES], + header_pos: 0, + read_remaining: 0, + wr_buf: Vec::new(), + header_written: false, + } + } + + pub fn start_handshake(&mut self) { + log::trace!("Handshake starting"); + self.pending_handshake = true; + } + + pub fn handshake_complete(&mut self) { + log::trace!("Handshake complete"); + self.pending_handshake = false; + } +} + +#[cfg(feature = "_rt-async-std")] +type PollReadOut = usize; + +#[cfg(feature = "_rt-tokio")] +type PollReadOut = (); + +impl AsyncRead for TlsPreloginWrapper { + #[cfg(feature = "_rt-tokio")] + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut task::Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + if !self.pending_handshake { + return Pin::new(&mut self.stream).poll_read(cx, buf); + } + + let inner = self.get_mut(); + + if !inner.header_buf[inner.header_pos..].is_empty() { + while !inner.header_buf[inner.header_pos..].is_empty() { + let mut header_buf = ReadBuf::new(&mut inner.header_buf[inner.header_pos..]); + ready!(Pin::new(&mut inner.stream).poll_read(cx, &mut header_buf))?; + + let read = header_buf.filled().len(); + if read == 0 { + return Poll::Ready(Ok(PollReadOut::default())); + } + + inner.header_pos += read; + } + + let header: PacketHeader = Decode::decode(Bytes::copy_from_slice(&inner.header_buf)) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; + + inner.read_remaining = usize::from(header.length) - HEADER_BYTES; + + log::trace!( + "Discarding header ({:?}), reading packet of {} bytes", + header, + inner.read_remaining, + ); + } + + let max_read = std::cmp::min(inner.read_remaining, buf.remaining()); + let mut limited_buf = buf.take(max_read); + + let res = ready!(Pin::new(&mut inner.stream).poll_read(cx, &mut limited_buf))?; + + let read = limited_buf.filled().len(); + buf.advance(read); + inner.read_remaining -= read; + + if inner.read_remaining == 0 { + inner.header_pos = 0; + } + + Poll::Ready(Ok(res)) + } + + #[cfg(feature = "_rt-async-std")] + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut task::Context<'_>, + buf: &mut [u8], + ) -> Poll> { + if !self.pending_handshake { + return Pin::new(&mut self.stream).poll_read(cx, buf); + } + + let inner = self.get_mut(); + + if !inner.header_buf[inner.header_pos..].is_empty() { + while !inner.header_buf[inner.header_pos..].is_empty() { + let header_buf = &mut inner.header_buf[inner.header_pos..]; + let read = ready!(Pin::new(&mut inner.stream).poll_read(cx, header_buf))?; + + if read == 0 { + return Poll::Ready(Ok(PollReadOut::default())); + } + + inner.header_pos += read; + } + + let header: PacketHeader = Decode::decode(Bytes::copy_from_slice(&inner.header_buf)) + .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; + + inner.read_remaining = usize::from(header.length) - HEADER_BYTES; + + log::trace!( + "Discarding header ({:?}), reading packet of {} bytes", + header, + inner.read_remaining, + ); + } + + let max_read = std::cmp::min(inner.read_remaining, buf.len()); + let limited_buf = &mut buf[..max_read]; + + let read = ready!(Pin::new(&mut inner.stream).poll_read(cx, limited_buf))?; + + inner.read_remaining -= read; + + if inner.read_remaining == 0 { + inner.header_pos = 0; + } + + Poll::Ready(Ok(read)) + } +} + +impl AsyncWrite for TlsPreloginWrapper { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut task::Context<'_>, + buf: &[u8], + ) -> Poll> { + // Normal operation does not need any extra treatment, we handle + // packets in the codec. + if !self.pending_handshake { + return Pin::new(&mut self.stream).poll_write(cx, buf); + } + + // Buffering data. + self.wr_buf.extend_from_slice(buf); + + Poll::Ready(Ok(buf.len())) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll> { + let inner = self.get_mut(); + + // If on handshake mode, wraps the data to a TDS packet before sending. + if inner.pending_handshake { + if !inner.header_written { + let buf = std::mem::take(&mut inner.wr_buf); + write_packets( + &mut inner.wr_buf, + 4096, + PacketType::PreLogin, + buf.as_slice(), + ); + inner.header_written = true; + } + + while !inner.wr_buf.is_empty() { + log::trace!("Writing {} bytes of TLS handshake", inner.wr_buf.len()); + + let written = ready!(Pin::new(&mut inner.stream).poll_write(cx, &inner.wr_buf))?; + + inner.wr_buf.drain(..written); + } + + inner.header_written = false; + } + + Pin::new(&mut inner.stream).poll_flush(cx) + } + + #[cfg(feature = "_rt-tokio")] + fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll> { + Pin::new(&mut self.stream).poll_shutdown(cx) + } + + #[cfg(feature = "_rt-async-std")] + fn poll_close(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll> { + Pin::new(&mut self.stream).poll_close(cx) + } +} + +use std::ops::{Deref, DerefMut}; + +impl Deref for TlsPreloginWrapper { + type Target = S; + + fn deref(&self) -> &Self::Target { + &self.stream + } +} + +impl DerefMut for TlsPreloginWrapper { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.stream + } +} diff --git a/sqlx-core/src/mssql/options/mod.rs b/sqlx-core/src/mssql/options/mod.rs index a66cd7a0ef..70ebdbbbd3 100644 --- a/sqlx-core/src/mssql/options/mod.rs +++ b/sqlx-core/src/mssql/options/mod.rs @@ -1,4 +1,7 @@ -use crate::connection::LogSettings; +use std::path::Path; + +use super::protocol::pre_login::Encrypt; +use crate::{connection::LogSettings, net::CertificateInput}; mod connect; mod parse; @@ -27,6 +30,10 @@ pub struct MssqlConnectOptions { pub(crate) language: String, /// Size in bytes of TDS packets to exchange with the server pub(crate) requested_packet_size: u32, + pub(crate) encrypt: Encrypt, + pub(crate) trust_server_certificate: bool, + pub(crate) hostname_in_certificate: Option, + pub(crate) ssl_root_cert: Option, } impl Default for MssqlConnectOptions { @@ -48,11 +55,15 @@ impl MssqlConnectOptions { requested_packet_size: 4096, client_program_version: 0, client_pid: 0, - hostname: "".to_string(), - app_name: "".to_string(), - server_name: "".to_string(), - client_interface_name: "".to_string(), - language: "".to_string(), + hostname: String::new(), + app_name: String::new(), + server_name: String::new(), + client_interface_name: String::new(), + language: String::new(), + encrypt: Encrypt::On, + trust_server_certificate: true, + hostname_in_certificate: None, + ssl_root_cert: None, } } @@ -87,12 +98,12 @@ impl MssqlConnectOptions { } pub fn client_program_version(mut self, client_program_version: u32) -> Self { - self.client_program_version = client_program_version.to_owned(); + self.client_program_version = client_program_version; self } pub fn client_pid(mut self, client_pid: u32) -> Self { - self.client_pid = client_pid.to_owned(); + self.client_pid = client_pid; self } @@ -131,4 +142,27 @@ impl MssqlConnectOptions { Ok(self) } } + + pub fn encrypt(mut self, encrypt: Encrypt) -> Self { + self.encrypt = encrypt; + self + } + + pub fn trust_server_certificate(mut self, trust: bool) -> Self { + self.trust_server_certificate = trust; + self + } + + pub fn hostname_in_certificate(mut self, hostname: &str) -> Self { + self.hostname_in_certificate = Some(hostname.to_owned()); + self + } + + /// Sets the name of a file containing SSL certificate authority (CA) certificate(s). + /// If the file exists, the server's certificate will be verified to be signed by + /// one of these authorities. + pub fn ssl_root_cert(mut self, cert: impl AsRef) -> Self { + self.ssl_root_cert = Some(CertificateInput::File(cert.as_ref().to_path_buf())); + self + } } diff --git a/sqlx-core/src/mssql/options/parse.rs b/sqlx-core/src/mssql/options/parse.rs index ec90a2ea6c..fe26fdf8d1 100644 --- a/sqlx-core/src/mssql/options/parse.rs +++ b/sqlx-core/src/mssql/options/parse.rs @@ -1,4 +1,5 @@ use crate::error::Error; +use crate::mssql::protocol::pre_login::Encrypt; use crate::mssql::MssqlConnectOptions; use percent_encoding::percent_decode_str; use std::str::FromStr; @@ -9,9 +10,39 @@ impl FromStr for MssqlConnectOptions { /// Parse a connection string into a set of connection options. /// - /// The connection string is expected to be a valid URL with the following format: + /// The connection string should be a valid URL with the following format: /// ```text - /// mssql://[username[:password]@]host/database[?instance=instance_name&packet_size=packet_size&client_program_version=client_program_version&client_pid=client_pid&hostname=hostname&app_name=app_name&server_name=server_name&client_interface_name=client_interface_name&language=language] + /// mssql://[username[:password]@]host[:port][/database][?param1=value1¶m2=value2...] + /// ``` + /// + /// Components: + /// - `username`: The username for SQL Server authentication. + /// - `password`: The password for SQL Server authentication. + /// - `host`: The hostname or IP address of the SQL Server. + /// - `port`: The port number (default is 1433). + /// - `database`: The name of the database to connect to. + /// + /// Supported query parameters: + /// - `instance`: SQL Server named instance. + /// - `encrypt`: Controls connection encryption: + /// - `strict`: Requires encryption and validates the server certificate. + /// - `mandatory` or `true` or `yes`: Requires encryption but doesn't validate the server certificate. + /// - `optional` or `false` or `no`: Uses encryption if available, falls back to unencrypted. + /// - `sslrootcert` or `ssl-root-cert` or `ssl-ca`: Path to the root certificate for validating the server's SSL certificate. + /// - `trust_server_certificate`: When true, skips validation of the server's SSL certificate. Use with caution as it makes the connection vulnerable to man-in-the-middle attacks. + /// - `hostname_in_certificate`: The hostname expected in the server's SSL certificate. Use this when the server's hostname doesn't match the certificate. + /// - `packet_size`: Size of TDS packets in bytes. Larger sizes can improve performance but consume more memory on the server + /// - `client_program_version`: Version number of the client program, sent to the server for logging purposes. + /// - `client_pid`: Process ID of the client, sent to the server for logging purposes. + /// - `hostname`: Name of the client machine, sent to the server for logging purposes. + /// - `app_name`: Name of the client application, sent to the server for logging purposes. + /// - `server_name`: Name of the server to connect to. Useful when connecting through a proxy or load balancer. + /// - `client_interface_name`: Name of the client interface, sent to the server for logging purposes. + /// - `language`: Sets the language for server messages. Affects date formats and system messages. + /// + /// Example: + /// ```text + /// mssql://user:pass@localhost:1433/mydb?encrypt=strict&app_name=MyApp&packet_size=4096 /// ``` fn from_str(s: &str) -> Result { let url: Url = s.parse().map_err(Error::config)?; @@ -52,6 +83,27 @@ impl FromStr for MssqlConnectOptions { "instance" => { options = options.instance(&*value); } + "encrypt" => { + match value.to_lowercase().as_str() { + "strict" => options = options.encrypt(Encrypt::Required), + "mandatory" | "true" | "yes" => options = options.encrypt(Encrypt::On), + "optional" | "false" | "no" => options = options.encrypt(Encrypt::NotSupported), + _ => return Err(Error::config(MssqlInvalidOption(format!( + "encrypt={} is not a valid value for encrypt. Valid values are: strict, mandatory, optional, true, false, yes, no", + value + )))), + } + } + "sslrootcert" | "ssl-root-cert" | "ssl-ca" => { + options = options.ssl_root_cert(&*value); + } + "trust_server_certificate" => { + let trust = value.parse::().map_err(Error::config)?; + options = options.trust_server_certificate(trust); + } + "hostname_in_certificate" => { + options = options.hostname_in_certificate(&*value); + } "packet_size" => { let size = value.parse().map_err(Error::config)?; options = options.requested_packet_size(size).map_err(|_| { diff --git a/sqlx-core/src/mssql/protocol/packet.rs b/sqlx-core/src/mssql/protocol/packet.rs index 7fc1b8870a..c9f494f13c 100644 --- a/sqlx-core/src/mssql/protocol/packet.rs +++ b/sqlx-core/src/mssql/protocol/packet.rs @@ -27,18 +27,21 @@ pub(crate) struct PacketHeader { pub(crate) packet_id: u8, } +impl PacketHeader { + fn to_array(&self) -> [u8; PACKET_HEADER_SIZE] { + let mut arr = [0u8; PACKET_HEADER_SIZE]; + arr[0] = self.r#type as u8; + arr[1] = self.status.bits(); + arr[2..4].copy_from_slice(&self.length.to_be_bytes()); + arr[4..6].copy_from_slice(&self.server_process_id.to_be_bytes()); + arr[6] = self.packet_id; + arr + } +} + impl<'s> Encode<'s, ()> for PacketHeader { fn encode_with(&self, buf: &mut Vec, _: ()) { - buf.push(self.r#type as u8); - buf.push(self.status.bits()); - - buf.extend(&self.length.to_be_bytes()); - - buf.extend(&self.server_process_id.to_be_bytes()); - buf.push(self.packet_id); - - // window, unused - buf.push(0); + buf.extend_from_slice(&self.to_array()); } } diff --git a/sqlx-core/src/mssql/protocol/pre_login.rs b/sqlx-core/src/mssql/protocol/pre_login.rs index 8887c96384..a7a6395e4b 100644 --- a/sqlx-core/src/mssql/protocol/pre_login.rs +++ b/sqlx-core/src/mssql/protocol/pre_login.rs @@ -1,6 +1,6 @@ +use std::default; use std::fmt::{self, Display, Formatter}; -use bitflags::bitflags; use bytes::{Buf, Bytes}; use uuid::Uuid; @@ -56,7 +56,7 @@ impl<'de> Decode<'de> for PreLogin { } PreLoginOptionToken::Encryption => { - encryption = Some(Encrypt::from_bits_truncate(data.get_u8())); + encryption = Some(Encrypt::from(data.get_u8())); } PreLoginOptionToken::Instance => { @@ -135,8 +135,8 @@ impl Encode<'_> for PreLogin { // Calculate the length of the option offset block. Each block is 5 bytes and it ends in // a 1 byte terminator. let len_offsets = (num_options * 5) + 1; - let mut offsets = buf.len() as usize; - let mut offset = len_offsets as u16; + let mut offsets = buf.len(); + let mut offset = u16::try_from(len_offsets).unwrap(); // Reserve a chunk for the offset block and set the final terminator buf.resize(buf.len() + len_offsets, 0); @@ -148,10 +148,15 @@ impl Encode<'_> for PreLogin { self.version.encode(buf); Encryption.put(buf, &mut offsets, &mut offset, 1); - buf.push(self.encryption.bits()); + buf.push(u8::from(self.encryption)); if let Some(name) = &self.instance { - Instance.put(buf, &mut offsets, &mut offset, name.len() as u16 + 1); + Instance.put( + buf, + &mut offsets, + &mut offset, + u16::try_from(name.len() + 1).unwrap(), + ); buf.extend_from_slice(name.as_bytes()); buf.push(b'\0'); } @@ -233,7 +238,7 @@ pub(crate) struct TraceId { } // Version of the sender (UL_VERSION) -#[derive(Debug, Default)] +#[derive(Debug)] pub(crate) struct Version { pub(crate) major: u8, pub(crate) minor: u8, @@ -243,6 +248,17 @@ pub(crate) struct Version { pub(crate) sub_build: u16, } +impl Default for Version { + fn default() -> Self { + Self { + major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(), + minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(), + build: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(), + sub_build: 0, + } + } +} + impl Version { fn encode(&self, buf: &mut Vec) { buf.push(self.major); @@ -258,23 +274,39 @@ impl Display for Version { } } -bitflags! { - /// During the Pre-Login handshake, the client and the server negotiate the - /// wire encryption to be used. - #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)] - pub(crate) struct Encrypt: u8 { - /// Encryption is available but on. - const ON = 0x01; +/// During the Pre-Login handshake, the client and the server negotiate the +/// wire encryption to be used. +#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum Encrypt { + /// Encryption is available but off. + Off = 0x00, - /// Encryption is not available. - const NOT_SUPPORTED = 0x02; + /// Encryption is available and on. + #[default] + On = 0x01, - /// Encryption is required. - const REQUIRED = 0x03; + /// Encryption is not available. + NotSupported = 0x02, + + /// Encryption is required. + Required = 0x03, +} + +impl From for Encrypt { + fn from(value: u8) -> Self { + match value { + 0x00 => Encrypt::Off, + 0x01 => Encrypt::On, + 0x02 => Encrypt::NotSupported, + 0x03 => Encrypt::Required, + _ => Encrypt::Off, + } + } +} - /// The client certificate should be used to authenticate - /// the user in place of a user/password. - const CLIENT_CERT = 0x80; +impl From for u8 { + fn from(value: Encrypt) -> Self { + value as u8 } } @@ -289,7 +321,7 @@ fn test_encode_pre_login() { build: 0, sub_build: 0, }, - encryption: Encrypt::ON, + encryption: Encrypt::On, instance: Some("".to_string()), thread_id: Some(0x00000DB8), multiple_active_result_sets: Some(true), @@ -327,5 +359,5 @@ fn test_decode_pre_login() { assert_eq!(pre_login.version.sub_build, 0); // ENCRYPT_OFF - assert_eq!(pre_login.encryption.bits(), 0); + assert_eq!(u8::from(pre_login.encryption), 0); } diff --git a/sqlx-core/src/mssql/protocol/rpc.rs b/sqlx-core/src/mssql/protocol/rpc.rs index 9bd01817ff..0a4c61ec2c 100644 --- a/sqlx-core/src/mssql/protocol/rpc.rs +++ b/sqlx-core/src/mssql/protocol/rpc.rs @@ -77,7 +77,7 @@ impl Encode<'_> for RpcRequest<'_> { match &self.procedure { Either::Left(name) => { - buf.extend(&(name.len() as u16).to_le_bytes()); + buf.extend(&(u16::try_from(name.len()).unwrap()).to_le_bytes()); buf.put_utf16_str(name); } diff --git a/sqlx-core/src/mssql/protocol/type_info.rs b/sqlx-core/src/mssql/protocol/type_info.rs index e994f2c6a0..48677a4732 100644 --- a/sqlx-core/src/mssql/protocol/type_info.rs +++ b/sqlx-core/src/mssql/protocol/type_info.rs @@ -269,11 +269,11 @@ impl TypeInfo { | DataType::VarChar | DataType::Binary | DataType::VarBinary => { - buf.push(self.size as u8); + buf.push(u8::try_from(self.size).unwrap()); } DataType::Decimal | DataType::Numeric | DataType::DecimalN | DataType::NumericN => { - buf.push(self.size as u8); + buf.push(u8::try_from(self.size).unwrap()); buf.push(self.precision); buf.push(self.scale); } @@ -397,7 +397,7 @@ impl TypeInfo { // Unknown size 0xfffffffffffffffe => Vec::new(), // Known size - _ => Vec::with_capacity(len as usize), + _ => Vec::with_capacity(usize::try_from(len).unwrap()), }; loop { @@ -483,7 +483,7 @@ impl TypeInfo { let size = if let IsNull::Yes = value.encode(buf) { 0xFF } else { - (buf.len() - offset - 1) as u8 + u8::try_from(buf.len() - offset - 1).unwrap() }; buf[offset] = size; @@ -500,7 +500,7 @@ impl TypeInfo { let size = if let IsNull::Yes = value.encode(buf) { 0xFFFF } else { - (buf.len() - offset - 2) as u16 + u16::try_from(buf.len() - offset - 2).unwrap() }; buf[offset..(offset + 2)].copy_from_slice(&size.to_le_bytes()); @@ -532,7 +532,7 @@ impl TypeInfo { let size = if let IsNull::Yes = value.encode(buf) { 0xFFFF_FFFF } else { - (buf.len() - offset - 4) as u32 + u32::try_from(buf.len() - offset - 4).unwrap() }; buf[offset..(offset + 4)].copy_from_slice(&size.to_le_bytes()); @@ -691,19 +691,19 @@ impl TypeInfo { DataType::DateTime2N => { s.push_str("datetime2("); s.push_str(itoa::Buffer::new().format(self.scale)); - s.push_str(")"); + s.push(')'); } DataType::DateTimeOffsetN => { s.push_str("datetimeoffset("); s.push_str(itoa::Buffer::new().format(self.scale)); - s.push_str(")"); + s.push(')'); } DataType::TimeN => { s.push_str("time("); s.push_str(itoa::Buffer::new().format(self.scale)); - s.push_str(")"); + s.push(')'); } DataType::SmallDateTime => s.push_str("smalldatetime"), DataType::Money => s.push_str("money"), @@ -714,21 +714,21 @@ impl TypeInfo { DataType::DecimalN => { s.push_str("decimal("); s.push_str(itoa::Buffer::new().format(self.precision)); - s.push_str(", "); + s.push(','); s.push_str(itoa::Buffer::new().format(self.scale)); - s.push_str(")"); + s.push(')'); } DataType::NumericN => { s.push_str("numeric("); s.push_str(itoa::Buffer::new().format(self.precision)); - s.push_str(", "); + s.push(','); s.push_str(itoa::Buffer::new().format(self.scale)); - s.push_str(")"); + s.push(')'); } DataType::MoneyN => { s.push_str("money("); s.push_str(itoa::Buffer::new().format(self.scale)); - s.push_str(")"); + s.push(')'); } DataType::Xml => s.push_str("xml"), DataType::UserDefined => s.push_str("user_defined_type"), diff --git a/sqlx-core/src/mssql/row.rs b/sqlx-core/src/mssql/row.rs index 08f3ec6395..2232ec6694 100644 --- a/sqlx-core/src/mssql/row.rs +++ b/sqlx-core/src/mssql/row.rs @@ -19,7 +19,7 @@ impl Row for MssqlRow { type Database = Mssql; fn columns(&self) -> &[MssqlColumn] { - &*self.columns + &self.columns } fn try_get_raw(&self, index: I) -> Result, Error> @@ -41,7 +41,7 @@ impl ColumnIndex for &'_ str { row.column_names .get(*self) .ok_or_else(|| Error::ColumnNotFound((*self).into())) - .map(|v| *v) + .copied() } } diff --git a/sqlx-core/src/mssql/statement.rs b/sqlx-core/src/mssql/statement.rs index 3bba4906bb..ecf3ab73dd 100644 --- a/sqlx-core/src/mssql/statement.rs +++ b/sqlx-core/src/mssql/statement.rs @@ -52,7 +52,7 @@ impl ColumnIndex> for &'_ str { .column_names .get(*self) .ok_or_else(|| Error::ColumnNotFound((*self).into())) - .map(|v| *v) + .copied() } } diff --git a/sqlx-core/src/mssql/transaction.rs b/sqlx-core/src/mssql/transaction.rs index e5402fe602..87fced617d 100644 --- a/sqlx-core/src/mssql/transaction.rs +++ b/sqlx-core/src/mssql/transaction.rs @@ -80,11 +80,12 @@ impl TransactionManager for MssqlTransactionManager { conn.stream.pending_done_count += 1; + // We cannot flush since we are in a synchronous context, but the packet will always be small here conn.stream.write_packet( PacketType::SqlBatch, SqlBatch { transaction_descriptor: conn.stream.transaction_descriptor, - sql: &*query, + sql: &query, }, ); diff --git a/sqlx-core/src/mssql/types/bigdecimal.rs b/sqlx-core/src/mssql/types/bigdecimal.rs index 08ce8ff97c..4b7a420948 100644 --- a/sqlx-core/src/mssql/types/bigdecimal.rs +++ b/sqlx-core/src/mssql/types/bigdecimal.rs @@ -42,7 +42,9 @@ impl Encode<'_, Mssql> for BigDecimal { buf.push(sign); let mantissa = if exponent <= i64::from(u8::MAX) { if exponent < 0 { - bigint *= BigInt::from(10).pow((-exponent) as u32); + if let Ok(abs_exponent) = u32::try_from(-exponent) { + bigint *= BigInt::from(10).pow(abs_exponent); + } } bigint.abs().to_u128().unwrap_or(0) } else { diff --git a/sqlx-core/src/mssql/types/bytes.rs b/sqlx-core/src/mssql/types/bytes.rs index a933546a99..48e0f71318 100644 --- a/sqlx-core/src/mssql/types/bytes.rs +++ b/sqlx-core/src/mssql/types/bytes.rs @@ -22,11 +22,12 @@ impl Type for [u8] { impl Encode<'_, Mssql> for &'_ [u8] { fn produces(&self) -> Option { let size = if self.len() <= 8000 { - u32::try_from(self.len()).unwrap().max(1) + let u_len = u32::try_from(self.len()).unwrap(); + std::cmp::max(u_len, 1) } else { 0xFF_FF }; - return Some(MssqlTypeInfo(TypeInfo::new(DataType::BigVarBinary, size))); + Some(MssqlTypeInfo(TypeInfo::new(DataType::BigVarBinary, size))) } fn encode_by_ref(&self, buf: &mut Vec) -> IsNull { diff --git a/sqlx-core/src/mssql/types/chrono.rs b/sqlx-core/src/mssql/types/chrono.rs index 62f2551016..89be7b73f9 100644 --- a/sqlx-core/src/mssql/types/chrono.rs +++ b/sqlx-core/src/mssql/types/chrono.rs @@ -160,7 +160,10 @@ where buf.extend_from_slice(&encode_date_time2(&self.naive_utc())); let seconds_from_utc = self.offset().fix().local_minus_utc(); let mut encoded_offset: [u8; 2] = [0, 0]; - LittleEndian::write_i16(&mut encoded_offset, (seconds_from_utc / 60) as i16); + LittleEndian::write_i16( + &mut encoded_offset, + i16::try_from(seconds_from_utc / 60).unwrap_or(i16::MAX), + ); buf.extend_from_slice(&encoded_offset); IsNull::No } diff --git a/sqlx-core/src/net/tls/rustls.rs b/sqlx-core/src/net/tls/rustls.rs index 0be1921b5c..53022c43c9 100644 --- a/sqlx-core/src/net/tls/rustls.rs +++ b/sqlx-core/src/net/tls/rustls.rs @@ -2,8 +2,8 @@ use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, Server use rustls::client::WebPkiServerVerifier; use rustls::pki_types::{CertificateDer, PrivateKeyDer, ServerName, UnixTime}; use rustls::{ - CertificateError, ClientConfig, DigitallySignedStruct, Error as TlsError, RootCertStore, - SignatureScheme, + CertificateError, ClientConfig, DigitallySignedStruct, Error as TlsError, KeyLogFile, + RootCertStore, SignatureScheme, }; use std::io::{BufReader, Cursor}; use std::sync::Arc; @@ -50,7 +50,7 @@ pub async fn configure_tls_connector( }; // authentication using user's key and its associated certificate - let config = match (tls_config.client_cert_path, tls_config.client_key_path) { + let mut config = match (tls_config.client_cert_path, tls_config.client_key_path) { (Some(cert_path), Some(key_path)) => { let cert_chain = certs_from_pem(cert_path.data().await?)?; let key_der = private_key_from_pem(key_path.data().await?)?; @@ -66,6 +66,9 @@ pub async fn configure_tls_connector( } }; + // When SSLKEYLOGFILE is set, write the TLS keys to a file for use with Wireshark + config.key_log = Arc::new(KeyLogFile::new()); + Ok(Arc::new(config).into()) } diff --git a/sqlx-macros/Cargo.toml b/sqlx-macros/Cargo.toml index b9a59e127f..b5eb31e7fd 100644 --- a/sqlx-macros/Cargo.toml +++ b/sqlx-macros/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sqlx-macros-oldapi" -version = "0.6.27" +version = "0.6.28" repository = "https://github.com/lovasoa/sqlx" description = "Macros for SQLx, the rust SQL toolkit. Not intended to be used directly." license = "MIT OR Apache-2.0" @@ -75,8 +75,8 @@ heck = { version = "0.5" } either = "1.6.1" once_cell = "1.9.0" proc-macro2 = { version = "1.0.36", default-features = false } -sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.27", default-features = false, features = ["any"], path = "../sqlx-core" } -sqlx-rt = { version = "0.6.27", default-features = false, path = "../sqlx-rt", package = "sqlx-rt-oldapi" } +sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.28", default-features = false, features = ["any"], path = "../sqlx-core" } +sqlx-rt = { version = "0.6.28", default-features = false, path = "../sqlx-rt", package = "sqlx-rt-oldapi" } serde = { version = "1.0.132", features = ["derive"], optional = true } serde_json = { version = "1.0.73", optional = true } sha2 = { version = "0.10.0", optional = true } diff --git a/sqlx-rt/Cargo.toml b/sqlx-rt/Cargo.toml index 1867f2e80b..93918d1fc3 100644 --- a/sqlx-rt/Cargo.toml +++ b/sqlx-rt/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sqlx-rt-oldapi" -version = "0.6.27" +version = "0.6.28" repository = "https://github.com/launchbadge/sqlx" license = "MIT OR Apache-2.0" description = "Runtime abstraction used by SQLx, the Rust SQL toolkit. Not intended to be used directly." diff --git a/tests/mssql/mssql.rs b/tests/mssql/mssql.rs index 02b0e2a696..cc02a2653c 100644 --- a/tests/mssql/mssql.rs +++ b/tests/mssql/mssql.rs @@ -205,7 +205,7 @@ async fn it_binds_string_with_special_chars() -> anyhow::Result<()> { async fn it_accepts_long_query_strings() -> anyhow::Result<()> { let mut conn = new::().await?; // try a query that does not fit in a single TDS packet - let (n,): (i32,) = sqlx_oldapi::query_as(&format!("SELECT {} 42", " ".repeat(0x1_00_00))) + let (n,): (i32,) = sqlx_oldapi::query_as(&format!("SELECT {} 42", " ".repeat(3000))) .fetch_one(&mut conn) .await?; assert_eq!(n, 42);