2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <sys/socket.h>
24 #ifdef USER_SPACE_SMACK
25 #include "security-server.h"
28 #include "smartcard-types.h"
30 #include "ByteArray.h"
31 #include "ServerResource.h"
32 #include "GDBusHelper.h"
33 #include "ServerGDBus.h"
37 namespace smartcard_service_api
39 GDBusDispatcher::GDBusDispatcher() : Synchronous()
43 GDBusDispatcher::~GDBusDispatcher()
47 GDBusDispatcher &GDBusDispatcher::getInstance()
49 static GDBusDispatcher dispatcher;
54 void GDBusDispatcher::_push(dispatcher_cb_t cb,
55 const vector<void *> ¶ms)
59 q.push(make_pair(cb, params));
60 _INFO("request pushed, count [%d]", q.size());
64 _INFO("start dispatcher");
65 g_idle_add(&GDBusDispatcher::dispatch, this);
71 void GDBusDispatcher::push(dispatcher_cb_t cb,
72 const vector<void *> ¶ms)
74 GDBusDispatcher::getInstance()._push(cb, params);
77 gboolean GDBusDispatcher::dispatch(gpointer user_data)
79 GDBusDispatcher *dispatcher = (GDBusDispatcher *)user_data;
80 gboolean result = false;
84 dispatcher->syncLock();
86 pair<dispatcher_cb_t, vector<void *> > &job =
87 dispatcher->q.front();
89 dispatcher->syncUnlock();
91 job.first(job.second);
93 dispatcher->syncLock();
96 if (dispatcher->q.size() > 0) {
97 _INFO("remaining messages : %d", dispatcher->q.size());
101 _INFO("dispatch finished");
104 dispatcher->syncUnlock();
111 ServerGDBus::ServerGDBus() : dbus_proxy(NULL), connection(NULL),
112 seService(NULL), reader(NULL), session(NULL), channel(NULL)
116 ServerGDBus::~ServerGDBus()
121 ServerGDBus &ServerGDBus::getInstance()
123 static ServerGDBus serverGDBus;
128 static void name_owner_changed(GDBusProxy *proxy,
129 const gchar *name, const gchar *old_owner,
130 const gchar *new_owner, void *user_data)
132 if (name == NULL || old_owner == NULL || new_owner == NULL) {
133 _ERR("invalid parameter");
137 if (strlen(new_owner) == 0) {
138 ClientInstance *client;
140 ServerResource &resource = ServerResource::getInstance();
142 client = resource.getClient(old_owner);
143 if (client != NULL) {
144 _INFO("terminated client, pid [%d]", client->getPID());
145 resource.removeClient(old_owner);
152 static void _on_name_owner_changed(GDBusConnection *connection,
153 const gchar *sender_name, const gchar *object_path,
154 const gchar *interface_name, const gchar *signal_name,
155 GVariant *parameters, gpointer user_data)
161 g_variant_get(parameters,
167 name_owner_changed((GDBusProxy *)connection,
168 name, old_owner, new_owner, user_data);
171 bool ServerGDBus::_init()
173 GError *error = NULL;
175 /* init default context */
176 dbus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
177 G_DBUS_PROXY_FLAGS_NONE,
178 NULL, /* GDBusInterfaceInfo */
179 "org.freedesktop.DBus",
180 "/org/freedesktop/DBus",
181 "org.freedesktop.DBus",
182 NULL, /* GCancellable */
184 if (dbus_proxy == NULL)
186 _ERR("Can not create proxy : %s", error->message);
192 /* subscribe signal */
193 g_dbus_connection_signal_subscribe(connection,
194 "org.freedesktop.DBus", /* bus name */
195 "org.freedesktop.DBus", /* interface */
196 "NameOwnerChanged", /* member */
197 "/org/freedesktop/DBus", /* path */
199 G_DBUS_SIGNAL_FLAGS_NONE,
200 _on_name_owner_changed,
206 void ServerGDBus::_deinit()
208 if (dbus_proxy != NULL) {
209 g_object_unref(dbus_proxy);
214 bool ServerGDBus::init()
216 GError *error = NULL;
218 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
219 if (connection != NULL) {
221 _ERR("Can not get connection %s", error->message);
237 void ServerGDBus::deinit()
246 if (connection != NULL) {
247 g_object_unref(connection);
252 static gboolean _call_get_connection_unix_process_id_sync(
253 GDBusProxy *proxy, const gchar *arg_name, guint *out_pid,
254 GCancellable *cancellable, GError **error) {
257 _ret = g_dbus_proxy_call_sync(proxy,
258 "GetConnectionUnixProcessID",
259 g_variant_new("(s)", arg_name),
260 G_DBUS_CALL_FLAGS_NONE,
261 -1, cancellable, error);
263 g_variant_get(_ret, "(u)", out_pid);
264 g_variant_unref(_ret);
270 pid_t ServerGDBus::getPID(const char *name)
273 GError *error = NULL;
275 if (_call_get_connection_unix_process_id_sync(
276 (GDBusProxy *)dbus_proxy, name,
277 &pid, NULL, &error) == true) {
279 _ERR("_g_freedesktop_dbus_call_get_connection_unix_process_id_sync failed : %s", error->message);
286 static bool _is_authorized_request(GDBusMethodInvocation *invocation,
290 #ifdef USER_SPACE_SMACK
293 ClientInstance *instance;
295 name = g_dbus_method_invocation_get_sender(invocation);
297 instance = ServerResource::getInstance().getClient(name);
298 if (instance != NULL) {
299 pid = instance->getPID();
301 pid = ServerGDBus::getInstance().getPID(name);
304 result = (security_server_check_privilege_by_pid(
307 rights) == SECURITY_SERVER_API_SUCCESS);
316 static GVariant *_reader_to_variant(
317 vector<pair<unsigned int, string> > &readers)
319 GVariantBuilder builder;
322 g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
324 for (i = 0; i < readers.size(); i++) {
325 g_variant_builder_add(&builder, "(us)",
326 readers[i].first, readers[i].second.c_str());
329 return g_variant_builder_end(&builder);
332 static gboolean __process_se_service(SmartcardServiceSeService *object,
333 GDBusMethodInvocation *invocation,
336 gint result = SCARD_ERROR_OK;
337 GVariant *readers = NULL;
338 vector<pair<unsigned int, string> > list;
339 unsigned int handle = IntegerHandle::INVALID_HANDLE;
343 _INFO("[MSG_REQUEST_READERS]");
345 ServerResource &resource = ServerResource::getInstance();
347 name = g_dbus_method_invocation_get_sender(invocation);
349 /* load secure elements */
350 resource.loadSecureElements();
352 pid = ServerGDBus::getInstance().getPID(name);
354 _DBG("service requested, pid [%d]", pid);
357 ClientInstance *instance;
359 instance = resource.getClient(name);
360 if (instance == NULL) {
361 _INFO("create client instance, pid [%d]", pid);
363 resource.createClient(name, pid);
365 instance = resource.getClient(name);
366 if (instance != NULL) {
367 /* generate certification hashes */
368 instance->generateCertificationHashes();
370 _ERR("createClient failed");
374 if (instance != NULL) {
375 ServiceInstance *service;
378 service = resource.createService(name);
379 if (service != NULL) {
381 handle = service->getHandle();
382 resource.getReaders(list);
384 if (list.size() == 0) {
385 _INFO("no secure elements");
388 _ERR("createService failed");
390 result = SCARD_ERROR_OUT_OF_MEMORY;
393 _ERR("client doesn't exist, pid [%d]", pid);
395 result = SCARD_ERROR_OUT_OF_MEMORY;
398 _ERR("invalid pid, [%d]", pid);
400 result = SCARD_ERROR_IPC_FAILED;
403 readers = _reader_to_variant(list);
405 /* response to client */
406 smartcard_service_se_service_complete_se_service(object,
407 invocation, result, handle, readers);
412 static void _process_se_service(vector<void *> ¶ms)
414 SmartcardServiceSeService *object;
415 GDBusMethodInvocation *invocation;
418 if (params.size() != 3) {
419 _ERR("invalid parameter");
424 object = (SmartcardServiceSeService *)params[0];
425 invocation = (GDBusMethodInvocation *)params[1];
426 user_data = params[2];
428 __process_se_service(object, invocation, user_data);
430 g_object_unref(object);
431 g_object_unref(invocation);
434 static gboolean _handle_se_service(SmartcardServiceSeService *object,
435 GDBusMethodInvocation *invocation,
438 vector<void *> params;
440 /* apply user space smack */
441 if (_is_authorized_request(invocation, "r") == true) {
442 g_object_ref(object);
443 params.push_back((void *)object);
445 g_object_ref(invocation);
446 params.push_back((void *)invocation);
448 params.push_back((void *)user_data);
450 GDBusDispatcher::push(_process_se_service, params);
452 vector<pair<unsigned int, string> > list;
454 _ERR("access denied");
456 /* response to client */
457 smartcard_service_se_service_complete_se_service(object,
459 SCARD_ERROR_SECURITY_NOT_ALLOWED,
460 IntegerHandle::INVALID_HANDLE,
461 _reader_to_variant(list));
467 static gboolean __process_shutdown(SmartcardServiceSeService *object,
468 GDBusMethodInvocation *invocation,
469 intptr_t handle, void *user_data)
473 _INFO("[MSG_REQUEST_SHUTDOWN]");
475 ServerResource &resource = ServerResource::getInstance();
477 name = g_dbus_method_invocation_get_sender(invocation);
479 resource.removeService(name, handle);
481 /* response to client */
482 smartcard_service_se_service_complete_shutdown(object,
483 invocation, SCARD_ERROR_OK);
491 static void _process_shutdown(vector<void *> ¶ms)
493 SmartcardServiceSeService *object;
494 GDBusMethodInvocation *invocation;
498 if (params.size() != 4) {
499 _ERR("invalid parameter");
504 object = (SmartcardServiceSeService *)params[0];
505 invocation = (GDBusMethodInvocation *)params[1];
506 handle = (intptr_t)params[2];
507 user_data = params[3];
509 __process_shutdown(object, invocation, handle, user_data);
511 g_object_unref(object);
512 g_object_unref(invocation);
515 static gboolean _handle_shutdown(SmartcardServiceSeService *object,
516 GDBusMethodInvocation *invocation,
520 vector<void *> params;
522 /* apply user space smack */
523 if (_is_authorized_request(invocation, "r") == true) {
524 g_object_ref(object);
525 params.push_back((void *)object);
527 g_object_ref(invocation);
528 params.push_back((void *)invocation);
530 params.push_back((void *)handle);
531 params.push_back(user_data);
533 GDBusDispatcher::push(_process_shutdown, params);
535 _ERR("access denied");
537 /* response to client */
538 smartcard_service_se_service_complete_shutdown(object,
539 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
545 bool ServerGDBus::initSEService()
547 GError *error = NULL;
549 seService = smartcard_service_se_service_skeleton_new();
551 g_signal_connect(seService,
553 G_CALLBACK(_handle_se_service),
556 g_signal_connect(seService,
558 G_CALLBACK(_handle_shutdown),
561 if (g_dbus_interface_skeleton_export(
562 G_DBUS_INTERFACE_SKELETON(seService),
564 "/org/tizen/SmartcardService/SeService",
567 _ERR("Can not skeleton_export %s", error->message);
570 g_object_unref(seService);
579 void ServerGDBus::deinitSEService()
581 if (seService != NULL) {
582 g_object_unref(seService);
587 void ServerGDBus::emitReaderInserted(unsigned int reader_id,
588 const char *reader_name)
590 smartcard_service_se_service_emit_reader_inserted(
591 SMARTCARD_SERVICE_SE_SERVICE(seService),
592 reader_id, reader_name);
595 void ServerGDBus::emitReaderRemoved(unsigned int reader_id,
596 const char *reader_name)
598 smartcard_service_se_service_emit_reader_removed(
599 SMARTCARD_SERVICE_SE_SERVICE(seService),
600 reader_id, reader_name);
607 static gboolean __process_open_session(SmartcardServiceReader *object,
608 GDBusMethodInvocation *invocation, intptr_t service_id,
609 intptr_t reader_id, void *user_data)
611 unsigned int handle = IntegerHandle::INVALID_HANDLE;
615 _INFO("[MSG_REQUEST_OPEN_SESSION]");
617 ServerResource &resource = ServerResource::getInstance();
619 name = g_dbus_method_invocation_get_sender(invocation);
621 if (resource.isValidReaderHandle(reader_id)) {
622 vector<ByteArray> temp;
624 handle = resource.createSession(name,
629 if (handle != IntegerHandle::INVALID_HANDLE) {
630 result = SCARD_ERROR_OK;
632 _ERR("createSession failed [%d]", handle);
634 result = SCARD_ERROR_OUT_OF_MEMORY;
637 _ERR("request invalid reader handle [%d]", reader_id);
639 result = SCARD_ERROR_ILLEGAL_PARAM;
642 /* response to client */
643 smartcard_service_reader_complete_open_session(object,
644 invocation, result, handle);
649 static void _process_open_session(vector<void *> ¶ms)
651 SmartcardServiceReader *object;
652 GDBusMethodInvocation *invocation;
657 if (params.size() != 5) {
658 _ERR("invalid parameter");
663 object = (SmartcardServiceReader *)params[0];
664 invocation = (GDBusMethodInvocation *)params[1];
665 service_id = (intptr_t)params[2];
666 reader_id = (intptr_t)params[3];
667 user_data = params[4];
669 __process_open_session(object, invocation, service_id,
670 reader_id, user_data);
672 g_object_unref(object);
673 g_object_unref(invocation);
676 static gboolean _handle_open_session(SmartcardServiceReader *object,
677 GDBusMethodInvocation *invocation,
679 intptr_t reader_id, void *user_data)
681 vector<void *> params;
683 /* apply user space smack */
684 if (_is_authorized_request(invocation, "r") == true) {
685 g_object_ref(object);
686 params.push_back((void *)object);
688 g_object_ref(invocation);
689 params.push_back((void *)invocation);
691 params.push_back((void *)service_id);
692 params.push_back((void *)reader_id);
693 params.push_back(user_data);
695 GDBusDispatcher::push(_process_open_session, params);
697 _ERR("access denied");
699 /* response to client */
700 smartcard_service_reader_complete_open_session(object,
702 SCARD_ERROR_SECURITY_NOT_ALLOWED,
703 IntegerHandle::INVALID_HANDLE);
709 bool ServerGDBus::initReader()
711 GError *error = NULL;
713 reader = smartcard_service_reader_skeleton_new();
715 g_signal_connect(reader,
716 "handle-open-session",
717 G_CALLBACK(_handle_open_session),
720 if (g_dbus_interface_skeleton_export(
721 G_DBUS_INTERFACE_SKELETON(reader),
723 "/org/tizen/SmartcardService/Reader",
726 _ERR("Can not skeleton_export %s", error->message);
729 g_object_unref(reader);
738 void ServerGDBus::deinitReader()
740 if (reader != NULL) {
741 g_object_unref(reader);
750 static gboolean __process_close_session(SmartcardServiceSession *object,
751 GDBusMethodInvocation *invocation, intptr_t service_id,
752 intptr_t session_id, void *user_data)
756 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
758 ServerResource &resource = ServerResource::getInstance();
760 name = g_dbus_method_invocation_get_sender(invocation);
762 if (resource.isValidSessionHandle(name, service_id,
764 resource.removeSession(name, service_id,
767 _ERR("invalid parameters");
770 /* response to client */
771 smartcard_service_session_complete_close_session(object,
772 invocation, SCARD_ERROR_OK);
777 static void _process_close_session(vector<void *> ¶ms)
779 SmartcardServiceSession *object;
780 GDBusMethodInvocation *invocation;
785 if (params.size() != 5) {
786 _ERR("invalid parameter");
791 object = (SmartcardServiceSession *)params[0];
792 invocation = (GDBusMethodInvocation *)params[1];
793 service_id = (intptr_t)params[2];
794 session_id = (intptr_t)params[3];
795 user_data = params[4];
797 __process_close_session(object, invocation, service_id,
798 session_id, user_data);
800 g_object_unref(object);
801 g_object_unref(invocation);
804 static gboolean _handle_close_session(SmartcardServiceSession *object,
805 GDBusMethodInvocation *invocation,
807 intptr_t session_id, void *user_data)
809 vector<void *> params;
811 /* apply user space smack */
812 if (_is_authorized_request(invocation, "r") == true) {
813 g_object_ref(object);
814 params.push_back((void *)object);
816 g_object_ref(invocation);
817 params.push_back((void *)invocation);
819 params.push_back((void *)service_id);
820 params.push_back((void *)session_id);
821 params.push_back(user_data);
823 GDBusDispatcher::push(_process_close_session, params);
825 _ERR("access denied");
827 /* response to client */
828 smartcard_service_session_complete_close_session(object,
829 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
835 static gboolean __process_get_atr(SmartcardServiceSession *object,
836 GDBusMethodInvocation *invocation, intptr_t service_id,
837 intptr_t session_id, void *user_data)
841 GVariant *atr = NULL;
843 ServiceInstance *client = NULL;
845 _INFO("[MSG_REQUEST_GET_ATR]");
847 ServerResource &resource = ServerResource::getInstance();
849 name = g_dbus_method_invocation_get_sender(invocation);
851 client = resource.getService(name, service_id);
852 if (client != NULL) {
855 terminal = client->getTerminal(session_id);
856 if (terminal != NULL) {
859 if ((rv = terminal->getATRSync(resp)) == 0) {
860 result = SCARD_ERROR_OK;
862 _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
867 _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
869 result = SCARD_ERROR_UNAVAILABLE;
872 _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
874 result = SCARD_ERROR_UNAVAILABLE;
877 atr = GDBusHelper::convertByteArrayToVariant(resp);
879 /* response to client */
880 smartcard_service_session_complete_get_atr(object, invocation,
886 static void _process_get_atr(vector<void *> ¶ms)
888 SmartcardServiceSession *object;
889 GDBusMethodInvocation *invocation;
894 if (params.size() != 5) {
895 _ERR("invalid parameter");
900 object = (SmartcardServiceSession *)params[0];
901 invocation = (GDBusMethodInvocation *)params[1];
902 service_id = (intptr_t)params[2];
903 session_id = (intptr_t)params[3];
904 user_data = params[4];
906 __process_get_atr(object, invocation, service_id,
907 session_id, user_data);
909 g_object_unref(object);
910 g_object_unref(invocation);
913 static gboolean _handle_get_atr(SmartcardServiceSession *object,
914 GDBusMethodInvocation *invocation,
916 intptr_t session_id, void *user_data)
918 vector<void *> params;
920 /* apply user space smack */
921 if (_is_authorized_request(invocation, "r") == true) {
922 g_object_ref(object);
923 params.push_back((void *)object);
925 g_object_ref(invocation);
926 params.push_back((void *)invocation);
928 params.push_back((void *)service_id);
929 params.push_back((void *)session_id);
930 params.push_back(user_data);
932 GDBusDispatcher::push(_process_get_atr, params);
936 _ERR("access denied");
938 /* response to client */
939 smartcard_service_session_complete_get_atr(
942 SCARD_ERROR_SECURITY_NOT_ALLOWED,
943 GDBusHelper::convertByteArrayToVariant(resp));
949 static gboolean __process_open_channel(SmartcardServiceSession *object,
950 GDBusMethodInvocation *invocation, intptr_t service_id,
951 intptr_t session_id, intptr_t type, GVariant *aid, void *user_data)
953 int result = SCARD_ERROR_UNKNOWN;
955 GVariant *response = NULL;
956 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
959 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
961 ServerResource &resource = ServerResource::getInstance();
963 name = g_dbus_method_invocation_get_sender(invocation);
969 GDBusHelper::convertVariantToByteArray(aid,
972 channelID = resource.createChannel(name,
973 service_id, session_id, type, tempAid);
974 if (channelID != IntegerHandle::INVALID_HANDLE) {
977 temp = (ServerChannel *)resource.getChannel(
978 name, service_id, channelID);
980 resp = temp->getSelectResponse();
982 result = SCARD_ERROR_OK;
985 _ERR("channel is null.");
987 /* set error value */
988 result = SCARD_ERROR_UNAVAILABLE;
991 catch (ExceptionBase &e)
993 result = e.getErrorCode();
996 response = GDBusHelper::convertByteArrayToVariant(resp);
998 /* response to client */
999 smartcard_service_session_complete_open_channel(object,
1000 invocation, result, channelID, response);
1005 static void _process_open_channel(vector<void *> ¶ms)
1007 SmartcardServiceSession *object;
1008 GDBusMethodInvocation *invocation;
1009 intptr_t service_id;
1010 intptr_t session_id;
1015 if (params.size() != 7) {
1016 _ERR("invalid parameter");
1021 object = (SmartcardServiceSession *)params[0];
1022 invocation = (GDBusMethodInvocation *)params[1];
1023 service_id = (intptr_t)params[2];
1024 session_id = (intptr_t)params[3];
1025 type = (intptr_t)params[4];
1026 aid = (GVariant *)params[5];
1027 user_data = params[6];
1029 __process_open_channel(object, invocation, service_id,
1030 session_id, type, aid, user_data);
1032 g_object_unref(object);
1033 g_object_unref(invocation);
1034 g_object_unref(aid);
1037 static gboolean _handle_open_channel(SmartcardServiceSession *object,
1038 GDBusMethodInvocation *invocation,
1039 intptr_t service_id,
1040 intptr_t session_id, intptr_t type, GVariant *aid, void *user_data)
1042 vector<void *> params;
1044 /* apply user space smack */
1045 if (_is_authorized_request(invocation, "rw") == true) {
1046 g_object_ref(object);
1047 params.push_back((void *)object);
1049 g_object_ref(invocation);
1050 params.push_back((void *)invocation);
1052 params.push_back((void *)service_id);
1053 params.push_back((void *)session_id);
1054 params.push_back((void *)type);
1057 params.push_back((void *)aid);
1058 params.push_back(user_data);
1060 GDBusDispatcher::push(_process_open_channel, params);
1064 _ERR("access denied");
1066 /* response to client */
1067 smartcard_service_session_complete_open_channel(object,
1069 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1070 IntegerHandle::INVALID_HANDLE,
1071 GDBusHelper::convertByteArrayToVariant(resp));
1077 bool ServerGDBus::initSession()
1079 GError *error = NULL;
1081 session = smartcard_service_session_skeleton_new();
1083 g_signal_connect(session,
1084 "handle-close-session",
1085 G_CALLBACK(_handle_close_session),
1088 g_signal_connect(session,
1090 G_CALLBACK(_handle_get_atr),
1093 g_signal_connect(session,
1094 "handle-open-channel",
1095 G_CALLBACK(_handle_open_channel),
1098 if (g_dbus_interface_skeleton_export(
1099 G_DBUS_INTERFACE_SKELETON(session),
1101 "/org/tizen/SmartcardService/Session",
1104 _ERR("Can not skeleton_export %s", error->message);
1106 g_error_free(error);
1107 g_object_unref(session);
1116 void ServerGDBus::deinitSession()
1118 if (session != NULL) {
1119 g_object_unref(session);
1128 static gboolean __process_close_channel(SmartcardServiceChannel *object,
1129 GDBusMethodInvocation *invocation, intptr_t service_id,
1130 intptr_t channel_id, void *user_data)
1135 _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
1137 ServerResource &resource = ServerResource::getInstance();
1139 name = g_dbus_method_invocation_get_sender(invocation);
1141 resource.removeChannel(name, service_id, channel_id);
1143 result = SCARD_ERROR_OK;
1145 /* response to client */
1146 smartcard_service_channel_complete_close_channel(object,
1147 invocation, result);
1152 static void _process_close_channel(vector<void *> ¶ms)
1154 SmartcardServiceChannel *object;
1155 GDBusMethodInvocation *invocation;
1156 intptr_t service_id;
1157 intptr_t channel_id;
1160 if (params.size() != 5) {
1161 _ERR("invalid parameter");
1166 object = (SmartcardServiceChannel *)params[0];
1167 invocation = (GDBusMethodInvocation *)params[1];
1168 service_id = (intptr_t)params[2];
1169 channel_id = (intptr_t)params[3];
1170 user_data = params[4];
1172 __process_close_channel(object, invocation, service_id,
1173 channel_id, user_data);
1175 g_object_unref(object);
1176 g_object_unref(invocation);
1179 static gboolean _handle_close_channel(SmartcardServiceChannel *object,
1180 GDBusMethodInvocation *invocation,
1181 intptr_t service_id, intptr_t channel_id, void *user_data)
1183 vector<void *> params;
1185 /* apply user space smack */
1186 if (_is_authorized_request(invocation, "r") == true) {
1187 g_object_ref(object);
1188 params.push_back((void *)object);
1190 g_object_ref(invocation);
1191 params.push_back((void *)invocation);
1193 params.push_back((void *)service_id);
1194 params.push_back((void *)channel_id);
1195 params.push_back(user_data);
1197 GDBusDispatcher::push(_process_close_channel, params);
1199 _ERR("access denied");
1201 /* response to client */
1202 smartcard_service_channel_complete_close_channel(
1205 SCARD_ERROR_SECURITY_NOT_ALLOWED);
1211 static gboolean __process_transmit(SmartcardServiceChannel *object,
1212 GDBusMethodInvocation *invocation,
1213 intptr_t service_id,
1214 intptr_t channel_id,
1219 Channel *channel = NULL;
1221 GVariant *response = NULL;
1224 _INFO("[MSG_REQUEST_TRANSMIT]");
1226 ServerResource &resource = ServerResource::getInstance();
1228 name = g_dbus_method_invocation_get_sender(invocation);
1230 channel = resource.getChannel(name, service_id, channel_id);
1231 if (channel != NULL) {
1235 GDBusHelper::convertVariantToByteArray(command, cmd);
1237 rv = channel->transmitSync(cmd, resp);
1239 result = SCARD_ERROR_OK;
1241 _ERR("transmit failed [%d]", rv);
1246 _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
1248 result = SCARD_ERROR_UNAVAILABLE;
1251 response = GDBusHelper::convertByteArrayToVariant(resp);
1253 /* response to client */
1254 smartcard_service_channel_complete_transmit(object, invocation,
1260 static void _process_transmit(vector<void *> ¶ms)
1262 SmartcardServiceChannel *object;
1263 GDBusMethodInvocation *invocation;
1264 intptr_t service_id;
1265 intptr_t channel_id;
1269 if (params.size() != 6) {
1270 _ERR("invalid parameter");
1275 object = (SmartcardServiceChannel *)params[0];
1276 invocation = (GDBusMethodInvocation *)params[1];
1277 service_id = (intptr_t)params[2];
1278 channel_id = (intptr_t)params[3];
1279 command = (GVariant *)params[4];
1280 user_data = params[5];
1282 __process_transmit(object, invocation, service_id,
1283 channel_id, command, user_data);
1285 g_object_unref(object);
1286 g_object_unref(invocation);
1287 g_object_unref(command);
1290 static gboolean _handle_transmit(SmartcardServiceChannel *object,
1291 GDBusMethodInvocation *invocation,
1292 intptr_t service_id,
1293 intptr_t channel_id,
1297 vector<void *> params;
1299 /* apply user space smack */
1300 if (_is_authorized_request(invocation, "r") == true) {
1301 /* enqueue message */
1302 g_object_ref(object);
1303 params.push_back((void *)object);
1305 g_object_ref(invocation);
1306 params.push_back((void *)invocation);
1308 params.push_back((void *)service_id);
1309 params.push_back((void *)channel_id);
1311 g_object_ref(command);
1312 params.push_back((void *)command);
1314 params.push_back(user_data);
1316 GDBusDispatcher::push(_process_transmit, params);
1320 _ERR("access denied");
1322 /* response to client */
1323 smartcard_service_channel_complete_transmit(object,
1325 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1326 GDBusHelper::convertByteArrayToVariant(resp));
1332 bool ServerGDBus::initChannel()
1334 GError *error = NULL;
1336 channel = smartcard_service_channel_skeleton_new();
1338 g_signal_connect(channel,
1339 "handle-close-channel",
1340 G_CALLBACK(_handle_close_channel),
1343 g_signal_connect(channel,
1345 G_CALLBACK(_handle_transmit),
1348 if (g_dbus_interface_skeleton_export(
1349 G_DBUS_INTERFACE_SKELETON(channel),
1351 "/org/tizen/SmartcardService/Channel",
1354 _ERR("Can not skeleton_export %s", error->message);
1356 g_error_free(error);
1357 g_object_unref(channel);
1366 void ServerGDBus::deinitChannel()
1368 if (channel != NULL) {
1369 g_object_unref(channel);
1373 } /* namespace smartcard_service_api */