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 _SLOGE("[%s(%d)] : [%s] : [%s] : [%d] : [%s]", func, line, errorObject, errorSubject, reason, msg);
296 static int __ri_verify_file(xmlSecKeysMngrPtr sec_key_mngr, const char *sigxmlfile)
298 xmlDocPtr doc = NULL;
299 xmlNodePtr node = NULL;
300 xmlSecDSigCtxPtr dsigCtx = NULL;
302 if (sigxmlfile == NULL)
304 if (sec_key_mngr == NULL)
307 /* set error callback to xmlsec1 */
308 xmlSecErrorsSetCallback(__ri_xmlsec_debug_print);
311 doc = xmlParseFile(sigxmlfile);
312 if ((doc == NULL) || (xmlDocGetRootElement(doc) == NULL)) {
313 _LOGE("unable to parse file \"%s\"\n", sigxmlfile);
316 /* find start node */
317 node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
319 _LOGE("start node not found in \"%s\"\n", sigxmlfile);
322 /* create signature context */
323 dsigCtx = xmlSecDSigCtxCreate(sec_key_mngr);
324 if (dsigCtx == NULL) {
325 _LOGE("failed to create signature context\n");
328 /* Verify signature */
329 if (xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
330 _LOGE("failed to verify signature\n");
333 /* print verification result to stdout */
334 if (dsigCtx->status == xmlSecDSigStatusSucceeded) {
336 _LOGD("valid signature");
339 _LOGD("invalid signature");
344 if (dsigCtx != NULL) {
345 xmlSecDSigCtxDestroy(dsigCtx);
353 static xmlSecKeysMngrPtr __ri_load_trusted_certs(char *files, int files_size)
355 xmlSecKeysMngrPtr sec_key_mngr;
362 sec_key_mngr = xmlSecKeysMngrCreate();
363 if (sec_key_mngr == NULL) {
364 _LOGE("failed to create keys manager.\n");
368 if (xmlSecCryptoAppDefaultKeysMngrInit(sec_key_mngr) < 0) {
369 _LOGE("failed to initialize keys manager.\n");
370 xmlSecKeysMngrDestroy(sec_key_mngr);
374 /* load trusted cert */
375 if (xmlSecCryptoAppKeysMngrCertLoad(sec_key_mngr, files, xmlSecKeyDataFormatPem, xmlSecKeyDataTypeTrusted) < 0) {
376 _LOGE("failed to load pem certificate from \"%s\"\n", files);
377 xmlSecKeysMngrDestroy(sec_key_mngr);
384 static int __ri_xmlsec_verify_signature(const char *sigxmlfile, char *rootca)
387 xmlSecKeysMngrPtr sec_key_mngr = NULL;
388 xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
389 xmlSubstituteEntitiesDefault(1);
391 #ifndef XMLSEC_NO_XSLT
392 xmlIndentTreeOutput = 1;
393 xsltSecurityPrefsPtr sec_prefs = xsltNewSecurityPrefs();
394 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid);
395 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid);
396 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid);
397 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid);
398 xsltSetSecurityPrefs(sec_prefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid);
399 xsltSetDefaultSecurityPrefs(sec_prefs);
404 _LOGE("xmlsec initialization failed [%d]\n", ret);
407 ret = xmlSecCheckVersion();
409 _LOGE("Incompatible version of loaded xmlsec library [%d]\n", ret);
412 #ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
413 ret = xmlSecCryptoDLLoadLibrary(BAD_CAST "openssl");
415 _LOGE("unable to load openssl library [%d]\n", ret);
420 ret = xmlSecCryptoAppInit(NULL);
422 _LOGE("crypto initialization failed [%d]\n", ret);
425 ret = xmlSecCryptoInit();
427 _LOGE("xmlsec-crypto initialization failed [%d]\n", ret);
431 sec_key_mngr = __ri_load_trusted_certs(rootca, 1);
432 if (sec_key_mngr == NULL) {
433 _LOGE("loading of trusted certs failed\n");
438 if (__ri_verify_file(sec_key_mngr, sigxmlfile) < 0) {
444 xmlSecKeysMngrDestroy(sec_key_mngr);
446 xmlSecCryptoShutdown();
447 xmlSecCryptoAppShutdown();
449 #ifndef XMLSEC_NO_XSLT
450 xsltFreeSecurityPrefs(sec_prefs);
451 xsltCleanupGlobals();
457 int _rpm_installer_get_group_id(const char *pkgid, char **result)
460 const char *value = NULL;
461 char author_signature[BUF_SIZE] = { '\0' };
462 char *e_rootcert = NULL;
463 char *d_rootcert = NULL;
465 unsigned char hashout[BUF_SIZE] = { '\0' };
466 unsigned int h_size = 0;
469 pkgmgrinfo_certinfo_h handle = NULL;
471 snprintf(author_signature, BUF_SIZE, "%s/%s/%s", USR_APPS, pkgid, AUTHOR_SIGNATURE_XML);
472 if (access(author_signature, F_OK) != 0) {
473 _LOGE("[%s] isn't existed.", author_signature);
477 ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
479 _LOGE("pkgmgrinfo_pkginfo_create_certinfo(%s) failed.", pkgid);
483 ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid, handle);
485 _LOGE("pkgmgrinfo_pkginfo_load_certinfo(%s) failed.", pkgid);
489 /* get root certificate */
490 ret = pkgmgrinfo_pkginfo_get_cert_value(handle, PMINFO_AUTHOR_SIGNER_CERT, &value);
491 if (ret < 0 || value == NULL) {
492 _LOGE("pkgmgrinfo_pkginfo_get_cert_value(%s) failed. [%d]", pkgid, ret);
497 d_rootcert = (char *)g_base64_decode(value, &d_size);
498 if (d_rootcert == NULL) {
499 _LOGE("g_base64_decode() failed.");
502 _LOGD("g_base64_decode() succeed, d_size=[%d]", d_size);
505 EVP_Digest(d_rootcert, d_size, hashout, &h_size, EVP_sha1(), NULL);
507 _LOGE("EVP_Digest(hash) failed.");
510 _LOGD("EVP_Digest() succeed, h_size=[%d]", h_size);
513 e_rootcert = g_base64_encode((const guchar *)hashout, h_size);
514 if (e_rootcert == NULL) {
515 _LOGE("g_base64_encode() failed.");
518 e_size = strlen(e_rootcert);
519 _LOGD("g_base64_encode() succeed, e_size=[%d]", e_size);
522 for (length = e_size; length >= 0; --length) {
523 if (e_rootcert[length] == '/') {
524 e_rootcert[length] = '#';
528 *result = e_rootcert;
537 pkgmgrinfo_pkginfo_destroy_certinfo(handle);
543 void __rpm_apply_smack(const char *pkgname, int flag, char *smack_label)
546 char dirpath[BUF_SIZE] = { '\0' };
547 char *groupid = NULL;
548 char *shared_data_label = NULL;
549 char buf[BUF_SIZE] = { 0, };
551 if (smack_label == NULL || strlen(smack_label) == 0) {
552 smack_label = (char *)pkgname;
555 /* execute privilege APIs. The APIs should not fail */
556 _ri_privilege_register_package(smack_label);
558 /* home dir. Dont setup path but change smack access to "_" */
559 snprintf(dirpath, BUF_SIZE, "%s/%s", USR_APPS, pkgname);
560 if (__is_dir(dirpath))
561 _ri_privilege_change_smack_label(dirpath, "_", 0); /* 0 is SMACK_LABEL_ACCESS */
562 memset(dirpath, '\0', BUF_SIZE);
563 snprintf(dirpath, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgname);
564 if (__is_dir(dirpath))
565 _ri_privilege_change_smack_label(dirpath, "_", 0); /* 0 is SMACK_LABEL_ACCESS */
568 memset(dirpath, '\0', BUF_SIZE);
569 snprintf(dirpath, BUF_SIZE, "%s/%s/data", OPT_USR_APPS, pkgname);
570 if (!__is_dir(dirpath)) {
571 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
573 _LOGE("directory making is failed.\n");
577 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
579 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
580 _LOGE("chown failed!! [%s]", buf);
583 _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_PRIVATE, smack_label);
586 memset(dirpath, '\0', BUF_SIZE);
587 snprintf(dirpath, BUF_SIZE, "%s/%s/cache", OPT_USR_APPS, pkgname);
588 if (!__is_dir(dirpath)) {
589 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
591 _LOGE("directory making is failed.\n");
594 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
596 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
597 _LOGE("chown failed!! [%s]", buf);
600 _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_PRIVATE, smack_label);
603 memset(dirpath, '\0', BUF_SIZE);
604 snprintf(dirpath, BUF_SIZE, "%s/%s/shared", USR_APPS, pkgname);
605 if (__is_dir(dirpath))
606 _ri_privilege_change_smack_label(dirpath, "_", 0); /* 0 is SMACK_LABEL_ACCESS */
607 memset(dirpath, '\0', BUF_SIZE);
608 snprintf(dirpath, BUF_SIZE, "%s/%s/shared", OPT_USR_APPS, pkgname);
609 if (!__is_dir(dirpath)) {
610 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
612 _LOGE("directory making is failed.\n");
614 _ri_privilege_change_smack_label(dirpath, "_", 0); /* 0 is SMACK_LABEL_ACCESS */
615 memset(dirpath, '\0', BUF_SIZE);
618 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/res", USR_APPS, pkgname);
619 if (__is_dir(dirpath))
620 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_ANY_LABEL, "_");
621 memset(dirpath, '\0', BUF_SIZE);
623 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/res", OPT_USR_APPS, pkgname);
624 if (__is_dir(dirpath))
625 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_ANY_LABEL, "_");
626 memset(dirpath, '\0', BUF_SIZE);
629 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/data", USR_APPS, pkgname);
630 if (__is_dir(dirpath)) {
631 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
633 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
634 _LOGE("chown failed!! [%s]", buf);
637 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_PUBLIC, NULL);
639 memset(dirpath, '\0', BUF_SIZE);
641 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/data", OPT_USR_APPS, pkgname);
642 if (__is_dir(dirpath)) {
643 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
645 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
646 _LOGE("chown failed!! [%s]", buf);
649 _ri_privilege_setup_path(smack_label, dirpath, PERM_APP_PATH_PUBLIC, NULL);
653 ret = _coretpk_installer_get_smack_label_access(dirpath, &shared_data_label);
655 _LOGE("_coretpk_installer_apply_directory_policy() failed, appdir=[%s], ret=[%d]", dirpath, ret);
657 memset(dirpath, '\0', BUF_SIZE);
658 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/cache", OPT_USR_APPS, pkgname);
659 if (!__is_dir(dirpath)) {
660 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
662 _LOGE("directory making is failed.\n");
665 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
667 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
668 _LOGE("chown failed!! [%s]", buf);
671 ret = _coretpk_installer_set_smack_label_access(dirpath, shared_data_label);
673 _LOGE("_coretpk_installer_apply_directory_policy() failed, appdir=[%s], ret=[%d]", dirpath, ret);
675 ret = _coretpk_installer_set_smack_label_transmute(dirpath, "1");
677 _LOGE("_coretpk_installer_apply_directory_policy() failed, appdir=[%s], ret=[%d]", dirpath, ret);
680 /* /shared/trusted/ */
681 memset(dirpath, '\0', BUF_SIZE);
682 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/trusted", USR_APPS, pkgname);
683 if (__is_dir(dirpath)) {
684 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
686 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
687 _LOGE("chown failed!! [%s]", buf);
691 ret = _rpm_installer_get_group_id(pkgname, &groupid);
693 _LOGD("group id for trusted directory is [%s]", groupid);
694 _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_GROUP_RW, groupid);
695 FREE_AND_NULL(groupid);
698 memset(dirpath, '\0', BUF_SIZE);
700 snprintf(dirpath, BUF_SIZE, "%s/%s/shared/trusted", OPT_USR_APPS, pkgname);
702 _LOGD("dirpath [%s]", dirpath);
704 ret = _rpm_installer_get_group_id(pkgname, &groupid);
706 if (__is_dir(dirpath) != 1) {
707 _LOGE("dont have [%s]", dirpath);
709 ret = mkdir(dirpath, DIRECTORY_PERMISSION_755);
710 if (ret == -1 && errno != EEXIST) {
711 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
712 _LOGE("mkdir failed!! [%s]", buf);
717 ret = chown(dirpath, APP_OWNER_ID, APP_GROUP_ID);
719 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
720 _LOGE("chown failed!! [%s]", buf);
724 _LOGD("group id for trusted directory is [%s]", groupid);
725 _ri_privilege_setup_path(smack_label, dirpath, APP_PATH_GROUP_RW, groupid);
726 _ri_set_group_id(pkgname, groupid);
728 FREE_AND_NULL(groupid);
732 int __is_dir(const char *dirname)
734 struct stat stFileInfo;
735 if (dirname == NULL) {
736 _LOGE("dirname is null\n");
740 if (stat(dirname, &stFileInfo) < 0) {
744 if (S_ISDIR(stFileInfo.st_mode)) {
750 static void __rpm_process_line(char *line)
753 char *save_str = NULL;
754 tok = strtok_r(line, " ", &save_str);
756 if (!strncmp(tok, "%%", 2)) {
757 tok = strtok_r(NULL, " ", &save_str);
759 _LOGD("Install percentage is %s\n", tok);
760 _ri_broadcast_status_notification(gpkgname, PKGTYPE_RPM, "install_percent", tok);
761 _ri_stat_cb(gpkgname, "install_percent", tok);
769 static void __rpm_perform_read(int fd)
771 char *buf_ptr = NULL;
772 char *tmp_ptr = NULL;
774 static char buffer[BUF_SIZE] = { 0, };
775 static int buffer_position;
777 size = read(fd, &buffer[buffer_position], sizeof(buffer) - buffer_position);
778 buffer_position += size;
782 /* Process each line of the recieved buffer */
783 buf_ptr = tmp_ptr = buffer;
784 while ((tmp_ptr = (char *)memchr(buf_ptr, '\n', buffer + buffer_position - buf_ptr)) != NULL) {
786 __rpm_process_line(buf_ptr);
787 /* move to next line and continue */
788 buf_ptr = tmp_ptr + 1;
791 /* move the remaining bits at the start of the buffer
792 and update the buffer position */
793 buf_ptr = (char *)memrchr(buffer, 0, buffer_position);
797 /* we have processed till the last \n which has now become
798 0x0. So we increase the pointer to next position */
801 memmove(buffer, buf_ptr, buf_ptr - buffer);
802 buffer_position = buffer + buffer_position - buf_ptr;
805 int _rpm_xsystem(const char *argv[])
814 if (pipe(pipefd) == -1) {
815 _LOGE("pipe creation failed\n");
818 /* Read progress info via pipe */
823 _LOGE("fork failed\n");
832 _LOGE("dup failed\n");
836 result = dup(pipefd[1]);
838 _LOGE("dup failed\n");
842 if (execvp(argv[0], (char *const *)argv) == -1) {
843 _LOGE("execvp failed\n");
853 while ((err = waitpid(pid, &status, WNOHANG)) != pid) {
857 _LOGE("waitpid failed\n");
866 FD_SET(pipefd[0], &rfds);
869 select_ret = pselect(pipefd[0] + 1, &rfds, NULL, NULL, &tv, NULL);
873 else if (select_ret < 0 && errno == EINTR)
875 else if (select_ret < 0) {
876 _LOGE("select() returned error\n");
879 if (FD_ISSET(pipefd[0], &rfds))
880 __rpm_perform_read(pipefd[0]);
884 /* Check for an error code. */
885 if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) {
886 if (WIFSIGNALED(status) != 0 && WTERMSIG(status) == SIGSEGV) {
887 printf("Sub-process %s received a segmentation fault. \n", argv[0]);
888 } else if (WIFEXITED(status) != 0) {
889 printf("Sub-process %s returned an error code (%u)\n", argv[0], WEXITSTATUS(status));
891 printf("Sub-process %s exited unexpectedly\n", argv[0]);
894 return WEXITSTATUS(status);
897 void __rpm_clear_dir_list(GList *dir_list)
900 app2ext_dir_details *dir_detail = NULL;
902 list = g_list_first(dir_list);
904 dir_detail = (app2ext_dir_details *) list->data;
905 if (dir_detail && dir_detail->name) {
906 free(dir_detail->name);
909 list = g_list_next(list);
911 g_list_free(dir_list);
915 GList *__rpm_populate_dir_list()
917 GList *dir_list = NULL;
919 app2ext_dir_details *dir_detail = NULL;
921 char pkg_ro_content_rpm[3][5] = { "bin", "res", "lib" };
923 for (i = 0; i < 3; i++) {
924 dir_detail = (app2ext_dir_details *) calloc(1, sizeof(app2ext_dir_details));
925 if (dir_detail == NULL) {
926 printf("\nMemory allocation failed\n");
929 dir_detail->name = (char *)calloc(1, sizeof(char) * (strlen(pkg_ro_content_rpm[i]) + 2));
930 if (dir_detail->name == NULL) {
931 printf("\nMemory allocation failed\n");
935 snprintf(dir_detail->name, (strlen(pkg_ro_content_rpm[i]) + 1), "%s", pkg_ro_content_rpm[i]);
936 dir_detail->type = APP2EXT_DIR_RO;
937 dir_list = g_list_append(dir_list, dir_detail);
940 list = g_list_first(dir_list);
942 dir_detail = (app2ext_dir_details *) list->data;
943 list = g_list_next(list);
951 list = g_list_first(dir_list);
953 dir_detail = (app2ext_dir_details *) list->data;
954 if (dir_detail && dir_detail->name) {
955 free(dir_detail->name);
958 list = g_list_next(list);
960 g_list_free(dir_list);
966 static char *__ri_get_cert_from_file(const char *file)
968 FILE *fp_cert = NULL;
970 char *certbuf = NULL;
971 char *startcert = NULL;
972 char *endcert = NULL;
979 if (!(fp_cert = fopen(file, "r"))) {
980 _LOGE("[ERR][%s] Fail to open file, [%s]\n", __func__, file);
984 fseek(fp_cert, 0L, SEEK_END);
986 if (ftell(fp_cert) < 0) {
987 _LOGE("[ERR][%s] Fail to find EOF\n", __func__);
992 certlen = ftell(fp_cert);
994 _LOGE("[ERR][%s] Fail to find EOF\n", __func__);
999 fseek(fp_cert, 0L, SEEK_SET);
1001 if (!(certbuf = (char *)malloc(sizeof(char) * (int)certlen))) {
1002 _LOGE("[ERR][%s] Fail to allocate memory\n", __func__);
1006 memset(certbuf, 0x00, (int)certlen);
1009 while ((ch = fgetc(fp_cert)) != EOF) {
1017 startcert = strstr(certbuf, "-----BEGIN CERTIFICATE-----") + strlen("-----BEGIN CERTIFICATE-----");
1018 endcert = strstr(certbuf, "-----END CERTIFICATE-----");
1019 certwrite = (int)endcert - (int)startcert;
1021 cert = (char *)malloc(sizeof(char) * (certwrite + 2));
1023 _LOGE("[ERR][%s] Fail to allocate memory\n", __func__);
1027 memset(cert, 0x00, certwrite + 2);
1028 snprintf(cert, certwrite + 1, "%s", startcert);
1029 _LOGD("Root CA, len=[%d]\n%s", certwrite, cert);
1041 static int __privilege_func(const char *name, void *user_data)
1044 privilegeinfo *info = (privilegeinfo *) user_data;
1046 _LOGD("package_id=[%s], privilege=[%s]", info->package_id, name);
1047 info->privileges = g_list_append(info->privileges, strdup((char *)name));
1049 if (strcmp(name, EXT_APPDATA_PRIVILEGE_NAME) == 0) {
1050 _LOGD("it is EXT_APPDATA_PRIVILEGE_NAME");
1051 if (_coretpk_installer_make_directory_for_ext((char *)info->package_id) < 0) {
1052 _LOGE("make_directory_for_ext failed.");
1059 char *__strlwr(char *str)
1063 while (*(str + i) != '\0') {
1064 if (*(str + i) >= 65 || *(str + i) <= 90) {
1065 *(str + i) = towlower(*(str + i));
1072 static char *__getvalue(const char *pBuf, const char *pKey)
1074 const char *p = NULL;
1075 const char *pStart = NULL;
1076 const char *pEnd = NULL;
1078 p = strstr(pBuf, pKey);
1082 pStart = p + strlen(pKey) + 1;
1083 pEnd = strchr(pStart, SEPERATOR_START);
1087 size_t len = pEnd - pStart;
1091 char *pRes = (char *)malloc(len + 1);
1093 _LOGE("@malloc failed");
1096 strncpy(pRes, pStart, len);
1102 static char *__find_rpm_pkgid(const char *manifest)
1105 char buf[BUF_SIZE] = { 0 };
1108 fp = fopen(manifest, "r");
1110 _LOGE("csc-info : Fail get : %s\n", manifest);
1114 while (fgets(buf, BUF_SIZE, fp) != NULL) {
1116 pkgid = __getvalue(buf, TOKEN_PACKAGE_STR);
1117 if (pkgid != NULL) {
1121 memset(buf, 0x00, BUF_SIZE);
1130 static int __copy_file(const char *src_path, const char *dst_path)
1134 unsigned char temp_buf[8192] = { '\0', };
1135 size_t size_of_uchar = sizeof(unsigned char);
1136 size_t size_of_temp_buf = sizeof(temp_buf);
1137 char buf[BUF_SIZE] = { 0, };
1139 src = fopen(src_path, "r");
1141 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
1142 _LOGE("Failed to open(). path=%s, E:%d(%s)", src_path, errno, buf);
1147 dst = fopen(dst_path, "w");
1149 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
1150 _LOGE("Failed to open dst file. file=%s, E:%d(%s)", dst_path, errno, buf);
1156 while (!feof(src)) {
1157 rc = fread(temp_buf, size_of_uchar, size_of_temp_buf, src);
1158 fwrite(temp_buf, size_of_uchar, rc, dst);
1166 static int __ri_install_csc(char *path_str, char *remove_str)
1170 char delims[] = "/";
1172 char argv[BUF_SIZE] = { '\0' };
1173 char xml_name[BUF_SIZE] = { '\0' };
1174 char src_file[BUF_SIZE] = { '\0' };
1175 char dest_file[BUF_SIZE] = { '\0' };
1176 char *save_str = NULL;
1178 snprintf(src_file, sizeof(src_file), "%s", path_str);
1180 /* get pkgid from path str */
1181 pkgid = __find_rpm_pkgid(path_str);
1182 if (pkgid == NULL) {
1183 _LOGE("csc-info : fail to find pkgid\n");
1186 _LOGD("csc-info : find pkgid=[%s] for installation\n", pkgid);
1189 token = strtok_r(path_str, delims, &save_str);
1191 memset(xml_name, 0x00, sizeof(xml_name));
1192 strncat(xml_name, token, sizeof(xml_name) - 1);
1193 token = strtok_r(NULL, delims, &save_str);
1195 _LOGD("csc-info : xml name = %s\n", xml_name);
1197 /* copy xml to /opt/share/packages */
1198 snprintf(dest_file, sizeof(dest_file), "%s/%s", OPT_SHARE_PACKAGES, xml_name);
1199 ret = __copy_file(src_file, dest_file);
1201 _LOGE("csc-info : xml copy fail(%d)\n", ret);
1203 _LOGE("csc-info : xml copy success to [%s] \n", dest_file);
1206 /* remove old pkg info */
1207 ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
1209 _LOGD("csc-info : fail remove old pkg info\n");
1211 _LOGD("csc-info : success remove old pkg info\n");
1214 /* insert new pkg info */
1215 memset(argv, 0x00, sizeof(argv));
1216 snprintf(argv, sizeof(argv), "%s/%s", OPT_SHARE_PACKAGES, xml_name);
1217 ret = __ri_init_csc_xml(argv, remove_str);
1219 _LOGD("csc-info : fail insert db\n");
1221 _LOGD("csc-info : success xml name = %s\n", xml_name);
1231 static int __ri_uninstall_csc(char *pkgid)
1233 /* remove old pkg info */
1234 int ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
1236 _LOGD("csc-info : fail remove old pkg info\n");
1238 _LOGD("csc-info : success remove old pkg info\n");
1244 static int __get_size_from_xml(const char *manifest, int *size)
1246 const char *val = NULL;
1247 const xmlChar *node;
1248 xmlTextReaderPtr reader;
1249 int ret = PMINFO_R_OK;
1251 if (manifest == NULL) {
1252 _LOGE("Input argument is NULL\n");
1253 return PMINFO_R_ERROR;
1257 _LOGE("Argument supplied to hold return value is NULL\n");
1258 return PMINFO_R_ERROR;
1261 reader = xmlReaderForFile(manifest, NULL, 0);
1264 if (_child_element(reader, -1)) {
1265 node = xmlTextReaderConstName(reader);
1267 _LOGE("xmlTextReaderConstName value is NULL\n");
1268 ret = PMINFO_R_ERROR;
1272 if (!strcmp(ASCII(node), "manifest")) {
1273 ret = _ri_get_attribute(reader, "size", &val);
1275 _LOGE("@Error in getting the attribute value");
1276 ret = PMINFO_R_ERROR;
1284 _LOGE("package size is not specified\n");
1285 ret = PMINFO_R_ERROR;
1289 _LOGE("Unable to create xml reader\n");
1290 ret = PMINFO_R_ERROR;
1295 _LOGE("xmlReaderForFile value is NULL\n");
1296 ret = PMINFO_R_ERROR;
1300 xmlFreeTextReader(reader);
1304 static int __get_location_from_xml(const char *manifest, pkgmgrinfo_install_location * location)
1306 const char *val = NULL;
1307 const xmlChar *node;
1308 xmlTextReaderPtr reader;
1311 if (manifest == NULL) {
1312 _LOGE("Input argument is NULL\n");
1313 return PMINFO_R_ERROR;
1316 if (location == NULL) {
1317 _LOGE("Argument supplied to hold return value is NULL\n");
1318 return PMINFO_R_ERROR;
1321 reader = xmlReaderForFile(manifest, NULL, 0);
1324 if (_child_element(reader, -1)) {
1325 node = xmlTextReaderConstName(reader);
1327 _LOGE("xmlTextReaderConstName value is NULL\n");
1328 xmlFreeTextReader(reader);
1329 return PMINFO_R_ERROR;
1332 if (!strcmp(ASCII(node), "manifest")) {
1333 ret = _ri_get_attribute(reader, "install-location", &val);
1335 _LOGE("@Error in getting the attribute value");
1336 xmlFreeTextReader(reader);
1337 return PMINFO_R_ERROR;
1341 if (strcmp(val, "internal-only") == 0)
1342 *location = PMINFO_INSTALL_LOCATION_INTERNAL_ONLY;
1343 else if (strcmp(val, "prefer-external") == 0)
1344 *location = PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL;
1346 *location = PMINFO_INSTALL_LOCATION_AUTO;
1350 _LOGE("Unable to create xml reader\n");
1351 xmlFreeTextReader(reader);
1352 return PMINFO_R_ERROR;
1356 _LOGE("xmlReaderForFile value is NULL\n");
1357 return PMINFO_R_ERROR;
1360 xmlFreeTextReader(reader);
1365 static char *__get_pkg_path(const char *pkg_path, const char *pkgid)
1368 char buff[BUF_SIZE] = { '\0' };
1369 char *real_path = NULL;
1370 char buf[BUF_SIZE] = { 0, };
1372 snprintf(buff, BUF_SIZE, "%s/%s", pkg_path, pkgid);
1376 memset(buff, '\0', BUF_SIZE);
1377 snprintf(buff, BUF_SIZE, "%s/%s", USR_APPS, pkgid);
1380 memset(buff, '\0', BUF_SIZE);
1381 snprintf(buff, BUF_SIZE, "/opt/apps/%s", pkgid);
1384 memset(buff, '\0', BUF_SIZE);
1385 snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
1392 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
1393 _LOGE("chdir(%s) failed. [%s]", buff, buf);
1398 real_path = (char *)malloc(strlen(buff) + 1);
1399 if (real_path == NULL) {
1400 _LOGE("malloc() failed.");
1403 memset(real_path, '\0', strlen(buff) + 1);
1404 memcpy(real_path, buff, strlen(buff));
1409 void _ri_register_cert(const char *pkgid)
1412 pkgmgrinfo_instcertinfo_h handle = NULL;
1415 error = pkgmgrinfo_create_certinfo_set_handle(&handle);
1417 _LOGE("Cert handle creation failed. Err:%d", error);
1418 __ri_free_cert_chain();
1422 if (list[SIG_AUTH].cert_value == NULL) {
1423 _LOGE("pkgid[%s] dont have SIG_AUTH.cert_value ", pkgid);
1427 for (i = 0; i < MAX_CERT_NUM; i++) {
1429 if (list[i].cert_value) {
1430 error = pkgmgrinfo_set_cert_value(handle, list[i].cert_type, list[i].cert_value);
1432 _LOGE("pkgmgrinfo_set_cert_value failed. cert type:%d. Err:%d", list[i].cert_type, error);
1437 /* Save the certificates in cert DB */
1438 error = pkgmgrinfo_save_certinfo(pkgid, handle);
1440 _LOGE("pkgmgrinfo_save_certinfo failed. Err:%d", error);
1445 pkgmgrinfo_destroy_certinfo_set_handle(handle);
1446 __ri_free_cert_chain();
1449 void _ri_unregister_cert(const char *pkgid)
1452 /* Delete the certifictes from cert DB */
1453 error = pkgmgrinfo_delete_certinfo(pkgid);
1455 _LOGE("pkgmgrinfo_delete_certinfo failed. Err:%d", error);
1460 int _ri_get_visibility_from_signature_file(const char *sigfile, int *visibility, bool save_ca_path)
1462 char certval[BUF_SIZE] = { '\0' };
1466 int ret = RPM_INSTALLER_SUCCESS;
1467 signature_x *signx = NULL;
1468 struct keyinfo_x *keyinfo = NULL;
1469 struct x509data_x *x509data = NULL;
1470 CERT_CONTEXT *ctx = NULL;
1473 if (sigfile == NULL) {
1474 return RPM_INSTALLER_ERR_WRONG_PARAM;
1477 ctx = cert_svc_cert_context_init();
1479 _LOGE("cert_svc_cert_context_init() failed.");
1480 return RPM_INSTALLER_ERR_INTERNAL;
1483 if (!strstr(sigfile, SIGNATURE1_XML)) {
1484 _LOGE("Unsupported signature type! [%s]", sigfile);
1485 cert_svc_cert_context_final(ctx);
1486 return RPM_INSTALLER_ERR_INTERNAL;
1489 signx = _ri_process_signature_xml(sigfile);
1490 if (signx == NULL) {
1491 _LOGE("_ri_process_signature_xml(%s) failed.", sigfile);
1492 ret = RPM_INSTALLER_ERR_INTERNAL;
1496 keyinfo = signx->keyinfo;
1497 if ((keyinfo == NULL) || (keyinfo->x509data == NULL)
1498 || (keyinfo->x509data->x509certificate == NULL)) {
1499 _LOGE("keyinfo is invalid. [%s]", sigfile);
1500 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1504 x509data = keyinfo->x509data;
1505 x509certificate_x *cert = x509data->x509certificate;
1507 /* First cert is Signer certificate */
1508 if (cert->text != NULL) {
1509 for (i = 0; i <= (int)strlen(cert->text); i++) {
1510 if (cert->text[i] != '\n') {
1511 certval[j++] = cert->text[i];
1516 err = cert_svc_load_buf_to_context(ctx, (unsigned char *)certval);
1518 _LOGE("cert_svc_load_buf_to_context() failed. err = [%d]", err);
1519 _SLOGE("cert_svc_load_buf_to_context() failed. cert = [%s]", certval);
1520 ret = RPM_INSTALLER_ERR_INTERNAL;
1525 err = __ri_create_cert_chain(SIG_DIST1, SIG_SIGNER, certval);
1527 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", (int)SIG_DIST1);
1528 _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", certval);
1529 __ri_free_cert_chain();
1530 ret = RPM_INSTALLER_ERR_INTERNAL;
1536 /* Second cert is Intermediate certificate */
1538 if ((cert != NULL) && (cert->text != NULL)) {
1539 memset(certval, 0x00, BUF_SIZE);
1541 for (i = 0; i <= (int)strlen(cert->text); i++) {
1542 if (cert->text[i] != '\n') {
1543 certval[j++] = cert->text[i];
1548 if (cert->text != NULL) {
1549 err = cert_svc_push_buf_into_context(ctx, (unsigned char *)certval);
1551 _LOGE("cert_svc_push_buf_into_context() failed. cert = [%s], err = [%d]", certval, err);
1552 ret = RPM_INSTALLER_ERR_INTERNAL;
1558 err = __ri_create_cert_chain(SIG_DIST1, SIG_INTERMEDIATE, certval);
1560 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", (int)SIG_DIST1);
1561 _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", certval);
1562 __ri_free_cert_chain();
1563 ret = RPM_INSTALLER_ERR_INTERNAL;
1568 _LOGE("Invalid CertChain! (cert->text is NULL.)");
1569 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1573 err = cert_svc_verify_package_certificate(ctx, &validity, sigfile);
1576 _LOGE("cert_svc_verify_package_certificate() failed.");
1577 ret = RPM_INSTALLER_ERR_INTERNAL;
1580 if (validity == 0) {
1581 _LOGE("Certificate Invalid/Expired (validity == 0)");
1582 ret = RPM_INSTALLER_ERR_CERTCHAIN_VERIFICATION_FAILED;
1585 _LOGD("cert_svc_verify() is done successfully. validity=[%d]", validity);
1587 err = cert_svc_get_visibility(ctx, visibility);
1589 _LOGE("cert_svc_get_visibility() failed. err = [%d]", err);
1590 ret = RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED;
1595 if (save_ca_path && ctx->fileNames && ctx->fileNames->filename) {
1596 FREE_AND_NULL(sig1_capath);
1597 sig1_capath = strdup(ctx->fileNames->filename);
1598 sig1_visibility = *visibility;
1602 cert_svc_cert_context_final(ctx);
1604 _ri_free_signature_xml(signx);
1609 int _ri_verify_sig_and_cert(const char *sigfile, int *visibility, bool need_verify, char *ca_path)
1611 char certval[BUF_SIZE] = { '\0' };
1616 int ret = RPM_INSTALLER_SUCCESS;
1618 signature_x *signx = NULL;
1619 struct keyinfo_x *keyinfo = NULL;
1620 struct x509data_x *x509data = NULL;
1621 CERT_CONTEXT *ctx = NULL;
1623 char *root_ca_path = NULL;
1625 ctx = cert_svc_cert_context_init();
1627 _LOGE("cert_svc_cert_context_init() failed.");
1628 return RPM_INSTALLER_ERR_INTERNAL;
1631 if (strstr(sigfile, AUTHOR_SIGNATURE_XML))
1633 else if (strstr(sigfile, SIGNATURE1_XML))
1634 sigtype = SIG_DIST1;
1635 else if (strstr(sigfile, SIGNATURE2_XML))
1636 sigtype = SIG_DIST2;
1638 _LOGE("Unsupported signature type! [%s]", sigfile);
1639 cert_svc_cert_context_final(ctx);
1640 return RPM_INSTALLER_ERR_SIG_INVALID;
1643 if (sigtype == SIG_DIST1 && ca_path != NULL && strlen(ca_path) != 0) {
1644 root_ca_path = ca_path;
1645 *visibility = sig1_visibility;
1649 signx = _ri_process_signature_xml(sigfile);
1650 if (signx == NULL) {
1651 _LOGE("_ri_process_signature_xml(%s) failed.", sigfile);
1652 ret = RPM_INSTALLER_ERR_SIG_INVALID;
1656 keyinfo = signx->keyinfo;
1657 if ((keyinfo == NULL) || (keyinfo->x509data == NULL) || (keyinfo->x509data->x509certificate == NULL)) {
1658 _LOGE("keyinfo is invalid. [%s]", sigfile);
1659 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1663 x509data = keyinfo->x509data;
1664 x509certificate_x *cert = x509data->x509certificate;
1666 /* First cert is Signer certificate */
1667 if (cert->text != NULL) {
1668 for (i = 0; i <= (int)strlen(cert->text); i++) {
1669 if (cert->text[i] != '\n') {
1670 certval[j++] = cert->text[i];
1675 err = cert_svc_load_buf_to_context(ctx, (unsigned char *)certval);
1677 _LOGE("cert_svc_load_buf_to_context() failed. err = [%d]", err);
1678 _SLOGE("cert_svc_load_buf_to_context() failed. cert = [%s]", certval);
1679 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1683 err = __ri_create_cert_chain(sigtype, SIG_SIGNER, certval);
1685 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", sigtype);
1686 _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", certval);
1687 __ri_free_cert_chain();
1688 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1692 _LOGE("cert->text is NULL. [Signer]");
1693 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1697 /* Second cert is Intermediate certificate */
1700 _LOGE("cert is NULL. [Intermediate]");
1701 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1705 if (cert->text != NULL) {
1706 memset(certval, 0x00, BUF_SIZE);
1708 for (i = 0; i <= (int)strlen(cert->text); i++) {
1709 if (cert->text[i] != '\n') {
1710 certval[j++] = cert->text[i];
1715 if (cert->text != NULL) {
1716 err = cert_svc_push_buf_into_context(ctx, (unsigned char *)certval);
1718 _LOGE("cert_svc_push_buf_into_context() failed. cert = [%s], err = [%d]", certval, err);
1719 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1724 err = __ri_create_cert_chain(sigtype, SIG_INTERMEDIATE, certval);
1726 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", sigtype);
1727 _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", certval);
1728 __ri_free_cert_chain();
1729 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1733 _LOGE("Invalid CertChain! (cert->text is NULL.) [Intermediate]");
1734 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1738 err = cert_svc_verify_package_certificate(ctx, &validity, sigfile);
1739 if (err != 0 && (need_verify == true)) {
1740 _LOGE("cert_svc_verify_package_certificate() failed. err=[%d]", err);
1744 _LOGD("cert_svc_verify() is done successfully. validity=[%d]", validity);
1746 if (validity == 0) {
1747 _LOGE("Certificate Invalid/Expired (validity == 0)");
1748 ret = RPM_INSTALLER_ERR_CERTIFICATE_EXPIRED;
1752 err = cert_svc_get_visibility(ctx, visibility);
1754 _LOGE("cert_svc_get_visibility() failed. err = [%d]", err);
1755 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1758 _LOGD("cert_svc_get_visibility() returns visibility=[%d]", *visibility);
1760 if (ctx->fileNames == NULL || ctx->fileNames->filename == NULL) {
1761 _LOGE("No Root CA cert found. Signature validation failed.");
1762 ret = RPM_INSTALLER_ERR_ROOT_CERT_NOT_FOUND;
1765 root_ca_path = ctx->fileNames->filename;
1769 For reference validation, we should be in TEMP_DIR/usr/apps/<pkgid> */
1770 if (root_ca_path != NULL && strlen(root_ca_path) != 0) {
1771 _LOGD("Root CA cert path=[%s]", root_ca_path);
1773 if (need_verify == true) {
1774 err = __ri_xmlsec_verify_signature(sigfile, root_ca_path);
1776 _LOGE("__ri_xmlsec_verify_signature(%s) failed.", sigfile);
1777 ret = RPM_INSTALLER_ERR_SIG_VERIFICATION_FAILED;
1782 crt = __ri_get_cert_from_file(root_ca_path);
1783 err = __ri_create_cert_chain(sigtype, SIG_ROOT, crt);
1785 _LOGE("__ri_create_cert_chain() failed. sigtype = [%d]", sigtype);
1786 _SLOGE("__ri_create_cert_chain() failed. cert = [%s]", crt);
1787 __ri_free_cert_chain();
1788 ret = RPM_INSTALLER_ERR_CERT_INVALID;
1796 cert_svc_cert_context_final(ctx);
1798 _ri_free_signature_xml(signx);
1803 int _ri_verify_signatures(const char *root_path, const char *pkgid, bool need_verify)
1806 char buff[BUF_SIZE] = { '\0' };
1807 char *pkg_path = NULL;
1810 _LOGD("root_path=[%s], pkgid=[%s]", root_path, pkgid);
1812 /* check for signature and certificate */
1813 pkg_path = __get_pkg_path(root_path, pkgid);
1814 if (pkg_path == NULL) {
1815 _LOGE("__get_pkg_path(%s, %s) failed.", root_path, pkgid);
1819 _LOGD("switched to pkg_path=[%s]", pkg_path);
1821 /* author-signature.xml is mandatory */
1822 snprintf(buff, BUF_SIZE, "%s/author-signature.xml", pkg_path);
1823 if (access(buff, F_OK) == 0) {
1824 _LOGD("author-signature.xml, path=[%s]", buff);
1825 ret = _ri_verify_sig_and_cert(buff, &visibility, need_verify, NULL);
1827 _LOGE("_ri_verify_sig_and_cert(%s) failed.", buff);
1831 _LOGD("------------------------------------------------------");
1832 _LOGD("signature is verified successfully");
1833 _LOGD("path=[%s]", buff);
1834 _LOGD("------------------------------------------------------");
1836 memset(buff, '\0', BUF_SIZE);
1838 /* signature2.xml is optional */
1839 snprintf(buff, BUF_SIZE, "%s/signature2.xml", pkg_path);
1840 if (access(buff, F_OK) == 0) {
1841 _LOGD("signature2.xml found. [%s]", pkg_path);
1842 ret = _ri_verify_sig_and_cert(buff, &visibility, need_verify, NULL);
1844 _LOGE("_ri_verify_sig_and_cert(%s) failed.", buff);
1848 _LOGD("_ri_verify_sig_and_cert(%s) succeed.", buff);
1850 memset(buff, '\0', BUF_SIZE);
1852 /* signature1.xml is mandatory */
1853 snprintf(buff, BUF_SIZE, "%s/signature1.xml", pkg_path);
1854 if (access(buff, F_OK) == 0) {
1855 _LOGD("signature1.xml, path=[%s]", buff);
1856 ret = _ri_verify_sig_and_cert(buff, &visibility, need_verify, NULL);
1858 _LOGE("_ri_verify_sig_and_cert(%s) failed.", buff);
1862 _LOGD("------------------------------------------------------");
1863 _LOGD("signature is verified successfully");
1864 _LOGD("path=[%s]", buff);
1865 _LOGD("------------------------------------------------------");
1867 memset(buff, '\0', BUF_SIZE);
1877 if ((ret != 0) && (sig_enable == 0)) {
1878 _LOGD("_ri_verify_signatures(%s, %s) failed, but it's ok for config.", root_path, pkgid);
1885 void _ri_apply_smack(const char *pkgname, int flag, char *smack_label)
1887 __rpm_apply_smack(pkgname, flag, smack_label);
1890 int _ri_apply_privilege(const char *pkgid, int visibility, char *smack_label)
1893 pkgmgrinfo_pkginfo_h handle = NULL;
1895 int apptype = PERM_APP_TYPE_EFL;
1897 char *privilege_fota[BUF_SIZE] = { NULL, };
1898 char *api_version = NULL;
1901 if (smack_label == NULL || strlen(smack_label) == 0) {
1902 smack_label = (char *)pkgid;
1905 memset(&info, '\0', sizeof(info));
1907 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
1908 if (ret != PMINFO_R_OK) {
1909 _LOGE("pkgmgrinfo_pkginfo_get_pkginfo(%s) failed.", pkgid);
1913 ret = pkgmgrinfo_pkginfo_get_api_version(handle, &api_version);
1914 if (ret != PMINFO_R_OK)
1915 _LOGE("failed to get api version (%s)", pkgid);
1918 ret = _ri_privilege_set_package_version(smack_label, api_version);
1920 _LOGE("failed to set api version for smack_label: %s, ret[%d]", smack_label, ret);
1921 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1924 _LOGD("api-version[%s] fot privilege has done successfully.", api_version);
1927 strncpy(info.package_id, pkgid, sizeof(info.package_id) - 1);
1928 info.visibility = visibility;
1930 ret = pkgmgrinfo_pkginfo_foreach_privilege(handle, __privilege_func, (void *)&info);
1931 if (ret != PMINFO_R_OK) {
1932 _LOGE("pkgmgrinfo_pkginfo_foreach_privilege(%s) failed.", pkgid);
1933 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1936 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1938 if (visibility & CERT_SVC_VISIBILITY_PLATFORM) {
1939 _LOGD("VISIBILITY_PLATFORM!");
1940 apptype = PERM_APP_TYPE_EFL_PLATFORM;
1941 } else if ((visibility & CERT_SVC_VISIBILITY_PARTNER) ||
1942 (visibility & CERT_SVC_VISIBILITY_PARTNER_OPERATOR) ||
1943 (visibility & CERT_SVC_VISIBILITY_PARTNER_MANUFACTURER)) {
1944 _LOGD("VISIBILITY_PARTNER!");
1945 apptype = PERM_APP_TYPE_EFL_PARTNER;
1948 list = g_list_first(info.privileges);
1951 privilege_fota[i] = strdup((char *)list->data);
1953 list = g_list_next(list);
1956 privilege_fota[i] = NULL;
1958 ret = _ri_privilege_enable_permissions(smack_label, apptype, (const char **)privilege_fota, 1);
1959 for (i = 0; i < g_list_length(info.privileges); i++) {
1960 if (privilege_fota[i]) {
1961 free(privilege_fota[i]);
1962 privilege_fota[i] = NULL;
1966 if (info.privileges != NULL) {
1967 list = g_list_first(info.privileges);
1972 list = g_list_next(list);
1974 g_list_free(info.privileges);
1975 info.privileges = NULL;
1979 _LOGE("_ri_privilege_enable_permissions(%s, %d) failed.", smack_label, apptype);
1986 int _ri_set_group_id(const char *pkgid, const char *groupid)
1988 retvm_if(pkgid == NULL, PMINFO_R_EINVAL, "pkgid is NULL\n");
1989 retvm_if(groupid == NULL, PMINFO_R_EINVAL, "groupid is NULL\n");
1991 sqlite3 *pkginfo_db = NULL;
1995 ret = db_util_open(PKGMGR_DB, &pkginfo_db, 0);
1996 retvm_if(ret != SQLITE_OK, PMINFO_R_ERROR, "connect db [%s] failed!", PKGMGR_DB);
1998 /* Begin transaction */
1999 ret = sqlite3_exec(pkginfo_db, "BEGIN EXCLUSIVE", NULL, NULL, NULL);
2000 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Failed to begin transaction\n");
2001 _LOGD("Transaction Begin\n");
2003 query = sqlite3_mprintf("update package_info set package_reserve3=%Q where package=%Q", groupid, pkgid);
2005 ret = sqlite3_exec(pkginfo_db, query, NULL, NULL, NULL);
2006 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
2008 /* Commit transaction */
2009 ret = sqlite3_exec(pkginfo_db, "COMMIT", NULL, NULL, NULL);
2010 if (ret != SQLITE_OK) {
2011 _LOGE("Failed to commit transaction. Rollback now\n");
2012 ret = sqlite3_exec(pkginfo_db, "ROLLBACK", NULL, NULL, NULL);
2013 tryvm_if(ret != SQLITE_OK, ret = PMINFO_R_ERROR, "Don't execute query = %s\n", query);
2015 _LOGD("Transaction Commit and End\n");
2019 sqlite3_free(query);
2020 sqlite3_close(pkginfo_db);
2026 * callback for the pkgmgrinfo_appinfo_get_list used in _rpm_uninstall_pkg()
2028 int __ri_check_running_app(const pkgmgrinfo_appinfo_h handle, void *user_data)
2033 app_context_h appCtx = NULL;
2035 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
2037 _LOGE("Failed to execute pkgmgrinfo_appinfo_get_appid[%d].\n", ret);
2041 if (user_data != NULL)
2042 *(GList **)user_data = g_list_append(*(GList **)user_data, strdup(appid));
2044 ret = app_manager_is_running(appid, &isRunning);
2046 _LOGE("Failed to execute app_manager_is_running[%d].\n", ret);
2049 _LOGE("app[%s] , running state[%d].\n", appid, isRunning);
2052 ret = app_manager_get_app_context(appid, &appCtx);
2054 _LOGE("Failed to execute app_manager_get_app_context[%d].\n", ret);
2058 ret = app_manager_terminate_app(appCtx);
2060 _LOGE("Failed to execute app_manager_terminate_app[%d].\n", ret);
2061 app_context_destroy(appCtx);
2066 for (i = 0; i < TERMINATE_RETRY_COUNT; i++) {
2067 ret = app_manager_is_running(appid, &isRunning);
2069 _LOGE("Failed to execute app_manager_is_running[%d].\n", ret);
2070 app_context_destroy(appCtx);
2075 _LOGD("App(%s) is terminated.\n", appid);
2078 _LOGD("App(%s) is not terminated yet. wait count=[%d].\n", appid, i);
2083 ret = app_context_destroy(appCtx);
2085 _LOGE("Failed to execute app_context_destroy[%d].\n", ret);
2093 int __ri_change_dir(const char *dirname)
2097 ret = mkdir(dirname, 0644);
2099 if (access(dirname, F_OK) == 0) {
2100 _installer_util_delete_dir(dirname);
2101 ret = mkdir(dirname, 0644);
2103 _LOGE("mkdir(%s) failed\n", dirname);
2107 _LOGE("can not access[%s]\n", dirname);
2112 ret = chdir(dirname);
2114 char buf[BUF_SIZE] = { 0, };
2115 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
2116 _LOGE("chdir(%s) failed [%s]\n", dirname, buf);
2123 int _ri_smack_reload(const char *pkgid, rpm_request_type request_type)
2126 char *op_type = NULL;
2128 switch (request_type) {
2130 op_type = strdup("install");
2134 op_type = strdup("update");
2138 op_type = strdup("uninstall");
2145 if (op_type == NULL) {
2146 _LOGE("@Failed to reload smack. request_type not matched[pkgid=%s, op=%s]", pkgid, op_type);
2150 const char *smack_argv[] = { "/usr/bin/smack_reload.sh", op_type, pkgid, NULL };
2151 ret = _ri_xsystem(smack_argv);
2153 _LOGE("@Failed to reload smack[pkgid=%s, op=%s].", pkgid, op_type);
2155 _LOGD("#success: smack reload[pkgid=%s, op=%s]", pkgid, op_type);
2164 int _ri_smack_reload_all(void)
2168 const char *smack_argv[] = { "/usr/bin/smackload-fast", NULL };
2169 ret = _ri_xsystem(smack_argv);
2171 _LOGE("@Failed to reload all smack : %d", errno);
2173 _LOGD("#success: smack reload all");
2179 void __ri_remove_updated_dir(const char *pkgid)
2181 char path_buf[BUF_SIZE] = { '\0' };
2184 if (pkgid == NULL) {
2185 _LOGE("pkgid is NULL.");
2189 /* remove bin dir */
2190 snprintf(path_buf, BUF_SIZE, "%s/%s/%s", OPT_USR_APPS, pkgid, BIN_DIR_STR);
2191 if (__is_dir(path_buf)) {
2192 _LOGE("@pkgid[%s] need to clean dir[%s]\n", pkgid, path_buf);
2193 _installer_util_delete_dir(path_buf);
2196 /* remove res dir */
2197 memset(path_buf, '\0', BUF_SIZE);
2198 snprintf(path_buf, BUF_SIZE, "%s/%s/%s", OPT_USR_APPS, pkgid, RES_DIR_STR);
2199 if (__is_dir(path_buf)) {
2200 _LOGE("@pkgid[%s] need to clean dir[%s]\n", pkgid, path_buf);
2201 _installer_util_delete_dir(path_buf);
2204 /* remove shared/res dir */
2205 memset(path_buf, '\0', BUF_SIZE);
2206 snprintf(path_buf, BUF_SIZE, "%s/%s/%s", OPT_USR_APPS, pkgid, SHARED_RES_DIR_STR);
2207 if (__is_dir(path_buf)) {
2208 _LOGE("@pkgid[%s] need to clean dir[%s]\n", pkgid, path_buf);
2209 _installer_util_delete_dir(path_buf);
2213 static int __metadata_func(const char *key, const char *value, void *user_data)
2219 _LOGE("key is null\n");
2222 if (value == NULL) {
2223 _LOGE("value is null\n");
2226 if (user_data == NULL) {
2227 _LOGE("user_data is null\n");
2231 if ((strcmp(key, "launch-on-attach") == 0) && (strcmp(value, "true") == 0)) {
2232 _LOGE("consumer[%s] : launch-on-attach is true \n", (char *)user_data);
2234 ret = app_manager_is_running((char *)user_data, &isRunning);
2236 _LOGE("Failed to execute app_manager_is_running[%s].\n", (char *)user_data);
2241 _LOGE("consumer[%s] is already launched \n", (char *)user_data);
2243 usleep(100 * 1000); /* 100ms sleep for infomation ready */
2244 ret = aul_launch_app((char *)user_data, NULL);
2245 if (ret == AUL_R_ERROR) {
2246 _LOGE("consumer[%s] launch fail, sleep and retry launch_app\n", (char *)user_data);
2247 usleep(100 * 1000); /* 100ms sleep for infomation ready */
2248 aul_launch_app((char *)user_data, NULL);
2250 _LOGE("consumer[%s] is launched !!!! \n", (char *)user_data);
2256 static int __ri_find_svcapp(const pkgmgrinfo_appinfo_h handle, void *user_data)
2260 char *component_type = NULL;
2262 ret = pkgmgrinfo_appinfo_get_component_type(handle, &component_type);
2263 if (ret != PMINFO_R_OK) {
2264 _LOGE("@Failed to get component_type\n");
2268 if (strcmp(component_type, "svcapp") == 0) {
2269 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
2270 if (ret != PMINFO_R_OK) {
2271 _LOGE("@Failed to get appid\n");
2274 _LOGE("@find consumer[%s], check metadata for launch\n", appid);
2276 ret = pkgmgrinfo_appinfo_foreach_metadata(handle, __metadata_func, (void *)appid);
2277 if (ret != PMINFO_R_OK) {
2278 _LOGE("@Failed to get foreach_metadata\n");
2286 static void __ri_launch_consumer(const char *pkgid)
2289 pkgmgrinfo_pkginfo_h pkghandle = NULL;
2291 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
2293 _LOGE("@Failed to get pkginfo handle [%s]\n", pkgid);
2297 ret = pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_find_svcapp, NULL);
2299 _LOGE("@Failed to get appinfo_get_list [%s]\n", pkgid);
2302 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
2305 static int __child_list_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data)
2310 ret = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid);
2312 _LOGE("get_pkgid failed\n");
2316 _LOGD("@child pkgid is [%s] for uninstallation", pkgid);
2318 ret = _rpm_uninstall_pkg_with_dbpath(pkgid, 0);
2320 _LOGE("uninstall pkg(%s) failed\n", pkgid);
2326 static void __uninstall_child_package_by_mother_pkgid(const char *pkgid)
2329 pkgmgrinfo_pkginfo_filter_h handle = NULL;
2331 ret = pkgmgrinfo_pkginfo_filter_create(&handle);
2333 _LOGE("filter_create failed for (%s)\n", pkgid);
2337 ret = pkgmgrinfo_pkginfo_filter_add_string(handle, PMINFO_PKGINFO_PROP_PACKAGE_STORECLIENT_ID, pkgid);
2339 _LOGE("PMINFO_PKGINFO_PROP_PACKAGE_STORECLIENT_ID add failed\n");
2343 ret = pkgmgrinfo_pkginfo_filter_foreach_pkginfo(handle, __child_list_cb, NULL);
2345 _LOGE("foreach_pkginfo failed\n");
2349 pkgmgrinfo_pkginfo_filter_destroy(handle);
2352 int _rpm_install_pkg_with_dbpath(char *pkgfilepath, char *pkgid, char *clientid)
2355 char manifest[BUF_SIZE] = { '\0' };
2356 char resultxml[BUF_SIZE] = { '\0' };
2357 char resxml[BUF_SIZE] = { '\0' };
2358 char cwd[BUF_SIZE] = { '\0' };
2361 char buf[BUF_SIZE] = { 0, };
2363 #ifdef APP2EXT_ENABLE
2364 app2ext_handle *handle = NULL;
2365 GList *dir_list = NULL;
2366 pkgmgrinfo_install_location location = 1;
2368 unsigned long rpm_size = 0;
2370 char *smack_label = NULL;
2372 /* send event for start */
2373 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "start", "install");
2374 _LOGD("[#]start : _rpm_install_pkg_with_dbpath");
2377 temp = getcwd(cwd, BUF_SIZE);
2378 if ((temp == NULL) || (cwd[0] == '\0')) {
2379 _LOGE("@failed to get the current directory info.");
2380 ret = RPM_INSTALLER_ERR_INTERNAL;
2383 _LOGD("#current working directory is %s", cwd);
2386 ret = __ri_change_dir(TEMP_DIR);
2388 _LOGE("@failed to change directory.");
2389 ret = RPM_INSTALLER_ERR_INTERNAL;
2392 _LOGD("#switched to %s", TEMP_DIR);
2394 /* run cpio script */
2395 const char *cpio_argv[] = { CPIO_SCRIPT, pkgfilepath, NULL };
2396 ret = _ri_xsystem(cpio_argv);
2398 /* get manifext.xml path */
2399 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, OPT_SHARE_PACKAGES, pkgid);
2400 _LOGD("#manifest name is %s", manifest);
2402 if (access(manifest, F_OK)) {
2403 _LOGD("#there is no RW manifest.xml. check RO manifest.xml.");
2405 memset(manifest, '\0', sizeof(manifest));
2406 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, USR_SHARE_PACKAGES, pkgid);
2407 _LOGD("#manifest name is %s", manifest);
2409 if (access(manifest, F_OK)) {
2410 _LOGE("@can not find manifest.xml in the pkg.");
2411 ret = RPM_INSTALLER_ERR_NO_MANIFEST;
2418 /* disable "copy ro-xml to rw-xml", because of some bug */
2419 snprintf(srcpath, BUF_SIZE, "%s", manifest);
2420 memset(manifest, '\0', sizeof(manifest));
2421 snprintf(manifest, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2423 const char *xml_update_argv[] = { CPIO_SCRIPT_UPDATE_XML, srcpath, manifest, NULL };
2424 ret = _ri_xsystem(xml_update_argv);
2430 /* send event for install_percent */
2431 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "30");
2433 /* check manifest.xml validation */
2434 ret = pkgmgr_parser_check_manifest_validation(manifest);
2436 _LOGE("@invalid manifest");
2437 ret = RPM_INSTALLER_ERR_INVALID_MANIFEST;
2441 /* check existance of res.xml for resource manager */
2442 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, USR_APPS, pkgid);
2443 _LOGD("#path of res.xml is %s", resxml);
2444 if (access(resxml, F_OK) != 0) {
2445 _LOGE("file not found. try other paths");
2446 memset(resxml, '\0', sizeof(resxml));
2447 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, OPT_USR_APPS, pkgid);
2448 if (access(resxml, F_OK) != 0) {
2449 _LOGE("file not found");
2450 memset(resxml, '\0', sizeof(resxml));
2454 if (resxml[0] != '\0') {
2455 if (access(resxml, R_OK) == 0) {
2457 ret = pkgmgr_resource_parser_check_xml_validation(resxml);
2459 _LOGE("pkgmgr_resource_parser_check_xml_validation(%s) failed.", resxml);
2460 ret = RPM_INSTALLER_ERR_INTERNAL;
2469 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
2470 _LOGE("@failed to change directory(%s)(%s)", cwd, buf);
2472 ret = RPM_INSTALLER_ERR_INTERNAL;
2475 #ifdef APP2EXT_ENABLE
2476 ret = __get_location_from_xml(manifest, &location);
2478 _LOGE("@Failed to get install location\n");
2479 ret = RPM_INSTALLER_ERR_INTERNAL;
2482 if (location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) {
2483 _LOGD("#Install: external storage location");
2485 /* Get the rpm's size from rpm header */
2486 rpm_size = _ri_calculate_rpm_size(pkgfilepath);
2487 if (rpm_size != 0) {
2488 rpm_size = rpm_size / (1024 * 1024); /* rpm size in MB */
2489 _LOGD("#Rpm file(%s) size is %lu MB", pkgfilepath, rpm_size);
2491 /* Add margin to the rpm size */
2492 rpm_size = rpm_size + RPM_SIZE_MARGIN(rpm_size);
2493 _LOGD("#Rpm file (%s) size after margin is %lu MB", pkgfilepath, rpm_size);
2495 _LOGE("@Failed to get size from rpm header\n");
2496 ret = RPM_INSTALLER_ERR_INTERNAL;
2500 /* Get the size from the manifest file. */
2501 ret = __get_size_from_xml(manifest, &size);
2502 if (ret != PMINFO_R_OK) {
2504 _LOGD(" #rpm size is %d MB", size);
2506 size = size > rpm_size ? size : rpm_size;
2507 _LOGD("#rpm size is %d MB", size);
2512 if ((location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) && size > 0) {
2513 handle = app2ext_init(APP2EXT_SD_CARD);
2514 if (handle == NULL) {
2515 _LOGE("@app2ext init failed\n");
2516 ret = RPM_INSTALLER_ERR_INTERNAL;
2519 if ((&(handle->interface) != NULL) && (handle->interface.pre_install != NULL)
2520 && (handle->interface.post_install != NULL)) {
2521 dir_list = __rpm_populate_dir_list();
2522 if (dir_list == NULL) {
2523 _LOGE("@ \nError in populating the directory list\n");
2524 app2ext_deinit(handle);
2525 ret = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
2528 ret = handle->interface.pre_install(gpkgname, dir_list, size);
2529 if (ret == APP2EXT_ERROR_MMC_STATUS) {
2530 _LOGE("@app2xt MMC is not here, go internal\n");
2531 } else if (ret == APP2EXT_SUCCESS) {
2532 _LOGE("@pre_install done, go internal\n");
2534 _LOGE("@app2xt pre install API failed (%d)\n", ret);
2535 __rpm_clear_dir_list(dir_list);
2536 handle->interface.post_install(gpkgname, APP2EXT_STATUS_FAILED);
2537 app2ext_deinit(handle);
2538 ret = RPM_INSTALLER_ERR_INTERNAL;
2546 if (home_dir == 0) {
2548 /* disable "INSTALL_SCRIPT_WITH_DBPATH_RO", because of some bug */
2549 const char *argv[] = { INSTALL_SCRIPT_WITH_DBPATH_RO, pkgfilepath, NULL };
2550 ret = _ri_xsystem(argv);
2552 const char *argv[] = { INSTALL_SCRIPT, pkgfilepath, NULL };
2553 ret = _ri_xsystem(argv);
2555 const char *argv[] = { INSTALL_SCRIPT_WITH_DBPATH_RW, pkgfilepath, NULL };
2556 ret = _ri_xsystem(argv);
2559 _LOGE("@failed to install the pkg(%d).", ret);
2560 #ifdef APP2EXT_ENABLE
2561 if ((handle != NULL) && (handle->interface.post_install != NULL)) {
2562 __rpm_clear_dir_list(dir_list);
2563 handle->interface.post_install(gpkgname, APP2EXT_STATUS_FAILED);
2564 app2ext_deinit(handle);
2569 _LOGD("#install success.");
2571 /* check for signature and certificate */
2572 ret = _ri_verify_signatures(TEMP_DIR, pkgid, true);
2574 _LOGE("@signature and certificate failed(%s).", pkgid);
2575 ret = RPM_INSTALLER_ERR_SIG_INVALID;
2578 _LOGD("#_ri_verify_signatures success.");
2580 /* write the storeclient-id to manifest.xml */
2581 if (clientid != NULL) {
2582 if (home_dir == 0) {
2583 snprintf(resultxml, BUF_SIZE, "%s/%s.xml", USR_SHARE_PACKAGES, pkgid);
2585 snprintf(resultxml, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2588 const char *convert_argv[] = { RPM_UPDATE_XML, manifest, clientid, resultxml, NULL };
2589 ret = _ri_xsystem(convert_argv);
2591 _LOGE("@Failed to convert the manifest.xml");
2595 _LOGD("#client id[%s], input manifest:[%s], dest manifest:[%s]", clientid, manifest, resultxml);
2598 /* send event for install_percent */
2599 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "60");
2601 /* Parse the manifest to get install location and size.
2602 If installation fails, remove manifest info from DB */
2603 if (clientid != NULL) {
2604 ret = pkgmgr_parser_parse_manifest_for_installation(resultxml, NULL);
2606 ret = pkgmgr_parser_parse_manifest_for_installation(manifest, NULL);
2609 _LOGE("@failed to parse the manifest.");
2610 ret = RPM_INSTALLER_ERR_INTERNAL;
2613 _LOGD("#manifest parsing success");
2615 #ifdef APP2EXT_ENABLE
2616 if ((handle != NULL) && (handle->interface.post_install != NULL)) {
2617 __rpm_clear_dir_list(dir_list);
2618 handle->interface.post_install(gpkgname, APP2EXT_STATUS_SUCCESS);
2619 app2ext_deinit(handle);
2622 /* register cert info */
2623 _ri_register_cert(pkgid);
2626 _coretpk_installer_search_ui_gadget(pkgid);
2628 /* apply smack to shared dir */
2629 ret = __get_smack_label_from_db(pkgid, &smack_label);
2630 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
2632 __rpm_apply_smack(pkgid, 1, smack_label);
2634 /* apply smack by privilege */
2635 ret = _ri_apply_privilege(pkgid, 0, smack_label);
2637 _LOGE("@failed to apply permission(%d).", ret);
2639 _LOGD("#permission applying success.");
2642 ret = _ri_smack_reload_all();
2644 _LOGD("@failed to reload_all the smack.");
2647 /* send event for install_percent */
2648 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "100");
2650 ret = RPM_INSTALLER_SUCCESS;
2653 _installer_util_delete_dir(TEMP_DIR);
2654 _installer_util_delete_dir(TEMP_DBPATH);
2656 if (ret == RPM_INSTALLER_SUCCESS) {
2657 _LOGD("[#]end : _rpm_install_pkg_with_dbpath");
2658 __ri_launch_consumer(pkgid);
2659 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "ok");
2660 _ri_stat_cb(pkgid, "end", "ok");
2662 _LOGE("[@]end : _rpm_install_pkg_with_dbpath");
2663 /* remove db info */
2664 ret = _coretpk_installer_remove_db_info(pkgid);
2666 _LOGE("_coretpk_installer_remove_db_info is failed.");
2669 char *errstr = NULL;
2670 _ri_error_no_to_string(ret, &errstr);
2671 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "error", errstr);
2672 _ri_stat_cb(pkgid, "error", errstr);
2673 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "fail");
2675 _ri_stat_cb(pkgid, "end", "fail");
2676 _LOGE("install failed with err(%d) (%s)\n", ret, errstr);
2679 FREE_AND_NULL(smack_label);
2684 int _rpm_upgrade_pkg_with_dbpath(char *pkgfilepath, char *pkgid)
2687 char manifest[BUF_SIZE] = { '\0' };
2688 char cwd[BUF_SIZE] = { '\0' };
2690 pkgmgrinfo_pkginfo_h pkghandle;
2692 #ifdef APP2EXT_ENABLE
2693 app2ext_handle *handle = NULL;
2694 GList *dir_list = NULL;
2695 pkgmgrinfo_installed_storage location = 1;
2697 unsigned long rpm_size = 0;
2699 char *smack_label = NULL;
2700 char resxml[BUF_SIZE] = { '\0' };
2701 char buf[BUF_SIZE] = { 0, };
2703 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "start", "update");
2704 _LOGD("[#]start : _rpm_upgrade_pkg_with_dbpath");
2706 /* terminate running app */
2707 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
2709 _LOGE("@failed to get pkginfo handle");
2710 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
2713 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
2714 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
2717 temp = getcwd(cwd, BUF_SIZE);
2718 if ((temp == NULL) || (cwd[0] == '\0')) {
2719 _LOGE("@getcwd() failed.");
2720 ret = RPM_INSTALLER_ERR_INTERNAL;
2723 _LOGD("#current working directory is %s.", cwd);
2726 ret = __ri_change_dir(TEMP_DIR);
2728 _LOGE("@change dir failed.");
2729 ret = RPM_INSTALLER_ERR_INTERNAL;
2732 _LOGD("#switched to %s", TEMP_DIR);
2734 /* run cpio script */
2735 const char *cpio_argv[] = { CPIO_SCRIPT, pkgfilepath, NULL };
2736 ret = _ri_xsystem(cpio_argv);
2738 /* get manifext.xml path */
2739 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, OPT_SHARE_PACKAGES, pkgid);
2740 _LOGD("#manifest name is %s.", manifest);
2742 if (access(manifest, F_OK)) {
2743 _LOGD("#there is no RW manifest.xml. check RO manifest.xml.");
2745 memset(manifest, '\0', sizeof(manifest));
2746 snprintf(manifest, BUF_SIZE, "%s%s/%s.xml", TEMP_DIR, USR_SHARE_PACKAGES, pkgid);
2747 _LOGD("#manifest name is %s.", manifest);
2749 if (access(manifest, F_OK)) {
2750 _LOGE("@can not find manifest.xml in the pkg.");
2751 ret = RPM_INSTALLER_ERR_NO_MANIFEST;
2758 /* disable "copy ro-xml to rw-xml", because of some bug */
2759 snprintf(srcpath, BUF_SIZE, "%s", manifest);
2760 memset(manifest, '\0', sizeof(manifest));
2761 snprintf(manifest, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
2763 const char *xml_update_argv[] = { CPIO_SCRIPT_UPDATE_XML, srcpath, manifest, NULL };
2764 ret = _ri_xsystem(xml_update_argv);
2770 /* check existance of res.xml for resource manager */
2771 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, USR_APPS, pkgid);
2772 _LOGD("#path of res.xml is %s", resxml);
2773 if (access(resxml, F_OK) != 0) {
2774 _LOGE("file not found. try other paths");
2775 memset(resxml, '\0', sizeof(resxml));
2776 snprintf(resxml, BUF_SIZE, "%s%s/%s/res/res.xml", TEMP_DIR, OPT_USR_APPS, pkgid);
2777 if (access(resxml, F_OK) != 0) {
2778 _LOGE("file not found");
2779 memset(resxml, '\0', sizeof(resxml));
2783 if (resxml[0] != '\0') {
2784 if (access(resxml, R_OK) == 0) {
2786 ret = pkgmgr_resource_parser_check_xml_validation(resxml);
2788 _LOGE("pkgmgr_resource_parser_check_xml_validation(%s) failed.", resxml);
2789 ret = RPM_INSTALLER_ERR_INTERNAL;
2795 /* send event for install_percent */
2796 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "30");
2798 /* check manifest.xml validation */
2799 ret = pkgmgr_parser_check_manifest_validation(manifest);
2801 _LOGE("@invalid manifest");
2802 ret = RPM_INSTALLER_ERR_INVALID_MANIFEST;
2806 /* check for signature and certificate */
2807 ret = _ri_verify_signatures(TEMP_DIR, pkgid, true);
2809 _LOGE("@signature and certificate failed(%s).", pkgid);
2810 ret = RPM_INSTALLER_ERR_SIG_INVALID;
2813 _LOGD("#_ri_verify_signatures success.");
2818 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
2819 _LOGE("@chdir(%s) failed(%s).", cwd, buf);
2821 ret = RPM_INSTALLER_ERR_INTERNAL;
2825 /* remove dir for clean */
2826 __ri_remove_updated_dir(pkgid);
2828 _LOGD("#Preserve the smack file");
2829 /* Preserve the smack rule file */
2830 ret = __ri_copy_smack_rule_file(UPGRADE_REQ, pkgid, 0);
2831 if (ret != RPM_INSTALLER_SUCCESS)
2834 #ifdef APP2EXT_ENABLE
2835 ret = pkgmgrinfo_pkginfo_get_pkginfo(gpkgname, &pkghandle);
2837 _LOGE("Failed to get pkginfo handle\n");
2838 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
2842 ret = pkgmgrinfo_pkginfo_get_installed_storage(pkghandle, &location);
2844 _LOGE("Failed to get install location\n");
2845 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
2846 ret = RPM_INSTALLER_ERR_INTERNAL;
2850 if (location == PMINFO_EXTERNAL_STORAGE) {
2851 /* Get the rpm's size from rpm header */
2852 rpm_size = _ri_calculate_rpm_size(pkgfilepath);
2853 if (rpm_size == 0) {
2854 _LOGE("@Failed to get size from rpm header\n");
2855 ret = RPM_INSTALLER_ERR_INTERNAL;
2858 rpm_size = rpm_size / (1024 * 1024); /* rpm size in MB */
2859 _LOGD("#Rpm file(%s) size is %lu MB", pkgfilepath, rpm_size);
2861 /* Add margin to the rpm size */
2862 rpm_size = rpm_size + RPM_SIZE_MARGIN(rpm_size);
2863 _LOGD("#Rpm file (%s) size after margin is %lu MB", pkgfilepath, rpm_size);
2865 /* Get the size from the manifest file. */
2866 ret = __get_size_from_xml(manifest, &size);
2867 if (ret != PMINFO_R_OK) {
2869 _LOGD(" #rpm size is %d", size);
2871 size = size > rpm_size ? size : rpm_size;
2872 _LOGD("#rpm size is %d", size);
2876 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
2878 if ((location == PMINFO_EXTERNAL_STORAGE) && size > 0) {
2879 handle = app2ext_init(APP2EXT_SD_CARD);
2880 if (handle == NULL) {
2881 _LOGE("app2ext init failed\n");
2882 ret = RPM_INSTALLER_ERR_INTERNAL;
2886 if ((&(handle->interface) != NULL) && (handle->interface.pre_upgrade != NULL)
2887 && (handle->interface.post_upgrade != NULL)) {
2888 dir_list = __rpm_populate_dir_list();
2889 if (dir_list == NULL) {
2890 _LOGE("\nError in populating the directory list\n");
2891 ret = RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
2892 app2ext_deinit(handle);
2895 ret = handle->interface.pre_upgrade(gpkgname, dir_list, size);
2896 if (ret == APP2EXT_ERROR_MMC_STATUS) {
2897 _LOGE("app2xt MMC is not here, go internal (%d)\n", ret);
2898 } else if (ret == APP2EXT_SUCCESS) {
2899 _LOGE("pre upgrade done, go internal");
2901 _LOGE("app2xt pre upgrade API failed (%d)\n", ret);
2902 __rpm_clear_dir_list(dir_list);
2903 handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_FAILED);
2904 ret = RPM_INSTALLER_ERR_INTERNAL;
2905 app2ext_deinit(handle);
2913 if (home_dir == 0) {
2915 /* disable "UPGRADE_SCRIPT_WITH_DBPATH_RO", because of some bug */
2916 const char *argv[] = { UPGRADE_SCRIPT_WITH_DBPATH_RO, pkgfilepath, NULL };
2917 ret = _ri_xsystem(argv);
2919 const char *argv[] = { UPGRADE_SCRIPT, pkgfilepath, NULL };
2920 ret = _ri_xsystem(argv);
2922 const char *argv[] = { UPGRADE_SCRIPT_WITH_DBPATH_RW, pkgfilepath, NULL };
2923 ret = _ri_xsystem(argv);
2926 _LOGE("@upgrade complete with error(%d)", ret);
2927 #ifdef APP2EXT_ENABLE
2928 if ((handle != NULL) && (handle->interface.post_upgrade != NULL)) {
2929 __rpm_clear_dir_list(dir_list);
2930 handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_FAILED);
2931 app2ext_deinit(handle);
2936 _LOGD("#upgrade script success.");
2938 /* send event for install_percent */
2939 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "60");
2941 /* Parse the manifest to get install location and size.
2942 If fails, remove manifest info from DB. */
2943 ret = pkgmgr_parser_parse_manifest_for_upgrade(manifest, NULL);
2945 _LOGE("@parsing manifest failed.");
2946 ret = RPM_INSTALLER_ERR_INTERNAL;
2949 _LOGD("#parsing manifest success.");
2951 /* unregister cert info */
2952 _ri_unregister_cert(pkgid);
2954 /* register cert info */
2955 _ri_register_cert(pkgid);
2957 #ifdef APP2EXT_ENABLE
2958 if ((handle != NULL) && (handle->interface.post_upgrade != NULL)) {
2959 __rpm_clear_dir_list(dir_list);
2960 handle->interface.post_upgrade(gpkgname, APP2EXT_STATUS_SUCCESS);
2961 app2ext_deinit(handle);
2966 _coretpk_installer_search_ui_gadget(pkgid);
2968 /* apply smack to shared dir */
2969 ret = __get_smack_label_from_db(pkgid, &smack_label);
2970 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
2972 __rpm_apply_smack(pkgid, 1, smack_label);
2974 /* apply smack by privilege */
2975 ret = _ri_apply_privilege(pkgid, 0, smack_label);
2977 _LOGE("@apply perm failed with err(%d)", ret);
2979 _LOGD("#apply perm success.");
2982 ret = _ri_smack_reload_all();
2984 _LOGD("_ri_smack_reload_all failed.");
2987 /* send event for install_percent */
2988 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "install_percent", "100");
2990 ret = RPM_INSTALLER_SUCCESS;
2993 _installer_util_delete_dir(TEMP_DIR);
2994 _installer_util_delete_dir(TEMP_DBPATH);
2996 if (ret == RPM_INSTALLER_SUCCESS) {
2997 _LOGD("[#]end : _rpm_upgrade_pkg_with_dbpath");
2998 __ri_launch_consumer(pkgid);
2999 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "ok");
3000 _ri_stat_cb(pkgid, "end", "ok");
3002 _LOGE("[@]end : _rpm_upgrade_pkg_with_dbpath");
3003 char *errstr = NULL;
3004 _ri_error_no_to_string(ret, &errstr);
3005 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "error", errstr);
3006 _ri_stat_cb(pkgid, "error", errstr);
3007 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "end", "fail");
3009 _ri_stat_cb(pkgid, "end", "fail");
3010 _LOGE("install failed with err(%d) (%s)\n", ret, errstr);
3013 FREE_AND_NULL(smack_label);
3018 int _rpm_uninstall_pkg_with_dbpath(const char *pkgid, bool is_system)
3020 if (pkgid == NULL) {
3021 _LOGE("pkgid is NULL.");
3022 return RPM_INSTALLER_ERR_WRONG_PARAM;
3027 char buff[BUF_SIZE] = { '\0' };
3028 char extpath[BUF_SIZE] = { '\0' };
3029 char tizen_manifest[BUF_SIZE] = { '\0' };
3030 pkgmgrinfo_pkginfo_h pkghandle = NULL;
3031 bool mother_package = false;
3032 bool coretpk = false;
3033 GList *appid_list = NULL;
3035 #ifdef APP2EXT_ENABLE
3036 app2ext_handle *handle = NULL;
3037 pkgmgrinfo_installed_storage location = 1;
3039 char *smack_label = NULL;
3041 _LOGD("pkgid=[%s], is_system=[%d]", pkgid, is_system);
3043 snprintf(tizen_manifest, BUF_SIZE, "%s/%s/tizen-manifest.xml", OPT_USR_APPS, pkgid);
3044 if (access(tizen_manifest, R_OK) == 0) {
3046 _LOGD("[%s] is existing.", tizen_manifest);
3049 /* send start event */
3051 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "start", "update");
3053 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "start", "uninstall");
3056 /* terminate running app */
3057 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3059 _LOGE("pkgmgrinfo_pkginfo_get_pkginfo(%s) failed.", pkgid);
3060 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3063 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, &appid_list);
3065 while (appid_list != NULL) {
3066 _ri_broadcast_app_uninstall_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, (char *)appid_list->data);
3068 if (appid_list->next == NULL)
3071 appid_list = g_list_next(appid_list);
3074 /* If package is mother package, then uninstall child package */
3075 pkgmgrinfo_pkginfo_is_mother_package(pkghandle, &mother_package);
3076 if (mother_package == true) {
3077 _LOGD("[%s] is mother package", pkgid);
3078 __uninstall_child_package_by_mother_pkgid(pkgid);
3080 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3082 ret = __get_smack_label_from_db(pkgid, &smack_label);
3083 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
3085 /* del root path dir */
3086 snprintf(buff, BUF_SIZE, "%s/%s", OPT_USR_APPS, pkgid);
3087 if (__is_dir(buff)) {
3088 _installer_util_delete_dir(buff);
3091 /* del root path dir for ext */
3092 snprintf(extpath, BUF_SIZE, "%s/%s", OPT_STORAGE_SDCARD_APP_ROOT, pkgid);
3093 if (__is_dir(extpath)) {
3094 _installer_util_delete_dir(extpath);
3098 memset(buff, '\0', BUF_SIZE);
3099 snprintf(buff, BUF_SIZE, "%s/%s.xml", OPT_SHARE_PACKAGES, pkgid);
3102 /* check system pkg, if pkg is system pkg, need to update xml on USR_SHARE_PACKAGES */
3104 memset(buff, '\0', BUF_SIZE);
3105 snprintf(buff, BUF_SIZE, "%s/%s.xml", USR_SHARE_PACKAGES, pkgid);
3106 _LOGE("manifest for upgrade, path=[%s]", buff);
3108 ret = pkgmgr_parser_parse_manifest_for_upgrade(buff, NULL);
3110 _LOGE("parsing manifest failed.");
3114 #ifdef APP2EXT_ENABLE
3115 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3117 _LOGE("failed to get pkginfo handle");
3118 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3121 ret = pkgmgrinfo_pkginfo_get_installed_storage(pkghandle, &location);
3123 _LOGE("failed to get install location\n");
3124 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3125 ret = RPM_INSTALLER_ERR_INTERNAL;
3128 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3130 if (location == PMINFO_EXTERNAL_STORAGE) {
3131 handle = app2ext_init(APP2EXT_SD_CARD);
3132 if (handle == NULL) {
3133 _LOGE("app2ext init failed\n");
3134 ret = RPM_INSTALLER_ERR_INTERNAL;
3137 if ((&(handle->interface) != NULL) && (handle->interface.pre_uninstall != NULL) &&
3138 (handle->interface.post_uninstall != NULL) &&
3139 (handle->interface.disable != NULL)) {
3140 ret = handle->interface.disable(pkgid);
3141 if (ret != APP2EXT_SUCCESS) {
3142 _LOGE("Unmount ret[%d]", ret);
3144 ret = app2ext_get_app_location(pkgid);
3145 if (ret == APP2EXT_INTERNAL_MEM) {
3146 _LOGE("app2xt APP is not in MMC, go internal (%d)\n", ret);
3148 ret = handle->interface.pre_uninstall(pkgid);
3149 if (ret == APP2EXT_ERROR_MMC_STATUS) {
3150 _LOGE("app2xt MMC is not here, go internal (%d)\n", ret);
3151 } else if (ret == APP2EXT_SUCCESS) {
3152 _LOGE("pre uninstall done, go to internal");
3154 _LOGE("app2xt pre uninstall API failed (%d)\n", ret);
3155 handle->interface.post_uninstall(pkgid);
3156 app2ext_deinit(handle);
3157 ret = RPM_INSTALLER_ERR_INTERNAL;
3166 ret = pkgmgr_parser_parse_manifest_for_uninstallation(pkgid, NULL);
3168 _LOGE("pkgmgr_parser_parse_manifest_for_uninstallation() failed, pkgid=[%s]", pkgid);
3171 #ifdef APP2EXT_ENABLE
3172 if ((handle != NULL) && (handle->interface.post_uninstall != NULL)) {
3173 handle->interface.post_uninstall(pkgid);
3174 app2ext_deinit(handle);
3179 /* execute privilege APIs */
3180 _ri_privilege_revoke_permissions(smack_label);
3181 _ri_privilege_unregister_package(smack_label);
3183 /* Unregister cert info */
3184 _ri_unregister_cert(pkgid);
3186 ret = RPM_INSTALLER_SUCCESS;
3189 /* Free appid list */
3190 appid_list = g_list_first(appid_list);
3191 while (appid_list != NULL) {
3192 if (appid_list->data != NULL) {
3193 free(appid_list->data);
3196 if (appid_list->next == NULL)
3199 appid_list = g_list_next(appid_list);
3201 g_list_free(appid_list);
3203 /* Restore the old smack file */
3204 if (coretpk == false) {
3205 tmp = __ri_copy_smack_rule_file(UNINSTALL_REQ, pkgid, is_system);
3206 if (tmp != RPM_INSTALLER_SUCCESS) {
3207 _LOGD("smack restore failed");
3211 tmp = _ri_smack_reload_all();
3213 _LOGD("_ri_smack_reload_all failed.");
3220 _LOGE("failed, ret=[%d]", ret);
3221 char *errstr = NULL;
3222 _ri_error_no_to_string(ret, &errstr);
3223 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "error", errstr);
3224 _ri_stat_cb(pkgid, "error", errstr);
3226 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "end", "fail");
3227 _ri_stat_cb(pkgid, "end", "fail");
3228 _LOGE("remove failed with err(%d) (%s)\n", ret, errstr);
3231 _ri_broadcast_status_notification(pkgid, coretpk ? PKGTYPE_TPK : PKGTYPE_RPM, "end", "ok");
3232 _ri_stat_cb(pkgid, "end", "ok");
3235 FREE_AND_NULL(smack_label);
3240 int _rpm_uninstall_pkg(char *pkgid)
3245 bool is_removable = 0;
3246 pkgmgrinfo_install_location location = 1;
3247 #ifdef APP2EXT_ENABLE
3248 app2ext_handle *handle = NULL;
3250 #ifdef PRE_CHECK_FOR_MANIFEST
3251 char *manifest = NULL;
3254 char *smack_label = NULL;
3256 pkgmgrinfo_pkginfo_h pkghandle;
3257 const char *argv[] = { UNINSTALL_SCRIPT, pkgid, NULL };
3259 _LOGD("start : _rpm_uninstall_pkg\n");
3261 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &pkghandle);
3263 _LOGE("Failed to get pkginfo handle\n");
3264 return RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3266 /* terminate running app */
3267 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3269 ret = pkgmgrinfo_pkginfo_is_system(pkghandle, &is_system);
3271 _LOGE("pkgmgrinfo_pkginfo_is_system failed.\n");
3272 return RPM_INSTALLER_ERR_INTERNAL;
3275 ret = pkgmgrinfo_pkginfo_is_update(pkghandle, &is_update);
3277 _LOGE("pkgmgrinfo_pkginfo_is_system failed.\n");
3278 return RPM_INSTALLER_ERR_INTERNAL;
3281 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3282 /* updated and system pkg need to "remove-update" */
3283 _LOGD("Remove Update[%s]", pkgid);
3284 ret = _rpm_uninstall_pkg_with_dbpath(pkgid, 1);
3286 _LOGE("uninstall_pkg_with_dbpath for system, is_update fail\n");
3291 pkgmgrinfo_pkginfo_is_removable(pkghandle, &is_removable);
3293 /* non-system and can be removable, it should be deleted */
3294 _LOGD("Delete Package [%s]", pkgid);
3295 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3296 ret = _rpm_uninstall_pkg_with_dbpath(pkgid, 0);
3298 _LOGE("uninstall_pkg_with_dbpath for non-system, is_remove fail\n");
3304 _ri_broadcast_status_notification(pkgid, PKGTYPE_RPM, "start", "uninstall");
3306 #ifdef APP2EXT_ENABLE
3307 ret = pkgmgrinfo_pkginfo_get_install_location(pkghandle, &location);
3309 _LOGE("Failed to get install location\n");
3310 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3311 return RPM_INSTALLER_ERR_INTERNAL;
3314 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3316 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3317 if (location == PMINFO_INSTALL_LOCATION_PREFER_EXTERNAL) {
3318 handle = app2ext_init(APP2EXT_SD_CARD);
3319 if (handle == NULL) {
3320 _LOGE("app2ext init failed\n");
3321 return RPM_INSTALLER_ERR_INTERNAL;
3323 if ((&(handle->interface) != NULL) && (handle->interface.pre_uninstall != NULL) &&
3324 (handle->interface.post_uninstall != NULL)) {
3325 ret = app2ext_get_app_location(pkgid);
3326 if (ret == APP2EXT_INTERNAL_MEM) {
3327 _LOGE("app2xt APP is not in MMC, go internal (%d)\n", ret);
3329 ret = handle->interface.pre_uninstall(pkgid);
3330 if (ret == APP2EXT_ERROR_MMC_STATUS || ret == APP2EXT_SUCCESS) {
3331 _LOGE("app2xt MMC is not here, go internal (%d)\n", ret);
3333 _LOGE("app2xt pre uninstall API failed (%d)\n", ret);
3334 handle->interface.post_uninstall(pkgid);
3335 app2ext_deinit(handle);
3336 return RPM_INSTALLER_ERR_INTERNAL;
3343 ret = __get_smack_label_from_db(pkgid, &smack_label);
3344 _LOGD("smack_label[%s], ret[%d]\n", smack_label, ret);
3346 #ifdef PRE_CHECK_FOR_MANIFEST
3347 /* Manifest info should be removed first because after installation manifest
3348 file is uninstalled. If uninstallation fails, we need to re-insert manifest info for consistency */
3349 manifest = pkgmgr_parser_get_manifest_file(pkgid);
3350 if (manifest == NULL) {
3351 _LOGE("manifest name is NULL\n");
3352 app2ext_deinit(handle);
3353 FREE_AND_NULL(smack_label);
3354 return RPM_INSTALLER_ERR_NO_MANIFEST;
3356 _LOGD("manifest name is %s\n", manifest);
3357 ret = pkgmgr_parser_parse_manifest_for_uninstallation(manifest, NULL);
3359 _LOGE("pkgmgr_parser_parse_manifest_for_uninstallation failed.\n");
3363 ret = _rpm_xsystem(argv);
3365 _LOGE("uninstall failed with error(%d)\n", ret);
3366 #ifdef PRE_CHECK_FOR_MANIFEST
3367 err = pkgmgr_parser_parse_manifest_for_installation(manifest, NULL);
3369 _LOGE("Parsing Manifest Failed\n");
3372 FREE_AND_NULL(manifest);
3374 #ifdef APP2EXT_ENABLE
3375 if ((handle != NULL) && (handle->interface.post_uninstall != NULL)) {
3376 handle->interface.post_uninstall(pkgid);
3377 app2ext_deinit(handle);
3381 FREE_AND_NULL(smack_label);
3385 #ifdef APP2EXT_ENABLE
3386 if ((handle != NULL) && (handle->interface.post_uninstall != NULL)) {
3387 handle->interface.post_uninstall(pkgid);
3388 app2ext_deinit(handle);
3392 /* execute privilege APIs */
3393 _ri_privilege_revoke_permissions(smack_label);
3394 _ri_privilege_unregister_package(smack_label);
3396 /* Unregister cert info */
3397 _ri_unregister_cert(gpkgname);
3399 FREE_AND_NULL(manifest);
3400 FREE_AND_NULL(smack_label);
3402 _LOGD("end : _rpm_uninstall_pkg(%d)\n", ret);
3407 int _rpm_install_corexml(const char *pkgfilepath, char *pkgid)
3411 /* validate signature and certifictae */
3412 ret = _ri_verify_signatures(USR_APPS, pkgid, true);
3414 _LOGE("_ri_verify_signatures Failed : %s\n", pkgid);
3415 ret = RPM_INSTALLER_ERR_SIG_INVALID;
3419 /* Parse and insert manifest in DB */
3420 ret = pkgmgr_parser_parse_manifest_for_installation(pkgfilepath, NULL);
3422 _LOGD("Installing Manifest Failed : %s\n", pkgfilepath);
3423 ret = RPM_INSTALLER_ERR_PACKAGE_NOT_INSTALLED;
3427 /* _ri_register_cert has __ri_free_cert_chain. */
3428 _ri_register_cert(pkgid);
3431 _coretpk_installer_search_ui_gadget(pkgid);
3433 ret = RPM_INSTALLER_SUCCESS;
3437 __ri_free_cert_chain();
3443 int _rpm_move_pkg(char *pkgid, int move_type)
3445 app2ext_handle *hdl = NULL;
3448 GList *dir_list = NULL;
3449 pkgmgrinfo_pkginfo_h pkghandle = NULL;
3451 if (move_type == PM_MOVE_TO_INTERNAL)
3452 movetype = APP2EXT_MOVE_TO_PHONE;
3453 else if (move_type == PM_MOVE_TO_SDCARD)
3454 movetype = APP2EXT_MOVE_TO_EXT;
3456 return RPM_INSTALLER_ERR_WRONG_PARAM;
3458 ret = pkgmgrinfo_pkginfo_get_pkginfo(gpkgname, &pkghandle);
3460 _LOGE("@failed to get the pkginfo handle!!");
3461 ret = RPM_INSTALLER_ERR_PKG_NOT_FOUND;
3465 /* Terminate the running instance of app */
3466 pkgmgrinfo_appinfo_get_list(pkghandle, PM_UI_APP, __ri_check_running_app, NULL);
3467 pkgmgrinfo_pkginfo_destroy_pkginfo(pkghandle);
3468 hdl = app2ext_init(APP2EXT_SD_CARD);
3469 if ((hdl != NULL) && (hdl->interface.move != NULL)) {
3470 dir_list = __rpm_populate_dir_list();
3471 if (dir_list == NULL) {
3472 _LOGE("\nError in populating the directory list\n");
3473 return RPM_INSTALLER_ERR_RPM_SCRIPT_WRONG_ARGS;
3475 ret = hdl->interface.move(pkgid, dir_list, movetype);
3476 __rpm_clear_dir_list(dir_list);
3478 _LOGE("Failed to move app\n");
3479 return RPM_INSTALLER_ERR_INTERNAL;
3481 app2ext_deinit(hdl);
3482 return RPM_INSTALLER_SUCCESS;
3484 _LOGE("Failed to get app2ext handle\n");
3485 return RPM_INSTALLER_ERR_INTERNAL;
3489 int _rpm_process_cscxml(char *csc_script)
3494 char *path_str = NULL;
3495 char *op_str = NULL;
3496 char *remove_str = NULL;
3497 char csc_str[BUF_SIZE] = { '\0' };
3498 snprintf(csc_str, BUF_SIZE - 1, "%s:", csc_script);
3500 /* get params from csc script */
3501 path_str = _installer_util_get_str(csc_str, TOKEN_PATH_STR);
3502 op_str = _installer_util_get_str(csc_str, TOKEN_OPERATION_STR);
3503 remove_str = _installer_util_get_str(csc_str, TOKEN_REMOVE_STR);
3504 if ((path_str == NULL) || (op_str == NULL) || (remove_str == NULL)) {
3505 _LOGE("csc-info : input param is null[%s, %s, %s]\n", path_str, op_str, remove_str);
3508 _LOGD("csc-info : path=%s, op=%s, remove=%s\n", path_str, op_str, remove_str);
3510 /* get operation type */
3511 op_type = __ri_get_op_type(op_str);
3513 _LOGE("csc-info : operation error[%s, %s]\n", path_str, op_str);
3519 ret = __ri_install_csc(path_str, remove_str);
3523 ret = __ri_install_csc(path_str, remove_str);
3527 ret = __ri_uninstall_csc(path_str);
3535 _LOGE("fota-info : Fota fail [pkgid=%s, operation=%d]\n", path_str, op_type);
3548 int __ri_copy_smack_rule_file(int op, const char *pkgname, int is_system)
3550 mode_t mode = DIR_PERMS;
3551 int ret = RPM_INSTALLER_SUCCESS;
3552 char src[BUF_SIZE] = { 0 };
3553 char dest[BUF_SIZE] = { 0 };
3554 char buf[BUF_SIZE] = { 0, };
3558 /* For downloadable native app, restore the smack file.
3559 Otherwise, remove the stored smack file. */
3560 snprintf(dest, BUF_SIZE - 1, "%s/%s.rule", SMACK_RULES_ALT_PATH, pkgname);
3561 snprintf(src, BUF_SIZE - 1, "%s%s.rule", DIR_RPM_WGT_SMACK_RULE_OPT, pkgname);
3562 _LOGD("#src:[%s] dest:[%s]", src, dest);
3565 if (!access(src, F_OK)) {
3568 _LOGD("#File [%s] deleted.", src);
3570 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
3571 _LOGE("@Unable to delete the file [%s], error:(%s)", src, buf);
3573 ret = RPM_INSTALLER_ERR_INTERNAL;
3577 if (!access(dest, F_OK)) {
3580 _LOGD("#File [%s] deleted.", dest);
3582 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
3583 _LOGE("@Unable to delete the file [%s], error:(%s)", dest, buf);
3585 ret = RPM_INSTALLER_ERR_INTERNAL;
3590 _LOGD("#Restore smack files for uninstallation [%s]", pkgname);
3591 if (!access(src, F_OK)) {
3592 _LOGD("#Copying [%s] to [%s]", src, dest);
3593 ret = __copy_file(src, dest);
3597 _LOGD("#File [%s] deleted.", src);
3599 if( strerror_r(errno, buf, sizeof(buf)) == 0) {
3600 _LOGE("@Unable to delete the file [%s], error:(%s)", src, buf);
3602 ret = RPM_INSTALLER_ERR_INTERNAL;
3606 _LOGE("@Copy Failed!!");
3607 ret = RPM_INSTALLER_ERR_INTERNAL;
3611 _LOGE("@ %s.rule file is not preserved", pkgname);
3616 _LOGD("#Preserve the smack file for upgrade [%s]", pkgname);
3618 /* Apply the new smack file and preserve the old smack rule file
3619 if it is not preserved. */
3620 snprintf(src, BUF_SIZE - 1, "%s/%s.rule", SMACK_RULES_ALT_PATH, pkgname);
3621 snprintf(dest, BUF_SIZE - 1, "%s%s.rule", DIR_RPM_WGT_SMACK_RULE_OPT, pkgname);
3623 _LOGD("#src[%s] dest[%s]", src, dest);
3625 /* Create the directory if not exist to preserve the smack files */
3626 if (mkdir(DIR_RPM_WGT_SMACK_RULE_OPT, mode) == 0 || errno == EEXIST) {
3627 if ((access(src, F_OK) == 0) && (access(dest, F_OK) != 0)) {
3628 ret = __copy_file(src, dest);
3630 _LOGD("#Smack file is already preserved");
3633 _LOGE("@Temporary folder creation failed");
3634 ret = RPM_INSTALLER_ERR_INTERNAL;
3638 _LOGE("@Unsupported Operation\n");
3639 ret = RPM_INSTALLER_ERR_INTERNAL;
3645 int __get_smack_label_from_xml(const char *manifest, const char *pkgid, char **label)
3647 const char *val = NULL;
3648 char pkgpath[BUF_SIZE] = { '\0' };
3649 const xmlChar *node;
3650 xmlTextReaderPtr reader;
3651 int ret = PMINFO_R_OK;
3653 if (label == NULL) {
3654 _LOGE("space for label is NULL\n");
3655 return PMINFO_R_ERROR;
3660 if (pkgid == NULL) {
3661 _LOGE("pkgid is NULL\n");
3662 return PMINFO_R_ERROR;
3665 if (manifest == NULL) {
3666 _LOGE("manifest is NULL\n");
3667 *label = strdup(pkgid);
3668 return PMINFO_R_ERROR;
3671 snprintf(pkgpath, BUF_SIZE, "%s/%s/tizen-manifest.xml", OPT_USR_APPS, pkgid);
3672 if (access(pkgpath, R_OK) == 0) {
3673 _LOGE("This is a core tpk package");
3674 *label = strdup(pkgid);
3678 reader = xmlReaderForFile(manifest, NULL, 0);
3681 if (_child_element(reader, -1)) {
3682 node = xmlTextReaderConstName(reader);
3684 _LOGE("xmlTextReaderConstName value is NULL\n");
3685 ret = PMINFO_R_ERROR;
3689 if (!strcmp(ASCII(node), "manifest")) {
3690 ret = _ri_get_attribute(reader, "smack-label", &val);
3692 _LOGE("@Error in getting the attribute value");
3693 ret = PMINFO_R_ERROR;
3697 *label = strdup(val);
3698 if (*label == NULL) {
3699 _LOGE("Out of memeory\n");
3700 ret = PMINFO_R_ERROR;
3705 _LOGE("package smack-label is not specified\n");
3709 _LOGE("Unable to create xml reader\n");
3710 ret = PMINFO_R_ERROR;
3715 _LOGE("xmlReaderForFile value is NULL\n");
3716 ret = PMINFO_R_ERROR;
3721 xmlFreeTextReader(reader);
3723 if (*label == NULL) {
3724 *label = strdup(pkgid);
3730 int __get_smack_label_from_db(const char *pkgid, char **label)
3732 char *smack_label = NULL;
3733 pkgmgrinfo_pkginfo_h handle = NULL;
3734 int ret = PMINFO_R_OK;
3736 if (label == NULL) {
3737 _LOGE("space for label is NULL\n");
3738 return PMINFO_R_ERROR;
3743 if (pkgid == NULL) {
3744 _LOGE("pkgid is NULL\n");
3745 return PMINFO_R_ERROR;
3748 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
3749 if (ret != PMINFO_R_OK) {
3750 _LOGE("failed to get pkginfo\n");
3751 ret = PMINFO_R_ERROR;
3754 ret = pkgmgrinfo_pkginfo_get_custom_smack_label(handle, &smack_label);
3755 if (ret != PMINFO_R_OK) {
3756 _LOGE("failed to get custom smack_label\n");
3757 ret = PMINFO_R_ERROR;
3761 _LOGD("smack_label(%s)\n", smack_label);
3763 *label = strdup(smack_label);
3767 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
3769 if (*label == NULL) {
3770 *label = strdup(pkgid);