Skip to content

Commit b971dca

Browse files
author
Valentin Obst
committed
lib/utils: fall back to env for configs and Ghidra plugins
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.
1 parent 457d2db commit b971dca

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

src/cwe_checker_lib/src/utils/ghidra.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ fn generate_ghidra_call_command(
183183
.ok_or_else(|| anyhow!("Invalid file name"))?
184184
.to_string_lossy()
185185
.to_string();
186-
let ghidra_plugin_path = get_ghidra_plugin_path("p_code_extractor");
186+
let ghidra_plugin_path = get_ghidra_plugin_path("p_code_extractor")?;
187187

188188
let mut ghidra_command = Command::new(headless_path);
189189
ghidra_command

src/cwe_checker_lib/src/utils/mod.rs

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,77 @@ pub mod symbol_utils;
1010

1111
use crate::prelude::*;
1212

13+
use std::{env, fs, path};
14+
15+
use anyhow::bail;
16+
17+
const ENV_CWE_CHECKER_CONFIGS_PATH: &str = "CWE_CHECKER_CONFIGS_PATH";
18+
const ENV_CWE_CHECKER_GHIDRA_PLUGINS_PATH: &str = "CWE_CHECKER_GHIDRA_PLUGINS_PATH";
19+
1320
/// Get the contents of a configuration file.
21+
///
22+
/// We first search the file in our config directory. Then, we fall back to
23+
/// the CWE_CHECKER_CONFIG environment variable.
1424
pub fn read_config_file(filename: &str) -> Result<serde_json::Value, Error> {
15-
let project_dirs = directories::ProjectDirs::from("", "", "cwe_checker")
16-
.context("Could not discern location of configuration files.")?;
25+
let config_path = if let Some(config_path) = get_config_path_from_project_dir(filename) {
26+
config_path
27+
} else if let Some(config_path) = get_path_from_env(ENV_CWE_CHECKER_CONFIGS_PATH, filename) {
28+
config_path
29+
} else {
30+
bail!("Unable to find configuration file: {}.", filename)
31+
};
32+
let config_file = fs::read_to_string(config_path)
33+
.context(format!("Could not read configuration file: {}", filename))?;
34+
Ok(serde_json::from_str(&config_file)?)
35+
}
36+
37+
fn get_config_path_from_project_dir(filename: &str) -> Option<path::PathBuf> {
38+
let project_dirs = directories::ProjectDirs::from("", "", "cwe_checker")?;
1739
let config_dir = project_dirs.config_dir();
1840
let config_path = config_dir.join(filename);
19-
let config_file =
20-
std::fs::read_to_string(config_path).context("Could not read configuration file")?;
21-
Ok(serde_json::from_str(&config_file)?)
41+
42+
if config_path.exists() {
43+
Some(config_path)
44+
} else {
45+
None
46+
}
47+
}
48+
49+
/// Get the path to a Ghidra plugin that is bundled with the cwe_checker.
50+
///
51+
/// We first search the plugin in our data directory, then we fall back to
52+
/// the CWE_CHECKER_GHIDRA_PLUGIN_PATH environment variable.
53+
pub fn get_ghidra_plugin_path(plugin_name: &str) -> Result<path::PathBuf, Error> {
54+
if let Some(ghidra_plugin_path) = get_ghidra_plugin_path_from_project_dirs(plugin_name) {
55+
Ok(ghidra_plugin_path)
56+
} else if let Some(ghidra_plugin_path) =
57+
get_path_from_env(ENV_CWE_CHECKER_GHIDRA_PLUGINS_PATH, plugin_name)
58+
{
59+
Ok(ghidra_plugin_path)
60+
} else {
61+
bail!("Unable to find Ghidra plugin: {}", plugin_name)
62+
}
2263
}
2364

24-
/// Get the folder path to a Ghidra plugin bundled with the cwe_checker.
25-
pub fn get_ghidra_plugin_path(plugin_name: &str) -> std::path::PathBuf {
26-
let project_dirs = directories::ProjectDirs::from("", "", "cwe_checker")
27-
.expect("Could not discern location of data directory.");
65+
fn get_ghidra_plugin_path_from_project_dirs(plugin_name: &str) -> Option<path::PathBuf> {
66+
let project_dirs = directories::ProjectDirs::from("", "", "cwe_checker")?;
2867
let data_dir = project_dirs.data_dir();
29-
data_dir.join("ghidra").join(plugin_name)
68+
let plugin_path = data_dir.join("ghidra").join(plugin_name);
69+
70+
if plugin_path.exists() {
71+
Some(plugin_path)
72+
} else {
73+
None
74+
}
75+
}
76+
77+
fn get_path_from_env(var: &str, filename: &str) -> Option<path::PathBuf> {
78+
let val = env::var(var).ok()?;
79+
let path = path::PathBuf::from(val).join(filename);
80+
81+
if path.exists() {
82+
Some(path)
83+
} else {
84+
None
85+
}
3086
}

0 commit comments

Comments
 (0)