Skip to content

Commit

Permalink
Merge pull request #123 from kunai-project/chg-config-format
Browse files Browse the repository at this point in the history
chg: config format
  • Loading branch information
qjerome authored Oct 14, 2024
2 parents 30812f9 + 1bd46ac commit a89718d
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 110 deletions.
54 changes: 1 addition & 53 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions kunai-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,23 @@ publish = false

[features]
default = []
user = ["aya", "dns-parser", "uuid", "thiserror"]
user = ["aya", "dns-parser", "uuid", "thiserror", "serde"]

[build-dependencies]
bindgen = "0.69"

[dependencies]
# Non Aya deps
dns-parser = { version = "0.8.0", optional = true }
# optional deps (only for userland)
thiserror = { version = "1.0", optional = true }
uuid = { version = "1.3.0", optional = true, features = ["v4"] }
dns-parser = { version = "0.8.0", optional = true }
serde = { version = "1.0.164", features = ["derive"], optional = true }

# Non Aya deps
cfg-if = "1.0.0"
paste = "1.0"
thiserror = { version = "1.0", optional = true }
kunai-macros = { path = "src/kunai-macros" }

# Aya deps
aya = { version = "0.12.0", optional = true }
# we fix version including patch as some APIs got changed
Expand Down
21 changes: 21 additions & 0 deletions kunai-common/src/bpf_events/user.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use aya::Pod;
use core::fmt::{Debug, Display};
use core::str::FromStr;
use serde::{Deserialize, Serialize};

use thiserror::Error;

Expand All @@ -11,6 +13,25 @@ impl Display for Type {
}
}

impl Serialize for Type {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(self.as_str())
}
}

impl<'de> Deserialize<'de> for Type {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Type::from_str(&s).map_err(serde::de::Error::custom)
}
}

#[repr(C)]
#[derive(Debug, Clone)]
pub struct EncodedEvent {
Expand Down
1 change: 0 additions & 1 deletion kunai/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ tokio = { version = "1.39", features = [
"time",
"sync",
] }
toml = "0.7.4"
serde = { version = "1.0.164", features = ["derive"] }
clap = { version = "4.3.4", features = ["derive"] }
serde_json = "1.0.108"
Expand Down
18 changes: 10 additions & 8 deletions kunai/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ impl<'s> EventConsumer<'s> {
let scan_events_enabled = config
.events
.iter()
.any(|e| e.name() == Type::FileScan.as_str() && e.is_enabled());
.any(|(&ty, e)| ty == Type::FileScan && e.is_enabled());

let output = Self::prepare_output(&config)?;

Expand Down Expand Up @@ -2191,7 +2191,7 @@ impl TryFrom<ReplayOpt> for Config {
let mut conf = Self::default();

if let Some(conf_file) = opt.config {
conf = Self::from_toml(std::fs::read_to_string(conf_file)?)?;
conf = serde_yaml::from_str(&std::fs::read_to_string(conf_file)?)?;
}

// command line supersedes configuration
Expand Down Expand Up @@ -2268,7 +2268,7 @@ impl TryFrom<RunOpt> for Config {
let mut conf = Self::default();

if let Some(conf_file) = opt.config {
conf = Self::from_toml(std::fs::read_to_string(conf_file)?)?;
conf = serde_yaml::from_str(&std::fs::read_to_string(conf_file)?)?;
}

// command line supersedes configuration
Expand Down Expand Up @@ -2311,7 +2311,8 @@ impl TryFrom<RunOpt> for Config {
conf.disable_all()
} else {
for exc in exclude {
if let Some(e) = conf.events.iter_mut().find(|e| e.name() == exc) {
if let Some((_, e)) = conf.events.iter_mut().find(|(ty, _)| ty.as_str() == exc)
{
e.disable()
}
}
Expand All @@ -2325,7 +2326,8 @@ impl TryFrom<RunOpt> for Config {
conf.enable_all()
} else {
for inc in include {
if let Some(e) = conf.events.iter_mut().find(|e| e.name() == inc) {
if let Some((_, e)) = conf.events.iter_mut().find(|(ty, _)| ty.as_str() == inc)
{
e.enable()
}
}
Expand Down Expand Up @@ -2362,7 +2364,7 @@ struct InstallOpt {

/// Where to write the configuration file. Any intermediate directory
/// will be created if needed.
#[arg(long, default_value_t = String::from("/etc/kunai/config.toml"))]
#[arg(long, default_value_t = String::from("/etc/kunai/config.yaml"))]
config: String,

/// Make a systemd unit installation
Expand Down Expand Up @@ -2643,7 +2645,7 @@ impl Command {
fn config(co: ConfigOpt) -> anyhow::Result<()> {
if co.dump {
let conf = Config::default().generate_host_uuid();
println!("{}", conf.to_toml()?);
println!("{}", serde_yaml::to_string(&conf)?);
return Ok(());
}

Expand Down Expand Up @@ -2777,7 +2779,7 @@ WantedBy=sysinit.target"#,
config_path.to_string_lossy()
);
// we write configuration file
fs::write(&config_path, conf.to_toml()?)?;
fs::write(&config_path, serde_yaml::to_string(&conf)?)?;

// we read our own binary
let self_bin = fs::read("/proc/self/exe")?;
Expand Down
65 changes: 21 additions & 44 deletions kunai/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use core::str::FromStr;
use huby::ByteSize;
use kunai_common::{
bpf_events,
config::{BpfConfig, Filter, Loader},
};
use serde::{Deserialize, Serialize};
use std::{fs, path::Path};
use std::{collections::BTreeMap, fs, path::Path};
use thiserror::Error;

pub const DEFAULT_SEND_DATA_MIN_LEN: u64 = 256;
Expand All @@ -21,16 +20,10 @@ pub enum Error {

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Event {
name: String,
enable: bool,
}

impl Event {
#[inline(always)]
pub fn name(&self) -> &str {
&self.name
}

#[inline(always)]
pub fn disable(&mut self) {
self.enable = false
Expand Down Expand Up @@ -67,12 +60,12 @@ pub struct Config {
pub yara: Vec<String>,
pub always_show_positive_scans: bool,
pub harden: bool,
pub events: Vec<Event>,
pub events: BTreeMap<bpf_events::Type, Event>,
}

impl Default for Config {
fn default() -> Self {
let mut events = vec![];
let mut events = BTreeMap::new();
for v in bpf_events::Type::variants() {
// some events get disabled by default because there are too many
let en = !matches!(
Expand All @@ -81,10 +74,7 @@ impl Default for Config {
);

if v.is_configurable() {
events.push(Event {
name: v.as_str().into(),
enable: en,
})
events.insert(v, Event { enable: en });
}
}

Expand Down Expand Up @@ -153,33 +143,12 @@ impl Config {
self
}

pub fn to_toml(&self) -> Result<String, toml::ser::Error> {
toml::to_string(self)
}

pub fn from_toml<S: AsRef<str>>(toml: S) -> Result<Self, toml::de::Error> {
toml::from_str(toml.as_ref())
}

pub fn validate(&self) -> Result<(), Error> {
for e in self.events.iter() {
let Ok(ty) = bpf_events::Type::from_str(&e.name) else {
return Err(Error::InvalidEvent(e.name.clone()));
};

if !ty.is_configurable() {
return Err(Error::InvalidEvent(e.name.clone()));
}
}
Ok(())
}

pub fn enable_all(&mut self) {
self.events.iter_mut().for_each(|e| e.enable())
self.events.iter_mut().for_each(|(_, e)| e.enable())
}

pub fn disable_all(&mut self) {
self.events.iter_mut().for_each(|e| e.disable())
self.events.iter_mut().for_each(|(_, e)| e.disable())
}
}

Expand All @@ -197,13 +166,10 @@ impl TryFrom<&Config> for Filter {
fn try_from(value: &Config) -> Result<Self, Error> {
let mut filter = Filter::all_disabled();

for e in value.events.iter() {
// config should have been verified so it should not fail
let ty = bpf_events::Type::from_str(&e.name)
.map_err(|_| Error::InvalidEvent(e.name.clone()))?;
for (ty, e) in value.events.iter() {
// we enable event in BpfConfig only if it has been configured
if e.enable {
filter.enable(ty);
filter.enable(*ty);
}
}

Expand Down Expand Up @@ -234,6 +200,9 @@ impl TryFrom<&Config> for BpfConfig {
#[cfg(test)]
mod test {

use serde_yaml;
use std::collections::BTreeMap;

use super::*;

#[test]
Expand All @@ -242,9 +211,17 @@ mod test {
..Default::default()
};

config.validate().unwrap();
println!("{}", serde_yaml::to_string(&config).unwrap());
}

#[test]
fn test_serialize_btreemap() {
let mut config = BTreeMap::<String, isize>::new();
config.insert("c".into(), 0);
config.insert("b".into(), 1);
config.insert("a".into(), 2);

println!("{}", toml::to_string_pretty(&config).unwrap());
println!("{}", serde_yaml::to_string(&config).unwrap());
}

#[test]
Expand Down

0 comments on commit a89718d

Please sign in to comment.