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