diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp index e6c0c94c..b2b64d8c 100644 --- a/src/Daemon/Daemon.cpp +++ b/src/Daemon/Daemon.cpp @@ -71,7 +71,8 @@ namespace usbguard "IPCAccessControlFiles", "AuditFilePath", "AuditBackend", - "HidePII" + "HidePII", + "RuleSourceLogging" }; static const std::vector> device_policy_method_strings = { @@ -125,6 +126,7 @@ namespace usbguard _inserted_device_policy_method = DevicePolicyMethod::ApplyPolicy; _device_rules_with_port = false; _restore_controller_device_state = false; + _rule_source = false; pid_fd = -1; } @@ -396,6 +398,22 @@ namespace usbguard } } + /* RuleSourceLogging */ + if (_config.hasSettingValue("RuleSourceLogging")) { + const std::string value = _config.getSettingValue("RuleSourceLogging"); + USBGUARD_LOG(Debug) << "Setting RuleSourceLogging to " << value; + + if (value == "true") { + _rule_source = true; + } + else if (value == "false") { + _rule_source = false; + } + else { + throw Exception("Configuration", "RuleSourceLogging", "Invalid value"); + } + } + USBGUARD_LOG(Info) << "Configuration loaded successfully."; } @@ -861,7 +879,28 @@ namespace usbguard { USBGUARD_LOG(Trace) << "device_ptr=" << device.get() << " matched_rule_ptr=" << matched_rule.get(); - auto audit_event = _audit.policyEvent(device, device->getTarget(), matched_rule->getTarget()); + + auto audit_event = [&]() { + if (_rule_source){ + if (matched_rule->getRuleID() == Rule::ImplicitID) { + return _audit.policyEventSource(device, device->getTarget(), matched_rule->getTarget(), RULE_TYPE_IMPLICIT); + } + + if (matched_rule->hasKey()){ + return _audit.policyEventSourceKey(device, device->getTarget(), matched_rule->getTarget(), RULE_TYPE_LOOKUP, matched_rule->getKey()); + } + + return _audit.policyEventSource(device, device->getTarget(), matched_rule->getTarget(), RULE_TYPE_LOOKUP); + } + + if (matched_rule->hasKey()){ + return _audit.policyEventKey(device, device->getTarget(), matched_rule->getTarget(), matched_rule->getKey()); + } + + return _audit.policyEvent(device, device->getTarget(), matched_rule->getTarget()); + + }(); + const Rule::Target target_old = device->getTarget(); std::shared_ptr device_post = \ _dm->applyDevicePolicy(device->getID(), diff --git a/src/Daemon/Daemon.hpp b/src/Daemon/Daemon.hpp index a9681c65..b3606ae3 100644 --- a/src/Daemon/Daemon.hpp +++ b/src/Daemon/Daemon.hpp @@ -135,6 +135,10 @@ namespace usbguard bool _device_rules_with_port; bool _restore_controller_device_state; + bool _rule_source; + + static inline const std::string RULE_TYPE_LOOKUP = "lookup"; + static inline const std::string RULE_TYPE_IMPLICIT = "implicit"; AuditIdentity _audit_identity; Audit _audit; diff --git a/src/Library/RuleParser/Actions.hpp b/src/Library/RuleParser/Actions.hpp index bb3feb26..19e01467 100644 --- a/src/Library/RuleParser/Actions.hpp +++ b/src/Library/RuleParser/Actions.hpp @@ -91,7 +91,7 @@ namespace usbguard } } }; - + static const std::string stringValueFromRule(const std::string& value) { const std::string string_raw(value.substr(1, value.size() - 2)); @@ -523,6 +523,24 @@ namespace usbguard } } }; + + template + struct key_actions : tao::pegtl::nothing {}; + + template<> + struct key_actions { + template + static void apply(const Input& in, Rule& rule) + { + try { + rule.setKey(stringValueFromRule(in.string())); + } + catch (const std::exception& ex) { + throw tao::pegtl::parse_error(ex.what(), in); + } + } + }; + } /* namespace RuleParser */ } /* namespace usbguard */ diff --git a/src/Library/RuleParser/Grammar.hpp b/src/Library/RuleParser/Grammar.hpp index 5d7bdb40..c913e068 100644 --- a/src/Library/RuleParser/Grammar.hpp +++ b/src/Library/RuleParser/Grammar.hpp @@ -76,12 +76,14 @@ namespace usbguard struct str_match_all: TAO_PEGTL_STRING("match-all") {}; + struct str_key: TAO_PEGTL_STRING("key") {}; + /* * Generic rule attribute */ struct multiset_operator : sor {}; - + template struct attribute_value_multiset : seq>, @@ -91,7 +93,7 @@ namespace usbguard template struct rule_attribute - : seq, + : seq, sor, attribute_value_rule>> {}; @@ -225,6 +227,17 @@ namespace usbguard : seq, if_must, star, any>>>> {}; + /* + * Rule key + */ + struct key_logic + : action {}; + + struct key + : seq, + key_logic> {}; + /* * Rule */ @@ -232,6 +245,7 @@ namespace usbguard : seq, device_id>, opt, list>>, + opt, key>, opt, star> {}; diff --git a/src/Library/RulePrivate.cpp b/src/Library/RulePrivate.cpp index 337fdd44..cd78dcad 100644 --- a/src/Library/RulePrivate.cpp +++ b/src/Library/RulePrivate.cpp @@ -39,7 +39,8 @@ namespace usbguard _via_port("via-port"), _with_interface("with-interface"), _conditions("if"), - _label("label") + _label("label"), + _key("key") { _rule_id = Rule::DefaultID; _target = Rule::Target::Invalid; @@ -56,7 +57,8 @@ namespace usbguard _via_port("via-port"), _with_interface("with-interface"), _conditions("if"), - _label("label") + _label("label"), + _key("key") { *this = rhs; } @@ -263,6 +265,21 @@ namespace usbguard return _serial.get(); } + void RulePrivate::setKey(const std::string& value) + { + _key.set(value); + } + + const std::string& RulePrivate::getKey() const + { + return _key.get(); + } + + bool RulePrivate::hasKey() const + { + return !_key.empty(); + } + const Rule::Attribute& RulePrivate::attributeSerial() const { return _serial; @@ -459,6 +476,7 @@ namespace usbguard toString_appendNonEmptyAttribute(rule_string, _conditions); toString_appendNonEmptyAttribute(rule_string, _with_connect_type); toString_appendNonEmptyAttribute(rule_string, _label); + return rule_string; } diff --git a/src/Library/RulePrivate.hpp b/src/Library/RulePrivate.hpp index 8a635c55..14d8980f 100644 --- a/src/Library/RulePrivate.hpp +++ b/src/Library/RulePrivate.hpp @@ -111,6 +111,10 @@ namespace usbguard const Rule::Attribute& attributeViaPort() const; Rule::Attribute& attributeViaPort(); + void setKey(const std::string& value); + const std::string& getKey() const; + bool hasKey() const; + /* * Set/get for a single value isn't useful for the * with-interface attribute as it usualy contains @@ -146,6 +150,7 @@ namespace usbguard Rule::Attribute _with_interface; Rule::Attribute _conditions; Rule::Attribute _label; + Rule::Attribute _key; uint64_t _conditions_state; }; } diff --git a/src/Library/public/usbguard/Audit.cpp b/src/Library/public/usbguard/Audit.cpp index 796ef7b1..35d382ae 100644 --- a/src/Library/public/usbguard/Audit.cpp +++ b/src/Library/public/usbguard/Audit.cpp @@ -190,6 +190,24 @@ namespace usbguard return policyEvent(_identity, device, old_target, new_target); } + AuditEvent Audit::policyEventKey(std::shared_ptr device, Rule::Target old_target, Rule::Target new_target, + std::string matched_rule_key) + { + return policyEventKey(_identity, device, old_target, new_target, matched_rule_key); + } + + AuditEvent Audit::policyEventSource(std::shared_ptr device, Rule::Target old_target, Rule::Target new_target, + std::string rule_source) + { + return policyEventSource(_identity, device, old_target, new_target, rule_source); + } + + AuditEvent Audit::policyEventSourceKey(std::shared_ptr device, Rule::Target old_target, Rule::Target new_target, + std::string rule_source, std::string matched_rule_key) + { + return policyEventSourceKey(_identity, device, old_target, new_target, rule_source, matched_rule_key); + } + AuditEvent Audit::deviceEvent(std::shared_ptr device, DeviceManager::EventType event) { return deviceEvent(_identity, device, event); @@ -241,6 +259,46 @@ namespace usbguard return event; } + AuditEvent Audit::policyEventKey(const AuditIdentity& identity, std::shared_ptr device, Rule::Target old_target, + Rule::Target new_target, std::string matched_rule_key) + { + AuditEvent event(identity, _backend); + event.setKey("type", std::string("Policy.Device.") + Policy::eventTypeToString(Policy::EventType::Update)); + event.setKey("target.old", Rule::targetToString(old_target)); + event.setKey("target.new", Rule::targetToString(new_target)); + event.setKey("device.system_name", device->getSystemName()); + event.setKey("device.rule", device->getDeviceRule()->toString(false, _hide_pii)); + event.setKey("rule.key", matched_rule_key); + return event; + } + + AuditEvent Audit::policyEventSource(const AuditIdentity& identity, std::shared_ptr device, Rule::Target old_target, + Rule::Target new_target, std::string rule_source) + { + AuditEvent event(identity, _backend); + event.setKey("type", std::string("Policy.Device.") + Policy::eventTypeToString(Policy::EventType::Update)); + event.setKey("target.old", Rule::targetToString(old_target)); + event.setKey("target.new", Rule::targetToString(new_target)); + event.setKey("device.system_name", device->getSystemName()); + event.setKey("device.rule", device->getDeviceRule()->toString(false, _hide_pii)); + event.setKey("rule.source", rule_source); + return event; + } + + AuditEvent Audit::policyEventSourceKey(const AuditIdentity& identity, std::shared_ptr device, Rule::Target old_target, + Rule::Target new_target, std::string rule_source, std::string matched_rule_key) + { + AuditEvent event(identity, _backend); + event.setKey("type", std::string("Policy.Device.") + Policy::eventTypeToString(Policy::EventType::Update)); + event.setKey("target.old", Rule::targetToString(old_target)); + event.setKey("target.new", Rule::targetToString(new_target)); + event.setKey("device.system_name", device->getSystemName()); + event.setKey("device.rule", device->getDeviceRule()->toString(false, _hide_pii)); + event.setKey("rule.source", rule_source); + event.setKey("rule.key", matched_rule_key); + return event; + } + AuditEvent Audit::deviceEvent(const AuditIdentity& identity, std::shared_ptr device, DeviceManager::EventType event_type) { diff --git a/src/Library/public/usbguard/Audit.hpp b/src/Library/public/usbguard/Audit.hpp index f5830976..f8c3471d 100644 --- a/src/Library/public/usbguard/Audit.hpp +++ b/src/Library/public/usbguard/Audit.hpp @@ -373,6 +373,109 @@ namespace usbguard */ AuditEvent policyEvent(std::shared_ptr device, Rule::Target old_target, Rule::Target new_target); + /** + * @brief Constructs new \link AuditEvent AuditEvent\endlink for given + * policy \link Policy::EventType event\endlink. + * + * Sets audit event keys: + * - type\=Policy\.Device\.Update + * - target\.old\=\ + * - target\.new\=\ + * - device\.system_name\= + * - device\.rule\=\ + * - rule\.key\=\ + * + * Audit policy changes: + * - rule append + * - rule remove + * - rule update + * - policy parameter change + * + * Audit data: + * - who: uid + pid + * - when: time + * - what: append, remove, update + * - update: old, new + * + * @param device Device where the rule target has changed. + * @param old_target Old rule target. + * @param new_target New rule target. + * @param matched_rule_key Key of the new rule. + * @return \link AuditEvent Audit event\endlink. + */ + AuditEvent policyEventKey(std::shared_ptr device, Rule::Target old_target, Rule::Target new_target, + std::string matched_rule_key); + + + /** + * @brief Constructs new \link AuditEvent AuditEvent\endlink for given + * policy \link Policy::EventType event\endlink. + * + * Sets audit event keys: + * - type\=Policy\.Device\.Update + * - target\.old\=\ + * - target\.new\=\ + * - device\.system_name\= + * - device\.rule\=\ + * - rule\.source\=\ + * + * Audit policy changes: + * - rule append + * - rule remove + * - rule update + * - policy parameter change + * + * Audit data: + * - who: uid + pid + * - when: time + * - what: append, remove, update + * - update: old, new + * + * @param device Device where the rule target has changed. + * @param old_target Old rule target. + * @param new_target New rule target. + * @param rule_source From where the matched rule is defined. + * @return \link AuditEvent Audit event\endlink. + */ + AuditEvent policyEventSource(std::shared_ptr device, Rule::Target old_target, Rule::Target new_target, + std::string rule_source); + + + /** + * @brief Constructs new \link AuditEvent AuditEvent\endlink for given + * policy \link Policy::EventType event\endlink. + * + * Sets audit event keys: + * - type\=Policy\.Device\.Update + * - target\.old\=\ + * - target\.new\=\ + * - device\.system_name\= + * - device\.rule\=\ + * - rule\.source\=\ + * - rule\.key\=\ + * + * Audit policy changes: + * - rule append + * - rule remove + * - rule update + * - policy parameter change + * + * Audit data: + * - who: uid + pid + * - when: time + * - what: append, remove, update + * - update: old, new + * + * @param device Device where the rule target has changed. + * @param old_target Old rule target. + * @param new_target New rule target. + * @param rule_source From where the matched rule is defined. + * @param matched_rule_key Key of the new rule. + * @return \link AuditEvent Audit event\endlink. + */ + AuditEvent policyEventSourceKey(std::shared_ptr device, Rule::Target old_target, Rule::Target new_target, + std::string rule_source, std::string matched_rule_key); + /** * @brief Constructs new \link AuditEvent AuditEvent\endlink for given * device \link DeviceManager::EventType event\endlink. @@ -544,6 +647,110 @@ namespace usbguard AuditEvent policyEvent(const AuditIdentity& identity, std::shared_ptr device, Rule::Target old_target, Rule::Target new_target); + /** + * @brief Constructs new \link AuditEvent AuditEvent\endlink for given + * policy \link Policy::EventType event\endlink. + * + * Sets audit event keys: + * - type\=Policy\.Device\.Update + * - target\.old\=\ + * - target\.new\=\ + * - device\.system_name\=\ + * - device\.rule\=\ + * - matched\.rule\.key\=\ + * + * Audit policy changes: + * - rule append + * - rule remove + * - rule update + * - policy parameter change + * + * Audit data: + * - who: uid + pid + * - when: time + * - what: append, remove, update + * - update: old, new + * + * @param identity Audit identity. + * @param device Device where the rule target has changed. + * @param old_target Old rule target. + * @param new_target New rule target. + * @param matched_rule_key New rule key. + * @return \link AuditEvent Audit event\endlink. + */ + AuditEvent policyEventKey(const AuditIdentity& identity, std::shared_ptr device, Rule::Target old_target, + Rule::Target new_target, std::string matched_rule_key); + + /** + * @brief Constructs new \link AuditEvent AuditEvent\endlink for given + * policy \link Policy::EventType event\endlink. + * + * Sets audit event keys: + * - type\=Policy\.Device\.Update + * - target\.old\=\ + * - target\.new\=\ + * - device\.system_name\= + * - device\.rule\=\ + * - rule\.source\=\ + * + * Audit policy changes: + * - rule append + * - rule remove + * - rule update + * - policy parameter change + * + * Audit data: + * - who: uid + pid + * - when: time + * - what: append, remove, update + * - update: old, new + * + * @param identity Audit identity. + * @param device Device where the rule target has changed. + * @param old_target Old rule target. + * @param new_target New rule target. + * @param rule_source From where the matched rule is defined. + * @return \link AuditEvent Audit event\endlink. + */ + AuditEvent policyEventSource(const AuditIdentity& identity, std::shared_ptr device, Rule::Target old_target, + Rule::Target new_target, std::string rule_source); + + /** + * @brief Constructs new \link AuditEvent AuditEvent\endlink for given + * policy \link Policy::EventType event\endlink. + * + * Sets audit event keys: + * - type\=Policy\.Device\.Update + * - target\.old\=\ + * - target\.new\=\ + * - device\.system_name\= + * - device\.rule\=\ + * - rule\.source\=\ + * - rule\.key\=\ + * + * Audit policy changes: + * - rule append + * - rule remove + * - rule update + * - policy parameter change + * + * Audit data: + * - who: uid + pid + * - when: time + * - what: append, remove, update + * - update: old, new + * + * @param identity Audit identity. + * @param device Device where the rule target has changed. + * @param old_target Old rule target. + * @param new_target New rule target. + * @param rule_source From where the matched rule is defined. + * @param matched_rule_key Key of the new rule. + * @return \link AuditEvent Audit event\endlink. + */ + AuditEvent policyEventSourceKey(const AuditIdentity& identity, std::shared_ptr device, Rule::Target old_target, + Rule::Target new_target, std::string rule_source, std::string matched_rule_key); + /** * @brief Constructs new \link AuditEvent AuditEvent\endlink for given * device \link DeviceManager::EventType event\endlink. diff --git a/src/Library/public/usbguard/Rule.cpp b/src/Library/public/usbguard/Rule.cpp index 7f2f42b2..65ce31db 100644 --- a/src/Library/public/usbguard/Rule.cpp +++ b/src/Library/public/usbguard/Rule.cpp @@ -106,6 +106,21 @@ namespace usbguard return d_pointer->getSerial(); } + void Rule::setKey(const std::string& value) + { + d_pointer->setKey(value); + } + + const std::string& Rule::getKey() const + { + return d_pointer->getKey(); + } + + bool Rule::hasKey() const + { + return d_pointer->hasKey(); + } + const Rule::Attribute& Rule::attributeSerial() const { return d_pointer->attributeSerial(); diff --git a/src/Library/public/usbguard/Rule.hpp b/src/Library/public/usbguard/Rule.hpp index 9305a860..7f162ef4 100644 --- a/src/Library/public/usbguard/Rule.hpp +++ b/src/Library/public/usbguard/Rule.hpp @@ -819,6 +819,29 @@ namespace usbguard */ const std::string& getSerial() const; + /** + * @brief Sets key attribute. + * + * @param value Key to set. + * @see \link Attribute::set() set()\endlink + */ + void setKey(const std::string& value); + + /** + * @brief Returns key. + * + * @return Rule key. + * @see \link Attribute::get() get()\endlink + */ + const std::string& getKey() const; + + /** + * @brief Returns true if the Rule has a key. + * + * @return Rule key status. + */ + bool hasKey() const; + /** * @brief Returns imutable serial number attribute. * diff --git a/usbguard-daemon.conf.in b/usbguard-daemon.conf.in index f53f03b0..42e04d1e 100644 --- a/usbguard-daemon.conf.in +++ b/usbguard-daemon.conf.in @@ -213,3 +213,12 @@ AuditFilePath=%localstatedir%/log/usbguard/usbguard-audit.log # hashes of descriptors (which include the serial number) from audit entries. # HidePII=false + +# +# When logging policy events, enable differentiation between implicit policy +# events and defined rules. +# +# * true - show rule source in logs +# * false - hide rule source in logs +# +RuleSourceLogging=false \ No newline at end of file