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