Added API for APP enable and disable permissions
authorPawel Polawski <p.polawski@partner.samsung.com>
Thu, 25 Jul 2013 13:00:48 +0000 (15:00 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 6 Feb 2014 16:13:21 +0000 (17:13 +0100)
[Issue#]        SSDWSSP-155
[Bug/Feature]   Implement API for removing/adding API feature rules from
                applications SMACK profile
[Cause]         Need new API
[Solution]      New API added
[Verification]  Compile. No new tests should fail

Change-Id: Ib6e95f32fa0cf0ebb2fdfd787b1c1f156b5a96b6

12 files changed:
packaging/security-server.spec
src/CMakeLists.txt
src/include/security-server-common.h
src/include/security-server.h
src/server2/client/client-app-permissions.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/app-permissions.cpp [new file with mode: 0644]
src/server2/service/app-permissions.h [new file with mode: 0644]
systemd/CMakeLists.txt
systemd/security-server-app-permissions.socket [new file with mode: 0644]

index 0a957da..2cb5b22 100644 (file)
@@ -35,6 +35,7 @@ Tizen Security server client libraries
 Summary:    Security server (client-devel)
 Group:      Security/Development
 Requires:   libsecurity-server-client = %{version}-%{release}
+Requires:   libprivilege-control-devel
 
 %description -n libsecurity-server-client-devel
 Development files needed for using the security client
@@ -83,6 +84,7 @@ ln -s ../security-server-get-gid.socket %{buildroot}/usr/lib/systemd/system/sock
 ln -s ../security-server-privilege-by-pid.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-privilege-by-pid.socket
 ln -s ../security-server-exec-path.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-exec-path.socket
 ln -s ../security-server-get-object-name.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-get-object-name.socket
+ln -s ../security-server-app-permissions.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-app-permissions.socket
 
 %clean
 rm -rf %{buildroot}
@@ -123,6 +125,8 @@ systemctl daemon-reload
 %attr(-,root,root) /usr/lib/systemd/system/security-server-exec-path.socket
 %attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-get-object-name.socket
 %attr(-,root,root) /usr/lib/systemd/system/security-server-get-object-name.socket
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-app-permissions.socket
+%attr(-,root,root) /usr/lib/systemd/system/security-server-app-permissions.socket
 
 %{_datadir}/license/%{name}
 
index dc87653..7feb454 100644 (file)
@@ -22,6 +22,7 @@ SET(SECURITY_SERVER_SOURCES
     ${SERVER2_PATH}/service/data-share.cpp
     ${SERVER2_PATH}/service/echo.cpp
     ${SERVER2_PATH}/service/get-gid.cpp
+    ${SERVER2_PATH}/service/app-permissions.cpp
     ${SERVER2_PATH}/service/privilege-by-pid.cpp
     ${SERVER2_PATH}/service/exec-path.cpp
     ${SERVER2_PATH}/service/get-object-name.cpp
@@ -66,6 +67,7 @@ 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}/server2/client/client-app-permissions.cpp
     ${SECURITY_SERVER_PATH}/server2/client/client-privilege-by-pid.cpp
     ${SECURITY_SERVER_PATH}/server2/client/client-socket-privilege.cpp
     ${SECURITY_SERVER_PATH}/server2/client/client-get-object-name.cpp
index 1bf5697..0e2f2f8 100644 (file)
@@ -89,6 +89,8 @@ extern "C" {
 
 
 /* Data types *****************************************************************/
+
+
 /* Cookie List data type */
 typedef struct _cookie_list
 {
index bcea29c..e885b6f 100644 (file)
@@ -23,6 +23,7 @@
 #define SECURITY_SERVER_H
 
 #include <sys/types.h>
+#include <privilege-control.h>
 
 /**
  * @file    security-server.h
 #define SECURITY_SERVER_API_ERROR_UNKNOWN -255
 /** @}*/
 
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -964,6 +966,30 @@ int security_server_app_give_access(const char *customer_label, int customer_pid
  */
 int security_server_check_privilege_by_pid(int pid, const char *object, const char *access_rights);
 
+/*
+ * This function allows middleware to enable permissions for specified app_id.
+ *
+ * \param[in] Application ID
+ * \param[in] Application type definet in enum at the beginning of this file
+ * \param[in] Permissions list
+ * \param[in] Persistent
+ *
+ * \return SECURITY_SERVER_SUCCESS on success or error code on fail
+ */
+int security_server_app_enable_permissions(const char *app_id, app_type_t app_type, const char **perm_list, int persistent);
+
+/*
+ * This function allows middleware to disable permissions for specified app_id.
+ *
+ * \param[in] Application ID
+ * \param[in] Application type definet in enum at the beginning of this file
+ * \param[in] Permissions list
+ *
+ * \return SECURITY_SERVER_SUCCESS on success or error code on fail
+ */
+int security_server_app_disable_permissions(const char *app_id, app_type_t app_type, const char **perm_list);
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/server2/client/client-app-permissions.cpp b/src/server2/client/client-app-permissions.cpp
new file mode 100644 (file)
index 0000000..13fbb50
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ *  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-app-permissions.cpp
+ * @author      Pawel Polawski (pawel.polawski@partner.samsung.com)
+ * @version     1.0
+ * @brief       This file contain implementation of security_server_app_enable_permissions
+ *              and security_server_app_disable functions
+ */
+
+
+#include <stdio.h>
+
+#include <dpl/log/log.h>
+#include <dpl/exception.h>
+
+#include <socket-buffer.h>
+#include <client-common.h>
+#include <protocols.h>
+
+#include <privilege-control.h>
+#include <security-server.h>
+#include <security-server-common.h>
+
+
+SECURITY_SERVER_API
+int security_server_app_enable_permissions(const char *app_id, app_type_t app_type, const char **perm_list, int persistent)
+{
+    using namespace SecurityServer;
+    SocketBuffer send, recv;
+    Serialization serialization;
+    Deserialization deserialization;
+    std::vector<std::string> permissions_list;
+    int i;
+    int ret;
+
+    LogDebug("security_server_app_enable_permissions() called");
+
+    try {
+        if ((NULL == app_id) || (strlen(app_id) == 0)) {
+            LogDebug("App_id is NULL");
+            return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+        }
+        if ((NULL == perm_list) || (strlen(perm_list[0]) == 0)) {
+            LogDebug("Perm_list is NULL");
+            return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+        }
+
+        LogDebug("app_type: " << (int)app_type);
+        LogDebug("persistent: " << persistent);
+        LogDebug("app_id: " << app_id);
+
+        //put all strings in STL vector
+        for (i = 0; perm_list[i] != NULL; i++) {
+            LogDebug("perm_list[" << i << "]: " << perm_list[i]);
+            permissions_list.push_back(std::string(perm_list[i]));
+        }
+
+        //put data into buffer
+        serialization.Serialize(send, (int)AppPermissionsAction::ENABLE);   //works as a MSG_ID
+        serialization.Serialize(send, persistent);
+        serialization.Serialize(send, (int)app_type);
+        serialization.Serialize(send, std::string(app_id));
+        serialization.Serialize(send, permissions_list);
+
+        //send buffer to server
+        ret = sendToServer(SERVICE_SOCKET_APP_PERMISSIONS, send.Pop(), recv);
+        if (ret != SECURITY_SERVER_API_SUCCESS) {
+            LogDebug("Unable to send");
+            return ret;
+        }
+
+        //receive response from server
+        deserialization.Deserialize(recv, ret);
+        if (ret != SECURITY_SERVER_API_SUCCESS) {
+            LogDebug("Received error from server");
+            return ret;
+        }
+
+    } 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;
+}
+
+
+SECURITY_SERVER_API
+int security_server_app_disable_permissions(const char *app_id, app_type_t app_type, const char **perm_list)
+{
+    using namespace SecurityServer;
+    SocketBuffer send, recv;
+    Serialization serialization;
+    Deserialization deserialization;
+    std::vector<std::string> permissions_list;
+    int i;
+    int ret;
+
+    LogDebug("security_server_app_disable_permissions() called");
+
+    try {
+        if ((NULL == app_id) || (strlen(app_id) == 0)) {
+            LogDebug("App_id is NULL");
+            return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+        }
+        if ((NULL == perm_list) || (strlen(perm_list[0]) == 0)) {
+            LogDebug("Perm_list is NULL");
+            return SECURITY_SERVER_API_ERROR_INPUT_PARAM;
+        }
+
+        LogDebug("app_type: " << (int)app_type);
+        LogDebug("app_id: " << app_id);
+
+        //put all strings in STL vector
+        for (i = 0; perm_list[i] != NULL; i++) {
+            LogDebug("perm_list[" << i << "]: " << perm_list[i]);
+            permissions_list.push_back(std::string(perm_list[i]));
+        }
+
+        //put data into buffer
+        serialization.Serialize(send, (int)AppPermissionsAction::DISABLE);   //works as a MSG_ID
+        serialization.Serialize(send, (int)app_type);
+        serialization.Serialize(send, std::string(app_id));
+        serialization.Serialize(send, permissions_list);
+
+        //send buffer to server
+        ret = sendToServer(SERVICE_SOCKET_APP_PERMISSIONS, send.Pop(), recv);
+        if (ret != SECURITY_SERVER_API_SUCCESS) {
+            LogDebug("Unable to send");
+            return ret;
+        }
+
+        //receive response from server
+        deserialization.Deserialize(recv, ret);
+        if (ret != SECURITY_SERVER_API_SUCCESS) {
+            LogDebug("Received error from server");
+            return ret;
+        }
+
+    } 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 91564da..1bb65a1 100644 (file)
@@ -38,6 +38,8 @@ char const * const SERVICE_SOCKET_EXEC_PATH =
     "/tmp/.security-server-api-exec-path.sock";
 char const * const SERVICE_SOCKET_GET_OBJECT_NAME =
     "/tmp/.security-server-api-get-object-name.sock";
+char const * const SERVICE_SOCKET_APP_PERMISSIONS =
+    "/tmp/.security-server-api-app-permissions.sock";
 
 } // namespace SecurityServer
 
index 4152383..54eef9c 100644 (file)
@@ -33,6 +33,9 @@ extern char const * const SERVICE_SOCKET_GET_GID;
 extern char const * const SERVICE_SOCKET_PRIVILEGE_BY_PID;
 extern char const * const SERVICE_SOCKET_EXEC_PATH;
 extern char const * const SERVICE_SOCKET_GET_OBJECT_NAME;
+extern char const * const SERVICE_SOCKET_APP_PERMISSIONS;
+
+enum class AppPermissionsAction { ENABLE, DISABLE};
 
 } // namespace SecuritySever
 
index 291f323..c333f64 100644 (file)
@@ -36,6 +36,7 @@
 #include <privilege-by-pid.h>
 #include <exec-path.h>
 #include <get-object-name.h>
+#include <app-permissions.h>
 #include <echo.h>
 
 IMPLEMENT_SAFE_SINGLETON(SecurityServer::Log::LogSystem);
@@ -72,6 +73,10 @@ int server2(void) {
         getObjectNameService->Create();
         manager.RegisterSocketService(getObjectNameService);
 
+        SecurityServer::AppPermissionsService *appEnablePermissionsService = new SecurityServer::AppPermissionsService;
+        appEnablePermissionsService->Create();
+        manager.RegisterSocketService(appEnablePermissionsService);
+
         manager.MainLoop();
     }
     UNHANDLED_EXCEPTION_HANDLER_END
diff --git a/src/server2/service/app-permissions.cpp b/src/server2/service/app-permissions.cpp
new file mode 100644 (file)
index 0000000..e536b54
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *  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        app-permissions.cpp
+ * @author      Pawel Polawski (pawel.polawski@partner.samsung.com)
+ * @version     1.0
+ * @brief       This function contain implementation of security_server_app_enable_permissions
+ *              and security_server_app_disable_permissions on server side
+ */
+
+#include <memory>
+#include <dpl/log/log.h>
+#include <dpl/serialization.h>
+#include <protocols.h>
+#include <security-server.h>
+#include <privilege-control.h>
+#include <security-server-common.h>
+#include <app-permissions.h>
+
+namespace SecurityServer {
+
+GenericSocketService::ServiceDescriptionVector AppPermissionsService::GetServiceDescription() {
+    ServiceDescription sd = {
+        "security-server::api-app-permissions",
+        0,
+        SERVICE_SOCKET_APP_PERMISSIONS
+    };
+    ServiceDescriptionVector v;
+    v.push_back(sd);
+    return v;
+}
+
+void AppPermissionsService::accept(const AcceptEvent &event) {
+    LogDebug("Accept event. ConnectionID.sock: " << event.connectionID.sock
+        << " ConnectionID.counter: " << event.connectionID.counter
+        << " ServiceID: " << event.interfaceID);
+}
+
+void AppPermissionsService::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 AppPermissionsService::read(const ReadEvent &event) {
+    LogDebug("Read event for counter: " << event.connectionID.counter);
+    auto &buffer = m_socketBufferMap[event.connectionID.counter];
+    buffer.Push(event.rawBuffer);
+
+    // We can get several requests in one package.
+    // Extract and process them all
+    while(readOne(event.connectionID, buffer));
+}
+
+void AppPermissionsService::close(const CloseEvent &event) {
+    LogDebug("CloseEvent. ConnectionID: " << event.connectionID.sock);
+    m_socketBufferMap.erase(event.connectionID.counter);
+}
+
+void AppPermissionsService::error(const ErrorEvent &event) {
+    LogDebug("ErrorEvent. ConnectionID: " << event.connectionID.sock);
+    m_serviceManager->Close(event.connectionID);
+}
+
+bool AppPermissionsService::readOne(const ConnectionID &conn, SocketBuffer &buffer)
+{
+    LogDebug("Iteration begin");
+    SocketBuffer send, recv;
+    Serialization serialization;
+    Deserialization deserialization;
+    std::vector<std::string> permissions_list;
+    std::string app_id;
+    int persistent;
+    int i;
+    int ret = SECURITY_SERVER_API_ERROR_SERVER_ERROR;
+    app_type_t app_type;
+    AppPermissionsAction appPermAction;
+
+    //waiting for all data
+    if (!buffer.Ready()) {
+        return false;
+    }
+
+    LogDebug("Entering app_permissions server side handler");
+
+    //receive data from buffer and check MSG_ID
+    Try {
+        deserialization.Deserialize(buffer, i);                 //receive MSG_ID
+        appPermAction = (AppPermissionsAction)i;
+
+        if (appPermAction == AppPermissionsAction::ENABLE)      //persistent is only in APP_ENABLE frame
+            deserialization.Deserialize(buffer, persistent);
+
+        deserialization.Deserialize(buffer, i);
+        app_type = (app_type_t)i;
+        deserialization.Deserialize(buffer, app_id);
+        deserialization.Deserialize(buffer, permissions_list);
+    } Catch (SocketBuffer::Exception::Base) {
+        LogDebug("Broken protocol. Closing socket.");
+        m_serviceManager->Close(conn);
+        return false;
+    }
+
+    //+1 bellow is for NULL pointer at the end
+    std::unique_ptr<const char *[]> perm_list (new (std::nothrow) const char *[permissions_list.size() + 1]);
+    if (NULL == perm_list.get()) {
+        LogError("Allocation error");
+        m_serviceManager->Close(conn);
+        return false;
+    }
+
+    //print received data
+    LogDebug("app_type: " << (int)app_type);
+    if (appPermAction == AppPermissionsAction::ENABLE)    //persistent is only in APP_ENABLE frame
+        LogDebug("persistent: " << persistent);
+    LogDebug("app_id: " << app_id);
+
+    //left one free pointer for the NULL at the end
+    for (i = 0; i < (int)permissions_list.size(); i++) {
+        LogDebug("perm_list[" << i << "]: " << permissions_list[i]);
+        perm_list[i] = (permissions_list[i]).c_str();
+    }
+    //put the NULL at the end
+    perm_list[i] = NULL;
+
+    //use received data
+    if (appPermAction == AppPermissionsAction::ENABLE) {
+        LogDebug("Calling app_enable_permiossions()");
+        ret = perm_app_enable_permissions(app_id.c_str(), app_type, perm_list.get(), persistent);
+        LogDebug("app_enable_permissions() returned: " << ret);
+    } else {
+        LogDebug("Calling app_disable_permiossions()");
+        ret = perm_app_disable_permissions(app_id.c_str(), app_type, perm_list.get());
+        LogDebug("app_disable_permissions() returned: " << ret);
+    }
+
+    //send response
+    serialization.Serialize(send, ret);
+    m_serviceManager->Write(conn, send.Pop());
+    return true;
+}
+
+} // namespace SecurityServer
+
diff --git a/src/server2/service/app-permissions.h b/src/server2/service/app-permissions.h
new file mode 100644 (file)
index 0000000..183d9cc
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  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        app-permissions.h
+ * @author      Pawel Polawski (pawel.polawski@partner.samsung.com)
+ * @version     1.0
+ * @brief       This function contain header for implementation of security_server_app_enable_permissions
+ *              and SS_app_disable_permissions on server side
+ */
+
+#ifndef _SECURITY_SERVER_APP_PERMISSIONS_
+#define _SECURITY_SERVER_APP_PERMISSIONS__
+
+#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 AppPermissionsService  :
+    public SecurityServer::GenericSocketService
+  , public SecurityServer::ServiceThread<AppPermissionsService>
+{
+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:
+    bool readOne(const ConnectionID &conn, SocketBuffer &buffer);
+
+    SocketBufferMap m_socketBufferMap;
+};
+
+} // namespace SecurityServer
+
+#endif // _SECURITY_SERVER_APP_ENABLE_PERMISSIONS_
index 267a5da..79d6a1e 100644 (file)
@@ -6,6 +6,7 @@ INSTALL(FILES
     ${CMAKE_SOURCE_DIR}/systemd/security-server-privilege-by-pid.socket
     ${CMAKE_SOURCE_DIR}/systemd/security-server-exec-path.socket
     ${CMAKE_SOURCE_DIR}/systemd/security-server-get-object-name.socket
+    ${CMAKE_SOURCE_DIR}/systemd/security-server-app-permissions.socket
     DESTINATION
     /usr/lib/systemd/system
 )
diff --git a/systemd/security-server-app-permissions.socket b/systemd/security-server-app-permissions.socket
new file mode 100644 (file)
index 0000000..5faa4ec
--- /dev/null
@@ -0,0 +1,10 @@
+[Socket]
+ListenStream=/tmp/.security-server-api-app-permissions.sock
+SocketMode=0777
+SmackLabelIPIn=security-server::api-app-permissions
+SmackLabelIPOut=@
+
+Service=security-server.service
+
+[Install]
+WantedBy=sockets.target