From a41af0d1e2a95773389dcf6a67c2213b1e6debc1 Mon Sep 17 00:00:00 2001 From: Radoslaw Bartosiak Date: Wed, 3 Sep 2014 21:48:25 +0200 Subject: [PATCH 01/16] Prepare libcynara-creds-dbus for implementation Change-Id: Ibdecf8790b7d296e35c063c52202a4a672ad9e9a --- src/helpers/creds-dbus/CMakeLists.txt | 1 + src/helpers/creds-dbus/creds-dbus-inner.cpp | 58 +++++++++++++ src/helpers/creds-dbus/creds-dbus-inner.h | 39 +++++++++ src/helpers/creds-dbus/creds-dbus.cpp | 51 +++++++++++- src/include/cynara-creds-dbus.h | 125 +++++++++++++++++++++++++++- 5 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 src/helpers/creds-dbus/creds-dbus-inner.cpp create mode 100644 src/helpers/creds-dbus/creds-dbus-inner.h diff --git a/src/helpers/creds-dbus/CMakeLists.txt b/src/helpers/creds-dbus/CMakeLists.txt index 4e19a8b..c80d301 100644 --- a/src/helpers/creds-dbus/CMakeLists.txt +++ b/src/helpers/creds-dbus/CMakeLists.txt @@ -25,6 +25,7 @@ SET(LIB_CREDS_DBUS_PATH ${CYNARA_PATH}/helpers/creds-dbus) SET(LIB_CREDS_DBUS_SOURCES ${LIB_CREDS_DBUS_PATH}/creds-dbus.cpp + ${LIB_CREDS_DBUS_PATH}/creds-dbus-inner.cpp ) PKG_CHECK_MODULES(LIB_CREDS_DBUS_DEP diff --git a/src/helpers/creds-dbus/creds-dbus-inner.cpp b/src/helpers/creds-dbus/creds-dbus-inner.cpp new file mode 100644 index 0000000..f72f073 --- /dev/null +++ b/src/helpers/creds-dbus/creds-dbus-inner.cpp @@ -0,0 +1,58 @@ +/* + * 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 creds-dbus-inner.cpp + * @author Radoslaw Bartosiak + * @author Aleksander Zdyb + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief Implementation of internal libcynara-creds-dbus functions + */ + +#include + +#include + +#include "creds-dbus-inner.h" + +int getClientSmackLabel(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, + char **client UNUSED) { + //todo + return CYNARA_API_METHOD_NOT_SUPPORTED; +} + +int getClientPid(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, + char **client UNUSED) { + //todo + return CYNARA_API_METHOD_NOT_SUPPORTED; +} + +int getUserId(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, + char **user UNUSED) { + //todo + return CYNARA_API_METHOD_NOT_SUPPORTED; +} + +int getUserGid(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, + char **user UNUSED) { + //todo + return CYNARA_API_METHOD_NOT_SUPPORTED; +} + +int getPid(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, pid_t *pid UNUSED) { + //todo + return CYNARA_API_METHOD_NOT_SUPPORTED; +} diff --git a/src/helpers/creds-dbus/creds-dbus-inner.h b/src/helpers/creds-dbus/creds-dbus-inner.h new file mode 100644 index 0000000..4c51119 --- /dev/null +++ b/src/helpers/creds-dbus/creds-dbus-inner.h @@ -0,0 +1,39 @@ +/* + * 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 creds-dbus-inner.h + * @author Radoslaw Bartosiak + * @author Aleksander Zdyb + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief Definition of internal external libcynara-creds-dbus functions + */ + +#ifndef SRC_HELPERS_CREDSDBUS_CREDSDBUSINNER_H_ +#define SRC_HELPERS_CREDSDBUS_CREDSDBUSINNER_H_ + +#include +#include + +int getClientSmackLabel(DBusConnection *connection, const char *uniqueName, char **client); +int getClientPid(DBusConnection *connection, const char *uniqueName, char **client); + +int getUserId(DBusConnection *connection, const char *uniqueName, char **user); +int getUserGid(DBusConnection *connection, const char *uniqueName, char **user); + +int getPid(DBusConnection *connection, const char *uniqueName, pid_t *pid); + +#endif /* SRC_HELPERS_CREDSDBUS_CREDSDBUSINNER_H_ */ diff --git a/src/helpers/creds-dbus/creds-dbus.cpp b/src/helpers/creds-dbus/creds-dbus.cpp index 535ca84..344cd02 100644 --- a/src/helpers/creds-dbus/creds-dbus.cpp +++ b/src/helpers/creds-dbus/creds-dbus.cpp @@ -15,9 +15,58 @@ */ /* * @file creds-dbus.cpp + * @author Radoslaw Bartosiak + * @author Aleksander Zdyb * @author Lukasz Wojciechowski * @version 1.0 * @brief Implementation of external libcynara-creds-dbus API */ -// Empty initial file + +#include + +#include + +#include +#include +#include + +CYNARA_API +int cynara_creds_dbus_get_client(DBusConnection *connection, const char *uniqueName, + enum cynara_client_creds method, char **client) { + if (connection == nullptr || uniqueName == nullptr || client == nullptr) + return CYNARA_API_INVALID_PARAM; + + switch (method) { + case cynara_client_creds::CLIENT_METHOD_SMACK: + return getClientSmackLabel(connection, uniqueName, client); + case cynara_client_creds::CLIENT_METHOD_PID: + return getClientPid(connection, uniqueName, client); + default: + return CYNARA_API_METHOD_NOT_SUPPORTED; + } +} + +CYNARA_API +int cynara_creds_dbus_get_user(DBusConnection *connection, const char *uniqueName, + enum cynara_user_creds method, char **user) { + if (connection == nullptr || uniqueName == nullptr || user == nullptr) + return CYNARA_API_INVALID_PARAM; + + switch (method) { + case cynara_user_creds::USER_METHOD_UID: + return getUserId(connection, uniqueName, user); + case cynara_user_creds::USER_METHOD_GID: + return getUserGid(connection, uniqueName, user); + default: + return CYNARA_API_METHOD_NOT_SUPPORTED; + } +} + +CYNARA_API +int cynara_creds_dbus_get_pid(DBusConnection *connection, const char *uniqueName, pid_t *pid) { + if (connection == nullptr || uniqueName == nullptr) + return CYNARA_API_INVALID_PARAM; + + return getPid(connection, uniqueName, pid); +} diff --git a/src/include/cynara-creds-dbus.h b/src/include/cynara-creds-dbus.h index 925a829..904e4dd 100644 --- a/src/include/cynara-creds-dbus.h +++ b/src/include/cynara-creds-dbus.h @@ -16,6 +16,7 @@ /* * @file cynara-creds-dbus.h * @author Lukasz Wojciechowski + * @author Radoslaw Bartosiak * @version 1.0 * @brief This file contains Cynara credentials helper APIs for dbus clients. */ @@ -24,11 +25,133 @@ #ifndef CYNARA_CREDS_DBUS_H #define CYNARA_CREDS_DBUS_H +#include +#include + +#include "cynara-creds-commons.h" + #ifdef __cplusplus extern "C" { #endif -/* empty initial file */ +/** + * \par Description: + * Creates a client identification string with given method. Client is a process identified by the + * unique name at the other side of the dbus connection. + * + * \par Purpose: + * Client identification string is required for cynara_check() and cynara_async_check() functions. + * + * \par Typical use case: + * The function is called before the call of one of ...check() functions. + * Returned string is used as client parameter in ...check() function. + * String is released with free() function when it is no longer needed. + * + * \par Method of function operation: + * The function generates client string by calling a method from DBus Interface + * ("org.freedesktop.DBus") which is placed on system bus ("org.freedesktop.DBus"). + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread safety: + * This function is NOT thread-safe. If functions from described API are called by multithreaded + * application from different threads, they must be put into mutex protected critical section. + * + * \par Important notes: + * Memory for returned client string is obtained with malloc(), and should be freed with free(). + * Allocated string is returned only, when function succeeds. + * + * \param[in] connection DBus connection to a bus. It manages incomming and outgoing messages + * \param[in] uniqueName DBus identifier of the client + * \param[in] method Method of client identifier creation + * \param[out] client Placeholder for allocated string containing client id + * + * \return CYNARA_API_SUCCESS on success + * CYNARA_API_INVALID_PARAM when client is NULL or uniqueName or client has wrong + * value (i.e NULL or non-existing) + * CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported + * CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_dbus_get_client(DBusConnection *connection, const char *uniqueName, + enum cynara_client_creds method, char **client); + +/** + * \par Description: + * Creates a user identification string with given method. User is an executor of process + * at the other side of socket. + * + * \par Purpose: + * User identification string is required for cynara_check() and cynara_async_check() functions. + * + * \par Typical use case: + * The function is called before the call of one of ...check() functions. + * Returned string is used as user parameter in ...check() function. + * String is released with free() function when it is no longer needed. + * + * \par Method of function operation: + * The function generates user string by calling a method from DBus Interface + * ("org.freedesktop.DBus") which is placed on system bus ("org.freedesktop.DBus"). + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread safety: + * This function is NOT thread-safe. If functions from described API are called by multithreaded + * application from different threads, they must be put into mutex protected critical section. + * + * \par Important notes: + * Memory for returned user string is obtained with malloc(), and should be freed with free(). + * Allocated string is returned only, when function succeeds. + * + * \param[in] connection DBus connection to a bus. It manages incomming and outgoing messages + * \param[in] uniqueName DBus identifier of the client invoked by the user + * \param[in] method Method of client identifier creation + * \param[out] user Placeholder for allocated string containing user id + * + * \return CYNARA_API_SUCCESS on success + * CYNARA_API_INVALID_PARAM when user is NULL or connection is not valid DBus connection or + * uniqueName does not represent a process conected to the DBus + * CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported + * CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_dbus_get_user(DBusConnection *connection, const char *uniqueName, + enum cynara_user_creds method, char **user); + +/** + * \par Description: + * Return PID of a proces identified by the unique name at the other side of the dbus connection. + * + * \par Purpose: + * PID may be used for client_session creation with cynara_helper_session_from_pid() function + * from libcynara-helper-session library. Client_session is needed for cynara_check() + * and cynara_async_check() functions. + * + * \par Typical use case: + * The function is called before the call of cynara_helper_session_from_pid() function. + * + * \par Method of function operation: + * The function reads PID of the peer by calling a method from DBus Interface + * ("org.freedesktop.DBus") which is placed on system bus ("org.freedesktop.DBus") + * with "GetConnectionUnixProcessID" argument. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread safety: + * This function is NOT thread-safe. If functions from described API are called by multithreaded + * application from different threads, they must be put into mutex protected critical section. + * + * \param[in] connection DBus connection to a bus. It manages incomming and outgoing messages + * \param[in] uniqueName DBus identifier of the client invoked by the user + * \param[out] pid Placeholder for PID returned by function + * + * \return CYNARA_API_SUCCESS on success + * CYNARA_API_INVALID_PARAM when socket_fd is not valid connected socket descriptor + * CYNARA_API_UNKNOWN_ERROR when system function fails in incredible situation + * CYNARA_API_OUT_OF_MEMORY when there was error allocating memory + */ +int cynara_creds_dbus_get_pid(DBusConnection *connection, const char *uniqueName, pid_t *pid); #ifdef __cplusplus } -- 2.7.4 From f42327401e1a13cb8434b24ab9195d269c5c99f6 Mon Sep 17 00:00:00 2001 From: Radoslaw Bartosiak Date: Sun, 31 Aug 2014 21:01:33 +0200 Subject: [PATCH 02/16] Add mockuped versions of default credential methods helpers Change-Id: I762a435b4a2fcf81239e7d91b454cd8c785095cb --- src/helpers/creds-commons/creds-commons.cpp | 23 ++++++++++++++++++++++- src/include/cynara-creds-commons.h | 4 +++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/helpers/creds-commons/creds-commons.cpp b/src/helpers/creds-commons/creds-commons.cpp index 4cb7897..390f2ea 100644 --- a/src/helpers/creds-commons/creds-commons.cpp +++ b/src/helpers/creds-commons/creds-commons.cpp @@ -16,8 +16,29 @@ /* * @file creds-commons.cpp * @author Lukasz Wojciechowski + * @author Radoslaw Bartosiak + * @author Aleksander Zdyb * @version 1.0 * @brief Implementation of external libcynara-creds-commons API */ -// Empty initial file +#include + +#include +#include + +CYNARA_API +int cynara_creds_get_default_client_method(enum cynara_client_creds *method) { + //todo read from proper file and parse + + *method = CLIENT_METHOD_SMACK; + return CYNARA_API_SUCCESS; +} + +CYNARA_API +int cynara_creds_get_default_user_method(enum cynara_user_creds *method) { + //todo read from proper file and parse + + *method = USER_METHOD_UID; + return CYNARA_API_SUCCESS; +} diff --git a/src/include/cynara-creds-commons.h b/src/include/cynara-creds-commons.h index 9f012e1..7e46126 100644 --- a/src/include/cynara-creds-commons.h +++ b/src/include/cynara-creds-commons.h @@ -40,7 +40,9 @@ enum cynara_user_creds { extern "C" { #endif -/* empty initial file */ +int cynara_creds_get_default_client_method(enum cynara_client_creds *method); + +int cynara_creds_get_default_user_method(enum cynara_user_creds *method); #ifdef __cplusplus } -- 2.7.4 From 86a124c006960764e9eb4fc5754e705dcd05e994 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Thu, 4 Sep 2014 15:31:31 +0200 Subject: [PATCH 03/16] Implement cynara-creds-dbus library Signed-off-by: Radoslaw Bartosiak Signed-off-by: Aleksander Zdyb Change-Id: Iccf9cb0acb1016746d8af7a4ee85714e74f4664e --- src/helpers/creds-dbus/creds-dbus-inner.cpp | 168 +++++++++++++++++++++++++--- 1 file changed, 153 insertions(+), 15 deletions(-) diff --git a/src/helpers/creds-dbus/creds-dbus-inner.cpp b/src/helpers/creds-dbus/creds-dbus-inner.cpp index f72f073..dbbfb0d 100644 --- a/src/helpers/creds-dbus/creds-dbus-inner.cpp +++ b/src/helpers/creds-dbus/creds-dbus-inner.cpp @@ -23,27 +23,160 @@ */ #include +#include +#include #include #include "creds-dbus-inner.h" -int getClientSmackLabel(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, - char **client UNUSED) { - //todo - return CYNARA_API_METHOD_NOT_SUPPORTED; +// TODO: Move this class somewhere else +// TODO: Find a better name for this class +// TODO: Introduce std::exception instead of throwing ints +// TODO: Make this class more general +// TODO: Write tests for this class +class DBusMethod { +public: + typedef int ArgType; + DBusMethod(DBusConnection *connection, const std::string &method) : m_connection(connection) { + if (connection == nullptr) + throw CYNARA_API_INVALID_PARAM; + + m_message = dbus_message_new_method_call(m_dbusName.c_str(), m_dbusObject.c_str(), + m_dbusInterface.c_str(), method.c_str()); + + if (m_message == nullptr) + throw CYNARA_API_OUT_OF_MEMORY; + } + + ~DBusMethod() { + if (m_message != nullptr) + dbus_message_unref(m_message); + + delete m_argsIter; + } + + void appendArg(ArgType type, void *value) { + if (dbus_message_append_args(m_message, type, value, DBUS_TYPE_INVALID) == FALSE) + throw CYNARA_API_UNKNOWN_ERROR; + } + + void getArgPtr(ArgType type, void *value) { + if (m_argsIter == nullptr) + throw CYNARA_API_UNKNOWN_ERROR; + + if (dbus_message_iter_get_arg_type(m_argsIter) != type) + throw CYNARA_API_UNKNOWN_ERROR; + + dbus_message_iter_get_basic(m_argsIter, value); + dbus_message_iter_next(m_argsIter); + } + + DBusMethod send(void) { + DBusPendingCall *reply = nullptr; + auto ret = dbus_connection_send_with_reply(m_connection, m_message, &reply, + DBUS_TIMEOUT_USE_DEFAULT); + if (ret == FALSE) + throw CYNARA_API_OUT_OF_MEMORY; + + if (reply == nullptr) + throw CYNARA_API_INVALID_PARAM; + + dbus_connection_flush(m_connection); + dbus_pending_call_block(reply); + + DBusMessage *replyMsg = dbus_pending_call_steal_reply(reply); + if (replyMsg == nullptr) + throw CYNARA_API_UNKNOWN_ERROR; + + return { m_connection, replyMsg }; + } + +private: + DBusMethod(DBusConnection *connection, DBusMessage *message) + : m_connection(connection), m_message(message), m_argsIter(new DBusMessageIter()) { + + if (dbus_message_iter_init(m_message, m_argsIter) == FALSE) + throw CYNARA_API_UNKNOWN_ERROR; + } + + DBusConnection *m_connection = nullptr; + DBusMessage *m_message = nullptr; + DBusMessageIter *m_argsIter = nullptr; + + static const std::string m_dbusName; + static const std::string m_dbusObject; + static const std::string m_dbusInterface; +}; + +const std::string DBusMethod::m_dbusName = "org.freedesktop.DBus"; +const std::string DBusMethod::m_dbusObject = "/org/freedesktop/DBus"; +const std::string DBusMethod::m_dbusInterface = "org.freedesktop.DBus"; + + +int getIdFromConnection(DBusConnection *connection, const char *uniqueName, + const std::string &dbusMethod, unsigned int *id) { + + if (uniqueName == nullptr) + return CYNARA_API_INVALID_PARAM; + + if (dbusMethod != "GetConnectionUnixUser" && dbusMethod != "GetConnectionUnixProcessID") + return CYNARA_API_INVALID_PARAM; + + try { + DBusMethod call(connection, dbusMethod); + call.appendArg(DBUS_TYPE_STRING, &uniqueName); + auto reply = call.send(); + reply.getArgPtr(DBUS_TYPE_UINT32, id); + } catch (int apiError) { + return apiError; + } + + return CYNARA_API_SUCCESS; } -int getClientPid(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, - char **client UNUSED) { - //todo - return CYNARA_API_METHOD_NOT_SUPPORTED; +int getClientSmackLabel(DBusConnection *connection, const char *uniqueName, char **client) { + if (uniqueName == nullptr) + return CYNARA_API_INVALID_PARAM; + + try { + DBusMethod call(connection, "GetConnectionSmackContext"); + call.appendArg(DBUS_TYPE_STRING, &uniqueName); + auto reply = call.send(); + char *label; + reply.getArgPtr(DBUS_TYPE_STRING, &label); + *client = strdup(label); + if (*client == nullptr) + return CYNARA_API_OUT_OF_MEMORY; + } catch (int apiError) { + return apiError; + } + + return CYNARA_API_SUCCESS; } -int getUserId(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, - char **user UNUSED) { - //todo - return CYNARA_API_METHOD_NOT_SUPPORTED; +int getUint32(DBusConnection *connection, const char *uniqueName, const char *method, + char **value) { + unsigned int dbusValue; + int ret = getIdFromConnection(connection, uniqueName, method, &dbusValue); + + if (ret != CYNARA_API_SUCCESS) + return ret; + + *value = strdup(std::to_string(dbusValue).c_str()); + + if (*value == nullptr) + return CYNARA_API_OUT_OF_MEMORY; + + return CYNARA_API_SUCCESS; +} + +int getClientPid(DBusConnection *connection, const char *uniqueName, char **client) { + return getUint32(connection, uniqueName, "GetConnectionUnixProcessID", client); +} + +int getUserId(DBusConnection *connection, const char *uniqueName, char **user) { + return getUint32(connection, uniqueName, "GetConnectionUnixUser", user); } int getUserGid(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, @@ -52,7 +185,12 @@ int getUserGid(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, return CYNARA_API_METHOD_NOT_SUPPORTED; } -int getPid(DBusConnection *connection UNUSED, const char *uniqueName UNUSED, pid_t *pid UNUSED) { - //todo - return CYNARA_API_METHOD_NOT_SUPPORTED; +int getPid(DBusConnection *connection, const char *uniqueName, pid_t *pid) { + unsigned int _pid; + auto ret = getIdFromConnection(connection, uniqueName, "GetConnectionUnixProcessID", &_pid); + + if (ret == CYNARA_API_SUCCESS) + *pid = _pid; + + return ret; } -- 2.7.4 From 409a48e8b43bae1ee0b5b786b9f029577726adb3 Mon Sep 17 00:00:00 2001 From: Jacek Bukarewicz Date: Thu, 28 Aug 2014 14:21:47 +0200 Subject: [PATCH 04/16] Synchronize RPM and pkg-config versions This change also introduces CYNARA_VERSION cmake variable which will need to be kept in sync with rpm package version. We cannot rely on passing version from RPM spec since we want to be able to build Cynara independently of the Tizen build system. Change-Id: I1bdd3a603a486d386f261e8330a9635923945569 Signed-off-by: Jacek Bukarewicz --- CMakeLists.txt | 1 + pkgconfig/cynara-admin/cynara-admin.pc.in | 2 +- pkgconfig/cynara-client/cynara-client.pc.in | 2 +- pkgconfig/cynara-creds-commons/cynara-creds-commons.pc.in | 2 +- pkgconfig/cynara-creds-dbus/cynara-creds-dbus.pc.in | 2 +- pkgconfig/cynara-creds-socket/cynara-creds-socket.pc.in | 2 +- pkgconfig/cynara-session/cynara-session.pc.in | 2 +- 7 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c4f80a2..8cdd475 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3) PROJECT("cynara") +set(CYNARA_VERSION 0.2.2) ############################# cmake packages ################################## diff --git a/pkgconfig/cynara-admin/cynara-admin.pc.in b/pkgconfig/cynara-admin/cynara-admin.pc.in index 3bf19a0..faa6c47 100644 --- a/pkgconfig/cynara-admin/cynara-admin.pc.in +++ b/pkgconfig/cynara-admin/cynara-admin.pc.in @@ -5,7 +5,7 @@ includedir=${prefix}/include Name: cynara-admin Description: cynara-admin package -Version: 0.0.1 +Version: @CYNARA_VERSION@ Requires: Libs: -L${libdir} -lcynara-admin Cflags: -I${includedir}/cynara diff --git a/pkgconfig/cynara-client/cynara-client.pc.in b/pkgconfig/cynara-client/cynara-client.pc.in index d81e8ab..e1505a0 100644 --- a/pkgconfig/cynara-client/cynara-client.pc.in +++ b/pkgconfig/cynara-client/cynara-client.pc.in @@ -5,7 +5,7 @@ includedir=${prefix}/include Name: cynara-client Description: cynara-client package -Version: 0.0.1 +Version: @CYNARA_VERSION@ Requires: Libs: -L${libdir} -lcynara-client Cflags: -I${includedir}/cynara diff --git a/pkgconfig/cynara-creds-commons/cynara-creds-commons.pc.in b/pkgconfig/cynara-creds-commons/cynara-creds-commons.pc.in index cb87e5f..7d6e3c4 100644 --- a/pkgconfig/cynara-creds-commons/cynara-creds-commons.pc.in +++ b/pkgconfig/cynara-creds-commons/cynara-creds-commons.pc.in @@ -5,7 +5,7 @@ includedir=${prefix}/include Name: cynara-creds-commons Description: Base package for all cynara-creds packages -Version: 0.0.1 +Version: @CYNARA_VERSION@ Requires: Libs: -L${libdir} -lcynara-creds-commons Cflags: -I${includedir}/cynara diff --git a/pkgconfig/cynara-creds-dbus/cynara-creds-dbus.pc.in b/pkgconfig/cynara-creds-dbus/cynara-creds-dbus.pc.in index 296ce6c..eb09848 100644 --- a/pkgconfig/cynara-creds-dbus/cynara-creds-dbus.pc.in +++ b/pkgconfig/cynara-creds-dbus/cynara-creds-dbus.pc.in @@ -5,7 +5,7 @@ includedir=${prefix}/include Name: cynara-creds-dbus Description: cynara-creds package for dbus clients -Version: 0.0.1 +Version: @CYNARA_VERSION@ Requires: dbus-1 Libs: -L${libdir} -lcynara-creds-dbus Cflags: -I${includedir}/cynara diff --git a/pkgconfig/cynara-creds-socket/cynara-creds-socket.pc.in b/pkgconfig/cynara-creds-socket/cynara-creds-socket.pc.in index b81cf68..3c53f53 100644 --- a/pkgconfig/cynara-creds-socket/cynara-creds-socket.pc.in +++ b/pkgconfig/cynara-creds-socket/cynara-creds-socket.pc.in @@ -5,7 +5,7 @@ includedir=${prefix}/include Name: cynara-creds-socket Description: cynara-creds package for socket clients -Version: 0.0.1 +Version: @CYNARA_VERSION@ Requires: Libs: -L${libdir} -lcynara-creds-socket Cflags: -I${includedir}/cynara diff --git a/pkgconfig/cynara-session/cynara-session.pc.in b/pkgconfig/cynara-session/cynara-session.pc.in index fa6e763..e734739 100644 --- a/pkgconfig/cynara-session/cynara-session.pc.in +++ b/pkgconfig/cynara-session/cynara-session.pc.in @@ -5,7 +5,7 @@ includedir=${prefix}/include Name: cynara-session Description: cynara-session package -Version: 0.0.1 +Version: @CYNARA_VERSION@ Requires: Libs: -L${libdir} -lcynara-session Cflags: -I${includedir}/cynara -- 2.7.4 From 90c41617da666439c88415a2fb2868ac9e8ef1fa Mon Sep 17 00:00:00 2001 From: Radoslaw Bartosiak Date: Thu, 4 Sep 2014 15:59:50 +0200 Subject: [PATCH 05/16] Add documentation to cynara-creds-commons.h Signed-off-by: Radoslaw Bartosiak Change-Id: I717b1cc988c5fc6780d42774c75a4596a522c3e2 --- src/include/cynara-creds-commons.h | 59 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/src/include/cynara-creds-commons.h b/src/include/cynara-creds-commons.h index 7e46126..1bb3ffc 100644 --- a/src/include/cynara-creds-commons.h +++ b/src/include/cynara-creds-commons.h @@ -40,8 +40,67 @@ enum cynara_user_creds { extern "C" { #endif +/** + * \par Description: + * Gets the system default method value for client feature used in cynara-creds. + * + * \par Purpose: + * Functions cynara_creds_dbus_get_client() and cynara_creds_socket_get_client() take a method + * parameter, which determines a kind of process feature (i.e PID, SMACK label) returned by them. + * The described function provides implementation for obtaining a system default value + * for this parameter. + * + * \par Typical use case: + * The function might be called before cynara_creds_dbus_get_client() and cynara_creds_socket_get_client(), + * when functions shall be invoked with system default value of method parameter. + * + * \par Method of function operation: + * Now the function is mocked up. It sets method to CLIENT_METHOD_SMACK and returns CYNARA_API_SUCCESS. + * In the future the function will probably read the value from /etc/cynara/cynara_client_creds file. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread safety: + * This function is thread-safe. + * + * \param[out] method Placeholder for system default client feature + * (like CLIENT_METHOD_SMACK, CLIENT_METHOD_PID) + * + * \return CYNARA_API_SUCCESS on success, negative error code on error + */ int cynara_creds_get_default_client_method(enum cynara_client_creds *method); +/** + * \par Description: + * Gets the system default method value for user feature used in cynara-creds. + * + * \par Purpose: + * Functions cynara_creds_dbus_get_user() and cynara_creds_socket_get_user() take a method + * parameter, which determines a kind of process feature (i.e UID, GID) returned by them. + * The described function provides implementation for obtaining a system default value + * for this parameter. + * + * \par Typical use case: + * The function might be called before cynara_creds_dbus_get_user() and cynara_creds_socket_get_user(), + * when functions shall be invoked with system default value of method parameter. + * + * \par Method of function operation: + * + * The function reads the value from /etc/cynara/cynara_user_creds file. + * Now the function is mocked up. It sets method to USER_METHOD_UID and returns CYNARA_API_SUCCESS. + * In the future the function will probably read the value from /etc/cynara/cynara_user_creds file. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \par Thread safety: + * This function is thread-safe. + * + * \param[out] method Placeholder for system default user feature (like USER_METHOD_UID, USER_METHOD_GID) + * + * \return CYNARA_API_SUCCESS on success, negative error code on error + */ int cynara_creds_get_default_user_method(enum cynara_user_creds *method); #ifdef __cplusplus -- 2.7.4 From 95189fc1ae98c7f85885048dbb9ccb5eed584e33 Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Thu, 4 Sep 2014 15:16:42 +0200 Subject: [PATCH 06/16] Fix creds dependencies Change-Id: I3d5dd7bdfad9a58b99e754d5acb9dcb20a18b0e8 --- packaging/cynara.spec | 2 ++ src/include/cynara-creds-commons.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 2036d61..a297c4f 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -132,6 +132,7 @@ Cynara credentials helpers library for dbus clients %package -n libcynara-creds-dbus-devel Summary: Cynara credentials helpers library for dbus clients (devel) Requires: libcynara-creds-dbus = %{version}-%{release} +Requires: libcynara-creds-commons-devel = %{version}-%{release} %description -n libcynara-creds-dbus-devel Cynara credentials helpers library for dbus clients (devel) @@ -146,6 +147,7 @@ Cynara credentials helpers library for socket clients %package -n libcynara-creds-socket-devel Summary: Cynara credentials helpers library for socket clients (devel) Requires: libcynara-creds-socket = %{version}-%{release} +Requires: libcynara-creds-commons-devel = %{version}-%{release} %description -n libcynara-creds-socket-devel Cynara credentials helpers library for socket clients (devel) diff --git a/src/include/cynara-creds-commons.h b/src/include/cynara-creds-commons.h index 1bb3ffc..ca83e3a 100644 --- a/src/include/cynara-creds-commons.h +++ b/src/include/cynara-creds-commons.h @@ -26,6 +26,8 @@ #ifndef CYNARA_CREDS_COMMONS_H #define CYNARA_CREDS_COMMONS_H +#include + enum cynara_client_creds { CLIENT_METHOD_SMACK, CLIENT_METHOD_PID -- 2.7.4 From 474344e9f47d86b5bc9bee844980cb85495b10f6 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Wed, 3 Sep 2014 16:05:03 +0200 Subject: [PATCH 07/16] build: configure default installation directories in cmake Set the default installation paths in main CMakeLists.txt. On Tizen these settings will be overridden by variables passed to cmake by rpmbuild. But having them defined makes the standalone build possible, outside of Tizen. Change-Id: Idf84ff5a5e15fd99912b53e0970198d031bbbee5 Signed-off-by: Rafal Krypa --- CMakeLists.txt | 17 +++++++++++++++++ src/service/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8cdd475..18b0dee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,23 @@ set(CYNARA_VERSION 0.2.2) INCLUDE(FindPkgConfig) INCLUDE(CheckCXXCompilerFlag) +############################# install dirs ################################## + +SET(LIB_INSTALL_DIR + "${CMAKE_INSTALL_PREFIX}/lib" + CACHE PATH + "Library installation directory") + +SET(BIN_INSTALL_DIR + "${CMAKE_INSTALL_PREFIX}/bin" + CACHE PATH + "Binary installation directory") + +SET(INCLUDE_INSTALL_DIR + "${CMAKE_INSTALL_PREFIX}/include" + CACHE PATH + "Include installation directory") + ############################# compiler flags ################################## SET(CMAKE_CXX_FLAGS_PROFILING "-O0 -g -pg") diff --git a/src/service/CMakeLists.txt b/src/service/CMakeLists.txt index 47482eb..ce1e67d 100644 --- a/src/service/CMakeLists.txt +++ b/src/service/CMakeLists.txt @@ -42,4 +42,4 @@ TARGET_LINK_LIBRARIES(${TARGET_CYNARA} ${TARGET_CYNARA_COMMON} ) -INSTALL(TARGETS ${TARGET_CYNARA} DESTINATION bin) +INSTALL(TARGETS ${TARGET_CYNARA} DESTINATION ${BIN_INSTALL_DIR}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c3e3eea..b04f6d8 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -69,4 +69,4 @@ ADD_EXECUTABLE(${TARGET_CYNARA_TESTS} TARGET_LINK_LIBRARIES(${TARGET_CYNARA_TESTS} ${PKGS_LDFLAGS} ${PKGS_LIBRARIES} ) -INSTALL(TARGETS ${TARGET_CYNARA_TESTS} DESTINATION bin) +INSTALL(TARGETS ${TARGET_CYNARA_TESTS} DESTINATION ${BIN_INSTALL_DIR}) -- 2.7.4 From 7f339a1e206f36e92139eb16de499ceba6b7cba6 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Wed, 3 Sep 2014 16:22:45 +0200 Subject: [PATCH 08/16] build: unbreak out-of-tree build of pkgconfig files Fix regression introduced recently in 21175a33. "Make install" fails on pkgconfig files when building out-of-tree. Change-Id: Ib544993ae4daa784ca93d9e115eeba9830957ecc Signed-off-by: Rafal Krypa --- pkgconfig/cynara-admin/CMakeLists.txt | 2 +- pkgconfig/cynara-client/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkgconfig/cynara-admin/CMakeLists.txt b/pkgconfig/cynara-admin/CMakeLists.txt index 6adc6b9..c66ec5c 100644 --- a/pkgconfig/cynara-admin/CMakeLists.txt +++ b/pkgconfig/cynara-admin/CMakeLists.txt @@ -20,7 +20,7 @@ CONFIGURE_FILE(cynara-admin.pc.in cynara-admin.pc @ONLY) INSTALL(FILES - cynara-admin.pc + ${CMAKE_BINARY_DIR}/pkgconfig/cynara-admin/cynara-admin.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig ) diff --git a/pkgconfig/cynara-client/CMakeLists.txt b/pkgconfig/cynara-client/CMakeLists.txt index ecb78c7..03ee41e 100644 --- a/pkgconfig/cynara-client/CMakeLists.txt +++ b/pkgconfig/cynara-client/CMakeLists.txt @@ -20,7 +20,7 @@ CONFIGURE_FILE(cynara-client.pc.in cynara-client.pc @ONLY) INSTALL(FILES - cynara-client.pc + ${CMAKE_BINARY_DIR}/pkgconfig/cynara-client/cynara-client.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig ) -- 2.7.4 From fc366e4070b6a2696e4de4e42cbd4b740f7ade15 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Wed, 3 Sep 2014 16:04:26 +0200 Subject: [PATCH 09/16] build: allow conditional building of cynara-tests, turn it on in spec Change cmake to build cynara-tests only when enabled and enable it in spec file. This will enable cynara build outside of Tizen (without tests). Current setup for cynara-tests build depends on Tizen-specific packaging of gmock package. This dependency cannot be met outside of Tizen, which would break the whole build. It is not easy to apply a proper fix to have cynara-tests built outside of Tizen. Gmock is not meant to be used as dependency in such way. Most certainly we will have to handle gmock dependency differently in upstream and in Tizen. Change-Id: Id9fc8142979d1a2061c1c72c610520479d9e61a2 Signed-off-by: Rafal Krypa --- CMakeLists.txt | 5 ++++- packaging/cynara.spec | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 18b0dee..8c10a18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,9 @@ SET(TARGET_LIB_CREDS_SOCKET "cynara-creds-socket") SET(TARGET_LIB_SESSION "cynara-session") ADD_SUBDIRECTORY(src) -ADD_SUBDIRECTORY(test) ADD_SUBDIRECTORY(pkgconfig) ADD_SUBDIRECTORY(systemd) + +IF (BUILD_TESTS) +ADD_SUBDIRECTORY(test) +ENDIF() diff --git a/packaging/cynara.spec b/packaging/cynara.spec index a297c4f..ce6fe5c 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -209,6 +209,7 @@ export CXXFLAGS="$CXXFLAGS -DCYNARA_STATE_PATH=\\\"%{state_path}\\\"" export LDFLAGS+="-Wl,--rpath=%{_libdir}" %cmake . \ + -DBUILD_TESTS=ON \ -DCMAKE_BUILD_TYPE=%{?build_type} \ -DCMAKE_VERBOSE_MAKEFILE=ON make %{?jobs:-j%jobs} -- 2.7.4 From bb1f0f1ab80f9f02f04140f6da35f01902522508 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Fri, 5 Sep 2014 16:31:43 +0200 Subject: [PATCH 10/16] Add changelog for keeping release history Changelog filled with historical data. Change-Id: Idf35e1024d19ac2e66699b2aea6555a5a37ae323 --- changelog | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 changelog diff --git a/changelog b/changelog new file mode 100644 index 0000000..5887ebc --- /dev/null +++ b/changelog @@ -0,0 +1,75 @@ +############################## + +Release: 0.2.2 +Date: 2014.08.08 +Name: Merge cynara and cynara-tests SRPMs + +Libraries: +libcynara-common.0.0.1 +libcynara-client.0.0.2 +libcynara-admin.0.0.2 + +Description: +Cynara's and cynara-tests spec files were merged. They are built together now. + +############################## + +Release: 0.2.1 +Date: 2014.08.06 +Name: "cynara" system user + +Libraries: +libcynara-common.0.0.1 +libcynara-client.0.0.2 +libcynara-admin.0.0.2 + +Description: +Cynara service runs as user cynara, created during package installation. +Minor bug fixing. + +############################## + +Release: 0.2.0 +Date: 2014.08.01 +Name: Client cache feature + +Libraries: +libcynara-common.0.0.1 +libcynara-client.0.0.2 +libcynara-admin.0.0.2 + +Description: +Policy responses cache added in libcynara-client. +Lots of code cleaning and bug fixing. + +############################## + +Release: 0.1.1 +Date: 2014.07.21 +Name: First version base on cynara service + +Libraries: +libcynara-common.0.0.1 +libcynara-client.0.0.2 +libcynara-admin.0.0.2 + +Description: +First version of cynara using own service and database. +API provided by 2 libraries - client for privilege checking +and admin for managing policies in database. + +############################## + +Release: 0.0.1 +Date: 2014.05.08 +Name: Cynara bootstrap version + +Libraries: +libcynara-client.0.0.1 + +Description: +First version of cynara client - using security-server API. +libprivilege-control database was used for holding privilege access policies. + +############################## + -- 2.7.4 From 9e1c068991d3f0673bf946651a5753986389be0d Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Fri, 5 Sep 2014 16:56:04 +0200 Subject: [PATCH 11/16] Release 0.3.0 Change-Id: I5e2b5d39b1a14dca7575dcfd8812087f401dc82a --- changelog | 21 +++++++++++++++++++++ packaging/cynara.spec | 2 +- src/admin/CMakeLists.txt | 2 +- src/client-common/CMakeLists.txt | 2 +- src/client/CMakeLists.txt | 2 +- src/common/CMakeLists.txt | 2 +- src/helpers/creds-commons/CMakeLists.txt | 2 +- src/helpers/creds-dbus/CMakeLists.txt | 2 +- src/helpers/creds-socket/CMakeLists.txt | 2 +- src/helpers/session/CMakeLists.txt | 2 +- 10 files changed, 30 insertions(+), 9 deletions(-) diff --git a/changelog b/changelog index 5887ebc..a2d08e3 100644 --- a/changelog +++ b/changelog @@ -1,5 +1,26 @@ ############################## +Release: 0.3.0 +Date: 2014.09.05 +Name: Helper libraries + +Libraries: +libcynara-common.0.3.0 +libcynara-client.0.3.0 +libcynara-client-common.0.3.0 +libcynara-admin.0.3.0 +libcynara-session.0.3.0 +libcynara-creds-commons.0.3.0 +libcynara-creds-dbus.0.3.0 +libcynara-creds-socket.0.3.0 + +Description: +Helper libraries for credentials and session. +Client-common library - common for all client libraries introduced. +Improve cache performance and move cache to client-common library. + +############################## + Release: 0.2.2 Date: 2014.08.08 Name: Merge cynara and cynara-tests SRPMs diff --git a/packaging/cynara.spec b/packaging/cynara.spec index ce6fe5c..677142b 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -1,6 +1,6 @@ Name: cynara Summary: Cynara service with client libraries -Version: 0.2.2 +Version: 0.3.0 Release: 1 Group: Security/Access Control License: Apache-2.0 diff --git a/src/admin/CMakeLists.txt b/src/admin/CMakeLists.txt index cc3d7ac..4918571 100644 --- a/src/admin/CMakeLists.txt +++ b/src/admin/CMakeLists.txt @@ -17,7 +17,7 @@ # SET(LIB_CYNARA_ADMIN_VERSION_MAJOR 0) -SET(LIB_CYNARA_ADMIN_VERSION ${LIB_CYNARA_ADMIN_VERSION_MAJOR}.0.2) +SET(LIB_CYNARA_ADMIN_VERSION ${LIB_CYNARA_ADMIN_VERSION_MAJOR}.3.0) SET(CYNARA_LIB_CYNARA_ADMIN_PATH ${CYNARA_PATH}/admin) diff --git a/src/client-common/CMakeLists.txt b/src/client-common/CMakeLists.txt index dd05c79..90e09d7 100644 --- a/src/client-common/CMakeLists.txt +++ b/src/client-common/CMakeLists.txt @@ -17,7 +17,7 @@ # SET(LIB_CYNARA_CLIENT_COMMON_VERSION_MAJOR 0) -SET(LIB_CYNARA_CLIENT_COMMON_VERSION ${LIB_CYNARA_CLIENT_COMMON_VERSION_MAJOR}.0.2) +SET(LIB_CYNARA_CLIENT_COMMON_VERSION ${LIB_CYNARA_CLIENT_COMMON_VERSION_MAJOR}.3.0) SET(LIB_CYNARA_COMMON_PATH ${CYNARA_PATH}/client-common) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index d364e2d..db0622c 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -18,7 +18,7 @@ # SET(LIB_CYNARA_VERSION_MAJOR 0) -SET(LIB_CYNARA_VERSION ${LIB_CYNARA_VERSION_MAJOR}.0.2) +SET(LIB_CYNARA_VERSION ${LIB_CYNARA_VERSION_MAJOR}.3.0) SET(LIB_CYNARA_PATH ${CYNARA_PATH}/client) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index f489b44..8f99d0e 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -17,7 +17,7 @@ # SET(CYNARA_COMMON_VERSION_MAJOR 0) -SET(CYNARA_COMMON_VERSION ${CYNARA_COMMON_VERSION_MAJOR}.0.1) +SET(CYNARA_COMMON_VERSION ${CYNARA_COMMON_VERSION_MAJOR}.3.0) SET(COMMON_PATH ${CYNARA_PATH}/common) diff --git a/src/helpers/creds-commons/CMakeLists.txt b/src/helpers/creds-commons/CMakeLists.txt index 00484b7..92b31bd 100644 --- a/src/helpers/creds-commons/CMakeLists.txt +++ b/src/helpers/creds-commons/CMakeLists.txt @@ -19,7 +19,7 @@ # SET(LIB_CREDS_COMMONS_VERSION_MAJOR 0) -SET(LIB_CREDS_COMMONS_VERSION ${LIB_CREDS_COMMONS_VERSION_MAJOR}.0.1) +SET(LIB_CREDS_COMMONS_VERSION ${LIB_CREDS_COMMONS_VERSION_MAJOR}.3.0) SET(LIB_CREDS_COMMONS_PATH ${CYNARA_PATH}/helpers/creds-commons) diff --git a/src/helpers/creds-dbus/CMakeLists.txt b/src/helpers/creds-dbus/CMakeLists.txt index c80d301..d4ea94c 100644 --- a/src/helpers/creds-dbus/CMakeLists.txt +++ b/src/helpers/creds-dbus/CMakeLists.txt @@ -19,7 +19,7 @@ # SET(LIB_CREDS_DBUS_VERSION_MAJOR 0) -SET(LIB_CREDS_DBUS_VERSION ${LIB_CREDS_DBUS_VERSION_MAJOR}.0.1) +SET(LIB_CREDS_DBUS_VERSION ${LIB_CREDS_DBUS_VERSION_MAJOR}.3.0) SET(LIB_CREDS_DBUS_PATH ${CYNARA_PATH}/helpers/creds-dbus) diff --git a/src/helpers/creds-socket/CMakeLists.txt b/src/helpers/creds-socket/CMakeLists.txt index a425c0b..0a05e10 100644 --- a/src/helpers/creds-socket/CMakeLists.txt +++ b/src/helpers/creds-socket/CMakeLists.txt @@ -19,7 +19,7 @@ # SET(LIB_CREDS_SOCKET_VERSION_MAJOR 0) -SET(LIB_CREDS_SOCKET_VERSION ${LIB_CREDS_SOCKET_VERSION_MAJOR}.0.1) +SET(LIB_CREDS_SOCKET_VERSION ${LIB_CREDS_SOCKET_VERSION_MAJOR}.3.0) SET(LIB_CREDS_SOCKET_PATH ${CYNARA_PATH}/helpers/creds-socket) diff --git a/src/helpers/session/CMakeLists.txt b/src/helpers/session/CMakeLists.txt index b019f4c..0de24c4 100644 --- a/src/helpers/session/CMakeLists.txt +++ b/src/helpers/session/CMakeLists.txt @@ -19,7 +19,7 @@ # SET(LIB_SESSION_VERSION_MAJOR 0) -SET(LIB_SESSION_VERSION ${LIB_SESSION_VERSION_MAJOR}.0.1) +SET(LIB_SESSION_VERSION ${LIB_SESSION_VERSION_MAJOR}.3.0) SET(LIB_SESSION_PATH ${CYNARA_PATH}/helpers/session) -- 2.7.4 From 2324fffe9befd04cc57d396265f12750216bfd5a Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Mon, 18 Aug 2014 13:05:58 +0200 Subject: [PATCH 12/16] Add start point in Storage::checkPolicy() Storage::checkPolicy() now accepts id of bucket to start search with. Additional parameter (recursive) indicates, if search should go down into encountered buckets. Change-Id: I23ff8e044fc9ff0198183c335ffe845e75efe08b --- src/common/types/PolicyBucket.h | 7 +++++++ src/service/storage/Storage.cpp | 19 ++++++++++++------- src/service/storage/Storage.h | 6 ++++-- src/service/storage/StorageBackend.h | 1 + test/storage/storage/check.cpp | 32 +++++++++++++++++++++----------- 5 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/common/types/PolicyBucket.h b/src/common/types/PolicyBucket.h index b865d9e..c4675c2 100644 --- a/src/common/types/PolicyBucket.h +++ b/src/common/types/PolicyBucket.h @@ -48,12 +48,19 @@ public: typedef PolicyCollection::value_type value_type; typedef const_policy_iterator const_iterator; + // TODO: Review usefulness of ctors PolicyBucket() : m_defaultPolicy(PredefinedPolicyType::DENY) {} PolicyBucket(const PolicyBucketId &id, const PolicyResult &defaultPolicy) : m_defaultPolicy(defaultPolicy), m_id(id) {} PolicyBucket(const PolicyCollection &policies) : m_policyCollection(makePolicyMap(policies)), m_defaultPolicy(PredefinedPolicyType::DENY) {} + PolicyBucket(const PolicyBucketId &id, + const PolicyResult &defaultPolicy, + const PolicyCollection &policies) + : m_policyCollection(makePolicyMap(policies)), + m_defaultPolicy(defaultPolicy), + m_id(id) {} PolicyBucket filtered(const PolicyKey &key) const; void insertPolicy(PolicyPtr policy); diff --git a/src/service/storage/Storage.cpp b/src/service/storage/Storage.cpp index 7f92c34..8e81edc 100644 --- a/src/service/storage/Storage.cpp +++ b/src/service/storage/Storage.cpp @@ -38,12 +38,15 @@ namespace Cynara { -PolicyResult Storage::checkPolicy(const PolicyKey &key) { - auto policies = m_backend.searchDefaultBucket(key); - return minimalPolicy(policies, key); +PolicyResult Storage::checkPolicy(const PolicyKey &key, + const PolicyBucketId &startBucketId /*= defaultPolicyBucketId*/, + bool recursive /*= true*/) { + auto policies = m_backend.searchBucket(startBucketId, key); + return minimalPolicy(policies, key, recursive); }; -PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key) { +PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key, + bool recursive) { bool hasMinimal = false; PolicyResult minimal = bucket.defaultPolicy(); @@ -63,9 +66,11 @@ PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey case PredefinedPolicyType::DENY: return policyResult; // Do not expect lower value than DENY case PredefinedPolicyType::BUCKET: { - auto bucketResults = m_backend.searchBucket(policyResult.metadata(), key); - auto minimumOfBucket = minimalPolicy(bucketResults, key); - proposeMinimal(minimumOfBucket); + if (recursive == true) { + auto bucketResults = m_backend.searchBucket(policyResult.metadata(), key); + auto minimumOfBucket = minimalPolicy(bucketResults, key, true); + proposeMinimal(minimumOfBucket); + } continue; } case PredefinedPolicyType::ALLOW: diff --git a/src/service/storage/Storage.h b/src/service/storage/Storage.h index adee6ec..82052d0 100644 --- a/src/service/storage/Storage.h +++ b/src/service/storage/Storage.h @@ -43,7 +43,9 @@ class Storage public: Storage(StorageBackend &backend) : m_backend(backend) {} - PolicyResult checkPolicy(const PolicyKey &key); + PolicyResult checkPolicy(const PolicyKey &key, + const PolicyBucketId &startBucketId = defaultPolicyBucketId, + bool recursive = true); void insertPolicies(const std::map> &policiesByBucketId); void deletePolicies(const std::map> &keysByBucketId); @@ -55,7 +57,7 @@ public: void save(void); protected: - PolicyResult minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key); + PolicyResult minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key, bool recursive); private: StorageBackend &m_backend; // backend strategy diff --git a/src/service/storage/StorageBackend.h b/src/service/storage/StorageBackend.h index cc711f9..b015bf0 100644 --- a/src/service/storage/StorageBackend.h +++ b/src/service/storage/StorageBackend.h @@ -37,6 +37,7 @@ class StorageBackend { public: virtual ~StorageBackend() {} + // TODO: Remove searchDefaultBucket() virtual PolicyBucket searchDefaultBucket(const PolicyKey &key) = 0; virtual PolicyBucket searchBucket(const PolicyBucketId &bucket, const PolicyKey &key) = 0; diff --git a/test/storage/storage/check.cpp b/test/storage/storage/check.cpp index e71e40f..f56e7fe 100644 --- a/test/storage/storage/check.cpp +++ b/test/storage/storage/check.cpp @@ -49,7 +49,7 @@ TEST(storage, checkEmpty) { Cynara::Storage storage(backend); PolicyKey pk = Helpers::generatePolicyKey(); - EXPECT_CALL(backend, searchDefaultBucket(pk)) + EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, pk)) .WillOnce(ReturnPointee(&emptyBucket)); // Default bucket empty -- return DENY @@ -66,7 +66,7 @@ TEST(storage, checkSimple) { Cynara::Storage storage(backend); PolicyKey pk = Helpers::generatePolicyKey(); - EXPECT_CALL(backend, searchDefaultBucket(pk)) + EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, pk)) .WillRepeatedly(ReturnPointee(&bucket)); // Default bucket empty -- return DENY @@ -81,6 +81,7 @@ TEST(storage, checkSimple) { ASSERT_EQ(PredefinedPolicyType::DENY, storage.checkPolicy(pk).policyType()); } +// TODO: Refactorize to resemble checkNonrecursive() TEST(storage, checkBucket) { using ::testing::ReturnPointee; @@ -97,9 +98,6 @@ TEST(storage, checkBucket) { PolicyBucket additionalBucket; - EXPECT_CALL(backend, searchDefaultBucket(pk)) - .WillRepeatedly(ReturnPointee(&defaultBucket)); - EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, pk)) .WillRepeatedly(ReturnPointee(&defaultBucket)); @@ -136,9 +134,6 @@ TEST(storage, checkBucketWildcard) { FakeStorageBackend backend; Cynara::Storage storage(backend); - EXPECT_CALL(backend, searchDefaultBucket(checkKey)) - .WillRepeatedly(ReturnPointee(&defaultBucket)); - EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, checkKey)) .WillRepeatedly(ReturnPointee(&defaultBucket)); @@ -166,9 +161,6 @@ TEST(storage, checkBucketWildcardOtherDefault) { FakeStorageBackend backend; Cynara::Storage storage(backend); - EXPECT_CALL(backend, searchDefaultBucket(checkKey)) - .WillRepeatedly(ReturnPointee(&defaultBucket)); - EXPECT_CALL(backend, searchBucket(defaultPolicyBucketId, checkKey)) .WillRepeatedly(ReturnPointee(&defaultBucket)); @@ -179,3 +171,21 @@ TEST(storage, checkBucketWildcardOtherDefault) { // Should return additional bucket's default policy ASSERT_EQ(PredefinedPolicyType::ALLOW, storage.checkPolicy(checkKey)); } + +TEST(storage, checkNonrecursive) { + using ::testing::ReturnPointee; + + PolicyKey pk = Helpers::generatePolicyKey(); + PolicyBucketId bucketId = "a-bucket"; + + PolicyBucket bucket(bucketId, PredefinedPolicyType::ALLOW, + { Policy::bucketWithKey(pk, "must-not-be-touched") }); + FakeStorageBackend backend; + + Cynara::Storage storage(backend); + + EXPECT_CALL(backend, searchBucket(bucketId, pk)) + .WillOnce(ReturnPointee(&bucket)); + + ASSERT_EQ(PredefinedPolicyType::ALLOW, storage.checkPolicy(pk, bucketId, false)); +} -- 2.7.4 From 88947829a167aa393f228433d903cd10586bd0cc Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Wed, 20 Aug 2014 08:30:23 +0200 Subject: [PATCH 13/16] Support NONE policy in storage Change-Id: I80d28fee394c5e461bccf102b0d6f7b4ab243174 --- .../exceptions/DefaultBucketSetNoneException.h | 44 +++++++++++++ src/common/types/PolicyResult.h | 8 +++ src/common/types/PolicyType.cpp | 4 ++ src/common/types/PolicyType.h | 2 + src/service/storage/Storage.cpp | 14 ++++- test/storage/storage/check.cpp | 73 ++++++++++++++++++++++ test/storage/storage/fakestoragebackend.h | 2 + 7 files changed, 144 insertions(+), 3 deletions(-) create mode 100644 src/common/exceptions/DefaultBucketSetNoneException.h diff --git a/src/common/exceptions/DefaultBucketSetNoneException.h b/src/common/exceptions/DefaultBucketSetNoneException.h new file mode 100644 index 0000000..d9664b3 --- /dev/null +++ b/src/common/exceptions/DefaultBucketSetNoneException.h @@ -0,0 +1,44 @@ +/* + * 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 DefaultBucketSetNoneException.h + * @author Aleksander Zdyb + * @version 1.0 + * @brief Implementation of DefaultBucketSetNoneException + */ + +#ifndef SRC_COMMON_EXCEPTIONS_DEFAULTBUCKETSETNONEEXCEPTION_H_ +#define SRC_COMMON_EXCEPTIONS_DEFAULTBUCKETSETNONEEXCEPTION_H_ + +#include + +#include "Exception.h" + +namespace Cynara { + +class DefaultBucketSetNoneException : public Exception { +public: + DefaultBucketSetNoneException() = default; + virtual ~DefaultBucketSetNoneException() noexcept {}; + + virtual const std::string message(void) const { + return "DefaultBucketSetNoneException"; + } +}; + +} /* namespace Cynara */ + +#endif // SRC_COMMON_EXCEPTIONS_DEFAULTBUCKETSETNONEEXCEPTION_H_ diff --git a/src/common/types/PolicyResult.h b/src/common/types/PolicyResult.h index a9369d8..0e0c716 100644 --- a/src/common/types/PolicyResult.h +++ b/src/common/types/PolicyResult.h @@ -60,9 +60,17 @@ public: return std::tie(m_type, m_metadata) == std::tie(other.m_type, other.m_metadata); } + bool operator !=(const PolicyResult &other) const { + return !(*this == other); + } + bool operator ==(const PolicyType &policyType) const { return (m_type == policyType) && m_metadata.empty(); } + + bool operator !=(const PolicyType &policyType) const { + return !(*this == policyType); + } }; } // namespace Cynara diff --git a/src/common/types/PolicyType.cpp b/src/common/types/PolicyType.cpp index bf022f5..9491f6c 100644 --- a/src/common/types/PolicyType.cpp +++ b/src/common/types/PolicyType.cpp @@ -29,4 +29,8 @@ bool operator ==(const PolicyType &policyType, const PolicyResult &policyResult) return policyResult == policyType; } +bool operator !=(const PolicyType &policyType, const PolicyResult &policyResult) { + return !(policyResult == policyType); +} + } // namespace Cynara diff --git a/src/common/types/PolicyType.h b/src/common/types/PolicyType.h index 9131b1b..e7ad60d 100644 --- a/src/common/types/PolicyType.h +++ b/src/common/types/PolicyType.h @@ -33,12 +33,14 @@ typedef std::uint16_t PolicyType; namespace PredefinedPolicyType { const PolicyType DENY = 0; + const PolicyType NONE = 1; const PolicyType BUCKET = 0xFFFE; const PolicyType ALLOW = 0xFFFF; }; class PolicyResult; bool operator ==(const PolicyType &policyType, const PolicyResult &policyResult); +bool operator !=(const PolicyType &policyType, const PolicyResult &policyResult); } // namespace Cynara diff --git a/src/service/storage/Storage.cpp b/src/service/storage/Storage.cpp index 8e81edc..108ebe8 100644 --- a/src/service/storage/Storage.cpp +++ b/src/service/storage/Storage.cpp @@ -25,7 +25,8 @@ #include #include -#include "exceptions/DefaultBucketDeletionException.h" +#include +#include #include #include #include @@ -69,7 +70,9 @@ PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey if (recursive == true) { auto bucketResults = m_backend.searchBucket(policyResult.metadata(), key); auto minimumOfBucket = minimalPolicy(bucketResults, key, true); - proposeMinimal(minimumOfBucket); + if (minimumOfBucket != PredefinedPolicyType::NONE) { + proposeMinimal(minimumOfBucket); + } } continue; } @@ -112,7 +115,12 @@ void Storage::insertPolicies(const std::map> } } -void Storage::addOrUpdateBucket(const PolicyBucketId &bucketId, const PolicyResult &defaultBucketPolicy) { +void Storage::addOrUpdateBucket(const PolicyBucketId &bucketId, + const PolicyResult &defaultBucketPolicy) { + + if (bucketId == defaultPolicyBucketId && defaultBucketPolicy == PredefinedPolicyType::NONE) + throw DefaultBucketSetNoneException(); + if (m_backend.hasBucket(bucketId)) { m_backend.updateBucket(bucketId, defaultBucketPolicy); } else { diff --git a/test/storage/storage/check.cpp b/test/storage/storage/check.cpp index f56e7fe..e1f6505 100644 --- a/test/storage/storage/check.cpp +++ b/test/storage/storage/check.cpp @@ -189,3 +189,76 @@ TEST(storage, checkNonrecursive) { ASSERT_EQ(PredefinedPolicyType::ALLOW, storage.checkPolicy(pk, bucketId, false)); } + +/* + * bucket1 contains policy (with key pk) pointing to bucket2 + * bucket2 is empty and it's default policy is NONE + * Because NONE policy in bucket2, check should yield default policy of bucket1 and not of bucket2 + */ +TEST(storage, noneBucket) { + using ::testing::ReturnPointee; + using PredefinedPolicyType::ALLOW; + using PredefinedPolicyType::NONE; + + auto pk = Helpers::generatePolicyKey(); + + PolicyBucket bucket2("bucket-2", NONE); + PolicyBucket bucket1("bucket-1", ALLOW, { Policy::bucketWithKey(pk, bucket2.id()) }); + + FakeStorageBackend backend; + Cynara::Storage storage(backend); + + EXPECT_CALL(backend, searchBucket(bucket1.id(), pk)) + .WillOnce(ReturnPointee(&bucket1)); + EXPECT_CALL(backend, searchBucket(bucket2.id(), pk)) + .WillOnce(ReturnPointee(&bucket2)); + + ASSERT_EQ(ALLOW, storage.checkPolicy(pk, bucket1.id(), true)); +} + +/* + * Scenario similar to noneBucket, but bucket2 contains matching policy. + * In this case this policy should be returned. + */ +TEST(storage, noneBucketNotEmpty) { + using ::testing::ReturnPointee; + using PredefinedPolicyType::ALLOW; + using PredefinedPolicyType::DENY; + using PredefinedPolicyType::NONE; + + auto pk = Helpers::generatePolicyKey(); + + PolicyBucket bucket2("bucket-2", NONE, { Policy::simpleWithKey(pk, DENY) }); + PolicyBucket bucket1("bucket-1", ALLOW, { Policy::bucketWithKey(pk, bucket2.id()) }); + + FakeStorageBackend backend; + Cynara::Storage storage(backend); + + EXPECT_CALL(backend, searchBucket(bucket1.id(), pk)) + .WillOnce(ReturnPointee(&bucket1)); + EXPECT_CALL(backend, searchBucket(bucket2.id(), pk)) + .WillOnce(ReturnPointee(&bucket2)); + + ASSERT_EQ(DENY, storage.checkPolicy(pk, bucket1.id(), true)); +} + +/* + * Single empty bucket with default policy of NONE + * -- searching for any key should yield NONE + */ +TEST(storage, singleNoneBucket) { + using ::testing::ReturnPointee; + using PredefinedPolicyType::NONE; + + auto pk = Helpers::generatePolicyKey(); + + PolicyBucket bucket("bucket", NONE, {}); + + FakeStorageBackend backend; + Cynara::Storage storage(backend); + + EXPECT_CALL(backend, searchBucket(bucket.id(), pk)) + .WillOnce(ReturnPointee(&bucket)); + + ASSERT_EQ(NONE, storage.checkPolicy(pk, bucket.id(), true)); +} diff --git a/test/storage/storage/fakestoragebackend.h b/test/storage/storage/fakestoragebackend.h index b1e8b69..fa8898b 100644 --- a/test/storage/storage/fakestoragebackend.h +++ b/test/storage/storage/fakestoragebackend.h @@ -23,6 +23,8 @@ #ifndef FAKESTORAGEBACKEND_H_ #define FAKESTORAGEBACKEND_H_ +#include + using namespace Cynara; class FakeStorageBackend : public StorageBackend { -- 2.7.4 From 5504f5f71535309694ca2926b6fb5afc496990c4 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Wed, 20 Aug 2014 11:24:44 +0200 Subject: [PATCH 14/16] Support NONE policy in admin API Change-Id: I8a54f020f2d69f9c0ad71773b8d32b09f6519b9e --- src/admin/api/admin-api.cpp | 30 ++++++++++++++++++++---------- src/include/cynara-admin.h | 7 +++++-- src/service/logic/Logic.cpp | 13 ++++++++++--- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/src/admin/api/admin-api.cpp b/src/admin/api/admin-api.cpp index 417baa3..ce7e241 100644 --- a/src/admin/api/admin-api.cpp +++ b/src/admin/api/admin-api.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -85,7 +86,7 @@ int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, std::map> insertOrUpdate; std::map> remove; - auto key = ([](const cynara_admin_policy *i)->Cynara::PolicyKey { + auto key = ([](const cynara_admin_policy *policy)->Cynara::PolicyKey { std::string wildcard(CYNARA_ADMIN_WILDCARD); auto feature = ([&wildcard] (const char *str)->Cynara::PolicyKeyFeature { @@ -95,34 +96,37 @@ int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, return Cynara::PolicyKeyFeature::createWildcard(); }); - return Cynara::PolicyKey(feature(i->client), feature(i->user), feature(i->privilege)); + return Cynara::PolicyKey(feature(policy->client), feature(policy->user), + feature(policy->privilege)); }); try { for (auto i = policies; *i; i++) { - if(!(*i)->bucket || !(*i)->client || !(*i)->user || !(*i)->privilege) + const cynara_admin_policy *policy = *i; + if(!policy->bucket || !policy->client || !policy->user || !policy->privilege) return CYNARA_ADMIN_API_INVALID_PARAM; - switch ((*i)->result) { + switch (policy->result) { case CYNARA_ADMIN_DELETE: - remove[(*i)->bucket].push_back(key(*i)); + remove[policy->bucket].push_back(key(policy)); break; case CYNARA_ADMIN_DENY: - insertOrUpdate[(*i)->bucket].push_back(Cynara::Policy(key(*i), + insertOrUpdate[policy->bucket].push_back(Cynara::Policy(key(policy), Cynara::PredefinedPolicyType::DENY)); break; case CYNARA_ADMIN_ALLOW: - insertOrUpdate[(*i)->bucket].push_back(Cynara::Policy(key(*i), + insertOrUpdate[policy->bucket].push_back(Cynara::Policy(key(policy), Cynara::PredefinedPolicyType::ALLOW)); break; case CYNARA_ADMIN_BUCKET: - if (!(*i)->result_extra) + if (!policy->result_extra) return CYNARA_ADMIN_API_INVALID_PARAM; - insertOrUpdate[(*i)->bucket].push_back(Cynara::Policy(key(*i), + insertOrUpdate[policy->bucket].push_back(Cynara::Policy(key(policy), Cynara::PolicyResult( Cynara::PredefinedPolicyType::BUCKET, - (*i)->result_extra))); + policy->result_extra))); break; + case CYNARA_ADMIN_NONE: default: return CYNARA_ADMIN_API_INVALID_PARAM; } @@ -157,6 +161,12 @@ int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *buc case CYNARA_ADMIN_ALLOW: return p_cynara_admin->impl->insertOrUpdateBucket(bucket, Cynara::PolicyResult(Cynara::PredefinedPolicyType::ALLOW, extraStr)); + case CYNARA_ADMIN_NONE: + if (bucket != Cynara::defaultPolicyBucketId) { + return p_cynara_admin->impl->insertOrUpdateBucket(bucket, + Cynara::PolicyResult(Cynara::PredefinedPolicyType::NONE)); + } + return CYNARA_ADMIN_API_OPERATION_NOT_ALLOWED; case CYNARA_ADMIN_BUCKET: default: return CYNARA_ADMIN_API_INVALID_PARAM; diff --git a/src/include/cynara-admin.h b/src/include/cynara-admin.h index b8aec4e..1e0a162 100644 --- a/src/include/cynara-admin.h +++ b/src/include/cynara-admin.h @@ -64,11 +64,14 @@ struct cynara_admin; /*! \brief set policy result or bucket's default policy to DENY */ #define CYNARA_ADMIN_DENY 0 +/*! \brief set bucket's default policy to NONE */ +#define CYNARA_ADMIN_NONE 1 + /*! \brief set policy result or bucket's default policy to ALLOW */ -#define CYNARA_ADMIN_ALLOW 1 +#define CYNARA_ADMIN_ALLOW 2 /*! \brief set policy to point into another bucket */ -#define CYNARA_ADMIN_BUCKET 2 +#define CYNARA_ADMIN_BUCKET 3 /** @}*/ /** diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index 377bcce..2701e86 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include
@@ -90,10 +91,16 @@ bool Logic::check(RequestContextPtr context UNUSED, const PolicyKey &key, } void Logic::execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request) { - m_storage->addOrUpdateBucket(request->bucketId(), request->result()); - onPoliciesChanged(); + auto code = CodeResponse::Code::OK; - context->returnResponse(context, std::make_shared(CodeResponse::Code::OK, + try { + m_storage->addOrUpdateBucket(request->bucketId(), request->result()); + onPoliciesChanged(); + } catch (const DefaultBucketSetNoneException &ex) { + code = CodeResponse::Code::NOT_ALLOWED; + } + + context->returnResponse(context, std::make_shared(code, request->sequenceNumber())); } -- 2.7.4 From 7ca84d1e7ee1845a936c49921c026de4e907336a Mon Sep 17 00:00:00 2001 From: Jacek Bukarewicz Date: Thu, 11 Sep 2014 15:37:41 +0200 Subject: [PATCH 15/16] Add missing 'struct' keyword in cynara-admin.h Change-Id: I48405d368fb8a95a86d6c94df5c50a490869f1e4 --- src/admin/api/admin-api.cpp | 2 +- src/include/cynara-admin.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/admin/api/admin-api.cpp b/src/admin/api/admin-api.cpp index ce7e241..3f6885d 100644 --- a/src/admin/api/admin-api.cpp +++ b/src/admin/api/admin-api.cpp @@ -77,7 +77,7 @@ int cynara_admin_finish(struct cynara_admin *p_cynara_admin) { CYNARA_API int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, - const cynara_admin_policy *const *policies) { + const struct cynara_admin_policy *const *policies) { if (!p_cynara_admin || !p_cynara_admin->impl) return CYNARA_ADMIN_API_INVALID_PARAM; if (!policies) diff --git a/src/include/cynara-admin.h b/src/include/cynara-admin.h index 1e0a162..8260676 100644 --- a/src/include/cynara-admin.h +++ b/src/include/cynara-admin.h @@ -206,7 +206,7 @@ int cynara_admin_finish(struct cynara_admin *p_cynara_admin); * \brief Insert, update or delete policies in cynara database. */ int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, - const cynara_admin_policy *const *policies); + const struct cynara_admin_policy *const *policies); /** * \par Description: -- 2.7.4 From 1c3bee02b5b66ebd389eec9b4fe35c760c170ec9 Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Tue, 26 Aug 2014 10:41:33 +0200 Subject: [PATCH 16/16] Fix startup with half-populated db In some cases, Cynara could start with half-populated database. As this is potential security issue, we now make sure, that in case of any error, Cynara will start with empty database and return DENY for every request. There are added tests revealing these potential issues. Some test cases depend on specific state of Cynara's policy database directory. These are now provided in cynara-tests package and placed in /usr/share/cynara/tests/ during installation. Test execution does not affect real database -- it uses above tests path only, accessible by non-root users as well. Signed-off-by: Aleksander Zdyb Signed-off-by: Pawel Wieczorek Change-Id: Ia943f77a2a0c85f394c40dd10333a73df4d0c96a --- packaging/cynara.spec | 8 ++- .../exceptions/BucketRecordCorruptedException.h | 6 +- src/service/storage/InMemoryStorageBackend.cpp | 11 ++-- test/db/db2/buckets | 1 + test/db/db3/_ | 0 test/db/db3/buckets | 1 + test/db/db4/_ | 0 test/db/db4/_additional | 0 test/db/db4/buckets | 2 + test/db/db5/_ | 0 test/db/db5/_additional | 1 + test/db/db5/buckets | 2 + .../inmemeorystoragebackendfixture.h | 11 ++++ .../inmemorystoragebackend.cpp | 68 +++++++++++++++++++++- 14 files changed, 102 insertions(+), 9 deletions(-) create mode 100644 test/db/db2/buckets create mode 100644 test/db/db3/_ create mode 100644 test/db/db3/buckets create mode 100644 test/db/db4/_ create mode 100644 test/db/db4/_additional create mode 100644 test/db/db4/buckets create mode 100644 test/db/db5/_ create mode 100644 test/db/db5/_additional create mode 100644 test/db/db5/buckets diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 677142b..f4e8d1a 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -29,6 +29,7 @@ BuildRequires: pkgconfig(libsystemd-journal) %global group_name %{name} %global state_path %{_localstatedir}/%{name}/ +%global tests_dir %{_datarootdir}/%{name}/tests %global build_type %{?build_type:%build_type}%{!?build_type:RELEASE} @@ -195,6 +196,7 @@ cp -a %{SOURCE1007} . cp -a %{SOURCE1008} . cp -a %{SOURCE1009} . cp -a %{SOURCE1010} . +cp -a test/db/db* . %build %if 0%{?sec_build_binary_debug_enable} @@ -205,7 +207,8 @@ export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" export CXXFLAGS="$CXXFLAGS -Wp,-U_FORTIFY_SOURCE" %endif -export CXXFLAGS="$CXXFLAGS -DCYNARA_STATE_PATH=\\\"%{state_path}\\\"" +export CXXFLAGS="$CXXFLAGS -DCYNARA_STATE_PATH=\\\"%{state_path}\\\" \ + -DCYNARA_TESTS_DIR=\\\"%{tests_dir}\\\"" export LDFLAGS+="-Wl,--rpath=%{_libdir}" %cmake . \ @@ -221,6 +224,8 @@ rm -rf %{buildroot} mkdir -p %{buildroot}/usr/lib/systemd/system/sockets.target.wants mkdir -p %{buildroot}/%{state_path} +mkdir -p %{buildroot}/%{tests_dir} +cp -a db* %{buildroot}/%{tests_dir} ln -s ../cynara.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/cynara.socket ln -s ../cynara-admin.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/cynara-admin.socket @@ -380,6 +385,7 @@ fi %files -n cynara-tests %manifest cynara-tests.manifest %attr(755,root,root) /usr/bin/cynara-tests +%attr(755,root,root) %{tests_dir}/db*/* %files -n libcynara-creds-commons %manifest libcynara-creds-commons.manifest diff --git a/src/common/exceptions/BucketRecordCorruptedException.h b/src/common/exceptions/BucketRecordCorruptedException.h index 8152a77..335fbc9 100644 --- a/src/common/exceptions/BucketRecordCorruptedException.h +++ b/src/common/exceptions/BucketRecordCorruptedException.h @@ -22,13 +22,13 @@ #ifndef SRC_COMMON_EXCEPTIONS_BUCKETRECORDCORRUPTEDEXCEPTION_H_ #define SRC_COMMON_EXCEPTIONS_BUCKETRECORDCORRUPTEDEXCEPTION_H_ -#include "Exception.h" - #include +#include + namespace Cynara { -class BucketRecordCorruptedException : public Exception { +class BucketRecordCorruptedException : public DatabaseException { public: BucketRecordCorruptedException(void) = delete; virtual ~BucketRecordCorruptedException() noexcept {}; diff --git a/src/service/storage/InMemoryStorageBackend.cpp b/src/service/storage/InMemoryStorageBackend.cpp index 9fee197..20c16cf 100644 --- a/src/service/storage/InMemoryStorageBackend.cpp +++ b/src/service/storage/InMemoryStorageBackend.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -63,13 +64,15 @@ void InMemoryStorageBackend::load(void) { storageDeserializer.initBuckets(buckets()); storageDeserializer.loadBuckets(buckets()); - } catch (const FileNotFoundException &) { - LOGE("Reading cynara database failed."); + } catch (const DatabaseException &) { + LOGC("Reading cynara database failed."); + buckets().clear(); + // TODO: Implement emergency mode toggle } if (!hasBucket(defaultPolicyBucketId)) { - LOGN("Creating defaultBucket."); - this->buckets().insert({ defaultPolicyBucketId, PolicyBucket() }); + LOGN("Creating defaultBucket."); + this->buckets().insert({ defaultPolicyBucketId, PolicyBucket() }); } } diff --git a/test/db/db2/buckets b/test/db/db2/buckets new file mode 100644 index 0000000..b6d719f --- /dev/null +++ b/test/db/db2/buckets @@ -0,0 +1 @@ +;0x0 diff --git a/test/db/db3/_ b/test/db/db3/_ new file mode 100644 index 0000000..e69de29 diff --git a/test/db/db3/buckets b/test/db/db3/buckets new file mode 100644 index 0000000..b6d719f --- /dev/null +++ b/test/db/db3/buckets @@ -0,0 +1 @@ +;0x0 diff --git a/test/db/db4/_ b/test/db/db4/_ new file mode 100644 index 0000000..e69de29 diff --git a/test/db/db4/_additional b/test/db/db4/_additional new file mode 100644 index 0000000..e69de29 diff --git a/test/db/db4/buckets b/test/db/db4/buckets new file mode 100644 index 0000000..19d7a93 --- /dev/null +++ b/test/db/db4/buckets @@ -0,0 +1,2 @@ +;0x0 +additional;0xFFFF diff --git a/test/db/db5/_ b/test/db/db5/_ new file mode 100644 index 0000000..e69de29 diff --git a/test/db/db5/_additional b/test/db/db5/_additional new file mode 100644 index 0000000..d30fa55 --- /dev/null +++ b/test/db/db5/_additional @@ -0,0 +1 @@ +INVALID \ No newline at end of file diff --git a/test/db/db5/buckets b/test/db/db5/buckets new file mode 100644 index 0000000..19d7a93 --- /dev/null +++ b/test/db/db5/buckets @@ -0,0 +1,2 @@ +;0x0 +additional;0xFFFF diff --git a/test/storage/inmemorystoragebackend/inmemeorystoragebackendfixture.h b/test/storage/inmemorystoragebackend/inmemeorystoragebackendfixture.h index 2c6e593..298732c 100644 --- a/test/storage/inmemorystoragebackend/inmemeorystoragebackendfixture.h +++ b/test/storage/inmemorystoragebackend/inmemeorystoragebackendfixture.h @@ -24,6 +24,7 @@ #define INMEMEORYSTORAGEBACKENDFIXTURE_H_ #include +#include #include #include @@ -52,6 +53,16 @@ protected: } } + static void ASSERT_DB_VIRGIN(Cynara::Buckets &buckets) { + using ::testing::IsEmpty; + ASSERT_EQ(1, buckets.size()); + auto defaultBucketIter = buckets.find(Cynara::defaultPolicyBucketId); + ASSERT_NE(buckets.end(), defaultBucketIter); + auto &defaultBucket = defaultBucketIter->second; + ASSERT_THAT(defaultBucket, IsEmpty()); + ASSERT_EQ(Cynara::PredefinedPolicyType::DENY, defaultBucket.defaultPolicy()); + } + virtual ~InMemeoryStorageBackendFixture() {} // TODO: consider defaulting accessor with ON_CALL diff --git a/test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp b/test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp index 6e84475..e81af8f 100644 --- a/test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp +++ b/test/storage/inmemorystoragebackend/inmemorystoragebackend.cpp @@ -23,8 +23,10 @@ #include #include -#include "exceptions/DefaultBucketDeletionException.h" #include "exceptions/BucketNotExistsException.h" +#include "exceptions/BucketDeserializationException.h" +#include "exceptions/DefaultBucketDeletionException.h" +#include "exceptions/FileNotFoundException.h" #include "storage/InMemoryStorageBackend.h" #include "storage/StorageBackend.h" #include "types/PolicyCollection.h" @@ -186,3 +188,67 @@ TEST_F(InMemeoryStorageBackendFixture, deletePolicyFromNonexistentBucket) { EXPECT_THROW(backend.deletePolicy("non-existent", Helpers::generatePolicyKey()), BucketNotExistsException); } + +// Database dir is empty +TEST_F(InMemeoryStorageBackendFixture, load_no_db) { + using ::testing::ReturnRef; + auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/db1/"; + FakeInMemoryStorageBackend backend(testDbPath); + EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets)); + backend.load(); + ASSERT_DB_VIRGIN(m_buckets); +} + +// Database dir contains index with default bucket, but no file for this bucket +TEST_F(InMemeoryStorageBackendFixture, load_no_default) { + using ::testing::ReturnRef; + auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/db2/"; + FakeInMemoryStorageBackend backend(testDbPath); + EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets)); + backend.load(); + ASSERT_DB_VIRGIN(m_buckets); +} + +// Database contains index with default bucket and an empty bucket file +TEST_F(InMemeoryStorageBackendFixture, load_default_only) { + using ::testing::ReturnRef; + auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/db3/"; + FakeInMemoryStorageBackend backend(testDbPath); + EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets)); + backend.load(); + ASSERT_DB_VIRGIN(m_buckets); +} + +// Database contains index with default bucket and an additional bucket +// There are files for both buckets present +TEST_F(InMemeoryStorageBackendFixture, load_2_buckets) { + using ::testing::ReturnRef; + using ::testing::IsEmpty; + + auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/db4/"; + + FakeInMemoryStorageBackend backend(testDbPath); + EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets)); + backend.load(); + + std::vector bucketIds = { "", "additional" }; + + for(const auto &bucketId : bucketIds) { + SCOPED_TRACE(bucketId); + const auto bucketIter = m_buckets.find(bucketId); + ASSERT_NE(m_buckets.end(), bucketIter); + + const auto &bucketPolicies = bucketIter->second; + ASSERT_THAT(bucketPolicies, IsEmpty()); + } +} + +// Database contains index with 2 buckets; 1st bucket is valid, but second is corrupted +TEST_F(InMemeoryStorageBackendFixture, second_bucket_corrupted) { + using ::testing::ReturnRef; + auto testDbPath = std::string(CYNARA_TESTS_DIR) + "/db5/"; + FakeInMemoryStorageBackend backend(testDbPath); + EXPECT_CALL(backend, buckets()).WillRepeatedly(ReturnRef(m_buckets)); + backend.load(); + ASSERT_DB_VIRGIN(m_buckets); +} -- 2.7.4