Fix isPwdValid. Correct logs. Change history related function names.
[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.isIgnorePeriod()) {
67             LogError("Retry timeout occured.");
68             return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
69         }
70
71         if (!m_pwdFile.isPasswordActive()) {
72             LogError("Current password not active.");
73             return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
74         } else {
75             currentAttempt = m_pwdFile.getAttempt();
76             maxAttempt = m_pwdFile.getMaxAttempt();
77             expirationTime = m_pwdFile.getExpireTimeLeft();
78
79             return SECURITY_SERVER_API_ERROR_PASSWORD_EXIST;
80         }
81
82         return SECURITY_SERVER_API_SUCCESS;
83     }
84
85     int PasswordManager::checkPassword(const std::string &challenge, unsigned int &currentAttempt,
86                                        unsigned int &maxAttempt, unsigned int &expirationTime)
87     {
88         LogSecureDebug("Inside checkPassword function.");
89
90         if (m_pwdFile.isIgnorePeriod()) {
91             LogError("Retry timeout occurred.");
92             return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
93         }
94
95         if (!m_pwdFile.isPasswordActive()) {
96             LogError("Password not active.");
97             return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
98         }
99
100         m_pwdFile.incrementAttempt();
101         m_pwdFile.writeAttemptToFile();
102
103         currentAttempt = m_pwdFile.getAttempt();
104         maxAttempt = m_pwdFile.getMaxAttempt();
105         expirationTime = m_pwdFile.getExpireTimeLeft();
106
107         if (m_pwdFile.checkIfAttemptsExceeded()) {
108             LogError("Too many tries.");
109             return SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
110         }
111
112         if (!m_pwdFile.checkPassword(challenge)) {
113             LogError("Wrong password.");
114             return SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH;
115         }
116
117         if (m_pwdFile.checkExpiration()) {
118             LogError("Password expired.");
119             return SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED;
120         }
121
122         m_pwdFile.resetAttempt();
123         m_pwdFile.writeAttemptToFile();
124
125         return SECURITY_SERVER_API_SUCCESS;
126     }
127
128     int PasswordManager::setPassword(const std::string &currentPassword,
129                                      const std::string &newPassword,
130                                      const unsigned int receivedAttempts,
131                                      const unsigned int receivedDays)
132     {
133         LogSecureDebug("Curpwd = " << currentPassword << ", newpwd = " << newPassword <<
134                        ", recatt = " << receivedAttempts << ", recdays = " << receivedDays);
135
136         unsigned int valid_secs = 0;
137
138         //check retry timer
139         if (m_pwdFile.isIgnorePeriod()) {
140             LogError("Retry timeout occured.");
141             return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
142         }
143
144         //check if passwords are correct
145         if (currentPassword.size() > MAX_PASSWORD_LEN) {
146             LogError("Current password length failed.");
147             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
148         }
149
150         if (newPassword.size() > MAX_PASSWORD_LEN) {
151             LogError("New password length failed.");
152             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
153         }
154
155         //check delivered currentPassword
156         //when m_passwordActive flag is true, currentPassword shouldn't be empty
157         if (currentPassword.empty() && m_pwdFile.isPasswordActive()) {
158             LogError("Password is already set. Max history: " << m_pwdFile.getMaxHistorySize());
159             return SECURITY_SERVER_API_ERROR_PASSWORD_EXIST;
160         }
161
162         //increment attempt count before checking it against max attempt count
163         m_pwdFile.incrementAttempt();
164         m_pwdFile.writeAttemptToFile();
165
166         // check attempt
167         if (m_pwdFile.checkIfAttemptsExceeded()) {
168             LogError("Too many attempts.");
169             return SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
170         }
171
172         //check current password, however only when we don't send empty string as current.
173         if(!currentPassword.empty()) {
174             if(!m_pwdFile.checkPassword(currentPassword)) {
175                 LogError("Wrong password.");
176                 return SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH;
177             }
178         }
179
180         //check if password expired
181         if (m_pwdFile.checkExpiration()) {
182             LogError("Password expired.");
183             return SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED;
184         }
185
186         //check history, however only if history is active
187         if (m_pwdFile.isPasswordActive() && m_pwdFile.isHistoryActive()) {
188             if (m_pwdFile.isPasswordReused(newPassword)) {
189                 LogError("Password reused.");
190                 return SECURITY_SERVER_API_ERROR_PASSWORD_REUSED;
191             }
192         }
193
194         if(!calculateExpiredTime(receivedDays, valid_secs)) {
195             LogError("Received expiration time incorrect.");
196             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
197         }
198
199         //setting password
200         m_pwdFile.setPassword(newPassword);
201         m_pwdFile.activatePassword();
202         m_pwdFile.setMaxAttempt(receivedAttempts);
203         m_pwdFile.setExpireTime(valid_secs);
204         m_pwdFile.writeMemoryToFile();
205
206         m_pwdFile.resetAttempt();
207         m_pwdFile.writeAttemptToFile();
208
209         return SECURITY_SERVER_API_SUCCESS;
210     }
211
212     int PasswordManager::setPasswordValidity(const unsigned int receivedDays)
213     {
214         unsigned int valid_secs = 0;
215
216         LogSecureDebug("received_days: " << receivedDays);
217
218         if (!m_pwdFile.isPasswordActive()) {
219             LogError("Current password is not active.");
220             return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
221         }
222
223         if(!calculateExpiredTime(receivedDays, valid_secs))
224             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
225
226         m_pwdFile.setExpireTime(valid_secs);
227         m_pwdFile.writeMemoryToFile();
228
229         return SECURITY_SERVER_API_SUCCESS;
230     }
231
232     int PasswordManager::resetPassword(const std::string &newPassword,
233                                        const unsigned int receivedAttempts,
234                                        const unsigned int receivedDays)
235     {
236         unsigned int valid_secs = 0;
237
238         if (m_pwdFile.isIgnorePeriod()) {
239             LogError("Retry timeout occured.");
240             return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
241         }
242
243         if(!calculateExpiredTime(receivedDays, valid_secs))
244             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
245
246         m_pwdFile.setPassword(newPassword);
247         m_pwdFile.activatePassword();
248         m_pwdFile.setMaxAttempt(receivedAttempts);
249         m_pwdFile.setExpireTime(valid_secs);
250         m_pwdFile.writeMemoryToFile();
251
252         m_pwdFile.resetAttempt();
253         m_pwdFile.writeAttemptToFile();
254
255         return SECURITY_SERVER_API_SUCCESS;
256     }
257
258     int PasswordManager::setPasswordHistory(const unsigned int history)
259     {
260         if(history > MAX_PASSWORD_HISTORY) {
261             LogError("Incorrect input param.");
262             return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
263         }
264
265         // check retry time
266         if (m_pwdFile.isIgnorePeriod()) {
267             LogError("Retry timeout occurred.");
268             return SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER;
269         }
270
271         m_pwdFile.setMaxHistorySize(history);
272         m_pwdFile.writeMemoryToFile();
273
274         return SECURITY_SERVER_API_SUCCESS;
275     }
276
277     int PasswordManager::setPasswordMaxChallenge(const unsigned int maxChallenge)
278     {
279         // check if there is password
280         if (!m_pwdFile.isPasswordActive()) {
281             LogError("Password not active.");
282             return SECURITY_SERVER_API_ERROR_NO_PASSWORD;
283         }
284
285         m_pwdFile.setMaxAttempt(maxChallenge);
286         m_pwdFile.writeMemoryToFile();
287
288         m_pwdFile.resetAttempt();
289         m_pwdFile.writeAttemptToFile();
290
291         return SECURITY_SERVER_API_SUCCESS;
292     }
293 } //namespace SecurityServer