2 * This file is part of MSM security plugin
3 * Greatly based on the code of MSSF security plugin
5 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
7 * Contact: Tero Aho <ext-tero.aho@nokia.com>
9 * Copyright (C) 2011 -2013 Intel Corporation.
11 * Contact: Elena Reshetova <elena.reshetova@intel.com>
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
33 #include <sys/types.h>
37 #include <libxml/xmlreader.h>
38 #include <sys/capability.h>
42 #include "rpmio/rpmbase64.h"
43 #include "rpmio/rpmlog.h"
45 /* We'll support only the basic set of characters */
46 #define ASCII(s) (const char *)s
47 #define XMLCHAR(s) (const xmlChar *)s
49 static int msmVerifyAccessType(const char* type)
54 if (strlen(type) > SMACK_ACCESS_TYPE_LENGHT) {
55 rpmlog(RPMLOG_ERR, "Lenght of the access type is bigger than allowed value: %s\n", type);
58 while ( type[idx] != '\0' ){
59 if ((type[idx] !='a') && (type[idx]!='r') && (type[idx]!='w') &&
60 (type[idx]!='x') && (type[idx]!='t') && (type[idx]!='l') && (type[idx] !='-')) {
61 rpmlog(RPMLOG_ERR, "Not allowed character in access type: %s\n", type);
72 static int msmVerifySmackLabel(const char* label)
77 if (strlen(ASCII(label)) > SMACK_LABEL_LENGTH) { //smack limitation on lenght
78 rpmlog(RPMLOG_ERR, "Domain or label name %s lenght is longer than defined SMACK_LABEL_LENGTH\n", label);
81 if (strlen(ASCII(label)) == 0){
82 rpmlog(RPMLOG_ERR, "An attempt to define an empty domain or label name\n");
85 if (label[0] == '-') {
86 rpmlog(RPMLOG_ERR, "Dash is not allowed as first character in smack label: %s\n", label);
89 while ( label[idx] != '\0' ){
90 if ((label[idx] =='\"') || (label[idx] =='\'') || (label[idx] =='/') ||
91 (label[idx] =='\\') || (label[idx] > '~') || (label[idx] <= ' ')) {
92 rpmlog(RPMLOG_ERR, "Not allowed character in smack label: %s, position: %d \n", label, idx);
103 static int msmVerifyLabelPrefix(const char* sub_label, const char* domain_name)
108 tmp = calloc(strlen(domain_name) + 3, sizeof (const char));
112 strncpy(tmp, domain_name, strlen(domain_name));
113 strncpy(tmp + strlen(domain_name), sep, 2);
115 if (strstr(ASCII(sub_label), tmp) != ASCII(sub_label)) { //sub label name should be prefixed by domain name and "::"
116 rpmlog(RPMLOG_ERR, "Label name %s isn't prefixed by domain name %s\n", ASCII(sub_label), domain_name);
117 msmFreePointer((void**)&tmp);
121 msmFreePointer((void**)&tmp);
125 static int msmNextChildElement(xmlTextReaderPtr reader, int depth)
127 int ret = xmlTextReaderRead(reader);
128 int cur = xmlTextReaderDepth(reader);
130 /* rpmlog(RPMLOG_DEBUG, "node %s %d\n",
131 ASCII(xmlTextReaderConstName(reader)),
132 xmlTextReaderDepth(reader));
134 switch (xmlTextReaderNodeType(reader)) {
135 case XML_READER_TYPE_ELEMENT:
136 case XML_READER_TYPE_TEXT:
140 case XML_READER_TYPE_END_ELEMENT:
149 ret = xmlTextReaderRead(reader);
150 cur = xmlTextReaderDepth(reader);
155 static ac_domain_x *msmFreeACDomain(ac_domain_x *ac_domain)
158 ac_domain_x *prev = ac_domain->prev;
159 msmFreePointer((void**)&ac_domain->name);
160 msmFreePointer((void**)&ac_domain->type);
161 msmFreePointer((void**)&ac_domain->match);
162 msmFreePointer((void**)&ac_domain->plist);
163 msmFreePointer((void**)&ac_domain);
168 static annotation_x *msmProcessAnnotation(xmlTextReaderPtr reader)
170 const xmlChar *name, *value;
172 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
173 value = xmlTextReaderGetAttribute(reader, XMLCHAR("value"));
174 rpmlog(RPMLOG_DEBUG, "annotation %s %s\n", ASCII(name), ASCII(value));
177 annotation_x *annotation = calloc(1, sizeof(annotation_x));
179 annotation->name = ASCII(name);
180 annotation->value = ASCII(value);
184 msmFreePointer((void**)&name);
185 msmFreePointer((void**)&value);
189 static int msmProcessMember(xmlTextReaderPtr reader, member_x *member)
191 const xmlChar *node, *name;
194 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
195 rpmlog(RPMLOG_DEBUG, "member %s\n", ASCII(name));
196 member->name = ASCII(name);
198 if (!name) return -1;
200 depth = xmlTextReaderDepth(reader);
201 while ((ret = msmNextChildElement(reader, depth))) {
202 node = xmlTextReaderConstName(reader);
203 if (!node) return -1;
205 if (!strcmp(ASCII(node), "annotation")) {
206 annotation_x *annotation = msmProcessAnnotation(reader);
208 member->annotation = annotation;
212 if (ret < 0) return -1;
217 static int msmProcessInterface(xmlTextReaderPtr reader, interface_x *interface)
219 const xmlChar *node, *name;
222 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
223 rpmlog(RPMLOG_DEBUG, "interface %s\n", ASCII(name));
224 interface->name = ASCII(name);
226 if (!name) return -1;
228 depth = xmlTextReaderDepth(reader);
229 while ((ret = msmNextChildElement(reader, depth))) {
230 node = xmlTextReaderConstName(reader);
231 if (!node) return -1;
233 if (!strcmp(ASCII(node), "method")) {
234 member_x *member = calloc(1, sizeof(member_x));
236 member->type = DBUS_METHOD;
237 ret = msmProcessMember(reader, member);
238 LISTADD(interface->members, member);
240 } else if (!strcmp(ASCII(node), "signal")) {
241 member_x *member = calloc(1, sizeof(member_x));
243 member->type = DBUS_SIGNAL;
244 ret = msmProcessMember(reader, member);
245 LISTADD(interface->members, member);
247 } else if (!strcmp(ASCII(node), "annotation")) {
248 annotation_x *annotation = msmProcessAnnotation(reader);
250 interface->annotation = annotation;
254 if (ret < 0) return -1;
259 static int msmProcessNode(xmlTextReaderPtr reader, node_x *nodex)
261 const xmlChar *node, *name;
264 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
265 rpmlog(RPMLOG_DEBUG, "node %s\n", ASCII(name));
266 nodex->name = ASCII(name);
268 if (!name) return -1;
270 depth = xmlTextReaderDepth(reader);
271 while ((ret = msmNextChildElement(reader, depth))) {
272 node = xmlTextReaderConstName(reader);
273 if (!node) return -1;
275 if (!strcmp(ASCII(node), "interface")) {
276 interface_x *interface = calloc(1, sizeof(interface_x));
278 ret = msmProcessInterface(reader, interface);
279 LISTADD(nodex->interfaces, interface);
281 } else if (!strcmp(ASCII(node), "method")) {
282 member_x *member = calloc(1, sizeof(member_x));
284 member->type = DBUS_METHOD;
285 ret = msmProcessMember(reader, member);
286 LISTADD(nodex->members, member);
288 } else if (!strcmp(ASCII(node), "signal")) {
289 member_x *member = calloc(1, sizeof(member_x));
291 member->type = DBUS_SIGNAL;
292 ret = msmProcessMember(reader, member);
293 LISTADD(nodex->members, member);
295 } else if (!strcmp(ASCII(node), "annotation")) {
296 annotation_x *annotation = msmProcessAnnotation(reader);
298 nodex->annotation = annotation;
302 if (ret < 0) return -1;
307 static int msmProcessDBus(xmlTextReaderPtr reader, dbus_x *dbus)
309 const xmlChar *node, *name, *own, *bus;
312 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
313 own = xmlTextReaderGetAttribute(reader, XMLCHAR("own"));
314 bus = xmlTextReaderGetAttribute(reader, XMLCHAR("bus"));
315 rpmlog(RPMLOG_DEBUG, "dbus %s %s %s\n", ASCII(name), ASCII(own), ASCII(bus));
316 dbus->name = ASCII(name);
317 dbus->own = ASCII(own);
318 dbus->bus = ASCII(bus);
320 if (!name || !bus) return -1;
321 if (strcmp(dbus->bus, "session") && strcmp(dbus->bus, "system"))
324 depth = xmlTextReaderDepth(reader);
325 while ((ret = msmNextChildElement(reader, depth))) {
326 node = xmlTextReaderConstName(reader);
327 if (!node) return -1;
329 if (!strcmp(ASCII(node), "node")) {
330 node_x *nodex = calloc(1, sizeof(node_x));
332 ret = msmProcessNode(reader, nodex);
333 LISTADD(dbus->nodes, nodex);
335 } else if (!strcmp(ASCII(node), "annotation")) {
336 annotation_x *annotation = msmProcessAnnotation(reader);
338 dbus->annotation = annotation;
342 if (ret < 0) return -1;
347 static ac_domain_x *msmProcessACDomain(xmlTextReaderPtr reader, sw_source_x *sw_source, const char* pkg_name)
349 const xmlChar *name, *match, *policy, *plist;
351 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
352 match = xmlTextReaderGetAttribute(reader, XMLCHAR("match"));
353 policy = xmlTextReaderGetAttribute(reader, XMLCHAR("policy"));
354 plist = xmlTextReaderGetAttribute(reader, XMLCHAR("plist"));
355 rpmlog(RPMLOG_DEBUG, "ac_domain %s match %s policy %s plist %s\n", ASCII(name), ASCII(match), ASCII(policy), ASCII(plist));
357 if (!((!name && !match) || (name && match))) {
358 ac_domain_x *ac_domain = calloc(1, sizeof(ac_domain_x));
360 ac_domain->name = ASCII(name);
361 ac_domain->match = ASCII(match);
362 ac_domain->type = ASCII(policy);
363 ac_domain->plist = ASCII(plist);
364 ac_domain->sw_source = sw_source;
365 ac_domain->pkg_name = pkg_name;
369 rpmlog(RPMLOG_ERR, "Mandatory argument is missing for ac domain definition\n");
370 rpmlog(RPMLOG_ERR, "ac_domain %s match %s policy %s plist %s\n", ASCII(name), ASCII(match), ASCII(policy), ASCII(plist));
371 msmFreePointer((void**)&name);
372 msmFreePointer((void**)&match);
373 msmFreePointer((void**)&policy);
374 msmFreePointer((void**)&plist);
378 static filesystem_x *msmProcessFilesystem(xmlTextReaderPtr reader)
380 const xmlChar *path, *label, *type, *exec_label;
382 path = xmlTextReaderGetAttribute(reader, XMLCHAR("path"));
383 label = xmlTextReaderGetAttribute(reader, XMLCHAR("label"));
384 exec_label = xmlTextReaderGetAttribute(reader, XMLCHAR("exec_label"));
385 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
387 rpmlog(RPMLOG_DEBUG, "filesystem path %s label %s exec label %s type %s\n",
388 ASCII(path), ASCII(label), ASCII(exec_label), ASCII(type));
390 if (path && (label || exec_label)) {
391 if ((label) && (msmVerifySmackLabel(ASCII(label)) < 0)) {
394 if ((exec_label) && (msmVerifySmackLabel(ASCII(exec_label)) < 0)) {
398 filesystem_x *filesystem = calloc(1, sizeof(filesystem_x));
400 filesystem->path = ASCII(path);
401 filesystem->label = ASCII(label);
402 filesystem->exec_label = ASCII(exec_label);
403 filesystem->type = ASCII(type);
408 rpmlog(RPMLOG_ERR, "Mandatory argument is missing for filesystem assign request\n");
409 rpmlog(RPMLOG_ERR, "filesystem path %s label %s exec label %s\n",
410 ASCII(path), ASCII(label), ASCII(exec_label));
414 msmFreePointer((void**)&path);
415 msmFreePointer((void**)&label);
416 msmFreePointer((void**)&exec_label);
417 msmFreePointer((void**)&type);
421 static int msmProcessProvide(xmlTextReaderPtr reader, provide_x *provide, sw_source_x *current, manifest_x *mfx, const char* pkg_name)
423 const xmlChar *node, *name, *origin;
426 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
427 rpmlog(RPMLOG_DEBUG, "assign %s\n", ASCII(name));
428 provide->name = ASCII(name);
431 (strcmp(provide->name, "_system_") || mfx->sw_source->parent))
432 return -1; /* only _system_ is accepted from root sw source */
434 depth = xmlTextReaderDepth(reader);
435 while ((ret = msmNextChildElement(reader, depth))) {
436 node = xmlTextReaderConstName(reader);
437 if (!node) return -1;
439 if (!strcmp(ASCII(node), "dbus")) {
440 dbus_x *dbus = calloc(1, sizeof(dbus_x));
442 ret = msmProcessDBus(reader, dbus);
443 LISTADD(provide->dbuss, dbus);
445 } else if (!strcmp(ASCII(node), "ac_domain")) {
446 ac_domain_x *ac_domain = msmProcessACDomain(reader, current, pkg_name);
448 const char *name = ac_domain->name;
449 LISTADD(provide->ac_domains, ac_domain);
450 if (!name) return -1;
451 if (mfx && !provide->name) {
452 ac_domain->name = malloc(strlen(mfx->name) + 2 +
454 sprintf((char *)ac_domain->name, "%s::%s", mfx->name, name);
455 msmFreePointer((void**)&name);
459 } else if (!strcmp(ASCII(node), "for")) {
460 origin = xmlTextReaderGetAttribute(reader, XMLCHAR("origin"));
461 rpmlog(RPMLOG_DEBUG, "for %s\n", ASCII(origin));
462 if (!origin) return -1;
463 if (provide->origin) {
464 msmFreePointer((void**)&origin);
467 provide->origin = ASCII(origin);
468 if (strcmp(ASCII(origin), "trusted") &&
469 strcmp(ASCII(origin), "current") &&
470 strcmp(ASCII(origin), "all"))
473 } else if (!strcmp(ASCII(node), "filesystem")) {
474 filesystem_x *filesystem = msmProcessFilesystem(reader);
476 LISTADD(provide->filesystems, filesystem);
480 rpmlog(RPMLOG_ERR, "No allowed element in assign section: %s\n", ASCII(node));
484 if (ret < 0) return ret;
490 static int msmProcessPackage(xmlTextReaderPtr reader, package_x *package, sw_source_x *current)
492 const xmlChar *node, *name, *modified;
495 /* config processing */
496 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
497 modified = xmlTextReaderGetAttribute(reader, XMLCHAR("modified"));
498 rpmlog(RPMLOG_DEBUG, "package %s %s\n", name, modified);
500 package->name = ASCII(name);
501 package->modified = ASCII(modified);
502 package->sw_source = current;
504 depth = xmlTextReaderDepth(reader);
505 while ((ret = msmNextChildElement(reader, depth))) {
506 node = xmlTextReaderConstName(reader);
507 if (!node) return -1;
509 if (!strcmp(ASCII(node), "provide")) {
510 provide_x *provide = calloc(1, sizeof(provide_x));
512 LISTADD(package->provides, provide);
513 ret = msmProcessProvide(reader, provide, current, NULL, package->name);
517 if (ret < 0) return ret;
522 static int msmProcessRequest(xmlTextReaderPtr reader, request_x *request)
524 const xmlChar *node, *name;
525 int ret, depth, requestPresent = 0;
527 rpmlog(RPMLOG_DEBUG, "request \n");
528 depth = xmlTextReaderDepth(reader);
529 while ((ret = msmNextChildElement(reader, depth))) {
530 node = xmlTextReaderConstName(reader);
531 if (!node) return -1;
533 if (!strcmp(ASCII(node), "domain")) {
534 if (requestPresent) {
535 rpmlog(RPMLOG_ERR, "A second domain defined inside a request section. Abort package installation\n");
538 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
539 rpmlog(RPMLOG_DEBUG, "ac domain name %s\n", ASCII(name));
541 request->ac_domain = ASCII(name);
544 rpmlog(RPMLOG_ERR, "No ac domain name defined in request.\n");
548 rpmlog(RPMLOG_ERR, "Not allowed element in request section: %s\n", ASCII(node));
555 static int msmProcessDRequest(xmlTextReaderPtr reader, define_x *define)
557 const xmlChar *node = NULL, *label = NULL, *type = NULL;
560 rpmlog(RPMLOG_DEBUG, "request\n");
563 rpmlog(RPMLOG_ERR, "An attempt to define a domain without a name. Abort.\n");
567 depth = xmlTextReaderDepth(reader);
568 while ((ret = msmNextChildElement(reader, depth))) {
569 node = xmlTextReaderConstName(reader);
570 if (!node) return -1;
572 if (!strcmp(ASCII(node), "smack")) {
573 label = xmlTextReaderGetAttribute(reader, XMLCHAR("request"));
574 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
575 rpmlog(RPMLOG_DEBUG, "request label %s type %s\n", ASCII(label), ASCII(type));
577 if (msmVerifyAccessType(ASCII(type)) < 0) {
578 msmFreePointer((void**)&label);
579 msmFreePointer((void**)&type);
582 if (msmVerifySmackLabel(ASCII(label)) < 0) {
583 msmFreePointer((void**)&label);
584 msmFreePointer((void**)&type);
587 d_request_x *request = calloc(1, sizeof(d_request_x));
589 request->label_name = ASCII(label);
590 request->ac_type = ASCII(type);
591 LISTADD(define->d_requests, request);
593 msmFreePointer((void**)&label);
594 msmFreePointer((void**)&type);
598 rpmlog(RPMLOG_ERR, "One of the mandatory arguments for domain request is missing. Abort installation\n");
599 rpmlog(RPMLOG_ERR, "smack request label %s type %s\n", ASCII(label), ASCII(type));
600 msmFreePointer((void**)&label);
601 msmFreePointer((void**)&type);
605 rpmlog(RPMLOG_ERR, "Not allowed element in domain request section: %s\n", ASCII(node));
608 if (ret < 0) return ret;
614 static int msmProcessDPermit(xmlTextReaderPtr reader, define_x *define)
616 const xmlChar *node, *label, *type, *to_label;
619 rpmlog(RPMLOG_DEBUG, "permit\n");
622 rpmlog(RPMLOG_ERR, "An attempt to define a domain without a name. Abort.\n");
626 depth = xmlTextReaderDepth(reader);
628 while ((ret = msmNextChildElement(reader, depth))) {
629 node = xmlTextReaderConstName(reader);
630 if (!node) return -1;
632 if (!strcmp(ASCII(node), "smack")) {
633 label = xmlTextReaderGetAttribute(reader, XMLCHAR("permit"));
634 to_label = xmlTextReaderGetAttribute(reader, XMLCHAR("to"));
635 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
636 rpmlog(RPMLOG_DEBUG, "permit %s to %s type %s\n", ASCII(label), ASCII(to_label), ASCII(type));
639 if (msmVerifyAccessType(ASCII(type)) < 0) {
640 msmFreePointer((void**)&label);
641 msmFreePointer((void**)&to_label);
642 msmFreePointer((void**)&type);
645 if (msmVerifySmackLabel(ASCII(label)) < 0) {
646 msmFreePointer((void**)&label);
647 msmFreePointer((void**)&to_label);
648 msmFreePointer((void**)&type);
651 if ((to_label) && (msmVerifyLabelPrefix(ASCII(to_label), define->name) < 0)) {
652 msmFreePointer((void**)&label);
653 msmFreePointer((void**)&to_label);
654 msmFreePointer((void**)&type);
657 d_permit_x *permit = calloc(1, sizeof(d_permit_x));
659 permit->label_name = ASCII(label);
660 permit->to_label_name = ASCII(to_label);
661 permit->ac_type = ASCII(type);
662 LISTADD(define->d_permits, permit);
664 msmFreePointer((void**)&label);
665 msmFreePointer((void**)&to_label);
666 msmFreePointer((void**)&type);
670 rpmlog(RPMLOG_ERR, "One of the mandatory arguments for domain permit is missing. Abort installation\n");
671 rpmlog(RPMLOG_ERR, "smack permit label %s type %s\n", ASCII(label), ASCII(type));
672 msmFreePointer((void**)&label);
673 msmFreePointer((void**)&to_label);
674 msmFreePointer((void**)&type);
678 rpmlog(RPMLOG_ERR, "Not allowed element in domain permit section: %s\n", ASCII(node));
681 if (ret < 0) return ret;
687 static int msmProcessDProvide(xmlTextReaderPtr reader, define_x *define)
689 const xmlChar *node, *label;
692 rpmlog(RPMLOG_DEBUG, "provide\n");
695 rpmlog(RPMLOG_ERR, "An attempt to define a domain without a name. Abort.\n");
699 depth = xmlTextReaderDepth(reader);
700 while ((ret = msmNextChildElement(reader, depth))) {
701 node = xmlTextReaderConstName(reader);
702 if (!node) return -1;
703 if (!strcmp(ASCII(node), "label")) {
704 label = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
705 rpmlog(RPMLOG_DEBUG, "label %s \n", ASCII(label));
708 if (msmVerifySmackLabel(ASCII(label)) < 0) {
709 msmFreePointer((void**)&label);
712 if (msmVerifyLabelPrefix(ASCII(label), define->name) < 0) {
713 msmFreePointer((void**)&label);
716 d_provide_x *provide = calloc(1, sizeof(d_provide_x));
718 provide->label_name = ASCII(label);
719 LISTADD(define->d_provides, provide);
721 msmFreePointer((void**)&label);
725 rpmlog(RPMLOG_INFO, "Label name is empty. Label provide is ignored\n");
729 rpmlog(RPMLOG_ERR, "Not allowed element in domain provide section: %s\n", ASCII(node));
732 if (ret < 0) return ret;
738 static int msmProcessDefine(xmlTextReaderPtr reader, define_x *define, manifest_x *mfx, sw_source_x *current)
740 const xmlChar *node, *name, *policy, *plist;
741 int ret, depth, domainPresent = 0;
743 rpmlog(RPMLOG_DEBUG, "define\n");
745 depth = xmlTextReaderDepth(reader);
747 while ((ret = msmNextChildElement(reader, depth))) {
748 node = xmlTextReaderConstName(reader);
749 if (!node) return -1;
750 if (!strcmp(ASCII(node), "domain")) {
752 rpmlog(RPMLOG_ERR, "Only one domain is allowed per define section. Abort installation\n");
756 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
757 policy = xmlTextReaderGetAttribute(reader, XMLCHAR("policy"));
758 plist = xmlTextReaderGetAttribute(reader, XMLCHAR("plist"));
759 rpmlog(RPMLOG_DEBUG, "domain %s policy %s plist %s\n",
760 ASCII(name), ASCII(policy), ASCII(plist));
763 if (msmVerifySmackLabel(ASCII(name)) < 0) {
764 msmFreePointer((void**)&name);
765 msmFreePointer((void**)&policy);
766 msmFreePointer((void**)&plist);
770 define->name = ASCII(name);
771 define->policy = ASCII(policy);
772 define->plist = ASCII(plist);
773 // store defined ac domain name
774 ac_domain_x *ac_domain = calloc(1, sizeof(ac_domain_x));
777 ac_domain->name = strdup(define->name);
779 ac_domain->match = strdup("trusted"); // hardcode trusted policy for ac domain definition
780 if (define->policy) {
781 ac_domain->type = strdup(define->policy);
784 ac_domain->plist = strdup(define->plist);
786 ac_domain->sw_source = current;
787 ac_domain->pkg_name = mfx->name;
789 provide_x *provide = calloc(1, sizeof(provide_x));
791 LISTADD(mfx->provides, provide);
794 msmFreeACDomain(ac_domain);
799 LISTADD(mfx->provides->ac_domains, ac_domain);
802 rpmlog(RPMLOG_ERR, "Domain name must be defined. Abort installation\n");
803 msmFreePointer((void**)&policy);
804 msmFreePointer((void**)&plist);
807 } else if (!strcmp(ASCII(node), "request")) {
808 int res = msmProcessDRequest(reader, define);
809 if (res < 0) return res;
810 } else if (!strcmp(ASCII(node), "permit")) {
811 int res = msmProcessDPermit(reader, define);
812 if (res < 0) return res;
813 } else if (!strcmp(ASCII(node), "provide")) {
814 int res = msmProcessDProvide(reader, define);
815 if (res < 0) return res;
817 rpmlog(RPMLOG_ERR, "Not allowed element in domain define section: %s\n", ASCII(node));
820 if (ret < 0) return ret;
825 int msmFindSWSourceByKey(sw_source_x *sw_source, void *param)
829 keyinfo_x *current_keyinfo = (keyinfo_x*)param;
831 for (origin = sw_source->origins; origin; origin = origin->prev) {
832 for (keyinfo = origin->keyinfos; keyinfo; keyinfo = keyinfo->prev) {
833 if (strncmp((const char*)current_keyinfo->keydata, (const char*)keyinfo->keydata,
834 strlen((const char*)current_keyinfo->keydata)) == 0
835 && (current_keyinfo->keylen == keyinfo->keylen))
842 int msmFindSWSourceByName(sw_source_x *sw_source, void *param)
844 const char *name = (const char *)param;
845 return strcmp(sw_source->name, name);
848 int msmFindSWSourceBySignature(sw_source_x *sw_source, void *param, void* param2)
852 pgpDigParams sig = (pgpDigParams)param;
853 DIGEST_CTX ctx = (DIGEST_CTX)param2;
854 pgpDigParams key = NULL;
856 for (origin = sw_source->origins; origin; origin = origin->prev) {
857 for (keyinfo = origin->keyinfos; keyinfo; keyinfo = keyinfo->prev) {
858 if (pgpPrtParams(keyinfo->keydata, keyinfo->keylen, PGPTAG_PUBLIC_KEY, &key)) {
859 rpmlog(RPMLOG_ERR, "invalid sw source key\n");
862 if (pgpVerifySignature(key, sig, ctx) == RPMRC_OK) {
870 static int msmProcessKeyinfo(xmlTextReaderPtr reader, origin_x *origin, sw_source_x *parent)
872 const xmlChar *keydata;
876 depth = xmlTextReaderDepth(reader);
877 while ((ret = msmNextChildElement(reader, depth))) {
878 keydata = xmlTextReaderConstValue(reader);
879 rpmlog(RPMLOG_DEBUG, "keyinfo %.40s...\n", ASCII(keydata));
880 if (!keydata) return -1;
881 keyinfo = calloc(1, sizeof(keyinfo_x));
883 if ((ret = rpmBase64Decode(ASCII(keydata), (void **)&keyinfo->keydata, &keyinfo->keylen))) {
884 rpmlog(RPMLOG_ERR, "Failed to decode keyinfo %s, %d\n", keydata, ret);
888 // check that keys aren't matching
889 sw_source_x *old = msmSWSourceTreeTraversal(parent, msmFindSWSourceByKey, (void *)keyinfo, NULL);
891 rpmlog(RPMLOG_ERR, "SW source with this key has already been installed\n");
895 LISTADD(origin->keyinfos, keyinfo);
898 if (ret < 0) return ret;
903 static access_x *msmProcessAccess(xmlTextReaderPtr reader, origin_x *origin)
905 const xmlChar *data, *type;
907 data = xmlTextReaderGetAttribute(reader, XMLCHAR("data"));
908 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
909 rpmlog(RPMLOG_DEBUG, "access %s %s\n", ASCII(data), ASCII(type));
912 access_x *access = calloc(1, sizeof(access_x));
914 access->data = ASCII(data);
915 access->type = ASCII(type);
919 msmFreePointer((void**)&data);
920 msmFreePointer((void**)&type);
924 static int msmProcessOrigin(xmlTextReaderPtr reader, origin_x *origin, sw_source_x *parent)
926 const xmlChar *node, *type;
929 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
930 rpmlog(RPMLOG_DEBUG, "origin %s\n", ASCII(type));
931 origin->type = ASCII(type);
933 depth = xmlTextReaderDepth(reader);
934 while ((ret = msmNextChildElement(reader, depth))) {
935 node = xmlTextReaderConstName(reader);
936 if (!node) return -1;
937 if (!strcmp(ASCII(node), "keyinfo")) {
938 ret = msmProcessKeyinfo(reader, origin, parent);
939 } else if (!strcmp(ASCII(node), "access")) {
940 access_x *access = msmProcessAccess(reader, origin);
942 LISTADD(origin->accesses, access);
946 if (ret < 0) return ret;
951 static int msmProcessDeny(xmlTextReaderPtr reader, sw_source_x *sw_source)
956 rpmlog(RPMLOG_DEBUG, "deny\n");
958 depth = xmlTextReaderDepth(reader);
959 while ((ret = msmNextChildElement(reader, depth))) {
960 node = xmlTextReaderConstName(reader);
961 if (!node) return -1;
962 if (!strcmp(ASCII(node), "ac_domain")) {
963 ac_domain_x *ac_domain = msmProcessACDomain(reader, sw_source, NULL);
965 if (ac_domain->name) {
966 HASH_ADD_KEYPTR(hh, sw_source->denys, ac_domain->name,
967 strlen(ac_domain->name), ac_domain);
969 LISTADD(sw_source->denymatches, ac_domain);
973 if (ret < 0) return ret;
978 static int msmProcessAllow(xmlTextReaderPtr reader, sw_source_x *sw_source)
983 rpmlog(RPMLOG_DEBUG, "allow\n");
985 depth = xmlTextReaderDepth(reader);
986 while ((ret = msmNextChildElement(reader, depth))) {
987 node = xmlTextReaderConstName(reader);
988 if (!node) return -1;
989 if (!strcmp(ASCII(node), "deny")) {
990 ret = msmProcessDeny(reader, sw_source);
991 } else if (!strcmp(ASCII(node), "ac_domain")) {
992 ac_domain_x *ac_domain = msmProcessACDomain(reader, sw_source, NULL);
994 if (ac_domain->name) {
995 HASH_ADD_KEYPTR(hh, sw_source->allows, ac_domain->name,
996 strlen(ac_domain->name), ac_domain);
998 LISTADD(sw_source->allowmatches, ac_domain);
1002 if (ret < 0) return ret;
1007 static int msmProcessSWSource(xmlTextReaderPtr reader, sw_source_x *sw_source, const char *parentkey, manifest_x *mfx)
1009 const xmlChar *name, *node, *rank, *rankkey;
1010 sw_source_x *current;
1011 int ret, depth, len;
1014 /* config processing */
1015 current = sw_source;
1017 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
1018 rank = xmlTextReaderGetAttribute(reader, XMLCHAR("rank"));
1019 rankkey = xmlTextReaderGetAttribute(reader, XMLCHAR("rankkey"));
1020 rpmlog(RPMLOG_DEBUG, "sw source %s rank %s key %s\n",
1021 ASCII(name), ASCII(rank), ASCII(rankkey));
1023 sw_source->name = ASCII(name);
1026 /* config processing */
1027 sw_source->rankkey = ASCII(rankkey);
1030 rankval = atoi(ASCII(rank));
1031 msmFreePointer((void**)&rank); /* rankkey is used from now on */
1034 if (!sw_source->name) return -1; /* sw source must have name */
1035 if (!mfx && rankkey) return -1; /* manifest cannot set rankkey itself */
1038 sw_source_x *old = msmSWSourceTreeTraversal(sw_source->parent, msmFindSWSourceByName, (void *)sw_source->name, NULL);
1039 if (old && old->parent != sw_source->parent) {
1040 if (!old->parent && old == sw_source->parent) {
1041 /* root sw source upgrade (it's signed by root) */
1044 rpmlog(RPMLOG_ERR, "SW source called %s has already been installed\n",
1046 return -1; /* sw_source names are unique (allow upgrade though) */
1049 /* rank algorithm is copied from harmattan dpkg wrapper */
1050 if (rankval > RANK_LIMIT) rankval = RANK_LIMIT;
1051 if (rankval < -RANK_LIMIT) rankval = -RANK_LIMIT;
1052 rankval += RANK_LIMIT;
1054 len = strlen(parentkey) + 1 + 5 + 1 + 5 + 1 + strlen(sw_source->name) + 1;
1055 if (!(sw_source->rankkey = malloc(len))) return -1;
1056 sprintf((char *)sw_source->rankkey, "%s/%05d/%05d.%s",
1057 parentkey, rankval, RANK_LIMIT, sw_source->name);
1060 depth = xmlTextReaderDepth(reader);
1061 while ((ret = msmNextChildElement(reader, depth))) {
1062 node = xmlTextReaderConstName(reader);
1063 if (!node) return -1;
1064 if (!strcmp(ASCII(node), "allow")) {
1065 ret = msmProcessAllow(reader, sw_source);
1066 } else if (!strcmp(ASCII(node), "deny")) {
1067 ret = msmProcessDeny(reader, sw_source);
1068 } else if (!strcmp(ASCII(node), "origin")) {
1069 origin_x *origin = calloc(1, sizeof(origin_x));
1071 LISTADD(sw_source->origins, origin);
1072 ret = msmProcessOrigin(reader, origin, sw_source->parent);
1074 } else if (!strcmp(ASCII(node), "package")) {
1075 /* config processing */
1076 if (!mfx) return -1;
1077 package_x *package = calloc(1, sizeof(package_x));
1079 LISTADD(sw_source->packages, package);
1080 ret = msmProcessPackage(reader, package, current);
1082 } else if (!strcmp(ASCII(node), "sw_source")) {
1083 /* config processing */
1084 if (!mfx) return -1;
1085 sw_source_x *sw_source = calloc(1, sizeof(sw_source_x));
1087 sw_source->parent = current;
1088 LISTADD(mfx->sw_sources, sw_source);
1090 ret = msmProcessSWSource(reader, sw_source, "", mfx);
1093 if (ret < 0) return ret;
1098 static int msmProcessAttributes(xmlTextReaderPtr reader, manifest_x *mfx)
1100 const xmlChar *node, *type;
1101 int ret, depth, attributePresent = 0;
1103 rpmlog(RPMLOG_DEBUG, "attributes\n");
1104 depth = xmlTextReaderDepth(reader);
1106 while ((ret = msmNextChildElement(reader, depth))) {
1107 node = xmlTextReaderConstName(reader);
1108 if (!node) return -1;
1109 if (!strcmp(ASCII(node), "package")) {
1110 if (attributePresent) {
1111 rpmlog(RPMLOG_ERR, "Only one attribute is currently allowed per attribute section. Abort installation\n");
1114 attributePresent = 1;
1115 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
1116 rpmlog(RPMLOG_DEBUG, "package type is %s\n", ASCII(type));
1119 if ((strcmp(type, "system") != 0) &&
1120 (strcmp(type, "application") != 0)){
1121 rpmlog(RPMLOG_ERR, "Not allowed attribute name in a package type specification. Abort installation.\n");
1122 msmFreePointer((void**)&type);
1125 mfx->package_type = ASCII(type);
1127 rpmlog(RPMLOG_ERR, "Type name must be defined. Abort installation\n");
1131 rpmlog(RPMLOG_ERR, "Not allowed element in attribute section: %s\n", ASCII(node));
1134 if (ret < 0) return ret;
1139 static int msmProcessMsm(xmlTextReaderPtr reader, manifest_x *mfx, sw_source_x *current)
1141 const xmlChar *node;
1143 int assignPresent = 0, requestPresent = 0, attributesPresent = 0; /* there must be only one section per manifest */
1144 mfx->sw_source = current;
1146 rpmlog(RPMLOG_DEBUG, "manifest\n");
1148 depth = xmlTextReaderDepth(reader);
1149 while ((ret = msmNextChildElement(reader, depth))) {
1150 node = xmlTextReaderConstName(reader);
1151 if (!node) return -1;
1152 if (!strcmp(ASCII(node), "assign")) {
1153 if (assignPresent) {
1154 rpmlog(RPMLOG_ERR, "A second assign section in manifest isn't allowed. Abort installation.\n");
1158 provide_x *provide = calloc(1, sizeof(provide_x));
1160 LISTADD(mfx->provides, provide);
1161 ret = msmProcessProvide(reader, provide, current, mfx, NULL);
1163 } else if (!strcmp(ASCII(node), "attributes")) {
1164 if (attributesPresent) {
1165 rpmlog(RPMLOG_ERR, "A second attribute section in manifest isn't allowed. Abort installation.\n");
1168 attributesPresent = 1;
1169 ret = msmProcessAttributes(reader, mfx);
1170 } else if (!strcmp(ASCII(node), "define")) {
1171 define_x *define = calloc(1, sizeof(define_x));
1173 LISTADD(mfx->defines, define);
1174 ret = msmProcessDefine(reader, define, mfx, current);
1176 } else if (!strcmp(ASCII(node), "request")) {
1177 if (requestPresent) {
1178 rpmlog(RPMLOG_ERR, "A second request section in manifest isn't allowed. Abort installation.\n");
1182 mfx->request = calloc(1, sizeof(request_x));
1184 ret = msmProcessRequest(reader, mfx->request);
1186 } else if (!strcmp(ASCII(node), "sw_source")) {
1187 sw_source_x *sw_source = calloc(1, sizeof(sw_source_x));
1189 char parentkey[256] = { 0 };
1190 sw_source->parent = current;
1191 if (sw_source->parent) {
1192 snprintf(parentkey, sizeof(parentkey),
1193 "%s", sw_source->parent->rankkey);
1194 char *sep = strrchr(parentkey, '/');
1195 if (sep) *sep = '\0';
1197 LISTADD(mfx->sw_sources, sw_source);
1198 ret = msmProcessSWSource(reader, sw_source, parentkey, NULL);
1201 if (ret < 0) return ret;
1206 static int msmProcessConfig(xmlTextReaderPtr reader, manifest_x *mfx)
1208 const xmlChar *node;
1211 rpmlog(RPMLOG_DEBUG, "config\n");
1213 depth = xmlTextReaderDepth(reader);
1214 if ((ret = msmNextChildElement(reader, depth))) {
1215 node = xmlTextReaderConstName(reader);
1216 if (!node) return -1;
1217 if (!strcmp(ASCII(node), "sw_source")) {
1218 mfx->sw_sources = calloc(1, sizeof(sw_source_x));
1219 if (!mfx->sw_sources) return -1;
1220 ret = msmProcessSWSource(reader, mfx->sw_sources, "", mfx);
1226 static int msmProcessManifest(xmlTextReaderPtr reader, manifest_x *mfx, sw_source_x *current)
1228 const xmlChar *node;
1231 if ((ret = msmNextChildElement(reader, -1))) {
1232 node = xmlTextReaderConstName(reader);
1233 if (!node) return -1;
1234 if (!strcmp(ASCII(node), "manifest")) {
1235 ret = msmProcessMsm(reader, mfx, current);
1236 } else if (!strcmp(ASCII(node), "config")) {
1237 ret = msmProcessConfig(reader, mfx);
1243 static filesystem_x *msmFreeFilesystem(filesystem_x *filesystem)
1246 filesystem_x *prev = filesystem->prev;
1247 msmFreePointer((void**)&filesystem->path);
1248 msmFreePointer((void**)&filesystem->label);
1249 msmFreePointer((void**)&filesystem->exec_label);
1250 msmFreePointer((void**)&filesystem->type);
1251 msmFreePointer((void**)&filesystem);
1257 static member_x *msmFreeMember(member_x *member)
1260 member_x *prev = member->prev;
1261 msmFreePointer((void**)&member->name);
1262 if (member->annotation) {
1263 msmFreePointer((void**)&member->annotation->name);
1264 msmFreePointer((void**)&member->annotation->value);
1265 msmFreePointer((void**)&member->annotation);
1267 msmFreePointer((void**)&member);
1273 static interface_x *msmFreeInterface(interface_x *interface)
1278 interface_x *prev = interface->prev;
1279 msmFreePointer((void**)&interface->name);
1280 if (interface->annotation) {
1281 msmFreePointer((void**)&interface->annotation->name);
1282 msmFreePointer((void**)&interface->annotation->value);
1283 msmFreePointer((void**)&interface->annotation);
1285 for (member = interface->members; member; member = msmFreeMember(member));
1286 msmFreePointer((void**)&interface);
1292 static node_x *msmFreeNode(node_x *node)
1295 interface_x *interface;
1298 node_x *prev = node->prev;
1299 msmFreePointer((void**)&node->name);
1300 if (node->annotation) {
1301 msmFreePointer((void**)&node->annotation->name);
1302 msmFreePointer((void**)&node->annotation->value);
1303 msmFreePointer((void**)&node->annotation);
1305 for (member = node->members; member; member = msmFreeMember(member));
1306 for (interface = node->interfaces; interface; interface = msmFreeInterface(interface));
1307 msmFreePointer((void**)&node);
1313 static dbus_x *msmFreeDBus(dbus_x *dbus)
1318 dbus_x *prev = dbus->prev;
1319 msmFreePointer((void**)&dbus->name);
1320 msmFreePointer((void**)&dbus->own);
1321 msmFreePointer((void**)&dbus->bus);
1322 if (dbus->annotation) {
1323 msmFreePointer((void**)&dbus->annotation->name);
1324 msmFreePointer((void**)&dbus->annotation->value);
1325 msmFreePointer((void**)&dbus->annotation);
1327 for (node = dbus->nodes; node; node = msmFreeNode(node));
1328 msmFreePointer((void**)&dbus);
1333 static provide_x *msmFreeProvide(provide_x *provide)
1335 ac_domain_x *ac_domain;
1336 filesystem_x *filesystem;
1337 provide_x *prev = provide->prev;
1341 for (ac_domain = provide->ac_domains; ac_domain; ac_domain = msmFreeACDomain(ac_domain));
1342 if (provide->filesystems)
1343 for (filesystem = provide->filesystems; filesystem; filesystem = msmFreeFilesystem(filesystem));
1344 msmFreePointer((void**)&provide->name);
1345 msmFreePointer((void**)&provide->origin);
1346 for (dbus = provide->dbuss; dbus; dbus = msmFreeDBus(dbus));
1347 msmFreePointer((void**)&provide);
1352 static file_x *msmFreeFile(file_x *file)
1354 file_x *prev = file->prev;
1355 msmFreePointer((void**)&file->path);
1356 msmFreePointer((void**)&file);
1360 package_x *msmFreePackage(package_x *package)
1363 package_x *prev = package->prev;
1364 for (provide = package->provides; provide; provide = msmFreeProvide(provide));
1365 msmFreePointer((void**)&package->name);
1366 msmFreePointer((void**)&package->modified);
1367 msmFreePointer((void**)&package);
1371 static keyinfo_x *msmFreeKeyinfo(keyinfo_x *keyinfo)
1373 keyinfo_x *prev = keyinfo->prev;
1374 msmFreePointer((void**)&keyinfo->keydata);
1375 msmFreePointer((void**)&keyinfo);
1379 static access_x *msmFreeAccess(access_x *access)
1381 access_x *prev = access->prev;
1382 msmFreePointer((void**)&access->data);
1383 msmFreePointer((void**)&access->type);
1384 msmFreePointer((void**)&access);
1388 static origin_x *msmFreeOrigin(origin_x *origin)
1392 origin_x *prev = origin->prev;
1393 for (keyinfo = origin->keyinfos; keyinfo; keyinfo = msmFreeKeyinfo(keyinfo));
1394 for (access = origin->accesses; access; access = msmFreeAccess(access));
1395 msmFreePointer((void**)&origin->type);
1396 msmFreePointer((void**)&origin);
1400 static sw_source_x *msmFreeSWSource(sw_source_x *sw_source)
1403 ac_domain_x *ac_domain, *temp;
1405 sw_source_x *next = sw_source->next;
1407 rpmlog(RPMLOG_DEBUG, "freeing sw source %s\n", sw_source->name);
1409 for (package = sw_source->packages; package; package = msmFreePackage(package));
1410 for (ac_domain = sw_source->allowmatches; ac_domain; ac_domain = msmFreeACDomain(ac_domain));
1411 if (sw_source->allows) {
1412 HASH_ITER(hh, sw_source->allows, ac_domain, temp) {
1413 HASH_DELETE(hh, sw_source->allows, ac_domain);
1414 msmFreeACDomain(ac_domain);
1418 for (ac_domain = sw_source->denymatches; ac_domain; ac_domain = msmFreeACDomain(ac_domain));
1419 if (sw_source->denys) {
1420 HASH_ITER(hh, sw_source->denys, ac_domain, temp) {
1421 HASH_DELETE(hh, sw_source->denys, ac_domain);
1422 msmFreeACDomain(ac_domain);
1425 for (origin = sw_source->origins; origin; origin = msmFreeOrigin(origin));
1426 msmFreePointer((void**)&sw_source->name);
1427 msmFreePointer((void**)&sw_source->rankkey);
1428 msmFreePointer((void**)&sw_source);
1432 static d_request_x *msmFreeDRequest(d_request_x *d_request)
1434 d_request_x *next = d_request->next;
1435 rpmlog(RPMLOG_DEBUG, "freeing domain request %s\n", d_request->label_name);
1436 msmFreePointer((void**)&d_request->label_name);
1437 msmFreePointer((void**)&d_request->ac_type);
1438 msmFreePointer((void**)&d_request);
1442 static d_permit_x *msmFreeDPermit(d_permit_x *d_permit)
1444 d_permit_x *next = d_permit->next;
1445 rpmlog(RPMLOG_DEBUG, "freeing domain permit %s\n", d_permit->label_name);
1446 msmFreePointer((void**)&d_permit->label_name);
1447 msmFreePointer((void**)&d_permit->to_label_name);
1448 msmFreePointer((void**)&d_permit->ac_type);
1449 msmFreePointer((void**)&d_permit);
1453 static d_provide_x *msmFreeDProvide(d_provide_x *d_provide)
1455 d_provide_x *next = d_provide->next;
1456 rpmlog(RPMLOG_DEBUG, "freeing domain provide %s\n", d_provide->label_name);
1457 msmFreePointer((void**)&d_provide->label_name);
1458 msmFreePointer((void**)&d_provide);
1462 static define_x *msmFreeDefine(define_x *define)
1464 define_x *next = define->next;
1465 d_request_x *d_request;
1466 d_permit_x *d_permit;
1467 d_provide_x *d_provide;
1469 msmFreePointer((void**)&define->name);
1470 msmFreePointer((void**)&define->policy);
1471 msmFreePointer((void**)&define->plist);
1473 if (define->d_requests) {
1474 LISTHEAD(define->d_requests, d_request);
1475 for (; d_request; d_request = msmFreeDRequest(d_request));
1477 rpmlog(RPMLOG_DEBUG, "after freeing define requests\n");
1478 if (define->d_permits) {
1479 LISTHEAD(define->d_permits, d_permit);
1480 for (; d_permit; d_permit = msmFreeDPermit(d_permit));
1482 rpmlog(RPMLOG_DEBUG, "after freeing define permits\n");
1483 if (define->d_provides) {
1484 LISTHEAD(define->d_provides, d_provide);
1485 for (; d_provide; d_provide = msmFreeDProvide(d_provide));
1487 rpmlog(RPMLOG_DEBUG, "after freeing provides\n");
1488 msmFreePointer((void**)&define);
1492 manifest_x* msmFreeManifestXml(manifest_x* mfx)
1496 sw_source_x *sw_source;
1499 rpmlog(RPMLOG_DEBUG, "in msmFreeManifestXml\n");
1502 for (provide = mfx->provides; provide; provide = msmFreeProvide(provide));
1503 rpmlog(RPMLOG_DEBUG, "after freeing provides\n");
1505 msmFreePointer((void**)&mfx->request->ac_domain);
1506 msmFreePointer((void**)&mfx->request);
1508 rpmlog(RPMLOG_DEBUG, "after freeing requests\n");
1509 for (file = mfx->files; file; file = msmFreeFile(file));
1510 rpmlog(RPMLOG_DEBUG, "after freeing files\n");
1511 if (mfx->sw_sources) {
1512 LISTHEAD(mfx->sw_sources, sw_source);
1513 for (; sw_source; sw_source = msmFreeSWSource(sw_source));
1515 msmFreePointer((void**)&mfx->name);
1516 rpmlog(RPMLOG_DEBUG, "after freeing name\n");
1518 LISTHEAD(mfx->defines, define);
1519 for (; define; define = msmFreeDefine(define));
1521 rpmlog(RPMLOG_DEBUG, "after freeing defines \n");
1522 msmFreePointer((void**)&mfx);
1527 manifest_x *msmProcessManifestXml(const char *buffer, int size, sw_source_x *current, const char *packagename)
1529 xmlTextReaderPtr reader;
1530 manifest_x *mfx = NULL;
1532 reader = xmlReaderForMemory(buffer, size, NULL, NULL, 0);
1534 mfx = calloc(1, sizeof(manifest_x));
1536 mfx->name = strdup(packagename);
1537 if (msmProcessManifest(reader, mfx, current) < 0) {
1538 /* error in parcing. Let's display some hint where we failed */
1539 rpmlog(RPMLOG_DEBUG, "Syntax error in processing manifest in the above line\n");
1540 mfx = msmFreeManifestXml(mfx);
1543 xmlFreeTextReader(reader);
1545 rpmlog(RPMLOG_ERR, "Unable to create xml reader\n");
1550 manifest_x *msmProcessDevSecPolicyXml(const char *filename)
1552 xmlTextReaderPtr reader;
1553 manifest_x *mfx = NULL;
1555 reader = xmlReaderForFile(filename, NULL, 0);
1557 mfx = calloc(1, sizeof(manifest_x));
1559 if (msmProcessManifest(reader, mfx, NULL) < 0) {
1560 mfx = msmFreeManifestXml(mfx);
1563 xmlFreeTextReader(reader);
1565 rpmlog(RPMLOG_ERR, "Unable to open device security policy %s\n", filename);