Remove media-util-internal.h
[platform/core/multimedia/media-server.git] / lib / media-util-cynara.c
1 /*
2  * Media Server
3  *
4  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 /**
21  * This file contains Cynara integration code
22  *
23  * @file                media-util-cynara.c
24  * @author      Jacek Bukarewicz (j.bukarewicz@samsung.com)
25  * @version     1.0
26  * @brief
27  */
28
29 #include <glib.h>
30 #include <unistd.h>
31
32 #include <media-util-cynara.h>
33 #include <media-util-dbg.h>
34 #include <media-util-err.h>
35
36 #include <cynara-client.h>
37 #include <cynara-session.h>
38 #include <cynara-error.h>
39 #include <cynara-creds-socket.h>
40
41 static cynara *_cynara = NULL;
42 static cynara_configuration *_p_conf = NULL;
43 G_LOCK_DEFINE_STATIC(cynara_mutex);
44
45 static void ms_cynara_dbg_err(const char *prefix, int error_code)
46 {
47         char error_buffer[256];
48         int err;
49         error_buffer[0] = '\0';
50
51         err = cynara_strerror(error_code, error_buffer, sizeof(error_buffer));
52         if (err == CYNARA_API_SUCCESS)
53                 MSAPI_DBG_ERR("%s: %s", prefix, error_buffer);
54         else
55                 MSAPI_DBG_ERR("%s: error code %i", prefix, error_code);
56 }
57
58 int ms_cynara_initialize(void)
59 {
60         int ret = 0;
61
62         ret = cynara_configuration_create(&_p_conf);
63         if (ret != CYNARA_API_SUCCESS)  {
64                 ms_cynara_dbg_err("cynara_configuration_create", ret);
65                 return MS_MEDIA_ERR_INTERNAL;
66         }
67         ret = cynara_configuration_set_cache_size(_p_conf, 100);
68         if (ret != CYNARA_API_SUCCESS)  {
69                 ms_cynara_dbg_err("cynara_configuration_set_cache_size", ret);
70                 return MS_MEDIA_ERR_INTERNAL;
71         }
72         ret = cynara_initialize(&_cynara, _p_conf);
73         if (ret  != CYNARA_API_SUCCESS) {
74                 ms_cynara_dbg_err("cynara_initialize", ret);
75                 return MS_MEDIA_ERR_INTERNAL;
76         }
77
78         cynara_configuration_destroy(_p_conf);
79
80         return MS_MEDIA_ERR_NONE;
81 }
82
83 void ms_cynara_finish(void)
84 {
85         cynara_finish(_cynara);
86         _cynara = NULL;
87 }
88
89 int ms_cynara_receive_untrusted_message(int sockfd, ms_comm_msg_s *recv_msg, ms_peer_credentials *credentials)
90 {
91         int ret = 0;
92         int recv_msg_size = 0;
93
94         if (!recv_msg || !credentials)
95                 return MS_MEDIA_ERR_INVALID_PARAMETER;
96
97         if ((recv_msg_size = read(sockfd, recv_msg, sizeof(ms_comm_msg_s))) < 0) {
98                 MSAPI_DBG_STRERROR("recv failed");
99                 return MS_MEDIA_ERR_IPC;
100         }
101
102         MSAPI_RETVM_IF(!ms_ipc_is_valid_msg(recv_msg->msg), MS_MEDIA_ERR_IPC, "Invalid msg");
103
104         MSAPI_DBG_SLOG("receive msg from P[%d] T[%d] M[%.*s] S[%.*s]", recv_msg->pid, recv_msg->msg_type, MAX_MSG_SIZE, recv_msg->msg, MS_UUID_SIZE, recv_msg->storage_id);
105
106         if (strlen(recv_msg->storage_id) >= MS_UUID_SIZE) {
107                 MSAPI_DBG_ERR("IPC message is wrong. storage_id size is over MS_UUID_SIZE");
108                 return MS_MEDIA_ERR_IPC;
109         }
110
111         ret = cynara_creds_socket_get_pid(sockfd, &(credentials->pid));
112         MSAPI_RETVM_IF(ret != 0, MS_MEDIA_ERR_INTERNAL, "[CYNARA]Failed to get pid");
113
114         ret = cynara_creds_socket_get_user(sockfd, USER_METHOD_UID, &(credentials->uid));
115         MSAPI_RETVM_IF(ret != 0, MS_MEDIA_ERR_INTERNAL, "[CYNARA]Failed to get uid");
116
117         ret = cynara_creds_socket_get_client(sockfd, CLIENT_METHOD_SMACK, &(credentials->smack));
118         if (ret != 0) {
119                 MSAPI_DBG_ERR("[CYNARA]Failed to get smack");
120                 if (credentials->uid) {
121                         free(credentials->uid);
122                         credentials->uid = NULL;
123                 }
124
125                 return MS_MEDIA_ERR_INTERNAL;
126         }
127
128         return MS_MEDIA_ERR_NONE;
129 }
130
131 int ms_cynara_check(const ms_peer_credentials *creds, const char *privilege)
132 {
133         int result = 0;
134         char *session = NULL;
135
136         if (!creds || !privilege)
137                 return MS_MEDIA_ERR_INVALID_PARAMETER;
138
139         session = cynara_session_from_pid(creds->pid);
140         MSAPI_RETVM_IF(session == NULL, MS_MEDIA_ERR_INTERNAL, "cynara_session_from_pid failed");
141
142         G_LOCK(cynara_mutex);
143         result = cynara_check(_cynara, creds->smack, session, creds->uid, privilege);
144         G_UNLOCK(cynara_mutex);
145
146         if (result != CYNARA_API_ACCESS_ALLOWED)
147                 ms_cynara_dbg_err("cynara_check", result);
148
149         if (session)
150                 free(session);
151
152         return result == CYNARA_API_ACCESS_ALLOWED ? MS_MEDIA_ERR_NONE : MS_MEDIA_ERR_PERMISSION_DENIED;
153 }
154
155 int ms_cynara_enable_credentials_passing(int fd)
156 {
157         const int optval = 1;
158         int err;
159
160         err = setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &optval, sizeof(optval));
161         MSAPI_RETVM_IF(err != 0, MS_MEDIA_ERR_IPC, "Failed to set SO_PASSSEC socket option");
162
163         err = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval));
164         MSAPI_RETVM_IF(err != 0, MS_MEDIA_ERR_IPC, "Failed to set SO_PASSCRED socket option");
165
166         return MS_MEDIA_ERR_NONE;
167 }