Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions keylime-agent/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,10 +623,24 @@ async fn main() -> Result<()> {
ak_handle,
retry_config: None,
};
use keylime::error::Error;
use keylime::registrar_client::RegistrarClientError;

match keylime::agent_registration::register_agent(aa, &mut ctx).await {
Ok(()) => (),
Err(Error::RegistrarClient(
RegistrarClientError::RegistrationForbidden { message },
)) => {
error!("Failed to register agent: Registration forbidden - {message}");
error!("This indicates a security rejection (403 Forbidden), likely due to TPM identity mismatch or UUID spoofing attempt.");
error!("The existing agent record must be deleted before re-registering with a different TPM.");
return Err(Error::RegistrarClient(
RegistrarClientError::RegistrationForbidden { message },
));
}
Err(e) => {
error!("Failed to register agent: {e:?}");
error!("Registration failed with a non-security error. The agent will continue but may have degraded functionality.");
}
}

Expand Down
10 changes: 10 additions & 0 deletions keylime/src/config/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,10 @@ impl Drop for TestConfigGuard {
mod tests {
use super::*;
use std::collections::HashMap;
use std::sync::Mutex;

// Mutex to ensure tests that modify global TESTING_CONFIG_OVERRIDE run serially
static TEST_MUTEX: Mutex<()> = Mutex::new(());

#[test]
fn test_get_testing_config() {
Expand Down Expand Up @@ -288,6 +292,9 @@ mod tests {

#[test]
fn test_testing_config_override() {
// Acquire mutex to prevent concurrent access to global state
let _lock = TEST_MUTEX.lock().unwrap(); //#[allow_ci]

// Clear any existing override
clear_testing_config_override();

Expand Down Expand Up @@ -330,6 +337,9 @@ mod tests {

#[test]
fn test_testconfig_guard_automatic_cleanup() {
// Acquire mutex to prevent concurrent access to global state
let _lock = TEST_MUTEX.lock().unwrap(); //#[allow_ci]

// Clear any existing override
clear_testing_config_override();

Expand Down
34 changes: 34 additions & 0 deletions keylime/src/registrar_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,10 @@ pub enum RegistrarClientError {
#[error("Failed to register agent: received {code} from {addr}")]
Registration { addr: String, code: u16 },

/// Registration forbidden - TPM identity mismatch or security rejection
#[error("Registration forbidden: {message}. This may indicate a TPM identity change or UUID spoofing attempt. The existing agent record must be deleted before re-registering with a different TPM.")]
RegistrationForbidden { message: String },

/// Reqwest error
#[error("Reqwest error: {0}")]
Reqwest(#[from] reqwest::Error),
Expand Down Expand Up @@ -387,6 +391,16 @@ impl RegistrarClient {
};

if !resp.status().is_success() {
// Check if this is a 403 Forbidden - indicates security rejection
if resp.status() == StatusCode::FORBIDDEN {
let error_message = resp
.text()
.await
.unwrap_or_else(|_| "Unknown error".to_string());
return Err(RegistrarClientError::RegistrationForbidden {
message: error_message,
});
}
return Err(RegistrarClientError::Registration {
addr,
code: resp.status().as_u16(),
Expand Down Expand Up @@ -438,6 +452,15 @@ impl RegistrarClient {
info!("Trying to register agent using API version {api_version}");
let r = self.try_register_agent(ai, api_version).await;

// Check if this is a security rejection (403 Forbidden)
// If so, return immediately - don't try other API versions
if let Err(RegistrarClientError::RegistrationForbidden {
..
}) = r
{
return r;
}

// If successful, cache the API version for future requests
if r.is_ok() {
self.api_version = api_version.to_string();
Expand All @@ -458,6 +481,17 @@ impl RegistrarClient {
let r =
self.try_register_agent(ai, api_version).await;

// Check if this is a security rejection (403 Forbidden)
// If so, return immediately - don't try other API versions
if let Err(
RegistrarClientError::RegistrationForbidden {
..
},
) = r
{
return r;
}

// If successful, cache the API version for future requests
if r.is_ok() {
self.api_version = api_version.to_string();
Expand Down