Change to use handle instead of context parameter
[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
35 #ifndef EXTERN_API
36 #define EXTERN_API __attribute__((visibility("default")))
37 #endif
38
39 namespace smartcard_service_api
40 {
41         unsigned int IntegerHandle::newHandle = 0;
42         set<unsigned int> IntegerHandle::setHandles;
43         PMutex IntegerHandle::mutexLock;
44
45         unsigned int IntegerHandle::assignHandle()
46         {
47                 SCOPE_LOCK(mutexLock)
48                 {
49                         pair<set<unsigned int>::iterator, bool> result;
50
51                         do
52                         {
53                                 newHandle++;
54                                 if (newHandle == (unsigned int)-1)
55                                 {
56                                         newHandle = 1;
57                                 }
58
59                                 result = setHandles.insert(newHandle);
60
61                         }
62                         while (!result.second);
63                 }
64
65                 _DBG("assign handle : newHandle [%d]", newHandle);
66
67                 return newHandle;
68         }
69
70         void IntegerHandle::releaseHandle(unsigned int handle)
71         {
72                 _DBG("will be released : Handle [%d]", handle);
73
74                 SCOPE_LOCK(mutexLock)
75                 {
76                         setHandles.erase(handle);
77                 }
78         }
79
80 #define OMAPI_SE_PATH "/usr/lib/se"
81
82         ServerResource::ServerResource()
83                 : mainLoop(NULL), seLoaded(false)
84         {
85                 _BEGIN();
86
87                 serverIPC = ServerIPC::getInstance();
88                 serverDispatcher = ServerDispatcher::getInstance();
89
90                 _END();
91         }
92
93         ServerResource::~ServerResource()
94         {
95         }
96
97         ServerResource &ServerResource::getInstance()
98         {
99                 static ServerResource serverResource;
100
101                 return serverResource;
102         }
103
104         bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
105         {
106                 bool result = false;
107
108                 if (getClient(socket) == NULL)
109                 {
110                         ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
111                         if (instance != NULL)
112                         {
113                                 mapClients.insert(make_pair(socket, instance));
114                                 result = true;
115                         }
116                         else
117                         {
118                                 _ERR("alloc failed");
119                         }
120                 }
121                 else
122                 {
123                         _ERR("client already exist [%d]", socket);
124                 }
125
126                 return result;
127         }
128
129         ClientInstance *ServerResource::getClient(int socket)
130         {
131                 ClientInstance *result = NULL;
132                 map<int, ClientInstance *>::iterator item;
133
134                 if ((item = mapClients.find(socket)) != mapClients.end())
135                 {
136                         result = item->second;
137                 }
138
139                 return result;
140         }
141
142         void ServerResource::setPID(int socket, int pid)
143         {
144                 map<int, ClientInstance *>::iterator item;
145
146                 if ((item = mapClients.find(socket)) != mapClients.end())
147                 {
148                         if (item->second->getPID() < 0)
149                                 item->second->setPID(pid);
150                 }
151         }
152
153         int ServerResource::getClientCount()
154         {
155                 return (int)mapClients.size();
156         }
157
158         void ServerResource::removeClient(int socket)
159         {
160                 map<int, ClientInstance *>::iterator item;
161
162                 if ((item = mapClients.find(socket)) != mapClients.end())
163                 {
164                         ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
165
166                         delete item->second;
167                         mapClients.erase(item);
168                 }
169                 else
170                 {
171                         _DBG("client removed already [%d]", socket);
172                 }
173         }
174
175         void ServerResource::removeClients()
176         {
177                 map<int, ClientInstance *>::iterator item;
178
179                 for (item = mapClients.begin(); item != mapClients.end(); item++)
180                 {
181                         ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
182
183                         delete item->second;
184                 }
185
186                 mapClients.clear();
187         }
188
189         ServiceInstance *ServerResource::createService(int socket)
190         {
191                 ServiceInstance *result = NULL;
192                 ClientInstance *instance = NULL;
193
194                 if ((instance = getClient(socket)) != NULL)
195                 {
196                         if ((result = instance->createService()) == NULL)
197                         {
198                                 _ERR("ClientInstance::createService failed [%d]", socket);
199                         }
200                 }
201                 else
202                 {
203                         _ERR("client doesn't exist [%d]", socket);
204                 }
205
206                 return result;
207         }
208
209         ServiceInstance *ServerResource::getService(int socket, unsigned int handle)
210         {
211                 ServiceInstance *result = NULL;
212                 ClientInstance *instance = NULL;
213
214                 if ((instance = getClient(socket)) != NULL)
215                 {
216                         result = instance->getService(handle);
217                 }
218                 else
219                 {
220                         _ERR("client doesn't exist [%d]", socket);
221                 }
222
223                 return result;
224         }
225
226         void ServerResource::removeService(int socket, unsigned int handle)
227         {
228                 ClientInstance *instance = NULL;
229
230                 if ((instance = getClient(socket)) != NULL)
231                 {
232                         instance->removeService(handle);
233                 }
234                 else
235                 {
236                         _ERR("client doesn't exist [%d]", socket);
237                 }
238         }
239
240         void ServerResource::removeServices(int socket)
241         {
242                 ClientInstance *instance = NULL;
243
244                 if ((instance = getClient(socket)) != NULL)
245                 {
246                         instance->removeServices();
247                 }
248                 else
249                 {
250                         _ERR("client doesn't exist [%d]", socket);
251                 }
252         }
253
254         Terminal *ServerResource::getTerminal(unsigned int terminalID)
255         {
256                 Terminal *result = NULL;
257                 map<unsigned int, Terminal *>::iterator item;
258
259                 if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
260                 {
261                         result = item->second;
262                 }
263                 else
264                 {
265                         _ERR("Terminal doesn't exist [%d]", terminalID);
266                 }
267
268                 return result;
269         }
270
271         Terminal *ServerResource::getTerminal(const char *name)
272         {
273                 Terminal *result = NULL;
274                 map<unsigned int, Terminal *>::iterator item;
275
276                 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
277                 {
278                         if (strncmp(name, item->second->getName(), strlen(name)) == 0)
279                         {
280                                 result = item->second;
281                                 break;
282                         }
283                 }
284
285                 return result;
286         }
287
288         Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
289         {
290                 Terminal *result = NULL;
291                 map<unsigned int, unsigned int>::iterator item;
292
293                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
294                 {
295                         result = getTerminal(item->second);
296                 }
297                 else
298                 {
299                         _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
300                 }
301
302                 return result;
303         }
304
305         unsigned int ServerResource::getTerminalID(const char *name)
306         {
307                 unsigned int result = IntegerHandle::INVALID_HANDLE;
308                 map<unsigned int, Terminal *>::iterator item;
309
310                 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
311                 {
312                         if (strncmp(name, item->second->getName(), strlen(name)) == 0)
313                         {
314                                 result = item->first;
315                                 break;
316                         }
317                 }
318
319                 return result;
320         }
321
322         unsigned int ServerResource::createSession(int socket, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
323         {
324                 unsigned int result = -1;
325                 Terminal *temp = NULL;
326                 ServiceInstance *instance = NULL;
327
328                 if ((instance = getService(socket, handle)) != NULL)
329                 {
330                         if ((temp = getTerminalByReaderID(readerID)) != NULL)
331                         {
332                                 result = instance->openSession(temp, certHashes, caller);
333                         }
334                 }
335                 else
336                 {
337                         _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
338                 }
339
340                 return result;
341         }
342
343         ServerSession *ServerResource::getSession(int socket, unsigned int handle, unsigned int sessionID)
344         {
345                 ServerSession *result = NULL;
346                 ServiceInstance *instance = NULL;
347
348                 if ((instance = getService(socket, handle)) != NULL)
349                 {
350                         result = instance->getSession(sessionID);
351                 }
352                 else
353                 {
354                         _ERR("Session doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, sessionID);
355                 }
356
357                 return result;
358         }
359
360         unsigned int ServerResource::getChannelCount(int socket, unsigned int handle, unsigned int sessionID)
361         {
362                 unsigned int result = -1;
363                 ServiceInstance *instance = NULL;
364
365                 if ((instance = getService(socket, handle)) != NULL)
366                 {
367                         result = instance->getChannelCountBySession(sessionID);
368                 }
369                 else
370                 {
371                         _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
372                 }
373
374                 return result;
375         }
376
377         void ServerResource::removeSession(int socket, unsigned int handle, unsigned int sessionID)
378         {
379                 ServiceInstance *instance = NULL;
380
381                 if ((instance = getService(socket, handle)) != NULL)
382                 {
383                         instance->closeSession(sessionID);
384                 }
385                 else
386                 {
387                         _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
388                 }
389         }
390
391         bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
392         {
393                 bool result = true;
394                 AccessControlList *acList = NULL;
395
396                 /* request open channel sequence */
397                 if ((acList = getAccessControlList(channel)) == NULL)
398                 {
399                         /* load access control defined by Global Platform */
400                         GPACE *acl = new GPACE();
401                         if (acl != NULL)
402                         {
403                                 int ret;
404
405                                 ret = acl->loadACL(channel);
406                                 if (ret >= SCARD_ERROR_OK)
407                                 {
408                                         acList = acl;
409                                         addAccessControlList(channel, acList);
410                                 }
411                                 else
412                                 {
413                                         _ERR("unknown error, 0x%x", -ret);
414                                         delete acl;
415                                 }
416                         }
417                         else
418                         {
419                                 _ERR("alloc failed");
420                         }
421                 }
422                 else
423                 {
424                         _ERR("acList is null");
425                         result = false;
426                 }
427
428                 if (acList != NULL)
429                 {
430                         result = acList->isAuthorizedAccess(aid, hashes);
431                 }
432
433                 return result;
434         }
435
436         int ServerResource::_openLogicalChannel(Terminal *terminal)
437         {
438                 int result = -1;
439                 int rv = 0;
440                 ByteArray command;
441                 ByteArray response;
442
443                 /* open channel */
444                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
445                 rv = terminal->transmitSync(command, response);
446                 if (rv == 0 && response.getLength() >= 2)
447                 {
448                         ResponseHelper resp(response);
449
450                         if (resp.getStatus() >= 0)
451                         {
452                                 result = resp.getDataField()[0];
453                         }
454                         else
455                         {
456                                 result = resp.getStatus();
457                         }
458                 }
459                 else
460                 {
461                         _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
462                 }
463
464                 return result;
465         }
466
467         int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
468         {
469                 int result = SCARD_ERROR_UNKNOWN;
470                 int rv = 0;
471                 ByteArray command;
472                 ByteArray response;
473
474                 /* open channel */
475                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
476                 rv = terminal->transmitSync(command, response);
477                 if (rv == 0 && response.getLength() >= 2)
478                 {
479                         ResponseHelper resp(response);
480
481                         if (resp.getStatus() >= 0)
482                         {
483                                 _DBG("channel closed [%d]", channelNum);
484                                 result = SCARD_ERROR_OK;
485                         }
486                         else
487                         {
488                                 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
489                         }
490                 }
491                 else
492                 {
493                         _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
494                 }
495
496                 return result;
497         }
498
499         unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
500                 throw(ExceptionBase &)
501         {
502                 unsigned int result = IntegerHandle::INVALID_HANDLE;
503                 int channelNum = 0;
504                 ServerChannel *channel = NULL;
505
506                 /* open logical channel */
507                 if (channelType == 1)
508                 {
509                         channelNum = _openLogicalChannel(terminal);
510                         if (channelNum > 0)
511                         {
512                                 _DBG("channelNum [%d]", channelNum);
513                         }
514                         else
515                         {
516                                 _ERR("_openLogicalChannel failed [%d]", channelNum);
517                                 throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
518                         }
519                 }
520
521                 /* create channel instance */
522                 result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
523                 if (result == IntegerHandle::INVALID_HANDLE)
524                 {
525                         _ERR("channel is null.");
526
527                         /* close logical channel */
528                         if (channelNum > 0)
529                         {
530                                 _closeLogicalChannel(terminal, channelNum);
531                         }
532                         throw ExceptionBase(SCARD_ERROR_OUT_OF_MEMORY);
533                 }
534
535                 channel = service->getChannel(result);
536
537                 /* check */
538                 if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
539                                 aid, service->getParent()->getCertificationHashes()) == true)
540                 {
541                         int rv = 0;
542
543                         /* select aid */
544                         if (aid == PKCS15::PKCS15_AID)
545                         {
546                                 PKCS15 pkcs15(channel);
547
548                                 rv = pkcs15.select();
549                                 if (rv >= SCARD_ERROR_OK)
550                                 {
551                                         /* remove privilege mode */
552                                         channel->unsetPrivilegeMode();
553                                         channel->setSelectResponse(pkcs15.getSelectResponse());
554                                 }
555                                 else
556                                 {
557                                         _ERR("select failed, [%x]", -rv);
558
559                                         service->closeChannel(result);
560                                         throw ExceptionBase(SCARD_ERROR_IO_FAILED);
561                                 }
562                         }
563                         else
564                         {
565                                 FileObject file(channel);
566
567                                 rv = file.select(aid);
568                                 if (rv >= SCARD_ERROR_OK)
569                                 {
570                                         /* remove privilege mode */
571                                         channel->unsetPrivilegeMode();
572                                         channel->setSelectResponse(file.getSelectResponse());
573                                 }
574                                 else
575                                 {
576                                         _ERR("select failed [%x]", -rv);
577
578                                         service->closeChannel(result);
579                                         throw ExceptionBase(SCARD_ERROR_IO_FAILED);
580                                 }
581                         }
582                 }
583                 else
584                 {
585                         _ERR("unauthorized access");
586
587                         service->closeChannel(result);
588                         throw ExceptionBase(SCARD_ERROR_SECURITY_NOT_ALLOWED);
589                 }
590
591                 return result;
592         }
593
594         unsigned int ServerResource::createChannel(int socket, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
595                 throw(ExceptionBase &)
596         {
597                 unsigned int result = -1;
598                 ServiceInstance *service = NULL;
599
600                 if ((service = getService(socket, handle)) != NULL)
601                 {
602                         if (service->isVaildSessionHandle(sessionID) == true)
603                         {
604                                 ServerSession *session = NULL;
605                                 Terminal *terminal = NULL;
606
607                                 terminal = service->getTerminal(sessionID);
608                                 session = service->getSession(sessionID);
609                                 if (terminal != NULL && session != NULL)
610                                 {
611                                         result = _createChannel(terminal, service, channelType, sessionID, aid);
612                                         if (result == IntegerHandle::INVALID_HANDLE)
613                                         {
614                                                 _ERR("create channel failed [%d]", sessionID);
615                                         }
616                                 }
617                                 else
618                                 {
619                                         _ERR("session is invalid [%d]", sessionID);
620                                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
621                                 }
622                         }
623                         else
624                         {
625                                 _ERR("session is invalid [%d]", sessionID);
626                                 throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
627                         }
628                 }
629                 else
630                 {
631                         _ERR("getService is failed [%d] [%d]", socket, handle);
632                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
633                 }
634
635                 return result;
636         }
637
638         Channel *ServerResource::getChannel(int socket, unsigned int handle, unsigned int channelID)
639         {
640                 Channel *result = NULL;
641                 ServiceInstance *instance = NULL;
642
643                 if ((instance = getService(socket, handle)) != NULL)
644                 {
645                         result = instance->getChannel(channelID);
646                 }
647                 else
648                 {
649                         _ERR("Channel doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, channelID);
650                 }
651
652                 return result;
653         }
654
655         void ServerResource::removeChannel(int socket, unsigned int handle, unsigned int channelID)
656         {
657                 ServiceInstance *instance = NULL;
658
659                 if ((instance = getService(socket, handle)) != NULL)
660                 {
661                         instance->closeChannel(channelID);
662                 }
663                 else
664                 {
665                         _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
666                 }
667         }
668
669         void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
670         {
671                 map<Terminal *, AccessControlList *>::iterator item;
672
673                 if ((item = mapACL.find(terminal)) == mapACL.end())
674                 {
675                         mapACL.insert(make_pair(terminal, acl));
676                 }
677                 else
678                 {
679                         item->second = acl;
680                 }
681         }
682
683         void ServerResource::addAccessControlList(ServerChannel *channel, AccessControlList *acl)
684         {
685                 map<Terminal *, AccessControlList *>::iterator item;
686
687                 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
688                 {
689                         mapACL.insert(make_pair(channel->getTerminal(), acl));
690                 }
691                 else
692                 {
693                         item->second = acl;
694                 }
695         }
696
697         AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
698         {
699                 AccessControlList *result = NULL;
700                 map<Terminal *, AccessControlList *>::iterator item;
701
702                 if ((item = mapACL.find(terminal)) != mapACL.end())
703                 {
704                         result = item->second;
705                 }
706
707                 return result;
708         }
709
710         AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
711         {
712                 AccessControlList *result = NULL;
713                 map<Terminal *, AccessControlList *>::iterator item;
714
715                 if ((item = mapACL.find(channel->getTerminal())) != mapACL.end())
716                 {
717                         result = item->second;
718                 }
719
720                 return result;
721         }
722
723         Terminal *ServerResource::createInstance(void *library)
724         {
725                 Terminal *terminal = NULL;
726                 terminal_create_instance_fn createInstance = NULL;
727
728                 /* create se instance */
729                 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
730                 if (createInstance != NULL)
731                 {
732                         terminal = (Terminal *)createInstance();
733                         if (terminal != NULL)
734                         {
735                                 _DBG("terminal [%p]", terminal);
736                         }
737                         else
738                         {
739                                 _ERR("terminal is null");
740                         }
741                 }
742                 else
743                 {
744                         _ERR("create_instance is null [%d]", errno);
745                 }
746
747                 return terminal;
748         }
749
750         bool ServerResource::appendSELibrary(char *library)
751         {
752                 void *libHandle = NULL;
753                 bool result = false;
754
755                 libHandle = dlopen(library, RTLD_LAZY);
756                 if (libHandle != NULL)
757                 {
758                         Terminal *terminal = NULL;
759
760                         terminal = createInstance(libHandle);
761                         if (terminal != NULL)
762                         {
763                                 unsigned int handle = IntegerHandle::assignHandle();
764
765                                 mapTerminals.insert(make_pair(handle, terminal));
766                                 libraries.push_back(libHandle);
767
768                                 terminal->setStatusCallback(&ServerResource::terminalCallback);
769
770                                 _DBG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
771
772                                 if (terminal->isSecureElementPresence() == true)
773                                 {
774                                         createReader(handle);
775                                 }
776
777                                 result = true;
778                         }
779                         else
780                         {
781                                 _ERR("terminal is null [%s]", library);
782
783                                 dlclose(libHandle);
784                         }
785                 }
786                 else
787                 {
788                         _ERR("it is not se file [%s] [%d]", library, errno);
789                 }
790
791                 return result;
792         }
793
794         int ServerResource::loadSecureElements()
795         {
796                 int result = 0;
797
798                 if (seLoaded == false)
799                 {
800                         DIR *dir;
801                         struct dirent *entry;
802
803                         if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
804                         {
805                                 while ((entry = readdir(dir)) != NULL)
806                                 {
807                                         if (strncmp(entry->d_name, ".", 1) != 0 &&
808                                                 strncmp(entry->d_name, "..", 2) != 0)
809                                         {
810                                                 char fullPath[1024];
811
812                                                 /* TODO : need additional name rule :) */
813
814                                                 /* append each files */
815                                                 snprintf(fullPath, sizeof(fullPath),
816                                                         "%s/%s", OMAPI_SE_PATH, entry->d_name);
817
818                                                 SCARD_DEBUG("se name [%s]", fullPath);
819
820                                                 result = appendSELibrary(fullPath);
821                                         }
822                                 }
823
824                                 closedir(dir);
825
826                                 seLoaded = true;
827                         }
828                         else
829                         {
830                                 result = -1;
831                         }
832                 }
833
834                 return result;
835         }
836
837         void ServerResource::unloadSecureElements()
838         {
839                 if (seLoaded == true)
840                 {
841                         size_t i;
842                         map<unsigned int, Terminal *>::iterator item;
843
844                         for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
845                         {
846                                 item->second->finalize();
847
848                                 IntegerHandle::releaseHandle(item->first);
849                         }
850
851                         mapTerminals.clear();
852
853                         for (i = 0; i < libraries.size(); i++)
854                         {
855                                 if (libraries[i] != NULL)
856                                         dlclose(libraries[i]);
857                         }
858
859                         libraries.clear();
860
861                         seLoaded = false;
862                 }
863         }
864
865         bool ServerResource::isValidReaderHandle(unsigned int reader)
866         {
867                 return (getTerminalByReaderID(reader) != NULL);
868         }
869
870         bool ServerResource::isValidSessionHandle(int socket, unsigned int handle, unsigned int session)
871         {
872                 ServiceInstance *instance = NULL;
873
874                 return (((instance = getService(socket, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
875         }
876
877         int ServerResource::getReadersInformation(ByteArray &info)
878         {
879                 int result = 0;
880                 unsigned char *buffer = NULL;
881                 unsigned int length = 0;
882                 unsigned int offset = 0;
883                 unsigned int nameLen = 0;
884
885                 if (mapReaders.size() > 0)
886                 {
887                         Terminal *terminal = NULL;
888                         map<unsigned int, unsigned int>::iterator item;
889
890                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
891                         {
892                                 if (item->second != IntegerHandle::INVALID_HANDLE)
893                                 {
894                                         terminal = getTerminal(item->second);
895                                         if (terminal != NULL)
896                                         {
897                                                 if (terminal->isSecureElementPresence())
898                                                 {
899                                                         length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
900                                                         result++;
901                                                 }
902                                         }
903                                 }
904                         }
905
906                         buffer = new unsigned char[length];
907                         if (buffer != NULL)
908                         {
909                                 memset(buffer, 0, length);
910
911                                 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
912                                 {
913                                         if (item->second != IntegerHandle::INVALID_HANDLE)
914                                         {
915                                                 terminal = getTerminal(item->second);
916                                                 if (terminal != NULL)
917                                                 {
918                                                         if (terminal->isSecureElementPresence())
919                                                         {
920                                                                 nameLen = strlen(terminal->getName());
921
922                                                                 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
923                                                                 offset += sizeof(nameLen);
924
925                                                                 memcpy(buffer + offset, terminal->getName(), nameLen);
926                                                                 offset += nameLen;
927
928                                                                 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
929                                                                 offset += sizeof(unsigned int);
930                                                         }
931                                                 }
932                                         }
933                                 }
934
935                                 info.setBuffer(buffer, length);
936                                 delete []buffer;
937                         }
938                         else
939                         {
940                                 _ERR("alloc failed");
941                                 result = -1;
942                         }
943                 }
944                 else
945                 {
946                         _INFO("no secure element");
947                 }
948
949                 return result;
950         }
951
952         bool ServerResource::sendMessageToAllClients(Message &msg)
953         {
954                 bool result = true;
955                 map<int, ClientInstance *>::iterator item;
956
957                 for (item = mapClients.begin(); item != mapClients.end(); item++)
958                 {
959                         if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
960                                 result = false;
961                 }
962
963                 return result;
964         }
965
966         void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
967         {
968                 _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
969
970                 switch (event)
971                 {
972                 case Terminal::NOTIFY_SE_AVAILABLE :
973                         {
974                                 ServerResource &instance = ServerResource::getInstance();
975                                 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
976                                 Message msg;
977
978                                 _INFO("[NOTIFY_SE_AVAILABLE]");
979
980                                 terminalID = instance.getTerminalID((char *)terminal);
981                                 if (terminalID != IntegerHandle::INVALID_HANDLE)
982                                 {
983                                         /* send all client to refresh reader */
984                                         msg.message = msg.MSG_NOTIFY_SE_INSERTED;
985                                         msg.param1 = instance.createReader(terminalID);
986                                         msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
987
988                                         instance.sendMessageToAllClients(msg);
989                                 }
990                         }
991                         break;
992
993                 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
994                         {
995                                 ServerResource &instance = ServerResource::getInstance();
996                                 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
997                                 Message msg;
998
999                                 _INFO("[NOTIFY_SE_NOT_AVAILABLE]");
1000
1001                                 readerID = instance.getReaderID((char *)terminal);
1002
1003                                 /* send all client to refresh reader */
1004                                 msg.message = msg.MSG_NOTIFY_SE_REMOVED;
1005                                 msg.param1 = readerID;
1006                                 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1007
1008                                 instance.sendMessageToAllClients(msg);
1009                                 instance.removeReader(readerID);
1010                         }
1011                         break;
1012
1013                 default :
1014                         _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1015                         break;
1016                 }
1017         }
1018
1019         unsigned int ServerResource::createReader(unsigned int terminalID)
1020         {
1021                 unsigned int result = -1;
1022
1023                 result = IntegerHandle::assignHandle();
1024
1025                 mapReaders.insert(make_pair(result, terminalID));
1026
1027                 return result;
1028         }
1029
1030         unsigned int ServerResource::getReaderID(const char *name)
1031         {
1032                 unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
1033
1034                 terminalID = getTerminalID(name);
1035                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1036                 {
1037                         map<unsigned int, unsigned int>::iterator item;
1038
1039                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1040                         {
1041                                 if (item->second == terminalID)
1042                                 {
1043                                         result = item->first;
1044                                         break;
1045                                 }
1046                         }
1047                 }
1048
1049                 return result;
1050         }
1051
1052         void ServerResource::removeReader(unsigned int readerID)
1053         {
1054                 map<unsigned int, unsigned int>::iterator item;
1055
1056                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1057                 {
1058                         item->second = IntegerHandle::INVALID_HANDLE;
1059                 }
1060         }
1061
1062         bool ServerResource::isAuthorizedNFCAccess(Terminal *terminal, ByteArray &aid, vector<ByteArray> &hashes)
1063         {
1064                 bool result = false;
1065
1066                 if (terminal == NULL) {
1067                         return result;
1068                 }
1069
1070                 int num = _openLogicalChannel(terminal);
1071                 if (num > 0) {
1072                         /* create channel instance */
1073                         ServerChannel *channel = new ServerChannel(NULL, NULL, num, terminal);
1074                         if (channel != NULL) {
1075                                 AccessControlList *acl = getAccessControlList(channel);
1076                                 if (acl == NULL) {
1077
1078                                         /* load access control defined by Global Platform */
1079                                         GPACE *acl = new GPACE();
1080                                         if (acl != NULL) {
1081                                                 int ret;
1082
1083                                                 ret = acl->loadACL(channel);
1084                                                 if (ret >= SCARD_ERROR_OK) {
1085                                                         addAccessControlList(channel, acl);
1086                                                 } else {
1087                                                         _ERR("unknown error, 0x%x", -ret);
1088                                                         delete acl;
1089                                                 }
1090                                         } else {
1091                                                 _ERR("alloc failed");
1092                                         }
1093                                 } else {
1094                                         acl->updateACL(channel);
1095                                 }
1096
1097                                 delete channel;
1098
1099                                 if (acl != NULL) {
1100                                         result = acl->isAuthorizedNFCAccess(aid, hashes);
1101                                 }
1102                         }
1103                 }
1104
1105                 return result;
1106         }
1107 } /* namespace smartcard_service_api */
1108
1109 using namespace smartcard_service_api;
1110
1111 EXTERN_API void server_resource_set_main_loop_instance(void *instance)
1112 {
1113         ServerResource::getInstance().setMainLoopInstance(instance);
1114 }