Rule management added.
[platform/core/security/suspicious-activity-monitor.git] / daemon / dpm / policy_enforce.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   policy_enforce.cpp
20  * @brief  Policy group agregator
21  * @date   Created Jul 01, 2016
22  * @author Mail to: <A HREF="mailto:a.volkov@samsung.com">Aleksey Volkov, a.volkov@samsung.com</A>
23  */
24
25 #include "policy_enforce.h"
26 #include <jsoncpp/json/reader.h>
27 #include "ipolicy.h"
28 #include "logging.h"
29 #include "samonitor_tag.h"
30 #include "../utils.h"
31
32 namespace
33 {
34
35 #define DPM_OWNER_NAME "owner"
36
37 class DpmHandle
38 {
39 public:
40     DpmHandle()
41     {
42         m_handle = dpm_manager_create();
43     }
44     ~DpmHandle()
45     {
46         dpm_manager_destroy(m_handle);
47     }
48     operator device_policy_manager_h () const {
49         return m_handle;
50     }
51     operator bool () const {
52         return m_handle != nullptr;
53     }
54 private:
55     device_policy_manager_h m_handle;
56 };
57
58 struct DropPrivilege
59 {
60     DropPrivilege(uid_t from, uid_t to): euid(from), cuid(to)
61     {
62         if (0 != setresuid(cuid, cuid, euid)) {
63             throw std::runtime_error("Failed to drop privilege error code: " + std::to_string(errno));
64         }
65     }
66
67     ~DropPrivilege()
68     {
69         (void)setresuid(euid, euid, -1);
70     }
71
72     uid_t euid, cuid;
73 };
74
75 }
76
77 namespace dpm
78 {
79
80 PolicyEnforce::PolicyEnforce() : m_policy_map()
81 {
82     this_user = geteuid();
83     dpm_user = agent::getUidByName(DPM_OWNER_NAME);
84 }
85
86 PolicyEnforce::~PolicyEnforce()
87 {
88 }
89
90 PolicyEnforce& PolicyEnforce::GetInstance()
91 {
92     static PolicyEnforce policy_enforce;
93     return policy_enforce;
94 }
95
96 void PolicyEnforce::registerPolicy(const std::string& policy_name, IPolicyPtr policy_applier)
97 {
98     m_policy_map[policy_name] = policy_applier;
99 }
100
101 PolicyEnforce::Result PolicyEnforce::applyPolicy(const std::string& jsonString)
102 {
103     Result result = Result::SUCCESS;
104
105     LOG_D(TAG, "PolicyEnforce::applyPolicy");
106
107     try {
108         if (jsonString.empty()) {
109             LOG_E(TAG, "Empty policy");
110             return Result::ERROR_PARSING;
111         }
112
113         Json::Reader reader;
114         Json::Value object;
115         if (!reader.parse(jsonString, object) || object.empty()) {
116             LOG_E(TAG, "Can't read policy");
117             return Result::ERROR_PARSING;
118         }
119
120         if (object["type"].asString() != "policy") {
121             LOG_E(TAG, "Invalid policy type");
122             return Result::ERROR_TYPE;
123         }
124
125         Json::Value& data = object["data"];
126         if (data.empty()) {
127             LOG_E(TAG, "Empty policy data");
128             return Result::ERROR_DATA;
129         }
130
131         DropPrivilege priv{this_user, dpm_user};
132
133         DpmHandle dpmh;
134         if (!dpmh) {
135             LOG_E(TAG, "DPM initialization error!");
136             return Result::ERROR_DPM;
137         }
138
139         for (auto& node : data) {
140             std::string name = node.get("name", "").asString();
141
142             PolicyMap::iterator it = m_policy_map.find(name);
143             if (it == m_policy_map.end()) {
144                 LOG_E(TAG, "Policy \"%s\" not found", name.c_str());
145                 continue;
146             }
147
148             IPolicy& applier = *(it->second);
149             if (applier.apply((device_policy_manager_h)dpmh, node) != TIZEN_ERROR_NONE) {
150                 LOG_E(TAG, "Failed to apply policy \"%s\"", name.c_str());
151             }
152         }
153     } catch (std::exception& e) {
154         LOG_E(TAG, "Failed to apply policy, exception: %s", e.what());
155         result = Result::ERROR_UNKNOWN;
156     }
157
158     return result;
159 }
160
161 PolicyEnforce::Result PolicyEnforce::getStates(Json::Value& policy)
162 {
163     Result result = Result::SUCCESS;
164
165     LOG_D(TAG, "PolicyEnforce::getStates");
166
167     try {
168         if (policy.empty()) {
169             LOG_E(TAG, "Empty policy");
170             return Result::ERROR_PARSING;
171         }
172
173         if (policy["type"].asString() != "state-policy") {
174             LOG_E(TAG, "Invalid policy type");
175             return Result::ERROR_TYPE;
176         }
177
178         Json::Value& data = policy["data"];
179         if (data.empty()) {
180             LOG_E(TAG, "Empty policy data");
181             return Result::ERROR_DATA;
182         }
183
184         DropPrivilege priv{this_user, dpm_user};
185
186         DpmHandle dpmh;
187         if (!dpmh) {
188             LOG_E(TAG, "DPM initialization error!");
189             return Result::ERROR_DPM;
190         }
191
192         for (Json::Value& node : data) {
193             std::string name = node.get("name", "").asString();
194
195             PolicyMap::iterator it = m_policy_map.find(name);
196             if (it == m_policy_map.end()) {
197                 LOG_E(TAG, "Policy \"%s\" not found", name.c_str());
198                 continue;
199             }
200
201             IPolicy& applier = *(it->second);
202             if (applier.getState((device_policy_manager_h)dpmh, node) != TIZEN_ERROR_NONE) {
203                 LOG_E(TAG, "Failed to get policy \"%s\" state", name.c_str());
204             }
205         }
206     } catch (std::exception& e) {
207         LOG_E(TAG, "Failed to get policy state, exception: %s", e.what());
208         result = Result::ERROR_UNKNOWN;
209     }
210
211     return result;
212 }
213
214 } //namespace dpm