4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd All Rights Reserved
6 * Contact: Bumjin Im <bj.im@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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
26 #include <sys/socket.h>
27 #include <sys/types.h>
28 #include <sys/smack.h>
34 #include "security-server-common.h"
35 #include "security-server-cookie.h"
36 #include "security-server-comm.h"
37 #include "security-server-util.h"
38 #include "security-server.h"
41 /* Get all cookie info response *
44 * 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
45 * |---------------------------------------------------------------|
46 * | version=0x01 |MessageID=0x52 | Message Length |
47 * |---------------------------------------------------------------|
48 * | return code | tot # of cooks (32bit) |
49 * |---------------------------------------------------------------|
50 * | cont'd... | 1st cmdline_len (32bit) |
51 * |---------------------------------------------------------------|
52 * | cont'd... | 1st permission_len (32bit) |
53 * ----------------------------------------------------------------|
58 * |---------------------------------------------------------------|
60 * |---------------------------------------------------------------|
61 * | 1st cmdline (string) |
62 * |---------------------------------------------------------------|
64 * |---------------------------------------------------------------|
66 * |---------------------------------------------------------------|
68 * |---------------------------------------------------------------|
69 * | 2nd cmdline_len (32bit) |
70 * |---------------------------------------------------------------|
71 * | 2nd permission_len (32bit) |
72 * |---------------------------------------------------------------|
76 * |---------------------------------------------------------------|
77 * | 2nd PID (32 bit) |
78 * |---------------------------------------------------------------|
79 * | 2nd cmdline (string) |
80 * |---------------------------------------------------------------|
82 * |---------------------------------------------------------------|
84 * |---------------------------------------------------------------|
86 * |---------------------------------------------------------------|
92 unsigned char * get_all_cookie_info(cookie_list *list, int *size)
94 cookie_list *current = list;
95 int ptr, total_num, total_size, tempnum, i;
96 unsigned char *buf = NULL, *tempptr = NULL;
99 total_size = sizeof(hdr) + sizeof(int);
101 buf = malloc(total_size); /* header size */
102 ptr = sizeof(hdr) + sizeof(int);
103 total_num = 0; /* Total # of cookies initial value */
105 while(current != NULL)
107 current = garbage_collection(current);
112 total_size += sizeof(int) + sizeof(int) + SECURITY_SERVER_COOKIE_LEN + sizeof(int) + current->path_len + (current->permission_len * sizeof(int));
113 tempptr = realloc(buf, total_size);
116 SEC_SVR_DBG("%s", "Out of memory");
121 tempnum = current->path_len;
122 memcpy(buf+ptr, &tempnum, sizeof(int));
124 tempnum = current->permission_len;
125 memcpy(buf+ptr, &tempnum, sizeof(int));
127 memcpy(buf+ptr, current->cookie, SECURITY_SERVER_COOKIE_LEN);
128 ptr += SECURITY_SERVER_COOKIE_LEN;
129 tempnum = current->pid;
130 memcpy(buf+ptr, &tempnum, sizeof(int));
132 memcpy(buf+ptr, current->path, current->path_len);
133 ptr += current->path_len;
135 for(i=0;i<current->permission_len;i++)
137 tempnum = current->permissions[i];
138 memcpy(buf+ptr, &tempnum, sizeof(int));
141 current = current->next;
144 if(total_size > 65530)
146 SEC_SVR_DBG("Packet too big. message length overflow: %d", total_size);
151 hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
152 hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_GET_ALL_COOKIES_RESPONSE;
153 hdr.basic_hdr.msg_len =(unsigned short)( total_size - sizeof(hdr));
154 hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
155 memcpy(buf, &hdr, sizeof(hdr));
157 memcpy(buf + sizeof(hdr), &tempnum, sizeof(int));
162 int send_all_cookie_info(const unsigned char *buf, int size, int sockfd)
166 ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
167 if(ret == SECURITY_SERVER_ERROR_POLL)
169 SEC_SVR_DBG("%s", "poll() error");
170 return SECURITY_SERVER_ERROR_SEND_FAILED;
172 if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
174 SEC_SVR_DBG("%s", "poll() timeout");
175 return SECURITY_SERVER_ERROR_SEND_FAILED;
179 ret = TEMP_FAILURE_RETRY(write(sockfd, buf, size));
182 return SECURITY_SERVER_ERROR_SEND_FAILED;
183 return SECURITY_SERVER_SUCCESS;
186 /* Get one cookie info response *
189 * 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
190 * |---------------------------------------------------------------|
191 * | version=0x01 |MessageID=0x54 | Message Length |
192 * |---------------------------------------------------------------|
193 * | return code | cmdline_len (32bit)t) |
194 * |---------------------------------------------------------------|
195 * | cont'd... | permission_len (32bit) |
196 * ----------------------------------------------------------------|
198 * |---------------- |
201 * |---------------------------------------------------------------|
203 * |---------------------------------------------------------------|
204 * | cmdline (string) |
205 * |---------------------------------------------------------------|
207 * |---------------------------------------------------------------|
209 * |---------------------------------------------------------------|
211 * |---------------------------------------------------------------|
213 int send_one_cookie_info(const cookie_list *list, int sockfd)
215 unsigned char *buf = NULL;
217 int total_size, ptr = 0, tempnum, ret, i;
219 total_size = sizeof(hdr) + sizeof(int) + sizeof(int) + SECURITY_SERVER_COOKIE_LEN + sizeof(int) + list->path_len + (list->permission_len * sizeof(int));
220 buf = malloc(total_size);
223 SEC_SVR_DBG("%s", "Out of memory");
224 return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
227 hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
228 hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_GET_COOKIEINFO_RESPONSE;
229 hdr.basic_hdr.msg_len =sizeof(int) + sizeof(int) + SECURITY_SERVER_COOKIE_LEN + sizeof(int) + list->path_len + (list->permission_len * sizeof(int));
230 hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
231 memcpy(buf, &hdr, sizeof(hdr));
234 tempnum = list->path_len;
235 memcpy(buf+ptr, &tempnum, sizeof(int));
237 tempnum = list->permission_len;
238 memcpy(buf+ptr, &tempnum, sizeof(int));
240 memcpy(buf+ptr, list->cookie, SECURITY_SERVER_COOKIE_LEN);
241 ptr += SECURITY_SERVER_COOKIE_LEN;
243 memcpy(buf+ptr, &tempnum, sizeof(int));
245 memcpy(buf+ptr, list->path, list->path_len);
246 ptr += list->path_len;
248 for(i=0;i<list->permission_len;i++)
250 tempnum = list->permissions[i];
251 memcpy(buf+ptr, &tempnum, sizeof(int));
255 ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
256 if(ret == SECURITY_SERVER_ERROR_POLL)
258 SEC_SVR_DBG("%s", "poll() error");
260 return SECURITY_SERVER_ERROR_SEND_FAILED;
262 if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
264 SEC_SVR_DBG("%s", "poll() timeout");
266 return SECURITY_SERVER_ERROR_SEND_FAILED;
270 ret = TEMP_FAILURE_RETRY(write(sockfd, buf, total_size));
273 return SECURITY_SERVER_ERROR_SEND_FAILED;
274 return SECURITY_SERVER_SUCCESS;
277 int util_process_all_cookie(int sockfd, cookie_list* list)
279 unsigned char *buf = NULL;
281 buf = get_all_cookie_info(list, &ret);
284 return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
287 ret = send_all_cookie_info(buf, ret, sockfd);
293 int util_process_cookie_from_pid(int sockfd, cookie_list* list)
296 cookie_list *result = NULL;
298 ret = TEMP_FAILURE_RETRY(read(sockfd, &pid, sizeof(int)));
299 if(ret < (int)sizeof(int))
301 SEC_SVR_DBG("Received cookie size is too small: %d", ret);
302 return SECURITY_SERVER_ERROR_RECV_FAILED;
306 SEC_SVR_DBG("%s", "ERROR: Default cookie is not allowed to be retrieved");
307 ret = send_generic_response(sockfd, SECURITY_SERVER_MSG_TYPE_GET_COOKIEINFO_RESPONSE,
308 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
309 if(ret != SECURITY_SERVER_SUCCESS)
311 SEC_SVR_DBG("ERROR: Cannot send generic response: %d", ret);
314 result = search_cookie_from_pid(list, pid);
317 ret = send_generic_response(sockfd, SECURITY_SERVER_MSG_TYPE_GET_COOKIEINFO_RESPONSE,
318 SECURITY_SERVER_RETURN_CODE_NO_SUCH_COOKIE);
319 if(ret != SECURITY_SERVER_SUCCESS)
321 SEC_SVR_DBG("ERROR: Cannot send generic response: %d", ret);
326 ret = send_one_cookie_info(result, sockfd);
327 if(ret != SECURITY_SERVER_SUCCESS)
329 SEC_SVR_DBG("ERROR: Cannot send cookie info response: %d", ret);
336 int util_process_cookie_from_cookie(int sockfd, cookie_list* list)
338 unsigned char cookie[SECURITY_SERVER_COOKIE_LEN];
340 int privileges[] = { 0 }; //only one privilege to check - root
341 cookie_list *result = NULL;
343 ret = TEMP_FAILURE_RETRY(read(sockfd, cookie, SECURITY_SERVER_COOKIE_LEN));
344 if(ret < SECURITY_SERVER_COOKIE_LEN)
346 SEC_SVR_DBG("Received cookie size is too small: %d", ret);
347 return SECURITY_SERVER_ERROR_RECV_FAILED;
349 result = search_cookie(list, cookie, privileges, 1);
352 ret = send_generic_response(sockfd, SECURITY_SERVER_MSG_TYPE_GET_COOKIEINFO_RESPONSE,
353 SECURITY_SERVER_RETURN_CODE_NO_SUCH_COOKIE);
354 if(ret != SECURITY_SERVER_SUCCESS)
356 SEC_SVR_DBG("ERROR: Cannot send generic response: %d", ret);
361 ret = send_one_cookie_info(result, sockfd);
362 if(ret != SECURITY_SERVER_SUCCESS)
364 SEC_SVR_DBG("ERROR: Cannot send cookie info response: %d", ret);
371 int util_smack_label_is_valid(const char *smack_label){
374 if (!smack_label || smack_label[0] == '\0' || smack_label[0] == '-')
377 for (i = 0; smack_label[i]; ++i) {
378 if (i >= SMACK_LABEL_LEN)
380 switch (smack_label[i]) {
395 // TODO replace it with SEC_SVR_DBG when master is merged
396 SEC_SVR_DBG("ERROR: Invalid Smack label: %s", smack_label);