Add OOM exception handler
[platform/core/appfw/wgt-backend.git] / src / wgt / step / security / step_check_extension_privileges.cc
1 // Copyright (c) 2016 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 "wgt/step/security/step_check_extension_privileges.h"
6
7 #include <boost/scope_exit.hpp>
8
9 #include <common/privileges.h>
10 #include <common/certificate_validation.h>
11 #include <common/utils/glist_range.h>
12 #include <manifest_parser/values.h>
13
14 #include <pkgmgrinfo_basic.h>
15 #include <glib.h>
16 #include <glob.h>
17 #include <sys/utsname.h>
18
19 #include <set>
20 #include <vector>
21 #include <cstdlib>
22 #include <string>
23 #include <memory>
24
25 #include "wgt/extension_config_parser.h"
26
27 namespace {
28 const char kPluginsDirectory[] = "/res/wgt/plugin/";
29 const char kArchArmv7l[] = "armv7l";
30 const char kArchI586[] = "i586";
31 const char kArchDefault[] = "default";
32 }
33
34 namespace wgt {
35 namespace security {
36
37 common_installer::Step::Status StepCheckExtensionPrivileges::precheck() {
38   if (!context_->manifest_data.get()) {
39     LOG(ERROR) << "Manifest data is not set";
40     return Status::ERROR;
41   }
42   return Status::OK;
43 }
44
45 common_installer::Step::Status StepCheckExtensionPrivileges::process() {
46   std::string app_ext_config_pattern(GetExtensionPath());
47
48   manifest_x* m = context_->manifest_data.get();
49   std::set<std::string> current_privileges;
50   for (privilege_x* priv : GListRange<privilege_x*>(m->privileges)) {
51     if (strcmp(priv->type, common_installer::kWebPrivilegeType) == 0)
52       current_privileges.insert(priv->value);
53   }
54
55   std::set<std::string> xmlFiles;
56   {
57     glob_t glob_result;
58     glob(app_ext_config_pattern.c_str(), GLOB_TILDE, NULL, &glob_result);
59     for (unsigned int i = 0; i < glob_result.gl_pathc; ++i) {
60       xmlFiles.insert(glob_result.gl_pathv[i]);
61     }
62   }
63   GList* privileges = nullptr;
64   BOOST_SCOPE_EXIT_ALL(&) {
65     g_list_free_full(privileges, &common_installer::FreePrivilegeX);
66   };
67   for (auto it = xmlFiles.begin(); it != xmlFiles.end(); ++it) {
68     LOG(DEBUG) << "start to parse extension xml : " << *it;
69     ExtensionConfigParser extensionParser(*it);
70     std::vector<std::string> list = extensionParser.GetExtensionPrivilegeList();
71     for (const std::string& priv : list) {
72       if (current_privileges.find(priv) == current_privileges.end()) {
73         privilege_x* privilege =
74             reinterpret_cast<privilege_x*>(calloc(1, sizeof(privilege_x)));
75         if (!privilege) {
76           g_list_free_full(privileges, &common_installer::FreePrivilegeX);
77           return Status::ERROR;
78         }
79         privilege->type = strdup(common_installer::kWebPrivilegeType);
80         if (!privilege->type) {
81           common_installer::FreePrivilegeX(privilege);
82           g_list_free_full(privileges, &common_installer::FreePrivilegeX);
83           return Status::ERROR;
84         }
85         privilege->value = strdup(priv.c_str());
86         if (!privilege->value) {
87           common_installer::FreePrivilegeX(privilege);
88           g_list_free_full(privileges, &common_installer::FreePrivilegeX);
89           return Status::ERROR;
90         }
91         privileges = g_list_append(privileges, privilege);
92       }
93     }
94   }
95
96   if (privileges) {
97     if (!CheckPrivilegeLevel(privileges)) {
98       LOG(DEBUG) << "Fail to validation of privilege";
99       return Status::ERROR;
100     }
101     m->privileges = g_list_concat(m->privileges, privileges);
102     privileges = nullptr;
103   }
104   return Status::OK;
105 }
106
107 std::string StepCheckExtensionPrivileges::GetExtensionPath() {
108   std::string app_ext_config_pattern(context_->pkg_path.get().string());
109   app_ext_config_pattern.append(kPluginsDirectory);
110   struct utsname u;
111   if (0 == uname(&u)) {
112     std::string machine = u.machine;
113     LOG(DEBUG) << "Machine archicture for user defined plugins: " << machine;
114     if (!machine.empty()) {
115       if (machine == kArchArmv7l) {
116         app_ext_config_pattern.append(kArchArmv7l);
117       } else if (machine == kArchI586) {
118         app_ext_config_pattern.append(kArchI586);
119       } else {
120         app_ext_config_pattern.append(kArchDefault);
121       }
122     } else {
123       LOG(ERROR) << "cannot get machine info";
124       app_ext_config_pattern.append(kArchDefault);
125     }
126     app_ext_config_pattern.append("/");
127   }
128   app_ext_config_pattern.append("*");
129   app_ext_config_pattern.append(".xml");
130   return app_ext_config_pattern;
131 }
132
133 bool StepCheckExtensionPrivileges::CheckPrivilegeLevel(
134     GList* privileges) {
135   if (g_list_length(privileges) == 0)
136     return true;
137
138   std::string error_message;
139   if (!common_installer::ValidatePrivilegeLevel(
140          context_->privilege_level.get(),
141          context_->uid.get(),
142          context_->manifest_data.get()->api_version,
143          privileges,
144          &error_message)) {
145     if (!error_message.empty()) {
146       LOG(ERROR) << "error_message: " << error_message;
147     }
148     return false;
149   }
150   return true;
151 }
152
153 }  // namespace security
154 }  // namespace wgt