2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
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.
18 /* standard library header */
25 /* SLP library header */
29 #include "ServerResource.h"
30 #include "TerminalInterface.h"
31 #include "APDUHelper.h"
32 #include "SignatureHelper.h"
35 namespace smartcard_service_api
37 unsigned int IntegerHandle::newHandle = 0;
38 set<unsigned int> IntegerHandle::setHandles;
39 PMutex IntegerHandle::mutexLock;
41 unsigned int IntegerHandle::assignHandle()
45 pair<set<unsigned int>::iterator, bool> result;
50 if (newHandle == (unsigned int)-1)
55 result = setHandles.insert(newHandle);
58 while (!result.second);
61 SCARD_DEBUG("assign handle : newHandle [%d]", newHandle);
66 void IntegerHandle::releaseHandle(unsigned int handle)
68 SCARD_DEBUG("will be released : Handle [%d]", handle);
72 setHandles.erase(handle);
76 #define OMAPI_SE_PATH "/usr/lib/se"
78 ServerResource::ServerResource()
82 serverIPC = ServerIPC::getInstance();
83 serverDispatcher = ServerDispatcher::getInstance();
91 ServerResource::~ServerResource()
95 ServerResource &ServerResource::getInstance()
97 static ServerResource serverResource;
99 return serverResource;
102 bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
106 if (getClient(socket) == NULL)
108 ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
109 if (instance != NULL)
111 mapClients.insert(make_pair(socket, instance));
116 SCARD_DEBUG_ERR("alloc failed");
121 SCARD_DEBUG_ERR("client already exist [%d]", socket);
127 ClientInstance *ServerResource::getClient(int socket)
129 ClientInstance *result = NULL;
130 map<int, ClientInstance *>::iterator item;
132 if ((item = mapClients.find(socket)) != mapClients.end())
134 result = item->second;
140 void ServerResource::setPID(int socket, int pid)
142 map<int, ClientInstance *>::iterator item;
144 if ((item = mapClients.find(socket)) != mapClients.end())
146 if (item->second->getPID() < 0)
147 item->second->setPID(pid);
151 void ServerResource::removeClient(int socket)
153 map<int, ClientInstance *>::iterator item;
155 if ((item = mapClients.find(socket)) != mapClients.end())
157 ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
160 mapClients.erase(item);
164 SCARD_DEBUG("client exists already [%d]", socket);
168 void ServerResource::removeClients()
170 map<int, ClientInstance *>::iterator item;
172 for (item = mapClients.begin(); item != mapClients.end(); item++)
174 ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
182 bool ServerResource::createService(int socket, unsigned int context)
185 ClientInstance *instance = NULL;
187 if ((instance = getClient(socket)) != NULL)
189 if ((result = instance->createService(context)) == false)
191 SCARD_DEBUG_ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
196 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
202 ServiceInstance *ServerResource::getService(int socket, unsigned int context)
204 ServiceInstance *result = NULL;
205 ClientInstance *instance = NULL;
207 if ((instance = getClient(socket)) != NULL)
209 result = instance->getService(context);
213 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
219 void ServerResource::removeService(int socket, unsigned int context)
221 ClientInstance *instance = NULL;
223 if ((instance = getClient(socket)) != NULL)
225 instance->removeService(context);
229 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
233 void ServerResource::removeServices(int socket)
235 ClientInstance *instance = NULL;
237 if ((instance = getClient(socket)) != NULL)
239 instance->removeServices();
243 SCARD_DEBUG_ERR("client doesn't exist [%d]", socket);
247 Terminal *ServerResource::getTerminal(unsigned int terminalID)
249 Terminal *result = NULL;
250 map<unsigned int, Terminal *>::iterator item;
252 if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
254 result = item->second;
258 SCARD_DEBUG_ERR("Terminal doesn't exist [%d]", terminalID);
264 Terminal *ServerResource::getTerminal(const char *name)
266 Terminal *result = NULL;
267 map<unsigned int, Terminal *>::iterator item;
269 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
271 if (strncmp(name, item->second->getName(), strlen(name)) == 0)
273 result = item->second;
281 unsigned int ServerResource::createSession(int socket, unsigned int context, unsigned int terminalID, ByteArray packageCert, void *caller)
283 unsigned int result = -1;
284 Terminal *temp = NULL;
285 ServiceInstance *instance = NULL;
287 if ((instance = getService(socket, context)) != NULL)
289 if ((temp = getTerminal(terminalID)) != NULL)
291 result = instance->openSession(temp, packageCert, caller);
296 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
302 ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
304 ServerSession *result = NULL;
305 ServiceInstance *instance = NULL;
307 if ((instance = getService(socket, context)) != NULL)
309 result = instance->getSession(sessionID);
313 SCARD_DEBUG_ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
319 unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
321 unsigned int result = -1;
322 ServiceInstance *instance = NULL;
324 if ((instance = getService(socket, context)) != NULL)
326 result = instance->getChannelCountBySession(sessionID);
330 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
336 void ServerResource::removeSession(int socket, unsigned int context, unsigned int sessionID)
338 ServiceInstance *instance = NULL;
340 if ((instance = getService(socket, context)) != NULL)
342 instance->closeSession(sessionID);
346 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
350 unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
352 unsigned int result = -1;
353 ServiceInstance *client = NULL;
355 if ((client = getService(socket, context)) != NULL)
357 if (client->isVaildSessionHandle(sessionID) == true)
359 AccessControlList *acList = NULL;
360 ServerSession *session = NULL;
361 Terminal *terminal = NULL;
363 terminal = client->getTerminal(sessionID);
364 session = client->getSession(sessionID);
365 if (terminal != NULL && session != NULL)
370 ByteArray selectResponse;
372 char filename[1024] = { 0, };
374 /* check exceptional case */
375 SignatureHelper::getProcessName(client->getParent()->getPID(), filename, sizeof(filename));
376 if (strncmp(filename, "ozD3Dw1MZruTDKHWGgYaDib2B2LV4/nfT+8b/g1Vsk8=", sizeof(filename)) != 0)
379 certHash = session->packageCert;
381 certHash = client->getParent()->getCertificationHash();
383 /* request open channel sequence */
384 if ((acList = getAccessControlList(terminal)) == NULL)
386 SCARD_DEBUG_ERR("acList is null");
391 if (acList->isAuthorizedAccess(aid, certHash) == false)
393 SCARD_DEBUG_ERR("unauthorized access, aid %s, hash %s", aid.toString(), certHash.toString());
399 if (channelType == 1)
404 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
405 rv = terminal->transmitSync(command, response);
407 if (rv == 0 && response.getLength() >= 2)
409 ResponseHelper resp(response);
411 if (resp.getStatus() == 0)
413 channelNum = resp.getDataField()[0];
415 SCARD_DEBUG("channelNum [%d]", channelNum);
419 SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), response[response.getLength() - 2], response[response.getLength() - 1]);
426 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
433 command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelNum, aid);
434 rv = terminal->transmitSync(command, selectResponse);
435 if (rv == 0 && selectResponse.getLength() >= 2)
437 ResponseHelper resp(selectResponse);
439 if (resp.getStatus() == 0)
441 result = client->openChannel(sessionID, channelNum);
442 if (result != IntegerHandle::INVALID_HANDLE)
444 ServerChannel *temp = (ServerChannel *)client->getChannel(result);
447 /* set select response */
448 temp->selectResponse = selectResponse;
452 SCARD_DEBUG_ERR("IS IT POSSIBLE??????????????????");
457 SCARD_DEBUG_ERR("channel is null.");
462 SCARD_DEBUG_ERR("status word [%d][ 0x%02X 0x%02X ]", resp.getStatus(), selectResponse[selectResponse.getLength() - 2], selectResponse[selectResponse.getLength() - 1]);
467 SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, selectResponse.getLength());
473 SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
478 SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
483 SCARD_DEBUG_ERR("getClient is failed [%d] [%d]", socket, context);
489 Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
491 Channel *result = NULL;
492 ServiceInstance *instance = NULL;
494 if ((instance = getService(socket, context)) != NULL)
496 result = instance->getChannel(channelID);
500 SCARD_DEBUG_ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
506 void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
508 ServiceInstance *instance = NULL;
510 if ((instance = getService(socket, context)) != NULL)
512 instance->closeChannel(channelID);
516 SCARD_DEBUG_ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
520 AccessControlList *ServerResource::getAccessControlList(Terminal *terminal)
522 AccessControlList *result = NULL;
523 map<Terminal *, AccessControlList *>::iterator item;
525 if ((item = mapACL.find(terminal)) == mapACL.end())
527 ServerChannel *channel = new ServerChannel(NULL, NULL, 0, terminal);
530 /* load access control */
531 result = new GPSEACL(channel);
536 mapACL.insert(make_pair(terminal, result));
540 SCARD_DEBUG_ERR("alloc failed");
545 SCARD_DEBUG_ERR("alloc failed");
550 result = item->second;
556 Terminal *ServerResource::createInstance(void *library)
558 Terminal *terminal = NULL;
559 terminal_create_instance_fn createInstance = NULL;
561 /* create se instance */
562 createInstance = (terminal_create_instance_fn)dlsym(library, "create_instance");
563 if (createInstance != NULL)
565 terminal = (Terminal *)createInstance();
566 if (terminal != NULL)
568 SCARD_DEBUG("terminal [%p]", terminal);
572 SCARD_DEBUG_ERR("terminal is null");
577 SCARD_DEBUG_ERR("create_instance is null [%d]", errno);
583 bool ServerResource::appendSELibrary(char *library)
585 void *libHandle = NULL;
588 libHandle = dlopen(library, RTLD_LAZY);
589 if (libHandle != NULL)
591 Terminal *terminal = NULL;
593 terminal = createInstance(libHandle);
594 if (terminal != NULL)
596 unsigned int handle = IntegerHandle::assignHandle();
598 mapTerminals.insert(make_pair(handle, terminal));
599 libraries.push_back(libHandle);
601 terminal->setStatusCallback(&ServerResource::terminalCallback);
603 SCARD_DEBUG("register success [%s] [%p] [%s] [%p]", library, libHandle, terminal->getName(), terminal);
609 SCARD_DEBUG_ERR("terminal is null [%s]", library);
616 SCARD_DEBUG_ERR("it is not se file [%s] [%d]", library, errno);
622 int ServerResource::loadSecureElements()
627 struct dirent *entry = NULL;
629 if ((dir = opendir(OMAPI_SE_PATH)) != NULL)
631 while ((entry = readdir(dir)) != NULL)
633 if (strncmp(entry->d_name, ".", 1) != 0 && strncmp(entry->d_name, "..", 2) != 0)
635 char fullPath[1024] = { 0, };
637 /* TODO : need additional name rule :) */
639 /* open each files */
642 snprintf(fullPath, sizeof(fullPath), "%s/%s", OMAPI_SE_PATH, entry->d_name);
644 SCARD_DEBUG("se name [%s]", fullPath);
646 result = appendSELibrary(fullPath);
662 void ServerResource::unloadSecureElements()
665 map<unsigned int, Terminal *>::iterator item;
667 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
669 item->second->finalize();
671 IntegerHandle::releaseHandle(item->first);
674 mapTerminals.clear();
676 for (i = 0; i < libraries.size(); i++)
678 if (libraries[i] != NULL)
679 dlclose(libraries[i]);
685 bool ServerResource::isValidReaderHandle(unsigned int reader)
687 return (getTerminal(reader) != NULL);
690 bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
692 ServiceInstance *instance = NULL;
694 return (((instance = getService(socket, context)) != NULL) && (getService(socket, context)->isVaildSessionHandle(session)));
697 int ServerResource::getReadersInformation(ByteArray &info)
700 unsigned char *buffer = NULL;
701 unsigned int length = 0;
702 unsigned int offset = 0;
703 unsigned int nameLen = 0;
705 if (mapTerminals.size() > 0)
707 map<unsigned int, Terminal *>::iterator item;
709 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
711 if (item->second->isSecureElementPresence())
713 length += sizeof(nameLen) + strlen(item->second->getName()) + sizeof(unsigned int);
718 buffer = new unsigned char[length];
721 memset(buffer, 0, length);
723 for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
725 if (item->second->isSecureElementPresence())
727 nameLen = strlen(item->second->getName());
729 memcpy(buffer + offset, &nameLen, sizeof(nameLen));
730 offset += sizeof(nameLen);
732 memcpy(buffer + offset, item->second->getName(), nameLen);
735 memcpy(buffer + offset, &item->first, sizeof(unsigned int));
736 offset += sizeof(unsigned int);
740 info.setBuffer(buffer, length);
745 SCARD_DEBUG_ERR("alloc failed");
751 SCARD_DEBUG("no secure element");
757 bool ServerResource::sendMessageToAllClients(Message &msg)
760 map<int, ClientInstance *>::iterator item;
762 for (item = mapClients.begin(); item != mapClients.end(); item++)
764 if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
771 void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
777 case Terminal::NOTIFY_SE_AVAILABLE :
781 SCARD_DEBUG("[NOTIFY_SE_AVAILABLE]");
783 SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
785 /* send all client to refresh reader */
786 msg.message = msg.MSG_NOTIFY_SE_INSERTED;
787 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
789 ServerResource::getInstance().sendMessageToAllClients(msg);
793 case Terminal::NOTIFY_SE_NOT_AVAILABLE :
797 SCARD_DEBUG("[NOTIFY_SE_NOT_AVAILABLE]");
799 SCARD_DEBUG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
801 /* send all client to refresh reader */
802 msg.message = msg.MSG_NOTIFY_SE_REMOVED;
803 msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
805 ServerResource::getInstance().sendMessageToAllClients(msg);
816 } /* namespace smartcard_service_api */