dragonfly_client_rs/
exts.rs

1use yara::{MetadataValue, Rule};
2
3use crate::scanner::RuleScore;
4
5pub trait RuleExt<'a> {
6    /// Get the value of a metadata by key. `None` if that key/value pair doesn't exist
7    fn get_metadata_value(&'a self, key: &str) -> Option<&'a MetadataValue<'a>>;
8
9    /// Get the weight of this rule. `0` if no weight is defined.
10    fn get_rule_weight(&'a self) -> i64;
11
12    /// Get a vector over the `filetype` metadata value. An empty Vec if not defined.
13    fn get_filetypes(&'a self) -> Vec<&'a str>;
14}
15
16impl RuleExt<'_> for Rule<'_> {
17    fn get_metadata_value(&self, key: &str) -> Option<&'_ MetadataValue<'_>> {
18        self.metadatas
19            .iter()
20            .find(|metadata| metadata.identifier == key)
21            .map(|metadata| &metadata.value)
22    }
23
24    fn get_filetypes(&'_ self) -> Vec<&'_ str> {
25        if let Some(MetadataValue::String(string)) = self.get_metadata_value("filetype") {
26            string.split(' ').collect()
27        } else {
28            Vec::new()
29        }
30    }
31
32    fn get_rule_weight(&self) -> i64 {
33        if let Some(MetadataValue::Integer(integer)) = self.get_metadata_value("weight") {
34            *integer
35        } else {
36            0
37        }
38    }
39}
40
41impl From<Rule<'_>> for RuleScore {
42    fn from(rule: Rule) -> Self {
43        Self {
44            name: rule.identifier.to_owned(),
45            score: rule.get_rule_weight(),
46        }
47    }
48}