Merge branch 'tizen' into dbus 38/38638/1 dbus
authorZbigniew Jasinski <z.jasinski@samsung.com>
Thu, 23 Apr 2015 09:38:56 +0000 (11:38 +0200)
committerZbigniew Jasinski <z.jasinski@samsung.com>
Thu, 23 Apr 2015 09:53:48 +0000 (11:53 +0200)
Conflicts:
src/security-tests-all.sh
src/smack-dbus-tests/CMakeLists.txt
tests/CMakeLists.txt

Change-Id: I6a190cf7b1b955aa608aa45b2b20f37575bb5165

22 files changed:
1  2 
packaging/security-tests.spec
src/common/dbus_connection.cpp
src/common/dbus_connection.h
src/common/dbus_message_in.cpp
src/common/dbus_message_in.h
src/common/dbus_message_out.cpp
src/common/dbus_message_out.h
src/common/smack_access.cpp
src/common/smack_access.h
src/security-tests.sh
src/smack-dbus-tests/CMakeLists.txt
src/smack-dbus-tests/common/dbus_test_busconfig_writer.cpp
src/smack-dbus-tests/common/dbus_test_busconfig_writer.h
src/smack-dbus-tests/common/dbus_test_commons.cpp
src/smack-dbus-tests/common/dbus_test_commons.h
src/smack-dbus-tests/common/dbus_test_service.cpp
src/smack-dbus-tests/common/dbus_test_service.h
src/smack-dbus-tests/common/dbus_test_service_object.cpp
src/smack-dbus-tests/common/dbus_test_service_object.h
src/smack-dbus-tests/cynara_dbus_tests.cpp
src/smack-dbus-tests/main.cpp
src/smack-dbus-tests/smack_dbus_tests.cpp

Simple merge
index 0000000000000000000000000000000000000000,424bd0eb3701cfae38f6f0915659545e00c51a9f..9ddceea56468bc0d13ad92ff0d41c1979fa3b457
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,135 +1,196 @@@
 - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ /*
 -void Connection::readWriteDispatch()
++ * Copyright (c) 2014-2015 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        dbus_connection.cpp
+  * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
+  * @version     1.0
+  * @brief       DBus connection wrapper class source file
+  */
+ #include <dbus_connection.h>
+ #include <dpl/test/test_runner.h>
+ namespace DBus
+ {
+ Connection::Connection(DBusBusType busType, bool busPrivate)
+     : m_busPrivate(busPrivate)
++    , m_unref(true)
+ {
+     DBusError error;
+     dbus_error_init(&error);
+     ErrorPtr errorPtr(&error);
+     if (busPrivate)
+         m_connection = dbus_bus_get_private(busType, &error);
+     else
+         m_connection = dbus_bus_get(busType, &error);
+     RUNNER_ASSERT_MSG(m_connection != nullptr,
+                       "Failed to open connection on "
+                           << (busPrivate ? "private" : "public") << " bus."
+                           << " Error: " << error.message);
+     dbus_connection_set_exit_on_disconnect(m_connection, FALSE);
+ }
++Connection::Connection(DBusConnection *connection)
++    : m_connection(connection)
++    , m_unref(false)
++{
++}
++
+ Connection::~Connection()
+ {
++    if (!m_unref)
++        return;
+     if (m_busPrivate)
+         dbus_connection_close(m_connection);
+     dbus_connection_unref(m_connection);
+ }
+ void Connection::addMatch(const std::string &rule)
+ {
+     DBusError error;
+     dbus_error_init(&error);
+     ErrorPtr errorPtr(&error);
+     dbus_bus_add_match(m_connection, rule.c_str(), &error);
+     RUNNER_ASSERT_MSG(dbus_error_is_set(&error) != TRUE, "Failed to add match."
+                                                              << " Rule: " << rule << ";"
+                                                              << " Error: " << error.message);
+ }
+ void Connection::addFilter(DBusHandleMessageFunction handleMessageFunction,
+                            void *userData,
+                            DBusFreeFunction freeDataFunction)
+ {
+     if (freeDataFunction == nullptr)
+         freeDataFunction = [](void*)->void {};
+     dbus_bool_t ret = dbus_connection_add_filter(m_connection,
+                                                  handleMessageFunction,
+                                                  userData,
+                                                  freeDataFunction);
+     RUNNER_ASSERT_MSG(ret == TRUE, "Failed to add filter. Not enough memory");
+ }
 -    dbus_bool_t ret = dbus_connection_read_write_dispatch(m_connection, -1);
++void Connection::readWrite(int timeoutMilliseconds)
++{
++    dbus_bool_t ret = dbus_connection_read_write(m_connection, timeoutMilliseconds);
++    RUNNER_ASSERT_MSG(ret == TRUE, "Failed to read write. Disconnect message has been processed");
++}
++
++void Connection::dispatch()
++{
++    DBusDispatchStatus ret = dbus_connection_dispatch(m_connection);
++    RUNNER_ASSERT_MSG(ret != DBUS_DISPATCH_NEED_MEMORY,
++                      "Failed to dispatch. Not enough memory");
++}
++
++void Connection::readWriteDispatch(int timeoutMilliseconds)
+ {
 -void Connection::requestName(const std::string &name)
++    dbus_bool_t ret = dbus_connection_read_write_dispatch(m_connection, timeoutMilliseconds);
+     RUNNER_ASSERT_MSG(ret == TRUE, "Failed to read write dispatch. Disconnect message has been processed");
+ }
+ void Connection::flush()
+ {
+     dbus_connection_flush(m_connection);
+ }
 -    switch (ret)
 -    {
 -        case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
 -        case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
 -            return;
 -        case DBUS_REQUEST_NAME_REPLY_EXISTS:
 -            RUNNER_FAIL_MSG("Failed to request name."
 -                                << " Name: " << name << ";"
 -                                << " Owner did not specified DBUS_NAME_FLAG_ALLOW_REPLACEMENT flag");
 -        case -1:
 -            RUNNER_FAIL_MSG("Failed to request name."
 -                                << " Name: " << name << ";"
 -                                << " Error: " << error.message);
 -        default: // DBUS_REQUEST_NAME_REPLY_IN_QUEUE
 -            RUNNER_FAIL_MSG("Should not happen");
 -    }
++void Connection::requestName(const std::string &name, int expectedResult)
+ {
+     DBusError error;
+     dbus_error_init(&error);
+     ErrorPtr errorPtr(&error);
+     int ret = dbus_bus_request_name(m_connection,
+                                     name.c_str(),
+                                     DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_DO_NOT_QUEUE,
+                                     &error);
++    RUNNER_ASSERT_MSG(ret == expectedResult, "dbus_bus_request_name returned wrong value."
++                                                 << " Result: " << ret << ","
++                                                 << " Expected result: " << expectedResult << ","
++                                                 << " Name: " << name << ","
++                                                 << " Error: " << error.message);
++}
++
++void Connection::registerObjectPath(const std::string &path,
++                                    DBusObjectPathMessageFunction messageFunction,
++                                    void *userData)
++{
++    auto p = m_pathVTables.insert(
++        std::pair<std::string, DBusObjectPathVTable>(
++            path, { [] (DBusConnection *connection, void *userData)->void { (void) connection;
++                                                                            (void) userData; },
++                    messageFunction,
++                    nullptr, nullptr, nullptr, nullptr
++                  }
++            )
++        );
++    RUNNER_ASSERT_MSG(p.second, "Path <" << path << "> already exists");
++
++    DBusError error;
++    dbus_error_init(&error);
++    ErrorPtr errorPtr(&error);
++    dbus_bool_t ret = dbus_connection_try_register_object_path(m_connection,
++                                                               path.c_str(),
++                                                               &(p.first->second),
++                                                               userData,
++                                                               &error);
++    RUNNER_ASSERT_MSG(ret != FALSE, "Failed to register object path. "
++                                        << "Error: " << error.message);
+ }
+ MessageIn Connection::sendWithReplyAndBlock(const MessageOut &messageOut)
+ {
+     DBusError error;
+     dbus_error_init(&error);
+     ErrorPtr errorPtr(&error);
+     DBusMessage *messageRecv = dbus_connection_send_with_reply_and_block(m_connection,
+                                                                          messageOut.getMessage(),
+                                                                          -1,
+                                                                          &error);
+     RUNNER_ASSERT_MSG(messageRecv != nullptr, "Failed to send with reply and block. "
+                                                   << "Error: " << error.message);
+     return MessageIn(messageRecv);
+ }
++DBusMessage* Connection::sendWithReplyAndBlock(const MessageOut &messageOut,
++                                               int timeoutMilliseconds,
++                                               DBusError *error)
++{
++    return dbus_connection_send_with_reply_and_block(m_connection,
++                                                     messageOut.getMessage(),
++                                                     timeoutMilliseconds,
++                                                     error);
++}
++
++
++void Connection::send(const MessageOut &messageOut)
++{
++    DBusError error;
++    dbus_error_init(&error);
++    ErrorPtr errorPtr(&error);
++
++    dbus_bool_t ret = dbus_connection_send(m_connection,
++                                           messageOut.getMessage(),
++                                           nullptr);
++    RUNNER_ASSERT_MSG(ret == TRUE, "Failed to send. Not enough memory");
++}
++
+ } // namespace DBus
index 0000000000000000000000000000000000000000,f2db5aced8696ee88294bb936fbe7c59a0034600..b338fc2cc496bf765d74a4d8f006b42fe09f1c78
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,64 +1,78 @@@
 - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ /*
 -    void readWriteDispatch();
++ * Copyright (c) 2014-2015 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        dbus_connection.h
+  * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
+  * @version     1.0
+  * @brief       DBus connection wrapper class header
+  */
+ #ifndef COMMON_DBUS_CONNECTION_H
+ #define COMMON_DBUS_CONNECTION_H
+ #include <dbus/dbus.h>
+ #include <dbus_message_in.h>
+ #include <dbus_message_out.h>
+ #include <memory.h>
++#include <map>
+ #include <string>
+ namespace DBus
+ {
+ DEFINE_SMARTPTR(dbus_error_free, DBusError, ErrorPtr);
+ class Connection
+ {
+ public:
+     Connection(DBusBusType busType, bool privateGet);
++    Connection(DBusConnection *connection);
+     Connection(const Connection &other) = delete;
+     ~Connection();
+     Connection& operator=(const Connection &other) = delete;
+     void addMatch(const std::string &rule);
+     void addFilter(DBusHandleMessageFunction handleMessageFunction,
+                    void *userData,
+                    DBusFreeFunction freeDataFunction = nullptr);
 -    void requestName(const std::string &name);
++    void readWrite(int timeoutMilliseconds = -1);
++    void dispatch();
++    void readWriteDispatch(int timeoutMilliseconds = -1);
+     void flush();
++    void requestName(const std::string &name,
++                     int expectedResult = DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER);
++    void registerObjectPath(const std::string &path,
++                            DBusObjectPathMessageFunction messageFunction,
++                            void *userData);
+     MessageIn sendWithReplyAndBlock(const MessageOut &messageOut);
++    DBusMessage* sendWithReplyAndBlock(const MessageOut &messageOut,
++                                       int timeoutMilliseconds,
++                                       DBusError *error);
++    void send(const MessageOut &messageOut);
+ private:
+     DBusConnection *m_connection;
++    std::map<std::string, DBusObjectPathVTable> m_pathVTables;
+     bool m_busPrivate;
++    bool m_unref;
+ };
+ } // namespace DBus
+ #endif // COMMON_DBUS_CONNECTION_H
index 0000000000000000000000000000000000000000,c04533bba705d1ddf5aa55ae4c1f2f7c39b340ff..41478b40696aab04dfb1467afc05986eb1a64f72
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,180 +1,185 @@@
+ /*
+  * 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        dbus_message_in.cpp
+  * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
+  * @version     1.0
+  * @brief       DBus incoming message wrapper class source file
+  */
+ #include <dbus_message_in.h>
+ #include <dpl/test/test_runner.h>
+ namespace DBus
+ {
+ MessageIn::MessageIn(DBusMessage *message, bool ref)
+     : m_message(message)
+ {
+     RUNNER_ASSERT(m_message != nullptr);
+     if (ref)
+         dbus_message_ref(m_message);
+ }
+ MessageIn::MessageIn(MessageIn &&other)
+     : m_message(other.m_message)
+ {
+     other.m_message = nullptr;
+ }
+ MessageIn::~MessageIn()
+ {
+     if (m_message != nullptr)
+         dbus_message_unref(m_message);
+ }
++DBusMessage* MessageIn::getMessage() const
++{
++    return m_message;
++}
++
+ int MessageIn::getType()
+ {
+     return dbus_message_get_type(m_message);
+ }
+ bool MessageIn::isMethodCall(const std::string &interface, const std::string &method)
+ {
+     dbus_bool_t ret = dbus_message_is_method_call(m_message,
+                                                   interface.c_str(),
+                                                   method.c_str());
+     return ret == TRUE;
+ }
+ bool MessageIn::isSignal(const std::string &interface, const std::string &signalName)
+ {
+     dbus_bool_t ret = dbus_message_is_signal(m_message,
+                                              interface.c_str(),
+                                              signalName.c_str());
+     return ret == TRUE;
+ }
+ bool MessageIn::isError(const std::string &errorName)
+ {
+     dbus_bool_t ret = dbus_message_is_error(m_message,
+                                             errorName.c_str());
+     return ret == TRUE;
+ }
+ MessageIn::Iterator MessageIn::iterInit()
+ {
+     return Iterator(this->m_message);
+ }
+ MessageIn::Iterator::Iterator(DBusMessage* message)
+ {
+     dbus_message_iter_init(message, &m_iterator);
+ }
+ MessageIn::Iterator::Iterator(DBusMessageIter *iteratorOver)
+ {
+     dbus_message_iter_recurse(iteratorOver, &m_iterator);
+ }
+ bool MessageIn::Iterator::next()
+ {
+     return dbus_message_iter_next(&m_iterator) != FALSE;
+ }
+ void MessageIn::Iterator::expectNext()
+ {
+     RUNNER_ASSERT_MSG(next(), "No next argument in message");
+ }
+ int MessageIn::Iterator::getArgType()
+ {
+     return dbus_message_iter_get_arg_type(&m_iterator);
+ }
+ void MessageIn::Iterator::expectArgType(int argType)
+ {
+     int argTypeActual = getArgType();
+     RUNNER_ASSERT_MSG(argTypeActual == argType, "Wrong argument type in message"
+                                                     << " Actual: " << argTypeActual
+                                                     << " Expected: " << argType);
+ }
+ void MessageIn::Iterator::expectArgTypeValid()
+ {
+     RUNNER_ASSERT_MSG(getArgType() != DBUS_TYPE_INVALID, "Invalid argument type in message");
+ }
+ char MessageIn::Iterator::getArgChar()
+ {
+     return getArg<char>();
+ }
+ bool MessageIn::Iterator::getArgBool()
+ {
+     dbus_bool_t value;
+     dbus_message_iter_get_basic(&m_iterator, &value);
+     return value != FALSE;
+ }
+ int16_t MessageIn::Iterator::getArgInt16()
+ {
+     return getArg<int16_t>();
+ }
+ uint16_t MessageIn::Iterator::getArgUint16()
+ {
+     return getArg<uint16_t>();
+ }
+ int32_t MessageIn::Iterator::getArgInt32()
+ {
+     return getArg<int32_t>();
+ }
+ uint32_t MessageIn::Iterator::getArgUint32()
+ {
+     return getArg<uint32_t>();
+ }
+ int64_t MessageIn::Iterator::getArgInt64()
+ {
+     return getArg<int64_t>();
+ }
+ uint64_t MessageIn::Iterator::getArgUint64()
+ {
+     return getArg<uint64_t>();
+ }
+ double MessageIn::Iterator::getArgDouble()
+ {
+     return getArg<double>();
+ }
+ std::string MessageIn::Iterator::getArgString()
+ {
+     char *value;
+     dbus_message_iter_get_basic(&m_iterator, &value);
+     return std::string(value);
+ }
+ MessageIn::Iterator MessageIn::Iterator::recurse()
+ {
+     return Iterator(&(this->m_iterator));
+ }
+ } // namespace DBus
index 0000000000000000000000000000000000000000,e0a0dc78686178da4bf4f30d5e2a8c300e56a42f..1c26e21993a9e97863a7cc4837da3738cd03f018
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,94 +1,96 @@@
+ /*
+  * 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        dbus_message_in.h
+  * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
+  * @version     1.0
+  * @brief       DBus incoming message wrapper class header
+  */
+ #ifndef COMMON_DBUS_MESSAGE_IN_H
+ #define COMMON_DBUS_MESSAGE_IN_H
+ #include <dbus/dbus.h>
+ #include <cstdint>
+ #include <string>
+ namespace DBus
+ {
+ class MessageIn
+ {
+ public:
+     MessageIn(DBusMessage *message, bool ref = false);
+     MessageIn(const MessageIn &other) = delete;
+     MessageIn(MessageIn &&other);
+     ~MessageIn();
+     MessageIn& operator=(const MessageIn &other) = delete;
++    DBusMessage* getMessage() const;
++
+     int getType();
+     bool isMethodCall(const std::string &interface, const std::string &method);
+     bool isSignal(const std::string &interface, const std::string &signalName);
+     bool isError(const std::string &errorName);
+     class Iterator
+     {
+     public:
+         friend class MessageIn;
+         bool next();
+         void expectNext();
+         int getArgType();
+         void expectArgType(int argType);
+         void expectArgTypeValid();
+         char getArgChar();
+         bool getArgBool();
+         int16_t getArgInt16();
+         uint16_t getArgUint16();
+         int32_t getArgInt32();
+         uint32_t getArgUint32();
+         int64_t getArgInt64();
+         uint64_t getArgUint64();
+         double getArgDouble();
+         std::string getArgString();
+         Iterator recurse();
+     private:
+         template<class T>
+         T getArg() {
+             T value;
+             dbus_message_iter_get_basic(&m_iterator, &value);
+             return value;
+         }
+         // sub constructor
+         Iterator(DBusMessageIter *iteratorOver);
+         // message constructor
+         Iterator(DBusMessage *message);
+         DBusMessageIter m_iterator;
+     };
+     Iterator iterInit();
+ private:
+     DBusMessage *m_message;
+ };
+ } // namespace DBus
+ #endif // COMMON_DBUS_MESSAGE_IN_H
index 0000000000000000000000000000000000000000,2de0659bf3ecfa647be9029413a49e49e0b0869f..c055cd79e389de4c28c02e45de8b0f28b51a2698
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,111 +1,120 @@@
+ /*
+  * 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        dbus_message_out.cpp
+  * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
+  * @version     1.0
+  * @brief       DBus outgoing message wrapper class source file
+  */
+ #include <dbus_message_out.h>
+ #include <dpl/test/test_runner.h>
+ namespace DBus
+ {
+ MessageOut::MessageOut(const std::string &destination,
+                        const std::string &path,
+                        const std::string &interface,
+                        const std::string &method)
+ {
+     m_message = dbus_message_new_method_call(destination.c_str(),
+                                              path.c_str(),
+                                              interface.c_str(),
+                                              method.c_str());
+     RUNNER_ASSERT_MSG(nullptr != m_message,
+                       "Failed to create new method call. Not enough memory");
+ }
++MessageOut::MessageOut(DBusMessage *replyTo,
++                       const std::string &errorName,
++                       const std::string &errorMessage)
++{
++    m_message = dbus_message_new_error(replyTo, errorName.c_str(), errorMessage.c_str());
++    RUNNER_ASSERT_MSG(nullptr != m_message,
++                      "Failed to create new error");
++}
++
+ MessageOut::MessageOut(MessageOut &&other)
+     : m_message(other.m_message)
+ {
+     other.m_message = nullptr;
+ }
+ MessageOut::~MessageOut()
+ {
+     if (m_message != nullptr)
+         dbus_message_unref(m_message);
+ }
+ DBusMessage* MessageOut::getMessage() const
+ {
+     return m_message;
+ }
+ void MessageOut::append(bool b)
+ {
+     DBusMessageIter iter;
+     dbus_message_iter_init_append(m_message, &iter);
+     dbus_bool_t bArg = b ? TRUE : FALSE;
+     dbus_bool_t ret = dbus_message_iter_append_basic(&iter,
+                                                      DBUS_TYPE_BOOLEAN,
+                                                      &bArg);
+     RUNNER_ASSERT_MSG(ret != FALSE, "Failed to append basic boolean. Not enough memory");
+ }
+ void MessageOut::append(const char *cstr)
+ {
+     DBusMessageIter iter;
+     dbus_message_iter_init_append(m_message, &iter);
+     dbus_bool_t ret = dbus_message_iter_append_basic(&iter,
+                                                      DBUS_TYPE_STRING,
+                                                      &cstr);
+     RUNNER_ASSERT_MSG(ret != FALSE, "Failed to append basic string. Not enough memory");
+ }
+ void MessageOut::append(const std::string &str)
+ {
+     append(str.c_str());
+ }
+ void MessageOut::append(const std::vector<std::string> &strs)
+ {
+     DBusMessageIter iter;
+     dbus_message_iter_init_append(m_message, &iter);
+     DBusMessageIter subIter;
+     dbus_bool_t ret = dbus_message_iter_open_container(&iter,
+                                                        DBUS_TYPE_ARRAY,
+                                                        DBUS_TYPE_STRING_AS_STRING,
+                                                        &subIter);
+     RUNNER_ASSERT_MSG(ret != FALSE, "Failed to open container. Not enough memory");
+     for (const auto &str : strs) {
+         const char *cstr = str.c_str();
+         ret = dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &cstr);
+         if (ret == FALSE) {
+             dbus_message_iter_abandon_container(&iter, &subIter);
+             RUNNER_FAIL_MSG("Failed to append basic string. Not enough memory");
+         }
+     }
+     ret = dbus_message_iter_close_container(&iter, &subIter);
+     RUNNER_ASSERT_MSG(ret != FALSE, "Failed to close container. Not enough memory");
+ }
+ } // namespace DBus
index 0000000000000000000000000000000000000000,8b34d06e61439c89ed668c882f4fad50d61caf0f..6ceb6f7bc529faef149a5732132c0a6f93ea70fa
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,60 +1,63 @@@
+ /*
+  * 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        dbus_message_out.h
+  * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
+  * @version     1.0
+  * @brief       DBus outgoing message wrapper class header
+  */
+ #ifndef COMMON_DBUS_MESSAGE_OUT_H
+ #define COMMON_DBUS_MESSAGE_OUT_H
+ #include <dbus/dbus.h>
+ #include <string>
+ #include <vector>
+ namespace DBus
+ {
+ class MessageOut
+ {
+ public:
+     MessageOut(const std::string &destination,
+                const std::string &path,
+                const std::string &interface,
+                const std::string &method);
++    MessageOut(DBusMessage *replyTo,
++               const std::string &errorName,
++               const std::string &errorMessage);
+     MessageOut(const MessageOut &other) = delete;
+     MessageOut(MessageOut &&other);
+     ~MessageOut();
+     MessageOut& operator=(const MessageOut &other) = delete;
+     DBusMessage* getMessage() const;
+     void append(bool b);
+     void append(const char *cstr);
+     void append(const std::string &str);
+     void append(const std::vector<std::string> &strs);
+ private:
+     DBusMessage *m_message;
+ };
+ } // namespace DBus
+ #endif // COMMON_DBUS_MESSAGE_OUT_H
index 0000000000000000000000000000000000000000,354b99718153d821d8847702b8ed003392b7dc1f..b917027f918cecb2e645eecc5e0668626a6dcbfa
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,57 +1,62 @@@
+ /*
+  * Copyright (c) 2013 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        smack_access.cpp
+  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+  * @version     1.0
+  * @brief       Common functions and macros used in security-tests package.
+  */
+ #include <sys/smack.h>
+ #include <tests_common.h>
+ #include <smack_access.h>
+ SmackAccess::SmackAccess()
+   : m_handle(nullptr)
+ {
+     RUNNER_ASSERT_MSG(0 == smack_accesses_new(&m_handle),
+         "Error in smack_accesses_new");
+ }
+ void SmackAccess::add(
+     const std::string &subject,
+     const std::string &object,
+     const std::string &rights)
+ {
+     RUNNER_ASSERT_MSG(0 == smack_accesses_add(m_handle,
+             subject.c_str(),
+             object.c_str(),
+             rights.c_str()),
+         "Error in smack_accesses_add.");
+ }
+ void SmackAccess::apply() {
+     RUNNER_ASSERT_MSG(0 == smack_accesses_apply(m_handle),
+         "Error in smack_accessses_apply.");
+ }
++void SmackAccess::clear() {
++    RUNNER_ASSERT_MSG(0 == smack_accesses_clear(m_handle),
++        "Error in smack_accessses_clear.");
++}
++
+ SmackAccess::~SmackAccess() {
+     if (m_handle)
+         smack_accesses_free(m_handle);
+ }
index 0000000000000000000000000000000000000000,f20842be14caf995ddb6dd02f5d038e93785bbc9..f7e69b90747147f7e65f6253af85e2b4bb71e5e3
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,45 +1,46 @@@
+ /*
+  * Copyright (c) 2013 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        smack_access.h
+  * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+  * @version     1.0
+  * @brief       Common functions and macros used in security-tests package.
+  */
+ #ifndef _SMACK_ACCESS_H_
+ #define _SMACK_ACCESS_H_
+ #include <string>
+ struct smack_accesses;
+ class SmackAccess {
+ public:
+     SmackAccess();
+     SmackAccess(const SmackAccess &second) = delete;
+     SmackAccess& operator=(SmackAccess &second) = delete;
+     void add(const std::string &subject,
+              const std::string &object,
+              const std::string &rights);
+     void apply();
++    void clear();
+     virtual ~SmackAccess();
+ private:
+     struct smack_accesses *m_handle;
+ };
+ #endif // _SMACK_ACCESS_H_
index 0000000000000000000000000000000000000000,f99127bc99cd530c191a6b918238f6c2ca9ba41a..772021b3a13014dacadee595f3544a5a6f065340
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,108 +1,108 @@@
 -"smack-dbus")
+ #!/bin/sh
+ #####################################################################
+ # Copyright (c) 2012-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.
+ #####################################################################
+ #testing internet access and date on the target
+ echo "### Starting tests ######################################################"
+ case $1 in
+ "smack")
+     echo "========================================================================="
+     echo $1
+     echo
+     libsmack-test "${@:2}" # propagate all remaining arguments (except first)
+     ;;
 -    echo "SMACK DBUS TEST"
++"dbus")
+     echo "========================================================================="
 -    smack-dbus-tests "${@:2}"
++    echo "DBUS TEST"
+     echo
 -    echo "modules: smack, smack-dbus, libprivilege-control, ss-clientsmack"
++    dbus-tests "${@:2}"
+     ;;
+ "libprivilege-control")
+     echo "========================================================================="
+     echo $1
+     echo
+     libprivilege-control-test "${@:2}"
+     ;;
+ "ss-clientsmack")
+     echo "========================================================================="
+     echo "SECURITY SERVER TEST CLIENT SMACK"
+     echo
+     security-server-tests-client-smack "${@:2}"
+     ;;
+ "ss-stress")
+     echo "========================================================================="
+     echo "SECURITY SERVER TEST STRESS"
+     echo
+     security-server-tests-stress "${@:2}"
+     ;;
+ "ss-server")
+     echo "========================================================================="
+     echo "SECURITY SERVER TEST SERVER"
+     echo
+     security-server-tests-server "${@:2}"
+     ;;
+ "ss-api-speed")
+     echo "========================================================================="
+     echo "SECURITY SERVER MEASURER SERVER"
+     echo
+     security-server-tests-api-speed "${@:2}"
+     ;;
+ "ss-password")
+     echo "========================================================================="
+     echo "SECURITY SERVER TEST PASSWORD"
+     echo
+     security-server-tests-password "${@:2}"
+     ;;
+ "ss-privilege")
+     echo "========================================================================="
+     echo "SECURITY SERVER TEST PRIVILEGE"
+     echo
+     security-server-tests-privilege "${@:2}"
+     ;;
+ "security-manager")
+     echo "========================================================================="
+     echo "SECURITY MANAGER TESTS"
+     echo
+     security-manager-tests "${@:2}"
+     ;;
+ "cynara")
+     echo "========================================================================="
+     echo "CYNARA TEST"
+     echo
+     cynara-test "${@:2}"
+     ;;
+ "ckm")
+     echo "========================================================================="
+     echo "KEY MANAGER TESTS"
+     echo
+     ckm-tests "${@:2}"
+     ;;
+ *)
+     echo "Correct using:"
+     echo "    security_test.sh <module> <args_for_module>"
+     echo
++    echo "modules: smack, dbus, libprivilege-control, ss-clientsmack"
+     echo "         ss-server, ss-api-speed, ss-password, ss-stress"
+     echo "         ss-privilege, security-manager, cynara, ckm"
+     ;;
+ esac
+ echo "### Tests done ##########################################################"
index 0000000000000000000000000000000000000000,865b714bce0303cfc035d8461f3778d0a33ef2b2..39793a1c642c8bd35c95bc75572fba6ef3fe5c5d
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,56 +1,68 @@@
 -PKG_CHECK_MODULES(SMACK_DBUS_TESTS_DEP
++#
+ # Copyright (c) 2014-2015 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      Michal Eljasiewicz (m.eljasiewic@samsung.com)
+ # @brief
+ #
+ INCLUDE(FindPkgConfig)
+ # Dependencies
 -    ${SMACK_DBUS_TESTS_DEP_INCLUDE_DIRS}
++PKG_CHECK_MODULES(DBUS_TESTS_DEP
+     libsmack
++    cynara-admin
+     dbus-1
+     REQUIRED)
+ # Targets definition
+ INCLUDE_DIRECTORIES(SYSTEM
 -SET(TARGET_SMACK_DBUS_TESTS "smack-dbus-tests")
++    ${DBUS_TESTS_DEP_INCLUDE_DIRS}
+    )
 -SET(SMACK_DBUS_SOURCES
++SET(TARGET_DBUS_TESTS "dbus-tests")
+ # Sources definition
 -ADD_EXECUTABLE(${TARGET_SMACK_DBUS_TESTS} ${SMACK_DBUS_SOURCES})
++SET(DBUS_TESTS_SOURCES
++    ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/cynara_test_admin.cpp
++    ${PROJECT_SOURCE_DIR}/src/smack-dbus-tests/common/dbus_test_commons.cpp
++    ${PROJECT_SOURCE_DIR}/src/smack-dbus-tests/common/dbus_test_service.cpp
++    ${PROJECT_SOURCE_DIR}/src/smack-dbus-tests/common/dbus_test_service_object.cpp
++    ${PROJECT_SOURCE_DIR}/src/smack-dbus-tests/main.cpp
++    ${PROJECT_SOURCE_DIR}/src/smack-dbus-tests/common/dbus_test_busconfig_writer.cpp
++    ${PROJECT_SOURCE_DIR}/src/smack-dbus-tests/cynara_dbus_tests.cpp
+     ${PROJECT_SOURCE_DIR}/src/smack-dbus-tests/smack_dbus_tests.cpp
+    )
+ INCLUDE_DIRECTORIES(
+     ${PROJECT_SOURCE_DIR}/src/common/
++    ${PROJECT_SOURCE_DIR}/src/cynara-tests/common/
++    ${PROJECT_SOURCE_DIR}/src/cynara-tests/plugins/
++    ${PROJECT_SOURCE_DIR}/src/smack-dbus-tests/common/
+    )
 -TARGET_LINK_LIBRARIES(${TARGET_SMACK_DBUS_TESTS}
 -    ${SMACK_DBUS_TESTS_DEP_LIBRARIES}
++ADD_EXECUTABLE(${TARGET_DBUS_TESTS} ${DBUS_TESTS_SOURCES})
 -INSTALL(TARGETS ${TARGET_SMACK_DBUS_TESTS} DESTINATION /usr/bin)
++TARGET_LINK_LIBRARIES(${TARGET_DBUS_TESTS}
++    ${DBUS_TESTS_DEP_LIBRARIES}
+     dpl-test-framework
+     tests-common
+     )
+ # Installation
++INSTALL(TARGETS ${TARGET_DBUS_TESTS} DESTINATION /usr/bin)
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1f5cc1986176b284a47a7898bfc6033bc8d2ac9b
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,163 @@@
++/*
++ * Copyright (c) 2015 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        dbus_test_busconfig_writer.cpp
++ * @author      Marcin Niesluchowski <m.niesluchow@samsung.com>
++ * @version     1.0
++ * @brief       dbus test busconfig writer definition
++ */
++
++#include <dbus_test_busconfig_writer.h>
++
++#include <dpl/test/test_runner.h>
++
++#include <map>
++#include <unistd.h>
++
++namespace DBusTest {
++
++namespace {
++
++const char* const BUSCONFIG_ENCODING = "ISO-8859-1";
++
++const std::map<Attr, std::string> ATTR_MAP = {
++    { Attr::OWN, "own" },
++    { Attr::OWN_PREFIX, "own_prefix" },
++
++    { Attr::SEND_DESTINATION, "send_destination" },
++    { Attr::SEND_PATH, "send_path" },
++    { Attr::SEND_INTERFACE, "send_interface" },
++    { Attr::SEND_TYPE, "send_type" },
++    { Attr::SEND_MEMBER, "send_member" },
++    { Attr::SEND_ERROR, "send_error" },
++
++    { Attr::RECEIVE_SENDER, "receive_sender" },
++    { Attr::RECEIVE_PATH, "receive_path" },
++    { Attr::RECEIVE_INTERFACE, "receive_interface" },
++    { Attr::RECEIVE_TYPE, "receive_type" },
++    { Attr::RECEIVE_MEMBER, "receive_member" },
++    { Attr::RECEIVE_ERROR, "receive_error" }
++};
++
++}
++
++const std::string VAL_ALL = "*";
++const std::string CONF_FILE_PATH("/etc/dbus-1/system.d/security_tests_dbus_tests.conf");
++
++BusConfigWriter::BusConfigWriter()
++    : m_writer(nullptr)
++    , m_doc(nullptr)
++{
++    RUNNER_ASSERT_MSG(0 == unlink(CONF_FILE_PATH.c_str()) || errno == ENOENT,
++                      "Unable to unlink existing file " << CONF_FILE_PATH << " file");
++
++    m_writer = xmlNewTextWriterDoc(&m_doc, 0);
++    RUNNER_ASSERT_MSG(m_writer, "xmlNewTextWriterDoc failed");
++
++    RUNNER_ASSERT(0 <= xmlTextWriterStartDocument(m_writer, NULL, BUSCONFIG_ENCODING, NULL));
++
++    RUNNER_ASSERT(0 <= xmlTextWriterWriteDTD(
++                          m_writer,
++                          BAD_CAST "busconfig",
++                          BAD_CAST "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN",
++                          BAD_CAST "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd",
++                          NULL));
++
++    startElement("busconfig");
++
++    writeElement("type", "system");
++
++    startElement("policy");
++    writeAttribute("context", "default");
++}
++
++BusConfigWriter::~BusConfigWriter()
++{
++    if (m_doc)
++        xmlFreeDoc(m_doc);
++    if (m_writer)
++        xmlFreeTextWriter(m_writer);
++}
++
++void BusConfigWriter::addPolicyAllow(const AttrValVec &attrValVec)
++{
++    startElement("allow");
++    for (const auto &attrVal : attrValVec)
++        writeAttribute(attrVal);
++    endElement();
++}
++
++void BusConfigWriter::addPolicyDeny(const AttrValVec &attrValVec)
++{
++    startElement("deny");
++    for (const auto &attrVal : attrValVec)
++        writeAttribute(attrVal);
++    endElement();
++}
++
++void BusConfigWriter::addPolicyCheck(const std::string &privilege, const AttrValVec &attrValVec)
++{
++    startElement("check");
++    for (const auto &attrVal : attrValVec)
++        writeAttribute(attrVal);
++    writeAttribute("privilege", privilege);
++    endElement();
++}
++
++void BusConfigWriter::save()
++{
++    endElement();
++    endElement();
++
++    RUNNER_ASSERT(0 <= xmlTextWriterEndDocument(m_writer));
++
++    RUNNER_ASSERT_MSG(0 <= xmlSaveFileEnc(CONF_FILE_PATH.c_str(), m_doc, BUSCONFIG_ENCODING),
++                      "Unable to save doc file: " << CONF_FILE_PATH);
++}
++
++void BusConfigWriter::startElement(const std::string &element)
++{
++    RUNNER_ASSERT_MSG(0 <= xmlTextWriterStartElement(m_writer, BAD_CAST element.c_str()),
++                      "Unable to start element: " << element);
++}
++
++void BusConfigWriter::writeAttribute(const std::string &attr, const std::string &val)
++{
++    RUNNER_ASSERT_MSG(0 <= xmlTextWriterWriteAttribute(m_writer,
++                                                       BAD_CAST attr.c_str(),
++                                                       BAD_CAST val.c_str()),
++                      "Unable to write attribute: " << attr << "=\"" << val << "\"");
++}
++
++void BusConfigWriter::writeAttribute(const AttrVal &attrVal)
++{
++    writeAttribute(ATTR_MAP.at(attrVal.attr), attrVal.val);
++}
++
++void BusConfigWriter::endElement()
++{
++    RUNNER_ASSERT(0 <= xmlTextWriterEndElement(m_writer));
++}
++
++void BusConfigWriter::writeElement(const std::string &element, const std::string &content)
++{
++    RUNNER_ASSERT_MSG(0 <= xmlTextWriterWriteElement(m_writer,
++                                                     BAD_CAST element.c_str(),
++                                                     BAD_CAST content.c_str()),
++                      "Unable to write element: " << element << "; content: " << content);
++}
++
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7b41bbf52607f35c276500f06f16eedccdd19455
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,90 @@@
++/*
++ * Copyright (c) 2015 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        dbus_test_busconfig_writer.h
++ * @author      Marcin Niesluchowski <m.niesluchow@samsung.com>
++ * @version     1.0
++ * @brief       dbus test busconfig writer declaration
++ */
++
++#ifndef DBUS_TEST_BUSCONFIG_WRITER
++#define DBUS_TEST_BUSCONFIG_WRITER
++
++#include <libxml/xmlwriter.h>
++
++#include <string>
++#include <vector>
++
++namespace DBusTest {
++
++enum class Attr
++{
++    OWN,
++    OWN_PREFIX,
++
++    SEND_DESTINATION,
++    SEND_PATH,
++    SEND_INTERFACE,
++    SEND_TYPE,
++    SEND_MEMBER,
++    SEND_ERROR,
++
++    RECEIVE_SENDER,
++    RECEIVE_PATH,
++    RECEIVE_INTERFACE,
++    RECEIVE_TYPE,
++    RECEIVE_MEMBER,
++    RECEIVE_ERROR
++};
++
++struct AttrVal
++{
++    Attr attr;
++    std::string val;
++};
++
++extern const std::string VAL_ALL;
++extern const std::string CONF_FILE_PATH;
++
++typedef std::vector<AttrVal> AttrValVec;
++
++class BusConfigWriter
++{
++public:
++    BusConfigWriter();
++    ~BusConfigWriter();
++
++    void addPolicyAllow(const AttrValVec &attrValVec);
++    void addPolicyDeny(const AttrValVec &attrValVec);
++    void addPolicyCheck(const std::string &privilege, const AttrValVec &attrValVec);
++
++    void save();
++
++private:
++    void startElement(const std::string &element);
++    void writeAttribute(const std::string &attr, const std::string &val);
++    void writeAttribute(const AttrVal &attrVal);
++    void endElement();
++    void writeElement(const std::string &element, const std::string &content);
++
++    xmlTextWriterPtr m_writer;
++    xmlDocPtr m_doc;
++    std::string m_filePath;
++};
++
++}
++
++#endif // DBUS_TEST_BUSCONFIG_WRITER
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..548d015ad04eb1f55471621683e65dfac349e634
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,35 @@@
++/*
++ * Copyright (c) 2015 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        dbus_test_commons.cpp
++ * @author      Marcin Niesluchowski <m.niesluchow@samsung.com>
++ * @version     1.0
++ * @brief       commons for dbus test files
++ */
++
++#include <dbus_test_commons.h>
++
++namespace DBusTest
++{
++
++const std::string CONNECTION_NAME_PREFIX("com.security_tests");
++
++const std::string connectionNameFromStr(const std::string &str)
++{
++    return CONNECTION_NAME_PREFIX + "." + str;
++}
++
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..24090635c32fac38e3de2112f4b2e8f01722ccd4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,37 @@@
++/*
++ * Copyright (c) 2015 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        dbus_test_commons.h
++ * @author      Marcin Niesluchowski <m.niesluchow@samsung.com>
++ * @version     1.0
++ * @brief       commons for dbus test files
++ */
++
++#ifndef DBUS_TESTS_COMMON_DBUS_TEST_COMMONS_H
++#define DBUS_TESTS_COMMON_DBUS_TEST_COMMONS_H
++
++#include <string>
++
++namespace DBusTest
++{
++
++extern const std::string CONNECTION_NAME_PREFIX;
++
++const std::string connectionNameFromStr(const std::string &str);
++
++}
++
++#endif // DBUS_TESTS_COMMON_DBUS_TEST_COMMONS_H
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..81da52b764620918266099148f2c591695f0d5f5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,127 @@@
++/*
++ * Copyright (c) 2015 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        dbus_test_service.cpp
++ * @author      Marcin Niesluchowski <m.niesluchow@samsung.com>
++ * @version     1.0
++ * @brief       dbus test service definition
++ */
++
++#include <dbus_test_service.h>
++#include <dbus_test_commons.h>
++
++#include <chrono>
++
++#include <dpl/test/test_runner.h>
++
++namespace {
++
++const std::string OBJECT_PATH_DIR("/com/security_tests/");
++const std::string INTERFACE_SUFFIX("TestInterface");
++
++}
++
++namespace DBusTest
++{
++
++ServiceCreds::ServiceCreds(const std::string &name)
++    : m_connectionName(connectionNameFromStr(name))
++    , m_objectPath(OBJECT_PATH_DIR + name)
++    , m_interface(m_connectionName + "." + INTERFACE_SUFFIX)
++{
++}
++
++const std::string& ServiceCreds::connectionName() const
++{
++    return m_connectionName;
++}
++
++const std::string& ServiceCreds::objectPath() const
++{
++    return m_objectPath;
++}
++
++const std::string& ServiceCreds::interface() const
++{
++    return m_interface;
++}
++
++Service::Service(const ServiceCreds &serviceCreds)
++    : m_connection(DBUS_BUS_SYSTEM, true)
++    , m_object(serviceCreds.interface())
++    , m_messageReceived(false)
++    , m_exceptionThrown(false)
++{
++    m_connection.requestName(serviceCreds.connectionName());
++    m_connection.registerObjectPath(serviceCreds.objectPath(),
++                                    handleMessage,
++                                    (void*)this);
++}
++
++void Service::insertMethodHandler(const std::string &method,
++                                  const MessageHandler &messageHandler)
++{
++    m_object.insertMethodHandler(method, messageHandler);
++}
++
++DBusHandlerResult Service::handleMessage(DBusConnection *connection,
++                                         DBusMessage *message,
++                                         void *userData)
++{
++    Service* service = reinterpret_cast<Service*>(userData);
++    (void)userData;
++    try {
++        service->m_messageReceived = true;
++        DBus::MessageIn messageIn(message, true);
++        DBus::Connection conn(connection);
++        service->m_object.handleMessage(conn, messageIn, service->m_errorString);
++    } catch(...) {
++        service->m_exceptionThrown = true;
++    }
++    return DBUS_HANDLER_RESULT_HANDLED;
++}
++
++void Service::run(bool &finish, bool timeout)
++{
++    using namespace std::chrono;
++    high_resolution_clock::time_point tpEnd = high_resolution_clock::now() + seconds(5);
++    while (!finish) {
++        m_connection.readWrite(1000);
++
++        high_resolution_clock::time_point tp = high_resolution_clock::now();
++        if (tp > tpEnd) {
++            if (timeout)
++                return;
++            RUNNER_FAIL_MSG("Timeout not expected");
++        }
++
++        while(true) {
++            m_errorString.clear();
++            m_exceptionThrown = false;
++
++            m_connection.dispatch();
++            if (!m_messageReceived)
++                break;
++            m_messageReceived = false;
++
++            RUNNER_ASSERT_MSG(!m_exceptionThrown, "Exception thrown while handling message");
++            RUNNER_ASSERT_MSG(m_errorString.empty(), "Error while handling dispatched message. "
++                                                         << m_errorString);
++        }
++    }
++}
++
++} // namespace DBusTest
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bf986df59e645f20bbefa68d28b7fb305388d194
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,78 @@@
++/*
++ * Copyright (c) 2015 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        dbus_test_service.h
++ * @author      Marcin Niesluchowski <m.niesluchow@samsung.com>
++ * @version     1.0
++ * @brief       dbus test service declaration
++ */
++
++#ifndef DBUS_TESTS_COMMON_DBUS_TEST_SERVICE_H
++#define DBUS_TESTS_COMMON_DBUS_TEST_SERVICE_H
++
++#include <dbus_test_service_object.h>
++
++#include <dbus_connection.h>
++
++#include <string>
++
++namespace DBusTest
++{
++
++class ServiceCreds
++{
++public:
++    ServiceCreds(const std::string &name);
++    ~ServiceCreds() = default;
++
++    const std::string& connectionName() const;
++    const std::string& objectPath() const;
++    const std::string& interface() const;
++
++private:
++    std::string m_connectionName;
++    std::string m_objectPath;
++    std::string m_interface;
++};
++
++class Service
++{
++public:
++    Service(const ServiceCreds &serviceCreds);
++    Service(const Service &other) = delete;
++    ~Service() = default;
++
++    Service& operator=(const Service &other) = delete;
++
++    void insertMethodHandler(const std::string &method,
++                             const MessageHandler &messageHandler);
++    void run(bool &finish, bool timeout);
++
++private:
++    static DBusHandlerResult handleMessage(DBusConnection *connection,
++                                           DBusMessage *message,
++                                           void *userData);
++
++    DBus::Connection m_connection;
++    ServiceObject m_object;
++    bool m_messageReceived;
++    bool m_exceptionThrown;
++    std::string m_errorString;
++};
++
++} // namespace DBusTest
++
++#endif // DBUS_TESTS_COMMON_DBUS_TEST_SERVICE_H
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8cc1ca6c990ef3e00f8171afbc747bd387417cac
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,58 @@@
++/*
++ * Copyright (c) 2015 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        dbus_test_service_object.cpp
++ * @author      Marcin Niesluchowski <m.niesluchow@samsungcom>
++ * @version     1.0
++ * @brief       Definition of dbus test service object class for handling
++ *              incoming messages
++ */
++
++#include <dbus_test_service_object.h>
++
++namespace DBusTest
++{
++
++ServiceObject::ServiceObject(const std::string &interface)
++    : m_interface(interface)
++{
++}
++
++const std::string& ServiceObject::interface() const
++{
++    return m_interface;
++}
++
++void ServiceObject::insertMethodHandler(const std::string &method,
++                                        const MessageHandler &messageHandler)
++{
++    m_methodHandlers[method] = messageHandler;
++}
++
++void ServiceObject::handleMessage(DBus::Connection &connection,
++                                  DBus::MessageIn &messageIn,
++                                  std::string &errorStr)
++{
++    for (auto &methodHandler : m_methodHandlers) {
++        if (messageIn.isMethodCall(m_interface, methodHandler.first)) {
++            methodHandler.second(connection, messageIn, errorStr);
++            return;
++        }
++    }
++    errorStr = "Received unregistered message";
++}
++
++} // namespace DBusTest
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d2692c25002e8e9dd28d5d4207a0382689782bd3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,64 @@@
++/*
++ * Copyright (c) 2015 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        dbus_test_service_object.h
++ * @author      Marcin Niesluchowski <m.niesluchow@samsungcom>
++ * @version     1.0
++ * @brief       Declaration of dbus test service object class for handling
++ *              incoming messages
++ */
++
++#ifndef DBUS_TESTS_COMMON_DBUS_TEST_SERVICE_OBJECT_H
++#define DBUS_TESTS_COMMON_DBUS_TEST_SERVICE_OBJECT_H
++
++#include <dbus_connection.h>
++#include <dbus_message_in.h>
++
++#include <functional>
++#include <map>
++#include <string>
++
++namespace DBusTest
++{
++
++using MessageHandler = std::function<void(DBus::Connection &connection,
++                                          DBus::MessageIn &messageIn,
++                                          std::string &errorStr)>;
++
++class ServiceObject
++{
++public:
++    ServiceObject(const std::string &interface);
++    ServiceObject(const ServiceObject &other) = delete;
++    ~ServiceObject() = default;
++
++    ServiceObject& operator=(const ServiceObject &other) = delete;
++
++    const std::string& interface() const;
++    void insertMethodHandler(const std::string &method,
++                             const MessageHandler &messageHandler);
++    void handleMessage(DBus::Connection &connection,
++                       DBus::MessageIn &messageIn,
++                       std::string &errorStr);
++
++private:
++    std::map<std::string, MessageHandler> m_methodHandlers;
++    std::string m_interface;
++};
++
++} // namespace DBusTest
++
++#endif // DBUS_TESTS_COMMON_DBUS_TEST_SERVICE_OBJECT_H
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0cbd8fc710b05c9f372eee7e8180f6a30db95463
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,671 @@@
++/*
++ * Copyright (c) 2015 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        cynara_dbus_tests.cpp
++ * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
++ * @version     1.0
++ * @brief       Tests for cynara checks implemented in dbus
++ */
++
++#include <dpl/test/test_runner.h>
++#include <dpl/test/test_runner_child.h>
++
++#include <cynara_test_admin.h>
++#include <dbus_connection.h>
++#include <dbus_message_out.h>
++#include <dbus_test_busconfig_writer.h>
++#include <dbus_test_commons.h>
++#include <dbus_test_service.h>
++#include <smack_access.h>
++#include <tests_common.h>
++
++#include <dbus/dbus.h>
++#include <sys/smack.h>
++
++#include <string>
++#include <unistd.h>
++#include <iostream>
++
++using namespace DBusTest;
++
++static const std::string ROOT_UID_STR("0");
++static const std::string MESSSAGE_TYPE_METHOD_CALL = "method_call";
++static const std::string MESSSAGE_TYPE_ERROR = "error";
++
++static const std::string clientIdFromStr(const std::string &str)
++{
++    return str + "Client";
++}
++
++static const std::string serviceIdFromStr(const std::string &str)
++{
++    return str + "Service";
++}
++
++static const std::string memberFromStr(const std::string &str)
++{
++    return str + "Member";
++}
++
++static const std::string privilegeFromStr(const std::string &str)
++{
++    return str + "Privilege";
++}
++
++static const std::string smackLabelFromStr(const std::string &str)
++{
++    return str + "SmackLabel";
++}
++
++static const std::string errorFromStr(const std::string &interface, const std::string &str)
++{
++    return interface + ".Error.Err" + str;
++}
++
++static void addBusconfigPolicyOwn(const std::string &id)
++{
++    BusConfigWriter writer;
++    writer.addPolicyCheck(privilegeFromStr(id), {{Attr::OWN, connectionNameFromStr(id)}});
++    writer.save();
++}
++
++static void assertUnlink(const std::string &filePath)
++{
++    RUNNER_ASSERT_MSG(0 == unlink(filePath.c_str()), "Unable to unlink " << filePath << " file");
++}
++
++static void addCynaraPolicy(const std::string &id)
++{
++    CynaraTestAdmin::Admin admin;
++    CynaraTestAdmin::CynaraPoliciesContainer cp;
++    cp.add(CYNARA_ADMIN_DEFAULT_BUCKET,
++           smackLabelFromStr(id).c_str(), ROOT_UID_STR.c_str(), privilegeFromStr(id).c_str(),
++           CYNARA_ADMIN_ALLOW, nullptr);
++    admin.setPolicies(cp);
++}
++
++static void addSmackAccessForDbus(SmackAccess &access, const std::string &label)
++{
++    access.add("System", label, "rx");
++    access.apply();
++}
++
++static void removeSmackAccessForDbus(SmackAccess &access)
++{
++    access.clear();
++}
++
++static pid_t assertFork()
++{
++    pid_t pid = fork();
++    RUNNER_ASSERT_ERRNO_MSG(pid != -1, "fork() failed");
++    return pid;
++}
++
++RUNNER_TEST_GROUP_INIT(CYNARA_DBUS);
++
++static void testOwn(const std::string &testId,
++                    const std::function<void(const std::string &)> &addBusconfigPolicyFunc,
++                    bool allow)
++{
++    SmackAccess access;
++    const std::string label(smackLabelFromStr(testId));
++
++    addBusconfigPolicyFunc(testId);
++    addSmackAccessForDbus(access, label);
++    if (allow)
++        addCynaraPolicy(testId);
++
++    sleep(1);
++
++    pid_t pid = assertFork();
++
++    if (pid == 0) {
++        RUNNER_ASSERT(0 == smack_set_label_for_self(label.c_str()));
++        DBus::Connection client(DBUS_BUS_SYSTEM, true);
++        client.requestName(connectionNameFromStr(testId),
++                           allow ? DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER : -1);
++    } else {
++        sleep(3);
++        removeSmackAccessForDbus(access);
++        assertUnlink(CONF_FILE_PATH);
++    }
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_1130_own_deny)
++{
++    testOwn("tcc1130", addBusconfigPolicyOwn, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_1170_own_allow)
++{
++    testOwn("tcc1170", addBusconfigPolicyOwn, true);
++}
++
++static void addBusconfigPolicyOwnPrefix(const std::string &id)
++{
++    BusConfigWriter writer;
++    writer.addPolicyCheck(privilegeFromStr(id), {{Attr::OWN_PREFIX, CONNECTION_NAME_PREFIX}});
++    writer.save();
++}
++
++RUNNER_CHILD_TEST_SMACK(tcc_1230_own_prefix_deny)
++{
++    testOwn("tcc1230", addBusconfigPolicyOwnPrefix, false);
++}
++
++RUNNER_CHILD_TEST_SMACK(tcc_1270_own_prefix_allow)
++{
++    testOwn("tcc1270", addBusconfigPolicyOwnPrefix, true);
++}
++
++static void addBusconfigPolicySendAllows(BusConfigWriter &writer)
++{
++    writer.addPolicyAllow({{Attr::OWN_PREFIX, CONNECTION_NAME_PREFIX}});
++    writer.addPolicyAllow({{Attr::RECEIVE_TYPE, MESSSAGE_TYPE_METHOD_CALL}});
++}
++
++static void addBusconfigPolicySendDestination(const std::string &testId)
++{
++    BusConfigWriter writer;
++    addBusconfigPolicySendAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(clientIdFromStr(testId)),
++                          {{Attr::SEND_DESTINATION, connectionNameFromStr(serviceIdFromStr(testId))}});
++    writer.save();
++}
++
++static void runMessageClient(const std::string &testId, bool changeLabel)
++{
++    const std::string clientId(clientIdFromStr(testId));
++    const std::string serviceId(serviceIdFromStr(testId));
++    const ServiceCreds serviceCreds(serviceId);
++
++    sleep(1);
++
++    if (changeLabel)
++        RUNNER_ASSERT(0 == smack_set_label_for_self(smackLabelFromStr(clientId).c_str()));
++    DBus::Connection client(DBUS_BUS_SYSTEM, true);
++    client.requestName(connectionNameFromStr(clientId));
++
++    DBus::MessageOut messageOut(serviceCreds.connectionName(),
++                                serviceCreds.objectPath(),
++                                serviceCreds.interface(),
++                                memberFromStr(serviceId));
++    client.send(messageOut);
++    client.flush();
++
++    sleep(1);
++}
++
++static void runMessageService(const std::string &testId, bool changeLabel,
++                              const std::string &errorStr, bool allow)
++{
++    const std::string clientId(clientIdFromStr(testId));
++    const std::string serviceId(serviceIdFromStr(testId));
++    const std::string member(memberFromStr(serviceId));
++    const ServiceCreds serviceCreds(serviceId);
++
++    if (changeLabel)
++        RUNNER_ASSERT(0 == smack_set_label_for_self(smackLabelFromStr(serviceId).c_str()));
++
++    Service service(serviceCreds);
++    bool finish = false;
++    if (allow) {
++        service.insertMethodHandler(
++            member,
++            [&] (DBus::Connection &connection,
++                 DBus::MessageIn &messageIn,
++                 std::string &errorMessage)->void {
++                    (void) connection;
++                    (void) messageIn;
++                    (void) errorMessage;
++                    finish = true;
++                });
++    } else {
++        service.insertMethodHandler(
++            member,
++            [&] (DBus::Connection &connection,
++                 DBus::MessageIn &messageIn,
++                 std::string &errorMessage)->void {
++                    (void) connection;
++                    (void) messageIn;
++                    errorMessage = errorStr;
++                });
++    }
++    service.run(finish, !allow);
++
++    assertUnlink(CONF_FILE_PATH);
++}
++
++static void testSend(const std::string &testId,
++                     const std::function<void(const std::string &)> addBusconfigPolicyFunc,
++                     bool allow)
++{
++    SmackAccess access;
++    const std::string clientId(clientIdFromStr(testId));
++    const std::string serviceId(serviceIdFromStr(testId));
++
++    addBusconfigPolicyFunc(testId);
++    addSmackAccessForDbus(access, smackLabelFromStr(clientId));
++    if (allow)
++        addCynaraPolicy(clientId);
++
++    sleep(1);
++
++    pid_t pid = assertFork();
++    if (pid == 0)
++        runMessageClient(testId, true);
++    else
++        runMessageService(testId, false,
++                          "Should not be able to send to " + connectionNameFromStr(serviceId),
++                          allow);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2130_send_destination_deny)
++{
++    testSend("tcc2130", addBusconfigPolicySendDestination, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2170_send_destination_allow)
++{
++    testSend("tcc2170", addBusconfigPolicySendDestination, true);
++}
++
++static void addBusconfigPolicySendPath(const std::string &testId)
++{
++    const ServiceCreds serviceCreds(serviceIdFromStr(testId));
++    BusConfigWriter writer;
++    addBusconfigPolicySendAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(clientIdFromStr(testId)),
++                          {{Attr::SEND_DESTINATION, serviceCreds.connectionName()},
++                           {Attr::SEND_PATH, serviceCreds.objectPath()}});
++    writer.save();
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2230_send_path_deny)
++{
++    testSend("tcc2230", addBusconfigPolicySendPath, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2270_send_path_allow)
++{
++    testSend("tcc2270", addBusconfigPolicySendPath, true);
++}
++
++static void addBusconfigPolicySendInterface(const std::string &testId)
++{
++    const ServiceCreds serviceCreds(serviceIdFromStr(testId));
++    BusConfigWriter writer;
++    addBusconfigPolicySendAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(clientIdFromStr(testId)),
++                          {{Attr::SEND_DESTINATION, serviceCreds.connectionName()},
++                           {Attr::SEND_INTERFACE, serviceCreds.interface()}});
++    writer.save();
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2330_send_interface_deny)
++{
++    testSend("tcc2330", addBusconfigPolicySendInterface, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2370_send_interface_allow)
++{
++    testSend("tcc2370", addBusconfigPolicySendInterface, true);
++}
++
++static void addBusconfigPolicySendType(const std::string &testId)
++{
++    const ServiceCreds serviceCreds(serviceIdFromStr(testId));
++    BusConfigWriter writer;
++    addBusconfigPolicySendAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(clientIdFromStr(testId)),
++                          {{Attr::SEND_DESTINATION, serviceCreds.connectionName()},
++                           {Attr::SEND_TYPE, MESSSAGE_TYPE_METHOD_CALL}});
++    writer.save();
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2430_send_type_deny)
++{
++    testSend("tcc2430", addBusconfigPolicySendType, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2470_send_type_allow)
++{
++    testSend("tcc2470", addBusconfigPolicySendType, true);
++}
++
++static void addBusconfigPolicySendMember(const std::string &testId)
++{
++    const std::string serviceId = serviceIdFromStr(testId);
++    const ServiceCreds serviceCreds(serviceId);
++    BusConfigWriter writer;
++    addBusconfigPolicySendAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(clientIdFromStr(testId)),
++                          {{Attr::SEND_DESTINATION, serviceCreds.connectionName()},
++                           {Attr::SEND_INTERFACE, serviceCreds.interface()},
++                           {Attr::SEND_MEMBER, memberFromStr(serviceId)}});
++    writer.save();
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2530_send_member_deny)
++{
++    testSend("tcc2530", addBusconfigPolicySendMember, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2570_send_member_allow)
++{
++    testSend("tcc2570", addBusconfigPolicySendMember, true);
++}
++
++static void addBusconfigPolicySendError(const std::string &testId)
++{
++    const std::string serviceId(serviceIdFromStr(testId));
++    const ServiceCreds serviceCreds(serviceId);
++    BusConfigWriter writer;
++    addBusconfigPolicySendAllows(writer);
++    writer.addPolicyAllow({{Attr::RECEIVE_TYPE, MESSSAGE_TYPE_ERROR}});
++    writer.addPolicyAllow({{Attr::SEND_TYPE, MESSSAGE_TYPE_ERROR}});
++    writer.addPolicyAllow({{Attr::SEND_TYPE, MESSSAGE_TYPE_METHOD_CALL}});
++    writer.addPolicyAllow({{Attr::SEND_DESTINATION, serviceCreds.connectionName()}});
++    writer.addPolicyCheck(privilegeFromStr(serviceId),
++                          {{Attr::SEND_DESTINATION, connectionNameFromStr(clientIdFromStr(testId))},
++                           {Attr::SEND_ERROR, errorFromStr(serviceCreds.interface(), serviceId)}});
++    writer.save();
++}
++
++static void runClientError(const std::string &testId, bool changeLabel, bool allow)
++{
++    const std::string clientId(clientIdFromStr(testId));
++    const std::string serviceId(serviceIdFromStr(testId));
++    const ServiceCreds serviceCreds(serviceId);
++
++    sleep(1);
++
++    if (changeLabel)
++        RUNNER_ASSERT(0 == smack_set_label_for_self(smackLabelFromStr(clientId).c_str()));
++    DBus::Connection client(DBUS_BUS_SYSTEM, true);
++    client.requestName(connectionNameFromStr(clientId));
++
++    DBus::MessageOut messageOut(serviceCreds.connectionName(),
++                                serviceCreds.objectPath(),
++                                serviceCreds.interface(),
++                                memberFromStr(serviceId));
++
++    DBusError error;
++    dbus_error_init(&error);
++    DBus::ErrorPtr errorPtr(&error);
++
++    DBusMessage* message = client.sendWithReplyAndBlock(messageOut,
++                                                        4000,
++                                                        &error);
++    if (message != nullptr) {
++        DBus::MessageIn messageIn(message);
++        RUNNER_FAIL_MSG("message received is null");
++    }
++
++    std::string expectedErrorName;
++    if (allow)
++        expectedErrorName = errorFromStr(serviceCreds.interface(), serviceId);
++    else
++        expectedErrorName = "org.freedesktop.DBus.Error.NoReply";
++
++    RUNNER_ASSERT_MSG(expectedErrorName == error.name,
++                      "Wrong error received."
++                          << "\n Expected error name: " << expectedErrorName
++                          << "\n Received error name: " << error.name
++                          << "\n Received error message: " << error.message);
++
++    assertUnlink(CONF_FILE_PATH);
++}
++
++static void runServiceError(const std::string &testId, bool changeLabel)
++{
++    const std::string clientId(clientIdFromStr(testId));
++    const std::string serviceId(serviceIdFromStr(testId));
++    const ServiceCreds serviceCreds(serviceId);
++
++    if (changeLabel)
++        RUNNER_ASSERT(0 == smack_set_label_for_self(smackLabelFromStr(serviceId).c_str()));
++
++    Service service(serviceCreds);
++    bool finish = false;
++    service.insertMethodHandler(
++        memberFromStr(serviceId),
++        [&] (DBus::Connection &connection,
++             DBus::MessageIn &messageIn,
++             std::string &errorMessage)->void {
++                DBus::MessageOut messageOut(messageIn.getMessage(),
++                                            errorFromStr(serviceCreds.interface(), serviceId),
++                                            "Security-tests error message");
++                connection.send(messageOut);
++                connection.flush();
++                (void) errorMessage;
++                finish = true;
++             });
++    service.run(finish, false);
++
++    sleep(2);
++}
++
++static void testSendError(const std::string &testId, bool allow)
++{
++    const std::string serviceId(serviceIdFromStr(testId));
++    SmackAccess access;
++    addBusconfigPolicySendError(testId);
++    addSmackAccessForDbus(access, smackLabelFromStr(serviceId));
++    if (allow)
++        addCynaraPolicy(serviceId);
++
++    sleep(1);
++
++    pid_t pid = assertFork();
++    if (pid == 0) {
++        runServiceError(testId, true);
++    } else {
++        runClientError(testId, false, allow);
++    }
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2630_send_error_deny)
++{
++    testSendError("tcc2630", false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_2670_send_error_allow)
++{
++    testSendError("tcc2670", true);
++}
++
++static void addBusconfigPolicyReceiveAllows(BusConfigWriter &writer)
++{
++    writer.addPolicyAllow({{Attr::OWN_PREFIX, CONNECTION_NAME_PREFIX}});
++    writer.addPolicyAllow({{Attr::SEND_TYPE, MESSSAGE_TYPE_METHOD_CALL}});
++}
++
++static void addBusconfigPolicyReceiveSender(const std::string &testId)
++{
++    BusConfigWriter writer;
++    addBusconfigPolicyReceiveAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(serviceIdFromStr(testId)),
++                          {{Attr::RECEIVE_SENDER, connectionNameFromStr(clientIdFromStr(testId))}});
++    writer.save();
++}
++
++static void testReceive(const std::string &testId,
++                        const std::function<void(const std::string &)> addBusconfigPolicyFunc,
++                        bool allow)
++{
++    const std::string clientId(clientIdFromStr(testId));
++    const std::string serviceId(serviceIdFromStr(testId));
++    addBusconfigPolicyFunc(testId);
++    SmackAccess access;
++    addSmackAccessForDbus(access, smackLabelFromStr(serviceId));
++    if (allow)
++        addCynaraPolicy(serviceId);
++
++    sleep(1);
++
++    pid_t pid = assertFork();
++    if (pid == 0)
++        runMessageService(testId, true,
++                          "Should not be able to receive from " + connectionNameFromStr(clientId),
++                          allow);
++    else
++        runMessageClient(testId, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3130_receive_sender_deny)
++{
++    testReceive("tcc3130", addBusconfigPolicyReceiveSender, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3170_receive_sender_allow)
++{
++    testReceive("tcc3170", addBusconfigPolicyReceiveSender, true);
++}
++
++static void addBusconfigPolicyReceivePath(const std::string &testId)
++{
++    const ServiceCreds serviceCreds(serviceIdFromStr(testId));
++    BusConfigWriter writer;
++    addBusconfigPolicyReceiveAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(serviceIdFromStr(testId)),
++                          {{Attr::RECEIVE_SENDER, connectionNameFromStr(clientIdFromStr(testId))},
++                           {Attr::RECEIVE_PATH, serviceCreds.objectPath()}});
++    writer.save();
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3230_receive_path_deny)
++{
++    testReceive("tcc3230", addBusconfigPolicyReceivePath, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3270_receive_path_allow)
++{
++    testReceive("tcc3270", addBusconfigPolicyReceivePath, true);
++}
++
++static void addBusconfigPolicyReceiveInterface(const std::string &testId)
++{
++    const ServiceCreds serviceCreds(serviceIdFromStr(testId));
++    BusConfigWriter writer;
++    addBusconfigPolicyReceiveAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(serviceIdFromStr(testId)),
++                          {{Attr::RECEIVE_SENDER, connectionNameFromStr(clientIdFromStr(testId))},
++                           {Attr::RECEIVE_INTERFACE, serviceCreds.interface()}});
++    writer.save();
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3330_receive_interface_deny)
++{
++    testReceive("tcc3330", addBusconfigPolicyReceiveInterface, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3370_receive_interface_allow)
++{
++    testReceive("tcc3370", addBusconfigPolicyReceiveInterface, true);
++}
++
++static void addBusconfigPolicyReceiveType(const std::string &testId)
++{
++    BusConfigWriter writer;
++    addBusconfigPolicyReceiveAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(serviceIdFromStr(testId)),
++                          {{Attr::RECEIVE_SENDER, connectionNameFromStr(clientIdFromStr(testId))},
++                           {Attr::RECEIVE_TYPE, MESSSAGE_TYPE_METHOD_CALL}});
++    writer.save();
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3430_receive_type_deny)
++{
++    testReceive("tcc3430", addBusconfigPolicyReceiveType, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3470_receive_interface_allow)
++{
++    testReceive("tcc3470", addBusconfigPolicyReceiveType, true);
++}
++
++static void addBusconfigPolicyReceiveMember(const std::string &testId)
++{
++    const std::string serviceId(serviceIdFromStr(testId));
++    const ServiceCreds serviceCreds(serviceId);
++    BusConfigWriter writer;
++    addBusconfigPolicyReceiveAllows(writer);
++    writer.addPolicyCheck(privilegeFromStr(serviceId),
++                          {{Attr::RECEIVE_SENDER, connectionNameFromStr(clientIdFromStr(testId))},
++                           {Attr::RECEIVE_INTERFACE, serviceCreds.interface()},
++                           {Attr::RECEIVE_MEMBER, memberFromStr(serviceId)}});
++    writer.save();
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3530_receive_member_deny)
++{
++    testReceive("tcc3530", addBusconfigPolicyReceiveMember, false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3570_receive_member_allow)
++{
++    testReceive("tcc3570", addBusconfigPolicyReceiveMember, true);
++}
++
++static void addBusconfigPolicyReceiveError(const std::string &testId)
++{
++    const std::string clientId(clientIdFromStr(testId));
++    const std::string serviceId(serviceIdFromStr(testId));
++    const ServiceCreds serviceCreds(serviceId);
++    BusConfigWriter writer;
++    addBusconfigPolicyReceiveAllows(writer);
++    writer.addPolicyAllow({{Attr::SEND_TYPE, MESSSAGE_TYPE_ERROR}});
++    writer.addPolicyAllow({{Attr::RECEIVE_TYPE, MESSSAGE_TYPE_ERROR}});
++    writer.addPolicyAllow({{Attr::RECEIVE_TYPE, MESSSAGE_TYPE_METHOD_CALL}});
++    writer.addPolicyAllow({{Attr::SEND_DESTINATION, serviceCreds.connectionName()}});
++    writer.addPolicyAllow({{Attr::SEND_DESTINATION, connectionNameFromStr(clientId)}});
++    writer.addPolicyCheck(privilegeFromStr(clientId),
++                          {{Attr::RECEIVE_SENDER, serviceCreds.connectionName()},
++                           {Attr::RECEIVE_ERROR, errorFromStr(serviceCreds.interface(), serviceId)}});
++    writer.save();
++}
++
++static void testReceiveError(const std::string &testId, bool allow)
++{
++    const std::string clientId(clientIdFromStr(testId));
++    addBusconfigPolicyReceiveError(testId);
++    SmackAccess access;
++    addSmackAccessForDbus(access, smackLabelFromStr(clientId));
++    if (allow)
++        addCynaraPolicy(clientId);
++
++    sleep(1);
++
++    pid_t pid = assertFork();
++    if (pid == 0) {
++        runClientError(testId, true, allow);
++    } else {
++        runServiceError(testId, false);
++    }
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3630_receive_error_deny)
++{
++    testReceiveError("tcc3630", false);
++}
++
++RUNNER_MULTIPROCESS_TEST_SMACK(tcc_3670_receive_error_allow)
++{
++    testReceiveError("tcc3670", true);
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8d2261b7f71d9ade82e38bf2392f646e2fe098bf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,29 @@@
++/*
++ * 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        main.cpp
++ * @author      Marcin Niesluchowski (m.niesluchow@samsung.com)
++ * @version     1.0
++ * @brief       main for dbus tests
++ */
++
++#include <dpl/test/test_runner.h>
++
++int main(int argc, char *argv[])
++{
++    return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
++}
index 0000000000000000000000000000000000000000,233994e863e3afa9cd4420cb506a98b9a677c9eb..a17b5431e822c905f8e9b1c96e5207caef1d3d22
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,305 +1,300 @@@
 -RUNNER_MULTIPROCESS_TEST_SMACK(tc01_smack_context_from_DBus)
+ #include <cstring>
+ #include <unistd.h>
+ #include <sys/smack.h>
+ #include <dpl/test/test_runner.h>
+ #include <dpl/test/test_runner_multiprocess.h>
+ #include <dbus/dbus.h>
+ #include "tests_common.h"
+ #define DBUS_SERVER_NAME                        "test.method.server"
+ #define DBUS_CALLER_NAME                        "test.method.caller"
+ #define DBUS_SMACK_NAME                         "org.freedesktop.DBus"
+ #define DBUS_SMACK_OBJECT                       "/org/freedesktop/DBus"
+ #define DBUS_SMACK_INTERFACE                    "org.freedesktop.DBus"
+ #define DBUS_SMACK_METHOD                       "GetConnectionCredentials"
+ RUNNER_TEST_GROUP_INIT(SMACK_DBUS);
 -RUNNER_MULTIPROCESS_TEST_NOSMACK(tc01_smack_context_from_DBus_nosmack)
++RUNNER_MULTIPROCESS_TEST_SMACK(tcs_01_smack_context_from_DBus)
+ {
+     RUNNER_IGNORED_MSG("dbus does not support smack context in GetConnectionCredentials method"
+                        " yet.");
+     int ret = -1;
+     const char *subject_parent = "subject_parent";
+     const char *subject_child = "subject_child";
+     DBusMessage* msg = nullptr;
+     DBusMessageIter args, iter, var, var_iter, var_value;
+     DBusConnection* conn = nullptr;
+     DBusError err;
+     DBusPendingCall *pending = nullptr;
+     const char *dbus_server_name = DBUS_SERVER_NAME;
+     char *smack_context = nullptr;
+     pid_t pid = fork();
+     RUNNER_ASSERT_ERRNO_MSG(-1 != pid, "fork() failed");
+     if (pid == 0) {
+         // child
+         ret = smack_set_label_for_self(subject_child);
+         RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
+             "smack_set__label_for_self() failed, ret: " << ret);
+         // initialize the errors
+         dbus_error_init(&err);
+         // connect to the system bus and check for errors
+         conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+         ret = dbus_error_is_set(&err);
+         if (1 == ret) {
+             dbus_error_free(&err);
+             RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret);
+         }
+         // request our name on the bus
+         ret = dbus_bus_request_name(conn, DBUS_CALLER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+         if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+         dbus_error_free(&err);
+         RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
+             "dbus_bus_request_name() failed, ret: " << ret);
+         }
+         // crate a new method call for checking SMACK context from DBus interface
+         msg = dbus_message_new_method_call(DBUS_SMACK_NAME,
+                                            DBUS_SMACK_OBJECT,
+                                            DBUS_SMACK_INTERFACE,
+                                            DBUS_SMACK_METHOD);
+         RUNNER_ASSERT_MSG(nullptr != msg,
+             "dbus_message_new_method_call() failed, ret: " << ret);
+         // append arguments, we need SMACK context for our parent process "test.method.server"
+         dbus_message_iter_init_append(msg, &args);
+         ret = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &dbus_server_name);
+         RUNNER_ASSERT_MSG(1 == ret, "Out of memory");
+         // wait for parent to connect to DBus
+         sleep(3);
+         // send message and get a handle for a reply
+         // -1 is default timeout
+         ret = dbus_connection_send_with_reply (conn, msg, &pending, -1);
+         RUNNER_ASSERT_MSG(1 == ret, "Out of memory");
+         RUNNER_ASSERT_MSG(nullptr != pending, "Pending call null");
+         dbus_connection_flush(conn);
+         // free message
+         dbus_message_unref(msg);
+         // block until reply
+         dbus_pending_call_block(pending);
+         // get the reply
+         msg = dbus_pending_call_steal_reply(pending);
+         RUNNER_ASSERT_MSG(nullptr != msg, "Reply null");
+         // free message handle
+         dbus_pending_call_unref(pending);
+         ret = dbus_message_iter_init(msg, &iter);
+         RUNNER_ASSERT_MSG(0 != ret, "Message has no arguments");
+         dbus_message_iter_recurse(&iter, &var);
+         while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) {
+             dbus_message_iter_recurse(&var, &var_iter);
+             while(dbus_message_iter_get_arg_type(&var_iter) != DBUS_TYPE_INVALID) {
+                 dbus_message_iter_recurse(&var_iter, &var_value);
+                 switch(dbus_message_iter_get_arg_type(&var_value)) {
+                     case DBUS_TYPE_STRING:
+                         dbus_message_iter_get_basic(&var_value, &smack_context);
+                         break;
+                     default:
+                         ;
+                 }
+                 dbus_message_iter_next(&var_iter);
+             }
+             dbus_message_iter_next(&var);
+         }
+         // free reply and close connection
+         dbus_message_unref(msg);
+         dbus_connection_unref(conn);
+         RUNNER_ASSERT(smack_context != nullptr);
+         ret = strcmp(smack_context, subject_parent);
+         RUNNER_ASSERT_MSG(0 == ret,
+             "Context mismatch! context from dbus: " << smack_context);
+         exit(0);
+     } else {
+         // parent
+         ret = smack_set_label_for_self(subject_parent);
+         RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
+             "smack_set_label_for_self() failed, ret: " << ret);
+         // initialise the error
+         dbus_error_init(&err);
+         // connect to the bus and check for errors
+         conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+         ret = dbus_error_is_set(&err);
+         if (1 == ret) {
+             dbus_error_free(&err);
+             RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret);
+         }
+         // request our name on the bus and check for errors
+         ret = dbus_bus_request_name(conn, DBUS_SERVER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+         if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+             dbus_error_free(&err);
+             RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
+                 "dbus_bus_request_name() failed, ret: " << ret);
+         }
+         // close the connection
+         dbus_connection_unref(conn);
+     }
+ }
+ ///////////////////////////////////////
+ //////NOSMACK ENV TESTS////////////////
+ ///////////////////////////////////////
 -
 -int main(int argc, char *argv[])
 -{
 -    return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
 -}
++RUNNER_MULTIPROCESS_TEST_NOSMACK(tcs_01_smack_context_from_DBus_nosmack)
+ {
+     RUNNER_IGNORED_MSG("dbus does not support smack context in GetConnectionCredentials method"
+                        " yet.");
+     int ret = -1;
+     const char* subject_parent = "subject_parent";
+     DBusMessage* msg = nullptr;
+     DBusMessageIter args, iter, var, var_iter, var_value;
+     DBusConnection* conn = nullptr;
+     DBusError err;
+     DBusPendingCall *pending = nullptr;
+     const char *dbus_server_name = DBUS_SERVER_NAME;
+     char *smack_context = nullptr;
+     pid_t pid = fork();
+     RUNNER_ASSERT_ERRNO_MSG(-1 != pid, "fork() failed");
+     if (pid == 0) {
+         // child
+         // initialize the errors
+         dbus_error_init(&err);
+         // connect to the system bus and check for errors; failure = exit with result 1
+         conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+         ret = dbus_error_is_set(&err);
+         if (1 == ret) {
+             dbus_error_free(&err);
+             RUNNER_FAIL_MSG("Failed to connect to system bus. Ret " << ret);
+         }
+         // request our name on the bus; failure = exit with result 2
+         ret = dbus_bus_request_name(conn, DBUS_CALLER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+         if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+             dbus_error_free(&err);
+             RUNNER_FAIL_MSG("Failed to request name on the bus. Ret " << ret);
+         }
+         // crate a new method call for checking SMACK context from DBus interface
+         msg = dbus_message_new_method_call(DBUS_SMACK_NAME,
+                                            DBUS_SMACK_OBJECT,
+                                            DBUS_SMACK_INTERFACE,
+                                            DBUS_SMACK_METHOD);
+         RUNNER_ASSERT_MSG(msg != nullptr, "dbus_message_new_method_call() failed.");
+         // append arguments, we need SMACK context for our parent process "test.method.server"
+         dbus_message_iter_init_append(msg, &args);
+         ret = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &dbus_server_name);
+         RUNNER_ASSERT_MSG(ret == 1, "Out of memory. Ret " << ret);
+         // wait for parent to connect to DBus
+         sleep(3);
+         // send message and get a handle for a reply
+         // -1 is default timeout
+         ret = dbus_connection_send_with_reply (conn, msg, &pending, -1);
+         RUNNER_ASSERT_MSG(ret == 1, "Out of memory. Ret " << ret);
+         RUNNER_ASSERT_MSG(pending != nullptr, "Pending call is nullptr.");
+         dbus_connection_flush(conn);
+         // free message
+         dbus_message_unref(msg);
+         // block until reply
+         dbus_pending_call_block(pending);
+         // get the reply
+         msg = dbus_pending_call_steal_reply(pending);
+         RUNNER_ASSERT_MSG(msg != nullptr, "Failed to get the reply from bus.");
+         // free message handle
+         dbus_pending_call_unref(pending);
+         ret = dbus_message_iter_init(msg, &iter);
+         RUNNER_ASSERT_MSG(ret != 0, "DBus message has no arguments. Ret " << ret);
+         dbus_message_iter_recurse(&iter, &var);
+         while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) {
+             dbus_message_iter_recurse(&var, &var_iter);
+             while(dbus_message_iter_get_arg_type(&var_iter) != DBUS_TYPE_INVALID) {
+                 dbus_message_iter_recurse(&var_iter, &var_value);
+                 switch(dbus_message_iter_get_arg_type(&var_value)) {
+                     case DBUS_TYPE_STRING:
+                         dbus_message_iter_get_basic(&var_value, &smack_context);
+                         break;
+                     default:
+                         ;
+                 }
+                 dbus_message_iter_next(&var_iter);
+             }
+             dbus_message_iter_next(&var);
+         }
+         // free reply and close connection
+         dbus_message_unref(msg);
+         dbus_connection_unref(conn);
+         RUNNER_ASSERT(smack_context != nullptr);
+         ret = strcmp(smack_context, subject_parent);
+         RUNNER_ASSERT_MSG(ret == 0, "Context mismatch. Context " << smack_context);
+         exit(0);
+     } else {
+         // parent
+         // initialise the error
+         dbus_error_init(&err);
+         // connect to the bus and check for errors
+         conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+         ret = dbus_error_is_set(&err);
+         if (1 == ret) {
+             dbus_error_free(&err);
+             RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret);
+         }
+         // request our name on the bus and check for errors
+         ret = dbus_bus_request_name(conn, DBUS_SERVER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+         if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+             dbus_error_free(&err);
+             RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
+                 "dbus_bus_request_name() failed, ret: " << ret);
+         }
+         // close the connection
+         dbus_connection_unref(conn);
+     }
+ }