2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 /* standard library header */
24 /* SLP library header */
28 #include "ServerResource.h"
29 #include "TerminalInterface.h"
30 #include "APDUHelper.h"
31 #include "SignatureHelper.h"
35 #define EXTERN_API __attribute__((visibility("default")))
38 namespace smartcard_service_api
40 unsigned int IntegerHandle::newHandle = 0;
41 set<unsigned int> IntegerHandle::setHandles;
42 PMutex IntegerHandle::mutexLock;
44 unsigned int IntegerHandle::assignHandle()
48 pair<set<unsigned int>::iterator, bool> result;
53 if (newHandle == (unsigned int)-1)
58 result = setHandles.insert(newHandle);
61 while (!result.second);
64 _DBG("assign handle : newHandle [%d]", newHandle);
69 void IntegerHandle::releaseHandle(unsigned int handle)
71 _DBG("will be released : Handle [%d]", handle);
75 setHandles.erase(handle);
79 #define OMAPI_SE_PATH "/usr/lib/se"
81 ServerResource::ServerResource()
82 : mainLoop(NULL), seLoaded(false)
86 serverIPC = ServerIPC::getInstance();
87 serverDispatcher = ServerDispatcher::getInstance();
92 ServerResource::~ServerResource()
96 ServerResource &ServerResource::getInstance()
98 static ServerResource serverResource;
100 return serverResource;
103 bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
107 if (getClient(socket) == NULL)
109 ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
110 if (instance != NULL)
112 mapClients.insert(make_pair(socket, instance));
117 _ERR("alloc failed");
122 _ERR("client already exist [%d]", socket);
128 ClientInstance *ServerResource::getClient(int socket)
130 ClientInstance *result = NULL;
131 map<int, ClientInstance *>::iterator item;
133 if ((item = mapClients.find(socket)) != mapClients.end())
135 result = item->second;
141 void ServerResource::setPID(int socket, int pid)
143 map<int, ClientInstance *>::iterator item;
145 if ((item = mapClients.find(socket)) != mapClients.end())
147 if (item->second->getPID() < 0)
148 item->second->setPID(pid);
152 int ServerResource::getClientCount()
154 return (int)mapClients.size();
157 void ServerResource::removeClient(int socket)
159 map<int, ClientInstance *>::iterator item;
161 if ((item = mapClients.find(socket)) != mapClients.end())
163 ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
166 mapClients.erase(item);
170 _DBG("client removed already [%d]", socket);
174 void ServerResource::removeClients()
176 map<int, ClientInstance *>::iterator item;
178 for (item = mapClients.begin(); item != mapClients.end(); item++)
180 ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
188 ServiceInstance *ServerResource::createService(int socket, unsigned int context)
190 ServiceInstance *result = NULL;
191 ClientInstance *instance = NULL;
193 if ((instance = getClient(socket)) != NULL)
195 if ((result = instance->getService(context)) == NULL)
197 if ((result = instance->createService(context)) == NULL)
199 _ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
205 _ERR("client doesn't exist [%d]", socket);
211 ServiceInstance *ServerResource::getService(int socket, unsigned int context)
213 ServiceInstance *result = NULL;
214 ClientInstance *instance = NULL;
216 if ((instance = getClient(socket)) != NULL)
218 result = instance->getService(context);
222 _ERR("client doesn't exist [%d]", socket);
228 void ServerResource::removeService(int socket, unsigned int context)
230 ClientInstance *instance = NULL;
232 if ((instance = getClient(socket)) != NULL)
234 instance->removeService(context);
238 _ERR("client doesn't exist [%d]", socket);
242 void ServerResource::removeServices(int socket)
244 ClientInstance *instance = NULL;
246 if ((instance = getClient(socket)) != NULL)
248 instance->removeServices();
252 _ERR("client doesn't exist [%d]", socket);
256 Terminal *ServerResource::getTerminal(unsigned int terminalID)
258 Terminal *result = NULL;
259 map<unsigned int, Terminal *>::iterator item;
261 if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
263 result = item->second;
267 _ERR("Terminal doesn't exist [%d]", terminalID);
273 Terminal *ServerResource::getTerminal(const char *name)
275 Terminal *result = NULL;
276 map<unsigned int, Terminal *>::iterator item;
278 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
280 if (strncmp(name, item->second->getName(), strlen(name)) == 0)
282 result = item->second;
290 Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID)
292 Terminal *result = NULL;
293 map<unsigned int, unsigned int>::iterator item;
295 if ((item = mapReaders.find(readerID)) != mapReaders.end())
297 result = getTerminal(item->second);
301 _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
307 unsigned int ServerResource::getTerminalID(const char *name)
309 unsigned int result = IntegerHandle::INVALID_HANDLE;
310 map<unsigned int, Terminal *>::iterator item;
312 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
314 if (strncmp(name, item->second->getName(), strlen(name)) == 0)
316 result = item->first;
324 unsigned int ServerResource::createSession(int socket, unsigned int context, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
326 unsigned int result = -1;
327 Terminal *temp = NULL;
328 ServiceInstance *instance = NULL;
330 if ((instance = getService(socket, context)) != NULL)
332 if ((temp = getTerminalByReaderID(readerID)) != NULL)
334 result = instance->openSession(temp, certHashes, caller);
339 _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
345 ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
347 ServerSession *result = NULL;
348 ServiceInstance *instance = NULL;
350 if ((instance = getService(socket, context)) != NULL)
352 result = instance->getSession(sessionID);
356 _ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
362 unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
364 unsigned int result = -1;
365 ServiceInstance *instance = NULL;
367 if ((instance = getService(socket, context)) != NULL)
369 result = instance->getChannelCountBySession(sessionID);
373 _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
379 void ServerResource::removeSession(int socket, unsigned int context, unsigned int sessionID)
381 ServiceInstance *instance = NULL;
383 if ((instance = getService(socket, context)) != NULL)
385 instance->closeSession(sessionID);
389 _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
393 bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
396 AccessControlList *acList = NULL;
398 /* request open channel sequence */
399 if ((acList = getAccessControlList(channel)) != NULL)
401 PKCS15 pkcs15(channel);
403 acList->loadACL(channel);
404 result = acList->isAuthorizedAccess(aid, hashes);
408 _ERR("acList is null");
415 int ServerResource::_openLogicalChannel(Terminal *terminal)
423 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
424 rv = terminal->transmitSync(command, response);
425 if (rv == 0 && response.getLength() >= 2)
427 ResponseHelper resp(response);
429 if (resp.getStatus() == 0)
431 result = resp.getDataField()[0];
435 _ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
438 /* TODO : if there is no more channel, return error code */
439 _ERR("no more logical channel");
446 _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
452 int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
460 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
461 rv = terminal->transmitSync(command, response);
462 if (rv == 0 && response.getLength() >= 2)
464 ResponseHelper resp(response);
466 if (resp.getStatus() == 0)
468 _DBG("channel closed [%d]", channelNum);
473 _ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
478 _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
484 unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
485 throw(ExceptionBase &)
487 unsigned int result = IntegerHandle::INVALID_HANDLE;
489 ServerChannel *channel = NULL;
491 /* open logical channel */
492 if (channelType == 1)
494 channelNum = _openLogicalChannel(terminal);
497 _DBG("channelNum [%d]", channelNum);
501 _ERR("_openLogicalChannel failed [%d]", channelNum);
502 throw ExceptionBase(SCARD_ERROR_NOT_ENOUGH_RESOURCE);
506 /* create channel instance */
507 result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
508 if (result == IntegerHandle::INVALID_HANDLE)
510 _ERR("channel is null.");
512 /* close logical channel */
515 _closeLogicalChannel(terminal, channelNum);
517 throw ExceptionBase(SCARD_ERROR_OUT_OF_MEMORY);
520 channel = service->getChannel(result);
523 if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
524 aid, service->getParent()->getCertificationHashes()) == true)
529 if (aid == PKCS15::PKCS15_AID)
531 PKCS15 pkcs15(channel);
533 if (pkcs15.isClosed() == false)
535 /* remove privilege mode */
536 channel->unsetPrivilegeMode();
540 _ERR("select failed");
542 service->closeChannel(result);
543 throw ExceptionBase(SCARD_ERROR_IO_FAILED);
548 FileObject file(channel);
550 rv = file.select(aid);
551 if (rv == FileObject::SUCCESS)
553 /* remove privilege mode */
554 channel->unsetPrivilegeMode();
558 _ERR("select failed [%d]", rv);
560 service->closeChannel(result);
561 throw ExceptionBase(SCARD_ERROR_IO_FAILED);
567 _ERR("unauthorized access");
569 service->closeChannel(result);
570 throw ExceptionBase(SCARD_ERROR_SECURITY_NOT_ALLOWED);
576 unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
577 throw(ExceptionBase &)
579 unsigned int result = -1;
580 ServiceInstance *service = NULL;
582 if ((service = getService(socket, context)) != NULL)
584 if (service->isVaildSessionHandle(sessionID) == true)
586 ServerSession *session = NULL;
587 Terminal *terminal = NULL;
589 terminal = service->getTerminal(sessionID);
590 session = service->getSession(sessionID);
591 if (terminal != NULL && session != NULL)
593 result = _createChannel(terminal, service, channelType, sessionID, aid);
594 if (result == IntegerHandle::INVALID_HANDLE)
596 _ERR("create channel failed [%d]", sessionID);
601 _ERR("session is invalid [%d]", sessionID);
602 throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
607 _ERR("session is invalid [%d]", sessionID);
608 throw ExceptionBase(SCARD_ERROR_ILLEGAL_PARAM);
613 _ERR("getService is failed [%d] [%d]", socket, context);
614 throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
620 Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
622 Channel *result = NULL;
623 ServiceInstance *instance = NULL;
625 if ((instance = getService(socket, context)) != NULL)
627 result = instance->getChannel(channelID);
631 _ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
637 void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
639 ServiceInstance *instance = NULL;
641 if ((instance = getService(socket, context)) != NULL)
643 instance->closeChannel(channelID);
647 _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
651 AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
653 AccessControlList *result = NULL;
654 map<Terminal *, AccessControlList *>::iterator item;
656 if ((item = mapACL.find(terminal)) == mapACL.end())
658 /* load access control */
659 result = new GPSEACL();
662 mapACL.insert(make_pair(terminal, result));
666 _ERR("alloc failed");
671 result = item->second;
677 AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
679 AccessControlList *result = NULL;
680 map<Terminal *, AccessControlList *>::iterator item;
682 if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
684 /* load access control */
685 result = new GPSEACL();
688 mapACL.insert(make_pair(channel->getTerminal(), result));
692 _ERR("alloc failed");
697 result = item->second;
703 Terminal *ServerResource::createInstance(void *library)
705 Terminal *terminal = NULL;
706 terminal_create_instance_fn createInstance = NULL;
708 /* create se instance */
709 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
710 if (createInstance != NULL)
712 terminal = (Terminal *)createInstance();
713 if (terminal != NULL)
715 _DBG("terminal [%p]", terminal);
719 _ERR("terminal is null");
724 _ERR("create_instance is null [%d]", errno);
730 bool ServerResource::appendSELibrary(char *library)
732 void *libHandle = NULL;
735 libHandle = dlopen(library, RTLD_LAZY);
736 if (libHandle != NULL)
738 Terminal *terminal = NULL;
740 terminal = createInstance(libHandle);
741 if (terminal != NULL)
743 unsigned int handle = IntegerHandle::assignHandle();
745 mapTerminals.insert(make_pair(handle, terminal));
746 libraries.push_back(libHandle);
748 terminal->setStatusCallback(&ServerResource::terminalCallback);
750 _DBG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
752 if (terminal->isSecureElementPresence() == true)
754 createReader(handle);
761 _ERR("terminal is null [%s]", library);
768 _ERR("it is not se file [%s] [%d]", library, errno);
774 int ServerResource::loadSecureElements()
778 if (seLoaded == false)
781 struct dirent *entry;
783 if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
785 while ((entry = readdir(dir)) != NULL)
787 if (strncmp(entry->d_name, ".", 1) != 0 &&
788 strncmp(entry->d_name, "..", 2) != 0)
792 /* TODO : need additional name rule :) */
794 /* append each files */
795 snprintf(fullPath, sizeof(fullPath),
796 "%s/%s", OMAPI_SE_PATH, entry->d_name);
798 SCARD_DEBUG("se name [%s]", fullPath);
800 result = appendSELibrary(fullPath);
817 void ServerResource::unloadSecureElements()
819 if (seLoaded == true)
822 map<unsigned int, Terminal *>::iterator item;
824 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
826 item->second->finalize();
828 IntegerHandle::releaseHandle(item->first);
831 mapTerminals.clear();
833 for (i = 0; i < libraries.size(); i++)
835 if (libraries[i] != NULL)
836 dlclose(libraries[i]);
845 bool ServerResource::isValidReaderHandle(unsigned int reader)
847 return (getTerminalByReaderID(reader) != NULL);
850 bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
852 ServiceInstance *instance = NULL;
854 return (((instance = getService(socket, context)) != NULL) && (instance->isVaildSessionHandle(session)));
857 int ServerResource::getReadersInformation(ByteArray &info)
860 unsigned char *buffer = NULL;
861 unsigned int length = 0;
862 unsigned int offset = 0;
863 unsigned int nameLen = 0;
865 if (mapReaders.size() > 0)
867 Terminal *terminal = NULL;
868 map<unsigned int, unsigned int>::iterator item;
870 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
872 if (item->second != IntegerHandle::INVALID_HANDLE)
874 terminal = getTerminal(item->second);
875 if (terminal != NULL)
877 if (terminal->isSecureElementPresence())
879 length += sizeof(nameLen) + strlen(terminal->getName()) + sizeof(unsigned int);
886 buffer = new unsigned char[length];
889 memset(buffer, 0, length);
891 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
893 if (item->second != IntegerHandle::INVALID_HANDLE)
895 terminal = getTerminal(item->second);
896 if (terminal != NULL)
898 if (terminal->isSecureElementPresence())
900 nameLen = strlen(terminal->getName());
902 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
903 offset += sizeof(nameLen);
905 memcpy(buffer + offset, terminal->getName(), nameLen);
908 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
909 offset += sizeof(unsigned int);
915 info.setBuffer(buffer, length);
920 _ERR("alloc failed");
926 _INFO("no secure element");
932 bool ServerResource::sendMessageToAllClients(Message &msg)
935 map<int, ClientInstance *>::iterator item;
937 for (item = mapClients.begin(); item != mapClients.end(); item++)
939 if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
946 void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
948 _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
952 case Terminal::NOTIFY_SE_AVAILABLE :
954 ServerResource &instance = ServerResource::getInstance();
955 unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
958 _INFO("[NOTIFY_SE_AVAILABLE]");
960 terminalID = instance.getTerminalID((char *)terminal);
961 if (terminalID != IntegerHandle::INVALID_HANDLE)
963 /* send all client to refresh reader */
964 msg.message = msg.MSG_NOTIFY_SE_INSERTED;
965 msg.param1 = instance.createReader(terminalID);
966 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
968 instance.sendMessageToAllClients(msg);
973 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
975 ServerResource &instance = ServerResource::getInstance();
976 unsigned int readerID = IntegerHandle::INVALID_HANDLE;
979 _INFO("[NOTIFY_SE_NOT_AVAILABLE]");
981 readerID = instance.getReaderID((char *)terminal);
983 /* send all client to refresh reader */
984 msg.message = msg.MSG_NOTIFY_SE_REMOVED;
985 msg.param1 = readerID;
986 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
988 instance.sendMessageToAllClients(msg);
989 instance.removeReader(readerID);
994 _DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
999 unsigned int ServerResource::createReader(unsigned int terminalID)
1001 unsigned int result = -1;
1003 result = IntegerHandle::assignHandle();
1005 mapReaders.insert(make_pair(result, terminalID));
1010 unsigned int ServerResource::getReaderID(const char *name)
1012 unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
1014 terminalID = getTerminalID(name);
1015 if (terminalID != IntegerHandle::INVALID_HANDLE)
1017 map<unsigned int, unsigned int>::iterator item;
1019 for (item = mapReaders.begin(); item != mapReaders.end(); item++)
1021 if (item->second == terminalID)
1023 result = item->first;
1032 void ServerResource::removeReader(unsigned int readerID)
1034 map<unsigned int, unsigned int>::iterator item;
1036 if ((item = mapReaders.find(readerID)) != mapReaders.end())
1038 item->second = IntegerHandle::INVALID_HANDLE;
1042 } /* namespace smartcard_service_api */
1044 using namespace smartcard_service_api;
1046 EXTERN_API void server_resource_set_main_loop_instance(void *instance)
1048 ServerResource::getInstance().setMainLoopInstance(instance);