9bba6898a92c1d26cd8e334865daf243d100e90e
[platform/core/security/suspicious-activity-monitor.git] / daemon / audit / rule.cpp
1 /**
2  * Samsung Ukraine R&D Center (SRK under a contract between)
3  * LLC "Samsung Electronics Co", Ltd (Seoul, Republic of Korea)
4  * Copyright (C) 2018 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License
17  */
18 /**
19  * @file   rule.cpp
20  * @brief  Audit rule representation
21  * @date   Created Apr 04, 2018
22  * @author Mail to: <A HREF="mailto:i.metelytsia@samsung.com">Iurii Metelytsia, i.metelytsia@samsung.com</A>
23  */
24
25 #include <algorithm>
26 #include <sstream>
27 #include <stdexcept>
28 #include <cassert>
29
30 #include "logging.h"
31 #include "samonitor_tag.h"
32
33 #include "rule.h"
34
35 namespace audit
36 {
37
38 const std::map<int, Field::FieldData> Field::s_fields = {
39     {AUDIT_PID, {"pid", FieldType::t_int}},
40     {AUDIT_UID, {"uid", FieldType::t_int}},
41     {AUDIT_EUID, {"euid", FieldType::t_int}},
42     {AUDIT_SUID, {"suid", FieldType::t_int}},
43     {AUDIT_FSUID, {"fsuid", FieldType::t_int}},
44     {AUDIT_GID, {"gid", FieldType::t_int}},
45     {AUDIT_EGID, {"egid", FieldType::t_int}},
46     {AUDIT_SGID, {"sgid", FieldType::t_int}},
47     {AUDIT_FSGID, {"fsgid", FieldType::t_int}},
48     {AUDIT_LOGINUID, {"loginuid", FieldType::t_int}},
49     {AUDIT_PERS, {"pers", FieldType::t_int}},
50     {AUDIT_ARCH, {"arch", FieldType::t_str}},
51     {AUDIT_MSGTYPE, {"msgtype", FieldType::t_int}},
52     {AUDIT_SUBJ_USER, {"subj_user", FieldType::t_str}},
53     {AUDIT_SUBJ_ROLE, {"subj_role", FieldType::t_str}},
54     {AUDIT_SUBJ_TYPE, {"subj_type", FieldType::t_str}},
55     {AUDIT_SUBJ_SEN, {"subj_sen", FieldType::t_str}},
56     {AUDIT_SUBJ_CLR, {"subj_clr", FieldType::t_str}},
57     {AUDIT_PPID, {"ppid", FieldType::t_int}},
58     {AUDIT_OBJ_USER, {"obj_user", FieldType::t_str}},
59     {AUDIT_OBJ_ROLE, {"obj_role", FieldType::t_str}},
60     {AUDIT_OBJ_TYPE, {"obj_type", FieldType::t_str}},
61     {AUDIT_OBJ_LEV_LOW, {"obj_lev_low", FieldType::t_str}},
62     {AUDIT_OBJ_LEV_HIGH, {"obj_lev_high", FieldType::t_str}},
63     {AUDIT_LOGINUID_SET, {"loginuid_set", FieldType::t_int}},
64     {AUDIT_DEVMAJOR, {"dev_major", FieldType::t_int}},
65     {AUDIT_DEVMINOR, {"dev_minor", FieldType::t_int}},
66     {AUDIT_INODE, {"inode", FieldType::t_int}},
67     {AUDIT_EXIT, {"exit", FieldType::t_int}},
68     {AUDIT_SUCCESS, {"success", FieldType::t_int}},
69     {AUDIT_WATCH, {"watch", FieldType::t_str}},
70     {AUDIT_PERM, {"perm", FieldType::t_int}},
71     {AUDIT_DIR, {"dir", FieldType::t_str}},
72     {AUDIT_FILETYPE, {"filetype", FieldType::t_int}},
73     {AUDIT_OBJ_UID, {"obj_uid", FieldType::t_int}},
74     {AUDIT_OBJ_GID, {"obj_gid", FieldType::t_int}},
75     {AUDIT_FIELD_COMPARE, {"compare", FieldType::t_int}},
76     {AUDIT_ARG0, {"arg0", FieldType::t_int}},
77     {AUDIT_ARG1, {"arg1", FieldType::t_int}},
78     {AUDIT_ARG2, {"arg2", FieldType::t_int}},
79     {AUDIT_ARG3, {"arg3", FieldType::t_int}},
80     {AUDIT_FILTERKEY, {"filter_key", FieldType::t_str}},
81 };
82
83 const std::map<int, std::string> Operation::s_operations = {
84     {AUDIT_BIT_MASK, "bit_mask"},
85     {AUDIT_LESS_THAN, "less"},
86     {AUDIT_GREATER_THAN, "greater"},
87     {AUDIT_NOT_EQUAL, "not_equal"},
88     {AUDIT_EQUAL, "equal"},
89     {AUDIT_BIT_TEST, "bit_test"},
90     {AUDIT_LESS_THAN_OR_EQUAL, "less_or_equal"},
91     {AUDIT_GREATER_THAN_OR_EQUAL, "greater_or_equal"},
92 };
93
94 void syscallCallback(unsigned int syscall, void* user_data)
95 {
96     assert(user_data);
97     Rule* rule = reinterpret_cast<Rule*>(user_data);
98     rule->m_data.m_syscall.insert(syscall);
99 }
100
101 void conditionCallback(unsigned int field, unsigned int operation, const void* value, void* user_data)
102 {
103     assert(user_data);
104     Rule* rule = reinterpret_cast<Rule*>(user_data);
105     Field f(field);
106     if ((int)f == AUDIT_FILTERKEY) {
107         rule->m_data.m_key = (const char*)value;
108     } else {
109         if (f.type() == FieldType::t_int) {
110             rule->m_data.m_condition.push_back({(int)field, (int)operation, (int)value});
111         } else if (f.type() == FieldType::t_str) {
112             rule->m_data.m_condition.push_back({(int)field, (int)operation, (const char*)value});
113         }
114     }
115 }
116
117 Rule::Rule(const std::string& key) : m_handle(nullptr), m_data()
118 {
119     m_data.m_key = key;
120
121     if (audit_rule_create(&m_handle) != AUDIT_TRAIL_ERROR_NONE) {
122         throw std::runtime_error("Failed to create audit rule!");
123     }
124     if (audit_rule_add_condition(m_handle, AUDIT_FILTERKEY, AUDIT_EQUAL, (const void*)m_data.m_key.c_str()) != AUDIT_TRAIL_ERROR_NONE) {
125         throw std::runtime_error("Failed to set audit rule key!");
126     }
127 }
128 Rule::Rule(audit_rule_h handle) : m_handle(handle), m_data()
129 {
130     if (audit_rule_foreach_systemcall(m_handle, syscallCallback, this) != AUDIT_TRAIL_ERROR_NONE) {
131         throw std::runtime_error("audit_rule_foreach_systemcall failed!");
132     }
133     if (audit_rule_foreach_condition(m_handle, conditionCallback, this) != AUDIT_TRAIL_ERROR_NONE) {
134         throw std::runtime_error("audit_rule_foreach_condition failed!");
135     }
136 }
137 Rule::Rule(const RuleData& data) : m_handle(nullptr), m_data(data)
138 {
139     if (audit_rule_create(&m_handle) != AUDIT_TRAIL_ERROR_NONE) {
140         throw std::runtime_error("Failed to create audit rule!");
141     }
142
143     if (audit_rule_add_condition(m_handle, AUDIT_FILTERKEY, AUDIT_EQUAL, (const void*)m_data.m_key.c_str()) != AUDIT_TRAIL_ERROR_NONE) {
144         throw std::runtime_error("Failed to set audit rule key!");
145     }
146
147     for (int v : m_data.m_syscall) {
148         if (audit_rule_add_systemcall(m_handle, v) != AUDIT_TRAIL_ERROR_NONE) {
149             throw std::runtime_error("Can't add syscall!");
150         }
151     }
152
153     for (const Condition& c : m_data.m_condition) {
154         if (audit_rule_add_condition(m_handle, c.m_field, c.m_operation, (const void*)c.m_value) != AUDIT_TRAIL_ERROR_NONE) {
155             throw std::runtime_error("Can't add condition!");
156         }
157     }
158 }
159
160 Rule::~Rule()
161 {
162     audit_rule_destroy(m_handle);
163 }
164
165 int Rule::addSyscall(int syscall)
166 {
167     int res = 0;
168
169     if (m_data.m_syscall.find(syscall) == m_data.m_syscall.end()) {
170         if ((res = audit_rule_add_systemcall(m_handle, syscall)) == AUDIT_TRAIL_ERROR_NONE) {
171             m_data.m_syscall.insert(syscall);
172         }
173     }
174
175     return res;
176 }
177
178 int Rule::removeSyscall(int syscall)
179 {
180     int res = 0;
181
182     if (m_data.m_syscall.find(syscall) != m_data.m_syscall.end()) {
183         if ((res = audit_rule_remove_systemcall(m_handle, syscall)) == AUDIT_TRAIL_ERROR_NONE) {
184             m_data.m_syscall.erase(syscall);
185         }
186     }
187
188     return res;
189 }
190
191 int Rule::addCondition(const std::string& field, const std::string& operation, int value)
192 {
193     int res = 0;
194
195     Condition c{field, operation, value};
196     if ((res = audit_rule_add_condition(m_handle, c.m_field, c.m_operation, (const void*)value)) == AUDIT_TRAIL_ERROR_NONE) {
197         m_data.m_condition.push_back(c);
198     }
199
200     return res;
201 }
202 int Rule::addCondition(const std::string& field, const std::string& operation, const std::string& value)
203 {
204     int res = 0;
205
206     Condition c{field, operation, value};
207     if ((res = audit_rule_add_condition(m_handle, c.m_field, c.m_operation, (const void*)value.c_str())) == AUDIT_TRAIL_ERROR_NONE) {
208         m_data.m_condition.push_back(c);
209     }
210
211     return res;
212 }
213
214 int Rule::removeCondition(const std::string& field, const std::string& operation, int value)
215 {
216     int res = 0;
217
218     Condition c{field, operation, value};
219     ConditionList::iterator it = std::find(m_data.m_condition.begin(), m_data.m_condition.end(), c);
220     if (it != m_data.m_condition.end()) {
221         if ((res = audit_rule_remove_condition(m_handle, c.m_field, c.m_operation, (const void*)value)) == AUDIT_TRAIL_ERROR_NONE) {
222             m_data.m_condition.erase(it);
223         }
224     }
225
226     return res;
227 }
228 int Rule::removeCondition(const std::string& field, const std::string& operation, const std::string& value)
229 {
230     int res = 0;
231
232     Condition c{field, operation, value};
233     ConditionList::iterator it = std::find(m_data.m_condition.begin(), m_data.m_condition.end(), c);
234     if (it != m_data.m_condition.end()) {
235         if ((res = audit_rule_remove_condition(m_handle, c.m_field, c.m_operation, (const void*)value.c_str())) == AUDIT_TRAIL_ERROR_NONE) {
236             m_data.m_condition.erase(it);
237         }
238     }
239
240     return res;
241 }
242
243 } //namespace audit