2 Copyright 2015, 2016, 2017 IoT.bzh
4 author: José Bollo <jose.bollo@iot.bzh>
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
10 http://www.apache.org/licenses/LICENSE-2.0
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.
33 #include "wgt-strings.h"
34 #include "wgtpkg-files.h"
35 #include "wgtpkg-workdir.h"
36 #include "wgtpkg-zip.h"
37 #include "wgtpkg-permissions.h"
38 #include "wgtpkg-digsig.h"
39 #include "wgtpkg-install.h"
40 #include "secmgr-wrap.h"
41 #include "utils-dir.h"
43 static const char* exec_type_strings[] = {
44 "application/x-executable",
45 "application/vnd.agl.native"
48 static int check_defined(const void *data, const char *name)
52 ERROR("widget has no defined '%s' (temporary constraints)", name);
57 static int check_valid_string(const char *value, const char *name)
62 if (check_defined(value, name))
67 ERROR("empty string forbidden in '%s' (temporary constraints)", name);
72 if (!isalnum(c) && !strchr(".-_", c)) {
73 ERROR("forbidden char %c in '%s' -> '%s' (temporary constraints)", c, name, value);
82 static int check_temporary_constraints(const struct wgt_desc *desc)
86 result = check_valid_string(desc->id, "id");
87 result |= check_valid_string(desc->version, "version");
88 result |= check_valid_string(desc->ver, "ver");
89 result |= check_defined(desc->icons, "icon");
90 result |= check_defined(desc->content_src, "content");
94 if (desc->icons->next) {
95 ERROR("widget has more than one icon defined (temporary constraints)");
102 static int set_required_permissions(struct wgt_desc_param *params, int required)
107 /* check the value */
108 if (!strcmp(params->value, string_required))
109 optional = !required;
110 else if (!strcmp(params->value, string_optional))
113 ERROR("unexpected parameter value: %s found for %s", params->value, params->name);
117 /* set the permission */
118 if (request_permission(params->name)) {
119 DEBUG("granted permission: %s", params->name);
120 } else if (optional) {
121 INFO("optional permission ungranted: %s", params->name);
123 ERROR("ungranted permission required: %s", params->name);
127 params = params->next;
132 static int check_widget(const struct wgt_desc *desc)
135 const struct wgt_desc_feature *feature;
137 result = check_temporary_constraints(desc);
138 feature = desc->features;
139 while(result >= 0 && feature) {
140 if (!strcmp(feature->name, feature_required_permission))
141 result = set_required_permissions(feature->params, feature->required);
142 feature = feature->next;
147 static int get_target_directory(char target[PATH_MAX], const char *root, const struct wgt_desc *desc)
151 rc = snprintf(target, PATH_MAX, "%s/%s/%s", root, desc->id, desc->ver);
155 ERROR("path too long");
162 static int move_widget_to(const char *destdir, int force)
164 return move_workdir(destdir, 1, force);
167 static int install_icon(const struct wgt_desc *desc)
170 char target[PATH_MAX];
173 create_directory(FWK_ICON_DIR, 0755, 1);
174 rc = snprintf(link, sizeof link, "%s/%s", FWK_ICON_DIR, desc->idaver);
175 if (rc >= (int)sizeof link) {
176 ERROR("link too long in install_icon");
181 rc = snprintf(target, sizeof target, "%s/%s", workdir, desc->icons->src);
182 if (rc >= (int)sizeof target) {
183 ERROR("target too long in install_icon");
189 rc = symlink(target, link);
191 ERROR("can't create link %s -> %s", link, target);
195 static int install_exec_flag(const struct wgt_desc *desc)
199 if (desc->content_type) {
200 i = sizeof exec_type_strings / sizeof *exec_type_strings;
202 if (!strcasecmp(desc->content_type, exec_type_strings[--i]))
203 return fchmodat(workdirfd, desc->content_src, 0755, 0);
209 static int install_security(const struct wgt_desc *desc)
211 char path[PATH_MAX], *head;
212 const char *icon, *perm;
214 unsigned int i, n, len, lic, lf;
217 rc = secmgr_init(desc->id);
221 rc = secmgr_path_public_read_only(workdir);
225 /* instal the files */
226 head = stpcpy(path, workdir);
227 assert(head < path + sizeof path);
228 len = (unsigned)((path + sizeof path) - head);
230 ERROR("root path too long in install_security");
231 errno = ENAMETOOLONG;
236 icon = desc->icons->src;
237 lic = (unsigned)strlen(icon);
241 f = file_of_index(i++);
242 lf = (unsigned)strlen(f->name);
244 ERROR("path too long in install_security");
245 errno = ENAMETOOLONG;
248 strcpy(head, f->name);
249 if (lf <= lic && !memcmp(f->name, icon, lf) && (!f->name[lf] || f->name[lf] == '/'))
250 rc = secmgr_path_public_read_only(path);
252 rc = secmgr_path_read_only(path);
257 /* install the permissions */
258 perm = first_usable_permission();
260 rc = secmgr_permit(perm);
261 INFO("permitting %s %s", perm, rc ? "FAILED!" : "success");
264 perm = next_usable_permission();
267 rc = secmgr_install();
275 /* install the widget of the file */
276 struct wgt_info *install_widget(const char *wgtfile, const char *root, int force)
278 struct wgt_info *ifo;
279 const struct wgt_desc *desc;
280 char installdir[PATH_MAX];
282 NOTICE("-- INSTALLING widget %s to %s --", wgtfile, root);
285 create_directory(root, 0755, 1);
286 if (make_workdir(root, "TMP", 0)) {
287 ERROR("failed to create a working directory");
291 if (zread(wgtfile, 0))
294 if (check_all_signatures())
297 ifo = wgt_info_createat(workdirfd, NULL, 1, 1, 1);
301 reset_requested_permissions();
302 desc = wgt_info_desc(ifo);
303 if (check_widget(desc))
306 if (get_target_directory(installdir, root, desc))
309 if (move_widget_to(installdir, force))
312 if (install_icon(desc))
315 if (install_exec_flag(desc))
318 if (install_security(desc))