in src/enclave_proc/mod.rs [253:417]
fn handle_command(
cmd: EnclaveProcessCommandType,
logger: &EnclaveProcLogWriter,
connection: &Connection,
conn_listener: &mut ConnectionListener,
enclave_manager: &mut EnclaveManager,
terminate_thread: &mut Option<std::thread::JoinHandle<()>>,
describe_thread: &mut DescribeThread,
) -> NitroCliResult<(i32, bool)> {
Ok(match cmd {
EnclaveProcessCommandType::Run => {
// We should never receive a Run command if we are already running.
if !enclave_manager.enclave_id.is_empty() {
(libc::EEXIST, false)
} else {
let run_args = connection.read::<RunEnclavesArgs>().map_err(|e| {
e.add_subaction("Failed to get run arguments".to_string())
.set_action("Run Enclave".to_string())
})?;
info!("Run args = {:?}", run_args);
let run_result = run_enclaves(&run_args, Some(connection)).map_err(|e| {
e.add_subaction("Failed to trigger enclave run".to_string())
.set_action("Run Enclave".to_string())
})?;
*enclave_manager = run_result.enclave_manager;
*describe_thread = run_result.describe_thread;
info!("Enclave ID = {}", enclave_manager.enclave_id);
logger
.update_logger_id(&get_logger_id(&enclave_manager.enclave_id))
.map_err(|e| e.set_action("Failed to update logger ID".to_string()))?;
conn_listener
.start(&enclave_manager.enclave_id)
.map_err(|e| {
e.set_action("Failed to start connection listener thread".to_string())
})?;
// Add the enclave descriptor to epoll to listen for enclave events.
let enc_fd = enclave_manager
.get_enclave_descriptor()
.map_err(|e| e.set_action("Failed to get enclave descriptor".to_string()))?;
conn_listener
.register_enclave_descriptor(enc_fd)
.map_err(|e| {
e.set_action("Failed to register enclave descriptor".to_string())
})?;
(0, false)
}
}
EnclaveProcessCommandType::Terminate => {
*terminate_thread = Some(
notify_terminate(connection.clone(), conn_listener, enclave_manager.clone())
.map_err(|e| {
e.set_action("Failed to send enclave termination request".to_string())
})?,
);
(0, false)
}
EnclaveProcessCommandType::TerminateComplete => {
info!("Enclave has completed termination.");
(0, true)
}
EnclaveProcessCommandType::GetEnclaveCID => {
let enclave_cid = enclave_manager
.get_console_resources_enclave_cid()
.map_err(|e| {
e.set_action("Failed to get console resources (enclave CID)".to_string())
})?;
connection.write_u64(enclave_cid).map_err(|e| {
e.add_subaction("Failed to write enclave CID to connection".to_string())
.set_action("Get Enclave CID".to_string())
})?;
(0, false)
}
EnclaveProcessCommandType::GetEnclaveFlags => {
let enclave_flags = enclave_manager
.get_console_resources_enclave_flags()
.map_err(|e| {
e.set_action("Failed to get console resources (enclave flags)".to_string())
})?;
connection.write_u64(enclave_flags).map_err(|e| {
e.add_subaction("Failed to write enclave flags to connection".to_string())
.set_action("Get Enclave Flags".to_string())
})?;
(0, false)
}
EnclaveProcessCommandType::GetEnclaveName => {
connection.write_u64(MSG_ENCLAVE_CONFIRM).map_err(|e| {
e.add_subaction("Failed to write confirmation".to_string())
.set_action("Get Enclave Name".to_string())
})?;
safe_conn_println(
Some(connection),
serde_json::to_string_pretty(&enclave_manager.enclave_name)
.map_err(|err| {
new_nitro_cli_failure!(
&format!("Failed to write enclave name to connection: {:?}", err),
NitroCliErrorEnum::SerdeError
)
})?
.as_str(),
)?;
(0, false)
}
EnclaveProcessCommandType::GetIDbyName => {
connection.write_u64(MSG_ENCLAVE_CONFIRM).map_err(|e| {
e.add_subaction("Failed to write confirmation".to_string())
.set_action("Name to ID".to_string())
})?;
let name = connection.read::<String>().map_err(|e| {
e.add_subaction("Failed to get enclave name".to_string())
.set_action("Name to ID".to_string())
})?;
// Respond only if the current enclave name matches
if enclave_manager.enclave_name == name {
safe_conn_println(
Some(connection),
serde_json::to_string_pretty(&enclave_manager.enclave_id)
.map_err(|err| {
new_nitro_cli_failure!(
&format!("Failed to display RunEnclaves data: {:?}", err),
NitroCliErrorEnum::SerdeError
)
})?
.as_str(),
)?;
}
(0, false)
}
EnclaveProcessCommandType::Describe => {
let describe_args = connection.read::<DescribeEnclavesArgs>().map_err(|e| {
e.add_subaction("Failed to get describe arguments".to_string())
.set_action("Describe Enclave".to_string())
})?;
connection.write_u64(MSG_ENCLAVE_CONFIRM).map_err(|e| {
e.add_subaction("Failed to write confirmation".to_string())
.set_action("Describe Enclaves".to_string())
})?;
// Evaluate describe thread result if needed
fetch_describe_result(describe_thread, enclave_manager)?;
describe_enclaves(enclave_manager, connection, describe_args.metadata).map_err(
|e| {
e.add_subaction("Failed to describe enclave".to_string())
.set_action("Describe Enclaves".to_string())
},
)?;
(0, false)
}
EnclaveProcessCommandType::ConnectionListenerStop => (0, true),
EnclaveProcessCommandType::NotPermitted => (libc::EACCES, false),
})
}