SET(submodule "controller")
# for package file
-SET(dependents "capi-base-common glib-2.0 gio-2.0 dlog sqlite3 db-util aul bundle libtzplatform-config")
+SET(dependents "capi-base-common glib-2.0 gio-2.0 dlog sqlite3 db-util aul bundle libtzplatform-config cynara-client cynara-session cynara-creds-socket")
SET(fw_name "${project_prefix}-${service}-${submodule}")
PROJECT(${fw_name})
BuildRequires: pkgconfig(bundle)
BuildRequires: pkgconfig(libsystemd-daemon)
BuildRequires: pkgconfig(libtzplatform-config)
+BuildRequires: pkgconfig(cynara-client)
+BuildRequires: pkgconfig(cynara-session)
%description
A media controller library in SLP C API
# for package file
-SET(dependents "capi-base-common glib-2.0 gio-2.0 dlog sqlite3 db-util libsystemd-daemon libtzplatform-config")
+SET(dependents "capi-base-common glib-2.0 gio-2.0 dlog sqlite3 db-util libsystemd-daemon libtzplatform-config cynara-client cynara-session cynara-creds-socket")
SET(fw_svc "media-controller-svc")
PROJECT(${fw_svc})
#include "media_controller_private.h"
#include "../media_controller_socket.h"
#include "../media_controller_svc.h"
+#include "media_controller_cynara.h"
GMainLoop *g_mc_mainloop = NULL;
static int g_mc_timer_id = 0;
/*Init main loop*/
g_mc_mainloop = g_main_loop_new(NULL, FALSE);
+ if(mc_cynara_initialize() != MEDIA_CONTROLLER_ERROR_NONE) {
+ mc_error("Failed to initialize cynara");
+ return -1;
+ }
+
fd = mc_create_socket_activation();
if (fd < 0) {
mc_error("Failed to socekt creation");
g_thread_join(svc_thread);
g_main_loop_unref(g_mc_mainloop);
+ mc_cynara_finish();
+
mc_debug("*** Media Controller Daemon is stopped ***");
return 0;
--- /dev/null
+/*\r
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+#define _GNU_SOURCE\r
+\r
+#include <errno.h>\r
+#include <glib.h>\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <sys/socket.h>\r
+#include <unistd.h>\r
+\r
+#include <media_controller_cynara.h>\r
+#include <media_controller_type.h>\r
+#include <media_controller_private.h>\r
+\r
+#include <cynara-client.h>\r
+#include <cynara-session.h>\r
+#include <cynara-error.h>\r
+#include <cynara-creds-socket.h>\r
+\r
+/* this definition is missing in glibc headers (version 2.21). It was introduced in kernel version 2.6.17 */\r
+#ifndef SCM_SECURITY\r
+#define SCM_SECURITY 0x03\r
+#endif\r
+\r
+static cynara *_cynara = NULL;\r
+G_LOCK_DEFINE_STATIC(cynara_mutex);\r
+\r
+static void mc_cynara_dbg_err(const char *prefix, int error_code)\r
+{\r
+ char error_buffer[256];\r
+ int err;\r
+ error_buffer[0] = '\0';\r
+\r
+ err = cynara_strerror(error_code, error_buffer, sizeof(error_buffer));\r
+ if (err == CYNARA_API_SUCCESS) {\r
+ mc_error("%s: %s", prefix, error_buffer);\r
+ } else {\r
+ mc_error("%s: error code %i", prefix, error_code);\r
+ }\r
+}\r
+\r
+int mc_cynara_initialize(void)\r
+{\r
+ int ret = cynara_initialize(&_cynara, NULL);\r
+ if (ret != CYNARA_API_SUCCESS) {\r
+ mc_cynara_dbg_err("cynara_initialize", ret);\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;\r
+ }\r
+ return MEDIA_CONTROLLER_ERROR_NONE;\r
+}\r
+\r
+void mc_cynara_finish(void)\r
+{\r
+ cynara_finish(_cynara);\r
+ _cynara = NULL;\r
+}\r
+\r
+int mc_cynara_receive_untrusted_message(int sockfd, mc_comm_msg_s *recv_msg, mc_peer_creds *credentials)\r
+{\r
+ int ret = 0;\r
+ int recv_msg_size = 0;\r
+\r
+ if (!recv_msg ||!credentials)\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER;\r
+\r
+ if ((recv_msg_size = read(sockfd, recv_msg, sizeof(mc_comm_msg_s))) < 0) {\r
+ if (errno == EWOULDBLOCK) {\r
+ mc_error("Timeout. Can't try any more");\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;\r
+ } else {\r
+ mc_stderror("recv failed");\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;\r
+ }\r
+ }\r
+\r
+/* mc_debug("receive msg[%d] from [%d(%d)] %d, %s", recv_msg_size, recv_msg->pid, recv_msg->uid, recv_msg->msg_type, recv_msg->msg); */\r
+\r
+ ret = cynara_creds_socket_get_pid(sockfd, &(credentials->pid));\r
+ if(ret < 0) {\r
+ mc_error("cynara_creds_socket_get_pid failed");\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;\r
+ }\r
+\r
+ ret = cynara_creds_socket_get_user(sockfd, USER_METHOD_UID, &(credentials->uid));\r
+ if(ret < 0) {\r
+ mc_error("cynara_creds_socket_get_user failed");\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;\r
+ }\r
+\r
+ ret = cynara_creds_socket_get_client(sockfd, CLIENT_METHOD_SMACK, &(credentials->smack));\r
+ if(ret < 0) {\r
+ mc_error("cynara_creds_socket_get_client failed");\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;\r
+ }\r
+\r
+/* mc_error("cynara_creds_info : P[%d]U[%s]S[%s]", credentials->pid, credentials->uid, credentials->smack); */\r
+\r
+ return MEDIA_CONTROLLER_ERROR_NONE;\r
+}\r
+\r
+int mc_cynara_check(const mc_peer_creds *creds, const char *privilege)\r
+{\r
+ int result;\r
+ char *session;\r
+\r
+ if (!creds || !privilege)\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_PARAMETER;\r
+\r
+ session = cynara_session_from_pid(creds->pid);\r
+ if (session == NULL) {\r
+ mc_error("cynara_session_from_pid failed");\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;\r
+ }\r
+\r
+ G_LOCK(cynara_mutex);\r
+ result = cynara_check(_cynara, creds->smack, session, creds->uid, privilege);\r
+ G_UNLOCK(cynara_mutex);\r
+\r
+ if (result != CYNARA_API_ACCESS_ALLOWED)\r
+ mc_cynara_dbg_err("cynara_check", result);\r
+\r
+ MC_SAFE_FREE(session);\r
+ return result == CYNARA_API_ACCESS_ALLOWED ? MEDIA_CONTROLLER_ERROR_NONE: MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED;\r
+}\r
+\r
+int mc_cynara_enable_credentials_passing(int sockfd)\r
+{\r
+ const int optval = 1;\r
+ int err = 0;\r
+\r
+ err = setsockopt(sockfd, SOL_SOCKET, SO_PASSSEC, &optval, sizeof(optval));\r
+ if (err != 0) {\r
+ mc_error("Failed to set SO_PASSSEC socket option");\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;\r
+ }\r
+\r
+ err = setsockopt(sockfd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval));\r
+ if (err != 0) {\r
+ mc_error("Failed to set SO_PASSCRED socket option");\r
+ return MEDIA_CONTROLLER_ERROR_INVALID_OPERATION;\r
+ }\r
+\r
+ return MEDIA_CONTROLLER_ERROR_NONE;\r
+}\r
--- /dev/null
+/*\r
+* Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved\r
+*\r
+* Licensed under the Apache License, Version 2.0 (the "License");\r
+* you may not use this file except in compliance with the License.\r
+* You may obtain a copy of the License at\r
+*\r
+* http://www.apache.org/licenses/LICENSE-2.0\r
+*\r
+* Unless required by applicable law or agreed to in writing, software\r
+* distributed under the License is distributed on an "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+* See the License for the specific language governing permissions and\r
+* limitations under the License.\r
+*/\r
+\r
+#ifndef __TIZEN_MEDIA_CONTROLLER_CYNARA_H__\r
+#define __TIZEN_MEDIA_CONTROLLER_CYNARA_H__\r
+\r
+#include <stdbool.h>\r
+\r
+#include <media_controller_private.h>\r
+\r
+#define MC_CLIENT_PRIVILEGE "http://tizen.org/privilege/mediacontroller.client"\r
+#define MC_SERVER_PRIVILEGE "http://tizen.org/privilege/mediacontroller.server"\r
+\r
+typedef struct {\r
+ pid_t pid;\r
+ char *uid;\r
+ char *smack;\r
+} mc_peer_creds;\r
+\r
+int mc_cynara_initialize(void);\r
+int mc_cynara_check(const mc_peer_creds *creds, const char *privilege);\r
+int mc_cynara_receive_untrusted_message(int sockfd, mc_comm_msg_s *recv_msg, mc_peer_creds *credentials);\r
+int mc_cynara_enable_credentials_passing(int sockfd);\r
+void mc_cynara_finish(void);\r
+\r
+\r
+#endif/* _MEDIA_CONTROLLER_CYNARA_H_ */\r
#include "media_controller_private.h"
#include "media_controller_socket.h"
#include "media_controller_db_util.h"
+#include "media_controller_cynara.h"
static GMainLoop *g_mc_svc_mainloop = NULL;
static int g_connection_cnt = -1;
-static int __mc_privilege_ask(int client_sockfd, const char *type, const char *privilege_object)
-{
- int ret = MEDIA_CONTROLLER_ERROR_NONE;
-#if 0
- ret = security_server_check_privilege_by_sockfd(client_sockfd, type, privilege_object);
- if (ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED) {
- mc_error("You do not have permission for this operation.");
- ret = MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED;
- } else {
- mc_debug("PERMISSION OK");
- }
-#endif
- return ret;
-}
-
static int __create_socket_activation(void)
{
int fd = -1;
bool is_duplicated = FALSE;
unsigned int i = 0;
mc_svc_data_t *mc_svc_data = (mc_svc_data_t*)data;
+ mc_peer_creds creds = {0, };
mc_debug("mc_read_service_request_tcp_socket is called!!!!!");
return TRUE;
}
- ret = mc_ipc_receive_message_tcp(client_sock, &recv_msg);
+ memset(&creds, 0, sizeof(mc_peer_creds));
+
+ ret = mc_cynara_receive_untrusted_message(client_sock, &recv_msg, &creds);
if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
mc_error("mc_ipc_receive_message_tcp failed [%d]", ret);
send_msg = ret;
}
} else if (recv_msg.msg_type == MC_MSG_CLIENT_SET) {
/* check privileage */
- ret = __mc_privilege_ask(client_sock, "mediacontroller::svc", "w");
- if (ret == MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED) {
- mc_error("permission is denied!");
+ ret = mc_cynara_check(&creds, MC_CLIENT_PRIVILEGE);
+ if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+ mc_error("permission is denied![%d]", ret);
send_msg = MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED;
goto ERROR;
}
+ MC_SAFE_FREE(creds.uid);
+ MC_SAFE_FREE(creds.smack);
+
for (i = 0; i < g_list_length(mc_svc_data->mc_svc_list); i++) {
char *nth_data = (char *)g_list_nth_data(mc_svc_data->mc_svc_list, i);
if (nth_data != NULL && strcmp(nth_data, recv_msg.msg) == 0) {
}
} else if (recv_msg.msg_type == MC_MSG_CLIENT_GET) {
/* check privileage */
- ret = __mc_privilege_ask(client_sock, "mediacontroller::svc", "r");
- if (ret == MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED) {
- mc_error("permission is denied!");
+ ret = mc_cynara_check(&creds, MC_SERVER_PRIVILEGE);
+ if (ret != MEDIA_CONTROLLER_ERROR_NONE) {
+ mc_error("permission is denied![%d]", ret);
send_msg = MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED;
goto ERROR;
}
+ MC_SAFE_FREE(creds.uid);
+ MC_SAFE_FREE(creds.smack);
+
for (i = 0; i < g_list_length(mc_svc_data->mc_svc_list); i++) {
send_msg = MEDIA_CONTROLLER_ERROR_PERMISSION_DENIED;
char *nth_data = (char *)g_list_nth_data(mc_svc_data->mc_svc_list, i);
if (close(client_sock) < 0) {
mc_stderror("close failed");
}
+ MC_SAFE_FREE(creds.uid);
+ MC_SAFE_FREE(creds.smack);
return TRUE;
}
return FALSE;
}
+ ret = mc_cynara_enable_credentials_passing(sockfd);
+ if(ret != MEDIA_CONTROLLER_ERROR_NONE) {
+ mc_error("Failed to append socket options");
+ return FALSE;
+ }
+
/* Create list for command*/
mc_svc_data->mc_svc_list = g_list_alloc();
if (mc_svc_data->mc_svc_list == NULL) {