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.
21 #if defined(HAVE_LIVEBOX)
22 #include <dynamicbox_errno.h>
24 #include "lite-errno.h"
29 #include <sys/smack.h>
31 #include <security-server.h>
34 #include "service_common.h"
40 Eina_List *context_list;
41 struct service_context *svc_ctx;
43 .context_list = NULL, /*!< \WARN: This is only used for SERVICE THREAD */
44 .svc_ctx = NULL, /*!< \WARN: This is only used for MAIN THREAD */
55 static inline int put_reply_context(struct tcb *tcb, double seq)
59 ctx = malloc(sizeof(*ctx));
61 ErrPrint("Heap: %s\n", strerror(errno));
66 ctx->seq = seq; /* Could we this sequence value is uniq? */
68 s_info.context_list = eina_list_append(s_info.context_list, ctx);
75 static inline struct tcb *get_reply_context(double seq)
83 EINA_LIST_FOREACH_SAFE(s_info.context_list, l, n, ctx) {
84 if (ctx->seq != seq) {
88 s_info.context_list = eina_list_remove(s_info.context_list, ctx);
97 static void send_reply_packet(struct tcb *tcb, struct packet *packet, int ret)
99 struct packet *reply_packet;
101 reply_packet = packet_create_reply(packet, "i", ret);
103 ErrPrint("Failed to create a packet\n");
107 if (service_common_unicast_packet(tcb, reply_packet) < 0) {
108 ErrPrint("Unable to send reply packet\n");
111 packet_destroy(reply_packet);
117 static int service_thread_main(struct tcb *tcb, struct packet *packet, void *data)
123 DbgPrint("TCB: %p is terminated (NIL packet)\n", tcb);
127 command = packet_command(packet);
129 ErrPrint("Invalid command\n");
133 switch (packet_type(packet)) {
136 /* Need to send reply packet */
137 DbgPrint("%p REQ: Command: [%s]\n", tcb, command);
138 if (!strcmp(command, "add_livebox") || !strcmp(command, "rm_livebox")) {
139 ret = security_server_check_privilege_by_sockfd(tcb_fd(tcb), "data-provider-master::shortcut.livebox", "w");
140 if (ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
141 ErrPrint("SMACK:Access denied\n");
142 send_reply_packet(tcb, packet, SHORTCUT_ERROR_PERMISSION_DENIED);
146 } else if (!strcmp(command, "add_shortcut") || !strcmp(command, "rm_shortcut")) {
147 ret = security_server_check_privilege_by_sockfd(tcb_fd(tcb), "data-provider-master::shortcut.shortcut", "w");
148 if (ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
149 ErrPrint("SMACK:Access denied\n");
150 send_reply_packet(tcb, packet, SHORTCUT_ERROR_PERMISSION_DENIED);
155 if (service_common_multicast_packet(tcb, packet, TCB_CLIENT_TYPE_SERVICE) < 0) {
156 ErrPrint("Unable to send service request packet\n");
158 (void)put_reply_context(tcb, packet_seq(packet));
161 case PACKET_REQ_NOACK:
162 /* Doesn't need to send reply packet */
163 DbgPrint("%p REQ_NOACK: Command: [%s]\n", tcb, command);
164 if (!strcmp(command, "service_register")) {
165 tcb_client_type_set(tcb, TCB_CLIENT_TYPE_SERVICE);
169 if (service_common_multicast_packet(tcb, packet, TCB_CLIENT_TYPE_SERVICE) < 0) {
170 ErrPrint("Unable to send service reuqest packet\n");
174 /* Okay, client(or app) send a reply packet to us. */
175 DbgPrint("%p ACK: Command: [%s]\n", tcb, command);
176 tcb = get_reply_context(packet_seq(packet));
178 ErrPrint("There is no proper context\n");
182 if (tcb_is_valid(s_info.svc_ctx, tcb) < 0) {
183 ErrPrint("TCB is not valid (already disconnected?)\n");
187 if (service_common_unicast_packet(tcb, packet) < 0) {
188 ErrPrint("Unable to send reply packet\n");
192 ErrPrint("Packet type is not valid[%s]\n", command);
197 * return value has no meanning,
198 * it will be printed by dlogutil.
206 * Do not try to do anyother operation in these functions
209 HAPI int shortcut_service_init(void)
211 if (s_info.svc_ctx) {
212 ErrPrint("Already initialized\n");
213 return DBOX_STATUS_ERROR_ALREADY;
216 s_info.svc_ctx = service_common_create(SHORTCUT_SOCKET, service_thread_main, NULL);
217 if (!s_info.svc_ctx) {
218 ErrPrint("Unable to activate service thread\n");
219 return DBOX_STATUS_ERROR_FAULT;
222 if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), SHORTCUT_SMACK_LABEL, SMACK_LABEL_IPOUT) != 0) {
223 if (errno != EOPNOTSUPP) {
224 ErrPrint("Unable to set SMACK label(%d)\n", errno);
225 service_common_destroy(s_info.svc_ctx);
226 s_info.svc_ctx = NULL;
227 return DBOX_STATUS_ERROR_FAULT;
231 if (smack_fsetlabel(service_common_fd(s_info.svc_ctx), SHORTCUT_SMACK_LABEL, SMACK_LABEL_IPIN) != 0) {
232 if (errno != EOPNOTSUPP) {
233 ErrPrint("Unable to set SMACK label(%d)\n", errno);
234 service_common_destroy(s_info.svc_ctx);
235 s_info.svc_ctx = NULL;
236 return DBOX_STATUS_ERROR_FAULT;
240 DbgPrint("Successfully initiated\n");
241 return DBOX_STATUS_ERROR_NONE;
244 HAPI int shortcut_service_fini(void)
246 if (!s_info.svc_ctx) {
247 return DBOX_STATUS_ERROR_INVALID_PARAMETER;
250 service_common_destroy(s_info.svc_ctx);
251 s_info.svc_ctx = NULL;
252 DbgPrint("Successfully Finalized\n");
253 return DBOX_STATUS_ERROR_NONE;