2 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Rafal Krypa <r.krypa@samsung.com>
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
19 * @file client-common.cpp
20 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
22 * @brief This file is implementation of client-common functions.
27 #include <sys/types.h>
28 #include <sys/socket.h>
30 #include <sys/smack.h>
31 #include <sys/xattr.h>
32 #include <linux/xattr.h>
35 #include <dpl/log/log.h>
36 #include <dpl/serialization.h>
37 #include <dpl/singleton.h>
38 #include <dpl/singleton_safe_impl.h>
40 #include <message-buffer.h>
41 #include <smack-common.h>
43 #include <protocols.h>
45 IMPLEMENT_SAFE_SINGLETON(SecurityManager::Log::LogSystem);
49 const int POLL_TIMEOUT = 2000;
51 void securityClientEnableLogSystem(void) {
52 SecurityManager::Singleton<SecurityManager::Log::LogSystem>::Instance().SetTag("SECURITY_MANAGER_CLIENT");
55 int waitForSocket(int sock, int event, int timeout) {
59 desc[0].events = event;
61 while((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) {
67 LogDebug("Poll timeout");
68 } else if (-1 == retval) {
70 LogError("Error in poll: " << strerror(err));
86 int Connect(char const * const interface) {
87 sockaddr_un clientAddr;
90 if (m_sock != -1) // guard
93 m_sock = socket(AF_UNIX, SOCK_STREAM, 0);
96 LogError("Error creating socket: " << strerror(err));
97 return SECURITY_MANAGER_API_ERROR_SOCKET;
100 if ((flags = fcntl(m_sock, F_GETFL, 0)) < 0 ||
101 fcntl(m_sock, F_SETFL, flags | O_NONBLOCK) < 0)
104 LogError("Error in fcntl: " << strerror(err));
105 return SECURITY_MANAGER_API_ERROR_SOCKET;
108 memset(&clientAddr, 0, sizeof(clientAddr));
110 clientAddr.sun_family = AF_UNIX;
112 if (strlen(interface) >= sizeof(clientAddr.sun_path)) {
113 LogError("Error: interface name " << interface << "is too long. Max len is:" << sizeof(clientAddr.sun_path));
114 return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE;
117 strcpy(clientAddr.sun_path, interface);
119 LogDebug("ClientAddr.sun_path = " << interface);
121 int retval = TEMP_FAILURE_RETRY(connect(m_sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr)));
122 if ((retval == -1) && (errno == EINPROGRESS)) {
123 if (0 >= waitForSocket(m_sock, POLLIN, POLL_TIMEOUT)) {
124 LogError("Error in waitForSocket.");
125 return SECURITY_MANAGER_API_ERROR_SOCKET;
128 socklen_t len = sizeof(error);
129 retval = getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &len);
133 LogError("Error in getsockopt: " << strerror(err));
134 return SECURITY_MANAGER_API_ERROR_SOCKET;
137 if (error == EACCES) {
138 LogError("Access denied");
139 return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED;
143 LogError("Error in connect: " << strerror(error));
144 return SECURITY_MANAGER_API_ERROR_SOCKET;
147 return SECURITY_MANAGER_API_SUCCESS;
152 LogError("Error connecting socket: " << strerror(err));
154 return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED;
156 return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE;
157 return SECURITY_MANAGER_API_ERROR_SOCKET;
160 return SECURITY_MANAGER_API_SUCCESS;
171 } // namespace anonymous
173 namespace SecurityManager {
175 int getSmackLabelFromBinary(char **smackLabel, const char *path)
182 const LabelInfo labels[] = {
183 { XATTR_NAME_SMACKEXEC, 1 },
184 { XATTR_NAME_TIZENEXEC, 1 },
185 { XATTR_NAME_TIZENEXEC, 0 }
188 LogDebug("Entering function: " << __func__ << ". Params: smackLabel=" << smackLabel <<
191 if (smackLabel == NULL) {
192 LogError("getSmackLabelFromBinary: smackLabel is NULL");
193 return SECURITY_MANAGER_API_ERROR_INPUT_PARAM;
197 LogError("getSmackLabelFromBinary: path is NULL");
198 return SECURITY_MANAGER_API_ERROR_INPUT_PARAM;
201 for (const auto &l : labels) {
202 ret = smack_new_label_from_path(path, l.xattr, l.followSymlinks, smackLabel);
204 return SECURITY_MANAGER_API_SUCCESS;
208 LogError("Getting exec label from " << path << " failed");
209 return SECURITY_MANAGER_API_ERROR_GETTING_FILE_LABEL_FAILED;
213 int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) {
219 if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) {
220 LogError("Error in SockRAII");
224 while ((send.size() - done) > 0) {
225 if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) {
226 LogError("Error in poll(POLLOUT)");
227 return SECURITY_MANAGER_API_ERROR_SOCKET;
229 ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done));
232 LogError("Error in write: " << strerror(err));
233 return SECURITY_MANAGER_API_ERROR_SOCKET;
239 if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
240 LogError("Error in poll(POLLIN)");
241 return SECURITY_MANAGER_API_ERROR_SOCKET;
243 ssize_t temp = TEMP_FAILURE_RETRY(read(sock.Get(), buffer, 2048));
246 LogError("Error in read: " << strerror(err));
247 return SECURITY_MANAGER_API_ERROR_SOCKET;
251 LogError("Read return 0/Connection closed by server(?)");
252 return SECURITY_MANAGER_API_ERROR_SOCKET;
255 RawBuffer raw(buffer, buffer+temp);
257 } while(!recv.Ready());
258 return SECURITY_MANAGER_API_SUCCESS;
261 int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) {
266 if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) {
267 LogError("Error in SockRAII");
271 while ((send.size() - done) > 0) {
272 if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) {
273 LogError("Error in poll(POLLOUT)");
274 return SECURITY_MANAGER_API_ERROR_SOCKET;
276 ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done));
279 LogError("Error in write: " << strerror(err));
280 return SECURITY_MANAGER_API_ERROR_SOCKET;
285 if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) {
286 LogError("Error in poll(POLLIN)");
287 return SECURITY_MANAGER_API_ERROR_SOCKET;
290 ssize_t temp = TEMP_FAILURE_RETRY(recvmsg(sock.Get(), &hdr, MSG_CMSG_CLOEXEC));
294 LogError("Error in recvmsg(): " << strerror(err) << " errno: " << err);
295 return SECURITY_MANAGER_API_ERROR_SOCKET;
299 LogError("Read return 0/Connection closed by server(?)");
300 return SECURITY_MANAGER_API_ERROR_SOCKET;
303 return SECURITY_MANAGER_API_SUCCESS;
306 int try_catch(const std::function<int()>& func)
310 } catch (MessageBuffer::Exception::Base &e) {
311 LogError("SecurityManager::MessageBuffer::Exception " << e.DumpToString());
312 } catch (std::exception &e) {
313 LogError("STD exception " << e.what());
315 LogError("Unknown exception occured");
317 return SECURITY_MANAGER_API_ERROR_UNKNOWN;
320 } // namespace SecurityMANAGER
322 static void init_lib(void) __attribute__ ((constructor));
323 static void init_lib(void)
325 securityClientEnableLogSystem();
328 static void fini_lib(void) __attribute__ ((destructor));
329 static void fini_lib(void)