Commented Access control process for 3.0 smartcard operation
[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                 /* NOTICE : This code is Access contol implementation in OpenMobile Specification.
688                  If you need the Access control in your target, please remove this comment.*/
689                 /*
690                 if (_isAuthorizedAccess(channel, aid,
691                         service->getParent()->getCertificationHashes()) == true)
692                 {
693                         int rv = 0;
694
695                         if (aid == PKCS15::PKCS15_AID)
696                         {
697                                 PKCS15 pkcs15(channel);
698
699                                 rv = pkcs15.select();
700                                 if (rv >= SCARD_ERROR_OK)
701                                 {
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                                         channel->unsetPrivilegeMode();
721                                         channel->setSelectResponse(file.getSelectResponse());
722                                 }
723                                 else
724                                 {
725                                         _ERR("select failed [%x]", -rv);
726
727                                         service->closeChannel(result);
728                                         throw ExceptionBase(SCARD_ERROR_IO_FAILED);
729                                 }
730                         }
731                 }
732                 else
733                 {
734                         _ERR("unauthorized access");
735
736                         service->closeChannel(result);
737                         throw ExceptionBase(SCARD_ERROR_SECURITY_NOT_ALLOWED);
738                 }
739                 */
740                 return result;
741         }
742
743         void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
744         {
745                 map<Terminal *, AccessControlList *>::iterator item;
746
747                 if ((item = mapACL.find(terminal)) == mapACL.end())
748                 {
749                         mapACL.insert(make_pair(terminal, acl));
750                 }
751                 else
752                 {
753                         item->second = acl;
754                 }
755         }
756
757         void ServerResource::addAccessControlList(ServerChannel *channel, AccessControlList *acl)
758         {
759                 map<Terminal *, AccessControlList *>::iterator item;
760
761                 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
762                 {
763                         mapACL.insert(make_pair(channel->getTerminal(), acl));
764                 }
765                 else
766                 {
767                         item->second = acl;
768                 }
769         }
770
771         AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
772         {
773                 AccessControlList *result = NULL;
774                 map<Terminal *, AccessControlList *>::iterator item;
775
776                 if ((item = mapACL.find(terminal)) != mapACL.end())
777                 {
778                         result = item->second;
779                 }
780
781                 return result;
782         }
783
784         AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
785         {
786                 AccessControlList *result = NULL;
787                 map<Terminal *, AccessControlList *>::iterator item;
788
789                 if ((item = mapACL.find(channel->getTerminal())) != mapACL.end())
790                 {
791                         result = item->second;
792                 }
793
794                 return result;
795         }
796
797         Terminal *ServerResource::createInstance(void *library)
798         {
799                 Terminal *terminal = NULL;
800                 terminal_create_instance_fn createInstance = NULL;
801
802                 /* create se instance */
803                 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
804                 if (createInstance != NULL)
805                 {
806                         terminal = (Terminal *)createInstance();
807                         if (terminal != NULL)
808                         {
809                                 _DBG("terminal [%p]", terminal);
810                         }
811                         else
812                         {
813                                 _ERR("terminal is null");
814                         }
815                 }
816                 else
817                 {
818                         _ERR("create_instance is null [%d]", errno);
819                 }
820
821                 return terminal;
822         }
823
824         bool ServerResource::appendSELibrary(char *library)
825         {
826                 void *libHandle = NULL;
827                 bool result = false;
828
829                 libHandle = dlopen(library, RTLD_LAZY);
830                 if (libHandle != NULL)
831                 {
832                         Terminal *terminal = NULL;
833
834                         terminal = createInstance(libHandle);
835                         if (terminal != NULL)
836                         {
837                                 unsigned int handle = IntegerHandle::assignHandle();
838
839                                 mapTerminals.insert(make_pair(handle, terminal));
840                                 libraries.push_back(libHandle);
841
842                                 terminal->setStatusCallback(&ServerResource::terminalCallback);
843
844                                 _DBG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
845
846                                 if (terminal->isSecureElementPresence() == true)
847                                 {
848                                         createReader(handle);
849                                 }
850
851                                 result = true;
852                         }
853                         else
854                         {
855                                 _ERR("terminal is null [%s]", library);
856
857                                 dlclose(libHandle);
858                         }
859                 }
860                 else
861                 {
862                         _ERR("it is not se file [%s] [%d]", library, errno);
863                 }
864
865                 return result;
866         }
867
868         int ServerResource::loadSecureElements()
869         {
870                 int result = 0;
871
872                 if (seLoaded == false)
873                 {
874                         DIR *dir;
875                         struct dirent *entry;
876
877                         if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
878                         {
879                                 while ((entry = readdir(dir)) != NULL)
880                                 {
881                                         if (strncmp(entry->d_name, ".", 1) != 0 &&
882                                                 strncmp(entry->d_name, "..", 2) != 0)
883                                         {
884                                                 char fullPath[1024];
885                                                 /* TODO : need additional name rule :) */
886
887                                                 /* append each files */
888                                                 snprintf(fullPath, sizeof(fullPath),
889                                                         "%s/%s", OMAPI_SE_PATH, entry->d_name);
890
891                                                 SECURE_LOGD("se name [%s]", fullPath);
892
893                                                 result = appendSELibrary(fullPath);
894                                         }
895                                 }
896
897                                 closedir(dir);
898
899                                 seLoaded = true;
900                         }
901                         else
902                         {
903                                 result = -1;
904                         }
905                 }
906
907                 return result;
908         }
909
910         void ServerResource::unloadSecureElements()
911         {
912                 if (seLoaded == true)
913                 {
914                         size_t i;
915                         map<unsigned int, Terminal *>::iterator item;
916
917                         for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
918                         {
919                                 item->second->finalize();
920
921                                 IntegerHandle::releaseHandle(item->first);
922                         }
923
924                         mapTerminals.clear();
925
926                         for (i = 0; i < libraries.size(); i++)
927                         {
928                                 if (libraries[i] != NULL)
929                                         dlclose(libraries[i]);
930                         }
931
932                         libraries.clear();
933
934                         seLoaded = false;
935                 }
936         }
937
938         bool ServerResource::isValidReaderHandle(unsigned int reader) const
939         {
940                 return (getTerminalByReaderID(reader) != NULL);
941         }
942
943         void ServerResource::getReaders(vector<pair<unsigned int, string> > &readers) const
944         {
945                 const Terminal *terminal;
946                 map<unsigned int, unsigned int>::const_iterator item;
947
948                 readers.clear();
949
950                 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
951                 {
952                         if (item->second != IntegerHandle::INVALID_HANDLE)
953                         {
954                                 terminal = getTerminal(item->second);
955                                 if (terminal != NULL && terminal->isSecureElementPresence() == true)
956                                 {
957                                         readers.push_back(make_pair(item->first, terminal->getName()));
958                                 }
959                         }
960                 }
961         }
962
963         int ServerResource::getReadersInformation(ByteArray &info) const
964         {
965                 int result = 0;
966                 unsigned char *buffer = NULL;
967                 unsigned int length = 0;
968                 unsigned int offset = 0;
969                 unsigned int nameLen = 0;
970
971                 if (mapReaders.size() > 0)
972                 {
973                         const Terminal *terminal = NULL;
974                         map<unsigned int, unsigned int>::const_iterator item;
975
976                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
977                         {
978                                 if (item->second != IntegerHandle::INVALID_HANDLE)
979                                 {
980                                         terminal = getTerminal(item->second);
981                                         if (terminal != NULL)
982                                         {
983                                                 if (terminal->isSecureElementPresence())
984                                                 {
985                                                         length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
986                                                         result++;
987                                                 }
988                                         }
989                                 }
990                         }
991
992                         buffer = new unsigned char[length];
993                         if (buffer != NULL)
994                         {
995                                 memset(buffer, 0, length);
996
997                                 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
998                                 {
999                                         if (item->second != IntegerHandle::INVALID_HANDLE)
1000                                         {
1001                                                 terminal = getTerminal(item->second);
1002                                                 if (terminal != NULL)
1003                                                 {
1004                                                         if (terminal->isSecureElementPresence())
1005                                                         {
1006                                                                 nameLen = strlen(terminal->getName());
1007
1008                                                                 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
1009                                                                 offset += sizeof(nameLen);
1010
1011                                                                 memcpy(buffer + offset, terminal->getName(), nameLen);
1012                                                                 offset += nameLen;
1013
1014                                                                 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
1015                                                                 offset += sizeof(unsigned int);
1016                                                         }
1017                                                 }
1018                                         }
1019                                 }
1020
1021                                 info.assign(buffer, length);
1022                                 delete []buffer;
1023                         }
1024                         else
1025                         {
1026                                 _ERR("alloc failed");
1027                                 result = -1;
1028                         }
1029                 }
1030                 else
1031                 {
1032                         _INFO("no secure element");
1033                 }
1034
1035                 return result;
1036         }
1037
1038         void ServerResource::terminalCallback(const void *terminal, int event,
1039                 int error, void *user_param)
1040         {
1041                 _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1042
1043                 switch (event)
1044                 {
1045                 case Terminal::NOTIFY_SE_AVAILABLE :
1046                         {
1047                                 ServerResource &instance = ServerResource::getInstance();
1048                                 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
1049
1050                                 _INFO("[NOTIFY_SE_AVAILABLE]");
1051
1052                                 terminalID = instance.getTerminalID((char *)terminal);
1053                                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1054                                 {
1055                                         unsigned int readerID = instance.createReader(terminalID);
1056
1057                                         ServerGDBus::getInstance().emitReaderInserted(readerID, (const char *)terminal);
1058                                 }
1059                         }
1060                         break;
1061
1062                 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
1063                         {
1064                                 ServerResource &instance = ServerResource::getInstance();
1065                                 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
1066
1067                                 _INFO("[NOTIFY_SE_NOT_AVAILABLE]");
1068
1069                                 readerID = instance.getReaderID((char *)terminal);
1070
1071                                 ServerGDBus::getInstance().emitReaderRemoved(
1072                                         readerID, (const char *)terminal);
1073
1074                                 instance.removeReader(readerID);
1075                         }
1076                         break;
1077
1078                 default :
1079                         _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1080                         break;
1081                 }
1082         }
1083
1084         unsigned int ServerResource::createReader(unsigned int terminalID)
1085         {
1086                 unsigned int result = -1;
1087
1088                 result = IntegerHandle::assignHandle();
1089
1090                 mapReaders.insert(make_pair(result, terminalID));
1091
1092                 return result;
1093         }
1094
1095         unsigned int ServerResource::getReaderID(const char *name) const
1096         {
1097                 unsigned int result = IntegerHandle::INVALID_HANDLE,
1098                         terminalID = IntegerHandle::INVALID_HANDLE;
1099
1100                 terminalID = getTerminalID(name);
1101                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1102                 {
1103                         map<unsigned int, unsigned int>::const_iterator item;
1104
1105                         for (item = mapReaders.begin();
1106                                 item != mapReaders.end(); item++)
1107                         {
1108                                 if (item->second == terminalID)
1109                                 {
1110                                         result = item->first;
1111                                         break;
1112                                 }
1113                         }
1114                 }
1115
1116                 return result;
1117         }
1118
1119         void ServerResource::removeReader(unsigned int readerID)
1120         {
1121                 map<unsigned int, unsigned int>::iterator item;
1122
1123                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1124                 {
1125                         item->second = IntegerHandle::INVALID_HANDLE;
1126                 }
1127         }
1128
1129         ServerChannel *ServerResource::createInternalChannel(Terminal *terminal,
1130                 int channelType)
1131         {
1132                 int channelNum = 0;
1133                 ServerChannel *channel = NULL;
1134
1135                 /* open logical channel */
1136                 if (channelType == 1)
1137                 {
1138                         channelNum = _openLogicalChannel(terminal);
1139                         if (channelNum > 0)
1140                         {
1141                                 _DBG("channelNum [%d]", channelNum);
1142                         }
1143                         else
1144                         {
1145                                 _ERR("_openLogicalChannel failed [%d]", channelNum);
1146                                 throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
1147                         }
1148                 }
1149
1150                 /* create channel instance */
1151                 channel = new ServerChannel(NULL, NULL, channelNum, terminal);
1152
1153                 return channel;
1154         }
1155
1156         bool ServerResource::isAuthorizedNFCAccess(Terminal *terminal,
1157                 const ByteArray &aid, const vector<ByteArray> &hashes)
1158         {
1159                 bool result = false;
1160                 ServerChannel *channel;
1161
1162                 if (terminal == NULL) {
1163                         return result;
1164                 }
1165
1166                 channel = createInternalChannel(terminal, 1);
1167                 if (channel != NULL) {
1168                         AccessControlList *acl = getAccessControlList(channel);
1169                         if (acl == NULL) {
1170
1171                                 /* load access control defined by Global Platform */
1172                                 acl = new GPACE();
1173                                 if (acl != NULL) {
1174                                         int ret;
1175
1176                                         ret = acl->loadACL(channel);
1177                                         if (ret >= SCARD_ERROR_OK) {
1178                                                 addAccessControlList(channel, acl);
1179                                         } else {
1180                                                 _ERR("unknown error, 0x%x", -ret);
1181
1182                                                 delete acl;
1183                                                 acl = NULL;
1184                                         }
1185                                 } else {
1186                                         _ERR("alloc failed");
1187                                 }
1188                         } else {
1189                                 acl->updateACL(channel);
1190                         }
1191
1192                         if (acl != NULL) {
1193                                 result = acl->isAuthorizedNFCAccess(aid, hashes);
1194                         } else {
1195                                 _ERR("acl is null");
1196                         }
1197
1198                         delete channel;
1199                 } else {
1200                         _ERR("alloc failed");
1201                 }
1202
1203                 return result;
1204         }
1205
1206         bool ServerResource::isAuthorizedAccess(Terminal *terminal,
1207                 const ByteArray &aid, const vector<ByteArray> &hashes)
1208         {
1209                 bool result = false;
1210                 ServerChannel *channel;
1211
1212                 if (terminal == NULL) {
1213                         return result;
1214                 }
1215
1216                 channel = createInternalChannel(terminal, 1);
1217                 if (channel != NULL) {
1218                         AccessControlList *acl = getAccessControlList(channel);
1219                         if (acl == NULL) {
1220
1221                                 /* load access control defined by Global Platform */
1222                                 acl = new GPACE();
1223                                 if (acl != NULL) {
1224                                         int ret;
1225
1226                                         ret = acl->loadACL(channel);
1227                                         if (ret >= SCARD_ERROR_OK) {
1228                                                 addAccessControlList(channel, acl);
1229                                         } else {
1230                                                 _ERR("unknown error, 0x%x", -ret);
1231
1232                                                 delete acl;
1233                                                 acl = NULL;
1234                                         }
1235                                 } else {
1236                                         _ERR("alloc failed");
1237                                 }
1238                         } else {
1239                                 acl->updateACL(channel);
1240                         }
1241
1242                         if (acl != NULL) {
1243                                 result = acl->isAuthorizedAccess(aid, hashes);
1244                         } else {
1245                                 _ERR("acl is null");
1246                         }
1247
1248                         delete channel;
1249                 } else {
1250                         _ERR("alloc failed");
1251                 }
1252
1253                 return result;
1254         }
1255
1256         void ServerResource::finish()
1257         {
1258                 if (getClientCount() == 0) {
1259                         _INFO("no client connected. terminate server");
1260
1261                         smartcard_daemon_exit();
1262                 }
1263         }
1264 } /* namespace smartcard_service_api */