Prepare release for tizen.org
[platform/core/security/security-manager.git] / src / server / client / client-socket-privilege.cpp
1 /*
2  *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Bumjin Im <bj.im@samsung.com>
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  * @file        client-socket-privilege.cpp
20  * @author      Zofia Abramowska (z.abramowska@samsung.com)
21  * @version     1.0
22  * @brief       This file constains implementation of socket privilege api.
23  */
24 #include <memory>
25
26 #include <sys/socket.h>
27 #include <sys/smack.h>
28
29 #include <dpl/log/log.h>
30 #include <dpl/exception.h>
31
32 #include <message-buffer.h>
33 #include <client-common.h>
34 #include <protocols.h>
35 #include <smack-check.h>
36
37 #include <security-server.h>
38
39 SECURITY_SERVER_API
40 int security_server_check_privilege_by_sockfd(int sockfd,
41                                               const char *object,
42                                               const char *access_rights)
43 {
44     char *subject = NULL;
45     int ret;
46     std::string path;
47     std::unique_ptr<char, void (*)(void*)throw ()> subjectPtr(NULL, std::free);
48
49     //for get socket options
50     struct ucred cr;
51     size_t len = sizeof(struct ucred);
52
53     //SMACK runtime check
54     if (!SecurityServer::smack_runtime_check())
55     {
56         LogDebug("No SMACK support on device");
57         return SECURITY_SERVER_API_SUCCESS;
58     }
59
60     if (sockfd < 0 || !object || !access_rights)
61         return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
62
63     ret = smack_new_label_from_socket(sockfd, &subject);
64     if (ret >= 0) {
65         subjectPtr.reset(subject);
66         subject = NULL;
67     } else {
68         LogError("Failed to get new label from socket. Object="
69             << object << ", access=" << access_rights
70             << ", error=" << strerror(errno));
71         return SECURITY_SERVER_API_ERROR_SOCKET;
72     }
73
74     ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
75     if (ret < 0) {
76         LogError("Error in getsockopt(). Errno: "
77             << strerror(errno) <<  ", subject="
78             << (subjectPtr.get() ? subjectPtr.get() : "NULL")
79             << ", object=" << object << ", access=" << access_rights
80             << ", error=" << strerror(errno));
81         return SECURITY_SERVER_API_ERROR_SOCKET;
82     }
83
84     return security_server_check_privilege_by_pid(cr.pid, object, access_rights);
85 }
86
87 SECURITY_SERVER_API
88 char *security_server_get_smacklabel_sockfd(int fd)
89 {
90     char *label = NULL;
91
92     if (!SecurityServer::smack_check())
93     {
94         LogDebug("No SMACK support on device");
95         label = (char*) malloc(1);
96         if (label) label[0] = '\0';
97         return label;
98     }
99
100     if (smack_new_label_from_socket(fd, &label) < 0)
101     {
102         LogError("Client ERROR: Unable to get socket SMACK label");
103         return NULL;
104     }
105
106     return label;
107 }