Implement cynara-creds-socket library 88/26888/6
authorRadoslaw Bartosiak <r.bartosiak@samsung.com>
Wed, 3 Sep 2014 19:13:03 +0000 (21:13 +0200)
committerLukasz Wojciechowski <l.wojciechow@partner.samsung.com>
Thu, 4 Sep 2014 11:57:22 +0000 (13:57 +0200)
Change-Id: Ifa27c49c3361547c75d50aa7cbf72e4bd3648201

src/helpers/creds-socket/CMakeLists.txt
src/helpers/creds-socket/creds-socket-inner.cpp [new file with mode: 0644]
src/helpers/creds-socket/creds-socket-inner.h [new file with mode: 0644]
src/helpers/creds-socket/creds-socket.cpp
src/include/cynara-creds-socket.h

index c42e94d..a425c0b 100644 (file)
@@ -25,6 +25,7 @@ SET(LIB_CREDS_SOCKET_PATH ${CYNARA_PATH}/helpers/creds-socket)
 
 SET(LIB_CREDS_SOCKET_SOURCES
     ${LIB_CREDS_SOCKET_PATH}/creds-socket.cpp
+    ${LIB_CREDS_SOCKET_PATH}/creds-socket-inner.cpp
     )
 
 INCLUDE_DIRECTORIES(
diff --git a/src/helpers/creds-socket/creds-socket-inner.cpp b/src/helpers/creds-socket/creds-socket-inner.cpp
new file mode 100644 (file)
index 0000000..a227e5b
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        creds-socket-inner.cpp
+ * @author      Radoslaw Bartosiak <r.bartosiak@samsung.com>
+ * @author      Aleksander Zdyb <a.zdyb@partner.samsung.com>
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       Implementation of internal libcynara-creds-socket functions
+ */
+
+
+#include <errno.h>
+#include <string>
+#include <string.h>
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <cynara-client-error.h>
+
+#include "creds-socket-inner.h"
+
+int getClientSmackLabel(int socketFd, char **client) {
+    char dummy;
+    int ret;
+    socklen_t length = 1;
+    char *result;
+
+    ret = getsockopt(socketFd, SOL_SOCKET, SO_PEERSEC, &dummy, &length);
+    if ((ret < 0) && (errno != ERANGE))
+            return CYNARA_API_INVALID_PARAM;
+
+    result = static_cast<char*>(calloc(length + 1, sizeof(char)));
+    if (result == nullptr)
+            return CYNARA_API_OUT_OF_MEMORY;
+
+    ret = getsockopt(socketFd, SOL_SOCKET, SO_PEERSEC, result, &length);
+    if (ret < 0) {
+            free(result);
+            return CYNARA_API_INVALID_PARAM;
+    }
+
+    *client = result;
+    return CYNARA_API_SUCCESS;
+}
+
+#define GET_CRED(SOCK, RESULT, CRED) \
+    struct ucred credentials; \
+    int ret = getCredentials(SOCK, &credentials); \
+    if (ret < 0) \
+        return ret; \
+ \
+    *RESULT = strdup(std::to_string(credentials.CRED).c_str()); \
+    if (*RESULT == nullptr) \
+            return CYNARA_API_OUT_OF_MEMORY; \
+ \
+    return CYNARA_API_SUCCESS; \
+
+int getClientPid(int socketFd, char **client) {
+    GET_CRED(socketFd, client, pid)
+}
+
+int getUserId(int socketFd, char **user) {
+    GET_CRED(socketFd, user, uid)
+}
+
+int getUserGid(int socketFd, char **user) {
+    GET_CRED(socketFd, user, gid)
+}
+
+int getCredentials(int socketFd, struct ucred *credentials) {
+    if (credentials == nullptr)
+        return CYNARA_API_UNKNOWN_ERROR;
+
+    int ret;
+    socklen_t length = sizeof(struct ucred);
+    ret = getsockopt(socketFd, SOL_SOCKET, SO_PEERCRED, credentials, &length);
+    if (ret < 0) {
+        switch (errno) {
+            case EBADF:
+            case ENOTSOCK:
+                return CYNARA_API_INVALID_PARAM;
+            default:
+                return CYNARA_API_UNKNOWN_ERROR;
+        }
+    }
+    return CYNARA_API_SUCCESS;
+}
+
+int getPid(int socketFd, pid_t *pid) {
+    struct ucred credentials;
+    int ret = getCredentials(socketFd, &credentials);
+    if (ret < 0)
+        return ret;
+
+    *pid = credentials.pid;
+
+    return CYNARA_API_SUCCESS;
+}
diff --git a/src/helpers/creds-socket/creds-socket-inner.h b/src/helpers/creds-socket/creds-socket-inner.h
new file mode 100644 (file)
index 0000000..3edb151
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        creds-socket-inner.h
+ * @author      Radoslaw Bartosiak <r.bartosiak@samsung.com>
+ * @author      Aleksander Zdyb <a.zdyb@partner.samsung.com>
+ * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
+ * @version     1.0
+ * @brief       Definition of internal external libcynara-creds-socket functions
+ */
+
+#ifndef SRC_HELPERS_CREDSSOCKET_CREDSSOCKETINNER_H_
+#define SRC_HELPERS_CREDSSOCKET_CREDSSOCKETINNER_H_
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+int getClientSmackLabel(int socketFd, char **client);
+
+int getClientPid(int socketFd, char **client);
+int getUserId(int socketFd, char **user);
+int getUserGid(int socketFd, char **user);
+
+int getCredentials(int socketFd, struct ucred *credentials);
+
+int getPid(int socketFd, pid_t *pid);
+
+#endif /* SRC_HELPERS_CREDSSOCKET_CREDSSOCKETINNER_H_ */
index 0ee2661..a135f87 100644 (file)
  */
 /*
  * @file        creds-socket.cpp
+ * @author      Radoslaw Bartosiak <r.bartosiak@samsung.com>
+ * @author      Aleksander Zdyb <a.zdyb@partner.samsung.com>
  * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
  * @version     1.0
  * @brief       Implementation of external libcynara-creds-socket API
  */
 
-// Empty initial file
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <attributes/attributes.h>
+
+#include <creds-socket-inner.h>
+
+#include <cynara-client-error.h>
+#include <cynara-creds-commons.h>
+#include <cynara-creds-socket.h>
+
+CYNARA_API
+int cynara_creds_socket_get_client(int socket_fd, enum cynara_client_creds method, char **client) {
+    if (client == nullptr)
+        return CYNARA_API_INVALID_PARAM;
+
+    switch (method) {
+        case cynara_client_creds::CLIENT_METHOD_SMACK:
+            return getClientSmackLabel(socket_fd, client);
+        case cynara_client_creds::CLIENT_METHOD_PID:
+            return getClientPid(socket_fd, client);
+        default:
+            return CYNARA_API_METHOD_NOT_SUPPORTED;
+    }
+}
+
+CYNARA_API
+int cynara_creds_socket_get_user(int socket_fd, enum cynara_user_creds method, char **user) {
+    if (user == nullptr)
+        return CYNARA_API_INVALID_PARAM;
+
+    switch (method) {
+        case cynara_user_creds::USER_METHOD_UID:
+            return getUserId(socket_fd, user);
+        case cynara_user_creds::USER_METHOD_GID:
+            return getUserGid(socket_fd, user);
+        default:
+            return CYNARA_API_METHOD_NOT_SUPPORTED;
+    }
+}
+
+CYNARA_API
+int cynara_creds_socket_get_pid(int socket_fd, pid_t *pid) {
+    return getPid(socket_fd, pid);
+}
index bc89684..1b6c09e 100644 (file)
@@ -15,6 +15,8 @@
  */
 /*
  * @file        cynara-creds-socket.h
+ * @author      Radoslaw Bartosiak <r.bartosiak@samsung.com>
+ * @author      Aleksander Zdyb <a.zdyb@partner.samsung.com>
  * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
  * @version     1.0
  * @brief       This file contains Cynara credentials helper APIs for socket clients.
 #ifndef CYNARA_CREDS_SOCKET_H
 #define CYNARA_CREDS_SOCKET_H
 
+#include <sys/types.h>
+
+#include "cynara-creds-commons.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/* empty initial file */
+/**
+ * \par Description:
+ * Creates a client identification string with given method. Client is a process at the other
+ * side of socket.
+ *
+ * \par Purpose:
+ * Client identification string is required for cynara_check() and cynara_async_check() functions.
+ *
+ * \par Typical use case:
+ * The function is called before the call of one of ...check() functions.
+ * Returned string is used as client parameter in ...check() function.
+ * String is released with free() function when it is no longer needed.
+ *
+ * \par Method of function operation:
+ * The function generates client string using SO_PEERCRED on socket.
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \par Thread safety:
+ * This function is NOT thread-safe. If functions from described API are called by multithreaded
+ * application from different threads, they must be put into mutex protected critical section.
+ *
+ * \par Important notes:
+ * Memory for returned client string is obtained with malloc(), and should be freed with free().
+ * Allocated string is returned only, when function succeeds.
+ *
+ * \param[in] socket_fd Descriptor of open connected UNIX socket
+ * \param[in] method Method of client identifier creation
+ * \param[out] client Placeholder for allocated string containing client id
+ *
+ * \return CYNARA_API_SUCCESS on success
+ *         CYNARA_API_INVALID_PARAM when client is NULL or socket_fd is not valid connected socket
+ *                                  descriptor
+ *         CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported
+ *         CYNARA_API_OUT_OF_MEMORY when there was error allocating memory
+ */
+int cynara_creds_socket_get_client(int socket_fd, enum cynara_client_creds method, char **client);
+
+/**
+ * \par Description:
+ * Creates a user identification string with given method. User is an executor of process
+ * at the other side of socket.
+ *
+ * \par Purpose:
+ * User identification string is required for cynara_check() and cynara_async_check() functions.
+ *
+ * \par Typical use case:
+ * The function is called before the call of one of ...check() functions.
+ * Returned string is used as user parameter in ...check() function.
+ * String is released with free() function when it is no longer needed.
+ *
+ * \par Method of function operation:
+ * The function generates user string using SO_PEERCRED on socket.
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \par Thread safety:
+ * This function is NOT thread-safe. If functions from described API are called by multithreaded
+ * application from different threads, they must be put into mutex protected critical section.
+ *
+ * \par Important notes:
+ * Memory for returned user string is obtained with malloc(), and should be freed with free().
+ * Allocated string is returned only, when function succeeds.
+ *
+ * \param[in] socket_fd Descriptor of open connected UNIX socket
+ * \param[in] method Method of user identifier creation
+ * \param[out] user Placeholder for allocated string containing user id
+ *
+ * \return CYNARA_API_SUCCESS on success
+ *         CYNARA_API_INVALID_PARAM when user is NULL or socket_fd is not valid connected socket
+ *                                  descriptor
+ *         CYNARA_API_METHOD_NOT_SUPPORTED when requested method is not supported
+ *         CYNARA_API_OUT_OF_MEMORY when there was error allocating memory
+ */
+int cynara_creds_socket_get_user(int socket_fd, enum cynara_user_creds method, char **user);
+
+/**
+ * \par Description:
+ * Return PID of process at the other side of socket.
+ *
+ * \par Purpose:
+ * PID may be used for client_session creation with cynara_session_from_pid() function
+ * from libcynara-session library. Client_session is needed for cynara_check()
+ * and cynara_async_check() functions.
+ *
+ * \par Typical use case:
+ * The function is called before the call of cynara_session_from_pid() function.
+ *
+ * \par Method of function operation:
+ * The function reads PID of peer using SO_PEERCRED on socket.
+ *
+ * \par Sync (or) Async:
+ * This is a synchronous API.
+ *
+ * \par Thread safety:
+ * This function is NOT thread-safe. If functions from described API are called by multithreaded
+ * application from different threads, they must be put into mutex protected critical section.
+ *
+ * \param[in] socket_fd Descriptor of open connected UNIX socket
+ * \param[out] pid Placeholder for pid
+ *
+ * \return CYNARA_API_SUCCESS on success
+ *         CYNARA_API_INVALID_PARAM when socket_fd is not valid connected socket descriptor
+ *         CYNARA_API_UNKNOWN_ERROR when system function fails in incredible situation
+ */
+int cynara_creds_socket_get_pid(int socket_fd, pid_t *pid);
 
 #ifdef __cplusplus
 }