diff options
60 files changed, 6113 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..a62936fd --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Bumjin Im <bj.i@samsung.com> diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..e5647df6 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,73 @@ +# Copyright (c) 2011 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 +# @brief +# + +############################# Check minimum CMake version ##################### + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT("key-manager") + +############################# cmake packages ################################## + +INCLUDE(FindPkgConfig) + +############################# compiler flags ################################## + +SET(CMAKE_C_FLAGS_PROFILING "-g -O0 -pg") +SET(CMAKE_CXX_FLAGS_PROFILING "-g -std=c++0x -O0 -pg") +SET(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb") +SET(CMAKE_CXX_FLAGS_DEBUG "-g -std=c++0x -O0 -ggdb") +SET(CMAKE_C_FLAGS_RELEASE "-g -O2") +SET(CMAKE_CXX_FLAGS_RELEASE "-g -std=c++0x -O2") +SET(CMAKE_C_FLAGS_CCOV "-g -O2 --coverage") +SET(CMAKE_CXX_FLAGS_CCOV "-g -std=c++0x -O2 --coverage") + +# If supported for the target machine, emit position-independent code,suitable +# for dynamic linking and avoiding any limit on the size of the global offset +# table. This option makes a difference on the m68k, PowerPC and SPARC. +# (BJ: our ARM too?) +ADD_DEFINITIONS("-fPIC") + +# 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 + +STRING(REGEX MATCH "([^.]*)" API_VERSION "${VERSION}") +ADD_DEFINITIONS("-DAPI_VERSION=\"$(API_VERSION)\"") +ADD_DEFINITIONS("-DSMACK_ENABLED") + +IF (CMAKE_BUILD_TYPE MATCHES "DEBUG") + ADD_DEFINITIONS("-DTIZEN_DEBUG_ENABLE") + ADD_DEFINITIONS("-DBUILD_TYPE_DEBUG") +ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") + +SET(TARGET_KEY_MANAGER "key-manager") +SET(TARGET_KEY_MANAGER_CLIENT "key-manager-client") +SET(TARGET_KEY_MANAGER_COMMON "key-manager-commons") + +INSTALL(FILES + ${CMAKE_SOURCE_DIR}/packaging/libkey-manager-client.manifest + ${CMAKE_SOURCE_DIR}/packaging/key-manager.manifest + DESTINATION + /usr/share +) + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(build) +ADD_SUBDIRECTORY(systemd) diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..247c97d0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,203 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. @@ -0,0 +1,35 @@ +README for key-manager project + +key-manager project contains of two parts: +1) the server part, that is implemented as a daemon that has vast rights for +vulnerable, security-related data, and that may be trusted by its clients. + +2) the client part, libkey-manager-client: a library that allows programs to +communicate with the server part. + +The libkey-manager-client library's API is available in the header file +src/include/key-manager.h. + +The libkey-manager-client API may be used to: +#TODO + +key-manager: + +The server part of manager is implemented in a /src/manager directory. +The implementation is divided into: + communication manager part: that is responsible for threads and communication management + with no awareness of what information is being transferred. This part is + implemented by SocketManager class that works with GenericSocketService as + a generalization for services that key-manager provides. +and + services part: implemented as classes derived from GenericSocketService + grouped in src/manager/service directory that defines actions done by + key-manager after receiving certain requests from client side. + +Adding services to key-manager should be done by creating a new class +derived from GenericSocketService, implementing proper functions for it, +registering it to SocketManager in main loop and making unix socket for service. + +The paths of unix sockets used in communication between server and libclient are +defined in src/manager/common directory. Sockets themselves are configured in +files in systemd directory. diff --git a/build/CMakeLists.txt b/build/CMakeLists.txt new file mode 100644 index 00000000..02ca0258 --- /dev/null +++ b/build/CMakeLists.txt @@ -0,0 +1,19 @@ +# Copyright (c) 2011 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 Tomasz Swierczek (t.swierczek@samsung.com) +# + +ADD_SUBDIRECTORY(key-manager) diff --git a/build/key-manager/CMakeLists.txt b/build/key-manager/CMakeLists.txt new file mode 100644 index 00000000..896cf6f8 --- /dev/null +++ b/build/key-manager/CMakeLists.txt @@ -0,0 +1,27 @@ +# Copyright (c) 2011 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 Barlomiej Grzelewski (b.grzelewski@samsung.com) +# @author Zofia Abramowska (z.abramowska@samsung.com) +# @brief +# + +CONFIGURE_FILE(key-manager.pc.in key-manager.pc @ONLY) + +INSTALL(FILES + ${CMAKE_BINARY_DIR}/build/key-manager/key-manager.pc + DESTINATION + ${LIB_INSTALL_DIR}/pkgconfig + ) diff --git a/build/key-manager/key-manager.pc.in b/build/key-manager/key-manager.pc.in new file mode 100644 index 00000000..aaf9e018 --- /dev/null +++ b/build/key-manager/key-manager.pc.in @@ -0,0 +1,11 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=@LIB_INSTALL_DIR@ +includedir=${prefix}/include + +Name: key-manager +Description: Central Key Manager Package +Version: 1.0.1 +Requires: openssl libsmack +Libs: -L${libdir} -lkey-manager-client -lsmack +Cflags: -I${includedir}/key-manager diff --git a/packaging/key-manager.manifest b/packaging/key-manager.manifest new file mode 100644 index 00000000..4c64b24d --- /dev/null +++ b/packaging/key-manager.manifest @@ -0,0 +1,8 @@ +<manifest> + <request> + <domain name="System" /> + </request> + <assign> + <filesystem path="/usr/bin/key-manager" label="key-manager" exec_label="key-manager"/> + </assign> +</manifest> diff --git a/packaging/key-manager.spec b/packaging/key-manager.spec new file mode 100644 index 00000000..77508b7b --- /dev/null +++ b/packaging/key-manager.spec @@ -0,0 +1,128 @@ +Name: key-manager +Summary: Central Key Manager and utilities +Version: 0.0.1 +Release: 1 +Group: System/Security +License: Apache License, Version 2.0 +Source0: %{name}-%{version}.tar.gz +BuildRequires: cmake +BuildRequires: zip +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(openssl) +BuildRequires: libattr-devel +BuildRequires: pkgconfig(libsmack) +BuildRequires: pkgconfig(libsystemd-daemon) +%{?systemd_requires} + +%description +Central Key Manager and utilities + +%package -n libkey-manager-client +Summary: Central Key Manager (client) +Group: Development/Libraries +Requires: key-manager = %{version}-%{release} +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libkey-manager-client +Central Key Manager package (client) + +%package -n libkey-manager-client-devel +Summary: Central Key Manager (client-devel) +Group: Development/Libraries +Requires: libkey-manager-client = %{version}-%{release} + +%description -n libkey-manager-client-devel +Central Key Manager package (client-devel) + +%package -n key-manager-devel +Summary: Central Key Manager (Development) +Group: Development/Libraries +Requires: key-manager = %{version}-%{release} + +%description -n key-manager-devel +Central Key Manager (Development) + + +%prep +%setup -q + +%build +%if 0%{?sec_build_binary_debug_enable} + export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" + export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" + export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" +%endif + +export LDFLAGS+="-Wl,--rpath=%{_libdir}" + +%cmake . -DVERSION=%{version} \ + -DCMAKE_BUILD_TYPE=%{?build_type:%build_type}%{!?build_type:RELEASE} \ + -DCMAKE_VERBOSE_MAKEFILE=ON +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +mkdir -p %{buildroot}/usr/share/license +cp LICENSE %{buildroot}/usr/share/license/%{name} +cp LICENSE %{buildroot}/usr/share/license/libkey-manager-client +mkdir -p %{buildroot}/etc/security/ +%make_install + +mkdir -p %{buildroot}/usr/lib/systemd/system/multi-user.target.wants +mkdir -p %{buildroot}/usr/lib/systemd/system/sockets.target.wants +ln -s ../key-manager.service %{buildroot}/usr/lib/systemd/system/multi-user.target.wants/key-manager.service + +%clean +rm -rf %{buildroot} + +%post +systemctl daemon-reload +if [ $1 = 1 ]; then + # installation + systemctl start key-manager.service +fi + +if [ $1 = 2 ]; then + # update + systemctl restart key-manager.service +fi + + +%preun +if [ $1 = 0 ]; then + # unistall + systemctl stop key-manager.service +fi + +%postun +if [ $1 = 0 ]; then + # unistall + systemctl daemon-reload +fi + +%post -n libkey-manager-client -p /sbin/ldconfig + +%postun -n libkey-manager-client -p /sbin/ldconfig + +%files -n key-manager +%manifest %{_datadir}/key-manager.manifest +%attr(755,root,root) /usr/bin/key-manager +%{_libdir}/libkey-manager-commons.so.* +%attr(-,root,root) /usr/lib/systemd/system/multi-user.target.wants/key-manager.service +%attr(-,root,root) /usr/lib/systemd/system/key-manager.service +%attr(-,root,root) /usr/lib/systemd/system/key-manager.target +%{_datadir}/license/%{name} + +%files -n libkey-manager-client +%manifest %{_datadir}/libkey-manager-client.manifest +%defattr(-,root,root,-) +%{_libdir}/libkey-manager-client.so.* +%{_datadir}/license/libkey-manager-client + +%files -n libkey-manager-client-devel +%defattr(-,root,root,-) +%{_libdir}/libkey-manager-client.so +%{_libdir}/libkey-manager-commons.so +/usr/include/key-manager/key-manager.h +%{_libdir}/pkgconfig/*.pc diff --git a/packaging/libkey-manager-client.manifest b/packaging/libkey-manager-client.manifest new file mode 100644 index 00000000..a76fdbae --- /dev/null +++ b/packaging/libkey-manager-client.manifest @@ -0,0 +1,5 @@ +<manifest> + <request> + <domain name="_" /> + </request> +</manifest> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..4735dc73 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,90 @@ +PKG_CHECK_MODULES(KEY_MANAGER_DEP + dlog + openssl + libsmack + libsystemd-daemon + REQUIRED + ) + +SET(KEY_MANAGER_SRC_PATH ${PROJECT_SOURCE_DIR}/src) +SET(KEY_MANAGER_PATH ${PROJECT_SOURCE_DIR}/src/manager) + +SET(KEY_MANAGER_SOURCES + ${KEY_MANAGER_PATH}/main/key-manager-util.cpp + ${KEY_MANAGER_PATH}/main/generic-socket-manager.cpp + ${KEY_MANAGER_PATH}/main/socket-manager.cpp + ${KEY_MANAGER_PATH}/main/key-manager-main.cpp + ) + +SET_SOURCE_FILES_PROPERTIES( + ${KEY_MANAGER_SOURCES} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden") + +INCLUDE_DIRECTORIES(SYSTEM + ${KEY_MANAGER_DEP_INCLUDE_DIRS} + ) + +INCLUDE_DIRECTORIES( + ${KEY_MANAGER_SRC_PATH}/include + ${KEY_MANAGER_PATH}/main + ${KEY_MANAGER_PATH}/common + ${KEY_MANAGER_PATH}/service + ${KEY_MANAGER_PATH}/dpl/core/include + ${KEY_MANAGER_PATH}/dpl/log/include + ) + +ADD_EXECUTABLE(${TARGET_KEY_MANAGER} ${KEY_MANAGER_SOURCES}) + +TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER} + ${KEY_MANAGER_DEP_LIBRARIES} + ${TARGET_KEY_MANAGER_COMMON} + ) + +################################################################################ + +SET(KEY_MANAGER_CLIENT_VERSION_MAJOR 1) +SET(KEY_MANAGER_CLIENT_VERSION ${KEY_MANAGER_CLIENT_VERSION_MAJOR}.0.1) + +SET(KEY_MANAGER_CLIENT_SRC_PATH ${KEY_MANAGER_PATH}/client) + +INCLUDE_DIRECTORIES( + ${KEY_MANAGER_PATH}/client + ${KEY_MANAGER_PATH}/common + ${KEY_MANAGER_PATH}/dpl/core/include + ${KEY_MANAGER_PATH}/dpl/log/include + ) + +SET(KEY_MANAGER_CLIENT_SOURCES + ${KEY_MANAGER_CLIENT_SRC_PATH}/client-common.cpp + ) + +ADD_LIBRARY(${TARGET_KEY_MANAGER_CLIENT} SHARED ${KEY_MANAGER_CLIENT_SOURCES}) + +SET_TARGET_PROPERTIES( + ${TARGET_KEY_MANAGER_CLIENT} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=hidden" + SOVERSION ${KEY_MANAGER_CLIENT_VERSION_MAJOR} + VERSION ${KEY_MANAGER_CLIENT_VERSION} + ) + +TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER_CLIENT} + ${KEY_MANAGER_DEP_LIBRARIES} + ${TARGET_KEY_MANAGER_COMMON} + ) + +################################################################################ + +INSTALL(TARGETS ${TARGET_KEY_MANAGER_CLIENT} DESTINATION ${LIB_INSTALL_DIR}) + +INSTALL(TARGETS ${TARGET_KEY_MANAGER} DESTINATION bin) + +INSTALL(FILES + ${KEY_MANAGER_SRC_PATH}/include/key-manager.h + DESTINATION /usr/include/key-manager + ) + +################################################################################ + +ADD_SUBDIRECTORY(manager) diff --git a/src/include/key-manager.h b/src/include/key-manager.h new file mode 100644 index 00000000..d25517a3 --- /dev/null +++ b/src/include/key-manager.h @@ -0,0 +1,123 @@ +/* + * key-manager + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 + * + */ + +#ifndef KEY_MANAGER_H +#define KEY_MANAGER_H + +#include <sys/types.h> + +/** + * @file key-manager.h + * @version 1.0 + * @brief This file contains APIs of the Central Key Manager +*/ + +/** + * @defgroup SecurityFW + * @{ + * + * @defgroup KEY_MANAGER Central Key Manager + * @version 1.0 + * @brief Central Key Manager client library functions + * +*/ + +/** + * @addtogroup KEY_MANAGER + * @{ +*/ + +/** + * \name Return Codes + * exported by the foundation API. + * result codes begin with the start error code and extend into negative direction. + * @{ +*/ +#define KEY_MANAGER_API_SUCCESS 0 +/*! \brief indicating the result of the one specific API is successful */ +#define KEY_MANAGER_API_ERROR_SOCKET -1 + +/*! \brief indicating the socket between client and Central Key Manager failed */ +#define KEY_MANAGER_API_ERROR_BAD_REQUEST -2 + +/*! \brief indicating the response from Central Key Manager is malformed */ +#define KEY_MANAGER_API_ERROR_BAD_RESPONSE -3 + +/*! \brief indicating the transmitting request failed */ +/* deprecated unused */ +#define KEY_MANAGER_API_ERROR_SEND_FAILED -4 + +/*! \brief indicating the receiving response failed */ +/* deprecated unused */ +#define KEY_MANAGER_API_ERROR_RECV_FAILED -5 + +/*! \brief indicating the authentication between client and manager failed */ +#define KEY_MANAGER_API_ERROR_AUTHENTICATION_FAILED -6 + +/*! \brief indicating the API's input parameter is malformed */ +#define KEY_MANAGER_API_ERROR_INPUT_PARAM -7 + +/*! \brief indicating the output buffer size which is passed as parameter is too small */ +#define KEY_MANAGER_API_ERROR_BUFFER_TOO_SMALL -8 + +/*! \brief indicating system is running out of memory state */ +#define KEY_MANAGER_API_ERROR_OUT_OF_MEMORY -9 + +/*! \brief indicating the access has been denied by Central Key Manager */ +#define KEY_MANAGER_API_ERROR_ACCESS_DENIED -10 + +/*! \brief indicating Central Key Manager has been failed for some reason */ +#define KEY_MANAGER_API_ERROR_SERVER_ERROR -11 + +/*! \brief indicating getting smack label from socket failed */ +#define KEY_MANAGER_API_ERROR_GETTING_SOCKET_LABEL_FAILED -12 + +/*! \brief indicating getting smack label from file failed */ +#define KEY_MANAGER_API_ERROR_GETTING_FILE_LABEL_FAILED -13 + +/*! \brief indicating setting smack label for file failed */ +#define KEY_MANAGER_API_ERROR_SETTING_FILE_LABEL_FAILED -14 + +/*! \brief indicating the error with unknown reason */ +#define KEY_MANAGER_API_ERROR_UNKNOWN -255 +/** @}*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +#ifdef __cplusplus +} +#endif + +/** + * @} +*/ + +/** + * @} +*/ + +#endif diff --git a/src/manager/CMakeLists.txt b/src/manager/CMakeLists.txt new file mode 100644 index 00000000..85841f71 --- /dev/null +++ b/src/manager/CMakeLists.txt @@ -0,0 +1,52 @@ +PKG_CHECK_MODULES(COMMON_DEP + dlog + REQUIRED + ) + +SET(COMMON_PATH ${PROJECT_SOURCE_DIR}/src/manager) + +SET(COMMON_SOURCES + ${COMMON_PATH}/common/protocols.cpp + ${COMMON_PATH}/common/message-buffer.cpp + ${COMMON_PATH}/common/smack-check.cpp + ${COMMON_PATH}/dpl/log/src/abstract_log_provider.cpp + ${COMMON_PATH}/dpl/log/src/dlog_log_provider.cpp + ${COMMON_PATH}/dpl/log/src/log.cpp + ${COMMON_PATH}/dpl/log/src/old_style_log_provider.cpp + ${COMMON_PATH}/dpl/core/src/assert.cpp + ${COMMON_PATH}/dpl/core/src/binary_queue.cpp + ${COMMON_PATH}/dpl/core/src/colors.cpp + ${COMMON_PATH}/dpl/core/src/exception.cpp + ${COMMON_PATH}/dpl/core/src/noncopyable.cpp + ${COMMON_PATH}/dpl/core/src/serialization.cpp + ${COMMON_PATH}/dpl/core/src/singleton.cpp + ) + +INCLUDE_DIRECTORIES(SYSTEM + ${COMMON_DEP_INCLUDE_DIRS} + ) + +INCLUDE_DIRECTORIES( + ${COMMON_PATH}/common + ${COMMON_PATH}/dpl/core/include + ${COMMON_PATH}/dpl/log/include + ) + +ADD_LIBRARY(${TARGET_KEY_MANAGER_COMMON} SHARED ${COMMON_SOURCES}) + +SET_TARGET_PROPERTIES( + ${TARGET_KEY_MANAGER_COMMON} + PROPERTIES + COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=default" + SOVERSION 1.0.0 + VERSION 1.0.0 + ) + +TARGET_LINK_LIBRARIES(${TARGET_KEY_MANAGER_COMMON} + ${COMMON_DEP_LIBRARIES} + ) + +################################################################################ + +INSTALL(TARGETS ${TARGET_KEY_MANAGER_COMMON} DESTINATION lib) + diff --git a/src/manager/client/client-common.cpp b/src/manager/client/client-common.cpp new file mode 100644 index 00000000..8223c890 --- /dev/null +++ b/src/manager/client/client-common.cpp @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 client-common.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief This file is implementation of client-common functions. + */ + +#include <fcntl.h> +#include <poll.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> + +#include <dpl/log/log.h> +#include <dpl/serialization.h> +#include <dpl/singleton.h> +#include <dpl/singleton_safe_impl.h> + +#include <message-buffer.h> + +#include <key-manager.h> + +IMPLEMENT_SAFE_SINGLETON(CentralKeyManager::Log::LogSystem); + +namespace { + +const int POLL_TIMEOUT = 2000; + +void centKeyClientEnableLogSystem(void) { + CentralKeyManager::Singleton<CentralKeyManager::Log::LogSystem>::Instance().SetTag("CENT_KEY_CLIENT"); +} + +int waitForSocket(int sock, int event, int timeout) { + int retval; + pollfd desc[1]; + desc[0].fd = sock; + desc[0].events = event; + + while((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) { + timeout >>= 1; + errno = 0; + } + + if (0 == retval) { + LogDebug("Poll timeout"); + } else if (-1 == retval) { + int err = errno; + LogError("Error in poll: " << strerror(err)); + } + return retval; +} + +class SockRAII { +public: + SockRAII() + : m_sock(-1) + {} + + virtual ~SockRAII() { + if (m_sock > -1) + close(m_sock); + } + + int Connect(char const * const interface) { + sockaddr_un clientAddr; + int flags; + + if (m_sock != -1) // guard + close(m_sock); + + m_sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (m_sock < 0) { + int err = errno; + LogError("Error creating socket: " << strerror(err)); + return KEY_MANAGER_API_ERROR_SOCKET; + } + + if ((flags = fcntl(m_sock, F_GETFL, 0)) < 0 || + fcntl(m_sock, F_SETFL, flags | O_NONBLOCK) < 0) + { + int err = errno; + LogError("Error in fcntl: " << strerror(err)); + return KEY_MANAGER_API_ERROR_SOCKET; + } + + memset(&clientAddr, 0, sizeof(clientAddr)); + + clientAddr.sun_family = AF_UNIX; + + if (strlen(interface) >= sizeof(clientAddr.sun_path)) { + LogError("Error: interface name " << interface << "is too long. Max len is:" << sizeof(clientAddr.sun_path)); + return KEY_MANAGER_API_ERROR_SOCKET; + } + + strcpy(clientAddr.sun_path, interface); + + LogDebug("ClientAddr.sun_path = " << interface); + + int retval = TEMP_FAILURE_RETRY(connect(m_sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr))); + if ((retval == -1) && (errno == EINPROGRESS)) { + if (0 >= waitForSocket(m_sock, POLLIN, POLL_TIMEOUT)) { + LogError("Error in waitForSocket."); + return KEY_MANAGER_API_ERROR_SOCKET; + } + int error = 0; + size_t len = sizeof(error); + retval = getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &len); + + if (-1 == retval) { + int err = errno; + LogError("Error in getsockopt: " << strerror(err)); + return KEY_MANAGER_API_ERROR_SOCKET; + } + + if (error == EACCES) { + LogError("Access denied"); + return KEY_MANAGER_API_ERROR_ACCESS_DENIED; + } + + if (error != 0) { + LogError("Error in connect: " << strerror(error)); + return KEY_MANAGER_API_ERROR_SOCKET; + } + + return KEY_MANAGER_API_SUCCESS; + } + + if (-1 == retval) { + int err = errno; + LogError("Error connecting socket: " << strerror(err)); + if (err == EACCES) + return KEY_MANAGER_API_ERROR_ACCESS_DENIED; + return KEY_MANAGER_API_ERROR_SOCKET; + } + + return KEY_MANAGER_API_SUCCESS; + } + + int Get() { + return m_sock; + } + +private: + int m_sock; +}; + +} // namespace anonymous + +namespace CentralKeyManager { + + +int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) { + int ret; + SockRAII sock; + ssize_t done = 0; + char buffer[2048]; + + if (KEY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) { + LogError("Error in SockRAII"); + return ret; + } + + while ((send.size() - done) > 0) { + if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) { + LogError("Error in poll(POLLOUT)"); + return KEY_MANAGER_API_ERROR_SOCKET; + } + ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done)); + if (-1 == temp) { + int err = errno; + LogError("Error in write: " << strerror(err)); + return KEY_MANAGER_API_ERROR_SOCKET; + } + done += temp; + } + + do { + if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) { + LogError("Error in poll(POLLIN)"); + return KEY_MANAGER_API_ERROR_SOCKET; + } + ssize_t temp = TEMP_FAILURE_RETRY(read(sock.Get(), buffer, 2048)); + if (-1 == temp) { + int err = errno; + LogError("Error in read: " << strerror(err)); + return KEY_MANAGER_API_ERROR_SOCKET; + } + + if (0 == temp) { + LogError("Read return 0/Connection closed by server(?)"); + return KEY_MANAGER_API_ERROR_SOCKET; + } + + RawBuffer raw(buffer, buffer+temp); + recv.Push(raw); + } while(!recv.Ready()); + return KEY_MANAGER_API_SUCCESS; +} + +int try_catch(const std::function<int()>& func) +{ + try { + return func(); + } catch (MessageBuffer::Exception::Base &e) { + LogError("CentralKeyManager::MessageBuffer::Exception " << e.DumpToString()); + } catch (std::exception &e) { + LogError("STD exception " << e.what()); + } catch (...) { + LogError("Unknown exception occured"); + } + return KEY_MANAGER_API_ERROR_UNKNOWN; +} + +} // namespace CentralKeyManager + +static void init_lib(void) __attribute__ ((constructor)); +static void init_lib(void) +{ + centKeyClientEnableLogSystem(); +} + +static void fini_lib(void) __attribute__ ((destructor)); +static void fini_lib(void) +{ + +} + diff --git a/src/manager/client/client-common.h b/src/manager/client/client-common.h new file mode 100644 index 00000000..9022fa8e --- /dev/null +++ b/src/manager/client/client-common.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 client-common.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief This file constains implementation of common types + * used in Central Key Manager. + */ + +#ifndef _KEY_MANAGER_CLIENT_ +#define _KEY_MANAGER_CLIENT_ + +#include <vector> +#include <functional> + +#include <message-buffer.h> + +#define KEY_MANAGER_API __attribute__((visibility("default"))) + +extern "C" { + struct msghdr; +} + +namespace CentralKeyManager { + +typedef std::vector<unsigned char> RawBuffer; + +int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv); + +/* + * Decorator function that performs frequently repeated exception handling in + * SS client API functions. Accepts lambda expression as an argument. + */ +int try_catch(const std::function<int()>& func); + +} // namespace CentralKeyManager + +#endif // _KEY_MANAGER_CLIENT_ diff --git a/src/manager/common/connection-info.h b/src/manager/common/connection-info.h new file mode 100644 index 00000000..6b50a522 --- /dev/null +++ b/src/manager/common/connection-info.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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-info.h + * @author Lukasz Kostyra (l.kostyra@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief Definition of ConnectionInfo structure and ConnectionInfoMap type. + */ + +#ifndef _CONNECTION_INFO_H_ +#define _CONNECTION_INFO_H_ + +#include <map> +#include <generic-socket-manager.h> +#include <message-buffer.h> + +namespace CentralKeyManager +{ + struct ConnectionInfo { + InterfaceID interfaceID; + MessageBuffer buffer; + }; + + typedef std::map<int, ConnectionInfo> ConnectionInfoMap; +} //namespace CentralKeyManager + +#endif //_CONNECTION_INFO_H_ diff --git a/src/manager/common/message-buffer.cpp b/src/manager/common/message-buffer.cpp new file mode 100644 index 00000000..7425a25f --- /dev/null +++ b/src/manager/common/message-buffer.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 message-buffer.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief Implementation of MessageBuffer. + */ + +#include <message-buffer.h> + +#include <dpl/log/log.h> + +namespace CentralKeyManager { + +void MessageBuffer::Push(const RawBuffer &data) { + m_buffer.AppendCopy(&data[0], data.size()); +} + +RawBuffer MessageBuffer::Pop() { + size_t size = m_buffer.Size(); + RawBuffer buffer; + buffer.resize(size + sizeof(size_t)); + memcpy(&buffer[0], &size, sizeof(size_t)); + m_buffer.FlattenConsume(&buffer[sizeof(size_t)], size); + return buffer; +} + +bool MessageBuffer::Ready() { + CountBytesLeft(); + if (m_bytesLeft == 0) + return false; + if (m_bytesLeft > m_buffer.Size()) + return false; + return true; +} + +void MessageBuffer::Read(size_t num, void *bytes) { + CountBytesLeft(); + if (num > m_bytesLeft) { + LogDebug("Protocol broken. OutOfData. Asked for: " << num << " Ready: " << m_bytesLeft << " Buffer.size(): " << m_buffer.Size()); + Throw(Exception::OutOfData); + } + + m_buffer.FlattenConsume(bytes, num); + m_bytesLeft -= num; +} + +void MessageBuffer::Write(size_t num, const void *bytes) { + m_buffer.AppendCopy(bytes, num); +} + +} // namespace CentralKeyManager + diff --git a/src/manager/common/message-buffer.h b/src/manager/common/message-buffer.h new file mode 100644 index 00000000..89cd824c --- /dev/null +++ b/src/manager/common/message-buffer.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 secket-buffer.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief Implementatin of MessageBuffer. + */ + +#ifndef _CENT_KEY_MNG_SOCKET_BUFFER_ +#define _CENT_KEY_MNG_SOCKET_BUFFER_ + +#include <vector> + +#include <dpl/binary_queue.h> +#include <dpl/exception.h> +#include <dpl/serialization.h> + +namespace CentralKeyManager { + +typedef std::vector<unsigned char> RawBuffer; + +class MessageBuffer : public CentralKeyManager::IStream { +public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(CentralKeyManager::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OutOfData) + }; + + MessageBuffer() + : m_bytesLeft(0) + {} + + void Push(const RawBuffer &data); + + RawBuffer Pop(); + + bool Ready(); + + virtual void Read(size_t num, void *bytes); + + virtual void Write(size_t num, const void *bytes); + +protected: + + inline void CountBytesLeft() { + if (m_bytesLeft > 0) + return; // we already counted m_bytesLeft nothing to do + + if (m_buffer.Size() < sizeof(size_t)) + return; // we cannot count m_bytesLeft because buffer is too small + + m_buffer.FlattenConsume(&m_bytesLeft, sizeof(size_t)); + } + + size_t m_bytesLeft; + CentralKeyManager::BinaryQueue m_buffer; +}; + +} // namespace CentralKeyManager + +#endif // _CENT_KEY_MNG_SOCKET_BUFFER_ diff --git a/src/manager/common/protocols.cpp b/src/manager/common/protocols.cpp new file mode 100644 index 00000000..f12d7e29 --- /dev/null +++ b/src/manager/common/protocols.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 protocols.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief List of all protocols supported by Central Key Manager. + */ + +#include <protocols.h> + +namespace CentralKeyManager { + + +} // namespace CentralKeyManager + diff --git a/src/manager/common/protocols.h b/src/manager/common/protocols.h new file mode 100644 index 00000000..31bdc3e3 --- /dev/null +++ b/src/manager/common/protocols.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 protocols.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief This file contains list of all protocols suported by Central + * Key Manager. + */ + +#ifndef _CENT_KEY_MNG_PROTOCOLS_ +#define _CENT_KEY_MNG_PROTOCOLS_ + +namespace CentralKeyManager { + + +} // namespace CentralKeyManager + +#endif // _CENT_KEY_MNG_PROTOCOLS_ + diff --git a/src/manager/common/smack-check.cpp b/src/manager/common/smack-check.cpp new file mode 100644 index 00000000..f6f6f303 --- /dev/null +++ b/src/manager/common/smack-check.cpp @@ -0,0 +1,34 @@ +#include <smack-check.h> + +#include <stdlib.h> +#include <sys/smack.h> + +#include <dpl/log/log.h> + +namespace CentralKeyManager { + +int smack_runtime_check(void) +{ + static int smack_present = -1; + if (-1 == smack_present) { + if (NULL == smack_smackfs_path()) { + LogDebug("no smack found on device"); + smack_present = 0; + } else { + LogDebug("found smack on device"); + smack_present = 1; + } + } + return smack_present; +} + +int smack_check(void) +{ +#ifndef SMACK_ENABLED + return 0; +#else + return smack_runtime_check(); +#endif +} + +} // namespace CentralKeyManager diff --git a/src/manager/common/smack-check.h b/src/manager/common/smack-check.h new file mode 100644 index 00000000..e1d81b15 --- /dev/null +++ b/src/manager/common/smack-check.h @@ -0,0 +1,42 @@ +/* + * key-manager + * + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 + */ + +#ifndef _SMACK_CHECK_H_ +#define _SMACK_CHECK_H_ + +namespace CentralKeyManager { + +/* + * A very simple runtime check for SMACK on the platform + * Returns 1 if SMACK is present, 0 otherwise + */ + +int smack_runtime_check(void); + +/* + * A very simple runtime check for SMACK on the platform + * Returns 1 if SMACK is present, 0 otherwise. If SMACK_ENABLED is not defined + * It returns 0. + */ +int smack_check(void); + +} // namespace CentralKeyManager + +#endif // _SMACK_CHECK_H_ diff --git a/src/manager/dpl/core/include/dpl/assert.h b/src/manager/dpl/core/include/dpl/assert.h new file mode 100644 index 00000000..7e1062e9 --- /dev/null +++ b/src/manager/dpl/core/include/dpl/assert.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2011 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 assert.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of assert + */ +#ifndef CENT_KEY_ASSERT_H +#define CENT_KEY_ASSERT_H + +#include <dpl/noreturn.h> + +namespace CentralKeyManager { +// Assertion handler procedure +// Do not call directly +// Always use Assert macro +CENT_KEY_NORETURN void AssertProc(const char *condition, + const char *file, + int line, + const char *function); +} // namespace CentralKeyManager + +#define Assert(Condition) do { if (!(Condition)) { CentralKeyManager::AssertProc(#Condition, \ + __FILE__, \ + __LINE__, \ + __FUNCTION__); \ + } } while (0) + +#endif // CENT_KEY_ASSERT_H diff --git a/src/manager/dpl/core/include/dpl/binary_queue.h b/src/manager/dpl/core/include/dpl/binary_queue.h new file mode 100644 index 00000000..2b3dd7a1 --- /dev/null +++ b/src/manager/dpl/core/include/dpl/binary_queue.h @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2011 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) + * @version 1.0 + * @brief This file is the header file of binary queue + */ +#ifndef CENT_KEY_BINARY_QUEUE_H +#define CENT_KEY_BINARY_QUEUE_H + +//#include <dpl/abstract_input_output.h> +#include <dpl/exception.h> +#include <dpl/noncopyable.h> +#include <memory> +#include <list> + +namespace CentralKeyManager { +/** + * Binary queue auto pointer + */ +class BinaryQueue; +typedef std::auto_ptr<BinaryQueue> BinaryQueueAutoPtr; + +/** + * Binary stream implemented as constant size bucket list + * + * @todo Add optimized implementation for FlattenConsume + */ +class BinaryQueue +// : public AbstractInputOutput +{ + public: + class Exception + { + public: + DECLARE_EXCEPTION_TYPE(CentralKeyManager::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, OutOfData) + }; + + typedef void (*BufferDeleter)(const void *buffer, size_t bufferSize, + void *userParam); + static void BufferDeleterFree(const void *buffer, + size_t bufferSize, + void *userParam); + + class BucketVisitor + { + public: + /** + * Destructor + */ + virtual ~BucketVisitor(); + + /** + * Visit bucket + * + * @return none + * @param[in] buffer Constant pointer to bucket data buffer + * @param[in] bufferSize Number of bytes in bucket + */ + virtual void OnVisitBucket(const void *buffer, size_t bufferSize) = 0; + }; + + private: + struct Bucket : + private Noncopyable + { + const void *buffer; + const void *ptr; + size_t size; + size_t left; + + BufferDeleter deleter; + void *param; + + Bucket(const void *buffer, + size_t bufferSize, + BufferDeleter deleter, + void *userParam); + virtual ~Bucket(); + }; + + typedef std::list<Bucket *> BucketList; + BucketList m_buckets; + size_t m_size; + + static void DeleteBucket(Bucket *bucket); + + class BucketVisitorCall + { + private: + BucketVisitor *m_visitor; + + public: + BucketVisitorCall(BucketVisitor *visitor); + virtual ~BucketVisitorCall(); + + void operator()(Bucket *bucket) const; + }; + + public: + /** + * Construct empty binary queue + */ + BinaryQueue(); + + /** + * Construct binary queue via bare copy of other binary queue + * + * @param[in] other Other binary queue to copy from + * @warning One cannot assume that bucket structure is preserved during copy + */ + BinaryQueue(const BinaryQueue &other); + + /** + * Destructor + */ + virtual ~BinaryQueue(); + + /** + * Construct binary queue via bare copy of other binary queue + * + * @param[in] other Other binary queue to copy from + * @warning One cannot assume that bucket structure is preserved during copy + */ + const BinaryQueue &operator=(const BinaryQueue &other); + + /** + * Append copy of @a bufferSize bytes from memory pointed by @a buffer + * to the end of binary queue. Uses default deleter based on free. + * + * @return none + * @param[in] buffer Pointer to buffer to copy data from + * @param[in] bufferSize Number of bytes to copy + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @see BinaryQueue::BufferDeleterFree + */ + void AppendCopy(const void *buffer, size_t bufferSize); + + /** + * Append @a bufferSize bytes from memory pointed by @a buffer + * to the end of binary queue. Uses custom provided deleter. + * Responsibility for deleting provided buffer is transfered to BinaryQueue. + * + * @return none + * @param[in] buffer Pointer to data buffer + * @param[in] bufferSize Number of bytes available in buffer + * @param[in] deleter Pointer to deleter procedure used to free provided + * buffer + * @param[in] userParam User parameter passed to deleter routine + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendUnmanaged( + const void *buffer, + size_t bufferSize, + BufferDeleter deleter = + &BinaryQueue::BufferDeleterFree, + void *userParam = NULL); + + /** + * Append copy of other binary queue to the end of this binary queue + * + * @return none + * @param[in] other Constant reference to other binary queue to copy data + * from + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @warning One cannot assume that bucket structure is preserved during copy + */ + void AppendCopyFrom(const BinaryQueue &other); + + /** + * Move bytes from other binary queue to the end of this binary queue. + * This also removes all bytes from other binary queue. + * This method is designed to be as fast as possible (only pointer swaps) + * and is suggested over making copies of binary queues. + * Bucket structure is preserved after operation. + * + * @return none + * @param[in] other Reference to other binary queue to move data from + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendMoveFrom(BinaryQueue &other); + + /** + * Append copy of binary queue to the end of other binary queue + * + * @return none + * @param[in] other Constant reference to other binary queue to copy data to + * @exception std::bad_alloc Cannot allocate memory to hold additional data + * @warning One cannot assume that bucket structure is preserved during copy + */ + void AppendCopyTo(BinaryQueue &other) const; + + /** + * Move bytes from binary queue to the end of other binary queue. + * This also removes all bytes from binary queue. + * This method is designed to be as fast as possible (only pointer swaps) + * and is suggested over making copies of binary queues. + * Bucket structure is preserved after operation. + * + * @return none + * @param[in] other Reference to other binary queue to move data to + * @exception std::bad_alloc Cannot allocate memory to hold additional data + */ + void AppendMoveTo(BinaryQueue &other); + + /** + * Retrieve total size of all data contained in binary queue + * + * @return Number of bytes in binary queue + */ + size_t Size() const; + + /** + * Remove all data from binary queue + * + * @return none + */ + void Clear(); + + /** + * Check if binary queue is empty + * + * @return true if binary queue is empty, false otherwise + */ + bool Empty() const; + + /** + * Remove @a size bytes from beginning of binary queue + * + * @return none + * @param[in] size Number of bytes to remove + * @exception BinaryQueue::Exception::OutOfData Number of bytes is larger + * than available bytes in binary queue + */ + void Consume(size_t size); + + /** + * Retrieve @a bufferSize bytes from beginning of binary queue and copy them + * to user supplied buffer + * + * @return none + * @param[in] buffer Pointer to user buffer to receive bytes + * @param[in] bufferSize Size of user buffer pointed by @a buffer + * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten + * is larger than available bytes in binary queue + */ + void Flatten(void *buffer, size_t bufferSize) const; + + /** + * Retrieve @a bufferSize bytes from beginning of binary queue, copy them + * to user supplied buffer, and remove from binary queue + * + * @return none + * @param[in] buffer Pointer to user buffer to receive bytes + * @param[in] bufferSize Size of user buffer pointed by @a buffer + * @exception BinaryQueue::Exception::OutOfData Number of bytes to flatten + * is larger than available bytes in binary queue + */ + void FlattenConsume(void *buffer, size_t bufferSize); + + /** + * Visit each buffer with data using visitor object + * + * @return none + * @param[in] visitor Pointer to bucket visitor + * @see BinaryQueue::BucketVisitor + */ + void VisitBuckets(BucketVisitor *visitor) const; + + /** + * IAbstractInput interface + */ + virtual BinaryQueueAutoPtr Read(size_t size); + + /** + * IAbstractOutput interface + */ + virtual size_t Write(const BinaryQueue &buffer, size_t bufferSize); +}; + +} // namespace CentralKeyManager + +#endif // CENT_KEY_BINARY_QUEUE_H diff --git a/src/manager/dpl/core/include/dpl/colors.h b/src/manager/dpl/core/include/dpl/colors.h new file mode 100644 index 00000000..641904b6 --- /dev/null +++ b/src/manager/dpl/core/include/dpl/colors.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2011 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 colors.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Some constants with definition of colors for Console + * and html output + */ + +#ifndef CENT_KEY_COLORS_H +#define CENT_KEY_COLORS_H + +namespace CentralKeyManager { +namespace Colors { +namespace Text { +extern const char* BOLD_GREEN_BEGIN; +extern const char* BOLD_GREEN_END; +extern const char* PURPLE_BEGIN; +extern const char* PURPLE_END; +extern const char* RED_BEGIN; +extern const char* RED_END; +extern const char* GREEN_BEGIN; +extern const char* GREEN_END; +extern const char* CYAN_BEGIN; +extern const char* CYAN_END; +extern const char* BOLD_RED_BEGIN; +extern const char* BOLD_RED_END; +extern const char* BOLD_YELLOW_BEGIN; +extern const char* BOLD_YELLOW_END; +extern const char* BOLD_GOLD_BEGIN; +extern const char* BOLD_GOLD_END; +extern const char* BOLD_WHITE_BEGIN; +extern const char* BOLD_WHITE_END; +} //namespace Text + +namespace Html { +extern const char* BOLD_GREEN_BEGIN; +extern const char* BOLD_GREEN_END; +extern const char* PURPLE_BEGIN; +extern const char* PURPLE_END; +extern const char* RED_BEGIN; +extern const char* RED_END; +extern const char* GREEN_BEGIN; +extern const char* GREEN_END; +extern const char* CYAN_BEGIN; +extern const char* CYAN_END; +extern const char* BOLD_RED_BEGIN; +extern const char* BOLD_RED_END; +extern const char* BOLD_YELLOW_BEGIN; +extern const char* BOLD_YELLOW_END; +extern const char* BOLD_GOLD_BEGIN; +extern const char* BOLD_GOLD_END; +extern const char* BOLD_WHITE_BEGIN; +extern const char* BOLD_WHITE_END; +} //namespace Html +} //namespace Colors +} //namespace CentralKeyManager + +#endif /* CENT_KEY_COLORS_H */ diff --git a/src/manager/dpl/core/include/dpl/exception.h b/src/manager/dpl/core/include/dpl/exception.h new file mode 100644 index 00000000..1e06cc78 --- /dev/null +++ b/src/manager/dpl/core/include/dpl/exception.h @@ -0,0 +1,385 @@ +/* + * Copyright (c) 2011 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 exception.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief Header file for base exception + */ +#ifndef CENT_KEY_EXCEPTION_H +#define CENT_KEY_EXCEPTION_H + +#include <string> +#include <cstring> +#include <cstdio> +#include <exception> +#include <cstdlib> +#include <sstream> + +namespace CentralKeyManager { +void LogUnhandledException(const std::string &str); +void LogUnhandledException(const std::string &str, + const char *filename, + int line, + const char *function); +} + +namespace CentralKeyManager { +class Exception +{ + private: + static unsigned int m_exceptionCount; + static Exception* m_lastException; + static void (*m_terminateHandler)(); + + static void AddRef(Exception* exception) + { + if (!m_exceptionCount) { + m_terminateHandler = std::set_terminate(&TerminateHandler); + } + + ++m_exceptionCount; + m_lastException = exception; + } + + static void UnRef(Exception* e) + { + if (m_lastException == e) { + m_lastException = NULL; + } + + --m_exceptionCount; + + if (!m_exceptionCount) { + std::set_terminate(m_terminateHandler); + m_terminateHandler = NULL; + } + } + + static void TerminateHandler() + { + if (m_lastException != NULL) { + DisplayKnownException(*m_lastException); + abort(); + } else { + DisplayUnknownException(); + abort(); + } + } + + Exception *m_reason; + std::string m_path; + std::string m_function; + int m_line; + + protected: + std::string m_message; + std::string m_className; + + public: + static std::string KnownExceptionToString(const Exception &e) + { + std::ostringstream message; + message << + "\033[1;5;31m\n=== Unhandled CentralKeyManager exception occurred ===\033[m\n\n"; + message << "\033[1;33mException trace:\033[m\n\n"; + message << e.DumpToString(); + message << "\033[1;31m\n=== Will now abort ===\033[m\n"; + + return message.str(); + } + + static std::string UnknownExceptionToString() + { + std::ostringstream message; + message << + "\033[1;5;31m\n=== Unhandled non-CentralKeyManager exception occurred ===\033[m\n\n"; + message << "\033[1;31m\n=== Will now abort ===\033[m\n"; + + return message.str(); + } + + static void DisplayKnownException(const Exception& e) + { + LogUnhandledException(KnownExceptionToString(e).c_str()); + } + + static void DisplayUnknownException() + { + LogUnhandledException(UnknownExceptionToString().c_str()); + } + + Exception(const Exception &other) + { + // Deep copy + if (other.m_reason != NULL) { + m_reason = new Exception(*other.m_reason); + } else { + m_reason = NULL; + } + + m_message = other.m_message; + m_path = other.m_path; + m_function = other.m_function; + m_line = other.m_line; + + m_className = other.m_className; + + AddRef(this); + } + + const Exception &operator =(const Exception &other) + { + if (this == &other) { + return *this; + } + + // Deep copy + if (other.m_reason != NULL) { + m_reason = new Exception(*other.m_reason); + } else { + m_reason = NULL; + } + + m_message = other.m_message; + m_path = other.m_path; + m_function = other.m_function; + m_line = other.m_line; + + m_className = other.m_className; + + AddRef(this); + + return *this; + } + + Exception(const char *path, + const char *function, + int line, + const std::string &message) : + m_reason(NULL), + m_path(path), + m_function(function), + m_line(line), + m_message(message) + { + AddRef(this); + } + + Exception(const char *path, + const char *function, + int line, + const Exception &reason, + const std::string &message) : + m_reason(new Exception(reason)), + m_path(path), + m_function(function), + m_line(line), + m_message(message) + { + AddRef(this); + } + + virtual ~Exception() throw() + { + if (m_reason != NULL) { + delete m_reason; + m_reason = NULL; + } + + UnRef(this); + } + + void Dump() const + { + // Show reason first + if (m_reason != NULL) { + m_reason->Dump(); + } + + // Afterward, dump exception + const char *file = strchr(m_path.c_str(), '/'); + + if (file == NULL) { + file = m_path.c_str(); + } else { + ++file; + } + + printf("\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", + file, m_line, + m_function.c_str(), + m_className.c_str(), + m_message.empty() ? "<EMPTY>" : m_message.c_str()); + } + + std::string DumpToString() const + { + std::string ret; + if (m_reason != NULL) { + ret = m_reason->DumpToString(); + } + + const char *file = strchr(m_path.c_str(), '/'); + + if (file == NULL) { + file = m_path.c_str(); + } else { + ++file; + } + + char buf[1024]; + snprintf(buf, + sizeof(buf), + "\033[0;36m[%s:%i]\033[m %s() \033[4;35m%s\033[m: %s\033[m\n", + file, + m_line, + m_function.c_str(), + m_className.c_str(), + m_message.empty() ? "<EMPTY>" : m_message.c_str()); + + buf[sizeof(buf) - 1] = '\n'; + ret += buf; + + return ret; + } + + Exception *GetReason() const + { + return m_reason; + } + + std::string GetPath() const + { + return m_path; + } + + std::string GetFunction() const + { + return m_function; + } + + int GetLine() const + { + return m_line; + } + + std::string GetMessage() const + { + return m_message; + } + + std::string GetClassName() const + { + return m_className; + } +}; +} // namespace CentralKeyManager + +#define Try try + +#define Throw(ClassName) \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__) + +#define ThrowMsg(ClassName, Message) \ + do \ + { \ + std::ostringstream dplLoggingStream; \ + dplLoggingStream << Message; \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__, dplLoggingStream.str()); \ + } while (0) + +#define ReThrow(ClassName) \ + throw ClassName(__FILE__, __FUNCTION__, __LINE__, _rethrown_exception) + +#define ReThrowMsg(ClassName, Message) \ + throw ClassName(__FILE__, \ + __FUNCTION__, \ + __LINE__, \ + _rethrown_exception, \ + Message) + +#define Catch(ClassName) \ + catch (const ClassName &_rethrown_exception) + +#define DECLARE_EXCEPTION_TYPE(BaseClass, Class) \ + class Class : \ + public BaseClass \ + { \ + public: \ + Class(const char *path, \ + const char *function, \ + int line, \ + const std::string & message = std::string()) : \ + BaseClass(path, function, line, message) \ + { \ + BaseClass::m_className = #Class; \ + } \ + \ + Class(const char *path, \ + const char *function, \ + int line, \ + const CentralKeyManager::Exception & reason, \ + const std::string & message = std::string()) : \ + BaseClass(path, function, line, reason, message) \ + { \ + BaseClass::m_className = #Class; \ + } \ + }; + +#define UNHANDLED_EXCEPTION_HANDLER_BEGIN try + +#define UNHANDLED_EXCEPTION_HANDLER_END \ + catch (const CentralKeyManager::Exception &exception) \ + { \ + std::ostringstream msg; \ + msg << CentralKeyManager::Exception::KnownExceptionToString(exception); \ + CentralKeyManager::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + catch (std::exception& e) \ + { \ + std::ostringstream msg; \ + msg << e.what(); \ + msg << "\n"; \ + msg << CentralKeyManager::Exception::UnknownExceptionToString(); \ + CentralKeyManager::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } \ + catch (...) \ + { \ + std::ostringstream msg; \ + msg << CentralKeyManager::Exception::UnknownExceptionToString(); \ + CentralKeyManager::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__); \ + abort(); \ + } + +namespace CentralKeyManager { +namespace CommonException { +/** + * Internal exception definitions + * + * These should normally not happen. + * Usually, exception trace with internal error includes + * important messages. + */ +DECLARE_EXCEPTION_TYPE(Exception, InternalError) ///< Unexpected error from + // underlying libraries or + // kernel +} +} + +#endif // CENT_KEY_EXCEPTION_H diff --git a/src/manager/dpl/core/include/dpl/fstream_accessors.h b/src/manager/dpl/core/include/dpl/fstream_accessors.h new file mode 100644 index 00000000..1f6b7a3a --- /dev/null +++ b/src/manager/dpl/core/include/dpl/fstream_accessors.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 fstream-helper.h + * @author Marek Smolinski (m.smolinski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of fstream-helper + * + */ + +#ifndef CENT_KEY_FSTREAM_ACCESSORS_H +#define CENT_KEY_FSTREAM_ACCESSORS_H + +namespace DPL { + +/* + * Bypass lack of public member function to get file + * descriptor from fstream objects in std + * This feature is needed for flushing data from kernel space buffer to + * physical device [fsync(int fd) - syscall] on opened fstream object +*/ + +template<typename T> +class FstreamAccessors : T::__filebuf_type { + typedef FstreamAccessors<T> MyType; +public: + static int GetFd(T &strm) { + return static_cast<MyType *>(strm.rdbuf())->_M_file.fd(); + } +}; + +} // namespace DPL + +#endif // CENT_KEY_FSTREAM_ACCESSORS_H diff --git a/src/manager/dpl/core/include/dpl/noncopyable.h b/src/manager/dpl/core/include/dpl/noncopyable.h new file mode 100644 index 00000000..5d006a35 --- /dev/null +++ b/src/manager/dpl/core/include/dpl/noncopyable.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 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 noncopyable + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of noncopyable + */ +#ifndef CENT_KEY_NONCOPYABLE_H +#define CENT_KEY_NONCOPYABLE_H + +namespace CentralKeyManager { +class Noncopyable +{ + private: + Noncopyable(const Noncopyable &); + const Noncopyable &operator=(const Noncopyable &); + + public: + Noncopyable(); + virtual ~Noncopyable(); +}; +} // namespace CentralKeyManager + +#endif // CENT_KEY_NONCOPYABLE_H diff --git a/src/manager/dpl/core/include/dpl/noreturn.h b/src/manager/dpl/core/include/dpl/noreturn.h new file mode 100644 index 00000000..b9b85e0a --- /dev/null +++ b/src/manager/dpl/core/include/dpl/noreturn.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 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 noreturn.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of noreturn + */ +#ifndef CENT_KEY_NORETURN_H +#define CENT_KEY_NORETURN_H + +#define CENT_KEY_NORETURN __attribute__((__noreturn__)) + +#endif // CENT_KEY_NORETURN_H diff --git a/src/manager/dpl/core/include/dpl/serialization.h b/src/manager/dpl/core/include/dpl/serialization.h new file mode 100644 index 00000000..7bd0bd22 --- /dev/null +++ b/src/manager/dpl/core/include/dpl/serialization.h @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2011 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. + */ +#ifndef CENT_KEY_SERIALIZATION_H +#define CENT_KEY_SERIALIZATION_H + +#include <string> +#include <vector> +#include <list> +#include <map> +#include <memory> + +namespace CentralKeyManager { +// 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 int + static void Serialize(IStream& stream, const unsigned value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream& stream, const unsigned* const value) + { + stream.Write(sizeof(*value), value); + } + + // int + static void Serialize(IStream& stream, const int value) + { + stream.Write(sizeof(value), &value); + } + static void Serialize(IStream& stream, const int* 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); + } + + // time_t + 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); + } + + // std::string + static void Serialize(IStream& stream, const std::string& str) + { + int length = str.size(); + stream.Write(sizeof(length), &length); + stream.Write(length, str.c_str()); + } + static void Serialize(IStream& stream, const std::string* const str) + { + int length = str->size(); + stream.Write(sizeof(length), &length); + stream.Write(length, str->c_str()); + } + + // STL templates + + // std::list + template <typename T> + static void Serialize(IStream& stream, const std::list<T>& list) + { + int length = list.size(); + stream.Write(sizeof(length), &length); + for (typename std::list<T>::const_iterator list_iter = list.begin(); + list_iter != list.end(); list_iter++) + { + Serialize(stream, *list_iter); + } + } + template <typename T> + static void Serialize(IStream& stream, const std::list<T>* const list) + { + Serialize(stream, *list); + } + + // std::vector + template <typename T> + static void Serialize(IStream& stream, const std::vector<T>& vec) + { + int length = vec.size(); + stream.Write(sizeof(length), &length); + for (typename std::vector<T>::const_iterator vec_iter = vec.begin(); + vec_iter != vec.end(); vec_iter++) + { + Serialize(stream, *vec_iter); + } + } + template <typename T> + static void Serialize(IStream& stream, const std::vector<T>* 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) + { + int length = map.size(); + stream.Write(sizeof(length), &length); + typename std::map<K, T>::const_iterator it; + for (it = map.begin(); it != map.end(); ++it) { + Serialize(stream, (*it).first); + Serialize(stream, (*it).second); + } + } + template <typename K, typename T> + static void Serialize(IStream& stream, const std::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); + } +}; // 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); + } + + // 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 int + static void Deserialize(IStream& stream, unsigned& value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream& stream, unsigned*& value) + { + value = new unsigned; + stream.Read(sizeof(*value), value); + } + + // int + static void Deserialize(IStream& stream, int& value) + { + stream.Read(sizeof(value), &value); + } + static void Deserialize(IStream& stream, int*& value) + { + value = new int; + 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); + } + + // time_t + 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); + } + + // 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; + } + 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; + } + + // 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); + } + + // std::vector + template <typename T> + static void Deserialize(IStream& stream, std::vector<T>& 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> + static void Deserialize(IStream& stream, std::vector<T>*& vec) + { + vec = new std::vector<T>; + 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); + } +}; // struct Deserialization +} // namespace CentralKeyManager + +#endif // CENT_KEY_SERIALIZATION_H diff --git a/src/manager/dpl/core/include/dpl/singleton.h b/src/manager/dpl/core/include/dpl/singleton.h new file mode 100644 index 00000000..ad6ff71b --- /dev/null +++ b/src/manager/dpl/core/include/dpl/singleton.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011 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 singleton.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#ifndef CENT_KEY_SINGLETON_H +#define CENT_KEY_SINGLETON_H + +namespace CentralKeyManager { +template<typename Class> +class Singleton : + private Class +{ + // + // Note: + // + // To remove posibility of instantiating directly Class, + // make Class' default constructor protected + // + + private: + Singleton() + {} + + static Singleton &InternalInstance(); + + public: + virtual ~Singleton() + {} + + static Class &Instance(); +}; +} // namespace CentralKeyManager + +#endif // CENT_KEY_SINGLETON_H diff --git a/src/manager/dpl/core/include/dpl/singleton_impl.h b/src/manager/dpl/core/include/dpl/singleton_impl.h new file mode 100644 index 00000000..da703254 --- /dev/null +++ b/src/manager/dpl/core/include/dpl/singleton_impl.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011 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 singleton_impl.h + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#ifndef CENT_KEY_SINGLETON_IMPL_H +#define CENT_KEY_SINGLETON_IMPL_H + +/* + * WARNING! + * + * If some singleton's implementation uses another singletons implementation, + * those templates make the second singleton a dubleton. Be warned. Try to use + * singleton_safe_impl.h if possible. + */ + +namespace CentralKeyManager { +template<typename Class> +Singleton<Class>& Singleton<Class>::InternalInstance() +{ + static Singleton<Class> instance; + return instance; +} + +template<typename Class> +Class &Singleton<Class>::Instance() +{ + Singleton<Class>& instance = Singleton<Class>::InternalInstance(); + return instance; +} +} // namespace CentralKeyManager + +#define IMPLEMENT_SINGLETON(Type) \ + template CentralKeyManager::Singleton<Type>&CentralKeyManager::Singleton<Type>::InternalInstance(); \ + template Type & CentralKeyManager::Singleton<Type>::Instance(); \ + +#endif // CENT_KEY_SINGLETON_IMPL_H diff --git a/src/manager/dpl/core/include/dpl/singleton_safe_impl.h b/src/manager/dpl/core/include/dpl/singleton_safe_impl.h new file mode 100644 index 00000000..6a502cbb --- /dev/null +++ b/src/manager/dpl/core/include/dpl/singleton_safe_impl.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011 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 singleton_safe_impl.h + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#ifndef CENT_KEY_SINGLETON_SAFE_IMPL_H +#define CENT_KEY_SINGLETON_SAFE_IMPL_H + +#define IMPLEMENT_SAFE_SINGLETON(Class) \ + namespace CentralKeyManager { \ + template<> \ + Singleton<Class>&Singleton<Class>::InternalInstance() \ + { \ + static Singleton<Class> instance; \ + return instance; \ + } \ + \ + template<> \ + Class & Singleton<Class>::Instance() \ + { \ + Singleton<Class>& instance = Singleton<Class>::InternalInstance(); \ + return instance; \ + } \ + \ + template Singleton<Class>&Singleton<Class>::InternalInstance(); \ + template Class & Singleton<Class>::Instance(); \ + } // namespace CentralKeyManager + +#endif // CENT_KEY_SINGLETON_SAFE_IMPL_H diff --git a/src/manager/dpl/core/src/assert.cpp b/src/manager/dpl/core/src/assert.cpp new file mode 100644 index 00000000..6ec7db30 --- /dev/null +++ b/src/manager/dpl/core/src/assert.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2011 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 assert.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of assert + */ +#include <stddef.h> +#include <dpl/assert.h> +#include <dpl/colors.h> +#include <dpl/log/log.h> +#include <dpl/exception.h> +#include <cstdlib> + +namespace CentralKeyManager { +void AssertProc(const char *condition, + const char *file, + int line, + const char *function) +{ +#define INTERNAL_LOG(message) \ + do \ + { \ + std::ostringstream platformLog; \ + platformLog << message; \ + CentralKeyManager::Log::LogSystemSingleton::Instance().Pedantic( \ + platformLog.str().c_str(), \ + __FILE__, __LINE__, __FUNCTION__); \ + } \ + while (0) + + // Try to log failed assertion to log system + Try + { + INTERNAL_LOG( + "################################################################################"); + INTERNAL_LOG( + "### CentralKeyManager assertion failed! ###"); + INTERNAL_LOG( + "################################################################################"); + INTERNAL_LOG("### Condition: " << condition); + INTERNAL_LOG("### File: " << file); + INTERNAL_LOG("### Line: " << line); + INTERNAL_LOG("### Function: " << function); + INTERNAL_LOG( + "################################################################################"); + } catch (Exception) { + // Just ignore possible double errors + } + + // Fail with c-library abort + abort(); +} +} // namespace CentralKeyManager diff --git a/src/manager/dpl/core/src/binary_queue.cpp b/src/manager/dpl/core/src/binary_queue.cpp new file mode 100644 index 00000000..ba0cf807 --- /dev/null +++ b/src/manager/dpl/core/src/binary_queue.cpp @@ -0,0 +1,317 @@ +/* + * Copyright (c) 2011 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) + * @version 1.0 + * @brief This file is the implementation file of binary queue + */ +#include <stddef.h> +#include <dpl/binary_queue.h> +#include <dpl/assert.h> +#include <algorithm> +#include <malloc.h> +#include <cstring> +#include <new> + +namespace CentralKeyManager { +BinaryQueue::BinaryQueue() : + m_size(0) +{} + +BinaryQueue::BinaryQueue(const BinaryQueue &other) : + m_size(0) +{ + AppendCopyFrom(other); +} + +BinaryQueue::~BinaryQueue() +{ + // Remove all remainig buckets + Clear(); +} + +const BinaryQueue &BinaryQueue::operator=(const BinaryQueue &other) +{ + if (this != &other) { + Clear(); + AppendCopyFrom(other); + } + + return *this; +} + +void BinaryQueue::AppendCopyFrom(const BinaryQueue &other) +{ + // To speed things up, always copy as one bucket + void *bufferCopy = malloc(other.m_size); + + if (bufferCopy == NULL) { + throw std::bad_alloc(); + } + + try { + other.Flatten(bufferCopy, other.m_size); + AppendUnmanaged(bufferCopy, other.m_size, &BufferDeleterFree, NULL); + } catch (const std::bad_alloc &) { + // Free allocated memory + free(bufferCopy); + throw; + } +} + +void BinaryQueue::AppendMoveFrom(BinaryQueue &other) +{ + // Copy all buckets + std::copy(other.m_buckets.begin(), + other.m_buckets.end(), std::back_inserter(m_buckets)); + m_size += other.m_size; + + // Clear other, but do not free memory + other.m_buckets.clear(); + other.m_size = 0; +} + +void BinaryQueue::AppendCopyTo(BinaryQueue &other) const +{ + other.AppendCopyFrom(*this); +} + +void BinaryQueue::AppendMoveTo(BinaryQueue &other) +{ + other.AppendMoveFrom(*this); +} + +void BinaryQueue::Clear() +{ + std::for_each(m_buckets.begin(), m_buckets.end(), &DeleteBucket); + m_buckets.clear(); + m_size = 0; +} + +void BinaryQueue::AppendCopy(const void* buffer, size_t bufferSize) +{ + // Create data copy with malloc/free + void *bufferCopy = malloc(bufferSize); + + // Check if allocation succeded + if (bufferCopy == NULL) { + throw std::bad_alloc(); + } + + // Copy user data + memcpy(bufferCopy, buffer, bufferSize); + + try { + // Try to append new bucket + AppendUnmanaged(bufferCopy, bufferSize, &BufferDeleterFree, NULL); + } catch (const std::bad_alloc &) { + // Free allocated memory + free(bufferCopy); + throw; + } +} + +void BinaryQueue::AppendUnmanaged(const void* buffer, + size_t bufferSize, + BufferDeleter deleter, + void* userParam) +{ + // Do not attach empty buckets + if (bufferSize == 0) { + deleter(buffer, bufferSize, userParam); + return; + } + + // Just add new bucket with selected deleter + Bucket *bucket = new Bucket(buffer, bufferSize, deleter, userParam); + try { + m_buckets.push_back(bucket); + } catch (const std::bad_alloc &) { + delete bucket; + throw; + } + + // Increase total queue size + m_size += bufferSize; +} + +size_t BinaryQueue::Size() const +{ + return m_size; +} + +bool BinaryQueue::Empty() const +{ + return m_size == 0; +} + +void BinaryQueue::Consume(size_t size) +{ + // Check parameters + if (size > m_size) { + Throw(Exception::OutOfData); + } + + size_t bytesLeft = size; + + // Consume data and/or remove buckets + while (bytesLeft > 0) { + // Get consume size + size_t count = std::min(bytesLeft, m_buckets.front()->left); + + m_buckets.front()->ptr = + static_cast<const char *>(m_buckets.front()->ptr) + count; + m_buckets.front()->left -= count; + bytesLeft -= count; + m_size -= count; + + if (m_buckets.front()->left == 0) { + DeleteBucket(m_buckets.front()); + m_buckets.pop_front(); + } + } +} + +void BinaryQueue::Flatten(void *buffer, size_t bufferSize) const +{ + // Check parameters + if (bufferSize == 0) { + return; + } + + if (bufferSize > m_size) { + Throw(Exception::OutOfData); + } + + size_t bytesLeft = bufferSize; + void *ptr = buffer; + BucketList::const_iterator bucketIterator = m_buckets.begin(); + Assert(m_buckets.end() != bucketIterator); + + // Flatten data + while (bytesLeft > 0) { + // Get consume size + size_t count = std::min(bytesLeft, (*bucketIterator)->left); + + // Copy data to user pointer + memcpy(ptr, (*bucketIterator)->ptr, count); + + // Update flattened bytes count + bytesLeft -= count; + ptr = static_cast<char *>(ptr) + count; + + // Take next bucket + ++bucketIterator; + } +} + +void BinaryQueue::FlattenConsume(void *buffer, size_t bufferSize) +{ + // FIXME: Optimize + Flatten(buffer, bufferSize); + Consume(bufferSize); +} + +void BinaryQueue::DeleteBucket(BinaryQueue::Bucket *bucket) +{ + delete bucket; +} + +void BinaryQueue::BufferDeleterFree(const void* data, + size_t dataSize, + void* userParam) +{ + (void)dataSize; + (void)userParam; + + // Default free deleter + free(const_cast<void *>(data)); +} + +BinaryQueue::Bucket::Bucket(const void* data, + size_t dataSize, + BufferDeleter dataDeleter, + void* userParam) : + buffer(data), + ptr(data), + size(dataSize), + left(dataSize), + deleter(dataDeleter), + param(userParam) +{ + Assert(data != NULL); + Assert(deleter != NULL); +} + +BinaryQueue::Bucket::~Bucket() +{ + // Invoke deleter on bucket data + deleter(buffer, size, param); +} + +BinaryQueue::BucketVisitor::~BucketVisitor() +{} + +BinaryQueue::BucketVisitorCall::BucketVisitorCall(BucketVisitor *visitor) : + m_visitor(visitor) +{} + +BinaryQueue::BucketVisitorCall::~BucketVisitorCall() +{} + +void BinaryQueue::BucketVisitorCall::operator()(Bucket *bucket) const +{ + m_visitor->OnVisitBucket(bucket->ptr, bucket->left); +} + +void BinaryQueue::VisitBuckets(BucketVisitor *visitor) const +{ + Assert(visitor != NULL); + + // Visit all buckets + std::for_each(m_buckets.begin(), m_buckets.end(), BucketVisitorCall(visitor)); +} + +BinaryQueueAutoPtr BinaryQueue::Read(size_t size) +{ + // Simulate input stream + size_t available = std::min(size, m_size); + + std::unique_ptr<void, std::function<void(void*)>> + bufferCopy(malloc(available), free); + + if (!bufferCopy.get()) { + throw std::bad_alloc(); + } + + BinaryQueueAutoPtr result(new BinaryQueue()); + + Flatten(bufferCopy.get(), available); + result->AppendUnmanaged( + bufferCopy.release(), available, &BufferDeleterFree, NULL); + Consume(available); + + return result; +} + +size_t BinaryQueue::Write(const BinaryQueue &buffer, size_t bufferSize) +{ + // Simulate output stream + AppendCopyFrom(buffer); + return bufferSize; +} +} // namespace CentralKeyManager diff --git a/src/manager/dpl/core/src/colors.cpp b/src/manager/dpl/core/src/colors.cpp new file mode 100644 index 00000000..c099a96d --- /dev/null +++ b/src/manager/dpl/core/src/colors.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2011 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 colors.cpp + * @author Lukasz Wrzosek (l.wrzosek@samsung.com) + * @version 1.0 + * @brief Some constants with definition of colors for Console + * and html output + */ +#include <stddef.h> +#include <dpl/colors.h> + +namespace CentralKeyManager { +namespace Colors { +namespace Text { +const char* BOLD_GREEN_BEGIN = "\033[1;32m"; +const char* BOLD_GREEN_END = "\033[m"; +const char* RED_BEGIN = "\033[0;31m"; +const char* RED_END = "\033[m"; +const char* PURPLE_BEGIN = "\033[0;35m"; +const char* PURPLE_END = "\033[m"; +const char* GREEN_BEGIN = "\033[0;32m"; +const char* GREEN_END = "\033[m"; +const char* CYAN_BEGIN = "\033[0;36m"; +const char* CYAN_END = "\033[m"; +const char* BOLD_RED_BEGIN = "\033[1;31m"; +const char* BOLD_RED_END = "\033[m"; +const char* BOLD_YELLOW_BEGIN = "\033[1;33m"; +const char* BOLD_YELLOW_END = "\033[m"; +const char* BOLD_GOLD_BEGIN = "\033[0;33m"; +const char* BOLD_GOLD_END = "\033[m"; +const char* BOLD_WHITE_BEGIN = "\033[1;37m"; +const char* BOLD_WHITE_END = "\033[m"; +} //namespace Text + +namespace Html { +const char* BOLD_GREEN_BEGIN = "<font color=\"green\"><b>"; +const char* BOLD_GREEN_END = "</b></font>"; +const char* PURPLE_BEGIN = "<font color=\"purple\"><b>"; +const char* PURPLE_END = "</b></font>"; +const char* RED_BEGIN = "<font color=\"red\"><b>"; +const char* RED_END = "</b></font>"; +const char* GREEN_BEGIN = "<font color=\"green\">"; +const char* GREEN_END = "</font>"; +const char* CYAN_BEGIN = "<font color=\"cyan\">"; +const char* CYAN_END = "</font>"; +const char* BOLD_RED_BEGIN = "<font color=\"red\"><b>"; +const char* BOLD_RED_END = "</b></font>"; +const char* BOLD_YELLOW_BEGIN = "<font color=\"yellow\"><b>"; +const char* BOLD_YELLOW_END = "</b></font>"; +const char* BOLD_GOLD_BEGIN = "<font color=\"gold\"><b>"; +const char* BOLD_GOLD_END = "</b></font>"; +const char* BOLD_WHITE_BEGIN = "<font color=\"white\"><b>"; +const char* BOLD_WHITE_END = "</b></font>"; +} //namespace Html +} //namespace Colors +} //namespace CentralKeyManager diff --git a/src/manager/dpl/core/src/exception.cpp b/src/manager/dpl/core/src/exception.cpp new file mode 100644 index 00000000..db45e8a8 --- /dev/null +++ b/src/manager/dpl/core/src/exception.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011 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 exception.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation of exception system + */ +#include <stddef.h> +#include <dpl/exception.h> +#include <dpl/log/log.h> +#include <cstdio> + +namespace CentralKeyManager { +Exception* Exception::m_lastException = NULL; +unsigned int Exception::m_exceptionCount = 0; +void (*Exception::m_terminateHandler)() = NULL; + +void LogUnhandledException(const std::string &str) +{ + // Logging to console + printf("%s\n", str.c_str()); + + // Logging to dlog + LogPedantic(str); +} + +void LogUnhandledException(const std::string &str, + const char *filename, + int line, + const char *function) +{ + // Logging to console + std::ostringstream msg; + msg << "\033[1;5;31m\n=== [" << filename << ":" << line << "] " << + function << " ===\033[m"; + msg << str; + printf("%s\n", msg.str().c_str()); + + // Logging to dlog + CentralKeyManager::Log::LogSystemSingleton::Instance().Error( + str.c_str(), filename, line, function); +} +} // namespace CentralKeyManager diff --git a/src/manager/dpl/core/src/noncopyable.cpp b/src/manager/dpl/core/src/noncopyable.cpp new file mode 100644 index 00000000..9e9c7239 --- /dev/null +++ b/src/manager/dpl/core/src/noncopyable.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 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 noncopyable.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of noncopyable + */ +#include <stddef.h> +#include <dpl/noncopyable.h> + +namespace CentralKeyManager { +Noncopyable::Noncopyable() +{} + +Noncopyable::~Noncopyable() +{} +} // namespace CentralKeyManager diff --git a/src/manager/dpl/core/src/serialization.cpp b/src/manager/dpl/core/src/serialization.cpp new file mode 100644 index 00000000..f8f05ff6 --- /dev/null +++ b/src/manager/dpl/core/src/serialization.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 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.cpp + * @author Tomasz Swierczek (t.swierczek@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of data serialization. + */ +#include <stddef.h> +#include <dpl/serialization.h> + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/src/manager/dpl/core/src/singleton.cpp b/src/manager/dpl/core/src/singleton.cpp new file mode 100644 index 00000000..a76e8ac3 --- /dev/null +++ b/src/manager/dpl/core/src/singleton.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 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 generic_event.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of singleton + */ +#include <stddef.h> +#include <dpl/singleton.h> + +// +// Note: +// +// The file here is left blank to enable precompilation +// of templates in corresponding header file. +// Do not remove this file. +// diff --git a/src/manager/dpl/log/include/dpl/log/abstract_log_provider.h b/src/manager/dpl/log/include/dpl/log/abstract_log_provider.h new file mode 100644 index 00000000..bcc7e5c2 --- /dev/null +++ b/src/manager/dpl/log/include/dpl/log/abstract_log_provider.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2011 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 abstract_log_provider.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract log provider + */ +#ifndef CENT_KEY_ABSTRACT_LOG_PROVIDER_H +#define CENT_KEY_ABSTRACT_LOG_PROVIDER_H + +namespace CentralKeyManager { +namespace Log { +class AbstractLogProvider +{ + public: + virtual ~AbstractLogProvider() {} + + virtual void SetTag(const char *tag); + + virtual void Debug(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void Info(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void Warning(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void Error(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void Pedantic(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void SecureDebug(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void SecureInfo(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void SecureWarning(const char *message, + const char *fileName, + int line, + const char *function) = 0; + virtual void SecureError(const char *message, + const char *fileName, + int line, + const char *function) = 0; + protected: + static const char *LocateSourceFileName(const char *filename); +}; +} +} // namespace CentralKeyManager + +#endif // CENT_KEY_ABSTRACT_LOG_PROVIDER_H diff --git a/src/manager/dpl/log/include/dpl/log/dlog_log_provider.h b/src/manager/dpl/log/include/dpl/log/dlog_log_provider.h new file mode 100644 index 00000000..da11b6e2 --- /dev/null +++ b/src/manager/dpl/log/include/dpl/log/dlog_log_provider.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2011 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 dlog_log_provider.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of DLOG log provider + */ +#ifndef CENT_KEY_DLOG_LOG_PROVIDER_H +#define CENT_KEY_DLOG_LOG_PROVIDER_H + +#include <dpl/log/abstract_log_provider.h> +#include <memory> +#include <string> + +namespace CentralKeyManager { +namespace Log { +class DLOGLogProvider : + public AbstractLogProvider +{ + private: + std::unique_ptr<char[]> m_tag; + + static std::string FormatMessage(const char *message, + const char *filename, + int line, + const char *function); + + public: + DLOGLogProvider(); + virtual ~DLOGLogProvider(); + + virtual void Debug(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Info(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Warning(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Error(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Pedantic(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureDebug(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureInfo(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureWarning(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureError(const char *message, + const char *fileName, + int line, + const char *function); + // Set global Tag according to DLOG + void SetTag(const char *tag); +}; + +} // namespace Log +} // namespace CentralKeyManager + +#endif // CENT_KEY_DLOG_LOG_PROVIDER_H diff --git a/src/manager/dpl/log/include/dpl/log/log.h b/src/manager/dpl/log/include/dpl/log/log.h new file mode 100644 index 00000000..3a3ed074 --- /dev/null +++ b/src/manager/dpl/log/include/dpl/log/log.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2011 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 log.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of log system + */ +#ifndef CENT_KEY_LOG_H +#define CENT_KEY_LOG_H + +#include <dpl/singleton.h> +#include <dpl/noncopyable.h> +#include <dpl/log/abstract_log_provider.h> +#include <sstream> +#include <list> + +namespace CentralKeyManager { +namespace Log { +/** + * CentralKeyManager log system + * + * To switch logs into old style, export + * DPL_USE_OLD_STYLE_LOGS before application start + */ +class LogSystem : + private Noncopyable +{ + private: + typedef std::list<AbstractLogProvider *> AbstractLogProviderPtrList; + AbstractLogProviderPtrList m_providers; + + bool m_isLoggingEnabled; + + public: + bool IsLoggingEnabled() const; + LogSystem(); + virtual ~LogSystem(); + + /** + * Log debug message + */ + void Debug(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log info message + */ + void Info(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log warning message + */ + void Warning(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log error message + */ + void Error(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log pedantic message + */ + void Pedantic(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log pedantic message with secure macro + */ + void SecureDebug(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log info message with secure macro + */ + void SecureInfo(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log warning message with secure macro + */ + void SecureWarning(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Log error message with secure macro + */ + void SecureError(const char *message, + const char *filename, + int line, + const char *function); + + /** + * Set default's DLOG provider Tag + */ + void SetTag(const char *tag); + + /** + * Add abstract provider to providers list + * + * @notice Ownership is transfered to LogSystem and deleted upon exit + */ + void AddProvider(AbstractLogProvider *provider); + + /** + * Remove abstract provider from providers list + */ + void RemoveProvider(AbstractLogProvider *provider); +}; + +/* + * Replacement low overhead null logging class + */ +class NullStream +{ + public: + NullStream() {} + + template <typename T> + NullStream& operator<<(const T&) + { + return *this; + } +}; + +/** + * Log system singleton + */ +typedef Singleton<LogSystem> LogSystemSingleton; +} +} // namespace CentralKeyManager + +// +// Log support +// +// + +/* avoid warnings about unused variables */ +#define DPL_MACRO_DUMMY_LOGGING(message, function) \ + do { \ + CentralKeyManager::Log::NullStream ns; \ + ns << message; \ + } while (0) + +#define DPL_MACRO_FOR_LOGGING(message, function) \ +do \ +{ \ + if (CentralKeyManager::Log::LogSystemSingleton::Instance().IsLoggingEnabled()) \ + { \ + std::ostringstream platformLog; \ + platformLog << message; \ + CentralKeyManager::Log::LogSystemSingleton::Instance().function( \ + platformLog.str().c_str(), \ + __FILE__, __LINE__, __FUNCTION__); \ + } \ +} while (0) + +/* Errors must be always logged. */ +#define LogError(message) DPL_MACRO_FOR_LOGGING(message, Error) +#define LogSecureError(message) DPL_MACRO_FOR_LOGGING(message, SecureError) + +#ifdef BUILD_TYPE_DEBUG + #define LogDebug(message) DPL_MACRO_FOR_LOGGING(message, Debug) + #define LogInfo(message) DPL_MACRO_FOR_LOGGING(message, Info) + #define LogWarning(message) DPL_MACRO_FOR_LOGGING(message, Warning) + #define LogPedantic(message) DPL_MACRO_FOR_LOGGING(message, Pedantic) + #define LogSecureDebug(message) DPL_MACRO_FOR_LOGGING(message, SecureDebug) + #define LogSecureInfo(message) DPL_MACRO_FOR_LOGGING(message, SecureInfo) + #define LogSecureWarning(message) DPL_MACRO_FOR_LOGGING(message, SecureWarning) +#else + #define LogDebug(message) DPL_MACRO_DUMMY_LOGGING(message, Debug) + #define LogInfo(message) DPL_MACRO_DUMMY_LOGGING(message, Info) + #define LogWarning(message) DPL_MACRO_DUMMY_LOGGING(message, Warning) + #define LogPedantic(message) DPL_MACRO_DUMMY_LOGGING(message, Pedantic) + #define LogSecureDebug(message) DPL_MACRO_DUMMY_LOGGING(message, SecureDebug) + #define LogSecureInfo(message) DPL_MACRO_DUMMY_LOGGING(message, SecureInfo) + #define LogSecureWarning(message) DPL_MACRO_DUMMY_LOGGING(message, SecureWarning) +#endif // BUILD_TYPE_DEBUG + +#endif // CENT_KEY_LOG_H diff --git a/src/manager/dpl/log/include/dpl/log/old_style_log_provider.h b/src/manager/dpl/log/include/dpl/log/old_style_log_provider.h new file mode 100644 index 00000000..59472ef4 --- /dev/null +++ b/src/manager/dpl/log/include/dpl/log/old_style_log_provider.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2011 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 old_style_log_provider.h + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of old style log provider + */ +#ifndef CENT_KEY_OLD_STYLE_LOG_PROVIDER_H +#define CENT_KEY_OLD_STYLE_LOG_PROVIDER_H + +#include <dpl/log/abstract_log_provider.h> +#include <string> + +namespace CentralKeyManager { +namespace Log { +class OldStyleLogProvider : + public AbstractLogProvider +{ + private: + bool m_showDebug; + bool m_showInfo; + bool m_showWarning; + bool m_showError; + bool m_showPedantic; + bool m_printStdErr; + + static std::string FormatMessage(const char *message, + const char *filename, + int line, + const char *function); + + public: + OldStyleLogProvider(bool showDebug, + bool showInfo, + bool showWarning, + bool showError, + bool showPedantic); + OldStyleLogProvider(bool showDebug, + bool showInfo, + bool showWarning, + bool showError, + bool showPedantic, + bool printStdErr); + virtual ~OldStyleLogProvider() {} + + virtual void Debug(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Info(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Warning(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Error(const char *message, + const char *fileName, + int line, + const char *function); + virtual void Pedantic(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureDebug(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureInfo(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureWarning(const char *message, + const char *fileName, + int line, + const char *function); + virtual void SecureError(const char *message, + const char *fileName, + int line, + const char *function); +}; +} +} // namespace CentralKeyManager + +#endif // CENT_KEY_OLD_STYLE_LOG_PROVIDER_H diff --git a/src/manager/dpl/log/src/abstract_log_provider.cpp b/src/manager/dpl/log/src/abstract_log_provider.cpp new file mode 100644 index 00000000..a08eaa7f --- /dev/null +++ b/src/manager/dpl/log/src/abstract_log_provider.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 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 abstract_log_provider.cpp + * @author Pawel Sikorski (p.sikorski@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of abstract log provider + */ +#include <stddef.h> +#include <dpl/log/abstract_log_provider.h> +#include <cstring> + +#define UNUSED __attribute__((unused)) + +namespace CentralKeyManager { +namespace Log { + +void AbstractLogProvider::SetTag(const char *tag UNUSED) {} + +const char *AbstractLogProvider::LocateSourceFileName(const char *filename) +{ + const char *ptr = strrchr(filename, '/'); + return ptr != NULL ? ptr + 1 : filename; +} +} +} diff --git a/src/manager/dpl/log/src/dlog_log_provider.cpp b/src/manager/dpl/log/src/dlog_log_provider.cpp new file mode 100644 index 00000000..9ce3d562 --- /dev/null +++ b/src/manager/dpl/log/src/dlog_log_provider.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2011 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 dlog_log_provider.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of DLOG log provider + */ +#include <stddef.h> +#include <dpl/log/dlog_log_provider.h> +#include <cstring> +#include <sstream> +#include <dlog.h> + +#define UNUSED __attribute__((unused)) + +namespace CentralKeyManager { +namespace Log { +std::string DLOGLogProvider::FormatMessage(const char *message, + const char *filename, + int line, + const char *function) +{ + std::ostringstream val; + + val << std::string("[") << + LocateSourceFileName(filename) << std::string(":") << line << + std::string("] ") << function << std::string("(): ") << message; + + return val.str(); +} + +DLOGLogProvider::DLOGLogProvider() +{} + +DLOGLogProvider::~DLOGLogProvider() +{} + +void DLOGLogProvider::SetTag(const char *tag) +{ + size_t size = strlen(tag)+1; + char *buff = new (std::nothrow) char[size]; + if (buff) + memcpy(buff, tag, size); + m_tag.reset(buff); +} + +void DLOGLogProvider::Debug(const char *message, + const char *filename, + int line, + const char *function) +{ + SLOG(LOG_DEBUG, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::Info(const char *message, + const char *filename, + int line, + const char *function) +{ + SLOG(LOG_INFO, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::Warning(const char *message, + const char *filename, + int line, + const char *function) +{ + SLOG(LOG_WARN, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::Error(const char *message, + const char *filename, + int line, + const char *function) +{ + SLOG(LOG_ERROR, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::Pedantic(const char *message, + const char *filename, + int line, + const char *function) +{ + SLOG(LOG_DEBUG, "CentralKeyManager", "%s", FormatMessage(message, + filename, + line, + function).c_str()); +} + +void DLOGLogProvider::SecureDebug(const char *message UNUSED, + const char *filename UNUSED, + int line UNUSED, + const char *function UNUSED) +{ + SECURE_SLOG(LOG_DEBUG, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::SecureInfo(const char *message UNUSED, + const char *filename UNUSED, + int line UNUSED, + const char *function UNUSED) +{ + SECURE_SLOG(LOG_INFO, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::SecureWarning(const char *message UNUSED, + const char *filename UNUSED, + int line UNUSED, + const char *function UNUSED) +{ + SECURE_SLOG(LOG_WARN, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +void DLOGLogProvider::SecureError(const char *message UNUSED, + const char *filename UNUSED, + int line UNUSED, + const char *function UNUSED) +{ + SECURE_SLOG(LOG_ERROR, m_tag.get(), "%s", + FormatMessage(message, filename, line, function).c_str()); +} + +} // nemespace Log +} // namespace CentralKeyManager diff --git a/src/manager/dpl/log/src/log.cpp b/src/manager/dpl/log/src/log.cpp new file mode 100644 index 00000000..16c73b3c --- /dev/null +++ b/src/manager/dpl/log/src/log.cpp @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2011 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 log.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of log system + */ +#include <stddef.h> +#include <string.h> + +#include <dpl/log/log.h> +#include <dpl/singleton_impl.h> +#include <dpl/log/dlog_log_provider.h> +#include <dpl/log/old_style_log_provider.h> + +IMPLEMENT_SINGLETON(CentralKeyManager::Log::LogSystem) + +namespace CentralKeyManager { +namespace Log { +namespace // anonymous +{ +#ifdef BUILD_TYPE_DEBUG +const char *OLD_STYLE_LOGS_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS"; +const char *OLD_STYLE_PEDANTIC_LOGS_ENV_NAME = + "DPL_USE_OLD_STYLE_PEDANTIC_LOGS"; +const char *OLD_STYLE_LOGS_MASK_ENV_NAME = "DPL_USE_OLD_STYLE_LOGS_MASK"; +#endif // BUILD_TYPE_DEBUG +const char *CENT_KEY_LOG_OFF = "DPL_LOG_OFF"; +} // namespace anonymous + +bool LogSystem::IsLoggingEnabled() const +{ + return m_isLoggingEnabled; +} + +LogSystem::LogSystem() : + m_isLoggingEnabled(!getenv(CENT_KEY_LOG_OFF)) +{ +#ifdef BUILD_TYPE_DEBUG + bool oldStyleLogs = false; + bool oldStyleDebugLogs = true; + bool oldStyleInfoLogs = true; + bool oldStyleWarningLogs = true; + bool oldStyleErrorLogs = true; + bool oldStylePedanticLogs = false; + + // Check environment settings about pedantic logs + const char *value = getenv(OLD_STYLE_LOGS_ENV_NAME); + + if (value != NULL && !strcmp(value, "1")) { + oldStyleLogs = true; + } + + value = getenv(OLD_STYLE_PEDANTIC_LOGS_ENV_NAME); + + if (value != NULL && !strcmp(value, "1")) { + oldStylePedanticLogs = true; + } + + value = getenv(OLD_STYLE_LOGS_MASK_ENV_NAME); + + if (value != NULL) { + size_t len = strlen(value); + + if (len >= 1) { + if (value[0] == '0') { + oldStyleDebugLogs = false; + } else if (value[0] == '1') { + oldStyleDebugLogs = true; + } + } + + if (len >= 2) { + if (value[1] == '0') { + oldStyleInfoLogs = false; + } else if (value[1] == '1') { + oldStyleInfoLogs = true; + } + } + + if (len >= 3) { + if (value[2] == '0') { + oldStyleWarningLogs = false; + } else if (value[2] == '1') { + oldStyleWarningLogs = true; + } + } + + if (len >= 4) { + if (value[3] == '0') { + oldStyleErrorLogs = false; + } else if (value[3] == '1') { + oldStyleErrorLogs = true; + } + } + } + + // Setup default DLOG and old style logging + if (oldStyleLogs) { + // Old style + AddProvider(new OldStyleLogProvider(oldStyleDebugLogs, + oldStyleInfoLogs, + oldStyleWarningLogs, + oldStyleErrorLogs, + oldStylePedanticLogs)); + } else { + // DLOG + AddProvider(new DLOGLogProvider()); + } +#else // BUILD_TYPE_DEBUG + AddProvider(new DLOGLogProvider()); +#endif // BUILD_TYPE_DEBUG +} + +LogSystem::~LogSystem() +{ + // Delete all providers + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + delete *iterator; + } + + m_providers.clear(); +} + +void LogSystem::SetTag(const char* tag) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->SetTag(tag); + } +} + +void LogSystem::AddProvider(AbstractLogProvider *provider) +{ + m_providers.push_back(provider); +} + +void LogSystem::RemoveProvider(AbstractLogProvider *provider) +{ + m_providers.remove(provider); +} + +void LogSystem::Debug(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Debug(message, filename, line, function); + } +} + +void LogSystem::Info(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Info(message, filename, line, function); + } +} + +void LogSystem::Warning(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Warning(message, filename, line, function); + } +} + +void LogSystem::Error(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Error(message, filename, line, function); + } +} + +void LogSystem::Pedantic(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->Pedantic(message, filename, line, function); + } +} + +void LogSystem::SecureInfo(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->SecureInfo(message, filename, line, function); + } +} + +void LogSystem::SecureDebug(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->SecureDebug(message, filename, line, function); + } +} + +void LogSystem::SecureError(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->SecureError(message, filename, line, function); + } +} + +void LogSystem::SecureWarning(const char *message, + const char *filename, + int line, + const char *function) +{ + for (AbstractLogProviderPtrList::iterator iterator = m_providers.begin(); + iterator != m_providers.end(); + ++iterator) + { + (*iterator)->SecureWarning(message, filename, line, function); + } +} + +} +} // namespace CentralKeyManager diff --git a/src/manager/dpl/log/src/old_style_log_provider.cpp b/src/manager/dpl/log/src/old_style_log_provider.cpp new file mode 100644 index 00000000..399d2885 --- /dev/null +++ b/src/manager/dpl/log/src/old_style_log_provider.cpp @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2011 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 old_style_log_provider.cpp + * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com) + * @version 1.0 + * @brief This file is the implementation file of old style log provider + */ +#include <stddef.h> +#include <dpl/log/old_style_log_provider.h> +#include <dpl/colors.h> +#include <cstdio> +#include <cstring> +#include <sstream> +#include <sys/time.h> +#include <unistd.h> +#include <dlog.h> + +namespace CentralKeyManager { +namespace Log { +namespace // anonymous +{ +using namespace CentralKeyManager::Colors::Text; +const char *DEBUG_BEGIN = GREEN_BEGIN; +const char *DEBUG_END = GREEN_END; +const char *INFO_BEGIN = CYAN_BEGIN; +const char *INFO_END = CYAN_END; +const char *ERROR_BEGIN = RED_BEGIN; +const char *ERROR_END = RED_END; +const char *WARNING_BEGIN = BOLD_GOLD_BEGIN; +const char *WARNING_END = BOLD_GOLD_END; +const char *PEDANTIC_BEGIN = PURPLE_BEGIN; +const char *PEDANTIC_END = PURPLE_END; + +std::string GetFormattedTime() +{ + timeval tv; + tm localNowTime; + + gettimeofday(&tv, NULL); + localtime_r(&tv.tv_sec, &localNowTime); + + char format[64]; + snprintf(format, + sizeof(format), + "%02i:%02i:%02i.%03i", + localNowTime.tm_hour, + localNowTime.tm_min, + localNowTime.tm_sec, + static_cast<int>(tv.tv_usec / 1000)); + return format; +} +} // namespace anonymous + +std::string OldStyleLogProvider::FormatMessage(const char *message, + const char *filename, + int line, + const char *function) +{ + std::ostringstream val; + + val << std::string("[") << GetFormattedTime() << std::string("] [") << + static_cast<unsigned long>(pthread_self()) << "/" << + static_cast<int>(getpid()) << std::string("] [") << + LocateSourceFileName(filename) << std::string(":") << line << + std::string("] ") << function << std::string("(): ") << message; + + return val.str(); +} + +OldStyleLogProvider::OldStyleLogProvider(bool showDebug, + bool showInfo, + bool showWarning, + bool showError, + bool showPedantic) : + m_showDebug(showDebug), + m_showInfo(showInfo), + m_showWarning(showWarning), + m_showError(showError), + m_showPedantic(showPedantic), + m_printStdErr(false) +{} + +OldStyleLogProvider::OldStyleLogProvider(bool showDebug, + bool showInfo, + bool showWarning, + bool showError, + bool showPedantic, + bool printStdErr) : + m_showDebug(showDebug), + m_showInfo(showInfo), + m_showWarning(showWarning), + m_showError(showError), + m_showPedantic(showPedantic), + m_printStdErr(printStdErr) +{} + +void OldStyleLogProvider::Debug(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showDebug) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", DEBUG_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), DEBUG_END); + } else { + fprintf(stdout, "%s%s%s\n", DEBUG_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), DEBUG_END); + } + } +} + +void OldStyleLogProvider::Info(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showInfo) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", INFO_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), INFO_END); + } else { + fprintf(stdout, "%s%s%s\n", INFO_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), INFO_END); + } + } +} + +void OldStyleLogProvider::Warning(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showWarning) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", WARNING_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), WARNING_END); + } else { + fprintf(stdout, "%s%s%s\n", WARNING_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), WARNING_END); + } + } +} + +void OldStyleLogProvider::Error(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showError) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", ERROR_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), ERROR_END); + } else { + fprintf(stdout, "%s%s%s\n", ERROR_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), ERROR_END); + } + } +} + +void OldStyleLogProvider::Pedantic(const char *message, + const char *filename, + int line, + const char *function) +{ + if (m_showPedantic) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", PEDANTIC_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), PEDANTIC_END); + } else { + fprintf(stdout, "%s%s%s\n", PEDANTIC_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), PEDANTIC_END); + } + } +} + +void OldStyleLogProvider::SecureDebug(const char *message, + const char *filename, + int line, + const char *function) +{ +#ifdef _SECURE_LOG + if (m_showDebug) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", DEBUG_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), DEBUG_END); + } else { + fprintf(stdout, "%s%s%s\n", DEBUG_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), DEBUG_END); + } + } +#else + (void)message; + (void)filename; + (void)line; + (void)function; +#endif +} + +void OldStyleLogProvider::SecureInfo(const char *message, + const char *filename, + int line, + const char *function) +{ +#ifdef _SECURE_LOG + if (m_showInfo) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", INFO_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), INFO_END); + } else { + fprintf(stdout, "%s%s%s\n", INFO_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), INFO_END); + } + } +#else + (void)message; + (void)filename; + (void)line; + (void)function; +#endif +} + +void OldStyleLogProvider::SecureWarning(const char *message, + const char *filename, + int line, + const char *function) +{ +#ifdef _SECURE_LOG + if (m_showWarning) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", WARNING_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), WARNING_END); + } else { + fprintf(stdout, "%s%s%s\n", WARNING_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), WARNING_END); + } + } +#else + (void)message; + (void)filename; + (void)line; + (void)function; +#endif +} + +void OldStyleLogProvider::SecureError(const char *message, + const char *filename, + int line, + const char *function) +{ +#ifdef _SECURE_LOG + if (m_showError) { + if (m_printStdErr) { + fprintf(stderr, "%s%s%s\n", ERROR_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), ERROR_END); + } else { + fprintf(stdout, "%s%s%s\n", ERROR_BEGIN, + FormatMessage(message, filename, line, + function).c_str(), ERROR_END); + } + } +#else + (void)message; + (void)filename; + (void)line; + (void)function; +#endif +} + +} +} // namespace CentralKeyManager diff --git a/src/manager/main/generic-event.h b/src/manager/main/generic-event.h new file mode 100644 index 00000000..ebb88ac2 --- /dev/null +++ b/src/manager/main/generic-event.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 protocols.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief Implementation of GenericEvent. + */ + +#ifndef _CENT_KEY_MNG_GENERIC_EVENT_ +#define _CENT_KEY_MNG_GENERIC_EVENT_ + +namespace CentralKeyManager { + +struct GenericEvent { + virtual ~GenericEvent(){} +}; + +} // namespace CentralKeyManager + +#endif // _CENT_KEY_MNG_GENERIC_EVENT_ diff --git a/src/manager/main/generic-socket-manager.cpp b/src/manager/main/generic-socket-manager.cpp new file mode 100644 index 00000000..abd23d9e --- /dev/null +++ b/src/manager/main/generic-socket-manager.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 generic-socket-manager.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief Implementation of GenericSocketService and GenericSocketManager. + */ + +#include <sys/socket.h> +#include <sys/types.h> + +#include <generic-socket-manager.h> + +namespace CentralKeyManager { + + +} // namespace CentralKeyManager + diff --git a/src/manager/main/generic-socket-manager.h b/src/manager/main/generic-socket-manager.h new file mode 100644 index 00000000..bf0dc6ae --- /dev/null +++ b/src/manager/main/generic-socket-manager.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 generic-socket-manager.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief Implementation of GenericSocketService and GenericSocketManager. + */ + +#ifndef _CENT_KEY_MNG_GENERIC_SERVICE_MANAGER_ +#define _CENT_KEY_MNG_GENERIC_SERVICE_MANAGER_ + +#include <vector> +#include <string> + +#include <dpl/exception.h> + +#include <generic-event.h> + +extern "C" { +struct msghdr; +} // extern "C" + +namespace CentralKeyManager { + +typedef int InterfaceID; + +struct ConnectionID { + int sock; // This is decriptor used for connection + int counter; // Unique handler per socket + inline bool operator<(const ConnectionID &second) const { + return counter < second.counter; + } +}; + +typedef std::vector<unsigned char> RawBuffer; + +struct GenericSocketManager; + +struct GenericSocketService { + typedef std::string SmackLabel; + typedef std::string ServiceHandlerPath; + struct ServiceDescription { + ServiceDescription(const char *path, + const char *smackLabel, + InterfaceID interfaceID = 0, + bool useSendMsg = false) + : smackLabel(smackLabel) + , interfaceID(interfaceID) + , serviceHandlerPath(path) + , useSendMsg(useSendMsg) + {} + + SmackLabel smackLabel; // Smack label for socket + InterfaceID interfaceID; // All data from serviceHandlerPath will be marked with this interfaceHandler + ServiceHandlerPath serviceHandlerPath; // Path to file + bool useSendMsg; + }; + + typedef std::vector<ServiceDescription> ServiceDescriptionVector; + + struct AcceptEvent : public GenericEvent { + ConnectionID connectionID; + InterfaceID interfaceID; + }; + + struct WriteEvent : public GenericEvent { + ConnectionID connectionID; + size_t size; + size_t left; + }; + + struct ReadEvent : public GenericEvent { + ConnectionID connectionID; + RawBuffer rawBuffer; + }; + + struct CloseEvent : public GenericEvent { + ConnectionID connectionID; + }; + + virtual void SetSocketManager(GenericSocketManager *manager) { + m_serviceManager = manager; + } + + virtual ServiceDescriptionVector GetServiceDescription() = 0; + virtual void Event(const AcceptEvent &event) = 0; + virtual void Event(const WriteEvent &event) = 0; + virtual void Event(const ReadEvent &event) = 0; + virtual void Event(const CloseEvent &event) = 0; + + GenericSocketService() : m_serviceManager(NULL) {} + virtual ~GenericSocketService(){} +protected: + GenericSocketManager *m_serviceManager; +}; + +struct GenericSocketManager { + virtual void MainLoop() = 0; + virtual void RegisterSocketService(GenericSocketService *ptr) = 0; + virtual void Close(ConnectionID connectionID) = 0; + virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer) = 0; + virtual ~GenericSocketManager(){} +}; + +} // namespace CentralKeyManager + +#endif // _CENT_KEY_MNG_GENERIC_SERVICE_MANAGER_ diff --git a/src/manager/main/key-manager-main.cpp b/src/manager/main/key-manager-main.cpp new file mode 100644 index 00000000..8964dd61 --- /dev/null +++ b/src/manager/main/key-manager-main.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 sever2-main.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief Implementation of security-server2 + */ +#include <stdlib.h> +#include <signal.h> + +#include <dpl/log/log.h> +#include <dpl/singleton.h> +#include <dpl/singleton_safe_impl.h> + +#include <socket-manager.h> + +IMPLEMENT_SAFE_SINGLETON(CentralKeyManager::Log::LogSystem); + +#define REGISTER_SOCKET_SERVICE(manager, service) \ + registerSocketService<service>(manager, #service) + +template<typename T> +void registerSocketService(CentralKeyManager::SocketManager &manager, const std::string& serviceName) +{ + T *service = NULL; + try { + service = new T(); + service->Create(); + manager.RegisterSocketService(service); + service = NULL; + } catch (const CentralKeyManager::Exception &exception) { + LogError("Error in creating service " << serviceName << + ", details:\n" << exception.DumpToString()); + } catch (const std::exception& e) { + LogError("Error in creating service " << serviceName << + ", details:\n" << e.what()); + } catch (...) { + LogError("Error in creating service " << serviceName << + ", unknown exception occured"); + } + if (service) + delete service; +} + +int main(void) { + + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + CentralKeyManager::Singleton<CentralKeyManager::Log::LogSystem>::Instance().SetTag("CENT_KEY_MNG"); + + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGTERM); + sigaddset(&mask, SIGPIPE); + if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL)) { + LogError("Error in pthread_sigmask"); + return 1; + } + + LogInfo("Start!"); + CentralKeyManager::SocketManager manager; + + manager.MainLoop(); + } + UNHANDLED_EXCEPTION_HANDLER_END + return 0; +} + diff --git a/src/manager/main/key-manager-util.cpp b/src/manager/main/key-manager-util.cpp new file mode 100644 index 00000000..8574b0b3 --- /dev/null +++ b/src/manager/main/key-manager-util.cpp @@ -0,0 +1,116 @@ +/* + * key-manager + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/smack.h> +#include <unistd.h> + +#include <limits> + +#include <key-manager-util.h> +#include <dpl/log/log.h> + +namespace { +const size_t SIZE_T_MAX = std::numeric_limits<size_t>::max(); +} // namespace anonymous + +namespace CentralKeyManager { + +int util_smack_label_is_valid(const char *smack_label) +{ + int i; + + if (!smack_label || smack_label[0] == '\0' || smack_label[0] == '-') + goto err; + + for (i = 0; smack_label[i]; ++i) { + if (i >= SMACK_LABEL_LEN) + return 0; + switch (smack_label[i]) { + case '~': + case ' ': + case '/': + case '"': + case '\\': + case '\'': + goto err; + default: + break; + } + } + + return 1; +err: + LogError("Invalid Smack label: " << (smack_label ? smack_label : "")); + return 0; +} + +char *read_exe_path_from_proc(pid_t pid) +{ + char link[32]; + char *exe = NULL; + size_t size = 64; + ssize_t cnt = 0; + + // get link to executable + snprintf(link, sizeof(link), "/proc/%d/exe", pid); + + for (;;) + { + exe = (char*) malloc(size); + if (exe == NULL) + { + LogError("Out of memory"); + return NULL; + } + + // read link target + cnt = readlink(link, exe, size); + + // error + if (cnt < 0 || (size_t) cnt > size) + { + LogError("Can't locate process binary for pid=" << pid); + free(exe); + return NULL; + } + + // read less than requested + if ((size_t) cnt < size) + break; + + // read exactly the number of bytes requested + free(exe); + if (size > (SIZE_T_MAX >> 1)) + { + LogError("Exe path too long (more than " << size << " characters)"); + return NULL; + } + size <<= 1; + } + // readlink does not append null byte to buffer. + exe[cnt] = '\0'; + return exe; +} + +} // namespace CentralKeyManager + diff --git a/src/manager/main/key-manager-util.h b/src/manager/main/key-manager-util.h new file mode 100644 index 00000000..d32d9327 --- /dev/null +++ b/src/manager/main/key-manager-util.h @@ -0,0 +1,34 @@ +/* + * Central Key Manager + * + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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 + * + */ + +#ifndef CENT_KEY_MNG_UTIL_H +#define CENT_KEY_MNG_UTIL_H + +#include <sys/types.h> + +namespace CentralKeyManager { + +int util_smack_label_is_valid(const char *smack_label); +char *read_exe_path_from_proc(pid_t pid); + +} // namespace CentralKeyManager + +#endif /*CENT_KEY_MNG_UTIL_H*/ diff --git a/src/manager/main/service-thread.h b/src/manager/main/service-thread.h new file mode 100644 index 00000000..0918c3dd --- /dev/null +++ b/src/manager/main/service-thread.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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-thread.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief Implementation of threads. + */ + +#ifndef _CENT_KEY_SERVICE_THREAD_ +#define _CENT_KEY_SERVICE_THREAD_ + +#include <cassert> +#include <queue> +#include <mutex> +#include <thread> +#include <memory> +#include <condition_variable> + +#include <cstdio> + +#include <dpl/exception.h> + +#include "generic-event.h" + +#define DEFINE_THREAD_EVENT(eventType) \ + void Event(const eventType &event) { \ + CentralKeyManager::ServiceThread<ParentClassName>:: \ + Event(event, \ + this, \ + &ParentClassName::EventInternal##eventType); \ + } \ + void EventInternal##eventType(const eventType &event) + +#define DECLARE_THREAD_EVENT(eventType, methodName) \ + void Event(const eventType &event) { \ + CentralKeyManager::ServiceThread<ParentClassName>:: \ + Event(event, \ + this, \ + &ParentClassName::methodName); \ + } + +namespace CentralKeyManager { + +template <class Service> +class ServiceThread { +public: + typedef Service ParentClassName; + enum class State { + NoThread, + Work, + }; + + ServiceThread() + : m_state(State::NoThread) + , m_quit(false) + {} + + void Create() { + assert(m_state == State::NoThread); + m_thread = std::thread(ThreadLoopStatic, this); + m_state = State::Work; + } + + void Join() { + assert(m_state != State::NoThread); + { + std::lock_guard<std::mutex> lock(m_eventQueueMutex); + m_quit = true; + m_waitCondition.notify_one(); + } + m_thread.join(); + m_state = State::NoThread; + } + + virtual ~ServiceThread() + { + if (m_state != State::NoThread) + Join(); + while (!m_eventQueue.empty()){ + auto front = m_eventQueue.front(); + delete front.eventPtr; + m_eventQueue.pop(); + } + } + + template <class T> + void Event(const T &event, + Service *servicePtr, + void (Service::*serviceFunction)(const T &)) + { + EventDescription description; + description.serviceFunctionPtr = + reinterpret_cast<void (Service::*)(void*)>(serviceFunction); + description.servicePtr = servicePtr; + description.eventFunctionPtr = &ServiceThread::EventCall<T>; + description.eventPtr = new T(event); + { + std::lock_guard<std::mutex> lock(m_eventQueueMutex); + m_eventQueue.push(description); + } + m_waitCondition.notify_one(); + } + +protected: + + struct EventDescription { + void (Service::*serviceFunctionPtr)(void *); + Service *servicePtr; + void (ServiceThread::*eventFunctionPtr)(const EventDescription &event); + GenericEvent* eventPtr; + }; + + template <class T> + void EventCall(const EventDescription &desc) { + auto fun = reinterpret_cast<void (Service::*)(const T&)>(desc.serviceFunctionPtr); + const T& eventLocale = *(static_cast<T*>(desc.eventPtr)); + (desc.servicePtr->*fun)(eventLocale); + } + + static void ThreadLoopStatic(ServiceThread *ptr) { + ptr->ThreadLoop(); + } + + void ThreadLoop(){ + for (;;) { + EventDescription description = {NULL, NULL, NULL, NULL}; + { + std::unique_lock<std::mutex> ulock(m_eventQueueMutex); + if (m_quit) + return; + if (!m_eventQueue.empty()) { + description = m_eventQueue.front(); + m_eventQueue.pop(); + } else { + m_waitCondition.wait(ulock); + } + } + + if (description.eventPtr != NULL) { + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + (this->*description.eventFunctionPtr)(description); + delete description.eventPtr; + } + UNHANDLED_EXCEPTION_HANDLER_END + } + } + } + + std::thread m_thread; + std::mutex m_eventQueueMutex; + std::queue<EventDescription> m_eventQueue; + std::condition_variable m_waitCondition; + + State m_state; + bool m_quit; +}; + +} // namespace CentralKeyManager + +#endif // _CENT_KEY_SERVICE_THREAD_ diff --git a/src/manager/main/socket-manager.cpp b/src/manager/main/socket-manager.cpp new file mode 100644 index 00000000..9b938f23 --- /dev/null +++ b/src/manager/main/socket-manager.cpp @@ -0,0 +1,640 @@ +/* + * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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-manager.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @version 1.0 + * @brief Implementation of SocketManager. + */ + +#include <set> + +#include <signal.h> +#include <sys/select.h> +#include <sys/signalfd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/smack.h> +#include <sys/un.h> +#include <sys/stat.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <errno.h> +#include <time.h> + +#include <systemd/sd-daemon.h> + +#include <dpl/log/log.h> +#include <dpl/assert.h> + +#include <smack-check.h> +#include <socket-manager.h> + +namespace { + +const time_t SOCKET_TIMEOUT = 20; + +} // namespace anonymous + +namespace CentralKeyManager { + +struct DummyService : public GenericSocketService { + ServiceDescriptionVector GetServiceDescription() { + return ServiceDescriptionVector(); + } + void Event(const AcceptEvent &event) { (void)event; } + void Event(const WriteEvent &event) { (void)event; } + void Event(const ReadEvent &event) { (void)event; } + void Event(const CloseEvent &event) { (void)event; } +}; + +struct SignalService : public GenericSocketService { + int GetDescriptor() { + LogInfo("set up"); + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGTERM); + if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL)) + return -1; + return signalfd(-1, &mask, 0); + } + + ServiceDescriptionVector GetServiceDescription() { + return ServiceDescriptionVector(); + } + + void Event(const AcceptEvent &event) { (void)event; } // not supported + void Event(const WriteEvent &event) { (void)event; } // not supported + void Event(const CloseEvent &event) { (void)event; } // not supported + + void Event(const ReadEvent &event) { + LogDebug("Get signal information"); + + if(sizeof(struct signalfd_siginfo) != event.rawBuffer.size()) { + LogError("Wrong size of signalfd_siginfo struct. Expected: " + << sizeof(signalfd_siginfo) << " Get: " + << event.rawBuffer.size()); + return; + } + + signalfd_siginfo *siginfo = (signalfd_siginfo*)(&(event.rawBuffer[0])); + + if (siginfo->ssi_signo == SIGTERM) { + LogInfo("Got signal: SIGTERM"); + static_cast<SocketManager*>(m_serviceManager)->MainLoopStop(); + return; + } + + LogInfo("This should not happend. Got signal: " << siginfo->ssi_signo); + } +}; + +SocketManager::SocketDescription& +SocketManager::CreateDefaultReadSocketDescription(int sock, bool timeout) +{ + if ((int)m_socketDescriptionVector.size() <= sock) + m_socketDescriptionVector.resize(sock+20); + + auto &desc = m_socketDescriptionVector[sock]; + desc.isListen = false; + desc.isOpen = true; + desc.interfaceID = 0; + desc.service = NULL; + desc.counter = ++m_counter; + + if (timeout) { + desc.timeout = time(NULL) + SOCKET_TIMEOUT; + if (false == desc.isTimeout) { + Timeout tm; + tm.time = desc.timeout; + tm.sock = sock; + m_timeoutQueue.push(tm); + } + } + + desc.isTimeout = timeout; + + FD_SET(sock, &m_readSet); + m_maxDesc = sock > m_maxDesc ? sock : m_maxDesc; + return desc; +} + +SocketManager::SocketManager() + : m_counter(0) +{ + FD_ZERO(&m_readSet); + FD_ZERO(&m_writeSet); + if (-1 == pipe(m_notifyMe)) { + int err = errno; + ThrowMsg(Exception::InitFailed, "Error in pipe: " << strerror(err)); + } + LogInfo("Pipe: Read desc: " << m_notifyMe[0] << " Write desc: " << m_notifyMe[1]); + + auto &desc = CreateDefaultReadSocketDescription(m_notifyMe[0], false); + desc.service = new DummyService; + + // std::thread bases on pthread so this should work fine + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGPIPE); + pthread_sigmask(SIG_BLOCK, &set, NULL); + + // add support for TERM signal (passed from systemd) + auto *signalService = new SignalService; + signalService->SetSocketManager(this); + int filefd = signalService->GetDescriptor(); + if (-1 == filefd) { + LogError("Error in SignalService.GetDescriptor()"); + delete signalService; + } else { + auto &desc2 = CreateDefaultReadSocketDescription(filefd, false); + desc2.service = signalService; + LogInfo("SignalService mounted on " << filefd << " descriptor"); + } +} + +SocketManager::~SocketManager() { + std::set<GenericSocketService*> serviceMap; + + // Find all services. Set is used to remove duplicates. + // In this implementation, services are not able to react in any way. + for (size_t i=0; i < m_socketDescriptionVector.size(); ++i) + if (m_socketDescriptionVector[i].isOpen) + serviceMap.insert(m_socketDescriptionVector[i].service); + + // Time to destroy all services. + for(auto it = serviceMap.begin(); it != serviceMap.end(); ++it) { + LogDebug("delete " << (void*)(*it)); + delete *it; + } + + for (size_t i = 0; i < m_socketDescriptionVector.size(); ++i) + if (m_socketDescriptionVector[i].isOpen) + close(i); + + // All socket except one were closed. Now pipe input must be closed. + close(m_notifyMe[1]); +} + +void SocketManager::ReadyForAccept(int sock) { + struct sockaddr_un clientAddr; + unsigned int clientLen = sizeof(clientAddr); + int client = accept4(sock, (struct sockaddr*) &clientAddr, &clientLen, SOCK_NONBLOCK); +// LogInfo("Accept on sock: " << sock << " Socket opended: " << client); + if (-1 == client) { + int err = errno; + LogDebug("Error in accept: " << strerror(err)); + return; + } + + auto &desc = CreateDefaultReadSocketDescription(client, true); + desc.interfaceID = m_socketDescriptionVector[sock].interfaceID; + desc.service = m_socketDescriptionVector[sock].service; + + GenericSocketService::AcceptEvent event; + event.connectionID.sock = client; + event.connectionID.counter = desc.counter; + event.interfaceID = desc.interfaceID; + desc.service->Event(event); +} + +void SocketManager::ReadyForRead(int sock) { + if (m_socketDescriptionVector[sock].isListen) { + ReadyForAccept(sock); + return; + } + + GenericSocketService::ReadEvent event; + event.connectionID.sock = sock; + event.connectionID.counter = m_socketDescriptionVector[sock].counter; + event.rawBuffer.resize(4096); + + auto &desc = m_socketDescriptionVector[sock]; + desc.timeout = time(NULL) + SOCKET_TIMEOUT; + + ssize_t size = read(sock, &event.rawBuffer[0], 4096); + + if (size == 0) { + CloseSocket(sock); + } else if (size >= 0) { + event.rawBuffer.resize(size); + desc.service->Event(event); + } else if (size == -1) { + int err = errno; + switch(err) { + case EAGAIN: + case EINTR: + break; + default: + LogDebug("Reading sock error: " << strerror(err)); + CloseSocket(sock); + } + } +} + +void SocketManager::ReadyForWriteBuffer(int sock) { + auto &desc = m_socketDescriptionVector[sock]; + size_t size = desc.rawBuffer.size(); + ssize_t result = write(sock, &desc.rawBuffer[0], size); + if (result == -1) { + int err = errno; + switch(err) { + case EAGAIN: + case EINTR: + // select will trigger write once again, nothing to do + break; + case EPIPE: + default: + LogDebug("Error during write: " << strerror(err)); + CloseSocket(sock); + break; + } + return; // We do not want to propagate error to next layer + } + + desc.rawBuffer.erase(desc.rawBuffer.begin(), desc.rawBuffer.begin()+result); + + desc.timeout = time(NULL) + SOCKET_TIMEOUT; + + if (desc.rawBuffer.empty()) + FD_CLR(sock, &m_writeSet); + + GenericSocketService::WriteEvent event; + event.connectionID.sock = sock; + event.connectionID.counter = desc.counter; + event.size = result; + event.left = desc.rawBuffer.size(); + + desc.service->Event(event); +} + +void SocketManager::ReadyForWrite(int sock) { + ReadyForWriteBuffer(sock); +} + +void SocketManager::MainLoop() { + // remove evironment values passed by systemd + // uncomment it after removing old security-server code + // sd_listen_fds(1); + + // Daemon is ready to work. + sd_notify(0, "READY=1"); + + m_working = true; + while(m_working) { + fd_set readSet = m_readSet; + fd_set writeSet = m_writeSet; + + timeval localTempTimeout; + timeval *ptrTimeout = &localTempTimeout; + + // I need to extract timeout from priority_queue. + // Timeout in priority_queue may be deprecated. + // I need to find some actual one. + while(!m_timeoutQueue.empty()) { + auto &top = m_timeoutQueue.top(); + auto &desc = m_socketDescriptionVector[top.sock]; + + if (top.time == desc.timeout) { + // This timeout matches timeout from socket. + // It can be used. + break; + } else { + // This socket was used after timeout in priority queue was set up. + // We need to update timeout and find some useable one. + Timeout tm = { desc.timeout , top.sock}; + m_timeoutQueue.pop(); + m_timeoutQueue.push(tm); + } + } + + if (m_timeoutQueue.empty()) { + LogDebug("No usaable timeout found."); + ptrTimeout = NULL; // select will wait without timeout + } else { + time_t currentTime = time(NULL); + auto &pqTimeout = m_timeoutQueue.top(); + + // 0 means that select won't block and socket will be closed ;-) + ptrTimeout->tv_sec = + currentTime < pqTimeout.time ? pqTimeout.time - currentTime : 0; + ptrTimeout->tv_usec = 0; +// LogDebug("Set up timeout: " << (int)ptrTimeout->tv_sec +// << " seconds. Socket: " << pqTimeout.sock); + } + + int ret = select(m_maxDesc+1, &readSet, &writeSet, NULL, ptrTimeout); + + if (0 == ret) { // timeout + Assert(!m_timeoutQueue.empty()); + + Timeout pqTimeout = m_timeoutQueue.top(); + m_timeoutQueue.pop(); + + auto &desc = m_socketDescriptionVector[pqTimeout.sock]; + + if (!desc.isTimeout || !desc.isOpen) { + // Connection was closed. Timeout is useless... + desc.isTimeout = false; + continue; + } + + if (pqTimeout.time < desc.timeout) { + // Is it possible? + // This socket was used after timeout. We need to update timeout. + pqTimeout.time = desc.timeout; + m_timeoutQueue.push(pqTimeout); + continue; + } + + // timeout from m_timeoutQueue matches with socket.timeout + // and connection is open. Time to close it! + // Putting new timeout in queue here is pointless. + desc.isTimeout = false; + CloseSocket(pqTimeout.sock); + + // All done. Now we should process next select ;-) + continue; + } + + if (-1 == ret) { + switch(errno) { + case EINTR: + LogDebug("EINTR in select"); + break; + default: + int err = errno; + LogError("Error in select: " << strerror(err)); + return; + } + continue; + } + for(int i = 0; i<m_maxDesc+1 && ret; ++i) { + if (FD_ISSET(i, &readSet)) { + ReadyForRead(i); + --ret; + } + if (FD_ISSET(i, &writeSet)) { + ReadyForWrite(i); + --ret; + } + } + ProcessQueue(); + } +} + +void SocketManager::MainLoopStop() +{ + m_working = false; + NotifyMe(); +} + +int SocketManager::GetSocketFromSystemD( + const GenericSocketService::ServiceDescription &desc) +{ + int fd; + + // TODO optimalization - do it once in object constructor + // and remember all information path->sockfd + int n = sd_listen_fds(0); + + LogInfo("sd_listen_fds returns: " << n); + + if (n < 0) { + LogError("Error in sd_listend_fds"); + ThrowMsg(Exception::InitFailed, "Error in sd_listend_fds"); + } + + for(fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) { + if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1, + desc.serviceHandlerPath.c_str(), 0)) + { + LogInfo("Useable socket " << desc.serviceHandlerPath << + " was passed by SystemD under descriptor " << fd); + return fd; + } + } + LogInfo("No useable sockets were passed by systemd."); + return -1; +} + +int SocketManager::CreateDomainSocketHelp( + const GenericSocketService::ServiceDescription &desc) +{ + int sockfd; + + if (-1 == (sockfd = socket(AF_UNIX, SOCK_STREAM, 0))) { + int err = errno; + LogError("Error in socket: " << strerror(err)); + ThrowMsg(Exception::InitFailed, "Error in socket: " << strerror(err)); + } + + if (smack_check()) { + LogInfo("Set up smack label: " << desc.smackLabel); + + if (0 != smack_fsetlabel(sockfd, desc.smackLabel.c_str(), SMACK_LABEL_IPIN)) { + LogError("Error in smack_fsetlabel"); + ThrowMsg(Exception::InitFailed, "Error in smack_fsetlabel"); + } + } else { + LogInfo("No smack on platform. Socket won't be securied with smack label!"); + } + + int flags; + if (-1 == (flags = fcntl(sockfd, F_GETFL, 0))) + flags = 0; + + if (-1 == fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)) { + int err = errno; + close(sockfd); + LogError("Error in fcntl: " << strerror(err)); + ThrowMsg(Exception::InitFailed, "Error in fcntl: " << strerror(err)); + } + + sockaddr_un serverAddress; + memset(&serverAddress, 0, sizeof(serverAddress)); + serverAddress.sun_family = AF_UNIX; + strcpy(serverAddress.sun_path, desc.serviceHandlerPath.c_str()); + unlink(serverAddress.sun_path); + + mode_t originalUmask; + originalUmask = umask(0); + + if (-1 == bind(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress))) { + int err = errno; + close(sockfd); + LogError("Error in bind: " << strerror(err)); + ThrowMsg(Exception::InitFailed, "Error in bind: " << strerror(err)); + } + + umask(originalUmask); + + if (-1 == listen(sockfd, 5)) { + int err = errno; + close(sockfd); + LogError("Error in listen: " << strerror(err)); + ThrowMsg(Exception::InitFailed, "Error in listen: " << strerror(err)); + } + + return sockfd; +} + +void SocketManager::CreateDomainSocket( + GenericSocketService *service, + const GenericSocketService::ServiceDescription &desc) +{ + int sockfd = GetSocketFromSystemD(desc); + if (-1 == sockfd) + sockfd = CreateDomainSocketHelp(desc); + + auto &description = CreateDefaultReadSocketDescription(sockfd, false); + + description.isListen = true; + description.interfaceID = desc.interfaceID; + description.service = service; + + LogDebug("Listen on socket: " << sockfd << + " Handler: " << desc.serviceHandlerPath.c_str()); +} + +void SocketManager::RegisterSocketService(GenericSocketService *service) { + service->SetSocketManager(this); + auto serviceVector = service->GetServiceDescription(); + Try { + for (auto iter = serviceVector.begin(); iter != serviceVector.end(); ++iter) + CreateDomainSocket(service, *iter); + } Catch (Exception::Base) { + for (int i =0; i < (int)m_socketDescriptionVector.size(); ++i) + { + auto &desc = m_socketDescriptionVector[i]; + if (desc.service == service && desc.isOpen) { + close(i); + desc.isOpen = false; + } + } + ReThrow(Exception::Base); + } +} + +void SocketManager::Close(ConnectionID connectionID) { + { + std::lock_guard<std::mutex> ulock(m_eventQueueMutex); + m_closeQueue.push(connectionID); + } + NotifyMe(); +} + +void SocketManager::Write(ConnectionID connectionID, const RawBuffer &rawBuffer) { + WriteBuffer buffer; + buffer.connectionID = connectionID; + buffer.rawBuffer = rawBuffer; + { + std::lock_guard<std::mutex> ulock(m_eventQueueMutex); + m_writeBufferQueue.push(buffer); + } + NotifyMe(); +} + +void SocketManager::NotifyMe() { + TEMP_FAILURE_RETRY(write(m_notifyMe[1], "You have message ;-)", 1)); +} + +void SocketManager::ProcessQueue() { + WriteBuffer buffer; + { + std::lock_guard<std::mutex> ulock(m_eventQueueMutex); + while (!m_writeBufferQueue.empty()) { + buffer = m_writeBufferQueue.front(); + m_writeBufferQueue.pop(); + + auto &desc = m_socketDescriptionVector[buffer.connectionID.sock]; + + if (!desc.isOpen) { + LogDebug("Received packet for write but connection is closed. Packet ignored!"); + continue; + } + + if (desc.counter != buffer.connectionID.counter) + { + LogDebug("Received packet for write but counter is broken. Packet ignored!"); + continue; + } + + std::copy( + buffer.rawBuffer.begin(), + buffer.rawBuffer.end(), + std::back_inserter(desc.rawBuffer)); + + FD_SET(buffer.connectionID.sock, &m_writeSet); + } + + } + + while (1) { + ConnectionID connection; + { + std::lock_guard<std::mutex> ulock(m_eventQueueMutex); + if (m_closeQueue.empty()) + return; + connection = m_closeQueue.front(); + m_closeQueue.pop(); + } + + if (!m_socketDescriptionVector[connection.sock].isOpen) + continue; + + if (connection.counter != m_socketDescriptionVector[connection.sock].counter) + continue; + + CloseSocket(connection.sock); + } +} + +void SocketManager::CloseSocket(int sock) { +// LogInfo("Closing socket: " << sock); + auto &desc = m_socketDescriptionVector[sock]; + + if (!(desc.isOpen)) { + // This may happend when some information was waiting for write to the + // socket and in the same time socket was closed by the client. + LogError("Socket " << sock << " is not open. Nothing to do!"); + return; + } + + GenericSocketService::CloseEvent event; + event.connectionID.sock = sock; + event.connectionID.counter = desc.counter; + auto service = desc.service; + + desc.isOpen = false; + desc.service = NULL; + desc.interfaceID = -1; + desc.rawBuffer.clear(); + + if (service) + service->Event(event); + else + LogError("Critical! Service is NULL! This should never happend!"); + + TEMP_FAILURE_RETRY(close(sock)); + FD_CLR(sock, &m_readSet); + FD_CLR(sock, &m_writeSet); +} + +} // namespace CentralKeyManager diff --git a/src/manager/main/socket-manager.h b/src/manager/main/socket-manager.h new file mode 100644 index 00000000..8fae0a86 --- /dev/null +++ b/src/manager/main/socket-manager.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Bumjin Im <bj.im@samsung.com> + * + * 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-manager.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Zofia Abramowska (z.abramowska@samsung.com) + * @version 1.0 + * @brief SocketManager implementation. + */ + +#ifndef _CENT_KEY_MNG_SOCKET_MANAGER_ +#define _CENT_KEY_MNG_SOCKET_MANAGER_ + +#include <vector> +#include <queue> +#include <string> +#include <mutex> +#include <thread> + +#include <dpl/exception.h> + +#include <generic-socket-manager.h> + +namespace CentralKeyManager { + +class SocketManager : public GenericSocketManager { +public: + class Exception { + public: + DECLARE_EXCEPTION_TYPE(CentralKeyManager::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InitFailed) + }; + SocketManager(); + virtual ~SocketManager(); + virtual void MainLoop(); + virtual void MainLoopStop(); + + virtual void RegisterSocketService(GenericSocketService *service); + virtual void Close(ConnectionID connectionID); + virtual void Write(ConnectionID connectionID, const RawBuffer &rawBuffer); + +protected: + void CreateDomainSocket( + GenericSocketService *service, + const GenericSocketService::ServiceDescription &desc); + int CreateDomainSocketHelp( + const GenericSocketService::ServiceDescription &desc); + int GetSocketFromSystemD( + const GenericSocketService::ServiceDescription &desc); + + void ReadyForRead(int sock); + void ReadyForWrite(int sock); + void ReadyForWriteBuffer(int sock); + void ReadyForSendMsg(int sock); + void ReadyForAccept(int sock); + void ProcessQueue(void); + void NotifyMe(void); + void CloseSocket(int sock); + + struct SocketDescription { + bool isListen; + bool isOpen; + bool isTimeout; + InterfaceID interfaceID; + GenericSocketService *service; + time_t timeout; + RawBuffer rawBuffer; + int counter; + + SocketDescription() + : isListen(false) + , isOpen(false) + , isTimeout(false) + , interfaceID(-1) + , service(NULL) + {} + }; + + SocketDescription& CreateDefaultReadSocketDescription(int sock, bool timeout); + + typedef std::vector<SocketDescription> SocketDescriptionVector; + + struct WriteBuffer { + ConnectionID connectionID; + RawBuffer rawBuffer; + }; + + struct Timeout { + time_t time; + int sock; + bool operator<(const Timeout &second) const { + return time > second.time; // mininum first! + } + }; + + SocketDescriptionVector m_socketDescriptionVector; + fd_set m_readSet; + fd_set m_writeSet; + int m_maxDesc; + bool m_working; + std::mutex m_eventQueueMutex; + std::queue<WriteBuffer> m_writeBufferQueue; + std::queue<ConnectionID> m_closeQueue; + int m_notifyMe[2]; + int m_counter; + std::priority_queue<Timeout> m_timeoutQueue; +}; + +} // namespace CentralKeyManager + +#endif // _CENT_KEY_MNG_SOCKET_MANAGER_ diff --git a/systemd/CMakeLists.txt b/systemd/CMakeLists.txt new file mode 100644 index 00000000..85339816 --- /dev/null +++ b/systemd/CMakeLists.txt @@ -0,0 +1,7 @@ +INSTALL(FILES + ${CMAKE_SOURCE_DIR}/systemd/key-manager.service + ${CMAKE_SOURCE_DIR}/systemd/key-manager.target + DESTINATION + /usr/lib/systemd/system +) + diff --git a/systemd/key-manager.service b/systemd/key-manager.service new file mode 100644 index 00000000..d6d1381a --- /dev/null +++ b/systemd/key-manager.service @@ -0,0 +1,9 @@ +[Unit] +Description=Start the Central Key Manager + +[Service] +Type=notify +ExecStart=/usr/bin/key-manager + +[Install] +WantedBy=multi-user.target diff --git a/systemd/key-manager.target b/systemd/key-manager.target new file mode 100644 index 00000000..5e66e417 --- /dev/null +++ b/systemd/key-manager.target @@ -0,0 +1,4 @@ +[Unit] +Description=Cert Key Manager sockets +DefaultDependencies=true + |