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