2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <livebox-errno.h>
25 #include <sys/smack.h>
29 #include <security-server.h>
31 #include "service_common.h"
37 Eina_List *context_list;
38 struct service_context *svc_ctx;
40 .context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
41 .svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */
44 #define ENABLE_BS_ACCESS_CONTROL 0
51 struct badge_service {
53 void (*handler)(struct tcb *tcb, struct packet *packet, void *data);
59 * FUNCTIONS to handle badge
61 static inline char *get_string(char *string)
66 if (string[0] == '\0') {
76 static void _handler_insert_badge(struct tcb *tcb, struct packet *packet, void *data)
78 int ret = 0, ret_p = 0;
79 struct packet *packet_reply = NULL;
80 struct packet *packet_service = NULL;
82 char *writable_pkg = NULL;
85 if (packet_get(packet, "sss", &pkgname, &writable_pkg, &caller) == 3) {
86 pkgname = get_string(pkgname);
87 writable_pkg = get_string(writable_pkg);
88 caller = get_string(caller);
90 if (pkgname != NULL && writable_pkg != NULL && caller != NULL) {
91 ret = badge_db_insert(pkgname, writable_pkg, caller);
94 ret = BADGE_ERROR_INVALID_DATA;
97 packet_reply = packet_create_reply(packet, "i", ret);
99 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
100 ErrPrint("Failed to send a reply packet:%d", ret_p);
102 packet_destroy(packet_reply);
104 ErrPrint("Failed to create a reply packet");
107 if (ret == BADGE_ERROR_NONE) {
108 packet_service = packet_create("insert_badge", "is", ret, pkgname);
109 if (packet_service != NULL) {
110 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
111 ErrPrint("Failed to send a muticast packet:%d", ret_p);
113 packet_destroy(packet_service);
115 ErrPrint("Failed to create a multicast packet");
118 ErrPrint("Failed to insert a badge:%d", ret);
121 ErrPrint("Failed to get data from the packet");
125 static void _handler_delete_badge(struct tcb *tcb, struct packet *packet, void *data)
127 int ret = 0, ret_p = 0;
128 struct packet *packet_reply = NULL;
129 struct packet *packet_service = NULL;
130 char *pkgname = NULL;
133 if (packet_get(packet, "ss", &pkgname, &caller) == 2) {
134 pkgname = get_string(pkgname);
135 caller = get_string(caller);
137 if (pkgname != NULL && caller != NULL) {
138 ret = badge_db_delete(pkgname, caller);
141 ret = BADGE_ERROR_INVALID_DATA;
144 packet_reply = packet_create_reply(packet, "i", ret);
146 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
147 ErrPrint("Failed to send a reply packet:%d", ret_p);
149 packet_destroy(packet_reply);
151 ErrPrint("Failed to create a reply packet");
154 if (ret == BADGE_ERROR_NONE) {
155 packet_service = packet_create("delete_badge", "is", ret, pkgname);
156 if (packet_service != NULL) {
157 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
158 ErrPrint("Failed to send a muticast packet:%d", ret_p);
160 packet_destroy(packet_service);
162 ErrPrint("Failed to create a multicast packet");
165 ErrPrint("Failed to delete a badge:%d", ret);
168 ErrPrint("Failed to get data from the packet");
172 static void _handler_set_badge_count(struct tcb *tcb, struct packet *packet, void *data)
174 int ret = 0, ret_p = 0;
175 struct packet *packet_reply = NULL;
176 struct packet *packet_service = NULL;
177 char *pkgname = NULL;
181 if (packet_get(packet, "ssi", &pkgname, &caller, &count) == 3) {
182 pkgname = get_string(pkgname);
183 caller = get_string(caller);
185 if (pkgname != NULL && caller != NULL) {
186 ret = badge_db_set_count(pkgname, caller, count);
189 ret = BADGE_ERROR_INVALID_DATA;
192 packet_reply = packet_create_reply(packet, "i", ret);
194 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
195 ErrPrint("Failed to send a reply packet:%d", ret_p);
197 packet_destroy(packet_reply);
199 ErrPrint("Failed to create a reply packet");
202 if (ret == BADGE_ERROR_NONE) {
203 packet_service = packet_create("set_badge_count", "isi", ret, pkgname, count);
204 if (packet_service != NULL) {
205 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
206 ErrPrint("Failed to send a muticast packet:%d", ret_p);
208 packet_destroy(packet_service);
210 ErrPrint("Failed to create a multicast packet");
213 ErrPrint("Failed to set count of badge:%d", ret);
216 ErrPrint("Failed to get data from the packet");
220 static void _handler_set_display_option(struct tcb *tcb, struct packet *packet, void *data)
222 int ret = 0, ret_p = 0;
223 struct packet *packet_reply = NULL;
224 struct packet *packet_service = NULL;
225 char *pkgname = NULL;
229 if (packet_get(packet, "ssi", &pkgname, &caller, &is_display) == 3) {
230 pkgname = get_string(pkgname);
231 caller = get_string(caller);
233 if (pkgname != NULL && caller != NULL) {
234 ret = badge_db_set_display_option(pkgname, caller, is_display);
237 ret = BADGE_ERROR_INVALID_DATA;
240 packet_reply = packet_create_reply(packet, "i", ret);
242 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
243 ErrPrint("Failed to send a reply packet:%d", ret_p);
245 packet_destroy(packet_reply);
247 ErrPrint("Failed to create a reply packet");
250 if (ret == BADGE_ERROR_NONE) {
251 packet_service = packet_create("set_disp_option", "isi", ret, pkgname, is_display);
252 if (packet_service != NULL) {
253 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
254 ErrPrint("Failed to send a muticast packet:%d", ret_p);
256 packet_destroy(packet_service);
258 ErrPrint("Failed to create a multicast packet");
261 ErrPrint("Failed to set display option of badge:%d", ret);
264 ErrPrint("Failed to get data from the packet");
268 static void _handler_service_register(struct tcb *tcb, struct packet *packet, void *data)
271 struct packet *packet_reply;
273 ret = tcb_client_type_set(tcb, TCB_CLIENT_TYPE_SERVICE);
275 ErrPrint("Failed to set the type of client:%d", ret);
278 packet_reply = packet_create_reply(packet, "i", ret);
280 if ((ret = service_common_unicast_packet(tcb, packet_reply)) < 0) {
281 ErrPrint("Failed to send a reply packet:%d", ret);
283 packet_destroy(packet_reply);
285 ErrPrint("Failed to create a reply packet");
289 static int _is_valid_permission(int fd, struct badge_service *service)
293 if (service->rule != NULL && service->access != NULL) {
294 ret = security_server_check_privilege_by_sockfd(fd, service->rule, service->access);
295 if (ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
296 ErrPrint("SMACK:Access denied\n");
307 static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
311 static struct badge_service service_req_table[] = {
313 .cmd = "insert_badge",
314 .handler = _handler_insert_badge,
315 .rule = "data-provider-master::badge.client",
319 .cmd = "delete_badge",
320 .handler = _handler_delete_badge,
321 .rule = "data-provider-master::badge.client",
325 .cmd = "set_badge_count",
326 .handler = _handler_set_badge_count,
327 .rule = "data-provider-master::badge.client",
331 .cmd = "set_disp_option",
332 .handler = _handler_set_display_option,
333 .rule = "data-provider-master::badge.client",
337 .cmd = "service_register",
338 .handler = _handler_service_register,
351 DbgPrint("TCB: %p is terminated (NIL packet)\n", tcb);
355 command = packet_command(packet);
357 ErrPrint("Invalid command\n");
360 DbgPrint("Command: [%s], Packet type[%d]\n", command, packet_type(packet));
362 switch (packet_type(packet)) {
364 /* Need to send reply packet */
365 for (i = 0; service_req_table[i].cmd; i++) {
366 if (strcmp(service_req_table[i].cmd, command))
369 #if ENABLE_BS_ACCESS_CONTROL
370 if (_is_valid_permission(tcb_fd(tcb), &(service_req_table[i])) == 1) {
371 service_req_table[i].handler(tcb, packet, data);
374 _is_valid_permission(tcb_fd(tcb), &(service_req_table[i]));
375 service_req_table[i].handler(tcb, packet, data);
381 case PACKET_REQ_NOACK:
386 ErrPrint("Packet type is not valid[%s]\n", command);
391 * return value has no meanning,
392 * it will be printed by dlogutil.
400 * Do not try to do anyother operation in these functions
402 HAPI int badge_service_init(void)
404 if (s_info.svc_ctx) {
405 ErrPrint("Already initialized\n");
406 return LB_STATUS_ERROR_ALREADY;
409 s_info.svc_ctx = service_common_create(BADGE_SOCKET, service_thread_main, NULL);
410 if (!s_info.svc_ctx) {
411 ErrPrint("Unable to activate service thread\n");
412 return LB_STATUS_ERROR_FAULT;
415 if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), BADGE_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) {
416 if (errno != EOPNOTSUPP) {
417 ErrPrint("Unable to set SMACK label(%d)\n", errno);
418 service_common_destroy(s_info.svc_ctx);
419 s_info.svc_ctx = NULL;
420 return LB_STATUS_ERROR_FAULT;
424 if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), BADGE_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) {
425 if (errno != EOPNOTSUPP) {
426 ErrPrint("Unable to set SMACK label(%d)\n", errno);
427 service_common_destroy(s_info.svc_ctx);
428 s_info.svc_ctx = NULL;
429 return LB_STATUS_ERROR_FAULT;
433 DbgPrint("Successfully initiated\n");
434 return LB_STATUS_SUCCESS;
437 HAPI int badge_service_fini(void)
440 return LB_STATUS_ERROR_INVALID;
442 service_common_destroy(s_info.svc_ctx);
443 s_info.svc_ctx = NULL;
444 DbgPrint("Successfully finalized\n");
445 return LB_STATUS_SUCCESS;