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"
42 #include "wgtpkg-unit.h"
44 static const char* exec_type_strings[] = {
45 "application/x-executable",
46 "application/vnd.agl.native"
49 static int check_defined(const void *data, const char *name)
53 ERROR("widget has no defined '%s' (temporary constraints)", name);
58 static int check_valid_string(const char *value, const char *name)
63 if (check_defined(value, name))
68 ERROR("empty string forbidden in '%s' (temporary constraints)", name);
73 if (!isalnum(c) && !strchr(".-_", c)) {
74 ERROR("forbidden char %c in '%s' -> '%s' (temporary constraints)", c, name, value);
83 static int check_temporary_constraints(const struct wgt_desc *desc)
87 result = check_valid_string(desc->id, "id");
88 result |= check_valid_string(desc->version, "version");
89 result |= check_valid_string(desc->ver, "ver");
90 result |= check_defined(desc->icons, "icon");
91 result |= check_defined(desc->content_src, "content");
95 if (desc->icons->next) {
96 ERROR("widget has more than one icon defined (temporary constraints)");
103 static int set_required_permissions(struct wgt_desc_param *params, int required)
108 /* check if target */
109 if (!strcmp(params->name, string_sharp_target)) {
110 /* do nothing when #target */
112 /* check the value */
113 if (!strcmp(params->value, string_required))
114 optional = !required;
115 else if (!strcmp(params->value, string_optional))
118 ERROR("unexpected parameter value: %s found for %s", params->value, params->name);
122 /* set the permission */
123 if (request_permission(params->name)) {
124 DEBUG("granted permission: %s", params->name);
125 } else if (optional) {
126 INFO("optional permission ungranted: %s", params->name);
128 ERROR("ungranted permission required: %s", params->name);
133 params = params->next;
138 static int check_permissions(const struct wgt_desc *desc)
141 const struct wgt_desc_feature *feature;
144 feature = desc->features;
145 while(result >= 0 && feature) {
146 if (!strcmp(feature->name, feature_required_permission))
147 result = set_required_permissions(feature->params, feature->required);
148 feature = feature->next;
153 static int check_widget(const struct wgt_desc *desc)
157 result = check_temporary_constraints(desc);
159 result = check_permissions(desc);
163 static int get_target_directory(char target[PATH_MAX], const char *root, const struct wgt_desc *desc)
167 rc = snprintf(target, PATH_MAX, "%s/%s/%s", root, desc->id, desc->ver);
171 ERROR("path too long");
178 static int move_widget_to(const char *destdir, int force)
180 return move_workdir(destdir, 1, force);
183 static int install_icon(const struct wgt_desc *desc)
186 char target[PATH_MAX];
189 create_directory(FWK_ICON_DIR, 0755, 1);
190 rc = snprintf(link, sizeof link, "%s/%s", FWK_ICON_DIR, desc->idaver);
191 if (rc >= (int)sizeof link) {
192 ERROR("link too long in install_icon");
197 rc = snprintf(target, sizeof target, "%s/%s", workdir, desc->icons->src);
198 if (rc >= (int)sizeof target) {
199 ERROR("target too long in install_icon");
205 rc = symlink(target, link);
207 ERROR("can't create link %s -> %s", link, target);
211 static int install_exec_flag(const struct wgt_desc *desc)
215 if (desc->content_type) {
216 i = sizeof exec_type_strings / sizeof *exec_type_strings;
218 if (!strcasecmp(desc->content_type, exec_type_strings[--i]))
219 return fchmodat(workdirfd, desc->content_src, 0755, 0);
225 static int install_security(const struct wgt_desc *desc)
227 char path[PATH_MAX], *head;
228 const char *icon, *perm;
230 unsigned int i, n, len, lic, lf;
233 rc = secmgr_init(desc->id);
237 rc = secmgr_path_public_read_only(workdir);
241 /* instal the files */
242 head = stpcpy(path, workdir);
243 assert(head < path + sizeof path);
244 len = (unsigned)((path + sizeof path) - head);
246 ERROR("root path too long in install_security");
247 errno = ENAMETOOLONG;
252 icon = desc->icons->src;
253 lic = (unsigned)strlen(icon);
257 f = file_of_index(i++);
258 lf = (unsigned)strlen(f->name);
260 ERROR("path too long in install_security");
261 errno = ENAMETOOLONG;
264 strcpy(head, f->name);
265 if (lf <= lic && !memcmp(f->name, icon, lf) && (!f->name[lf] || f->name[lf] == '/'))
266 rc = secmgr_path_public_read_only(path);
268 rc = secmgr_path_read_only(path);
273 /* install the permissions */
274 perm = first_usable_permission();
276 rc = secmgr_permit(perm);
277 INFO("permitting %s %s", perm, rc ? "FAILED!" : "success");
280 perm = next_usable_permission();
283 rc = secmgr_install();
291 /* install the widget of the file */
292 struct wgt_info *install_widget(const char *wgtfile, const char *root, int force)
294 struct wgt_info *ifo;
295 const struct wgt_desc *desc;
296 char installdir[PATH_MAX];
298 NOTICE("-- INSTALLING widget %s to %s --", wgtfile, root);
301 create_directory(root, 0755, 1);
302 if (make_workdir(root, "TMP", 0)) {
303 ERROR("failed to create a working directory");
307 if (zread(wgtfile, 0))
310 if (check_all_signatures())
313 ifo = wgt_info_createat(workdirfd, NULL, 1, 1, 1);
317 reset_requested_permissions();
318 desc = wgt_info_desc(ifo);
319 if (check_widget(desc))
322 if (get_target_directory(installdir, root, desc))
325 if (move_widget_to(installdir, force))
328 if (install_icon(desc))
331 if (install_security(desc))
334 if (install_exec_flag(desc))
337 if (unit_install(ifo, installdir, FWK_ICON_DIR, 1234/*TODO*/))