Apply user space smack, step 1
authorWonkyu Kwon <wonkyu.kwon@samsung.com>
Tue, 23 Jul 2013 06:45:58 +0000 (15:45 +0900)
committerWonkyu Kwon <wonkyu.kwon@samsung.com>
Wed, 24 Jul 2013 08:56:38 +0000 (17:56 +0900)
Change-Id: Idc828cac02c4212267060cdfd98e35d61c62d27f

13 files changed:
CMakeLists.txt
client/ClientChannel.cpp
client/ClientGDBus.cpp [new file with mode: 0644]
client/Reader.cpp
client/SEService.cpp
client/Session.cpp
client/include/ClientGDBus.h [new file with mode: 0644]
common/include/ReaderHelper.h
common/smartcard-service-gdbus.xml
server/ServerGDBus.cpp
server/ServerResource.cpp
server/include/ClientInstance.h
server/include/ServerGDBus.h

index 8646bee..224b22e 100644 (file)
@@ -6,7 +6,10 @@ SET(CMAKE_VERBOSE_MAKEFILE OFF)
 
 IF(DEFINED USE_GDBUS)
        ADD_DEFINITIONS("-DUSE_GDBUS")
-       
+
+       # apply smack
+       ADD_DEFINITIONS("-DUSER_SPACE_SMACK")
+
        IF(DEFINED USE_AUTOSTART)
                ADD_DEFINITIONS("-DUSE_AUTOSTART")
        ENDIF()
index d42aaa6..bbf6988 100644 (file)
@@ -30,8 +30,7 @@
 #include "ReaderHelper.h"
 #include "APDUHelper.h"
 #ifdef USE_GDBUS
-#include "smartcard-service-gdbus.h"
-#include "GDBusHelper.h"
+#include "ClientGDBus.h"
 #else
 #include "Message.h"
 #include "ClientIPC.h"
@@ -197,6 +196,7 @@ namespace smartcard_service_api
 
                                if (smartcard_service_channel_call_close_channel_sync(
                                        (SmartcardServiceChannel *)proxy,
+                                       ClientGDBus::getCookie(),
                                        GPOINTER_TO_UINT(context),
                                        GPOINTER_TO_UINT(handle),
                                        &ret, NULL, &error) == true) {
@@ -272,6 +272,7 @@ namespace smartcard_service_api
 
                                smartcard_service_channel_call_close_channel(
                                        (SmartcardServiceChannel *)proxy,
+                                       ClientGDBus::getCookie(),
                                        GPOINTER_TO_UINT(context),
                                        GPOINTER_TO_UINT(handle), NULL,
                                        &ClientChannel::channel_close_cb, param);
@@ -320,6 +321,7 @@ namespace smartcard_service_api
 
                        if (smartcard_service_channel_call_transmit_sync(
                                (SmartcardServiceChannel *)proxy,
+                               ClientGDBus::getCookie(),
                                GPOINTER_TO_UINT(context),
                                GPOINTER_TO_UINT(handle),
                                var_command, &rv, &var_response,
@@ -404,6 +406,7 @@ namespace smartcard_service_api
 
                        smartcard_service_channel_call_transmit(
                                (SmartcardServiceChannel *)proxy,
+                               ClientGDBus::getCookie(),
                                GPOINTER_TO_UINT(context),
                                GPOINTER_TO_UINT(handle),
                                var_command, NULL,
diff --git a/client/ClientGDBus.cpp b/client/ClientGDBus.cpp
new file mode 100644 (file)
index 0000000..2eee1c5
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#ifdef USE_GDBUS
+/* standard library header */
+#include <glib.h>
+
+/* SLP library header */
+#ifdef USER_SPACE_SMACK
+#include "security-server.h"
+#endif
+
+/* local header */
+#include "smartcard-types.h"
+#include "Debug.h"
+#include "ByteArray.h"
+#include "ClientGDBus.h"
+
+using namespace std;
+
+namespace smartcard_service_api
+{
+       ByteArray ClientGDBus::cookie = ByteArray::EMPTY;
+
+       GVariant *ClientGDBus::getCookie()
+       {
+               GVariant *result;
+#ifdef USER_SPACE_SMACK
+               if (cookie.isEmpty()) {
+                       uint8_t *buffer;
+                       int len;
+
+                       len = security_server_get_cookie_size();
+                       if (len > 0) {
+                               buffer = new uint8_t[len];
+                               if (buffer != NULL) {
+                                       if (security_server_request_cookie(
+                                               (char *)buffer, len) == 0) {
+                                               cookie.assign(buffer, len);
+                                       } else {
+                                               _ERR("security_server_request_cookie failed");
+                                       }
+
+                                       delete[] buffer;
+                               } else {
+                                       _ERR("alloc failed");
+                               }
+                       } else {
+                               _ERR("security_server_get_cookie_size failed");
+                       }
+               }
+#endif
+               result = GDBusHelper::convertByteArrayToVariant(cookie);
+
+               return result;
+       }
+} /* namespace smartcard_service_api */
+#endif
index c140b04..1ba8c12 100644 (file)
@@ -26,7 +26,7 @@
 #include "Reader.h"
 #include "Session.h"
 #ifdef USE_GDBUS
-#include "GDBusHelper.h"
+#include "ClientGDBus.h"
 #include "smartcard-service-gdbus.h"
 #else
 #include "Message.h"
 namespace smartcard_service_api
 {
        Reader::Reader(void *context, const char *name, void *handle) :
-               ReaderHelper(), context(context), handle(handle)
+               ReaderHelper(name), context(context), handle(handle)
        {
                _BEGIN();
 
-               if (context == NULL || name == NULL || strlen(name) == 0 || handle == NULL)
+               if (context == NULL || name == NULL ||
+                       strlen(name) == 0 || handle == NULL)
                {
                        _ERR("invalid param");
 
                        return;
                }
-
-               this->handle = handle;
-               this->context = context;
-               this->name = name;
 #ifdef USE_GDBUS
                /* initialize client */
                if (!g_thread_supported())
@@ -123,12 +120,12 @@ namespace smartcard_service_api
 
                        if (smartcard_service_reader_call_open_session_sync(
                                (SmartcardServiceReader *)proxy,
+                               ClientGDBus::getCookie(),
                                GPOINTER_TO_UINT(context),
                                GPOINTER_TO_UINT(handle),
                                &result, &session_id, NULL, &error) == true) {
                                if (result == SCARD_ERROR_OK) {
                                        /* create new instance of channel */
-
                                        session = new Session(context, this,
                                                GUINT_TO_POINTER(session_id));
                                        if (session != NULL) {
@@ -267,6 +264,7 @@ namespace smartcard_service_api
 
                        smartcard_service_reader_call_open_session(
                                (SmartcardServiceReader *)proxy,
+                               ClientGDBus::getCookie(),
                                GPOINTER_TO_UINT(context),
                                GPOINTER_TO_UINT(handle),
                                NULL, &Reader::reader_open_session_cb, param);
index 9136258..9d467a0 100644 (file)
@@ -27,7 +27,7 @@
 #include "SEService.h"
 #include "Reader.h"
 #ifdef USE_GDBUS
-#include "smartcard-service-gdbus.h"
+#include "ClientGDBus.h"
 #else
 #include "Message.h"
 #include "ClientIPC.h"
@@ -88,13 +88,15 @@ namespace smartcard_service_api
                readers.clear();
        }
 
-       SEService *SEService::createInstance(void *user_data, SEServiceListener *listener)
+       SEService *SEService::createInstance(void *user_data,
+               SEServiceListener *listener)
                throw(ErrorIO &, ErrorIllegalParameter &)
        {
                return new SEService(user_data, listener);
        }
 
-       SEService *SEService::createInstance(void *user_data, serviceConnected handler)
+       SEService *SEService::createInstance(void *user_data,
+               serviceConnected handler)
                throw(ErrorIO &, ErrorIllegalParameter &)
        {
                return new SEService(user_data, handler);
@@ -234,8 +236,12 @@ namespace smartcard_service_api
                        }
 #ifdef USE_GDBUS
                        smartcard_service_se_service_call_shutdown(
-                               (SmartcardServiceSeService *)proxy, handle,
-                               NULL, &SEService::se_service_shutdown_cb, this);
+                               (SmartcardServiceSeService *)proxy,
+                               ClientGDBus::getCookie(),
+                               handle,
+                               NULL,
+                               &SEService::se_service_shutdown_cb,
+                               this);
 #else
                        Message msg;
 
@@ -269,7 +275,11 @@ namespace smartcard_service_api
 
                        if (smartcard_service_se_service_call_shutdown_sync(
                                (SmartcardServiceSeService *)proxy,
-                               handle, &result, NULL, &error) == false) {
+                               ClientGDBus::getCookie(),
+                               handle,
+                               &result,
+                               NULL,
+                               &error) == false) {
                                _ERR("smartcard_service_se_service_call_shutdown_sync failed, [%s]", error->message);
 
                                g_error_free(error);
@@ -355,8 +365,11 @@ namespace smartcard_service_api
 
                /* request reader */
                smartcard_service_se_service_call_se_service(
-                       (SmartcardServiceSeService *)proxy, NULL,
-                       &SEService::se_service_cb, this);
+                       (SmartcardServiceSeService *)proxy,
+                       ClientGDBus::getCookie(),
+                       NULL,
+                       &SEService::se_service_cb,
+                       this);
 #else
                clientDispatcher = &ClientDispatcher::getInstance();
                clientIPC = &ClientIPC::getInstance();
@@ -457,7 +470,8 @@ namespace smartcard_service_api
                return true;
        }
 #endif
-       bool SEService::parseReaderInformation(unsigned int count, const ByteArray &data)
+       bool SEService::parseReaderInformation(unsigned int count,
+               const ByteArray &data)
        {
                size_t i;
                unsigned int offset = 0;
index 6951ced..18b2275 100644 (file)
@@ -28,8 +28,7 @@
 #include "Reader.h"
 #include "ClientChannel.h"
 #ifdef USE_GDBUS
-#include "smartcard-service-gdbus.h"
-#include "GDBusHelper.h"
+#include "ClientGDBus.h"
 #else
 #include "ClientIPC.h"
 #endif
@@ -270,6 +269,7 @@ namespace smartcard_service_api
 
                                if (smartcard_service_session_call_get_atr_sync(
                                        (SmartcardServiceSession *)proxy,
+                                       ClientGDBus::getCookie(),
                                        GPOINTER_TO_UINT(context),
                                        GPOINTER_TO_UINT(handle),
                                        &ret, &var_atr, NULL, &error) == true) {
@@ -352,6 +352,7 @@ namespace smartcard_service_api
 
                                smartcard_service_session_call_get_atr(
                                        (SmartcardServiceSession *)proxy,
+                                       ClientGDBus::getCookie(),
                                        GPOINTER_TO_UINT(context),
                                        GPOINTER_TO_UINT(handle), NULL,
                                        &Session::session_get_atr_cb, param);
@@ -411,6 +412,7 @@ namespace smartcard_service_api
 
                        if (smartcard_service_session_call_close_session_sync(
                                (SmartcardServiceSession *)proxy,
+                               ClientGDBus::getCookie(),
                                GPOINTER_TO_UINT(context),
                                GPOINTER_TO_UINT(handle),
                                &ret, NULL, &error) == true) {
@@ -483,6 +485,7 @@ namespace smartcard_service_api
 
                        smartcard_service_session_call_close_session(
                                (SmartcardServiceSession *)proxy,
+                               ClientGDBus::getCookie(),
                                GPOINTER_TO_UINT(context),
                                GPOINTER_TO_UINT(handle), NULL,
                                &Session::session_close_cb, param);
@@ -618,6 +621,7 @@ namespace smartcard_service_api
 
                        if (smartcard_service_session_call_open_channel_sync(
                                (SmartcardServiceSession *)proxy,
+                               ClientGDBus::getCookie(),
                                GPOINTER_TO_UINT(context),
                                GPOINTER_TO_UINT(handle),
                                (guint)id, var_aid, &ret, &channel_id,
@@ -721,6 +725,7 @@ namespace smartcard_service_api
 
                        smartcard_service_session_call_open_channel(
                                (SmartcardServiceSession *)proxy,
+                               ClientGDBus::getCookie(),
                                GPOINTER_TO_UINT(context),
                                GPOINTER_TO_UINT(handle),
                                (guint)id, var_aid, NULL,
diff --git a/client/include/ClientGDBus.h b/client/include/ClientGDBus.h
new file mode 100644 (file)
index 0000000..1909382
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
+ *
+ * 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.
+ */
+
+#ifndef CLIENTGDBUS_H_
+#define CLIENTGDBUS_H_
+
+#ifdef USE_GDBUS
+/* standard library header */
+#include <glib.h>
+
+/* SLP library header */
+
+/* local header */
+#include "GDBusHelper.h"
+#include "smartcard-service-gdbus.h"
+
+namespace smartcard_service_api
+{
+       class ClientGDBus
+       {
+       public :
+               static GVariant *getCookie();
+
+       private :
+               static ByteArray cookie;
+       };
+} /* namespace smartcard_service_api */
+#endif
+#endif /* CLIENTGDBUS_H_ */
index f34436c..259044a 100644 (file)
@@ -33,17 +33,20 @@ namespace smartcard_service_api
 {
        class SEServiceHelper;
 
-       typedef void (*openSessionCallback)(SessionHelper *session, int error, void *userData);
+       typedef void (*openSessionCallback)(SessionHelper *session, int error,
+               void *userData);
 
        class ReaderHelper : public Synchronous
        {
        protected:
-               string name;
-               vector<SessionHelper *> sessions;
                SEServiceHelper *seService;
+               string name;
                bool present;
+               vector<SessionHelper *> sessions;
 
                ReaderHelper() : seService(NULL), present(false) {}
+               ReaderHelper(const char *name) : seService(NULL), name(name),
+                       present(false) {}
                virtual ~ReaderHelper() {}
 
        public:
index cc8b21a..da14b88 100755 (executable)
@@ -8,6 +8,7 @@
       SeService
     -->
     <method name="SeService">
+      <arg type="a(y)" name="privilege" direction="in" />
       <arg type="i" name="result" direction="out" />
       <arg type="u" name="handle" direction="out" />
       <arg type="a(us)" name="readers" direction="out" />
@@ -17,6 +18,7 @@
       shutdown
     -->
     <method name="shutdown">
+      <arg type="a(y)" name="privilege" direction="in" />
       <arg type="u" name="service_id" direction="in" />
       <arg type="i" name="result" direction="out" />
     </method>
@@ -43,6 +45,7 @@
       openSession
     -->
     <method name="openSession">
+      <arg type="a(y)" name="privilege" direction="in" />
       <arg type="u" name="service_id" direction="in" />
       <arg type="u" name="reader_id" direction="in" />
       <arg type="i" name="result" direction="out" />
@@ -55,6 +58,7 @@
       getATR
     -->
     <method name="getATR">
+      <arg type="a(y)" name="privilege" direction="in" />
       <arg type="u" name="service_id" direction="in" />
       <arg type="u" name="session_id" direction="in" />
       <arg type="i" name="result" direction="out" />
@@ -64,6 +68,7 @@
       openChannel
     -->
     <method name="openChannel">
+      <arg type="a(y)" name="privilege" direction="in" />
       <arg type="u" name="service_id" direction="in" />
       <arg type="u" name="session_id" direction="in" />
       <arg type="u" name="type" direction="in" />
@@ -76,6 +81,7 @@
       closeSession
     -->
     <method name="closeSession">
+      <arg type="a(y)" name="privilege" direction="in" />
       <arg type="u" name="service_id" direction="in" />
       <arg type="u" name="session_id" direction="in" />
       <arg type="i" name="result" direction="out" />
@@ -87,6 +93,7 @@
       transmit
     -->
     <method name="transmit">
+      <arg type="a(y)" name="privilege" direction="in" />
       <arg type="u" name="service_id" direction="in" />
       <arg type="u" name="channel_id" direction="in" />
       <arg type="a(y)" name="command" direction="in" />
       closeChannel
     -->
     <method name="closeChannel">
+      <arg type="a(y)" name="privilege" direction="in" />
       <arg type="u" name="service_id" direction="in" />
       <arg type="u" name="channel_id" direction="in" />
       <arg type="i" name="result" direction="out" />
index 87a0c65..1c1ae5e 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #ifdef USE_GDBUS
+/* standard library header */
 #include <unistd.h>
 #include <glib.h>
 #include <gio/gio.h>
 #include <string>
 #include <sys/socket.h>
 
+/* SLP library header */
+#include "security-server.h"
+
+/* local header */
 #include "smartcard-types.h"
 #include "Debug.h"
 #include "ByteArray.h"
@@ -48,22 +53,27 @@ namespace smartcard_service_api
                return dispatcher;
        }
 
-       void GDBusDispatcher::push(dispatcher_cb_t cb, const vector<void *> &params)
+       void GDBusDispatcher::_push(dispatcher_cb_t cb,
+               const vector<void *> &params)
        {
-               _BEGIN();
-
                syncLock();
 
                q.push(make_pair(cb, params));
+               _INFO("request pushed, count [%d]", q.size());
+
                if (q.size() == 1) {
                        /* start dispatch */
-                       _INFO("start dispatch");
+                       _INFO("start dispatcher");
                        g_idle_add(&GDBusDispatcher::dispatch, this);
                }
 
                syncUnlock();
+       }
 
-               _END();
+       void GDBusDispatcher::push(dispatcher_cb_t cb,
+               const vector<void *> &params)
+       {
+               GDBusDispatcher::getInstance()._push(cb, params);
        }
 
        gboolean GDBusDispatcher::dispatch(gpointer user_data)
@@ -90,7 +100,7 @@ namespace smartcard_service_api
 
                        result = true;
                } else {
-                       _INFO("dispatch finish");
+                       _INFO("dispatch finished");
                }
 
                dispatcher->syncUnlock();
@@ -117,7 +127,7 @@ namespace smartcard_service_api
                return serverGDBus;
        }
 
-       void ServerGDBus::name_owner_changed(GDBusProxy *proxy,
+       static void name_owner_changed(GDBusProxy *proxy,
                const gchar *name, const gchar *old_owner,
                const gchar *new_owner, void *user_data)
        {
@@ -138,6 +148,26 @@ namespace smartcard_service_api
                }
        }
 
+       static void _on_name_owner_changed(GDBusConnection *connection,
+               const gchar *sender_name, const gchar *object_path,
+               const gchar *interface_name, const gchar *signal_name,
+               GVariant *parameters, gpointer user_data)
+       {
+               GVariantIter *iter;
+               gchar *name;
+               gchar *old_owner;
+               gchar *new_owner;
+
+               iter = g_variant_iter_new(parameters);
+
+               g_variant_iter_next(iter, "s", &name);
+               g_variant_iter_next(iter, "s", &old_owner);
+               g_variant_iter_next(iter, "s", &new_owner);
+
+               name_owner_changed((GDBusProxy *)connection,
+                       name, old_owner, new_owner, user_data);
+       }
+
        bool ServerGDBus::_init()
        {
                GError *error = NULL;
@@ -159,9 +189,16 @@ namespace smartcard_service_api
                        return false;
                }
 
-               g_signal_connect(dbus_proxy, "name-owner-changed",
-                               G_CALLBACK(&ServerGDBus::name_owner_changed),
-                               this);
+               /* subscribe signal */
+               g_dbus_connection_signal_subscribe(connection,
+                       "org.freedesktop.DBus", /* bus name */
+                       "org.freedesktop.DBus", /* interface */
+                       "NameOwnerChanged", /* member */
+                       "/org/freedesktop/DBus", /* path */
+                       NULL, /* arg0 */
+                       G_DBUS_SIGNAL_FLAGS_NONE,
+                       _on_name_owner_changed,
+                       NULL, NULL);
 
                return true;
        }
@@ -178,8 +215,6 @@ namespace smartcard_service_api
        {
                GError *error = NULL;
 
-               _init();
-
                connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
                if (connection != NULL) {
                } else {
@@ -189,6 +224,8 @@ namespace smartcard_service_api
                        return false;
                }
 
+               _init();
+
                initSEService();
                initReader();
                initSession();
@@ -204,12 +241,12 @@ namespace smartcard_service_api
                deinitSession();
                deinitChannel();
 
+               _deinit();
+
                if (connection != NULL) {
                        g_object_unref(connection);
                        connection = NULL;
                }
-
-               _deinit();
        }
 
        static gboolean _call_get_connection_unix_process_id_sync(
@@ -218,10 +255,10 @@ namespace smartcard_service_api
                GVariant *_ret;
 
                _ret = g_dbus_proxy_call_sync(proxy,
-                               "GetConnectionUnixProcessID",
-                               g_variant_new("(s)", arg_name),
-                               G_DBUS_CALL_FLAGS_NONE,
-                               -1, cancellable, error);
+                       "GetConnectionUnixProcessID",
+                       g_variant_new("(s)", arg_name),
+                       G_DBUS_CALL_FLAGS_NONE,
+                       -1, cancellable, error);
                if (_ret != NULL) {
                        g_variant_get(_ret, "(u)", out_pid);
                        g_variant_unref(_ret);
@@ -246,11 +283,30 @@ namespace smartcard_service_api
                return pid;
        }
 
+       static bool _is_authorized_request(GVariant *privilege,
+               const char *rights)
+       {
+               bool result = true;
+#ifdef USER_SPACE_SMACK
+               ByteArray temp;
+
+               /* apply user space smack */
+               GDBusHelper::convertVariantToByteArray(privilege, temp);
+
+               result = (security_server_check_privilege_by_cookie(
+                       (char *)temp.getBuffer(),
+                       "smartcard-service",
+                       rights) == SECURITY_SERVER_API_SUCCESS);
+#endif
+               return result;
+       }
+
        /* SEService *
         *
         *
         */
-       static GVariant *_reader_to_variant(vector<pair<unsigned int, string> > &readers)
+       static GVariant *_reader_to_variant(
+               vector<pair<unsigned int, string> > &readers)
        {
                GVariantBuilder builder;
                uint32_t i;
@@ -258,14 +314,16 @@ namespace smartcard_service_api
                g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
 
                for (i = 0; i < readers.size(); i++) {
-                       g_variant_builder_add(&builder, "(us)", readers[i].first, readers[i].second.c_str());
+                       g_variant_builder_add(&builder, "(us)",
+                               readers[i].first, readers[i].second.c_str());
                }
 
                return g_variant_builder_end(&builder);
        }
 
        static gboolean __process_se_service(SmartcardServiceSeService *object,
-               GDBusMethodInvocation *invocation, void *user_data)
+               GDBusMethodInvocation *invocation,
+               void *user_data)
        {
                _INFO("[MSG_REQUEST_READERS]");
 
@@ -273,15 +331,18 @@ namespace smartcard_service_api
                GVariant *readers = NULL;
                vector<pair<unsigned int, string> > list;
                unsigned int handle = IntegerHandle::INVALID_HANDLE;
+               const char *name;
 
                ServerResource &resource = ServerResource::getInstance();
 
+               name = g_dbus_method_invocation_get_sender(invocation);
+
+               pid_t pid;
+
                /* load secure elements */
                resource.loadSecureElements();
 
-               const char *name = g_dbus_method_invocation_get_sender(invocation);
-
-               pid_t pid = ServerGDBus::getInstance().getPID(name);
+               pid = ServerGDBus::getInstance().getPID(name);
 
                _INFO("service requested, pid [%d]", pid);
 
@@ -310,6 +371,9 @@ namespace smartcard_service_api
                                        handle = service->getHandle();
                                        resource.getReaders(list);
 
+                                       if (list.size() == 0) {
+                                               _INFO("no secure elements");
+                                       }
                                } else {
                                        _ERR("createService failed");
 
@@ -327,10 +391,6 @@ namespace smartcard_service_api
                }
 
                readers = _reader_to_variant(list);
-               if (list.size() > 0) {
-               } else {
-                       _INFO("no secure elements");
-               }
 
                /* response to client */
                smartcard_service_se_service_complete_se_service(object,
@@ -356,42 +416,70 @@ namespace smartcard_service_api
                user_data = params[2];
 
                __process_se_service(object, invocation, user_data);
+
+               g_object_unref(object);
+               g_object_unref(invocation);
        }
 
        static gboolean _handle_se_service(SmartcardServiceSeService *object,
-               GDBusMethodInvocation *invocation, void *user_data)
+               GDBusMethodInvocation *invocation,
+               GVariant *privilege,
+               void *user_data)
        {
                vector<void *> params;
 
-               g_object_ref(object);
-               params.push_back((void *)object);
+               /* apply user space smack */
+               if (_is_authorized_request(privilege, "r") == true) {
+                       g_object_ref(object);
+                       params.push_back((void *)object);
+
+                       g_object_ref(invocation);
+                       params.push_back((void *)invocation);
 
-               g_object_ref(invocation);
-               params.push_back((void *)invocation);
+                       params.push_back((void *)user_data);
 
-               params.push_back((void *)user_data);
+                       GDBusDispatcher::push(_process_se_service, params);
+               } else {
+                       vector<pair<unsigned int, string> > list;
 
-               GDBusDispatcher::getInstance().push(_process_se_service,
-                       params);
+                       _ERR("access denied");
+
+                       /* response to client */
+                       smartcard_service_se_service_complete_se_service(object,
+                               invocation,
+                               SCARD_ERROR_SECURITY_NOT_ALLOWED,
+                               IntegerHandle::INVALID_HANDLE,
+                               _reader_to_variant(list));
+               }
 
                return true;
        }
 
-
        static gboolean __process_shutdown(SmartcardServiceSeService *object,
                GDBusMethodInvocation *invocation,
                guint handle, void *user_data)
        {
+               const char *name;
+
                _INFO("[MSG_REQUEST_SHUTDOWN]");
 
-               const char *name = g_dbus_method_invocation_get_sender(invocation);
+               name = g_dbus_method_invocation_get_sender(invocation);
+
+               ServerResource &resource = ServerResource::getInstance();
 
-               ServerResource::getInstance().removeService(name, handle);
+               resource.removeService(name, handle);
 
                /* response to client */
                smartcard_service_se_service_complete_shutdown(object,
                        invocation, SCARD_ERROR_OK);
 
+               /* terminate */
+               if (resource.getClientCount() == 0) {
+                       _INFO("no client connected. terminate server");
+
+                       g_main_loop_quit((GMainLoop *)resource.getMainLoopInstance());
+               }
+
                return true;
        }
 
@@ -414,25 +502,38 @@ namespace smartcard_service_api
                user_data = params[3];
 
                __process_shutdown(object, invocation, handle, user_data);
+
+               g_object_unref(object);
+               g_object_unref(invocation);
        }
 
        static gboolean _handle_shutdown(SmartcardServiceSeService *object,
-               GDBusMethodInvocation *invocation, guint handle,
+               GDBusMethodInvocation *invocation,
+               GVariant *privilege,
+               guint handle,
                void *user_data)
        {
                vector<void *> params;
 
-               g_object_ref(object);
-               params.push_back((void *)object);
+               /* apply user space smack */
+               if (_is_authorized_request(privilege, "r") == true) {
+                       g_object_ref(object);
+                       params.push_back((void *)object);
 
-               g_object_ref(invocation);
-               params.push_back((void *)invocation);
+                       g_object_ref(invocation);
+                       params.push_back((void *)invocation);
 
-               params.push_back((void *)handle);
-               params.push_back(user_data);
+                       params.push_back((void *)handle);
+                       params.push_back(user_data);
 
-               GDBusDispatcher::getInstance().push(_process_shutdown,
-                       params);
+                       GDBusDispatcher::push(_process_shutdown, params);
+               } else {
+                       _ERR("access denied");
+
+                       /* response to client */
+                       smartcard_service_se_service_complete_shutdown(object,
+                               invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
+               }
 
                return true;
        }
@@ -505,31 +606,32 @@ namespace smartcard_service_api
        {
                unsigned int handle = IntegerHandle::INVALID_HANDLE;
                int result;
+               const char *name;
 
                _INFO("[MSG_REQUEST_OPEN_SESSION]");
 
                ServerResource &resource = ServerResource::getInstance();
 
-               const char *name = g_dbus_method_invocation_get_sender(invocation);
+               name = g_dbus_method_invocation_get_sender(invocation);
 
-               if (resource.isValidReaderHandle(reader_id))
-               {
+               if (resource.isValidReaderHandle(reader_id)) {
                        vector<ByteArray> temp;
 
-                       handle = resource.createSession(name, service_id, reader_id, temp, (void *)NULL);
-                       if (handle != IntegerHandle::INVALID_HANDLE)
-                       {
+                       handle = resource.createSession(name,
+                               service_id,
+                               reader_id,
+                               temp,
+                               (void *)NULL);
+                       if (handle != IntegerHandle::INVALID_HANDLE) {
                                result = SCARD_ERROR_OK;
-                       }
-                       else
-                       {
+                       } else {
                                _ERR("createSession failed [%d]", handle);
+
                                result = SCARD_ERROR_OUT_OF_MEMORY;
                        }
-               }
-               else
-               {
+               } else {
                        _ERR("request invalid reader handle [%d]", reader_id);
+
                        result = SCARD_ERROR_ILLEGAL_PARAM;
                }
 
@@ -562,26 +664,41 @@ namespace smartcard_service_api
 
                __process_open_session(object, invocation, service_id,
                        reader_id, user_data);
+
+               g_object_unref(object);
+               g_object_unref(invocation);
        }
 
        static gboolean _handle_open_session(SmartcardServiceReader *object,
-               GDBusMethodInvocation *invocation, guint service_id,
+               GDBusMethodInvocation *invocation,
+               GVariant *privilege,
+               guint service_id,
                guint reader_id, void *user_data)
        {
                vector<void *> params;
 
-               g_object_ref(object);
-               params.push_back((void *)object);
+               /* apply user space smack */
+               if (_is_authorized_request(privilege, "r") == true) {
+                       g_object_ref(object);
+                       params.push_back((void *)object);
 
-               g_object_ref(invocation);
-               params.push_back((void *)invocation);
+                       g_object_ref(invocation);
+                       params.push_back((void *)invocation);
 
-               params.push_back((void *)service_id);
-               params.push_back((void *)reader_id);
-               params.push_back(user_data);
+                       params.push_back((void *)service_id);
+                       params.push_back((void *)reader_id);
+                       params.push_back(user_data);
 
-               GDBusDispatcher::getInstance().push(_process_open_session,
-                       params);
+                       GDBusDispatcher::push(_process_open_session, params);
+               } else {
+                       _ERR("access denied");
+
+                       /* response to client */
+                       smartcard_service_reader_complete_open_session(object,
+                               invocation,
+                               SCARD_ERROR_SECURITY_NOT_ALLOWED,
+                               IntegerHandle::INVALID_HANDLE);
+               }
 
                return true;
        }
@@ -631,15 +748,20 @@ namespace smartcard_service_api
                GDBusMethodInvocation *invocation, guint service_id,
                guint session_id, void *user_data)
        {
+               const char *name;
+
                _INFO("[MSG_REQUEST_CLOSE_SESSION]");
 
                ServerResource &resource = ServerResource::getInstance();
 
-               const char *name = g_dbus_method_invocation_get_sender(invocation);
+               name = g_dbus_method_invocation_get_sender(invocation);
 
-               if (resource.isValidSessionHandle(name, service_id, session_id))
-               {
-                       resource.removeSession(name, service_id, session_id);
+               if (resource.isValidSessionHandle(name, service_id,
+                       session_id)) {
+                       resource.removeSession(name, service_id,
+                               session_id);
+               } else {
+                       _ERR("invalid parameters");
                }
 
                /* response to client */
@@ -671,26 +793,39 @@ namespace smartcard_service_api
 
                __process_close_session(object, invocation, service_id,
                        session_id, user_data);
+
+               g_object_unref(object);
+               g_object_unref(invocation);
        }
 
        static gboolean _handle_close_session(SmartcardServiceSession *object,
-               GDBusMethodInvocation *invocation, guint service_id,
+               GDBusMethodInvocation *invocation,
+               GVariant *privilege,
+               guint service_id,
                guint session_id, void *user_data)
        {
                vector<void *> params;
 
-               g_object_ref(object);
-               params.push_back((void *)object);
+               /* apply user space smack */
+               if (_is_authorized_request(privilege, "r") == true) {
+                       g_object_ref(object);
+                       params.push_back((void *)object);
 
-               g_object_ref(invocation);
-               params.push_back((void *)invocation);
+                       g_object_ref(invocation);
+                       params.push_back((void *)invocation);
 
-               params.push_back((void *)service_id);
-               params.push_back((void *)session_id);
-               params.push_back(user_data);
+                       params.push_back((void *)service_id);
+                       params.push_back((void *)session_id);
+                       params.push_back(user_data);
 
-               GDBusDispatcher::getInstance().push(_process_close_session,
-                       params);
+                       GDBusDispatcher::push(_process_close_session, params);
+               } else {
+                       _ERR("access denied");
+
+                       /* response to client */
+                       smartcard_service_session_complete_close_session(object,
+                               invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
+               }
 
                return true;
        }
@@ -700,51 +835,45 @@ namespace smartcard_service_api
                guint session_id, void *user_data)
        {
                int result;
+               ByteArray resp;
                GVariant *atr = NULL;
-               ServiceInstance *client = NULL;
+               const char *name;
 
                _INFO("[MSG_REQUEST_GET_ATR]");
 
                ServerResource &resource = ServerResource::getInstance();
 
-               const char *name = g_dbus_method_invocation_get_sender(invocation);
+               name = g_dbus_method_invocation_get_sender(invocation);
 
-               if ((client = resource.getService(name, service_id)) != NULL)
-               {
-                       Terminal *terminal = NULL;
+               ServiceInstance *client = NULL;
 
-                       if ((terminal = client->getTerminal(session_id)) != NULL)
-                       {
+               client = resource.getService(name, service_id);
+               if (client != NULL) {
+                       Terminal *terminal;
+
+                       terminal = client->getTerminal(session_id);
+                       if (terminal != NULL) {
                                int rv;
-                               ByteArray temp;
 
-                               if ((rv = terminal->getATRSync(temp)) == 0)
-                               {
-                                       atr = GDBusHelper::convertByteArrayToVariant(temp);
+                               if ((rv = terminal->getATRSync(resp)) == 0) {
                                        result = SCARD_ERROR_OK;
-                               }
-                               else
-                               {
-                                       _ERR("transmit failed [%d]", rv);
+                               } else {
+                                       _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
 
                                        result = rv;
                                }
-                       }
-                       else
-                       {
+                       } else {
                                _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
+
                                result = SCARD_ERROR_UNAVAILABLE;
                        }
-               }
-               else
-               {
+               } else {
                        _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
+
                        result = SCARD_ERROR_UNAVAILABLE;
                }
 
-               if (atr == NULL) {
-                       atr = GDBusHelper::convertByteArrayToVariant(ByteArray::EMPTY);
-               }
+               atr = GDBusHelper::convertByteArrayToVariant(resp);
 
                /* response to client */
                smartcard_service_session_complete_get_atr(object, invocation,
@@ -775,26 +904,44 @@ namespace smartcard_service_api
 
                __process_get_atr(object, invocation, service_id,
                        session_id, user_data);
+
+               g_object_unref(object);
+               g_object_unref(invocation);
        }
 
        static gboolean _handle_get_atr(SmartcardServiceSession *object,
-               GDBusMethodInvocation *invocation, guint service_id,
+               GDBusMethodInvocation *invocation,
+               GVariant *privilege,
+               guint service_id,
                guint session_id, void *user_data)
        {
                vector<void *> params;
 
-               g_object_ref(object);
-               params.push_back((void *)object);
+               /* apply user space smack */
+               if (_is_authorized_request(privilege, "r") == true) {
+                       g_object_ref(object);
+                       params.push_back((void *)object);
 
-               g_object_ref(invocation);
-               params.push_back((void *)invocation);
+                       g_object_ref(invocation);
+                       params.push_back((void *)invocation);
 
-               params.push_back((void *)service_id);
-               params.push_back((void *)session_id);
-               params.push_back(user_data);
+                       params.push_back((void *)service_id);
+                       params.push_back((void *)session_id);
+                       params.push_back(user_data);
+
+                       GDBusDispatcher::push(_process_get_atr, params);
+               } else {
+                       ByteArray resp;
 
-               GDBusDispatcher::getInstance().push(_process_get_atr,
-                       params);
+                       _ERR("access denied");
+
+                       /* response to client */
+                       smartcard_service_session_complete_get_atr(
+                               object,
+                               invocation,
+                               SCARD_ERROR_SECURITY_NOT_ALLOWED,
+                               GDBusHelper::convertByteArrayToVariant(resp));
+               }
 
                return true;
        }
@@ -804,35 +951,37 @@ namespace smartcard_service_api
                guint session_id, guint type, GVariant *aid, void *user_data)
        {
                int result = SCARD_ERROR_UNKNOWN;
+               ByteArray resp;
                GVariant *response = NULL;
                unsigned int channelID = IntegerHandle::INVALID_HANDLE;
+               const char *name;
 
                _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
 
                ServerResource &resource = ServerResource::getInstance();
 
-               const char *name = g_dbus_method_invocation_get_sender(invocation);
+               name = g_dbus_method_invocation_get_sender(invocation);
 
                try
                {
                        ByteArray tempAid;
 
-                       GDBusHelper::convertVariantToByteArray(aid, tempAid);
+                       GDBusHelper::convertVariantToByteArray(aid,
+                               tempAid);
 
-                       channelID = resource.createChannel(name, service_id, session_id, type, tempAid);
-                       if (channelID != IntegerHandle::INVALID_HANDLE)
-                       {
+                       channelID = resource.createChannel(name,
+                               service_id, session_id, type, tempAid);
+                       if (channelID != IntegerHandle::INVALID_HANDLE) {
                                ServerChannel *temp;
 
-                               temp = (ServerChannel *)resource.getChannel(name, service_id, channelID);
-                               if (temp != NULL)
-                               {
+                               temp = (ServerChannel *)resource.getChannel(
+                                       name, service_id, channelID);
+                               if (temp != NULL) {
+                                       resp = temp->getSelectResponse();
+
                                        result = SCARD_ERROR_OK;
-                                       response = GDBusHelper::convertByteArrayToVariant(temp->getSelectResponse());
                                }
-                       }
-                       else
-                       {
+                       } else {
                                _ERR("channel is null.");
 
                                /* set error value */
@@ -844,9 +993,8 @@ namespace smartcard_service_api
                        result = e.getErrorCode();
                }
 
-               if (response == NULL) {
-                       response = GDBusHelper::convertByteArrayToVariant(ByteArray::EMPTY);
-               }
+               response = GDBusHelper::convertByteArrayToVariant(resp);
+
                /* response to client */
                smartcard_service_session_complete_open_channel(object,
                        invocation, result, channelID, response);
@@ -880,30 +1028,49 @@ namespace smartcard_service_api
 
                __process_open_channel(object, invocation, service_id,
                        session_id, type, aid, user_data);
+
+               g_object_unref(object);
+               g_object_unref(invocation);
+               g_object_unref(aid);
        }
 
        static gboolean _handle_open_channel(SmartcardServiceSession *object,
-               GDBusMethodInvocation *invocation, guint service_id,
+               GDBusMethodInvocation *invocation,
+               GVariant *privilege,
+               guint service_id,
                guint session_id, guint type, GVariant *aid, void *user_data)
        {
                vector<void *> params;
 
-               g_object_ref(object);
-               params.push_back((void *)object);
+               /* apply user space smack */
+               if (_is_authorized_request(privilege, "rw") == true) {
+                       g_object_ref(object);
+                       params.push_back((void *)object);
+
+                       g_object_ref(invocation);
+                       params.push_back((void *)invocation);
 
-               g_object_ref(invocation);
-               params.push_back((void *)invocation);
+                       params.push_back((void *)service_id);
+                       params.push_back((void *)session_id);
+                       params.push_back((void *)type);
 
-               params.push_back((void *)service_id);
-               params.push_back((void *)session_id);
-               params.push_back((void *)type);
+                       g_object_ref(aid);
+                       params.push_back((void *)aid);
+                       params.push_back(user_data);
+
+                       GDBusDispatcher::push(_process_open_channel, params);
+               } else {
+                       ByteArray resp;
 
-               g_object_ref(aid);
-               params.push_back((void *)aid);
-               params.push_back(user_data);
+                       _ERR("access denied");
 
-               GDBusDispatcher::getInstance().push(_process_open_channel,
-                       params);
+                       /* response to client */
+                       smartcard_service_session_complete_open_channel(object,
+                               invocation,
+                               SCARD_ERROR_SECURITY_NOT_ALLOWED,
+                               IntegerHandle::INVALID_HANDLE,
+                               GDBusHelper::convertByteArrayToVariant(resp));
+               }
 
                return true;
        }
@@ -964,19 +1131,17 @@ namespace smartcard_service_api
                guint channel_id, void *user_data)
        {
                int result;
+               const char *name;
 
                _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
 
                ServerResource &resource = ServerResource::getInstance();
 
-               const char *name = g_dbus_method_invocation_get_sender(invocation);
+               name = g_dbus_method_invocation_get_sender(invocation);
 
-               result = SCARD_ERROR_OK;
+               resource.removeChannel(name, service_id, channel_id);
 
-               if (resource.getChannel(name, service_id, channel_id) != NULL)
-               {
-                       resource.removeChannel(name, service_id, channel_id);
-               }
+               result = SCARD_ERROR_OK;
 
                /* response to client */
                smartcard_service_channel_complete_close_channel(object,
@@ -993,7 +1158,7 @@ namespace smartcard_service_api
                guint channel_id;
                void *user_data;
 
-               if (params.size() != 7) {
+               if (params.size() != 5) {
                        _ERR("invalid parameter");
 
                        return;
@@ -1007,71 +1172,85 @@ namespace smartcard_service_api
 
                __process_close_channel(object, invocation, service_id,
                        channel_id, user_data);
+
+               g_object_unref(object);
+               g_object_unref(invocation);
        }
 
        static gboolean _handle_close_channel(SmartcardServiceChannel *object,
-               GDBusMethodInvocation *invocation, guint service_id,
-               guint channel_id, void *user_data)
+               GDBusMethodInvocation *invocation,
+               GVariant *privilege,
+               guint service_id, guint channel_id, void *user_data)
        {
                vector<void *> params;
 
-               g_object_ref(object);
-               params.push_back((void *)object);
+               /* apply user space smack */
+               if (_is_authorized_request(privilege, "r") == true) {
+                       g_object_ref(object);
+                       params.push_back((void *)object);
 
-               g_object_ref(invocation);
-               params.push_back((void *)invocation);
+                       g_object_ref(invocation);
+                       params.push_back((void *)invocation);
 
-               params.push_back((void *)service_id);
-               params.push_back((void *)channel_id);
-               params.push_back(user_data);
+                       params.push_back((void *)service_id);
+                       params.push_back((void *)channel_id);
+                       params.push_back(user_data);
 
-               GDBusDispatcher::getInstance().push(_process_close_channel,
-                       params);
+                       GDBusDispatcher::push(_process_close_channel, params);
+               } else {
+                       _ERR("access denied");
+
+                       /* response to client */
+                       smartcard_service_channel_complete_close_channel(
+                               object,
+                               invocation,
+                               SCARD_ERROR_SECURITY_NOT_ALLOWED);
+               }
 
                return true;
        }
 
        static gboolean __process_transmit(SmartcardServiceChannel *object,
-               GDBusMethodInvocation *invocation, guint service_id,
-               guint channel_id, GVariant *command, void *user_data)
+               GDBusMethodInvocation *invocation,
+               guint service_id,
+               guint channel_id,
+               GVariant *command,
+               void *user_data)
        {
                int result;
                Channel *channel = NULL;
+               ByteArray resp;
                GVariant *response = NULL;
+               const char *name;
 
                _INFO("[MSG_REQUEST_TRANSMIT]");
 
                ServerResource &resource = ServerResource::getInstance();
 
-               const char *name = g_dbus_method_invocation_get_sender(invocation);
+               name = g_dbus_method_invocation_get_sender(invocation);
 
-               if ((channel = resource.getChannel(name, service_id, channel_id)) != NULL)
-               {
+               channel = resource.getChannel(name, service_id, channel_id);
+               if (channel != NULL) {
                        int rv;
-                       ByteArray cmd, resp;
+                       ByteArray cmd;
 
                        GDBusHelper::convertVariantToByteArray(command, cmd);
 
-                       if ((rv = channel->transmitSync(cmd, resp)) == 0)
-                       {
-                               response = GDBusHelper::convertByteArrayToVariant(resp);
+                       rv = channel->transmitSync(cmd, resp);
+                       if (rv == 0) {
                                result = SCARD_ERROR_OK;
-                       }
-                       else
-                       {
+                       } else {
                                _ERR("transmit failed [%d]", rv);
+
                                result = rv;
                        }
-               }
-               else
-               {
+               } else {
                        _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
+
                        result = SCARD_ERROR_UNAVAILABLE;
                }
 
-               if (response == NULL) {
-                       response = GDBusHelper::convertByteArrayToVariant(ByteArray::EMPTY);
-               }
+               response = GDBusHelper::convertByteArrayToVariant(resp);
 
                /* response to client */
                smartcard_service_channel_complete_transmit(object, invocation,
@@ -1089,7 +1268,7 @@ namespace smartcard_service_api
                GVariant *command;
                void *user_data;
 
-               if (params.size() != 7) {
+               if (params.size() != 6) {
                        _ERR("invalid parameter");
 
                        return;
@@ -1104,30 +1283,51 @@ namespace smartcard_service_api
 
                __process_transmit(object, invocation, service_id,
                        channel_id, command, user_data);
+
+               g_object_unref(object);
+               g_object_unref(invocation);
+               g_object_unref(command);
        }
 
        static gboolean _handle_transmit(SmartcardServiceChannel *object,
-               GDBusMethodInvocation *invocation, guint service_id,
-               guint channel_id, GVariant *command, void *user_data)
+               GDBusMethodInvocation *invocation,
+               GVariant *privilege,
+               guint service_id,
+               guint channel_id,
+               GVariant *command,
+               void *user_data)
        {
                vector<void *> params;
 
-               g_object_ref(object);
-               params.push_back((void *)object);
+               /* apply user space smack */
+               if (_is_authorized_request(privilege, "r") == true) {
+                       /* enqueue message */
+                       g_object_ref(object);
+                       params.push_back((void *)object);
 
-               g_object_ref(invocation);
-               params.push_back((void *)invocation);
+                       g_object_ref(invocation);
+                       params.push_back((void *)invocation);
 
-               params.push_back((void *)service_id);
-               params.push_back((void *)channel_id);
+                       params.push_back((void *)service_id);
+                       params.push_back((void *)channel_id);
 
-               g_object_ref(command);
-               params.push_back((void *)command);
+                       g_object_ref(command);
+                       params.push_back((void *)command);
 
-               params.push_back(user_data);
+                       params.push_back(user_data);
 
-               GDBusDispatcher::getInstance().push(_process_transmit,
-                       params);
+                       GDBusDispatcher::push(_process_transmit, params);
+               } else {
+                       ByteArray resp;
+
+                       _ERR("access denied");
+
+                       /* response to client */
+                       smartcard_service_channel_complete_transmit(object,
+                               invocation,
+                               SCARD_ERROR_SECURITY_NOT_ALLOWED,
+                               GDBusHelper::convertByteArrayToVariant(resp));
+               }
 
                return true;
        }
index ae14a4e..172e496 100644 (file)
@@ -221,6 +221,11 @@ namespace smartcard_service_api
                if ((instance = getClient(name)) != NULL)
                {
                        instance->removeService(handle);
+                       if (instance->getServiceCounts() == 0) {
+
+                               /* remove client instance */
+                               removeClient(name);
+                       }
                }
                else
                {
@@ -235,6 +240,9 @@ namespace smartcard_service_api
                if ((instance = getClient(name)) != NULL)
                {
                        instance->removeServices();
+
+                       /* remove client instance */
+                       removeClient(name);
                }
                else
                {
index c8ddc45..7c22d4e 100644 (file)
@@ -84,6 +84,7 @@ namespace smartcard_service_api
                ServiceInstance *getService(unsigned int handle);
                void removeService(unsigned int handle);
                void removeServices();
+               inline size_t getServiceCounts() const { return mapServices.size(); }
 #ifndef USE_GDBUS
                bool sendMessageToAllServices(int socket, const Message &msg);
 #endif
index 9b4527c..1af3aff 100644 (file)
@@ -40,7 +40,7 @@ namespace smartcard_service_api
                static GDBusDispatcher &getInstance();
 
                /* push to queue */
-               void push(dispatcher_cb_t cb, const vector<void *> &params);
+               static void push(dispatcher_cb_t cb, const vector<void *> &params);
 
        private :
                std::queue<pair<dispatcher_cb_t, vector<void *> > > q;
@@ -48,6 +48,7 @@ namespace smartcard_service_api
                GDBusDispatcher();
                ~GDBusDispatcher();
 
+               void _push(dispatcher_cb_t cb, const vector<void *> &params);
                static gboolean dispatch(gpointer user_data);
        };
 
@@ -82,10 +83,6 @@ namespace smartcard_service_api
                ServerGDBus();
                ~ServerGDBus();
 
-               static void name_owner_changed(GDBusProxy *proxy,
-                       const gchar *name, const gchar *old_owner,
-                       const gchar *new_owner, void *user_data);
-
                bool initSEService();
                void deinitSEService();