diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.rs | 19 | ||||
| -rw-r--r-- | src/registry.rs | 47 |
2 files changed, 50 insertions, 16 deletions
diff --git a/src/main.rs b/src/main.rs index 4f42d45..0d08fc6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use crate::docker::DockerRef; use crate::manifest::ManifestFile; use crate::dockerfile::DockerfileFile; use crate::db::{Db, SqliteDb}; -use crate::registry::{Registry, HttpRegistry, AuthInfo, basic_auth}; +use crate::registry::{Registry, HttpRegistry, AuthInfo, Credentials, basic_auth}; use rand::distr::{Alphanumeric, SampleString}; use std::ops::Range; @@ -27,6 +27,7 @@ Search FILE for docker images and suggest updates Options: --auth <REGISTRY> <USER> <PASS> Authenticate against REGISTRY (repeatable) +--anonymous-auth <REGISTRY> Access REGISTRY anonymously (repeatable) --config <PATH> Read config from PATH --scratch <DIR> Store temporary files in DIR --metrics-port <PORT> Serve Prometheus metrics on PORT (default: disabled)", @@ -473,7 +474,7 @@ fn main() { if let Some(registry) = it.next() && let Some(username) = it.next() && let Some(password) = it.next() { auths.push(AuthInfo { host: registry.clone(), - auth: basic_auth(username, password), + credentials: Credentials::Basic(basic_auth(username, password)), }); } else { println!("Error: --auth requires three parameters"); @@ -481,6 +482,18 @@ fn main() { std::process::exit(1); } }, + Some("--anonymous-auth") => { + if let Some(registry) = it.next() { + auths.push(AuthInfo { + host: registry.clone(), + credentials: Credentials::Anonymous, + }); + } else { + println!("Error: --anonymous-auth requires a registry parameter"); + help(cmd); + std::process::exit(1); + } + }, Some("--config") => { if let Some(path) = it.next() { config_path = Some(std::path::PathBuf::from(path)); @@ -600,7 +613,7 @@ fn main() { Ok(json_event_parser::JsonEvent::String(v)) => { auths.push(AuthInfo { host: key, - auth: v.into_owned(), + credentials: Credentials::Basic(v.into_owned()), }); }, _ => panic!("Invalid config json"), diff --git a/src/registry.rs b/src/registry.rs index afd2794..9f497fd 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -39,9 +39,14 @@ pub fn basic_auth(user: &str, pass: &str) -> String { return BASE64_STANDARD.encode(format!("{}:{}", user, pass)); } +pub enum Credentials { + Anonymous, + Basic(String), +} + pub struct AuthInfo { pub host: String, - pub auth: String, + pub credentials: Credentials, } enum AuthStage { @@ -92,22 +97,32 @@ impl AuthState { let auth_header = response.headers().get("www-authenticate").unwrap(); match AuthMethod::from_header(auth_header) { Some(AuthMethod::Basic) => { - let basic_auth = format!("Basic {}", self.info.auth); - self.stage = AuthStage::Authorized(basic_auth); - - return Ok(()); + match &self.info.credentials { + Credentials::Basic(creds) => { + self.stage = AuthStage::Authorized(format!("Basic {}", creds)); + return Ok(()); + } + Credentials::Anonymous => { + return Err(format!( + "Server {} requires Basic auth but configured as anonymous", + self.info.host + )); + } + } } Some(AuthMethod::Bearer { realm, scope, service }) => { - let basic_auth = format!("Basic {}", self.info.auth); - let url = format!("{}?service={}&scope={}", realm, service, scope); - let body = ureq::get(url) + let mut request = ureq::get(url) .config() .http_status_as_error(false) - .build() - .header("Authorization", basic_auth) - .call(); + .build(); + + if let Credentials::Basic(creds) = &self.info.credentials { + request = request.header("Authorization", format!("Basic {}", creds)); + } + + let body = request.call(); let body = body .map_err(|x| { @@ -467,7 +482,10 @@ mod tests { #[cfg(feature = "integration")] fn conformance_http_get_tags() { crate::metrics::init(); - let reg = HttpRegistry::new(vec![]); + let reg = HttpRegistry::new(vec![AuthInfo { + host: "registry.hub.docker.com".to_string(), + credentials: Credentials::Anonymous, + }]); test_http_get_tags(®); } @@ -475,7 +493,10 @@ mod tests { #[cfg(feature = "integration")] fn conformance_http_get_digest() { crate::metrics::init(); - let reg = HttpRegistry::new(vec![]); + let reg = HttpRegistry::new(vec![AuthInfo { + host: "registry.hub.docker.com".to_string(), + credentials: Credentials::Anonymous, + }]); test_http_get_digest(®); } } |
