[UI]Lockscreen for RSA
[apps/core/preloaded/lockscreen.git] / src / password-verification.c
1 /*\r
2  * Copyright 2012  Samsung Electronics Co., Ltd\r
3  *\r
4  * Licensed under the Flora License, Version 1.0 (the License);\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *  http://www.tizenopensource.org/license\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an AS IS BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 #include <Elementary.h>\r
18 #include <sys/types.h>\r
19 #include <unistd.h>\r
20 #include <security-server.h>\r
21 #include <mdm.h>\r
22 #include <vconf.h>\r
23 #include <vconf-keys.h>\r
24 \r
25 #include "log.h"\r
26 #include "password-verification.h"\r
27 \r
28 typedef enum {\r
29         NORMAL_PASSWORD = 0,\r
30         EMPTY_PASSWORD,\r
31         OVERLENGTH_PASSWORD,\r
32 }lockscreen_password_type;\r
33 \r
34 typedef struct {\r
35         unsigned int current_attempt;\r
36         unsigned int max_attempt;\r
37         unsigned int expire_sec;\r
38         int recoverable;\r
39         int mdm_quality;\r
40         password_operation_cb callback;\r
41         void *data;\r
42 } lockscreen_password_policy;\r
43 \r
44 static Eina_Bool __password_verification_check_pw_expired(void *data)\r
45 {\r
46         lockscreen_password_policy *password_policy = (lockscreen_password_policy *)data;\r
47         if (!password_policy) {\r
48                 return EINA_FALSE;\r
49         }\r
50 \r
51         LOCK_SCREEN_TRACE_DBG("Checking pw expired => valid_secs:%d:%d", password_policy->expire_sec);\r
52 \r
53         if (password_policy->expire_sec == 0) {\r
54                 return EINA_TRUE;\r
55         } else\r
56                 return EINA_FALSE;\r
57 }\r
58 \r
59 static Eina_Bool __password_verification_check_recovery(void *data)\r
60 {\r
61         lockscreen_password_policy *password_policy = (lockscreen_password_policy *)data;\r
62         if (!password_policy) {\r
63                 return EINA_FALSE;\r
64         }\r
65 \r
66         LOCK_SCREEN_TRACE_DBG("Checking recovery => current_attempt:%d max_attempt:%d",\r
67                 password_policy->current_attempt, password_policy->max_attempt);\r
68 \r
69         if ((password_policy->max_attempt != 0) && (password_policy->max_attempt == password_policy->current_attempt))  {\r
70                 password_policy->recoverable = 1;\r
71                 return EINA_TRUE;\r
72         } else\r
73                 return EINA_FALSE;\r
74 }\r
75 \r
76 static Eina_Bool __password_verification_check_phone_password(void *data, const char *str)\r
77 {\r
78         LOCK_SCREEN_TRACE_DBG("%s : %s\n", __FUNCTION__, str);\r
79 \r
80         lockscreen_password_policy *lock_policy = (lockscreen_password_policy *)data;\r
81 \r
82         int ret = SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH;\r
83 \r
84         unsigned int current_attempt = 0;\r
85         unsigned int max_attempt = 0;\r
86         unsigned int valid_secs = 0;\r
87 \r
88         if(!lock_policy) {\r
89                 LOCK_SCREEN_TRACE_DBG("lock_policy is NULL");\r
90                 return EINA_FALSE;\r
91         }\r
92 \r
93         ret = security_server_chk_pwd(str, &current_attempt, &max_attempt, &valid_secs);\r
94         LOCK_SCREEN_TRACE_DBG("security_server_chk_pwd => ret:%d current_attempt:%d max_attempt:%d valid_secs:%d",\r
95                 ret, current_attempt, max_attempt, valid_secs);\r
96         lock_policy->current_attempt = current_attempt;\r
97         lock_policy->max_attempt = max_attempt;\r
98         lock_policy->expire_sec = valid_secs;\r
99         if ((ret == SECURITY_SERVER_API_SUCCESS) || (ret == SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED)) {\r
100                 LOCK_SCREEN_TRACE_DBG("correct password!");\r
101                 return EINA_TRUE;\r
102         } else {\r
103                 LOCK_SCREEN_TRACE_DBG("incorrect password!");\r
104                 return EINA_FALSE;\r
105         }\r
106 }\r
107 \r
108 static lockscreen_password_type __password_verification_check_length(const char *str, int min, int max)\r
109 {\r
110         int len = 0;\r
111 \r
112         if (!str) {\r
113                 return EMPTY_PASSWORD;\r
114         }\r
115 \r
116         len = strlen(str);\r
117 \r
118         LOCK_SCREEN_TRACE_DBG("%s() len : %d", __FUNCTION__, len);\r
119 \r
120         if (len == 0) {\r
121                 return EMPTY_PASSWORD;\r
122         }\r
123 \r
124         if (len < min || len > max) {\r
125                 return OVERLENGTH_PASSWORD;\r
126         }\r
127 \r
128         return NORMAL_PASSWORD;\r
129 }\r
130 \r
131 static void __password_verification_set_expired_password_by_mdm(void *data)\r
132 {\r
133         lockscreen_password_policy *password_policy = (lockscreen_password_policy *)data;\r
134 \r
135         if(!password_policy) {\r
136                 LOCK_SCREEN_TRACE_DBG("lock_policy is NULL");\r
137                 return;\r
138         }\r
139 \r
140         if(mdm_get_service() == MDM_RESULT_SUCCESS) {\r
141                 LOCK_SCREEN_TRACE_DBG("success to connect mdm server..!!");\r
142                 if (mdm_enforce_password_change() == MDM_RESULT_SUCCESS) {\r
143                         LOCK_SCREEN_TRACE_DBG("success to call mdm_enforce_password_change..!!");\r
144                 } else {\r
145                         LOCK_SCREEN_TRACE_DBG("[ERROR] failed to call mdm_enforce_password_change..!!");\r
146                 }\r
147 \r
148                 if (mdm_set_password_status(MDM_PASSWORD_EXPIRED) == MDM_RESULT_SUCCESS) {\r
149                         LOCK_SCREEN_TRACE_DBG("success to set MDM_PASSWORD_EXPIRED..!!");\r
150                 } else {\r
151                         LOCK_SCREEN_TRACE_DBG("[ERROR] failed to set MDM_PASSWORD_EXPIRED..!!");\r
152                 }\r
153                 mdm_release_service();\r
154         } else {\r
155                 LOCK_SCREEN_TRACE_DBG("[ERROR] failed to connect mdm server");\r
156         }\r
157 }\r
158 \r
159 static void __password_verification_recorver_password_by_mdm(void *data)\r
160 {\r
161         lockscreen_password_policy *password_policy = (lockscreen_password_policy *)data;\r
162 \r
163         if(!password_policy) {\r
164                 LOCK_SCREEN_TRACE_DBG("lock_policy is NULL");\r
165                 return;\r
166         }\r
167 \r
168         if(mdm_get_service() == MDM_RESULT_SUCCESS) {\r
169                 LOCK_SCREEN_TRACE_DBG("success to connect mdm server..!!");\r
170                 mdm_data_t * lp_data = NULL;\r
171                 mdm_password_policy_t *pwd_info = NULL;\r
172                 lp_data = mdm_get_password_policy();\r
173                 if (lp_data != NULL) {\r
174                         pwd_info = (mdm_password_policy_t *)lp_data->data;\r
175                         password_policy->mdm_quality = pwd_info->quality;\r
176                         LOCK_SCREEN_TRACE_DBG("mdm quality : %d", password_policy->mdm_quality);\r
177                         lp_data->mem_header.free_func(lp_data);\r
178                 } else {\r
179                         LOCK_SCREEN_TRACE_DBG("set password policy fail");\r
180                 }\r
181                 if (password_policy->mdm_quality != MDM_PASSWORD_QUALITY_UNSPECIFIED) {\r
182                         if (mdm_set_password_status(MDM_PASSWORD_FAILED) == MDM_RESULT_SUCCESS) {\r
183                                 LOCK_SCREEN_TRACE_DBG("success to set MDM_PASSWORD_FAILED..!!");\r
184                         } else {\r
185                                 LOCK_SCREEN_TRACE_DBG("[ERROR] failed to set MDM_PASSWORD_FAILED..!!");\r
186                         }\r
187                 }\r
188                 mdm_release_service();\r
189         }else {\r
190                 LOCK_SCREEN_TRACE_DBG("[ERROR] failed to connect mdm server");\r
191         }\r
192 }\r
193 \r
194 void *password_verification_policy_create()\r
195 {\r
196         lockscreen_password_policy *password_policy = NULL;\r
197         int ret = 0;\r
198         unsigned int cur_attempt = 0;\r
199         unsigned int max_attempt = 0;\r
200         unsigned int expire_sec = 0;\r
201 \r
202         password_policy = (lockscreen_password_policy *) calloc(1, sizeof(lockscreen_password_policy));\r
203 \r
204         if (!password_policy){\r
205                 return NULL;\r
206         }\r
207 \r
208         password_policy->mdm_quality = MDM_PASSWORD_QUALITY_UNSPECIFIED;\r
209 \r
210         ret = security_server_is_pwd_valid(&cur_attempt, &max_attempt, &expire_sec);\r
211         LOCK_SCREEN_TRACE_DBG("policy status:%d, cur_attempt:%d, max_attempt:%d ", ret, cur_attempt, max_attempt);\r
212 \r
213         if(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD) {\r
214                 password_policy->current_attempt = cur_attempt;\r
215                 password_policy->max_attempt = max_attempt;\r
216                 password_policy->recoverable = EINA_FALSE;\r
217                 password_policy->expire_sec = expire_sec;\r
218         }\r
219 \r
220         return password_policy;\r
221 }\r
222 \r
223 void password_verification_policy_destroy(void *data)\r
224 {\r
225         lockscreen_password_policy *password_policy = (lockscreen_password_policy *)data;\r
226 \r
227         if (!password_policy){\r
228                 return;\r
229         }\r
230 \r
231         free(password_policy);\r
232         password_policy = NULL;\r
233 }\r
234 \r
235 void password_verification_verify(void *data, const char *password)\r
236 {\r
237         lockscreen_password_type password_type = NORMAL_PASSWORD;\r
238         lockscreen_password_policy *password_policy = (lockscreen_password_policy *)data;\r
239 \r
240         if(!password_policy) {\r
241                 LOCK_SCREEN_TRACE_DBG("lock_policy is NULL");\r
242                 return;\r
243         }\r
244         password_type = __password_verification_check_length(password, 4, 16);\r
245         switch(password_type){\r
246                 case NORMAL_PASSWORD:\r
247                         if (__password_verification_check_phone_password(password_policy, password)) {\r
248                                 if ( __password_verification_check_pw_expired(password_policy)) {\r
249                                         __password_verification_set_expired_password_by_mdm(password_policy);\r
250                                 }\r
251                                 LOCK_SCREEN_TRACE_DBG("password is right!!!!");\r
252                                 elm_exit();\r
253                         } else {\r
254                                 if (__password_verification_check_recovery (password_policy)) {\r
255                                         LOCK_SCREEN_TRACE_DBG("Recovery lock mode..!!");\r
256                                         __password_verification_recorver_password_by_mdm(password_policy);\r
257                                 }\r
258                                 if(password_policy->callback){\r
259                                         password_policy->callback("", password_policy->data);\r
260                                 }\r
261                         }\r
262                         break;\r
263                 case EMPTY_PASSWORD:\r
264                         password_policy->callback("empty", password_policy->data);\r
265                         break;\r
266                 case OVERLENGTH_PASSWORD:\r
267                         password_policy->callback("overlength", password_policy->data);\r
268                         break;\r
269         }\r
270 }\r
271 \r
272 void password_verification_callback_set(void *data, password_operation_cb callback, void *priv)\r
273 {\r
274         lockscreen_password_policy *password_policy = (lockscreen_password_policy *)data;\r
275 \r
276         if (!password_policy){\r
277                 return;\r
278         }\r
279 \r
280         password_policy->callback = callback;\r
281         password_policy->data = priv;\r
282 }\r