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 (strnlen(type, SMACK_ACCESS_TYPE_LENGTH + 1) >
55 SMACK_ACCESS_TYPE_LENGTH) {
56 rpmlog(RPMLOG_ERR, "Lenght of the access type is bigger than allowed value: %s\n", type);
59 while ( type[idx] != '\0' ){
60 if ((type[idx] !='a') && (type[idx]!='r') && (type[idx]!='w') &&
61 (type[idx]!='x') && (type[idx]!='t') && (type[idx]!='l') && (type[idx] !='-')) {
62 rpmlog(RPMLOG_ERR, "Not allowed character in access type: %s\n", type);
73 static int msmVerifySmackLabel(const char* label)
78 if (strlen(ASCII(label)) > SMACK_LABEL_LENGTH) { //smack limitation on lenght
79 rpmlog(RPMLOG_ERR, "Domain or label name %s lenght is longer than defined SMACK_LABEL_LENGTH\n", label);
82 if (strlen(ASCII(label)) == 0){
83 rpmlog(RPMLOG_ERR, "An attempt to define an empty domain or label name\n");
86 if (label[0] == '-') {
87 rpmlog(RPMLOG_ERR, "Dash is not allowed as first character in smack label: %s\n", label);
90 while ( label[idx] != '\0' ){
91 if ((label[idx] =='\"') || (label[idx] =='\'') || (label[idx] =='/') ||
92 (label[idx] =='\\') || (label[idx] > '~') || (label[idx] <= ' ')) {
93 rpmlog(RPMLOG_ERR, "Not allowed character in smack label: %s, position: %d \n", label, idx);
104 static int msmVerifyLabelPrefix(const char* sub_label, const char* domain_name)
109 tmp = calloc(strlen(domain_name) + 3, sizeof (const char));
113 strncpy(tmp, domain_name, strlen(domain_name));
114 strncpy(tmp + strlen(domain_name), sep, 2);
116 if (strstr(ASCII(sub_label), tmp) != ASCII(sub_label)) { //sub label name should be prefixed by domain name and "::"
117 rpmlog(RPMLOG_ERR, "Label name %s isn't prefixed by domain name %s\n", ASCII(sub_label), domain_name);
118 msmFreePointer((void**)&tmp);
122 msmFreePointer((void**)&tmp);
126 static int msmNextChildElement(xmlTextReaderPtr reader, int depth)
128 int ret = xmlTextReaderRead(reader);
129 int cur = xmlTextReaderDepth(reader);
131 /* rpmlog(RPMLOG_DEBUG, "node %s %d\n",
132 ASCII(xmlTextReaderConstName(reader)),
133 xmlTextReaderDepth(reader));
135 switch (xmlTextReaderNodeType(reader)) {
136 case XML_READER_TYPE_ELEMENT:
137 case XML_READER_TYPE_TEXT:
141 case XML_READER_TYPE_END_ELEMENT:
150 ret = xmlTextReaderRead(reader);
151 cur = xmlTextReaderDepth(reader);
156 static ac_domain_x *msmFreeACDomain(ac_domain_x *ac_domain)
159 ac_domain_x *prev = ac_domain->prev;
160 msmFreePointer((void**)&ac_domain->name);
161 msmFreePointer((void**)&ac_domain->type);
162 msmFreePointer((void**)&ac_domain->match);
163 msmFreePointer((void**)&ac_domain->plist);
164 msmFreePointer((void**)&ac_domain);
169 static annotation_x *msmProcessAnnotation(xmlTextReaderPtr reader)
171 const xmlChar *name, *value;
173 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
174 value = xmlTextReaderGetAttribute(reader, XMLCHAR("value"));
175 rpmlog(RPMLOG_DEBUG, "annotation %s %s\n", ASCII(name), ASCII(value));
178 annotation_x *annotation = calloc(1, sizeof(annotation_x));
180 annotation->name = ASCII(name);
181 annotation->value = ASCII(value);
185 msmFreePointer((void**)&name);
186 msmFreePointer((void**)&value);
190 static int msmProcessMember(xmlTextReaderPtr reader, member_x *member)
192 const xmlChar *node, *name;
195 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
196 rpmlog(RPMLOG_DEBUG, "member %s\n", ASCII(name));
197 member->name = ASCII(name);
199 if (!name) return -1;
201 depth = xmlTextReaderDepth(reader);
202 while ((ret = msmNextChildElement(reader, depth))) {
203 node = xmlTextReaderConstName(reader);
204 if (!node) return -1;
206 if (!strcmp(ASCII(node), "annotation")) {
207 annotation_x *annotation = msmProcessAnnotation(reader);
209 member->annotation = annotation;
213 if (ret < 0) return -1;
218 static int msmProcessInterface(xmlTextReaderPtr reader, interface_x *interface)
220 const xmlChar *node, *name;
223 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
224 rpmlog(RPMLOG_DEBUG, "interface %s\n", ASCII(name));
225 interface->name = ASCII(name);
227 if (!name) return -1;
229 depth = xmlTextReaderDepth(reader);
230 while ((ret = msmNextChildElement(reader, depth))) {
231 node = xmlTextReaderConstName(reader);
232 if (!node) return -1;
234 if (!strcmp(ASCII(node), "method")) {
235 member_x *member = calloc(1, sizeof(member_x));
237 member->type = DBUS_METHOD;
238 ret = msmProcessMember(reader, member);
239 LISTADD(interface->members, member);
241 } else if (!strcmp(ASCII(node), "signal")) {
242 member_x *member = calloc(1, sizeof(member_x));
244 member->type = DBUS_SIGNAL;
245 ret = msmProcessMember(reader, member);
246 LISTADD(interface->members, member);
248 } else if (!strcmp(ASCII(node), "annotation")) {
249 annotation_x *annotation = msmProcessAnnotation(reader);
251 interface->annotation = annotation;
255 if (ret < 0) return -1;
260 static int msmProcessNode(xmlTextReaderPtr reader, node_x *nodex)
262 const xmlChar *node, *name;
265 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
266 rpmlog(RPMLOG_DEBUG, "node %s\n", ASCII(name));
267 nodex->name = ASCII(name);
269 if (!name) return -1;
271 depth = xmlTextReaderDepth(reader);
272 while ((ret = msmNextChildElement(reader, depth))) {
273 node = xmlTextReaderConstName(reader);
274 if (!node) return -1;
276 if (!strcmp(ASCII(node), "interface")) {
277 interface_x *interface = calloc(1, sizeof(interface_x));
279 ret = msmProcessInterface(reader, interface);
280 LISTADD(nodex->interfaces, interface);
282 } else if (!strcmp(ASCII(node), "method")) {
283 member_x *member = calloc(1, sizeof(member_x));
285 member->type = DBUS_METHOD;
286 ret = msmProcessMember(reader, member);
287 LISTADD(nodex->members, member);
289 } else if (!strcmp(ASCII(node), "signal")) {
290 member_x *member = calloc(1, sizeof(member_x));
292 member->type = DBUS_SIGNAL;
293 ret = msmProcessMember(reader, member);
294 LISTADD(nodex->members, member);
296 } else if (!strcmp(ASCII(node), "annotation")) {
297 annotation_x *annotation = msmProcessAnnotation(reader);
299 nodex->annotation = annotation;
303 if (ret < 0) return -1;
308 static int msmProcessDBus(xmlTextReaderPtr reader, dbus_x *dbus)
310 const xmlChar *node, *name, *own, *bus;
313 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
314 own = xmlTextReaderGetAttribute(reader, XMLCHAR("own"));
315 bus = xmlTextReaderGetAttribute(reader, XMLCHAR("bus"));
316 rpmlog(RPMLOG_DEBUG, "dbus %s %s %s\n", ASCII(name), ASCII(own), ASCII(bus));
317 dbus->name = ASCII(name);
318 dbus->own = ASCII(own);
319 dbus->bus = ASCII(bus);
321 if (!name || !bus) return -1;
322 if (strcmp(dbus->bus, "session") && strcmp(dbus->bus, "system"))
325 depth = xmlTextReaderDepth(reader);
326 while ((ret = msmNextChildElement(reader, depth))) {
327 node = xmlTextReaderConstName(reader);
328 if (!node) return -1;
330 if (!strcmp(ASCII(node), "node")) {
331 node_x *nodex = calloc(1, sizeof(node_x));
333 ret = msmProcessNode(reader, nodex);
334 LISTADD(dbus->nodes, nodex);
336 } else if (!strcmp(ASCII(node), "annotation")) {
337 annotation_x *annotation = msmProcessAnnotation(reader);
339 dbus->annotation = annotation;
343 if (ret < 0) return -1;
348 static ac_domain_x *msmProcessACDomain(xmlTextReaderPtr reader, sw_source_x *sw_source, const char* pkg_name)
350 const xmlChar *name, *match, *policy, *plist;
352 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
353 match = xmlTextReaderGetAttribute(reader, XMLCHAR("match"));
354 policy = xmlTextReaderGetAttribute(reader, XMLCHAR("policy"));
355 plist = xmlTextReaderGetAttribute(reader, XMLCHAR("plist"));
356 rpmlog(RPMLOG_DEBUG, "ac_domain %s match %s policy %s plist %s\n", ASCII(name), ASCII(match), ASCII(policy), ASCII(plist));
358 if (!((!name && !match) || (name && match))) {
359 ac_domain_x *ac_domain = calloc(1, sizeof(ac_domain_x));
361 ac_domain->name = ASCII(name);
362 ac_domain->match = ASCII(match);
363 ac_domain->type = ASCII(policy);
364 ac_domain->plist = ASCII(plist);
365 ac_domain->sw_source = sw_source;
366 ac_domain->pkg_name = pkg_name;
370 rpmlog(RPMLOG_ERR, "Mandatory argument is missing for ac domain definition\n");
371 rpmlog(RPMLOG_ERR, "ac_domain %s match %s policy %s plist %s\n", ASCII(name), ASCII(match), ASCII(policy), ASCII(plist));
372 msmFreePointer((void**)&name);
373 msmFreePointer((void**)&match);
374 msmFreePointer((void**)&policy);
375 msmFreePointer((void**)&plist);
379 static filesystem_x *msmProcessFilesystem(xmlTextReaderPtr reader)
381 const xmlChar *path, *label, *type, *exec_label;
383 path = xmlTextReaderGetAttribute(reader, XMLCHAR("path"));
384 label = xmlTextReaderGetAttribute(reader, XMLCHAR("label"));
385 exec_label = xmlTextReaderGetAttribute(reader, XMLCHAR("exec_label"));
386 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
388 rpmlog(RPMLOG_DEBUG, "filesystem path %s label %s exec label %s type %s\n",
389 ASCII(path), ASCII(label), ASCII(exec_label), ASCII(type));
391 if (path && (label || exec_label)) {
392 if ((label) && (msmVerifySmackLabel(ASCII(label)) < 0)) {
395 if ((exec_label) && (msmVerifySmackLabel(ASCII(exec_label)) < 0)) {
399 filesystem_x *filesystem = calloc(1, sizeof(filesystem_x));
401 filesystem->path = ASCII(path);
402 filesystem->label = ASCII(label);
403 filesystem->exec_label = ASCII(exec_label);
404 filesystem->type = ASCII(type);
409 rpmlog(RPMLOG_ERR, "Mandatory argument is missing for filesystem assign request\n");
410 rpmlog(RPMLOG_ERR, "filesystem path %s label %s exec label %s\n",
411 ASCII(path), ASCII(label), ASCII(exec_label));
415 msmFreePointer((void**)&path);
416 msmFreePointer((void**)&label);
417 msmFreePointer((void**)&exec_label);
418 msmFreePointer((void**)&type);
422 static int msmProcessProvide(xmlTextReaderPtr reader, provide_x *provide, sw_source_x *current, manifest_x *mfx, const char* pkg_name)
424 const xmlChar *node, *name, *origin;
427 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
428 rpmlog(RPMLOG_DEBUG, "assign %s\n", ASCII(name));
429 provide->name = ASCII(name);
432 (strcmp(provide->name, "_system_") || mfx->sw_source->parent))
433 return -1; /* only _system_ is accepted from root sw source */
435 depth = xmlTextReaderDepth(reader);
436 while ((ret = msmNextChildElement(reader, depth))) {
437 node = xmlTextReaderConstName(reader);
438 if (!node) return -1;
440 if (!strcmp(ASCII(node), "dbus")) {
441 dbus_x *dbus = calloc(1, sizeof(dbus_x));
443 ret = msmProcessDBus(reader, dbus);
444 LISTADD(provide->dbuss, dbus);
446 } else if (!strcmp(ASCII(node), "ac_domain")) {
447 ac_domain_x *ac_domain = msmProcessACDomain(reader, current, pkg_name);
449 const char *name = ac_domain->name;
450 LISTADD(provide->ac_domains, ac_domain);
451 if (!name) return -1;
452 if (mfx && !provide->name) {
453 ac_domain->name = malloc(strlen(mfx->name) + 2 +
455 if (!ac_domain->name) return -1;
456 sprintf((char *)ac_domain->name, "%s::%s", mfx->name, name);
457 msmFreePointer((void**)&name);
461 } else if (!strcmp(ASCII(node), "for")) {
462 origin = xmlTextReaderGetAttribute(reader, XMLCHAR("origin"));
463 rpmlog(RPMLOG_DEBUG, "for %s\n", ASCII(origin));
464 if (!origin) return -1;
465 if (provide->origin) {
466 msmFreePointer((void**)&origin);
469 provide->origin = ASCII(origin);
470 if (strcmp(ASCII(origin), "trusted") &&
471 strcmp(ASCII(origin), "current") &&
472 strcmp(ASCII(origin), "all"))
475 } else if (!strcmp(ASCII(node), "filesystem")) {
476 filesystem_x *filesystem = msmProcessFilesystem(reader);
478 LISTADD(provide->filesystems, filesystem);
482 rpmlog(RPMLOG_ERR, "No allowed element in assign section: %s\n", ASCII(node));
486 if (ret < 0) return ret;
492 static int msmProcessPackage(xmlTextReaderPtr reader, package_x *package, sw_source_x *current)
494 const xmlChar *node, *name, *modified;
497 /* config processing */
498 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
499 modified = xmlTextReaderGetAttribute(reader, XMLCHAR("modified"));
500 rpmlog(RPMLOG_DEBUG, "package %s %s\n", name, modified);
502 package->name = ASCII(name);
503 package->modified = ASCII(modified);
504 package->sw_source = current;
506 depth = xmlTextReaderDepth(reader);
507 while ((ret = msmNextChildElement(reader, depth))) {
508 node = xmlTextReaderConstName(reader);
509 if (!node) return -1;
511 if (!strcmp(ASCII(node), "provide")) {
512 provide_x *provide = calloc(1, sizeof(provide_x));
514 LISTADD(package->provides, provide);
515 ret = msmProcessProvide(reader, provide, current, NULL, package->name);
519 if (ret < 0) return ret;
524 static int msmProcessRequest(xmlTextReaderPtr reader, request_x *request)
526 const xmlChar *node, *name;
527 int ret, depth, requestPresent = 0;
529 rpmlog(RPMLOG_DEBUG, "request \n");
530 depth = xmlTextReaderDepth(reader);
531 while ((ret = msmNextChildElement(reader, depth))) {
532 node = xmlTextReaderConstName(reader);
533 if (!node) return -1;
535 if (!strcmp(ASCII(node), "domain")) {
536 if (requestPresent) {
537 rpmlog(RPMLOG_ERR, "A second domain defined inside a request section. Abort package installation\n");
540 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
541 rpmlog(RPMLOG_DEBUG, "ac domain name %s\n", ASCII(name));
543 request->ac_domain = ASCII(name);
546 rpmlog(RPMLOG_ERR, "No ac domain name defined in request.\n");
550 rpmlog(RPMLOG_ERR, "Not allowed element in request section: %s\n", ASCII(node));
557 static int msmProcessDRequest(xmlTextReaderPtr reader, define_x *define)
559 const xmlChar *node = NULL, *label = NULL, *type = NULL;
562 rpmlog(RPMLOG_DEBUG, "request\n");
565 rpmlog(RPMLOG_ERR, "An attempt to define a domain without a name. Abort.\n");
569 depth = xmlTextReaderDepth(reader);
570 while ((ret = msmNextChildElement(reader, depth))) {
571 node = xmlTextReaderConstName(reader);
572 if (!node) return -1;
574 if (!strcmp(ASCII(node), "smack")) {
575 label = xmlTextReaderGetAttribute(reader, XMLCHAR("request"));
576 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
577 rpmlog(RPMLOG_DEBUG, "request label %s type %s\n", ASCII(label), ASCII(type));
579 if (msmVerifyAccessType(ASCII(type)) < 0) {
580 msmFreePointer((void**)&label);
581 msmFreePointer((void**)&type);
584 if (msmVerifySmackLabel(ASCII(label)) < 0) {
585 msmFreePointer((void**)&label);
586 msmFreePointer((void**)&type);
589 d_request_x *request = calloc(1, sizeof(d_request_x));
591 request->label_name = ASCII(label);
592 request->ac_type = ASCII(type);
593 LISTADD(define->d_requests, request);
595 msmFreePointer((void**)&label);
596 msmFreePointer((void**)&type);
600 rpmlog(RPMLOG_ERR, "One of the mandatory arguments for domain request is missing. Abort installation\n");
601 rpmlog(RPMLOG_ERR, "smack request label %s type %s\n", ASCII(label), ASCII(type));
602 msmFreePointer((void**)&label);
603 msmFreePointer((void**)&type);
607 rpmlog(RPMLOG_ERR, "Not allowed element in domain request section: %s\n", ASCII(node));
610 if (ret < 0) return ret;
616 static int msmProcessDPermit(xmlTextReaderPtr reader, define_x *define)
618 const xmlChar *node, *label, *type, *to_label;
621 rpmlog(RPMLOG_DEBUG, "permit\n");
624 rpmlog(RPMLOG_ERR, "An attempt to define a domain without a name. Abort.\n");
628 depth = xmlTextReaderDepth(reader);
630 while ((ret = msmNextChildElement(reader, depth))) {
631 node = xmlTextReaderConstName(reader);
632 if (!node) return -1;
634 if (!strcmp(ASCII(node), "smack")) {
635 label = xmlTextReaderGetAttribute(reader, XMLCHAR("permit"));
636 to_label = xmlTextReaderGetAttribute(reader, XMLCHAR("to"));
637 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
638 rpmlog(RPMLOG_DEBUG, "permit %s to %s type %s\n", ASCII(label), ASCII(to_label), ASCII(type));
641 if (msmVerifyAccessType(ASCII(type)) < 0) {
642 msmFreePointer((void**)&label);
643 msmFreePointer((void**)&to_label);
644 msmFreePointer((void**)&type);
647 if (msmVerifySmackLabel(ASCII(label)) < 0) {
648 msmFreePointer((void**)&label);
649 msmFreePointer((void**)&to_label);
650 msmFreePointer((void**)&type);
653 if ((to_label) && (msmVerifyLabelPrefix(ASCII(to_label), define->name) < 0)) {
654 msmFreePointer((void**)&label);
655 msmFreePointer((void**)&to_label);
656 msmFreePointer((void**)&type);
659 d_permit_x *permit = calloc(1, sizeof(d_permit_x));
661 permit->label_name = ASCII(label);
662 permit->to_label_name = ASCII(to_label);
663 permit->ac_type = ASCII(type);
664 LISTADD(define->d_permits, permit);
666 msmFreePointer((void**)&label);
667 msmFreePointer((void**)&to_label);
668 msmFreePointer((void**)&type);
672 rpmlog(RPMLOG_ERR, "One of the mandatory arguments for domain permit is missing. Abort installation\n");
673 rpmlog(RPMLOG_ERR, "smack permit label %s type %s\n", ASCII(label), ASCII(type));
674 msmFreePointer((void**)&label);
675 msmFreePointer((void**)&to_label);
676 msmFreePointer((void**)&type);
680 rpmlog(RPMLOG_ERR, "Not allowed element in domain permit section: %s\n", ASCII(node));
683 if (ret < 0) return ret;
689 static int msmProcessDProvide(xmlTextReaderPtr reader, define_x *define)
691 const xmlChar *node, *label;
694 rpmlog(RPMLOG_DEBUG, "provide\n");
697 rpmlog(RPMLOG_ERR, "An attempt to define a domain without a name. Abort.\n");
701 depth = xmlTextReaderDepth(reader);
702 while ((ret = msmNextChildElement(reader, depth))) {
703 node = xmlTextReaderConstName(reader);
704 if (!node) return -1;
705 if (!strcmp(ASCII(node), "label")) {
706 label = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
707 rpmlog(RPMLOG_DEBUG, "label %s \n", ASCII(label));
710 if (msmVerifySmackLabel(ASCII(label)) < 0) {
711 msmFreePointer((void**)&label);
714 if (msmVerifyLabelPrefix(ASCII(label), define->name) < 0) {
715 msmFreePointer((void**)&label);
718 d_provide_x *provide = calloc(1, sizeof(d_provide_x));
720 provide->label_name = ASCII(label);
721 LISTADD(define->d_provides, provide);
723 msmFreePointer((void**)&label);
727 rpmlog(RPMLOG_INFO, "Label name is empty. Label provide is ignored\n");
731 rpmlog(RPMLOG_ERR, "Not allowed element in domain provide section: %s\n", ASCII(node));
734 if (ret < 0) return ret;
740 static int msmProcessDefine(xmlTextReaderPtr reader, define_x *define, manifest_x *mfx, sw_source_x *current)
742 const xmlChar *node, *name, *policy, *plist;
743 int ret, depth, domainPresent = 0;
745 rpmlog(RPMLOG_DEBUG, "define\n");
747 depth = xmlTextReaderDepth(reader);
749 while ((ret = msmNextChildElement(reader, depth))) {
750 node = xmlTextReaderConstName(reader);
751 if (!node) return -1;
752 if (!strcmp(ASCII(node), "domain")) {
754 rpmlog(RPMLOG_ERR, "Only one domain is allowed per define section. Abort installation\n");
758 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
759 policy = xmlTextReaderGetAttribute(reader, XMLCHAR("policy"));
760 plist = xmlTextReaderGetAttribute(reader, XMLCHAR("plist"));
761 rpmlog(RPMLOG_DEBUG, "domain %s policy %s plist %s\n",
762 ASCII(name), ASCII(policy), ASCII(plist));
765 if (msmVerifySmackLabel(ASCII(name)) < 0) {
766 msmFreePointer((void**)&name);
767 msmFreePointer((void**)&policy);
768 msmFreePointer((void**)&plist);
772 define->name = ASCII(name);
773 define->policy = ASCII(policy);
774 define->plist = ASCII(plist);
775 // store defined ac domain name
776 ac_domain_x *ac_domain = calloc(1, sizeof(ac_domain_x));
779 ac_domain->name = strdup(define->name);
781 ac_domain->match = strdup("trusted"); // hardcode trusted policy for ac domain definition
782 if (define->policy) {
783 ac_domain->type = strdup(define->policy);
786 ac_domain->plist = strdup(define->plist);
788 ac_domain->sw_source = current;
789 ac_domain->pkg_name = mfx->name;
791 provide_x *provide = calloc(1, sizeof(provide_x));
793 LISTADD(mfx->provides, provide);
796 msmFreeACDomain(ac_domain);
801 LISTADD(mfx->provides->ac_domains, ac_domain);
804 rpmlog(RPMLOG_ERR, "Domain name must be defined. Abort installation\n");
805 msmFreePointer((void**)&policy);
806 msmFreePointer((void**)&plist);
809 } else if (!strcmp(ASCII(node), "request")) {
810 int res = msmProcessDRequest(reader, define);
811 if (res < 0) return res;
812 } else if (!strcmp(ASCII(node), "permit")) {
813 int res = msmProcessDPermit(reader, define);
814 if (res < 0) return res;
815 } else if (!strcmp(ASCII(node), "provide")) {
816 int res = msmProcessDProvide(reader, define);
817 if (res < 0) return res;
819 rpmlog(RPMLOG_ERR, "Not allowed element in domain define section: %s\n", ASCII(node));
822 if (ret < 0) return ret;
827 int msmFindSWSourceByKey(sw_source_x *sw_source, void *param)
831 keyinfo_x *current_keyinfo = (keyinfo_x*)param;
833 for (origin = sw_source->origins; origin; origin = origin->prev) {
834 for (keyinfo = origin->keyinfos; keyinfo; keyinfo = keyinfo->prev) {
835 if (strncmp((const char*)current_keyinfo->keydata, (const char*)keyinfo->keydata,
836 strlen((const char*)current_keyinfo->keydata)) == 0
837 && (current_keyinfo->keylen == keyinfo->keylen))
844 int msmFindSWSourceByName(sw_source_x *sw_source, void *param)
846 const char *name = (const char *)param;
847 return strcmp(sw_source->name, name);
850 int msmFindSWSourceBySignature(sw_source_x *sw_source, void *param, void* param2)
854 pgpDigParams sig = (pgpDigParams)param;
855 DIGEST_CTX ctx = (DIGEST_CTX)param2;
856 pgpDigParams key = NULL;
858 for (origin = sw_source->origins; origin; origin = origin->prev) {
859 for (keyinfo = origin->keyinfos; keyinfo; keyinfo = keyinfo->prev) {
860 if (pgpPrtParams(keyinfo->keydata, keyinfo->keylen, PGPTAG_PUBLIC_KEY, &key)) {
861 rpmlog(RPMLOG_ERR, "invalid sw source key\n");
864 if (pgpVerifySignature(key, sig, ctx) == RPMRC_OK) {
872 static int msmProcessKeyinfo(xmlTextReaderPtr reader, origin_x *origin, sw_source_x *parent)
874 const xmlChar *keydata;
878 depth = xmlTextReaderDepth(reader);
879 while ((ret = msmNextChildElement(reader, depth))) {
880 keydata = xmlTextReaderConstValue(reader);
881 rpmlog(RPMLOG_DEBUG, "keyinfo %.40s...\n", ASCII(keydata));
882 if (!keydata) return -1;
883 keyinfo = calloc(1, sizeof(keyinfo_x));
885 if ((ret = rpmBase64Decode(ASCII(keydata), (void **)&keyinfo->keydata, &keyinfo->keylen))) {
886 rpmlog(RPMLOG_ERR, "Failed to decode keyinfo %s, %d\n", keydata, ret);
890 // check that keys aren't matching
891 sw_source_x *old = msmSWSourceTreeTraversal(parent, msmFindSWSourceByKey, (void *)keyinfo, NULL);
893 rpmlog(RPMLOG_ERR, "SW source with this key has already been installed\n");
897 LISTADD(origin->keyinfos, keyinfo);
900 if (ret < 0) return ret;
905 static access_x *msmProcessAccess(xmlTextReaderPtr reader, origin_x *origin)
907 const xmlChar *data, *type;
909 data = xmlTextReaderGetAttribute(reader, XMLCHAR("data"));
910 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
911 rpmlog(RPMLOG_DEBUG, "access %s %s\n", ASCII(data), ASCII(type));
914 access_x *access = calloc(1, sizeof(access_x));
916 access->data = ASCII(data);
917 access->type = ASCII(type);
921 msmFreePointer((void**)&data);
922 msmFreePointer((void**)&type);
926 static int msmProcessOrigin(xmlTextReaderPtr reader, origin_x *origin, sw_source_x *parent)
928 const xmlChar *node, *type;
931 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
932 rpmlog(RPMLOG_DEBUG, "origin %s\n", ASCII(type));
933 origin->type = ASCII(type);
935 depth = xmlTextReaderDepth(reader);
936 while ((ret = msmNextChildElement(reader, depth))) {
937 node = xmlTextReaderConstName(reader);
938 if (!node) return -1;
939 if (!strcmp(ASCII(node), "keyinfo")) {
940 ret = msmProcessKeyinfo(reader, origin, parent);
941 } else if (!strcmp(ASCII(node), "access")) {
942 access_x *access = msmProcessAccess(reader, origin);
944 LISTADD(origin->accesses, access);
948 if (ret < 0) return ret;
953 static int msmProcessDeny(xmlTextReaderPtr reader, sw_source_x *sw_source)
958 rpmlog(RPMLOG_DEBUG, "deny\n");
960 depth = xmlTextReaderDepth(reader);
961 while ((ret = msmNextChildElement(reader, depth))) {
962 node = xmlTextReaderConstName(reader);
963 if (!node) return -1;
964 if (!strcmp(ASCII(node), "ac_domain")) {
965 ac_domain_x *ac_domain = msmProcessACDomain(reader, sw_source, NULL);
967 if (ac_domain->name) {
968 HASH_ADD_KEYPTR(hh, sw_source->denys, ac_domain->name,
969 strlen(ac_domain->name), ac_domain);
971 LISTADD(sw_source->denymatches, ac_domain);
975 if (ret < 0) return ret;
980 static int msmProcessAllow(xmlTextReaderPtr reader, sw_source_x *sw_source)
985 rpmlog(RPMLOG_DEBUG, "allow\n");
987 depth = xmlTextReaderDepth(reader);
988 while ((ret = msmNextChildElement(reader, depth))) {
989 node = xmlTextReaderConstName(reader);
990 if (!node) return -1;
991 if (!strcmp(ASCII(node), "deny")) {
992 ret = msmProcessDeny(reader, sw_source);
993 } else if (!strcmp(ASCII(node), "ac_domain")) {
994 ac_domain_x *ac_domain = msmProcessACDomain(reader, sw_source, NULL);
996 if (ac_domain->name) {
997 HASH_ADD_KEYPTR(hh, sw_source->allows, ac_domain->name,
998 strlen(ac_domain->name), ac_domain);
1000 LISTADD(sw_source->allowmatches, ac_domain);
1004 if (ret < 0) return ret;
1009 static int msmProcessSWSource(xmlTextReaderPtr reader, sw_source_x *sw_source, const char *parentkey, manifest_x *mfx)
1011 const xmlChar *name, *node, *rank, *rankkey;
1012 sw_source_x *current;
1013 int ret, depth, len;
1016 /* config processing */
1017 current = sw_source;
1019 name = xmlTextReaderGetAttribute(reader, XMLCHAR("name"));
1020 rank = xmlTextReaderGetAttribute(reader, XMLCHAR("rank"));
1021 rankkey = xmlTextReaderGetAttribute(reader, XMLCHAR("rankkey"));
1022 rpmlog(RPMLOG_DEBUG, "sw source %s rank %s key %s\n",
1023 ASCII(name), ASCII(rank), ASCII(rankkey));
1025 sw_source->name = ASCII(name);
1028 /* config processing */
1029 sw_source->rankkey = ASCII(rankkey);
1032 rankval = atoi(ASCII(rank));
1033 msmFreePointer((void**)&rank); /* rankkey is used from now on */
1036 if (!sw_source->name) return -1; /* sw source must have name */
1037 if (!mfx && rankkey) return -1; /* manifest cannot set rankkey itself */
1040 sw_source_x *old = msmSWSourceTreeTraversal(sw_source->parent, msmFindSWSourceByName, (void *)sw_source->name, NULL);
1041 if (old && old->parent != sw_source->parent) {
1042 if (!old->parent && old == sw_source->parent) {
1043 /* root sw source upgrade (it's signed by root) */
1046 rpmlog(RPMLOG_ERR, "SW source called %s has already been installed\n",
1048 return -1; /* sw_source names are unique (allow upgrade though) */
1051 /* rank algorithm is copied from harmattan dpkg wrapper */
1052 if (rankval > RANK_LIMIT) rankval = RANK_LIMIT;
1053 if (rankval < -RANK_LIMIT) rankval = -RANK_LIMIT;
1054 rankval += RANK_LIMIT;
1056 len = strlen(parentkey) + 1 + 5 + 1 + 5 + 1 + strlen(sw_source->name) + 1;
1057 if (!(sw_source->rankkey = malloc(len))) return -1;
1058 sprintf((char *)sw_source->rankkey, "%s/%05d/%05d.%s",
1059 parentkey, rankval, RANK_LIMIT, sw_source->name);
1062 depth = xmlTextReaderDepth(reader);
1063 while ((ret = msmNextChildElement(reader, depth))) {
1064 node = xmlTextReaderConstName(reader);
1065 if (!node) return -1;
1066 if (!strcmp(ASCII(node), "allow")) {
1067 ret = msmProcessAllow(reader, sw_source);
1068 } else if (!strcmp(ASCII(node), "deny")) {
1069 ret = msmProcessDeny(reader, sw_source);
1070 } else if (!strcmp(ASCII(node), "origin")) {
1071 origin_x *origin = calloc(1, sizeof(origin_x));
1073 LISTADD(sw_source->origins, origin);
1074 ret = msmProcessOrigin(reader, origin, sw_source->parent);
1076 } else if (!strcmp(ASCII(node), "package")) {
1077 /* config processing */
1078 if (!mfx) return -1;
1079 package_x *package = calloc(1, sizeof(package_x));
1081 LISTADD(sw_source->packages, package);
1082 ret = msmProcessPackage(reader, package, current);
1084 } else if (!strcmp(ASCII(node), "sw_source")) {
1085 /* config processing */
1086 if (!mfx) return -1;
1087 sw_source_x *sw_source = calloc(1, sizeof(sw_source_x));
1089 sw_source->parent = current;
1090 LISTADD(mfx->sw_sources, sw_source);
1092 ret = msmProcessSWSource(reader, sw_source, "", mfx);
1095 if (ret < 0) return ret;
1100 static int msmProcessAttributes(xmlTextReaderPtr reader, manifest_x *mfx)
1102 const xmlChar *node, *type;
1103 int ret, depth, attributePresent = 0;
1105 rpmlog(RPMLOG_DEBUG, "attributes\n");
1106 depth = xmlTextReaderDepth(reader);
1108 while ((ret = msmNextChildElement(reader, depth))) {
1109 node = xmlTextReaderConstName(reader);
1110 if (!node) return -1;
1111 if (!strcmp(ASCII(node), "package")) {
1112 if (attributePresent) {
1113 rpmlog(RPMLOG_ERR, "Only one attribute is currently allowed per attribute section. Abort installation\n");
1116 attributePresent = 1;
1117 type = xmlTextReaderGetAttribute(reader, XMLCHAR("type"));
1118 rpmlog(RPMLOG_DEBUG, "package type is %s\n", ASCII(type));
1121 if ((strcmp(type, "system") != 0) &&
1122 (strcmp(type, "application") != 0)){
1123 rpmlog(RPMLOG_ERR, "Not allowed attribute name in a package type specification. Abort installation.\n");
1124 msmFreePointer((void**)&type);
1127 mfx->package_type = ASCII(type);
1129 rpmlog(RPMLOG_ERR, "Type name must be defined. Abort installation\n");
1133 rpmlog(RPMLOG_ERR, "Not allowed element in attribute section: %s\n", ASCII(node));
1136 if (ret < 0) return ret;
1141 static int msmProcessMsm(xmlTextReaderPtr reader, manifest_x *mfx, sw_source_x *current)
1143 const xmlChar *node;
1145 int assignPresent = 0, requestPresent = 0, attributesPresent = 0; /* there must be only one section per manifest */
1146 mfx->sw_source = current;
1148 rpmlog(RPMLOG_DEBUG, "manifest\n");
1150 depth = xmlTextReaderDepth(reader);
1151 while ((ret = msmNextChildElement(reader, depth))) {
1152 node = xmlTextReaderConstName(reader);
1153 if (!node) return -1;
1154 if (!strcmp(ASCII(node), "assign")) {
1155 if (assignPresent) {
1156 rpmlog(RPMLOG_ERR, "A second assign section in manifest isn't allowed. Abort installation.\n");
1160 provide_x *provide = calloc(1, sizeof(provide_x));
1162 LISTADD(mfx->provides, provide);
1163 ret = msmProcessProvide(reader, provide, current, mfx, NULL);
1165 } else if (!strcmp(ASCII(node), "attributes")) {
1166 if (attributesPresent) {
1167 rpmlog(RPMLOG_ERR, "A second attribute section in manifest isn't allowed. Abort installation.\n");
1170 attributesPresent = 1;
1171 ret = msmProcessAttributes(reader, mfx);
1172 } else if (!strcmp(ASCII(node), "define")) {
1173 define_x *define = calloc(1, sizeof(define_x));
1175 LISTADD(mfx->defines, define);
1176 ret = msmProcessDefine(reader, define, mfx, current);
1178 } else if (!strcmp(ASCII(node), "request")) {
1179 if (requestPresent) {
1180 rpmlog(RPMLOG_ERR, "A second request section in manifest isn't allowed. Abort installation.\n");
1184 mfx->request = calloc(1, sizeof(request_x));
1186 ret = msmProcessRequest(reader, mfx->request);
1188 } else if (!strcmp(ASCII(node), "sw_source")) {
1189 sw_source_x *sw_source = calloc(1, sizeof(sw_source_x));
1191 char parentkey[256] = { 0 };
1192 sw_source->parent = current;
1193 if (sw_source->parent) {
1194 snprintf(parentkey, sizeof(parentkey),
1195 "%s", sw_source->parent->rankkey);
1196 char *sep = strrchr(parentkey, '/');
1197 if (sep) *sep = '\0';
1199 LISTADD(mfx->sw_sources, sw_source);
1200 ret = msmProcessSWSource(reader, sw_source, parentkey, NULL);
1203 if (ret < 0) return ret;
1208 static int msmProcessConfig(xmlTextReaderPtr reader, manifest_x *mfx)
1210 const xmlChar *node;
1213 rpmlog(RPMLOG_DEBUG, "config\n");
1215 depth = xmlTextReaderDepth(reader);
1216 if ((ret = msmNextChildElement(reader, depth))) {
1217 node = xmlTextReaderConstName(reader);
1218 if (!node) return -1;
1219 if (!strcmp(ASCII(node), "sw_source")) {
1220 mfx->sw_sources = calloc(1, sizeof(sw_source_x));
1221 if (!mfx->sw_sources) return -1;
1222 ret = msmProcessSWSource(reader, mfx->sw_sources, "", mfx);
1228 static int msmProcessManifest(xmlTextReaderPtr reader, manifest_x *mfx, sw_source_x *current)
1230 const xmlChar *node;
1233 if ((ret = msmNextChildElement(reader, -1))) {
1234 node = xmlTextReaderConstName(reader);
1235 if (!node) return -1;
1236 if (!strcmp(ASCII(node), "manifest")) {
1237 ret = msmProcessMsm(reader, mfx, current);
1238 } else if (!strcmp(ASCII(node), "config")) {
1239 ret = msmProcessConfig(reader, mfx);
1245 static filesystem_x *msmFreeFilesystem(filesystem_x *filesystem)
1248 filesystem_x *prev = filesystem->prev;
1249 msmFreePointer((void**)&filesystem->path);
1250 msmFreePointer((void**)&filesystem->label);
1251 msmFreePointer((void**)&filesystem->exec_label);
1252 msmFreePointer((void**)&filesystem->type);
1253 msmFreePointer((void**)&filesystem);
1259 static member_x *msmFreeMember(member_x *member)
1262 member_x *prev = member->prev;
1263 msmFreePointer((void**)&member->name);
1264 if (member->annotation) {
1265 msmFreePointer((void**)&member->annotation->name);
1266 msmFreePointer((void**)&member->annotation->value);
1267 msmFreePointer((void**)&member->annotation);
1269 msmFreePointer((void**)&member);
1275 static interface_x *msmFreeInterface(interface_x *interface)
1280 interface_x *prev = interface->prev;
1281 msmFreePointer((void**)&interface->name);
1282 if (interface->annotation) {
1283 msmFreePointer((void**)&interface->annotation->name);
1284 msmFreePointer((void**)&interface->annotation->value);
1285 msmFreePointer((void**)&interface->annotation);
1287 for (member = interface->members; member; member = msmFreeMember(member));
1288 msmFreePointer((void**)&interface);
1294 static node_x *msmFreeNode(node_x *node)
1297 interface_x *interface;
1300 node_x *prev = node->prev;
1301 msmFreePointer((void**)&node->name);
1302 if (node->annotation) {
1303 msmFreePointer((void**)&node->annotation->name);
1304 msmFreePointer((void**)&node->annotation->value);
1305 msmFreePointer((void**)&node->annotation);
1307 for (member = node->members; member; member = msmFreeMember(member));
1308 for (interface = node->interfaces; interface; interface = msmFreeInterface(interface));
1309 msmFreePointer((void**)&node);
1315 static dbus_x *msmFreeDBus(dbus_x *dbus)
1320 dbus_x *prev = dbus->prev;
1321 msmFreePointer((void**)&dbus->name);
1322 msmFreePointer((void**)&dbus->own);
1323 msmFreePointer((void**)&dbus->bus);
1324 if (dbus->annotation) {
1325 msmFreePointer((void**)&dbus->annotation->name);
1326 msmFreePointer((void**)&dbus->annotation->value);
1327 msmFreePointer((void**)&dbus->annotation);
1329 for (node = dbus->nodes; node; node = msmFreeNode(node));
1330 msmFreePointer((void**)&dbus);
1335 static provide_x *msmFreeProvide(provide_x *provide)
1337 ac_domain_x *ac_domain;
1338 filesystem_x *filesystem;
1339 provide_x *prev = provide->prev;
1343 for (ac_domain = provide->ac_domains; ac_domain; ac_domain = msmFreeACDomain(ac_domain));
1344 if (provide->filesystems)
1345 for (filesystem = provide->filesystems; filesystem; filesystem = msmFreeFilesystem(filesystem));
1346 msmFreePointer((void**)&provide->name);
1347 msmFreePointer((void**)&provide->origin);
1348 for (dbus = provide->dbuss; dbus; dbus = msmFreeDBus(dbus));
1349 msmFreePointer((void**)&provide);
1354 static file_x *msmFreeFile(file_x *file)
1356 file_x *prev = file->prev;
1357 msmFreePointer((void**)&file->path);
1358 msmFreePointer((void**)&file);
1362 package_x *msmFreePackage(package_x *package)
1365 package_x *prev = package->prev;
1366 for (provide = package->provides; provide; provide = msmFreeProvide(provide));
1367 msmFreePointer((void**)&package->name);
1368 msmFreePointer((void**)&package->modified);
1369 msmFreePointer((void**)&package);
1373 static keyinfo_x *msmFreeKeyinfo(keyinfo_x *keyinfo)
1375 keyinfo_x *prev = keyinfo->prev;
1376 msmFreePointer((void**)&keyinfo->keydata);
1377 msmFreePointer((void**)&keyinfo);
1381 static access_x *msmFreeAccess(access_x *access)
1383 access_x *prev = access->prev;
1384 msmFreePointer((void**)&access->data);
1385 msmFreePointer((void**)&access->type);
1386 msmFreePointer((void**)&access);
1390 static origin_x *msmFreeOrigin(origin_x *origin)
1394 origin_x *prev = origin->prev;
1395 for (keyinfo = origin->keyinfos; keyinfo; keyinfo = msmFreeKeyinfo(keyinfo));
1396 for (access = origin->accesses; access; access = msmFreeAccess(access));
1397 msmFreePointer((void**)&origin->type);
1398 msmFreePointer((void**)&origin);
1402 static sw_source_x *msmFreeSWSource(sw_source_x *sw_source)
1405 ac_domain_x *ac_domain, *temp;
1407 sw_source_x *next = sw_source->next;
1409 rpmlog(RPMLOG_DEBUG, "freeing sw source %s\n", sw_source->name);
1411 for (package = sw_source->packages; package; package = msmFreePackage(package));
1412 for (ac_domain = sw_source->allowmatches; ac_domain; ac_domain = msmFreeACDomain(ac_domain));
1413 if (sw_source->allows) {
1414 HASH_ITER(hh, sw_source->allows, ac_domain, temp) {
1415 HASH_DELETE(hh, sw_source->allows, ac_domain);
1416 msmFreeACDomain(ac_domain);
1420 for (ac_domain = sw_source->denymatches; ac_domain; ac_domain = msmFreeACDomain(ac_domain));
1421 if (sw_source->denys) {
1422 HASH_ITER(hh, sw_source->denys, ac_domain, temp) {
1423 HASH_DELETE(hh, sw_source->denys, ac_domain);
1424 msmFreeACDomain(ac_domain);
1427 for (origin = sw_source->origins; origin; origin = msmFreeOrigin(origin));
1428 msmFreePointer((void**)&sw_source->name);
1429 msmFreePointer((void**)&sw_source->rankkey);
1430 msmFreePointer((void**)&sw_source);
1434 static d_request_x *msmFreeDRequest(d_request_x *d_request)
1436 d_request_x *next = d_request->next;
1437 rpmlog(RPMLOG_DEBUG, "freeing domain request %s\n", d_request->label_name);
1438 msmFreePointer((void**)&d_request->label_name);
1439 msmFreePointer((void**)&d_request->ac_type);
1440 msmFreePointer((void**)&d_request);
1444 static d_permit_x *msmFreeDPermit(d_permit_x *d_permit)
1446 d_permit_x *next = d_permit->next;
1447 rpmlog(RPMLOG_DEBUG, "freeing domain permit %s\n", d_permit->label_name);
1448 msmFreePointer((void**)&d_permit->label_name);
1449 msmFreePointer((void**)&d_permit->to_label_name);
1450 msmFreePointer((void**)&d_permit->ac_type);
1451 msmFreePointer((void**)&d_permit);
1455 static d_provide_x *msmFreeDProvide(d_provide_x *d_provide)
1457 d_provide_x *next = d_provide->next;
1458 rpmlog(RPMLOG_DEBUG, "freeing domain provide %s\n", d_provide->label_name);
1459 msmFreePointer((void**)&d_provide->label_name);
1460 msmFreePointer((void**)&d_provide);
1464 static define_x *msmFreeDefine(define_x *define)
1466 define_x *next = define->next;
1467 d_request_x *d_request;
1468 d_permit_x *d_permit;
1469 d_provide_x *d_provide;
1471 msmFreePointer((void**)&define->name);
1472 msmFreePointer((void**)&define->policy);
1473 msmFreePointer((void**)&define->plist);
1475 if (define->d_requests) {
1476 LISTHEAD(define->d_requests, d_request);
1477 for (; d_request; d_request = msmFreeDRequest(d_request));
1479 rpmlog(RPMLOG_DEBUG, "after freeing define requests\n");
1480 if (define->d_permits) {
1481 LISTHEAD(define->d_permits, d_permit);
1482 for (; d_permit; d_permit = msmFreeDPermit(d_permit));
1484 rpmlog(RPMLOG_DEBUG, "after freeing define permits\n");
1485 if (define->d_provides) {
1486 LISTHEAD(define->d_provides, d_provide);
1487 for (; d_provide; d_provide = msmFreeDProvide(d_provide));
1489 rpmlog(RPMLOG_DEBUG, "after freeing provides\n");
1490 msmFreePointer((void**)&define);
1494 manifest_x* msmFreeManifestXml(manifest_x* mfx)
1498 sw_source_x *sw_source;
1501 rpmlog(RPMLOG_DEBUG, "in msmFreeManifestXml\n");
1504 for (provide = mfx->provides; provide; provide = msmFreeProvide(provide));
1505 rpmlog(RPMLOG_DEBUG, "after freeing provides\n");
1507 msmFreePointer((void**)&mfx->request->ac_domain);
1508 msmFreePointer((void**)&mfx->request);
1510 rpmlog(RPMLOG_DEBUG, "after freeing requests\n");
1511 for (file = mfx->files; file; file = msmFreeFile(file));
1512 rpmlog(RPMLOG_DEBUG, "after freeing files\n");
1513 if (mfx->sw_sources) {
1514 LISTHEAD(mfx->sw_sources, sw_source);
1515 for (; sw_source; sw_source = msmFreeSWSource(sw_source));
1517 msmFreePointer((void**)&mfx->name);
1518 rpmlog(RPMLOG_DEBUG, "after freeing name\n");
1520 LISTHEAD(mfx->defines, define);
1521 for (; define; define = msmFreeDefine(define));
1523 rpmlog(RPMLOG_DEBUG, "after freeing defines \n");
1524 msmFreePointer((void**)&mfx);
1529 manifest_x *msmProcessManifestXml(const char *buffer, int size, sw_source_x *current, const char *packagename)
1531 xmlTextReaderPtr reader;
1532 manifest_x *mfx = NULL;
1534 reader = xmlReaderForMemory(buffer, size, NULL, NULL, 0);
1536 mfx = calloc(1, sizeof(manifest_x));
1538 mfx->name = strdup(packagename);
1539 if (msmProcessManifest(reader, mfx, current) < 0) {
1540 /* error in parcing. Let's display some hint where we failed */
1541 rpmlog(RPMLOG_DEBUG, "Syntax error in processing manifest in the above line\n");
1542 mfx = msmFreeManifestXml(mfx);
1545 xmlFreeTextReader(reader);
1547 rpmlog(RPMLOG_ERR, "Unable to create xml reader\n");
1552 manifest_x *msmProcessDevSecPolicyXml(const char *filename)
1554 xmlTextReaderPtr reader;
1555 manifest_x *mfx = NULL;
1557 reader = xmlReaderForFile(filename, NULL, 0);
1559 mfx = calloc(1, sizeof(manifest_x));
1561 if (msmProcessManifest(reader, mfx, NULL) < 0) {
1562 mfx = msmFreeManifestXml(mfx);
1565 xmlFreeTextReader(reader);
1567 rpmlog(RPMLOG_ERR, "Unable to open device security policy %s\n", filename);