rust-lang / cargo

The Rust package manager
https://doc.rust-lang.org/cargo
Apache License 2.0
12.76k stars 2.42k forks source link

Private registry authorization stops working when Cargo's HTTP settings are changed #12524

Open babinskiy opened 1 year ago

babinskiy commented 1 year ago

Problem

In our current setup, we have a private registry hosted on cloudsmith.io, and we utilize git-credentials authorization to access the repository successfully. However, we have encountered a couple of issues that we need to address.

When we attempt to modify some Cargo parameters, the authorization process stops working.

user@ubuntu2204-amd64-build:~/repo$ cargo fetch
    Updating crates.io index
    Updating `private` index
warning: spurious network error (50 tries remaining): failed to receive HTTP 200 response: got 401; class=Net (12)
warning: spurious network error (49 tries remaining): failed to receive HTTP 200 response: got 401; class=Net (12)

Steps

  1. Add a private registry that requires authentication:
    ...
    [registries.private]
    index = "https://dl.cloudsmith.io/basic/myacc/private/cargo/index.git"
    ...
  2. Configure cloudsmith.io authentication as described here: https://help.cloudsmith.io/docs/cargo-registry#registry-setup
    git config --global credential.helper store
    echo "https://USERNAME:API-KEY@dl.cloudsmith.io" > ~/.git-credentials
  3. Change some default parameters. I have only tried a few, and I'm not sure if any of these parameters will break the authentication. Parameters can be added in different ways, either in config.toml or as an environment variable:
[http]
timeout = 10

or

export CARGO_HTTP_TIMEOUT=10
  1. run cargo fetch:
    ubuntu@ubuntu2204-amd64-build:~/repo$ cargo fetch
    Updating crates.io index
    Updating `private` index
    warning: spurious network error (50 tries remaining): failed to receive HTTP 200 response: got 401; class=Net (12)
    warning: spurious network error (49 tries remaining): failed to receive HTTP 200 response: got 401; class=Net (12)
    ^C

Possible Solution(s)

There is a workaround - putting the authentication token in repo's URL, as described here: https://help.cloudsmith.io/docs/cargo-registry#registry-setup

[registries.OWNER-REPOSITORY]
index = "https://dl.cloudsmith.io/TOKEN/OWNER/REPOSITORY/cargo/"

However, it is important to note that this approach is insecure and may result in token leakage

Notes

I played with different parameters:

Version

cargo 1.71.0 (cfd3bbd8f 2023-06-08)
release: 1.71.0
commit-hash: cfd3bbd8fe4fd92074dfad04b7eb9a923646839f
commit-date: 2023-06-08
host: x86_64-unknown-linux-gnu
libgit2: 1.6.4 (sys:0.17.1 vendored)
libcurl: 8.0.1-DEV (sys:0.4.61+curl-8.0.1 vendored ssl:OpenSSL/1.1.1t)
ssl: OpenSSL 1.1.1t  7 Feb 2023
os: Ubuntu 22.04 (jammy) [64-bit]
ehuss commented 1 year ago

This is an issue with the git2-curl crate, since it doesn't support authentication. I think it roughly needs to handle the authentication similar to handle_auth where it would need to detect an unauthorized response and do all the callback stuff.

In the meantime, I would recommend using net.git-fetch-with-cli.