Skip to content

Commit 01c9eba

Browse files
Add insertRule method
1 parent 57022f1 commit 01c9eba

25 files changed

+323
-57
lines changed

doc/man/usbguard.1.adoc

+7-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,13 @@ Append the 'rule' to the current rule set.
157157
Available options:
158158

159159
*-a, --after* 'id'::
160-
Append the new rule after a rule with the specified rule 'id'.
160+
Append the new rule after a rule with the specified rule 'id'
161+
instead of appending it at the end of the rule set.
162+
If 'id' is 0, then the rule is appended to the beginning
163+
of the rule set.
164+
165+
*-r, --ruleset* 'prefix'::
166+
Append the new rule into a rule set with specified prefix.
161167

162168
*-t, --temporary*::
163169
Make the decision temporary. The rule policy file will not be updated.

scripts/bash_completion/usbguard

+4-1
Original file line numberDiff line numberDiff line change
@@ -303,11 +303,14 @@ function _usbguard()
303303
if _usbguard_contains "-a --after" $prev; then
304304
opts=$(_usbguard_get_rules || :)
305305

306+
elif _usbguard_contains "-r --ruleset" $prev; then
307+
return 0
308+
306309
elif ! _usbguard_in_option && [[ $args -eq 2 ]]; then
307310
return 0
308311

309312
else
310-
opts="$opts -a --after -t --temporary"
313+
opts="$opts -a --after -r --ruleset -t --temporary"
311314
fi
312315
;;
313316

scripts/usbguard-zsh-completion

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ case $state in
113113
'<rule>[rule]'
114114
_command_args=( \
115115
'(--after)--after <id>[Append the new rule after a rule with the specified id instead of appending it]' \
116+
'(--ruleset)--ruleset <prefix>[Append the new rule into a ruleset with specified prefix.]' \
116117
'(--help)--help[Show help]'
117118
)
118119
;;

src/CLI/usbguard-append-rule.cpp

+16-7
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@
2929

3030
namespace usbguard
3131
{
32-
static const char* options_short = "ha:t";
32+
static const char* options_short = "ha:r:t";
3333

3434
static const struct ::option options_long[] = {
3535
{ "help", no_argument, nullptr, 'h' },
3636
{ "after", required_argument, nullptr, 'a' },
37+
{ "ruleset", required_argument, nullptr, 'r' },
3738
{ "temporary", no_argument, nullptr, 't' },
3839
{ nullptr, 0, nullptr, 0 }
3940
};
@@ -43,17 +44,21 @@ namespace usbguard
4344
stream << " Usage: " << usbguard_arg0 << " append-rule [OPTIONS] <rule>" << std::endl;
4445
stream << std::endl;
4546
stream << " Options:" << std::endl;
46-
stream << " -a, --after <id> Append the new rule after a rule with the specified id" << std::endl;
47-
stream << " instead of appending it at the end of the rule set." << std::endl;
48-
stream << " -t, --temporary Make the decision temporary. The rule policy file will not" << std::endl;
49-
stream << " be updated." << std::endl;
50-
stream << " -h, --help Show this help." << std::endl;
47+
stream << " -a, --after <id> Append the new rule after a rule with the specified id" << std::endl;
48+
stream << " instead of appending it at the end of the rule set." << std::endl;
49+
stream << " If 'id' is 0, then the rule is appended to the beginning" << std::endl;
50+
stream << " of the rule set." << std::endl;
51+
stream << " -r, --ruleset <prefix> Append the new rule into a ruleset with specified prefix." << std::endl;
52+
stream << " -t, --temporary Make the decision temporary. The rule policy file will not" << std::endl;
53+
stream << " be updated." << std::endl;
54+
stream << " -h, --help Show this help." << std::endl;
5155
stream << std::endl;
5256
}
5357

5458
int usbguard_append_rule(int argc, char* argv[])
5559
{
5660
uint32_t parent_id = usbguard::Rule::LastID;
61+
std::string ruleset;
5762
bool permanent = true;
5863
int opt = 0;
5964

@@ -67,6 +72,10 @@ namespace usbguard
6772
parent_id = std::stoul(optarg);
6873
break;
6974

75+
case 'r':
76+
ruleset = optarg;
77+
break;
78+
7079
case 't':
7180
permanent = false;
7281
break;
@@ -89,7 +98,7 @@ namespace usbguard
8998

9099
usbguard::IPCClient ipc(/*connected=*/true);
91100
const std::string rule_spec = argv[0];
92-
const uint32_t id = ipc.appendRule(rule_spec, parent_id, permanent);
101+
const uint32_t id = ipc.insertRule(rule_spec, parent_id, ruleset, permanent);
93102
std::cout << id << std::endl;
94103
return EXIT_SUCCESS;
95104
}

src/DBus/DBusBridge.cpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,19 @@ namespace usbguard
135135
return;
136136
}
137137

138+
if (method_name == "insertRule") {
139+
const char* rule_spec_cstr = nullptr;
140+
uint32_t parent_id = 0;
141+
const char* ruleset_cstr = nullptr;
142+
gboolean temporary = false;
143+
g_variant_get(parameters, "(&sub)", &rule_spec_cstr, &parent_id, &ruleset_cstr, &temporary);
144+
std::string rule_spec(rule_spec_cstr);
145+
std::string ruleset(ruleset_cstr);
146+
const uint32_t rule_id = insertRule(rule_spec, parent_id, ruleset, !temporary);
147+
g_dbus_method_invocation_return_value(invocation, g_variant_new("(u)", rule_id));
148+
return;
149+
}
150+
138151
if (method_name == "appendRule") {
139152
const char* rule_spec_cstr = nullptr;
140153
uint32_t parent_id = 0;
@@ -337,11 +350,9 @@ namespace usbguard
337350
g_variant_builder_add(builder, "{ss}",
338351
"with-interface",
339352
with_interface_string.c_str());
340-
341353
g_variant_builder_add(builder, "{ss}",
342354
"with-connect-type",
343355
device_rule.getWithConnectType().c_str());
344-
345356
return builder;
346357
}
347358
} /* namespace usbguard */

src/DBus/DBusInterface.xml

+24
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,30 @@
7474
<arg name="ruleset" direction="out" type="a(us)"/>
7575
</method>
7676

77+
<!--
78+
insertRule:
79+
@rule: The rule that should be appended to the policy.
80+
@parent_id: Rule id of the parent rule.
81+
@ruleset: Prefix of a ruleset where the rule should be appended.
82+
@temporary: A boolean to avoid adding this rule to the policy file.
83+
@id: The rule id assigned to the succesfully appended rule.
84+
85+
Append a new rule to the current policy. Using the parent_id
86+
parameter and ruleset prefix, the rule can be inserted anywhere in the
87+
policy. 4294967293 (UINT32_MAX-2) is the last possible
88+
ID and thus, when using this as parent_id, the rule is effectively
89+
appended to the end of the ruleset. If parent_id is 0, the rule is
90+
appended to the beginning of the ruleset. When the rule is successfully
91+
appended, the id assigned to the new rule is returned.
92+
-->
93+
<method name="insertRule">
94+
<arg name="rule" direction="in" type="s"/>
95+
<arg name="parent_id" direction="in" type="u"/>
96+
<arg name="ruleset" direction="in" type="s"/>
97+
<arg name="temporary" direction="in" type="b"/>
98+
<arg name="id" direction="out" type="u"/>
99+
</method>
100+
77101
<!--
78102
appendRule:
79103
@rule: The rule that should be appended to the policy.

src/DBus/org.usbguard1.policy

+9
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,15 @@
1515
</defaults>
1616
</action>
1717

18+
<action id="org.usbguard.Policy1.insertRule">
19+
<description>Append a new rule to the policy</description>
20+
<message>Prevents from appending rules to the USBGuard policy</message>
21+
<defaults>
22+
<allow_inactive>no</allow_inactive>
23+
<allow_active>auth_admin</allow_active>
24+
</defaults>
25+
</action>
26+
1827
<action id="org.usbguard.Policy1.appendRule">
1928
<description>Append a new rule to the policy</description>
2029
<message>Prevents from appending rules to the USBGuard policy</message>

src/Daemon/Daemon.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,25 @@ namespace usbguard
730730
}
731731
}
732732

733+
uint32_t Daemon::insertRule(const std::string& rule_spec,
734+
uint32_t parent_id, const std::string& ruleset, bool permanent)
735+
{
736+
USBGUARD_LOG(Trace) << "entry:"
737+
<< " rule_spec=" << rule_spec
738+
<< " parent_id=" << parent_id
739+
<< " ruleset=" << ruleset;
740+
const Rule rule = Rule::fromString(rule_spec);
741+
/* TODO: reevaluate the firewall rules for all active devices */
742+
const uint32_t id = _policy.insertRule(rule, parent_id, ruleset);
743+
744+
if (_config.hasSettingValue("RuleFile") && permanent) {
745+
_policy.save();
746+
}
747+
748+
USBGUARD_LOG(Trace) << "return: id=" << id;
749+
return id;
750+
}
751+
733752
uint32_t Daemon::appendRule(const std::string& rule_spec,
734753
uint32_t parent_id, bool permanent)
735754
{

src/Daemon/Daemon.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ namespace usbguard
8787
std::string setParameter(const std::string& name, const std::string& value) override;
8888
std::string getParameter(const std::string& name) override;
8989

90+
uint32_t insertRule(const std::string& rule_spec, uint32_t parent_id, const std::string& ruleset, bool permanent) override;
9091
uint32_t appendRule(const std::string& rule_spec, uint32_t parent_id, bool permanent) override;
9192
void removeRule(uint32_t id) override;
9293
const std::vector<Rule> listRules(const std::string& query) override;

src/Daemon/FileRuleSet.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
#include "FileRuleSet.hpp"
2424

25+
#include "Common/Utility.hpp"
2526
#include "usbguard/Typedefs.hpp"
2627
#include "usbguard/Rule.hpp"
2728
#include "usbguard/RuleParser.hpp"
@@ -36,6 +37,7 @@ namespace usbguard
3637
: RuleSet(interface_ptr),
3738
_rulesPath(path)
3839
{
40+
setName(filenameFromPath(path, false));
3941
setWritable();
4042
USBGUARD_LOG(Info) << "Creating FileRuleSet";
4143
}

src/Daemon/RuleSetFactory.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ namespace usbguard
7575
}
7676
}
7777

78-
if (ruleSet.empty()){
78+
if (ruleSet.empty()) {
7979
USBGUARD_LOG(Warning) << "RuleFile not set; Modification of the permanent policy won't be possible.";
8080
ruleSet = generateDefaultRuleSet();
8181
}

src/Library/IPC/Policy.proto

+18
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,24 @@ message listRules {
1818
}
1919

2020

21+
message insertRuleRequest {
22+
required string rule = 1;
23+
required uint32 parent_id = 2;
24+
required string ruleset = 3;
25+
required bool permanent = 4;
26+
}
27+
28+
message insertRuleResponse {
29+
required uint32 id = 1;
30+
}
31+
32+
message insertRule {
33+
required MessageHeader header = 1;
34+
required insertRuleRequest request = 2;
35+
optional insertRuleResponse response = 3;
36+
}
37+
38+
2139
message appendRuleRequest {
2240
required string rule = 1;
2341
required uint32 parent_id = 2;

src/Library/IPCClientPrivate.cpp

+17-4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ namespace usbguard
7777
registerHandler<IPC::getParameter>(&IPCClientPrivate::handleMethodResponse);
7878
registerHandler<IPC::setParameter>(&IPCClientPrivate::handleMethodResponse);
7979
registerHandler<IPC::listRules>(&IPCClientPrivate::handleMethodResponse);
80+
registerHandler<IPC::insertRule>(&IPCClientPrivate::handleMethodResponse);
8081
registerHandler<IPC::appendRule>(&IPCClientPrivate::handleMethodResponse);
8182
registerHandler<IPC::removeRule>(&IPCClientPrivate::handleMethodResponse);
8283
registerHandler<IPC::applyDevicePolicy>(&IPCClientPrivate::handleMethodResponse);
@@ -143,7 +144,6 @@ namespace usbguard
143144
<< " do_wait=" << do_wait;
144145
USBGUARD_LOG(Trace) << "_qb_conn=" << _qb_conn
145146
<< " _qb_fd=" << _qb_fd;
146-
147147
std::unique_lock<std::mutex> disconnect_lock(_disconnect_mutex);
148148

149149
if (_qb_conn != nullptr && _qb_fd >= 0) {
@@ -386,6 +386,18 @@ namespace usbguard
386386
return message_in->response().value();
387387
}
388388

389+
uint32_t IPCClientPrivate::insertRule(const std::string& rule_spec,
390+
uint32_t parent_id, const std::string& ruleset, bool permanent)
391+
{
392+
IPC::insertRule message_out;
393+
message_out.mutable_request()->set_rule(rule_spec);
394+
message_out.mutable_request()->set_parent_id(parent_id);
395+
message_out.mutable_request()->set_ruleset(ruleset);
396+
message_out.mutable_request()->set_permanent(permanent);
397+
auto message_in = qbIPCSendRecvMessage(message_out);
398+
return message_in->response().id();
399+
}
400+
389401
uint32_t IPCClientPrivate::appendRule(const std::string& rule_spec, uint32_t parent_id, bool permanent)
390402
{
391403
IPC::appendRule message_out;
@@ -445,16 +457,17 @@ namespace usbguard
445457
return devices;
446458
}
447459

448-
bool IPCClientPrivate::checkIPCPermissions(const IPCServer::AccessControl::Section& section, const IPCServer::AccessControl::Privilege& privilege)
460+
bool IPCClientPrivate::checkIPCPermissions(const IPCServer::AccessControl::Section& section,
461+
const IPCServer::AccessControl::Privilege& privilege)
449462
{
450463
IPC::checkIPCPermissions message_out;
451464
message_out.mutable_request()->set_uid(getuid());
452465
message_out.mutable_request()->set_gid(getgid());
453466
message_out.mutable_request()->set_section(
454-
IPCServer::AccessControl::sectionToString(section)
467+
IPCServer::AccessControl::sectionToString(section)
455468
);
456469
message_out.mutable_request()->set_privilege(
457-
IPCServer::AccessControl::privilegeToString(privilege)
470+
IPCServer::AccessControl::privilegeToString(privilege)
458471
);
459472
auto message_in = qbIPCSendRecvMessage(message_out);
460473
return message_in->response().permit();

src/Library/IPCClientPrivate.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,16 @@ namespace usbguard
5858
std::string setParameter(const std::string& name, const std::string& value);
5959
std::string getParameter(const std::string& name);
6060

61+
uint32_t insertRule(const std::string& rule_spec, uint32_t parent_id, const std::string& ruleset, bool permanent);
6162
uint32_t appendRule(const std::string& rule_spec, uint32_t parent_id, bool permanent);
6263
void removeRule(uint32_t id);
6364
const std::vector<Rule> listRules(const std::string& label);
6465

6566
uint32_t applyDevicePolicy(uint32_t id, Rule::Target target, bool permanent);
6667
const std::vector<Rule> listDevices(const std::string& query);
6768

68-
bool checkIPCPermissions(const IPCServer::AccessControl::Section& section, const IPCServer::AccessControl::Privilege& privilege);
69+
bool checkIPCPermissions(const IPCServer::AccessControl::Section& section,
70+
const IPCServer::AccessControl::Privilege& privilege);
6971

7072
void processReceiveEvent();
7173

src/Library/IPCPrivate.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,13 @@ namespace usbguard
4040
{ 0x04, "usbguard.IPC.DevicePolicyChangedSignal" },
4141
{ 0x05, "usbguard.IPC.PropertyParameterChangedSignal" },
4242
{ 0x06, "usbguard.IPC.listRules" },
43-
{ 0x07, "usbguard.IPC.appendRule" },
44-
{ 0x08, "usbguard.IPC.removeRule" },
45-
{ 0x09, "usbguard.IPC.Exception" },
46-
{ 0x0a, "usbguard.IPC.getParameter" },
47-
{ 0x0b, "usbguard.IPC.setParameter" },
48-
{ 0x0c, "usbguard.IPC.checkIPCPermissions" }
43+
{ 0x07, "usbguard.IPC.insertRule" },
44+
{ 0x08, "usbguard.IPC.appendRule" },
45+
{ 0x09, "usbguard.IPC.removeRule" },
46+
{ 0x0a, "usbguard.IPC.Exception" },
47+
{ 0x0b, "usbguard.IPC.getParameter" },
48+
{ 0x0c, "usbguard.IPC.setParameter" },
49+
{ 0x0d, "usbguard.IPC.checkIPCPermissions" }
4950
};
5051

5152
uint32_t IPC::messageTypeNameToNumber(const std::string& name)

0 commit comments

Comments
 (0)