Skip to content

Commit

Permalink
lib/utils: fall back to env for configs and Ghidra plugins
Browse files Browse the repository at this point in the history
If config files or Ghidra plugins are not found in the respective project
directories, fall back to env vars that contain an alternative search
directory.
  • Loading branch information
Valentin Obst committed Dec 10, 2024
1 parent 457d2db commit b971dca
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/cwe_checker_lib/src/utils/ghidra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ fn generate_ghidra_call_command(
.ok_or_else(|| anyhow!("Invalid file name"))?
.to_string_lossy()
.to_string();
let ghidra_plugin_path = get_ghidra_plugin_path("p_code_extractor");
let ghidra_plugin_path = get_ghidra_plugin_path("p_code_extractor")?;

let mut ghidra_command = Command::new(headless_path);
ghidra_command
Expand Down
76 changes: 66 additions & 10 deletions src/cwe_checker_lib/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,77 @@ pub mod symbol_utils;

use crate::prelude::*;

use std::{env, fs, path};

use anyhow::bail;

const ENV_CWE_CHECKER_CONFIGS_PATH: &str = "CWE_CHECKER_CONFIGS_PATH";
const ENV_CWE_CHECKER_GHIDRA_PLUGINS_PATH: &str = "CWE_CHECKER_GHIDRA_PLUGINS_PATH";

/// Get the contents of a configuration file.
///
/// We first search the file in our config directory. Then, we fall back to
/// the CWE_CHECKER_CONFIG environment variable.
pub fn read_config_file(filename: &str) -> Result<serde_json::Value, Error> {
let project_dirs = directories::ProjectDirs::from("", "", "cwe_checker")
.context("Could not discern location of configuration files.")?;
let config_path = if let Some(config_path) = get_config_path_from_project_dir(filename) {
config_path
} else if let Some(config_path) = get_path_from_env(ENV_CWE_CHECKER_CONFIGS_PATH, filename) {
config_path
} else {
bail!("Unable to find configuration file: {}.", filename)
};
let config_file = fs::read_to_string(config_path)
.context(format!("Could not read configuration file: {}", filename))?;
Ok(serde_json::from_str(&config_file)?)
}

fn get_config_path_from_project_dir(filename: &str) -> Option<path::PathBuf> {
let project_dirs = directories::ProjectDirs::from("", "", "cwe_checker")?;
let config_dir = project_dirs.config_dir();
let config_path = config_dir.join(filename);
let config_file =
std::fs::read_to_string(config_path).context("Could not read configuration file")?;
Ok(serde_json::from_str(&config_file)?)

if config_path.exists() {
Some(config_path)
} else {
None
}
}

/// Get the path to a Ghidra plugin that is bundled with the cwe_checker.
///
/// We first search the plugin in our data directory, then we fall back to
/// the CWE_CHECKER_GHIDRA_PLUGIN_PATH environment variable.
pub fn get_ghidra_plugin_path(plugin_name: &str) -> Result<path::PathBuf, Error> {
if let Some(ghidra_plugin_path) = get_ghidra_plugin_path_from_project_dirs(plugin_name) {
Ok(ghidra_plugin_path)
} else if let Some(ghidra_plugin_path) =
get_path_from_env(ENV_CWE_CHECKER_GHIDRA_PLUGINS_PATH, plugin_name)
{
Ok(ghidra_plugin_path)
} else {
bail!("Unable to find Ghidra plugin: {}", plugin_name)
}
}

/// Get the folder path to a Ghidra plugin bundled with the cwe_checker.
pub fn get_ghidra_plugin_path(plugin_name: &str) -> std::path::PathBuf {
let project_dirs = directories::ProjectDirs::from("", "", "cwe_checker")
.expect("Could not discern location of data directory.");
fn get_ghidra_plugin_path_from_project_dirs(plugin_name: &str) -> Option<path::PathBuf> {
let project_dirs = directories::ProjectDirs::from("", "", "cwe_checker")?;
let data_dir = project_dirs.data_dir();
data_dir.join("ghidra").join(plugin_name)
let plugin_path = data_dir.join("ghidra").join(plugin_name);

if plugin_path.exists() {
Some(plugin_path)
} else {
None
}
}

fn get_path_from_env(var: &str, filename: &str) -> Option<path::PathBuf> {
let val = env::var(var).ok()?;
let path = path::PathBuf::from(val).join(filename);

if path.exists() {
Some(path)
} else {
None
}
}

0 comments on commit b971dca

Please sign in to comment.