Implement authentication service 40/59840/2
authorjooseong.lee <jooseong.lee@samsung.com>
Fri, 19 Feb 2016 02:56:25 +0000 (11:56 +0900)
committerjooseong.lee <jooseong.lee@samsung.com>
Fri, 19 Feb 2016 05:49:00 +0000 (14:49 +0900)
* Authentication-server (password check/set/recovery)
* Authentication-server-admin (password reset)
* Authenticate each user via password

Change-Id: I8c524fe1bce8df4aa68c0ca28f2c19f96e8bb6fb
Signed-off-by: jooseong.lee <jooseong.lee@samsung.com>
85 files changed:
AUTHORS [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
README [new file with mode: 0644]
packaging/authentication-server.manifest [new file with mode: 0644]
packaging/authentication-server.spec [new file with mode: 0644]
packaging/libauthentication-server-client-admin.manifest [new file with mode: 0644]
packaging/libauthentication-server-client.manifest [new file with mode: 0644]
pkgconfig/CMakeLists.txt [new file with mode: 0644]
pkgconfig/authentication-server-admin.pc.in [new file with mode: 0644]
pkgconfig/authentication-server.pc.in [new file with mode: 0644]
src/CMakeLists.txt [new file with mode: 0644]
src/client/CMakeLists.txt [new file with mode: 0644]
src/client/client-common.cpp [new file with mode: 0644]
src/client/client-password-admin.cpp [new file with mode: 0644]
src/client/client-password.cpp [new file with mode: 0644]
src/client/include/client-common.h [new file with mode: 0644]
src/common/CMakeLists.txt [new file with mode: 0644]
src/common/error-description.cpp [new file with mode: 0644]
src/common/include/connection-info.h [new file with mode: 0644]
src/common/include/error-description.h [new file with mode: 0644]
src/common/include/message-buffer.h [new file with mode: 0644]
src/common/include/policy.h [new file with mode: 0644]
src/common/include/protocols.h [new file with mode: 0644]
src/common/include/smack-check.h [new file with mode: 0644]
src/common/include/user-check.h [new file with mode: 0644]
src/common/message-buffer.cpp [new file with mode: 0644]
src/common/protocols.cpp [new file with mode: 0644]
src/common/smack-check.cpp [new file with mode: 0644]
src/common/user-check.cpp [new file with mode: 0644]
src/dpl/core/include/dpl/assert.h [new file with mode: 0644]
src/dpl/core/include/dpl/binary_queue.h [new file with mode: 0644]
src/dpl/core/include/dpl/colors.h [new file with mode: 0644]
src/dpl/core/include/dpl/exception.h [new file with mode: 0644]
src/dpl/core/include/dpl/fstream_accessors.h [new file with mode: 0644]
src/dpl/core/include/dpl/noncopyable.h [new file with mode: 0644]
src/dpl/core/include/dpl/noreturn.h [new file with mode: 0644]
src/dpl/core/include/dpl/serialization.h [new file with mode: 0644]
src/dpl/core/include/dpl/singleton.h [new file with mode: 0644]
src/dpl/core/include/dpl/singleton_impl.h [new file with mode: 0644]
src/dpl/core/include/dpl/singleton_safe_impl.h [new file with mode: 0644]
src/dpl/core/src/assert.cpp [new file with mode: 0644]
src/dpl/core/src/binary_queue.cpp [new file with mode: 0644]
src/dpl/core/src/colors.cpp [new file with mode: 0644]
src/dpl/core/src/exception.cpp [new file with mode: 0644]
src/dpl/core/src/noncopyable.cpp [new file with mode: 0644]
src/dpl/core/src/serialization.cpp [new file with mode: 0644]
src/dpl/core/src/singleton.cpp [new file with mode: 0644]
src/dpl/log/include/dpl/log/abstract_log_provider.h [new file with mode: 0644]
src/dpl/log/include/dpl/log/dlog_log_provider.h [new file with mode: 0644]
src/dpl/log/include/dpl/log/log.h [new file with mode: 0644]
src/dpl/log/include/dpl/log/old_style_log_provider.h [new file with mode: 0644]
src/dpl/log/src/abstract_log_provider.cpp [new file with mode: 0644]
src/dpl/log/src/dlog_log_provider.cpp [new file with mode: 0644]
src/dpl/log/src/log.cpp [new file with mode: 0644]
src/dpl/log/src/old_style_log_provider.cpp [new file with mode: 0644]
src/include/CMakeLists.txt [new file with mode: 0644]
src/include/auth-passwd-admin.h [new file with mode: 0644]
src/include/auth-passwd-error.h [new file with mode: 0644]
src/include/auth-passwd-policy-types.h [new file with mode: 0644]
src/include/auth-passwd.h [new file with mode: 0644]
src/server/CMakeLists.txt [new file with mode: 0644]
src/server/main/generic-socket-manager.cpp [new file with mode: 0644]
src/server/main/include/generic-event.h [new file with mode: 0644]
src/server/main/include/generic-socket-manager.h [new file with mode: 0644]
src/server/main/include/service-thread.h [new file with mode: 0644]
src/server/main/include/socket-manager.h [new file with mode: 0644]
src/server/main/server-main.cpp [new file with mode: 0644]
src/server/main/socket-manager.cpp [new file with mode: 0644]
src/server/service/include/password-exception.h [new file with mode: 0644]
src/server/service/include/password-file-buffer.h [new file with mode: 0644]
src/server/service/include/password-file.h [new file with mode: 0644]
src/server/service/include/password-manager.h [new file with mode: 0644]
src/server/service/include/password.h [new file with mode: 0644]
src/server/service/password-file-buffer.cpp [new file with mode: 0644]
src/server/service/password-file.cpp [new file with mode: 0644]
src/server/service/password-manager.cpp [new file with mode: 0644]
src/server/service/password.cpp [new file with mode: 0644]
systemd/CMakeLists.txt [new file with mode: 0644]
systemd/authentication-server-passwd-check.socket [new file with mode: 0644]
systemd/authentication-server-passwd-policy.socket [new file with mode: 0644]
systemd/authentication-server-passwd-reset.socket [new file with mode: 0644]
systemd/authentication-server-passwd-set.socket [new file with mode: 0644]
systemd/authentication-server.service [new file with mode: 0644]
systemd/authentication-server.target [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..a6c868e
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Jooseong Lee <jooseong.lee@samsung.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b05761b
--- /dev/null
@@ -0,0 +1,74 @@
+# Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+#
+# @file        CMakeLists.txt
+# @author
+# @brief
+#
+############################# Check minimum CMake version #####################
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT("auth-fw")
+
+############################# cmake packages ##################################
+
+INCLUDE(FindPkgConfig)
+
+############################# compiler flags ##################################
+
+SET(CMAKE_C_FLAGS_PROFILING    "-g -O0 -pg -Wp,-U_FORTIFY_SOURCE")
+SET(CMAKE_CXX_FLAGS_PROFILING  "-g -std=c++0x -O0 -pg -Wp,-U_FORTIFY_SOURCE")
+SET(CMAKE_C_FLAGS_DEBUG        "-g -O0 -ggdb -Wp,-U_FORTIFY_SOURCE")
+SET(CMAKE_CXX_FLAGS_DEBUG      "-g -std=c++0x -O0 -ggdb -Wp,-U_FORTIFY_SOURCE")
+SET(CMAKE_C_FLAGS_RELEASE      "-g -O2")
+SET(CMAKE_CXX_FLAGS_RELEASE    "-g -std=c++0x -O2")
+SET(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")
+ADD_DEFINITIONS("-DTIZEN_VERSION=${TIZEN_VERSION}")
+ADD_DEFINITIONS("-DDLOG_WARN_ENABLED")
+ADD_DEFINITIONS("-DDLOG_ERROR_ENABLED")
+SET(CACHE_DIR  \"/opt/data/privilege-control-cache\")
+ADD_DEFINITIONS("-DCACHE_DIR=${CACHE_DIR}")
+
+IF (CMAKE_BUILD_TYPE MATCHES "DEBUG")
+    ADD_DEFINITIONS("-DBUILD_TYPE_DEBUG")
+    ADD_DEFINITIONS("-DDLOG_DEBUG_ENABLED")
+ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG")
+
+INSTALL(FILES
+    ${CMAKE_SOURCE_DIR}/packaging/authentication-server.manifest
+    ${CMAKE_SOURCE_DIR}/packaging/libauthentication-server-client.manifest
+    ${CMAKE_SOURCE_DIR}/packaging/libauthentication-server-client-admin.manifest
+    DESTINATION
+    /usr/share
+)
+
+ADD_SUBDIRECTORY(src)
+ADD_SUBDIRECTORY(pkgconfig)
+ADD_SUBDIRECTORY(systemd)
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..247c97d
--- /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.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..4c3eb5d
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+README for authentication server project
diff --git a/packaging/authentication-server.manifest b/packaging/authentication-server.manifest
new file mode 100644 (file)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
diff --git a/packaging/authentication-server.spec b/packaging/authentication-server.spec
new file mode 100644 (file)
index 0000000..0ddd2b0
--- /dev/null
@@ -0,0 +1,164 @@
+Name:       authentication-server
+Summary:    Authentication server
+Version:    0.0.1
+Release:    1
+Group:      System/Security
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+BuildRequires: cmake
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(openssl)
+BuildRequires: pkgconfig(libsmack)
+BuildRequires: pkgconfig(libsystemd-daemon)
+BuildRequires: pkgconfig(libtzplatform-config)
+%{?systemd_requires}
+
+%description
+Authentication server with client libraries
+
+%package -n libauthentication-server-client
+Summary:    Authentication server (client)
+Group:      Development/Libraries
+Requires:   authentication-server = %{version}-%{release}
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description -n libauthentication-server-client
+Authentication server package (client)
+
+%package -n libauthentication-server-client-admin
+Summary:    Authentication server (client-admin)
+Group:      Development/Libraries
+Requires:   authentication-server = %{version}-%{release}
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description -n libauthentication-server-client-admin
+Authentication server package (client-admin)
+
+%package -n libauthentication-server-client-devel
+Summary:    Authentication server (client-devel)
+Group:      Development/Libraries
+Requires:   libauthentication-server-client = %{version}-%{release}
+Requires:   libauthentication-server-client-admin = %{version}-%{release}
+
+%description -n libauthentication-server-client-devel
+Authentication server package (client-devel)
+
+%package -n authentication-server-devel
+Summary:    Authentication (Development)
+Group:      Development/Libraries
+Requires:   authentication-server = %{version}-%{release}
+
+%description -n authentication-server-devel
+Authentication server package (Development)
+
+%prep
+%setup -q
+
+%build
+
+export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE"
+export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE"
+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/libauthentication-server-client
+cp LICENSE %{buildroot}/usr/share/license/libauthentication-server-client-admin
+%make_install
+
+mkdir -p %{buildroot}/usr/lib/systemd/system/multi-user.target.wants
+mkdir -p %{buildroot}/usr/lib/systemd/system/sockets.target.wants
+mkdir -p %{buildroot}/usr/lib/systemd/system/basic.target.wants
+ln -s ../authentication-server.service %{buildroot}/usr/lib/systemd/system/multi-user.target.wants/authentication-server.service
+ln -s ../authentication-server-passwd-check.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/authentication-server-passwd-check.socket
+ln -s ../authentication-server-passwd-set.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/authentication-server-passwd-set.socket
+ln -s ../authentication-server-passwd-reset.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/authentication-server-passwd-reset.socket
+ln -s ../authentication-server-passwd-policy.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/authentication-server-passwd-policy.socket
+
+%clean
+rm -rf %{buildroot}
+
+%post
+systemctl daemon-reload
+if [ $1 = 1 ]; then
+    # installation
+    systemctl start authentication-server.service
+fi
+
+if [ $1 = 2 ]; then
+    # update
+    systemctl restart authentication-server.service
+fi
+
+%preun
+if [ $1 = 0 ]; then
+    # unistall
+    systemctl stop authentication-server.service
+fi
+
+%postun
+if [ $1 = 0 ]; then
+    # unistall
+    systemctl daemon-reload
+fi
+
+%post -n libauthentication-server-client -p /sbin/ldconfig
+
+%postun -n libauthentication-server-client -p /sbin/ldconfig
+
+%post -n libauthentication-server-client-admin -p /sbin/ldconfig
+
+%postun -n libauthentication-server-client-admin -p /sbin/ldconfig
+
+%files -n authentication-server
+%manifest %{_datadir}/authentication-server.manifest
+%attr(755,root,root) /usr/bin/authentication-server
+%{_libdir}/libauthentication-server-commons.so.*
+%attr(-,root,root) /usr/lib/systemd/system/multi-user.target.wants/authentication-server.service
+%attr(-,root,root) /usr/lib/systemd/system/authentication-server.service
+%attr(-,root,root) /usr/lib/systemd/system/authentication-server.target
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/authentication-server-passwd-check.socket
+%attr(-,root,root) /usr/lib/systemd/system/authentication-server-passwd-check.socket
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/authentication-server-passwd-set.socket
+%attr(-,root,root) /usr/lib/systemd/system/authentication-server-passwd-set.socket
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/authentication-server-passwd-reset.socket
+%attr(-,root,root) /usr/lib/systemd/system/authentication-server-passwd-reset.socket
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/authentication-server-passwd-policy.socket
+%attr(-,root,root) /usr/lib/systemd/system/authentication-server-passwd-policy.socket
+
+%{_datadir}/license/%{name}
+
+%files -n libauthentication-server-client
+%manifest %{_datadir}/libauthentication-server-client.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libauthentication-server-client.so.*
+%{_datadir}/license/libauthentication-server-client
+
+%files -n libauthentication-server-client-admin
+%manifest %{_datadir}/libauthentication-server-client-admin.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libauthentication-server-client-admin.so.*
+%{_datadir}/license/libauthentication-server-client-admin
+
+%files -n libauthentication-server-client-devel
+%defattr(-,root,root,-)
+%{_libdir}/libauthentication-server-client.so
+%{_libdir}/libauthentication-server-client-admin.so
+%{_libdir}/libauthentication-server-commons.so
+/usr/include/authentication-server/auth-passwd.h
+/usr/include/authentication-server/auth-passwd-admin.h
+/usr/include/authentication-server/auth-passwd-error.h
+/usr/include/authentication-server/auth-passwd-policy-types.h
+%{_libdir}/pkgconfig/*.pc
+
diff --git a/packaging/libauthentication-server-client-admin.manifest b/packaging/libauthentication-server-client-admin.manifest
new file mode 100644 (file)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
diff --git a/packaging/libauthentication-server-client.manifest b/packaging/libauthentication-server-client.manifest
new file mode 100644 (file)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
diff --git a/pkgconfig/CMakeLists.txt b/pkgconfig/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a3ef112
--- /dev/null
@@ -0,0 +1,28 @@
+# 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      Jooseong Lee (jooseong.lee@samsung.com)
+# @brief
+#
+
+CONFIGURE_FILE(authentication-server.pc.in authentication-server.pc @ONLY)
+CONFIGURE_FILE(authentication-server-admin.pc.in authentication-server-admin.pc @ONLY)
+
+INSTALL(FILES
+    ${CMAKE_BINARY_DIR}/pkgconfig/authentication-server.pc
+    ${CMAKE_BINARY_DIR}/pkgconfig/authentication-server-admin.pc
+    DESTINATION
+    ${LIB_INSTALL_DIR}/pkgconfig
+    )
diff --git a/pkgconfig/authentication-server-admin.pc.in b/pkgconfig/authentication-server-admin.pc.in
new file mode 100644 (file)
index 0000000..b10e320
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=@LIB_INSTALL_DIR@
+includedir=${prefix}/include
+
+Name: authentication-server-admin
+Description: Authentication server admin
+Version: 1.0.1
+Requires:
+Libs: -L${libdir} -lauthentication-server-client-admin -lauthentication-server-commons
+Cflags: -I${includedir}/authentication-server
diff --git a/pkgconfig/authentication-server.pc.in b/pkgconfig/authentication-server.pc.in
new file mode 100644 (file)
index 0000000..da2e4e9
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=${prefix}
+libdir=@LIB_INSTALL_DIR@
+includedir=${prefix}/include
+
+Name: authentication-server
+Description: Authentication server
+Version: 1.0.1
+Requires:
+Libs: -L${libdir} -lauthentication-server-client -lauthentication-server-commons
+Cflags: -I${includedir}/authentication-server
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0319df7
--- /dev/null
@@ -0,0 +1,16 @@
+SET(INCLUDE_PATH ${PROJECT_SOURCE_DIR}/src/include)
+SET(COMMON_PATH  ${PROJECT_SOURCE_DIR}/src/common)
+SET(CLIENT_PATH  ${PROJECT_SOURCE_DIR}/src/client)
+SET(SERVER_PATH  ${PROJECT_SOURCE_DIR}/src/server)
+SET(PLUGIN_PATH  ${PROJECT_SOURCE_DIR}/src/plugin)
+SET(DPL_PATH     ${PROJECT_SOURCE_DIR}/src/dpl)
+
+SET(TARGET_SERVER "authentication-server")
+SET(TARGET_CLIENT "authentication-server-client")
+SET(TARGET_CLIENT_ADMIN "authentication-server-client-admin")
+SET(TARGET_COMMON "authentication-server-commons")
+
+ADD_SUBDIRECTORY(include)
+ADD_SUBDIRECTORY(common)
+ADD_SUBDIRECTORY(client)
+ADD_SUBDIRECTORY(server)
diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt
new file mode 100644 (file)
index 0000000..31a4bf9
--- /dev/null
@@ -0,0 +1,62 @@
+SET(AUTH_CLIENT_VERSION_MAJOR 1)
+SET(AUTH_CLIENT_VERSION ${AUTH_CLIENT_VERSION_MAJOR}.0.1)
+
+INCLUDE_DIRECTORIES(
+    ${INCLUDE_PATH}
+    ${COMMON_PATH}/include
+    ${CLIENT_PATH}/include
+    ${DPL_PATH}/core/include
+    ${DPL_PATH}/log/include
+    )
+
+SET(CLIENT_SOURCES
+    ${CLIENT_PATH}/client-common.cpp
+    ${CLIENT_PATH}/client-password.cpp
+    )
+
+ADD_LIBRARY(${TARGET_CLIENT} SHARED ${CLIENT_SOURCES})
+
+SET_TARGET_PROPERTIES(
+    ${TARGET_CLIENT}
+    PROPERTIES
+        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=hidden" 
+        SOVERSION ${AUTH_CLIENT_VERSION_MAJOR}
+        VERSION ${AUTH_CLIENT_VERSION}
+    )
+
+TARGET_LINK_LIBRARIES(${TARGET_CLIENT}
+    ${TARGET_COMMON}
+    )
+
+INSTALL(TARGETS ${TARGET_CLIENT} DESTINATION ${LIB_INSTALL_DIR})
+
+################################################################################
+
+INCLUDE_DIRECTORIES(
+    ${INCLUDE_PATH}
+    ${COMMON_PATH}/include
+    ${CLIENT_PATH}/include
+    ${DPL_PATH}/core/include
+    ${DPL_PATH}/log/include
+    )
+
+SET(CLIENT_ADMIN_SOURCES
+    ${CLIENT_PATH}/client-common.cpp
+    ${CLIENT_PATH}/client-password-admin.cpp
+    )
+
+ADD_LIBRARY(${TARGET_CLIENT_ADMIN} SHARED ${CLIENT_ADMIN_SOURCES})
+
+SET_TARGET_PROPERTIES(
+    ${TARGET_CLIENT_ADMIN}
+    PROPERTIES
+        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=hidden" 
+        SOVERSION ${AUTH_CLIENT_VERSION_MAJOR}
+        VERSION ${AUTH_CLIENT_VERSION}
+    )
+
+TARGET_LINK_LIBRARIES(${TARGET_CLIENT_ADMIN}
+    ${TARGET_COMMON}
+    )
+
+INSTALL(TARGETS ${TARGET_CLIENT_ADMIN} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/src/client/client-common.cpp b/src/client/client-common.cpp
new file mode 100644 (file)
index 0000000..ff811ce
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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)
+ * @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 <error-description.h>
+#include <message-buffer.h>
+#include <auth-passwd.h>
+#include <auth-passwd-admin.h>
+#include <client-common.h>
+
+IMPLEMENT_SAFE_SINGLETON(AuthPasswd::Log::LogSystem);
+
+namespace {
+
+const int POLL_TIMEOUT = 300000;
+
+void authPasswdClientEnableLogSystem(void) {
+    AuthPasswd::Singleton<AuthPasswd::Log::LogSystem>::Instance().SetTag("AUTH_PASSWD_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: " << AuthPasswd::errnoToString(err));
+    }
+    return retval;
+}
+
+} // namespace anonymous
+
+namespace AuthPasswd {
+
+
+int SockRAII::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: " << AuthPasswd::errnoToString(err));
+        return AUTH_PASSWD_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: " << AuthPasswd::errnoToString(err));
+        return AUTH_PASSWD_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 AUTH_PASSWD_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, POLLOUT, POLL_TIMEOUT)) {
+            LogError("Error in waitForSocket.");
+            return AUTH_PASSWD_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: " << AuthPasswd::errnoToString(err));
+            return AUTH_PASSWD_API_ERROR_SOCKET;
+        }
+
+        if (error == EACCES) {
+            LogError("Access denied");
+            return AUTH_PASSWD_API_ERROR_ACCESS_DENIED;
+        }
+
+        if (error != 0) {
+            LogError("Error in connect: " << AuthPasswd::errnoToString(error));
+            return AUTH_PASSWD_API_ERROR_SOCKET;
+        }
+
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+
+    if (-1 == retval) {
+        int err = errno;
+        LogError("Error connecting socket: " << AuthPasswd::errnoToString(err));
+        if (err == EACCES)
+            return AUTH_PASSWD_API_ERROR_ACCESS_DENIED;
+        return AUTH_PASSWD_API_ERROR_SOCKET;
+    }
+
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+int sendToServerWithFd(int fd, const RawBuffer &send, MessageBuffer &recv) {
+    ssize_t done = 0;
+    char buffer[2048];
+    while ((send.size() - done) > 0) {
+        if (0 >= waitForSocket(fd, POLLOUT, POLL_TIMEOUT)) {
+            LogError("Error in poll(POLLOUT)");
+            return AUTH_PASSWD_API_ERROR_SOCKET;
+        }
+        ssize_t temp = TEMP_FAILURE_RETRY(::send(fd, &send[done], send.size() - done, MSG_NOSIGNAL));
+        if (-1 == temp) {
+            int err = errno;
+            LogError("Error in send: " << errnoToString(err));
+            return AUTH_PASSWD_API_ERROR_SOCKET;
+        }
+        done += temp;
+    }
+
+    do {
+        if (0 >= waitForSocket(fd, POLLIN, POLL_TIMEOUT)) {
+            LogError("Error in poll(POLLIN)");
+            return AUTH_PASSWD_API_ERROR_SOCKET;
+        }
+        ssize_t temp = TEMP_FAILURE_RETRY(::recv(fd, buffer, 2048, 0));
+        if (-1 == temp) {
+            int err = errno;
+            LogError("Error in recv: " << errnoToString(err));
+            return AUTH_PASSWD_API_ERROR_SOCKET;
+        }
+
+        if (0 == temp) {
+            LogError("Read return 0/Connection closed by server(?)");
+            return AUTH_PASSWD_API_ERROR_SOCKET;
+        }
+
+        RawBuffer raw(buffer, buffer+temp);
+        recv.Push(raw);
+    } while(!recv.Ready());
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) {
+    int ret;
+    SockRAII sock;
+
+    if (AUTH_PASSWD_API_SUCCESS != (ret = sock.Connect(interface))) {
+        LogError("Error in SockRAII");
+        return ret;
+    }
+
+    return sendToServerWithFd(sock.Get(), send, recv);
+}
+
+int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) {
+    int ret;
+    SockRAII sock;
+    ssize_t done = 0;
+
+    if (AUTH_PASSWD_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 AUTH_PASSWD_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: " << errnoToString(err));
+            return AUTH_PASSWD_API_ERROR_SOCKET;
+        }
+        done += temp;
+    }
+
+    if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
+        LogError("Error in poll(POLLIN)");
+        return AUTH_PASSWD_API_ERROR_SOCKET;
+    }
+
+    ssize_t temp = TEMP_FAILURE_RETRY(recvmsg(sock.Get(), &hdr, MSG_CMSG_CLOEXEC));
+
+    if (temp < 0) {
+        int err = errno;
+        LogError("Error in recvmsg(): " << errnoToString(err) << " errno: " << err);
+        return AUTH_PASSWD_API_ERROR_SOCKET;
+    }
+
+    if (0 == temp) {
+        LogError("Read return 0/Connection closed by server(?)");
+        return AUTH_PASSWD_API_ERROR_SOCKET;
+    }
+
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+int try_catch(const std::function<int()>& func)
+{
+    try {
+        return func();
+    } catch (MessageBuffer::Exception::Base &e) {
+        LogError("AuthPasswd::MessageBuffer::Exception " << e.DumpToString());
+    } catch (std::bad_alloc &e) {
+        LogError("Memory allocation failed " << e.what());
+        return AUTH_PASSWD_API_ERROR_OUT_OF_MEMORY;
+    } catch (std::exception &e) {
+        LogError("STD exception " << e.what());
+    } catch (...) {
+        LogError("Unknown exception occured");
+    }
+    return AUTH_PASSWD_API_ERROR_UNKNOWN;
+}
+
+} // namespace AuthPasswd
+
+static void init_lib(void) __attribute__ ((constructor));
+static void init_lib(void)
+{
+    authPasswdClientEnableLogSystem();
+}
+
+static void fini_lib(void) __attribute__ ((destructor));
+static void fini_lib(void)
+{
+
+}
+
diff --git a/src/client/client-password-admin.cpp b/src/client/client-password-admin.cpp
new file mode 100644 (file)
index 0000000..8a4dcbf
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ *  Copyright (c) 2016 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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-password-admin.cpp
+ * @author      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       This file contains implementation of password functions.
+ */
+
+#include <cstring>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <message-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+#include <policy.h>
+
+#include <auth-passwd-admin.h>
+
+namespace {
+
+const char *NO_PASSWORD = "";
+
+inline bool isPasswordIncorrect(const char* pwd)
+{
+    // NULL means that password must be cancelled.
+    return (pwd && (strlen(pwd) == 0 || strlen(pwd) > AuthPasswd::MAX_PASSWORD_LEN));
+}
+
+} // namespace anonymous
+
+AUTH_PASSWD_API
+int auth_passwd_reset_passwd(const password_type passwd_type,
+                             const uid_t uid,
+                             const char *new_passwd)
+{
+    using namespace AuthPasswd;
+
+    return try_catch([&] {
+        if (isPasswordIncorrect(new_passwd)) {
+            LogError("Wrong input param.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        if (!new_passwd) {
+            new_passwd = NO_PASSWORD;
+        }
+
+        MessageBuffer send, recv;
+
+        Serialization::Serialize(send, static_cast<int>(PasswordHdrs::HDR_RST_PASSWD));
+        Serialization::Serialize(send, passwd_type);
+        Serialization::Serialize(send, uid);
+        Serialization::Serialize(send, std::string(new_passwd));
+
+        int retCode = sendToServer(SERVICE_SOCKET_PASSWD_RESET, send.Pop(), recv);
+        if (AUTH_PASSWD_API_SUCCESS != retCode) {
+            LogError("Error in sendToServer. Error code: " << retCode);
+            return retCode;
+        }
+
+        Deserialization::Deserialize(recv, retCode);
+
+        return retCode;
+    });
+}
+
+AUTH_PASSWD_API
+int auth_passwd_new_policy(policy_h **pp_policy)
+{
+    if (!pp_policy)
+        return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+    try {
+        *pp_policy = new policy_h;
+
+    } catch (std::bad_alloc& ex) {
+        return AUTH_PASSWD_API_ERROR_OUT_OF_MEMORY;
+    }
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_user(policy_h *p_policy, const uid_t uid)
+{
+    if (!p_policy)
+        return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+    p_policy->uid = uid;
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_max_attempts(policy_h *p_policy, const unsigned int max_attempts)
+{
+    if (!p_policy)
+        return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+    p_policy->maxAttempts = max_attempts;
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_validity(policy_h *p_policy, const unsigned int valid_days)
+{
+    if (!p_policy)
+        return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+    p_policy->validPeriod = valid_days;
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_history_size(policy_h *p_policy, const unsigned int history_size)
+{
+    if (!p_policy)
+        return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+    p_policy->historySize = history_size;
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_min_length(policy_h *p_policy, const unsigned int min_length)
+{
+    if (!p_policy)
+        return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+    p_policy->minLength = min_length;
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_quality(policy_h *p_policy, password_quality_type quality_type)
+{
+    if (!p_policy)
+        return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+    p_policy->qualityType = quality_type;
+    return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_policy(policy_h *p_policy)
+{
+    using namespace AuthPasswd;
+
+    return try_catch([&] {
+        if (!p_policy) {
+            LogError("Wrong input param.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        MessageBuffer send, recv;
+
+        Serialization::Serialize(send, static_cast<int>(PasswordHdrs::HDR_SET_PASSWD_POLICY));
+        Serialization::Serialize(send, p_policy);
+
+        int retCode = sendToServer(SERVICE_SOCKET_PASSWD_POLICY, send.Pop(), recv);
+        if (AUTH_PASSWD_API_SUCCESS != retCode) {
+            LogError("Error in sendToServer. Error code: " << retCode);
+            return retCode;
+        }
+
+        Deserialization::Deserialize(recv, retCode);
+
+        return retCode;
+    });
+}
+
+AUTH_PASSWD_API
+void auth_passwd_free_policy(policy_h *p_policy)
+{
+    delete p_policy;
+}
diff --git a/src/client/client-password.cpp b/src/client/client-password.cpp
new file mode 100644 (file)
index 0000000..aad13c4
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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-password.cpp
+ * @author      Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @author      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       This file contains implementation of password functions.
+ */
+
+#include <cstring>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <message-buffer.h>
+#include <client-common.h>
+#include <policy.h>
+#include <protocols.h>
+
+#include <auth-passwd.h>
+
+namespace {
+
+const char *NO_PASSWORD = "";
+
+inline bool isPasswordIncorrect(const char* passwd)
+{
+    // NULL means that password must be cancelled.
+    return (passwd && (strlen(passwd) == 0 || strlen(passwd) > AuthPasswd::MAX_PASSWORD_LEN));
+}
+
+} // namespace anonymous
+
+AUTH_PASSWD_API
+int auth_passwd_check_passwd(const password_type passwd_type,
+                             const char *passwd,
+                             unsigned int *current_attempts,
+                             unsigned int *max_attempts,
+                             unsigned int *valid_secs)
+{
+    using namespace AuthPasswd;
+
+    return try_catch([&] {
+        if (isPasswordIncorrect(passwd) ||
+            current_attempts == NULL || max_attempts == NULL || valid_secs == NULL) {
+            LogError("Wrong input param");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        if (!passwd) {
+            passwd = NO_PASSWORD;
+        }
+
+        MessageBuffer send, recv;
+
+        *current_attempts = 0;
+        *max_attempts = 0;
+        *valid_secs = 0;
+
+        Serialization::Serialize(send, static_cast<int>(PasswordHdrs::HDR_CHK_PASSWD));
+        Serialization::Serialize(send, passwd_type);
+
+        //Clear pwd memory
+        std::string passwd_str(passwd);
+        Serialization::Serialize(send, passwd_str);
+        passwd_str.clear();
+
+        int retCode = sendToServer(SERVICE_SOCKET_PASSWD_CHECK, send.Pop(), recv);
+        if (AUTH_PASSWD_API_SUCCESS != retCode) {
+            LogDebug("Error in sendToServer. Error code: " << retCode);
+            return retCode;
+        }
+
+        Deserialization::Deserialize(recv, retCode);
+
+        switch (retCode) {
+        case AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH:
+        case AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED:
+        case AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED:
+        case AUTH_PASSWD_API_SUCCESS:
+            Deserialization::Deserialize(recv, *current_attempts);
+            Deserialization::Deserialize(recv, *max_attempts);
+            Deserialization::Deserialize(recv, *valid_secs);
+            break;
+        default:
+            break;
+        }
+
+        return retCode;
+    });
+}
+
+AUTH_PASSWD_API
+int auth_passwd_check_passwd_state(const password_type passwd_type,
+                                   unsigned int *current_attempts,
+                                   unsigned int *max_attempts,
+                                   unsigned int *valid_secs)
+{
+    using namespace AuthPasswd;
+
+    return try_catch([&] {
+        if (NULL == current_attempts || NULL == max_attempts ||
+            NULL == valid_secs) {
+
+            LogError("Wrong input param");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        MessageBuffer send, recv;
+
+        *current_attempts = 0;
+        *max_attempts = 0;
+        *valid_secs = 0;
+
+        Serialization::Serialize(send, static_cast<int>(PasswordHdrs::HDR_CHK_PASSWD_STATE));
+        Serialization::Serialize(send, passwd_type);
+
+        int retCode = sendToServer(SERVICE_SOCKET_PASSWD_CHECK, send.Pop(), recv);
+        if (AUTH_PASSWD_API_SUCCESS != retCode) {
+            LogDebug("Error in sendToServer. Error code: " << retCode);
+            return retCode;
+        }
+
+        Deserialization::Deserialize(recv, retCode);
+
+        if(retCode == AUTH_PASSWD_API_SUCCESS) {
+            Deserialization::Deserialize(recv, *current_attempts);
+            Deserialization::Deserialize(recv, *max_attempts);
+            Deserialization::Deserialize(recv, *valid_secs);
+        }
+
+        return retCode;
+    });
+}
+
+AUTH_PASSWD_API
+int auth_passwd_check_passwd_reused(const password_type passwd_type, 
+                                    const char *passwd,
+                                    int *is_reused)
+{
+    using namespace AuthPasswd;
+
+    return try_catch([&] {
+        if (NULL == passwd || NULL == is_reused) {
+            LogError("Wrong input param");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        MessageBuffer send, recv;
+
+        Serialization::Serialize(send, static_cast<int>(PasswordHdrs::HDR_CHK_PASSWD_REUSED));
+        Serialization::Serialize(send, passwd_type);
+        Serialization::Serialize(send, std::string(passwd));
+
+        int retCode = sendToServer(SERVICE_SOCKET_PASSWD_SET, send.Pop(), recv);
+        if (AUTH_PASSWD_API_SUCCESS != retCode) {
+            LogDebug("Error in sendToServer. Error code: " << retCode);
+            return retCode;
+        }
+
+        Deserialization::Deserialize(recv, retCode);
+
+        if (AUTH_PASSWD_API_SUCCESS == retCode) {
+            Deserialization::Deserialize(recv, *is_reused);
+        }
+
+        return retCode;
+    });
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_passwd(const password_type passwd_type,
+                           const char *cur_passwd,
+                           const char *new_passwd)
+{
+    using namespace AuthPasswd;
+
+    return try_catch([&] {
+        if (!cur_passwd) {
+            cur_passwd = NO_PASSWORD;
+        }
+
+        if (isPasswordIncorrect(new_passwd) || strlen(cur_passwd) > MAX_PASSWORD_LEN) {
+            LogError("Wrong input param.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        if (!new_passwd) {
+            new_passwd = NO_PASSWORD;
+        }
+
+        MessageBuffer send, recv;
+
+        Serialization::Serialize(send, static_cast<int>(PasswordHdrs::HDR_SET_PASSWD));
+        Serialization::Serialize(send, passwd_type);
+        Serialization::Serialize(send, std::string(cur_passwd));
+        Serialization::Serialize(send, std::string(new_passwd));
+
+        int retCode = sendToServer(SERVICE_SOCKET_PASSWD_SET, send.Pop(), recv);
+        if (AUTH_PASSWD_API_SUCCESS != retCode) {
+            LogError("Error in sendToServer. Error code: " << retCode);
+            return retCode;
+        }
+
+        Deserialization::Deserialize(recv, retCode);
+
+        return retCode;
+    });
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_passwd_recovery(const char *cur_recovery_passwd,
+                                    const char *new_normal_passwd)
+{
+    using namespace AuthPasswd;
+
+    return try_catch([&] {
+        if (!new_normal_passwd || isPasswordIncorrect(new_normal_passwd) ||
+            !cur_recovery_passwd || isPasswordIncorrect(cur_recovery_passwd)) {
+
+            LogError("Wrong input param.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        MessageBuffer send, recv;
+
+        Serialization::Serialize(send, static_cast<int>(PasswordHdrs::HDR_SET_PASSWD_RECOVERY));
+        Serialization::Serialize(send, std::string(cur_recovery_passwd));
+        Serialization::Serialize(send, std::string(new_normal_passwd));
+
+        int retCode = sendToServer(SERVICE_SOCKET_PASSWD_SET, send.Pop(), recv);
+        if (AUTH_PASSWD_API_SUCCESS != retCode) {
+            LogError("Error in sendToServer. Error code: " << retCode);
+            return retCode;
+        }
+
+        Deserialization::Deserialize(recv, retCode);
+
+        return retCode;
+    });
+}
diff --git a/src/client/include/client-common.h b/src/client/include/client-common.h
new file mode 100644 (file)
index 0000000..6d24c51
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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 authentication password.
+ */
+
+#ifndef _AUTH_PASSWD_CLIENT_
+#define _AUTH_PASSWD_CLIENT_
+
+#include <unistd.h>
+
+#include <vector>
+#include <functional>
+
+#include <message-buffer.h>
+
+#define AUTH_PASSWD_API __attribute__((visibility("default")))
+
+extern "C" {
+    struct msghdr;
+}
+
+namespace AuthPasswd {
+
+typedef std::vector<unsigned char> RawBuffer;
+
+int sendToServerWithFd(int fd, const RawBuffer &send, MessageBuffer &recv);
+
+int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv);
+
+/*
+ * sendToServerAncData is special case when we want to receive file descriptor
+ * passed by Authentication Server on behalf of calling process. We can't get it with
+ * MessageBuffer.
+ *
+ * This function should be called _ONLY_ in this particular case.
+ *
+ */
+int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr);
+
+/*
+ * 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);
+
+
+class SockRAII {
+public:
+    SockRAII()
+      : m_sock(-1)
+    {}
+
+    ~SockRAII() {
+        if (m_sock > -1 )
+            close(m_sock);
+    }
+
+    int Connect(char const * const interface);
+
+    int Get() const {
+        return m_sock;
+    }
+
+private:
+    int m_sock;
+};
+} // namespace AuthPasswd
+
+#endif // _AUTH_PASSWD_CLIENT_
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bec6f53
--- /dev/null
@@ -0,0 +1,57 @@
+PKG_CHECK_MODULES(COMMON_DEP
+    dlog
+    libsmack
+    REQUIRED
+    )
+
+SET(COMMON_SOURCES
+    ${COMMON_PATH}/error-description.cpp
+    ${COMMON_PATH}/protocols.cpp
+    ${COMMON_PATH}/message-buffer.cpp
+    ${COMMON_PATH}/smack-check.cpp
+    ${COMMON_PATH}/user-check.cpp
+    ${DPL_PATH}/log/src/abstract_log_provider.cpp
+    ${DPL_PATH}/log/src/dlog_log_provider.cpp
+    ${DPL_PATH}/log/src/log.cpp
+    ${DPL_PATH}/log/src/old_style_log_provider.cpp
+    ${DPL_PATH}/core/src/assert.cpp
+    ${DPL_PATH}/core/src/binary_queue.cpp
+    ${DPL_PATH}/core/src/colors.cpp
+    ${DPL_PATH}/core/src/exception.cpp
+    ${DPL_PATH}/core/src/noncopyable.cpp
+    ${DPL_PATH}/core/src/serialization.cpp
+    ${DPL_PATH}/core/src/singleton.cpp
+    )
+
+SET_SOURCE_FILES_PROPERTIES(
+    ${COMMON_SOURCES}
+    PROPERTIES
+        COMPILE_FLAGS "-fvisibility=default"
+    )
+
+INCLUDE_DIRECTORIES(SYSTEM
+    ${COMMON_DEP_INCLUDE_DIRS}
+    )
+
+INCLUDE_DIRECTORIES(
+    ${COMMON_PATH}/include
+    ${PLUGIN_PATH}/include
+    ${DPL_PATH}/core/include
+    ${DPL_PATH}/log/include
+    )
+
+ADD_LIBRARY(${TARGET_COMMON} SHARED ${COMMON_SOURCES})
+
+SET_TARGET_PROPERTIES(
+    ${TARGET_COMMON}
+    PROPERTIES
+        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC"
+        SOVERSION 1.0.0
+        VERSION 1.0.0
+    )
+
+TARGET_LINK_LIBRARIES(${TARGET_COMMON}
+    ${COMMON_DEP_LIBRARIES}
+    )
+
+INSTALL(TARGETS ${TARGET_COMMON} DESTINATION lib)
diff --git a/src/common/error-description.cpp b/src/common/error-description.cpp
new file mode 100644 (file)
index 0000000..62f7e55
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ * @file        error-description.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementatin of errorToString function.
+ */
+#include <string.h>
+
+#include <error-description.h>
+
+#define MAX_BUF 256
+
+namespace AuthPasswd {
+
+std::string errnoToString(int err) {
+    char buffer[MAX_BUF] = {};
+
+#if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE
+    if (0 == strerror_r(err, buffer, MAX_BUF))
+        return std::string(buffer);
+#else
+    char *result = strerror_r(err, buffer, MAX_BUF);
+    if (result)
+        return std::string(result);
+#endif
+    return std::string();
+}
+
+} // namespace AuthPasswd
diff --git a/src/common/include/connection-info.h b/src/common/include/connection-info.h
new file mode 100644 (file)
index 0000000..2d88ae1
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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@partner.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 AuthPasswd
+{
+    struct ConnectionInfo {
+        InterfaceID interfaceID;
+        MessageBuffer buffer;
+    };
+
+    typedef std::map<int, ConnectionInfo> ConnectionInfoMap;
+} //namespace AuthPasswd
+
+#endif //_CONNECTION_INFO_H_
diff --git a/src/common/include/error-description.h b/src/common/include/error-description.h
new file mode 100644 (file)
index 0000000..f4e7613
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ * @file        error-description.h
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementatin of errorToString function.
+ */
+#ifndef _AUTH_PASSWD_ERROR_DESCRIPTION_
+#define _AUTH_PASSWD_ERROR_DESCRIPTION_
+
+#include <string>
+
+namespace AuthPasswd {
+
+std::string errnoToString(int err);
+
+} // namespace AuthPasswd
+
+#endif // _AUTH_PASSWD_ERROR_DESCRIPTION_
diff --git a/src/common/include/message-buffer.h b/src/common/include/message-buffer.h
new file mode 100644 (file)
index 0000000..0707017
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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)
+ * @version     1.0
+ * @brief       Implementatin of MessageBuffer.
+ */
+
+#ifndef _AUTH_PASSWD_SOCKET_BUFFER_
+#define _AUTH_PASSWD_SOCKET_BUFFER_
+
+#include <vector>
+
+#include <dpl/binary_queue.h>
+#include <dpl/exception.h>
+#include <dpl/serialization.h>
+
+namespace AuthPasswd {
+
+typedef std::vector<unsigned char> RawBuffer;
+
+class MessageBuffer : public AuthPasswd::IStream {
+public:
+    class Exception
+    {
+    public:
+        DECLARE_EXCEPTION_TYPE(AuthPasswd::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;
+    AuthPasswd::BinaryQueue m_buffer;
+};
+
+} // namespace AuthPasswd
+
+#endif // _AUTH_PASSWD_SOCKET_BUFFER_
diff --git a/src/common/include/policy.h b/src/common/include/policy.h
new file mode 100644 (file)
index 0000000..60e7fbf
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (c) 2016 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        policy.h
+ * @author      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       Implementatin of MessageBuffer.
+ */
+
+#ifndef _AUTH_PASSWD_POLICY_H_
+#define _AUTH_PASSWD_POLICY_H_
+
+#include <auth-passwd-policy-types.h>
+
+struct auth_password_policy {
+
+    uid_t uid;
+    unsigned int maxAttempts;
+    unsigned int validPeriod;
+    unsigned int historySize; 
+    unsigned int minLength;
+    password_quality_type qualityType;
+};
+
+#endif // _AUTH_PASSWD_POLICY_H_
diff --git a/src/common/include/protocols.h b/src/common/include/protocols.h
new file mode 100644 (file)
index 0000000..047a962
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       This file contains list of all protocols suported by authentication password.
+ */
+
+#ifndef _AUTH_PASSWD_PROTOCOLS_
+#define _AUTH_PASSWD_PROTOCOLS_
+
+#include <cstddef>
+#include <time.h>
+#include <sys/types.h>
+
+namespace AuthPasswd {
+
+extern char const * const SERVICE_SOCKET_PASSWD_CHECK;
+extern char const * const SERVICE_SOCKET_PASSWD_SET;
+extern char const * const SERVICE_SOCKET_PASSWD_RESET;
+extern char const * const SERVICE_SOCKET_PASSWD_POLICY;
+
+enum class PasswordHdrs
+{
+    HDR_CHK_PASSWD,
+    HDR_CHK_PASSWD_STATE,
+    HDR_CHK_PASSWD_REUSED,
+    HDR_SET_PASSWD,
+    HDR_SET_PASSWD_RECOVERY,
+    HDR_RST_PASSWD,
+    HDR_SET_PASSWD_POLICY
+};
+
+extern const size_t MAX_PASSWORD_LEN;
+extern const unsigned int MAX_PASSWORD_HISTORY;
+extern const unsigned int PASSWORD_INFINITE_EXPIRATION_DAYS;
+extern const unsigned int PASSWORD_INFINITE_ATTEMPT_COUNT;
+extern const unsigned int PASSWORD_API_NO_EXPIRATION;
+
+} // namespace AuthPasswd
+
+#endif // _AUTH_PASSWD_PROTOCOLS_
+
diff --git a/src/common/include/smack-check.h b/src/common/include/smack-check.h
new file mode 100644 (file)
index 0000000..43fc4a6
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  Authentication password
+ *
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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 AuthPasswd {
+
+/*
+ * 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 AuthPasswd
+
+#endif // _SMACK_CHECK_H_
diff --git a/src/common/include/user-check.h b/src/common/include/user-check.h
new file mode 100644 (file)
index 0000000..a16a7b8
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  Authentication password
+ *
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee  <jooseong.lee@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 <sys/socket.h>
+#include <sys/un.h>
+
+namespace AuthPasswd {
+
+int socket_get_user(int sockfd, unsigned int &user);
+
+} // namespace AuthPasswd
+
diff --git a/src/common/message-buffer.cpp b/src/common/message-buffer.cpp
new file mode 100644 (file)
index 0000000..80bdd96
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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)
+ * @version     1.0
+ * @brief       Implementation of MessageBuffer.
+ */
+
+#include <message-buffer.h>
+
+#include <dpl/log/log.h>
+
+namespace AuthPasswd {
+
+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 AuthPasswd
+
diff --git a/src/common/protocols.cpp b/src/common/protocols.cpp
new file mode 100644 (file)
index 0000000..a8bd92e
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       List of all protocols supported by authentication password.
+ */
+
+#include <protocols.h>
+#include <cstddef>
+
+namespace AuthPasswd {
+
+char const * const SERVICE_SOCKET_PASSWD_CHECK =
+    "/run/.authentication-server-api-passwd-check.sock";
+char const * const SERVICE_SOCKET_PASSWD_SET =
+    "/run/.authentication-server-api-passwd-set.sock";
+char const * const SERVICE_SOCKET_PASSWD_RESET =
+    "/run/.authentication-server-api-passwd-reset.sock";
+char const * const SERVICE_SOCKET_PASSWD_POLICY =
+    "/run/.authentication-server-api-passwd-policy.sock";
+
+const size_t MAX_PASSWORD_LEN = 32;
+const unsigned int MAX_PASSWORD_HISTORY = 50;
+const unsigned int PASSWORD_INFINITE_EXPIRATION_DAYS = 0;
+const unsigned int PASSWORD_INFINITE_ATTEMPT_COUNT = 0;
+const unsigned int PASSWORD_API_NO_EXPIRATION = 0xFFFFFFFF;
+
+} // namespace AuthPasswd
+
diff --git a/src/common/smack-check.cpp b/src/common/smack-check.cpp
new file mode 100644 (file)
index 0000000..8b1e414
--- /dev/null
@@ -0,0 +1,34 @@
+#include <smack-check.h>
+
+#include <stdlib.h>
+#include <sys/smack.h>
+
+#include <dpl/log/log.h>
+
+namespace AuthPasswd {
+
+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 AuthPasswd
diff --git a/src/common/user-check.cpp b/src/common/user-check.cpp
new file mode 100644 (file)
index 0000000..0776b7c
--- /dev/null
@@ -0,0 +1,19 @@
+#include <user-check.h>
+#include <dpl/log/log.h>
+
+namespace AuthPasswd {
+
+int socket_get_user(int sockfd, unsigned int &user)
+{
+    struct ucred cr;
+    socklen_t len = sizeof(struct ucred);
+    if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &len))
+    {
+        LogError("getsockopt() failed");
+        return 1;
+    }
+    user = cr.uid;
+    return 0;
+}
+
+} // namespace AuthPasswd
diff --git a/src/dpl/core/include/dpl/assert.h b/src/dpl/core/include/dpl/assert.h
new file mode 100644 (file)
index 0000000..adcd289
--- /dev/null
@@ -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 AUTH_PASSWD_ASSERT_H
+#define AUTH_PASSWD_ASSERT_H
+
+#include <dpl/noreturn.h>
+
+namespace AuthPasswd {
+// Assertion handler procedure
+// Do not call directly
+// Always use Assert macro
+AUTHPASSWD_NORETURN void AssertProc(const char *condition,
+                             const char *file,
+                             int line,
+                             const char *function);
+} // namespace AuthPasswd
+
+#define Assert(Condition) do { if (!(Condition)) { AuthPasswd::AssertProc(#Condition, \
+                                                                   __FILE__, \
+                                                                   __LINE__, \
+                                                                   __FUNCTION__); \
+                               } } while (0)
+
+#endif // AUTH_PASSWD_ASSERT_H
diff --git a/src/dpl/core/include/dpl/binary_queue.h b/src/dpl/core/include/dpl/binary_queue.h
new file mode 100644 (file)
index 0000000..9f29570
--- /dev/null
@@ -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 AUTH_PASSWD_BINARY_QUEUE_H
+#define AUTH_PASSWD_BINARY_QUEUE_H
+
+//#include <dpl/abstract_input_output.h>
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <memory>
+#include <list>
+
+namespace AuthPasswd {
+/**
+ * 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(AuthPasswd::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 AuthPasswd
+
+#endif // AUTH_PASSWD_BINARY_QUEUE_H
diff --git a/src/dpl/core/include/dpl/colors.h b/src/dpl/core/include/dpl/colors.h
new file mode 100644 (file)
index 0000000..400647e
--- /dev/null
@@ -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 AUTH_PASSWD_COLORS_H
+#define AUTH_PASSWD_COLORS_H
+
+namespace AuthPasswd {
+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 AuthPasswd
+
+#endif /* AUTH_PASSWD_COLORS_H */
diff --git a/src/dpl/core/include/dpl/exception.h b/src/dpl/core/include/dpl/exception.h
new file mode 100644 (file)
index 0000000..2d66d62
--- /dev/null
@@ -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 AUTH_PASSWD_EXCEPTION_H
+#define AUTH_PASSWD_EXCEPTION_H
+
+#include <string>
+#include <cstring>
+#include <cstdio>
+#include <exception>
+#include <cstdlib>
+#include <sstream>
+
+namespace AuthPasswd {
+void LogUnhandledException(const std::string &str);
+void LogUnhandledException(const std::string &str,
+                           const char *filename,
+                           int line,
+                           const char *function);
+}
+
+namespace AuthPasswd {
+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 AuthPasswd 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-AuthPasswd 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 AuthPasswd
+
+#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 AuthPasswd::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 AuthPasswd::Exception &exception)                                                                   \
+    {                                                                                                     \
+        std::ostringstream msg;                                                                           \
+        msg << AuthPasswd::Exception::KnownExceptionToString(exception);                                             \
+        AuthPasswd::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__);                              \
+        abort();                                                                                          \
+    }                                                                                                     \
+    catch (std::exception& e)                                                                             \
+    {                                                                                                     \
+        std::ostringstream msg;                                                                           \
+        msg << e.what();                                                                                  \
+        msg << "\n";                                                                                      \
+        msg << AuthPasswd::Exception::UnknownExceptionToString();                                                    \
+        AuthPasswd::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__);                              \
+        abort();                                                                                          \
+    }                                                                                                     \
+    catch (...)                                                                                           \
+    {                                                                                                     \
+        std::ostringstream msg;                                                                           \
+        msg << AuthPasswd::Exception::UnknownExceptionToString();                                                    \
+        AuthPasswd::LogUnhandledException(msg.str(), __FILE__, __LINE__, __FUNCTION__);                              \
+        abort();                                                                                          \
+    }
+
+namespace AuthPasswd {
+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 // AUTH_PASSWD_EXCEPTION_H
diff --git a/src/dpl/core/include/dpl/fstream_accessors.h b/src/dpl/core/include/dpl/fstream_accessors.h
new file mode 100644 (file)
index 0000000..ea692bd
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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 AUTH_PASSWD_FSTREAM_ACCESSORS_H
+#define AUTH_PASSWD_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 // AUTH_PASSWD_FSTREAM_ACCESSORS_H
diff --git a/src/dpl/core/include/dpl/noncopyable.h b/src/dpl/core/include/dpl/noncopyable.h
new file mode 100644 (file)
index 0000000..873f386
--- /dev/null
@@ -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 AUTHPASSWD_NONCOPYABLE_H
+#define AUTHPASSWD_NONCOPYABLE_H
+
+namespace AuthPasswd {
+class Noncopyable
+{
+  private:
+    Noncopyable(const Noncopyable &);
+    const Noncopyable &operator=(const Noncopyable &);
+
+  public:
+    Noncopyable();
+    virtual ~Noncopyable();
+};
+} // namespace AuthPasswd
+
+#endif // AUTHPASSWD_NONCOPYABLE_H
diff --git a/src/dpl/core/include/dpl/noreturn.h b/src/dpl/core/include/dpl/noreturn.h
new file mode 100644 (file)
index 0000000..7da368f
--- /dev/null
@@ -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 AUTHPASSWD_NORETURN_H
+#define AUTHPASSWD_NORETURN_H
+
+#define AUTHPASSWD_NORETURN __attribute__((__noreturn__))
+
+#endif // AUTHPASSWD_NORETURN_H
diff --git a/src/dpl/core/include/dpl/serialization.h b/src/dpl/core/include/dpl/serialization.h
new file mode 100644 (file)
index 0000000..ab7a193
--- /dev/null
@@ -0,0 +1,405 @@
+/*
+ * 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 SERIALIZATION_H
+#define SERIALIZATION_H
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+#include <memory>
+
+namespace AuthPasswd {
+// 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);
+    }
+
+    // std::shared_ptr
+    template <typename T>
+    static void Serialize(IStream& stream, const std::shared_ptr<T>& p)
+    {
+        Serialize(stream, *p);
+    }
+}; // struct Serialization
+
+struct Deserialization {
+    // deserialization
+    // normal functions
+
+    // ISerializable objects
+    // T instead of ISerializable is needed to call proper constructor
+    template <typename T>
+    static void Deserialize(IStream& stream, T& object)
+    {
+        object = T(stream);
+    }
+    template <typename T>
+    static void Deserialize(IStream& stream, T*& object)
+    {
+        object = new T(stream);
+    }
+
+    // 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 AuthPasswd
+
+#endif // SERIALIZATION_H
diff --git a/src/dpl/core/include/dpl/singleton.h b/src/dpl/core/include/dpl/singleton.h
new file mode 100644 (file)
index 0000000..2b42513
--- /dev/null
@@ -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 AUTHPASSWD_SINGLETON_H
+#define AUTHPASSWD_SINGLETON_H
+
+namespace AuthPasswd {
+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 AuthPasswd
+
+#endif // AUTHPASSWD_SINGLETON_H
diff --git a/src/dpl/core/include/dpl/singleton_impl.h b/src/dpl/core/include/dpl/singleton_impl.h
new file mode 100644 (file)
index 0000000..9f2e425
--- /dev/null
@@ -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 AUTHPASSWD_SINGLETON_IMPL_H
+#define AUTHPASSWD_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 AuthPasswd {
+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 AuthPasswd
+
+#define IMPLEMENT_SINGLETON(Type)                                           \
+    template AuthPasswd::Singleton<Type>&AuthPasswd::Singleton<Type>::InternalInstance();    \
+    template Type & AuthPasswd::Singleton<Type>::Instance();                            \
+
+#endif // AUTHPASSWD_SINGLETON_IMPL_H
diff --git a/src/dpl/core/include/dpl/singleton_safe_impl.h b/src/dpl/core/include/dpl/singleton_safe_impl.h
new file mode 100644 (file)
index 0000000..3ab2028
--- /dev/null
@@ -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 AUTHPASSWD_SINGLETON_SAFE_IMPL_H
+#define AUTHPASSWD_SINGLETON_SAFE_IMPL_H
+
+#define IMPLEMENT_SAFE_SINGLETON(Class)                                        \
+    namespace AuthPasswd {                                                         \
+    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 AuthPasswd
+
+#endif // AUTHPASSWD_SINGLETON_SAFE_IMPL_H
diff --git a/src/dpl/core/src/assert.cpp b/src/dpl/core/src/assert.cpp
new file mode 100644 (file)
index 0000000..10b9ccb
--- /dev/null
@@ -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 AuthPasswd {
+void AssertProc(const char *condition,
+                const char *file,
+                int line,
+                const char *function)
+{
+#define INTERNAL_LOG(message)                                          \
+    do                                                                 \
+    {                                                                  \
+        std::ostringstream platformLog;                                \
+        platformLog << message;                                        \
+        AuthPasswd::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(
+            "###                            AuthPasswd 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 AuthPasswd
diff --git a/src/dpl/core/src/binary_queue.cpp b/src/dpl/core/src/binary_queue.cpp
new file mode 100644 (file)
index 0000000..12277d4
--- /dev/null
@@ -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 AuthPasswd {
+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 AuthPasswd
diff --git a/src/dpl/core/src/colors.cpp b/src/dpl/core/src/colors.cpp
new file mode 100644 (file)
index 0000000..083ab37
--- /dev/null
@@ -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 AuthPasswd {
+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 AuthPasswd
diff --git a/src/dpl/core/src/exception.cpp b/src/dpl/core/src/exception.cpp
new file mode 100644 (file)
index 0000000..26f7385
--- /dev/null
@@ -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 AuthPasswd {
+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
+    AuthPasswd::Log::LogSystemSingleton::Instance().Error(
+        str.c_str(), filename, line, function);
+}
+} // namespace AuthPasswd
diff --git a/src/dpl/core/src/noncopyable.cpp b/src/dpl/core/src/noncopyable.cpp
new file mode 100644 (file)
index 0000000..06c8772
--- /dev/null
@@ -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 AuthPasswd {
+Noncopyable::Noncopyable()
+{}
+
+Noncopyable::~Noncopyable()
+{}
+} // namespace AuthPasswd
diff --git a/src/dpl/core/src/serialization.cpp b/src/dpl/core/src/serialization.cpp
new file mode 100644 (file)
index 0000000..f8f05ff
--- /dev/null
@@ -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/dpl/core/src/singleton.cpp b/src/dpl/core/src/singleton.cpp
new file mode 100644 (file)
index 0000000..a76e8ac
--- /dev/null
@@ -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/dpl/log/include/dpl/log/abstract_log_provider.h b/src/dpl/log/include/dpl/log/abstract_log_provider.h
new file mode 100644 (file)
index 0000000..021d705
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * 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 AUTHPASSWD_ABSTRACT_LOG_PROVIDER_H
+#define AUTHPASSWD_ABSTRACT_LOG_PROVIDER_H
+
+namespace AuthPasswd {
+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 AuthPasswd
+
+#endif // AUTHPASSWD_ABSTRACT_LOG_PROVIDER_H
diff --git a/src/dpl/log/include/dpl/log/dlog_log_provider.h b/src/dpl/log/include/dpl/log/dlog_log_provider.h
new file mode 100644 (file)
index 0000000..f87c7d5
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * 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 AUTHPASSWD_DLOG_LOG_PROVIDER_H
+#define AUTHPASSWD_DLOG_LOG_PROVIDER_H
+
+#include <dpl/log/abstract_log_provider.h>
+#include <memory>
+#include <string>
+
+namespace AuthPasswd {
+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 AuthPasswd
+
+#endif // AUTHPASSWD_DLOG_LOG_PROVIDER_H
diff --git a/src/dpl/log/include/dpl/log/log.h b/src/dpl/log/include/dpl/log/log.h
new file mode 100644 (file)
index 0000000..3af6a81
--- /dev/null
@@ -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 AUTHPASSWD_LOG_H
+#define AUTHPASSWD_LOG_H
+
+#include <dpl/singleton.h>
+#include <dpl/noncopyable.h>
+#include <dpl/log/abstract_log_provider.h>
+#include <sstream>
+#include <list>
+
+namespace AuthPasswd {
+namespace Log {
+/**
+ * AuthPasswd 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 AuthPasswd
+
+//
+// Log support
+//
+//
+
+/* avoid warnings about unused variables */
+#define DPL_MACRO_DUMMY_LOGGING(message, function)                         \
+    do {                                                                   \
+        AuthPasswd::Log::NullStream ns;                                \
+        ns << message;                                                     \
+    } while (0)
+
+#define DPL_MACRO_FOR_LOGGING(message, function)                           \
+do                                                                         \
+{                                                                          \
+    if (AuthPasswd::Log::LogSystemSingleton::Instance().IsLoggingEnabled())   \
+    {                                                                      \
+        std::ostringstream platformLog;                                    \
+        platformLog << message;                                            \
+        AuthPasswd::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 // AUTHPASSWD_LOG_H
diff --git a/src/dpl/log/include/dpl/log/old_style_log_provider.h b/src/dpl/log/include/dpl/log/old_style_log_provider.h
new file mode 100644 (file)
index 0000000..39e58e6
--- /dev/null
@@ -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 AUTHPASSWD_OLD_STYLE_LOG_PROVIDER_H
+#define AUTHPASSWD_OLD_STYLE_LOG_PROVIDER_H
+
+#include <dpl/log/abstract_log_provider.h>
+#include <string>
+
+namespace AuthPasswd {
+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 AuthPasswd
+
+#endif // AUTHPASSWD_OLD_STYLE_LOG_PROVIDER_H
diff --git a/src/dpl/log/src/abstract_log_provider.cpp b/src/dpl/log/src/abstract_log_provider.cpp
new file mode 100644 (file)
index 0000000..7f7c07f
--- /dev/null
@@ -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 AuthPasswd {
+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/dpl/log/src/dlog_log_provider.cpp b/src/dpl/log/src/dlog_log_provider.cpp
new file mode 100644 (file)
index 0000000..a9cfc8f
--- /dev/null
@@ -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 AuthPasswd {
+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, "AuthPasswd", "%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 AuthPasswd
diff --git a/src/dpl/log/src/log.cpp b/src/dpl/log/src/log.cpp
new file mode 100644 (file)
index 0000000..cf4f256
--- /dev/null
@@ -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(AuthPasswd::Log::LogSystem)
+
+namespace AuthPasswd {
+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 *AUTH_PASSWD_LOG_OFF = "DPL_LOG_OFF";
+} // namespace anonymous
+
+bool LogSystem::IsLoggingEnabled() const
+{
+    return m_isLoggingEnabled;
+}
+
+LogSystem::LogSystem() :
+    m_isLoggingEnabled(!getenv(AUTH_PASSWD_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 AuthPasswd
diff --git a/src/dpl/log/src/old_style_log_provider.cpp b/src/dpl/log/src/old_style_log_provider.cpp
new file mode 100644 (file)
index 0000000..fcdf111
--- /dev/null
@@ -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 AuthPasswd {
+namespace Log {
+namespace // anonymous
+{
+using namespace AuthPasswd::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 AuthPasswd
diff --git a/src/include/CMakeLists.txt b/src/include/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3eeea74
--- /dev/null
@@ -0,0 +1,7 @@
+INSTALL(FILES
+    ${INCLUDE_PATH}/auth-passwd.h
+    ${INCLUDE_PATH}/auth-passwd-admin.h
+    ${INCLUDE_PATH}/auth-passwd-policy-types.h
+    ${INCLUDE_PATH}/auth-passwd-error.h
+    DESTINATION /usr/include/authentication-server
+    )
diff --git a/src/include/auth-passwd-admin.h b/src/include/auth-passwd-admin.h
new file mode 100644 (file)
index 0000000..1bc4503
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Authentication password
+ *
+ *  Copyright (c) 2016 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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 AUTH_PASSWD_ADMIN_H
+#define AUTH_PASSWD_ADMIN_H
+
+#include <sys/types.h>
+#include <auth-passwd-error.h>
+#include <auth-passwd-policy-types.h>
+
+/**
+ * @file    auth-passwd-admin.h
+ * @version 1.0
+ * @brief   This file contains APIs of the Authentication Server
+*/
+
+/**
+ * @defgroup SecurityFW
+ * @{
+ *
+ * @defgroup AUTH_PASSWD Authentication Server - password
+ * @version  1.0
+ * @brief    Authentication Server client library functions
+ *
+*/
+
+/**
+ * @addtogroup AUTH_PASSWD
+ * @{
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int auth_passwd_reset_passwd(const password_type passwd_type,
+                             const uid_t uid,
+                             const char *new_passwd);
+
+int auth_passwd_new_policy(policy_h **pp_policy);
+
+int auth_passwd_set_user(policy_h *p_policy, const uid_t uid);
+
+int auth_passwd_set_max_attempts(policy_h *p_policy, const unsigned int max_attempts);
+
+int auth_passwd_set_validity(policy_h *p_policy, const unsigned int valid_days);
+
+int auth_passwd_set_history_size(policy_h *p_policy, const unsigned int history_size);
+
+int auth_passwd_set_min_length(policy_h *p_policy, const unsigned int min_length);
+
+int auth_passwd_set_quality(policy_h *p_policy, password_quality_type quality_type);
+
+int auth_passwd_set_policy(policy_h *p_policy);
+
+void auth_passwd_free_policy(policy_h *p_policy);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+*/
+
+/**
+ * @}
+*/
+
+#endif
diff --git a/src/include/auth-passwd-error.h b/src/include/auth-passwd-error.h
new file mode 100644 (file)
index 0000000..610f828
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ *  Authentication password
+ *
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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 AUTH_PASSWD_ERROR_H
+#define AUTH_PASSWD_ERROR_H
+
+/**
+ * \name Return Codes
+ * exported by the foundation API.
+ * result codes begin with the start error code and extend into negative direction.
+ * @{
+*/
+#define AUTH_PASSWD_API_SUCCESS 0
+
+/*! \brief   indicating the result of the one specific API is successful */
+#define AUTH_PASSWD_API_ERROR_SOCKET -1
+
+/*! \brief   indicating the API's input parameter is malformed */
+#define AUTH_PASSWD_API_ERROR_INPUT_PARAM -2
+
+/*! \brief   indicating system  is running out of memory state */
+#define AUTH_PASSWD_API_ERROR_OUT_OF_MEMORY -3
+
+/*! \brief   indicating the output buffer size which is passed as parameter is too small */
+#define Auth_PASSWD_API_ERROR_BUFFER_TOO_SMALL -4
+
+/*! \brief   indicating Authenticaton Server has been failed for some reason */
+#define AUTH_PASSWD_API_ERROR_SERVER_ERROR -5
+
+/*! \brief   indicating the access has been denied by Authetnication Server */
+#define AUTH_PASSWD_API_ERROR_ACCESS_DENIED -6
+
+/*! \brief   indicating there is no user  */
+#define AUTH_PASSWD_API_ERROR_NO_USER -8
+
+/*! \brief   indicating there is no password set  */
+#define AUTH_PASSWD_API_ERROR_NO_PASSWORD -9
+
+/*! \brief   indicating there is no recovery password set  */
+#define AUTH_PASSWD_API_ERROR_NO_RECOVERY_PASSWORD -10
+
+/*! \brief   indicating password exists in system  */
+#define AUTH_PASSWD_API_ERROR_PASSWORD_EXIST -11
+
+/*! \brief   indicating password mismatch  */
+#define AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH -12
+
+/*! \brief   indicating password retry timeout is not occurred yet  */
+#define AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER -13
+
+/*! \brief   indicating password retry timeout is not occurred yet  */
+#define AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED -14
+
+/*! \brief   indicating password retry timeout is not occurred yet  */
+#define AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED -15
+
+/*! \brief   indicating password retry timeout is not occurred yet  */
+#define AUTH_PASSWD_API_ERROR_PASSWORD_REUSED -16
+
+/*! \brief   indicating password retry timeout is not occurred yet  */
+#define AUTH_PASSWD_API_ERROR_RECOVERY_PASSWORD_RESTRICTED -17
+
+/*! \brief   indicating the error with unknown reason */
+#define AUTH_PASSWD_API_ERROR_UNKNOWN -255
+/** @}*/
+
+#endif
diff --git a/src/include/auth-passwd-policy-types.h b/src/include/auth-passwd-policy-types.h
new file mode 100644 (file)
index 0000000..7a7ea5e
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Authentication password
+ *
+ *  Copyright (c) 2016 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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 AUTH_PASSWD_POLICY_TYPES_H
+#define AUTH_PASSWD_POLICY_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct auth_password_policy policy_h;
+
+typedef enum {
+    AUTH_PWD_NORMAL,
+    AUTH_PWD_RECOVERY
+} password_type;
+
+typedef enum {
+    AUTH_PWD_QUALITY_UNSPECIFIED,
+    AUTH_PWD_QUALITY_SOMETHING,
+    AUTH_PWD_QUALITY_NUMERIC,
+    AUTH_PWD_QUALITY_ALPHABETIC,
+    AUTH_PWD_QUALITY_ALPHANUMERIC
+} password_quality_type;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AUTH_PASSWD_POLICY_TYPES_H */
diff --git a/src/include/auth-passwd.h b/src/include/auth-passwd.h
new file mode 100644 (file)
index 0000000..9ea70f9
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Authentication password
+ *
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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 AUTH_PASSWD_H
+#define AUTH_PASSWD_H
+
+#include <sys/types.h>
+#include <auth-passwd-error.h>
+#include <auth-passwd-policy-types.h>
+
+/**
+ * @file    auth-passwd.h
+ * @version 1.0
+ * @brief   This file contains APIs of the Authentication Server
+*/
+
+/**
+ * @defgroup SecurityFW
+ * @{
+ *
+ * @defgroup AUTH_PASSWD Authentication Server - password
+ * @version  1.0
+ * @brief    Authentication Server client library functions
+ *
+*/
+
+/**
+ * @addtogroup AUTH_PASSWD
+ * @{
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int auth_passwd_check_passwd(const password_type passwd_type,
+                             const char *passwd, 
+                             unsigned int *current_attempts,
+                             unsigned int *max_attempts,
+                             unsigned int *valid_secs);
+
+int auth_passwd_check_passwd_state(const password_type passwd_type, 
+                                   unsigned int *current_attempts, 
+                                   unsigned int *max_attempts, 
+                                   unsigned int *valid_secs);
+
+int auth_passwd_check_passwd_reused(const password_type passwd_type, 
+                                    const char *passwd, 
+                                    int *is_reused);
+
+int auth_passwd_set_passwd(const password_type passwd_type,
+                           const char *cur_passwd,
+                           const char *new_passwd);
+
+int auth_passwd_set_passwd_recovery(const char *cur_recovery_passwd, 
+                                    const char *new_normal_passwd);
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}
+*/
+
+/**
+ * @}
+*/
+
+#endif
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
new file mode 100644 (file)
index 0000000..72e99b7
--- /dev/null
@@ -0,0 +1,47 @@
+PKG_CHECK_MODULES(SERVER_DEP
+    dlog
+    openssl
+    libsmack
+    libsystemd-daemon
+    libtzplatform-config
+    REQUIRED
+    )
+FIND_PACKAGE(Threads REQUIRED)
+
+INCLUDE_DIRECTORIES(SYSTEM
+    ${SERVER_DEP_INCLUDE_DIRS}
+    )
+
+INCLUDE_DIRECTORIES(
+    ${INCLUDE_PATH}
+    ${COMMON_PATH}/include
+    ${SERVER_PATH}/main/include
+    ${SERVER_PATH}/service/include
+    ${DPL_PATH}/core/include
+    ${DPL_PATH}/log/include
+    )
+
+SET(SERVER_SOURCES
+    ${SERVER_PATH}/main/generic-socket-manager.cpp
+    ${SERVER_PATH}/main/socket-manager.cpp
+    ${SERVER_PATH}/main/server-main.cpp
+    ${SERVER_PATH}/service/password.cpp
+    ${SERVER_PATH}/service/password-file.cpp
+    ${SERVER_PATH}/service/password-manager.cpp
+    ${SERVER_PATH}/service/password-file-buffer.cpp
+    )
+
+SET_SOURCE_FILES_PROPERTIES(
+    ${SERVER_SOURCES}
+    PROPERTIES
+        COMPILE_FLAGS "-D_GNU_SOURCE -fvisibility=hidden -fPIE")
+
+ADD_EXECUTABLE(${TARGET_SERVER} ${SERVER_SOURCES})
+
+TARGET_LINK_LIBRARIES(${TARGET_SERVER}
+    ${TARGET_COMMON}
+    ${CMAKE_THREAD_LIBS_INIT}
+    ${SERVER_DEP_LIBRARIES} -pie -ldl
+    )
+
+INSTALL(TARGETS ${TARGET_SERVER} DESTINATION bin)
diff --git a/src/server/main/generic-socket-manager.cpp b/src/server/main/generic-socket-manager.cpp
new file mode 100644 (file)
index 0000000..1e0dbdd
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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)
+ * @version     1.0
+ * @brief       Implementation of GenericSocketService and GenericSocketManager.
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <generic-socket-manager.h>
+
+namespace AuthPasswd {
+
+class SendMsgData::Internal {
+public:
+    Internal(int resultCode, int fileDesc)
+      : m_resultCode(resultCode)
+      , m_fileDesc(fileDesc)
+    {
+        memset(&m_hdr, 0, sizeof(msghdr));
+        memset(m_cmsgbuf, 0, CMSG_SPACE(sizeof(int)));
+
+        m_iov.iov_base = &m_resultCode;
+        m_iov.iov_len = sizeof(m_resultCode);
+
+        m_hdr.msg_iov = &m_iov;
+        m_hdr.msg_iovlen = 1;
+
+        if (fileDesc != -1) {
+            m_hdr.msg_control = m_cmsgbuf;
+            m_hdr.msg_controllen = CMSG_SPACE(sizeof(int));
+
+            m_cmsg = CMSG_FIRSTHDR(&m_hdr);
+            m_cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+            m_cmsg->cmsg_level = SOL_SOCKET;
+            m_cmsg->cmsg_type = SCM_RIGHTS;
+
+            memmove(CMSG_DATA(m_cmsg), &m_fileDesc, sizeof(int));
+        }
+    }
+
+    msghdr* data() { return &m_hdr; }
+
+private:
+    msghdr m_hdr;
+    iovec m_iov;
+    cmsghdr *m_cmsg;
+    unsigned char m_cmsgbuf[CMSG_SPACE(sizeof(int))];
+    int m_resultCode;
+    int m_fileDesc;
+};
+
+SendMsgData::SendMsgData()
+  : m_resultCode(0)
+  , m_fileDesc(-1)
+  , m_flags(0)
+  , m_pimpl(NULL)
+{}
+
+SendMsgData::SendMsgData(int resultCode, int fileDesc, int paramFlags)
+  : m_resultCode(resultCode)
+  , m_fileDesc(fileDesc)
+  , m_flags(paramFlags)
+  , m_pimpl(NULL)
+{}
+
+SendMsgData::SendMsgData(const SendMsgData &second)
+  : m_resultCode(second.m_resultCode)
+  , m_fileDesc(second.m_fileDesc)
+  , m_flags(second.m_flags)
+  , m_pimpl(NULL)
+{}
+
+SendMsgData::~SendMsgData() {
+    delete m_pimpl;
+}
+
+SendMsgData& SendMsgData::operator=(const SendMsgData &second) {
+    m_resultCode = second.m_resultCode;
+    m_fileDesc = second.m_fileDesc;
+    m_flags = second.m_flags;
+    delete m_pimpl;
+    m_pimpl = NULL;
+    return *this;
+}
+
+msghdr* SendMsgData::getMsghdr() {
+    if (!m_pimpl)
+        m_pimpl = new Internal(m_resultCode, m_fileDesc);
+    return m_pimpl->data();
+}
+
+int SendMsgData::flags() {
+    return m_flags;
+}
+
+} // namespace AuthPasswd
+
diff --git a/src/server/main/include/generic-event.h b/src/server/main/include/generic-event.h
new file mode 100644 (file)
index 0000000..ef119fe
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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)
+ * @version     1.0
+ * @brief       Implementation of GenericEvent.
+ */
+
+#ifndef _AUTH_PASSWD_GENERIC_EVENT_
+#define _AUTH_PASSWD_GENERIC_EVENT_
+
+namespace AuthPasswd {
+
+struct GenericEvent {
+    virtual ~GenericEvent(){}
+};
+
+} // namespace AuthPasswd
+
+#endif // _AUTH_PASSWD_GENERIC_EVENT_
diff --git a/src/server/main/include/generic-socket-manager.h b/src/server/main/include/generic-socket-manager.h
new file mode 100644 (file)
index 0000000..f39e7a1
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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)
+ * @version     1.0
+ * @brief       Implementation of GenericSocketService and GenericSocketManager.
+ */
+
+#ifndef _AUTH_PASSWD_GENERIC_SERVICE_MANAGER_
+#define _AUTH_PASSWD_GENERIC_SERVICE_MANAGER_
+
+#include <vector>
+#include <string>
+
+#include <dpl/exception.h>
+
+#include <generic-event.h>
+
+extern "C" {
+struct msghdr;
+} // extern "C"
+
+namespace AuthPasswd {
+
+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;
+    }
+    inline bool operator==(const ConnectionID &second) const {
+        return counter == second.counter;
+    }
+    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 *paramPath,
+            const char *paramSmackLabel,
+            InterfaceID paramInterfaceID = 0,
+            bool paramUseSendMsg = false)
+          : type(SOCKET_SERVICE),
+            interfaceID(paramInterfaceID),
+            useSendMsg(paramUseSendMsg),
+            smackLabel(paramSmackLabel),
+            serviceHandlerPath(paramPath),
+            fileDesc(-1)
+        {}
+
+        ServiceDescription(int fileDesc,
+            InterfaceID paramInterfaceID = 0,
+            bool paramUseSendMsg = false)
+          : type(FILE_DESC_SERVICE),
+            interfaceID(paramInterfaceID),
+            useSendMsg(paramUseSendMsg),
+            fileDesc(fileDesc)
+        {}
+
+        enum ServiceType {
+            SOCKET_SERVICE = 0,
+            FILE_DESC_SERVICE
+        };
+        ServiceType type;
+        InterfaceID interfaceID;               // All data from serviceHandlerPath will be marked with this interfaceHandler
+        bool useSendMsg;
+
+        // if a socket service
+        SmackLabel smackLabel;                 // Smack label for socket
+        ServiceHandlerPath serviceHandlerPath; // Path to file
+
+        // if a file descriptor
+        int fileDesc;
+    };
+
+    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;
+        InterfaceID interfaceID;
+    };
+
+    struct CloseEvent : public GenericEvent {
+        ConnectionID connectionID;
+    };
+
+    virtual void SetSocketManager(GenericSocketManager *manager) {
+        m_serviceManager = manager;
+    }
+
+    virtual ServiceDescriptionVector GetServiceDescription() = 0;
+
+    virtual void Start() = 0;
+    virtual void Stop() = 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;
+};
+
+class SendMsgData {
+public:
+    class Internal;
+
+    SendMsgData();
+    SendMsgData(int resultCode, int fileDesc, int flags = 0);
+    SendMsgData(const SendMsgData &second);
+    SendMsgData& operator=(const SendMsgData &second);
+    virtual ~SendMsgData();
+
+    msghdr* getMsghdr();
+    int flags();
+private:
+    int m_resultCode;
+    int m_fileDesc;
+    int m_flags;
+    Internal *m_pimpl;
+};
+
+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 void Write(ConnectionID connectionID, const SendMsgData &sendMsgData) = 0;
+    virtual ~GenericSocketManager(){}
+};
+
+} // namespace AuthPasswd
+
+#endif // _AUTH_PASSWD_GENERIC_SERVICE_MANAGER_
diff --git a/src/server/main/include/service-thread.h b/src/server/main/include/service-thread.h
new file mode 100644 (file)
index 0000000..ea9bfd2
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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)
+ * @version     1.0
+ * @brief       Implementation of threads.
+ */
+
+#ifndef _AUTH_PASSWD_SERVICE_THREAD_
+#define _AUTH_PASSWD_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) {                              \
+        AuthPasswd::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) {                              \
+        AuthPasswd::ServiceThread<ParentClassName>::                  \
+            Event(event,                                              \
+                  this,                                               \
+                  &ParentClassName::methodName);                      \
+    }
+
+namespace AuthPasswd {
+
+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()
+    {
+        assert((m_state == State::NoThread) && "You must stop thread before destruction!");
+
+        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 AuthPasswd
+
+#endif // _AUTH_PASSWD_SERVICE_THREAD_
diff --git a/src/server/main/include/socket-manager.h b/src/server/main/include/socket-manager.h
new file mode 100644 (file)
index 0000000..75bc815
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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)
+ * @version     1.0
+ * @brief       SocketManager implementation.
+ */
+
+#ifndef _AUTH_PASSWD_SOCKET_MANAGER_
+#define _AUTH_PASSWD_SOCKET_MANAGER_
+
+#include <vector>
+#include <queue>
+#include <string>
+#include <mutex>
+#include <thread>
+
+#include <dpl/exception.h>
+
+#include <generic-socket-manager.h>
+
+namespace AuthPasswd {
+
+class SocketManager : public GenericSocketManager {
+public:
+    class Exception {
+    public:
+        DECLARE_EXCEPTION_TYPE(AuthPasswd::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);
+    virtual void Write(ConnectionID connectionID, const SendMsgData &sendMsgData);
+
+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;
+        bool useSendMsg;
+        InterfaceID interfaceID;
+        GenericSocketService *service;
+        time_t timeout;
+        RawBuffer rawBuffer;
+        std::queue<SendMsgData> sendMsgDataQueue;
+        int counter;
+
+        SocketDescription()
+          : isListen(false)
+          , isOpen(false)
+          , isTimeout(false)
+          , useSendMsg(false)
+          , interfaceID(-1)
+          , service(NULL)
+        {}
+    };
+
+    SocketDescription& CreateDefaultReadSocketDescription(int sock, bool timeout, InterfaceID ifaceID = 0, GenericSocketService *service = NULL);
+
+    typedef std::vector<SocketDescription> SocketDescriptionVector;
+
+    struct WriteBuffer {
+        ConnectionID connectionID;
+        RawBuffer rawBuffer;
+    };
+
+    struct WriteData {
+        ConnectionID connectionID;
+        SendMsgData sendMsgData;
+    };
+
+    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<WriteData> m_writeDataQueue;
+    std::queue<ConnectionID> m_closeQueue;
+    int m_notifyMe[2];
+    int m_counter;
+    std::priority_queue<Timeout> m_timeoutQueue;
+};
+
+} // namespace AuthPasswd
+
+#endif // _AUTH_PASSWD_SOCKET_MANAGER_
diff --git a/src/server/main/server-main.cpp b/src/server/main/server-main.cpp
new file mode 100644 (file)
index 0000000..bf986a2
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        sever-main.cpp
+ * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of authentication server
+ */
+#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>
+
+#include <password.h>
+
+IMPLEMENT_SAFE_SINGLETON(AuthPasswd::Log::LogSystem);
+
+#define REGISTER_SOCKET_SERVICE(manager, service) \
+    registerSocketService<service>(manager, #service)
+
+template<typename T>
+void registerSocketService(AuthPasswd::SocketManager &manager, const std::string& serviceName)
+{
+    T *service = NULL;
+    try {
+        service = new T();
+        service->Start();
+        manager.RegisterSocketService(service);
+        service = NULL;
+    } catch (const AuthPasswd::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
+    {
+        AuthPasswd::Singleton<AuthPasswd::Log::LogSystem>::Instance().SetTag("AUTH_PASSWD");
+
+        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!");
+        AuthPasswd::SocketManager manager;
+
+        REGISTER_SOCKET_SERVICE(manager, AuthPasswd::PasswordService);
+
+        manager.MainLoop();
+    }
+    UNHANDLED_EXCEPTION_HANDLER_END
+    return 0;
+}
+
diff --git a/src/server/main/socket-manager.cpp b/src/server/main/socket-manager.cpp
new file mode 100644 (file)
index 0000000..76ac82a
--- /dev/null
@@ -0,0 +1,766 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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 <error-description.h>
+#include <smack-check.h>
+#include <socket-manager.h>
+
+namespace {
+
+const time_t SOCKET_TIMEOUT = 300;
+
+} // namespace anonymous
+
+namespace AuthPasswd {
+
+struct DummyService : public GenericSocketService {
+    ServiceDescriptionVector GetServiceDescription() {
+        return ServiceDescriptionVector();
+    }
+
+    void Start() {}
+    void Stop() {}
+
+    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 Start() {}
+    void Stop() {}
+
+    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;
+        }
+
+        const signalfd_siginfo *siginfo = reinterpret_cast<const signalfd_siginfo*>(
+            reinterpret_cast<const void*>(event.rawBuffer.data()));
+
+        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, InterfaceID ifaceID /*= 0*/, GenericSocketService *service /* = NULL*/)
+{
+    if ((int)m_socketDescriptionVector.size() <= sock)
+        m_socketDescriptionVector.resize(sock+20);
+
+    auto &desc = m_socketDescriptionVector[sock];
+    desc.isListen = false;
+    desc.isOpen = true;
+    desc.interfaceID = ifaceID;
+    desc.service = service;
+    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_maxDesc(0)
+  , 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: " << errnoToString(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 service : serviceMap) {
+        LogDebug("delete " << (void*)(service));
+        service->Stop();
+        delete service;
+    }
+
+    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: " << errnoToString(err));
+        return;
+    }
+
+    auto &desc = CreateDefaultReadSocketDescription(client, false);
+    desc.interfaceID = m_socketDescriptionVector[sock].interfaceID;
+    desc.service = m_socketDescriptionVector[sock].service;
+    desc.useSendMsg = m_socketDescriptionVector[sock].useSendMsg;
+
+    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;
+    }
+
+    auto &desc = m_socketDescriptionVector[sock];
+    GenericSocketService::ReadEvent event;
+    event.connectionID.sock = sock;
+    event.connectionID.counter = m_socketDescriptionVector[sock].counter;
+    event.interfaceID = desc.interfaceID;
+    event.rawBuffer.resize(4096);
+
+    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: " << errnoToString(err));
+                CloseSocket(sock);
+        }
+    }
+}
+
+void SocketManager::ReadyForSendMsg(int sock) {
+    auto &desc = m_socketDescriptionVector[sock];
+
+    if (desc.sendMsgDataQueue.empty()) {
+         FD_CLR(sock, &m_writeSet);
+         return;
+    }
+
+    auto data = desc.sendMsgDataQueue.front();
+    ssize_t result = sendmsg(sock, data.getMsghdr(), data.flags());
+
+    if (result == -1) {
+        int err = errno;
+        switch(err) {
+        case EAGAIN:
+        case EINTR:
+            break;
+        case EPIPE:
+        default:
+            LogDebug("Error during send: " << errnoToString(err));
+            CloseSocket(sock);
+            break;
+        }
+        return;
+    } else {
+        desc.sendMsgDataQueue.pop();
+    }
+
+    if (desc.sendMsgDataQueue.empty()) {
+        FD_CLR(sock, &m_writeSet);
+    }
+
+    desc.timeout = time(NULL) + SOCKET_TIMEOUT;
+
+    GenericSocketService::WriteEvent event;
+    event.connectionID.sock = sock;
+    event.connectionID.counter = desc.counter;
+    event.size = result;
+    event.left = desc.sendMsgDataQueue.size();
+
+    desc.service->Event(event);
+}
+
+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: " << errnoToString(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) {
+    m_socketDescriptionVector[sock].useSendMsg ?
+        ReadyForSendMsg(sock) : ReadyForWriteBuffer(sock);
+}
+
+void SocketManager::MainLoop() {
+    // remove evironment values passed by systemd
+    // uncomment it after removing old authentication password 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: " << errnoToString(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;
+
+    GenericSocketService::ServiceHandlerPath::size_type maxlen =
+            sizeof(static_cast<sockaddr_un*>(nullptr)->sun_path) /
+            sizeof(GenericSocketService::ServiceHandlerPath::value_type);
+    if(desc.serviceHandlerPath.size() >= maxlen) {
+        LogError("Service handler path too long: " << desc.serviceHandlerPath.size());
+        ThrowMsg(Exception::InitFailed,
+                 "Service handler path too long: " << desc.serviceHandlerPath.size());
+    }
+
+    if (-1 == (sockfd = socket(AF_UNIX, SOCK_STREAM, 0))) {
+        int err = errno;
+        LogError("Error in socket: " << errnoToString(err));
+        ThrowMsg(Exception::InitFailed, "Error in socket: " << errnoToString(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: " << errnoToString(err));
+        ThrowMsg(Exception::InitFailed, "Error in fcntl: " << errnoToString(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: " << errnoToString(err));
+        ThrowMsg(Exception::InitFailed, "Error in bind: " << errnoToString(err));
+    }
+
+    umask(originalUmask);
+
+    if (-1 == listen(sockfd, 5)) {
+        int err = errno;
+        close(sockfd);
+        LogError("Error in listen: " << errnoToString(err));
+        ThrowMsg(Exception::InitFailed, "Error in listen: " << errnoToString(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.useSendMsg = desc.useSendMsg;
+    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)
+        {
+            switch(iter->type)
+            {
+                case GenericSocketService::ServiceDescription::SOCKET_SERVICE:
+                    CreateDomainSocket(service, *iter);
+                    break;
+                case GenericSocketService::ServiceDescription::FILE_DESC_SERVICE:
+                    CreateDefaultReadSocketDescription(iter->fileDesc, false, iter->interfaceID, service);
+                    break;
+                default:
+                    ThrowMsg(Exception::InitFailed, "Wrong service type in service description: " << iter->type);
+                    break;
+            }
+        }
+    } 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::Write(ConnectionID connectionID, const SendMsgData &sendMsgData) {
+    WriteData data;
+    data.connectionID = connectionID;
+    data.sendMsgData = sendMsgData;
+    {
+        std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
+        m_writeDataQueue.push(data);
+    }
+    NotifyMe();
+}
+
+void SocketManager::NotifyMe() {
+    TEMP_FAILURE_RETRY(write(m_notifyMe[1], "You have message ;-)", 1));
+}
+
+void SocketManager::ProcessQueue() {
+    WriteBuffer buffer;
+    WriteData data;
+    {
+        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;
+            }
+
+            if (desc.useSendMsg) {
+                LogError("Some service tried to push rawdata to socket that usees sendmsg!");
+                continue;
+            }
+
+            std::copy(
+                buffer.rawBuffer.begin(),
+                buffer.rawBuffer.end(),
+                std::back_inserter(desc.rawBuffer));
+
+            FD_SET(buffer.connectionID.sock, &m_writeSet);
+        }
+
+        while(!m_writeDataQueue.empty()) {
+            data = m_writeDataQueue.front();
+            m_writeDataQueue.pop();
+
+            auto &desc = m_socketDescriptionVector[data.connectionID.sock];
+
+            if (!desc.isOpen) {
+                LogDebug("Received packet for sendmsg but connection is closed. Packet ignored!");
+                continue;
+            }
+
+            if (desc.counter != data.connectionID.counter)
+            {
+                LogDebug("Received packet for write but counter is broken. Packet ignored!");
+                continue;
+            }
+
+            if (!desc.useSendMsg) {
+                LogError("Some service tries to push SendMsgData to socket that uses write!");
+                continue;
+            }
+
+            desc.sendMsgDataQueue.push(data.sendMsgData);
+
+            FD_SET(data.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();
+    while(!desc.sendMsgDataQueue.empty())
+        desc.sendMsgDataQueue.pop();
+
+    if (service)
+        service->Event(event);
+    else
+        LogError("Critical! Service is NULL! This should never happen!");
+
+    TEMP_FAILURE_RETRY(close(sock));
+    FD_CLR(sock, &m_readSet);
+    FD_CLR(sock, &m_writeSet);
+}
+
+} // namespace AuthPasswd
diff --git a/src/server/service/include/password-exception.h b/src/server/service/include/password-exception.h
new file mode 100644 (file)
index 0000000..417ce1e
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        password-exception.h
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @version     1.0
+ * @brief       Definition of PasswordException class.
+ */
+
+#ifndef _PASSWORD_EXCEPTION_H_
+#define _PASSWORD_EXCEPTION_H_
+
+#include <dpl/exception.h>
+
+namespace AuthPasswd
+{
+    class PasswordException
+    {
+    public:
+        DECLARE_EXCEPTION_TYPE(AuthPasswd::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, OutOfData)
+        DECLARE_EXCEPTION_TYPE(Base, NoData)
+        DECLARE_EXCEPTION_TYPE(Base, FStreamOpenError)
+        DECLARE_EXCEPTION_TYPE(Base, FStreamWriteError)
+        DECLARE_EXCEPTION_TYPE(Base, FStreamReadError)
+        DECLARE_EXCEPTION_TYPE(Base, MemoryError)
+        DECLARE_EXCEPTION_TYPE(Base, NoPasswords)
+        DECLARE_EXCEPTION_TYPE(Base, PasswordNotActive)
+        DECLARE_EXCEPTION_TYPE(Base, MakeDirError)
+               DECLARE_EXCEPTION_TYPE(Base, ChmodError)
+               DECLARE_EXCEPTION_TYPE(Base, RemoveError)
+        DECLARE_EXCEPTION_TYPE(Base, TimerError)
+    };
+} //namespace AuthPasswd
+
+#endif //_PASSWORD_EXCEPTION_H_
diff --git a/src/server/service/include/password-file-buffer.h b/src/server/service/include/password-file-buffer.h
new file mode 100644 (file)
index 0000000..10375b3
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        password-file-buffer.h
+ * @author      Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @version     1.0
+ * @brief       Implementation of password file buffer, used for serialization in password-manager.h
+ */
+
+#ifndef _PASSWORD_FILE_BUFFER_H_
+#define _PASSWORD_FILE_BUFFER_H_
+
+#include <stddef.h>
+#include <vector>
+#include <string>
+
+#include <dpl/serialization.h>
+
+namespace AuthPasswd
+{
+    class PasswordFileBuffer: public IStream
+    {
+    public:
+        PasswordFileBuffer();
+
+        virtual void Read(size_t num, void *bytes);
+        virtual void Write(size_t num, const void *bytes);
+
+        void Save(const std::string &path);
+        void Load(const std::string &path);
+
+    private:
+        typedef std::vector<char> DataBuffer;
+
+        DataBuffer m_buffer;
+        size_t m_bufferReadBytes;
+    };
+} //namespace AuthPasswd
+
+#endif
diff --git a/src/server/service/include/password-file.h b/src/server/service/include/password-file.h
new file mode 100644 (file)
index 0000000..9b18365
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        password-file.h
+ * @author      Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @author      Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
+ * @author      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of PasswordFile, used to manage password files.
+ */
+#ifndef _PASSWORD_FILE_H_
+#define _PASSWORD_FILE_H_
+
+#include <string>
+#include <vector>
+#include <list>
+#include <chrono>
+#include <memory>
+
+#include <time.h>
+
+#include <dpl/serialization.h>
+
+namespace AuthPasswd
+{
+    extern const time_t PASSWORD_INFINITE_EXPIRATION_TIME;
+
+    struct IPassword: public ISerializable
+    {
+        typedef std::vector<unsigned char> RawHash;
+
+        enum class PasswordType : unsigned int
+        {
+            NONE = 0,
+            SHA256 = 1,
+        };
+
+        virtual bool match(const std::string &password) const = 0;
+    };
+
+    typedef std::shared_ptr<IPassword> IPasswordPtr;
+    typedef std::list<IPasswordPtr> PasswordList;
+
+    class PasswordFile
+    {
+    public:
+        PasswordFile(const unsigned int user);
+
+        void writeMemoryToFile() const;
+        void writeAttemptToFile() const;
+
+        void setPassword(const unsigned int passwdType, const std::string &password);
+        bool checkPassword(const unsigned int passwdType, const std::string &password) const;
+
+        bool isPasswordActive(const unsigned int passwdType) const;
+
+        void setMaxHistorySize(unsigned int history);
+        unsigned int getMaxHistorySize() const;
+
+        unsigned int getExpireTimeLeft() const;
+        void setExpireTime(time_t expireTime);
+
+        //attempt manipulating functions
+        unsigned int getAttempt() const;
+        void resetAttempt();
+        void incrementAttempt();
+        int getMaxAttempt() const;
+        void setMaxAttempt(unsigned int maxAttempt);
+
+        bool isPasswordReused(const std::string &password) const;
+
+        bool checkExpiration() const;
+        bool checkIfAttemptsExceeded() const;
+        bool isIgnorePeriod() const;
+
+        bool isHistoryActive() const;
+
+    private:
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ >= 7))
+        typedef std::chrono::steady_clock ClockType;
+#else
+        typedef std::chrono::monotonic_clock ClockType;
+#endif
+        typedef std::chrono::duration<double> TimeDiff;
+        typedef std::chrono::time_point<ClockType, TimeDiff> TimePoint;
+
+        void loadMemoryFromFile();
+        bool tryLoadMemoryFromOldFormatFile();
+
+        void resetTimer();
+        void preparePwdFile();
+        void prepareAttemptFile();
+        void resetState();
+        bool fileExists(const std::string &filename) const;
+        bool dirExists(const std::string &dirpath) const;
+        std::string createDir(const std::string &dir, const unsigned int user) const;
+
+        mutable TimePoint m_retryTimerStart;
+
+        //user name
+        const unsigned int m_user;
+
+        //password file data
+        IPasswordPtr m_passwordCurrent;
+        IPasswordPtr m_passwordRecovery;
+        PasswordList m_passwordHistory;
+        unsigned int m_maxAttempt;
+        unsigned int m_maxHistorySize;
+        time_t       m_expireTime;
+        bool         m_passwordActive;
+        bool         m_passwordRcvActive;
+
+        //attempt file data
+        unsigned int m_attempt;
+    };
+}    //namespace AuthPasswd
+
+#endif
diff --git a/src/server/service/include/password-manager.h b/src/server/service/include/password-manager.h
new file mode 100644 (file)
index 0000000..4832b57
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        password-manager.h
+ * @author      Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @author      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of password management functions
+ */
+
+#ifndef _PASSWORDMANAGER_H_
+#define _PASSWORDMANAGER_H_
+
+#include <string>
+#include <map>
+
+#include <password-file.h>
+
+namespace AuthPasswd
+{
+    class PasswordManager
+    {
+    public:
+        typedef std::map<unsigned int, PasswordFile> PasswordFileMap;
+
+        //checking functions
+        //no const in checkPassword, attempts are update
+        int checkPassword(const unsigned int passwdType, const std::string& challenge,
+                          const unsigned int currentUser, unsigned int &currentAttempt,
+                          unsigned int &maxAttempt, unsigned int &expirationTime);
+        int isPwdValid(const unsigned int passwdType, const unsigned int currentUser,
+                       unsigned int &currentAttempt, unsigned int &maxAttempt,
+                       unsigned int &expirationTime);
+        int isPwdReused(const unsigned int passwdType, const std::string &passwd, 
+                        const unsigned int currentUser, bool &isReused);
+
+        //setting functions
+        int setPassword(const unsigned int passwdType, const std::string &currentPassword,
+                        const std::string &newPassword, const unsigned int currentUser,
+                        const unsigned int receivedAttempts, const unsigned int receivedDays,
+                        const unsigned int receivedHistory);
+        int setPasswordRecovery(const std::string &curRcvPassword, const std::string &newPassword,
+                        const unsigned int currentUser, const unsigned int receivedAttempts,
+                        const unsigned int receivedDays, const unsigned int receivedHistory);
+
+        //resetting functions
+        int resetPassword(const unsigned int passwdType, const std::string &newPassword,
+                          const unsigned int receivedUser, const unsigned int receivedAttempts,
+                          const unsigned int receivedDays, const unsigned int receivedHistory);
+
+        //setting policy on the current passwd
+        int setPasswordMaxAttempts(const unsigned int receivedUser,
+                                   const unsigned int receivedAttempts);
+        int setPasswordValidity(const unsigned int receivedUser, const unsigned int receivedDays);
+        int setPasswordHistory(const unsigned int receivedUser, const unsigned int receivedHistory);
+
+    private:
+        //managing functions
+        void addPassword(const unsigned int user);
+        void removePassword(const unsigned int user);
+        void existPassword(const unsigned int user);
+
+        PasswordFileMap m_pwdFile;
+    };
+} //namespace AuthPasswd
+
+#endif
diff --git a/src/server/service/include/password.h b/src/server/service/include/password.h
new file mode 100644 (file)
index 0000000..1f69592
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        password.h
+ * @author      Zigniew Jasinski (z.jasinski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @author      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of password service
+ */
+
+#ifndef _PASSWORD_H_
+#define _PASSWORD_H_
+
+#include <map>
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+#include <message-buffer.h>
+#include <connection-info.h>
+#include <protocols.h>
+#include <policy.h>
+
+#include <password-manager.h>
+
+namespace AuthPasswd
+{
+    class PasswordService
+      : public AuthPasswd::GenericSocketService
+      , public AuthPasswd::ServiceThread<PasswordService>
+    {
+    public:
+        class Exception
+        {
+        public:
+            DECLARE_EXCEPTION_TYPE(AuthPasswd::Exception, Base)
+            DECLARE_EXCEPTION_TYPE(Base, IncorrectHeader)
+        };
+
+        //service functions
+        ServiceDescriptionVector GetServiceDescription();
+
+        void Start();
+        void Stop();
+
+        DECLARE_THREAD_EVENT(AcceptEvent, accept)
+        DECLARE_THREAD_EVENT(WriteEvent, write)
+        DECLARE_THREAD_EVENT(ReadEvent, process)
+        DECLARE_THREAD_EVENT(CloseEvent, close)
+
+        void accept(const AcceptEvent &event);
+        void write(const WriteEvent &event);
+        void process(const ReadEvent &event);
+        void close(const CloseEvent &event);
+
+    private:
+        //internal service functions
+        bool processOne(const ConnectionID &conn, MessageBuffer &buffer, InterfaceID interfaceID);
+        int processCheckFunctions(PasswordHdrs hdr, MessageBuffer& buffer,
+                                  const unsigned int cur_user, unsigned int &cur_att,
+                                  unsigned int &max_att, unsigned int &exp_time);
+        int processSetFunctions(PasswordHdrs hdr, MessageBuffer& buffer,
+                                const unsigned int cur_user, bool &isPwdReused);
+        int processResetFunctions(PasswordHdrs hdr, MessageBuffer& buffer);
+        int processPolicyFunctions(PasswordHdrs hdr, MessageBuffer& buffer);
+
+        // service attributes
+        PasswordManager m_pwdManager;
+        ConnectionInfoMap m_connectionInfoMap;
+    };
+} // namespace AuthPasswd
+
+#endif // _PASSWORD_H_
diff --git a/src/server/service/password-file-buffer.cpp b/src/server/service/password-file-buffer.cpp
new file mode 100644 (file)
index 0000000..feefec2
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        password-file-buffer.h
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @version     1.0
+ * @brief       Implementation of PasswordFileBuffer, used for serialization in PasswordFile class
+ */
+
+#include <password-file-buffer.h>
+
+#include <fstream>
+#include <iterator>
+
+#include <dpl/log/log.h>
+#include <dpl/fstream_accessors.h>
+
+#include <auth-passwd-error.h>
+#include <password-exception.h>
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+
+namespace AuthPasswd
+{
+    PasswordFileBuffer::PasswordFileBuffer(): m_bufferReadBytes(0) {}
+
+    void PasswordFileBuffer::Read(size_t num, void *bytes)
+    {
+        if(m_buffer.empty()) {
+            LogError("Buffer doesn't contain any data.");
+            Throw(PasswordException::NoData);
+        }
+
+        if((m_bufferReadBytes + num) > m_buffer.size()) {
+            LogError("Not enough buffer to read " << num << " data.");
+            Throw(PasswordException::OutOfData);
+        }
+
+        void* ret = memcpy(bytes, &m_buffer[m_bufferReadBytes], num);
+
+        if(ret == 0) {
+            LogError("Failed to read " << num << " bytes.");
+            Throw(PasswordException::MemoryError);
+        }
+
+        m_bufferReadBytes += num;
+    }
+
+    void PasswordFileBuffer::Write(size_t num, const void *bytes)
+    {
+        const char* buffer = static_cast<const char*>(bytes);
+        std::copy(buffer, buffer+num, std::back_inserter(m_buffer));
+    }
+
+    void PasswordFileBuffer::Save(const std::string &path)
+    {
+        std::ofstream file(path, std::ofstream::trunc);
+
+        if(!file.good()) {
+            LogError("Error while opening file stream.");
+            Throw(PasswordException::FStreamOpenError);
+        }
+
+        file.write(m_buffer.data(), m_buffer.size());
+        if(!file) {
+            LogError("Failed to write data.");
+            Throw(PasswordException::FStreamWriteError);
+        }
+
+        file.flush();
+        fsync(DPL::FstreamAccessors<std::ofstream>::GetFd(file)); // flush kernel space buffer
+        file.close();
+    }
+
+    void PasswordFileBuffer::Load(const std::string &path)
+    {
+        std::ifstream file(path, std::ifstream::binary);
+
+        if(!file.good()) {
+            LogError("Error while opening file stream.");
+            Throw(PasswordException::FStreamOpenError);
+        }
+
+        //reset read bytes counter
+        m_bufferReadBytes = 0;
+
+        m_buffer.assign(std::istreambuf_iterator<char>(file),
+                        std::istreambuf_iterator<char>());
+
+        if(!file) {
+            LogError("Failed to read data. Failbit: " << file.fail() << ", Badbit: " << file.bad());
+            Throw(PasswordException::FStreamReadError);
+        }
+    }
+
+} //namespace AuthPasswd
diff --git a/src/server/service/password-file.cpp b/src/server/service/password-file.cpp
new file mode 100644 (file)
index 0000000..22a768d
--- /dev/null
@@ -0,0 +1,574 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        password-file.cpp
+ * @author      Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @author      Piotr Bartosiewicz (p.bartosiewi@partner.samsung.com)
+ * @author      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of PasswordFile, used to manage password files.
+ */
+#include <password-file.h>
+
+#include <fstream>
+#include <algorithm>
+#include <limits>
+
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <tzplatform_config.h>
+#include <openssl/sha.h>
+
+#include <dpl/log/log.h>
+#include <dpl/fstream_accessors.h>
+
+#include <auth-passwd-policy-types.h>
+#include <auth-passwd-error.h>
+
+#include <error-description.h>
+#include <protocols.h>
+#include <password-exception.h>
+#include <password-file-buffer.h>
+
+namespace {
+    const std::string DATA_DIR = tzplatform_mkpath(TZ_SYS_DATA, "authentication-server");
+    const std::string PASSWORD_FILE = "/password";
+    const std::string OLD_VERSION_PASSWORD_FILE = "/password.old";
+    const std::string ATTEMPT_FILE = "/attempt";
+    const double RETRY_TIMEOUT = 0.5;
+    const mode_t FILE_MODE = S_IRUSR | S_IWUSR;
+    const unsigned int CURRENT_FILE_VERSION = 1;
+} // namespace anonymous
+
+namespace AuthPasswd
+{
+    const time_t PASSWORD_INFINITE_EXPIRATION_TIME = std::numeric_limits<time_t>::max();
+
+    class NoPassword: public IPassword
+    {
+        public:
+            NoPassword(IStream&) {}
+            NoPassword() {}
+
+            void Serialize(IStream &stream) const
+            {
+                Serialization::Serialize(stream, static_cast<unsigned int>(PasswordType::NONE));
+            }
+
+            bool match(const std::string &pass) const
+            {
+                return pass.empty();
+            }
+    };
+
+    class SHA256Password: public IPassword
+    {
+        public:
+            SHA256Password(IStream& stream)
+            {
+                Deserialization::Deserialize(stream, m_hash);
+            }
+
+            SHA256Password(const std::string &password)
+                : m_hash(hash(password)) {}
+
+            SHA256Password(const RawHash& paramHash)
+                : m_hash(paramHash) {}
+
+            void Serialize(IStream &stream) const
+            {
+                Serialization::Serialize(stream, static_cast<unsigned int>(PasswordType::SHA256));
+                Serialization::Serialize(stream, m_hash);
+            }
+
+            bool match(const std::string &password) const
+            {
+                return m_hash == hash(password);
+            }
+        private:
+            RawHash m_hash;
+
+            static RawHash hash(const std::string &password)
+            {
+                RawHash result(SHA256_DIGEST_LENGTH);
+
+                SHA256_CTX context;
+                SHA256_Init(&context);
+                SHA256_Update(&context, reinterpret_cast<const unsigned char*>(password.c_str()),
+                        password.size());
+                SHA256_Final(result.data(), &context);
+
+                return result;
+            }
+    };
+
+    // deserialization of new password format
+    template <>
+    void Deserialization::Deserialize(IStream& stream, IPasswordPtr& ptr)
+    {
+        unsigned int algorithm;
+        Deserialization::Deserialize(stream, algorithm);
+        switch (algorithm) {
+            case (unsigned int)IPassword::PasswordType::NONE:
+                ptr.reset(new NoPassword());
+                break;
+            case (unsigned int)IPassword::PasswordType::SHA256:
+                ptr.reset(new SHA256Password(stream));
+                break;
+            default:
+                Throw(PasswordException::FStreamReadError);
+        }
+    }
+
+    PasswordFile::PasswordFile(const unsigned int user): m_user(user),
+                                  m_passwordCurrent(new NoPassword()),
+                                  m_passwordRecovery(new NoPassword()),
+                                  m_maxAttempt(PASSWORD_INFINITE_ATTEMPT_COUNT),
+                                  m_maxHistorySize(0),
+                                  m_expireTime(PASSWORD_INFINITE_EXPIRATION_TIME),
+                                  m_passwordActive(false),
+                                  m_passwordRcvActive(false),
+                                  m_attempt(0)
+    {
+        // check if data directory exists
+        // if not create it
+
+        std::string userDir = createDir(DATA_DIR.c_str(), m_user);
+
+        if (!dirExists(DATA_DIR.c_str())) {
+            if(mkdir(DATA_DIR.c_str(), 0700)) {
+                LogError("Failed to create directory for files. Error: " << strerror(errno));
+                Throw(PasswordException::MakeDirError);
+            }
+        }
+
+        if (!dirExists(userDir.c_str())) {
+            if(mkdir(userDir.c_str(), 0700)) {
+                LogError("Failed to create directory for files. Error: " << strerror(errno));
+                Throw(PasswordException::MakeDirError);
+            }
+        }
+
+        preparePwdFile();
+        prepareAttemptFile();
+        resetTimer();
+    }
+
+    void PasswordFile::resetState()
+    {
+        m_maxAttempt = PASSWORD_INFINITE_ATTEMPT_COUNT;
+        m_maxHistorySize = 0;
+        m_expireTime = PASSWORD_INFINITE_EXPIRATION_TIME;
+        m_passwordRcvActive = false;
+        m_passwordRecovery.reset(new NoPassword());
+        m_passwordActive = false;
+        m_passwordCurrent.reset(new NoPassword());
+    }
+
+    void PasswordFile::resetTimer()
+    {
+        m_retryTimerStart = ClockType::now();
+        m_retryTimerStart -= TimeDiff(RETRY_TIMEOUT);
+    }
+
+    void PasswordFile::preparePwdFile()
+    {
+        std::string pwdFile = createDir(DATA_DIR.c_str(), m_user) + PASSWORD_FILE;
+        std::string oldVersionPwdFile = createDir(DATA_DIR.c_str(), m_user) + OLD_VERSION_PASSWORD_FILE;
+
+        // check if password file exists
+        if (!fileExists(pwdFile)) {
+            // if old format file exist - load it
+            if (tryLoadMemoryFromOldFormatFile()) {
+                // save in new format
+                writeMemoryToFile();
+                // and remove old file
+                if (remove(oldVersionPwdFile.c_str())) {
+                    LogError("Failed to remove file" << oldVersionPwdFile <<
+                             " Error: " << strerror(errno));
+                    Throw(PasswordException::RemoveError);
+                }
+                return;
+            }
+            LogSecureDebug("PWD_DBG not found " << m_user << " password file. Creating.");
+
+            //create file
+            writeMemoryToFile();
+        } else {     //if file exists, load data
+            LogSecureDebug("PWD_DBG found " << m_user << " password file. Opening.");
+            try {
+                loadMemoryFromFile();
+            } catch (...) {
+                LogError("Invalid " << pwdFile << " file format");
+                resetState();
+                writeMemoryToFile();
+            }
+        }
+    }
+
+    void PasswordFile::prepareAttemptFile()
+    {
+        std::string attemptFile = createDir(DATA_DIR.c_str(), m_user) + ATTEMPT_FILE;
+
+        // check if attempt file exists
+        // if not create it
+        if (!fileExists(attemptFile)) {
+            LogSecureDebug("PWD_DBG not found " << m_user << " attempt file. Creating.");
+            writeAttemptToFile();
+        } else {
+            LogSecureDebug("PWD_DBG found " << m_user << " attempt file. Opening.");
+            std::ifstream AttemptFile(attemptFile);
+            if(!AttemptFile) {
+                LogError("Failed to open " << m_user << " attempt file.");
+                // ignore error
+                return;
+            }
+
+            AttemptFile.read(reinterpret_cast<char*>(&m_attempt), sizeof(unsigned int));
+            if(!AttemptFile) {
+                LogError("Failed to read " << m_user <<" attempt count.");
+                // ignore error
+                resetAttempt();
+            }
+        }
+    }
+
+    bool PasswordFile::fileExists(const std::string &filename) const
+    {
+        struct stat buf;
+
+        return ((stat(filename.c_str(), &buf) == 0));
+    }
+
+    bool PasswordFile::dirExists(const std::string &dirpath) const
+    {
+        struct stat buf;
+
+        return ((stat(dirpath.c_str(), &buf) == 0) && (((buf.st_mode) & S_IFMT) == S_IFDIR));
+    }
+
+    std::string PasswordFile::createDir(const std::string &dir, const unsigned int user) const
+    {
+        std::string User = std::to_string(user);
+        return dir + "/" + User;
+    }
+
+    void PasswordFile::writeMemoryToFile() const
+    {
+        PasswordFileBuffer pwdBuffer;
+
+        LogSecureDebug("User: " << m_user << ", saving max_att: " << m_maxAttempt <<
+                       ", history_size: " << m_maxHistorySize << ", m_expireTime: " <<
+                       m_expireTime << ", isActive: " << m_passwordActive << 
+                       ", isRcvActive: " << m_passwordRcvActive);
+
+        //serialize password attributes
+        Serialization::Serialize(pwdBuffer, CURRENT_FILE_VERSION);
+        Serialization::Serialize(pwdBuffer, m_maxAttempt);
+        Serialization::Serialize(pwdBuffer, m_maxHistorySize);
+        Serialization::Serialize(pwdBuffer, m_expireTime);
+        Serialization::Serialize(pwdBuffer, m_passwordRcvActive);
+        Serialization::Serialize(pwdBuffer, m_passwordRecovery);
+        Serialization::Serialize(pwdBuffer, m_passwordActive);
+        Serialization::Serialize(pwdBuffer, m_passwordCurrent);
+        Serialization::Serialize(pwdBuffer, m_passwordHistory);
+
+        std::string pwdFile = createDir(DATA_DIR.c_str(), m_user) + PASSWORD_FILE;
+        pwdBuffer.Save(pwdFile);
+
+        if (chmod(pwdFile.c_str(), FILE_MODE)) {
+            LogError("Failed to chmod for " << pwdFile << " Error: " << strerror(errno));
+            Throw(PasswordException::ChmodError);
+        }
+    }
+
+    void PasswordFile::loadMemoryFromFile()
+    {
+        PasswordFileBuffer pwdBuffer;
+        std::string pwdFile = createDir(DATA_DIR.c_str(), m_user) + PASSWORD_FILE;
+
+        pwdBuffer.Load(pwdFile);
+
+        unsigned int fileVersion = 0;
+        Deserialization::Deserialize(pwdBuffer, fileVersion);
+        if (fileVersion != CURRENT_FILE_VERSION)
+            Throw(PasswordException::FStreamReadError);
+
+        m_passwordHistory.clear();
+
+        Deserialization::Deserialize(pwdBuffer, m_maxAttempt);
+        Deserialization::Deserialize(pwdBuffer, m_maxHistorySize);
+        Deserialization::Deserialize(pwdBuffer, m_expireTime);
+        Deserialization::Deserialize(pwdBuffer, m_passwordRcvActive);
+        Deserialization::Deserialize(pwdBuffer, m_passwordRecovery);
+        Deserialization::Deserialize(pwdBuffer, m_passwordActive);
+        Deserialization::Deserialize(pwdBuffer, m_passwordCurrent);
+        Deserialization::Deserialize(pwdBuffer, m_passwordHistory);
+
+        LogSecureDebug("User: " << m_user << ", loaded max_att: " << m_maxAttempt <<
+                       ", history_size: " << m_maxHistorySize << ", m_expireTime: " <<
+                       m_expireTime << ", isActive: " << m_passwordActive <<
+                       ", isRcvActive: " << m_passwordRcvActive);
+    }
+
+    bool PasswordFile::tryLoadMemoryFromOldFormatFile()
+    {
+        struct stat oldFileStat;
+        std::string oldVersionPwdFile = createDir(DATA_DIR.c_str(), m_user) + OLD_VERSION_PASSWORD_FILE;
+
+        if (stat(oldVersionPwdFile.c_str(), &oldFileStat) != 0)
+            return false;
+
+        static const int ELEMENT_SIZE = sizeof(unsigned) + SHA256_DIGEST_LENGTH;
+        static const int VERSION_1_REMAINING = sizeof(unsigned) * 4;
+        static const int VERSION_2_REMAINING = VERSION_1_REMAINING + sizeof(bool);
+        int remaining = oldFileStat.st_size % ELEMENT_SIZE;
+
+        if (remaining != VERSION_1_REMAINING && remaining != VERSION_2_REMAINING)
+            return false;
+
+        try {
+            PasswordFileBuffer pwdBuffer;
+            pwdBuffer.Load(oldVersionPwdFile);
+
+            Deserialization::Deserialize(pwdBuffer, m_maxAttempt);
+            Deserialization::Deserialize(pwdBuffer, m_maxHistorySize);
+            Deserialization::Deserialize(pwdBuffer, m_expireTime);
+            if (m_expireTime == 0)
+                m_expireTime = PASSWORD_INFINITE_EXPIRATION_TIME;
+
+            if (remaining == VERSION_2_REMAINING)
+                Deserialization::Deserialize(pwdBuffer, m_passwordActive);
+            else
+                m_passwordActive = true;
+
+            // deserialize passwords in old format
+            struct OldPassword {
+                OldPassword() {}
+                OldPassword(IStream &stream)
+                {
+                    Deserialization::Deserialize(stream, m_hash);
+                }
+                IPassword::RawHash m_hash;
+            };
+            std::list<OldPassword> oldFormatPasswords;
+            Deserialization::Deserialize(pwdBuffer, oldFormatPasswords);
+
+            // convert passwords to new format
+            m_passwordHistory.clear();
+            if (oldFormatPasswords.empty()) {
+                m_passwordCurrent.reset(new NoPassword());
+                m_passwordActive = false;
+            } else {
+                m_passwordCurrent.reset(new SHA256Password(oldFormatPasswords.front().m_hash));
+                std::for_each(++oldFormatPasswords.begin(), oldFormatPasswords.end(),
+                    [&] (const OldPassword& pwd)
+                    {m_passwordHistory.push_back(IPasswordPtr(new SHA256Password(pwd.m_hash)));}
+                    );
+            }
+
+            m_passwordRcvActive = false;
+            m_passwordRecovery.reset(new NoPassword());
+
+        } catch (...) {
+            LogWarning("Invalid " << oldVersionPwdFile << " file format");
+            resetState();
+            return false;
+        }
+
+        return true;
+    }
+
+    void PasswordFile::writeAttemptToFile() const
+    {
+        std::string attemptFile = createDir(DATA_DIR.c_str(), m_user) + ATTEMPT_FILE;
+
+        std::ofstream AttemptFile(attemptFile, std::ofstream::trunc);
+
+        if(!AttemptFile.good()) {
+            LogError("Failed to open " << m_user << " attempt file.");
+            Throw(PasswordException::FStreamOpenError);
+        }
+
+        AttemptFile.write(reinterpret_cast<const char*>(&m_attempt), sizeof(unsigned int));
+        if(!AttemptFile) {
+            LogError("Failed to write " << m_user << " attempt count.");
+            Throw(PasswordException::FStreamWriteError);
+        }
+
+        AttemptFile.flush();
+        fsync(DPL::FstreamAccessors<std::ofstream>::GetFd(AttemptFile)); // flush kernel space buffer
+        AttemptFile.close();
+    }
+
+    bool PasswordFile::isPasswordActive(const unsigned int passwdType) const
+    {
+        bool ret = false;
+
+        if (passwdType == AUTH_PWD_NORMAL)
+            ret = m_passwordActive;
+        else if (passwdType == AUTH_PWD_RECOVERY)
+            ret = m_passwordRcvActive;
+        return ret;
+    }
+
+    void PasswordFile::setMaxHistorySize(unsigned int history)
+    {
+        // put current password in history
+        if (m_maxHistorySize == 0 && history > 0)
+            m_passwordHistory.push_front(m_passwordCurrent);
+
+        //setting history should be independent from password being set
+        m_maxHistorySize = history;
+
+        while(m_passwordHistory.size() > history)
+            m_passwordHistory.pop_back();
+    }
+
+    unsigned int PasswordFile::getMaxHistorySize() const
+    {
+        return m_maxHistorySize;
+    }
+
+    unsigned int PasswordFile::getAttempt() const
+    {
+        return m_attempt;
+    }
+
+    void PasswordFile::resetAttempt()
+    {
+        m_attempt = 0;
+    }
+
+    void PasswordFile::incrementAttempt()
+    {
+        m_attempt++;
+    }
+
+    int PasswordFile::getMaxAttempt() const
+    {
+        return m_maxAttempt;
+    }
+
+    void PasswordFile::setMaxAttempt(unsigned int maxAttempt)
+    {
+        m_maxAttempt = maxAttempt;
+    }
+
+    bool PasswordFile::isPasswordReused(const std::string &password) const
+    {
+        LogSecureDebug("Checking if " << m_user << " pwd is reused. HistorySize: " <<
+                       m_passwordHistory.size() << ", MaxHistorySize: " << getMaxHistorySize());
+
+        //go through history and check if password existed earlier
+        if(std::any_of(m_passwordHistory.begin(), m_passwordHistory.end(),
+                      [&password](const IPasswordPtr& pwd) { return pwd->match(password); })) {
+            LogSecureDebug(m_user << " passwords match!");
+            return true;
+        }
+
+        LogSecureDebug("isPasswordReused: No passwords match, " << m_user <<
+                       " password not reused.");
+        return false;
+    }
+
+    void PasswordFile::setPassword(const unsigned int passwdType, const std::string &password)
+    {
+        if (passwdType == AUTH_PWD_NORMAL) {
+            //replace current password with new one
+            if (password.empty()) {
+                m_passwordCurrent.reset(new NoPassword());
+                m_passwordActive = false;
+            } else {
+                m_passwordCurrent.reset(new SHA256Password(password));
+
+                //put current password to history
+                m_passwordHistory.push_front(m_passwordCurrent);
+
+                //erase last password if we exceed max history size
+                if(m_passwordHistory.size() > getMaxHistorySize())
+                    m_passwordHistory.pop_back();
+                m_passwordActive = true;
+            }
+        } else if (passwdType == AUTH_PWD_RECOVERY) {
+            //replace current password with new one
+            if (password.empty()) {
+                m_passwordRecovery.reset(new NoPassword());
+                m_passwordRcvActive = false;
+            } else {
+                m_passwordRecovery.reset(new SHA256Password(password));
+                m_passwordRcvActive = true;
+            }
+        }
+    }
+
+    bool PasswordFile::checkPassword(const unsigned int passwdType, const std::string &password) const
+    {
+        bool ret = false;
+        if (passwdType == AUTH_PWD_NORMAL)
+            ret = m_passwordCurrent->match(password);
+        else if (passwdType == AUTH_PWD_RECOVERY)
+            ret = m_passwordRecovery->match(password);
+        return ret;
+    }
+
+    void PasswordFile::setExpireTime(time_t expireTime)
+    {
+        m_expireTime = expireTime;
+    }
+
+    unsigned int PasswordFile::getExpireTimeLeft() const
+    {
+        if(m_expireTime != PASSWORD_INFINITE_EXPIRATION_TIME) {
+            time_t timeLeft = m_expireTime - time(NULL);
+            return (timeLeft < 0) ? 0 : static_cast<unsigned int>(timeLeft);
+        } else
+            return PASSWORD_API_NO_EXPIRATION;
+    }
+
+    bool PasswordFile::checkExpiration() const
+    {
+        //return true if expired, else false
+        return ((m_expireTime != PASSWORD_INFINITE_EXPIRATION_TIME) && (time(NULL) > m_expireTime));
+    }
+
+    bool PasswordFile::checkIfAttemptsExceeded() const
+    {
+        return ((m_maxAttempt != PASSWORD_INFINITE_ATTEMPT_COUNT) && (m_attempt > m_maxAttempt));
+    }
+
+    bool PasswordFile::isIgnorePeriod() const
+    {
+        TimePoint retryTimerStop = ClockType::now();
+        TimeDiff diff = retryTimerStop - m_retryTimerStart;
+
+        m_retryTimerStart = retryTimerStop;
+
+        return (diff.count() < RETRY_TIMEOUT);
+    }
+
+    bool PasswordFile::isHistoryActive() const
+    {
+        return (m_maxHistorySize != 0);
+    }
+} //namespace AuthPasswd
+
diff --git a/src/server/service/password-manager.cpp b/src/server/service/password-manager.cpp
new file mode 100644 (file)
index 0000000..2cc39f2
--- /dev/null
@@ -0,0 +1,482 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        password-manager.cpp
+ * @author      Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @author      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of password management functions
+ */
+
+#include <password-manager.h>
+
+#include <iostream>
+#include <iterator>
+#include <algorithm>
+
+#include <limits.h>
+
+#include <dpl/log/log.h>
+
+#include <auth-passwd-policy-types.h>
+#include <auth-passwd-error.h>
+
+#include <protocols.h>
+
+namespace {
+    bool calculateExpiredTime(unsigned int receivedDays, time_t &validSecs)
+    {
+        validSecs = AuthPasswd::PASSWORD_INFINITE_EXPIRATION_TIME;
+
+        //when receivedDays means infinite expiration, return default validSecs value.
+        if(receivedDays == AuthPasswd::PASSWORD_INFINITE_EXPIRATION_DAYS)
+            return true;
+
+        time_t curTime = time(NULL);
+
+        if (receivedDays > ((UINT_MAX - curTime) / 86400)) {
+            LogError("Incorrect input param.");
+            return false;
+        } else {
+            validSecs = (curTime + (receivedDays * 86400));
+            return true;
+        }
+    }
+} //namespace
+
+namespace AuthPasswd
+{
+    void PasswordManager::addPassword(const unsigned int user)
+    {
+        m_pwdFile.insert(PasswordFileMap::value_type(user, PasswordFile(user)));
+    }
+
+    void PasswordManager::removePassword(const unsigned int user)
+    {
+        m_pwdFile.erase(user);
+    }
+
+    void PasswordManager::existPassword(const unsigned int user)
+    {
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(user);
+        if (itPwd != m_pwdFile.end())
+            return;
+
+        addPassword(user);
+        return;
+    }
+
+    int PasswordManager::checkPassword(const unsigned int passwdType,
+                                       const std::string &challenge,
+                                       const unsigned int currentUser,
+                                       unsigned int &currentAttempt,
+                                       unsigned int &maxAttempt,
+                                       unsigned int &expirationTime)
+    {
+        LogSecureDebug("Inside checkPassword function.");
+
+        existPassword(currentUser);
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
+
+        if (itPwd->second.isIgnorePeriod()) {
+            LogError("Retry timeout occurred.");
+            return AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER;
+        }
+        if (!itPwd->second.isPasswordActive(passwdType) && !challenge.empty()) {
+            LogError("Password not active.");
+            return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
+        }
+
+        switch(passwdType) {
+            case AUTH_PWD_NORMAL:
+
+                itPwd->second.incrementAttempt();
+                itPwd->second.writeAttemptToFile();
+
+                currentAttempt = itPwd->second.getAttempt();
+                maxAttempt = itPwd->second.getMaxAttempt();
+                expirationTime = itPwd->second.getExpireTimeLeft();
+
+                if (itPwd->second.checkIfAttemptsExceeded()) {
+                    LogError("Too many tries.");
+                    return AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
+                }
+                if (!itPwd->second.checkPassword(AUTH_PWD_NORMAL, challenge)) {
+                    LogError("Wrong password.");
+                    return AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH;
+                }
+
+                // Password maches and attempt number is fine - time to reset counter.
+                itPwd->second.resetAttempt();
+                itPwd->second.writeAttemptToFile();
+
+                // Password is too old. You must change it before login.
+                if (itPwd->second.checkExpiration()) {
+                    LogError("Password expired.");
+                    return AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED;
+                }
+                break;
+            
+            case AUTH_PWD_RECOVERY: 
+                if (!itPwd->second.checkPassword(AUTH_PWD_RECOVERY, challenge)) {
+                    LogError("Wrong password.");
+                    return AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH;
+                }
+                break;
+
+            default:
+                LogError("Not supported password type.");
+                return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+
+    int PasswordManager::isPwdValid(const unsigned int passwdType, const unsigned int currentUser,
+                                    unsigned int &currentAttempt, unsigned int &maxAttempt,
+                                    unsigned int &expirationTime)
+    {
+        existPassword(currentUser);
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
+
+        if (!itPwd->second.isPasswordActive(passwdType)) {
+            LogError("Current password not active.");
+            return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
+        }
+
+        switch(passwdType) {
+            case AUTH_PWD_NORMAL:
+                currentAttempt = itPwd->second.getAttempt();
+                maxAttempt = itPwd->second.getMaxAttempt();
+                expirationTime = itPwd->second.getExpireTimeLeft();
+                break;
+
+            case AUTH_PWD_RECOVERY:
+                // there are no maxAttempt and expirationTime for recovery password
+                currentAttempt = PASSWORD_INFINITE_ATTEMPT_COUNT;
+                maxAttempt = PASSWORD_INFINITE_ATTEMPT_COUNT;
+                expirationTime = PASSWORD_API_NO_EXPIRATION;
+                break;
+
+            default:
+                LogError("Not supported password type.");
+                return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+
+    int PasswordManager::isPwdReused(const unsigned int passwdType, const std::string &passwd,
+                                     const unsigned int currentUser, bool &isReused)
+    {
+        existPassword(currentUser);
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
+
+        isReused = false;
+
+        switch(passwdType) {
+            case AUTH_PWD_NORMAL:
+                // check history, however only if history is active and password is not empty
+                if (itPwd->second.isHistoryActive() && !passwd.empty())
+                    isReused = itPwd->second.isPasswordReused(passwd);
+                break;
+
+            case AUTH_PWD_RECOVERY:
+                break;
+
+            default:
+                LogError("Not supported password type.");
+                return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        } 
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+
+    int PasswordManager::setPassword(const unsigned int passwdType, 
+                                     const std::string &currentPassword,
+                                     const std::string &newPassword,
+                                     const unsigned int currentUser,
+                                     const unsigned int receivedAttempts,
+                                     const unsigned int receivedDays,
+                                     const unsigned int receivedHistory)
+    {
+        LogSecureDebug("curUser = " << currentUser << ", pwdType = " << passwdType <<
+                       ", curPwd = " << currentPassword << ", newPwd = " << newPassword <<
+                       ", recAtt = " << receivedAttempts << ", recDays = " << receivedDays <<
+                       ", recHistory = " << receivedHistory);
+
+        time_t valid_secs = 0;
+
+        existPassword(currentUser);
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
+
+        if (itPwd->second.isIgnorePeriod()) {
+            LogError("Retry timeout occured.");
+            return AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER;
+        }
+
+        //check if passwords are correct
+        if (currentPassword.size() > MAX_PASSWORD_LEN) {
+            LogError("Current password length failed.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+        if (newPassword.size() > MAX_PASSWORD_LEN) {
+            LogError("New password length failed.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        // check delivered currentPassword
+        // when m_passwordActive flag is false, current password should be empty
+        if (!currentPassword.empty() && !itPwd->second.isPasswordActive(passwdType)) {
+            LogError("Password not active.");
+            return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
+        }
+
+        switch(passwdType) {
+            case AUTH_PWD_NORMAL:
+                // You remove password and set up recAttempts or recDays
+                if (newPassword.empty() && (receivedAttempts != 0 || receivedDays != 0)) {
+                    LogError("Attempts or receivedDays is not equal 0");
+                    return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+                }
+
+                //increment attempt count before checking it against max attempt count
+                itPwd->second.incrementAttempt();
+                itPwd->second.writeAttemptToFile();
+
+                if (itPwd->second.checkIfAttemptsExceeded()) {
+                    LogError("Too many tries.");
+                    return AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
+                }
+
+                if (!itPwd->second.checkPassword(AUTH_PWD_NORMAL, currentPassword)) {
+                    LogError("Wrong password.");
+                    return AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH;
+                }
+
+                //here we are sure that user knows current password - we can reset attempt counter
+                itPwd->second.resetAttempt();
+                itPwd->second.writeAttemptToFile();
+
+                // check history, however only if history is active and new password is not empty
+                if (itPwd->second.isHistoryActive() && !newPassword.empty()) {
+                    if (itPwd->second.isPasswordReused(newPassword)) {
+                        LogError("Password reused.");
+                        return AUTH_PASSWD_API_ERROR_PASSWORD_REUSED;
+                    }
+                }
+
+                if (!calculateExpiredTime(receivedDays, valid_secs)) {
+                    LogError("Received expiration time incorrect.");
+                    return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+                }
+
+                //setting password
+                itPwd->second.setPassword(AUTH_PWD_NORMAL, newPassword);
+                itPwd->second.setMaxAttempt(receivedAttempts);
+                itPwd->second.setExpireTime(valid_secs);
+                itPwd->second.setMaxHistorySize(receivedHistory);
+                itPwd->second.writeMemoryToFile();
+                break;
+
+            case AUTH_PWD_RECOVERY:
+                if (!itPwd->second.checkPassword(AUTH_PWD_RECOVERY, currentPassword)) {
+                    LogError("Wrong password.");
+                    return AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH;
+                }
+                itPwd->second.setPassword(AUTH_PWD_RECOVERY, newPassword);
+                itPwd->second.writeMemoryToFile();
+                break;
+
+            default:
+                LogError("Not supported password type.");
+                return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+
+    int PasswordManager::setPasswordRecovery(const std::string &curRcvPassword,
+                                             const std::string &newPassword,
+                                             const unsigned int currentUser,
+                                             const unsigned int receivedAttempts,
+                                             const unsigned int receivedDays,
+                                             const unsigned int receivedHistory)
+    {
+        LogSecureDebug("curUser = " << currentUser << ", curPwd = " << curRcvPassword <<
+                       ", newPwd = " << newPassword << ", recAtt = " << receivedAttempts <<
+                       ", recDays = " << receivedDays << ", recHistory = " << receivedHistory);
+
+        time_t valid_secs = 0;
+
+        existPassword(currentUser);
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
+
+        if (itPwd->second.isIgnorePeriod()) {
+            LogError("Retry timeout occured.");
+            return AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER;
+        }
+
+        //check if passwords are correct
+        if (curRcvPassword.size() > MAX_PASSWORD_LEN || curRcvPassword.empty()) {
+            LogError("Current recovery password length failed.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+        if (newPassword.size() > MAX_PASSWORD_LEN || newPassword.empty()) {
+            LogError("New password length failed.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        // current recovery password should be existed.
+        if (!itPwd->second.isPasswordActive(AUTH_PWD_RECOVERY)) {
+            LogError("Password not active.");
+            return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
+        }
+
+        if (!itPwd->second.checkPassword(AUTH_PWD_RECOVERY, curRcvPassword)) {
+            LogError("Wrong password.");
+            return AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH;
+        }
+
+        // check history, however only if history is active and new password is not empty
+        if (itPwd->second.isHistoryActive()) {
+            if (itPwd->second.isPasswordReused(newPassword)) {
+                LogError("Password reused.");
+                return AUTH_PASSWD_API_ERROR_PASSWORD_REUSED;
+            }
+        }
+
+        if (!calculateExpiredTime(receivedDays, valid_secs)) {
+            LogError("Received expiration time incorrect.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        itPwd->second.resetAttempt();
+        itPwd->second.writeAttemptToFile();
+
+        //setting password
+        itPwd->second.setPassword(AUTH_PWD_NORMAL, newPassword);
+        itPwd->second.setMaxAttempt(receivedAttempts);
+        itPwd->second.setExpireTime(valid_secs);
+        itPwd->second.setMaxHistorySize(receivedHistory);
+        itPwd->second.writeMemoryToFile();
+
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+
+    int PasswordManager::resetPassword(const unsigned int passwdType,
+                                       const std::string &newPassword,
+                                       const unsigned int receivedUser,
+                                       const unsigned int receivedAttempts,
+                                       const unsigned int receivedDays,
+                                       const unsigned int receivedHistory)
+    {
+        time_t valid_secs = 0;
+
+        existPassword(receivedUser);
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(receivedUser);
+
+        switch(passwdType) {
+            case AUTH_PWD_NORMAL:
+                if (!calculateExpiredTime(receivedDays, valid_secs))
+                    return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+                if (newPassword.empty() && (receivedAttempts != 0 || receivedDays != 0)) {
+                    LogError("Attempts or receivedDays is not equal 0");
+                    return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+                }
+                itPwd->second.resetAttempt();
+                itPwd->second.writeAttemptToFile();
+                itPwd->second.setPassword(AUTH_PWD_NORMAL, newPassword);
+                itPwd->second.setMaxAttempt(receivedAttempts);
+                itPwd->second.setExpireTime(valid_secs);
+                itPwd->second.setMaxHistorySize(receivedHistory);
+                itPwd->second.writeMemoryToFile();
+                break;
+
+            case AUTH_PWD_RECOVERY:
+                itPwd->second.setPassword(AUTH_PWD_RECOVERY, newPassword);
+                itPwd->second.writeMemoryToFile();
+                break;
+
+            default:
+                LogError("Not supported password type.");
+                return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+
+    int PasswordManager::setPasswordMaxAttempts(const unsigned int receivedUser,
+                                                const unsigned int receivedAttempts)
+    {
+        existPassword(receivedUser);
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(receivedUser);
+
+        // check if there is password
+        if (!itPwd->second.isPasswordActive(AUTH_PWD_NORMAL)) {
+            LogError("Password not active.");
+            return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
+        }
+
+        itPwd->second.setMaxAttempt(receivedAttempts);
+        itPwd->second.writeMemoryToFile();
+
+        itPwd->second.resetAttempt();
+        itPwd->second.writeAttemptToFile();
+
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+
+    int PasswordManager::setPasswordValidity(const unsigned int receivedUser,
+                                             const unsigned int receivedDays)
+    {
+        time_t valid_secs = 0;
+
+        LogSecureDebug("received_days: " << receivedDays);
+
+        existPassword(receivedUser);
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(receivedUser);
+
+        if (!itPwd->second.isPasswordActive(AUTH_PWD_NORMAL)) {
+            LogError("Current password is not active.");
+            return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
+        }
+
+        if (!calculateExpiredTime(receivedDays, valid_secs))
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+        itPwd->second.setExpireTime(valid_secs);
+        itPwd->second.writeMemoryToFile();
+
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+
+    int PasswordManager::setPasswordHistory(const unsigned int receivedUser,
+                                            const unsigned int receivedHistory)
+    {
+        existPassword(receivedUser);
+        PasswordFileMap::iterator itPwd = m_pwdFile.find(receivedUser);
+
+        if (receivedHistory > MAX_PASSWORD_HISTORY) {
+            LogError("Incorrect input param.");
+            return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+        }
+
+        itPwd->second.setMaxHistorySize(receivedHistory);
+        itPwd->second.writeMemoryToFile();
+
+        return AUTH_PASSWD_API_SUCCESS;
+    }
+} //namespace AuthPasswd
diff --git a/src/server/service/password.cpp b/src/server/service/password.cpp
new file mode 100644 (file)
index 0000000..4267539
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Jooseong Lee <jooseong.lee@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        password.cpp
+ * @author      Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @author      Jooseong Lee (jooseong.lee@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of password service
+ */
+
+#include <iostream>
+#include <string>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <user-check.h>
+
+#include <password.h>
+
+#include <auth-passwd-error.h>
+#include <password-exception.h>
+
+namespace AuthPasswd {
+
+namespace {
+// Service may open more than one socket.
+// These ID's will be assigned to sockets
+// and will be used only by service.
+// When new connection arrives, AcceptEvent
+// will be generated with proper ID to inform
+// service about input socket.
+//
+// Please note: SocketManager does not use it and
+// does not check it in any way.
+//
+// If your service requires only one socket
+// (uses only one socket labeled with smack)
+// you may ignore this ID (just pass 0)
+const InterfaceID SOCKET_ID_CHECK   = 0;
+const InterfaceID SOCKET_ID_SET     = 1;
+const InterfaceID SOCKET_ID_RESET   = 2;
+const InterfaceID SOCKET_ID_POLICY  = 3;
+
+} // namespace anonymous
+
+GenericSocketService::ServiceDescriptionVector PasswordService::GetServiceDescription()
+{
+    return ServiceDescriptionVector {
+        {SERVICE_SOCKET_PASSWD_CHECK,  "*", SOCKET_ID_CHECK},
+        {SERVICE_SOCKET_PASSWD_SET,    "*", SOCKET_ID_SET},
+        {SERVICE_SOCKET_PASSWD_RESET,  "*", SOCKET_ID_RESET},
+        {SERVICE_SOCKET_PASSWD_POLICY, "*", SOCKET_ID_POLICY}
+    };
+}
+
+void PasswordService::Start() {
+    Create();
+}
+
+void PasswordService::Stop() {
+    Join();
+}
+
+void PasswordService::accept(const AcceptEvent &event)
+{
+    LogSecureDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+        << " ConnectionID.counter: " << event.connectionID.counter
+        << " ServiceID: " << event.interfaceID);
+
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.interfaceID = event.interfaceID;
+}
+
+void PasswordService::write(const WriteEvent &event)
+{
+    LogSecureDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
+        " Size: " << event.size << " Left: " << event.left);
+    if (event.left == 0)
+        m_serviceManager->Close(event.connectionID);
+}
+
+void PasswordService::process(const ReadEvent &event)
+{
+    LogSecureDebug("Read event for counter: " << event.connectionID.counter);
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.buffer.Push(event.rawBuffer);
+
+    // We can get several requests in one package.
+    // Extract and process them all
+    while(processOne(event.connectionID, info.buffer, info.interfaceID));
+}
+
+void PasswordService::close(const CloseEvent &event)
+{
+    LogSecureDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+    m_connectionInfoMap.erase(event.connectionID.counter);
+}
+
+int PasswordService::processCheckFunctions(PasswordHdrs hdr, MessageBuffer& buffer,
+                                           const unsigned int cur_user, unsigned int &cur_att,
+                                           unsigned int &max_att, unsigned int &exp_time)
+{
+    int result = AUTH_PASSWD_API_ERROR_SERVER_ERROR;
+
+    switch (hdr) {
+        case PasswordHdrs::HDR_CHK_PASSWD: {
+            unsigned int passwdType = 0;
+            std::string challenge;
+            Deserialization::Deserialize(buffer, passwdType);
+            Deserialization::Deserialize(buffer, challenge);
+            result = m_pwdManager.checkPassword(passwdType, challenge, cur_user, cur_att, max_att,
+                                                exp_time);
+            break;
+        }
+
+        case PasswordHdrs::HDR_CHK_PASSWD_STATE: {
+            unsigned int passwdType = 0;
+            Deserialization::Deserialize(buffer, passwdType);
+            result = m_pwdManager.isPwdValid(passwdType, cur_user, cur_att, max_att, exp_time);
+            break;
+        }
+
+        default:
+            LogError("Unknown msg header.");
+            Throw(Exception::IncorrectHeader);
+    }
+
+    return result;
+}
+
+int PasswordService::processSetFunctions(PasswordHdrs hdr, MessageBuffer& buffer,
+                                         const unsigned int cur_user, bool &isPwdReused)
+{
+    int result = AUTH_PASSWD_API_ERROR_SERVER_ERROR;
+
+    switch(hdr) {
+        case PasswordHdrs::HDR_SET_PASSWD: {
+            std::string curPasswd, newPasswd;
+            unsigned int passwdType = 0, rec_att = 0, rec_days = 0, rec_history = 0;
+            Deserialization::Deserialize(buffer, passwdType);
+            Deserialization::Deserialize(buffer, curPasswd);
+            Deserialization::Deserialize(buffer, newPasswd);
+            /* TO DO: Check newPassword based on passwd policy. Get max att, expired date and histoy */
+            result = m_pwdManager.setPassword(passwdType, curPasswd, newPasswd, cur_user, rec_att,
+                                              rec_days, rec_history);
+            break;
+        }
+
+        case PasswordHdrs::HDR_SET_PASSWD_RECOVERY: {
+            std::string curRcvPasswd, newPasswd;
+            unsigned int rec_att = 0, rec_days = 0, rec_history = 0;
+            Deserialization::Deserialize(buffer, curRcvPasswd);
+            Deserialization::Deserialize(buffer, newPasswd);
+            /* TO DO: Check newPassword based on passwd policy. Get max att, expired date and histoy */
+
+            // Don't recovery password if MaxAttempt value is not infinite.
+            if (rec_days != PASSWORD_INFINITE_EXPIRATION_DAYS)
+                return AUTH_PASSWD_API_ERROR_RECOVERY_PASSWORD_RESTRICTED;
+
+            result = m_pwdManager.setPasswordRecovery(curRcvPasswd, newPasswd, cur_user, rec_att,
+                                                      rec_days, rec_history);
+            break;
+        }
+
+        case PasswordHdrs::HDR_CHK_PASSWD_REUSED: {
+             unsigned int passwdType = 0;
+             std::string passwd;
+             Deserialization::Deserialize(buffer, passwdType);
+             Deserialization::Deserialize(buffer, passwd);
+             result = m_pwdManager.isPwdReused(passwdType, passwd, cur_user, isPwdReused);
+             break;
+        }
+
+        default:
+            LogError("Unknown msg header.");
+            Throw(Exception::IncorrectHeader);
+    }
+
+    return result;
+}
+
+int PasswordService::processResetFunctions(PasswordHdrs hdr, MessageBuffer& buffer)
+{
+    int result = AUTH_PASSWD_API_ERROR_SERVER_ERROR;
+
+    std::string newPasswd;
+    unsigned int passwdType = 0, rec_user = 0, rec_att = 0, rec_days = 0, rec_history = 0;
+
+    switch(hdr) {
+        case PasswordHdrs::HDR_RST_PASSWD:
+            Deserialization::Deserialize(buffer, passwdType);
+            Deserialization::Deserialize(buffer, newPasswd);
+            Deserialization::Deserialize(buffer, rec_user);
+
+            /* TO DO: Get max att, expired date and history */
+            result = m_pwdManager.resetPassword(passwdType, newPasswd, rec_user, rec_att, rec_days,
+                                                rec_history);
+            break;
+
+        default:
+            LogError("Unknown msg header.");
+            Throw(Exception::IncorrectHeader);
+    }
+
+    return result;
+}
+
+int PasswordService::processPolicyFunctions(PasswordHdrs hdr, MessageBuffer& buffer)
+{
+    int result = AUTH_PASSWD_API_SUCCESS;
+/*
+    int result = AUTH_PASSWD_API_ERROR_SERVER_ERROR;
+
+    policy_h *p_policy;
+    unsigned int rec_user = 0, rec_att = 0, rec_days = 0, rec_history = 0;
+
+    swithch(hdr) {
+        case PasswordHdrs::HDR_SET_PASSWD_POLICY: {
+             Deserialization::Deserialize(buffer, p_policy);
+
+             result = m_policyManager.setPolicy(p_policy);
+
+             if(result == AUTH_PASSWD_API_SUCCESS)
+                 m_pwdManager.setPasswordMaxAttempts(rec_user, rec_att);
+                 m_pwdManager.setPasswordValidity(rec_user, rec_days);
+                 m_pwdManager.setPasswordHistory(rec_user, rec_history);
+             }
+             break;
+
+        default:
+            LogError("Unknown msg header.");
+            Throw(Exception::IncorrectHeader);
+    }
+*/
+    return result;
+}
+
+bool PasswordService::processOne(const ConnectionID &conn, MessageBuffer &buffer,
+                                 InterfaceID interfaceID)
+{
+    LogSecureDebug("Iteration begin");
+
+    MessageBuffer sendBuffer;
+
+    int retCode = AUTH_PASSWD_API_ERROR_SERVER_ERROR;
+    unsigned int cur_user = 0, cur_att = 0, max_att = 0, exp_time = 0;
+    bool isPwdReused;
+
+    if (!buffer.Ready())
+        return false;
+
+    Try {       //try..catch for MessageBuffer errors, closes connection when exception is thrown
+        int tempHdr;
+        Deserialization::Deserialize(buffer, tempHdr);
+        PasswordHdrs hdr = static_cast<PasswordHdrs>(tempHdr);
+
+        try {   //try..catch for internal service errors, assigns error code for returning.
+            switch (interfaceID) {
+                case SOCKET_ID_CHECK:
+                    if(socket_get_user(conn.sock, cur_user))
+                        retCode = AUTH_PASSWD_API_ERROR_NO_USER;
+                    else
+                        retCode = processCheckFunctions(hdr, buffer, cur_user, cur_att, max_att, exp_time);
+                    break;
+
+                case SOCKET_ID_SET:
+                    if(socket_get_user(conn.sock, cur_user))
+                        retCode = AUTH_PASSWD_API_ERROR_NO_USER;
+                    else
+                        retCode = processSetFunctions(hdr, buffer, cur_user, isPwdReused);
+                    break;
+
+                case SOCKET_ID_RESET:
+                    retCode = processResetFunctions(hdr, buffer);
+                    break;
+
+                case SOCKET_ID_POLICY:
+                    retCode = processPolicyFunctions(hdr, buffer);
+                    break;
+
+                default:
+                    LogError("Wrong interfaceID.");
+                    Throw(Exception::IncorrectHeader);
+            }
+        } catch (PasswordException::Base &e) {
+            LogError("Password error: " << e.DumpToString());
+            retCode = AUTH_PASSWD_API_ERROR_SERVER_ERROR;
+        } catch (std::exception &e) {
+            LogError("STD error: " << e.what());
+            retCode = AUTH_PASSWD_API_ERROR_SERVER_ERROR;
+        }
+
+        //everything is OK, send return code and extra data
+        Serialization::Serialize(sendBuffer, retCode);
+
+        //Returning additional information should occur only when checking functions
+        //are called, and under certain return values
+        if (interfaceID == SOCKET_ID_CHECK)
+        {
+            switch(retCode)
+            {
+                case AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH:
+                case AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED:
+                case AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED:
+                case AUTH_PASSWD_API_SUCCESS:
+                    Serialization::Serialize(sendBuffer, cur_att);
+                    Serialization::Serialize(sendBuffer, max_att);
+                    Serialization::Serialize(sendBuffer, exp_time);
+                    break;
+            default:
+                break;
+            }
+        } else if (interfaceID == SOCKET_ID_SET) {
+            if (hdr == PasswordHdrs::HDR_CHK_PASSWD_REUSED && retCode == AUTH_PASSWD_API_SUCCESS) {
+                Serialization::Serialize(sendBuffer, (int)isPwdReused);
+            }
+        }
+
+        m_serviceManager->Write(conn, sendBuffer.Pop());
+    } Catch (MessageBuffer::Exception::Base) {
+        LogError("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    } Catch (PasswordService::Exception::Base) {
+        LogError("Incorrect message header. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }
+
+    return true;
+}
+
+} // namespace AuthPasswd
+
diff --git a/systemd/CMakeLists.txt b/systemd/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b4e46b4
--- /dev/null
@@ -0,0 +1,11 @@
+INSTALL(FILES
+    ${CMAKE_SOURCE_DIR}/systemd/authentication-server.service
+    ${CMAKE_SOURCE_DIR}/systemd/authentication-server.target
+    ${CMAKE_SOURCE_DIR}/systemd/authentication-server-passwd-check.socket
+    ${CMAKE_SOURCE_DIR}/systemd/authentication-server-passwd-set.socket
+    ${CMAKE_SOURCE_DIR}/systemd/authentication-server-passwd-reset.socket
+    ${CMAKE_SOURCE_DIR}/systemd/authentication-server-passwd-policy.socket
+    DESTINATION
+    /usr/lib/systemd/system
+)
+
diff --git a/systemd/authentication-server-passwd-check.socket b/systemd/authentication-server-passwd-check.socket
new file mode 100644 (file)
index 0000000..d9bb7ec
--- /dev/null
@@ -0,0 +1,14 @@
+[Socket]
+ListenStream=/run/.authentication-server-api-passwd-check.sock
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=authentication-server.service
+
+[Unit]
+Wants=authentication-server.target
+Before=authentication-server.target
+
+[Install]
+WantedBy=sockets.target
diff --git a/systemd/authentication-server-passwd-policy.socket b/systemd/authentication-server-passwd-policy.socket
new file mode 100644 (file)
index 0000000..feb474c
--- /dev/null
@@ -0,0 +1,14 @@
+[Socket]
+ListenStream=/run/.authentication-server-api-passwd-policy.sock
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=authentication-server.service
+
+[Unit]
+Wants=authentication-server.target
+Before=authentication-server.target
+
+[Install]
+WantedBy=sockets.target
diff --git a/systemd/authentication-server-passwd-reset.socket b/systemd/authentication-server-passwd-reset.socket
new file mode 100644 (file)
index 0000000..94b1c61
--- /dev/null
@@ -0,0 +1,14 @@
+[Socket]
+ListenStream=/run/.authentication-server-api-passwd-reset.sock
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=authentication-server.service
+
+[Unit]
+Wants=authentication-server.target
+Before=authetication-server.target
+
+[Install]
+WantedBy=sockets.target
diff --git a/systemd/authentication-server-passwd-set.socket b/systemd/authentication-server-passwd-set.socket
new file mode 100644 (file)
index 0000000..ff839bf
--- /dev/null
@@ -0,0 +1,14 @@
+[Socket]
+ListenStream=/run/.authentication-server-api-passwd-set.sock
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+Service=authentication-server.service
+
+[Unit]
+Wants=authentication-server.target
+Before=authentication-server.target
+
+[Install]
+WantedBy=sockets.target
diff --git a/systemd/authentication-server.service b/systemd/authentication-server.service
new file mode 100644 (file)
index 0000000..92c3d97
--- /dev/null
@@ -0,0 +1,13 @@
+[Unit]
+Description=Start authentication server
+
+[Service]
+Type=notify
+ExecStart=/usr/bin/authentication-server
+Sockets=authentication-server-passwd-check.socket
+Sockets=authentication-server-passwd-set.socket
+Sockets=authentication-server-passwd-reset.socket
+Sockets=authentication-server-passwd-policy.socket
+
+[Install]
+WantedBy=multi-user.target
diff --git a/systemd/authentication-server.target b/systemd/authentication-server.target
new file mode 100644 (file)
index 0000000..39d4861
--- /dev/null
@@ -0,0 +1,4 @@
+[Unit]
+Description=authentication server sockets
+DefaultDependencies=true
+