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 #if defined(HAVE_LIVEBOX)
23 #include <dynamicbox_errno.h>
25 #include "lite-errno.h"
29 #include <sys/smack.h>
33 #include <badge_setting_service.h>
34 #include <security-server.h>
36 #include "service_common.h"
42 Eina_List *context_list;
43 struct service_context *svc_ctx;
45 .context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
46 .svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */
49 #define ENABLE_BS_ACCESS_CONTROL 1
56 struct badge_service {
58 void (*handler)(struct tcb *tcb, struct packet *packet, void *data);
64 * FUNCTIONS to check smack permission
66 static int _is_valid_permission(int fd, struct badge_service *service)
70 if (service->rule != NULL && service->access != NULL) {
71 ret = security_server_check_privilege_by_sockfd(fd, service->rule, service->access);
72 if (ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
73 ErrPrint("SMACK:Access denied\n");
81 static int _is_manager_permission(int fd)
85 ret = security_server_check_privilege_by_sockfd(fd,
86 "data-provider-master::badge.manager", "w");
87 if (ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
88 ErrPrint("SMACK:not a manager\n");
96 * FUNCTIONS to handle badge
98 static inline char *get_string(char *string)
100 if (string == NULL) {
103 if (string[0] == '\0') {
113 static void _handler_insert_badge(struct tcb *tcb, struct packet *packet, void *data)
115 int ret = 0, ret_p = 0;
116 struct packet *packet_reply = NULL;
117 struct packet *packet_service = NULL;
118 char *pkgname = NULL;
119 char *writable_pkg = NULL;
122 if (packet_get(packet, "sss", &pkgname, &writable_pkg, &caller) == 3) {
123 pkgname = get_string(pkgname);
124 writable_pkg = get_string(writable_pkg);
125 caller = get_string(caller);
127 if (pkgname != NULL && writable_pkg != NULL && caller != NULL) {
128 ret = badge_db_insert(pkgname, writable_pkg, caller);
130 ret = BADGE_ERROR_INVALID_PARAMETER;
133 packet_reply = packet_create_reply(packet, "i", ret);
135 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
136 ErrPrint("Failed to send a reply packet:%d", ret_p);
138 packet_destroy(packet_reply);
140 ErrPrint("Failed to create a reply packet");
143 if (ret == BADGE_ERROR_NONE) {
144 packet_service = packet_create("insert_badge", "is", ret, pkgname);
145 if (packet_service != NULL) {
146 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
147 ErrPrint("Failed to send a muticast packet:%d", ret_p);
149 packet_destroy(packet_service);
151 ErrPrint("Failed to create a multicast packet");
154 ErrPrint("Failed to insert a badge:%d", ret);
157 ErrPrint("Failed to get data from the packet");
161 static void _handler_delete_badge(struct tcb *tcb, struct packet *packet, void *data)
163 int ret = 0, ret_p = 0;
164 struct packet *packet_reply = NULL;
165 struct packet *packet_service = NULL;
166 char *pkgname = NULL;
169 if (packet_get(packet, "ss", &pkgname, &caller) == 2) {
170 pkgname = get_string(pkgname);
171 caller = get_string(caller);
173 if (pkgname != NULL && caller != NULL) {
174 if (_is_manager_permission(tcb_fd(tcb)) == 1) {
175 ret = badge_db_delete(pkgname, pkgname);
177 ret = badge_db_delete(pkgname, caller);
180 ret = BADGE_ERROR_INVALID_PARAMETER;
183 packet_reply = packet_create_reply(packet, "i", ret);
185 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
186 ErrPrint("Failed to send a reply packet:%d", ret_p);
188 packet_destroy(packet_reply);
190 ErrPrint("Failed to create a reply packet");
193 if (ret == BADGE_ERROR_NONE) {
194 packet_service = packet_create("delete_badge", "is", ret, pkgname);
195 if (packet_service != NULL) {
196 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
197 ErrPrint("Failed to send a muticast packet:%d", ret_p);
199 packet_destroy(packet_service);
201 ErrPrint("Failed to create a multicast packet");
204 ErrPrint("Failed to delete a badge:%d", ret);
207 ErrPrint("Failed to get data from the packet");
211 static void _handler_set_badge_count(struct tcb *tcb, struct packet *packet, void *data)
213 int ret = 0, ret_p = 0;
214 struct packet *packet_reply = NULL;
215 struct packet *packet_service = NULL;
216 char *pkgname = NULL;
220 if (packet_get(packet, "ssi", &pkgname, &caller, &count) == 3) {
221 pkgname = get_string(pkgname);
222 caller = get_string(caller);
224 if (pkgname != NULL && caller != NULL) {
225 ret = badge_db_set_count(pkgname, caller, count);
227 ret = BADGE_ERROR_INVALID_PARAMETER;
230 packet_reply = packet_create_reply(packet, "i", ret);
232 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
233 ErrPrint("Failed to send a reply packet:%d", ret_p);
235 packet_destroy(packet_reply);
237 ErrPrint("Failed to create a reply packet");
240 if (ret == BADGE_ERROR_NONE) {
241 packet_service = packet_create("set_badge_count", "isi", ret, pkgname, count);
242 if (packet_service != NULL) {
243 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
244 ErrPrint("Failed to send a muticast packet:%d", ret_p);
246 packet_destroy(packet_service);
248 ErrPrint("Failed to create a multicast packet");
251 ErrPrint("Failed to set count of badge:%d", ret);
254 ErrPrint("Failed to get data from the packet");
258 static void _handler_set_display_option(struct tcb *tcb, struct packet *packet, void *data)
260 int ret = 0, ret_p = 0;
261 struct packet *packet_reply = NULL;
262 struct packet *packet_service = NULL;
263 char *pkgname = NULL;
267 if (packet_get(packet, "ssi", &pkgname, &caller, &is_display) == 3) {
268 pkgname = get_string(pkgname);
269 caller = get_string(caller);
271 if (pkgname != NULL && caller != NULL) {
272 ret = badge_db_set_display_option(pkgname, caller, is_display);
274 ret = BADGE_ERROR_INVALID_PARAMETER;
277 packet_reply = packet_create_reply(packet, "i", ret);
279 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
280 ErrPrint("Failed to send a reply packet:%d", ret_p);
282 packet_destroy(packet_reply);
284 ErrPrint("Failed to create a reply packet");
287 if (ret == BADGE_ERROR_NONE) {
288 packet_service = packet_create("set_disp_option", "isi", ret, pkgname, is_display);
289 if (packet_service != NULL) {
290 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
291 ErrPrint("Failed to send a muticast packet:%d", ret_p);
293 packet_destroy(packet_service);
295 ErrPrint("Failed to create a multicast packet");
298 ErrPrint("Failed to set display option of badge:%d", ret);
301 ErrPrint("Failed to get data from the packet");
305 static void _handler_set_setting_property(struct tcb *tcb, struct packet *packet, void *data)
307 int ret = 0, ret_p = 0;
309 struct packet *packet_reply = NULL;
310 struct packet *packet_service = NULL;
311 char *pkgname = NULL;
312 char *property = NULL;
315 if (packet_get(packet, "sss", &pkgname, &property, &value) == 3) {
316 pkgname = get_string(pkgname);
317 property = get_string(property);
318 value = get_string(value);
320 if (pkgname != NULL && property != NULL && value != NULL) {
321 ret = badge_setting_db_set(pkgname, property, value);
323 ret = BADGE_ERROR_INVALID_PARAMETER;
326 packet_reply = packet_create_reply(packet, "ii", ret, ret);
328 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
329 ErrPrint("failed to send reply packet:%d\n", ret_p);
331 packet_destroy(packet_reply);
333 ErrPrint("failed to create a reply packet\n");
336 if (ret == BADGE_ERROR_NONE) {
337 if (strcmp(property, "OPT_BADGE") == 0) {
338 if (strcmp(value, "ON") == 0) {
344 packet_service = packet_create("set_disp_option", "isi", ret, pkgname, is_display);
345 if (packet_service != NULL) {
346 if ((ret_p = service_common_multicast_packet(tcb, packet_service, TCB_CLIENT_TYPE_SERVICE)) < 0) {
347 ErrPrint("Failed to send a muticast packet:%d", ret_p);
349 packet_destroy(packet_service);
351 ErrPrint("Failed to create a multicast packet");
355 ErrPrint("failed to set noti property:%d\n", ret);
358 ErrPrint("Failed to get data from the packet");
362 static void _handler_get_setting_property(struct tcb *tcb, struct packet *packet, void *data)
364 int ret = 0, ret_p = 0;
365 struct packet *packet_reply = NULL;
366 char *pkgname = NULL;
367 char *property = NULL;
370 if (packet_get(packet, "sss", &pkgname, &property) == 2) {
371 pkgname = get_string(pkgname);
372 property = get_string(property);
374 if (pkgname != NULL && property != NULL) {
375 ret = badge_setting_db_get(pkgname, property, &value);
377 ret = BADGE_ERROR_INVALID_PARAMETER;
380 packet_reply = packet_create_reply(packet, "is", ret, value);
382 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
383 ErrPrint("failed to send reply packet:%d\n", ret_p);
385 packet_destroy(packet_reply);
387 ErrPrint("failed to create a reply packet\n");
396 static void _handler_service_register(struct tcb *tcb, struct packet *packet, void *data)
399 struct packet *packet_reply;
401 ret = tcb_client_type_set(tcb, TCB_CLIENT_TYPE_SERVICE);
403 ErrPrint("Failed to set the type of client:%d", ret);
406 packet_reply = packet_create_reply(packet, "i", ret);
408 if ((ret = service_common_unicast_packet(tcb, packet_reply)) < 0) {
409 ErrPrint("Failed to send a reply packet:%d", ret);
411 packet_destroy(packet_reply);
413 ErrPrint("Failed to create a reply packet");
417 static void _handler_access_control_error(struct tcb *tcb, struct packet *packet)
420 struct packet *packet_reply = NULL;
422 packet_reply = packet_create_reply(packet, "i", BADGE_ERROR_PERMISSION_DENIED);
424 if ((ret_p = service_common_unicast_packet(tcb, packet_reply)) < 0) {
425 ErrPrint("Failed to send a reply packet:%d", ret_p);
427 packet_destroy(packet_reply);
429 ErrPrint("Failed to create a reply packet");
436 static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
440 static struct badge_service service_req_table[] = {
442 .cmd = "insert_badge",
443 .handler = _handler_insert_badge,
444 .rule = "data-provider-master::badge.client",
448 .cmd = "delete_badge",
449 .handler = _handler_delete_badge,
450 .rule = "data-provider-master::badge.client",
454 .cmd = "set_badge_count",
455 .handler = _handler_set_badge_count,
456 .rule = "data-provider-master::badge.client",
460 .cmd = "set_disp_option",
461 .handler = _handler_set_display_option,
462 .rule = "data-provider-master::badge.client",
466 .cmd = "set_noti_property",
467 .handler = _handler_set_setting_property,
468 .rule = "data-provider-master::badge.client",
472 .cmd = "get_noti_property",
473 .handler = _handler_get_setting_property,
474 .rule = "data-provider-master::badge.client",
478 .cmd = "service_register",
479 .handler = _handler_service_register,
492 DbgPrint("TCB: %p is terminated (NIL packet)\n", tcb);
496 command = packet_command(packet);
498 ErrPrint("Invalid command\n");
501 DbgPrint("Command: [%s], Packet type[%d]\n", command, packet_type(packet));
503 switch (packet_type(packet)) {
505 /* Need to send reply packet */
506 for (i = 0; service_req_table[i].cmd; i++) {
507 if (strcmp(service_req_table[i].cmd, command)) {
511 #if ENABLE_BS_ACCESS_CONTROL
512 if (_is_valid_permission(tcb_fd(tcb), &(service_req_table[i])) == 1) {
513 service_req_table[i].handler(tcb, packet, data);
515 _handler_access_control_error(tcb, packet);
518 _is_valid_permission(tcb_fd(tcb), &(service_req_table[i]));
519 service_req_table[i].handler(tcb, packet, data);
525 case PACKET_REQ_NOACK:
530 ErrPrint("Packet type is not valid[%s]\n", command);
535 * return value has no meanning,
536 * it will be printed by dlogutil.
544 * Do not try to do anyother operation in these functions
546 HAPI int badge_service_init(void)
548 if (s_info.svc_ctx) {
549 ErrPrint("Already initialized\n");
550 return DBOX_STATUS_ERROR_ALREADY;
553 s_info.svc_ctx = service_common_create(BADGE_SOCKET, service_thread_main, NULL);
554 if (!s_info.svc_ctx) {
555 ErrPrint("Unable to activate service thread\n");
556 return DBOX_STATUS_ERROR_FAULT;
559 if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), BADGE_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) {
560 if (errno != EOPNOTSUPP) {
561 ErrPrint("Unable to set SMACK label(%d)\n", errno);
562 service_common_destroy(s_info.svc_ctx);
563 s_info.svc_ctx = NULL;
564 return DBOX_STATUS_ERROR_FAULT;
568 if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), BADGE_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) {
569 if (errno != EOPNOTSUPP) {
570 ErrPrint("Unable to set SMACK label(%d)\n", errno);
571 service_common_destroy(s_info.svc_ctx);
572 s_info.svc_ctx = NULL;
573 return DBOX_STATUS_ERROR_FAULT;
577 DbgPrint("Successfully initiated\n");
578 return DBOX_STATUS_ERROR_NONE;
581 HAPI int badge_service_fini(void)
583 if (!s_info.svc_ctx) {
584 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
587 service_common_destroy(s_info.svc_ctx);
588 s_info.svc_ctx = NULL;
589 DbgPrint("Successfully finalized\n");
590 return DBOX_STATUS_ERROR_NONE;