Skip to content

Commit 6087147

Browse files
committed
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 <[email protected]>
1 parent d838630 commit 6087147

File tree

4 files changed

+48
-12
lines changed

4 files changed

+48
-12
lines changed

keylime-agent/src/config.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use config::{
99
use glob::glob;
1010
use keylime::{
1111
algorithms::{EncryptionAlgorithm, HashAlgorithm, SignAlgorithm},
12+
ip_parser::parse_ip,
1213
list_parser::parse_list,
1314
};
1415
use log::*;
@@ -806,6 +807,11 @@ fn config_translate_keywords(
806807
s => s.to_string(),
807808
};
808809

810+
let ip = parse_ip(config.agent.ip.as_ref())?.to_string();
811+
let contact_ip = parse_ip(config.agent.contact_ip.as_ref())?.to_string();
812+
let registrar_ip =
813+
parse_ip(config.agent.registrar_ip.as_ref())?.to_string();
814+
809815
// Validate the configuration
810816

811817
// If revocation notifications is enabled, verify all the required options for revocation
@@ -837,17 +843,20 @@ fn config_translate_keywords(
837843
Ok(KeylimeConfig {
838844
agent: AgentConfig {
839845
keylime_dir: keylime_dir.display().to_string(),
840-
uuid,
841-
server_key,
842-
server_cert,
846+
agent_data_path,
847+
contact_ip,
848+
ek_handle,
843849
iak_cert,
844850
idevid_cert,
845-
trusted_client_ca,
846-
ek_handle,
847-
agent_data_path,
848851
ima_ml_path,
852+
ip,
849853
measuredboot_ml_path,
854+
registrar_ip,
850855
revocation_cert,
856+
server_cert,
857+
server_key,
858+
trusted_client_ca,
859+
uuid,
851860
..config.agent.clone()
852861
},
853862
})

keylime-agent/src/error.rs

+4
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,12 @@ pub(crate) enum Error {
4141
Glob(#[from] glob::GlobError),
4242
#[error("Glob pattern error")]
4343
GlobPattern(#[from] glob::PatternError),
44+
#[error("Invalid IP: {0}")]
45+
InvalidIP(#[from] std::net::AddrParseError),
4446
#[error("IO error: {0}")]
4547
Io(#[from] std::io::Error),
48+
#[error("Failed to parse IP")]
49+
IpParserError(#[from] keylime::ip_parser::IpParsingError),
4650
#[error("Text decoding error: {0}")]
4751
Utf8(#[from] std::string::FromUtf8Error),
4852
#[error("Secure Mount error: {0})")]

keylime-agent/src/main.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ use std::{
6868
convert::TryFrom,
6969
fs,
7070
io::{BufReader, Read, Write},
71+
net::IpAddr,
7172
path::{Path, PathBuf},
7273
str::FromStr,
7374
sync::Mutex,
@@ -913,7 +914,13 @@ async fn main() -> Result<()> {
913914
.disable_signals();
914915

915916
let server;
916-
let ip = &config.agent.ip;
917+
918+
// Add bracket if IPv6
919+
let ip = if config.agent.ip.parse::<IpAddr>()?.is_ipv6() {
920+
format!("[{}]", config.agent.ip)
921+
} else {
922+
config.agent.ip.to_string()
923+
};
917924
let port = config.agent.port;
918925
if config.agent.enable_agent_mtls && ssl_context.is_some() {
919926
server = actix_server

keylime-agent/src/registrar_agent.rs

+21-5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use log::*;
66
use openssl::x509::X509;
77
use serde::{Deserialize, Serialize};
88
use serde_json::Number;
9+
use std::net::IpAddr;
910

1011
fn is_empty(buf: &[u8]) -> bool {
1112
buf.is_empty()
@@ -83,12 +84,20 @@ pub(crate) async fn do_activate_agent(
8384
) -> crate::error::Result<()> {
8485
let data = Activate { auth_tag };
8586

87+
// Add brackets if the address is IPv6
88+
let parsed_ip = registrar_ip.parse::<IpAddr>()?;
89+
let remote_ip = if parsed_ip.is_ipv6() {
90+
format!("[{registrar_ip}]")
91+
} else {
92+
registrar_ip.to_string()
93+
};
94+
8695
#[cfg(test)]
87-
let addr = format!("http://{registrar_ip}:{registrar_port}");
96+
let addr = format!("http://{remote_ip}:{registrar_port}");
8897

8998
#[cfg(not(test))]
9099
let addr = format!(
91-
"http://{registrar_ip}:{registrar_port}/{API_VERSION}/agents/{agent_uuid}"
100+
"http://{remote_ip}:{registrar_port}/{API_VERSION}/agents/{agent_uuid}"
92101
);
93102

94103
info!(
@@ -164,12 +173,20 @@ pub(crate) async fn do_register_agent(
164173
port: Some(port),
165174
};
166175

176+
// Add brackets if the address is IPv6
177+
let parsed_ip = registrar_ip.parse::<IpAddr>()?;
178+
let remote_ip = if parsed_ip.is_ipv6() {
179+
format!("[{registrar_ip}]")
180+
} else {
181+
registrar_ip.to_string()
182+
};
183+
167184
#[cfg(test)]
168-
let addr = format!("http://{registrar_ip}:{registrar_port}");
185+
let addr = format!("http://{remote_ip}:{registrar_port}");
169186

170187
#[cfg(not(test))]
171188
let addr = format!(
172-
"http://{registrar_ip}:{registrar_port}/{API_VERSION}/agents/{agent_uuid}"
189+
"http://{remote_ip}:{registrar_port}/{API_VERSION}/agents/{agent_uuid}"
173190
);
174191

175192
info!(
@@ -203,7 +220,6 @@ pub(crate) async fn do_register_agent(
203220
#[cfg(test)]
204221
mod tests {
205222
use super::*;
206-
use crate::crypto;
207223
use keylime::crypto;
208224
use wiremock::matchers::{any, method};
209225
use wiremock::{Mock, MockServer, ResponseTemplate};

0 commit comments

Comments
 (0)