Fix bug in traversing pkgmgr-info lists
[platform/core/appfw/app-installers.git] / src / common / security_registration.cc
1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/security_registration.h"
6
7 #include <security-manager.h>
8
9 #include "utils/logging.h"
10
11 /* NOTE: For *_x list types in pkgmgr-info, like privileges_x or privilege_x,
12  * this macro moves the current node to the head of the list.
13  * This LISTHEAD() macro is defined in pkgmgr_parser.h in pkgmgr-info package.
14  */
15 #define PKGMGR_LIST_MOVE_NODE_TO_HEAD(list, node) do {                        \
16     if (list) { LISTHEAD(list, node); }                                       \
17   } while (0)
18
19 namespace bf = boost::filesystem;
20
21 namespace {
22
23 bool PrepareRequest(const std::string& app_id, const std::string& pkg_id,
24     const boost::filesystem::path& path, manifest_x* manifest,
25     app_inst_req* req) {
26   if (app_id.empty() || pkg_id.empty()) {
27     LOG(ERROR) << "Appid or pkgid is empty. Both values must be set";
28     return false;
29   }
30
31   int error = security_manager_app_inst_req_set_app_id(req,
32       app_id.c_str());
33   if (error != SECURITY_MANAGER_SUCCESS) {
34     return false;
35   }
36
37   error = security_manager_app_inst_req_set_pkg_id(req,
38       pkg_id.c_str());
39   if (error != SECURITY_MANAGER_SUCCESS) {
40     return false;
41   }
42
43   if (!path.empty()) {
44     error = security_manager_app_inst_req_add_path(req, path.string().c_str(),
45         SECURITY_MANAGER_PATH_PRIVATE);
46     if (error != SECURITY_MANAGER_SUCCESS) {
47       return false;
48     }
49   }
50
51   if (manifest) {
52     privileges_x *privileges;
53     PKGMGR_LIST_MOVE_NODE_TO_HEAD(manifest->privileges, privileges);
54     for (;privileges != nullptr; privileges = privileges->next) {
55       privilege_x* priv;
56       PKGMGR_LIST_MOVE_NODE_TO_HEAD(privileges->privilege, priv);
57       for (;priv != nullptr; priv = priv->next) {
58         security_manager_app_inst_req_add_privilege(req, priv->text);
59       }
60     }
61   }
62   return true;
63 }
64
65 bool RegisterSecurityContext(const std::string& app_id,
66     const std::string& pkg_id, const boost::filesystem::path& path,
67     manifest_x* manifest) {
68   app_inst_req* req;
69
70   int error = security_manager_app_inst_req_new(&req);
71   if (error != SECURITY_MANAGER_SUCCESS) {
72     LOG(ERROR)
73         << "Failed while calling security_manager_app_inst_req_new failed "
74         << "(error code: " << error << ")";
75     return false;
76   }
77
78   if (!PrepareRequest(app_id, pkg_id, path, manifest, req)) {
79       LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
80       security_manager_app_inst_req_free(req);
81       return false;
82   }
83
84   error = security_manager_app_install(req);
85   if (error != SECURITY_MANAGER_SUCCESS) {
86     LOG(ERROR) << "Failed while calling security_manager_app_install failed "
87                << "(error code: " << error << ")";
88     security_manager_app_inst_req_free(req);
89     return false;
90   }
91
92   security_manager_app_inst_req_free(req);
93   return true;
94 }
95
96
97 bool UnregisterSecurityContext(const std::string& app_id,
98     const std::string& pkg_id) {
99   app_inst_req* req;
100
101   int error = security_manager_app_inst_req_new(&req);
102   if (error != SECURITY_MANAGER_SUCCESS) {
103     LOG(ERROR) << "Failed while calling security_manager_app_inst_req_new  "
104                << "(error code: " << error << ")";
105     return false;
106   }
107
108   if (!PrepareRequest(app_id, pkg_id, bf::path(), nullptr, req)) {
109     LOG(ERROR) << "Failed while preparing security_manager_app_inst_req";
110     security_manager_app_inst_req_free(req);
111     return false;
112   }
113
114   error = security_manager_app_uninstall(req);
115   if (error != SECURITY_MANAGER_SUCCESS) {
116     LOG(ERROR) << "Failed while calling  security_manager_app_uninstall failed "
117                << "(error code: " << error << ")";
118     security_manager_app_inst_req_free(req);
119     return false;
120   }
121
122   security_manager_app_inst_req_free(req);
123   return true;
124 }
125
126 }  // namespace
127
128 namespace common_installer {
129
130 bool RegisterSecurityContextForApps(
131     const std::string& pkg_id, const boost::filesystem::path& path,
132     manifest_x* manifest) {
133   for (uiapplication_x* ui = manifest->uiapplication;
134       ui != nullptr; ui = ui->next) {
135     if (!ui->appid) {
136       return false;
137     }
138     if (!RegisterSecurityContext(ui->appid, pkg_id, path, manifest)) {
139       return false;
140     }
141   }
142
143   for (serviceapplication_x* svc =
144       manifest->serviceapplication;
145       svc != nullptr; svc = svc->next) {
146     if (!svc->appid) {
147       return false;
148     }
149     if (!RegisterSecurityContext(svc->appid, pkg_id, path,  manifest)) {
150       return false;
151     }
152   }
153   return true;
154 }
155
156 bool UnregisterSecurityContextForApps(
157     const std::string& pkg_id, manifest_x* manifest) {
158   for (uiapplication_x* ui = manifest->uiapplication;
159       ui != nullptr; ui = ui->next) {
160     if (!ui->appid) {
161       return false;
162     }
163     if (!UnregisterSecurityContext(ui->appid, pkg_id)) {
164       return false;
165     }
166   }
167
168   for (serviceapplication_x* svc =
169       manifest->serviceapplication;
170       svc != nullptr; svc = svc->next) {
171     if (!svc->appid) {
172       return false;
173     }
174     if (!UnregisterSecurityContext(svc->appid, pkg_id)) {
175       return false;
176     }
177   }
178   return true;
179 }
180
181 }  // namespace common_installer