Apply tizen 2.4 smartcard-service
[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         bool ServerResource::isValidChannelHandle(const char *name, unsigned int handle, unsigned int channel)
292         {
293                 ServiceInstance *instance = NULL;
294
295                 return (((instance = getService(name, handle)) != NULL) && (instance->isVaildChannelHandle(channel)));
296         }
297
298         unsigned int ServerResource::getChannelCount(const char *name, unsigned int handle, unsigned int sessionID)
299         {
300                 unsigned int result = -1;
301                 ServiceInstance *instance = NULL;
302
303                 if ((instance = getService(name, handle)) != NULL)
304                 {
305                         result = instance->getChannelCountBySession(sessionID);
306                 }
307                 else
308                 {
309                         _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
310                 }
311
312                 return result;
313         }
314
315         void ServerResource::removeSession(const char *name, unsigned int handle, unsigned int sessionID)
316         {
317                 ServiceInstance *instance = NULL;
318
319                 if ((instance = getService(name, handle)) != NULL)
320                 {
321                         instance->closeSession(sessionID);
322                 }
323                 else
324                 {
325                         _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
326                 }
327         }
328
329         unsigned int ServerResource::createChannel(const char *name, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
330                 throw(ExceptionBase &)
331         {
332                 unsigned int result = -1;
333                 ServiceInstance *service = NULL;
334
335                 if ((service = getService(name, handle)) != NULL)
336                 {
337                         if (service->isVaildSessionHandle(sessionID) == true)
338                         {
339                                 ServerSession *session = NULL;
340                                 Terminal *terminal = NULL;
341
342                                 terminal = service->getTerminal(sessionID);
343                                 session = service->getSession(sessionID);
344                                 if (terminal != NULL && session != NULL)
345                                 {
346                                         if (terminal->open() == true) {
347                                                 result = _createChannel(terminal, service, channelType, sessionID, aid);
348                                                 if (result == IntegerHandle::INVALID_HANDLE)
349                                                 {
350                                                         _ERR("create channel failed [%d]", sessionID);
351
352                                                         terminal->close();
353                                                 }
354                                         } else {
355                                                 _ERR("terminal open failed");
356                                                 throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
357                                         }
358                                 }
359                                 else
360                                 {
361                                         _ERR("session is invalid [%d]", sessionID);
362                                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
363                                 }
364                         }
365                         else
366                         {
367                                 _ERR("session is invalid [%d]", sessionID);
368                                 throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
369                         }
370                 }
371                 else
372                 {
373                         _ERR("getService is failed, name [%s], handle [%d]", name, handle);
374                         throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
375                 }
376
377                 return result;
378         }
379
380         Channel *ServerResource::getChannel(const char *name, unsigned int handle, unsigned int channelID)
381         {
382                 Channel *result = NULL;
383                 ServiceInstance *instance = NULL;
384
385                 if ((instance = getService(name, handle)) != NULL)
386                 {
387                         result = instance->getChannel(channelID);
388                 }
389                 else
390                 {
391                         _ERR("Channel doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, channelID);
392                 }
393
394                 return result;
395         }
396
397         void ServerResource::removeChannel(const char *name, unsigned int handle, unsigned int channelID)
398         {
399                 ServiceInstance *instance = NULL;
400
401                 if ((instance = getService(name, handle)) != NULL)
402                 {
403                         ServerChannel *channel;
404                         Terminal *terminal = NULL;
405
406                         channel = instance->getChannel(channelID);
407                         if (channel != NULL) {
408                                 terminal = channel->getTerminal();
409                         }
410
411                         instance->closeChannel(channelID);
412
413                         if (terminal != NULL) {
414                                 terminal->close();
415                         }
416                 }
417                 else
418                 {
419                         _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
420                 }
421         }
422
423         Terminal *ServerResource::getTerminal(unsigned int terminalID)
424         {
425                 Terminal *result = NULL;
426                 map<unsigned int, Terminal *>::iterator item;
427
428                 if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
429                 {
430                         result = item->second;
431                 }
432                 else
433                 {
434                         _ERR("Terminal doesn't exist [%d]", terminalID);
435                 }
436
437                 return result;
438         }
439
440         const Terminal *ServerResource::getTerminal(unsigned int terminalID) const
441         {
442                 const Terminal *result = NULL;
443                 map<unsigned int, Terminal *>::const_iterator item;
444
445                 if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
446                 {
447                         result = item->second;
448                 }
449                 else
450                 {
451                         _ERR("Terminal doesn't exist [%d]", terminalID);
452                 }
453
454                 return result;
455         }
456
457         Terminal *ServerResource::getTerminal(const char *name)
458         {
459                 Terminal *result = NULL;
460                 map<unsigned int, Terminal *>::iterator item;
461
462                 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
463                 {
464                         if (strncmp(name, item->second->getName(), strlen(name)) == 0)
465                         {
466                                 result = item->second;
467                                 break;
468                         }
469                 }
470
471                 return result;
472         }
473
474         Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
475         {
476                 Terminal *result = NULL;
477                 map<unsigned int, unsigned int>::iterator item;
478
479                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
480                 {
481                         result = getTerminal(item->second);
482                 }
483                 else
484                 {
485                         _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
486                 }
487
488                 return result;
489         }
490
491         const Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID) const
492         {
493                 const Terminal *result = NULL;
494                 map<unsigned int, unsigned int>::const_iterator item;
495
496                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
497                 {
498                         result = getTerminal(item->second);
499                 }
500                 else
501                 {
502                         _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
503                 }
504
505                 return result;
506         }
507
508         unsigned int ServerResource::getTerminalID(const char *name) const
509         {
510                 unsigned int result = IntegerHandle::INVALID_HANDLE;
511                 map<unsigned int, Terminal *>::const_iterator item;
512
513                 for (item = mapTerminals.begin();
514                         item != mapTerminals.end(); item++)
515                 {
516                         if (strncmp(name, item->second->getName(),
517                                 strlen(name)) == 0)
518                         {
519                                 result = item->first;
520                                 break;
521                         }
522                 }
523
524                 return result;
525         }
526
527         bool ServerResource::_isAuthorizedAccess(ServerChannel *channel,
528                 const ByteArray &aid, const vector<ByteArray> &hashes)
529         {
530                 bool result = false;
531                 AccessControlList *acList = NULL;
532
533                 /* request open channel sequence */
534                 if ((acList = getAccessControlList(channel)) == NULL)
535                 {
536                         /* load access control defined by Global Platform */
537                         GPACE *acl = new GPACE();
538                         if (acl != NULL)
539                         {
540                                 int ret;
541
542                                 ret = acl->loadACL(channel);
543                                 if (ret >= SCARD_ERROR_OK)
544                                 {
545                                         acList = acl;
546                                         addAccessControlList(channel, acList);
547                                 }
548                                 else
549                                 {
550                                         _ERR("unknown error, 0x%x", -ret);
551                                         delete acl;
552                                 }
553                         }
554                         else
555                         {
556                                 _ERR("alloc failed");
557                         }
558                 }
559                 else
560                 {
561                         acList->loadACL(channel);
562                 }
563
564                 if (acList != NULL)
565                 {
566                         result = acList->isAuthorizedAccess(aid, hashes);
567                 }
568
569                 return result;
570         }
571
572         int ServerResource::_openLogicalChannel(Terminal *terminal)
573         {
574                 int result = -1;
575                 int rv = 0;
576                 ByteArray command;
577                 ByteArray response;
578
579                 /* open channel */
580                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
581
582                 _DBG("command [%d] : %s", command.size(), command.toString().c_str());
583
584                 rv = terminal->transmitSync(command, response);
585                 if (rv == 0 && response.size() >= 2)
586                 {
587                         ResponseHelper resp(response);
588
589                         if (resp.getStatus() >= 0)
590                         {
591                                 result = resp.getDataField()[0];
592                         }
593                         else
594                         {
595                                 result = resp.getStatus();
596                         }
597                 }
598                 else
599                 {
600                         _ERR("transmitSync failed, rv [%d], length [%d]", rv, response.size());
601                 }
602
603                 return result;
604         }
605
606         int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
607         {
608                 int result = SCARD_ERROR_UNKNOWN;
609                 int rv = 0;
610                 ByteArray command;
611                 ByteArray response;
612
613                 /* open channel */
614                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
615
616                 _DBG("command [%d] : %s", command.size(), command.toString().c_str());
617
618                 rv = terminal->transmitSync(command, response);
619                 if (rv == 0 && response.size() >= 2)
620                 {
621                         ResponseHelper resp(response);
622
623                         if (resp.getStatus() >= 0)
624                         {
625                                 _DBG("channel closed [%d]", channelNum);
626                                 result = SCARD_ERROR_OK;
627                         }
628                         else
629                         {
630                                 _ERR("status word [ %02X %02X ]", resp.getSW1(), resp.getSW2());
631                         }
632                 }
633                 else
634                 {
635                         _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.size());
636                 }
637
638                 return result;
639         }
640
641         unsigned int ServerResource::_createChannel(Terminal *terminal,
642                 ServiceInstance *service, int channelType,
643                 unsigned int sessionID, const ByteArray &aid)
644                 throw(ExceptionBase &)
645         {
646                 unsigned int result = IntegerHandle::INVALID_HANDLE;
647                 int channelNum = 0;
648                 ServerChannel *channel = NULL;
649
650                 /* open logical channel */
651                 if (channelType == 1)
652                 {
653                         channelNum = _openLogicalChannel(terminal);
654                         if (channelNum > 0)
655                         {
656                                 _DBG("channelNum [%d]", channelNum);
657                         }
658                         else
659                         {
660                                 _ERR("_openLogicalChannel failed [%d]", channelNum);
661                                 throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
662                         }
663                 }
664
665                 /* create channel instance */
666                 result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
667                 if (result == IntegerHandle::INVALID_HANDLE)
668                 {
669                         _ERR("channel is null.");
670
671                         /* close logical channel */
672                         if (channelNum > 0)
673                         {
674                                 _closeLogicalChannel(terminal, channelNum);
675                         }
676                         throw ExceptionBase(SCARD_ERROR_OUT_OF_MEMORY);
677                 }
678
679                 channel = service->getChannel(result);
680                 if(channel == NULL)
681                 {
682                         _ERR("channel is null.");
683
684                          throw ExceptionBase(SCARD_ERROR_OUT_OF_MEMORY);
685                 }
686
687                 /* check */
688                 if (_isAuthorizedAccess(channel, aid,
689                         service->getParent()->getCertificationHashes()) == true)
690                 {
691                         int rv = 0;
692
693                         /* select aid */
694                         if (aid == PKCS15::PKCS15_AID)
695                         {
696                                 PKCS15 pkcs15(channel);
697
698                                 rv = pkcs15.select();
699                                 if (rv >= SCARD_ERROR_OK)
700                                 {
701                                         /* remove privilege mode */
702                                         channel->unsetPrivilegeMode();
703                                         channel->setSelectResponse(pkcs15.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                         else
714                         {
715                                 FileObject file(channel);
716
717                                 rv = file.select(aid);
718                                 if (rv >= SCARD_ERROR_OK)
719                                 {
720                                         /* remove privilege mode */
721                                         channel->unsetPrivilegeMode();
722                                         channel->setSelectResponse(file.getSelectResponse());
723                                 }
724                                 else
725                                 {
726                                         _ERR("select failed [%x]", -rv);
727
728                                         service->closeChannel(result);
729                                         throw ExceptionBase(SCARD_ERROR_IO_FAILED);
730                                 }
731                         }
732                 }
733                 else
734                 {
735                         _ERR("unauthorized access");
736
737                         service->closeChannel(result);
738                         throw ExceptionBase(SCARD_ERROR_SECURITY_NOT_ALLOWED);
739                 }
740
741                 return result;
742         }
743
744         void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
745         {
746                 map<Terminal *, AccessControlList *>::iterator item;
747
748                 if ((item = mapACL.find(terminal)) == mapACL.end())
749                 {
750                         mapACL.insert(make_pair(terminal, acl));
751                 }
752                 else
753                 {
754                         item->second = acl;
755                 }
756         }
757
758         void ServerResource::addAccessControlList(ServerChannel *channel, AccessControlList *acl)
759         {
760                 map<Terminal *, AccessControlList *>::iterator item;
761
762                 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
763                 {
764                         mapACL.insert(make_pair(channel->getTerminal(), acl));
765                 }
766                 else
767                 {
768                         item->second = acl;
769                 }
770         }
771
772         AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
773         {
774                 AccessControlList *result = NULL;
775                 map<Terminal *, AccessControlList *>::iterator item;
776
777                 if ((item = mapACL.find(terminal)) != mapACL.end())
778                 {
779                         result = item->second;
780                 }
781
782                 return result;
783         }
784
785         AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
786         {
787                 AccessControlList *result = NULL;
788                 map<Terminal *, AccessControlList *>::iterator item;
789
790                 if ((item = mapACL.find(channel->getTerminal())) != mapACL.end())
791                 {
792                         result = item->second;
793                 }
794
795                 return result;
796         }
797
798         Terminal *ServerResource::createInstance(void *library)
799         {
800                 Terminal *terminal = NULL;
801                 terminal_create_instance_fn createInstance = NULL;
802
803                 /* create se instance */
804                 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
805                 if (createInstance != NULL)
806                 {
807                         terminal = (Terminal *)createInstance();
808                         if (terminal != NULL)
809                         {
810                                 _DBG("terminal [%p]", terminal);
811                         }
812                         else
813                         {
814                                 _ERR("terminal is null");
815                         }
816                 }
817                 else
818                 {
819                         _ERR("create_instance is null [%d]", errno);
820                 }
821
822                 return terminal;
823         }
824
825         bool ServerResource::appendSELibrary(char *library)
826         {
827                 void *libHandle = NULL;
828                 bool result = false;
829
830                 libHandle = dlopen(library, RTLD_LAZY);
831                 if (libHandle != NULL)
832                 {
833                         Terminal *terminal = NULL;
834
835                         terminal = createInstance(libHandle);
836                         if (terminal != NULL)
837                         {
838                                 unsigned int handle = IntegerHandle::assignHandle();
839
840                                 mapTerminals.insert(make_pair(handle, terminal));
841                                 libraries.push_back(libHandle);
842
843                                 terminal->setStatusCallback(&ServerResource::terminalCallback);
844
845                                 _DBG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
846
847                                 if (terminal->isSecureElementPresence() == true)
848                                 {
849                                         createReader(handle);
850                                 }
851
852                                 result = true;
853                         }
854                         else
855                         {
856                                 _ERR("terminal is null [%s]", library);
857
858                                 dlclose(libHandle);
859                         }
860                 }
861                 else
862                 {
863                         _ERR("it is not se file [%s] [%d]", library, errno);
864                 }
865
866                 return result;
867         }
868
869         int ServerResource::loadSecureElements()
870         {
871                 int result = 0;
872
873                 if (seLoaded == false)
874                 {
875                         DIR *dir;
876                         struct dirent *entry;
877
878                         if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
879                         {
880                                 while ((entry = readdir(dir)) != NULL)
881                                 {
882                                         if (strncmp(entry->d_name, ".", 1) != 0 &&
883                                                 strncmp(entry->d_name, "..", 2) != 0)
884                                         {
885                                                 char fullPath[1024];
886                                                 /* TODO : need additional name rule :) */
887
888                                                 /* append each files */
889                                                 snprintf(fullPath, sizeof(fullPath),
890                                                         "%s/%s", OMAPI_SE_PATH, entry->d_name);
891
892                                                 SECURE_LOGD("se name [%s]", fullPath);
893
894                                                 result = appendSELibrary(fullPath);
895                                         }
896                                 }
897
898                                 closedir(dir);
899
900                                 seLoaded = true;
901                         }
902                         else
903                         {
904                                 result = -1;
905                         }
906                 }
907
908                 return result;
909         }
910
911         void ServerResource::unloadSecureElements()
912         {
913                 if (seLoaded == true)
914                 {
915                         size_t i;
916                         map<unsigned int, Terminal *>::iterator item;
917
918                         for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
919                         {
920                                 item->second->finalize();
921
922                                 IntegerHandle::releaseHandle(item->first);
923                         }
924
925                         mapTerminals.clear();
926
927                         for (i = 0; i < libraries.size(); i++)
928                         {
929                                 if (libraries[i] != NULL)
930                                         dlclose(libraries[i]);
931                         }
932
933                         libraries.clear();
934
935                         seLoaded = false;
936                 }
937         }
938
939         bool ServerResource::isValidReaderHandle(unsigned int reader) const
940         {
941                 return (getTerminalByReaderID(reader) != NULL);
942         }
943
944         void ServerResource::getReaders(vector<pair<unsigned int, string> > &readers) const
945         {
946                 const Terminal *terminal;
947                 map<unsigned int, unsigned int>::const_iterator item;
948
949                 readers.clear();
950
951                 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
952                 {
953                         if (item->second != IntegerHandle::INVALID_HANDLE)
954                         {
955                                 terminal = getTerminal(item->second);
956                                 if (terminal != NULL && terminal->isSecureElementPresence() == true)
957                                 {
958                                         readers.push_back(make_pair(item->first, terminal->getName()));
959                                 }
960                         }
961                 }
962         }
963
964         int ServerResource::getReadersInformation(ByteArray &info) const
965         {
966                 int result = 0;
967                 unsigned char *buffer = NULL;
968                 unsigned int length = 0;
969                 unsigned int offset = 0;
970                 unsigned int nameLen = 0;
971
972                 if (mapReaders.size() > 0)
973                 {
974                         const Terminal *terminal = NULL;
975                         map<unsigned int, unsigned int>::const_iterator item;
976
977                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
978                         {
979                                 if (item->second != IntegerHandle::INVALID_HANDLE)
980                                 {
981                                         terminal = getTerminal(item->second);
982                                         if (terminal != NULL)
983                                         {
984                                                 if (terminal->isSecureElementPresence())
985                                                 {
986                                                         length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
987                                                         result++;
988                                                 }
989                                         }
990                                 }
991                         }
992
993                         buffer = new unsigned char[length];
994                         if (buffer != NULL)
995                         {
996                                 memset(buffer, 0, length);
997
998                                 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
999                                 {
1000                                         if (item->second != IntegerHandle::INVALID_HANDLE)
1001                                         {
1002                                                 terminal = getTerminal(item->second);
1003                                                 if (terminal != NULL)
1004                                                 {
1005                                                         if (terminal->isSecureElementPresence())
1006                                                         {
1007                                                                 nameLen = strlen(terminal->getName());
1008
1009                                                                 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
1010                                                                 offset += sizeof(nameLen);
1011
1012                                                                 memcpy(buffer + offset, terminal->getName(), nameLen);
1013                                                                 offset += nameLen;
1014
1015                                                                 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
1016                                                                 offset += sizeof(unsigned int);
1017                                                         }
1018                                                 }
1019                                         }
1020                                 }
1021
1022                                 info.assign(buffer, length);
1023                                 delete []buffer;
1024                         }
1025                         else
1026                         {
1027                                 _ERR("alloc failed");
1028                                 result = -1;
1029                         }
1030                 }
1031                 else
1032                 {
1033                         _INFO("no secure element");
1034                 }
1035
1036                 return result;
1037         }
1038
1039         void ServerResource::terminalCallback(const void *terminal, int event,
1040                 int error, void *user_param)
1041         {
1042                 _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1043
1044                 switch (event)
1045                 {
1046                 case Terminal::NOTIFY_SE_AVAILABLE :
1047                         {
1048                                 ServerResource &instance = ServerResource::getInstance();
1049                                 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
1050
1051                                 _INFO("[NOTIFY_SE_AVAILABLE]");
1052
1053                                 terminalID = instance.getTerminalID((char *)terminal);
1054                                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1055                                 {
1056                                         unsigned int readerID = instance.createReader(terminalID);
1057
1058                                         ServerGDBus::getInstance().emitReaderInserted(readerID, (const char *)terminal);
1059                                 }
1060                         }
1061                         break;
1062
1063                 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
1064                         {
1065                                 ServerResource &instance = ServerResource::getInstance();
1066                                 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
1067
1068                                 _INFO("[NOTIFY_SE_NOT_AVAILABLE]");
1069
1070                                 readerID = instance.getReaderID((char *)terminal);
1071
1072                                 ServerGDBus::getInstance().emitReaderRemoved(
1073                                         readerID, (const char *)terminal);
1074
1075                                 instance.removeReader(readerID);
1076                         }
1077                         break;
1078
1079                 default :
1080                         _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1081                         break;
1082                 }
1083         }
1084
1085         unsigned int ServerResource::createReader(unsigned int terminalID)
1086         {
1087                 unsigned int result = -1;
1088
1089                 result = IntegerHandle::assignHandle();
1090
1091                 mapReaders.insert(make_pair(result, terminalID));
1092
1093                 return result;
1094         }
1095
1096         unsigned int ServerResource::getReaderID(const char *name) const
1097         {
1098                 unsigned int result = IntegerHandle::INVALID_HANDLE,
1099                         terminalID = IntegerHandle::INVALID_HANDLE;
1100
1101                 terminalID = getTerminalID(name);
1102                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1103                 {
1104                         map<unsigned int, unsigned int>::const_iterator item;
1105
1106                         for (item = mapReaders.begin();
1107                                 item != mapReaders.end(); item++)
1108                         {
1109                                 if (item->second == terminalID)
1110                                 {
1111                                         result = item->first;
1112                                         break;
1113                                 }
1114                         }
1115                 }
1116
1117                 return result;
1118         }
1119
1120         void ServerResource::removeReader(unsigned int readerID)
1121         {
1122                 map<unsigned int, unsigned int>::iterator item;
1123
1124                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1125                 {
1126                         item->second = IntegerHandle::INVALID_HANDLE;
1127                 }
1128         }
1129
1130         ServerChannel *ServerResource::createInternalChannel(Terminal *terminal,
1131                 int channelType)
1132         {
1133                 int channelNum = 0;
1134                 ServerChannel *channel = NULL;
1135
1136                 /* open logical channel */
1137                 if (channelType == 1)
1138                 {
1139                         channelNum = _openLogicalChannel(terminal);
1140                         if (channelNum > 0)
1141                         {
1142                                 _DBG("channelNum [%d]", channelNum);
1143                         }
1144                         else
1145                         {
1146                                 _ERR("_openLogicalChannel failed [%d]", channelNum);
1147                                 throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
1148                         }
1149                 }
1150
1151                 /* create channel instance */
1152                 channel = new ServerChannel(NULL, NULL, channelNum, terminal);
1153
1154                 return channel;
1155         }
1156
1157         bool ServerResource::isAuthorizedNFCAccess(Terminal *terminal,
1158                 const ByteArray &aid, const vector<ByteArray> &hashes)
1159         {
1160                 bool result = false;
1161                 ServerChannel *channel;
1162
1163                 if (terminal == NULL) {
1164                         return result;
1165                 }
1166
1167                 channel = createInternalChannel(terminal, 1);
1168                 if (channel != NULL) {
1169                         AccessControlList *acl = getAccessControlList(channel);
1170                         if (acl == NULL) {
1171
1172                                 /* load access control defined by Global Platform */
1173                                 acl = new GPACE();
1174                                 if (acl != NULL) {
1175                                         int ret;
1176
1177                                         ret = acl->loadACL(channel);
1178                                         if (ret >= SCARD_ERROR_OK) {
1179                                                 addAccessControlList(channel, acl);
1180                                         } else {
1181                                                 _ERR("unknown error, 0x%x", -ret);
1182
1183                                                 delete acl;
1184                                                 acl = NULL;
1185                                         }
1186                                 } else {
1187                                         _ERR("alloc failed");
1188                                 }
1189                         } else {
1190                                 acl->updateACL(channel);
1191                         }
1192
1193                         if (acl != NULL) {
1194                                 result = acl->isAuthorizedNFCAccess(aid, hashes);
1195                         } else {
1196                                 _ERR("acl is null");
1197                         }
1198
1199                         delete channel;
1200                 } else {
1201                         _ERR("alloc failed");
1202                 }
1203
1204                 return result;
1205         }
1206
1207         bool ServerResource::isAuthorizedAccess(Terminal *terminal,
1208                 const ByteArray &aid, const vector<ByteArray> &hashes)
1209         {
1210                 bool result = false;
1211                 ServerChannel *channel;
1212
1213                 if (terminal == NULL) {
1214                         return result;
1215                 }
1216
1217                 channel = createInternalChannel(terminal, 1);
1218                 if (channel != NULL) {
1219                         AccessControlList *acl = getAccessControlList(channel);
1220                         if (acl == NULL) {
1221
1222                                 /* load access control defined by Global Platform */
1223                                 acl = new GPACE();
1224                                 if (acl != NULL) {
1225                                         int ret;
1226
1227                                         ret = acl->loadACL(channel);
1228                                         if (ret >= SCARD_ERROR_OK) {
1229                                                 addAccessControlList(channel, acl);
1230                                         } else {
1231                                                 _ERR("unknown error, 0x%x", -ret);
1232
1233                                                 delete acl;
1234                                                 acl = NULL;
1235                                         }
1236                                 } else {
1237                                         _ERR("alloc failed");
1238                                 }
1239                         } else {
1240                                 acl->updateACL(channel);
1241                         }
1242
1243                         if (acl != NULL) {
1244                                 result = acl->isAuthorizedAccess(aid, hashes);
1245                         } else {
1246                                 _ERR("acl is null");
1247                         }
1248
1249                         delete channel;
1250                 } else {
1251                         _ERR("alloc failed");
1252                 }
1253
1254                 return result;
1255         }
1256
1257         void ServerResource::finish()
1258         {
1259                 if (getClientCount() == 0) {
1260                         _INFO("no client connected. terminate server");
1261
1262                         smartcard_daemon_exit();
1263                 }
1264         }
1265 } /* namespace smartcard_service_api */