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