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_string[] = "application/x-executable";
47 static int check_defined(const void *data, const char *name)
51 ERROR("widget has no defined '%s' (temporary constraints)", name);
56 static int check_valid_string(const char *value, const char *name)
61 if (check_defined(value, name))
66 ERROR("empty string forbidden in '%s' (temporary constraints)", name);
71 if (!isalnum(c) && !strchr(".-_", c)) {
72 ERROR("forbidden char %c in '%s' -> '%s' (temporary constraints)", c, name, value);
81 static int check_temporary_constraints(const struct wgt_desc *desc)
83 int result = check_valid_string(desc->id, "id");
84 result |= check_valid_string(desc->version, "version");
85 result |= check_valid_string(desc->ver, "ver");
86 result |= check_defined(desc->icons, "icon");
87 result |= check_defined(desc->content_src, "content");
90 if (desc->icons->next) {
91 ERROR("widget has more than one icon defined (temporary constraints)");
98 static int set_required_permissions(struct wgt_desc_param *params, int required)
103 /* check the value */
104 if (!strcmp(params->value, permission_required))
105 optional = !required;
106 else if (!strcmp(params->value, permission_optional))
109 ERROR("unexpected parameter value: %s found for %s", params->value, params->name);
113 /* set the permission */
114 if (request_permission(params->name)) {
115 DEBUG("granted permission: %s", params->name);
116 } else if (optional) {
117 INFO("optional permission ungranted: %s", params->name);
119 ERROR("ungranted permission required: %s", params->name);
123 params = params->next;
128 static int check_widget(const struct wgt_desc *desc)
131 const struct wgt_desc_feature *feature;
133 result = check_temporary_constraints(desc);
134 feature = desc->features;
135 while(result >= 0 && feature) {
136 if (!strcmp(feature->name, feature_required_permissions))
137 result = set_required_permissions(feature->params, feature->required);
138 feature = feature->next;
143 static int move_widget(const char *root, const struct wgt_desc *desc, int force)
145 char newdir[PATH_MAX];
148 rc = snprintf(newdir, sizeof newdir, "%s/%s/%s", root, desc->id, desc->ver);
149 if (rc >= (int)sizeof newdir) {
150 ERROR("path too long in move_widget");
155 return move_workdir(newdir, 1, force);
158 static int install_icon(const struct wgt_desc *desc)
161 char target[PATH_MAX];
164 create_directory(FWK_ICON_DIR, 0755, 1);
165 rc = snprintf(link, sizeof link, "%s/%s", FWK_ICON_DIR, desc->idaver);
166 if (rc >= (int)sizeof link) {
167 ERROR("link too long in install_icon");
172 rc = snprintf(target, sizeof target, "%s/%s", workdir, desc->icons->src);
173 if (rc >= (int)sizeof target) {
174 ERROR("target too long in install_icon");
180 rc = symlink(target, link);
182 ERROR("can't create link %s -> %s", link, target);
186 static int install_exec_flag(const struct wgt_desc *desc)
188 return desc->content_type != NULL && !strcmp(desc->content_type, exec_type_string)
189 ? fchmodat(workdirfd, desc->content_src, 0755, 0) : 0;
192 static int install_security(const struct wgt_desc *desc)
194 char path[PATH_MAX], *head;
195 const char *icon, *perm;
197 unsigned int i, n, len, lic, lf;
200 rc = secmgr_init(desc->id);
204 rc = secmgr_path_public_read_only(workdir);
208 /* instal the files */
209 head = stpcpy(path, workdir);
210 assert(head < path + sizeof path);
211 len = (unsigned)((path + sizeof path) - head);
213 ERROR("root path too long in install_security");
214 errno = ENAMETOOLONG;
219 icon = desc->icons->src;
220 lic = (unsigned)strlen(icon);
224 f = file_of_index(i++);
225 lf = (unsigned)strlen(f->name);
227 ERROR("path too long in install_security");
228 errno = ENAMETOOLONG;
231 strcpy(head, f->name);
232 if (lf <= lic && !memcmp(f->name, icon, lf) && (!f->name[lf] || f->name[lf] == '/'))
233 rc = secmgr_path_public_read_only(path);
235 rc = secmgr_path_read_only(path);
240 /* install the permissions */
241 perm = first_usable_permission();
243 rc = secmgr_permit(perm);
246 perm = next_usable_permission();
249 rc = secmgr_install();
257 /* install the widget of the file */
258 struct wgt_info *install_widget(const char *wgtfile, const char *root, int force)
260 struct wgt_info *ifo;
261 const struct wgt_desc *desc;
263 NOTICE("-- INSTALLING widget %s to %s --", wgtfile, root);
266 create_directory(root, 0755, 1);
267 if (make_workdir(root, "TMP", 0)) {
268 ERROR("failed to create a working directory");
272 if (zread(wgtfile, 0))
275 if (check_all_signatures())
278 ifo = wgt_info_createat(workdirfd, NULL, 1, 1, 1);
282 reset_requested_permissions();
283 desc = wgt_info_desc(ifo);
284 if (check_widget(desc))
287 if (move_widget(root, desc, force))
290 if (install_icon(desc))
293 if (install_exec_flag(desc))
296 if (install_security(desc))