Add AUTH_PWD_PIN and AUTH_PWD_PATTERN type 96/318796/7
authorDongsun Lee <ds73.lee@samsung.com>
Thu, 16 Jan 2025 08:12:14 +0000 (17:12 +0900)
committerDongsun Lee <ds73.lee@samsung.com>
Wed, 12 Feb 2025 04:20:14 +0000 (13:20 +0900)
Change-Id: I137da8568fd040fccb475405d0989891f1b61bf6

27 files changed:
src/client/client-password-admin.cpp
src/client/client-password.cpp
src/common/include/policy.h
src/common/policy.cpp
src/include/auth-passwd-admin.h
src/include/auth-passwd-policy-types.h
src/include/auth-passwd.h
src/server/plugin/generic-backend/ipassword-file.h
src/server/plugin/sw-backend/password-file.cpp
src/server/plugin/sw-backend/password-file.h
src/server/plugin/tz-backend/password-file.cpp
src/server/plugin/tz-backend/password-file.h
src/server/service/include/password-manager.h
src/server/service/include/password-policy-manager.h
src/server/service/include/policy-file.h
src/server/service/password-manager.cpp
src/server/service/password-policy-manager.cpp
src/server/service/password.cpp
src/server/service/policy-file.cpp
tests/CMakeLists.txt
tests/test-admin.cpp
tests/test-client.cpp
tests/test-pattern.cpp [new file with mode: 0644]
tests/test-pin.cpp [new file with mode: 0644]
tests/test-sw-backend.cpp
tests/test-util.cpp
tests/test-util.h

index 166ad5f4e8e520bb53f646056054aa3f8548a5f7..0e069d03379a53840ef57d135a7ade6b6663afe6 100644 (file)
@@ -105,6 +105,18 @@ int auth_passwd_set_user(policy_h *p_policy, uid_t uid)
        return AUTH_PASSWD_API_SUCCESS;
 }
 
+AUTH_PASSWD_API
+int auth_passwd_set_password_type(policy_h *p_policy, password_type type)
+{
+       if (!p_policy)
+               return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+
+       auto policy = reinterpret_cast<AuthPasswd::Policy *>(p_policy);
+       policy->setFlag(POLICY_PASSWORD_TYPE);
+       policy->passwordType = type;
+       return AUTH_PASSWD_API_SUCCESS;
+}
+
 AUTH_PASSWD_API
 int auth_passwd_set_max_attempts(policy_h *p_policy, unsigned int max_attempts)
 {
@@ -246,7 +258,7 @@ int auth_passwd_set_policy(policy_h *p_policy)
 
                auto policy = reinterpret_cast<AuthPasswd::Policy *>(p_policy);
 
-               if (!policy->isFlagOn(POLICY_USER))
+               if (!policy->isFlagOn(POLICY_USER) || !policy->isFlagOn(POLICY_PASSWORD_TYPE))
                        return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
 
                MessageBuffer send, recv;
@@ -275,13 +287,14 @@ void auth_passwd_free_policy(policy_h *p_policy)
 }
 
 AUTH_PASSWD_API
-int auth_passwd_disable_policy(uid_t uid)
+int auth_passwd_disable_policy(password_type passwd_type, 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, passwd_type);
                Serialization::Serialize(send, uid);
 
                int retCode = sendToServer(SERVICE_SOCKET_PASSWD_POLICY, send.Pop(), recv);
index 69dbd67aedd3b0d408313165ef89eadf481a991a..d3c000dba99a3e033de7a8677dfdff26015380f6 100644 (file)
@@ -212,8 +212,9 @@ int auth_passwd_check_passwd_reused(password_type passwd_type,
 }
 
 AUTH_PASSWD_API
-int auth_passwd_set_passwd(password_type passwd_type,
+int auth_passwd_set_passwd(password_type cur_passwd_type,
                                                   const char *cur_passwd,
+                                                  password_type new_passwd_type,
                                                   const char *new_passwd)
 {
        using namespace AuthPasswd;
@@ -232,8 +233,9 @@ int auth_passwd_set_passwd(password_type passwd_type,
                MessageBuffer send, recv;
 
                Serialization::Serialize(send, static_cast<int>(PasswordHdrs::HDR_SET_PASSWD));
-               Serialization::Serialize(send, passwd_type);
+               Serialization::Serialize(send, cur_passwd_type);
                Serialization::Serialize(send, std::string(cur_passwd));
+               Serialization::Serialize(send, new_passwd_type);
                Serialization::Serialize(send, std::string(new_passwd));
 
                int retCode = sendToServer(SERVICE_SOCKET_PASSWD_SET, send.Pop(), recv);
index 52bab33ce8ec4354a3fb4c0ce9932f2a976c8881..7dcddbbec6833cb9a59cb06969921e1d816eade7 100644 (file)
@@ -77,6 +77,13 @@ extern const std::string REGEX_QUALITY_ALPHABETIC;
 COMMON_API
 extern const std::string REGEX_QUALITY_ALPHANUMERIC;
 
+
+COMMON_API
+extern const std::string REGEX_PIN;
+
+COMMON_API
+extern const std::string REGEX_PATTERN;
+
 struct COMMON_API Policy {
        Policy();
        virtual ~Policy();
@@ -102,6 +109,9 @@ struct COMMON_API Policy {
 
        uid_t uid;
 
+       // password type
+       unsigned int passwordType;
+
        // 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
@@ -130,7 +140,9 @@ struct COMMON_API Policy {
 struct COMMON_API PolicySerializable : public Policy, ISerializable {
        explicit PolicySerializable(const Policy &);
        explicit PolicySerializable(IStream &);
+       explicit PolicySerializable(IStream &stream, unsigned int version);
        void Serialize(IStream &) const;
+       void Deserialize(IStream & stream, unsigned int version);
 };
 
 }
index 29a09bc6755dfa8d54893e8474a09e8e7db06db7..df1f6d863b12bc1d1f0ea537beb3ea01a58ce02c 100644 (file)
@@ -43,9 +43,15 @@ 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-z]+.*)(?=.*[0-9]+.*)";
 
+const std::string REGEX_PIN = "[0-9]*";
+const std::string REGEX_PATTERN = REGEX_PIN;
+
+const unsigned int CURRENT_FILE_VERSION = 2;
+
 Policy::Policy() :
        flag(0),
        uid(0),
+       passwordType(0),
        maxAttempts(0),
        validPeriod(0),
        historySize(0),
@@ -76,6 +82,7 @@ std::string Policy::info() const
        ss << " pattern: " << pattern;
        ss << " forbiddenPasswd size: " << forbiddenPasswds.size();
        ss << " forbiddenPasswd items:";
+       ss << " passwordType: " << passwordType;
 
        for (auto &item : forbiddenPasswds)
                ss << " " << item;
@@ -88,6 +95,16 @@ PolicySerializable::PolicySerializable(const Policy &policy) : Policy(policy)
 }
 
 PolicySerializable::PolicySerializable(IStream &stream)
+{
+       Deserialize(stream, CURRENT_FILE_VERSION);
+}
+
+PolicySerializable::PolicySerializable(IStream &stream, unsigned int version)
+{
+       Deserialize(stream, version);
+}
+
+void PolicySerializable::Deserialize(IStream & stream, unsigned int version)
 {
        Deserialization::Deserialize(stream, flag);
        Deserialization::Deserialize(stream, uid);
@@ -101,6 +118,8 @@ PolicySerializable::PolicySerializable(IStream &stream)
        Deserialization::Deserialize(stream, qualityType);
        Deserialization::Deserialize(stream, pattern);
        Deserialization::Deserialize(stream, forbiddenPasswds);
+       if (version == CURRENT_FILE_VERSION)
+               Deserialization::Deserialize(stream, passwordType);
 }
 
 void PolicySerializable::Serialize(IStream &stream) const
@@ -117,6 +136,7 @@ void PolicySerializable::Serialize(IStream &stream) const
        Serialization::Serialize(stream, qualityType);
        Serialization::Serialize(stream, pattern);
        Serialization::Serialize(stream, forbiddenPasswds);
+       Serialization::Serialize(stream, passwordType);
 }
 
 } // namespace AuthPasswd
index 8f14a6020ae42ac01ce6f66df335b11e958650fa..6f386ea8af9208d2446f8471f2ccbe2e8d63ee0c 100644 (file)
@@ -147,6 +147,9 @@ int auth_passwd_new_policy(policy_h **pp_policy);
 /*
  * This API is used to add user to policy_h structure.
  *
+ * \par Important notes:
+ * A uid must be set in policy_h before calling auth_passwd_set_policy().\n
+ *
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] uid Target user.
  *
@@ -154,9 +157,25 @@ int auth_passwd_new_policy(policy_h **pp_policy);
  */
 int auth_passwd_set_user(policy_h *p_policy, uid_t uid);
 
+/*
+ * This API is used to add password_type to policy_h structure.
+ *
+ * \par Important notes:
+ * A password_type must be set in policy_h before calling auth_passwd_set_policy().\n
+ *
+ * \param[in] p_policy Pointer handling p_policy structure.
+ * \param[in] type Target password type.
+ *
+ * \return AUTH_PASSWD_API_SUCCESS if function call was successful. Error code otherwise.
+ */
+int auth_passwd_set_password_type(policy_h *p_policy, password_type type);
+
 /*
  * This API is used to add max attempts to policy_h structure.
  *
+ * \par Coverage:
+ * This policy works for all types of password_type.
+ *
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] max_attempts Number of maximum attempts that the password locks. 0 means infinite.
  *
@@ -167,6 +186,9 @@ int auth_passwd_set_max_attempts(policy_h *p_policy, unsigned int max_attempts);
 /*
  * This API is used to add valid days to policy_h structure.
  *
+ * \par Coverage:
+ * This policy works for all types of password_type.
+ *
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] valid_days Number of days that this password is valid. 0 means infinity.
  *
@@ -177,6 +199,9 @@ int auth_passwd_set_validity(policy_h *p_policy, unsigned int valid_days);
 /*
  * This API is used to add history size to policy_h structure.
  *
+ * \par Coverage:
+ * This policy works for all types of password_type.
+ *
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] history_size Number of history to be checked when user tries to change password. Maximum is currently 50.
  *
@@ -187,6 +212,9 @@ int auth_passwd_set_history_size(policy_h *p_policy, unsigned int history_size);
 /*
  * This API is used to add minimum password length to policy_h structure.
  *
+ * \par Coverage:
+ * This policy works for all types of password_type.
+ *
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] min_length Minimum number of characters of password.
  *
@@ -197,6 +225,9 @@ int auth_passwd_set_min_length(policy_h *p_policy, unsigned int min_length);
 /*
  * This API is used to add a minimum numbum of complex characters(non-alphabetic) to policy_h structure.
  *
+ * \par Coverage:
+ * This policy only works for AUTH_PWD_NORMAL type.
+ *
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] val Minimum number of complex characters in password.
  *
@@ -207,6 +238,9 @@ int auth_passwd_set_min_complex_char_num(policy_h *p_policy, unsigned int val);
 /*
  * This API is used to add maximum count of the same character to policy_h structure.
  *
+ * \par Coverage:
+ *
+ * This policy only works for AUTH_PWD_NORMAL type.
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] val Maximum count of the same character in the password.
  *
@@ -217,6 +251,9 @@ int auth_passwd_set_max_char_occurrences(policy_h *p_policy, unsigned int val);
 /*
  * This API is used to add maximum numeric sequence length to policy_h structure.
  *
+ * \par Coverage:
+ * This policy only works for AUTH_PWD_NORMAL type.
+ *
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] val Maximum numeric sequence length in the password
  *            regardless descending order, ascending order or repetitiona.
@@ -228,6 +265,9 @@ int auth_passwd_set_max_num_seq_len(policy_h *p_policy, unsigned int val);
 /*
  * This API is used to add password quality type to policy_h structure.
  *
+ * \par Coverage:
+ * This policy only works for AUTH_PWD_NORMAL type.
+ *
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] quality_type password complexity type.
  *
@@ -238,6 +278,9 @@ int auth_passwd_set_quality(policy_h *p_policy, password_quality_type quality_ty
 /*
  * This API is used to add password pattern to policy_h structure.
  *
+ * \par Coverage:
+ * This policy only works for AUTH_PWD_NORMAL type.
+ *
  * \param[in] p_policy Pointer handling p_policy structure.
  * \param[in] pattern Regular expression for password strings.
  *            If you want to remove pattern in auth-fw you must set:
@@ -251,6 +294,9 @@ int auth_passwd_set_pattern(policy_h *p_policy, const char *pattern);
  * This API is used to add forbidden password to policy_h structure.
  * It can be called multiple times.
  *
+ * \par Coverage:
+ * This policy works for all types of password_type.
+ *
  * \param[in] p_policy Pointer handling p_policy structure
  * \param[in] forbidden_passwd forbidden password user cannot set.
  *            If you want to remove forbidden passwords in auth-fw you must set:
@@ -343,12 +389,13 @@ void auth_passwd_free_policy(policy_h *p_policy);
 /*
  * This API is used to disable current password policies in auth-fw.
  *
+ * \param[in] passwd_type Password type.
  * \param[in] uid Taget user
  *
  * \return AUTH_PASSWD_API_SUCCESS if function call was successful. Error code otherwise.
  *
  */
-int auth_passwd_disable_policy(uid_t uid);
+int auth_passwd_disable_policy(password_type passwd_type, uid_t uid);
 
 #ifdef __cplusplus
 }
index 76ae18eb364cbfd75e087fd64c23ea290248ed67..931e4e4eb7a132e1d76b3cd0e5e19d33fb0663fc 100644 (file)
@@ -30,6 +30,7 @@ typedef struct _policy_h policy_h;
 
 typedef enum {
        POLICY_USER,
+       POLICY_PASSWORD_TYPE,
        POLICY_MAX_ATTEMPTS,
        POLICY_VALID_PERIOD,
        POLICY_HISTORY_SIZE,
@@ -45,7 +46,9 @@ typedef enum {
 } password_policy_type;
 
 typedef enum {
-       AUTH_PWD_NORMAL,
+       AUTH_PWD_NORMAL, // Character string. It should comply with password_quality_type.
+       AUTH_PWD_PIN, // Numeric character string. It should comply with AUTH_PWD_QUALITY_NUMERIC.
+       AUTH_PWD_PATTERN, // Numeric character string. It should comply with AUTH_PWD_QUALITY_NUMERIC.
 } password_type;
 
 typedef enum {
index 6e5f91356853d842838155e4359f45784536f9a0..0a9a021875893e8159d3d2db96d1fb428e96632a 100644 (file)
@@ -346,9 +346,10 @@ int auth_passwd_check_passwd_reused(password_type passwd_type,
  * There is retry timer on this API to limit replay attack. You will get error
  * if you called this API too often.\n
  *
- * \param[in] passwd_type Password type, such as normal(lock) password.
+ * \param[in] cur_passwd_type Current password type, such as normal(lock) password.
  * \param[in] cur_passwd Null terminated current password string or NULL
  *            pointer if there is no password set yet.
+ * \param[in] new_passwd_type New password type, such as normal(lock) password.
  * \param[in] new_passwd Null terminated new password string or NULL.
  *            If you want to remove password you must set:
  *            new_pwd = NULL.
@@ -397,7 +398,7 @@ int auth_passwd_check_passwd_reused(password_type passwd_type,
  * if(ret == AUTH_PASSWD_API_ERROR_NO_PASSWORD)
  * {
  *      printf("%s", "There is no password exists\n");
- *      ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, "this_is_new_pwd");
+ *      ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, AUTH_PWD_NORMAL, "this_is_new_pwd");
  *      if(ret != AUTH_PASSWD_API_SUCCESS)
  *      {
  *              printf("%s", "we have error\n");
@@ -407,7 +408,7 @@ int auth_passwd_check_passwd_reused(password_type passwd_type,
  * else if(ret == AUTH_PASSWD_API_SUCCESS && expire_sec > 0 && attempt < max_attempts)
  * {
  *      printf("%s", "Password is valid by now\n");
- *      ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, "this_is_current_passwd", "this_is_new_passwd");
+ *      ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, "this_is_current_passwd", AUTH_PWD_NORMAL, "this_is_new_passwd");
  *      if(ret != AUTH_PASSWD_API_SUCCESS)
  *      {
  *              printf("%s", "we have error\n");
@@ -423,8 +424,9 @@ int auth_passwd_check_passwd_reused(password_type passwd_type,
  * \endcode
  *
  */
-int auth_passwd_set_passwd(password_type passwd_type,
+int auth_passwd_set_passwd(password_type cur_passwd_type,
                                                   const char *cur_passwd,
+                                                  password_type new_passwd_type,
                                                   const char *new_passwd);
 
 #ifdef __cplusplus
index dfd6ebe358bfa2ae9e545d4b5b5e3cab4283a232..4e0cf64e2cde5b8d2f0a685dc1185c9ba367a35c 100644 (file)
@@ -41,7 +41,9 @@ struct IPasswordFile {
        virtual bool checkPassword(unsigned int passwdType,
                                                           const std::string &password) = 0;
 
-       virtual bool isPasswordActive(unsigned int passwdType) const = 0;
+       virtual bool isPasswordActive() const = 0;
+
+       virtual unsigned int getPasswordType() const = 0;
 
        virtual void setMaxHistorySize(unsigned int history) = 0;
        virtual unsigned int getMaxHistorySize() const = 0;
index 4e6d1a1e0fe3078448987c6a742af85b4425f594..900904ad45a266dfddc54662738248d255b8bd93 100644 (file)
@@ -60,7 +60,7 @@ 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;
+const unsigned int CURRENT_FILE_VERSION = 5;
 } // namespace anonymous
 
 namespace AuthPasswd {
@@ -209,7 +209,7 @@ void PasswordFile::writeMemoryToFile() const
                                   ", history_size: " << m_maxHistorySize << ", m_expireTime: " <<
                                   m_expireTime << ", m_expireTimeLeft: " << m_expireTimeLeft <<
                                   ", isActive: " << m_passwordActive << ", isRcvActive: " <<
-                                  m_passwordRcvActive);
+                                  m_passwordRcvActive << ", m_passwordType: " << m_passwordType);
        //serialize password attributes
        Serialization::Serialize(pwdBuffer, CURRENT_FILE_VERSION);
        Serialization::Serialize(pwdBuffer, m_maxAttempt);
@@ -220,6 +220,7 @@ void PasswordFile::writeMemoryToFile() const
        Serialization::Serialize(pwdBuffer, m_passwordActive);
        Serialization::Serialize(pwdBuffer, m_passwordCurrent);
        Serialization::Serialize(pwdBuffer, m_passwordHistory);
+       Serialization::Serialize(pwdBuffer, m_passwordType);
        std::string pwdFile = createDir(RW_DATA_DIR, m_user) + PASSWORD_FILE;
        pwdBuffer.Save(pwdFile);
 
@@ -249,11 +250,12 @@ void PasswordFile::loadMemoryFromFile()
        Deserialization::Deserialize(pwdBuffer, m_passwordActive);
        Deserialization::Deserialize(pwdBuffer, m_passwordCurrent);
        Deserialization::Deserialize(pwdBuffer, m_passwordHistory);
+       Deserialization::Deserialize(pwdBuffer, m_passwordType);
        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);
+                                  m_passwordRcvActive<< ", m_passwordType: " << m_passwordType);
 }
 
 bool PasswordFile::tryLoadMemoryFromOldFormatFile()
@@ -279,9 +281,20 @@ bool PasswordFile::tryLoadMemoryFromOldFormatFile()
                Deserialization::Deserialize(pwdBuffer, m_passwordActive);
                Deserialization::Deserialize(pwdBuffer, m_passwordCurrent);
                Deserialization::Deserialize(pwdBuffer, m_passwordHistory);
-
                m_expireTime = PASSWORD_INFINITE_EXPIRATION_DAYS;
                m_passwordRcvActive = false;
+               m_passwordType = 0; // Normal
+               break;
+       case 4:
+               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);
+               m_passwordType = 0; // Normal
                break;
        default:
                LogError("Invaild password version: " << fileVersion);
@@ -313,14 +326,16 @@ void PasswordFile::writeAttemptToFile() const
        AttemptFile.close();
 }
 
-bool PasswordFile::isPasswordActive(unsigned int passwdType) const
+bool PasswordFile::isPasswordActive() const
 {
-       if (passwdType != AUTH_PWD_NORMAL)
-               return false;
-
        return m_passwordActive;
 }
 
+unsigned int PasswordFile::getPasswordType() const
+{
+       return m_passwordType;
+}
+
 void PasswordFile::setMaxHistorySize(unsigned int history)
 {
        // put current password in history
@@ -387,10 +402,7 @@ bool PasswordFile::isPasswordReused(const std::string &password) const
 
 void PasswordFile::setPassword(unsigned int passwdType, const std::string &password)
 {
-       if (passwdType != AUTH_PWD_NORMAL) {
-               LogError("Password type is wrong.");
-               return;
-       }
+       m_passwordType = passwdType;
 
        //replace current password with new one
        if (password.empty()) {
@@ -411,7 +423,7 @@ void PasswordFile::setPassword(unsigned int passwdType, const std::string &passw
 
 bool PasswordFile::checkPassword(unsigned int passwdType, const std::string &password)
 {
-       if (passwdType != AUTH_PWD_NORMAL)
+       if (passwdType != m_passwordType)
                return false;
 
        return m_passwordCurrent->match(password);
index f954531459023304aa2c7b2f3c5cf62d135395df..4a5a1f8da45e7d1680d2ed2985191f24b07ed190 100644 (file)
@@ -60,7 +60,9 @@ public:
        bool checkPassword(unsigned int passwdType,
                                           const std::string &password) override;
 
-       bool isPasswordActive(unsigned int passwdType) const override;
+       bool isPasswordActive() const override;
+
+       unsigned int getPasswordType() const override;
 
        void setMaxHistorySize(unsigned int history) override;
        unsigned int getMaxHistorySize() const override;
@@ -117,6 +119,7 @@ private:
        time_t       m_expireTimeLeft;
        bool         m_passwordActive;
        bool         m_passwordRcvActive;
+       unsigned int m_passwordType;
 
        //attempt file data
        unsigned int m_attempt;
index d67e3ac5c568cf599e61d44c5dc021ad8ee64d14..529c59b5e2d73876a35f40335566c48aa0066b7e 100644 (file)
@@ -58,6 +58,12 @@ bool PasswordFile::checkPassword(unsigned int,
        return false;
 }
 
+unsigned int PasswordFile::getPasswordType() const
+{
+       std::runtime_error("TZ-Backend is not implemented.");
+       return -1;
+}
+
 void PasswordFile::setMaxHistorySize(unsigned int)
 {
        std::runtime_error("TZ-Backend is not implemented.");
@@ -118,7 +124,7 @@ void PasswordFile::setMaxAttempt(unsigned int)
        std::runtime_error("TZ-Backend is not implemented.");
 }
 
-bool PasswordFile::isPasswordActive(unsigned int) const
+bool PasswordFile::isPasswordActive() const
 {
        std::runtime_error("TZ-Backend is not implemented.");
        return false;
index 11bdc0d72851178b27446840c25427eadf134cff..48d62eba79e99b770ccfe26622f6468ffbb48c98 100644 (file)
@@ -39,6 +39,8 @@ public:
        bool checkPassword(unsigned int passwdType,
                                           const std::string &password) override;
 
+       unsigned int getPasswordType() const override;
+
        void setMaxHistorySize(unsigned int history) override;
        unsigned int getMaxHistorySize() const override;
 
@@ -54,7 +56,7 @@ public:
        int getMaxAttempt() const override;
        void setMaxAttempt(unsigned int maxAttempt) override;
 
-       bool isPasswordActive(unsigned int passwdType) const override;
+       bool isPasswordActive() const override;
        bool isPasswordReused(const std::string &password) const override;
 
        bool checkExpiration() const override;
index a63ea5de3ef33e607b7ddf22a3d387039ec1cc44..c6a22cc145b4d6ca4aa779fd46de8a9db0a97f55 100644 (file)
@@ -55,8 +55,8 @@ public:
                                        unsigned int currentUser, bool &isReused);
 
        //setting functions
-       int setPassword(unsigned int passwdType, const std::string &currentPassword,
-                                       const std::string &newPassword, unsigned int currentUser);
+       int setPassword(unsigned int curPasswdType, const std::string &currentPassword,
+                                       unsigned int newPasswdType, const std::string &newPassword, unsigned int currentUser);
 
        //resetting functions
        int resetPassword(unsigned int passwdType, const std::string &newPassword,
index a7180958f6802e62106e307113f46c2d960f0486..105d6921a80f1419f35cc93259984e5bb7699283 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <string>
 #include <map>
+#include <utility>
 
 #include <policy.h>
 
 namespace AuthPasswd {
 class PolicyManager {
 public:
-       typedef std::map<unsigned int, PolicyFile> PolicyFileMap;
+       typedef std::map<std::pair<unsigned int,unsigned int>, PolicyFile> PolicyFileMap;
 
        // policy checking functions
-       int checkPolicy(unsigned int passwdType,
-                                       const std::string &currentPassword,
+       int checkPolicy(unsigned int newPasswdType,
                                        const std::string &newPassword,
                                        unsigned int user);
 
@@ -47,13 +47,13 @@ public:
        int setPolicy(Policy policy);
 
        // policy disabling functions
-       int disablePolicy(unsigned int user);
+       int disablePolicy(unsigned int user, unsigned int passwordType);
 
 private:
        // managing functions
-       void addPolicy(unsigned int user);
-       void removePolicy(unsigned int user);
-       void existPolicy(unsigned int user);
+       void addPolicy(unsigned int user, unsigned int passwordType);
+       void removePolicy(unsigned int user, unsigned int passwordType);
+       void existPolicy(unsigned int user, unsigned int passwordType);
 
        PolicyFileMap m_policyFile;
 };
index cfb692806b49217693c6055c3dd5566f3ea7a0d6..6758d127bb5abcd64118a9a8ac5c555291379a20 100644 (file)
@@ -32,7 +32,7 @@
 namespace AuthPasswd {
 class PolicyFile {
 public:
-       PolicyFile(unsigned int user);
+       PolicyFile(unsigned int user, unsigned int passwordType);
 
        void enable();
        void disable();
@@ -70,10 +70,15 @@ private:
        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;
-
+       std::string getDir(const std::string &dir, unsigned int user) const;
+       std::string getFilePath(const std::string &dir, unsigned int user,
+                                                       unsigned int passwordType, const std::string& file) const;
+       std::string getOldFilePath(const std::string &dir, unsigned int user,
+                                                       const std::string& file) const;
        //user name
        unsigned int m_user;
+       //password type
+       unsigned int m_passwordType;
 
        bool m_enable;
 
index b42320f6d6f879d3759e70987198b4bdb65eb6c4..940cab0118bcfcb54648b097d3263aa7b7ae07bb 100644 (file)
@@ -52,6 +52,17 @@ void calculateExpiredTime(unsigned int receivedDays, time_t &validSecs)
        validSecs = (curTime + (receivedDays * 86400));
        return;
 }
+
+bool isValidPasswordType(unsigned int type)
+{
+       switch(type) {
+       case AUTH_PWD_NORMAL:
+       case AUTH_PWD_PIN:
+       case AUTH_PWD_PATTERN:
+               return true;
+       }
+       return false;
+}
 } //namespace
 
 namespace AuthPasswd {
@@ -116,44 +127,35 @@ int PasswordManager::checkPassword(unsigned int passwdType,
                return AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER;
        }
 
-       if (!itPwd->second->isPasswordActive(passwdType) && !challenge.empty()) {
+       if (!itPwd->second->isPasswordActive() && !challenge.empty()) {
                LogError("Password not active.");
                return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
        }
 
-       switch (passwdType) {
-       case AUTH_PWD_NORMAL:
-               itPwd->second->incrementAttempt();
-               itPwd->second->writeAttemptToFile();
-               currentAttempt = itPwd->second->getAttempt();
-               maxAttempt = itPwd->second->getMaxAttempt();
-               expirationTime = itPwd->second->getExpireTimeLeft();
-
-               if (itPwd->second->checkIfAttemptsExceeded()) {
-                       LogError("Too many tries.");
-                       return AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
-               }
+       itPwd->second->incrementAttempt();
+       itPwd->second->writeAttemptToFile();
+       currentAttempt = itPwd->second->getAttempt();
+       maxAttempt = itPwd->second->getMaxAttempt();
+       expirationTime = itPwd->second->getExpireTimeLeft();
 
-               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();
+       if (itPwd->second->checkIfAttemptsExceeded()) {
+               LogError("Too many tries.");
+               return AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
+       }
 
-               // Password is too old. You must change it before login.
-               if (itPwd->second->checkExpiration()) {
-                       LogError("Password expired.");
-                       return AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED;
-               }
+       if (!itPwd->second->checkPassword(passwdType, challenge)) {
+               LogError("Wrong password.");
+               return AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH;
+       }
 
-               break;
+       // Password maches and attempt number is fine - time to reset counter.
+       itPwd->second->resetAttempt();
+       itPwd->second->writeAttemptToFile();
 
-       default:
-               LogError("Not supported password type.");
-               return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+       // Password is too old. You must change it before login.
+       if (itPwd->second->checkExpiration()) {
+               LogError("Password expired.");
+               return AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED;
        }
 
        return AUTH_PASSWD_API_SUCCESS;
@@ -166,23 +168,21 @@ int PasswordManager::isPwdValid(unsigned int passwdType, unsigned int currentUse
        existPassword(currentUser);
        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
 
-       if (!itPwd->second->isPasswordActive(passwdType)) {
-               LogError("Current password not active.");
+       if (itPwd->second->getPasswordType() != passwdType) {
+               LogError("Password Type mismatch. provided=" << passwdType
+                                                                       << ", stored=" << itPwd->second->getPasswordType());
                return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
        }
 
-       switch (passwdType) {
-       case AUTH_PWD_NORMAL:
-               currentAttempt = itPwd->second->getAttempt();
-               maxAttempt = itPwd->second->getMaxAttempt();
-               expirationTime = itPwd->second->getExpireTimeLeft();
-               break;
-
-       default:
-               LogError("Not supported password type.");
-               return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+       if (!itPwd->second->isPasswordActive()) {
+               LogError("Current password not active.");
+               return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
        }
 
+       currentAttempt = itPwd->second->getAttempt();
+       maxAttempt = itPwd->second->getMaxAttempt();
+       expirationTime = itPwd->second->getExpireTimeLeft();
+
        return AUTH_PASSWD_API_SUCCESS;
 }
 
@@ -193,35 +193,38 @@ int PasswordManager::isPwdReused(unsigned int passwdType, const std::string &pas
        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
        isReused = false;
 
-       switch (passwdType) {
-       case AUTH_PWD_NORMAL:
-
-               // check history, however only if history is active and password is not empty
-               if (itPwd->second->isHistoryActive() && !passwd.empty())
-                       isReused = itPwd->second->isPasswordReused(passwd);
-
-               break;
-
-       default:
-               LogError("Not supported password type.");
-               return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+       if (itPwd->second->getPasswordType() != passwdType) {
+               LogError("Password Type mismatch. provided=" << passwdType
+                                                                       << ", stored=" << itPwd->second->getPasswordType());
+               return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
        }
 
+       // check history, however only if history is active and password is not empty
+       if (itPwd->second->isHistoryActive() && !passwd.empty())
+               isReused = itPwd->second->isPasswordReused(passwd);
+
        return AUTH_PASSWD_API_SUCCESS;
 }
 
-int PasswordManager::setPassword(unsigned int passwdType,
+int PasswordManager::setPassword(unsigned int curPasswdType,
                                                                 const std::string &currentPassword,
+                                                                unsigned int newPasswdType,
                                                                 const std::string &newPassword,
                                                                 unsigned int currentUser)
 {
-       LogSecureDebug("curUser = " << currentUser << ", pwdType = " << passwdType <<
-                                  ", curPwd = " << currentPassword << ", newPwd = " << newPassword);
+       LogSecureDebug("curUser = " << currentUser
+                                       << ", curPwdType = " << curPasswdType <<  ", curPwd = " << "****"
+                                       << ", newPasswdType = " << newPasswdType << ", newPwd = " << "****");
        unsigned int receivedDays = PASSWORD_INFINITE_EXPIRATION_DAYS;
        time_t valid_secs = 0;
        existPassword(currentUser);
        PasswordFileMap::iterator itPwd = m_pwdFile.find(currentUser);
 
+       if (!isValidPasswordType(newPasswdType)) {
+               LogError("Not supported new password type: " << newPasswdType);
+               return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+       }
+
        if (itPwd->second->isIgnorePeriod()) {
                LogError("Retry timeout occured.");
                return AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER;
@@ -229,53 +232,45 @@ int PasswordManager::setPassword(unsigned int passwdType,
 
        // 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()) {
                LogError("Password not active.");
                return AUTH_PASSWD_API_ERROR_NO_PASSWORD;
        }
 
-       switch (passwdType) {
-       case AUTH_PWD_NORMAL:
-               //increment attempt count before checking it against max attempt count
-               itPwd->second->incrementAttempt();
-               itPwd->second->writeAttemptToFile();
+       //increment attempt count before checking it against max attempt count
+       itPwd->second->incrementAttempt();
+       itPwd->second->writeAttemptToFile();
 
-               if (itPwd->second->checkIfAttemptsExceeded()) {
-                       LogError("Too many tries.");
-                       return AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
-               }
+       if (itPwd->second->checkIfAttemptsExceeded()) {
+               LogError("Too many tries.");
+               return AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
+       }
 
-               if (!itPwd->second->checkPassword(AUTH_PWD_NORMAL, currentPassword)) {
-                       LogError("Wrong password.");
-                       return AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH;
-               }
+       if (!itPwd->second->checkPassword(curPasswdType, 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();
+       //here we are sure that user knows current password - we can reset attempt counter
+       itPwd->second->resetAttempt();
+       itPwd->second->writeAttemptToFile();
 
-               // check history, however only if history is active and new password is not empty
-               if (itPwd->second->isHistoryActive() && !newPassword.empty()) {
-                       if (itPwd->second->isPasswordReused(newPassword)) {
-                               LogError("Password reused.");
-                               return AUTH_PASSWD_API_ERROR_PASSWORD_REUSED;
-                       }
+       // check history, however only if history is active and new password is not empty
+       if (itPwd->second->isHistoryActive() && !newPassword.empty()) {
+               if (itPwd->second->isPasswordReused(newPassword)) {
+                       LogError("Password reused.");
+                       return AUTH_PASSWD_API_ERROR_PASSWORD_REUSED;
                }
+       }
 
-               if (!newPassword.empty())
-                       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();
-               break;
+       if (!newPassword.empty())
+               receivedDays = itPwd->second->getExpireTime();
 
-       default:
-               LogError("Not supported password type.");
-               return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
-       }
+       calculateExpiredTime(receivedDays, valid_secs);
+       //setting password
+       itPwd->second->setPassword(newPasswdType, newPassword);
+       itPwd->second->setExpireTimeLeft(valid_secs);
+       itPwd->second->writeMemoryToFile();
 
        return AUTH_PASSWD_API_SUCCESS;
 }
@@ -289,24 +284,21 @@ int PasswordManager::resetPassword(unsigned int passwdType,
        existPassword(receivedUser);
        PasswordFileMap::iterator itPwd = m_pwdFile.find(receivedUser);
 
-       switch (passwdType) {
-       case AUTH_PWD_NORMAL:
-               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->setExpireTimeLeft(valid_secs);
-               itPwd->second->writeMemoryToFile();
-               break;
-
-       default:
-               LogError("Not supported password type.");
+       if (!isValidPasswordType(passwdType)) {
+               LogError("Not supported password type: " << passwdType);
                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(passwdType, newPassword);
+       itPwd->second->setExpireTimeLeft(valid_secs);
+       itPwd->second->writeMemoryToFile();
+
        return AUTH_PASSWD_API_SUCCESS;
 }
 
@@ -333,7 +325,7 @@ void PasswordManager::setPasswordValidity(unsigned int receivedUser,
        PasswordFileMap::iterator itPwd = m_pwdFile.find(receivedUser);
        calculateExpiredTime(receivedDays, valid_secs);
 
-       if (itPwd->second->isPasswordActive(AUTH_PWD_NORMAL))
+       if (itPwd->second->isPasswordActive())
                itPwd->second->setExpireTimeLeft(valid_secs);
 
        itPwd->second->setExpireTime(receivedDays);
index 413b3bc79014f00ce8ac33d13a441c69017f7b4f..95470d1523607df382e156c6be2ddf47125aa35b 100644 (file)
@@ -29,6 +29,7 @@
 #include <algorithm>
 #include <cassert>
 #include <climits>
+#include <regex>
 
 #include <dpl/log/log.h>
 
 #include <auth-passwd-error.h>
 
 namespace AuthPasswd {
-void PolicyManager::addPolicy(unsigned int user)
+void PolicyManager::addPolicy(unsigned int user, unsigned int passwordType)
 {
-       m_policyFile.insert(PolicyFileMap::value_type(user, PolicyFile(user)));
+       m_policyFile.insert(PolicyFileMap::value_type(std::make_pair(user, passwordType), PolicyFile(user, passwordType)));
 }
 
-void PolicyManager::removePolicy(unsigned int user)
+void PolicyManager::removePolicy(unsigned int user, unsigned int passwordType)
 {
-       m_policyFile.erase(user);
+       m_policyFile.erase(std::make_pair(user, passwordType));
 }
 
-void PolicyManager::existPolicy(unsigned int user)
+void PolicyManager::existPolicy(unsigned int user, unsigned int passwordType)
 {
-       PolicyFileMap::iterator itPwd = m_policyFile.find(user);
+       PolicyFileMap::iterator itPwd = m_policyFile.find(std::make_pair(user, passwordType));
 
        if (itPwd != m_policyFile.end())
                return;
 
-       addPolicy(user);
+       addPolicy(user, passwordType);
        return;
 }
 
-int PolicyManager::checkPolicy(unsigned int passwdType,
-                                                          const std::string &currentPassword,
-                                                          const std::string &newPassword,
-                                                          unsigned int user)
+int __checkCommonPolicy(const PolicyFile& policy,
+                                       const std::string &newPassword)
 {
-       LogSecureDebug("Inside checkPolicy function.");
+       if (!policy.isPolicyActive())
+               return AUTH_PASSWD_API_SUCCESS;
 
-       // 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.empty())
+               return AUTH_PASSWD_API_SUCCESS;
+
+       if (!policy.checkMinLength(newPassword)) {
+               LogError("new passwd's minLength is invalid");
+               return AUTH_PASSWD_API_ERROR_INVALID_MIN_LENGTH;
        }
 
-       if (newPassword.size() > MAX_PASSWORD_LEN) {
-               LogError("New password length failed.");
-               return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+       if (!policy.checkForbiddenPasswds(newPassword)) {
+               LogError("new passwd is forbiddenPasswd");
+               return AUTH_PASSWD_API_ERROR_INVALID_FORBIDDEN_PASSWORDS;
        }
 
-       existPolicy(user);
-       PolicyFileMap::iterator itPolicy = m_policyFile.find(user);
+       return AUTH_PASSWD_API_SUCCESS;
+}
 
-       if (!itPolicy->second.isPolicyActive() || (passwdType != AUTH_PWD_NORMAL))
+int __checkNormalPasswordPolicy(const PolicyFile& policy,
+                                       const std::string &newPassword)
+{
+       if (!policy.isPolicyActive())
                return AUTH_PASSWD_API_SUCCESS;
 
-       if (itPolicy->second.getQualityType() == AUTH_PWD_QUALITY_UNSPECIFIED && newPassword.empty())
+       if (policy.getQualityType() == AUTH_PWD_QUALITY_UNSPECIFIED && newPassword.empty())
                return AUTH_PASSWD_API_SUCCESS;
 
-       if (!itPolicy->second.checkMinLength(newPassword)) {
-               LogError("new passwd's minLength is invalid");
-               return AUTH_PASSWD_API_ERROR_INVALID_MIN_LENGTH;
-       }
-
-       if (!itPolicy->second.checkMinComplexCharNumber(newPassword)) {
+       if (!policy.checkMinComplexCharNumber(newPassword)) {
                LogError("new passwd's minComplexCharNumber is invalid");
                return AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM;
        }
 
-       if (!itPolicy->second.checkMaxCharOccurrences(newPassword)) {
+       if (!policy.checkMaxCharOccurrences(newPassword)) {
                LogError("new passwd's maxCharOccurrences is invalid");
                return AUTH_PASSWD_API_ERROR_INVALID_MAX_CHAR_OCCURENCES;
        }
 
-       if (!itPolicy->second.checkMaxNumSeqLength(newPassword)) {
+       if (!policy.checkMaxNumSeqLength(newPassword)) {
                LogError("new passwd's maxNumSeqLength is invalid");
                return AUTH_PASSWD_API_ERROR_INVALID_MAX_NUM_SEQ_LENGTH;
        }
 
-       if (!itPolicy->second.checkForbiddenPasswds(newPassword)) {
-               LogError("new passwd is forbiddenPasswd");
-               return AUTH_PASSWD_API_ERROR_INVALID_FORBIDDEN_PASSWORDS;
-       }
-
-       if (!itPolicy->second.checkQualityType(newPassword)) {
+       if (!policy.checkQualityType(newPassword)) {
                LogError("new passwd's qualityType is invalid");
                return AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE;
        }
 
-       if (!itPolicy->second.checkPattern(newPassword)) {
+       if (!policy.checkPattern(newPassword)) {
                LogError("new passwd's pattern is invalid");
                return AUTH_PASSWD_API_ERROR_INVALID_PATTERN;
        }
@@ -122,11 +117,64 @@ int PolicyManager::checkPolicy(unsigned int passwdType,
        return AUTH_PASSWD_API_SUCCESS;
 }
 
+int __checkPinPolicy(__attribute__((unused)) const PolicyFile& policy,
+                                       const std::string &newPassword)
+{
+       if (!std::regex_match(newPassword, std::regex(REGEX_PIN)))
+               return AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE;
+       return AUTH_PASSWD_API_SUCCESS;
+}
+
+int __checkPatternPolicy(__attribute__((unused)) const PolicyFile& policy,
+                                       const std::string &newPassword)
+{
+       if (!std::regex_match(newPassword, std::regex(REGEX_PATTERN)))
+               return AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE;
+       return AUTH_PASSWD_API_SUCCESS;
+}
+
+int PolicyManager::checkPolicy(unsigned int newPasswordType,
+                                                          const std::string &newPassword,
+                                                          unsigned int user)
+{
+       int ret = AUTH_PASSWD_API_SUCCESS;
+       LogSecureDebug("Inside checkPolicy function.");
+
+       // check if passwords are correct
+       if (newPassword.size() > MAX_PASSWORD_LEN) {
+               LogError("New password length failed.");
+               return AUTH_PASSWD_API_ERROR_INPUT_PARAM;
+       }
+
+       existPolicy(user, newPasswordType);
+       PolicyFileMap::iterator itPolicy = m_policyFile.find(std::make_pair(user, newPasswordType));
+
+       // common check
+       ret = __checkCommonPolicy(itPolicy->second, newPassword);
+       if (ret != AUTH_PASSWD_API_SUCCESS)
+               return ret;
+
+       // password type specific check
+       switch(newPasswordType) {
+       case AUTH_PWD_NORMAL:
+               ret = __checkNormalPasswordPolicy(itPolicy->second, newPassword);
+               break;
+       case AUTH_PWD_PIN:
+               ret = __checkPinPolicy(itPolicy->second, newPassword);
+               break;
+       case AUTH_PWD_PATTERN:
+               ret = __checkPatternPolicy(itPolicy->second, newPassword);
+               break;
+       }
+
+       return ret;
+}
+
 int PolicyManager::setPolicy(Policy policy)
 {
-       LogSecureDebug("Inside setPolicy function.");
-       existPolicy(policy.uid);
-       PolicyFileMap::iterator itPolicy = m_policyFile.find(policy.uid);
+       LogSecureDebug("Inside setPolicy function: uid=" << policy.uid << ", passwordType=" << policy.passwordType);
+       existPolicy(policy.uid, policy.passwordType);
+       PolicyFileMap::iterator itPolicy = m_policyFile.find(std::make_pair(policy.uid, policy.passwordType));
 
        // check if policies are correct
        assert(POLICY_TYPE_FIRST == POLICY_MAX_ATTEMPTS);
@@ -271,11 +319,11 @@ int PolicyManager::setPolicy(Policy policy)
        return AUTH_PASSWD_API_SUCCESS;
 }
 
-int PolicyManager::disablePolicy(unsigned int user)
+int PolicyManager::disablePolicy(unsigned int user, unsigned int passwordType)
 {
        LogSecureDebug("Inside disablePolicy function.");
-       existPolicy(user);
-       PolicyFileMap::iterator itPolicy = m_policyFile.find(user);
+       existPolicy(user, passwordType);
+       PolicyFileMap::iterator itPolicy = m_policyFile.find(std::make_pair(user, passwordType));
        itPolicy->second.disable();
        itPolicy->second.writeMemoryToFile();
        return AUTH_PASSWD_API_SUCCESS;
index 339136b8528900e1008c811f693effc3fe298d96..8016763ac6a5ecbb99f0f5082c14976d526304a0 100644 (file)
@@ -146,14 +146,12 @@ int PasswordService::processCheckFunctions(PasswordHdrs hdr, MessageBuffer &buff
                Deserialization::Deserialize(buffer, passwdType);
                Deserialization::Deserialize(buffer, challenge);
                result = m_pwdManager.isPwdReused(passwdType, challenge, cur_user, isPwdReused);
-
                if (result == AUTH_PASSWD_API_SUCCESS) {
                        if(!isPwdReused)
-                               result = m_policyManager.checkPolicy(passwdType, NO_PASSWORD, challenge, cur_user);
+                               result = m_policyManager.checkPolicy(passwdType, challenge, cur_user);
                        else
                                result = AUTH_PASSWD_API_ERROR_PASSWORD_REUSED;
                }
-
                break;
        }
 
@@ -173,14 +171,15 @@ int PasswordService::processSetFunctions(PasswordHdrs hdr, MessageBuffer &buffer
        switch (hdr) {
        case PasswordHdrs::HDR_SET_PASSWD: {
                std::string curPasswd, newPasswd;
-               unsigned int passwdType = 0;
-               Deserialization::Deserialize(buffer, passwdType);
+               unsigned int curPasswdType, newPasswdPype = 0;
+               Deserialization::Deserialize(buffer, curPasswdType);
                Deserialization::Deserialize(buffer, curPasswd);
+               Deserialization::Deserialize(buffer, newPasswdPype);
                Deserialization::Deserialize(buffer, newPasswd);
-               result = m_policyManager.checkPolicy(passwdType, curPasswd, newPasswd, cur_user);
+               result = m_policyManager.checkPolicy(newPasswdPype, newPasswd, cur_user);
 
                if (result == AUTH_PASSWD_API_SUCCESS)
-                       result = m_pwdManager.setPassword(passwdType, curPasswd, newPasswd, cur_user);
+                       result = m_pwdManager.setPassword(curPasswdType, curPasswd, newPasswdPype, newPasswd, cur_user);
 
                break;
        }
@@ -231,19 +230,7 @@ int PasswordService::processPolicyFunctions(PasswordHdrs hdr, MessageBuffer &buf
 
        switch (hdr) {
        case PasswordHdrs::HDR_SET_PASSWD_POLICY: {
-               Policy policy;
-               Deserialization::Deserialize(buffer, policy.flag);
-               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);
+               PolicySerializable policy(buffer);
                result = m_policyManager.setPolicy(policy);
 
                if (result == AUTH_PASSWD_API_SUCCESS) {
@@ -262,8 +249,10 @@ int PasswordService::processPolicyFunctions(PasswordHdrs hdr, MessageBuffer &buf
 
        case PasswordHdrs::HDR_DIS_PASSWD_POLICY: {
                uid_t rec_user = 0;
+               unsigned int rec_passwordType = 0;
+               Deserialization::Deserialize(buffer, rec_passwordType);
                Deserialization::Deserialize(buffer, rec_user);
-               result = m_policyManager.disablePolicy(rec_user);
+               result = m_policyManager.disablePolicy(rec_user, rec_passwordType);
 
                if (result == AUTH_PASSWD_API_SUCCESS) {
                        m_pwdManager.setPasswordMaxAttempts(rec_user, PASSWORD_INFINITE_ATTEMPT_COUNT);
@@ -285,7 +274,6 @@ int PasswordService::processPolicyFunctions(PasswordHdrs hdr, MessageBuffer &buf
 bool PasswordService::processOne(const ConnectionID &conn, MessageBuffer &buffer,
                                                                 InterfaceID interfaceID)
 {
-       LogSecureDebug("Iteration begin");
        MessageBuffer sendBuffer;
        int retCode = AUTH_PASSWD_API_ERROR_SERVER_ERROR;
        unsigned int cur_user = 0, cur_att = 0, max_att = 0, exp_time = 0;
@@ -300,6 +288,8 @@ bool PasswordService::processOne(const ConnectionID &conn, MessageBuffer &buffer
                PasswordHdrs hdr = static_cast<PasswordHdrs>(tempHdr);
                auto& cynaraChecker = CynaraChecker::instance();
 
+               LogSecureDebug("Iteration begin: interfaceID=" << interfaceID << ", Task=" << static_cast<int>(hdr));
+
                try {   //try..catch for internal service errors, assigns error code for returning.
                        switch (interfaceID) {
                        case SOCKET_ID_CHECK:
@@ -351,6 +341,8 @@ bool PasswordService::processOne(const ConnectionID &conn, MessageBuffer &buffer
 
                //everything is OK, send return code and extra data
                Serialization::Serialize(sendBuffer, retCode);
+               LogSecureDebug("...wrote return code: interfaceID=" << interfaceID << ", Task=" << static_cast<int>(hdr)
+                                       << ", retCode=" << retCode);
 
                //Returning additional information should occur only when checking functions
                //are called, and under certain return values
index 176d0ca4daee8da251f16a7e57177b0d14d8d39f..f596f3ca358c4dedcead9dc1c3ffd342ca831599 100644 (file)
@@ -44,9 +44,9 @@
 #include <generic-backend/password-file-buffer.h>
 
 namespace {
-const std::string POLICY_FILE = "/policy";
+const std::string POLICY_FILE = "policy";
 const mode_t FILE_MODE = S_IRUSR | S_IWUSR;
-const unsigned int CURRENT_FILE_VERSION = 1;
+const unsigned int CURRENT_FILE_VERSION = 2;
 } // namespace anonymous
 
 namespace AuthPasswd {
@@ -61,11 +61,12 @@ const std::string REGEX_COMPLEX_GROUP2 = REGEX_COMPLEX_GROUP1;
 const std::string REGEX_COMPLEX_GROUP3 = "(?=.*[A-Za-z]+.*)(?=.*[0-9]+.*)(?=.*[^A-Za-z0-9]+.*)";
 const std::string REGEX_COMPLEX_GROUP4 = "(?=.*[A-Z]+.*)(?=.*[a-z]+.*)(?=.*[0-9]+.*)(?=.*[^A-Za-z0-9]+.*)";
 
-PolicyFile::PolicyFile(unsigned int user): m_user(user), m_enable(false)
+PolicyFile::PolicyFile(unsigned int user, unsigned int passwordType)
+                                       : m_user(user), m_passwordType(passwordType), m_enable(false)
 {
        // check if data directory exists
        // if not create it
-       std::string userDir = createDir(RW_DATA_DIR, m_user);
+       std::string userDir = getDir(RW_DATA_DIR, m_user);
 
        if (!dirExists(RW_DATA_DIR)) {
                if (mkdir(RW_DATA_DIR, 0700)) {
@@ -92,7 +93,7 @@ void PolicyFile::resetState()
 
 void PolicyFile::preparePolicyFile()
 {
-       std::string policyFile = createDir(RW_DATA_DIR, m_user) + POLICY_FILE;
+       std::string policyFile = getFilePath(RW_DATA_DIR, m_user, m_passwordType, POLICY_FILE);
 
        // check if policy file exists
        if (!fileExists(policyFile)) {
@@ -124,12 +125,27 @@ bool PolicyFile::dirExists(const std::string &dirpath) const
        return ((stat(dirpath.c_str(), &buf) == 0) && (((buf.st_mode) & S_IFMT) == S_IFDIR));
 }
 
-std::string PolicyFile::createDir(const std::string &dir, unsigned int user) const
+std::string PolicyFile::getDir(const std::string &dir, unsigned int user) const
 {
        std::string User = std::to_string(user);
        return dir + "/" + User;
 }
 
+std::string PolicyFile::getFilePath(const std::string &dir, unsigned int user,
+                                       unsigned int passwordType, const std::string& file) const
+{
+       std::string PasswordType = std::to_string(passwordType);
+       std::string Dir = getDir(dir, user);
+       return Dir + "/" + file + "_" + PasswordType;
+}
+
+std::string PolicyFile::getOldFilePath(const std::string &dir, unsigned int user,
+                                       const std::string& file) const
+{
+       std::string Dir = getDir(dir, user);
+       return Dir + "/" + file;
+}
+
 void PolicyFile::writeMemoryToFile() const
 {
        PasswordFileBuffer policyBuffer;
@@ -139,7 +155,7 @@ void PolicyFile::writeMemoryToFile() const
        Serialization::Serialize(policyBuffer, m_enable);
        PolicySerializable policys(m_policy);
        policys.Serialize(policyBuffer);
-       std::string policyFile = createDir(RW_DATA_DIR, m_user) + POLICY_FILE;
+       std::string policyFile = getFilePath(RW_DATA_DIR, m_user, m_passwordType, POLICY_FILE);
        policyBuffer.Save(policyFile);
 
        if (chmod(policyFile.c_str(), FILE_MODE)) {
@@ -151,19 +167,41 @@ void PolicyFile::writeMemoryToFile() const
 void PolicyFile::loadMemoryFromFile()
 {
        PasswordFileBuffer policyBuffer;
-       std::string policyFile = createDir(RW_DATA_DIR, m_user) + POLICY_FILE;
+       bool loadedFromOld = false;
+       std::string policyFile = getFilePath(RW_DATA_DIR, m_user, m_passwordType, POLICY_FILE);
+       if (!fileExists(policyFile)) {
+               LogWarning("No file file to load :  policy file=" << policyFile << ", trying to load from old file.");
+               policyFile = getOldFilePath(RW_DATA_DIR, m_user, POLICY_FILE);
+               if (!fileExists(policyFile)) {
+                       LogError("No file file to load : old policy file= " << policyFile);
+                       Throw(PasswordException::FStreamOpenError);
+               }
+               loadedFromOld = true;
+       }
+
        policyBuffer.Load(policyFile);
        // deserialize policy attributes
        unsigned int fileVersion = 0;
        Deserialization::Deserialize(policyBuffer, fileVersion);
 
-       if (fileVersion != CURRENT_FILE_VERSION)
+       if (fileVersion > CURRENT_FILE_VERSION) {
+               LogError("Invalid policy file version: policy file= " << policyFile << ", version="  << fileVersion);
                Throw(PasswordException::FStreamReadError);
+       }
 
        Deserialization::Deserialize(policyBuffer, m_enable);
-       PolicySerializable policys(policyBuffer);
+       PolicySerializable policys(policyBuffer, fileVersion);
        m_policy = *(static_cast<Policy *>(&policys));
        LogSecureDebug("User: " << m_user << "Policy: " << m_policy.info());
+
+       if (loadedFromOld) {
+               writeMemoryToFile();
+               if (remove(policyFile.c_str())) {
+                       LogError("Failed to remove file" << policyFile <<
+                                                " Error: " << errnoToString());
+                               Throw(PasswordException::RemoveError);
+               }
+       }
 }
 
 void PolicyFile::enable()
index 11249d071073bdd37bb02a6bc8d45b1da0f2b236..c73805e7bfe9aafa7a31f308ea12d6f9276fe1f9 100644 (file)
@@ -20,6 +20,8 @@ SET(TEST_SRCS main.cpp
                          test-util.cpp
                          test-client.cpp
                          test-admin.cpp
+                         test-pin.cpp
+                         test-pattern.cpp
                          test-sw-backend.cpp
 
                          ${SERVER_PATH}/service/plugin-loader.cpp
index 0157e98afc9543c29c5c714a624762aa7ce5400e..cf61dc0c0017e7920d5783461a71136366f98c64 100644 (file)
@@ -55,6 +55,9 @@ TESTCASE(T00201_set_policy_params)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        ret = auth_passwd_set_max_attempts(policy, 10);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
@@ -89,11 +92,263 @@ TESTCASE(T00201_set_policy_params)
 
 TESTCASE(T00202_disable_policy)
 {
-       int ret = auth_passwd_disable_policy(test::get_test_uid(false));
+       int ret = auth_passwd_disable_policy(AUTH_PWD_NORMAL, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T00203_max_attempts)
+{
+       const char *right_pass = "right-password";
+       const char *wrong_pass = "wrong-password";
+
+       const char *right_pin = "1479";
+       const char *wrong_pin = "9999";
+
+       const char *right_pattern = "9807332";
+       const char *wrong_pattern = "1986786";
+
+       test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
+       policy_h *policy = sp.get();
+       TEST_EXPECT(true, policy != nullptr);
+
+       int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       // Max Attempts is stored in password file.
+       ret = auth_passwd_set_max_attempts(policy, 2);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // ===============================
+       // for normal password type
+       ret = auth_passwd_reset_passwd(AUTH_PWD_NORMAL, test::get_test_uid(false), right_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // with wrong password
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, wrong_pass, AUTH_PWD_NORMAL, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+       sleep(1);
+
+       ret = test::check_passwd(AUTH_PWD_NORMAL, wrong_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+       sleep(1);
+
+       // with valid passwod
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, right_pass, AUTH_PWD_NORMAL, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED, ret);
+       sleep(1);
+
+       ret = test::check_passwd(AUTH_PWD_NORMAL, right_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED, ret);
+       sleep(1);
+
+       // ===============================
+       // for PIN password type
+       ret = auth_passwd_reset_passwd(AUTH_PWD_PIN, test::get_test_uid(false), right_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // with wrong password
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, wrong_pin, AUTH_PWD_PIN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+       sleep(1);
+
+       ret = test::check_passwd(AUTH_PWD_PIN, wrong_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+       sleep(1);
+
+       // with valid passwod
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, right_pin, AUTH_PWD_PIN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED, ret);
+       sleep(1);
+
+       ret = test::check_passwd(AUTH_PWD_PIN, right_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED, ret);
+       sleep(1);
+
+       // ===============================
+       // for Pattern password type
+       ret = auth_passwd_reset_passwd(AUTH_PWD_PATTERN, test::get_test_uid(false), right_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // with wrong password
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, wrong_pattern, AUTH_PWD_PATTERN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+       sleep(1);
+
+       ret = test::check_passwd(AUTH_PWD_PATTERN, wrong_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+       sleep(1);
+
+       // with valid passwod
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, right_pattern, AUTH_PWD_PATTERN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED, ret);
+       sleep(1);
+
+       ret = test::check_passwd(AUTH_PWD_PATTERN, right_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED, ret);
+       sleep(1);
+}
+
+TESTCASE(T00204_min_length)
+{
+       const char *right_pass = "right-password";
+       const char *wrong_pass = "wro";
+
+       const char *right_pin = "1479";
+       const char *wrong_pin = "999";
+
+       const char *right_pattern = "9807332";
+       const char *wrong_pattern = "198";
+
+       test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
+       policy_h *policy = sp.get();
+       TEST_EXPECT(true, policy != nullptr);
+
+       int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_min_length(policy, 4);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       // ===============================
+       // for normal password type
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       ret = auth_passwd_reset_passwd(AUTH_PWD_NORMAL, test::get_test_uid(false), right_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // with wrong password
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, right_pass, AUTH_PWD_NORMAL, wrong_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_LENGTH, ret);
+       sleep(1);
+
+       // ===============================
+       // for PIN password type
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PIN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       ret = auth_passwd_reset_passwd(AUTH_PWD_PIN, test::get_test_uid(false), right_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // with wrong password
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, right_pin, AUTH_PWD_PIN, wrong_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_LENGTH, ret);
+       sleep(1);
+
+       // ===============================
+       // for Pattern password type
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PATTERN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       ret = auth_passwd_reset_passwd(AUTH_PWD_PATTERN, test::get_test_uid(false), right_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // with wrong password
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, right_pattern, AUTH_PWD_PATTERN, wrong_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_LENGTH, ret);
+       sleep(1);
+}
+
+
+TESTCASE(T00205_forbidden_password)
+{
+       const char *forbidden_pass = "9999";
+
+       const char *right_pass = "right-password";
+       const char *right_pin = "1479";
+       const char *right_pattern = "9807332";
+
+       test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
+       policy_h *policy = sp.get();
+       TEST_EXPECT(true, policy != nullptr);
+
+       int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_forbidden_passwd(policy, forbidden_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       // ===============================
+       // for normal password type
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       ret = auth_passwd_reset_passwd(AUTH_PWD_NORMAL, test::get_test_uid(false), right_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // with wrong password
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, right_pass, AUTH_PWD_NORMAL, forbidden_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_FORBIDDEN_PASSWORDS, ret);
+       sleep(1);
+
+       // ===============================
+       // for PIN password type
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PIN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       ret = auth_passwd_reset_passwd(AUTH_PWD_PIN, test::get_test_uid(false), right_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // with wrong password
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, right_pin, AUTH_PWD_PIN, forbidden_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_FORBIDDEN_PASSWORDS, ret);
+       sleep(1);
+
+       // ===============================
+       // for Pattern password type
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PATTERN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       ret = auth_passwd_reset_passwd(AUTH_PWD_PATTERN, test::get_test_uid(false), right_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+       sleep(1);
+
+       // with wrong password
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, right_pattern, AUTH_PWD_PATTERN, forbidden_pass);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_FORBIDDEN_PASSWORDS, ret);
+       sleep(1);
 }
 
-TESTCASE(T00203_password_qaulity)
+TESTCASE(T00206_password_qaulity)
 {
        test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
        policy_h *policy = sp.get();
@@ -102,6 +357,9 @@ TESTCASE(T00203_password_qaulity)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        // ===============================
        ret = auth_passwd_set_quality(policy, AUTH_PWD_QUALITY_SOMETHING);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
@@ -114,11 +372,11 @@ TESTCASE(T00203_password_qaulity)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, NULL);
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, NULL);
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "11112222");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "11112222");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        // ===============================
@@ -133,11 +391,11 @@ TESTCASE(T00203_password_qaulity)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "!%^&*()@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "!%^&*()@");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "atizen12@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "atizen12@");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
@@ -145,7 +403,7 @@ TESTCASE(T00203_password_qaulity)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "aaaaaaa");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "aaaaaaa");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
@@ -153,7 +411,7 @@ TESTCASE(T00203_password_qaulity)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "@aaaaaaa");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "@aaaaaaa");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        // ===============================
@@ -168,11 +426,11 @@ TESTCASE(T00203_password_qaulity)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "1234");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "1234");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "btizen12@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "btizen12@");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        // ===============================
@@ -187,23 +445,23 @@ TESTCASE(T00203_password_qaulity)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "1234");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "1234");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "1234@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "1234@");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen@");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "ctizen12@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "ctizen12@");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
@@ -211,7 +469,7 @@ TESTCASE(T00203_password_qaulity)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "12dtizen@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "12dtizen@");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
@@ -219,7 +477,7 @@ TESTCASE(T00203_password_qaulity)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "@12dtizen");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "@12dtizen");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
@@ -227,12 +485,12 @@ TESTCASE(T00203_password_qaulity)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "12@tizen");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "12@tizen");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
 
-TESTCASE(T00204_min_complex_char)
+TESTCASE(T00207_min_complex_char)
 {
        test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
        policy_h *policy = sp.get();
@@ -241,6 +499,9 @@ TESTCASE(T00204_min_complex_char)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        ret = auth_passwd_set_history_size(policy, 0);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
@@ -262,7 +523,7 @@ TESTCASE(T00204_min_complex_char)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
@@ -270,7 +531,7 @@ TESTCASE(T00204_min_complex_char)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen@");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
@@ -278,7 +539,7 @@ TESTCASE(T00204_min_complex_char)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen1");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen1");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        // AUTH_PWD_COMPLEX_CHAR_GROUP_2
@@ -293,19 +554,19 @@ TESTCASE(T00204_min_complex_char)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "1234");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "1234");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen@");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen1");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen1");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        // AUTH_PWD_COMPLEX_CHAR_GROUP_3
@@ -320,18 +581,18 @@ TESTCASE(T00204_min_complex_char)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen1");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen1");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen@");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen1@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen1@");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        // AUTH_PWD_COMPLEX_CHAR_GROUP_4
@@ -346,31 +607,31 @@ TESTCASE(T00204_min_complex_char)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen1");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen1");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen@");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "tizen1@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "tizen1@");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "Tizen@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "Tizen@");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "AAAA@1234");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "AAAA@1234");
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MIN_COMPLEX_CHAR_NUM, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "Tizen1@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "Tizen1@");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        // AUTH_PWD_COMPLEX_CHAR_UNSPECIFIED
@@ -385,7 +646,7 @@ TESTCASE(T00204_min_complex_char)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "1234");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "1234");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
@@ -393,7 +654,7 @@ TESTCASE(T00204_min_complex_char)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "aaaaa");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "aaaaa");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
@@ -401,11 +662,11 @@ TESTCASE(T00204_min_complex_char)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, "aaaaa1234@");
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, "aaaaa1234@");
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
-TESTCASE(T00205_pattern)
+TESTCASE(T00208_pattern)
 {
        const char* pattern = "[0-9]+";
        const char* allowed_pass = "Tizen123";
@@ -418,6 +679,9 @@ TESTCASE(T00205_pattern)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        ret = auth_passwd_set_history_size(policy, 0);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
@@ -436,11 +700,11 @@ TESTCASE(T00205_pattern)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, not_allowed_pass);
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, not_allowed_pass);
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_PATTERN, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, allowed_pass);
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, allowed_pass);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        // restore original setting
@@ -451,7 +715,7 @@ TESTCASE(T00205_pattern)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
-TESTCASE(T00206_max_num_seq)
+TESTCASE(T00209_max_num_seq)
 {
        int max_num_seq = 2;
        const char* allowed_pass = "124589";
@@ -465,6 +729,9 @@ TESTCASE(T00206_max_num_seq)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        ret = auth_passwd_set_max_num_seq_len(policy, max_num_seq);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
@@ -475,22 +742,22 @@ TESTCASE(T00206_max_num_seq)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, not_allowed_pass1);
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, not_allowed_pass1);
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MAX_NUM_SEQ_LENGTH, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, not_allowed_pass2);
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, not_allowed_pass2);
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_MAX_NUM_SEQ_LENGTH, ret);
        sleep(1);
 
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, allowed_pass);
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, allowed_pass);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
-       ret = auth_passwd_disable_policy(test::get_test_uid(false));
+       ret = auth_passwd_disable_policy(AUTH_PWD_NORMAL, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
-TESTCASE(T00207_reset_passwd_privilege)
+TESTCASE(T00210_reset_passwd_privilege)
 {
        auto reset_passwd_function = [] () -> int {
                return auth_passwd_reset_passwd(AUTH_PWD_NORMAL, test::get_test_uid(false), default_pass);
@@ -509,13 +776,16 @@ TESTCASE(T00207_reset_passwd_privilege)
                AUTH_PASSWD_API_SUCCESS, reset_passwd_function));
 }
 
-TESTCASE(T00208_set_policy_privilege)
+TESTCASE(T00211_set_policy_privilege)
 {
        auto set_policy_function = [] () -> int {
                test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
                policy_h *policy = sp.get();
 
                int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+               if (ret != AUTH_PASSWD_API_SUCCESS)
+                       return ret;
+               ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
                if (ret != AUTH_PASSWD_API_SUCCESS)
                        return ret;
                ret = auth_passwd_set_max_attempts(policy, 10);
index ec4bcd876f3e47ab8a982793827b6b35d739be2c..be461a086fb73668ed9a03d43f899395a6969273 100644 (file)
 #include <auth-passwd.h>
 #include <auth-passwd-admin.h> /* for init/deinit */
 
-#include <ctime>
-#include <chrono>
-#include <thread>
 #include <unistd.h>
 
 namespace {
 
 const char *default_pass = "test-password";
 
-struct Policy {
-       unsigned int current_attempts;
-       unsigned int max_attempts;
-       unsigned int valid_secs;
-
-       Policy() :
-               current_attempts(0),
-               max_attempts(0),
-               valid_secs(0) {}
-};
-
-inline void sleep_for_retry_timeout(void)
-{
-       std::chrono::milliseconds dur(500);
-       std::this_thread::sleep_for(dur);
-}
-
-int check_passwd(password_type type, const char *token)
-{
-       sleep_for_retry_timeout();
-
-       Policy policy;
-
-       int ret = auth_passwd_check_passwd(
-                       type,
-                       token,
-                       &policy.current_attempts,
-                       &policy.max_attempts,
-                       &policy.valid_secs);
-
-       return ret;
-}
-
-int check_passwd_state(password_type type)
-{
-       Policy policy;
-
-       return auth_passwd_check_passwd_state(type,
-                                                                                 &policy.current_attempts,
-                                                                                 &policy.max_attempts,
-                                                                                 &policy.valid_secs);
-}
-
-int check_passwd_reusable(password_type type, const char *token)
-{
-       int is_reused = -1;
-       return auth_passwd_check_passwd_reused(type, token, &is_reused);
-}
-
-int set_relative_date(int days)
-{
-       timespec ts = {};
-       clock_gettime(CLOCK_REALTIME, &ts);
-       ts.tv_sec += days * 86400;
-       return (clock_settime(CLOCK_REALTIME, &ts));
-}
 } // anonymous namespace
 
 TESTCASE(T0010_init)
@@ -101,26 +42,26 @@ TESTCASE(T0010_init)
 
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
-       auth_passwd_disable_policy(test::get_test_uid(false));
+       auth_passwd_disable_policy(AUTH_PWD_NORMAL, test::get_test_uid(false));
 }
 
 TESTCASE(T00111_check)
 {
-       int ret = check_passwd(AUTH_PWD_NORMAL, default_pass);
+       int ret = test::check_passwd(AUTH_PWD_NORMAL, default_pass);
 
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
 TESTCASE(T00112_check_state)
 {
-       int ret = check_passwd_state(AUTH_PWD_NORMAL);
+       int ret = test::check_passwd_state(AUTH_PWD_NORMAL);
 
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
 TESTCASE(T00113_check_reusable)
 {
-       int ret = check_passwd_reusable(AUTH_PWD_NORMAL, "hoipoi");
+       int ret = test::check_passwd_reusable(AUTH_PWD_NORMAL, "hoipoi");
 
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
@@ -129,18 +70,18 @@ TESTCASE(T00114_set)
 {
        const char *new_pass = "new_pass_temp";
 
-       sleep_for_retry_timeout();
-       int ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, new_pass);
+       test::sleep_for_retry_timeout();
+       int ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, new_pass);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* remove passwd */
-       sleep_for_retry_timeout();
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, new_pass, NULL);
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, new_pass, AUTH_PWD_NORMAL, NULL);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* rollback passwd to default pass */
-       sleep_for_retry_timeout();
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, default_pass);
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, AUTH_PWD_NORMAL, default_pass);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
@@ -157,13 +98,16 @@ TESTCASE(T00115_check_passwd_available)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        ret = auth_passwd_set_quality(policy, AUTH_PWD_QUALITY_ALPHABETIC);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        ret = auth_passwd_set_policy(policy);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
-       sleep_for_retry_timeout();
+       test::sleep_for_retry_timeout();
 
        ret = auth_passwd_check_passwd_available(AUTH_PWD_NORMAL, not_usable_pass);
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
@@ -189,20 +133,23 @@ TESTCASE(T00116_remove_password_with_empty_policy)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        ret = auth_passwd_set_policy(policy);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* test : remove passwd with empty policy */
-       sleep_for_retry_timeout();
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, NULL);
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, NULL);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* restore */
-       ret = auth_passwd_disable_policy(test::get_test_uid(false));
+       ret = auth_passwd_disable_policy(AUTH_PWD_NORMAL, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
-       sleep_for_retry_timeout();
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, default_pass);
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, AUTH_PWD_NORMAL, default_pass);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
@@ -216,6 +163,9 @@ TESTCASE(T00117_remove_password_with_min_length_policy)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        ret = auth_passwd_set_min_length(policy, 4);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
@@ -223,16 +173,16 @@ TESTCASE(T00117_remove_password_with_min_length_policy)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* test : remove passwd with min-length policy */
-       sleep_for_retry_timeout();
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, NULL);
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, NULL);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* restore */
-       ret = auth_passwd_disable_policy(test::get_test_uid(false));
+       ret = auth_passwd_disable_policy(AUTH_PWD_NORMAL, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
-       sleep_for_retry_timeout();
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, default_pass);
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, AUTH_PWD_NORMAL, default_pass);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
@@ -246,6 +196,9 @@ TESTCASE(T00118_remove_password_with_min_complex_char_policy)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        ret = auth_passwd_set_min_complex_char_num(policy, AUTH_PWD_COMPLEX_CHAR_GROUP_1);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
@@ -253,16 +206,16 @@ TESTCASE(T00118_remove_password_with_min_complex_char_policy)
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* test : remove passwd with min-complex-char policy */
-       sleep_for_retry_timeout();
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, NULL);
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, NULL);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* restore */
-       ret = auth_passwd_disable_policy(test::get_test_uid(false));
+       ret = auth_passwd_disable_policy(AUTH_PWD_NORMAL, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
-       sleep_for_retry_timeout();
-       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, default_pass);
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, NULL, AUTH_PWD_NORMAL, default_pass);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
@@ -276,33 +229,36 @@ TESTCASE(T00119_check_expire_policy)
        int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
        ret = auth_passwd_set_validity(policy, 1);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        ret = auth_passwd_set_policy(policy);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
-       ret = check_passwd(AUTH_PWD_NORMAL, default_pass);
+       ret = test::check_passwd(AUTH_PWD_NORMAL, default_pass);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
-       ret = check_passwd_state(AUTH_PWD_NORMAL);
+       ret = test::check_passwd_state(AUTH_PWD_NORMAL);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* test : set date as +2 days */
-       ret = set_relative_date(2);
+       ret = test::set_relative_date(2);
        TEST_EXPECT(true, ret == 0);
 
-       ret = check_passwd(AUTH_PWD_NORMAL, default_pass);
+       ret = test::check_passwd(AUTH_PWD_NORMAL, default_pass);
        TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED, ret);
 
-       ret = check_passwd_state(AUTH_PWD_NORMAL);
+       ret = test::check_passwd_state(AUTH_PWD_NORMAL);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        /* restore */
-       ret = set_relative_date(-2);
+       ret = test::set_relative_date(-2);
        TEST_EXPECT(true, ret == 0);
 
-       ret = auth_passwd_disable_policy(test::get_test_uid(false));
+       ret = auth_passwd_disable_policy(AUTH_PWD_NORMAL, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 }
 
@@ -310,7 +266,7 @@ TESTCASE(T00119_check_expire_policy)
 TESTCASE(T00120_check_passwd_privilege)
 {
        auto check_passwd_function = [] () -> int {
-               return check_passwd(AUTH_PWD_NORMAL, default_pass);
+               return test::check_passwd(AUTH_PWD_NORMAL, default_pass);
        };
 
        int ret = auth_passwd_reset_passwd(AUTH_PWD_NORMAL, test::get_test_uid(false), default_pass);
@@ -318,9 +274,9 @@ TESTCASE(T00120_check_passwd_privilege)
        ret = auth_passwd_reset_passwd(AUTH_PWD_NORMAL, test::get_test_uid(true), default_pass);
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
-       ret = auth_passwd_disable_policy(test::get_test_uid(false));
+       ret = auth_passwd_disable_policy(AUTH_PWD_NORMAL, test::get_test_uid(false));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
-       ret = auth_passwd_disable_policy(test::get_test_uid(true));
+       ret = auth_passwd_disable_policy(AUTH_PWD_NORMAL, test::get_test_uid(true));
        TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
 
        TEST_EXPECT(true, test::run_in_process(SM_PROCESS_TYPE_APP, "org.tizen.settings.main",
@@ -339,8 +295,8 @@ TESTCASE(T00120_check_passwd_privilege)
 TESTCASE(T00121_set_passwd_privilege)
 {
        auto set_passwd_function = [] () -> int {
-               sleep_for_retry_timeout();
-               return auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, NULL);
+               test::sleep_for_retry_timeout();
+               return auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pass, AUTH_PWD_NORMAL, NULL);
        };
 
        int ret = auth_passwd_reset_passwd(AUTH_PWD_NORMAL, test::get_test_uid(true), default_pass);
diff --git a/tests/test-pattern.cpp b/tests/test-pattern.cpp
new file mode 100644 (file)
index 0000000..3b6dba8
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ *  Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        test-pattern.cpp
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+
+#include <klay/testbench.h>
+
+#include "test-util.h"
+
+#include <auth-passwd.h>
+#include <auth-passwd-admin.h>
+
+#include <unistd.h>
+
+namespace {
+
+const char *default_pattern = "0123456789";
+
+} // anonymous namespace
+
+TESTCASE(T00400_init)
+{
+       int ret = auth_passwd_reset_passwd(
+                       AUTH_PWD_PATTERN,
+                       test::get_test_uid(false),
+                       default_pattern);
+
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+
+TESTCASE(T00411_pattern_check)
+{
+       int ret = test::check_passwd(AUTH_PWD_PATTERN, default_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T004112_pattern_check_state)
+{
+       int ret = test::check_passwd_state(AUTH_PWD_PATTERN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T004113_pattern_check_reusable)
+{
+       int ret = test::check_passwd_reusable(AUTH_PWD_PATTERN, "123400");
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T004114_pattern_set)
+{
+       const char *new_pattern = "0987654321";
+
+       test::sleep_for_retry_timeout();
+       int ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, default_pattern, AUTH_PWD_PATTERN, new_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* remove pin */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, new_pattern, AUTH_PWD_PATTERN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* rollback passwd to default pin */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, NULL, AUTH_PWD_PATTERN, default_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T004115_pattern_passwd_available)
+{
+       int ret = AUTH_PASSWD_API_SUCCESS;
+       test::sleep_for_retry_timeout();
+
+       ret = auth_passwd_check_passwd_available(AUTH_PWD_PATTERN, "8888");
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_check_passwd_available(AUTH_PWD_PATTERN, "");
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_check_passwd_available(AUTH_PWD_PATTERN, "abcd");
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
+
+       ret = auth_passwd_check_passwd_available(AUTH_PWD_PATTERN, "123d");
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
+}
+
+TESTCASE(T004116_pattern_remove_password_with_empty_policy)
+{
+       /* precondition : set empty policy */
+       test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
+       policy_h *policy = sp.get();
+       TEST_EXPECT(true, policy != nullptr);
+
+       int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PATTERN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* test : remove passwd with empty policy */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, default_pattern, AUTH_PWD_PATTERN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* restore */
+       ret = auth_passwd_disable_policy(AUTH_PWD_PATTERN, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, NULL, AUTH_PWD_PATTERN, default_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T004117_pattern_remove_password_with_min_length_policy)
+{
+       /* precondition : set min-length policy */
+       test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
+       policy_h *policy = sp.get();
+       TEST_EXPECT(true, policy != nullptr);
+
+       int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PATTERN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_min_length(policy, 4);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* test : remove passwd with min-length policy */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, default_pattern, AUTH_PWD_PATTERN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* restore */
+       ret = auth_passwd_disable_policy(AUTH_PWD_PATTERN, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, NULL, AUTH_PWD_PATTERN, default_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T004118_pattern_check_expire_policy)
+{
+       /* precondition : set validity(expire time) policy */
+       test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
+       policy_h *policy = sp.get();
+       TEST_EXPECT(true, policy != nullptr);
+
+       int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PATTERN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_validity(policy, 1);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = test::check_passwd(AUTH_PWD_PATTERN, default_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = test::check_passwd_state(AUTH_PWD_PATTERN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* test : set date as +2 days */
+       ret = test::set_relative_date(2);
+       TEST_EXPECT(true, ret == 0);
+
+       ret = test::check_passwd(AUTH_PWD_PATTERN, default_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED, ret);
+
+       ret = test::check_passwd_state(AUTH_PWD_PATTERN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* restore */
+       ret = test::set_relative_date(-2);
+       TEST_EXPECT(true, ret == 0);
+
+       ret = auth_passwd_disable_policy(AUTH_PWD_PATTERN, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T004120_pattern_set_from_to_password)
+{
+       const char *new_password = "dgdbgdfdef";
+
+       test::sleep_for_retry_timeout();
+       int ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, default_pattern, AUTH_PWD_NORMAL, new_password);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* rollback passwd to default pin */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, new_password, AUTH_PWD_PATTERN, default_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T004121_pattern_set_from_to_pin)
+{
+       const char *new_pin = "4444";
+
+       test::sleep_for_retry_timeout();
+       int ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, default_pattern, AUTH_PWD_PIN, new_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* rollback passwd to default pin */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, new_pin, AUTH_PWD_PATTERN, default_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
diff --git a/tests/test-pin.cpp b/tests/test-pin.cpp
new file mode 100644 (file)
index 0000000..24f41f4
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ *  Copyright (c) 2025 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        test-pin.cpp
+ * @author      Dongsun Lee (ds73.lee@samsung.com)
+ * @version     1.0
+ * @brief
+ */
+
+#include <klay/testbench.h>
+
+#include "test-util.h"
+
+#include <auth-passwd.h>
+#include <auth-passwd-admin.h>
+
+#include <unistd.h>
+
+namespace {
+
+const char *default_pin = "9999";
+
+} // anonymous namespace
+
+TESTCASE(T00300_pin_init)
+{
+       int ret = auth_passwd_reset_passwd( AUTH_PWD_PIN, test::get_test_uid(false), default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_disable_policy(AUTH_PWD_PIN, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T00311_pin_check)
+{
+       int ret = AUTH_PASSWD_API_SUCCESS;
+
+       ret = test::check_passwd(AUTH_PWD_PIN, default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = test::check_passwd(AUTH_PWD_PIN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+
+       ret = test::check_passwd(AUTH_PWD_PIN, "1111");
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+
+       ret = test::check_passwd(AUTH_PWD_NORMAL, default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+
+       ret = test::check_passwd(AUTH_PWD_PIN, "");
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INPUT_PARAM, ret);
+
+       ret = test::check_passwd(AUTH_PWD_PIN, "123456789012345678901234567890123");
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INPUT_PARAM, ret);
+}
+
+TESTCASE(T003112_pin_check_state)
+{
+       int ret = AUTH_PASSWD_API_SUCCESS;
+
+       ret = test::check_passwd_state(AUTH_PWD_PIN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = test::check_passwd_state(AUTH_PWD_NORMAL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_NO_PASSWORD, ret);
+}
+
+TESTCASE(T003113_pin_check_reusable)
+{
+       int ret = AUTH_PASSWD_API_SUCCESS;
+
+       ret = test::check_passwd_reusable(AUTH_PWD_PIN, "1234");
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = test::check_passwd_reusable(AUTH_PWD_NORMAL, "1234");
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_NO_PASSWORD, ret);
+}
+
+TESTCASE(T003114_pin_set)
+{
+       int ret = AUTH_PASSWD_API_SUCCESS;
+       const char *new_pin = "1234";
+
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, default_pin, AUTH_PWD_PIN, new_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* remove pin */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, new_pin, AUTH_PWD_PIN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* rollback passwd to default pin */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, NULL, AUTH_PWD_PIN, default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* Error cases*/
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, new_pin, AUTH_PWD_PIN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_RETRY_TIMER, ret);
+
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, default_pin, AUTH_PWD_PIN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, "4444", AUTH_PWD_PIN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_MISMATCH, ret);
+
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, new_pin, AUTH_PWD_PIN, "123a");
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
+}
+
+TESTCASE(T003115_pin_passwd_available)
+{
+       int ret = AUTH_PASSWD_API_SUCCESS;
+       test::sleep_for_retry_timeout();
+
+       ret = auth_passwd_check_passwd_available(AUTH_PWD_PIN, "8888");
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_check_passwd_available(AUTH_PWD_PIN, "");
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_check_passwd_available(AUTH_PWD_PIN, "abcd");
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
+
+       ret = auth_passwd_check_passwd_available(AUTH_PWD_PIN, "123d");
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_INVALID_QUALITY_TYPE, ret);
+}
+
+TESTCASE(T003116_pin_remove_password_with_empty_policy)
+{
+       /* precondition : set empty policy */
+       test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
+       policy_h *policy = sp.get();
+       TEST_EXPECT(true, policy != nullptr);
+
+       int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PIN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* test : remove passwd with empty policy */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, default_pin, AUTH_PWD_PIN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* restore */
+       ret = auth_passwd_disable_policy(AUTH_PWD_PIN, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, NULL, AUTH_PWD_PIN, default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T003117_pin_remove_password_with_min_length_policy)
+{
+       /* precondition : set min-length policy */
+       test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
+       policy_h *policy = sp.get();
+       TEST_EXPECT(true, policy != nullptr);
+
+       int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PIN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_min_length(policy, 4);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* test : remove passwd with min-length policy */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, default_pin, AUTH_PWD_PIN, NULL);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* restore */
+       ret = auth_passwd_disable_policy(AUTH_PWD_PIN, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PIN, NULL, AUTH_PWD_PIN, default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T003118_pin_check_expire_policy)
+{
+       /* precondition : set validity(expire time) policy */
+       test::ScopedPolicy sp(test::create_policy_h(), auth_passwd_free_policy);
+       policy_h *policy = sp.get();
+       TEST_EXPECT(true, policy != nullptr);
+
+       int ret = auth_passwd_set_user(policy, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_password_type(policy, AUTH_PWD_PIN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_validity(policy, 1);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = auth_passwd_set_policy(policy);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = test::check_passwd(AUTH_PWD_PIN, default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       ret = test::check_passwd_state(AUTH_PWD_PIN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* test : set date as +2 days */
+       ret = test::set_relative_date(2);
+       TEST_EXPECT(true, ret == 0);
+
+       ret = test::check_passwd(AUTH_PWD_PIN, default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_ERROR_PASSWORD_EXPIRED, ret);
+
+       ret = test::check_passwd_state(AUTH_PWD_PIN);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* restore */
+       ret = test::set_relative_date(-2);
+       TEST_EXPECT(true, ret == 0);
+
+       ret = auth_passwd_disable_policy(AUTH_PWD_PIN, test::get_test_uid(false));
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T003120_pin_set_from_to_password)
+{
+       const char *new_password = "dgdbgdfdef";
+
+       test::sleep_for_retry_timeout();
+       int ret = auth_passwd_set_passwd(AUTH_PWD_PIN, default_pin, AUTH_PWD_NORMAL, new_password);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* rollback passwd to default pin */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_NORMAL, new_password, AUTH_PWD_PIN, default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
+
+TESTCASE(T003121_pin_set_from_to_pattern)
+{
+       const char *new_pattern = "53654753434";
+
+       test::sleep_for_retry_timeout();
+       int ret = auth_passwd_set_passwd(AUTH_PWD_PIN, default_pin, AUTH_PWD_PATTERN, new_pattern);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+
+       /* rollback passwd to default pin */
+       test::sleep_for_retry_timeout();
+       ret = auth_passwd_set_passwd(AUTH_PWD_PATTERN, new_pattern, AUTH_PWD_PIN, default_pin);
+       TEST_EXPECT(AUTH_PASSWD_API_SUCCESS, ret);
+}
index 605bbc55b17809250d781e2fe78f89da061eff37..158473b4cccd1f8c49179082fa226fa144f94345 100644 (file)
@@ -29,7 +29,7 @@
 
 using namespace AuthPasswd;
 
-TESTCASE(T00300_is_support)
+TESTCASE(T00500_is_support)
 {
        PluginManager pm;
 
@@ -37,7 +37,7 @@ TESTCASE(T00300_is_support)
        TEST_EXPECT(false, pm.isSupport(BackendType::TZ));
 }
 
-TESTCASE(T00301_bind_backend)
+TESTCASE(T00501_bind_backend)
 {
        PluginManager pm;
        pm.setBackend(BackendType::SW);
index bf4e485f6a27487a04a058f1d0cbe8b23a6ec14c..0aaf190e8073f895873553abbc9e8edb1bcbb411 100644 (file)
  * @brief
  */
 
+#include <ctime>
+#include <chrono>
+#include <thread>
+
 #include <tzplatform_config.h>
+#include <auth-passwd.h>
 
 #include "test-util.h"
 
@@ -46,4 +51,62 @@ uid_t get_test_uid(bool app)
                return 0;
 }
 
+struct Policy {
+       unsigned int current_attempts;
+       unsigned int max_attempts;
+       unsigned int valid_secs;
+
+       Policy() :
+               current_attempts(0),
+               max_attempts(0),
+               valid_secs(0) {}
+};
+
+void sleep_for_retry_timeout(void)
+{
+       std::chrono::milliseconds dur(500);
+       std::this_thread::sleep_for(dur);
+}
+
+int check_passwd(password_type type, const char *token)
+{
+       sleep_for_retry_timeout();
+
+       Policy policy;
+
+       int ret = auth_passwd_check_passwd(
+                       type,
+                       token,
+                       &policy.current_attempts,
+                       &policy.max_attempts,
+                       &policy.valid_secs);
+
+       return ret;
+}
+
+
+int check_passwd_state(password_type type)
+{
+       Policy policy;
+
+       return auth_passwd_check_passwd_state(type,
+                       &policy.current_attempts,
+                       &policy.max_attempts,
+                       &policy.valid_secs);
+}
+
+int check_passwd_reusable(password_type type, const char *token)
+{
+       int is_reused = -1;
+       return auth_passwd_check_passwd_reused(type, token, &is_reused);
+}
+
+int set_relative_date(int days)
+{
+       timespec ts = {};
+       clock_gettime(CLOCK_REALTIME, &ts);
+       ts.tv_sec += days * 86400;
+       return (clock_settime(CLOCK_REALTIME, &ts));
+}
+
 } // namespace test
index ef6fe1704883f59c3255d035e450e984e4ffe700..daf545c71476e7bd8169f418282cd9d0337a68ed 100644 (file)
@@ -36,6 +36,11 @@ namespace test {
 
 policy_h *create_policy_h();
 uid_t get_test_uid(bool app);
+void sleep_for_retry_timeout(void);
+int check_passwd(password_type type, const char *token);
+int check_passwd_state(password_type type);
+int check_passwd_reusable(password_type type, const char *token);
+int set_relative_date(int days);
 
 using ScopedPolicy = std::unique_ptr<policy_h, decltype(&auth_passwd_free_policy)>;