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.
32 #include "wgtpkg-files.h"
33 #include "wgtpkg-workdir.h"
34 #include "wgtpkg-zip.h"
35 #include "wgtpkg-permissions.h"
36 #include "wgtpkg-digsig.h"
37 #include "wgtpkg-install.h"
38 #include "secmgr-wrap.h"
39 #include "utils-dir.h"
41 static const char permission_required[] = "required";
42 static const char permission_optional[] = "optional";
43 static const char feature_required_permissions[] = FWK_PREFIX "required-permissions";
45 static int check_defined(const void *data, const char *name)
49 ERROR("widget has no defined '%s' (temporary constraints)", name);
54 static int check_valid_string(const char *value, const char *name)
59 if (check_defined(value, name))
64 ERROR("empty string forbidden in '%s' (temporary constraints)", name);
69 if (!isalnum(c) && !strchr(".-_", c)) {
70 ERROR("forbidden char %c in '%s' -> '%s' (temporary constraints)", c, name, value);
79 static int check_temporary_constraints(const struct wgt_desc *desc)
81 int result = check_valid_string(desc->id, "id");
82 result |= check_valid_string(desc->version, "version");
83 result |= check_valid_string(desc->ver, "ver");
84 result |= check_defined(desc->icons, "icon");
85 result |= check_defined(desc->content_src, "content");
88 if (desc->icons->next) {
89 ERROR("widget has more than one icon defined (temporary constraints)");
96 static int set_required_permissions(struct wgt_desc_param *params, int required)
101 /* check the value */
102 if (!strcmp(params->value, permission_required))
103 optional = !required;
104 else if (!strcmp(params->value, permission_optional))
107 ERROR("unexpected parameter value: %s found for %s", params->value, params->name);
111 /* set the permission */
112 if (request_permission(params->name)) {
113 DEBUG("granted permission: %s", params->name);
114 } else if (optional) {
115 INFO("optional permission ungranted: %s", params->name);
117 ERROR("ungranted permission required: %s", params->name);
121 params = params->next;
126 static int check_widget(const struct wgt_desc *desc)
129 const struct wgt_desc_feature *feature;
131 result = check_temporary_constraints(desc);
132 feature = desc->features;
133 while(result >= 0 && feature) {
134 if (!strcmp(feature->name, feature_required_permissions))
135 result = set_required_permissions(feature->params, feature->required);
136 feature = feature->next;
141 static int move_widget(const char *root, const struct wgt_desc *desc, int force)
143 char newdir[PATH_MAX];
146 rc = snprintf(newdir, sizeof newdir, "%s/%s/%s", root, desc->id, desc->ver);
147 if (rc >= (int)sizeof newdir) {
148 ERROR("path to long in move_widget");
153 return move_workdir(newdir, 1, force);
156 static int install_icon(const struct wgt_desc *desc)
159 char target[PATH_MAX];
162 create_directory(FWK_ICON_DIR, 0755, 1);
163 rc = snprintf(link, sizeof link, "%s/%s", FWK_ICON_DIR, desc->idaver);
164 if (rc >= (int)sizeof link) {
165 ERROR("link to long in install_icon");
170 rc = snprintf(target, sizeof target, "%s/%s", workdir, desc->icons->src);
171 if (rc >= (int)sizeof target) {
172 ERROR("target to long in install_icon");
178 rc = symlink(target, link);
180 ERROR("can't create link %s -> %s", link, target);
184 static int install_security(const struct wgt_desc *desc)
186 char path[PATH_MAX], *head;
187 const char *icon, *perm;
189 unsigned int i, n, len, lic, lf;
192 rc = secmgr_init(desc->id);
196 rc = secmgr_path_public_read_only(workdir);
200 /* instal the files */
201 head = stpcpy(path, workdir);
202 assert(head < path + sizeof path);
203 len = (unsigned)((path + sizeof path) - head);
205 ERROR("root path too long in install_security");
206 errno = ENAMETOOLONG;
211 icon = desc->icons->src;
212 lic = (unsigned)strlen(icon);
216 f = file_of_index(i++);
217 lf = (unsigned)strlen(f->name);
219 ERROR("path too long in install_security");
220 errno = ENAMETOOLONG;
223 strcpy(head, f->name);
224 if (lf <= lic && !memcmp(f->name, icon, lf) && (!f->name[lf] || f->name[lf] == '/'))
225 rc = secmgr_path_public_read_only(path);
227 rc = secmgr_path_read_only(path);
232 /* install the permissions */
233 perm = first_usable_permission();
235 rc = secmgr_permit(perm);
238 perm = next_usable_permission();
241 rc = secmgr_install();
249 /* install the widget of the file */
250 struct wgt_info *install_widget(const char *wgtfile, const char *root, int force)
252 struct wgt_info *ifo;
253 const struct wgt_desc *desc;
255 NOTICE("-- INSTALLING widget %s to %s --", wgtfile, root);
258 create_directory(root, 0755, 1);
259 if (make_workdir(root, "TMP", 0)) {
260 ERROR("failed to create a working directory");
264 if (zread(wgtfile, 0))
267 if (check_all_signatures())
270 ifo = wgt_info_createat(workdirfd, NULL, 1, 1, 1);
274 reset_requested_permissions();
275 desc = wgt_info_desc(ifo);
276 if (check_widget(desc))
279 if (move_widget(root, desc, force))
282 if (install_icon(desc))
285 if (install_security(desc))