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.
17 /* standard library header */
23 #include <sys/socket.h>
26 #include "smartcard-types.h"
28 #include "ByteArray.h"
29 #include "ServerResource.h"
30 #include "GDBusHelper.h"
31 #include "ServerGDBus.h"
34 #include "cynara-client.h"
35 #include "cynara-creds-gdbus.h"
36 #include "cynara-session.h"
38 #define SMARTCARD_PRIVILEGE "http://tizen.org/privilege/secureelement"
44 extern "C" bool smartcard_service_init_access_control(void *connection);
45 extern "C" void smartcard_service_deinit_access_control();
48 namespace smartcard_service_api
50 GDBusDispatcher::GDBusDispatcher() : Synchronous()
54 GDBusDispatcher::~GDBusDispatcher()
58 GDBusDispatcher &GDBusDispatcher::getInstance()
60 static GDBusDispatcher dispatcher;
65 void GDBusDispatcher::_push(dispatcher_cb_t cb,
66 const vector<void *> ¶ms)
70 q.push(make_pair(cb, params));
71 _INFO("request pushed, count [%d]", q.size());
75 _INFO("start dispatcher");
76 g_idle_add(&GDBusDispatcher::dispatch, this);
82 void GDBusDispatcher::push(dispatcher_cb_t cb,
83 const vector<void *> ¶ms)
85 GDBusDispatcher::getInstance()._push(cb, params);
88 gboolean GDBusDispatcher::dispatch(gpointer user_data)
90 GDBusDispatcher *dispatcher = (GDBusDispatcher *)user_data;
91 gboolean result = false;
95 dispatcher->syncLock();
97 pair<dispatcher_cb_t, vector<void *> > &job =
98 dispatcher->q.front();
100 dispatcher->syncUnlock();
102 job.first(job.second);
104 dispatcher->syncLock();
107 if (dispatcher->q.size() > 0) {
108 _INFO("remaining messages : %d", dispatcher->q.size());
112 _INFO("dispatch finished");
115 dispatcher->syncUnlock();
122 ServerGDBus::ServerGDBus() : dbus_proxy(NULL), connection(NULL),
123 seService(NULL), reader(NULL), session(NULL), channel(NULL)
127 ServerGDBus::~ServerGDBus()
132 ServerGDBus &ServerGDBus::getInstance()
134 static ServerGDBus serverGDBus;
139 static void name_owner_changed(GDBusProxy *proxy,
140 const gchar *name, const gchar *old_owner,
141 const gchar *new_owner, void *user_data)
143 if (name == NULL || old_owner == NULL || new_owner == NULL) {
144 _ERR("invalid parameter");
148 if (strlen(new_owner) == 0) {
149 ClientInstance *client;
151 ServerResource &resource = ServerResource::getInstance();
153 client = resource.getClient(old_owner);
154 if (client != NULL) {
155 _INFO("terminated client, pid [%d]", client->getPID());
156 resource.removeClient(old_owner);
163 static void _on_name_owner_changed(GDBusConnection *connection,
164 const gchar *sender_name, const gchar *object_path,
165 const gchar *interface_name, const gchar *signal_name,
166 GVariant *parameters, gpointer user_data)
172 g_variant_get(parameters,
178 name_owner_changed((GDBusProxy *)connection,
179 name, old_owner, new_owner, user_data);
186 bool ServerGDBus::_init()
188 GError *error = NULL;
190 /* init default context */
191 dbus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
192 G_DBUS_PROXY_FLAGS_NONE,
193 NULL, /* GDBusInterfaceInfo */
194 "org.freedesktop.DBus",
195 "/org/freedesktop/DBus",
196 "org.freedesktop.DBus",
197 NULL, /* GCancellable */
199 if (dbus_proxy == NULL)
201 _ERR("Can not create proxy : %s", error->message);
207 /* subscribe signal */
208 g_dbus_connection_signal_subscribe(connection,
209 "org.freedesktop.DBus", /* bus name */
210 "org.freedesktop.DBus", /* interface */
211 "NameOwnerChanged", /* member */
212 "/org/freedesktop/DBus", /* path */
214 G_DBUS_SIGNAL_FLAGS_NONE,
215 _on_name_owner_changed,
221 void ServerGDBus::_deinit()
223 if (dbus_proxy != NULL) {
224 g_object_unref(dbus_proxy);
229 bool ServerGDBus::init()
231 GError *error = NULL;
233 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
234 if (connection != NULL) {
236 _ERR("Can not get connection %s", error->message);
249 smartcard_service_init_access_control(connection);
254 void ServerGDBus::deinit()
257 smartcard_service_deinit_access_control();
266 if (connection != NULL) {
267 g_object_unref(connection);
272 static gboolean _call_get_connection_unix_process_id_sync(
273 GDBusProxy *proxy, const gchar *arg_name, guint *out_pid,
274 GCancellable *cancellable, GError **error) {
277 _ret = g_dbus_proxy_call_sync(proxy,
278 "GetConnectionUnixProcessID",
279 g_variant_new("(s)", arg_name),
280 G_DBUS_CALL_FLAGS_NONE,
281 -1, cancellable, error);
283 g_variant_get(_ret, "(u)", out_pid);
284 g_variant_unref(_ret);
290 pid_t ServerGDBus::getPID(const char *name)
293 GError *error = NULL;
295 if (_call_get_connection_unix_process_id_sync(
296 (GDBusProxy *)dbus_proxy, name,
297 &pid, NULL, &error) == true) {
299 _ERR("_g_freedesktop_dbus_call_get_connection_unix_process_id_sync failed : %s", error->message);
307 static bool _get_credentials(GDBusMethodInvocation *invocation)
313 char *client_session;
314 cynara *p_cynara = NULL;
315 const char *sender_unique_name;
316 GDBusConnection *connection;
318 connection = g_dbus_method_invocation_get_connection(invocation);
319 sender_unique_name = g_dbus_method_invocation_get_sender(invocation);
321 pid = ServerGDBus::getInstance().getPID(sender_unique_name);
323 ret = cynara_initialize(&p_cynara, NULL);
324 if (ret != CYNARA_API_SUCCESS) {
325 _ERR("cynara_initialize() failed");
329 ret = cynara_creds_gdbus_get_user(connection, sender_unique_name, USER_METHOD_DEFAULT, &user);
330 if (ret != CYNARA_API_SUCCESS) {
331 _ERR("cynara_creds_gdbus_get_user() failed");
335 ret = cynara_creds_gdbus_get_client(connection, sender_unique_name, CLIENT_METHOD_DEFAULT, &client);
336 if (ret != CYNARA_API_SUCCESS) {
337 _ERR("cynara_creds_gdbus_get_client() failed");
342 _ERR("user :%s , client :%s ,unique_name : %s, pid() : %d", user, client, sender_unique_name, pid);
344 client_session = cynara_session_from_pid(pid);
346 if (!client_session) {
347 _ERR("cynara_session_from_pid() failed");
353 ret = cynara_check(p_cynara, client, client_session, user, SMARTCARD_PRIVILEGE);
354 if ( ret == CYNARA_API_ACCESS_ALLOWED ) {
355 _INFO("cynara PASS");
358 g_free(client_session);
363 cynara_finish(p_cynara);
367 return (ret == CYNARA_API_ACCESS_ALLOWED ) ? true : false;
371 static bool _is_authorized_request(GDBusMethodInvocation *invocation)
376 result = _get_credentials(invocation);
379 _ERR("api security check result : %d", result);
388 static GVariant *_reader_to_variant(
389 vector<pair<unsigned int, string> > &readers)
391 GVariantBuilder builder;
394 g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
396 for (i = 0; i < readers.size(); i++) {
397 g_variant_builder_add(&builder, "(us)",
398 readers[i].first, readers[i].second.c_str());
401 return g_variant_builder_end(&builder);
404 static gboolean __process_se_service(SmartcardServiceSeService *object,
405 GDBusMethodInvocation *invocation,
408 gint result = SCARD_ERROR_OK;
409 GVariant *readers = NULL;
410 vector<pair<unsigned int, string> > list;
411 unsigned int handle = IntegerHandle::INVALID_HANDLE;
415 _INFO("[MSG_REQUEST_READERS]");
417 ServerResource &resource = ServerResource::getInstance();
419 name = g_dbus_method_invocation_get_sender(invocation);
421 /* load secure elements */
422 resource.loadSecureElements();
424 pid = ServerGDBus::getInstance().getPID(name);
426 _DBG("service requested, pid [%d]", pid);
429 ClientInstance *instance;
431 instance = resource.getClient(name);
432 if (instance == NULL) {
433 _INFO("create client instance, pid [%d]", pid);
435 resource.createClient(name, pid);
437 instance = resource.getClient(name);
438 if (instance != NULL) {
439 /* generate certification hashes */
440 instance->generateCertificationHashes();
442 _ERR("createClient failed");
446 if (instance != NULL) {
447 ServiceInstance *service;
450 service = resource.createService(name);
451 if (service != NULL) {
452 handle = service->getHandle();
453 resource.getReaders(list);
455 if (list.size() == 0) {
456 _INFO("no secure elements");
459 _ERR("createService failed");
461 result = SCARD_ERROR_OUT_OF_MEMORY;
464 _ERR("client doesn't exist, pid [%d]", pid);
466 result = SCARD_ERROR_OUT_OF_MEMORY;
469 _ERR("invalid pid, [%d]", pid);
471 result = SCARD_ERROR_IPC_FAILED;
474 readers = _reader_to_variant(list);
476 /* response to client */
477 smartcard_service_se_service_complete_se_service(object,
478 invocation, result, handle, readers);
483 static void _process_se_service(vector<void *> ¶ms)
485 SmartcardServiceSeService *object;
486 GDBusMethodInvocation *invocation;
489 if (params.size() != 3) {
490 _ERR("invalid parameter");
495 object = (SmartcardServiceSeService *)params[0];
496 invocation = (GDBusMethodInvocation *)params[1];
497 user_data = params[2];
499 __process_se_service(object, invocation, user_data);
501 g_object_unref(object);
502 g_object_unref(invocation);
505 static gboolean _handle_se_service(SmartcardServiceSeService *object,
506 GDBusMethodInvocation *invocation,
509 vector<void *> params;
511 /* apply user space smack */
512 if (_is_authorized_request(invocation) == true) {
513 g_object_ref(object);
514 params.push_back((void *)object);
516 g_object_ref(invocation);
517 params.push_back((void *)invocation);
519 params.push_back((void *)user_data);
521 GDBusDispatcher::push(_process_se_service, params);
523 vector<pair<unsigned int, string> > list;
525 _ERR("access denied");
527 /* response to client */
528 smartcard_service_se_service_complete_se_service(object,
530 SCARD_ERROR_SECURITY_NOT_ALLOWED,
531 IntegerHandle::INVALID_HANDLE,
532 _reader_to_variant(list));
538 static gboolean __process_shutdown(SmartcardServiceSeService *object,
539 GDBusMethodInvocation *invocation,
540 guint handle, void *user_data)
544 _INFO("[MSG_REQUEST_SHUTDOWN]");
546 ServerResource &resource = ServerResource::getInstance();
548 name = g_dbus_method_invocation_get_sender(invocation);
550 resource.removeService(name, handle);
552 /* response to client */
553 smartcard_service_se_service_complete_shutdown(object,
554 invocation, SCARD_ERROR_OK);
562 static void _process_shutdown(vector<void *> ¶ms)
564 SmartcardServiceSeService *object;
565 GDBusMethodInvocation *invocation;
569 if (params.size() != 4) {
570 _ERR("invalid parameter");
575 object = (SmartcardServiceSeService *)params[0];
576 invocation = (GDBusMethodInvocation *)params[1];
577 handle = (gulong)params[2];
578 user_data = params[3];
580 __process_shutdown(object, invocation, handle, user_data);
582 g_object_unref(object);
583 g_object_unref(invocation);
586 static gboolean _handle_shutdown(SmartcardServiceSeService *object,
587 GDBusMethodInvocation *invocation,
591 vector<void *> params;
593 /* apply user space smack */
594 if (_is_authorized_request(invocation) == true) {
595 g_object_ref(object);
596 params.push_back((void *)object);
598 g_object_ref(invocation);
599 params.push_back((void *)invocation);
601 params.push_back((void *)handle);
602 params.push_back(user_data);
604 GDBusDispatcher::push(_process_shutdown, params);
606 _ERR("access denied");
608 /* response to client */
609 smartcard_service_se_service_complete_shutdown(object,
610 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
616 bool ServerGDBus::initSEService()
618 GError *error = NULL;
620 seService = smartcard_service_se_service_skeleton_new();
622 g_signal_connect(seService,
624 G_CALLBACK(_handle_se_service),
627 g_signal_connect(seService,
629 G_CALLBACK(_handle_shutdown),
632 if (g_dbus_interface_skeleton_export(
633 G_DBUS_INTERFACE_SKELETON(seService),
635 "/org/tizen/SmartcardService/SeService",
638 _ERR("Can not skeleton_export %s", error->message);
641 g_object_unref(seService);
650 void ServerGDBus::deinitSEService()
652 if (seService != NULL) {
653 g_object_unref(seService);
658 void ServerGDBus::emitReaderInserted(unsigned int reader_id,
659 const char *reader_name)
661 smartcard_service_se_service_emit_reader_inserted(
662 SMARTCARD_SERVICE_SE_SERVICE(seService),
663 reader_id, reader_name);
666 void ServerGDBus::emitReaderRemoved(unsigned int reader_id,
667 const char *reader_name)
669 smartcard_service_se_service_emit_reader_removed(
670 SMARTCARD_SERVICE_SE_SERVICE(seService),
671 reader_id, reader_name);
678 static gboolean __process_open_session(SmartcardServiceReader *object,
679 GDBusMethodInvocation *invocation, guint service_id,
680 guint reader_id, void *user_data)
682 unsigned int handle = IntegerHandle::INVALID_HANDLE;
686 _INFO("[MSG_REQUEST_OPEN_SESSION]");
688 ServerResource &resource = ServerResource::getInstance();
690 name = g_dbus_method_invocation_get_sender(invocation);
692 if (resource.isValidReaderHandle(reader_id)) {
693 vector<ByteArray> temp;
695 handle = resource.createSession(name,
700 if (handle != IntegerHandle::INVALID_HANDLE) {
701 result = SCARD_ERROR_OK;
703 _ERR("createSession failed [%d]", handle);
705 result = SCARD_ERROR_OUT_OF_MEMORY;
708 _ERR("request invalid reader handle [%d]", reader_id);
710 result = SCARD_ERROR_ILLEGAL_PARAM;
713 /* response to client */
714 smartcard_service_reader_complete_open_session(object,
715 invocation, result, handle);
720 static void _process_open_session(vector<void *> ¶ms)
722 SmartcardServiceReader *object;
723 GDBusMethodInvocation *invocation;
728 if (params.size() != 5) {
729 _ERR("invalid parameter");
734 object = (SmartcardServiceReader *)params[0];
735 invocation = (GDBusMethodInvocation *)params[1];
736 service_id = (gulong)params[2];
737 reader_id = (gulong)params[3];
738 user_data = params[4];
740 __process_open_session(object, invocation, service_id,
741 reader_id, user_data);
743 g_object_unref(object);
744 g_object_unref(invocation);
747 static gboolean _handle_open_session(SmartcardServiceReader *object,
748 GDBusMethodInvocation *invocation,
750 guint reader_id, void *user_data)
752 vector<void *> params;
754 /* apply user space smack */
755 if (_is_authorized_request(invocation) == true) {
756 g_object_ref(object);
757 params.push_back((void *)object);
759 g_object_ref(invocation);
760 params.push_back((void *)invocation);
762 params.push_back((void *)service_id);
763 params.push_back((void *)reader_id);
764 params.push_back(user_data);
766 GDBusDispatcher::push(_process_open_session, params);
768 _ERR("access denied");
770 /* response to client */
771 smartcard_service_reader_complete_open_session(object,
773 SCARD_ERROR_SECURITY_NOT_ALLOWED,
774 IntegerHandle::INVALID_HANDLE);
780 bool ServerGDBus::initReader()
782 GError *error = NULL;
784 reader = smartcard_service_reader_skeleton_new();
786 g_signal_connect(reader,
787 "handle-open-session",
788 G_CALLBACK(_handle_open_session),
791 if (g_dbus_interface_skeleton_export(
792 G_DBUS_INTERFACE_SKELETON(reader),
794 "/org/tizen/SmartcardService/Reader",
797 _ERR("Can not skeleton_export %s", error->message);
800 g_object_unref(reader);
809 void ServerGDBus::deinitReader()
811 if (reader != NULL) {
812 g_object_unref(reader);
821 static gboolean __process_close_session(SmartcardServiceSession *object,
822 GDBusMethodInvocation *invocation, guint service_id,
823 guint session_id, void *user_data)
827 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
829 ServerResource &resource = ServerResource::getInstance();
831 name = g_dbus_method_invocation_get_sender(invocation);
833 if (resource.isValidSessionHandle(name, service_id,
835 resource.removeSession(name, service_id,
838 _ERR("invalid parameters");
841 /* response to client */
842 smartcard_service_session_complete_close_session(object,
843 invocation, SCARD_ERROR_OK);
848 static void _process_close_session(vector<void *> ¶ms)
850 SmartcardServiceSession *object;
851 GDBusMethodInvocation *invocation;
856 if (params.size() != 5) {
857 _ERR("invalid parameter");
862 object = (SmartcardServiceSession *)params[0];
863 invocation = (GDBusMethodInvocation *)params[1];
864 service_id = (gulong)params[2];
865 session_id = (gulong)params[3];
866 user_data = params[4];
868 __process_close_session(object, invocation, service_id,
869 session_id, user_data);
871 g_object_unref(object);
872 g_object_unref(invocation);
875 static gboolean _handle_close_session(SmartcardServiceSession *object,
876 GDBusMethodInvocation *invocation,
878 guint session_id, void *user_data)
880 vector<void *> params;
882 /* apply user space smack */
883 if (_is_authorized_request(invocation) == true) {
884 g_object_ref(object);
885 params.push_back((void *)object);
887 g_object_ref(invocation);
888 params.push_back((void *)invocation);
890 params.push_back((void *)service_id);
891 params.push_back((void *)session_id);
892 params.push_back(user_data);
894 GDBusDispatcher::push(_process_close_session, params);
896 _ERR("access denied");
898 /* response to client */
899 smartcard_service_session_complete_close_session(object,
900 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
906 static gboolean __process_get_atr(SmartcardServiceSession *object,
907 GDBusMethodInvocation *invocation, guint service_id,
908 guint session_id, void *user_data)
912 GVariant *atr = NULL;
914 ServiceInstance *client = NULL;
916 _INFO("[MSG_REQUEST_GET_ATR]");
918 ServerResource &resource = ServerResource::getInstance();
920 name = g_dbus_method_invocation_get_sender(invocation);
922 client = resource.getService(name, service_id);
923 if (client != NULL) {
926 terminal = client->getTerminal(session_id);
927 if (terminal != NULL) {
928 if (terminal->open() == true) {
929 result = terminal->getATRSync(resp);
930 if (result < SCARD_ERROR_OK) {
931 _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
936 _ERR("terminal->open failed");
938 result = SCARD_ERROR_UNAVAILABLE;
941 _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
943 result = SCARD_ERROR_UNAVAILABLE;
946 _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
948 result = SCARD_ERROR_UNAVAILABLE;
951 atr = GDBusHelper::convertByteArrayToVariant(resp);
953 /* response to client */
954 smartcard_service_session_complete_get_atr(object, invocation,
960 static void _process_get_atr(vector<void *> ¶ms)
962 SmartcardServiceSession *object;
963 GDBusMethodInvocation *invocation;
968 if (params.size() != 5) {
969 _ERR("invalid parameter");
974 object = (SmartcardServiceSession *)params[0];
975 invocation = (GDBusMethodInvocation *)params[1];
976 service_id = (gulong)params[2];
977 session_id = (gulong)params[3];
978 user_data = params[4];
980 __process_get_atr(object, invocation, service_id,
981 session_id, user_data);
983 g_object_unref(object);
984 g_object_unref(invocation);
987 static gboolean _handle_get_atr(SmartcardServiceSession *object,
988 GDBusMethodInvocation *invocation,
990 guint session_id, void *user_data)
992 vector<void *> params;
994 /* apply user space smack */
995 if (_is_authorized_request(invocation) == true) {
996 g_object_ref(object);
997 params.push_back((void *)object);
999 g_object_ref(invocation);
1000 params.push_back((void *)invocation);
1002 params.push_back((void *)service_id);
1003 params.push_back((void *)session_id);
1004 params.push_back(user_data);
1006 GDBusDispatcher::push(_process_get_atr, params);
1010 _ERR("access denied");
1012 /* response to client */
1013 smartcard_service_session_complete_get_atr(
1016 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1017 GDBusHelper::convertByteArrayToVariant(resp));
1023 static gboolean __process_open_channel(SmartcardServiceSession *object,
1024 GDBusMethodInvocation *invocation, guint service_id,
1025 guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
1027 int channelNum = -1;
1028 int result = SCARD_ERROR_UNKNOWN;
1030 GVariant *response = NULL;
1031 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
1034 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
1035 _INFO("P2 is %x", P2);
1037 ServerResource &resource = ServerResource::getInstance();
1039 name = g_dbus_method_invocation_get_sender(invocation);
1045 GDBusHelper::convertVariantToByteArray(aid,
1048 channelID = resource.createChannel(name,
1049 service_id, session_id, type, tempAid);
1050 if (channelID != IntegerHandle::INVALID_HANDLE) {
1051 ServerChannel *temp;
1053 temp = (ServerChannel *)resource.getChannel(
1054 name, service_id, channelID);
1056 resp = temp->getSelectResponse();
1057 channelNum = temp->getChannelNumber();
1058 result = SCARD_ERROR_OK;
1060 _ERR("getChannel is failed");
1061 result = SCARD_ERROR_UNAVAILABLE;
1064 _ERR("channel is null.");
1066 /* set error value */
1067 result = SCARD_ERROR_UNAVAILABLE;
1070 catch (ExceptionBase &e)
1072 result = e.getErrorCode();
1075 response = GDBusHelper::convertByteArrayToVariant(resp);
1077 /* response to client */
1078 smartcard_service_session_complete_open_channel(object,
1079 invocation, result, channelID, channelNum, response);
1084 static void _process_open_channel(vector<void *> ¶ms)
1086 SmartcardServiceSession *object;
1087 GDBusMethodInvocation *invocation;
1095 if (params.size() != 8) {
1096 _ERR("invalid parameter");
1101 object = (SmartcardServiceSession *)params[0];
1102 invocation = (GDBusMethodInvocation *)params[1];
1103 service_id = (gulong)params[2];
1104 session_id = (gulong)params[3];
1105 type = (gulong)params[4];
1106 aid = (GVariant *)params[5];
1107 P2 = (guint8)((gulong)params[6]);
1108 user_data = params[7];
1110 __process_open_channel(object, invocation, service_id,
1111 session_id, type, aid, P2, user_data);
1113 g_object_unref(object);
1114 g_object_unref(invocation);
1115 g_variant_unref(aid);
1118 static gboolean _handle_open_channel(SmartcardServiceSession *object,
1119 GDBusMethodInvocation *invocation,
1121 guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
1123 vector<void *> params;
1125 /* apply user space smack */
1126 if (_is_authorized_request(invocation) == true) {
1127 g_object_ref(object);
1128 params.push_back((void *)object);
1130 g_object_ref(invocation);
1131 params.push_back((void *)invocation);
1133 params.push_back((void *)service_id);
1134 params.push_back((void *)session_id);
1135 params.push_back((void *)type);
1138 params.push_back((void *)aid);
1139 params.push_back((void *)((int)P2));
1140 params.push_back(user_data);
1142 GDBusDispatcher::push(_process_open_channel, params);
1146 _ERR("access denied");
1148 /* response to client */
1149 smartcard_service_session_complete_open_channel(object,
1151 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1152 IntegerHandle::INVALID_HANDLE,
1154 GDBusHelper::convertByteArrayToVariant(resp));
1160 bool ServerGDBus::initSession()
1162 GError *error = NULL;
1164 session = smartcard_service_session_skeleton_new();
1166 g_signal_connect(session,
1167 "handle-close-session",
1168 G_CALLBACK(_handle_close_session),
1171 g_signal_connect(session,
1173 G_CALLBACK(_handle_get_atr),
1176 g_signal_connect(session,
1177 "handle-open-channel",
1178 G_CALLBACK(_handle_open_channel),
1181 if (g_dbus_interface_skeleton_export(
1182 G_DBUS_INTERFACE_SKELETON(session),
1184 "/org/tizen/SmartcardService/Session",
1187 _ERR("Can not skeleton_export %s", error->message);
1189 g_error_free(error);
1190 g_object_unref(session);
1199 void ServerGDBus::deinitSession()
1201 if (session != NULL) {
1202 g_object_unref(session);
1211 static gboolean __process_close_channel(SmartcardServiceChannel *object,
1212 GDBusMethodInvocation *invocation, guint service_id,
1213 guint channel_id, void *user_data)
1218 _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
1220 ServerResource &resource = ServerResource::getInstance();
1222 name = g_dbus_method_invocation_get_sender(invocation);
1224 resource.removeChannel(name, service_id, channel_id);
1226 result = SCARD_ERROR_OK;
1228 /* response to client */
1229 smartcard_service_channel_complete_close_channel(object,
1230 invocation, result);
1235 static void _process_close_channel(vector<void *> ¶ms)
1237 SmartcardServiceChannel *object;
1238 GDBusMethodInvocation *invocation;
1243 if (params.size() != 5) {
1244 _ERR("invalid parameter");
1249 object = (SmartcardServiceChannel *)params[0];
1250 invocation = (GDBusMethodInvocation *)params[1];
1251 service_id = (gulong)params[2];
1252 channel_id = (gulong)params[3];
1253 user_data = params[4];
1255 __process_close_channel(object, invocation, service_id,
1256 channel_id, user_data);
1258 g_object_unref(object);
1259 g_object_unref(invocation);
1262 static gboolean _handle_close_channel(SmartcardServiceChannel *object,
1263 GDBusMethodInvocation *invocation,
1264 guint service_id, guint channel_id, void *user_data)
1266 vector<void *> params;
1268 /* apply user space smack */
1269 if (_is_authorized_request(invocation) == true) {
1270 g_object_ref(object);
1271 params.push_back((void *)object);
1273 g_object_ref(invocation);
1274 params.push_back((void *)invocation);
1276 params.push_back((void *)service_id);
1277 params.push_back((void *)channel_id);
1278 params.push_back(user_data);
1280 GDBusDispatcher::push(_process_close_channel, params);
1282 _ERR("access denied");
1284 /* response to client */
1285 smartcard_service_channel_complete_close_channel(
1288 SCARD_ERROR_SECURITY_NOT_ALLOWED);
1294 static gboolean __process_transmit(SmartcardServiceChannel *object,
1295 GDBusMethodInvocation *invocation,
1302 Channel *channel = NULL;
1304 GVariant *response = NULL;
1307 _INFO("[MSG_REQUEST_TRANSMIT]");
1309 ServerResource &resource = ServerResource::getInstance();
1311 name = g_dbus_method_invocation_get_sender(invocation);
1313 channel = resource.getChannel(name, service_id, channel_id);
1314 if (channel != NULL) {
1318 GDBusHelper::convertVariantToByteArray(command, cmd);
1320 rv = channel->transmitSync(cmd, resp);
1322 result = SCARD_ERROR_OK;
1324 _ERR("transmit failed [%d]", rv);
1329 _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
1331 result = SCARD_ERROR_UNAVAILABLE;
1334 response = GDBusHelper::convertByteArrayToVariant(resp);
1336 /* response to client */
1337 smartcard_service_channel_complete_transmit(object, invocation,
1343 static void _process_transmit(vector<void *> ¶ms)
1345 SmartcardServiceChannel *object;
1346 GDBusMethodInvocation *invocation;
1352 if (params.size() != 6) {
1353 _ERR("invalid parameter");
1358 object = (SmartcardServiceChannel *)params[0];
1359 invocation = (GDBusMethodInvocation *)params[1];
1360 service_id = (gulong)params[2];
1361 channel_id = (gulong)params[3];
1362 command = (GVariant *)params[4];
1363 user_data = params[5];
1365 __process_transmit(object, invocation, service_id,
1366 channel_id, command, user_data);
1368 g_object_unref(object);
1369 g_object_unref(invocation);
1370 g_object_unref(command);
1373 static gboolean _handle_transmit(SmartcardServiceChannel *object,
1374 GDBusMethodInvocation *invocation,
1380 vector<void *> params;
1382 /* apply user space smack */
1383 if (_is_authorized_request(invocation) == true) {
1384 /* enqueue message */
1385 g_object_ref(object);
1386 params.push_back((void *)object);
1388 g_object_ref(invocation);
1389 params.push_back((void *)invocation);
1391 params.push_back((void *)service_id);
1392 params.push_back((void *)channel_id);
1394 g_object_ref(command);
1395 params.push_back((void *)command);
1397 params.push_back(user_data);
1399 GDBusDispatcher::push(_process_transmit, params);
1403 _ERR("access denied");
1405 /* response to client */
1406 smartcard_service_channel_complete_transmit(object,
1408 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1409 GDBusHelper::convertByteArrayToVariant(resp));
1415 bool ServerGDBus::initChannel()
1417 GError *error = NULL;
1419 channel = smartcard_service_channel_skeleton_new();
1421 g_signal_connect(channel,
1422 "handle-close-channel",
1423 G_CALLBACK(_handle_close_channel),
1426 g_signal_connect(channel,
1428 G_CALLBACK(_handle_transmit),
1431 if (g_dbus_interface_skeleton_export(
1432 G_DBUS_INTERFACE_SKELETON(channel),
1434 "/org/tizen/SmartcardService/Channel",
1437 _ERR("Can not skeleton_export %s", error->message);
1439 g_error_free(error);
1440 g_object_unref(channel);
1449 void ServerGDBus::deinitChannel()
1451 if (channel != NULL) {
1452 g_object_unref(channel);
1456 } /* namespace smartcard_service_api */