merge with master
[framework/security/security-server.git] / src / communication / security-server-comm.c
1 /*
2  * security-server
3  *
4  *  Copyright (c) 2000 - 2011 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 <sys/poll.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <sys/socket.h>
26 #include <sys/types.h>
27 #include <sys/smack.h>
28 #include <fcntl.h>
29 #include <pwd.h>
30 #include <sys/un.h>
31 #include <errno.h>
32 #include <unistd.h>
33 #include <sys/stat.h>
34 #include <limits.h>
35
36 #include "security-server-common.h"
37 #include "security-server-comm.h"
38
39 void printhex(const unsigned char *data, int size)
40 {
41         int i;
42         for(i=0;i<size;i++)
43         {
44                 if(data[i] < 0xF)
45                         printf("0");
46
47                 printf("%X ", data[i]);
48                 if(((i+1) % 16) == 0 && i != 0)
49                         printf("\n");
50         }
51         printf("\n");
52 }
53
54 char *read_cmdline_from_proc(pid_t pid)
55 {
56         int memsize = 32;
57         char path[32];
58         char *cmdline = NULL, *tempptr = NULL;
59         FILE *fp = NULL;
60
61         snprintf(path, sizeof(path), "/proc/%d/cmdline", pid);
62
63         fp = fopen(path, "r");
64         if(fp == NULL)
65         {
66                 SEC_SVR_DBG("Cannot open cmdline on pid[%d]", pid);
67                 return NULL;
68         }
69
70         cmdline = malloc(32);
71         if(cmdline == NULL)
72         {
73                 SEC_SVR_DBG("%s", "Out of memory");
74                 fclose(fp);
75                 return NULL;
76         }
77
78         bzero(cmdline, memsize);
79         if(fgets(cmdline, 32, fp) == NULL)
80         {
81                 SEC_SVR_DBG("%s", "Cannot read cmdline");
82                 free(cmdline);
83                 fclose(fp);
84                 return NULL;
85         }
86
87         while(cmdline[memsize -2] != 0)
88         {
89                 cmdline[memsize -1] = (char) fgetc(fp);
90                 tempptr = realloc(cmdline, memsize + 32);
91                 if(tempptr == NULL)
92                 {
93                         fclose(fp);
94                         SEC_SVR_DBG("%s", "Out of memory");
95                         return NULL;
96                 }
97                 cmdline = tempptr;
98                 bzero(cmdline + memsize, 32);
99                 fgets(cmdline + memsize, 32, fp);
100                 memsize += 32;
101         }
102
103         if(fp != NULL)
104                 fclose(fp);
105         return cmdline;
106 }
107
108 /* Return code in packet is positive integer *
109  * We need to convert them to error code which are negative integer */
110 int return_code_to_error_code(int ret_code)
111 {
112         int ret;
113         switch(ret_code)
114         {
115                 case SECURITY_SERVER_RETURN_CODE_SUCCESS:
116                 case SECURITY_SERVER_RETURN_CODE_ACCESS_GRANTED:
117                         ret = SECURITY_SERVER_SUCCESS;
118                         break;
119                 case SECURITY_SERVER_RETURN_CODE_BAD_REQUEST:
120                         ret = SECURITY_SERVER_ERROR_BAD_REQUEST;
121                         break;
122                 case SECURITY_SERVER_RETURN_CODE_AUTHENTICATION_FAILED:
123                         ret = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
124                         break;
125                 case SECURITY_SERVER_RETURN_CODE_ACCESS_DENIED:
126                         ret = SECURITY_SERVER_ERROR_ACCESS_DENIED;
127                         break;
128                 case SECURITY_SERVER_RETURN_CODE_NO_SUCH_OBJECT:
129                         ret = SECURITY_SERVER_ERROR_NO_SUCH_OBJECT;
130                         break;
131                 case SECURITY_SERVER_RETURN_CODE_SERVER_ERROR:
132                         ret = SECURITY_SERVER_ERROR_SERVER_ERROR;
133                         break;
134                 case SECURITY_SERVER_RETURN_CODE_NO_SUCH_COOKIE:
135                         ret = SECURITY_SERVER_ERROR_NO_SUCH_COOKIE;
136                         break;
137                 case SECURITY_SERVER_RETURN_CODE_NO_PASSWORD:
138                         ret = SECURITY_SERVER_ERROR_NO_PASSWORD;
139                         break;
140                 case SECURITY_SERVER_RETURN_CODE_PASSWORD_EXIST:
141                         ret = SECURITY_SERVER_ERROR_PASSWORD_EXIST;
142                         break;
143                 case SECURITY_SERVER_RETURN_CODE_PASSWORD_MISMATCH:
144                         ret = SECURITY_SERVER_ERROR_PASSWORD_MISMATCH;
145                         break;
146                 case SECURITY_SERVER_RETURN_CODE_PASSWORD_RETRY_TIMER:
147                         ret = SECURITY_SERVER_ERROR_PASSWORD_RETRY_TIMER;
148                         break;
149                 case SECURITY_SERVER_RETURN_CODE_PASSWORD_EXPIRED:
150                         ret = SECURITY_SERVER_ERROR_PASSWORD_EXPIRED;
151                         break;
152                 case SECURITY_SERVER_RETURN_CODE_PASSWORD_MAX_ATTEMPTS_EXCEEDED:
153                         ret = SECURITY_SERVER_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED;
154                         break;
155                 case SECURITY_SERVER_RETURN_CODE_PASSWORD_REUSED:
156                         ret = SECURITY_SERVER_ERROR_PASSWORD_REUSED;
157                         break;
158                 default:
159                         ret = SECURITY_SERVER_ERROR_UNKNOWN;
160                         break;
161         }
162         return ret;
163 }
164
165 int check_socket_poll(int sockfd, int event, int timeout)
166 {
167         struct pollfd poll_fd[1];
168         int retval = SECURITY_SERVER_ERROR_POLL;
169
170         poll_fd[0].fd = sockfd;
171         poll_fd[0].events = event;
172         retval = poll(poll_fd, 1, timeout);
173         if(retval < 0)
174         {
175                 SEC_SVR_DBG("poll() error. errno=%d", errno);
176                 if(errno != EINTR)
177                         return SECURITY_SERVER_ERROR_POLL;
178                 else
179                 {
180                         /* Chile process has been closed. Not poll() problem. Call it once again */
181                         return check_socket_poll(sockfd, event, timeout);
182                 }
183         }
184
185         /* Timed out */
186         if(retval == 0)
187         {
188                 return SECURITY_SERVER_ERROR_TIMEOUT;
189         }
190
191         if(poll_fd[0].revents != event)
192         {
193                 SEC_SVR_DBG("Something wrong on the peer socket. event=0x%x", poll_fd[0].revents);
194                 return SECURITY_SERVER_ERROR_POLL;
195         }
196         return SECURITY_SERVER_SUCCESS;
197 }
198
199 int safe_server_sock_close(int client_sockfd)
200 {
201         struct pollfd poll_fd[1];
202         int retval;
203         retval = SECURITY_SERVER_ERROR_POLL;
204         poll_fd[0].fd = client_sockfd;
205         poll_fd[0].events = POLLRDHUP;
206         retval = poll(poll_fd, 1, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
207         SEC_SVR_DBG("%s", "Server: Closing server socket");
208         close(client_sockfd);
209         return SECURITY_SERVER_SUCCESS;
210 }
211
212 /* Create a Unix domain socket and bind */
213 int create_new_socket(int *sockfd)
214 {
215         int retval = 0, localsockfd = 0, flags;
216         struct sockaddr_un serveraddr;
217         mode_t sock_mode;
218
219         /* Deleted garbage Unix domain socket file */
220         retval = remove(SECURITY_SERVER_SOCK_PATH);
221
222     if (retval == -1 && errno != ENOENT) {
223         retval = SECURITY_SERVER_ERROR_UNKNOWN;
224         localsockfd = -1;
225         SEC_SVR_DBG("%s", "Unable to remove /tmp/.security_server.sock");
226         goto error;
227     }
228
229         /* Create Unix domain socket */
230         if((localsockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 )
231         {
232                 retval = SECURITY_SERVER_ERROR_SOCKET;
233                 localsockfd = -1;
234                 SEC_SVR_DBG("%s", "Socket creation failed");
235                 goto error;
236         }
237
238         if(smack_fsetlabel(localsockfd, "@", SMACK_LABEL_IPOUT) != 0)
239         {
240                 SEC_SVR_DBG("%s", "SMACK labeling failed");
241                 if(errno != EOPNOTSUPP)
242                 {
243                         retval = SECURITY_SERVER_ERROR_SOCKET;
244             close(localsockfd);
245                         localsockfd = -1;
246                         goto error;
247                 }
248         }
249         if(smack_fsetlabel(localsockfd, "*", SMACK_LABEL_IPIN) != 0)
250         {       SEC_SVR_DBG("%s", "SMACK labeling failed");
251                 if(errno != EOPNOTSUPP)
252                 {
253                         retval = SECURITY_SERVER_ERROR_SOCKET;
254             close(localsockfd);
255                         localsockfd = -1;
256                         goto error;
257                 }
258         }
259
260         /* Make socket as non blocking */
261         if((flags = fcntl(localsockfd, F_GETFL, 0)) < 0 ||
262                         fcntl(localsockfd, F_SETFL, flags | O_NONBLOCK) < 0)
263         {
264                 retval = SECURITY_SERVER_ERROR_SOCKET;
265                 close(localsockfd);
266                 localsockfd = -1;
267                 SEC_SVR_DBG("%s", "Cannot go to nonblocking mode");
268                 goto error;
269         }
270
271         bzero (&serveraddr, sizeof(serveraddr));
272         serveraddr.sun_family = AF_UNIX;
273         strncpy(serveraddr.sun_path, SECURITY_SERVER_SOCK_PATH,
274                         strlen(SECURITY_SERVER_SOCK_PATH));
275         serveraddr.sun_path[strlen(SECURITY_SERVER_SOCK_PATH)] = 0;
276
277         /* Bind the socket */
278         if((bind(localsockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0)
279         {
280                 retval = SECURITY_SERVER_ERROR_SOCKET_BIND;
281                 SEC_SVR_DBG("%s", "Cannot bind");
282                 close(localsockfd);
283                 localsockfd = -1;
284                 goto error;
285         }
286
287
288         /* Change permission to accept all processes that has different uID/gID */
289         sock_mode = (S_IRWXU | S_IRWXG | S_IRWXO);
290         /* Flawfinder hits this chmod function as level 5 CRITICAL as race condition flaw *
291          * Flawfinder recommends to user fchmod insted of chmod
292          * But, fchmod doesn't work on socket file so there is no other choice at this point */
293         if(chmod(SECURITY_SERVER_SOCK_PATH, sock_mode) < 0)             /* Flawfinder: ignore */
294         {
295                 SEC_SVR_DBG("%s", "chmod() error");
296                 retval = SECURITY_SERVER_ERROR_SOCKET;
297                 close(localsockfd);
298                 localsockfd = -1;
299                 goto error;
300         }
301
302         retval = SECURITY_SERVER_SUCCESS;
303
304 error:
305         *sockfd = localsockfd;
306         return retval;
307 }
308
309 /* Authenticate peer that it's really security server.
310  * Check UID that is root
311  */
312 int authenticate_server(int sockfd)
313 {
314         int retval;
315         struct ucred cr;
316         unsigned int cl = sizeof(cr);
317 /*      char *cmdline = NULL;*/
318
319         /* get socket peer credential */
320         if(getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) != 0)
321         {
322                 retval = SECURITY_SERVER_ERROR_SOCKET;
323                 SEC_SVR_DBG("%s", "getsockopt() failed");
324                 goto error;
325         }
326
327         /* Security server must run as root */
328         if(cr.uid != 0)
329         {
330                 retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
331                 SEC_SVR_DBG("Peer is not root: uid=%d", cr.uid);
332                 goto error;
333         }
334         else
335                 retval = SECURITY_SERVER_SUCCESS;
336
337         /* Read command line of the PID from proc fs */
338         /* This is commented out because non root process cannot read link of /proc/pid/exe */
339 /*      cmdline = read_cmdline_from_proc(cr.pid);
340
341         if(strcmp(cmdline, SECURITY_SERVER_DAEMON_PATH) != 0)
342         {
343                 retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
344                 SEC_SVR_DBG("Cmdline is different. auth failed. cmdline=%s", cmdline);
345         }
346         else
347         {
348                 retval = SECURITY_SERVER_SUCCESS;
349                 SEC_SVR_DBG("Server authenticatd. %s, sockfd=%d", cmdline, sockfd);
350         }
351 */
352 error:
353 /*      if(cmdline != NULL)
354                 free(cmdline);
355 */
356         return retval;
357 }
358
359 /* Create a socket and connect to Security Server */
360 int connect_to_server(int *fd)
361 {
362         struct sockaddr_un clientaddr;
363         int client_len = 0, localsockfd, ret, flags;
364         *fd = -1;
365
366         /* Create a socket */
367         localsockfd = socket(AF_UNIX, SOCK_STREAM, 0);
368         if(localsockfd < 0)
369         {
370                 SEC_SVR_DBG("%s", "Error on socket()");
371                 return SECURITY_SERVER_ERROR_SOCKET;
372         }
373
374         /* Make socket as non blocking */
375         if((flags = fcntl(localsockfd, F_GETFL, 0)) < 0 ||
376                         fcntl(localsockfd, F_SETFL, flags | O_NONBLOCK) < 0)
377         {
378                 close(localsockfd);
379                 SEC_SVR_DBG("%s", "Cannot go to nonblocking mode");
380                 return SECURITY_SERVER_ERROR_SOCKET;
381         }
382
383         bzero(&clientaddr, sizeof(clientaddr));
384         clientaddr.sun_family = AF_UNIX;
385         strncpy(clientaddr.sun_path, SECURITY_SERVER_SOCK_PATH, strlen(SECURITY_SERVER_SOCK_PATH));
386         clientaddr.sun_path[strlen(SECURITY_SERVER_SOCK_PATH)] = 0;
387         client_len = sizeof(clientaddr);
388
389         ret = connect(localsockfd, (struct sockaddr*)&clientaddr, client_len);
390         if( ret < 0)
391         {
392                 if(errno == EINPROGRESS)
393                 {
394                         SEC_SVR_DBG("%s", "Connection is in progress");
395                         ret = check_socket_poll(localsockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
396                         if(ret == SECURITY_SERVER_ERROR_POLL)
397                         {
398                                 SEC_SVR_DBG("%s", "poll() error");
399                                 close(localsockfd);
400                                 return SECURITY_SERVER_ERROR_SOCKET;
401                         }
402                         if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
403                         {
404                                 SEC_SVR_DBG("%s", "poll() timeout");
405                                 close(localsockfd);
406                                 return SECURITY_SERVER_ERROR_SOCKET;
407                         }
408                         ret = connect(localsockfd, (struct sockaddr*)&clientaddr, client_len);
409                         if(ret < 0)
410                         {
411                                 SEC_SVR_DBG("%s", "connection failed");
412                                 close(localsockfd);
413                                 return SECURITY_SERVER_ERROR_SOCKET;
414                         }
415                 }
416                 else
417                 {
418                         SEC_SVR_DBG("%s", "Connection failed");
419                         close(localsockfd);
420                         return SECURITY_SERVER_ERROR_SOCKET;
421                 }
422         }
423
424         /* Authenticate the peer is actually security server */
425         ret = authenticate_server(localsockfd);
426         if(ret  != SECURITY_SERVER_SUCCESS)
427         {
428                 close(localsockfd);
429                 SEC_SVR_DBG("Authentication failed. %d", ret);
430                 return ret;
431         }
432         *fd = localsockfd;
433         return SECURITY_SERVER_SUCCESS;
434 }
435
436 /* Accept a new client connection */
437 int accept_client(int server_sockfd)
438 {
439         /* Call poll() to wait for socket connection */
440         int retval, localsockfd;
441         struct sockaddr_un clientaddr;
442         unsigned int client_len;
443
444         client_len = sizeof(clientaddr);
445
446         /* Check poll */
447         retval = check_socket_poll(server_sockfd, POLLIN, SECURITY_SERVER_ACCEPT_TIMEOUT_MILISECOND);
448         if(retval == SECURITY_SERVER_ERROR_POLL)
449         {
450                 SEC_SVR_DBG("%s", "Error on polling");
451                 return SECURITY_SERVER_ERROR_SOCKET;
452         }
453
454         /* Timed out */
455         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
456         {
457                 /*SEC_SVR_DBG("%s", "accept() timeout");*/
458                 return SECURITY_SERVER_ERROR_TIMEOUT;
459         }
460
461         localsockfd = accept(server_sockfd,
462                         (struct sockaddr *)&clientaddr,
463                         &client_len);
464
465         if(localsockfd < 0)
466         {
467                 SEC_SVR_DBG("Cannot accept client. errno=%d", errno);
468                 return SECURITY_SERVER_ERROR_SOCKET;
469         }
470         return localsockfd;
471 }
472
473 /* Minimal check of request packet */
474 int validate_header(basic_header hdr)
475 {
476         if(hdr.version != SECURITY_SERVER_MSG_VERSION)
477                 return SECURITY_SERVER_ERROR_BAD_REQUEST;
478
479         return SECURITY_SERVER_SUCCESS;
480 }
481
482 /* Send generic response packet to client
483  *
484  * Generic Response Packet Format
485  0                   1                   2                   3
486  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
487 |---------------------------------------------------------------|
488 | version=0x01  |  Message ID   |Message Length (without header)|
489 |---------------------------------------------------------------|
490 |  return code  |
491 -----------------
492 */
493 int send_generic_response (int sockfd, unsigned char msgid, unsigned char return_code)
494 {
495         response_header hdr;
496         int size;
497
498         /* Assemble header */
499         hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
500         hdr.basic_hdr.msg_id = msgid;
501         hdr.basic_hdr.msg_len = 0;
502         hdr.return_code = return_code;
503
504         /* Check poll */
505         size = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
506         if(size == SECURITY_SERVER_ERROR_POLL)
507         {
508                 SEC_SVR_DBG("%s", "poll() error");
509                 return SECURITY_SERVER_ERROR_SEND_FAILED;
510         }
511         if(size == SECURITY_SERVER_ERROR_TIMEOUT)
512         {
513                 SEC_SVR_DBG("%s", "poll() timeout");
514                 return SECURITY_SERVER_ERROR_SEND_FAILED;
515         }
516
517         /* Send to client */
518         size = write(sockfd, &hdr, sizeof(hdr));
519
520         if(size < sizeof(hdr))
521                 return SECURITY_SERVER_ERROR_SEND_FAILED;
522         return SECURITY_SERVER_SUCCESS;
523 }
524
525 /* Send cookie response to client
526  *
527  * Get Cookie response packet format
528  *  0                   1                   2                   3
529  *  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
530  *  |---------------------------------------------------------------|
531  *  | version=0x01  |MessageID=0x02 |       Message Length =20      |
532  *  |---------------------------------------------------------------|
533  *  |  return code  |                                               |
534  *  -----------------                                               |
535  *  |                 cookie (20 bytes)                             |
536  *  |---------------------------------------------------------------|
537 */
538 int send_cookie(int sockfd, unsigned char *cookie)
539 {
540         response_header hdr;
541         unsigned char msg[SECURITY_SERVER_COOKIE_LEN + sizeof(hdr)];
542         int ret;
543
544         /* Assemble header */
545         hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
546         hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_COOKIE_RESPONSE;
547         hdr.basic_hdr.msg_len = SECURITY_SERVER_COOKIE_LEN;
548         hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
549
550         memcpy(msg, &hdr, sizeof(hdr));
551         memcpy(msg + sizeof(hdr), cookie, SECURITY_SERVER_COOKIE_LEN);
552
553         /* Check poll */
554         ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
555         if(ret == SECURITY_SERVER_ERROR_POLL)
556         {
557                 SEC_SVR_DBG("%s", "poll() error");
558                 return SECURITY_SERVER_ERROR_SEND_FAILED;
559         }
560         if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
561         {
562                 SEC_SVR_DBG("%s", "poll() timeout");
563                 return SECURITY_SERVER_ERROR_SEND_FAILED;
564         }
565
566         ret = write(sockfd, msg, sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN);
567         if(ret <  sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN)
568         {
569                 /* Error on writing */
570                 SEC_SVR_DBG("Error on write: %d", ret);
571                 ret = SECURITY_SERVER_ERROR_SEND_FAILED;
572                 return ret;
573         }
574         return SECURITY_SERVER_SUCCESS;
575 }
576
577 /* Send Object name response *
578  * Get Object name response packet format
579  *  0                   1                   2                   3
580  *  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
581  * |---------------------------------------------------------------|
582  * | version=0x01  |MessageID=0x06 |       Message Length          |
583  * |---------------------------------------------------------------|
584  * |  return code  |                                               |
585  * -----------------                                               |
586  * |                 object name                                   |
587  * |---------------------------------------------------------------|
588 */
589 int send_object_name(int sockfd, char *obj)
590 {
591         response_header hdr;
592         unsigned char msg[strlen(obj) + sizeof(hdr)];
593         int ret;
594
595         hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
596         hdr.basic_hdr.msg_id = 0x06;
597         hdr.basic_hdr.msg_len = strlen(obj);
598         hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
599
600         memcpy(msg, &hdr, sizeof(hdr));
601         memcpy(msg + sizeof(hdr), obj, strlen(obj));
602
603         /* Check poll */
604         ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
605         if(ret == SECURITY_SERVER_ERROR_POLL)
606         {
607                 SEC_SVR_DBG("%s", "poll() error");
608                 return SECURITY_SERVER_ERROR_SEND_FAILED;
609         }
610         if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
611         {
612                 SEC_SVR_DBG("%s", "poll() timeout");
613                 return SECURITY_SERVER_ERROR_SEND_FAILED;
614         }
615
616         ret = write(sockfd, msg, sizeof(hdr) + strlen(obj));
617         if(ret <  sizeof(hdr) + strlen(obj))
618         {
619                 /* Error on writing */
620                 SEC_SVR_DBG("Error on write: %d", ret);
621                 ret = SECURITY_SERVER_ERROR_SEND_FAILED;
622                 return ret;
623         }
624         return SECURITY_SERVER_SUCCESS;
625 }
626
627 /* Send GID response to client
628  *
629  * Get GID response packet format
630  *  0                   1                   2                   3
631  *  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
632  * |---------------------------------------------------------------|
633  * | version=0x01  |MessageID=0x08 |       Message Length = 4      |
634  * |---------------------------------------------------------------|
635  * |  return code  |           gid (first 3 words)                 |
636  * |---------------------------------------------------------------|
637  * |gid(last word) |
638  * |---------------|
639 */
640 int send_gid(int sockfd, int gid)
641 {
642         response_header hdr;
643         unsigned char msg[sizeof(gid) + sizeof(hdr)];
644         int ret;
645
646         /* Assemble header */
647         hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
648         hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_GID_RESPONSE;
649         hdr.basic_hdr.msg_len = sizeof(gid);
650         hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
651
652         /* Perpare packet */
653         memcpy(msg, &hdr, sizeof(hdr));
654         memcpy(msg + sizeof(hdr), &gid, sizeof(gid));
655
656         /* Check poll */
657         ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
658         if(ret == SECURITY_SERVER_ERROR_POLL)
659         {
660                 SEC_SVR_DBG("%s", "poll() error");
661                 return SECURITY_SERVER_ERROR_SEND_FAILED;
662         }
663         if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
664         {
665                 SEC_SVR_DBG("%s", "poll() timeout");
666                 return SECURITY_SERVER_ERROR_SEND_FAILED;
667         }
668
669         /* Send it */
670         ret = write(sockfd, msg, sizeof(hdr) + sizeof(gid));
671         if(ret <  sizeof(hdr) + sizeof(gid))
672         {
673                 /* Error on writing */
674                 SEC_SVR_DBG("Error on write(): %d", ret);
675                 ret = SECURITY_SERVER_ERROR_SEND_FAILED;
676                 return ret;
677         }
678         return SECURITY_SERVER_SUCCESS;
679 }
680
681 /* Send PID response to client
682  *
683  * Get PID response packet format
684  *  0                   1                   2                   3
685  *  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
686  * |---------------------------------------------------------------|
687  * | version=0x01  |MessageID=0x0a |       Message Length = 4      |
688  * |---------------------------------------------------------------|
689  * |  return code  |           pid (first 3 words)                 |
690  * |---------------------------------------------------------------|
691  * |pid(last word) |
692  * |---------------|
693 */
694 int send_pid(int sockfd, int pid)
695 {
696         response_header hdr;
697         unsigned char msg[sizeof(pid) + sizeof(hdr)];
698         int ret;
699
700         /* Assemble header */
701         hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
702         hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_PID_RESPONSE;
703         hdr.basic_hdr.msg_len = sizeof(pid);
704         hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
705
706         /* Perpare packet */
707         memcpy(msg, &hdr, sizeof(hdr));
708         memcpy(msg + sizeof(hdr), &pid, sizeof(pid));
709
710         /* Check poll */
711         ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
712         if(ret == SECURITY_SERVER_ERROR_POLL)
713         {
714                 SEC_SVR_DBG("%s", "poll() error");
715                 return SECURITY_SERVER_ERROR_SEND_FAILED;
716         }
717         if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
718         {
719                 SEC_SVR_DBG("%s", "poll() timeout");
720                 return SECURITY_SERVER_ERROR_SEND_FAILED;
721         }
722
723         /* Send it */
724         ret = write(sockfd, msg, sizeof(hdr) + sizeof(pid));
725         if(ret <  sizeof(hdr) + sizeof(pid))
726         {
727                 /* Error on writing */
728                 SEC_SVR_DBG("Error on write(): %d", ret);
729                 ret = SECURITY_SERVER_ERROR_SEND_FAILED;
730                 return ret;
731         }
732         return SECURITY_SERVER_SUCCESS;
733 }
734
735 /* Send SMACK label to client with lenght N
736  *  0                   1                   2                   3
737  *  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
738  * |---------------------------------------------------------------|
739  * | version=0x01  |MessageID=0x1e |  Message Length = SMACK_LABEL_LEN + 1
740  * |---------------------------------------------------------------|
741  * |  return code  |           SMACK label byte 0                  |
742  * |---------------------------------------------------------------|
743  * |                      ..................                       |
744  * |---------------------------------------------------------------|
745  * |                      SMACK label byte N                       |
746  * |---------------------------------------------------------------|
747 */
748 int send_smack(int sockfd, char * label)
749 {
750         response_header hdr;
751     //added 1 to the size is for NULL terminating label
752     int LABEL_SIZE = SMACK_LABEL_LEN + 1;
753     int PACKET_SIZE = sizeof(hdr) + LABEL_SIZE;
754         unsigned char msg[PACKET_SIZE];
755         int ret;
756
757         /* Assemble header */
758         hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
759         hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_SMACK_RESPONSE;
760         hdr.basic_hdr.msg_len = LABEL_SIZE;
761         hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
762
763         /* Perpare packet */
764         memcpy(msg, &hdr, sizeof(hdr));
765         memcpy(msg + sizeof(hdr), label, LABEL_SIZE);
766     memset(msg + sizeof(hdr) + SMACK_LABEL_LEN, 0x00, 1); //adding NULL ad the label end
767
768         /* Check poll */
769         ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
770         if(ret == SECURITY_SERVER_ERROR_POLL)
771         {
772                 SEC_SVR_DBG("%s", "poll() error");
773                 return SECURITY_SERVER_ERROR_SEND_FAILED;
774         }
775         if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
776         {
777                 SEC_SVR_DBG("%s", "poll() timeout");
778                 return SECURITY_SERVER_ERROR_SEND_FAILED;
779         }
780
781         /* Send it */
782         ret = write(sockfd, msg, PACKET_SIZE);
783         if(ret <  PACKET_SIZE)
784         {
785                 /* Error on writing */
786                 SEC_SVR_DBG("Error on write(): %d", ret);
787                 ret = SECURITY_SERVER_ERROR_SEND_FAILED;
788                 return ret;
789         }
790         return SECURITY_SERVER_SUCCESS;
791 }
792
793 /* Send Check password response to client
794  *
795  * Check password response packet format
796  *  0                   1                   2                   3
797  *  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
798  * |---------------------------------------------------------------|
799  * | version=0x01  |   MessageID   |       Message Length = 12     |
800  * |---------------------------------------------------------------|
801  * |  return code  |           attempts (first 3 words)            |
802  * |---------------------------------------------------------------|
803  * |attempts(rest) |          max_attempts (first 3 words)         |
804  * |---------------|-----------------------------------------------|
805  * | max_attempts  |          expire_in_days (first 3 words)       |
806  * |---------------------------------------------------------------|
807  * |expire_in_days |
808  * |----------------
809  */
810 int send_pwd_response(const int sockfd,
811         const unsigned char msg_id,
812         const unsigned char return_code,
813         const unsigned int current_attempts,
814         const unsigned int max_attempts,
815         const unsigned int expire_time)
816 {
817         response_header hdr;
818         unsigned int expire_secs;
819         unsigned char msg[sizeof(hdr) + sizeof(current_attempts) + sizeof(max_attempts) + sizeof(expire_secs)];
820         int ret, ptr = 0;
821
822
823         /* Assemble header */
824         hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
825         hdr.basic_hdr.msg_id = msg_id;
826         hdr.basic_hdr.msg_len = sizeof(unsigned int) * 3;
827         hdr.return_code = return_code;
828
829         /* Perpare packet */
830         memcpy(msg, &hdr, sizeof(hdr));
831         ptr += sizeof(hdr);
832         memcpy(msg + ptr, &current_attempts, sizeof(current_attempts));
833         ptr += sizeof(current_attempts);
834         memcpy(msg + ptr, &max_attempts, sizeof(max_attempts));
835         ptr += sizeof(max_attempts);
836         memcpy(msg + ptr, &expire_time, sizeof(expire_time));
837         ptr += sizeof(expire_time);
838
839         /* Check poll */
840         ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
841         if(ret == SECURITY_SERVER_ERROR_POLL)
842         {
843                 SEC_SVR_DBG("%s", "Server: poll() error");
844                 return SECURITY_SERVER_ERROR_SEND_FAILED;
845         }
846         if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
847         {
848                 SEC_SVR_DBG("%s", "Server: poll() timeout");
849                 return SECURITY_SERVER_ERROR_SEND_FAILED;
850         }
851
852         /* Send it */
853         ret = write(sockfd, msg, ptr);
854         if(ret <  ptr)
855         {
856                 /* Error on writing */
857                 SEC_SVR_DBG("Server: ERROR on write(): %d", ret);
858                 ret = SECURITY_SERVER_ERROR_SEND_FAILED;
859                 return ret;
860         }
861         return SECURITY_SERVER_SUCCESS;
862 }
863
864 /* Send cookie request packet to security server *
865  *
866  * Message format
867  *  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
868  * |---------------------------------------------------------------|
869  * | version=0x01  |MessageID=0x01 |       Message Length = 0      |
870  * |---------------------------------------------------------------|
871  */
872 int send_cookie_request(int sock_fd)
873 {
874         basic_header hdr;
875         int retval;
876
877         /* Assemble header */
878         hdr.version = SECURITY_SERVER_MSG_VERSION;
879         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_COOKIE_REQUEST;
880         hdr.msg_len = 0;
881
882         /* Check poll */
883         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
884         if(retval == SECURITY_SERVER_ERROR_POLL)
885         {
886                 SEC_SVR_DBG("%s", "poll() error");
887                 return SECURITY_SERVER_ERROR_SEND_FAILED;
888         }
889         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
890         {
891                 SEC_SVR_DBG("%s", "poll() timeout");
892                 return SECURITY_SERVER_ERROR_SEND_FAILED;
893         }
894
895         /* Send to server */
896         retval = write(sock_fd, &hdr, sizeof(hdr));
897         if(retval < sizeof(hdr))
898         {
899                 /* Write error */
900                 SEC_SVR_DBG("Error on write(): %d", retval);
901                 return SECURITY_SERVER_ERROR_SEND_FAILED;
902         }
903         return SECURITY_SERVER_SUCCESS;
904 }
905
906 /* Send GID request message to security server
907  *
908  * Message format
909  *  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
910  * |---------------------------------------------------------------|
911  * | version=0x01  |MessageID=0x07 |   Message Length = variable   |
912  * |---------------------------------------------------------------|
913  * |                                                               |
914  * |                   Object name (variable)                      |
915  * |                                                               |
916  * |---------------------------------------------------------------|
917  */
918 int send_gid_request(int sock_fd, const char* object)
919 {
920         basic_header hdr;
921         int retval = 0, send_len = 0;
922         unsigned char *buf = NULL;
923
924         if(strlen(object) > SECURITY_SERVER_MAX_OBJ_NAME)
925         {
926                 /* Object name is too big*/
927                 SEC_SVR_DBG("Object name is too big %dbytes", strlen(object));
928                 return SECURITY_SERVER_ERROR_INPUT_PARAM;
929         }
930
931         hdr.version = SECURITY_SERVER_MSG_VERSION;
932         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_GID_REQUEST;
933         hdr.msg_len = strlen(object);
934
935         send_len = sizeof(hdr) + strlen(object);
936
937         buf = malloc(send_len);
938         if(buf == NULL)
939         {
940                 SEC_SVR_DBG("%s", "out of memory");
941                 return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
942         }
943
944         memcpy(buf, &hdr, sizeof(hdr));
945         memcpy(buf + sizeof(hdr), object, strlen(object));
946
947         /* Check poll */
948         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
949         if(retval == SECURITY_SERVER_ERROR_POLL)
950         {
951                 SEC_SVR_DBG("%s", "poll() error");
952                 retval = SECURITY_SERVER_ERROR_SEND_FAILED;
953                 goto error;
954         }
955         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
956         {
957                 SEC_SVR_DBG("%s", "poll() timeout");
958                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
959                 goto error;
960         }
961
962         retval = write(sock_fd, buf, send_len);
963         if(retval < send_len)
964         {
965                 /* Write error */
966                 SEC_SVR_DBG("Error on write(): %d. errno=%d, sockfd=%d", retval, errno, sock_fd);
967                 retval = SECURITY_SERVER_ERROR_SEND_FAILED;
968         }
969         else
970                 retval = SECURITY_SERVER_SUCCESS;
971
972 error:
973         if(buf != NULL)
974                 free(buf);
975
976         return retval;
977 }
978
979 /* Send object name request message to security server *
980  *
981  * Message format
982  *  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
983  * |---------------------------------------------------------------|
984  * | version=0x01  |MessageID=0x05 |       Message Length = 4      |
985  * |---------------------------------------------------------------|
986  * |                               gid                             |
987  * |---------------------------------------------------------------|
988  */
989 int send_object_name_request(int sock_fd, int gid)
990 {
991         basic_header hdr;
992         int retval;
993         unsigned char buf[sizeof(hdr) + sizeof(gid)];
994
995         /* Assemble header */
996         hdr.version = SECURITY_SERVER_MSG_VERSION;
997         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_OBJECT_NAME_REQUEST;
998         hdr.msg_len = sizeof(gid);
999
1000         memcpy(buf, &hdr, sizeof(hdr));
1001         memcpy(buf + sizeof(hdr), &gid, sizeof(gid));
1002
1003         /* Check poll */
1004         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1005         if(retval == SECURITY_SERVER_ERROR_POLL)
1006         {
1007                 SEC_SVR_DBG("%s", "poll() error");
1008                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1009         }
1010         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1011         {
1012                 SEC_SVR_DBG("%s", "poll() timeout");
1013                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1014         }
1015
1016         /* Send to server */
1017         retval = write(sock_fd, buf, sizeof(buf));
1018         if(retval < sizeof(buf))
1019         {
1020                 /* Write error */
1021                 SEC_SVR_DBG("Error on write(): %d", retval);
1022                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1023         }
1024         return SECURITY_SERVER_SUCCESS;
1025 }
1026
1027 /* Send privilege check request message to security server *
1028  *
1029  * Message format
1030  *  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
1031  * |---------------------------------------------------------------|
1032  * | version=0x01  |MessageID=0x03 |      Message Length = 24      |
1033  * |---------------------------------------------------------------|
1034  * |                                                               |
1035  * |                                                               |
1036  * |                      Cookie (20bytes)                         |
1037  * |                                                               |
1038  * |                                                               |
1039  * |---------------------------------------------------------------|
1040  * |                            GID                                |
1041  * |---------------------------------------------------------------|
1042  */
1043 int send_privilege_check_request(int sock_fd, const char*cookie, int gid)
1044 {
1045         basic_header hdr;
1046         int retval;
1047         unsigned char buf[sizeof(hdr) + sizeof(gid) + SECURITY_SERVER_COOKIE_LEN];
1048
1049         /* Assemble header */
1050         hdr.version = SECURITY_SERVER_MSG_VERSION;
1051         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_CHECK_PRIVILEGE_REQUEST;
1052         hdr.msg_len = sizeof(gid) + SECURITY_SERVER_COOKIE_LEN;
1053
1054         memcpy(buf, &hdr, sizeof(hdr));
1055         memcpy(buf + sizeof(hdr), cookie, SECURITY_SERVER_COOKIE_LEN);
1056         memcpy(buf + sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN, &gid, sizeof(gid));
1057
1058         /* Check poll */
1059         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1060         if(retval == SECURITY_SERVER_ERROR_POLL)
1061         {
1062                 SEC_SVR_DBG("%s", "poll() error");
1063                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1064         }
1065         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1066         {
1067                 SEC_SVR_DBG("%s", "poll() timeout");
1068                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1069         }
1070
1071         /* Send to server */
1072         retval = write(sock_fd, buf, sizeof(buf));
1073         if(retval < sizeof(buf))
1074         {
1075                 /* Write error */
1076                 SEC_SVR_DBG("Error on write(): %d", retval);
1077                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1078         }
1079         return SECURITY_SERVER_SUCCESS;
1080 }
1081
1082 int send_privilege_check_new_request(int sock_fd,
1083                                      const char *cookie,
1084                                      const char *object,
1085                                      const char *access_rights)
1086 {
1087         basic_header hdr;
1088         int retval;
1089         int olen, alen;
1090         int size;
1091
1092         olen = strlen(object);
1093         alen = strlen(access_rights);
1094         if (olen > MAX_OBJECT_LABEL_LEN || alen > MAX_MODE_STR_LEN)
1095         {
1096                 return SECURITY_SERVER_ERROR_INPUT_PARAM;
1097         }
1098
1099         unsigned char buf[sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN +
1100                           2*sizeof(int) + MAX_OBJECT_LABEL_LEN + MAX_MODE_STR_LEN];
1101
1102         /* Assemble header */
1103         hdr.version = SECURITY_SERVER_MSG_VERSION;
1104         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_CHECK_PRIVILEGE_NEW_REQUEST;
1105         hdr.msg_len = SECURITY_SERVER_COOKIE_LEN + 2*sizeof(int) + olen + alen;
1106
1107         memcpy(buf, &hdr, sizeof(hdr));
1108         memcpy(buf + sizeof(hdr), cookie, SECURITY_SERVER_COOKIE_LEN);
1109         memcpy(buf + sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN, &olen, sizeof(int));
1110         memcpy(buf + sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN + sizeof(int),
1111                &alen, sizeof(int));
1112         memcpy(buf + sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN + 2*sizeof(int), object, olen);
1113         memcpy(buf + sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN + 2*sizeof(int) + olen,
1114                access_rights, alen);
1115
1116         /* Check poll */
1117         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1118         if(retval == SECURITY_SERVER_ERROR_POLL)
1119         {
1120                 SEC_SVR_DBG("%s", "poll() error");
1121                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1122         }
1123         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1124         {
1125                 SEC_SVR_DBG("%s", "poll() timeout");
1126                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1127         }
1128
1129         size = sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN + 2*sizeof(int) + olen + alen;
1130         /* Send to server */
1131         retval = write(sock_fd, buf, size);
1132         if(retval < size)
1133         {
1134                 /* Write error */
1135                 SEC_SVR_DBG("Error on write(): %d", retval);
1136                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1137         }
1138         return SECURITY_SERVER_SUCCESS;
1139 }
1140
1141 /* Send SMACK request message to security server *
1142  *
1143  * Message format
1144  *  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
1145  * |---------------------------------------------------------------|
1146  * | version=0x01  |MessageID=0x1d |      Message Length = 20      |
1147  * |---------------------------------------------------------------|
1148  * |                                                               |
1149  * |                                                               |
1150  * |                      Cookie (20bytes)                         |
1151  * |                                                               |
1152  * |                                                               |
1153  * |---------------------------------------------------------------|
1154  */
1155 int send_smack_request(int sock_fd, const char * cookie)
1156 {
1157         basic_header hdr;
1158         int retval;
1159         unsigned char buf[sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN];
1160
1161         /* Assemble header */
1162         hdr.version = SECURITY_SERVER_MSG_VERSION;
1163         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_SMACK_REQUEST;
1164         hdr.msg_len = SECURITY_SERVER_COOKIE_LEN;
1165
1166         memcpy(buf, &hdr, sizeof(hdr));
1167         memcpy(buf + sizeof(hdr), cookie, SECURITY_SERVER_COOKIE_LEN);
1168
1169         /* Check poll */
1170         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1171         if(retval == SECURITY_SERVER_ERROR_POLL)
1172         {
1173                 SEC_SVR_DBG("%s", "poll() error");
1174                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1175         }
1176         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1177         {
1178                 SEC_SVR_DBG("%s", "poll() timeout");
1179                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1180         }
1181
1182         /* Send to server */
1183         retval = write(sock_fd, buf, sizeof(buf));
1184         if(retval < sizeof(buf))
1185         {
1186                 /* Write error */
1187                 SEC_SVR_DBG("Error on write(): %d", retval);
1188                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1189         }
1190         return SECURITY_SERVER_SUCCESS;
1191 }
1192
1193 /* Send PID check request message to security server *
1194  *
1195  * Message format
1196  *  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
1197  * |---------------------------------------------------------------|
1198  * | version=0x01  |MessageID=0x09 |      Message Length = 20      |
1199  * |---------------------------------------------------------------|
1200  * |                                                               |
1201  * |                                                               |
1202  * |                      Cookie (20bytes)                         |
1203  * |                                                               |
1204  * |                                                               |
1205  * |---------------------------------------------------------------|
1206  */
1207 int send_pid_request(int sock_fd, const char*cookie)
1208 {
1209         basic_header hdr;
1210         int retval;
1211         unsigned char buf[sizeof(hdr) + SECURITY_SERVER_COOKIE_LEN];
1212
1213         /* Assemble header */
1214         hdr.version = SECURITY_SERVER_MSG_VERSION;
1215         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_PID_REQUEST;
1216         hdr.msg_len = SECURITY_SERVER_COOKIE_LEN;
1217
1218         memcpy(buf, &hdr, sizeof(hdr));
1219         memcpy(buf + sizeof(hdr), cookie, SECURITY_SERVER_COOKIE_LEN);
1220
1221         /* Check poll */
1222         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1223         if(retval == SECURITY_SERVER_ERROR_POLL)
1224         {
1225                 SEC_SVR_DBG("%s", "poll() error");
1226                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1227         }
1228         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1229         {
1230                 SEC_SVR_DBG("%s", "poll() timeout");
1231                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1232         }
1233
1234         /* Send to server */
1235         retval = write(sock_fd, buf, sizeof(buf));
1236         if(retval < sizeof(buf))
1237         {
1238                 /* Write error */
1239                 SEC_SVR_DBG("Error on write(): %d", retval);
1240                 return SECURITY_SERVER_ERROR_SEND_FAILED;
1241         }
1242         return SECURITY_SERVER_SUCCESS;
1243 }
1244
1245
1246 /* Send debug tool launch request message to security server *
1247  *
1248  * Message format
1249  *  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
1250  * |---------------------------------------------------------------|
1251  * | version=0x01  |MessageID=0x0b |       Message Length          |
1252  * |---------------------------------------------------------------|
1253  * |                        total # of args                        |
1254  * |---------------------------------------------------------------|
1255  * |                        1st argv length                        |
1256  * |---------------------------------------------------------------|
1257  * |                                                               |
1258  * |                            1st argv                           |
1259  * |                                                               |
1260  * |---------------------------------------------------------------|
1261  * |                        2nd argv length                        |
1262  * |---------------------------------------------------------------|
1263  * |                                                               |
1264  * |                            2nd argv                           |
1265  * |                                                               |
1266  * |---------------------------------------------------------------|
1267  * |                                ...                            |
1268  * |---------------------------------------------------------------|
1269  * |                        nth argv length                        |
1270  * |---------------------------------------------------------------|
1271  * |                                                               |
1272  * |                            nth argv                           |
1273  * |                                                               |
1274  * |---------------------------------------------------------------|
1275  */
1276 int send_launch_tool_request(int sock_fd, int argc, const char **argv)
1277 {
1278         basic_header hdr;
1279         int retval, total_length = 0, ptr, i, tempnum;
1280         unsigned char *buf = NULL;
1281
1282         for (i=0;i<argc;i++)
1283         {
1284                 if(argv[i] == NULL)
1285                 {
1286                         SEC_SVR_DBG("Error: %dth argv is NULL", i);
1287                         return SECURITY_SERVER_ERROR_INPUT_PARAM;
1288                 }
1289                 total_length += strlen(argv[i]);
1290         }
1291
1292         if(total_length < 1)
1293         {
1294                 SEC_SVR_DBG("Error: There is a problem in argv. [%d]", total_length);
1295                 return SECURITY_SERVER_ERROR_INPUT_PARAM;
1296         }
1297         total_length += sizeof(hdr) + sizeof(int) +(argc * sizeof(int));
1298
1299         if(total_length > 0xffff)
1300         {
1301                 SEC_SVR_DBG("Buffer overflow. too big payload. [%d]", total_length);
1302                 return SECURITY_SERVER_ERROR_INPUT_PARAM;
1303         }
1304
1305         buf = malloc(total_length);
1306         if(buf == NULL)
1307         {
1308                 SEC_SVR_DBG("%s", "Error: failed to malloc()");
1309                 return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
1310         }
1311
1312         /* Assemble header */
1313         hdr.version = SECURITY_SERVER_MSG_VERSION;
1314         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_TOOL_REQUEST;
1315         hdr.msg_len = (unsigned short)total_length;
1316         memcpy(buf, &hdr, sizeof(hdr));
1317         ptr = sizeof(hdr);
1318         memcpy(buf + ptr, &argc, sizeof(int));
1319         ptr += sizeof(hdr);
1320
1321         /* Assemple each argv length and value */
1322         for(i=0;i<argc;i++)
1323         {
1324                 tempnum = strlen(argv[i]);
1325                 memcpy(buf + ptr, &tempnum, sizeof(int));
1326                 ptr += sizeof(int);
1327                 memcpy(buf + ptr, argv[i], tempnum);
1328                 ptr += tempnum;
1329         }
1330
1331         /* Check poll */
1332         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1333         if(retval == SECURITY_SERVER_ERROR_POLL)
1334         {
1335                 SEC_SVR_DBG("%s", "poll() error");
1336                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1337                 goto error;
1338
1339         }
1340         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1341         {
1342                 SEC_SVR_DBG("%s", "poll() timeout");
1343                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1344                 goto error;
1345         }
1346
1347         /* Send to server */
1348         retval = write(sock_fd, buf, total_length);
1349         if(retval < sizeof(buf))
1350         {
1351                 /* Write error */
1352                 SEC_SVR_DBG("Error on write(): %d", retval);
1353                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1354                 goto error;
1355         }
1356         retval = SECURITY_SERVER_SUCCESS;
1357
1358 error:
1359         if(buf != NULL)
1360                 free(buf);
1361         return retval;
1362 }
1363
1364 /* Send validate password request message to security server *
1365  *
1366  * Message format
1367  *  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
1368  * |---------------------------------------------------------------|
1369  * | version=0x01  |MessageID=0x0d |       Message Length          |
1370  * |---------------------------------------------------------------|
1371  */
1372 int send_valid_pwd_request(int sock_fd)
1373 {
1374         basic_header hdr;
1375         int retval;
1376
1377         hdr.version = SECURITY_SERVER_MSG_VERSION;
1378         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_VALID_PWD_REQUEST;
1379         hdr.msg_len = 0;
1380
1381         /* Check poll */
1382         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1383         if(retval == SECURITY_SERVER_ERROR_POLL)
1384         {
1385                 SEC_SVR_DBG("%s", "poll() error");
1386                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1387                 goto error;
1388
1389         }
1390         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1391         {
1392                 SEC_SVR_DBG("%s", "poll() timeout");
1393                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1394                 goto error;
1395         }
1396
1397         /* Send to server */
1398         retval = write(sock_fd, &hdr, sizeof(hdr));
1399         if(retval < sizeof(hdr))
1400         {
1401                 /* Write error */
1402                 SEC_SVR_DBG("Error on write(): %d", retval);
1403                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1404                 goto error;
1405         }
1406         retval = SECURITY_SERVER_SUCCESS;
1407
1408 error:
1409         return retval;
1410 }
1411
1412 /* Send password set request message to security server *
1413  *
1414  * Message format
1415  *  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
1416  * |---------------------------------------------------------------|
1417  * | version=0x01  |MessageID=0x0f |       Message Length          |
1418  * |---------------------------------------------------------------|
1419  * |  cur_pwd_len  |  new_pwd_len  |                               |
1420  * |--------------------------------                               |
1421  * |                            cur pwd                            |
1422  * |---------------------------------------------------------------|
1423  * |                                                               |
1424  * |                            new pwd                            |
1425  * |                                                               |
1426  * |---------------------------------------------------------------|
1427  * |                         max attempts                          |
1428  * |---------------------------------------------------------------|
1429  * |                         valid days                            |
1430  * |---------------------------------------------------------------|
1431  */
1432 int send_set_pwd_request(int sock_fd,
1433                         const char*cur_pwd,
1434                         const char*new_pwd,
1435                         const unsigned int max_challenge,
1436                         const unsigned int valid_period_in_days)
1437 {
1438         basic_header hdr;
1439         int retval, total_length = 0, ptr;
1440         unsigned char *buf = NULL, cur_pwd_len, new_pwd_len;
1441
1442         if(cur_pwd == NULL)
1443                 cur_pwd_len = 0;
1444         else
1445                 cur_pwd_len = strlen(cur_pwd);
1446         new_pwd_len = strlen(new_pwd);
1447
1448         total_length += sizeof(hdr) + sizeof(char) + sizeof(char) + cur_pwd_len
1449                 + new_pwd_len + sizeof(unsigned int) + sizeof(unsigned int);
1450
1451         buf = malloc(total_length);
1452         if(buf == NULL)
1453         {
1454                 SEC_SVR_DBG("%s", "Error: failed to malloc()");
1455                 return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
1456         }
1457
1458         /* Assemble header */
1459         hdr.version = SECURITY_SERVER_MSG_VERSION;
1460         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_SET_PWD_REQUEST;
1461         hdr.msg_len = (unsigned short)total_length;
1462         memcpy(buf, &hdr, sizeof(hdr));
1463         ptr = sizeof(hdr);
1464         memcpy(buf + ptr, &cur_pwd_len, sizeof(char));
1465         ptr += sizeof(char);
1466         memcpy(buf + ptr, &new_pwd_len, sizeof(char));
1467         ptr += sizeof(char);
1468         if(cur_pwd != NULL)
1469         {
1470                 memcpy(buf + ptr, cur_pwd, cur_pwd_len);
1471                 ptr += cur_pwd_len;
1472         }
1473         memcpy(buf + ptr, new_pwd, new_pwd_len);
1474         ptr += new_pwd_len;
1475         memcpy(buf + ptr, &max_challenge, sizeof(unsigned int));
1476         ptr += sizeof(unsigned int);
1477         memcpy(buf + ptr, &valid_period_in_days, sizeof(unsigned int));
1478
1479         /* Check poll */
1480         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1481         if(retval == SECURITY_SERVER_ERROR_POLL)
1482         {
1483                 SEC_SVR_DBG("%s", "poll() error");
1484                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1485                 goto error;
1486
1487         }
1488         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1489         {
1490                 SEC_SVR_DBG("%s", "poll() timeout");
1491                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1492                 goto error;
1493         }
1494
1495         /* Send to server */
1496         retval = write(sock_fd, buf, total_length);
1497         if(retval < sizeof(buf))
1498         {
1499                 /* Write error */
1500                 SEC_SVR_DBG("Error on write(): %d", retval);
1501                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1502                 goto error;
1503         }
1504         retval = SECURITY_SERVER_SUCCESS;
1505
1506 error:
1507         if(buf != NULL)
1508                 free(buf);
1509         return retval;
1510 }
1511
1512 /* Send password validity change request message to security server *
1513  *
1514  * Message format
1515  *  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
1516  * |---------------------------------------------------------------|
1517  * | version=0x01  |MessageID=0x0f |       Message Length          |
1518  * |---------------------------------------------------------------|
1519  * |                         valid days                            |
1520  * |---------------------------------------------------------------|
1521  */
1522 int send_set_pwd_validity_request(int sock_fd, const unsigned int valid_period_in_days)
1523 {
1524     basic_header hdr;
1525     int retval, total_length = 0, ptr;
1526     unsigned char *buf = NULL;
1527
1528     total_length = sizeof(hdr) + sizeof(unsigned int);
1529
1530     buf = malloc(total_length);
1531     if(buf == NULL)
1532     {
1533         SEC_SVR_DBG("%s", "Error: failed to malloc()");
1534         return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
1535     }
1536
1537     /* Assemble header */
1538     hdr.version = SECURITY_SERVER_MSG_VERSION;
1539     hdr.msg_id = SECURITY_SERVER_MSG_TYPE_SET_PWD_VALIDITY_REQUEST;
1540     hdr.msg_len = (unsigned short)total_length;
1541     memcpy(buf, &hdr, sizeof(hdr));
1542     ptr = sizeof(hdr);
1543     memcpy(buf + ptr, &valid_period_in_days, sizeof(unsigned int));
1544
1545     /* Check poll */
1546     retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1547     if(retval == SECURITY_SERVER_ERROR_POLL)
1548     {
1549         SEC_SVR_DBG("%s", "poll() error");
1550         retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1551         goto error;
1552
1553     }
1554     if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1555     {
1556         SEC_SVR_DBG("%s", "poll() timeout");
1557         retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1558         goto error;
1559     }
1560
1561     /* Send to server */
1562     retval = write(sock_fd, buf, total_length);
1563     if(retval < sizeof(buf))
1564     {
1565         /* Write error */
1566         SEC_SVR_DBG("Error on write(): %d", retval);
1567         retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1568         goto error;
1569     }
1570     retval = SECURITY_SERVER_SUCCESS;
1571
1572 error:
1573     if(buf != NULL)
1574         free(buf);
1575     return retval;
1576 }
1577
1578 /* Send password max challenge request message to security server *
1579  *
1580  * Message format
1581  *  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
1582  * |---------------------------------------------------------------|
1583  * | version=0x01  |MessageID=0x0f |       Message Length          |
1584  * |---------------------------------------------------------------|
1585  * |                         max challenge                         |
1586  * |---------------------------------------------------------------|
1587  */
1588 int send_set_pwd_max_challenge_request(int sock_fd, const unsigned int max_challenge)
1589 {
1590     basic_header hdr;
1591     int retval, total_length = 0, ptr;
1592     unsigned char *buf = NULL;
1593
1594     total_length = sizeof(hdr) + sizeof(unsigned int);
1595
1596     buf = malloc(total_length);
1597     if(buf == NULL)
1598     {
1599         SEC_SVR_DBG("%s", "Error: failed to malloc()");
1600         return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
1601     }
1602
1603     /* Assemble header */
1604     hdr.version = SECURITY_SERVER_MSG_VERSION;
1605     hdr.msg_id = SECURITY_SERVER_MSG_TYPE_SET_PWD_MAX_CHALLENGE_REQUEST;
1606     hdr.msg_len = (unsigned short)total_length;
1607     memcpy(buf, &hdr, sizeof(hdr));
1608     ptr = sizeof(hdr);
1609     memcpy(buf + ptr, &max_challenge, sizeof(unsigned int));
1610
1611     /* Check poll */
1612     retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1613     if(retval == SECURITY_SERVER_ERROR_POLL)
1614     {
1615         SEC_SVR_DBG("%s", "poll() error");
1616         retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1617         goto error;
1618
1619     }
1620     if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1621     {
1622         SEC_SVR_DBG("%s", "poll() timeout");
1623         retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1624         goto error;
1625     }
1626
1627     /* Send to server */
1628     retval = write(sock_fd, buf, total_length);
1629     if(retval < sizeof(buf))
1630     {
1631         /* Write error */
1632         SEC_SVR_DBG("Error on write(): %d", retval);
1633         retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1634         goto error;
1635     }
1636     retval = SECURITY_SERVER_SUCCESS;
1637
1638 error:
1639     if(buf != NULL)
1640         free(buf);
1641     return retval;
1642 }
1643
1644 /* Send password reset request message to security server *
1645  *
1646  * Message format
1647  *  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
1648  * |---------------------------------------------------------------|
1649  * | version=0x01  |MessageID=0x11 |       Message Length          |
1650  * |---------------------------------------------------------------|
1651  * |  new_pwd_len  |                                               |
1652  * |---------------------------------------------------------------|
1653  * |                                                               |
1654  * |                            new pwd                            |
1655  * |                                                               |
1656  * |---------------------------------------------------------------|
1657  * |                         max attempts                          |
1658  * |---------------------------------------------------------------|
1659  * |                         valid days                            |
1660  * |---------------------------------------------------------------|
1661  */
1662 int send_reset_pwd_request(int sock_fd,
1663                         const char*new_pwd,
1664                         const unsigned int max_challenge,
1665                         const unsigned int valid_period_in_days)
1666 {
1667         basic_header hdr;
1668         int retval, total_length = 0, ptr;
1669         unsigned char *buf = NULL, new_pwd_len;
1670
1671         new_pwd_len = strlen(new_pwd);
1672
1673         total_length += sizeof(hdr) + sizeof(char) + new_pwd_len + sizeof(unsigned int) +
1674                 sizeof(unsigned int);
1675
1676         buf = malloc(total_length);
1677         if(buf == NULL)
1678         {
1679                 SEC_SVR_DBG("%s", "Error: failed to malloc()");
1680                 return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
1681         }
1682
1683         /* Assemble header */
1684         hdr.version = SECURITY_SERVER_MSG_VERSION;
1685         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_RESET_PWD_REQUEST;
1686         hdr.msg_len = (unsigned short)total_length;
1687         memcpy(buf, &hdr, sizeof(hdr));
1688         ptr = sizeof(hdr);
1689         memcpy(buf + ptr, &new_pwd_len, sizeof(char));
1690         ptr += sizeof(char);
1691         memcpy(buf + ptr, new_pwd, new_pwd_len);
1692         ptr += new_pwd_len;
1693         memcpy(buf + ptr, &max_challenge, sizeof(unsigned int));
1694         ptr += sizeof(unsigned int);
1695         memcpy(buf + ptr, &valid_period_in_days, sizeof(unsigned int));
1696
1697         /* Check poll */
1698         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1699         if(retval == SECURITY_SERVER_ERROR_POLL)
1700         {
1701                 SEC_SVR_DBG("%s", "poll() error");
1702                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1703                 goto error;
1704
1705         }
1706         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1707         {
1708                 SEC_SVR_DBG("%s", "poll() timeout");
1709                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1710                 goto error;
1711         }
1712
1713         /* Send to server */
1714         retval = write(sock_fd, buf, total_length);
1715         if(retval < sizeof(buf))
1716         {
1717                 /* Write error */
1718                 SEC_SVR_DBG("Error on write(): %d", retval);
1719                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1720                 goto error;
1721         }
1722         retval = SECURITY_SERVER_SUCCESS;
1723
1724 error:
1725         if(buf != NULL)
1726                 free(buf);
1727         return retval;
1728 }
1729
1730 /* Send password check request message to security server *
1731  *
1732  * Message format
1733  *  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
1734  * |---------------------------------------------------------------|
1735  * | version=0x01  |MessageID=0x13 |       Message Length          |
1736  * |---------------------------------------------------------------|
1737  * | challenge_len |                                               |
1738  * |---------------                                                |
1739  * |                          challenge                            |
1740  * |---------------------------------------------------------------|
1741  */
1742 int send_chk_pwd_request(int sock_fd, const char*challenge)
1743 {
1744         basic_header hdr;
1745         int retval, total_length = 0, ptr;
1746         unsigned char *buf = NULL, challenge_len;
1747
1748         challenge_len = strlen(challenge);
1749
1750         total_length += sizeof(hdr) + sizeof(char) + challenge_len;
1751
1752         buf = malloc(total_length);
1753         if(buf == NULL)
1754         {
1755                 SEC_SVR_DBG("%s", "Error: failed to malloc()");
1756                 return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
1757         }
1758
1759         /* Assemble header */
1760         hdr.version = SECURITY_SERVER_MSG_VERSION;
1761         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_CHK_PWD_REQUEST;
1762         hdr.msg_len = (unsigned short)total_length;
1763         memcpy(buf, &hdr, sizeof(hdr));
1764         ptr = sizeof(hdr);
1765         memcpy(buf + ptr, &challenge_len, sizeof(char));
1766         ptr += sizeof(char);
1767         memcpy(buf + ptr, challenge, challenge_len);
1768         ptr += sizeof(char);
1769
1770         /* Check poll */
1771         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1772         if(retval == SECURITY_SERVER_ERROR_POLL)
1773         {
1774                 SEC_SVR_DBG("%s", "poll() error");
1775                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1776                 goto error;
1777
1778         }
1779         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1780         {
1781                 SEC_SVR_DBG("%s", "poll() timeout");
1782                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1783                 goto error;
1784         }
1785
1786         /* Send to server */
1787         retval = write(sock_fd, buf, total_length);
1788         if(retval < sizeof(buf))
1789         {
1790                 /* Write error */
1791                 SEC_SVR_DBG("Error on write(): %d", retval);
1792                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1793                 goto error;
1794         }
1795         retval = SECURITY_SERVER_SUCCESS;
1796
1797 error:
1798         if(buf != NULL)
1799                 free(buf);
1800         return retval;
1801 }
1802
1803 /* Send password history set request message to security server *
1804  *
1805  * Message format
1806  *  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
1807  * |---------------------------------------------------------------|
1808  * | version=0x01  |MessageID=0x15 |       Message Length          |
1809  * |---------------------------------------------------------------|
1810  * | challenge_len |
1811  * |----------------
1812  */
1813 int send_set_pwd_history_request(int sock_fd, int num)
1814 {
1815         basic_header hdr;
1816         int retval, total_length = 0, ptr;
1817         unsigned char history;
1818         unsigned char buf[sizeof(hdr) + sizeof(history)];
1819
1820         total_length = sizeof(hdr) + sizeof(char);
1821         history = (unsigned char) num;
1822
1823         /* Assemble header */
1824         hdr.version = SECURITY_SERVER_MSG_VERSION;
1825         hdr.msg_id = SECURITY_SERVER_MSG_TYPE_SET_PWD_HISTORY_REQUEST;
1826         hdr.msg_len = (unsigned short)total_length;
1827         memcpy(buf, &hdr, sizeof(hdr));
1828         ptr = sizeof(hdr);
1829         memcpy(buf + ptr, &history, sizeof(char));
1830         ptr += sizeof(char);
1831
1832         /* Check poll */
1833         retval = check_socket_poll(sock_fd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1834         if(retval == SECURITY_SERVER_ERROR_POLL)
1835         {
1836                 SEC_SVR_DBG("%s", "poll() error");
1837                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1838                 goto error;
1839
1840         }
1841         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1842         {
1843                 SEC_SVR_DBG("%s", "poll() timeout");
1844                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1845                 goto error;
1846         }
1847
1848         /* Send to server */
1849         retval = write(sock_fd, buf, ptr);
1850         if(retval < sizeof(buf))
1851         {
1852                 /* Write error */
1853                 SEC_SVR_DBG("Error on write(): %d", retval);
1854                 retval =  SECURITY_SERVER_ERROR_SEND_FAILED;
1855                 goto error;
1856         }
1857         retval = SECURITY_SERVER_SUCCESS;
1858
1859 error:
1860         return retval;
1861 }
1862
1863 /* Receive request header */
1864 int recv_hdr(int client_sockfd, basic_header *basic_hdr)
1865 {
1866         int retval;
1867
1868         /* Check poll */
1869         retval = check_socket_poll(client_sockfd, POLLIN, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
1870         if(retval == SECURITY_SERVER_ERROR_POLL)
1871         {
1872                 SEC_SVR_DBG("%s", "poll() error");
1873                 return SECURITY_SERVER_ERROR_SOCKET;
1874         }
1875         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
1876         {
1877                 SEC_SVR_DBG("%s", "poll() timeout");
1878                 return SECURITY_SERVER_ERROR_TIMEOUT;
1879         }
1880
1881         /* Receive request header first */
1882         retval = read(client_sockfd, basic_hdr, sizeof(basic_header));
1883         if(retval < sizeof(basic_header))
1884         {
1885                 SEC_SVR_DBG("read failed. closing socket %d", retval);
1886                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1887         }
1888
1889         /* Validate header */
1890         retval = validate_header(*basic_hdr);
1891         return retval;
1892 }
1893
1894
1895 /* Receive check privilege request packet body */
1896 int recv_check_privilege_request(int sockfd, unsigned char *requested_cookie, int *requested_privilege)
1897 {
1898         int retval;
1899         retval = read(sockfd, requested_cookie, SECURITY_SERVER_COOKIE_LEN);
1900         if(retval < SECURITY_SERVER_COOKIE_LEN)
1901         {
1902                 SEC_SVR_DBG("Received cookie size is too small: %d", retval);
1903                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1904         }
1905
1906         retval = read(sockfd, requested_privilege, sizeof(int));
1907         if(retval < sizeof(int))
1908         {
1909                 SEC_SVR_DBG("privilege size is too small: %d", retval);
1910                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1911         }
1912         return SECURITY_SERVER_SUCCESS;
1913 }
1914
1915 /* Receive check privilege request packet body (new mode)*/
1916 int recv_check_privilege_new_request(int sockfd,
1917                                      unsigned char *requested_cookie,
1918                                      char *object_label,
1919                                      char *access_rights)
1920 {
1921         int retval;
1922         int olen, alen;
1923
1924         retval = read(sockfd, requested_cookie, SECURITY_SERVER_COOKIE_LEN);
1925         if(retval < SECURITY_SERVER_COOKIE_LEN)
1926         {
1927                 SEC_SVR_DBG("Received cookie size is too small: %d", retval);
1928                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1929         }
1930
1931         retval = read(sockfd, &olen, sizeof(int));
1932         if(retval < sizeof(int) || olen < 0 || olen > MAX_OBJECT_LABEL_LEN)
1933         {
1934                 SEC_SVR_DBG("error reading object_label len: %d", retval);
1935                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1936         }
1937
1938         retval = read(sockfd, &alen, sizeof(int));
1939         if(retval < sizeof(int) || alen < 0 || alen > MAX_MODE_STR_LEN)
1940         {
1941                 SEC_SVR_DBG("error reading access_rights len: %d", retval);
1942                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1943         }
1944
1945         retval = read(sockfd, object_label, olen);
1946         if(retval < olen)
1947         {
1948                 SEC_SVR_DBG("error reading object_label: %d", retval);
1949                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1950         }
1951         object_label[olen] = '\0';
1952
1953         retval = read(sockfd, access_rights, olen);
1954         if(retval < alen)
1955         {
1956                 SEC_SVR_DBG("error reading access_rights: %d", retval);
1957                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1958         }
1959         access_rights[alen] = '\0';
1960
1961         return SECURITY_SERVER_SUCCESS;
1962 }
1963
1964 /* Receive pid request packet body */
1965 int recv_pid_request(int sockfd, unsigned char *requested_cookie)
1966 {
1967         int retval;
1968         retval = read(sockfd, requested_cookie, SECURITY_SERVER_COOKIE_LEN);
1969         if(retval < SECURITY_SERVER_COOKIE_LEN)
1970         {
1971                 SEC_SVR_DBG("Received cookie size is too small: %d", retval);
1972                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1973         }
1974         return SECURITY_SERVER_SUCCESS;
1975 }
1976
1977 /* receiving cookie from package */
1978 int recv_smack_request(int sockfd, unsigned char *requested_cookie)
1979 {
1980         int retval;
1981         retval = read(sockfd, requested_cookie, SECURITY_SERVER_COOKIE_LEN);
1982         if(retval < SECURITY_SERVER_COOKIE_LEN)
1983         {
1984                 SEC_SVR_DBG("Received cookie size is too small: %d", retval);
1985                 return SECURITY_SERVER_ERROR_RECV_FAILED;
1986         }
1987         return SECURITY_SERVER_SUCCESS;
1988 }
1989
1990 /* Receive pid request packet body */
1991 int recv_launch_tool_request(int sockfd, int argc, char *argv[])
1992 {
1993         int retval, i, argv_len;
1994
1995         argv[0] = malloc(strlen(SECURITY_SERVER_DEBUG_TOOL_PATH) + 1);
1996         strncpy(argv[0], SECURITY_SERVER_DEBUG_TOOL_PATH, (strlen(SECURITY_SERVER_DEBUG_TOOL_PATH) + 1));
1997
1998         for(i=1;i<argc;i++)
1999         {
2000                 retval = read(sockfd, &argv_len, sizeof(int));
2001                 if(retval < sizeof(int))
2002                 {
2003                         SEC_SVR_DBG("Error: argv length recieve failed: %d", retval);
2004                         free_argv(argv, argc);
2005                         return SECURITY_SERVER_ERROR_RECV_FAILED;
2006                 }
2007
2008                 if(argv_len <= 0 || argv_len >= INT_MAX)
2009                 {
2010                         SEC_SVR_DBG("Error: argv length out of boundaries");
2011                         free_argv(argv, argc);
2012                         return SECURITY_SERVER_ERROR_RECV_FAILED;
2013                 }
2014
2015                 argv[i] = malloc(argv_len + 1);
2016                 if(argv[i] == NULL)
2017                 {
2018                         SEC_SVR_DBG("Error: malloc() failed: %d", retval);
2019                         free_argv(argv, argc);
2020                         return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
2021                 }
2022
2023                 memset(argv[i], 0x00, argv_len + 1);
2024                 retval = read(sockfd, argv[i], argv_len);
2025                 if(retval < argv_len)
2026                 {
2027                         SEC_SVR_DBG("Error: argv recieve failed: %d", retval);
2028                         free_argv(argv, argc);
2029                         return SECURITY_SERVER_ERROR_RECV_FAILED;
2030                 }
2031         }
2032
2033         return SECURITY_SERVER_SUCCESS;
2034 }
2035
2036 int recv_generic_response(int sockfd, response_header *hdr)
2037 {
2038         int retval;
2039
2040         /* Check poll */
2041         retval = check_socket_poll(sockfd, POLLIN, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
2042         if(retval == SECURITY_SERVER_ERROR_POLL)
2043         {
2044                 SEC_SVR_DBG("%s", "Client: poll() error");
2045                 return SECURITY_SERVER_ERROR_RECV_FAILED;
2046         }
2047         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
2048         {
2049                 SEC_SVR_DBG("%s", "Client: poll() timeout");
2050                 return SECURITY_SERVER_ERROR_RECV_FAILED;
2051         }
2052
2053         /* Receive response */
2054         retval = read(sockfd, hdr, sizeof(response_header));
2055         if(retval < sizeof(response_header) )
2056         {
2057                 /* Error on socket */
2058                 SEC_SVR_DBG("Client: Receive failed %d", retval);
2059                 return  SECURITY_SERVER_ERROR_RECV_FAILED;
2060         }
2061
2062         if(hdr->return_code != SECURITY_SERVER_RETURN_CODE_SUCCESS)
2063         {
2064                 SEC_SVR_DBG("Client: return code is not success: %d", hdr->return_code);
2065                 return return_code_to_error_code(hdr->return_code);
2066         }
2067         return SECURITY_SERVER_SUCCESS;
2068 }
2069
2070 int recv_get_gid_response(int sockfd, response_header *hdr, int *gid)
2071 {
2072         int retval;
2073
2074         retval = recv_generic_response(sockfd, hdr);
2075         if(retval != SECURITY_SERVER_SUCCESS)
2076                 return return_code_to_error_code(hdr->return_code);
2077
2078         retval = read(sockfd, gid, sizeof(int));
2079         if(retval < sizeof(int))
2080         {
2081                 /* Error on socket */
2082                 SEC_SVR_DBG("Receive failed %d", retval);
2083                 return  SECURITY_SERVER_ERROR_RECV_FAILED;
2084         }
2085         return SECURITY_SERVER_SUCCESS;
2086 }
2087
2088 int recv_get_object_name(int sockfd, response_header *hdr, char *object, int max_object_size)
2089 {
2090         int retval;
2091         char *local_obj_name = NULL;
2092
2093         /* Check poll */
2094         retval = check_socket_poll(sockfd, POLLIN, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
2095         if(retval == SECURITY_SERVER_ERROR_POLL)
2096         {
2097                 SEC_SVR_DBG("%s", "poll() error");
2098                 return SECURITY_SERVER_ERROR_RECV_FAILED;
2099         }
2100         if(retval == SECURITY_SERVER_ERROR_TIMEOUT)
2101         {
2102                 SEC_SVR_DBG("%s", "poll() timeout");
2103                 return SECURITY_SERVER_ERROR_RECV_FAILED;
2104         }
2105
2106         /* Read response */
2107         retval = read(sockfd, hdr, sizeof(response_header));
2108         if(retval < sizeof(hdr) )
2109         {
2110                 /* Error on socket */
2111                 SEC_SVR_DBG("cannot recv respons: %d", retval);
2112                 return SECURITY_SERVER_ERROR_RECV_FAILED;
2113         }
2114
2115         if(hdr->return_code == SECURITY_SERVER_RETURN_CODE_SUCCESS)
2116         {
2117                 if(max_object_size < hdr->basic_hdr.msg_len)
2118                 {
2119                         SEC_SVR_DBG("Object name is too small need %d bytes, but %d bytes", hdr->basic_hdr.msg_len, max_object_size);
2120                         return SECURITY_SERVER_ERROR_BUFFER_TOO_SMALL;
2121                 }
2122                 if(hdr->basic_hdr.msg_len > SECURITY_SERVER_MAX_OBJ_NAME)
2123                 {
2124                         SEC_SVR_DBG("Received object name is too big. %d", hdr->basic_hdr.msg_len);
2125                         return SECURITY_SERVER_ERROR_BAD_RESPONSE;
2126                 }
2127
2128                 local_obj_name = malloc(hdr->basic_hdr.msg_len + 1);
2129                 if(local_obj_name == NULL)
2130                 {
2131                         SEC_SVR_DBG("%s", "Out of memory error");
2132                         return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
2133                 }
2134
2135                 retval = read(sockfd, local_obj_name, hdr->basic_hdr.msg_len);
2136                 if(retval < (hdr->basic_hdr.msg_len))
2137                 {
2138                         /* Error on socket */
2139                         SEC_SVR_DBG("read() failed: %d", retval);
2140                         if(local_obj_name != NULL)
2141                                 free(local_obj_name);
2142                         return SECURITY_SERVER_ERROR_RECV_FAILED;
2143                 }
2144                 memcpy(object, local_obj_name, hdr->basic_hdr.msg_len);
2145                 object[hdr->basic_hdr.msg_len] = 0;
2146                 retval = SECURITY_SERVER_SUCCESS;
2147         }
2148         else
2149         {
2150                 SEC_SVR_DBG("Error received. return code: %d", hdr->return_code);
2151                 retval = return_code_to_error_code(hdr->return_code);
2152                 return retval;
2153         }
2154
2155         if(local_obj_name != NULL)
2156                 free(local_obj_name);
2157         return SECURITY_SERVER_SUCCESS;
2158 }
2159
2160 int recv_cookie(int sockfd, response_header *hdr, char *cookie)
2161 {
2162         int retval;
2163
2164         retval = recv_generic_response(sockfd, hdr);
2165         if(retval != SECURITY_SERVER_SUCCESS)
2166                 return return_code_to_error_code(hdr->return_code);
2167
2168         retval = read(sockfd, cookie, SECURITY_SERVER_COOKIE_LEN);
2169         if(retval < SECURITY_SERVER_COOKIE_LEN)
2170         {
2171                 /* Error on socket */
2172                 SEC_SVR_DBG("read() failed: %d", retval);
2173                 return SECURITY_SERVER_ERROR_RECV_FAILED;
2174         }
2175         return SECURITY_SERVER_SUCCESS;
2176 }
2177
2178 int recv_privilege_check_response(int sockfd, response_header *hdr)
2179 {
2180         int retval;
2181
2182         retval = recv_generic_response(sockfd, hdr);
2183         if(hdr->return_code != SECURITY_SERVER_RETURN_CODE_ACCESS_GRANTED &&
2184                         hdr->return_code != SECURITY_SERVER_RETURN_CODE_ACCESS_DENIED)
2185         {
2186                 SEC_SVR_DBG("response error: %d", hdr->return_code);
2187                 return return_code_to_error_code(hdr->return_code);
2188         }
2189         return SECURITY_SERVER_SUCCESS;
2190 }
2191
2192 int recv_privilege_check_new_response(int sockfd, response_header *hdr)
2193 {
2194         int retval;
2195
2196         retval = recv_generic_response(sockfd, hdr);
2197         if(hdr->return_code != SECURITY_SERVER_RETURN_CODE_ACCESS_GRANTED &&
2198                         hdr->return_code != SECURITY_SERVER_RETURN_CODE_ACCESS_DENIED)
2199         {
2200                 SEC_SVR_DBG("response error: %d", hdr->return_code);
2201                 return return_code_to_error_code(hdr->return_code);
2202         }
2203         return SECURITY_SERVER_SUCCESS;
2204 }
2205
2206 int recv_smack_response(int sockfd, response_header *hdr, char * label)
2207 {
2208         int retval;
2209
2210         retval = recv_generic_response(sockfd, hdr);
2211         if(retval != SECURITY_SERVER_SUCCESS)
2212                 return return_code_to_error_code(hdr->return_code);
2213
2214         retval = read(sockfd, label, SMACK_LABEL_LEN + 1);
2215         if(retval < sizeof(int))
2216         {
2217                 /* Error on socket */
2218                 SEC_SVR_DBG("Client: Receive failed %d", retval);
2219                 return  SECURITY_SERVER_ERROR_RECV_FAILED;
2220         }
2221         return SECURITY_SERVER_SUCCESS;
2222 }
2223
2224 int recv_pid_response(int sockfd, response_header *hdr, int *pid)
2225 {
2226         int retval;
2227
2228         retval = recv_generic_response(sockfd, hdr);
2229         if(retval != SECURITY_SERVER_SUCCESS)
2230                 return return_code_to_error_code(hdr->return_code);
2231
2232         retval = read(sockfd, pid, sizeof(int));
2233         if(retval < sizeof(int))
2234         {
2235                 /* Error on socket */
2236                 SEC_SVR_DBG("Client: Receive failed %d", retval);
2237                 return  SECURITY_SERVER_ERROR_RECV_FAILED;
2238         }
2239         return SECURITY_SERVER_SUCCESS;
2240 }
2241
2242 int recv_pwd_response(int sockfd, response_header *hdr,
2243         unsigned int *current_attempts,
2244         unsigned int *max_attempts,
2245         unsigned int *valid_secs)
2246 {
2247         int retval;
2248         *current_attempts = 0;
2249         *max_attempts = 0;
2250         *valid_secs = 0;
2251
2252         retval = recv_generic_response(sockfd, hdr);
2253
2254         switch(retval)
2255         {
2256                 case SECURITY_SERVER_ERROR_PASSWORD_EXIST:
2257                 case SECURITY_SERVER_ERROR_NO_PASSWORD:
2258                 case SECURITY_SERVER_ERROR_PASSWORD_MISMATCH:
2259                 case SECURITY_SERVER_ERROR_PASSWORD_RETRY_TIMER:
2260                 case SECURITY_SERVER_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED:
2261                 case SECURITY_SERVER_ERROR_PASSWORD_EXPIRED:
2262                 case SECURITY_SERVER_ERROR_PASSWORD_REUSED:
2263                 case SECURITY_SERVER_SUCCESS:
2264                         break;
2265                 default:
2266                         return return_code_to_error_code(hdr->return_code);
2267         }
2268
2269         retval = read(sockfd, current_attempts, sizeof(unsigned int));
2270         if(retval < sizeof(unsigned int))
2271         {
2272                 /* Error on socket */
2273                 SEC_SVR_DBG("Client: Receive failed %d", retval);
2274                 return  SECURITY_SERVER_ERROR_RECV_FAILED;
2275         }
2276         retval = read(sockfd, max_attempts, sizeof(unsigned int));
2277         if(retval < sizeof(unsigned int))
2278         {
2279                 /* Error on socket */
2280                 SEC_SVR_DBG("Client: Receive failed %d", retval);
2281                 return  SECURITY_SERVER_ERROR_RECV_FAILED;
2282         }
2283         retval = read(sockfd, valid_secs, sizeof(unsigned int));
2284         if(retval < sizeof(unsigned int))
2285         {
2286                 /* Error on socket */
2287                 SEC_SVR_DBG("Client: Receive failed %d", retval);
2288                 return  SECURITY_SERVER_ERROR_RECV_FAILED;
2289         }
2290
2291     //if come here there were no errors
2292     return SECURITY_SERVER_SUCCESS;
2293 }
2294
2295 /* Authenticate client application *
2296  * Currently it only gets peer's credential information only *
2297  * If we need, we can extend in the futer */
2298 int authenticate_client_application(int sockfd, int *pid, int *uid)
2299 {
2300         int retval = 0;
2301         struct ucred cr;
2302         unsigned int cl = sizeof(cr);
2303
2304         /* get PID of socket peer */
2305         if(getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) != 0)
2306         {
2307                 retval = SECURITY_SERVER_ERROR_SOCKET;
2308                 SEC_SVR_DBG("%s", "getsockopt failed");
2309                 *pid = 0;
2310                 goto error;
2311         }
2312         *pid = cr.pid;
2313         *uid = cr.uid;
2314
2315         /* Authenticate client that it's real client application */
2316         /* TBA */
2317
2318 error:
2319         return retval;
2320 }
2321
2322 /* Checking client is pre-defined middleware daemons *
2323  * Check privilege API is only allowed to middleware daemons *
2324  * cmd line list of middleware daemons are listed in
2325  * /usr/share/security-server/mw-list */
2326 int search_middleware_cmdline(char *cmdline)
2327 {
2328         FILE *fp = NULL;
2329         int ret;
2330         char middleware[SECURITY_SERVER_MAX_PATH_LEN];
2331
2332         /* Open the list file */
2333         fp = fopen(SECURITY_SERVER_MIDDLEWARE_LIST_PATH, "r");
2334         if(fp == NULL)
2335         {
2336                 /* error on file */
2337                 SEC_SVR_DBG("%s", "Error oening mw-list file");
2338                 return SECURITY_SERVER_ERROR_FILE_OPERATION;
2339         }
2340
2341         /* Search each line */
2342         ret = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
2343         while(fgets(middleware, SECURITY_SERVER_MAX_PATH_LEN, fp) != NULL)
2344         {
2345                 if(strncmp(middleware, cmdline, strlen(middleware)-1) == 0)
2346                 {
2347                         /* found */
2348                         SEC_SVR_DBG("%s", "found matching cmd line");
2349                         ret = SECURITY_SERVER_SUCCESS;
2350                         break;
2351                 }
2352
2353         }
2354         if(fp != NULL)
2355                 fclose(fp);
2356         return ret;
2357 }
2358
2359 /* Authenticate the application is middleware daemon
2360  * The middleware must run as root (or middleware user) and the cmd line must be
2361  * pre listed for authentication to succeed */
2362 int authenticate_client_middleware(int sockfd, int *pid)
2363 {
2364         int retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
2365         struct ucred cr;
2366         unsigned int cl = sizeof(cr);
2367         char *cmdline = NULL;
2368         struct passwd pw, *ppw;
2369         size_t buf_size;
2370         char *buf;
2371         static uid_t middleware_uid = 0;
2372
2373         *pid = 0;
2374
2375         /* get PID of socket peer */
2376         if(getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) != 0)
2377         {
2378                 retval = SECURITY_SERVER_ERROR_SOCKET;
2379                 SEC_SVR_DBG("%s", "Error on getsockopt");
2380                 goto error;
2381         }
2382
2383         if (!middleware_uid)
2384         {
2385                 buf_size = sysconf(_SC_GETPW_R_SIZE_MAX);
2386                 if (buf_size == -1)
2387                         buf_size = 1024;
2388
2389                 buf = malloc(buf_size);
2390
2391                 /* This test isn't essential, skip it in case of error */
2392                 if (buf) {
2393                         if (getpwnam_r(SECURITY_SERVER_MIDDLEWARE_USER, &pw, buf, buf_size, &ppw) == 0 && ppw)
2394                                 middleware_uid = pw.pw_uid;
2395
2396                         free(buf);
2397                 }
2398         }
2399
2400         /* Middleware services need to run as root or middleware/app user */
2401         if(cr.uid != 0 && cr.uid != middleware_uid)
2402         {
2403                 retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
2404                 SEC_SVR_DBG("Non root process has called API: %d", cr.uid);
2405                 goto error;
2406         }
2407
2408         /* Read command line of the PID from proc fs */
2409         cmdline = read_cmdline_from_proc(cr.pid);
2410         if(cmdline  == NULL)
2411         {
2412                 /* It's weired. no file in proc file system, */
2413                 retval = SECURITY_SERVER_ERROR_FILE_OPERATION;
2414                 SEC_SVR_DBG("Error on opening /proc/%d/cmdline", cr.pid);
2415                 goto error;
2416         }
2417
2418         /* Search cmdline of the peer that is really middleware executable */
2419         retval = search_middleware_cmdline(cmdline);
2420         *pid = cr.pid;
2421
2422 error:
2423         if(cmdline != NULL)
2424                 free(cmdline);
2425
2426         return retval;
2427 }
2428
2429 /* Get app PID from socked and read its privilege (GID) list
2430  * from /proc/<PDI>/status.
2431  *
2432  * param 1: socket descriptor
2433  * param 2: pointer for hold returned array
2434  *
2435  * ret: size of array or -1 in case of error
2436  *
2437  * Notice that user must free space allocated in this function and
2438  * returned by second parameter (int * privileges)
2439  * */
2440 int get_client_gid_list(int sockfd, int ** privileges)
2441 {
2442     int ret;
2443     //for read socket options
2444     struct ucred socopt;
2445     unsigned int socoptSize = sizeof(socopt);
2446     //privileges to be returned
2447     int privilegesSize;
2448     //buffer for store /proc/<PID>/status filepath
2449     const int PATHSIZE = 24;
2450     char path[PATHSIZE];
2451     //file pointer
2452     FILE * fp = NULL;
2453     //buffer for filelines
2454     const int LINESIZE = 128;
2455     char fileLine[LINESIZE];
2456     //for parsing file
2457     char delim[] = ": ";
2458     char * token = NULL;
2459
2460
2461     //clear pointer
2462     *privileges = NULL;
2463
2464     //read socket options
2465     ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &socopt, &socoptSize);
2466     if(ret != 0)
2467     {
2468         SEC_SVR_DBG("%s", "Error on getsockopt");
2469         return -1;
2470     }
2471
2472     //now we have PID in sockopt.pid
2473     bzero(path, PATHSIZE);
2474     snprintf(path, PATHSIZE, "/proc/%d/status", socopt.pid);
2475
2476     fp = fopen(path, "r");
2477     if(fp == NULL)
2478     {
2479         SEC_SVR_DBG("%s", "Error on fopen");
2480         return -1;
2481     }
2482
2483     bzero(fileLine, LINESIZE);
2484
2485     //search for line beginning with "Groups:"
2486     while(strncmp(fileLine, "Groups:", 7) != 0)
2487     {
2488         ret = fgets(fileLine, LINESIZE, fp);
2489         if(ret == NULL)
2490         {
2491             SEC_SVR_DBG("%s", "Error on fgets");
2492             fclose(fp);
2493             return -1;
2494         }
2495     }
2496
2497     fclose(fp);
2498     
2499     //now we have "Groups:" line in fileLine[]
2500     ret = 0;
2501     token = strtok(fileLine, delim);
2502     while(token = strtok(NULL, delim))
2503     {
2504         //add found GID
2505         if(*privileges == NULL)
2506         {
2507             //first GID on list
2508             *privileges = (int *)malloc(sizeof(int) * 1);
2509             if(*privileges == NULL)
2510             {
2511                 SEC_SVR_DBG("%s", "Error on malloc");
2512                 return -1;
2513             }
2514             (*privileges)[0] = atoi(token);
2515         }
2516         else
2517         {
2518             *privileges = realloc(*privileges, sizeof(int) * (ret + 1));
2519             (*privileges)[ret] = atoi(token);
2520         }
2521
2522         ret++;
2523     }
2524
2525     //check if we found any GIDs for process
2526     if(*privileges == NULL)
2527     {
2528         SEC_SVR_DBG("%s %d", "No GIDs found for PID:", socopt.pid);
2529     }
2530     else
2531     {
2532         SEC_SVR_DBG("%s %d", "Number of GIDs found:", ret);
2533     }
2534
2535     return ret;
2536 }
2537
2538 /* Authenticate the application is middleware daemon
2539  * The middleware must run as root and the cmd line must be pre listed */
2540 int authenticate_developer_shell(int sockfd)
2541 {
2542         int retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
2543         struct ucred cr;
2544         unsigned int cl = sizeof(cr);
2545         char *cmdline = NULL;
2546
2547         /* get PID of socket peer */
2548         if(getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &cl) != 0)
2549         {
2550                 retval = SECURITY_SERVER_ERROR_SOCKET;
2551                 SEC_SVR_DBG("%s", "Error on getsockopt");
2552                 goto error;
2553         }
2554
2555         /* All middlewares will run as root */
2556         if(cr.uid != SECURITY_SERVER_DEVELOPER_UID)
2557         {
2558                 retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
2559                 SEC_SVR_DBG("Non root process has called API: %d", cr.uid);
2560                 goto error;
2561         }
2562
2563         /* Read command line of the PID from proc fs */
2564         cmdline = read_cmdline_from_proc(cr.pid);
2565         if(cmdline  == NULL)
2566         {
2567                 /* It's weired. no file in proc file system, */
2568                 retval = SECURITY_SERVER_ERROR_FILE_OPERATION;
2569                 SEC_SVR_DBG("Error on opening /proc/%d/cmdline", cr.pid);
2570                 goto error;
2571         }
2572
2573         /* Search cmdline of the peer that is really debug tool */
2574         if(strncmp(cmdline, SECURITY_SERVER_DEBUG_TOOL_PATH, strlen(SECURITY_SERVER_DEBUG_TOOL_PATH)) != 0)
2575         {
2576                 SEC_SVR_DBG("Error: Wrong cmdline [%s]", cmdline);
2577                 retval = SECURITY_SERVER_ERROR_AUTHENTICATION_FAILED;
2578                 goto error;
2579         }
2580         retval = SECURITY_SERVER_SUCCESS;
2581         SEC_SVR_DBG("%s", "Client Authenticated");
2582
2583 error:
2584         if(cmdline != NULL)
2585                 free(cmdline);
2586
2587         return retval;
2588 }
2589
2590 int free_argv(char **argv, int argc)
2591 {
2592         int i;
2593         if(argv == NULL)
2594         {
2595                 SEC_SVR_DBG("%s", "Cannot free NULL pointer");
2596                 return SECURITY_SERVER_ERROR_INPUT_PARAM;
2597         }
2598         for (i=0;i<argc;i++)
2599         {
2600                 if(argv[i] != NULL)
2601                         free(argv[i]);
2602         }
2603         free(argv);
2604         return SECURITY_SERVER_SUCCESS;
2605 }
2606