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)
48 time_t curTime = time(NULL);
50 if (receivedDays > ((UINT_MAX - curTime) / 86400)) {
51 LogError("Incorrect input param.");
54 validSecs = (curTime + (receivedDays * 86400));
58 //when receivedDays equal to zero, it means infinite password valid time
59 //if receivedDays is 0 return true, else return false (that is, an error)
64 namespace SecurityServer
66 int PasswordManager::isPwdValid(unsigned int ¤tAttempt, unsigned int &maxAttempt,
67 unsigned int &expirationTime) const
69 if (m_pwdFile.isIgnorePeriod()) {
70 LogError("Retry timeout occured.");
71 return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
74 if (!m_pwdFile.isPasswordActive()) {
75 LogError("Current password not active.");
76 return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
78 currentAttempt = m_pwdFile.getAttempt();
79 maxAttempt = m_pwdFile.getMaxAttempt();
80 expirationTime = m_pwdFile.getExpireTimeLeft();
82 return SECURITY_SERVER_API_ERROR_PASSWORD_EXIST;
85 return SECURITY_SERVER_API_SUCCESS;
88 int PasswordManager::checkPassword(const std::string &challenge, unsigned int ¤tAttempt,
89 unsigned int &maxAttempt, unsigned int &expirationTime)
91 LogSecureDebug("Inside checkPassword function.");
93 if (m_pwdFile.isIgnorePeriod()) {
94 LogError("Retry timeout occurred.");
95 return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
98 if (!m_pwdFile.isPasswordActive()) {
99 LogError("Password not active.");
100 return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
103 currentAttempt = m_pwdFile.getAttempt();
104 maxAttempt = m_pwdFile.getMaxAttempt();
105 expirationTime = m_pwdFile.getExpireTimeLeft();
107 if ((maxAttempt != 0) && (currentAttempt >= maxAttempt)) {
108 LogError("Too many tries.");
109 return SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
112 m_pwdFile.incrementAttempt();
113 m_pwdFile.writeAttemptToFile();
115 if (!m_pwdFile.checkPassword(challenge)) {
116 LogError("Wrong password.");
117 return SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH;
120 if (m_pwdFile.checkExpiration()) {
121 LogError("Password expired.");
122 return SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED;
125 m_pwdFile.resetAttempt();
126 m_pwdFile.writeAttemptToFile();
128 return SECURITY_SERVER_API_SUCCESS;
131 int PasswordManager::setPassword(const std::string ¤tPassword,
132 const std::string &newPassword,
133 const unsigned int receivedAttempts,
134 const unsigned int receivedDays)
136 LogSecureDebug("Curpwd = " << currentPassword << ", newpwd = " << newPassword <<
137 ", recatt = " << receivedAttempts << ", recdays = " << receivedDays);
139 unsigned int valid_secs = 0;
142 if (m_pwdFile.isIgnorePeriod()) {
143 LogError("Retry timeout occured.");
144 return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
147 //check if passwords are correct
148 if (currentPassword.size() > MAX_PASSWORD_LEN) {
149 LogError("Current password length failed.");
150 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
153 if (newPassword.size() > MAX_PASSWORD_LEN) {
154 LogError("New password length failed.");
155 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
158 //check delivered currentPassword
159 //when m_passwordActive flag is true, currentPassword shouldn't be empty
160 if (currentPassword.empty() && m_pwdFile.isPasswordActive()) {
161 LogError("Password is already set.");
162 return SECURITY_SERVER_API_ERROR_PASSWORD_EXIST;
166 unsigned int maxAttempt = m_pwdFile.getMaxAttempt();
167 if ((maxAttempt != 0) && (m_pwdFile.getAttempt() >= maxAttempt)) {
168 LogError("Too many attempts.");
169 return SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
172 //if we didn't exceed max attempts, increment attempt count and save it to separate file
173 m_pwdFile.incrementAttempt();
174 m_pwdFile.writeAttemptToFile();
176 //check current password, however only when we don't send empty string as current.
177 if(!currentPassword.empty()) {
178 if(!m_pwdFile.checkPassword(currentPassword)) {
179 LogError("Wrong password.");
180 return SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH;
184 //check if password expired
185 if (m_pwdFile.checkExpiration()) {
186 LogError("Password expired.");
187 return SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED;
191 if (m_pwdFile.isPasswordActive()) {
192 if (m_pwdFile.isPasswordReused(newPassword)) {
193 LogError("Password reused.");
194 return SECURITY_SERVER_API_ERROR_PASSWORD_REUSED;
198 if(!calculateExpiredTime(receivedDays, valid_secs)) {
199 LogError("Received expiration time incorrect.");
200 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
204 m_pwdFile.setPassword(newPassword);
205 m_pwdFile.setMaxAttempt(receivedAttempts);
206 m_pwdFile.setExpireTime(valid_secs);
207 m_pwdFile.writeMemoryToFile();
209 m_pwdFile.resetAttempt();
210 m_pwdFile.writeAttemptToFile();
212 return SECURITY_SERVER_API_SUCCESS;
215 int PasswordManager::setPasswordValidity(const unsigned int receivedDays)
217 unsigned int valid_secs = 0;
219 LogSecureDebug("received_days: " << receivedDays);
221 if (!m_pwdFile.isPasswordActive()) {
222 LogError("Current password is not active.");
223 return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
226 if(!calculateExpiredTime(receivedDays, valid_secs))
227 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
229 m_pwdFile.setExpireTime(valid_secs);
230 m_pwdFile.writeMemoryToFile();
232 return SECURITY_SERVER_API_SUCCESS;
235 int PasswordManager::resetPassword(const std::string &newPassword,
236 const unsigned int receivedAttempts,
237 const unsigned int receivedDays)
239 unsigned int valid_secs = 0;
241 if (m_pwdFile.isIgnorePeriod()) {
242 LogError("Retry timeout occured.");
243 return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
246 if(!calculateExpiredTime(receivedDays, valid_secs))
247 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
249 m_pwdFile.setPassword(newPassword);
250 m_pwdFile.setMaxAttempt(receivedAttempts);
251 m_pwdFile.setExpireTime(valid_secs);
252 m_pwdFile.writeMemoryToFile();
254 m_pwdFile.resetAttempt();
255 m_pwdFile.writeAttemptToFile();
257 return SECURITY_SERVER_API_SUCCESS;
260 int PasswordManager::setPasswordHistory(const unsigned int history)
262 if(history > MAX_PASSWORD_HISTORY) {
263 LogError("Incorrect input param.");
264 return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
268 if (m_pwdFile.isIgnorePeriod()) {
269 LogError("Retry timeout occurred.");
270 return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
273 m_pwdFile.setHistory(history);
274 m_pwdFile.writeMemoryToFile();
276 return SECURITY_SERVER_API_SUCCESS;
279 int PasswordManager::setPasswordMaxChallenge(const unsigned int maxChallenge)
281 // check if there is password
282 if (!m_pwdFile.isPasswordActive()) {
283 LogError("Password not active.");
284 return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
287 m_pwdFile.setMaxAttempt(maxChallenge);
288 m_pwdFile.writeMemoryToFile();
290 m_pwdFile.resetAttempt();
291 m_pwdFile.writeAttemptToFile();
293 return SECURITY_SERVER_API_SUCCESS;
295 } //namespace SecurityServer