feat: Migrate TLS backend from rustls to native-tls (#3807)

## Fixes

- #1142
- #2528
- #570
- #3369
- #968
- #3196
This commit is contained in:
Marko Vejnovic
2026-07-30 16:44:11 -07:00
committed by GitHub
parent 6c9f57a7b5
commit 3aac1b3f5e
24 changed files with 180 additions and 241 deletions
+1 -1
View File
@@ -42,4 +42,4 @@ jobs:
# Run `nix fmt` to fix any failures here
- name: Check nix formatting
run: nix fmt -- --check $(git ls-files '*.nix')
run: nix fmt -- --ci
+27 -3
View File
@@ -23,6 +23,10 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: Install OpenSSL dev libraries (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libssl-dev pkg-config
- name: Install rust
uses: dtolnay/rust-toolchain@master
with:
@@ -76,14 +80,14 @@ jobs:
run: cross build -p atuin-common --locked --target ${{ matrix.target }}
- name: Run cross build client
run: cross build -p atuin-client --locked --target ${{ matrix.target }}
run: cross build -p atuin-client --locked --target ${{ matrix.target }} --features vendored-tls
- name: Run cross build server
run: cross build -p atuin-server --locked --target ${{ matrix.target }}
run: cross build -p atuin-server --locked --target ${{ matrix.target }} --features vendored-tls
- name: Run cross build main
run: |
cross build --all --locked --target ${{ matrix.target }}
cross build --all --locked --target ${{ matrix.target }} --features vendored-tls
unit-test:
strategy:
@@ -94,6 +98,10 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: Install OpenSSL dev libraries (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libssl-dev pkg-config
- name: Install rust
uses: dtolnay/rust-toolchain@master
with:
@@ -124,6 +132,10 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: Install OpenSSL dev libraries (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libssl-dev pkg-config
- name: Install rust
uses: dtolnay/rust-toolchain@master
with:
@@ -168,6 +180,10 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: Install OpenSSL dev libraries (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libssl-dev pkg-config
- name: Install rust
uses: dtolnay/rust-toolchain@master
with:
@@ -197,6 +213,10 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: Install OpenSSL dev libraries (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libssl-dev pkg-config
- name: Install latest rust
uses: dtolnay/rust-toolchain@master
with:
@@ -223,6 +243,10 @@ jobs:
steps:
- uses: actions/checkout@v7
- name: Install OpenSSL dev libraries (Linux)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y libssl-dev pkg-config
- name: Install rust
uses: dtolnay/rust-toolchain@master
with:
Generated
+103 -183
View File
@@ -406,7 +406,6 @@ dependencies = [
"pretty_assertions",
"proptest",
"rstest",
"rustls",
"serde",
"serde_json",
"serde_with",
@@ -1115,16 +1114,6 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "combine"
version = "4.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
dependencies = [
"bytes",
"memchr",
]
[[package]]
name = "compact_str"
version = "0.9.0"
@@ -1878,6 +1867,21 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
[[package]]
name = "foreign-types"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
dependencies = [
"foreign-types-shared",
]
[[package]]
name = "foreign-types-shared"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "form_urlencoded"
version = "1.2.2"
@@ -2293,21 +2297,6 @@ dependencies = [
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.27.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f"
dependencies = [
"http",
"hyper",
"hyper-util",
"rustls",
"tokio",
"tokio-rustls",
"tower-service",
]
[[package]]
name = "hyper-timeout"
version = "0.5.2"
@@ -2321,6 +2310,22 @@ dependencies = [
"tower-service",
]
[[package]]
name = "hyper-tls"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
dependencies = [
"bytes",
"http-body-util",
"hyper",
"hyper-util",
"native-tls",
"tokio",
"tokio-native-tls",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.20"
@@ -2645,55 +2650,6 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "jni"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498"
dependencies = [
"cfg-if",
"combine",
"jni-macros",
"jni-sys",
"log",
"simd_cesu8",
"thiserror 2.0.18",
"walkdir",
"windows-link",
]
[[package]]
name = "jni-macros"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3"
dependencies = [
"proc-macro2",
"quote",
"rustc_version",
"simd_cesu8",
"syn 2.0.119",
]
[[package]]
name = "jni-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2"
dependencies = [
"jni-sys-macros",
]
[[package]]
name = "jni-sys-macros"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264"
dependencies = [
"quote",
"syn 2.0.119",
]
[[package]]
name = "js-sys"
version = "0.3.100"
@@ -3050,6 +3006,23 @@ version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
[[package]]
name = "native-tls"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2"
dependencies = [
"libc",
"log",
"openssl",
"openssl-probe",
"openssl-sys",
"schannel",
"security-framework",
"security-framework-sys",
"tempfile",
]
[[package]]
name = "nix"
version = "0.28.0"
@@ -3306,12 +3279,59 @@ dependencies = [
"pathdiff",
]
[[package]]
name = "openssl"
version = "0.10.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77823a27f0babb03091cb9ed9ef80af3b39dbc82f97e8fa530374b7dafd87a45"
dependencies = [
"bitflags 2.13.0",
"cfg-if",
"foreign-types",
"libc",
"openssl-macros",
"openssl-sys",
]
[[package]]
name = "openssl-macros"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.119",
]
[[package]]
name = "openssl-probe"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe"
[[package]]
name = "openssl-src"
version = "300.6.1+3.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46eb8fb9fb3b61ce1c0f8a026c4c1a0714d3a9e138e7fbde78753ce2babc3846"
dependencies = [
"cc",
]
[[package]]
name = "openssl-sys"
version = "0.9.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b47e7e6bb2c38cd930d25a23b40fa52e068c10e85f3e03a7f5ba5aaca5713695"
dependencies = [
"cc",
"libc",
"openssl-src",
"pkg-config",
"vcpkg",
]
[[package]]
name = "option-ext"
version = "0.2.0"
@@ -4171,20 +4191,19 @@ dependencies = [
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-tls",
"hyper-util",
"js-sys",
"log",
"native-tls",
"percent-encoding",
"pin-project-lite",
"rustls",
"rustls-pki-types",
"rustls-platform-verifier",
"serde",
"serde_json",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tokio-native-tls",
"tokio-util",
"tower",
"tower-http",
@@ -4326,32 +4345,6 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "rustls"
version = "0.23.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c54fcab019b409d04215d3a17cb438fd7fbf192ee61461f20f4fe18704bc138"
dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d"
dependencies = [
"openssl-probe",
"rustls-pki-types",
"schannel",
"security-framework",
]
[[package]]
name = "rustls-pki-types"
version = "1.14.1"
@@ -4361,44 +4354,6 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rustls-platform-verifier"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0"
dependencies = [
"core-foundation",
"core-foundation-sys",
"jni",
"log",
"once_cell",
"rustls",
"rustls-native-certs",
"rustls-platform-verifier-android",
"rustls-webpki",
"security-framework",
"security-framework-sys",
"webpki-root-certs",
"windows-sys 0.61.2",
]
[[package]]
name = "rustls-platform-verifier-android"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f"
[[package]]
name = "rustls-webpki"
version = "0.103.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
name = "rustversion"
version = "1.0.22"
@@ -4826,22 +4781,6 @@ dependencies = [
"rand_core 0.6.4",
]
[[package]]
name = "simd_cesu8"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33"
dependencies = [
"rustc_version",
"simdutf8",
]
[[package]]
name = "simdutf8"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]]
name = "siphasher"
version = "1.0.3"
@@ -4949,8 +4888,8 @@ dependencies = [
"indexmap 2.14.0",
"log",
"memchr",
"native-tls",
"percent-encoding",
"rustls",
"serde",
"serde_json",
"sha2 0.10.9",
@@ -4962,7 +4901,6 @@ dependencies = [
"tracing",
"url",
"uuid",
"webpki-roots",
]
[[package]]
@@ -5506,12 +5444,12 @@ dependencies = [
]
[[package]]
name = "tokio-rustls"
version = "0.26.4"
name = "tokio-native-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61"
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
dependencies = [
"rustls",
"native-tls",
"tokio",
]
@@ -6324,24 +6262,6 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki-root-certs"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "webpki-roots"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d"
dependencies = [
"rustls-pki-types",
]
[[package]]
name = "wezterm-bidi"
version = "0.2.3"
+1 -6
View File
@@ -71,11 +71,6 @@ ratatui = "0.30.0"
sql-builder = "3"
tempfile = { version = "3.19" }
minijinja = "2.9.0"
rustls = { version = "0.23", default-features = false, features = [
"ring",
"std",
"tls12",
] }
glob-match = "0.2.1"
imara-diff = "0.2"
xxhash-rust = { version = "0.8", features = ["xxh3"] }
@@ -90,7 +85,7 @@ features = ["ansi", "fmt", "registry", "env-filter", "json"]
[workspace.dependencies.reqwest]
version = "0.13"
features = ["json", "rustls-no-provider", "stream"]
features = ["json", "native-tls", "stream"]
default-features = false
[workspace.dependencies.sqlx]
+12
View File
@@ -0,0 +1,12 @@
[target.x86_64-unknown-illumos]
pre-build = [
# perl+make build the vendored (target) OpenSSL. pkg-config+libssl-dev satisfy the
# HOST openssl-sys that the sqlx-macros proc-macro links: resolver v2 resolves the
# proc-macro graph separately, so `vendored-tls` never reaches it and it needs a
# real system OpenSSL on the build host.
"apt-get update && apt-get install --assume-yes --no-install-recommends perl make pkg-config libssl-dev",
# openssl-src builds vendored OpenSSL with the solaris64 target, whose Makefile
# calls `granlib` (the Solaris name for GNU ranlib). The cross image ships the
# toolchain's ranlib as x86_64-unknown-illumos-ranlib but no `granlib`, so provide it.
"ln -sf \"$(command -v x86_64-unknown-illumos-ranlib)\" /usr/local/bin/granlib",
]
+2 -2
View File
@@ -8,7 +8,7 @@ RUN cargo chef prepare --recipe-path recipe.json
FROM chef AS builder
# Ensure working C compile setup (not installed by default in arm64 images)
RUN apt update && apt install build-essential -y
RUN apt update && apt install build-essential libssl-dev pkg-config -y
COPY --from=planner /app/recipe.json recipe.json
RUN cargo chef cook --release --recipe-path recipe.json
@@ -23,7 +23,7 @@ LABEL org.opencontainers.image.source="https://github.com/atuinsh/atuin" \
RUN useradd -c 'atuin user' atuin && mkdir /config && chown atuin:atuin /config
# ca-certificates for webhooks to work, curl for the healthcheck
RUN apt update && apt install --no-install-recommends ca-certificates curl -y && rm -rf /var/lib/apt/lists/*
RUN apt update && apt install --no-install-recommends ca-certificates curl libssl3 -y && rm -rf /var/lib/apt/lists/*
WORKDIR app
USER atuin
+16 -2
View File
@@ -10,6 +10,8 @@
installShellFiles,
rustPlatform,
libiconv,
pkg-config,
openssl,
}:
rustPlatform.buildRustPackage {
name = "atuin";
@@ -22,9 +24,21 @@ rustPlatform.buildRustPackage {
allowBuiltinFetchGit = true;
};
nativeBuildInputs = [ installShellFiles ];
nativeBuildInputs = [
installShellFiles
pkg-config
];
buildInputs = lib.optionals stdenv.isDarwin [ libiconv ];
buildInputs = [ openssl ] ++ lib.optionals stdenv.isDarwin [ libiconv ];
OPENSSL_NO_VENDOR = 1;
# native-tls pulls OpenSSL into the sqlx-macros proc-macro, which rustc dlopens at
# build time. With OPENSSL_NO_VENDOR it links libssl.so.3 dynamically, so the loader
# needs it on LD_LIBRARY_PATH while the proc-macro is loaded.
preBuild = ''
export LD_LIBRARY_PATH="${lib.makeLibraryPath [ openssl ]}''${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
'';
postInstall = ''
installShellCompletion --cmd atuin \
-1
View File
@@ -28,7 +28,6 @@ pub(crate) struct ModelList {
/// Fetch the models available to this user. Sent authenticated because the
/// server includes feature-flag-gated models only for entitled users.
pub(crate) async fn fetch_models(endpoint: &reqwest::Url, token: &str) -> Result<ModelList> {
atuin_common::tls::ensure_crypto_provider();
let url = endpoint.append_path("api/cli/models")?;
let mut request = reqwest::Client::new()
-2
View File
@@ -6,7 +6,6 @@ use atuin_client::history::History;
use atuin_client::settings::AiCapabilities;
use crate::context::history_output_capability_available;
use atuin_common::tls::ensure_crypto_provider;
use atuin_common::url::UrlAppendExt;
use eventsource_stream::Eventsource;
@@ -130,7 +129,6 @@ pub(crate) fn create_chat_stream(
skill_overflow: Option<String>,
) -> std::pin::Pin<Box<dyn futures::Stream<Item = Result<StreamFrame>> + Send>> {
Box::pin(async_stream::stream! {
ensure_crypto_provider();
let endpoint = match hub_address.append_path("api/cli/chat") {
Ok(url) => url,
Err(e) => {
-1
View File
@@ -90,7 +90,6 @@ pub(crate) fn cache_key(token: &str) -> String {
/// Fetch current usage from the hub. Mirrors the `credits` object on the
/// chat `done` event, for refreshing without starting a chat.
pub(crate) async fn fetch_usage(endpoint: &reqwest::Url, token: &str) -> Result<UsageSnapshot> {
atuin_common::tls::ensure_crypto_provider();
let url = endpoint.append_path("api/cli/usage")?;
let response = reqwest::Client::new()
+3
View File
@@ -19,6 +19,9 @@ sync = ["reqwest"]
hub = ["reqwest"]
daemon = []
check-update = []
# Statically link (vendor) OpenSSL for native-tls instead of using the system
# libssl. Used for portable release artifacts; a no-op on macOS/Windows.
vendored-tls = ["reqwest?/native-tls-vendored"]
[dependencies]
derive_more = { workspace = true }
+1 -7
View File
@@ -8,7 +8,7 @@ use reqwest::{
header::{AUTHORIZATION, HeaderMap, HeaderName, HeaderValue, USER_AGENT},
};
use atuin_common::{tls::ensure_crypto_provider, url::UrlAppendExt};
use atuin_common::url::UrlAppendExt;
use atuin_domain::api::{
ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, ATUIN_VERSION, ChangePasswordRequest, ErrorResponse,
LoginRequest, LoginResponse, MeResponse, RegisterResponse,
@@ -105,7 +105,6 @@ pub async fn register(
password: &str,
extra_headers: &HashMap<String, String>,
) -> Result<RegisterResponse> {
ensure_crypto_provider();
let mut map = HashMap::new();
map.insert("username", username);
map.insert("email", email);
@@ -141,7 +140,6 @@ pub async fn login(
req: LoginRequest,
extra_headers: &HashMap<String, String>,
) -> Result<LoginResponse> {
ensure_crypto_provider();
let url = address.append(["login"])?;
let client = client_builder(extra_headers).build()?;
@@ -163,7 +161,6 @@ pub async fn login(
pub async fn latest_version() -> Result<Version> {
use atuin_domain::api::IndexResponse;
ensure_crypto_provider();
let url = crate::settings::DEFAULT_SYNC_URL.clone();
let client = reqwest::Client::new();
@@ -251,7 +248,6 @@ impl<'a> Client<'a> {
timeout: u64,
extra_headers: &HashMap<String, String>,
) -> Result<Self> {
ensure_crypto_provider();
let mut headers = extra_headers_map(extra_headers)?;
headers.insert(AUTHORIZATION, auth.to_header_value().parse()?);
headers.insert(USER_AGENT, APP_USER_AGENT.parse()?);
@@ -452,7 +448,6 @@ mod tests {
.await;
});
ensure_crypto_provider();
let client = client_builder(&extra_headers).build().unwrap();
let err = client
.get(format!("http://127.0.0.1:{port}/"))
@@ -489,7 +484,6 @@ mod tests {
.await;
});
ensure_crypto_provider();
let client = client_builder(&extra_headers).build().unwrap();
let resp = client
.get(format!("http://127.0.0.1:{port}/"))
+1 -6
View File
@@ -5,7 +5,7 @@ use eyre::{Context, Result, bail};
use reqwest::{StatusCode, Url, header::USER_AGENT};
use serde::Deserialize;
use atuin_common::{tls::ensure_crypto_provider, url::UrlAppendExt};
use atuin_common::url::UrlAppendExt;
use atuin_domain::api::{
ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, ChangePasswordRequest, LoginRequest, LoginResponse,
RegisterResponse,
@@ -126,7 +126,6 @@ impl LegacyAuthClient {
.as_deref()
.ok_or_else(|| eyre::eyre!("Not logged in"))?;
ensure_crypto_provider();
let mut headers = crate::api_client::extra_headers_map(&self.extra_headers)?;
headers.insert(
reqwest::header::AUTHORIZATION,
@@ -278,7 +277,6 @@ impl AuthClient for HubAuthClient {
password: &str,
totp_code: Option<&str>,
) -> Result<AuthResponse> {
ensure_crypto_provider();
let url = self.address.append_path("api/v0/login")?;
let client = reqwest::Client::new();
@@ -326,7 +324,6 @@ impl AuthClient for HubAuthClient {
}
async fn register(&self, username: &str, email: &str, password: &str) -> Result<AuthResponse> {
ensure_crypto_provider();
let url = self.address.append_path("api/v0/register")?;
let client = reqwest::Client::new();
@@ -380,7 +377,6 @@ impl AuthClient for HubAuthClient {
);
}
ensure_crypto_provider();
let url = self.address.append_path("api/v0/account/password")?;
let client = reqwest::Client::new();
@@ -452,7 +448,6 @@ impl AuthClient for HubAuthClient {
);
}
ensure_crypto_provider();
let url = self.address.append_path("api/v0/account")?;
let client = reqwest::Client::new();
+1 -4
View File
@@ -13,7 +13,7 @@ use std::time::Duration;
use eyre::{Context, Result, bail};
use reqwest::{StatusCode, Url, header::USER_AGENT};
use atuin_common::{tls::ensure_crypto_provider, url::UrlAppendExt};
use atuin_common::url::UrlAppendExt;
use atuin_domain::api::{
ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, CliCodeResponse, CliVerifyResponse, ErrorResponse,
};
@@ -191,7 +191,6 @@ pub async fn link_account(hub_address: &Url, cli_token: &str) -> Result<()> {
debug!("Linking CLI account to Hub at {}", hub_address);
ensure_crypto_provider();
let client = reqwest::Client::new();
let resp = client
@@ -246,7 +245,6 @@ async fn handle_resp_error(resp: reqwest::Response) -> Result<reqwest::Response>
/// Request a CLI auth code from the Atuin Hub
async fn request_code(address: &Url) -> Result<CliCodeResponse> {
ensure_crypto_provider();
let url = address.append_path("auth/cli/code")?;
let client = reqwest::Client::new();
@@ -266,7 +264,6 @@ async fn request_code(address: &Url) -> Result<CliCodeResponse> {
/// Poll to verify the CLI auth code and get the session token
async fn verify_code(address: &Url, code: &str) -> Result<CliVerifyResponse> {
ensure_crypto_provider();
let mut url = address.append_path("auth/cli/verify")?;
let client = reqwest::Client::new();
-1
View File
@@ -36,7 +36,6 @@ directories = { workspace = true }
sysinfo = "0.30.7"
base64 = { workspace = true }
getrandom = "0.4"
rustls = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true, optional = true }
unicode-width = { version = "0.2", optional = true }
-1
View File
@@ -12,6 +12,5 @@ pub mod string;
#[cfg(feature = "test-utils")]
pub mod test_utils;
pub mod time;
pub mod tls;
pub mod url;
pub mod utils;
-15
View File
@@ -1,15 +0,0 @@
use std::sync::Once;
static INIT: Once = Once::new();
/// Ensure the rustls crypto provider (ring) is installed.
///
/// Must be called before creating any reqwest clients. Safe to call
/// multiple times — only the first call installs the provider.
pub fn ensure_crypto_provider() {
INIT.call_once(|| {
rustls::crypto::ring::default_provider()
.install_default()
.expect("Failed to install rustls crypto provider");
});
}
+1 -1
View File
@@ -19,7 +19,7 @@ eyre = { workspace = true }
tracing = { workspace = true }
time = { workspace = true }
serde = { workspace = true }
sqlx = { workspace = true, features = ["postgres", "tls-rustls"] }
sqlx = { workspace = true, features = ["postgres", "tls-native-tls"] }
async-trait = { workspace = true }
uuid = { workspace = true }
metrics = "0.24"
+5
View File
@@ -18,6 +18,11 @@ path = "src/lib.rs"
name = "atuin-server"
path = "src/bin/main.rs"
[features]
# Statically link (vendor) OpenSSL for native-tls instead of using the system
# libssl. Used for portable release artifacts; a no-op on macOS/Windows.
vendored-tls = ["reqwest/native-tls-vendored"]
[dependencies]
atuin-common = { workspace = true }
atuin-domain = { workspace = true }
-3
View File
@@ -16,8 +16,6 @@ use metrics::counter;
use rand::rngs::OsRng;
use tracing::{debug, error, info, instrument};
use atuin_common::tls::ensure_crypto_provider;
use super::{ErrorResponse, ErrorResponseStatus, RespExt};
use crate::router::{AppState, UserAuth};
use atuin_server_database::{
@@ -41,7 +39,6 @@ pub fn verify_str(hash: &str, password: &str) -> bool {
// Try to send a Discord webhook once - if it fails, we don't retry. "At most once", and best effort.
// Don't return the status because if this fails, we don't really care.
async fn send_register_hook(url: &url::Url, username: String, registered: String) {
ensure_crypto_provider();
let hook = HashMap::from([
("username", username),
("content", format!("{registered} has just signed up!")),
+1
View File
@@ -49,6 +49,7 @@ pty-proxy = ["dep:atuin-pty-proxy"]
hex = ["pty-proxy"]
clipboard = ["arboard"]
check-update = ["atuin-client/check-update"]
vendored-tls = ["atuin-client?/vendored-tls"]
[dependencies]
atuin-ai = { path = "../atuin-ai", version = "18.19.0-beta.2", optional = true, default-features = false }
+1 -1
View File
@@ -21,7 +21,7 @@ tokio = { workspace = true }
tracing = { workspace = true }
time = { workspace = true }
serde = { workspace = true }
sqlx = { workspace = true, features = ["sqlite", "regexp", "postgres", "tls-rustls"] }
sqlx = { workspace = true, features = ["sqlite", "regexp", "postgres", "tls-native-tls"] }
async-trait = { workspace = true }
uuid = { workspace = true }
metrics = "0.24"
+3
View File
@@ -21,6 +21,9 @@ install-updater = true
unix-archive = ".tar.gz"
# Whether to enable GitHub Attestations
github-attestations = true
# Vendor (statically link) OpenSSL so the downloadable binaries are portable and
# don't depend on the host's libssl version. No-op on macOS/Windows.
features = ["vendored-tls"]
[dist.github-custom-runners]
aarch64-unknown-linux-gnu = "depot-ubuntu-24.04-arm-8"
+1 -1
View File
@@ -40,7 +40,7 @@
default = atuin;
};
formatter = pkgs.nixfmt;
formatter = pkgs.nixfmt-tree;
devShells.default = pkgs.mkShell {
inputsFrom = [ atuin ];