4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7 * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
28 #include <sys/types.h>
38 #include <ctype.h> /* for isspace () */
39 #include <wctype.h> /* for towlower() */
41 #include <cert-service.h>
42 #include <libxml/parser.h>
43 #include <libxml/tree.h>
44 #include <libxml/xmlmemory.h>
47 #include <sys/xattr.h>
49 #ifndef XMLSEC_NO_XSLT
50 #include <libxslt/xslt.h>
51 #include <libxslt/security.h>
54 #include <xmlsec/xmlsec.h>
55 #include <xmlsec/xmltree.h>
56 #include <xmlsec/xmldsig.h>
57 #include <xmlsec/crypto.h>
58 #include <xmlsec/errors.h>
59 #include <pkgmgr-info.h>
60 #include <pkgmgr_parser.h>
61 #include <package-manager.h>
62 #include <privilege-control.h>
63 #include <app_manager.h>
64 #include <app_manager_extension.h>
67 #define APP2EXT_ENABLE
69 #include <app2ext_interface.h>
72 #include "rpm-installer-signature.h"
73 #include "rpm-installer.h"
74 #include "rpm-frontend.h"
75 #include "installer-type.h"
76 #include "installer-util.h"
77 #include "coretpk-installer-internal.h"
78 #include "pkgmgr_parser_resource.h"
80 extern char *gpkgname;
81 extern int sig_enable;
85 static void __rpm_process_line(char *line);
86 static void __rpm_perform_read(int fd);
87 static int __ri_xmlsec_verify_signature(const char *sigxmlfile, char *rootca);
88 static xmlSecKeysMngrPtr __ri_load_trusted_certs(char *files, int files_size);
89 static int __ri_verify_file(xmlSecKeysMngrPtr mngr, const char *sigxmlfile);
90 static int __ri_create_cert_chain(int sigtype, int sigsubtype, char *value);
91 static void __ri_free_cert_chain(void);
92 static char *__ri_get_cert_from_file(const char *file);
93 static int __privilege_func(const char *name, void *user_data);
94 static void __ri_xmlsec_debug_print(const char *file, int line, const char *func, const char *errorObject, const char *errorSubject, int reason, const char *msg);
96 int _ri_set_group_id(const char *pkgid, const char *groupid);
98 static void __str_trim(char *input)
100 char *trim_str = input;
105 while (*input != 0) {
106 if (!isspace(*input)) {
117 static int __ri_get_op_type(char *op_str)
119 if (strcmp(op_str, "install") == 0)
121 else if (strcmp(op_str, "update") == 0)
123 else if (strcmp(op_str, "uninstall") == 0)
124 return UNINSTALL_REQ;
129 int __get_version_from_xml(char* manifest, char** version){
131 const char *val = NULL;
133 xmlTextReaderPtr reader;
134 int ret = PMINFO_R_OK;
136 if(manifest == NULL) {
137 _LOGE("Input argument is NULL\n");
138 return PMINFO_R_ERROR;
141 if(version == NULL) {
142 _LOGE("Argument supplied to hold return value is NULL\n");
143 return PMINFO_R_ERROR;
146 reader = xmlReaderForFile(manifest, NULL, 0);
149 if ( _child_element(reader, -1)) {
150 node = xmlTextReaderConstName(reader);
152 _LOGE("xmlTextReaderConstName value is NULL\n");
153 ret = PMINFO_R_ERROR;
157 if (!strcmp(ASCII(node), "manifest")) {
158 ret = _ri_get_attribute(reader, "version", &val);
160 _LOGE("@Error in getting attribute value");
161 ret = PMINFO_R_ERROR;
166 *version = strdup(val);
167 if(*version == NULL){
168 _LOGE("Malloc Failed!!");
169 ret = PMINFO_R_ERROR;
174 _LOGE("Unable to create xml reader\n");
175 ret = PMINFO_R_ERROR;
179 _LOGE("xmlReaderForFile value is NULL\n");
180 return PMINFO_R_ERROR;
184 xmlFreeTextReader(reader);
192 static int __ri_init_csc_xml(char *xml_path, char *removable)
195 char *csc_tags[3] = { NULL, };
197 if (strcmp(removable, "true") == 0)
198 csc_tags[0] = "removable=true";
200 csc_tags[0] = "removable=false";
202 csc_tags[1] = "preload=true";
205 ret = pkgmgr_parser_parse_manifest_for_installation(xml_path, csc_tags);
210 static int __ri_create_cert_chain(int sigtype, int sigsubtype, char *value)
214 /* _LOGD("Push in list [%d] [%d] [%s]", sigtype, sigsubtype, value); */
217 switch (sigsubtype) {
219 list[PMINFO_SET_AUTHOR_SIGNER_CERT].cert_type = PMINFO_SET_AUTHOR_SIGNER_CERT;
220 list[PMINFO_SET_AUTHOR_SIGNER_CERT].cert_value = strdup(value);
222 case SIG_INTERMEDIATE:
223 list[PMINFO_SET_AUTHOR_INTERMEDIATE_CERT].cert_type = PMINFO_SET_AUTHOR_INTERMEDIATE_CERT;
224 list[PMINFO_SET_AUTHOR_INTERMEDIATE_CERT].cert_value = strdup(value);
227 /* value is already a mallocd pointer */
228 list[PMINFO_SET_AUTHOR_ROOT_CERT].cert_type = PMINFO_SET_AUTHOR_ROOT_CERT;
229 list[PMINFO_SET_AUTHOR_ROOT_CERT].cert_value = value;
236 switch (sigsubtype) {
238 list[PMINFO_SET_DISTRIBUTOR_SIGNER_CERT].cert_type = PMINFO_SET_DISTRIBUTOR_SIGNER_CERT;
239 list[PMINFO_SET_DISTRIBUTOR_SIGNER_CERT].cert_value = strdup(value);
241 case SIG_INTERMEDIATE:
242 list[PMINFO_SET_DISTRIBUTOR_INTERMEDIATE_CERT].cert_type = PMINFO_SET_DISTRIBUTOR_INTERMEDIATE_CERT;
243 list[PMINFO_SET_DISTRIBUTOR_INTERMEDIATE_CERT].cert_value = strdup(value);
246 /* value is already a mallocd pointer */
247 list[PMINFO_SET_DISTRIBUTOR_ROOT_CERT].cert_type = PMINFO_SET_DISTRIBUTOR_ROOT_CERT;
248 list[PMINFO_SET_DISTRIBUTOR_ROOT_CERT].cert_value = value;
255 switch (sigsubtype) {
257 list[PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT].cert_type = PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT;
258 list[PMINFO_SET_DISTRIBUTOR2_SIGNER_CERT].cert_value = strdup(value);
260 case SIG_INTERMEDIATE:
261 list[PMINFO_SET_DISTRIBUTOR2_INTERMEDIATE_CERT].cert_type = PMINFO_SET_DISTRIBUTOR2_INTERMEDIATE_CERT;
262 list[PMINFO_SET_DISTRIBUTOR2_INTERMEDIATE_CERT].cert_value = strdup(value);
265 /* value is already a mallocd pointer */
266 list[PMINFO_SET_DISTRIBUTOR2_ROOT_CERT].cert_type = PMINFO_SET_DISTRIBUTOR2_ROOT_CERT;
267 list[PMINFO_SET_DISTRIBUTOR2_ROOT_CERT].cert_value = value;
280 static void __ri_free_cert_chain()
283 for (i = 0; i < MAX_CERT_NUM; i++) {
284 if (list[i].cert_value) {
285 free(list[i].cert_value);
286 list[i].cert_value = NULL;
291 static void __ri_xmlsec_debug_print(const char *file, int line, const char *func, const char *errorObject, const char *errorSubject, int reason, const char *msg)
293 char total[BUF_SIZE];
294 snprintf(total, sizeof(total), "[%s(%d)] : [%s] : [%s] : [%s]", func, line, errorObject, errorSubject, msg);
296 fprintf(stderr, "## [validate error]: %s\n", total);
303 static int __ri_verify_file(xmlSecKeysMngrPtr sec_key_mngr, const char *sigxmlfile)
305 xmlDocPtr doc = NULL;
306 xmlNodePtr node = NULL;
307 xmlSecDSigCtxPtr dsigCtx = NULL;
309 if (sigxmlfile == NULL)
311 if (sec_key_mngr == NULL)
314 /* set error callback to xmlsec1 */
315 xmlSecErrorsSetCallback(__ri_xmlsec_debug_print);
318 doc = xmlParseFile(sigxmlfile);
319 if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)) {
320 _LOGE("unable to parse file \"%s\"\n", sigxmlfile);
323 /* find start node */
324 node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
326 _LOGE("start node not found in \"%s\"\n", sigxmlfile);
329 /* create signature context */
330 dsigCtx = xmlSecDSigCtxCreate(sec_key_mngr);
331 if (dsigCtx == NULL) {
332 _LOGE("failed to create signature context\n");
335 /* Verify signature */
336 if (xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
337 _LOGE("failed to verify signature\n");
340 /* print verification result to stdout */
341 if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
343 _LOGD("valid signature");
346 _LOGD("invalid signature");
351 if (dsigCtx != NULL) {
352 xmlSecDSigCtxDestroy(dsigCtx);
360 static xmlSecKeysMngrPtr __ri_load_trusted_certs(char *files, int files_size)
362 xmlSecKeysMngrPtr sec_key_mngr;
369 sec_key_mngr = xmlSecKeysMngrCreate();
370 if (sec_key_mngr == NULL) {
371 _LOGE("failed to create keys manager.\n");
375 if (xmlSecCryptoAppDefaultKeysMngrInit(sec_key_mngr) < 0) {
376 _LOGE("failed to initialize keys manager.\n");
377 xmlSecKeysMngrDestroy(sec_key_mngr);
381 /* load trusted cert */
382 if (xmlSecCryptoAppKeysMngrCertLoad(sec_key_mngr, files, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
383 _LOGE("failed to load pem certificate from \"%s\"\n", files);
384 xmlSecKeysMngrDestroy(sec_key_mngr);
391 static int __ri_xmlsec_verify_signature(const char *sigxmlfile, char *rootca)
394 xmlSecKeysMngrPtr sec_key_mngr = NULL;
395 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
396 xmlSubstituteEntitiesDefault(1);
398 #ifndef XMLSEC_NO_XSLT
399 xmlIndentTreeOutput = 1;
400 xsltSecurityPrefsPtr sec_prefs = xsltNewSecurityPrefs();
401 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid);
402 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid);
403 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid);
404 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid);
405 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid);
406 xsltSetDefaultSecurityPrefs(sec_prefs);
411 _LOGE("xmlsec initialization failed [%d]\n", ret);
414 ret = xmlSecCheckVersion();
416 _LOGE("Incompatible version of loaded xmlsec library [%d]\n", ret);
419 #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
420 ret = xmlSecCryptoDLLoadLibrary(BAD_CAST "openssl");
422 _LOGE("unable to load openssl library [%d]\n", ret);
427 ret = xmlSecCryptoAppInit(NULL);
429 _LOGE("crypto initialization failed [%d]\n", ret);
432 ret = xmlSecCryptoInit();
434 _LOGE("xmlsec-crypto initialization failed [%d]\n", ret);
438 sec_key_mngr = __ri_load_trusted_certs(rootca, 1);
439 if (sec_key_mngr == NULL) {
440 _LOGE("loading of trusted certs failed\n");
445 if (__ri_verify_file(sec_key_mngr, sigxmlfile) < 0) {
451 xmlSecKeysMngrDestroy(sec_key_mngr);
453 xmlSecCryptoShutdown();
454 xmlSecCryptoAppShutdown();
456 #ifndef XMLSEC_NO_XSLT
457 xsltFreeSecurityPrefs(sec_prefs);
458 xsltCleanupGlobals();
464 int _rpm_installer_get_group_id(const char *pkgid, char **result)
467 const char *value = NULL;
468 char author_signature[BUF_SIZE] = { '\0' };
469 char *e_rootcert = NULL;
470 char *d_rootcert = NULL;
472 unsigned char hashout[BUF_SIZE] = { '\0' };
473 unsigned int h_size = 0;
476 pkgmgrinfo_certinfo_h handle = NULL;
478 snprintf(author_signature, BUF_SIZE, "%s/%s/%s", USR_APPS, pkgid, AUTHOR_SIGNATURE_XML);
479 if (access(author_signature, F_OK) != 0) {
480 _LOGE("[%s] isn't existed.", author_signature);
484 ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
486 _LOGE("pkgmgrinfo_pkginfo_create_certinfo(%s) failed.", pkgid);
490 ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, handle);
492 _LOGE("pkgmgrinfo_pkginfo_load_certinfo(%s) failed.", pkgid);
496 /* get root certificate */
497 ret = pkgmgrinfo_pkginfo_get_cert_value(handle, PMINFO_AUTHOR_SIGNER_CERT, &value);
498 if (ret < 0 || value == NULL) {
499 _LOGE("pkgmgrinfo_pkginfo_get_cert_value(%s) failed. [%d]", pkgid, ret);
504 d_rootcert = (char *)g_base64_decode(value, &d_size);
505 if (d_rootcert == NULL) {
506 _LOGE("g_base64_decode() failed.");
509 _LOGD("g_base64_decode() succeed, d_size=[%d]", d_size);
512 EVP_Digest(d_rootcert, d_size, hashout, &h_size, EVP_sha1(), NULL);
514 _LOGE("EVP_Digest(hash) failed.");
517 _LOGD("EVP_Digest() succeed, h_size=[%d]", h_size);
520 e_rootcert = g_base64_encode((const guchar *)hashout, h_size);
521 if (e_rootcert == NULL) {
522 _LOGE("g_base64_encode() failed.");
525 e_size = strlen(e_rootcert);
526 _LOGD("g_base64_encode() succeed, e_size=[%d]", e_size);
529 for (length = e_size; length >= 0; --length) {
530 if (e_rootcert[length] == '/') {
531 e_rootcert[length] = '#';
535 *result = e_rootcert;
544 pkgmgrinfo_pkginfo_destroy_certinfo(handle);
550 void __rpm_apply_smack(const char *pkgname, int flag, char *smack_label)
553 char dirpath[BUF_SIZE] = { '\0' };
554 char *groupid = NULL;
555 char *shared_data_label = NULL;
556 char buf[BUF_SIZE] = { 0, };
558 if (smack_label == NULL || strlen(smack_label) == 0) {
559 smack_label = (char *)pkgname;
562 /* execute privilege APIs. The APIs should not fail */
563 _ri_privilege_register_package(smack_label);
565 /* home dir. Dont setup path but change smack access to "_" */
566 snprintf(dirpath, BUF_SIZE, "%s/%s", USR_APPS, pkgname);
567 if (__is_dir(dirpath))
568 _ri_privilege_change_smack_label(dirpath, "_", 0); /* 0 is SMACK_LABEL_ACCESS */
569 memset(dirpath, '\0', BUF_SIZE);
570 snprintf(dirpath, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgname);
571 if (__is_dir(dirpath))
572 _ri_privilege_change_smack_label(dirpath, "_", 0); /* 0 is SMACK_LABEL_ACCESS */
575 memset(dirpath, '\0', BUF_SIZE);
576 snprintf(dirpath, BUF_SIZE, "%s/%s/data", OPT_USR_APPS, pkgname);
577 if (!__is_dir(dirpath)) {
578 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
580 _LOGE("directory making is failed.\n");
584 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
586 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
587 _LOGE("chown failed!! [%s]", buf);
590 _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_PRIVATE, smack_label);
593 memset(dirpath, '\0', BUF_SIZE);
594 snprintf(dirpath, BUF_SIZE, "%s/%s/cache", OPT_USR_APPS, pkgname);
595 if (!__is_dir(dirpath)) {
596 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
598 _LOGE("directory making is failed.\n");
601 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
603 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
604 _LOGE("chown failed!! [%s]", buf);
607 _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_PRIVATE, smack_label);
610 memset(dirpath, '\0', BUF_SIZE);
611 snprintf(dirpath, BUF_SIZE, "%s/%s/shared", USR_APPS, pkgname);
612 if (__is_dir(dirpath))
613 _ri_privilege_change_smack_label(dirpath, "_", 0); /* 0 is SMACK_LABEL_ACCESS */
614 memset(dirpath, '\0', BUF_SIZE);
615 snprintf(dirpath, BUF_SIZE, "%s/%s/shared", OPT_USR_APPS, pkgname);
616 if (!__is_dir(dirpath)) {
617 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
619 _LOGE("directory making is failed.\n");
621 _ri_privilege_change_smack_label(dirpath, "_", 0); /* 0 is SMACK_LABEL_ACCESS */
622 memset(dirpath, '\0', BUF_SIZE);
625 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/res", USR_APPS, pkgname);
626 if (__is_dir(dirpath))
627 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_ANY_LABEL, "_");
628 memset(dirpath, '\0', BUF_SIZE);
630 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/res", OPT_USR_APPS, pkgname);
631 if (__is_dir(dirpath))
632 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_ANY_LABEL, "_");
633 memset(dirpath, '\0', BUF_SIZE);
636 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/data", USR_APPS, pkgname);
637 if (__is_dir(dirpath)) {
638 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
640 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
641 _LOGE("chown failed!! [%s]", buf);
644 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_PUBLIC, NULL);
646 memset(dirpath, '\0', BUF_SIZE);
648 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/data", OPT_USR_APPS, pkgname);
649 if (__is_dir(dirpath)) {
650 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
652 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
653 _LOGE("chown failed!! [%s]", buf);
656 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_PUBLIC, NULL);
660 ret = _coretpk_installer_get_smack_label_access(dirpath, &shared_data_label);
662 _LOGE("_coretpk_installer_apply_directory_policy() failed, appdir=[%s], ret=[%d]", dirpath, ret);
664 memset(dirpath, '\0', BUF_SIZE);
665 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/cache", OPT_USR_APPS, pkgname);
666 if (!__is_dir(dirpath)) {
667 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
669 _LOGE("directory making is failed.\n");
672 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
674 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
675 _LOGE("chown failed!! [%s]", buf);
678 ret = _coretpk_installer_set_smack_label_access(dirpath, shared_data_label);
680 _LOGE("_coretpk_installer_apply_directory_policy() failed, appdir=[%s], ret=[%d]", dirpath, ret);
682 ret = _coretpk_installer_set_smack_label_transmute(dirpath, "1");
684 _LOGE("_coretpk_installer_apply_directory_policy() failed, appdir=[%s], ret=[%d]", dirpath, ret);
687 /* /shared/trusted/ */
688 memset(dirpath, '\0', BUF_SIZE);
689 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/trusted", USR_APPS, pkgname);
690 if (__is_dir(dirpath)) {
691 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
693 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
694 _LOGE("chown failed!! [%s]", buf);
698 ret = _rpm_installer_get_group_id(pkgname, &groupid);
700 _LOGD("group id for trusted directory is [%s]", groupid);
701 _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_GROUP_RW, groupid);
702 FREE_AND_NULL(groupid);
705 memset(dirpath, '\0', BUF_SIZE);
707 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/trusted", OPT_USR_APPS, pkgname);
709 _LOGD("dirpath [%s]", dirpath);
711 ret = _rpm_installer_get_group_id(pkgname, &groupid);
713 if (__is_dir(dirpath) != 1) {
714 _LOGE("dont have [%s]", dirpath);
716 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
717 if (ret == -1 && errno != EEXIST) {
718 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
719 _LOGE("mkdir failed!! [%s]", buf);
724 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
726 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
727 _LOGE("chown failed!! [%s]", buf);
731 _LOGD("group id for trusted directory is [%s]", groupid);
732 _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_GROUP_RW, groupid);
733 _ri_set_group_id(pkgname, groupid);
735 FREE_AND_NULL(groupid);
739 int __is_dir(const char *dirname)
741 struct stat stFileInfo;
742 if (dirname == NULL) {
743 _LOGE("dirname is null\n");
747 (void)stat(dirname, &stFileInfo);
749 if (S_ISDIR(stFileInfo.st_mode)) {
755 static void __rpm_process_line(char *line)
758 char *save_str = NULL;
759 tok = strtok_r(line, " ", &save_str);
761 if (!strncmp(tok, "%%", 2)) {
762 tok = strtok_r(NULL, " ", &save_str);
764 _LOGD("Install percentage is %s\n", tok);
765 _ri_broadcast_status_notification(gpkgname, PKGTYPE_RPM, "install_percent", tok);
766 _ri_stat_cb(gpkgname, "install_percent", tok);
774 static void __rpm_perform_read(int fd)
776 char *buf_ptr = NULL;
777 char *tmp_ptr = NULL;
779 static char buffer[BUF_SIZE] = { 0, };
780 static int buffer_position;
782 size = read(fd, &buffer[buffer_position], sizeof(buffer) - buffer_position);
783 buffer_position += size;
787 /* Process each line of the recieved buffer */
788 buf_ptr = tmp_ptr = buffer;
789 while ((tmp_ptr = (char *)memchr(buf_ptr, '\n', buffer + buffer_position - buf_ptr)) != NULL) {
791 __rpm_process_line(buf_ptr);
792 /* move to next line and continue */
793 buf_ptr = tmp_ptr + 1;
796 /* move the remaining bits at the start of the buffer
797 and update the buffer position */
798 buf_ptr = (char *)memrchr(buffer, 0, buffer_position);
802 /* we have processed till the last \n which has now become
803 0x0. So we increase the pointer to next position */
806 memmove(buffer, buf_ptr, buf_ptr - buffer);
807 buffer_position = buffer + buffer_position - buf_ptr;
810 int _rpm_xsystem(const char *argv[])
819 if (pipe(pipefd) == -1) {
820 _LOGE("pipe creation failed\n");
823 /* Read progress info via pipe */
828 _LOGE("fork failed\n");
837 _LOGE("dup failed\n");
841 result = dup(pipefd[1]);
843 _LOGE("dup failed\n");
847 if (execvp(argv[0], (char *const *)argv) == -1) {
848 _LOGE("execvp failed\n");
858 while ((err = waitpid(pid, &status, WNOHANG)) != pid) {
862 _LOGE("waitpid failed\n");
871 FD_SET(pipefd[0], &rfds);
874 select_ret = pselect(pipefd[0] + 1, &rfds, NULL, NULL, &tv, NULL);
878 else if (select_ret < 0 && errno == EINTR)
880 else if (select_ret < 0) {
881 _LOGE("select() returned error\n");
884 if (FD_ISSET(pipefd[0], &rfds))
885 __rpm_perform_read(pipefd[0]);
889 /* Check for an error code. */
890 if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) {
891 if (WIFSIGNALED(status) != 0 && WTERMSIG(status) == SIGSEGV) {
892 printf("Sub-process %s received a segmentation fault. \n", argv[0]);
893 } else if (WIFEXITED(status) != 0) {
894 printf("Sub-process %s returned an error code (%u)\n", argv[0], WEXITSTATUS(status));
896 printf("Sub-process %s exited unexpectedly\n", argv[0]);
899 return WEXITSTATUS(status);
902 void __rpm_clear_dir_list(GList *dir_list)
905 app2ext_dir_details *dir_detail = NULL;
907 list = g_list_first(dir_list);
909 dir_detail = (app2ext_dir_details *) list->data;
910 if (dir_detail && dir_detail->name) {
911 free(dir_detail->name);
914 list = g_list_next(list);
916 g_list_free(dir_list);
920 GList *__rpm_populate_dir_list()
922 GList *dir_list = NULL;
924 app2ext_dir_details *dir_detail = NULL;
926 char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
928 for (i = 0; i < 3; i++) {
929 dir_detail = (app2ext_dir_details *) calloc(1, sizeof(app2ext_dir_details));
930 if (dir_detail == NULL) {
931 printf("\nMemory allocation failed\n");
934 dir_detail->name = (char *)calloc(1, sizeof(char) * (strlen(pkg_ro_content_rpm[i]) + 2));
935 if (dir_detail->name == NULL) {
936 printf("\nMemory allocation failed\n");
940 snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i]) + 1), "%s", pkg_ro_content_rpm[i]);
941 dir_detail->type = APP2EXT_DIR_RO;
942 dir_list = g_list_append(dir_list, dir_detail);
945 list = g_list_first(dir_list);
947 dir_detail = (app2ext_dir_details *) list->data;
948 list = g_list_next(list);
956 list = g_list_first(dir_list);
958 dir_detail = (app2ext_dir_details *) list->data;
959 if (dir_detail && dir_detail->name) {
960 free(dir_detail->name);
963 list = g_list_next(list);
965 g_list_free(dir_list);
971 static char *__ri_get_cert_from_file(const char *file)
973 FILE *fp_cert = NULL;
975 char *certbuf = NULL;
976 char *startcert = NULL;
977 char *endcert = NULL;
984 if (!(fp_cert = fopen(file, "r"))) {
985 _LOGE("[ERR][%s] Fail to open file, [%s]\n", __func__, file);
989 fseek(fp_cert, 0L, SEEK_END);
991 if (ftell(fp_cert) < 0) {
992 _LOGE("[ERR][%s] Fail to find EOF\n", __func__);
997 certlen = ftell(fp_cert);
999 _LOGE("[ERR][%s] Fail to find EOF\n", __func__);
1004 fseek(fp_cert, 0L, SEEK_SET);
1006 if (!(certbuf = (char *)malloc(sizeof(char) * (int)certlen))) {
1007 _LOGE("[ERR][%s] Fail to allocate memory\n", __func__);
1011 memset(certbuf, 0x00, (int)certlen);
1014 while ((ch = fgetc(fp_cert)) != EOF) {
1022 startcert = strstr(certbuf, "-----BEGIN CERTIFICATE-----") + strlen("-----BEGIN CERTIFICATE-----");
1023 endcert = strstr(certbuf, "-----END CERTIFICATE-----");
1024 certwrite = (int)endcert - (int)startcert;
1026 cert = (char *)malloc(sizeof(char) * (certwrite + 2));
1028 _LOGE("[ERR][%s] Fail to allocate memory\n", __func__);
1032 memset(cert, 0x00, certwrite + 2);
1033 snprintf(cert, certwrite + 1, "%s", startcert);
1034 _LOGD("Root CA, len=[%d]\n%s", certwrite, cert);
1046 static int __privilege_func(const char *name, void *user_data)
1049 privilegeinfo *info = (privilegeinfo *) user_data;
1051 _LOGD("package_id=[%s], privilege=[%s]", info->package_id, name);
1052 info->privileges = g_list_append(info->privileges, strdup((char *)name));
1054 if (strcmp(name, EXT_APPDATA_PRIVILEGE_NAME) == 0) {
1055 _LOGD("it is EXT_APPDATA_PRIVILEGE_NAME");
1056 if (_coretpk_installer_make_directory_for_ext((char *)info->package_id) < 0) {
1057 _LOGE("make_directory_for_ext failed.");
1064 char *__strlwr(char *str)
1068 while (*(str + i) != '\0') {
1069 if (*(str + i) >= 65 || *(str + i) <= 90) {
1070 *(str + i) = towlower(*(str + i));
1077 static int __ri_install_fota(const char *pkgid)
1081 char manifest[BUF_SIZE] = { 0, };
1082 char rw_manifest[BUF_SIZE] = { 0, };
1083 char root_path[BUF_SIZE] = { 0, };
1084 char signature_file[BUF_SIZE] = { 0, };
1085 char *fota_version = NULL;
1086 char *temp[] = { "fota=true", NULL };
1087 pkginfo *db_info = NULL;
1088 char *smack_label = NULL;
1090 _LOGD("fota-info : pkgid[%s] start installation.", pkgid);
1092 snprintf(manifest, BUF_SIZE, "%s/%s.xml", USR_SHARE_PACKAGES, pkgid);
1093 snprintf(rw_manifest, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
1095 _LOGD("fota-info : pkgid[%s] has manefest[%s].", pkgid, manifest);
1097 if (access(rw_manifest, F_OK) == 0) {
1098 _LOGD("fota-info : [%s] is existed.", rw_manifest);
1100 // compare version(db, fota)
1101 db_info = _rpm_installer_get_pkgname_info(pkgid);
1102 if (db_info != NULL) {
1103 __get_version_from_xml(manifest, &fota_version);
1104 if (fota_version != NULL) {
1105 _LOGD("fota-info : dbinfo version=[%s], fota version=[%s]", db_info->version, fota_version);
1107 ret = _installer_util_compare_version(db_info->version, fota_version);
1108 if (ret == VERSION_NEW) {
1109 _LOGD("fota is new version. [%s]", manifest);
1111 _LOGD("fota is not new version. [%s]", manifest);
1114 _LOGE("fota-info : __get_version_from_xml(%s) failed.", manifest);
1125 if (ret != VERSION_NEW) {
1126 _LOGD("fota-info : [%s] installation skip. [version is not new]", pkgid);
1130 _LOGE("fota-info : _rpm_installer_get_pkgname_info(%s) failed.", pkgid);
1134 ret = pkgmgr_parser_parse_manifest_for_installation(manifest, temp);
1136 _LOGE("fota-info : installation fail. [manifest=%s]", manifest);
1140 _LOGD("fota-info : pkgid[%s] installation success.", pkgid);
1142 snprintf(root_path, BUF_SIZE, "%s/%s", USR_APPS, pkgid);
1143 ret = _ri_verify_signatures(root_path, pkgid, false);
1145 _LOGD("fota-info : certificate register(%s).", pkgid);
1146 _ri_register_cert(pkgid);
1149 __ri_make_directory(pkgid);
1151 ret = __get_smack_label_from_db(pkgid, &smack_label);
1152 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
1154 __rpm_apply_smack(pkgid, 0, smack_label);
1156 snprintf(signature_file, BUF_SIZE, "%s/%s", root_path, SIGNATURE1_XML);
1157 if (access(signature_file, F_OK) != 0){
1158 _LOGE("[%s] is not present", signature_file);
1160 ret = _ri_get_visibility_from_signature_file(signature_file, &visibility, false);
1162 _LOGE("Couldnt get visiblity [%d], ret: %d", visibility, ret);
1163 ret = RPM_INSTALLER_ERR_INTERNAL;
1166 _LOGD("visibility : %d", visibility);
1170 ret = _ri_apply_privilege(pkgid, visibility, smack_label);
1172 _LOGE("fota-info : _ri_apply_privilege fail[pkgid=%s]\n", pkgid);
1176 _LOGD("fota-info : pkgid[%s] apply smack success\n", pkgid);
1179 FREE_AND_NULL(smack_label);
1184 static int __ri_upgrade_fota(const char *pkgid)
1186 _LOGD("fota-info : pkgid[%s] start upgrade.", pkgid);
1190 char manifest[BUF_SIZE] = { 0, };
1191 char root_path[BUF_SIZE] = { 0, };
1192 char signature_file[BUF_SIZE] = { 0, };
1193 char *temp[] = { "fota=true", NULL };
1194 char *smack_label = NULL;
1197 snprintf(manifest, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
1198 (void)remove(manifest);
1199 memset(manifest, '\0', BUF_SIZE);
1201 snprintf(manifest, BUF_SIZE, "%s/%s.xml", USR_SHARE_PACKAGES, pkgid);
1202 _LOGD("fota-info : pkgid[%s] has manefest[%s].", pkgid, manifest);
1204 if (access(manifest, F_OK) != 0) {
1205 _LOGE("fota-info : can not access[manifest=%s].", manifest);
1210 ret = pkgmgr_parser_parse_manifest_for_upgrade(manifest, temp);
1212 _LOGE("fota-info : upgrade fail[manifest=%s].", manifest);
1217 snprintf(root_path, BUF_SIZE, "%s/%s", USR_APPS, pkgid);
1218 ret = _ri_verify_signatures(root_path, pkgid, false);
1220 _LOGD("fota-info : certificate register(%s).", pkgid);
1221 _ri_register_cert(pkgid);
1224 __ri_make_directory(pkgid);
1226 ret = __get_smack_label_from_db(pkgid, &smack_label);
1227 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
1229 __rpm_apply_smack(pkgid, 0, smack_label);
1231 snprintf(signature_file, BUF_SIZE, "%s/%s", root_path, SIGNATURE1_XML);
1232 if (access(signature_file, F_OK) != 0){
1233 _LOGE("[%s] is not present", signature_file);
1235 ret = _ri_get_visibility_from_signature_file(signature_file, &visibility, false);
1237 _LOGE("Couldnt get visiblity [%d], ret: %d", visibility, ret);
1238 ret = RPM_INSTALLER_ERR_INTERNAL;
1241 _LOGD("visibility : %d", visibility);
1245 ret = _ri_apply_privilege(pkgid, visibility, smack_label);
1247 _LOGE("fota-info : _ri_apply_privilege fail[pkgid=%s].", pkgid);
1250 _LOGD("fota-info : pkgid[%s] upgrade success.", pkgid);
1253 FREE_AND_NULL(smack_label);
1258 static int __ri_uninstall_fota(char *pkgid)
1260 _LOGD("fota-info : pkgid[%s] start uninstallation\n", pkgid);
1263 char buff[BUF_SIZE] = { '\0' };
1264 char *smack_label = NULL;
1266 /* del root path dir */
1267 snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
1268 if (__is_dir(buff)) {
1269 _installer_util_delete_dir(buff);
1272 /* del root path dir for ext */
1273 char extpath[BUF_SIZE] = { '\0' };
1274 snprintf(extpath, BUF_SIZE, "%s/%s", OPT_STORAGE_SDCARD_APP_ROOT, pkgid);
1275 if (__is_dir(extpath)) {
1276 _installer_util_delete_dir(extpath);
1279 /* Unregister cert info */
1280 _ri_unregister_cert(pkgid);
1282 ret = __get_smack_label_from_db(pkgid, &smack_label);
1283 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
1285 ret = _ri_privilege_unregister_package(smack_label);
1287 _LOGE("fota-info : _ri_privilege_unregister_package fail[smack_label=%s]\n", smack_label);
1290 ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
1292 _LOGE("fota-info : uninstall fail[pkgid=%s]\n", pkgid);
1295 ret = _ri_smack_reload(smack_label, UNINSTALL_REQ);
1297 _LOGD("_ri_smack_reload failed.");
1300 _LOGD("fota-info : pkgid[%s] uninstall success\n", pkgid);
1302 FREE_AND_NULL(smack_label);
1307 static char *__getvalue(const char *pBuf, const char *pKey)
1309 const char *p = NULL;
1310 const char *pStart = NULL;
1311 const char *pEnd = NULL;
1313 p = strstr(pBuf, pKey);
1317 pStart = p + strlen(pKey) + 1;
1318 pEnd = strchr(pStart, SEPERATOR_START);
1322 size_t len = pEnd - pStart;
1326 char *pRes = (char *)malloc(len + 1);
1328 _LOGE("@malloc failed");
1331 strncpy(pRes, pStart, len);
1337 static char *__find_rpm_pkgid(const char *manifest)
1340 char buf[BUF_SIZE] = { 0 };
1343 fp = fopen(manifest, "r");
1345 _LOGE("csc-info : Fail get : %s\n", manifest);
1349 while (fgets(buf, BUF_SIZE, fp) != NULL) {
1351 pkgid = __getvalue(buf, TOKEN_PACKAGE_STR);
1352 if (pkgid != NULL) {
1356 memset(buf, 0x00, BUF_SIZE);
1365 static int __copy_file(const char *src_path, const char *dst_path)
1369 unsigned char temp_buf[8192] = { '\0', };
1370 size_t size_of_uchar = sizeof(unsigned char);
1371 size_t size_of_temp_buf = sizeof(temp_buf);
1372 char buf[BUF_SIZE] = { 0, };
1374 src = fopen(src_path, "r");
1376 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
1377 _LOGE("Failed to open(). path=%s, E:%d(%s)", src_path, errno, buf);
1382 dst = fopen(dst_path, "w");
1384 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
1385 _LOGE("Failed to open dst file. file=%s, E:%d(%s)", dst_path, errno, buf);
1391 while (!feof(src)) {
1392 rc = fread(temp_buf, size_of_uchar, size_of_temp_buf, src);
1393 fwrite(temp_buf, size_of_uchar, rc, dst);
1401 static int __ri_install_csc(char *path_str, char *remove_str)
1405 char delims[] = "/";
1407 char argv[BUF_SIZE] = { '\0' };
1408 char xml_name[BUF_SIZE] = { '\0' };
1409 char src_file[BUF_SIZE] = { '\0' };
1410 char dest_file[BUF_SIZE] = { '\0' };
1411 char *save_str = NULL;
1413 snprintf(src_file, sizeof(src_file), "%s", path_str);
1415 /* get pkgid from path str */
1416 pkgid = __find_rpm_pkgid(path_str);
1417 if (pkgid == NULL) {
1418 _LOGE("csc-info : fail to find pkgid\n");
1421 _LOGD("csc-info : find pkgid=[%s] for installation\n", pkgid);
1424 token = strtok_r(path_str, delims, &save_str);
1426 memset(xml_name, 0x00, sizeof(xml_name));
1427 strncat(xml_name, token, sizeof(xml_name) - 1);
1428 token = strtok_r(NULL, delims, &save_str);
1430 _LOGD("csc-info : xml name = %s\n", xml_name);
1432 /* copy xml to /opt/share/packages */
1433 snprintf(dest_file, sizeof(dest_file), "%s/%s", OPT_SHARE_PACKAGES, xml_name);
1434 ret = __copy_file(src_file, dest_file);
1436 _LOGE("csc-info : xml copy fail(%d)\n", ret);
1438 _LOGE("csc-info : xml copy success to [%s] \n", dest_file);
1441 /* remove old pkg info */
1442 ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
1444 _LOGD("csc-info : fail remove old pkg info\n");
1446 _LOGD("csc-info : success remove old pkg info\n");
1449 /* insert new pkg info */
1450 memset(argv, 0x00, sizeof(argv));
1451 snprintf(argv, sizeof(argv), "%s/%s", OPT_SHARE_PACKAGES, xml_name);
1452 ret = __ri_init_csc_xml(argv, remove_str);
1454 _LOGD("csc-info : fail insert db\n");
1456 _LOGD("csc-info : success xml name = %s\n", xml_name);
1466 static int __ri_uninstall_csc(char *pkgid)
1468 /* remove old pkg info */
1469 int ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
1471 _LOGD("csc-info : fail remove old pkg info\n");
1473 _LOGD("csc-info : success remove old pkg info\n");
1479 static int __get_size_from_xml(const char *manifest, int *size)
1481 const char *val = NULL;
1482 const xmlChar *node;
1483 xmlTextReaderPtr reader;
1484 int ret = PMINFO_R_OK;
1486 if (manifest == NULL) {
1487 _LOGE("Input argument is NULL\n");
1488 return PMINFO_R_ERROR;
1492 _LOGE("Argument supplied to hold return value is NULL\n");
1493 return PMINFO_R_ERROR;
1496 reader = xmlReaderForFile(manifest, NULL, 0);
1499 if (_child_element(reader, -1)) {
1500 node = xmlTextReaderConstName(reader);
1502 _LOGE("xmlTextReaderConstName value is NULL\n");
1503 ret = PMINFO_R_ERROR;
1507 if (!strcmp(ASCII(node), "manifest")) {
1508 ret = _ri_get_attribute(reader, "size", &val);
1510 _LOGE("@Error in getting the attribute value");
1511 ret = PMINFO_R_ERROR;
1519 _LOGE("package size is not specified\n");
1520 ret = PMINFO_R_ERROR;
1524 _LOGE("Unable to create xml reader\n");
1525 ret = PMINFO_R_ERROR;
1530 _LOGE("xmlReaderForFile value is NULL\n");
1531 ret = PMINFO_R_ERROR;
1535 xmlFreeTextReader(reader);
1539 static int __get_location_from_xml(const char *manifest, pkgmgrinfo_install_location * location)
1541 const char *val = NULL;
1542 const xmlChar *node;
1543 xmlTextReaderPtr reader;
1546 if (manifest == NULL) {
1547 _LOGE("Input argument is NULL\n");
1548 return PMINFO_R_ERROR;
1551 if (location == NULL) {
1552 _LOGE("Argument supplied to hold return value is NULL\n");
1553 return PMINFO_R_ERROR;
1556 reader = xmlReaderForFile(manifest, NULL, 0);
1559 if (_child_element(reader, -1)) {
1560 node = xmlTextReaderConstName(reader);
1562 _LOGE("xmlTextReaderConstName value is NULL\n");
1563 xmlFreeTextReader(reader);
1564 return PMINFO_R_ERROR;
1567 if (!strcmp(ASCII(node), "manifest")) {
1568 ret = _ri_get_attribute(reader, "install-location", &val);
1570 _LOGE("@Error in getting the attribute value");
1571 xmlFreeTextReader(reader);
1572 return PMINFO_R_ERROR;
1576 if (strcmp(val, "internal-only") == 0)
1577 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
1578 else if (strcmp(val, "prefer-external") == 0)
1579 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
1581 *location = PMINFO_INSTALL_LOCATION_AUTO;
1585 _LOGE("Unable to create xml reader\n");
1586 xmlFreeTextReader(reader);
1587 return PMINFO_R_ERROR;
1591 _LOGE("xmlReaderForFile value is NULL\n");
1592 return PMINFO_R_ERROR;
1595 xmlFreeTextReader(reader);
1600 static char *__get_pkg_path(const char *pkg_path, const char *pkgid)
1603 char buff[BUF_SIZE] = { '\0' };
1604 char *real_path = NULL;
1605 char buf[BUF_SIZE] = { 0, };
1607 snprintf(buff, BUF_SIZE, "%s/%s", pkg_path, pkgid);
1611 memset(buff, '\0', BUF_SIZE);
1612 snprintf(buff, BUF_SIZE, "%s/%s", USR_APPS, pkgid);
1615 memset(buff, '\0', BUF_SIZE);
1616 snprintf(buff, BUF_SIZE, "/opt/apps/%s", pkgid);
1619 memset(buff, '\0', BUF_SIZE);
1620 snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
1627 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
1628 _LOGE("chdir(%s) failed. [%s]", buff, buf);
1633 real_path = (char *)malloc(strlen(buff) + 1);
1634 if (real_path == NULL) {
1635 _LOGE("malloc() failed.");
1638 memset(real_path, '\0', strlen(buff) + 1);
1639 memcpy(real_path, buff, strlen(buff));
1644 void _ri_register_cert(const char *pkgid)
1647 pkgmgrinfo_instcertinfo_h handle = NULL;
1650 error = pkgmgrinfo_create_certinfo_set_handle(&handle);
1652 _LOGE("Cert handle creation failed. Err:%d", error);
1653 __ri_free_cert_chain();
1657 if (list[SIG_AUTH].cert_value == NULL) {
1658 _LOGE("pkgid[%s] dont have SIG_AUTH.cert_value ", pkgid);
1662 for (i = 0; i < MAX_CERT_NUM; i++) {
1664 if (list[i].cert_value) {
1665 error = pkgmgrinfo_set_cert_value(handle, list[i].cert_type, list[i].cert_value);
1667 _LOGE("pkgmgrinfo_set_cert_value failed. cert type:%d. Err:%d", list[i].cert_type, error);
1672 /* Save the certificates in cert DB */
1673 error = pkgmgrinfo_save_certinfo(pkgid, handle);
1675 _LOGE("pkgmgrinfo_save_certinfo failed. Err:%d", error);
1680 pkgmgrinfo_destroy_certinfo_set_handle(handle);
1681 __ri_free_cert_chain();
1684 void _ri_unregister_cert(const char *pkgid)
1687 /* Delete the certifictes from cert DB */
1688 error = pkgmgrinfo_delete_certinfo(pkgid);
1690 _LOGE("pkgmgrinfo_delete_certinfo failed. Err:%d", error);
1695 int _ri_get_visibility_from_signature_file(const char *sigfile, int *visibility, bool save_ca_path)
1697 char certval[BUF_SIZE] = { '\0' };
1701 int ret = RPM_INSTALLER_SUCCESS;
1702 signature_x *signx = NULL;
1703 struct keyinfo_x *keyinfo = NULL;
1704 struct x509data_x *x509data = NULL;
1705 CERT_CONTEXT *ctx = NULL;
1708 if (sigfile == NULL) {
1709 return RPM_INSTALLER_ERR_WRONG_PARAM;
1712 ctx = cert_svc_cert_context_init();
1714 _LOGE("cert_svc_cert_context_init() failed.");
1715 return RPM_INSTALLER_ERR_INTERNAL;
1718 if (!strstr(sigfile, SIGNATURE1_XML)) {
1719 _LOGE("Unsupported signature type! [%s]", sigfile);
1720 cert_svc_cert_context_final(ctx);
1721 return RPM_INSTALLER_ERR_INTERNAL;
1724 signx = _ri_process_signature_xml(sigfile);
1725 if (signx == NULL) {
1726 _LOGE("_ri_process_signature_xml(%s) failed.", sigfile);
1727 ret = RPM_INSTALLER_ERR_INTERNAL;
1731 keyinfo = signx->keyinfo;
1732 if ((keyinfo == NULL) || (keyinfo->x509data == NULL)
1733 || (keyinfo->x509data->x509certificate == NULL)) {
1734 _LOGE("keyinfo is invalid. [%s]", sigfile);
1735 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1739 x509data = keyinfo->x509data;
1740 x509certificate_x *cert = x509data->x509certificate;
1742 /* First cert is Signer certificate */
1743 if (cert->text != NULL) {
1744 for (i = 0; i <= (int)strlen(cert->text); i++) {
1745 if (cert->text[i] != '\n') {
1746 certval[j++] = cert->text[i];
1751 err = cert_svc_load_buf_to_context(ctx, (unsigned char *)certval);
1753 _LOGE("cert_svc_load_buf_to_context() failed. cert = [%s], err = [%d]", certval, err);
1754 ret = RPM_INSTALLER_ERR_INTERNAL;
1759 err = __ri_create_cert_chain(SIG_DIST1, SIG_SIGNER, certval);
1761 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d], certval = [%s]", SIG_DIST1, certval);
1762 __ri_free_cert_chain();
1763 ret = RPM_INSTALLER_ERR_INTERNAL;
1769 /* Second cert is Intermediate certificate */
1771 if ((cert != NULL) && (cert->text != NULL)) {
1772 memset(certval, 0x00, BUF_SIZE);
1774 for (i = 0; i <= (int)strlen(cert->text); i++) {
1775 if (cert->text[i] != '\n') {
1776 certval[j++] = cert->text[i];
1781 if (cert->text != NULL) {
1782 err = cert_svc_push_buf_into_context(ctx, (unsigned char *)certval);
1784 _LOGE("cert_svc_push_buf_into_context() failed. cert = [%s], err = [%d]", certval, err);
1785 ret = RPM_INSTALLER_ERR_INTERNAL;
1791 err = __ri_create_cert_chain(SIG_DIST1, SIG_INTERMEDIATE, certval);
1793 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d], certval = [%s]", SIG_DIST1, certval);
1794 __ri_free_cert_chain();
1795 ret = RPM_INSTALLER_ERR_INTERNAL;
1800 _LOGE("Invalid CertChain! (cert->text is NULL.)");
1801 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1805 err = cert_svc_verify_certificate(ctx, &validity);
1808 _LOGE("cert_svc_verify_certificate() failed.");
1809 ret = RPM_INSTALLER_ERR_INTERNAL;
1812 if (validity == 0) {
1813 _LOGE("Certificate Invalid/Expired (validity == 0)");
1814 ret = RPM_INSTALLER_ERR_CERTCHAIN_VERIFICATION_FAILED;
1817 _LOGD("cert_svc_verify() is done successfully. validity=[%d]", validity);
1819 err = cert_svc_get_visibility(ctx, visibility);
1821 _LOGE("cert_svc_get_visibility() failed. err = [%d]", err);
1822 ret = RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED;
1827 if (save_ca_path && ctx->fileNames && ctx->fileNames->filename) {
1828 FREE_AND_NULL(sig1_capath);
1829 sig1_capath = strdup(ctx->fileNames->filename);
1830 sig1_visibility = *visibility;
1834 cert_svc_cert_context_final(ctx);
1836 _ri_free_signature_xml(signx);
1841 int _ri_verify_sig_and_cert(const char *sigfile, int *visibility, bool need_verify, char *ca_path)
1843 char certval[BUF_SIZE] = { '\0' };
1848 int ret = RPM_INSTALLER_SUCCESS;
1850 signature_x *signx = NULL;
1851 struct keyinfo_x *keyinfo = NULL;
1852 struct x509data_x *x509data = NULL;
1853 CERT_CONTEXT *ctx = NULL;
1855 char *root_ca_path = NULL;
1857 ctx = cert_svc_cert_context_init();
1859 _LOGE("cert_svc_cert_context_init() failed.");
1860 return RPM_INSTALLER_ERR_INTERNAL;
1863 if (strstr(sigfile, AUTHOR_SIGNATURE_XML))
1865 else if (strstr(sigfile, SIGNATURE1_XML))
1866 sigtype = SIG_DIST1;
1867 else if (strstr(sigfile, SIGNATURE2_XML))
1868 sigtype = SIG_DIST2;
1870 _LOGE("Unsupported signature type! [%s]", sigfile);
1871 cert_svc_cert_context_final(ctx);
1872 return RPM_INSTALLER_ERR_INTERNAL;
1875 if (sigtype == SIG_DIST1 && ca_path != NULL && strlen(ca_path) != 0) {
1876 root_ca_path = ca_path;
1877 *visibility = sig1_visibility;
1881 signx = _ri_process_signature_xml(sigfile);
1882 if (signx == NULL) {
1883 _LOGE("_ri_process_signature_xml(%s) failed.", sigfile);
1884 ret = RPM_INSTALLER_ERR_SIG_INVALID;
1888 keyinfo = signx->keyinfo;
1889 if ((keyinfo == NULL) || (keyinfo->x509data == NULL) || (keyinfo->x509data->x509certificate == NULL)) {
1890 _LOGE("keyinfo is invalid. [%s]", sigfile);
1891 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1895 x509data = keyinfo->x509data;
1896 x509certificate_x *cert = x509data->x509certificate;
1898 /* First cert is Signer certificate */
1899 if (cert->text != NULL) {
1900 for (i = 0; i <= (int)strlen(cert->text); i++) {
1901 if (cert->text[i] != '\n') {
1902 certval[j++] = cert->text[i];
1907 err = cert_svc_load_buf_to_context(ctx, (unsigned char *)certval);
1909 _LOGE("cert_svc_load_buf_to_context() failed. cert = [%s], err = [%d]", certval, err);
1910 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1914 err = __ri_create_cert_chain(sigtype, SIG_SIGNER, certval);
1916 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d], certval = [%s]", sigtype, certval);
1917 __ri_free_cert_chain();
1918 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1922 _LOGE("cert->text is NULL. [Signer]");
1923 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1927 /* Second cert is Intermediate certificate */
1930 _LOGE("cert is NULL. [Intermediate]");
1931 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1935 if (cert->text != NULL) {
1936 memset(certval, 0x00, BUF_SIZE);
1938 for (i = 0; i <= (int)strlen(cert->text); i++) {
1939 if (cert->text[i] != '\n') {
1940 certval[j++] = cert->text[i];
1945 if (cert->text != NULL) {
1946 err = cert_svc_push_buf_into_context(ctx, (unsigned char *)certval);
1948 _LOGE("cert_svc_push_buf_into_context() failed. cert = [%s], err = [%d]", certval, err);
1949 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1954 err = __ri_create_cert_chain(sigtype, SIG_INTERMEDIATE, certval);
1956 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d], certval = [%s]", sigtype, certval);
1957 __ri_free_cert_chain();
1958 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1962 _LOGE("Invalid CertChain! (cert->text is NULL.) [Intermediate]");
1963 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1967 err = cert_svc_verify_certificate(ctx, &validity);
1968 if (err != 0 && (need_verify == true)) {
1969 _LOGE("cert_svc_verify_certificate() failed. err=[%d]", err);
1973 _LOGD("cert_svc_verify() is done successfully. validity=[%d]", validity);
1975 if (validity == 0) {
1976 _LOGE("Certificate Invalid/Expired (validity == 0)");
1977 ret = RPM_INSTALLER_ERR_CERTIFICATE_EXPIRED;
1981 err = cert_svc_get_visibility(ctx, visibility);
1983 _LOGE("cert_svc_get_visibility() failed. err = [%d]", err);
1984 ret = RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED;
1987 _LOGD("cert_svc_get_visibility() returns visibility=[%d]", *visibility);
1989 if (ctx->fileNames == NULL || ctx->fileNames->filename == NULL) {
1990 _LOGE("No Root CA cert found. Signature validation failed.");
1991 ret = RPM_INSTALLER_ERR_ROOT_CERT_NOT_FOUND;
1994 root_ca_path = ctx->fileNames->filename;
1998 For reference validation, we should be in TEMP_DIR/usr/apps/<pkgid> */
1999 if (root_ca_path != NULL && strlen(root_ca_path) != 0) {
2000 _LOGD("Root CA cert path=[%s]", root_ca_path);
2002 err = __ri_xmlsec_verify_signature(sigfile, root_ca_path);
2003 if (err < 0 && (need_verify == true)) {
2004 _LOGE("__ri_xmlsec_verify_signature(%s) failed.", sigfile);
2005 ret = RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED;
2009 crt = __ri_get_cert_from_file(root_ca_path);
2010 err = __ri_create_cert_chain(sigtype, SIG_ROOT, crt);
2012 _LOGE("__ri_create_cert_chain(%d) failed.", sigtype);
2013 __ri_free_cert_chain();
2014 ret = RPM_INSTALLER_ERR_CERT_INVALID;
2022 cert_svc_cert_context_final(ctx);
2024 _ri_free_signature_xml(signx);
2029 int _ri_verify_signatures(const char *root_path, const char *pkgid, bool need_verify)
2032 char buff[BUF_SIZE] = { '\0' };
2033 char *pkg_path = NULL;
2036 _LOGD("root_path=[%s], pkgid=[%s]", root_path, pkgid);
2038 /* check for signature and certificate */
2039 pkg_path = __get_pkg_path(root_path, pkgid);
2040 if (pkg_path == NULL) {
2041 _LOGE("__get_pkg_path(%s, %s) failed.", root_path, pkgid);
2045 _LOGD("switched to pkg_path=[%s]", pkg_path);
2047 /* author-signature.xml is mandatory */
2048 snprintf(buff, BUF_SIZE, "%s/author-signature.xml", pkg_path);
2049 if (access(buff, F_OK) == 0) {
2050 _LOGD("author-signature.xml, path=[%s]", buff);
2051 ret = _ri_verify_sig_and_cert(buff, &visibility, need_verify, NULL);
2053 _LOGE("_ri_verify_sig_and_cert(%s) failed.", buff);
2057 _LOGD("------------------------------------------------------");
2058 _LOGD("signature is verified successfully");
2059 _LOGD("path=[%s]", buff);
2060 _LOGD("------------------------------------------------------");
2062 memset(buff, '\0', BUF_SIZE);
2064 /* signature2.xml is optional */
2065 snprintf(buff, BUF_SIZE, "%s/signature2.xml", pkg_path);
2066 if (access(buff, F_OK) == 0) {
2067 _LOGD("signature2.xml found. [%s]", pkg_path);
2068 ret = _ri_verify_sig_and_cert(buff, &visibility, need_verify, NULL);
2070 _LOGE("_ri_verify_sig_and_cert(%s) failed.", buff);
2074 _LOGD("_ri_verify_sig_and_cert(%s) succeed.", buff);
2076 memset(buff, '\0', BUF_SIZE);
2078 /* signature1.xml is mandatory */
2079 snprintf(buff, BUF_SIZE, "%s/signature1.xml", pkg_path);
2080 if (access(buff, F_OK) == 0) {
2081 _LOGD("signature1.xml, path=[%s]", buff);
2082 ret = _ri_verify_sig_and_cert(buff, &visibility, need_verify, NULL);
2084 _LOGE("_ri_verify_sig_and_cert(%s) failed.", buff);
2088 _LOGD("------------------------------------------------------");
2089 _LOGD("signature is verified successfully");
2090 _LOGD("path=[%s]", buff);
2091 _LOGD("------------------------------------------------------");
2093 memset(buff, '\0', BUF_SIZE);
2103 if ((ret != 0) && (sig_enable == 0)) {
2104 _LOGD("_ri_verify_signatures(%s, %s) failed, but it's ok for config.", root_path, pkgid);
2111 void _ri_apply_smack(const char *pkgname, int flag, char *smack_label)
2113 __rpm_apply_smack(pkgname, flag, smack_label);
2116 int _ri_apply_privilege(const char *pkgid, int visibility, char *smack_label)
2119 pkgmgrinfo_pkginfo_h handle = NULL;
2121 int apptype = PERM_APP_TYPE_EFL;
2123 char *privilege_fota[BUF_SIZE] = { NULL, };
2124 char *api_version = NULL;
2127 if (smack_label == NULL || strlen(smack_label) == 0) {
2128 smack_label = (char *)pkgid;
2131 memset(&info, '\0', sizeof(info));
2133 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
2134 if (ret != PMINFO_R_OK) {
2135 _LOGE("pkgmgrinfo_pkginfo_get_pkginfo(%s) failed.", pkgid);
2139 ret = pkgmgrinfo_pkginfo_get_api_version(handle, &api_version);
2140 if (ret != PMINFO_R_OK)
2141 _LOGE("failed to get api version (%s)", pkgid);
2144 ret = _ri_privilege_set_package_version(smack_label, api_version);
2146 _LOGE("failed to set api version for smack_label: %s, ret[%d]", smack_label, ret);
2147 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2150 _LOGD("api-version[%s] fot privilege has done successfully.", api_version);
2153 strncpy(info.package_id, pkgid, sizeof(info.package_id) - 1);
2154 info.visibility = visibility;
2156 ret = pkgmgrinfo_pkginfo_foreach_privilege(handle, __privilege_func, (void *)&info);
2157 if (ret != PMINFO_R_OK) {
2158 _LOGE("pkgmgrinfo_pkginfo_foreach_privilege(%s) failed.", pkgid);
2159 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2162 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
2164 if (visibility & CERT_SVC_VISIBILITY_PLATFORM) {
2165 _LOGD("VISIBILITY_PLATFORM!");
2166 apptype = PERM_APP_TYPE_EFL_PLATFORM;
2167 } else if ((visibility & CERT_SVC_VISIBILITY_PARTNER) ||
2168 (visibility & CERT_SVC_VISIBILITY_PARTNER_OPERATOR) ||
2169 (visibility & CERT_SVC_VISIBILITY_PARTNER_MANUFACTURER)) {
2170 _LOGD("VISIBILITY_PARTNER!");
2171 apptype = PERM_APP_TYPE_EFL_PARTNER;
2174 list = g_list_first(info.privileges);
2177 privilege_fota[i] = strdup((char *)list->data);
2179 list = g_list_next(list);
2182 privilege_fota[i] = NULL;
2184 ret = _ri_privilege_enable_permissions(smack_label, apptype, (const char **)privilege_fota, 1);
2185 for (i = 0; i < g_list_length(info.privileges); i++) {
2186 if (privilege_fota[i]) {
2187 free(privilege_fota[i]);
2188 privilege_fota[i] = NULL;
2192 if (info.privileges != NULL) {
2193 list = g_list_first(info.privileges);
2198 list = g_list_next(list);
2200 g_list_free(info.privileges);
2201 info.privileges = NULL;
2205 _LOGE("_ri_privilege_enable_permissions(%s, %d) failed.", smack_label, apptype);
2212 int _ri_set_group_id(const char *pkgid, const char *groupid)
2214 retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
2215 retvm_if(groupid == NULL, PMINFO_R_EINVAL, "groupid is NULL\n");
2217 sqlite3 *pkginfo_db = NULL;
2221 ret = db_util_open(PKGMGR_DB, &pkginfo_db, 0);
2222 retvm_if(ret != SQLITE_OK, PMINFO_R_ERROR, "connect db [%s] failed!", PKGMGR_DB);
2224 /* Begin transaction */
2225 ret = sqlite3_exec(pkginfo_db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
2226 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
2227 _LOGD("Transaction Begin\n");
2229 query = sqlite3_mprintf("update package_info set package_reserve3=%Q where package=%Q", groupid, pkgid);
2231 ret = sqlite3_exec(pkginfo_db, query, NULL, NULL, NULL);
2232 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
2234 /* Commit transaction */
2235 ret = sqlite3_exec(pkginfo_db, "COMMIT", NULL, NULL, NULL);
2236 if (ret != SQLITE_OK) {
2237 _LOGE("Failed to commit transaction. Rollback now\n");
2238 ret = sqlite3_exec(pkginfo_db, "ROLLBACK", NULL, NULL, NULL);
2239 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
2241 _LOGD("Transaction Commit and End\n");
2245 sqlite3_free(query);
2246 sqlite3_close(pkginfo_db);
2251 static int __ri_install_fota_for_rw(char *pkgid)
2255 char buff[BUF_SIZE] = { '\0' };
2256 char *smack_label = NULL;
2258 char signature_file[BUF_SIZE] = {0, };
2260 _LOGD("fota-info : pkgid[%s] start installation\n", pkgid);
2262 /* unzip pkg path from factoryrest data */
2263 snprintf(buff, BUF_SIZE, "opt/usr/apps/%s/*", pkgid); // relative path
2264 const char *pkg_argv[] = { "/usr/bin/unzip", "-oX", OPT_ZIP_FILE, buff, "-d", "/", NULL };
2265 ret = _ri_xsystem(pkg_argv);
2267 _LOGE("fota-info : unzip root path[%s] is fail .\n", buff);
2269 _LOGE("fota-info : unzip root path[%s] is success\n", buff);
2272 /* unzip manifest from factoryrest data */
2273 memset(buff, '\0', BUF_SIZE);
2274 snprintf(buff, BUF_SIZE, "opt/share/packages/%s.xml", pkgid); // relative path
2276 const char *xml_argv[] = { "/usr/bin/unzip", "-oX", OPT_ZIP_FILE, buff, "-d", "/", NULL };
2277 ret = _ri_xsystem(xml_argv);
2279 _LOGE("fota-info : xml_argv fail for pkgid[%s] .\n", pkgid);
2281 _LOGE("fota-info : xml_argv[%s] is success\n", pkgid);
2284 /* get updated manifest path */
2285 memset(buff, '\0', BUF_SIZE);
2286 snprintf(buff, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2287 _LOGE("Manifest name is %s\n", buff);
2289 /* apply smack for manifest */
2290 ret = __get_smack_label_from_db(pkgid, &smack_label);
2291 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
2293 _ri_privilege_change_smack_label(buff, smack_label, 0); /* 0 is SMACK_LABEL_ACCESS */
2295 /* register manifest */
2296 char *fota_tags[3] = { NULL, };
2297 fota_tags[0] = "removable=true";
2298 fota_tags[1] = "preload=true";
2299 fota_tags[2] = NULL;
2301 ret = pkgmgr_parser_parse_manifest_for_installation(buff, fota_tags);
2303 _LOGE("Parsing Manifest Failed\n");
2307 _LOGE("Parsing Manifest Success\n");
2310 memset(buff, '\0', BUF_SIZE);
2311 snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
2312 ret = _ri_verify_signatures(buff, pkgid, false);
2314 _LOGE("fota-info : certificate register(%s).", pkgid);
2315 _ri_register_cert(pkgid);
2318 __ri_make_directory(pkgid);
2319 ret = _coretpk_installer_apply_smack(pkgid, 0);
2321 _LOGE("failed to apply the smack.");
2324 snprintf(signature_file, BUF_SIZE, "%s/%s", buff, SIGNATURE1_XML);
2325 if (access(signature_file, F_OK) != 0){
2326 _LOGE("[%s] is not present", signature_file);
2328 ret = _ri_get_visibility_from_signature_file(signature_file, &visibility, false);
2330 _LOGE("Couldnt get visiblity [%d], ret: %d", visibility, ret);
2331 ret = RPM_INSTALLER_ERR_INTERNAL;
2334 _LOGE("visibility : %d", visibility);
2338 ret = _ri_apply_privilege(pkgid, visibility, smack_label);
2340 _LOGE("fota-info : _ri_apply_privilege fail[pkgid=%s]\n", pkgid);
2342 _LOGE("fota-info : pkgid[%s] apply smack success\n", pkgid);
2346 FREE_AND_NULL(smack_label);
2351 static int __ri_upgrade_fota_for_rw(char *pkgid)
2355 char buff[BUF_SIZE] = { '\0' };
2357 char signature_file[BUF_SIZE] = {0, };
2358 char *smack_label = NULL;
2360 _LOGD("fota-info : pkgid[%s] start upgrade\n", pkgid);
2362 /* unzip pkg dir from factoryrest data */
2363 snprintf(buff, BUF_SIZE, "opt/usr/apps/%s/*", pkgid); // relative path
2364 const char *pkg_argv[] = { "/usr/bin/unzip", "-oX", OPT_ZIP_FILE, buff, "-d", "/", NULL };
2365 ret = _ri_xsystem(pkg_argv);
2367 _LOGE("fota-info : unzip root path[%s] is fail .\n", buff);
2369 _LOGD("fota-info : unzip root path[%s] is success\n", buff);
2372 /* unzip manifest from factoryrest data */
2373 memset(buff, '\0', BUF_SIZE);
2374 snprintf(buff, BUF_SIZE, "opt/share/packages/%s.xml", pkgid); // relative path
2375 const char *xml_argv[] = { "/usr/bin/unzip", "-oX", OPT_ZIP_FILE, buff, "-d", "/", NULL };
2376 ret = _ri_xsystem(xml_argv);
2378 _LOGE("fota-info : unzip manifest[%s] is fail .\n", buff);
2380 _LOGD("fota-info : unzip manifest[%s] is success\n", buff);
2383 /* get updated manifest path */
2384 memset(buff, '\0', BUF_SIZE);
2385 snprintf(buff, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2386 _LOGE("Manifest name is %s\n", buff);
2388 /* apply smack for manifest */
2389 ret = __get_smack_label_from_db(pkgid, &smack_label);
2390 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
2392 _ri_privilege_change_smack_label(buff, smack_label, 0); /* 0 is SMACK_LABEL_ACCESS */
2394 /* register manifest */
2395 ret = pkgmgr_parser_parse_manifest_for_upgrade(buff, NULL);
2397 _LOGE("Parsing Manifest Failed\n");
2401 _LOGD("Parsing Manifest Success\n");
2404 memset(buff, '\0', BUF_SIZE);
2405 snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
2406 ret = _ri_verify_signatures(buff, pkgid, false);
2408 _LOGE("fota-info : certificate register(%s).", pkgid);
2409 /* Register new cert info */
2410 _ri_unregister_cert(pkgid);
2411 _ri_register_cert(pkgid);
2414 __ri_make_directory(pkgid);
2415 ret = _coretpk_installer_apply_smack(pkgid, 0);
2417 _LOGE("failed to apply the smack.");
2420 snprintf(signature_file, BUF_SIZE, "%s/%s", buff, SIGNATURE1_XML);
2421 if (access(signature_file, F_OK) != 0){
2422 _LOGE("[%s] is not present", signature_file);
2424 ret = _ri_get_visibility_from_signature_file(signature_file, &visibility, false);
2426 _LOGE("Couldnt get visiblity [%d], ret: %d", visibility, ret);
2427 ret = RPM_INSTALLER_ERR_INTERNAL;
2430 _LOGE("visibility : %d", visibility);
2434 ret = _ri_apply_privilege(pkgid, visibility, smack_label);
2436 _LOGE("fota-info : _ri_apply_privilege fail[pkgid=%s]\n", pkgid);
2438 _LOGE("fota-info : pkgid[%s] apply smack success\n", pkgid);
2442 FREE_AND_NULL(smack_label);
2447 static int __ri_uninstall_fota_for_rw(char *pkgid)
2450 char buff[BUF_SIZE] = { '\0' };
2451 char *smack_label = NULL;
2453 _LOGD("fota-info : pkgid[%s] start uninstall\n", pkgid);
2455 ret = __get_smack_label_from_db(pkgid, &smack_label);
2456 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
2458 /* del root path dir */
2459 snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
2461 if (__is_dir(buff)) {
2462 _installer_util_delete_dir(buff);
2466 memset(buff, '\0', BUF_SIZE);
2467 snprintf(buff, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2471 ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
2473 _LOGE("Parsing Manifest Failed\n");
2476 /* execute privilege APIs */
2477 _ri_privilege_revoke_permissions(smack_label);
2478 _ri_privilege_unregister_package(smack_label);
2480 /* Unregister cert info */
2481 _ri_unregister_cert(pkgid);
2483 FREE_AND_NULL(smack_label);
2489 * callback for the pkgmgrinfo_appinfo_get_list used in _rpm_uninstall_pkg()
2491 int __ri_check_running_app(const pkgmgrinfo_appinfo_h handle, void *user_data)
2496 app_context_h appCtx = NULL;
2498 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
2500 _LOGE("Failed to execute pkgmgrinfo_appinfo_get_appid[%d].\n", ret);
2504 if (user_data != NULL)
2505 *(GList **)user_data = g_list_append(*(GList **)user_data, strdup(appid));
2507 ret = app_manager_is_running(appid, &isRunning);
2509 _LOGE("Failed to execute app_manager_is_running[%d].\n", ret);
2512 _LOGE("app[%s] , running state[%d].\n", appid, isRunning);
2515 ret = app_manager_get_app_context(appid, &appCtx);
2517 _LOGE("Failed to execute app_manager_get_app_context[%d].\n", ret);
2521 ret = app_manager_terminate_app(appCtx);
2523 _LOGE("Failed to execute app_manager_terminate_app[%d].\n", ret);
2524 app_context_destroy(appCtx);
2529 for (i = 0; i < TERMINATE_RETRY_COUNT; i++) {
2530 ret = app_manager_is_running(appid, &isRunning);
2532 _LOGE("Failed to execute app_manager_is_running[%d].\n", ret);
2533 app_context_destroy(appCtx);
2538 _LOGD("App(%s) is terminated.\n", appid);
2541 _LOGD("App(%s) is not terminated yet. wait count=[%d].\n", appid, i);
2546 ret = app_context_destroy(appCtx);
2548 _LOGE("Failed to execute app_context_destroy[%d].\n", ret);
2556 int __ri_change_dir(const char *dirname)
2560 ret = mkdir(dirname, 0644);
2562 if (access(dirname, F_OK) == 0) {
2563 _installer_util_delete_dir(dirname);
2564 ret = mkdir(dirname, 0644);
2566 _LOGE("mkdir(%s) failed\n", dirname);
2570 _LOGE("can not access[%s]\n", dirname);
2575 ret = chdir(dirname);
2577 char buf[BUF_SIZE] = { 0, };
2578 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
2579 _LOGE("chdir(%s) failed [%s]\n", dirname, buf);
2586 int _ri_smack_reload(const char *pkgid, rpm_request_type request_type)
2589 char *op_type = NULL;
2591 switch (request_type) {
2593 op_type = strdup("install");
2597 op_type = strdup("update");
2601 op_type = strdup("uninstall");
2608 if (op_type == NULL) {
2609 _LOGE("@Failed to reload smack. request_type not matched[pkgid=%s, op=%s]", pkgid, op_type);
2613 const char *smack_argv[] = { "/usr/bin/smack_reload.sh", op_type, pkgid, NULL };
2614 ret = _ri_xsystem(smack_argv);
2616 _LOGE("@Failed to reload smack[pkgid=%s, op=%s].", pkgid, op_type);
2618 _LOGD("#success: smack reload[pkgid=%s, op=%s]", pkgid, op_type);
2627 int _ri_smack_reload_all(void)
2631 const char *smack_argv[] = { "/usr/bin/smackload-fast", NULL };
2632 ret = _ri_xsystem(smack_argv);
2634 _LOGE("@Failed to reload all smack : %d", errno);
2636 _LOGD("#success: smack reload all");
2642 void __ri_remove_updated_dir(const char *pkgid)
2644 char path_buf[BUF_SIZE] = { '\0' };
2647 if (pkgid == NULL) {
2648 _LOGE("pkgid is NULL.");
2652 /* remove bin dir */
2653 snprintf(path_buf, BUF_SIZE, "%s/%s/%s", OPT_USR_APPS, pkgid, BIN_DIR_STR);
2654 if (__is_dir(path_buf)) {
2655 _LOGE("@pkgid[%s] need to clean dir[%s]\n", pkgid, path_buf);
2656 _installer_util_delete_dir(path_buf);
2659 /* remove res dir */
2660 memset(path_buf, '\0', BUF_SIZE);
2661 snprintf(path_buf, BUF_SIZE, "%s/%s/%s", OPT_USR_APPS, pkgid, RES_DIR_STR);
2662 if (__is_dir(path_buf)) {
2663 _LOGE("@pkgid[%s] need to clean dir[%s]\n", pkgid, path_buf);
2664 _installer_util_delete_dir(path_buf);
2667 /* remove shared/res dir */
2668 memset(path_buf, '\0', BUF_SIZE);
2669 snprintf(path_buf, BUF_SIZE, "%s/%s/%s", OPT_USR_APPS, pkgid, SHARED_RES_DIR_STR);
2670 if (__is_dir(path_buf)) {
2671 _LOGE("@pkgid[%s] need to clean dir[%s]\n", pkgid, path_buf);
2672 _installer_util_delete_dir(path_buf);
2676 static int __metadata_func(const char *key, const char *value, void *user_data)
2682 _LOGE("key is null\n");
2685 if (value == NULL) {
2686 _LOGE("value is null\n");
2689 if (user_data == NULL) {
2690 _LOGE("user_data is null\n");
2694 if ((strcmp(key, "launch-on-attach") == 0) && (strcmp(value, "true") == 0)) {
2695 _LOGE("consumer[%s] : launch-on-attach is true \n", (char *)user_data);
2697 ret = app_manager_is_running((char *)user_data, &isRunning);
2699 _LOGE("Failed to execute app_manager_is_running[%s].\n", (char *)user_data);
2704 _LOGE("consumer[%s] is already launched \n", (char *)user_data);
2706 usleep(100 * 1000); /* 100ms sleep for infomation ready */
2707 ret = aul_launch_app((char *)user_data, NULL);
2708 if (ret == AUL_R_ERROR) {
2709 _LOGE("consumer[%s] launch fail, sleep and retry launch_app\n", (char *)user_data);
2710 usleep(100 * 1000); /* 100ms sleep for infomation ready */
2711 aul_launch_app((char *)user_data, NULL);
2713 _LOGE("consumer[%s] is launched !!!! \n", (char *)user_data);
2719 static int __ri_find_svcapp(const pkgmgrinfo_appinfo_h handle, void *user_data)
2723 char *component_type = NULL;
2725 ret = pkgmgrinfo_appinfo_get_component_type(handle, &component_type);
2726 if (ret != PMINFO_R_OK) {
2727 _LOGE("@Failed to get component_type\n");
2731 if (strcmp(component_type, "svcapp") == 0) {
2732 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
2733 if (ret != PMINFO_R_OK) {
2734 _LOGE("@Failed to get appid\n");
2737 _LOGE("@find consumer[%s], check metadata for launch\n", appid);
2739 ret = pkgmgrinfo_appinfo_foreach_metadata(handle, __metadata_func, (void *)appid);
2740 if (ret != PMINFO_R_OK) {
2741 _LOGE("@Failed to get foreach_metadata\n");
2749 static void __ri_launch_consumer(const char *pkgid)
2752 pkgmgrinfo_pkginfo_h pkghandle = NULL;
2754 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
2756 _LOGE("@Failed to get pkginfo handle [%s]\n", pkgid);
2760 ret = pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_find_svcapp, NULL);
2762 _LOGE("@Failed to get appinfo_get_list [%s]\n", pkgid);
2765 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
2768 static int __child_list_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data)
2773 ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
2775 _LOGE("get_pkgid failed\n");
2779 _LOGD("@child pkgid is [%s] for uninstallation", pkgid);
2781 ret = _rpm_uninstall_pkg_with_dbpath(pkgid, 0);
2783 _LOGE("uninstall pkg(%s) failed\n", pkgid);
2789 static void __uninstall_child_package_by_mother_pkgid(const char *pkgid)
2792 pkgmgrinfo_pkginfo_filter_h handle = NULL;
2794 ret = pkgmgrinfo_pkginfo_filter_create(&handle);
2796 _LOGE("filter_create failed for (%s)\n", pkgid);
2800 ret = pkgmgrinfo_pkginfo_filter_add_string(handle, PMINFO_PKGINFO_PROP_PACKAGE_STORECLIENT_ID, pkgid);
2802 _LOGE("PMINFO_PKGINFO_PROP_PACKAGE_STORECLIENT_ID add failed\n");
2806 ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, __child_list_cb, NULL);
2808 _LOGE("foreach_pkginfo failed\n");
2812 pkgmgrinfo_pkginfo_filter_destroy(handle);
2815 int _rpm_install_pkg_with_dbpath(char *pkgfilepath, char *pkgid, char *clientid)
2818 char manifest[BUF_SIZE] = { '\0' };
2819 char resultxml[BUF_SIZE] = { '\0' };
2820 char resxml[BUF_SIZE] = { '\0' };
2821 char cwd[BUF_SIZE] = { '\0' };
2824 char buf[BUF_SIZE] = { 0, };
2826 #ifdef APP2EXT_ENABLE
2827 app2ext_handle *handle = NULL;
2828 GList *dir_list = NULL;
2829 pkgmgrinfo_install_location location = 1;
2831 unsigned long rpm_size = 0;
2833 char *smack_label = NULL;
2835 /* send event for start */
2836 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "start", "install");
2837 _LOGD("[#]start : _rpm_install_pkg_with_dbpath");
2840 temp = getcwd(cwd, BUF_SIZE);
2841 if ((temp == NULL) || (cwd[0] == '\0')) {
2842 _LOGE("@failed to get the current directory info.");
2843 ret = RPM_INSTALLER_ERR_INTERNAL;
2846 _LOGD("#current working directory is %s", cwd);
2849 ret = __ri_change_dir(TEMP_DIR);
2851 _LOGE("@failed to change directory.");
2852 ret = RPM_INSTALLER_ERR_INTERNAL;
2855 _LOGD("#switched to %s", TEMP_DIR);
2857 /* run cpio script */
2858 const char *cpio_argv[] = { CPIO_SCRIPT, pkgfilepath, NULL };
2859 ret = _ri_xsystem(cpio_argv);
2861 /* get manifext.xml path */
2862 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, OPT_SHARE_PACKAGES, pkgid);
2863 _LOGD("#manifest name is %s", manifest);
2865 if (access(manifest, F_OK)) {
2866 _LOGD("#there is no RW manifest.xml. check RO manifest.xml.");
2868 memset(manifest, '\0', sizeof(manifest));
2869 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, USR_SHARE_PACKAGES, pkgid);
2870 _LOGD("#manifest name is %s", manifest);
2872 if (access(manifest, F_OK)) {
2873 _LOGE("@can not find manifest.xml in the pkg.");
2874 ret = RPM_INSTALLER_ERR_NO_MANIFEST;
2881 /* disable "copy ro-xml to rw-xml", because of some bug */
2882 snprintf(srcpath, BUF_SIZE, "%s", manifest);
2883 memset(manifest, '\0', sizeof(manifest));
2884 snprintf(manifest, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2886 const char *xml_update_argv[] = { CPIO_SCRIPT_UPDATE_XML, srcpath, manifest, NULL };
2887 ret = _ri_xsystem(xml_update_argv);
2893 /* send event for install_percent */
2894 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "30");
2896 /* check manifest.xml validation */
2897 ret = pkgmgr_parser_check_manifest_validation(manifest);
2899 _LOGE("@invalid manifest");
2900 ret = RPM_INSTALLER_ERR_INVALID_MANIFEST;
2904 /* check existance of res.xml for resource manager */
2905 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, USR_APPS, pkgid);
2906 _LOGD("#path of res.xml is %s", resxml);
2907 if (access(resxml, F_OK) != 0) {
2908 _LOGE("file not found. try other paths");
2909 memset(resxml, '\0', sizeof(resxml));
2910 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, OPT_USR_APPS, pkgid);
2911 if (access(resxml, F_OK) != 0) {
2912 _LOGE("file not found");
2913 memset(resxml, '\0', sizeof(resxml));
2917 if (resxml[0] != '\0') {
2918 if (access(resxml, R_OK) == 0) {
2920 ret = pkgmgr_resource_parser_check_xml_validation(resxml);
2922 _LOGE("pkgmgr_resource_parser_check_xml_validation(%s) failed.", resxml);
2923 ret = RPM_INSTALLER_ERR_INTERNAL;
2932 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
2933 _LOGE("@failed to change directory(%s)(%s)", cwd, buf);
2935 ret = RPM_INSTALLER_ERR_INTERNAL;
2938 #ifdef APP2EXT_ENABLE
2939 ret = __get_location_from_xml(manifest, &location);
2941 _LOGE("@Failed to get install location\n");
2942 ret = RPM_INSTALLER_ERR_INTERNAL;
2945 if (location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) {
2946 _LOGD("#Install: external storage location");
2948 /* Get the rpm's size from rpm header */
2949 rpm_size = _ri_calculate_rpm_size(pkgfilepath);
2950 if (rpm_size != 0) {
2951 rpm_size = rpm_size / (1024 * 1024); /* rpm size in MB */
2952 _LOGD("#Rpm file(%s) size is %lu MB", pkgfilepath, rpm_size);
2954 /* Add margin to the rpm size */
2955 rpm_size = rpm_size + RPM_SIZE_MARGIN(rpm_size);
2956 _LOGD("#Rpm file (%s) size after margin is %lu MB", pkgfilepath, rpm_size);
2958 _LOGE("@Failed to get size from rpm header\n");
2959 ret = RPM_INSTALLER_ERR_INTERNAL;
2963 /* Get the size from the manifest file. */
2964 ret = __get_size_from_xml(manifest, &size);
2965 if (ret != PMINFO_R_OK) {
2967 _LOGD(" #rpm size is %d MB", size);
2969 size = size > rpm_size ? size : rpm_size;
2970 _LOGD("#rpm size is %d MB", size);
2975 if ((location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) && size > 0) {
2976 handle = app2ext_init(APP2EXT_SD_CARD);
2977 if (handle == NULL) {
2978 _LOGE("@app2ext init failed\n");
2979 ret = RPM_INSTALLER_ERR_INTERNAL;
2982 if ((&(handle->interface) != NULL) && (handle->interface.pre_install != NULL)
2983 && (handle->interface.post_install != NULL)) {
2984 dir_list = __rpm_populate_dir_list();
2985 if (dir_list == NULL) {
2986 _LOGE("@ \nError in populating the directory list\n");
2987 app2ext_deinit(handle);
2988 ret = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
2991 ret = handle->interface.pre_install(gpkgname, dir_list, size);
2992 if (ret == APP2EXT_ERROR_MMC_STATUS) {
2993 _LOGE("@app2xt MMC is not here, go internal\n");
2994 } else if (ret == APP2EXT_SUCCESS) {
2995 _LOGE("@pre_install done, go internal\n");
2997 _LOGE("@app2xt pre install API failed (%d)\n", ret);
2998 __rpm_clear_dir_list(dir_list);
2999 handle->interface.post_install(gpkgname, APP2EXT_STATUS_FAILED);
3000 app2ext_deinit(handle);
3001 ret = RPM_INSTALLER_ERR_INTERNAL;
3009 if (home_dir == 0) {
3011 /* disable "INSTALL_SCRIPT_WITH_DBPATH_RO", because of some bug */
3012 const char *argv[] = { INSTALL_SCRIPT_WITH_DBPATH_RO, pkgfilepath, NULL };
3013 ret = _ri_xsystem(argv);
3015 const char *argv[] = { INSTALL_SCRIPT, pkgfilepath, NULL };
3016 ret = _ri_xsystem(argv);
3018 const char *argv[] = { INSTALL_SCRIPT_WITH_DBPATH_RW, pkgfilepath, NULL };
3019 ret = _ri_xsystem(argv);
3022 _LOGE("@failed to install the pkg(%d).", ret);
3023 #ifdef APP2EXT_ENABLE
3024 if ((handle != NULL) && (handle->interface.post_install != NULL)) {
3025 __rpm_clear_dir_list(dir_list);
3026 handle->interface.post_install(gpkgname, APP2EXT_STATUS_FAILED);
3027 app2ext_deinit(handle);
3032 _LOGD("#install success.");
3034 /* check for signature and certificate */
3035 ret = _ri_verify_signatures(TEMP_DIR, pkgid, true);
3037 _LOGE("@signature and certificate failed(%s).", pkgid);
3038 ret = RPM_INSTALLER_ERR_SIG_INVALID;
3041 _LOGD("#_ri_verify_signatures success.");
3043 /* write the storeclient-id to manifest.xml */
3044 if (clientid != NULL) {
3045 if (home_dir == 0) {
3046 snprintf(resultxml, BUF_SIZE, "%s/%s.xml", USR_SHARE_PACKAGES, pkgid);
3048 snprintf(resultxml, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
3051 const char *convert_argv[] = { RPM_UPDATE_XML, manifest, clientid, resultxml, NULL };
3052 ret = _ri_xsystem(convert_argv);
3054 _LOGE("@Failed to convert the manifest.xml");
3058 _LOGD("#client id[%s], input manifest:[%s], dest manifest:[%s]", clientid, manifest, resultxml);
3061 /* send event for install_percent */
3062 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "60");
3064 /* Parse the manifest to get install location and size.
3065 If installation fails, remove manifest info from DB */
3066 if (clientid != NULL) {
3067 ret = pkgmgr_parser_parse_manifest_for_installation(resultxml, NULL);
3069 ret = pkgmgr_parser_parse_manifest_for_installation(manifest, NULL);
3072 _LOGE("@failed to parse the manifest.");
3073 ret = RPM_INSTALLER_ERR_INTERNAL;
3076 _LOGD("#manifest parsing success");
3078 #ifdef APP2EXT_ENABLE
3079 if ((handle != NULL) && (handle->interface.post_install != NULL)) {
3080 __rpm_clear_dir_list(dir_list);
3081 handle->interface.post_install(gpkgname, APP2EXT_STATUS_SUCCESS);
3082 app2ext_deinit(handle);
3085 /* register cert info */
3086 _ri_register_cert(pkgid);
3089 _coretpk_installer_search_ui_gadget(pkgid);
3091 /* apply smack to shared dir */
3092 ret = __get_smack_label_from_db(pkgid, &smack_label);
3093 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
3095 __rpm_apply_smack(pkgid, 1, smack_label);
3097 /* apply smack by privilege */
3098 ret = _ri_apply_privilege(pkgid, 0, smack_label);
3100 _LOGE("@failed to apply permission(%d).", ret);
3102 _LOGD("#permission applying success.");
3105 ret = _ri_smack_reload_all();
3107 _LOGD("@failed to reload_all the smack.");
3110 /* send event for install_percent */
3111 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "100");
3113 ret = RPM_INSTALLER_SUCCESS;
3116 _installer_util_delete_dir(TEMP_DIR);
3117 _installer_util_delete_dir(TEMP_DBPATH);
3119 if (ret == RPM_INSTALLER_SUCCESS) {
3120 _LOGD("[#]end : _rpm_install_pkg_with_dbpath");
3121 __ri_launch_consumer(pkgid);
3122 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "ok");
3123 _ri_stat_cb(pkgid, "end", "ok");
3125 _LOGE("[@]end : _rpm_install_pkg_with_dbpath");
3126 /* remove db info */
3127 ret = _coretpk_installer_remove_db_info(pkgid);
3129 _LOGE("_coretpk_installer_remove_db_info is failed.");
3132 char *errstr = NULL;
3133 _ri_error_no_to_string(ret, &errstr);
3134 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "error", errstr);
3135 _ri_stat_cb(pkgid, "error", errstr);
3136 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "fail");
3138 _ri_stat_cb(pkgid, "end", "fail");
3139 _LOGE("install failed with err(%d) (%s)\n", ret, errstr);
3142 FREE_AND_NULL(smack_label);
3147 int _rpm_upgrade_pkg_with_dbpath(char *pkgfilepath, char *pkgid)
3150 char manifest[BUF_SIZE] = { '\0' };
3151 char cwd[BUF_SIZE] = { '\0' };
3153 pkgmgrinfo_pkginfo_h pkghandle;
3155 #ifdef APP2EXT_ENABLE
3156 app2ext_handle *handle = NULL;
3157 GList *dir_list = NULL;
3158 pkgmgrinfo_installed_storage location = 1;
3160 unsigned long rpm_size = 0;
3162 char *smack_label = NULL;
3163 char resxml[BUF_SIZE] = { '\0' };
3164 char buf[BUF_SIZE] = { 0, };
3166 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "start", "update");
3167 _LOGD("[#]start : _rpm_upgrade_pkg_with_dbpath");
3169 /* terminate running app */
3170 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3172 _LOGE("@failed to get pkginfo handle");
3173 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3176 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3177 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3180 temp = getcwd(cwd, BUF_SIZE);
3181 if ((temp == NULL) || (cwd[0] == '\0')) {
3182 _LOGE("@getcwd() failed.");
3183 ret = RPM_INSTALLER_ERR_INTERNAL;
3186 _LOGD("#current working directory is %s.", cwd);
3189 ret = __ri_change_dir(TEMP_DIR);
3191 _LOGE("@change dir failed.");
3192 ret = RPM_INSTALLER_ERR_INTERNAL;
3195 _LOGD("#switched to %s", TEMP_DIR);
3197 /* run cpio script */
3198 const char *cpio_argv[] = { CPIO_SCRIPT, pkgfilepath, NULL };
3199 ret = _ri_xsystem(cpio_argv);
3201 /* get manifext.xml path */
3202 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, OPT_SHARE_PACKAGES, pkgid);
3203 _LOGD("#manifest name is %s.", manifest);
3205 if (access(manifest, F_OK)) {
3206 _LOGD("#there is no RW manifest.xml. check RO manifest.xml.");
3208 memset(manifest, '\0', sizeof(manifest));
3209 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, USR_SHARE_PACKAGES, pkgid);
3210 _LOGD("#manifest name is %s.", manifest);
3212 if (access(manifest, F_OK)) {
3213 _LOGE("@can not find manifest.xml in the pkg.");
3214 ret = RPM_INSTALLER_ERR_NO_MANIFEST;
3221 /* disable "copy ro-xml to rw-xml", because of some bug */
3222 snprintf(srcpath, BUF_SIZE, "%s", manifest);
3223 memset(manifest, '\0', sizeof(manifest));
3224 snprintf(manifest, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
3226 const char *xml_update_argv[] = { CPIO_SCRIPT_UPDATE_XML, srcpath, manifest, NULL };
3227 ret = _ri_xsystem(xml_update_argv);
3233 /* check existance of res.xml for resource manager */
3234 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, USR_APPS, pkgid);
3235 _LOGD("#path of res.xml is %s", resxml);
3236 if (access(resxml, F_OK) != 0) {
3237 _LOGE("file not found. try other paths");
3238 memset(resxml, '\0', sizeof(resxml));
3239 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, OPT_USR_APPS, pkgid);
3240 if (access(resxml, F_OK) != 0) {
3241 _LOGE("file not found");
3242 memset(resxml, '\0', sizeof(resxml));
3246 if (resxml[0] != '\0') {
3247 if (access(resxml, R_OK) == 0) {
3249 ret = pkgmgr_resource_parser_check_xml_validation(resxml);
3251 _LOGE("pkgmgr_resource_parser_check_xml_validation(%s) failed.", resxml);
3252 ret = RPM_INSTALLER_ERR_INTERNAL;
3258 /* send event for install_percent */
3259 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "30");
3261 /* check manifest.xml validation */
3262 ret = pkgmgr_parser_check_manifest_validation(manifest);
3264 _LOGE("@invalid manifest");
3265 ret = RPM_INSTALLER_ERR_INVALID_MANIFEST;
3269 /* check for signature and certificate */
3270 ret = _ri_verify_signatures(TEMP_DIR, pkgid, true);
3272 _LOGE("@signature and certificate failed(%s).", pkgid);
3273 ret = RPM_INSTALLER_ERR_SIG_INVALID;
3276 _LOGD("#_ri_verify_signatures success.");
3281 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
3282 _LOGE("@chdir(%s) failed(%s).", cwd, buf);
3284 ret = RPM_INSTALLER_ERR_INTERNAL;
3288 /* remove dir for clean */
3289 __ri_remove_updated_dir(pkgid);
3291 _LOGD("#Preserve the smack file");
3292 /* Preserve the smack rule file */
3293 ret = __ri_copy_smack_rule_file(UPGRADE_REQ, pkgid, 0);
3294 if (ret != RPM_INSTALLER_SUCCESS)
3297 #ifdef APP2EXT_ENABLE
3298 ret = pkgmgrinfo_pkginfo_get_pkginfo(gpkgname, &pkghandle);
3300 _LOGE("Failed to get pkginfo handle\n");
3301 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3305 ret = pkgmgrinfo_pkginfo_get_installed_storage(pkghandle, &location);
3307 _LOGE("Failed to get install location\n");
3308 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3309 ret = RPM_INSTALLER_ERR_INTERNAL;
3313 if (location == PMINFO_EXTERNAL_STORAGE) {
3314 /* Get the rpm's size from rpm header */
3315 rpm_size = _ri_calculate_rpm_size(pkgfilepath);
3316 if (rpm_size == 0) {
3317 _LOGE("@Failed to get size from rpm header\n");
3318 ret = RPM_INSTALLER_ERR_INTERNAL;
3321 rpm_size = rpm_size / (1024 * 1024); /* rpm size in MB */
3322 _LOGD("#Rpm file(%s) size is %lu MB", pkgfilepath, rpm_size);
3324 /* Add margin to the rpm size */
3325 rpm_size = rpm_size + RPM_SIZE_MARGIN(rpm_size);
3326 _LOGD("#Rpm file (%s) size after margin is %lu MB", pkgfilepath, rpm_size);
3328 /* Get the size from the manifest file. */
3329 ret = __get_size_from_xml(manifest, &size);
3330 if (ret != PMINFO_R_OK) {
3332 _LOGD(" #rpm size is %d", size);
3334 size = size > rpm_size ? size : rpm_size;
3335 _LOGD("#rpm size is %d", size);
3339 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3341 if ((location == PMINFO_EXTERNAL_STORAGE) && size > 0) {
3342 handle = app2ext_init(APP2EXT_SD_CARD);
3343 if (handle == NULL) {
3344 _LOGE("app2ext init failed\n");
3345 ret = RPM_INSTALLER_ERR_INTERNAL;
3349 if ((&(handle->interface) != NULL) && (handle->interface.pre_upgrade != NULL)
3350 && (handle->interface.post_upgrade != NULL)) {
3351 dir_list = __rpm_populate_dir_list();
3352 if (dir_list == NULL) {
3353 _LOGE("\nError in populating the directory list\n");
3354 ret = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
3355 app2ext_deinit(handle);
3358 ret = handle->interface.pre_upgrade(gpkgname, dir_list, size);
3359 if (ret == APP2EXT_ERROR_MMC_STATUS) {
3360 _LOGE("app2xt MMC is not here, go internal (%d)\n", ret);
3361 } else if (ret == APP2EXT_SUCCESS) {
3362 _LOGE("pre upgrade done, go internal");
3364 _LOGE("app2xt pre upgrade API failed (%d)\n", ret);
3365 __rpm_clear_dir_list(dir_list);
3366 handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_FAILED);
3367 ret = RPM_INSTALLER_ERR_INTERNAL;
3368 app2ext_deinit(handle);
3376 if (home_dir == 0) {
3378 /* disable "UPGRADE_SCRIPT_WITH_DBPATH_RO", because of some bug */
3379 const char *argv[] = { UPGRADE_SCRIPT_WITH_DBPATH_RO, pkgfilepath, NULL };
3380 ret = _ri_xsystem(argv);
3382 const char *argv[] = { UPGRADE_SCRIPT, pkgfilepath, NULL };
3383 ret = _ri_xsystem(argv);
3385 const char *argv[] = { UPGRADE_SCRIPT_WITH_DBPATH_RW, pkgfilepath, NULL };
3386 ret = _ri_xsystem(argv);
3389 _LOGE("@upgrade complete with error(%d)", ret);
3390 #ifdef APP2EXT_ENABLE
3391 if ((handle != NULL) && (handle->interface.post_upgrade != NULL)) {
3392 __rpm_clear_dir_list(dir_list);
3393 handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_FAILED);
3394 app2ext_deinit(handle);
3399 _LOGD("#upgrade script success.");
3401 /* send event for install_percent */
3402 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "60");
3404 /* Parse the manifest to get install location and size.
3405 If fails, remove manifest info from DB. */
3406 ret = pkgmgr_parser_parse_manifest_for_upgrade(manifest, NULL);
3408 _LOGE("@parsing manifest failed.");
3409 ret = RPM_INSTALLER_ERR_INTERNAL;
3412 _LOGD("#parsing manifest success.");
3414 /* unregister cert info */
3415 _ri_unregister_cert(pkgid);
3417 /* register cert info */
3418 _ri_register_cert(pkgid);
3420 #ifdef APP2EXT_ENABLE
3421 if ((handle != NULL) && (handle->interface.post_upgrade != NULL)) {
3422 __rpm_clear_dir_list(dir_list);
3423 handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_SUCCESS);
3424 app2ext_deinit(handle);
3429 _coretpk_installer_search_ui_gadget(pkgid);
3431 /* apply smack to shared dir */
3432 ret = __get_smack_label_from_db(pkgid, &smack_label);
3433 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
3435 __rpm_apply_smack(pkgid, 1, smack_label);
3437 /* apply smack by privilege */
3438 ret = _ri_apply_privilege(pkgid, 0, smack_label);
3440 _LOGE("@apply perm failed with err(%d)", ret);
3442 _LOGD("#apply perm success.");
3445 ret = _ri_smack_reload_all();
3447 _LOGD("_ri_smack_reload_all failed.");
3450 /* send event for install_percent */
3451 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "100");
3453 ret = RPM_INSTALLER_SUCCESS;
3456 _installer_util_delete_dir(TEMP_DIR);
3457 _installer_util_delete_dir(TEMP_DBPATH);
3459 if (ret == RPM_INSTALLER_SUCCESS) {
3460 _LOGD("[#]end : _rpm_upgrade_pkg_with_dbpath");
3461 __ri_launch_consumer(pkgid);
3462 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "ok");
3463 _ri_stat_cb(pkgid, "end", "ok");
3465 _LOGE("[@]end : _rpm_upgrade_pkg_with_dbpath");
3466 char *errstr = NULL;
3467 _ri_error_no_to_string(ret, &errstr);
3468 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "error", errstr);
3469 _ri_stat_cb(pkgid, "error", errstr);
3470 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "fail");
3472 _ri_stat_cb(pkgid, "end", "fail");
3473 _LOGE("install failed with err(%d) (%s)\n", ret, errstr);
3476 FREE_AND_NULL(smack_label);
3481 int _rpm_uninstall_pkg_with_dbpath(const char *pkgid, bool is_system)
3483 if (pkgid == NULL) {
3484 _LOGE("pkgid is NULL.");
3485 return RPM_INSTALLER_ERR_WRONG_PARAM;
3490 char buff[BUF_SIZE] = { '\0' };
3491 char extpath[BUF_SIZE] = { '\0' };
3492 char tizen_manifest[BUF_SIZE] = { '\0' };
3493 pkgmgrinfo_pkginfo_h pkghandle = NULL;
3494 bool mother_package = false;
3495 bool coretpk = false;
3496 GList *appid_list = NULL;
3498 #ifdef APP2EXT_ENABLE
3499 app2ext_handle *handle = NULL;
3500 pkgmgrinfo_installed_storage location = 1;
3502 char *smack_label = NULL;
3504 _LOGD("pkgid=[%s], is_system=[%d]", pkgid, is_system);
3506 snprintf(tizen_manifest, BUF_SIZE, "%s/%s/tizen-manifest.xml", OPT_USR_APPS, pkgid);
3507 if (access(tizen_manifest, R_OK) == 0) {
3509 _LOGD("[%s] is existing.", tizen_manifest);
3512 /* send start event */
3514 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "start", "update");
3516 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "start", "uninstall");
3519 /* terminate running app */
3520 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3522 _LOGE("pkgmgrinfo_pkginfo_get_pkginfo(%s) failed.", pkgid);
3523 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3526 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, &appid_list);
3528 while (appid_list != NULL) {
3529 _ri_broadcast_app_uninstall_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, (char *)appid_list->data);
3531 if (appid_list->next == NULL)
3534 appid_list = g_list_next(appid_list);
3537 /* If package is mother package, then uninstall child package */
3538 pkgmgrinfo_pkginfo_is_mother_package(pkghandle, &mother_package);
3539 if (mother_package == true) {
3540 _LOGD("[%s] is mother package", pkgid);
3541 __uninstall_child_package_by_mother_pkgid(pkgid);
3543 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3545 ret = __get_smack_label_from_db(pkgid, &smack_label);
3546 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
3548 /* del root path dir */
3549 snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
3550 if (__is_dir(buff)) {
3551 _installer_util_delete_dir(buff);
3554 /* del root path dir for ext */
3555 snprintf(extpath, BUF_SIZE, "%s/%s", OPT_STORAGE_SDCARD_APP_ROOT, pkgid);
3556 if (__is_dir(extpath)) {
3557 _installer_util_delete_dir(extpath);
3561 memset(buff, '\0', BUF_SIZE);
3562 snprintf(buff, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
3565 /* check system pkg, if pkg is system pkg, need to update xml on USR_SHARE_PACKAGES */
3567 memset(buff, '\0', BUF_SIZE);
3568 snprintf(buff, BUF_SIZE, "%s/%s.xml", USR_SHARE_PACKAGES, pkgid);
3569 _LOGE("manifest for upgrade, path=[%s]", buff);
3571 ret = pkgmgr_parser_parse_manifest_for_upgrade(buff, NULL);
3573 _LOGE("parsing manifest failed.");
3577 #ifdef APP2EXT_ENABLE
3578 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3580 _LOGE("failed to get pkginfo handle");
3581 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3584 ret = pkgmgrinfo_pkginfo_get_installed_storage(pkghandle, &location);
3586 _LOGE("failed to get install location\n");
3587 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3588 ret = RPM_INSTALLER_ERR_INTERNAL;
3591 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3593 if (location == PMINFO_EXTERNAL_STORAGE) {
3594 handle = app2ext_init(APP2EXT_SD_CARD);
3595 if (handle == NULL) {
3596 _LOGE("app2ext init failed\n");
3597 ret = RPM_INSTALLER_ERR_INTERNAL;
3600 if ((&(handle->interface) != NULL) && (handle->interface.pre_uninstall != NULL) &&
3601 (handle->interface.post_uninstall != NULL) &&
3602 (handle->interface.disable != NULL)) {
3603 ret = handle->interface.disable(pkgid);
3604 if (ret != APP2EXT_SUCCESS) {
3605 _LOGE("Unmount ret[%d]", ret);
3607 ret = app2ext_get_app_location(pkgid);
3608 if (ret == APP2EXT_INTERNAL_MEM) {
3609 _LOGE("app2xt APP is not in MMC, go internal (%d)\n", ret);
3611 ret = handle->interface.pre_uninstall(pkgid);
3612 if (ret == APP2EXT_ERROR_MMC_STATUS) {
3613 _LOGE("app2xt MMC is not here, go internal (%d)\n", ret);
3614 } else if (ret == APP2EXT_SUCCESS) {
3615 _LOGE("pre uninstall done, go to internal");
3617 _LOGE("app2xt pre uninstall API failed (%d)\n", ret);
3618 handle->interface.post_uninstall(pkgid);
3619 app2ext_deinit(handle);
3620 ret = RPM_INSTALLER_ERR_INTERNAL;
3629 ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
3631 _LOGE("pkgmgr_parser_parse_manifest_for_uninstallation() failed, pkgid=[%s]", pkgid);
3634 #ifdef APP2EXT_ENABLE
3635 if ((handle != NULL) && (handle->interface.post_uninstall != NULL)) {
3636 handle->interface.post_uninstall(pkgid);
3637 app2ext_deinit(handle);
3642 /* execute privilege APIs */
3643 _ri_privilege_revoke_permissions(smack_label);
3644 _ri_privilege_unregister_package(smack_label);
3646 /* Unregister cert info */
3647 _ri_unregister_cert(pkgid);
3649 ret = RPM_INSTALLER_SUCCESS;
3652 /* Free appid list */
3653 appid_list = g_list_first(appid_list);
3654 while (appid_list != NULL) {
3655 if (appid_list->data != NULL) {
3656 free(appid_list->data);
3659 if (appid_list->next == NULL)
3662 appid_list = g_list_next(appid_list);
3664 g_list_free(appid_list);
3666 /* Restore the old smack file */
3667 if (coretpk == false) {
3668 tmp = __ri_copy_smack_rule_file(UNINSTALL_REQ, pkgid, is_system);
3669 if (tmp != RPM_INSTALLER_SUCCESS) {
3670 _LOGD("smack restore failed");
3674 tmp = _ri_smack_reload_all();
3676 _LOGD("_ri_smack_reload_all failed.");
3683 _LOGE("failed, ret=[%d]", ret);
3684 char *errstr = NULL;
3685 _ri_error_no_to_string(ret, &errstr);
3686 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "error", errstr);
3687 _ri_stat_cb(pkgid, "error", errstr);
3689 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "end", "fail");
3690 _ri_stat_cb(pkgid, "end", "fail");
3691 _LOGE("remove failed with err(%d) (%s)\n", ret, errstr);
3694 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "end", "ok");
3695 _ri_stat_cb(pkgid, "end", "ok");
3698 FREE_AND_NULL(smack_label);
3703 int _rpm_uninstall_pkg(char *pkgid)
3708 bool is_removable = 0;
3709 pkgmgrinfo_install_location location = 1;
3710 #ifdef APP2EXT_ENABLE
3711 app2ext_handle *handle = NULL;
3713 #ifdef PRE_CHECK_FOR_MANIFEST
3714 char *manifest = NULL;
3717 char *smack_label = NULL;
3719 pkgmgrinfo_pkginfo_h pkghandle;
3720 const char *argv[] = { UNINSTALL_SCRIPT, pkgid, NULL };
3722 _LOGD("start : _rpm_uninstall_pkg\n");
3724 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3726 _LOGE("Failed to get pkginfo handle\n");
3727 return RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3729 /* terminate running app */
3730 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3732 ret = pkgmgrinfo_pkginfo_is_system(pkghandle, &is_system);
3734 _LOGE("pkgmgrinfo_pkginfo_is_system failed.\n");
3735 return RPM_INSTALLER_ERR_INTERNAL;
3738 ret = pkgmgrinfo_pkginfo_is_update(pkghandle, &is_update);
3740 _LOGE("pkgmgrinfo_pkginfo_is_system failed.\n");
3741 return RPM_INSTALLER_ERR_INTERNAL;
3744 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3745 /* updated and system pkg need to "remove-update" */
3746 _LOGD("Remove Update[%s]", pkgid);
3747 ret = _rpm_uninstall_pkg_with_dbpath(pkgid, 1);
3749 _LOGE("uninstall_pkg_with_dbpath for system, is_update fail\n");
3754 pkgmgrinfo_pkginfo_is_removable(pkghandle, &is_removable);
3756 /* non-system and can be removable, it should be deleted */
3757 _LOGD("Delete Package [%s]", pkgid);
3758 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3759 ret = _rpm_uninstall_pkg_with_dbpath(pkgid, 0);
3761 _LOGE("uninstall_pkg_with_dbpath for non-system, is_remove fail\n");
3767 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "start", "uninstall");
3769 #ifdef APP2EXT_ENABLE
3770 ret = pkgmgrinfo_pkginfo_get_install_location(pkghandle, &location);
3772 _LOGE("Failed to get install location\n");
3773 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3774 return RPM_INSTALLER_ERR_INTERNAL;
3777 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3779 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3780 if (location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) {
3781 handle = app2ext_init(APP2EXT_SD_CARD);
3782 if (handle == NULL) {
3783 _LOGE("app2ext init failed\n");
3784 return RPM_INSTALLER_ERR_INTERNAL;
3786 if ((&(handle->interface) != NULL) && (handle->interface.pre_uninstall != NULL) &&
3787 (handle->interface.post_uninstall != NULL)) {
3788 ret = app2ext_get_app_location(pkgid);
3789 if (ret == APP2EXT_INTERNAL_MEM) {
3790 _LOGE("app2xt APP is not in MMC, go internal (%d)\n", ret);
3792 ret = handle->interface.pre_uninstall(pkgid);
3793 if (ret == APP2EXT_ERROR_MMC_STATUS || ret == APP2EXT_SUCCESS) {
3794 _LOGE("app2xt MMC is not here, go internal (%d)\n", ret);
3796 _LOGE("app2xt pre uninstall API failed (%d)\n", ret);
3797 handle->interface.post_uninstall(pkgid);
3798 app2ext_deinit(handle);
3799 return RPM_INSTALLER_ERR_INTERNAL;
3806 ret = __get_smack_label_from_db(pkgid, &smack_label);
3807 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
3809 #ifdef PRE_CHECK_FOR_MANIFEST
3810 /* Manifest info should be removed first because after installation manifest
3811 file is uninstalled. If uninstallation fails, we need to re-insert manifest info for consistency */
3812 manifest = pkgmgr_parser_get_manifest_file(pkgid);
3813 if (manifest == NULL) {
3814 _LOGE("manifest name is NULL\n");
3815 app2ext_deinit(handle);
3816 FREE_AND_NULL(smack_label);
3817 return RPM_INSTALLER_ERR_NO_MANIFEST;
3819 _LOGD("manifest name is %s\n", manifest);
3820 ret = pkgmgr_parser_parse_manifest_for_uninstallation(manifest, NULL);
3822 _LOGE("pkgmgr_parser_parse_manifest_for_uninstallation failed.\n");
3826 ret = _rpm_xsystem(argv);
3828 _LOGE("uninstall failed with error(%d)\n", ret);
3829 #ifdef PRE_CHECK_FOR_MANIFEST
3830 err = pkgmgr_parser_parse_manifest_for_installation(manifest, NULL);
3832 _LOGE("Parsing Manifest Failed\n");
3835 FREE_AND_NULL(manifest);
3837 #ifdef APP2EXT_ENABLE
3838 if ((handle != NULL) && (handle->interface.post_uninstall != NULL)) {
3839 handle->interface.post_uninstall(pkgid);
3840 app2ext_deinit(handle);
3844 FREE_AND_NULL(smack_label);
3848 #ifdef APP2EXT_ENABLE
3849 if ((handle != NULL) && (handle->interface.post_uninstall != NULL)) {
3850 handle->interface.post_uninstall(pkgid);
3851 app2ext_deinit(handle);
3855 /* execute privilege APIs */
3856 _ri_privilege_revoke_permissions(smack_label);
3857 _ri_privilege_unregister_package(smack_label);
3859 /* Unregister cert info */
3860 _ri_unregister_cert(gpkgname);
3862 FREE_AND_NULL(manifest);
3863 FREE_AND_NULL(smack_label);
3865 _LOGD("end : _rpm_uninstall_pkg(%d)\n", ret);
3870 int _rpm_install_corexml(const char *pkgfilepath, char *pkgid)
3874 /* validate signature and certifictae */
3875 ret = _ri_verify_signatures(USR_APPS, pkgid, true);
3877 _LOGE("_ri_verify_signatures Failed : %s\n", pkgid);
3878 ret = RPM_INSTALLER_ERR_SIG_INVALID;
3882 /* Parse and insert manifest in DB */
3883 ret = pkgmgr_parser_parse_manifest_for_installation(pkgfilepath, NULL);
3885 _LOGD("Installing Manifest Failed : %s\n", pkgfilepath);
3886 ret = RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED;
3890 /* _ri_register_cert has __ri_free_cert_chain. */
3891 _ri_register_cert(pkgid);
3894 _coretpk_installer_search_ui_gadget(pkgid);
3896 ret = RPM_INSTALLER_SUCCESS;
3900 __ri_free_cert_chain();
3906 int _rpm_move_pkg(char *pkgid, int move_type)
3908 app2ext_handle *hdl = NULL;
3911 GList *dir_list = NULL;
3912 pkgmgrinfo_pkginfo_h pkghandle = NULL;
3914 if (move_type == PM_MOVE_TO_INTERNAL)
3915 movetype = APP2EXT_MOVE_TO_PHONE;
3916 else if (move_type == PM_MOVE_TO_SDCARD)
3917 movetype = APP2EXT_MOVE_TO_EXT;
3919 return RPM_INSTALLER_ERR_WRONG_PARAM;
3921 ret = pkgmgrinfo_pkginfo_get_pkginfo(gpkgname, &pkghandle);
3923 _LOGE("@failed to get the pkginfo handle!!");
3924 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3928 /* Terminate the running instance of app */
3929 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3930 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3931 hdl = app2ext_init(APP2EXT_SD_CARD);
3932 if ((hdl != NULL) && (hdl->interface.move != NULL)) {
3933 dir_list = __rpm_populate_dir_list();
3934 if (dir_list == NULL) {
3935 _LOGE("\nError in populating the directory list\n");
3936 return RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
3938 ret = hdl->interface.move(pkgid, dir_list, movetype);
3939 __rpm_clear_dir_list(dir_list);
3941 _LOGE("Failed to move app\n");
3942 return RPM_INSTALLER_ERR_INTERNAL;
3944 app2ext_deinit(hdl);
3945 return RPM_INSTALLER_SUCCESS;
3947 _LOGE("Failed to get app2ext handle\n");
3948 return RPM_INSTALLER_ERR_INTERNAL;
3952 int _rpm_process_cscxml(char *csc_script)
3957 char *path_str = NULL;
3958 char *op_str = NULL;
3959 char *remove_str = NULL;
3960 char csc_str[BUF_SIZE] = { '\0' };
3961 snprintf(csc_str, BUF_SIZE - 1, "%s:", csc_script);
3963 /* get params from csc script */
3964 path_str = _installer_util_get_str(csc_str, TOKEN_PATH_STR);
3965 op_str = _installer_util_get_str(csc_str, TOKEN_OPERATION_STR);
3966 remove_str = _installer_util_get_str(csc_str, TOKEN_REMOVE_STR);
3967 if ((path_str == NULL) || (op_str == NULL) || (remove_str == NULL)) {
3968 _LOGE("csc-info : input param is null[%s, %s, %s]\n", path_str, op_str, remove_str);
3971 _LOGD("csc-info : path=%s, op=%s, remove=%s\n", path_str, op_str, remove_str);
3973 /* get operation type */
3974 op_type = __ri_get_op_type(op_str);
3976 _LOGE("csc-info : operation error[%s, %s]\n", path_str, op_str);
3982 ret = __ri_install_csc(path_str, remove_str);
3986 ret = __ri_install_csc(path_str, remove_str);
3990 ret = __ri_uninstall_csc(path_str);
3998 _LOGE("fota-info : Fota fail [pkgid=%s, operation=%d]\n", path_str, op_type);
4011 int _rpm_process_csc_coretpk(const char *csc_script)
4016 char *path_str = NULL;
4017 char *op_str = NULL;
4018 char *remove_str = NULL;
4019 char csc_str[BUF_SIZE] = { '\0' };
4020 snprintf(csc_str, BUF_SIZE - 1, "%s:", csc_script);
4022 /* get params from csc script */
4023 path_str = _installer_util_get_str(csc_str, TOKEN_PATH_STR);
4024 op_str = _installer_util_get_str(csc_str, TOKEN_OPERATION_STR);
4025 remove_str = _installer_util_get_str(csc_str, TOKEN_REMOVE_STR);
4026 if ((path_str == NULL) || (op_str == NULL) || (remove_str == NULL)) {
4027 _LOGE("csc-info : input param is null[%s, %s, %s]\n", path_str, op_str, remove_str);
4030 _LOGD("csc-info : path=%s, op=%s, remove=%s\n", path_str, op_str, remove_str);
4032 /* get operation type */
4033 op_type = __ri_get_op_type(op_str);
4035 _LOGE("csc-info : operation error[%s, %s]\n", path_str, op_str);
4041 ret = _coretpk_installer_csc_install(path_str, remove_str, csc_script);
4045 ret = _coretpk_installer_csc_upgrade(path_str, remove_str, csc_script);
4049 ret = _coretpk_installer_csc_uninstall(path_str);
4057 _LOGE("csc-info : csc fail [pkgid=%s, operation=%d]\n", path_str, op_type);
4070 int _rpm_process_fota(char *fota_script)
4075 char *op_str = NULL;
4077 char csc_str[BUF_SIZE] = { '\0' };
4078 snprintf(csc_str, BUF_SIZE - 1, "%s:", fota_script);
4080 /* get params from fota script */
4081 pkgid = _installer_util_get_str(csc_str, TOKEN_PATH_STR);
4082 op_str = _installer_util_get_str(csc_str, TOKEN_OPERATION_STR);
4083 if ((pkgid == NULL) || (op_str == NULL)) {
4084 _LOGE("fota-info : input param is null[%s, %s]\n", pkgid, op_str);
4087 _LOGD("fota-info : path=%s, op=%s\n", pkgid, op_str);
4089 /* get operation type */
4090 op_type = __ri_get_op_type(op_str);
4092 _LOGE("fota-info : operation error[%s, %s]\n", pkgid, op_str);
4098 ret = __ri_install_fota(pkgid);
4102 ret = __ri_upgrade_fota(pkgid);
4106 ret = __ri_uninstall_fota(pkgid);
4114 _LOGE("fota-info : Fota fail [pkgid=%s, operation=%d]\n", pkgid, op_type);
4125 int _rpm_process_fota_for_rw(char *fota_script)
4130 char *op_str = NULL;
4132 char fota_str[BUF_SIZE] = { '\0' };
4133 snprintf(fota_str, BUF_SIZE - 1, "%s:", fota_script);
4135 /* get params from fota script */
4136 pkgid = _installer_util_get_str(fota_str, TOKEN_PATH_STR);
4137 op_str = _installer_util_get_str(fota_str, TOKEN_OPERATION_STR);
4138 if ((pkgid == NULL) || (op_str == NULL)) {
4139 _LOGE("fota-info : input param is null[%s, %s]\n", pkgid, op_str);
4142 _LOGD("fota-info : path=%s, op=%s\n", pkgid, op_str);
4144 /* get operation type */
4145 op_type = __ri_get_op_type(op_str);
4147 _LOGE("fota-info : operation error[%s, %s]\n", pkgid, op_str);
4153 ret = __ri_install_fota_for_rw(pkgid);
4157 ret = __ri_upgrade_fota_for_rw(pkgid);
4161 ret = __ri_uninstall_fota_for_rw(pkgid);
4169 _LOGE("fota-info : Fota fail [pkgid=%s, operation=%d]\n", pkgid, op_type);
4182 int __ri_copy_smack_rule_file(int op, const char *pkgname, int is_system)
4184 mode_t mode = DIR_PERMS;
4185 int ret = RPM_INSTALLER_SUCCESS;
4186 char src[BUF_SIZE] = { 0 };
4187 char dest[BUF_SIZE] = { 0 };
4188 char buf[BUF_SIZE] = { 0, };
4192 /* For downloadable native app, restore the smack file.
4193 Otherwise, remove the stored smack file. */
4194 snprintf(dest, BUF_SIZE - 1, "%s/%s.rule", SMACK_RULES_ALT_PATH, pkgname);
4195 snprintf(src, BUF_SIZE - 1, "%s%s.rule", DIR_RPM_WGT_SMACK_RULE_OPT, pkgname);
4196 _LOGD("#src:[%s] dest:[%s]", src, dest);
4199 if (!access(src, F_OK)) {
4202 _LOGD("#File [%s] deleted.", src);
4204 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
4205 _LOGE("@Unable to delete the file [%s], error:(%s)", src, buf);
4207 ret = RPM_INSTALLER_ERR_INTERNAL;
4211 if (!access(dest, F_OK)) {
4214 _LOGD("#File [%s] deleted.", dest);
4216 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
4217 _LOGE("@Unable to delete the file [%s], error:(%s)", dest, buf);
4219 ret = RPM_INSTALLER_ERR_INTERNAL;
4224 _LOGD("#Restore smack files for uninstallation [%s]", pkgname);
4225 if (!access(src, F_OK)) {
4226 _LOGD("#Copying [%s] to [%s]", src, dest);
4227 ret = __copy_file(src, dest);
4231 _LOGD("#File [%s] deleted.", src);
4233 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
4234 _LOGE("@Unable to delete the file [%s], error:(%s)", src, buf);
4236 ret = RPM_INSTALLER_ERR_INTERNAL;
4240 _LOGE("@Copy Failed!!");
4241 ret = RPM_INSTALLER_ERR_INTERNAL;
4245 _LOGE("@ %s.rule file is not preserved", pkgname);
4250 _LOGD("#Preserve the smack file for upgrade [%s]", pkgname);
4252 /* Apply the new smack file and preserve the old smack rule file
4253 if it is not preserved. */
4254 snprintf(src, BUF_SIZE - 1, "%s/%s.rule", SMACK_RULES_ALT_PATH, pkgname);
4255 snprintf(dest, BUF_SIZE - 1, "%s%s.rule", DIR_RPM_WGT_SMACK_RULE_OPT, pkgname);
4257 _LOGD("#src[%s] dest[%s]", src, dest);
4259 /* Create the directory if not exist to preserve the smack files */
4260 if (mkdir(DIR_RPM_WGT_SMACK_RULE_OPT, mode) == 0 || errno == EEXIST) {
4261 if ((access(src, F_OK) == 0) && (access(dest, F_OK) != 0)) {
4262 ret = __copy_file(src, dest);
4264 _LOGD("#Smack file is already preserved");
4267 _LOGE("@Temporary folder creation failed");
4268 ret = RPM_INSTALLER_ERR_INTERNAL;
4272 _LOGE("@Unsupported Operation\n");
4273 ret = RPM_INSTALLER_ERR_INTERNAL;
4279 int __get_smack_label_from_xml(const char *manifest, const char *pkgid, char **label)
4281 const char *val = NULL;
4282 char pkgpath[BUF_SIZE] = { '\0' };
4283 const xmlChar *node;
4284 xmlTextReaderPtr reader;
4285 int ret = PMINFO_R_OK;
4287 if (label == NULL) {
4288 _LOGE("space for label is NULL\n");
4289 return PMINFO_R_ERROR;
4294 if (pkgid == NULL) {
4295 _LOGE("pkgid is NULL\n");
4296 return PMINFO_R_ERROR;
4299 if (manifest == NULL) {
4300 _LOGE("manifest is NULL\n");
4301 *label = strdup(pkgid);
4302 return PMINFO_R_ERROR;
4305 snprintf(pkgpath, BUF_SIZE, "%s/%s/tizen-manifest.xml", OPT_USR_APPS, pkgid);
4306 if (access(pkgpath, R_OK) == 0) {
4307 _LOGE("This is a core tpk package");
4308 *label = strdup(pkgid);
4312 reader = xmlReaderForFile(manifest, NULL, 0);
4315 if (_child_element(reader, -1)) {
4316 node = xmlTextReaderConstName(reader);
4318 _LOGE("xmlTextReaderConstName value is NULL\n");
4319 ret = PMINFO_R_ERROR;
4323 if (!strcmp(ASCII(node), "manifest")) {
4324 ret = _ri_get_attribute(reader, "smack-label", &val);
4326 _LOGE("@Error in getting the attribute value");
4327 ret = PMINFO_R_ERROR;
4331 *label = strdup(val);
4332 if (*label == NULL) {
4333 _LOGE("Out of memeory\n");
4334 ret = PMINFO_R_ERROR;
4339 _LOGE("package smack-label is not specified\n");
4343 _LOGE("Unable to create xml reader\n");
4344 ret = PMINFO_R_ERROR;
4349 _LOGE("xmlReaderForFile value is NULL\n");
4350 ret = PMINFO_R_ERROR;
4355 xmlFreeTextReader(reader);
4357 if (*label == NULL) {
4358 *label = strdup(pkgid);
4364 int __get_smack_label_from_db(const char *pkgid, char **label)
4366 char *smack_label = NULL;
4367 pkgmgrinfo_pkginfo_h handle = NULL;
4368 int ret = PMINFO_R_OK;
4370 if (label == NULL) {
4371 _LOGE("space for label is NULL\n");
4372 return PMINFO_R_ERROR;
4377 if (pkgid == NULL) {
4378 _LOGE("pkgid is NULL\n");
4379 return PMINFO_R_ERROR;
4382 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
4383 if (ret != PMINFO_R_OK) {
4384 _LOGE("failed to get pkginfo\n");
4385 ret = PMINFO_R_ERROR;
4388 ret = pkgmgrinfo_pkginfo_get_custom_smack_label(handle, &smack_label);
4389 if (ret != PMINFO_R_OK) {
4390 _LOGE("failed to get custom smack_label\n");
4391 ret = PMINFO_R_ERROR;
4395 _LOGD("smack_label(%s)\n", smack_label);
4397 *label = strdup(smack_label);
4401 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
4403 if (*label == NULL) {
4404 *label = strdup(pkgid);