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 [%zu]", 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 /* LCOV_EXCL_START */
108 if (dispatcher->q.size() > 0) {
109 _INFO("remaining messages : %zu", dispatcher->q.size());
114 _INFO("dispatch finished");
117 dispatcher->syncUnlock();
124 ServerGDBus::ServerGDBus() : dbus_proxy(NULL), connection(NULL),
125 seService(NULL), reader(NULL), session(NULL), channel(NULL)
129 ServerGDBus::~ServerGDBus()
134 ServerGDBus &ServerGDBus::getInstance()
136 static ServerGDBus serverGDBus;
141 static void name_owner_changed(GDBusProxy *proxy,
142 const gchar *name, const gchar *old_owner,
143 const gchar *new_owner, void *user_data)
145 /* LCOV_EXCL_START */
146 if (name == NULL || old_owner == NULL || new_owner == NULL) {
147 _ERR("invalid parameter");
151 if (strlen(new_owner) == 0) {
152 ClientInstance *client;
154 ServerResource &resource = ServerResource::getInstance();
156 client = resource.getClient(old_owner);
157 if (client != NULL) {
158 _INFO("terminated client, pid [%d]", client->getPID());
159 resource.removeClient(old_owner);
166 static void _on_name_owner_changed(GDBusConnection *connection,
167 const gchar *sender_name, const gchar *object_path,
168 const gchar *interface_name, const gchar *signal_name,
169 GVariant *parameters, gpointer user_data)
175 g_variant_get(parameters,
181 name_owner_changed((GDBusProxy *)connection,
182 name, old_owner, new_owner, user_data);
189 bool ServerGDBus::_init()
191 GError *error = NULL;
193 /* init default context */
194 dbus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
195 G_DBUS_PROXY_FLAGS_NONE,
196 NULL, /* GDBusInterfaceInfo */
197 "org.freedesktop.DBus",
198 "/org/freedesktop/DBus",
199 "org.freedesktop.DBus",
200 NULL, /* GCancellable */
202 if (dbus_proxy == NULL)
204 /* LCOV_EXCL_START */
205 _ERR("Can not create proxy : %s", error->message);
212 /* subscribe signal */
213 g_dbus_connection_signal_subscribe(connection,
214 "org.freedesktop.DBus", /* bus name */
215 "org.freedesktop.DBus", /* interface */
216 "NameOwnerChanged", /* member */
217 "/org/freedesktop/DBus", /* path */
219 G_DBUS_SIGNAL_FLAGS_NONE,
220 _on_name_owner_changed,
226 void ServerGDBus::_deinit()
228 if (dbus_proxy != NULL) {
229 g_object_unref(dbus_proxy);
234 bool ServerGDBus::init()
236 GError *error = NULL;
238 connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
239 if (connection != NULL) {
240 /* LCOV_EXCL_START */
242 _ERR("Can not get connection %s", error->message);
256 smartcard_service_init_access_control(connection);
261 void ServerGDBus::deinit()
264 smartcard_service_deinit_access_control();
273 if (connection != NULL) {
274 g_object_unref(connection);
279 static gboolean _call_get_connection_unix_process_id_sync(
280 GDBusProxy *proxy, const gchar *arg_name, guint *out_pid,
281 GCancellable *cancellable, GError **error) {
284 _ret = g_dbus_proxy_call_sync(proxy,
285 "GetConnectionUnixProcessID",
286 g_variant_new("(s)", arg_name),
287 G_DBUS_CALL_FLAGS_NONE,
288 -1, cancellable, error);
290 g_variant_get(_ret, "(u)", out_pid);
291 g_variant_unref(_ret);
297 pid_t ServerGDBus::getPID(const char *name)
300 GError *error = NULL;
302 if (_call_get_connection_unix_process_id_sync(
303 (GDBusProxy *)dbus_proxy, name,
304 &pid, NULL, &error) == true) {
305 /* LCOV_EXCL_START */
307 _ERR("_g_freedesktop_dbus_call_get_connection_unix_process_id_sync failed : %s", error->message);
316 static bool _get_credentials(GDBusMethodInvocation *invocation)
322 char *client_session;
323 cynara *p_cynara = NULL;
324 const char *sender_unique_name;
325 GDBusConnection *connection;
327 connection = g_dbus_method_invocation_get_connection(invocation);
328 sender_unique_name = g_dbus_method_invocation_get_sender(invocation);
330 pid = ServerGDBus::getInstance().getPID(sender_unique_name);
332 ret = cynara_initialize(&p_cynara, NULL);
333 /* LCOV_EXCL_START */
334 if (ret != CYNARA_API_SUCCESS) {
335 _ERR("cynara_initialize() failed");
340 ret = cynara_creds_gdbus_get_user(connection, sender_unique_name, USER_METHOD_DEFAULT, &user);
341 /* LCOV_EXCL_START */
342 if (ret != CYNARA_API_SUCCESS) {
343 _ERR("cynara_creds_gdbus_get_user() failed");
348 ret = cynara_creds_gdbus_get_client(connection, sender_unique_name, CLIENT_METHOD_DEFAULT, &client);
349 /* LCOV_EXCL_START */
350 if (ret != CYNARA_API_SUCCESS) {
351 _ERR("cynara_creds_gdbus_get_client() failed");
357 _ERR("user :%s , client :%s ,unique_name : %s, pid() : %d", user, client, sender_unique_name, pid);
359 client_session = cynara_session_from_pid(pid);
361 /* LCOV_EXCL_START */
362 if (!client_session) {
363 _ERR("cynara_session_from_pid() failed");
370 ret = cynara_check(p_cynara, client, client_session, user, SMARTCARD_PRIVILEGE);
371 if ( ret == CYNARA_API_ACCESS_ALLOWED ) {
372 _INFO("cynara PASS");
375 g_free(client_session);
380 cynara_finish(p_cynara);
384 return (ret == CYNARA_API_ACCESS_ALLOWED ) ? true : false;
388 static bool _is_authorized_request(GDBusMethodInvocation *invocation)
393 result = _get_credentials(invocation);
396 _ERR("api security check result : %d", result);
405 static GVariant *_reader_to_variant(
406 vector<pair<unsigned int, string> > &readers)
408 GVariantBuilder builder;
411 g_variant_builder_init(&builder, G_VARIANT_TYPE("a(us)"));
413 for (i = 0; i < readers.size(); i++) {
414 g_variant_builder_add(&builder, "(us)",
415 readers[i].first, readers[i].second.c_str());
418 return g_variant_builder_end(&builder);
421 static gboolean __process_se_service(SmartcardServiceSeService *object,
422 GDBusMethodInvocation *invocation,
425 gint result = SCARD_ERROR_OK;
426 GVariant *readers = NULL;
427 vector<pair<unsigned int, string> > list;
428 unsigned int handle = IntegerHandle::INVALID_HANDLE;
432 _INFO("[MSG_REQUEST_READERS]");
434 ServerResource &resource = ServerResource::getInstance();
436 name = g_dbus_method_invocation_get_sender(invocation);
438 /* load secure elements */
439 resource.loadSecureElements();
441 pid = ServerGDBus::getInstance().getPID(name);
443 _DBG("service requested, pid [%d]", pid);
446 ClientInstance *instance;
448 instance = resource.getClient(name);
449 if (instance == NULL) {
450 _INFO("create client instance, pid [%d]", pid);
452 resource.createClient(name, pid);
454 instance = resource.getClient(name);
455 if (instance != NULL) {
456 /* generate certification hashes */
457 instance->generateCertificationHashes();
459 _ERR("createClient failed"); /* LCOV_EXCL_LINE */
463 if (instance != NULL) {
464 ServiceInstance *service;
467 service = resource.createService(name);
468 if (service != NULL) {
469 handle = service->getHandle();
470 resource.getReaders(list);
472 if (list.size() == 0) {
473 _INFO("no secure elements");
475 /* LCOV_EXCL_START */
477 _ERR("createService failed");
479 result = SCARD_ERROR_OUT_OF_MEMORY;
482 _ERR("client doesn't exist, pid [%d]", pid);
484 result = SCARD_ERROR_OUT_OF_MEMORY;
487 _ERR("invalid pid, [%d]", pid);
489 result = SCARD_ERROR_IPC_FAILED;
493 readers = _reader_to_variant(list);
495 /* response to client */
496 smartcard_service_se_service_complete_se_service(object,
497 invocation, result, handle, readers);
502 static void _process_se_service(vector<void *> ¶ms)
504 SmartcardServiceSeService *object;
505 GDBusMethodInvocation *invocation;
508 /* LCOV_EXCL_START */
509 if (params.size() != 3) {
510 _ERR("invalid parameter");
516 object = (SmartcardServiceSeService *)params[0];
517 invocation = (GDBusMethodInvocation *)params[1];
518 user_data = params[2];
520 __process_se_service(object, invocation, user_data);
522 g_object_unref(object);
523 g_object_unref(invocation);
526 static gboolean _handle_se_service(SmartcardServiceSeService *object,
527 GDBusMethodInvocation *invocation,
530 vector<void *> params;
532 /* apply user space smack */
533 if (_is_authorized_request(invocation) == true) {
534 g_object_ref(object);
535 params.push_back((void *)object);
537 g_object_ref(invocation);
538 params.push_back((void *)invocation);
540 params.push_back((void *)user_data);
542 GDBusDispatcher::push(_process_se_service, params);
543 /* LCOV_EXCL_START */
545 vector<pair<unsigned int, string> > list;
547 _ERR("access denied");
549 /* response to client */
550 smartcard_service_se_service_complete_se_service(object,
552 SCARD_ERROR_SECURITY_NOT_ALLOWED,
553 IntegerHandle::INVALID_HANDLE,
554 _reader_to_variant(list));
561 static gboolean __process_shutdown(SmartcardServiceSeService *object,
562 GDBusMethodInvocation *invocation,
563 guint handle, void *user_data)
567 _INFO("[MSG_REQUEST_SHUTDOWN]");
569 ServerResource &resource = ServerResource::getInstance();
571 name = g_dbus_method_invocation_get_sender(invocation);
573 resource.removeService(name, handle);
575 /* response to client */
576 smartcard_service_se_service_complete_shutdown(object,
577 invocation, SCARD_ERROR_OK);
585 static void _process_shutdown(vector<void *> ¶ms)
587 SmartcardServiceSeService *object;
588 GDBusMethodInvocation *invocation;
592 /* LCOV_EXCL_START */
593 if (params.size() != 4) {
594 _ERR("invalid parameter");
600 object = (SmartcardServiceSeService *)params[0];
601 invocation = (GDBusMethodInvocation *)params[1];
602 handle = (gulong)params[2];
603 user_data = params[3];
605 __process_shutdown(object, invocation, handle, user_data);
607 g_object_unref(object);
608 g_object_unref(invocation);
611 static gboolean _handle_shutdown(SmartcardServiceSeService *object,
612 GDBusMethodInvocation *invocation,
616 vector<void *> params;
618 /* apply user space smack */
619 if (_is_authorized_request(invocation) == true) {
620 g_object_ref(object);
621 params.push_back((void *)object);
623 g_object_ref(invocation);
624 params.push_back((void *)invocation);
626 params.push_back((void *)handle);
627 params.push_back(user_data);
629 GDBusDispatcher::push(_process_shutdown, params);
630 /* LCOV_EXCL_START */
632 _ERR("access denied");
634 /* response to client */
635 smartcard_service_se_service_complete_shutdown(object,
636 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
643 bool ServerGDBus::initSEService()
645 GError *error = NULL;
647 seService = smartcard_service_se_service_skeleton_new();
649 g_signal_connect(seService,
651 G_CALLBACK(_handle_se_service),
654 g_signal_connect(seService,
656 G_CALLBACK(_handle_shutdown),
659 /* LCOV_EXCL_START */
660 if (g_dbus_interface_skeleton_export(
661 G_DBUS_INTERFACE_SKELETON(seService),
663 "/org/tizen/SmartcardService/SeService",
666 _ERR("Can not skeleton_export %s", error->message);
669 g_object_unref(seService);
679 void ServerGDBus::deinitSEService()
681 if (seService != NULL) {
682 g_object_unref(seService);
687 void ServerGDBus::emitReaderInserted(unsigned int reader_id,
688 const char *reader_name)
690 /* LCOV_EXCL_START */
691 smartcard_service_se_service_emit_reader_inserted(
692 SMARTCARD_SERVICE_SE_SERVICE(seService),
693 reader_id, reader_name);
697 void ServerGDBus::emitReaderRemoved(unsigned int reader_id,
698 const char *reader_name)
700 /* LCOV_EXCL_START */
701 smartcard_service_se_service_emit_reader_removed(
702 SMARTCARD_SERVICE_SE_SERVICE(seService),
703 reader_id, reader_name);
711 static gboolean __process_open_session(SmartcardServiceReader *object,
712 GDBusMethodInvocation *invocation, guint service_id,
713 guint reader_id, void *user_data)
715 unsigned int handle = IntegerHandle::INVALID_HANDLE;
719 _INFO("[MSG_REQUEST_OPEN_SESSION]");
721 ServerResource &resource = ServerResource::getInstance();
723 name = g_dbus_method_invocation_get_sender(invocation);
725 if (resource.isValidReaderHandle(reader_id)) {
726 vector<ByteArray> temp;
728 handle = resource.createSession(name,
733 if (handle != IntegerHandle::INVALID_HANDLE) {
734 result = SCARD_ERROR_OK;
736 /* LCOV_EXCL_START */
737 _ERR("createSession failed [%d]", handle);
739 result = SCARD_ERROR_OUT_OF_MEMORY;
742 _ERR("request invalid reader handle [%d]", reader_id);
744 result = SCARD_ERROR_ILLEGAL_PARAM;
748 /* response to client */
749 smartcard_service_reader_complete_open_session(object,
750 invocation, result, handle);
755 static void _process_open_session(vector<void *> ¶ms)
757 SmartcardServiceReader *object;
758 GDBusMethodInvocation *invocation;
763 if (params.size() != 5) {
764 /* LCOV_EXCL_START */
765 _ERR("invalid parameter");
771 object = (SmartcardServiceReader *)params[0];
772 invocation = (GDBusMethodInvocation *)params[1];
773 service_id = (gulong)params[2];
774 reader_id = (gulong)params[3];
775 user_data = params[4];
777 __process_open_session(object, invocation, service_id,
778 reader_id, user_data);
780 g_object_unref(object);
781 g_object_unref(invocation);
784 static gboolean _handle_open_session(SmartcardServiceReader *object,
785 GDBusMethodInvocation *invocation,
787 guint reader_id, void *user_data)
789 vector<void *> params;
791 /* apply user space smack */
792 if (_is_authorized_request(invocation) == true) {
793 g_object_ref(object);
794 params.push_back((void *)object);
796 g_object_ref(invocation);
797 params.push_back((void *)invocation);
799 params.push_back((void *)service_id);
800 params.push_back((void *)reader_id);
801 params.push_back(user_data);
803 GDBusDispatcher::push(_process_open_session, params);
805 /* LCOV_EXCL_START */
806 _ERR("access denied");
808 /* response to client */
809 smartcard_service_reader_complete_open_session(object,
811 SCARD_ERROR_SECURITY_NOT_ALLOWED,
812 IntegerHandle::INVALID_HANDLE);
819 bool ServerGDBus::initReader()
821 GError *error = NULL;
823 reader = smartcard_service_reader_skeleton_new();
825 g_signal_connect(reader,
826 "handle-open-session",
827 G_CALLBACK(_handle_open_session),
830 if (g_dbus_interface_skeleton_export(
831 G_DBUS_INTERFACE_SKELETON(reader),
833 "/org/tizen/SmartcardService/Reader",
836 /* LCOV_EXCL_START */
837 _ERR("Can not skeleton_export %s", error->message);
840 g_object_unref(reader);
850 void ServerGDBus::deinitReader()
852 /* LCOV_EXCL_START */
853 if (reader != NULL) {
854 g_object_unref(reader);
864 static gboolean __process_close_session(SmartcardServiceSession *object,
865 GDBusMethodInvocation *invocation, guint service_id,
866 guint session_id, void *user_data)
870 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
872 ServerResource &resource = ServerResource::getInstance();
874 name = g_dbus_method_invocation_get_sender(invocation);
876 if (resource.isValidSessionHandle(name, service_id,
878 resource.removeSession(name, service_id,
881 _ERR("invalid parameters"); //LCOV_EXCL_LINE
884 /* response to client */
885 smartcard_service_session_complete_close_session(object,
886 invocation, SCARD_ERROR_OK);
891 static void _process_close_session(vector<void *> ¶ms)
893 SmartcardServiceSession *object;
894 GDBusMethodInvocation *invocation;
899 if (params.size() != 5) {
900 /* LCOV_EXCL_START */
901 _ERR("invalid parameter");
907 object = (SmartcardServiceSession *)params[0];
908 invocation = (GDBusMethodInvocation *)params[1];
909 service_id = (gulong)params[2];
910 session_id = (gulong)params[3];
911 user_data = params[4];
913 __process_close_session(object, invocation, service_id,
914 session_id, user_data);
916 g_object_unref(object);
917 g_object_unref(invocation);
920 static gboolean _handle_close_session(SmartcardServiceSession *object,
921 GDBusMethodInvocation *invocation,
923 guint session_id, void *user_data)
925 vector<void *> params;
927 /* apply user space smack */
928 if (_is_authorized_request(invocation) == true) {
929 g_object_ref(object);
930 params.push_back((void *)object);
932 g_object_ref(invocation);
933 params.push_back((void *)invocation);
935 params.push_back((void *)service_id);
936 params.push_back((void *)session_id);
937 params.push_back(user_data);
939 GDBusDispatcher::push(_process_close_session, params);
941 /* LCOV_EXCL_START */
942 _ERR("access denied");
944 /* response to client */
945 smartcard_service_session_complete_close_session(object,
946 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
953 static gboolean __process_get_atr(SmartcardServiceSession *object,
954 GDBusMethodInvocation *invocation, guint service_id,
955 guint session_id, void *user_data)
959 GVariant *atr = NULL;
961 ServiceInstance *client = NULL;
963 _INFO("[MSG_REQUEST_GET_ATR]");
965 ServerResource &resource = ServerResource::getInstance();
967 name = g_dbus_method_invocation_get_sender(invocation);
969 client = resource.getService(name, service_id);
970 /* LCOV_EXCL_START */
971 if (client != NULL) {
974 terminal = client->getTerminal(session_id);
975 if (terminal != NULL) {
976 if (terminal->open() == true) {
977 result = terminal->getATRSync(resp);
978 if (result < SCARD_ERROR_OK) {
979 _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
984 _ERR("terminal->open failed");
986 result = SCARD_ERROR_UNAVAILABLE;
989 _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
991 result = SCARD_ERROR_UNAVAILABLE;
994 _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
996 result = SCARD_ERROR_UNAVAILABLE;
1000 atr = GDBusHelper::convertByteArrayToVariant(resp);
1002 /* response to client */
1003 smartcard_service_session_complete_get_atr(object, invocation,
1009 static void _process_get_atr(vector<void *> ¶ms)
1011 SmartcardServiceSession *object;
1012 GDBusMethodInvocation *invocation;
1017 if (params.size() != 5) {
1018 /* LCOV_EXCL_START */
1019 _ERR("invalid parameter");
1022 /* LCOV_EXCL_STOP */
1025 object = (SmartcardServiceSession *)params[0];
1026 invocation = (GDBusMethodInvocation *)params[1];
1027 service_id = (gulong)params[2];
1028 session_id = (gulong)params[3];
1029 user_data = params[4];
1031 __process_get_atr(object, invocation, service_id,
1032 session_id, user_data);
1034 g_object_unref(object);
1035 g_object_unref(invocation);
1038 static gboolean _handle_get_atr(SmartcardServiceSession *object,
1039 GDBusMethodInvocation *invocation,
1041 guint session_id, void *user_data)
1043 vector<void *> params;
1045 /* apply user space smack */
1046 if (_is_authorized_request(invocation) == true) {
1047 g_object_ref(object);
1048 params.push_back((void *)object);
1050 g_object_ref(invocation);
1051 params.push_back((void *)invocation);
1053 params.push_back((void *)service_id);
1054 params.push_back((void *)session_id);
1055 params.push_back(user_data);
1057 GDBusDispatcher::push(_process_get_atr, params);
1059 /* LCOV_EXCL_START */
1062 _ERR("access denied");
1064 /* response to client */
1065 smartcard_service_session_complete_get_atr(
1068 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1069 GDBusHelper::convertByteArrayToVariant(resp));
1070 /* LCOV_EXCL_STOP */
1076 static gboolean __process_open_channel(SmartcardServiceSession *object,
1077 GDBusMethodInvocation *invocation, guint service_id,
1078 guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
1080 int channelNum = -1;
1081 int result = SCARD_ERROR_UNKNOWN;
1083 GVariant *response = NULL;
1084 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
1087 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
1088 _INFO("P2 is %x", P2);
1090 ServerResource &resource = ServerResource::getInstance();
1092 name = g_dbus_method_invocation_get_sender(invocation);
1098 GDBusHelper::convertVariantToByteArray(aid,
1101 channelID = resource.createChannel(name,
1102 service_id, session_id, type, tempAid);
1103 /* LCOV_EXCL_START */
1104 if (channelID != IntegerHandle::INVALID_HANDLE) {
1105 ServerChannel *temp;
1107 temp = (ServerChannel *)resource.getChannel(
1108 name, service_id, channelID);
1110 resp = temp->getSelectResponse();
1111 channelNum = temp->getChannelNumber();
1112 result = SCARD_ERROR_OK;
1114 _ERR("getChannel is failed");
1115 result = SCARD_ERROR_UNAVAILABLE;
1118 _ERR("channel is null.");
1120 /* set error value */
1121 result = SCARD_ERROR_UNAVAILABLE;
1123 /* LCOV_EXCL_STOP */
1125 catch (ExceptionBase &e)
1127 result = e.getErrorCode();
1130 response = GDBusHelper::convertByteArrayToVariant(resp);
1132 /* response to client */
1133 smartcard_service_session_complete_open_channel(object,
1134 invocation, result, channelID, channelNum, response);
1139 static void _process_open_channel(vector<void *> ¶ms)
1141 SmartcardServiceSession *object;
1142 GDBusMethodInvocation *invocation;
1150 if (params.size() != 8) {
1151 /* LCOV_EXCL_START */
1152 _ERR("invalid parameter");
1155 /* LCOV_EXCL_STOP */
1158 object = (SmartcardServiceSession *)params[0];
1159 invocation = (GDBusMethodInvocation *)params[1];
1160 service_id = (gulong)params[2];
1161 session_id = (gulong)params[3];
1162 type = (gulong)params[4];
1163 aid = (GVariant *)params[5];
1164 P2 = (guint8)((gulong)params[6]);
1165 user_data = params[7];
1167 __process_open_channel(object, invocation, service_id,
1168 session_id, type, aid, P2, user_data);
1170 g_object_unref(object);
1171 g_object_unref(invocation);
1172 g_variant_unref(aid);
1175 static gboolean _handle_open_channel(SmartcardServiceSession *object,
1176 GDBusMethodInvocation *invocation,
1178 guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
1180 vector<void *> params;
1182 /* apply user space smack */
1183 if (_is_authorized_request(invocation) == true) {
1184 g_object_ref(object);
1185 params.push_back((void *)object);
1187 g_object_ref(invocation);
1188 params.push_back((void *)invocation);
1190 params.push_back((void *)service_id);
1191 params.push_back((void *)session_id);
1192 params.push_back((void *)type);
1195 params.push_back((void *)aid);
1196 params.push_back((void *)((int)P2));
1197 params.push_back(user_data);
1199 GDBusDispatcher::push(_process_open_channel, params);
1201 /* LCOV_EXCL_START */
1204 _ERR("access denied");
1206 /* response to client */
1207 smartcard_service_session_complete_open_channel(object,
1209 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1210 IntegerHandle::INVALID_HANDLE,
1212 GDBusHelper::convertByteArrayToVariant(resp));
1213 /* LCOV_EXCL_STOP */
1219 bool ServerGDBus::initSession()
1221 GError *error = NULL;
1223 session = smartcard_service_session_skeleton_new();
1225 g_signal_connect(session,
1226 "handle-close-session",
1227 G_CALLBACK(_handle_close_session),
1230 g_signal_connect(session,
1232 G_CALLBACK(_handle_get_atr),
1235 g_signal_connect(session,
1236 "handle-open-channel",
1237 G_CALLBACK(_handle_open_channel),
1240 if (g_dbus_interface_skeleton_export(
1241 G_DBUS_INTERFACE_SKELETON(session),
1243 "/org/tizen/SmartcardService/Session",
1246 /* LCOV_EXCL_START */
1247 _ERR("Can not skeleton_export %s", error->message);
1249 g_error_free(error);
1250 g_object_unref(session);
1254 /* LCOV_EXCL_STOP */
1260 void ServerGDBus::deinitSession()
1262 if (session != NULL) {
1263 g_object_unref(session);
1272 static gboolean __process_close_channel(SmartcardServiceChannel *object,
1273 GDBusMethodInvocation *invocation, guint service_id,
1274 guint channel_id, void *user_data)
1279 _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
1281 ServerResource &resource = ServerResource::getInstance();
1283 name = g_dbus_method_invocation_get_sender(invocation);
1285 resource.removeChannel(name, service_id, channel_id);
1287 result = SCARD_ERROR_OK;
1289 /* response to client */
1290 smartcard_service_channel_complete_close_channel(object,
1291 invocation, result);
1296 static void _process_close_channel(vector<void *> ¶ms)
1298 SmartcardServiceChannel *object;
1299 GDBusMethodInvocation *invocation;
1304 if (params.size() != 5) {
1305 /* LCOV_EXCL_START */
1306 _ERR("invalid parameter");
1309 /* LCOV_EXCL_STOP */
1312 object = (SmartcardServiceChannel *)params[0];
1313 invocation = (GDBusMethodInvocation *)params[1];
1314 service_id = (gulong)params[2];
1315 channel_id = (gulong)params[3];
1316 user_data = params[4];
1318 __process_close_channel(object, invocation, service_id,
1319 channel_id, user_data);
1321 g_object_unref(object);
1322 g_object_unref(invocation);
1325 static gboolean _handle_close_channel(SmartcardServiceChannel *object,
1326 GDBusMethodInvocation *invocation,
1327 guint service_id, guint channel_id, void *user_data)
1329 vector<void *> params;
1331 /* apply user space smack */
1332 if (_is_authorized_request(invocation) == true) {
1333 g_object_ref(object);
1334 params.push_back((void *)object);
1336 g_object_ref(invocation);
1337 params.push_back((void *)invocation);
1339 params.push_back((void *)service_id);
1340 params.push_back((void *)channel_id);
1341 params.push_back(user_data);
1343 GDBusDispatcher::push(_process_close_channel, params);
1345 /* LCOV_EXCL_START */
1346 _ERR("access denied");
1348 /* response to client */
1349 smartcard_service_channel_complete_close_channel(
1352 SCARD_ERROR_SECURITY_NOT_ALLOWED);
1353 /* LCOV_EXCL_STOP */
1359 static gboolean __process_transmit(SmartcardServiceChannel *object,
1360 GDBusMethodInvocation *invocation,
1367 Channel *channel = NULL;
1369 GVariant *response = NULL;
1372 _INFO("[MSG_REQUEST_TRANSMIT]");
1374 ServerResource &resource = ServerResource::getInstance();
1376 name = g_dbus_method_invocation_get_sender(invocation);
1378 channel = resource.getChannel(name, service_id, channel_id);
1379 /* LCOV_EXCL_START */
1380 if (channel != NULL) {
1384 GDBusHelper::convertVariantToByteArray(command, cmd);
1386 rv = channel->transmitSync(cmd, resp);
1388 result = SCARD_ERROR_OK;
1390 _ERR("transmit failed [%d]", rv);
1395 _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
1397 result = SCARD_ERROR_UNAVAILABLE;
1399 /* LCOV_EXCL_STOP */
1401 response = GDBusHelper::convertByteArrayToVariant(resp);
1403 /* response to client */
1404 smartcard_service_channel_complete_transmit(object, invocation,
1410 static void _process_transmit(vector<void *> ¶ms)
1412 SmartcardServiceChannel *object;
1413 GDBusMethodInvocation *invocation;
1419 if (params.size() != 6) {
1420 /* LCOV_EXCL_START */
1421 _ERR("invalid parameter");
1424 /* LCOV_EXCL_STOP */
1427 object = (SmartcardServiceChannel *)params[0];
1428 invocation = (GDBusMethodInvocation *)params[1];
1429 service_id = (gulong)params[2];
1430 channel_id = (gulong)params[3];
1431 command = (GVariant *)params[4];
1432 user_data = params[5];
1434 __process_transmit(object, invocation, service_id,
1435 channel_id, command, user_data);
1437 g_object_unref(object);
1438 g_object_unref(invocation);
1439 g_object_unref(command);
1442 static gboolean _handle_transmit(SmartcardServiceChannel *object,
1443 GDBusMethodInvocation *invocation,
1449 vector<void *> params;
1451 /* apply user space smack */
1452 if (_is_authorized_request(invocation) == true) {
1453 /* enqueue message */
1454 g_object_ref(object);
1455 params.push_back((void *)object);
1457 g_object_ref(invocation);
1458 params.push_back((void *)invocation);
1460 params.push_back((void *)service_id);
1461 params.push_back((void *)channel_id);
1463 g_object_ref(command);
1464 params.push_back((void *)command);
1466 params.push_back(user_data);
1468 GDBusDispatcher::push(_process_transmit, params);
1470 /* LCOV_EXCL_START */
1473 _ERR("access denied");
1475 /* response to client */
1476 smartcard_service_channel_complete_transmit(object,
1478 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1479 GDBusHelper::convertByteArrayToVariant(resp));
1480 /* LCOV_EXCL_STOP */
1486 bool ServerGDBus::initChannel()
1488 GError *error = NULL;
1490 channel = smartcard_service_channel_skeleton_new();
1492 g_signal_connect(channel,
1493 "handle-close-channel",
1494 G_CALLBACK(_handle_close_channel),
1497 g_signal_connect(channel,
1499 G_CALLBACK(_handle_transmit),
1502 if (g_dbus_interface_skeleton_export(
1503 G_DBUS_INTERFACE_SKELETON(channel),
1505 "/org/tizen/SmartcardService/Channel",
1508 /* LCOV_EXCL_START */
1509 _ERR("Can not skeleton_export %s", error->message);
1511 g_error_free(error);
1512 g_object_unref(channel);
1516 /* LCOV_EXCL_STOP */
1522 void ServerGDBus::deinitChannel()
1524 if (channel != NULL) {
1525 g_object_unref(channel);
1529 } /* namespace smartcard_service_api */