summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjooseong.lee <jooseong.lee@samsung.com>2016-03-02 17:18:43 +0900
committerjooseong.lee <jooseong.lee@samsung.com>2016-03-04 13:25:33 +0900
commit9bc74292337a3aa99755bf462c7e18746073caf4 (patch)
treee74bd5740d42346243c07937b00f628c72c075dd
parentea4a34ef2af43c3c101ccb96a4679ac3ff9cc926 (diff)
downloadauth-fw-9bc74292337a3aa99755bf462c7e18746073caf4.tar.gz
auth-fw-9bc74292337a3aa99755bf462c7e18746073caf4.tar.bz2
auth-fw-9bc74292337a3aa99755bf462c7e18746073caf4.zip
Implement-password-policy-management
Change-Id: I4d3e47e9196efdc7cd185e7abc2d1668626b0aa0 Signed-off-by: jooseong.lee <jooseong.lee@samsung.com>
-rw-r--r--src/client/client-password-admin.cpp117
-rw-r--r--src/client/client-password.cpp5
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/common/include/policy.h49
-rw-r--r--src/common/include/protocols.h9
-rw-r--r--src/common/policy.cpp45
-rw-r--r--src/common/protocols.cpp7
-rw-r--r--src/include/auth-passwd-admin.h13
-rw-r--r--src/include/auth-passwd-error.h15
-rw-r--r--src/include/auth-passwd-policy-types.h19
-rw-r--r--src/server/CMakeLists.txt2
-rw-r--r--src/server/service/include/password-file.h8
-rw-r--r--src/server/service/include/password-manager.h18
-rw-r--r--src/server/service/include/password.h3
-rw-r--r--src/server/service/include/policy-file.h94
-rw-r--r--src/server/service/include/policy-manager.h64
-rw-r--r--src/server/service/password-file.cpp46
-rw-r--r--src/server/service/password-manager.cpp151
-rw-r--r--src/server/service/password.cpp92
-rw-r--r--src/server/service/policy-file.cpp434
-rw-r--r--src/server/service/policy-manager.cpp273
21 files changed, 1263 insertions, 203 deletions
diff --git a/src/client/client-password-admin.cpp b/src/client/client-password-admin.cpp
index 8a4dcbf..d961c82 100644
--- a/src/client/client-password-admin.cpp
+++ b/src/client/client-password-admin.cpp
@@ -36,8 +36,6 @@
namespace {
-const char *NO_PASSWORD = "";
-
inline bool isPasswordIncorrect(const char* pwd)
{
// NULL means that password must be cancelled.
@@ -59,9 +57,8 @@ int auth_passwd_reset_passwd(const password_type passwd_type,
return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
}
- if (!new_passwd) {
+ if (!new_passwd)
new_passwd = NO_PASSWORD;
- }
MessageBuffer send, recv;
@@ -94,6 +91,9 @@ int auth_passwd_new_policy(policy_h **pp_policy)
} catch (std::bad_alloc& ex) {
return AUTH_PASSWD_API_ERROR_OUT_OF_MEMORY;
}
+
+ (*pp_policy)->policyFlag = 0;
+
return AUTH_PASSWD_API_SUCCESS;
}
@@ -103,6 +103,7 @@ 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->policyFlag = p_policy->policyFlag | (1 << POLICY_USER);
p_policy->uid = uid;
return AUTH_PASSWD_API_SUCCESS;
}
@@ -113,6 +114,7 @@ int auth_passwd_set_max_attempts(policy_h *p_policy, const unsigned int max_atte
if (!p_policy)
return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ p_policy->policyFlag = p_policy->policyFlag | (1 << POLICY_MAX_ATTEMPTS);
p_policy->maxAttempts = max_attempts;
return AUTH_PASSWD_API_SUCCESS;
}
@@ -123,6 +125,7 @@ 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->policyFlag = p_policy->policyFlag | (1 << POLICY_VALID_PERIOD);
p_policy->validPeriod = valid_days;
return AUTH_PASSWD_API_SUCCESS;
}
@@ -133,6 +136,7 @@ int auth_passwd_set_history_size(policy_h *p_policy, const unsigned int history_
if (!p_policy)
return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ p_policy->policyFlag = p_policy->policyFlag | (1 << POLICY_HISTORY_SIZE);
p_policy->historySize = history_size;
return AUTH_PASSWD_API_SUCCESS;
}
@@ -143,21 +147,86 @@ 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->policyFlag = p_policy->policyFlag | (1 << POLICY_MIN_LENGTH);
p_policy->minLength = min_length;
return AUTH_PASSWD_API_SUCCESS;
}
AUTH_PASSWD_API
+int auth_passwd_set_minComplexCharNumber(policy_h *p_policy,
+ const unsigned int minComplexCharNumber)
+{
+ if (!p_policy)
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+ p_policy->policyFlag = p_policy->policyFlag | (1 << POLICY_MIN_COMPLEX_CHAR_NUMBER);
+ p_policy->minComplexCharNumber = minComplexCharNumber;
+ return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_maxCharOccurrences(policy_h *p_policy, const unsigned int maxCharOccurrences)
+{
+ if (!p_policy)
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+ p_policy->policyFlag = p_policy->policyFlag | (1 << POLICY_MAX_CHAR_OCCURRENCES);
+ p_policy->maxCharOccurrences = maxCharOccurrences;
+ return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_maxNumSeqLength(policy_h *p_policy, const unsigned int maxNumSeqLength)
+{
+ if (!p_policy)
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+ p_policy->policyFlag = p_policy->policyFlag | (1 << POLICY_MAX_NUMERIC_SEQ_LENGTH);
+ p_policy->maxNumSeqLength = maxNumSeqLength;
+ 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->policyFlag = p_policy->policyFlag | (1 << POLICY_QUALITY_TYPE);
p_policy->qualityType = quality_type;
return AUTH_PASSWD_API_SUCCESS;
}
AUTH_PASSWD_API
+int auth_passwd_set_pattern(policy_h *p_policy, const char *pattern)
+{
+ if (!p_policy)
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+ if (!pattern)
+ pattern = AuthPasswd::NO_PATTERN;
+
+ p_policy->policyFlag = p_policy->policyFlag | (1 << POLICY_PATTERN);
+ p_policy->pattern = std::string(pattern);
+ return AUTH_PASSWD_API_SUCCESS;
+
+}
+
+AUTH_PASSWD_API
+int auth_passwd_set_forbiddenPasswd(policy_h *p_policy, const char *forbiddenPasswd)
+{
+ if (!p_policy)
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+ if (!forbiddenPasswd)
+ forbiddenPasswd = AuthPasswd::NO_FORBIDDEND_PASSWORD;
+
+ p_policy->policyFlag = p_policy->policyFlag | (1 << POLICY_FORBIDDEN_PASSWDS);
+ p_policy->forbiddenPasswds.push_back(forbiddenPasswd);
+ return AUTH_PASSWD_API_SUCCESS;
+}
+
+AUTH_PASSWD_API
int auth_passwd_set_policy(policy_h *p_policy)
{
using namespace AuthPasswd;
@@ -168,10 +237,24 @@ int auth_passwd_set_policy(policy_h *p_policy)
return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
}
+ if (!(p_policy->policyFlag & (1 << POLICY_USER)))
+ 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);
+ Serialization::Serialize(send, p_policy->policyFlag);
+ Serialization::Serialize(send, p_policy->uid);
+ Serialization::Serialize(send, p_policy->maxAttempts);
+ Serialization::Serialize(send, p_policy->validPeriod);
+ Serialization::Serialize(send, p_policy->historySize);
+ Serialization::Serialize(send, p_policy->minLength);
+ Serialization::Serialize(send, p_policy->minComplexCharNumber);
+ Serialization::Serialize(send, p_policy->maxCharOccurrences);
+ Serialization::Serialize(send, p_policy->maxNumSeqLength);
+ Serialization::Serialize(send, p_policy->qualityType);
+ Serialization::Serialize(send, p_policy->pattern);
+ Serialization::Serialize(send, p_policy->forbiddenPasswds);
int retCode = sendToServer(SERVICE_SOCKET_PASSWD_POLICY, send.Pop(), recv);
if (AUTH_PASSWD_API_SUCCESS != retCode) {
@@ -190,3 +273,27 @@ void auth_passwd_free_policy(policy_h *p_policy)
{
delete p_policy;
}
+
+AUTH_PASSWD_API
+int auth_passwd_disable_policy(const uid_t uid)
+{
+ using namespace AuthPasswd;
+
+ return try_catch([&] {
+
+ MessageBuffer send, recv;
+
+ Serialization::Serialize(send, static_cast<int>(PasswordHdrs::HDR_DIS_PASSWD_POLICY));
+ Serialization::Serialize(send, uid);
+
+ 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;
+ });
+}
diff --git a/src/client/client-password.cpp b/src/client/client-password.cpp
index aad13c4..f49a5ac 100644
--- a/src/client/client-password.cpp
+++ b/src/client/client-password.cpp
@@ -31,15 +31,14 @@
#include <message-buffer.h>
#include <client-common.h>
-#include <policy.h>
+
#include <protocols.h>
+#include <policy.h>
#include <auth-passwd.h>
namespace {
-const char *NO_PASSWORD = "";
-
inline bool isPasswordIncorrect(const char* passwd)
{
// NULL means that password must be cancelled.
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index bec6f53..e69189b 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -7,6 +7,7 @@ PKG_CHECK_MODULES(COMMON_DEP
SET(COMMON_SOURCES
${COMMON_PATH}/error-description.cpp
${COMMON_PATH}/protocols.cpp
+ ${COMMON_PATH}/policy.cpp
${COMMON_PATH}/message-buffer.cpp
${COMMON_PATH}/smack-check.cpp
${COMMON_PATH}/user-check.cpp
@@ -34,6 +35,7 @@ INCLUDE_DIRECTORIES(SYSTEM
)
INCLUDE_DIRECTORIES(
+ ${INCLUDE_PATH}
${COMMON_PATH}/include
${PLUGIN_PATH}/include
${DPL_PATH}/core/include
diff --git a/src/common/include/policy.h b/src/common/include/policy.h
index 60e7fbf..bae5c82 100644
--- a/src/common/include/policy.h
+++ b/src/common/include/policy.h
@@ -25,16 +25,61 @@
#ifndef _AUTH_PASSWD_POLICY_H_
#define _AUTH_PASSWD_POLICY_H_
+#include <unistd.h>
+#include <vector>
+#include <string>
#include <auth-passwd-policy-types.h>
struct auth_password_policy {
+ int policyFlag;
+
uid_t uid;
+
+ // maximum number of attempts that user can try to check the password without success in serial
unsigned int maxAttempts;
+ // number of days that this password is valid
unsigned int validPeriod;
- unsigned int historySize;
+ // recent number of passwords which user cannot reuse
+ unsigned int historySize;
+ // a min number of characters of password
unsigned int minLength;
- password_quality_type qualityType;
+ // a min number of complex chars(non-alphabetic) in password
+ unsigned int minComplexCharNumber;
+ // Maximum count of the same character in the password
+ unsigned int maxCharOccurrences;
+ // Maximum numeric sequence length in the password
+ // regardless descending order, ascending order or repetition
+ unsigned int maxNumSeqLength;
+ // password quality
+ unsigned int qualityType;
+
+ // password regular expression
+ std::string pattern;
+
+ // forbidden strings in password
+ std::vector<std::string> forbiddenPasswds;
};
+namespace AuthPasswd {
+
+extern const size_t MAX_PASSWORD_LEN;
+extern const unsigned int MAX_PASSWORD_HISTORY;
+extern const unsigned int MAX_PASSWORD_ATTEMPTS;
+extern const unsigned int PASSWORD_INFINITE_EXPIRATION_DAYS;
+extern const unsigned int PASSWORD_INFINITE_ATTEMPT_COUNT;
+extern const unsigned int PASSWORD_API_NO_EXPIRATION;
+
+extern const char* NO_PASSWORD;
+extern const char* NO_PATTERN;
+extern const char* NO_FORBIDDEND_PASSWORD;
+
+extern const std::string REGEX_QUALITY_UNSPECIFIED;
+extern const std::string REGEX_QUALITY_SOMETHING;
+extern const std::string REGEX_QUALITY_NUMERIC;
+extern const std::string REGEX_QUALITY_ALPHABETIC;
+extern const std::string REGEX_QUALITY_ALPHANUMERIC;
+
+}
+
#endif // _AUTH_PASSWD_POLICY_H_
diff --git a/src/common/include/protocols.h b/src/common/include/protocols.h
index 047a962..4ec5776 100644
--- a/src/common/include/protocols.h
+++ b/src/common/include/protocols.h
@@ -45,15 +45,10 @@ enum class PasswordHdrs
HDR_SET_PASSWD,
HDR_SET_PASSWD_RECOVERY,
HDR_RST_PASSWD,
- HDR_SET_PASSWD_POLICY
+ HDR_SET_PASSWD_POLICY,
+ HDR_DIS_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/policy.cpp b/src/common/policy.cpp
new file mode 100644
index 0000000..6f5190c
--- /dev/null
+++ b/src/common/policy.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 protocols.cpp
+ * @author Jooseong Lee (jooseong.lee@samsung.com)
+ * @version 1.0
+ * @brief List of all protocols supported by authentication password.
+ */
+
+#include <policy.h>
+
+namespace AuthPasswd {
+
+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;
+
+const char* NO_PASSWORD = "";
+const char* NO_PATTERN = "";
+const char* NO_FORBIDDEND_PASSWORD = "";
+
+const std::string REGEX_QUALITY_UNSPECIFIED = "[.]*";
+const std::string REGEX_QUALITY_SOMETHING = ".+";
+const std::string REGEX_QUALITY_NUMERIC = "^[0-9]+$";
+const std::string REGEX_QUALITY_ALPHABETIC = "^[A-Za-z]+$";
+const std::string REGEX_QUALITY_ALPHANUMERIC = "^[A-Za-z0-9]+$";
+
+} // namespace AuthPasswd
diff --git a/src/common/protocols.cpp b/src/common/protocols.cpp
index a8bd92e..d8645e1 100644
--- a/src/common/protocols.cpp
+++ b/src/common/protocols.cpp
@@ -18,7 +18,6 @@
/*
* @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.
*/
@@ -37,11 +36,5 @@ char const * const SERVICE_SOCKET_PASSWD_RESET =
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/include/auth-passwd-admin.h b/src/include/auth-passwd-admin.h
index 1bc4503..e2f9f6c 100644
--- a/src/include/auth-passwd-admin.h
+++ b/src/include/auth-passwd-admin.h
@@ -67,12 +67,25 @@ int auth_passwd_set_history_size(policy_h *p_policy, const unsigned int history_
int auth_passwd_set_min_length(policy_h *p_policy, const unsigned int min_length);
+int auth_passwd_set_minComplexCharNumber(policy_h *p_policy,
+ const unsigned int minComplexCharNumber);
+
+int auth_passwd_set_maxCharOccurrences(policy_h *p_policy, const unsigned int maxCharOccurrences);
+
+int auth_passwd_set_maxNumSeqLength(policy_h *p_policy, const unsigned int maxNumSeqLength);
+
int auth_passwd_set_quality(policy_h *p_policy, password_quality_type quality_type);
+int auth_passwd_set_pattern(policy_h *p_policy, const char *pattern);
+
+int auth_passwd_set_forbiddenPasswd(policy_h *p_policy, const char *forbiddenPasswd);
+
int auth_passwd_set_policy(policy_h *p_policy);
void auth_passwd_free_policy(policy_h *p_policy);
+int auth_passwd_disable_policy(const uid_t uid);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/include/auth-passwd-error.h b/src/include/auth-passwd-error.h
index 610f828..82103d0 100644
--- a/src/include/auth-passwd-error.h
+++ b/src/include/auth-passwd-error.h
@@ -40,7 +40,7 @@
#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
+#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
@@ -63,20 +63,23 @@
/*! \brief indicating password mismatch */
#define AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH -12
+/*! \brief indicating password is invalid */
+#define AUTH_PASSWD_API_ERROR_PASSWORD_INVALID -13
+
/*! \brief indicating password retry timeout is not occurred yet */
-#define AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER -13
+#define AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER -14
/*! \brief indicating password retry timeout is not occurred yet */
-#define AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED -14
+#define AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED -15
/*! \brief indicating password retry timeout is not occurred yet */
-#define AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED -15
+#define AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED -16
/*! \brief indicating password retry timeout is not occurred yet */
-#define AUTH_PASSWD_API_ERROR_PASSWORD_REUSED -16
+#define AUTH_PASSWD_API_ERROR_PASSWORD_REUSED -17
/*! \brief indicating password retry timeout is not occurred yet */
-#define AUTH_PASSWD_API_ERROR_RECOVERY_PASSWORD_RESTRICTED -17
+#define AUTH_PASSWD_API_ERROR_RECOVERY_PASSWORD_RESTRICTED -18
/*! \brief indicating the error with unknown reason */
#define AUTH_PASSWD_API_ERROR_UNKNOWN -255
diff --git a/src/include/auth-passwd-policy-types.h b/src/include/auth-passwd-policy-types.h
index 7a7ea5e..89c9d5a 100644
--- a/src/include/auth-passwd-policy-types.h
+++ b/src/include/auth-passwd-policy-types.h
@@ -29,6 +29,22 @@ extern "C" {
typedef struct auth_password_policy policy_h;
typedef enum {
+ POLICY_USER,
+ POLICY_MAX_ATTEMPTS,
+ POLICY_VALID_PERIOD,
+ POLICY_HISTORY_SIZE,
+ POLICY_MIN_LENGTH,
+ POLICY_MIN_COMPLEX_CHAR_NUMBER,
+ POLICY_MAX_CHAR_OCCURRENCES,
+ POLICY_MAX_NUMERIC_SEQ_LENGTH,
+ POLICY_QUALITY_TYPE,
+ POLICY_PATTERN,
+ POLICY_FORBIDDEN_PASSWDS,
+ POLICY_TYPE_FIRST = POLICY_MAX_ATTEMPTS,
+ POLICY_TYPE_LAST = POLICY_FORBIDDEN_PASSWDS
+} password_policy_type;
+
+typedef enum {
AUTH_PWD_NORMAL,
AUTH_PWD_RECOVERY
} password_type;
@@ -38,7 +54,8 @@ typedef enum {
AUTH_PWD_QUALITY_SOMETHING,
AUTH_PWD_QUALITY_NUMERIC,
AUTH_PWD_QUALITY_ALPHABETIC,
- AUTH_PWD_QUALITY_ALPHANUMERIC
+ AUTH_PWD_QUALITY_ALPHANUMERIC,
+ AUTH_PWD_QUALITY_LAST = AUTH_PWD_QUALITY_ALPHANUMERIC
} password_quality_type;
#ifdef __cplusplus
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 72e99b7..62a1695 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -29,6 +29,8 @@ SET(SERVER_SOURCES
${SERVER_PATH}/service/password-file.cpp
${SERVER_PATH}/service/password-manager.cpp
${SERVER_PATH}/service/password-file-buffer.cpp
+ ${SERVER_PATH}/service/policy-manager.cpp
+ ${SERVER_PATH}/service/policy-file.cpp
)
SET_SOURCE_FILES_PROPERTIES(
diff --git a/src/server/service/include/password-file.h b/src/server/service/include/password-file.h
index 9b18365..1ab4fcb 100644
--- a/src/server/service/include/password-file.h
+++ b/src/server/service/include/password-file.h
@@ -73,8 +73,11 @@ namespace AuthPasswd
void setMaxHistorySize(unsigned int history);
unsigned int getMaxHistorySize() const;
+ unsigned int getExpireTime() const;
+ void setExpireTime(unsigned int expireTime);
+
unsigned int getExpireTimeLeft() const;
- void setExpireTime(time_t expireTime);
+ void setExpireTimeLeft(time_t expireTimeLeft);
//attempt manipulating functions
unsigned int getAttempt() const;
@@ -122,7 +125,8 @@ namespace AuthPasswd
PasswordList m_passwordHistory;
unsigned int m_maxAttempt;
unsigned int m_maxHistorySize;
- time_t m_expireTime;
+ unsigned int m_expireTime;
+ time_t m_expireTimeLeft;
bool m_passwordActive;
bool m_passwordRcvActive;
diff --git a/src/server/service/include/password-manager.h b/src/server/service/include/password-manager.h
index 4832b57..be1075d 100644
--- a/src/server/service/include/password-manager.h
+++ b/src/server/service/include/password-manager.h
@@ -41,7 +41,7 @@ namespace AuthPasswd
//checking functions
//no const in checkPassword, attempts are update
- int checkPassword(const unsigned int passwdType, const std::string& challenge,
+ 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,
@@ -52,23 +52,19 @@ namespace AuthPasswd
//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);
+ const std::string &newPassword, const unsigned int currentUser);
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);
+ const unsigned int currentUser);
//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);
+ const unsigned int receivedUser);
//setting policy on the current passwd
- int setPasswordMaxAttempts(const unsigned int receivedUser,
+ void 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);
+ void setPasswordValidity(const unsigned int receivedUser, const unsigned int receivedDays);
+ void setPasswordHistory(const unsigned int receivedUser, const unsigned int receivedHistory);
private:
//managing functions
diff --git a/src/server/service/include/password.h b/src/server/service/include/password.h
index 1f69592..9063e07 100644
--- a/src/server/service/include/password.h
+++ b/src/server/service/include/password.h
@@ -34,9 +34,9 @@
#include <message-buffer.h>
#include <connection-info.h>
#include <protocols.h>
-#include <policy.h>
#include <password-manager.h>
+#include <policy-manager.h>
namespace AuthPasswd
{
@@ -81,6 +81,7 @@ namespace AuthPasswd
// service attributes
PasswordManager m_pwdManager;
+ PolicyManager m_policyManager;
ConnectionInfoMap m_connectionInfoMap;
};
} // namespace AuthPasswd
diff --git a/src/server/service/include/policy-file.h b/src/server/service/include/policy-file.h
new file mode 100644
index 0000000..f258f47
--- /dev/null
+++ b/src/server/service/include/policy-file.h
@@ -0,0 +1,94 @@
+/*
+ * 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-file.h
+ * @author Jooseong Lee (jooseong.lee@samsung.com)
+ * @version 1.0
+ * @brief Implementation of PolicyFile, used to manage policy files.
+ */
+#ifndef _POLICY_FILE_H_
+#define _PILICY_FILE_H_
+
+#include <string>
+#include <vector>
+#include <list>
+#include <memory>
+
+#include <dpl/serialization.h>
+
+namespace AuthPasswd
+{
+ class PolicyFile
+ {
+ public:
+ PolicyFile(const unsigned int user);
+
+ void enable();
+ void disable();
+
+ bool isPolicyActive() const;
+
+ void writeMemoryToFile() const;
+
+ bool checkMinLength(const std::string &password) const;
+ void setMinLength(unsigned int minLength);
+
+ bool checkMinComplexCharNumber(const std::string &password) const;
+ void setMinComplexCharNumber(unsigned int minComplexCharNumber);
+
+ bool checkMaxCharOccurrences(const std::string &password) const;
+ void setMaxCharOccurrences(unsigned int maxCharOccurrences);
+
+ bool checkMaxNumSeqLength(const std::string &password) const;
+ void setMaxNumSeqLength(unsigned int maxNumSeqLength);
+
+ bool checkQualityType(const std::string &password) const;
+ void setQualityType(unsigned int qualityType);
+
+ bool isValidPattern(const std::string &pattern) const;
+ bool checkPattern(const std::string &password) const;
+ void setPattern(const std::string &pattern);
+
+ bool checkForbiddenPasswds(const std::string &password) const;
+ void setForbiddenPasswds(std::vector<std::string> forbiddenPasswds);
+
+ private:
+ void loadMemoryFromFile();
+ void preparePolicyFile();
+ 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;
+
+ //user name
+ unsigned int m_user;
+
+ bool m_enable;
+
+ //policy file data
+ unsigned int m_minLength;
+ unsigned int m_minComplexCharNumber;
+ unsigned int m_maxCharOccurrences;
+ unsigned int m_maxNumSeqLength;
+ unsigned int m_qualityType;
+ std::string m_pattern;
+ std::vector<std::string> m_forbiddenPasswds;
+ };
+} //namespace AuthPasswd
+
+#endif
diff --git a/src/server/service/include/policy-manager.h b/src/server/service/include/policy-manager.h
new file mode 100644
index 0000000..c83b811
--- /dev/null
+++ b/src/server/service/include/policy-manager.h
@@ -0,0 +1,64 @@
+/*
+ * 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-manager.h
+ * @author Jooseong Lee (jooseong.lee@samsung.com)
+ * @version 1.0
+ * @brief Implementation of password management functions
+ */
+
+#ifndef _POLICYMANAGER_H_
+#define _POLICYMANAGER_H_
+
+#include <string>
+#include <map>
+
+#include <policy.h>
+
+#include <policy-file.h>
+
+namespace AuthPasswd
+{
+ class PolicyManager
+ {
+ public:
+ typedef std::map<unsigned int, PolicyFile> PolicyFileMap;
+
+ // policy checking functions
+ int checkPolicy(const unsigned int passwdType,
+ const std::string &currentPassword,
+ const std::string &newPassword,
+ const unsigned int user);
+
+ // policy setting functions
+ int setPolicy(const auth_password_policy policy);
+
+ // policy disabling functions
+ int disablePolicy(const unsigned int user);
+
+ private:
+ // managing functions
+ void addPolicy(const unsigned int user);
+ void removePolicy(const unsigned int user);
+ void existPolicy(const unsigned int user);
+
+ PolicyFileMap m_policyFile;
+ };
+} //namespace AuthPasswd
+
+#endif
diff --git a/src/server/service/password-file.cpp b/src/server/service/password-file.cpp
index 22a768d..d53435b 100644
--- a/src/server/service/password-file.cpp
+++ b/src/server/service/password-file.cpp
@@ -45,7 +45,7 @@
#include <auth-passwd-error.h>
#include <error-description.h>
-#include <protocols.h>
+#include <policy.h>
#include <password-exception.h>
#include <password-file-buffer.h>
@@ -144,14 +144,14 @@ namespace AuthPasswd
m_passwordRecovery(new NoPassword()),
m_maxAttempt(PASSWORD_INFINITE_ATTEMPT_COUNT),
m_maxHistorySize(0),
- m_expireTime(PASSWORD_INFINITE_EXPIRATION_TIME),
+ 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(DATA_DIR.c_str(), m_user);
if (!dirExists(DATA_DIR.c_str())) {
@@ -177,7 +177,8 @@ namespace AuthPasswd
{
m_maxAttempt = PASSWORD_INFINITE_ATTEMPT_COUNT;
m_maxHistorySize = 0;
- m_expireTime = PASSWORD_INFINITE_EXPIRATION_TIME;
+ m_expireTime = PASSWORD_INFINITE_EXPIRATION_DAYS;
+ m_expireTimeLeft = PASSWORD_INFINITE_EXPIRATION_TIME;
m_passwordRcvActive = false;
m_passwordRecovery.reset(new NoPassword());
m_passwordActive = false;
@@ -278,14 +279,16 @@ namespace AuthPasswd
LogSecureDebug("User: " << m_user << ", saving max_att: " << m_maxAttempt <<
", history_size: " << m_maxHistorySize << ", m_expireTime: " <<
- m_expireTime << ", isActive: " << m_passwordActive <<
- ", isRcvActive: " << m_passwordRcvActive);
+ 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_passwordRecovery);
Serialization::Serialize(pwdBuffer, m_passwordActive);
@@ -318,6 +321,7 @@ namespace AuthPasswd
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_passwordRecovery);
Deserialization::Deserialize(pwdBuffer, m_passwordActive);
@@ -326,8 +330,9 @@ namespace AuthPasswd
LogSecureDebug("User: " << m_user << ", loaded max_att: " << m_maxAttempt <<
", history_size: " << m_maxHistorySize << ", m_expireTime: " <<
- m_expireTime << ", isActive: " << m_passwordActive <<
- ", isRcvActive: " << m_passwordRcvActive);
+ m_expireTime << ", m_expireTimeLeft: " << m_expireTimeLeft <<
+ ", isActive: " << m_passwordActive << ", isRcvActive: " <<
+ m_passwordRcvActive);
}
bool PasswordFile::tryLoadMemoryFromOldFormatFile()
@@ -352,9 +357,9 @@ namespace AuthPasswd
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;
+ Deserialization::Deserialize(pwdBuffer, m_expireTimeLeft);
+ if (m_expireTimeLeft == 0)
+ m_expireTimeLeft = PASSWORD_INFINITE_EXPIRATION_TIME;
if (remaining == VERSION_2_REMAINING)
Deserialization::Deserialize(pwdBuffer, m_passwordActive);
@@ -386,6 +391,7 @@ namespace AuthPasswd
);
}
+ m_expireTime = PASSWORD_INFINITE_EXPIRATION_DAYS;
m_passwordRcvActive = false;
m_passwordRecovery.reset(new NoPassword());
@@ -531,15 +537,25 @@ namespace AuthPasswd
return ret;
}
- void PasswordFile::setExpireTime(time_t expireTime)
+ 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_expireTime != PASSWORD_INFINITE_EXPIRATION_TIME) {
- time_t timeLeft = m_expireTime - time(NULL);
+ 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;
@@ -548,7 +564,7 @@ namespace AuthPasswd
bool PasswordFile::checkExpiration() const
{
//return true if expired, else false
- return ((m_expireTime != PASSWORD_INFINITE_EXPIRATION_TIME) && (time(NULL) > m_expireTime));
+ return ((m_expireTimeLeft != PASSWORD_INFINITE_EXPIRATION_TIME) && (time(NULL) > m_expireTimeLeft));
}
bool PasswordFile::checkIfAttemptsExceeded() const
diff --git a/src/server/service/password-manager.cpp b/src/server/service/password-manager.cpp
index 2cc39f2..8c1bd91 100644
--- a/src/server/service/password-manager.cpp
+++ b/src/server/service/password-manager.cpp
@@ -37,26 +37,20 @@
#include <auth-passwd-policy-types.h>
#include <auth-passwd-error.h>
-#include <protocols.h>
+#include <policy.h>
namespace {
- bool calculateExpiredTime(unsigned int receivedDays, time_t &validSecs)
+ void 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;
+ return;
time_t curTime = time(NULL);
-
- if (receivedDays > ((UINT_MAX - curTime) / 86400)) {
- LogError("Incorrect input param.");
- return false;
- } else {
- validSecs = (curTime + (receivedDays * 86400));
- return true;
- }
+ validSecs = (curTime + (receivedDays * 86400));
+ return;
}
} //namespace
@@ -205,19 +199,15 @@ namespace AuthPasswd
return AUTH_PASSWD_API_SUCCESS;
}
- int PasswordManager::setPassword(const unsigned int passwdType,
+ 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)
+ const unsigned int currentUser)
{
LogSecureDebug("curUser = " << currentUser << ", pwdType = " << passwdType <<
- ", curPwd = " << currentPassword << ", newPwd = " << newPassword <<
- ", recAtt = " << receivedAttempts << ", recDays = " << receivedDays <<
- ", recHistory = " << receivedHistory);
+ ", curPwd = " << currentPassword << ", newPwd = " << newPassword);
+ unsigned int receivedDays = PASSWORD_INFINITE_EXPIRATION_DAYS;
time_t valid_secs = 0;
existPassword(currentUser);
@@ -228,16 +218,6 @@ namespace AuthPasswd
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)) {
@@ -247,11 +227,6 @@ namespace AuthPasswd
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();
@@ -279,16 +254,14 @@ namespace AuthPasswd
}
}
- if (!calculateExpiredTime(receivedDays, valid_secs)) {
- LogError("Received expiration time incorrect.");
- return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
- }
+ if (!newPassword.empty())
+ receivedDays = itPwd->second.getExpireTime();
+
+ calculateExpiredTime(receivedDays, valid_secs);
//setting password
itPwd->second.setPassword(AUTH_PWD_NORMAL, newPassword);
- itPwd->second.setMaxAttempt(receivedAttempts);
- itPwd->second.setExpireTime(valid_secs);
- itPwd->second.setMaxHistorySize(receivedHistory);
+ itPwd->second.setExpireTimeLeft(valid_secs);
itPwd->second.writeMemoryToFile();
break;
@@ -310,15 +283,12 @@ namespace AuthPasswd
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)
+ const unsigned int currentUser)
{
LogSecureDebug("curUser = " << currentUser << ", curPwd = " << curRcvPassword <<
- ", newPwd = " << newPassword << ", recAtt = " << receivedAttempts <<
- ", recDays = " << receivedDays << ", recHistory = " << receivedHistory);
+ ", newPwd = " << newPassword);
+ unsigned int receivedDays = PASSWORD_INFINITE_EXPIRATION_DAYS;
time_t valid_secs = 0;
existPassword(currentUser);
@@ -330,12 +300,8 @@ namespace AuthPasswd
}
//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.");
+ if (curRcvPassword.empty() || newPassword.empty()) {
+ LogError("Incorrect input param.");
return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
}
@@ -345,6 +311,12 @@ namespace AuthPasswd
return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
}
+ receivedDays = itPwd->second.getExpireTime();
+
+ // don't recovery password if MaxAttempt value is not infinite.
+ if (receivedDays != PASSWORD_INFINITE_EXPIRATION_DAYS)
+ return AUTH_PASSWD_API_ERROR_RECOVERY_PASSWORD_RESTRICTED;
+
if (!itPwd->second.checkPassword(AUTH_PWD_RECOVERY, curRcvPassword)) {
LogError("Wrong password.");
return AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH;
@@ -358,19 +330,14 @@ namespace AuthPasswd
}
}
- if (!calculateExpiredTime(receivedDays, valid_secs)) {
- LogError("Received expiration time incorrect.");
- return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
- }
+ calculateExpiredTime(receivedDays, valid_secs);
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.setExpireTimeLeft(valid_secs);
itPwd->second.writeMemoryToFile();
return AUTH_PASSWD_API_SUCCESS;
@@ -378,11 +345,9 @@ namespace AuthPasswd
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)
+ const unsigned int receivedUser)
{
+ unsigned int receivedDays = PASSWORD_INFINITE_EXPIRATION_DAYS;
time_t valid_secs = 0;
existPassword(receivedUser);
@@ -390,19 +355,17 @@ namespace AuthPasswd
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;
- }
+ if (!newPassword.empty())
+ receivedDays = itPwd->second.getExpireTime();
+
+ calculateExpiredTime(receivedDays, valid_secs);
+
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.setExpireTimeLeft(valid_secs);
itPwd->second.writeMemoryToFile();
break;
@@ -418,65 +381,49 @@ namespace AuthPasswd
return AUTH_PASSWD_API_SUCCESS;
}
- int PasswordManager::setPasswordMaxAttempts(const unsigned int receivedUser,
+ void PasswordManager::setPasswordMaxAttempts(const unsigned int receivedUser,
const unsigned int receivedAttempts)
{
+ LogSecureDebug("received_attempts: " << 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,
+ void PasswordManager::setPasswordValidity(const unsigned int receivedUser,
const unsigned int receivedDays)
{
- time_t valid_secs = 0;
-
LogSecureDebug("received_days: " << receivedDays);
+ time_t valid_secs = 0;
+
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;
- }
+ calculateExpiredTime(receivedDays, valid_secs);
- if (!calculateExpiredTime(receivedDays, valid_secs))
- return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ if (itPwd->second.isPasswordActive(AUTH_PWD_NORMAL))
+ itPwd->second.setExpireTimeLeft(valid_secs);
- itPwd->second.setExpireTime(valid_secs);
+ itPwd->second.setExpireTime(receivedDays);
itPwd->second.writeMemoryToFile();
-
- return AUTH_PASSWD_API_SUCCESS;
}
- int PasswordManager::setPasswordHistory(const unsigned int receivedUser,
+ void PasswordManager::setPasswordHistory(const unsigned int receivedUser,
const unsigned int receivedHistory)
{
+ LogSecureDebug("received_historySize: " << 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
index 4267539..8e8f2a0 100644
--- a/src/server/service/password.cpp
+++ b/src/server/service/password.cpp
@@ -34,6 +34,7 @@
#include <password.h>
+#include <auth-passwd-policy-types.h>
#include <auth-passwd-error.h>
#include <password-exception.h>
@@ -141,7 +142,6 @@ int PasswordService::processCheckFunctions(PasswordHdrs hdr, MessageBuffer& buff
LogError("Unknown msg header.");
Throw(Exception::IncorrectHeader);
}
-
return result;
}
@@ -150,32 +150,26 @@ int PasswordService::processSetFunctions(PasswordHdrs hdr, MessageBuffer& buffer
{
int result = AUTH_PASSWD_API_ERROR_SERVER_ERROR;
- switch(hdr) {
+ switch (hdr) {
case PasswordHdrs::HDR_SET_PASSWD: {
std::string curPasswd, newPasswd;
- unsigned int passwdType = 0, rec_att = 0, rec_days = 0, rec_history = 0;
+ unsigned int passwdType = 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);
+ result = m_policyManager.checkPolicy(passwdType, curPasswd, newPasswd, cur_user);
+ if (result == AUTH_PASSWD_API_SUCCESS)
+ result = m_pwdManager.setPassword(passwdType, curPasswd, newPasswd, cur_user);
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);
+ result = m_policyManager.checkPolicy(AUTH_PWD_NORMAL, curRcvPasswd, newPasswd, cur_user);
+ if (result == AUTH_PASSWD_API_SUCCESS)
+ result = m_pwdManager.setPasswordRecovery(curRcvPasswd, newPasswd, cur_user);
break;
}
@@ -192,7 +186,6 @@ int PasswordService::processSetFunctions(PasswordHdrs hdr, MessageBuffer& buffer
LogError("Unknown msg header.");
Throw(Exception::IncorrectHeader);
}
-
return result;
}
@@ -200,55 +193,72 @@ int PasswordService::processResetFunctions(PasswordHdrs hdr, MessageBuffer& buff
{
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;
+ std::string newPasswd, emptyStr="";
+ unsigned int passwdType = 0, rec_user = 0;
- switch(hdr) {
+ 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);
+ result = m_pwdManager.resetPassword(passwdType, newPasswd, rec_user);
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;
+ int rec_user = 0;
+ auth_password_policy policy;
- 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);
+ switch (hdr) {
+ case PasswordHdrs::HDR_SET_PASSWD_POLICY:
+ Deserialization::Deserialize(buffer, policy.policyFlag);
+ Deserialization::Deserialize(buffer, policy.uid);
+ Deserialization::Deserialize(buffer, policy.maxAttempts);
+ Deserialization::Deserialize(buffer, policy.validPeriod);
+ Deserialization::Deserialize(buffer, policy.historySize);
+ Deserialization::Deserialize(buffer, policy.minLength);
+ Deserialization::Deserialize(buffer, policy.minComplexCharNumber);
+ Deserialization::Deserialize(buffer, policy.maxCharOccurrences);
+ Deserialization::Deserialize(buffer, policy.maxNumSeqLength);
+ Deserialization::Deserialize(buffer, policy.qualityType);
+ Deserialization::Deserialize(buffer, policy.pattern);
+ Deserialization::Deserialize(buffer, policy.forbiddenPasswds);
+
+ result = m_policyManager.setPolicy(policy);
+
+ if (result == AUTH_PASSWD_API_SUCCESS) {
+ if (policy.policyFlag & (1 << POLICY_MAX_ATTEMPTS))
+ m_pwdManager.setPasswordMaxAttempts(policy.uid, policy.maxAttempts);
+ if (policy.policyFlag & (1 << POLICY_VALID_PERIOD))
+ m_pwdManager.setPasswordValidity(policy.uid, policy.validPeriod);
+ if (policy.policyFlag & (1 << POLICY_HISTORY_SIZE))
+ m_pwdManager.setPasswordHistory(policy.uid, policy.historySize);
+ }
+ break;
- 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;
+ case PasswordHdrs::HDR_DIS_PASSWD_POLICY:
+ Deserialization::Deserialize(buffer, rec_user);
+ result = m_policyManager.disablePolicy(rec_user);
+ if (result == AUTH_PASSWD_API_SUCCESS) {
+ m_pwdManager.setPasswordMaxAttempts(rec_user, PASSWORD_INFINITE_ATTEMPT_COUNT);
+ m_pwdManager.setPasswordValidity(rec_user, PASSWORD_INFINITE_EXPIRATION_DAYS);
+ m_pwdManager.setPasswordHistory(rec_user, 0);
+ }
+ break;
default:
LogError("Unknown msg header.");
Throw(Exception::IncorrectHeader);
}
-*/
+
return result;
}
diff --git a/src/server/service/policy-file.cpp b/src/server/service/policy-file.cpp
new file mode 100644
index 0000000..5c41fbc
--- /dev/null
+++ b/src/server/service/policy-file.cpp
@@ -0,0 +1,434 @@
+/*
+ * 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-file.cpp
+ * @author Jooseong Lee (jooseong.lee@samsung.com)
+ * @version 1.0
+ * @brief Implementation of PolicyFile, used to manage policy files.
+ */
+#include <policy-file.h>
+
+#include <fstream>
+#include <algorithm>
+#include <regex.h>
+
+#include <fcntl.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <tzplatform_config.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 DATA_DIR = tzplatform_mkpath(TZ_SYS_DATA, "authentication-server");
+ const std::string POLICY_FILE = "/policy";
+ const mode_t FILE_MODE = S_IRUSR | S_IWUSR;
+ const unsigned int CURRENT_FILE_VERSION = 1;
+} // namespace anonymous
+
+namespace AuthPasswd
+{
+ PolicyFile::PolicyFile(const unsigned int user): m_user(user),
+ m_enable(false),
+ m_minLength(0),
+ m_minComplexCharNumber(0),
+ m_maxCharOccurrences(0),
+ m_maxNumSeqLength(0),
+ m_qualityType(AUTH_PWD_QUALITY_UNSPECIFIED),
+ m_pattern(NO_PATTERN)
+ {
+ // 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);
+ }
+ }
+
+ preparePolicyFile();
+ }
+
+ void PolicyFile::resetState()
+ {
+ m_enable = false;
+ m_minLength = 0;
+ m_minComplexCharNumber = 0;
+ m_maxCharOccurrences = 0;
+ m_maxNumSeqLength = 0;
+ m_qualityType = AUTH_PWD_QUALITY_UNSPECIFIED;
+ m_pattern = NO_PATTERN;
+ m_forbiddenPasswds.clear();
+ }
+
+ void PolicyFile::preparePolicyFile()
+ {
+ std::string policyFile = createDir(DATA_DIR.c_str(), m_user) + POLICY_FILE;
+
+ // check if policy file exists
+ if (!fileExists(policyFile)) {
+ LogSecureDebug("POLICY_DBG not found " << m_user << " policy file. Creating.");
+
+ //create file
+ writeMemoryToFile();
+ } else { //if file exists, load data
+ LogSecureDebug("POLICY_DBG found " << m_user << " policy file. Opening.");
+ try {
+ loadMemoryFromFile();
+ } catch (...) {
+ LogError("Invalid " << policyFile << " file format");
+ resetState();
+ writeMemoryToFile();
+ }
+ }
+ }
+
+ bool PolicyFile::fileExists(const std::string &filename) const
+ {
+ struct stat buf;
+
+ return ((stat(filename.c_str(), &buf) == 0));
+ }
+
+ bool PolicyFile::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 PolicyFile::createDir(const std::string &dir, const unsigned int user) const
+ {
+ std::string User = std::to_string(user);
+ return dir + "/" + User;
+ }
+
+ void PolicyFile::writeMemoryToFile() const
+ {
+ PasswordFileBuffer policyBuffer;
+
+ LogSecureDebug("User: " << m_user << ", m_minLength: " << m_minLength <<
+ ", m_minComplexCharNumber: " << m_minComplexCharNumber <<
+ ", m_maxCharOccurrences: " << m_maxCharOccurrences <<
+ ", m_maxNumSeqLength: " << m_maxNumSeqLength <<
+ ", m_qualityType: " << m_qualityType <<
+ ", m_pattern: " << m_pattern <<
+ ", m_forbiddenPasswds.size: " << m_forbiddenPasswds.size());
+
+ // serialize policy attributes
+ Serialization::Serialize(policyBuffer, CURRENT_FILE_VERSION);
+ Serialization::Serialize(policyBuffer, m_enable);
+ Serialization::Serialize(policyBuffer, m_minLength);
+ Serialization::Serialize(policyBuffer, m_minComplexCharNumber);
+ Serialization::Serialize(policyBuffer, m_maxCharOccurrences);
+ Serialization::Serialize(policyBuffer, m_maxNumSeqLength);
+ Serialization::Serialize(policyBuffer, m_qualityType);
+ Serialization::Serialize(policyBuffer, m_pattern);
+ Serialization::Serialize(policyBuffer, m_forbiddenPasswds);
+
+ std::string policyFile = createDir(DATA_DIR.c_str(), m_user) + POLICY_FILE;
+ policyBuffer.Save(policyFile);
+
+ if (chmod(policyFile.c_str(), FILE_MODE)) {
+ LogError("Failed to chmod for " << policyFile << " Error: " << strerror(errno));
+ Throw(PasswordException::ChmodError);
+ }
+ }
+
+ void PolicyFile::loadMemoryFromFile()
+ {
+ PasswordFileBuffer policyBuffer;
+ std::string policyFile = createDir(DATA_DIR.c_str(), m_user) + POLICY_FILE;
+
+ policyBuffer.Load(policyFile);
+
+ // deserialize policy attributes
+ unsigned int fileVersion = 0;
+ Deserialization::Deserialize(policyBuffer, fileVersion);
+ if (fileVersion != CURRENT_FILE_VERSION)
+ Throw(PasswordException::FStreamReadError);
+
+ Deserialization::Deserialize(policyBuffer, m_enable);
+ Deserialization::Deserialize(policyBuffer, m_minLength);
+ Deserialization::Deserialize(policyBuffer, m_minComplexCharNumber);
+ Deserialization::Deserialize(policyBuffer, m_maxCharOccurrences);
+ Deserialization::Deserialize(policyBuffer, m_maxNumSeqLength);
+ Deserialization::Deserialize(policyBuffer, m_qualityType);
+ Deserialization::Deserialize(policyBuffer, m_pattern);
+ Deserialization::Deserialize(policyBuffer, m_forbiddenPasswds);
+
+ LogSecureDebug("User: " << m_user << ", m_minLength: " << m_minLength <<
+ ", m_minComplexCharNumber: " << m_minComplexCharNumber <<
+ ", m_maxCharOccurrences: " << m_maxCharOccurrences <<
+ ", m_maxNumSeqLength: " << m_maxNumSeqLength <<
+ ", m_qualityType: " << m_qualityType <<
+ ", m_pattern: " << m_pattern <<
+ ", m_forbiddenPasswds.size: " << m_forbiddenPasswds.size());
+ }
+
+ void PolicyFile::enable()
+ {
+ m_enable = true;
+ }
+
+ void PolicyFile::disable()
+ {
+ m_enable = false;
+ resetState();
+ }
+
+ bool PolicyFile::isPolicyActive() const
+ {
+ return m_enable;
+ }
+
+ // policy minLength
+ bool PolicyFile::checkMinLength(const std::string &password) const
+ {
+ return (password.size() >= m_minLength);
+ }
+
+ void PolicyFile::setMinLength(unsigned int minLength)
+ {
+ m_minLength = minLength;
+ }
+
+ // policy minComplexCharNumber
+ bool PolicyFile::checkMinComplexCharNumber(const std::string &password) const
+ {
+ unsigned int i = 0, cnt = 0;
+ char ch;
+
+ if (m_minComplexCharNumber == 0)
+ return true;
+
+ for (i = 0; i < password.size(); i++) {
+ ch = password[i];
+ if( ch < 'A' || ( 'Z' < ch && ch < 'a') || 'z' < ch)
+ cnt++;
+ }
+ return (cnt >= m_minComplexCharNumber);
+ }
+
+ void PolicyFile::setMinComplexCharNumber(unsigned int minComplexCharNumber)
+ {
+ m_minComplexCharNumber = minComplexCharNumber;
+ }
+
+ // policy maxCharOccurrences
+ bool PolicyFile::checkMaxCharOccurrences(const std::string &password) const
+ {
+ unsigned int i = 0;
+ unsigned char ch;
+ char occurrence[256]= {0, };
+
+ if (m_maxCharOccurrences == 0)
+ return true;
+
+ for (i = 0; i < password.size(); i++) {
+ ch = (unsigned char)password[i];
+ occurrence[ch]++;
+ }
+
+ for (i = 0; i<256; i++) {
+ if(occurrence[i] > m_maxCharOccurrences)
+ return false;
+ }
+ return true;
+ }
+
+ void PolicyFile::setMaxCharOccurrences(unsigned int maxCharOccurrences)
+ {
+ m_maxCharOccurrences = maxCharOccurrences;
+ }
+
+ // policy maxNumSeqLength
+ bool PolicyFile::checkMaxNumSeqLength(const std::string &password) const
+ {
+ char curr_ch = 0, prev_num = 0;
+ unsigned int i, num_cnt=0, max_num_seq_len = 0, curr_num_seq_len = 0;
+ unsigned int len = password.size();
+ int order = -2; // -2: not set, -1 : decreasing, 0 : same, +1: increasing
+
+ if (m_maxNumSeqLength == 0)
+ return true;
+
+ for (i = 0; i < len; i++) {
+ curr_ch = password[i];
+ if ('0' <= curr_ch && curr_ch <= '9') {
+ num_cnt++;
+ if (order == -2) { // not set, fist or second char of a sequence
+ if (prev_num == 0) { // fist second char
+ curr_num_seq_len = 1;
+ } else if (curr_ch == prev_num - 1) { // decreasing order
+ order = -1;
+ curr_num_seq_len = 2;
+ } else if (curr_ch == prev_num + 0) { // same order
+ order = 0;
+ curr_num_seq_len = 2;
+ } else if (curr_ch == prev_num + 1) { // increasing order
+ order = 1;
+ curr_num_seq_len = 2;
+ } else { // order restarts again
+ if (max_num_seq_len < curr_num_seq_len)
+ max_num_seq_len = curr_num_seq_len;
+
+ order = -2;
+ curr_num_seq_len = 1;
+ }
+ } else if (curr_ch == prev_num + order) { // order is still working
+ curr_num_seq_len++;
+ } else { // order changed
+ if (max_num_seq_len < curr_num_seq_len)
+ max_num_seq_len = curr_num_seq_len;
+ order = -2;
+ curr_num_seq_len = 1;
+ }
+ prev_num = curr_ch;
+ } else { // order reset
+ if (max_num_seq_len < curr_num_seq_len)
+ max_num_seq_len = curr_num_seq_len;
+
+ order = -2;
+ curr_num_seq_len = 0;
+ prev_num = 0;
+ }
+ }
+ return max_num_seq_len <= m_maxNumSeqLength;
+ }
+
+ void PolicyFile::setMaxNumSeqLength(unsigned int maxNumSeqLength)
+ {
+ m_maxNumSeqLength = maxNumSeqLength;
+ }
+
+ // policy qalityType
+ bool PolicyFile::checkQualityType(const std::string &password) const
+ {
+ std::string pattern;
+
+ switch (m_qualityType) {
+ case AUTH_PWD_QUALITY_UNSPECIFIED:
+ pattern = REGEX_QUALITY_UNSPECIFIED;
+ break;
+
+ case AUTH_PWD_QUALITY_SOMETHING:
+ pattern = REGEX_QUALITY_SOMETHING;
+ break;
+
+ case AUTH_PWD_QUALITY_NUMERIC:
+ pattern = REGEX_QUALITY_NUMERIC;
+ break;
+
+ case AUTH_PWD_QUALITY_ALPHABETIC:
+ pattern = REGEX_QUALITY_ALPHABETIC;
+ break;
+
+ case AUTH_PWD_QUALITY_ALPHANUMERIC:
+ pattern = REGEX_QUALITY_ALPHANUMERIC;
+ break;
+
+ default:
+ return false;
+ }
+
+ regex_t re;
+ if (regcomp(&re, pattern.c_str(), REG_EXTENDED|REG_NEWLINE) != 0)
+ return false;
+ return (regexec(&re, password.c_str(), 0, NULL, 0) == 0);
+ }
+
+ void PolicyFile::setQualityType(unsigned int qualityType)
+ {
+ m_qualityType = qualityType;
+ }
+
+ // policy pattern
+ bool PolicyFile::isValidPattern(const std::string &pattern) const
+ {
+ if (pattern.empty())
+ return true;
+
+ regex_t re;
+ return (regcomp(&re, pattern.c_str(), REG_EXTENDED|REG_NEWLINE) == 0);
+ }
+
+ bool PolicyFile::checkPattern(const std::string &password) const
+ {
+ if (m_pattern.empty())
+ return true;
+
+ regex_t re;
+ if (regcomp(&re, m_pattern.c_str(), REG_EXTENDED|REG_NEWLINE) != 0)
+ return false;
+
+ return (regexec(&re, password.c_str(), 0, NULL, 0) == 0);
+ }
+
+ void PolicyFile::setPattern(const std::string &pattern)
+ {
+ m_pattern = pattern;
+ }
+
+ // policy forbiddenPasswds
+ bool PolicyFile::checkForbiddenPasswds(const std::string &password) const
+ {
+ if (password.empty())
+ return true;
+
+ return (std::find(m_forbiddenPasswds.begin(), m_forbiddenPasswds.end(), password)
+ == m_forbiddenPasswds.end());
+ }
+
+ void PolicyFile::setForbiddenPasswds(std::vector<std::string> forbiddenPasswds)
+ {
+ for (std::vector<std::string>::iterator it = forbiddenPasswds.begin() ;
+ it != forbiddenPasswds.end() ; ++it) {
+
+ std::string forbiddenPasswd = *it;
+ LogError("forbiddenPasswd : " << forbiddenPasswd);
+
+ if (forbiddenPasswd.empty())
+ m_forbiddenPasswds.clear();
+ else
+ if (std::find(m_forbiddenPasswds.begin(), m_forbiddenPasswds.end(), forbiddenPasswd)
+ == m_forbiddenPasswds.end())
+ m_forbiddenPasswds.push_back(forbiddenPasswd);
+ }
+ }
+} //namespace AuthPasswd
diff --git a/src/server/service/policy-manager.cpp b/src/server/service/policy-manager.cpp
new file mode 100644
index 0000000..e206b14
--- /dev/null
+++ b/src/server/service/policy-manager.cpp
@@ -0,0 +1,273 @@
+/*
+ * 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-manager.cpp
+ * @author Jooseong Lee (jooseong.lee@samsung.com)
+ * @version 1.0
+ * @brief Implementation of password policy management functions
+ */
+
+#include <policy-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>
+
+namespace AuthPasswd
+{
+
+ void PolicyManager::addPolicy(const unsigned int user)
+ {
+ m_policyFile.insert(PolicyFileMap::value_type(user, PolicyFile(user)));
+ }
+
+ void PolicyManager::removePolicy(const unsigned int user)
+ {
+ m_policyFile.erase(user);
+ }
+
+ void PolicyManager::existPolicy(const unsigned int user)
+ {
+ PolicyFileMap::iterator itPwd = m_policyFile.find(user);
+ if (itPwd != m_policyFile.end())
+ return;
+
+ addPolicy(user);
+ return;
+ }
+
+ int PolicyManager::checkPolicy(const unsigned int passwdType,
+ const std::string &currentPassword,
+ const std::string &newPassword,
+ const unsigned int user)
+ {
+ LogSecureDebug("Inside checkPolicy function.");
+
+ // 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;
+ }
+
+ existPolicy(user);
+ PolicyFileMap::iterator itPolicy = m_policyFile.find(user);
+
+ if (!itPolicy->second.isPolicyActive() || (passwdType != AUTH_PWD_NORMAL))
+ return AUTH_PASSWD_API_SUCCESS;
+
+ if (!itPolicy->second.checkMinLength(newPassword)) {
+ LogError("new passwd's minLength is invalid");
+ return AUTH_PASSWD_API_ERROR_PASSWORD_INVALID;
+ }
+ if (!itPolicy->second.checkMinComplexCharNumber(newPassword)) {
+ LogError("new passwd's minComplexCharNumber is invalid");
+ return AUTH_PASSWD_API_ERROR_PASSWORD_INVALID;
+ }
+ if (!itPolicy->second.checkMaxCharOccurrences(newPassword)) {
+ LogError("new passwd's maxCharOccurrences is invalid");
+ return AUTH_PASSWD_API_ERROR_PASSWORD_INVALID;
+ }
+ if (!itPolicy->second.checkMaxNumSeqLength(newPassword)) {
+ LogError("new passwd's maxNumSeqLength is invalid");
+ return AUTH_PASSWD_API_ERROR_PASSWORD_INVALID;
+ }
+ if (!itPolicy->second.checkQualityType(newPassword)) {
+ LogError("new passwd's qualityType is invalid");
+ return AUTH_PASSWD_API_ERROR_PASSWORD_INVALID;
+ }
+ if (!itPolicy->second.checkPattern(newPassword)) {
+ LogError("new passwd's pattern is invalid");
+ return AUTH_PASSWD_API_ERROR_PASSWORD_INVALID;
+ }
+ if (!itPolicy->second.checkForbiddenPasswds(newPassword)) {
+ LogError("new passwd is forbiddenPasswd");
+ return AUTH_PASSWD_API_ERROR_PASSWORD_INVALID;
+ }
+
+ return AUTH_PASSWD_API_SUCCESS;
+ }
+
+ int PolicyManager::setPolicy(const auth_password_policy policy)
+ {
+ LogSecureDebug("Inside setPolicy function.");
+
+ existPolicy(policy.uid);
+ PolicyFileMap::iterator itPolicy = m_policyFile.find(policy.uid);
+
+ // check if policies are correct
+ for (int i = POLICY_TYPE_FIRST ; i < POLICY_TYPE_LAST+1 ; i++) {
+ if (policy.policyFlag & (1 << i)) {
+ switch (i) {
+ case POLICY_MAX_ATTEMPTS:
+ break;
+
+ case POLICY_VALID_PERIOD: {
+ time_t curTime = time(NULL);
+ if (policy.validPeriod > ((UINT_MAX - curTime) / 86400)) {
+ LogError("Incorrect input param.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ break;
+ }
+
+ case POLICY_HISTORY_SIZE:
+ if (policy.historySize > MAX_PASSWORD_HISTORY) {
+ LogError("Incorrect input param.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ break;
+
+ case POLICY_MIN_LENGTH:
+ if (policy.minLength > MAX_PASSWORD_LEN) {
+ LogError("Incorrect input param.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ break;
+
+ case POLICY_MIN_COMPLEX_CHAR_NUMBER:
+ if (policy.minComplexCharNumber > MAX_PASSWORD_LEN) {
+ LogError("Incorrect input param.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ break;
+
+ case POLICY_MAX_CHAR_OCCURRENCES:
+ if (policy.maxCharOccurrences > MAX_PASSWORD_LEN) {
+ LogError("Incorrect input param.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ break;
+
+ case POLICY_MAX_NUMERIC_SEQ_LENGTH:
+ if (policy.maxNumSeqLength > MAX_PASSWORD_LEN) {
+ LogError("Incorrect input param.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ break;
+
+ case POLICY_QUALITY_TYPE:
+ if (policy.qualityType > AUTH_PWD_QUALITY_LAST) {
+ LogError("Incorrect input param.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ break;
+
+ case POLICY_PATTERN:
+ if (!itPolicy->second.isValidPattern(policy.pattern)) {
+ LogError("Incorrect input param.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ break;
+
+ case POLICY_FORBIDDEN_PASSWDS:
+ break;
+
+ default:
+ LogError("Not supported policy type.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ }
+ }
+
+ // update policies
+ for (int i = POLICY_TYPE_FIRST ; i < POLICY_TYPE_LAST+1 ; i++) {
+ if (policy.policyFlag & (1 << i)) {
+ switch (i) {
+ case POLICY_MAX_ATTEMPTS:
+ LogSecureDebug("maxAttempts: " << policy.maxAttempts);
+ break;
+
+ case POLICY_VALID_PERIOD:
+ LogSecureDebug("validPeriod: " << policy.validPeriod);
+ break;
+
+ case POLICY_HISTORY_SIZE:
+ LogSecureDebug("historySize: " << policy.historySize);
+ break;
+
+ case POLICY_MIN_LENGTH:
+ LogSecureDebug("minLength: " << policy.minLength);
+ itPolicy->second.setMinLength(policy.minLength);
+ break;
+
+ case POLICY_MIN_COMPLEX_CHAR_NUMBER:
+ LogSecureDebug("minComplexCharNumber: " << policy.minComplexCharNumber);
+ itPolicy->second.setMinComplexCharNumber(policy.minComplexCharNumber);
+ break;
+
+ case POLICY_MAX_CHAR_OCCURRENCES:
+ LogSecureDebug("maxCharOccurrences: " << policy.maxCharOccurrences);
+ itPolicy->second.setMaxCharOccurrences(policy.maxCharOccurrences);
+ break;
+
+ case POLICY_MAX_NUMERIC_SEQ_LENGTH:
+ LogSecureDebug("maxNumSeqLength: " << policy.maxNumSeqLength);
+ itPolicy->second.setMaxNumSeqLength(policy.maxNumSeqLength);
+ break;
+
+ case POLICY_QUALITY_TYPE:
+ LogSecureDebug("qualityType: " << policy.qualityType);
+ itPolicy->second.setQualityType(policy.qualityType);
+ break;
+
+ case POLICY_PATTERN:
+ LogSecureDebug("pattern: " << policy.pattern);
+ itPolicy->second.setPattern(policy.pattern);
+ break;
+
+ case POLICY_FORBIDDEN_PASSWDS:
+ LogSecureDebug("forbiddenPasswds number: " << policy.forbiddenPasswds.size());
+ itPolicy->second.setForbiddenPasswds(policy.forbiddenPasswds);
+ break;
+
+ default:
+ LogError("Not supported policy type.");
+ return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+ }
+ }
+ }
+ itPolicy->second.enable();
+ itPolicy->second.writeMemoryToFile();
+
+ return AUTH_PASSWD_API_SUCCESS;
+ }
+
+ int PolicyManager::disablePolicy(const unsigned int user)
+ {
+ LogSecureDebug("Inside disablePolicy function.");
+
+ existPolicy(user);
+ PolicyFileMap::iterator itPolicy = m_policyFile.find(user);
+
+ itPolicy->second.disable();
+ itPolicy->second.writeMemoryToFile();
+
+ return AUTH_PASSWD_API_SUCCESS;
+ }
+} //namespace AuthPasswd