summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs19
-rw-r--r--src/registry.rs47
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(&reg);
}
@@ -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(&reg);
}
}