Change the authorization sequence
authorWonkyu Kwon <wonkyu.kwon@samsung.com>
Mon, 7 Jan 2013 10:27:12 +0000 (19:27 +0900)
committerWonkyu Kwon <wonkyu.kwon@samsung.com>
Thu, 10 Jan 2013 09:21:56 +0000 (18:21 +0900)
 - AccessControlList doesn't include Channel instance.
   You should pass Channel instance when call loadACL().
 - Change getting the Channel sequence.
   1. Open a logical channel.
   2. Check authorized access using opened channel.
   3-1. If it authorized, makes instance and return true.
   3-2. If it doesn't, close opened channel and return false

Change-Id: I693e75a1e1218edef4d6656f7d38c1a9a12e50fd

13 files changed:
common/APDUHelper.cpp
common/AccessControlList.cpp
common/GPSEACL.cpp
common/include/APDUHelper.h
common/include/AccessControlList.h
common/include/GPSEACL.h
server/ServerChannel.cpp
server/ServerReader.cpp
server/ServerResource.cpp
server/ServerSession.cpp
server/include/ServerChannel.h
server/include/ServerResource.h
test-client/test-client.cpp

index 16bb029..e858054 100644 (file)
@@ -301,7 +301,7 @@ namespace smartcard_service_api
                        default :
                                switch (type)
                                {
-                               case 0 : /* standard class byte, two logical channel bits (1~3) */
+                               case CLA_CHANNEL_STANDARD : /* standard class byte, two logical channel bits (1~3) */
                                        if (channelNum > 0 && channelNum < 4)
                                        {
                                                unsigned char temp;
@@ -315,7 +315,7 @@ namespace smartcard_service_api
                                        }
                                        break;
 
-                               case 1 : /* extended class byte, four logical channel bits (1~15) */
+                               case CLA_CHANNEL_EXTENDED : /* extended class byte, four logical channel bits (1~15) */
                                        if (channelNum > 0 && channelNum < 16)
                                        {
                                                unsigned char temp;
index 7dff180..bfd7cf6 100644 (file)
@@ -36,49 +36,18 @@ namespace smartcard_service_api
 
        AccessControlList::AccessControlList()
        {
-               channel = NULL;
-               terminal = NULL;
                allGranted = false;
        }
 
-       AccessControlList::AccessControlList(Channel *channel)
-       {
-               channel = NULL;
-               terminal = NULL;
-               allGranted = false;
-
-               setChannel(channel);
-       }
-
-       AccessControlList::AccessControlList(Terminal *terminal)
-       {
-               channel = NULL;
-               terminal = NULL;
-               allGranted = false;
-
-               setTerminal(terminal);
-       }
-
        AccessControlList::~AccessControlList()
        {
                releaseACL();
        }
 
-       int AccessControlList::setChannel(Channel *channel)
-       {
-               this->channel = channel;
-
-               return 0;
-       }
-
-       int AccessControlList::updateACL()
-       {
-               return loadACL();
-       }
-
        void AccessControlList::releaseACL()
        {
                mapConditions.clear();
+               allGranted = false;
        }
 
        bool AccessControlList::isAuthorizedAccess(ByteArray aid, ByteArray certHash, bool update)
@@ -86,12 +55,6 @@ namespace smartcard_service_api
                bool result = allGranted;
                map<ByteArray, AccessCondition>::iterator iterMap;
 
-               if (update)
-               {
-                       loadACL();
-                       result = allGranted;
-               }
-
                if (result == false)
                {
                        SCARD_DEBUG("aid : %s", aid.toString());
@@ -133,8 +96,6 @@ namespace smartcard_service_api
                bool result;
                size_t i;
 
-               loadACL();
-
                result = allGranted;
 
                if (result == false)
index 17cc2af..019accf 100644 (file)
@@ -37,75 +37,77 @@ namespace smartcard_service_api
        static unsigned char oid_globalplatform[] = { 0x2A, 0x86, 0x48, 0x86, 0xFC, 0x6B, 0x81, 0x48, 0x01, 0x01 };
        ByteArray GPSEACL::OID_GLOBALPLATFORM(ARRAY_AND_SIZE(oid_globalplatform));
 
-       GPSEACL::GPSEACL(Channel *channel):AccessControlList(channel)
+       GPSEACL::GPSEACL():AccessControlList()
        {
-               this->channel = channel;
-
-               if (channel->getSelectResponse().isEmpty() == true)
-               {
-                       pkcs15 = new PKCS15(channel);
-               }
-               else
-               {
-                       pkcs15 = new PKCS15(channel, channel->getSelectResponse());
-               }
        }
 
        GPSEACL::~GPSEACL()
        {
-               if (pkcs15 != NULL)
-               {
-                       delete pkcs15;
-               }
        }
 
-       int GPSEACL::loadACL()
+       int GPSEACL::loadACL(Channel *channel)
        {
                int result = 0;
-               ByteArray aid, certHash;
-               PKCS15ODF *odf;
+               PKCS15 *pkcs15;
 
-               /* basically, all requests will be accepted when PKCS #15 doesn't exist or global platform OID is not placed */
-               allGranted = true;
+               if (channel == NULL)
+               {
+                       return -1;
+               }
 
-               if (pkcs15->isClosed() == false)
+               pkcs15 = new PKCS15(channel, channel->getSelectResponse());
+               if (pkcs15 != NULL)
                {
-                       if ((odf = pkcs15->getODF()) != NULL)
+                       /* basically, all requests will be accepted when PKCS #15 doesn't exist or global platform OID is not placed */
+                       allGranted = true;
+
+                       if (pkcs15->isClosed() == false)
                        {
-                               PKCS15DODF *dodf;
+                               PKCS15ODF *odf;
 
-                               if ((dodf = odf->getDODF()) != NULL)
+                               if ((odf = pkcs15->getODF()) != NULL)
                                {
-                                       if (loadAccessControl(dodf) == 0)
+                                       PKCS15DODF *dodf;
+
+                                       if ((dodf = odf->getDODF()) != NULL)
                                        {
-                                               printAccessControlList();
+                                               if (loadAccessControl(channel, dodf) == 0)
+                                               {
+                                                       printAccessControlList();
 
-                                               result = 0;
+                                                       result = 0;
+                                               }
+                                               else
+                                               {
+                                                       SCARD_DEBUG_ERR("loadAccessControl failed, every request will be accepted.");
+                                               }
                                        }
                                        else
                                        {
-                                               SCARD_DEBUG_ERR("loadAccessControl failed, every request will be accepted.");
+                                               SCARD_DEBUG_ERR("dodf null, every request will be accepted.");
                                        }
                                }
                                else
                                {
-                                       SCARD_DEBUG_ERR("dodf null, every request will be accepted.");
+                                       SCARD_DEBUG_ERR("odf null, every request will be accepted.");
                                }
                        }
                        else
                        {
-                               SCARD_DEBUG_ERR("odf null, every request will be accepted.");
+                               SCARD_DEBUG_ERR("failed to open PKCS15, every request will be accepted.");
                        }
+
+                       delete pkcs15;
                }
                else
                {
-                       SCARD_DEBUG_ERR("failed to open PKCS15, every request will be accepted.");
+                       return -1;
                }
 
                return result;
        }
 
-       int GPSEACL::loadAccessControl(PKCS15DODF *dodf)
+       int GPSEACL::loadAccessControl(Channel *channel, PKCS15DODF *dodf)
        {
                int result = -1;
                ByteArray path;
@@ -153,7 +155,7 @@ namespace smartcard_service_api
                                                path = SimpleTLV::getOctetString(tlv.getValue());
                                                SCARD_DEBUG("access control rule path : %s", path.toString());
 
-                                               if (loadRules(path) == 0)
+                                               if (loadRules(channel, path) == 0)
                                                {
                                                        SCARD_DEBUG("loadRules success");
                                                }
@@ -178,7 +180,7 @@ namespace smartcard_service_api
                return result;
        }
 
-       int GPSEACL::loadRules(ByteArray path)
+       int GPSEACL::loadRules(Channel *channel, ByteArray path)
        {
                FileObject file(channel);
                ByteArray data, aid;
@@ -223,7 +225,7 @@ namespace smartcard_service_api
                                        path = SimpleTLV::getOctetString(tlv.getValue());
                                        SCARD_DEBUG("path : %s", path.toString());
 
-                                       if (loadAccessConditions(aid, path) == 0)
+                                       if (loadAccessConditions(channel, aid, path) == 0)
                                        {
                                                SCARD_DEBUG("loadCertHashes success");
                                        }
@@ -247,7 +249,7 @@ namespace smartcard_service_api
                return 0;
        }
 
-       int GPSEACL::loadAccessConditions(ByteArray aid, ByteArray path)
+       int GPSEACL::loadAccessConditions(Channel *channel, ByteArray aid, ByteArray path)
        {
                FileObject file(channel);
                ByteArray data;
@@ -285,30 +287,30 @@ namespace smartcard_service_api
 
 using namespace smartcard_service_api;
 
-EXTERN_API gp_se_acl_h gp_se_acl_create_instance(channel_h channel)
+EXTERN_API gp_se_acl_h gp_se_acl_create_instance()
 {
-       GPSEACL *acl = new GPSEACL((Channel *)channel);
+       GPSEACL *acl = new GPSEACL();
 
        return (gp_se_acl_h)acl;
 }
 
-EXTERN_API int gp_se_acl_load_acl(gp_se_acl_h handle)
+EXTERN_API int gp_se_acl_load_acl(gp_se_acl_h handle, channel_h channel)
 {
        int result = -1;
 
        GP_SE_ACL_EXTERN_BEGIN;
-       result = acl->loadACL();
+       result = acl->loadACL((Channel *)channel);
        GP_SE_ACL_EXTERN_END;
 
        return result;
 }
 
-EXTERN_API int gp_se_acl_update_acl(gp_se_acl_h handle)
+EXTERN_API int gp_se_acl_update_acl(gp_se_acl_h handle, channel_h channel)
 {
        int result = -1;
 
        GP_SE_ACL_EXTERN_BEGIN;
-       acl->updateACL();
+       acl->updateACL((Channel *)channel);
        GP_SE_ACL_EXTERN_END;
 
        return result;
index 2e1ceff..25d1c25 100644 (file)
@@ -115,6 +115,9 @@ namespace smartcard_service_api
                static const unsigned char P2_SELECT_GET_FCP = (unsigned char)0x04;
 //             static const unsigned char P2_ = (unsigned char)0x;
 
+               static const unsigned char CLA_CHANNEL_STANDARD = (unsigned char)0x00;
+               static const unsigned char CLA_CHANNEL_EXTENDED = (unsigned char)0x01;
+
                APDUCommand();
                ~APDUCommand();
 
index b3d4a53..64c0345 100644 (file)
@@ -32,19 +32,15 @@ using namespace std;
 
 namespace smartcard_service_api
 {
-       class Terminal;
        class AccessCondition;
 
        class AccessControlList
        {
        protected:
                map<ByteArray, AccessCondition> mapConditions;
-               Channel *channel;
-               Terminal *terminal;
                bool allGranted;
 
                void printAccessControlList();
-
                bool isAuthorizedAccess(ByteArray aid, ByteArray certHash, bool update);
 
        public:
@@ -52,21 +48,15 @@ namespace smartcard_service_api
                static ByteArray AID_DEFAULT;
 
                AccessControlList();
-               AccessControlList(Channel *channel);
-               AccessControlList(Terminal *terminal);
                virtual ~AccessControlList();
 
-               int setChannel(Channel *channel);
-               virtual int setTerminal(Terminal *terminal) { this->terminal = terminal; return 0; }
-
-               virtual int loadACL() = 0;
+               virtual int loadACL(Channel *channel) = 0;
 
-               int updateACL();
+               int updateACL(Channel *channel) { return loadACL(channel); }
                void releaseACL();
 
                bool isAuthorizedAccess(ByteArray aid, ByteArray certHash);
                bool isAuthorizedAccess(unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength);
-
                bool isAuthorizedAccess(ByteArray aid, vector<ByteArray> &certHashes);
        };
 
index efde39e..4c9dff5 100644 (file)
@@ -35,20 +35,19 @@ namespace smartcard_service_api
        class GPSEACL: public AccessControlList
        {
        private:
-               PKCS15 *pkcs15;
                ByteArray refreshTag;
 
                static ByteArray OID_GLOBALPLATFORM;
 
-               int loadAccessControl(PKCS15DODF *dodf);
-               int loadRules(ByteArray path);
-               int loadAccessConditions(ByteArray aid, ByteArray path);
+               int loadAccessControl(Channel *channel, PKCS15DODF *dodf);
+               int loadRules(Channel *channel, ByteArray path);
+               int loadAccessConditions(Channel *channel, ByteArray aid, ByteArray path);
 
        public:
-               GPSEACL(Channel *channel);
+               GPSEACL();
                ~GPSEACL();
 
-               int loadACL();
+               int loadACL(Channel *channel);
 
        };
 
@@ -63,9 +62,9 @@ extern "C"
 
 typedef void *gp_se_acl_h;
 
-gp_se_acl_h gp_se_acl_create_instance(channel_h channel);
-int gp_se_acl_load_acl(gp_se_acl_h handle);
-int gp_se_acl_update_acl(gp_se_acl_h handle);
+gp_se_acl_h gp_se_acl_create_instance();
+int gp_se_acl_load_acl(gp_se_acl_h handle, channel_h channel);
+int gp_se_acl_update_acl(gp_se_acl_h handle, channel_h channel);
 void gp_se_acl_release_acl(gp_se_acl_h handle);
 bool gp_se_acl_is_authorized_access(gp_se_acl_h handle, unsigned char *aidBuffer, unsigned int aidLength, unsigned char *certHashBuffer, unsigned int certHashLength);
 void gp_se_acl_destroy_instance(gp_se_acl_h handle);
index 81d0017..8550058 100644 (file)
@@ -30,6 +30,7 @@ namespace smartcard_service_api
                this->terminal = terminal;
                this->caller = caller;
                this->channelNum = channelNum;
+               this->privilege = true;
        }
 
        ServerChannel::~ServerChannel()
@@ -74,31 +75,31 @@ namespace smartcard_service_api
                channelNum = -1;
        }
 
-       int ServerChannel::getChannelNumber()
-       {
-               return channelNum;
-       }
-
        int ServerChannel::transmitSync(ByteArray command, ByteArray &result)
        {
                APDUCommand helper;
 
-               if (session != NULL) /* admin channel */
+               if (isClosed() == true)
                {
-                       helper.setCommand(command);
+                       return -1;
+               }
 
-                       /* filter command */
+               helper.setCommand(command);
+
+               /* filter command */
+               if (privilege == false)
+               {
                        if ((helper.getINS() == APDUCommand::INS_SELECT_FILE && helper.getP1() == APDUCommand::P1_SELECT_BY_DF_NAME) ||
                                (helper.getINS() == APDUCommand::INS_MANAGE_CHANNEL))
                        {
                                return -4; /* security reason */
                        }
+               }
 
-                       /* insert channel ID */
-                       helper.setChannel(0, channelNum);
+               /* TODO : insert channel ID using atr information */
+               helper.setChannel(APDUCommand::CLA_CHANNEL_STANDARD, channelNum);
 
-                       helper.getBuffer(command);
-               }
+               helper.getBuffer(command);
 
                SCARD_DEBUG("command [%d] : %s", command.getLength(), command.toString());
 
index a00ac3d..8febd13 100644 (file)
@@ -93,10 +93,10 @@ namespace smartcard_service_api
                if (acList == NULL)
                {
                        /* load access control */
-                       acList = new GPSEACL(adminChannel);
+                       acList = new GPSEACL();
                        if (acList != NULL)
                        {
-                               acList->loadACL();
+                               acList->loadACL(adminChannel);
                        }
                        else
                        {
index f28a4a0..1300629 100644 (file)
@@ -390,7 +390,7 @@ namespace smartcard_service_api
                }
        }
 
-       bool ServerResource::_isAuthorizedAccess(Terminal *terminal, int pid, ByteArray aid, vector<ByteArray> &hashes)
+       bool ServerResource::_isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes)
        {
                bool result = true;
 
@@ -403,51 +403,15 @@ namespace smartcard_service_api
                if (strncmp(filename, "ozD3Dw1MZruTDKHWGgYaDib2B2LV4/nfT+8b/g1Vsk8=", sizeof(filename)) != 0)
                {
                        /* request open channel sequence */
-                       if ((acList = getAccessControlList(terminal)) != NULL)
+                       if ((acList = getAccessControlList(channel)) != NULL)
                        {
 #if 1
-                               result = acList->isAuthorizedAccess(aid, hashes);
-#else
-                               result = acList->isAuthorizedAccess(aid, session->packageCert);
-#endif
-                       }
-                       else
-                       {
-                               SCARD_DEBUG_ERR("acList is null");
-                               result = false;
-                       }
-               }
-#endif
-
-               return result;
-       }
+                               PKCS15 pkcs15(channel);
 
-       bool ServerResource::_isAuthorizedAccess(Terminal *terminal, int pid, ByteArray aid, vector<ByteArray> &hashes, int channelNum)
-       {
-               bool result = true;
-
-#if 1 /* disable for temporary */
-               char filename[1024] = { 0, };
-               AccessControlList *acList = NULL;
-
-               SCARD_DEBUG_ERR("=== _isAuthorizedAccess22");
-
-               /* check exceptional case */
-               SignatureHelper::getProcessName(pid, filename, sizeof(filename));
-               if (strncmp(filename, "ozD3Dw1MZruTDKHWGgYaDib2B2LV4/nfT+8b/g1Vsk8=", sizeof(filename)) != 0)
-               {
-                       /* request open channel sequence */
-                       if ((acList = getAccessControlList(terminal, channelNum)) != NULL)
-                       {
-#if 1
+                               acList->loadACL(channel);
                                result = acList->isAuthorizedAccess(aid, hashes);
-
-                               SCARD_DEBUG_ERR("AC result [%d]", result);
-
 #else
-                               SCARD_DEBUG_ERR("=== Get access control done");
-
-//                             result = acList->isAuthorizedAccess(aid, session->packageCert);
+                               result = acList->isAuthorizedAccess(aid, session->packageCert);
 #endif
                        }
                        else
@@ -461,7 +425,7 @@ namespace smartcard_service_api
                return result;
        }
 
-
+#if 0
        unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
        {
                unsigned int result = IntegerHandle::INVALID_HANDLE;
@@ -501,89 +465,188 @@ namespace smartcard_service_api
                        }
                }
 
+               /* select aid */
+               APDUCommand apdu;
+               apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_DF_NAME, APDUCommand::P2_SELECT_GET_FCP, aid, 0);
+               apdu.setChannel(1, channelNum);
+               apdu.getBuffer(command);
 
-               if (_isAuthorizedAccess(terminal, service->getParent()->getPID(), aid, service->getParent()->getCertificationHashes(), channelNum) == true)
+               rv = terminal->transmitSync(command, response);
+               if (rv == 0 && response.getLength() >= 2)
                {
-                       /* select aid */
-                       APDUCommand apdu;
-                       apdu.setCommand(0, APDUCommand::INS_SELECT_FILE, APDUCommand::P1_SELECT_BY_DF_NAME, APDUCommand::P2_SELECT_GET_FCP, aid, 0);
-                       apdu.setChannel(1, channelNum);
-                       apdu.getBuffer(command);
+                       ResponseHelper resp(response);
 
-                       rv = terminal->transmitSync(command, response);
-                       if (rv == 0 && response.getLength() >= 2)
+                       if (resp.getStatus() == 0)
                        {
-                               ResponseHelper resp(response);
-
-                               if (resp.getStatus() == 0)
+                               result = service->openChannel(sessionID, channelNum, response);
+                               if (result == IntegerHandle::INVALID_HANDLE)
                                {
-                                       result = service->openChannel(sessionID, channelNum, response);
-                                       if (result == IntegerHandle::INVALID_HANDLE)
-                                       {
-                                               SCARD_DEBUG_ERR("channel is null.");
-                                       }
+                                       SCARD_DEBUG_ERR("channel is null.");
                                }
-                               else
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
+                       }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+               }
+
+               return result;
+       }
+#else
+       int ServerResource::_openLogicalChannel(Terminal *terminal)
+       {
+               int result = -1;
+               int rv = 0;
+               ByteArray command;
+               ByteArray response;
+
+               /* open channel */
+               command = APDUHelper::generateAPDU(APDUHelper::COMMAND_OPEN_LOGICAL_CHANNEL, 0, ByteArray::EMPTY);
+               rv = terminal->transmitSync(command, response);
+               if (rv == 0 && response.getLength() >= 2)
+               {
+                       ResponseHelper resp(response);
+
+                       if (resp.getStatus() == 0)
+                       {
+                               result = resp.getDataField()[0];
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
+                               if (0)
                                {
-                                       SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
+                                       /* TODO : if there is no more channel, return error code */
+                                       SCARD_DEBUG_ERR("no more logical channel");
+                                       result = -2;
                                }
                        }
+               }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+               }
+
+               return result;
+       }
+
+       int ServerResource::_closeLogicalChannel(Terminal *terminal, int channelNum)
+       {
+               int result = -1;
+               int rv = 0;
+               ByteArray command;
+               ByteArray response;
+
+               /* open channel */
+               command = APDUHelper::generateAPDU(APDUHelper::COMMAND_CLOSE_LOGICAL_CHANNEL, channelNum, ByteArray::EMPTY);
+               rv = terminal->transmitSync(command, response);
+               if (rv == 0 && response.getLength() >= 2)
+               {
+                       ResponseHelper resp(response);
+
+                       if (resp.getStatus() == 0)
+                       {
+                               SCARD_DEBUG("channel closed [%d]", channelNum);
+                               result = 0;
+                       }
                        else
                        {
-                               SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+                               SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
                        }
                }
+               else
+               {
+                       SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
+               }
+
                return result;
        }
 
-#if 0
-       unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
+       unsigned int ServerResource::_createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid)
        {
-               unsigned int result = -1;
-               ServiceInstance *service = NULL;
+               unsigned int result = IntegerHandle::INVALID_HANDLE;
+               int channelNum = 0;
+               ServerChannel *channel = NULL;
 
-               if ((service = getService(socket, context)) != NULL)
+               /* open logical channel */
+               if (channelType == 1)
                {
-                       if (service->isVaildSessionHandle(sessionID) == true)
+                       channelNum = _openLogicalChannel(terminal);
+                       if (channelNum > 0)
                        {
-                               ServerSession *session = NULL;
-                               Terminal *terminal = NULL;
+                               SCARD_DEBUG("channelNum [%d]", result);
+                       }
+                       else
+                       {
+                               SCARD_DEBUG_ERR("_openLogicalChannel failed [%d]", channelNum);
+                               return result;
+                       }
+               }
 
-                               terminal = service->getTerminal(sessionID);
-                               session = service->getSession(sessionID);
-                               if (terminal != NULL && session != NULL)
+               /* create channel instance */
+               result = service->openChannel(sessionID, channelNum, ByteArray::EMPTY);
+               if (result == IntegerHandle::INVALID_HANDLE)
+               {
+                       SCARD_DEBUG_ERR("channel is null.");
+
+                       /* close logical channel */
+                       if (channelNum > 0)
+                       {
+                               _closeLogicalChannel(terminal, channelNum);
+                       }
+                       return result;
+               }
+
+               channel = service->getChannel(result);
+
+               /* check */
+               if (_isAuthorizedAccess(channel, service->getParent()->getPID(),
+                               aid, service->getParent()->getCertificationHashes()) == true)
+               {
+                       int rv = 0;
+                       ByteArray command;
+                       ByteArray response;
+
+                       /* select aid */
+                       command = APDUHelper::generateAPDU(APDUHelper::COMMAND_SELECT_BY_DF_NAME, channelNum, aid);
+                       rv = channel->transmitSync(command, response);
+                       if (rv == 0 && response.getLength() >= 2)
+                       {
+                               ResponseHelper resp(response);
+
+                               if (resp.getStatus() == 0)
                                {
-                                       if (_isAuthorizedAccess(terminal, service->getParent()->getPID(), aid, service->getParent()->getCertificationHashes()) == true)
-                                       {
-                                               result = _createChannel(terminal, service, channelType, sessionID, aid);
-                                       }
-                                       else
-                                       {
-                                               SCARD_DEBUG_ERR("access denied [%d]", sessionID);
-                                       }
+                                       channel->selectResponse = response;
+                                       /* remove privilege mode */
+                                       channel->unsetPrivilegeMode();
                                }
                                else
                                {
-                                       SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
+                                       SCARD_DEBUG_ERR("status word [%d][ %02X %02X ]", resp.getStatus(), resp.getSW1(), resp.getSW2());
                                }
                        }
                        else
                        {
-                               SCARD_DEBUG_ERR("session is invalid [%d]", sessionID);
+                               SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, response.getLength());
                        }
                }
                else
                {
-                       SCARD_DEBUG_ERR("getService is failed [%d] [%d]", socket, context);
+                       SCARD_DEBUG_ERR("unauthorized access");
+
+                       service->closeChannel(result);
+                       result = IntegerHandle::INVALID_HANDLE;
                }
 
+
                return result;
        }
-
 #endif
 
-
-/****************************************************************************************************/
        unsigned int ServerResource::createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid)
        {
                unsigned int result = -1;
@@ -601,6 +664,10 @@ namespace smartcard_service_api
                                if (terminal != NULL && session != NULL)
                                {
                                        result = _createChannel(terminal, service, channelType, sessionID, aid);
+                                       if (result == IntegerHandle::INVALID_HANDLE)
+                                       {
+                                               SCARD_DEBUG_ERR("create channel failed [%d]", sessionID);
+                                       }
                                }
                                else
                                {
@@ -658,19 +725,11 @@ namespace smartcard_service_api
 
                if ((item = mapACL.find(terminal)) == mapACL.end())
                {
-                       ServerChannel *channel = new ServerChannel(NULL, NULL, 0, terminal);
-                       if (channel != NULL)
+                       /* load access control */
+                       result = new GPSEACL();
+                       if (result != NULL)
                        {
-                               /* load access control */
-                               result = new GPSEACL(channel);
-                               if (result != NULL)
-                               {
-                                       mapACL.insert(make_pair(terminal, result));
-                               }
-                               else
-                               {
-                                       SCARD_DEBUG_ERR("alloc failed");
-                               }
+                               mapACL.insert(make_pair(terminal, result));
                        }
                        else
                        {
@@ -685,26 +744,18 @@ namespace smartcard_service_api
                return result;
        }
 
-       AccessControlList *ServerResource::getAccessControlList(Terminal *terminal, int channelNuml)
+       AccessControlList *ServerResource::getAccessControlList(ServerChannel *channel)
        {
                AccessControlList *result = NULL;
                map<Terminal *, AccessControlList *>::iterator item;
 
-               if ((item = mapACL.find(terminal)) == mapACL.end())
+               if ((item = mapACL.find(channel->getTerminal())) == mapACL.end())
                {
-                       ServerChannel *channel = new ServerChannel(NULL, NULL, channelNuml, terminal);
-                       if (channel != NULL)
+                       /* load access control */
+                       result = new GPSEACL();
+                       if (result != NULL)
                        {
-                               /* load access control */
-                               result = new GPSEACL(channel);
-                               if (result != NULL)
-                               {
-                                       mapACL.insert(make_pair(terminal, result));
-                               }
-                               else
-                               {
-                                       SCARD_DEBUG_ERR("alloc failed");
-                               }
+                               mapACL.insert(make_pair(channel->getTerminal(), result));
                        }
                        else
                        {
index ee77af3..11b54f3 100644 (file)
@@ -89,6 +89,7 @@ namespace smartcard_service_api
        Channel *ServerSession::openBasicChannelSync(ByteArray aid, void *caller)
        {
                ServerChannel *channel = NULL;
+#if 0
                AccessControlList *acList = NULL;
                ByteArray command, result;
                int channelID = 0;
@@ -141,7 +142,7 @@ namespace smartcard_service_api
                {
                        SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
                }
-
+#endif
                return channel;
        }
 
@@ -163,6 +164,7 @@ namespace smartcard_service_api
        Channel *ServerSession::openLogicalChannelSync(ByteArray aid, void *caller)
        {
                ServerChannel *channel = NULL;
+#if 0
                AccessControlList *acList = NULL;
                ByteArray command, result;
                int channelID = 1;
@@ -240,7 +242,7 @@ namespace smartcard_service_api
                {
                        SCARD_DEBUG_ERR("select apdu is failed, rv [%d], length [%d]", rv, result.getLength());
                }
-
+#endif
                return channel;
        }
 
index 3c3a260..9312345 100644 (file)
@@ -34,8 +34,11 @@ namespace smartcard_service_api
        private:
                Terminal *terminal;
                void *caller;
+               bool privilege;
 
                ServerChannel(ServerSession *session, void *caller, int channelNum, Terminal *terminal);
+               void setChannelNumber(int channelNum) { this->channelNum = channelNum; }
+               void unsetPrivilegeMode() { this->privilege = false; }
 
        protected:
                void closeSync();
@@ -44,7 +47,8 @@ namespace smartcard_service_api
        public:
                ~ServerChannel();
 
-               int getChannelNumber();
+               int getChannelNumber() { return channelNum; }
+               Terminal *getTerminal() { return terminal; }
 
                int close(closeCallback callback, void *userParam) { return -1; }
                int transmit(ByteArray command, transmitCallback callback, void *userParam) { return -1; };
index 9b93d81..e6f7405 100644 (file)
@@ -80,6 +80,10 @@ namespace smartcard_service_api
 
                static void terminalCallback(void *terminal, int event, int error, void *user_param);
 
+               int _openLogicalChannel(Terminal *terminal);
+               int _closeLogicalChannel(Terminal *terminal, int channelNum);
+               bool _isAuthorizedAccess(ServerChannel *channel, int pid, ByteArray aid, vector<ByteArray> &hashes);
+               unsigned int _createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid);
        public:
                /* static member */
                static ServerResource &getInstance();
@@ -126,16 +130,12 @@ namespace smartcard_service_api
                void removeSession(int socket, unsigned int context, unsigned int session);
                bool isValidSessionHandle(int socket, unsigned int context, unsigned int sessionID);
 
-               bool _isAuthorizedAccess(Terminal *terminal, int pid, ByteArray aid, vector<ByteArray> &hashes);
-               bool _isAuthorizedAccess(Terminal *terminal, int pid, ByteArray aid, vector<ByteArray> &hashes, int channelNum);
-
-               unsigned int _createChannel(Terminal *terminal, ServiceInstance *service, int channelType, unsigned int sessionID, ByteArray aid);
                unsigned int createChannel(int socket, unsigned int context, unsigned int sessionID, int channelType, ByteArray aid);
                Channel *getChannel(int socket, unsigned int context, unsigned int channelID);
                void removeChannel(int socket, unsigned int context, unsigned int channelID);
 
                AccessControlList *getAccessControlList(Terminal *terminal);
-               AccessControlList *getAccessControlList(Terminal *termina, int channelNuml);
+               AccessControlList *getAccessControlList(ServerChannel *channel);
 
                bool sendMessageToAllClients(Message &msg);
 
index 1923933..23cf920 100644 (file)
@@ -58,7 +58,7 @@ class TestEventHandler : public SEServiceListener
 
        void eventHandler(SEServiceHelper *service, char *seName, int event, void *userData)
        {
-               user_context_t *context = (user_context_t *)userData;
+//             user_context_t *context = (user_context_t *)userData;
                vector<ReaderHelper *> readers;
                size_t i;