Skip to content

Commit

Permalink
Enable recursive directory traversal in casc
Browse files Browse the repository at this point in the history
This enables recursively discovering all policy files in the specified
path(s), which is expected to be the most common use case.

Additional ergonomics, like defaulting to CWD if no path is specified is
future work.
  • Loading branch information
dburgener committed Jun 14, 2022
1 parent e03b2dc commit 1d4e886
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Expand Up @@ -19,3 +19,4 @@ lalrpop-util = "0.19"
regex = "1"
sexp = "1.1"
thiserror = "1.0"
walkdir = "2"
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -27,7 +27,9 @@ on the secilc package.

## casc
The Cascade compiler is named casc, and will be located at target/debug/casc after a
successful build. It takes one argument, the name of a policy file to be built:
successful build. Input files are supplied as arguments. Directory arguments
are searched recursively for policy files. If no valid policy files are found,
casc will exit with an error.

```
$ casc my_policy.cas
Expand Down
40 changes: 37 additions & 3 deletions src/bin/casc.rs
Expand Up @@ -6,19 +6,37 @@ use selinux_cascade::error::ErrorItem;
use clap::Parser;
use std::fs::File;
use std::io::{Error, ErrorKind, Write};
use walkdir::WalkDir;

#[derive(Parser, Debug)]
#[clap(author, version, name = "casc")]
#[clap(author, version, name = "casc", about)]
struct Args {
/// List of input files to process. Directories are searched recursively.
#[clap(required(true))]
input_file: Vec<String>,
}

fn main() -> std::io::Result<()> {
let args = Args::parse();
let policies: Vec<&str> = args.input_file.iter().map(|s| s as &str).collect();
let policies: Vec<String> = match get_policy_files(args.input_file) {
Ok(mut s) => {
s.sort_unstable();
s
}
Err(e) => {
eprintln!("{}", e);
return Err(e);
}
};
if policies.is_empty() {
// Files supplied on command line, but no .cas files found
return Err(Error::new(
ErrorKind::InvalidData,
"No policy source files found",
));
}
let mut out_file = File::create("out.cil")?;
let res = compile_system_policy(policies);
let res = compile_system_policy(policies.iter().map(|s| s as &str).collect());
match res {
Err(error_list) => {
for e in error_list {
Expand All @@ -35,3 +53,19 @@ fn main() -> std::io::Result<()> {
Ok(s) => out_file.write_all(s.as_bytes()),
}
}

// Create a list of policy files
fn get_policy_files(filenames: Vec<String>) -> Result<Vec<String>, Error> {
let mut policy_files = Vec::new();
for file in filenames {
for entry in WalkDir::new(file) {
let entry = entry?;
if entry.file_type().is_file() && entry.path().extension().unwrap_or_default() == "cas"
{
let filename = entry.path().display().to_string();
policy_files.push(filename);
}
}
}
Ok(policy_files)
}

0 comments on commit 1d4e886

Please sign in to comment.