2 Copyright 2015, 2016 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 "wgtpkg-files.h"
34 #include "wgtpkg-workdir.h"
35 #include "wgtpkg-zip.h"
36 #include "wgtpkg-permissions.h"
37 #include "wgtpkg-digsig.h"
38 #include "wgtpkg-install.h"
39 #include "secmgr-wrap.h"
40 #include "utils-dir.h"
42 static const char permission_required[] = "required";
43 static const char permission_optional[] = "optional";
44 static const char feature_required_permissions[] = FWK_PREFIX "required-permissions";
45 static const char* exec_type_strings[] = {
46 "application/x-executable",
47 "application/vnd.agl.native"
50 static int check_defined(const void *data, const char *name)
54 ERROR("widget has no defined '%s' (temporary constraints)", name);
59 static int check_valid_string(const char *value, const char *name)
64 if (check_defined(value, name))
69 ERROR("empty string forbidden in '%s' (temporary constraints)", name);
74 if (!isalnum(c) && !strchr(".-_", c)) {
75 ERROR("forbidden char %c in '%s' -> '%s' (temporary constraints)", c, name, value);
84 static int check_temporary_constraints(const struct wgt_desc *desc)
86 int 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");
93 if (desc->icons->next) {
94 ERROR("widget has more than one icon defined (temporary constraints)");
101 static int set_required_permissions(struct wgt_desc_param *params, int required)
106 /* check the value */
107 if (!strcmp(params->value, permission_required))
108 optional = !required;
109 else if (!strcmp(params->value, permission_optional))
112 ERROR("unexpected parameter value: %s found for %s", params->value, params->name);
116 /* set the permission */
117 if (request_permission(params->name)) {
118 DEBUG("granted permission: %s", params->name);
119 } else if (optional) {
120 INFO("optional permission ungranted: %s", params->name);
122 ERROR("ungranted permission required: %s", params->name);
126 params = params->next;
131 static int check_widget(const struct wgt_desc *desc)
134 const struct wgt_desc_feature *feature;
136 result = check_temporary_constraints(desc);
137 feature = desc->features;
138 while(result >= 0 && feature) {
139 if (!strcmp(feature->name, feature_required_permissions))
140 result = set_required_permissions(feature->params, feature->required);
141 feature = feature->next;
146 static int move_widget(const char *root, const struct wgt_desc *desc, int force)
148 char newdir[PATH_MAX];
151 rc = snprintf(newdir, sizeof newdir, "%s/%s/%s", root, desc->id, desc->ver);
152 if (rc >= (int)sizeof newdir) {
153 ERROR("path too long in move_widget");
158 return move_workdir(newdir, 1, force);
161 static int install_icon(const struct wgt_desc *desc)
164 char target[PATH_MAX];
167 create_directory(FWK_ICON_DIR, 0755, 1);
168 rc = snprintf(link, sizeof link, "%s/%s", FWK_ICON_DIR, desc->idaver);
169 if (rc >= (int)sizeof link) {
170 ERROR("link too long in install_icon");
175 rc = snprintf(target, sizeof target, "%s/%s", workdir, desc->icons->src);
176 if (rc >= (int)sizeof target) {
177 ERROR("target too long in install_icon");
183 rc = symlink(target, link);
185 ERROR("can't create link %s -> %s", link, target);
189 static int install_exec_flag(const struct wgt_desc *desc)
193 if (desc->content_type) {
194 i = sizeof exec_type_strings / sizeof *exec_type_strings;
196 if (!strcasecmp(desc->content_type, exec_type_strings[--i]))
197 return fchmodat(workdirfd, desc->content_src, 0755, 0);
203 static int install_security(const struct wgt_desc *desc)
205 char path[PATH_MAX], *head;
206 const char *icon, *perm;
208 unsigned int i, n, len, lic, lf;
211 rc = secmgr_init(desc->id);
215 rc = secmgr_path_public_read_only(workdir);
219 /* instal the files */
220 head = stpcpy(path, workdir);
221 assert(head < path + sizeof path);
222 len = (unsigned)((path + sizeof path) - head);
224 ERROR("root path too long in install_security");
225 errno = ENAMETOOLONG;
230 icon = desc->icons->src;
231 lic = (unsigned)strlen(icon);
235 f = file_of_index(i++);
236 lf = (unsigned)strlen(f->name);
238 ERROR("path too long in install_security");
239 errno = ENAMETOOLONG;
242 strcpy(head, f->name);
243 if (lf <= lic && !memcmp(f->name, icon, lf) && (!f->name[lf] || f->name[lf] == '/'))
244 rc = secmgr_path_public_read_only(path);
246 rc = secmgr_path_read_only(path);
251 /* install the permissions */
252 perm = first_usable_permission();
254 rc = secmgr_permit(perm);
257 perm = next_usable_permission();
260 rc = secmgr_install();
268 /* install the widget of the file */
269 struct wgt_info *install_widget(const char *wgtfile, const char *root, int force)
271 struct wgt_info *ifo;
272 const struct wgt_desc *desc;
274 NOTICE("-- INSTALLING widget %s to %s --", wgtfile, root);
277 create_directory(root, 0755, 1);
278 if (make_workdir(root, "TMP", 0)) {
279 ERROR("failed to create a working directory");
283 if (zread(wgtfile, 0))
286 if (check_all_signatures())
289 ifo = wgt_info_createat(workdirfd, NULL, 1, 1, 1);
293 reset_requested_permissions();
294 desc = wgt_info_desc(ifo);
295 if (check_widget(desc))
298 if (move_widget(root, desc, force))
301 if (install_icon(desc))
304 if (install_exec_flag(desc))
307 if (install_security(desc))