Implemented security_server_get_gid function in new framework.
authorJan Olszak <j.olszak@samsung.com>
Tue, 9 Jul 2013 10:03:56 +0000 (12:03 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 12 Jul 2013 09:18:54 +0000 (11:18 +0200)
[Issue#] Function for new security-server framework.
[Bug/Feature] Check GID in new security-server.
[Cause] N/A
[Solution] Used old implementation with small changes.
[Verification]  Build, install, run tests.

Change-Id: I3032d80dc2af8d9fa40f4aa7ab8cbf9d0daa0919

src/CMakeLists.txt
src/client/security-server-client.c
src/server2/client/client-get-gid.cpp [new file with mode: 0644]
src/server2/common/protocols.cpp
src/server2/common/protocols.h
src/server2/main/server2-main.cpp
src/server2/service/get-gid.cpp [new file with mode: 0644]
src/server2/service/get-gid.h [new file with mode: 0644]

index 937e0d7..c2e9b18 100644 (file)
@@ -21,6 +21,7 @@ SET(SECURITY_SERVER_SOURCES
     ${SERVER2_PATH}/main/server2-main.cpp
     ${SERVER2_PATH}/service/data-share.cpp
     ${SERVER2_PATH}/service/echo.cpp
+    ${SERVER2_PATH}/service/get-gid.cpp
     )
 
 SET_SOURCE_FILES_PROPERTIES(
@@ -61,6 +62,7 @@ INCLUDE_DIRECTORIES(
 SET(SECURITY_CLIENT_SOURCES
     ${SECURITY_SERVER_PATH}/server2/client/client-common.cpp
     ${SECURITY_SERVER_PATH}/server2/client/client-shared-memory.cpp
+    ${SECURITY_SERVER_PATH}/server2/client/client-get-gid.cpp
     ${SECURITY_SERVER_PATH}/client/security-server-client.c
     ${SECURITY_SERVER_PATH}/communication/security-server-comm.c
     ${SECURITY_SERVER_PATH}/util/smack-check.c
index b2af44c..4274f9e 100644 (file)
@@ -238,91 +238,91 @@ out:
 }
 
 
-SECURITY_SERVER_API
-int security_server_get_gid(const char *object)
-{
-    int sockfd = -1, retval, gid;
-    response_header hdr;
-
-    if (object == NULL)
-    {
-        SEC_SVR_ERR("%s", "Client: object is null or object is too big");
-        retval = SECURITY_SERVER_API_ERROR_INPUT_PARAM;
-        goto error;
-    }
-    if (strlen(object) > SECURITY_SERVER_MAX_OBJ_NAME)
-    {
-        SEC_SVR_ERR("%s", "object is null or object is too big");
-        retval = SECURITY_SERVER_API_ERROR_INPUT_PARAM;
-        goto error;
-    }
-
-    if (strlen(object) == 0)
-    {
-        SEC_SVR_ERR("Client: object is is empty");
-        retval = SECURITY_SERVER_API_ERROR_INPUT_PARAM;
-        goto error;
-    }
-
-    SECURE_SLOGD("%s", "Client: security_server_get_gid() is called");
-    retval = connect_to_server(&sockfd);
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        /* Error on socket */
-        SEC_SVR_ERR("Connection failed: %d", retval);
-        goto error;
-    }
-    SECURE_SLOGD("%s", "Client: Security server has been connected");
-
-    /* make request packet and send to server*/
-    retval = send_gid_request(sockfd, object);
-    SEC_SVR_DBG("%s", "Client: gid request has been sent");
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        /* Error on socket */
-        SEC_SVR_ERR("Send gid request failed: %d", retval);
-        goto error;
-    }
-
-    /* Receive response */
-    retval = recv_get_gid_response(sockfd, &hdr, &gid);
-    if (retval != SECURITY_SERVER_SUCCESS)
-    {
-        SEC_SVR_ERR("Client: Receive response failed: %d", retval);
-        goto error;
-    }
-    SEC_SVR_DBG("%s", "Client: get gid response has been received");
-
-    if (hdr.basic_hdr.msg_id != SECURITY_SERVER_MSG_TYPE_GID_RESPONSE)   /* Wrong response */
-    {
-        if (hdr.basic_hdr.msg_id == SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE)
-        {
-            /* There must be some error */
-            SEC_SVR_ERR("Client: It'll be an error. return code:%d", hdr.return_code);
-            retval = return_code_to_error_code(hdr.return_code);
-            goto error;
-        }
-        else
-        {
-            /* Something wrong with response */
-            SEC_SVR_ERR("Client: Something wrong with response:%d", hdr.basic_hdr.msg_id);
-            retval = SECURITY_SERVER_ERROR_BAD_RESPONSE;
-            goto error;
-        }
-    }
-
-    SEC_SVR_DBG("received gid is %d", gid);
-    retval = gid;
-
-error:
-    if (sockfd > 0)
-        close(sockfd);
-    /* If error happened */
-    if (retval < 0)
-        retval = convert_to_public_error_code(retval);
-
-    return retval;
-}
+// SECURITY_SERVER_API
+// int security_server_get_gid(const char *object)
+// {
+//     int sockfd = -1, retval, gid;
+//     response_header hdr;
+
+//     if (object == NULL)
+//     {
+//         SEC_SVR_ERR("%s", "Client: object is null or object is too big");
+//         retval = SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+//         goto error;
+//     }
+//     if (strlen(object) > SECURITY_SERVER_MAX_OBJ_NAME)
+//     {
+//         SEC_SVR_ERR("%s", "object is null or object is too big");
+//         retval = SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+//         goto error;
+//     }
+
+//     if (strlen(object) == 0)
+//     {
+//         SEC_SVR_ERR("Client: object is is empty");
+//         retval = SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+//         goto error;
+//     }
+
+//     SECURE_SLOGD("%s", "Client: security_server_get_gid() is called");
+//     retval = connect_to_server(&sockfd);
+//     if (retval != SECURITY_SERVER_SUCCESS)
+//     {
+//         /* Error on socket */
+//         SEC_SVR_ERR("Connection failed: %d", retval);
+//         goto error;
+//     }
+//     SECURE_SLOGD("%s", "Client: Security server has been connected");
+
+//     /* make request packet and send to server*/
+//     retval = send_gid_request(sockfd, object);
+//     SEC_SVR_DBG("%s", "Client: gid request has been sent");
+//     if (retval != SECURITY_SERVER_SUCCESS)
+//     {
+//         /* Error on socket */
+//         SEC_SVR_ERR("Send gid request failed: %d", retval);
+//         goto error;
+//     }
+
+//     /* Receive response */
+//     retval = recv_get_gid_response(sockfd, &hdr, &gid);
+//     if (retval != SECURITY_SERVER_SUCCESS)
+//     {
+//         SEC_SVR_ERR("Client: Receive response failed: %d", retval);
+//         goto error;
+//     }
+//     SEC_SVR_DBG("%s", "Client: get gid response has been received");
+
+//     if (hdr.basic_hdr.msg_id != SECURITY_SERVER_MSG_TYPE_GID_RESPONSE)   /* Wrong response */
+//     {
+//         if (hdr.basic_hdr.msg_id == SECURITY_SERVER_MSG_TYPE_GENERIC_RESPONSE)
+//         {
+//             /* There must be some error */
+//             SEC_SVR_ERR("Client: It'll be an error. return code:%d", hdr.return_code);
+//             retval = return_code_to_error_code(hdr.return_code);
+//             goto error;
+//         }
+//         else
+//         {
+//             /* Something wrong with response */
+//             SEC_SVR_ERR("Client: Something wrong with response:%d", hdr.basic_hdr.msg_id);
+//             retval = SECURITY_SERVER_ERROR_BAD_RESPONSE;
+//             goto error;
+//         }
+//     }
+
+//     SEC_SVR_DBG("received gid is %d", gid);
+//     retval = gid;
+
+// error:
+//     if (sockfd > 0)
+//         close(sockfd);
+//     /* If error happened */
+//     if (retval < 0)
+//         retval = convert_to_public_error_code(retval);
+
+//     return retval;
+// }
 
 
 
diff --git a/src/server2/client/client-get-gid.cpp b/src/server2/client/client-get-gid.cpp
new file mode 100644 (file)
index 0000000..db4d863
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        client-get-gid.cpp
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     1.0
+ * @brief       This file constains implementation of get GID function.
+ */
+
+#include <stdio.h>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <socket-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+
+#include <security-server.h>
+#include <security-server-common.h>
+
+SECURITY_SERVER_API
+int security_server_get_gid(const char *objectName) {
+    using namespace SecurityServer;
+    try {
+        if (NULL == objectName){
+            LogDebug("Objects name is NULL");
+            return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+        }
+
+        int objectsNameLen = strlen(objectName);
+        if (0 == objectsNameLen || objectsNameLen > SECURITY_SERVER_MAX_OBJ_NAME){
+            LogDebug("Objects name is empty or too long");
+            return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+        }
+
+        SocketBuffer send, recv;
+        Serialization ser;
+        ser.Serialize(send, std::string(objectName));
+
+        int retCode = sendToServer(
+          SERVICE_SOCKET_GET_GID,
+          send.Pop(),
+          recv);
+
+        if (retCode != SECURITY_SERVER_API_SUCCESS)
+            return retCode;
+
+        Deserialization des;
+        des.Deserialize(recv, retCode);
+
+        // Return if errors
+        if (retCode < 0)
+            return retCode;
+
+        // No errors, return gid
+        gid_t gid;
+        des.Deserialize(recv, gid);
+        return gid;
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogDebug("SecurityServer::SocketBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogDebug("STD exception " << e.what());
+    } catch (...) {
+        LogDebug("Unknown exception occured");
+    }
+    return SECURITY_SERVER_API_ERROR_UNKNOWN;
+}
+
index dea97c8..3126977 100644 (file)
@@ -29,7 +29,8 @@ namespace SecurityServer {
 char const * const SERVICE_SOCKET_SHARED_MEMORY =
     "/tmp/.security-server-api-data-share.sock";
 char const * const SERVICE_SOCKET_ECHO =
-    "/tmp/.security-server-api-echo.sock";
-
+    "/tmp/security-server-api-echo.sock";
+char const * const SERVICE_SOCKET_GET_GID =
+    "/tmp/security-server-api-get-gid.sock";
 } // namespace SecurityServer
 
index 9ab3dbe..c09a1f7 100644 (file)
@@ -29,6 +29,7 @@ namespace SecurityServer {
 
 extern char const * const SERVICE_SOCKET_SHARED_MEMORY;
 extern char const * const SERVICE_SOCKET_ECHO;
+extern char const * const SERVICE_SOCKET_GET_GID;
 
 } // namespace SecuritySever
 
index 94be9bb..46d2641 100644 (file)
@@ -32,6 +32,7 @@
 #include <socket-manager.h>
 
 #include <data-share.h>
+#include <get-gid.h>
 #include <echo.h>
 
 IMPLEMENT_SAFE_SINGLETON(SecurityServer::Log::LogSystem);
@@ -52,6 +53,10 @@ int server2(void) {
         shmService->Create();
         manager.RegisterSocketService(shmService);
 
+        SecurityServer::GetGidService *getGidService = new SecurityServer::GetGidService;
+        getGidService->Create();
+        manager.RegisterSocketService(getGidService);
+
         manager.MainLoop();
     }
     UNHANDLED_EXCEPTION_HANDLER_END
diff --git a/src/server2/service/get-gid.cpp b/src/server2/service/get-gid.cpp
new file mode 100644 (file)
index 0000000..ba9ebe6
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        get-gid.cpp
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of api-get-gid service.
+ */
+
+#include <sys/smack.h>
+#include <grp.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <protocols.h>
+#include <get-gid.h>
+#include <security-server.h>
+
+namespace SecurityServer {
+
+GenericSocketService::ServiceDescriptionVector GetGidService::GetServiceDescription() {
+    ServiceDescription sd = {
+        "*",
+        0,
+        SERVICE_SOCKET_GET_GID
+    };
+    ServiceDescriptionVector v;
+    v.push_back(sd);
+    return v;
+}
+
+void GetGidService::accept(const AcceptEvent &event) {
+    LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+        << " ConnectionID.counter: " << event.connectionID.counter
+        << " ServiceID: " << event.interfaceID);
+}
+
+void GetGidService::write(const WriteEvent &event) {
+    LogDebug("WriteEvent. ConnectionID: " << event.connectionID.sock <<
+        " Size: " << event.size << " Left: " << event.left);
+    if (event.left == 0)
+        m_serviceManager->Close(event.connectionID);
+}
+
+
+/*
+ * Searches for group ID by given group name
+ */
+int GetGidService::setGid(std::string& obj)
+{
+    int ret = 0;
+    struct group *grpbuf = NULL;
+    struct group grp;
+    std::vector<char> buf;
+
+    /*
+     * The maximum needed size for buf can be found using sysconf(3)
+     * with the argument _SC_GETGR_R_SIZE_MAX. If _SC_GETGR_R_SIZE_MAX is not
+     * returned we set max_buf_size to 1024 bytes. Enough to store few groups.
+     */
+    long int maxBufSize = sysconf(_SC_GETGR_R_SIZE_MAX);
+    if (maxBufSize == -1)
+        maxBufSize = 1024;
+
+
+    /*
+     * There can be some corner cases when for example user is assigned to a
+     * lot of groups. In that case if buffer is to small getgrnam_r will
+     * return ERANGE error. Solution could be calling getgrnam_r with bigger
+     * buffer until it's big enough.
+     */
+    do {
+        try{
+            buf.resize(maxBufSize);
+        }catch(std::bad_alloc&) {
+            ret = SECURITY_SERVER_API_ERROR_OUT_OF_MEMORY;
+            LogError("Out Of Memory");
+            return ret;
+        }
+        maxBufSize *= 2;
+    } while ((ret = getgrnam_r(obj.c_str(), &grp, &(buf[0]), buf.size(), &grpbuf)) == ERANGE);
+
+    // Check for errors:
+    if (ret != 0){
+        ret = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+        LogError("getgrnam_r failed with error: " << strerror(errno));
+        return ret;
+
+    } else if (grpbuf == NULL) {
+        ret = SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT;
+        LogError("Cannot find gid for group: " << obj);
+        return ret;
+    }
+
+    m_gid = grpbuf->gr_gid;
+
+    return ret;
+}
+
+
+bool GetGidService::readOne(const ConnectionID &conn, SocketBuffer &buffer) {
+    LogDebug("Iteration begin");
+    std::string objectName;
+    int retCode = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+    if (!buffer.Ready()) {
+        LogDebug("Got part of message. Service is waiting for the rest.");
+        return false;
+    }
+
+    // Get objects name:
+    Try {
+        SecurityServer::Deserialization des;
+        des.Deserialize(buffer, objectName);
+     } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }
+
+    // Get GID
+    retCode = setGid(objectName);
+
+    // Send the result
+    SecurityServer::Serialization ser;
+    SocketBuffer sendBuffer;
+    ser.Serialize(sendBuffer, retCode);
+    ser.Serialize(sendBuffer, m_gid);
+    m_serviceManager->Write(conn, sendBuffer.Pop());
+    return true;
+}
+
+void GetGidService::read(const ReadEvent &event) {
+    LogDebug("Read event for counter: " << event.connectionID.counter);
+    auto &buffer = m_socketBufferMap[event.connectionID.counter];
+    buffer.Push(event.rawBuffer);
+
+    LogDebug("Pushed to buffer ptr: " << (void*)&buffer);
+
+    // We can get several requests in one package.
+    // Extract and process them all
+    while(readOne(event.connectionID, buffer));
+}
+
+void GetGidService::close(const CloseEvent &event) {
+    LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+    m_socketBufferMap.erase(event.connectionID.counter);
+}
+
+void GetGidService::error(const ErrorEvent &event) {
+    LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
+    m_serviceManager->Close(event.connectionID);
+}
+
+} // namespace SecurityServer
+
diff --git a/src/server2/service/get-gid.h b/src/server2/service/get-gid.h
new file mode 100644 (file)
index 0000000..fd69124
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (c) 2000 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Bumjin Im <bj.im@samsung.com>
+ *
+ *  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        get-gid.h
+ * @author      Jan Olszak (j.olszak@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of api-get-gid
+ */
+
+#ifndef _SECURITY_SERVER_GET_GID_
+#define _SECURITY_SERVER_GET_GID_
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+
+#include <dpl/serialization.h>
+#include <socket-buffer.h>
+
+#include <security-server-common.h>
+
+namespace SecurityServer {
+
+class GetGidService  : 
+    public SecurityServer::GenericSocketService
+  , public SecurityServer::ServiceThread<GetGidService>
+{
+public:
+    typedef std::map<int, SocketBuffer> SocketBufferMap;
+
+    ServiceDescriptionVector GetServiceDescription();
+
+    DECLARE_THREAD_EVENT(AcceptEvent, accept)
+    DECLARE_THREAD_EVENT(WriteEvent, write)
+    DECLARE_THREAD_EVENT(ReadEvent, read)
+    DECLARE_THREAD_EVENT(CloseEvent, close)
+    DECLARE_THREAD_EVENT(ErrorEvent, error)
+
+    void accept(const AcceptEvent &event);
+    void write(const WriteEvent &event);
+    void read(const ReadEvent &event);
+    void close(const CloseEvent &event);
+    void error(const ErrorEvent &event);
+private:
+    gid_t m_gid;
+    bool readOne(const ConnectionID &conn, SocketBuffer &buffer);
+    int  setGid(std::string& objectName);
+    SocketBufferMap m_socketBufferMap;
+};
+
+} // namespace SecurityServer
+
+#endif // _SECURITY_SERVER_GET_GID_