#include "TerminalInterface.h"
#include "APDUHelper.h"
#include "SignatureHelper.h"
-#include "GPSEACL.h"
+#include "GPACE.h"
+#include "PKCS15.h"
+#ifdef USE_GDBUS
+#include "ServerGDBus.h"
+#endif
+#include "smartcard-daemon.h"
#ifndef EXTERN_API
#define EXTERN_API __attribute__((visibility("default")))
#endif
+using namespace std;
+
namespace smartcard_service_api
{
unsigned int IntegerHandle::newHandle = 0;
#define OMAPI_SE_PATH "/usr/lib/se"
- ServerResource::ServerResource()
- : mainLoop(NULL), seLoaded(false)
+ ServerResource::ServerResource() : seLoaded(false)
{
_BEGIN();
-
+#ifndef USE_GDBUS
serverIPC = ServerIPC::getInstance();
serverDispatcher = ServerDispatcher::getInstance();
-
+#endif
_END();
}
return serverResource;
}
- bool ServerResource::createClient(void *ioChannel, int socket, int watchID, int state, int pid)
+#ifdef USE_GDBUS
+ bool ServerResource::createClient(const char *name, pid_t pid)
+ {
+ bool result = false;
+
+ if (getClient(name) == NULL)
+ {
+ ClientInstance *instance = new ClientInstance(name, pid);
+ if (instance != NULL)
+ {
+ mapClients.insert(make_pair(name, instance));
+ result = true;
+ }
+ else
+ {
+ _ERR("alloc failed");
+ }
+ }
+ else
+ {
+ _ERR("client already exist, name [%s]", name);
+ }
+
+ return result;
+ }
+
+ ClientInstance *ServerResource::getClient(const char *name)
+ {
+ ClientInstance *result = NULL;
+ map<string, ClientInstance *>::iterator item;
+
+ if ((item = mapClients.find(name)) != mapClients.end())
+ {
+ result = item->second;
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeClient(const char *name)
+ {
+ map<string, ClientInstance *>::iterator item;
+
+ if ((item = mapClients.find(name)) != mapClients.end())
+ {
+ delete item->second;
+ mapClients.erase(item);
+ }
+ else
+ {
+ _DBG("client removed already, name [%s]", name);
+ }
+ }
+
+ void ServerResource::removeClients()
+ {
+ map<string, ClientInstance *>::iterator item;
+
+ for (item = mapClients.begin(); item != mapClients.end(); item++)
+ {
+ delete item->second;
+ }
+
+ mapClients.clear();
+ }
+
+ int ServerResource::getClientCount() const
+ {
+ return (int)mapClients.size();
+ }
+
+ ServiceInstance *ServerResource::createService(const char *name)
+ {
+ ServiceInstance *result = NULL;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(name)) != NULL)
+ {
+ if ((result = instance->createService()) == NULL)
+ {
+ _ERR("ClientInstance::createService failed [%d]", name);
+ }
+ }
+ else
+ {
+ _ERR("client doesn't exist, name [%s]", name);
+ }
+
+ return result;
+ }
+
+ ServiceInstance *ServerResource::getService(const char *name, unsigned int handle)
+ {
+ ServiceInstance *result = NULL;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(name)) != NULL)
+ {
+ result = instance->getService(handle);
+ }
+ else
+ {
+ _ERR("client doesn't exist, name [%s]", name);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeService(const char *name, unsigned int handle)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(name)) != NULL)
+ {
+ instance->removeService(handle);
+ if (instance->getServiceCounts() == 0) {
+
+ /* remove client instance */
+ removeClient(name);
+ }
+ }
+ else
+ {
+ _ERR("client doesn't exist, name [%s]", name);
+ }
+ }
+
+ void ServerResource::removeServices(const char *name)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(name)) != NULL)
+ {
+ instance->removeServices();
+
+ /* remove client instance */
+ removeClient(name);
+ }
+ else
+ {
+ _ERR("client doesn't exist, name [%s]", name);
+ }
+ }
+
+ unsigned int ServerResource::createSession(const char *name, unsigned int handle, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
+ {
+ unsigned int result = -1;
+ Terminal *temp = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ if ((temp = getTerminalByReaderID(readerID)) != NULL)
+ {
+ result = instance->openSession(temp, certHashes, caller);
+ }
+ }
+ else
+ {
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+
+ return result;
+ }
+
+ ServerSession *ServerResource::getSession(const char *name, unsigned int handle, unsigned int sessionID)
+ {
+ ServerSession *result = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ result = instance->getSession(sessionID);
+ }
+ else
+ {
+ _ERR("Session doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, sessionID);
+ }
+
+ return result;
+ }
+
+ bool ServerResource::isValidSessionHandle(const char *name, unsigned int handle, unsigned int session)
+ {
+ ServiceInstance *instance = NULL;
+
+ return (((instance = getService(name, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
+ }
+
+ unsigned int ServerResource::getChannelCount(const char *name, unsigned int handle, unsigned int sessionID)
+ {
+ unsigned int result = -1;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ result = instance->getChannelCountBySession(sessionID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeSession(const char *name, unsigned int handle, unsigned int sessionID)
+ {
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ instance->closeSession(sessionID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+ }
+
+ unsigned int ServerResource::createChannel(const char *name, unsigned int handle, unsigned int sessionID, int channelType, ByteArray aid)
+ throw(ExceptionBase &)
+ {
+ unsigned int result = -1;
+ ServiceInstance *service = NULL;
+
+ if ((service = getService(name, handle)) != NULL)
+ {
+ if (service->isVaildSessionHandle(sessionID) == true)
+ {
+ ServerSession *session = NULL;
+ Terminal *terminal = NULL;
+
+ terminal = service->getTerminal(sessionID);
+ session = service->getSession(sessionID);
+ if (terminal != NULL && session != NULL)
+ {
+ result = _createChannel(terminal, service, channelType, sessionID, aid);
+ if (result == IntegerHandle::INVALID_HANDLE)
+ {
+ _ERR("create channel failed [%d]", sessionID);
+ }
+ }
+ else
+ {
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
+ }
+ }
+ else
+ {
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
+ }
+ }
+ else
+ {
+ _ERR("getService is failed, name [%s], handle [%d]", name, handle);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
+ }
+
+ return result;
+ }
+
+ Channel *ServerResource::getChannel(const char *name, unsigned int handle, unsigned int channelID)
+ {
+ Channel *result = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ result = instance->getChannel(channelID);
+ }
+ else
+ {
+ _ERR("Channel doesn't exist : name [%s], handle [%d], handle [%d]", name, handle, channelID);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeChannel(const char *name, unsigned int handle, unsigned int channelID)
+ {
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(name, handle)) != NULL)
+ {
+ instance->closeChannel(channelID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : name [%s], handle [%d]", name, handle);
+ }
+ }
+#else
+ bool ServerResource::createClient(void *ioChannel, int socket,
+ int watchID, int state, int pid)
{
bool result = false;
if (getClient(socket) == NULL)
{
- ClientInstance *instance = new ClientInstance(ioChannel, socket, watchID, state, pid);
+ ClientInstance *instance = new ClientInstance(ioChannel,
+ socket, watchID, state, pid);
if (instance != NULL)
{
mapClients.insert(make_pair(socket, instance));
}
else
{
- _ERR("client already exist [%d]", socket);
+ _ERR("client already exist, socket[%d]", socket);
+ }
+
+ return result;
+ }
+
+ bool ServerResource::createClient(int pid)
+ {
+ bool result = false;
+
+ if (getClient(pid) == NULL)
+ {
+ ClientInstance *instance = new ClientInstance(pid);
+ if (instance != NULL)
+ {
+ mapClients.insert(make_pair(pid, instance));
+ result = true;
+ }
+ else
+ {
+ _ERR("alloc failed");
+ }
+ }
+ else
+ {
+ _ERR("client already exist, pid[%d]", pid);
}
return result;
return result;
}
+ const ClientInstance *ServerResource::getClient(int socket) const
+ {
+ const ClientInstance *result = NULL;
+ map<int, ClientInstance *>::const_iterator item;
+
+ if ((item = mapClients.find(socket)) != mapClients.end())
+ {
+ result = item->second;
+ }
+
+ return result;
+ }
+
void ServerResource::setPID(int socket, int pid)
{
map<int, ClientInstance *>::iterator item;
}
}
- int ServerResource::getClientCount()
- {
- return (int)mapClients.size();
- }
-
void ServerResource::removeClient(int socket)
{
map<int, ClientInstance *>::iterator item;
if ((item = mapClients.find(socket)) != mapClients.end())
{
+#ifndef USE_GDBUS
ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
-
+#endif
delete item->second;
mapClients.erase(item);
}
for (item = mapClients.begin(); item != mapClients.end(); item++)
{
- ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
-
- delete item->second;
+#ifndef USE_GDBUS
+ ServerIPC::getInstance()->releaseClient(item->second->getIOChannel(), item->second->getSocket(), item->second->getWatchID());
+#endif
+ delete item->second;
+ }
+
+ mapClients.clear();
+ }
+
+ int ServerResource::getClientCount() const
+ {
+ return (int)mapClients.size();
+ }
+
+ ServiceInstance *ServerResource::createService(int socket)
+ {
+ ServiceInstance *result = NULL;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ if ((result = instance->createService()) == NULL)
+ {
+ _ERR("ClientInstance::createService failed [%d]", socket);
+ }
+ }
+ else
+ {
+ _ERR("client doesn't exist [%d]", socket);
+ }
+
+ return result;
+ }
+
+ ServiceInstance *ServerResource::getService(int socket, unsigned int handle)
+ {
+ ServiceInstance *result = NULL;
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ result = instance->getService(handle);
+ }
+ else
+ {
+ _ERR("client doesn't exist [%d]", socket);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeService(int socket, unsigned int handle)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ instance->removeService(handle);
+ }
+ else
+ {
+ _ERR("client doesn't exist [%d]", socket);
+ }
+ }
+
+ void ServerResource::removeServices(int socket)
+ {
+ ClientInstance *instance = NULL;
+
+ if ((instance = getClient(socket)) != NULL)
+ {
+ instance->removeServices();
+ }
+ else
+ {
+ _ERR("client doesn't exist [%d]", socket);
+ }
+ }
+
+ unsigned int ServerResource::createSession(int socket, unsigned int handle, unsigned int readerID, const vector<ByteArray> &certHashes, void *caller)
+ {
+ unsigned int result = -1;
+ Terminal *temp = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, handle)) != NULL)
+ {
+ if ((temp = getTerminalByReaderID(readerID)) != NULL)
+ {
+ result = instance->openSession(temp, certHashes, caller);
+ }
+ }
+ else
+ {
+ _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
+ }
+
+ return result;
+ }
+
+ ServerSession *ServerResource::getSession(int socket, unsigned int handle, unsigned int sessionID)
+ {
+ ServerSession *result = NULL;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, handle)) != NULL)
+ {
+ result = instance->getSession(sessionID);
+ }
+ else
+ {
+ _ERR("Session doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, sessionID);
+ }
+
+ return result;
+ }
+
+ bool ServerResource::isValidSessionHandle(int socket, unsigned int handle, unsigned int session)
+ {
+ ServiceInstance *instance = NULL;
+
+ return (((instance = getService(socket, handle)) != NULL) && (instance->isVaildSessionHandle(session)));
+ }
+
+ unsigned int ServerResource::getChannelCount(int socket, unsigned int handle, unsigned int sessionID)
+ {
+ unsigned int result = -1;
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, handle)) != NULL)
+ {
+ result = instance->getChannelCountBySession(sessionID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
+ }
+
+ return result;
+ }
+
+ void ServerResource::removeSession(int socket, unsigned int handle, unsigned int sessionID)
+ {
+ ServiceInstance *instance = NULL;
+
+ if ((instance = getService(socket, handle)) != NULL)
+ {
+ instance->closeSession(sessionID);
+ }
+ else
+ {
+ _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
}
-
- mapClients.clear();
}
- ServiceInstance *ServerResource::createService(int socket, unsigned int context)
+ unsigned int ServerResource::createChannel(int socket, unsigned int handle, unsigned int sessionID, int channelType, const ByteArray &aid)
+ throw(ExceptionBase &)
{
- ServiceInstance *result = NULL;
- ClientInstance *instance = NULL;
+ unsigned int result = -1;
+ ServiceInstance *service = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((service = getService(socket, handle)) != NULL)
{
- if ((result = instance->getService(context)) == NULL)
+ if (service->isVaildSessionHandle(sessionID) == true)
{
- if ((result = instance->createService(context)) == NULL)
+ ServerSession *session = NULL;
+ Terminal *terminal = NULL;
+
+ terminal = service->getTerminal(sessionID);
+ session = service->getSession(sessionID);
+ if (terminal != NULL && session != NULL)
+ {
+ result = _createChannel(terminal, service, channelType, sessionID, aid);
+ if (result == IntegerHandle::INVALID_HANDLE)
+ {
+ _ERR("create channel failed [%d]", sessionID);
+ }
+ }
+ else
{
- _ERR("ClientInstance::createService failed [%d] [%d]", socket, context);
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
}
}
+ else
+ {
+ _ERR("session is invalid [%d]", sessionID);
+ throw ExceptionBase(SCARD_ERROR_ILLEGAL_STATE);
+ }
}
else
{
- _ERR("client doesn't exist [%d]", socket);
+ _ERR("getService is failed [%d] [%d]", socket, handle);
+ throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
}
return result;
}
- ServiceInstance *ServerResource::getService(int socket, unsigned int context)
+ Channel *ServerResource::getChannel(int socket, unsigned int handle, unsigned int channelID)
{
- ServiceInstance *result = NULL;
- ClientInstance *instance = NULL;
+ Channel *result = NULL;
+ ServiceInstance *instance = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((instance = getService(socket, handle)) != NULL)
{
- result = instance->getService(context);
+ result = instance->getChannel(channelID);
}
else
{
- _ERR("client doesn't exist [%d]", socket);
+ _ERR("Channel doesn't exist : socket [%d], handle [%d], handle [%d]", socket, handle, channelID);
}
return result;
}
- void ServerResource::removeService(int socket, unsigned int context)
+ void ServerResource::removeChannel(int socket, unsigned int handle, unsigned int channelID)
{
- ClientInstance *instance = NULL;
+ ServiceInstance *instance = NULL;
- if ((instance = getClient(socket)) != NULL)
+ if ((instance = getService(socket, handle)) != NULL)
{
- instance->removeService(context);
+ instance->closeChannel(channelID);
}
else
{
- _ERR("client doesn't exist [%d]", socket);
+ _ERR("getService doesn't exist : socket [%d], handle [%d]", socket, handle);
}
}
-
- void ServerResource::removeServices(int socket)
+#endif
+ Terminal *ServerResource::getTerminal(unsigned int terminalID)
{
- ClientInstance *instance = NULL;
+ Terminal *result = NULL;
+ map<unsigned int, Terminal *>::iterator item;
- if ((instance = getClient(socket)) != NULL)
+ if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
{
- instance->removeServices();
+ result = item->second;
}
else
{
- _ERR("client doesn't exist [%d]", socket);
+ _ERR("Terminal doesn't exist [%d]", terminalID);
}
+
+ return result;
}
- Terminal *ServerResource::getTerminal(unsigned int terminalID)
+ const Terminal *ServerResource::getTerminal(unsigned int terminalID) const
{
- Terminal *result = NULL;
- map<unsigned int, Terminal *>::iterator item;
+ const Terminal *result = NULL;
+ map<unsigned int, Terminal *>::const_iterator item;
if ((item = mapTerminals.find(terminalID)) != mapTerminals.end())
{
return result;
}
- unsigned int ServerResource::getTerminalID(const char *name)
+ const Terminal *ServerResource::getTerminalByReaderID(unsigned int readerID) const
{
- unsigned int result = IntegerHandle::INVALID_HANDLE;
- map<unsigned int, Terminal *>::iterator item;
-
- for (item = mapTerminals.begin(); item != mapTerminals.end(); item++)
- {
- if (strncmp(name, item->second->getName(), strlen(name)) == 0)
- {
- result = item->first;
- break;
- }
- }
-
- return result;
- }
-
- unsigned int ServerResource::createSession(int socket, unsigned int context, unsigned int readerID, vector<ByteArray> &certHashes, void *caller)
- {
- unsigned int result = -1;
- Terminal *temp = NULL;
- ServiceInstance *instance = NULL;
+ const Terminal *result = NULL;
+ map<unsigned int, unsigned int>::const_iterator item;
- if ((instance = getService(socket, context)) != NULL)
+ if ((item = mapReaders.find(readerID)) != mapReaders.end())
{
- if ((temp = getTerminalByReaderID(readerID)) != NULL)
- {
- result = instance->openSession(temp, certHashes, caller);
- }
+ result = getTerminal(item->second);
}
else
{
- _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ _ERR("Terminal doesn't exist, reader ID [%d]", readerID);
}
return result;
}
- ServerSession *ServerResource::getSession(int socket, unsigned int context, unsigned int sessionID)
+ unsigned int ServerResource::getTerminalID(const char *name) const
{
- ServerSession *result = NULL;
- ServiceInstance *instance = NULL;
+ unsigned int result = IntegerHandle::INVALID_HANDLE;
+ map<unsigned int, Terminal *>::const_iterator item;
- if ((instance = getService(socket, context)) != NULL)
- {
- result = instance->getSession(sessionID);
- }
- else
+ for (item = mapTerminals.begin();
+ item != mapTerminals.end(); item++)
{
- _ERR("Session doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, sessionID);
+ if (strncmp(name, item->second->getName(),
+ strlen(name)) == 0)
+ {
+ result = item->first;
+ break;
+ }
}
return result;
}
- unsigned int ServerResource::getChannelCount(int socket, unsigned int context, unsigned int sessionID)
+ bool ServerResource::_isAuthorizedAccess(ServerChannel *channel,
+ const ByteArray &aid, const vector<ByteArray> &hashes)
{
- unsigned int result = -1;
- ServiceInstance *instance = NULL;
+ bool result = false;
+ AccessControlList *acList = NULL;
- if ((instance = getService(socket, context)) != NULL)
- {
- result = instance->getChannelCountBySession(sessionID);
- }
- else
+ /* request open channel sequence */
+ if ((acList = getAccessControlList(channel)) == NULL)
{
- _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
- }
-
- return result;
- }
-
- void ServerResource::removeSession(int socket, unsigned int context, unsigned int sessionID)
- {
- ServiceInstance *instance = NULL;
+ /* load access control defined by Global Platform */
+ GPACE *acl = new GPACE();
+ if (acl != NULL)
+ {
+ int ret;
- if ((instance = getService(socket, context)) != NULL)
- {
- instance->closeSession(sessionID);
+ ret = acl->loadACL(channel);
+ if (ret >= SCARD_ERROR_OK)
+ {
+ acList = acl;
+ addAccessControlList(channel, acList);
+ }
+ else
+ {
+ _ERR("unknown error, 0x%x", -ret);
+ delete acl;
+ }
+ }
+ else
+ {
+ _ERR("alloc failed");
+ }
}
else
{
- _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ acList->loadACL(channel);
}
- }
-
- bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
- {
- bool result = true;
- AccessControlList *acList = NULL;
- /* request open channel sequence */
- if ((acList = getAccessControlList(channel)) != NULL)
+ if (acList != NULL)
{
- PKCS15 pkcs15(channel);
-
- acList->loadACL(channel);
result = acList->isAuthorizedAccess(aid, hashes);
}
- else
- {
- _ERR("acList is null");
- result = false;
- }
return result;
}
/* open channel */
command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
rv = terminal->transmitSync(command, response);
- if (rv == 0 && response.getLength() >= 2)
+ if (rv == 0 && response.size() >= 2)
{
ResponseHelper resp(response);
}
else
{
- _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+ _ERR("transmitSync failed, rv [%d], length [%d]", rv, response.size());
}
return result;
/* open channel */
command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
rv = terminal->transmitSync(command, response);
- if (rv == 0 && response.getLength() >= 2)
+ if (rv == 0 && response.size() >= 2)
{
ResponseHelper resp(response);
}
else
{
- _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+ _ERR("select apdu is failed, rv [%d], length [%d]", rv, response.size());
}
return result;
}
- unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
+ unsigned int ServerResource::_createChannel(Terminal *terminal,
+ ServiceInstance *service, int channelType,
+ unsigned int sessionID, const ByteArray &aid)
throw(ExceptionBase &)
{
unsigned int result = IntegerHandle::INVALID_HANDLE;
channel = service->getChannel(result);
/* check */
- if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
- aid, service->getParent()->getCertificationHashes()) == true)
+ if (_isAuthorizedAccess(channel, aid,
+ service->getParent()->getCertificationHashes()) == true)
{
int rv = 0;
{
PKCS15 pkcs15(channel);
- if (pkcs15.isClosed() == false)
+ rv = pkcs15.select();
+ if (rv >= SCARD_ERROR_OK)
{
/* remove privilege mode */
channel->unsetPrivilegeMode();
+ channel->setSelectResponse(pkcs15.getSelectResponse());
}
else
{
- _ERR("select failed");
+ _ERR("select failed, [%x]", -rv);
service->closeChannel(result);
throw ExceptionBase(SCARD_ERROR_IO_FAILED);
FileObject file(channel);
rv = file.select(aid);
- if (rv >= 0)
+ if (rv >= SCARD_ERROR_OK)
{
/* remove privilege mode */
channel->unsetPrivilegeMode();
+ channel->setSelectResponse(file.getSelectResponse());
}
else
{
- _ERR("select failed [%d]", rv);
+ _ERR("select failed [%x]", -rv);
service->closeChannel(result);
throw ExceptionBase(SCARD_ERROR_IO_FAILED);
return result;
}
- unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
- throw(ExceptionBase &)
- {
- unsigned int result = -1;
- ServiceInstance *service = NULL;
-
- if ((service = getService(socket, context)) != NULL)
- {
- if (service->isVaildSessionHandle(sessionID) == true)
- {
- ServerSession *session = NULL;
- Terminal *terminal = NULL;
-
- terminal = service->getTerminal(sessionID);
- session = service->getSession(sessionID);
- if (terminal != NULL && session != NULL)
- {
- result = _createChannel(terminal, service, channelType, sessionID, aid);
- if (result == IntegerHandle::INVALID_HANDLE)
- {
- _ERR("create channel failed [%d]", sessionID);
- }
- }
- else
- {
- _ERR("session is invalid [%d]", sessionID);
- throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
- }
- }
- else
- {
- _ERR("session is invalid [%d]", sessionID);
- throw ExceptionBase(SCARD_ERROR_ILLEGAL_PARAM);
- }
- }
- else
- {
- _ERR("getService is failed [%d] [%d]", socket, context);
- throw ExceptionBase(SCARD_ERROR_UNAVAILABLE);
- }
-
- return result;
- }
-
- Channel *ServerResource::getChannel(int socket, unsigned int context, unsigned int channelID)
+ void ServerResource::addAccessControlList(Terminal *terminal, AccessControlList *acl)
{
- Channel *result = NULL;
- ServiceInstance *instance = NULL;
+ map<Terminal *, AccessControlList *>::iterator item;
- if ((instance = getService(socket, context)) != NULL)
+ if ((item = mapACL.find(terminal)) == mapACL.end())
{
- result = instance->getChannel(channelID);
+ mapACL.insert(make_pair(terminal, acl));
}
else
{
- _ERR("Channel doesn't exist : socket [%d], context [%d], handle [%d]", socket, context, channelID);
+ item->second = acl;
}
-
- return result;
}
- void ServerResource::removeChannel(int socket, unsigned int context, unsigned int channelID)
+ void ServerResource::addAccessControlList(ServerChannel *channel, AccessControlList *acl)
{
- ServiceInstance *instance = NULL;
+ map<Terminal *, AccessControlList *>::iterator item;
- if ((instance = getService(socket, context)) != NULL)
+ if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
{
- instance->closeChannel(channelID);
+ mapACL.insert(make_pair(channel->getTerminal(), acl));
}
else
{
- _ERR("getService doesn't exist : socket [%d], context [%d]", socket, context);
+ item->second = acl;
}
}
AccessControlList *result = NULL;
map<Terminal *, AccessControlList *>::iterator item;
- if ((item = mapACL.find(terminal)) == mapACL.end())
- {
- /* load access control */
- result = new GPSEACL();
- if (result != NULL)
- {
- mapACL.insert(make_pair(terminal, result));
- }
- else
- {
- _ERR("alloc failed");
- }
- }
- else
+ if ((item = mapACL.find(terminal)) != mapACL.end())
{
result = item->second;
}
AccessControlList *result = NULL;
map<Terminal *, AccessControlList *>::iterator item;
- if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
- {
- /* load access control */
- result = new GPSEACL();
- if (result != NULL)
- {
- mapACL.insert(make_pair(channel->getTerminal(), result));
- }
- else
- {
- _ERR("alloc failed");
- }
- }
- else
+ if ((item = mapACL.find(channel->getTerminal())) != mapACL.end())
{
result = item->second;
}
}
}
- bool ServerResource::isValidReaderHandle(unsigned int reader)
+ bool ServerResource::isValidReaderHandle(unsigned int reader) const
{
return (getTerminalByReaderID(reader) != NULL);
}
- bool ServerResource::isValidSessionHandle(int socket, unsigned int context, unsigned int session)
+ void ServerResource::getReaders(vector<pair<unsigned int, string> > &readers) const
{
- ServiceInstance *instance = NULL;
+ const Terminal *terminal;
+ map<unsigned int, unsigned int>::const_iterator item;
- return (((instance = getService(socket, context)) != NULL) && (instance->isVaildSessionHandle(session)));
+ readers.clear();
+
+ for (item = mapReaders.begin(); item != mapReaders.end(); item++)
+ {
+ if (item->second != IntegerHandle::INVALID_HANDLE)
+ {
+ terminal = getTerminal(item->second);
+ if (terminal != NULL && terminal->isSecureElementPresence() == true)
+ {
+ readers.push_back(make_pair(item->first, terminal->getName()));
+ }
+ }
+ }
}
- int ServerResource::getReadersInformation(ByteArray &info)
+ int ServerResource::getReadersInformation(ByteArray &info) const
{
int result = 0;
unsigned char *buffer = NULL;
if (mapReaders.size() > 0)
{
- Terminal *terminal = NULL;
- map<unsigned int, unsigned int>::iterator item;
+ const Terminal *terminal = NULL;
+ map<unsigned int, unsigned int>::const_iterator item;
for (item = mapReaders.begin(); item != mapReaders.end(); item++)
{
}
}
- info.setBuffer(buffer, length);
+ info.assign(buffer, length);
delete []buffer;
}
else
return result;
}
- bool ServerResource::sendMessageToAllClients(Message &msg)
+#ifndef USE_GDBUS
+ bool ServerResource::sendMessageToAllClients(const Message &msg)
{
bool result = true;
- map<int, ClientInstance *>::iterator item;
- for (item = mapClients.begin(); item != mapClients.end(); item++)
+ map<int, ClientInstance *>::const_iterator item;
+
+ for (item = mapClients.begin();
+ item != mapClients.end(); item++)
{
- if (item->second->sendMessageToAllServices(item->second->getSocket(), msg) == false)
+ if (item->second->sendMessageToAllServices(
+ item->second->getSocket(), msg) == false)
result = false;
}
return result;
}
+#endif
- void ServerResource::terminalCallback(void *terminal, int event, int error, void *user_param)
+ void ServerResource::terminalCallback(const void *terminal, int event,
+ int error, void *user_param)
{
_DBG("terminal [%s], event [%d], error [%d], user_param [%p]", (char *)terminal, event, error, user_param);
{
ServerResource &instance = ServerResource::getInstance();
unsigned int terminalID = IntegerHandle::INVALID_HANDLE;
- Message msg;
_INFO("[NOTIFY_SE_AVAILABLE]");
terminalID = instance.getTerminalID((char *)terminal);
if (terminalID != IntegerHandle::INVALID_HANDLE)
{
+ unsigned int readerID = instance.createReader(terminalID);
+#ifdef USE_GDBUS
+ ServerGDBus::getInstance().emitReaderInserted(readerID, (const char *)terminal);
+#else
+ Message msg;
+
/* send all client to refresh reader */
msg.message = msg.MSG_NOTIFY_SE_INSERTED;
- msg.param1 = instance.createReader(terminalID);
- msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+ msg.param1 = readerID;
+ msg.data.assign((uint8_t *)terminal,
+ strlen((char *)terminal) + 1);
instance.sendMessageToAllClients(msg);
+#endif
}
}
break;
{
ServerResource &instance = ServerResource::getInstance();
unsigned int readerID = IntegerHandle::INVALID_HANDLE;
- Message msg;
_INFO("[NOTIFY_SE_NOT_AVAILABLE]");
readerID = instance.getReaderID((char *)terminal);
+#ifdef USE_GDBUS
+ ServerGDBus::getInstance().emitReaderRemoved(
+ readerID, (const char *)terminal);
+#else
+ Message msg;
/* send all client to refresh reader */
msg.message = msg.MSG_NOTIFY_SE_REMOVED;
msg.param1 = readerID;
- msg.data.setBuffer((unsigned char *)terminal, strlen((char *)terminal) + 1);
+ msg.data.assign((uint8_t *)terminal,
+ strlen((char *)terminal) + 1);
instance.sendMessageToAllClients(msg);
+#endif
instance.removeReader(readerID);
}
break;
return result;
}
- unsigned int ServerResource::getReaderID(const char *name)
+ unsigned int ServerResource::getReaderID(const char *name) const
{
- unsigned int result = IntegerHandle::INVALID_HANDLE, terminalID = IntegerHandle::INVALID_HANDLE;
+ unsigned int result = IntegerHandle::INVALID_HANDLE,
+ terminalID = IntegerHandle::INVALID_HANDLE;
terminalID = getTerminalID(name);
if (terminalID != IntegerHandle::INVALID_HANDLE)
{
- map<unsigned int, unsigned int>::iterator item;
+ map<unsigned int, unsigned int>::const_iterator item;
- for (item = mapReaders.begin(); item != mapReaders.end(); item++)
+ for (item = mapReaders.begin();
+ item != mapReaders.end(); item++)
{
if (item->second == terminalID)
{
}
}
-} /* namespace smartcard_service_api */
+ bool ServerResource::isAuthorizedNFCAccess(Terminal *terminal,
+ const ByteArray &aid, const vector<ByteArray> &hashes)
+ {
+ bool result = false;
-using namespace smartcard_service_api;
+ if (terminal == NULL) {
+ return result;
+ }
-EXTERN_API void server_resource_set_main_loop_instance(void *instance)
-{
- ServerResource::getInstance().setMainLoopInstance(instance);
-}
+ int num = _openLogicalChannel(terminal);
+ if (num > 0) {
+ /* create channel instance */
+ ServerChannel *channel = new ServerChannel(NULL, NULL, num, terminal);
+ if (channel != NULL) {
+ AccessControlList *acl = getAccessControlList(channel);
+ if (acl == NULL) {
+
+ /* load access control defined by Global Platform */
+ acl = new GPACE();
+ if (acl != NULL) {
+ int ret;
+
+ ret = acl->loadACL(channel);
+ if (ret >= SCARD_ERROR_OK) {
+ addAccessControlList(channel, acl);
+ } else {
+ _ERR("unknown error, 0x%x", -ret);
+
+ delete acl;
+ acl = NULL;
+ }
+ } else {
+ _ERR("alloc failed");
+ }
+ } else {
+ acl->updateACL(channel);
+ }
+
+ if (acl != NULL) {
+ result = acl->isAuthorizedNFCAccess(aid, hashes);
+ } else {
+ _ERR("acl is null");
+ }
+
+ delete channel;
+ } else {
+ _ERR("alloc failed");
+ }
+ } else {
+ _ERR("_openLogicalChannel failed");
+ }
+
+ return result;
+ }
+
+ void ServerResource::finish()
+ {
+ if (getClientCount() == 0) {
+ _INFO("no client connected. terminate server");
+
+ smartcard_daemon_exit();
+ }
+ }
+} /* namespace smartcard_service_api */