diff options
48 files changed, 2225 insertions, 217 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f5ba424..fd24809 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved -# + # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at @@ -14,13 +14,14 @@ # # @file CMakeLists.txt # @author Janusz Kozerski <j.kozerski@samsung.com> +# @author Sangwan Kwon <sangwan.kwon@samsung.com> # @brief # ############################# Check minimum CMake version ##################### CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT("cert-checker") +PROJECT(${SERVICE_NAME}) ############################# cmake packages ################################## @@ -29,7 +30,6 @@ INCLUDE(FindPkgConfig) ############################# defines ################################## SET(PREFIX ${CMAKE_INSTALL_PREFIX}) -SET(BINDIR "${PREFIX}/bin") SET(RESDIR "${PREFIX}/res") SET(LOCALEDIR "${RESDIR}/locale") @@ -48,12 +48,22 @@ ADD_DEFINITIONS("-Wall") # Generate all warnings ADD_DEFINITIONS("-Wextra") # Generate even more extra warnings ADD_DEFINITIONS("-fvisibility=hidden -fPIE") # Hide symbols by default +# Set library flag +ADD_DEFINITIONS("-fPIC") + # Set linker flag SET(CMAKE_SHARED_LINKER_FLAGS "-Wl,--as-needed") SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") -# Pass project name to sources -ADD_DEFINITIONS("-DPROJECT_NAME=\"${PROJECT_NAME}\"") +# Pass macro to sources +ADD_DEFINITIONS("-DSERVICE_NAME=\"${SERVICE_NAME}\"") +ADD_DEFINITIONS("-DSERVICE_STREAM=\"${SERVICE_STREAM}\"") +ADD_DEFINITIONS("-DSERVICE_USER=\"${SERVICE_USER}\"") +ADD_DEFINITIONS("-DSERVICE_GROUP=\"${SERVICE_GROUP}\"") + +ADD_DEFINITIONS("-DINCLUDE_INSTALL_DIR=\"${INCLUDE_INSTALL_DIR}\"") + +STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}") IF (CMAKE_BUILD_TYPE MATCHES "DEBUG") ADD_DEFINITIONS("-DBUILD_TYPE_DEBUG") @@ -63,14 +73,37 @@ ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") ADD_DEFINITIONS("-DPOPUP=1") ADD_DEFINITIONS("-DDB_INSTALL_DIR=\"${DB_INSTALL_DIR}\"") -SET(TARGET_CERT_CHECKER "cert-checker") -SET(TARGET_CERT_CHECKER_POPUP "cert-checker-popup") +# Define global macro about TARGET +SET(TARGET_CERT_CHECKER "${SERVICE_NAME}") +SET(TARGET_CERT_CHECKER_COMMON "${SERVICE_NAME}-common") +SET(TARGET_CERT_CHECKER_POPUP "${SERVICE_NAME}-popup") + # Tests -SET(TARGET_CERT_CHECKER_TESTS "cert-checker-tests") -SET(TARGET_CERT_CHECKER_TESTS_LOGIC "cert-checker-tests-logic") -SET(TARGET_CERT_CHECKER_POPUP_TEST "cert-checker-popup-test") +SET(TARGET_CERT_CHECKER_TESTS "${SERVICE_NAME}-tests") +SET(TARGET_CERT_CHECKER_TESTS_LOGIC "${SERVICE_NAME}-tests-logic") +SET(TARGET_CERT_CHECKER_POPUP_TEST "${SERVICE_NAME}-popup-test") + +# Define global macro about PATH +SET(CERT_CHECKER_SRC_PATH ${PROJECT_SOURCE_DIR}/src) +SET(CERT_CHECKER_SERVICE_PATH ${CERT_CHECKER_SRC_PATH}/service) +SET(CERT_CHECKER_LOG_PATH ${CERT_CHECKER_SRC_PATH}/log) +SET(CERT_CHECKER_UI_PATH ${CERT_CHECKER_SRC_PATH}/ui) +SET(CERT_CHECKER_DB_PATH ${CERT_CHECKER_SRC_PATH}/db) + +SET(DPL_CORE_PATH ${CERT_CHECKER_SRC_PATH}/dpl/core) +SET(DPL_CORE_SRC_PATH ${DPL_CORE_PATH}/src) +SET(DPL_DB_PATH ${CERT_CHECKER_SRC_PATH}/dpl/db) +SET(DPL_DB_SRC_PATH ${DPL_DB_PATH}/src) + +CONFIGURE_FILE( + packaging/${SERVICE_NAME}.manifest.in + ${SERVICE_NAME}.manifest @ONLY) +CONFIGURE_FILE( + packaging/${SERVICE_NAME}-common.manifest.in + ${SERVICE_NAME}-common.manifest @ONLY) ADD_SUBDIRECTORY(src) ADD_SUBDIRECTORY(db) ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(systemd) +ADD_SUBDIRECTORY(pkgconfig) diff --git a/packaging/cert-checker.manifest b/packaging/cert-checker-common.manifest.in index 75b0fa5..75b0fa5 100644 --- a/packaging/cert-checker.manifest +++ b/packaging/cert-checker-common.manifest.in diff --git a/packaging/cert-checker.manifest.in b/packaging/cert-checker.manifest.in new file mode 100644 index 0000000..75b0fa5 --- /dev/null +++ b/packaging/cert-checker.manifest.in @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_"/> + </request> +</manifest> diff --git a/packaging/cert-checker.spec b/packaging/cert-checker.spec index aef14a3..649a4a1 100644 --- a/packaging/cert-checker.spec +++ b/packaging/cert-checker.spec @@ -5,7 +5,6 @@ Release: 1 Group: Security/Certificate Management License: Apache-2.0 and BSL-1.0 Source0: %{name}-%{version}.tar.gz -Source1: %{name}.manifest BuildRequires: cmake BuildRequires: zip BuildRequires: gettext-tools @@ -24,24 +23,55 @@ BuildRequires: pkgconfig(pkgmgr) BuildRequires: pkgconfig(pkgmgr-info) BuildRequires: boost-devel Requires: security-config +Requires: lib%{name}-common = %{version}-%{release} +%description +Check OCSP validation at app install/uninstall time. + +%global SBIN_DIR /sbin %global TZ_SYS_DB %{?TZ_SYS_DB:%TZ_SYS_DB}%{!?TZ_SYS_DB:/opt/dbspace} %global TZ_SYS_ROOT %{?TZ_SYS_ROOT:%TZ_SYS_ROOT}%{!?TZ_SYS_ROOT:/root} %global TZ_SYS_RO_SHARE %{?TZ_SYS_RO_SHARE:%TZ_SYS_RO_SHARE}%{!?TZ_SYS_RO_SHARE:/usr/share} %global TZ_SYS_BIN %{?TZ_SYS_BIN:%TZ_SYS_BIN}%{!?TZ_SYS_BIN:/usr/bin} -%global DB_INST_DIR %{TZ_SYS_DB}/cert-checker - -%description -Cert-checker - -%package -n cert-checker-tests +%global DB_INST_DIR %{TZ_SYS_DB}/%{name} + +# service macro +%global service_name %{name} +%global service_stream /tmp/%{service_name}.socket +%global service_user security_fw +%global service_group security_fw + +# common lib package +%package -n lib%{name}-common +Summary: Common Library package for %{name} +License: Apache-2.0 +Group: Security/Libraries +Requires: %{SBIN_DIR}/ldconfig + +%description -n lib%{name}-common +cert-checker common library package. + +# devel package +%package devel +Summary: Development files for %{name} +License: Apache-2.0 +Group: Security/Development +BuildRequires: pkgconfig(capi-base-common) +Requires: %{name} = %{version}-%{release} + +%description devel +cert-checker development files. + +# test package +%package -n %{name}-tests Summary: Internal test for cert-checker -Group: Development +License: Apache-2.0 and BSL-1.0 +Group: Security/Testing Requires: boost-test -Requires: cert-checker = %{version}-%{release} +Requires: %{name} = %{version}-%{release} -%description -n cert-checker-tests +%description -n %{name}-tests Internal test for cert-checker implementation. %prep @@ -53,73 +83,86 @@ export CXXFLAGS="$CXXFLAGS" export FFLAGS="$FFLAGS" export LDFLAGS+="-Wl,--rpath=%{_libdir} " -%cmake . -DVERSION=%{version} \ - -DDB_INSTALL_DIR=%{DB_INST_DIR} \ - -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:RELEASE} \ - -DCMAKE_VERBOSE_MAKEFILE=ON \ - -DTEST_APP_SIGNATURES_DIR="%{TZ_SYS_ROOT}/cert-checker-test" \ - -DSYSTEMD_UNIT_DIR=%{_unitdir} +%cmake . \ + -DVERSION=%{version} \ + -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:RELEASE} \ + -DMAKE_VERBOSE_MAKEFILE=ON \ + -DSERVICE_NAME=%{service_name} \ + -DSERVICE_STREAM=%{service_stream} \ + -DSERVICE_USER=%{service_user} \ + -DSERVICE_GROUP=%{service_group} \ + -DINCLUDE_INSTALL_DIR:PATH=%{_includedir} \ + -DTEST_APP_SIGNATURES_DIR="%{TZ_SYS_ROOT}/cert-checker-test" \ + -DSYSTEMD_UNIT_DIR=%{_unitdir} \ + -DBIN_DIR=%{TZ_SYS_BIN} \ + -DDB_INSTALL_DIR=%{DB_INST_DIR} make %{?jobs:-j%jobs} %install -rm -rf %{buildroot} -mkdir -p %{buildroot}/%{DB_INST_DIR} -mkdir -p %{buildroot}/%{TZ_SYS_RO_SHARE}/license -cp LICENSE %{buildroot}/%{TZ_SYS_RO_SHARE}/license/%{name} %make_install -cp -a %{SOURCE1} %{buildroot}%{TZ_SYS_RO_SHARE}/ %find_lang %{name} -%make_install -mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants -ln -s ../cert-checker.service %{buildroot}%{_unitdir}/multi-user.target.wants/cert-checker.service - %clean rm -rf %{buildroot} %post systemctl daemon-reload + +# install if [ $1 = 1 ]; then - # installation - systemctl start cert-checker.service + systemctl start %{name}.socket fi - +# upgrade / reinstall if [ $1 = 2 ]; then - # update - systemctl restart cert-checker.service + systemctl stop %{name}.service + systemctl restart %{name}.socket fi + chsmack -a System %{DB_INST_DIR} -chsmack -a System %{DB_INST_DIR}/.cert-checker.db +chsmack -a System %{DB_INST_DIR}/.%{name}.db %preun +# uninstall if [ $1 = 0 ]; then - # unistall - systemctl stop cert-checker.service + systemctl stop %{name}.service + systemctl stop %{name}.socket fi %postun if [ $1 = 0 ]; then - # unistall systemctl daemon-reload fi +%post -n lib%{name}-common -p %{SBIN_DIR}/ldconfig +%postun -n lib%{name}-common -p %{SBIN_DIR}/ldconfig %files -f %{name}.lang -%{TZ_SYS_BIN}/cert-checker -%{TZ_SYS_BIN}/cert-checker-popup -%manifest %{TZ_SYS_RO_SHARE}/%{name}.manifest -%{TZ_SYS_RO_SHARE}/license/%{name} -%dir %attr(0700,security_fw,security_fw) %{DB_INST_DIR} -%config(noreplace) %attr(0600,security_fw,security_fw) %{DB_INST_DIR}/.cert-checker.db -%{_unitdir}/cert-checker.service -%{_unitdir}/multi-user.target.wants/cert-checker.service - -%files -n cert-checker-tests -%license LICENSE.BSL-1.0 -%defattr(-,security_fw,security_fw,-) -%{TZ_SYS_BIN}/cert-checker-tests -%{TZ_SYS_BIN}/cert-checker-tests-logic -%{TZ_SYS_BIN}/cert-checker-popup-test -%{DB_INST_DIR}/.cert-checker-test.db -%{TZ_SYS_ROOT}/cert-checker-test/*/*.xml +%manifest %{name}.manifest +%license LICENSE +%dir %attr(0700,%{service_user},%{service_group}) %{DB_INST_DIR} +%config(noreplace) %attr(0600,%{service_user},%{service_group}) %{DB_INST_DIR}/.%{name}.db +%{_unitdir}/%{name}.service +%{_unitdir}/%{name}.socket +%{TZ_SYS_BIN}/%{name} +%{TZ_SYS_BIN}/%{name}-popup + +%files -n lib%{name}-common +%defattr(-,root,root,-) +%manifest %{name}-common.manifest +%license LICENSE +%{_libdir}/lib%{name}-common.so.* + +%files devel +%defattr(-,root,root,-) +%{_libdir}/pkgconfig/%{name}.pc +%{_libdir}/lib%{name}-common.so + +%files -n %{name}-tests +%defattr(-,%{service_user},%{service_group},-) +%license LICENSE LICENSE.BSL-1.0 +%{TZ_SYS_BIN}/%{name}-tests +%{TZ_SYS_BIN}/%{name}-tests-logic +%{TZ_SYS_BIN}/%{name}-popup-test +%{DB_INST_DIR}/.%{name}-test.db +%{TZ_SYS_ROOT}/%{name}-test/*/*.xml diff --git a/pkgconfig/CMakeLists.txt b/pkgconfig/CMakeLists.txt new file mode 100644 index 0000000..a2d10a4 --- /dev/null +++ b/pkgconfig/CMakeLists.txt @@ -0,0 +1,11 @@ +CONFIGURE_FILE( + ${SERVICE_NAME}.pc.in + ${SERVICE_NAME}.pc + @ONLY +) + +INSTALL( + FILES + ${SERVICE_NAME}.pc + DESTINATION + ${LIB_INSTALL_DIR}/pkgconfig) diff --git a/pkgconfig/cert-checker.pc.in b/pkgconfig/cert-checker.pc.in new file mode 100644 index 0000000..f9dd91d --- /dev/null +++ b/pkgconfig/cert-checker.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=%{prefix} +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@ + +Name: @SERVICE_NAME@ +Description: @PACKAGE_DESCRIPTION@ +Version: @VERSION@ +Requires: +Libs: -L${libdir} -l@SERVICE_NAME@-common +Cflags: -I${includedir} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 568f553..36e35c4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,25 @@ -PKG_CHECK_MODULES(CERT_CHECKER_DEP +# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Janusz Kozerski <j.kozerski@samsung.com> +# @author Sangwan Kwon <sangwan.kwon@samsung.com> +# @brief +# + +############### CERT_CHECKER ############### +PKG_CHECK_MODULES(${TARGET_CERT_CHECKER}_DEP REQUIRED capi-appfw-application dbus-1 @@ -10,59 +31,61 @@ PKG_CHECK_MODULES(CERT_CHECKER_DEP icu-i18n key-manager libsystemd-journal + libsystemd-daemon sqlite3 pkgmgr pkgmgr-info - ) +) -SET(CERT_CHECKER_SRC_PATH ${PROJECT_SOURCE_DIR}/src) +SET(MAIN_PATH ${CERT_CHECKER_SRC_PATH}/main) -SET(CERT_CHECKER_SOURCES - ${CERT_CHECKER_SRC_PATH}/cert-checker.cpp - ${CERT_CHECKER_SRC_PATH}/app.cpp - ${CERT_CHECKER_SRC_PATH}/logic.cpp - ${CERT_CHECKER_SRC_PATH}/queue.cpp - ${CERT_CHECKER_SRC_PATH}/certs.cpp - # logs - ${CERT_CHECKER_SRC_PATH}/log/log.cpp - # dpl - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/assert.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/char_traits.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/errno_string.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/exception.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/noncopyable.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/string.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/serialization.cpp - # dpl DB - ${CERT_CHECKER_SRC_PATH}/dpl/db/src/sql_connection.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/db/src/naive_synchronization_object.cpp - # DB - ${CERT_CHECKER_SRC_PATH}/db/sql_query.cpp - # UI - ${CERT_CHECKER_SRC_PATH}/ui/UIBackend.cpp - ${CERT_CHECKER_SRC_PATH}/ui/popup-runner.cpp - ) +SET(${TARGET_CERT_CHECKER}_SRCS + ${MAIN_PATH}/cert-checker.cpp + ${CERT_CHECKER_SERVICE_PATH}/app.cpp + ${CERT_CHECKER_SERVICE_PATH}/logic.cpp + ${CERT_CHECKER_SERVICE_PATH}/queue.cpp + ${CERT_CHECKER_SERVICE_PATH}/certs.cpp + ${CERT_CHECKER_SERVICE_PATH}/ocsp-service.cpp + ${CERT_CHECKER_LOG_PATH}/log.cpp + ${CERT_CHECKER_DB_PATH}/sql_query.cpp + ${CERT_CHECKER_UI_PATH}/UIBackend.cpp + ${CERT_CHECKER_UI_PATH}/popup-runner.cpp + ${DPL_CORE_SRC_PATH}/assert.cpp + ${DPL_CORE_SRC_PATH}/char_traits.cpp + ${DPL_CORE_SRC_PATH}/errno_string.cpp + ${DPL_CORE_SRC_PATH}/exception.cpp + ${DPL_CORE_SRC_PATH}/noncopyable.cpp + ${DPL_CORE_SRC_PATH}/string.cpp + ${DPL_CORE_SRC_PATH}/serialization.cpp + ${DPL_DB_SRC_PATH}/sql_connection.cpp + ${DPL_DB_SRC_PATH}/naive_synchronization_object.cpp +) INCLUDE_DIRECTORIES(SYSTEM - ${CERT_CHECKER_DEP_INCLUDE_DIRS} + ./ + ${${TARGET_CERT_CHECKER}_DEP_INCLUDE_DIRS} ${CERT_CHECKER_SRC_PATH}/include/ - ${CERT_CHECKER_SRC_PATH}/dpl/core/include/ - ${CERT_CHECKER_SRC_PATH}/dpl/db/include/ - ) - -ADD_EXECUTABLE(${TARGET_CERT_CHECKER} ${CERT_CHECKER_SOURCES}) + ${DPL_CORE_PATH}/include/ + ${DPL_DB_PATH}/include/ +) -SET_TARGET_PROPERTIES(${TARGET_CERT_CHECKER} PROPERTIES - COMPILE_FLAGS - -fpie +SET_SOURCE_FILES_PROPERTIES(${${TARGET_CERT_CHECKER}_SRCS} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fPIE -fvisibility=default" ) +ADD_EXECUTABLE(${TARGET_CERT_CHECKER} ${${TARGET_CERT_CHECKER}_SRCS}) + TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER} - ${CERT_CHECKER_DEP_LIBRARIES} + ${${TARGET_CERT_CHECKER}_DEP_LIBRARIES} + ${TARGET_CERT_CHECKER_COMMON} -pie - ) +) -INSTALL(TARGETS ${TARGET_CERT_CHECKER} DESTINATION ${BINDIR}) +INSTALL(TARGETS ${TARGET_CERT_CHECKER} DESTINATION ${BIN_DIR}) +ADD_SUBDIRECTORY(main) +ADD_SUBDIRECTORY(service) +ADD_SUBDIRECTORY(common) ADD_SUBDIRECTORY(po) ADD_SUBDIRECTORY(ui) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt new file mode 100644 index 0000000..fbfd9ff --- /dev/null +++ b/src/common/CMakeLists.txt @@ -0,0 +1,58 @@ +# Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# @file CMakeLists.txt +# @author Sangwan Kwon (sangwan.kwon@samsung.com) +# @brief Make common library for both of server and client. +# +PKG_CHECK_MODULES(${TARGET_CERT_CHECKER_COMMON}_DEP + REQUIRED + libsystemd-journal + libsystemd-daemon +) + +SET(COMMON_PATH ${CERT_CHECKER_SRC_PATH}/common) + +SET(${TARGET_CERT_CHECKER_COMMON}_SRCS + ${COMMON_PATH}/binary-queue.cpp + ${COMMON_PATH}/connection.cpp + ${COMMON_PATH}/mainloop.cpp + ${COMMON_PATH}/service.cpp + ${COMMON_PATH}/socket.cpp +) + +INCLUDE_DIRECTORIES(SYSTEM + ${${TARGET_CERT_CHECKER_COMMON}_DEP_INCLUDE_DIRS} + ${CERT_CHECKER_SRC_PATH}/include/ + ${DPL_CORE_PATH}/include/ + ${DPL_DB_PATH}/include/ +) + +ADD_LIBRARY(${TARGET_CERT_CHECKER_COMMON} + SHARED ${${TARGET_CERT_CHECKER_COMMON}_SRCS} +) + +SET_TARGET_PROPERTIES(${TARGET_CERT_CHECKER_COMMON} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=default" # TODO: visibility hidden + LINKER_LANGUAGE CXX + SOVERSION ${API_VERSION} + VERSION ${VERSION} +) + +TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER_COMMON} + ${${TARGET_CERT_CHECKER_COMMON}_DEP_LIBRARIES} +) + +INSTALL(TARGETS ${TARGET_CERT_CHECKER_COMMON} DESTINATION ${LIB_INSTALL_DIR}) diff --git a/src/common/binary-queue.cpp b/src/common/binary-queue.cpp new file mode 100644 index 0000000..776f65e --- /dev/null +++ b/src/common/binary-queue.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2016 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 binary-queue.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief + */ +#include "common/binary-queue.h" + +#include <cstring> +#include <stdexcept> +#include <new> + +namespace CCHECKER { + +BinaryQueue::BinaryQueue() : m_size(0) +{ +} + +BinaryQueue::~BinaryQueue() +{ +} + +RawBuffer BinaryQueue::pop() +{ + RawBuffer buf(m_size); + + read(m_size, buf.data()); + + return buf; +} + +void BinaryQueue::push(const RawBuffer &data) +{ + write(data.size(), data.data()); +} + +void BinaryQueue::write(size_t size, const void *bytes) +{ + while (size > 0) { + auto s = (size > MaxBucketSize) ? MaxBucketSize : size; + auto b = new unsigned char[s]; + memcpy(b, bytes, s); + m_buckets.emplace(new Bucket(b, s)); + m_size += s; + size -= s; + } +} + +void BinaryQueue::read(size_t size, void *bytes) +{ + if (size == 0) + return; + + if (size > m_size) + throw std::logic_error("protocol broken. no more binary to flatten in queue"); + + void *cur = bytes; + + while (size > 0) { + if (m_buckets.empty()) + throw std::logic_error("protocol broken. no more buckets to extract"); + + size_t count = std::min(size, m_buckets.front()->left); + cur = m_buckets.front()->extractTo(cur, count); + + size -= count; + m_size -= count; + + if (m_buckets.front()->left == 0) + m_buckets.pop(); + } +} + +BinaryQueue::Bucket::Bucket(unsigned char *_data, size_t _size) : + data(_data), + cur(_data), + left(_size) +{ + if (_data == nullptr || _size == 0) + throw std::invalid_argument("Bucket construct failed."); +} + +BinaryQueue::Bucket::~Bucket() +{ + delete []data; +} + +void *BinaryQueue::Bucket::extractTo(void *dest, size_t size) +{ + if (dest == nullptr || size == 0) + throw std::logic_error("logic error. invalid input to Bucket::extractTo."); + + memcpy(dest, cur, size); + + cur += size; + left -= size; + + return static_cast<unsigned char *>(dest) + size; +} + +} // namespace CCHECKER diff --git a/src/common/binary-queue.h b/src/common/binary-queue.h new file mode 100644 index 0000000..a70c9ec --- /dev/null +++ b/src/common/binary-queue.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2016 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 binary-queue.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief This file is the header file of binary queue + */ +#pragma once + +#include <queue> +#include <memory> +#include <cstddef> + +#include "common/serialization.h" +#include "common/types.h" + +using namespace CCHECKER::Common; + +namespace CCHECKER { + +class BinaryQueue : public IStream { +public: + BinaryQueue(); + virtual ~BinaryQueue(); + + BinaryQueue(BinaryQueue &&) = default; + BinaryQueue &operator=(BinaryQueue &&) = default; + BinaryQueue(const BinaryQueue &) = delete; + BinaryQueue &operator=(const BinaryQueue &) = delete; + + RawBuffer pop(void); + void push(const RawBuffer &); + + template <typename ...Args> + static BinaryQueue Serialize(const Args &...args); + + template <typename ...Args> + void Deserialize(Args &...args); + + virtual void read(size_t num, void *bytes) override; + virtual void write(size_t num, const void *bytes) override; + +private: + const static size_t MaxBucketSize = 1024; /* Bytes */ + + struct Bucket { + explicit Bucket(unsigned char *_data, size_t _size); + virtual ~Bucket(); + + /* extract ''size'' of bytes from bucket to dest and return updated dest */ + void *extractTo(void *dest, size_t size); + + Bucket(Bucket &&) = default; + Bucket &operator=(Bucket &&) = default; + Bucket(const Bucket &) = delete; + Bucket &operator=(const Bucket &) = delete; + + unsigned char *data; + const unsigned char *cur; // current valid position of data + size_t left; + }; + + std::queue<std::unique_ptr<Bucket>> m_buckets; + size_t m_size; +}; + +template <typename ...Args> +BinaryQueue BinaryQueue::Serialize(const Args &...args) +{ + BinaryQueue q; + Serializer<Args...>::Serialize(q, args...); + return q; +} + +template <typename ...Args> +void BinaryQueue::Deserialize(Args &...args) +{ + Deserializer<Args...>::Deserialize(*this, args...); +} + +} // namespace CCHECKER diff --git a/src/common/connection.cpp b/src/common/connection.cpp new file mode 100644 index 0000000..54abe7c --- /dev/null +++ b/src/common/connection.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016 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 connection.cpp + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief + */ +#include "common/connection.h" + +#include <utility> + +namespace CCHECKER { + +Connection::Connection(Socket &&socket) : m_socket(std::move(socket)) +{ +} + +Connection::~Connection() +{ +} + +Connection::Connection(Connection &&other) : m_socket(std::move(other.m_socket)) +{ +} + +Connection &Connection::operator=(Connection &&other) +{ + if (this == &other) + return *this; + + m_socket = std::move(other.m_socket); + return *this; +} + +void Connection::send(const RawBuffer &buf) const +{ + std::lock_guard<std::mutex> lock(m_mSend); + m_socket.write(buf); +} + +RawBuffer Connection::receive() const +{ + std::lock_guard<std::mutex> lock(m_mRecv); + return m_socket.read(); +} + +int Connection::getFd() const +{ + return m_socket.getFd(); +} + +} diff --git a/src/common/connection.h b/src/common/connection.h new file mode 100644 index 0000000..3172772 --- /dev/null +++ b/src/common/connection.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2016 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 connection.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief + */ +#pragma once + +#include <memory> +#include <mutex> + +#include "common/socket.h" +#include "common/types.h" + +namespace CCHECKER { + +class Connection { +public: + explicit Connection(Socket &&socket); + virtual ~Connection(); + + Connection(const Connection &) = delete; + Connection &operator=(const Connection &) = delete; + + Connection(Connection &&); + Connection &operator=(Connection &&); + + void send(const RawBuffer &) const; + RawBuffer receive(void) const; + int getFd(void) const; + +private: + Socket m_socket; + mutable std::mutex m_mSend; + mutable std::mutex m_mRecv; +}; + +using ConnShPtr = std::shared_ptr<Connection>; + +} // namespace CCHECKER diff --git a/src/common/mainloop.cpp b/src/common/mainloop.cpp new file mode 100644 index 0000000..19ff477 --- /dev/null +++ b/src/common/mainloop.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2016 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 mainloop.cpp + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief Mainloop with epoll + */ +#include "common/mainloop.h" + +#include <exception> +#include <stdexcept> +#include <system_error> +#include <sys/epoll.h> +#include <unistd.h> + +#include <cchecker/log.h> + +namespace CCHECKER { + +Mainloop::Mainloop() : + m_isTimedOut(false), + m_pollfd(::epoll_create1(EPOLL_CLOEXEC)) +{ + if (m_pollfd == -1) + throw std::system_error( + std::error_code(errno, std::generic_category()), + "Failed to epoll_create1"); +} + +Mainloop::~Mainloop() +{ + if (!m_isTimedOut && !m_callbacks.empty()) + throw std::logic_error("mainloop registered callbacks should be empty " + "except timed out case"); + + ::close(m_pollfd); +} + +void Mainloop::run(int timeout) +{ + m_isTimedOut = false; + + while (!m_isTimedOut) { + dispatch(timeout); + } + + LogDebug("Mainloop run stopped"); +} + +void Mainloop::addEventSource(int fd, uint32_t event, Callback &&callback) +{ + /* TODO: use scoped-lock to thread safe on member variables */ + if (m_callbacks.count(fd) != 0) + throw std::logic_error("event source already added!"); + + LogDebug("Add event[" << event << "] source on fd[" << fd << "]"); + + epoll_event e; + + e.events = event; + e.data.fd = fd; + + if (::epoll_ctl(m_pollfd, EPOLL_CTL_ADD, fd, &e) == -1) + throw std::system_error( + std::error_code(errno, std::generic_category()), + "epoll_ctl failed to EPOLL_CTL_ADD."); + + m_callbacks[fd] = std::move(callback); +} + +void Mainloop::removeEventSource(int fd) +{ + /* TODO: use scoped-lock to thread safe on member variables */ + if (m_callbacks.count(fd) == 0) + throw std::logic_error("event source isn't added at all"); + + LogDebug("Remove event source on fd[" << fd << "]"); + + do { + m_callbacks.erase(fd); + + if (::epoll_ctl(m_pollfd, EPOLL_CTL_DEL, fd, nullptr) == -1) { + if (errno == ENOENT) + throw std::logic_error("Tried to delete epoll item which wasn't added"); + else + throw std::system_error( + std::error_code(errno, std::generic_category()), + "epoll_ctl failed to EPOLL_CTL_DEL."); + } + } while (false); +} + +void Mainloop::dispatch(int timeout) +{ + int nfds = -1; + epoll_event event[MAX_EPOLL_EVENTS]; + + LogDebug("Mainloop dispatched with timeout: " << timeout); + + do { + nfds = ::epoll_wait(m_pollfd, event, MAX_EPOLL_EVENTS, timeout); + } while ((nfds == -1) && (errno == EINTR)); + + if (nfds < 0) + throw std::system_error( + std::error_code(errno, std::generic_category()), + "epoll_wait failed!"); + + if (nfds == 0) { + LogDebug("Mainloop timed out!"); + m_isTimedOut = true; + return; + } + + for (int i = 0; i < nfds; i++) { + /* TODO: use scoped-lock to thread safe on member variables */ + int fd = event[i].data.fd; + + if (m_callbacks.count(fd) == 0) + throw std::logic_error("event in, but associated callback isn't exist!"); + + if (event[i].events & (EPOLLHUP | EPOLLRDHUP)) { + LogInfo("peer connection closed on fd[" << fd << "]"); + event[i].events &= ~EPOLLIN; + } + + LogDebug("event[" << event[i].events << "] polled on fd[" << fd << "]"); + + m_callbacks[fd](event[i].events); + } +} + +} // namespace CCHECKER diff --git a/src/common/mainloop.h b/src/common/mainloop.h new file mode 100644 index 0000000..c52a115 --- /dev/null +++ b/src/common/mainloop.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016 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 mainloop.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief Manageloop with epoll + */ +#pragma once + +#include <functional> +#include <mutex> +#include <unordered_map> + +namespace CCHECKER { + +class Mainloop { +public: + typedef std::function<void(uint32_t event)> Callback; + + Mainloop(); + virtual ~Mainloop(); + + Mainloop(const Mainloop &) = delete; + Mainloop &operator=(const Mainloop &) = delete; + Mainloop(Mainloop &&) = delete; + Mainloop &operator=(Mainloop &&) = delete; + + void run(int timeout); + + void addEventSource(int fd, uint32_t event, Callback &&callback); + void removeEventSource(int fd); + +private: + void dispatch(int timeout); + + bool m_isTimedOut; + int m_pollfd; + std::mutex m_mutex; + std::unordered_map<int, Callback> m_callbacks; + + constexpr static size_t MAX_EPOLL_EVENTS = 32; +}; + +} // namespace CCHECKER diff --git a/src/common/serialization.h b/src/common/serialization.h new file mode 100644 index 0000000..7f0ee84 --- /dev/null +++ b/src/common/serialization.h @@ -0,0 +1,610 @@ +/* + * Copyright (c) 2016 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 serialization.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief Interfaces and templates used for data serialization. + */ +#pragma once + +#include <stdint.h> +#include <time.h> + +#include <string> +#include <vector> +#include <list> +#include <map> +#include <unordered_map> +#include <set> +#include <memory> + +namespace CCHECKER { + +namespace Common { + +// Abstract data stream buffer +class IStream { +public: + virtual void read(size_t num, void *bytes) = 0; + virtual void write(size_t num, const void *bytes) = 0; + virtual ~IStream() {} +}; + +// Serializable interface +class ISerializable { +public: + ISerializable() {} + ISerializable(IStream &) {} + virtual void Serialize(IStream &) const = 0; + virtual ~ISerializable() {} +}; + +struct Serialization { + // serialization + // normal functions + + // ISerializable objects + static void Serialize(IStream &stream, const ISerializable &object) + { + object.Serialize(stream); + } + + static void Serialize(IStream &stream, const ISerializable *const object) + { + object->Serialize(stream); + } + + // char + static void Serialize(IStream &stream, const char value) + { + stream.write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const char *const value) + { + stream.write(sizeof(*value), value); + } + + // unsigned char + static void Serialize(IStream &stream, const unsigned char value) + { + stream.write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const unsigned char *const value) + { + stream.write(sizeof(*value), value); + } + + // unsigned int32 + static void Serialize(IStream &stream, const uint32_t value) + { + stream.write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const uint32_t *const value) + { + stream.write(sizeof(*value), value); + } + + // int32 + static void Serialize(IStream &stream, const int32_t value) + { + stream.write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const int32_t *const value) + { + stream.write(sizeof(*value), value); + } + + // unsigned int64 + static void Serialize(IStream &stream, const uint64_t value) + { + stream.write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const uint64_t *const value) + { + stream.write(sizeof(*value), value); + } + + // int64 + static void Serialize(IStream &stream, const int64_t value) + { + stream.write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const int64_t *const value) + { + stream.write(sizeof(*value), value); + } + + static void Serialize(IStream &stream, const time_t value) + { + stream.write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const time_t *const value) + { + stream.write(sizeof(*value), value); + } + + // bool + static void Serialize(IStream &stream, const bool value) + { + stream.write(sizeof(value), &value); + } + static void Serialize(IStream &stream, const bool *const value) + { + stream.write(sizeof(*value), value); + } + + // std::string + template <typename T, typename R, typename A> + static void Serialize(IStream &stream, const std::basic_string<T, R, A> &str) + { + int length = str.size(); + stream.write(sizeof(length), &length); + stream.write(length * sizeof(T), str.data()); + } + + template<typename T, typename R, typename A> + static void Serialize(IStream &stream, + const std::basic_string<T, R, A> *const str) + { + int length = str->size(); + stream.write(sizeof(length), &length); + stream.write(length * sizeof(T), str->data()); + } + + // STL templates + + // std::list + template <typename T> + static void Serialize(IStream &stream, const std::list<T> &list) + { + size_t length = list.size(); + stream.write(sizeof(length), &length); + + for (const auto &item : list) + Serialize(stream, item); + } + template <typename T> + static void Serialize(IStream &stream, const std::list<T> *const list) + { + Serialize(stream, *list); + } + + template <typename T> + static void Serialize(IStream &stream, const std::set<T> &set) + { + auto len = set.size(); + stream.write(sizeof(len), &len); + + for (const auto &item : set) + Serialize(stream, item); + } + template <typename T> + static void Serialize(IStream &stream, const std::set<T> *const set) + { + Serialize(stream, *set); + } + + // RawBuffer + template <typename A> + static void Serialize(IStream &stream, const std::vector<unsigned char, A> &vec) + { + int length = vec.size(); + stream.write(sizeof(length), &length); + stream.write(length, vec.data()); + } + + template <typename A> + static void Serialize(IStream &stream, + const std::vector<unsigned char, A> *const vec) + { + Serialize(stream, *vec); + } + + // std::vector + template <typename T, typename A> + static void Serialize(IStream &stream, const std::vector<T, A> &vec) + { + int length = vec.size(); + stream.write(sizeof(length), &length); + + for (const auto &i : vec) + Serialize(stream, i); + } + template <typename T, typename A> + static void Serialize(IStream &stream, const std::vector<T, A> *const vec) + { + Serialize(stream, *vec); + } + + // std::pair + template <typename A, typename B> + static void Serialize(IStream &stream, const std::pair<A, B> &p) + { + Serialize(stream, p.first); + Serialize(stream, p.second); + } + template <typename A, typename B> + static void Serialize(IStream &stream, const std::pair<A, B> *const p) + { + Serialize(stream, *p); + } + + // std::map + template <typename K, typename T> + static void Serialize(IStream &stream, const std::map<K, T> &map) + { + size_t length = map.size(); + stream.write(sizeof(length), &length); + + for (const auto &item : map) { + Serialize(stream, item.first); + Serialize(stream, item.second); + } + } + template <typename K, typename T> + static void Serialize(IStream &stream, const std::map<K, T> *const map) + { + Serialize(stream, *map); + } + + // std::unordered_map + template <typename K, typename T> + static void Serialize(IStream &stream, const std::unordered_map<K, T> &map) + { + size_t length = map.size(); + stream.write(sizeof(length), &length); + + for (const auto &item : map) { + Serialize(stream, item.first); + Serialize(stream, item.second); + } + } + template <typename K, typename T> + static void Serialize(IStream &stream, + const std::unordered_map<K, T> *const map) + { + Serialize(stream, *map); + } + + // std::unique_ptr + template <typename T> + static void Serialize(IStream &stream, const std::unique_ptr<T> &p) + { + Serialize(stream, *p); + } + + // std::shared_ptr + template <typename T> + static void Serialize(IStream &stream, const std::shared_ptr<T> &p) + { + Serialize(stream, *p); + } +}; // struct Serialization + +struct Deserialization { + // deserialization + // normal functions + + // ISerializable objects + // T instead of ISerializable is needed to call proper constructor + template <typename T> + static void Deserialize(IStream &stream, T &object) + { + object = T(stream); + } + template <typename T> + static void Deserialize(IStream &stream, T *&object) + { + object = new T(stream); + } + + template <typename T> + static void Deserialize(IStream &stream, std::shared_ptr<T> &object) + { + object.reset(new T(stream)); + } + + // char + static void Deserialize(IStream &stream, char &value) + { + stream.read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, char *&value) + { + value = new char; + stream.read(sizeof(*value), value); + } + + // unsigned char + static void Deserialize(IStream &stream, unsigned char &value) + { + stream.read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, unsigned char *&value) + { + value = new unsigned char; + stream.read(sizeof(*value), value); + } + + // unsigned int32 + static void Deserialize(IStream &stream, uint32_t &value) + { + stream.read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, uint32_t *&value) + { + value = new uint32_t; + stream.read(sizeof(*value), value); + } + + // int32 + static void Deserialize(IStream &stream, int32_t &value) + { + stream.read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, int32_t *&value) + { + value = new int32_t; + stream.read(sizeof(*value), value); + } + + // unsigned int64 + static void Deserialize(IStream &stream, uint64_t &value) + { + stream.read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, uint64_t *&value) + { + value = new uint64_t; + stream.read(sizeof(*value), value); + } + + // int64 + static void Deserialize(IStream &stream, int64_t &value) + { + stream.read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, int64_t *&value) + { + value = new int64_t; + stream.read(sizeof(*value), value); + } + + static void Deserialize(IStream &stream, time_t &value) + { + stream.read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, time_t *&value) + { + value = new time_t; + stream.read(sizeof(*value), value); + } + + // bool + static void Deserialize(IStream &stream, bool &value) + { + stream.read(sizeof(value), &value); + } + static void Deserialize(IStream &stream, bool *&value) + { + value = new bool; + stream.read(sizeof(*value), value); + } + + template <typename T, typename R, typename A> + static void Deserialize(IStream &stream, std::basic_string<T, R, A> &str) + { + int length; + stream.read(sizeof(length), &length); + std::vector<T> buf(length); + stream.read(length * sizeof(T), buf.data()); + str = std::basic_string<T, R, A>(buf.data(), buf.data() + length); + } + + template <typename T, typename R, typename A> + static void Deserialize(IStream &stream, std::basic_string<T, R, A> *&str) + { + int length; + stream.read(sizeof(length), &length); + std::vector<T> buf(length); + stream.read(length * sizeof(T), buf.data()); + str = new std::basic_string<T, R, A>(buf.data(), buf.data() + length); + } + + // STL templates + + // std::list + template <typename T> + static void Deserialize(IStream &stream, std::list<T> &list) + { + int length; + stream.read(sizeof(length), &length); + + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + list.push_back(std::move(obj)); + } + } + template <typename T> + static void Deserialize(IStream &stream, std::list<T> *&list) + { + list = new std::list<T>; + Deserialize(stream, *list); + } + + template <typename T> + static void Deserialize(IStream &stream, std::set<T> &set) + { + size_t len; + stream.read(sizeof(len), &len); + + for (size_t i = 0; i < len; ++i) { + T obj; + Deserialize(stream, obj); + set.insert(std::move(obj)); + } + } + template <typename T> + static void Deserialize(IStream &stream, std::set<T> *&set) + { + set = new std::set<T>; + Deserialize(stream, *set); + } + + // RawBuffer + template <typename A> + static void Deserialize(IStream &stream, std::vector<unsigned char, A> &vec) + { + int length; + stream.read(sizeof(length), &length); + vec.resize(length); + stream.read(length, vec.data()); + } + + template <typename A> + static void Deserialize(IStream &stream, std::vector<unsigned char, A> *&vec) + { + vec = new std::vector<unsigned char, A>; + Deserialize(stream, *vec); + } + + // std::vector + template <typename T, typename A> + static void Deserialize(IStream &stream, std::vector<T, A> &vec) + { + int length; + stream.read(sizeof(length), &length); + + for (int i = 0; i < length; ++i) { + T obj; + Deserialize(stream, obj); + vec.push_back(std::move(obj)); + } + } + template <typename T, typename A> + static void Deserialize(IStream &stream, std::vector<T, A> *&vec) + { + vec = new std::vector<T, A>; + Deserialize(stream, *vec); + } + + // std::pair + template <typename A, typename B> + static void Deserialize(IStream &stream, std::pair<A, B> &p) + { + Deserialize(stream, p.first); + Deserialize(stream, p.second); + } + template <typename A, typename B> + static void Deserialize(IStream &stream, std::pair<A, B> *&p) + { + p = new std::pair<A, B>; + Deserialize(stream, *p); + } + + // std::map + template <typename K, typename T> + static void Deserialize(IStream &stream, std::map<K, T> &map) + { + int length; + stream.read(sizeof(length), &length); + + for (int i = 0; i < length; ++i) { + K key; + T obj; + Deserialize(stream, key); + Deserialize(stream, obj); + map[key] = std::move(obj); + } + } + template <typename K, typename T> + static void Deserialize(IStream &stream, std::map<K, T> *&map) + { + map = new std::map<K, T>; + Deserialize(stream, *map); + } + + // std::unordered_map + template <typename K, typename T> + static void Deserialize(IStream &stream, std::unordered_map<K, T> &map) + { + size_t length; + stream.read(sizeof(length), &length); + + for (size_t i = 0; i < length; ++i) { + K key; + T obj; + Deserialize(stream, key); + Deserialize(stream, obj); + map[key] = std::move(obj); + } + } + template <typename K, typename T> + static void Deserialize(IStream &stream, std::unordered_map<K, T> *&map) + { + map = new std::map<K, T>; + Deserialize(stream, *map); + } +}; // struct Deserialization + +// generic serialization +template <typename... Args> +struct Serializer; + +template <typename First, typename... Args> +struct Serializer<First, Args...> : public Serializer<Args...> { + static void Serialize(IStream &stream, const First &f, const Args &... args) + { + Serialization::Serialize(stream, f); + Serializer<Args...>::Serialize(stream, args...); + } +}; + +// end of recursion +template <> +struct Serializer<> { + static void Serialize(IStream &) + { + return; + } +}; + +// generic deserialization +template <typename... Args> +struct Deserializer; + +template <typename First, typename... Args> +struct Deserializer<First, Args...> : public Deserializer<Args...> { + static void Deserialize(IStream &stream, First &f, Args &... args) + { + Deserialization::Deserialize(stream, f); + Deserializer<Args...>::Deserialize(stream, args...); + } +}; + +// end of recursion +template <> +struct Deserializer<> { + static void Deserialize(IStream &) + { + return; + } +}; + +} // namespace Common +} // namespace CCHECKER diff --git a/src/common/service.cpp b/src/common/service.cpp new file mode 100644 index 0000000..49f2408 --- /dev/null +++ b/src/common/service.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016 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 service.cpp + * @author Kyungwook Tak (k.tak@samsung.com) + * @author Sangwan Kwon (sangwan.kwon@samsung.com) + * @version 1.0 + * @brief + */ +#include "common/service.h" + +#include <sys/types.h> +#include <sys/epoll.h> + +#include <cchecker/log.h> + +namespace CCHECKER { + +Service::Service(const std::string &address) : m_address(address) +{ + LogDebug("Service constructed with address[" << address << "]"); + + m_timeout = -1; + setNewConnectionCallback(nullptr); + setCloseConnectionCallback(nullptr); +} + +Service::~Service() +{ +} + +void Service::start() +{ + LogInfo("Service start!"); + + Socket socket(m_address); + + LogDebug("Get systemd socket[" << socket.getFd() + << "] with address[" << m_address << "]"); + + m_loop.addEventSource(socket.getFd(), EPOLLIN | EPOLLHUP | EPOLLRDHUP, + [&](uint32_t event) { + if (event != EPOLLIN) + return; + + m_onNewConnection(std::make_shared<Connection>(socket.accept())); + }); + + m_loop.run(m_timeout); +} + +void Service::stop() +{ + LogInfo("Service stop!"); +} + +void Service::setNewConnectionCallback(const ConnCallback &/*callback*/) +{ + /* TODO: scoped-lock */ + m_onNewConnection = [&](const ConnShPtr & connection) { + if (!connection) + throw std::logic_error("onNewConnection called but ConnShPtr is nullptr."); + + int fd = connection->getFd(); + + LogInfo("welcome! accepted client socket fd[" << fd << "]"); + + /* + // TODO: disable temporarily + if (callback) + callback(connection); + */ + + m_loop.addEventSource(fd, EPOLLIN | EPOLLHUP | EPOLLRDHUP, + [ &, fd](uint32_t event) { + LogDebug("read event comes in to fd[" << fd << "]"); + + if (m_connectionRegistry.count(fd) == 0) + throw std::logic_error("get event on fd, but no associated connection exist"); + + auto &conn = m_connectionRegistry[fd]; + + if (event & (EPOLLHUP | EPOLLRDHUP)) { + LogDebug("event of epoll hup. close connection on fd[" << fd << "]"); + m_onCloseConnection(conn); + return; + } + + LogDebug("Start message process on fd[" << fd << "]"); + + onMessageProcess(conn); + }); + + m_connectionRegistry[fd] = connection; + }; +} + +void Service::setCloseConnectionCallback(const ConnCallback &/*callback*/) +{ + /* TODO: scoped-lock */ + m_onCloseConnection = [&](const ConnShPtr & connection) { + if (!connection) + throw std::logic_error("no connection to close"); + + int fd = connection->getFd(); + + if (m_connectionRegistry.count(fd) == 0) + throw std::logic_error("no connection in registry to remove."); + + LogInfo("good-bye! close socket fd[" << fd << "]"); + + m_loop.removeEventSource(fd); + m_connectionRegistry.erase(fd); /* scoped-lock needed? */ + + /* + // TODO: disable temporarily + if (callback) + callback(connection); + */ + }; +} + +void Service::setTimeout(int timeout) +{ + m_timeout = timeout; +} + +} // namespace CCHECKER diff --git a/src/common/service.h b/src/common/service.h new file mode 100644 index 0000000..3297b78 --- /dev/null +++ b/src/common/service.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016 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 service.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @author Sangwan Kwon (sangwan.kwon@samsung.com) + * @version 1.0 + * @brief + */ +#pragma once + +#include <string> +#include <functional> + +#include "common/connection.h" +#include "common/mainloop.h" + +namespace CCHECKER { + +using ConnCallback = std::function<void(const ConnShPtr &)>; + +class Service { +public: + Service(const std::string &address); + virtual ~Service(); + + Service(const Service &) = delete; + Service &operator=(const Service &) = delete; + Service(Service &&) = delete; + Service &operator=(Service &&) = delete; + + virtual void start(void) final; + virtual void stop(void) final; + + /* ConnCallback param should throw exception to handle error */ + virtual void setNewConnectionCallback(const ConnCallback &) final; + virtual void setCloseConnectionCallback(const ConnCallback &) final; + + virtual void setTimeout(int timeout) final; + +private: + virtual void onMessageProcess(const ConnShPtr &) = 0; + + ConnCallback m_onNewConnection; + ConnCallback m_onCloseConnection; + + int m_timeout; + std::unordered_map<int, ConnShPtr> m_connectionRegistry; + Mainloop m_loop; + std::string m_address; +}; + +} // namespace CCHECKER diff --git a/src/common/socket.cpp b/src/common/socket.cpp new file mode 100644 index 0000000..a829484 --- /dev/null +++ b/src/common/socket.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2016 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 socket.cpp + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief + */ +#include "common/socket.h" + +#include <exception> +#include <system_error> + +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/un.h> +#include <unistd.h> + +#include <systemd/sd-daemon.h> + +#include <cchecker/log.h> + +namespace { + +int createSystemdSocket(const std::string &path) +{ + int n = ::sd_listen_fds(-1); + + if (n < 0) + throw std::system_error(std::error_code(), "failed to sd_listen_fds"); + + for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; ++fd) { + if (::sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0) > 0) { + LogInfo("service's systemd socket found with fd: " << fd); + return fd; + } + } + + throw std::system_error(std::error_code(), "get systemd socket failed!"); +} + +} // namespace anonymous + +namespace CCHECKER { + +Socket::Socket(int fd) : m_fd(fd) +{ + if (m_fd < 0) + throw std::logic_error("Socket fd from constructor is invalid!!"); +} + +Socket::Socket(const std::string &path) : m_fd(createSystemdSocket(path)) +{ +} + +Socket::Socket(Socket &&other) +{ + if (other.m_fd < 0) + throw std::logic_error("Socket fd from move constructor is invalid!!"); + + m_fd = other.m_fd; + other.m_fd = 0; +} + +Socket &Socket::operator=(Socket &&other) +{ + if (this == &other) + return *this; + + if (other.m_fd < 0) + throw std::logic_error("Socket fd from move assignment is invalid!!"); + + m_fd = other.m_fd; + other.m_fd = 0; + + return *this; +} + +Socket::~Socket() +{ + if (m_fd == 0) + return; + + LogInfo("Close socket of fd: " << m_fd); + ::close(m_fd); +} + +Socket Socket::accept() const +{ + int fd = ::accept(m_fd, nullptr, nullptr); + + if (fd < 0) + throw std::system_error( + std::error_code(errno, std::generic_category()), + "socket accept failed!"); + + LogInfo("Accept client success with fd: " << fd); + + return Socket(fd); +} + +Socket Socket::connect(const std::string &path) +{ + if (path.size() >= sizeof(sockaddr_un::sun_path)) + throw std::invalid_argument("socket path size too long!"); + + int fd = ::socket(AF_UNIX, SOCK_STREAM, 0); + + if (fd < 0) + throw std::system_error( + std::error_code(errno, std::generic_category()), + "socket create failed!"); + + sockaddr_un addr; + addr.sun_family = AF_UNIX; + + strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path)); + + if (::connect(fd, reinterpret_cast<sockaddr *>(&addr), + sizeof(sockaddr_un)) == -1) + throw std::system_error( + std::error_code(errno, std::generic_category()), + "socket connect failed!"); + + LogInfo("Connect to CSR server success with fd:" << fd); + + return Socket(fd); +} + +int Socket::getFd() const +{ + return m_fd; +} + +RawBuffer Socket::read(void) const +{ + size_t total = 0; + + RawBuffer data(1024, 0); + auto buf = reinterpret_cast<char *>(data.data()); + auto size = data.size(); + + LogDebug("Read data from stream on socket fd[" << m_fd << "]"); + + while (total < size) { + int bytes = ::read(m_fd, buf + total, size - total); + + if (bytes < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + continue; + else + throw std::system_error( + std::error_code(errno, std::generic_category()), + "socket read failed!"); + } + + /* TODO: handle the case of more bytes in stream to read than buffer size */ + total += bytes; + break; + } + + data.resize(total); + + LogDebug("Read data of size[" << total + << "] from stream on socket fd[" << m_fd << "] done."); + + return data; +} + +void Socket::write(const RawBuffer &data) const +{ + size_t total = 0; + + auto buf = reinterpret_cast<const char *>(data.data()); + auto size = data.size(); + + LogDebug("Write data to stream on socket fd[" << m_fd << "]"); + + while (total < size) { + int bytes = ::write(m_fd, buf + total, size - total); + + if (bytes < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) + continue; + else + throw std::system_error( + std::error_code(errno, std::generic_category()), + "socket write failed!"); + } + + total += bytes; + } + + LogDebug("Write data of size[" << total << + "] to stream on socket fd[" << m_fd << "] done."); +} + +} // namespace CCHECKER diff --git a/src/common/socket.h b/src/common/socket.h new file mode 100644 index 0000000..6283cba --- /dev/null +++ b/src/common/socket.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016 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 socket.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief + */ +#pragma once + +#include <string> + +#include "common/types.h" + +namespace CCHECKER { + +class Socket { +public: + Socket(int fd = 0); + Socket(const std::string &path); /* Construct with systemd socket from path */ + + Socket(const Socket &) = delete; + Socket &operator=(const Socket &) = delete; + + Socket(Socket &&); + Socket &operator=(Socket &&); + + virtual ~Socket(); + + Socket accept(void) const; + int getFd(void) const; + + RawBuffer read(void) const; + void write(const RawBuffer &data) const; + + /* TODO: can it be constructor? */ + static Socket connect(const std::string &path); + +private: + int m_fd; +}; + +} diff --git a/src/common/types.h b/src/common/types.h new file mode 100644 index 0000000..b00419b --- /dev/null +++ b/src/common/types.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016 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 types.h + * @author Kyungwook Tak (k.tak@samsung.com) + * @version 1.0 + * @brief Typedefs of primitives + */ +#pragma once + +#include <vector> + +namespace CCHECKER { + +using RawBuffer = std::vector<unsigned char>; + +} // namespace CCHECKER diff --git a/src/include/cchecker/UIBackend.h b/src/include/cchecker/UIBackend.h index 6133078..659adb8 100644 --- a/src/include/cchecker/UIBackend.h +++ b/src/include/cchecker/UIBackend.h @@ -21,7 +21,7 @@ #pragma once -#include <cchecker/app.h> +#include "service/app.h" namespace CCHECKER { namespace UI { diff --git a/src/include/cchecker/sql_query.h b/src/include/cchecker/sql_query.h index fd28fd5..6338561 100644 --- a/src/include/cchecker/sql_query.h +++ b/src/include/cchecker/sql_query.h @@ -24,7 +24,7 @@ #include <string> #include <cchecker/dpl/db/sql_connection.h> -#include <cchecker/app.h> +#include "service/app.h" namespace CCHECKER { namespace DB { diff --git a/src/cert-checker.cpp b/src/main/cert-checker.cpp index c6e7537..e4cdb44 100644 --- a/src/cert-checker.cpp +++ b/src/main/cert-checker.cpp @@ -23,26 +23,33 @@ #include <glib.h> #include <cchecker/log.h> -#include <cchecker/logic.h> + +#include "service/logic.h" +#include "service/ocsp-service.h" using namespace CCHECKER; int main(void) { - LogDebug("Cert-checker start!"); + try { + LogInfo("Cert-checker start!"); + + CCHECKER::OcspService service(SERVICE_STREAM); - setlocale(LC_ALL, ""); - GMainLoop *main_loop = g_main_loop_new(NULL, FALSE); + setlocale(LC_ALL, ""); - Logic logic; - if (logic.setup() != NO_ERROR) { - LogError("Cannot setup logic. Exit cert-checker!"); - return -1; - } + // Set timeout about socket read event. + service.setTimeout(50); + service.start(); - LogDebug("Running the main loop"); - g_main_loop_run(main_loop); + LogInfo("Cert-checker exit!"); + return 0; - LogDebug("Cert-checker exit!"); - return 0; + } catch (const std::exception &e) { + LogError("Exception occured in cert-checker main : " << e.what()); + return -1; + } catch (...) { + LogError("Unhandled exception occured in cert-checker main."); + return -1; + } } diff --git a/src/po/CMakeLists.txt b/src/po/CMakeLists.txt index b89f4cb..27eae39 100644 --- a/src/po/CMakeLists.txt +++ b/src/po/CMakeLists.txt @@ -37,7 +37,7 @@ FOREACH(pofile ${POFILES}) DEPENDS ${absPofile} ) INSTALL(FILES ${moFile} - DESTINATION ${LOCALEDIR}/${lang}/LC_MESSAGES RENAME ${PROJECT_NAME}.mo) + DESTINATION ${LOCALEDIR}/${lang}/LC_MESSAGES RENAME ${SERVICE_NAME}.mo) SET(moFiles ${moFiles} ${moFile}) ENDFOREACH(pofile) diff --git a/src/app.cpp b/src/service/app.cpp index 29a9b2d..a61f4a3 100644 --- a/src/app.cpp +++ b/src/service/app.cpp @@ -19,12 +19,12 @@ * @version 1.0 * @brief This file is the implementation of app struct */ +#include "service/app.h" #include <sstream> #include <string> #include <sys/types.h> -#include <cchecker/app.h> #include <cchecker/log.h> namespace CCHECKER { diff --git a/src/include/cchecker/app.h b/src/service/app.h index df4a860..df4a860 100644 --- a/src/include/cchecker/app.h +++ b/src/service/app.h diff --git a/src/certs.cpp b/src/service/certs.cpp index 8f45a7f..248b867 100644 --- a/src/certs.cpp +++ b/src/service/certs.cpp @@ -21,6 +21,8 @@ * Getting out app signature, getting certificates out of * signature. Checking OCSP */ +#include "service/certs.h" + #include <sys/types.h> #include <dirent.h> #include <list> @@ -31,7 +33,6 @@ #include <ckm/ckm-type.h> #include <ckm/ckm-raw-buffer.h> -#include <cchecker/certs.h> #include <cchecker/log.h> namespace CCHECKER { diff --git a/src/include/cchecker/certs.h b/src/service/certs.h index 0cb9135..4871c39 100644 --- a/src/include/cchecker/certs.h +++ b/src/service/certs.h @@ -28,7 +28,7 @@ #include <ckm/ckm-certificate.h> #include <pkgmgr-info.h> -#include <cchecker/app.h> +#include "service/app.h" #include <ckm/ckm-manager.h> namespace CCHECKER { diff --git a/src/logic.cpp b/src/service/logic.cpp index 181ebea..f0ebaee 100644 --- a/src/logic.cpp +++ b/src/service/logic.cpp @@ -16,17 +16,20 @@ /* * @file logic.cpp * @author Janusz Kozerski (j.kozerski@samsung.com) + * @author Sangwan Kwon (sangwan.kwon@samsung.com) * @version 1.0 * @brief This file is the implementation of SQL queries */ +#include "logic.h" + #include <stdexcept> +#include <set> -#include <cchecker/logic.h> #include <cchecker/log.h> #include <cchecker/sql_query.h> #include <cchecker/UIBackend.h> -#include <set> +#include "common/binary-queue.h" using namespace std; @@ -70,7 +73,8 @@ struct PkgmgrinfoEvent { std::set<PkgmgrinfoEvent> pkgmgrinfo_event_set; const char *const DB_PATH = DB_INSTALL_DIR"/.cert-checker.db"; -} + +} // namespace Anonymous Logic::~Logic(void) { @@ -79,7 +83,7 @@ Logic::~Logic(void) void Logic::clean(void) { - LogDebug("Cert-checker cleaning."); + LogDebug("Cert-checker cleaning start."); // wait and join processing thread if (m_thread.joinable()) { @@ -87,6 +91,7 @@ void Logic::clean(void) { std::lock_guard<std::mutex> lock(m_mutex_cv); set_should_exit(); + LogDebug("Notify thread : enforced by cleaning"); m_to_process.notify_one(); } m_thread.join(); @@ -98,10 +103,16 @@ void Logic::clean(void) if (m_proxy_connman) g_object_unref(m_proxy_connman); + if (m_loop) + g_main_loop_unref(m_loop); + delete m_sqlquery; + + LogDebug("Cert-checker cleaning finish."); } Logic::Logic(void) : + m_loop(g_main_loop_new(NULL, FALSE)), m_sqlquery(NULL), m_was_setup_called(false), m_is_online(false), @@ -110,7 +121,8 @@ Logic::Logic(void) : m_proxy_connman(NULL), m_pc_install(nullptr, nullptr), m_pc_uninstall(nullptr, nullptr) -{} +{ +} bool Logic::get_online() const { @@ -125,6 +137,7 @@ void Logic::set_online(bool online) m_is_online = online; if (m_is_online) { m_is_online_enabled = true; + LogDebug("Notify thread : Network connected"); m_to_process.notify_one(); } } @@ -220,6 +233,9 @@ error_t Logic::setup() LogDebug("Register package event handler success"); + LogDebug("Running the main loop"); + g_main_loop_run(m_loop); + return NO_ERROR; } @@ -248,6 +264,7 @@ int Logic::pkgmgrinfo_event_handler_static( } else if (keyStr.compare("end") == 0 && valStr.compare("ok") == 0) { return static_cast<Logic *>(data)->push_pkgmgrinfo_event(uid, pkgid); } else { + // TODO(sangwan.kwon) if get untreat event like fail, must quit loop LogDebug("Untreated event was caught : " << val); return -1; } @@ -430,7 +447,6 @@ void Logic::connman_callback(GDBusProxy */*proxy*/, if (params_str == "('State', <'online'>)") { LogDebug("Device online"); logic->set_online(true); - logic->m_to_process.notify_one(); } else if (params_str == "('State', <'offline'>)") { LogDebug("Device offline"); @@ -521,6 +537,7 @@ void Logic::push_event(event_t event) { std::lock_guard<std::mutex> lock(m_mutex_cv); m_queue.push_event(std::move(event)); + LogDebug("Notify thread : pkgmgr event added"); m_to_process.notify_one(); } @@ -528,26 +545,32 @@ void Logic::process_all() { for(;;) { std::unique_lock<std::mutex> lock(m_mutex_cv); - if (m_should_exit) - break; //lock will be unlocked upon destruction // don't sleep if there are online/installation/deinstallation events to process - if(m_queue.empty() && !m_is_online_enabled) { - LogDebug("Processing thread: waiting on condition"); + if(m_queue.empty() || !get_online()) { + LogDebug("Processing thread : wait condition <Queue, Network> : " + << !m_queue.empty() << ", " << get_online()); m_to_process.wait(lock); // spurious wakeups do not concern us - LogDebug("Processing thread: running"); + LogDebug("Processing thread : running"); } - m_is_online_enabled = false; lock.unlock(); - process_queue(); - if (get_online()) + if (m_should_exit) + break; + + if (get_online() && !m_queue.empty()) { + process_queue(); // move event data from queue to buffer & database process_buffer(); - else - LogDebug("No network. Buffer won't be processed"); - LogDebug("Processing done"); + LogDebug("Processing thread : done. g_main_loop quit"); + g_main_loop_quit(m_loop); + break; + } else if (!get_online()) { + LogDebug("Processing thread : no network. Buffer won't be processed"); + } else { + LogDebug("Processing thread : no event since cert-checker started"); + } } } @@ -621,4 +644,4 @@ void Logic::set_should_exit(void) } -} //CCHECKER +} // namespace CCHECKER diff --git a/src/include/cchecker/logic.h b/src/service/logic.h index 888fe07..dca58b7 100644 --- a/src/include/cchecker/logic.h +++ b/src/service/logic.h @@ -16,6 +16,7 @@ /* * @file logic.h * @author Janusz Kozerski (j.kozerski@samsung.com) + * @author Sangwan Kwon (sangwan.kwon@samsung.com) * @version 1.0 * @brief This file is the implementation of SQL queries */ @@ -31,9 +32,11 @@ #include <thread> #include <memory> -#include <cchecker/app.h> -#include <cchecker/certs.h> -#include <cchecker/queue.h> +#include "common/types.h" +#include "common/binary-queue.h" +#include "service/app.h" +#include "service/certs.h" +#include "service/queue.h" #include <package-manager.h> #include <pkgmgr-info.h> @@ -42,7 +45,7 @@ namespace CCHECKER { namespace DB { class SqlQuery; -} +} // namespace DB enum error_t { NO_ERROR, @@ -58,6 +61,11 @@ enum pkgmgr_event_t { EVENT_UNINSTALL }; +enum class CommandId : int { + CC_OCSP_SYN = 0x01, + CC_OCSP_ACK = 0x02 +}; + class Logic { public: Logic(void); @@ -130,6 +138,10 @@ class Logic { bool call_ui(const app_t &app); + + // main event loop data type + GMainLoop *m_loop; + Queue m_queue; Certs m_certs; std::list<app_t> m_buffer; @@ -146,12 +158,13 @@ class Logic { GDBusProxy *m_proxy_connman; + // about pkgmgr event int m_reqid_install; int m_reqid_uninstall; std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> m_pc_install; std::unique_ptr<pkgmgrinfo_client, int(*)(pkgmgrinfo_client *)> m_pc_uninstall; }; -} // CCHECKER +} // namespace CCHECKER #endif //CCHECKER_LOGIC_H diff --git a/src/service/ocsp-service.cpp b/src/service/ocsp-service.cpp new file mode 100644 index 0000000..7bb0ea1 --- /dev/null +++ b/src/service/ocsp-service.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016 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 ocsp-service.cpp + * @author Sangwan Kwon (sangwan.kwon@samsung.com) + * @version 1.0 + * @brief + */ +#include "service/ocsp-service.h" + +#include <cchecker/log.h> + +namespace CCHECKER { + +OcspService::OcspService(const std::string &address) : + Service(address) +{ +} + +OcspService::~OcspService() +{ +} + +void OcspService::onMessageProcess(const ConnShPtr &connection) +{ + LogDebug("Start to process message on ocsp service."); + + auto in = connection->receive(); + connection->send(this->process(connection, in)); + if (m_logic.setup() != NO_ERROR) + throw std::logic_error("Cannot setup logic."); + + LogDebug("Start to process message on ocsp service."); +} + +RawBuffer OcspService::process(const ConnShPtr &, RawBuffer &data) +{ + BinaryQueue q; + q.push(data); + + int cmd; + q.Deserialize(cmd); + + LogInfo("Request dispatch on ocsp-service."); + switch (static_cast<CommandId>(cmd)) { + case CommandId::CC_OCSP_SYN: { + // TODO(sangwan.kwon) : set protocol with client + return BinaryQueue::Serialize(1).pop(); + } + case CommandId::CC_OCSP_ACK: + default: + throw std::logic_error("Protocol error. unknown command id."); + } +} + +} // namespace CCHECKER diff --git a/src/service/ocsp-service.h b/src/service/ocsp-service.h new file mode 100644 index 0000000..1f497cc --- /dev/null +++ b/src/service/ocsp-service.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 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 ocsp-service.h + * @author Sangwan Kwon (sagnwan.kwon@samsung.com) + * @version 1.0 + * @brief + */ +#pragma once + +#include <string> + +#include "common/service.h" +#include "service/logic.h" + +namespace CCHECKER { + +class OcspService : public Service { +public: + OcspService(const std::string &address); + virtual ~OcspService(); + +private: + virtual void onMessageProcess(const ConnShPtr &) override; + + RawBuffer process(const ConnShPtr &, RawBuffer &); + + Logic m_logic; +}; + +} // namespace CCHECKER diff --git a/src/queue.cpp b/src/service/queue.cpp index d0ecb41..1ae4f1b 100644 --- a/src/queue.cpp +++ b/src/service/queue.cpp @@ -19,12 +19,11 @@ * @version 1.0 * @brief This file is the implementation of thread-safe queue */ +#include "service/queue.h" #include <mutex> #include <utility> -#include <cchecker/queue.h> - namespace CCHECKER { event_t::event_t(): diff --git a/src/include/cchecker/queue.h b/src/service/queue.h index 7100265..9c3eaae 100644 --- a/src/include/cchecker/queue.h +++ b/src/service/queue.h @@ -26,7 +26,7 @@ #include <mutex> #include <queue> -#include <cchecker/app.h> +#include "service/app.h" namespace CCHECKER { diff --git a/src/ui/popup-bin/CMakeLists.txt b/src/ui/popup-bin/CMakeLists.txt index 8c2ac68..285653a 100644 --- a/src/ui/popup-bin/CMakeLists.txt +++ b/src/ui/popup-bin/CMakeLists.txt @@ -29,16 +29,16 @@ set(CERT_CHECKER_POPUP_SRC_DIR ${PROJECT_SOURCE_DIR}/src/ui/popup-bin) set(CERT_CHECKER_POPUP_SOURCES ${CERT_CHECKER_POPUP_SRC_DIR}/popup.cpp - ${CERT_CHECKER_SRC_PATH}/ui/popup-runner.cpp - ${CERT_CHECKER_SRC_PATH}/app.cpp + ${CERT_CHECKER_UI_PATH}/popup-runner.cpp + ${CERT_CHECKER_SERVICE_PATH}/app.cpp # logs - ${CERT_CHECKER_SRC_PATH}/log/log.cpp + ${CERT_CHECKER_LOG_PATH}/log.cpp # dpl - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/assert.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/exception.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/serialization.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/errno_string.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/noncopyable.cpp + ${DPL_CORE_SRC_PATH}/assert.cpp + ${DPL_CORE_SRC_PATH}/exception.cpp + ${DPL_CORE_SRC_PATH}/serialization.cpp + ${DPL_CORE_SRC_PATH}/errno_string.cpp + ${DPL_CORE_SRC_PATH}/noncopyable.cpp ) ADD_DEFINITIONS(${CERT_CHECKER_POPUP_DEP_CFLAGS}) @@ -47,7 +47,7 @@ INCLUDE_DIRECTORIES( ${CERT_CHECKER_POPUP_SRC_DIR} ${CERT_CHECKER_POPUP_DEP_INCLUDE_DIRS} ${CERT_CHECKER_SRC_PATH}/include/ - ${CERT_CHECKER_SRC_PATH}/dpl/core/include/ + ${DPL_CORE_SRC_PATH}/include/ ) ADD_EXECUTABLE(${TARGET_CERT_CHECKER_POPUP} @@ -64,4 +64,4 @@ TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER_POPUP} -pie ) -INSTALL(TARGETS ${TARGET_CERT_CHECKER_POPUP} DESTINATION ${BINDIR}) +INSTALL(TARGETS ${TARGET_CERT_CHECKER_POPUP} DESTINATION ${BIN_DIR}) diff --git a/src/ui/popup-bin/popup.cpp b/src/ui/popup-bin/popup.cpp index 019ef04..f616907 100644 --- a/src/ui/popup-bin/popup.cpp +++ b/src/ui/popup-bin/popup.cpp @@ -82,7 +82,7 @@ void show_popup(struct cert_checker_popup_data *pdp) { } pdp->win = elm_win_add(NULL, - dgettext(PROJECT_NAME, "SID_TITLE_OCSP_VERIFICATION_FAILED"), + dgettext(SERVICE_NAME, "SID_TITLE_OCSP_VERIFICATION_FAILED"), ELM_WIN_NOTIFICATION); elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED); @@ -98,7 +98,7 @@ void show_popup(struct cert_checker_popup_data *pdp) { pdp->title = elm_label_add(pdp->popup); elm_object_style_set(pdp->title, "elm.text.title"); - elm_object_text_set(pdp->title, dgettext(PROJECT_NAME, "SID_TITLE_OCSP_VERIFICATION_FAILED")); + elm_object_text_set(pdp->title, dgettext(SERVICE_NAME, "SID_TITLE_OCSP_VERIFICATION_FAILED")); evas_object_show(pdp->title); elm_box_pack_end(pdp->box, pdp->title); @@ -112,11 +112,11 @@ void show_popup(struct cert_checker_popup_data *pdp) { // Set message // App ID may be absent, so in that case we need to use only package ID if (pdp->app_id == std::string(CCHECKER::TEMP_APP_ID)) { - char *content = dgettext(PROJECT_NAME, "SID_CONTENT_OCSP_PACKAGE VERIFICATION_FAILED"); + char *content = dgettext(SERVICE_NAME, "SID_CONTENT_OCSP_PACKAGE VERIFICATION_FAILED"); ret = asprintf(&buff, content, pdp->pkg_id.c_str()); } else { - char *content = dgettext(PROJECT_NAME, "SID_CONTENT_OCSP_VERIFICATION_FAILED"); + char *content = dgettext(SERVICE_NAME, "SID_CONTENT_OCSP_VERIFICATION_FAILED"); ret = asprintf(&buff, content, pdp->app_id.c_str(), pdp->pkg_id.c_str()); } @@ -139,13 +139,13 @@ void show_popup(struct cert_checker_popup_data *pdp) { pdp->keep_button = elm_button_add(pdp->popup); elm_object_style_set(pdp->keep_button, "elm.swallow.content.button1"); - elm_object_text_set(pdp->keep_button, dgettext(PROJECT_NAME, "SID_BTN_OCSP_KEEP_APP")); + elm_object_text_set(pdp->keep_button, dgettext(SERVICE_NAME, "SID_BTN_OCSP_KEEP_APP")); elm_object_part_content_set(pdp->popup, "button1", pdp->keep_button); evas_object_smart_callback_add(pdp->keep_button, "clicked", keep_answer, pdp); pdp->uninstall_button = elm_button_add(pdp->popup); elm_object_style_set(pdp->uninstall_button, "elm.swallow.content.button2"); - elm_object_text_set(pdp->uninstall_button, dgettext(PROJECT_NAME, "SID_BTN_OCSP_UNINSTALL_APP")); + elm_object_text_set(pdp->uninstall_button, dgettext(SERVICE_NAME, "SID_BTN_OCSP_UNINSTALL_APP")); elm_object_part_content_set(pdp->popup, "button2 ", pdp->uninstall_button); evas_object_smart_callback_add(pdp->uninstall_button, "clicked", uninstall_answer, pdp); diff --git a/src/ui/popup-runner.cpp b/src/ui/popup-runner.cpp index 2004e05..bae75e8 100644 --- a/src/ui/popup-runner.cpp +++ b/src/ui/popup-runner.cpp @@ -29,8 +29,8 @@ #include <tzplatform_config.h> -#include <cchecker/app.h> -#include <cchecker/logic.h> +#include "service/app.h" +#include "service/logic.h" #include <cchecker/log.h> #include <cchecker/UIBackend.h> #include <cchecker/popup-runner.h> diff --git a/systemd/CMakeLists.txt b/systemd/CMakeLists.txt index 982fe1d..0b25467 100644 --- a/systemd/CMakeLists.txt +++ b/systemd/CMakeLists.txt @@ -1,4 +1,13 @@ -INSTALL(FILES - ${PROJECT_SOURCE_DIR}/systemd/cert-checker.service - DESTINATION - ${SYSTEMD_UNIT_DIR}) +CONFIGURE_FILE( + ${SERVICE_NAME}.socket.in + ${SERVICE_NAME}.socket @ONLY) +CONFIGURE_FILE( + ${SERVICE_NAME}.service.in + ${SERVICE_NAME}.service @ONLY) + +INSTALL( + FILES + ${SERVICE_NAME}.socket + ${SERVICE_NAME}.service + DESTINATION + ${SYSTEMD_UNIT_DIR}) diff --git a/systemd/cert-checker.service b/systemd/cert-checker.service.in index ab744c9..8819f29 100644 --- a/systemd/cert-checker.service +++ b/systemd/cert-checker.service.in @@ -3,13 +3,11 @@ Description=Start the Cert-Checker Requires=dbus.service [Service] -User=security_fw -Group=security_fw +User=@SERVICE_USER@ +Group=@SERVICE_GROUP@ EnvironmentFile=-/etc/sysconfig/enlightenment # Makes popup bigger Environment="ELM_SCALE=4.0" Type=simple -ExecStart=/usr/bin/cert-checker - -[Install] -WantedBy=multi-user.target +ExecStart=@BIN_DIR@/cert-checker +Sockets=@SERVICE_NAME@.socket diff --git a/systemd/cert-checker.socket.in b/systemd/cert-checker.socket.in new file mode 100644 index 0000000..26d6ace --- /dev/null +++ b/systemd/cert-checker.socket.in @@ -0,0 +1,7 @@ +[Socket] +ListenStream=@SERVICE_STREAM@ +SocketUser=@SERVICE_USER@ +SocketGroup=@SERVICE_GROUP@ +SocketMode=0777 + +Service=@SERVICE_NAME@.service diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fa2817a..cf924e1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,7 +19,6 @@ FIND_PACKAGE(Threads REQUIRED) ADD_DEFINITIONS( "-DBOOST_TEST_DYN_LINK" ) ADD_DEFINITIONS("-DTEST_APP_SIGNATURES_DIR=\"${TEST_APP_SIGNATURES_DIR}\"") -SET(CERT_CHECKER_SRC_PATH ${PROJECT_SOURCE_DIR}/src) SET(CERT_CHECKER_TESTS_SRC_PATH ${PROJECT_SOURCE_DIR}/tests) SET(CERT_CHECKER_TESTS_SOURCES @@ -35,24 +34,24 @@ SET(CERT_CHECKER_TESTS_SOURCES ${CERT_CHECKER_TESTS_SRC_PATH}/test_certs.cpp ${CERT_CHECKER_TESTS_SRC_PATH}/certs_.cpp # cert-checker - ${CERT_CHECKER_SRC_PATH}/app.cpp - ${CERT_CHECKER_SRC_PATH}/queue.cpp - ${CERT_CHECKER_SRC_PATH}/certs.cpp + ${CERT_CHECKER_SERVICE_PATH}/app.cpp + ${CERT_CHECKER_SERVICE_PATH}/queue.cpp + ${CERT_CHECKER_SERVICE_PATH}/certs.cpp # logs - ${CERT_CHECKER_SRC_PATH}/log/log.cpp + ${CERT_CHECKER_LOG_PATH}/log.cpp # dpl - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/assert.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/char_traits.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/colors.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/errno_string.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/exception.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/noncopyable.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/string.cpp + ${DPL_CORE_SRC_PATH}/assert.cpp + ${DPL_CORE_SRC_PATH}/char_traits.cpp + ${DPL_CORE_SRC_PATH}/colors.cpp + ${DPL_CORE_SRC_PATH}/errno_string.cpp + ${DPL_CORE_SRC_PATH}/exception.cpp + ${DPL_CORE_SRC_PATH}/noncopyable.cpp + ${DPL_CORE_SRC_PATH}/string.cpp # dpl DB - ${CERT_CHECKER_SRC_PATH}/dpl/db/src/sql_connection.cpp - ${CERT_CHECKER_SRC_PATH}/dpl/db/src/naive_synchronization_object.cpp + ${DPL_DB_SRC_PATH}/sql_connection.cpp + ${DPL_DB_SRC_PATH}/naive_synchronization_object.cpp # DB - ${CERT_CHECKER_SRC_PATH}/db/sql_query.cpp + ${CERT_CHECKER_DB_PATH}/sql_query.cpp ) SET(CERT_CHECKER_TESTS_LOGIC_SOURCES @@ -63,31 +62,32 @@ SET(CERT_CHECKER_TESTS_LOGIC_SOURCES ${CERT_CHECKER_TESTS_SRC_PATH}/logic_.cpp ${CERT_CHECKER_TESTS_SRC_PATH}/stubs_.cpp # cert-checker - ${CERT_CHECKER_SRC_PATH}/logic.cpp - ${CERT_CHECKER_SRC_PATH}/app.cpp - ${CERT_CHECKER_SRC_PATH}/queue.cpp + ${CERT_CHECKER_SERVICE_PATH}/logic.cpp + ${CERT_CHECKER_SERVICE_PATH}/app.cpp + ${CERT_CHECKER_SERVICE_PATH}/queue.cpp # logs - ${CERT_CHECKER_SRC_PATH}/log/log.cpp + ${CERT_CHECKER_LOG_PATH}/log.cpp # dpl - ${CERT_CHECKER_SRC_PATH}/dpl/core/src/colors.cpp + ${DPL_CORE_SRC_PATH}/colors.cpp ) SET(CERT_CHECKER_POPUP_TEST_SOURCES # tests ${CERT_CHECKER_TESTS_SRC_PATH}/popup_test.cpp # cert-checker - ${CERT_CHECKER_SRC_PATH}/app.cpp - ${CERT_CHECKER_SRC_PATH}/ui/popup-runner.cpp - ${CERT_CHECKER_SRC_PATH}/ui/UIBackend.cpp + ${CERT_CHECKER_SERVICE_PATH}/app.cpp + ${CERT_CHECKER_UI_PATH}/popup-runner.cpp + ${CERT_CHECKER_UI_PATH}/UIBackend.cpp # logs - ${CERT_CHECKER_SRC_PATH}/log/log.cpp + ${CERT_CHECKER_LOG_PATH}/log.cpp ) INCLUDE_DIRECTORIES(SYSTEM - ${CERT_CHECKER_DEP_INCLUDE_DIRS} + ${CERT_CHECKER_TESTS_DEP_INCLUDE_DIRS} + ${CERT_CHECKER_SRC_PATH}/ ${CERT_CHECKER_SRC_PATH}/include/ - ${CERT_CHECKER_SRC_PATH}/dpl/core/include/ - ${CERT_CHECKER_SRC_PATH}/dpl/db/include/ + ${DPL_CORE_PATH}/include/ + ${DPL_DB_PATH}/include/ ${CERT_CHECKER_TESTS_SRC_PATH}/ ) @@ -96,6 +96,7 @@ ADD_EXECUTABLE(${TARGET_CERT_CHECKER_TESTS_LOGIC} ${CERT_CHECKER_TESTS_LOGIC_SOU ADD_EXECUTABLE(${TARGET_CERT_CHECKER_POPUP_TEST} ${CERT_CHECKER_POPUP_TEST_SOURCES}) TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER_TESTS} + ${TARGET_CERT_CHECKER_COMMON} ${CERT_CHECKER_TESTS_DEP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} boost_unit_test_framework @@ -103,6 +104,7 @@ TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER_TESTS} ) TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER_TESTS_LOGIC} + ${TARGET_CERT_CHECKER_COMMON} ${CERT_CHECKER_TESTS_DEP_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} boost_unit_test_framework @@ -110,6 +112,7 @@ TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER_TESTS_LOGIC} ) TARGET_LINK_LIBRARIES(${TARGET_CERT_CHECKER_POPUP_TEST} + ${TARGET_CERT_CHECKER_COMMON} ${CERT_CHECKER_TESTS_DEP_LIBRARIES} -ldl ) @@ -130,6 +133,6 @@ INSTALL(FILES files/app4/signature1.xml DESTINATION ${TEST_APP_SIGNATURES_DIR}/app4/) -INSTALL(TARGETS ${TARGET_CERT_CHECKER_TESTS} DESTINATION ${BINDIR}) -INSTALL(TARGETS ${TARGET_CERT_CHECKER_TESTS_LOGIC} DESTINATION ${BINDIR}) -INSTALL(TARGETS ${TARGET_CERT_CHECKER_POPUP_TEST} DESTINATION ${BINDIR}) +INSTALL(TARGETS ${TARGET_CERT_CHECKER_TESTS} DESTINATION ${BIN_DIR}) +INSTALL(TARGETS ${TARGET_CERT_CHECKER_TESTS_LOGIC} DESTINATION ${BIN_DIR}) +INSTALL(TARGETS ${TARGET_CERT_CHECKER_POPUP_TEST} DESTINATION ${BIN_DIR}) diff --git a/tests/app_event_operators.h b/tests/app_event_operators.h index 2638c19..a047e56 100644 --- a/tests/app_event_operators.h +++ b/tests/app_event_operators.h @@ -20,8 +20,8 @@ * @brief Implementation of app_test class (from app_t) */ -#include <cchecker/app.h> -#include <cchecker/queue.h> +#include "service/app.h" +#include "service/queue.h" #ifndef CCHECKER_APP_TEST_CLASS_H #define CCHECKER_APP_TEST_CLASS_H diff --git a/tests/certs_.h b/tests/certs_.h index ba1daab..163d299 100644 --- a/tests/certs_.h +++ b/tests/certs_.h @@ -20,7 +20,7 @@ * @brief Implementation of Certs for testing */ -#include <cchecker/certs.h> +#include "service/certs.h" #ifndef CCHECKER_DBFIXTURE_H #define CCHECKER_DBFIXTURE_H diff --git a/tests/logic_.h b/tests/logic_.h index 45ed559..a9317aa 100644 --- a/tests/logic_.h +++ b/tests/logic_.h @@ -28,7 +28,7 @@ * Some of methods are stubbed, and some of them just calls corresponding methods from Logic Class. */ -#include <cchecker/logic.h> +#include "service/logic.h" namespace CCHECKER { diff --git a/tests/queue_test_thread.cpp b/tests/queue_test_thread.cpp index aefc11b..b553dde 100644 --- a/tests/queue_test_thread.cpp +++ b/tests/queue_test_thread.cpp @@ -23,8 +23,8 @@ #include <thread> #include <unistd.h> -#include <cchecker/app.h> -#include <cchecker/queue.h> +#include "service/app.h" +#include "service/queue.h" #include <cchecker/log.h> #include <queue_test_thread.h> diff --git a/tests/queue_test_thread.h b/tests/queue_test_thread.h index c2489d5..2c2989e 100644 --- a/tests/queue_test_thread.h +++ b/tests/queue_test_thread.h @@ -20,7 +20,7 @@ * @brief Implementation of class for multi-thread testing Queue */ -#include <cchecker/queue.h> +#include "service/queue.h" namespace CCHECKER { diff --git a/tests/stubs_.cpp b/tests/stubs_.cpp index c63c668..1360986 100644 --- a/tests/stubs_.cpp +++ b/tests/stubs_.cpp @@ -20,8 +20,9 @@ * @brief Implementation of stubbed functions for testing */ -#include <cchecker/certs.h> -#include <cchecker/queue.h> +#include "service/certs.h" +#include "service/queue.h" + #include <cchecker/sql_query.h> #include <cchecker/UIBackend.h> diff --git a/tests/test_logic.cpp b/tests/test_logic.cpp index 99871fe..e471e99 100644 --- a/tests/test_logic.cpp +++ b/tests/test_logic.cpp @@ -49,12 +49,10 @@ std::string log_apps(std::list<app_t> &apps, std::list<app_t> buff) return ret; } - -} //anonymus +} // anonymous namespace BOOST_FIXTURE_TEST_SUITE(LOGIC_TEST, LogicWrapper) - BOOST_AUTO_TEST_CASE(logic_setup) { BOOST_REQUIRE(setup() == NO_ERROR); @@ -448,5 +446,4 @@ BOOST_AUTO_TEST_CASE(logic_workflow_OCSP_APP_REVOKED_2) { buff = get_buffer_(); BOOST_CHECK_MESSAGE(buff == apps, log_apps(apps, buff)); } - BOOST_AUTO_TEST_SUITE_END() |