Add NOTICE, AUTHOR file and modify boilerplate
[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
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(ServerChannel *channel, 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(channel)) != NULL)
407                         {
408 #if 1
409                                 PKCS15 pkcs15(channel);
410
411                                 acList->loadACL(channel);
412                                 result = acList->isAuthorizedAccess(aid, hashes);
413 #else
414                                 result = acList->isAuthorizedAccess(aid, session->packageCert);
415 #endif
416                         }
417                         else
418                         {
419                                 SCARD_DEBUG_ERR("acList is null");
420                                 result = false;
421                         }
422                 }
423 #endif
424
425                 return result;
426         }
427
428 #if 0
429         unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
430         {
431                 unsigned int result = IntegerHandle::INVALID_HANDLE;
432                 int rv = 0;
433                 int channelNum = 0;
434                 ByteArray command;
435                 ByteArray response;
436
437                 if (channelType == 1)
438                 {
439                         /* open channel */
440                         command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
441                         rv = terminal->transmitSync(command, response);
442
443                         if (rv == 0 && response.getLength() >= 2)
444                         {
445                                 ResponseHelper resp(response);
446
447                                 if (resp.getStatus() == 0)
448                                 {
449                                         channelNum = resp.getDataField()[0];
450
451                                         SCARD_DEBUG("channelNum [%d]", channelNum);
452                                 }
453                                 else
454                                 {
455                                         SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
456
457                                         return result;
458                                 }
459                         }
460                         else
461                         {
462                                 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
463
464                                 return result;
465                         }
466                 }
467
468                 /* select aid */
469                 APDUCommand apdu;
470                 apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_DF_NAME, APDUCommand::P2_SELECT_GET_FCP, aid, 0);
471                 apdu.setChannel(1, channelNum);
472                 apdu.getBuffer(command);
473
474                 rv = terminal->transmitSync(command, response);
475                 if (rv == 0 && response.getLength() >= 2)
476                 {
477                         ResponseHelper resp(response);
478
479                         if (resp.getStatus() == 0)
480                         {
481                                 result = service->openChannel(sessionID, channelNum, response);
482                                 if (result == IntegerHandle::INVALID_HANDLE)
483                                 {
484                                         SCARD_DEBUG_ERR("channel is null.");
485                                 }
486                         }
487                         else
488                         {
489                                 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
490                         }
491                 }
492                 else
493                 {
494                         SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
495                 }
496
497                 return result;
498         }
499 #else
500         int ServerResource::_openLogicalChannel(Terminal *terminal)
501         {
502                 int result = -1;
503                 int rv = 0;
504                 ByteArray command;
505                 ByteArray response;
506
507                 /* open channel */
508                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
509                 rv = terminal->transmitSync(command, response);
510                 if (rv == 0 && response.getLength() >= 2)
511                 {
512                         ResponseHelper resp(response);
513
514                         if (resp.getStatus() == 0)
515                         {
516                                 result = resp.getDataField()[0];
517                         }
518                         else
519                         {
520                                 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
521                                 if (0)
522                                 {
523                                         /* TODO : if there is no more channel, return error code */
524                                         SCARD_DEBUG_ERR("no more logical channel");
525                                         result = -2;
526                                 }
527                         }
528                 }
529                 else
530                 {
531                         SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
532                 }
533
534                 return result;
535         }
536
537         int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
538         {
539                 int result = -1;
540                 int rv = 0;
541                 ByteArray command;
542                 ByteArray response;
543
544                 /* open channel */
545                 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
546                 rv = terminal->transmitSync(command, response);
547                 if (rv == 0 && response.getLength() >= 2)
548                 {
549                         ResponseHelper resp(response);
550
551                         if (resp.getStatus() == 0)
552                         {
553                                 SCARD_DEBUG("channel closed [%d]", channelNum);
554                                 result = 0;
555                         }
556                         else
557                         {
558                                 SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
559                         }
560                 }
561                 else
562                 {
563                         SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
564                 }
565
566                 return result;
567         }
568
569         unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
570         {
571                 unsigned int result = IntegerHandle::INVALID_HANDLE;
572                 int channelNum = 0;
573                 ServerChannel *channel = NULL;
574
575                 /* open logical channel */
576                 if (channelType == 1)
577                 {
578                         channelNum = _openLogicalChannel(terminal);
579                         if (channelNum > 0)
580                         {
581                                 SCARD_DEBUG("channelNum [%d]", result);
582                         }
583                         else
584                         {
585                                 SCARD_DEBUG_ERR("_openLogicalChannel failed [%d]", channelNum);
586                                 return result;
587                         }
588                 }
589
590                 /* create channel instance */
591                 result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
592                 if (result == IntegerHandle::INVALID_HANDLE)
593                 {
594                         SCARD_DEBUG_ERR("channel is null.");
595
596                         /* close logical channel */
597                         if (channelNum > 0)
598                         {
599                                 _closeLogicalChannel(terminal, channelNum);
600                         }
601                         return result;
602                 }
603
604                 channel = service->getChannel(result);
605
606                 /* check */
607                 if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
608                                 aid, service->getParent()->getCertificationHashes()) == true)
609                 {
610                         int rv = 0;
611                         ByteArray command;
612                         ByteArray response;
613
614                         /* select aid */
615                         command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelNum, aid);
616                         rv = channel->transmitSync(command, response);
617                         if (rv == 0 && response.getLength() >= 2)
618                         {
619                                 ResponseHelper resp(response);
620
621                                 if (resp.getStatus() == 0)
622                                 {
623                                         channel->selectResponse = response;
624                                         /* remove privilege mode */
625                                         channel->unsetPrivilegeMode();
626                                 }
627                                 else
628                                 {
629                                         SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
630                                 }
631                         }
632                         else
633                         {
634                                 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
635                         }
636                 }
637                 else
638                 {
639                         SCARD_DEBUG_ERR("unauthorized access");
640
641                         service->closeChannel(result);
642                         result = IntegerHandle::INVALID_HANDLE;
643                 }
644
645
646                 return result;
647         }
648 #endif
649
650         unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
651         {
652                 unsigned int result = -1;
653                 ServiceInstance *service = NULL;
654
655                 if ((service = getService(socket, context)) != NULL)
656                 {
657                         if (service->isVaildSessionHandle(sessionID) == true)
658                         {
659                                 ServerSession *session = NULL;
660                                 Terminal *terminal = NULL;
661
662                                 terminal = service->getTerminal(sessionID);
663                                 session = service->getSession(sessionID);
664                                 if (terminal != NULL && session != NULL)
665                                 {
666                                         result = _createChannel(terminal, service, channelType, sessionID, aid);
667                                         if (result == IntegerHandle::INVALID_HANDLE)
668                                         {
669                                                 SCARD_DEBUG_ERR("create channel failed [%d]", sessionID);
670                                         }
671                                 }
672                                 else
673                                 {
674                                         SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
675                                 }
676                         }
677                         else
678                         {
679                                 SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
680                         }
681                 }
682                 else
683                 {
684                         SCARD_DEBUG_ERR("getService is failed [%d] [%d]", socket, context);
685                 }
686
687                 return result;
688         }
689
690         Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
691         {
692                 Channel *result = NULL;
693                 ServiceInstance *instance = NULL;
694
695                 if ((instance = getService(socket, context)) != NULL)
696                 {
697                         result = instance->getChannel(channelID);
698                 }
699                 else
700                 {
701                         SCARD_DEBUG_ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
702                 }
703
704                 return result;
705         }
706
707         void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
708         {
709                 ServiceInstance *instance = NULL;
710
711                 if ((instance = getService(socket, context)) != NULL)
712                 {
713                         instance->closeChannel(channelID);
714                 }
715                 else
716                 {
717                         SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
718                 }
719         }
720
721         AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
722         {
723                 AccessControlList *result = NULL;
724                 map<Terminal *, AccessControlList *>::iterator item;
725
726                 if ((item = mapACL.find(terminal)) == mapACL.end())
727                 {
728                         /* load access control */
729                         result = new GPSEACL();
730                         if (result != NULL)
731                         {
732                                 mapACL.insert(make_pair(terminal, result));
733                         }
734                         else
735                         {
736                                 SCARD_DEBUG_ERR("alloc failed");
737                         }
738                 }
739                 else
740                 {
741                         result = item->second;
742                 }
743
744                 return result;
745         }
746
747         AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
748         {
749                 AccessControlList *result = NULL;
750                 map<Terminal *, AccessControlList *>::iterator item;
751
752                 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
753                 {
754                         /* load access control */
755                         result = new GPSEACL();
756                         if (result != NULL)
757                         {
758                                 mapACL.insert(make_pair(channel->getTerminal(), result));
759                         }
760                         else
761                         {
762                                 SCARD_DEBUG_ERR("alloc failed");
763                         }
764                 }
765                 else
766                 {
767                         result = item->second;
768                 }
769
770                 return result;
771         }
772
773         Terminal *ServerResource::createInstance(void *library)
774         {
775                 Terminal *terminal = NULL;
776                 terminal_create_instance_fn createInstance = NULL;
777
778                 /* create se instance */
779                 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
780                 if (createInstance != NULL)
781                 {
782                         terminal = (Terminal *)createInstance();
783                         if (terminal != NULL)
784                         {
785                                 SCARD_DEBUG("terminal [%p]", terminal);
786                         }
787                         else
788                         {
789                                 SCARD_DEBUG_ERR("terminal is null");
790                         }
791                 }
792                 else
793                 {
794                         SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
795                 }
796
797                 return terminal;
798         }
799
800         bool ServerResource::appendSELibrary(char *library)
801         {
802                 void *libHandle = NULL;
803                 bool result = false;
804
805                 libHandle = dlopen(library, RTLD_LAZY);
806                 if (libHandle != NULL)
807                 {
808                         Terminal *terminal = NULL;
809
810                         terminal = createInstance(libHandle);
811                         if (terminal != NULL)
812                         {
813                                 unsigned int handle = IntegerHandle::assignHandle();
814
815                                 mapTerminals.insert(make_pair(handle, terminal));
816                                 libraries.push_back(libHandle);
817
818                                 terminal->setStatusCallback(&ServerResource::terminalCallback);
819
820                                 SCARD_DEBUG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
821
822                                 if (terminal->isSecureElementPresence() == true)
823                                 {
824                                         createReader(handle);
825                                 }
826
827                                 result = true;
828                         }
829                         else
830                         {
831                                 SCARD_DEBUG_ERR("terminal is null [%s]", library);
832
833                                 dlclose(libHandle);
834                         }
835                 }
836                 else
837                 {
838                         SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
839                 }
840
841                 return result;
842         }
843
844         int ServerResource::loadSecureElements()
845         {
846                 int result;
847                 void *libHandle;
848                 DIR *dir = NULL;
849                 struct dirent *entry = NULL;
850
851                 if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
852                 {
853                         while ((entry = readdir(dir)) != NULL)
854                         {
855                                 if (strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
856                                 {
857                                         char fullPath[1024] = { 0, };
858
859                                         /* TODO : need additional name rule :) */
860
861                                         /* open each files */
862                                         libHandle = NULL;
863
864                                         snprintf(fullPath, sizeof(fullPath), "%s/%s", OMAPI_SE_PATH, entry->d_name);
865
866                                         SCARD_DEBUG("se name [%s]", fullPath);
867
868                                         result = appendSELibrary(fullPath);
869                                 }
870                         }
871
872                         closedir(dir);
873
874                         result = 0;
875                 }
876                 else
877                 {
878                         result = -1;
879                 }
880
881                 return result;
882         }
883
884         void ServerResource::unloadSecureElements()
885         {
886                 size_t i;
887                 map<unsigned int, Terminal *>::iterator item;
888
889                 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
890                 {
891                         item->second->finalize();
892
893                         IntegerHandle::releaseHandle(item->first);
894                 }
895
896                 mapTerminals.clear();
897
898                 for (i = 0; i < libraries.size(); i++)
899                 {
900                         if (libraries[i] != NULL)
901                                 dlclose(libraries[i]);
902                 }
903
904                 libraries.clear();
905         }
906
907         bool ServerResource::isValidReaderHandle(unsigned int reader)
908         {
909                 return (getTerminalByReaderID(reader) != NULL);
910         }
911
912         bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
913         {
914                 ServiceInstance *instance = NULL;
915
916                 return (((instance = getService(socket, context)) != NULL) && (instance->isVaildSessionHandle(session)));
917         }
918
919         int ServerResource::getReadersInformation(ByteArray &info)
920         {
921                 int result = 0;
922                 unsigned char *buffer = NULL;
923                 unsigned int length = 0;
924                 unsigned int offset = 0;
925                 unsigned int nameLen = 0;
926
927                 if (mapReaders.size() > 0)
928                 {
929                         Terminal *terminal = NULL;
930                         map<unsigned int, unsigned int>::iterator item;
931
932                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
933                         {
934                                 if (item->second != IntegerHandle::INVALID_HANDLE)
935                                 {
936                                         terminal = getTerminal(item->second);
937                                         if (terminal != NULL)
938                                         {
939                                                 if (terminal->isSecureElementPresence())
940                                                 {
941                                                         length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
942                                                         result++;
943                                                 }
944                                         }
945                                 }
946                         }
947
948                         buffer = new unsigned char[length];
949                         if (buffer != NULL)
950                         {
951                                 memset(buffer, 0, length);
952
953                                 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
954                                 {
955                                         if (item->second != IntegerHandle::INVALID_HANDLE)
956                                         {
957                                                 terminal = getTerminal(item->second);
958                                                 if (terminal != NULL)
959                                                 {
960                                                         if (terminal->isSecureElementPresence())
961                                                         {
962                                                                 nameLen = strlen(terminal->getName());
963
964                                                                 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
965                                                                 offset += sizeof(nameLen);
966
967                                                                 memcpy(buffer + offset, terminal->getName(), nameLen);
968                                                                 offset += nameLen;
969
970                                                                 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
971                                                                 offset += sizeof(unsigned int);
972                                                         }
973                                                 }
974                                         }
975                                 }
976
977                                 info.setBuffer(buffer, length);
978                                 delete []buffer;
979                         }
980                         else
981                         {
982                                 SCARD_DEBUG_ERR("alloc failed");
983                                 result = -1;
984                         }
985                 }
986                 else
987                 {
988                         SCARD_DEBUG("no secure element");
989                 }
990
991                 return result;
992         }
993
994         bool ServerResource::sendMessageToAllClients(Message &msg)
995         {
996                 bool result = true;
997                 map<int, ClientInstance *>::iterator item;
998
999                 for (item = mapClients.begin(); item != mapClients.end(); item++)
1000                 {
1001                         if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
1002                                 result = false;
1003                 }
1004
1005                 return result;
1006         }
1007
1008         void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
1009         {
1010                 SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1011
1012                 switch (event)
1013                 {
1014                 case Terminal::NOTIFY_SE_AVAILABLE :
1015                         {
1016                                 ServerResource &instance = ServerResource::getInstance();
1017                                 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
1018                                 Message msg;
1019
1020                                 SCARD_DEBUG("[NOTIFY_SE_AVAILABLE]");
1021
1022                                 terminalID = instance.getTerminalID((char *)terminal);
1023                                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1024                                 {
1025                                         /* send all client to refresh reader */
1026                                         msg.message = msg.MSG_NOTIFY_SE_INSERTED;
1027                                         msg.param1 = instance.createReader(terminalID);
1028                                         msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1029
1030                                         instance.sendMessageToAllClients(msg);
1031                                 }
1032                         }
1033                         break;
1034
1035                 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
1036                         {
1037                                 ServerResource &instance = ServerResource::getInstance();
1038                                 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
1039                                 Message msg;
1040
1041                                 SCARD_DEBUG("[NOTIFY_SE_NOT_AVAILABLE]");
1042
1043                                 readerID = instance.getReaderID((char *)terminal);
1044
1045                                 /* send all client to refresh reader */
1046                                 msg.message = msg.MSG_NOTIFY_SE_REMOVED;
1047                                 msg.param1 = readerID;
1048                                 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
1049
1050                                 instance.sendMessageToAllClients(msg);
1051                                 instance.removeReader(readerID);
1052                         }
1053                         break;
1054
1055                 default :
1056                         SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
1057                         break;
1058                 }
1059         }
1060
1061         unsigned int ServerResource::createReader(unsigned int terminalID)
1062         {
1063                 unsigned int result = -1;
1064
1065                 result = IntegerHandle::assignHandle();
1066
1067                 mapReaders.insert(make_pair(result, terminalID));
1068
1069                 return result;
1070         }
1071
1072         unsigned int ServerResource::getReaderID(const char *name)
1073         {
1074                 unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
1075
1076                 terminalID = getTerminalID(name);
1077                 if (terminalID != IntegerHandle::INVALID_HANDLE)
1078                 {
1079                         map<unsigned int, unsigned int>::iterator item;
1080
1081                         for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1082                         {
1083                                 if (item->second == terminalID)
1084                                 {
1085                                         result = item->first;
1086                                         break;
1087                                 }
1088                         }
1089                 }
1090
1091                 return result;
1092         }
1093
1094         void ServerResource::removeReader(unsigned int readerID)
1095         {
1096                 map<unsigned int, unsigned int>::iterator item;
1097
1098                 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1099                 {
1100                         item->second = IntegerHandle::INVALID_HANDLE;
1101                 }
1102         }
1103
1104 } /* namespace smartcard_service_api */
1105
1106 using namespace smartcard_service_api;
1107
1108 EXTERN_API void server_resource_set_main_loop_instance(void *instance)
1109 {
1110         ServerResource::getInstance().setMainLoopInstance(instance);
1111 }