Removing unused code and separating deprecated files
[platform/core/security/security-manager.git] / src / server / security-server-password.c
1 /*
2  *  security-server
3  *
4  *  Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved
5  *
6  *  Contact: Bumjin Im <bj.im@samsung.com>
7  *
8  *  Licensed under the Apache License, Version 2.0 (the "License");
9  *  you may not use this file except in compliance with the License.
10  *  You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *  Unless required by applicable law or agreed to in writing, software
15  *  distributed under the License is distributed on an "AS IS" BASIS,
16  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  *  See the License for the specific language governing permissions and
18  *  limitations under the License
19  *
20  */
21
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <dirent.h>
26 #include <errno.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <fcntl.h>
30 #include <openssl/sha.h>
31
32 #include "security-server-password.h"
33
34 struct timeval prev_try;
35
36 void initiate_try()
37 {
38         gettimeofday(&prev_try, NULL);
39 }
40
41 int validate_pwd_file(char *filename)
42 {
43         int i;
44
45         if((strncmp(filename + (strlen(filename) -4), ".pwd" , 4)) != 0)
46         {
47                 SEC_SVR_DBG("The passwor filename [%s] is invalid", filename);
48                 return SECURITY_SERVER_ERROR_NO_PASSWORD;
49         }
50
51         for(i=0;i<(strlen(filename) -4);i++)
52         {
53                 if(filename[i] > '9' || filename[i] < '0')
54                 {
55                         SEC_SVR_DBG("The passwor filename [%s] is invalid", filename);
56                         return SECURITY_SERVER_ERROR_NO_PASSWORD;
57                 }
58         }
59         return SECURITY_SERVER_SUCCESS;
60 }
61
62 int dir_filter(const struct dirent *entry)
63 {
64         if ((strcmp(entry->d_name, ".") == 0) ||
65                 (strcmp(entry->d_name, "..") == 0) ||
66                 (strcmp(entry->d_name, "attempts") ==0) ||
67                 (strcmp(entry->d_name, "history") ==0) )
68                 return (0);
69         else
70                 return (1);
71 }
72
73 int get_pwd_path(char *path)
74 {
75         int retval;
76         struct dirent **mydirent;
77         int num;
78         num = scandir(SECURITY_SERVER_DATA_DIRECTORY_PATH, &mydirent, &dir_filter, alphasort);
79         if(num < 0)
80         {
81                 SEC_SVR_DBG("Server: [Error] Cannot scan password directory. errno: %d", errno);
82                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
83         }
84         if(num == 0)
85         {
86                 SEC_SVR_DBG("%s", "Server: There is no password file");
87                 return SECURITY_SERVER_ERROR_NO_PASSWORD;
88         }
89
90         snprintf(path, 255, "%s/%s", SECURITY_SERVER_DATA_DIRECTORY_PATH, mydirent[num-1]->d_name);
91         retval = validate_pwd_file(mydirent[num-1]->d_name);
92         if(retval != SECURITY_SERVER_SUCCESS)
93         {
94                 SEC_SVR_DBG("Removing invalid password file: %s", path);
95                 unlink(path);
96                 get_pwd_path(path);
97         }
98         SEC_SVR_DBG("Password file path: %s", path);
99         while (num--)
100                 free(mydirent[num]);
101         free(mydirent);
102         return SECURITY_SERVER_SUCCESS;
103 }
104
105 int load_password(unsigned char *cur_pwd, unsigned int *max_attempt, unsigned int *expire_time)
106 {
107         int retval, fd;
108         char pwd_path[255];
109
110         /* Create directory */
111         retval = mkdir(SECURITY_SERVER_DATA_DIRECTORY_PATH, 0700);
112         if(retval != 0)
113         {
114                 if(errno != EEXIST)
115                 {
116                         SEC_SVR_DBG("Cannot create directory. errno: %d", errno);
117                         return SECURITY_SERVER_ERROR_FILE_OPERATION;
118                 }
119         }
120
121         /* Check password files */
122         while(1)
123         {
124                 /* Get password file path */
125                 retval = get_pwd_path(pwd_path);
126                 if(retval == SECURITY_SERVER_ERROR_NO_PASSWORD)
127                 {
128                         SEC_SVR_DBG("%s", "Current password doesn't exist");
129                         return SECURITY_SERVER_ERROR_NO_PASSWORD;
130                 }
131
132                 /* Load password file */
133                 fd = open(pwd_path, O_RDONLY | O_NONBLOCK );
134                 if(fd < 0)
135                 {
136                         if(errno == ENOENT)
137                         {
138                                 SEC_SVR_DBG("%s", "Server: Current password doesn't exist");
139                                 return SECURITY_SERVER_ERROR_NO_PASSWORD;
140                         }
141                         SEC_SVR_DBG("Server: Current password cannot be opened. errno: %d", errno);
142                         return SECURITY_SERVER_ERROR_FILE_OPERATION;
143                 }
144
145                 /* Read and store into memory */
146                 retval = read(fd, cur_pwd, SECURITY_SERVER_HASHED_PWD_LEN);
147                 if(retval < SECURITY_SERVER_HASHED_PWD_LEN)
148                 {
149                         SEC_SVR_DBG("%s", "Server: Current password corrupted. resetting to previous one. 0");
150                         close(fd);
151                         fd = 0;
152                         unlink(pwd_path);
153                         continue;
154                 }
155
156                 retval = read(fd, max_attempt, sizeof(unsigned int));
157                 if(retval < sizeof(unsigned int))
158                 {
159                         SEC_SVR_DBG("%s", "Server: Current password corrupted. resetting to previous one. 1");
160                         close(fd);
161                         fd = 0;
162                         unlink(pwd_path);
163                         continue;
164                 }
165
166                 retval = read(fd, expire_time, sizeof(unsigned int));
167                 if(retval < sizeof(unsigned int))
168                 {
169                         SEC_SVR_DBG("%s", "Server: Current password corrupted. resetting to previous one. 2");
170                         close(fd);
171                         fd = 0;
172                         unlink(pwd_path);
173                         continue;
174                 }
175                 close(fd);
176
177                 /* Check expiration time. */
178                 if(*expire_time == 0)  /* No valid period */
179                         *expire_time = 0xffffffff;
180                 else if(*expire_time <= time(NULL)) /* expired */
181                         *expire_time =0;
182                 else            /* valid yet */
183                         *expire_time -= time(NULL);
184                 break;
185         }
186         SEC_SVR_DBG("%s", "Server: Current password file successfully loaded");
187         return SECURITY_SERVER_SUCCESS;
188 }
189
190 int get_current_attempt(int increase)
191 {
192         int retval, fd, attempt;
193         char path[255];
194
195         snprintf(path, 255, "%s/%s", SECURITY_SERVER_DATA_DIRECTORY_PATH,
196                 SECURITY_SERVER_ATTEMPT_FILE_NAME);
197
198         /* Open current attempt file as read mode */
199         fd = open(path, O_RDONLY | O_NONBLOCK );
200         if(fd < 0)
201         {
202                 if(errno == ENOENT)
203                 {
204                         SEC_SVR_DBG("%s", "Server: attempt doesn't exist. Creating one:");
205                         /* Create one if it doesn't exist */
206                         fd = open(path, O_WRONLY | O_NONBLOCK | O_CREAT, 0600);
207                         if(fd < 0)
208                         {
209                                 SEC_SVR_DBG("Server ERROR: Cannot open attempt file. errno: %d", errno);
210                                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
211                         }
212                         retval = fchmod(fd, 0600);
213                         if(retval != 0)
214                         {
215                                 SEC_SVR_DBG("Server ERROR: Cannot chmod attempt file. errno: %d", errno);
216                                 close(fd);
217                                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
218                         }
219                         attempt = increase;
220                         retval = write(fd, &attempt, sizeof(int));
221                         close(fd);
222                         if(retval < sizeof(int))
223                         {
224                                 SEC_SVR_DBG("%s", "Server ERROR: Cannot write attempt");
225                                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
226                         }
227                         return attempt;
228                 }
229                 SEC_SVR_DBG("Current password cannot be opened. errno: %d", errno);
230                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
231         }
232         retval = read(fd, &attempt, sizeof(int));
233         close(fd);
234         if(retval < sizeof(int))
235         {
236                 SEC_SVR_DBG("%s", "Server ERROR: Cannot read attempt");
237                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
238         }
239
240         if(increase > 0)
241         {
242                 /* Open the file again with write mode */
243                 fd = open(path, O_WRONLY | O_NONBLOCK, 0600);
244                 if(fd < 0)
245                 {
246                         SEC_SVR_DBG("Server ERROR: Cannot open attempt file. errno: %d", errno);
247                         return SECURITY_SERVER_ERROR_FILE_OPERATION;
248                 }
249                 retval = fchmod(fd, 0600);
250                 if(retval != 0)
251                 {
252                         SEC_SVR_DBG("Server ERROR: Cannot chmod attempt file. errno: %d", errno);
253                         close(fd);
254                         return SECURITY_SERVER_ERROR_FILE_OPERATION;
255                 }
256                 attempt += increase;
257                 retval = write(fd, &attempt, sizeof(int));
258                 close(fd);
259                 if(retval < sizeof(int))
260                 {
261                         SEC_SVR_DBG("%s", "Server ERROR: Cannot write attempt");
262                         return SECURITY_SERVER_ERROR_FILE_OPERATION;
263                 }
264         }
265         return attempt;
266 }
267
268 int reset_attempt(void)
269 {
270         int fd, retval;
271         char path[255];
272         unsigned int attempt = 0;
273
274         snprintf(path, 255, "%s/%s", SECURITY_SERVER_DATA_DIRECTORY_PATH,
275                 SECURITY_SERVER_ATTEMPT_FILE_NAME);
276
277         /* Open the file again with write mode */
278         fd = open(path, O_WRONLY | O_NONBLOCK, 0600);
279         if(fd < 0)
280         {
281                 SEC_SVR_DBG("Server ERROR: Cannot open attempt file. errno: %d", errno);
282                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
283         }
284         retval = fchmod(fd, 0600);
285         if(retval != 0)
286         {
287                 SEC_SVR_DBG("Server ERROR: Cannot chmod attempt file. errno: %d", errno);
288                 close(fd);
289                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
290         }
291         retval = write(fd, &attempt, sizeof(int));
292         close(fd);
293         if(retval < sizeof(int))
294         {
295                 SEC_SVR_DBG("%s", "Server ERROR: Cannot write attempt");
296                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
297         }
298         SEC_SVR_DBG("%s", "Server: Attempt reset");
299         return SECURITY_SERVER_SUCCESS;
300 }
301
302 /* Compare current password Stored password is hashed by SHA-256 Algorithm */
303 int check_password(const unsigned char *cur_pwd, const unsigned char *requested_pwd,
304                         const unsigned int max_attempts, const unsigned int expire_time,
305                         int *current_attempt)
306 {
307         unsigned int current_time = time(NULL);
308
309         if(max_attempts != 0)
310         {
311                 *current_attempt = get_current_attempt(1);
312
313                 if(*current_attempt > max_attempts)
314                 {
315                         SEC_SVR_DBG("Server: Max attempt exceeded: %d, %d", *current_attempt, max_attempts);
316                         return SECURITY_SERVER_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
317                 }
318                 if(*current_attempt < 0)
319                 {
320                         SEC_SVR_DBG("Server: Attempt file operation failed. Ignoring... : %d", *current_attempt);
321                 }
322         }
323
324         /* Compare */
325         if(memcmp(cur_pwd, requested_pwd, SECURITY_SERVER_HASHED_PWD_LEN) != 0)
326         {
327             SEC_SVR_DBG("%s", "Password mismatched");
328             return SECURITY_SERVER_ERROR_PASSWORD_MISMATCH;
329         }
330
331     if(expire_time == 0)
332     {
333         SEC_SVR_DBG("Server: Password has been expired: %d, %d", current_time, expire_time);
334         return SECURITY_SERVER_ERROR_PASSWORD_EXPIRED;
335     }
336
337     SEC_SVR_DBG("%s", "Password matched");
338     return SECURITY_SERVER_SUCCESS;
339 }
340
341 int set_history(int num)
342 {
343         int fd, retval;
344         char path[255];
345
346         snprintf(path, 255, "%s/%s", SECURITY_SERVER_DATA_DIRECTORY_PATH,
347                 SECURITY_SERVER_HISTORY_FILE_NAME);
348
349         /* Open the file again with write mode */
350         fd = open(path, O_WRONLY | O_NONBLOCK, 0600);
351         if(fd < 0)
352         {
353                 if (errno == ENOENT)
354                 {
355                         fd = open(path, O_WRONLY | O_NONBLOCK | O_CREAT, 0600);
356                         if(fd < 0)
357                         {
358                                 SEC_SVR_DBG("Server ERROR: Cannot create history file. errno: %d", errno);
359                                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
360                         }
361                 }
362                 else
363                 {
364                         SEC_SVR_DBG("Server ERROR: Cannot open history file. errno: %d", errno);
365                         return SECURITY_SERVER_ERROR_FILE_OPERATION;
366                 }
367         }
368         retval = fchmod(fd, 0600);
369         if(retval != 0)
370         {
371                 SEC_SVR_DBG("Server ERROR: Cannot chmod history file. errno: %d", errno);
372                 close(fd);
373                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
374         }
375         retval = write(fd, &num, sizeof(int));
376         close(fd);
377         if(retval < sizeof(int))
378         {
379                 SEC_SVR_DBG("%s", "Server ERROR: Cannot write history");
380                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
381         }
382         SEC_SVR_DBG("%s", "Server: history set finished");
383         return SECURITY_SERVER_SUCCESS;
384 }
385
386
387 int get_history_num(void)
388 {
389         /* Placeholder for password history check count getting function */
390         int fd, retval, history;
391         char path[255];
392
393         snprintf(path, 255, "%s/%s", SECURITY_SERVER_DATA_DIRECTORY_PATH,
394                 SECURITY_SERVER_HISTORY_FILE_NAME);
395
396         /* Load password file */
397         fd = open(path, O_RDONLY | O_NONBLOCK );
398         if(fd < 0)
399         {
400                 if(errno == ENOENT)
401                 {
402                         SEC_SVR_DBG("%s", "Server: history file doesn't exist");
403                         retval = set_history(0);
404                         return retval;
405                 }
406                 SEC_SVR_DBG("Server ERROR: history file cannot be opened. errno: %d", errno);
407                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
408         }
409         retval = read(fd, &history, sizeof(history));
410         close(fd);
411         if(retval < sizeof(history))
412         {
413                 SEC_SVR_DBG("%s", "History file corrupted. Creating new one");
414                 unlink(path);
415                 retval = set_history(0);
416                 return retval;
417         }
418         SEC_SVR_DBG("History file read: %d", history);
419         return history;
420 }
421
422
423
424 int check_history(const unsigned char *requested_pwd)
425 {
426         unsigned char history_pwd[SECURITY_SERVER_HASHED_PWD_LEN];
427         char path[255];
428         unsigned int max_history;
429         int num, history_count, fd, file_count, retval;
430         int retval2 = SECURITY_SERVER_SUCCESS;
431         struct dirent **mydirent;
432
433         history_count = get_history_num();
434         if(history_count <= 0)
435                 return SECURITY_SERVER_SUCCESS;
436
437         num = scandir(SECURITY_SERVER_DATA_DIRECTORY_PATH, &mydirent, &dir_filter, alphasort);
438         if(num < 0)
439         {
440                 SEC_SVR_DBG("Server: [Error] Cannot scan password directory. errno: %d", errno);
441                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
442         }
443
444         if(num == 0)
445         {
446                 SEC_SVR_DBG("%s", "Server: There is no password file");
447                 return SECURITY_SERVER_ERROR_NO_PASSWORD;
448         }
449
450         file_count = 2;
451         while((num--))
452         {
453                 snprintf(path, 255, "%s/%s", SECURITY_SERVER_DATA_DIRECTORY_PATH, mydirent[num]->d_name);
454                 SEC_SVR_DBG("Password file path: %s", path);
455                 if(history_count > 0)
456                 {
457                         /* Load password file */
458                         fd = open(path, O_RDONLY | O_NONBLOCK );
459                         if(fd < 0)
460                         {
461                                 if(errno == ENOENT)
462                                 {
463                                         SEC_SVR_DBG("%s", "Current password doesn't exist");
464                                         return SECURITY_SERVER_SUCCESS;
465                                 }
466                                 SEC_SVR_DBG("Current password cannot be opened. errno: %d", errno);
467                                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
468                         }
469                         /* Read and store into memory */
470                         retval = read(fd, history_pwd, SECURITY_SERVER_HASHED_PWD_LEN);
471                         if(retval < SECURITY_SERVER_HASHED_PWD_LEN)
472                         {
473                                 SEC_SVR_DBG("%s", "Current password corrupted. resetting to previous one. 0");
474                                 close(fd);
475                                 fd = 0;
476                                 unlink(path);
477                                 continue;
478                         }
479                         close(fd);
480                         /* Compare */
481                         if(memcmp(history_pwd, requested_pwd, SECURITY_SERVER_HASHED_PWD_LEN) == 0)
482                         {
483                                 SEC_SVR_DBG("%s", "Server: Password has been reused");
484                                 retval2 =  SECURITY_SERVER_ERROR_PASSWORD_REUSED;
485                         }
486                         history_count--;
487
488                 }
489
490                 /* Remove too old or invalid password history */
491                 retval = validate_pwd_file(mydirent[num]->d_name);
492                 if(retval != SECURITY_SERVER_SUCCESS || file_count > (SECURITY_SERVER_MAX_PASSWORD_HISTORY))
493                 {
494                         SEC_SVR_DBG("Removing too old password. %s", path);
495                         unlink(path);
496                 }
497                 file_count++;
498                 free(mydirent[num]);
499         }
500         free(mydirent);
501         if(retval2 == SECURITY_SERVER_ERROR_PASSWORD_REUSED)
502                 retval = retval2;
503         return retval;
504 }
505
506 /* Password file format */
507 /*  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
508  * |---------------------------------------------------------------|
509  * |                                                               |
510  * |                                                               |
511  * |                       Hashed PWD (32 bytes)                   |
512  * |                                                               |
513  * |---------------------------------------------------------------|
514  * |                       Max attempts (4 bytes)                  |
515  * |---------------------------------------------------------------|
516  * |              Expiration time in seconds (4 bytes)             |
517  * |---------------------------------------------------------------|
518  */
519 int set_password(const unsigned char *requested_new_pwd, const unsigned int attempts,
520                         const unsigned int expire_time)
521 {
522         int retval, fd;
523         char pwd_path[255];
524
525         /* New file created */
526         retval = time(NULL);
527         snprintf(pwd_path, 255, "%s/%d.pwd", SECURITY_SERVER_DATA_DIRECTORY_PATH, retval);
528
529         /* Save new password as current password */
530         fd = open(pwd_path, O_WRONLY | O_NONBLOCK | O_CREAT, 0600);
531         if(fd < 0)
532         {
533                 SEC_SVR_DBG("Cannot open current password file. errno: %d", errno);
534                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
535         }
536         retval = fchmod(fd, 0600);
537         if(retval != 0)
538         {
539                 SEC_SVR_DBG("Cannot chmod current password file. errno: %d", errno);
540                 close(fd);
541                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
542         }
543         retval = write(fd, requested_new_pwd, SECURITY_SERVER_HASHED_PWD_LEN);
544         if(retval < SECURITY_SERVER_HASHED_PWD_LEN)
545         {
546                 SEC_SVR_DBG("%s", "Cannot write password");
547                 close(fd);
548                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
549         }
550         retval = write(fd, &attempts, sizeof(unsigned int));
551         if(retval < sizeof(unsigned int))
552         {
553                 SEC_SVR_DBG("%s", "Cannot write password");
554                 close(fd);
555                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
556         }
557         retval = write(fd, &expire_time, sizeof(unsigned int));
558         if(retval < sizeof(unsigned int))
559         {
560                 SEC_SVR_DBG("%s", "Cannot write password");
561                 close(fd);
562                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
563         }
564         fsync(fd);
565         close(fd);
566         SEC_SVR_DBG("%s", "Password file created");
567         return SECURITY_SERVER_SUCCESS;
568 }
569
570 int check_retry(const struct timeval cur_try)
571 {
572         int retval, interval_sec, interval_usec;
573         interval_sec = cur_try.tv_sec - prev_try.tv_sec;
574         interval_usec = cur_try.tv_usec - prev_try.tv_usec;
575         prev_try = cur_try;
576         if(interval_sec > SECURITY_SERVER_PASSWORD_RETRY_TIMEOUT_SECOND)
577                 return SECURITY_SERVER_SUCCESS;
578
579         if(interval_sec == SECURITY_SERVER_PASSWORD_RETRY_TIMEOUT_SECOND
580                         && interval_usec >= 0)
581                 return SECURITY_SERVER_SUCCESS;
582
583         SEC_SVR_DBG("%s", "retry timer hit");
584         return SECURITY_SERVER_ERROR_PASSWORD_RETRY_TIMER;
585 }
586
587 int process_valid_pwd_request(int sockfd)
588 {
589         struct timeval cur_try;
590         int retval, current_attempts, password_set;
591         unsigned char cur_pwd[SECURITY_SERVER_HASHED_PWD_LEN];
592         unsigned int max_attempt, expire_time;
593
594 /*
595         if(retval != SECURITY_SERVER_SUCCESS)
596         {
597                 SEC_SVR_DBG("%s", "Client Authentication Failed");
598                 retval = send_generic_response(client_sockfd,
599                                 SECURITY_SERVER_MSG_TYPE_TOOL_RESPONSE,
600                                 SECURITY_SERVER_RETURN_CODE_AUTHENTICATION_FAILED);
601                 if(retval != SECURITY_SERVER_SUCCESS)
602                 {
603                         SEC_SVR_DBG("ERROR: Cannot send generic response: %d", retval);
604                 }
605                 goto error;
606         }
607 */
608
609         /* Check retry timer */
610         gettimeofday(&cur_try, NULL);
611         retval = check_retry(cur_try);
612         if(retval != SECURITY_SERVER_SUCCESS)
613         {
614                 SEC_SVR_DBG("%s", "Server: Retry timeout occurred");
615                 retval = send_generic_response(sockfd,
616                                 SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE,
617                                 SECURITY_SERVER_RETURN_CODE_PASSWORD_RETRY_TIMER);
618                 if(retval != SECURITY_SERVER_SUCCESS)
619                 {
620                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
621                 }
622                 goto error;
623         }
624         password_set = load_password(cur_pwd, &max_attempt, &expire_time);
625         if(password_set == SECURITY_SERVER_ERROR_SERVER_ERROR)
626         {
627                 SEC_SVR_DBG("%s", "Server: Responding error because we cannot provide password service");
628                 retval = send_generic_response(sockfd,
629                                 SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE,
630                                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
631                 if(retval != SECURITY_SERVER_SUCCESS)
632                 {
633                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
634                 }
635                 goto error;
636         }
637
638         current_attempts = get_current_attempt(0);
639         if(current_attempts < 0)
640         {
641                 SEC_SVR_DBG("Server ERROR: Cannot get attempts: %d", current_attempts);
642                 retval = send_generic_response(sockfd,
643                                 SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE,
644                                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
645                 if(retval != SECURITY_SERVER_SUCCESS)
646                 {
647                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
648                 }
649         }
650
651         /* There is no password */
652         if(password_set == SECURITY_SERVER_ERROR_NO_PASSWORD)
653         {
654                 retval = send_pwd_response(sockfd,
655                                 SECURITY_SERVER_MSG_TYPE_VALID_PWD_RESPONSE,
656                                 SECURITY_SERVER_RETURN_CODE_NO_PASSWORD,
657                                 0, 0, 0);
658                 if(retval != SECURITY_SERVER_SUCCESS)
659                 {
660                         SEC_SVR_DBG("Server ERROR: Cannot send password response: %d", retval);
661                 }
662                 goto error;
663         }
664         if(password_set == SECURITY_SERVER_SUCCESS)
665         {
666                 retval = send_pwd_response(sockfd,
667                                 SECURITY_SERVER_MSG_TYPE_VALID_PWD_RESPONSE,
668                                 SECURITY_SERVER_RETURN_CODE_PASSWORD_EXIST,
669                                 current_attempts, max_attempt, expire_time);
670                 if(retval != SECURITY_SERVER_SUCCESS)
671                 {
672                         SEC_SVR_DBG("Server ERROR: Cannot send password response: %d", retval);
673                 }
674                 goto error;
675         }
676         SEC_SVR_DBG("Server ERROR: Unknown error: %d", retval);
677         retval = send_generic_response(sockfd,
678                         SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE,
679                         SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
680         if(retval != SECURITY_SERVER_SUCCESS)
681         {
682                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
683         }
684 error:
685         return retval;
686 }
687
688 int process_set_pwd_request(int sockfd)
689 {
690         struct timeval cur_try;
691         int retval, password_set, current_attempt;
692         unsigned int max_attempt, expire_time, valid_days, received_attempts;
693         char  new_pwd_len = 0, cur_pwd_len = 0;
694         char requested_cur_pwd[SECURITY_SERVER_MAX_PASSWORD_LEN+1];
695         char requested_new_pwd[SECURITY_SERVER_MAX_PASSWORD_LEN+1];
696         unsigned char cur_pwd[SECURITY_SERVER_HASHED_PWD_LEN];
697         unsigned char hashed_challenge[SECURITY_SERVER_HASHED_PWD_LEN];
698         unsigned char hashed_new_pw[SECURITY_SERVER_HASHED_PWD_LEN];
699
700         SHA256_CTX context;
701
702         /* Authenticate client that peer is setting app goes here*/
703         /* Check SMACK 'rw' rule for the set password */
704         retval = SECURITY_SERVER_SUCCESS;
705 /*
706         if(retval != SECURITY_SERVER_SUCCESS)
707         {
708                 SEC_SVR_DBG("%s", "Client Authentication Failed");
709                 retval = send_generic_response(client_sockfd,
710                                 SECURITY_SERVER_MSG_TYPE_TOOL_RESPONSE,
711                                 SECURITY_SERVER_RETURN_CODE_AUTHENTICATION_FAILED);
712                 if(retval != SECURITY_SERVER_SUCCESS)
713                 {
714                         SEC_SVR_DBG("ERROR: Cannot send generic response: %d", retval);
715                 }
716                 goto error;
717         }
718 */
719
720         /* Check retry timer */
721         gettimeofday(&cur_try, NULL);
722         retval = check_retry(cur_try);
723         if(retval != SECURITY_SERVER_SUCCESS)
724         {
725                 SEC_SVR_DBG("%s", "Server: Retry timeout occurred");
726                 retval = send_generic_response(sockfd,
727                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
728                                 SECURITY_SERVER_RETURN_CODE_PASSWORD_RETRY_TIMER);
729                 if(retval != SECURITY_SERVER_SUCCESS)
730                 {
731                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
732                 }
733                 goto error;
734         }
735         password_set = load_password(cur_pwd, &max_attempt, &expire_time);
736         /* If we cannot load password file */
737         if(password_set == SECURITY_SERVER_ERROR_SERVER_ERROR)
738         {
739                 SEC_SVR_DBG("%s", "Server: Responding error because we cannot provide password service");
740                 retval = send_generic_response(sockfd,
741                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
742                                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
743                 if(retval != SECURITY_SERVER_SUCCESS)
744                 {
745                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
746                 }
747                 goto error;
748         }
749
750         /* Receive size of pwds */
751         retval = read(sockfd, &cur_pwd_len, sizeof(char));
752         if(retval < sizeof(char) || cur_pwd_len > SECURITY_SERVER_MAX_PASSWORD_LEN)
753         {
754                 SEC_SVR_DBG("Server Error: current password length recieve failed: %d, %d", retval, cur_pwd_len);
755                 retval = send_generic_response(sockfd,
756                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
757                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
758                 if(retval != SECURITY_SERVER_SUCCESS)
759                 {
760                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
761                 }
762                 goto error;
763         }
764         retval = read(sockfd, &new_pwd_len, sizeof(char));
765         if(retval < sizeof(char)  || new_pwd_len > SECURITY_SERVER_MAX_PASSWORD_LEN || new_pwd_len < 0)
766         {
767                 SEC_SVR_DBG("Server Error: new password length recieve failed: %d, %d", retval, new_pwd_len);
768                 retval = send_generic_response(sockfd,
769                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
770                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
771                 if(retval != SECURITY_SERVER_SUCCESS)
772                 {
773                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
774                 }
775                 goto error;
776         }
777
778         /* Receive current password */
779         if(cur_pwd_len > 0)
780         {
781                 /* Check wheter current password is exist */
782                 if(password_set == SECURITY_SERVER_SUCCESS)
783                 retval = read(sockfd, requested_cur_pwd, cur_pwd_len);
784                 if(retval < cur_pwd_len)
785                 {
786                         SEC_SVR_DBG("Server Error: current password recieve failed: %d", retval);
787                         retval = send_generic_response(sockfd,
788                                         SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
789                                         SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
790                         if(retval != SECURITY_SERVER_SUCCESS)
791                         {
792                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
793                         }
794                         goto error;
795                 }
796                 requested_cur_pwd[cur_pwd_len] = 0;
797         }
798         else /* Check first password set attempt but password is already set */
799         {
800                 if(password_set == SECURITY_SERVER_SUCCESS)
801                 {
802                         SEC_SVR_DBG("Server Error: password is already set: %d", retval);
803                         retval = send_generic_response(sockfd,
804                                         SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
805                                         SECURITY_SERVER_RETURN_CODE_PASSWORD_EXIST);
806                         if(retval != SECURITY_SERVER_SUCCESS)
807                         {
808                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
809                         }
810                         goto error;
811                 }
812         }
813
814         /* Receive new password */
815         retval = read(sockfd, requested_new_pwd, new_pwd_len);
816         if(retval < new_pwd_len)
817         {
818                 SEC_SVR_DBG("Server Error:  new password recieve failed: %d", retval);
819                 retval = send_generic_response(sockfd,
820                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
821                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
822                 if(retval != SECURITY_SERVER_SUCCESS)
823                 {
824                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
825                 }
826                 goto error;
827         }
828         requested_new_pwd[new_pwd_len] = 0;
829
830         /* Receive max attempt */
831         retval = read(sockfd, &received_attempts, sizeof(unsigned int));
832         if(retval < sizeof(unsigned int))
833         {
834                 SEC_SVR_DBG("Sever Error:  Max attempt receive failed: %d", retval);
835                 retval = send_generic_response(sockfd,
836                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
837                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
838                 if(retval != SECURITY_SERVER_SUCCESS)
839                 {
840                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
841                 }
842                 goto error;
843         }
844
845         /* Receive valid period  */
846         retval = read(sockfd, &valid_days, sizeof(unsigned int));
847         if(retval < sizeof(unsigned int))
848         {
849                 SEC_SVR_DBG("Sever Error:  Max attempt receive failed: %d", retval);
850                 retval = send_generic_response(sockfd,
851                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
852                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
853                 if(retval != SECURITY_SERVER_SUCCESS)
854                 {
855                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
856                 }
857                 goto error;
858         }
859
860         /* Hash requested password */
861         SHA256_Init(&context);
862         SHA256_Update(&context, (unsigned char*)requested_cur_pwd, strlen(requested_cur_pwd));
863         SHA256_Final(hashed_challenge, &context);
864
865         SHA256_Init(&context);
866         SHA256_Update(&context, (unsigned char*)requested_new_pwd, strlen(requested_new_pwd));
867         SHA256_Final(hashed_new_pw, &context);
868
869         /* check current password */
870         if(password_set  == SECURITY_SERVER_SUCCESS)
871         {
872                 retval = check_password(cur_pwd, hashed_challenge, max_attempt, expire_time, &current_attempt);
873                 if(retval == SECURITY_SERVER_ERROR_PASSWORD_MISMATCH)
874                 {
875                         SEC_SVR_DBG("%s", "Server: Wrong password");
876                         retval = send_generic_response(sockfd,
877                                         SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
878                                         SECURITY_SERVER_RETURN_CODE_PASSWORD_MISMATCH);
879                         if(retval != SECURITY_SERVER_SUCCESS)
880                         {
881                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
882                         }
883                         goto error;
884                 }
885                 if(retval == SECURITY_SERVER_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED)
886                 {
887                         SEC_SVR_DBG("%s", "Server: Too many challange");
888                         retval = send_generic_response(sockfd,
889                                         SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
890                                         SECURITY_SERVER_RETURN_CODE_PASSWORD_MAX_ATTEMPTS_EXCEEDED);
891                         if(retval != SECURITY_SERVER_SUCCESS)
892                         {
893                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
894                         }
895                         goto error;
896                 }
897                 if(retval == SECURITY_SERVER_ERROR_PASSWORD_EXPIRED)
898                 {
899                         SEC_SVR_DBG("%s", "Server: Password expired");
900                         retval = send_generic_response(sockfd,
901                                         SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
902                                         SECURITY_SERVER_RETURN_CODE_PASSWORD_EXPIRED);
903                         if(retval != SECURITY_SERVER_SUCCESS)
904                         {
905                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
906                         }
907                         goto error;
908                 }
909                 if(retval != SECURITY_SERVER_SUCCESS)
910                 {
911                         SEC_SVR_DBG("Error: Password check failed: %d", retval);
912                         retval = send_generic_response(sockfd,
913                                         SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
914                                         SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
915                         if(retval != SECURITY_SERVER_SUCCESS)
916                         {
917                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
918                         }
919                         goto error;
920                 }
921                 retval = check_history(hashed_new_pw);
922                 if(retval == SECURITY_SERVER_ERROR_PASSWORD_REUSED)
923                 {
924                         retval = send_generic_response(sockfd,
925                                         SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
926                                         SECURITY_SERVER_RETURN_CODE_PASSWORD_REUSED);
927                         if(retval != SECURITY_SERVER_SUCCESS)
928                         {
929                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
930                         }
931                         goto error;
932                 }
933         }
934         else if(cur_pwd_len != 0)
935         {
936                 /* Client ask to set with current password, but there is no password now */
937                 SEC_SVR_DBG("%s", "Server: There is no current password. But try to set with current password");
938                 retval = send_generic_response(sockfd,
939                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
940                                 SECURITY_SERVER_RETURN_CODE_PASSWORD_MISMATCH);
941                 if(retval != SECURITY_SERVER_SUCCESS)
942                 {
943                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
944                 }
945                 goto error;
946         }
947
948         /* Calculate expire time in seconds */
949         if(valid_days == 0)
950                 expire_time = 0;
951         else
952                 expire_time = time(NULL) + (valid_days * 86400);
953
954         /* set new password */
955         retval = set_password(hashed_new_pw, received_attempts, expire_time);
956         if(retval != SECURITY_SERVER_SUCCESS)
957         {
958                 SEC_SVR_DBG("Server Error: Password set failed: %d", retval);
959                 retval = send_generic_response(sockfd,
960                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
961                                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
962                 if(retval != SECURITY_SERVER_SUCCESS)
963                 {
964                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
965                 }
966                 password_set = SECURITY_SERVER_ERROR_SERVER_ERROR;
967                 goto error;
968         }
969         password_set = SECURITY_SERVER_SUCCESS;
970         retval = reset_attempt();
971
972         /* All done. send response */
973         SEC_SVR_DBG("%s", "Server: Password has been successfully modified");
974         retval = send_generic_response(sockfd,
975                         SECURITY_SERVER_MSG_TYPE_SET_PWD_RESPONSE,
976                         SECURITY_SERVER_RETURN_CODE_SUCCESS);
977         if(retval != SECURITY_SERVER_SUCCESS)
978         {
979                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
980         }
981 error:
982         return retval;
983 }
984
985 int process_reset_pwd_request(int sockfd)
986 {
987         int retval, password_set;
988         char new_pwd_len;
989         unsigned int valid_days, received_attempts, expire_time;
990         char requested_new_pwd[SECURITY_SERVER_MAX_PASSWORD_LEN +1];
991         unsigned char hashed_new_pw[SECURITY_SERVER_HASHED_PWD_LEN];
992         unsigned char cur_pwd[SECURITY_SERVER_HASHED_PWD_LEN];
993         struct timeval cur_try;
994
995         SHA256_CTX context;
996
997         /* Authenticate client that peer is setting app goes here*/
998 /*
999         if(retval != SECURITY_SERVER_SUCCESS)
1000         {
1001                 SEC_SVR_DBG("%s", "Client Authentication Failed");
1002                 retval = send_generic_response(client_sockfd,
1003                                 SECURITY_SERVER_MSG_TYPE_TOOL_RESPONSE,
1004                                 SECURITY_SERVER_RETURN_CODE_AUTHENTICATION_FAILED);
1005                 if(retval != SECURITY_SERVER_SUCCESS)
1006                 {
1007                         SEC_SVR_DBG("ERROR: Cannot send generic response: %d", retval);
1008                 }
1009                 goto error;
1010         }
1011 */
1012
1013         /* Check retry timer */
1014         gettimeofday(&cur_try, NULL);
1015         retval = check_retry(cur_try);
1016         if(retval != SECURITY_SERVER_SUCCESS)
1017         {
1018                 SEC_SVR_DBG("%s", "Server: Retry timeout occurred");
1019                 retval = send_generic_response(sockfd,
1020                                 SECURITY_SERVER_MSG_TYPE_RESET_PWD_RESPONSE,
1021                                 SECURITY_SERVER_RETURN_CODE_PASSWORD_RETRY_TIMER);
1022                 if(retval != SECURITY_SERVER_SUCCESS)
1023                 {
1024                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1025                 }
1026                 goto error;
1027         }
1028
1029         password_set = load_password(cur_pwd, &valid_days, &expire_time);
1030         if(password_set == SECURITY_SERVER_ERROR_SERVER_ERROR)
1031         {
1032                 SEC_SVR_DBG("%s", "Server: Responding error because we cannot provide password service");
1033                 retval = send_generic_response(sockfd,
1034                                 SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE,
1035                                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
1036                 if(retval != SECURITY_SERVER_SUCCESS)
1037                 {
1038                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1039                 }
1040                 goto error;
1041         }
1042
1043         /* Receive size of pwd */
1044         retval = read(sockfd, &new_pwd_len, sizeof(char));
1045         if(retval < sizeof(char) || new_pwd_len < 0 || new_pwd_len > SECURITY_SERVER_MAX_PASSWORD_LEN)
1046         {
1047                 SEC_SVR_DBG("Server Error: new password length recieve failed: %d, %d", retval, new_pwd_len);
1048                 retval = send_generic_response(sockfd,
1049                                 SECURITY_SERVER_MSG_TYPE_RESET_PWD_RESPONSE,
1050                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1051                 if(retval != SECURITY_SERVER_SUCCESS)
1052                 {
1053                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1054                 }
1055                 goto error;
1056         }
1057
1058         /* Receive new password */
1059         retval = read(sockfd, requested_new_pwd, new_pwd_len);
1060         if(retval < new_pwd_len)
1061         {
1062                 SEC_SVR_DBG("Server Error:  new password recieve failed: %d", retval);
1063                 retval = send_generic_response(sockfd,
1064                                 SECURITY_SERVER_MSG_TYPE_RESET_PWD_RESPONSE,
1065                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1066                 if(retval != SECURITY_SERVER_SUCCESS)
1067                 {
1068                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1069                 }
1070                 goto error;
1071         }
1072         requested_new_pwd[new_pwd_len] = 0;
1073
1074         /* Receive max attempt */
1075         retval = read(sockfd, &received_attempts, sizeof(unsigned int));
1076         if(retval < sizeof(unsigned int))
1077         {
1078                 SEC_SVR_DBG("Sever Error:  Max attempt receive failed: %d", retval);
1079                 retval = send_generic_response(sockfd,
1080                                 SECURITY_SERVER_MSG_TYPE_RESET_PWD_RESPONSE,
1081                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1082                 if(retval != SECURITY_SERVER_SUCCESS)
1083                 {
1084                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1085                 }
1086                 goto error;
1087         }
1088
1089         /* Receive valid period  */
1090         retval = read(sockfd, &valid_days, sizeof(unsigned int));
1091         if(retval < sizeof(unsigned int))
1092         {
1093                 SEC_SVR_DBG("Sever Error:  Max attempt receive failed: %d", retval);
1094                 retval = send_generic_response(sockfd,
1095                                 SECURITY_SERVER_MSG_TYPE_RESET_PWD_RESPONSE,
1096                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1097                 if(retval != SECURITY_SERVER_SUCCESS)
1098                 {
1099                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1100                 }
1101                 goto error;
1102         }
1103
1104         /* Calculate expire time in seconds */
1105         if(valid_days == 0)
1106                 expire_time = 0;
1107         else
1108                 expire_time = time(NULL) + (valid_days * 86400);
1109
1110         /* Hash requested password */
1111         SHA256_Init(&context);
1112         SHA256_Update(&context, (unsigned char*)requested_new_pwd, strlen(requested_new_pwd));
1113         SHA256_Final(hashed_new_pw, &context);
1114         /* set new password */
1115         retval = set_password(hashed_new_pw, received_attempts, expire_time);
1116         if(retval != SECURITY_SERVER_SUCCESS)
1117         {
1118                 SEC_SVR_DBG("Server Error: Password set failed: %d", retval);
1119                 retval = send_generic_response(sockfd,
1120                                 SECURITY_SERVER_MSG_TYPE_RESET_PWD_RESPONSE,
1121                                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
1122                 if(retval != SECURITY_SERVER_SUCCESS)
1123                 {
1124                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1125                 }
1126                 goto error;
1127         }
1128         retval = reset_attempt();
1129
1130         /* All done. send response */
1131         SEC_SVR_DBG("%s", "Server: Password has been successfully modified");
1132         retval = send_generic_response(sockfd,
1133                         SECURITY_SERVER_MSG_TYPE_RESET_PWD_RESPONSE,
1134                         SECURITY_SERVER_RETURN_CODE_SUCCESS);
1135         if(retval != SECURITY_SERVER_SUCCESS)
1136         {
1137                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1138         }
1139 error:
1140         return retval;
1141 }
1142
1143 int process_chk_pwd_request(int sockfd)
1144 {
1145         int retval, password_set, current_attempt;
1146         unsigned int max_attempt, expire_time;
1147         char requested_challenge[SECURITY_SERVER_MAX_PASSWORD_LEN+1];
1148         char challenge_len;
1149         unsigned char cur_pwd[SECURITY_SERVER_HASHED_PWD_LEN];
1150         unsigned char hashed_challenge[SECURITY_SERVER_HASHED_PWD_LEN];
1151         struct timeval cur_try;
1152
1153         SHA256_CTX context;
1154
1155         /* Authenticate client that peer is proper app goes here*/
1156         /* Check SMACK rule for the 'r' for password */
1157         retval = SECURITY_SERVER_SUCCESS;
1158 /*
1159         if(retval != SECURITY_SERVER_SUCCESS)
1160         {
1161                 SEC_SVR_DBG("%s", "Client Authentication Failed");
1162                 retval = send_generic_response(sockfd,
1163                                 SECURITY_SERVER_MSG_TYPE_TOOL_RESPONSE,
1164                                 SECURITY_SERVER_RETURN_CODE_AUTHENTICATION_FAILED);
1165                 if(retval != SECURITY_SERVER_SUCCESS)
1166                 {
1167                         SEC_SVR_DBG("ERROR: Cannot send generic response: %d", retval);
1168                 }
1169                 goto error;
1170         }
1171 */
1172         /* Check retry timer */
1173         gettimeofday(&cur_try, NULL);
1174         retval = check_retry(cur_try);
1175         if(retval != SECURITY_SERVER_SUCCESS)
1176         {
1177                 SEC_SVR_DBG("%s", "Server: Retry timeout occurred");
1178                 retval = send_generic_response(sockfd,
1179                                 SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1180                                 SECURITY_SERVER_RETURN_CODE_PASSWORD_RETRY_TIMER);
1181                 if(retval != SECURITY_SERVER_SUCCESS)
1182                 {
1183                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1184                 }
1185                 goto error;
1186         }
1187
1188         /* If we cannot load password file */
1189         password_set = load_password(cur_pwd, &max_attempt, &expire_time);;
1190         if(password_set == SECURITY_SERVER_ERROR_SERVER_ERROR)
1191         {
1192                 SEC_SVR_DBG("%s", "ServerERROR: Responding error because we cannot provide password service");
1193                 retval = send_generic_response(sockfd,
1194                                 SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1195                                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
1196                 if(retval != SECURITY_SERVER_SUCCESS)
1197                 {
1198                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1199                 }
1200                 goto error;
1201         }
1202
1203         /* Receive size of challenge */
1204         retval = read(sockfd, &challenge_len, sizeof(char));
1205         if(retval < sizeof(char) || challenge_len > SECURITY_SERVER_MAX_PASSWORD_LEN)
1206         {
1207                 SEC_SVR_DBG("Server ERROR: challenge length recieve failed: %d", retval);
1208                 retval = send_generic_response(sockfd,
1209                                 SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1210                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1211                 if(retval != SECURITY_SERVER_SUCCESS)
1212                 {
1213                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1214                 }
1215                 goto error;
1216         }
1217         /* Receive challenge */
1218         if(challenge_len > 0)
1219         {
1220                 retval = read(sockfd, requested_challenge, challenge_len);
1221                 if(retval < challenge_len)
1222                 {
1223                         SEC_SVR_DBG("Server ERROR: current password recieve failed: %d", retval);
1224                         retval = send_generic_response(sockfd,
1225                                         SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1226                                         SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1227                         if(retval != SECURITY_SERVER_SUCCESS)
1228                         {
1229                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1230                         }
1231                         goto error;
1232                 }
1233                 requested_challenge[challenge_len] = 0;
1234         }
1235         else
1236         {
1237                 SEC_SVR_DBG("Error: Challenge length too short: %d", retval);
1238                 retval = send_generic_response(sockfd,
1239                                 SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1240                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1241                 if(retval != SECURITY_SERVER_SUCCESS)
1242                 {
1243                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1244                 }
1245                 goto error;
1246         }
1247
1248         /* Hash requested password */
1249         SHA256_Init(&context);
1250         SHA256_Update(&context, (unsigned char*)requested_challenge, challenge_len);
1251         SHA256_Final(hashed_challenge, &context);
1252
1253         /* check current password */
1254         if(password_set  == SECURITY_SERVER_SUCCESS)
1255         {
1256                 retval = check_password(cur_pwd, hashed_challenge, max_attempt, expire_time, &current_attempt);
1257                 if(retval == SECURITY_SERVER_ERROR_PASSWORD_MISMATCH)
1258                 {
1259                         SEC_SVR_DBG("%s", "Server: Wrong password");
1260                         retval = send_pwd_response(sockfd,
1261                                         SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1262                                         SECURITY_SERVER_RETURN_CODE_PASSWORD_MISMATCH,
1263                                         current_attempt, max_attempt, expire_time);
1264                         if(retval != SECURITY_SERVER_SUCCESS)
1265                         {
1266                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1267                         }
1268                         goto error;
1269                 }
1270                 if(retval == SECURITY_SERVER_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED)
1271                 {
1272                         SEC_SVR_DBG("%s", "Server: Too many trial");
1273                         retval = send_pwd_response(sockfd,
1274                                         SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1275                                         SECURITY_SERVER_RETURN_CODE_PASSWORD_MAX_ATTEMPTS_EXCEEDED,
1276                                         current_attempt, max_attempt, expire_time);
1277                         if(retval != SECURITY_SERVER_SUCCESS)
1278                         {
1279                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1280                         }
1281                         goto error;
1282                 }
1283                 if(retval == SECURITY_SERVER_ERROR_PASSWORD_EXPIRED)
1284                 {
1285                         SEC_SVR_DBG("%s", "Server: Password expired");
1286                         retval = send_pwd_response(sockfd,
1287                                         SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1288                                         SECURITY_SERVER_RETURN_CODE_PASSWORD_EXPIRED,
1289                                         current_attempt, max_attempt, 0);
1290                         if(retval != SECURITY_SERVER_SUCCESS)
1291                         {
1292                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1293                         }
1294                         goto error;
1295                 }
1296                 if(retval != SECURITY_SERVER_SUCCESS)
1297                 {
1298                         SEC_SVR_DBG("Server ERROR: Password check failed: %d", retval);
1299                         retval = send_generic_response(sockfd,
1300                                         SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1301                                         SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
1302                         if(retval != SECURITY_SERVER_SUCCESS)
1303                         {
1304                                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1305                         }
1306                         goto error;
1307                 }
1308
1309                 /* Password matched */
1310                 SEC_SVR_DBG("%s", "Server: Password matched");
1311                 retval = send_pwd_response(sockfd,
1312                                 SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1313                                 SECURITY_SERVER_RETURN_CODE_SUCCESS,
1314                                 current_attempt, max_attempt, expire_time);
1315                 if(retval != SECURITY_SERVER_SUCCESS)
1316                 {
1317                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1318                 }
1319                 retval = reset_attempt();
1320                 goto error;
1321         }
1322
1323         /* There is no password */
1324
1325         SEC_SVR_DBG("%s", "Server: There is no password to be checked");
1326         retval = send_generic_response(sockfd,
1327                         SECURITY_SERVER_MSG_TYPE_CHK_PWD_RESPONSE,
1328                         SECURITY_SERVER_RETURN_CODE_NO_PASSWORD);
1329         if(retval != SECURITY_SERVER_SUCCESS)
1330         {
1331                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1332         }
1333 error:
1334         return retval;
1335 }
1336
1337 int process_set_pwd_history_request(int sockfd)
1338 {
1339         int retval;
1340         char history_num;
1341         struct timeval cur_try;
1342
1343         /* Authenticate client that peer is setting app goes here*/
1344 /*
1345         f(retval != SECURITY_SERVER_SUCCESS)
1346         {
1347                 SEC_SVR_DBG("%s", "Client Authentication Failed");
1348                 retval = send_generic_response(client_sockfd,
1349                                 SECURITY_SERVER_MSG_TYPE_TOOL_RESPONSE,
1350                                 SECURITY_SERVER_RETURN_CODE_AUTHENTICATION_FAILED);
1351                 if(retval != SECURITY_SERVER_SUCCESS)
1352                 {
1353                         SEC_SVR_DBG("ERROR: Cannot send generic response: %d", retval);
1354                 }
1355                 goto error;
1356         }
1357 */
1358
1359         /* Check retry timer */
1360         gettimeofday(&cur_try, NULL);
1361         retval = check_retry(cur_try);
1362         if(retval != SECURITY_SERVER_SUCCESS)
1363         {
1364                 SEC_SVR_DBG("%s", "Server: Retry timeout occurred");
1365                 retval = send_generic_response(sockfd,
1366                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_HISTORY_RESPONSE,
1367                                 SECURITY_SERVER_RETURN_CODE_PASSWORD_RETRY_TIMER);
1368                 if(retval != SECURITY_SERVER_SUCCESS)
1369                 {
1370                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1371                 }
1372                 goto error;
1373         }
1374
1375         /* Receive size of pwds */
1376         retval = read(sockfd, &history_num, sizeof(char));
1377         if(retval < sizeof(char) || history_num > SECURITY_SERVER_MAX_PASSWORD_HISTORY || history_num < 0 )
1378         {
1379                 SEC_SVR_DBG("Server Error: History number recieve failed: %d, %d", retval, history_num);
1380                 retval = send_generic_response(sockfd,
1381                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_HISTORY_RESPONSE,
1382                                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1383                 if(retval != SECURITY_SERVER_SUCCESS)
1384                 {
1385                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1386                 }
1387                 goto error;
1388         }
1389
1390         retval = set_history((int)history_num);
1391         if(retval != SECURITY_SERVER_SUCCESS)
1392         {
1393                 SEC_SVR_DBG("Server Error: History number set failed: %d", retval);
1394                 retval = send_generic_response(sockfd,
1395                                 SECURITY_SERVER_MSG_TYPE_SET_PWD_HISTORY_RESPONSE,
1396                                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
1397                 if(retval != SECURITY_SERVER_SUCCESS)
1398                 {
1399                         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1400                 }
1401         }
1402         SEC_SVR_DBG("Server History has been set to %d", history_num);
1403         retval = send_generic_response(sockfd,
1404                         SECURITY_SERVER_MSG_TYPE_SET_PWD_HISTORY_RESPONSE,
1405                         SECURITY_SERVER_RETURN_CODE_SUCCESS);
1406         if(retval != SECURITY_SERVER_SUCCESS)
1407         {
1408                 SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1409         }
1410 error:
1411         return retval;
1412 }
1413
1414
1415 int process_set_pwd_max_challenge_request(int sockfd)
1416 {
1417     unsigned int max_challenge, current_challenge, current_validity;
1418     unsigned char cur_pwd[SECURITY_SERVER_HASHED_PWD_LEN];
1419     int retval;
1420
1421     // TODO here we should probably check if the peer has rights to change
1422     // this value (max challenge) for current password
1423
1424     retval = read(sockfd, &max_challenge, sizeof(unsigned int));
1425     if(retval < sizeof(unsigned int))
1426     {
1427         SEC_SVR_DBG("Server Error: recieve failed: %d", retval);
1428         retval = send_generic_response(sockfd,
1429                 SECURITY_SERVER_MSG_TYPE_SET_PWD_MAX_CHALLENGE_RESPONSE,
1430                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1431         if(retval != SECURITY_SERVER_SUCCESS)
1432         {
1433             SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1434         }
1435         goto error;
1436     }
1437
1438     SEC_SVR_DBG("Server max challenge request: %d", max_challenge);
1439
1440     // Getting currently set password
1441     retval = load_password(cur_pwd, &current_challenge, &current_validity);
1442     /* If we cannot load password file */
1443     if(retval == SECURITY_SERVER_ERROR_NO_PASSWORD)
1444     {
1445         SEC_SVR_DBG("%s", "Server: can't read current password");
1446         retval = send_generic_response(sockfd,
1447                 SECURITY_SERVER_MSG_TYPE_SET_PWD_MAX_CHALLENGE_RESPONSE,
1448                 SECURITY_SERVER_RETURN_CODE_NO_PASSWORD);
1449         if(retval != SECURITY_SERVER_SUCCESS)
1450         {
1451             SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1452         }
1453         goto error;
1454     }
1455     else if(retval != SECURITY_SERVER_SUCCESS)
1456     {
1457         SEC_SVR_DBG("%s", "Server: can't read current password");
1458         retval = send_generic_response(sockfd,
1459                 SECURITY_SERVER_MSG_TYPE_SET_PWD_MAX_CHALLENGE_RESPONSE,
1460                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
1461         if(retval != SECURITY_SERVER_SUCCESS)
1462         {
1463             SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1464         }
1465         goto error;
1466     }
1467
1468     // Set 'new' password file with old password and new max challenge
1469     retval = set_password(cur_pwd, max_challenge, time(NULL) + current_validity);
1470     if(retval != SECURITY_SERVER_SUCCESS)
1471     {
1472         SEC_SVR_DBG("Server Error: Password set failed: %d", retval);
1473         retval = send_generic_response(sockfd,
1474                 SECURITY_SERVER_MSG_TYPE_SET_PWD_MAX_CHALLENGE_RESPONSE,
1475                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
1476         if(retval != SECURITY_SERVER_SUCCESS)
1477         {
1478             SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1479         }
1480         goto error;
1481     }
1482
1483     retval = send_generic_response(sockfd,
1484             SECURITY_SERVER_MSG_TYPE_SET_PWD_MAX_CHALLENGE_RESPONSE,
1485             SECURITY_SERVER_RETURN_CODE_SUCCESS);
1486     if(retval != SECURITY_SERVER_SUCCESS)
1487     {
1488         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1489     }
1490     retval = reset_attempt();
1491 error:
1492     return retval;
1493 }
1494
1495 int process_set_pwd_validity_request(int sockfd)
1496 {
1497     unsigned int current_challenge, current_validity, validity;
1498     unsigned char cur_pwd[SECURITY_SERVER_HASHED_PWD_LEN];
1499     int retval;
1500
1501     // TODO here we should probably check if the peer has rights to change
1502     // this value (validity) for current password
1503
1504     retval = read(sockfd, &validity, sizeof(unsigned int));
1505     if(retval < sizeof(unsigned int))
1506     {
1507         SEC_SVR_DBG("Server Error: recieve failed: %d", retval);
1508         retval = send_generic_response(sockfd,
1509                 SECURITY_SERVER_MSG_TYPE_SET_PWD_VALIDITY_RESPONSE,
1510                 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
1511         if(retval != SECURITY_SERVER_SUCCESS)
1512         {
1513             SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1514         }
1515         goto error;
1516     }
1517
1518     SEC_SVR_DBG("Server validity request: %d", validity);
1519
1520     // Calculating validity in seconds
1521     if(validity == 0)
1522         validity = 0;
1523     else
1524         validity = time(NULL) + (validity * 86400);
1525
1526     // Getting currently set password
1527     retval = load_password(cur_pwd, &current_challenge, &current_validity);
1528     /* If we cannot load password file */
1529     if(retval == SECURITY_SERVER_ERROR_NO_PASSWORD)
1530     {
1531         SEC_SVR_DBG("%s", "Server: can't read current password");
1532         retval = send_generic_response(sockfd,
1533                 SECURITY_SERVER_MSG_TYPE_SET_PWD_VALIDITY_RESPONSE,
1534                 SECURITY_SERVER_RETURN_CODE_NO_PASSWORD);
1535         if(retval != SECURITY_SERVER_SUCCESS)
1536         {
1537             SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1538         }
1539         goto error;
1540     }
1541     else if(retval != SECURITY_SERVER_SUCCESS)
1542     {
1543         SEC_SVR_DBG("%s", "Server: can't read current password");
1544         retval = send_generic_response(sockfd,
1545                 SECURITY_SERVER_MSG_TYPE_SET_PWD_VALIDITY_RESPONSE,
1546                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
1547         if(retval != SECURITY_SERVER_SUCCESS)
1548         {
1549             SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1550         }
1551         goto error;
1552     }
1553
1554     // Set 'new' password file with old password and new validity
1555     retval = set_password(cur_pwd, current_challenge, validity);
1556     if(retval != SECURITY_SERVER_SUCCESS)
1557     {
1558         SEC_SVR_DBG("Server Error: Password set failed: %d", retval);
1559         retval = send_generic_response(sockfd,
1560                 SECURITY_SERVER_MSG_TYPE_SET_PWD_VALIDITY_RESPONSE,
1561                 SECURITY_SERVER_RETURN_CODE_SERVER_ERROR);
1562         if(retval != SECURITY_SERVER_SUCCESS)
1563         {
1564             SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1565         }
1566         goto error;
1567     }
1568
1569     retval = send_generic_response(sockfd,
1570             SECURITY_SERVER_MSG_TYPE_SET_PWD_VALIDITY_RESPONSE,
1571             SECURITY_SERVER_RETURN_CODE_SUCCESS);
1572     if(retval != SECURITY_SERVER_SUCCESS)
1573     {
1574         SEC_SVR_DBG("Server ERROR: Cannot send generic response: %d", retval);
1575     }
1576     retval = reset_attempt();
1577 error:
1578     return retval;
1579 }