Update to upstream version 0.1.0

Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
This commit is contained in:
Anderson Toshiyuki Sasaki 2022-11-01 16:32:38 +01:00
parent c66421c405
commit 72e12733c3
10 changed files with 76 additions and 677 deletions

2
.gitignore vendored
View File

@ -4,3 +4,5 @@
/rust-keylime-0.1.0~20220602gitc98e381.tar.gz
/rust-keylime-0.1.0~20220603gitaed51c7.tar.gz
/rust-keylime-0.1.0~20220603gitaed51c7-vendor.tar.xz
/v0.1.0.tar.gz
/rust-keylime-0.1.0-vendor.tar.xz

View File

@ -4,11 +4,6 @@
%bcond_without check
%global crate keylime_agent
%global crate_version 0.1.0
%global commit aed51c7c8c526953e945357594352c3df2ca4ace
%global shortcommit %(c=%{commit}; echo ${c:0:7})
%global commitdate 20220603
%if 0%{?rhel}
# RHEL: Use bundled deps as it doesn't ship Rust libraries
@ -19,7 +14,7 @@
%endif
Name: keylime-agent-rust
Version: %{crate_version}~%{commitdate}git%{shortcommit}
Version: 0.1.0
Release: %{?autorelease}%{!?autorelease:1%{?dist}}
Summary: Rust agent for Keylime
@ -44,32 +39,29 @@ License: ASL 2.0 and BSD and MIT
URL: https://github.com/keylime/rust-keylime/
# The source tarball is downloaded using the following commands:
# spectool -g keylime-agent-rust.spec
Source0: %{url}/archive/%{commit}/rust-keylime-%{version}.tar.gz
# The vendor tarball is created using cargo vendor:
Source0: %{url}/archive/refs/tags/v%{version}.tar.gz
# The vendor tarball is created using cargo-vendor-filterer to remove Windows
# related files (https://github.com/cgwalters/cargo-vendor-filterer)
# tar xf rust-keylime-%%{version}.tar.gz
# cd rust-keylime-%%{version}
# cargo vendor
# cargo vendor-filterer --platform x86_64-unknown-linux-gnu \
# --platform powerpc64le-unknown-linux-gnu \
# --platform aarch64-unknown-linux-gnu \
# --platform i686-unknown-linux-gnu \
# --platform s390x-unknown-linux-gnu \
# --exclude-crate-path "libloading#tests"
# tar jcf rust-keylime-%%{version}-vendor.tar.xz vendor
Source1: rust-keylime-%{version}-vendor.tar.xz
# Drop rustc-serialize and flate2, update clap, and make wiremock optional
Patch0: rust-keylime-drop-dependencies.patch
# Add serialization functions to fix issue on big-endian arches
Patch1: rust-keylime-add-quote-serialization.patch
# Show path on missing mTLS certificate
Patch2: rust-keylime-show-path-missing-cert.patch
# Use more descriptive error messages for missing files errors
Patch3: rust-keylime-descriptive-error-messages.patch
# Set supplementary groups when dropping privileges
Patch4: rust-keylime-set-supplementary-groups.patch
# Fix version requirement for clap to avoid FTBFS in Fedora
Patch5: rust-keylime-metadata.patch
Patch1: rust-keylime-metadata.patch
# Use API available on rust-config-0.12.0
Patch2: rust-keylime-config-separator.patch
ExclusiveArch: %{rust_arches}
Requires: tpm2-tss
# The keylime-base package provides the configuration file from the python
# implementation which can be used for the rust implementation. It is available
# The keylime-base package provides the keylime user creation. It is available
# from Fedora 36
%if 0%{?fedora} >= 36
Requires: keylime-base
@ -93,7 +85,7 @@ Conflicts: keylime-agent
Rust agent for Keylime
%prep
%autosetup -n rust-keylime-%{commit} -p1
%autosetup -n rust-keylime-%{version} -p1
%if 0%{?bundled_rust_deps}
# Source1 is vendored dependencies
%cargo_prep -V 1
@ -113,6 +105,11 @@ mkdir -p %{buildroot}/%{_sharedstatedir}/keylime
mkdir -p --mode=0700 %{buildroot}/%{_rundir}/keylime
mkdir -p --mode=0700 %{buildroot}/%{_localstatedir}/log/keylime
mkdir -p --mode=0700 %{buildroot}/%{_libexecdir}/keylime
mkdir -p --mode=0700 %{buildroot}/%{_sysconfdir}/keylime
mkdir -p --mode=0700 %{buildroot}/%{_sysconfdir}/keylime/agent.conf.d
install -Dpm 400 keylime-agent.conf \
%{buildroot}%{_sysconfdir}/keylime/agent.conf
install -Dpm 644 ./dist/systemd/system/keylime_agent.service \
%{buildroot}%{_unitdir}/keylime_agent.service
@ -120,6 +117,18 @@ install -Dpm 644 ./dist/systemd/system/keylime_agent.service \
install -Dpm 644 ./dist/systemd/system/var-lib-keylime-secure.mount \
%{buildroot}%{_unitdir}/var-lib-keylime-secure.mount
# Setting up the agent to use keylime:keylime user/group after dropping privileges.
cat > %{buildroot}/%{_sysconfdir}/keylime/agent.conf.d/001-run_as.conf << EOF
[agent]
run_as = "keylime:keylime"
EOF
%posttrans
chmod 500 %{_sysconfdir}/keylime/agent.conf.d
chmod 400 %{_sysconfdir}/keylime/agent.conf.d/*.conf
chmod 500 %{_sysconfdir}/keylime
chown -R keylime:keylime %{_sysconfdir}/keylime
%preun
%systemd_preun keylime_agent.service
%systemd_preun var-lib-keylime-secure.mount
@ -131,6 +140,10 @@ install -Dpm 644 ./dist/systemd/system/var-lib-keylime-secure.mount \
%files
%license LICENSE
%doc README.md
%attr(500,keylime,keylime) %dir %{_sysconfdir}/keylime
%attr(500,keylime,keylime) %dir %{_sysconfdir}/keylime/agent.conf.d
%config(noreplace) %attr(400,keylime,keylime) %{_sysconfdir}/keylime/agent.conf.d/001-run_as.conf
%config(noreplace) %attr(400,keylime,keylime) %{_sysconfdir}/keylime/agent.conf
%{_unitdir}/keylime_agent.service
%{_unitdir}/var-lib-keylime-secure.mount
%attr(700,keylime,keylime) %dir %{_rundir}/keylime

View File

@ -1,217 +0,0 @@
From 423f7337d991ec5085914a361e68260bdd513ac6 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Mon, 20 Jun 2022 11:51:46 +0200
Subject: [PATCH] tpm: Add serialization functions for structures in quotes
Add serialization and deserialization functions for the data in quotes
to avoid endianness issues when the arch is big-endian.
The added serialization and deserialization functions will convert the
data endianness as necessary.
Note: the official marshalling and unmarshalling functions cannot be
used directly because the tpm2-tools uses a custom format.
Fixes: #407
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
---
src/tpm.rs | 139 +++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 107 insertions(+), 32 deletions(-)
diff --git a/src/tpm.rs b/src/tpm.rs
index 9002c29..5521892 100644
--- a/src/tpm.rs
+++ b/src/tpm.rs
@@ -52,15 +52,20 @@ use tss_esapi::{
tss2_esys::{
Tss2_MU_TPM2B_PUBLIC_Marshal, Tss2_MU_TPMS_ATTEST_Marshal,
Tss2_MU_TPMS_ATTEST_Unmarshal, Tss2_MU_TPMT_SIGNATURE_Marshal,
- TPM2B_ATTEST, TPM2B_PUBLIC, TPML_DIGEST, TPML_PCR_SELECTION,
- TPMS_ATTEST, TPMS_SCHEME_HASH, TPMT_SIGNATURE, TPMT_SIG_SCHEME,
- TPMU_SIG_SCHEME,
+ TPM2B_ATTEST, TPM2B_DIGEST, TPM2B_PUBLIC, TPML_DIGEST,
+ TPML_PCR_SELECTION, TPMS_ATTEST, TPMS_PCR_SELECTION,
+ TPMS_SCHEME_HASH, TPMT_SIGNATURE, TPMT_SIG_SCHEME, TPMU_SIG_SCHEME,
},
utils::TpmsContext,
Context,
};
pub const MAX_NONCE_SIZE: usize = 64;
+pub const TPML_DIGEST_SIZE: usize = std::mem::size_of::<TPML_DIGEST>();
+pub const TPML_PCR_SELECTION_SIZE: usize =
+ std::mem::size_of::<TPML_PCR_SELECTION>();
+pub const TPMS_PCR_SELECTION_SIZE: usize =
+ std::mem::size_of::<TPMS_PCR_SELECTION>();
/*
* Input: None
@@ -123,6 +128,95 @@ pub(crate) fn create_ek(
assert_eq_size!(TPML_PCR_SELECTION, [u8; 132]);
assert_eq_size!(TPML_DIGEST, [u8; 532]);
+// Serialize a TPML_PCR_SELECTION into a Vec<u8>
+// The serialization will adjust the data endianness as necessary and add paddings to keep the
+// memory aligment.
+pub(crate) fn serialize_pcrsel(
+ pcr_selection: &TPML_PCR_SELECTION,
+) -> Vec<u8> {
+ let mut output = Vec::with_capacity(TPML_PCR_SELECTION_SIZE);
+ output.extend(u32::to_le_bytes(pcr_selection.count));
+ for selection in pcr_selection.pcrSelections.iter() {
+ output.extend(selection.hash.to_le_bytes());
+ output.extend(selection.sizeofSelect.to_le_bytes());
+ output.extend(selection.pcrSelect);
+ output.extend([0u8; 1]); // padding to keep the memory alignment
+ }
+ output
+}
+
+// Deserialize a TPML_PCR_SELECTION from a &[u8] slice.
+// The deserialization will adjust the data endianness as necessary.
+pub(crate) fn deserialize_pcrsel(
+ pcrsel_vec: &[u8],
+) -> Result<TPML_PCR_SELECTION> {
+ if pcrsel_vec.len() != TPML_PCR_SELECTION_SIZE {
+ return Err(KeylimeError::InvalidRequest);
+ }
+
+ let mut reader = std::io::Cursor::new(pcrsel_vec);
+ let mut count_vec = [0u8; 4];
+ reader.read_exact(&mut count_vec)?;
+ let count = u32::from_le_bytes(count_vec);
+
+ let mut pcr_selections: [TPMS_PCR_SELECTION; 16] =
+ [TPMS_PCR_SELECTION::default(); 16];
+
+ for selection in &mut pcr_selections {
+ let mut hash_vec = [0u8; 2];
+ reader.read_exact(&mut hash_vec)?;
+ selection.hash = u16::from_le_bytes(hash_vec);
+
+ let mut size_vec = [0u8; 1];
+ reader.read_exact(&mut size_vec)?;
+ selection.sizeofSelect = u8::from_le_bytes(size_vec);
+
+ reader.read_exact(&mut selection.pcrSelect)?;
+ }
+
+ Ok(TPML_PCR_SELECTION {
+ count,
+ pcrSelections: pcr_selections,
+ })
+}
+
+// Serialize a TPML_DIGEST into a Vec<u8>
+// The serialization will adjust the data endianness as necessary.
+pub(crate) fn serialize_digest(digest_list: &TPML_DIGEST) -> Vec<u8> {
+ let mut output = Vec::with_capacity(TPML_DIGEST_SIZE);
+ output.extend(u32::to_le_bytes(digest_list.count));
+ for digest in digest_list.digests.iter() {
+ output.extend(digest.size.to_le_bytes());
+ output.extend(digest.buffer);
+ }
+ output
+}
+
+// Deserialize a TPML_DIGEST from a &[u8] slice.
+// The deserialization will adjust the data endianness as necessary.
+pub(crate) fn deserialize_digest(digest_vec: &[u8]) -> Result<TPML_DIGEST> {
+ if digest_vec.len() != TPML_DIGEST_SIZE {
+ return Err(KeylimeError::InvalidRequest);
+ }
+
+ let mut reader = std::io::Cursor::new(digest_vec);
+ let mut count_vec = [0u8; 4];
+
+ reader.read_exact(&mut count_vec)?;
+ let count = u32::from_le_bytes(count_vec);
+
+ let mut digests: [TPM2B_DIGEST; 8] = [TPM2B_DIGEST::default(); 8];
+
+ for digest in &mut digests {
+ let mut size_vec = [0u8; 2];
+ reader.read_exact(&mut size_vec)?;
+ digest.size = u16::from_le_bytes(size_vec);
+ reader.read_exact(&mut digest.buffer)?;
+ }
+
+ Ok(TPML_DIGEST { count, digests })
+}
+
// Recreate how tpm2-tools creates the PCR out file. Roughly, this is a
// TPML_PCR_SELECTION + number of TPML_DIGESTS + TPML_DIGESTs.
// Reference:
@@ -140,16 +234,14 @@ pub(crate) fn pcrdata_to_vec(
const DIGEST_SIZE: usize = std::mem::size_of::<TPML_DIGEST>();
let mut pcrsel: TPML_PCR_SELECTION = selection_list.into();
- pcrsel.count = pcrsel.count.to_le();
- let pcrsel_vec: [u8; PCRSEL_SIZE] =
- unsafe { std::mem::transmute(pcrsel) };
+ let pcrsel_vec = serialize_pcrsel(&pcrsel);
let digest: Vec<TPML_DIGEST> = pcrdata.into();
let num_tpml_digests = digest.len() as u32;
let mut digest_vec = Vec::with_capacity(digest.len() * DIGEST_SIZE);
for d in digest {
- let vec: [u8; DIGEST_SIZE] = unsafe { std::mem::transmute(d) };
+ let vec = serialize_digest(&d);
digest_vec.extend(vec);
}
@@ -665,41 +757,24 @@ pub mod testing {
);
fn vec_to_pcrdata(val: &[u8]) -> Result<(PcrSelectionList, PcrData)> {
- const PCRSEL_SIZE: usize = std::mem::size_of::<TPML_PCR_SELECTION>();
- const DIGEST_SIZE: usize = std::mem::size_of::<TPML_DIGEST>();
-
let mut reader = std::io::Cursor::new(val);
- let mut pcrsel_vec = [0u8; PCRSEL_SIZE];
- let len = reader.read(&mut pcrsel_vec)?;
- if len != pcrsel_vec.len() {
- return Err(KeylimeError::InvalidRequest);
- }
- let mut pcrsel = unsafe {
- std::mem::transmute::<[u8; PCRSEL_SIZE], TPML_PCR_SELECTION>(
- pcrsel_vec,
- )
- };
+ let mut pcrsel_vec = [0u8; TPML_PCR_SELECTION_SIZE];
+ reader.read_exact(&mut pcrsel_vec)?;
+
+ let pcrsel = deserialize_pcrsel(&pcrsel_vec)?;
let pcrlist: PcrSelectionList = pcrsel.try_into()?;
let mut count_vec = [0u8; 4];
- let len = reader.read(&mut count_vec)?;
- if len < count_vec.len() {
- return Err(KeylimeError::InvalidRequest);
- }
+ reader.read_exact(&mut count_vec)?;
let count = u32::from_le_bytes(count_vec);
// Always 1 PCR digest should follow
if count != 1 {
return Err(KeylimeError::InvalidRequest);
}
- let mut digest_vec = [0u8; DIGEST_SIZE];
- let len = reader.read(&mut digest_vec)?;
- if len != digest_vec.len() {
- return Err(KeylimeError::InvalidRequest);
- }
- let mut digest = unsafe {
- std::mem::transmute::<[u8; DIGEST_SIZE], TPML_DIGEST>(digest_vec)
- };
+ let mut digest_vec = [0u8; TPML_DIGEST_SIZE];
+ reader.read_exact(&mut digest_vec)?;
+ let digest = deserialize_digest(&digest_vec)?;
let mut digest_list = DigestList::new();
for i in 0..digest.count {
digest_list.add(digest.digests[i as usize].try_into()?);
--
2.35.3

View File

@ -0,0 +1,20 @@
--- a/src/config.rs 2022-11-01 14:47:42.702938017 +0100
+++ b/src/config.rs 2022-11-01 15:19:07.072122442 +0100
@@ -408,8 +408,7 @@
// Add environment variables overrides
.add_source(
Environment::with_prefix("KEYLIME")
- .separator("_")
- .prefix_separator("_"),
+ .separator("_"),
))
}
@@ -425,7 +424,6 @@
// Add environment variables overrides
.add_source(
Environment::with_prefix("KEYLIME")
- .prefix_separator("_")
.separator("_"),
));
} else {

View File

@ -1,43 +0,0 @@
From e20b936fc9d92ae05406cb86471d3e6fba823b7f Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Tue, 28 Jun 2022 13:47:38 +0200
Subject: [PATCH] main: Use more descriptive message for missing files error
Use more descriptive message when required paths are missing instead of
the generic message.
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
---
src/main.rs | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index 9404284..ef29eb2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -608,9 +608,22 @@ async fn main() -> Result<()> {
let payload = Arc::clone(&encr_payload_arc);
let revocation_cert = revocation::get_revocation_cert_path(&config)?;
- let actions_dir =
- Path::new(&config.revocation_actions_dir).canonicalize()?;
- let work_dir = Path::new(&config.work_dir).canonicalize()?;
+ let actions_dir = Path::new(&config.revocation_actions_dir)
+ .canonicalize()
+ .map_err(|e| {
+ Error::Configuration(format!(
+ "Path {} set in revocation_actions_dir not found: {}",
+ &config.revocation_actions_dir, e
+ ))
+ })?;
+
+ let work_dir =
+ Path::new(&config.work_dir).canonicalize().map_err(|e| {
+ Error::Configuration(format!(
+ "Path {} set in keylime_dir not found: {}",
+ &config.work_dir, e
+ ))
+ })?;
let quotedata = web::Data::new(QuoteData {
tpmcontext: Mutex::new(ctx),

View File

@ -1,193 +0,0 @@
From 9229cb4673aad2cae7605e66bdf2160716e1f694 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Thu, 9 Jun 2022 18:34:34 +0200
Subject: [PATCH 1/4] Update clap dependency to 3.1.18
This change replaces clap::App with clap::Command in main.rs file.
On commit f3fa925 the clap dependency in Cargo.lock file was updated
from version 3.0.14 to version 3.1.18.
In clap version 3.1.0, clap::App was deprecated in favor of
clap::Command. This causes warnings during the Keylime agent build due
to the usage of the deprecated structure.
To avoid similar issues in the future, use the tilde dependency version
requirement to allow versions >= 3.1.18 but < 3.2.0.
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
---
Cargo.lock | 76 ++++++++++++++++++++++-------------------------------
Cargo.toml | 2 +-
src/main.rs | 2 +-
3 files changed, 33 insertions(+), 47 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index 92f3974..f0c7d39 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,7 +21,7 @@ doc = false
actix-web = { version = "4", features = ["openssl"] }
base64 = "0.13"
cfg-if = "1"
-clap = { version = "3.0.14", features = ["derive"] }
+clap = { version = "~3.1.18", features = ["derive"] }
compress-tools = "0.12"
flate2 = "1.0.4"
futures = "0.3.6"
diff --git a/src/main.rs b/src/main.rs
index 1896104..8540597 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -51,7 +51,7 @@ mod tpm;
mod version_handler;
use actix_web::{dev::Service, http, middleware, rt, web, App, HttpServer};
-use clap::{App as ClapApp, Arg};
+use clap::{Arg, Command as ClapApp};
use common::*;
use compress_tools::*;
use error::{Error, Result};
--
2.35.3
From c61e3f389e4bde4d0a318a571c9b3dcf8a62749f Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Tue, 17 May 2022 18:31:01 +0200
Subject: [PATCH 2/4] Drop unused dependency rustc-serialize
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
---
Cargo.lock | 7 -------
Cargo.toml | 1 -
2 files changed, 8 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index f0c7d39..0f4e4ab 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -34,7 +34,6 @@ picky-asn1-x509 = "0.6.1"
pretty_env_logger = "0.4"
reqwest = {version = "0.11", features = ["json"]}
rust-ini = "0.17"
-rustc-serialize = "0.3.24"
serde = "1.0.80"
serde_derive = "1.0.80"
serde_json = { version = "1.0", features = ["raw_value"] }
--
2.35.3
From f7b59a6a7739d275ffe15a915eb48a36ceafccdd Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Tue, 17 May 2022 18:56:50 +0200
Subject: [PATCH 3/4] Drop unused dependency flate2
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
---
Cargo.lock | 1 -
Cargo.toml | 1 -
src/tpm.rs | 3 ---
3 files changed, 5 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index 0f4e4ab..69d2eec 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -23,7 +23,6 @@ base64 = "0.13"
cfg-if = "1"
clap = { version = "~3.1.18", features = ["derive"] }
compress-tools = "0.12"
-flate2 = "1.0.4"
futures = "0.3.6"
hex = "0.4"
libc = "0.2.43"
diff --git a/src/tpm.rs b/src/tpm.rs
index 355dd0d..43129f1 100644
--- a/src/tpm.rs
+++ b/src/tpm.rs
@@ -20,8 +20,6 @@ use openssl::{
pkey::{Id, PKeyRef, Public},
};
-use flate2::{write::ZlibEncoder, Compression};
-
use tss_esapi::{
abstraction::{
ak,
@@ -635,7 +633,6 @@ pub(crate) fn quote(
#[cfg(test)]
pub mod testing {
use super::*;
- use flate2::read::ZlibDecoder;
use tss_esapi::constants::structure_tags::StructureTag;
use tss_esapi::structures::{Attest, AttestBuffer, DigestList, Ticket};
use tss_esapi::tss2_esys::Tss2_MU_TPMT_SIGNATURE_Unmarshal;
--
2.35.3
From c3f0b4f603089d38715535f8e16b7a40f413e4de Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Thu, 9 Jun 2022 16:21:06 +0200
Subject: [PATCH 4/4] Make wiremock an optional dependency
Make a wiremock optional, enabled when the 'testing' feature is enabled.
The goal is to reduce the number of dependencies, with the downside that
the test code coverage will drop.
Wiremock is currently used only on 'registrar_agent' tests to mock
responses from the registrar service.
Note: wiremock was moved to be an optional regular dependency because
optional dev-dependencies are not supported.
see: https://github.com/rust-lang/cargo/issues/1596
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
---
Cargo.toml | 7 +++++--
src/registrar_agent.rs | 1 +
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
index 69d2eec..5052512 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -43,16 +43,19 @@ tss-esapi = "7.1.0"
thiserror = "1.0"
uuid = {version = "0.8", features = ["v4"]}
zmq = {version = "0.9.2", optional = true}
+# wiremock was moved to be a regular dependency because optional
+# dev-dependencies are not supported
+# see: https://github.com/rust-lang/cargo/issues/1596
+wiremock = {version = "0.5", optional = true}
[dev-dependencies]
actix-rt = "2"
-wiremock = "0.5"
[features]
# The features enabled by default
default = ["with-zmq", "legacy-python-actions"]
# this should change to dev-dependencies when we have integration testing
-testing = []
+testing = ["wiremock"]
# Whether the agent should be compiled with support to listen for notification
# messages on ZeroMQ
with-zmq = ["zmq"]
diff --git a/src/registrar_agent.rs b/src/registrar_agent.rs
index 85b5931..b02ba48 100644
--- a/src/registrar_agent.rs
+++ b/src/registrar_agent.rs
@@ -149,6 +149,7 @@ pub(crate) async fn do_register_agent(
}
}
+#[cfg(feature = "testing")]
#[cfg(test)]
mod tests {
use super::*;
--
2.35.3

View File

@ -1,25 +1,24 @@
From 360ac8eb65eb44d6a4217f75b94cdb14804df02e Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Fri, 5 Aug 2022 16:03:03 +0900
Subject: [PATCH] rust-keylime-metadata.patch
---
Cargo.toml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Cargo.toml b/Cargo.toml
index 933df5e..20edb8d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,7 +21,7 @@ doc = false
--- a/Cargo.toml 2022-11-01 11:14:11.349498931 +0100
+++ b/Cargo.toml 2022-11-01 14:22:01.934115151 +0100
@@ -21,17 +21,17 @@
actix-web = { version = "4", features = ["openssl"] }
base64 = "0.13"
cfg-if = "1"
-clap = { version = "~3.1.18", features = ["derive"] }
+clap = { version = "3.1.18", features = ["derive"] }
compress-tools = "0.12"
-config = { version = "0.13", features = ["toml"] }
+config = { version = "0.12", features = ["toml"] }
futures = "0.3.6"
glob = "0.3"
hex = "0.4"
--
2.37.1
libc = "0.2.43"
log = "0.4"
openssl = "0.10.15"
-picky-asn1-der = "0.3.1"
-picky-asn1-x509 = "0.6.1"
+picky-asn1-der = "0.3"
+picky-asn1-x509 = "0.7"
pretty_env_logger = "0.4"
reqwest = {version = "0.11", features = ["json"]}
rust-ini = "0.17"

View File

@ -1,162 +0,0 @@
From 4ec807b1bbcfaa67f85d0c2659b1f439c2f540b4 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Fri, 24 Jun 2022 16:25:54 +0200
Subject: [PATCH] permissions: Set supplementary groups when dropping
privileges
This allows the agent to run with the user primary group and have the
access given by the supplementary groups.
Fixes: #414
Signed-off-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
---
src/permissions.rs | 70 ++++++++++++++++++++++++++++++++++------------
1 file changed, 52 insertions(+), 18 deletions(-)
diff --git a/src/permissions.rs b/src/permissions.rs
index 279a6dd..86e3fae 100644
--- a/src/permissions.rs
+++ b/src/permissions.rs
@@ -2,7 +2,7 @@
// Copyright 2021 Keylime Authors
use crate::error::{Error, Result};
-use libc::{gid_t, uid_t};
+use libc::{c_char, c_int, gid_t, uid_t};
use log::*;
use std::os::unix::ffi::OsStrExt;
use std::{
@@ -13,10 +13,9 @@ use std::{
ptr,
};
-#[derive(Debug)]
pub(crate) struct UserIds {
- uid: uid_t,
- gid: gid_t,
+ passwd: libc::passwd,
+ group: libc::group,
}
pub(crate) fn get_gid() -> gid_t {
@@ -47,14 +46,14 @@ impl TryFrom<&str> for UserIds {
let group = parts[1];
// Get gid from group name
- let gid = if let Ok(g_cstr) = CString::new(group.as_bytes()) {
+ let grnam = if let Ok(g_cstr) = CString::new(group.as_bytes()) {
let p = unsafe { libc::getgrnam(g_cstr.as_ptr()) };
if p.is_null() {
let e = io::Error::last_os_error();
error!("Could not get group {}: {}", group, e);
return Err(Error::Conversion(e.to_string()));
}
- unsafe { (*p).gr_gid }
+ unsafe { (*p) }
} else {
return Err(Error::Conversion(format!(
"Failed to convert {} to CString",
@@ -63,14 +62,14 @@ impl TryFrom<&str> for UserIds {
};
// Get uid from user name
- let uid = if let Ok(u_cstr) = CString::new(user.as_bytes()) {
+ let passwd = if let Ok(u_cstr) = CString::new(user.as_bytes()) {
let p = unsafe { libc::getpwnam(u_cstr.as_ptr()) };
if p.is_null() {
let e = io::Error::last_os_error();
error!("Could not get user {}: {}", user, e);
return Err(Error::Conversion(e.to_string()));
}
- unsafe { (*p).pw_uid }
+ unsafe { (*p) }
} else {
return Err(Error::Conversion(format!(
"Failed to convert {} to CString",
@@ -78,7 +77,10 @@ impl TryFrom<&str> for UserIds {
)));
};
- Ok(UserIds { uid, gid })
+ Ok(UserIds {
+ passwd,
+ group: grnam,
+ })
}
}
@@ -88,22 +90,51 @@ impl TryFrom<&str> for UserIds {
pub(crate) fn run_as(user_group: &str) -> Result<()> {
let ids: UserIds = user_group.try_into()?;
- // Drop supplementary groups
- if unsafe { libc::setgroups(0, ptr::null()) } != 0 {
+ // Set gid
+ if unsafe { libc::setgid(ids.group.gr_gid) } != 0 {
let e = io::Error::last_os_error();
- error!("Could not drop supplementary groups: {}", e);
+ error!("Could not set group id: {}", e);
return Err(Error::Permission);
}
- // Set gid
- if unsafe { libc::setgid(ids.gid) } != 0 {
+ // Get list of supplementary groups
+ let mut sup_groups: [gid_t; 32] = [0u32; 32];
+ let mut ngroups: c_int = 32;
+ if unsafe {
+ libc::getgrouplist(
+ ids.passwd.pw_name,
+ ids.group.gr_gid,
+ sup_groups.as_mut_ptr(),
+ &mut ngroups,
+ )
+ } < 0
+ {
+ // Allocate a Vec and try again
+ let mut sup_groups: Vec<gid_t> = Vec::with_capacity(ngroups as usize);
+ if unsafe {
+ libc::getgrouplist(
+ ids.passwd.pw_name,
+ ids.group.gr_gid,
+ sup_groups.as_mut_ptr(),
+ &mut ngroups,
+ )
+ } < 0
+ {
+ error!("Could not get list of supplementary groups");
+ return Err(Error::Permission);
+ }
+ }
+
+ // Set supplementary groups
+ if unsafe { libc::setgroups(ngroups as usize, sup_groups.as_ptr()) } != 0
+ {
let e = io::Error::last_os_error();
- error!("Could not set group id: {}", e);
+ error!("Could not set supplementary groups: {}", e);
return Err(Error::Permission);
}
// Set uid
- if unsafe { libc::setuid(ids.uid) } != 0 {
+ if unsafe { libc::setuid(ids.passwd.pw_uid) } != 0 {
let e = io::Error::last_os_error();
error!("Could not set user id: {}", e);
return Err(Error::Permission);
@@ -126,9 +157,12 @@ pub(crate) fn chown(user_group: &str, path: &Path) -> Result<()> {
return Err(Error::Permission);
}
- // change directory owner to root
+ // change directory owner
let c_path = CString::new(path.as_os_str().as_bytes())?;
- if unsafe { libc::chown(c_path.as_ptr(), ids.uid, ids.gid) } != 0 {
+ if unsafe {
+ libc::chown(c_path.as_ptr(), ids.passwd.pw_uid, ids.group.gr_gid)
+ } != 0
+ {
error!("Failed to change file {} owner.", path.display());
return Err(Error::Permission);
}

View File

@ -1,20 +0,0 @@
--- a/src/main.rs 2022-06-28 16:54:37.559307146 +0200
+++ b/src/main.rs 2022-06-28 17:37:39.512350575 +0200
@@ -512,7 +512,16 @@
let ssl_context;
if config.mtls_enabled {
let keylime_ca_cert =
- crypto::load_x509(Path::new(&config.keylime_ca_path))?;
+ match crypto::load_x509(Path::new(&config.keylime_ca_path)) {
+ Ok(t) => Ok(t),
+ Err(e) => {
+ error!(
+ "Certificate not installed: {}",
+ config.keylime_ca_path
+ );
+ Err(e)
+ }
+ }?;
cert = crypto::generate_x509(&nk_priv, &config.agent_uuid)?;
mtls_cert = Some(&cert);

View File

@ -1,2 +1,2 @@
SHA512 (rust-keylime-0.1.0~20220603gitaed51c7.tar.gz) = 0a045b0caa13a582a1270428edb49a7e20cc7df15b749458a9ddb2b84c05f240225d9e876a0cc082978dc5b52f7e0175cbbc3b937edd1ffed68e252be3ea17f8
SHA512 (rust-keylime-0.1.0~20220603gitaed51c7-vendor.tar.xz) = 071cec539b70dc25ca8a03fbc17a185d0d8bc3eb90d120da72abfa056712a41e773cc5f372d2d4dd1e6f13b8aba448c200492c830d2f2241c7cb27e5a2833352
SHA512 (v0.1.0.tar.gz) = 204e5cdf0901d237ed22f5265ce8c9f4c13d7d8ad4c1b64419a469213d88e584f0555f6edfbf7aa9346d2e3a86d8f7f0a0d5056a3e0ab0dfe5d170f8910fc7cf
SHA512 (rust-keylime-0.1.0-vendor.tar.xz) = e19fccc9e0f05a9dbcc2e2bae509724b5457031765527222497d5e301b096e9a606827a4ecadff56ec6bb2c122c8c643ef310717c3a4b84c578ad219dd36cd57