app_installer.cc
context_installer.cc
pkgmgr_interface.cc
+ pkgmgr_registration.cc
pkgmgr_signal.cc
security_registration.cc
step/step_backup_icons.cc
#include <unistd.h>
#include <sys/types.h>
+#include <vcore/Certificate.h>
#include <memory>
#include <string>
virtual ~BackendData() { }
};
+class CertificateInfo {
+ public:
+ Property<ValidationCore::CertificatePtr> author_certificate;
+};
+
enum class PrivilegeLevel : int {
UNTRUSTED = 0,
PUBLIC = 1,
// request privilege level of package
Property<PrivilegeLevel> privilege_level;
+
+ // certificate information
+ Property<CertificateInfo> certificate_info;
};
boost::filesystem::path GetBackupPathForPackagePath(
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/pkgmgr_registration.h"
+
+#include <pkgmgr-info.h>
+#include <pkgmgr_installer.h>
+#include <tzplatform_config.h>
+
+#include "common/utils/logging.h"
+
+namespace bf = boost::filesystem;
+
+namespace {
+
+// TODO(sdi2): Check if data->removable is correctly setting
+// during parsing step.
+// Same check should be done for preload field.
+
+// Having a specific step to implement a installer commandline tool
+// for image build could be usefull also.
+const char* const kAppinstTags[] = {"removable=true", nullptr, };
+
+bool RegisterAuthorCertificate(
+ const common_installer::CertificateInfo& cert_info,
+ const std::string& pkgid, uid_t uid) {
+ pkgmgr_instcertinfo_h handle;
+ if (pkgmgr_installer_create_certinfo_set_handle(&handle) < 0) {
+ LOG(ERROR) << "Cannot create pkgmgr_instcertinfo_h";
+ return false;
+ }
+
+ const auto& cert = cert_info.author_certificate.get();
+ pkgmgr_instcert_type inst_cert_type = PM_SET_AUTHOR_ROOT_CERT;
+ if (cert->isRootCert()) {
+ inst_cert_type = PM_SET_AUTHOR_ROOT_CERT;
+ } else if (cert->isCA()) {
+ inst_cert_type = PM_SET_AUTHOR_INTERMEDIATE_CERT;
+ } else {
+ inst_cert_type = PM_SET_AUTHOR_SIGNER_CERT;
+ }
+
+ if (pkgmgr_installer_set_cert_value(handle, inst_cert_type,
+ const_cast<char*>(cert->getBase64().c_str())) < 0) {
+ pkgmgr_installer_destroy_certinfo_set_handle(handle);
+ LOG(ERROR) << "pkgmgrInstallerSetCertValue fail";
+ return false;
+ }
+
+ if (pkgmgr_installer_save_certinfo(pkgid.c_str(), handle, uid) < 0) {
+ pkgmgr_installer_destroy_certinfo_set_handle(handle);
+ LOG(ERROR) << "Failed to save certificate information";
+ return false;
+ }
+
+ pkgmgr_installer_destroy_certinfo_set_handle(handle);
+ return true;
+}
+
+} // anonymous namespace
+
+namespace common_installer {
+
+bool RegisterAppInPkgmgr(const bf::path& xml_path,
+ const std::string& pkgid,
+ const CertificateInfo& cert_info, uid_t uid) {
+ int ret = uid != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
+ pkgmgr_parser_parse_usr_manifest_for_installation(
+ xml_path.c_str(), uid, const_cast<char* const*>(kAppinstTags)) :
+ pkgmgr_parser_parse_manifest_for_installation(
+ xml_path.c_str(), const_cast<char* const*>(kAppinstTags));
+ if (ret) {
+ LOG(ERROR) << "Failed to unregister package: " << xml_path;
+ return false;
+ }
+
+ if (!!cert_info.author_certificate.get()) {
+ if (!RegisterAuthorCertificate(cert_info, pkgid, uid)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool UpgradeAppInPkgmgr(const bf::path& xml_path, const std::string& pkgid,
+ const CertificateInfo& cert_info, uid_t uid) {
+ int ret = uid != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
+ pkgmgr_parser_parse_usr_manifest_for_upgrade(
+ xml_path.string().c_str(), uid,
+ const_cast<char* const*>(kAppinstTags)) :
+ pkgmgr_parser_parse_manifest_for_upgrade(
+ xml_path.string().c_str(),
+ const_cast<char* const*>(kAppinstTags));
+
+ if (ret != 0) {
+ LOG(ERROR) << "Failed to upgrade package: " << xml_path;
+ return false;
+ }
+
+ (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
+ if (!!cert_info.author_certificate.get()) {
+ if (!RegisterAuthorCertificate(cert_info, pkgid, uid)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool UnregisterAppInPkgmgr(const bf::path& xml_path,
+ const std::string& pkgid, uid_t uid) {
+ int ret = uid != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
+ pkgmgr_parser_parse_usr_manifest_for_uninstallation(
+ xml_path.string().c_str(), uid,
+ const_cast<char* const*>(kAppinstTags)) :
+ pkgmgr_parser_parse_manifest_for_uninstallation(
+ xml_path.string().c_str(), const_cast<char* const*>(kAppinstTags));
+ if (ret) {
+ LOG(ERROR) << "Failed to unregister package: " << xml_path;
+ return false;
+ }
+
+ // Certificate info may be not present
+ (void) pkgmgr_installer_delete_certinfo(pkgid.c_str());
+
+ return true;
+}
+
+std::string QueryCertificateAuthorCertificate(const std::string& pkgid) {
+ pkgmgrinfo_certinfo_h handle;
+ int ret = pkgmgrinfo_pkginfo_create_certinfo(&handle);
+ if (ret != PMINFO_R_OK) {
+ LOG(ERROR) << "pkgmgrinfo_pkginfo_create_certinfo failed with error: "
+ << ret;
+ return {};
+ }
+ ret = pkgmgrinfo_pkginfo_load_certinfo(pkgid.c_str(), handle, getuid());
+ if (ret != PMINFO_R_OK) {
+ LOG(ERROR) << "pkgmgrinfo_pkginfo_load_certinfo failed with error: " << ret;
+ pkgmgrinfo_pkginfo_destroy_certinfo(handle);
+ return {};
+ }
+ const char* author_cert = nullptr;
+ ret = pkgmgrinfo_pkginfo_get_cert_value(handle, PMINFO_AUTHOR_SIGNER_CERT,
+ &author_cert);
+ if (ret != PMINFO_R_OK) {
+ LOG(ERROR) << "pkgmgrinfo_pkginfo_get_cert_value failed with error: "
+ << ret;
+ pkgmgrinfo_pkginfo_destroy_certinfo(handle);
+ return {};
+ }
+ std::string old_author_certificate;
+ if (author_cert)
+ old_author_certificate = author_cert;
+ pkgmgrinfo_pkginfo_destroy_certinfo(handle);
+ return old_author_certificate;
+}
+
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_PKGMGR_REGISTRATION_H_
+#define COMMON_PKGMGR_REGISTRATION_H_
+
+#include <boost/filesystem.hpp>
+#include <unistd.h>
+
+#include <string>
+
+#include "common/context_installer.h"
+
+namespace common_installer {
+
+bool RegisterAppInPkgmgr(const boost::filesystem::path& xml_path,
+ const std::string& pkgid,
+ const CertificateInfo& cert_info, uid_t uid);
+bool UpgradeAppInPkgmgr(const boost::filesystem::path& xml_path,
+ const std::string& pkgid,
+ const CertificateInfo& cert_info, uid_t uid);
+bool UnregisterAppInPkgmgr(const boost::filesystem::path& xml_path,
+ const std::string& pkgid, uid_t uid);
+std::string QueryCertificateAuthorCertificate(const std::string& pkgid);
+
+} // namespace common_installer
+
+#endif // COMMON_PKGMGR_REGISTRATION_H_
common_installer::Step::Status ValidateSignatureFile(
const bf::path& base_path,
const ValidationCore::SignatureFileInfo& file_info,
- common_installer::PrivilegeLevel* level) {
+ common_installer::PrivilegeLevel* level,
+ common_installer::CertificateInfo* cert_info) {
bf::path path = base_path / file_info.getFileName();
LOG(INFO) << "Processing signature: " << path;
ValidationCore::SignatureData data(path.string(), file_info.getFileNumber());
*level == common_installer::PrivilegeLevel::UNTRUSTED) {
*level = CertStoreIdToPrivilegeLevel(data.getVisibilityLevel());
}
+ } else {
+ // set author certificate to be saved in pkgmgr
+ cert_info->author_certificate.set(data.getEndEntityCertificatePtr());
}
break;
};
namespace signature {
Step::Status ValidateSignatures(const bf::path& base_path,
- PrivilegeLevel* level) {
+ PrivilegeLevel* level, common_installer::CertificateInfo* cert_info) {
ValidationCore::VCoreInit();
// Find signature files
ValidationCore::SignatureFileInfoSet signature_files;
// Read xml schema for signatures
for (auto& file_info : signature_files) {
- Step::Status status = ValidateSignatureFile(base_path, file_info, level);
+ Step::Status status = ValidateSignatureFile(base_path, file_info, level,
+ cert_info);
if (status != Step::Status::OK) {
ValidationCore::VCoreDeinit();
return status;
Step::Status StepCheckSignature::process() {
PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
Status status =
- ValidateSignatures(context_->unpacked_dir_path.get(), &level);
+ ValidateSignatures(context_->unpacked_dir_path.get(), &level,
+ &context_->certificate_info.get());
if (status != Status::OK) {
return status;
}
// Exposed for tests
Step::Status ValidateSignatures(const boost::filesystem::path& base_path,
- PrivilegeLevel* level);
+ PrivilegeLevel* level, common_installer::CertificateInfo* cert_info);
} // namespace signature
} // namespace common_installer
#include "common/step/step_register_app.h"
-#include <pkgmgr-info.h>
#include <unistd.h>
-#include <boost/filesystem.hpp>
#include <cassert>
#include <cstring>
#include <cstdio>
#include <string>
+#include "common/pkgmgr_registration.h"
#include "common/utils/file_util.h"
-namespace {
-
-const char* const kAppinstTags[] = {"removable=true", nullptr, };
-
-} // anonymous namespace
-
namespace common_installer {
namespace register_app {
}
Step::Status StepRegisterApplication::process() {
- // TODO(sdi2): Check if data->removable is correctly setting
- // during parsing step.
- // Same check should be done for preload field.
-
- // Having a specific step to implement a installer commandline tool
- // for image build could be usefull also.
-
- int ret = context_->uid.get() != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
- pkgmgr_parser_parse_usr_manifest_for_installation(
- context_->xml_path.get().c_str(), context_->uid.get(),
- const_cast<char* const*>(kAppinstTags)) :
- pkgmgr_parser_parse_manifest_for_installation(
- context_->xml_path.get().c_str(),
- const_cast<char* const*>(kAppinstTags));
-
- if (ret) {
+ if (!RegisterAppInPkgmgr(context_->xml_path.get(),
+ context_->pkgid.get().c_str(),
+ context_->certificate_info.get(),
+ context_->uid.get())) {
LOG(ERROR) << "Failed to register the app";
return Step::Status::ERROR;
}
- in_registry_ = true;
LOG(INFO) << "Successfully registered the app";
return Status::OK;
}
Step::Status StepRegisterApplication::undo() {
- if (in_registry_) {
- int ret = context_->uid.get() != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
- pkgmgr_parser_parse_usr_manifest_for_uninstallation(
- context_->xml_path.get().c_str(), context_->uid.get(),
- const_cast<char* const*>(kAppinstTags)) :
- pkgmgr_parser_parse_manifest_for_uninstallation(
- context_->xml_path.get().c_str(),
- const_cast<char* const*>(kAppinstTags));
-
- if (ret) {
- LOG(ERROR) << "Failed to restore old content pkgmgr database";
- return Step::Status::ERROR;
- }
- LOG(INFO) << "Successfuly clean database";
- }
+ UnregisterAppInPkgmgr(context_->xml_path.get(), context_->pkgid.get(),
+ context_->uid.get());
+ LOG(INFO) << "Successfuly clean database";
return Status::OK;
}
class StepRegisterApplication : public Step {
public:
- explicit StepRegisterApplication(ContextInstaller* context)
- : Step(context),
- in_registry_(false) { }
+ using Step::Step;
Status process() override;
Status clean() override;
Status undo() override;
Status precheck() override;
- private:
- bool in_registry_;
-
SCOPE_LOG_TAG(RegisterApp)
};
#include <unistd.h>
#include <boost/filesystem.hpp>
+#include <pkgmgr_installer.h>
#include <cassert>
#include <cstring>
+#include "common/pkgmgr_registration.h"
#include "common/step/step_unregister_app.h"
#include "common/utils/file_util.h"
}
Step::Status StepUnregisterApplication::process() {
- const char* const appinst_tags[] = {"removable=true", nullptr, };
-
- int ret = context_->uid.get() != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
- pkgmgr_parser_parse_usr_manifest_for_uninstallation(
- context_->xml_path.get().c_str(), context_->uid.get(),
- const_cast<char* const*>(appinst_tags)) :
- pkgmgr_parser_parse_manifest_for_uninstallation(
- context_->xml_path.get().c_str(),
- const_cast<char* const*>(appinst_tags));
-
- if (ret != 0) {
+ if (!UnregisterAppInPkgmgr(context_->xml_path.get(), context_->pkgid.get(),
+ context_->uid.get())) {
LOG(ERROR) << "Failed to unregister package into database";
return Status::ERROR;
}
+
LOG(DEBUG) << "Successfully unregister the application";
return Status::OK;
#include <unistd.h>
#include <boost/filesystem.hpp>
+#include <vcore/Base64.h>
+#include <vcore/Certificate.h>
+
#include <cassert>
#include <cstdio>
#include <cstring>
#include <string>
+#include "common/pkgmgr_registration.h"
#include "common/utils/file_util.h"
namespace bf = boost::filesystem;
-namespace {
-
-const char* const kAppinstTags[] = {"removable=true", nullptr, };
-
-bool UpgradeManifestInformation(uid_t uid, const bf::path& xml_path) {
- int ret = uid != tzplatform_getuid(TZ_SYS_GLOBALAPP_USER) ?
- pkgmgr_parser_parse_usr_manifest_for_upgrade(
- xml_path.string().c_str(), uid,
- const_cast<char* const*>(kAppinstTags)) :
- pkgmgr_parser_parse_manifest_for_upgrade(
- xml_path.string().c_str(),
- const_cast<char* const*>(kAppinstTags));
- return !ret;
-}
-
-} // anonymous namespace
-
namespace common_installer {
namespace update_app {
}
Step::Status StepUpdateApplication::process() {
- if (!UpgradeManifestInformation(context_->uid.get(),
- context_->xml_path.get())) {
+ if (!UpgradeAppInPkgmgr(context_->xml_path.get(),
+ context_->pkgid.get(), context_->certificate_info.get(),
+ context_->uid.get())) {
LOG(ERROR) << "Cannot upgrade manifest for application";
return Status::ERROR;
}
}
Step::Status StepUpdateApplication::undo() {
- if (!UpgradeManifestInformation(context_->uid.get(),
- context_->backup_xml_path.get())) {
+ // Prepare certification info for revert
+ ValidationCore::Base64Decoder decoder;
+ decoder.append(QueryCertificateAuthorCertificate(context_->pkgid.get()));
+ decoder.finalize();
+ CertificateInfo certificate_info;
+ certificate_info.author_certificate.set(ValidationCore::CertificatePtr(
+ new ValidationCore::Certificate(decoder.get())));
+
+ if (!UpgradeAppInPkgmgr(context_->backup_xml_path.get(),
+ context_->pkgid.get(), certificate_info,
+ context_->uid.get())) {
LOG(ERROR) << "Cannot revert manifest for application";
return Status::ERROR;
}
signature_file.reset(new bf::path(
"/usr/share/app-installers-ut/test_samples/good_signatures"));
PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
- EXPECT_EQ(ValidateSignatures(*signature_file, &level),
+ common_installer::CertificateInfo cert_info;
+ EXPECT_EQ(ValidateSignatures(*signature_file, &level, &cert_info),
Step::Status::OK);
}
signature_file.reset(new bf::path(
"/usr/share/app-installers-ut/test_samples/bad_signatures"));
PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
- EXPECT_EQ(ValidateSignatures(*signature_file, &level),
+ common_installer::CertificateInfo cert_info;
+ EXPECT_EQ(ValidateSignatures(*signature_file, &level, &cert_info),
Step::Status::ERROR);
}