2 * Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Bumjin Im <bj.im@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
19 * @file password-manager.cpp
20 * @author Zbigniew Jasinski (z.jasinski@samsung.com)
21 * @author Lukasz Kostyra (l.kostyra@partner.samsung.com)
23 * @brief Implementation of password management functions
26 #include <password-manager.h>
34 #include <dpl/log/log.h>
36 #include <protocols.h>
38 #include <security-server.h>
41 bool calculateExpiredTime(unsigned int receivedDays, unsigned int &validSecs)
43 validSecs = SecurityServer::PASSWORD_INFINITE_EXPIRATION_TIME;
45 //when receivedDays means infinite expiration, return default validSecs value.
46 if(receivedDays == SecurityServer::PASSWORD_INFINITE_EXPIRATION_DAYS)
49 time_t curTime = time(NULL);
51 if (receivedDays > ((UINT_MAX - curTime) / 86400)) {
52 LogError("Incorrect input param.");
55 validSecs = (curTime + (receivedDays * 86400));
61 namespace SecurityServer
63 int PasswordManager::isPwdValid(unsigned int ¤tAttempt, unsigned int &maxAttempt,
64 unsigned int &expirationTime) const
66 if (!m_pwdFile.isPasswordActive()) {
67 LogError("Current password not active.");
68 return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
70 currentAttempt = m_pwdFile.getAttempt();
71 maxAttempt = m_pwdFile.getMaxAttempt();
72 expirationTime = m_pwdFile.getExpireTimeLeft();
74 return SECURITY_SERVER_API_ERROR_PASSWORD_EXIST;
77 return SECURITY_SERVER_API_SUCCESS;
80 int PasswordManager::checkPassword(const std::string &challenge, unsigned int ¤tAttempt,
81 unsigned int &maxAttempt, unsigned int &expirationTime)
83 LogSecureDebug("Inside checkPassword function.");
85 if (m_pwdFile.isIgnorePeriod()) {
86 LogError("Retry timeout occurred.");
87 return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
90 if (!m_pwdFile.isPasswordActive()) {
91 LogError("Password not active.");
92 return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
95 m_pwdFile.incrementAttempt();
96 m_pwdFile.writeAttemptToFile();
98 currentAttempt = m_pwdFile.getAttempt();
99 maxAttempt = m_pwdFile.getMaxAttempt();
100 expirationTime = m_pwdFile.getExpireTimeLeft();
102 if (m_pwdFile.checkIfAttemptsExceeded()) {
103 LogError("Too many tries.");
104 return SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
107 if (!m_pwdFile.checkPassword(challenge)) {
108 LogError("Wrong password.");
109 return SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH;
112 if (m_pwdFile.checkExpiration()) {
113 LogError("Password expired.");
114 return SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED;
117 m_pwdFile.resetAttempt();
118 m_pwdFile.writeAttemptToFile();
120 return SECURITY_SERVER_API_SUCCESS;
123 int PasswordManager::setPassword(const std::string ¤tPassword,
124 const std::string &newPassword,
125 const unsigned int receivedAttempts,
126 const unsigned int receivedDays)
128 LogSecureDebug("Curpwd = " << currentPassword << ", newpwd = " << newPassword <<
129 ", recatt = " << receivedAttempts << ", recdays = " << receivedDays);
131 unsigned int valid_secs = 0;
133 if (m_pwdFile.isIgnorePeriod()) {
134 LogError("Retry timeout occured.");
135 return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
138 //check if passwords are correct
139 if (currentPassword.size() > MAX_PASSWORD_LEN) {
140 LogError("Current password length failed.");
141 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
144 if (newPassword.size() > MAX_PASSWORD_LEN) {
145 LogError("New password length failed.");
146 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
149 //check delivered currentPassword
150 //when m_passwordActive flag is true, currentPassword shouldn't be empty
151 if (currentPassword.empty() && m_pwdFile.isPasswordActive()) {
152 LogError("Password is already set. Max history: " << m_pwdFile.getMaxHistorySize());
153 return SECURITY_SERVER_API_ERROR_PASSWORD_EXIST;
156 //increment attempt count before checking it against max attempt count
157 m_pwdFile.incrementAttempt();
158 m_pwdFile.writeAttemptToFile();
161 if (m_pwdFile.checkIfAttemptsExceeded()) {
162 LogError("Too many attempts.");
163 return SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
166 //check current password, however only when we don't send empty string as current.
167 if(!currentPassword.empty()) {
168 if(!m_pwdFile.checkPassword(currentPassword)) {
169 LogError("Wrong password.");
170 return SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH;
174 //check if password expired
175 if (m_pwdFile.checkExpiration()) {
176 LogError("Password expired.");
177 return SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED;
180 //check history, however only if history is active
181 if (m_pwdFile.isPasswordActive() && m_pwdFile.isHistoryActive()) {
182 if (m_pwdFile.isPasswordReused(newPassword)) {
183 LogError("Password reused.");
184 return SECURITY_SERVER_API_ERROR_PASSWORD_REUSED;
188 if(!calculateExpiredTime(receivedDays, valid_secs)) {
189 LogError("Received expiration time incorrect.");
190 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
194 m_pwdFile.setPassword(newPassword);
195 m_pwdFile.activatePassword();
196 m_pwdFile.setMaxAttempt(receivedAttempts);
197 m_pwdFile.setExpireTime(valid_secs);
198 m_pwdFile.writeMemoryToFile();
200 m_pwdFile.resetAttempt();
201 m_pwdFile.writeAttemptToFile();
203 return SECURITY_SERVER_API_SUCCESS;
206 int PasswordManager::setPasswordValidity(const unsigned int receivedDays)
208 unsigned int valid_secs = 0;
210 LogSecureDebug("received_days: " << receivedDays);
212 if (!m_pwdFile.isPasswordActive()) {
213 LogError("Current password is not active.");
214 return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
217 if(!calculateExpiredTime(receivedDays, valid_secs))
218 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
220 m_pwdFile.setExpireTime(valid_secs);
221 m_pwdFile.writeMemoryToFile();
223 return SECURITY_SERVER_API_SUCCESS;
226 int PasswordManager::resetPassword(const std::string &newPassword,
227 const unsigned int receivedAttempts,
228 const unsigned int receivedDays)
230 unsigned int valid_secs = 0;
232 if(!calculateExpiredTime(receivedDays, valid_secs))
233 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
235 m_pwdFile.setPassword(newPassword);
236 m_pwdFile.activatePassword();
237 m_pwdFile.setMaxAttempt(receivedAttempts);
238 m_pwdFile.setExpireTime(valid_secs);
239 m_pwdFile.writeMemoryToFile();
241 m_pwdFile.resetAttempt();
242 m_pwdFile.writeAttemptToFile();
244 return SECURITY_SERVER_API_SUCCESS;
247 int PasswordManager::setPasswordHistory(const unsigned int history)
249 if(history > MAX_PASSWORD_HISTORY) {
250 LogError("Incorrect input param.");
251 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
254 m_pwdFile.setMaxHistorySize(history);
255 m_pwdFile.writeMemoryToFile();
257 return SECURITY_SERVER_API_SUCCESS;
260 int PasswordManager::setPasswordMaxChallenge(const unsigned int maxChallenge)
262 // check if there is password
263 if (!m_pwdFile.isPasswordActive()) {
264 LogError("Password not active.");
265 return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
268 m_pwdFile.setMaxAttempt(maxChallenge);
269 m_pwdFile.writeMemoryToFile();
271 m_pwdFile.resetAttempt();
272 m_pwdFile.writeAttemptToFile();
274 return SECURITY_SERVER_API_SUCCESS;
276 } //namespace SecurityServer