Remove boost dependency
[platform/core/appfw/app-installers.git] / src / common / step / security / step_register_trust_anchor.cc
1 // Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/step/security/step_register_trust_anchor.h"
6
7 #include <trust-anchor.h>
8
9 #include <filesystem>
10 #include <string>
11
12 #include "common/utils/file_util.h"
13
14 namespace common_installer {
15 namespace security {
16
17 namespace fs = std::filesystem;
18
19 namespace {
20
21 const char kTpkTrustAnchorPath[] = "res/.trust-anchor";
22 const char kWgtTrustAnchorPath[] = ".trust-anchor";
23 const char kWgt[] = "wgt";
24
25 bool RemoveWgtTrustAnchorSymLinks(const fs::path& path) {
26   for (fs::directory_iterator file(path);
27       file != fs::directory_iterator(); ++file) {
28     fs::path current(file->path());
29     if (fs::is_symlink(symlink_status(current)) &&
30       !fs::remove(current))
31         return false;
32   }
33   return true;
34 }
35
36 }  // namespace
37
38 StepRegisterTrustAnchor::StepRegisterTrustAnchor(
39     InstallerContext* context, RegisterType register_type)
40     : Step(context),
41       register_type_(register_type) {
42 }
43
44 Step::Status StepRegisterTrustAnchor::precheck() {
45   if (context_->GetPkgPath().empty()) {
46     LOG(ERROR) << "pkg path is empty";
47     return Step::Status::INVALID_VALUE;
48   }
49
50   if (!context_->manifest_data.get()) {
51     LOG(ERROR) << "manifest_data attribute is empty";
52     return Step::Status::INVALID_VALUE;
53   }
54
55   return Step::Status::OK;
56 }
57
58 Step::Status StepRegisterTrustAnchor::process() {
59   int ret;
60   fs::path pkg_certs_path = context_->GetPkgPath() / kTpkTrustAnchorPath;
61   manifest_x* manifest = context_->manifest_data.get();
62
63   if (register_type_ == RegisterType::UPDATE) {
64     ret = trust_anchor_uninstall(context_->pkgid.get().c_str(),
65         context_->uid.get());
66     if (ret != TRUST_ANCHOR_ERROR_NONE) {
67       LOG(ERROR) << "Failed to unregister trust anchor. error : " << ret;
68       return Step::Status::SECURITY_ERROR;
69     }
70
71     if (!context_->partial_rw.get() &&
72         !context_->pkg_type.get().compare(kWgt)) {
73       if (fs::exists(pkg_certs_path) &&
74           !RemoveWgtTrustAnchorSymLinks(pkg_certs_path))
75         return Step::Status::APP_DIR_ERROR;
76     }
77   }
78
79   if (!manifest->use_system_certs)
80     return Step::Status::OK;
81
82   if (!context_->pkg_type.get().compare(kWgt) &&
83       (context_->request_type.get() != RequestType::ManifestPartialInstall &&
84       context_->request_type.get() != RequestType::ManifestPartialUpdate &&
85       context_->request_type.get() != RequestType::PartialUninstall &&
86       context_->request_type.get() != RequestType::ReadonlyUpdateUninstall)) {
87     // For wgt package,
88     // create [pkg_root]/res/.trust-anchor directory and create symbolic link
89     if (!common_installer::CreateDir(pkg_certs_path))
90       return Step::Status::APP_DIR_ERROR;
91
92     fs::path pkg_certs_src_path =
93         context_->GetPkgPath() / "res/wgt" / kWgtTrustAnchorPath;
94     for (fs::directory_iterator file(pkg_certs_src_path);
95         file != fs::directory_iterator(); ++file) {
96       fs::path current(file->path());
97       try {
98         fs::create_symlink(current, pkg_certs_path / current.filename());
99       } catch (const fs::filesystem_error& error) {
100         LOG(ERROR) << "Failed to make trust anchor symlink : " << error.what();
101         return Step::Status::APP_DIR_ERROR;
102       }
103     }
104   }
105
106   ret = trust_anchor_install(context_->pkgid.get().c_str(),
107       context_->uid.get(), pkg_certs_path.c_str(),
108       (strcasecmp(manifest->use_system_certs, "true") == 0) ? true : false);
109
110   if (ret != TRUST_ANCHOR_ERROR_NONE) {
111     LOG(ERROR) << "Failed to register trust anchor. error : " << ret;
112     return Step::Status::SECURITY_ERROR;
113   }
114
115   return Step::Status::OK;
116 }
117
118 Step::Status StepRegisterTrustAnchor::undo() {
119   manifest_x* manifest = context_->manifest_data.get();
120   if (!manifest)
121     return Step::Status::SECURITY_ERROR;
122
123   if (!manifest->use_system_certs)
124     return Step::Status::OK;
125
126   int ret = trust_anchor_uninstall(context_->pkgid.get().c_str(),
127       context_->uid.get());
128   if (ret != TRUST_ANCHOR_ERROR_NONE) {
129     LOG(ERROR) << "Failed to unregister trust anchor. error : " << ret;
130     return Step::Status::SECURITY_ERROR;
131   }
132
133   // Re-registration of trust anchor with previous value
134   // should be performed after rollback files.
135
136   return Step::Status::OK;
137 }
138
139 }  // namespace security
140 }  // namespace common_installer