Add tests covering installation & updating many apps in single request.
Add a function checking if an app has proper Smack policy.
Add a function parsing smack rules template files.
Add a function creating a new app in InstallRequest class.
Modify ScopedInstaller class for many apps in single request
compatibility.
Change-Id: I35bb9757f54b111629d45b1769ca4e53ccccd017
/*
- * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-2019 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.
class ScopedInstaller {
public:
ScopedInstaller(const AppInstallHelper &app, bool requestUid = true)
- : m_appId(app.getAppId()),
+ : m_appIds({app.getAppId()}),
m_uid(app.getUID()),
m_installType(app.getInstallType()),
m_shouldUninstall(true),
SecurityManagerTest::Api::install(instReq);
}
+ ScopedInstaller(const std::vector<std::string> &appIds, const std::string &pkgId)
+ : m_appIds(appIds),
+ m_uid(0),
+ m_installType(SM_APP_INSTALL_NONE),
+ m_shouldUninstall(true),
+ m_requestUid(false),
+ m_creatorPid(getpid())
+ {
+ SecurityManagerTest::InstallRequest instReq;
+
+ instReq.setPkgId(pkgId);
+ for (unsigned int i = 0; i < appIds.size(); i++) {
+ if (i > 0)
+ instReq.nextApp();
+
+ instReq.setAppId(appIds[i]);
+ }
+
+ SecurityManagerTest::Api::install(instReq);
+ }
+
ScopedInstaller(const ScopedInstaller &) = delete;
ScopedInstaller(ScopedInstaller &&other)
- : m_appId(std::move(other.m_appId)),
+ : m_appIds(std::move(other.m_appIds)),
m_uid(other.m_uid),
m_installType(other.m_installType),
m_shouldUninstall(other.m_shouldUninstall),
if (!m_shouldUninstall)
return;
SecurityManagerTest::InstallRequest uninstReq;
- uninstReq.setAppId(m_appId);
+ for (unsigned int i = 0; i < m_appIds.size(); i++) {
+ if (i > 0)
+ uninstReq.nextApp();
+
+ uninstReq.setAppId(m_appIds[i]);
+ }
if (m_requestUid)
uninstReq.setUid(m_uid);
if (m_installType != SM_APP_INSTALL_NONE)
}
protected:
- std::string m_appId;
+ std::vector<std::string> m_appIds;
uid_t m_uid;
app_install_type m_installType;
bool m_shouldUninstall;
/*
- * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2019 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.
<< " App id: " << appId << ";"
<< " Result: " << result << ";"
<< " Expected result: " << expectedResult);
- m_appId = std::move(appId);
}
void InstallRequest::setPkgId(std::string pkgId, lib_retcode expectedResult)
<< " Expected result: " << expectedResult);
}
+void InstallRequest::nextApp(lib_retcode expectedResult)
+{
+ int result = security_manager_app_inst_req_next(m_req);
+ RUNNER_ASSERT_MSG((lib_retcode)result == expectedResult,
+ "security_manager_app_inst_req_next() returned wrong value."
+ << " Result: " << result << ";"
+ << " Expected result: " << expectedResult);
+}
+
std::ostream& operator<<(std::ostream &os, const InstallRequest &request)
{
- if (!request.m_appId.empty())
- os << "app id: " << request.m_appId << "; ";
if (!request.m_pkgId.empty())
os << "pkg id: " << request.m_pkgId << "; ";
if (!request.m_privileges.empty()) {
/*
- * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2019 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.
InstallRequest& operator=(const InstallRequest&) = delete;
InstallRequest(InstallRequest &&other)
: m_req(std::move(other.m_req)),
- m_appId(std::move(other.m_appId)),
m_pkgId(std::move(other.m_pkgId)),
m_authorId(std::move(other.m_authorId)),
m_privileges(std::move(other.m_privileges)),
void setAuthorId(std::string authorId, lib_retcode expectedResult= SECURITY_MANAGER_SUCCESS);
void setInstallType(const enum app_install_type &type, lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
void setHybrid(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
+ void nextApp(lib_retcode expectedResult = SECURITY_MANAGER_SUCCESS);
std::string getPkgId() const { return m_pkgId; }
std::string getAppTizenVersion() const { return m_tizenVer; }
app_inst_req *get() { return m_req; }
app_inst_req *m_req;
std::string m_tizenVer;
- std::string m_appId;
std::string m_pkgId;
std::string m_authorId;
PrivilegeVector m_privileges;
${PROJECT_SOURCE_DIR}/src/security-manager-tests/security_manager_tests.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/policy_configuration.cpp
${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_commons.cpp
+ ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/template_parser.cpp
${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_client.cpp
${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_admin.cpp
${PROJECT_SOURCE_DIR}/src/cynara-tests/plugins/plugins.cpp
#include <unordered_map>
#include <cstdlib>
+#include <array>
#include <unordered_set>
+#include <utility>
#include <vector>
#include <security-manager-types.h>
#include <policy_configuration.h>
#include "tzplatform.h"
#include <label_generator.h>
+#include <template_parser.h>
using namespace SecurityManagerTest;
+#define CONF_DIR "/usr/share/security-manager/policy/"
+
// Common DB/nftw checks
// nftw doesn't allow passing user data to functions. Work around by using global variable
}
}
-static void check_app(const std::string &appId, const std::string &pkgId, bool shouldBeInstalled)
+static void check_app_smack_accesses(const std::string &appId, const std::string &pkgId,
+ bool isHybrid = false)
+{
+ static const std::vector<AccessRequest> rules[] =
+ {parseSmackRulesFile(CONF_DIR "pkg-rules-template.smack"),
+ parseSmackRulesFile(CONF_DIR "app-rules-template.smack")};
+
+ const std::pair<std::string, std::string> switchAliases[] =
+ {std::make_pair("~PATH_RW~", generatePathRWLabel(pkgId)),
+ std::make_pair("~PATH_RO~", generatePathROLabel(pkgId)),
+ std::make_pair("~PATH_SHARED_RO~", generatePathSharedROLabel(pkgId)),
+ std::make_pair("~PROCESS~", generateProcessLabel(appId, pkgId, isHybrid))};
+
+ for (auto rule : rules[isHybrid]) {
+ if (rule.object == "~PATH_TRUSTED~") {
+ continue;
+ }
+
+ for (const auto &alias : switchAliases) {
+ if (rule.subject == alias.first) {
+ rule.subject = alias.second;
+ }
+ if (rule.object == alias.first) {
+ rule.object = alias.second;
+ }
+ }
+
+ if (rule.object == "_") {
+ rule.access = "rx" + rule.access;
+ }
+
+ check_exact_smack_accesses(rule.subject, rule.object, rule.access);
+ }
+}
+
+static void check_app(const std::string &appId, const std::string &pkgId,
+ bool shouldBeInstalled, bool isHybrid)
{
char *retPkgId;
int ret = security_manager_get_app_pkgid(&retPkgId, appId.c_str());
RUNNER_ASSERT_MSG(strcmp(pkgId.c_str(), retPkgId) == 0,
"The given appId does not belong to the given pkgId.");
}
+ check_app_smack_accesses(appId, pkgId, isHybrid);
} else {
RUNNER_ASSERT_MSG(ret == SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT, "The given appId is installed.");
}
}
-void check_app_after_install(const std::string &app_id, const std::string &pkg_id)
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id, bool isHybrid)
{
- check_app(app_id, pkg_id, true);
+ check_app(app_id, pkg_id, true, isHybrid);
}
static void check_app_gids(const std::string &app_id, const std::vector<gid_t> &allowed_gids)
const privileges_t &denied_privs,
bool isHybrid)
{
- check_app(app_id, pkg_id, true);
-
+ check_app(app_id, pkg_id, true, isHybrid);
/* Privileges should be granted to all users if root installs app */
check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, allowed_privs, denied_privs, isHybrid);
RUNNER_ASSERT_MSG(result == 0, "Unable to check Smack labels for " << path);
}
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id)
+void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
+ bool isHybrid)
{
- check_app(app_id, pkg_id, false);
+ check_app(app_id, pkg_id, false, isHybrid);
}
void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
const privileges_t &privileges, bool isHybrid)
{
- check_app(app_id, pkg_id, false);
+ check_app(app_id, pkg_id, false, isHybrid);
/* Privileges should not be granted anymore to any user */
check_app_permissions(app_id, pkg_id, ANY_USER_REPRESENTATION, {}, privileges, isHybrid);
/*
- * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-2019 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.
void sm_app_has_privileges(const AppInstallHelper &app,
const std::vector<std::string> &privileges,
int result);
-void check_app_after_install(const std::string &app_id, const std::string &pkg_id);
+void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
+ bool isHybrid = false);
void check_app_after_install(const std::string &app_id, const std::string &pkg_id,
const privileges_t &allowed_privs,
const privileges_t &denied_privs,
bool isHybrid = false);
void check_path(const std::string &path, const std::string &label,
bool transmute = true, bool execute = false);
-void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id);
+void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
+ bool isHybrid = false);
void check_app_after_uninstall(const std::string &app_id, const std::string &pkg_id,
const privileges_t &privileges, bool isHybrid = false);
--- /dev/null
+/*
+ * Copyright (c) 2019 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 template_parser.cpp
+ * @author Alicja Kluczek <a.kluczek@samsung.com>
+ * @brief Parsing function for smack rules templates
+ */
+#include "template_parser.h"
+#include <fstream>
+
+std::vector<AccessRequest> parseSmackRulesFile(const std::string &path)
+{
+ std::vector<AccessRequest> rules;
+ std::ifstream rulesFile(path);
+ std::string object, subject, access;
+ while (rulesFile >> subject >> object >> access) {
+ rules.emplace_back(std::move(subject), std::move(object), std::move(access));
+ }
+ return rules;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2019 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 template_parser.h
+ * @author Alicja Kluczek <a.kluczek@samsung.com>
+ * @brief Parsing function for smack rules templates
+ */
+#include <vector>
+#include <string>
+
+struct AccessRequest {
+ AccessRequest(std::string sub, std::string obj, std::string acc)
+ : subject(std::move(sub)),
+ object(std::move(obj)),
+ access(std::move(acc))
+ {}
+ std::string subject;
+ std::string object;
+ std::string access;
+};
+
+std::vector<AccessRequest> parseSmackRulesFile(const std::string &path);
+
install(users[0], pkgId[0], appId[0], version[0], author[1], hybrid[0], SECURITY_MANAGER_ERROR_INPUT_PARAM);
}
+RUNNER_TEST(security_manager_09a_install_many_apps_in_single_request)
+{
+ const std::string pkgId = "sm_test_09a_pkg_id_0";
+ const std::vector<std::string> appIds = {"sm_test_09a_app_id_0", "sm_test_09a_app_id_1", "sm_test_09a_app_id_2"};
+
+ {
+ ScopedInstaller appsInstall(appIds, pkgId);
+ // Installing many applications in single request
+ for (const auto &appId : appIds) {
+ check_app_after_install(appId, pkgId);
+ }
+ }
+
+ for (const auto &appId : appIds) {
+ check_app_after_uninstall(appId, pkgId);
+ }
+}
+
+RUNNER_TEST(security_manager_09b_install_many_apps_in_single_request_duplicated_ids)
+{
+ const std::string pkgId = "sm_test_09b_pkg_id_0";
+ const std::string appId = "sm_test_09b_app_id_0";
+
+ {
+ ScopedInstaller appsInstall({appId, appId}, pkgId);
+ check_app_after_install(appId, pkgId);
+ }
+
+ check_app_after_uninstall(appId, pkgId);
+}
+
+RUNNER_TEST(security_manager_09c_update_many_apps_in_single_request_hybrid_package)
+{
+ const std::vector<std::string> appIds = {"sm_test_09c_app_id_0", "sm_test_09c_app_id_1", "sm_test_09c_app_id_2"};
+ const std::string pkgId = "sm_test_09c_pkg_id_0";
+
+ {
+ ScopedInstaller appsInstall(appIds, pkgId);
+ // Package is not hybrid, every app has same policy.
+ for (const auto &appId : appIds) {
+ check_app_after_install(appId, pkgId);
+ }
+
+ // Updating package -- changing set of apps in package and setting hybrid mode
+ InstallRequest updateRequest;
+ updateRequest.setPkgId(pkgId);
+ updateRequest.setAppId(appIds[0]);
+ updateRequest.nextApp();
+ updateRequest.setAppId(appIds[1]);
+ updateRequest.setHybrid();
+
+ Api::update(updateRequest);
+ // Package became hybrid, so every app has its own Smack label
+ check_app_after_install(appIds[0], pkgId, true);
+ check_app_after_install(appIds[1], pkgId, true);
+ // Package became hybrid properly,
+ // so app not included in updated version of package was uninstalled.
+ check_app_after_uninstall(appIds[2], pkgId, false);
+ }
+
+ for (const auto &appId : appIds) {
+ check_app_after_uninstall(appId, pkgId, true);
+ }
+}
+
RUNNER_CHILD_TEST(security_manager_10_app_has_privilege)
{
const std::vector<std::string> allowedPrivs = {