mirror of
https://github.com/rust-lang/cargo
synced 2024-10-04 06:49:15 +00:00
Error on invalid token for registry auth
When using registry operations with authentication there will be now an error if the given token is not valid. This is a technically a breaking change because a registry might give some tokens which will be denied by these new checks. In practice these tokens cause issues with HTTP so no registry should generate them.
This commit is contained in:
parent
2f84e1a45c
commit
3d2e107b5a
|
@ -394,6 +394,7 @@ impl Registry {
|
|||
Some(s) => s,
|
||||
None => bail!("no upload token found, please run `cargo login`"),
|
||||
};
|
||||
check_token(token)?;
|
||||
headers.append(&format!("Authorization: {}", token))?;
|
||||
}
|
||||
self.handle.http_headers(headers)?;
|
||||
|
@ -510,3 +511,23 @@ pub fn is_url_crates_io(url: &str) -> bool {
|
|||
.map(|u| u.host_str() == Some("crates.io"))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
/// Checks if a token is valid or malformed.
|
||||
///
|
||||
/// This check is necessary to prevent sending tokens which create an invalid HTTP request.
|
||||
/// It would be easier to check just for alphanumeric tokens, but we can't be sure that all
|
||||
/// registries only create tokens in that format so that is as less restricted as possible.
|
||||
pub fn check_token(token: &str) -> Result<()> {
|
||||
let is_valid = token.bytes().all(|b| {
|
||||
b >= 32 // undefined in ISO-8859-1, in ASCII/ UTF-8 not-printable character
|
||||
&& b < 128 // utf-8: the first bit signals a multi-byte character
|
||||
&& b != 127 // 127 is a control character in ascii and not in ISO 8859-1
|
||||
|| b == b't' // tab is also allowed (even when < 32)
|
||||
});
|
||||
|
||||
if is_valid {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(anyhow::anyhow!("invalid token."))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -901,6 +901,7 @@ pub fn registry_login(
|
|||
if tok.is_empty() {
|
||||
bail!("please provide a non-empty token");
|
||||
}
|
||||
crates_io::check_token(tok.as_ref().expose())?;
|
||||
}
|
||||
}
|
||||
if ®_cfg == &new_token {
|
||||
|
|
|
@ -126,6 +126,38 @@ fn empty_login_token() {
|
|||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn invalid_login_token() {
|
||||
let registry = RegistryBuilder::new()
|
||||
.no_configure_registry()
|
||||
.no_configure_token()
|
||||
.build();
|
||||
setup_new_credentials();
|
||||
|
||||
let check_ = |stdin: &str, stderr: &str| {
|
||||
cargo_process("login")
|
||||
.replace_crates_io(registry.index_url())
|
||||
.with_stdout("please paste the token found on [..]/me below")
|
||||
.with_stdin(stdin)
|
||||
.with_stderr(stderr)
|
||||
.with_status(101)
|
||||
.run();
|
||||
};
|
||||
let check = |stdin: &str| {
|
||||
check_(stdin, "[ERROR] invalid token.");
|
||||
};
|
||||
// first check updates index so it must be handled differently
|
||||
check_(
|
||||
"😄",
|
||||
"\
|
||||
[UPDATING] crates.io index
|
||||
[ERROR] invalid token.",
|
||||
);
|
||||
check("\u{0016}");
|
||||
check("\u{0000}");
|
||||
check("你好");
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn bad_asymmetric_token_args() {
|
||||
// These cases are kept brief as the implementation is covered by clap, so this is only smoke testing that we have clap configured correctly.
|
||||
|
|
Loading…
Reference in a new issue