Add codes for Recover databases 76/182176/11
authorJunghyun Yeon <jungh.yeon@samsung.com>
Thu, 21 Jun 2018 06:15:12 +0000 (15:15 +0900)
committerJunghyun Yeon <jungh.yeon@samsung.com>
Thu, 12 Jul 2018 07:35:25 +0000 (07:35 +0000)
- New request type for register infomation into pkg database is needed.
- Add new options in pkg_initdb to invoke backend with "recover-db" option.
- Add new steps to get privilege level from stored signature values.

Related changes:
[slp-pkgmgr] : https://review.tizen.org/gerrit/182189

Change-Id: If9eb06937fc8049fc354b8a33f161207678b2401
Signed-off-by: Junghyun Yeon <jungh.yeon@samsung.com>
src/common/app_installer.cc
src/common/app_installer.h
src/common/pkgmgr_interface.cc
src/common/request.h
src/common/step/configuration/step_configure.cc
src/common/step/security/step_get_privilege_level.cc [new file with mode: 0644]
src/common/step/security/step_get_privilege_level.h [new file with mode: 0644]
src/pkg_initdb/pkg_initdb.cc

index aa8b87c35c21e87a51ac841cf16627cfa602bb98..9dd4139b3e1b7e40150541893252bfcdd980e393 100644 (file)
@@ -98,6 +98,9 @@ void AppInstaller::Init() {
     case RequestType::MigrateExtImg:
       MigrateExtImgSteps();
       break;
+    case RequestType::RecoverDB:
+      RecoverDBSteps();
+      break;
     default:
       UnknownSteps();
       break;
@@ -183,6 +186,7 @@ void AppInstaller::ReadonlyUpdateUninstallSteps() { UnknownSteps(); }
 void AppInstaller::DisablePkgSteps() { UnknownSteps(); }
 void AppInstaller::EnablePkgSteps() { UnknownSteps(); }
 void AppInstaller::MigrateExtImgSteps() { UnknownSteps(); }
+void AppInstaller::RecoverDBSteps() { UnknownSteps(); }
 void AppInstaller::UnknownSteps() {
   AddStep<configuration::StepFail>();
 }
index 4ee1b96f3592f00bcece8c3838cc7899bd40d4cb..242bcea3d59a83300334e134438add2075c6466c 100644 (file)
@@ -142,6 +142,7 @@ class AppInstaller {
   virtual void DisablePkgSteps();
   virtual void EnablePkgSteps();
   virtual void MigrateExtImgSteps();
+  virtual void RecoverDBSteps();
   virtual void UnknownSteps();
 
   // data used to send signal
index cbe4f3cc496724f14ffdeedd0a7504d12b337a22..a324d02180b722a4a14d0170ffd3808e8450d0dd 100644 (file)
@@ -208,6 +208,8 @@ RequestType PkgMgrInterface::GetRequestType() const {
       return RequestType::EnablePkg;
     case PKGMGR_REQ_MIGRATE_EXTIMG:
       return RequestType::MigrateExtImg;
+    case PKGMGR_REQ_RECOVER_DB:
+      return RequestType::RecoverDB;
     default:
       return RequestType::Unknown;
   }
index a42d8522053c36c7451dc909cb5b236d7d64839a..92e4f0ce4f355700ce443535224cb8cd1ce6fe50 100644 (file)
@@ -33,7 +33,8 @@ enum class RequestType : int {
   ReadonlyUpdateUninstall,
   DisablePkg,
   EnablePkg,
-  MigrateExtImg
+  MigrateExtImg,
+  RecoverDB
 };
 
 /** Request mode (USER vs GLOBAL) */
index cd0118c778f9ff391d5a150b5f265a61361e1f1d..e3916f9d8229a30ac62a4990665c65ef84b9e5c3 100644 (file)
@@ -129,6 +129,10 @@ Step::Status StepConfigure::process() {
       context_->pkgid.set(pkgmgr_->GetRequestInfo());
       break;
     }
+    case RequestType::RecoverDB: {
+      context_->pkgid.set(pkgmgr_->GetRequestInfo());
+      break;
+    }
     default:
       LOG(ERROR) <<
           "Only installation, update and uninstallation is now supported";
diff --git a/src/common/step/security/step_get_privilege_level.cc b/src/common/step/security/step_get_privilege_level.cc
new file mode 100644 (file)
index 0000000..c9cf06d
--- /dev/null
@@ -0,0 +1,35 @@
+// Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/security/step_get_privilege_level.h"
+
+#include "common/certificate_validation.h"
+
+namespace common_installer {
+namespace security {
+
+Step::Status StepGetPrivilegeLevel::process() {
+  PrivilegeLevel level = PrivilegeLevel::UNTRUSTED;
+
+  if (!GetSignatureFromFile(context_->pkgid.get(),
+      context_->is_readonly_package.get(), &level,
+      &context_->certificate_info.get()))
+    LOG(INFO) << "Failed to get privilege level from file";
+
+  if (context_->is_readonly_package.get())
+    level = PrivilegeLevel::PLATFORM;
+
+  if (level == PrivilegeLevel::UNTRUSTED) {
+    std::string error_message =
+        "Failed to get privilege level from file";
+    on_error(Status::CERT_ERROR, error_message);
+    return Status::CERT_ERROR;
+  }
+
+  context_->privilege_level.set(level);
+  return Status::OK;
+}
+
+}  // namespace security
+}  // namespace common_installer
diff --git a/src/common/step/security/step_get_privilege_level.h b/src/common/step/security/step_get_privilege_level.h
new file mode 100644 (file)
index 0000000..c4360c7
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_SECURITY_STEP_GET_PRIVILEGE_LEVEL_H_
+#define COMMON_STEP_SECURITY_STEP_GET_PRIVILEGE_LEVEL_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include <string>
+
+#include "common/installer_context.h"
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace security {
+
+/**
+ * \brief Step responsible for getting privilege level of given package.
+ *        Used by WGT and TPK backend
+ */
+class StepGetPrivilegeLevel : public Step {
+ public:
+  using Step::Step;
+
+  /**
+   * \brief main logic of getting privilege level
+   *
+   * \return Status::OK if retrieval has succeed, Status:ERROR otherwise
+   */
+  Status process() override;
+
+  Status undo() override { return Status::OK; }
+  Status clean() override { return Status::OK; }
+  Status precheck() override { return Status::OK; }
+
+  STEP_NAME(GetPrivilegeLevel)
+};
+
+}  // namespace security
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_SECURITY_STEP_GET_PRIVILEGE_LEVEL_H_
index fa3a8bcb1156d00d374a97b3f3ef5bc562ee1063..0f7367eb802ecd3afde25e85d797355137743bed 100644 (file)
@@ -33,10 +33,32 @@ const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
 const char kPkgInstallManifestPath[] = "/usr/bin/pkg-install-manifest";
 const char kBackendDirectoryPath[] = "/etc/package-manager/backend/";
 
+int RecoverDB(const std::string& pkgid,
+              const std::string& type,
+              uid_t uid, bool preload) {
+  bf::path backend_path(kBackendDirectoryPath);
+  backend_path /= type;
+  ci::Subprocess backend(backend_path.string());
+  if (preload) {
+    if (uid != kRootUserUid) {
+      std::cerr << "Preload request for non-root user" << std::endl;
+      return -1;
+    }
+    backend.Run("--recover-db", pkgid.c_str(), "--preload");
+  } else {
+    std::string str_uid = std::to_string(uid);
+    backend.Run("--recover-db", pkgid.c_str(), "-u", str_uid.c_str());
+  }
+  return backend.Wait();
+}
+
 int InstallManifestOffline(const std::string& pkgid,
                            const std::string& type,
                            uid_t uid, bool preload,
-                           bool rw_only) {
+                           bool rw_only, bool pkgdb_only) {
+  if (pkgdb_only)
+    return RecoverDB(pkgid, type, uid, preload);
+
   bf::path backend_path(kBackendDirectoryPath);
   backend_path /= type;
   ci::Subprocess backend(backend_path.string());
@@ -61,7 +83,7 @@ bool IsGlobal(uid_t uid) {
 }
 
 void InitdbLoadDirectory(uid_t uid, const bf::path& directory,
-                         bool preload, bool rw_only) {
+                         bool preload, bool rw_only, bool pkgdb_only) {
   std::cerr << "Loading manifest files from " << directory << std::endl;
   for (bf::directory_iterator iter(directory); iter != bf::directory_iterator();
        ++iter) {
@@ -88,7 +110,7 @@ void InitdbLoadDirectory(uid_t uid, const bf::path& directory,
       type = "tpk";
 
     InstallManifestOffline(package_info->package(), type, uid,
-                           preload, rw_only);
+                           preload, rw_only, pkgdb_only);
   }
 }
 
@@ -151,6 +173,7 @@ int main(int argc, char *argv[]) {
   bool ro_only = false;
   bool rw_only = false;
   bool keep_db = false;
+  bool recover_db = false;
   try {
     options.add_options()
         ("uid,u", bpo::value<int>()->default_value(kRootUserUid), "user id")
@@ -158,7 +181,8 @@ int main(int argc, char *argv[]) {
         ("ro", "readonly packages only")
         ("rw", "rw packages only")
         ("keep-db", "keep current database")
-        ("help,h", "display this help message");
+        ("help,h", "display this help message")
+        ("recover-db", "register pkg db only");
     bpo::store(bpo::parse_command_line(argc, argv, options), opt_map);
     if (opt_map.count("help")) {
       std::cerr << options << std::endl;
@@ -173,6 +197,8 @@ int main(int argc, char *argv[]) {
       rw_only = true;
     if (opt_map.count("keep-db"))
       keep_db = true;
+    if (opt_map.count("recover-db"))
+      recover_db = true;
     bpo::notify(opt_map);
     uid = opt_map["uid"].as<int>();
   } catch (...) {
@@ -192,6 +218,9 @@ int main(int argc, char *argv[]) {
     std::cerr << "Conflicting options : 'rw' or 'partial-rw'"
               << " only affect on global user";
     return -1;
+  } else if (recover_db && partial_rw) {
+    std::cerr << "Conflicting options : 'recover-db' and 'partial-rw'";
+    return -1;
   }
 
   if (!keep_db) {
@@ -208,7 +237,7 @@ int main(int argc, char *argv[]) {
     // RO location
     if (!rw_only) {
       bf::path ro_dir(tzplatform_getenv(TZ_SYS_RO_PACKAGES));
-      InitdbLoadDirectory(uid, ro_dir, true, partial_rw);
+      InitdbLoadDirectory(uid, ro_dir, true, partial_rw, recover_db);
     }
 
     if (ro_only)
@@ -216,12 +245,12 @@ int main(int argc, char *argv[]) {
 
     // RW location
     bf::path rw_dir(tzplatform_getenv(TZ_SYS_RW_PACKAGES));
-    InitdbLoadDirectory(uid, rw_dir, false, false);
+    InitdbLoadDirectory(uid, rw_dir, false, false, recover_db);
   } else {
     // Specified user location
     tzplatform_set_user(uid);
     bf::path dir(tzplatform_getenv(TZ_USER_PACKAGES));
-    InitdbLoadDirectory(uid, dir, false, false);
+    InitdbLoadDirectory(uid, dir, false, false, recover_db);
     tzplatform_reset_user();
   }