Overview
Comment: | Improved waiting for slot event to allow C_Finalize to terminate any waiting |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | wait-for-slot-event |
Files: | files | file ages | folders |
SHA1: |
d52881feec0a9e75f2d968f4aa98efb2 |
User & Date: | rkeene on 2013-08-19 03:14:12 |
Other Links: | branch diff | manifest | tags |
Context
2013-08-19
| ||
03:14 | Improved waiting for slot event to allow C_Finalize to terminate any waiting Leaf check-in: d52881feec user: rkeene tags: wait-for-slot-event | |
2013-08-18
| ||
07:02 | Added support for CKF_DONT_BLOCK check-in: 0058a3b41b user: rkeene tags: wait-for-slot-event | |
Changes
Modified cackey.c from [5d076538a2] to [ee6ec0dbf4].
︙ | ︙ | |||
883 884 885 886 887 888 889 890 891 892 893 894 895 896 | #define CACKEY_PIN_COMMAND_DEFAULT_XSTR(str) CACKEY_PIN_COMMAND_DEFAULT_STR(str) #define CACKEY_PIN_COMMAND_DEFAULT_STR(str) #str static char *cackey_pin_command = NULL; static char *cackey_pin_command_xonly = NULL; /* PCSC Global Handles */ static LPSCARDCONTEXT cackey_pcsc_handle = NULL; static unsigned long cackey_getversion(void) { static unsigned long retval = 255; unsigned long major = 0; unsigned long minor = 0; char *major_str = NULL; char *minor_str = NULL; | > | 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 | #define CACKEY_PIN_COMMAND_DEFAULT_XSTR(str) CACKEY_PIN_COMMAND_DEFAULT_STR(str) #define CACKEY_PIN_COMMAND_DEFAULT_STR(str) #str static char *cackey_pin_command = NULL; static char *cackey_pin_command_xonly = NULL; /* PCSC Global Handles */ static LPSCARDCONTEXT cackey_pcsc_handle = NULL; static LPSCARDCONTEXT cackey_waiting_pcsc_handle = NULL; static unsigned long cackey_getversion(void) { static unsigned long retval = 255; unsigned long major = 0; unsigned long minor = 0; char *major_str = NULL; char *minor_str = NULL; |
︙ | ︙ | |||
1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 | cackey_pcsc_handle = NULL; cackey_slots_disconnect_all(); return(CACKEY_PCSC_E_GENERIC); } } #ifdef HAVE_SCARDISVALIDCONTEXT CACKEY_DEBUG_PRINTF("SCardIsValidContext() called"); scard_isvalid_ret = SCardIsValidContext(*cackey_pcsc_handle); if (scard_isvalid_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Handle has become invalid (SCardIsValidContext = %s/%li), trying to re-establish...", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_isvalid_ret), (long) scard_isvalid_ret); | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | cackey_pcsc_handle = NULL; cackey_slots_disconnect_all(); return(CACKEY_PCSC_E_GENERIC); } } if (cackey_waiting_pcsc_handle == NULL) { cackey_waiting_pcsc_handle = malloc(sizeof(*cackey_waiting_pcsc_handle)); if (cackey_waiting_pcsc_handle == NULL) { CACKEY_DEBUG_PRINTF("Call to malloc() failed, returning in failure"); cackey_slots_disconnect_all(); free(cackey_pcsc_handle); cackey_pcsc_handle = NULL; return(CACKEY_PCSC_E_GENERIC); } CACKEY_DEBUG_PRINTF("SCardEstablishContext() called"); scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_waiting_pcsc_handle); if (scard_est_context_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %s/%li), returning in failure", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_est_context_ret), (long) scard_est_context_ret); free(cackey_pcsc_handle); cackey_pcsc_handle = NULL; free(cackey_waiting_pcsc_handle); cackey_waiting_pcsc_handle = NULL; cackey_slots_disconnect_all(); return(CACKEY_PCSC_E_GENERIC); } } #ifdef HAVE_SCARDISVALIDCONTEXT CACKEY_DEBUG_PRINTF("SCardIsValidContext() called"); scard_isvalid_ret = SCardIsValidContext(*cackey_pcsc_handle); if (scard_isvalid_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Handle has become invalid (SCardIsValidContext = %s/%li), trying to re-establish...", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_isvalid_ret), (long) scard_isvalid_ret); |
︙ | ︙ | |||
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 | cackey_slots_disconnect_all(); return(CACKEY_PCSC_E_GENERIC); } CACKEY_DEBUG_PRINTF("Handle has been re-established"); } #endif CACKEY_DEBUG_PRINTF("Sucessfully connected to PC/SC, returning in success"); return(CACKEY_PCSC_S_OK); } | > > > > > > > > > > > > > > > > > > > > > | 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 | cackey_slots_disconnect_all(); return(CACKEY_PCSC_E_GENERIC); } CACKEY_DEBUG_PRINTF("Handle has been re-established"); } CACKEY_DEBUG_PRINTF("SCardIsValidContext() called"); scard_isvalid_ret = SCardIsValidContext(*cackey_waiting_pcsc_handle); if (scard_isvalid_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Handle has become invalid (SCardIsValidContext = %s/%li), trying to re-establish...", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_isvalid_ret), (long) scard_isvalid_ret); CACKEY_DEBUG_PRINTF("SCardEstablishContext() called"); scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_waiting_pcsc_handle); if (scard_est_context_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %s/%li), returning in failure", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_est_context_ret), (long) scard_est_context_ret); free(cackey_waiting_pcsc_handle); cackey_waiting_pcsc_handle = NULL; cackey_slots_disconnect_all(); return(CACKEY_PCSC_E_GENERIC); } CACKEY_DEBUG_PRINTF("Waiting handle has been re-established"); } #endif CACKEY_DEBUG_PRINTF("Sucessfully connected to PC/SC, returning in success"); return(CACKEY_PCSC_S_OK); } |
︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 | * NOTES * This function disconnects from the PC/SC Connection manager and updates * the global handle. * */ static cackey_ret cackey_pcsc_disconnect(void) { LONG scard_rel_context_ret; CACKEY_DEBUG_PRINTF("Called."); | > | > > | | < < < > > | | | > > > > > | | 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 | * NOTES * This function disconnects from the PC/SC Connection manager and updates * the global handle. * */ static cackey_ret cackey_pcsc_disconnect(void) { LONG scard_rel_context_ret; cackey_ret retval = CACKEY_PCSC_S_OK; CACKEY_DEBUG_PRINTF("Called."); if (cackey_pcsc_handle != NULL) { scard_rel_context_ret = SCardReleaseContext(*cackey_pcsc_handle); if (scard_rel_context_ret != SCARD_S_SUCCESS) { retval = CACKEY_PCSC_E_GENERIC; } free(cackey_pcsc_handle); cackey_pcsc_handle = NULL; } if (cackey_waiting_pcsc_handle != NULL) { scard_rel_context_ret = SCardReleaseContext(*cackey_waiting_pcsc_handle); if (scard_rel_context_ret != SCARD_S_SUCCESS) { retval = CACKEY_PCSC_E_GENERIC; } free(cackey_waiting_pcsc_handle); cackey_waiting_pcsc_handle = NULL; } return(retval); } /* * SYNPOSIS * void cackey_mark_slot_reset(struct cackey_slot *slot); * * ARGUMENTS |
︙ | ︙ | |||
4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 | for (idx = 0; idx < (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])); idx++) { if (cackey_sessions[idx].active) { C_CloseSession(idx); } } cackey_slots_disconnect_all(); for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { if (cackey_slots[idx].internal) { continue; } | > > | 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 | for (idx = 0; idx < (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])); idx++) { if (cackey_sessions[idx].active) { C_CloseSession(idx); } } cackey_mutex_lock(cackey_biglock); cackey_slots_disconnect_all(); for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) { if (cackey_slots[idx].internal) { continue; } |
︙ | ︙ | |||
4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 | cackey_slots[idx].cached_certs = NULL; } } cackey_pcsc_disconnect(); cackey_initialized = 0; CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK); return(CKR_OK); } CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)(CK_INFO_PTR pInfo) { | > > | 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 | cackey_slots[idx].cached_certs = NULL; } } cackey_pcsc_disconnect(); cackey_initialized = 0; cackey_mutex_unlock(cackey_biglock); CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK); return(CKR_OK); } CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)(CK_INFO_PTR pInfo) { |
︙ | ︙ | |||
4727 4728 4729 4730 4731 4732 4733 | CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK); return(CKR_OK); } CK_DEFINE_FUNCTION(CK_RV, C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlotID, CK_VOID_PTR pReserved) { SCARD_READERSTATE reader_states[(sizeof(cackey_slots) / sizeof(cackey_slots[0])) + 1]; | | | | | | 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 | CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK); return(CKR_OK); } CK_DEFINE_FUNCTION(CK_RV, C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlotID, CK_VOID_PTR pReserved) { SCARD_READERSTATE reader_states[(sizeof(cackey_slots) / sizeof(cackey_slots[0])) + 1]; LPSCARDCONTEXT handle; LONG scard_getstatchng_ret; cackey_ret pcsc_connect_ret; struct cackey_slot *cackey_slot; unsigned int currslot, reader_state_slot, reader_state_slot_cnt; int mutex_retval; int slot_changed; CACKEY_DEBUG_PRINTF("Called."); if (pReserved != NULL) { CACKEY_DEBUG_PRINTF("Error. pReserved is not NULL."); |
︙ | ︙ | |||
4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 | } if (!cackey_initialized) { CACKEY_DEBUG_PRINTF("Error. Not initialized."); return(CKR_CRYPTOKI_NOT_INITIALIZED); } pcsc_connect_ret = cackey_pcsc_connect(); if (pcsc_connect_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Connection to PC/SC failed, returning in failure"); return(CKR_GENERAL_ERROR); } for (reader_state_slot = currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) { if (cackey_slots[currslot].internal) { | > > > > > > > > > | 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 | } if (!cackey_initialized) { CACKEY_DEBUG_PRINTF("Error. Not initialized."); return(CKR_CRYPTOKI_NOT_INITIALIZED); } mutex_retval = cackey_mutex_lock(cackey_biglock); if (mutex_retval != 0) { CACKEY_DEBUG_PRINTF("Error. Locking failed."); return(CKR_GENERAL_ERROR); } pcsc_connect_ret = cackey_pcsc_connect(); if (pcsc_connect_ret != CACKEY_PCSC_S_OK) { cackey_mutex_unlock(cackey_biglock); CACKEY_DEBUG_PRINTF("Connection to PC/SC failed, returning in failure"); return(CKR_GENERAL_ERROR); } for (reader_state_slot = currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) { if (cackey_slots[currslot].internal) { |
︙ | ︙ | |||
4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 | reader_states[reader_state_slot].dwCurrentState = SCARD_STATE_UNAWARE; } else { reader_states[reader_state_slot].dwCurrentState = cackey_slots[currslot].pcsc_state; } reader_state_slot++; } reader_states[reader_state_slot].szReader = "\\\\?PnP?\\Notification"; reader_states[reader_state_slot].pvUserData = NULL; reader_states[reader_state_slot].dwCurrentState = SCARD_STATE_UNAWARE; reader_state_slot++; | > > > > > > > > | > > | > | > > > | > | > | > > > | > > > > > | > > > > | | | | | > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | | > > | > > > > > > > > > > > > > > | 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 | reader_states[reader_state_slot].dwCurrentState = SCARD_STATE_UNAWARE; } else { reader_states[reader_state_slot].dwCurrentState = cackey_slots[currslot].pcsc_state; } reader_state_slot++; } mutex_retval = cackey_mutex_unlock(cackey_biglock); if (mutex_retval != 0) { CACKEY_DEBUG_PRINTF("Error. Unlocking failed."); return(CKR_GENERAL_ERROR); } reader_states[reader_state_slot].szReader = "\\\\?PnP?\\Notification"; reader_states[reader_state_slot].pvUserData = NULL; reader_states[reader_state_slot].dwCurrentState = SCARD_STATE_UNAWARE; reader_state_slot++; reader_state_slot_cnt = reader_state_slot; while (1) { cackey_mutex_lock(cackey_biglock); handle = cackey_waiting_pcsc_handle; cackey_mutex_unlock(cackey_biglock); if (handle == NULL) { CACKEY_DEBUG_PRINTF("Waiting handle disappeared, not attempting to wait."); break; } CACKEY_DEBUG_PRINTF("Calling SCardGetStatusChange(), which will block for 1 second"); scard_getstatchng_ret = SCardGetStatusChange(*handle, 1000, reader_states, reader_state_slot_cnt); if (scard_getstatchng_ret == SCARD_E_TIMEOUT) { continue; } break; } if (scard_getstatchng_ret != SCARD_S_SUCCESS) { CACKEY_DEBUG_PRINTF("Returning CKR_GENERAL_ERROR (%i) because SCardGetStatusChange failed: %lx", CKR_GENERAL_ERROR, scard_getstatchng_ret); return(CKR_GENERAL_ERROR); } mutex_retval = cackey_mutex_lock(cackey_biglock); if (mutex_retval != 0) { CACKEY_DEBUG_PRINTF("Error. Locking failed."); return(CKR_GENERAL_ERROR); } for (reader_state_slot = 0; reader_state_slot < reader_state_slot_cnt; reader_state_slot++) { CACKEY_DEBUG_PRINTF("[pcsc/slot = %u] CurrentState = %lx, EventState = %lx", reader_state_slot, reader_states[reader_state_slot].dwCurrentState & 0xffff, reader_states[reader_state_slot].dwEventState & 0xffff ); cackey_slot = NULL; for (currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) { if (cackey_slots[currslot].internal) { continue; } if (reader_states[reader_state_slot].szReader == NULL) { continue; } if (cackey_slots[currslot].pcsc_reader == NULL) { continue; } CACKEY_DEBUG_PRINTF("Checking to see if pcsc/slot:%u (%s) is cackey/slot:%u (%s)...", reader_state_slot, reader_states[reader_state_slot].szReader, currslot, cackey_slots[currslot].pcsc_reader ); if (strcmp(reader_states[reader_state_slot].szReader, cackey_slots[currslot].pcsc_reader) != 0) { CACKEY_DEBUG_PRINTF(" no match"); continue; } cackey_slot = &cackey_slots[currslot]; CACKEY_DEBUG_PRINTF(" match, slot = %p", cackey_slot); break; } if (cackey_slot == NULL) { /* XXX: TODO: Someone plugged in a new slot or removed a slot */ CACKEY_DEBUG_PRINTF("WARNING: Unhandled code. Slot inserted or removed."); continue; } slot_changed = 0; if ((flags & CKF_DONT_BLOCK) == CKF_DONT_BLOCK) { if (cackey_slot->pcsc_state != reader_states[reader_state_slot].dwEventState) { slot_changed = 1; } } else { if (reader_states[reader_state_slot].dwCurrentState != reader_states[reader_state_slot].dwEventState) { slot_changed = 1; } } if (slot_changed == 0) { CACKEY_DEBUG_PRINTF("[pcsc/slot = %u] Slot did not change", (unsigned int) reader_state_slot); continue; } CACKEY_DEBUG_PRINTF("Returning slot changed: %u", (unsigned int) cackey_slot->id); cackey_slot->pcsc_state = reader_states[reader_state_slot].dwEventState; *pSlotID = (CK_SLOT_ID) cackey_slot->id; CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK); mutex_retval = cackey_mutex_unlock(cackey_biglock); if (mutex_retval != 0) { CACKEY_DEBUG_PRINTF("Error. Unlocking failed."); return(CKR_GENERAL_ERROR); } return(CKR_OK); } mutex_retval = cackey_mutex_unlock(cackey_biglock); if (mutex_retval != 0) { CACKEY_DEBUG_PRINTF("Error. Unlocking failed."); return(CKR_GENERAL_ERROR); } if ((flags & CKF_DONT_BLOCK) != CKF_DONT_BLOCK) { CACKEY_DEBUG_PRINTF("Returning CKR_NO_EVENT (%i), but asked to block !? BUG ENCOUNTERED.", CKR_NO_EVENT); } else { CACKEY_DEBUG_PRINTF("Returning CKR_NO_EVENT (%i)", CKR_NO_EVENT); } |
︙ | ︙ |