More changes about using gdbus
[platform/core/connectivity/smartcard-service.git] / server / ServerResource.cpp
1 /*
2  * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 /* standard library header */
18 #include <stdio.h>
19 #include <string.h>
20 #include <dlfcn.h>
21 #include <errno.h>
22 #include <dirent.h>
23
24 /* SLP library header */
25
26 /* local header */
27 #include "Debug.h"
28 #include "ServerResource.h"
29 #include "TerminalInterface.h"
30 #include "APDUHelper.h"
31 #include "SignatureHelper.h"
32 #include "GPACE.h"
33 #include "PKCS15.h"
34 #ifdef USE_GDBUS
35 #include "ServerGDBus.h"
36 #endif
37
38 #ifndef EXTERN_API
39 #define EXTERN_API __attribute__((visibility("default")))
40 #endif
41
42 using namespace std;
43
44 namespace smartcard_service_api
45 {
46         unsigned int IntegerHandle::newHandle = 0;
47         set<unsigned int> IntegerHandle::setHandles;
48         PMutex IntegerHandle::mutexLock;
49
50         unsigned int IntegerHandle::assignHandle()
51         {
52                 SCOPE_LOCK(mutexLock)
53                 {
54                         pair<set<unsigned int>::iterator, bool> result;
55
56                         do
57                         {
58                                 newHandle++;
59                                 if (newHandle == (unsigned int)-1)
60                                 {
61                                         newHandle = 1;
62                                 }
63
64                                 result = setHandles.insert(newHandle);
65
66                         }
67                         while (!result.second);
68                 }
69
70                 _DBG("assign handle : newHandle [%d]", newHandle);
71
72                 return newHandle;
73         }
74
75         void IntegerHandle::releaseHandle(unsigned int handle)
76         {
77                 _DBG("will be released : Handle [%d]", handle);
78
79                 SCOPE_LOCK(mutexLock)
80                 {
81                         setHandles.erase(handle);
82                 }
83         }
84
85 #define OMAPI_SE_PATH "/usr/lib/se"
86
87         ServerResource::ServerResource()
88                 : mainLoop(NULL), seLoaded(false)
89         {
90                 _BEGIN();
91 #ifndef USE_GDBUS
92                 serverIPC = ServerIPC::getInstance();
93                 serverDispatcher = ServerDispatcher::getInstance();
94 #endif
95                 _END();
96         }
97
98         ServerResource::~ServerResource()
99         {
100         }
101
102         ServerResource &ServerResource::getInstance()
103         {
104                 static ServerResource serverResource;
105
106                 return serverResource;
107         }
108
109 #ifdef USE_GDBUS
110         bool ServerResource::createClient(const char *name, pid_t pid)
111         {
112                 bool result = false;
113
114                 if (getClient(name) == NULL)
115                 {
116                         ClientInstance *instance = new ClientInstance(name, pid);
117                         if (instance != NULL)
118                         {
119                                 mapClients.insert(make_pair(name, instance));
120                                 result = true;
121                         }
122                         else
123                         {
124                                 _ERR("alloc failed");
125                         }
126                 }
127                 else
128                 {
129                         _ERR("client already exist, name [%s]", name);
130                 }
131
132                 return result;
133         }
134
135         ClientInstance *ServerResource::getClient(const char *name)
136         {
137                 ClientInstance *result = NULL;
138                 map<string, ClientInstance *>::iterator item;
139
140                 if ((item = mapClients.find(name)) != mapClients.end())
141                 {
142                         result = item->second;
143                 }
144
145                 return result;
146         }
147
148         void ServerResource::removeClient(const char *name)
149         {
150                 map<string, ClientInstance *>::iterator item;
151
152                 if ((item = mapClients.find(name)) != mapClients.end())
153                 {
154                         delete item->second;
155                         mapClients.erase(item);
156                 }
157                 else
158                 {
159                         _DBG("client removed already, name [%s]", name);
160                 }
161         }
162
163         void ServerResource::removeClients()
164         {
165                 map<string, ClientInstance *>::iterator item;
166
167                 for (item = mapClients.begin(); item != mapClients.end(); item++)
168                 {
169                         delete item->second;
170                 }
171
172                 mapClients.clear();
173         }
174
175         int ServerResource::getClientCount()
176         {
177                 return (int)mapClients.size();
178         }
179
180         ServiceInstance *ServerResource::createService(const char *name)
181         {
182                 ServiceInstance *result = NULL;
183                 ClientInstance *instance = NULL;
184
185                 if ((instance = getClient(name)) != NULL)
186                 {
187                         if ((result = instance->createService()) == NULL)
188                         {
189                                 _ERR("ClientInstance::createService failed [%d]", name);
190                         }
191                 }
192                 else
193                 {
194                         _ERR("client doesn't exist, name [%s]", name);
195                 }
196
197                 return result;
198         }
199
200         ServiceInstance *ServerResource::getService(const char *name, unsigned int handle)
201         {
202                 ServiceInstance *result = NULL;
203                 ClientInstance *instance = NULL;
204
205                 if ((instance = getClient(name)) != NULL)
206                 {
207                         result = instance->getService(handle);
208                 }
209                 else
210                 {
211                         _ERR("client doesn't exist, name [%s]", name);
212                 }
213
214                 return result;
215         }
216
217         void ServerResource::removeService(const char *name, unsigned int handle)
218         {
219                 ClientInstance *instance = NULL;
220
221                 if ((instance = getClient(name)) != NULL)
222                 {
223                         instance->removeService(handle);
224                 }
225                 else
226                 {
227                         _ERR("client doesn't exist, name [%s]", name);
228                 }
229         }
230
231         void ServerResource::removeServices(const char *name)
232         {
233                 ClientInstance *instance = NULL;
234
235                 if ((instance = getClient(name)) != NULL)
236                 {
237                         instance->removeServices();
238                 }
239                 else
240                 {
241                         _ERR("client doesn't exist, name [%s]", name);
242                 }
243         }
244
245         unsigned int ServerResource::createSession(const char *name, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
246         {
247                 unsigned int result = -1;
248                 Terminal *temp = NULL;
249                 ServiceInstance *instance = NULL;
250
251                 if ((instance = getService(name, handle)) != NULL)
252                 {
253                         if ((temp = getTerminalByReaderID(readerID)) != NULL)
254                         {
255                                 result = instance->openSession(temp, certHashes, caller);
256                         }
257                 }
258                 else
259                 {
260                         _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
261                 }
262
263                 return result;
264         }
265
266         ServerSession *ServerResource::getSession(const char *name, unsigned int handle, unsigned int sessionID)
267         {
268                 ServerSession *result = NULL;
269                 ServiceInstance *instance = NULL;
270
271                 if ((instance = getService(name, handle)) != NULL)
272                 {
273                         result = instance->getSession(sessionID);
274                 }
275                 else
276                 {
277                         _ERR("Session doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, sessionID);
278                 }
279
280                 return result;
281         }
282
283         bool ServerResource::isValidSessionHandle(const char *name, unsigned int handle, unsigned int session)
284         {
285                 ServiceInstance *instance = NULL;
286
287                 return (((instance = getService(name, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
288         }
289
290         unsigned int ServerResource::getChannelCount(const char *name, unsigned int handle, unsigned int sessionID)
291         {
292                 unsigned int result = -1;
293                 ServiceInstance *instance = NULL;
294
295                 if ((instance = getService(name, handle)) != NULL)
296                 {
297                         result = instance->getChannelCountBySession(sessionID);
298                 }
299                 else
300                 {
301                         _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
302                 }
303
304                 return result;
305         }
306
307         void ServerResource::removeSession(const char *name, unsigned int handle, unsigned int sessionID)
308         {
309                 ServiceInstance *instance = NULL;
310
311                 if ((instance = getService(name, handle)) != NULL)
312                 {
313                         instance->closeSession(sessionID);
314                 }
315                 else
316                 {
317                         _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
318                 }
319         }
320
321         unsigned int ServerResource::createChannel(const char *name, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
322                 throw(ExceptionBase &)
323         {
324                 unsigned int result = -1;
325                 ServiceInstance *service = NULL;
326
327                 if ((service = getService(name, handle)) != NULL)
328                 {
329                         if (service->isVaildSessionHandle(sessionID) == true)
330                         {
331                                 ServerSession *session = NULL;
332                                 Terminal *terminal = NULL;
333
334                                 terminal = service->getTerminal(sessionID);
335                                 session = service->getSession(sessionID);
336                                 if (terminal != NULL && session != NULL)
337                                 {
338                                         result = _createChannel(terminal, service, channelType, sessionID, aid);
339                                         if (result == IntegerHandle::INVALID_HANDLE)
340                                         {
341                                                 _ERR("create channel failed [%d]", sessionID);
342                                         }
343                                 }
344                                 else
345                                 {
346                                         _ERR("session is invalid [%d]", sessionID);
347                                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
348                                 }
349                         }
350                         else
351                         {
352                                 _ERR("session is invalid [%d]", sessionID);
353                                 throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
354                         }
355                 }
356                 else
357                 {
358                         _ERR("getService is failed, name [%s], handle [%d]", name, handle);
359                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
360                 }
361
362                 return result;
363         }
364
365         Channel *ServerResource::getChannel(const char *name, unsigned int handle, unsigned int channelID)
366         {
367                 Channel *result = NULL;
368                 ServiceInstance *instance = NULL;
369
370                 if ((instance = getService(name, handle)) != NULL)
371                 {
372                         result = instance->getChannel(channelID);
373                 }
374                 else
375                 {
376                         _ERR("Channel doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, channelID);
377                 }
378
379                 return result;
380         }
381
382         void ServerResource::removeChannel(const char *name, unsigned int handle, unsigned int channelID)
383         {
384                 ServiceInstance *instance = NULL;
385
386                 if ((instance = getService(name, handle)) != NULL)
387                 {
388                         instance->closeChannel(channelID);
389                 }
390                 else
391                 {
392                         _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
393                 }
394         }
395 #else
396         bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
397         {
398                 bool result = false;
399
400                 if (getClient(socket) == NULL)
401                 {
402                         ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
403                         if (instance != NULL)
404                         {
405                                 mapClients.insert(make_pair(socket, instance));
406                                 result = true;
407                         }
408                         else
409                         {
410                                 _ERR("alloc failed");
411                         }
412                 }
413                 else
414                 {
415                         _ERR("client already exist, socket[%d]", socket);
416                 }
417
418                 return result;
419         }
420
421         bool ServerResource::createClient(int pid)
422         {
423                 bool result = false;
424
425                 if (getClient(pid) == NULL)
426                 {
427                         ClientInstance *instance = new ClientInstance(pid);
428                         if (instance != NULL)
429                         {
430                                 mapClients.insert(make_pair(pid, instance));
431                                 result = true;
432                         }
433                         else
434                         {
435                                 _ERR("alloc failed");
436                         }
437                 }
438                 else
439                 {
440                         _ERR("client already exist, pid[%d]", pid);
441                 }
442
443                 return result;
444         }
445
446         ClientInstance *ServerResource::getClient(int socket)
447         {
448                 ClientInstance *result = NULL;
449                 map<int, ClientInstance *>::iterator item;
450
451                 if ((item = mapClients.find(socket)) != mapClients.end())
452                 {
453                         result = item->second;
454                 }
455
456                 return result;
457         }
458
459         void ServerResource::setPID(int socket, int pid)
460         {
461                 map<int, ClientInstance *>::iterator item;
462
463                 if ((item = mapClients.find(socket)) != mapClients.end())
464                 {
465                         if (item->second->getPID() < 0)
466                                 item->second->setPID(pid);
467                 }
468         }
469
470         void ServerResource::removeClient(int socket)
471         {
472                 map<int, ClientInstance *>::iterator item;
473
474                 if ((item = mapClients.find(socket)) != mapClients.end())
475                 {
476 #ifndef USE_GDBUS
477                         ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
478 #endif
479                         delete item->second;
480                         mapClients.erase(item);
481                 }
482                 else
483                 {
484                         _DBG("client removed already [%d]", socket);
485                 }
486         }
487
488         void ServerResource::removeClients()
489         {
490                 map<int, ClientInstance *>::iterator item;
491
492                 for (item = mapClients.begin(); item != mapClients.end(); item++)
493                 {
494 #ifndef USE_GDBUS
495                         ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
496 #endif
497                         delete item->second;
498                 }
499
500                 mapClients.clear();
501         }
502
503         int ServerResource::getClientCount()
504         {
505                 return (int)mapClients.size();
506         }
507
508         ServiceInstance *ServerResource::createService(int socket)
509         {
510                 ServiceInstance *result = NULL;
511                 ClientInstance *instance = NULL;
512
513                 if ((instance = getClient(socket)) != NULL)
514                 {
515                         if ((result = instance->createService()) == NULL)
516                         {
517                                 _ERR("ClientInstance::createService failed [%d]", socket);
518                         }
519                 }
520                 else
521                 {
522                         _ERR("client doesn't exist [%d]", socket);
523                 }
524
525                 return result;
526         }
527
528         ServiceInstance *ServerResource::getService(int socket, unsigned int handle)
529         {
530                 ServiceInstance *result = NULL;
531                 ClientInstance *instance = NULL;
532
533                 if ((instance = getClient(socket)) != NULL)
534                 {
535                         result = instance->getService(handle);
536                 }
537                 else
538                 {
539                         _ERR("client doesn't exist [%d]", socket);
540                 }
541
542                 return result;
543         }
544
545         void ServerResource::removeService(int socket, unsigned int handle)
546         {
547                 ClientInstance *instance = NULL;
548
549                 if ((instance = getClient(socket)) != NULL)
550                 {
551                         instance->removeService(handle);
552                 }
553                 else
554                 {
555                         _ERR("client doesn't exist [%d]", socket);
556                 }
557         }
558
559         void ServerResource::removeServices(int socket)
560         {
561                 ClientInstance *instance = NULL;
562
563                 if ((instance = getClient(socket)) != NULL)
564                 {
565                         instance->removeServices();
566                 }
567                 else
568                 {
569                         _ERR("client doesn't exist [%d]", socket);
570                 }
571         }
572
573         unsigned int ServerResource::createSession(int socket, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
574         {
575                 unsigned int result = -1;
576                 Terminal *temp = NULL;
577                 ServiceInstance *instance = NULL;
578
579                 if ((instance = getService(socket, handle)) != NULL)
580                 {
581                         if ((temp = getTerminalByReaderID(readerID)) != NULL)
582                         {
583                                 result = instance->openSession(temp, certHashes, caller);
584                         }
585                 }
586                 else
587                 {
588                         _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
589                 }
590
591                 return result;
592         }
593
594         ServerSession *ServerResource::getSession(int socket, unsigned int handle, unsigned int sessionID)
595         {
596                 ServerSession *result = NULL;
597                 ServiceInstance *instance = NULL;
598
599                 if ((instance = getService(socket, handle)) != NULL)
600                 {
601                         result = instance->getSession(sessionID);
602                 }
603                 else
604                 {
605                         _ERR("Session doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, sessionID);
606                 }
607
608                 return result;
609         }
610
611         bool ServerResource::isValidSessionHandle(int socket, unsigned int handle, unsigned int session)
612         {
613                 ServiceInstance *instance = NULL;
614
615                 return (((instance = getService(socket, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
616         }
617
618         unsigned int ServerResource::getChannelCount(int socket, unsigned int handle, unsigned int sessionID)
619         {
620                 unsigned int result = -1;
621                 ServiceInstance *instance = NULL;
622
623                 if ((instance = getService(socket, handle)) != NULL)
624                 {
625                         result = instance->getChannelCountBySession(sessionID);
626                 }
627                 else
628                 {
629                         _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
630                 }
631
632                 return result;
633         }
634
635         void ServerResource::removeSession(int socket, unsigned int handle, unsigned int sessionID)
636         {
637                 ServiceInstance *instance = NULL;
638
639                 if ((instance = getService(socket, handle)) != NULL)
640                 {
641                         instance->closeSession(sessionID);
642                 }
643                 else
644                 {
645                         _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
646                 }
647         }
648
649         unsigned int ServerResource::createChannel(int socket, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
650                 throw(ExceptionBase &)
651         {
652                 unsigned int result = -1;
653                 ServiceInstance *service = NULL;
654
655                 if ((service = getService(socket, handle)) != NULL)
656                 {
657                         if (service->isVaildSessionHandle(sessionID) == true)
658                         {
659                                 ServerSession *session = NULL;
660                                 Terminal *terminal = NULL;
661
662                                 terminal = service->getTerminal(sessionID);
663                                 session = service->getSession(sessionID);
664                                 if (terminal != NULL && session != NULL)
665                                 {
666                                         result = _createChannel(terminal, service, channelType, sessionID, aid);
667                                         if (result == IntegerHandle::INVALID_HANDLE)
668                                         {
669                                                 _ERR("create channel failed [%d]", sessionID);
670                                         }
671                                 }
672                                 else
673                                 {
674                                         _ERR("session is invalid [%d]", sessionID);
675                                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
676                                 }
677                         }
678                         else
679                         {
680                                 _ERR("session is invalid [%d]", sessionID);
681                                 throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
682                         }
683                 }
684                 else
685                 {
686                         _ERR("getService is failed [%d] [%d]", socket, handle);
687                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
688                 }
689
690                 return result;
691         }
692
693         Channel *ServerResource::getChannel(int socket, unsigned int handle, unsigned int channelID)
694         {
695                 Channel *result = NULL;
696                 ServiceInstance *instance = NULL;
697
698                 if ((instance = getService(socket, handle)) != NULL)
699                 {
700                         result = instance->getChannel(channelID);
701                 }
702                 else
703                 {
704                         _ERR("Channel doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, channelID);
705                 }
706
707                 return result;
708         }
709
710         void ServerResource::removeChannel(int socket, unsigned int handle, unsigned int channelID)
711         {
712                 ServiceInstance *instance = NULL;
713
714                 if ((instance = getService(socket, handle)) != NULL)
715                 {
716                         instance->closeChannel(channelID);
717                 }
718                 else
719                 {
720                         _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
721                 }
722         }
723 #endif
724         Terminal *ServerResource::getTerminal(unsigned int terminalID)
725         {
726                 Terminal *result = NULL;
727                 map<unsigned int, Terminal *>::iterator item;
728
729                 if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
730                 {
731                         result = item->second;
732                 }
733                 else
734                 {
735                         _ERR("Terminal doesn't exist [%d]", terminalID);
736                 }
737
738                 return result;
739         }
740
741         Terminal *ServerResource::getTerminal(const char *name)
742         {
743                 Terminal *result = NULL;
744                 map<unsigned int, Terminal *>::iterator item;
745
746                 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
747                 {
748                         if (strncmp(name, item->second->getName(), strlen(name)) == 0)
749                         {
750                                 result = item->second;
751                                 break;
752                         }
753                 }
754
755                 return result;
756         }
757
758         Terminal *ServerResource::getTerminalByIndex(int index)
759         {
760                 int count = 0;
761                 Terminal *result = NULL;
762                 map<unsigned int, Terminal *>::iterator item;
763
764                 for (item = mapTerminals.begin(), count = 0; item != mapTerminals.end(); item++, count++) {
765                         if (count == index) {
766                                 result = item->second;
767                                 break;
768                         }
769                 }
770
771                 return result;
772         }
773
774         Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
775         {
776                 Terminal *result = NULL;
777                 map<unsigned int, unsigned int>::iterator item;
778
779                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
780                 {
781                         result = getTerminal(item->second);
782                 }
783                 else
784                 {
785                         _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
786                 }
787
788                 return result;
789         }
790
791         unsigned int ServerResource::getTerminalID(const char *name)
792         {
793                 unsigned int result = IntegerHandle::INVALID_HANDLE;
794                 map<unsigned int, Terminal *>::iterator item;
795
796                 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
797                 {
798                         if (strncmp(name, item->second->getName(), strlen(name)) == 0)
799                         {
800                                 result = item->first;
801                                 break;
802                         }
803                 }
804
805                 return result;
806         }
807
808         bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, ByteArray aid, vector<ByteArray> &hashes)
809         {
810                 bool result = true;
811                 AccessControlList *acList = NULL;
812
813                 /* request open channel sequence */
814                 if ((acList = getAccessControlList(channel)) == NULL)
815                 {
816                         /* load access control defined by Global Platform */
817                         GPACE *acl = new GPACE();
818                         if (acl != NULL)
819                         {
820                                 int ret;
821
822                                 ret = acl->loadACL(channel);
823                                 if (ret >= SCARD_ERROR_OK)
824                                 {
825                                         acList = acl;
826                                         addAccessControlList(channel, acList);
827                                 }
828                                 else
829                                 {
830                                         _ERR("unknown error, 0x%x", -ret);
831                                         delete acl;
832                                 }
833                         }
834                         else
835                         {
836                                 _ERR("alloc failed");
837                         }
838                 }
839                 else
840                 {
841                         acList->loadACL(channel);
842                 }
843
844                 if (acList != NULL)
845                 {
846                         result = acList->isAuthorizedAccess(aid, hashes);
847                 }
848
849                 return result;
850         }
851
852         int ServerResource::_openLogicalChannel(Terminal *terminal)
853         {
854                 int result = -1;
855                 int rv = 0;
856                 ByteArray command;
857                 ByteArray response;
858
859                 /* open channel */
860                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
861                 rv = terminal->transmitSync(command, response);
862                 if (rv == 0 && response.getLength() >= 2)
863                 {
864                         ResponseHelper resp(response);
865
866                         if (resp.getStatus() >= 0)
867                         {
868                                 result = resp.getDataField()[0];
869                         }
870                         else
871                         {
872                                 result = resp.getStatus();
873                         }
874                 }
875                 else
876                 {
877                         _ERR("transmitSync failed, rv [%d], length [%d]", rv, response.getLength());
878                 }
879
880                 return result;
881         }
882
883         int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
884         {
885                 int result = SCARD_ERROR_UNKNOWN;
886                 int rv = 0;
887                 ByteArray command;
888                 ByteArray response;
889
890                 /* open channel */
891                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
892                 rv = terminal->transmitSync(command, response);
893                 if (rv == 0 && response.getLength() >= 2)
894                 {
895                         ResponseHelper resp(response);
896
897                         if (resp.getStatus() >= 0)
898                         {
899                                 _DBG("channel closed [%d]", channelNum);
900                                 result = SCARD_ERROR_OK;
901                         }
902                         else
903                         {
904                                 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
905                         }
906                 }
907                 else
908                 {
909                         _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
910                 }
911
912                 return result;
913         }
914
915         unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
916                 throw(ExceptionBase &)
917         {
918                 unsigned int result = IntegerHandle::INVALID_HANDLE;
919                 int channelNum = 0;
920                 ServerChannel *channel = NULL;
921
922                 /* open logical channel */
923                 if (channelType == 1)
924                 {
925                         channelNum = _openLogicalChannel(terminal);
926                         if (channelNum > 0)
927                         {
928                                 _DBG("channelNum [%d]", channelNum);
929                         }
930                         else
931                         {
932                                 _ERR("_openLogicalChannel failed [%d]", channelNum);
933                                 throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
934                         }
935                 }
936
937                 /* create channel instance */
938                 result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
939                 if (result == IntegerHandle::INVALID_HANDLE)
940                 {
941                         _ERR("channel is null.");
942
943                         /* close logical channel */
944                         if (channelNum > 0)
945                         {
946                                 _closeLogicalChannel(terminal, channelNum);
947                         }
948                         throw ExceptionBase(SCARD_ERROR_OUT_OF_MEMORY);
949                 }
950
951                 channel = service->getChannel(result);
952
953                 /* check */
954                 if (_isAuthorizedAccess(channel, aid,
955                         service->getParent()->getCertificationHashes()) == true)
956                 {
957                         int rv = 0;
958
959                         /* select aid */
960                         if (aid == PKCS15::PKCS15_AID)
961                         {
962                                 PKCS15 pkcs15(channel);
963
964                                 rv = pkcs15.select();
965                                 if (rv >= SCARD_ERROR_OK)
966                                 {
967                                         /* remove privilege mode */
968                                         channel->unsetPrivilegeMode();
969                                         channel->setSelectResponse(pkcs15.getSelectResponse());
970                                 }
971                                 else
972                                 {
973                                         _ERR("select failed, [%x]", -rv);
974
975                                         service->closeChannel(result);
976                                         throw ExceptionBase(SCARD_ERROR_IO_FAILED);
977                                 }
978                         }
979                         else
980                         {
981                                 FileObject file(channel);
982
983                                 rv = file.select(aid);
984                                 if (rv >= SCARD_ERROR_OK)
985                                 {
986                                         /* remove privilege mode */
987                                         channel->unsetPrivilegeMode();
988                                         channel->setSelectResponse(file.getSelectResponse());
989                                 }
990                                 else
991                                 {
992                                         _ERR("select failed [%x]", -rv);
993
994                                         service->closeChannel(result);
995                                         throw ExceptionBase(SCARD_ERROR_IO_FAILED);
996                                 }
997                         }
998                 }
999                 else
1000                 {
1001                         _ERR("unauthorized access");
1002
1003                         service->closeChannel(result);
1004                         throw ExceptionBase(SCARD_ERROR_SECURITY_NOT_ALLOWED);
1005                 }
1006
1007                 return result;
1008         }
1009
1010         void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
1011         {
1012                 map<Terminal *, AccessControlList *>::iterator item;
1013
1014                 if ((item = mapACL.find(terminal)) == mapACL.end())
1015                 {
1016                         mapACL.insert(make_pair(terminal, acl));
1017                 }
1018                 else
1019                 {
1020                         item->second = acl;
1021                 }
1022         }
1023
1024         void ServerResource::addAccessControlList(ServerChannel *channel, AccessControlList *acl)
1025         {
1026                 map<Terminal *, AccessControlList *>::iterator item;
1027
1028                 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
1029                 {
1030                         mapACL.insert(make_pair(channel->getTerminal(), acl));
1031                 }
1032                 else
1033                 {
1034                         item->second = acl;
1035                 }
1036         }
1037
1038         AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
1039         {
1040                 AccessControlList *result = NULL;
1041                 map<Terminal *, AccessControlList *>::iterator item;
1042
1043                 if ((item = mapACL.find(terminal)) != mapACL.end())
1044                 {
1045                         result = item->second;
1046                 }
1047
1048                 return result;
1049         }
1050
1051         AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
1052         {
1053                 AccessControlList *result = NULL;
1054                 map<Terminal *, AccessControlList *>::iterator item;
1055
1056                 if ((item = mapACL.find(channel->getTerminal())) != mapACL.end())
1057                 {
1058                         result = item->second;
1059                 }
1060
1061                 return result;
1062         }
1063
1064         Terminal *ServerResource::createInstance(void *library)
1065         {
1066                 Terminal *terminal = NULL;
1067                 terminal_create_instance_fn createInstance = NULL;
1068
1069                 /* create se instance */
1070                 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
1071                 if (createInstance != NULL)
1072                 {
1073                         terminal = (Terminal *)createInstance();
1074                         if (terminal != NULL)
1075                         {
1076                                 _DBG("terminal [%p]", terminal);
1077                         }
1078                         else
1079                         {
1080                                 _ERR("terminal is null");
1081                         }
1082                 }
1083                 else
1084                 {
1085                         _ERR("create_instance is null [%d]", errno);
1086                 }
1087
1088                 return terminal;
1089         }
1090
1091         bool ServerResource::appendSELibrary(char *library)
1092         {
1093                 void *libHandle = NULL;
1094                 bool result = false;
1095
1096                 libHandle = dlopen(library, RTLD_LAZY);
1097                 if (libHandle != NULL)
1098                 {
1099                         Terminal *terminal = NULL;
1100
1101                         terminal = createInstance(libHandle);
1102                         if (terminal != NULL)
1103                         {
1104                                 unsigned int handle = IntegerHandle::assignHandle();
1105
1106                                 mapTerminals.insert(make_pair(handle, terminal));
1107                                 libraries.push_back(libHandle);
1108
1109                                 terminal->setStatusCallback(&ServerResource::terminalCallback);
1110
1111                                 _DBG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
1112
1113                                 if (terminal->isSecureElementPresence() == true)
1114                                 {
1115                                         createReader(handle);
1116                                 }
1117
1118                                 result = true;
1119                         }
1120                         else
1121                         {
1122                                 _ERR("terminal is null [%s]", library);
1123
1124                                 dlclose(libHandle);
1125                         }
1126                 }
1127                 else
1128                 {
1129                         _ERR("it is not se file [%s] [%d]", library, errno);
1130                 }
1131
1132                 return result;
1133         }
1134
1135         int ServerResource::loadSecureElements()
1136         {
1137                 int result = 0;
1138
1139                 if (seLoaded == false)
1140                 {
1141                         DIR *dir;
1142                         struct dirent *entry;
1143
1144                         if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
1145                         {
1146                                 while ((entry = readdir(dir)) != NULL)
1147                                 {
1148                                         if (strncmp(entry->d_name, ".", 1) != 0 &&
1149                                                 strncmp(entry->d_name, "..", 2) != 0)
1150                                         {
1151                                                 char fullPath[1024];
1152
1153                                                 /* TODO : need additional name rule :) */
1154
1155                                                 /* append each files */
1156                                                 snprintf(fullPath, sizeof(fullPath),
1157                                                         "%s/%s", OMAPI_SE_PATH, entry->d_name);
1158
1159                                                 SCARD_DEBUG("se name [%s]", fullPath);
1160
1161                                                 result = appendSELibrary(fullPath);
1162                                         }
1163                                 }
1164
1165                                 closedir(dir);
1166
1167                                 seLoaded = true;
1168                         }
1169                         else
1170                         {
1171                                 result = -1;
1172                         }
1173                 }
1174
1175                 return result;
1176         }
1177
1178         void ServerResource::unloadSecureElements()
1179         {
1180                 if (seLoaded == true)
1181                 {
1182                         size_t i;
1183                         map<unsigned int, Terminal *>::iterator item;
1184
1185                         for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
1186                         {
1187                                 item->second->finalize();
1188
1189                                 IntegerHandle::releaseHandle(item->first);
1190                         }
1191
1192                         mapTerminals.clear();
1193
1194                         for (i = 0; i < libraries.size(); i++)
1195                         {
1196                                 if (libraries[i] != NULL)
1197                                         dlclose(libraries[i]);
1198                         }
1199
1200                         libraries.clear();
1201
1202                         seLoaded = false;
1203                 }
1204         }
1205
1206         bool ServerResource::isValidReaderHandle(unsigned int reader)
1207         {
1208                 return (getTerminalByReaderID(reader) != NULL);
1209         }
1210
1211         void ServerResource::getReaders(vector<pair<unsigned int, string> > &readers)
1212         {
1213                 Terminal *terminal;
1214                 map<unsigned int, unsigned int>::iterator item;
1215
1216                 readers.clear();
1217
1218                 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1219                 {
1220                         if (item->second != IntegerHandle::INVALID_HANDLE)
1221                         {
1222                                 terminal = getTerminal(item->second);
1223                                 if (terminal != NULL && terminal->isSecureElementPresence() == true)
1224                                 {
1225                                         readers.push_back(make_pair(item->first, terminal->getName()));
1226                                 }
1227                         }
1228                 }
1229         }
1230
1231         int ServerResource::getReadersInformation(ByteArray &info)
1232         {
1233                 int result = 0;
1234                 unsigned char *buffer = NULL;
1235                 unsigned int length = 0;
1236                 unsigned int offset = 0;
1237                 unsigned int nameLen = 0;
1238
1239                 if (mapReaders.size() > 0)
1240                 {
1241                         Terminal *terminal = NULL;
1242                         map<unsigned int, unsigned int>::iterator item;
1243
1244                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1245                         {
1246                                 if (item->second != IntegerHandle::INVALID_HANDLE)
1247                                 {
1248                                         terminal = getTerminal(item->second);
1249                                         if (terminal != NULL)
1250                                         {
1251                                                 if (terminal->isSecureElementPresence())
1252                                                 {
1253                                                         length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
1254                                                         result++;
1255                                                 }
1256                                         }
1257                                 }
1258                         }
1259
1260                         buffer = new unsigned char[length];
1261                         if (buffer != NULL)
1262                         {
1263                                 memset(buffer, 0, length);
1264
1265                                 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1266                                 {
1267                                         if (item->second != IntegerHandle::INVALID_HANDLE)
1268                                         {
1269                                                 terminal = getTerminal(item->second);
1270                                                 if (terminal != NULL)
1271                                                 {
1272                                                         if (terminal->isSecureElementPresence())
1273                                                         {
1274                                                                 nameLen = strlen(terminal->getName());
1275
1276                                                                 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
1277                                                                 offset += sizeof(nameLen);
1278
1279                                                                 memcpy(buffer + offset, terminal->getName(), nameLen);
1280                                                                 offset += nameLen;
1281
1282                                                                 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
1283                                                                 offset += sizeof(unsigned int);
1284                                                         }
1285                                                 }
1286                                         }
1287                                 }
1288
1289                                 info.setBuffer(buffer, length);
1290                                 delete []buffer;
1291                         }
1292                         else
1293                         {
1294                                 _ERR("alloc failed");
1295                                 result = -1;
1296                         }
1297                 }
1298                 else
1299                 {
1300                         _INFO("no secure element");
1301                 }
1302
1303                 return result;
1304         }
1305
1306 #ifndef USE_GDBUS
1307         bool ServerResource::sendMessageToAllClients(Message &msg)
1308         {
1309                 bool result = true;
1310
1311                 map<int, ClientInstance *>::iterator item;
1312
1313                 for (item = mapClients.begin(); item != mapClients.end(); item++)
1314                 {
1315                         if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
1316                                 result = false;
1317                 }
1318
1319                 return result;
1320         }
1321 #endif
1322
1323         void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
1324         {
1325                 _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1326
1327                 switch (event)
1328                 {
1329                 case Terminal::NOTIFY_SE_AVAILABLE :
1330                         {
1331                                 ServerResource &instance = ServerResource::getInstance();
1332                                 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
1333
1334                                 _INFO("[NOTIFY_SE_AVAILABLE]");
1335
1336                                 terminalID = instance.getTerminalID((char *)terminal);
1337                                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1338                                 {
1339                                         unsigned int readerID = instance.createReader(terminalID);
1340 #ifdef USE_GDBUS
1341                                         ServerGDBus::getInstance().emitReaderInserted(readerID, (const char *)terminal);
1342 #else
1343                                         Message msg;
1344
1345                                         /* send all client to refresh reader */
1346                                         msg.message = msg.MSG_NOTIFY_SE_INSERTED;
1347                                         msg.param1 = readerID;
1348                                         msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1349
1350                                         instance.sendMessageToAllClients(msg);
1351 #endif
1352                                 }
1353                         }
1354                         break;
1355
1356                 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
1357                         {
1358                                 ServerResource &instance = ServerResource::getInstance();
1359                                 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
1360
1361                                 _INFO("[NOTIFY_SE_NOT_AVAILABLE]");
1362
1363                                 readerID = instance.getReaderID((char *)terminal);
1364 #ifdef USE_GDBUS
1365                                 ServerGDBus::getInstance().emitReaderRemoved(readerID, (const char *)terminal);
1366 #else
1367                                 Message msg;
1368
1369                                 /* send all client to refresh reader */
1370                                 msg.message = msg.MSG_NOTIFY_SE_REMOVED;
1371                                 msg.param1 = readerID;
1372                                 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1373
1374                                 instance.sendMessageToAllClients(msg);
1375 #endif
1376                                 instance.removeReader(readerID);
1377                         }
1378                         break;
1379
1380                 default :
1381                         _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1382                         break;
1383                 }
1384         }
1385
1386         unsigned int ServerResource::createReader(unsigned int terminalID)
1387         {
1388                 unsigned int result = -1;
1389
1390                 result = IntegerHandle::assignHandle();
1391
1392                 mapReaders.insert(make_pair(result, terminalID));
1393
1394                 return result;
1395         }
1396
1397         unsigned int ServerResource::getReaderID(const char *name)
1398         {
1399                 unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
1400
1401                 terminalID = getTerminalID(name);
1402                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1403                 {
1404                         map<unsigned int, unsigned int>::iterator item;
1405
1406                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1407                         {
1408                                 if (item->second == terminalID)
1409                                 {
1410                                         result = item->first;
1411                                         break;
1412                                 }
1413                         }
1414                 }
1415
1416                 return result;
1417         }
1418
1419         void ServerResource::removeReader(unsigned int readerID)
1420         {
1421                 map<unsigned int, unsigned int>::iterator item;
1422
1423                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1424                 {
1425                         item->second = IntegerHandle::INVALID_HANDLE;
1426                 }
1427         }
1428
1429         bool ServerResource::isAuthorizedNFCAccess(Terminal *terminal, ByteArray &aid, vector<ByteArray> &hashes)
1430         {
1431                 bool result = false;
1432
1433                 if (terminal == NULL) {
1434                         return result;
1435                 }
1436
1437                 int num = _openLogicalChannel(terminal);
1438                 if (num > 0) {
1439                         /* create channel instance */
1440                         ServerChannel *channel = new ServerChannel(NULL, NULL, num, terminal);
1441                         if (channel != NULL) {
1442                                 AccessControlList *acl = getAccessControlList(channel);
1443                                 if (acl == NULL) {
1444
1445                                         /* load access control defined by Global Platform */
1446                                         acl = new GPACE();
1447                                         if (acl != NULL) {
1448                                                 int ret;
1449
1450                                                 ret = acl->loadACL(channel);
1451                                                 if (ret >= SCARD_ERROR_OK) {
1452                                                         addAccessControlList(channel, acl);
1453                                                 } else {
1454                                                         _ERR("unknown error, 0x%x", -ret);
1455                                                         delete acl;
1456                                                 }
1457                                         } else {
1458                                                 _ERR("alloc failed");
1459                                         }
1460                                 } else {
1461                                         acl->updateACL(channel);
1462                                 }
1463
1464                                 if (acl != NULL) {
1465                                         result = acl->isAuthorizedNFCAccess(aid, hashes);
1466                                 } else {
1467                                         _ERR("acl is null");
1468                                 }
1469
1470                                 delete channel;
1471                         } else {
1472                                 _ERR("alloc failed");
1473                         }
1474                 } else {
1475                         _ERR("_openLogicalChannel failed");
1476                 }
1477
1478                 return result;
1479         }
1480 } /* namespace smartcard_service_api */
1481
1482 using namespace smartcard_service_api;
1483
1484 EXTERN_API void server_resource_set_main_loop_instance(void *instance)
1485 {
1486         ServerResource::getInstance().setMainLoopInstance(instance);
1487 }