Implement ima/evm set/get state and set/get policy on server side 41/26741/1
authorJanusz Kozerski <j.kozerski@samsung.com>
Wed, 6 Aug 2014 13:03:31 +0000 (15:03 +0200)
committerJanusz Kozerski <j.kozerski@samsung.com>
Thu, 28 Aug 2014 11:41:59 +0000 (13:41 +0200)
List of implemeted fuction:
 * ima_set_state()
 * ima_get_state()
 * evm_set_state()
 * evm_get_state()
 * ima_set_policy()
 * ima_get_policy()

Change-Id: I1587b231a0c5983317302db4de7e8feec0747833
Signed-off-by: Janusz Kozerski <j.kozerski@samsung.com>
15 files changed:
src/CMakeLists.txt
src/include/ima-evm-server.h
src/service/CMakeLists.txt
src/service/client/client-common.h
src/service/client/client-ima-evm-server-set-state.cpp [new file with mode: 0644]
src/service/common/connection-info.h [new file with mode: 0644]
src/service/common/protocols.cpp
src/service/common/protocols.h
src/service/main/generic-socket-manager.h
src/service/main/server2-main.cpp
src/service/main/socket-manager.cpp
src/service/service/echo.cpp
src/service/service/echo.h
src/service/service/ima-evm-server-set-state.cpp [new file with mode: 0644]
src/service/service/ima-evm-server-set-state.h [new file with mode: 0644]

index 264a462..c4a3d09 100644 (file)
@@ -34,6 +34,7 @@ ADD_EXECUTABLE(${TARGET_IM_UIGADGET} ${SRCS})
 TARGET_LINK_LIBRARIES(${TARGET_IM_UIGADGET}
     ${im-uigadget_pkgs_LIBRARIES}
     ${im-uigadget_pkgs_LDFLAGS}
+    ${TARGET_IMA_EVM_CLIENT}
     imaevm
 )
 
@@ -46,6 +47,7 @@ SET(IMA_EVM_SERVER_SOURCES
     ${SERVER2_PATH}/main/socket-manager.cpp
     ${SERVER2_PATH}/main/server2-main.cpp
     ${SERVER2_PATH}/service/echo.cpp
+    ${SERVER2_PATH}/service/ima-evm-server-set-state.cpp
 )
 
 SET_SOURCE_FILES_PROPERTIES(
@@ -71,6 +73,7 @@ ADD_EXECUTABLE(${TARGET_IMA_EVM_SERVER} ${IMA_EVM_SERVER_SOURCES})
 TARGET_LINK_LIBRARIES(${TARGET_IMA_EVM_SERVER}
     ${IMA_EVM_SERVER_DEP_LIBRARIES}
     ${TARGET_SERVER_COMMON}
+    imaevm
 #    -lcap
     )
 
@@ -88,6 +91,7 @@ INCLUDE_DIRECTORIES(
 
 SET(IMA_EVM_CLIENT_SOURCES
     ${SERVER2_PATH}/client/client-common.cpp
+    ${SERVER2_PATH}/client/client-ima-evm-server-set-state.cpp
     )
 
 ADD_LIBRARY(${TARGET_IMA_EVM_CLIENT} SHARED ${IMA_EVM_CLIENT_SOURCES})
index 43e9263..374cb39 100644 (file)
 #define IMA_EVM_SERVER_API_ERROR_UNKNOWN -255
 /** @}*/
 
+#define IMA_SERVER_API_STATE_DISABLED 1
+#define IMA_SERVER_API_STATE_IGNORE   2
+#define IMA_SERVER_API_STATE_ENFORCE  3
+#define IMA_SERVER_API_STATE_FIX      4
+
+#define EVM_SERVER_API_STATE_DISABLED 10
+#define EVM_SERVER_API_STATE_ENABLED  11
+#define EVM_SERVER_API_STATE_FIX      12
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+int ima_evm_server_set_ima_state (int state);
+int ima_evm_server_set_evm_state (int state);
+
+int ima_evm_server_get_ima_state (int *state);
+int ima_evm_server_get_evm_state (int *state);
+
+int ima_evm_server_set_policy(const char **policy, const char *policy_sig);
+int ima_evm_server_set_policy_file(const char *policy_path);
+int ima_evm_server_get_policy(char ***policy);
 
 
 /**
@@ -403,6 +421,7 @@ int ima_evm_server_get_cookie_size(void);
  * ... // Receiving request with cookie
  *
  * call_gid = ima_evm_server_get_gid("telephony_makecall");
+100G
  * retval = ima_evm_server_check_privilege(recved_cookie, (gid_t)call_gid);
  * if(retval < 0)
  * {
index a5d6167..b19e5f9 100644 (file)
@@ -41,6 +41,7 @@ SET_TARGET_PROPERTIES(
 
 TARGET_LINK_LIBRARIES(${TARGET_SERVER_COMMON}
     ${COMMON_DEP_LIBRARIES}
+    imaevm
     )
 
 ################################################################################
index f3a347f..1afe1cc 100644 (file)
@@ -30,6 +30,8 @@
 
 #include <socket-buffer.h>
 
+#define IMA_EVM_SERVER_API __attribute__((visibility("default")))
+
 namespace IMAEVMServer {
 
 typedef std::vector<unsigned char> RawBuffer;
diff --git a/src/service/client/client-ima-evm-server-set-state.cpp b/src/service/client/client-ima-evm-server-set-state.cpp
new file mode 100644 (file)
index 0000000..c8b3c0d
--- /dev/null
@@ -0,0 +1,294 @@
+/*
+ * Copyright (c) 2000 - 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        client-ima-evm-server-set-state.cpp
+ * @author      Janusz Kozerski (j.kozerski@samsung.com)
+ * @version     1.0
+ * @brief       This file contains implementation of
+ *              ima/evm-set-state functions
+ */
+#include <imaevm.h>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <socket-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+
+#include <ima-evm-server.h>
+
+IMA_EVM_SERVER_API
+int ima_evm_server_set_ima_state(int state)
+{
+    using namespace IMAEVMServer;
+    SocketBuffer send, recv;
+
+    try {
+        //put data into buffer
+        Serialization::Serialize(send, static_cast<int>(IMAEVMFuncHdrs::SET_STATE));
+       Serialization::Serialize(send, static_cast<int>(IMAEVMSwitch::IMA_SWITCH));
+        Serialization::Serialize(send, state);
+
+        //send buffer
+        int apiResult = sendToServer(SERVICE_SOCKET_IMA_EVM, send.Pop(), recv);
+        if (apiResult != IMA_EVM_SERVER_API_SUCCESS) {
+            return apiResult;
+        }
+
+        //receive response from server
+        Deserialization::Deserialize(recv, apiResult);
+        return apiResult;
+
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogError("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogError("STD exception " << e.what());
+    } catch (...) {
+        LogError("Unknown exception occured");
+    }
+
+    return IMA_EVM_SERVER_API_ERROR_UNKNOWN;
+}
+
+IMA_EVM_SERVER_API
+int ima_evm_server_set_evm_state(int state)
+{
+    using namespace IMAEVMServer;
+    SocketBuffer send, recv;
+
+    try {
+        //put data into buffer
+        Serialization::Serialize(send, static_cast<int>(IMAEVMFuncHdrs::SET_STATE));
+        Serialization::Serialize(send, static_cast<int>(IMAEVMSwitch::EVM_SWITCH));
+        Serialization::Serialize(send, state);
+
+        //send buffer
+        int apiResult = sendToServer(SERVICE_SOCKET_IMA_EVM, send.Pop(), recv);
+        if (apiResult != IMA_EVM_SERVER_API_SUCCESS) {
+            return apiResult;
+        }   
+
+        //receive response from server
+        Deserialization::Deserialize(recv, apiResult);
+        return apiResult;
+
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogError("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogError("STD exception " << e.what());
+    } catch (...) {
+        LogError("Unknown exception occured");
+    }   
+
+    return IMA_EVM_SERVER_API_ERROR_UNKNOWN;
+}
+
+IMA_EVM_SERVER_API
+int ima_evm_server_get_ima_state(int *state)
+{
+    using namespace IMAEVMServer;
+    SocketBuffer send, recv;
+
+    try {
+        //put data into buffer
+        Serialization::Serialize(send, static_cast<int>(IMAEVMFuncHdrs::GET_STATE));
+        Serialization::Serialize(send, static_cast<int>(IMAEVMSwitch::IMA_SWITCH));
+        Serialization::Serialize(send, state);
+
+        //send buffer
+        int apiResult = sendToServer(SERVICE_SOCKET_IMA_EVM, send.Pop(), recv);
+        if (apiResult != IMA_EVM_SERVER_API_SUCCESS) {
+            return apiResult;
+        }   
+
+        //receive response from server
+        Deserialization::Deserialize(recv, apiResult);
+        if (apiResult == IMA_EVM_SERVER_API_SUCCESS) {
+            Deserialization::Deserialize(recv, *state);
+        }   
+        return apiResult;
+
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogError("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogError("STD exception " << e.what());
+    } catch (...) {
+        LogError("Unknown exception occured");
+    }   
+
+    return IMA_EVM_SERVER_API_ERROR_UNKNOWN;
+}
+
+IMA_EVM_SERVER_API
+int ima_evm_server_get_evm_state(int *state)
+{
+    using namespace IMAEVMServer;
+    SocketBuffer send, recv;
+
+    try {
+        //put data into buffer
+        Serialization::Serialize(send, static_cast<int>(IMAEVMFuncHdrs::GET_STATE));
+        Serialization::Serialize(send, static_cast<int>(IMAEVMSwitch::EVM_SWITCH));
+        Serialization::Serialize(send, state);
+
+        //send buffer
+        int apiResult = sendToServer(SERVICE_SOCKET_IMA_EVM, send.Pop(), recv);
+        if (apiResult != IMA_EVM_SERVER_API_SUCCESS) {
+            return apiResult;
+        }
+
+        //receive response from server
+        Deserialization::Deserialize(recv, apiResult);
+        if (apiResult == IMA_EVM_SERVER_API_SUCCESS) {
+            Deserialization::Deserialize(recv, *state);
+        }
+        return apiResult;
+
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogError("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogError("STD exception " << e.what());
+    } catch (...) {
+        LogError("Unknown exception occured");
+    }
+
+    return IMA_EVM_SERVER_API_ERROR_UNKNOWN;
+}
+
+IMA_EVM_SERVER_API
+int ima_evm_server_set_policy(const char **policy, const char *policy_sig)
+{
+    using namespace IMAEVMServer;
+    int rules_count = 0;
+    SocketBuffer send, recv;
+
+    try {
+        //put data into buffer
+        Serialization::Serialize(send, static_cast<int>(IMAEVMFuncHdrs::SET_POLICY));
+
+        while(policy[rules_count])
+            ++rules_count;
+        Serialization::Serialize(send, static_cast<int>(rules_count));
+
+        for (int i=0; i<rules_count; ++i)
+            Serialization::Serialize(send, std::string(policy[i]));
+
+        Serialization::Serialize(send, std::string(policy_sig));
+
+        //send buffer
+        int apiResult = sendToServer(SERVICE_SOCKET_IMA_EVM, send.Pop(), recv);
+        if (apiResult != IMA_EVM_SERVER_API_SUCCESS) {
+            return apiResult;
+        }   
+
+        //receive response from server
+        Deserialization::Deserialize(recv, apiResult);
+        return apiResult;
+
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogError("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogError("STD exception " << e.what());
+    } catch (...) {
+        LogError("Unknown exception occured");
+    }   
+
+    return IMA_EVM_SERVER_API_ERROR_UNKNOWN;
+}
+
+IMA_EVM_SERVER_API
+int ima_evm_server_set_policy_file(const char *policy_path)
+{
+    using namespace IMAEVMServer;
+    SocketBuffer send, recv;
+
+    try {
+        //put data into buffer
+        Serialization::Serialize(send, static_cast<int>(IMAEVMFuncHdrs::SET_POLICY_FILE));
+
+        Serialization::Serialize(send, std::string(policy_path));
+
+        //send buffer
+        int apiResult = sendToServer(SERVICE_SOCKET_IMA_EVM, send.Pop(), recv);
+        if (apiResult != IMA_EVM_SERVER_API_SUCCESS) {
+            return apiResult;
+        }   
+
+        //receive response from server
+        Deserialization::Deserialize(recv, apiResult);
+        return apiResult;
+
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogError("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogError("STD exception " << e.what());
+    } catch (...) {
+        LogError("Unknown exception occured");
+    }   
+
+    return IMA_EVM_SERVER_API_ERROR_UNKNOWN;
+}
+
+IMA_EVM_SERVER_API
+int ima_evm_server_get_policy(char ***policy)
+{
+    using namespace IMAEVMServer;
+    int rules_count = 0;
+    std::string rule;
+    SocketBuffer send, recv;
+
+    printf("ima_evm_server_get_policy\n");
+    try {
+        //put data into buffer
+        Serialization::Serialize(send, static_cast<int>(IMAEVMFuncHdrs::GET_POLICY));
+
+        //send buffer
+        int apiResult = sendToServer(SERVICE_SOCKET_IMA_EVM, send.Pop(), recv);
+        if (apiResult != IMA_EVM_SERVER_API_SUCCESS) {
+            return apiResult;
+        }   
+
+        //receive response from server
+        Deserialization::Deserialize(recv, apiResult);
+        if (apiResult != IMA_EVM_SERVER_API_SUCCESS)
+            return apiResult;
+
+        Deserialization::Deserialize(recv, rules_count);
+        *policy = (char**) malloc(rules_count * sizeof(char*));
+        if (!policy)
+            return IMA_EVM_SERVER_API_ERROR_OUT_OF_MEMORY;
+
+        for (int i=0; i<rules_count; ++i) {
+            Deserialization::Deserialize(recv, rule);
+            (*policy)[i] = (char *) malloc((rule.size() + 1 ) * sizeof(char));
+            // FIXME: add malloc error handling
+            std::copy(rule.begin(), rule.end(), (*policy)[i]);
+            (*policy)[i][rule.size()] = '\0';
+        }
+        (*policy)[rules_count] = NULL;
+        return apiResult;
+
+    } catch (SocketBuffer::Exception::Base &e) {
+        LogError("SecurityServer::MessageBuffer::Exception " << e.DumpToString());
+    } catch (std::exception &e) {
+        LogError("STD exception " << e.what());
+    } catch (...) {
+        LogError("Unknown exception occured");
+    }   
+
+    return IMA_EVM_SERVER_API_ERROR_UNKNOWN;
+}
diff --git a/src/service/common/connection-info.h b/src/service/common/connection-info.h
new file mode 100644 (file)
index 0000000..e4692ea
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ *  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        connection-info.h
+ * @author      Lukasz Kostyra (l.kostyra@partner.samsung.com)
+ * @version     1.0
+ * @brief       Definition of ConnectionInfo structure and ConnectionInfoMap type.
+ */
+
+#ifndef _CONNECTION_INFO_H_
+#define _CONNECTION_INFO_H_
+
+#include <map>
+#include <generic-socket-manager.h>
+#include <socket-buffer.h>
+
+namespace IMAEVMServer
+{
+    struct ConnectionInfo {
+        InterfaceID interfaceID;
+        SocketBuffer buffer;
+    };
+
+    typedef std::map<int, ConnectionInfo> ConnectionInfoMap;
+} //namespace IMAEVMServer
+
+#endif //_CONNECTION_INFO_H_
index d5b2fff..fbc08d9 100644 (file)
@@ -17,7 +17,7 @@
  */
 /*
  * @file        protocols.cpp
- * @author      Bartlomiej Grzelewski (b.grzelewski@samsung.com)
+ * @author      Janusz Kozerski (j.kozerski@samsung.com)
  * @version     1.0
  * @brief       List of all protocols supported by ima-evm server.
  */
@@ -26,8 +26,8 @@
 
 namespace IMAEVMServer {
 
-char const * const SERVICE_SOCKET_SHARED_MEMORY =
-    "/tmp/ima-evm-server-api-data-share";
+char const * const SERVICE_SOCKET_IMA_EVM =
+    "/tmp/ima-evm-server-api";
 char const * const SERVICE_SOCKET_ECHO =
     "/tmp/ima-evm-server-api-echo";
 
index 0837580..0ae06cf 100644 (file)
 
 namespace IMAEVMServer {
 
-extern char const * const SERVICE_SOCKET_SHARED_MEMORY;
+extern char const * const SERVICE_SOCKET_IMA_EVM;
 extern char const * const SERVICE_SOCKET_ECHO;
 
+enum class IMAEVMFuncHdrs
+{
+    SET_STATE,
+    GET_STATE,
+    SET_XATTR,
+    GET_XATTR,
+    SET_POLICY,
+    SET_POLICY_FILE,
+    GET_POLICY
+};
+
+enum class IMAEVMSwitch
+{
+    IMA_SWITCH,
+    EVM_SWITCH
+};
+
 } // namespace IMAEVMServer
 
 #endif // _IMA_EVM_SERVER_PROTOCOLS_
index d7e66e8..7d23fa8 100644 (file)
@@ -79,10 +79,6 @@ struct GenericSocketService {
         ConnectionID connectionID;
     };
 
-    struct ErrorEvent : public GenericEvent {
-        ConnectionID connectionID;
-    };
-
     virtual void SetSocketManager(GenericSocketManager *manager) {
         m_serviceManager = manager;
     }
@@ -92,7 +88,6 @@ struct GenericSocketService {
     virtual void Event(const WriteEvent &event) = 0;
     virtual void Event(const ReadEvent &event) = 0;
     virtual void Event(const CloseEvent &event) = 0;
-    virtual void Event(const ErrorEvent &event) = 0;
     virtual ~GenericSocketService(){}
 protected:
     GenericSocketManager *m_serviceManager;
index 94e2145..7cc8e42 100644 (file)
@@ -32,6 +32,7 @@
 #include <socket-manager.h>
 
 #include <echo.h>
+#include <ima-evm-server-set-state.h>
 
 IMPLEMENT_SAFE_SINGLETON(IMAEVMServer::Log::LogSystem);
 
@@ -47,6 +48,10 @@ int main(void) {
         echoService->Create();
         manager.RegisterSocketService(echoService);
 
+        IMAEVMServer::IMAEVMStateService *imaevmService = new IMAEVMServer::IMAEVMStateService; 
+        imaevmService->Create();
+        manager.RegisterSocketService(imaevmService);
+
         manager.MainLoop();
     }
     UNHANDLED_EXCEPTION_HANDLER_END
index 96bda94..028a49c 100644 (file)
@@ -55,7 +55,7 @@ struct DummyService : public GenericSocketService {
     void Event(const WriteEvent &event) { (void)event; }
     void Event(const ReadEvent &event) { (void)event; }
     void Event(const CloseEvent &event) { (void)event; }
-    void Event(const ErrorEvent &event) { (void)event; }
+//    void Event(const ErrorEvent &event) { (void)event; }
 };
 
 SocketManager::SocketDescription&
@@ -322,6 +322,7 @@ void SocketManager::CreateDomainSocket(
         ThrowMsg(Exception::InitFailed, "Error in socket: " << strerror(err));
     }
 
+    //FIXME: service socket should be protected by Smack
     //LogInfo("TODO: Set up smack label: " << desc.smackLabel);
 
     //if (0 != smack_fsetlabel(sockfd, desc.smackLabel.c_str(), SMACK_LABEL_IPIN)) {
index 75939d7..f8deaca 100644 (file)
@@ -48,7 +48,8 @@ namespace IMAEVMServer {
 
 GenericSocketService::ServiceDescriptionVector EchoService::GetServiceDescription() {
     ServiceDescription sd = {
-        "ima-evm-server::api-echo",
+        //"ima-evm-server::api-echo",
+        "*",
         SERVICE_SOCKET_ID,
         SERVICE_SOCKET_ECHO
     };
@@ -80,10 +81,5 @@ void EchoService::close(const CloseEvent &event) {
     LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
 }
 
-void EchoService::error(const ErrorEvent &event) {
-    LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
-    m_serviceManager->Close(event.connectionID);
-}
-
 } // namespace IMAEVMServer
 
index f243123..651cc97 100644 (file)
@@ -45,13 +45,11 @@ public:
     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);
 };
 
 } // namespace IMAEVMServer
diff --git a/src/service/service/ima-evm-server-set-state.cpp b/src/service/service/ima-evm-server-set-state.cpp
new file mode 100644 (file)
index 0000000..d261afa
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ *  Copyright (c) 2000 - 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        ima-evm-server-set-state.cpp
+ * @author      Janusz Kozerski (j.kozerski@samsung.com)
+ * @version     1.0
+ * @brief       This file contains implementation of ima/evm-set-state
+ *              on server side
+ */
+#include <imaevm.h>
+
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+
+#include <sys/smack.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <ima-evm-server-set-state.h>
+#include <protocols.h>
+#include <ima-evm-server.h>
+
+namespace IMAEVMServer {
+
+namespace {
+
+int libimaevmToIMAEVMServiceError (int error)
+{
+    printf("libimaevmToIMAEVMServiceError\n");
+    switch (error) {
+        case LIB_SUCCESS:           return IMA_EVM_SERVER_API_SUCCESS;
+        case LIB_ERROR_UNKNOWN:     return IMA_EVM_SERVER_API_ERROR_UNKNOWN;
+        case LIB_ERROR_INPUT_PARAM: return IMA_EVM_SERVER_API_ERROR_INPUT_PARAM;
+        case LIB_ERROR_MEMORY:      return IMA_EVM_SERVER_API_ERROR_OUT_OF_MEMORY;
+        case LIB_ERROR_SYSCALL:     return IMA_EVM_SERVER_API_ERROR_SERVER_ERROR;
+        case LIB_ERROR_ATTRIBUTE:   return IMA_EVM_SERVER_API_ERROR_NO_SUCH_OBJECT;
+        default: return IMA_EVM_SERVER_API_ERROR_UNKNOWN;
+    }
+}
+
+const int SERVICE_SOCKET_ID = 1;
+
+} // namespace anonymous
+
+GenericSocketService::ServiceDescriptionVector IMAEVMStateService::GetServiceDescription()
+{
+#if 1
+     ServiceDescription sd = { 
+        //"ima-evm-server::api",
+        "*",
+        SERVICE_SOCKET_ID,
+        SERVICE_SOCKET_IMA_EVM 
+    };  
+    ServiceDescriptionVector v;
+    v.push_back(sd);
+    return v;
+#endif
+#if 0
+    return ServiceDescriptionVector {
+        {SERVICE_SOCKET_IMA_EVM, SERVICE_SOCKET_ID, "*"}
+    };
+#endif
+}
+
+void IMAEVMStateService::accept(const AcceptEvent &event) {
+    LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+        << " ConnectionID.counter: " << event.connectionID.counter
+        << " ServiceID: " << event.interfaceID);
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.interfaceID = event.interfaceID;
+}
+
+void IMAEVMStateService::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);
+}
+
+void IMAEVMStateService::process(const ReadEvent &event) {
+    LogDebug("Read event for counter: " << event.connectionID.counter);
+    auto &info = m_connectionInfoMap[event.connectionID.counter];
+    info.buffer.Push(event.rawBuffer);
+
+    // We can get several requests in one package.
+    // Extract and process them all
+    while(processOne(event.connectionID, info.buffer));
+}
+
+void IMAEVMStateService::close(const CloseEvent &event) {
+    LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+    m_connectionInfoMap.erase(event.connectionID.counter);
+}
+
+int IMAEVMStateService::imaState(int state)
+{
+    switch (state) {
+    case IMA_SERVER_API_STATE_DISABLED:
+        return IMA_STATE_DISABLED;
+    case IMA_SERVER_API_STATE_IGNORE:
+    //TODO: Update the IMA state enums when libimaevm will be updated.
+    //    return IMA_STATE_IGNORE;
+        return IMA_STATE_DISABLED;
+    //case IMA_SERVER_API_STATE_ENFORCE:
+    //    return IMA_STATE_ENFORCE;
+    case IMA_SERVER_API_STATE_ENFORCE:
+          return IMA_STATE_ENABLED;
+    case IMA_SERVER_API_STATE_FIX:
+        return IMA_STATE_FIX;
+    default:
+        return IMA_EVM_SERVER_API_ERROR_INPUT_PARAM;
+    }
+}
+
+int IMAEVMStateService::evmState(int state)
+{
+    switch (state) {
+    case EVM_SERVER_API_STATE_DISABLED:
+        return EVM_STATE_DISABLED;
+    case EVM_SERVER_API_STATE_ENABLED:
+          return EVM_STATE_ENABLED;
+    case EVM_SERVER_API_STATE_FIX:
+        return EVM_STATE_FIX;
+    default:
+        return IMA_EVM_SERVER_API_ERROR_INPUT_PARAM;
+    }   
+}
+
+bool IMAEVMStateService::processOne(const ConnectionID &conn,
+                                    SocketBuffer &buffer)
+{
+    LogDebug("Begin of an iteration");
+
+    //waiting for all data
+    if (!buffer.Ready()) {
+        return false;
+    }
+
+    LogDebug("Entering ima_evm_set_state server side handler");
+
+    Try {
+        int funct;
+        Deserialization::Deserialize(buffer, funct);
+        switch(static_cast<IMAEVMFuncHdrs>(funct)) {
+        case IMAEVMFuncHdrs::SET_STATE :
+            return IMAEVMStateService::setState(conn, buffer);
+        case IMAEVMFuncHdrs::GET_STATE : return true;
+            return IMAEVMStateService::getState(conn, buffer);
+        case IMAEVMFuncHdrs::SET_XATTR : return true; //FIXME: Not implemeted yet
+        case IMAEVMFuncHdrs::GET_XATTR : return true; //FIXME: Not implemeted yet
+                    // Should we have rights to change xattrs? Not sure about it.
+        case IMAEVMFuncHdrs::SET_POLICY :
+            return IMAEVMStateService::setPolicy(conn, buffer);;
+        case IMAEVMFuncHdrs::SET_POLICY_FILE : 
+            return IMAEVMStateService::setPolicyFromFile(conn, buffer); 
+        case IMAEVMFuncHdrs::GET_POLICY :
+            return IMAEVMStateService::getPolicy(conn);
+        default:
+            return false;
+        }
+
+    } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }
+
+    // This should never happend;
+    return false;
+}
+
+bool IMAEVMStateService::setState(const ConnectionID &conn,
+                                  SocketBuffer &buffer)
+{
+    SocketBuffer send;
+    Try {
+        int tmpModule;
+        int state;
+        int result;
+        Deserialization::Deserialize(buffer, tmpModule);
+        Deserialization::Deserialize(buffer, state);
+        IMAEVMSwitch module = static_cast<IMAEVMSwitch>(tmpModule); // IMA vs EVM
+        switch(module) {
+        case IMAEVMSwitch::IMA_SWITCH:
+            if ((state = imaState(state)) == IMA_EVM_SERVER_API_ERROR_INPUT_PARAM)
+                return false;
+            result = ima_set_state(state);
+            break;
+        case IMAEVMSwitch::EVM_SWITCH:
+            if ((state = evmState(state)) == IMA_EVM_SERVER_API_ERROR_INPUT_PARAM)
+                return false;
+            result = evm_set_state(state);
+            break;
+        default:
+            return false;
+        }   
+        Serialization::Serialize(send, libimaevmToIMAEVMServiceError(result));
+        m_serviceManager->Write(conn, send.Pop());
+        return true;
+
+    } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }   
+
+    // This should never happend;
+    return false;
+
+}
+
+bool IMAEVMStateService::getState(const ConnectionID &conn,
+                                  SocketBuffer &buffer)
+{
+    SocketBuffer send;
+    int state;
+    Try {
+        int tmpModule;
+        int result;
+        Deserialization::Deserialize(buffer, tmpModule);
+        IMAEVMSwitch module = static_cast<IMAEVMSwitch>(tmpModule); // IMA vs EVM
+        switch(module) {
+        case IMAEVMSwitch::IMA_SWITCH:
+            result = ima_get_state(&state);
+            break;
+        case IMAEVMSwitch::EVM_SWITCH:
+            result = evm_get_state(&state);
+            break;
+        default:
+            return false;
+        }   
+        Serialization::Serialize(send, libimaevmToIMAEVMServiceError(result));
+        if (result == LIB_SUCCESS)
+            Serialization::Serialize(send, state);
+        m_serviceManager->Write(conn, send.Pop());
+        return true;
+
+    } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }   
+
+    // This should never happend;
+    return false;
+
+}
+
+bool IMAEVMStateService::setPolicy(const ConnectionID &conn,
+                                  SocketBuffer &buffer)
+{
+    SocketBuffer send;
+    Try {
+        std::string policy_rule;
+        std::string policy_sig;
+        char **policy_c;
+        int result;
+        int rule_count;
+
+        Deserialization::Deserialize(buffer, rule_count);
+        policy_c = (char **) malloc((rule_count + 1) * sizeof(char*));
+        for (int i=0; i<rule_count; i++) {
+            Deserialization::Deserialize(buffer, policy_rule);
+            policy_c[i] = (char *) malloc((policy_rule.size() + 1 ) * sizeof(char));
+            std::copy(policy_rule.begin(), policy_rule.end(), policy_c[i]);
+            policy_c[i][policy_rule.size()] = '\0';
+        }
+        policy_c[rule_count] = NULL;
+        
+        Deserialization::Deserialize(buffer, policy_sig);
+
+        result = ima_set_policy((const char**) policy_c, policy_sig.c_str());
+
+        Serialization::Serialize(send, libimaevmToIMAEVMServiceError(result));
+        m_serviceManager->Write(conn, send.Pop());
+        // FIXME: if error occurs the memory won't be freed
+        ima_free_policy(policy_c);
+        return true;
+
+    } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }
+
+    // This should never happend;
+    return false;
+
+}
+
+bool IMAEVMStateService::setPolicyFromFile(const ConnectionID &conn,
+                                           SocketBuffer &buffer)
+{
+    SocketBuffer send;
+    Try {
+        std::string policy_path;
+        int result;
+
+        Deserialization::Deserialize(buffer, policy_path);
+        result = ima_set_policy_file(policy_path.c_str());
+
+        Serialization::Serialize(send, libimaevmToIMAEVMServiceError(result));
+        m_serviceManager->Write(conn, send.Pop());
+        // FIXME: if error occurs the memory won't be freed
+        return true;
+
+    } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }
+
+    // This should never happend;
+    return false;
+
+}
+
+bool IMAEVMStateService::getPolicy(const ConnectionID &conn)
+{
+    SocketBuffer send;
+    Try {
+        std::string policy_rule;
+        char **policy_c;
+        int result;
+        int rule_count = 0;
+        
+        result = ima_get_policy(&policy_c);
+        Serialization::Serialize(send, libimaevmToIMAEVMServiceError(result));
+        if (result != LIB_SUCCESS) {
+            m_serviceManager->Write(conn, send.Pop());
+            return true;
+        }
+
+        while (policy_c[rule_count])
+            ++rule_count;
+
+        Serialization::Serialize(send, rule_count);
+        for(int i=0; i<rule_count; ++i)
+            Serialization::Serialize(send, std::string(policy_c[i]));
+
+        m_serviceManager->Write(conn, send.Pop());
+
+        // FIXME: if error occurs the memory won't be freed
+        ima_free_policy(policy_c);
+        return true;
+
+    } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }   
+
+    // This should never happend;
+    return false;
+}
+
+} //namespace IMAEVMServer
diff --git a/src/service/service/ima-evm-server-set-state.h b/src/service/service/ima-evm-server-set-state.h
new file mode 100644 (file)
index 0000000..a96570d
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  Copyright (c) 2000 - 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        ima-evm-server-set-state.h
+ * @author      Janusz Kozerski (j.kozerski@samsung.com)
+ * @version     1.0
+ * @brief       This function contains header for implementation of
+ *              ima-evm-server-set-state on server side
+ */
+
+#ifndef _IMA_EVM_SERVER_SET_STATE_
+#define _IMA_EVM_SERVER_SET_STATE_
+
+#include <imaevm.h>
+
+#include <service-thread.h>
+#include <generic-socket-manager.h>
+#include <dpl/serialization.h>
+#include <socket-buffer.h>
+#include <connection-info.h>
+
+namespace IMAEVMServer {
+
+class IMAEVMStateService
+  : public IMAEVMServer::GenericSocketService
+  , public IMAEVMServer::ServiceThread<IMAEVMStateService>
+{
+public:
+    ServiceDescriptionVector GetServiceDescription();
+
+    DECLARE_THREAD_EVENT(AcceptEvent, accept)
+    DECLARE_THREAD_EVENT(WriteEvent, write)
+    DECLARE_THREAD_EVENT(ReadEvent, process)
+    DECLARE_THREAD_EVENT(CloseEvent, close)
+
+    void accept(const AcceptEvent &event);
+    void write(const WriteEvent &event);
+    void process(const ReadEvent &event);
+    void close(const CloseEvent &event);
+
+private:
+    bool processOne(const ConnectionID &conn, SocketBuffer &buffer);
+    bool setState(const ConnectionID &conn, SocketBuffer &buffer);
+    bool getState(const ConnectionID &conn, SocketBuffer &buffer);
+    bool setPolicy(const ConnectionID &conn, SocketBuffer &buffer);
+    bool setPolicyFromFile(const ConnectionID &conn, SocketBuffer &buffer);
+    bool getPolicy(const ConnectionID &conn);
+    int  imaState(int state);
+    int  evmState(int state);
+
+    ConnectionInfoMap m_connectionInfoMap;
+};
+
+} // namespace IMAEVMServer
+
+#endif // _IMA_EVM_SERVER_SET_STATE_