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 * @buffer output buffer
42 * @position target position in output buffer
44 * @len source data length
46 static void append_to_buffer(unsigned char *buffer, int* position, const void* source, size_t len) {
48 SEC_SVR_DBG("Appending nothing.");
51 memcpy(buffer + *position, source, len);
55 static void append_cookie(unsigned char *buffer, int* position, const cookie_list* cookie) {
57 int path_len = cookie->path ? strlen(cookie->path) : 0;
59 append_to_buffer(buffer, position, &path_len, sizeof(int));
60 append_to_buffer(buffer, position, &cookie->permission_len, sizeof(int));
61 append_to_buffer(buffer, position, &cookie->cookie, SECURITY_SERVER_COOKIE_LEN);
62 append_to_buffer(buffer, position, &cookie->pid, sizeof(pid_t));
63 append_to_buffer(buffer, position, &cookie->path, path_len);
65 for(i=0;i<cookie->permission_len;++i)
66 append_to_buffer(buffer, position, &cookie->permissions[i], sizeof(int));
69 /* Get all cookie info response *
72 * 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
73 * |---------------------------------------------------------------|
74 * | version=0x01 |MessageID=0x52 | Message Length |
75 * |---------------------------------------------------------------|
76 * | return code | tot # of cooks (32bit) |
77 * |---------------------------------------------------------------|
78 * | cont'd... | 1st cmdline_len (32bit) |
79 * |---------------------------------------------------------------|
80 * | cont'd... | 1st permission_len (32bit) |
81 * ----------------------------------------------------------------|
86 * |---------------------------------------------------------------|
88 * |---------------------------------------------------------------|
89 * | 1st cmdline (string) |
90 * |---------------------------------------------------------------|
92 * |---------------------------------------------------------------|
94 * |---------------------------------------------------------------|
96 * |---------------------------------------------------------------|
97 * | 2nd cmdline_len (32bit) |
98 * |---------------------------------------------------------------|
99 * | 2nd permission_len (32bit) |
100 * |---------------------------------------------------------------|
104 * |---------------------------------------------------------------|
105 * | 2nd PID (32 bit) |
106 * |---------------------------------------------------------------|
107 * | 2nd cmdline (string) |
108 * |---------------------------------------------------------------|
110 * |---------------------------------------------------------------|
112 * |---------------------------------------------------------------|
114 * |---------------------------------------------------------------|
120 unsigned char * get_all_cookie_info(cookie_list *list, int *size)
122 cookie_list *current = list;
123 int ptr, total_num, total_size, path_len;
124 unsigned char *buf = NULL, *tempptr = NULL;
127 total_size = sizeof(hdr) + sizeof(int);
129 buf = malloc(total_size); /* header size */
130 ptr = sizeof(hdr) + sizeof(int);
131 total_num = 0; /* Total # of cookies initial value */
133 while(current != NULL)
135 current = garbage_collection(current);
140 path_len = current->path ? strlen(current->path) : 0;
141 total_size += sizeof(int) + sizeof(int) + SECURITY_SERVER_COOKIE_LEN + sizeof(pid_t) + path_len + (current->permission_len * sizeof(int));
142 tempptr = realloc(buf, total_size);
145 SEC_SVR_DBG("%s", "Out of memory");
150 append_cookie(buf, &ptr, current);
151 current = current->next;
154 if(total_size > 65530)
156 SEC_SVR_DBG("Packet too big. message length overflow: %d", total_size);
161 hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
162 hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_GET_ALL_COOKIES_RESPONSE;
163 hdr.basic_hdr.msg_len =(unsigned short)( total_size - sizeof(hdr));
164 hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
166 // reset buffer position to the beginning of buffer and insert header
168 append_to_buffer(buf, &ptr, &hdr, sizeof(hdr));
169 append_to_buffer(buf, &ptr, &total_num, sizeof(total_num));
174 int send_all_cookie_info(const unsigned char *buf, int size, int sockfd)
178 ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
179 if(ret == SECURITY_SERVER_ERROR_POLL)
181 SEC_SVR_DBG("%s", "poll() error");
182 return SECURITY_SERVER_ERROR_SEND_FAILED;
184 if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
186 SEC_SVR_DBG("%s", "poll() timeout");
187 return SECURITY_SERVER_ERROR_SEND_FAILED;
191 ret = TEMP_FAILURE_RETRY(write(sockfd, buf, size));
194 return SECURITY_SERVER_ERROR_SEND_FAILED;
195 return SECURITY_SERVER_SUCCESS;
198 /* Get one cookie info response *
201 * 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
202 * |---------------------------------------------------------------|
203 * | version=0x01 |MessageID=0x54 | Message Length |
204 * |---------------------------------------------------------------|
205 * | return code | cmdline_len (32bit)t) |
206 * |---------------------------------------------------------------|
207 * | cont'd... | permission_len (32bit) |
208 * ----------------------------------------------------------------|
210 * |---------------- |
213 * |---------------------------------------------------------------|
215 * |---------------------------------------------------------------|
216 * | cmdline (string) |
217 * |---------------------------------------------------------------|
219 * |---------------------------------------------------------------|
221 * |---------------------------------------------------------------|
223 * |---------------------------------------------------------------|
225 int send_one_cookie_info(const cookie_list *list, int sockfd)
227 unsigned char *buf = NULL;
229 int total_size, ptr = 0, ret, path_len;
231 path_len = list->path ? strlen(list->path) : 0;
233 total_size = sizeof(hdr) + sizeof(int) + sizeof(int) + SECURITY_SERVER_COOKIE_LEN + sizeof(pid_t) + path_len + (list->permission_len * sizeof(int));
234 buf = malloc(total_size);
237 SEC_SVR_DBG("%s", "Out of memory");
238 return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
241 hdr.basic_hdr.version = SECURITY_SERVER_MSG_VERSION;
242 hdr.basic_hdr.msg_id = SECURITY_SERVER_MSG_TYPE_GET_COOKIEINFO_RESPONSE;
243 hdr.basic_hdr.msg_len =sizeof(int) + sizeof(int) + SECURITY_SERVER_COOKIE_LEN + sizeof(pid_t) + path_len + (list->permission_len * sizeof(int));
244 hdr.return_code = SECURITY_SERVER_RETURN_CODE_SUCCESS;
247 append_to_buffer(buf, &ptr, &hdr, sizeof(hdr));
249 append_cookie(buf, &ptr, list);
251 ret = check_socket_poll(sockfd, POLLOUT, SECURITY_SERVER_SOCKET_TIMEOUT_MILISECOND);
252 if(ret == SECURITY_SERVER_ERROR_POLL)
254 SEC_SVR_DBG("%s", "poll() error");
256 return SECURITY_SERVER_ERROR_SEND_FAILED;
258 if(ret == SECURITY_SERVER_ERROR_TIMEOUT)
260 SEC_SVR_DBG("%s", "poll() timeout");
262 return SECURITY_SERVER_ERROR_SEND_FAILED;
266 ret = TEMP_FAILURE_RETRY(write(sockfd, buf, total_size));
269 return SECURITY_SERVER_ERROR_SEND_FAILED;
270 return SECURITY_SERVER_SUCCESS;
273 int util_process_all_cookie(int sockfd, cookie_list* list)
275 unsigned char *buf = NULL;
277 buf = get_all_cookie_info(list, &ret);
280 return SECURITY_SERVER_ERROR_OUT_OF_MEMORY;
283 ret = send_all_cookie_info(buf, ret, sockfd);
289 int util_process_cookie_from_pid(int sockfd, cookie_list* list)
292 cookie_list *result = NULL;
294 ret = TEMP_FAILURE_RETRY(read(sockfd, &pid, sizeof(int)));
295 if(ret < (int)sizeof(int))
297 SEC_SVR_DBG("Received cookie size is too small: %d", ret);
298 return SECURITY_SERVER_ERROR_RECV_FAILED;
302 SEC_SVR_DBG("%s", "ERROR: Default cookie is not allowed to be retrieved");
303 ret = send_generic_response(sockfd, SECURITY_SERVER_MSG_TYPE_GET_COOKIEINFO_RESPONSE,
304 SECURITY_SERVER_RETURN_CODE_BAD_REQUEST);
305 if(ret != SECURITY_SERVER_SUCCESS)
307 SEC_SVR_DBG("ERROR: Cannot send generic response: %d", ret);
310 result = search_cookie_from_pid(list, pid);
313 ret = send_generic_response(sockfd, SECURITY_SERVER_MSG_TYPE_GET_COOKIEINFO_RESPONSE,
314 SECURITY_SERVER_RETURN_CODE_NO_SUCH_COOKIE);
315 if(ret != SECURITY_SERVER_SUCCESS)
317 SEC_SVR_DBG("ERROR: Cannot send generic response: %d", ret);
322 ret = send_one_cookie_info(result, sockfd);
323 if(ret != SECURITY_SERVER_SUCCESS)
325 SEC_SVR_DBG("ERROR: Cannot send cookie info response: %d", ret);
332 int util_process_cookie_from_cookie(int sockfd, cookie_list* list)
334 unsigned char cookie[SECURITY_SERVER_COOKIE_LEN];
336 int privileges[] = { 0 }; //only one privilege to check - root
337 cookie_list *result = NULL;
339 ret = TEMP_FAILURE_RETRY(read(sockfd, cookie, SECURITY_SERVER_COOKIE_LEN));
340 if(ret < SECURITY_SERVER_COOKIE_LEN)
342 SEC_SVR_DBG("Received cookie size is too small: %d", ret);
343 return SECURITY_SERVER_ERROR_RECV_FAILED;
345 result = search_cookie(list, cookie, privileges, 1);
348 ret = send_generic_response(sockfd, SECURITY_SERVER_MSG_TYPE_GET_COOKIEINFO_RESPONSE,
349 SECURITY_SERVER_RETURN_CODE_NO_SUCH_COOKIE);
350 if(ret != SECURITY_SERVER_SUCCESS)
352 SEC_SVR_DBG("ERROR: Cannot send generic response: %d", ret);
357 ret = send_one_cookie_info(result, sockfd);
358 if(ret != SECURITY_SERVER_SUCCESS)
360 SEC_SVR_DBG("ERROR: Cannot send cookie info response: %d", ret);
367 int util_smack_label_is_valid(const char *smack_label){
370 if (!smack_label || smack_label[0] == '\0' || smack_label[0] == '-')
373 for (i = 0; smack_label[i]; ++i) {
374 if (i >= SMACK_LABEL_LEN)
376 switch (smack_label[i]) {
391 // TODO replace it with SEC_SVR_DBG when master is merged
392 SEC_SVR_DBG("ERROR: Invalid Smack label: %s", smack_label);