From 291941667d1847c6ba2cd24994fe75ccdd22d681 Mon Sep 17 00:00:00 2001 From: Noor Date: Thu, 3 Apr 2025 19:01:51 +0530 Subject: [PATCH] feat: add directory support on launch config dtpm proto changed upload files through grpc stream seperated filesystem from dtpm config tar zstd archiving directory to upload test directory support on config test archive directory --- Cargo.lock | 176 +++++++++++++++++++++++++++++--- Cargo.toml | 5 + proto/sgx/dtpm.proto | 12 ++- src/sgx/types/dtpm.rs | 57 ++++++++--- tests/dtpm-config_test.rs | 32 ++++++ tests/fixtures/dtpm_config.yaml | 15 +++ 6 files changed, 265 insertions(+), 32 deletions(-) create mode 100644 tests/dtpm-config_test.rs create mode 100644 tests/fixtures/dtpm_config.yaml diff --git a/Cargo.lock b/Cargo.lock index ede831e..58ca45d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -163,6 +163,17 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +[[package]] +name = "cc" +version = "1.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -177,9 +188,12 @@ dependencies = [ "prost", "serde", "serde_yaml", + "tar", + "tempfile", "thiserror", "tonic", "tonic-build", + "zstd", ] [[package]] @@ -210,6 +224,18 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -269,7 +295,19 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -449,6 +487,15 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "libc" version = "0.2.169" @@ -456,10 +503,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", + "redox_syscall", +] + +[[package]] +name = "linux-raw-sys" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "log" @@ -501,7 +559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -574,6 +632,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + [[package]] name = "ppv-lite86" version = "0.2.20" @@ -663,6 +727,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -690,7 +760,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "redox_syscall" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +dependencies = [ + "bitflags", ] [[package]] @@ -730,9 +809,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.42" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" +checksum = "d97817398dd4bb2e6da002002db259209759911da105da92bec29ccb12cf58bf" dependencies = [ "bitflags", "errno", @@ -786,6 +865,12 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "slab" version = "0.4.9" @@ -829,13 +914,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" [[package]] -name = "tempfile" -version = "3.14.0" +name = "tar" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "cfg-if", "fastrand", + "getrandom 0.3.2", "once_cell", "rustix", "windows-sys 0.59.0", @@ -1066,6 +1162,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -1148,6 +1253,25 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "xattr" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" +dependencies = [ + "libc", + "rustix", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -1168,3 +1292,31 @@ dependencies = [ "quote", "syn", ] + +[[package]] +name = "zstd" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.15+zstd.1.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index f282463..1b4a8d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,11 @@ serde = { version = "1.0.216", features = ["derive"] } serde_yaml = "0.9.34" thiserror = "2.0.11" tonic = "0.12.3" +tar = "0.4.44" +zstd = "0.13.3" [build-dependencies] tonic-build = "0.12.3" + +[dev-dependencies] +tempfile = "3.19.1" diff --git a/proto/sgx/dtpm.proto b/proto/sgx/dtpm.proto index 5622bb3..89cc5d1 100644 --- a/proto/sgx/dtpm.proto +++ b/proto/sgx/dtpm.proto @@ -5,16 +5,19 @@ package dtpm_proto; import "shared/common.proto"; message DtpmConfigData { - repeated FileEntry filesystems = 1; - repeated EnvironmentEntry environments = 2; - repeated ChildProcess child_processes = 3; + repeated EnvironmentEntry environments = 1; + repeated ChildProcess child_processes = 2; } message FileEntry { string path = 1; - string content = 2; + oneof content { + string data = 2; + bytes archive = 3; + } } + message EnvironmentEntry { string name = 1; string value = 2; @@ -52,5 +55,6 @@ message DtpmGetConfigRes { service DtpmConfigManager { rpc SetConfig(DtpmSetConfigReq) returns (DtpmSetConfigRes) {} + rpc UploadFiles(stream FileEntry) returns (DtpmSetConfigRes) {} rpc GetConfig(common_proto.Empty) returns (DtpmGetConfigRes) {} } \ No newline at end of file diff --git a/src/sgx/types/dtpm.rs b/src/sgx/types/dtpm.rs index 7b33293..c3d7212 100644 --- a/src/sgx/types/dtpm.rs +++ b/src/sgx/types/dtpm.rs @@ -1,6 +1,9 @@ use crate::sgx::pb::dtpm_proto; use base64::{engine::general_purpose::STANDARD as BASE64, Engine}; use serde::{Deserialize, Serialize}; +use std::path::Path; +use tar::Builder; +use zstd::Encoder; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct DtpmConfig { @@ -12,11 +15,7 @@ pub struct DtpmConfig { impl From for DtpmConfig { fn from(pb_val: dtpm_proto::DtpmConfigData) -> Self { DtpmConfig { - filesystems: pb_val - .filesystems - .into_iter() - .map(FileEntry::from) - .collect(), + filesystems: vec![], environments: pb_val .environments .into_iter() @@ -34,7 +33,6 @@ impl From for DtpmConfig { impl From for dtpm_proto::DtpmConfigData { fn from(val: DtpmConfig) -> dtpm_proto::DtpmConfigData { dtpm_proto::DtpmConfigData { - filesystems: val.filesystems.into_iter().map(Into::into).collect(), environments: val.environments.into_iter().map(Into::into).collect(), child_processes: val.child_processes.into_iter().map(Into::into).collect(), } @@ -51,7 +49,11 @@ impl From for FileEntry { fn from(pb_val: dtpm_proto::FileEntry) -> Self { FileEntry { path: pb_val.path, - content: FileContent::Data(pb_val.content), + content: match pb_val.content { + Some(dtpm_proto::file_entry::Content::Data(data)) => FileContent::Data(data), + Some(dtpm_proto::file_entry::Content::Archive(_)) => todo!(), + None => FileContent::Data("".to_string()), + }, } } } @@ -60,8 +62,11 @@ impl From for dtpm_proto::FileEntry { dtpm_proto::FileEntry { path: val.path, content: match val.content { - FileContent::Data(data) => data, - FileContent::Path(path) => path, + FileContent::Path(_) => unimplemented!(), + FileContent::Data(data) => Some(dtpm_proto::file_entry::Content::Data(data)), + FileContent::Archive(file_entry) => { + Some(dtpm_proto::file_entry::Content::Archive(file_entry)) + } }, } } @@ -73,6 +78,8 @@ pub enum FileContent { Path(String), #[serde(rename = "data")] Data(String), + #[serde(rename = "directory")] + Archive(Vec), } #[derive(Debug, Clone, Serialize, Deserialize, Default)] @@ -197,15 +204,33 @@ impl DtpmConfig { } pub fn load_data(mut self) -> Result { - self.filesystems.iter_mut().for_each(|x| { - if let FileContent::Path(path) = &x.content { - let content = - std::fs::read(path).unwrap_or_else(|_| panic!("Unable to read file {path}")); - let encoded = BASE64.encode(content); - x.content = FileContent::Data(encoded); + for file_entry in self.filesystems.iter_mut() { + if let FileContent::Path(path) = &file_entry.content { + if Path::new(path).is_dir() { + let compressed_data = compress_directory(path)?; + file_entry.content = FileContent::Archive(compressed_data); + } else { + let content = std::fs::read(path) + .unwrap_or_else(|_| panic!("Unable to read file {path}")); + let encoded = BASE64.encode(content); + file_entry.content = FileContent::Data(encoded); + } } - }); + } Ok(self) } } + +pub fn compress_directory(input_dir: &str) -> Result> { + let mut tar_builder = Builder::new(Encoder::new(Vec::new(), 3)?); + + tar_builder.append_dir_all(".", input_dir)?; + + tar_builder.finish()?; + + let zstd_encoder = tar_builder.into_inner()?; + let compressed_data = zstd_encoder.finish()?; + + Ok(compressed_data) +} diff --git a/tests/dtpm-config_test.rs b/tests/dtpm-config_test.rs new file mode 100644 index 0000000..44bfd91 --- /dev/null +++ b/tests/dtpm-config_test.rs @@ -0,0 +1,32 @@ +use detee_shared::sgx::types::dtpm::{compress_directory, DtpmConfig}; + +#[test] +fn dtpm_config_dir_support_test() { + let file_path = "tests/fixtures/dtpm_config.yaml"; + let unloaded_config = DtpmConfig::from_path(file_path).unwrap(); + + let loaded_config = unloaded_config.load_data().unwrap(); + + dbg!(&loaded_config); +} + +#[test] +fn test_compression() { + // let file_path = "/Users/user/.cache/hunter/toolchain"; + let file_path = "./tests"; + let compressed_buff = compress_directory(file_path).unwrap(); + + let tmp_dir = tempfile::tempdir() + .unwrap() + .into_path() + .to_string_lossy() + .to_string(); + + dbg!(&tmp_dir); + + std::fs::write( + format!("{}/{}", tmp_dir, "archive.tar.zst"), + &compressed_buff, + ) + .unwrap(); +} diff --git a/tests/fixtures/dtpm_config.yaml b/tests/fixtures/dtpm_config.yaml new file mode 100644 index 0000000..6594cee --- /dev/null +++ b/tests/fixtures/dtpm_config.yaml @@ -0,0 +1,15 @@ +environments: + - name: APP_NAME + value: actix-injectio-from-base-package + - name: PORT + value: 8080 +child_processes: + - path: /bin/actix-app-info + arguments: [] + restart: + max_retries: 2 + delay_seconds: 2 + policy: !OnNonZeroExit true +filesystems: + - path: /bin/actix-app-info + content: !path "/Users/user/tmp/actix-app-info/target/x86_64-unknown-linux-musl/release/actix-app-info"