diff --git a/Makefile.am b/Makefile.am index 090e69c..1852983 100644 --- a/Makefile.am +++ b/Makefile.am @@ -138,7 +138,7 @@ man1_MANS=\ AM_CPPFLAGS=\ -I$(top_srcdir)/src \ - -I$(top_srcdir)/src/Library + -I$(top_srcdir)/src/Library/public pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libusbguard.pc @@ -150,6 +150,7 @@ libusbguard_la_CPPFLAGS=\ -fPIC \ -I$(top_srcdir)/src \ -I$(top_srcdir)/src/Library \ + -I$(top_srcdir)/src/Library/public \ -I$(top_builddir)/src/Library/IPC \ @qb_CFLAGS@ \ @protobuf_CFLAGS@ \ @@ -196,94 +197,94 @@ CLEANFILES+=\ $(nodist_libusbguard_la_SOURCES) libusbguard_la_SOURCES=\ - src/Common/Thread.hpp \ src/Common/ByteOrder.hpp \ - src/Common/Utility.hpp \ - src/Common/Utility.cpp \ src/Common/FDInputStream.hpp \ - src/Library/ConfigFile.cpp \ + src/Common/Thread.hpp \ + src/Common/Utility.cpp \ + src/Common/Utility.hpp \ + src/Library/AllowedMatchesCondition.cpp \ + src/Library/AllowedMatchesCondition.hpp \ + src/Library/Base64.cpp \ + src/Library/Base64.hpp \ src/Library/ConfigFilePrivate.cpp \ src/Library/ConfigFilePrivate.hpp \ - src/Library/IPCPrivate.hpp \ - src/Library/IPCPrivate.cpp \ - src/Library/IPCClient.cpp \ - src/Library/IPCClientPrivate.hpp \ + src/Library/DeviceManagerPrivate.cpp \ + src/Library/DeviceManagerPrivate.hpp \ + src/Library/DevicePrivate.cpp \ + src/Library/DevicePrivate.hpp \ + src/Library/FixedStateCondition.cpp \ + src/Library/FixedStateCondition.hpp \ + src/Library/Hash.cpp \ + src/Library/Hash.hpp \ src/Library/IPCClientPrivate.cpp \ - src/Library/IPCServer.cpp \ - src/Library/IPCServerPrivate.hpp \ + src/Library/IPCClientPrivate.hpp \ + src/Library/IPCPrivate.cpp \ + src/Library/IPCPrivate.hpp \ src/Library/IPCServerPrivate.cpp \ - src/Library/USB.cpp \ - src/Library/Rule.cpp \ - src/Library/RuleParser.cpp \ - src/Library/RuleParser.hpp \ - src/Library/RuleParser/Grammar.hpp \ - src/Library/RuleParser/Actions.hpp \ - src/Library/RulePrivate.cpp \ - src/Library/RulePrivate.hpp \ - src/Library/RuleSet.cpp \ - src/Library/RuleSetPrivate.cpp \ - src/Library/RuleSetPrivate.hpp \ - src/Library/Typedefs.cpp \ - src/Library/DeviceManagerHooks.cpp \ - src/Library/Device.cpp \ - src/Library/DevicePrivate.hpp \ - src/Library/DevicePrivate.cpp \ - src/Library/DeviceManager.cpp \ - src/Library/DeviceManagerPrivate.hpp \ - src/Library/DeviceManagerPrivate.cpp \ - src/Library/Logger.cpp \ + src/Library/IPCServerPrivate.hpp \ src/Library/Init.cpp \ - src/Library/RuleCondition.hpp \ - src/Library/RuleCondition.cpp \ - src/Library/AllowedMatchesCondition.hpp \ - src/Library/AllowedMatchesCondition.cpp \ - src/Library/FixedStateCondition.hpp \ - src/Library/FixedStateCondition.cpp \ - src/Library/RandomStateCondition.hpp \ - src/Library/RandomStateCondition.cpp \ - src/Library/LocaltimeCondition.hpp \ src/Library/LocaltimeCondition.cpp \ + src/Library/LocaltimeCondition.hpp \ + src/Library/RandomStateCondition.cpp \ + src/Library/RandomStateCondition.hpp \ src/Library/RuleAppliedCondition.cpp \ src/Library/RuleAppliedCondition.hpp \ src/Library/RuleEvaluatedCondition.cpp \ src/Library/RuleEvaluatedCondition.hpp \ - src/Library/Utility.cpp \ - src/Library/Base64.cpp \ - src/Library/Base64.hpp \ - src/Library/Hash.cpp \ - src/Library/Hash.hpp \ - src/Library/UEvent.hpp \ + src/Library/RuleParser/Actions.hpp \ + src/Library/RuleParser/Grammar.hpp \ + src/Library/RulePrivate.cpp \ + src/Library/RulePrivate.hpp \ + src/Library/RuleSetPrivate.cpp \ + src/Library/RuleSetPrivate.hpp \ + src/Library/SysFSDevice.cpp \ + src/Library/SysFSDevice.hpp \ src/Library/UEvent.cpp \ - src/Library/UEventParser.hpp \ - src/Library/UEventParser.cpp \ - src/Library/UEventDeviceManager.hpp \ + src/Library/UEvent.hpp \ src/Library/UEventDeviceManager.cpp \ - src/Library/SysFSDevice.hpp \ - src/Library/SysFSDevice.cpp \ - src/Library/USBGuard.cpp \ - src/Library/Policy.cpp \ - src/Library/Audit.cpp \ - src/Library/Audit.hpp + src/Library/UEventDeviceManager.hpp \ + src/Library/UEventParser.cpp \ + src/Library/UEventParser.hpp \ + src/Library/Utility.cpp \ + src/Library/Utility.hpp \ + src/Library/public/usbguard/Audit.cpp \ + src/Library/public/usbguard/Audit.hpp \ + src/Library/public/usbguard/ConfigFile.cpp \ + src/Library/public/usbguard/Device.cpp \ + src/Library/public/usbguard/DeviceManager.cpp \ + src/Library/public/usbguard/DeviceManagerHooks.cpp \ + src/Library/public/usbguard/IPCClient.cpp \ + src/Library/public/usbguard/IPCServer.cpp \ + src/Library/public/usbguard/Logger.cpp \ + src/Library/public/usbguard/Policy.cpp \ + src/Library/public/usbguard/Rule.cpp \ + src/Library/public/usbguard/RuleCondition.cpp \ + src/Library/public/usbguard/RuleParser.cpp \ + src/Library/public/usbguard/RuleParser.hpp \ + src/Library/public/usbguard/RuleSet.cpp \ + src/Library/public/usbguard/Typedefs.cpp \ + src/Library/public/usbguard/USB.cpp \ + src/Library/public/usbguard/USBGuard.cpp pkginclude_HEADERS=\ - src/Library/ConfigFile.hpp \ - src/Library/Interface.hpp \ - src/Library/IPCClient.hpp \ - src/Library/IPCServer.hpp \ - src/Library/USB.hpp \ - src/Library/Rule.hpp \ - src/Library/RuleSet.hpp \ - src/Library/Typedefs.hpp \ - src/Library/DeviceManagerHooks.hpp \ - src/Library/Device.hpp \ - src/Library/DeviceManager.hpp \ - src/Library/Logger.hpp \ - src/Library/Predicates.hpp \ - src/Library/Utility.hpp \ - src/Library/Exception.hpp \ - src/Library/USBGuard.hpp \ - src/Library/Policy.hpp \ - src/Library/Audit.hpp + src/Library/public/usbguard/Audit.hpp \ + src/Library/public/usbguard/ConfigFile.hpp \ + src/Library/public/usbguard/Device.hpp \ + src/Library/public/usbguard/DeviceManager.hpp \ + src/Library/public/usbguard/DeviceManagerHooks.hpp \ + src/Library/public/usbguard/Exception.hpp \ + src/Library/public/usbguard/IPCClient.hpp \ + src/Library/public/usbguard/IPCServer.hpp \ + src/Library/public/usbguard/Interface.hpp \ + src/Library/public/usbguard/Logger.hpp \ + src/Library/public/usbguard/Policy.hpp \ + src/Library/public/usbguard/Predicates.hpp \ + src/Library/public/usbguard/Rule.hpp \ + src/Library/public/usbguard/RuleCondition.hpp \ + src/Library/public/usbguard/RuleSet.hpp \ + src/Library/public/usbguard/Typedefs.hpp \ + src/Library/public/usbguard/USB.hpp \ + src/Library/public/usbguard/USBGuard.hpp # Workaround for generated protobuf code mishaps #``` @@ -304,11 +305,9 @@ sbin_PROGRAMS=\ usbguard_daemon_SOURCES=\ src/Daemon/Daemon.cpp \ src/Daemon/Daemon.hpp \ - src/Daemon/Exceptions.hpp \ src/Daemon/main.cpp \ src/Daemon/Seccomp.c \ src/Daemon/Seccomp.h \ - src/Common/CCBQueue.hpp \ src/Common/Utility.hpp \ src/Common/Utility.cpp diff --git a/configure.ac b/configure.ac index 0c9a525..287abf2 100644 --- a/configure.ac +++ b/configure.ac @@ -17,6 +17,7 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])]) # EXTERNAL_CXXFLAGS="$CXXFLAGS" EXTERNAL_CFLAGS="$CFLAGS" +EXTERNAL_CPPFLAGS="$CPPFLAGS" COMMON_WARNING_FLAGS=" -pedantic" COMMON_WARNING_FLAGS+=" -Wno-unknown-pragmas" @@ -54,6 +55,7 @@ AX_CHECK_COMPILE_FLAG([-Wno-implicit-fallthrough], # CXXFLAGS="-std=c++11 $EXTERNAL_CXXFLAGS" CFLAGS="-std=c99 $EXTERNAL_CFLAGS" +CPPFLAGS="-DHAVE_BUILD_CONFIG_H $EXTERNAL_CPPFLAGS" # # Additional CXXFLAGS used when --enable-debug-build is used diff --git a/src/CLI/IPCSignalWatcher.cpp b/src/CLI/IPCSignalWatcher.cpp index 3dbb616..d4e9e1a 100644 --- a/src/CLI/IPCSignalWatcher.cpp +++ b/src/CLI/IPCSignalWatcher.cpp @@ -16,6 +16,10 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include #include "IPCSignalWatcher.hpp" diff --git a/src/CLI/IPCSignalWatcher.hpp b/src/CLI/IPCSignalWatcher.hpp index 36e979e..2101def 100644 --- a/src/CLI/IPCSignalWatcher.hpp +++ b/src/CLI/IPCSignalWatcher.hpp @@ -17,7 +17,11 @@ // Authors: Daniel Kopecek // #pragma once -#include +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/IPCClient.hpp" namespace usbguard { diff --git a/src/CLI/PolicyGenerator.cpp b/src/CLI/PolicyGenerator.cpp index 277019f..1035e40 100644 --- a/src/CLI/PolicyGenerator.cpp +++ b/src/CLI/PolicyGenerator.cpp @@ -16,6 +16,10 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "PolicyGenerator.hpp" namespace usbguard @@ -77,7 +81,7 @@ namespace usbguard _catchall_target = target; } - void PolicyGenerator::dmHookDeviceEvent(DeviceManager::EventType event, Pointer device) + void PolicyGenerator::dmHookDeviceEvent(DeviceManager::EventType event, std::shared_ptr device) { if (event != DeviceManager::EventType::Present) { /* @@ -96,11 +100,11 @@ namespace usbguard port_specific = device->getSerial().empty(); } - Pointer rule = device->getDeviceRule(/*include_port=*/port_specific); + std::shared_ptr rule = device->getDeviceRule(/*include_port=*/port_specific); /* Remove everything but the hash value for hash-only rules */ if (_hash_only) { - Pointer rule_hashonly(new Rule()); + std::shared_ptr rule_hashonly(new Rule()); rule_hashonly->setRuleID(rule->getRuleID()); rule_hashonly->setHash(rule->getHash()); rule_hashonly->setParentHash(rule->getParentHash()); @@ -127,7 +131,7 @@ namespace usbguard return _ruleset.assignID(); } - void PolicyGenerator::dmHookDeviceException(const String& message) + void PolicyGenerator::dmHookDeviceException(const std::string& message) { USBGUARD_LOG(Error) << message; } diff --git a/src/CLI/PolicyGenerator.hpp b/src/CLI/PolicyGenerator.hpp index bbb872a..5de5429 100644 --- a/src/CLI/PolicyGenerator.hpp +++ b/src/CLI/PolicyGenerator.hpp @@ -16,10 +16,14 @@ // // Authors: Daniel Kopecek // -#include -#include -#include -#include +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Rule.hpp" +#include "usbguard/RuleSet.hpp" +#include "usbguard/DeviceManager.hpp" +#include "usbguard/DeviceManagerHooks.hpp" namespace usbguard { @@ -37,13 +41,13 @@ namespace usbguard void generate(); const RuleSet& refRuleSet() const; - void dmHookDeviceEvent(DeviceManager::EventType event, Pointer device) override; + void dmHookDeviceEvent(DeviceManager::EventType event, std::shared_ptr device) override; uint32_t dmHookAssignID() override; - void dmHookDeviceException(const String& message) override; + void dmHookDeviceException(const std::string& message) override; private: RuleSet _ruleset; - Pointer _dm; + std::shared_ptr _dm; bool _with_hash; bool _hash_only; diff --git a/src/CLI/usbguard-add-user.cpp b/src/CLI/usbguard-add-user.cpp index 228c08d..e8307ea 100644 --- a/src/CLI/usbguard-add-user.cpp +++ b/src/CLI/usbguard-add-user.cpp @@ -16,11 +16,18 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-add-user.hpp" -#include -#include + +#include "usbguard/USBGuard.hpp" +#include "usbguard/IPCServer.hpp" + #include + #include #include diff --git a/src/CLI/usbguard-add-user.hpp b/src/CLI/usbguard-add-user.hpp index 9bd8b12..73d74f4 100644 --- a/src/CLI/usbguard-add-user.hpp +++ b/src/CLI/usbguard-add-user.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_add_user(int argc, char **argv); diff --git a/src/CLI/usbguard-allow-device.cpp b/src/CLI/usbguard-allow-device.cpp index 7a3cf07..449218c 100644 --- a/src/CLI/usbguard-allow-device.cpp +++ b/src/CLI/usbguard-allow-device.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-allow-device.hpp" -#include +#include "usbguard/IPCClient.hpp" + #include namespace usbguard diff --git a/src/CLI/usbguard-allow-device.hpp b/src/CLI/usbguard-allow-device.hpp index 80cdd34..d236a69 100644 --- a/src/CLI/usbguard-allow-device.hpp +++ b/src/CLI/usbguard-allow-device.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_allow_device(int argc, char **argv); diff --git a/src/CLI/usbguard-append-rule.cpp b/src/CLI/usbguard-append-rule.cpp index c455905..ab1adbb 100644 --- a/src/CLI/usbguard-append-rule.cpp +++ b/src/CLI/usbguard-append-rule.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-append-rule.hpp" -#include +#include "usbguard/IPCClient.hpp" + #include namespace usbguard diff --git a/src/CLI/usbguard-append-rule.hpp b/src/CLI/usbguard-append-rule.hpp index 1a1b229..049a40d 100644 --- a/src/CLI/usbguard-append-rule.hpp +++ b/src/CLI/usbguard-append-rule.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_append_rule(int argc, char **argv); diff --git a/src/CLI/usbguard-block-device.cpp b/src/CLI/usbguard-block-device.cpp index 71bd011..b4100bc 100644 --- a/src/CLI/usbguard-block-device.cpp +++ b/src/CLI/usbguard-block-device.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-block-device.hpp" -#include +#include "usbguard/IPCClient.hpp" + #include namespace usbguard diff --git a/src/CLI/usbguard-block-device.hpp b/src/CLI/usbguard-block-device.hpp index b0e1812..8962e7b 100644 --- a/src/CLI/usbguard-block-device.hpp +++ b/src/CLI/usbguard-block-device.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_block_device(int argc, char **argv); diff --git a/src/CLI/usbguard-generate-policy.cpp b/src/CLI/usbguard-generate-policy.cpp index 47bbbc0..207aa5d 100644 --- a/src/CLI/usbguard-generate-policy.cpp +++ b/src/CLI/usbguard-generate-policy.cpp @@ -16,15 +16,20 @@ // // Authors: Daniel Kopecek // -#include -#include -#include +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif #include "usbguard.hpp" #include "usbguard-generate-policy.hpp" #include "PolicyGenerator.hpp" #include "Common/Utility.hpp" +#include "usbguard/DeviceManager.hpp" + +#include +#include + namespace usbguard { static const char *options_short = "hpPt:HX"; diff --git a/src/CLI/usbguard-generate-policy.hpp b/src/CLI/usbguard-generate-policy.hpp index 464edfa..3d3d975 100644 --- a/src/CLI/usbguard-generate-policy.hpp +++ b/src/CLI/usbguard-generate-policy.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_generate_policy(int argc, char **argv); diff --git a/src/CLI/usbguard-get-parameter.cpp b/src/CLI/usbguard-get-parameter.cpp index 2a1ce08..b81f416 100644 --- a/src/CLI/usbguard-get-parameter.cpp +++ b/src/CLI/usbguard-get-parameter.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-get-parameter.hpp" -#include +#include "usbguard/IPCClient.hpp" + #include namespace usbguard diff --git a/src/CLI/usbguard-get-parameter.hpp b/src/CLI/usbguard-get-parameter.hpp index fdd74fe..147cd15 100644 --- a/src/CLI/usbguard-get-parameter.hpp +++ b/src/CLI/usbguard-get-parameter.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_get_parameter(int argc, char **argv); diff --git a/src/CLI/usbguard-list-devices.cpp b/src/CLI/usbguard-list-devices.cpp index 01389df..94112d6 100644 --- a/src/CLI/usbguard-list-devices.cpp +++ b/src/CLI/usbguard-list-devices.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-list-devices.hpp" -#include +#include "usbguard/IPCClient.hpp" + #include namespace usbguard diff --git a/src/CLI/usbguard-list-devices.hpp b/src/CLI/usbguard-list-devices.hpp index 0b99454..563f754 100644 --- a/src/CLI/usbguard-list-devices.hpp +++ b/src/CLI/usbguard-list-devices.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_list_devices(int argc, char **argv); diff --git a/src/CLI/usbguard-list-rules.cpp b/src/CLI/usbguard-list-rules.cpp index 396c3c8..2508d5a 100644 --- a/src/CLI/usbguard-list-rules.cpp +++ b/src/CLI/usbguard-list-rules.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-list-rules.hpp" -#include +#include "usbguard/IPCClient.hpp" + #include namespace usbguard diff --git a/src/CLI/usbguard-list-rules.hpp b/src/CLI/usbguard-list-rules.hpp index 9508e1b..60ccccc 100644 --- a/src/CLI/usbguard-list-rules.hpp +++ b/src/CLI/usbguard-list-rules.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_list_rules(int argc, char **argv); diff --git a/src/CLI/usbguard-read-descriptor.cpp b/src/CLI/usbguard-read-descriptor.cpp index deb3364..451fb8f 100644 --- a/src/CLI/usbguard-read-descriptor.cpp +++ b/src/CLI/usbguard-read-descriptor.cpp @@ -16,10 +16,16 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-read-descriptor.hpp" -#include -#include + +#include "usbguard/USB.hpp" +#include "usbguard/Exception.hpp" + #include #include #include diff --git a/src/CLI/usbguard-read-descriptor.hpp b/src/CLI/usbguard-read-descriptor.hpp index ca505a4..8310dae 100644 --- a/src/CLI/usbguard-read-descriptor.hpp +++ b/src/CLI/usbguard-read-descriptor.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_read_descriptor(int argc, char **argv); diff --git a/src/CLI/usbguard-reject-device.cpp b/src/CLI/usbguard-reject-device.cpp index adaaa18..08649a3 100644 --- a/src/CLI/usbguard-reject-device.cpp +++ b/src/CLI/usbguard-reject-device.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-reject-device.hpp" -#include +#include "usbguard/IPCClient.hpp" + #include namespace usbguard diff --git a/src/CLI/usbguard-reject-device.hpp b/src/CLI/usbguard-reject-device.hpp index 2d54a37..8d42276 100644 --- a/src/CLI/usbguard-reject-device.hpp +++ b/src/CLI/usbguard-reject-device.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_reject_device(int argc, char **argv); diff --git a/src/CLI/usbguard-remove-rule.cpp b/src/CLI/usbguard-remove-rule.cpp index b99dc0f..05acd0a 100644 --- a/src/CLI/usbguard-remove-rule.cpp +++ b/src/CLI/usbguard-remove-rule.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-remove-rule.hpp" -#include +#include "usbguard/IPCClient.hpp" + #include namespace usbguard diff --git a/src/CLI/usbguard-remove-rule.hpp b/src/CLI/usbguard-remove-rule.hpp index e31a11f..0c0f9e0 100644 --- a/src/CLI/usbguard-remove-rule.hpp +++ b/src/CLI/usbguard-remove-rule.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_remove_rule(int argc, char **argv); diff --git a/src/CLI/usbguard-remove-user.cpp b/src/CLI/usbguard-remove-user.cpp index 89cc5ba..23fe05e 100644 --- a/src/CLI/usbguard-remove-user.cpp +++ b/src/CLI/usbguard-remove-user.cpp @@ -16,11 +16,18 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-remove-user.hpp" -#include -#include + +#include "usbguard/USBGuard.hpp" +#include "usbguard/IPCServer.hpp" + #include + #include namespace usbguard diff --git a/src/CLI/usbguard-remove-user.hpp b/src/CLI/usbguard-remove-user.hpp index d32a0a6..ce2b4db 100644 --- a/src/CLI/usbguard-remove-user.hpp +++ b/src/CLI/usbguard-remove-user.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_remove_user(int argc, char **argv); diff --git a/src/CLI/usbguard-rule-parser.cpp b/src/CLI/usbguard-rule-parser.cpp index 6a85b15..cdb880a 100644 --- a/src/CLI/usbguard-rule-parser.cpp +++ b/src/CLI/usbguard-rule-parser.cpp @@ -16,15 +16,21 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Rule.hpp" +#include "usbguard/RuleParser.hpp" + #include #ifndef _GNU_SOURCE # define _GNU_SOURCE #endif #include #include + #include -#include "Rule.hpp" -#include "RuleParser.hpp" static const char *options_short = "hft"; diff --git a/src/CLI/usbguard-set-parameter.cpp b/src/CLI/usbguard-set-parameter.cpp index c3a141c..9df5ce6 100644 --- a/src/CLI/usbguard-set-parameter.cpp +++ b/src/CLI/usbguard-set-parameter.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-set-parameter.hpp" -#include +#include "usbguard/IPCClient.hpp" + #include namespace usbguard diff --git a/src/CLI/usbguard-set-parameter.hpp b/src/CLI/usbguard-set-parameter.hpp index d3c238c..116f400 100644 --- a/src/CLI/usbguard-set-parameter.hpp +++ b/src/CLI/usbguard-set-parameter.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_set_parameter(int argc, char **argv); diff --git a/src/CLI/usbguard-watch.cpp b/src/CLI/usbguard-watch.cpp index bd1cb0d..da333f3 100644 --- a/src/CLI/usbguard-watch.cpp +++ b/src/CLI/usbguard-watch.cpp @@ -16,6 +16,10 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "usbguard.hpp" #include "usbguard-watch.hpp" diff --git a/src/CLI/usbguard-watch.hpp b/src/CLI/usbguard-watch.hpp index 1be98ef..f538715 100644 --- a/src/CLI/usbguard-watch.hpp +++ b/src/CLI/usbguard-watch.hpp @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + namespace usbguard { int usbguard_watch(int argc, char **argv); diff --git a/src/CLI/usbguard.cpp b/src/CLI/usbguard.cpp index faf1a5d..77c5497 100644 --- a/src/CLI/usbguard.cpp +++ b/src/CLI/usbguard.cpp @@ -16,11 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include +#endif + +#include "usbguard/Logger.hpp" +#include "usbguard/Exception.hpp" + #include #include -#include -#include #ifndef _GNU_SOURCE # define _GNU_SOURCE diff --git a/src/CLI/usbguard.hpp b/src/CLI/usbguard.hpp index 9688c3d..dace3e4 100644 --- a/src/CLI/usbguard.hpp +++ b/src/CLI/usbguard.hpp @@ -16,12 +16,17 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Logger.hpp" + #include #include #include -#include "Logger.hpp" - namespace usbguard { extern const char *usbguard_arg0; diff --git a/src/Common/ByteOrder.hpp b/src/Common/ByteOrder.hpp index c7a4650..7f2e88d 100644 --- a/src/Common/ByteOrder.hpp +++ b/src/Common/ByteOrder.hpp @@ -17,6 +17,10 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include #include diff --git a/src/Common/CCBQueue.hpp b/src/Common/CCBQueue.hpp deleted file mode 100644 index 1686991..0000000 --- a/src/Common/CCBQueue.hpp +++ /dev/null @@ -1,256 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#ifndef CCBQUEUE_HPP -#define CCBQUEUE_HPP - -#include -#include -#include - -#ifndef CCBQUEUE_STATE_BITS -# define CCBQUEUE_STATE_BITS 32 -#endif - -namespace CCBQueueOpt -{ - enum BlockingMethod { - NoBlocking, - Spinlock, - Yield, - ConstSleep, - AdaptiveSleep - }; -} - -template(nullptr)> -class CCBQueue -{ -public: -#if CCBQUEUE_STATE_BITS == 64 - typedef uint32_t index_type; - typedef uint32_t count_type; - typedef uint64_t state_type; - const index_type invalid_index = UINT32_MAX; - const count_type count_type_max = UINT32_MAX; -#elif CCBQUEUE_STATE_BITS == 32 - typedef uint16_t index_type; - typedef uint16_t count_type; - typedef uint32_t state_type; - const index_type invalid_index = UINT16_MAX; - const count_type count_type_max = UINT16_MAX; -#elif CCBQUEUE_STATE_BITS == 16 - typedef uint8_t index_type; - typedef uint8_t count_type; - typedef uint16_t state_type; - const index_type invalid_index = UINT8_MAX; - const count_type count_type_max = UINT8_MAX; -#else -# error "Invalid CCBQUEUE_STATE_BITS value. Must be one of: 64, 32, 16." -#endif -private: - union State { - struct { - index_type begin; - count_type count; - }; - state_type unified; - }; - - uint8_t* _queue_mem; - const size_t _item_size; - const count_type _capacity; - - State _r_state; // readability state - State _w_state; // writability state - -protected: - T* indexToPointer(index_type index) const __attribute__((/*returns_nonnull,*/ nothrow, hot)) - { - return (T *)(((uintptr_t)_queue_mem) + (_item_size * index)); - } - - index_type pointerToIndex(const T* pointer) const __attribute__((nonnull, nothrow, hot)) - { - return (index_type)((((uintptr_t)pointer) - ((uintptr_t)_queue_mem)) / _item_size); - } - - // Modifies write state (++count) - index_type acquireFreeIndex() __attribute__((nothrow)) - { - State w_state_old, w_state_new; - do { - // Read the current state - w_state_old.unified = _w_state.unified; - // Check whether there's scape for a new item - if (w_state_old.count >= _capacity) { - // No free index - return invalid_index; - } - // Create a new state - w_state_new.unified = w_state_old.unified; - ++w_state_new.count; - // - // Try to atomically update the state, repeat the - // whole process if it fails - // - } while(!__sync_bool_compare_and_swap(&_w_state.unified, - w_state_old.unified, - w_state_new.unified)); - - return ((w_state_old.begin + w_state_old.count) % _capacity); - } - - // Modifies read state (++begin, --count) - index_type acquireReadIndex() __attribute__((nothrow)) - { - State r_state_old, r_state_new; - do { - // Read the current state - r_state_old.unified = _r_state.unified; - // Check whether there's something to read - if (r_state_old.count == 0) { - return invalid_index; - } - // Create a new state - r_state_new.unified = r_state_old.unified; - --r_state_new.count; - // Wrap the .begin index if needed - if (++r_state_new.begin == _capacity) { - r_state_new.begin = 0; - } - // - // Try to atomically update the state, repeat the - // while process if it fails - // - } while(!__sync_bool_compare_and_swap(&_r_state.unified, - r_state_old.unified, - r_state_new.unified)); - return r_state_old.begin; - } - - index_type nextEnqueueIndex() __attribute__((nothrow)) - { - State r_state; - r_state.unified = __sync_add_and_fetch(&_r_state.unified, 0); - return ((r_state.begin + r_state.count) % _capacity); - } - - index_type nextReleaseIndex() __attribute__((nothrow)) - { - State w_state; - w_state.unified = __sync_add_and_fetch(&_w_state.unified, 0); - return w_state.begin; - } - -public: - CCBQueue(uint32_t max_memory_MiB) - : _item_size(sizeof(T)), - _capacity(((max_memory_MiB*1<<20)/sizeof(T))>count_type_max? - count_type_max:(max_memory_MiB*1<<20)/sizeof(T)) - { - _queue_mem = new uint8_t[_capacity * _item_size]; - _w_state.unified = 0; - _r_state.unified = 0; - } - - ~CCBQueue() - { - delete [] _queue_mem; - } - - T* acquire() __attribute__((nothrow)) - { - const index_type free_index = acquireFreeIndex(); - if (free_index == invalid_index) { - /* No free space */ - return nullptr; - } - else { - return indexToPointer(free_index); - } - } - - // Modifies read state (++count) - bool enqueue(const T* item) __attribute__((nonnull, nothrow)) - { - // Check that we can enqueue the item - if (pointerToIndex(item) != nextEnqueueIndex()) { - return false; - } - // Enqueue the item / Update readability state - State r_state_old, r_state_new; - - do { - r_state_old.unified = _r_state.unified; - r_state_new.unified = r_state_old.unified; - ++r_state_new.count; - } while(!__sync_bool_compare_and_swap(&_r_state.unified, - r_state_old.unified, - r_state_new.unified)); - return true; - } - - const T* dequeue() __attribute__((nothrow)) - { - const index_type index = acquireReadIndex(); - if (index == invalid_index) { - return nullptr; - } - else { - return indexToPointer(index); - } - } - - // Modifies write state (++begin, --count) - bool release(const T* item) __attribute__((nonnull, nothrow)) - { - // Check that we can release the item - if (pointerToIndex(item) != nextReleaseIndex()) { - return false; - } - - State w_state_old, w_state_new; - - do { - // Read the current state - w_state_old.unified = _w_state.unified; - // Create an updated state - w_state_new.unified = w_state_old.unified; - --w_state_new.count; - if (++w_state_new.begin == _capacity) { - w_state_new.begin = 0; - } - // Atomically update the state - } while(!__sync_bool_compare_and_swap(&_w_state.unified, - w_state_old.unified, - w_state_new.unified)); - return true; - } - - // Returns number of queued items - count_type count() const - { - return _r_state.count; - } - -}; - -#endif /* CCBQUEUE_HPP */ diff --git a/src/Common/FDInputStream.hpp b/src/Common/FDInputStream.hpp index 5ab319b..4d6a92c 100644 --- a/src/Common/FDInputStream.hpp +++ b/src/Common/FDInputStream.hpp @@ -17,8 +17,10 @@ // Authors: Daniel Kopecek // #pragma once - +#ifdef HAVE_BUILD_CONFIG_H #include +#endif + #include #include #include diff --git a/src/Common/Thread.hpp b/src/Common/Thread.hpp index b413b4a..04730b8 100644 --- a/src/Common/Thread.hpp +++ b/src/Common/Thread.hpp @@ -17,8 +17,11 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif -#include "Logger.hpp" +#include "usbguard/Logger.hpp" #include #include diff --git a/src/Common/Utility.cpp b/src/Common/Utility.cpp index 2867ccf..f84d2a8 100644 --- a/src/Common/Utility.cpp +++ b/src/Common/Utility.cpp @@ -16,23 +16,28 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include -#include +#endif + +#include "usbguard/Logger.hpp" + #include "Common/Utility.hpp" +#include +#include + +#include +#include +#include #include -#include -#include -#include #include -#include +#include #include +#include +#include #include -#include -#include -#include -#include -#include +#include namespace usbguard { @@ -77,7 +82,7 @@ namespace usbguard return; } - bool writePID(const String& filepath) + bool writePID(const std::string& filepath) { std::ofstream pidstream(filepath, std::ios_base::trunc); if (!pidstream) { @@ -87,7 +92,7 @@ namespace usbguard return true; } - static void runCommandExecChild(const String& path, const std::vector& args) + static void runCommandExecChild(const std::string& path, const std::vector& args) { struct rlimit rlim; @@ -147,20 +152,20 @@ namespace usbguard int runCommand(const char * const path, const char * const arg1, const int timeout_secs) { - std::vector args; + std::vector args; args.push_back(arg1); return runCommand(path, args, timeout_secs); } int runCommand(const char * const path, const char * const arg1, const char * const arg2, const int timeout_secs) { - std::vector args; + std::vector args; args.push_back(arg1); args.push_back(arg2); return runCommand(path, args, timeout_secs); } - int runCommand(const String& path, const std::vector& args, const int timeout_secs) + int runCommand(const std::string& path, const std::vector& args, const int timeout_secs) { int retval = 0, status = 0; bool timedout = false; @@ -218,18 +223,18 @@ namespace usbguard return retval; } - String filenameFromPath(const String& filepath, const bool include_extension) + std::string filenameFromPath(const std::string& filepath, const bool include_extension) { - const String directory_separator = "/"; - StringVector path_tokens; + const std::string directory_separator = "/"; + std::vector path_tokens; tokenizeString(filepath, path_tokens, directory_separator); if (path_tokens.size() == 0) { - return String(); + return std::string(); } - const String& filename = path_tokens.back(); + const std::string& filename = path_tokens.back(); if (include_extension) { return filename; @@ -240,10 +245,10 @@ namespace usbguard return filename.substr(0, substr_to); } - String parentPath(const String& path) + std::string parentPath(const std::string& path) { - const String directory_separator = "/"; - String parent_path(path); + const std::string directory_separator = "/"; + std::string parent_path(path); // find first not '/' (from end) // find first '/' (from end) @@ -256,7 +261,7 @@ namespace usbguard * Whole path consists only of '/'. */ if (reverse_start_pos == std::string::npos) { - return String(); + return std::string(); } reverse_start_pos = \ @@ -266,7 +271,7 @@ namespace usbguard * No directory separator in the rest of the path. */ if (reverse_start_pos == std::string::npos) { - return String(); + return std::string(); } reverse_start_pos = \ @@ -277,41 +282,41 @@ namespace usbguard * /foo/bar => /foo * /foo/bar/ => /foo * /foo/bar// => /foo - * /foo => String() - * /foo/ => String() - * / => String() - * //foo => String() + * /foo => std::string() + * /foo/ => std::string() + * / => std::string() + * //foo => std::string() * */ if (reverse_start_pos == std::string::npos) { - return String(); + return std::string(); } return path.substr(0, reverse_start_pos + 1); } - String trimRight(const String& s, const String& delimiters) + std::string trimRight(const std::string& s, const std::string& delimiters) { const size_t substr_to = s.find_last_not_of(delimiters); if (substr_to != std::string::npos) { return s.substr(0, substr_to + 1); } else { - return String(); + return std::string(); } } - String trimLeft(const String& s, const String& delimiters) + std::string trimLeft(const std::string& s, const std::string& delimiters) { const size_t substr_from = s.find_first_not_of(delimiters); - if (substr_from == String::npos) { + if (substr_from == std::string::npos) { return s; } else { return s.substr(substr_from); } } - String trim(const String& s, const String& delimiters) + std::string trim(const std::string& s, const std::string& delimiters) { return trimRight(trimLeft(s, delimiters), delimiters); } @@ -323,20 +328,20 @@ namespace usbguard * an unsigned int. */ template<> - String numberToString(const uint8_t number, const String& prefix, const int base, const int align, const char align_char) + std::string numberToString(const uint8_t number, const std::string& prefix, const int base, const int align, const char align_char) { const uint16_t n = static_cast(number); return numberToString(n, prefix, base, align, align_char); } template<> - uint8_t stringToNumber(const String& s, const int base) + uint8_t stringToNumber(const std::string& s, const int base) { const unsigned int num = stringToNumber(s, base); return (uint8_t)num; } - bool isNumericString(const String& s) + bool isNumericString(const std::string& s) { for (int c : s) { if (!isdigit(c)) { @@ -346,10 +351,10 @@ namespace usbguard return true; } - int loadFiles(const String& directory, - std::function filter, - std::function loader, - std::function&, const std::pair&)> sorter) + int loadFiles(const std::string& directory, + std::function filter, + std::function loader, + std::function&, const std::pair&)> sorter) { DIR* dirobj = opendir(directory.c_str()); int retval = 0; @@ -358,7 +363,7 @@ namespace usbguard throw ErrnoException("loadFiles", directory, errno); } try { - std::vector> loadpaths; + std::vector> loadpaths; struct dirent *entry_ptr = nullptr; /* * readdir usage note: We rely on the fact that readdir should be thread-safe @@ -367,14 +372,14 @@ namespace usbguard * readdir_r, is deprecated in newer versions of glibc. */ while((entry_ptr = readdir(dirobj)) != nullptr) { - const String filename(entry_ptr->d_name); + const std::string filename(entry_ptr->d_name); if (filename == "." || filename == "..") { continue; } - String fullpath = directory + "/" + filename; - String loadpath = filter(fullpath, entry_ptr); + std::string fullpath = directory + "/" + filename; + std::string loadpath = filter(fullpath, entry_ptr); if (!loadpath.empty()) { loadpaths.emplace_back(std::make_pair(std::move(loadpath),std::move(fullpath))); @@ -400,7 +405,7 @@ namespace usbguard return retval; } - String removePrefix(const String& prefix, const String& value) + std::string removePrefix(const std::string& prefix, const std::string& value) { if (value.compare(0, prefix.size(), prefix) == 0) { return value.substr(prefix.size()); @@ -410,7 +415,7 @@ namespace usbguard } } - String symlinkPath(const String& linkpath, struct stat *st_user) + std::string symlinkPath(const std::string& linkpath, struct stat *st_user) { struct stat st = { }; struct stat *st_ptr = nullptr; @@ -440,7 +445,7 @@ namespace usbguard throw Exception("symlinkPath", linkpath, "symlink value size out of range"); } - String buffer(st_ptr->st_size, 0); + std::string buffer(st_ptr->st_size, 0); const ssize_t link_size = readlink(linkpath.c_str(), &buffer[0], buffer.capacity()); if (link_size <= 0 || link_size > st_ptr->st_size) { diff --git a/src/Common/Utility.hpp b/src/Common/Utility.hpp index 1ca922b..f722b22 100644 --- a/src/Common/Utility.hpp +++ b/src/Common/Utility.hpp @@ -17,20 +17,26 @@ // Authors: Daniel Kopecek // #pragma once -#include "Typedefs.hpp" -#include "Exception.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Exception.hpp" +#include "usbguard/Typedefs.hpp" + +#include +#include +#include +#include +#include #include +#include #include -#include -#include -#include -#include + #include -#include -#include -#include #include -#include +#include +#include namespace usbguard { @@ -51,7 +57,7 @@ namespace usbguard * Writes the current PID to a file at filepath. * Returns true on success, otherwise returns false. */ - bool writePID(const String& filepath); + bool writePID(const std::string& filepath); /** * Wrappers for the __builtin_expect function. @@ -66,7 +72,7 @@ namespace usbguard int runCommand(const char *path, const char *arg1, int timeout_secs = 10); int runCommand(const char *path, const char *arg1, const char *arg2, int timeout_secs = 10); - int runCommand(const String& path, const std::vector& args = std::vector(), int timeout_secs = 10); + int runCommand(const std::string& path, const std::vector& args = std::vector(), int timeout_secs = 10); /** * Tokenize a std::string compatible type using delimiters specified in a string. @@ -105,15 +111,15 @@ namespace usbguard * representation. */ template - String numberToString(const T number, const String& prefix = String(), const int base = 10, const int align = -1, const char align_char = ' ') + std::string numberToString(const T number, const std::string& prefix = std::string(), const int base = 10, const int align = -1, const char align_char = ' ') { std::ostringstream ss; ss << std::setbase(base); ss << number; - const String number_string = ss.str(); - String result; + const std::string number_string = ss.str(); + std::string result; result.append(prefix); if (align > 0 && number_string.size() < (size_t)align) { @@ -128,14 +134,14 @@ namespace usbguard } template<> - String numberToString(const uint8_t number, const String& prefix, const int base, const int align, const char align_char); + std::string numberToString(const uint8_t number, const std::string& prefix, const int base, const int align, const char align_char); /** * Convert a string representation of a number * to a number of type T. */ template - T stringToNumber(const String& s, const int base = 10) + T stringToNumber(const std::string& s, const int base = 10) { std::istringstream ss(s); T num; @@ -144,9 +150,9 @@ namespace usbguard } template<> - uint8_t stringToNumber(const String& s, const int base); + uint8_t stringToNumber(const std::string& s, const int base); - bool isNumericString(const String& s); + bool isNumericString(const std::string& s); /** * Return the filename part of a path. If include_extension is set to @@ -159,48 +165,48 @@ namespace usbguard * "/foo/bar/baz.woo.txt" (include_extension=false) => "baz.woo" * "foo.txt" (include_extension=true) => "foo.txt" */ - String filenameFromPath(const String& filepath, bool include_extension = false); + std::string filenameFromPath(const std::string& filepath, bool include_extension = false); /** * Return the parent path part of a path. */ - String parentPath(const String& path); + std::string parentPath(const std::string& path); /** * Remove whitespace characters from the right side of a string. */ - String trimRight(const String& s, const String& delimiters = " \f\n\r\t\v"); + std::string trimRight(const std::string& s, const std::string& delimiters = " \f\n\r\t\v"); /** * Remove whitespace characters from the left side of a string. */ - String trimLeft(const String& s, const String& delimiters = " \f\n\r\t\v"); + std::string trimLeft(const std::string& s, const std::string& delimiters = " \f\n\r\t\v"); /** * Remove whitespace characters from the left & right side of a string. */ - String trim(const String& s, const String& delimiters = " \f\n\r\t\v"); + std::string trim(const std::string& s, const std::string& delimiters = " \f\n\r\t\v"); /** - * Call a void(*)(const String&) compatible method for every file in a directory + * Call a void(*)(const std::string&) compatible method for every file in a directory * matching a regular expression. The function does not recursively descent into * subdirectories. */ - int loadFiles(const String& directory, - std::function filter, - std::function loader, - std::function&, const std::pair&)> sorter = \ - [](const std::pair& a, const std::pair& b) { return a.first < b.first; }); + int loadFiles(const std::string& directory, + std::function filter, + std::function loader, + std::function&, const std::pair&)> sorter = \ + [](const std::pair& a, const std::pair& b) { return a.first < b.first; }); /** * Remove prefix from string. */ - String removePrefix(const String& prefix, const String& value); + std::string removePrefix(const std::string& prefix, const std::string& value); /** * Read symlink destination. */ - String symlinkPath(const String& linkpath, struct stat *st_user = nullptr); + std::string symlinkPath(const std::string& linkpath, struct stat *st_user = nullptr); /* * Restorer class diff --git a/src/DBus/DBusBridge.cpp b/src/DBus/DBusBridge.cpp index 7985304..02c6bbc 100644 --- a/src/DBus/DBusBridge.cpp +++ b/src/DBus/DBusBridge.cpp @@ -16,6 +16,10 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "DBusBridge.hpp" namespace usbguard diff --git a/src/DBus/DBusBridge.hpp b/src/DBus/DBusBridge.hpp index 2c15945..fe8a5ac 100644 --- a/src/DBus/DBusBridge.hpp +++ b/src/DBus/DBusBridge.hpp @@ -17,14 +17,17 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/IPCClient.hpp" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-register" #include #pragma clang diagnostic pop -#include "IPCClient.hpp" - namespace usbguard { class DBusBridge : public IPCClient diff --git a/src/DBus/gdbus-server.cpp b/src/DBus/gdbus-server.cpp index fee0329..8f596b8 100644 --- a/src/DBus/gdbus-server.cpp +++ b/src/DBus/gdbus-server.cpp @@ -16,6 +16,10 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include #include #include diff --git a/src/Daemon/Daemon.cpp b/src/Daemon/Daemon.cpp index 4e93f91..b317c85 100644 --- a/src/Daemon/Daemon.cpp +++ b/src/Daemon/Daemon.cpp @@ -16,15 +16,16 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include +#endif #include "Daemon.hpp" -#include "Logger.hpp" #include "Common/Utility.hpp" -#include "IPCPrivate.hpp" -#include "RulePrivate.hpp" -#include "RuleParser.hpp" -#include "Audit.hpp" + +#include "usbguard/Logger.hpp" +#include "usbguard/RuleParser.hpp" +#include "usbguard/Audit.hpp" #include #include @@ -36,7 +37,6 @@ #include #include #include - #include #include @@ -47,7 +47,7 @@ namespace usbguard * unknown setting is found in the config file, * a warning message will be displayed. */ - static const StringVector G_config_known_names = { + static const std::vector G_config_known_names = { "RuleFile", "ImplicitPolicyTarget", "PresentDevicePolicy", @@ -62,7 +62,7 @@ namespace usbguard "AuditFilePath" }; - static const std::vector > device_policy_method_strings = { + static const std::vector > device_policy_method_strings = { { "allow", Daemon::DevicePolicyMethod::Allow }, { "block", Daemon::DevicePolicyMethod::Block }, { "reject", Daemon::DevicePolicyMethod::Reject }, @@ -70,7 +70,7 @@ namespace usbguard { "apply-policy", Daemon::DevicePolicyMethod::ApplyPolicy } }; - Daemon::DevicePolicyMethod Daemon::devicePolicyMethodFromString(const String& policy_string) + Daemon::DevicePolicyMethod Daemon::devicePolicyMethodFromString(const std::string& policy_string) { for (auto device_policy_method_string : device_policy_method_strings) { if (device_policy_method_string.first == policy_string) { @@ -119,14 +119,14 @@ namespace usbguard _config.close(); } - void Daemon::loadConfiguration(const String& path) + void Daemon::loadConfiguration(const std::string& path) { USBGUARD_LOG(Info) << "Loading configuration from " << path; _config.open(path); /* RuleFile */ if (_config.hasSettingValue("RuleFile")) { - const String& rule_file = _config.getSettingValue("RuleFile"); + const std::string& rule_file = _config.getSettingValue("RuleFile"); try { loadRules(rule_file); } @@ -145,36 +145,36 @@ namespace usbguard /* ImplicitPolicyTarget */ if (_config.hasSettingValue("ImplicitPolicyTarget")) { - const String& target_string = _config.getSettingValue("ImplicitPolicyTarget"); + const std::string& target_string = _config.getSettingValue("ImplicitPolicyTarget"); Rule::Target target = Rule::targetFromString(target_string); setImplicitPolicyTarget(target); } /* PresentDevicePolicy */ if (_config.hasSettingValue("PresentDevicePolicy")) { - const String& policy_string = _config.getSettingValue("PresentDevicePolicy"); + const std::string& policy_string = _config.getSettingValue("PresentDevicePolicy"); DevicePolicyMethod policy = Daemon::devicePolicyMethodFromString(policy_string); setPresentDevicePolicyMethod(policy); } /* PresentControllerPolicy */ if (_config.hasSettingValue("PresentControllerPolicy")) { - const String& policy_string = _config.getSettingValue("PresentControllerPolicy"); + const std::string& policy_string = _config.getSettingValue("PresentControllerPolicy"); DevicePolicyMethod policy = Daemon::devicePolicyMethodFromString(policy_string); setPresentControllerPolicyMethod(policy); } /* InsertedDevicePolicy */ if (_config.hasSettingValue("InsertedDevicePolicy")) { - const String& policy_string = _config.getSettingValue("InsertedDevicePolicy"); + const std::string& policy_string = _config.getSettingValue("InsertedDevicePolicy"); DevicePolicyMethod policy = Daemon::devicePolicyMethodFromString(policy_string); setInsertedDevicePolicyMethod(policy); } /* IPCAllowedUsers */ if (_config.hasSettingValue("IPCAllowedUsers")) { - const String users_value = _config.getSettingValue("IPCAllowedUsers"); - StringVector users; + const std::string users_value = _config.getSettingValue("IPCAllowedUsers"); + std::vector users; tokenizeString(users_value, users, " ", /*trim_empty=*/true); USBGUARD_LOG(Debug) << "Setting IPCAllowedUsers to { " << users_value << " }"; @@ -185,8 +185,8 @@ namespace usbguard /* IPCAllowedGroups */ if (_config.hasSettingValue("IPCAllowedGroups")) { - const String groups_value =_config.getSettingValue("IPCAllowedGroups"); - StringVector groups; + const std::string groups_value =_config.getSettingValue("IPCAllowedGroups"); + std::vector groups; tokenizeString(groups_value, groups, " ", /*trim_empty=*/true); USBGUARD_LOG(Debug) << "Setting IPCAllowedGroups to { " << groups_value << " }"; @@ -197,7 +197,7 @@ namespace usbguard /* DeviceRulesWithPort */ if (_config.hasSettingValue("DeviceRulesWithPort")) { - const String value = _config.getSettingValue("DeviceRulesWithPort"); + const std::string value = _config.getSettingValue("DeviceRulesWithPort"); USBGUARD_LOG(Debug) << "Setting DeviceRulesWithPort to " << value; if (value == "true") { _device_rules_with_port = true; @@ -219,7 +219,7 @@ namespace usbguard /* RestoreControllerDeviceState */ if (_config.hasSettingValue("RestoreControllerDeviceState")) { - const String value = _config.getSettingValue("RestoreControllerDeviceState"); + const std::string value = _config.getSettingValue("RestoreControllerDeviceState"); if (value == "true") { _restore_controller_device_state = true; @@ -236,13 +236,13 @@ namespace usbguard /* IPCAccessControlFiles */ if (_config.hasSettingValue("IPCAccessControlFiles")) { - const String value = _config.getSettingValue("IPCAccessControlFiles"); + const std::string value = _config.getSettingValue("IPCAccessControlFiles"); loadIPCAccessControlFiles(value); } /* AuditFilePath */ if (_config.hasSettingValue("AuditFilePath")) { - const String value = _config.getSettingValue("AuditFilePath"); + const std::string value = _config.getSettingValue("AuditFilePath"); USBGUARD_LOG(Debug) << "Setting AuditFilePath to " << value; USBGUARD_LOGGER.setAuditFile(true, value); } @@ -250,40 +250,40 @@ namespace usbguard USBGUARD_LOG(Info) << "Configuration loaded successfully."; } - void Daemon::loadRules(const String& path) + void Daemon::loadRules(const std::string& path) { USBGUARD_LOG(Info) << "Loading permanent policy file " << path; _ruleset.load(path); } - void Daemon::loadIPCAccessControlFiles(const String& path) + void Daemon::loadIPCAccessControlFiles(const std::string& path) { USBGUARD_LOG(Info) << "Loading IPC access control files at " << path; loadFiles(path, - [](const String& path, const struct dirent * dir_entry) + [](const std::string& path, const struct dirent * dir_entry) { (void)dir_entry; return filenameFromPath(path, /*include_extension=*/true); } , - [this](const String& basename, const String& fullpath) + [this](const std::string& basename, const std::string& fullpath) { return loadIPCAccessControlFile(basename, fullpath); }); } - void Daemon::checkIPCAccessControlName(const String& name) + void Daemon::checkIPCAccessControlName(const std::string& name) { IPCServer::checkAccessControlName(name); } - void Daemon::parseIPCAccessControlFilename(const String& basename, String * const ptr_user, String * const ptr_group) + void Daemon::parseIPCAccessControlFilename(const std::string& basename, std::string * const ptr_user, std::string * const ptr_group) { const auto ug_separator = basename.find_first_of(":"); const bool has_group = ug_separator != std::string::npos; - const String user = basename.substr(0, ug_separator); - const String group = has_group ? basename.substr(ug_separator + 1) : String(); + const std::string user = basename.substr(0, ug_separator); + const std::string group = has_group ? basename.substr(ug_separator + 1) : std::string(); checkIPCAccessControlName(user); checkIPCAccessControlName(group); @@ -292,12 +292,12 @@ namespace usbguard *ptr_group = group; } - bool Daemon::loadIPCAccessControlFile(const String& basename, const String& fullpath) + bool Daemon::loadIPCAccessControlFile(const std::string& basename, const std::string& fullpath) { USBGUARD_LOG(Info) << "Loading IPC access control file " << fullpath; - String user; - String group; + std::string user; + std::string group; IPCServer::AccessControl ac; try { @@ -506,14 +506,14 @@ namespace usbguard << " target=" << Rule::targetToString(target) << " permanent=" << permanent; - Pointer device = _dm->getDevice(id); - Pointer rule; + std::shared_ptr device = _dm->getDevice(id); + std::shared_ptr rule; if (permanent) { rule = upsertDeviceRule(id, target); } else { - rule = makePointer(); + rule = std::make_shared(); rule->setTarget(target); } @@ -524,14 +524,14 @@ namespace usbguard return rule->getRuleID(); } - void Daemon::dmHookDeviceEvent(DeviceManager::EventType event, Pointer device) + void Daemon::dmHookDeviceEvent(DeviceManager::EventType event, std::shared_ptr device) { USBGUARD_LOG(Trace) << "event=" << DeviceManager::eventTypeToString(event) << " device_ptr=" << device.get(); auto audit_event = Audit::deviceEvent(_audit_identity, device, event); - Pointer device_rule = \ + std::shared_ptr device_rule = \ device->getDeviceRule(/*with_port*/true, /*with_parent_hash=*/true); @@ -542,7 +542,7 @@ namespace usbguard audit_event.success(); - Pointer policy_rule = nullptr; + std::shared_ptr policy_rule = nullptr; switch(event) { case DeviceManager::EventType::Present: @@ -562,12 +562,12 @@ namespace usbguard dmApplyDevicePolicy(device, policy_rule); } - void Daemon::dmHookDeviceException(const String& message) + void Daemon::dmHookDeviceException(const std::string& message) { USBGUARD_LOG(Warning) << message; } - void Daemon::dmApplyDevicePolicy(Pointer device, Pointer matched_rule) + void Daemon::dmApplyDevicePolicy(std::shared_ptr device, std::shared_ptr matched_rule) { USBGUARD_LOG(Trace) << "device_ptr=" << device.get() << " matched_rule_ptr=" << matched_rule.get(); @@ -576,7 +576,7 @@ namespace usbguard device, device->getTarget(), matched_rule->getTarget()); const Rule::Target target_old = device->getTarget(); - Pointer device_post = \ + std::shared_ptr device_post = \ _dm->applyDevicePolicy(device->getID(), matched_rule->getTarget()); @@ -592,7 +592,7 @@ namespace usbguard USBGUARD_LOG(Debug) << "Implicit rule matched"; } - Pointer device_rule = \ + std::shared_ptr device_rule = \ device_post->getDeviceRule(/*with_port=*/true, /*with_parent_hash=*/true); @@ -607,17 +607,17 @@ namespace usbguard audit_event.success(); } - Pointer Daemon::getInsertedDevicePolicyRule(Pointer device) + std::shared_ptr Daemon::getInsertedDevicePolicyRule(std::shared_ptr device) { USBGUARD_LOG(Trace) << "device_ptr=" << device.get(); - Pointer device_rule = \ + std::shared_ptr device_rule = \ device->getDeviceRule(/*with_port=*/true, /*with_parent_hash=*/true, /*match_rule=*/true); Rule::Target target = Rule::Target::Invalid; - Pointer policy_rule; + std::shared_ptr policy_rule; const DevicePolicyMethod policy_method = _inserted_device_policy_method; switch (policy_method) { @@ -637,7 +637,7 @@ namespace usbguard } if (policy_rule == nullptr) { - policy_rule = makePointer(); + policy_rule = std::make_shared(); policy_rule->setTarget(target); policy_rule->setRuleID(Rule::RootID); } @@ -645,11 +645,11 @@ namespace usbguard return policy_rule; } - Pointer Daemon::getPresentDevicePolicyRule(Pointer device) + std::shared_ptr Daemon::getPresentDevicePolicyRule(std::shared_ptr device) { USBGUARD_LOG(Trace) << "entry: device_ptr=" << device.get(); - Pointer device_rule = \ + std::shared_ptr device_rule = \ device->getDeviceRule(/*with_port=*/true, /*with_parent_hash=*/true, /*match_rule=*/true); @@ -661,7 +661,7 @@ namespace usbguard device->isController() ? _present_controller_policy_method : _present_device_policy_method; Rule::Target target = Rule::Target::Invalid; - Pointer matched_rule = nullptr; + std::shared_ptr matched_rule = nullptr; switch (policy_method) { case DevicePolicyMethod::Allow: @@ -685,7 +685,7 @@ namespace usbguard } if (matched_rule == nullptr) { - matched_rule = makePointer(); + matched_rule = std::make_shared(); matched_rule->setTarget(target); matched_rule->setRuleID(Rule::ImplicitID); } @@ -719,13 +719,13 @@ namespace usbguard return device_rules; } - Pointer Daemon::upsertDeviceRule(uint32_t id, Rule::Target target) + std::shared_ptr Daemon::upsertDeviceRule(uint32_t id, Rule::Target target) { USBGUARD_LOG(Trace) << "entry:" << "id=" << id << "target=" << Rule::targetToString(target); - Pointer device = _dm->getDevice(id); + std::shared_ptr device = _dm->getDevice(id); bool with_port = true && _device_rules_with_port; bool with_parent_hash = true; @@ -766,15 +766,15 @@ namespace usbguard } /* Generate a match rule for upsert */ - Pointer match_rule = device->getDeviceRule(false, false, /*match_rule=*/true); - const String match_spec = match_rule->toString(); + std::shared_ptr match_rule = device->getDeviceRule(false, false, /*match_rule=*/true); + const std::string match_spec = match_rule->toString(); USBGUARD_LOG(Debug) << "match_spec=" << match_spec; /* Generate new device rule */ - Pointer device_rule = device->getDeviceRule(with_port, with_parent_hash); + std::shared_ptr device_rule = device->getDeviceRule(with_port, with_parent_hash); device_rule->setTarget(target); - const String rule_spec = device_rule->toString(); + const std::string rule_spec = device_rule->toString(); USBGUARD_LOG(Debug) << "rule_spec=" << rule_spec; @@ -794,7 +794,7 @@ namespace usbguard IPCServer::addAllowedUID(uid, ac); } - void Daemon::addIPCAllowedUID(const String& uid_string, const IPCServer::AccessControl& ac) + void Daemon::addIPCAllowedUID(const std::string& uid_string, const IPCServer::AccessControl& ac) { addIPCAllowedUID(stringToNumber(uid_string), ac); } @@ -805,12 +805,12 @@ namespace usbguard IPCServer::addAllowedGID(gid, ac); } - void Daemon::addIPCAllowedGID(const String& gid_string, const IPCServer::AccessControl& ac) + void Daemon::addIPCAllowedGID(const std::string& gid_string, const IPCServer::AccessControl& ac) { addIPCAllowedGID(stringToNumber(gid_string), ac); } - void Daemon::addIPCAllowedUser(const String& user, const IPCServer::AccessControl& ac) + void Daemon::addIPCAllowedUser(const std::string& user, const IPCServer::AccessControl& ac) { USBGUARD_LOG(Trace) << "user=" << user; @@ -822,7 +822,7 @@ namespace usbguard } } - void Daemon::addIPCAllowedGroup(const String& group, const IPCServer::AccessControl& ac) + void Daemon::addIPCAllowedGroup(const std::string& group, const IPCServer::AccessControl& ac) { USBGUARD_LOG(Trace) << "group=" << group; diff --git a/src/Daemon/Daemon.hpp b/src/Daemon/Daemon.hpp index d6081d3..cfd02d9 100644 --- a/src/Daemon/Daemon.hpp +++ b/src/Daemon/Daemon.hpp @@ -17,19 +17,22 @@ // Authors: Daniel Kopecek // #pragma once - -#include "Typedefs.hpp" -#include "ConfigFile.hpp" -#include "IPCServer.hpp" -#include "RuleSet.hpp" -#include "Rule.hpp" -#include "Device.hpp" -#include "DeviceManager.hpp" -#include "DeviceManagerHooks.hpp" -#include "Audit.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif #include "Common/Thread.hpp" +#include "usbguard/Typedefs.hpp" +#include "usbguard/ConfigFile.hpp" +#include "usbguard/IPCServer.hpp" +#include "usbguard/RuleSet.hpp" +#include "usbguard/Rule.hpp" +#include "usbguard/Device.hpp" +#include "usbguard/DeviceManager.hpp" +#include "usbguard/DeviceManagerHooks.hpp" +#include "usbguard/Audit.hpp" + #include #include #include @@ -47,18 +50,18 @@ namespace usbguard ApplyPolicy }; - static DevicePolicyMethod devicePolicyMethodFromString(const String& policy_string); + static DevicePolicyMethod devicePolicyMethodFromString(const std::string& policy_string); static const std::string devicePolicyMethodToString(DevicePolicyMethod policy); Daemon(); ~Daemon(); - void loadConfiguration(const String& path); - void loadRules(const String& path); - void loadIPCAccessControlFiles(const String& path); - bool loadIPCAccessControlFile(const String& basename, const String& fullpath); - void checkIPCAccessControlName(const String& basename); - void parseIPCAccessControlFilename(const String& basename, String * const ptr_user, String * const ptr_group); + void loadConfiguration(const std::string& path); + void loadRules(const std::string& path); + void loadIPCAccessControlFiles(const std::string& path); + bool loadIPCAccessControlFile(const std::string& basename, const std::string& fullpath); + void checkIPCAccessControlName(const std::string& basename); + void parseIPCAccessControlFilename(const std::string& basename, std::string * const ptr_user, std::string * const ptr_group); void setImplicitPolicyTarget(Rule::Target target); void setPresentDevicePolicyMethod(DevicePolicyMethod policy); @@ -85,32 +88,32 @@ namespace usbguard const std::vector listDevices(const std::string& query) override; /* Device manager hooks */ - void dmHookDeviceEvent(DeviceManager::EventType event, Pointer device) override; + void dmHookDeviceEvent(DeviceManager::EventType event, std::shared_ptr device) override; uint32_t dmHookAssignID() override; - void dmHookDeviceException(const String& message) override; + void dmHookDeviceException(const std::string& message) override; #define USBGUARD_IPCSERVER_DEFAULT_AC \ IPCServer::AccessControl(IPCServer::AccessControl::Section::ALL, IPCServer::AccessControl::Privilege::ALL) void addIPCAllowedUID(uid_t uid, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); - void addIPCAllowedUID(const String& uid_string, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); + void addIPCAllowedUID(const std::string& uid_string, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); void addIPCAllowedGID(gid_t gid, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); - void addIPCAllowedGID(const String& gid_string, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); - void addIPCAllowedUser(const String& user, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); - void addIPCAllowedGroup(const String& group, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); + void addIPCAllowedGID(const std::string& gid_string, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); + void addIPCAllowedUser(const std::string& user, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); + void addIPCAllowedGroup(const std::string& group, const IPCServer::AccessControl& ac = USBGUARD_IPCSERVER_DEFAULT_AC); private: - void dmApplyDevicePolicy(Pointer device, Pointer matched_rule); - Pointer getInsertedDevicePolicyRule(Pointer device); - Pointer getPresentDevicePolicyRule(Pointer device); + void dmApplyDevicePolicy(std::shared_ptr device, std::shared_ptr matched_rule); + std::shared_ptr getInsertedDevicePolicyRule(std::shared_ptr device); + std::shared_ptr getPresentDevicePolicyRule(std::shared_ptr device); - Pointer upsertDeviceRule(uint32_t id, Rule::Target target); + std::shared_ptr upsertDeviceRule(uint32_t id, Rule::Target target); ConfigFile _config; RuleSet _ruleset; - String _device_manager_backend; - Pointer _dm; + std::string _device_manager_backend; + std::shared_ptr _dm; std::atomic _implicit_policy_target; std::atomic _present_device_policy_method; diff --git a/src/Daemon/Exceptions.hpp b/src/Daemon/Exceptions.hpp deleted file mode 100644 index 79fa499..0000000 --- a/src/Daemon/Exceptions.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#ifndef USBFW_EXCEPTIONS_HPP -#define USBFW_EXCEPTIONS_HPP -#include - -#include - -namespace usbguard -{ - /** - * Exception class representing an error - * in configuration. FirewallD has several - * sources of configuration data. - * 1) the main configuration file - * 2) the XML definition files for zones, services, icmptypes - */ - class ConfigurationError : public std::runtime_error - { - public: - ConfigurationError(const std::string& source, const std::string& message, size_t line = 0) - : std::runtime_error("Configuration error"), - _source(source), - _message(message), - _line(line) - {} - - const std::string source() const { return _source; } - size_t line() const { return _line; } - const std::string message() const { return _message; } - - private: - const std::string _source; // configuration file specifier - const std::string _message; - size_t _line; // error line or 0 if unknown/unavailable - }; - - /** - * Exception class representin an error - * in the firewall abstraction layer. - */ - class FirewallError : public std::runtime_error - { - public: - FirewallError(const String& name, const String& message = String()) - : std::runtime_error("Firewall error"), - _name(name), - _message(message) - {} - - const String& name() const { return _name; } - const String& message() const { return _message; } - - private: - const String _name; - const String _message; - }; - -} /* namespace usbguard */ - -#endif /* USBFW_EXCEPTIONS_HPP */ diff --git a/src/Daemon/Seccomp.c b/src/Daemon/Seccomp.c index 29eab3a..9d727a8 100644 --- a/src/Daemon/Seccomp.c +++ b/src/Daemon/Seccomp.c @@ -16,7 +16,9 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include +#endif #include "Seccomp.h" @@ -169,3 +171,5 @@ bool setupSeccompWhitelist(void) return false; } #endif + +/* vim: set ts=2 sw=2 et */ diff --git a/src/Daemon/Seccomp.h b/src/Daemon/Seccomp.h index 09b9f35..2e9389f 100644 --- a/src/Daemon/Seccomp.h +++ b/src/Daemon/Seccomp.h @@ -16,6 +16,11 @@ // // Authors: Daniel Kopecek // +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include #ifdef __cplusplus @@ -27,3 +32,5 @@ bool setupSeccompWhitelist(void); #ifdef __cplusplus } #endif + +/* vim: set ts=2 sw=2 et */ diff --git a/src/Daemon/main.cpp b/src/Daemon/main.cpp index 73c49b3..869c2e2 100644 --- a/src/Daemon/main.cpp +++ b/src/Daemon/main.cpp @@ -16,17 +16,20 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include +#endif -#include - -#include "Logger.hpp" #include "Daemon.hpp" -#include "Exception.hpp" #include "Common/Utility.hpp" #include "Seccomp.h" +#include "usbguard/Typedefs.hpp" +#include "usbguard/Logger.hpp" +#include "usbguard/Exception.hpp" + #include + #include #if defined(HAVE_LIBCAPNG) @@ -41,7 +44,7 @@ const char * const G_optstring = "dskl:p:c:hWC"; static void printUsage(std::ostream& stream, const char *arg0) { stream << std::endl; - stream << "Usage: " << filenameFromPath(String(arg0), true) << " [OPTIONS]" << std::endl; + stream << "Usage: " << filenameFromPath(std::string(arg0), true) << " [OPTIONS]" << std::endl; stream << std::endl; stream << " -d Enable debugging messages in the log." << std::endl; stream << " -s Log to syslog." << std::endl; @@ -65,9 +68,9 @@ int main(int argc, char *argv[]) bool log_file = false; bool use_seccomp_whitelist = false; bool drop_capabilities = false; - String log_file_path; - String pid_file; - String conf_file = "/etc/usbguard/usbguard-daemon.conf"; + std::string log_file_path; + std::string pid_file; + std::string conf_file = "/etc/usbguard/usbguard-daemon.conf"; int opt; while ((opt = getopt(argc, argv, G_optstring)) != -1) { @@ -84,13 +87,13 @@ int main(int argc, char *argv[]) break; case 'l': log_file = true; - log_file_path = String(optarg); + log_file_path = std::string(optarg); break; case 'p': - pid_file = String(optarg); + pid_file = std::string(optarg); break; case 'c': - conf_file = String(optarg); + conf_file = std::string(optarg); break; case 'W': use_seccomp_whitelist = true; diff --git a/src/GUI.Qt/DeviceDialog.cpp b/src/GUI.Qt/DeviceDialog.cpp index c9fb172..28407b1 100644 --- a/src/GUI.Qt/DeviceDialog.cpp +++ b/src/GUI.Qt/DeviceDialog.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "DeviceDialog.h" #include "DeviceDialog.ui.h" -#include +#include "usbguard/Logger.hpp" + #include #include diff --git a/src/GUI.Qt/DeviceDialog.h b/src/GUI.Qt/DeviceDialog.h index 23f7a74..3461179 100644 --- a/src/GUI.Qt/DeviceDialog.h +++ b/src/GUI.Qt/DeviceDialog.h @@ -17,11 +17,15 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/USB.hpp" +#include "usbguard/Rule.hpp" #include #include -#include -#include namespace Ui { class DeviceDialog; @@ -92,3 +96,5 @@ private: QString _device_id; QStringList _interface_types; }; + +/* vim: set ts=2 sw=2 et */ diff --git a/src/GUI.Qt/DeviceModel.cpp b/src/GUI.Qt/DeviceModel.cpp index 265eba0..51b203b 100644 --- a/src/GUI.Qt/DeviceModel.cpp +++ b/src/GUI.Qt/DeviceModel.cpp @@ -16,9 +16,14 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include +#endif + #include "DeviceModel.h" -#include + +#include "usbguard/Logger.hpp" + #include #include #include diff --git a/src/GUI.Qt/DeviceModel.h b/src/GUI.Qt/DeviceModel.h index 51238e3..c64d5e0 100644 --- a/src/GUI.Qt/DeviceModel.h +++ b/src/GUI.Qt/DeviceModel.h @@ -16,14 +16,17 @@ // // Authors: Daniel Kopecek // -#ifndef DEVICEMODEL_H -#define DEVICEMODEL_H +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Rule.hpp" #include #include #include #include -#include class DeviceModelItem { @@ -98,4 +101,4 @@ private: DeviceModelItem *_root_item; }; -#endif // DEVICEMODEL_H +/* vim: set ts=2 sw=2 et */ diff --git a/src/GUI.Qt/MainWindow.cpp b/src/GUI.Qt/MainWindow.cpp index 12751e6..31d4ad7 100644 --- a/src/GUI.Qt/MainWindow.cpp +++ b/src/GUI.Qt/MainWindow.cpp @@ -15,13 +15,18 @@ // along with this program. If not, see . // // Authors: Daniel Kopecek +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif #include "MainWindow.h" #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wswitch-default" #include "MainWindow.ui.h" #include "DeviceDialog.h" -#include + +#include "usbguard/Logger.hpp" + #include #include #include diff --git a/src/GUI.Qt/MainWindow.h b/src/GUI.Qt/MainWindow.h index 4b9f5a0..efb6a3e 100644 --- a/src/GUI.Qt/MainWindow.h +++ b/src/GUI.Qt/MainWindow.h @@ -17,15 +17,19 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif #include "DeviceModel.h" #include "TargetDelegate.h" +#include "usbguard/IPCClient.hpp" + #include #include #include #include -#include namespace Ui { class MainWindow; @@ -132,3 +136,4 @@ private: TargetDelegate _target_delegate; }; +/* vim: set ts=2 sw=2 et */ diff --git a/src/GUI.Qt/TargetDelegate.cpp b/src/GUI.Qt/TargetDelegate.cpp index 18a3db2..415e1b3 100644 --- a/src/GUI.Qt/TargetDelegate.cpp +++ b/src/GUI.Qt/TargetDelegate.cpp @@ -16,10 +16,16 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "TargetDelegate.h" #include "DeviceModel.h" + +#include "usbguard/Rule.hpp" + #include -#include TargetDelegate::TargetDelegate(QObject *parent) : QStyledItemDelegate(parent) diff --git a/src/GUI.Qt/TargetDelegate.h b/src/GUI.Qt/TargetDelegate.h index c4b3218..2661b39 100644 --- a/src/GUI.Qt/TargetDelegate.h +++ b/src/GUI.Qt/TargetDelegate.h @@ -16,8 +16,10 @@ // // Authors: Daniel Kopecek // -#ifndef TARGETDELEGATE_H -#define TARGETDELEGATE_H +#pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif #include @@ -34,4 +36,4 @@ public: void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; }; -#endif // TARGETDELEGATE_H +/* vim: set ts=2 sw=2 et */ diff --git a/src/GUI.Qt/main.cpp b/src/GUI.Qt/main.cpp index 458217f..c9e86e2 100644 --- a/src/GUI.Qt/main.cpp +++ b/src/GUI.Qt/main.cpp @@ -16,6 +16,10 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "MainWindow.h" #include #include diff --git a/src/Library/AllowedMatchesCondition.cpp b/src/Library/AllowedMatchesCondition.cpp index f871a9c..b60c63c 100644 --- a/src/Library/AllowedMatchesCondition.cpp +++ b/src/Library/AllowedMatchesCondition.cpp @@ -16,14 +16,19 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "AllowedMatchesCondition.hpp" -#include "RuleParser.hpp" -#include "Logger.hpp" -#include + +#include "usbguard/Interface.hpp" +#include "usbguard/Logger.hpp" +#include "usbguard/RuleParser.hpp" namespace usbguard { - AllowedMatchesCondition::AllowedMatchesCondition(const String& device_spec, bool negated) + AllowedMatchesCondition::AllowedMatchesCondition(const std::string& device_spec, bool negated) : RuleConditionBase("allowed-matches", device_spec, negated) { _device_match_rule = parseRuleFromString(std::string("allow ") + device_spec); diff --git a/src/Library/AllowedMatchesCondition.hpp b/src/Library/AllowedMatchesCondition.hpp index f0c8451..3fb4788 100644 --- a/src/Library/AllowedMatchesCondition.hpp +++ b/src/Library/AllowedMatchesCondition.hpp @@ -17,16 +17,23 @@ // Authors: Daniel Kopecek // #pragma once -#include "Typedefs.hpp" -#include "RuleCondition.hpp" -#include "Rule.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/RuleCondition.hpp" + +#include "usbguard/Rule.hpp" +#include "usbguard/Typedefs.hpp" + +#include namespace usbguard { class AllowedMatchesCondition : public RuleConditionBase { public: - AllowedMatchesCondition(const String& device_spec, bool negated = false); + AllowedMatchesCondition(const std::string& device_spec, bool negated = false); AllowedMatchesCondition(const AllowedMatchesCondition& rhs); void init(Interface * const interface_ptr); bool update(const Rule& rule); diff --git a/src/Library/Audit.cpp b/src/Library/Audit.cpp deleted file mode 100644 index ad7a744..0000000 --- a/src/Library/Audit.cpp +++ /dev/null @@ -1,252 +0,0 @@ -// -// Copyright (C) 2017 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// - -#include "Audit.hpp" - -#include -#include -#include - -namespace usbguard -{ - - AuditIdentity::AuditIdentity() - { - _uid = getuid(); - _pid = getpid(); - } - - AuditIdentity::AuditIdentity(uid_t uid, pid_t pid) - { - _uid = uid; - _pid = pid; - } - - std::string AuditIdentity::toString() const - { - std::string identity_string; - - identity_string.append("{ uid="); - identity_string.append(numberToString(_uid)); - identity_string.append(" pid="); - identity_string.append(numberToString(_pid)); - identity_string.append(" }"); - - return identity_string; - } - - AuditEvent::AuditEvent(const AuditIdentity& identity) - : _confirmed(false), - _identity(identity) - { - - } - - AuditEvent::AuditEvent(AuditEvent&& event) - : _confirmed(event._confirmed), - _identity(std::move(event._identity)), - _message(std::move(event._message)) - { - event.setConfirmed(true); - } - - AuditEvent::~AuditEvent() - { - if (!_confirmed) { - failure(); - } - } - - void AuditEvent::confirm(const std::string& result) - { - USBGUARD_LOG(Audit) << "result=" << result \ - << " identity=" << _identity.toString() \ - << " " << _message; - setConfirmed(true); - } - - void AuditEvent::success() - { - confirm("SUCCESS"); - } - - void AuditEvent::failure() - { - confirm("FAILURE"); - } - - void AuditEvent::setConfirmed(bool state) - { - _confirmed = state; - } - - std::string& AuditEvent::refMessage() - { - return _message; - } - - Audit::Audit(const AuditIdentity& identity) - : _identity(identity) - { - - } - - AuditEvent Audit::policyEvent(Pointer rule, Policy::EventType event) - { - return policyEvent(_identity, rule, event); - } - - AuditEvent Audit::policyEvent(Pointer new_rule, Pointer old_rule) - { - return policyEvent(_identity, new_rule, old_rule); - } - - AuditEvent Audit::policyEvent(Pointer device, Policy::EventType event) - { - return policyEvent(_identity, device, event); - } - - AuditEvent Audit::policyEvent(Pointer device, Rule::Target old_target, Rule::Target new_target) - { - return policyEvent(_identity, device, old_target, new_target); - } - - AuditEvent Audit::deviceEvent(Pointer device, DeviceManager::EventType event) - { - return deviceEvent(_identity, device, event); - } - - AuditEvent Audit::deviceEvent(Pointer new_device, Pointer old_device) - { - return deviceEvent(_identity, new_device, old_device); - } - - AuditEvent Audit::policyEvent(const AuditIdentity& identity, Pointer rule, Policy::EventType event) - { - AuditEvent audit_event(identity); - auto& message = audit_event.refMessage(); - - message += "type=Policy."; - message += Policy::eventTypeToString(event); - - message += " rule.id="; - message += numberToString(rule->getRuleID()); - - message += " rule='"; - message += rule->toString(); - message += "'"; - - return audit_event; - } - - AuditEvent Audit::policyEvent(const AuditIdentity& identity, Pointer new_rule, Pointer old_rule) - { - AuditEvent audit_event(identity); - auto& message = audit_event.refMessage(); - - message += "type=Policy."; - message += Policy::eventTypeToString(Policy::EventType::Update); - - message += " rule.id="; - message += numberToString(old_rule->getRuleID()); - - message += " rule.old='"; - message += old_rule->toString(); - message += "'"; - - message += " rule.new='"; - message += new_rule->toString(); - message += "'"; - - return audit_event; - } - - AuditEvent Audit::policyEvent(const AuditIdentity& identity, Pointer device, Policy::EventType event) - { - AuditEvent audit_event(identity); - auto& message = audit_event.refMessage(); - - message += "type=Policy.Device."; - message += Policy::eventTypeToString(event); - - message += " target="; - message += Rule::targetToString(device->getTarget()); - - message += " device='"; - message += device->getDeviceRule()->toString(); - message += "'"; - - return audit_event; - } - - AuditEvent Audit::policyEvent(const AuditIdentity& identity, Pointer device, Rule::Target old_target, Rule::Target new_target) - { - AuditEvent audit_event(identity); - auto& message = audit_event.refMessage(); - - message += "type=Policy.Device."; - message += Policy::eventTypeToString(Policy::EventType::Update); - - message += " target.old="; - message += Rule::targetToString(old_target); - - message += " target.new="; - message += Rule::targetToString(new_target); - - message += " device='"; - message += device->getDeviceRule()->toString(); - message += "'"; - - return audit_event; - } - - AuditEvent Audit::deviceEvent(const AuditIdentity& identity, Pointer device, DeviceManager::EventType event) - { - AuditEvent audit_event(identity); - auto& message = audit_event.refMessage(); - - message += "type=Device."; - message += DeviceManager::eventTypeToString(event); - - message += " device='"; - message += device->getDeviceRule()->toString(); - message += "'"; - - return audit_event; - } - - AuditEvent Audit::deviceEvent(const AuditIdentity& identity, Pointer new_device, Pointer old_device) - { - AuditEvent audit_event(identity); - auto& message = audit_event.refMessage(); - - message += "type=Device."; - message += DeviceManager::eventTypeToString(DeviceManager::EventType::Update); - - message += " device.old='"; - message += old_device->getDeviceRule()->toString(); - message += "'"; - - message += " device.new='"; - message += new_device->getDeviceRule()->toString(); - message += "'"; - - return audit_event; - } -} /* namespace usbguard */ diff --git a/src/Library/Audit.hpp b/src/Library/Audit.hpp deleted file mode 100644 index 8ef5020..0000000 --- a/src/Library/Audit.hpp +++ /dev/null @@ -1,120 +0,0 @@ -// -// Copyright (C) 2017 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -namespace usbguard -{ - class DLL_PUBLIC AuditIdentity - { - public: - AuditIdentity(); - AuditIdentity(uid_t uid, pid_t pid); - - std::string toString() const; - private: - uid_t _uid; - pid_t _pid; - }; - - class DLL_PUBLIC AuditEvent - { - AuditEvent(const AuditIdentity& identity); - public: - AuditEvent(AuditEvent&& event); - AuditEvent(const AuditEvent& event) = delete; - ~AuditEvent(); - - void success(); - void failure(); - - private: - void confirm(const std::string& result); - void setConfirmed(bool state); - std::string& refMessage(); - - bool _confirmed; - AuditIdentity _identity; - std::string _message; - - friend class Audit; - }; - - class DLL_PUBLIC Audit - { - public: - Audit(const AuditIdentity& identity); - - AuditEvent policyEvent(Pointer rule, Policy::EventType event); - AuditEvent policyEvent(Pointer new_rule, Pointer old_rule); - AuditEvent policyEvent(Pointer device, Policy::EventType event); - AuditEvent policyEvent(Pointer device, Rule::Target old_target, Rule::Target new_target); - - AuditEvent deviceEvent(Pointer device, DeviceManager::EventType event); - AuditEvent deviceEvent(Pointer new_device, Pointer old_device); - - /* - * 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 - */ - static AuditEvent policyEvent(const AuditIdentity& identity, Pointer rule, Policy::EventType event); - static AuditEvent policyEvent(const AuditIdentity& identity, Pointer new_rule, Pointer old_rule); - static AuditEvent policyEvent(const AuditIdentity& identity, Pointer device, Policy::EventType event); - static AuditEvent policyEvent(const AuditIdentity& identity, Pointer device, Rule::Target old_target, Rule::Target new_target); - - /* - * Audit device changes: - * - device insertion - * - device removal - * - device authorization target change - * - * Audit data: - * - who: uid + pid - * - when: time - * - what: insert, remove, authorization target - * - change: old, new - */ - static AuditEvent deviceEvent(const AuditIdentity& identity, Pointer device, DeviceManager::EventType event); - static AuditEvent deviceEvent(const AuditIdentity& identity, Pointer new_device, Pointer old_device); - - private: - AuditIdentity _identity; - }; -} /* namespace usbguard */ diff --git a/src/Library/Base64.cpp b/src/Library/Base64.cpp index 6471c31..6f8cc4d 100644 --- a/src/Library/Base64.cpp +++ b/src/Library/Base64.cpp @@ -16,7 +16,12 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "Base64.hpp" +#include #include namespace usbguard @@ -180,7 +185,7 @@ namespace usbguard } #undef B - String base64Encode (const uint8_t * const data, const size_t size) { + std::string base64Encode (const uint8_t * const data, const size_t size) { if (size == 0 || data == nullptr) { throw std::runtime_error("base64encode: invalid input"); } @@ -189,7 +194,7 @@ namespace usbguard const uint8_t remainder = size % 3; const size_t enc3_count = (size - remainder) / 3; - String result(encoded_size, 0); + std::string result(encoded_size, 0); char * const buffer = &result[0]; size_t i = 0; @@ -213,7 +218,7 @@ namespace usbguard return result; } - String base64Decode(const char * const data, const size_t size) { + std::string base64Decode(const char * const data, const size_t size) { if (size == 0 || (size % 4) != 0) { throw std::runtime_error("base64Decode: invalid input"); } @@ -231,7 +236,7 @@ namespace usbguard --dec4_count; } - String result(decoded_size, 0); + std::string result(decoded_size, 0); uint8_t * const buffer = reinterpret_cast(&result[0]); size_t i = 0; @@ -268,12 +273,12 @@ namespace usbguard return (encoded_size / 4 * 3) + (encoded_size % 4); } - String base64Encode(const String& value) + std::string base64Encode(const std::string& value) { return base64Encode(reinterpret_cast(value.c_str()), value.size()); } - String base64Decode(const String& value) + std::string base64Decode(const std::string& value) { return base64Decode(value.c_str(), value.size()); } diff --git a/src/Library/Base64.hpp b/src/Library/Base64.hpp index d297735..d8d733b 100644 --- a/src/Library/Base64.hpp +++ b/src/Library/Base64.hpp @@ -16,7 +16,11 @@ // // Authors: Daniel Kopecek // -#include "Typedefs.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include #include namespace usbguard @@ -24,11 +28,11 @@ namespace usbguard size_t base64EncodedSize(size_t decoded_size); size_t base64DecodedSize(size_t encoded_size); - String base64Encode(const String& value); - String base64Encode(const uint8_t *buffer, size_t buflen); + std::string base64Encode(const std::string& value); + std::string base64Encode(const uint8_t *buffer, size_t buflen); - String base64Decode(const String& value); - size_t base64Decode(const String& value, void *buffer, size_t buflen); - String base64Decode(const char * const data, const size_t size); + std::string base64Decode(const std::string& value); + size_t base64Decode(const std::string& value, void *buffer, size_t buflen); + std::string base64Decode(const char * const data, const size_t size); } /* namespace usbguard */ diff --git a/src/Library/ConfigFile.cpp b/src/Library/ConfigFile.cpp deleted file mode 100644 index b55faaa..0000000 --- a/src/Library/ConfigFile.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include "ConfigFilePrivate.hpp" - -namespace usbguard -{ - ConfigFile::ConfigFile(const StringVector& known_names) - { - d_pointer = new ConfigFilePrivate(*this, known_names); - } - - ConfigFile::~ConfigFile() - { - delete d_pointer; - } - - void ConfigFile::open(const String& path) - { - d_pointer->open(path); - } - - void ConfigFile::write() - { - d_pointer->write(); - } - - void ConfigFile::close() - { - d_pointer->close(); - } - - const String& ConfigFile::getSettingValue(const String& name) const - { - return d_pointer->getSettingValue(name); - } - - void ConfigFile::setSettingValue(const String& name, String& value) - { - d_pointer->setSettingValue(name, value); - } - - bool ConfigFile::hasSettingValue(const String& name) const - { - return d_pointer->hasSettingValue(name); - } -} /* namespace usbguard */ diff --git a/src/Library/ConfigFile.hpp b/src/Library/ConfigFile.hpp deleted file mode 100644 index f987640..0000000 --- a/src/Library/ConfigFile.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once -#include - -namespace usbguard { - class ConfigFilePrivate; - class DLL_PUBLIC ConfigFile - { - public: - ConfigFile(const StringVector& known_names = StringVector()); - ~ConfigFile(); - - void open(const String& path); - void write(); - void close(); - - void setSettingValue(const String& name, String& value); - bool hasSettingValue(const String& name) const; - const String& getSettingValue(const String& name) const; - - private: - ConfigFilePrivate* d_pointer; - }; -} /* namespace usbguard */ diff --git a/src/Library/ConfigFilePrivate.cpp b/src/Library/ConfigFilePrivate.cpp index eb15ca4..63a455a 100644 --- a/src/Library/ConfigFilePrivate.cpp +++ b/src/Library/ConfigFilePrivate.cpp @@ -16,15 +16,24 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif #include "ConfigFilePrivate.hpp" #include "Common/Utility.hpp" -#include "Logger.hpp" + +#include "usbguard/Logger.hpp" + #include +#include +#include + +#include namespace usbguard { - ConfigFilePrivate::ConfigFilePrivate(ConfigFile& p_instance, const StringVector& known_names) + ConfigFilePrivate::ConfigFilePrivate(ConfigFile& p_instance, const std::vector& known_names) : _p_instance(p_instance), _known_names(known_names) { @@ -40,7 +49,7 @@ namespace usbguard } } - void ConfigFilePrivate::open(const String& path) + void ConfigFilePrivate::open(const std::string& path) { _stream.open(path, std::ios::in|std::ios::out); if (!_stream.is_open()) { @@ -81,27 +90,27 @@ namespace usbguard _stream.close(); } - const String& ConfigFilePrivate::getSettingValue(const String& name) const + const std::string& ConfigFilePrivate::getSettingValue(const std::string& name) const { const NVPair& setting = _settings.at(name); return setting.value; } - void ConfigFilePrivate::setSettingValue(const String& name, String& value) + void ConfigFilePrivate::setSettingValue(const std::string& name, std::string& value) { NVPair& setting = _settings.at(name); setting.value = value; _dirty = true; } - bool ConfigFilePrivate::hasSettingValue(const String& name) const + bool ConfigFilePrivate::hasSettingValue(const std::string& name) const { return (_settings.count(name) != 0); } void ConfigFilePrivate::parse() { - String config_line; + std::string config_line; size_t config_line_number = 0; while(std::getline(_stream, config_line)) { @@ -109,12 +118,12 @@ namespace usbguard _lines.push_back(config_line); const size_t nv_separator = config_line.find_first_of("="); - if (nv_separator == String::npos) { + if (nv_separator == std::string::npos) { continue; } - String name = trim(config_line.substr(0, nv_separator)); - String value = config_line.substr(nv_separator + 1); + std::string name = trim(config_line.substr(0, nv_separator)); + std::string value = config_line.substr(nv_separator + 1); if (name[0] == '#') { continue; @@ -132,7 +141,7 @@ namespace usbguard } } - bool ConfigFilePrivate::checkNVPair(const String& name, const String& value) const + bool ConfigFilePrivate::checkNVPair(const std::string& name, const std::string& value) const { (void)value; /* TODO */ diff --git a/src/Library/ConfigFilePrivate.hpp b/src/Library/ConfigFilePrivate.hpp index 39788a7..3d57a11 100644 --- a/src/Library/ConfigFilePrivate.hpp +++ b/src/Library/ConfigFilePrivate.hpp @@ -17,43 +17,50 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H #include -#include "ConfigFile.hpp" +#endif + +#include "usbguard/ConfigFile.hpp" + #include +#include +#include +#include namespace usbguard { class ConfigFilePrivate { public: - ConfigFilePrivate(ConfigFile& p_instance, const StringVector& known_names); + ConfigFilePrivate(ConfigFile& p_instance, const std::vector& known_names); ~ConfigFilePrivate(); - void open(const String& path); + void open(const std::string& path); void write(); void close(); - void setSettingValue(const String& name, String& value); - bool hasSettingValue(const String& name) const; - const String& getSettingValue(const String& name) const; + void setSettingValue(const std::string& name, std::string& value); + bool hasSettingValue(const std::string& name) const; + const std::string& getSettingValue(const std::string& name) const; protected: void parse(); - bool checkNVPair(const String& name, const String& value) const; + bool checkNVPair(const std::string& name, const std::string& value) const; private: struct NVPair { - String name; - String value; + std::string name; + std::string value; size_t line_number; }; ConfigFile& _p_instance; - String _path; + std::string _path; std::fstream _stream; - StringVector _lines; - StringKeyMap _settings; + std::vector _lines; + std::map _settings; bool _dirty; - StringVector _known_names; + std::vector _known_names; }; } diff --git a/src/Library/Device.cpp b/src/Library/Device.cpp deleted file mode 100644 index 636349e..0000000 --- a/src/Library/Device.cpp +++ /dev/null @@ -1,196 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include -#include "DevicePrivate.hpp" - -namespace usbguard { - Device::Device(DeviceManager& manager) - { - d_pointer = new DevicePrivate(*this, manager); - } - - Device::~Device() - { - delete d_pointer; - d_pointer = nullptr; - } - - Device::Device(const Device& rhs) - { - d_pointer = new DevicePrivate(*this, *rhs.d_pointer); - } - - const Device& Device::operator=(const Device &rhs) - { - DevicePrivate* n_pointer = new DevicePrivate(*this, *rhs.d_pointer); - delete d_pointer; - d_pointer = n_pointer; - return *this; - } - - DeviceManager& Device::manager() const - { - return d_pointer->manager(); - } - - std::mutex& Device::refDeviceMutex() - { - return d_pointer->refDeviceMutex(); - } - - Pointer Device::getDeviceRule(const bool with_port, const bool with_parent_hash, const bool match_rule) - { - return d_pointer->getDeviceRule(with_port, with_parent_hash, match_rule); - } - - String Device::hashString(const String& value) const - { - return d_pointer->hashString(value); - } - - void Device::initializeHash() - { - d_pointer->initializeHash(); - } - - void Device::updateHash(const void * const ptr, const size_t size) - { - d_pointer->updateHash(ptr, size); - } - - void Device::updateHash(std::istream& descriptor_stream, const size_t expected_size) - { - d_pointer->updateHash(descriptor_stream, expected_size); - } - - String Device::finalizeHash() - { - return d_pointer->finalizeHash(); - } - - const String& Device::getHash() const - { - return d_pointer->getHash(); - } - - void Device::setParentHash(const String& hash) - { - d_pointer->setParentHash(hash); - } - - void Device::setID(uint32_t id) - { - d_pointer->setID(id); - } - - uint32_t Device::getID() const - { - return d_pointer->getID(); - } - - void Device::setParentID(uint32_t id) - { - d_pointer->setParentID(id); - } - - uint32_t Device::getParentID() const - { - return d_pointer->getParentID(); - } - - void Device::setTarget(Rule::Target target) - { - d_pointer->setTarget(target); - } - - Rule::Target Device::getTarget() const - { - return d_pointer->getTarget(); - } - - void Device::setName(const String& name) - { - d_pointer->setName(name); - } - - const String& Device::getName() const - { - return d_pointer->getName(); - } - - void Device::setDeviceID(const USBDeviceID& device_id) - { - d_pointer->setDeviceID(device_id); - } - - const USBDeviceID& Device::getDeviceID() const - { - return d_pointer->getDeviceID(); - } - - void Device::setPort(const String& port) - { - d_pointer->setPort(port); - } - - const String& Device::getPort() const - { - return d_pointer->getPort(); - } - - void Device::setSerial(const String& serial_number) - { - d_pointer->setSerial(serial_number); - } - - const String& Device::getSerial() const - { - return d_pointer->getSerial(); - } - - std::vector& Device::refMutableInterfaceTypes() - { - return d_pointer->refMutableInterfaceTypes(); - } - - const std::vector& Device::getInterfaceTypes() const - { - return d_pointer->getInterfaceTypes(); - } - - void Device::loadDeviceDescriptor(USBDescriptorParser* parser, const USBDescriptor* const descriptor) - { - d_pointer->loadDeviceDescriptor(parser, descriptor); - } - - void Device::loadConfigurationDescriptor(USBDescriptorParser* parser, const USBDescriptor* const descriptor) - { - d_pointer->loadConfigurationDescriptor(parser, descriptor); - } - - void Device::loadInterfaceDescriptor(USBDescriptorParser* parser, const USBDescriptor* const descriptor) - { - d_pointer->loadInterfaceDescriptor(parser, descriptor); - } - - void Device::loadEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* const descriptor) - { - d_pointer->loadEndpointDescriptor(parser, descriptor); - } -} /* namespace usbguard */ diff --git a/src/Library/Device.hpp b/src/Library/Device.hpp deleted file mode 100644 index e90580e..0000000 --- a/src/Library/Device.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include -#include -#include -#include - -namespace usbguard { - class DeviceManager; - class DevicePrivate; - class DLL_PUBLIC Device - { - public: - Device(DeviceManager& manager); - ~Device(); - Device(const Device& rhs); - const Device& operator=(const Device& rhs); - - DeviceManager& manager() const; - - std::mutex& refDeviceMutex(); - Pointer getDeviceRule(bool with_port = true, bool with_parent_hash = true, bool match_rule = false); - String hashString(const String& value) const; - void initializeHash(); - void updateHash(const void * ptr, size_t size); - void updateHash(std::istream& descriptor_stream, size_t expected_size); - String finalizeHash(); - const String& getHash() const; - - void setParentHash(const String& hash); - - void setID(uint32_t id); - uint32_t getID() const; - - void setParentID(uint32_t id); - uint32_t getParentID() const; - - void setTarget(Rule::Target target); - Rule::Target getTarget() const; - - void setName(const String& name); - const String& getName() const; - - void setDeviceID(const USBDeviceID& device_id); - const USBDeviceID& getDeviceID() const; - - void setPort(const String& port); - const String& getPort() const; - - void setSerial(const String& serial_number); - const String& getSerial() const; - - std::vector& refMutableInterfaceTypes(); - const std::vector& getInterfaceTypes() const; - - virtual bool isController() const = 0; - - void loadDeviceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); - void loadConfigurationDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); - void loadInterfaceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); - void loadEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); - - private: - DevicePrivate *d_pointer; - }; -} /* namespace usbguard */ diff --git a/src/Library/DeviceManager.cpp b/src/Library/DeviceManager.cpp deleted file mode 100644 index 8a2bbdd..0000000 --- a/src/Library/DeviceManager.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include -#include -#include -#include -#include "DeviceManagerPrivate.hpp" - -namespace usbguard { - uint32_t DeviceManager::eventTypeToInteger(DeviceManager::EventType event) - { - return static_cast(event); - } - - DeviceManager::EventType DeviceManager::eventTypeFromInteger(uint32_t event_integer) - { - switch(event_integer) { - case static_cast(EventType::Insert): - case static_cast(EventType::Update): - case static_cast(EventType::Remove): - break; - default: - throw std::runtime_error("Invalid event type integer value"); - } - return static_cast(event_integer); - } - - std::string DeviceManager::eventTypeToString(DeviceManager::EventType event) - { - switch(event) { - case DeviceManager::EventType::Present: - return "Present"; - case DeviceManager::EventType::Insert: - return "Insert"; - case DeviceManager::EventType::Remove: - return "Remove"; - case DeviceManager::EventType::Update: - return "Update"; - default: - throw USBGUARD_BUG("unknown event type"); - } - } - - DeviceManager::DeviceManager(DeviceManagerHooks& hooks) - { - d_pointer = new DeviceManagerPrivate(*this, hooks); - } - - DeviceManager::DeviceManager(const DeviceManager& rhs) - { - d_pointer = new DeviceManagerPrivate(*this, *rhs.d_pointer); - } - - const DeviceManager& DeviceManager::operator=(const DeviceManager& rhs) - { - DeviceManagerPrivate* n_pointer = new DeviceManagerPrivate(*this, *rhs.d_pointer); - delete d_pointer; - d_pointer = n_pointer; - return *this; - } - - DeviceManager::~DeviceManager() - { - delete d_pointer; - d_pointer = nullptr; - } - - void DeviceManager::setRestoreControllerDeviceState(bool enabled) - { - d_pointer->setRestoreControllerDeviceState(enabled); - } - - bool DeviceManager::getRestoreControllerDeviceState() const - { - return d_pointer->getRestoreControllerDeviceState(); - } - - void DeviceManager::insertDevice(Pointer device) - { - d_pointer->insertDevice(device); - } - - Pointer DeviceManager::removeDevice(uint32_t id) - { - return d_pointer->removeDevice(id); - } - - PointerVector DeviceManager::getDeviceList() - { - return d_pointer->getDeviceList(); - } - - PointerVector DeviceManager::getDeviceList(const Rule& query) - { - PointerVector matching_devices; - - for (auto const& device : getDeviceList()) { - if (query.appliesTo(device->getDeviceRule())) { - switch(query.getTarget()) { - case Rule::Target::Allow: - case Rule::Target::Block: - if (device->getTarget() == query.getTarget()) { - matching_devices.push_back(device); - } - break; - case Rule::Target::Device: - case Rule::Target::Match: - matching_devices.push_back(device); - break; - case Rule::Target::Reject: - case Rule::Target::Unknown: - case Rule::Target::Invalid: - default: - throw std::runtime_error("Invalid device query target"); - } - } - } - - return matching_devices; - } - - Pointer DeviceManager::getDevice(uint32_t id) - { - return d_pointer->getDevice(id); - } - - void DeviceManager::DeviceEvent(DeviceManager::EventType event, Pointer device) - { - d_pointer->DeviceEvent(event, device); - } - - void DeviceManager::DeviceException(const String& message) - { - d_pointer->DeviceException(message); - } -} /* namespace usbguard */ - -#if defined(HAVE_UEVENT) -# include "UEventDeviceManager.hpp" -#endif - -usbguard::Pointer usbguard::DeviceManager::create(DeviceManagerHooks& hooks, const String& backend) -{ -#if defined(HAVE_UEVENT) - if (backend == "udev") { - USBGUARD_LOG(Warning) << "udev backend is OBSOLETE. Falling back to new default: uevent"; - } - if (backend == "uevent" || /* transition udev => uevent */backend == "udev") { - return usbguard::makePointer(hooks); - } - if (backend == "dummy") { - const char * const device_root_cstr = getenv("USBGUARD_DUMMY_DEVICE_ROOT"); - if (device_root_cstr == nullptr) { - throw Exception("DeviceManager", "dummy", "USBGUARD_DUMMY_DEVICE_ROOT environment variable not defined"); - } - const String device_root(device_root_cstr); - return usbguard::makePointer(hooks, device_root, /*dummy_mode=*/true); - } -#endif - throw Exception("DeviceManager", "backend", "requested backend is not available"); -} diff --git a/src/Library/DeviceManager.hpp b/src/Library/DeviceManager.hpp deleted file mode 100644 index 4edeb13..0000000 --- a/src/Library/DeviceManager.hpp +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once -#include -#include -#include -#include - -namespace usbguard { - class DeviceManagerHooks; - class DeviceManagerPrivate; - class DLL_PUBLIC DeviceManager - { - public: - enum class EventType { - Present = 0, - Insert = 1, - Update = 2, /* use case: writable attribute changed externally */ - Remove = 3, - }; - - static uint32_t eventTypeToInteger(EventType event); - static EventType eventTypeFromInteger(uint32_t event_integer); - static std::string eventTypeToString(EventType event); - - DeviceManager(DeviceManagerHooks& hooks); - DeviceManager(const DeviceManager& rhs); - const DeviceManager& operator=(const DeviceManager& rhs); - - virtual ~DeviceManager(); - - virtual void setDefaultBlockedState(bool state) = 0; - virtual void setEnumerationOnlyMode(bool state) = 0; - virtual void start() = 0; - virtual void stop() = 0; - virtual void scan() = 0; - - void setRestoreControllerDeviceState(bool enabled); - bool getRestoreControllerDeviceState() const; - - virtual Pointer applyDevicePolicy(uint32_t id, Rule::Target target) = 0; - - virtual void insertDevice(Pointer device); - Pointer removeDevice(uint32_t id); - - /* Returns a copy of the list of active USB devices */ - PointerVector getDeviceList(); - PointerVector getDeviceList(const Rule& query); - - Pointer getDevice(uint32_t id); - std::mutex& refDeviceMapMutex(); - - /* Call Daemon instance hooks */ - void DeviceEvent(EventType event, Pointer device); - void DeviceException(const String& message); - - static Pointer create(DeviceManagerHooks& hooks, const String& backend); - - private: - DeviceManagerPrivate *d_pointer; - }; - -} /* namespace usbguard */ diff --git a/src/Library/DeviceManagerHooks.cpp b/src/Library/DeviceManagerHooks.cpp deleted file mode 100644 index f039389..0000000 --- a/src/Library/DeviceManagerHooks.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include - -namespace usbguard -{ - void DeviceManagerHooks::dmHookDeviceEvent(DeviceManager::EventType event, Pointer device) - { - (void)event; - (void)device; - /* NOOP */ - } -} /* namespace usbguard */ diff --git a/src/Library/DeviceManagerHooks.hpp b/src/Library/DeviceManagerHooks.hpp deleted file mode 100644 index 7a4d20a..0000000 --- a/src/Library/DeviceManagerHooks.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include -#include -#include -#include - -namespace usbguard -{ - class DLL_PUBLIC DeviceManagerHooks - { - public: - virtual void dmHookDeviceEvent(DeviceManager::EventType event, Pointer device); - virtual uint32_t dmHookAssignID() = 0; - virtual void dmHookDeviceException(const String& message) = 0; - }; -} /* namespace usbguard */ diff --git a/src/Library/DeviceManagerPrivate.cpp b/src/Library/DeviceManagerPrivate.cpp index 579b3c7..990641d 100644 --- a/src/Library/DeviceManagerPrivate.cpp +++ b/src/Library/DeviceManagerPrivate.cpp @@ -16,10 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "DeviceManagerPrivate.hpp" -#include -#include "Exception.hpp" -#include "Logger.hpp" + +#include "usbguard/DeviceManagerHooks.hpp" +#include "usbguard/Exception.hpp" +#include "usbguard/Logger.hpp" namespace usbguard { DeviceManagerPrivate::DeviceManagerPrivate(DeviceManager& p_instance, DeviceManagerHooks& hooks) @@ -55,7 +60,7 @@ namespace usbguard { return _restore_controller_device_state; } - void DeviceManagerPrivate::insertDevice(Pointer device) + void DeviceManagerPrivate::insertDevice(std::shared_ptr device) { USBGUARD_LOG(Trace) << "device_ptr=" << device.get(); std::unique_lock device_map_lock(_device_map_mutex); @@ -65,7 +70,7 @@ namespace usbguard { _device_map[id] = device; } - Pointer DeviceManagerPrivate::removeDevice(uint32_t id) + std::shared_ptr DeviceManagerPrivate::removeDevice(uint32_t id) { USBGUARD_LOG(Trace) << "entry: id=" << id; std::unique_lock device_map_lock(_device_map_mutex); @@ -73,16 +78,16 @@ namespace usbguard { if (it == _device_map.end()) { throw Exception("Device remove", "device id", "id doesn't exist"); } - Pointer device = it->second; + std::shared_ptr device = it->second; _device_map.erase(it); USBGUARD_LOG(Trace) << "return: device_ptr=" << device.get(); return device; } - PointerVector DeviceManagerPrivate::getDeviceList() + std::vector> DeviceManagerPrivate::getDeviceList() { std::unique_lock device_map_lock(_device_map_mutex); - PointerVector devices; + std::vector> devices; for (auto& map_entry : _device_map) { devices.push_back(map_entry.second); @@ -91,7 +96,7 @@ namespace usbguard { return devices; } - Pointer DeviceManagerPrivate::getDevice(uint32_t id) + std::shared_ptr DeviceManagerPrivate::getDevice(uint32_t id) { USBGUARD_LOG(Trace) << "id=" << id; std::unique_lock device_map_lock(_device_map_mutex); @@ -103,14 +108,14 @@ namespace usbguard { } } - void DeviceManagerPrivate::DeviceEvent(DeviceManager::EventType event, Pointer device) + void DeviceManagerPrivate::DeviceEvent(DeviceManager::EventType event, std::shared_ptr device) { USBGUARD_LOG(Trace) << "event=" << DeviceManager::eventTypeToString(event) << "device_ptr=" << device.get(); _hooks.dmHookDeviceEvent(event, device); } - void DeviceManagerPrivate::DeviceException(const String& message) + void DeviceManagerPrivate::DeviceException(const std::string& message) { USBGUARD_LOG(Trace) << "message=" << message; _hooks.dmHookDeviceException(message); diff --git a/src/Library/DeviceManagerPrivate.hpp b/src/Library/DeviceManagerPrivate.hpp index b98443b..7ccf39a 100644 --- a/src/Library/DeviceManagerPrivate.hpp +++ b/src/Library/DeviceManagerPrivate.hpp @@ -17,10 +17,17 @@ // Authors: Daniel Kopecek // #pragma once -#include -#include -#include -#include +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Device.hpp" +#include "usbguard/DeviceManager.hpp" +#include "usbguard/RuleSet.hpp" +#include "usbguard/Typedefs.hpp" + +#include +#include #include namespace usbguard { @@ -35,23 +42,23 @@ namespace usbguard { void setRestoreControllerDeviceState(bool enabled); bool getRestoreControllerDeviceState() const; - void insertDevice(Pointer device); - Pointer removeDevice(uint32_t id); + void insertDevice(std::shared_ptr device); + std::shared_ptr removeDevice(uint32_t id); /* Returns a copy of the list of active USB devices */ - PointerVector getDeviceList(); - Pointer getDevice(uint32_t id); + std::vector> getDeviceList(); + std::shared_ptr getDevice(uint32_t id); std::mutex& refDeviceMapMutex(); /* Call Daemon instance hooks */ - void DeviceEvent(DeviceManager::EventType event, Pointer device); - void DeviceException(const String& message); + void DeviceEvent(DeviceManager::EventType event, std::shared_ptr device); + void DeviceException(const std::string& message); private: DeviceManager& _p_instance; DeviceManagerHooks& _hooks; mutable std::mutex _device_map_mutex; - PointerMap _device_map; + std::map> _device_map; bool _restore_controller_device_state; }; diff --git a/src/Library/DevicePrivate.cpp b/src/Library/DevicePrivate.cpp index da91c27..fa422ac 100644 --- a/src/Library/DevicePrivate.cpp +++ b/src/Library/DevicePrivate.cpp @@ -16,12 +16,18 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "DevicePrivate.hpp" -#include "DeviceManager.hpp" -#include "Logger.hpp" #include "Hash.hpp" -#include "Exception.hpp" #include "Common/Utility.hpp" + +#include "usbguard/DeviceManager.hpp" +#include "usbguard/Logger.hpp" +#include "usbguard/Exception.hpp" + #include namespace usbguard { @@ -68,14 +74,14 @@ namespace usbguard { return _mutex; } - Pointer DevicePrivate::getDeviceRule(const bool with_port, const bool with_parent_hash, const bool match_rule) + std::shared_ptr DevicePrivate::getDeviceRule(const bool with_port, const bool with_parent_hash, const bool match_rule) { USBGUARD_LOG(Trace) << "entry: " << " with_port=" << with_port << " with_parent_hash=" << with_parent_hash << " match_rule=" << match_rule; - Pointer device_rule = makePointer(); + std::shared_ptr device_rule = std::make_shared(); std::unique_lock device_lock(refDeviceMutex()); device_rule->setRuleID(_id); @@ -117,7 +123,7 @@ namespace usbguard { return device_rule; } - String DevicePrivate::hashString(const String& value) const + std::string DevicePrivate::hashString(const std::string& value) const { Hash hash; hash.update(value); @@ -128,8 +134,8 @@ namespace usbguard { { Hash hash; - const String vendor_id = _device_id.getVendorID(); - const String product_id = _device_id.getProductID(); + const std::string vendor_id = _device_id.getVendorID(); + const std::string product_id = _device_id.getProductID(); if (vendor_id.empty() || product_id.empty()) { throw Exception("Device hash initialization", numberToString(getID()), "vendor and/or product id values not available"); @@ -138,7 +144,7 @@ namespace usbguard { /* * Hash name, device id and serial number fields. */ - for (const String& field : { _name, vendor_id, product_id, _serial_number }) { + for (const std::string& field : { _name, vendor_id, product_id, _serial_number }) { hash.update(field); } @@ -167,13 +173,13 @@ namespace usbguard { _hash = std::move(hash); } - String DevicePrivate::finalizeHash() + std::string DevicePrivate::finalizeHash() { _hash_base64 = _hash.getBase64(); return _hash_base64; } - const String& DevicePrivate::getHash() const + const std::string& DevicePrivate::getHash() const { if (_hash_base64.empty()) { throw USBGUARD_BUG("Accessing unfinalized device hash value"); @@ -181,7 +187,7 @@ namespace usbguard { return _hash_base64; } - void DevicePrivate::setParentHash(const String& hash) + void DevicePrivate::setParentHash(const std::string& hash) { _parent_hash = hash; } @@ -216,7 +222,7 @@ namespace usbguard { return _target; } - void DevicePrivate::setName(const String& name) + void DevicePrivate::setName(const std::string& name) { if (name.size() > USB_GENERIC_STRING_MAX_LENGTH) { throw Exception("DevicePrivate::setName", numberToString(getID()), "name string size out-of-range"); @@ -224,7 +230,7 @@ namespace usbguard { _name = name; } - const String& DevicePrivate::getName() const + const std::string& DevicePrivate::getName() const { return _name; } @@ -239,7 +245,7 @@ namespace usbguard { return _device_id; } - void DevicePrivate::setPort(const String& port) + void DevicePrivate::setPort(const std::string& port) { if (port.size() > USB_PORT_STRING_MAX_LENGTH) { throw std::runtime_error("device port string size out of range"); @@ -247,12 +253,12 @@ namespace usbguard { _port = port; } - const String& DevicePrivate::getPort() const + const std::string& DevicePrivate::getPort() const { return _port; } - void DevicePrivate::setSerial(const String& serial_number) + void DevicePrivate::setSerial(const std::string& serial_number) { if (serial_number.size() > USB_GENERIC_STRING_MAX_LENGTH) { throw std::runtime_error("device serial number string size out of range"); @@ -260,7 +266,7 @@ namespace usbguard { _serial_number = serial_number; } - const String& DevicePrivate::getSerial() const + const std::string& DevicePrivate::getSerial() const { return _serial_number; } diff --git a/src/Library/DevicePrivate.hpp b/src/Library/DevicePrivate.hpp index 940653d..ef1d801 100644 --- a/src/Library/DevicePrivate.hpp +++ b/src/Library/DevicePrivate.hpp @@ -17,14 +17,23 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "Hash.hpp" + +#include "usbguard/Device.hpp" +#include "usbguard/Rule.hpp" +#include "usbguard/Typedefs.hpp" +#include "usbguard/USB.hpp" -#include -#include -#include -#include -#include -#include #include +#include +#include +#include + +#include namespace usbguard { class DevicePrivate @@ -37,16 +46,16 @@ namespace usbguard { DeviceManager& manager() const; std::mutex& refDeviceMutex(); - Pointer getDeviceRule(bool with_port = true, bool with_parent_hash = true, bool match_rule = false); - String hashString(const String& value) const; + std::shared_ptr getDeviceRule(bool with_port = true, bool with_parent_hash = true, bool match_rule = false); + std::string hashString(const std::string& value) const; void initializeHash(); void updateHash(const void * const ptr, size_t size); void updateHash(std::istream& descriptor_stream, size_t expected_size); - String finalizeHash(); - const String& getHash() const; + std::string finalizeHash(); + const std::string& getHash() const; - void setParentHash(const String& hash); + void setParentHash(const std::string& hash); void setID(uint32_t id); uint32_t getID() const; @@ -57,17 +66,17 @@ namespace usbguard { void setTarget(Rule::Target target); Rule::Target getTarget() const; - void setName(const String& name); - const String& getName() const; + void setName(const std::string& name); + const std::string& getName() const; void setDeviceID(const USBDeviceID& device_id); const USBDeviceID& getDeviceID() const; - void setPort(const String& port); - const String& getPort() const; + void setPort(const std::string& port); + const std::string& getPort() const; - void setSerial(const String& serial_number); - const String& getSerial() const; + void setSerial(const std::string& serial_number); + const std::string& getSerial() const; std::vector& refMutableInterfaceTypes(); const std::vector& getInterfaceTypes() const; @@ -83,14 +92,14 @@ namespace usbguard { std::mutex _mutex; uint32_t _id; uint32_t _parent_id; - String _parent_hash; + std::string _parent_hash; Rule::Target _target; - String _name; + std::string _name; USBDeviceID _device_id; - String _serial_number; - String _port; + std::string _serial_number; + std::string _port; std::vector _interface_types; - String _hash_base64; + std::string _hash_base64; Hash _hash; }; } /* namespace usbguard */ diff --git a/src/Library/Exception.hpp b/src/Library/Exception.hpp deleted file mode 100644 index c985704..0000000 --- a/src/Library/Exception.hpp +++ /dev/null @@ -1,176 +0,0 @@ -// -// Copyright (C) 2016 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include - -#include -#ifndef _GNU_SOURCE -# define _GNU_SOURCE -#endif -#include -#include - -namespace usbguard -{ - class DLL_PUBLIC Exception : public std::exception - { - public: - Exception(const String& context, - const String& object, - const String& reason_val) - : _context(context), - _object(object), - _reason(reason_val) - { - } - - Exception(const Exception& rhs) - : _context(rhs._context), - _object(rhs._object), - _reason(rhs._reason) - { - } - - const String& context() const noexcept - { - return _context; - } - - const String& object() const noexcept - { - return _object; - } - - const String& reason() const noexcept - { - return _reason; - } - - void setContext(const String& context) - { - _context = context; - } - - void setObject(const String& object) - { - _object = object; - } - - void setReason(const String& reason_val) - { - _reason = reason_val; - } - - virtual String message() const noexcept - { - try { - return _context + ": " + (!_object.empty() ? _object + ": " : "") + _reason; - } - catch(...) { - return "usbguard::Exception: exception^2"; - } - } - - virtual const char * what() const noexcept - { - return "usbguard::Exception"; - } - - private: - String _context; - String _object; - String _reason; - }; - -#define USBGUARD_BUG(m) \ - ::usbguard::Exception(__PRETTY_FUNCTION__, "BUG", m) - - class ErrnoException : public Exception - { - public: - ErrnoException(const String& context, const String& object, const int errno_value) - : Exception(context, object, ErrnoException::reasonFromErrno(errno_value)) - { - } - private: - static String reasonFromErrno(const int errno_value) - { - char buffer[1024]; - return String(strerror_r(errno_value, buffer, sizeof buffer)); - } - }; - -#define USBGUARD_SYSCALL_THROW(context, syscall_bool_expression) \ - do { \ - if (syscall_bool_expression) { \ - throw usbguard::ErrnoException(context, #syscall_bool_expression, errno); \ - } \ - } while(0) - - class IPCException : public Exception - { - public: - IPCException() - : Exception("", "", ""), - _message_id(0) - { - } - - IPCException(const Exception& exception, - uint64_t message_id = 0) - : Exception(exception), - _message_id(message_id) - { - } - - IPCException(const String& context, - const String& object, - const String& reason, - uint64_t message_id = 0) - : Exception(context, object, reason), - _message_id(message_id) - { - } - - IPCException(const IPCException& rhs) - : Exception(rhs), - _message_id(rhs._message_id) - { - } - - bool hasMessageID() const noexcept - { - return _message_id != 0; - } - - uint64_t messageID() const noexcept - { - return _message_id; - } - - void setMessageID(uint64_t message_id) - { - _message_id = message_id; - } - - private: - uint64_t _message_id; - }; -} /* namespace usbguard */ diff --git a/src/Library/FixedStateCondition.cpp b/src/Library/FixedStateCondition.cpp index e201f64..b53de2f 100644 --- a/src/Library/FixedStateCondition.cpp +++ b/src/Library/FixedStateCondition.cpp @@ -16,8 +16,13 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "FixedStateCondition.hpp" -#include "RuleParser.hpp" + +#include "usbguard/RuleParser.hpp" namespace usbguard { diff --git a/src/Library/FixedStateCondition.hpp b/src/Library/FixedStateCondition.hpp index 9a23376..250f74e 100644 --- a/src/Library/FixedStateCondition.hpp +++ b/src/Library/FixedStateCondition.hpp @@ -17,9 +17,14 @@ // Authors: Daniel Kopecek // #pragma once -#include "Typedefs.hpp" -#include "RuleCondition.hpp" -#include "Rule.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Typedefs.hpp" +#include "usbguard/Rule.hpp" + +#include "usbguard/RuleCondition.hpp" namespace usbguard { diff --git a/src/Library/Hash.cpp b/src/Library/Hash.cpp index 455f773..0bad18b 100644 --- a/src/Library/Hash.cpp +++ b/src/Library/Hash.cpp @@ -16,13 +16,16 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include +#endif #include "Hash.hpp" #include "Base64.hpp" -#include "Exception.hpp" #include "Common/Utility.hpp" +#include "usbguard/Exception.hpp" + namespace usbguard { Hash::Hash() @@ -87,7 +90,7 @@ namespace usbguard #endif } - size_t Hash::update(const String& value) + size_t Hash::update(const std::string& value) { return update(value.c_str(), value.size()); } @@ -127,7 +130,7 @@ namespace usbguard return size_hashed; } - String Hash::getBase64() + std::string Hash::getBase64() { #if defined(USBGUARD_USE_LIBSODIUM) uint8_t hash_binary[crypto_hash_sha256_BYTES]; diff --git a/src/Library/Hash.hpp b/src/Library/Hash.hpp index 23623ec..5c2fa5f 100644 --- a/src/Library/Hash.hpp +++ b/src/Library/Hash.hpp @@ -17,12 +17,16 @@ // Authors: Daniel Kopecek // #pragma once - +#ifdef HAVE_BUILD_CONFIG_H #include +#endif + +#include "usbguard/Typedefs.hpp" -#include "Typedefs.hpp" -#include #include +#include + +#include #if defined(USBGUARD_USE_LIBSODIUM) #include @@ -42,10 +46,10 @@ namespace usbguard Hash(Hash&& rhs); Hash& operator=(Hash&& rhs); ~Hash(); - size_t update(const String& value); + size_t update(const std::string& value); size_t update(const void *ptr, size_t size); size_t update(std::istream& stream); - String getBase64(); + std::string getBase64(); private: #if defined(USBGUARD_USE_LIBSODIUM) crypto_hash_sha256_state _state; diff --git a/src/Library/IPCClient.cpp b/src/Library/IPCClient.cpp deleted file mode 100644 index 03b2fa5..0000000 --- a/src/Library/IPCClient.cpp +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include "IPCClientPrivate.hpp" - -namespace usbguard -{ - IPCClient::IPCClient(bool connected) - { - d_pointer = new IPCClientPrivate(*this, connected); - } - - IPCClient::~IPCClient() - { - delete d_pointer; - } - - void IPCClient::connect() - { - d_pointer->connect(); - } - - void IPCClient::disconnect() - { - d_pointer->disconnect(/*do_wait*/true); - } - - bool IPCClient::isConnected() const - { - return d_pointer->isConnected(); - } - - void IPCClient::wait() - { - d_pointer->wait(); - } - - std::string IPCClient::setParameter(const std::string& name, const std::string& value) - { - return d_pointer->setParameter(name, value); - } - - std::string IPCClient::getParameter(const std::string& name) - { - return d_pointer->getParameter(name); - } - - uint32_t IPCClient::appendRule(const std::string& rule_spec, uint32_t parent_id) - { - return d_pointer->appendRule(rule_spec, parent_id); - } - - void IPCClient::removeRule(uint32_t id) - { - d_pointer->removeRule(id); - } - - const RuleSet IPCClient::listRules(const std::string& query) - { - return d_pointer->listRules(query); - } - - uint32_t IPCClient::applyDevicePolicy(uint32_t id, Rule::Target target, bool permanent) - { - return d_pointer->applyDevicePolicy(id, target, permanent); - } - - const std::vector IPCClient::listDevices(const std::string& query) - { - return d_pointer->listDevices(query); - } -} /* namespace usbguard */ diff --git a/src/Library/IPCClient.hpp b/src/Library/IPCClient.hpp deleted file mode 100644 index d72c043..0000000 --- a/src/Library/IPCClient.hpp +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once -#include -#include -#include -#include - -namespace usbguard -{ - class IPCClientPrivate; - class DLL_PUBLIC IPCClient : public Interface - { - public: - IPCClient(bool connected = false); - virtual ~IPCClient(); - - void connect(); - void disconnect(); - bool isConnected() const; - void wait(); - - std::string setParameter(const std::string& name, const std::string& value) override; - std::string getParameter(const std::string& name) override; - - uint32_t appendRule(const std::string& rule_spec, uint32_t parent_id) override; - void removeRule(uint32_t id) override; - const RuleSet listRules(const std::string& query) override; - const RuleSet listRules() - { - return listRules("match"); - } - - uint32_t applyDevicePolicy(uint32_t id, Rule::Target target, bool permanent) override; - const std::vector listDevices(const std::string& query) override; - const std::vector listDevices() /* NOTE: left for compatibility */ - { - return listDevices("match"); - } - - virtual void IPCConnected() {} - - virtual void IPCDisconnected(bool exception_initiated, const IPCException& exception) - { - (void)exception_initiated; - (void)exception; - } - - virtual void DevicePresenceChanged(uint32_t id, - DeviceManager::EventType event, - Rule::Target target, - const std::string& device_rule) override - { - (void)id; - (void)event; - (void)target; - (void)device_rule; - } - - virtual void DevicePolicyChanged(uint32_t id, - Rule::Target target_old, - Rule::Target target_new, - const std::string& device_rule, - uint32_t rule_id) override - { - (void)id; - (void)target_old; - (void)target_new; - (void)device_rule; - (void)rule_id; - } - - virtual void ExceptionMessage(const std::string& context, - const std::string& object, - const std::string& reason) override - { - (void)context; - (void)object; - (void)reason; - } - - private: - IPCClientPrivate* d_pointer; - }; - -} /* namespace usbguard */ diff --git a/src/Library/IPCClientPrivate.cpp b/src/Library/IPCClientPrivate.cpp index 5e24a09..fc9e044 100644 --- a/src/Library/IPCClientPrivate.cpp +++ b/src/Library/IPCClientPrivate.cpp @@ -16,9 +16,14 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "IPCClientPrivate.hpp" #include "IPCPrivate.hpp" -#include "Logger.hpp" + +#include "usbguard/Logger.hpp" #include #include diff --git a/src/Library/IPCClientPrivate.hpp b/src/Library/IPCClientPrivate.hpp index 71ad73e..3905d9a 100644 --- a/src/Library/IPCClientPrivate.hpp +++ b/src/Library/IPCClientPrivate.hpp @@ -17,9 +17,10 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H #include -#include "Typedefs.hpp" -#include "IPCClient.hpp" +#endif + #include "IPCPrivate.hpp" #include "Common/Thread.hpp" @@ -28,6 +29,9 @@ #include "Exception.pb.h" #include "Parameter.pb.h" +#include "usbguard/Typedefs.hpp" +#include "usbguard/IPCClient.hpp" + #include #include #include diff --git a/src/Library/IPCPrivate.cpp b/src/Library/IPCPrivate.cpp index 14f3015..1fdc6c0 100644 --- a/src/Library/IPCPrivate.cpp +++ b/src/Library/IPCPrivate.cpp @@ -16,12 +16,17 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "IPCPrivate.hpp" -#include "Logger.hpp" -#include -#include -#include +#include "Devices.pb.h" +#include "Exception.pb.h" +#include "Policy.pb.h" + +#include "usbguard/Logger.hpp" #include #include diff --git a/src/Library/IPCPrivate.hpp b/src/Library/IPCPrivate.hpp index badf450..1723649 100644 --- a/src/Library/IPCPrivate.hpp +++ b/src/Library/IPCPrivate.hpp @@ -17,10 +17,13 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif -#include "Exception.hpp" -#include "Typedefs.hpp" -#include "IPCServer.hpp" +#include "usbguard/Exception.hpp" +#include "usbguard/Typedefs.hpp" +#include "usbguard/IPCServer.hpp" #include #include diff --git a/src/Library/IPCServer.cpp b/src/Library/IPCServer.cpp deleted file mode 100644 index 69db0d2..0000000 --- a/src/Library/IPCServer.cpp +++ /dev/null @@ -1,303 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include "IPCServerPrivate.hpp" -#include "Common/Utility.hpp" - -#include - -namespace usbguard -{ - void IPCServer::checkAccessControlName(const std::string& name) - { - if (name.size() > 32) { - throw Exception("IPC access control", "name too long", name); - } - - const String valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; - - if (name.find_first_not_of(valid_chars) != std::string::npos) { - throw Exception("IPC access control", "name contains invalid character(s)", name); - } - - } - - static const std::vector> section_ttable = { - { "ALL", IPCServer::AccessControl::Section::ALL }, - { "Policy", IPCServer::AccessControl::Section::POLICY }, - { "Parameters", IPCServer::AccessControl::Section::PARAMETERS }, - { "Devices", IPCServer::AccessControl::Section::DEVICES }, - { "Exceptions", IPCServer::AccessControl::Section::EXCEPTIONS }, - { "None", IPCServer::AccessControl::Section::NONE } - }; - - IPCServer::AccessControl::Section IPCServer::AccessControl::sectionFromString(const std::string& section_string) - { - for (auto ttable_entry : section_ttable) { - if (ttable_entry.first == section_string) { - return ttable_entry.second; - } - } - throw std::runtime_error("Invalid AccessControl::Section string"); - } - - std::string IPCServer::AccessControl::sectionToString(const IPCServer::AccessControl::Section section) - { - for (auto ttable_entry : section_ttable) { - if (ttable_entry.second == section) { - return ttable_entry.first; - } - } - throw std::runtime_error("Invalid AccessControl::Section value"); - } - - static const std::vector> privilege_ttable = { - { "ALL", IPCServer::AccessControl::Privilege::ALL }, - { "modify", IPCServer::AccessControl::Privilege::MODIFY }, - { "list", IPCServer::AccessControl::Privilege::LIST }, - { "listen", IPCServer::AccessControl::Privilege::LISTEN }, - { "none", IPCServer::AccessControl::Privilege::NONE } - }; - - IPCServer::AccessControl::Privilege IPCServer::AccessControl::privilegeFromString(const std::string& privilege_string) - { - for (auto ttable_entry : privilege_ttable) { - if (ttable_entry.first == privilege_string) { - return ttable_entry.second; - } - } - throw std::runtime_error("Invalid AccessControl::Section string"); - } - - std::string IPCServer::AccessControl::privilegeToString(const IPCServer::AccessControl::Privilege privilege) - { - for (auto ttable_entry : privilege_ttable) { - if (ttable_entry.second == privilege) { - return ttable_entry.first; - } - } - throw std::runtime_error("Invalid AccessControl::Privilege value"); - } - - IPCServer::AccessControl::AccessControl() - { - /* Empty: no privileges */ - } - - IPCServer::AccessControl::AccessControl(const std::string& access_control_string) - { - std::stringstream ss(access_control_string); - load(ss); - } - - IPCServer::AccessControl::AccessControl(IPCServer::AccessControl::Section section, IPCServer::AccessControl::Privilege privilege) - { - setPrivilege(section, privilege); - } - - IPCServer::AccessControl::AccessControl(const IPCServer::AccessControl& rhs) - : _access_control(rhs._access_control) - { - } - - IPCServer::AccessControl& IPCServer::AccessControl::operator=(const IPCServer::AccessControl& rhs) - { - _access_control = rhs._access_control; - return *this; - } - - bool IPCServer::AccessControl::hasPrivilege(IPCServer::AccessControl::Section section, IPCServer::AccessControl::Privilege privilege) const - { - if (section == Section::ALL || section == Section::NONE) { - throw USBGUARD_BUG("Cannot test against ALL, NONE sections"); - } - - const auto it = _access_control.find(section); - - if (it == _access_control.cend()) { - return false; - } - - return (it->second & static_cast(privilege)) == static_cast(privilege); - } - - void IPCServer::AccessControl::setPrivilege(IPCServer::AccessControl::Section section, IPCServer::AccessControl::Privilege privilege) - { - if (section == Section::NONE) { - throw USBGUARD_BUG("Cannot set privileges for NONE section"); - } - if (section == Section::ALL) { - for (const auto& value : { - Section::POLICY, - Section::PARAMETERS, - Section::EXCEPTIONS, - Section::DEVICES }) { - _access_control[value] |= static_cast(privilege); - } - } - else { - _access_control[section] |= static_cast(privilege); - } - } - - void IPCServer::AccessControl::clear() - { - _access_control.clear(); - } - - void IPCServer::AccessControl::load(std::istream& stream) - { - std::string line; - size_t line_number = 0; - - while (std::getline(stream, line)) { - ++line_number; - const size_t nv_separator = line.find_first_of("="); - - if (nv_separator == String::npos) { - continue; - } - - const String section_string = trim(line.substr(0, nv_separator)); - const Section section = sectionFromString(section_string); - - const String privileges_string = line.substr(nv_separator + 1); - StringVector privilege_strings; - tokenizeString(privileges_string, privilege_strings, " ,", /*trim_empty=*/true); - - for (const String& privilege_string : privilege_strings) { - const Privilege privilege = privilegeFromString(privilege_string); - setPrivilege(section, privilege); - } - } - } - - void IPCServer::AccessControl::save(std::ostream& stream) const - { - std::string access_control_string; - - for (auto const& section : { - Section::DEVICES, - Section::POLICY, - Section::PARAMETERS, - Section::EXCEPTIONS - }) { - bool section_is_empty = true; - std::string section_string = sectionToString(section); - section_string.append("="); - - for (auto const& privilege : { - Privilege::LIST, - Privilege::MODIFY, - Privilege::LISTEN - }) { - if (hasPrivilege(section, privilege)) { - const std::string privilege_string = privilegeToString(privilege); - section_string.append(privilege_string); - section_string.append(","); - section_is_empty = false; - } - } - - if (!section_is_empty) { - section_string.pop_back(); - access_control_string.append(section_string); - access_control_string.append("\n"); - } - } - - stream << access_control_string; - } - - void IPCServer::AccessControl::merge(const IPCServer::AccessControl& rhs) - { - for (auto const& ac_entry : rhs._access_control) { - _access_control[ac_entry.first] |= ac_entry.second; - } - } - - void IPCServer::AccessControl::merge(const std::string& access_control_string) - { - const AccessControl access_control(access_control_string); - merge(access_control); - } - - IPCServer::IPCServer() - { - d_pointer = new IPCServerPrivate(*this); - } - - IPCServer::~IPCServer() - { - delete d_pointer; - } - - void IPCServer::start() - { - d_pointer->start(); - } - - void IPCServer::stop() - { - d_pointer->stop(); - } - - void IPCServer::DevicePresenceChanged(uint32_t id, - DeviceManager::EventType event, - Rule::Target target, - const std::string& device_rule) - { - d_pointer->DevicePresenceChanged(id, event, target, device_rule); - } - - void IPCServer::DevicePolicyChanged(uint32_t id, - Rule::Target target_old, - Rule::Target target_new, - const std::string& device_rule, - uint32_t rule_id) - { - d_pointer->DevicePolicyChanged(id, target_old, target_new, device_rule, rule_id); - } - - void IPCServer::ExceptionMessage(const std::string& context, - const std::string& object, - const std::string& reason) - { - d_pointer->ExceptionMessage(context, object, reason); - } - - void IPCServer::addAllowedUID(uid_t uid, const IPCServer::AccessControl& ac) - { - d_pointer->addAllowedUID(uid, ac); - } - - void IPCServer::addAllowedGID(gid_t gid, const IPCServer::AccessControl& ac) - { - d_pointer->addAllowedGID(gid, ac); - } - - void IPCServer::addAllowedUsername(const std::string& username, const IPCServer::AccessControl& ac) - { - d_pointer->addAllowedUsername(username, ac); - } - - void IPCServer::addAllowedGroupname(const std::string& groupname, const IPCServer::AccessControl& ac) - { - d_pointer->addAllowedGroupname(groupname, ac); - } -} /* namespace usbguard */ diff --git a/src/Library/IPCServer.hpp b/src/Library/IPCServer.hpp deleted file mode 100644 index 954be0c..0000000 --- a/src/Library/IPCServer.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// -// Copyright (C) 2016 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once -#include -#include -#include -#include - -#include -#include - -namespace usbguard -{ - class IPCServerPrivate; - class DLL_PUBLIC IPCServer : public Interface - { - public: - static void checkAccessControlName(const std::string& name); - - class AccessControl - { - public: - enum class Section : uint8_t { - NONE = 0, - DEVICES = 1, - POLICY = 2, - PARAMETERS = 3, - EXCEPTIONS = 4, - ALL = 255 - }; - - static Section sectionFromString(const std::string& section_string); - static std::string sectionToString(const Section section); - - enum class Privilege : uint8_t { - NONE = 0x00, - LIST = 0x01, - MODIFY = 0x02, - LISTEN = 0x08, - ALL = 0xff - }; - - static Privilege privilegeFromString(const std::string& privilege_string); - static std::string privilegeToString(const Privilege privilege); - - AccessControl(); - AccessControl(const std::string& access_control_string); - AccessControl(Section section, Privilege privilege); - AccessControl(const AccessControl& rhs); - AccessControl& operator=(const AccessControl& rhs); - - bool hasPrivilege(Section section, Privilege privilege) const; - void setPrivilege(Section section, Privilege privilege); - void clear(); - void load(std::istream& stream); - void save(std::ostream& stream) const; - void merge(const AccessControl& rhs); - void merge(const std::string& access_control_string); - - private: - struct SectionHash { - std::size_t operator()(Section value) const - { - return static_cast(value); - } - }; - - std::unordered_map _access_control; - }; - - IPCServer(); - virtual ~IPCServer(); - - void start(); - void stop(); - - void DevicePresenceChanged(uint32_t id, - DeviceManager::EventType event, - Rule::Target target, - const std::string& device_rule); - - void DevicePolicyChanged(uint32_t id, - Rule::Target target_old, - Rule::Target target_new, - const std::string& device_rule, - uint32_t rule_id); - - void ExceptionMessage(const std::string& context, - const std::string& object, - const std::string& reason); - - void addAllowedUID(uid_t uid, const IPCServer::AccessControl& ac); - void addAllowedGID(gid_t gid, const IPCServer::AccessControl& ac); - void addAllowedUsername(const std::string& username, const IPCServer::AccessControl& ac); - void addAllowedGroupname(const std::string& groupname, const IPCServer::AccessControl& ac); - - private: - IPCServerPrivate* d_pointer; - }; -} /* namespace usbguard */ - diff --git a/src/Library/IPCServerPrivate.cpp b/src/Library/IPCServerPrivate.cpp index 56f8890..a83fc0e 100644 --- a/src/Library/IPCServerPrivate.cpp +++ b/src/Library/IPCServerPrivate.cpp @@ -16,12 +16,17 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "IPCServerPrivate.hpp" #include "IPCPrivate.hpp" -#include "Logger.hpp" -#include "Exception.hpp" #include "Common/Utility.hpp" +#include "usbguard/Logger.hpp" +#include "usbguard/Exception.hpp" + #include #include #include @@ -237,7 +242,7 @@ namespace usbguard IPCServerPrivate* server = \ static_cast(qb_ipcs_connection_service_context_get(conn)); - UniquePointer access_control(new IPCServer::AccessControl()); + std::unique_ptr access_control(new IPCServer::AccessControl()); const bool auth = server->qbIPCConnectionAllowed(uid, gid, access_control.get()); qb_ipcs_context_set(conn, access_control.release()); @@ -587,7 +592,7 @@ namespace usbguard USBGUARD_LOG(Trace) << "uid=" << uid << " gid=" << gid << " ac_ptr=" << ac_ptr; bool matched = false; - const String uid_name = getNameFromUID(uid); + const std::string uid_name = getNameFromUID(uid); const bool check_uid_group_membership = !uid_name.empty(); if (!uid_name.empty()) { @@ -602,7 +607,7 @@ namespace usbguard } } - const String gid_name = getNameFromGID(gid); + const std::string gid_name = getNameFromGID(gid); if (!gid_name.empty()) { const auto& it = _allowed_groupnames.find(gid_name); @@ -623,7 +628,7 @@ namespace usbguard */ for (auto const& allowed_gid_entry : _allowed_gids) { const auto& allowed_gid = allowed_gid_entry.first; - const std::vector group_members = getGroupMemberNames(allowed_gid); + const std::vector group_members = getGroupMemberNames(allowed_gid); for (const auto& group_member : group_members) { if (group_member == uid_name) { @@ -641,7 +646,7 @@ namespace usbguard */ for (auto const& allowed_groupnames_entry : _allowed_groupnames) { const auto& allowed_groupname = allowed_groupnames_entry.first; - const std::vector group_members = getGroupMemberNames(allowed_groupname); + const std::vector group_members = getGroupMemberNames(allowed_groupname); for (const auto& group_member : group_members) { if (group_member == uid_name) { @@ -665,87 +670,87 @@ namespace usbguard return matched; } - String IPCServerPrivate::getNameFromUID(uid_t uid) + std::string IPCServerPrivate::getNameFromUID(uid_t uid) { - String buffer(1024, 0); + std::string buffer(1024, 0); struct passwd pw = { }; struct passwd *pwptr = nullptr; if (getpwuid_r(uid, &pw, &buffer[0], buffer.capacity(), &pwptr) != 0) { USBGUARD_LOG(Warning) << "Unable to lookup username for uid=" << uid << ": errno=" << errno; - return String(); + return std::string(); } if (pwptr == nullptr || pw.pw_name == nullptr) { USBGUARD_LOG(Info) << "No username associated with uid=" << uid; - return String(); + return std::string(); } - return String(pw.pw_name); + return std::string(pw.pw_name); } - String IPCServerPrivate::getNameFromGID(gid_t gid) + std::string IPCServerPrivate::getNameFromGID(gid_t gid) { - String buffer(4096, 0); + std::string buffer(4096, 0); struct group gr = { }; struct group *grptr = nullptr; if (getgrgid_r(gid, &gr, &buffer[0], buffer.capacity(), &grptr) != 0) { USBGUARD_LOG(Warning) << "Unable to lookup groupname for gid=" << gid << ": errno=" << errno; - return String(); + return std::string(); } if (grptr == nullptr || gr.gr_name == nullptr) { USBGUARD_LOG(Info) << "No groupname associated with gid=" << gid; - return String(); + return std::string(); } - return String(gr.gr_name); + return std::string(gr.gr_name); } - std::vector IPCServerPrivate::getGroupMemberNames(gid_t gid) + std::vector IPCServerPrivate::getGroupMemberNames(gid_t gid) { - std::vector names; - String buffer(4096, 0); + std::vector names; + std::string buffer(4096, 0); struct group gr = { }; struct group *grptr = nullptr; if (getgrgid_r(gid, &gr, &buffer[0], buffer.capacity(), &grptr) != 0) { USBGUARD_LOG(Warning) << "Unable to fetch group members for gid=" << gid << ": errno=" << errno; - return std::vector(); + return std::vector(); } if (grptr == nullptr || gr.gr_name == nullptr) { USBGUARD_LOG(Info) << "No group associated with gid=" << gid; - return std::vector(); + return std::vector(); } for (size_t i = 0; gr.gr_mem[i] != nullptr; ++i) { - names.emplace_back(String(gr.gr_mem[i])); + names.emplace_back(std::string(gr.gr_mem[i])); } return names; } - std::vector IPCServerPrivate::getGroupMemberNames(const std::string& groupname) + std::vector IPCServerPrivate::getGroupMemberNames(const std::string& groupname) { - std::vector names; - String buffer(4096, 0); + std::vector names; + std::string buffer(4096, 0); struct group gr = { }; struct group *grptr = nullptr; if (getgrnam_r(groupname.c_str(), &gr, &buffer[0], buffer.capacity(), &grptr) != 0) { USBGUARD_LOG(Warning) << "Unable to fetch group member names for groupname=" << groupname << ": errno=" << errno; - return std::vector(); + return std::vector(); } if (grptr == nullptr || gr.gr_name == nullptr) { USBGUARD_LOG(Info) << "Can't find group with name=" << groupname; - return std::vector(); + return std::vector(); } for (size_t i = 0; gr.gr_mem[i] != nullptr; ++i) { - names.emplace_back(String(gr.gr_mem[i])); + names.emplace_back(std::string(gr.gr_mem[i])); } return names; diff --git a/src/Library/IPCServerPrivate.hpp b/src/Library/IPCServerPrivate.hpp index 8c4629b..4ee1429 100644 --- a/src/Library/IPCServerPrivate.hpp +++ b/src/Library/IPCServerPrivate.hpp @@ -17,12 +17,21 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H #include -#include "Typedefs.hpp" -#include "IPCServer.hpp" +#endif + #include "IPCPrivate.hpp" #include "Common/Thread.hpp" +#include "Devices.pb.h" +#include "Policy.pb.h" +#include "Exception.pb.h" +#include "Parameter.pb.h" + +#include "usbguard/Typedefs.hpp" +#include "usbguard/IPCServer.hpp" + #include #include #include @@ -30,11 +39,6 @@ #include #include -#include "Devices.pb.h" -#include "Policy.pb.h" -#include "Exception.pb.h" -#include "Parameter.pb.h" - namespace usbguard { class IPCServerPrivate { @@ -97,10 +101,10 @@ namespace usbguard { bool matchACLByGID(gid_t gid, IPCServer::AccessControl * const ac_ptr) const; bool matchACLByName(uid_t uid, gid_t gid, IPCServer::AccessControl * const ac_ptr) const; - static String getNameFromUID(uid_t uid); - static String getNameFromGID(gid_t gid); - static std::vector getGroupMemberNames(gid_t gid); - static std::vector getGroupMemberNames(const std::string& groupname); + static std::string getNameFromUID(uid_t uid); + static std::string getNameFromGID(gid_t gid); + static std::vector getGroupMemberNames(gid_t gid); + static std::vector getGroupMemberNames(const std::string& groupname); static void qbIPCSendMessage(qb_ipcs_connection_t *qb_conn, const IPC::MessagePointer& message); static IPCServer::AccessControl::Section messageTypeNameToAccessControlSection(const std::string& name); diff --git a/src/Library/Init.cpp b/src/Library/Init.cpp index c4acbc5..23b81a5 100644 --- a/src/Library/Init.cpp +++ b/src/Library/Init.cpp @@ -16,7 +16,9 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include +#endif #include "IPCServerPrivate.hpp" #include "IPCClientPrivate.hpp" diff --git a/src/Library/Interface.hpp b/src/Library/Interface.hpp deleted file mode 100644 index 5acc99a..0000000 --- a/src/Library/Interface.hpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace usbguard -{ - class DLL_PUBLIC Interface - { - public: - /* Parameters */ - virtual std::string setParameter(const std::string& name, const std::string& value) = 0; - virtual std::string getParameter(const std::string& name) = 0; - - /* Methods */ - virtual uint32_t appendRule(const std::string& rule_spec, - uint32_t parent_id) = 0; - - virtual void removeRule(uint32_t id) = 0; - - virtual const RuleSet listRules(const std::string& query) = 0; - - virtual uint32_t applyDevicePolicy(uint32_t id, - Rule::Target target, - bool permanent) = 0; - - virtual const std::vector listDevices(const std::string& query) = 0; - - /* Signals */ - virtual void DevicePresenceChanged(uint32_t id, - DeviceManager::EventType event, - Rule::Target target, - const std::string& device_rule) = 0; - - virtual void DevicePolicyChanged(uint32_t id, - Rule::Target target_old, - Rule::Target target_new, - const std::string& device_rule, - uint32_t rule_id) = 0; - - virtual void ExceptionMessage(const std::string& context, - const std::string& object, - const std::string& reason) = 0; - }; -} /* namespace usbguard */ diff --git a/src/Library/LocaltimeCondition.cpp b/src/Library/LocaltimeCondition.cpp index 0ed05e8..7299875 100644 --- a/src/Library/LocaltimeCondition.cpp +++ b/src/Library/LocaltimeCondition.cpp @@ -16,9 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "LocaltimeCondition.hpp" -#include "RuleParser.hpp" #include "Common/Utility.hpp" + +#include "usbguard/RuleParser.hpp" + #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #include @@ -26,11 +32,11 @@ namespace usbguard { - LocaltimeCondition::LocaltimeCondition(const String& time_range, bool negated) + LocaltimeCondition::LocaltimeCondition(const std::string& time_range, bool negated) : RuleConditionBase("localtime", time_range, negated) { - String time_begin; - String time_end; + std::string time_begin; + std::string time_end; const size_t dash_pos = time_range.find('-'); if (dash_pos == std::string::npos) { @@ -106,7 +112,7 @@ namespace usbguard return tm_string; } - std::time_t LocaltimeCondition::stringToDaytime(const String& string) + std::time_t LocaltimeCondition::stringToDaytime(const std::string& string) { USBGUARD_LOG(Trace) << "string=" << string; struct ::tm tm = { }; diff --git a/src/Library/LocaltimeCondition.hpp b/src/Library/LocaltimeCondition.hpp index c7672c6..8ff5663 100644 --- a/src/Library/LocaltimeCondition.hpp +++ b/src/Library/LocaltimeCondition.hpp @@ -17,24 +17,31 @@ // Authors: Daniel Kopecek // #pragma once -#include "Typedefs.hpp" -#include "RuleCondition.hpp" -#include "Rule.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/RuleCondition.hpp" + +#include "usbguard/Typedefs.hpp" +#include "usbguard/Rule.hpp" + #include +#include namespace usbguard { class LocaltimeCondition : public RuleConditionBase { public: - LocaltimeCondition(const String& time_range, bool negated = false); + LocaltimeCondition(const std::string& time_range, bool negated = false); LocaltimeCondition(const LocaltimeCondition& rhs); bool update(const Rule& rule); RuleConditionBase * clone() const; protected: - static std::time_t stringToDaytime(const String& string); - static String tmToString(const struct ::tm * const tm); + static std::time_t stringToDaytime(const std::string& string); + static std::string tmToString(const struct ::tm * const tm); private: std::time_t _daytime_begin; diff --git a/src/Library/Logger.cpp b/src/Library/Logger.cpp deleted file mode 100644 index a2c4d7a..0000000 --- a/src/Library/Logger.cpp +++ /dev/null @@ -1,407 +0,0 @@ -// -// Copyright (C) 2016 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// - -#include "Logger.hpp" -#include "Exception.hpp" -#include "Common/Utility.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif -#include - -namespace usbguard -{ - /* Instantiate the logger */ - Logger G_logger; - - const std::string LogStream::sourceToString(const Source& source) - { - return source.file + "@" + std::to_string(source.line) + "/" + source.function; - } - - const std::string LogStream::levelToString(Level level) - { - switch (level) { - case LogStream::Level::Audit: - return "(A)"; - case LogStream::Level::Error: - return "(E)"; - case LogStream::Level::Warning: - return "(W)"; - case LogStream::Level::Info: - return "(i)"; - case LogStream::Level::Debug: - return "(D)"; - case LogStream::Level::Trace: - return "(T)"; - default: - throw std::runtime_error("BUG: unknown LogStream level value"); - } - } - - LogStream::LogStream(Logger& logger, const Source& source, const Level level) - : _logger(logger), - _source(source), - _level(level) - { - } - - LogStream::LogStream(const LogStream& rhs) - : std::basic_ios(), - std::ostringstream(rhs.str()), - _logger(rhs._logger), - _source(rhs._source), - _level(rhs._level) - { - } - - LogStream::~LogStream() - { - _logger.write(_source, _level, str()); - } - - LogSink::LogSink(const std::string& name) - : _name(name) - { - } - - LogSink::~LogSink() - { - } - - const std::string& LogSink::name() const - { - return _name; - } - - /* - * Internally required sinks - */ - class OStreamSink : public LogSink - { - public: - OStreamSink(const std::string& name, std::ostream& stream) - : LogSink(name), - _ostream(stream) - { - } - - void write(const LogStream::Source& source, LogStream::Level level, const std::string& message) - { - _ostream << '[' << Logger::timestamp() << "] "; - _ostream << LogStream::levelToString(level) << " "; - if (level >= LogStream::Level::Debug) { - _ostream << LogStream::sourceToString(source) << ": "; - } - _ostream << message; - _ostream << std::endl; - } - - ~OStreamSink() - { - _ostream.flush(); - } - private: - std::ostream& _ostream; - }; - - class ConsoleSink : public OStreamSink - { - public: - ConsoleSink() - : OStreamSink("console", std::clog) - { - } - }; - - class SyslogSink : public LogSink - { - public: - SyslogSink(const std::string& ident) - : LogSink("syslog"), - _ident(ident) - { - openlog(_ident.c_str(), LOG_NDELAY|LOG_PID|LOG_CONS, LOG_DAEMON); - } - - ~SyslogSink() - { - closelog(); - } - - int levelToPriority(const LogStream::Level level) - { - switch (level) { - case LogStream::Level::Audit: - return LOG_NOTICE; - case LogStream::Level::Error: - return LOG_ERR; - case LogStream::Level::Warning: - return LOG_WARNING; - case LogStream::Level::Info: - return LOG_INFO; - case LogStream::Level::Debug: - case LogStream::Level::Trace: - return LOG_DEBUG; - default: - throw USBGUARD_BUG("Invalid LogStream::Level value"); - } - } - - void write(const LogStream::Source& source, LogStream::Level level, const std::string& message) - { - std::string log_message; - - if (level >= LogStream::Level::Debug) { - log_message.append(LogStream::sourceToString(source)); - log_message.append(": "); - } - log_message.append(message); - - syslog(levelToPriority(level), "%s", log_message.c_str()); - } - - private: - std::string _ident; - }; - - class FileSink : public OStreamSink - { - public: - FileSink(const std::string& filepath, bool append = true) - : OStreamSink("file", _stream) - { - _filepath = filepath; - _stream.open(filepath, append ? std::fstream::app : std::fstream::trunc); - } - - ~FileSink() - { - _stream.close(); - } - private: - std::string _filepath; - std::ofstream _stream; - }; - - class AuditFileSink : public OStreamSink - { - public: - AuditFileSink(const std::string& filepath) - : OStreamSink("auditfile", _stream) - { - _filepath = filepath; - const auto saved_umask = umask(0177); - try { - _stream.open(filepath, std::fstream::app); - } - catch(...) { - umask(saved_umask); - throw; - } - umask(saved_umask); - } - - void write(const LogStream::Source& source, LogStream::Level level, const std::string& message) - { - /* - * AuditFileSink logs only Audit level messages. - */ - if (level == LogStream::Level::Audit) { - OStreamSink::write(source, level, message); - } - } - - ~AuditFileSink() - { - _stream.close(); - } - private: - std::string _filepath; - std::ofstream _stream; - }; - - Logger::Logger() - : _enabled(true), - _level(LogStream::Level::Warning) - { - const char * const envval = getenv("USBGUARD_DEBUG"); - /* - * If USBGUARD_DEBUG=1 is set in the current environment, - * set the debugging level to the highest level. - */ - if (envval != nullptr && strcmp(envval, "1") == 0) { - _level = LogStream::Level::Trace; - } - setOutputConsole(true); - } - - Logger::~Logger() - { - } - - std::unique_lock Logger::lock() const - { - return std::unique_lock(_mutex); - } - - void Logger::setEnabled(bool state, LogStream::Level level) - { - auto L = lock(); - _enabled = state; - _level = level; - } - - bool Logger::isEnabled(LogStream::Level level) const - { - auto L = lock(); - return (_enabled && _level >= level); - } - - void Logger::setOutputConsole(const bool state) - { - auto L = lock(); - if (state == true) { - std::unique_ptr sink(new ConsoleSink); - addOutputSink_nolock(sink); - } - else { - delOutputSink_nolock("console"); - } - } - - void Logger::setOutputFile(bool state, const std::string& filepath, bool append) - { - auto L = lock(); - if (state == true) { - std::unique_ptr sink(new FileSink(filepath, append)); - addOutputSink_nolock(sink); - } - else { - delOutputSink_nolock("file"); - } - } - - void Logger::setOutputSyslog(bool state, const std::string& ident) - { - auto L = lock(); - if (state == true) { - std::unique_ptr sink(new SyslogSink(ident)); - addOutputSink_nolock(sink); - } - else { - delOutputSink_nolock("syslog"); - } - } - - void Logger::setAuditFile(bool state, const std::string& filepath) - { - auto L = lock(); - if (state == true) { - std::unique_ptr sink(new AuditFileSink(filepath)); - addOutputSink_nolock(sink); - } - else { - delOutputSink_nolock("auditfile"); - } - } - - void Logger::addOutputSink(std::unique_ptr& sink) - { - auto L = lock(); - addOutputSink_nolock(sink); - } - - void Logger::addOutputSink_nolock(std::unique_ptr& sink) - { - _sinks.emplace(sink->name(), std::move(sink)); - } - - void Logger::delOutputSink(const std::string& name) - { - auto L = lock(); - delOutputSink_nolock(name); - } - - void Logger::delOutputSink_nolock(const std::string& name) - { - _sinks.erase(name); - } - - LogStream Logger::operator()(const std::string& file, const int line, const std::string& function, LogStream::Level level) - { - const LogStream::Source source = { - filenameFromPath(file, /*include_extension=*/true), line, function - }; - return LogStream(*this, source, level); - } - - void Logger::write(const LogStream::Source& source, const LogStream::Level level, const std::string& message) - { - auto L = lock(); - for (auto& kv_pair : _sinks) { - auto& sink = kv_pair.second; - try { - sink->write(source, level, message); - } - catch(const std::exception& ex) { - std::cerr << "Warning: sink->write failed for " << sink->name() << " sink: " << ex.what() << std::endl; - } - } - } - - /* - * Generate a timestamp string in the form: - * . - */ - const std::string Logger::timestamp() - { - struct timeval tv_now = { 0, 0 }; - - if (gettimeofday(&tv_now, nullptr) != 0) { - throw std::runtime_error("gettimeofday"); - } - - /* - * The following piece of code should work fine until - * Sat Nov 20 17:46:39 UTC 2286. - */ - char buffer[16]; - const int length = snprintf(buffer, sizeof buffer, "%.10" PRIu64 ".%03" PRIu64, - (uint64_t)tv_now.tv_sec, - (uint64_t)(tv_now.tv_usec / 1000)); - - if (length < 1 || static_cast(length) > (sizeof buffer - 1)) { - throw std::runtime_error("Failed to convert timestamp to string"); - } - - return std::string(buffer, (size_t)length); - } -} /* namespace usbguard */ - diff --git a/src/Library/Logger.hpp b/src/Library/Logger.hpp deleted file mode 100644 index a6abaad..0000000 --- a/src/Library/Logger.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// Copyright (C) 2016 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include "Typedefs.hpp" - -#include -#include -#include -#include -#include - -namespace usbguard -{ - class Logger; - - class DLL_PUBLIC LogStream : public std::ostringstream - { - public: - struct Source { - std::string file; - int line; - std::string function; - }; - - static const std::string sourceToString(const Source& source); - - enum class Level : int { - Audit = -2, - Error = -1, - Warning = 0, - Info = 1, - Debug = 2, - Trace = 3 - }; - - static const std::string levelToString(Level level); - - LogStream(Logger& logger, const Source& source, Level level); - LogStream(const LogStream& rhs); - - ~LogStream(); - - private: - Logger& _logger; - Source _source; - Level _level; - }; - - class DLL_PUBLIC LogSink - { - public: - LogSink(const std::string& name); - virtual ~LogSink(); - - const std::string& name() const; - - virtual void write(const LogStream::Source& source, LogStream::Level level, const std::string& message) = 0; - - private: - std::string _name; - }; - - class DLL_PUBLIC Logger - { - public: - Logger(); - ~Logger(); - - void setEnabled(bool state, LogStream::Level level = LogStream::Level::Warning); - bool isEnabled(LogStream::Level level) const; - - void setOutputConsole(bool state); - void setOutputFile(bool state, const std::string& filepath = std::string(), bool append = true); - void setOutputSyslog(bool state, const std::string& ident = std::string()); - void setAuditFile(bool state, const std::string& filepath); - - void addOutputSink(std::unique_ptr& sink); - void delOutputSink(const std::string& name); - - LogStream operator()(const std::string& file, int line, const std::string& function, LogStream::Level level); - - void write(const LogStream::Source& source, LogStream::Level level, const std::string& message); - - /* - * Generate a timestamp string in the form: - * . - */ - static const std::string timestamp(); - - private: - void addOutputSink_nolock(std::unique_ptr& sink); - void delOutputSink_nolock(const std::string& name); - - std::unique_lock lock() const; - - mutable std::mutex _mutex; - bool _enabled; - LogStream::Level _level; - std::map> _sinks; - }; - - extern DLL_PUBLIC Logger G_logger; - -#if defined(__GNUC__) -# define USBGUARD_SOURCE_FILE __BASE_FILE__ -#else -# define USBGUARD_SOURCE_FILE __FILE__ -#endif - -#define USBGUARD_LOGGER usbguard::G_logger - -#define USBGUARD_FUNCTION __func__ - -#define USBGUARD_LOG(level) \ - if (USBGUARD_LOGGER.isEnabled(usbguard::LogStream::Level::level)) \ - USBGUARD_LOGGER(USBGUARD_SOURCE_FILE, __LINE__, USBGUARD_FUNCTION, usbguard::LogStream::Level::level) - -} /* namespace usbguard */ diff --git a/src/Library/Policy.cpp b/src/Library/Policy.cpp deleted file mode 100644 index fd30d40..0000000 --- a/src/Library/Policy.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// Copyright (C) 2017 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include "Policy.hpp" -#include "Exception.hpp" - -namespace usbguard -{ - std::string Policy::eventTypeToString(Policy::EventType event) - { - switch(event) { - case Policy::EventType::Insert: - return "Insert"; - case Policy::EventType::Update: - return "Update"; - case Policy::EventType::Remove: - return "Remove"; - default: - throw USBGUARD_BUG("unknown Policy::EventType value"); - } - } -} /* namespace usbguard */ diff --git a/src/Library/Policy.hpp b/src/Library/Policy.hpp deleted file mode 100644 index f670e4b..0000000 --- a/src/Library/Policy.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (C) 2017 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include -#include - -namespace usbguard -{ - class DLL_PUBLIC Policy - { - public: - enum class EventType - { - Insert = 1, - Update = 2, - Remove = 3, - }; - - static std::string eventTypeToString(EventType event); - }; -} /* namespace usbguard */ diff --git a/src/Library/Predicates.hpp b/src/Library/Predicates.hpp deleted file mode 100644 index 21c54a2..0000000 --- a/src/Library/Predicates.hpp +++ /dev/null @@ -1,38 +0,0 @@ -// -// Copyright (C) 2016 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once -#include "Typedefs.hpp" -#include - -namespace usbguard -{ - namespace Predicates DLL_PUBLIC - { - /* - * Return true if the source set is a subset of the - * target set. Otherwise return false. - */ - template - bool isSubsetOf(const T& source, const T& target) - { - USBGUARD_LOG(Trace) << "generic isSubsetOf"; - return source == target; - } - } -} /* namespace usbguard */ diff --git a/src/Library/RandomStateCondition.cpp b/src/Library/RandomStateCondition.cpp index 4ebf12c..57bf4e5 100644 --- a/src/Library/RandomStateCondition.cpp +++ b/src/Library/RandomStateCondition.cpp @@ -16,13 +16,19 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "RandomStateCondition.hpp" -#include "RuleParser.hpp" + +#include "usbguard/RuleParser.hpp" + #include namespace usbguard { - RandomStateCondition::RandomStateCondition(const String& true_probability, bool negated) + RandomStateCondition::RandomStateCondition(const std::string& true_probability, bool negated) : RuleConditionBase("random", true_probability, negated), _rng_gen(_rng_device()), _true_probability(true_probability.empty() ? 0.5 : std::stod(true_probability)), diff --git a/src/Library/RandomStateCondition.hpp b/src/Library/RandomStateCondition.hpp index a26d68a..ce9910a 100644 --- a/src/Library/RandomStateCondition.hpp +++ b/src/Library/RandomStateCondition.hpp @@ -17,9 +17,15 @@ // Authors: Daniel Kopecek // #pragma once -#include "Typedefs.hpp" -#include "RuleCondition.hpp" -#include "Rule.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Typedefs.hpp" +#include "usbguard/Rule.hpp" + +#include "usbguard/RuleCondition.hpp" + #include namespace usbguard @@ -27,7 +33,7 @@ namespace usbguard class RandomStateCondition : public RuleConditionBase { public: - RandomStateCondition(const String& true_probability, bool negated = false); + RandomStateCondition(const std::string& true_probability, bool negated = false); RandomStateCondition(const RandomStateCondition& rhs); bool update(const Rule& rule); RuleConditionBase * clone() const; diff --git a/src/Library/Rule.cpp b/src/Library/Rule.cpp deleted file mode 100644 index 18ecb03..0000000 --- a/src/Library/Rule.cpp +++ /dev/null @@ -1,356 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include "RulePrivate.hpp" -#include "Common/Utility.hpp" - -namespace usbguard { - template<> - String toRuleString(const String& value) - { - return Utility::quoteEscapeString(value); - } - - const uint32_t Rule::RootID = std::numeric_limits::min(); - const uint32_t Rule::DefaultID = std::numeric_limits::max(); - const uint32_t Rule::LastID = std::numeric_limits::max() - 2; - const uint32_t Rule::ImplicitID = std::numeric_limits::max() - 1; - - Rule::Rule() - { - d_pointer = new RulePrivate(*this); - } - - Rule::~Rule() - { - delete d_pointer; - d_pointer = nullptr; - } - - Rule::Rule(const Rule& rhs) - { - d_pointer = new RulePrivate(*this, *rhs.d_pointer); - } - - const Rule& Rule::operator=(const Rule& rhs) - { - RulePrivate* n_pointer = new RulePrivate(*this, *rhs.d_pointer); - delete d_pointer; - d_pointer = n_pointer; - return *this; - } - - void Rule::setRuleID(uint32_t rule_id) - { - d_pointer->setRuleID(rule_id); - } - - uint32_t Rule::getRuleID() const - { - return d_pointer->getRuleID(); - } - - void Rule::setTarget(Rule::Target target) - { - d_pointer->setTarget(target); - } - - Rule::Target Rule::getTarget() const - { - return d_pointer->getTarget(); - } - - void Rule::setDeviceID(const USBDeviceID& value) - { - d_pointer->setDeviceID(value); - } - - const USBDeviceID& Rule::getDeviceID() const - { - return d_pointer->getDeviceID(); - } - - const Rule::Attribute& Rule::attributeDeviceID() const - { - return d_pointer->attributeDeviceID(); - } - - Rule::Attribute& Rule::attributeDeviceID() - { - return d_pointer->attributeDeviceID(); - } - - void Rule::setSerial(const String& value) - { - d_pointer->setSerial(value); - } - - const String& Rule::getSerial() const - { - return d_pointer->getSerial(); - } - - const Rule::Attribute& Rule::attributeSerial() const - { - return d_pointer->attributeSerial(); - } - - Rule::Attribute& Rule::attributeSerial() - { - return d_pointer->attributeSerial(); - } - - void Rule::setName(const String& value) - { - d_pointer->setName(value); - } - - const String& Rule::getName() const - { - return d_pointer->getName(); - } - - const Rule::Attribute& Rule::attributeName() const - { - return d_pointer->attributeName(); - } - - Rule::Attribute& Rule::attributeName() - { - return d_pointer->attributeName(); - } - - void Rule::setHash(const String& value) - { - d_pointer->setHash(value); - } - - const String& Rule::getHash() const - { - return d_pointer->getHash(); - } - - const Rule::Attribute& Rule::attributeHash() const - { - return d_pointer->attributeHash(); - } - - Rule::Attribute& Rule::attributeHash() - { - return d_pointer->attributeHash(); - } - - void Rule::setParentHash(const String& value) - { - d_pointer->setParentHash(value); - } - - const String& Rule::getParentHash() const - { - return d_pointer->getParentHash(); - } - - const Rule::Attribute& Rule::attributeParentHash() const - { - return d_pointer->attributeParentHash(); - } - - Rule::Attribute& Rule::attributeParentHash() - { - return d_pointer->attributeParentHash(); - } - - void Rule::setViaPort(const String& value) - { - d_pointer->setViaPort(value); - } - - const String& Rule::getViaPort() const - { - return d_pointer->getViaPort(); - } - - const Rule::Attribute& Rule::attributeViaPort() const - { - return d_pointer->attributeViaPort(); - } - - Rule::Attribute& Rule::attributeViaPort() - { - return d_pointer->attributeViaPort(); - } - - const Rule::Attribute& Rule::attributeWithInterface() const - { - return d_pointer->attributeWithInterface(); - } - - Rule::Attribute& Rule::attributeWithInterface() - { - return d_pointer->attributeWithInterface(); - } - - const Rule::Attribute& Rule::attributeConditions() const - { - return d_pointer->attributeConditions(); - } - - Rule::Attribute& Rule::attributeConditions() - { - return d_pointer->attributeConditions(); - } - - void Rule::setTimeoutSeconds(uint32_t timeout_seconds) - { - d_pointer->setTimeoutSeconds(timeout_seconds); - } - - uint32_t Rule::getTimeoutSeconds() const - { - return d_pointer->getTimeoutSeconds(); - } - - bool Rule::appliesTo(Pointer rhs) const - { - return appliesTo(*rhs); - } - - bool Rule::appliesTo(const Rule& rhs) const - { - return d_pointer->appliesTo(rhs); - } - - bool Rule::appliesTo(const Rule& rhs) - { - updateMetaDataCounters(/*applied=*/false, /*evaluated=*/true); - return d_pointer->appliesTo(rhs); - } - - bool Rule::isImplicit() const - { - return d_pointer->getRuleID() == Rule::DefaultID; - } - - Rule::operator bool() const - { - return !(getTarget() == Target::Unknown || - getTarget() == Target::Invalid); - } - - String Rule::toString(bool invalid) const - { - return d_pointer->toString(invalid); - } - - void Rule::updateMetaDataCounters(bool applied, bool evaluated) - { - d_pointer->updateMetaDataCounters(applied, evaluated); - } - - Rule Rule::fromString(const String& rule_string) - { - return RulePrivate::fromString(rule_string); - } - - RulePrivate* Rule::internal() - { - return d_pointer; - } - - const RulePrivate* Rule::internal() const - { - return d_pointer; - } - - static const std::vector > target_ttable = { - { "allow", Rule::Target::Allow }, - { "block", Rule::Target::Block }, - { "reject", Rule::Target::Reject }, - { "match", Rule::Target::Match }, - { "device", Rule::Target::Device } - }; - - const String Rule::targetToString(const Rule::Target target) - { - for (auto ttable_entry : target_ttable) { - if (ttable_entry.second == target) { - return ttable_entry.first; - } - } - throw std::runtime_error("Invalid rule target string"); - } - - Rule::Target Rule::targetFromString(const String& target_string) - { - for (auto ttable_entry : target_ttable) { - if (ttable_entry.first == target_string) { - return ttable_entry.second; - } - } - throw std::runtime_error("Invalid rule target string"); - } - - uint32_t Rule::targetToInteger(const Rule::Target target) - { - return static_cast(target); - } - - Rule::Target Rule::targetFromInteger(const uint32_t target_integer) - { - switch(target_integer) { - case static_cast(Rule::Target::Allow): - case static_cast(Rule::Target::Block): - case static_cast(Rule::Target::Reject): - case static_cast(Rule::Target::Match): - case static_cast(Rule::Target::Device): - break; - default: - throw std::runtime_error("Invalid rule target integer value"); - } - return static_cast(target_integer); - } - - static const std::vector > set_operator_ttable = { - { "all-of", Rule::SetOperator::AllOf }, - { "one-of", Rule::SetOperator::OneOf }, - { "none-of", Rule::SetOperator::NoneOf }, - { "equals", Rule::SetOperator::Equals }, - { "equals-ordered", Rule::SetOperator::EqualsOrdered }, - { "match", Rule::SetOperator::Match } - }; - - const String Rule::setOperatorToString(const Rule::SetOperator& op) - { - for (auto ttable_entry : set_operator_ttable) { - if (ttable_entry.second == op) { - return ttable_entry.first; - } - } - throw std::runtime_error("Invalid set operator string"); - } - - Rule::SetOperator Rule::setOperatorFromString(const String& set_operator_string) - { - for (auto ttable_entry : set_operator_ttable) { - if (ttable_entry.first == set_operator_string) { - return ttable_entry.second; - } - } - throw std::runtime_error("Invalid set operator string"); - } -} /* namespace usbguard */ diff --git a/src/Library/Rule.hpp b/src/Library/Rule.hpp deleted file mode 100644 index 37dad59..0000000 --- a/src/Library/Rule.hpp +++ /dev/null @@ -1,480 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include "Typedefs.hpp" -#include "USB.hpp" -#include "Predicates.hpp" -#include "Utility.hpp" -#include "RuleCondition.hpp" -#include "Logger.hpp" -#include "Exception.hpp" - -#include -#include - -namespace usbguard { - template - String toRuleString(T* const value) - { - return value->toRuleString(); - } - - template - String toRuleString(const T& value) - { - return value.toRuleString(); - } - - template<> - String DLL_PUBLIC toRuleString(const String& value); - - class RulePrivate; - class DLL_PUBLIC Rule - { - public: - /** - * Rule target enumeration. - */ - enum class Target { - Allow = 0, /**< Devices matching this rule will be authorized */ - Block = 1, /**< Devices matching this rule will not be authorized */ - Reject = 2, /**< Devices matching this rule will not be authorized and will be detached */ - Match = 3, /**< Special target which can be used to trigger actions. The rule wont affect the final decision. */ - Unknown = 4, /**< Unknown target. Used for default constructed rules. */ - Device = 5, /**< Special target which can only be used for a rule that represents a single device */ - Invalid = 6 - }; - - static const String targetToString(Target target); - static Target targetFromString(const String& target_string); - - static uint32_t targetToInteger(Target target); - static Target targetFromInteger(uint32_t target_integer); - - enum class SetOperator - { - AllOf, - OneOf, - NoneOf, - Equals, - EqualsOrdered, - Match /* Special operator: matches anything, cannot be used directly in a rule */ - }; - - static const String setOperatorToString(const Rule::SetOperator& op); - static SetOperator setOperatorFromString(const String& set_operator_string); - - /**< Sequence number of the (fake) root rule */ - static const uint32_t RootID; - /**< Sequence number assigned to default constructed rules. Cannot be used for searching. */ - static const uint32_t DefaultID; - /**< Sequence number for specifying that the last rule in the ruleset should be used in context of the operation */ - static const uint32_t LastID; - /**< Sequence number of the implicit target rule */ - static const uint32_t ImplicitID; - - template - class Attribute - { - public: - Attribute(const char * name) - { - _name = name; - _set_operator = SetOperator::Equals; - } - - Attribute(const Attribute& rhs) - { - _name = rhs._name; - _set_operator = rhs._set_operator; - _values = rhs._values; - } - - void setSetOperator(SetOperator op) - { - _set_operator = op; - } - - SetOperator setOperator() const - { - return _set_operator; - } - - void append(ValueType&& value) - { - _values.emplace_back(std::move(value)); - } - - void append(const ValueType& value) - { - _values.push_back(value); - } - - size_t count() const - { - return _values.size(); - } - - bool empty() const - { - return count() == 0; - } - - void clear() - { - _values.clear(); - _set_operator = SetOperator::Equals; - } - - const ValueType& get() const - { - if (count() == 1) { - return _values[0]; - } - else if (count() == 0) { - throw std::runtime_error("BUG: Accessing an empty attribute"); - } - else { - throw std::runtime_error("BUG: Accessing a multivalued attribute using get()"); - } - } - - const ValueType& get(size_t index) const - { - return _values.at(index); - } - - void set(ValueType&& value) - { - if (count() > 1) { - throw std::runtime_error("BUG: Setting single value for a multivalued attribute"); - } - if (count() == 0) { - append(value); - } - else { - _values[0] = std::move(value); - } - } - - void set(const ValueType& value) - { - if (count() > 1) { - throw std::runtime_error("BUG: Setting single value for a multivalued attribute"); - } - if (count() == 0) { - append(value); - } - else { - _values[0] = value; - } - } - - void set(const std::vector& values, SetOperator op) - { - _values = values; - _set_operator = op; - } - - bool appliesTo(const Attribute& target) const - { - USBGUARD_LOG(Trace) << "entry:" - << " source=" << this->toRuleString() - << " target=" << target.toRuleString(); - - bool applies = false; - - /* Nothing applies to anything */ - if (empty()) { - USBGUARD_LOG(Debug) << "empty source value, setting applies=true"; - applies = true; - } - else { - USBGUARD_LOG(Debug) << "set_operator=" << setOperatorToString(setOperator()); - switch(setOperator()) { - case SetOperator::Match: - applies = true; - break; - case SetOperator::AllOf: - applies = setSolveAllOf(_values, target._values); - break; - case SetOperator::OneOf: - applies = setSolveOneOf(_values, target._values); - break; - case SetOperator::NoneOf: - applies = setSolveNoneOf(_values, target._values); - break; - case SetOperator::Equals: - applies = setSolveEquals(_values, target._values); - break; - case SetOperator::EqualsOrdered: - applies = setSolveEqualsOrdered(_values, target._values); - break; - default: - throw USBGUARD_BUG("Invalid set operator value"); - } - } - - USBGUARD_LOG(Trace) << "return:" - << " applies=" << applies; - - return applies; - } - - String toRuleString() const - { - String result; - - result.append(_name); - result.append(" "); - - const bool nondefault_op = setOperator() != SetOperator::Equals; - const bool multiset_form = count() > 1 || nondefault_op; - - if (multiset_form) { - if (nondefault_op) { - result.append(setOperatorToString(setOperator())); - result.append(" "); - } - result.append("{ "); - } - - for(const auto& value : _values) { - result.append(usbguard::toRuleString(value)); - result.append(" "); - } - - if (multiset_form) { - result.append("}"); - } - else { - /* - * Remove the trailing space in case of a single - * valued attribute. - */ - result.erase(result.end() - 1); - } - - return result; - } - - const std::vector& values() const - { - return _values; - } - - std::vector& values() - { - return _values; - } - - private: - /* - * All of the items in source set must match an item in the target set - */ - bool setSolveAllOf(const std::vector& source_set, const std::vector& target_set) const - { - USBGUARD_LOG(Trace); - - for (auto const& source_item : source_set) { - bool match = false; - for (auto const& target_item : target_set) { - if (Predicates::isSubsetOf(source_item, target_item)) { - match = true; - break; - } - } - if (!match) { - return false; - } - } - return true; - } - - /* - * At least one of the items in the source set must match an item in the target set - */ - bool setSolveOneOf(const std::vector& source_set, const std::vector& target_set) const - { - USBGUARD_LOG(Trace); - - for (auto const& source_item : source_set) { - for (auto const& target_item : target_set) { - if (Predicates::isSubsetOf(source_item, target_item)) { - return true; - } - } - } - return false; - } - - /* - * None of the the items in the rule set must match any item in the - * applies_to set - */ - bool setSolveNoneOf(const std::vector& source_set, const std::vector& target_set) const - { - USBGUARD_LOG(Trace); - - for (auto const& source_item : source_set) { - for (auto const& target_item : target_set) { - if (Predicates::isSubsetOf(source_item, target_item)) { - return false; - } - } - } - return true; - } - - /* - * Every item in the rule set must match one item in the - * applies_to set and the sets have to have the same number - * of items - */ - bool setSolveEquals(const std::vector& source_set, const std::vector& target_set) const - { - USBGUARD_LOG(Trace); - - if (source_set.size() != target_set.size()) { - return false; - } - else { - for (auto const& source_item : source_set) { - bool match = false; - for (auto const& target_item : target_set) { - if (Predicates::isSubsetOf(source_item, target_item)) { - match = true; - break; - } - } - if (!match) { - return false; - } - } - return true; - } - } - - /* - * The sets are treated as arrays and they have to me equal - * (same number of items at the same positions) - */ - bool setSolveEqualsOrdered(const std::vector& source_set, const std::vector& target_set) const - { - USBGUARD_LOG(Trace); - - if (source_set.size() != target_set.size()) { - return false; - } - for (size_t i = 0; i < source_set.size(); ++i) { - if (!Predicates::isSubsetOf(source_set[i], target_set[i])) { - return false; - } - } - return false; - } - - String _name; - SetOperator _set_operator; - std::vector _values; - }; - - /** - * Construct a default rule. - * This rule matches only a default rule and cannot be converted to a string - * representation. - */ - Rule(); - ~Rule(); - Rule(const Rule& rhs); - const Rule& operator=(const Rule& rhs); - - void setRuleID(uint32_t rule_id); - uint32_t getRuleID() const; - - void setTarget(Rule::Target target); - Target getTarget() const; - - void setDeviceID(const USBDeviceID& value); - const USBDeviceID& getDeviceID() const; - const Attribute& attributeDeviceID() const; - Attribute& attributeDeviceID(); - - void setSerial(const String& value); - const String& getSerial() const; - const Attribute& attributeSerial() const; - Attribute& attributeSerial(); - - void setName(const String& value); - const String& getName() const; - const Attribute& attributeName() const; - Attribute& attributeName(); - - void setHash(const String& value); - const String& getHash() const; - const Attribute& attributeHash() const; - Attribute& attributeHash(); - - void setParentHash(const String& value); - const String& getParentHash() const; - const Rule::Attribute& attributeParentHash() const; - Rule::Attribute& attributeParentHash(); - - void setViaPort(const String& value); - const String& getViaPort() const; - const Attribute& attributeViaPort() const; - Attribute& attributeViaPort(); - - /* - * Set/get for a single value isn't useful for the - * with-interface attribute as it usualy contains - * multiple values. Therefore, we provide only the - * attribute accessors in this case. - */ - const Attribute& attributeWithInterface() const; - Attribute& attributeWithInterface(); - - const Attribute& attributeConditions() const; - Attribute& attributeConditions(); - - void setTimeoutSeconds(uint32_t timeout_seconds); - uint32_t getTimeoutSeconds() const; - - bool appliesTo(Pointer rhs) const; - bool appliesTo(const Rule& rhs) const; - bool appliesTo(const Rule& rhs); - bool isImplicit() const; - - - operator bool() const; - String toString(bool invalid = false) const; - - void updateMetaDataCounters(bool applied = true, bool evaluated = false); - - RulePrivate* internal(); - const RulePrivate* internal() const; - - /*** Static methods ***/ - static Rule fromString(const String& rule_string); - - private: - RulePrivate* d_pointer; - }; -} /* namespace usbguard */ diff --git a/src/Library/RuleAppliedCondition.cpp b/src/Library/RuleAppliedCondition.cpp index e3bf95f..cb62316 100644 --- a/src/Library/RuleAppliedCondition.cpp +++ b/src/Library/RuleAppliedCondition.cpp @@ -16,9 +16,15 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "RuleAppliedCondition.hpp" -#include "RuleParser.hpp" #include "RulePrivate.hpp" + +#include "usbguard/RuleParser.hpp" + #include #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE @@ -27,7 +33,7 @@ namespace usbguard { - RuleAppliedCondition::RuleAppliedCondition(const String& elapsed_time, bool negated) + RuleAppliedCondition::RuleAppliedCondition(const std::string& elapsed_time, bool negated) : RuleConditionBase("rule-applied", elapsed_time, negated) { _elapsed_time = std::chrono::steady_clock::duration(stringToSeconds(elapsed_time)); @@ -62,7 +68,7 @@ namespace usbguard return new RuleAppliedCondition(*this); } - uint64_t RuleAppliedCondition::stringToSeconds(const String& string) + uint64_t RuleAppliedCondition::stringToSeconds(const std::string& string) { struct ::tm tm = { }; diff --git a/src/Library/RuleAppliedCondition.hpp b/src/Library/RuleAppliedCondition.hpp index d8ab450..46dff42 100644 --- a/src/Library/RuleAppliedCondition.hpp +++ b/src/Library/RuleAppliedCondition.hpp @@ -17,9 +17,15 @@ // Authors: Daniel Kopecek // #pragma once -#include "Typedefs.hpp" -#include "RuleCondition.hpp" -#include "Rule.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/RuleCondition.hpp" + +#include "usbguard/Typedefs.hpp" +#include "usbguard/Rule.hpp" + #include namespace usbguard @@ -27,12 +33,12 @@ namespace usbguard class RuleAppliedCondition : public RuleConditionBase { public: - RuleAppliedCondition(const String& elapsed_time, bool negated = false); + RuleAppliedCondition(const std::string& elapsed_time, bool negated = false); RuleAppliedCondition(const RuleAppliedCondition& rhs); bool update(const Rule& rule); RuleConditionBase * clone() const; protected: - static uint64_t stringToSeconds(const String& string); + static uint64_t stringToSeconds(const std::string& string); private: std::chrono::steady_clock::duration _elapsed_time; }; diff --git a/src/Library/RuleCondition.cpp b/src/Library/RuleCondition.cpp deleted file mode 100644 index 79084e8..0000000 --- a/src/Library/RuleCondition.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// -// Copyright (C) 2016 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include "RuleCondition.hpp" -#include "Rule.hpp" -#include "Logger.hpp" - -#include -#include - -namespace usbguard -{ - RuleConditionBase::RuleConditionBase(const String& identifier, const String& parameter, bool negated) - : _identifier(identifier), - _parameter(parameter), - _negated(negated) - { - } - - RuleConditionBase::RuleConditionBase(const String& identifier, bool negated) - : _identifier(identifier), - _negated(negated) - { - } - - RuleConditionBase::RuleConditionBase(const RuleConditionBase& rhs) - : _identifier(rhs._identifier), - _parameter(rhs._parameter), - _negated(rhs._negated) - { - } - - RuleConditionBase::~RuleConditionBase() - { - fini(); - } - - void RuleConditionBase::init(Interface * const interface_ptr) - { - (void)interface_ptr; - } - - void RuleConditionBase::fini() - { - } - - bool RuleConditionBase::evaluate(const Rule& rule) - { - return isNegated() ? !update(rule) : update(rule); - } - - const String& RuleConditionBase::identifier() const - { - return _identifier; - } - - const String& RuleConditionBase::parameter() const - { - return _parameter; - } - - bool RuleConditionBase::hasParameter() const - { - return !_parameter.empty(); - } - - bool RuleConditionBase::isNegated() const - { - return _negated; - } - - const String RuleConditionBase::toString() const - { - String condition_string; - - if (isNegated()) { - condition_string.append("!"); - } - - condition_string.append(identifier()); - - if (hasParameter()) { - condition_string.append("("); - condition_string.append(parameter()); /* TODO: Escape parameter string */ - condition_string.append(")"); - } - - return condition_string; - } - - const String RuleConditionBase::toRuleString() const - { - return toString(); - } -} /* namespace usbguard */ - -#include "AllowedMatchesCondition.hpp" -#include "LocaltimeCondition.hpp" -#include "FixedStateCondition.hpp" -#include "RandomStateCondition.hpp" -#include "RuleAppliedCondition.hpp" -#include "RuleEvaluatedCondition.hpp" - -#include -#include - -namespace usbguard -{ - RuleConditionBase* RuleConditionBase::getImplementation(const String& condition_string) - { - if (condition_string.empty()) { - throw std::runtime_error("Empty condition"); - } - - const bool negated = condition_string[0] == '!'; - const size_t identifier_start = negated ? 1 : 0; - const size_t p_pos = condition_string.find_first_of('('); - - String identifier; - String parameter; - - if (p_pos == std::string::npos) { - /* - * The rest of the condition_string should be - * a condition identifier -- without a parameter. - */ - identifier = condition_string.substr(identifier_start); - - if (identifier.size() < 1) { - throw std::runtime_error("Invalid condition string. Missing identifier."); - } - } - else { - const size_t parameter_size = condition_string.size() - p_pos; - - if (parameter_size < 3 /* two parentheses + at least one character */) { - throw std::runtime_error("Invalid condition string. Invalid parameter."); - } - - const size_t identifier_size = p_pos - identifier_start; - identifier = condition_string.substr(identifier_start, identifier_size); - - if (condition_string[condition_string.size() - 1] != ')') { - throw std::runtime_error("Invalid condition string. Malformed parameter."); - } - - parameter = condition_string.substr(p_pos + 1, parameter_size - 2); - } - - return getImplementation(identifier, parameter, negated); - } - - RuleConditionBase* RuleConditionBase::getImplementation(const String& identifier, const String& parameter, bool negated) - { - if (identifier == "allowed-matches") { - return new AllowedMatchesCondition(parameter, negated); - } - if (identifier == "localtime") { - return new LocaltimeCondition(parameter, negated); - } - if (identifier == "true") { - return new FixedStateCondition(true, negated); - } - if (identifier == "false") { - return new FixedStateCondition(false, negated); - } - if (identifier == "random") { - return new RandomStateCondition(parameter, negated); - } - if (identifier == "rule-applied") { - return new RuleAppliedCondition(parameter, negated); - } - if (identifier == "rule-evaluated") { - return new RuleEvaluatedCondition(parameter, negated); - } - throw std::runtime_error("Unknown rule condition"); - } - - RuleCondition::RuleCondition() - { - } - - RuleCondition::RuleCondition(const String& condition_string) - : _condition(RuleConditionBase::getImplementation(condition_string)) - { - } - - RuleCondition::RuleCondition(const RuleCondition& rhs) - : _condition(rhs._condition->clone()) - { - } - - RuleCondition::RuleCondition(RuleCondition&& rhs) - : _condition(std::move(rhs._condition)) - { - } - - RuleCondition& RuleCondition::operator=(const RuleCondition& rhs) - { - _condition.reset(rhs._condition->clone()); - return *this; - } - - RuleCondition& RuleCondition::operator=(RuleCondition&& rhs) - { - _condition = std::move(rhs._condition); - return *this; - } -} /* namespace usbguard */ - diff --git a/src/Library/RuleCondition.hpp b/src/Library/RuleCondition.hpp deleted file mode 100644 index aec979b..0000000 --- a/src/Library/RuleCondition.hpp +++ /dev/null @@ -1,87 +0,0 @@ -// -// Copyright (C) 2016 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include "Typedefs.hpp" - -namespace usbguard -{ - class Interface; - class Rule; - class RuleConditionBase - { - public: - RuleConditionBase(const String& identifier, const String& parameter, bool negated = false); - RuleConditionBase(const String& identifier, bool negated = false); - RuleConditionBase(const RuleConditionBase& rhs); - virtual ~RuleConditionBase(); - - virtual void init(Interface * const interface_ptr); - virtual void fini(); - virtual bool update(const Rule& rule) = 0; - virtual RuleConditionBase* clone() const = 0; - - bool evaluate(const Rule& rule); - const String& identifier() const; - const String& parameter() const; - bool hasParameter() const; - bool isNegated() const; - const String toString() const; - const String toRuleString() const; - - static RuleConditionBase* getImplementation(const String& condition_string); - static RuleConditionBase* getImplementation(const String& identifier, const String& parameter, bool negated); - - private: - const String _identifier; - const String _parameter; - const bool _negated; - }; - - class RuleCondition - { - public: - RuleCondition(); - RuleCondition(const String& condition_string); - RuleCondition(const RuleCondition& rhs); - RuleCondition(RuleCondition&& rhs); - - RuleCondition& operator=(const RuleCondition& rhs); - RuleCondition& operator=(RuleCondition&& rhs); - - RuleConditionBase* operator->() - { - return _condition.get(); - } - - RuleConditionBase& operator*() - { - return *_condition.get(); - } - - String toRuleString() const - { - return _condition->toRuleString(); - } - - private: - UniquePointer _condition; - }; -} /*namespace usbguard */ - diff --git a/src/Library/RuleEvaluatedCondition.cpp b/src/Library/RuleEvaluatedCondition.cpp index 68d93ed..81ea728 100644 --- a/src/Library/RuleEvaluatedCondition.cpp +++ b/src/Library/RuleEvaluatedCondition.cpp @@ -16,10 +16,17 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "RuleEvaluatedCondition.hpp" -#include "RuleParser.hpp" #include "RulePrivate.hpp" + +#include "usbguard/RuleParser.hpp" + #include + #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #include @@ -27,7 +34,7 @@ namespace usbguard { - RuleEvaluatedCondition::RuleEvaluatedCondition(const String& elapsed_time, bool negated) + RuleEvaluatedCondition::RuleEvaluatedCondition(const std::string& elapsed_time, bool negated) : RuleConditionBase("rule-applied", elapsed_time, negated) { _elapsed_time = std::chrono::steady_clock::duration(stringToSeconds(elapsed_time)); @@ -62,7 +69,7 @@ namespace usbguard return new RuleEvaluatedCondition(*this); } - uint64_t RuleEvaluatedCondition::stringToSeconds(const String& string) + uint64_t RuleEvaluatedCondition::stringToSeconds(const std::string& string) { struct ::tm tm = { }; diff --git a/src/Library/RuleEvaluatedCondition.hpp b/src/Library/RuleEvaluatedCondition.hpp index 3595dc2..967c38e 100644 --- a/src/Library/RuleEvaluatedCondition.hpp +++ b/src/Library/RuleEvaluatedCondition.hpp @@ -17,9 +17,15 @@ // Authors: Daniel Kopecek // #pragma once -#include "Typedefs.hpp" -#include "RuleCondition.hpp" -#include "Rule.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/RuleCondition.hpp" + +#include "usbguard/Typedefs.hpp" +#include "usbguard/Rule.hpp" + #include namespace usbguard @@ -27,14 +33,13 @@ namespace usbguard class RuleEvaluatedCondition : public RuleConditionBase { public: - RuleEvaluatedCondition(const String& elapsed_time, bool negated = false); + RuleEvaluatedCondition(const std::string& elapsed_time, bool negated = false); RuleEvaluatedCondition(const RuleEvaluatedCondition& rhs); bool update(const Rule& rule); RuleConditionBase * clone() const; protected: - static uint64_t stringToSeconds(const String& string); + static uint64_t stringToSeconds(const std::string& string); private: std::chrono::steady_clock::duration _elapsed_time; }; } /* namespace usbguard */ - diff --git a/src/Library/RuleParser.cpp b/src/Library/RuleParser.cpp deleted file mode 100644 index 40a0a08..0000000 --- a/src/Library/RuleParser.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include - -#include "RuleParser.hpp" -#include "RuleParser/Grammar.hpp" -#include "RuleParser/Actions.hpp" - -#include "Typedefs.hpp" -#include "RulePrivate.hpp" -#include "USB.hpp" -#include "Common/Utility.hpp" -#include "Logger.hpp" - -#include -#include -#include - -#include - -namespace usbguard -{ - Rule parseRuleFromString(const String& rule_spec, const String& file, size_t line, bool trace) - { - try { - Rule rule; -#if HAVE_PEGTL_LTE_1_3_1 - if (!trace) { - pegtl::parse(rule_spec, file, rule); - } - else { - pegtl::parse(rule_spec, file, rule); - } -#else - if (!trace) { - pegtl::parse_string(rule_spec, file, rule); - } - else { - pegtl::parse_string(rule_spec, file, rule); - } -#endif - return rule; - } - catch(const pegtl::parse_error& ex) { - RuleParserError error(rule_spec); - - error.setHint(ex.what()); -#if HAVE_PEGTL_LTE_1_3_1 - error.setOffset(ex.positions[0].column); -#else - error.setOffset(ex.positions[0].byte_in_line); -#endif - - if (!file.empty() || line != 0) { - error.setFileInfo(file, line); - } - - throw error; - } - catch(const std::exception& ex) { - - throw; - } - } -} /* namespace usbguard */ diff --git a/src/Library/RuleParser.hpp b/src/Library/RuleParser.hpp deleted file mode 100644 index 265aacd..0000000 --- a/src/Library/RuleParser.hpp +++ /dev/null @@ -1,105 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once -#include "Typedefs.hpp" -#include "Rule.hpp" -#include - -namespace usbguard -{ - class RuleParserError : public std::exception - { - public: - RuleParserError(const std::string& rule_spec, const std::string& hint = "", - const std::string& file = "", size_t error_line = 0, unsigned int error_offset = 0) - : _rule_spec(rule_spec), - _hint(hint), - _offset(error_offset), - _file(file), - _line(error_line) - { - } - - void setHint(const std::string& hint) - { - _hint = hint; - } - - void setOffset(size_t offset) - { - _offset = offset; - } - - void setFileInfo(const std::string& file, size_t error_line, size_t error_offset = 0) - { - _file = file; - _line = error_line; - _offset = error_offset; - } - - const char *what() const noexcept - { - return "RuleParserError"; - } - - const std::string& rule() const - { - return _rule_spec; - } - - const std::string& hint() const - { - return _hint; - } - - bool hasFileInfo() const - { - return !_file.empty(); - } - - const std::string fileInfo() const - { - return _file + ": line=" + std::to_string(_line) + ": offset=" + std::to_string(_offset); - } - - const std::string& file() const - { - return _file; - } - - size_t line() const - { - return _line; - } - - size_t offset() const - { - return _offset; - } - - protected: - const std::string _rule_spec; - std::string _hint; - size_t _offset; - std::string _file; - size_t _line; - }; - - DLL_PUBLIC Rule parseRuleFromString(const String& rule_spec, const String& file = String(), size_t line = 0, bool trace = false); -} /* namespace usbguard */ diff --git a/src/Library/RuleParser/Actions.hpp b/src/Library/RuleParser/Actions.hpp index a11a96b..da63273 100644 --- a/src/Library/RuleParser/Actions.hpp +++ b/src/Library/RuleParser/Actions.hpp @@ -17,7 +17,13 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "Utility.hpp" #include "Common/Utility.hpp" + #include namespace usbguard @@ -76,9 +82,9 @@ namespace usbguard } }; - static const String stringValueFromRule(const String& value) + static const std::string stringValueFromRule(const std::string& value) { - const String string_raw(value.substr(1, value.size() - 2)); + const std::string string_raw(value.substr(1, value.size() - 2)); return Utility::unescapeString(string_raw); } diff --git a/src/Library/RuleParser/Grammar.hpp b/src/Library/RuleParser/Grammar.hpp index b8b21d3..31967b8 100644 --- a/src/Library/RuleParser/Grammar.hpp +++ b/src/Library/RuleParser/Grammar.hpp @@ -17,6 +17,10 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "Actions.hpp" #include diff --git a/src/Library/RulePrivate.cpp b/src/Library/RulePrivate.cpp index 7a3bdc2..af4477a 100644 --- a/src/Library/RulePrivate.cpp +++ b/src/Library/RulePrivate.cpp @@ -16,11 +16,16 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "RulePrivate.hpp" -#include "RuleParser.hpp" -#include "Logger.hpp" #include "Common/Utility.hpp" +#include "usbguard/RuleParser.hpp" +#include "usbguard/Logger.hpp" + namespace usbguard { RulePrivate::RulePrivate(Rule& p_instance) : //_p_instance(p_instance), @@ -37,7 +42,6 @@ namespace usbguard { _rule_id = Rule::DefaultID; _target = Rule::Target::Invalid; _conditions_state = 0; - _timeout_seconds = 0; } RulePrivate::RulePrivate(Rule& p_instance, const RulePrivate& rhs) @@ -71,7 +75,6 @@ namespace usbguard { _conditions = rhs._conditions; _conditions_state = rhs._conditions_state; - _timeout_seconds = rhs._timeout_seconds; return *this; #if 0 @@ -94,7 +97,7 @@ namespace usbguard { { } - bool RulePrivate::appliesTo(Pointer rhs, bool parent_insensitive) const + bool RulePrivate::appliesTo(std::shared_ptr rhs, bool parent_insensitive) const { return appliesTo(*rhs, parent_insensitive); } @@ -247,11 +250,6 @@ namespace usbguard { _conditions_state = state; } - uint32_t RulePrivate::getTimeoutSeconds() const - { - return _timeout_seconds; - } - void RulePrivate::setRuleID(uint32_t rule_id) { _rule_id = rule_id; @@ -292,102 +290,102 @@ namespace usbguard { return _device_id; } - void RulePrivate::setSerial(const String& value) + void RulePrivate::setSerial(const std::string& value) { _serial.set(value); } - const String& RulePrivate::getSerial() const + const std::string& RulePrivate::getSerial() const { return _serial.get(); } - const Rule::Attribute& RulePrivate::attributeSerial() const + const Rule::Attribute& RulePrivate::attributeSerial() const { return _serial; } - Rule::Attribute& RulePrivate::attributeSerial() + Rule::Attribute& RulePrivate::attributeSerial() { return _serial; } - void RulePrivate::setName(const String& value) + void RulePrivate::setName(const std::string& value) { _name.set(value); } - const String& RulePrivate::getName() const + const std::string& RulePrivate::getName() const { return _name.get(); } - const Rule::Attribute& RulePrivate::attributeName() const + const Rule::Attribute& RulePrivate::attributeName() const { return _name; } - Rule::Attribute& RulePrivate::attributeName() + Rule::Attribute& RulePrivate::attributeName() { return _name; } - void RulePrivate::setHash(const String& value) + void RulePrivate::setHash(const std::string& value) { _hash.set(value); } - const String& RulePrivate::getHash() const + const std::string& RulePrivate::getHash() const { return _hash.get(); } - const Rule::Attribute& RulePrivate::attributeHash() const + const Rule::Attribute& RulePrivate::attributeHash() const { return _hash; } - Rule::Attribute& RulePrivate::attributeHash() + Rule::Attribute& RulePrivate::attributeHash() { return _hash; } - void RulePrivate::setParentHash(const String& value) + void RulePrivate::setParentHash(const std::string& value) { _parent_hash.set(value); } - const String& RulePrivate::getParentHash() const + const std::string& RulePrivate::getParentHash() const { return _parent_hash.get(); } - const Rule::Attribute& RulePrivate::attributeParentHash() const + const Rule::Attribute& RulePrivate::attributeParentHash() const { return _parent_hash; } - Rule::Attribute& RulePrivate::attributeParentHash() + Rule::Attribute& RulePrivate::attributeParentHash() { return _parent_hash; } - void RulePrivate::setViaPort(const String& value) + void RulePrivate::setViaPort(const std::string& value) { _via_port.set(value); } - const String& RulePrivate::getViaPort() const + const std::string& RulePrivate::getViaPort() const { return _via_port.get(); } - const Rule::Attribute& RulePrivate::attributeViaPort() const + const Rule::Attribute& RulePrivate::attributeViaPort() const { return _via_port; } - Rule::Attribute& RulePrivate::attributeViaPort() + Rule::Attribute& RulePrivate::attributeViaPort() { return _via_port; } @@ -412,13 +410,8 @@ namespace usbguard { return _conditions; } - void RulePrivate::setTimeoutSeconds(uint32_t timeout_seconds) - { - _timeout_seconds = timeout_seconds; - } - template - static void toString_appendNonEmptyAttribute(String& rule_string, const Rule::Attribute& attribute) + static void toString_appendNonEmptyAttribute(std::string& rule_string, const Rule::Attribute& attribute) { if (attribute.empty()) { return; @@ -430,9 +423,9 @@ namespace usbguard { return; } - String RulePrivate::toString(bool invalid) const + std::string RulePrivate::toString(bool invalid) const { - String rule_string; + std::string rule_string; try { rule_string.append(Rule::targetToString(_target)); @@ -467,7 +460,7 @@ namespace usbguard { return _meta; } - Rule RulePrivate::fromString(const String& rule_string) + Rule RulePrivate::fromString(const std::string& rule_string) { return parseRuleFromString(rule_string); } diff --git a/src/Library/RulePrivate.hpp b/src/Library/RulePrivate.hpp index c9fdd21..f32ca55 100644 --- a/src/Library/RulePrivate.hpp +++ b/src/Library/RulePrivate.hpp @@ -17,9 +17,14 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H #include -#include "Rule.hpp" -#include "RuleCondition.hpp" +#endif + +#include "usbguard/RuleCondition.hpp" + +#include "usbguard/Rule.hpp" + #include namespace usbguard { @@ -56,7 +61,7 @@ namespace usbguard { const RulePrivate& operator=(const RulePrivate& rhs); ~RulePrivate(); - bool appliesTo(Pointer rhs, bool parent_insensitive = false) const; + bool appliesTo(std::shared_ptr rhs, bool parent_insensitive = false) const; bool appliesTo(const Rule& rhs, bool parent_insensitive = false) const; bool appliesToWithConditions(const Rule& rhs, bool with_update = false); @@ -78,30 +83,30 @@ namespace usbguard { const Rule::Attribute& attributeDeviceID() const; Rule::Attribute& attributeDeviceID(); - void setSerial(const String& value); - const String& getSerial() const; - const Rule::Attribute& attributeSerial() const; - Rule::Attribute& attributeSerial(); + void setSerial(const std::string& value); + const std::string& getSerial() const; + const Rule::Attribute& attributeSerial() const; + Rule::Attribute& attributeSerial(); - void setName(const String& value); - const String& getName() const; - const Rule::Attribute& attributeName() const; - Rule::Attribute& attributeName(); + void setName(const std::string& value); + const std::string& getName() const; + const Rule::Attribute& attributeName() const; + Rule::Attribute& attributeName(); - void setHash(const String& value); - const String& getHash() const; - const Rule::Attribute& attributeHash() const; - Rule::Attribute& attributeHash(); + void setHash(const std::string& value); + const std::string& getHash() const; + const Rule::Attribute& attributeHash() const; + Rule::Attribute& attributeHash(); - void setParentHash(const String& value); - const String& getParentHash() const; - const Rule::Attribute& attributeParentHash() const; - Rule::Attribute& attributeParentHash(); + void setParentHash(const std::string& value); + const std::string& getParentHash() const; + const Rule::Attribute& attributeParentHash() const; + Rule::Attribute& attributeParentHash(); - void setViaPort(const String& value); - const String& getViaPort() const; - const Rule::Attribute& attributeViaPort() const; - Rule::Attribute& attributeViaPort(); + void setViaPort(const std::string& value); + const std::string& getViaPort() const; + const Rule::Attribute& attributeViaPort() const; + Rule::Attribute& attributeViaPort(); /* * Set/get for a single value isn't useful for the @@ -115,17 +120,14 @@ namespace usbguard { const Rule::Attribute& attributeConditions() const; Rule::Attribute& attributeConditions(); - void setTimeoutSeconds(uint32_t timeout_seconds); - uint32_t getTimeoutSeconds() const; - - String toString(bool invalid = false) const; + std::string toString(bool invalid = false) const; MetaData& metadata(); const MetaData& metadata() const; void updateMetaDataCounters(bool applied = true, bool evaluated = false); /*** Static methods ***/ - static Rule fromString(const String& rule_string); + static Rule fromString(const std::string& rule_string); private: //Rule& _p_instance; @@ -133,14 +135,13 @@ namespace usbguard { uint32_t _rule_id; Rule::Target _target; Rule::Attribute _device_id; - Rule::Attribute _serial; - Rule::Attribute _name; - Rule::Attribute _hash; - Rule::Attribute _parent_hash; - Rule::Attribute _via_port; + Rule::Attribute _serial; + Rule::Attribute _name; + Rule::Attribute _hash; + Rule::Attribute _parent_hash; + Rule::Attribute _via_port; Rule::Attribute _with_interface; Rule::Attribute _conditions; uint64_t _conditions_state; - uint32_t _timeout_seconds; }; } diff --git a/src/Library/RuleSet.cpp b/src/Library/RuleSet.cpp deleted file mode 100644 index d1e70e9..0000000 --- a/src/Library/RuleSet.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include "Typedefs.hpp" -#include "RuleSetPrivate.hpp" - -namespace usbguard { - RuleSet::RuleSet(Interface * const interface_ptr) - { - d_pointer = new RuleSetPrivate(*this, interface_ptr); - } - - RuleSet::~RuleSet() - { - delete d_pointer; - d_pointer = nullptr; - } - - RuleSet::RuleSet(const RuleSet& rhs) - { - d_pointer = new RuleSetPrivate(*this, *rhs.d_pointer); - } - - const RuleSet& RuleSet::operator=(const RuleSet& rhs) - { - RuleSetPrivate * n_pointer = new RuleSetPrivate(*this, *rhs.d_pointer); - delete d_pointer; - d_pointer = n_pointer; - return *this; - } - - void RuleSet::load(const String& path) - { - d_pointer->load(path); - } - - void RuleSet::load(std::istream& stream) - { - d_pointer->load(stream); - } - - void RuleSet::save(const String& path) const - { - d_pointer->save(path); - } - - void RuleSet::save(std::ostream& stream) const - { - d_pointer->save(stream); - } - - void RuleSet::setDefaultTarget(Rule::Target target) - { - d_pointer->setDefaultTarget(target); - } - - Rule::Target RuleSet::getDefaultTarget() const - { - return d_pointer->getDefaultTarget(); - } - - void RuleSet::setDefaultAction(const String& action) - { - d_pointer->setDefaultAction(action); - } - - uint32_t RuleSet::appendRule(const Rule& rule, uint32_t parent_id) - { - return d_pointer->appendRule(rule, parent_id); - } - - uint32_t RuleSet::upsertRule(const Rule& match_rule, const Rule& new_rule, const bool parent_insensitive) - { - return d_pointer->upsertRule(match_rule, new_rule, parent_insensitive); - } - - Pointer RuleSet::getRule(uint32_t id) - { - return d_pointer->getRule(id); - } - - bool RuleSet::removeRule(uint32_t id) - { - return d_pointer->removeRule(id); - } - - Pointer RuleSet::getFirstMatchingRule(Pointer device_rule, uint32_t from_id) const - { - return d_pointer->getFirstMatchingRule(device_rule, from_id); - } - - PointerVector RuleSet::getRules() - { - return d_pointer->getRules(); - } - - Pointer RuleSet::getTimedOutRule() - { - return d_pointer->getTimedOutRule(); - } - - uint32_t RuleSet::assignID(Pointer rule) - { - return d_pointer->assignID(rule); - } - - uint32_t RuleSet::assignID() - { - return d_pointer->assignID(); - } - -} /* namespace usbguard */ diff --git a/src/Library/RuleSet.hpp b/src/Library/RuleSet.hpp deleted file mode 100644 index 07ffa82..0000000 --- a/src/Library/RuleSet.hpp +++ /dev/null @@ -1,143 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once -#include -#include -#include -#include - -namespace usbguard { - class RuleSetPrivate; - class Interface; - class DLL_PUBLIC RuleSet - { - public: - /** - * Construct an empty ruleset. - */ - RuleSet(Interface * const interface_ptr); - RuleSet(const RuleSet& rhs); - const RuleSet& operator=(const RuleSet& rhs); - ~RuleSet(); - - /** - * Load a ruleset from a file at `path'. - * Internally, this opens an input file stream and calls load(std::istream& stream). - */ - void load(const String& path); - - /** - * Load a ruleset from an input stream. - * The stream is read using std::getline() and each line is parsed as a separate rule. - * Empty lines are skipped. - */ - void load(std::istream& stream); - - /** - * Save the ruleset to a file at `path'. - * If a file exists at `path', it will be overwritten. Internally, this opens an output - * stream and calls save(std::ostream& stream). - */ - void save(const String& path) const; - - /** - * Write the ruleset to an output stream. - * Each rule is serialized to it's string representation and written line by line to - * the output stream. - */ - void save(std::ostream& stream) const; - - /** - * Set an implicit default target which will be used if there's no match for a device - * rule. - */ - void setDefaultTarget(Rule::Target target); - - /** - * Get the implicit target value. - */ - Rule::Target getDefaultTarget() const; - - /** - * Set an implicit default action which will be used if there's no match for a device - * rule. - */ - void setDefaultAction(const String& action); - - /** - * Assign a sequence number to a rule and append it to the rule set. - * If `parent_id' is not specified, the rule will be appended at the end od the ruleset. - * The method returns the sequence number assigned to the rule. - */ - uint32_t appendRule(const Rule& rule, uint32_t parent_id = Rule::LastID); - - /** - * Search for a rule that matches `match_rule' rule and update it with a rule specified - * by `new_rule'. Fail if multiple rules match. If there are no matching rules, append - * the `new_rule' rule to the rule set. - * - * Returns the id of the updated or new rule. - */ - uint32_t upsertRule(const Rule& match_rule, const Rule& new_rule, bool parent_insensitive = false); - - /** - * Get a rule pointer to a rule with the specified sequence number. - * Returns nullptr if no such rule exists. - */ - Pointer getRule(uint32_t id); - - /** - * Remove a rule from the ruleset. - * The method returns true if a rule was removed and false otherwise. - */ - bool removeRule(uint32_t id); - - /** - * Find first rule in the ruleset which matched the specified device rule. - * If `from_id' isn't specified, the method searches from the beginning of the ruleset. - * If no matching rule is found, nullptr is returned. - */ - Pointer getFirstMatchingRule(Pointer device_rule, uint32_t from_id = 1) const; - - /** - * Get all rules from the set. - */ - PointerVector getRules(); - - /** - * Get the oldest rule that timed out and should be removed from the ruleset. - * Returns nullptr if there are not timed out rules. - */ - Pointer getTimedOutRule(); - - /** - * Assign a unique sequence number to a rule. - * Return the assigned sequence number. - */ - uint32_t assignID(Pointer rule); - - /** - * Generate a unique sequence number. - */ - uint32_t assignID(); - - private: - RuleSetPrivate* d_pointer; - }; -} diff --git a/src/Library/RuleSetPrivate.cpp b/src/Library/RuleSetPrivate.cpp index 6188fc3..fe447d9 100644 --- a/src/Library/RuleSetPrivate.cpp +++ b/src/Library/RuleSetPrivate.cpp @@ -16,11 +16,17 @@ // // Authors: Daniel Kopecek // -#include "Typedefs.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "RuleSetPrivate.hpp" #include "RulePrivate.hpp" -#include "RuleParser.hpp" -#include "Exception.hpp" + +#include "usbguard/Typedefs.hpp" +#include "usbguard/RuleParser.hpp" +#include "usbguard/Exception.hpp" + #include namespace usbguard { @@ -31,7 +37,7 @@ namespace usbguard { { (void)_p_instance; _default_target = Rule::Target::Block; - _default_action = String(); + _default_action = std::string(); _id_next = Rule::RootID + 1; } @@ -48,7 +54,6 @@ namespace usbguard { _default_action = rhs._default_action; _id_next = rhs._id_next.load(); _rules = rhs._rules; - _rules_timed = rhs._rules_timed; return *this; } @@ -56,7 +61,7 @@ namespace usbguard { { } - void RuleSetPrivate::load(const String& path) + void RuleSetPrivate::load(const std::string& path) { std::ifstream stream(path); if (!stream.is_open()) { @@ -81,7 +86,7 @@ namespace usbguard { } while(stream.good()); } - void RuleSetPrivate::save(const String& path) const + void RuleSetPrivate::save(const std::string& path) const { std::ofstream stream(path, std::fstream::trunc); if (!stream.is_open()) { @@ -113,7 +118,7 @@ namespace usbguard { return _default_target; } - void RuleSetPrivate::setDefaultAction(const String& action) + void RuleSetPrivate::setDefaultAction(const std::string& action) { std::unique_lock op_lock(_op_mutex); _default_action = action; @@ -127,7 +132,7 @@ namespace usbguard { op_lock.lock(); } - auto rule_ptr = makePointer(rule); + auto rule_ptr = std::make_shared(rule); /* * If the rule doesn't already have a sequence number @@ -167,18 +172,13 @@ namespace usbguard { } } - /* If the rule is timed, put it into the priority queue */ - if (rule_ptr->getTimeoutSeconds() > 0) { - _rules_timed.push(rule_ptr); - } - return rule_ptr->getRuleID(); } uint32_t RuleSetPrivate::upsertRule(const Rule& match_rule, const Rule& new_rule, const bool parent_insensitive) { std::unique_lock op_lock(_op_mutex); - Pointer matching_rule; + std::shared_ptr matching_rule; for (auto& rule_ptr : _rules) { if (rule_ptr->internal()->appliesTo(match_rule, parent_insensitive)) { @@ -202,7 +202,7 @@ namespace usbguard { } } - Pointer RuleSetPrivate::getRule(uint32_t id) + std::shared_ptr RuleSetPrivate::getRule(uint32_t id) { std::unique_lock op_lock(_op_mutex); for (auto const& rule : _rules) { @@ -227,7 +227,7 @@ namespace usbguard { throw Exception("Rule set remove", "rule id", "id doesn't exist"); } - Pointer RuleSetPrivate::getFirstMatchingRule(Pointer device_rule, uint32_t from_id) const + std::shared_ptr RuleSetPrivate::getFirstMatchingRule(std::shared_ptr device_rule, uint32_t from_id) const { (void)from_id; /* TODO */ std::unique_lock op_lock(_op_mutex); @@ -238,7 +238,7 @@ namespace usbguard { } } - Pointer default_rule = makePointer(); + std::shared_ptr default_rule = std::make_shared(); default_rule->setRuleID(Rule::ImplicitID); default_rule->setTarget(_default_target); @@ -246,9 +246,9 @@ namespace usbguard { return default_rule; } - PointerVector RuleSetPrivate::getRules() + std::vector> RuleSetPrivate::getRules() { - PointerVector rules; + std::vector> rules; for (auto const& rule : _rules) { rules.push_back(rule); @@ -257,29 +257,7 @@ namespace usbguard { return rules; } - Pointer RuleSetPrivate::getTimedOutRule() - { - std::unique_lock op_lock(_op_mutex); - - if (_rules_timed.size() < 1) { - return nullptr; - } - - Pointer oldest_rule = _rules_timed.top(); - std::chrono::steady_clock::time_point tp_current = \ - std::chrono::steady_clock::now(); - - if ((tp_current - oldest_rule->internal()->metadata().tp_created) \ - < std::chrono::seconds(oldest_rule->getTimeoutSeconds())) { - return nullptr; - } else { - _rules_timed.pop(); - } - - return oldest_rule; - } - - uint32_t RuleSetPrivate::assignID(Pointer rule) + uint32_t RuleSetPrivate::assignID(std::shared_ptr rule) { rule->setRuleID(assignID()); return rule->getRuleID(); diff --git a/src/Library/RuleSetPrivate.hpp b/src/Library/RuleSetPrivate.hpp index 699a030..e0f4344 100644 --- a/src/Library/RuleSetPrivate.hpp +++ b/src/Library/RuleSetPrivate.hpp @@ -17,9 +17,13 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H #include -#include "Typedefs.hpp" -#include "RuleSet.hpp" +#endif + +#include "usbguard/Typedefs.hpp" +#include "usbguard/RuleSet.hpp" + #include #include #include @@ -33,21 +37,20 @@ namespace usbguard { const RuleSetPrivate& operator=(const RuleSetPrivate& rhs); ~RuleSetPrivate(); - void load(const String& path); + void load(const std::string& path); void load(std::istream& stream); - void save(const String& path) const; + void save(const std::string& path) const; void save(std::ostream& stream) const; void setDefaultTarget(Rule::Target target); Rule::Target getDefaultTarget() const; - void setDefaultAction(const String& action); + void setDefaultAction(const std::string& action); uint32_t appendRule(const Rule& rule, uint32_t parent_id = Rule::LastID, bool lock = true); uint32_t upsertRule(const Rule& match_rule, const Rule& new_rule, bool parent_insensitive = false); - Pointer getRule(uint32_t id); + std::shared_ptr getRule(uint32_t id); bool removeRule(uint32_t id); - Pointer getFirstMatchingRule(Pointer device_rule, uint32_t from_id = 1) const; - PointerVector getRules(); - Pointer getTimedOutRule(); - uint32_t assignID(Pointer rule); + std::shared_ptr getFirstMatchingRule(std::shared_ptr device_rule, uint32_t from_id = 1) const; + std::vector> getRules(); + uint32_t assignID(std::shared_ptr rule); uint32_t assignID(); private: @@ -56,9 +59,8 @@ namespace usbguard { RuleSet& _p_instance; Interface * const _interface_ptr; Rule::Target _default_target; - String _default_action; + std::string _default_action; Atomic _id_next; - PointerVector _rules; - PointerPQueue _rules_timed; + std::vector> _rules; }; } diff --git a/src/Library/SysFSDevice.cpp b/src/Library/SysFSDevice.cpp index 3cda3c0..ba20289 100644 --- a/src/Library/SysFSDevice.cpp +++ b/src/Library/SysFSDevice.cpp @@ -16,12 +16,16 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif #include "SysFSDevice.hpp" -#include "Logger.hpp" -#include "Exception.hpp" #include "Common/Utility.hpp" +#include "usbguard/Logger.hpp" +#include "usbguard/Exception.hpp" + #ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE #endif @@ -37,7 +41,7 @@ namespace usbguard { } - SysFSDevice::SysFSDevice(const String& sysfs_path, bool without_parent) + SysFSDevice::SysFSDevice(const std::string& sysfs_path, bool without_parent) : _sysfs_path(sysfs_path), _sysfs_name(filenameFromPath(_sysfs_path, /*include_extension=*/true)), _sysfs_dirfd(-1) @@ -95,12 +99,12 @@ namespace usbguard return *this; } - const String& SysFSDevice::getPath() const + const std::string& SysFSDevice::getPath() const { return _sysfs_path; } - const String& SysFSDevice::getName() const + const std::string& SysFSDevice::getName() const { return _sysfs_name; } @@ -110,12 +114,12 @@ namespace usbguard return _uevent; } - const String& SysFSDevice::getParentPath() const + const std::string& SysFSDevice::getParentPath() const { return _sysfs_parent_path; } - int SysFSDevice::openAttribute(const String& name) const + int SysFSDevice::openAttribute(const std::string& name) const { USBGUARD_LOG(Trace) << "name=" << name; @@ -126,21 +130,21 @@ namespace usbguard return fd; } - String SysFSDevice::readAttribute(const String& name, bool strip_last_null, bool optional) const + std::string SysFSDevice::readAttribute(const std::string& name, bool strip_last_null, bool optional) const { USBGUARD_LOG(Trace) << "name=" << name; const int fd = openat(_sysfs_dirfd, name.c_str(), O_RDONLY); if (fd < 0) { if (optional && errno == ENOENT) { - return String(); + return std::string(); } else { throw ErrnoException("SysFSDevice", name, errno); } } try { - String buffer(4096, 0); + std::string buffer(4096, 0); ssize_t rc = -1; USBGUARD_SYSCALL_THROW("SysFSDevice", (rc = read(fd, &buffer[0], buffer.capacity())) < 0); @@ -150,7 +154,7 @@ namespace usbguard buffer.resize(static_cast(rc) - 1); } else { - return String(); + return std::string(); } } else { @@ -167,7 +171,7 @@ namespace usbguard } } - void SysFSDevice::setAttribute(const String& name, const String& value) + void SysFSDevice::setAttribute(const std::string& name, const std::string& value) { USBGUARD_LOG(Trace) << "name=" << name << " value=" << value; USBGUARD_LOG(Trace) << "path=" << _sysfs_path; @@ -195,7 +199,7 @@ namespace usbguard void SysFSDevice::reloadUEvent() { - const String uevent_string = readAttribute("uevent"); + const std::string uevent_string = readAttribute("uevent"); _uevent = UEvent::fromString(uevent_string, /*attributes_only=*/true); } } /* namespace usbguard */ diff --git a/src/Library/SysFSDevice.hpp b/src/Library/SysFSDevice.hpp index c159323..2f39ff2 100644 --- a/src/Library/SysFSDevice.hpp +++ b/src/Library/SysFSDevice.hpp @@ -17,9 +17,15 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif #include "UEvent.hpp" -#include "Typedefs.hpp" + +#include "usbguard/Typedefs.hpp" + +#include namespace usbguard { @@ -27,26 +33,26 @@ namespace usbguard { public: SysFSDevice(); - SysFSDevice(const String& sysfs_path, bool without_parent = false); + SysFSDevice(const std::string& sysfs_path, bool without_parent = false); SysFSDevice(SysFSDevice&& device); ~SysFSDevice(); SysFSDevice& operator=(SysFSDevice&& rhs_device); - const String& getPath() const; - const String& getName() const; + const std::string& getPath() const; + const std::string& getName() const; const UEvent& getUEvent() const; - const String& getParentPath() const; - String readAttribute(const String& name, bool strip_last_null = false, bool optional = false) const; - void setAttribute(const String& name, const String& value); - int openAttribute(const String& name) const; + const std::string& getParentPath() const; + std::string readAttribute(const std::string& name, bool strip_last_null = false, bool optional = false) const; + void setAttribute(const std::string& name, const std::string& value); + int openAttribute(const std::string& name) const; void reload(); private: void reloadUEvent(); - String _sysfs_path; - String _sysfs_name; - String _sysfs_parent_path; + std::string _sysfs_path; + std::string _sysfs_name; + std::string _sysfs_parent_path; int _sysfs_dirfd; UEvent _uevent; }; diff --git a/src/Library/Typedefs.cpp b/src/Library/Typedefs.cpp deleted file mode 100644 index 28464d5..0000000 --- a/src/Library/Typedefs.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include "Typedefs.hpp" - -namespace usbguard { - - template<> - bool matches(const String& a, const String& b) - { - return a == b; - } - -} /* namespace usbguard */ diff --git a/src/Library/Typedefs.hpp b/src/Library/Typedefs.hpp deleted file mode 100644 index 13b1fc8..0000000 --- a/src/Library/Typedefs.hpp +++ /dev/null @@ -1,145 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace usbguard { - /* - * Char string typedefs - */ - typedef std::string String; - typedef std::vector StringVector; - typedef std::list StringList; - - template - using StringMap = std::map; - - template - using StringKeyMap = std::map; - - template - using StringVectorMap = std::map; - - template - bool matches(const T& a, const T& b) - { - return a == b; - } - - template<> - bool matches(const String& a, const String& b); - - /* - * Smart Pointer typedefs and custom operations - */ - template - using Pointer = std::shared_ptr; - - template > - using UniquePointer = std::unique_ptr; - - template - using PointerVector = std::vector >; - - template - using PointerMap = std::map >; - - template - using PointerPQueue = std::priority_queue >; - - template - static inline Pointer makePointer(Args&&... args) - { - return std::make_shared(std::forward(args)...); - } - - template - static inline UniquePointer makeUniquePointer(Args&&... args) - { - return std::move(std::unique_ptr(new pointer_type(std::forward(args)...))); - } - - namespace MapOp { - template - typename map_type::mapped_type findOne(const map_type& map, const typename map_type::key_type& key) - { - auto it = map.find(key); - if (it == map.end()) { - return typename map_type::mapped_type(); - } else { - return it->second; - } - } - } - - namespace PointerMapOp { - template - Pointer findOne(const PointerMap& map, - const key_type& key) - { - auto it = map.find(key); - if (it == map.end()) { - return Pointer(nullptr); - } else { - return it->second; - } - } - } - - /* - * Atomic - */ - template - using Atomic = std::atomic; - - /* - * Symbol visibility - */ - #if defined _WIN32 || defined __CYGWIN__ - #ifdef BUILDING_DLL - #ifdef __GNUC__ - #define DLL_PUBLIC __attribute__ ((dllexport)) - #else - #define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. - #endif - #else - #ifdef __GNUC__ - #define DLL_PUBLIC __attribute__ ((dllimport)) - #else - #define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. - #endif - #endif - #define DLL_LOCAL - #else - #if __GNUC__ >= 4 - #define DLL_PUBLIC __attribute__ ((visibility ("default"))) - #define DLL_LOCAL __attribute__ ((visibility ("hidden"))) - #else - #define DLL_PUBLIC - #define DLL_LOCAL - #endif - #endif -} /* namespace usbguard */ diff --git a/src/Library/UEvent.cpp b/src/Library/UEvent.cpp index c007d7e..a55b421 100644 --- a/src/Library/UEvent.cpp +++ b/src/Library/UEvent.cpp @@ -16,9 +16,14 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "UEvent.hpp" #include "UEventParser.hpp" -#include "Logger.hpp" + +#include "usbguard/Logger.hpp" namespace usbguard { @@ -37,7 +42,7 @@ namespace usbguard return *this; } - UEvent UEvent::fromString(const String& uevent_string, bool attributes_only, bool trace) + UEvent UEvent::fromString(const std::string& uevent_string, bool attributes_only, bool trace) { UEvent uevent; parseUEventFromString(uevent_string, uevent, attributes_only, trace); @@ -49,35 +54,35 @@ namespace usbguard _attributes.clear(); } - void UEvent::setAttribute(const String& name, const String& value) + void UEvent::setAttribute(const std::string& name, const std::string& value) { USBGUARD_LOG(Trace) << "Setting attribute: " << name << "=" << value; _attributes[name] = value; } - String UEvent::getAttribute(const String& name) const + std::string UEvent::getAttribute(const std::string& name) const { auto it = _attributes.find(name); if (it == _attributes.end()) { - return String(); + return std::string(); } else { return it->second; } } - bool UEvent::hasAttribute(const String& name) const + bool UEvent::hasAttribute(const std::string& name) const { return _attributes.count(name) == 1; } - String UEvent::getHeaderLine() const + std::string UEvent::getHeaderLine() const { if (!hasAttribute("ACTION") || !hasAttribute("DEVPATH")) { throw std::runtime_error("uevent: missing required header line values"); } - String header_line; + std::string header_line; header_line.append(getAttribute("ACTION")); header_line.append(1, '@'); @@ -86,9 +91,9 @@ namespace usbguard return header_line; } - String UEvent::toString(char separator) const + std::string UEvent::toString(char separator) const { - String uevent_string = getHeaderLine(); + std::string uevent_string = getHeaderLine(); uevent_string.append(1, separator); @@ -104,7 +109,7 @@ namespace usbguard bool UEvent::hasRequiredAttributes() const { - for (const String name : { "ACTION", "DEVPATH", "SUBSYSTEM" }) { + for (const std::string name : { "ACTION", "DEVPATH", "SUBSYSTEM" }) { if (!hasAttribute(name)) { return false; } diff --git a/src/Library/UEvent.hpp b/src/Library/UEvent.hpp index faa7930..f042e0d 100644 --- a/src/Library/UEvent.hpp +++ b/src/Library/UEvent.hpp @@ -17,8 +17,14 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif -#include "Typedefs.hpp" +#include "usbguard/Typedefs.hpp" + +#include +#include namespace usbguard { @@ -29,18 +35,18 @@ namespace usbguard UEvent(UEvent&& rhs); UEvent& operator=(UEvent&& rhs); - static UEvent fromString(const String& uevent_string, bool attributes_only = false, bool trace = false); + static UEvent fromString(const std::string& uevent_string, bool attributes_only = false, bool trace = false); void clear(); - void setAttribute(const String& name, const String& value); - String getAttribute(const String& name) const; - bool hasAttribute(const String& name) const; + void setAttribute(const std::string& name, const std::string& value); + std::string getAttribute(const std::string& name) const; + bool hasAttribute(const std::string& name) const; bool hasRequiredAttributes() const; - String getHeaderLine() const; - String toString(char separator = '\0') const; + std::string getHeaderLine() const; + std::string toString(char separator = '\0') const; private: - StringKeyMap _attributes; + std::map _attributes; }; } /* namespace usbguard */ diff --git a/src/Library/UEventDeviceManager.cpp b/src/Library/UEventDeviceManager.cpp index b6e3418..bdf4ad0 100644 --- a/src/Library/UEventDeviceManager.cpp +++ b/src/Library/UEventDeviceManager.cpp @@ -16,19 +16,22 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include +#endif #if defined(HAVE_UEVENT) #include "UEventDeviceManager.hpp" #include "UEventParser.hpp" #include "SysFSDevice.hpp" -#include "Logger.hpp" -#include "Exception.hpp" -#include "USB.hpp" #include "Base64.hpp" #include "Common/FDInputStream.hpp" #include "Common/Utility.hpp" +#include "usbguard/Logger.hpp" +#include "usbguard/Exception.hpp" +#include "usbguard/USB.hpp" + #include #include #include @@ -51,7 +54,7 @@ namespace usbguard { * Look for the parent USB device and set the parent id * if we find one. */ - const String sysfs_parent_path(sysfs_device.getParentPath()); + const std::string sysfs_parent_path(sysfs_device.getParentPath()); const SysFSDevice sysfs_parent_device(sysfs_parent_path); if (sysfs_parent_device.getUEvent().getAttribute("DEVTYPE") == "usb_device") { @@ -68,8 +71,8 @@ namespace usbguard { /* * Set USB ID */ - const String id_vendor(sysfs_device.readAttribute("idVendor", /*strip_last_null=*/true)); - const String id_product(sysfs_device.readAttribute("idProduct", /*strip_last_null=*/true)); + const std::string id_vendor(sysfs_device.readAttribute("idVendor", /*strip_last_null=*/true)); + const std::string id_product(sysfs_device.readAttribute("idProduct", /*strip_last_null=*/true)); const USBDeviceID device_id(id_vendor, id_product); setDeviceID(device_id); /* @@ -83,7 +86,7 @@ namespace usbguard { /* * Sync authorization target */ - const String authorized_value(sysfs_device.readAttribute("authorized", /*strip_last_null=*/true)); + const std::string authorized_value(sysfs_device.readAttribute("authorized", /*strip_last_null=*/true)); if (authorized_value == "0") { setTarget(Rule::Target::Block); @@ -130,7 +133,7 @@ namespace usbguard { return _sysfs_device; } - const String& UEventDevice::getSysPath() const + const std::string& UEventDevice::getSysPath() const { return _sysfs_device.getPath(); } @@ -223,7 +226,7 @@ namespace usbguard { /* * Manager */ - UEventDeviceManager::UEventDeviceManager(DeviceManagerHooks& hooks, const String& sysfs_root, bool dummy_mode) + UEventDeviceManager::UEventDeviceManager(DeviceManagerHooks& hooks, const std::string& sysfs_root, bool dummy_mode) : DeviceManager(hooks), _thread(this, &UEventDeviceManager::thread), _uevent_fd(-1), @@ -321,12 +324,12 @@ namespace usbguard { } } - Pointer UEventDeviceManager::applyDevicePolicy(uint32_t id, Rule::Target target) + std::shared_ptr UEventDeviceManager::applyDevicePolicy(uint32_t id, Rule::Target target) { USBGUARD_LOG(Trace) << "id=" << id << " target=" << Rule::targetToString(target); - Pointer device = std::static_pointer_cast(getDevice(id)); + std::shared_ptr device = std::static_pointer_cast(getDevice(id)); std::unique_lock device_lock(device->refDeviceMutex()); sysfsApplyTarget(device->sysfsDevice(), target); @@ -402,8 +405,8 @@ namespace usbguard { void UEventDeviceManager::sysfsApplyTarget(SysFSDevice& sysfs_device, Rule::Target target) { - String name; - String value("0"); + std::string name; + std::string value("0"); switch (target) { case Rule::Target::Allow: @@ -475,7 +478,7 @@ namespace usbguard { void UEventDeviceManager::ueventProcessRead() { - String buffer(4096, 0); + std::string buffer(4096, 0); struct iovec iov[1]; iov[0].iov_base = (void *)&buffer[0]; @@ -568,9 +571,9 @@ namespace usbguard { void UEventDeviceManager::ueventProcessUEvent(const UEvent& uevent) { - const String subsystem = uevent.getAttribute("SUBSYSTEM"); - const String devtype = uevent.getAttribute("DEVTYPE"); - const String action = uevent.getAttribute("ACTION"); + const std::string subsystem = uevent.getAttribute("SUBSYSTEM"); + const std::string devtype = uevent.getAttribute("DEVTYPE"); + const std::string action = uevent.getAttribute("ACTION"); if (subsystem != "usb" || devtype != "usb_device") { USBGUARD_LOG(Debug) << "Ignoring non-USB device:" @@ -580,7 +583,7 @@ namespace usbguard { return; } - const String sysfs_devpath = _sysfs_root + uevent.getAttribute("DEVPATH"); + const std::string sysfs_devpath = _sysfs_root + uevent.getAttribute("DEVPATH"); try { std::unique_lock lock(_enumeration_mutex); @@ -600,7 +603,7 @@ namespace usbguard { * Do some additional sanity checking. */ if (sysfs_device.getUEvent().hasAttribute("DEVTYPE")) { - const String devtype = sysfs_device.getUEvent().getAttribute("DEVTYPE"); + const std::string devtype = sysfs_device.getUEvent().getAttribute("DEVTYPE"); if (devtype != "usb_device") { USBGUARD_LOG(Warning) << sysfs_devpath << ": UEvent DEVTYPE mismatch." << " Expected \"usb_device\", got \"" << devtype << "\""; @@ -640,10 +643,10 @@ namespace usbguard { } } - bool UEventDeviceManager::ueventEnumerateComparePath(const std::pair& a, const std::pair& b) + bool UEventDeviceManager::ueventEnumerateComparePath(const std::pair& a, const std::pair& b) { - const String base_a = filenameFromPath(a.second, /*include_extension=*/true); - const String base_b = filenameFromPath(b.second, /*include_extension=*/true); + const std::string base_a = filenameFromPath(a.second, /*include_extension=*/true); + const std::string base_b = filenameFromPath(b.second, /*include_extension=*/true); const bool a_has_usb_prefix = (0 == base_a.compare(0, 3, "usb")); const bool b_has_usb_prefix = (0 == base_b.compare(0, 3, "usb")); @@ -673,7 +676,7 @@ namespace usbguard { USBGUARD_LOG(Trace); return loadFiles(_sysfs_root + "/bus/usb/devices", UEventDeviceManager::ueventEnumerateFilterDevice, - [this](const String& devpath, const String& buspath) + [this](const std::string& devpath, const std::string& buspath) { return ueventEnumerateTriggerDevice(devpath, buspath); }, @@ -685,7 +688,7 @@ namespace usbguard { USBGUARD_LOG(Trace); return loadFiles(_sysfs_root + "/bus/usb/devices", UEventDeviceManager::ueventEnumerateFilterDevice, - [this](const String& devpath, const String& buspath) + [this](const std::string& devpath, const std::string& buspath) { (void)buspath; UEvent uevent; @@ -704,7 +707,7 @@ namespace usbguard { UEventDeviceManager::ueventEnumerateComparePath); } - String UEventDeviceManager::ueventEnumerateFilterDevice(const String& filepath, const struct dirent* direntry) + std::string UEventDeviceManager::ueventEnumerateFilterDevice(const std::string& filepath, const struct dirent* direntry) { #if defined(_DIRENT_HAVE_D_TYPE) if (direntry->d_type != DT_UNKNOWN) { @@ -714,7 +717,7 @@ namespace usbguard { case DT_DIR: return filepath; default: - return String(); + return std::string(); } } else { @@ -729,7 +732,7 @@ namespace usbguard { * Cannot stat, skip this entry. */ USBGUARD_LOG(Warning) << "lstat(" << filepath << "): errno=" << errno; - return String(); + return std::string(); } if (S_ISLNK(st.st_mode)) { return symlinkPath(filepath, &st); @@ -738,16 +741,16 @@ namespace usbguard { return filepath; } else { - return String(); + return std::string(); } #if defined(_DIRENT_HAVE_D_TYPE) } #endif /* UNREACHABLE */ - return String(); + return std::string(); } - int UEventDeviceManager::ueventEnumerateTriggerDevice(const String& devpath, const String& buspath) + int UEventDeviceManager::ueventEnumerateTriggerDevice(const std::string& devpath, const std::string& buspath) { USBGUARD_LOG(Trace) << "devpath=" << devpath << " buspath=" << buspath; @@ -776,7 +779,7 @@ namespace usbguard { USBGUARD_LOG(Trace) << "id=" << id; try { - Pointer device = \ + std::shared_ptr device = \ std::static_pointer_cast(DeviceManager::getDevice(id)); device->sysfsDevice().reload(); @@ -811,7 +814,7 @@ namespace usbguard { void UEventDeviceManager::processDeviceInsertion(SysFSDevice& sysfs_device, const bool signal_present) { try { - Pointer device = makePointer(*this, sysfs_device); + std::shared_ptr device = std::make_shared(*this, sysfs_device); if (device->isController() && !_enumeration_only_mode) { USBGUARD_LOG(Debug) << "Setting default blocked state for controller device to " << _default_blocked_state; @@ -861,19 +864,19 @@ namespace usbguard { sysfsApplyTarget(sysfs_device, Rule::Target::Reject); } - void UEventDeviceManager::insertDevice(Pointer device) + void UEventDeviceManager::insertDevice(std::shared_ptr device) { DeviceManager::insertDevice(std::static_pointer_cast(device)); std::unique_lock device_lock(device->refDeviceMutex()); learnSysPath(device->getSysPath(), device->getID()); } - void UEventDeviceManager::processDeviceRemoval(const String& sysfs_devpath) + void UEventDeviceManager::processDeviceRemoval(const std::string& sysfs_devpath) { USBGUARD_LOG(Trace) << "sysfs_devpath=" << sysfs_devpath; try { - Pointer device = removeDevice(sysfs_devpath); + std::shared_ptr device = removeDevice(sysfs_devpath); DeviceEvent(DeviceManager::EventType::Remove, device); } catch(...) { /* Ignore for now */ @@ -882,7 +885,7 @@ namespace usbguard { } } - Pointer UEventDeviceManager::removeDevice(const String& syspath) + std::shared_ptr UEventDeviceManager::removeDevice(const std::string& syspath) { /* * FIXME: device map locking @@ -891,13 +894,13 @@ namespace usbguard { throw Exception("removeDevice", syspath, "unknown syspath, cannot remove device"); } - Pointer device = DeviceManager::removeDevice(getIDFromSysPath(syspath)); + std::shared_ptr device = DeviceManager::removeDevice(getIDFromSysPath(syspath)); _syspath_map.erase(syspath); return device; } - uint32_t UEventDeviceManager::getIDFromSysPath(const String& syspath) const + uint32_t UEventDeviceManager::getIDFromSysPath(const std::string& syspath) const { uint32_t id = 0; const bool known = knownSysPath(syspath, &id); @@ -909,7 +912,7 @@ namespace usbguard { throw Exception("UEventDeviceManager", syspath, "unknown syspath"); } - bool UEventDeviceManager::knownSysPath(const String& syspath, uint32_t * id_ptr) const + bool UEventDeviceManager::knownSysPath(const std::string& syspath, uint32_t * id_ptr) const { auto it = _syspath_map.find(syspath); @@ -928,13 +931,13 @@ namespace usbguard { return known; } - void UEventDeviceManager::learnSysPath(const String& syspath, uint32_t id) + void UEventDeviceManager::learnSysPath(const std::string& syspath, uint32_t id) { USBGUARD_LOG(Trace) << "syspath=" << syspath << " id=" << id; _syspath_map[syspath] = id; } - void UEventDeviceManager::forgetSysPath(const String& syspath) + void UEventDeviceManager::forgetSysPath(const std::string& syspath) { _syspath_map.erase(syspath); } diff --git a/src/Library/UEventDeviceManager.hpp b/src/Library/UEventDeviceManager.hpp index 4143fce..b7adb60 100644 --- a/src/Library/UEventDeviceManager.hpp +++ b/src/Library/UEventDeviceManager.hpp @@ -17,22 +17,24 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H #include +#endif #if defined(HAVE_UEVENT) -#include "Typedefs.hpp" #include "Common/Thread.hpp" - -#include "DeviceManager.hpp" -#include "Device.hpp" -#include "Rule.hpp" #include "SysFSDevice.hpp" -#include "USB.hpp" -#include +#include "usbguard/Typedefs.hpp" +#include "usbguard/DeviceManager.hpp" +#include "usbguard/Device.hpp" +#include "usbguard/Rule.hpp" +#include "usbguard/USB.hpp" +#include #include + #include #include @@ -45,7 +47,7 @@ namespace usbguard { UEventDevice(UEventDeviceManager& device_manager, SysFSDevice& sysfs_device); SysFSDevice& sysfsDevice(); - const String& getSysPath() const; + const std::string& getSysPath() const; bool isController() const override; private: @@ -66,7 +68,7 @@ namespace usbguard { using DeviceManager::insertDevice; public: - UEventDeviceManager(DeviceManagerHooks& hooks, const String& sysfs_root = USBGUARD_SYSFS_ROOT, bool dummy_mode = false); + UEventDeviceManager(DeviceManagerHooks& hooks, const std::string& sysfs_root = USBGUARD_SYSFS_ROOT, bool dummy_mode = false); ~UEventDeviceManager(); void setDefaultBlockedState(bool state) override; @@ -76,43 +78,43 @@ namespace usbguard { void stop() override; void scan() override; - Pointer applyDevicePolicy(uint32_t id, Rule::Target target) override; - void insertDevice(Pointer device); - Pointer removeDevice(const String& syspath); + std::shared_ptr applyDevicePolicy(uint32_t id, Rule::Target target) override; + void insertDevice(std::shared_ptr device); + std::shared_ptr removeDevice(const std::string& syspath); - uint32_t getIDFromSysPath(const String& syspath) const; + uint32_t getIDFromSysPath(const std::string& syspath) const; protected: int ueventOpen(); int ueventDummyOpen(); void sysfsApplyTarget(SysFSDevice& sysfs_device, Rule::Target target); - bool knownSysPath(const String& syspath, uint32_t * id = nullptr) const; - void learnSysPath(const String& syspath, uint32_t id = 0); - void forgetSysPath(const String& syspath); + bool knownSysPath(const std::string& syspath, uint32_t * id = nullptr) const; + void learnSysPath(const std::string& syspath, uint32_t id = 0); + void forgetSysPath(const std::string& syspath); void thread(); void ueventProcessRead(); void ueventProcessUEvent(const UEvent& uevent); - static bool ueventEnumerateComparePath(const std::pair& a, const std::pair& b); + static bool ueventEnumerateComparePath(const std::pair& a, const std::pair& b); int ueventEnumerateDevices(); int ueventEnumerateDummyDevices(); - static String ueventEnumerateFilterDevice(const String& filepath, const struct dirent* direntry); - int ueventEnumerateTriggerDevice(const String& devpath, const String& buspath); + static std::string ueventEnumerateFilterDevice(const std::string& filepath, const struct dirent* direntry); + int ueventEnumerateTriggerDevice(const std::string& devpath, const std::string& buspath); void processDevicePresence(SysFSDevice& sysfs_device); void processDeviceInsertion(SysFSDevice& sysfs_device, bool signal_present); void processDevicePresence(uint32_t id); - void processDeviceRemoval(const String& sysfs_devpath); + void processDeviceRemoval(const std::string& sysfs_devpath); private: Thread _thread; int _uevent_fd; int _wakeup_fd; - StringKeyMap _syspath_map; - String _sysfs_root; + std::map _syspath_map; + std::string _sysfs_root; bool _default_blocked_state; bool _enumeration_only_mode; bool _dummy_mode; diff --git a/src/Library/UEventParser.cpp b/src/Library/UEventParser.cpp index 528f323..d785a6c 100644 --- a/src/Library/UEventParser.cpp +++ b/src/Library/UEventParser.cpp @@ -16,13 +16,16 @@ // // Authors: Daniel Kopecek // +#ifdef HAVE_BUILD_CONFIG_H #include +#endif #include "UEventParser.hpp" #include "UEvent.hpp" -#include "Logger.hpp" #include "Common/Utility.hpp" +#include "usbguard/Logger.hpp" + #include #include @@ -47,10 +50,10 @@ namespace usbguard throw pegtl::parse_error("invalid attribute format", in); } - const String key = in.string().substr(0, p); - const String value = trim(in.string().substr(p + 1, std::string::npos), String("\n\0", 2)); + const std::string key = in.string().substr(0, p); + const std::string value = trim(in.string().substr(p + 1, std::string::npos), std::string("\n\0", 2)); - for (const String header_key : { "ACTION", "DEVPATH" }) { + for (const std::string header_key : { "ACTION", "DEVPATH" }) { if (key == header_key) { if (value != uevent.getAttribute(header_key)) { throw pegtl::parse_error("header value mismatch", in); @@ -90,7 +93,7 @@ namespace usbguard }; } /* namespace UEventParser */ - void parseUEventFromFile(const String& uevent_path, UEvent& uevent, bool attributes_only, bool trace) + void parseUEventFromFile(const std::string& uevent_path, UEvent& uevent, bool attributes_only, bool trace) { std::ifstream uevent_stream(uevent_path); @@ -111,22 +114,22 @@ namespace usbguard } template - void parseUEventFromString(const String& uevent_string, UEvent& uevent, bool trace) + void parseUEventFromString(const std::string& uevent_string, UEvent& uevent, bool trace) { try { #if HAVE_PEGTL_LTE_1_3_1 if (!trace) { - pegtl::parse(uevent_string, String(), uevent); + pegtl::parse(uevent_string, std::string(), uevent); } else { - pegtl::parse(uevent_string, String(), uevent); + pegtl::parse(uevent_string, std::string(), uevent); } #else if (!trace) { - pegtl::parse_string(uevent_string, String(), uevent); + pegtl::parse_string(uevent_string, std::string(), uevent); } else { - pegtl::parse_string(uevent_string, String(), uevent); + pegtl::parse_string(uevent_string, std::string(), uevent); } #endif } @@ -135,7 +138,7 @@ namespace usbguard } } - void parseUEventFromString(const String& uevent_string, UEvent& uevent, bool attributes_only, bool trace) + void parseUEventFromString(const std::string& uevent_string, UEvent& uevent, bool attributes_only, bool trace) { if (attributes_only) { parseUEventFromString(uevent_string, uevent, trace); diff --git a/src/Library/UEventParser.hpp b/src/Library/UEventParser.hpp index 5e42794..4927179 100644 --- a/src/Library/UEventParser.hpp +++ b/src/Library/UEventParser.hpp @@ -17,8 +17,12 @@ // Authors: Daniel Kopecek // #pragma once +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Typedefs.hpp" -#include "Typedefs.hpp" #include using namespace pegtl; @@ -58,6 +62,6 @@ namespace usbguard } /* namespace UEventParser */ - void parseUEventFromFile(const String& uevent_path, UEvent& uevent, bool attributes_only = false, bool trace = false); - void parseUEventFromString(const String& uevent_string, UEvent& uevent, bool attributes_only = false, bool trace = false); + void parseUEventFromFile(const std::string& uevent_path, UEvent& uevent, bool attributes_only = false, bool trace = false); + void parseUEventFromString(const std::string& uevent_string, UEvent& uevent, bool attributes_only = false, bool trace = false); } /* namespace usbguard */ diff --git a/src/Library/USB.cpp b/src/Library/USB.cpp deleted file mode 100644 index bc4a0fd..0000000 --- a/src/Library/USB.cpp +++ /dev/null @@ -1,519 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include "USB.hpp" -#include "Common/ByteOrder.hpp" -#include "Common/Utility.hpp" -#include "Logger.hpp" -#include -#include -#include - -namespace usbguard { - USBDeviceID::USBDeviceID() - { - } - - USBDeviceID::USBDeviceID(const String& vendor_id, const String& product_id) - { - checkDeviceID(vendor_id, product_id); - setVendorID(vendor_id); - setProductID(product_id); - } - - USBDeviceID::USBDeviceID(const USBDeviceID& rhs) - { - _vendor_id = rhs._vendor_id; - _product_id = rhs._product_id; - } - - void USBDeviceID::checkDeviceID(const String& vendor_id, const String& product_id) - { - if (vendor_id.empty() || vendor_id == "*") { - /* product id must be empty or "*" */ - if (!product_id.empty() && product_id != "*") { - throw std::runtime_error("Invalid USB device id format"); - } - } - if (vendor_id.size() > USB_VID_STRING_MAX_LENGTH) { - throw std::runtime_error("Vendor ID string size out of range"); - } - if (product_id.size() > USB_PID_STRING_MAX_LENGTH) { - throw std::runtime_error("Product ID string size out of range"); - } - } - - void USBDeviceID::setVendorID(const String& vendor_id) - { - checkDeviceID(vendor_id, _product_id); - _vendor_id = vendor_id; - } - - void USBDeviceID::setProductID(const String& product_id) - { - checkDeviceID(_vendor_id, product_id); - _product_id = product_id; - } - - const String& USBDeviceID::getVendorID() const - { - return _vendor_id; - } - - const String& USBDeviceID::getProductID() const - { - return _product_id; - } - - String USBDeviceID::toRuleString() const - { - return _vendor_id + ":" + _product_id; - } - - String USBDeviceID::toString() const - { - return toRuleString(); - } - - bool USBDeviceID::isSubsetOf(const USBDeviceID& rhs) const - { - if (_vendor_id.empty() || _vendor_id == "*") { - return true; - } - else if (_vendor_id != rhs._vendor_id) { - return false; - } - - if (_product_id.empty() || _product_id == "*") { - return true; - } - else if (_product_id != rhs._product_id) { - return false; - } - - return true; - } - - template<> - bool Predicates::isSubsetOf(const USBDeviceID& source, const USBDeviceID& target) - { - USBGUARD_LOG(Trace) << "source=" << source.toString() << " target=" << target.toString(); - const bool result = source.isSubsetOf(target); - USBGUARD_LOG(Trace) << "result=" << result; - return result; - } - - USBInterfaceType::USBInterfaceType() - { - _bClass = 0; - _bSubClass = 0; - _bProtocol = 0; - _mask = 0; - } - - USBInterfaceType::USBInterfaceType(uint8_t bClass, uint8_t bSubClass, uint8_t bProtocol, uint8_t mask) - { - _bClass = bClass; - _bSubClass = bSubClass; - _bProtocol = bProtocol; - _mask = mask; - } - - USBInterfaceType::USBInterfaceType(const USBInterfaceDescriptor& descriptor, uint8_t mask) - { - _bClass = descriptor.bInterfaceClass; - _bSubClass = descriptor.bInterfaceSubClass; - _bProtocol = descriptor.bInterfaceProtocol; - _mask = mask; - } - - USBInterfaceType::USBInterfaceType(const std::string& type_string) - { - std::vector tokens; - tokenizeString(type_string, tokens, ":", /*trim_empty=*/false); - - _bClass = 0; - _bSubClass = 0; - _bProtocol = 0; - _mask = 0; - - if (tokens.size() != 3) { - throw std::runtime_error("Invalid type_string"); - } - - if (tokens[0].size() != 2) { - throw std::runtime_error("Invalid type_string"); - } - else { - _bClass = stringToNumber(tokens[0], 16); - _mask |= MatchClass; - } - - if (tokens[1] != "*") { - if (tokens[1].size() != 2) { - throw std::runtime_error("Invalid type_string"); - } - else { - _bSubClass = stringToNumber(tokens[1], 16); - _mask |= MatchSubClass; - } - } - - if (tokens[2] != "*") { - if (tokens[2].size() != 2) { - throw std::runtime_error("Invalid type_string"); - } - else { - _bProtocol = stringToNumber(tokens[2], 16); - _mask |= MatchProtocol; - } - } - - if (!(_mask == (MatchAll) || - _mask == (MatchClass|MatchSubClass) || - _mask == (MatchClass))) { - throw std::runtime_error("Invalid type_string"); - } - } - - bool USBInterfaceType::operator==(const USBInterfaceType& rhs) const - { - return (_bClass == rhs._bClass && - _bSubClass == rhs._bSubClass && - _bProtocol == rhs._bProtocol && - _mask == rhs._mask); - } - - bool USBInterfaceType::appliesTo(const USBInterfaceType& rhs) const - { - if (_mask & MatchClass) { - if (_bClass != rhs._bClass) { - return false; - } - } - if (_mask & MatchSubClass) { - if (_bSubClass != rhs._bSubClass) { - return false; - } - } - if (_mask & MatchProtocol) { - if (_bProtocol != rhs._bProtocol) { - return false; - } - } - return true; - } - - template<> - bool Predicates::isSubsetOf(const USBInterfaceType& source, const USBInterfaceType& target) - { - return source.appliesTo(target); - } - - const String USBInterfaceType::typeString() const - { - return USBInterfaceType::typeString(_bClass, _bSubClass, _bProtocol, _mask); - } - - const String USBInterfaceType::toRuleString() const - { - return typeString(); - } - - const String USBInterfaceType::typeString(uint8_t bClass, uint8_t bSubClass, uint8_t bProtocol, uint8_t mask) - { - String type_string(""); - - if (mask & MatchClass) { - type_string.append(numberToString(bClass, "", 16, 2, '0') + ":"); - - if (mask & MatchSubClass) { - type_string.append(numberToString(bSubClass, "", 16, 2, '0') + ":"); - - if (mask & MatchProtocol) { - type_string.append(numberToString(bProtocol, "", 16, 2, '0')); - } - else { - type_string.append("*"); - } - } - else { - type_string.append("*:*"); - } - } - else { - throw std::runtime_error("BUG: cannot create type string, invalid mask"); - } - - return type_string; - } - - void USBParseDeviceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) - { - (void)parser; - const USBDeviceDescriptor* device_raw = reinterpret_cast(descriptor_raw); - USBDeviceDescriptor* device_out = reinterpret_cast(descriptor_out); - - /* Copy 1:1 */ - *device_out = *device_raw; - - /* Convert multibyte field to host endianness */ - device_out->bcdUSB = busEndianToHost(device_raw->bcdUSB); - device_out->idVendor = busEndianToHost(device_raw->idVendor); - device_out->idProduct = busEndianToHost(device_raw->idProduct); - device_out->bcdDevice = busEndianToHost(device_raw->bcdDevice); - } - - void USBParseConfigurationDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) - { - (void)parser; - const USBConfigurationDescriptor* configuration_raw = reinterpret_cast(descriptor_raw); - USBConfigurationDescriptor* configuration_out = reinterpret_cast(descriptor_out); - - /* Copy 1:1 */ - *configuration_out = *configuration_raw; - - /* Convert multibyte field to host endianness */ - configuration_out->wTotalLength = busEndianToHost(configuration_raw->wTotalLength); - } - - void USBParseInterfaceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) - { - (void)parser; - const USBInterfaceDescriptor* interface_raw = reinterpret_cast(descriptor_raw); - USBInterfaceDescriptor* interface_out = reinterpret_cast(descriptor_out); - - /* Copy 1:1 */ - *interface_out = *interface_raw; - } - - void USBParseEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) - { - (void)parser; - const USBEndpointDescriptor* endpoint_raw = reinterpret_cast(descriptor_raw); - USBEndpointDescriptor* endpoint_out = reinterpret_cast(descriptor_out); - - *endpoint_out = *endpoint_raw; - endpoint_out->wMaxPacketSize = busEndianToHost(endpoint_raw->wMaxPacketSize); - } - - void USBParseAudioEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) - { - (void)parser; - const USBAudioEndpointDescriptor* endpoint_raw = reinterpret_cast(descriptor_raw); - USBAudioEndpointDescriptor* endpoint_out = reinterpret_cast(descriptor_out); - - *endpoint_out = *endpoint_raw; - endpoint_out->wMaxPacketSize = busEndianToHost(endpoint_raw->wMaxPacketSize); - } - - void USBParseUnknownDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) - { - (void)parser; - *descriptor_out = *descriptor_raw; - } - - void USBDescriptorParserHooks::parseUSBDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) - { - USBGUARD_LOG(Trace); - - const auto type = static_cast(descriptor_raw->bHeader.bDescriptorType); - const auto size = descriptor_raw->bHeader.bLength; - - switch(type) { - case USBDescriptorType::Device: - switch (size) { - case sizeof(USBDeviceDescriptor): - USBParseDeviceDescriptor(parser, descriptor_raw, descriptor_out); - return; - default: - throw Exception("USB descriptor parser", "device descriptor", "unexpected descriptor size"); - } - break; - case USBDescriptorType::Configuration: - switch (size) { - case sizeof(USBConfigurationDescriptor): - USBParseConfigurationDescriptor(parser, descriptor_raw, descriptor_out); - return; - default: - throw Exception("USB descriptor parser", "configuration descriptor", "unexpected descriptor size"); - } - break; - case USBDescriptorType::Interface: - switch (size) { - case sizeof(USBInterfaceDescriptor): - USBParseInterfaceDescriptor(parser, descriptor_raw, descriptor_out); - return; - default: - throw Exception("USB descriptor parser", "interface descriptor", "unexpected descriptor size"); - } - break; - case USBDescriptorType::Endpoint: - switch (size) { - case sizeof(USBEndpointDescriptor): - USBParseEndpointDescriptor(parser, descriptor_raw, descriptor_out); - return; - case sizeof(USBAudioEndpointDescriptor): - USBParseAudioEndpointDescriptor(parser, descriptor_raw, descriptor_out); - return; - default: - throw Exception("USB descriptor parser", "endpoint descriptor", "unexpected descriptor size"); - } - break; - case USBDescriptorType::String: - case USBDescriptorType::AssociationInterface: - case USBDescriptorType::Unknown: - default: - USBParseUnknownDescriptor(parser, descriptor_raw, descriptor_out); - return; - } - /* UNREACHABLE */ - } - - void USBDescriptorParserHooks::loadUSBDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor) - { - (void)parser; - (void)descriptor; - USBGUARD_LOG(Trace); - } - - USBDescriptorParser::USBDescriptorParser(USBDescriptorParserHooks& hooks) - : _hooks(hooks) - { - } - - size_t USBDescriptorParser::parse(std::istream& stream) - { - size_t size_processed = 0; - - while (stream.good()) { - USBDescriptorHeader header; - stream.read(reinterpret_cast(&header), sizeof header); - - if (stream.gcount() != sizeof header) { - /* - * If we read nothing and the stream if at EOF, just break - * the loop and return normally. Checking the sanity of the - * parsed descriptor data is up to the higher layers. - */ - if (stream.gcount() == 0 && stream.eof()) { - break; - } - /* - * Otherwise throw an exception because there's unknown garbage - * in the stream which cannot be a valid USB descriptor. - */ - else { - throw std::runtime_error("Cannot parse descriptor data: partial read while reading header data"); - } - } - - /* - * The bLength value has to be at least 2, because that is the size of the USB - * descriptor header. - */ - if (header.bLength < sizeof(USBDescriptorHeader)) { - throw std::runtime_error("Invalid descriptor data: bLength is less than the size of the header"); - } - - /* - * Let's try to read the rest of the descriptor data before we start looking - * for the descriptor type handler. If there's not enough data in the stream, - * then there's no point for searching for the handler. - */ - USBDescriptor descriptor; - - descriptor.bHeader = header; - memset(&descriptor.bDescriptorData, 0, sizeof descriptor.bDescriptorData); - - /* - * We read (bLength - header_size) amount of data here because the bLength value - * counts in the size of the header too and we already read it from the stream. - */ - stream.read(reinterpret_cast(&descriptor.bDescriptorData), header.bLength - sizeof(USBDescriptorHeader)); - - if (stream.gcount() != (std::streamsize)(header.bLength - sizeof(USBDescriptorHeader))) { - throw std::runtime_error("Invalid descriptor data: bLength value larger than the amount of available data"); - } - - USBDescriptor descriptor_parsed; - descriptor_parsed.bHeader = header; - memset(&descriptor_parsed.bDescriptorData, 0, sizeof descriptor_parsed.bDescriptorData); - - _hooks.parseUSBDescriptor(this, &descriptor, &descriptor_parsed); - _hooks.loadUSBDescriptor(this, &descriptor_parsed); - - setDescriptor(header.bDescriptorType, descriptor_parsed); - size_processed += header.bLength; - } - - return size_processed; - } - - const std::vector* USBDescriptorParser::getDescriptor(uint8_t bDescriptorType) const - { - auto const& it = _dstate_map.find(bDescriptorType); - if (it == _dstate_map.end()) { - return nullptr; - } - return &it->second; - } - - void USBDescriptorParser::setDescriptor(uint8_t bDescriptorType, const USBDescriptor& descriptor) - { - auto& descriptors = _dstate_map[bDescriptorType]; - bool set = false; - for (auto& stored_descriptor : descriptors) { - if (stored_descriptor.bHeader.bLength == descriptor.bHeader.bLength) { - stored_descriptor = descriptor; - set = true; - } - } - if (!set) { - descriptors.push_back(descriptor); - } - /* - * Count in the descriptor no matter if we overwrote one or not. - * We are counting all occurences of a descriptor type. - */ - ++_count_map[bDescriptorType]; - } - - void USBDescriptorParser::delDescriptor(uint8_t bDescriptorType) - { - _dstate_map.erase(bDescriptorType); - } - - bool USBDescriptorParser::haveDescriptor(uint8_t bDescriptorType) const - { - return _dstate_map.count(bDescriptorType) > 0; - } - - const std::vector> USBDescriptorParser::getDescriptorCounts() const - { - std::vector> counts; - - for (auto const& kv : _count_map) { - counts.push_back(std::make_pair(kv.first, kv.second)); - } - - std::sort(counts.begin(), counts.end()); - - return counts; - } -} /* namespace usbguard */ diff --git a/src/Library/USB.hpp b/src/Library/USB.hpp deleted file mode 100644 index 3058157..0000000 --- a/src/Library/USB.hpp +++ /dev/null @@ -1,270 +0,0 @@ -// -// Copyright (C) 2015 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once -#include "Predicates.hpp" - -#include -#include -#include -#include -#include - -namespace usbguard { - /* - * Maximum lenght of a string that is read from a USB descriptor - * Since the string descriptors have an 8-bit length field, the - * maximum lenght of a string stored in a string descriptor is - * UINT8_MAX minus the size of the length field (1 byte) and the - * size of the type field (1 byte). - */ - const size_t USB_GENERIC_STRING_MAX_LENGTH = UINT8_MAX - 2; - - /* Maximum lenght of the vendor id in string form */ - const size_t USB_VID_STRING_MAX_LENGTH = 4; - - /* Maximum lenght of the product id in string form */ - const size_t USB_PID_STRING_MAX_LENGTH = 4; - - /* Maximum lenght of the port in string form */ - const size_t USB_PORT_STRING_MAX_LENGTH = PATH_MAX; - - /* - * NOTE: The USB specification dictates that all multibyte data fields - * are in little-endian form. The structures defined bellow are - * used for platform-independed passing of the USB descriptor - * data to the Device class. The Device class assumes that the - * values are in host-specific endianness. - */ - const uint8_t USB_DESCRIPTOR_TYPE_UNKNOWN = 0x00; - const uint8_t USB_DESCRIPTOR_TYPE_DEVICE = 0x01; - const uint8_t USB_DESCRIPTOR_TYPE_CONFIGURATION = 0x02; - const uint8_t USB_DESCRIPTOR_TYPE_STRING = 0x03; - const uint8_t USB_DESCRIPTOR_TYPE_INTERFACE = 0x04; - const uint8_t USB_DESCRIPTOR_TYPE_ENDPOINT = 0x05; - const uint8_t USB_DESCRIPTOR_TYPE_ASSOCIATION_INTERFACE = 0x0b; - - enum class USBDescriptorType : uint8_t { - Unknown = USB_DESCRIPTOR_TYPE_UNKNOWN, - Device = USB_DESCRIPTOR_TYPE_DEVICE, - Configuration = USB_DESCRIPTOR_TYPE_CONFIGURATION, - String = USB_DESCRIPTOR_TYPE_STRING, - Interface = USB_DESCRIPTOR_TYPE_INTERFACE, - Endpoint = USB_DESCRIPTOR_TYPE_ENDPOINT, - AssociationInterface = USB_DESCRIPTOR_TYPE_ASSOCIATION_INTERFACE - }; - - struct DLL_PUBLIC USBDescriptorHeader - { - uint8_t bLength; - uint8_t bDescriptorType; - } __attribute__((packed)); - - struct DLL_PUBLIC USBDescriptor - { - struct USBDescriptorHeader bHeader; - uint8_t bDescriptorData[256-sizeof(USBDescriptorHeader)]; - } __attribute__((packed)); - - struct DLL_PUBLIC USBDeviceDescriptor - { - struct USBDescriptorHeader bHeader; - uint16_t bcdUSB; - uint8_t bDeviceClass; - uint8_t bDeviceSubClass; - uint8_t bDeviceProtocol; - uint8_t bMaxPacketSize; - uint16_t idVendor; - uint16_t idProduct; - uint16_t bcdDevice; - uint8_t iManufacturer; - uint8_t iProduct; - uint8_t iSerialNumber; - uint8_t bNumConfigurations; - } __attribute__((packed)); - - struct DLL_PUBLIC USBConfigurationDescriptor - { - struct USBDescriptorHeader bHeader; - uint16_t wTotalLength; - uint8_t bNumInterfaces; - uint8_t bConfigurationValue; - uint8_t iConfiguration; - uint8_t bmAttributes; - uint8_t bMaxPower; - } __attribute__((packed)); - - struct DLL_PUBLIC USBInterfaceDescriptor - { - struct USBDescriptorHeader bHeader; - uint8_t bInterfaceNumber; - uint8_t bAlternateSetting; - uint8_t bNumEndpoints; - uint8_t bInterfaceClass; - uint8_t bInterfaceSubClass; - uint8_t bInterfaceProtocol; - uint8_t iInterface; - } __attribute__((packed)); - - struct USBEndpointDescriptor - { - struct USBDescriptorHeader bHeader; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - uint16_t wMaxPacketSize; - uint8_t bInterval; - } __attribute__((packed)); - - struct USBAudioEndpointDescriptor - { - struct USBDescriptorHeader bHeader; - uint8_t bEndpointAddress; - uint8_t bmAttributes; - uint16_t wMaxPacketSize; - uint8_t bInterval; - uint8_t bRefresh; - uint8_t bSynchAddress; - } __attribute__((packed)); - - class DLL_PUBLIC USBDeviceID - { - public: - USBDeviceID(); - USBDeviceID(const String& vendor_id, const String& product_id = String()); - USBDeviceID(const USBDeviceID& rhs); - - static void checkDeviceID(const String& vendor_id, const String& product_id); - - void setVendorID(const String& vendor_id); - void setProductID(const String& product_id); - - const String& getVendorID() const; - const String& getProductID() const; - - String toRuleString() const; - String toString() const; - bool isSubsetOf(const USBDeviceID& rhs) const; - - private: - String _vendor_id; - String _product_id; - }; - - namespace Predicates DLL_PUBLIC - { - template<> - bool isSubsetOf(const USBDeviceID& source, const USBDeviceID& target); - } - - class DLL_PUBLIC USBInterfaceType - { - public: - static const uint8_t MatchClass = 1<<0; - static const uint8_t MatchSubClass = 1<<1; - static const uint8_t MatchProtocol = 1<<2; - static const uint8_t MatchAll = MatchClass|MatchSubClass|MatchProtocol; - - USBInterfaceType(); - USBInterfaceType(uint8_t bClass, uint8_t bSubClass, uint8_t bProtocol, uint8_t mask = MatchAll); - USBInterfaceType(const USBInterfaceDescriptor& descriptor, uint8_t mask = MatchAll); - USBInterfaceType(const std::string& type_string); - - bool operator==(const USBInterfaceType& rhs) const; - bool appliesTo(const USBInterfaceType& rhs) const; - - const String typeString() const; - const String toRuleString() const; - static const String typeString(uint8_t bClass, uint8_t bSubClass, uint8_t bProtocol, uint8_t mask = MatchAll); - - private: - uint8_t _bClass; - uint8_t _bSubClass; - uint8_t _bProtocol; - uint8_t _mask; - }; - - namespace Predicates DLL_PUBLIC - { - template<> - bool isSubsetOf(const USBInterfaceType& source, const USBInterfaceType& target); - } - - class USBDescriptorParser; - - class DLL_PUBLIC USBDescriptorParserHooks - { - public: - virtual void parseUSBDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_in, USBDescriptor* descriptor_out); - virtual void loadUSBDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); - }; - - class DLL_PUBLIC USBDescriptorParser - { - public: - USBDescriptorParser(USBDescriptorParserHooks& hooks); - - /** - * Initiate parsing of USB descriptors from an input stream. - * - * Returns number of bytes succesfully parsed/processed from - * the stream. - */ - size_t parse(std::istream& stream); - - /** - * Return a pointer to a USBDescriptor of type bDescriptorType that - * is stored in the USB descriptor state. If there's no such descriptor, - * then nullptr is returned. - */ - const std::vector* getDescriptor(uint8_t bDescriptorType) const; - - /** - * Set the active instance of an USB descriptor of bDescriptorType type. - */ - void setDescriptor(uint8_t bDescriptorType, const USBDescriptor& descriptor); - - /** - * Delete the active instance of an USB descriptor of bDescriptorType type. - */ - void delDescriptor(uint8_t bDescriptorType); - - /** - * Returns true if the descriptor state contains a USB descriptor of type bDescriptorType. - */ - bool haveDescriptor(uint8_t bDescriptorType) const; - - /** - * Returns a vector of (bDescriptorType, count) pairs. - */ - const std::vector> getDescriptorCounts() const; - - private: - USBDescriptorParserHooks& _hooks; - - std::unordered_map> _dstate_map; /**< Descriptor State Map */ - std::unordered_map _count_map; - }; - - void DLL_PUBLIC USBParseDeviceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); - void DLL_PUBLIC USBParseConfigurationDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); - void DLL_PUBLIC USBParseInterfaceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); - void DLL_PUBLIC USBParseEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); - void DLL_PUBLIC USBParseAudioEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); - void DLL_PUBLIC USBParseUnknownDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); - -} /* namespace usbguard */ diff --git a/src/Library/USBGuard.cpp b/src/Library/USBGuard.cpp deleted file mode 100644 index 27955ab..0000000 --- a/src/Library/USBGuard.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// -// Copyright (C) 2017 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#include - -#include "USBGuard.hpp" -#include "ConfigFile.hpp" -#include "Exception.hpp" -#include "Logger.hpp" - -#include -#include - -#ifndef USBGUARD_DAEMON_CONF_PATH -# warning "Using hard-coded USBGUARD_DAEMON_CONF_PATH value" -# define USBGUARD_DAEMON_CONF_PATH "/etc/usbguard/usbguard-daemon.conf" -#endif - -namespace usbguard -{ - std::string getDaemonConfigPath() - { - USBGUARD_LOG(Trace); - const char * const envval = getenv("USBGUARD_DAEMON_CONF"); - - if (envval != nullptr) { - USBGUARD_LOG(Debug) << "Returning environment variable path: " << envval; - return std::string(envval); - } - else { - USBGUARD_LOG(Debug) << "Returning build-time path: " << USBGUARD_DAEMON_CONF_PATH; - return std::string(USBGUARD_DAEMON_CONF_PATH); - } - } - - std::string getIPCAccessControlFilesPath() - { - USBGUARD_LOG(Trace); - const std::string daemon_conf_path = getDaemonConfigPath(); - ConfigFile daemon_conf; - daemon_conf.open(daemon_conf_path); - - if (daemon_conf.hasSettingValue("IPCAccessControlFiles")) { - return daemon_conf.getSettingValue("IPCAccessControlFiles"); - } - - throw Exception("getIPCAccessControlFilesPath", daemon_conf_path, "IPCAccessControlFiles not set"); - } - - std::string getIPCAccessControlFileBasename(const std::string& name, bool is_group) - { - USBGUARD_LOG(Trace) << "name=" << name << " is_group=" << is_group; - std::string basename; - if (is_group) { - basename.append(":"); - } - basename.append(name); - return basename; - } -} /* namespace usbguard */ diff --git a/src/Library/USBGuard.hpp b/src/Library/USBGuard.hpp deleted file mode 100644 index 7950c88..0000000 --- a/src/Library/USBGuard.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// Copyright (C) 2017 Red Hat, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// -// Authors: Daniel Kopecek -// -#pragma once -#include "Typedefs.hpp" -#include - -namespace usbguard -{ - DLL_PUBLIC std::string getDaemonConfigPath(); - DLL_PUBLIC std::string getIPCAccessControlFilesPath(); - DLL_PUBLIC std::string getIPCAccessControlFileBasename(const std::string& name, bool is_group); -} /* namespace usbguard */ diff --git a/src/Library/Utility.cpp b/src/Library/Utility.cpp index cd2e6d9..68287b8 100644 --- a/src/Library/Utility.cpp +++ b/src/Library/Utility.cpp @@ -16,18 +16,24 @@ // // Authors: Daniel Kopecek // -#include "Typedefs.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + #include "Utility.hpp" #include "Common/Utility.hpp" + +#include "usbguard/Typedefs.hpp" + #include namespace usbguard { namespace Utility { - String escapeString(const String& string_raw) + std::string escapeString(const std::string& string_raw) { - String result; + std::string result; const std::locale c_locale("C"); for (auto it = string_raw.cbegin(); it != string_raw.cend(); ++it) { @@ -54,7 +60,7 @@ namespace usbguard if (std::isprint(c, c_locale)) { result.push_back((char)c); } else { - const String hexbyte = numberToString((uint8_t)c, "\\x", 16, 2, '0'); + const std::string hexbyte = numberToString((uint8_t)c, "\\x", 16, 2, '0'); result.append(hexbyte); } } @@ -62,9 +68,9 @@ namespace usbguard return result; } - String unescapeString(const String& string_escaped) + std::string unescapeString(const std::string& string_escaped) { - String result; + std::string result; bool escaped = false; const std::locale c_locale("C"); @@ -94,7 +100,7 @@ namespace usbguard throw std::runtime_error("Invalid \\xHH escape sequence: HH is not a hexadecimal number"); } - const String hexbyte(hb, 2); + const std::string hexbyte(hb, 2); result.push_back((char)stringToNumber(hexbyte, 16)); ++it; @@ -123,9 +129,9 @@ namespace usbguard return result; } - String quoteEscapeString(const String& value) + std::string quoteEscapeString(const std::string& value) { - String result; + std::string result; result.push_back('"'); result.append(escapeString(value)); result.push_back('"'); diff --git a/src/Library/Utility.hpp b/src/Library/Utility.hpp index 2764dd3..94a9ad1 100644 --- a/src/Library/Utility.hpp +++ b/src/Library/Utility.hpp @@ -17,14 +17,20 @@ // Authors: Daniel Kopecek // #pragma once -#include "Typedefs.hpp" +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Typedefs.hpp" + +#include namespace usbguard { namespace Utility { - String escapeString(const String& value); - String unescapeString(const String& value); - String quoteEscapeString(const String& value); + std::string escapeString(const std::string& value); + std::string unescapeString(const std::string& value); + std::string quoteEscapeString(const std::string& value); } } /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Audit.cpp b/src/Library/public/usbguard/Audit.cpp new file mode 100644 index 0000000..e692733 --- /dev/null +++ b/src/Library/public/usbguard/Audit.cpp @@ -0,0 +1,255 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "Audit.hpp" +#include "Exception.hpp" +#include "Logger.hpp" + +#include + +namespace usbguard +{ + + AuditIdentity::AuditIdentity() + { + _uid = getuid(); + _pid = getpid(); + } + + AuditIdentity::AuditIdentity(uid_t uid, pid_t pid) + { + _uid = uid; + _pid = pid; + } + + std::string AuditIdentity::toString() const + { + std::string identity_string; + + identity_string.append("{ uid="); + identity_string.append(numberToString(_uid)); + identity_string.append(" pid="); + identity_string.append(numberToString(_pid)); + identity_string.append(" }"); + + return identity_string; + } + + AuditEvent::AuditEvent(const AuditIdentity& identity) + : _confirmed(false), + _identity(identity) + { + + } + + AuditEvent::AuditEvent(AuditEvent&& event) + : _confirmed(event._confirmed), + _identity(std::move(event._identity)), + _message(std::move(event._message)) + { + event.setConfirmed(true); + } + + AuditEvent::~AuditEvent() + { + if (!_confirmed) { + failure(); + } + } + + void AuditEvent::confirm(const std::string& result) + { + USBGUARD_LOG(Audit) << "result=" << result \ + << " identity=" << _identity.toString() \ + << " " << _message; + setConfirmed(true); + } + + void AuditEvent::success() + { + confirm("SUCCESS"); + } + + void AuditEvent::failure() + { + confirm("FAILURE"); + } + + void AuditEvent::setConfirmed(bool state) + { + _confirmed = state; + } + + std::string& AuditEvent::refMessage() + { + return _message; + } + + Audit::Audit(const AuditIdentity& identity) + : _identity(identity) + { + + } + + AuditEvent Audit::policyEvent(std::shared_ptr rule, Policy::EventType event) + { + return policyEvent(_identity, rule, event); + } + + AuditEvent Audit::policyEvent(std::shared_ptr new_rule, std::shared_ptr old_rule) + { + return policyEvent(_identity, new_rule, old_rule); + } + + AuditEvent Audit::policyEvent(std::shared_ptr device, Policy::EventType event) + { + return policyEvent(_identity, device, event); + } + + AuditEvent Audit::policyEvent(std::shared_ptr device, Rule::Target old_target, Rule::Target new_target) + { + return policyEvent(_identity, device, old_target, new_target); + } + + AuditEvent Audit::deviceEvent(std::shared_ptr device, DeviceManager::EventType event) + { + return deviceEvent(_identity, device, event); + } + + AuditEvent Audit::deviceEvent(std::shared_ptr new_device, std::shared_ptr old_device) + { + return deviceEvent(_identity, new_device, old_device); + } + + AuditEvent Audit::policyEvent(const AuditIdentity& identity, std::shared_ptr rule, Policy::EventType event) + { + AuditEvent audit_event(identity); + auto& message = audit_event.refMessage(); + + message += "type=Policy."; + message += Policy::eventTypeToString(event); + + message += " rule.id="; + message += numberToString(rule->getRuleID()); + + message += " rule='"; + message += rule->toString(); + message += "'"; + + return audit_event; + } + + AuditEvent Audit::policyEvent(const AuditIdentity& identity, std::shared_ptr new_rule, std::shared_ptr old_rule) + { + AuditEvent audit_event(identity); + auto& message = audit_event.refMessage(); + + message += "type=Policy."; + message += Policy::eventTypeToString(Policy::EventType::Update); + + message += " rule.id="; + message += numberToString(old_rule->getRuleID()); + + message += " rule.old='"; + message += old_rule->toString(); + message += "'"; + + message += " rule.new='"; + message += new_rule->toString(); + message += "'"; + + return audit_event; + } + + AuditEvent Audit::policyEvent(const AuditIdentity& identity, std::shared_ptr device, Policy::EventType event) + { + AuditEvent audit_event(identity); + auto& message = audit_event.refMessage(); + + message += "type=Policy.Device."; + message += Policy::eventTypeToString(event); + + message += " target="; + message += Rule::targetToString(device->getTarget()); + + message += " device='"; + message += device->getDeviceRule()->toString(); + message += "'"; + + return audit_event; + } + + AuditEvent Audit::policyEvent(const AuditIdentity& identity, std::shared_ptr device, Rule::Target old_target, Rule::Target new_target) + { + AuditEvent audit_event(identity); + auto& message = audit_event.refMessage(); + + message += "type=Policy.Device."; + message += Policy::eventTypeToString(Policy::EventType::Update); + + message += " target.old="; + message += Rule::targetToString(old_target); + + message += " target.new="; + message += Rule::targetToString(new_target); + + message += " device='"; + message += device->getDeviceRule()->toString(); + message += "'"; + + return audit_event; + } + + AuditEvent Audit::deviceEvent(const AuditIdentity& identity, std::shared_ptr device, DeviceManager::EventType event) + { + AuditEvent audit_event(identity); + auto& message = audit_event.refMessage(); + + message += "type=Device."; + message += DeviceManager::eventTypeToString(event); + + message += " device='"; + message += device->getDeviceRule()->toString(); + message += "'"; + + return audit_event; + } + + AuditEvent Audit::deviceEvent(const AuditIdentity& identity, std::shared_ptr new_device, std::shared_ptr old_device) + { + AuditEvent audit_event(identity); + auto& message = audit_event.refMessage(); + + message += "type=Device."; + message += DeviceManager::eventTypeToString(DeviceManager::EventType::Update); + + message += " device.old='"; + message += old_device->getDeviceRule()->toString(); + message += "'"; + + message += " device.new='"; + message += new_device->getDeviceRule()->toString(); + message += "'"; + + return audit_event; + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Audit.hpp b/src/Library/public/usbguard/Audit.hpp new file mode 100644 index 0000000..398d4c2 --- /dev/null +++ b/src/Library/public/usbguard/Audit.hpp @@ -0,0 +1,120 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Device.hpp" +#include "DeviceManager.hpp" +#include "Logger.hpp" +#include "Policy.hpp" +#include "Rule.hpp" +#include "Typedefs.hpp" + +#include +#include + +#include +#include + +namespace usbguard +{ + class DLL_PUBLIC AuditIdentity + { + public: + AuditIdentity(); + AuditIdentity(uid_t uid, pid_t pid); + + std::string toString() const; + private: + uid_t _uid; + pid_t _pid; + }; + + class DLL_PUBLIC AuditEvent + { + AuditEvent(const AuditIdentity& identity); + public: + AuditEvent(AuditEvent&& event); + AuditEvent(const AuditEvent& event) = delete; + ~AuditEvent(); + + void success(); + void failure(); + + private: + void confirm(const std::string& result); + void setConfirmed(bool state); + std::string& refMessage(); + + bool _confirmed; + AuditIdentity _identity; + std::string _message; + + friend class Audit; + }; + + class DLL_PUBLIC Audit + { + public: + Audit(const AuditIdentity& identity); + + AuditEvent policyEvent(std::shared_ptr rule, Policy::EventType event); + AuditEvent policyEvent(std::shared_ptr new_rule, std::shared_ptr old_rule); + AuditEvent policyEvent(std::shared_ptr device, Policy::EventType event); + AuditEvent policyEvent(std::shared_ptr device, Rule::Target old_target, Rule::Target new_target); + + AuditEvent deviceEvent(std::shared_ptr device, DeviceManager::EventType event); + AuditEvent deviceEvent(std::shared_ptr new_device, std::shared_ptr old_device); + + /* + * 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 + */ + static AuditEvent policyEvent(const AuditIdentity& identity, std::shared_ptr rule, Policy::EventType event); + static AuditEvent policyEvent(const AuditIdentity& identity, std::shared_ptr new_rule, std::shared_ptr old_rule); + static AuditEvent policyEvent(const AuditIdentity& identity, std::shared_ptr device, Policy::EventType event); + static AuditEvent policyEvent(const AuditIdentity& identity, std::shared_ptr device, Rule::Target old_target, Rule::Target new_target); + + /* + * Audit device changes: + * - device insertion + * - device removal + * - device authorization target change + * + * Audit data: + * - who: uid + pid + * - when: time + * - what: insert, remove, authorization target + * - change: old, new + */ + static AuditEvent deviceEvent(const AuditIdentity& identity, std::shared_ptr device, DeviceManager::EventType event); + static AuditEvent deviceEvent(const AuditIdentity& identity, std::shared_ptr new_device, std::shared_ptr old_device); + + private: + AuditIdentity _identity; + }; +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/ConfigFile.cpp b/src/Library/public/usbguard/ConfigFile.cpp new file mode 100644 index 0000000..5d4c843 --- /dev/null +++ b/src/Library/public/usbguard/ConfigFile.cpp @@ -0,0 +1,66 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "ConfigFilePrivate.hpp" + +namespace usbguard +{ + ConfigFile::ConfigFile(const std::vector& known_names) + { + d_pointer = new ConfigFilePrivate(*this, known_names); + } + + ConfigFile::~ConfigFile() + { + delete d_pointer; + } + + void ConfigFile::open(const std::string& path) + { + d_pointer->open(path); + } + + void ConfigFile::write() + { + d_pointer->write(); + } + + void ConfigFile::close() + { + d_pointer->close(); + } + + const std::string& ConfigFile::getSettingValue(const std::string& name) const + { + return d_pointer->getSettingValue(name); + } + + void ConfigFile::setSettingValue(const std::string& name, std::string& value) + { + d_pointer->setSettingValue(name, value); + } + + bool ConfigFile::hasSettingValue(const std::string& name) const + { + return d_pointer->hasSettingValue(name); + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/ConfigFile.hpp b/src/Library/public/usbguard/ConfigFile.hpp new file mode 100644 index 0000000..44aaf8f --- /dev/null +++ b/src/Library/public/usbguard/ConfigFile.hpp @@ -0,0 +1,45 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Typedefs.hpp" + +#include +#include + +namespace usbguard { + class ConfigFilePrivate; + class DLL_PUBLIC ConfigFile + { + public: + ConfigFile(const std::vector& known_names = std::vector()); + ~ConfigFile(); + + void open(const std::string& path); + void write(); + void close(); + + void setSettingValue(const std::string& name, std::string& value); + bool hasSettingValue(const std::string& name) const; + const std::string& getSettingValue(const std::string& name) const; + + private: + ConfigFilePrivate* d_pointer; + }; +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Device.cpp b/src/Library/public/usbguard/Device.cpp new file mode 100644 index 0000000..49067c4 --- /dev/null +++ b/src/Library/public/usbguard/Device.cpp @@ -0,0 +1,199 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "DevicePrivate.hpp" + +namespace usbguard { + Device::Device(DeviceManager& manager) + { + d_pointer = new DevicePrivate(*this, manager); + } + + Device::~Device() + { + delete d_pointer; + d_pointer = nullptr; + } + + Device::Device(const Device& rhs) + { + d_pointer = new DevicePrivate(*this, *rhs.d_pointer); + } + + const Device& Device::operator=(const Device &rhs) + { + DevicePrivate* n_pointer = new DevicePrivate(*this, *rhs.d_pointer); + delete d_pointer; + d_pointer = n_pointer; + return *this; + } + + DeviceManager& Device::manager() const + { + return d_pointer->manager(); + } + + std::mutex& Device::refDeviceMutex() + { + return d_pointer->refDeviceMutex(); + } + + std::shared_ptr Device::getDeviceRule(const bool with_port, const bool with_parent_hash, const bool match_rule) + { + return d_pointer->getDeviceRule(with_port, with_parent_hash, match_rule); + } + + std::string Device::hashString(const std::string& value) const + { + return d_pointer->hashString(value); + } + + void Device::initializeHash() + { + d_pointer->initializeHash(); + } + + void Device::updateHash(const void * const ptr, const size_t size) + { + d_pointer->updateHash(ptr, size); + } + + void Device::updateHash(std::istream& descriptor_stream, const size_t expected_size) + { + d_pointer->updateHash(descriptor_stream, expected_size); + } + + std::string Device::finalizeHash() + { + return d_pointer->finalizeHash(); + } + + const std::string& Device::getHash() const + { + return d_pointer->getHash(); + } + + void Device::setParentHash(const std::string& hash) + { + d_pointer->setParentHash(hash); + } + + void Device::setID(uint32_t id) + { + d_pointer->setID(id); + } + + uint32_t Device::getID() const + { + return d_pointer->getID(); + } + + void Device::setParentID(uint32_t id) + { + d_pointer->setParentID(id); + } + + uint32_t Device::getParentID() const + { + return d_pointer->getParentID(); + } + + void Device::setTarget(Rule::Target target) + { + d_pointer->setTarget(target); + } + + Rule::Target Device::getTarget() const + { + return d_pointer->getTarget(); + } + + void Device::setName(const std::string& name) + { + d_pointer->setName(name); + } + + const std::string& Device::getName() const + { + return d_pointer->getName(); + } + + void Device::setDeviceID(const USBDeviceID& device_id) + { + d_pointer->setDeviceID(device_id); + } + + const USBDeviceID& Device::getDeviceID() const + { + return d_pointer->getDeviceID(); + } + + void Device::setPort(const std::string& port) + { + d_pointer->setPort(port); + } + + const std::string& Device::getPort() const + { + return d_pointer->getPort(); + } + + void Device::setSerial(const std::string& serial_number) + { + d_pointer->setSerial(serial_number); + } + + const std::string& Device::getSerial() const + { + return d_pointer->getSerial(); + } + + std::vector& Device::refMutableInterfaceTypes() + { + return d_pointer->refMutableInterfaceTypes(); + } + + const std::vector& Device::getInterfaceTypes() const + { + return d_pointer->getInterfaceTypes(); + } + + void Device::loadDeviceDescriptor(USBDescriptorParser* parser, const USBDescriptor* const descriptor) + { + d_pointer->loadDeviceDescriptor(parser, descriptor); + } + + void Device::loadConfigurationDescriptor(USBDescriptorParser* parser, const USBDescriptor* const descriptor) + { + d_pointer->loadConfigurationDescriptor(parser, descriptor); + } + + void Device::loadInterfaceDescriptor(USBDescriptorParser* parser, const USBDescriptor* const descriptor) + { + d_pointer->loadInterfaceDescriptor(parser, descriptor); + } + + void Device::loadEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* const descriptor) + { + d_pointer->loadEndpointDescriptor(parser, descriptor); + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Device.hpp b/src/Library/public/usbguard/Device.hpp new file mode 100644 index 0000000..d5a8130 --- /dev/null +++ b/src/Library/public/usbguard/Device.hpp @@ -0,0 +1,90 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Rule.hpp" +#include "Typedefs.hpp" +#include "USB.hpp" + +#include +#include +#include + +#include +#include + +namespace usbguard { + class DeviceManager; + class DevicePrivate; + class DLL_PUBLIC Device + { + public: + Device(DeviceManager& manager); + ~Device(); + Device(const Device& rhs); + const Device& operator=(const Device& rhs); + + DeviceManager& manager() const; + + std::mutex& refDeviceMutex(); + std::shared_ptr getDeviceRule(bool with_port = true, bool with_parent_hash = true, bool match_rule = false); + std::string hashString(const std::string& value) const; + void initializeHash(); + void updateHash(const void * ptr, size_t size); + void updateHash(std::istream& descriptor_stream, size_t expected_size); + std::string finalizeHash(); + const std::string& getHash() const; + + void setParentHash(const std::string& hash); + + void setID(uint32_t id); + uint32_t getID() const; + + void setParentID(uint32_t id); + uint32_t getParentID() const; + + void setTarget(Rule::Target target); + Rule::Target getTarget() const; + + void setName(const std::string& name); + const std::string& getName() const; + + void setDeviceID(const USBDeviceID& device_id); + const USBDeviceID& getDeviceID() const; + + void setPort(const std::string& port); + const std::string& getPort() const; + + void setSerial(const std::string& serial_number); + const std::string& getSerial() const; + + std::vector& refMutableInterfaceTypes(); + const std::vector& getInterfaceTypes() const; + + virtual bool isController() const = 0; + + void loadDeviceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); + void loadConfigurationDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); + void loadInterfaceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); + void loadEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); + + private: + DevicePrivate *d_pointer; + }; +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/DeviceManager.cpp b/src/Library/public/usbguard/DeviceManager.cpp new file mode 100644 index 0000000..f7282ad --- /dev/null +++ b/src/Library/public/usbguard/DeviceManager.cpp @@ -0,0 +1,180 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "DeviceManagerPrivate.hpp" + +#include "usbguard/DeviceManagerHooks.hpp" +#include "usbguard/Exception.hpp" + +namespace usbguard { + uint32_t DeviceManager::eventTypeToInteger(DeviceManager::EventType event) + { + return static_cast(event); + } + + DeviceManager::EventType DeviceManager::eventTypeFromInteger(uint32_t event_integer) + { + switch(event_integer) { + case static_cast(EventType::Insert): + case static_cast(EventType::Update): + case static_cast(EventType::Remove): + break; + default: + throw std::runtime_error("Invalid event type integer value"); + } + return static_cast(event_integer); + } + + std::string DeviceManager::eventTypeToString(DeviceManager::EventType event) + { + switch(event) { + case DeviceManager::EventType::Present: + return "Present"; + case DeviceManager::EventType::Insert: + return "Insert"; + case DeviceManager::EventType::Remove: + return "Remove"; + case DeviceManager::EventType::Update: + return "Update"; + default: + throw USBGUARD_BUG("unknown event type"); + } + } + + DeviceManager::DeviceManager(DeviceManagerHooks& hooks) + { + d_pointer = new DeviceManagerPrivate(*this, hooks); + } + + DeviceManager::DeviceManager(const DeviceManager& rhs) + { + d_pointer = new DeviceManagerPrivate(*this, *rhs.d_pointer); + } + + const DeviceManager& DeviceManager::operator=(const DeviceManager& rhs) + { + DeviceManagerPrivate* n_pointer = new DeviceManagerPrivate(*this, *rhs.d_pointer); + delete d_pointer; + d_pointer = n_pointer; + return *this; + } + + DeviceManager::~DeviceManager() + { + delete d_pointer; + d_pointer = nullptr; + } + + void DeviceManager::setRestoreControllerDeviceState(bool enabled) + { + d_pointer->setRestoreControllerDeviceState(enabled); + } + + bool DeviceManager::getRestoreControllerDeviceState() const + { + return d_pointer->getRestoreControllerDeviceState(); + } + + void DeviceManager::insertDevice(std::shared_ptr device) + { + d_pointer->insertDevice(device); + } + + std::shared_ptr DeviceManager::removeDevice(uint32_t id) + { + return d_pointer->removeDevice(id); + } + + std::vector> DeviceManager::getDeviceList() + { + return d_pointer->getDeviceList(); + } + + std::vector> DeviceManager::getDeviceList(const Rule& query) + { + std::vector> matching_devices; + + for (auto const& device : getDeviceList()) { + if (query.appliesTo(device->getDeviceRule())) { + switch(query.getTarget()) { + case Rule::Target::Allow: + case Rule::Target::Block: + if (device->getTarget() == query.getTarget()) { + matching_devices.push_back(device); + } + break; + case Rule::Target::Device: + case Rule::Target::Match: + matching_devices.push_back(device); + break; + case Rule::Target::Reject: + case Rule::Target::Unknown: + case Rule::Target::Invalid: + default: + throw std::runtime_error("Invalid device query target"); + } + } + } + + return matching_devices; + } + + std::shared_ptr DeviceManager::getDevice(uint32_t id) + { + return d_pointer->getDevice(id); + } + + void DeviceManager::DeviceEvent(DeviceManager::EventType event, std::shared_ptr device) + { + d_pointer->DeviceEvent(event, device); + } + + void DeviceManager::DeviceException(const std::string& message) + { + d_pointer->DeviceException(message); + } +} /* namespace usbguard */ + +#if defined(HAVE_UEVENT) +# include "UEventDeviceManager.hpp" +#endif + +std::shared_ptr usbguard::DeviceManager::create(DeviceManagerHooks& hooks, const std::string& backend) +{ +#if defined(HAVE_UEVENT) + if (backend == "udev") { + USBGUARD_LOG(Warning) << "udev backend is OBSOLETE. Falling back to new default: uevent"; + } + if (backend == "uevent" || /* transition udev => uevent */backend == "udev") { + return std::make_shared(hooks); + } + if (backend == "dummy") { + const char * const device_root_cstr = getenv("USBGUARD_DUMMY_DEVICE_ROOT"); + if (device_root_cstr == nullptr) { + throw Exception("DeviceManager", "dummy", "USBGUARD_DUMMY_DEVICE_ROOT environment variable not defined"); + } + const std::string device_root(device_root_cstr); + return std::make_shared(hooks, device_root, /*dummy_mode=*/true); + } +#endif + throw Exception("DeviceManager", "backend", "requested backend is not available"); +} diff --git a/src/Library/public/usbguard/DeviceManager.hpp b/src/Library/public/usbguard/DeviceManager.hpp new file mode 100644 index 0000000..89b09d1 --- /dev/null +++ b/src/Library/public/usbguard/DeviceManager.hpp @@ -0,0 +1,87 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Device.hpp" +#include "Rule.hpp" +#include "RuleSet.hpp" +#include "Typedefs.hpp" + +#include +#include +#include +#include + +#include + +namespace usbguard { + class DeviceManagerHooks; + class DeviceManagerPrivate; + class DLL_PUBLIC DeviceManager + { + public: + enum class EventType { + Present = 0, + Insert = 1, + Update = 2, /* use case: writable attribute changed externally */ + Remove = 3, + }; + + static uint32_t eventTypeToInteger(EventType event); + static EventType eventTypeFromInteger(uint32_t event_integer); + static std::string eventTypeToString(EventType event); + + DeviceManager(DeviceManagerHooks& hooks); + DeviceManager(const DeviceManager& rhs); + const DeviceManager& operator=(const DeviceManager& rhs); + + virtual ~DeviceManager(); + + virtual void setDefaultBlockedState(bool state) = 0; + virtual void setEnumerationOnlyMode(bool state) = 0; + virtual void start() = 0; + virtual void stop() = 0; + virtual void scan() = 0; + + void setRestoreControllerDeviceState(bool enabled); + bool getRestoreControllerDeviceState() const; + + virtual std::shared_ptr applyDevicePolicy(uint32_t id, Rule::Target target) = 0; + + virtual void insertDevice(std::shared_ptr device); + std::shared_ptr removeDevice(uint32_t id); + + /* Returns a copy of the list of active USB devices */ + std::vector> getDeviceList(); + std::vector> getDeviceList(const Rule& query); + + std::shared_ptr getDevice(uint32_t id); + std::mutex& refDeviceMapMutex(); + + /* Call Daemon instance hooks */ + void DeviceEvent(EventType event, std::shared_ptr device); + void DeviceException(const std::string& message); + + static std::shared_ptr create(DeviceManagerHooks& hooks, const std::string& backend); + + private: + DeviceManagerPrivate *d_pointer; + }; + +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/DeviceManagerHooks.cpp b/src/Library/public/usbguard/DeviceManagerHooks.cpp new file mode 100644 index 0000000..8c31941 --- /dev/null +++ b/src/Library/public/usbguard/DeviceManagerHooks.cpp @@ -0,0 +1,33 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/DeviceManagerHooks.hpp" + +namespace usbguard +{ + void DeviceManagerHooks::dmHookDeviceEvent(DeviceManager::EventType event, std::shared_ptr device) + { + (void)event; + (void)device; + /* NOOP */ + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/DeviceManagerHooks.hpp b/src/Library/public/usbguard/DeviceManagerHooks.hpp new file mode 100644 index 0000000..c85ee3a --- /dev/null +++ b/src/Library/public/usbguard/DeviceManagerHooks.hpp @@ -0,0 +1,39 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Device.hpp" +#include "DeviceManager.hpp" +#include "Typedefs.hpp" + +#include +#include + +#include + +namespace usbguard +{ + class DLL_PUBLIC DeviceManagerHooks + { + public: + virtual void dmHookDeviceEvent(DeviceManager::EventType event, std::shared_ptr device); + virtual uint32_t dmHookAssignID() = 0; + virtual void dmHookDeviceException(const std::string& message) = 0; + }; +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Exception.hpp b/src/Library/public/usbguard/Exception.hpp new file mode 100644 index 0000000..a46d9ee --- /dev/null +++ b/src/Library/public/usbguard/Exception.hpp @@ -0,0 +1,180 @@ +// +// Copyright (C) 2016 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Typedefs.hpp" + +#include +#include + +#ifndef _GNU_SOURCE +# define _GNU_SOURCE +#endif + +#include +#include +#include + +namespace usbguard +{ + class DLL_PUBLIC Exception : public std::exception + { + public: + Exception(const std::string& context, + const std::string& object, + const std::string& reason_val) + : _context(context), + _object(object), + _reason(reason_val) + { + } + + Exception(const Exception& rhs) + : _context(rhs._context), + _object(rhs._object), + _reason(rhs._reason) + { + } + + const std::string& context() const noexcept + { + return _context; + } + + const std::string& object() const noexcept + { + return _object; + } + + const std::string& reason() const noexcept + { + return _reason; + } + + void setContext(const std::string& context) + { + _context = context; + } + + void setObject(const std::string& object) + { + _object = object; + } + + void setReason(const std::string& reason_val) + { + _reason = reason_val; + } + + virtual std::string message() const noexcept + { + try { + return _context + ": " + (!_object.empty() ? _object + ": " : "") + _reason; + } + catch(...) { + return "usbguard::Exception: exception^2"; + } + } + + virtual const char * what() const noexcept + { + return "usbguard::Exception"; + } + + private: + std::string _context; + std::string _object; + std::string _reason; + }; + +#define USBGUARD_BUG(m) \ + ::usbguard::Exception(__PRETTY_FUNCTION__, "BUG", m) + + class ErrnoException : public Exception + { + public: + ErrnoException(const std::string& context, const std::string& object, const int errno_value) + : Exception(context, object, ErrnoException::reasonFromErrno(errno_value)) + { + } + private: + static std::string reasonFromErrno(const int errno_value) + { + char buffer[1024]; + return std::string(strerror_r(errno_value, buffer, sizeof buffer)); + } + }; + +#define USBGUARD_SYSCALL_THROW(context, syscall_bool_expression) \ + do { \ + if (syscall_bool_expression) { \ + throw usbguard::ErrnoException(context, #syscall_bool_expression, errno); \ + } \ + } while(0) + + class IPCException : public Exception + { + public: + IPCException() + : Exception("", "", ""), + _message_id(0) + { + } + + IPCException(const Exception& exception, + uint64_t message_id = 0) + : Exception(exception), + _message_id(message_id) + { + } + + IPCException(const std::string& context, + const std::string& object, + const std::string& reason, + uint64_t message_id = 0) + : Exception(context, object, reason), + _message_id(message_id) + { + } + + IPCException(const IPCException& rhs) + : Exception(rhs), + _message_id(rhs._message_id) + { + } + + bool hasMessageID() const noexcept + { + return _message_id != 0; + } + + uint64_t messageID() const noexcept + { + return _message_id; + } + + void setMessageID(uint64_t message_id) + { + _message_id = message_id; + } + + private: + uint64_t _message_id; + }; +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/IPCClient.cpp b/src/Library/public/usbguard/IPCClient.cpp new file mode 100644 index 0000000..4f4e08f --- /dev/null +++ b/src/Library/public/usbguard/IPCClient.cpp @@ -0,0 +1,91 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "IPCClientPrivate.hpp" + +namespace usbguard +{ + IPCClient::IPCClient(bool connected) + { + d_pointer = new IPCClientPrivate(*this, connected); + } + + IPCClient::~IPCClient() + { + delete d_pointer; + } + + void IPCClient::connect() + { + d_pointer->connect(); + } + + void IPCClient::disconnect() + { + d_pointer->disconnect(/*do_wait*/true); + } + + bool IPCClient::isConnected() const + { + return d_pointer->isConnected(); + } + + void IPCClient::wait() + { + d_pointer->wait(); + } + + std::string IPCClient::setParameter(const std::string& name, const std::string& value) + { + return d_pointer->setParameter(name, value); + } + + std::string IPCClient::getParameter(const std::string& name) + { + return d_pointer->getParameter(name); + } + + uint32_t IPCClient::appendRule(const std::string& rule_spec, uint32_t parent_id) + { + return d_pointer->appendRule(rule_spec, parent_id); + } + + void IPCClient::removeRule(uint32_t id) + { + d_pointer->removeRule(id); + } + + const RuleSet IPCClient::listRules(const std::string& query) + { + return d_pointer->listRules(query); + } + + uint32_t IPCClient::applyDevicePolicy(uint32_t id, Rule::Target target, bool permanent) + { + return d_pointer->applyDevicePolicy(id, target, permanent); + } + + const std::vector IPCClient::listDevices(const std::string& query) + { + return d_pointer->listDevices(query); + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/IPCClient.hpp b/src/Library/public/usbguard/IPCClient.hpp new file mode 100644 index 0000000..8ed62ed --- /dev/null +++ b/src/Library/public/usbguard/IPCClient.hpp @@ -0,0 +1,108 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "DeviceManager.hpp" +#include "Exception.hpp" +#include "Interface.hpp" +#include "Typedefs.hpp" + +#include +#include + +#include + +namespace usbguard +{ + class IPCClientPrivate; + class DLL_PUBLIC IPCClient : public Interface + { + public: + IPCClient(bool connected = false); + virtual ~IPCClient(); + + void connect(); + void disconnect(); + bool isConnected() const; + void wait(); + + std::string setParameter(const std::string& name, const std::string& value) override; + std::string getParameter(const std::string& name) override; + + uint32_t appendRule(const std::string& rule_spec, uint32_t parent_id) override; + void removeRule(uint32_t id) override; + const RuleSet listRules(const std::string& query) override; + const RuleSet listRules() + { + return listRules("match"); + } + + uint32_t applyDevicePolicy(uint32_t id, Rule::Target target, bool permanent) override; + const std::vector listDevices(const std::string& query) override; + const std::vector listDevices() /* NOTE: left for compatibility */ + { + return listDevices("match"); + } + + virtual void IPCConnected() {} + + virtual void IPCDisconnected(bool exception_initiated, const IPCException& exception) + { + (void)exception_initiated; + (void)exception; + } + + virtual void DevicePresenceChanged(uint32_t id, + DeviceManager::EventType event, + Rule::Target target, + const std::string& device_rule) override + { + (void)id; + (void)event; + (void)target; + (void)device_rule; + } + + virtual void DevicePolicyChanged(uint32_t id, + Rule::Target target_old, + Rule::Target target_new, + const std::string& device_rule, + uint32_t rule_id) override + { + (void)id; + (void)target_old; + (void)target_new; + (void)device_rule; + (void)rule_id; + } + + virtual void ExceptionMessage(const std::string& context, + const std::string& object, + const std::string& reason) override + { + (void)context; + (void)object; + (void)reason; + } + + private: + IPCClientPrivate* d_pointer; + }; + +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/IPCServer.cpp b/src/Library/public/usbguard/IPCServer.cpp new file mode 100644 index 0000000..adb2644 --- /dev/null +++ b/src/Library/public/usbguard/IPCServer.cpp @@ -0,0 +1,310 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "IPCServerPrivate.hpp" +#include "Common/Utility.hpp" + +#include "usbguard/Exception.hpp" + +#include +#include + +namespace usbguard +{ + void IPCServer::checkAccessControlName(const std::string& name) + { + if (name.size() > 32) { + throw Exception("IPC access control", "name too long", name); + } + + const std::string valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + + if (name.find_first_not_of(valid_chars) != std::string::npos) { + throw Exception("IPC access control", "name contains invalid character(s)", name); + } + + } + + static const std::vector> section_ttable = { + { "ALL", IPCServer::AccessControl::Section::ALL }, + { "Policy", IPCServer::AccessControl::Section::POLICY }, + { "Parameters", IPCServer::AccessControl::Section::PARAMETERS }, + { "Devices", IPCServer::AccessControl::Section::DEVICES }, + { "Exceptions", IPCServer::AccessControl::Section::EXCEPTIONS }, + { "None", IPCServer::AccessControl::Section::NONE } + }; + + IPCServer::AccessControl::Section IPCServer::AccessControl::sectionFromString(const std::string& section_string) + { + for (auto ttable_entry : section_ttable) { + if (ttable_entry.first == section_string) { + return ttable_entry.second; + } + } + throw std::runtime_error("Invalid AccessControl::Section string"); + } + + std::string IPCServer::AccessControl::sectionToString(const IPCServer::AccessControl::Section section) + { + for (auto ttable_entry : section_ttable) { + if (ttable_entry.second == section) { + return ttable_entry.first; + } + } + throw std::runtime_error("Invalid AccessControl::Section value"); + } + + static const std::vector> privilege_ttable = { + { "ALL", IPCServer::AccessControl::Privilege::ALL }, + { "modify", IPCServer::AccessControl::Privilege::MODIFY }, + { "list", IPCServer::AccessControl::Privilege::LIST }, + { "listen", IPCServer::AccessControl::Privilege::LISTEN }, + { "none", IPCServer::AccessControl::Privilege::NONE } + }; + + IPCServer::AccessControl::Privilege IPCServer::AccessControl::privilegeFromString(const std::string& privilege_string) + { + for (auto ttable_entry : privilege_ttable) { + if (ttable_entry.first == privilege_string) { + return ttable_entry.second; + } + } + throw std::runtime_error("Invalid AccessControl::Section string"); + } + + std::string IPCServer::AccessControl::privilegeToString(const IPCServer::AccessControl::Privilege privilege) + { + for (auto ttable_entry : privilege_ttable) { + if (ttable_entry.second == privilege) { + return ttable_entry.first; + } + } + throw std::runtime_error("Invalid AccessControl::Privilege value"); + } + + IPCServer::AccessControl::AccessControl() + { + /* Empty: no privileges */ + } + + IPCServer::AccessControl::AccessControl(const std::string& access_control_string) + { + std::stringstream ss(access_control_string); + load(ss); + } + + IPCServer::AccessControl::AccessControl(IPCServer::AccessControl::Section section, IPCServer::AccessControl::Privilege privilege) + { + setPrivilege(section, privilege); + } + + IPCServer::AccessControl::AccessControl(const IPCServer::AccessControl& rhs) + : _access_control(rhs._access_control) + { + } + + IPCServer::AccessControl& IPCServer::AccessControl::operator=(const IPCServer::AccessControl& rhs) + { + _access_control = rhs._access_control; + return *this; + } + + bool IPCServer::AccessControl::hasPrivilege(IPCServer::AccessControl::Section section, IPCServer::AccessControl::Privilege privilege) const + { + if (section == Section::ALL || section == Section::NONE) { + throw USBGUARD_BUG("Cannot test against ALL, NONE sections"); + } + + const auto it = _access_control.find(section); + + if (it == _access_control.cend()) { + return false; + } + + return (it->second & static_cast(privilege)) == static_cast(privilege); + } + + void IPCServer::AccessControl::setPrivilege(IPCServer::AccessControl::Section section, IPCServer::AccessControl::Privilege privilege) + { + if (section == Section::NONE) { + throw USBGUARD_BUG("Cannot set privileges for NONE section"); + } + if (section == Section::ALL) { + for (const auto& value : { + Section::POLICY, + Section::PARAMETERS, + Section::EXCEPTIONS, + Section::DEVICES }) { + _access_control[value] |= static_cast(privilege); + } + } + else { + _access_control[section] |= static_cast(privilege); + } + } + + void IPCServer::AccessControl::clear() + { + _access_control.clear(); + } + + void IPCServer::AccessControl::load(std::istream& stream) + { + std::string line; + size_t line_number = 0; + + while (std::getline(stream, line)) { + ++line_number; + const size_t nv_separator = line.find_first_of("="); + + if (nv_separator == std::string::npos) { + continue; + } + + const std::string section_string = trim(line.substr(0, nv_separator)); + const Section section = sectionFromString(section_string); + + const std::string privileges_string = line.substr(nv_separator + 1); + std::vector privilege_strings; + tokenizeString(privileges_string, privilege_strings, " ,", /*trim_empty=*/true); + + for (const std::string& privilege_string : privilege_strings) { + const Privilege privilege = privilegeFromString(privilege_string); + setPrivilege(section, privilege); + } + } + } + + void IPCServer::AccessControl::save(std::ostream& stream) const + { + std::string access_control_string; + + for (auto const& section : { + Section::DEVICES, + Section::POLICY, + Section::PARAMETERS, + Section::EXCEPTIONS + }) { + bool section_is_empty = true; + std::string section_string = sectionToString(section); + section_string.append("="); + + for (auto const& privilege : { + Privilege::LIST, + Privilege::MODIFY, + Privilege::LISTEN + }) { + if (hasPrivilege(section, privilege)) { + const std::string privilege_string = privilegeToString(privilege); + section_string.append(privilege_string); + section_string.append(","); + section_is_empty = false; + } + } + + if (!section_is_empty) { + section_string.pop_back(); + access_control_string.append(section_string); + access_control_string.append("\n"); + } + } + + stream << access_control_string; + } + + void IPCServer::AccessControl::merge(const IPCServer::AccessControl& rhs) + { + for (auto const& ac_entry : rhs._access_control) { + _access_control[ac_entry.first] |= ac_entry.second; + } + } + + void IPCServer::AccessControl::merge(const std::string& access_control_string) + { + const AccessControl access_control(access_control_string); + merge(access_control); + } + + IPCServer::IPCServer() + { + d_pointer = new IPCServerPrivate(*this); + } + + IPCServer::~IPCServer() + { + delete d_pointer; + } + + void IPCServer::start() + { + d_pointer->start(); + } + + void IPCServer::stop() + { + d_pointer->stop(); + } + + void IPCServer::DevicePresenceChanged(uint32_t id, + DeviceManager::EventType event, + Rule::Target target, + const std::string& device_rule) + { + d_pointer->DevicePresenceChanged(id, event, target, device_rule); + } + + void IPCServer::DevicePolicyChanged(uint32_t id, + Rule::Target target_old, + Rule::Target target_new, + const std::string& device_rule, + uint32_t rule_id) + { + d_pointer->DevicePolicyChanged(id, target_old, target_new, device_rule, rule_id); + } + + void IPCServer::ExceptionMessage(const std::string& context, + const std::string& object, + const std::string& reason) + { + d_pointer->ExceptionMessage(context, object, reason); + } + + void IPCServer::addAllowedUID(uid_t uid, const IPCServer::AccessControl& ac) + { + d_pointer->addAllowedUID(uid, ac); + } + + void IPCServer::addAllowedGID(gid_t gid, const IPCServer::AccessControl& ac) + { + d_pointer->addAllowedGID(gid, ac); + } + + void IPCServer::addAllowedUsername(const std::string& username, const IPCServer::AccessControl& ac) + { + d_pointer->addAllowedUsername(username, ac); + } + + void IPCServer::addAllowedGroupname(const std::string& groupname, const IPCServer::AccessControl& ac) + { + d_pointer->addAllowedGroupname(groupname, ac); + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/IPCServer.hpp b/src/Library/public/usbguard/IPCServer.hpp new file mode 100644 index 0000000..cf0242b --- /dev/null +++ b/src/Library/public/usbguard/IPCServer.hpp @@ -0,0 +1,126 @@ +// +// Copyright (C) 2016 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "DeviceManager.hpp" +#include "Interface.hpp" +#include "Rule.hpp" +#include "Typedefs.hpp" + +#include +#include +#include +#include + +#include +#include + +#include +#include + +namespace usbguard +{ + class IPCServerPrivate; + class DLL_PUBLIC IPCServer : public Interface + { + public: + static void checkAccessControlName(const std::string& name); + + class AccessControl + { + public: + enum class Section : uint8_t { + NONE = 0, + DEVICES = 1, + POLICY = 2, + PARAMETERS = 3, + EXCEPTIONS = 4, + ALL = 255 + }; + + static Section sectionFromString(const std::string& section_string); + static std::string sectionToString(const Section section); + + enum class Privilege : uint8_t { + NONE = 0x00, + LIST = 0x01, + MODIFY = 0x02, + LISTEN = 0x08, + ALL = 0xff + }; + + static Privilege privilegeFromString(const std::string& privilege_string); + static std::string privilegeToString(const Privilege privilege); + + AccessControl(); + AccessControl(const std::string& access_control_string); + AccessControl(Section section, Privilege privilege); + AccessControl(const AccessControl& rhs); + AccessControl& operator=(const AccessControl& rhs); + + bool hasPrivilege(Section section, Privilege privilege) const; + void setPrivilege(Section section, Privilege privilege); + void clear(); + void load(std::istream& stream); + void save(std::ostream& stream) const; + void merge(const AccessControl& rhs); + void merge(const std::string& access_control_string); + + private: + struct SectionHash { + std::size_t operator()(Section value) const + { + return static_cast(value); + } + }; + + std::unordered_map _access_control; + }; + + IPCServer(); + virtual ~IPCServer(); + + void start(); + void stop(); + + void DevicePresenceChanged(uint32_t id, + DeviceManager::EventType event, + Rule::Target target, + const std::string& device_rule); + + void DevicePolicyChanged(uint32_t id, + Rule::Target target_old, + Rule::Target target_new, + const std::string& device_rule, + uint32_t rule_id); + + void ExceptionMessage(const std::string& context, + const std::string& object, + const std::string& reason); + + void addAllowedUID(uid_t uid, const IPCServer::AccessControl& ac); + void addAllowedGID(gid_t gid, const IPCServer::AccessControl& ac); + void addAllowedUsername(const std::string& username, const IPCServer::AccessControl& ac); + void addAllowedGroupname(const std::string& groupname, const IPCServer::AccessControl& ac); + + private: + IPCServerPrivate* d_pointer; + }; +} /* namespace usbguard */ + diff --git a/src/Library/public/usbguard/Interface.hpp b/src/Library/public/usbguard/Interface.hpp new file mode 100644 index 0000000..41f7024 --- /dev/null +++ b/src/Library/public/usbguard/Interface.hpp @@ -0,0 +1,72 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "DeviceManager.hpp" +#include "Rule.hpp" +#include "RuleSet.hpp" +#include "Typedefs.hpp" +#include "USB.hpp" + +#include +#include +#include + +#include + +namespace usbguard +{ + class DLL_PUBLIC Interface + { + public: + /* Parameters */ + virtual std::string setParameter(const std::string& name, const std::string& value) = 0; + virtual std::string getParameter(const std::string& name) = 0; + + /* Methods */ + virtual uint32_t appendRule(const std::string& rule_spec, + uint32_t parent_id) = 0; + + virtual void removeRule(uint32_t id) = 0; + + virtual const RuleSet listRules(const std::string& query) = 0; + + virtual uint32_t applyDevicePolicy(uint32_t id, + Rule::Target target, + bool permanent) = 0; + + virtual const std::vector listDevices(const std::string& query) = 0; + + /* Signals */ + virtual void DevicePresenceChanged(uint32_t id, + DeviceManager::EventType event, + Rule::Target target, + const std::string& device_rule) = 0; + + virtual void DevicePolicyChanged(uint32_t id, + Rule::Target target_old, + Rule::Target target_new, + const std::string& device_rule, + uint32_t rule_id) = 0; + + virtual void ExceptionMessage(const std::string& context, + const std::string& object, + const std::string& reason) = 0; + }; +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Logger.cpp b/src/Library/public/usbguard/Logger.cpp new file mode 100644 index 0000000..762b5b6 --- /dev/null +++ b/src/Library/public/usbguard/Logger.cpp @@ -0,0 +1,411 @@ +// +// Copyright (C) 2016 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "Common/Utility.hpp" + +#include "usbguard/Logger.hpp" +#include "usbguard/Exception.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif +#include + +namespace usbguard +{ + /* Instantiate the logger */ + Logger G_logger; + + const std::string LogStream::sourceToString(const Source& source) + { + return source.file + "@" + std::to_string(source.line) + "/" + source.function; + } + + const std::string LogStream::levelToString(Level level) + { + switch (level) { + case LogStream::Level::Audit: + return "(A)"; + case LogStream::Level::Error: + return "(E)"; + case LogStream::Level::Warning: + return "(W)"; + case LogStream::Level::Info: + return "(i)"; + case LogStream::Level::Debug: + return "(D)"; + case LogStream::Level::Trace: + return "(T)"; + default: + throw std::runtime_error("BUG: unknown LogStream level value"); + } + } + + LogStream::LogStream(Logger& logger, const Source& source, const Level level) + : _logger(logger), + _source(source), + _level(level) + { + } + + LogStream::LogStream(const LogStream& rhs) + : std::basic_ios(), + std::ostringstream(rhs.str()), + _logger(rhs._logger), + _source(rhs._source), + _level(rhs._level) + { + } + + LogStream::~LogStream() + { + _logger.write(_source, _level, str()); + } + + LogSink::LogSink(const std::string& name) + : _name(name) + { + } + + LogSink::~LogSink() + { + } + + const std::string& LogSink::name() const + { + return _name; + } + + /* + * Internally required sinks + */ + class OStreamSink : public LogSink + { + public: + OStreamSink(const std::string& name, std::ostream& stream) + : LogSink(name), + _ostream(stream) + { + } + + void write(const LogStream::Source& source, LogStream::Level level, const std::string& message) + { + _ostream << '[' << Logger::timestamp() << "] "; + _ostream << LogStream::levelToString(level) << " "; + if (level >= LogStream::Level::Debug) { + _ostream << LogStream::sourceToString(source) << ": "; + } + _ostream << message; + _ostream << std::endl; + } + + ~OStreamSink() + { + _ostream.flush(); + } + private: + std::ostream& _ostream; + }; + + class ConsoleSink : public OStreamSink + { + public: + ConsoleSink() + : OStreamSink("console", std::clog) + { + } + }; + + class SyslogSink : public LogSink + { + public: + SyslogSink(const std::string& ident) + : LogSink("syslog"), + _ident(ident) + { + openlog(_ident.c_str(), LOG_NDELAY|LOG_PID|LOG_CONS, LOG_DAEMON); + } + + ~SyslogSink() + { + closelog(); + } + + int levelToPriority(const LogStream::Level level) + { + switch (level) { + case LogStream::Level::Audit: + return LOG_NOTICE; + case LogStream::Level::Error: + return LOG_ERR; + case LogStream::Level::Warning: + return LOG_WARNING; + case LogStream::Level::Info: + return LOG_INFO; + case LogStream::Level::Debug: + case LogStream::Level::Trace: + return LOG_DEBUG; + default: + throw USBGUARD_BUG("Invalid LogStream::Level value"); + } + } + + void write(const LogStream::Source& source, LogStream::Level level, const std::string& message) + { + std::string log_message; + + if (level >= LogStream::Level::Debug) { + log_message.append(LogStream::sourceToString(source)); + log_message.append(": "); + } + log_message.append(message); + + syslog(levelToPriority(level), "%s", log_message.c_str()); + } + + private: + std::string _ident; + }; + + class FileSink : public OStreamSink + { + public: + FileSink(const std::string& filepath, bool append = true) + : OStreamSink("file", _stream) + { + _filepath = filepath; + _stream.open(filepath, append ? std::fstream::app : std::fstream::trunc); + } + + ~FileSink() + { + _stream.close(); + } + private: + std::string _filepath; + std::ofstream _stream; + }; + + class AuditFileSink : public OStreamSink + { + public: + AuditFileSink(const std::string& filepath) + : OStreamSink("auditfile", _stream) + { + _filepath = filepath; + const auto saved_umask = umask(0177); + try { + _stream.open(filepath, std::fstream::app); + } + catch(...) { + umask(saved_umask); + throw; + } + umask(saved_umask); + } + + void write(const LogStream::Source& source, LogStream::Level level, const std::string& message) + { + /* + * AuditFileSink logs only Audit level messages. + */ + if (level == LogStream::Level::Audit) { + OStreamSink::write(source, level, message); + } + } + + ~AuditFileSink() + { + _stream.close(); + } + private: + std::string _filepath; + std::ofstream _stream; + }; + + Logger::Logger() + : _enabled(true), + _level(LogStream::Level::Warning) + { + const char * const envval = getenv("USBGUARD_DEBUG"); + /* + * If USBGUARD_DEBUG=1 is set in the current environment, + * set the debugging level to the highest level. + */ + if (envval != nullptr && strcmp(envval, "1") == 0) { + _level = LogStream::Level::Trace; + } + setOutputConsole(true); + } + + Logger::~Logger() + { + } + + std::unique_lock Logger::lock() const + { + return std::unique_lock(_mutex); + } + + void Logger::setEnabled(bool state, LogStream::Level level) + { + auto L = lock(); + _enabled = state; + _level = level; + } + + bool Logger::isEnabled(LogStream::Level level) const + { + auto L = lock(); + return (_enabled && _level >= level); + } + + void Logger::setOutputConsole(const bool state) + { + auto L = lock(); + if (state == true) { + std::unique_ptr sink(new ConsoleSink); + addOutputSink_nolock(sink); + } + else { + delOutputSink_nolock("console"); + } + } + + void Logger::setOutputFile(bool state, const std::string& filepath, bool append) + { + auto L = lock(); + if (state == true) { + std::unique_ptr sink(new FileSink(filepath, append)); + addOutputSink_nolock(sink); + } + else { + delOutputSink_nolock("file"); + } + } + + void Logger::setOutputSyslog(bool state, const std::string& ident) + { + auto L = lock(); + if (state == true) { + std::unique_ptr sink(new SyslogSink(ident)); + addOutputSink_nolock(sink); + } + else { + delOutputSink_nolock("syslog"); + } + } + + void Logger::setAuditFile(bool state, const std::string& filepath) + { + auto L = lock(); + if (state == true) { + std::unique_ptr sink(new AuditFileSink(filepath)); + addOutputSink_nolock(sink); + } + else { + delOutputSink_nolock("auditfile"); + } + } + + void Logger::addOutputSink(std::unique_ptr& sink) + { + auto L = lock(); + addOutputSink_nolock(sink); + } + + void Logger::addOutputSink_nolock(std::unique_ptr& sink) + { + _sinks.emplace(sink->name(), std::move(sink)); + } + + void Logger::delOutputSink(const std::string& name) + { + auto L = lock(); + delOutputSink_nolock(name); + } + + void Logger::delOutputSink_nolock(const std::string& name) + { + _sinks.erase(name); + } + + LogStream Logger::operator()(const std::string& file, const int line, const std::string& function, LogStream::Level level) + { + const LogStream::Source source = { + filenameFromPath(file, /*include_extension=*/true), line, function + }; + return LogStream(*this, source, level); + } + + void Logger::write(const LogStream::Source& source, const LogStream::Level level, const std::string& message) + { + auto L = lock(); + for (auto& kv_pair : _sinks) { + auto& sink = kv_pair.second; + try { + sink->write(source, level, message); + } + catch(const std::exception& ex) { + std::cerr << "Warning: sink->write failed for " << sink->name() << " sink: " << ex.what() << std::endl; + } + } + } + + /* + * Generate a timestamp string in the form: + * . + */ + const std::string Logger::timestamp() + { + struct timeval tv_now = { 0, 0 }; + + if (gettimeofday(&tv_now, nullptr) != 0) { + throw std::runtime_error("gettimeofday"); + } + + /* + * The following piece of code should work fine until + * Sat Nov 20 17:46:39 UTC 2286. + */ + char buffer[16]; + const int length = snprintf(buffer, sizeof buffer, "%.10" PRIu64 ".%03" PRIu64, + (uint64_t)tv_now.tv_sec, + (uint64_t)(tv_now.tv_usec / 1000)); + + if (length < 1 || static_cast(length) > (sizeof buffer - 1)) { + throw std::runtime_error("Failed to convert timestamp to string"); + } + + return std::string(buffer, (size_t)length); + } +} /* namespace usbguard */ + diff --git a/src/Library/public/usbguard/Logger.hpp b/src/Library/public/usbguard/Logger.hpp new file mode 100644 index 0000000..82fb341 --- /dev/null +++ b/src/Library/public/usbguard/Logger.hpp @@ -0,0 +1,136 @@ +// +// Copyright (C) 2016 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Typedefs.hpp" + +#include +#include +#include +#include +#include +#include + +namespace usbguard +{ + class Logger; + + class DLL_PUBLIC LogStream : public std::ostringstream + { + public: + struct Source { + std::string file; + int line; + std::string function; + }; + + static const std::string sourceToString(const Source& source); + + enum class Level : int { + Audit = -2, + Error = -1, + Warning = 0, + Info = 1, + Debug = 2, + Trace = 3 + }; + + static const std::string levelToString(Level level); + + LogStream(Logger& logger, const Source& source, Level level); + LogStream(const LogStream& rhs); + + ~LogStream(); + + private: + Logger& _logger; + Source _source; + Level _level; + }; + + class DLL_PUBLIC LogSink + { + public: + LogSink(const std::string& name); + virtual ~LogSink(); + + const std::string& name() const; + + virtual void write(const LogStream::Source& source, LogStream::Level level, const std::string& message) = 0; + + private: + std::string _name; + }; + + class DLL_PUBLIC Logger + { + public: + Logger(); + ~Logger(); + + void setEnabled(bool state, LogStream::Level level = LogStream::Level::Warning); + bool isEnabled(LogStream::Level level) const; + + void setOutputConsole(bool state); + void setOutputFile(bool state, const std::string& filepath = std::string(), bool append = true); + void setOutputSyslog(bool state, const std::string& ident = std::string()); + void setAuditFile(bool state, const std::string& filepath); + + void addOutputSink(std::unique_ptr& sink); + void delOutputSink(const std::string& name); + + LogStream operator()(const std::string& file, int line, const std::string& function, LogStream::Level level); + + void write(const LogStream::Source& source, LogStream::Level level, const std::string& message); + + /* + * Generate a timestamp string in the form: + * . + */ + static const std::string timestamp(); + + private: + void addOutputSink_nolock(std::unique_ptr& sink); + void delOutputSink_nolock(const std::string& name); + + std::unique_lock lock() const; + + mutable std::mutex _mutex; + bool _enabled; + LogStream::Level _level; + std::map> _sinks; + }; + + extern DLL_PUBLIC Logger G_logger; + +#if defined(__GNUC__) +# define USBGUARD_SOURCE_FILE __BASE_FILE__ +#else +# define USBGUARD_SOURCE_FILE __FILE__ +#endif + +#define USBGUARD_LOGGER usbguard::G_logger + +#define USBGUARD_FUNCTION __func__ + +#define USBGUARD_LOG(level) \ + if (USBGUARD_LOGGER.isEnabled(usbguard::LogStream::Level::level)) \ + USBGUARD_LOGGER(USBGUARD_SOURCE_FILE, __LINE__, USBGUARD_FUNCTION, usbguard::LogStream::Level::level) + +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Policy.cpp b/src/Library/public/usbguard/Policy.cpp new file mode 100644 index 0000000..9838239 --- /dev/null +++ b/src/Library/public/usbguard/Policy.cpp @@ -0,0 +1,41 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/Policy.hpp" +#include "usbguard/Exception.hpp" + +namespace usbguard +{ + std::string Policy::eventTypeToString(Policy::EventType event) + { + switch(event) { + case Policy::EventType::Insert: + return "Insert"; + case Policy::EventType::Update: + return "Update"; + case Policy::EventType::Remove: + return "Remove"; + default: + throw USBGUARD_BUG("unknown Policy::EventType value"); + } + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Policy.hpp b/src/Library/public/usbguard/Policy.hpp new file mode 100644 index 0000000..05a0c7e --- /dev/null +++ b/src/Library/public/usbguard/Policy.hpp @@ -0,0 +1,39 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Typedefs.hpp" + +#include + +namespace usbguard +{ + class DLL_PUBLIC Policy + { + public: + enum class EventType + { + Insert = 1, + Update = 2, + Remove = 3, + }; + + static std::string eventTypeToString(EventType event); + }; +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Predicates.hpp b/src/Library/public/usbguard/Predicates.hpp new file mode 100644 index 0000000..541efc2 --- /dev/null +++ b/src/Library/public/usbguard/Predicates.hpp @@ -0,0 +1,39 @@ +// +// Copyright (C) 2016 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Logger.hpp" +#include "Typedefs.hpp" + +namespace usbguard +{ + namespace Predicates DLL_PUBLIC + { + /* + * Return true if the source set is a subset of the + * target set. Otherwise return false. + */ + template + bool isSubsetOf(const T& source, const T& target) + { + USBGUARD_LOG(Trace) << "generic isSubsetOf"; + return source == target; + } + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Rule.cpp b/src/Library/public/usbguard/Rule.cpp new file mode 100644 index 0000000..ba68257 --- /dev/null +++ b/src/Library/public/usbguard/Rule.cpp @@ -0,0 +1,350 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "RulePrivate.hpp" +#include "Utility.hpp" + +namespace usbguard { + template<> + std::string toRuleString(const std::string& value) + { + return Utility::quoteEscapeString(value); + } + + const uint32_t Rule::RootID = std::numeric_limits::min(); + const uint32_t Rule::DefaultID = std::numeric_limits::max(); + const uint32_t Rule::LastID = std::numeric_limits::max() - 2; + const uint32_t Rule::ImplicitID = std::numeric_limits::max() - 1; + + Rule::Rule() + { + d_pointer = new RulePrivate(*this); + } + + Rule::~Rule() + { + delete d_pointer; + d_pointer = nullptr; + } + + Rule::Rule(const Rule& rhs) + { + d_pointer = new RulePrivate(*this, *rhs.d_pointer); + } + + const Rule& Rule::operator=(const Rule& rhs) + { + RulePrivate* n_pointer = new RulePrivate(*this, *rhs.d_pointer); + delete d_pointer; + d_pointer = n_pointer; + return *this; + } + + void Rule::setRuleID(uint32_t rule_id) + { + d_pointer->setRuleID(rule_id); + } + + uint32_t Rule::getRuleID() const + { + return d_pointer->getRuleID(); + } + + void Rule::setTarget(Rule::Target target) + { + d_pointer->setTarget(target); + } + + Rule::Target Rule::getTarget() const + { + return d_pointer->getTarget(); + } + + void Rule::setDeviceID(const USBDeviceID& value) + { + d_pointer->setDeviceID(value); + } + + const USBDeviceID& Rule::getDeviceID() const + { + return d_pointer->getDeviceID(); + } + + const Rule::Attribute& Rule::attributeDeviceID() const + { + return d_pointer->attributeDeviceID(); + } + + Rule::Attribute& Rule::attributeDeviceID() + { + return d_pointer->attributeDeviceID(); + } + + void Rule::setSerial(const std::string& value) + { + d_pointer->setSerial(value); + } + + const std::string& Rule::getSerial() const + { + return d_pointer->getSerial(); + } + + const Rule::Attribute& Rule::attributeSerial() const + { + return d_pointer->attributeSerial(); + } + + Rule::Attribute& Rule::attributeSerial() + { + return d_pointer->attributeSerial(); + } + + void Rule::setName(const std::string& value) + { + d_pointer->setName(value); + } + + const std::string& Rule::getName() const + { + return d_pointer->getName(); + } + + const Rule::Attribute& Rule::attributeName() const + { + return d_pointer->attributeName(); + } + + Rule::Attribute& Rule::attributeName() + { + return d_pointer->attributeName(); + } + + void Rule::setHash(const std::string& value) + { + d_pointer->setHash(value); + } + + const std::string& Rule::getHash() const + { + return d_pointer->getHash(); + } + + const Rule::Attribute& Rule::attributeHash() const + { + return d_pointer->attributeHash(); + } + + Rule::Attribute& Rule::attributeHash() + { + return d_pointer->attributeHash(); + } + + void Rule::setParentHash(const std::string& value) + { + d_pointer->setParentHash(value); + } + + const std::string& Rule::getParentHash() const + { + return d_pointer->getParentHash(); + } + + const Rule::Attribute& Rule::attributeParentHash() const + { + return d_pointer->attributeParentHash(); + } + + Rule::Attribute& Rule::attributeParentHash() + { + return d_pointer->attributeParentHash(); + } + + void Rule::setViaPort(const std::string& value) + { + d_pointer->setViaPort(value); + } + + const std::string& Rule::getViaPort() const + { + return d_pointer->getViaPort(); + } + + const Rule::Attribute& Rule::attributeViaPort() const + { + return d_pointer->attributeViaPort(); + } + + Rule::Attribute& Rule::attributeViaPort() + { + return d_pointer->attributeViaPort(); + } + + const Rule::Attribute& Rule::attributeWithInterface() const + { + return d_pointer->attributeWithInterface(); + } + + Rule::Attribute& Rule::attributeWithInterface() + { + return d_pointer->attributeWithInterface(); + } + + const Rule::Attribute& Rule::attributeConditions() const + { + return d_pointer->attributeConditions(); + } + + Rule::Attribute& Rule::attributeConditions() + { + return d_pointer->attributeConditions(); + } + + bool Rule::appliesTo(std::shared_ptr rhs) const + { + return appliesTo(*rhs); + } + + bool Rule::appliesTo(const Rule& rhs) const + { + return d_pointer->appliesTo(rhs); + } + + bool Rule::appliesTo(const Rule& rhs) + { + updateMetaDataCounters(/*applied=*/false, /*evaluated=*/true); + return d_pointer->appliesTo(rhs); + } + + bool Rule::isImplicit() const + { + return d_pointer->getRuleID() == Rule::DefaultID; + } + + Rule::operator bool() const + { + return !(getTarget() == Target::Unknown || + getTarget() == Target::Invalid); + } + + std::string Rule::toString(bool invalid) const + { + return d_pointer->toString(invalid); + } + + void Rule::updateMetaDataCounters(bool applied, bool evaluated) + { + d_pointer->updateMetaDataCounters(applied, evaluated); + } + + Rule Rule::fromString(const std::string& rule_string) + { + return RulePrivate::fromString(rule_string); + } + + RulePrivate* Rule::internal() + { + return d_pointer; + } + + const RulePrivate* Rule::internal() const + { + return d_pointer; + } + + static const std::vector > target_ttable = { + { "allow", Rule::Target::Allow }, + { "block", Rule::Target::Block }, + { "reject", Rule::Target::Reject }, + { "match", Rule::Target::Match }, + { "device", Rule::Target::Device } + }; + + const std::string Rule::targetToString(const Rule::Target target) + { + for (auto ttable_entry : target_ttable) { + if (ttable_entry.second == target) { + return ttable_entry.first; + } + } + throw std::runtime_error("Invalid rule target string"); + } + + Rule::Target Rule::targetFromString(const std::string& target_string) + { + for (auto ttable_entry : target_ttable) { + if (ttable_entry.first == target_string) { + return ttable_entry.second; + } + } + throw std::runtime_error("Invalid rule target string"); + } + + uint32_t Rule::targetToInteger(const Rule::Target target) + { + return static_cast(target); + } + + Rule::Target Rule::targetFromInteger(const uint32_t target_integer) + { + switch(target_integer) { + case static_cast(Rule::Target::Allow): + case static_cast(Rule::Target::Block): + case static_cast(Rule::Target::Reject): + case static_cast(Rule::Target::Match): + case static_cast(Rule::Target::Device): + break; + default: + throw std::runtime_error("Invalid rule target integer value"); + } + return static_cast(target_integer); + } + + static const std::vector > set_operator_ttable = { + { "all-of", Rule::SetOperator::AllOf }, + { "one-of", Rule::SetOperator::OneOf }, + { "none-of", Rule::SetOperator::NoneOf }, + { "equals", Rule::SetOperator::Equals }, + { "equals-ordered", Rule::SetOperator::EqualsOrdered }, + { "match", Rule::SetOperator::Match } + }; + + const std::string Rule::setOperatorToString(const Rule::SetOperator& op) + { + for (auto ttable_entry : set_operator_ttable) { + if (ttable_entry.second == op) { + return ttable_entry.first; + } + } + throw std::runtime_error("Invalid set operator string"); + } + + Rule::SetOperator Rule::setOperatorFromString(const std::string& set_operator_string) + { + for (auto ttable_entry : set_operator_ttable) { + if (ttable_entry.first == set_operator_string) { + return ttable_entry.second; + } + } + throw std::runtime_error("Invalid set operator string"); + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Rule.hpp b/src/Library/public/usbguard/Rule.hpp new file mode 100644 index 0000000..81f03f2 --- /dev/null +++ b/src/Library/public/usbguard/Rule.hpp @@ -0,0 +1,479 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "RuleCondition.hpp" +#include "Exception.hpp" +#include "Logger.hpp" +#include "Predicates.hpp" +#include "Typedefs.hpp" +#include "USB.hpp" + +#include +#include +#include +#include + +namespace usbguard { + template + std::string toRuleString(T* const value) + { + return value->toRuleString(); + } + + template + std::string toRuleString(const T& value) + { + return value.toRuleString(); + } + + template<> + std::string DLL_PUBLIC toRuleString(const std::string& value); + + class RulePrivate; + class DLL_PUBLIC Rule + { + public: + /** + * Rule target enumeration. + */ + enum class Target { + Allow = 0, /**< Devices matching this rule will be authorized */ + Block = 1, /**< Devices matching this rule will not be authorized */ + Reject = 2, /**< Devices matching this rule will not be authorized and will be detached */ + Match = 3, /**< Special target which can be used to trigger actions. The rule wont affect the final decision. */ + Unknown = 4, /**< Unknown target. Used for default constructed rules. */ + Device = 5, /**< Special target which can only be used for a rule that represents a single device */ + Invalid = 6 + }; + + static const std::string targetToString(Target target); + static Target targetFromString(const std::string& target_string); + + static uint32_t targetToInteger(Target target); + static Target targetFromInteger(uint32_t target_integer); + + enum class SetOperator + { + AllOf, + OneOf, + NoneOf, + Equals, + EqualsOrdered, + Match /* Special operator: matches anything, cannot be used directly in a rule */ + }; + + static const std::string setOperatorToString(const Rule::SetOperator& op); + static SetOperator setOperatorFromString(const std::string& set_operator_string); + + /**< Sequence number of the (fake) root rule */ + static const uint32_t RootID; + /**< Sequence number assigned to default constructed rules. Cannot be used for searching. */ + static const uint32_t DefaultID; + /**< Sequence number for specifying that the last rule in the ruleset should be used in context of the operation */ + static const uint32_t LastID; + /**< Sequence number of the implicit target rule */ + static const uint32_t ImplicitID; + + template + class Attribute + { + public: + Attribute(const char * name) + { + _name = name; + _set_operator = SetOperator::Equals; + } + + Attribute(const Attribute& rhs) + { + _name = rhs._name; + _set_operator = rhs._set_operator; + _values = rhs._values; + } + + void setSetOperator(SetOperator op) + { + _set_operator = op; + } + + SetOperator setOperator() const + { + return _set_operator; + } + + void append(ValueType&& value) + { + _values.emplace_back(std::move(value)); + } + + void append(const ValueType& value) + { + _values.push_back(value); + } + + size_t count() const + { + return _values.size(); + } + + bool empty() const + { + return count() == 0; + } + + void clear() + { + _values.clear(); + _set_operator = SetOperator::Equals; + } + + const ValueType& get() const + { + if (count() == 1) { + return _values[0]; + } + else if (count() == 0) { + throw std::runtime_error("BUG: Accessing an empty attribute"); + } + else { + throw std::runtime_error("BUG: Accessing a multivalued attribute using get()"); + } + } + + const ValueType& get(size_t index) const + { + return _values.at(index); + } + + void set(ValueType&& value) + { + if (count() > 1) { + throw std::runtime_error("BUG: Setting single value for a multivalued attribute"); + } + if (count() == 0) { + append(value); + } + else { + _values[0] = std::move(value); + } + } + + void set(const ValueType& value) + { + if (count() > 1) { + throw std::runtime_error("BUG: Setting single value for a multivalued attribute"); + } + if (count() == 0) { + append(value); + } + else { + _values[0] = value; + } + } + + void set(const std::vector& values, SetOperator op) + { + _values = values; + _set_operator = op; + } + + bool appliesTo(const Attribute& target) const + { + USBGUARD_LOG(Trace) << "entry:" + << " source=" << this->toRuleString() + << " target=" << target.toRuleString(); + + bool applies = false; + + /* Nothing applies to anything */ + if (empty()) { + USBGUARD_LOG(Debug) << "empty source value, setting applies=true"; + applies = true; + } + else { + USBGUARD_LOG(Debug) << "set_operator=" << setOperatorToString(setOperator()); + switch(setOperator()) { + case SetOperator::Match: + applies = true; + break; + case SetOperator::AllOf: + applies = setSolveAllOf(_values, target._values); + break; + case SetOperator::OneOf: + applies = setSolveOneOf(_values, target._values); + break; + case SetOperator::NoneOf: + applies = setSolveNoneOf(_values, target._values); + break; + case SetOperator::Equals: + applies = setSolveEquals(_values, target._values); + break; + case SetOperator::EqualsOrdered: + applies = setSolveEqualsOrdered(_values, target._values); + break; + default: + throw USBGUARD_BUG("Invalid set operator value"); + } + } + + USBGUARD_LOG(Trace) << "return:" + << " applies=" << applies; + + return applies; + } + + std::string toRuleString() const + { + std::string result; + + result.append(_name); + result.append(" "); + + const bool nondefault_op = setOperator() != SetOperator::Equals; + const bool multiset_form = count() > 1 || nondefault_op; + + if (multiset_form) { + if (nondefault_op) { + result.append(setOperatorToString(setOperator())); + result.append(" "); + } + result.append("{ "); + } + + for(const auto& value : _values) { + result.append(usbguard::toRuleString(value)); + result.append(" "); + } + + if (multiset_form) { + result.append("}"); + } + else { + /* + * Remove the trailing space in case of a single + * valued attribute. + */ + result.erase(result.end() - 1); + } + + return result; + } + + const std::vector& values() const + { + return _values; + } + + std::vector& values() + { + return _values; + } + + private: + /* + * All of the items in source set must match an item in the target set + */ + bool setSolveAllOf(const std::vector& source_set, const std::vector& target_set) const + { + USBGUARD_LOG(Trace); + + for (auto const& source_item : source_set) { + bool match = false; + for (auto const& target_item : target_set) { + if (Predicates::isSubsetOf(source_item, target_item)) { + match = true; + break; + } + } + if (!match) { + return false; + } + } + return true; + } + + /* + * At least one of the items in the source set must match an item in the target set + */ + bool setSolveOneOf(const std::vector& source_set, const std::vector& target_set) const + { + USBGUARD_LOG(Trace); + + for (auto const& source_item : source_set) { + for (auto const& target_item : target_set) { + if (Predicates::isSubsetOf(source_item, target_item)) { + return true; + } + } + } + return false; + } + + /* + * None of the the items in the rule set must match any item in the + * applies_to set + */ + bool setSolveNoneOf(const std::vector& source_set, const std::vector& target_set) const + { + USBGUARD_LOG(Trace); + + for (auto const& source_item : source_set) { + for (auto const& target_item : target_set) { + if (Predicates::isSubsetOf(source_item, target_item)) { + return false; + } + } + } + return true; + } + + /* + * Every item in the rule set must match one item in the + * applies_to set and the sets have to have the same number + * of items + */ + bool setSolveEquals(const std::vector& source_set, const std::vector& target_set) const + { + USBGUARD_LOG(Trace); + + if (source_set.size() != target_set.size()) { + return false; + } + else { + for (auto const& source_item : source_set) { + bool match = false; + for (auto const& target_item : target_set) { + if (Predicates::isSubsetOf(source_item, target_item)) { + match = true; + break; + } + } + if (!match) { + return false; + } + } + return true; + } + } + + /* + * The sets are treated as arrays and they have to me equal + * (same number of items at the same positions) + */ + bool setSolveEqualsOrdered(const std::vector& source_set, const std::vector& target_set) const + { + USBGUARD_LOG(Trace); + + if (source_set.size() != target_set.size()) { + return false; + } + for (size_t i = 0; i < source_set.size(); ++i) { + if (!Predicates::isSubsetOf(source_set[i], target_set[i])) { + return false; + } + } + return false; + } + + std::string _name; + SetOperator _set_operator; + std::vector _values; + }; + + /** + * Construct a default rule. + * This rule matches only a default rule and cannot be converted to a string + * representation. + */ + Rule(); + ~Rule(); + Rule(const Rule& rhs); + const Rule& operator=(const Rule& rhs); + + void setRuleID(uint32_t rule_id); + uint32_t getRuleID() const; + + void setTarget(Rule::Target target); + Target getTarget() const; + + void setDeviceID(const USBDeviceID& value); + const USBDeviceID& getDeviceID() const; + const Attribute& attributeDeviceID() const; + Attribute& attributeDeviceID(); + + void setSerial(const std::string& value); + const std::string& getSerial() const; + const Attribute& attributeSerial() const; + Attribute& attributeSerial(); + + void setName(const std::string& value); + const std::string& getName() const; + const Attribute& attributeName() const; + Attribute& attributeName(); + + void setHash(const std::string& value); + const std::string& getHash() const; + const Attribute& attributeHash() const; + Attribute& attributeHash(); + + void setParentHash(const std::string& value); + const std::string& getParentHash() const; + const Rule::Attribute& attributeParentHash() const; + + Rule::Attribute& attributeParentHash(); + + void setViaPort(const std::string& value); + const std::string& getViaPort() const; + const Attribute& attributeViaPort() const; + Attribute& attributeViaPort(); + + /* + * Set/get for a single value isn't useful for the + * with-interface attribute as it usualy contains + * multiple values. Therefore, we provide only the + * attribute accessors in this case. + */ + const Attribute& attributeWithInterface() const; + Attribute& attributeWithInterface(); + + const Attribute& attributeConditions() const; + Attribute& attributeConditions(); + + bool appliesTo(std::shared_ptr rhs) const; + bool appliesTo(const Rule& rhs) const; + bool appliesTo(const Rule& rhs); + bool isImplicit() const; + + + operator bool() const; + std::string toString(bool invalid = false) const; + + void updateMetaDataCounters(bool applied = true, bool evaluated = false); + + RulePrivate* internal(); + const RulePrivate* internal() const; + + /*** Static methods ***/ + static Rule fromString(const std::string& rule_string); + + private: + RulePrivate* d_pointer; + }; +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/RuleCondition.cpp b/src/Library/public/usbguard/RuleCondition.cpp new file mode 100644 index 0000000..c3515de --- /dev/null +++ b/src/Library/public/usbguard/RuleCondition.cpp @@ -0,0 +1,245 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "usbguard/RuleCondition.hpp" + +#include "usbguard/Rule.hpp" +#include "usbguard/Logger.hpp" + +#include +#include + +namespace usbguard +{ + RuleConditionBase::RuleConditionBase(const std::string& identifier, const std::string& parameter, bool negated) + : _identifier(identifier), + _parameter(parameter), + _negated(negated) + { + } + + RuleConditionBase::RuleConditionBase(const std::string& identifier, bool negated) + : _identifier(identifier), + _negated(negated) + { + } + + RuleConditionBase::RuleConditionBase(const RuleConditionBase& rhs) + : _identifier(rhs._identifier), + _parameter(rhs._parameter), + _negated(rhs._negated) + { + } + + RuleConditionBase::~RuleConditionBase() + { + fini(); + } + + void RuleConditionBase::init(Interface * const interface_ptr) + { + (void)interface_ptr; + } + + void RuleConditionBase::fini() + { + } + + bool RuleConditionBase::evaluate(const Rule& rule) + { + return isNegated() ? !update(rule) : update(rule); + } + + const std::string& RuleConditionBase::identifier() const + { + return _identifier; + } + + const std::string& RuleConditionBase::parameter() const + { + return _parameter; + } + + bool RuleConditionBase::hasParameter() const + { + return !_parameter.empty(); + } + + bool RuleConditionBase::isNegated() const + { + return _negated; + } + + const std::string RuleConditionBase::toString() const + { + std::string condition_string; + + if (isNegated()) { + condition_string.append("!"); + } + + condition_string.append(identifier()); + + if (hasParameter()) { + condition_string.append("("); + condition_string.append(parameter()); /* TODO: Escape parameter string */ + condition_string.append(")"); + } + + return condition_string; + } + + const std::string RuleConditionBase::toRuleString() const + { + return toString(); + } +} /* namespace usbguard */ + +#include "AllowedMatchesCondition.hpp" +#include "LocaltimeCondition.hpp" +#include "FixedStateCondition.hpp" +#include "RandomStateCondition.hpp" +#include "RuleAppliedCondition.hpp" +#include "RuleEvaluatedCondition.hpp" + +#include +#include + +namespace usbguard +{ + RuleConditionBase* RuleConditionBase::getImplementation(const std::string& condition_string) + { + if (condition_string.empty()) { + throw std::runtime_error("Empty condition"); + } + + const bool negated = condition_string[0] == '!'; + const size_t identifier_start = negated ? 1 : 0; + const size_t p_pos = condition_string.find_first_of('('); + + std::string identifier; + std::string parameter; + + if (p_pos == std::string::npos) { + /* + * The rest of the condition_string should be + * a condition identifier -- without a parameter. + */ + identifier = condition_string.substr(identifier_start); + + if (identifier.size() < 1) { + throw std::runtime_error("Invalid condition string. Missing identifier."); + } + } + else { + const size_t parameter_size = condition_string.size() - p_pos; + + if (parameter_size < 3 /* two parentheses + at least one character */) { + throw std::runtime_error("Invalid condition string. Invalid parameter."); + } + + const size_t identifier_size = p_pos - identifier_start; + identifier = condition_string.substr(identifier_start, identifier_size); + + if (condition_string[condition_string.size() - 1] != ')') { + throw std::runtime_error("Invalid condition string. Malformed parameter."); + } + + parameter = condition_string.substr(p_pos + 1, parameter_size - 2); + } + + return getImplementation(identifier, parameter, negated); + } + + RuleConditionBase* RuleConditionBase::getImplementation(const std::string& identifier, const std::string& parameter, bool negated) + { + if (identifier == "allowed-matches") { + return new AllowedMatchesCondition(parameter, negated); + } + if (identifier == "localtime") { + return new LocaltimeCondition(parameter, negated); + } + if (identifier == "true") { + return new FixedStateCondition(true, negated); + } + if (identifier == "false") { + return new FixedStateCondition(false, negated); + } + if (identifier == "random") { + return new RandomStateCondition(parameter, negated); + } + if (identifier == "rule-applied") { + return new RuleAppliedCondition(parameter, negated); + } + if (identifier == "rule-evaluated") { + return new RuleEvaluatedCondition(parameter, negated); + } + throw std::runtime_error("Unknown rule condition"); + } + + RuleCondition::RuleCondition() + { + } + + RuleCondition::RuleCondition(const std::string& condition_string) + : _condition(RuleConditionBase::getImplementation(condition_string)) + { + } + + RuleCondition::RuleCondition(const RuleCondition& rhs) + : _condition(rhs._condition->clone()) + { + } + + RuleCondition::RuleCondition(RuleCondition&& rhs) + : _condition(std::move(rhs._condition)) + { + } + + RuleCondition& RuleCondition::operator=(const RuleCondition& rhs) + { + _condition.reset(rhs._condition->clone()); + return *this; + } + + RuleCondition& RuleCondition::operator=(RuleCondition&& rhs) + { + _condition = std::move(rhs._condition); + return *this; + } + + RuleConditionBase* RuleCondition::operator->() + { + return _condition.get(); + } + + RuleConditionBase& RuleCondition::operator*() + { + return *_condition.get(); + } + + std::string RuleCondition::toRuleString() const + { + return _condition->toRuleString(); + } +} /* namespace usbguard */ + diff --git a/src/Library/public/usbguard/RuleCondition.hpp b/src/Library/public/usbguard/RuleCondition.hpp new file mode 100644 index 0000000..3a4d6a4 --- /dev/null +++ b/src/Library/public/usbguard/RuleCondition.hpp @@ -0,0 +1,79 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Typedefs.hpp" + +#include +#include + +namespace usbguard +{ + class Interface; + class Rule; + class DLL_PUBLIC RuleConditionBase + { + public: + RuleConditionBase(const std::string& identifier, const std::string& parameter, bool negated = false); + RuleConditionBase(const std::string& identifier, bool negated = false); + RuleConditionBase(const RuleConditionBase& rhs); + virtual ~RuleConditionBase(); + + virtual void init(Interface * const interface_ptr); + virtual void fini(); + virtual bool update(const Rule& rule) = 0; + virtual RuleConditionBase* clone() const = 0; + + bool evaluate(const Rule& rule); + const std::string& identifier() const; + const std::string& parameter() const; + bool hasParameter() const; + bool isNegated() const; + const std::string toString() const; + const std::string toRuleString() const; + + static RuleConditionBase* getImplementation(const std::string& condition_string); + static RuleConditionBase* getImplementation(const std::string& identifier, const std::string& parameter, bool negated); + + private: + const std::string _identifier; + const std::string _parameter; + const bool _negated; + }; + + class DLL_PUBLIC RuleCondition + { + public: + RuleCondition(); + RuleCondition(const std::string& condition_string); + RuleCondition(const RuleCondition& rhs); + RuleCondition(RuleCondition&& rhs); + + RuleCondition& operator=(const RuleCondition& rhs); + RuleCondition& operator=(RuleCondition&& rhs); + + RuleConditionBase* operator->(); + RuleConditionBase& operator*(); + + std::string toRuleString() const; + private: + std::unique_ptr _condition; + }; +} /*namespace usbguard */ + diff --git a/src/Library/public/usbguard/RuleParser.cpp b/src/Library/public/usbguard/RuleParser.cpp new file mode 100644 index 0000000..89c9084 --- /dev/null +++ b/src/Library/public/usbguard/RuleParser.cpp @@ -0,0 +1,83 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "RuleParser.hpp" +#include "RuleParser/Grammar.hpp" +#include "RuleParser/Actions.hpp" +#include "RulePrivate.hpp" + +#include "usbguard/Typedefs.hpp" +#include "usbguard/USB.hpp" +#include "usbguard/Logger.hpp" +#include "Common/Utility.hpp" + +#include +#include +#include + +#include + +namespace usbguard +{ + Rule parseRuleFromString(const std::string& rule_spec, const std::string& file, size_t line, bool trace) + { + try { + Rule rule; +#if HAVE_PEGTL_LTE_1_3_1 + if (!trace) { + pegtl::parse(rule_spec, file, rule); + } + else { + pegtl::parse(rule_spec, file, rule); + } +#else + if (!trace) { + pegtl::parse_string(rule_spec, file, rule); + } + else { + pegtl::parse_string(rule_spec, file, rule); + } +#endif + return rule; + } + catch(const pegtl::parse_error& ex) { + RuleParserError error(rule_spec); + + error.setHint(ex.what()); +#if HAVE_PEGTL_LTE_1_3_1 + error.setOffset(ex.positions[0].column); +#else + error.setOffset(ex.positions[0].byte_in_line); +#endif + + if (!file.empty() || line != 0) { + error.setFileInfo(file, line); + } + + throw error; + } + catch(const std::exception& ex) { + + throw; + } + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/RuleParser.hpp b/src/Library/public/usbguard/RuleParser.hpp new file mode 100644 index 0000000..0b5f53e --- /dev/null +++ b/src/Library/public/usbguard/RuleParser.hpp @@ -0,0 +1,110 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Typedefs.hpp" +#include "Rule.hpp" + +#include +#include + +#include + +namespace usbguard +{ + class RuleParserError : public std::exception + { + public: + RuleParserError(const std::string& rule_spec, const std::string& hint = "", + const std::string& file = "", size_t error_line = 0, unsigned int error_offset = 0) + : _rule_spec(rule_spec), + _hint(hint), + _offset(error_offset), + _file(file), + _line(error_line) + { + } + + void setHint(const std::string& hint) + { + _hint = hint; + } + + void setOffset(size_t offset) + { + _offset = offset; + } + + void setFileInfo(const std::string& file, size_t error_line, size_t error_offset = 0) + { + _file = file; + _line = error_line; + _offset = error_offset; + } + + const char *what() const noexcept + { + return "RuleParserError"; + } + + const std::string& rule() const + { + return _rule_spec; + } + + const std::string& hint() const + { + return _hint; + } + + bool hasFileInfo() const + { + return !_file.empty(); + } + + const std::string fileInfo() const + { + return _file + ": line=" + std::to_string(_line) + ": offset=" + std::to_string(_offset); + } + + const std::string& file() const + { + return _file; + } + + size_t line() const + { + return _line; + } + + size_t offset() const + { + return _offset; + } + + protected: + const std::string _rule_spec; + std::string _hint; + size_t _offset; + std::string _file; + size_t _line; + }; + + DLL_PUBLIC Rule parseRuleFromString(const std::string& rule_spec, const std::string& file = std::string(), size_t line = 0, bool trace = false); +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/RuleSet.cpp b/src/Library/public/usbguard/RuleSet.cpp new file mode 100644 index 0000000..1006269 --- /dev/null +++ b/src/Library/public/usbguard/RuleSet.cpp @@ -0,0 +1,126 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "Typedefs.hpp" +#include "RuleSetPrivate.hpp" + +namespace usbguard { + RuleSet::RuleSet(Interface * const interface_ptr) + { + d_pointer = new RuleSetPrivate(*this, interface_ptr); + } + + RuleSet::~RuleSet() + { + delete d_pointer; + d_pointer = nullptr; + } + + RuleSet::RuleSet(const RuleSet& rhs) + { + d_pointer = new RuleSetPrivate(*this, *rhs.d_pointer); + } + + const RuleSet& RuleSet::operator=(const RuleSet& rhs) + { + RuleSetPrivate * n_pointer = new RuleSetPrivate(*this, *rhs.d_pointer); + delete d_pointer; + d_pointer = n_pointer; + return *this; + } + + void RuleSet::load(const std::string& path) + { + d_pointer->load(path); + } + + void RuleSet::load(std::istream& stream) + { + d_pointer->load(stream); + } + + void RuleSet::save(const std::string& path) const + { + d_pointer->save(path); + } + + void RuleSet::save(std::ostream& stream) const + { + d_pointer->save(stream); + } + + void RuleSet::setDefaultTarget(Rule::Target target) + { + d_pointer->setDefaultTarget(target); + } + + Rule::Target RuleSet::getDefaultTarget() const + { + return d_pointer->getDefaultTarget(); + } + + void RuleSet::setDefaultAction(const std::string& action) + { + d_pointer->setDefaultAction(action); + } + + uint32_t RuleSet::appendRule(const Rule& rule, uint32_t parent_id) + { + return d_pointer->appendRule(rule, parent_id); + } + + uint32_t RuleSet::upsertRule(const Rule& match_rule, const Rule& new_rule, const bool parent_insensitive) + { + return d_pointer->upsertRule(match_rule, new_rule, parent_insensitive); + } + + std::shared_ptr RuleSet::getRule(uint32_t id) + { + return d_pointer->getRule(id); + } + + bool RuleSet::removeRule(uint32_t id) + { + return d_pointer->removeRule(id); + } + + std::shared_ptr RuleSet::getFirstMatchingRule(std::shared_ptr device_rule, uint32_t from_id) const + { + return d_pointer->getFirstMatchingRule(device_rule, from_id); + } + + std::vector> RuleSet::getRules() + { + return d_pointer->getRules(); + } + + uint32_t RuleSet::assignID(std::shared_ptr rule) + { + return d_pointer->assignID(rule); + } + + uint32_t RuleSet::assignID() + { + return d_pointer->assignID(); + } + +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/RuleSet.hpp b/src/Library/public/usbguard/RuleSet.hpp new file mode 100644 index 0000000..6893e38 --- /dev/null +++ b/src/Library/public/usbguard/RuleSet.hpp @@ -0,0 +1,149 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Rule.hpp" +#include "Typedefs.hpp" + +#include +#include +#include +#include + +#include + +namespace usbguard { + class RuleSetPrivate; + class Interface; + class DLL_PUBLIC RuleSet + { + public: + /** + * Construct an empty ruleset. + */ + RuleSet(Interface * const interface_ptr); + RuleSet(const RuleSet& rhs); + const RuleSet& operator=(const RuleSet& rhs); + ~RuleSet(); + + /** + * Load a ruleset from a file at `path'. + * Internally, this opens an input file stream and calls load(std::istream& stream). + */ + void load(const std::string& path); + + /** + * Load a ruleset from an input stream. + * The stream is read using std::getline() and each line is parsed as a separate rule. + * Empty lines are skipped. + */ + void load(std::istream& stream); + + /** + * Save the ruleset to a file at `path'. + * If a file exists at `path', it will be overwritten. Internally, this opens an output + * stream and calls save(std::ostream& stream). + */ + void save(const std::string& path) const; + + /** + * Write the ruleset to an output stream. + * Each rule is serialized to it's string representation and written line by line to + * the output stream. + */ + void save(std::ostream& stream) const; + + /** + * Set an implicit default target which will be used if there's no match for a device + * rule. + */ + void setDefaultTarget(Rule::Target target); + + /** + * Get the implicit target value. + */ + Rule::Target getDefaultTarget() const; + + /** + * Set an implicit default action which will be used if there's no match for a device + * rule. + */ + void setDefaultAction(const std::string& action); + + /** + * Assign a sequence number to a rule and append it to the rule set. + * If `parent_id' is not specified, the rule will be appended at the end od the ruleset. + * The method returns the sequence number assigned to the rule. + */ + uint32_t appendRule(const Rule& rule, uint32_t parent_id = Rule::LastID); + + /** + * Search for a rule that matches `match_rule' rule and update it with a rule specified + * by `new_rule'. Fail if multiple rules match. If there are no matching rules, append + * the `new_rule' rule to the rule set. + * + * Returns the id of the updated or new rule. + */ + uint32_t upsertRule(const Rule& match_rule, const Rule& new_rule, bool parent_insensitive = false); + + /** + * Get a rule pointer to a rule with the specified sequence number. + * Returns nullptr if no such rule exists. + */ + std::shared_ptr getRule(uint32_t id); + + /** + * Remove a rule from the ruleset. + * The method returns true if a rule was removed and false otherwise. + */ + bool removeRule(uint32_t id); + + /** + * Find first rule in the ruleset which matched the specified device rule. + * If `from_id' isn't specified, the method searches from the beginning of the ruleset. + * If no matching rule is found, nullptr is returned. + */ + std::shared_ptr getFirstMatchingRule(std::shared_ptr device_rule, uint32_t from_id = 1) const; + + /** + * Get all rules from the set. + */ + std::vector> getRules(); + + /** + * Get the oldest rule that timed out and should be removed from the ruleset. + * Returns nullptr if there are not timed out rules. + */ + std::shared_ptr getTimedOutRule(); + + /** + * Assign a unique sequence number to a rule. + * Return the assigned sequence number. + */ + uint32_t assignID(std::shared_ptr rule); + + /** + * Generate a unique sequence number. + */ + uint32_t assignID(); + + private: + RuleSetPrivate* d_pointer; + }; +} diff --git a/src/Library/public/usbguard/Typedefs.cpp b/src/Library/public/usbguard/Typedefs.cpp new file mode 100644 index 0000000..f15585f --- /dev/null +++ b/src/Library/public/usbguard/Typedefs.cpp @@ -0,0 +1,32 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "Typedefs.hpp" + +namespace usbguard +{ + template<> + bool matches(const std::string& a, const std::string& b) + { + return a == b; + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/Typedefs.hpp b/src/Library/public/usbguard/Typedefs.hpp new file mode 100644 index 0000000..452860e --- /dev/null +++ b/src/Library/public/usbguard/Typedefs.hpp @@ -0,0 +1,67 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include +#include + +namespace usbguard { + template + bool matches(const T& a, const T& b) + { + return a == b; + } + + template<> + bool matches(const std::string& a, const std::string& b); + + /* + * Atomic + */ + template + using Atomic = std::atomic; + + /* + * Symbol visibility + */ + #if defined _WIN32 || defined __CYGWIN__ + #ifdef BUILDING_DLL + #ifdef __GNUC__ + #define DLL_PUBLIC __attribute__ ((dllexport)) + #else + #define DLL_PUBLIC __declspec(dllexport) // Note: actually gcc seems to also supports this syntax. + #endif + #else + #ifdef __GNUC__ + #define DLL_PUBLIC __attribute__ ((dllimport)) + #else + #define DLL_PUBLIC __declspec(dllimport) // Note: actually gcc seems to also supports this syntax. + #endif + #endif + #define DLL_LOCAL + #else + #if __GNUC__ >= 4 + #define DLL_PUBLIC __attribute__ ((visibility ("default"))) + #define DLL_LOCAL __attribute__ ((visibility ("hidden"))) + #else + #define DLL_PUBLIC + #define DLL_LOCAL + #endif + #endif +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/USB.cpp b/src/Library/public/usbguard/USB.cpp new file mode 100644 index 0000000..5e81a68 --- /dev/null +++ b/src/Library/public/usbguard/USB.cpp @@ -0,0 +1,523 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "USB.hpp" +#include "Common/ByteOrder.hpp" +#include "Common/Utility.hpp" +#include "Logger.hpp" +#include +#include +#include + +namespace usbguard { + USBDeviceID::USBDeviceID() + { + } + + USBDeviceID::USBDeviceID(const std::string& vendor_id, const std::string& product_id) + { + checkDeviceID(vendor_id, product_id); + setVendorID(vendor_id); + setProductID(product_id); + } + + USBDeviceID::USBDeviceID(const USBDeviceID& rhs) + { + _vendor_id = rhs._vendor_id; + _product_id = rhs._product_id; + } + + void USBDeviceID::checkDeviceID(const std::string& vendor_id, const std::string& product_id) + { + if (vendor_id.empty() || vendor_id == "*") { + /* product id must be empty or "*" */ + if (!product_id.empty() && product_id != "*") { + throw std::runtime_error("Invalid USB device id format"); + } + } + if (vendor_id.size() > USB_VID_STRING_MAX_LENGTH) { + throw std::runtime_error("Vendor ID string size out of range"); + } + if (product_id.size() > USB_PID_STRING_MAX_LENGTH) { + throw std::runtime_error("Product ID string size out of range"); + } + } + + void USBDeviceID::setVendorID(const std::string& vendor_id) + { + checkDeviceID(vendor_id, _product_id); + _vendor_id = vendor_id; + } + + void USBDeviceID::setProductID(const std::string& product_id) + { + checkDeviceID(_vendor_id, product_id); + _product_id = product_id; + } + + const std::string& USBDeviceID::getVendorID() const + { + return _vendor_id; + } + + const std::string& USBDeviceID::getProductID() const + { + return _product_id; + } + + std::string USBDeviceID::toRuleString() const + { + return _vendor_id + ":" + _product_id; + } + + std::string USBDeviceID::toString() const + { + return toRuleString(); + } + + bool USBDeviceID::isSubsetOf(const USBDeviceID& rhs) const + { + if (_vendor_id.empty() || _vendor_id == "*") { + return true; + } + else if (_vendor_id != rhs._vendor_id) { + return false; + } + + if (_product_id.empty() || _product_id == "*") { + return true; + } + else if (_product_id != rhs._product_id) { + return false; + } + + return true; + } + + template<> + bool Predicates::isSubsetOf(const USBDeviceID& source, const USBDeviceID& target) + { + USBGUARD_LOG(Trace) << "source=" << source.toString() << " target=" << target.toString(); + const bool result = source.isSubsetOf(target); + USBGUARD_LOG(Trace) << "result=" << result; + return result; + } + + USBInterfaceType::USBInterfaceType() + { + _bClass = 0; + _bSubClass = 0; + _bProtocol = 0; + _mask = 0; + } + + USBInterfaceType::USBInterfaceType(uint8_t bClass, uint8_t bSubClass, uint8_t bProtocol, uint8_t mask) + { + _bClass = bClass; + _bSubClass = bSubClass; + _bProtocol = bProtocol; + _mask = mask; + } + + USBInterfaceType::USBInterfaceType(const USBInterfaceDescriptor& descriptor, uint8_t mask) + { + _bClass = descriptor.bInterfaceClass; + _bSubClass = descriptor.bInterfaceSubClass; + _bProtocol = descriptor.bInterfaceProtocol; + _mask = mask; + } + + USBInterfaceType::USBInterfaceType(const std::string& type_string) + { + std::vector tokens; + tokenizeString(type_string, tokens, ":", /*trim_empty=*/false); + + _bClass = 0; + _bSubClass = 0; + _bProtocol = 0; + _mask = 0; + + if (tokens.size() != 3) { + throw std::runtime_error("Invalid type_string"); + } + + if (tokens[0].size() != 2) { + throw std::runtime_error("Invalid type_string"); + } + else { + _bClass = stringToNumber(tokens[0], 16); + _mask |= MatchClass; + } + + if (tokens[1] != "*") { + if (tokens[1].size() != 2) { + throw std::runtime_error("Invalid type_string"); + } + else { + _bSubClass = stringToNumber(tokens[1], 16); + _mask |= MatchSubClass; + } + } + + if (tokens[2] != "*") { + if (tokens[2].size() != 2) { + throw std::runtime_error("Invalid type_string"); + } + else { + _bProtocol = stringToNumber(tokens[2], 16); + _mask |= MatchProtocol; + } + } + + if (!(_mask == (MatchAll) || + _mask == (MatchClass|MatchSubClass) || + _mask == (MatchClass))) { + throw std::runtime_error("Invalid type_string"); + } + } + + bool USBInterfaceType::operator==(const USBInterfaceType& rhs) const + { + return (_bClass == rhs._bClass && + _bSubClass == rhs._bSubClass && + _bProtocol == rhs._bProtocol && + _mask == rhs._mask); + } + + bool USBInterfaceType::appliesTo(const USBInterfaceType& rhs) const + { + if (_mask & MatchClass) { + if (_bClass != rhs._bClass) { + return false; + } + } + if (_mask & MatchSubClass) { + if (_bSubClass != rhs._bSubClass) { + return false; + } + } + if (_mask & MatchProtocol) { + if (_bProtocol != rhs._bProtocol) { + return false; + } + } + return true; + } + + template<> + bool Predicates::isSubsetOf(const USBInterfaceType& source, const USBInterfaceType& target) + { + return source.appliesTo(target); + } + + const std::string USBInterfaceType::typeString() const + { + return USBInterfaceType::typeString(_bClass, _bSubClass, _bProtocol, _mask); + } + + const std::string USBInterfaceType::toRuleString() const + { + return typeString(); + } + + const std::string USBInterfaceType::typeString(uint8_t bClass, uint8_t bSubClass, uint8_t bProtocol, uint8_t mask) + { + std::string type_string(""); + + if (mask & MatchClass) { + type_string.append(numberToString(bClass, "", 16, 2, '0') + ":"); + + if (mask & MatchSubClass) { + type_string.append(numberToString(bSubClass, "", 16, 2, '0') + ":"); + + if (mask & MatchProtocol) { + type_string.append(numberToString(bProtocol, "", 16, 2, '0')); + } + else { + type_string.append("*"); + } + } + else { + type_string.append("*:*"); + } + } + else { + throw std::runtime_error("BUG: cannot create type string, invalid mask"); + } + + return type_string; + } + + void USBParseDeviceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) + { + (void)parser; + const USBDeviceDescriptor* device_raw = reinterpret_cast(descriptor_raw); + USBDeviceDescriptor* device_out = reinterpret_cast(descriptor_out); + + /* Copy 1:1 */ + *device_out = *device_raw; + + /* Convert multibyte field to host endianness */ + device_out->bcdUSB = busEndianToHost(device_raw->bcdUSB); + device_out->idVendor = busEndianToHost(device_raw->idVendor); + device_out->idProduct = busEndianToHost(device_raw->idProduct); + device_out->bcdDevice = busEndianToHost(device_raw->bcdDevice); + } + + void USBParseConfigurationDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) + { + (void)parser; + const USBConfigurationDescriptor* configuration_raw = reinterpret_cast(descriptor_raw); + USBConfigurationDescriptor* configuration_out = reinterpret_cast(descriptor_out); + + /* Copy 1:1 */ + *configuration_out = *configuration_raw; + + /* Convert multibyte field to host endianness */ + configuration_out->wTotalLength = busEndianToHost(configuration_raw->wTotalLength); + } + + void USBParseInterfaceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) + { + (void)parser; + const USBInterfaceDescriptor* interface_raw = reinterpret_cast(descriptor_raw); + USBInterfaceDescriptor* interface_out = reinterpret_cast(descriptor_out); + + /* Copy 1:1 */ + *interface_out = *interface_raw; + } + + void USBParseEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) + { + (void)parser; + const USBEndpointDescriptor* endpoint_raw = reinterpret_cast(descriptor_raw); + USBEndpointDescriptor* endpoint_out = reinterpret_cast(descriptor_out); + + *endpoint_out = *endpoint_raw; + endpoint_out->wMaxPacketSize = busEndianToHost(endpoint_raw->wMaxPacketSize); + } + + void USBParseAudioEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) + { + (void)parser; + const USBAudioEndpointDescriptor* endpoint_raw = reinterpret_cast(descriptor_raw); + USBAudioEndpointDescriptor* endpoint_out = reinterpret_cast(descriptor_out); + + *endpoint_out = *endpoint_raw; + endpoint_out->wMaxPacketSize = busEndianToHost(endpoint_raw->wMaxPacketSize); + } + + void USBParseUnknownDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) + { + (void)parser; + *descriptor_out = *descriptor_raw; + } + + void USBDescriptorParserHooks::parseUSBDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out) + { + USBGUARD_LOG(Trace); + + const auto type = static_cast(descriptor_raw->bHeader.bDescriptorType); + const auto size = descriptor_raw->bHeader.bLength; + + switch(type) { + case USBDescriptorType::Device: + switch (size) { + case sizeof(USBDeviceDescriptor): + USBParseDeviceDescriptor(parser, descriptor_raw, descriptor_out); + return; + default: + throw Exception("USB descriptor parser", "device descriptor", "unexpected descriptor size"); + } + break; + case USBDescriptorType::Configuration: + switch (size) { + case sizeof(USBConfigurationDescriptor): + USBParseConfigurationDescriptor(parser, descriptor_raw, descriptor_out); + return; + default: + throw Exception("USB descriptor parser", "configuration descriptor", "unexpected descriptor size"); + } + break; + case USBDescriptorType::Interface: + switch (size) { + case sizeof(USBInterfaceDescriptor): + USBParseInterfaceDescriptor(parser, descriptor_raw, descriptor_out); + return; + default: + throw Exception("USB descriptor parser", "interface descriptor", "unexpected descriptor size"); + } + break; + case USBDescriptorType::Endpoint: + switch (size) { + case sizeof(USBEndpointDescriptor): + USBParseEndpointDescriptor(parser, descriptor_raw, descriptor_out); + return; + case sizeof(USBAudioEndpointDescriptor): + USBParseAudioEndpointDescriptor(parser, descriptor_raw, descriptor_out); + return; + default: + throw Exception("USB descriptor parser", "endpoint descriptor", "unexpected descriptor size"); + } + break; + case USBDescriptorType::String: + case USBDescriptorType::AssociationInterface: + case USBDescriptorType::Unknown: + default: + USBParseUnknownDescriptor(parser, descriptor_raw, descriptor_out); + return; + } + /* UNREACHABLE */ + } + + void USBDescriptorParserHooks::loadUSBDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor) + { + (void)parser; + (void)descriptor; + USBGUARD_LOG(Trace); + } + + USBDescriptorParser::USBDescriptorParser(USBDescriptorParserHooks& hooks) + : _hooks(hooks) + { + } + + size_t USBDescriptorParser::parse(std::istream& stream) + { + size_t size_processed = 0; + + while (stream.good()) { + USBDescriptorHeader header; + stream.read(reinterpret_cast(&header), sizeof header); + + if (stream.gcount() != sizeof header) { + /* + * If we read nothing and the stream if at EOF, just break + * the loop and return normally. Checking the sanity of the + * parsed descriptor data is up to the higher layers. + */ + if (stream.gcount() == 0 && stream.eof()) { + break; + } + /* + * Otherwise throw an exception because there's unknown garbage + * in the stream which cannot be a valid USB descriptor. + */ + else { + throw std::runtime_error("Cannot parse descriptor data: partial read while reading header data"); + } + } + + /* + * The bLength value has to be at least 2, because that is the size of the USB + * descriptor header. + */ + if (header.bLength < sizeof(USBDescriptorHeader)) { + throw std::runtime_error("Invalid descriptor data: bLength is less than the size of the header"); + } + + /* + * Let's try to read the rest of the descriptor data before we start looking + * for the descriptor type handler. If there's not enough data in the stream, + * then there's no point for searching for the handler. + */ + USBDescriptor descriptor; + + descriptor.bHeader = header; + memset(&descriptor.bDescriptorData, 0, sizeof descriptor.bDescriptorData); + + /* + * We read (bLength - header_size) amount of data here because the bLength value + * counts in the size of the header too and we already read it from the stream. + */ + stream.read(reinterpret_cast(&descriptor.bDescriptorData), header.bLength - sizeof(USBDescriptorHeader)); + + if (stream.gcount() != (std::streamsize)(header.bLength - sizeof(USBDescriptorHeader))) { + throw std::runtime_error("Invalid descriptor data: bLength value larger than the amount of available data"); + } + + USBDescriptor descriptor_parsed; + descriptor_parsed.bHeader = header; + memset(&descriptor_parsed.bDescriptorData, 0, sizeof descriptor_parsed.bDescriptorData); + + _hooks.parseUSBDescriptor(this, &descriptor, &descriptor_parsed); + _hooks.loadUSBDescriptor(this, &descriptor_parsed); + + setDescriptor(header.bDescriptorType, descriptor_parsed); + size_processed += header.bLength; + } + + return size_processed; + } + + const std::vector* USBDescriptorParser::getDescriptor(uint8_t bDescriptorType) const + { + auto const& it = _dstate_map.find(bDescriptorType); + if (it == _dstate_map.end()) { + return nullptr; + } + return &it->second; + } + + void USBDescriptorParser::setDescriptor(uint8_t bDescriptorType, const USBDescriptor& descriptor) + { + auto& descriptors = _dstate_map[bDescriptorType]; + bool set = false; + for (auto& stored_descriptor : descriptors) { + if (stored_descriptor.bHeader.bLength == descriptor.bHeader.bLength) { + stored_descriptor = descriptor; + set = true; + } + } + if (!set) { + descriptors.push_back(descriptor); + } + /* + * Count in the descriptor no matter if we overwrote one or not. + * We are counting all occurences of a descriptor type. + */ + ++_count_map[bDescriptorType]; + } + + void USBDescriptorParser::delDescriptor(uint8_t bDescriptorType) + { + _dstate_map.erase(bDescriptorType); + } + + bool USBDescriptorParser::haveDescriptor(uint8_t bDescriptorType) const + { + return _dstate_map.count(bDescriptorType) > 0; + } + + const std::vector> USBDescriptorParser::getDescriptorCounts() const + { + std::vector> counts; + + for (auto const& kv : _count_map) { + counts.push_back(std::make_pair(kv.first, kv.second)); + } + + std::sort(counts.begin(), counts.end()); + + return counts; + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/USB.hpp b/src/Library/public/usbguard/USB.hpp new file mode 100644 index 0000000..58be335 --- /dev/null +++ b/src/Library/public/usbguard/USB.hpp @@ -0,0 +1,276 @@ +// +// Copyright (C) 2015 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Predicates.hpp" +#include "Typedefs.hpp" + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace usbguard { + /* + * Maximum lenght of a string that is read from a USB descriptor + * Since the string descriptors have an 8-bit length field, the + * maximum lenght of a string stored in a string descriptor is + * UINT8_MAX minus the size of the length field (1 byte) and the + * size of the type field (1 byte). + */ + const size_t USB_GENERIC_STRING_MAX_LENGTH = UINT8_MAX - 2; + + /* Maximum lenght of the vendor id in string form */ + const size_t USB_VID_STRING_MAX_LENGTH = 4; + + /* Maximum lenght of the product id in string form */ + const size_t USB_PID_STRING_MAX_LENGTH = 4; + + /* Maximum lenght of the port in string form */ + const size_t USB_PORT_STRING_MAX_LENGTH = PATH_MAX; + + /* + * NOTE: The USB specification dictates that all multibyte data fields + * are in little-endian form. The structures defined bellow are + * used for platform-independed passing of the USB descriptor + * data to the Device class. The Device class assumes that the + * values are in host-specific endianness. + */ + const uint8_t USB_DESCRIPTOR_TYPE_UNKNOWN = 0x00; + const uint8_t USB_DESCRIPTOR_TYPE_DEVICE = 0x01; + const uint8_t USB_DESCRIPTOR_TYPE_CONFIGURATION = 0x02; + const uint8_t USB_DESCRIPTOR_TYPE_STRING = 0x03; + const uint8_t USB_DESCRIPTOR_TYPE_INTERFACE = 0x04; + const uint8_t USB_DESCRIPTOR_TYPE_ENDPOINT = 0x05; + const uint8_t USB_DESCRIPTOR_TYPE_ASSOCIATION_INTERFACE = 0x0b; + + enum class USBDescriptorType : uint8_t { + Unknown = USB_DESCRIPTOR_TYPE_UNKNOWN, + Device = USB_DESCRIPTOR_TYPE_DEVICE, + Configuration = USB_DESCRIPTOR_TYPE_CONFIGURATION, + String = USB_DESCRIPTOR_TYPE_STRING, + Interface = USB_DESCRIPTOR_TYPE_INTERFACE, + Endpoint = USB_DESCRIPTOR_TYPE_ENDPOINT, + AssociationInterface = USB_DESCRIPTOR_TYPE_ASSOCIATION_INTERFACE + }; + + struct DLL_PUBLIC USBDescriptorHeader + { + uint8_t bLength; + uint8_t bDescriptorType; + } __attribute__((packed)); + + struct DLL_PUBLIC USBDescriptor + { + struct USBDescriptorHeader bHeader; + uint8_t bDescriptorData[256-sizeof(USBDescriptorHeader)]; + } __attribute__((packed)); + + struct DLL_PUBLIC USBDeviceDescriptor + { + struct USBDescriptorHeader bHeader; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; + } __attribute__((packed)); + + struct DLL_PUBLIC USBConfigurationDescriptor + { + struct USBDescriptorHeader bHeader; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; + } __attribute__((packed)); + + struct DLL_PUBLIC USBInterfaceDescriptor + { + struct USBDescriptorHeader bHeader; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; + } __attribute__((packed)); + + struct USBEndpointDescriptor + { + struct USBDescriptorHeader bHeader; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; + } __attribute__((packed)); + + struct USBAudioEndpointDescriptor + { + struct USBDescriptorHeader bHeader; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; + uint8_t bRefresh; + uint8_t bSynchAddress; + } __attribute__((packed)); + + class DLL_PUBLIC USBDeviceID + { + public: + USBDeviceID(); + USBDeviceID(const std::string& vendor_id, const std::string& product_id = std::string()); + USBDeviceID(const USBDeviceID& rhs); + + static void checkDeviceID(const std::string& vendor_id, const std::string& product_id); + + void setVendorID(const std::string& vendor_id); + void setProductID(const std::string& product_id); + + const std::string& getVendorID() const; + const std::string& getProductID() const; + + std::string toRuleString() const; + std::string toString() const; + bool isSubsetOf(const USBDeviceID& rhs) const; + + private: + std::string _vendor_id; + std::string _product_id; + }; + + namespace Predicates DLL_PUBLIC + { + template<> + bool isSubsetOf(const USBDeviceID& source, const USBDeviceID& target); + } + + class DLL_PUBLIC USBInterfaceType + { + public: + static const uint8_t MatchClass = 1<<0; + static const uint8_t MatchSubClass = 1<<1; + static const uint8_t MatchProtocol = 1<<2; + static const uint8_t MatchAll = MatchClass|MatchSubClass|MatchProtocol; + + USBInterfaceType(); + USBInterfaceType(uint8_t bClass, uint8_t bSubClass, uint8_t bProtocol, uint8_t mask = MatchAll); + USBInterfaceType(const USBInterfaceDescriptor& descriptor, uint8_t mask = MatchAll); + USBInterfaceType(const std::string& type_string); + + bool operator==(const USBInterfaceType& rhs) const; + bool appliesTo(const USBInterfaceType& rhs) const; + + const std::string typeString() const; + const std::string toRuleString() const; + static const std::string typeString(uint8_t bClass, uint8_t bSubClass, uint8_t bProtocol, uint8_t mask = MatchAll); + + private: + uint8_t _bClass; + uint8_t _bSubClass; + uint8_t _bProtocol; + uint8_t _mask; + }; + + namespace Predicates DLL_PUBLIC + { + template<> + bool isSubsetOf(const USBInterfaceType& source, const USBInterfaceType& target); + } + + class USBDescriptorParser; + + class DLL_PUBLIC USBDescriptorParserHooks + { + public: + virtual void parseUSBDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_in, USBDescriptor* descriptor_out); + virtual void loadUSBDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor); + }; + + class DLL_PUBLIC USBDescriptorParser + { + public: + USBDescriptorParser(USBDescriptorParserHooks& hooks); + + /** + * Initiate parsing of USB descriptors from an input stream. + * + * Returns number of bytes succesfully parsed/processed from + * the stream. + */ + size_t parse(std::istream& stream); + + /** + * Return a pointer to a USBDescriptor of type bDescriptorType that + * is stored in the USB descriptor state. If there's no such descriptor, + * then nullptr is returned. + */ + const std::vector* getDescriptor(uint8_t bDescriptorType) const; + + /** + * Set the active instance of an USB descriptor of bDescriptorType type. + */ + void setDescriptor(uint8_t bDescriptorType, const USBDescriptor& descriptor); + + /** + * Delete the active instance of an USB descriptor of bDescriptorType type. + */ + void delDescriptor(uint8_t bDescriptorType); + + /** + * Returns true if the descriptor state contains a USB descriptor of type bDescriptorType. + */ + bool haveDescriptor(uint8_t bDescriptorType) const; + + /** + * Returns a vector of (bDescriptorType, count) pairs. + */ + const std::vector> getDescriptorCounts() const; + + private: + USBDescriptorParserHooks& _hooks; + + std::unordered_map> _dstate_map; /**< Descriptor State Map */ + std::unordered_map _count_map; + }; + + void DLL_PUBLIC USBParseDeviceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); + void DLL_PUBLIC USBParseConfigurationDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); + void DLL_PUBLIC USBParseInterfaceDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); + void DLL_PUBLIC USBParseEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); + void DLL_PUBLIC USBParseAudioEndpointDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); + void DLL_PUBLIC USBParseUnknownDescriptor(USBDescriptorParser* parser, const USBDescriptor* descriptor_raw, USBDescriptor* descriptor_out); + +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/USBGuard.cpp b/src/Library/public/usbguard/USBGuard.cpp new file mode 100644 index 0000000..212db63 --- /dev/null +++ b/src/Library/public/usbguard/USBGuard.cpp @@ -0,0 +1,77 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#ifdef HAVE_BUILD_CONFIG_H +#include +#endif + +#include "USBGuard.hpp" +#include "ConfigFile.hpp" +#include "Exception.hpp" +#include "Logger.hpp" + +#include +#include + +#ifndef USBGUARD_DAEMON_CONF_PATH +# warning "Using hard-coded USBGUARD_DAEMON_CONF_PATH value" +# define USBGUARD_DAEMON_CONF_PATH "/etc/usbguard/usbguard-daemon.conf" +#endif + +namespace usbguard +{ + std::string getDaemonConfigPath() + { + USBGUARD_LOG(Trace); + const char * const envval = getenv("USBGUARD_DAEMON_CONF"); + + if (envval != nullptr) { + USBGUARD_LOG(Debug) << "Returning environment variable path: " << envval; + return std::string(envval); + } + else { + USBGUARD_LOG(Debug) << "Returning build-time path: " << USBGUARD_DAEMON_CONF_PATH; + return std::string(USBGUARD_DAEMON_CONF_PATH); + } + } + + std::string getIPCAccessControlFilesPath() + { + USBGUARD_LOG(Trace); + const std::string daemon_conf_path = getDaemonConfigPath(); + ConfigFile daemon_conf; + daemon_conf.open(daemon_conf_path); + + if (daemon_conf.hasSettingValue("IPCAccessControlFiles")) { + return daemon_conf.getSettingValue("IPCAccessControlFiles"); + } + + throw Exception("getIPCAccessControlFilesPath", daemon_conf_path, "IPCAccessControlFiles not set"); + } + + std::string getIPCAccessControlFileBasename(const std::string& name, bool is_group) + { + USBGUARD_LOG(Trace) << "name=" << name << " is_group=" << is_group; + std::string basename; + if (is_group) { + basename.append(":"); + } + basename.append(name); + return basename; + } +} /* namespace usbguard */ diff --git a/src/Library/public/usbguard/USBGuard.hpp b/src/Library/public/usbguard/USBGuard.hpp new file mode 100644 index 0000000..fff4082 --- /dev/null +++ b/src/Library/public/usbguard/USBGuard.hpp @@ -0,0 +1,30 @@ +// +// Copyright (C) 2017 Red Hat, Inc. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// Authors: Daniel Kopecek +// +#pragma once + +#include "Typedefs.hpp" + +#include + +namespace usbguard +{ + DLL_PUBLIC std::string getDaemonConfigPath(); + DLL_PUBLIC std::string getIPCAccessControlFilesPath(); + DLL_PUBLIC std::string getIPCAccessControlFileBasename(const std::string& name, bool is_group); +} /* namespace usbguard */ diff --git a/src/Tests/Makefile.am b/src/Tests/Makefile.am index 06ecd08..7d93474 100644 --- a/src/Tests/Makefile.am +++ b/src/Tests/Makefile.am @@ -17,8 +17,9 @@ ## Authors: Daniel Kopecek ## AM_CPPFLAGS=\ - -I$(top_srcdir)/src\ - -I$(top_srcdir)/src/Library\ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/Library \ + -I$(top_srcdir)/src/Library/public \ @catch_CFLAGS@ EXTRA_DIST=\ diff --git a/src/Tests/Regression/test_Rule_ghi113.cpp b/src/Tests/Regression/test_Rule_ghi113.cpp index 9e5e36a..52e590b 100644 --- a/src/Tests/Regression/test_Rule_ghi113.cpp +++ b/src/Tests/Regression/test_Rule_ghi113.cpp @@ -16,8 +16,9 @@ // // Authors: Daniel Kopecek // +#include "usbguard/Rule.hpp" + #include -#include using namespace usbguard; diff --git a/src/Tests/Regression/test_Rule_ghi37.cpp b/src/Tests/Regression/test_Rule_ghi37.cpp index 89fa492..5c45050 100644 --- a/src/Tests/Regression/test_Rule_ghi37.cpp +++ b/src/Tests/Regression/test_Rule_ghi37.cpp @@ -16,8 +16,9 @@ // // Authors: Daniel Kopecek // +#include "usbguard/Rule.hpp" + #include -#include using namespace usbguard; diff --git a/src/Tests/Unit/test_IPCServer_AccessControl.cpp b/src/Tests/Unit/test_IPCServer_AccessControl.cpp index ea708db..4ddd48a 100644 --- a/src/Tests/Unit/test_IPCServer_AccessControl.cpp +++ b/src/Tests/Unit/test_IPCServer_AccessControl.cpp @@ -16,8 +16,9 @@ // // Authors: Daniel Kopecek // +#include "usbguard/IPCServer.hpp" + #include -#include #include using namespace usbguard; diff --git a/src/Tests/Unit/test_Rule.cpp b/src/Tests/Unit/test_Rule.cpp index 71f7fb0..22c7855 100644 --- a/src/Tests/Unit/test_Rule.cpp +++ b/src/Tests/Unit/test_Rule.cpp @@ -16,8 +16,9 @@ // // Authors: Daniel Kopecek // +#include "usbguard/Rule.hpp" + #include -#include using namespace usbguard; @@ -43,7 +44,6 @@ TEST_CASE("Default constructed rule", "[Rule]") { REQUIRE(rule.attributeHash().empty()); REQUIRE(rule.attributeViaPort().empty()); REQUIRE(rule.attributeWithInterface().empty()); - REQUIRE(rule.getTimeoutSeconds() == 0); } SECTION("is not valid") { diff --git a/src/Tests/Unit/test_RuleAttribute_id.cpp b/src/Tests/Unit/test_RuleAttribute_id.cpp index 9e76cdd..8216f96 100644 --- a/src/Tests/Unit/test_RuleAttribute_id.cpp +++ b/src/Tests/Unit/test_RuleAttribute_id.cpp @@ -16,8 +16,9 @@ // // Authors: Daniel Kopecek // +#include "usbguard/Rule.hpp" + #include -#include using namespace usbguard; diff --git a/src/Tests/Unit/test_RuleParser.cpp b/src/Tests/Unit/test_RuleParser.cpp index 106997c..e4d3410 100644 --- a/src/Tests/Unit/test_RuleParser.cpp +++ b/src/Tests/Unit/test_RuleParser.cpp @@ -16,8 +16,9 @@ // // Authors: Daniel Kopecek // +#include "usbguard/Rule.hpp" + #include -#include using namespace usbguard; @@ -72,7 +73,7 @@ TEST_CASE("Non-printable characters in a rule string", "[RuleParser]") { } SECTION("to/from string: allow via-port \"\"") { - const std::vector one_non_printable_string = { non_printable_string }; + const std::vector one_non_printable_string = { non_printable_string }; rule.setTarget(Rule::Target::Allow); rule.attributeViaPort().set(one_non_printable_string, Rule::SetOperator::Equals); @@ -87,7 +88,7 @@ TEST_CASE("Non-printable characters in a rule string", "[RuleParser]") { } SECTION("to/from string: allow via-port { \"\" \"\" }") { - const std::vector two_non_printable_strings = \ + const std::vector two_non_printable_strings = \ { non_printable_string, non_printable_string }; rule.setTarget(Rule::Target::Allow); rule.attributeViaPort().set(two_non_printable_strings, Rule::SetOperator::OneOf); @@ -153,7 +154,7 @@ TEST_CASE("Double quote and backslash characters in a rule string", "[RuleParser } SECTION("to/from string: allow via-port \"\"") { - const std::vector one_dqb_string = { dqb_string }; + const std::vector one_dqb_string = { dqb_string }; rule.setTarget(Rule::Target::Allow); rule.attributeViaPort().set(one_dqb_string, Rule::SetOperator::Equals); @@ -168,7 +169,7 @@ TEST_CASE("Double quote and backslash characters in a rule string", "[RuleParser } SECTION("to/from string: allow via-port { \"\" \"\" }") { - const std::vector two_dqb_strings = { dqb_string, dqb_string }; + const std::vector two_dqb_strings = { dqb_string, dqb_string }; rule.setTarget(Rule::Target::Allow); rule.attributeViaPort().set(two_dqb_strings, Rule::SetOperator::OneOf); diff --git a/src/Tests/Unit/test_UEvent.cpp b/src/Tests/Unit/test_UEvent.cpp index 59b5460..4d7e593 100644 --- a/src/Tests/Unit/test_UEvent.cpp +++ b/src/Tests/Unit/test_UEvent.cpp @@ -26,7 +26,7 @@ TEST_CASE("Default constructed UEvent", "[UEvent]") { SECTION("empty") { REQUIRE_NOTHROW(uevent.getAttribute("KEY1")); - REQUIRE(uevent.getAttribute("KEY1") == String()); + REQUIRE(uevent.getAttribute("KEY1") == std::string()); REQUIRE_FALSE(uevent.hasAttribute("KEY1")); REQUIRE_FALSE(uevent.hasRequiredAttributes()); REQUIRE_NOTHROW(uevent.clear()); @@ -55,7 +55,7 @@ TEST_CASE("UEvent with required attributes", "[UEvent]") { SECTION("non-existing attribute") { REQUIRE_NOTHROW(uevent.getAttribute("KEY1")); - REQUIRE(uevent.getAttribute("KEY1") == String()); + REQUIRE(uevent.getAttribute("KEY1") == std::string()); REQUIRE_FALSE(uevent.hasAttribute("KEY1")); } diff --git a/src/Tests/Unit/test_UEventParser.cpp b/src/Tests/Unit/test_UEventParser.cpp index 8bd4358..5bb2384 100644 --- a/src/Tests/Unit/test_UEventParser.cpp +++ b/src/Tests/Unit/test_UEventParser.cpp @@ -58,7 +58,7 @@ TEST_CASE("UEvent parsing", "[UEventParser]") { const size_t uevent_strlen = sizeof uevent_string; UEvent uevent; - REQUIRE_NOTHROW(uevent = UEvent::fromString(String(uevent_string, uevent_strlen), + REQUIRE_NOTHROW(uevent = UEvent::fromString(std::string(uevent_string, uevent_strlen), /*attributes_only=*/false, /*trace=*/true)); REQUIRE(uevent.hasRequiredAttributes()); diff --git a/src/Tests/Unit/test_Utility.cpp b/src/Tests/Unit/test_Utility.cpp index 640d712..c6fcc73 100644 --- a/src/Tests/Unit/test_Utility.cpp +++ b/src/Tests/Unit/test_Utility.cpp @@ -30,14 +30,14 @@ TEST_CASE("parentPath", "[Utility]") { REQUIRE(parentPath("/foo/bar") == "/foo"); REQUIRE(parentPath("/foo/bar/") == "/foo"); REQUIRE(parentPath("/foo/bar//") == "/foo"); - REQUIRE(parentPath("/foo") == String()); - REQUIRE(parentPath("/foo/") == String()); - REQUIRE(parentPath("/") == String()); - REQUIRE(parentPath("//") == String()); - REQUIRE(parentPath("///") == String()); - REQUIRE(parentPath("//foo") == String()); - REQUIRE(parentPath("//foo//") == String()); - REQUIRE(parentPath("") == String()); - REQUIRE(parentPath(String()) == String()); + REQUIRE(parentPath("/foo") == std::string()); + REQUIRE(parentPath("/foo/") == std::string()); + REQUIRE(parentPath("/") == std::string()); + REQUIRE(parentPath("//") == std::string()); + REQUIRE(parentPath("///") == std::string()); + REQUIRE(parentPath("//foo") == std::string()); + REQUIRE(parentPath("//foo//") == std::string()); + REQUIRE(parentPath("") == std::string()); + REQUIRE(parentPath(std::string()) == std::string()); }