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