Name: trust-anchor
-Version: 0.0.1
+Version: 0.0.2
Release: 0
License: Apache-2.0
Source0: file://%{name}-%{version}.tar.gz
${TANCHOR_SRC}/exception.cpp
${TANCHOR_SRC}/api.cpp
${TANCHOR_SRC}/certificate.cpp
+ ${TANCHOR_SRC}/file-system.cpp
+ ${TANCHOR_SRC}/logic.cpp
${TANCHOR_SRC}/trust-anchor.cpp)
INCLUDE_DIRECTORIES(SYSTEM ${TANCHOR_INCLUDE}
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file environment.hxx
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version 0.1
+ * @brief Environment variables
+ */
+#pragma once
+
+namespace tanchor {
+namespace path {
+
+const std::string BASE_USR_PATH(TANCHOR_USR_DIR);
+const std::string BASE_GLOBAL_PATH(TANCHOR_GLOBAL_DIR);
+const std::string SYS_CERTS_PATH(TZ_SYS_CA_CERTS);
+const std::string SYS_BUNDLE_PATH(TZ_SYS_CA_BUNDLE);
+
+const std::string TANCHOR_SYSCA_PATH = TANCHOR_SYSCA;
+const std::string TANCHOR_BUNDLE_PATH = TANCHOR_BUNDLE;
+
+const std::string MOUNT_POINT_CERTS(TZ_SYS_CA_CERTS);
+const std::string MOUNT_POINT_BUNDLE(TZ_SYS_CA_BUNDLE);
+
+} // namespace path
+} // namespace tanchor
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file file-system.cpp
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+#include "file-system.hxx"
+
+#include <climits>
+#include <cerrno>
+#include <unistd.h>
+
+#include <vector>
+
+#include "exception.hxx"
+
+namespace tanchor {
+
+void File::linkTo(const std::string &src, const std::string &dst)
+{
+ if (::symlink(src.c_str(), dst.c_str()))
+ ThrowErrno(errno, "Failed to link " + src + " -> " + dst);
+}
+
+std::string File::readLink(const std::string &path)
+{
+ std::vector<char> buf(PATH_MAX);
+ ssize_t count = ::readlink(path.c_str(), buf.data(), buf.size());
+ return std::string(buf.data(), (count > 0) ? count : 0);
+}
+
+std::string File::getName(const std::string &path)
+{
+ size_t pos = path.rfind('/');
+ if (pos == std::string::npos)
+ throw std::invalid_argument("Path is wrong. > " + path);
+ return path.substr(pos + 1);
+}
+
+} // namespace tanchor
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file file-system.hxx
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+#pragma once
+
+#include <string>
+
+namespace tanchor {
+
+class File {
+public:
+ static void linkTo(const std::string &src, const std::string &dst);
+ static std::string readLink(const std::string &path);
+ static std::string getName(const std::string &path);
+};
+
+} // namespace tanchor
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file logic.cpp
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+#include "logic.hxx"
+
+#include <ctime>
+#include <cerrno>
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+
+#include <klay/filesystem.h>
+#include <klay/audit/logger.h>
+
+#include "certificate.hxx"
+#include "file-system.hxx"
+#include "exception.hxx"
+#include "environment.hxx"
+
+namespace tanchor {
+
+Logic::Logic(const std::string &appCertsPath, const std::string &basePath) :
+ m_appCertsPath(appCertsPath),
+ m_customBasePath(basePath),
+ m_customCertsPath(m_customBasePath + "/certs"),
+ m_customBundlePath(m_customBasePath + "/bundle"),
+ m_customCertNameSet(),
+ m_customCertsData() {}
+
+void Logic::init(void) const
+{
+ runtime::File customBaseDir(this->m_customBasePath);
+ if (customBaseDir.exists()) {
+ WARN("App custom directory is already exist. remove it!");
+ customBaseDir.remove(true);
+ }
+ customBaseDir.makeDirectory(true);
+
+ runtime::File customCertsDir(this->m_customCertsPath);
+ customCertsDir.makeDirectory();
+
+ runtime::File customBundleDir(this->m_customBundlePath);
+ customBundleDir.makeDirectory();
+ DEBUG("Success to init[" << this->m_customBasePath << "]");
+}
+
+void Logic::deinit(bool isRollback) const
+{
+ runtime::File customBaseDir(this->m_customBasePath);
+ if (customBaseDir.exists())
+ customBaseDir.remove(true);
+ else if (!isRollback)
+ throw std::invalid_argument("tanchor is never installed before.");
+
+ DEBUG("Success to deinit[" << this->m_customBasePath << "]");
+}
+
+void Logic::makeCustomCerts(void)
+{
+ if (this->isSystemCertsUsed()) {
+ // link system certificates to the custom directory
+ runtime::DirectoryIterator iter(path::SYS_CERTS_PATH), end;
+ while (iter != end) {
+ auto name = iter->getName();
+ File::linkTo(File::readLink(iter->getPath()),
+ this->m_customCertsPath + "/" + name);
+ this->m_customCertNameSet.emplace(File::getName(iter->getPath()));
+ ++iter;
+ }
+ DEBUG("Success to migrate system certificates.");
+ }
+
+ // link app certificates to the custom directory as subjectNameHash
+ runtime::DirectoryIterator iter(this->m_appCertsPath), end;
+ while (iter != end) {
+ Certificate cert(iter->getPath());
+ std::string uName = this->getUniqueCertName(cert.getSubjectNameHash());
+ File::linkTo(iter->getPath(), this->m_customCertsPath + "/" + uName);
+ this->m_customCertNameSet.emplace(std::move(uName));
+
+ this->m_customCertsData.emplace_back(cert.getCertificateData());
+ ++iter;
+ }
+}
+
+void Logic::makeCustomBundle(void)
+{
+ runtime::File customBundle(this->m_customBundlePath + "/" +
+ File::getName(path::SYS_BUNDLE_PATH));
+ if (customBundle.exists()) {
+ WARN("App custom bundle is already exist. remove it!");
+ customBundle.remove();
+ }
+
+ DEBUG("Start to migrate previous bundle.");
+ if (this->isSystemCertsUsed()) {
+ runtime::File sysBundle(path::SYS_BUNDLE_PATH);
+ sysBundle.copyTo(this->m_customBundlePath);
+ } else {
+ runtime::File tanchorBundle(path::TANCHOR_BUNDLE_PATH);
+ tanchorBundle.copyTo(this->m_customBundlePath);
+ }
+ DEBUG("Finish migrating previous bundle.");
+
+ if (this->m_customCertsData.empty()) {
+ DEBUG("System certificates is changed after TrustAnchor installation.");
+ runtime::DirectoryIterator iter(this->m_appCertsPath), end;
+ while (iter != end) {
+ Certificate cert(iter->getPath());
+ this->m_customCertsData.emplace_back(cert.getCertificateData());
+ ++iter;
+ }
+ }
+
+ DEBUG("Start to add app's certificate to bundle.");
+ customBundle.open(O_RDWR | O_APPEND);
+ for (const auto &cert : this->m_customCertsData) {
+ customBundle.write(cert.c_str(), cert.length());
+ std::string newLine = "\n";
+ customBundle.write(newLine.c_str(), newLine.length());
+ }
+
+ INFO("Success to make app custom bundle.");
+}
+
+bool Logic::isAppCertsValid(void) const
+{
+ runtime::File file(this->m_appCertsPath);
+
+ if (!file.exists())
+ ThrowExc(TRUST_ANCHOR_ERROR_NO_SUCH_FILE,
+ "File [" << file.getPath() << "] does not exist.");
+
+ if (!file.canRead())
+ ThrowExc(TRUST_ANCHOR_ERROR_PERMISSION_DENIED,
+ "No permission to read [" << file.getPath() << "]");
+
+ return file.isDirectory();
+}
+
+void Logic::setSystemCertsUsed(void) const
+{
+ runtime::File tanchorSysCA(path::TANCHOR_SYSCA_PATH);
+ tanchorSysCA.copyTo(this->m_customBasePath);
+ DEBUG("Success to set SYSCA flag.");
+}
+
+bool Logic::isSystemCertsUsed(void) const
+{
+ runtime::File customSysCA(this->m_customBasePath + "/" +
+ File::getName(path::TANCHOR_SYSCA_PATH));
+
+ DEBUG("Wheter system certificates use or not : " << customSysCA.exists());
+ return customSysCA.exists();
+}
+
+bool Logic::isSystemCertsModified(void) const
+{
+ struct stat systemAttr, customAttr;
+ auto customBundle = this->m_customBundlePath + "/" +
+ File::getName(path::SYS_BUNDLE_PATH);
+
+ if (::stat(path::SYS_BUNDLE_PATH.c_str(), &systemAttr))
+ ThrowErrno(errno, path::SYS_BUNDLE_PATH);
+
+ if (::stat(customBundle.c_str(), &customAttr))
+ ThrowErrno(errno, customBundle);
+
+ DEBUG("System bundle mtime : " << ::ctime(&systemAttr.st_mtime) << ", " <<
+ "Custom bundle mtime : " << ::ctime(&customAttr.st_mtime));
+
+ return systemAttr.st_mtime > customAttr.st_mtime;
+}
+
+void Logic::disassociateNS(void) const
+{
+ if (::unshare(CLONE_NEWNS))
+ ThrowErrno(errno, "Failed to unshare.");
+
+ // convert it to a slave for preventing propagation
+ if (::mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL))
+ ThrowErrno(errno, "Failed to mount.");
+
+ DEBUG("Success to disassociate namespace.");
+}
+
+void Logic::mountCustomCerts(void) const
+{
+ if (::mount(this->m_customCertsPath.c_str(),
+ path::MOUNT_POINT_CERTS.c_str(),
+ NULL,
+ MS_BIND,
+ NULL))
+ ThrowErrno(errno, "Failed to mount. src[" +
+ this->m_customCertsPath + "] to dst[" +
+ path::MOUNT_POINT_CERTS + "]");
+}
+
+void Logic::mountCustomBundle(void) const
+{
+ auto bundle = this->m_customBundlePath + "/" +
+ File::getName(path::SYS_BUNDLE_PATH);
+ if (::mount(bundle.c_str(),
+ path::MOUNT_POINT_BUNDLE.c_str(),
+ NULL,
+ MS_BIND,
+ NULL))
+ ThrowErrno(errno, "Failed to mount. src[" + bundle +
+ "] to dst[" + path::MOUNT_POINT_BUNDLE + "]");
+}
+
+std::string Logic::getUniqueCertName(const std::string &name) const
+{
+ int sameNameCnt = 0;
+ std::string uName;
+ do {
+ uName = name + "." + std::to_string(sameNameCnt++);
+ } while (this->m_customCertNameSet.find(uName) !=
+ this->m_customCertNameSet.end());
+
+ return uName;
+}
+
+} // namespace tanchor
--- /dev/null
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file logic.hxx
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @version 0.1
+ * @brief
+ */
+#pragma once
+
+#include <string>
+#include <set>
+#include <vector>
+
+namespace tanchor {
+
+class Logic {
+public:
+ explicit Logic(const std::string &appCertsPath, const std::string &basePath);
+ virtual ~Logic(void) = default;
+
+ Logic(const Logic &) = delete;
+ Logic(Logic &&) = delete;
+ Logic &operator=(const Logic &) = delete;
+ Logic &operator=(Logic &&) = delete;
+
+ void init(void) const;
+ void deinit(bool isRollback) const;
+
+ void makeCustomCerts(void);
+ void makeCustomBundle(void);
+
+ bool isAppCertsValid(void) const;
+
+ bool isSystemCertsUsed(void) const;
+ bool isSystemCertsModified(void) const;
+ void setSystemCertsUsed(void) const;
+
+ void disassociateNS(void) const;
+ void mountCustomCerts(void) const;
+ void mountCustomBundle(void) const;
+
+private:
+ std::string getUniqueCertName(const std::string &name) const;
+
+ std::string m_appCertsPath;
+ std::string m_customBasePath;
+ std::string m_customCertsPath;
+ std::string m_customBundlePath;
+
+ std::set<std::string> m_customCertNameSet;
+ std::vector<std::string> m_customCertsData;
+};
+
+} // namespace tanchor
*/
#include "tanchor/trust-anchor.hxx"
-#include <climits>
-#include <cerrno>
-#include <ctime>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-
-#include <set>
-#include <vector>
-
-#include <klay/filesystem.h>
#include <klay/audit/logger.h>
-#include "certificate.hxx"
+#include "logic.hxx"
#include "exception.hxx"
+#include "environment.hxx"
namespace tanchor {
-namespace {
-
-const std::string BASE_USR_PATH(TANCHOR_USR_DIR);
-const std::string BASE_GLOBAL_PATH(TANCHOR_GLOBAL_DIR);
-const std::string TANCHOR_BUNDLE_PATH(TANCHOR_BUNDLE);
-const std::string TANCHOR_SYSCA_PATH(TANCHOR_SYSCA);
-const std::string SYS_CERTS_PATH(TZ_SYS_CA_CERTS);
-const std::string SYS_BUNDLE_PATH(TZ_SYS_CA_BUNDLE);
-const std::string MOUNT_POINT_CERTS(TZ_SYS_CA_CERTS);
-const std::string MOUNT_POINT_BUNDLE(TZ_SYS_CA_BUNDLE);
-const std::string NEW_LINE("\n");
-
-} // namespace anonymous
-
class TrustAnchor::Impl {
public:
explicit Impl(const std::string &packageId,
virtual ~Impl(void) = default;
int install(bool withSystemCerts) noexcept;
- int uninstall(bool isRollback = false) noexcept;
- int launch(void);
+ int uninstall(void) const noexcept;
+ int launch(void) noexcept;
+ int rollback(void) const noexcept;
private:
- void preInstall(void) const;
+ void preInstall(void);
void preLaunch(void);
- void linkTo(const std::string &src, const std::string &dst) const;
- void makeCustomCerts(bool withSystemCerts);
- void makeCustomBundle(bool withSystemCerts);
- std::string readLink(const std::string &path) const;
- std::string getUniqueHashName(const std::string &hashName) const;
- std::string getFileName(const std::string &path) const;
- bool isSystemCertsModified(void) const;
- void checkFileValidity(const runtime::File &file) const;
-
- std::string m_packageId;
- std::string m_appCertsPath;
- uid_t m_uid;
-
- std::string m_customBasePath;
- std::string m_customCertsPath;
- std::string m_customBundlePath;
-
- std::set<std::string> m_customCertNameSet;
- std::vector<std::string> m_customCertsData;
+
+ Logic m_logic;
};
TrustAnchor::Impl::Impl(const std::string &packageId,
const std::string &certsDir,
uid_t uid) noexcept :
- m_packageId(packageId),
- m_appCertsPath(certsDir),
- m_uid(uid),
- m_customBasePath(BASE_USR_PATH + "/" +
- std::to_string(static_cast<int>(uid)) + "/" +
- packageId),
- m_customCertsPath(m_customBasePath + "/certs"),
- m_customBundlePath(m_customBasePath + "/bundle"),
- m_customCertNameSet(),
- m_customCertsData() {}
-
-TrustAnchor::Impl::Impl(const std::string &packageId,
- const std::string &certsDir) noexcept :
- m_packageId(packageId),
- m_appCertsPath(certsDir),
- m_uid(-1),
- m_customBasePath(BASE_GLOBAL_PATH + "/" + packageId),
- m_customCertsPath(m_customBasePath + "/certs"),
- m_customBundlePath(m_customBasePath + "/bundle"),
- m_customCertNameSet(),
- m_customCertsData() {}
-
-std::string TrustAnchor::Impl::readLink(const std::string &path) const
+ m_logic(certsDir,
+ path::BASE_USR_PATH + "/" +
+ std::to_string(static_cast<int>(uid)) + "/" +
+ packageId)
{
- std::vector<char> buf(PATH_MAX);
- ssize_t count = ::readlink(path.c_str(), buf.data(), buf.size());
- return std::string(buf.data(), (count > 0) ? count : 0);
+ INFO("Start tanchor about usr[" << uid << "], app[" << packageId << "]");
}
-void TrustAnchor::Impl::linkTo(const std::string &src,
- const std::string &dst) const
+TrustAnchor::Impl::Impl(const std::string &packageId,
+ const std::string &certsDir) noexcept :
+ m_logic(certsDir, path::BASE_GLOBAL_PATH + "/" + packageId)
{
- errno = 0;
- int ret = ::symlink(src.c_str(), dst.c_str());
- if (ret != 0)
- ThrowErrno(errno, "Failed to link " + src + " -> " + dst);
+ INFO("Start tanchor about global app[" << packageId << "]");
}
-void TrustAnchor::Impl::preInstall(void) const
+void TrustAnchor::Impl::preInstall(void)
{
- runtime::File customBaseDir(this->m_customBasePath);
- if (customBaseDir.exists()) {
- WARN("App custom directory is already exist. remove it!");
- customBaseDir.remove(true);
- }
- customBaseDir.makeDirectory(true);
-
- runtime::File customCertsDir(this->m_customCertsPath);
- customCertsDir.makeDirectory();
-
- runtime::File customBundleDir(this->m_customBundlePath);
- customBundleDir.makeDirectory();
-
- runtime::File appCertsDir(this->m_appCertsPath);
- this->checkFileValidity(appCertsDir);
- if (!appCertsDir.isDirectory())
- throw std::invalid_argument("[" + this->m_appCertsPath +
- "] should be directory.");
+ this->m_logic.init();
+ if (!this->m_logic.isAppCertsValid())
+ throw std::invalid_argument("App certs dir should be directory.");
DEBUG("Success to pre-install stage.");
}
this->preInstall();
- this->makeCustomCerts(withSystemCerts);
- this->makeCustomBundle(withSystemCerts);
+ if (withSystemCerts)
+ this->m_logic.setSystemCertsUsed();
- INFO("Success to install[" << this->m_packageId <<
- "] to " << this->m_customBasePath);
+ this->m_logic.makeCustomCerts();
+ this->m_logic.makeCustomBundle();
+
+ INFO("Success to install.");
return TRUST_ANCHOR_ERROR_NONE;
EXCEPTION_GUARD_END
}
-int TrustAnchor::Impl::uninstall(bool isRollback) noexcept
+int TrustAnchor::Impl::rollback(void) const noexcept
{
EXCEPTION_GUARD_START
- runtime::File customBaseDir(this->m_customBasePath);
- if (!customBaseDir.exists() && !isRollback)
- throw std::logic_error("There is no installed anchor previous.");
-
- if (customBaseDir.exists())
- customBaseDir.remove(true);
+ this->m_logic.deinit(true);
- INFO("Success to uninstall. : " << this->m_packageId);
+ INFO("Success to rollback.");
return TRUST_ANCHOR_ERROR_NONE;
EXCEPTION_GUARD_END
}
-void TrustAnchor::Impl::checkFileValidity(const runtime::File &file) const
+int TrustAnchor::Impl::uninstall(void) const noexcept
{
- if (!file.exists())
- ThrowExc(TRUST_ANCHOR_ERROR_NO_SUCH_FILE,
- "File [" << file.getPath() << "] does not exist.");
-
- if (!file.canRead())
- ThrowExc(TRUST_ANCHOR_ERROR_PERMISSION_DENIED,
- "No permission to read [" << file.getPath() << "]");
-}
-
-bool TrustAnchor::Impl::isSystemCertsModified(void) const
-{
- struct stat systemAttr, customAttr;
-
- errno = 0;
- if (::stat(SYS_BUNDLE_PATH.c_str(), &systemAttr))
- ThrowErrno(errno, SYS_BUNDLE_PATH);
+ EXCEPTION_GUARD_START
- auto customBundle = this->m_customBundlePath + "/" +
- this->getFileName(SYS_BUNDLE_PATH);
- if (::stat(customBundle.c_str(), &customAttr))
- ThrowErrno(errno, customBundle);
+ this->m_logic.deinit(false);
- DEBUG("System bundle mtime : " << ::ctime(&systemAttr.st_mtime) << ", " <<
- "Custom bundle mtime : " << ::ctime(&customAttr.st_mtime));
+ INFO("Success to uninstall.");
+ return TRUST_ANCHOR_ERROR_NONE;
- return systemAttr.st_mtime > customAttr.st_mtime;
+ EXCEPTION_GUARD_END
}
void TrustAnchor::Impl::preLaunch(void)
{
- // check whether system certificates use or not
- runtime::File customSysCA(this->m_customBasePath + "/" +
- this->getFileName(TANCHOR_SYSCA_PATH));
- if (!customSysCA.exists()) {
- INFO("This package only use custom certificates.");
+ if (!this->m_logic.isSystemCertsUsed())
return;
- }
- INFO("This package use system certificates.");
- if (this->isSystemCertsModified()) {
- WARN("System certificates be changed. Remake custom bundle.");
- this->makeCustomBundle(true);
+ DEBUG("This package use system certificates.");
+ if (this->m_logic.isSystemCertsModified()) {
+ WARN("System certificates be changed. Do re-install for refresh.");
+ this->install(true);
}
-
- DEBUG("Success to pre-install stage.");
+ DEBUG("Success to pre-launch stage.");
}
-int TrustAnchor::Impl::launch()
+int TrustAnchor::Impl::launch() noexcept
{
EXCEPTION_GUARD_START
this->preLaunch();
- errno = 0;
- // disassociate from the parent namespace
- if (::unshare(CLONE_NEWNS))
- ThrowErrno(errno, "Failed to unshare.");
-
- // convert it to a slave for preventing propagation
- if (::mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL))
- ThrowErrno(errno, "Failed to mount.");
-
- if (::mount(this->m_customCertsPath.c_str(),
- MOUNT_POINT_CERTS.c_str(),
- NULL,
- MS_BIND,
- NULL))
- ThrowErrno(errno, "Failed to mount. src[" +
- this->m_customCertsPath + "] to dst[" +
- MOUNT_POINT_CERTS + "]");
-
- auto bundle = this->m_customBundlePath + "/" +
- this->getFileName(SYS_BUNDLE_PATH);
- if (::mount(bundle.c_str(),
- MOUNT_POINT_BUNDLE.c_str(),
- NULL,
- MS_BIND,
- NULL))
- ThrowErrno(errno, "Failed to mount. src[" + bundle +
- "] to dst[" + MOUNT_POINT_BUNDLE + "]");
-
- INFO("Success to launch. : " << this->m_packageId);
+ this->m_logic.disassociateNS();
+ this->m_logic.mountCustomCerts();
+ this->m_logic.mountCustomBundle();
+
+ INFO("Success to launch.");
return TRUST_ANCHOR_ERROR_NONE;
EXCEPTION_GUARD_END
}
-std::string TrustAnchor::Impl::getFileName(const std::string &path) const
-{
- size_t pos = path.rfind('/');
- if (pos == std::string::npos)
- throw std::logic_error("Path is wrong. > " + path);
-
- return path.substr(pos + 1);
-}
-
-std::string TrustAnchor::Impl::getUniqueHashName(
- const std::string &hashName) const
-{
- int sameFileNameCnt = 0;
- std::string uniqueName;
- do {
- uniqueName = hashName + "." + std::to_string(sameFileNameCnt++);
- } while (this->m_customCertNameSet.find(uniqueName) !=
- this->m_customCertNameSet.end());
-
- return uniqueName;
-}
-
-void TrustAnchor::Impl::makeCustomCerts(bool withSystemCerts)
-{
- if (withSystemCerts) {
- // link system certificates to the custom directory
- runtime::DirectoryIterator iter(SYS_CERTS_PATH), end;
- while (iter != end) {
- linkTo(this->readLink(iter->getPath()),
- this->m_customCertsPath + "/" + iter->getName());
- this->m_customCertNameSet.emplace(iter->getName());
- ++iter;
- }
- DEBUG("Success to migrate system certificates.");
-
- // copy sysca(withSystemCerts flag) and check at launching time
- runtime::File tanchorSysCA(TANCHOR_SYSCA_PATH);
- this->checkFileValidity(tanchorSysCA);
- tanchorSysCA.copyTo(this->m_customBasePath);
- DEBUG("Success to set SYSCA flag.");
- }
-
- // link app certificates to the custom directory as subjectNameHash
- runtime::DirectoryIterator iter(this->m_appCertsPath), end;
- while (iter != end) {
- Certificate cert(iter->getPath());
- std::string hashName = this->getUniqueHashName(cert.getSubjectNameHash());
- linkTo(iter->getPath(),
- this->m_customCertsPath + "/" + hashName);
- this->m_customCertNameSet.emplace(std::move(hashName));
-
- this->m_customCertsData.emplace_back(cert.getCertificateData());
- ++iter;
- }
-}
-
-void TrustAnchor::Impl::makeCustomBundle(bool withSystemCerts)
-{
- runtime::File customBundle(this->m_customBundlePath + "/" +
- this->getFileName(SYS_BUNDLE_PATH));
- if (customBundle.exists()) {
- WARN("App custom bundle is already exist. remove it!");
- customBundle.remove();
- }
-
- DEBUG("Start to migrate previous bundle.");
- if (withSystemCerts) {
- runtime::File sysBundle(SYS_BUNDLE_PATH);
- this->checkFileValidity(sysBundle);
- sysBundle.copyTo(this->m_customBundlePath);
- } else {
- runtime::File tanchorBundle(TANCHOR_BUNDLE_PATH);
- this->checkFileValidity(tanchorBundle);
- tanchorBundle.copyTo(this->m_customBundlePath);
- }
- DEBUG("Finish migrating previous bundle.");
-
- if (this->m_customCertsData.empty()) {
- DEBUG("System certificates is changed after TrustAnchor installation.");
- runtime::DirectoryIterator iter(this->m_appCertsPath), end;
- while (iter != end) {
- Certificate cert(iter->getPath());
- this->m_customCertsData.emplace_back(cert.getCertificateData());
- ++iter;
- }
- }
-
- DEBUG("Start to add app's certificate to bundle.");
- customBundle.open(O_RDWR | O_APPEND);
- for (const auto &cert : this->m_customCertsData) {
- customBundle.write(cert.c_str(), cert.length());
- customBundle.write(NEW_LINE.c_str(), NEW_LINE.length());
- }
-
- INFO("Success to make app custom bundle.");
-}
-
TrustAnchor::TrustAnchor(const std::string &packageId,
const std::string &certsDir,
uid_t uid) noexcept :
if (ret != TRUST_ANCHOR_ERROR_NONE) {
ERROR("Failed to intall ACTA. Remove custom directory for rollback.");
- this->m_pImpl->uninstall(true);
+ if (this->m_pImpl->rollback() != TRUST_ANCHOR_ERROR_NONE)
+ ERROR("Failed to rollback ACTA.");
}
return ret;
LAUNCHER=@BIN_INSTALL_DIR@/@TEST_LAUNCHER@
CLAUNCHER=@BIN_INSTALL_DIR@/@TEST_CLAUNCHER@
INTERNAL=@BIN_INSTALL_DIR@/@TEST_INTERNAL@
+SSL=@BIN_INSTALL_DIR@/@TEST_SSL@
CURL=@BIN_INSTALL_DIR@/curl
-declare -a TESTS=("$INSTALLER $LAUNCHER $CLAUNCHER $INTERNAL")
+declare -a TESTS=("$INSTALLER $LAUNCHER $CLAUNCHER $INTERNAL $SSL")
for t in "${TESTS[@]}"
do
# launch() needs CAP_SYS_ADMIN
setcap cap_sys_admin+ep $LAUNCHER
setcap cap_sys_admin+ep $CLAUNCHER
+setcap cap_sys_admin+ep $SSL