From 11ddb3bab10b043797aca9eaa491070aa8510f3d Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Thu, 18 Sep 2014 10:07:15 +0200 Subject: [PATCH 01/16] New get_container_id_by_pid API function [Bug/Feature] Introduce new API function: sc_get_container_id_by_pid [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: I8bee78c062bcbbe29fc9e2c651989570c26869d1 --- client/security-containers-client-impl.cpp | 36 +++++++++ client/security-containers-client-impl.hpp | 5 ++ client/security-containers-client.cpp | 5 ++ client/security-containers-client.h | 11 +++ client/utils.cpp | 118 ++++++++++++++++++++++++++++ client/utils.hpp | 32 ++++++++ tests/unit_tests/client/ut-client-utils.cpp | 55 +++++++++++++ tests/unit_tests/client/ut-client.cpp | 37 +++++++++ 8 files changed, 299 insertions(+) create mode 100644 client/utils.cpp create mode 100644 client/utils.hpp create mode 100644 tests/unit_tests/client/ut-client-utils.cpp diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index 8486ae7..a2c51ba 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -25,6 +25,7 @@ #include #include "security-containers-client-impl.hpp" +#include "utils.hpp" #include #include #include @@ -33,6 +34,7 @@ #include #include +#include using namespace std; using namespace dbus; @@ -122,6 +124,17 @@ ScStatus toStatus(const std::exception& ex) return SCCLIENT_OTHER_ERROR; } +bool readFirstLineOfFile(const std::string& path, std::string& ret) +{ + std::ifstream file(path); + if (!file) { + return false; + } + + std::getline(file, ret); + return true; +} + } //namespace ScStatus Client::sc_start_glib_loop() noexcept @@ -309,6 +322,29 @@ ScStatus Client::sc_get_active_container_id(ScString* id) noexcept return ret; } +ScStatus Client::sc_get_container_id_by_pid(int pid, ScString* id) noexcept +{ + assert(id); + + const std::string path = "/proc/" + std::to_string(pid) + "/cpuset"; + + std::string cpuset; + if (!readFirstLineOfFile(path, cpuset)) { + mStatus = Status(SCCLIENT_INVALID_ARGUMENT, "Process not found"); + return sc_get_status(); + } + + std::string containerId; + if (!parseContainerIdFromCpuSet(cpuset, containerId)) { + mStatus = Status(SCCLIENT_OTHER_ERROR, "unknown format of cpuset"); + return sc_get_status(); + } + + *id = strdup(containerId.c_str()); + mStatus = Status(); + return sc_get_status();; +} + ScStatus Client::sc_set_active_container(const char* id) noexcept { assert(id); diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp index 10aecaf..f1bfacb 100644 --- a/client/security-containers-client-impl.hpp +++ b/client/security-containers-client-impl.hpp @@ -117,6 +117,11 @@ public: ScStatus sc_get_active_container_id(ScString* id) noexcept; /** + * @see ::sc_get_container_id_by_pid + */ + ScStatus sc_get_container_id_by_pid(int pid, ScString* id) noexcept; + + /** * @see ::sc_set_active_container */ ScStatus sc_set_active_container(const char* id) noexcept; diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp index b1eb521..cb22544 100644 --- a/client/security-containers-client.cpp +++ b/client/security-containers-client.cpp @@ -121,6 +121,11 @@ API ScStatus sc_get_active_container_id(ScClient client, ScString* id) return getClient(client).sc_get_active_container_id(id); } +API ScStatus sc_get_container_id_by_pid(ScClient client, int pid, ScString* id) +{ + return getClient(client).sc_get_container_id_by_pid(pid, id); +} + API ScStatus sc_set_active_container(ScClient client, const char* id) { return getClient(client).sc_set_active_container(id); diff --git a/client/security-containers-client.h b/client/security-containers-client.h index c56e9de..4d37c3c 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -247,6 +247,17 @@ ScStatus sc_get_container_ids(ScClient client, ScArrayString* array); ScStatus sc_get_active_container_id(ScClient client, ScString* id); /** + * Get container name of process with given pid. + * + * @param[in] client security-containers-server's client + * @param[in] pid process id + * @param[out] id active container name + * @return status of this function call + * @remark Use @p sc_string_free() to free memory occupied by @p id. + */ +ScStatus sc_get_container_id_by_pid(ScClient client, int pid, ScString* id); + +/** * Set active (foreground) container. * * @param[in] client security-containers-server's client diff --git a/client/utils.cpp b/client/utils.cpp new file mode 100644 index 0000000..98b6905 --- /dev/null +++ b/client/utils.cpp @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Piotr Bartosiewicz + * + * 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 + * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief Utility functions definition + */ + +#include "config.hpp" +#include "utils.hpp" + +#include + +namespace { + +const std::string CPUSET_HOST = "/"; +const std::string CPUSET_LIBVIRT_PREFIX_OLD = "/machine/"; +const std::string CPUSET_LIBVIRT_SUFFIX_OLD = ".libvirt-lxc"; +const std::string CPUSET_LIBVIRT_PREFIX = "/machine.slice/machine-lxc\\x2d"; +const std::string CPUSET_LIBVIRT_SUFFIX = ".scope"; + +bool parseOldFormat(const std::string& cpuset, std::string& id) +{ + // '/machine/.libvirt-lxc' + if (!boost::starts_with(cpuset, CPUSET_LIBVIRT_PREFIX_OLD)) { + return false; + } + + if (!boost::ends_with(cpuset, CPUSET_LIBVIRT_SUFFIX_OLD)) { + return false; + } + + id.assign(cpuset, + CPUSET_LIBVIRT_PREFIX_OLD.size(), + cpuset.size() - CPUSET_LIBVIRT_PREFIX_OLD.size() - CPUSET_LIBVIRT_SUFFIX_OLD.size()); + return true; +} + +inline int unhex(char c) +{ + if (c >= '0' && c <= '9') { + return c - '0'; + } + if (c >= 'a' && c <= 'f') { + return c - 'a' + 10; + } + if (c >= 'A' && c <= 'F') { + return c - 'A' + 10; + } + return -1; +} + +void unescape(std::string& value) +{ + const size_t len = value.size(); + size_t inPos = 0; + size_t outPos = 0; + while (inPos < len) { + const char c = value[inPos++]; + if (c == '-') { + value[outPos++] = '/'; + } else if (c == '\\' && value[inPos] == 'x') { + const char a = unhex(value[inPos+1]); + const char b = unhex(value[inPos+2]); + value[outPos++] = (char) ((a << 4) | b); + inPos += 3; + } else { + value[outPos++] = c; + } + } + value.resize(outPos); +} + +bool parseNewFormat(const std::string& cpuset, std::string& id) +{ + // '/machine.slice/machine-lxc\x2d.scope' + if (!boost::starts_with(cpuset, CPUSET_LIBVIRT_PREFIX)) { + return false; + } + + if (!boost::ends_with(cpuset, CPUSET_LIBVIRT_SUFFIX)) { + return false; + } + + id = cpuset.substr(CPUSET_LIBVIRT_PREFIX.size(), + cpuset.size() - CPUSET_LIBVIRT_PREFIX.size() - CPUSET_LIBVIRT_SUFFIX.size()); + unescape(id); + return true; +} + +} // namespace + +bool parseContainerIdFromCpuSet(const std::string& cpuset, std::string& id) +{ + if (cpuset == CPUSET_HOST) { + id = "host"; + return true; + } + + return parseNewFormat(cpuset, id) || parseOldFormat(cpuset, id); +} + diff --git a/client/utils.hpp b/client/utils.hpp new file mode 100644 index 0000000..49b83c0 --- /dev/null +++ b/client/utils.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Piotr Bartosiewicz + * + * 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 + * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief Utility functions declaration + */ + +#ifndef SECURITY_CONTAINERS_CLIENT_UTILS_HPP +#define SECURITY_CONTAINERS_CLIENT_UTILS_HPP + +#include + +bool parseContainerIdFromCpuSet(const std::string& cpuset, std::string& id); + +#endif // SECURITY_CONTAINERS_CLIENT_UTILS_HPP diff --git a/tests/unit_tests/client/ut-client-utils.cpp b/tests/unit_tests/client/ut-client-utils.cpp new file mode 100644 index 0000000..ac4c1fd --- /dev/null +++ b/tests/unit_tests/client/ut-client-utils.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Piotr Bartosiewicz + * + * 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 + * @author Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com) + * @brief Unit tests of the client utils + */ + +#include +#include "ut.hpp" +#include + + +BOOST_AUTO_TEST_SUITE(ClientUtils) + +BOOST_AUTO_TEST_CASE(ParseContainerIdFromCpuSetTest) +{ + auto testBad = [](const std::string& input) { + std::string ret; + BOOST_CHECK(!parseContainerIdFromCpuSet(input, ret)); + }; + + auto testOK = [](const std::string& input, const std::string& expected) { + std::string ret; + BOOST_CHECK(parseContainerIdFromCpuSet(input, ret)); + BOOST_CHECK_EQUAL(expected, ret); + }; + + testBad(""); + testBad("/foo"); + + testOK("/", "host"); + testOK("/machine/a-b.libvirt-lxc", "a-b"); + testOK("/machine.slice/machine-lxc\\x2da\\x2db.scope", "a-b"); + testOK("/machine.slice/machine-lxc\\x2da-b.scope", "a/b"); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index bbf2013..574be39 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -256,4 +256,41 @@ BOOST_AUTO_TEST_CASE(NotificationTest) } } +BOOST_AUTO_TEST_CASE(GetContainerIdByPidTest1) +{ + ScClient client = sc_client_create(); + ScString container; + ScStatus status = sc_get_container_id_by_pid(client, 1, &container); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + + BOOST_CHECK_EQUAL(container, std::string("host")); + + sc_string_free(container); + sc_client_free(client); +} + +BOOST_AUTO_TEST_CASE(GetContainerIdByPidTest2) +{ + std::set ids; + + ScClient client = sc_client_create(); + for (int n = 0; n < 100000; ++n) { + ScString container; + ScStatus status = sc_get_container_id_by_pid(client, n, &container); + if (status == SCCLIENT_SUCCESS) { + ids.insert(container); + sc_string_free(container); + } else { + BOOST_WARN_MESSAGE(status == SCCLIENT_INVALID_ARGUMENT, sc_get_status_message(client)); + } + } + sc_client_free(client); + + BOOST_CHECK(ids.count("host") == 1); + + for (const auto& dbus : EXPECTED_DBUSES_STARTED) { + BOOST_CHECK(ids.count(dbus.first) == 1); + } +} + BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From ca9fe3b7e0eb6a308dd1215fd427bd97369f04ac Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Wed, 24 Sep 2014 16:12:13 +0200 Subject: [PATCH 02/16] Adjusting tests to the changed KVStore [Bug/Feature] Added isEmpty() and exists() functions [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: Ied7f469599cfdb31104e4f0bc1b67b8cbc2a2cc0 --- tests/unit_tests/config/ut-configuration.cpp | 22 ++++++++++++++++--- tests/unit_tests/config/ut-kvstore.cpp | 32 +++++++++++----------------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/tests/unit_tests/config/ut-configuration.cpp b/tests/unit_tests/config/ut-configuration.cpp index 1e98d22..b205339 100644 --- a/tests/unit_tests/config/ut-configuration.cpp +++ b/tests/unit_tests/config/ut-configuration.cpp @@ -48,11 +48,13 @@ struct TestConfig { }; int intVal; + std::vector intVector; SubSubConfig subSubObj; CONFIG_REGISTER ( intVal, + intVector, subSubObj ) }; @@ -63,6 +65,7 @@ struct TestConfig { double doubleVal; bool boolVal; + std::vector emptyIntVector; std::vector intVector; std::vector stringVector; std::vector doubleVector; @@ -78,6 +81,7 @@ struct TestConfig { doubleVal, boolVal, + emptyIntVector, intVector, stringVector, doubleVector, @@ -98,12 +102,13 @@ const std::string jsonTestString = "\"stringVal\": \"blah\", " "\"doubleVal\": -1.234000, " "\"boolVal\": true, " + "\"emptyIntVector\": [ ], " "\"intVector\": [ 1, 2, 3 ], " "\"stringVector\": [ \"a\", \"b\" ], " "\"doubleVector\": [ 0.000000, 1.000000, 2.000000 ], " - "\"subObj\": { \"intVal\": 54321, \"subSubObj\": { \"intVal\": 234 } }, " - "\"subVector\": [ { \"intVal\": 123, \"subSubObj\": { \"intVal\": 345 } }, " - "{ \"intVal\": 456, \"subSubObj\": { \"intVal\": 567 } } ] }"; + "\"subObj\": { \"intVal\": 54321, \"intVector\": [ 1, 2 ], \"subSubObj\": { \"intVal\": 234 } }, " + "\"subVector\": [ { \"intVal\": 123, \"intVector\": [ 3, 4 ], \"subSubObj\": { \"intVal\": 345 } }, " + "{ \"intVal\": 456, \"intVector\": [ 5, 6 ], \"subSubObj\": { \"intVal\": 567 } } ] }"; // Floating point tolerance as a number of rounding errors const int TOLERANCE = 1; @@ -121,6 +126,8 @@ BOOST_AUTO_TEST_CASE(FromStringTest) BOOST_CHECK_CLOSE(-1.234, testConfig.doubleVal, TOLERANCE); BOOST_CHECK_EQUAL(true, testConfig.boolVal); + BOOST_REQUIRE_EQUAL(0, testConfig.emptyIntVector.size()); + BOOST_REQUIRE_EQUAL(3, testConfig.intVector.size()); BOOST_CHECK_EQUAL(1, testConfig.intVector[0]); BOOST_CHECK_EQUAL(2, testConfig.intVector[1]); @@ -136,12 +143,21 @@ BOOST_AUTO_TEST_CASE(FromStringTest) BOOST_CHECK_CLOSE(2.0, testConfig.doubleVector[2], TOLERANCE); BOOST_CHECK_EQUAL(54321, testConfig.subObj.intVal); + BOOST_CHECK_EQUAL(2, testConfig.subObj.intVector.size()); + BOOST_CHECK_EQUAL(1, testConfig.subObj.intVector[0]); + BOOST_CHECK_EQUAL(2, testConfig.subObj.intVector[1]); + BOOST_CHECK_EQUAL(234, testConfig.subObj.subSubObj.intVal); BOOST_REQUIRE_EQUAL(2, testConfig.subVector.size()); BOOST_CHECK_EQUAL(123, testConfig.subVector[0].intVal); BOOST_CHECK_EQUAL(456, testConfig.subVector[1].intVal); BOOST_CHECK_EQUAL(345, testConfig.subVector[0].subSubObj.intVal); BOOST_CHECK_EQUAL(567, testConfig.subVector[1].subSubObj.intVal); + BOOST_CHECK_EQUAL(3, testConfig.subVector[0].intVector[0]); + BOOST_CHECK_EQUAL(5, testConfig.subVector[1].intVector[0]); + BOOST_CHECK_EQUAL(4, testConfig.subVector[0].intVector[1]); + BOOST_CHECK_EQUAL(6, testConfig.subVector[1].intVector[1]); + } diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp index 66efc2b..2c9a998 100644 --- a/tests/unit_tests/config/ut-kvstore.cpp +++ b/tests/unit_tests/config/ut-kvstore.cpp @@ -114,33 +114,29 @@ BOOST_AUTO_TEST_CASE(EscapedCharactersTest) std::string HARD_KEY = "[" + KEY; BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A")); BOOST_CHECK_NO_THROW(c.set(KEY, "B")); - BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1); - BOOST_CHECK_EQUAL(c.count(KEY), 1); - BOOST_CHECK_EQUAL(c.size(), 2); + BOOST_CHECK(c.exists(HARD_KEY)); + BOOST_CHECK(c.exists(KEY)); BOOST_CHECK_NO_THROW(c.clear()); HARD_KEY = "]" + KEY; BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A")); BOOST_CHECK_NO_THROW(c.set(KEY, "B")); - BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1); - BOOST_CHECK_EQUAL(c.count(KEY), 1); - BOOST_CHECK_EQUAL(c.size(), 2); + BOOST_CHECK(c.exists(HARD_KEY)); + BOOST_CHECK(c.exists(KEY)); BOOST_CHECK_NO_THROW(c.clear()); HARD_KEY = "?" + KEY; BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A")); BOOST_CHECK_NO_THROW(c.set(KEY, "B")); - BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1); - BOOST_CHECK_EQUAL(c.count(KEY), 1); - BOOST_CHECK_EQUAL(c.size(), 2); + BOOST_CHECK(c.exists(HARD_KEY)); + BOOST_CHECK(c.exists(KEY)); BOOST_CHECK_NO_THROW(c.clear()); HARD_KEY = "*" + KEY; BOOST_CHECK_NO_THROW(c.set(HARD_KEY, "A")); BOOST_CHECK_NO_THROW(c.set(KEY, "B")); - BOOST_CHECK_EQUAL(c.count(HARD_KEY), 1); - BOOST_CHECK_EQUAL(c.count(KEY), 1); - BOOST_CHECK_EQUAL(c.size(), 2); + BOOST_CHECK(c.exists(HARD_KEY)); + BOOST_CHECK(c.exists(KEY)); } namespace { @@ -154,11 +150,11 @@ void testSingleValue(Fixture& f, const A& a, const B& b) // Update BOOST_CHECK_NO_THROW(f.c.set(KEY, b)); BOOST_CHECK_EQUAL(f.c.get(KEY), b); - BOOST_CHECK_EQUAL(f.c.count(KEY), 1); + BOOST_CHECK(f.c.exists(KEY)); // Remove BOOST_CHECK_NO_THROW(f.c.remove(KEY)); - BOOST_CHECK_EQUAL(f.c.count(KEY), 0); + BOOST_CHECK(!f.c.exists(KEY)); BOOST_CHECK_THROW(f.c.get(KEY), ConfigException); } } // namespace @@ -182,8 +178,6 @@ void setVector(Fixture& f, std::vector vec) BOOST_CHECK_NO_THROW(f.c.set(KEY, vec)); BOOST_CHECK_NO_THROW(storedVec = f.c.get >(KEY)) BOOST_CHECK_EQUAL_COLLECTIONS(storedVec.begin(), storedVec.end(), vec.begin(), vec.end()); - BOOST_CHECK_EQUAL(f.c.count(KEY), vec.size()); - BOOST_CHECK_EQUAL(f.c.size(), vec.size()); } template @@ -199,8 +193,8 @@ void testVectorOfValues(Fixture& f, // Remove BOOST_CHECK_NO_THROW(f.c.remove(KEY)); - BOOST_CHECK_EQUAL(f.c.count(KEY), 0); - BOOST_CHECK_EQUAL(f.c.size(), 0); + BOOST_CHECK(!f.c.exists(KEY)); + BOOST_CHECK(f.c.isEmpty()); BOOST_CHECK_THROW(f.c.get >(KEY), ConfigException); BOOST_CHECK_THROW(f.c.get(KEY), ConfigException); } @@ -221,7 +215,7 @@ BOOST_AUTO_TEST_CASE(ClearTest) std::vector vec = {"A", "B"}; BOOST_CHECK_NO_THROW(c.set(KEY, vec)); BOOST_CHECK_NO_THROW(c.clear()); - BOOST_CHECK_EQUAL(c.size(), 0); + BOOST_CHECK(c.isEmpty()); BOOST_CHECK_NO_THROW(c.remove(KEY)); BOOST_CHECK_THROW(c.get>(KEY), ConfigException); -- 2.7.4 From 2d2f8fe00f8c450895a2ef67a698746294d25a0b Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Thu, 25 Sep 2014 11:59:58 +0200 Subject: [PATCH 03/16] Implement switchingSequenceMonitorNotify and add VT switching support [Feature] switchingSequenceMonitorNotify function implementation and module to handle VT switching [Cause] Nothing happened when user provided input sequence to Input Monitor [Solution] Implemented switchingSequenceMonitorNotify and added VT switching to function ContainersManager::focus. [Verification] Build, install, run unit tests. Tests (especially FocusTest) should pass. Change-Id: Ie4aa7d1679bfaa5a0fdfaf238ebc14a3b8150006 --- CMakeLists.txt | 4 + common/utils/img.cpp | 2 +- common/utils/img.hpp | 2 +- common/utils/vt.cpp | 86 ++++++++++++++++++++++ common/utils/vt.hpp | 36 +++++++++ packaging/security-containers.spec | 7 +- server/CMakeLists.txt | 2 +- server/configs/containers/business.conf | 3 +- server/configs/containers/private.conf | 3 +- server/container-config.hpp | 6 ++ server/container.cpp | 12 +++ server/container.hpp | 7 ++ server/containers-manager.cpp | 28 ++++++- server/containers-manager.hpp | 6 ++ server/server.cpp | 11 ++- .../ut-client/containers/console1-dbus.conf | 1 + .../ut-client/containers/console2-dbus.conf | 1 + .../ut-client/containers/console3-dbus.conf | 1 + .../ut-container-admin/containers/buggy.conf.in | 1 + .../ut-container-admin/containers/missing.conf | 1 + .../containers/test-no-shutdown.conf.in | 1 + .../ut-container-admin/containers/test.conf.in | 1 + .../configs/ut-container/containers/buggy.conf | 1 + .../configs/ut-container/containers/test-dbus.conf | 1 + .../configs/ut-container/containers/test.conf | 1 + .../containers/console1-dbus.conf | 1 + .../ut-containers-manager/containers/console1.conf | 1 + .../containers/console2-dbus.conf | 1 + .../ut-containers-manager/containers/console2.conf | 1 + .../containers/console3-dbus.conf | 1 + .../ut-containers-manager/containers/console3.conf | 1 + .../ut-containers-manager/templates/template.conf | 1 + .../ut-network-admin/containers/buggy.conf.in | 1 + .../ut-network-admin/containers/missing.conf | 1 + .../ut-network-admin/containers/test.conf.in | 1 + .../configs/ut-server/containers/container1.conf | 1 + .../configs/ut-server/containers/container2.conf | 1 + .../configs/ut-server/containers/container3.conf | 1 + 38 files changed, 228 insertions(+), 10 deletions(-) create mode 100644 common/utils/vt.cpp create mode 100644 common/utils/vt.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cb880a..c8e74c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,11 +72,15 @@ ENDIF(NOT DEFINED INPUT_EVENT_GROUP) IF(NOT DEFINED DISK_GROUP) SET(DISK_GROUP "disk") ENDIF(NOT DEFINED DISK_GROUP) +IF(NOT DEFINED TTY_GROUP) + SET(TTY_GROUP "tty") +ENDIF(NOT DEFINED TTY_GROUP) ADD_DEFINITIONS(-DSECURITY_CONTAINERS_USER="${SECURITY_CONTAINERS_USER}") ADD_DEFINITIONS(-DLIBVIRT_GROUP="${LIBVIRT_GROUP}") ADD_DEFINITIONS(-DINPUT_EVENT_GROUP="${INPUT_EVENT_GROUP}") ADD_DEFINITIONS(-DDISK_GROUP="${DISK_GROUP}") +ADD_DEFINITIONS(-DTTY_GROUP="${TTY_GROUP}") ## Python packages directory ################################################### diff --git a/common/utils/img.cpp b/common/utils/img.cpp index 4d7de88..bc77491 100644 --- a/common/utils/img.cpp +++ b/common/utils/img.cpp @@ -17,7 +17,7 @@ */ /** - * @file img.hpp + * @file * @author Lukasz Kostyra (l.kostyra@samsung.com) * @brief Image utility functions declaration */ diff --git a/common/utils/img.hpp b/common/utils/img.hpp index d42300e..db47cc6 100644 --- a/common/utils/img.hpp +++ b/common/utils/img.hpp @@ -17,7 +17,7 @@ */ /** - * @file img.hpp + * @file * @author Lukasz Kostyra (l.kostyra@samsung.com) * @brief Image utility functions declaration */ diff --git a/common/utils/vt.cpp b/common/utils/vt.cpp new file mode 100644 index 0000000..22a697e --- /dev/null +++ b/common/utils/vt.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Kostyra + * + * 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 + * @author Lukasz Kostyra (l.kostyra@samsung.com) + * @brief VT-related utility functions + */ + +#include "config.hpp" +#include "utils/vt.hpp" +#include "logger/logger.hpp" + +#include +#include +#include +#include +#include +#include + +namespace { + +const std::string TTY_DEV = "/dev/tty0"; + +} // namespace + +namespace security_containers { +namespace utils { + +bool activateVT(const int& vt) +{ + int consoleFD = ::open(TTY_DEV.c_str(), O_WRONLY); + if (consoleFD < 0) { + LOGE("console open failed: " << errno << " (" << strerror(errno) << ")"); + return false; + } + + struct vt_stat vtstat; + vtstat.v_active = 0; + if (::ioctl(consoleFD, VT_GETSTATE, &vtstat)) { + LOGE("Failed to get vt state: " << errno << " (" << strerror(errno) << ")"); + ::close(consoleFD); + return false; + } + + if (vtstat.v_active == vt) { + LOGW("vt" << vt << " is already active."); + ::close(consoleFD); + return true; + } + + // activate vt + if (::ioctl(consoleFD, VT_ACTIVATE, vt)) { + LOGE("Failed to activate vt" << vt << ": " << errno << " (" << strerror(errno) << ")"); + ::close(consoleFD); + return false; + } + + // wait until activation is finished + if (::ioctl(consoleFD, VT_WAITACTIVE, vt)) { + LOGE("Failed to wait for vt" << vt << " activation: " << errno << " (" << strerror(errno) << ")"); + ::close(consoleFD); + return false; + } + + ::close(consoleFD); + return true; +} + +} // namespace utils +} // namespace security_containers diff --git a/common/utils/vt.hpp b/common/utils/vt.hpp new file mode 100644 index 0000000..d285806 --- /dev/null +++ b/common/utils/vt.hpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Kostyra + * + * 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 + * @author Lukasz Kostyra (l.kostyra@samsung.com) + * @brief VT-related utility functions + */ + +#ifndef COMMON_UTILS_VT_HPP +#define COMMON_UTILS_VT_HPP + +namespace security_containers { +namespace utils { + +bool activateVT(const int& vt); + +} // namespace utils +} // namespace security_containers + +#endif // COMMON_UTILS_VT_HPP diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index 97bf4d5..fc1c806 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -7,6 +7,8 @@ %define input_event_group video # The group has access to /dev/loop* devices. %define disk_group disk +# The group that has write access to /dev/tty* devices. +%define tty_group tty Name: security-containers Version: 0.1.1 @@ -71,7 +73,8 @@ between them. A process from inside a container can request a switch of context -DSECURITY_CONTAINERS_USER=%{scs_user} \ -DLIBVIRT_GROUP=%{libvirt_group} \ -DINPUT_EVENT_GROUP=%{input_event_group} \ - -DDISK_GROUP=%{disk_group} + -DDISK_GROUP=%{disk_group} \ + -DTTY_GROUP=%{tty_group} make -k %{?jobs:-j%jobs} %install @@ -88,7 +91,7 @@ if [ $1 == 1 ]; then systemctl daemon-reload || : fi # set needed caps on the binary to allow restart without loosing them -setcap CAP_SYS_ADMIN,CAP_MAC_OVERRIDE+ei %{_bindir}/security-containers-server +setcap CAP_SYS_ADMIN,CAP_MAC_OVERRIDE,CAP_SYS_TTY_CONFIG+ei %{_bindir}/security-containers-server %preun # Stop the service before uninstall diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt index 3293307..2237f52 100644 --- a/server/CMakeLists.txt +++ b/server/CMakeLists.txt @@ -45,4 +45,4 @@ ADD_SUBDIRECTORY(configs) INSTALL(TARGETS ${SERVER_CODENAME} DESTINATION bin) ## Set capabilities on server executable ####################################### -INSTALL(CODE "EXECUTE_PROCESS(COMMAND setcap CAP_SYS_ADMIN,CAP_MAC_OVERRIDE+ei \$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/bin/${SERVER_CODENAME})") +INSTALL(CODE "EXECUTE_PROCESS(COMMAND setcap CAP_SYS_ADMIN,CAP_MAC_OVERRIDE,CAP_SYS_TTY_CONFIG+ei \$ENV{DESTDIR}/${CMAKE_INSTALL_PREFIX}/bin/${SERVER_CODENAME})") diff --git a/server/configs/containers/business.conf b/server/configs/containers/business.conf index 1b3502a..600edb1 100644 --- a/server/configs/containers/business.conf +++ b/server/configs/containers/business.conf @@ -1,8 +1,9 @@ { "cpuQuotaForeground" : -1, - "cpuQuotaBackground" : 1000, + "cpuQuotaBackground" : 10000, "enableDbusIntegration" : true, "privilege" : 1, + "vt" : 3, "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/business.xml", "networkConfig" : "../libvirt-config/business-network.xml", diff --git a/server/configs/containers/private.conf b/server/configs/containers/private.conf index 62c0f18..71d4bcb 100644 --- a/server/configs/containers/private.conf +++ b/server/configs/containers/private.conf @@ -1,8 +1,9 @@ { "cpuQuotaForeground" : -1, - "cpuQuotaBackground" : 1000, + "cpuQuotaBackground" : 10000, "enableDbusIntegration" : true, "privilege" : 10, + "vt" : 2, "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/private.xml", "networkConfig" : "../libvirt-config/private-network.xml", diff --git a/server/container-config.hpp b/server/container-config.hpp index b506770..e0c6760 100644 --- a/server/container-config.hpp +++ b/server/container-config.hpp @@ -43,6 +43,11 @@ struct ContainerConfig { int privilege; /** + * Number of virtual terminal used by xserver inside container + */ + int vt; + + /** * Allow switching to default container after timeout. * Setting this to false will disable switching to default container after timeout. */ @@ -101,6 +106,7 @@ struct ContainerConfig { CONFIG_REGISTER ( privilege, + vt, switchToDefaultAfterTimeout, enableDbusIntegration, config, diff --git a/server/container.cpp b/server/container.cpp index 494b0ae..59328db 100644 --- a/server/container.cpp +++ b/server/container.cpp @@ -29,6 +29,7 @@ #include "logger/logger.hpp" #include "utils/paths.hpp" +#include "utils/vt.hpp" #include "config/manager.hpp" #include @@ -210,6 +211,17 @@ std::string Container::getDbusAddress() return mDbusAddress; } +bool Container::activateVT() +{ + Lock lock(mReconnectMutex); + + if (mConfig.vt >= 0) { + return utils::activateVT(mConfig.vt); + } + + return true; +} + void Container::goForeground() { Lock lock(mReconnectMutex); diff --git a/server/container.hpp b/server/container.hpp index f741464..6800f7a 100644 --- a/server/container.hpp +++ b/server/container.hpp @@ -101,6 +101,13 @@ public: void stop(); /** + * Activate this container's VT + * + * @return Was activation successful? + */ + bool activateVT(); + + /** * Setup this container to be put in the foreground. * I.e. set appropriate scheduler level. */ diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index 5dc909b..d8858ab 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -183,6 +183,11 @@ void ContainersManager::focus(const std::string& containerId) /* try to access the object first to throw immediately if it doesn't exist */ ContainerMap::mapped_type& foregroundContainer = mContainers.at(containerId); + if (!foregroundContainer->activateVT()) { + LOGE("Failed to activate containers VT. Aborting focus."); + return; + } + for (auto& container : mContainers) { LOGD(container.second->getId() << ": being sent to background"); container.second->goBackground(); @@ -240,10 +245,31 @@ std::string ContainersManager::getRunningForegroundContainerId() return std::string(); } +std::string ContainersManager::getNextToForegroundContainerId() +{ + // handles case where there is no next container + if (mContainers.size() < 2) { + return std::string(); + } + + for (auto it = mContainers.begin(); it != mContainers.end(); ++it) { + if (it->first == mConfig.foregroundId && + it->second->isRunning()) { + auto nextIt = std::next(it); + if (nextIt != mContainers.end()) { + return nextIt->first; + } + } + } + return mContainers.begin()->first; +} + void ContainersManager::switchingSequenceMonitorNotify() { LOGI("switchingSequenceMonitorNotify() called"); - // TODO: implement + + auto nextContainerId = getNextToForegroundContainerId(); + focus(nextContainerId); } diff --git a/server/containers-manager.hpp b/server/containers-manager.hpp index cd1194d..3cbf833 100644 --- a/server/containers-manager.hpp +++ b/server/containers-manager.hpp @@ -78,6 +78,12 @@ public: std::string getRunningForegroundContainerId(); /** + * @return id of next to currently focused/foreground container. If currently focused container + * is last in container map, id of fisrt container from map is returned. + */ + std::string getNextToForegroundContainerId(); + + /** * Set whether ContainersManager should detach containers on exit */ void setContainersDetachOnExit(); diff --git a/server/server.cpp b/server/server.cpp index 547d023..a9ad444 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -62,6 +62,10 @@ #error "DISK_GROUP must be defined!" #endif +#ifndef TTY_GROUP +#error "TTY_GROUP must be defined!" +#endif + extern char** environ; namespace security_containers { @@ -189,7 +193,7 @@ bool Server::prepareEnvironment(const std::string& configPath, bool runAsRoot) // INPUT_EVENT_GROUP provides access to /dev/input/event* devices used by InputMonitor. // DISK_GROUP provides access to /dev/loop* devices, needed when adding new container to copy // containers image - if (!utils::setSuppGroups({LIBVIRT_GROUP, INPUT_EVENT_GROUP, DISK_GROUP})) { + if (!utils::setSuppGroups({LIBVIRT_GROUP, INPUT_EVENT_GROUP, DISK_GROUP, TTY_GROUP})) { return false; } @@ -197,7 +201,10 @@ bool Server::prepareEnvironment(const std::string& configPath, bool runAsRoot) // NOTE: CAP_MAC_OVERRIDE is temporary and must be removed when "smack namespace" // is introduced. The capability is needed to allow modify SMACK labels of // "/var/run/containers//run" mount point. - return (runAsRoot || utils::dropRoot(uid, gid, {CAP_SYS_ADMIN, CAP_MAC_OVERRIDE})); + // CAP_SYS_TTY_CONFIG is needed to activate virtual terminals through ioctl calls + return (runAsRoot || utils::dropRoot(uid, gid, {CAP_SYS_ADMIN, + CAP_MAC_OVERRIDE, + CAP_SYS_TTY_CONFIG})); } diff --git a/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf index e16f7d6..b32dd81 100644 --- a/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf +++ b/tests/unit_tests/client/configs/ut-client/containers/console1-dbus.conf @@ -1,5 +1,6 @@ { "privilege" : 20, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : true, "config" : "../libvirt-config/console1-dbus.xml", diff --git a/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf index 9aa8e51..3dda658 100644 --- a/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf +++ b/tests/unit_tests/client/configs/ut-client/containers/console2-dbus.conf @@ -1,5 +1,6 @@ { "privilege" : 20, + "vt" : -1, "switchToDefaultAfterTimeout" : false, "enableDbusIntegration" : true, "config" : "../libvirt-config/console2-dbus.xml", diff --git a/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf index 09ef262..0128c09 100644 --- a/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf +++ b/tests/unit_tests/client/configs/ut-client/containers/console3-dbus.conf @@ -1,5 +1,6 @@ { "privilege" : 20, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : true, "config" : "../libvirt-config/console3-dbus.xml", diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in b/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in index 6a0ba2d..f9f553e 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/buggy.conf.in @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container-admin/libvirt-config/buggy.xml", diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf b/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf index 4184401..8312204 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/missing.conf @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "/this/is/a/missing/file/path/missing.xml", diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in b/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in index 995f5ff..135654c 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/test-no-shutdown.conf.in @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container-admin/libvirt-config/test-no-shutdown.xml", diff --git a/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in b/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in index a1d3d53..de566ea 100644 --- a/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in +++ b/tests/unit_tests/server/configs/ut-container-admin/containers/test.conf.in @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "@SC_TEST_CONFIG_INSTALL_DIR@/server/ut-container-admin/libvirt-config/test.xml", diff --git a/tests/unit_tests/server/configs/ut-container/containers/buggy.conf b/tests/unit_tests/server/configs/ut-container/containers/buggy.conf index 5992433..d0a307e 100644 --- a/tests/unit_tests/server/configs/ut-container/containers/buggy.conf +++ b/tests/unit_tests/server/configs/ut-container/containers/buggy.conf @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "/missing/file/path/libvirt.xml", diff --git a/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf b/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf index 6301a5a..a272aa1 100644 --- a/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf +++ b/tests/unit_tests/server/configs/ut-container/containers/test-dbus.conf @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : true, "config" : "../libvirt-config/test-dbus.xml", diff --git a/tests/unit_tests/server/configs/ut-container/containers/test.conf b/tests/unit_tests/server/configs/ut-container/containers/test.conf index 111d9ee..bed56de 100644 --- a/tests/unit_tests/server/configs/ut-container/containers/test.conf +++ b/tests/unit_tests/server/configs/ut-container/containers/test.conf @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "../libvirt-config/test.xml", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf index e16f7d6..b32dd81 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1-dbus.conf @@ -1,5 +1,6 @@ { "privilege" : 20, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : true, "config" : "../libvirt-config/console1-dbus.xml", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf index be47df6..884e56d 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console1.conf @@ -1,5 +1,6 @@ { "privilege" : 20, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "../libvirt-config/console1.xml", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf index 9aa8e51..3dda658 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2-dbus.conf @@ -1,5 +1,6 @@ { "privilege" : 20, + "vt" : -1, "switchToDefaultAfterTimeout" : false, "enableDbusIntegration" : true, "config" : "../libvirt-config/console2-dbus.xml", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf index 4c88170..9928914 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console2.conf @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "../libvirt-config/console2.xml", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf index 09ef262..0128c09 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3-dbus.conf @@ -1,5 +1,6 @@ { "privilege" : 20, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : true, "config" : "../libvirt-config/console3-dbus.xml", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf index d6bc429..8a31b50 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/containers/console3.conf @@ -1,5 +1,6 @@ { "privilege" : 15, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "../libvirt-config/console3.xml", diff --git a/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf b/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf index 40dcacc..aeed716 100644 --- a/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf +++ b/tests/unit_tests/server/configs/ut-containers-manager/templates/template.conf @@ -1,5 +1,6 @@ { "privilege" : 20, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "config" : "../libvirt-config/~NAME~.xml", "networkConfig" : "../libvirt-config/~NAME~-network.xml", diff --git a/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in b/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in index 414b920..695ed15 100644 --- a/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in +++ b/tests/unit_tests/server/configs/ut-network-admin/containers/buggy.conf.in @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "", diff --git a/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf b/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf index 13ccc44..76492bb 100644 --- a/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf +++ b/tests/unit_tests/server/configs/ut-network-admin/containers/missing.conf @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "", diff --git a/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in b/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in index be65ee2..990da9a 100644 --- a/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in +++ b/tests/unit_tests/server/configs/ut-network-admin/containers/test.conf.in @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "", diff --git a/tests/unit_tests/server/configs/ut-server/containers/container1.conf b/tests/unit_tests/server/configs/ut-server/containers/container1.conf index 21fb52a..984e973 100644 --- a/tests/unit_tests/server/configs/ut-server/containers/container1.conf +++ b/tests/unit_tests/server/configs/ut-server/containers/container1.conf @@ -1,5 +1,6 @@ { "privilege" : 20, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "../libvirt-config/container1.xml", diff --git a/tests/unit_tests/server/configs/ut-server/containers/container2.conf b/tests/unit_tests/server/configs/ut-server/containers/container2.conf index 6302a39..d340530 100644 --- a/tests/unit_tests/server/configs/ut-server/containers/container2.conf +++ b/tests/unit_tests/server/configs/ut-server/containers/container2.conf @@ -1,5 +1,6 @@ { "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "../libvirt-config/container2.xml", diff --git a/tests/unit_tests/server/configs/ut-server/containers/container3.conf b/tests/unit_tests/server/configs/ut-server/containers/container3.conf index b445156..a9d9e97 100644 --- a/tests/unit_tests/server/configs/ut-server/containers/container3.conf +++ b/tests/unit_tests/server/configs/ut-server/containers/container3.conf @@ -1,5 +1,6 @@ { "privilege" : 15, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : false, "config" : "../libvirt-config/container3.xml", -- 2.7.4 From 634bae3b8623ea01c1204613d69122e280cf08e5 Mon Sep 17 00:00:00 2001 From: Jan Olszak Date: Fri, 3 Oct 2014 18:20:30 +0200 Subject: [PATCH 04/16] Tests of the serialization functions from libConfig [Bug/Feature] N/A [Cause] N/A [Solution] N/A [Verification] Build, install, run tests Change-Id: Ifa9e3397f4405cf4d9d1bcca2c891eb789cdf2ae --- tests/unit_tests/config/ut-configuration.cpp | 26 ++++++++++++++++++++++++++ tests/unit_tests/config/ut-kvstore.cpp | 1 + 2 files changed, 27 insertions(+) diff --git a/tests/unit_tests/config/ut-configuration.cpp b/tests/unit_tests/config/ut-configuration.cpp index b205339..1d72bd8 100644 --- a/tests/unit_tests/config/ut-configuration.cpp +++ b/tests/unit_tests/config/ut-configuration.cpp @@ -27,6 +27,9 @@ #include "ut.hpp" #include "config/fields.hpp" #include "config/manager.hpp" +#include +#include +#include #include namespace fs = boost::filesystem; @@ -316,6 +319,29 @@ BOOST_AUTO_TEST_CASE(FromToKVStoreTest) BOOST_CHECK_EQUAL(out, jsonTestString); fs::remove(dbPath); + fs::remove(dbPath + "-journal"); +} + +BOOST_AUTO_TEST_CASE(FromToFDTest) +{ + TestConfig config; + loadFromString(jsonTestString, config); + // Setup fd + std::string fifoPath = fs::unique_path("/tmp/fdstore-%%%%").string(); + BOOST_CHECK(::mkfifo(fifoPath.c_str(), S_IWUSR | S_IRUSR) >= 0); + int fd = ::open(fifoPath.c_str(), O_RDWR); + BOOST_REQUIRE(fd >= 0); + + // The test + saveToFD(fd, config); + TestConfig outConfig; + loadFromFD(fd, outConfig); + std::string out = saveToString(outConfig); + BOOST_CHECK_EQUAL(out, jsonTestString); + + // Cleanup + BOOST_CHECK(::close(fd) >= 0); + fs::remove(fifoPath); } BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/unit_tests/config/ut-kvstore.cpp b/tests/unit_tests/config/ut-kvstore.cpp index 2c9a998..ba95452 100644 --- a/tests/unit_tests/config/ut-kvstore.cpp +++ b/tests/unit_tests/config/ut-kvstore.cpp @@ -50,6 +50,7 @@ struct Fixture { ~Fixture() { fs::remove(dbPath); + fs::remove(dbPath + "-journal"); } }; -- 2.7.4 From 7ce7abac455827aef85ae5a8f369c25ba5331d4f Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Mon, 13 Oct 2014 14:02:40 +0200 Subject: [PATCH 05/16] Allow SCS to launch without any container [Bug] SCS segfaulted when launching without any containers provided in config. [Cause] Some functions assumed that certain config fields should never be empty [Solution] Additional checks to avoid segfault. [Verification] Build, install, run tests, launch SCS without any predefined containers. Try to switch between containers when less than two containers are present. Change-Id: I58a69d55807f686fb168057dfb1b447707351a46 --- server/containers-manager.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index d8858ab..c9c7ff8 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -112,7 +112,7 @@ ContainersManager::ContainersManager(const std::string& managerConfigPath): mDet } // check if default container exists, throw ContainerOperationException if not found - if (mContainers.find(mConfig.defaultId) == mContainers.end()) { + if (!mConfig.defaultId.empty() && mContainers.find(mConfig.defaultId) == mContainers.end()) { LOGE("Provided default container ID " << mConfig.defaultId << " is invalid."); throw ContainerOperationException("Provided default container ID " + mConfig.defaultId + " is invalid."); @@ -219,9 +219,11 @@ void ContainersManager::startAll() return c1.second->getPrivilege() < c2.second->getPrivilege(); }); - mConfig.foregroundId = foregroundIterator->second->getId(); - LOGI(mConfig.foregroundId << ": no foreground container configured, setting one with highest priority"); - foregroundIterator->second->goForeground(); + if (foregroundIterator != mContainers.end()) { + mConfig.foregroundId = foregroundIterator->second->getId(); + LOGI(mConfig.foregroundId << ": no foreground container configured, setting one with highest priority"); + foregroundIterator->second->goForeground(); + } } } @@ -269,7 +271,10 @@ void ContainersManager::switchingSequenceMonitorNotify() LOGI("switchingSequenceMonitorNotify() called"); auto nextContainerId = getNextToForegroundContainerId(); - focus(nextContainerId); + + if (!nextContainerId.empty()) { + focus(nextContainerId); + } } -- 2.7.4 From b87e6f2d5cce61d806fc6f120b5d50e2f2fa3940 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Wed, 15 Oct 2014 10:13:15 +0200 Subject: [PATCH 06/16] Update missing vt field in container template [Bug] Field 'vt' was missing in template used to add new containers. [Cause] N/A [Solution] N/A [Verification] Build, install, run freshly added container. SCS should not return "missing config field 'vt'" error. Change-Id: Iec9633d3e8a0e727f854a166d6ab7cfc65ccdf5b --- server/configs/templates/template.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/server/configs/templates/template.conf b/server/configs/templates/template.conf index 17480a0..b054fb1 100644 --- a/server/configs/templates/template.conf +++ b/server/configs/templates/template.conf @@ -2,6 +2,7 @@ "cpuQuotaForeground" : -1, "cpuQuotaBackground" : 1000, "privilege" : 10, + "vt" : -1, "switchToDefaultAfterTimeout" : true, "enableDbusIntegration" : true, "config" : "../libvirt-config/~NAME~.xml", -- 2.7.4 From f3330a0e728c9421629d082121f3e3123550e2a9 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Mon, 13 Oct 2014 14:49:29 +0200 Subject: [PATCH 07/16] Adjust configuration files for Tizen:Common profile [Feature] Configuration files modified for Tizen:Common profile. [Cause] Tizen:Common devices use different configuration than M0 devices. [Solution] Change configuration files. [Verification] Build, install on Tizen:Common device, run tests. Change-Id: Ib1db585f99ba4e8feecd1defa76de277e3fead0b --- packaging/security-containers.spec | 2 +- server/configs/daemon.conf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index fc1c806..3905904 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -4,7 +4,7 @@ %define libvirt_group libvirt # The group that has read and write access to /dev/input/event* devices. # It may vary between platforms. -%define input_event_group video +%define input_event_group input # The group has access to /dev/loop* devices. %define disk_group disk # The group that has write access to /dev/tty* devices. diff --git a/server/configs/daemon.conf b/server/configs/daemon.conf index db85284..dbfac95 100644 --- a/server/configs/daemon.conf +++ b/server/configs/daemon.conf @@ -8,9 +8,9 @@ "foregroundId" : "private", "defaultId" : "private", "inputConfig" : {"enabled" : true, - "device" : "gpio-keys", + "device" : "gpio_keys.6", "code" : 139, - "numberOfEvents" : 3, + "numberOfEvents" : 1, "timeWindowMs" : 500}, "proxyCallRules" : [] } -- 2.7.4 From e243eeb1fb3358b321dce9903865257ddaed8e23 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Thu, 9 Oct 2014 19:10:11 +0200 Subject: [PATCH 08/16] Command line interface to SCS [Feature] Command line interface to SCS [Cause] Need to manage SCS from shell [Solution] Binary that use libsecurity-containers [Verification] Build, install, execute security-containers-cli (switch container), check SCS logs. Change-Id: Ia6cc1cc00295e19befd2e0987900b69e2d4e7bd3 --- CMakeLists.txt | 2 + cli/CMakeLists.txt | 37 ++++++++++++ cli/command-line-interface.cpp | 115 +++++++++++++++++++++++++++++++++++++ cli/command-line-interface.hpp | 109 +++++++++++++++++++++++++++++++++++ cli/main.cpp | 74 ++++++++++++++++++++++++ doc/doxygen.cfg | 2 +- packaging/security-containers.spec | 14 +++++ 7 files changed, 352 insertions(+), 1 deletion(-) create mode 100644 cli/CMakeLists.txt create mode 100644 cli/command-line-interface.cpp create mode 100644 cli/command-line-interface.hpp create mode 100644 cli/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c8e74c6..f824f8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,7 @@ SET(CONTAINER_SUPPORT_FOLDER ${PROJECT_SOURCE_DIR}/container-support) SET(CONTAINER_DAEMON_FOLDER ${PROJECT_SOURCE_DIR}/container-daemon) SET(TESTS_FOLDER ${PROJECT_SOURCE_DIR}/tests) SET(UNIT_TESTS_FOLDER ${TESTS_FOLDER}/unit_tests) +SET(CLI_FOLDER ${PROJECT_SOURCE_DIR}/cli) IF(NOT DEFINED SYSCONF_INSTALL_DIR) SET(SYSCONF_INSTALL_DIR "/etc") @@ -132,4 +133,5 @@ ADD_SUBDIRECTORY(${SERVER_FOLDER}) ADD_SUBDIRECTORY(${CONTAINER_SUPPORT_FOLDER}) ADD_SUBDIRECTORY(${CONTAINER_DAEMON_FOLDER}) ADD_SUBDIRECTORY(${TESTS_FOLDER}) +ADD_SUBDIRECTORY(${CLI_FOLDER}) diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt new file mode 100644 index 0000000..076dd94 --- /dev/null +++ b/cli/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright (c) 2014 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 CMakeLists.txt +# @author Mateusz Malicki (m.malicki2@samsung.com) +# + +MESSAGE(STATUS "Generating makefile for the command line interface...") +FILE(GLOB cli_SRCS *.cpp *.hpp) + +## Setup target ################################################################ +SET(CLI_CODENAME "${PROJECT_NAME}-cli") +ADD_EXECUTABLE(${CLI_CODENAME} ${cli_SRCS}) + + +## Link libraries ############################################################## +PKG_CHECK_MODULES(LIB_DEPS REQUIRED security-containers) + +INCLUDE_DIRECTORIES(${CLIENT_FOLDER}) +INCLUDE_DIRECTORIES(${COMMON_FOLDER}) +TARGET_LINK_LIBRARIES(${CLI_CODENAME} ${LIB_DEPS_LIBRARIES} ${PROJECT_NAME}) + + +## Install ##################################################################### +INSTALL(TARGETS ${CLI_CODENAME} DESTINATION bin) diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp new file mode 100644 index 0000000..02c867f --- /dev/null +++ b/cli/command-line-interface.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * 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 + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Definition of CommandLineInterface class + */ + +#include "config.hpp" +#include "command-line-interface.hpp" +#include + +#include +#include +#include +#include + +using namespace std; + +namespace security_containers { +namespace cli { + +namespace { + +/** + * Invoke specific function on ScClient + * + * @param fun Function to be called. It must not throw any exception. + */ +void one_shot(const function& fun) +{ + string msg; + ScStatus status; + ScClient client; + + status = sc_start_glib_loop(); + if (SCCLIENT_SUCCESS != status) { + throw runtime_error("Can't start glib loop"); + } + + client = sc_client_create(); + if (NULL == client) { + msg = "Can't create client"; + goto finish; + } + + status = sc_connect(client); + if (SCCLIENT_SUCCESS != status) { + msg = sc_get_status_message(client); + goto finish; + } + + status = fun(client); + if (SCCLIENT_SUCCESS != status) { + msg = sc_get_status_message(client); + goto finish; + } + +finish: + sc_client_free(client); + sc_stop_glib_loop(); + if (! msg.empty()) { + throw runtime_error(msg); + } +} + +} // namespace + +void CommandLineInterface::printUsage(std::ostream& out) const +{ + out << mUsage << "\n\n" + << "\tDescription\n" + << "\t\t" << mUsageInfo << "\n\n" + << "\tOptions\n"; + for (const auto& args : mArgsSpec) { + out << "\t\t" << args.first << " -- " << args.second << "\n"; + } + out << "\n"; +} + +void CommandLineInterface::execute(int pos, int argc, const char** argv) +{ + mExecutorCallback(pos, argc, argv); +} + + +void set_active_container(int pos, int argc, const char** argv) +{ + using namespace std::placeholders; + + if (argc <= pos + 1) { + throw runtime_error("Not enough parameters"); + } + + one_shot(bind(sc_set_active_container, _1, argv[pos + 1])); +} + +} // namespace cli +} // namespace security_containers diff --git a/cli/command-line-interface.hpp b/cli/command-line-interface.hpp new file mode 100644 index 0000000..c193068 --- /dev/null +++ b/cli/command-line-interface.hpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * 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 + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Declaration of CommandLineInterface class + */ +#ifndef CLI_COMMAND_LINE_INTERFACE_HPP +#define CLI_COMMAND_LINE_INTERFACE_HPP + +#include +#include +#include +#include + +namespace security_containers { +namespace cli { + +/** + * Class that implements command pattern. + */ +class CommandLineInterface { + +public: + /** + * @see CommandLineInterface::execute + */ + typedef std::function ExecutorCallback; + + /** + * @see CommandLineInterface::CommandLineInterface + */ + typedef std::map ArgsSpec; + + /** + * Dummy constructor (for stl usage) + */ + CommandLineInterface() {} + + /** + * Construct command + * + * @param executorCallback Callback function that will do the job + * @param usage Description of use + * @param usageInfo Description of the command + * @param argsSpec Description of arguments + */ + CommandLineInterface(const ExecutorCallback& executorCallback, + const std::string& usage, + const std::string& usageInfo, + const ArgsSpec& argsSpec) + : mExecutorCallback(executorCallback), + mUsage(usage), + mUsageInfo(usageInfo), + mArgsSpec(argsSpec) {} + + /** + * Print usage to stream + * + * @param out Output stream + */ + void printUsage(std::ostream& out) const; + + /** + * Do the work + * + * It calls the callback passed in constructor + * + * @param pos Points to element in argv where command was recognized (i.e. command name) + * @param argc Number of elements in argv + * @param argv Command line arguments + */ + void execute(int pos, int argc, const char** argv); + + +private: + const ExecutorCallback mExecutorCallback; + const std::string mUsage; + const std::string mUsageInfo; + const ArgsSpec mArgsSpec; +}; + +/** + * Parses command line arguments and call sc_set_active_container + * + * @see sc_set_active_container + */ +void set_active_container(int pos, int argc, const char** argv); + +} // namespace cli +} // namespace security_containers + +#endif /* CLI_COMMAND_LINE_INTERFACE_HPP */ diff --git a/cli/main.cpp b/cli/main.cpp new file mode 100644 index 0000000..e74f620 --- /dev/null +++ b/cli/main.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Mateusz Malicki + * + * 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 + * @author Mateusz Malicki (m.malicki2@samsung.com) + * @brief Declaration of CommandLineInterface class + */ + +#include "command-line-interface.hpp" + +#include +#include +#include +#include +#include + +using namespace security_containers::cli; + +std::map commands = { + {"set_active_container", { + set_active_container, + "set_active_container container_id", + "Set active (foreground) container", + {{"container_id", "id container name"}}} + } +}; + +void printUsage(std::ostream& out, const std::string& name) +{ + out << "Usage: " << name << " [command [args]]\n\n" + << "command can be one of the following:\n"; + + for (const auto& command : commands) { + command.second.printUsage(out); + } +} + +int main(const int argc, const char** argv) +{ + if (argc < 2) { + printUsage(std::cout, argv[0]); + return EXIT_FAILURE; + } + if (commands.count(argv[1]) == 0) { + printUsage(std::cout, argv[0]); + return EXIT_FAILURE; + } + + CommandLineInterface& command = commands[argv[1]]; + try { + command.execute(1, argc, argv); + } catch (const std::runtime_error& ex) { + std::cerr << ex.what() << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg index 7e304e5..e997623 100644 --- a/doc/doxygen.cfg +++ b/doc/doxygen.cfg @@ -647,7 +647,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = ../common ../client ../server +INPUT = ../common ../client ../server ../cli # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index 3905904..137f02b 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -186,6 +186,20 @@ Daemon running inside every container. /etc/dbus-1/system.d/org.tizen.containers.domain.daemon.conf +## Command Line Interface ###################################################### +%package cli +Summary: Security Containers Command Line Interface +Group: Security/Other +Requires: security-containers-client = %{version}-%{release} + +%description cli +Command Line Interface for security-containers. + +%files cli +%defattr(644,root,root,755) +%attr(755,root,root) %{_bindir}/security-containers-cli + + ## Test Package ################################################################ %package tests Summary: Security Containers Tests -- 2.7.4 From 2a642703696fa9d3390c18ccd58325cae56e62fb Mon Sep 17 00:00:00 2001 From: Piotr Bartosiewicz Date: Tue, 21 Oct 2014 15:32:06 +0200 Subject: [PATCH 09/16] Fix missing package dependency [Bug/Feature] Test package require python-xml for working. [Cause] N/A [Solution] N/A [Verification] Build, install, run tests. Change-Id: I08774f20115dfd4d4ab18a65dd4ac395fb6322ce --- packaging/security-containers.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/security-containers.spec b/packaging/security-containers.spec index 137f02b..00a05a6 100644 --- a/packaging/security-containers.spec +++ b/packaging/security-containers.spec @@ -207,6 +207,7 @@ Group: Development/Libraries Requires: security-containers = %{version}-%{release} Requires: security-containers-client = %{version}-%{release} Requires: python +Requires: python-xml Requires: boost-test %description tests -- 2.7.4 From 0533ba4677d802d3821e04eb6756d76180994843 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Tue, 14 Oct 2014 10:00:49 +0200 Subject: [PATCH 10/16] Fix issue with permissions when copying dir contents [Bug] Permission denied error when trying to copy read-only directories recursively. [Cause] boost::filesystem::copy applied permissions immediately, which in some cases caused error when trying to write something inside processed directory. [Solution] Instead of using boost::filesystem::copy on directories, split action into three sub-actions: * Create new directory with boost::filesystem::create_directory * Call copyDirContentsRec() to copy contents of processed directory * Apply source directory permissions and ownership [Verification] Build, install, run tests. Change-Id: Ifdec110a595dcecd113abf4065dd1cdc03f2d3cb --- common/utils/fs.cpp | 52 +++++++++++++++++++++++++++------------- server/server.cpp | 5 +++- tests/unit_tests/utils/ut-fs.cpp | 35 ++++++++++++++++++++++++++- 3 files changed, 73 insertions(+), 19 deletions(-) diff --git a/common/utils/fs.cpp b/common/utils/fs.cpp index a03c139..8a6441c 100644 --- a/common/utils/fs.cpp +++ b/common/utils/fs.cpp @@ -208,38 +208,56 @@ bool copyDirContentsRec(const boost::filesystem::path& src, const boost::filesys namespace fs = boost::filesystem; // TODO: Right now this function skips files which produce error when copying. Errors show up - // when: - // a) fs::directory_iterator file(src) is created - // b) fs::copy(...) is called - // In both cases lack of permissions is the issue. + // when fs::directory_iterator file(src) is created - lack of permissions is the issue. // - // In a) case we can't do much - SCS won't be able to read the directory and its contents. Such - // directories are not common in the filesystem, so they *probably* can be skipped. - // - // In b) case multiple directories have too strict permissions to be directly copied. This - // is a problem for some files crucial to container launch (ex. we cannot copy - // /usr/lib/systemd/systemd because /usr/lib has 555 permissions). - // To fix b) issue, copying must be done in two steps: - // 1. Copy file contents without permissions (this probably can be achieved by opening two - // files in-code with fstream and programatically copying data from one file to another). - // 2. Apply all available file attributes from source (permissions, owner UID/GID, xattrs...) + // To fix lack of permissions, copying must be done as root. The easiest way would be to launch + // copyDirContents after fork() and setuid(0). try { for (fs::directory_iterator file(src); file != fs::directory_iterator(); ++file) { fs::path current(file->path()); + fs::path destination = dst / current.filename(); boost::system::error_code ec; - fs::copy(current, dst / current.filename(), ec); - if(ec.value() != boost::system::errc::success) { + + if (!fs::is_symlink(current) && fs::is_directory(current)) { + fs::create_directory(destination, ec); + } else { + fs::copy(current, destination, ec); + } + + if (ec.value() != boost::system::errc::success) { LOGW("Failed to copy " << current << ": " << ec.message()); + continue; } if (!fs::is_symlink(current) && fs::is_directory(current)) { - if (!copyDirContentsRec(current, dst / current.filename())) { + if (!copyDirContentsRec(current, destination)) { return false; } + + // apply permissions coming from source file/directory + fs::file_status stat = status(current); + fs::permissions(destination, stat.permissions(), ec); + + if (ec.value() != boost::system::errc::success) { + LOGW("Failed to set permissions for " << destination << ": " << ec.message()); + } + } + + // change owner + struct stat info; + ::stat(current.string().c_str(), &info); + if (fs::is_symlink(destination)) { + if (::lchown(destination.string().c_str(), info.st_uid, info.st_gid) < 0) { + LOGW("Failed to change owner of symlink " << destination.string() << ": " << strerror(errno)); + } + } else { + if (::chown(destination.string().c_str(), info.st_uid, info.st_gid) < 0) { + LOGW("Failed to change owner of file " << destination.string() << ": " << strerror(errno)); + } } } } catch (fs::filesystem_error& e) { diff --git a/server/server.cpp b/server/server.cpp index a9ad444..7b03f4c 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -202,9 +202,12 @@ bool Server::prepareEnvironment(const std::string& configPath, bool runAsRoot) // is introduced. The capability is needed to allow modify SMACK labels of // "/var/run/containers//run" mount point. // CAP_SYS_TTY_CONFIG is needed to activate virtual terminals through ioctl calls + // CAP_CHOWN is needed when creating new container from image to set owner/group for each file, + // directory or symlink return (runAsRoot || utils::dropRoot(uid, gid, {CAP_SYS_ADMIN, CAP_MAC_OVERRIDE, - CAP_SYS_TTY_CONFIG})); + CAP_SYS_TTY_CONFIG, + CAP_CHOWN})); } diff --git a/tests/unit_tests/utils/ut-fs.cpp b/tests/unit_tests/utils/ut-fs.cpp index 43be58a..a1eea40 100644 --- a/tests/unit_tests/utils/ut-fs.cpp +++ b/tests/unit_tests/utils/ut-fs.cpp @@ -64,6 +64,8 @@ const std::string FILE_DIR_RANDOM_2 = boost::filesystem::unique_path("testDir-%%%%").string(); const std::string FILE_DIR_RANDOM_3 = boost::filesystem::unique_path("testDir-%%%%").string(); +const std::string FILE_DIR_RANDOM_4 = + boost::filesystem::unique_path("testDir-%%%%").string(); const std::string FILE_NAME_RANDOM_1 = boost::filesystem::unique_path("testFile-%%%%").string(); const std::string FILE_NAME_RANDOM_2 = @@ -146,25 +148,47 @@ BOOST_AUTO_TEST_CASE(MoveFileTest) BOOST_AUTO_TEST_CASE(CopyDirContentsTest) { namespace fs = boost::filesystem; - std::string src, src_inner, dst, dst_inner; + std::string src, src_inner, src_inner2, dst, dst_inner, dst_inner2; boost::system::error_code ec; src = TMP_PATH + "/" + FILE_DIR_RANDOM_1; src_inner = src + "/" + FILE_DIR_RANDOM_3; + src_inner2 = src + "/" + FILE_DIR_RANDOM_4; dst = TMP_PATH + "/" + FILE_DIR_RANDOM_2; dst_inner = dst + "/" + FILE_DIR_RANDOM_3; + dst_inner2 = dst + "/" + FILE_DIR_RANDOM_4; + + // template dir structure: + // |-src + // |-FILE_NAME_RANDOM_1 + // |-FILE_NAME_RANDOM_2 + // |-src_inner (rw directory) + // | |-FILE_NAME_RANDOM_1 + // | + // |-src_inner2 (ro directory) + // |-FILE_NAME_RANDOM_1 + // |-FILE_NAME_RANDOM_2 // create entire structure with files BOOST_REQUIRE(fs::create_directory(src, ec)); BOOST_REQUIRE(ec.value() == 0); BOOST_REQUIRE(fs::create_directory(src_inner, ec)); BOOST_REQUIRE(ec.value() == 0); + BOOST_REQUIRE(fs::create_directory(src_inner2, ec)); + BOOST_REQUIRE(ec.value() == 0); BOOST_REQUIRE(saveFileContent(src + "/" + FILE_NAME_RANDOM_1, FILE_CONTENT)); BOOST_REQUIRE(saveFileContent(src + "/" + FILE_NAME_RANDOM_2, FILE_CONTENT_2)); BOOST_REQUIRE(saveFileContent(src_inner + "/" + FILE_NAME_RANDOM_1, FILE_CONTENT_3)); + BOOST_REQUIRE(saveFileContent(src_inner2 + "/" + FILE_NAME_RANDOM_1, FILE_CONTENT_3)); + BOOST_REQUIRE(saveFileContent(src_inner2 + "/" + FILE_NAME_RANDOM_2, FILE_CONTENT_2)); + // change permissions of src_inner2 directory + fs::permissions(src_inner2, fs::owner_read, ec); + BOOST_REQUIRE(ec.value() == 0); + + // create dst directory BOOST_REQUIRE(fs::create_directory(dst, ec)); BOOST_REQUIRE(ec.value() == 0); @@ -176,10 +200,19 @@ BOOST_AUTO_TEST_CASE(CopyDirContentsTest) BOOST_CHECK(fs::exists(dst + "/" + FILE_NAME_RANDOM_2)); BOOST_CHECK(fs::exists(dst_inner)); BOOST_CHECK(fs::exists(dst_inner + "/" + FILE_NAME_RANDOM_1)); + BOOST_CHECK(fs::exists(dst_inner2)); + BOOST_CHECK(fs::exists(dst_inner2 + "/" + FILE_NAME_RANDOM_1)); + BOOST_CHECK(fs::exists(dst_inner2 + "/" + FILE_NAME_RANDOM_2)); BOOST_CHECK_EQUAL(readFileContent(dst + "/" + FILE_NAME_RANDOM_1), FILE_CONTENT); BOOST_CHECK_EQUAL(readFileContent(dst + "/" + FILE_NAME_RANDOM_2), FILE_CONTENT_2); BOOST_CHECK_EQUAL(readFileContent(dst_inner + "/" + FILE_NAME_RANDOM_1), FILE_CONTENT_3); + BOOST_CHECK_EQUAL(readFileContent(dst_inner2 + "/" + FILE_NAME_RANDOM_1), FILE_CONTENT_3); + BOOST_CHECK_EQUAL(readFileContent(dst_inner2 + "/" + FILE_NAME_RANDOM_2), FILE_CONTENT_2); + + fs::file_status st; + BOOST_REQUIRE_NO_THROW(st = fs::status(fs::path(dst_inner2))); + BOOST_CHECK(fs::owner_read == st.permissions()); } BOOST_AUTO_TEST_SUITE_END() -- 2.7.4 From 46bf0c683aad2818f119c275042d39e8d7dcb19b Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Thu, 16 Oct 2014 14:44:52 +0200 Subject: [PATCH 11/16] Add launchAsRoot and use it when adding new container [Feature] Function launchAsRoot. [Cause] Some functions need to be launched as root. [Solution] Add launchAsRoot which forks, sets UID to 0 and then calls a function. [Verification] Build, install, run tests. Add new container - no copying errors should occur. Change-Id: Iaf917108ea4c7c699d9f2d69c8100430daa4f9c4 --- common/utils/environment.cpp | 39 +++++++++++++++++++++++++++++++++++++++ common/utils/environment.hpp | 8 ++++++++ common/utils/fs.cpp | 6 ------ server/containers-manager.cpp | 13 +++++++++---- server/server.cpp | 4 +++- 5 files changed, 59 insertions(+), 11 deletions(-) diff --git a/common/utils/environment.cpp b/common/utils/environment.cpp index 70ef27c..eaaef12 100644 --- a/common/utils/environment.cpp +++ b/common/utils/environment.cpp @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include @@ -82,6 +84,43 @@ bool dropRoot(uid_t uid, gid_t gid, const std::vector& caps) return true; } +bool launchAsRoot(const std::function& func) +{ + pid_t pid = fork(); + if (pid < 0) { + LOGE("Fork failed: " << strerror(errno)); + return false; + } + + if (pid == 0) { + if (::setuid(0) < 0) { + LOGW("Failed to become root: " << strerror(errno)); + ::exit(EXIT_FAILURE); + } + + try { + func(); + } catch (std::exception& e) { + LOGE("Failed to successfully execute func: " << e.what()); + ::exit(EXIT_FAILURE); + } + + ::exit(EXIT_SUCCESS); + } + + int result; + if (::waitpid(pid, &result, 0) < 0) { + LOGE("waitpid failed: " << strerror(errno)); + return false; + } + if (result != 0) { + LOGE("Function launched as root failed with result " << result); + return false; + } + + return true; +} + } // namespace utils } // namespace security_containers diff --git a/common/utils/environment.hpp b/common/utils/environment.hpp index b62189b..120b6ac 100644 --- a/common/utils/environment.hpp +++ b/common/utils/environment.hpp @@ -27,6 +27,7 @@ #include #include +#include #include @@ -44,6 +45,13 @@ bool setSuppGroups(const std::vector& groups); */ bool dropRoot(uid_t uid, gid_t gid, const std::vector& caps); +/** + * Launch func as root user. + * + * This function forks, sets UID 0 to child process and calls func. + */ +bool launchAsRoot(const std::function& func); + } // namespace utils } // namespace security_containers diff --git a/common/utils/fs.cpp b/common/utils/fs.cpp index 8a6441c..660db9f 100644 --- a/common/utils/fs.cpp +++ b/common/utils/fs.cpp @@ -207,12 +207,6 @@ bool copyDirContentsRec(const boost::filesystem::path& src, const boost::filesys { namespace fs = boost::filesystem; - // TODO: Right now this function skips files which produce error when copying. Errors show up - // when fs::directory_iterator file(src) is created - lack of permissions is the issue. - // - // To fix lack of permissions, copying must be done as root. The easiest way would be to launch - // copyDirContents after fork() and setuid(0). - try { for (fs::directory_iterator file(src); file != fs::directory_iterator(); diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index c9c7ff8..82be28d 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -37,6 +37,7 @@ #include "dbus/exception.hpp" #include "utils/fs.hpp" #include "utils/img.hpp" +#include "utils/environment.hpp" #include #include @@ -591,7 +592,11 @@ void ContainersManager::handleAddContainerCall(const std::string& id, // copy container image if config contains path to image LOGT("image path: " << mConfig.containerImagePath); if (!mConfig.containerImagePath.empty()) { - if (!utils::copyImageContents(mConfig.containerImagePath, containerPathStr)) { + auto copyImageContentsWrapper = std::bind(&utils::copyImageContents, + mConfig.containerImagePath, + containerPathStr); + + if (!utils::launchAsRoot(copyImageContentsWrapper)) { LOGE("Failed to copy container image."); result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, "Failed to copy container image."); @@ -636,7 +641,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id, generateNewConfig(id, libvirtNetworkFilterPath, newLibvirtNetworkFilterPath); } catch (SecurityContainersException& e) { LOGE(e.what()); - removeAllWrapper(containerPathStr); + utils::launchAsRoot(std::bind(removeAllWrapper, containerPathStr)); result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, e.what()); return; } @@ -646,7 +651,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id, addContainer(newConfigPath); } catch (SecurityContainersException& e) { LOGE(e.what()); - removeAllWrapper(containerPathStr); + utils::launchAsRoot(std::bind(removeAllWrapper, containerPathStr)); result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, e.what()); return; } @@ -656,7 +661,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id, result->setVoid(); } else { LOGE("Failed to start container."); - removeAllWrapper(containerPathStr); + utils::launchAsRoot(std::bind(removeAllWrapper, containerPathStr)); result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, "Failed to start container."); } diff --git a/server/server.cpp b/server/server.cpp index 7b03f4c..f477f0a 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -204,10 +204,12 @@ bool Server::prepareEnvironment(const std::string& configPath, bool runAsRoot) // CAP_SYS_TTY_CONFIG is needed to activate virtual terminals through ioctl calls // CAP_CHOWN is needed when creating new container from image to set owner/group for each file, // directory or symlink + // CAP_SETUID is needed to launch specific funtions as root (see environment.cpp) return (runAsRoot || utils::dropRoot(uid, gid, {CAP_SYS_ADMIN, CAP_MAC_OVERRIDE, CAP_SYS_TTY_CONFIG, - CAP_CHOWN})); + CAP_CHOWN, + CAP_SETUID})); } -- 2.7.4 From e34356ee58cea135d0396e4b1218f11a44dc0216 Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Mon, 20 Oct 2014 14:00:32 +0200 Subject: [PATCH 12/16] Improvements to SCS API [Bug] * removeAllWrapper caught wrong type of exception * AddContainer did not focus container after adding * getActiveContainerId segfaulted when no container was present [Cause] N/A [Solution] N/A [Verification] Build, install, run tests. Change-Id: I6bc665952c0f0c515c3aa548bdd6165b2ee7d55b --- server/containers-manager.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index 82be28d..a707fe2 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -490,7 +490,7 @@ void ContainersManager::handleGetContainerIdsCall(dbus::MethodResultBuilder::Poi void ContainersManager::handleGetActiveContainerIdCall(dbus::MethodResultBuilder::Pointer result) { LOGI("GetActiveContainerId call"); - if (mContainers[mConfig.foregroundId]->isRunning()){ + if (!mConfig.foregroundId.empty() && mContainers[mConfig.foregroundId]->isRunning()){ result->set(g_variant_new("(s)", mConfig.foregroundId.c_str())); } else { result->set(g_variant_new("(s)", "")); @@ -622,7 +622,7 @@ void ContainersManager::handleAddContainerCall(const std::string& id, try { LOGD("Removing copied data"); fs::remove_all(fs::path(path)); - } catch(const boost::exception& e) { + } catch(const std::exception& e) { LOGW("Failed to remove data: " << boost::diagnostic_information(e)); } }; @@ -656,8 +656,9 @@ void ContainersManager::handleAddContainerCall(const std::string& id, return; } - auto resultCallback = [result, containerPathStr, removeAllWrapper](bool succeeded) { + auto resultCallback = [this, id, result, containerPathStr, removeAllWrapper](bool succeeded) { if (succeeded) { + focus(id); result->setVoid(); } else { LOGE("Failed to start container."); -- 2.7.4 From 068abbdef3718ccd0b142eab2439134975cdd16e Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Thu, 23 Oct 2014 13:31:30 +0200 Subject: [PATCH 13/16] Handle empty container name in AddContainer API [Bug] AddContainer API did not handle the case when container id was empty. [Cause] N/A [Solution] N/A [Verification] Build, install, try adding a container with empty string as name. Change-Id: I9340e56c58070c5b4c7aa1a0e4d7c2f5ea9c3aa6 --- server/containers-manager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/server/containers-manager.cpp b/server/containers-manager.cpp index a707fe2..d0d0a36 100644 --- a/server/containers-manager.cpp +++ b/server/containers-manager.cpp @@ -572,6 +572,13 @@ void ContainersManager::generateNewConfig(const std::string& id, void ContainersManager::handleAddContainerCall(const std::string& id, dbus::MethodResultBuilder::Pointer result) { + if (id.empty()) { + LOGE("Failed to add container - invalid name."); + result->setError(api::host::ERROR_CONTAINER_CREATE_FAILED, + "Failed to add container - invalid name."); + return; + } + LOGI("Adding container " << id); // TODO: This solution is temporary. It utilizes direct access to config files when creating new -- 2.7.4 From 17ebae30eab7530460afee437b56c8ef59e8e0b5 Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Mon, 20 Oct 2014 09:34:33 +0200 Subject: [PATCH 14/16] Added sc_add_container to security-container's client [Feature] Ability to add container through SCS client [Cause] Cli need this [Solution] Add sc_add_container client function [Verification] Build, install, run Client/AddContainerTest test Change-Id: Ie0179cb02bdf1946fb9f8d2fd2f3c303cda401fe --- client/security-containers-client-impl.cpp | 8 ++++++++ client/security-containers-client-impl.hpp | 5 +++++ client/security-containers-client.cpp | 5 +++++ client/security-containers-client.h | 9 +++++++++ tests/unit_tests/client/ut-client.cpp | 12 ++++++++++++ 5 files changed, 39 insertions(+) diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index a2c51ba..95418b9 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -353,6 +353,14 @@ ScStatus Client::sc_set_active_container(const char* id) noexcept return callMethod(HOST_INTERFACE, api::host::METHOD_SET_ACTIVE_CONTAINER, args_in); } +ScStatus Client::sc_add_container(const char* id) noexcept +{ + assert(id); + + GVariant* args_in = g_variant_new("(s)", id); + return callMethod(HOST_INTERFACE, api::host::METHOD_ADD_CONTAINER, args_in); +} + ScStatus Client::sc_container_dbus_state(ScContainerDbusStateCallback containerDbusStateCallback, void* data) noexcept { diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp index f1bfacb..3f5a556 100644 --- a/client/security-containers-client-impl.hpp +++ b/client/security-containers-client-impl.hpp @@ -127,6 +127,11 @@ public: ScStatus sc_set_active_container(const char* id) noexcept; /** + * @see ::sc_add_container + */ + ScStatus sc_add_container(const char* id) noexcept; + + /** * @see ::sc_container_dbus_state */ ScStatus sc_container_dbus_state(ScContainerDbusStateCallback containerDbusStateCallback, diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp index cb22544..95c2758 100644 --- a/client/security-containers-client.cpp +++ b/client/security-containers-client.cpp @@ -131,6 +131,11 @@ API ScStatus sc_set_active_container(ScClient client, const char* id) return getClient(client).sc_set_active_container(id); } +API ScStatus sc_add_container(ScClient client, const char* id) +{ + return getClient(client).sc_add_container(id); +} + API ScStatus sc_container_dbus_state(ScClient client, ScContainerDbusStateCallback containerDbusStateCallback, void* data) diff --git a/client/security-containers-client.h b/client/security-containers-client.h index 4d37c3c..1307cb5 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -267,6 +267,15 @@ ScStatus sc_get_container_id_by_pid(ScClient client, int pid, ScString* id); ScStatus sc_set_active_container(ScClient client, const char* id); /** + * Create and add container + * + * @param[in] client security-containers-server's client + * @param[in] id container id + * @return status of this function call + */ +ScStatus sc_add_container(ScClient client, const char* id); + +/** * Register dbus state change callback function. * * @note The callback function will be invoked on a different thread. diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index 574be39..5db6962 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -188,6 +188,18 @@ BOOST_AUTO_TEST_CASE(SetActiveContainerTest) sc_client_free(client); } +BOOST_AUTO_TEST_CASE(AddContainerTest) +{ + const std::string newActiveContainerId = ""; + + ScClient client = sc_client_create(); + ScStatus status = sc_connect(client); + BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + status = sc_add_container(client, newActiveContainerId.c_str()); + BOOST_REQUIRE_EQUAL(SCCLIENT_CUSTOM_ERROR, status); + sc_client_free(client); +} + BOOST_AUTO_TEST_CASE(FileMoveRequestTest) { const std::string path = "/tmp/fake_path"; -- 2.7.4 From 69db805a5ca63b93cb41a4773bdc894444ec52df Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Mon, 20 Oct 2014 10:14:42 +0200 Subject: [PATCH 15/16] Added add_container to cli [Feature] Ability to add container through cli [Cause] The need for the ability to add containers [Solution] Add add_container cli function [Verification] Build, install, run add container Change-Id: I020bddaa3707f0e84227a35a85d0905fbb81d6be --- cli/command-line-interface.cpp | 11 +++++++++++ cli/command-line-interface.hpp | 7 +++++++ cli/main.cpp | 6 ++++++ 3 files changed, 24 insertions(+) diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp index 02c867f..a7b7aed 100644 --- a/cli/command-line-interface.cpp +++ b/cli/command-line-interface.cpp @@ -111,5 +111,16 @@ void set_active_container(int pos, int argc, const char** argv) one_shot(bind(sc_set_active_container, _1, argv[pos + 1])); } +void add_container(int pos, int argc, const char** argv) +{ + using namespace std::placeholders; + + if (argc <= pos + 1) { + throw runtime_error("Not enough parameters"); + } + + one_shot(bind(sc_add_container, _1, argv[pos + 1])); +} + } // namespace cli } // namespace security_containers diff --git a/cli/command-line-interface.hpp b/cli/command-line-interface.hpp index c193068..d9fc39f 100644 --- a/cli/command-line-interface.hpp +++ b/cli/command-line-interface.hpp @@ -103,6 +103,13 @@ private: */ void set_active_container(int pos, int argc, const char** argv); +/** + * Parses command line arguments and call sc_add_container + * + * @see sc_add_container + */ +void add_container(int pos, int argc, const char** argv); + } // namespace cli } // namespace security_containers diff --git a/cli/main.cpp b/cli/main.cpp index e74f620..d84d5ac 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -38,6 +38,12 @@ std::map commands = { "set_active_container container_id", "Set active (foreground) container", {{"container_id", "id container name"}}} + }, + {"add_container", { + add_container, + "add_container container_id", + "Create and add container", + {{"container_id", "id container name"}}} } }; -- 2.7.4 From 0ecba0804c632022b45655a3f168834327685a1d Mon Sep 17 00:00:00 2001 From: Mateusz Malicki Date: Thu, 6 Nov 2014 18:31:58 +0100 Subject: [PATCH 16/16] Rename cli, client library and client test functions [Feature] Brave New Name [Cause] New name of SCS [Solution] Rename: * sc_ -> vsm_ * Sc -> Vsm, * SC -> VSM, * container_dbus_state -> add_state_callback, * get_container_id_by_pid -> lookup_domain_by_pid, * get_container_ids -> get_domain_ids [Verification] Compile Change-Id: Icaffebaa5e7a0e9d5869a9d2ec701bf385e99529 --- cli/command-line-interface.cpp | 34 ++--- cli/command-line-interface.hpp | 16 +-- cli/main.cpp | 26 ++-- client/security-containers-client-impl.cpp | 161 ++++++++++++------------ client/security-containers-client-impl.hpp | 80 ++++++------ client/security-containers-client.cpp | 84 ++++++------- client/security-containers-client.h | 120 +++++++++--------- tests/unit_tests/client/ut-client.cpp | 194 +++++++++++++++-------------- 8 files changed, 366 insertions(+), 349 deletions(-) diff --git a/cli/command-line-interface.cpp b/cli/command-line-interface.cpp index a7b7aed..8af17a7 100644 --- a/cli/command-line-interface.cpp +++ b/cli/command-line-interface.cpp @@ -39,42 +39,42 @@ namespace cli { namespace { /** - * Invoke specific function on ScClient + * Invoke specific function on VsmClient * * @param fun Function to be called. It must not throw any exception. */ -void one_shot(const function& fun) +void one_shot(const function& fun) { string msg; - ScStatus status; - ScClient client; + VsmStatus status; + VsmClient client; - status = sc_start_glib_loop(); - if (SCCLIENT_SUCCESS != status) { + status = vsm_start_glib_loop(); + if (VSMCLIENT_SUCCESS != status) { throw runtime_error("Can't start glib loop"); } - client = sc_client_create(); + client = vsm_client_create(); if (NULL == client) { msg = "Can't create client"; goto finish; } - status = sc_connect(client); - if (SCCLIENT_SUCCESS != status) { - msg = sc_get_status_message(client); + status = vsm_connect(client); + if (VSMCLIENT_SUCCESS != status) { + msg = vsm_get_status_message(client); goto finish; } status = fun(client); - if (SCCLIENT_SUCCESS != status) { - msg = sc_get_status_message(client); + if (VSMCLIENT_SUCCESS != status) { + msg = vsm_get_status_message(client); goto finish; } finish: - sc_client_free(client); - sc_stop_glib_loop(); + vsm_client_free(client); + vsm_stop_glib_loop(); if (! msg.empty()) { throw runtime_error(msg); } @@ -108,10 +108,10 @@ void set_active_container(int pos, int argc, const char** argv) throw runtime_error("Not enough parameters"); } - one_shot(bind(sc_set_active_container, _1, argv[pos + 1])); + one_shot(bind(vsm_set_active_container, _1, argv[pos + 1])); } -void add_container(int pos, int argc, const char** argv) +void create_domain(int pos, int argc, const char** argv) { using namespace std::placeholders; @@ -119,7 +119,7 @@ void add_container(int pos, int argc, const char** argv) throw runtime_error("Not enough parameters"); } - one_shot(bind(sc_add_container, _1, argv[pos + 1])); + one_shot(bind(vsm_create_domain, _1, argv[pos + 1])); } } // namespace cli diff --git a/cli/command-line-interface.hpp b/cli/command-line-interface.hpp index d9fc39f..27415c1 100644 --- a/cli/command-line-interface.hpp +++ b/cli/command-line-interface.hpp @@ -62,9 +62,9 @@ public: * @param argsSpec Description of arguments */ CommandLineInterface(const ExecutorCallback& executorCallback, - const std::string& usage, - const std::string& usageInfo, - const ArgsSpec& argsSpec) + const std::string& usage, + const std::string& usageInfo, + const ArgsSpec& argsSpec) : mExecutorCallback(executorCallback), mUsage(usage), mUsageInfo(usageInfo), @@ -97,18 +97,18 @@ private: }; /** - * Parses command line arguments and call sc_set_active_container + * Parses command line arguments and call vsm_set_active_container * - * @see sc_set_active_container + * @see vsm_set_active_container */ void set_active_container(int pos, int argc, const char** argv); /** - * Parses command line arguments and call sc_add_container + * Parses command line arguments and call vsm_create_domain * - * @see sc_add_container + * @see vsm_create_domain */ -void add_container(int pos, int argc, const char** argv); +void create_domain(int pos, int argc, const char** argv); } // namespace cli } // namespace security_containers diff --git a/cli/main.cpp b/cli/main.cpp index d84d5ac..135385d 100644 --- a/cli/main.cpp +++ b/cli/main.cpp @@ -33,17 +33,21 @@ using namespace security_containers::cli; std::map commands = { - {"set_active_container", { - set_active_container, - "set_active_container container_id", - "Set active (foreground) container", - {{"container_id", "id container name"}}} + { + "set_active_container", { + set_active_container, + "set_active_container container_id", + "Set active (foreground) container", + {{"container_id", "id container name"}} + } }, - {"add_container", { - add_container, - "add_container container_id", - "Create and add container", - {{"container_id", "id container name"}}} + { + "create_domain", { + create_domain, + "create_domain container_id", + "Create and add container", + {{"container_id", "id container name"}} + } } }; @@ -70,7 +74,7 @@ int main(const int argc, const char** argv) CommandLineInterface& command = commands[argv[1]]; try { - command.execute(1, argc, argv); + command.execute(1, argc, argv); } catch (const std::runtime_error& ex) { std::cerr << ex.what() << std::endl; return EXIT_FAILURE; diff --git a/client/security-containers-client-impl.cpp b/client/security-containers-client-impl.cpp index 95418b9..39abbfd 100644 --- a/client/security-containers-client-impl.cpp +++ b/client/security-containers-client-impl.cpp @@ -52,7 +52,7 @@ const DbusInterfaceInfo CONTAINER_INTERFACE(api::container::BUS_NAME, unique_ptr gGlibLoop; -void toDict(GVariant* in, ScArrayString* keys, ScArrayString* values) +void toDict(GVariant* in, VsmArrayString* keys, VsmArrayString* values) { assert(in); assert(keys); @@ -108,20 +108,20 @@ void toArray(GVariant* in, T** scArray) *scArray = ids; } -ScStatus toStatus(const std::exception& ex) +VsmStatus toStatus(const std::exception& ex) { if (typeid(DbusCustomException) == typeid(ex)) { - return SCCLIENT_CUSTOM_ERROR; + return VSMCLIENT_CUSTOM_ERROR; } else if (typeid(DbusIOException) == typeid(ex)) { - return SCCLIENT_IO_ERROR; + return VSMCLIENT_IO_ERROR; } else if (typeid(DbusOperationException) == typeid(ex)) { - return SCCLIENT_OPERATION_FAILED; + return VSMCLIENT_OPERATION_FAILED; } else if (typeid(DbusInvalidArgumentException) == typeid(ex)) { - return SCCLIENT_INVALID_ARGUMENT; + return VSMCLIENT_INVALID_ARGUMENT; } else if (typeid(DbusException) == typeid(ex)) { - return SCCLIENT_OTHER_ERROR; + return VSMCLIENT_OTHER_ERROR; } - return SCCLIENT_OTHER_ERROR; + return VSMCLIENT_OTHER_ERROR; } bool readFirstLineOfFile(const std::string& path, std::string& ret) @@ -137,36 +137,36 @@ bool readFirstLineOfFile(const std::string& path, std::string& ret) } //namespace -ScStatus Client::sc_start_glib_loop() noexcept +VsmStatus Client::vsm_start_glib_loop() noexcept { try { if (!gGlibLoop) { gGlibLoop.reset(new ScopedGlibLoop()); } } catch (const exception&) { - return SCCLIENT_OTHER_ERROR; + return VSMCLIENT_OTHER_ERROR; } - return SCCLIENT_SUCCESS; + return VSMCLIENT_SUCCESS; } -ScStatus Client::sc_stop_glib_loop() noexcept +VsmStatus Client::vsm_stop_glib_loop() noexcept { try { gGlibLoop.reset(); } catch (const exception&) { - return SCCLIENT_OTHER_ERROR; + return VSMCLIENT_OTHER_ERROR; } - return SCCLIENT_SUCCESS; + return VSMCLIENT_SUCCESS; } Client::Status::Status() - : mScStatus(SCCLIENT_SUCCESS), mMsg() + : mVsmStatus(VSMCLIENT_SUCCESS), mMsg() { } -Client::Status::Status(ScStatus status, const std::string& msg) - : mScStatus(status), mMsg(msg) +Client::Status::Status(VsmStatus status, const std::string& msg) + : mVsmStatus(status), mMsg(msg) { } @@ -178,33 +178,33 @@ Client::~Client() noexcept { } -ScStatus Client::createSystem() noexcept +VsmStatus Client::createSystem() noexcept { try { mConnection = DbusConnection::createSystem(); mStatus = Status(); - } catch (const exception& ex) { + } catch (const exception& ex) { mStatus = Status(toStatus(ex), ex.what()); } - return sc_get_status(); + return vsm_get_status(); } -ScStatus Client::create(const string& address) noexcept +VsmStatus Client::create(const string& address) noexcept { try { mConnection = DbusConnection::create(address); mStatus = Status(); - } catch (const exception& ex) { + } catch (const exception& ex) { mStatus = Status(toStatus(ex), ex.what()); } - return sc_get_status(); + return vsm_get_status(); } -ScStatus Client::callMethod(const DbusInterfaceInfo& info, - const string& method, - GVariant* args_in, - const string& args_spec_out, - GVariant** args_out) +VsmStatus Client::callMethod(const DbusInterfaceInfo& info, + const string& method, + GVariant* args_in, + const string& args_spec_out, + GVariant** args_out) { try { GVariantPtr ret = mConnection->callMethod(info.busName, @@ -220,12 +220,12 @@ ScStatus Client::callMethod(const DbusInterfaceInfo& info, } catch (const exception& ex) { mStatus = Status(toStatus(ex), ex.what()); } - return sc_get_status(); + return vsm_get_status(); } -ScStatus Client::signalSubscribe(const DbusInterfaceInfo& info, - const string& name, - SignalCallback signalCallback) +VsmStatus Client::signalSubscribe(const DbusInterfaceInfo& info, + const string& name, + SignalCallback signalCallback) { auto onSignal = [=](const std::string& /*senderBusName*/, const std::string & objectPath, @@ -233,8 +233,8 @@ ScStatus Client::signalSubscribe(const DbusInterfaceInfo& info, const std::string & signalName, GVariant * parameters) { if (objectPath == info.objectPath && - interface == info.interface && - signalName == name) { + interface == info.interface && + signalName == name) { signalCallback(parameters); } @@ -245,31 +245,31 @@ ScStatus Client::signalSubscribe(const DbusInterfaceInfo& info, } catch (const std::exception& ex) { mStatus = Status(toStatus(ex), ex.what()); } - return sc_get_status(); + return vsm_get_status(); } -const char* Client::sc_get_status_message() noexcept +const char* Client::vsm_get_status_message() noexcept { return mStatus.mMsg.c_str(); } -ScStatus Client::sc_get_status() noexcept +VsmStatus Client::vsm_get_status() noexcept { - return mStatus.mScStatus; + return mStatus.mVsmStatus; } -ScStatus Client::sc_get_container_dbuses(ScArrayString* keys, ScArrayString* values) noexcept +VsmStatus Client::vsm_get_container_dbuses(VsmArrayString* keys, VsmArrayString* values) noexcept { assert(keys); assert(values); GVariant* out; - ScStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_CONTAINER_DBUSES, - NULL, - "(a{ss})", - &out); - if (ret != SCCLIENT_SUCCESS) { + VsmStatus ret = callMethod(HOST_INTERFACE, + api::host::METHOD_GET_CONTAINER_DBUSES, + NULL, + "(a{ss})", + &out); + if (ret != VSMCLIENT_SUCCESS) { return ret; } GVariant* unpacked; @@ -280,17 +280,17 @@ ScStatus Client::sc_get_container_dbuses(ScArrayString* keys, ScArrayString* val return ret; } -ScStatus Client::sc_get_container_ids(ScArrayString* array) noexcept +VsmStatus Client::vsm_get_domain_ids(VsmArrayString* array) noexcept { assert(array); GVariant* out; - ScStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_CONTAINER_ID_LIST, - NULL, - "(as)", - &out); - if (ret != SCCLIENT_SUCCESS) { + VsmStatus ret = callMethod(HOST_INTERFACE, + api::host::METHOD_GET_CONTAINER_ID_LIST, + NULL, + "(as)", + &out); + if (ret != VSMCLIENT_SUCCESS) { return ret; } GVariant* unpacked; @@ -301,17 +301,17 @@ ScStatus Client::sc_get_container_ids(ScArrayString* array) noexcept return ret; } -ScStatus Client::sc_get_active_container_id(ScString* id) noexcept +VsmStatus Client::vsm_get_active_container_id(VsmString* id) noexcept { assert(id); GVariant* out; - ScStatus ret = callMethod(HOST_INTERFACE, - api::host::METHOD_GET_ACTIVE_CONTAINER_ID, - NULL, - "(s)", - &out); - if (ret != SCCLIENT_SUCCESS) { + VsmStatus ret = callMethod(HOST_INTERFACE, + api::host::METHOD_GET_ACTIVE_CONTAINER_ID, + NULL, + "(s)", + &out); + if (ret != VSMCLIENT_SUCCESS) { return ret; } GVariant* unpacked; @@ -322,7 +322,7 @@ ScStatus Client::sc_get_active_container_id(ScString* id) noexcept return ret; } -ScStatus Client::sc_get_container_id_by_pid(int pid, ScString* id) noexcept +VsmStatus Client::vsm_lookup_domain_by_pid(int pid, VsmString* id) noexcept { assert(id); @@ -330,22 +330,22 @@ ScStatus Client::sc_get_container_id_by_pid(int pid, ScString* id) noexcept std::string cpuset; if (!readFirstLineOfFile(path, cpuset)) { - mStatus = Status(SCCLIENT_INVALID_ARGUMENT, "Process not found"); - return sc_get_status(); + mStatus = Status(VSMCLIENT_INVALID_ARGUMENT, "Process not found"); + return vsm_get_status(); } std::string containerId; if (!parseContainerIdFromCpuSet(cpuset, containerId)) { - mStatus = Status(SCCLIENT_OTHER_ERROR, "unknown format of cpuset"); - return sc_get_status(); + mStatus = Status(VSMCLIENT_OTHER_ERROR, "unknown format of cpuset"); + return vsm_get_status(); } *id = strdup(containerId.c_str()); mStatus = Status(); - return sc_get_status();; + return vsm_get_status();; } -ScStatus Client::sc_set_active_container(const char* id) noexcept +VsmStatus Client::vsm_set_active_container(const char* id) noexcept { assert(id); @@ -353,7 +353,7 @@ ScStatus Client::sc_set_active_container(const char* id) noexcept return callMethod(HOST_INTERFACE, api::host::METHOD_SET_ACTIVE_CONTAINER, args_in); } -ScStatus Client::sc_add_container(const char* id) noexcept +VsmStatus Client::vsm_create_domain(const char* id) noexcept { assert(id); @@ -361,12 +361,13 @@ ScStatus Client::sc_add_container(const char* id) noexcept return callMethod(HOST_INTERFACE, api::host::METHOD_ADD_CONTAINER, args_in); } -ScStatus Client::sc_container_dbus_state(ScContainerDbusStateCallback containerDbusStateCallback, +VsmStatus Client::vsm_add_state_callback(VsmContainerDbusStateCallback containerDbusStateCallback, void* data) noexcept { assert(containerDbusStateCallback); - auto onSigal = [=](GVariant * parameters) { + auto onSigal = [=](GVariant * parameters) + { const char* container; const char* dbusAddress; g_variant_get(parameters, "(&s&s)", &container, &dbusAddress); @@ -378,7 +379,7 @@ ScStatus Client::sc_container_dbus_state(ScContainerDbusStateCallback containerD onSigal); } -ScStatus Client::sc_notify_active_container(const char* application, const char* message) noexcept +VsmStatus Client::vsm_notify_active_container(const char* application, const char* message) noexcept { assert(application); assert(message); @@ -389,34 +390,34 @@ ScStatus Client::sc_notify_active_container(const char* application, const char* args_in); } -ScStatus Client::sc_file_move_request(const char* destContainer, const char* path) noexcept +VsmStatus Client::vsm_file_move_request(const char* destContainer, const char* path) noexcept { assert(destContainer); assert(path); GVariant* out; GVariant* args_in = g_variant_new("(ss)", destContainer, path); - ScStatus ret = callMethod(CONTAINER_INTERFACE, - api::container::METHOD_FILE_MOVE_REQUEST, - args_in, - "(s)", - &out); + VsmStatus ret = callMethod(CONTAINER_INTERFACE, + api::container::METHOD_FILE_MOVE_REQUEST, + args_in, + "(s)", + &out); - if (ret != SCCLIENT_SUCCESS) { + if (ret != VSMCLIENT_SUCCESS) { return ret; } const gchar* retcode = NULL;; g_variant_get(out, "(&s)", &retcode); if (strcmp(retcode, api::container::FILE_MOVE_SUCCEEDED.c_str()) != 0) { - mStatus = Status(SCCLIENT_CUSTOM_ERROR, retcode); + mStatus = Status(VSMCLIENT_CUSTOM_ERROR, retcode); g_variant_unref(out); - return sc_get_status(); + return vsm_get_status(); } g_variant_unref(out); return ret; } -ScStatus Client::sc_notification(ScNotificationCallback notificationCallback, void* data) noexcept +VsmStatus Client::vsm_notification(VsmNotificationCallback notificationCallback, void* data) noexcept { assert(notificationCallback); diff --git a/client/security-containers-client-impl.hpp b/client/security-containers-client-impl.hpp index 3f5a556..9a233e5 100644 --- a/client/security-containers-client-impl.hpp +++ b/client/security-containers-client-impl.hpp @@ -55,22 +55,22 @@ private: typedef std::function SignalCallback; struct Status { Status(); - Status(ScStatus status, const std::string& msg); - ScStatus mScStatus; + Status(VsmStatus status, const std::string& msg); + VsmStatus mVsmStatus; std::string mMsg; }; dbus::DbusConnection::Pointer mConnection; Status mStatus; - ScStatus callMethod(const DbusInterfaceInfo& info, - const std::string& method, - GVariant* args_in, - const std::string& args_spec_out = std::string(), - GVariant** args_out = NULL); - ScStatus signalSubscribe(const DbusInterfaceInfo& info, - const std::string& name, - SignalCallback signalCallback); + VsmStatus callMethod(const DbusInterfaceInfo& info, + const std::string& method, + GVariant* args_in, + const std::string& args_spec_out = std::string(), + GVariant** args_out = NULL); + VsmStatus signalSubscribe(const DbusInterfaceInfo& info, + const std::string& name, + SignalCallback signalCallback); public: Client() noexcept; @@ -81,7 +81,7 @@ public: * * @return status of this function call */ - ScStatus createSystem() noexcept; + VsmStatus createSystem() noexcept; /** * Create client. @@ -89,76 +89,76 @@ public: * @param address Dbus socket address * @return status of this function call */ - ScStatus create(const std::string& address) noexcept; + VsmStatus create(const std::string& address) noexcept; /** - * @see ::sc_get_status_message + * @see ::vsm_get_status_message */ - const char* sc_get_status_message() noexcept; + const char* vsm_get_status_message() noexcept; /** - * @see ::sc_get_status + * @see ::vsm_get_status */ - ScStatus sc_get_status() noexcept; + VsmStatus vsm_get_status() noexcept; /** - * @see ::sc_get_container_dbuses + * @see ::vsm_get_container_dbuses */ - ScStatus sc_get_container_dbuses(ScArrayString* keys, ScArrayString* values) noexcept; + VsmStatus vsm_get_container_dbuses(VsmArrayString* keys, VsmArrayString* values) noexcept; /** - * @see ::sc_get_container_ids + * @see ::vsm_get_domain_ids */ - ScStatus sc_get_container_ids(ScArrayString* array) noexcept; + VsmStatus vsm_get_domain_ids(VsmArrayString* array) noexcept; /** - * @see ::sc_get_active_container_id + * @see ::vsm_get_active_container_id */ - ScStatus sc_get_active_container_id(ScString* id) noexcept; + VsmStatus vsm_get_active_container_id(VsmString* id) noexcept; /** - * @see ::sc_get_container_id_by_pid + * @see ::vsm_lookup_domain_by_pid */ - ScStatus sc_get_container_id_by_pid(int pid, ScString* id) noexcept; + VsmStatus vsm_lookup_domain_by_pid(int pid, VsmString* id) noexcept; /** - * @see ::sc_set_active_container + * @see ::vsm_set_active_container */ - ScStatus sc_set_active_container(const char* id) noexcept; + VsmStatus vsm_set_active_container(const char* id) noexcept; /** - * @see ::sc_add_container + * @see ::vsm_create_domain */ - ScStatus sc_add_container(const char* id) noexcept; + VsmStatus vsm_create_domain(const char* id) noexcept; /** - * @see ::sc_container_dbus_state + * @see ::vsm_add_state_callback */ - ScStatus sc_container_dbus_state(ScContainerDbusStateCallback containerDbusStateCallback, + VsmStatus vsm_add_state_callback(VsmContainerDbusStateCallback containerDbusStateCallback, void* data) noexcept; /** - * @see ::sc_notify_active_container + * @see ::vsm_notify_active_container */ - ScStatus sc_notify_active_container(const char* application, const char* message) noexcept; + VsmStatus vsm_notify_active_container(const char* application, const char* message) noexcept; /** - * @see ::sc_file_move_request + * @see ::vsm_file_move_request */ - ScStatus sc_file_move_request(const char* destContainer, const char* path) noexcept; + VsmStatus vsm_file_move_request(const char* destContainer, const char* path) noexcept; /** - * @see ::sc_notification + * @see ::vsm_notification */ - ScStatus sc_notification(ScNotificationCallback notificationCallback, void* data) noexcept; + VsmStatus vsm_notification(VsmNotificationCallback notificationCallback, void* data) noexcept; /** - * @see ::sc_start_glib_loop + * @see ::vsm_start_glib_loop */ - static ScStatus sc_start_glib_loop() noexcept; + static VsmStatus vsm_start_glib_loop() noexcept; /** - * @see ::sc_stop_glib_loop + * @see ::vsm_stop_glib_loop */ - static ScStatus sc_stop_glib_loop() noexcept; + static VsmStatus vsm_stop_glib_loop() noexcept; }; #endif /* SECURITY_CONTAINERS_CLIENT_IMPL_HPP */ diff --git a/client/security-containers-client.cpp b/client/security-containers-client.cpp index 95c2758..ad8fb38 100644 --- a/client/security-containers-client.cpp +++ b/client/security-containers-client.cpp @@ -37,7 +37,7 @@ using namespace std; namespace { -Client& getClient(ScClient client) +Client& getClient(VsmClient client) { assert(client); return *reinterpret_cast(client); @@ -46,118 +46,118 @@ Client& getClient(ScClient client) } // namespace /* external */ -API ScStatus sc_start_glib_loop() +API VsmStatus vsm_start_glib_loop() { - return Client::sc_start_glib_loop(); + return Client::vsm_start_glib_loop(); } -API ScStatus sc_stop_glib_loop() +API VsmStatus vsm_stop_glib_loop() { - return Client::sc_stop_glib_loop(); + return Client::vsm_stop_glib_loop(); } -API ScClient sc_client_create() +API VsmClient vsm_client_create() { Client* clientPtr = new(nothrow) Client(); - return reinterpret_cast(clientPtr); + return reinterpret_cast(clientPtr); } -API ScStatus sc_connect(ScClient client) +API VsmStatus vsm_connect(VsmClient client) { return getClient(client).createSystem(); } -API ScStatus sc_connect_custom(ScClient client, const char* address) +API VsmStatus vsm_connect_custom(VsmClient client, const char* address) { return getClient(client).create(address); } -API void sc_array_string_free(ScArrayString astring) +API void vsm_array_string_free(VsmArrayString astring) { if (!astring) { return; } for (char** ptr = astring; *ptr; ++ptr) { - sc_string_free(*ptr); + vsm_string_free(*ptr); } free(astring); } -API void sc_string_free(ScString string) +API void vsm_string_free(VsmString string) { free(string); } -API void sc_client_free(ScClient client) +API void vsm_client_free(VsmClient client) { if (client != NULL) { delete &getClient(client); } } -API const char* sc_get_status_message(ScClient client) +API const char* vsm_get_status_message(VsmClient client) { - return getClient(client).sc_get_status_message(); + return getClient(client).vsm_get_status_message(); } -API ScStatus sc_get_status(ScClient client) +API VsmStatus vsm_get_status(VsmClient client) { - return getClient(client).sc_get_status(); + return getClient(client).vsm_get_status(); } -API ScStatus sc_get_container_dbuses(ScClient client, ScArrayString* keys, ScArrayString* values) +API VsmStatus vsm_get_container_dbuses(VsmClient client, VsmArrayString* keys, VsmArrayString* values) { - return getClient(client).sc_get_container_dbuses(keys, values); + return getClient(client).vsm_get_container_dbuses(keys, values); } -API ScStatus sc_get_container_ids(ScClient client, ScArrayString* array) +API VsmStatus vsm_get_domain_ids(VsmClient client, VsmArrayString* array) { - return getClient(client).sc_get_container_ids(array); + return getClient(client).vsm_get_domain_ids(array); } -API ScStatus sc_get_active_container_id(ScClient client, ScString* id) +API VsmStatus vsm_get_active_container_id(VsmClient client, VsmString* id) { - return getClient(client).sc_get_active_container_id(id); + return getClient(client).vsm_get_active_container_id(id); } -API ScStatus sc_get_container_id_by_pid(ScClient client, int pid, ScString* id) +API VsmStatus vsm_lookup_domain_by_pid(VsmClient client, int pid, VsmString* id) { - return getClient(client).sc_get_container_id_by_pid(pid, id); + return getClient(client).vsm_lookup_domain_by_pid(pid, id); } -API ScStatus sc_set_active_container(ScClient client, const char* id) +API VsmStatus vsm_set_active_container(VsmClient client, const char* id) { - return getClient(client).sc_set_active_container(id); + return getClient(client).vsm_set_active_container(id); } -API ScStatus sc_add_container(ScClient client, const char* id) +API VsmStatus vsm_create_domain(VsmClient client, const char* id) { - return getClient(client).sc_add_container(id); + return getClient(client).vsm_create_domain(id); } -API ScStatus sc_container_dbus_state(ScClient client, - ScContainerDbusStateCallback containerDbusStateCallback, +API VsmStatus vsm_add_state_callback(VsmClient client, + VsmContainerDbusStateCallback containerDbusStateCallback, void* data) { - return getClient(client).sc_container_dbus_state(containerDbusStateCallback, data); + return getClient(client).vsm_add_state_callback(containerDbusStateCallback, data); } -API ScStatus sc_notify_active_container(ScClient client, - const char* application, - const char* message) +API VsmStatus vsm_notify_active_container(VsmClient client, + const char* application, + const char* message) { - return getClient(client).sc_notify_active_container(application, message); + return getClient(client).vsm_notify_active_container(application, message); } -API ScStatus sc_file_move_request(ScClient client, const char* destContainer, const char* path) +API VsmStatus vsm_file_move_request(VsmClient client, const char* destContainer, const char* path) { - return getClient(client).sc_file_move_request(destContainer, path); + return getClient(client).vsm_file_move_request(destContainer, path); } -API ScStatus sc_notification(ScClient client, - ScNotificationCallback notificationCallback, - void* data) +API VsmStatus vsm_notification(VsmClient client, + VsmNotificationCallback notificationCallback, + void* data) { - return getClient(client).sc_notification(notificationCallback, data); + return getClient(client).vsm_notification(notificationCallback, data); } diff --git a/client/security-containers-client.h b/client/security-containers-client.h index 1307cb5..710af99 100644 --- a/client/security-containers-client.h +++ b/client/security-containers-client.h @@ -29,47 +29,47 @@ int main(int argc, char** argv) { - ScStatus status; - ScClient client; - ScArrayString values = NULL; + VsmStatus status; + VsmClient client; + VsmArrayString values = NULL; int ret = 0; - status = sc_start_glib_loop(); // start glib loop (if not started any yet) - if (SCCLIENT_SUCCESS != status) { + status = vsm_start_glib_loop(); // start glib loop (if not started any yet) + if (VSMCLIENT_SUCCESS != status) { // error! return 1; } - client = sc_client_create(); // create client handle + client = vsm_client_create(); // create client handle if (NULL == client) { // error! ret = 1; goto finish; } - status = sc_connect(client); // connect to dbus - if (SCCLIENT_SUCCESS != status) { + status = vsm_connect(client); // connect to dbus + if (VSMCLIENT_SUCCESS != status) { // error! ret = 1; goto finish; } - status = sc_get_container_ids(client, &values); - if (SCCLIENT_SUCCESS != status) { + status = vsm_get_domain_ids(client, &values); + if (VSMCLIENT_SUCCESS != status) { // error! ret = 1; goto finish; } // print array - for (ScArrayString iValues = values; *iValues; iValues++) { + for (VsmArrayString iValues = values; *iValues; iValues++) { printf("%s\n", *iValues); } finish: - sc_array_string_free(values); // free memory - sc_client_free(client); // destroy client handle - sc_stop_glib_loop(); // stop the glib loop (use only with sc_start_glib_loop) + vsm_array_string_free(values); // free memory + vsm_client_free(client); // destroy client handle + vsm_stop_glib_loop(); // stop the glib loop (use only with vsm_start_glib_loop) return ret; } @endcode @@ -86,33 +86,33 @@ extern "C" /** * security-containers-server's client pointer. */ -typedef void* ScClient; +typedef void* VsmClient; /** * NULL-terminated string type. * - * @sa sc_array_string_free + * @sa vsm_array_string_free */ -typedef char* ScString; +typedef char* VsmString; /** * NULL-terminated array of strings type. * - * @sa sc_string_free + * @sa vsm_string_free */ -typedef ScString* ScArrayString; +typedef VsmString* VsmArrayString; /** * Completion status of communication function. */ typedef enum { - SCCLIENT_CUSTOM_ERROR, ///< User specified error - SCCLIENT_IO_ERROR, ///< Input/Output error - SCCLIENT_OPERATION_FAILED, ///< Operation failed - SCCLIENT_INVALID_ARGUMENT, ///< Invalid argument - SCCLIENT_OTHER_ERROR, ///< Other error - SCCLIENT_SUCCESS ///< Success -} ScStatus; + VSMCLIENT_CUSTOM_ERROR, ///< User specified error + VSMCLIENT_IO_ERROR, ///< Input/Output error + VSMCLIENT_OPERATION_FAILED, ///< Operation failed + VSMCLIENT_INVALID_ARGUMENT, ///< Invalid argument + VSMCLIENT_OTHER_ERROR, ///< Other error + VSMCLIENT_SUCCESS ///< Success +} VsmStatus; /** * Start glib loop. @@ -122,30 +122,30 @@ typedef enum { * * @return status of this function call */ -ScStatus sc_start_glib_loop(); +VsmStatus vsm_start_glib_loop(); /** * Stop glib loop. * - * Call only if sc_start_glib_loop() was called. + * Call only if vsm_start_glib_loop() was called. * * @return status of this function call */ -ScStatus sc_stop_glib_loop(); +VsmStatus vsm_stop_glib_loop(); /** * Create a new security-containers-server's client. * * @return Created client pointer or NULL on failure. */ -ScClient sc_client_create(); +VsmClient vsm_client_create(); /** * Release client resources. * * @param[in] client security-containers-server's client */ -void sc_client_free(ScClient client); +void vsm_client_free(VsmClient client); /** * Get status code of last security-containers-server communication. @@ -153,7 +153,7 @@ void sc_client_free(ScClient client); * @param[in] client security-containers-server's client * @return status of this function call */ -ScStatus sc_get_status(ScClient client); +VsmStatus vsm_get_status(VsmClient client); /** * Get status message of the last security-containers-server communication. @@ -161,7 +161,7 @@ ScStatus sc_get_status(ScClient client); * @param[in] client security-containers-server's client * @return last status message from security-containers-server communication */ -const char* sc_get_status_message(ScClient client); +const char* vsm_get_status_message(VsmClient client); /** * Connect client to the security-containers-server. @@ -169,7 +169,7 @@ const char* sc_get_status_message(ScClient client); * @param[in] client security-containers-server's client * @return status of this function call */ -ScStatus sc_connect(ScClient client); +VsmStatus vsm_connect(VsmClient client); /** * Connect client to the security-containers-server via custom address. @@ -178,21 +178,21 @@ ScStatus sc_connect(ScClient client); * @param[in] address dbus address * @return status of this function call */ -ScStatus sc_connect_custom(ScClient client, const char* address); +VsmStatus vsm_connect_custom(VsmClient client, const char* address); /** - * Release ScArrayString. + * Release VsmArrayString. * - * @param[in] astring ScArrayString + * @param[in] astring VsmArrayString */ -void sc_array_string_free(ScArrayString astring); +void vsm_array_string_free(VsmArrayString astring); /** - * Release ScString. + * Release VsmString. * - * @param string ScString + * @param string VsmString */ -void sc_string_free(ScString string); +void vsm_string_free(VsmString string); /** @@ -208,9 +208,9 @@ void sc_string_free(ScString string); * * @param[in] containerId affected container id * @param[in] dbusAddress new D-Bus address - * @param data custom user's data pointer passed to sc_container_dbus_state() function + * @param data custom user's data pointer passed to vsm_add_state_callback() function */ -typedef void (*ScContainerDbusStateCallback)(const char* containerId, +typedef void (*VsmContainerDbusStateCallback)(const char* containerId, const char* dbusAddress, void* data); @@ -222,9 +222,9 @@ typedef void (*ScContainerDbusStateCallback)(const char* containerId, * @param[out] values array of containers dbus address * @return status of this function call * @post keys[i] corresponds to values[i] - * @remark Use sc_array_string_free() to free memory occupied by @p keys and @p values. + * @remark Use vsm_array_string_free() to free memory occupied by @p keys and @p values. */ -ScStatus sc_get_container_dbuses(ScClient client, ScArrayString* keys, ScArrayString* values); +VsmStatus vsm_get_container_dbuses(VsmClient client, VsmArrayString* keys, VsmArrayString* values); /** * Get containers name. @@ -232,9 +232,9 @@ ScStatus sc_get_container_dbuses(ScClient client, ScArrayString* keys, ScArraySt * @param[in] client security-containers-server's client * @param[out] array array of containers name * @return status of this function call - * @remark Use sc_array_string_free() to free memory occupied by @p array. + * @remark Use vsm_array_string_free() to free memory occupied by @p array. */ -ScStatus sc_get_container_ids(ScClient client, ScArrayString* array); +VsmStatus vsm_get_domain_ids(VsmClient client, VsmArrayString* array); /** * Get active (foreground) container name. @@ -242,9 +242,9 @@ ScStatus sc_get_container_ids(ScClient client, ScArrayString* array); * @param[in] client security-containers-server's client * @param[out] id active container name * @return status of this function call - * @remark Use @p sc_string_free() to free memory occupied by @p id. + * @remark Use @p vsm_string_free() to free memory occupied by @p id. */ -ScStatus sc_get_active_container_id(ScClient client, ScString* id); +VsmStatus vsm_get_active_container_id(VsmClient client, VsmString* id); /** * Get container name of process with given pid. @@ -253,9 +253,9 @@ ScStatus sc_get_active_container_id(ScClient client, ScString* id); * @param[in] pid process id * @param[out] id active container name * @return status of this function call - * @remark Use @p sc_string_free() to free memory occupied by @p id. + * @remark Use @p vsm_string_free() to free memory occupied by @p id. */ -ScStatus sc_get_container_id_by_pid(ScClient client, int pid, ScString* id); +VsmStatus vsm_lookup_domain_by_pid(VsmClient client, int pid, VsmString* id); /** * Set active (foreground) container. @@ -264,7 +264,7 @@ ScStatus sc_get_container_id_by_pid(ScClient client, int pid, ScString* id); * @param[in] id container name * @return status of this function call */ -ScStatus sc_set_active_container(ScClient client, const char* id); +VsmStatus vsm_set_active_container(VsmClient client, const char* id); /** * Create and add container @@ -273,7 +273,7 @@ ScStatus sc_set_active_container(ScClient client, const char* id); * @param[in] id container id * @return status of this function call */ -ScStatus sc_add_container(ScClient client, const char* id); +VsmStatus vsm_create_domain(VsmClient client, const char* id); /** * Register dbus state change callback function. @@ -285,8 +285,8 @@ ScStatus sc_add_container(ScClient client, const char* id); * @param[in] data some extra data that will be passed to callback function * @return status of this function call */ -ScStatus sc_container_dbus_state(ScClient client, - ScContainerDbusStateCallback containerDbusStateCallback, +VsmStatus vsm_add_state_callback(VsmClient client, + VsmContainerDbusStateCallback containerDbusStateCallback, void* data); /** @} */ // Host API @@ -306,9 +306,9 @@ ScStatus sc_container_dbus_state(ScClient client, * @param[in] container source container * @param[in] application sending application name * @param[in] message notification message - * @param data custom user's data pointer passed to sc_notification() + * @param data custom user's data pointer passed to vsm_notification() */ -typedef void (*ScNotificationCallback)(const char* container, +typedef void (*VsmNotificationCallback)(const char* container, const char* application, const char* message, void* data); @@ -320,7 +320,7 @@ typedef void (*ScNotificationCallback)(const char* container, * @param[in] message message * @return status of this function call */ -ScStatus sc_notify_active_container(ScClient client, const char* application, const char* message); +VsmStatus vsm_notify_active_container(VsmClient client, const char* application, const char* message); /** * Move file between containers. @@ -330,7 +330,7 @@ ScStatus sc_notify_active_container(ScClient client, const char* application, co * @param[in] path path to moved file * @return status of this function call */ -ScStatus sc_file_move_request(ScClient client, const char* destContainer, const char* path); +VsmStatus vsm_file_move_request(VsmClient client, const char* destContainer, const char* path); /** * Register notification callback function. @@ -342,7 +342,7 @@ ScStatus sc_file_move_request(ScClient client, const char* destContainer, const * @param[in] data some extra data that will be passed to callback function * @return status of this function call */ -ScStatus sc_notification(ScClient client, ScNotificationCallback notificationCallback, void* data); +VsmStatus vsm_notification(VsmClient client, VsmNotificationCallback notificationCallback, void* data); /** @} */ // Domain API diff --git a/tests/unit_tests/client/ut-client.cpp b/tests/unit_tests/client/ut-client.cpp index 5db6962..184659e 100644 --- a/tests/unit_tests/client/ut-client.cpp +++ b/tests/unit_tests/client/ut-client.cpp @@ -48,8 +48,14 @@ const std::string TEST_DBUS_CONFIG_PATH = SC_TEST_CONFIG_INSTALL_DIR "/client/ut-client/test-dbus-daemon.conf"; struct Loop { - Loop() { sc_start_glib_loop(); } - ~Loop() { sc_stop_glib_loop(); } + Loop() + { + vsm_start_glib_loop(); + } + ~Loop() + { + vsm_stop_glib_loop(); + } }; struct Fixture { @@ -64,32 +70,39 @@ struct Fixture { const int EVENT_TIMEOUT = 5000; ///< ms const std::map EXPECTED_DBUSES_STARTED = { - {"ut-containers-manager-console1-dbus", - "unix:path=/tmp/ut-containers-manager/console1-dbus/dbus/system_bus_socket"}, - {"ut-containers-manager-console2-dbus", - "unix:path=/tmp/ut-containers-manager/console2-dbus/dbus/system_bus_socket"}, - {"ut-containers-manager-console3-dbus", - "unix:path=/tmp/ut-containers-manager/console3-dbus/dbus/system_bus_socket"}}; - -void convertDictToMap(ScArrayString keys, - ScArrayString values, + { + "ut-containers-manager-console1-dbus", + "unix:path=/tmp/ut-containers-manager/console1-dbus/dbus/system_bus_socket" + }, + { + "ut-containers-manager-console2-dbus", + "unix:path=/tmp/ut-containers-manager/console2-dbus/dbus/system_bus_socket" + }, + { + "ut-containers-manager-console3-dbus", + "unix:path=/tmp/ut-containers-manager/console3-dbus/dbus/system_bus_socket" + } +}; + +void convertDictToMap(VsmArrayString keys, + VsmArrayString values, std::map& ret) { - ScArrayString iKeys; - ScArrayString iValues; + VsmArrayString iKeys; + VsmArrayString iValues; for (iKeys = keys, iValues = values; *iKeys && *iValues; iKeys++, iValues++) { ret.insert(std::make_pair(*iKeys, *iValues)); } } -void convertArrayToSet(ScArrayString values, std::set& ret) +void convertArrayToSet(VsmArrayString values, std::set& ret) { - for (ScArrayString iValues = values; *iValues; iValues++) { + for (VsmArrayString iValues = values; *iValues; iValues++) { ret.insert(*iValues); } } -int getArrayStringLength(ScArrayString astring, int max_len = -1) +int getArrayStringLength(VsmArrayString astring, int max_len = -1) { int i = 0; for (i = 0; astring[i]; i++) { @@ -108,21 +121,21 @@ BOOST_AUTO_TEST_CASE(NotRunningServerTest) { cm.stopAll(); - ScClient client = sc_client_create(); - ScStatus status = sc_connect_custom(client, - EXPECTED_DBUSES_STARTED.begin()->second.c_str()); - BOOST_CHECK_EQUAL(SCCLIENT_IO_ERROR, status); - sc_client_free(client); + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect_custom(client, + EXPECTED_DBUSES_STARTED.begin()->second.c_str()); + BOOST_CHECK_EQUAL(VSMCLIENT_IO_ERROR, status); + vsm_client_free(client); } BOOST_AUTO_TEST_CASE(GetContainerDbusesTest) { - ScClient client = sc_client_create(); - ScStatus status = sc_connect(client); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); - ScArrayString keys, values; - status = sc_get_container_dbuses(client, &keys, &values); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect(client); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + VsmArrayString keys, values; + status = vsm_get_container_dbuses(client, &keys, &values); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); BOOST_CHECK_EQUAL(getArrayStringLength(keys, EXPECTED_DBUSES_STARTED.size() + 1), EXPECTED_DBUSES_STARTED.size()); @@ -132,19 +145,19 @@ BOOST_AUTO_TEST_CASE(GetContainerDbusesTest) std::map containers; convertDictToMap(keys, values, containers); BOOST_CHECK(containers == EXPECTED_DBUSES_STARTED); - sc_array_string_free(keys); - sc_array_string_free(values); - sc_client_free(client); + vsm_array_string_free(keys); + vsm_array_string_free(values); + vsm_client_free(client); } BOOST_AUTO_TEST_CASE(GetContainerIdsTest) { - ScClient client = sc_client_create(); - ScStatus status = sc_connect(client); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); - ScArrayString values; - status = sc_get_container_ids(client, &values); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect(client); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + VsmArrayString values; + status = vsm_get_domain_ids(client, &values); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); BOOST_CHECK_EQUAL(getArrayStringLength(values, EXPECTED_DBUSES_STARTED.size() + 1), EXPECTED_DBUSES_STARTED.size()); @@ -154,23 +167,23 @@ BOOST_AUTO_TEST_CASE(GetContainerIdsTest) for (const auto& container : containers) { BOOST_CHECK(EXPECTED_DBUSES_STARTED.find(container) != EXPECTED_DBUSES_STARTED.cend()); } - sc_array_string_free(values); - sc_client_free(client); + vsm_array_string_free(values); + vsm_client_free(client); } BOOST_AUTO_TEST_CASE(GetActiveContainerIdTest) { - ScClient client = sc_client_create(); - ScStatus status = sc_connect(client); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); - ScString container; - status = sc_get_active_container_id(client, &container); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect(client); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + VsmString container; + status = vsm_get_active_container_id(client, &container); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); BOOST_CHECK_EQUAL(container, cm.getRunningForegroundContainerId()); - sc_string_free(container); - sc_client_free(client); + vsm_string_free(container); + vsm_client_free(client); } BOOST_AUTO_TEST_CASE(SetActiveContainerTest) @@ -179,25 +192,25 @@ BOOST_AUTO_TEST_CASE(SetActiveContainerTest) BOOST_REQUIRE_NE(newActiveContainerId, cm.getRunningForegroundContainerId()); - ScClient client = sc_client_create(); - ScStatus status = sc_connect(client); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); - status = sc_set_active_container(client, newActiveContainerId.c_str()); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect(client); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + status = vsm_set_active_container(client, newActiveContainerId.c_str()); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); BOOST_CHECK_EQUAL(newActiveContainerId, cm.getRunningForegroundContainerId()); - sc_client_free(client); + vsm_client_free(client); } BOOST_AUTO_TEST_CASE(AddContainerTest) { const std::string newActiveContainerId = ""; - ScClient client = sc_client_create(); - ScStatus status = sc_connect(client); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); - status = sc_add_container(client, newActiveContainerId.c_str()); - BOOST_REQUIRE_EQUAL(SCCLIENT_CUSTOM_ERROR, status); - sc_client_free(client); + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect(client); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + status = vsm_create_domain(client, newActiveContainerId.c_str()); + BOOST_REQUIRE_EQUAL(VSMCLIENT_CUSTOM_ERROR, status); + vsm_client_free(client); } BOOST_AUTO_TEST_CASE(FileMoveRequestTest) @@ -205,14 +218,14 @@ BOOST_AUTO_TEST_CASE(FileMoveRequestTest) const std::string path = "/tmp/fake_path"; const std::string secondContainer = "fake_container"; - ScClient client = sc_client_create(); - ScStatus status = sc_connect_custom(client, EXPECTED_DBUSES_STARTED.begin()->second.c_str()); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); - status = sc_file_move_request(client, secondContainer.c_str(), path.c_str()); - BOOST_REQUIRE_EQUAL(SCCLIENT_CUSTOM_ERROR, status); + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect_custom(client, EXPECTED_DBUSES_STARTED.begin()->second.c_str()); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); + status = vsm_file_move_request(client, secondContainer.c_str(), path.c_str()); + BOOST_REQUIRE_EQUAL(VSMCLIENT_CUSTOM_ERROR, status); BOOST_REQUIRE_EQUAL(api::container::FILE_MOVE_DESTINATION_NOT_FOUND, - sc_get_status_message(client)); - sc_client_free(client); + vsm_get_status_message(client)); + vsm_client_free(client); } BOOST_AUTO_TEST_CASE(NotificationTest) @@ -228,30 +241,29 @@ BOOST_AUTO_TEST_CASE(NotificationTest) auto callback = [](const char* container, const char* application, const char* message, - void* data) - { + void* data) { CallbackData& callbackData = *reinterpret_cast(data); callbackData.receivedSignalMsg.push_back(std::make_tuple(container, application, message)); callbackData.signalReceivedLatch.set(); }; CallbackData callbackData; - std::map clients; + std::map clients; for (const auto& it : EXPECTED_DBUSES_STARTED) { - ScClient client = sc_client_create(); - ScStatus status = sc_connect_custom(client, it.second.c_str()); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + VsmClient client = vsm_client_create(); + VsmStatus status = vsm_connect_custom(client, it.second.c_str()); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); clients[it.first] = client; } for (auto& client : clients) { - ScStatus status = sc_notification(client.second, callback, &callbackData); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + VsmStatus status = vsm_notification(client.second, callback, &callbackData); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); } for (auto& client : clients) { - ScStatus status = sc_notify_active_container(client.second, - MSG_APP.c_str(), - MSG_CONTENT.c_str()); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + VsmStatus status = vsm_notify_active_container(client.second, + MSG_APP.c_str(), + MSG_CONTENT.c_str()); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); } BOOST_CHECK(callbackData.signalReceivedLatch.waitForN(clients.size() - 1, EVENT_TIMEOUT)); @@ -264,39 +276,39 @@ BOOST_AUTO_TEST_CASE(NotificationTest) } for (auto& client : clients) { - sc_client_free(client.second); + vsm_client_free(client.second); } } BOOST_AUTO_TEST_CASE(GetContainerIdByPidTest1) { - ScClient client = sc_client_create(); - ScString container; - ScStatus status = sc_get_container_id_by_pid(client, 1, &container); - BOOST_REQUIRE_EQUAL(SCCLIENT_SUCCESS, status); + VsmClient client = vsm_client_create(); + VsmString container; + VsmStatus status = vsm_lookup_domain_by_pid(client, 1, &container); + BOOST_REQUIRE_EQUAL(VSMCLIENT_SUCCESS, status); BOOST_CHECK_EQUAL(container, std::string("host")); - sc_string_free(container); - sc_client_free(client); + vsm_string_free(container); + vsm_client_free(client); } BOOST_AUTO_TEST_CASE(GetContainerIdByPidTest2) { std::set ids; - ScClient client = sc_client_create(); + VsmClient client = vsm_client_create(); for (int n = 0; n < 100000; ++n) { - ScString container; - ScStatus status = sc_get_container_id_by_pid(client, n, &container); - if (status == SCCLIENT_SUCCESS) { + VsmString container; + VsmStatus status = vsm_lookup_domain_by_pid(client, n, &container); + if (status == VSMCLIENT_SUCCESS) { ids.insert(container); - sc_string_free(container); + vsm_string_free(container); } else { - BOOST_WARN_MESSAGE(status == SCCLIENT_INVALID_ARGUMENT, sc_get_status_message(client)); + BOOST_WARN_MESSAGE(status == VSMCLIENT_INVALID_ARGUMENT, vsm_get_status_message(client)); } } - sc_client_free(client); + vsm_client_free(client); BOOST_CHECK(ids.count("host") == 1); -- 2.7.4