Fix latest prevent defects
[platform/core/security/security-manager.git] / src / server2 / 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 <socket-buffer.h>
33 #include <client-common.h>
34 #include <protocols.h>
35 #include <smack-check.h>
36
37 #include <security-server.h>
38 #include <security-server-common.h>
39
40 static int get_exec_path(pid_t pid, std::string &exe)
41 {
42     using namespace SecurityServer;
43
44     try{
45         SocketBuffer send, recv;
46         Serialization ser;
47         ser.Serialize(send, pid);
48
49         int result = sendToServer(
50                 SERVICE_SOCKET_EXEC_PATH,
51                 send.Pop(),
52                 recv);
53         if(result != SECURITY_SERVER_API_SUCCESS)
54             return result;
55
56         Deserialization des;
57         des.Deserialize(recv, result);
58         if(result != SECURITY_SERVER_API_SUCCESS)
59             return result;
60
61         des.Deserialize(recv, exe);
62         return result;
63     } catch (SocketBuffer::Exception::Base &e) {
64         LogDebug("SecurityServer::SocketBuffer::Exception " << e.DumpToString());
65     } catch (std::exception &e) {
66         LogDebug("STD exception " << e.what());
67     } catch (...) {
68         LogDebug("Unknown exception occured");
69     }
70     return SECURITY_SERVER_API_ERROR_UNKNOWN;
71 }
72
73 SECURITY_SERVER_API
74 int security_server_check_privilege_by_sockfd(int sockfd,
75                                               const char *object,
76                                               const char *access_rights)
77 {
78     char *subject = NULL;
79     int ret;
80     std::string path;
81     std::unique_ptr<char, void (*)(void*)throw ()> subjectPtr(NULL, std::free);
82
83     //for get socket options
84     struct ucred cr;
85     size_t len = sizeof(struct ucred);
86
87     //SMACK runtime check
88     if (!smack_runtime_check())
89     {
90         LogDebug("No SMACK support on device");
91         return SECURITY_SERVER_API_SUCCESS;
92     }
93
94     if (sockfd < 0 || !object || !access_rights)
95         return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
96
97     ret = smack_new_label_from_socket(sockfd, &subject);
98     if (ret == 0) {
99         subjectPtr.reset(subject);
100         subject = NULL;
101     } else {
102         LogError("Failed to get new label from socket. Object="
103             << object << ", access=" << access_rights
104             << ", error=" << strerror(errno));
105         return SECURITY_SERVER_API_ERROR_SOCKET;
106     }
107
108     ret = getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, &cr, &len);
109     if (ret < 0) {
110         LogError("Error in getsockopt(). Errno: "
111             << strerror(errno) <<  ", subject="
112             << (subjectPtr.get() ? subjectPtr.get() : "NULL")
113             << ", object=" << object << ", access=" << access_rights
114             << ", error=" << strerror(errno));
115         return SECURITY_SERVER_API_ERROR_SOCKET;
116     }
117
118     ret = security_server_check_privilege_by_pid(cr.pid, object, access_rights);
119
120     //Getting path for logs
121     if (SECURITY_SERVER_API_SUCCESS != get_exec_path(cr.pid, path)) {
122         LogError("Failed to read executable path for process " << cr.pid);
123     }
124
125     if (ret == SECURITY_SERVER_API_SUCCESS)
126         LogSecureDebug("SS_SMACK: caller_pid=" << cr.pid << ", subject=" <<
127             (subjectPtr.get() ? subjectPtr.get() : "NULL") << ", object=" <<
128             object << ", access=" << access_rights << ", result=" <<
129             ret << ", caller_path=" << path.c_str());
130     else
131         LogSecureWarning("SS_SMACK: caller_pid=" << cr.pid << ", subject=" <<
132             (subjectPtr.get() ? subjectPtr.get() : "NULL") << ", object=" <<
133             object << ", access=" << access_rights << ", result=" <<
134             ret << ", caller_path=" << path.c_str());
135
136     return ret;
137 }
138
139 SECURITY_SERVER_API
140 char *security_server_get_smacklabel_sockfd(int fd)
141 {
142     char *label = NULL;
143
144     if (!smack_check())
145     {
146         LogDebug("No SMACK support on device");
147         label = (char*) malloc(1);
148         if (label) label[0] = '\0';
149         return label;
150     }
151
152     if (smack_new_label_from_socket(fd, &label) != 0)
153     {
154         LogError("Client ERROR: Unable to get socket SMACK label");
155         return NULL;
156     }
157
158     return label;
159 }