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)
84 int result = check_valid_string(desc->id, "id");
85 result |= check_valid_string(desc->version, "version");
86 result |= check_valid_string(desc->ver, "ver");
87 result |= check_defined(desc->icons, "icon");
88 result |= check_defined(desc->content_src, "content");
91 if (desc->icons->next) {
92 ERROR("widget has more than one icon defined (temporary constraints)");
99 static int set_required_permissions(struct wgt_desc_param *params, int required)
104 /* check the value */
105 if (!strcmp(params->value, string_required))
106 optional = !required;
107 else if (!strcmp(params->value, string_optional))
110 ERROR("unexpected parameter value: %s found for %s", params->value, params->name);
114 /* set the permission */
115 if (request_permission(params->name)) {
116 DEBUG("granted permission: %s", params->name);
117 } else if (optional) {
118 INFO("optional permission ungranted: %s", params->name);
120 ERROR("ungranted permission required: %s", params->name);
124 params = params->next;
129 static int check_widget(const struct wgt_desc *desc)
132 const struct wgt_desc_feature *feature;
134 result = check_temporary_constraints(desc);
135 feature = desc->features;
136 while(result >= 0 && feature) {
137 if (!strcmp(feature->name, feature_required_permission))
138 result = set_required_permissions(feature->params, feature->required);
139 feature = feature->next;
144 static int move_widget(const char *root, const struct wgt_desc *desc, int force)
146 char newdir[PATH_MAX];
149 rc = snprintf(newdir, sizeof newdir, "%s/%s/%s", root, desc->id, desc->ver);
150 if (rc >= (int)sizeof newdir) {
151 ERROR("path too long in move_widget");
156 return move_workdir(newdir, 1, force);
159 static int install_icon(const struct wgt_desc *desc)
162 char target[PATH_MAX];
165 create_directory(FWK_ICON_DIR, 0755, 1);
166 rc = snprintf(link, sizeof link, "%s/%s", FWK_ICON_DIR, desc->idaver);
167 if (rc >= (int)sizeof link) {
168 ERROR("link too long in install_icon");
173 rc = snprintf(target, sizeof target, "%s/%s", workdir, desc->icons->src);
174 if (rc >= (int)sizeof target) {
175 ERROR("target too long in install_icon");
181 rc = symlink(target, link);
183 ERROR("can't create link %s -> %s", link, target);
187 static int install_exec_flag(const struct wgt_desc *desc)
191 if (desc->content_type) {
192 i = sizeof exec_type_strings / sizeof *exec_type_strings;
194 if (!strcasecmp(desc->content_type, exec_type_strings[--i]))
195 return fchmodat(workdirfd, desc->content_src, 0755, 0);
201 static int install_security(const struct wgt_desc *desc)
203 char path[PATH_MAX], *head;
204 const char *icon, *perm;
206 unsigned int i, n, len, lic, lf;
209 rc = secmgr_init(desc->id);
213 rc = secmgr_path_public_read_only(workdir);
217 /* instal the files */
218 head = stpcpy(path, workdir);
219 assert(head < path + sizeof path);
220 len = (unsigned)((path + sizeof path) - head);
222 ERROR("root path too long in install_security");
223 errno = ENAMETOOLONG;
228 icon = desc->icons->src;
229 lic = (unsigned)strlen(icon);
233 f = file_of_index(i++);
234 lf = (unsigned)strlen(f->name);
236 ERROR("path too long in install_security");
237 errno = ENAMETOOLONG;
240 strcpy(head, f->name);
241 if (lf <= lic && !memcmp(f->name, icon, lf) && (!f->name[lf] || f->name[lf] == '/'))
242 rc = secmgr_path_public_read_only(path);
244 rc = secmgr_path_read_only(path);
249 /* install the permissions */
250 perm = first_usable_permission();
252 rc = secmgr_permit(perm);
253 INFO("permitting %s %s", perm, rc ? "FAILED!" : "success");
256 perm = next_usable_permission();
259 rc = secmgr_install();
267 /* install the widget of the file */
268 struct wgt_info *install_widget(const char *wgtfile, const char *root, int force)
270 struct wgt_info *ifo;
271 const struct wgt_desc *desc;
273 NOTICE("-- INSTALLING widget %s to %s --", wgtfile, root);
276 create_directory(root, 0755, 1);
277 if (make_workdir(root, "TMP", 0)) {
278 ERROR("failed to create a working directory");
282 if (zread(wgtfile, 0))
285 if (check_all_signatures())
288 ifo = wgt_info_createat(workdirfd, NULL, 1, 1, 1);
292 reset_requested_permissions();
293 desc = wgt_info_desc(ifo);
294 if (check_widget(desc))
297 if (move_widget(root, desc, force))
300 if (install_icon(desc))
303 if (install_exec_flag(desc))
306 if (install_security(desc))