Detach password file as interface 36/172236/5
authorsangwan.kwon <sangwan.kwon@samsung.com>
Mon, 12 Mar 2018 10:49:42 +0000 (19:49 +0900)
committersangwan kwon <sangwan.kwon@samsung.com>
Wed, 4 Apr 2018 02:08:27 +0000 (02:08 +0000)
1. Fix "password-file.h" to "ipassword-file.h".
  - IPasswordFile is interface of PasswordFile.
  - PasswordFile can be implemented by SW-Backend or TZ-Backend.

2. Add "libauth-sw-backend.so."
  - This library has PasswordFile which implemented by SW-Backend.
  - Auth-FW Server controls this as plugin.
    (Temporarily, server has PasswordFile for TDD)

Change-Id: I13790d36fdd5fc849e40ca30328393d1a7ff5c39
Signed-off-by: sangwan.kwon <sangwan.kwon@samsung.com>
17 files changed:
CMakeLists.txt
packaging/auth-fw.spec
packaging/libauth-fw-sw-backend.manifest [new file with mode: 0644]
src/server/CMakeLists.txt
src/server/plugin/CMakeLists.txt [new file with mode: 0644]
src/server/plugin/generic-backend/ipassword-file.h [new file with mode: 0644]
src/server/plugin/generic-backend/password-file-buffer.cpp [new file with mode: 0644]
src/server/plugin/generic-backend/password-file-buffer.h [new file with mode: 0644]
src/server/plugin/sw-backend/password-file.cpp [new file with mode: 0644]
src/server/plugin/sw-backend/password-file.h [new file with mode: 0644]
src/server/service/include/password-file-buffer.h [deleted file]
src/server/service/include/password-file.h [deleted file]
src/server/service/include/password-manager.h
src/server/service/password-file-buffer.cpp [deleted file]
src/server/service/password-file.cpp [deleted file]
src/server/service/password-manager.cpp
src/server/service/policy-file.cpp

index 7e499d3ce1d0271dc8f64cd94f3508753c91496c..28250e3673f4e8b833358edea1afc5f1da1e10d8 100644 (file)
@@ -69,13 +69,14 @@ 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(PLUGIN_PATH  ${PROJECT_SOURCE_DIR}/src/server/plugin)
 SET(DPL_PATH     ${PROJECT_SOURCE_DIR}/src/dpl)
 
 SET(TARGET_SERVER ${SERVICE_NAME})
 SET(TARGET_CLIENT ${SERVICE_NAME}-client)
 SET(TARGET_CLIENT_ADMIN ${SERVICE_NAME}-client-admin)
 SET(TARGET_COMMON ${SERVICE_NAME}-commons)
+SET(TARGET_SW_BACKEND ${SERVICE_NAME}-sw-backend)
 SET(TARGET_TEST ${SERVICE_NAME}-test)
 
 ADD_SUBDIRECTORY(src)
index 3aae3000db1a6fc20666cdc7ebca5d520d5cb579..ac6eba0d4d8702276394a10d15b38fa98a211961 100644 (file)
@@ -8,11 +8,11 @@ Source0:    %{name}-%{version}.tar.gz
 Source1001: %{name}.manifest
 Source1002: lib%{name}-client.manifest
 Source1003: lib%{name}-client-admin.manifest
-Source1004: %{name}-test.manifest
+Source1004: lib%{name}-sw-backend.manifest
+Source1005: %{name}-test.manifest
 Requires: security-config
 BuildRequires: cmake
 BuildRequires: pkgconfig(dlog)
-BuildRequires: pkgconfig(openssl)
 BuildRequires: pkgconfig(libsmack)
 BuildRequires: pkgconfig(libsystemd-daemon)
 BuildRequires: pkgconfig(libtzplatform-config)
@@ -59,13 +59,14 @@ Summary:    Authentication framework (client-devel)
 Group:      Security/Development
 Requires:   lib%{name}-client = %{version}-%{release}
 Requires:   lib%{name}-client-admin = %{version}-%{release}
+Requires:   lib%{name}-sw-backend = %{version}-%{release}
 
 %description -n lib%{name}-client-devel
 Authentication framework package (client-devel)
 
 %prep
 %setup -q
-cp -a %{SOURCE1001} %{SOURCE1002} %{SOURCE1003} %{SOURCE1004} .
+cp -a %{SOURCE1001} %{SOURCE1002} %{SOURCE1003} %{SOURCE1004} %{SOURCE1005} .
 
 %build
 export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE"
@@ -169,6 +170,7 @@ fi
 %files -n lib%{name}-client-devel
 %{_libdir}/lib%{name}-client.so
 %{_libdir}/lib%{name}-client-admin.so
+%{_libdir}/lib%{name}-sw-backend.so
 %{_libdir}/lib%{name}-commons.so
 %{_includedir}/%{name}/auth-passwd.h
 %{_includedir}/%{name}/auth-passwd-admin.h
@@ -176,6 +178,23 @@ fi
 %{_includedir}/%{name}/auth-passwd-policy-types.h
 %{_libdir}/pkgconfig/*.pc
 
+## SW-Backend(PasswordFile) Package ##########################################
+%package -n lib%{name}-sw-backend
+Summary: Authentication framework (sw-backend)
+Group: Security/Libraries
+BuildRequires: pkgconfig(openssl)
+Requires: %{name} = %{version}
+Requires(post): %{sbin_dir}/ldconfig
+Requires(postun): %{sbin_dir}/ldconfig
+
+%description -n lib%{name}-sw-backend
+SW-Backend for authentication framework
+
+%files -n lib%{name}-sw-backend
+%manifest lib%{name}-sw-backend.manifest
+%license LICENSE
+%{_libdir}/lib%{name}-sw-backend.so.*
+
 ## Test Package ##############################################################
 %package test
 Summary: Authentication framework (test)
diff --git a/packaging/libauth-fw-sw-backend.manifest b/packaging/libauth-fw-sw-backend.manifest
new file mode 100644 (file)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
index d442c65fc97afec91f3e5bbeefe0294f1755f5cd..5a26071891729bd1a7b6e2d03be35cfb4d666175 100644 (file)
@@ -16,6 +16,7 @@ INCLUDE_DIRECTORIES(
     ${SERVER_PATH}/service/include
     ${DPL_PATH}/core/include
     ${DPL_PATH}/log/include
+    ${PLUGIN_PATH}/
     )
 
 SET(SERVER_SOURCES
@@ -25,11 +26,13 @@ SET(SERVER_SOURCES
     main/socket-manager.cpp
     main/user-check.cpp
     service/password.cpp
-    service/password-file-buffer.cpp
-    service/password-file.cpp
     service/password-manager.cpp
     service/policy-file.cpp
     service/policy-manager.cpp
+    plugin/generic-backend/password-file-buffer.cpp
+
+    # TODO: Replace with dynamic load. (Temporary included for TDD)
+    plugin/sw-backend/password-file.cpp
     )
 
 SET_SOURCE_FILES_PROPERTIES(${SERVER_SOURCES}
@@ -59,3 +62,5 @@ INSTALL(TARGETS ${TARGET_SERVER}
         WORLD_READ
         WORLD_EXECUTE
     )
+
+ADD_SUBDIRECTORY(plugin)
diff --git a/src/server/plugin/CMakeLists.txt b/src/server/plugin/CMakeLists.txt
new file mode 100644 (file)
index 0000000..cd06ced
--- /dev/null
@@ -0,0 +1,35 @@
+PKG_CHECK_MODULES(SW_BACKEND_DEP
+    REQUIRED
+    openssl
+    )
+
+FIND_PACKAGE(Threads REQUIRED)
+
+INCLUDE_DIRECTORIES(
+    SYSTEM
+    ${SW_BACKEND_DEP_INCLUDE_DIRS}
+    ${COMMON_PATH}/include
+    ${SERVER_PATH}/service/include
+    ${DPL_PATH}/core/include
+    ${DPL_PATH}/log/include
+    ${PLUGIN_PATH}
+    )
+
+SET(SW_BACKEND_SOURCES
+    generic-backend/password-file-buffer.cpp
+    sw-backend/password-file.cpp
+    )
+
+ADD_LIBRARY(${TARGET_SW_BACKEND} SHARED ${SW_BACKEND_SOURCES})
+
+SET_TARGET_PROPERTIES(
+    ${TARGET_SW_BACKEND}
+    PROPERTIES
+        COMPILE_FLAGS "-D_GNU_SOURCE -fPIC -fvisibility=default"
+        SOVERSION ${API_VERSION}
+        VERSION ${VERSION}
+    )
+
+TARGET_LINK_LIBRARIES(${TARGET_SW_BACKEND} ${SW_BACKEND_DEP_LIBRARIES} ${TARGET_COMMON})
+
+INSTALL(TARGETS ${TARGET_SW_BACKEND} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/src/server/plugin/generic-backend/ipassword-file.h b/src/server/plugin/generic-backend/ipassword-file.h
new file mode 100644 (file)
index 0000000..466d23b
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (c) 2018 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
+ */
+#ifndef _IPASSWORD_FILE_H_
+#define _IPASSWORD_FILE_H_
+
+#include <string>
+#include <memory>
+
+#include <time.h>
+
+#include <limits>
+
+namespace AuthPasswd {
+
+constexpr time_t PASSWORD_INFINITE_EXPIRATION_TIME = std::numeric_limits<time_t>::max();
+
+struct IPasswordFile {
+       virtual void writeMemoryToFile() const = 0;
+       virtual void writeAttemptToFile() const = 0;
+
+       virtual void setPassword(unsigned int passwdType, const std::string &password) = 0;
+       virtual bool checkPassword(unsigned int passwdType,
+                                                          const std::string &password) const = 0;
+
+       virtual bool isPasswordActive(unsigned int passwdType) const = 0;
+
+       virtual void setMaxHistorySize(unsigned int history) = 0;
+       virtual unsigned int getMaxHistorySize() const = 0;
+
+       virtual unsigned int getExpireTime() const = 0;
+       virtual void setExpireTime(unsigned int expireTime) = 0;
+
+       virtual unsigned int getExpireTimeLeft() const = 0;
+       virtual void setExpireTimeLeft(time_t expireTimeLeft) = 0;
+
+       virtual unsigned int getAttempt() const = 0;
+       virtual void resetAttempt() = 0;
+       virtual void incrementAttempt() = 0;
+       virtual int getMaxAttempt() const = 0;
+       virtual void setMaxAttempt(unsigned int maxAttempt) = 0;
+
+       virtual bool isPasswordReused(const std::string &password) const = 0;
+
+       virtual bool checkExpiration() const = 0;
+       virtual bool checkIfAttemptsExceeded() const = 0;
+       virtual bool isIgnorePeriod() const = 0;
+
+       virtual bool isHistoryActive() const = 0;
+};
+
+using PasswordFileFactory = IPasswordFile* (*)(unsigned int);
+
+} //namespace AuthPasswd
+
+#endif
diff --git a/src/server/plugin/generic-backend/password-file-buffer.cpp b/src/server/plugin/generic-backend/password-file-buffer.cpp
new file mode 100644 (file)
index 0000000..a9e5d5a
--- /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 <generic-backend/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();
+       if (::fsync(DPL::FstreamAccessors<std::ofstream>::GetFd(file)) != 0)
+               LogError("Failed to synchronize a file's state.");
+       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/plugin/generic-backend/password-file-buffer.h b/src/server/plugin/generic-backend/password-file-buffer.h
new file mode 100644 (file)
index 0000000..2e87cef
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ *  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/plugin/sw-backend/password-file.cpp b/src/server/plugin/sw-backend/password-file.cpp
new file mode 100644 (file)
index 0000000..e92a3b2
--- /dev/null
@@ -0,0 +1,531 @@
+/*
+ *  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 <sw-backend/password-file.h>
+
+#include <fstream>
+#include <algorithm>
+
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.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 <policy.h>
+#include <password-exception.h>
+#include <generic-backend/password-file-buffer.h>
+
+namespace {
+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 = 4;
+} // namespace anonymous
+
+namespace AuthPasswd {
+
+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;
+       }
+};
+
+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);
+       }
+}
+
+namespace SWBackend {
+
+PasswordFile::PasswordFile(unsigned int user) :
+       m_user(user),
+       m_passwordCurrent(new NoPassword()),
+       m_maxAttempt(PASSWORD_INFINITE_ATTEMPT_COUNT),
+       m_maxHistorySize(0),
+       m_expireTime(PASSWORD_INFINITE_EXPIRATION_DAYS),
+       m_expireTimeLeft(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(RW_DATA_DIR, m_user);
+
+       if (!dirExists(RW_DATA_DIR)) {
+               if (mkdir(RW_DATA_DIR, 0700)) {
+                       LogError("Failed to create directory for files. Error: " << errnoToString());
+                       Throw(PasswordException::MakeDirError);
+               }
+       }
+
+       if (!dirExists(userDir.c_str())) {
+               if (mkdir(userDir.c_str(), 0700)) {
+                       LogError("Failed to create directory for files. Error: " << errnoToString());
+                       Throw(PasswordException::MakeDirError);
+               }
+       }
+
+       preparePwdFile();
+       prepareAttemptFile();
+       resetTimer();
+}
+
+void PasswordFile::resetState()
+{
+       m_maxAttempt = PASSWORD_INFINITE_ATTEMPT_COUNT;
+       m_maxHistorySize = 0;
+       m_expireTime = PASSWORD_INFINITE_EXPIRATION_DAYS;
+       m_expireTimeLeft = PASSWORD_INFINITE_EXPIRATION_TIME;
+       m_passwordRcvActive = false;
+       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(RW_DATA_DIR, m_user) + PASSWORD_FILE;
+       std::string oldVersionPwdFile = createDir(RW_DATA_DIR, 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: " << errnoToString());
+                               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(RW_DATA_DIR, 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, 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 << ", m_expireTimeLeft: " << m_expireTimeLeft <<
+                                  ", 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_expireTimeLeft);
+       Serialization::Serialize(pwdBuffer, m_passwordRcvActive);
+       Serialization::Serialize(pwdBuffer, m_passwordActive);
+       Serialization::Serialize(pwdBuffer, m_passwordCurrent);
+       Serialization::Serialize(pwdBuffer, m_passwordHistory);
+       std::string pwdFile = createDir(RW_DATA_DIR, m_user) + PASSWORD_FILE;
+       pwdBuffer.Save(pwdFile);
+
+       if (chmod(pwdFile.c_str(), FILE_MODE)) {
+               LogError("Failed to chmod for " << pwdFile << " Error: " << errnoToString());
+               Throw(PasswordException::ChmodError);
+       }
+}
+
+void PasswordFile::loadMemoryFromFile()
+{
+       PasswordFileBuffer pwdBuffer;
+       std::string pwdFile = createDir(RW_DATA_DIR, 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_expireTimeLeft);
+       Deserialization::Deserialize(pwdBuffer, m_passwordRcvActive);
+       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 << ", m_expireTimeLeft: " << m_expireTimeLeft <<
+                                  ", isActive: " << m_passwordActive << ", isRcvActive: " <<
+                                  m_passwordRcvActive);
+}
+
+bool PasswordFile::tryLoadMemoryFromOldFormatFile()
+{
+       struct stat oldFileStat;
+       std::string oldVersionPwdFile = createDir(RW_DATA_DIR, m_user) + OLD_VERSION_PASSWORD_FILE;
+
+       if (stat(oldVersionPwdFile.c_str(), &oldFileStat) != 0)
+               return false;
+
+       PasswordFileBuffer pwdBuffer;
+       pwdBuffer.Load(oldVersionPwdFile);
+       unsigned int fileVersion = 0;
+       Deserialization::Deserialize(pwdBuffer, fileVersion);
+
+       switch (fileVersion) {
+       case 1:
+       case 2:
+       case 3:
+               Deserialization::Deserialize(pwdBuffer, m_maxAttempt);
+               Deserialization::Deserialize(pwdBuffer, m_maxHistorySize);
+               Deserialization::Deserialize(pwdBuffer, m_expireTimeLeft);
+               Deserialization::Deserialize(pwdBuffer, m_passwordActive);
+               Deserialization::Deserialize(pwdBuffer, m_passwordCurrent);
+               Deserialization::Deserialize(pwdBuffer, m_passwordHistory);
+
+               m_expireTime = PASSWORD_INFINITE_EXPIRATION_DAYS;
+               m_passwordRcvActive = false;
+               break;
+       default:
+               LogError("Invaild password version: " << fileVersion);
+               Throw(PasswordException::FStreamReadError);
+       }
+       return true;
+}
+
+void PasswordFile::writeAttemptToFile() const
+{
+       std::string attemptFile = createDir(RW_DATA_DIR, 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();
+       if (::fsync(DPL::FstreamAccessors<std::ofstream>::GetFd(AttemptFile)) != 0)
+               LogError("Failed to synchronize a file's state.");
+       AttemptFile.close();
+}
+
+bool PasswordFile::isPasswordActive(unsigned int passwdType) const
+{
+       if (passwdType != AUTH_PWD_NORMAL)
+               return false;
+
+       return m_passwordActive;
+}
+
+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(unsigned int passwdType, const std::string &password)
+{
+       if (passwdType != AUTH_PWD_NORMAL) {
+               LogError("Password type is wrong.");
+               return;
+       }
+
+       //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;
+       }
+}
+
+bool PasswordFile::checkPassword(unsigned int passwdType, const std::string &password) const
+{
+       if (passwdType != AUTH_PWD_NORMAL)
+               return false;
+
+       return m_passwordCurrent->match(password);
+}
+
+void PasswordFile::setExpireTime(unsigned int expireTime)
+{
+       m_expireTime = expireTime;
+}
+
+unsigned int PasswordFile::getExpireTime() const
+{
+       return m_expireTime;
+}
+
+void PasswordFile::setExpireTimeLeft(time_t expireTimeLeft)
+{
+       m_expireTimeLeft = expireTimeLeft;
+}
+
+unsigned int PasswordFile::getExpireTimeLeft() const
+{
+       if (m_expireTimeLeft != PASSWORD_INFINITE_EXPIRATION_TIME) {
+               time_t timeLeft = m_expireTimeLeft - 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_expireTimeLeft != PASSWORD_INFINITE_EXPIRATION_TIME) && (time(NULL) > m_expireTimeLeft));
+}
+
+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 SWBackend
+} //namespace AuthPasswd
diff --git a/src/server/plugin/sw-backend/password-file.h b/src/server/plugin/sw-backend/password-file.h
new file mode 100644 (file)
index 0000000..a5097e5
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ *  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 _SW_BACKEND_PASSWORD_FILE_H_
+#define _SW_BACKEND_PASSWORD_FILE_H_
+
+#include <string>
+#include <vector>
+#include <list>
+#include <chrono>
+#include <memory>
+
+#include <time.h>
+
+#include <dpl/serialization.h>
+
+#include <generic-backend/ipassword-file.h>
+
+namespace AuthPasswd {
+
+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;
+};
+
+using IPasswordPtr = std::shared_ptr<IPassword>;
+using PasswordList = std::list<IPasswordPtr>;
+
+namespace SWBackend {
+
+class PasswordFile : public IPasswordFile {
+public:
+       PasswordFile(unsigned int user);
+
+       void writeMemoryToFile() const override;
+       void writeAttemptToFile() const override;
+
+       void setPassword(unsigned int passwdType, const std::string &password) override;
+       bool checkPassword(unsigned int passwdType,
+                                          const std::string &password) const override;
+
+       bool isPasswordActive(unsigned int passwdType) const override;
+
+       void setMaxHistorySize(unsigned int history) override;
+       unsigned int getMaxHistorySize() const override;
+
+       unsigned int getExpireTime() const override;
+       void setExpireTime(unsigned int expireTime) override;
+
+       unsigned int getExpireTimeLeft() const override;
+       void setExpireTimeLeft(time_t expireTimeLeft) override;
+
+       unsigned int getAttempt() const override;
+       void resetAttempt() override;
+       void incrementAttempt() override;
+       int getMaxAttempt() const override;
+       void setMaxAttempt(unsigned int maxAttempt) override;
+
+       bool isPasswordReused(const std::string &password) const override;
+
+       bool checkExpiration() const override;
+       bool checkIfAttemptsExceeded() const override;
+       bool isIgnorePeriod() const override;
+
+       bool isHistoryActive() const override;
+
+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, unsigned int user) const;
+
+       mutable TimePoint m_retryTimerStart;
+
+       const unsigned int m_user;
+
+       ::AuthPasswd::IPasswordPtr m_passwordCurrent;
+       ::AuthPasswd::PasswordList m_passwordHistory;
+       unsigned int m_maxAttempt;
+       unsigned int m_maxHistorySize;
+       unsigned int m_expireTime;
+       time_t       m_expireTimeLeft;
+       bool         m_passwordActive;
+       bool         m_passwordRcvActive;
+
+       //attempt file data
+       unsigned int m_attempt;
+};
+
+} // namespace SWBackend
+} // namespace AuthPasswd
+
+#endif
diff --git a/src/server/service/include/password-file-buffer.h b/src/server/service/include/password-file-buffer.h
deleted file mode 100644 (file)
index 2e87cef..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  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
deleted file mode 100644 (file)
index 165c93e..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *  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(unsigned int user);
-
-       void writeMemoryToFile() const;
-       void writeAttemptToFile() const;
-
-       void setPassword(unsigned int passwdType, const std::string &password);
-       bool checkPassword(unsigned int passwdType, const std::string &password) const;
-
-       bool isPasswordActive(unsigned int passwdType) const;
-
-       void setMaxHistorySize(unsigned int history);
-       unsigned int getMaxHistorySize() const;
-
-       unsigned int getExpireTime() const;
-       void setExpireTime(unsigned int expireTime);
-
-       unsigned int getExpireTimeLeft() const;
-       void setExpireTimeLeft(time_t expireTimeLeft);
-
-       //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, unsigned int user) const;
-
-       mutable TimePoint m_retryTimerStart;
-
-       //user name
-       const unsigned int m_user;
-
-       //password file data
-       IPasswordPtr m_passwordCurrent;
-       PasswordList m_passwordHistory;
-       unsigned int m_maxAttempt;
-       unsigned int m_maxHistorySize;
-       unsigned int m_expireTime;
-       time_t       m_expireTimeLeft;
-       bool         m_passwordActive;
-       bool         m_passwordRcvActive;
-
-       //attempt file data
-       unsigned int m_attempt;
-};
-}    //namespace AuthPasswd
-
-#endif
index 93ad3d6bbdac285ad145a6742c03e60e268d75d4..edb45f4f34180d63c136ea5382987bf132b36fd3 100644 (file)
 
 #include <string>
 #include <map>
+#include <memory>
 
-#include <password-file.h>
+#include <generic-backend/ipassword-file.h>
 
 namespace AuthPasswd {
 class PasswordManager {
 public:
-       typedef std::map<unsigned int, PasswordFile> PasswordFileMap;
+       typedef std::map<unsigned int, std::shared_ptr<IPasswordFile>> PasswordFileMap;
 
        //checking functions
        //no const in checkPassword, attempts are update
diff --git a/src/server/service/password-file-buffer.cpp b/src/server/service/password-file-buffer.cpp
deleted file mode 100644 (file)
index aa3ecf6..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *  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();
-       if (::fsync(DPL::FstreamAccessors<std::ofstream>::GetFd(file)) != 0)
-               LogError("Failed to synchronize a file's state.");
-       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
deleted file mode 100644 (file)
index 68b72be..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- *  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 <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 <policy.h>
-#include <password-exception.h>
-#include <password-file-buffer.h>
-
-namespace {
-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 = 4;
-} // 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(unsigned int user) :
-       m_user(user),
-       m_passwordCurrent(new NoPassword()),
-       m_maxAttempt(PASSWORD_INFINITE_ATTEMPT_COUNT),
-       m_maxHistorySize(0),
-       m_expireTime(PASSWORD_INFINITE_EXPIRATION_DAYS),
-       m_expireTimeLeft(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(RW_DATA_DIR, m_user);
-
-       if (!dirExists(RW_DATA_DIR)) {
-               if (mkdir(RW_DATA_DIR, 0700)) {
-                       LogError("Failed to create directory for files. Error: " << errnoToString());
-                       Throw(PasswordException::MakeDirError);
-               }
-       }
-
-       if (!dirExists(userDir.c_str())) {
-               if (mkdir(userDir.c_str(), 0700)) {
-                       LogError("Failed to create directory for files. Error: " << errnoToString());
-                       Throw(PasswordException::MakeDirError);
-               }
-       }
-
-       preparePwdFile();
-       prepareAttemptFile();
-       resetTimer();
-}
-
-void PasswordFile::resetState()
-{
-       m_maxAttempt = PASSWORD_INFINITE_ATTEMPT_COUNT;
-       m_maxHistorySize = 0;
-       m_expireTime = PASSWORD_INFINITE_EXPIRATION_DAYS;
-       m_expireTimeLeft = PASSWORD_INFINITE_EXPIRATION_TIME;
-       m_passwordRcvActive = false;
-       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(RW_DATA_DIR, m_user) + PASSWORD_FILE;
-       std::string oldVersionPwdFile = createDir(RW_DATA_DIR, 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: " << errnoToString());
-                               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(RW_DATA_DIR, 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, 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 << ", m_expireTimeLeft: " << m_expireTimeLeft <<
-                                  ", 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_expireTimeLeft);
-       Serialization::Serialize(pwdBuffer, m_passwordRcvActive);
-       Serialization::Serialize(pwdBuffer, m_passwordActive);
-       Serialization::Serialize(pwdBuffer, m_passwordCurrent);
-       Serialization::Serialize(pwdBuffer, m_passwordHistory);
-       std::string pwdFile = createDir(RW_DATA_DIR, m_user) + PASSWORD_FILE;
-       pwdBuffer.Save(pwdFile);
-
-       if (chmod(pwdFile.c_str(), FILE_MODE)) {
-               LogError("Failed to chmod for " << pwdFile << " Error: " << errnoToString());
-               Throw(PasswordException::ChmodError);
-       }
-}
-
-void PasswordFile::loadMemoryFromFile()
-{
-       PasswordFileBuffer pwdBuffer;
-       std::string pwdFile = createDir(RW_DATA_DIR, 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_expireTimeLeft);
-       Deserialization::Deserialize(pwdBuffer, m_passwordRcvActive);
-       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 << ", m_expireTimeLeft: " << m_expireTimeLeft <<
-                                  ", isActive: " << m_passwordActive << ", isRcvActive: " <<
-                                  m_passwordRcvActive);
-}
-
-bool PasswordFile::tryLoadMemoryFromOldFormatFile()
-{
-       struct stat oldFileStat;
-       std::string oldVersionPwdFile = createDir(RW_DATA_DIR, m_user) + OLD_VERSION_PASSWORD_FILE;
-
-       if (stat(oldVersionPwdFile.c_str(), &oldFileStat) != 0)
-               return false;
-
-       PasswordFileBuffer pwdBuffer;
-       pwdBuffer.Load(oldVersionPwdFile);
-       unsigned int fileVersion = 0;
-       Deserialization::Deserialize(pwdBuffer, fileVersion);
-
-       switch (fileVersion) {
-       case 1:
-       case 2:
-       case 3:
-               Deserialization::Deserialize(pwdBuffer, m_maxAttempt);
-               Deserialization::Deserialize(pwdBuffer, m_maxHistorySize);
-               Deserialization::Deserialize(pwdBuffer, m_expireTimeLeft);
-               Deserialization::Deserialize(pwdBuffer, m_passwordActive);
-               Deserialization::Deserialize(pwdBuffer, m_passwordCurrent);
-               Deserialization::Deserialize(pwdBuffer, m_passwordHistory);
-
-               m_expireTime = PASSWORD_INFINITE_EXPIRATION_DAYS;
-               m_passwordRcvActive = false;
-               break;
-       default:
-               LogError("Invaild password version: " << fileVersion);
-               Throw(PasswordException::FStreamReadError);
-       }
-       return true;
-}
-
-void PasswordFile::writeAttemptToFile() const
-{
-       std::string attemptFile = createDir(RW_DATA_DIR, 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();
-       if (::fsync(DPL::FstreamAccessors<std::ofstream>::GetFd(AttemptFile)) != 0)
-               LogError("Failed to synchronize a file's state.");
-       AttemptFile.close();
-}
-
-bool PasswordFile::isPasswordActive(unsigned int passwdType) const
-{
-       if (passwdType != AUTH_PWD_NORMAL)
-               return false;
-
-       return m_passwordActive;
-}
-
-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(unsigned int passwdType, const std::string &password)
-{
-       if (passwdType != AUTH_PWD_NORMAL) {
-               LogError("Password type is wrong.");
-               return;
-       }
-
-       //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;
-       }
-}
-
-bool PasswordFile::checkPassword(unsigned int passwdType, const std::string &password) const
-{
-       if (passwdType != AUTH_PWD_NORMAL)
-               return false;
-
-       return m_passwordCurrent->match(password);
-}
-
-void PasswordFile::setExpireTime(unsigned int expireTime)
-{
-       m_expireTime = expireTime;
-}
-
-unsigned int PasswordFile::getExpireTime() const
-{
-       return m_expireTime;
-}
-
-void PasswordFile::setExpireTimeLeft(time_t expireTimeLeft)
-{
-       m_expireTimeLeft = expireTimeLeft;
-}
-
-unsigned int PasswordFile::getExpireTimeLeft() const
-{
-       if (m_expireTimeLeft != PASSWORD_INFINITE_EXPIRATION_TIME) {
-               time_t timeLeft = m_expireTimeLeft - 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_expireTimeLeft != PASSWORD_INFINITE_EXPIRATION_TIME) && (time(NULL) > m_expireTimeLeft));
-}
-
-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
index fc4b2201ae583746f49b1e9265c36ba93d908efc..4cd403a3506b77681cb324bf69c8e1055b1c0509 100644 (file)
@@ -39,6 +39,9 @@
 
 #include <policy.h>
 
+// TODO(sangwan.kwon): Replace with dynamic load.
+#include <sw-backend/password-file.h>
+
 namespace {
 void calculateExpiredTime(unsigned int receivedDays, time_t &validSecs)
 {
@@ -52,12 +55,20 @@ void calculateExpiredTime(unsigned int receivedDays, time_t &validSecs)
        validSecs = (curTime + (receivedDays * 86400));
        return;
 }
+
+AuthPasswd::IPasswordFile* CreatePasswordFile(unsigned int user)
+{
+       return new AuthPasswd::SWBackend::PasswordFile(user);
+}
+
 } //namespace
 
 namespace AuthPasswd {
 void PasswordManager::addPassword(unsigned int user)
 {
-       m_pwdFile.insert(PasswordFileMap::value_type(user, PasswordFile(user)));
+       PasswordFileFactory factory = &CreatePasswordFile;
+       std::shared_ptr<IPasswordFile> passwordFile((*factory)(user));
+       m_pwdFile.insert(PasswordFileMap::value_type(user, passwordFile));
 }
 
 void PasswordManager::removePassword(unsigned int user)
@@ -87,40 +98,40 @@ int PasswordManager::checkPassword(unsigned int passwdType,
        existPassword(currentUser);
        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
 
-       if (itPwd->second.isIgnorePeriod()) {
+       if (itPwd->second->isIgnorePeriod()) {
                LogError("Retry timeout occurred.");
                return AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER;
        }
 
-       if (!itPwd->second.isPasswordActive(passwdType) && !challenge.empty()) {
+       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();
+               itPwd->second->incrementAttempt();
+               itPwd->second->writeAttemptToFile();
+               currentAttempt = itPwd->second->getAttempt();
+               maxAttempt = itPwd->second->getMaxAttempt();
+               expirationTime = itPwd->second->getExpireTimeLeft();
 
-               if (itPwd->second.checkIfAttemptsExceeded()) {
+               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)) {
+               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();
+               itPwd->second->resetAttempt();
+               itPwd->second->writeAttemptToFile();
 
                // Password is too old. You must change it before login.
-               if (itPwd->second.checkExpiration()) {
+               if (itPwd->second->checkExpiration()) {
                        LogError("Password expired.");
                        return AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED;
                }
@@ -142,16 +153,16 @@ int PasswordManager::isPwdValid(unsigned int passwdType, unsigned int currentUse
        existPassword(currentUser);
        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
 
-       if (!itPwd->second.isPasswordActive(passwdType)) {
+       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();
+               currentAttempt = itPwd->second->getAttempt();
+               maxAttempt = itPwd->second->getMaxAttempt();
+               expirationTime = itPwd->second->getExpireTimeLeft();
                break;
 
        default:
@@ -173,8 +184,8 @@ int PasswordManager::isPwdReused(unsigned int passwdType, const std::string &pas
        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);
+               if (itPwd->second->isHistoryActive() && !passwd.empty())
+                       isReused = itPwd->second->isPasswordReused(passwd);
 
                break;
 
@@ -198,14 +209,14 @@ int PasswordManager::setPassword(unsigned int passwdType,
        existPassword(currentUser);
        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
 
-       if (itPwd->second.isIgnorePeriod()) {
+       if (itPwd->second->isIgnorePeriod()) {
                LogError("Retry timeout occured.");
                return AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER;
        }
 
        // check delivered currentPassword
        // when m_passwordActive flag is false, current password should be empty
-       if (!currentPassword.empty() && !itPwd->second.isPasswordActive(passwdType)) {
+       if (!currentPassword.empty() && !itPwd->second->isPasswordActive(passwdType)) {
                LogError("Password not active.");
                return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
        }
@@ -213,39 +224,39 @@ int PasswordManager::setPassword(unsigned int passwdType,
        switch (passwdType) {
        case AUTH_PWD_NORMAL:
                //increment attempt count before checking it against max attempt count
-               itPwd->second.incrementAttempt();
-               itPwd->second.writeAttemptToFile();
+               itPwd->second->incrementAttempt();
+               itPwd->second->writeAttemptToFile();
 
-               if (itPwd->second.checkIfAttemptsExceeded()) {
+               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)) {
+               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();
+               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)) {
+               if (itPwd->second->isHistoryActive() && !newPassword.empty()) {
+                       if (itPwd->second->isPasswordReused(newPassword)) {
                                LogError("Password reused.");
                                return AUTH_PASSWD_API_ERROR_PASSWORD_REUSED;
                        }
                }
 
                if (!newPassword.empty())
-                       receivedDays = itPwd->second.getExpireTime();
+                       receivedDays = itPwd->second->getExpireTime();
 
                calculateExpiredTime(receivedDays, valid_secs);
                //setting password
-               itPwd->second.setPassword(AUTH_PWD_NORMAL, newPassword);
-               itPwd->second.setExpireTimeLeft(valid_secs);
-               itPwd->second.writeMemoryToFile();
+               itPwd->second->setPassword(AUTH_PWD_NORMAL, newPassword);
+               itPwd->second->setExpireTimeLeft(valid_secs);
+               itPwd->second->writeMemoryToFile();
                break;
 
        default:
@@ -268,14 +279,14 @@ int PasswordManager::resetPassword(unsigned int passwdType,
        switch (passwdType) {
        case AUTH_PWD_NORMAL:
                if (!newPassword.empty())
-                       receivedDays = itPwd->second.getExpireTime();
+                       receivedDays = itPwd->second->getExpireTime();
 
                calculateExpiredTime(receivedDays, valid_secs);
-               itPwd->second.resetAttempt();
-               itPwd->second.writeAttemptToFile();
-               itPwd->second.setPassword(AUTH_PWD_NORMAL, newPassword);
-               itPwd->second.setExpireTimeLeft(valid_secs);
-               itPwd->second.writeMemoryToFile();
+               itPwd->second->resetAttempt();
+               itPwd->second->writeAttemptToFile();
+               itPwd->second->setPassword(AUTH_PWD_NORMAL, newPassword);
+               itPwd->second->setExpireTimeLeft(valid_secs);
+               itPwd->second->writeMemoryToFile();
                break;
 
        default:
@@ -292,12 +303,12 @@ void PasswordManager::setPasswordMaxAttempts(unsigned int receivedUser,
        LogSecureDebug("received_attempts: " << receivedAttempts);
        existPassword(receivedUser);
        PasswordFileMap::iterator itPwd = m_pwdFile.find(receivedUser);
-       itPwd->second.setMaxAttempt(receivedAttempts);
-       itPwd->second.writeMemoryToFile();
+       itPwd->second->setMaxAttempt(receivedAttempts);
+       itPwd->second->writeMemoryToFile();
        // Do not reset current attempt when max attempt is reset.
        // It's a platform policy(2017.0327).
-       //itPwd->second.resetAttempt();
-       //itPwd->second.writeAttemptToFile();
+       //itPwd->second->resetAttempt();
+       //itPwd->second->writeAttemptToFile();
 }
 
 void PasswordManager::setPasswordValidity(unsigned int receivedUser,
@@ -309,11 +320,11 @@ void PasswordManager::setPasswordValidity(unsigned int receivedUser,
        PasswordFileMap::iterator itPwd = m_pwdFile.find(receivedUser);
        calculateExpiredTime(receivedDays, valid_secs);
 
-       if (itPwd->second.isPasswordActive(AUTH_PWD_NORMAL))
-               itPwd->second.setExpireTimeLeft(valid_secs);
+       if (itPwd->second->isPasswordActive(AUTH_PWD_NORMAL))
+               itPwd->second->setExpireTimeLeft(valid_secs);
 
-       itPwd->second.setExpireTime(receivedDays);
-       itPwd->second.writeMemoryToFile();
+       itPwd->second->setExpireTime(receivedDays);
+       itPwd->second->writeMemoryToFile();
 }
 
 void PasswordManager::setPasswordHistory(unsigned int receivedUser,
@@ -322,7 +333,7 @@ void PasswordManager::setPasswordHistory(unsigned int receivedUser,
        LogSecureDebug("received_historySize: " << receivedHistory);
        existPassword(receivedUser);
        PasswordFileMap::iterator itPwd = m_pwdFile.find(receivedUser);
-       itPwd->second.setMaxHistorySize(receivedHistory);
-       itPwd->second.writeMemoryToFile();
+       itPwd->second->setMaxHistorySize(receivedHistory);
+       itPwd->second->writeMemoryToFile();
 }
 } //namespace AuthPasswd
index f99b882e66e4bd7d60cac52df8c988887191882a..28cf4dd457c491bf907deda124ab17c51f1d124e 100644 (file)
@@ -41,7 +41,7 @@
 
 #include <error-description.h>
 #include <password-exception.h>
-#include <password-file-buffer.h>
+#include <generic-backend/password-file-buffer.h>
 
 namespace {
 const std::string POLICY_FILE = "/policy";