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_permissions(const struct wgt_desc *desc)
135 const struct wgt_desc_feature *feature;
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 check_widget(const struct wgt_desc *desc)
151 result = check_temporary_constraints(desc);
153 result = check_permissions(desc);
157 static int get_target_directory(char target[PATH_MAX], const char *root, const struct wgt_desc *desc)
161 rc = snprintf(target, PATH_MAX, "%s/%s/%s", root, desc->id, desc->ver);
165 ERROR("path too long");
172 static int move_widget_to(const char *destdir, int force)
174 return move_workdir(destdir, 1, force);
177 static int install_icon(const struct wgt_desc *desc)
180 char target[PATH_MAX];
183 create_directory(FWK_ICON_DIR, 0755, 1);
184 rc = snprintf(link, sizeof link, "%s/%s", FWK_ICON_DIR, desc->idaver);
185 if (rc >= (int)sizeof link) {
186 ERROR("link too long in install_icon");
191 rc = snprintf(target, sizeof target, "%s/%s", workdir, desc->icons->src);
192 if (rc >= (int)sizeof target) {
193 ERROR("target too long in install_icon");
199 rc = symlink(target, link);
201 ERROR("can't create link %s -> %s", link, target);
205 static int install_exec_flag(const struct wgt_desc *desc)
209 if (desc->content_type) {
210 i = sizeof exec_type_strings / sizeof *exec_type_strings;
212 if (!strcasecmp(desc->content_type, exec_type_strings[--i]))
213 return fchmodat(workdirfd, desc->content_src, 0755, 0);
219 static int install_security(const struct wgt_desc *desc)
221 char path[PATH_MAX], *head;
222 const char *icon, *perm;
224 unsigned int i, n, len, lic, lf;
227 rc = secmgr_init(desc->id);
231 rc = secmgr_path_public_read_only(workdir);
235 /* instal the files */
236 head = stpcpy(path, workdir);
237 assert(head < path + sizeof path);
238 len = (unsigned)((path + sizeof path) - head);
240 ERROR("root path too long in install_security");
241 errno = ENAMETOOLONG;
246 icon = desc->icons->src;
247 lic = (unsigned)strlen(icon);
251 f = file_of_index(i++);
252 lf = (unsigned)strlen(f->name);
254 ERROR("path too long in install_security");
255 errno = ENAMETOOLONG;
258 strcpy(head, f->name);
259 if (lf <= lic && !memcmp(f->name, icon, lf) && (!f->name[lf] || f->name[lf] == '/'))
260 rc = secmgr_path_public_read_only(path);
262 rc = secmgr_path_read_only(path);
267 /* install the permissions */
268 perm = first_usable_permission();
270 rc = secmgr_permit(perm);
271 INFO("permitting %s %s", perm, rc ? "FAILED!" : "success");
274 perm = next_usable_permission();
277 rc = secmgr_install();
285 /* install the widget of the file */
286 struct wgt_info *install_widget(const char *wgtfile, const char *root, int force)
288 struct wgt_info *ifo;
289 const struct wgt_desc *desc;
290 char installdir[PATH_MAX];
292 NOTICE("-- INSTALLING widget %s to %s --", wgtfile, root);
295 create_directory(root, 0755, 1);
296 if (make_workdir(root, "TMP", 0)) {
297 ERROR("failed to create a working directory");
301 if (zread(wgtfile, 0))
304 if (check_all_signatures())
307 ifo = wgt_info_createat(workdirfd, NULL, 1, 1, 1);
311 reset_requested_permissions();
312 desc = wgt_info_desc(ifo);
313 if (check_widget(desc))
316 if (get_target_directory(installdir, root, desc))
319 if (move_widget_to(installdir, force))
322 if (install_icon(desc))
325 if (install_exec_flag(desc))
328 if (install_security(desc))