fix invalid format argument types for dlog
[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  * Contact: Yong Yeon Kim <yy9875.kim@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22 /**
23  * This file contains Cynara integration code
24  *
25  * @file                media-util-cynara.c
26  * @author      Jacek Bukarewicz (j.bukarewicz@samsung.com)
27  * @version     1.0
28  * @brief
29  */
30
31 #include <errno.h>
32 #include <glib.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <sys/socket.h>
36 #include <unistd.h>
37
38 #include <media-util-cynara.h>
39 #include <media-util-dbg.h>
40 #include <media-util-err.h>
41 #include <media-util-ipc.h>
42 #include <media-util-internal.h>
43
44 #include <cynara-client.h>
45 #include <cynara-session.h>
46 #include <cynara-error.h>
47 #include <cynara-creds-socket.h>
48
49
50 /* this definition is missing in glibc headers (version 2.21). It was introduced in kernel version 2.6.17 */
51 #ifndef SCM_SECURITY
52 #define SCM_SECURITY 0x03
53 #endif
54
55 static cynara *_cynara = NULL;
56 static cynara_configuration *_p_conf = NULL;
57 G_LOCK_DEFINE_STATIC(cynara_mutex);
58
59 static void ms_cynara_dbg_err(const char *prefix, int error_code)
60 {
61         char error_buffer[256];
62         int err;
63         error_buffer[0] = '\0';
64
65         err = cynara_strerror(error_code, error_buffer, sizeof(error_buffer));
66         if (err == CYNARA_API_SUCCESS) {
67                 MSAPI_DBG_ERR("%s: %s", prefix, error_buffer);
68         } else {
69                 MSAPI_DBG_ERR("%s: error code %i", prefix, error_code);
70         }
71 }
72
73 int ms_cynara_initialize(void)
74 {
75         int ret = 0;
76
77         ret = cynara_configuration_create(&_p_conf);
78         if (ret != CYNARA_API_SUCCESS)  {
79                 ms_cynara_dbg_err("cynara_configuration_create", ret);
80                 return MS_MEDIA_ERR_INTERNAL;
81         }
82         ret = cynara_configuration_set_cache_size(_p_conf, 100);
83         if (ret != CYNARA_API_SUCCESS)  {
84                 ms_cynara_dbg_err("cynara_configuration_set_cache_size", ret);
85                 return MS_MEDIA_ERR_INTERNAL;
86         }
87         ret = cynara_initialize(&_cynara, _p_conf);
88         if (ret  != CYNARA_API_SUCCESS) {
89                 ms_cynara_dbg_err("cynara_initialize", ret);
90                 return MS_MEDIA_ERR_INTERNAL;
91         }
92
93         cynara_configuration_destroy(_p_conf);
94
95         return MS_MEDIA_ERR_NONE;
96 }
97
98 void ms_cynara_finish(void)
99 {
100         cynara_finish(_cynara);
101         _cynara = NULL;
102 }
103
104 int ms_cynara_receive_untrusted_message(int sockfd, ms_comm_msg_s *recv_msg, ms_peer_credentials *credentials)
105 {
106         int ret = 0;
107         int recv_msg_size = 0;
108
109         if (!recv_msg || !credentials)
110                 return MS_MEDIA_ERR_INVALID_PARAMETER;
111
112         if ((recv_msg_size = read(sockfd, recv_msg, sizeof(ms_comm_msg_s))) < 0) {
113                 if (errno == EWOULDBLOCK) {
114                         MSAPI_DBG_ERR("Timeout. Can't try any more");
115                         return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
116                 } else {
117                         MSAPI_DBG_ERR("recv failed");
118                         return MS_MEDIA_ERR_SOCKET_RECEIVE;
119                 }
120         }
121
122         MSAPI_DBG_SLOG("receive msg from [%d] %d, %s", recv_msg->pid, recv_msg->msg_type, recv_msg->msg);
123
124         if (!(recv_msg->msg_size > 0 && recv_msg->msg_size < MAX_MSG_SIZE)) {
125                 MSAPI_DBG_ERR("IPC message is wrong. message size is %d", recv_msg->msg_size);
126                 return MS_MEDIA_ERR_INVALID_IPC_MESSAGE;
127         }
128
129         ret = cynara_creds_socket_get_pid(sockfd, &(credentials->pid));
130         if (ret < 0) {
131                 MSAPI_DBG_ERR("cynara_creds_socket_get_pid failed");
132                 return MS_MEDIA_ERR_INTERNAL;
133         }
134
135         ret = cynara_creds_socket_get_user(sockfd, USER_METHOD_UID, &(credentials->uid));
136         if (ret < 0) {
137                 MSAPI_DBG_ERR("cynara_creds_socket_get_user failed");
138                 return MS_MEDIA_ERR_INTERNAL;
139         }
140
141         ret = cynara_creds_socket_get_client(sockfd, CLIENT_METHOD_SMACK, &(credentials->smack));
142         if (ret < 0) {
143                 MSAPI_DBG_ERR("cynara_creds_socket_get_client failed");
144                 return MS_MEDIA_ERR_INTERNAL;
145         }
146
147 //      MSAPI_DBG_ERR("cynara_creds_info : P[%d]U[%s]S[%s]", credentials->pid, credentials->uid, credentials->smack);
148
149         return MS_MEDIA_ERR_NONE;
150 }
151
152 int ms_cynara_receive_untrusted_message_thumb(int sockfd, thumbMsg *recv_msg, ms_peer_credentials *credentials)
153 {
154         int ret = 0;
155         int header_size = 0;
156         int recv_msg_size = 0;
157         unsigned char *buf = NULL;
158
159         if (!recv_msg || !credentials)
160                 return MS_MEDIA_ERR_INVALID_PARAMETER;
161
162         header_size = sizeof(thumbMsg) -(MAX_FILEPATH_LEN * 2) - sizeof(unsigned char *);
163         MS_MALLOC(buf, header_size);
164
165         if ((recv_msg_size = recv(sockfd, buf, header_size, 0)) < 0) {
166                 if (errno == EWOULDBLOCK) {
167                         MSAPI_DBG_ERR("Timeout. Can't try any more");
168                         MS_SAFE_FREE(buf);
169                         return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
170                 } else {
171                         MSAPI_DBG_ERR("recv failed");
172                         MS_SAFE_FREE(buf);
173                         return MS_MEDIA_ERR_SOCKET_RECEIVE;
174                 }
175         }
176
177         memcpy(recv_msg, buf, header_size);
178
179         MS_SAFE_FREE(buf);
180
181         if (recv_msg->origin_path_size <= 0) {
182                 MS_SAFE_FREE(buf);
183                 MSAPI_DBG_ERR("msg->origin_path_size is invalid %d", recv_msg->origin_path_size);
184                 return MS_MEDIA_ERR_INVALID_PARAMETER;
185         }
186
187         MS_MALLOC(buf, (unsigned int)(recv_msg->origin_path_size));
188         if (buf == NULL) {
189                 MSAPI_DBG_STRERROR("malloc failed");
190                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
191         }
192
193         if ((recv_msg_size = recv(sockfd, buf, recv_msg->origin_path_size, 0)) < 0) {
194                 MS_SAFE_FREE(buf);
195                 if (errno == EWOULDBLOCK) {
196                         MSAPI_DBG_ERR("Timeout. Can't try any more");
197                         return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
198                 } else {
199                         MSAPI_DBG_ERR("recv failed");
200                         return MS_MEDIA_ERR_SOCKET_RECEIVE;
201                 }
202
203         }
204
205         SAFE_STRLCPY(recv_msg->org_path, (char*)buf, sizeof(recv_msg->org_path));
206         MS_SAFE_FREE(buf);
207
208         if (recv_msg->dest_path_size <= 0) {
209                 MS_SAFE_FREE(buf);
210                 MSAPI_DBG_ERR("msg->origin_path_size is invalid %d", recv_msg->dest_path_size);
211                 return MS_MEDIA_ERR_INVALID_PARAMETER;
212         }
213
214         MS_MALLOC(buf, (unsigned int)(recv_msg->dest_path_size));
215         if (buf == NULL) {
216                 MSAPI_DBG_STRERROR("malloc failed");
217                 return MS_MEDIA_ERR_OUT_OF_MEMORY;
218         }
219
220         if ((recv_msg_size = recv(sockfd, buf, recv_msg->dest_path_size, 0)) < 0) {
221                 MS_SAFE_FREE(buf);
222                 if (errno == EWOULDBLOCK) {
223                         MSAPI_DBG_ERR("Timeout. Can't try any more");
224                         return MS_MEDIA_ERR_SOCKET_RECEIVE_TIMEOUT;
225                 } else {
226                         MSAPI_DBG_ERR("recv failed");
227                         return MS_MEDIA_ERR_SOCKET_RECEIVE;
228                 }
229
230         }
231
232         SAFE_STRLCPY(recv_msg->dst_path, (char*)buf, sizeof(recv_msg->dst_path));
233         MS_SAFE_FREE(buf);
234
235
236         ret = cynara_creds_socket_get_pid(sockfd, &(credentials->pid));
237         if (ret < 0) {
238                 MSAPI_DBG_ERR("cynara_creds_socket_get_pid failed");
239                 return MS_MEDIA_ERR_INTERNAL;
240         }
241
242         ret = cynara_creds_socket_get_user(sockfd, USER_METHOD_UID, &(credentials->uid));
243         if (ret < 0) {
244                 MSAPI_DBG_ERR("cynara_creds_socket_get_user failed");
245                 return MS_MEDIA_ERR_INTERNAL;
246         }
247
248         ret = cynara_creds_socket_get_client(sockfd, CLIENT_METHOD_SMACK, &(credentials->smack));
249         if (ret < 0) {
250                 MSAPI_DBG_ERR("cynara_creds_socket_get_client failed");
251                 return MS_MEDIA_ERR_INTERNAL;
252         }
253
254 //      MSAPI_DBG_ERR("cynara_creds_info : P[%d]U[%s]S[%s]", credentials->pid, credentials->uid, credentials->smack);
255
256         return MS_MEDIA_ERR_NONE;
257 }
258
259 int ms_cynara_check(const ms_peer_credentials *creds, const char *privilege)
260 {
261         int result;
262         char *session;
263
264         if (!creds || !privilege)
265                 return MS_MEDIA_ERR_INVALID_PARAMETER;
266
267         session = cynara_session_from_pid(creds->pid);
268         if (session == NULL) {
269                 MSAPI_DBG_ERR("cynara_session_from_pid failed");
270                 return MS_MEDIA_ERR_INTERNAL;
271         }
272
273         G_LOCK(cynara_mutex);
274         result = cynara_check(_cynara, creds->smack, session, creds->uid, privilege);
275         G_UNLOCK(cynara_mutex);
276
277         if (result != CYNARA_API_ACCESS_ALLOWED)
278                 ms_cynara_dbg_err("cynara_check", result);
279
280         MS_SAFE_FREE(session);
281         return result == CYNARA_API_ACCESS_ALLOWED ? MS_MEDIA_ERR_NONE : MS_MEDIA_ERR_PERMISSION_DENIED;
282 }
283
284 int ms_cynara_enable_credentials_passing(int fd)
285 {
286         const int optval = 1;
287         int err;
288
289         err = setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &optval, sizeof(optval));
290         if (err != 0) {
291                 MSAPI_DBG_ERR("Failed to set SO_PASSSEC socket option");
292                 return MS_MEDIA_ERR_SOCKET_INTERNAL;
293         }
294
295         err = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval));
296         if (err != 0) {
297                 MSAPI_DBG_ERR("Failed to set SO_PASSCRED socket option");
298                 return MS_MEDIA_ERR_SOCKET_INTERNAL;
299         }
300
301         return MS_MEDIA_ERR_NONE;
302 }
303
304