| OLD | NEW |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | 1 /* This Source Code Form is subject to the terms of the Mozilla Public |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | 2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| 4 | 4 |
| 5 #include "pkcs11.h" | 5 #include "pkcs11.h" |
| 6 | 6 |
| 7 #ifndef DEVM_H | 7 #ifndef DEVM_H |
| 8 #include "devm.h" | 8 #include "devm.h" |
| 9 #endif /* DEVM_H */ | 9 #endif /* DEVM_H */ |
| 10 | 10 |
| 11 #ifndef CKHELPER_H | 11 #ifndef CKHELPER_H |
| 12 #include "ckhelper.h" | 12 #include "ckhelper.h" |
| 13 #endif /* CKHELPER_H */ | 13 #endif /* CKHELPER_H */ |
| 14 | 14 |
| 15 #include "pk11pub.h" | 15 #include "pk11pub.h" |
| 16 | 16 |
| 17 /* measured in seconds */ | 17 /* measured in seconds */ |
| 18 #define NSSSLOT_TOKEN_DELAY_TIME 1 | 18 #define NSSSLOT_TOKEN_DELAY_TIME 1 |
| 19 | 19 |
| 20 /* this should track global and per-transaction login information */ | 20 /* this should track global and per-transaction login information */ |
| 21 | 21 |
| 22 #define NSSSLOT_IS_FRIENDLY(slot) \ | 22 #define NSSSLOT_IS_FRIENDLY(slot) \ |
| 23 (slot->base.flags & NSSSLOT_FLAGS_FRIENDLY) | 23 (slot->base.flags & NSSSLOT_FLAGS_FRIENDLY) |
| 24 | 24 |
| 25 /* measured as interval */ | 25 /* measured as interval */ |
| 26 static PRIntervalTime s_token_delay_time = 0; | 26 static PRIntervalTime s_token_delay_time = 0; |
| 27 | 27 |
| 28 NSS_IMPLEMENT PRStatus | 28 NSS_IMPLEMENT PRStatus |
| 29 nssSlot_Destroy ( | 29 nssSlot_Destroy( |
| 30 NSSSlot *slot | 30 NSSSlot *slot) |
| 31 ) | |
| 32 { | 31 { |
| 33 if (slot) { | 32 if (slot) { |
| 34 » if (PR_ATOMIC_DECREMENT(&slot->base.refCount) == 0) { | 33 if (PR_ATOMIC_DECREMENT(&slot->base.refCount) == 0) { |
| 35 » PZ_DestroyLock(slot->base.lock); | 34 PZ_DestroyLock(slot->base.lock); |
| 36 » return nssArena_Destroy(slot->base.arena); | 35 return nssArena_Destroy(slot->base.arena); |
| 37 » } | 36 } |
| 38 } | 37 } |
| 39 return PR_SUCCESS; | 38 return PR_SUCCESS; |
| 40 } | 39 } |
| 41 | 40 |
| 42 void | 41 void |
| 43 nssSlot_EnterMonitor(NSSSlot *slot) | 42 nssSlot_EnterMonitor(NSSSlot *slot) |
| 44 { | 43 { |
| 45 if (slot->lock) { | 44 if (slot->lock) { |
| 46 » PZ_Lock(slot->lock); | 45 PZ_Lock(slot->lock); |
| 47 } | 46 } |
| 48 } | 47 } |
| 49 | 48 |
| 50 void | 49 void |
| 51 nssSlot_ExitMonitor(NSSSlot *slot) | 50 nssSlot_ExitMonitor(NSSSlot *slot) |
| 52 { | 51 { |
| 53 if (slot->lock) { | 52 if (slot->lock) { |
| 54 » PZ_Unlock(slot->lock); | 53 PZ_Unlock(slot->lock); |
| 55 } | 54 } |
| 56 } | 55 } |
| 57 | 56 |
| 58 NSS_IMPLEMENT void | 57 NSS_IMPLEMENT void |
| 59 NSSSlot_Destroy ( | 58 NSSSlot_Destroy( |
| 60 NSSSlot *slot | 59 NSSSlot *slot) |
| 61 ) | |
| 62 { | 60 { |
| 63 (void)nssSlot_Destroy(slot); | 61 (void)nssSlot_Destroy(slot); |
| 64 } | 62 } |
| 65 | 63 |
| 66 NSS_IMPLEMENT NSSSlot * | 64 NSS_IMPLEMENT NSSSlot * |
| 67 nssSlot_AddRef ( | 65 nssSlot_AddRef( |
| 68 NSSSlot *slot | 66 NSSSlot *slot) |
| 69 ) | |
| 70 { | 67 { |
| 71 PR_ATOMIC_INCREMENT(&slot->base.refCount); | 68 PR_ATOMIC_INCREMENT(&slot->base.refCount); |
| 72 return slot; | 69 return slot; |
| 73 } | 70 } |
| 74 | 71 |
| 75 NSS_IMPLEMENT NSSUTF8 * | 72 NSS_IMPLEMENT NSSUTF8 * |
| 76 nssSlot_GetName ( | 73 nssSlot_GetName( |
| 77 NSSSlot *slot | 74 NSSSlot *slot) |
| 78 ) | |
| 79 { | 75 { |
| 80 return slot->base.name; | 76 return slot->base.name; |
| 81 } | 77 } |
| 82 | 78 |
| 83 NSS_IMPLEMENT NSSUTF8 * | 79 NSS_IMPLEMENT NSSUTF8 * |
| 84 nssSlot_GetTokenName ( | 80 nssSlot_GetTokenName( |
| 85 NSSSlot *slot | 81 NSSSlot *slot) |
| 86 ) | |
| 87 { | 82 { |
| 88 return nssToken_GetName(slot->token); | 83 return nssToken_GetName(slot->token); |
| 89 } | 84 } |
| 90 | 85 |
| 91 NSS_IMPLEMENT void | 86 NSS_IMPLEMENT void |
| 92 nssSlot_ResetDelay ( | 87 nssSlot_ResetDelay( |
| 93 NSSSlot *slot | 88 NSSSlot *slot) |
| 94 ) | |
| 95 { | 89 { |
| 96 slot->lastTokenPing = 0; | 90 slot->lastTokenPing = 0; |
| 97 } | 91 } |
| 98 | 92 |
| 99 static PRBool | 93 static PRBool |
| 100 within_token_delay_period(NSSSlot *slot) | 94 within_token_delay_period(NSSSlot *slot) |
| 101 { | 95 { |
| 102 PRIntervalTime time, lastTime; | 96 PRIntervalTime time, lastTime; |
| 103 /* Set the delay time for checking the token presence */ | 97 /* Set the delay time for checking the token presence */ |
| 104 if (s_token_delay_time == 0) { | 98 if (s_token_delay_time == 0) { |
| 105 » s_token_delay_time = PR_SecondsToInterval(NSSSLOT_TOKEN_DELAY_TIME); | 99 s_token_delay_time = PR_SecondsToInterval(NSSSLOT_TOKEN_DELAY_TIME); |
| 106 } | 100 } |
| 107 time = PR_IntervalNow(); | 101 time = PR_IntervalNow(); |
| 108 lastTime = slot->lastTokenPing; | 102 lastTime = slot->lastTokenPing; |
| 109 if ((lastTime) && ((time - lastTime) < s_token_delay_time)) { | 103 if ((lastTime) && ((time - lastTime) < s_token_delay_time)) { |
| 110 » return PR_TRUE; | 104 return PR_TRUE; |
| 111 } | 105 } |
| 112 slot->lastTokenPing = time; | 106 slot->lastTokenPing = time; |
| 113 return PR_FALSE; | 107 return PR_FALSE; |
| 114 } | 108 } |
| 115 | 109 |
| 116 NSS_IMPLEMENT PRBool | 110 NSS_IMPLEMENT PRBool |
| 117 nssSlot_IsTokenPresent ( | 111 nssSlot_IsTokenPresent( |
| 118 NSSSlot *slot | 112 NSSSlot *slot) |
| 119 ) | |
| 120 { | 113 { |
| 121 CK_RV ckrv; | 114 CK_RV ckrv; |
| 122 PRStatus nssrv; | 115 PRStatus nssrv; |
| 123 /* XXX */ | 116 /* XXX */ |
| 124 nssSession *session; | 117 nssSession *session; |
| 125 CK_SLOT_INFO slotInfo; | 118 CK_SLOT_INFO slotInfo; |
| 126 void *epv; | 119 void *epv; |
| 127 /* permanent slots are always present unless they're disabled */ | 120 /* permanent slots are always present unless they're disabled */ |
| 128 if (nssSlot_IsPermanent(slot)) { | 121 if (nssSlot_IsPermanent(slot)) { |
| 129 » return !PK11_IsDisabled(slot->pk11slot); | 122 return !PK11_IsDisabled(slot->pk11slot); |
| 130 } | 123 } |
| 131 /* avoid repeated calls to check token status within set interval */ | 124 /* avoid repeated calls to check token status within set interval */ |
| 132 if (within_token_delay_period(slot)) { | 125 if (within_token_delay_period(slot)) { |
| 133 » return ((slot->ckFlags & CKF_TOKEN_PRESENT) != 0); | 126 return ((slot->ckFlags & CKF_TOKEN_PRESENT) != 0); |
| 134 } | 127 } |
| 135 | 128 |
| 136 /* First obtain the slot info */ | 129 /* First obtain the slot info */ |
| 137 epv = slot->epv; | 130 epv = slot->epv; |
| 138 if (!epv) { | 131 if (!epv) { |
| 139 » return PR_FALSE; | 132 return PR_FALSE; |
| 140 } | 133 } |
| 141 nssSlot_EnterMonitor(slot); | 134 nssSlot_EnterMonitor(slot); |
| 142 ckrv = CKAPI(epv)->C_GetSlotInfo(slot->slotID, &slotInfo); | 135 ckrv = CKAPI(epv)->C_GetSlotInfo(slot->slotID, &slotInfo); |
| 143 nssSlot_ExitMonitor(slot); | 136 nssSlot_ExitMonitor(slot); |
| 144 if (ckrv != CKR_OK) { | 137 if (ckrv != CKR_OK) { |
| 145 » slot->token->base.name[0] = 0; /* XXX */ | 138 slot->token->base.name[0] = 0; /* XXX */ |
| 146 » return PR_FALSE; | 139 return PR_FALSE; |
| 147 } | 140 } |
| 148 slot->ckFlags = slotInfo.flags; | 141 slot->ckFlags = slotInfo.flags; |
| 149 /* check for the presence of the token */ | 142 /* check for the presence of the token */ |
| 150 if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) { | 143 if ((slot->ckFlags & CKF_TOKEN_PRESENT) == 0) { |
| 151 » if (!slot->token) { | 144 if (!slot->token) { |
| 152 » /* token was never present */ | 145 /* token was never present */ |
| 153 » return PR_FALSE; | 146 return PR_FALSE; |
| 154 » } | 147 } |
| 155 » session = nssToken_GetDefaultSession(slot->token); | 148 session = nssToken_GetDefaultSession(slot->token); |
| 156 » if (session) { | 149 if (session) { |
| 157 » nssSession_EnterMonitor(session); | 150 nssSession_EnterMonitor(session); |
| 158 » /* token is not present */ | 151 /* token is not present */ |
| 159 » if (session->handle != CK_INVALID_SESSION) { | 152 if (session->handle != CK_INVALID_SESSION) { |
| 160 » » /* session is valid, close and invalidate it */ | 153 /* session is valid, close and invalidate it */ |
| 161 » » CKAPI(epv)->C_CloseSession(session->handle); | 154 CKAPI(epv) |
| 162 » » session->handle = CK_INVALID_SESSION; | 155 ->C_CloseSession(session->handle); |
| 163 » } | 156 session->handle = CK_INVALID_SESSION; |
| 164 » nssSession_ExitMonitor(session); | 157 } |
| 165 » } | 158 nssSession_ExitMonitor(session); |
| 166 » if (slot->token->base.name[0] != 0) { | 159 } |
| 167 » /* notify the high-level cache that the token is removed */ | 160 if (slot->token->base.name[0] != 0) { |
| 168 » slot->token->base.name[0] = 0; /* XXX */ | 161 /* notify the high-level cache that the token is removed */ |
| 169 » nssToken_NotifyCertsNotVisible(slot->token); | 162 slot->token->base.name[0] = 0; /* XXX */ |
| 170 » } | 163 nssToken_NotifyCertsNotVisible(slot->token); |
| 171 » slot->token->base.name[0] = 0; /* XXX */ | 164 } |
| 172 » /* clear the token cache */ | 165 slot->token->base.name[0] = 0; /* XXX */ |
| 173 » nssToken_Remove(slot->token); | 166 /* clear the token cache */ |
| 174 » return PR_FALSE; | 167 nssToken_Remove(slot->token); |
| 168 return PR_FALSE; |
| 175 } | 169 } |
| 176 /* token is present, use the session info to determine if the card | 170 /* token is present, use the session info to determine if the card |
| 177 * has been removed and reinserted. | 171 * has been removed and reinserted. |
| 178 */ | 172 */ |
| 179 session = nssToken_GetDefaultSession(slot->token); | 173 session = nssToken_GetDefaultSession(slot->token); |
| 180 if (session) { | 174 if (session) { |
| 181 » PRBool isPresent = PR_FALSE; | 175 PRBool isPresent = PR_FALSE; |
| 182 » nssSession_EnterMonitor(session); | 176 nssSession_EnterMonitor(session); |
| 183 » if (session->handle != CK_INVALID_SESSION) { | 177 if (session->handle != CK_INVALID_SESSION) { |
| 184 » CK_SESSION_INFO sessionInfo; | 178 CK_SESSION_INFO sessionInfo; |
| 185 » ckrv = CKAPI(epv)->C_GetSessionInfo(session->handle, &sessionInfo); | 179 ckrv = CKAPI(epv)->C_GetSessionInfo(session->handle, &sessionInfo); |
| 186 » if (ckrv != CKR_OK) { | 180 if (ckrv != CKR_OK) { |
| 187 » » /* session is screwy, close and invalidate it */ | 181 /* session is screwy, close and invalidate it */ |
| 188 » » CKAPI(epv)->C_CloseSession(session->handle); | 182 CKAPI(epv) |
| 189 » » session->handle = CK_INVALID_SESSION; | 183 ->C_CloseSession(session->handle); |
| 190 » } | 184 session->handle = CK_INVALID_SESSION; |
| 191 » } | 185 } |
| 192 » isPresent = session->handle != CK_INVALID_SESSION; | 186 } |
| 193 » nssSession_ExitMonitor(session); | 187 isPresent = session->handle != CK_INVALID_SESSION; |
| 194 » /* token not removed, finished */ | 188 nssSession_ExitMonitor(session); |
| 195 » if (isPresent) | 189 /* token not removed, finished */ |
| 196 » return PR_TRUE; | 190 if (isPresent) |
| 197 } | 191 return PR_TRUE; |
| 192 } |
| 198 /* the token has been removed, and reinserted, or the slot contains | 193 /* the token has been removed, and reinserted, or the slot contains |
| 199 * a token it doesn't recognize. invalidate all the old | 194 * a token it doesn't recognize. invalidate all the old |
| 200 * information we had on this token, if we can't refresh, clear | 195 * information we had on this token, if we can't refresh, clear |
| 201 * the present flag */ | 196 * the present flag */ |
| 202 nssToken_NotifyCertsNotVisible(slot->token); | 197 nssToken_NotifyCertsNotVisible(slot->token); |
| 203 nssToken_Remove(slot->token); | 198 nssToken_Remove(slot->token); |
| 204 /* token has been removed, need to refresh with new session */ | 199 /* token has been removed, need to refresh with new session */ |
| 205 nssrv = nssSlot_Refresh(slot); | 200 nssrv = nssSlot_Refresh(slot); |
| 206 if (nssrv != PR_SUCCESS) { | 201 if (nssrv != PR_SUCCESS) { |
| 207 slot->token->base.name[0] = 0; /* XXX */ | 202 slot->token->base.name[0] = 0; /* XXX */ |
| 208 slot->ckFlags &= ~CKF_TOKEN_PRESENT; | 203 slot->ckFlags &= ~CKF_TOKEN_PRESENT; |
| 209 return PR_FALSE; | 204 return PR_FALSE; |
| 210 } | 205 } |
| 211 return PR_TRUE; | 206 return PR_TRUE; |
| 212 } | 207 } |
| 213 | 208 |
| 214 NSS_IMPLEMENT void * | 209 NSS_IMPLEMENT void * |
| 215 nssSlot_GetCryptokiEPV ( | 210 nssSlot_GetCryptokiEPV( |
| 216 NSSSlot *slot | 211 NSSSlot *slot) |
| 217 ) | |
| 218 { | 212 { |
| 219 return slot->epv; | 213 return slot->epv; |
| 220 } | 214 } |
| 221 | 215 |
| 222 NSS_IMPLEMENT NSSToken * | 216 NSS_IMPLEMENT NSSToken * |
| 223 nssSlot_GetToken ( | 217 nssSlot_GetToken( |
| 224 NSSSlot *slot | 218 NSSSlot *slot) |
| 225 ) | |
| 226 { | 219 { |
| 227 if (nssSlot_IsTokenPresent(slot)) { | 220 if (nssSlot_IsTokenPresent(slot)) { |
| 228 » return nssToken_AddRef(slot->token); | 221 return nssToken_AddRef(slot->token); |
| 229 } | 222 } |
| 230 return (NSSToken *)NULL; | 223 return (NSSToken *)NULL; |
| 231 } | 224 } |
| 232 | 225 |
| 233 NSS_IMPLEMENT PRStatus | 226 NSS_IMPLEMENT PRStatus |
| 234 nssSession_EnterMonitor ( | 227 nssSession_EnterMonitor( |
| 235 nssSession *s | 228 nssSession *s) |
| 236 ) | |
| 237 { | 229 { |
| 238 if (s->lock) PZ_Lock(s->lock); | 230 if (s->lock) |
| 231 PZ_Lock(s->lock); |
| 239 return PR_SUCCESS; | 232 return PR_SUCCESS; |
| 240 } | 233 } |
| 241 | 234 |
| 242 NSS_IMPLEMENT PRStatus | 235 NSS_IMPLEMENT PRStatus |
| 243 nssSession_ExitMonitor ( | 236 nssSession_ExitMonitor( |
| 244 nssSession *s | 237 nssSession *s) |
| 245 ) | |
| 246 { | 238 { |
| 247 return (s->lock) ? PZ_Unlock(s->lock) : PR_SUCCESS; | 239 return (s->lock) ? PZ_Unlock(s->lock) : PR_SUCCESS; |
| 248 } | 240 } |
| 249 | 241 |
| 250 NSS_EXTERN PRBool | 242 NSS_EXTERN PRBool |
| 251 nssSession_IsReadWrite ( | 243 nssSession_IsReadWrite( |
| 252 nssSession *s | 244 nssSession *s) |
| 253 ) | |
| 254 { | 245 { |
| 255 return s->isRW; | 246 return s->isRW; |
| 256 } | 247 } |
| 257 | |
| OLD | NEW |