From e19f4b805366e26d31275e9cb295c6e7bdab52b7 Mon Sep 17 00:00:00 2001 From: Erdem Meydanli Date: Thu, 21 Mar 2024 21:13:52 +0000 Subject: [PATCH] enclave_build: Extract parse_docker_host method Extract parse_docker_host method from get_credentials for reusability. Signed-off-by: Erdem Meydanli --- enclave_build/src/docker.rs | 95 +++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 46 deletions(-) diff --git a/enclave_build/src/docker.rs b/enclave_build/src/docker.rs index 4098b17d..dd225abc 100644 --- a/enclave_build/src/docker.rs +++ b/enclave_build/src/docker.rs @@ -63,67 +63,70 @@ impl DockerUtil { }) } - /// Returns the credentials by reading ${HOME}/.docker/config.json or ${DOCKER_CONFIG} - /// - /// config.json doesn't seem to have a schema that we could use to validate - /// we are parsing it correctly, so the parsing mechanism had been infered by - /// reading a config.json created by: - // Docker version 19.03.2 - fn get_credentials(&self) -> Result { - let image = self.docker_image.clone(); - let host = if let Ok(uri) = Url::parse(&image) { + fn parse_docker_host(docker_image: &str) -> Option { + if let Ok(uri) = Url::parse(docker_image) { uri.host().map(|s| s.to_string()) } else { // Some Docker URIs don't have the protocol included, so just use // a dummy one to trick Url that it's a properly defined Uri. - let uri = format!("dummy://{image}"); + let uri = format!("dummy://{docker_image}"); if let Ok(uri) = Url::parse(&uri) { uri.host().map(|s| s.to_string()) } else { None } + } + } + /// Returns the credentials by reading ${HOME}/.docker/config.json or ${DOCKER_CONFIG} + /// + /// config.json doesn't seem to have a schema that we could use to validate + /// we are parsing it correctly, so the parsing mechanism had been infered by + /// reading a config.json created by: + // Docker version 19.03.2 + fn get_credentials(&self) -> Result { + let host = match Self::parse_docker_host(&self.docker_image) { + Some(host) => host, + None => return Err(CredentialsError("Invalid docker image URI!".to_string())), }; - if let Some(registry_domain) = host { - let config_file = self.get_config_file()?; - - let config_json: serde_json::Value = serde_json::from_reader(&config_file) - .map_err(|err| CredentialsError(format!("JSON was not well-formatted: {err}")))?; - - let auths = config_json.get("auths").ok_or_else(|| { - CredentialsError("Could not find auths key in config JSON".to_string()) - })?; + let config_file = self.get_config_file()?; - if let Value::Object(auths) = auths { - for (registry_name, registry_auths) in auths.iter() { - if !registry_name.to_string().contains(®istry_domain) { - continue; - } + let config_json: serde_json::Value = serde_json::from_reader(&config_file) + .map_err(|err| CredentialsError(format!("JSON was not well-formatted: {err}")))?; - let auth = registry_auths - .get("auth") - .ok_or_else(|| { - CredentialsError("Could not find auth key in config JSON".to_string()) - })? - .to_string(); + let auths = config_json.get("auths").ok_or_else(|| { + CredentialsError("Could not find auths key in config JSON".to_string()) + })?; - let auth = auth.replace('"', ""); - let decoded = general_purpose::STANDARD.decode(auth).map_err(|err| { - CredentialsError(format!("Invalid Base64 encoding for auth: {err}")) - })?; - let decoded = std::str::from_utf8(&decoded).map_err(|err| { - CredentialsError(format!("Invalid utf8 encoding for auth: {err}")) - })?; + if let Value::Object(auths) = auths { + for (registry_name, registry_auths) in auths.iter() { + if !registry_name.to_string().contains(&host) { + continue; + } - if let Some(index) = decoded.rfind(':') { - let (user, after_user) = decoded.split_at(index); - let (_, password) = after_user.split_at(1); - return Ok(DockerCredentials { - username: Some(user.to_string()), - password: Some(password.to_string()), - ..Default::default() - }); - } + let auth = registry_auths + .get("auth") + .ok_or_else(|| { + CredentialsError("Could not find auth key in config JSON".to_string()) + })? + .to_string(); + + let auth = auth.replace('"', ""); + let decoded = general_purpose::STANDARD.decode(auth).map_err(|err| { + CredentialsError(format!("Invalid Base64 encoding for auth: {err}")) + })?; + let decoded = std::str::from_utf8(&decoded).map_err(|err| { + CredentialsError(format!("Invalid utf8 encoding for auth: {err}")) + })?; + + if let Some(index) = decoded.rfind(':') { + let (user, after_user) = decoded.split_at(index); + let (_, password) = after_user.split_at(1); + return Ok(DockerCredentials { + username: Some(user.to_string()), + password: Some(password.to_string()), + ..Default::default() + }); } } }