Add dpm auth policy 54/143454/5 accepted/tizen/4.0/unified/20170920.081814 accepted/tizen/unified/20170921.072449 submit/tizen/20170920.045814 submit/tizen/20170921.042645 submit/tizen_4.0/20170920.045210
authorJaemin Ryu <jm77.ryu@samsung.com>
Thu, 10 Aug 2017 04:20:15 +0000 (13:20 +0900)
committerJaemin Ryu <jm77.ryu@samsung.com>
Thu, 14 Sep 2017 00:42:25 +0000 (09:42 +0900)
Change-Id: Ia47beef8bc77ec200b0b8c2698c34cc42001ef71
Signed-off-by: Jaemin Ryu <jm77.ryu@samsung.com>
CMakeLists.txt [new file with mode: 0755]
api/CMakeLists.txt [new file with mode: 0755]
api/auth.h [new file with mode: 0644]
api/dpm-auth.pc.in [new file with mode: 0644]
api/password.cpp [new file with mode: 0644]
dpm-auth.manifest [new file with mode: 0644]
packaging/dpm-auth.spec [new file with mode: 0755]
plugin/CMakeLists.txt [new file with mode: 0755]
plugin/password-manager.cpp [new file with mode: 0644]
plugin/password-manager.h [new file with mode: 0644]
plugin/password.cpp [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..b738b49
--- /dev/null
@@ -0,0 +1,85 @@
+#
+# Copyright (c) 2017 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.
+#
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+PROJECT(dpm-auth)
+
+IF(NOT DEFINED VERSION)
+       SET(VERSION "0.0.1")
+ENDIF(NOT DEFINED VERSION)
+
+INCLUDE(FindPkgConfig)
+
+IF(NOT CMAKE_BUILD_TYPE)
+       SET(CMAKE_BUILD_TYPE "DEBUG")
+ENDIF(NOT CMAKE_BUILD_TYPE)
+
+SET(DPM_API     ${PROJECT_SOURCE_DIR}/api)
+SET(DPM_PLUGIN  ${PROJECT_SOURCE_DIR}/plugin)
+
+IF("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.7)
+       SET(CXX_STD "c++0x")
+else()
+       SET(CXX_STD "c++11")
+endif()
+
+SET(COMPILE_BASE_FLAGS         "-g -fPIC -Werror -Wall -Wl,--as-needed -Wl,--no-whole-archive")
+SET(CMAKE_C_FLAGS_PROFILING    "${COMPILE_BASE_FLAGS} -O0 -pg")
+SET(CMAKE_CXX_FLAGS_PROFILING  "${COMPILE_BASE_FLAGS} -O0 -pg -std=${CXX_STD} -fno-rtti")
+SET(CMAKE_C_FLAGS_DEBUG                "${COMPILE_BASE_FLAGS} -O0 -ggdb")
+SET(CMAKE_CXX_FLAGS_DEBUG      "${COMPILE_BASE_FLAGS} -O0 -ggdb -std=${CXX_STD} -fno-rtti")
+SET(CMAKE_C_FLAGS_RELEASE      "${COMPILE_BASE_FLAGS} -O2 -DNDEBUG")
+SET(CMAKE_CXX_FLAGS_RELEASE    "${COMPILE_BASE_FLAGS} -O2 -DNDEBUG -std=${CXX_STD} -fno-rtti")
+SET(CMAKE_C_FLAGS_CCOV         "${COMPILE_BASE_FLAGS} -O0 --coverage")
+SET(CMAKE_CXX_FLAGS_CCOV       "${COMPILE_BASE_FLAGS} -O0 --coverage -std=${CXX_STD} -fno-rtti")
+
+IF(NOT DEFINED LIB_INSTALL_DIR)
+       SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}")
+ENDIF(NOT DEFINED LIB_INSTALL_DIR)
+
+IF(NOT DEFINED INCLUDE_INSTALL_DIR)
+       SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}")
+ENDIF(NOT DEFINED INCLUDE_INSTALL_DIR)
+
+IF(NOT DEFINED CONF_INSTALL_DIR)
+       SET(CONF_INSTALL_DIR "${SYSCONF_INSTALL_DIR}/dpm")
+ENDIF(NOT DEFINED CONF_INSTALL_DIR)
+
+IF(NOT DEFINED DATA_INSTALL_DIR)
+       SET(DATA_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/dpm")
+ENDIF(NOT DEFINED DATA_INSTALL_DIR)
+
+IF(NOT DEFINED DB_INSTALL_DIR)
+       SET(DB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/dbspace")
+ENDIF(NOT DEFINED DB_INSTALL_DIR)
+
+IF(NOT DEFINED RUN_INSTALL_DIR)
+       SET(RUN_INSTALL_DIR "/var/run")
+ENDIF(NOT DEFINED RUN_INSTALL_DIR)
+
+IF(NOT DEFINED PAMD_INSTALL_DIR)
+       SET(PAMD_INSTALL_DIR "${SYSCONF_INSTALL_DIR}/pam.d")
+ENDIF(NOT DEFINED PAMD_INSTALL_DIR)
+
+IF(NOT DEFINED SYSTEMD_UNIT_INSTALL_DIR)
+       SET(SYSTEMD_UNIT_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib/systemd/system")
+ENDIF(NOT DEFINED SYSTEMD_UNIT_INSTALL_DIR)
+
+ADD_DEFINITIONS(-DUG_WAYLAND)
+
+ADD_SUBDIRECTORY(${DPM_PLUGIN})
+ADD_SUBDIRECTORY(${DPM_API})
diff --git a/api/CMakeLists.txt b/api/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..62c5112
--- /dev/null
@@ -0,0 +1,48 @@
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+SET(TARGET ${PROJECT_NAME})
+SET(PC_FILE "${TARGET}.pc")
+
+SET(LIB_VERSION "${VERSION}")
+SET(LIB_SOVERSION "0")
+
+SET(API_SOURCES "password.cpp")
+SET(API_HEADERS "auth.h")
+
+SET(DEPENDENCY      klay
+                                       dpm-pil
+                    capi-base-common
+                    capi-system-info
+)
+
+PKG_CHECK_MODULES(API_DEPS REQUIRED ${DEPENDENCY})
+
+SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
+
+ADD_LIBRARY(${TARGET} SHARED ${API_SOURCES})
+
+SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS "-fvisibility=default")
+SET_TARGET_PROPERTIES(${TARGET} PROPERTIES SOVERSION ${LIB_SOVERSION})
+SET_TARGET_PROPERTIES(${TARGET} PROPERTIES VERSION   ${LIB_VERSION})
+
+INCLUDE_DIRECTORIES(SYSTEM ${API_DEPS_INCLUDE_DIRS})
+TARGET_LINK_LIBRARIES(${TARGET} ${API_DEPS_LIBRARIES} pthread)
+
+CONFIGURE_FILE(${PC_FILE}.in ${CMAKE_BINARY_DIR}/${PC_FILE} @ONLY)
+
+INSTALL(FILES ${CMAKE_BINARY_DIR}/${PC_FILE} DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+INSTALL(TARGETS ${TARGET} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries)
+INSTALL(FILES ${API_HEADERS} DESTINATION ${INCLUDE_INSTALL_DIR}/dpm)
diff --git a/api/auth.h b/api/auth.h
new file mode 100644 (file)
index 0000000..c060858
--- /dev/null
@@ -0,0 +1,732 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#ifndef __CAPI_PASSWORD_POLICY_H__
+#define __CAPI_PASSWORD_POLICY_H__
+
+typedef void * device_policy_manager_h;
+
+/**
+ * @file password.h
+ * @brief This file provides APIs to control password functionality
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup  CAPI_DPM_PASSWORD_POLICY_MODULE
+ * @{
+ */
+
+/**
+ * @brief       Enumeration for dpm password quality type
+ * @since_tizen 3.0
+ */
+typedef enum {
+       DPM_PASSWORD_QUALITY_UNSPECIFIED     = 0x00,    /**< No requirements for password. */
+       DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD = 0x01,    /**< EAS(Exchange ActiveSync) requirement for simple password */
+       DPM_PASSWORD_QUALITY_SOMETHING       = 0x10,    /**< Some kind password is required, but doesn't care what it is */
+       DPM_PASSWORD_QUALITY_NUMERIC         = 0x20,    /**< Containing at least numeric characters */
+       DPM_PASSWORD_QUALITY_ALPHABETIC      = 0x40,    /**< Containing at least alphabetic (or other symbol) characters */
+       DPM_PASSWORD_QUALITY_ALPHANUMERIC    = 0x80,    /**< Containing at least numeric and alphabetic characters */
+} dpm_password_quality_e;
+
+/**
+ * @brief       Enumeration for dpm password status type
+ * @since_tizen 3.0
+ */
+typedef enum {
+       DPM_PASSWORD_STATUS_NORMAL,                     /**< Password normal status */
+       DPM_PASSWORD_STATUS_CHANGED,                    /**< Password successfully changed */
+       DPM_PASSWORD_STATUS_NOT_CHANGED,                /**< Password not changed */
+       DPM_PASSWORD_STATUS_CHANGE_REQUIRED ,           /**< Password change required */
+       DPM_PASSWORD_STATUS_MAX_ATTEMPTS_EXCEEDED,      /**< Password Max Attempts Exceeded*/
+
+       DPM_PASSWORD_STATUS_EXPIRED,                    /**< Password expired */
+       DPM_PASSWORD_STATUS_RECOVERY_PASSWORD_FAILED,   /**< Device unlock failed by Password Recovery */
+       DPM_PASSWORD_STATUS_RECOVERY_PASSWORD_SUCCEEDED,/**< Device unlock succeeded by Password Recovery */
+
+       DPM_PASSWORD_STATUS_QUALITY_CHANGED,            /**< Password quality successfully changed */
+       DPM_PASSWORD_STATUS_MIN_LENGTH_CHANGED,         /**< Password min_length successfully changed */
+       DPM_PASSWORD_STATUS_COMPLEX_CHAR_CHANGED,       /**< Password complex_char successfully changed */
+       DPM_PASSWORD_STATUS_PATTERN_CHANGED             /**< Password pattern successfully changed */
+} dpm_password_status_e;
+
+/**
+ * @partner
+ * @brief       Sets password quality.
+ * @details     An administrator can set the password restrictions it is imposing.
+ *              After setting this, the user will not be able to
+ *              enter a new password that is not at least as restrictive as what has been set.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   quality Password quality type, values of #dpm_password_quality_e combined with bitwise 'or'
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_quality(device_policy_manager_h handle, int quality);
+
+/**
+ * @partner
+ * @brief       Gets password quality.
+ * @details     An administrator can get the password restrictions it is imposing.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[out]   quality Password quality type, values of #dpm_password_quality_e combined with bitwise 'or'
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_quality(device_policy_manager_h handle, int *quality);
+
+/**
+ * @partner
+ * @brief       Sets password minimum length.
+ * @details     Sets the minimum allowed password length. After setting this,
+ *              the user will not be able to enter a new password that is
+ *              shorter than the setting length.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   value Allowed minimum password length
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_minimum_length(device_policy_manager_h handle, int value);
+
+/**
+ * @partner
+ * @brief       Gets password minimum length.
+ * @details     Gets the minimum allowed password length.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[out]   value Allowed minimum password length
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_minimum_length(device_policy_manager_h handle, int *value);
+
+/**
+ * @partner
+ * @brief       Sets minimum complex char in password.
+ * @details     Complex characters are all non-alphabetic characters;
+ *              that is, numbers and symbols. Admin can configure this
+ *              setting and make the password more secure.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   value Number of minimum complex char in password.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_min_complex_chars(device_policy_manager_h handle, int value);
+
+/**
+ * @partner
+ * @brief       Gets minimum complex char in password.
+ * @details     Complex characters are all non-alphabetic characters;
+ *              that is, numbers and symbols.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[out]   value Number of minimum complex char in password.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_min_complex_chars(device_policy_manager_h handle, int *value);
+
+/**
+ * @partner
+ * @brief       Sets maximum number of failed attempts before device is wiped.
+ * @details     If user fails the last attempt, device will be wiped.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   value Maximum count for failed passwords.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_maximum_failed_attempts_for_wipe(device_policy_manager_h handle, int value);
+
+/**
+ * @partner
+ * @brief       Gets maximum number of failed attempts before device is wiped.
+ * @details     If user fails the last attempt, device will be wiped.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[out]   value Maximum count for failed passwords.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_maximum_failed_attempts_for_wipe(device_policy_manager_h handle, int *value);
+
+/**
+ * @partner
+ * @brief       Sets the number of days password expires.
+ * @details     An administrator can configure the password age to force
+ *              the user to enter a new password after every expiration period.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   value Number of days after which the password expires.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_expires(device_policy_manager_h handle, int value);
+
+/**
+ * @partner
+ * @brief       Gets the number of days password expires.
+ * @details     An administrator can get the password age to force
+ *              the user to enter a new password after every expiration period.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[out]   value Number of days after which the password expires.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_expires(device_policy_manager_h handle, int *value);
+
+/**
+ * @partner
+ * @brief       Sets the number of min password history to avoid previous password.
+ * @details     An administrator can configure the number of previous
+ *              passwords which cannot be used when entering a new password.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   value Number of previous passwords which cannot be used when
+ *              settings a new password.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_history(device_policy_manager_h handle, int value);
+
+/**
+ * @partner
+ * @brief       Gets the number of min password history to avoid previous password.
+ * @details     An administrator can get the number of previous
+ *              passwords which cannot be used when entering a new password.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[out]   value Number of previous passwords which cannot be used when
+ *              settings a new password.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_history(device_policy_manager_h handle, int *value);
+
+/**
+ * @partner
+ * @brief       Sets the required password pattern.
+ * @details     An administrator can force User to enter password based on
+ *              a regular expression.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   pattern Password pattern. If regular expression is
+ *              [a-zA-Z]{4}[0-9]{4}, we can force user to enter a 8 character
+ *              password with first 4 alphabetic characters and next 4
+ *              numeric characters. An administrator must take care when
+ *              setting this pattern.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_pattern(device_policy_manager_h handle, const char *pattern);
+
+/**
+ * @partner
+ * @brief       Resets password.
+ * @details     This takes effect immediately to the device password.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   password New password
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_reset(device_policy_manager_h handle, const char *password);
+
+/**
+ * @partner
+ * @brief       Enforces password change.
+ * @details     An administrator can enforce password change. PasswordPolicy
+ *              change setting is launched.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_enforce_change(device_policy_manager_h handle);
+
+/**
+ * @partner
+ * @brief       Sets the maximum number of seconds of inactivity time
+ *              before the screen timeout occurs.
+ * @details     An administrator sets the maximum number of seconds of inactivity
+ *              time before the screen timeout occurs and a device user must
+ *              type the password to unlock the device.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   value Maximum inactivity time for device lock. Specifies how soon
+ *              the device can be unlocked again after use, without reprompting for
+ *              the passcode.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_max_inactivity_time_device_lock(device_policy_manager_h handle, int value);
+
+/**
+ * @partner
+ * @brief       Gets the maximum number of seconds of inactivity time
+ *              before the screen timeout occurs.
+ * @details     Called by an application that is managing the device to get
+ *              the value of timeout period.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[out]  value Pointer of Maximum inactivity time for device lock.
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_max_inactivity_time_device_lock(device_policy_manager_h handle, int *value);
+
+/**
+ * @partner
+ * @brief       Sets password status
+ * @details     An administrator can know password status for this API.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   status Password status
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_status(device_policy_manager_h handle, dpm_password_status_e status);
+
+/**
+ * @partner
+ * @brief       Gets password status
+ * @details     An administrator can know password status for this API.
+ * @since_tizen 3.0
+ * @param[in]   handle Device policy manager handle
+ * @param[out]   status Password status
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_status(device_policy_manager_h handle, dpm_password_status_e *status);
+
+
+/**
+ * @partner
+ * @brief       Removes all password patterns.
+ * @details     An administrator can remove all password patterns.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_delete_pattern(device_policy_manager_h handle);
+
+/**
+ * @partner
+ * @brief       Gets password pattern.
+ * @details     This API can be used for applying complexity on new password value.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @remarks     The @a pattern should be freed using free().
+ * @param[in]   handle Device policy manager handle
+ * @param[out]  pattern Password pattern
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_OUT_OF_MEMORY Out of memory
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_pattern(device_policy_manager_h handle, char **pattern);
+
+/**
+ * @partner
+ * @brief       Sets the maximum number of times a character can occur in
+ *              the device password.
+ * @details     Called by an admin that is managing the device to specify that
+ *              any character in the device password cannot occur more than
+ *              the specified maximum number of times. Characters can be numeric
+ *              or alphabetic or symbolic. "aaabcde" has 'a' which occurs 3 times,
+ *              "1b1c1de" has '1' which occurs 3 times and "a@b@c@" has '@' which
+ *              occurs 3 times. A value of '0' specifies that no restrictions are
+ *              applied.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   value Maximum character occurrences
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_maximum_character_occurrences(device_policy_manager_h handle, int value);
+
+/**
+ * @partner
+ * @brief       Gets the maximum number of times a character can occur in
+ *              the device password.
+ * @details     An administrator can retrieve the maximum number of times
+ *              a character can occur in the device password. If more than
+ *              one admin has set this value then the least value will take
+ *              preference.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[out]   value Pointer of Maximum Character Occurrences
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_maximum_character_occurrences(device_policy_manager_h handle, int *value);
+
+/**
+ * @partner
+ * @brief       Sets the maximum length of the numeric sequence
+ *              which is allowed in the device password.
+ * @details     Called by an administrator that is managing the device to set
+ *              the maximum numeric sequence length. This specifies that
+ *              the device password must not contain numeric sequences greater
+ *              than the given length.
+ *              Numeric sequences can be increasing successively by one like
+ *              "12345", or decreasing successively by one like "98765", or
+ *              repeating like "55555".
+ *              These are all numeric sequences of length '5'.
+ *              If maximum value is set to '5' then "123456" or "987654" or
+ *              "555555" are not allowed.
+ *              A value of '0' specifies that no such numeric sequence
+ *              restrictions are applied.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   value Maximum numeric sequence length
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_maximum_numeric_sequence_length(device_policy_manager_h handle, int value);
+
+/**
+ * @partner
+ * @brief       Gets the maximum numeric sequence length allowed in
+ *              the device password.
+ * @details     An administrator can retrieve the length of numeric sequences
+ *              which are allowed in the device password.
+ *              For instance, if the return value is '3' then "123", "987",
+ *              "555" would all be numeric sequences of length '3' and will be
+ *              allowed in the device password.
+ *              If more than one admin has set this value then the least value
+ *              will take preference.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[out]  value Pointer of maximum numeric sequence length
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_get_maximum_numeric_sequence_length(device_policy_manager_h handle, int *value);
+
+/**
+ * @brief       The password forbidden string list iterator handle
+ * @since_tizen 3.0
+ * @see         dpm_password_create_iterator()
+ * @see         dpm_password_iterator_next()
+ * @see         dpm_password_destroy_iterator()
+ */
+typedef void *dpm_password_iterator_h;
+
+/**
+ * @partner
+ * @brief       Creates a password forbidden string list iterator.
+ * @details     The password forbidden string list iterator can be used to get all forbidden strings.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @return      A password forbidden string list iterator on success, otherwise
+ *              null value
+ * @remarks     The specific error code can be obtained by using the
+ *              get_last_result() method. Error codes are described in
+ *              exception section.
+ *              The returned iterator should be released using dpm_password_destroy_iterator().
+ * @exception   #DPM_ERROR_NONE No error
+ * @exception   #DPM_ERROR_OUT_OF_MEMORY Out of memory
+ * @exception   #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @exception   #DPM_ERROR_TIMED_OUT Time out
+ * @exception   #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ * @see         dpm_password_iterator_next()
+ * @see         dpm_password_destroy_iterator()
+ * @see         get_last_result()
+ */
+dpm_password_iterator_h dpm_password_create_iterator(device_policy_manager_h handle);
+
+/**
+ * @partner
+ * @brief       Fetches a password forbidden string and forwards the iterator.
+ * @details     This API returns a password forbidden string indicated by the iterator, and then
+ *              the iterator is moved to the next position. If the iterator reaches
+ *              the end of the list, null value will be returned.
+ * @since_tizen 3.0
+ * @param[in]   iter The iterator to be controlled
+ * @param[out]  forbidden_string The forbidden string got from the iterator
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @remarks     The @a forbidden_string should not be freed using free().
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @pre         The iter must be created by dpm_password_create_iterator().
+ * @see         dpm_passsword_create_iterator()
+ * @see         dpm_password_destroy_iterator()
+ */
+int dpm_password_iterator_next(dpm_password_iterator_h iter, const char **forbidden_string);
+
+/**
+ * @partner
+ * @brief       Frees the password forbidden string iterator.
+ * @details     This API frees the password forbidden string iterator. This API must be called
+ *              if the iterator no longer used.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   iter The iterator to be removed
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The iter must be created by dpm_password_create_iterator()
+ * @see         dpm_password_create_iterator()
+ * @see         dpm_password_iterator_next()
+ */
+int dpm_password_destroy_iterator(dpm_password_iterator_h iter);
+
+/**
+ * @partner
+ * @brief       Sets strings which are forbidden in the device password.
+ * @details     Called by an admin that is managing the device to set strings that are forbidden to be used in the device password.
+ *              This specifies any strings which must not be present in the device password such as personal data (variations on the user's name, email address or X400 address), or any other strings.
+ *              If the parameter list has only one blank string(""), then the stored strings are cleared.
+ * @since_tizen 3.0
+ * @privlevel   partner
+ * @privilege   %http://tizen.org/privilege/dpm.password
+ * @param[in]   handle Device policy manager handle
+ * @param[in]   strings The forbidden strings
+ * @param[in]   length The length of the strings
+ * @return      #DPM_ERROR_NONE on success, otherwise a negative value
+ * @retval      #DPM_ERROR_NONE Successful
+ * @retval      #DPM_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval      #DPM_ERROR_TIMED_OUT Time out
+ * @retval      #DPM_ERROR_PERMISSION_DENIED The application does not have
+ *              the privilege to call this API
+ * @pre         The handle must be created by dpm_manager_create().
+ * @see         dpm_manager_create()
+ */
+int dpm_password_set_forbidden_strings(device_policy_manager_h handle, const char *strings[], int length);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  __CAPI_PASSWORD_POLICY_H__ */
diff --git a/api/dpm-auth.pc.in b/api/dpm-auth.pc.in
new file mode 100644 (file)
index 0000000..8f300a5
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@LIB_INSTALL_DIR@
+includedir=@INCLUDE_INSTALL_DIR@
+
+Name: Authentication policy module
+Description: Authentication policy module for device policy manager
+Version: @VERSION@
+Libs: -L${libdir} -ldpm-auth
+Cflags: -I${includedir}/dpm
+
diff --git a/api/password.cpp b/api/password.cpp
new file mode 100644 (file)
index 0000000..93963dd
--- /dev/null
@@ -0,0 +1,614 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include <cstring>
+#include <cassert>
+#include <vector>
+#include <utility>
+
+#include <tizen.h>
+#include <tizen_type.h>
+
+#include <dpm/pil/policy-client.h>
+
+#include "auth.h"
+
+template <typename T>
+class Array final {
+public:
+       Array() = delete;
+       Array(std::vector<T> &&list) : list(std::move(list)), it(this->list.begin())
+       {
+       }
+
+       Array(const std::vector<T> &list) : list(list), it(this->list.begin())
+       {
+       }
+
+       T *next() {
+               if (it != list.end()) {
+                       return &(*it++);
+               }
+               return NULL;
+       }
+
+       bool isEnd() {
+               return it == list.end();
+       }
+
+private:
+       std::vector<T> list;
+       typename std::vector<T>::iterator it;
+};
+
+EXPORT_API int dpm_password_set_quality(void* handle, int quality)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(quality >= 0, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setQuality", quality);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_quality(void* handle, int *quality)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(quality, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getQuality");
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *quality = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_minimum_length(void* handle, int value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value >= 0, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::setMinimumLength", value);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_minimum_length(void* handle, int *value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getMinimumLength");
+
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *value = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_min_complex_chars(void* handle, int value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value >= 0, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setMinComplexChars", value);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_min_complex_chars(void* handle, int *value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getMinComplexChars");
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *value = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_maximum_failed_attempts_for_wipe(void* handle, int value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value >= 0, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setMaximumFailedForWipe", value);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_maximum_failed_attempts_for_wipe(void* handle, int *value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getMaximumFailedForWipe");
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *value = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_expires(void* handle, int value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value >= 0, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setExpires", value);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_expires(void* handle, int *value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getExpires");
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *value = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_history(void* handle, int value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value >= 0, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setHistory", value);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_history(void* handle, int *value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getHistory");
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *value = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_pattern(void* handle, const char *pattern)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(pattern, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setPattern", pattern);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_reset(void* handle, const char *passwd)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(passwd, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::reset", passwd);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_enforce_change(void* handle)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::enforceChange");
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_set_max_inactivity_time_device_lock(void* handle, int value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value >= 0, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setMaxInactivityTimeDeviceLock", value);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_max_inactivity_time_device_lock(void* handle, int *value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getMaxInactivityTimeDeviceLock");;
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *value = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_status(void* handle, dpm_password_status_e status)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(status >= DPM_PASSWORD_STATUS_NORMAL &&
+                                  status <= DPM_PASSWORD_STATUS_PATTERN_CHANGED,
+                                  DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setStatus", (int)status);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_ret(void* handle, dpm_password_status_e *status)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(status, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getStatus");
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *status = (dpm_password_status_e)ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_delete_pattern(void* handle)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::deletePattern");
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_pattern(void* handle, char **pattern)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(pattern, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<std::string> ret { std::string() };
+               ret = client.methodCall<std::string>("Password::getPattern");
+               *pattern = ::strdup(ret.get().c_str());
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_maximum_character_occurrences(void* handle, int value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value >= 0, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setMaximumCharacterOccurrences", value);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_maximum_character_occurrences(void* handle, int *value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getMaximumCharacterOccurrences");
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *value = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_maximum_numeric_sequence_length(void* handle, int value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value >= 0, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setMaximumNumericSequenceLength", value);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_maximum_numeric_sequence_length(void* handle, int *value)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(value, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { 0 };
+               ret = client.methodCall<int>("Password::getMaximumNumericSequenceLength");
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *value = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
+typedef Array<std::string> dpm_password_iterator;
+
+EXPORT_API dpm_password_iterator_h dpm_password_create_iterator(void* handle)
+{
+       RET_ON_FAILURE(handle, NULL);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       Status<std::vector<std::string>> status { std::vector<std::string>() };
+       status = client.methodCall<std::vector<std::string>>("Password::getForbiddenStrings");
+
+       dpm_password_iterator *iter = new dpm_password_iterator(status.get());
+       return reinterpret_cast<dpm_password_iterator_h>(iter);
+}
+
+EXPORT_API int dpm_password_iterator_next(dpm_password_iterator_h iter, const char **result)
+{
+       RET_ON_FAILURE(iter, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(result, DPM_ERROR_INVALID_PARAMETER);
+
+       dpm_password_iterator *it = reinterpret_cast<dpm_password_iterator *>(iter);
+
+       if (it->isEnd())
+               *result = NULL;
+       else
+               *result = it->next()->c_str();
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_destroy_iterator(dpm_password_iterator_h iter)
+{
+       RET_ON_FAILURE(iter, DPM_ERROR_INVALID_PARAMETER);
+
+       delete reinterpret_cast<dpm_password_iterator *>(iter);
+
+       return DPM_ERROR_NONE;
+}
+
+EXPORT_API int dpm_password_set_forbidden_strings(void* handle, const char *strings[], int length)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+       std::vector<std::string> forbiddenStrings;
+
+       for (int i = 0; i < length; i++)
+               forbiddenStrings.push_back(strings[i]);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setForbiddenStrings", forbiddenStrings);
+               return ret.get();
+       } catch(...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_set_recovery(void* handle, int enable)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { -1 };
+               ret = client.methodCall<int>("Password::setRecovery", enable);
+               return ret.get();
+       } catch (...) {
+               return -1;
+       }
+}
+
+EXPORT_API int dpm_password_get_recovery(void* handle, int *enable)
+{
+       RET_ON_FAILURE(handle, DPM_ERROR_INVALID_PARAMETER);
+       RET_ON_FAILURE(enable, DPM_ERROR_INVALID_PARAMETER);
+
+       DevicePolicyClient &client = GetDevicePolicyClient(handle);
+
+       try {
+               Status<int> ret { false };
+               ret = client.methodCall<int>("Password::getRecovery");
+               if (ret.get() < 0) {
+                       return -1;
+               }
+
+               *enable = ret.get();
+       } catch (...) {
+               return -1;
+       }
+
+       return DPM_ERROR_NONE;
+}
+
diff --git a/dpm-auth.manifest b/dpm-auth.manifest
new file mode 100644 (file)
index 0000000..a76fdba
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+       <request>
+               <domain name="_" />
+       </request>
+</manifest>
diff --git a/packaging/dpm-auth.spec b/packaging/dpm-auth.spec
new file mode 100755 (executable)
index 0000000..c54fe99
--- /dev/null
@@ -0,0 +1,77 @@
+Name:    dpm-auth
+Version: 1.0.1
+Release: 0
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+Summary: Tizen Device Policy Manager Authentication Policy Module
+Group:   Security/Other
+BuildRequires: gcc
+BuildRequires: cmake
+BuildRequires: gettext-tools
+BuildRequires: pkgconfig(klay)
+BuildRequires: pkgconfig(dpm-pil)
+BuildRequires: pkgconfig(auth-fw-admin)
+BuildRequires: pkgconfig(capi-system-info)
+BuildRequires: pkgconfig(capi-base-common)
+
+%description
+The dpm-auth package provides authentication policy module for device policy manager
+
+%files
+%manifest dpm-auth.manifest
+%defattr(644,root,root,755)
+%attr(755,root,root) /opt/data/dpm/plugins/auth
+%attr(755,root,root) %{_libdir}/libdpm-auth.so.%{version}
+%{_libdir}/libdpm-auth.so.0
+
+%prep
+%setup -q
+
+%build
+%{!?build_type:%define build_type "RELEASE"}
+
+%if %{build_type} == "DEBUG" || %{build_type} == "PROFILING" || %{build_type} == "CCOV"
+       CFLAGS="$CFLAGS -Wp,-U_FORTIFY_SOURCE"
+       CXXFLAGS="$CXXFLAGS -Wp,-U_FORTIFY_SOURCE"
+%endif
+
+%cmake . -DVERSION=%{version} \
+         -DCMAKE_BUILD_TYPE=%{build_type} \
+         -DSCRIPT_INSTALL_DIR=%{_scriptdir} \
+         -DSYSTEMD_UNIT_INSTALL_DIR=%{_unitdir} \
+         -DDATA_INSTALL_DIR=%{TZ_SYS_DATA}/dpm \
+         -DDB_INSTALL_DIR=%{TZ_SYS_DB} \
+         -DRUN_INSTALL_DIR=%{TZ_SYS_RUN} \
+         -DAPP_INSTALL_PREFIX="%{TZ_SYS_RO_APP}" \
+         -DAPP_SHARE_PACKAGES_DIR="%{TZ_SYS_RO_PACKAGES}" \
+
+make %{?jobs:-j%jobs}
+
+%install
+%make_install
+
+%clean
+rm -rf %{buildroot}
+
+%post
+
+%preun
+
+%postun
+
+## Devel Package ##############################################################
+%package -n libdpm-auth-devel
+Summary: Libraries and header files for device policy client development
+Group: Development/Libraries
+Requires: device-policy-manager = %{version}-%{release}
+
+%description -n libdpm-auth-devel
+The libdpm-auth-devel package includes the libraries and header files necessary for
+developing the DPM client program.
+
+%files -n libdpm-auth-devel
+%manifest dpm-auth.manifest
+%defattr(644,root,root,755)
+%{_libdir}/libdpm-auth.so
+%{_libdir}/pkgconfig/dpm-auth.pc
+%{_includedir}/dpm
diff --git a/plugin/CMakeLists.txt b/plugin/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..2a441c7
--- /dev/null
@@ -0,0 +1,36 @@
+#
+# Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+SET(TARGET "dpm-plugin-auth")
+
+SET(PLUGIN_SOURCES  password.cpp
+                                       password-manager.cpp
+)
+
+SET(DEPENDENCY      klay
+                                       dpm-pil
+                                       auth-fw-admin
+)
+
+PKG_CHECK_MODULES(PLUGIN_DEPS REQUIRED ${DEPENDENCY})
+
+SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,noexecstack")
+
+ADD_LIBRARY(${TARGET} SHARED ${PLUGIN_SOURCES})
+SET_TARGET_PROPERTIES(${TARGET} PROPERTIES COMPILE_FLAGS "-fvisibility=default")
+INCLUDE_DIRECTORIES(SYSTEM ${PLUGIN_DEPS_INCLUDE_DIRS})
+TARGET_LINK_LIBRARIES(${TARGET} ${PLUGIN_DEPS_LIBRARIES})
+
+INSTALL(FILES libdpm-plugin-auth.so RENAME auth DESTINATION /opt/data/dpm/plugins)
diff --git a/plugin/password-manager.cpp b/plugin/password-manager.cpp
new file mode 100644 (file)
index 0000000..5f4035e
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include <klay/exception.h>
+
+#include "password-manager.h"
+
+PasswordManager::PasswordManager(uid_t uid) :
+       user(uid)
+{
+       if (auth_passwd_new_policy(&p_policy) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to get auth instance");
+       }
+
+       auth_passwd_set_user(p_policy, user);
+}
+
+PasswordManager::~PasswordManager()
+{
+       auth_passwd_free_policy(p_policy);
+}
+
+void PasswordManager::setQuality(PasswordManager::QualityType quality)
+{
+       if (auth_passwd_set_quality(p_policy, quality) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to enforce password quality");
+       }
+}
+
+void PasswordManager::setMinimumLength(int value)
+{
+       if (auth_passwd_set_min_length(p_policy, value) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to set minimum length");
+       }
+}
+
+void PasswordManager::setMinimumComplexCharacters(int value)
+{
+       if (auth_passwd_set_min_complex_char_num(p_policy, value) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to set minimum complex characters");
+       }
+}
+
+void PasswordManager::setMaximumFailedForWipe(int value)
+{
+       if (auth_passwd_set_max_attempts(p_policy, value) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to set maximum failed count for wipe");
+       }
+}
+
+void PasswordManager::setExpires(int value)
+{
+       if (auth_passwd_set_validity(p_policy, value) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to set expire");
+       }
+}
+
+void PasswordManager::setHistory(int value)
+{
+       if (auth_passwd_set_history_size(p_policy, value) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to set history size");
+       }
+}
+
+void PasswordManager::setPattern(const char* pattern)
+{
+       if (auth_passwd_set_pattern(p_policy, pattern) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to set pattern");
+       }
+}
+
+void PasswordManager::deletePatern()
+{
+       if (auth_passwd_set_pattern(p_policy, NULL) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to delete pattern");
+       }
+}
+
+void PasswordManager::setMaximumCharacterOccurrences(int value)
+{
+       if (auth_passwd_set_max_char_occurrences(p_policy, value) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to set maximum character occurrences");
+       }
+}
+
+void PasswordManager::setMaximumNumericSequenceLength(int value)
+{
+       if (auth_passwd_set_max_num_seq_len(p_policy, value) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to set maximum numeric sequence length");
+       }
+}
+
+void PasswordManager::setForbiddenStrings(const std::vector<std::string> &forbiddenStrings)
+{
+       for (const std::string& str : forbiddenStrings) {
+               if (auth_passwd_set_forbidden_passwd(p_policy, str.c_str()) != AUTH_PASSWD_API_SUCCESS) {
+                       throw runtime::Exception("Failed to set forbidden strings");
+               }
+       }
+}
+
+void PasswordManager::enforce()
+{
+       if (auth_passwd_set_policy(p_policy) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to enforce policy");
+       }
+}
+
+void PasswordManager::resetPassword(const std::string& password)
+{
+       if (auth_passwd_reset_passwd(AUTH_PWD_NORMAL, user, password.c_str()) != AUTH_PASSWD_API_SUCCESS) {
+               throw runtime::Exception("Failed to set reset password");
+       }
+}
diff --git a/plugin/password-manager.h b/plugin/password-manager.h
new file mode 100644 (file)
index 0000000..914dc5f
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#ifndef __DPM_PASSWORD_MANAGER_H__
+#define __DPM_PASSWORD_MANAGER_H__
+#include <sys/types.h>
+
+#include <vector>
+#include <string>
+
+#include <auth-passwd-admin.h>
+
+class PasswordManager {
+public:
+       typedef password_quality_type QualityType;
+
+       PasswordManager(uid_t uid);
+       ~PasswordManager();
+
+       void setQuality(QualityType quality);
+       void setMinimumLength(int value);
+       void setMinimumComplexCharacters(int value);
+       void setMaximumFailedForWipe(int value);
+       void setExpires(int value);
+       void setHistory(int value);
+       void setPattern(const char* pattern);
+       void deletePatern();
+       void setMaximumCharacterOccurrences(int value);
+       void setMaximumNumericSequenceLength(int value);
+       void setForbiddenStrings(const std::vector<std::string> &forbiddenStrings);
+       void resetPassword(const std::string& password);
+       void enforce();
+
+private:
+       uid_t user;
+       policy_h *p_policy;
+};
+#endif //!__DPM_PASSWORD_MANAGER_H__
diff --git a/plugin/password.cpp b/plugin/password.cpp
new file mode 100644 (file)
index 0000000..23763c1
--- /dev/null
@@ -0,0 +1,617 @@
+/*
+ *  Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#include <sys/types.h>
+
+#include <unordered_map>
+
+#include <dpm/pil/policy-context.h>
+#include <dpm/pil/policy-model.h>
+#include <dpm/pil/policy-storage.h>
+#include <dpm/pil/app-bundle.h>
+#include <dpm/pil/launchpad.h>
+
+#include "password-manager.h"
+
+typedef enum {
+       DPM_PASSWORD_QUALITY_UNSPECIFIED     = 0x00,    /**< No requirements for password. */
+       DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD = 0x01,    /**< Eas requirement for simple password */
+       DPM_PASSWORD_QUALITY_SOMETHING       = 0x10,    /**< Some kind password is required, but doesn't care what it is */
+       DPM_PASSWORD_QUALITY_NUMERIC         = 0x20,    /**< Containing at least numeric characters */
+       DPM_PASSWORD_QUALITY_ALPHABETIC      = 0x40,    /**< Containing at least alphabetic (or other symbol) characters */
+       DPM_PASSWORD_QUALITY_ALPHANUMERIC    = 0x80,    /**< Containing at least numeric and alphabetic characters */
+} PasswordPolicyQuality;
+
+typedef enum {
+       DPM_PASSWORD_STATUS_NORMAL,                  /**< Password normal status */
+       DPM_PASSWORD_STATUS_CHANGED,                 /**< Password successfully changed */
+       DPM_PASSWORD_STATUS_NOT_CHANGED,             /**< Password not changed */
+       DPM_PASSWORD_STATUS_CHANGE_REQUIRED ,        /**< Password change required */
+       DPM_PASSWORD_STATUS_MAX_ATTEMPTS_EXCEEDED,   /**< Password Max Attempts Exceeded*/
+
+       DPM_PASSWORD_STATUS_EXPIRED,                    /**< Password expired */
+       DPM_PASSWORD_STATUS_RECOVERY_PASSWORD_FAILED,   /**< Device unlock failed by Password Recovery */
+       DPM_PASSWORD_STATUS_RECOVERY_PASSWORD_SUCCEEDED,/**< Device unlock succeeded by Password Recovery */
+
+       DPM_PASSWORD_STATUS_QUALITY_CHANGED,            /**< Password quality successfully changed */
+       DPM_PASSWORD_STATUS_MIN_LENGTH_CHANGED,         /**< Password min_length successfully changed */
+       DPM_PASSWORD_STATUS_COMPLEX_CHAR_CHANGED,       /**< Password complex_char successfully changed */
+       DPM_PASSWORD_STATUS_PATTERN_CHANGED,            /**< Password pattern successfully changed */
+       DPM_PASSWORD_STATUS_MAX
+} PasswordPolicyStatus;
+
+namespace {
+
+const int simplePasswordLength = 4;
+const int infinite = 32767;
+
+std::unordered_map<uid_t, int> passwordStatus;
+
+inline int inverse(int value)
+{
+       return -value;
+}
+
+inline PasswordManager::QualityType getPasswordQualityType(int quality)
+{
+       switch (quality) {
+       case DPM_PASSWORD_QUALITY_UNSPECIFIED:
+               return AUTH_PWD_QUALITY_UNSPECIFIED;
+       case DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD:
+               return AUTH_PWD_QUALITY_UNSPECIFIED;
+       case DPM_PASSWORD_QUALITY_SOMETHING:
+               return AUTH_PWD_QUALITY_SOMETHING;
+       case DPM_PASSWORD_QUALITY_NUMERIC:
+               return AUTH_PWD_QUALITY_NUMERIC;
+       case DPM_PASSWORD_QUALITY_ALPHABETIC:
+               return AUTH_PWD_QUALITY_ALPHABETIC;
+       case DPM_PASSWORD_QUALITY_ALPHANUMERIC:
+               return AUTH_PWD_QUALITY_ALPHANUMERIC;
+       default:
+               throw runtime::Exception("Unknown quality type: " + std::to_string(quality));
+       }
+}
+
+} // namespace
+
+class PasswordQuality : public DomainPolicy<DataSetInt> {
+public:
+       PasswordQuality() : DomainPolicy("password-quality")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               try {
+                       int auth = DPM_PASSWORD_QUALITY_UNSPECIFIED;
+
+                       int quality = inverse(value);
+                       if (quality & DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD) {
+                               auth = quality - DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD;
+                       }
+
+                       PasswordManager::QualityType type = getPasswordQualityType(auth);
+
+                       PasswordManager passwordManager(domain);
+                       passwordManager.setQuality(type);
+                       passwordManager.enforce();
+               } catch (runtime::Exception &e) {
+                       ERROR(e.what());
+                       return false;
+               }
+
+               return true;
+       }
+};
+
+class PasswordSequences : public DomainPolicy<DataSetInt> {
+public:
+       PasswordSequences() : DomainPolicy("password-numeric-sequences-length")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               int v = value;
+               try {
+                       v = v == infinite ? 0 : v;
+                       PasswordManager passwordManager(domain);
+                       passwordManager.setMaximumNumericSequenceLength(v);
+                       passwordManager.enforce();
+               } catch (runtime::Exception &e) {
+                       ERROR(e.what());
+                       return false;
+               }
+
+               return true;
+       }
+};
+
+class PasswordOccurrences : public DomainPolicy<DataSetInt> {
+public:
+       PasswordOccurrences() : DomainPolicy("password-maximum-character-occurrences")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               int v = value;
+               try {
+                       v = v == infinite ? 0 : v;
+                       PasswordManager passwordManager(domain);
+                       passwordManager.setMaximumCharacterOccurrences(value);
+                       passwordManager.enforce();
+               } catch (runtime::Exception &e) {
+                       ERROR(e.what());
+                       return false;
+               }
+
+               return true;
+       }
+};
+
+class PasswordHistory : public DomainPolicy<DataSetInt> {
+public:
+       PasswordHistory() : DomainPolicy("password-history")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               try {
+                       PasswordManager passwordManager(domain);
+                       passwordManager.setHistory(inverse(value));
+                       passwordManager.enforce();
+               } catch (runtime::Exception &e) {
+                       ERROR(e.what());
+                       return false;
+               }
+
+               return true;
+       }
+};
+
+class PasswordExpire : public DomainPolicy<DataSetInt> {
+public:
+       PasswordExpire() : DomainPolicy("password-expired")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               try {
+                       PasswordManager passwordManager(domain);
+                       passwordManager.setExpires(value);
+                       passwordManager.enforce();
+               } catch (runtime::Exception &e) {
+                       ERROR(e.what());
+                       return false;
+               }
+
+               return true;
+       }
+};
+
+class PasswordFailureCount : public DomainPolicy<DataSetInt> {
+public:
+       PasswordFailureCount() : DomainPolicy("password-maximum-failure-count")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               try {
+                       PasswordManager passwordManager(domain);
+                       passwordManager.setMaximumFailedForWipe(value);
+                       passwordManager.enforce();
+               } catch (runtime::Exception &e) {
+                       ERROR(e.what());
+                       return false;
+               }
+
+               return true;
+       }
+};
+
+class PasswordComplexity : public DomainPolicy<DataSetInt> {
+public:
+       PasswordComplexity() : DomainPolicy("password-minimum-complexity")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               try {
+                       PasswordManager passwordManager(domain);
+                       passwordManager.setMinimumComplexCharacters(inverse(value));
+                       passwordManager.enforce();
+               } catch (runtime::Exception &e) {
+                       ERROR(e.what());
+                       return false;
+               }
+
+               return true;
+       }
+};
+
+class PasswordLength : public DomainPolicy<DataSetInt> {
+public:
+       PasswordLength() : DomainPolicy("password-minimum-length")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               try {
+                       PasswordManager passwordManager(domain);
+                       passwordManager.setMinimumLength(inverse(value));
+                       passwordManager.enforce();
+               } catch (runtime::Exception &e) {
+                       ERROR(e.what());
+                       return false;
+               }
+
+               return true;
+       }
+};
+
+class PasswordTimeout : public DomainPolicy<DataSetInt> {
+public:
+       PasswordTimeout() : DomainPolicy("password-inactivity-timeout")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               return true;
+       }
+};
+
+class PasswordRecovery : public DomainPolicy<DataSetInt> {
+public:
+       PasswordRecovery() : DomainPolicy("password-recovery")
+       {
+       }
+
+       bool apply(const DataType& value, uid_t domain)
+       {
+               return true;
+       }
+};
+
+class Password : public AbstractPolicyProvider {
+public:
+       int setQuality(int quality);
+       int getQuality();
+       int setMinimumLength(int value);
+       int getMinimumLength();
+       int setMinComplexChars(int value);
+       int getMinComplexChars();
+       int setMaximumFailedForWipe(int value);
+       int getMaximumFailedForWipe();
+       int setExpires(int value);
+       int getExpires();
+       int setHistory(int value);
+       int getHistory();
+       int setPattern(const std::string &pattern);
+       int reset(const std::string &passwd);
+       int enforceChange();
+       int setMaxInactivityTimeDeviceLock(int value);
+       int getMaxInactivityTimeDeviceLock();
+       int setStatus(int status);
+       int getStatus();
+       int deletePattern();
+       std::string getPattern();
+       int setMaximumCharacterOccurrences(int value);
+       int getMaximumCharacterOccurrences();
+       int setMaximumNumericSequenceLength(int value);
+       int getMaximumNumericSequenceLength();
+       int setForbiddenStrings(const std::vector<std::string> &forbiddenStrings);
+       std::vector<std::string> getForbiddenStrings();
+       int setRecovery(int enable);
+       int getRecovery();
+
+private:
+       PasswordQuality      quality;
+       PasswordHistory      history;
+       PasswordLength       length;
+       PasswordComplexity   complexity;
+       PasswordTimeout      timeout;
+       PasswordExpire       expire;
+       PasswordFailureCount failureCount;
+       PasswordSequences    sequences;
+       PasswordOccurrences  occurrences;
+       PasswordRecovery     recovery;
+};
+
+int Password::setQuality(int value)
+{
+       try {
+               quality.set(inverse(value));
+               if (value & DPM_PASSWORD_QUALITY_SIMPLE_PASSWORD) {
+                       length.set(inverse(simplePasswordLength));
+               }
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getQuality()
+{
+       int value = quality.get();
+       return inverse(value);
+}
+
+int Password::setMinimumLength(int value)
+{
+       try {
+               value = inverse(value);
+               length.set(value);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getMinimumLength()
+{
+       int value = length.get();
+       return inverse(value);
+}
+
+int Password::setMinComplexChars(int value)
+{
+       try {
+               value = inverse(value);
+               complexity.set(value);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getMinComplexChars()
+{
+       int value = complexity.get();
+       return inverse(value);
+}
+
+int Password::setMaximumFailedForWipe(int value)
+{
+       try {
+               value = value == 0 ? infinite : value;
+               failureCount.set(value);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getMaximumFailedForWipe()
+{
+       int value = failureCount.get();
+       return value == infinite ? 0 : value;
+}
+
+int Password::setExpires(int value)
+{
+       try {
+               value = value == 0 ? infinite : value;
+               expire.set(value);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getExpires()
+{
+       int value = expire.get();
+       return value == infinite ? 0 : value;
+}
+
+int Password::setHistory(int value)
+{
+       try {
+               value = inverse(value);
+               history.set(value);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getHistory()
+{
+       int value = history.get();
+       return inverse(value);
+}
+
+int Password::reset(const std::string &passwd)
+{
+       try {
+               PasswordManager passwordManager(rmi::Service::getPeerUid());
+               passwordManager.resetPassword(passwd);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::enforceChange()
+{
+       try {
+               Bundle bundle;
+               bundle.add("id", "password-enforce-change");
+
+               Launchpad launchpad(rmi::Service::getPeerUid());
+               launchpad.launch("org.tizen.dpm-syspopup", bundle);
+               passwordStatus[rmi::Service::getPeerUid()] = DPM_PASSWORD_STATUS_CHANGE_REQUIRED;
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::setMaxInactivityTimeDeviceLock(int value)
+{
+       try {
+               value = value == 0 ? infinite : value;
+               timeout.set(value);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getMaxInactivityTimeDeviceLock()
+{
+       int value = timeout.get();
+       return value == infinite ? 0 : value;
+}
+
+int Password::setStatus(int status)
+{
+       if (status >= DPM_PASSWORD_STATUS_MAX) {
+               ERROR("Invalid password status");
+               return -1;
+       }
+
+       passwordStatus[rmi::Service::getPeerUid()] = status;
+       //ctx.notify("password", "password-status");
+
+       return 0;
+}
+
+int Password::getStatus()
+{
+       return passwordStatus[rmi::Service::getPeerUid()];
+}
+
+int Password::setMaximumCharacterOccurrences(int value)
+{
+       try {
+               value = value == 0 ? infinite : value;
+               occurrences.set(value);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getMaximumCharacterOccurrences()
+{
+       int value = occurrences.get();
+       return value == infinite ? 0 : value;
+}
+
+int Password::setMaximumNumericSequenceLength(int value)
+{
+       try {
+               value = value == 0 ? infinite : value;
+               sequences.set(value);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getMaximumNumericSequenceLength()
+{
+       int value = sequences.get();
+       return value == infinite ? 0 : value;
+}
+
+int Password::setRecovery(int enable)
+{
+       try {
+               enable = inverse(enable);
+               recovery.set(enable);
+       } catch (runtime::Exception& e) {
+               ERROR(e.what());
+               return -1;
+       }
+
+       return 0;
+}
+
+int Password::getRecovery()
+{
+       int value = recovery.get();
+       return inverse(value);
+}
+
+extern "C" {
+
+#define PRIVILEGE "http://tizen.org/privilege/dpm.password"
+
+AbstractPolicyProvider *PolicyFactory(PolicyControlContext& context)
+{
+       Password *policy = new Password();
+
+       context.expose(policy, PRIVILEGE, (int)(Password::setQuality)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::setMinimumLength)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::setMinComplexChars)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::setMaximumFailedForWipe)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::setExpires)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::setHistory)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::reset)(std::string));
+       context.expose(policy, PRIVILEGE, (int)(Password::enforceChange)());
+       context.expose(policy, PRIVILEGE, (int)(Password::setMaxInactivityTimeDeviceLock)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::setStatus)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::setMaximumCharacterOccurrences)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::setMaximumNumericSequenceLength)(int));
+       context.expose(policy, PRIVILEGE, (int)(Password::setRecovery)(int));
+
+       context.expose(policy, "", (int)(Password::getStatus)());
+       context.expose(policy, PRIVILEGE, (int)(Password::getQuality)());
+       context.expose(policy, PRIVILEGE, (int)(Password::getMinimumLength)());
+       context.expose(policy, PRIVILEGE, (int)(Password::getMinComplexChars)());
+       context.expose(policy, PRIVILEGE, (int)(Password::getMaximumFailedForWipe)());
+       context.expose(policy, PRIVILEGE, (int)(Password::getExpires)());
+       context.expose(policy, PRIVILEGE, (int)(Password::getHistory)());
+       context.expose(policy, PRIVILEGE, (int)(Password::getMaxInactivityTimeDeviceLock)());
+       context.expose(policy, PRIVILEGE, (int)(Password::getMaximumCharacterOccurrences)());
+       context.expose(policy, PRIVILEGE, (int)(Password::getMaximumNumericSequenceLength)());
+       context.expose(policy, "", (int)(Password::getRecovery)());
+
+       return policy;
+}
+
+} // extern "C"