Remove retry timeout check
[platform/core/security/security-server.git] / src / server / service / password-manager.cpp
1 /*
2  *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Bumjin Im <bj.im@samsung.com>
5  *
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
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
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
17  */
18 /*
19  * @file        password-manager.cpp
20  * @author      Zbigniew Jasinski (z.jasinski@samsung.com)
21  * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
22  * @version     1.0
23  * @brief       Implementation of password management functions
24  */
25
26 #include <password-manager.h>
27
28 #include <iostream>
29 #include <iterator>
30 #include <algorithm>
31
32 #include <limits.h>
33
34 #include <dpl/log/log.h>
35
36 #include <protocols.h>
37
38 #include <security-server.h>
39
40 namespace {
41     bool calculateExpiredTime(unsigned int receivedDays, unsigned int &validSecs)
42     {
43         validSecs = SecurityServer::PASSWORD_INFINITE_EXPIRATION_TIME;
44
45         //when receivedDays means infinite expiration, return default validSecs value.
46         if(receivedDays == SecurityServer::PASSWORD_INFINITE_EXPIRATION_DAYS)
47             return true;
48
49         time_t curTime = time(NULL);
50
51         if (receivedDays > ((UINT_MAX - curTime) / 86400)) {
52             LogError("Incorrect input param.");
53             return false;
54         } else {
55             validSecs = (curTime + (receivedDays * 86400));
56             return true;
57         }
58     }
59 } //namespace
60
61 namespace SecurityServer
62 {
63     int PasswordManager::isPwdValid(unsigned int &currentAttempt, unsigned int &maxAttempt,
64                                     unsigned int &expirationTime) const
65     {
66         if (!m_pwdFile.isPasswordActive()) {
67             LogError("Current password not active.");
68             return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
69         } else {
70             currentAttempt = m_pwdFile.getAttempt();
71             maxAttempt = m_pwdFile.getMaxAttempt();
72             expirationTime = m_pwdFile.getExpireTimeLeft();
73
74             return SECURITY_SERVER_API_ERROR_PASSWORD_EXIST;
75         }
76
77         return SECURITY_SERVER_API_SUCCESS;
78     }
79
80     int PasswordManager::checkPassword(const std::string &challenge, unsigned int &currentAttempt,
81                                        unsigned int &maxAttempt, unsigned int &expirationTime)
82     {
83         LogSecureDebug("Inside checkPassword function.");
84
85         if (m_pwdFile.isIgnorePeriod()) {
86             LogError("Retry timeout occurred.");
87             return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
88         }
89
90         if (!m_pwdFile.isPasswordActive()) {
91             LogError("Password not active.");
92             return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
93         }
94
95         m_pwdFile.incrementAttempt();
96         m_pwdFile.writeAttemptToFile();
97
98         currentAttempt = m_pwdFile.getAttempt();
99         maxAttempt = m_pwdFile.getMaxAttempt();
100         expirationTime = m_pwdFile.getExpireTimeLeft();
101
102         if (m_pwdFile.checkIfAttemptsExceeded()) {
103             LogError("Too many tries.");
104             return SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
105         }
106
107         if (!m_pwdFile.checkPassword(challenge)) {
108             LogError("Wrong password.");
109             return SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH;
110         }
111
112         if (m_pwdFile.checkExpiration()) {
113             LogError("Password expired.");
114             return SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED;
115         }
116
117         m_pwdFile.resetAttempt();
118         m_pwdFile.writeAttemptToFile();
119
120         return SECURITY_SERVER_API_SUCCESS;
121     }
122
123     int PasswordManager::setPassword(const std::string &currentPassword,
124                                      const std::string &newPassword,
125                                      const unsigned int receivedAttempts,
126                                      const unsigned int receivedDays)
127     {
128         LogSecureDebug("Curpwd = " << currentPassword << ", newpwd = " << newPassword <<
129                        ", recatt = " << receivedAttempts << ", recdays = " << receivedDays);
130
131         unsigned int valid_secs = 0;
132
133         if (m_pwdFile.isIgnorePeriod()) {
134             LogError("Retry timeout occured.");
135             return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
136         }
137
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;
142         }
143
144         if (newPassword.size() > MAX_PASSWORD_LEN) {
145             LogError("New password length failed.");
146             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
147         }
148
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;
154         }
155
156         //increment attempt count before checking it against max attempt count
157         m_pwdFile.incrementAttempt();
158         m_pwdFile.writeAttemptToFile();
159
160         // check attempt
161         if (m_pwdFile.checkIfAttemptsExceeded()) {
162             LogError("Too many attempts.");
163             return SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
164         }
165
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;
171             }
172         }
173
174         //check if password expired
175         if (m_pwdFile.checkExpiration()) {
176             LogError("Password expired.");
177             return SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED;
178         }
179
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;
185             }
186         }
187
188         if(!calculateExpiredTime(receivedDays, valid_secs)) {
189             LogError("Received expiration time incorrect.");
190             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
191         }
192
193         //setting password
194         m_pwdFile.setPassword(newPassword);
195         m_pwdFile.activatePassword();
196         m_pwdFile.setMaxAttempt(receivedAttempts);
197         m_pwdFile.setExpireTime(valid_secs);
198         m_pwdFile.writeMemoryToFile();
199
200         m_pwdFile.resetAttempt();
201         m_pwdFile.writeAttemptToFile();
202
203         return SECURITY_SERVER_API_SUCCESS;
204     }
205
206     int PasswordManager::setPasswordValidity(const unsigned int receivedDays)
207     {
208         unsigned int valid_secs = 0;
209
210         LogSecureDebug("received_days: " << receivedDays);
211
212         if (!m_pwdFile.isPasswordActive()) {
213             LogError("Current password is not active.");
214             return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
215         }
216
217         if(!calculateExpiredTime(receivedDays, valid_secs))
218             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
219
220         m_pwdFile.setExpireTime(valid_secs);
221         m_pwdFile.writeMemoryToFile();
222
223         return SECURITY_SERVER_API_SUCCESS;
224     }
225
226     int PasswordManager::resetPassword(const std::string &newPassword,
227                                        const unsigned int receivedAttempts,
228                                        const unsigned int receivedDays)
229     {
230         unsigned int valid_secs = 0;
231
232         if(!calculateExpiredTime(receivedDays, valid_secs))
233             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
234
235         m_pwdFile.setPassword(newPassword);
236         m_pwdFile.activatePassword();
237         m_pwdFile.setMaxAttempt(receivedAttempts);
238         m_pwdFile.setExpireTime(valid_secs);
239         m_pwdFile.writeMemoryToFile();
240
241         m_pwdFile.resetAttempt();
242         m_pwdFile.writeAttemptToFile();
243
244         return SECURITY_SERVER_API_SUCCESS;
245     }
246
247     int PasswordManager::setPasswordHistory(const unsigned int history)
248     {
249         if(history > MAX_PASSWORD_HISTORY) {
250             LogError("Incorrect input param.");
251             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
252         }
253
254         m_pwdFile.setMaxHistorySize(history);
255         m_pwdFile.writeMemoryToFile();
256
257         return SECURITY_SERVER_API_SUCCESS;
258     }
259
260     int PasswordManager::setPasswordMaxChallenge(const unsigned int maxChallenge)
261     {
262         // check if there is password
263         if (!m_pwdFile.isPasswordActive()) {
264             LogError("Password not active.");
265             return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
266         }
267
268         m_pwdFile.setMaxAttempt(maxChallenge);
269         m_pwdFile.writeMemoryToFile();
270
271         m_pwdFile.resetAttempt();
272         m_pwdFile.writeAttemptToFile();
273
274         return SECURITY_SERVER_API_SUCCESS;
275     }
276 } //namespace SecurityServer