summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMili Verma <mili.verma@isode.com>2015-07-01 11:12:56 (GMT)
committerMili Verma <mili.verma@isode.com>2015-07-02 12:06:54 (GMT)
commit87137e983ed986df774a3373168a7611dff583c1 (patch)
tree6e7d3356ca499b4803e495970d6de9c0e702b48d /Swiften/TLS
parentd65daf31d58ad432dadb1639f05a0d7f7f367d01 (diff)
downloadswift-87137e983ed986df774a3373168a7611dff583c1.zip
swift-87137e983ed986df774a3373168a7611dff583c1.tar.bz2
Reestablish connection with smart card
When the card is reset in shared mode (which is the mode we use), an application trying to access certain commands will be returned the value SCARD_W_RESET_CARD. When this occurs SCardReconnect() must be called. This wasn't done before so this patch fixes it. Also provides more logging for SCard function returns. Test-information: Tested on Windows using NIST smart cards. Before the fix, the Card Removed Error was seen often even after the initial connection was established. After the fix, the reconnect attempt is done so the error is not seen. Also verified that if a card is removed deliberately, then the user is logged out. Change-Id: I94748ab9ff944a79de655646e1e06a8b61776f4b
Diffstat (limited to 'Swiften/TLS')
-rw-r--r--Swiften/TLS/CAPICertificate.cpp66
1 files changed, 42 insertions, 24 deletions
diff --git a/Swiften/TLS/CAPICertificate.cpp b/Swiften/TLS/CAPICertificate.cpp
index d10ae6d..f492c50 100644
--- a/Swiften/TLS/CAPICertificate.cpp
+++ b/Swiften/TLS/CAPICertificate.cpp
@@ -1,7 +1,7 @@
1/* 1/*
2 * Copyright (c) 2012 Isode Limited, London, England. 2 * Copyright (c) 2012-2015 Isode Limited.
3 * Licensed under the simplified BSD license. 3 * All rights reserved.
4 * See Documentation/Licenses/BSD-simplified.txt for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#pragma once 7#pragma once
@@ -17,6 +17,11 @@
17// Size of the SHA1 hash 17// Size of the SHA1 hash
18#define SHA1_HASH_LEN 20 18#define SHA1_HASH_LEN 20
19 19
20#define DEBUG_SCARD_STATUS(function, status) \
21{ \
22 boost::shared_ptr<boost::system::error_code> errorCode = boost::make_shared<boost::system::error_code>(status, boost::system::system_category()); \
23 SWIFT_LOG(debug) << std::hex << function << ": status: 0x" << status << ": " << errorCode->message() << std::endl; \
24}
20 25
21namespace Swift { 26namespace Swift {
22 27
@@ -48,11 +53,13 @@ CAPICertificate::~CAPICertificate() {
48 } 53 }
49 54
50 if (cardHandle_) { 55 if (cardHandle_) {
51 (void) SCardDisconnect(cardHandle_, SCARD_LEAVE_CARD); 56 LONG result = SCardDisconnect(cardHandle_, SCARD_LEAVE_CARD);
57 DEBUG_SCARD_STATUS("SCardDisconnect", result);
52 } 58 }
53 59
54 if (scardContext_) { 60 if (scardContext_) {
55 SCardReleaseContext(scardContext_); 61 LONG result = SCardReleaseContext(scardContext_);
62 DEBUG_SCARD_STATUS("SCardReleaseContext", result);
56 } 63 }
57} 64}
58 65
@@ -191,6 +198,7 @@ void CAPICertificate::setUri (const std::string& capiUri) {
191 smartCardReaderName_ = smartCardReader; 198 smartCardReaderName_ = smartCardReader;
192 199
193 LONG result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &scardContext_); 200 LONG result = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &scardContext_);
201 DEBUG_SCARD_STATUS("SCardEstablishContext", result);
194 if (SCARD_S_SUCCESS == result) { 202 if (SCARD_S_SUCCESS == result) {
195 // Initiate monitoring for smartcard ejection 203 // Initiate monitoring for smartcard ejection
196 smartCardTimer_ = timerFactory_->createTimer(SMARTCARD_EJECTION_CHECK_FREQUENCY_MILLISECONDS); 204 smartCardTimer_ = timerFactory_->createTimer(SMARTCARD_EJECTION_CHECK_FREQUENCY_MILLISECONDS);
@@ -223,25 +231,16 @@ static void smartcard_check_status (SCARDCONTEXT hContext,
223 SCARDHANDLE hCardHandle, /* Can be 0 on the first call */ 231 SCARDHANDLE hCardHandle, /* Can be 0 on the first call */
224 SCARDHANDLE* newCardHandle, /* The handle returned */ 232 SCARDHANDLE* newCardHandle, /* The handle returned */
225 DWORD* pdwState) { 233 DWORD* pdwState) {
234 DWORD shareMode = SCARD_SHARE_SHARED;
235 DWORD preferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
236 DWORD dwAP;
237 LONG result;
238
226 if (hCardHandle == 0) { 239 if (hCardHandle == 0) {
227 DWORD dwAP; 240 result = SCardConnect(hContext, pReader, shareMode, preferredProtocols, &hCardHandle, &dwAP);
228 LONG result = SCardConnect(hContext, pReader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCardHandle, &dwAP); 241 DEBUG_SCARD_STATUS("SCardConnect", result);
229 if (SCARD_S_SUCCESS != result) { 242 if (SCARD_S_SUCCESS != result) {
230 hCardHandle = 0; 243 hCardHandle = 0;
231 if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
232 *pdwState = SCARD_ABSENT;
233 }
234 else {
235 *pdwState = SCARD_UNKNOWN;
236 }
237
238 if (newCardHandle == NULL) {
239 (void) SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
240 hCardHandle = 0;
241 }
242 else {
243 *newCardHandle = hCardHandle;
244 }
245 } 244 }
246 } 245 }
247 246
@@ -249,7 +248,26 @@ static void smartcard_check_status (SCARDCONTEXT hContext,
249 DWORD cch = sizeof(szReader); 248 DWORD cch = sizeof(szReader);
250 BYTE bAttr[32]; 249 BYTE bAttr[32];
251 DWORD cByte = 32; 250 DWORD cByte = 32;
252 LONG result = SCardStatus(hCardHandle, /* Unfortunately we can't use NULL here */ szReader, &cch, pdwState, NULL, (LPBYTE)&bAttr, &cByte); 251 size_t countStatusAttempts = 0;
252
253 while (hCardHandle && (countStatusAttempts < 2)) {
254 *pdwState = SCARD_UNKNOWN;
255
256 result = SCardStatus(hCardHandle, /* Unfortunately we can't use NULL here */ szReader, &cch, pdwState, NULL, (LPBYTE)&bAttr, &cByte);
257 DEBUG_SCARD_STATUS("SCardStatus", result);
258 countStatusAttempts++;
259
260 if ((SCARD_W_RESET_CARD == result) && (countStatusAttempts < 2)) {
261 result = SCardReconnect(hCardHandle, shareMode, preferredProtocols, SCARD_RESET_CARD, &dwAP);
262 DEBUG_SCARD_STATUS("SCardReconnect", result);
263 if (SCARD_S_SUCCESS != result) {
264 break;
265 }
266 }
267 else {
268 break;
269 }
270 }
253 271
254 if (SCARD_S_SUCCESS != result) { 272 if (SCARD_S_SUCCESS != result) {
255 if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) { 273 if (SCARD_E_NO_SMARTCARD == result || SCARD_W_REMOVED_CARD == result) {
@@ -261,8 +279,8 @@ static void smartcard_check_status (SCARDCONTEXT hContext,
261 } 279 }
262 280
263 if (newCardHandle == NULL) { 281 if (newCardHandle == NULL) {
264 (void) SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD); 282 result = SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD);
265 hCardHandle = 0; 283 DEBUG_SCARD_STATUS("SCardDisconnect", result);
266 } 284 }
267 else { 285 else {
268 *newCardHandle = hCardHandle; 286 *newCardHandle = hCardHandle;