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