Skip to content

Commit

Permalink
Cargo proxy authentication methods: rust-lang#7330
Browse files Browse the repository at this point in the history
This commit adds support for HTTP proxy authentication methods in cargo as suggested by rust-lang#7330.

The added authentication methods added are supported by `libcurl`:
* NTLM
* NTLM_WB
* GSSNEGOTIATE
* BASIC
* DIGEST
* DIGEST_IE

The authentication methods suggest user credentials to be provided as well - and their support will be added in future commits.
  • Loading branch information
baburkin committed Sep 5, 2019
1 parent ba37dac commit c08f37b
Showing 1 changed file with 34 additions and 1 deletion.
35 changes: 34 additions & 1 deletion src/cargo/ops/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::time::Duration;
use std::{cmp, env};

use crates_io::{NewCrate, NewCrateDependency, Registry};
use curl::easy::{Easy, InfoType, SslOpt};
use curl::easy::{Easy, InfoType, SslOpt, Auth};
use failure::{bail, format_err};
use log::{log, Level};
use percent_encoding::{percent_encode, NON_ALPHANUMERIC};
Expand Down Expand Up @@ -409,12 +409,14 @@ pub fn http_handle_and_timeout(config: &Config) -> CargoResult<(Easy, HttpTimeou

pub fn needs_custom_http_transport(config: &Config) -> CargoResult<bool> {
let proxy_exists = http_proxy_exists(config)?;
let proxy_auth_exists = http_proxy_auth_exists(config)?;
let timeout = HttpTimeout::new(config)?.is_non_default();
let cainfo = config.get_path("http.cainfo")?;
let check_revoke = config.get_bool("http.check-revoke")?;
let user_agent = config.get_string("http.user-agent")?;

Ok(proxy_exists
|| proxy_auth_exists
|| timeout
|| cainfo.is_some()
|| check_revoke.is_some()
Expand All @@ -426,6 +428,9 @@ pub fn configure_http_handle(config: &Config, handle: &mut Easy) -> CargoResult<
if let Some(proxy) = http_proxy(config)? {
handle.proxy(&proxy)?;
}
if let Some(proxy_auth) = http_proxy_auth(config)? {
handle.proxy_auth(&proxy_auth)?;
}
if let Some(cainfo) = config.get_path("http.cainfo")? {
handle.cainfo(&cainfo.val)?;
}
Expand Down Expand Up @@ -545,6 +550,34 @@ fn http_proxy_exists(config: &Config) -> CargoResult<bool> {
}
}

/// Finds an explicit HTTP proxy authentication method if one is available.
///
/// Checks cargo's `http.proxy-auth`. This will be passed on
/// to libcurl via respective `Auth` parameter.
fn http_proxy_auth(config: &Config) -> CargoResult<Option<&Auth>> {
if let Some(s) = config.get_string("http.proxy-auth")? {
let val = match s {
Some("ntlm") => Some(Auth::new().ntlm(true)),
Some("ntlm_wb") => Some(Auth::new().ntlm_wb(true)),
Some("gssnegotiate") => Some(Auth::new().gssnegotiate(true)),
Some("basic") => Some(Auth::new().basic(true)),
Some("digest") => Some(Auth::new().digest(true)),
Some("digest_ie") => Some(Auth::new().digest_ie(true)),
_ => Ok(None)
};
return Ok(&*val);
}
Ok(None)
}

/// Determine if HTTP proxy authentication method is provided.
fn http_proxy_auth_exists(config: &Config) -> CargoResult<bool> {
if http_proxy_auth(config)?.is_some() {
return Ok(true)
}
Ok(false)
}

pub fn registry_login(
config: &Config,
token: Option<String>,
Expand Down

0 comments on commit c08f37b

Please sign in to comment.