From 6b4d2ee914680f497de4d0c9107d5d5245731a09 Mon Sep 17 00:00:00 2001 From: Anderson Toshiyuki Sasaki Date: Fri, 22 Mar 2024 17:40:30 +0100 Subject: [PATCH] config: Support IPv6 with or without brackets This adds support to use IPv6 in configuraton file with or without brackets. The brackets are removed when the IP is parsed and added back when necessary. This also fix the addition of IPv6 addresses to the mTLS certificate in Subject Alternative Name extension. Fixes: #583 Fixes: #753 Fixes: #755 Signed-off-by: Anderson Toshiyuki Sasaki --- keylime-agent/src/config.rs | 21 +++++++++++++++------ keylime-agent/src/error.rs | 4 ++++ keylime-agent/src/main.rs | 9 ++++++++- keylime-agent/src/registrar_agent.rs | 25 +++++++++++++++++++++---- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/keylime-agent/src/config.rs b/keylime-agent/src/config.rs index 9e254fbf8..45e374bf4 100644 --- a/keylime-agent/src/config.rs +++ b/keylime-agent/src/config.rs @@ -9,6 +9,7 @@ use config::{ use glob::glob; use keylime::{ algorithms::{EncryptionAlgorithm, HashAlgorithm, SignAlgorithm}, + ip_parser::parse_ip, list_parser::parse_list, }; use log::*; @@ -806,6 +807,11 @@ fn config_translate_keywords( s => s.to_string(), }; + let ip = parse_ip(config.agent.ip.as_ref())?.to_string(); + let contact_ip = parse_ip(config.agent.contact_ip.as_ref())?.to_string(); + let registrar_ip = + parse_ip(config.agent.registrar_ip.as_ref())?.to_string(); + // Validate the configuration // If revocation notifications is enabled, verify all the required options for revocation @@ -837,17 +843,20 @@ fn config_translate_keywords( Ok(KeylimeConfig { agent: AgentConfig { keylime_dir: keylime_dir.display().to_string(), - uuid, - server_key, - server_cert, + agent_data_path, + contact_ip, + ek_handle, iak_cert, idevid_cert, - trusted_client_ca, - ek_handle, - agent_data_path, ima_ml_path, + ip, measuredboot_ml_path, + registrar_ip, revocation_cert, + server_cert, + server_key, + trusted_client_ca, + uuid, ..config.agent.clone() }, }) diff --git a/keylime-agent/src/error.rs b/keylime-agent/src/error.rs index 5b41d98af..73bbc1a1e 100644 --- a/keylime-agent/src/error.rs +++ b/keylime-agent/src/error.rs @@ -41,8 +41,12 @@ pub(crate) enum Error { Glob(#[from] glob::GlobError), #[error("Glob pattern error")] GlobPattern(#[from] glob::PatternError), + #[error("Invalid IP: {0}")] + InvalidIP(#[from] std::net::AddrParseError), #[error("IO error: {0}")] Io(#[from] std::io::Error), + #[error("Failed to parse IP")] + IpParserError(#[from] keylime::ip_parser::IpParsingError), #[error("Text decoding error: {0}")] Utf8(#[from] std::string::FromUtf8Error), #[error("Secure Mount error: {0})")] diff --git a/keylime-agent/src/main.rs b/keylime-agent/src/main.rs index 2542339ee..d117987da 100644 --- a/keylime-agent/src/main.rs +++ b/keylime-agent/src/main.rs @@ -68,6 +68,7 @@ use std::{ convert::TryFrom, fs, io::{BufReader, Read, Write}, + net::IpAddr, path::{Path, PathBuf}, str::FromStr, sync::Mutex, @@ -913,7 +914,13 @@ async fn main() -> Result<()> { .disable_signals(); let server; - let ip = &config.agent.ip; + + // Add bracket if IPv6 + let ip = if config.agent.ip.parse::()?.is_ipv6() { + format!("[{}]", config.agent.ip) + } else { + config.agent.ip.to_string() + }; let port = config.agent.port; if config.agent.enable_agent_mtls && ssl_context.is_some() { server = actix_server diff --git a/keylime-agent/src/registrar_agent.rs b/keylime-agent/src/registrar_agent.rs index 172d958d7..aca5a3419 100644 --- a/keylime-agent/src/registrar_agent.rs +++ b/keylime-agent/src/registrar_agent.rs @@ -6,6 +6,7 @@ use log::*; use openssl::x509::X509; use serde::{Deserialize, Serialize}; use serde_json::Number; +use std::net::IpAddr; fn is_empty(buf: &[u8]) -> bool { buf.is_empty() @@ -83,12 +84,20 @@ pub(crate) async fn do_activate_agent( ) -> crate::error::Result<()> { let data = Activate { auth_tag }; + // Add brackets if the address is IPv6 + let parsed_ip = registrar_ip.parse::()?; + let remote_ip = if parsed_ip.is_ipv6() { + format!("[{registrar_ip}]") + } else { + registrar_ip.to_string() + }; + #[cfg(test)] - let addr = format!("http://{registrar_ip}:{registrar_port}"); + let addr = format!("http://{remote_ip}:{registrar_port}"); #[cfg(not(test))] let addr = format!( - "http://{registrar_ip}:{registrar_port}/{API_VERSION}/agents/{agent_uuid}" + "http://{remote_ip}:{registrar_port}/{API_VERSION}/agents/{agent_uuid}" ); info!( @@ -164,12 +173,20 @@ pub(crate) async fn do_register_agent( port: Some(port), }; + // Add brackets if the address is IPv6 + let parsed_ip = registrar_ip.parse::()?; + let remote_ip = if parsed_ip.is_ipv6() { + format!("[{registrar_ip}]") + } else { + registrar_ip.to_string() + }; + #[cfg(test)] - let addr = format!("http://{registrar_ip}:{registrar_port}"); + let addr = format!("http://{remote_ip}:{registrar_port}"); #[cfg(not(test))] let addr = format!( - "http://{registrar_ip}:{registrar_port}/{API_VERSION}/agents/{agent_uuid}" + "http://{remote_ip}:{registrar_port}/{API_VERSION}/agents/{agent_uuid}" ); info!(