From 867ee8bbfae554120c68f204c16e3dd0b4b16be5 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Thu, 3 Jul 2014 14:14:14 +0200 Subject: [PATCH 01/16] Move cynara-tests packaging to a separate directory No gmock dependency in main spec file Cynara-tests package can be build by passing "--packaging-dir packaging_tests" to gbs build Change-Id: I786ad78bae0bceca0ae6423f7bf33981435bd189 --- CMakeLists.txt | 2 -- packaging/cynara.spec | 17 +----------- .../cynara-tests.manifest | 0 packaging_tests/cynara-tests.spec | 31 ++++++++++++++++++++++ test/CMakeLists.txt | 27 ++++++++++++++++++- 5 files changed, 58 insertions(+), 19 deletions(-) rename {packaging => packaging_tests}/cynara-tests.manifest (100%) create mode 100644 packaging_tests/cynara-tests.spec diff --git a/CMakeLists.txt b/CMakeLists.txt index 7923083..85bcfdb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,9 +57,7 @@ SET(TARGET_CYNARA "cynara") SET(TARGET_LIB_CYNARA "cynara-client") SET(TARGET_LIB_CYNARA_ADMIN "cynara-admin") SET(TARGET_CYNARA_COMMON "cynara-commons") -SET(TARGET_CYNARA_TESTS "cynara-tests") ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(build) ADD_SUBDIRECTORY(systemd) -ADD_SUBDIRECTORY(test) diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 8ab687f..1d7b8c8 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -8,7 +8,6 @@ Source0: %{name}-%{version}.tar.gz Source1001: cynara.manifest Source1002: libcynara-client.manifest Source1003: libcynara-admin.manifest -Source1004: cynara-tests.manifest BuildRequires: cmake BuildRequires: zip BuildRequires: pkgconfig(libsystemd-daemon) @@ -74,21 +73,11 @@ Requires: cynara = %{version}-%{release} %description -n cynara-devel service (devel version) -####################################################### -%package -n cynara-tests -Summary: Cynara tests -BuildRequires: pkgconfig(gmock) - -%description -n cynara-tests -cynara tests - - %prep %setup -q cp -a %{SOURCE1001} . cp -a %{SOURCE1002} . cp -a %{SOURCE1003} . -cp -a %{SOURCE1004} . %build %if 0%{?sec_build_binary_debug_enable} @@ -202,9 +191,5 @@ fi %files -n libcynara-admin-devel %defattr(-,root,root,-) %{_includedir}/cynara/cynara-admin.h -%{_libdir}/pkgconfig/cynara-admin.pc %{_libdir}/libcynara-admin.so - -%files -n cynara-tests -%manifest cynara-tests.manifest -%attr(755,root,root) /usr/bin/cynara-tests +%{_libdir}/pkgconfig/cynara-admin.pc diff --git a/packaging/cynara-tests.manifest b/packaging_tests/cynara-tests.manifest similarity index 100% rename from packaging/cynara-tests.manifest rename to packaging_tests/cynara-tests.manifest diff --git a/packaging_tests/cynara-tests.spec b/packaging_tests/cynara-tests.spec new file mode 100644 index 0000000..8b1de31 --- /dev/null +++ b/packaging_tests/cynara-tests.spec @@ -0,0 +1,31 @@ +Name: cynara-tests +Summary: Cynara tests +Version: 0.0.1 +Release: 1 +Group: Development/Testing +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source1001: cynara-tests.manifest +BuildRequires: cmake +BuildRequires: pkgconfig(gmock) + +%description +Cynara tests + +%global build_type %{?build_type:%build_type}%{!?build_type:RELEASE} + +%prep +%setup -q +cp -a %{SOURCE1001} . + +%build +%cmake test -DCMAKE_BUILD_TYPE=%{?build_type} \ + -DCMAKE_VERBOSE_MAKEFILE=ON +make %{?jobs:-j%jobs} + +%install +%make_install + +%files +%manifest cynara-tests.manifest +%attr(755,root,root) /usr/bin/cynara-tests diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5828e62..0b6f913 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -17,9 +17,34 @@ # @brief Cmake for tests # +############################# Check minimum CMake version ##################### + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3) +PROJECT("cynara-tests") + +############################# cmake packages ################################## + +INCLUDE(FindPkgConfig) + +############################# compiler flags ################################## + +SET(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb") +SET(CMAKE_CXX_FLAGS_DEBUG "-g -std=c++0x -O0 -ggdb -Wp,-U_FORTIFY_SOURCE") +SET(CMAKE_C_FLAGS_RELEASE "-g -O2") +SET(CMAKE_CXX_FLAGS_RELEASE "-g -std=c++0x -O2") + +# Set compiler warning flags +ADD_DEFINITIONS("-Werror") # Make all warnings into errors. +ADD_DEFINITIONS("-Wall") # Generate all warnings +ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings + +MESSAGE(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") + +SET(TARGET_CYNARA_TESTS "cynara-tests") + PKG_CHECK_MODULES(PKGS REQUIRED gmock_main) -SET(CYNARA_SRC ${PROJECT_SOURCE_DIR}/src) +SET(CYNARA_SRC ${PROJECT_SOURCE_DIR}/../src) SET(CYNARA_SOURCES_FOR_TESTS ${CYNARA_SRC}/service/storage/Storage.cpp -- 2.7.4 From 919aff64e5a7e8767a03e65d8935abade71928d2 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Tue, 1 Jul 2014 21:28:09 +0200 Subject: [PATCH 02/16] Define libcynara-admin API Change-Id: I9d3708ad4a69336e893bcb683d69c3bc613e3054 --- src/include/cynara-admin.h | 208 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 203 insertions(+), 5 deletions(-) diff --git a/src/include/cynara-admin.h b/src/include/cynara-admin.h index 3eb9167..23325a9 100644 --- a/src/include/cynara-admin.h +++ b/src/include/cynara-admin.h @@ -13,21 +13,219 @@ * See the License for the specific language governing permissions and * limitations under the License */ -/* - * @file cynara-admin.h - * @author Lukasz Wojciechowski - * @version 1.0 - * @brief This file contains administration APIs of Cynara available with libcynara-admin. +/** + * \file cynara-admin.h + * \author Lukasz Wojciechowski + * \version 1.0 + * \brief This file contains administration APIs of cynara available with libcynara-admin. */ #ifndef CYNARA_ADMIN_H #define CYNARA_ADMIN_H +/** + * \name Return Codes + * exported by the foundation API. + * result codes begin with the start error code and extend into negative direction. + * @{ +*/ + +/*! \brief indicating the result of the one specific API is successful or access is allowed */ +#define CYNARA_ADMIN_API_SUCCESS 0 + +/*! \brief indicating system is running out of memory state */ +#define CYNARA_ADMIN_API_OUT_OF_MEMORY -1 + +/*! \brief indicating the API's parameter is malformed */ +#define CYNARA_ADMIN_API_INVALID_PARAM -2 + +/*! \brief service not available */ +#define CYNARA_ADMIN_API_SERVICE_NOT_AVAILABLE -3 +/** @}*/ + #ifdef __cplusplus extern "C" { #endif +//todo comment +const char *CYNARA_ADMIN_WILDCARD = "*"; + +//todo comment +const char *CYNARA_ADMIN_DEFAULT_BUCKET = ""; + +//todo comments +#define CYNARA_ADMIN_DELETE -1 +#define CYNARA_ADMIN_DENY 0 +#define CYNARA_ADMIN_ALLOW 1 +#define CYNARA_ADMIN_BUCKET 2 + +//todo comments +struct cynara_admin_policy { + const char *bucket; + + const char *client; + const char *user; + const char *privilege; + + int result; + const char *result_extra; +}; + +/** + * \par Description: + * Initialize cynara-admin library. + * Creates structure used in following API calls. + * + * \par Purpose: + * This function must be invoked prior to other admin API calls. It creates structure needed by + * other cynara-admin library API functions. + * + * \par Typical use case: + * Once before a service can call other cynara-admin library functions. + * + * \par Method of function operation: + * This API initializes inner library structures and in case of success creates cynara_admin + * structure and stores pointer to this structure at memory address passed in pp_cynara_admin + * parameter. + * + * \par Sync (or) async: + * This is a synchronous API. + * + * \par Important notes: + * Structure cynara_admin created by cynara_admin_initialize call should be released with + * cynara_admin_finish. + * + * \param[out] pp_cynara_admin address of pointer for created cynara_admin structure. + * + * \return CYNARA_ADMIN_API_SUCCESS on success, or error code otherwise. + * + * \brief Initialize cynara-admin library. + */ +int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin); + +/** + * \par Description: + * Releases cynara-admin library and destroys structure created with cynara_admin_initialize + * function. + * + * \par Purpose: + * This API should be used to clean up after usage of cynara-admin library. + * + * \par Typical use case: + * Function should be called once, when done with cynara-admin library API usage. + * + * \par Method of function operation: + * This API releases inner library structures and destroys cynara_admin structure. + * + * \par Sync (or) Async: + * This is a Synchronous API. + * + * \par Important notes: + * No invocations of cynara-admin library API functions are allowed after call to + * cynara_admin_finish. + * + * \param[in] p_cynara_admin cynara_admin structure created in cynara_admin_initialize. + * + * \return CYNARA_ADMIN_API_SUCCESS on success, or error code otherwise. + * + * \brief Release cynara-admin library. + */ +int cynara_admin_finish(cynara_admin *p_cynara_admin); + +/** + * \par Description: + * Manages policies in cynara. + * + * \par Purpose: + * This API should be used to insert, update or delete policies in cynara. + * + * \par Typical use case: + * Enables privileged services to alter policies by adding, updating or removing records. + * + * \par Method of function operation: + * Policies are arranged into buckets. Every policy is defined in context of some bucket identified + * with bucket field (string). A bucket consists of policies identified with tripple: (client, user, + * privilege), which is a (unique) key within considered bucket. + * + * Every policy can be one of two types: simple or bucket-pointing policy. + * Simple policies have result field with value of CYNARA_ADMIN_DENY or CYNARA_ADMIN_ALLOW. + * result_extra field should be NULL in this case. + * Bucket-pointing policies have result field with value of CYNARA_ADMIN_BUCKET and name of bucket + * they point to in result_extra field. + * + * Type of operation, which is run for every record (single policy) is defined by result field in + * cynara_admin_policy structure. + * In case of CYNARA_ADMIN_DENY or CYNARA_ADMIN_ALLOW a simple policy is updated or inserted into + * cynara database. + * In case of CYNARA_ADMIN_BUCKET, a bucket-pointing policy is updated or inserted into cynara + * database. + * In case of CYNARA_ADMIN_DELETE, a policy is removed from cynara database. + * One call of cynara_admin_insert_policies can manage many different policies in different buckets. + * + * However, considered buckets must exist before referring to them in policies. + * + * \par Sync (or) Async: + * This is a Synchronous API. + * + * \par Important notes: + * When plugin API will be specified, there will be more valid types to pass as result. + * Numerical values of defines CYNARA_ADMIN_... may change, so usage of defines names is strongly + * recommended. + * + * In case of error, database may end up in a state, where changes are partially applied. This is + * going to be fixed along with introduction of transactions in future releases. + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[in] policies NULL terminated array of policy structures + * + * \return CYNARA_ADMIN_API_SUCCESS on success, or error code otherwise. + * + * \brief Insert, update or delete policies in cynara database. + */ +int cynara_admin_set_policies(cynara_admin *p_cynara_admin, const cynara_admin_policy *policies); + +/** + * \par Description: + * Adds new, updates or removes existing bucket for policies in cynara. + * + * \par Purpose: + * This API should be used to add, remove or update buckets. + * + * \par Typical use case: + * Enables privileged services to alter policies database by adding, updating or removing buckets. + * + * \par Method of function operation: + * Every bucket has a default policy. During search, if no policy matches the searched key (client, + * user, privilege), default policy is returned. + + * Operation run on a single bucket defined with bucket parameter. + + * Operation parameter defines what should happen with bucket. In case of: + * CYNARA_ADMIN_DENY, a bucket is inserted or updated with CYNARA_ADMIN_DENY default policy; + * CYNARA_ADMIN_ALLOW, a bucket is inserted or updated with CYNARA_ADMIN_ALLOW default policy; + * CYNARA_ADMIN_DELETE, a bucket is removed with all policies that were kept in it. + * + * \par Sync (or) Async: + * This is a Synchronous API. + * + * \par Important notes: + * When plugin API will be specified, there will be more valid types to pass as operation / default + * policy. Numerical values of defines CYNARA_ADMIN_... may change, so usages of provided consts is + * strongly recommended. + * + * Default bucket identified with CYNARA_ADMIN_DEFAULT_BUCKET exists always. Its default policy + * is preset to DENY (can be altered, however). Default bucket cannot be removed. + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[in] bucket bucket name + * \param[in] operation type of operation (default policy or CYNARA_ADMIN_DELETE) + * + * \return CYNARA_ADMIN_API_SUCCESS on success, or error code otherwise. + * + * \brief Add, remove or update buckets in cynara database. + */ +int cynara_admin_set_bucket(cynara_admin *p_cynara_admin, const char *bucket, int operation); #ifdef __cplusplus } -- 2.7.4 From 46390d326e6659323090c0043229e4461ee5ace4 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Wed, 2 Jul 2014 09:28:35 +0200 Subject: [PATCH 03/16] Make SocketClient independent of specific protocol and path Add protocol and socket path to SocketClient constructor. Pass path to client socket and ProtocolClient object to SocketClient in libcynara-client Logic class. Change-Id: I45e991b8309616876248289558265e5df915012d --- src/client/logic/Logic.cpp | 7 ++++++- src/client/sockets/SocketClient.cpp | 7 ++----- src/client/sockets/SocketClient.h | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/client/logic/Logic.cpp b/src/client/logic/Logic.cpp index 4a46c33..6b04973 100644 --- a/src/client/logic/Logic.cpp +++ b/src/client/logic/Logic.cpp @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include #include @@ -38,8 +40,11 @@ namespace Cynara { +const std::string clientSocketPath("/run/cynara/cynara.socket"); + Logic::Logic() { - m_socketClient = std::make_shared(); + m_socketClient = std::make_shared(clientSocketPath, + std::make_shared()); } cynara_api_result Logic::check(const std::string &client, const std::string &session UNUSED, diff --git a/src/client/sockets/SocketClient.cpp b/src/client/sockets/SocketClient.cpp index 9bab9b1..90f89de 100644 --- a/src/client/sockets/SocketClient.cpp +++ b/src/client/sockets/SocketClient.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -37,10 +36,8 @@ namespace Cynara { -const std::string clientSocketPath("/run/cynara/cynara.socket"); - -SocketClient::SocketClient() : m_socket(clientSocketPath), - m_protocol(std::make_shared()) { +SocketClient::SocketClient(const std::string &socketPath, ProtocolPtr protocol) + : m_socket(socketPath), m_protocol(protocol) { } ResponsePtr SocketClient::askCynaraServer(RequestPtr request) { diff --git a/src/client/sockets/SocketClient.h b/src/client/sockets/SocketClient.h index f0af703..d3e16a1 100644 --- a/src/client/sockets/SocketClient.h +++ b/src/client/sockets/SocketClient.h @@ -46,7 +46,7 @@ private: BinaryQueue m_writeQueue; public: - SocketClient(); + SocketClient(const std::string &socketPath, ProtocolPtr protocol); virtual ~SocketClient() = default; //returns pointer to response -- 2.7.4 From 62d0e2190cdd6d2feb1f25efb4a1add2aa99d3c4 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Wed, 2 Jul 2014 09:34:08 +0200 Subject: [PATCH 04/16] Raw move of client socket classes to common library This will allow usage of same classes in libcynara-admin library. This patch does not compile. Please verify it with following patch. Change-Id: Ib0d2032e2e843ad9bdb34e6a087037436ff8a12f --- src/{client => common}/sockets/Socket.cpp | 0 src/{client => common}/sockets/Socket.h | 0 src/{client => common}/sockets/SocketClient.cpp | 0 src/{client => common}/sockets/SocketClient.h | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename src/{client => common}/sockets/Socket.cpp (100%) rename src/{client => common}/sockets/Socket.h (100%) rename src/{client => common}/sockets/SocketClient.cpp (100%) rename src/{client => common}/sockets/SocketClient.h (100%) diff --git a/src/client/sockets/Socket.cpp b/src/common/sockets/Socket.cpp similarity index 100% rename from src/client/sockets/Socket.cpp rename to src/common/sockets/Socket.cpp diff --git a/src/client/sockets/Socket.h b/src/common/sockets/Socket.h similarity index 100% rename from src/client/sockets/Socket.h rename to src/common/sockets/Socket.h diff --git a/src/client/sockets/SocketClient.cpp b/src/common/sockets/SocketClient.cpp similarity index 100% rename from src/client/sockets/SocketClient.cpp rename to src/common/sockets/SocketClient.cpp diff --git a/src/client/sockets/SocketClient.h b/src/common/sockets/SocketClient.h similarity index 100% rename from src/client/sockets/SocketClient.h rename to src/common/sockets/SocketClient.h -- 2.7.4 From 918289136936220302a30cc3f1e75e3b32e66c2c Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Wed, 2 Jul 2014 09:49:41 +0200 Subject: [PATCH 05/16] Adjust client socket classes after move to common library Fix #ifndef guards, include paths and CMakeLists. This patch should be verified together with previous one (Raw move). Change-Id: I81640c5297c11435e2fe0e8b18c9d37ded5318a3 --- src/client/CMakeLists.txt | 2 -- src/client/logic/Logic.cpp | 2 +- src/client/logic/Logic.h | 3 ++- src/common/CMakeLists.txt | 2 ++ src/common/sockets/Socket.cpp | 2 ++ src/common/sockets/Socket.h | 8 ++++---- src/common/sockets/SocketClient.cpp | 1 - src/common/sockets/SocketClient.h | 9 ++++----- 8 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 2f51764..89fe001 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -24,8 +24,6 @@ SET(CYNARA_LIB_CYNARA_PATH ${CYNARA_PATH}/client) SET(LIB_CYNARA_SOURCES ${CYNARA_LIB_CYNARA_PATH}/api/client-api.cpp ${CYNARA_LIB_CYNARA_PATH}/logic/Logic.cpp - ${CYNARA_LIB_CYNARA_PATH}/sockets/Socket.cpp - ${CYNARA_LIB_CYNARA_PATH}/sockets/SocketClient.cpp ) INCLUDE_DIRECTORIES( diff --git a/src/client/logic/Logic.cpp b/src/client/logic/Logic.cpp index 6b04973..aa62511 100644 --- a/src/client/logic/Logic.cpp +++ b/src/client/logic/Logic.cpp @@ -32,10 +32,10 @@ #include #include #include +#include #include #include -#include #include "Logic.h" namespace Cynara { diff --git a/src/client/logic/Logic.h b/src/client/logic/Logic.h index 512b313..e16a451 100644 --- a/src/client/logic/Logic.h +++ b/src/client/logic/Logic.h @@ -25,9 +25,10 @@ #include -#include #include +#include + namespace Cynara { class Logic : public ApiInterface { diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index dbc5c3a..a689435 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -32,6 +32,8 @@ SET(COMMON_SOURCES ${COMMON_PATH}/request/RequestTaker.cpp ${COMMON_PATH}/response/CheckResponse.cpp ${COMMON_PATH}/response/ResponseTaker.cpp + ${COMMON_PATH}/sockets/Socket.cpp + ${COMMON_PATH}/sockets/SocketClient.cpp ${COMMON_PATH}/types/PolicyBucket.cpp ${COMMON_PATH}/types/PolicyKey.cpp ) diff --git a/src/common/sockets/Socket.cpp b/src/common/sockets/Socket.cpp index cddd05f..81be8d4 100644 --- a/src/common/sockets/Socket.cpp +++ b/src/common/sockets/Socket.cpp @@ -31,6 +31,8 @@ #include #include +#include +#include #include #include #include diff --git a/src/common/sockets/Socket.h b/src/common/sockets/Socket.h index 7c6a286..7ea8c61 100644 --- a/src/common/sockets/Socket.h +++ b/src/common/sockets/Socket.h @@ -21,12 +21,12 @@ * @brief This file contains definition of UNIX client socket class */ -#ifndef SRC_CLIENT_SOCKETS_SOCKET_H_ -#define SRC_CLIENT_SOCKETS_SOCKET_H_ +#ifndef SRC_COMMON_SOCKETS_SOCKET_H_ +#define SRC_COMMON_SOCKETS_SOCKET_H_ #include -#include +#include namespace Cynara { @@ -76,4 +76,4 @@ public: } // namespace Cynara -#endif /* SRC_CLIENT_SOCKETS_SOCKET_H_ */ +#endif /* SRC_COMMON_SOCKETS_SOCKET_H_ */ diff --git a/src/common/sockets/SocketClient.cpp b/src/common/sockets/SocketClient.cpp index 90f89de..6eff9f5 100644 --- a/src/common/sockets/SocketClient.cpp +++ b/src/common/sockets/SocketClient.cpp @@ -29,7 +29,6 @@ #include #include #include - #include #include "SocketClient.h" diff --git a/src/common/sockets/SocketClient.h b/src/common/sockets/SocketClient.h index d3e16a1..04f0436 100644 --- a/src/common/sockets/SocketClient.h +++ b/src/common/sockets/SocketClient.h @@ -20,17 +20,16 @@ * @brief This file contains definition of cynara's socket client */ -#ifndef SRC_CLIENT_SOCKETS_SOCKETCLIENT_H_ -#define SRC_CLIENT_SOCKETS_SOCKETCLIENT_H_ +#ifndef SRC_COMMON_SOCKETS_SOCKETCLIENT_H_ +#define SRC_COMMON_SOCKETS_SOCKETCLIENT_H_ #include -#include +#include #include #include #include #include - #include namespace Cynara { @@ -56,4 +55,4 @@ public: } // namespace Cynara -#endif /* SRC_CLIENT_SOCKETS_SOCKETCLIENT_H_ */ +#endif /* SRC_COMMON_SOCKETS_SOCKETCLIENT_H_ */ -- 2.7.4 From 06e6660091c44b06164538add59e21b15b235b1c Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Thu, 26 Jun 2014 10:04:17 +0200 Subject: [PATCH 06/16] Add protocol deserialialization mechanism Change-Id: Id3b24f67a639f22cfd2995880ad3b21593318822 --- src/client/logic/Logic.cpp | 4 +- src/common/CMakeLists.txt | 3 + src/common/containers/BinaryQueue.h | 2 +- src/common/exceptions/InvalidProtocolException.h | 75 ++++++++++++ src/common/protocol/Protocol.h | 8 ++ src/common/protocol/ProtocolClient.cpp | 50 +++++++- src/common/protocol/ProtocolClient.h | 8 ++ src/common/protocol/ProtocolFrame.cpp | 44 +++++++ src/common/protocol/ProtocolFrame.h | 67 +++++++++++ src/common/protocol/ProtocolFrameHeader.cpp | 47 ++++++++ src/common/protocol/ProtocolFrameHeader.h | 114 ++++++++++++++++++ src/common/protocol/ProtocolFrameSerializer.cpp | 78 +++++++++++++ src/common/protocol/ProtocolFrameSerializer.h | 43 +++++++ src/common/protocol/ProtocolOpCode.h | 48 ++++++++ src/common/protocol/ProtocolSerialization.h | 141 ++++++++++++++++++----- src/common/request/CheckRequest.h | 3 +- src/common/request/Request.h | 13 ++- src/common/request/RequestTaker.cpp | 3 + src/common/types/ProtocolFields.h | 39 +++++++ 19 files changed, 753 insertions(+), 37 deletions(-) create mode 100644 src/common/exceptions/InvalidProtocolException.h create mode 100644 src/common/protocol/ProtocolFrame.cpp create mode 100644 src/common/protocol/ProtocolFrame.h create mode 100644 src/common/protocol/ProtocolFrameHeader.cpp create mode 100644 src/common/protocol/ProtocolFrameHeader.h create mode 100644 src/common/protocol/ProtocolFrameSerializer.cpp create mode 100644 src/common/protocol/ProtocolFrameSerializer.h create mode 100644 src/common/protocol/ProtocolOpCode.h create mode 100644 src/common/types/ProtocolFields.h diff --git a/src/client/logic/Logic.cpp b/src/client/logic/Logic.cpp index aa62511..597c8e4 100644 --- a/src/client/logic/Logic.cpp +++ b/src/client/logic/Logic.cpp @@ -56,7 +56,9 @@ cynara_api_result Logic::check(const std::string &client, const std::string &ses //Ask cynara service PolicyResult result(PredefinedPolicyType::DENY); try { - RequestPtr request = std::make_shared(PolicyKey(client, user, privilege)); + // todo handle sequence number correctly + ProtocolFrameSequenceNumber sequenceNumber = 0; + RequestPtr request = std::make_shared(PolicyKey(client, user, privilege), sequenceNumber); ResponsePtr response = m_socketClient->askCynaraServer(request); if (!response) { LOGW("Disconnected by cynara server."); diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index a689435..5e6308a 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -26,6 +26,9 @@ SET(COMMON_SOURCES ${COMMON_PATH}/log/log.cpp ${COMMON_PATH}/protocol/ProtocolAdmin.cpp ${COMMON_PATH}/protocol/ProtocolClient.cpp + ${COMMON_PATH}/protocol/ProtocolFrame.cpp + ${COMMON_PATH}/protocol/ProtocolFrameHeader.cpp + ${COMMON_PATH}/protocol/ProtocolFrameSerializer.cpp ${COMMON_PATH}/protocol/ProtocolSerialization.cpp ${COMMON_PATH}/protocol/ProtocolSignal.cpp ${COMMON_PATH}/request/CheckRequest.cpp diff --git a/src/common/containers/BinaryQueue.h b/src/common/containers/BinaryQueue.h index ada9a3e..ccfbffe 100644 --- a/src/common/containers/BinaryQueue.h +++ b/src/common/containers/BinaryQueue.h @@ -32,7 +32,7 @@ namespace Cynara { * Binary queue auto pointer */ class BinaryQueue; -typedef std::auto_ptr BinaryQueueAutoPtr; +typedef std::shared_ptr BinaryQueuePtr; /** * Binary stream implemented as constant size bucket list diff --git a/src/common/exceptions/InvalidProtocolException.h b/src/common/exceptions/InvalidProtocolException.h new file mode 100644 index 0000000..8b1317b --- /dev/null +++ b/src/common/exceptions/InvalidProtocolException.h @@ -0,0 +1,75 @@ +/* + * 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 InvalidProtocolException.h + * @author Adam Malinowski + * @version 1.0 + * @brief Implementation of InvalidProtocolException + */ + +#ifndef SRC_COMMON_EXCEPTIONS_INVALIDPROTOCOLEXCEPTION_H_ +#define SRC_COMMON_EXCEPTIONS_INVALIDPROTOCOLEXCEPTION_H_ + +#include +#include + +#include "Exception.h" + +namespace Cynara { + +class InvalidProtocolException : public Exception { +public: + enum ExceptionType { + InvalidSignature, + WrongOpCode, + Other + }; + +private: + std::string m_whatMessage; + ExceptionType m_exceptionType; + +public: + InvalidProtocolException(ExceptionType exceptionType) : + m_exceptionType(exceptionType) { + switch(m_exceptionType) { + case InvalidSignature: + m_whatMessage = "No valid signature found"; + break; + case WrongOpCode: + m_whatMessage = "Wrong request code"; + break; + case Other: + m_whatMessage = "Unknown problem"; + break; + } + + } + + virtual ~InvalidProtocolException() = default; + + virtual const char *what(void) const noexcept { + return m_whatMessage.c_str(); + } + + ExceptionType exceptionTyp(void) const { + return m_exceptionType; + } +}; + +} // namespace Cynara + +#endif /* SRC_COMMON_EXCEPTIONS_INVALIDPROTOCOLEXCEPTION_H_ */ diff --git a/src/common/protocol/Protocol.h b/src/common/protocol/Protocol.h index 56ee51e..daf001c 100644 --- a/src/common/protocol/Protocol.h +++ b/src/common/protocol/Protocol.h @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -45,6 +46,13 @@ public: virtual RequestPtr extractRequestFromBuffer(BinaryQueue &bufferQueue) = 0; virtual ResponsePtr extractResponseFromBuffer(BinaryQueue &bufferQueue) = 0; + + ProtocolFrameHeader &frameHeader(void) { + return m_frameHeader; + } + +protected: + ProtocolFrameHeader m_frameHeader; }; } // namespace Cynara diff --git a/src/common/protocol/ProtocolClient.cpp b/src/common/protocol/ProtocolClient.cpp index 4e98d53..2671eb7 100644 --- a/src/common/protocol/ProtocolClient.cpp +++ b/src/common/protocol/ProtocolClient.cpp @@ -16,12 +16,23 @@ /* * @file ProtocolClient.cpp * @author Lukasz Wojciechowski + * @author Adam Malinowski * @version 1.0 * @brief This file implements protocol class for communication with client */ #include #include + +#include +#include +#include +#include +#include +#include +#include +#include + #include "ProtocolClient.h" namespace Cynara { @@ -36,9 +47,33 @@ ProtocolPtr ProtocolClient::clone(void) { return std::make_shared(); } +RequestPtr ProtocolClient::deserializeCheckRequest(ProtocolFrameHeader &frame) { + std::string clientId, userId, privilegeId; + ProtocolDeserialization::deserialize(frame, clientId); + ProtocolDeserialization::deserialize(frame, userId); + ProtocolDeserialization::deserialize(frame, privilegeId); + return std::make_shared(PolicyKey(clientId, userId, privilegeId), + frame.sequenceNumber()); +} + RequestPtr ProtocolClient::extractRequestFromBuffer(BinaryQueue &bufferQueue) { - TODO_USE_ME(bufferQueue); - return RequestPtr(nullptr); + ProtocolFrameSerializer::deserializeHeader(m_frameHeader, bufferQueue); + + if (m_frameHeader.isFrameComplete()) { + ProtocolOpCode requestId; + + m_frameHeader.resetState(); + ProtocolDeserialization::deserialize(m_frameHeader, requestId); + switch (requestId) { + case OpCheckPolicy: + return deserializeCheckRequest(m_frameHeader); + default: + throw InvalidProtocolException(InvalidProtocolException::WrongOpCode); + break; + } + } + + return nullptr; } ResponsePtr ProtocolClient::extractResponseFromBuffer(BinaryQueue &bufferQueue) { @@ -46,4 +81,15 @@ ResponsePtr ProtocolClient::extractResponseFromBuffer(BinaryQueue &bufferQueue) return ResponsePtr(nullptr); } +void ProtocolClient::execute(RequestContextPtr context, CheckRequestPtr request) { + ProtocolFramePtr frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber()); + + ProtocolSerialization::serialize(*frame, OpCheckPolicy); + ProtocolSerialization::serialize(*frame, request->key().client().value()); + ProtocolSerialization::serialize(*frame, request->key().user().value()); + ProtocolSerialization::serialize(*frame, request->key().privilege().value()); + + ProtocolFrameSerializer::finishSerialization(frame, context->responseQueue()); +} + } // namespace Cynara diff --git a/src/common/protocol/ProtocolClient.h b/src/common/protocol/ProtocolClient.h index 0b5cdb9..1cd608b 100644 --- a/src/common/protocol/ProtocolClient.h +++ b/src/common/protocol/ProtocolClient.h @@ -23,6 +23,9 @@ #ifndef SRC_COMMON_PROTOCOL_PROTOCOLCLIENT_H_ #define SRC_COMMON_PROTOCOL_PROTOCOLCLIENT_H_ +#include +#include + #include "Protocol.h" namespace Cynara { @@ -36,6 +39,11 @@ public: virtual RequestPtr extractRequestFromBuffer(BinaryQueue &bufferQueue); virtual ResponsePtr extractResponseFromBuffer(BinaryQueue &bufferQueue); + + virtual void execute(RequestContextPtr context, CheckRequestPtr request); + +private: + RequestPtr deserializeCheckRequest(ProtocolFrameHeader &frame); }; } // namespace Cynara diff --git a/src/common/protocol/ProtocolFrame.cpp b/src/common/protocol/ProtocolFrame.cpp new file mode 100644 index 0000000..0ca0be6 --- /dev/null +++ b/src/common/protocol/ProtocolFrame.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Wojciechowski + * + * 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 ProtocolFrame.cpp + * @author Adam Malinowski + * @version 1.0 + * @brief Implementation of ProtocolFrame class. + */ + +#include + +#include "ProtocolFrame.h" + +namespace Cynara { + +ProtocolFrame::ProtocolFrame(ProtocolFrameHeaderPtr frameHeader, BinaryQueuePtr data) : + m_frameHeader(frameHeader), m_frameBodyContent(data) { +} + +void ProtocolFrame::read(size_t num, void *bytes) { + m_frameBodyContent->flattenConsume(bytes, num); +} + +void ProtocolFrame::write(size_t num, const void *bytes) { + m_frameBodyContent->appendCopy(bytes, num); + m_frameHeader->increaseFrameLength(num); +} + +} /* namespace Cynara */ diff --git a/src/common/protocol/ProtocolFrame.h b/src/common/protocol/ProtocolFrame.h new file mode 100644 index 0000000..709196e --- /dev/null +++ b/src/common/protocol/ProtocolFrame.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Wojciechowski + * + * 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 ProtocolFrame.h + * @author Adam Malinowski + * @version 1.0 + * @brief Header for ProtocolFrame class. + */ + +#ifndef SRC_COMMON_PROTOCOL_PROTOCOLFRAME_H_ +#define SRC_COMMON_PROTOCOL_PROTOCOLFRAME_H_ + +#include +#include + +#include +#include +#include + +namespace Cynara { + +class ProtocolFrameSerializer; + +class ProtocolFrame: public IStream { + +public: + ProtocolFrame(ProtocolFrameHeaderPtr frameHeader, BinaryQueuePtr headerContent); + virtual ~ProtocolFrame() = default; + + ProtocolFrameHeaderPtr frameHeader(void) { + return m_frameHeader; + } + + virtual void read(size_t num, void *bytes); + virtual void write(size_t num, const void *bytes); + +private: + ProtocolFrameHeaderPtr m_frameHeader; + BinaryQueuePtr m_frameBodyContent; + + BinaryQueue &bodyContent(void) { + return *m_frameBodyContent; + } + + friend class ProtocolFrameSerializer; +}; + +typedef std::shared_ptr ProtocolFramePtr; + +} /* namespace Cynara */ + +#endif /* SRC_COMMON_PROTOCOL_PROTOCOLFRAME_H_ */ diff --git a/src/common/protocol/ProtocolFrameHeader.cpp b/src/common/protocol/ProtocolFrameHeader.cpp new file mode 100644 index 0000000..b8d5a37 --- /dev/null +++ b/src/common/protocol/ProtocolFrameHeader.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Wojciechowski + * + * 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 ProtocolFrameHeader.cpp + * @author Adam Malinowski + * @version 1.0 + * @brief Implementation of protocol frame header (de)serializer class. + */ + +#include +#include + +#include "ProtocolFrameHeader.h" + +namespace Cynara { + +const ProtocolFrameSignature ProtocolFrameHeader::m_signature = "CPv1"; + +ProtocolFrameHeader::ProtocolFrameHeader(BinaryQueuePtr headerContent) : + m_frameHeaderContent(headerContent), m_frameLength(0), m_sequenceNumber(0), + m_headerComplete(false), m_bodyComplete(false) { +} + +void ProtocolFrameHeader::read(size_t num, void *bytes) { + m_frameHeaderContent->flattenConsume(bytes, num); +} + +void ProtocolFrameHeader::write(size_t num, const void *bytes) { + m_frameHeaderContent->appendCopy(bytes, num); +} + +} /* namespace Cynara */ diff --git a/src/common/protocol/ProtocolFrameHeader.h b/src/common/protocol/ProtocolFrameHeader.h new file mode 100644 index 0000000..0db0d6b --- /dev/null +++ b/src/common/protocol/ProtocolFrameHeader.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Wojciechowski + * + * 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 ProtocolFrameHeader.h + * @author Adam Malinowski + * @version 1.0 + * @brief Header file for protocol frame header (de)serializer class. + */ + +#ifndef SRC_COMMON_PROTOCOL_PROTOCOLFRAMEHEADER_H_ +#define SRC_COMMON_PROTOCOL_PROTOCOLFRAMEHEADER_H_ + +#include + +#include +#include +#include + +namespace Cynara { + +class ProtocolFrameSerializer; + +class ProtocolFrameHeader: public IStream { +private: + static const ProtocolFrameSignature m_signature; + static size_t frameHeaderLength(void) { + return m_signature.size() + + sizeof(ProtocolFrameLength) + + sizeof(ProtocolFrameSequenceNumber); + } + +public: + ProtocolFrameHeader(BinaryQueuePtr headerContent = nullptr); + virtual ~ProtocolFrameHeader() = default; + + virtual void read(size_t num, void *bytes); + virtual void write(size_t num, const void *bytes); + + ProtocolFrameSequenceNumber sequenceNumber(void) { + return m_sequenceNumber; + } + + bool isHeaderComplete(void) { + return m_headerComplete; + } + + bool isFrameComplete(void) { + return m_headerComplete && m_bodyComplete; + } + + void resetState(void) { + m_headerComplete = false; + m_bodyComplete = false; + } + + ProtocolFrameLength frameLength(void) { + return m_frameLength; + } + +private: + BinaryQueuePtr m_frameHeaderContent; + ProtocolFrameLength m_frameLength; + ProtocolFrameSequenceNumber m_sequenceNumber; + bool m_headerComplete; + bool m_bodyComplete; + + void setSequenceNumber(ProtocolFrameSequenceNumber sequenceNumber) { + m_sequenceNumber = sequenceNumber; + } + + void increaseFrameLength(ProtocolFrameLength size) { + m_frameLength += size; + } + + BinaryQueue &headerContent(void) { + return *m_frameHeaderContent; + } + + void setHeaderContent(BinaryQueuePtr headerContent) { + m_frameHeaderContent = headerContent; + } + + void setHeaderComplete(void) { + m_headerComplete = true; + } + + void setBodyComplete(void) { + m_bodyComplete = true; + } + + friend class ProtocolFrame; + friend class ProtocolFrameSerializer; +}; + +typedef std::shared_ptr ProtocolFrameHeaderPtr; + +} /* namespace Cynara */ + +#endif /* SRC_COMMON_PROTOCOL_PROTOCOLFRAMEHEADER_H_ */ diff --git a/src/common/protocol/ProtocolFrameSerializer.cpp b/src/common/protocol/ProtocolFrameSerializer.cpp new file mode 100644 index 0000000..25a5649 --- /dev/null +++ b/src/common/protocol/ProtocolFrameSerializer.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Wojciechowski + * + * 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 ProtocolSerializer.cpp + * @author Adam Malinowski + * @version 1.0 + * @brief Implementation of protocol frame (de)serializer class. + */ + +#include +#include + +#include "ProtocolFrameSerializer.h" + +namespace Cynara { + +void ProtocolFrameSerializer::deserializeHeader(ProtocolFrameHeader &frameHeader, + BinaryQueue &data) { + if (!frameHeader.isHeaderComplete()) { + if ((data.size() < ProtocolFrameHeader::frameHeaderLength())) { + return; + } + + frameHeader.setHeaderContent(BinaryQueuePtr(&data, [=] (BinaryQueue *) {})); + + ProtocolFrameSignature signature; + ProtocolDeserialization::deserialize(frameHeader, frameHeader.m_signature.length(), + signature); + if (ProtocolFrameHeader::m_signature != signature) { + throw InvalidProtocolException(InvalidProtocolException::InvalidSignature); + } + + ProtocolDeserialization::deserialize(frameHeader, frameHeader.m_frameLength); + ProtocolDeserialization::deserialize(frameHeader, frameHeader.m_sequenceNumber); + + frameHeader.setHeaderComplete(); + } + + if (data.size() >= (frameHeader.frameLength() - ProtocolFrameHeader::frameHeaderLength())) { + frameHeader.setBodyComplete(); + } +} + +ProtocolFramePtr ProtocolFrameSerializer::startSerialization(ProtocolFrameSequenceNumber sequenceNumber) { + BinaryQueuePtr headerQueue = std::make_shared(); + BinaryQueuePtr bodyQueue = std::make_shared(); + ProtocolFrameHeaderPtr header = std::make_shared(headerQueue); + header->setSequenceNumber(sequenceNumber); + header->increaseFrameLength(ProtocolFrameHeader::frameHeaderLength()); + return std::make_shared(header, bodyQueue); +} + +void ProtocolFrameSerializer::finishSerialization(ProtocolFramePtr frame, BinaryQueue &data) { + ProtocolFrameHeader &frameHeader = *frame->frameHeader(); + ProtocolSerialization::serializeNoSize(frameHeader, ProtocolFrameHeader::m_signature); + ProtocolSerialization::serialize(frameHeader, frameHeader.m_frameLength); + ProtocolSerialization::serialize(frameHeader, frameHeader.m_sequenceNumber); + + data.appendMoveFrom(frameHeader.headerContent()); + data.appendMoveFrom(frame->bodyContent()); +} + +} /* namespace Cynara */ diff --git a/src/common/protocol/ProtocolFrameSerializer.h b/src/common/protocol/ProtocolFrameSerializer.h new file mode 100644 index 0000000..8af23ba --- /dev/null +++ b/src/common/protocol/ProtocolFrameSerializer.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Wojciechowski + * + * 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 ProtocolFrameSerializer.h + * @author Adam Malinowski + * @version 1.0 + * @brief Header file for protocol frame (de)serialization. + */ + +#ifndef SRC_COMMON_PROTOCOL_PROTOCOLFRAMESERIALIZER_H_ +#define SRC_COMMON_PROTOCOL_PROTOCOLFRAMESERIALIZER_H_ + +#include +#include + +namespace Cynara { + +class ProtocolFrameSerializer { + +public: + static void deserializeHeader(ProtocolFrameHeader &frameHeader, BinaryQueue &data); + static ProtocolFramePtr startSerialization(ProtocolFrameSequenceNumber sequenceNumber); + static void finishSerialization(ProtocolFramePtr frame, BinaryQueue &data); +}; + +} /* namespace Cynara */ + +#endif /* SRC_COMMON_PROTOCOL_PROTOCOLFRAMESERIALIZER_H_ */ diff --git a/src/common/protocol/ProtocolOpCode.h b/src/common/protocol/ProtocolOpCode.h new file mode 100644 index 0000000..d797fee --- /dev/null +++ b/src/common/protocol/ProtocolOpCode.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Wojciechowski + * + * 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 ProtocolOpCode.h + * @author Adam Malinowski + * @version 1.0 + * @brief Decalaration of protocol frame operation codes. + */ + +#ifndef SRC_COMMON_TYPES_PROTOCOLOPCODE_H_ +#define SRC_COMMON_TYPES_PROTOCOLOPCODE_H_ + +#include + +namespace Cynara { + +enum ProtocolOpCode : uint8_t { + /** Client operations */ + OpCheckPolicy = 0, + + /** Opcodes 1 - 19 are reserved for future use */ + + /** Admin operations */ + OpInsertPolicy = 20, + OpDeletePolicy, + OpListPolicies, + OpBeginTransaction, + OpEndTransaction +}; + +} /* namespace Cynara */ + +#endif /* SRC_COMMON_TYPES_PROTOCOLOPCODE_H_ */ diff --git a/src/common/protocol/ProtocolSerialization.h b/src/common/protocol/ProtocolSerialization.h index ffa22a0..532f78b 100644 --- a/src/common/protocol/ProtocolSerialization.h +++ b/src/common/protocol/ProtocolSerialization.h @@ -16,17 +16,21 @@ /** * @file ProtocolSerialization.h * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @author Adam Malinowski (a.malinowsk2@samsung.com) * @version 1.0 * @brief Interfaces and templates used for data serialization. */ #ifndef SRC_COMMON_PROTOCOL_PROTOCOLSERIALIZATION_H_ #define SRC_COMMON_PROTOCOL_PROTOCOLSERIALIZATION_H_ -#include -#include +#include #include #include #include +#include +#include + +#include namespace Cynara { // Abstract data stream buffer @@ -72,20 +76,44 @@ struct ProtocolSerialization { stream.write(sizeof(*value), value); } - // unsigned int - static void serialize(IStream &stream, const unsigned value) { - stream.write(sizeof(value), &value); + // unsigned 16-bit int + static void serialize(IStream &stream, const uint16_t value) { + uint16_t _value = htole16(value); + stream.write(sizeof(value), &_value); } - static void serialize(IStream &stream, const unsigned* const value) { - stream.write(sizeof(*value), value); + static void serialize(IStream &stream, const uint16_t * const value) { + uint16_t _value = htole16(*value); + stream.write(sizeof(*value), &_value); } - // int - static void serialize(IStream &stream, const int value) { - stream.write(sizeof(value), &value); + // 16-bit int + static void serialize(IStream &stream, const int16_t value) { + int16_t _value = htole16(value); + stream.write(sizeof(value), &_value); } - static void serialize(IStream &stream, const int * const value) { - stream.write(sizeof(*value), value); + static void serialize(IStream &stream, const int16_t * const value) { + int16_t _value = htole16(*value); + stream.write(sizeof(*value), &_value); + } + + // unsigned 32-bit int + static void serialize(IStream &stream, const uint32_t value) { + uint32_t _value = htole32(value); + stream.write(sizeof(value), &_value); + } + static void serialize(IStream &stream, const uint32_t * const value) { + uint32_t _value = htole32(*value); + stream.write(sizeof(*value), &_value); + } + + // 32-bit int + static void serialize(IStream &stream, const int32_t value) { + int32_t _value = htole32(value); + stream.write(sizeof(value), &_value); + } + static void serialize(IStream &stream, const int32_t * const value) { + int32_t _value = htole32(*value); + stream.write(sizeof(*value), &_value); } // bool @@ -104,6 +132,14 @@ struct ProtocolSerialization { stream.write(sizeof(*value), value); } + // ProtocolOpCode + static void serialize(IStream &stream, const ProtocolOpCode value) { + stream.write(sizeof(value), &value); + } + static void serialize(IStream &stream, const ProtocolOpCode * const value) { + stream.write(sizeof(*value), value); + } + // std::string static void serialize(IStream &stream, const std::string &str) { int length = str.size(); @@ -115,6 +151,14 @@ struct ProtocolSerialization { stream.write(sizeof(length), &length); stream.write(length, str->c_str()); } + static void serializeNoSize(IStream &stream, const std::string &str) { + int length = str.size(); + stream.write(length, str.c_str()); + } + static void serializeNoSize(IStream &stream, const std::string * const str) { + int length = str->size(); + stream.write(length, str->c_str()); + } // STL templates @@ -213,22 +257,48 @@ struct ProtocolDeserialization { stream.read(sizeof(*value), value); } - // unsigned int - static void deserialize(IStream &stream, unsigned &value) { + // 16-bit int + static void deserialize(IStream &stream, int16_t &value) { stream.read(sizeof(value), &value); + value = le16toh(value); } - static void deserialize(IStream &stream, unsigned *&value) { - value = new unsigned; + static void deserialize(IStream &stream, int16_t *&value) { + value = new int16_t; stream.read(sizeof(*value), value); + value = le16toh(value); } - // int - static void deserialize(IStream &stream, int &value) { + // unsigned 16-bit int + static void deserialize(IStream &stream, uint16_t &value) { stream.read(sizeof(value), &value); + value = le16toh(value); } - static void deserialize(IStream &stream, int *&value) { - value = new int; + static void deserialize(IStream &stream, uint16_t *&value) { + value = new uint16_t; stream.read(sizeof(*value), value); + value = le16toh(value); + } + + // 32-bit int + static void deserialize(IStream &stream, int32_t &value) { + stream.read(sizeof(value), &value); + value = le32toh(value); + } + static void deserialize(IStream &stream, int32_t *&value) { + value = new int32_t; + stream.read(sizeof(*value), value); + value = le32toh(value); + } + + // unsigned 32-bit int + static void deserialize(IStream &stream, uint32_t &value) { + stream.read(sizeof(value), &value); + value = le32toh(value); + } + static void deserialize(IStream &stream, uint32_t *&value) { + value = new uint32_t; + stream.read(sizeof(*value), value); + value = le32toh(value); } // bool @@ -249,24 +319,35 @@ struct ProtocolDeserialization { stream.read(sizeof(*value), value); } + // PrtocolOpCode + static void deserialize(IStream &stream, ProtocolOpCode &value) { + stream.read(sizeof(value), &value); + } + static void deserialize(IStream &stream, ProtocolOpCode *&value) { + value = new ProtocolOpCode; + stream.read(sizeof(*value), value); + } + // std::string static void deserialize(IStream &stream, std::string &str) { int length; stream.read(sizeof(length), &length); - char *buf = new char[length + 1]; - stream.read(length, buf); - buf[length] = 0; - str = std::string(buf); - delete[] buf; + str.resize(length); + stream.read(length, &str[0]); } static void deserialize(IStream &stream, std::string *&str) { int length; stream.read(sizeof(length), &length); - char *buf = new char[length + 1]; - stream.read(length, buf); - buf[length] = 0; - str = new std::string(buf); - delete[] buf; + str = new std::string(length, '\0'); + stream.read(length, &str[0]); + } + static void deserialize(IStream &stream, int length, std::string &str) { + str.resize(length); + stream.read(length, &str[0]); + } + static void deserialize(IStream &stream, int length, std::string *&str) { + str = new std::string(length, '\0'); + stream.read(length, &str[0]); } // STL templates diff --git a/src/common/request/CheckRequest.h b/src/common/request/CheckRequest.h index cc4e4f2..03135c7 100644 --- a/src/common/request/CheckRequest.h +++ b/src/common/request/CheckRequest.h @@ -36,7 +36,8 @@ private: PolicyKey m_key; public: - CheckRequest(const PolicyKey &key) : m_key(key) { + CheckRequest(const PolicyKey &key, ProtocolFrameSequenceNumber sequenceNumber) : + Request(sequenceNumber), m_key(key) { } virtual ~CheckRequest() = default; diff --git a/src/common/request/Request.h b/src/common/request/Request.h index 5dc0ac9..ac92398 100644 --- a/src/common/request/Request.h +++ b/src/common/request/Request.h @@ -25,16 +25,25 @@ #include #include +#include namespace Cynara { class Request { public: - Request() = default; + Request(ProtocolFrameSequenceNumber sequenceNumber) : m_sequenceNumber(sequenceNumber) { + } virtual ~Request() = default; virtual void execute(RequestPtr self, RequestTakerPtr taker, - RequestContextPtr context) const = 0; + RequestContextPtr context) const = 0; + + ProtocolFrameSequenceNumber sequenceNumber(void) const { + return m_sequenceNumber; + } + +private: + ProtocolFrameSequenceNumber m_sequenceNumber; }; } // namespace Cynara diff --git a/src/common/request/RequestTaker.cpp b/src/common/request/RequestTaker.cpp index 13d2ee9..1725049 100644 --- a/src/common/request/RequestTaker.cpp +++ b/src/common/request/RequestTaker.cpp @@ -16,12 +16,15 @@ /* * @file RequestTaker.cpp * @author Lukasz Wojciechowski + * @author Adam Malinowski * @version 1.0 * @brief This file implements RequestTaker class */ #include #include +#include +#include #include "RequestTaker.h" diff --git a/src/common/types/ProtocolFields.h b/src/common/types/ProtocolFields.h new file mode 100644 index 0000000..e370ba4 --- /dev/null +++ b/src/common/types/ProtocolFields.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Lukasz Wojciechowski + * + * 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 ProtocolFields.h + * @author Adam Malinowski + * @version 1.0 + * @brief Types definition for protocol frame fields. + */ + +#ifndef SRC_COMMON_TYPES_PROTOCOLFIELDS_H_ +#define SRC_COMMON_TYPES_PROTOCOLFIELDS_H_ + +#include +#include + +namespace Cynara { + +typedef std::string ProtocolFrameSignature; +typedef uint32_t ProtocolFrameLength; +typedef uint16_t ProtocolFrameSequenceNumber; + +} /* namespace Cynara */ + +#endif /* SRC_COMMON_TYPES_PROTOCOLFIELDS_H_ */ -- 2.7.4 From 9f23bd041799ecb0f9c9132d1f46adeebd341e05 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Wed, 2 Jul 2014 15:51:35 +0200 Subject: [PATCH 07/16] Remove unused PolicyVector.h file Change-Id: Ic4c43d1e1afbd1c506a47cefc8cb78c47c92170d --- src/common/types/PolicyVector.h | 31 ------------------------------- 1 file changed, 31 deletions(-) delete mode 100644 src/common/types/PolicyVector.h diff --git a/src/common/types/PolicyVector.h b/src/common/types/PolicyVector.h deleted file mode 100644 index b23c617..0000000 --- a/src/common/types/PolicyVector.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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 PolicyVector.h - * @author Lukasz Wojciechowski - * @version 1.0 - * @brief This file defines vector of policies - */ - -#ifndef CYNARA_COMMON_TYPES_POLICYVECTOR_H -#define CYNARA_COMMON_TYPES_POLICYVECTOR_H - -#include -#include "Policy.h" - -typedef std::vector PolicyVector; - -#endif /* CYNARA_COMMON_TYPES_POLICYVECTOR_H */ -- 2.7.4 From 843d880197bd8e82d4adab19a8f5b0b30ce11ceb Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Thu, 3 Jul 2014 14:14:53 +0200 Subject: [PATCH 08/16] Remove usage of unwanted binutils library Change-Id: I616494d5280b87a6059149a8005911e4f7062fa3 --- packaging/cynara.spec | 2 - src/CMakeLists.txt | 1 - src/common/CMakeLists.txt | 3 -- src/common/log/Backtrace.cpp | 97 ++++++-------------------------------------- src/common/log/Backtrace.h | 15 +------ 5 files changed, 14 insertions(+), 104 deletions(-) diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 1d7b8c8..4b68a35 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -22,8 +22,6 @@ BuildRequires: pkgconfig(libsystemd-journal) %if %{?build_type} == "DEBUG" BuildRequires: pkgconfig(libunwind) -BuildRequires: pkgconfig(zlib) -BuildRequires: binutils-devel %endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6b908c3..852e0a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,7 +25,6 @@ IF (CMAKE_BUILD_TYPE MATCHES "DEBUG") SET(COMMON_DEPS ${COMMON_DEPS} libunwind - zlib ) ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 5e6308a..4962b78 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -60,9 +60,6 @@ SET_TARGET_PROPERTIES( IF (CMAKE_BUILD_TYPE MATCHES "DEBUG") SET(CYNARA_DBG_LIBRARIES ${CYNARA_DEP_LIBRARIES} - -lbfd - -liberty - -ldl ) ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") diff --git a/src/common/log/Backtrace.cpp b/src/common/log/Backtrace.cpp index a58c0ed..26e3e02 100644 --- a/src/common/log/Backtrace.cpp +++ b/src/common/log/Backtrace.cpp @@ -22,103 +22,36 @@ * @brief Implementation of backtrace utility class. */ -#include "Backtrace.h" - #include -#include #include #include #include +#include +#include + +#include "Backtrace.h" + namespace Cynara { Backtrace &Backtrace::getInstance(void) { - static Backtrace m_instance(NULL); + static Backtrace m_instance; return m_instance; } -Backtrace::Backtrace(bfd *abfd) : - m_bfd(abfd), m_found(false), m_pc(0), m_fileName(NULL), +Backtrace::Backtrace() : + m_fileName(NULL), m_functionName(NULL), m_lineNumber(0) { } Backtrace::~Backtrace() { - if (m_bfd) { - bfd_close(m_bfd); - LOGD("Binary file closed."); - } -} - -bool Backtrace::init(void) { - char exePath[BUFSIZ]; - readlink("/proc/self/exe", exePath, BUFSIZ); - - bfd_init(); - m_bfd = bfd_openr(exePath, NULL); - if (m_bfd) { - m_bfd->flags |= BFD_DECOMPRESS; - if (bfd_check_format_matches(m_bfd, bfd_object, 0)) { - return true; - } - bfd_close(m_bfd); - m_bfd = NULL; - LOGE("Binary file check format failed."); - } else { - LOGE("Failed to open file: %s", exePath); - } - - return false; -} - -void Backtrace::findAddressInSection(bfd *abfd, asection *section, void *data) { - bfd_vma vma; - bfd_size_type size; - - Backtrace *backtrace = static_cast(data); - - if (backtrace->m_found) { - return; - } - - if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0) { - return; - } - - vma = bfd_get_section_vma(abfd, section); - if (backtrace->m_pc < vma) { - return; - } - - size = bfd_get_section_size(section); - if (backtrace->m_pc >= vma + size) { - return; - } - - backtrace->m_found = bfd_find_nearest_line(abfd, section, NULL, - backtrace->m_pc - vma, &backtrace->m_fileName, - &backtrace->m_functionName, &backtrace->m_lineNumber); } -void Backtrace::getSourceInfo(unw_word_t proc_address) { - char addr[64]; - - sprintf(addr, "0x%lx", static_cast(proc_address)); - m_pc = bfd_scan_vma(addr, NULL, 16); - m_found = false; - bfd_map_over_sections(m_bfd, findAddressInSection, this); - - if (m_found) { - while (true) { - m_found = bfd_find_inliner_info(m_bfd, &m_fileName, &m_functionName, - &m_lineNumber); - if (!m_found) - break; - } - } else { - m_fileName = "??"; - m_functionName = "??"; - m_lineNumber = 0; - } +void Backtrace::getSourceInfo(unw_word_t proc_address UNUSED) { + // TODO: extract filename and line number for symbol at given address + m_fileName = "??"; + m_functionName = "??"; + m_lineNumber = 0; } const std::string Backtrace::buildBacktrace(void) { @@ -132,10 +65,6 @@ const std::string Backtrace::buildBacktrace(void) { char *realname; int status; - if (m_bfd == NULL) { - init(); - } - unw_getcontext(&uc); // get rid of previous function: Backtrace::getBacktrace unw_init_local(&cursor, &uc); diff --git a/src/common/log/Backtrace.h b/src/common/log/Backtrace.h index 568c921..b697195 100644 --- a/src/common/log/Backtrace.h +++ b/src/common/log/Backtrace.h @@ -25,14 +25,6 @@ #ifndef SRC_COMMON_LOG_BACKTRACE_H_ #define SRC_COMMON_LOG_BACKTRACE_H_ -// Bellow two defines are needed by /usr/include/bfd.h file. -// In fact it needs config.h generated by autotools -// but we dont use autotools to build cynara so we don't have config.h -// bfd.h checks for these defines -#define PACKAGE 1 -#define PACKAGE_VERSION 1 - -#include #define UNW_LOCAL_ONLY #include #include @@ -52,21 +44,16 @@ public: private: static Backtrace &getInstance(void); - Backtrace(bfd *abfd); + Backtrace(); Backtrace(Backtrace const &) = delete; ~Backtrace(); void operator=(Backtrace const &) = delete; - bool init(void); const std::string buildBacktrace(void); - static void findAddressInSection(bfd *abfd, asection *section, void *data); void getSourceInfo(unw_word_t proc_address); private: - bfd *m_bfd; - bool m_found; - bfd_vma m_pc; const char *m_fileName; const char *m_functionName; unsigned int m_lineNumber; -- 2.7.4 From f5df6f9a745eaf01f8a545855eee602423711c7f Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Thu, 3 Jul 2014 11:26:05 +0200 Subject: [PATCH 09/16] Add response deserialization Change-Id: Id3bb97e5cc590aa9ef3757b503d423e2c3c9a99f --- src/common/protocol/ProtocolClient.cpp | 31 +++++++++++++++++++++++++++++-- src/common/protocol/ProtocolClient.h | 2 ++ src/common/response/CheckResponse.h | 3 ++- src/common/response/Response.h | 11 ++++++++++- src/service/logic/Logic.cpp | 2 +- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/common/protocol/ProtocolClient.cpp b/src/common/protocol/ProtocolClient.cpp index 2671eb7..9369b54 100644 --- a/src/common/protocol/ProtocolClient.cpp +++ b/src/common/protocol/ProtocolClient.cpp @@ -49,9 +49,11 @@ ProtocolPtr ProtocolClient::clone(void) { RequestPtr ProtocolClient::deserializeCheckRequest(ProtocolFrameHeader &frame) { std::string clientId, userId, privilegeId; + ProtocolDeserialization::deserialize(frame, clientId); ProtocolDeserialization::deserialize(frame, userId); ProtocolDeserialization::deserialize(frame, privilegeId); + return std::make_shared(PolicyKey(clientId, userId, privilegeId), frame.sequenceNumber()); } @@ -76,9 +78,34 @@ RequestPtr ProtocolClient::extractRequestFromBuffer(BinaryQueue &bufferQueue) { return nullptr; } +ResponsePtr ProtocolClient::deserializeCheckResponse(ProtocolFrameHeader &frame) { + PolicyType result; + PolicyResult::PolicyMetadata additionalInfo; + + ProtocolDeserialization::deserialize(frame, result); + ProtocolDeserialization::deserialize(frame, additionalInfo); + + return std::make_shared(PolicyResult(result, additionalInfo), frame.sequenceNumber()); +} + ResponsePtr ProtocolClient::extractResponseFromBuffer(BinaryQueue &bufferQueue) { - TODO_USE_ME(bufferQueue); - return ResponsePtr(nullptr); + ProtocolFrameSerializer::deserializeHeader(m_frameHeader, bufferQueue); + + if (m_frameHeader.isFrameComplete()) { + ProtocolOpCode requestId; + + m_frameHeader.resetState(); + ProtocolDeserialization::deserialize(m_frameHeader, requestId); + switch (requestId) { + case OpCheckPolicy: + return deserializeCheckResponse(m_frameHeader); + default: + throw InvalidProtocolException(InvalidProtocolException::WrongOpCode); + break; + } + } + + return nullptr; } void ProtocolClient::execute(RequestContextPtr context, CheckRequestPtr request) { diff --git a/src/common/protocol/ProtocolClient.h b/src/common/protocol/ProtocolClient.h index 1cd608b..5f20547 100644 --- a/src/common/protocol/ProtocolClient.h +++ b/src/common/protocol/ProtocolClient.h @@ -25,6 +25,7 @@ #include #include +#include #include "Protocol.h" @@ -44,6 +45,7 @@ public: private: RequestPtr deserializeCheckRequest(ProtocolFrameHeader &frame); + ResponsePtr deserializeCheckResponse(ProtocolFrameHeader &frame); }; } // namespace Cynara diff --git a/src/common/response/CheckResponse.h b/src/common/response/CheckResponse.h index 0cb1182..7d3ebc4 100644 --- a/src/common/response/CheckResponse.h +++ b/src/common/response/CheckResponse.h @@ -35,7 +35,8 @@ class CheckResponse : public Response { public: const PolicyResult &m_resultRef; - CheckResponse(const PolicyResult &result) : m_resultRef(result) { + CheckResponse(const PolicyResult &result, ProtocolFrameSequenceNumber sequenceNumber) : + Response(sequenceNumber), m_resultRef(result) { } virtual ~CheckResponse() = default; diff --git a/src/common/response/Response.h b/src/common/response/Response.h index 31d66bc..e85de48 100644 --- a/src/common/response/Response.h +++ b/src/common/response/Response.h @@ -25,16 +25,25 @@ #include #include +#include namespace Cynara { class Response { public: - Response() = default; + Response(ProtocolFrameSequenceNumber sequenceNumber) : m_sequenceNumber(sequenceNumber) { + }; virtual ~Response() = default; virtual void execute(ResponsePtr self, ResponseTakerPtr taker, RequestContextPtr context) const = 0; + + ProtocolFrameSequenceNumber sequenceNumber(void) const { + return m_sequenceNumber; + } + +private: + ProtocolFrameSequenceNumber m_sequenceNumber; }; } // namespace Cynara diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index 98d7d05..a4de76b 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -42,7 +42,7 @@ Logic::~Logic() { void Logic::execute(RequestContextPtr context, CheckRequestPtr request) { PolicyResult result(PredefinedPolicyType::DENY); if (check(context, request->key(), result)) { - context->returnResponse(context, std::make_shared(result)); + context->returnResponse(context, std::make_shared(result, request->sequenceNumber())); } } -- 2.7.4 From 75bf81a46330d30007287ecfed69dea10fdbe06e Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Fri, 4 Jul 2014 14:38:22 +0200 Subject: [PATCH 10/16] Update libcynara-admin API header Change const strings from const char* to defines. Add missing struct keywords. In function cynara_admin_set_policies() change polices parameter to array of pointers. In function cynara_admin_set_bucket() add extra parameter for passing additional data to bucket's default policy. Change-Id: Id1370a202a39636572aa6a203ae29662e423c986 --- src/include/cynara-admin.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/include/cynara-admin.h b/src/include/cynara-admin.h index 23325a9..344ecbc 100644 --- a/src/include/cynara-admin.h +++ b/src/include/cynara-admin.h @@ -49,10 +49,10 @@ extern "C" { #endif //todo comment -const char *CYNARA_ADMIN_WILDCARD = "*"; +#define CYNARA_ADMIN_WILDCARD "*"; //todo comment -const char *CYNARA_ADMIN_DEFAULT_BUCKET = ""; +#define CYNARA_ADMIN_DEFAULT_BUCKET ""; //todo comments #define CYNARA_ADMIN_DELETE -1 @@ -131,7 +131,7 @@ int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin); * * \brief Release cynara-admin library. */ -int cynara_admin_finish(cynara_admin *p_cynara_admin); +int cynara_admin_finish(struct cynara_admin *p_cynara_admin); /** * \par Description: @@ -177,13 +177,14 @@ int cynara_admin_finish(cynara_admin *p_cynara_admin); * going to be fixed along with introduction of transactions in future releases. * * \param[in] p_cynara_admin cynara admin structure. - * \param[in] policies NULL terminated array of policy structures + * \param[in] policies NULL terminated array of pointers to policy structures. * * \return CYNARA_ADMIN_API_SUCCESS on success, or error code otherwise. * * \brief Insert, update or delete policies in cynara database. */ -int cynara_admin_set_policies(cynara_admin *p_cynara_admin, const cynara_admin_policy *policies); +int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const cynara_admin_policy *const *policies); /** * \par Description: @@ -217,15 +218,20 @@ int cynara_admin_set_policies(cynara_admin *p_cynara_admin, const cynara_admin_p * Default bucket identified with CYNARA_ADMIN_DEFAULT_BUCKET exists always. Its default policy * is preset to DENY (can be altered, however). Default bucket cannot be removed. * + * Extra parameter will be used to pass additional data to cynara extensions to build more complex + * policies, such as ALLOW but for 5 minutes only, or ALLOW if user confirms. + * * \param[in] p_cynara_admin cynara admin structure. * \param[in] bucket bucket name * \param[in] operation type of operation (default policy or CYNARA_ADMIN_DELETE) + * \param[in] extra additional data for default policy (will be available with cynara extensions) * * \return CYNARA_ADMIN_API_SUCCESS on success, or error code otherwise. * * \brief Add, remove or update buckets in cynara database. */ -int cynara_admin_set_bucket(cynara_admin *p_cynara_admin, const char *bucket, int operation); +int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket, int operation, + const char *extra); #ifdef __cplusplus } -- 2.7.4 From 581fb9cd470e99442f5138d37aaccc022419708f Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Thu, 3 Jul 2014 18:45:54 +0200 Subject: [PATCH 11/16] Add stub implementation of libcynara-admin API functions Prepare Logic and ApiInterface classes skeletons. Remove old empty admin-api.cpp file. Change-Id: I498e0e904dbd9dea3a07eaaa998a30fce21cb4e5 --- src/admin/CMakeLists.txt | 9 ++++- src/admin/admin-api.cpp | 23 ----------- src/admin/api/ApiInterface.h | 40 +++++++++++++++++++ src/admin/api/admin-api.cpp | 93 ++++++++++++++++++++++++++++++++++++++++++++ src/admin/logic/Logic.cpp | 40 +++++++++++++++++++ src/admin/logic/Logic.h | 45 +++++++++++++++++++++ 6 files changed, 225 insertions(+), 25 deletions(-) delete mode 100644 src/admin/admin-api.cpp create mode 100644 src/admin/api/ApiInterface.h create mode 100644 src/admin/api/admin-api.cpp create mode 100644 src/admin/logic/Logic.cpp create mode 100644 src/admin/logic/Logic.h diff --git a/src/admin/CMakeLists.txt b/src/admin/CMakeLists.txt index f78af24..bbf0ebc 100644 --- a/src/admin/CMakeLists.txt +++ b/src/admin/CMakeLists.txt @@ -17,12 +17,17 @@ # SET(LIB_CYNARA_ADMIN_VERSION_MAJOR 0) -SET(LIB_CYNARA_ADMIN_VERSION ${LIB_CYNARA_ADMIN_VERSION_MAJOR}.0.1) +SET(LIB_CYNARA_ADMIN_VERSION ${LIB_CYNARA_ADMIN_VERSION_MAJOR}.0.2) SET(CYNARA_LIB_CYNARA_ADMIN_PATH ${CYNARA_PATH}/admin) SET(LIB_CYNARA_ADMIN_SOURCES - ${CYNARA_LIB_CYNARA_ADMIN_PATH}/admin-api.cpp + ${CYNARA_LIB_CYNARA_ADMIN_PATH}/api/admin-api.cpp + ${CYNARA_LIB_CYNARA_ADMIN_PATH}/logic/Logic.cpp + ) + +INCLUDE_DIRECTORIES( + ${CYNARA_LIB_CYNARA_ADMIN_PATH} ) ADD_LIBRARY(${TARGET_LIB_CYNARA_ADMIN} SHARED ${LIB_CYNARA_ADMIN_SOURCES}) diff --git a/src/admin/admin-api.cpp b/src/admin/admin-api.cpp deleted file mode 100644 index 30b187c..0000000 --- a/src/admin/admin-api.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* -* 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 admin-api.cpp -* @author Lukasz Wojciechowski -* @version 1.0 -* @brief Implementation of external libcynara-admin API -*/ - -// empty file for init cynara commit diff --git a/src/admin/api/ApiInterface.h b/src/admin/api/ApiInterface.h new file mode 100644 index 0000000..5a9acbc --- /dev/null +++ b/src/admin/api/ApiInterface.h @@ -0,0 +1,40 @@ +/* + * 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 ApiInterface.h + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file contains libcynara-admin API interface definition. + */ + +#ifndef SRC_ADMIN_API_APIINTERFACE_H_ +#define SRC_ADMIN_API_APIINTERFACE_H_ + +#include + +#include + +namespace Cynara { + +class ApiInterface { +public: + ApiInterface() = default; + virtual ~ApiInterface() = default; +}; + +} // namespace Cynara + +#endif /* SRC_ADMIN_API_APIINTERFACE_H_ */ diff --git a/src/admin/api/admin-api.cpp b/src/admin/api/admin-api.cpp new file mode 100644 index 0000000..0809232 --- /dev/null +++ b/src/admin/api/admin-api.cpp @@ -0,0 +1,93 @@ +/* + * 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 admin-api.cpp + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief Implementation of external libcynara-admin API + */ + +#include + +#include +#include + +#include +#include + +struct cynara_admin { + Cynara::ApiInterface *impl; + + cynara_admin(Cynara::ApiInterface *_impl) : impl(_impl) { + } + ~cynara_admin() { + delete impl; + } +}; + +CYNARA_API +int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) { + if (!pp_cynara_admin) + return CYNARA_ADMIN_API_INVALID_PARAM; + + try { + *pp_cynara_admin = new cynara_admin(new Cynara::Logic); + } catch (const std::bad_alloc &ex) { + return CYNARA_ADMIN_API_OUT_OF_MEMORY; + } + + return CYNARA_ADMIN_API_SUCCESS; +} + +CYNARA_API +int cynara_admin_finish(struct cynara_admin *p_cynara_admin) { + delete p_cynara_admin; + + return CYNARA_ADMIN_API_SUCCESS; +} + +CYNARA_API +int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin, + const cynara_admin_policy *const *policies) { + if (!p_cynara_admin || !p_cynara_admin->impl) + return CYNARA_ADMIN_API_INVALID_PARAM; + if (!policies) + return CYNARA_ADMIN_API_INVALID_PARAM; + + //todo This is a stub. Parameters should be passed to p_cynara_admin->impl + return CYNARA_ADMIN_API_SUCCESS; +} + +CYNARA_API +int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket, + int operation, const char *extra UNUSED) { + if (!p_cynara_admin || !p_cynara_admin->impl) + return CYNARA_ADMIN_API_INVALID_PARAM; + if (!bucket) + return CYNARA_ADMIN_API_INVALID_PARAM; + switch (operation) { + case CYNARA_ADMIN_DELETE: + //todo This is a stub. Parameters should be passed to p_cynara_admin->impl + return CYNARA_ADMIN_API_SUCCESS; + case CYNARA_ADMIN_DENY: + case CYNARA_ADMIN_ALLOW: + //todo This is a stub. Parameters should be passed to p_cynara_admin->impl + return CYNARA_ADMIN_API_SUCCESS; + case CYNARA_ADMIN_BUCKET: + default: + return CYNARA_ADMIN_API_INVALID_PARAM; + } +} diff --git a/src/admin/logic/Logic.cpp b/src/admin/logic/Logic.cpp new file mode 100644 index 0000000..25b7e5e --- /dev/null +++ b/src/admin/logic/Logic.cpp @@ -0,0 +1,40 @@ +/* + * 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 Logic.cpp + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file contains implementation of Logic class - main libcynara-admin class + */ + +#include + +#include +#include +#include + +#include "Logic.h" + +namespace Cynara { + +const std::string adminSocketPath("/run/cynara/cynara-admin.socket"); + +Logic::Logic() { + m_socketClient = std::make_shared(adminSocketPath, + std::make_shared()); +} + +} // namespace Cynara diff --git a/src/admin/logic/Logic.h b/src/admin/logic/Logic.h new file mode 100644 index 0000000..ac3dba2 --- /dev/null +++ b/src/admin/logic/Logic.h @@ -0,0 +1,45 @@ +/* + * 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 Logic.h + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file contains definition of Logic class - main libcynara-admin class + */ + +#ifndef SRC_ADMIN_LOGIC_LOGIC_H_ +#define SRC_ADMIN_LOGIC_LOGIC_H_ + +#include + +#include + +#include + +namespace Cynara { + +class Logic : public ApiInterface { +private: + SocketClientPtr m_socketClient; + +public: + Logic(); + virtual ~Logic() = default; +}; + +} // namespace Cynara + +#endif /* SRC_ADMIN_LOGIC_LOGIC_H_ */ -- 2.7.4 From 4a7054da79f481cf453f1bfa2db649d8e7d696b4 Mon Sep 17 00:00:00 2001 From: Marcin Niesluchowski Date: Wed, 9 Jul 2014 14:58:20 +0200 Subject: [PATCH 12/16] Remove semicolon from defines. Change-Id: Ib18ffc5560f2b629fbd586f1e70b9bbe9e020b99 --- src/include/cynara-admin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/include/cynara-admin.h b/src/include/cynara-admin.h index 344ecbc..2960101 100644 --- a/src/include/cynara-admin.h +++ b/src/include/cynara-admin.h @@ -49,10 +49,10 @@ extern "C" { #endif //todo comment -#define CYNARA_ADMIN_WILDCARD "*"; +#define CYNARA_ADMIN_WILDCARD "*" //todo comment -#define CYNARA_ADMIN_DEFAULT_BUCKET ""; +#define CYNARA_ADMIN_DEFAULT_BUCKET "" //todo comments #define CYNARA_ADMIN_DELETE -1 -- 2.7.4 From 92d8163eb9a7d8b04fd70403dc69665cf091116c Mon Sep 17 00:00:00 2001 From: Marcin Niesluchowski Date: Wed, 9 Jul 2014 19:48:12 +0200 Subject: [PATCH 13/16] Fix comment for cynara_admin_set_policies function Change-Id: I02ed34465a41d1caa670617e2169d41567bd914a --- src/include/cynara-admin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/cynara-admin.h b/src/include/cynara-admin.h index 2960101..39a612b 100644 --- a/src/include/cynara-admin.h +++ b/src/include/cynara-admin.h @@ -161,7 +161,7 @@ int cynara_admin_finish(struct cynara_admin *p_cynara_admin); * In case of CYNARA_ADMIN_BUCKET, a bucket-pointing policy is updated or inserted into cynara * database. * In case of CYNARA_ADMIN_DELETE, a policy is removed from cynara database. - * One call of cynara_admin_insert_policies can manage many different policies in different buckets. + * One call of cynara_admin_set_policies can manage many different policies in different buckets. * * However, considered buckets must exist before referring to them in policies. * -- 2.7.4 From b953220f7a88458d9a1971f73c04f8c53651053b Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Mon, 7 Jul 2014 14:59:46 +0200 Subject: [PATCH 14/16] Add sequence number generation Change-Id: I1fc3250d211a171bc121846d96282d8ff5b095fa --- src/client/logic/Logic.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/client/logic/Logic.cpp b/src/client/logic/Logic.cpp index 597c8e4..3479597 100644 --- a/src/client/logic/Logic.cpp +++ b/src/client/logic/Logic.cpp @@ -47,30 +47,36 @@ Logic::Logic() { std::make_shared()); } +ProtocolFrameSequenceNumber generateSequenceNumber(void) { + static ProtocolFrameSequenceNumber sequenceNumber = 0; + return ++sequenceNumber; +} + cynara_api_result Logic::check(const std::string &client, const std::string &session UNUSED, const std::string &user, const std::string &privilege) noexcept { - //todo Handle session parameter. + PolicyKey key(client, user, privilege); + //todo Check if answer can be get from cache. Update cache. + //todo m_cache->check(session, key); + + ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber(); //Ask cynara service - PolicyResult result(PredefinedPolicyType::DENY); + CheckResponsePtr checkResponse; try { - // todo handle sequence number correctly - ProtocolFrameSequenceNumber sequenceNumber = 0; - RequestPtr request = std::make_shared(PolicyKey(client, user, privilege), sequenceNumber); + RequestPtr request = std::make_shared(key, sequenceNumber); ResponsePtr response = m_socketClient->askCynaraServer(request); if (!response) { LOGW("Disconnected by cynara server."); onDisconnected(); return cynara_api_result::CYNARA_API_SERVICE_NOT_AVAILABLE; } - CheckResponsePtr checkResponse = std::dynamic_pointer_cast(response); + checkResponse = std::dynamic_pointer_cast(response); if (!checkResponse) { LOGC("Critical error. Casting Response to CheckResponse failed."); throw UnexpectedErrorException("Error casting Response to CheckResponse"); } - result = checkResponse->m_resultRef; } catch (const ServerConnectionErrorException &ex) { LOGE("Cynara service not available."); onDisconnected(); @@ -80,6 +86,7 @@ cynara_api_result Logic::check(const std::string &client, const std::string &ses return cynara_api_result::CYNARA_API_ACCESS_DENIED; } + PolicyResult result = checkResponse->m_resultRef; //todo Interprete result. //todo Update cache. -- 2.7.4 From 2e27fc1b022111eb56a161e7a562c6e98a744cb8 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Mon, 7 Jul 2014 16:09:50 +0200 Subject: [PATCH 15/16] Add cache interface and NoCache stub Add interface defining API for cache, that will be used to speed up checks. Add NoCache class, that implements this interface with very simple version, which always enforces checks on Cynara server. Add usage of NoCache in Logic class. Change-Id: I3b799c4c6eccddfed98e8130ef1ca4cb849b8c05 --- src/client/CMakeLists.txt | 1 + src/client/cache/CacheInterface.h | 52 ++++++++++++++++++++++++++++++++++++ src/client/cache/NoCache.cpp | 39 +++++++++++++++++++++++++++ src/client/cache/NoCache.h | 56 +++++++++++++++++++++++++++++++++++++++ src/client/logic/Logic.cpp | 20 +++++--------- src/client/logic/Logic.h | 2 ++ 6 files changed, 157 insertions(+), 13 deletions(-) create mode 100644 src/client/cache/CacheInterface.h create mode 100644 src/client/cache/NoCache.cpp create mode 100644 src/client/cache/NoCache.h diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 89fe001..72db5f1 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -23,6 +23,7 @@ SET(CYNARA_LIB_CYNARA_PATH ${CYNARA_PATH}/client) SET(LIB_CYNARA_SOURCES ${CYNARA_LIB_CYNARA_PATH}/api/client-api.cpp + ${CYNARA_LIB_CYNARA_PATH}/cache/NoCache.cpp ${CYNARA_LIB_CYNARA_PATH}/logic/Logic.cpp ) diff --git a/src/client/cache/CacheInterface.h b/src/client/cache/CacheInterface.h new file mode 100644 index 0000000..acfbd7e --- /dev/null +++ b/src/client/cache/CacheInterface.h @@ -0,0 +1,52 @@ +/* + * 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 CacheInterface.h + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file contains cache interface definition. + */ + +#ifndef SRC_CLIENT_CACHE_CACHEINTERFACE_H_ +#define SRC_CLIENT_CACHE_CACHEINTERFACE_H_ + +#include +#include + +#include +#include + +#include + +namespace Cynara { + +class CacheInterface; +typedef std::shared_ptr CacheInterfacePtr; + +class CacheInterface { +public: + CacheInterface() = default; + virtual ~CacheInterface() = default; + + virtual cynara_api_result check(const std::string &session, const PolicyKey &key) = 0; + virtual cynara_api_result updateAndCheck(const std::string &session, const PolicyKey &key, + const PolicyResult &result) = 0; + virtual void clear(void) = 0; +}; + +} // namespace Cynara + +#endif /* SRC_CLIENT_CACHE_CACHEINTERFACE_H_ */ diff --git a/src/client/cache/NoCache.cpp b/src/client/cache/NoCache.cpp new file mode 100644 index 0000000..c9220e3 --- /dev/null +++ b/src/client/cache/NoCache.cpp @@ -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 NoCache.cpp + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file contains implementation of NoCache class - stub for no-cache version + */ + +#include +#include + +#include "NoCache.h" + +namespace Cynara { + +cynara_api_result NoCache::updateAndCheck(const std::string &session UNUSED, + const PolicyKey &key UNUSED, + const PolicyResult &result) { + if (result.policyType() == PredefinedPolicyType::ALLOW) + return cynara_api_result::CYNARA_API_SUCCESS; + else + return cynara_api_result::CYNARA_API_ACCESS_DENIED; +} + +} // namespace Cynara diff --git a/src/client/cache/NoCache.h b/src/client/cache/NoCache.h new file mode 100644 index 0000000..c4330b1 --- /dev/null +++ b/src/client/cache/NoCache.h @@ -0,0 +1,56 @@ +/* + * 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 NoCache.h + * @author Lukasz Wojciechowski + * @version 1.0 + * @brief This file contains definition of NoCache class - stub for no-cache version + */ + +#ifndef SRC_CLIENT_CACHE_NOCACHE_H_ +#define SRC_CLIENT_CACHE_NOCACHE_H_ + +#include + +#include +#include +#include + +#include +#include + +namespace Cynara { + +class NoCache : public CacheInterface { +public: + NoCache() = default; + virtual ~NoCache() = default; + + virtual cynara_api_result check(const std::string &session UNUSED, + const PolicyKey &key UNUSED) { + return cynara_api_result::CYNARA_API_SERVICE_NOT_AVAILABLE; + } + + virtual cynara_api_result updateAndCheck(const std::string &session, const PolicyKey &key, + const PolicyResult &result); + + virtual void clear(void) { + } +}; + +} // namespace Cynara + +#endif /* SRC_CLIENT_CACHE_NOCACHE_H_ */ diff --git a/src/client/logic/Logic.cpp b/src/client/logic/Logic.cpp index 3479597..6ac6fb9 100644 --- a/src/client/logic/Logic.cpp +++ b/src/client/logic/Logic.cpp @@ -36,6 +36,7 @@ #include #include +#include #include "Logic.h" namespace Cynara { @@ -45,6 +46,7 @@ const std::string clientSocketPath("/run/cynara/cynara.socket"); Logic::Logic() { m_socketClient = std::make_shared(clientSocketPath, std::make_shared()); + m_cache = std::make_shared(); } ProtocolFrameSequenceNumber generateSequenceNumber(void) { @@ -57,8 +59,9 @@ cynara_api_result Logic::check(const std::string &client, const std::string &ses { PolicyKey key(client, user, privilege); - //todo Check if answer can be get from cache. Update cache. - //todo m_cache->check(session, key); + auto cacheResponse = m_cache->check(session, key); + if(cacheResponse != cynara_api_result::CYNARA_API_SERVICE_NOT_AVAILABLE) + return cacheResponse; ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber(); @@ -86,20 +89,11 @@ cynara_api_result Logic::check(const std::string &client, const std::string &ses return cynara_api_result::CYNARA_API_ACCESS_DENIED; } - PolicyResult result = checkResponse->m_resultRef; - //todo Interprete result. - //todo Update cache. - - //todo return result after more detailed interpretation. - if (result.policyType() == PredefinedPolicyType::ALLOW) - return cynara_api_result::CYNARA_API_SUCCESS; - else - return cynara_api_result::CYNARA_API_ACCESS_DENIED; + return m_cache->updateAndCheck(session, key, checkResponse->m_resultRef); } void Logic::onDisconnected(void) { - //todo run special actions when disconnected from cynara service - // like cleaning cache + m_cache->clear(); } } // namespace Cynara diff --git a/src/client/logic/Logic.h b/src/client/logic/Logic.h index e16a451..06950d8 100644 --- a/src/client/logic/Logic.h +++ b/src/client/logic/Logic.h @@ -28,12 +28,14 @@ #include #include +#include namespace Cynara { class Logic : public ApiInterface { private: SocketClientPtr m_socketClient; + CacheInterfacePtr m_cache; void onDisconnected(void); -- 2.7.4 From 8ead440e0be714f14de99a657e58b008ab37f576 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 7 Jul 2014 15:22:02 +0200 Subject: [PATCH 16/16] Add signal processing For now only SIGTERM is processed to kindly stop the service. Change-Id: If754002a8af9f8ca70323f22b06fbd22da0ddb19 --- src/common/CMakeLists.txt | 1 + src/common/protocol/ProtocolSignal.cpp | 26 ++++++++++++---- src/common/protocol/ProtocolSignal.h | 4 +++ src/common/request/RequestTaker.cpp | 5 ++- src/common/request/RequestTaker.h | 1 + src/common/request/SignalRequest.cpp | 34 +++++++++++++++++++++ src/common/request/SignalRequest.h | 56 ++++++++++++++++++++++++++++++++++ src/common/request/pointers.h | 3 ++ src/service/logic/Logic.cpp | 15 +++++++++ src/service/logic/Logic.h | 1 + src/service/sockets/SocketManager.cpp | 32 ++++++++++++++++++- src/service/sockets/SocketManager.h | 1 + 12 files changed, 171 insertions(+), 8 deletions(-) create mode 100644 src/common/request/SignalRequest.cpp create mode 100644 src/common/request/SignalRequest.h diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 4962b78..9e7cece 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -33,6 +33,7 @@ SET(COMMON_SOURCES ${COMMON_PATH}/protocol/ProtocolSignal.cpp ${COMMON_PATH}/request/CheckRequest.cpp ${COMMON_PATH}/request/RequestTaker.cpp + ${COMMON_PATH}/request/SignalRequest.cpp ${COMMON_PATH}/response/CheckResponse.cpp ${COMMON_PATH}/response/ResponseTaker.cpp ${COMMON_PATH}/sockets/Socket.cpp diff --git a/src/common/protocol/ProtocolSignal.cpp b/src/common/protocol/ProtocolSignal.cpp index 9a30455..2ca6be8 100644 --- a/src/common/protocol/ProtocolSignal.cpp +++ b/src/common/protocol/ProtocolSignal.cpp @@ -16,12 +16,18 @@ /* * @file ProtocolSignal.cpp * @author Lukasz Wojciechowski + * @author Adam Malinowski * @version 1.0 * @brief This file implements protocol class for signals */ -#include #include +#include + +#include +#include +#include + #include "ProtocolSignal.h" namespace Cynara { @@ -32,18 +38,26 @@ ProtocolSignal::ProtocolSignal() { ProtocolSignal::~ProtocolSignal() { } +void ProtocolSignal::execute(RequestContextPtr context UNUSED, SignalRequestPtr request UNUSED) { + throw NotImplementedException(); +} + ProtocolPtr ProtocolSignal::clone(void) { return std::make_shared(); } RequestPtr ProtocolSignal::extractRequestFromBuffer(BinaryQueue &bufferQueue) { - TODO_USE_ME(bufferQueue); - return RequestPtr(nullptr); + if (bufferQueue.size() >= sizeof(struct signalfd_siginfo)) { + struct signalfd_siginfo sigInfo; + bufferQueue.flattenConsume(&sigInfo, sizeof(sigInfo)); + return std::make_shared(sigInfo); + } + + return nullptr; } -ResponsePtr ProtocolSignal::extractResponseFromBuffer(BinaryQueue &bufferQueue) { - TODO_USE_ME(bufferQueue); - return ResponsePtr(nullptr); +ResponsePtr ProtocolSignal::extractResponseFromBuffer(BinaryQueue &bufferQueue UNUSED) { + throw NotImplementedException(); } } // namespace Cynara diff --git a/src/common/protocol/ProtocolSignal.h b/src/common/protocol/ProtocolSignal.h index bd14478..a9f96aa 100644 --- a/src/common/protocol/ProtocolSignal.h +++ b/src/common/protocol/ProtocolSignal.h @@ -23,6 +23,8 @@ #ifndef SRC_COMMON_PROTOCOL_PROTOCOLSIGNAL_H_ #define SRC_COMMON_PROTOCOL_PROTOCOLSIGNAL_H_ +#include + #include "Protocol.h" namespace Cynara { @@ -36,6 +38,8 @@ public: virtual RequestPtr extractRequestFromBuffer(BinaryQueue &bufferQueue); virtual ResponsePtr extractResponseFromBuffer(BinaryQueue &bufferQueue); + + virtual void execute(RequestContextPtr context, SignalRequestPtr request); }; } // namespace Cynara diff --git a/src/common/request/RequestTaker.cpp b/src/common/request/RequestTaker.cpp index 1725049..4ed8e7f 100644 --- a/src/common/request/RequestTaker.cpp +++ b/src/common/request/RequestTaker.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include "RequestTaker.h" @@ -34,4 +33,8 @@ void RequestTaker::execute(RequestContextPtr context UNUSED, CheckRequestPtr req throw NotImplementedException(); } +void RequestTaker::execute(RequestContextPtr context UNUSED, SignalRequestPtr request UNUSED) { + throw NotImplementedException(); +} + } // namespace Cynara diff --git a/src/common/request/RequestTaker.h b/src/common/request/RequestTaker.h index 581d342..1739ba6 100644 --- a/src/common/request/RequestTaker.h +++ b/src/common/request/RequestTaker.h @@ -33,6 +33,7 @@ public: virtual ~RequestTaker() = default; virtual void execute(RequestContextPtr context, CheckRequestPtr request); + virtual void execute(RequestContextPtr context, SignalRequestPtr request); }; } // namespace Cynara diff --git a/src/common/request/SignalRequest.cpp b/src/common/request/SignalRequest.cpp new file mode 100644 index 0000000..852655e --- /dev/null +++ b/src/common/request/SignalRequest.cpp @@ -0,0 +1,34 @@ +/* + * 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 SignalRequest.cpp + * @author Adam Malinowski + * @version 1.0 + * @brief This file implements signal request class + */ + +#include + +#include "SignalRequest.h" + +namespace Cynara { + +void SignalRequest::execute(RequestPtr self, RequestTakerPtr taker, + RequestContextPtr context) const { + taker->execute(context, std::dynamic_pointer_cast(self)); +} + +} // namespace Cynara diff --git a/src/common/request/SignalRequest.h b/src/common/request/SignalRequest.h new file mode 100644 index 0000000..f9d1422 --- /dev/null +++ b/src/common/request/SignalRequest.h @@ -0,0 +1,56 @@ +/* + * 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 SignalRequest.h + * @author Adam Malinowski + * @version 1.0 + * @brief This file defines signal request class + */ + +#ifndef SRC_COMMON_REQUEST_SIGNALREQUEST_H_ +#define SRC_COMMON_REQUEST_SIGNALREQUEST_H_ + +#include + +#include +#include + +namespace Cynara { + +class SignalRequest : public Request { +private: + struct signalfd_siginfo m_sigInfo; + +public: + SignalRequest(struct signalfd_siginfo sigInfo) : Request(0), m_sigInfo(sigInfo) { + } + + virtual ~SignalRequest() = default; + + virtual void execute(RequestPtr self, RequestTakerPtr taker, RequestContextPtr context) const; + + uint32_t signalNumber(void) { + return m_sigInfo.ssi_signo; + } + + struct signalfd_siginfo &sigInfo(void) { + return m_sigInfo; + } +}; + +} // namespace Cynara + +#endif /* SRC_COMMON_REQUEST_SIGNALREQUEST_H_ */ diff --git a/src/common/request/pointers.h b/src/common/request/pointers.h index c492336..b3c22e7 100644 --- a/src/common/request/pointers.h +++ b/src/common/request/pointers.h @@ -39,6 +39,9 @@ typedef std::shared_ptr RequestContextPtr; class RequestTaker; typedef std::shared_ptr RequestTakerPtr; +class SignalRequest; +typedef std::shared_ptr SignalRequestPtr; + } // namespace Cynara #endif /* SRC_COMMON_REQUEST_POINTERS_H_ */ diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index a4de76b..40e2905 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -23,13 +23,17 @@ #include #include #include +#include #include
#include #include +#include #include #include +#include + #include "Logic.h" namespace Cynara { @@ -39,6 +43,17 @@ Logic::Logic() { Logic::~Logic() { } +void Logic::execute(RequestContextPtr context UNUSED, SignalRequestPtr request) { + LOGD("Processing signal: [%d]", request->signalNumber()); + + switch (request->signalNumber()) { + case SIGTERM: + LOGI("SIGTERM received!"); + m_socketManager->mainLoopStop(); + break; + } +} + void Logic::execute(RequestContextPtr context, CheckRequestPtr request) { PolicyResult result(PredefinedPolicyType::DENY); if (check(context, request->key(), result)) { diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index da4654c..a9d6cb9 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -51,6 +51,7 @@ public: } virtual void execute(RequestContextPtr context, CheckRequestPtr request); + virtual void execute(RequestContextPtr context, SignalRequestPtr request); private: StoragePtr m_storage; diff --git a/src/service/sockets/SocketManager.cpp b/src/service/sockets/SocketManager.cpp index 7c7adeb..55edc02 100644 --- a/src/service/sockets/SocketManager.cpp +++ b/src/service/sockets/SocketManager.cpp @@ -16,6 +16,7 @@ /* * @file SocketManager.cpp * @author Lukasz Wojciechowski + * @author Adam Malinowski * @version 1.0 * @brief This file implements socket layer manager for cynara */ @@ -23,7 +24,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -73,7 +76,7 @@ void SocketManager::init(void) { createDomainSocket(std::make_shared(), clientSocketPath, clientSocketUMask); createDomainSocket(std::make_shared(), adminSocketPath, adminSocketUMask); - // todo create signal descriptor + createSignalSocket(std::make_shared()); LOGI("SocketManger init done"); } @@ -327,6 +330,33 @@ int SocketManager::getSocketFromSystemD(const std::string &path) { return -1; } +void SocketManager::createSignalSocket(ProtocolPtr protocol) { + sigset_t mask; + + // Maybe someone will find useful some kind of registering signals with callbacks + // but for now I'm making it as simple as possible. + sigemptyset(&mask); + sigaddset(&mask, SIGTERM); // systemd terminates service sending this signal + + if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) { + LOGE("sigprocmask failed: <%s>", strerror(errno)); + return; + } + + int fd = signalfd(-1, &mask, SFD_NONBLOCK); + if (fd < 0) { + LOGE("Creating signal file descriptor failed: <%s>", strerror(errno)); + return; + } + + auto &desc = createDescriptor(fd); + desc.setListen(false); + desc.setProtocol(protocol); + addReadSocket(fd); + + LOGD("Signal socket: [%d] added.", fd); +} + Descriptor &SocketManager::createDescriptor(int fd) { if (fd > m_maxDesc) { m_maxDesc = fd; diff --git a/src/service/sockets/SocketManager.h b/src/service/sockets/SocketManager.h index 6112963..2acd810 100644 --- a/src/service/sockets/SocketManager.h +++ b/src/service/sockets/SocketManager.h @@ -78,6 +78,7 @@ private: void createDomainSocket(ProtocolPtr protocol, const std::string &path, mode_t mask); int createDomainSocketHelp(const std::string &path, mode_t mask); int getSocketFromSystemD(const std::string &path); + void createSignalSocket(ProtocolPtr protocol); Descriptor &createDescriptor(int fd); -- 2.7.4