[SM] Tests for trusted dir. 62/58262/3
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 28 Jan 2016 18:57:12 +0000 (19:57 +0100)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 29 Jan 2016 15:14:24 +0000 (16:14 +0100)
Change-Id: I4c97747253b8395a41bd85c004104f66bffc852a

src/security-manager-tests/common/app_install_helper.h [new file with mode: 0644]
src/security-manager-tests/common/sm_db.cpp
src/security-manager-tests/common/sm_db.h
src/security-manager-tests/common/sm_request.cpp
src/security-manager-tests/security_manager_tests.cpp

diff --git a/src/security-manager-tests/common/app_install_helper.h b/src/security-manager-tests/common/app_install_helper.h
new file mode 100644 (file)
index 0000000..c79d263
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014-2016 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.
+ */
+#pragma once
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/smack.h>
+
+#include <string>
+
+
+struct AppInstallHelper {
+    AppInstallHelper(const std::string &name)
+      : m_name(name)
+    {}
+
+    std::string getInstallDir() {
+        return "/usr/apps/" + getPkgId();
+    }
+
+    std::string getTrustedDir(int i = 0) {
+        return getInstallDir() + "/trustedDir" + std::to_string(i);
+    }
+
+    std::string getAppId() {
+        return m_name + "_app_id";
+    }
+
+    std::string getPkgId() {
+        return m_name + "_pkg_id";
+    }
+
+    void createInstallDir() {
+        mkdir(getInstallDir().c_str(), 0777);
+    }
+
+    void createTrustedDir(int i = 0) {
+        mkdir(getTrustedDir(i).c_str(), 0777);
+    }
+
+    void revokeRules() {
+        RUNNER_ASSERT_MSG(
+            0 == smack_revoke_subject(generateAppLabel().c_str()),
+            "Revoking smack subject failed");
+        RUNNER_ASSERT_MSG(
+            0 == smack_revoke_subject(generatePkgLabel().c_str()),
+            "Revoking smack subject failed");
+    }
+
+    std::string generateAppLabel() {
+        return "User::App::" + getAppId();
+    }
+
+    std::string generatePkgLabel() {
+        return "User::Pkg::" + getPkgId();
+    }
+
+    virtual ~AppInstallHelper() {
+        // TODO we should also remove trusted dirs created with custom params
+        rmdir(getTrustedDir().c_str());
+        rmdir(getInstallDir().c_str());
+    }
+
+protected:
+    std::string m_name;
+};
+
index 10aa48c..7eb6f3f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2016 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.
@@ -241,3 +241,25 @@ void TestSecurityManagerDatabase::setup_default_version_privilege(const std::str
         m_base.execute(sql.str(), result);
 
 }
+
+int64_t TestSecurityManagerDatabase::get_author_id(const std::string &authorName)
+{
+    Sqlite3DBaseSelectResult result;
+    std::ostringstream sql;
+
+    if (!m_base.is_open())
+        m_base.open();
+
+    sql.clear();
+    sql.str("SELECT author_id FROM author where name=\"" + authorName + "\"");
+    m_base.execute(sql.str(), result);
+
+    if(result.rows.empty())
+        return 0;
+
+    std::istringstream os(result.rows[0][0]);
+    int64_t id;
+    os >> id;
+    return id;
+}
+
index 0cffde2..da71fbe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2016 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.
@@ -165,6 +165,11 @@ public:
     void setup_default_version_privilege(const std::string &version_from,
                                          const std::string &version_to,
                                          const std::string &privilege);
+
+/**
+ * @brief Method for getting author id from database.
+ */
+    int64_t get_author_id(const std::string &authorName);
 private:
 /**
  * @var base
index 65087af..69d1a4d 100644 (file)
@@ -57,7 +57,7 @@ void InstallRequest::setAppId(const char *appId, lib_retcode expectedResult)
                           << " App id: " << appId << ";"
                           << " Result: " << result << ";"
                           << " Expected result: " << expectedResult);
-    m_appId = appId;
+    m_appId = strdup(appId);
 }
 
 void InstallRequest::setPkgId(const char *pkgId, lib_retcode expectedResult)
@@ -68,7 +68,7 @@ void InstallRequest::setPkgId(const char *pkgId, lib_retcode expectedResult)
                           << " Pkg id: " << pkgId << ";"
                           << " Result: " << result << ";"
                           << " Expected result: " << expectedResult);
-    m_pkgId = pkgId;
+    m_pkgId = strdup(pkgId);
 }
 
 void InstallRequest::addPrivilege(const char *privilege, lib_retcode expectedResult)
@@ -79,7 +79,7 @@ void InstallRequest::addPrivilege(const char *privilege, lib_retcode expectedRes
                           << " Privilege: " << privilege << ";"
                           << " Result: " << result << ";"
                           << " Expected result: " << expectedResult);
-    m_privileges.push_back(privilege);
+    m_privileges.push_back(strdup(privilege));
 }
 
 void InstallRequest::addPath(const char *path, app_install_path_type pathType, lib_retcode expectedResult)
index efc6a85..417561c 100644 (file)
@@ -12,6 +12,7 @@
 #include <sys/types.h>
 #include <sys/un.h>
 #include <sys/wait.h>
+#include <sys/smack.h>
 
 #include <algorithm>
 #include <fstream>
@@ -32,6 +33,7 @@
 #include <sm_db.h>
 #include <sm_request.h>
 #include <sm_user_request.h>
+#include <app_install_helper.h>
 #include <temp_test_user.h>
 #include <cynara_test_client.h>
 #include <cynara_test_admin.h>
@@ -88,6 +90,7 @@ std::string genOwnerRWOthersROPath(int app_num) {
 static const char *const SM_RW_PATH = "/usr/apps/sm_test_02_pkg_id_full/app_dir";
 
 static const char *const SM_DENIED_PATH = "/usr/apps/non_app_dir";
+static const char *const SM_TRUSTED_PATH = "/usr/apps/sm_test_02_pkg_id_full/app_dir_trusted";
 
 static const char *const ANY_USER_REPRESENTATION = "anyuser";/*this may be actually any string*/
 static const std::string EXEC_FILE("exec");
@@ -471,6 +474,31 @@ static inline struct passwd *getUserStruct(const uid_t uid) {
     return pw;
 };
 
+void check_exact_access(const std::string& subject, const std::string& object, const std::string& access)
+{
+    // check access
+    if (!access.empty()) {
+        int result = smack_have_access(subject.c_str(), object.c_str(), access.c_str());
+        RUNNER_ASSERT_MSG(result >= 0, "smack_have_access failed");
+        RUNNER_ASSERT_MSG(result == 1,
+          "No smack access: " << subject << " " << object << " " << access);
+    }
+    // check excessive access
+    auto foundInAccess = [&access](std::string::value_type c) {
+        return access.find(c) != std::string::npos; };
+
+    std::string negative = "rwxatl";
+    auto end = std::remove_if(negative.begin(), negative.end(), foundInAccess);
+    negative.erase(end, negative.end());
+
+    for(const auto& c : negative) {
+        int result = smack_have_access(subject.c_str(), object.c_str(), std::string(1, c).c_str());
+        RUNNER_ASSERT_MSG(result >= 0, "smack_have_access failed");
+        RUNNER_ASSERT_MSG(result == 0,
+                          "Unexpected smack access: " << subject << " " << object << " " << c);
+    }
+}
+
 RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER)
 
 
@@ -2731,14 +2759,14 @@ RUNNER_TEST(security_manager_27p_API30_app_uninstall)
     };
 }
 
-RUNNER_TEST(security_manager_27a_set_wrong_author_id)
+RUNNER_TEST(security_manager_40_set_wrong_author_id)
 {
     InstallRequest requestInst;
     requestInst.setAuthorId(NULL, SECURITY_MANAGER_ERROR_INPUT_PARAM);
     requestInst.setAuthorId("", SECURITY_MANAGER_ERROR_INPUT_PARAM);
 }
 
-RUNNER_TEST(security_manager_27b_set_author_id_multiple_times)
+RUNNER_TEST(security_manager_41_set_author_id_multiple_times)
 {
     for(unsigned int i=0; i<10; ++i) {
         std::string authorId = "some-author-id" + std::to_string(i);
@@ -2748,6 +2776,117 @@ RUNNER_TEST(security_manager_27b_set_author_id_multiple_times)
     }
 }
 
+RUNNER_TEST(security_manager_43_app_install_with_trusted_path)
+{
+    std::vector<AppInstallHelper> helper {{"app43a"}, {"app43b"}, {"app43c"}};
+    auto &provider  = helper[0];
+    auto &user      = helper[1];
+    auto &untrusted = helper[2];
+
+    TestSecurityManagerDatabase dbtest;
+    const char *author_id = "custom_author_id_test 41";
+
+    const char *const trusted_access = "rwxatl";
+    const char *const system_access = "rwxatl";
+
+    int result;
+
+    // cleanup
+    for (auto &e : helper) {
+        e.revokeRules();
+        e.createInstallDir();
+        e.createTrustedDir();
+    }
+
+    result = nftw(provider.getInstallDir().c_str(), &nftw_remove_labels, FTW_MAX_FDS, FTW_PHYS);
+    RUNNER_ASSERT_MSG(result == 0, "Unable to set Smack labels in " << SM_TRUSTED_PATH);
+
+    // install app with shared/trusted dir
+    InstallRequest trustingApp;
+    trustingApp.setAppId(provider.getAppId().c_str());
+    trustingApp.setPkgId(provider.getPkgId().c_str());
+    trustingApp.setAuthorId("author id to be overwritten");
+    trustingApp.setAuthorId(author_id);
+    trustingApp.addPath(provider.getTrustedDir().c_str(), SECURITY_MANAGER_PATH_TRUSTED_RW);
+    Api::install(trustingApp);
+
+    int64_t authorDb = dbtest.get_author_id(author_id);
+    const std::string trusted_label = std::string("User::Author::") + std::to_string(authorDb);
+
+    // check trusted path label
+    nftw_expected_label = trusted_label;
+    nftw_expected_transmute = true;
+    nftw_expected_exec = false;
+
+    // check labels
+    result = nftw(provider.getTrustedDir().c_str(), &nftw_check_sm_labels, FTW_MAX_FDS, FTW_PHYS);
+    RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << SM_TRUSTED_PATH);
+
+    // check rules
+    check_exact_access("System", trusted_label.c_str(), system_access);
+    check_exact_access("User", trusted_label.c_str(), system_access);
+    check_exact_access(generateAppLabel(provider.getAppId().c_str()), trusted_label, trusted_access);
+    check_exact_access(generatePkgLabel(provider.getPkgId().c_str()), trusted_label, "");
+
+    // install trusted app
+    InstallRequest trustedApp;
+    trustedApp.setAppId(user.getAppId().c_str());
+    trustedApp.setPkgId(user.getPkgId().c_str());
+    trustedApp.setAuthorId(author_id);
+    Api::install(trustedApp);
+
+    // check rules
+    check_exact_access(generateAppLabel(user.getAppId().c_str()), trusted_label, trusted_access);
+    check_exact_access(generatePkgLabel(user.getPkgId().c_str()), trusted_label, "");
+
+    // install untrusted app
+    InstallRequest untrustedApp;
+    untrustedApp.setAppId(untrusted.getAppId().c_str());
+    untrustedApp.setPkgId(untrusted.getPkgId().c_str());
+    Api::install(untrustedApp);
+
+    // check rules
+    check_exact_access(generateAppLabel(untrusted.getAppId().c_str()), trusted_label, "");
+    check_exact_access(generatePkgLabel(untrusted.getPkgId().c_str()), trusted_label, "");
+
+    // uninstall trusting app
+    Api::uninstall(trustingApp);
+
+    // there's still one app with author id, rules should be kept
+    check_exact_access("System", trusted_label, system_access);
+    check_exact_access("User", trusted_label, system_access);
+    check_exact_access(generateAppLabel(provider.getAppId().c_str()), trusted_label, "");
+    check_exact_access(generatePkgLabel(provider.getPkgId().c_str()), trusted_label, "");
+    check_exact_access(generateAppLabel(user.getAppId().c_str()), trusted_label, trusted_access);
+    check_exact_access(generatePkgLabel(user.getPkgId().c_str()), trusted_label, "");
+
+    Api::uninstall(trustedApp);
+
+    // no more apps with author id
+    check_exact_access("System", trusted_label, "");
+    check_exact_access("User", trusted_label, "");
+    check_exact_access(generateAppLabel(user.getAppId().c_str()), trusted_label, "");
+    check_exact_access(generatePkgLabel(user.getPkgId().c_str()), trusted_label, "");
+
+    Api::uninstall(untrustedApp);
+}
+
+
+RUNNER_TEST(security_manager_44_app_install_with_trusted_path_no_author_id)
+{
+    AppInstallHelper help("app44");
+    help.createInstallDir();
+    help.createTrustedDir();
+
+    // install app with shared/trusted dir but without authors id
+    InstallRequest app;
+    app.setAppId(help.getAppId().c_str());
+    app.setPkgId(help.getPkgId().c_str());
+    app.addPath(help.getTrustedDir().c_str(),
+        SECURITY_MANAGER_PATH_TRUSTED_RW);
+    Api::install(app, SECURITY_MANAGER_ERROR_INPUT_PARAM);
+}
+
 int main(int argc, char *argv[])
 {
     return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);