Skip to content

Commit 71ea310

Browse files
authored
Merge pull request #13 from crocs-muni/devel
Devel
2 parents cbc16ff + 628415d commit 71ea310

File tree

5 files changed

+496
-46
lines changed

5 files changed

+496
-46
lines changed

Winscard/CommonFnc.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,10 @@ int CCommonFnc::String_ParseNullSeparatedArray(BYTE* array, DWORD arraySize, ls*
392392
} //end while
393393
}
394394

395+
if (!itemName.empty()) {
396+
pValueString->push_back(itemName);
397+
itemName = "";
398+
}
395399
return status;
396400
}
397401

Winscard/Winscard.cpp

Lines changed: 123 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ static std::string INSTRUCTION_FILE = "Instructions.txt";
8484
// The one and only CWinscardApp object
8585
CWinscardApp theApp;
8686

87-
#define REMOTE_SOCKET_TIMEOUT 5
87+
#define REMOTE_SOCKET_TIMEOUT 20
8888
#define REMOTE_SOCKET_LONG_TIMEOUT 20
8989
static string_type REMOTE_SOCKET_ENDSEQ = _CONV("@@");
9090

@@ -99,8 +99,8 @@ BYTE GET_APDU1[] = { 0x00, 0xC0, 0x00, 0x00 };
9999
BYTE GET_APDU2[] = { 0xC0, 0xC0, 0x00, 0x00 };
100100

101101
//#define VIRT_READER_NAME "VirtOpenPGP"
102-
#define VIRT_READER_NAME "Simona /111.222.123.033@07"
103-
#define VIRTUAL_READERS_LEN strlen(VIRT_READER_NAME)
102+
//#define VIRT_READER_NAME "Simona /111.222.123.033@07"
103+
//#define VIRTUAL_READERS_LEN strlen(VIRT_READER_NAME)
104104

105105
#define CMD_APDU "APDU"
106106
#define CMD_RESET "RESET"
@@ -853,17 +853,47 @@ SCard LONG STDCALL SCardListReaders(
853853
// NO BUFFER IS SUPPLIED
854854

855855
// OBTAIN REQUIRED LENGTH FOR REAL READERS
856-
if ((status = (*Original_SCardListReaders)(hContext, mszGroups, NULL, pcchReaders)) == SCARD_S_SUCCESS) {
856+
status = (*Original_SCardListReaders)(hContext, mszGroups, NULL, pcchReaders);
857+
// Supress error when virtual readers are set
858+
if (status == SCARD_E_NO_READERS_AVAILABLE && theApp.m_winscardConfig.sVIRTUAL_READERS.length() > 0) {
859+
*pcchReaders = 0;
860+
status = SCARD_S_SUCCESS;
861+
}
862+
863+
if (status == SCARD_S_SUCCESS) {
857864
// ALLOCATE OWN BUFFER FOR REAL AND VIRTUAL READERS
858-
DWORD newLen = (DWORD)(*pcchReaders + VIRTUAL_READERS_LEN + 2);
865+
DWORD newLen = (DWORD)(*pcchReaders + theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 2);
859866
char* readers = new char[newLen];
860867
memset(readers, 0, newLen);
861868
*pcchReaders = newLen;
862-
if ((status = (*Original_SCardListReaders)(hContext, mszGroups, readers, pcchReaders)) == SCARD_S_SUCCESS) {
863-
// COPY NAME OF VIRTUAL READERS TO END
864-
memcpy(readers + *pcchReaders, VIRT_READER_NAME, strlen(VIRT_READER_NAME));
869+
status = (*Original_SCardListReaders)(hContext, mszGroups, readers, pcchReaders);
870+
871+
872+
if (status == SCARD_E_NO_READERS_AVAILABLE) {
873+
// No real readers are available. Check if virtual readers are supplied
874+
if (theApp.m_winscardConfig.sVIRTUAL_READERS.length() > 0) {
875+
LogDebugString(string_format(_CONV("No real cards available, but virtual readers specified => continuing only with virtual readers.\n")));
876+
// Virtual readers are required => continue as OK (only virtual will be returned)
877+
status = SCARD_S_SUCCESS;
878+
*pcchReaders = 0;
879+
}
880+
else {
881+
// No virtual readers specified => return SCARD_E_NO_READERS_AVAILABLE error
882+
}
883+
}
884+
885+
if (status == SCARD_S_SUCCESS) {
886+
// COPY NAME OF VIRTUAL READERS TO THE END
887+
char* virtReadersPtr = readers + *pcchReaders;
888+
memcpy(virtReadersPtr, theApp.m_winscardConfig.sVIRTUAL_READERS.c_str(), theApp.m_winscardConfig.sVIRTUAL_READERS.length());
889+
// Virtual readers are separated by ; => change to ';' to '\0')
890+
for (size_t i = 0; i < theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 1; i++) {
891+
if (virtReadersPtr[i] == ',') {
892+
virtReadersPtr[i] = '\0';
893+
}
894+
}
865895
// ADD TRAILING ZERO
866-
*pcchReaders += (DWORD)strlen(VIRT_READER_NAME) + 1;
896+
*pcchReaders += (DWORD) theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 1;
867897
readers[*pcchReaders - 1] = 0;
868898
// CAST mszReaders TO char** IS NECESSARY TO CORRECTLY PROPAGATE ALLOCATED BUFFER
869899
char** temp = (char**)mszReaders;
@@ -878,25 +908,67 @@ SCard LONG STDCALL SCardListReaders(
878908
// BUFFER SUPPLIED
879909
// OBTAIN REQUIRED LENGTH FOR REAL READERS
880910
DWORD realLen = *pcchReaders;
881-
if ((status = (*Original_SCardListReaders)(hContext, mszGroups, NULL, &realLen)) == SCARD_S_SUCCESS) {
882-
if ((realLen + VIRTUAL_READERS_LEN > *pcchReaders) || (mszReaders == NULL)) {
911+
status = (*Original_SCardListReaders)(hContext, mszGroups, NULL, &realLen);
912+
913+
// Supress error when virtual readers are set
914+
if (status == SCARD_E_NO_READERS_AVAILABLE && theApp.m_winscardConfig.sVIRTUAL_READERS.length() > 0) {
915+
realLen = 0;
916+
status = SCARD_S_SUCCESS;
917+
}
918+
919+
if (status == SCARD_S_SUCCESS) {
920+
if ((realLen + theApp.m_winscardConfig.sVIRTUAL_READERS.length() > *pcchReaders) || (mszReaders == NULL)) {
883921
// SUPPLIED BUFFER IS NOT LARGE ENOUGHT
884-
*pcchReaders = (DWORD) (realLen + VIRTUAL_READERS_LEN);
922+
*pcchReaders = (DWORD) (realLen + theApp.m_winscardConfig.sVIRTUAL_READERS.length());
885923
if (mszReaders != NULL) status = SCARD_E_INSUFFICIENT_BUFFER;
886924
}
887925
else {
888926
// SUPPLIED BUFFER IS OK, COPY REAL AND VIRTUAL READERS
927+
memset(mszReaders, 0, *pcchReaders);
889928
realLen = *pcchReaders;
890-
if ((status = (*Original_SCardListReaders)(hContext, mszGroups, mszReaders, &realLen)) == SCARD_S_SUCCESS) {
929+
status = (*Original_SCardListReaders)(hContext, mszGroups, mszReaders, &realLen);
930+
if (status == SCARD_E_NO_READERS_AVAILABLE) {
931+
// No real readers are available. Check if virtual readers are supplied
932+
if (theApp.m_winscardConfig.sVIRTUAL_READERS.length() > 0) {
933+
LogDebugString(string_format(_CONV("No real cards available, but virtual readers specified => continuing only with virtual readers.\n")));
934+
// Virtual readers are required => continue as OK (only virtual will be returned)
935+
status = SCARD_S_SUCCESS;
936+
realLen = 0;
937+
}
938+
else {
939+
// No virtual readers specified => return SCARD_E_NO_READERS_AVAILABLE error
940+
}
941+
}
942+
if (status == SCARD_S_SUCCESS) {
891943
*pcchReaders = realLen;
892944

893-
// ADD VIRTUAL READER
894-
// COPY NAME OF VIRTUAL READERS TO END
895-
memcpy(mszReaders + realLen, VIRT_READER_NAME, strlen(VIRT_READER_NAME));
896-
*pcchReaders = (DWORD) (realLen + strlen(VIRT_READER_NAME) + 1);
897-
// ADD TRAILING ZERO
945+
if (theApp.m_winscardConfig.sVIRTUAL_READERS.length() > 0) {
946+
// ADD VIRTUAL READER
947+
// COPY NAME OF VIRTUAL READERS TO END
948+
char* virtReadersPtr = mszReaders;
949+
if (realLen > 0) { // Jump right after real readers
950+
virtReadersPtr += realLen - 1;
951+
}
952+
memcpy(virtReadersPtr, theApp.m_winscardConfig.sVIRTUAL_READERS.c_str(), theApp.m_winscardConfig.sVIRTUAL_READERS.length());
953+
// Virtual readers are separated by ; => change to ';' to '\0')
954+
for (size_t i = 0; i < theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 1; i++) {
955+
if (virtReadersPtr[i] == ',') {
956+
virtReadersPtr[i] = '\0';
957+
}
958+
}
959+
// If no real readers were present, add two trailing zeroes, one otherwise
960+
if (realLen == 0) {
961+
*pcchReaders = (DWORD)(theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 2);
962+
}
963+
else {
964+
*pcchReaders = (DWORD)(realLen + theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 1);
965+
}
966+
}
967+
else { *pcchReaders = realLen; }
968+
969+
// ADD TWO TRAILING ZEROES
970+
mszReaders[*pcchReaders - 2] = 0;
898971
mszReaders[*pcchReaders - 1] = 0;
899-
/**/
900972
CCommonFnc::String_ParseNullSeparatedArray((BYTE*)mszReaders, *pcchReaders - 1, &readersList);
901973
}
902974
}
@@ -1060,17 +1132,20 @@ SCard LONG STDCALL SCardListReadersW(
10601132
// OBTAIN REQUIRED LENGTH FOR REAL READERS
10611133
if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, NULL, pcchReaders)) == SCARD_S_SUCCESS) {
10621134
// ALLOCATE OWN BUFFER FOR REAL AND VIRTUAL READERS
1063-
DWORD newLen = (DWORD) (*pcchReaders + VIRTUAL_READERS_LEN);
1135+
DWORD newLen = (DWORD) (*pcchReaders + theApp.m_winscardConfig.sVIRTUAL_READERS.length());
10641136
WCHAR* readers = new WCHAR[newLen];
10651137
memset(readers, 0, newLen * sizeof(WCHAR));
10661138
*pcchReaders = newLen;
10671139
if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, readers, pcchReaders)) == SCARD_S_SUCCESS) {
10681140
// COPY NAME OF VIRTUAL READERS TO END
1069-
for (DWORD i = 0; i < strlen(VIRT_READER_NAME) + 1; i++) {
1070-
readers[i + *pcchReaders] = VIRT_READER_NAME[i];
1141+
for (DWORD i = 0; i < theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 1; i++) {
1142+
readers[i + *pcchReaders] = theApp.m_winscardConfig.sVIRTUAL_READERS.at(i);
1143+
if (readers[i + *pcchReaders] == L',') {
1144+
readers[i + *pcchReaders] = L'\0';
1145+
}
10711146
}
10721147
// ADD TRAILING ZERO
1073-
*pcchReaders += (DWORD)strlen(VIRT_READER_NAME) + 1;
1148+
*pcchReaders += (DWORD) theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 1;
10741149
readers[*pcchReaders - 1] = 0;
10751150
// CAST mszReaders TO char** IS NECESSARY TO CORRECTLY PROPAGATE ALLOCATED BUFFER
10761151
WCHAR** temp = (WCHAR**)mszReaders;
@@ -1086,25 +1161,29 @@ SCard LONG STDCALL SCardListReadersW(
10861161
// OBTAIN REQUIRED LENGTH FOR REAL READERS
10871162
DWORD realLen = *pcchReaders;
10881163
if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, NULL, &realLen)) == SCARD_S_SUCCESS) {
1089-
if ((realLen + VIRTUAL_READERS_LEN > *pcchReaders) || (mszReaders == NULL)) {
1164+
if ((realLen + theApp.m_winscardConfig.sVIRTUAL_READERS.length() > *pcchReaders) || (mszReaders == NULL)) {
10901165
// SUPPLIED BUFFER IS NOT LARGE ENOUGHT
1091-
*pcchReaders = (DWORD) (realLen + VIRTUAL_READERS_LEN);
1166+
*pcchReaders = (DWORD) (realLen + theApp.m_winscardConfig.sVIRTUAL_READERS.length());
10921167
if (mszReaders != NULL) status = SCARD_E_INSUFFICIENT_BUFFER;
10931168
}
10941169
else {
10951170
// SUPPLIED BUFFER IS OK, COPY REAL AND VIRTUAL READERS
1096-
realLen = *pcchReaders;
1171+
realLen = *pcchReaders - 1;
10971172
memset(mszReaders, 0, *pcchReaders * sizeof(WCHAR));
10981173
if ((status = (*Original_SCardListReadersW)(hContext, mszGroups, mszReaders, &realLen)) == SCARD_S_SUCCESS) {
10991174
// COPY NAME OF VIRTUAL READERS TO END (IF USED)
1100-
if (strlen(VIRT_READER_NAME) > 0) {
1101-
for (DWORD i = 0; i < strlen(VIRT_READER_NAME) + 1; i++) {
1102-
mszReaders[i + realLen] = VIRT_READER_NAME[i];
1175+
if (theApp.m_winscardConfig.sVIRTUAL_READERS.length() > 0) {
1176+
for (DWORD i = 0; i < theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 1; i++) {
1177+
mszReaders[i + realLen] = theApp.m_winscardConfig.sVIRTUAL_READERS.at(i);
1178+
if (mszReaders[i + realLen] == L',') {
1179+
mszReaders[i + realLen] = L'\0';
1180+
}
11031181
}
1104-
*pcchReaders = (DWORD)(realLen + strlen(VIRT_READER_NAME) + 1);
1182+
*pcchReaders = (DWORD)(realLen + theApp.m_winscardConfig.sVIRTUAL_READERS.length() + 1);
11051183
}
11061184
else { *pcchReaders = realLen; }
1107-
// ADD TRAILING ZERO
1185+
// ADD TWO TRAILING ZEROES
1186+
mszReaders[*pcchReaders - 2] = 0;
11081187
mszReaders[*pcchReaders - 1] = 0;
11091188

11101189
CCommonFnc::String_ParseNullSeparatedArray(mszReaders, *pcchReaders, &readersList);
@@ -2933,14 +3012,14 @@ int CWinscardApp::Remote_Connect(REMOTE_CONFIG* pRemoteConfig) {
29333012
LogDebugString(message);
29343013
pRemoteConfig->pSocket = new SocketClient(sIP, type_to_int(pRemoteConfig->port.c_str(), NULL, 10));
29353014
if (pRemoteConfig->pSocket != NULL) {
2936-
LogDebugString(_CONV("success"), false);
3015+
LogDebugString(_CONV("success\n"), false);
29373016
}
29383017
else {
2939-
LogDebugString(_CONV("failed"), false);
3018+
LogDebugString(_CONV("failed\n"), false);
29403019
}
29413020
}
29423021
catch (std::string error) {
2943-
message = string_format(_CONV("Failed to connect to %s:%s (error: %s)\n"), pRemoteConfig->IP.c_str(), pRemoteConfig->port.c_str(), error);
3022+
message = string_format(_CONV("Failed to connect to %s:%s (error: %s)\n"), pRemoteConfig->IP.c_str(), pRemoteConfig->port.c_str(), error.c_str());
29443023
LogDebugString(message, false);
29453024
}
29463025
catch (...) {
@@ -3069,7 +3148,8 @@ Remote card protocol
30693148
all other lines not starting with > or # are ignored
30703149
*/
30713150
string_type Remote_FormatRequest(string_type targetReader, DWORD uniqueCmdID, string_type command, string_type commandData, string_type notes, string_type lineSeparator) {
3072-
return string_format(">%s%s>%d%s%s%s%s%s%s", targetReader.c_str(), lineSeparator.c_str(), uniqueCmdID, CMD_SEPARATOR, command.c_str(), CMD_SEPARATOR, commandData.c_str(), lineSeparator.c_str(), notes.c_str());
3151+
// return string_format(">%s%s>%d%s%s%s%s%s%s", targetReader.c_str(), lineSeparator.c_str(), uniqueCmdID, CMD_SEPARATOR, command.c_str(), CMD_SEPARATOR, commandData.c_str(), lineSeparator.c_str(), notes.c_str());
3152+
return string_format(">%s%s\n>%d%s%s%s%s%s%s", targetReader.c_str(), lineSeparator.c_str(), uniqueCmdID, CMD_SEPARATOR, command.c_str(), CMD_SEPARATOR, commandData.c_str(), lineSeparator.c_str(), notes.c_str());
30733153
}
30743154

30753155
#if defined (_WIN32)
@@ -3126,7 +3206,7 @@ LONG CWinscardApp::Remote_ParseResponse(string_type rawResponse, DWORD expectedC
31263206

31273207
size_t pos = 0;
31283208
if (rawResponse.at(pos) != '>') {
3129-
LogWinscardRules("'>'was expected at begin");
3209+
LogWinscardRules("'>'was expected at begin\n");
31303210
status = SCARD_F_COMM_ERROR;
31313211
}
31323212
pos++;
@@ -3135,7 +3215,7 @@ LONG CWinscardApp::Remote_ParseResponse(string_type rawResponse, DWORD expectedC
31353215
size_t pos2 = rawResponse.find(CMD_SEPARATOR);
31363216
string_type uniqueCmdID = rawResponse.substr(pos, pos2 - 1);
31373217
if (expectedCommandID != atoi(uniqueCmdID.c_str())) {
3138-
LogWinscardRules("Unexpected commandID in response");
3218+
LogWinscardRules("Unexpected commandID in response\n");
31393219
status = SCARD_F_COMM_ERROR;
31403220
}
31413221
pos = pos2 + 1;
@@ -3274,6 +3354,12 @@ int CWinscardApp::LoadRule(const char_type* section_name, dictionary* dict/*stri
32743354
{
32753355
m_winscardConfig.sREADER_ORDERED_FIRST = char_value;
32763356
}
3357+
type_copy(sec_and_key, section_name);
3358+
char_value = iniparser_getstring(dict, type_cat(sec_and_key, _CONV(":VIRTUAL_READERS")), "");
3359+
if (type_length(char_value) != 0)
3360+
{
3361+
m_winscardConfig.sVIRTUAL_READERS = char_value;
3362+
}
32773363
}
32783364

32793365
#if defined (_WIN32)

Winscard/stdafx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ typedef struct _WINSCARD_CONFIG {
219219
BOOL bMODIFY_APDU_BY_RULES = FALSE;
220220
BOOL bLOG_WRITE_DESCRIPTION = FALSE;
221221
string_type sREADER_ORDERED_FIRST;
222+
string_type sVIRTUAL_READERS;
222223
string_type sLOG_BASE_PATH;
223224

224225
_WINSCARD_CONFIG(void) {
@@ -245,6 +246,7 @@ typedef struct _WINSCARD_CONFIG {
245246
bLOG_EXCHANGED_APDU = FALSE; // DEFAULT: FALSE, SET TO TRUE IF LOGGING OF APDU DATA IS REQUIRED
246247
bMODIFY_APDU_BY_RULES = FALSE; // DEFAULT: FALSE, SET TO TRUE .
247248
sREADER_ORDERED_FIRST = "";
249+
sVIRTUAL_READERS = "";
248250
sLOG_BASE_PATH = "";
249251
#endif
250252
}

WinscardTests/main.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -238,11 +238,14 @@ TEST_CASE("Winscard tests", "[winscard_tests]")
238238
myfile << "LOG_FUNCTIONS_CALLS = 1\n";
239239
myfile << "AUTO_REQUEST_DATA = 1\n";
240240
myfile << "LOG_BASE_PATH = ./\n";
241-
myfile << "[RULE1]\n";
241+
myfile << "VIRTUAL_READERS = Simona13,Simona2 \n";
242+
myfile << "\n";
243+
myfile << "[RULE1]\n";
242244
myfile << "MATCH1=in=1,cla=80,ins=ca,p1=9f,p2=17,data0=90 00,\n";
243245
myfile << "ACTION=in=1,cla=80,ins=cb,p1=9f,p2=17,data0=97 00,\n";
244246
myfile << "USAGE = 1\n";
245247
myfile << "APDUIN = 1\n";
248+
myfile << "\n";
246249

247250
myfile << "[REMOTE]\n";
248251
myfile << "REDIRECT = 1\n";
@@ -268,26 +271,40 @@ TEST_CASE("Winscard tests", "[winscard_tests]")
268271
CHECK(status == SCARD_S_SUCCESS);
269272

270273
// Print available readers
274+
memset(readers, 0, READERS_LEN);
271275
status = Original_SCardListReaders(cardContext, NULL, (char*) &readers, &len);
272276
CHECK(status == SCARD_S_SUCCESS);
273-
size_t pos = 0;
274-
while (pos < len) {
275-
cout << readers + pos << endl;
276-
pos += strlen(readers + pos) + 1;
277+
if (status == SCARD_S_SUCCESS) {
278+
size_t pos = 0;
279+
while (pos < len) {
280+
cout << readers + pos << endl;
281+
pos += strlen(readers + pos) + 1;
282+
}
283+
}
284+
else {
285+
cout << "SCardListReaders failed, no print readers";
277286
}
278287
cout << endl;
279288

280289
// Connect to specific reader
281-
string_type remoteReader = "Simona /111.222.123.033@12";
282-
cout << "Connecting to reader '" << remoteReader << "'" << endl;
290+
string_type remoteReader = "Simona /111.222.123.033@07";
291+
cout << "Connecting to reader '" << remoteReader << "' ... ";
283292
status = Original_SCardConnect(cardContext, remoteReader.c_str(), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCard, &scProtocol);
284293
CHECK(status == SCARD_S_SUCCESS);
294+
if (status == SCARD_S_SUCCESS) cout << "success";
295+
else cout << "fail";
296+
cout << endl << endl;
285297

286298
// Send APDU
287-
SendAPDU("80 cb 9f 17 02 97 00", hCard, scProtocol);
299+
//SendAPDU("80 cb 9f 17 02 97 00", hCard, scProtocol);
300+
301+
//SendAPDU("00 a4 00 00 00", hCard, scProtocol);
302+
303+
SendAPDU("11 00 00 00 00", hCard, scProtocol);
288304

289-
SendAPDU("00 a4 00 00 00", hCard, scProtocol);
305+
SendAPDU("22 00 00 00 00", hCard, scProtocol);
290306

307+
SendAPDU("33 00 00 00 00", hCard, scProtocol);
291308

292309
//
293310
// Verify expected content of resulting files

0 commit comments

Comments
 (0)