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);
707 void ServerGDBus::emitCardInserted(unsigned int reader_id,
708 const char *reader_name)
710 /* LCOV_EXCL_START */
711 smartcard_service_se_service_emit_card_inserted(
712 SMARTCARD_SERVICE_SE_SERVICE(seService),
713 reader_id, reader_name);
717 void ServerGDBus::emitCardRemoved(unsigned int reader_id,
718 const char *reader_name)
720 /* LCOV_EXCL_START */
721 smartcard_service_se_service_emit_card_removed(
722 SMARTCARD_SERVICE_SE_SERVICE(seService),
723 reader_id, reader_name);
731 static gboolean __process_open_session(SmartcardServiceReader *object,
732 GDBusMethodInvocation *invocation, guint service_id,
733 guint reader_id, void *user_data)
735 unsigned int handle = IntegerHandle::INVALID_HANDLE;
739 _INFO("[MSG_REQUEST_OPEN_SESSION]");
741 ServerResource &resource = ServerResource::getInstance();
743 name = g_dbus_method_invocation_get_sender(invocation);
745 if (resource.isValidReaderHandle(reader_id)) {
746 vector<ByteArray> temp;
748 handle = resource.createSession(name,
753 if (handle != IntegerHandle::INVALID_HANDLE) {
754 result = SCARD_ERROR_OK;
756 /* LCOV_EXCL_START */
757 _ERR("createSession failed [%d]", handle);
759 result = SCARD_ERROR_OUT_OF_MEMORY;
762 _ERR("request invalid reader handle [%d]", reader_id);
764 result = SCARD_ERROR_ILLEGAL_PARAM;
768 /* response to client */
769 smartcard_service_reader_complete_open_session(object,
770 invocation, result, handle);
775 static void _process_open_session(vector<void *> ¶ms)
777 SmartcardServiceReader *object;
778 GDBusMethodInvocation *invocation;
783 if (params.size() != 5) {
784 /* LCOV_EXCL_START */
785 _ERR("invalid parameter");
791 object = (SmartcardServiceReader *)params[0];
792 invocation = (GDBusMethodInvocation *)params[1];
793 service_id = (gulong)params[2];
794 reader_id = (gulong)params[3];
795 user_data = params[4];
797 __process_open_session(object, invocation, service_id,
798 reader_id, user_data);
800 g_object_unref(object);
801 g_object_unref(invocation);
804 static gboolean _handle_open_session(SmartcardServiceReader *object,
805 GDBusMethodInvocation *invocation,
807 guint reader_id, void *user_data)
809 vector<void *> params;
811 /* apply user space smack */
812 if (_is_authorized_request(invocation) == 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 *)reader_id);
821 params.push_back(user_data);
823 GDBusDispatcher::push(_process_open_session, params);
825 /* LCOV_EXCL_START */
826 _ERR("access denied");
828 /* response to client */
829 smartcard_service_reader_complete_open_session(object,
831 SCARD_ERROR_SECURITY_NOT_ALLOWED,
832 IntegerHandle::INVALID_HANDLE);
839 bool ServerGDBus::initReader()
841 GError *error = NULL;
843 reader = smartcard_service_reader_skeleton_new();
845 g_signal_connect(reader,
846 "handle-open-session",
847 G_CALLBACK(_handle_open_session),
850 if (g_dbus_interface_skeleton_export(
851 G_DBUS_INTERFACE_SKELETON(reader),
853 "/org/tizen/SmartcardService/Reader",
856 /* LCOV_EXCL_START */
857 _ERR("Can not skeleton_export %s", error->message);
860 g_object_unref(reader);
870 void ServerGDBus::deinitReader()
872 /* LCOV_EXCL_START */
873 if (reader != NULL) {
874 g_object_unref(reader);
884 static gboolean __process_close_session(SmartcardServiceSession *object,
885 GDBusMethodInvocation *invocation, guint service_id,
886 guint session_id, void *user_data)
890 _INFO("[MSG_REQUEST_CLOSE_SESSION]");
892 ServerResource &resource = ServerResource::getInstance();
894 name = g_dbus_method_invocation_get_sender(invocation);
896 if (resource.isValidSessionHandle(name, service_id,
898 resource.removeSession(name, service_id,
901 _ERR("invalid parameters"); //LCOV_EXCL_LINE
904 /* response to client */
905 smartcard_service_session_complete_close_session(object,
906 invocation, SCARD_ERROR_OK);
911 static void _process_close_session(vector<void *> ¶ms)
913 SmartcardServiceSession *object;
914 GDBusMethodInvocation *invocation;
919 if (params.size() != 5) {
920 /* LCOV_EXCL_START */
921 _ERR("invalid parameter");
927 object = (SmartcardServiceSession *)params[0];
928 invocation = (GDBusMethodInvocation *)params[1];
929 service_id = (gulong)params[2];
930 session_id = (gulong)params[3];
931 user_data = params[4];
933 __process_close_session(object, invocation, service_id,
934 session_id, user_data);
936 g_object_unref(object);
937 g_object_unref(invocation);
940 static gboolean _handle_close_session(SmartcardServiceSession *object,
941 GDBusMethodInvocation *invocation,
943 guint session_id, void *user_data)
945 vector<void *> params;
947 /* apply user space smack */
948 if (_is_authorized_request(invocation) == true) {
949 g_object_ref(object);
950 params.push_back((void *)object);
952 g_object_ref(invocation);
953 params.push_back((void *)invocation);
955 params.push_back((void *)service_id);
956 params.push_back((void *)session_id);
957 params.push_back(user_data);
959 GDBusDispatcher::push(_process_close_session, params);
961 /* LCOV_EXCL_START */
962 _ERR("access denied");
964 /* response to client */
965 smartcard_service_session_complete_close_session(object,
966 invocation, SCARD_ERROR_SECURITY_NOT_ALLOWED);
973 static gboolean __process_get_atr(SmartcardServiceSession *object,
974 GDBusMethodInvocation *invocation, guint service_id,
975 guint session_id, void *user_data)
979 GVariant *atr = NULL;
981 ServiceInstance *client = NULL;
983 _INFO("[MSG_REQUEST_GET_ATR]");
985 ServerResource &resource = ServerResource::getInstance();
987 name = g_dbus_method_invocation_get_sender(invocation);
989 client = resource.getService(name, service_id);
990 /* LCOV_EXCL_START */
991 if (client != NULL) {
994 terminal = client->getTerminal(session_id);
995 if (terminal != NULL) {
996 if (terminal->open() == true) {
997 result = terminal->getATRSync(resp);
998 if (result < SCARD_ERROR_OK) {
999 _ERR("getATRSync failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
1004 _ERR("terminal->open failed");
1006 result = SCARD_ERROR_UNAVAILABLE;
1009 _ERR("getTerminal failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
1011 result = SCARD_ERROR_UNAVAILABLE;
1014 _ERR("getClient failed : name [%s], service_id [%d], session_id [%d]", name, service_id, session_id);
1016 result = SCARD_ERROR_UNAVAILABLE;
1018 /* LCOV_EXCL_STOP */
1020 atr = GDBusHelper::convertByteArrayToVariant(resp);
1022 /* response to client */
1023 smartcard_service_session_complete_get_atr(object, invocation,
1029 static void _process_get_atr(vector<void *> ¶ms)
1031 SmartcardServiceSession *object;
1032 GDBusMethodInvocation *invocation;
1037 if (params.size() != 5) {
1038 /* LCOV_EXCL_START */
1039 _ERR("invalid parameter");
1042 /* LCOV_EXCL_STOP */
1045 object = (SmartcardServiceSession *)params[0];
1046 invocation = (GDBusMethodInvocation *)params[1];
1047 service_id = (gulong)params[2];
1048 session_id = (gulong)params[3];
1049 user_data = params[4];
1051 __process_get_atr(object, invocation, service_id,
1052 session_id, user_data);
1054 g_object_unref(object);
1055 g_object_unref(invocation);
1058 static gboolean _handle_get_atr(SmartcardServiceSession *object,
1059 GDBusMethodInvocation *invocation,
1061 guint session_id, void *user_data)
1063 vector<void *> params;
1065 /* apply user space smack */
1066 if (_is_authorized_request(invocation) == true) {
1067 g_object_ref(object);
1068 params.push_back((void *)object);
1070 g_object_ref(invocation);
1071 params.push_back((void *)invocation);
1073 params.push_back((void *)service_id);
1074 params.push_back((void *)session_id);
1075 params.push_back(user_data);
1077 GDBusDispatcher::push(_process_get_atr, params);
1079 /* LCOV_EXCL_START */
1082 _ERR("access denied");
1084 /* response to client */
1085 smartcard_service_session_complete_get_atr(
1088 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1089 GDBusHelper::convertByteArrayToVariant(resp));
1090 /* LCOV_EXCL_STOP */
1096 static gboolean __process_open_channel(SmartcardServiceSession *object,
1097 GDBusMethodInvocation *invocation, guint service_id,
1098 guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
1100 int channelNum = -1;
1101 int result = SCARD_ERROR_UNKNOWN;
1103 GVariant *response = NULL;
1104 unsigned int channelID = IntegerHandle::INVALID_HANDLE;
1107 _INFO("[MSG_REQUEST_OPEN_CHANNEL]");
1108 _INFO("P2 is %x", P2);
1110 ServerResource &resource = ServerResource::getInstance();
1112 name = g_dbus_method_invocation_get_sender(invocation);
1118 GDBusHelper::convertVariantToByteArray(aid,
1121 channelID = resource.createChannel(name,
1122 service_id, session_id, type, tempAid);
1123 /* LCOV_EXCL_START */
1124 if (channelID != IntegerHandle::INVALID_HANDLE) {
1125 ServerChannel *temp;
1127 temp = (ServerChannel *)resource.getChannel(
1128 name, service_id, channelID);
1130 resp = temp->getSelectResponse();
1131 channelNum = temp->getChannelNumber();
1132 result = SCARD_ERROR_OK;
1134 _ERR("getChannel is failed");
1135 result = SCARD_ERROR_UNAVAILABLE;
1138 _ERR("channel is null.");
1140 /* set error value */
1141 result = SCARD_ERROR_UNAVAILABLE;
1143 /* LCOV_EXCL_STOP */
1145 catch (ExceptionBase &e)
1147 result = e.getErrorCode();
1150 response = GDBusHelper::convertByteArrayToVariant(resp);
1152 /* response to client */
1153 smartcard_service_session_complete_open_channel(object,
1154 invocation, result, channelID, channelNum, response);
1159 static void _process_open_channel(vector<void *> ¶ms)
1161 SmartcardServiceSession *object;
1162 GDBusMethodInvocation *invocation;
1170 if (params.size() != 8) {
1171 /* LCOV_EXCL_START */
1172 _ERR("invalid parameter");
1175 /* LCOV_EXCL_STOP */
1178 object = (SmartcardServiceSession *)params[0];
1179 invocation = (GDBusMethodInvocation *)params[1];
1180 service_id = (gulong)params[2];
1181 session_id = (gulong)params[3];
1182 type = (gulong)params[4];
1183 aid = (GVariant *)params[5];
1184 P2 = (guint8)((gulong)params[6]);
1185 user_data = params[7];
1187 __process_open_channel(object, invocation, service_id,
1188 session_id, type, aid, P2, user_data);
1190 g_object_unref(object);
1191 g_object_unref(invocation);
1192 g_variant_unref(aid);
1195 static gboolean _handle_open_channel(SmartcardServiceSession *object,
1196 GDBusMethodInvocation *invocation,
1198 guint session_id, guint type, GVariant *aid, guint8 P2, void *user_data)
1200 vector<void *> params;
1202 /* apply user space smack */
1203 if (_is_authorized_request(invocation) == true) {
1204 g_object_ref(object);
1205 params.push_back((void *)object);
1207 g_object_ref(invocation);
1208 params.push_back((void *)invocation);
1210 params.push_back((void *)service_id);
1211 params.push_back((void *)session_id);
1212 params.push_back((void *)type);
1215 params.push_back((void *)aid);
1216 params.push_back((void *)((int)P2));
1217 params.push_back(user_data);
1219 GDBusDispatcher::push(_process_open_channel, params);
1221 /* LCOV_EXCL_START */
1224 _ERR("access denied");
1226 /* response to client */
1227 smartcard_service_session_complete_open_channel(object,
1229 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1230 IntegerHandle::INVALID_HANDLE,
1232 GDBusHelper::convertByteArrayToVariant(resp));
1233 /* LCOV_EXCL_STOP */
1239 bool ServerGDBus::initSession()
1241 GError *error = NULL;
1243 session = smartcard_service_session_skeleton_new();
1245 g_signal_connect(session,
1246 "handle-close-session",
1247 G_CALLBACK(_handle_close_session),
1250 g_signal_connect(session,
1252 G_CALLBACK(_handle_get_atr),
1255 g_signal_connect(session,
1256 "handle-open-channel",
1257 G_CALLBACK(_handle_open_channel),
1260 if (g_dbus_interface_skeleton_export(
1261 G_DBUS_INTERFACE_SKELETON(session),
1263 "/org/tizen/SmartcardService/Session",
1266 /* LCOV_EXCL_START */
1267 _ERR("Can not skeleton_export %s", error->message);
1269 g_error_free(error);
1270 g_object_unref(session);
1274 /* LCOV_EXCL_STOP */
1280 void ServerGDBus::deinitSession()
1282 if (session != NULL) {
1283 g_object_unref(session);
1292 static gboolean __process_close_channel(SmartcardServiceChannel *object,
1293 GDBusMethodInvocation *invocation, guint service_id,
1294 guint channel_id, void *user_data)
1299 _INFO("[MSG_REQUEST_CLOSE_CHANNEL]");
1301 ServerResource &resource = ServerResource::getInstance();
1303 name = g_dbus_method_invocation_get_sender(invocation);
1305 resource.removeChannel(name, service_id, channel_id);
1307 result = SCARD_ERROR_OK;
1309 /* response to client */
1310 smartcard_service_channel_complete_close_channel(object,
1311 invocation, result);
1316 static void _process_close_channel(vector<void *> ¶ms)
1318 SmartcardServiceChannel *object;
1319 GDBusMethodInvocation *invocation;
1324 if (params.size() != 5) {
1325 /* LCOV_EXCL_START */
1326 _ERR("invalid parameter");
1329 /* LCOV_EXCL_STOP */
1332 object = (SmartcardServiceChannel *)params[0];
1333 invocation = (GDBusMethodInvocation *)params[1];
1334 service_id = (gulong)params[2];
1335 channel_id = (gulong)params[3];
1336 user_data = params[4];
1338 __process_close_channel(object, invocation, service_id,
1339 channel_id, user_data);
1341 g_object_unref(object);
1342 g_object_unref(invocation);
1345 static gboolean _handle_close_channel(SmartcardServiceChannel *object,
1346 GDBusMethodInvocation *invocation,
1347 guint service_id, guint channel_id, void *user_data)
1349 vector<void *> params;
1351 /* apply user space smack */
1352 if (_is_authorized_request(invocation) == true) {
1353 g_object_ref(object);
1354 params.push_back((void *)object);
1356 g_object_ref(invocation);
1357 params.push_back((void *)invocation);
1359 params.push_back((void *)service_id);
1360 params.push_back((void *)channel_id);
1361 params.push_back(user_data);
1363 GDBusDispatcher::push(_process_close_channel, params);
1365 /* LCOV_EXCL_START */
1366 _ERR("access denied");
1368 /* response to client */
1369 smartcard_service_channel_complete_close_channel(
1372 SCARD_ERROR_SECURITY_NOT_ALLOWED);
1373 /* LCOV_EXCL_STOP */
1379 static gboolean __process_transmit(SmartcardServiceChannel *object,
1380 GDBusMethodInvocation *invocation,
1387 Channel *channel = NULL;
1389 GVariant *response = NULL;
1392 _INFO("[MSG_REQUEST_TRANSMIT]");
1394 ServerResource &resource = ServerResource::getInstance();
1396 name = g_dbus_method_invocation_get_sender(invocation);
1398 channel = resource.getChannel(name, service_id, channel_id);
1399 /* LCOV_EXCL_START */
1400 if (channel != NULL) {
1404 GDBusHelper::convertVariantToByteArray(command, cmd);
1406 rv = channel->transmitSync(cmd, resp);
1408 result = SCARD_ERROR_OK;
1410 _ERR("transmit failed [%d]", rv);
1415 _ERR("invalid handle : name [%s], service_id [%d], channel_id [%d]", name, service_id, channel_id);
1417 result = SCARD_ERROR_UNAVAILABLE;
1419 /* LCOV_EXCL_STOP */
1421 response = GDBusHelper::convertByteArrayToVariant(resp);
1423 /* response to client */
1424 smartcard_service_channel_complete_transmit(object, invocation,
1430 static void _process_transmit(vector<void *> ¶ms)
1432 SmartcardServiceChannel *object;
1433 GDBusMethodInvocation *invocation;
1439 if (params.size() != 6) {
1440 /* LCOV_EXCL_START */
1441 _ERR("invalid parameter");
1444 /* LCOV_EXCL_STOP */
1447 object = (SmartcardServiceChannel *)params[0];
1448 invocation = (GDBusMethodInvocation *)params[1];
1449 service_id = (gulong)params[2];
1450 channel_id = (gulong)params[3];
1451 command = (GVariant *)params[4];
1452 user_data = params[5];
1454 __process_transmit(object, invocation, service_id,
1455 channel_id, command, user_data);
1457 g_object_unref(object);
1458 g_object_unref(invocation);
1459 g_object_unref(command);
1462 static GVariant *_copy_variant(GVariant *src)
1464 GVariantBuilder builder;
1470 g_variant_get(src, "a(y)", &iter);
1472 g_variant_builder_init(&builder, G_VARIANT_TYPE("a(y)"));
1474 for (i = 0; g_variant_iter_loop(iter, "(y)", &element); i++) {
1475 g_variant_builder_add(&builder, "(y)", element);
1478 g_variant_iter_free(iter);
1480 return g_variant_builder_end(&builder);
1483 static gboolean _handle_transmit(SmartcardServiceChannel *object,
1484 GDBusMethodInvocation *invocation,
1490 vector<void *> params;
1493 _command = _copy_variant(command);
1495 /* apply user space smack */
1496 if (_is_authorized_request(invocation) == true) {
1497 /* enqueue message */
1498 g_object_ref(object);
1499 params.push_back((void *)object);
1501 g_object_ref(invocation);
1502 params.push_back((void *)invocation);
1504 params.push_back((void *)service_id);
1505 params.push_back((void *)channel_id);
1507 g_object_ref(_command);
1508 params.push_back((void *)_command);
1510 params.push_back(user_data);
1512 GDBusDispatcher::push(_process_transmit, params);
1514 /* LCOV_EXCL_START */
1517 _ERR("access denied");
1519 /* response to client */
1520 smartcard_service_channel_complete_transmit(object,
1522 SCARD_ERROR_SECURITY_NOT_ALLOWED,
1523 GDBusHelper::convertByteArrayToVariant(resp));
1524 /* LCOV_EXCL_STOP */
1530 bool ServerGDBus::initChannel()
1532 GError *error = NULL;
1534 channel = smartcard_service_channel_skeleton_new();
1536 g_signal_connect(channel,
1537 "handle-close-channel",
1538 G_CALLBACK(_handle_close_channel),
1541 g_signal_connect(channel,
1543 G_CALLBACK(_handle_transmit),
1546 if (g_dbus_interface_skeleton_export(
1547 G_DBUS_INTERFACE_SKELETON(channel),
1549 "/org/tizen/SmartcardService/Channel",
1552 /* LCOV_EXCL_START */
1553 _ERR("Can not skeleton_export %s", error->message);
1555 g_error_free(error);
1556 g_object_unref(channel);
1560 /* LCOV_EXCL_STOP */
1566 void ServerGDBus::deinitChannel()
1568 if (channel != NULL) {
1569 g_object_unref(channel);
1573 } /* namespace smartcard_service_api */