26#include <freerdp/config.h> 
   28#include <winpr/assert.h> 
   31#include <winpr/print.h> 
   32#include <winpr/stream.h> 
   33#include <winpr/smartcard.h> 
   35#include <freerdp/freerdp.h> 
   36#include <freerdp/channels/rdpdr.h> 
   37#include <freerdp/channels/scard.h> 
   39#include <freerdp/utils/rdpdr_utils.h> 
   41#include <freerdp/utils/smartcard_operations.h> 
   42#include <freerdp/utils/smartcard_pack.h> 
   44#include <freerdp/log.h> 
   45#define TAG FREERDP_TAG("utils.smartcard.ops") 
   49  WINPR_ASSERT(operation);
 
   52      smartcard_scard_context_native_from_redir(&(operation->call.handles.hContext));
 
   53  operation->hCard = smartcard_scard_handle_native_from_redir(&(operation->call.handles.hCard));
 
   55  return SCARD_S_SUCCESS;
 
   63  WINPR_ASSERT(operation);
 
   65  status = smartcard_unpack_establish_context_call(s, &operation->call.establishContext);
 
   66  if (status != SCARD_S_SUCCESS)
 
   68    return scard_log_status_error(TAG, 
"smartcard_unpack_establish_context_call", status);
 
   71  return SCARD_S_SUCCESS;
 
   79  WINPR_ASSERT(operation);
 
   81  status = smartcard_unpack_context_call(s, &operation->call.context, 
"ReleaseContext");
 
   82  if (status != SCARD_S_SUCCESS)
 
   83    scard_log_status_error(TAG, 
"smartcard_unpack_context_call", status);
 
   93  WINPR_ASSERT(operation);
 
   95  status = smartcard_unpack_context_call(s, &operation->call.context, 
"IsValidContext");
 
  105  WINPR_ASSERT(operation);
 
  107  status = smartcard_unpack_list_reader_groups_call(s, &operation->call.listReaderGroups, FALSE);
 
  117  WINPR_ASSERT(operation);
 
  119  status = smartcard_unpack_list_reader_groups_call(s, &operation->call.listReaderGroups, TRUE);
 
  129  WINPR_ASSERT(operation);
 
  131  status = smartcard_unpack_list_readers_call(s, &operation->call.listReaders, FALSE);
 
  141  WINPR_ASSERT(operation);
 
  143  status = smartcard_unpack_list_readers_call(s, &operation->call.listReaders, TRUE);
 
  153  WINPR_ASSERT(operation);
 
  156      smartcard_unpack_context_and_two_strings_a_call(s, &operation->call.contextAndTwoStringA);
 
  166  WINPR_ASSERT(operation);
 
  169      smartcard_unpack_context_and_two_strings_w_call(s, &operation->call.contextAndTwoStringW);
 
  179  WINPR_ASSERT(operation);
 
  181  status = smartcard_unpack_context_and_string_a_call(s, &operation->call.contextAndStringA);
 
  191  WINPR_ASSERT(operation);
 
  193  status = smartcard_unpack_context_and_string_w_call(s, &operation->call.contextAndStringW);
 
  203  WINPR_ASSERT(operation);
 
  205  status = smartcard_unpack_locate_cards_a_call(s, &operation->call.locateCardsA);
 
  215  WINPR_ASSERT(operation);
 
  217  status = smartcard_unpack_locate_cards_w_call(s, &operation->call.locateCardsW);
 
  225  WINPR_ASSERT(operation);
 
  227  return smartcard_unpack_get_status_change_a_call(s, &operation->call.getStatusChangeA);
 
  233  WINPR_ASSERT(operation);
 
  235  return smartcard_unpack_get_status_change_w_call(s, &operation->call.getStatusChangeW);
 
  243  WINPR_ASSERT(operation);
 
  245  status = smartcard_unpack_context_call(s, &operation->call.context, 
"Cancel");
 
  255  WINPR_ASSERT(operation);
 
  257  status = smartcard_unpack_connect_a_call(s, &operation->call.connectA);
 
  267  WINPR_ASSERT(operation);
 
  269  status = smartcard_unpack_connect_w_call(s, &operation->call.connectW);
 
  279  WINPR_ASSERT(operation);
 
  281  status = smartcard_unpack_reconnect_call(s, &operation->call.reconnect);
 
  291  WINPR_ASSERT(operation);
 
  293  status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
 
  304  WINPR_ASSERT(operation);
 
  306  status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
 
  317  WINPR_ASSERT(operation);
 
  319  status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
 
  330  WINPR_ASSERT(operation);
 
  332  status = smartcard_unpack_state_call(s, &operation->call.state);
 
  342  WINPR_ASSERT(operation);
 
  344  status = smartcard_unpack_status_call(s, &operation->call.status, FALSE);
 
  354  WINPR_ASSERT(operation);
 
  356  status = smartcard_unpack_status_call(s, &operation->call.status, TRUE);
 
  366  WINPR_ASSERT(operation);
 
  368  status = smartcard_unpack_transmit_call(s, &operation->call.transmit);
 
  378  WINPR_ASSERT(operation);
 
  380  status = smartcard_unpack_control_call(s, &operation->call.control);
 
  390  WINPR_ASSERT(operation);
 
  392  status = smartcard_unpack_get_attrib_call(s, &operation->call.getAttrib);
 
  402  WINPR_ASSERT(operation);
 
  404  status = smartcard_unpack_set_attrib_call(s, &operation->call.setAttrib);
 
  412  WINPR_ASSERT(operation);
 
  414  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
 
  415    return SCARD_F_INTERNAL_ERROR;
 
  417  Stream_Read_INT32(s, operation->call.lng.LongValue); 
 
  419  return SCARD_S_SUCCESS;
 
  427  WINPR_ASSERT(operation);
 
  429  status = smartcard_unpack_locate_cards_by_atr_a_call(s, &operation->call.locateCardsByATRA);
 
  439  WINPR_ASSERT(operation);
 
  441  status = smartcard_unpack_locate_cards_by_atr_w_call(s, &operation->call.locateCardsByATRW);
 
  451  WINPR_ASSERT(operation);
 
  453  status = smartcard_unpack_read_cache_a_call(s, &operation->call.readCacheA);
 
  463  WINPR_ASSERT(operation);
 
  465  status = smartcard_unpack_read_cache_w_call(s, &operation->call.readCacheW);
 
  475  WINPR_ASSERT(operation);
 
  477  status = smartcard_unpack_write_cache_a_call(s, &operation->call.writeCacheA);
 
  487  WINPR_ASSERT(operation);
 
  489  status = smartcard_unpack_write_cache_w_call(s, &operation->call.writeCacheW);
 
  499  WINPR_ASSERT(operation);
 
  501  status = smartcard_unpack_get_transmit_count_call(s, &operation->call.getTransmitCount);
 
  509  WINPR_UNUSED(operation);
 
  510  WLog_WARN(TAG, 
"According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules " 
  511                 "SCARD_IOCTL_RELEASETARTEDEVENT is not supported");
 
  512  return SCARD_E_UNSUPPORTED_FEATURE;
 
  520  WINPR_ASSERT(operation);
 
  522  status = smartcard_unpack_get_reader_icon_call(s, &operation->call.getReaderIcon);
 
  532  WINPR_ASSERT(operation);
 
  534  status = smartcard_unpack_get_device_type_id_call(s, &operation->call.getDeviceTypeId);
 
  539LONG smartcard_irp_device_control_decode(
wStream* s, UINT32 CompletionId, UINT32 FileId,
 
  546  WINPR_ASSERT(operation);
 
  550  if (!Stream_CheckAndLogRequiredLength(TAG, s, 32))
 
  551    return SCARD_F_INTERNAL_ERROR;
 
  553  const UINT32 outputBufferLength = Stream_Get_UINT32(s); 
 
  554  const UINT32 inputBufferLength = Stream_Get_UINT32(s);  
 
  555  const UINT32 ioControlCode = Stream_Get_UINT32(s);      
 
  557  operation->ioControlCode = ioControlCode;
 
  558  operation->ioControlCodeName = scard_get_ioctl_string(ioControlCode, FALSE);
 
  559  operation->outputBufferLength = outputBufferLength;
 
  561  if (Stream_Length(s) != (Stream_GetPosition(s) + inputBufferLength))
 
  563    WLog_WARN(TAG, 
"InputBufferLength mismatch: Actual: %" PRIuz 
" Expected: %" PRIuz 
"",
 
  564              Stream_Length(s), Stream_GetPosition(s) + inputBufferLength);
 
  565    return SCARD_F_INTERNAL_ERROR;
 
  568  WLog_DBG(TAG, 
"%s (0x%08" PRIX32 
") FileId: %" PRIu32 
" CompletionId: %" PRIu32 
"",
 
  569           scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, FileId, CompletionId);
 
  571  if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
 
  572      (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
 
  574    status = smartcard_unpack_common_type_header(s);
 
  575    if (status != SCARD_S_SUCCESS)
 
  578    status = smartcard_unpack_private_type_header(s);
 
  579    if (status != SCARD_S_SUCCESS)
 
  584  switch (ioControlCode)
 
  586    case SCARD_IOCTL_ESTABLISHCONTEXT:
 
  587      status = smartcard_EstablishContext_Decode(s, operation);
 
  590    case SCARD_IOCTL_RELEASECONTEXT:
 
  591      status = smartcard_ReleaseContext_Decode(s, operation);
 
  594    case SCARD_IOCTL_ISVALIDCONTEXT:
 
  595      status = smartcard_IsValidContext_Decode(s, operation);
 
  598    case SCARD_IOCTL_LISTREADERGROUPSA:
 
  599      status = smartcard_ListReaderGroupsA_Decode(s, operation);
 
  602    case SCARD_IOCTL_LISTREADERGROUPSW:
 
  603      status = smartcard_ListReaderGroupsW_Decode(s, operation);
 
  606    case SCARD_IOCTL_LISTREADERSA:
 
  607      status = smartcard_ListReadersA_Decode(s, operation);
 
  610    case SCARD_IOCTL_LISTREADERSW:
 
  611      status = smartcard_ListReadersW_Decode(s, operation);
 
  614    case SCARD_IOCTL_INTRODUCEREADERGROUPA:
 
  615      status = smartcard_context_and_string_a_Decode(s, operation);
 
  618    case SCARD_IOCTL_INTRODUCEREADERGROUPW:
 
  619      status = smartcard_context_and_string_w_Decode(s, operation);
 
  622    case SCARD_IOCTL_FORGETREADERGROUPA:
 
  623      status = smartcard_context_and_string_a_Decode(s, operation);
 
  626    case SCARD_IOCTL_FORGETREADERGROUPW:
 
  627      status = smartcard_context_and_string_w_Decode(s, operation);
 
  630    case SCARD_IOCTL_INTRODUCEREADERA:
 
  631      status = smartcard_context_and_two_strings_a_Decode(s, operation);
 
  634    case SCARD_IOCTL_INTRODUCEREADERW:
 
  635      status = smartcard_context_and_two_strings_w_Decode(s, operation);
 
  638    case SCARD_IOCTL_FORGETREADERA:
 
  639      status = smartcard_context_and_string_a_Decode(s, operation);
 
  642    case SCARD_IOCTL_FORGETREADERW:
 
  643      status = smartcard_context_and_string_w_Decode(s, operation);
 
  646    case SCARD_IOCTL_ADDREADERTOGROUPA:
 
  647      status = smartcard_context_and_two_strings_a_Decode(s, operation);
 
  650    case SCARD_IOCTL_ADDREADERTOGROUPW:
 
  651      status = smartcard_context_and_two_strings_w_Decode(s, operation);
 
  654    case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
 
  655      status = smartcard_context_and_two_strings_a_Decode(s, operation);
 
  658    case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
 
  659      status = smartcard_context_and_two_strings_w_Decode(s, operation);
 
  662    case SCARD_IOCTL_LOCATECARDSA:
 
  663      status = smartcard_LocateCardsA_Decode(s, operation);
 
  666    case SCARD_IOCTL_LOCATECARDSW:
 
  667      status = smartcard_LocateCardsW_Decode(s, operation);
 
  670    case SCARD_IOCTL_GETSTATUSCHANGEA:
 
  671      status = smartcard_GetStatusChangeA_Decode(s, operation);
 
  674    case SCARD_IOCTL_GETSTATUSCHANGEW:
 
  675      status = smartcard_GetStatusChangeW_Decode(s, operation);
 
  678    case SCARD_IOCTL_CANCEL:
 
  679      status = smartcard_Cancel_Decode(s, operation);
 
  682    case SCARD_IOCTL_CONNECTA:
 
  683      status = smartcard_ConnectA_Decode(s, operation);
 
  686    case SCARD_IOCTL_CONNECTW:
 
  687      status = smartcard_ConnectW_Decode(s, operation);
 
  690    case SCARD_IOCTL_RECONNECT:
 
  691      status = smartcard_Reconnect_Decode(s, operation);
 
  694    case SCARD_IOCTL_DISCONNECT:
 
  695      status = smartcard_Disconnect_Decode(s, operation);
 
  698    case SCARD_IOCTL_BEGINTRANSACTION:
 
  699      status = smartcard_BeginTransaction_Decode(s, operation);
 
  702    case SCARD_IOCTL_ENDTRANSACTION:
 
  703      status = smartcard_EndTransaction_Decode(s, operation);
 
  706    case SCARD_IOCTL_STATE:
 
  707      status = smartcard_State_Decode(s, operation);
 
  710    case SCARD_IOCTL_STATUSA:
 
  711      status = smartcard_StatusA_Decode(s, operation);
 
  714    case SCARD_IOCTL_STATUSW:
 
  715      status = smartcard_StatusW_Decode(s, operation);
 
  718    case SCARD_IOCTL_TRANSMIT:
 
  719      status = smartcard_Transmit_Decode(s, operation);
 
  722    case SCARD_IOCTL_CONTROL:
 
  723      status = smartcard_Control_Decode(s, operation);
 
  726    case SCARD_IOCTL_GETATTRIB:
 
  727      status = smartcard_GetAttrib_Decode(s, operation);
 
  730    case SCARD_IOCTL_SETATTRIB:
 
  731      status = smartcard_SetAttrib_Decode(s, operation);
 
  734    case SCARD_IOCTL_ACCESSSTARTEDEVENT:
 
  735      status = smartcard_AccessStartedEvent_Decode(s, operation);
 
  738    case SCARD_IOCTL_LOCATECARDSBYATRA:
 
  739      status = smartcard_LocateCardsByATRA_Decode(s, operation);
 
  742    case SCARD_IOCTL_LOCATECARDSBYATRW:
 
  743      status = smartcard_LocateCardsByATRW_Decode(s, operation);
 
  746    case SCARD_IOCTL_READCACHEA:
 
  747      status = smartcard_ReadCacheA_Decode(s, operation);
 
  750    case SCARD_IOCTL_READCACHEW:
 
  751      status = smartcard_ReadCacheW_Decode(s, operation);
 
  754    case SCARD_IOCTL_WRITECACHEA:
 
  755      status = smartcard_WriteCacheA_Decode(s, operation);
 
  758    case SCARD_IOCTL_WRITECACHEW:
 
  759      status = smartcard_WriteCacheW_Decode(s, operation);
 
  762    case SCARD_IOCTL_GETTRANSMITCOUNT:
 
  763      status = smartcard_GetTransmitCount_Decode(s, operation);
 
  766    case SCARD_IOCTL_RELEASETARTEDEVENT:
 
  767      status = smartcard_ReleaseStartedEvent_Decode(s, operation);
 
  770    case SCARD_IOCTL_GETREADERICON:
 
  771      status = smartcard_GetReaderIcon_Decode(s, operation);
 
  774    case SCARD_IOCTL_GETDEVICETYPEID:
 
  775      status = smartcard_GetDeviceTypeId_Decode(s, operation);
 
  779      status = SCARD_F_INTERNAL_ERROR;
 
  783  smartcard_call_to_operation_handle(operation);
 
  785  if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
 
  786      (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
 
  788    offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH);
 
  789    smartcard_unpack_read_size_align(s, Stream_GetPosition(s) - offset, 8);
 
  792  if (Stream_GetPosition(s) < Stream_Length(s))
 
  794    size_t difference = 0;
 
  795    difference = Stream_Length(s) - Stream_GetPosition(s);
 
  797              "IRP was not fully parsed %s (%s [0x%08" PRIX32 
"]): Actual: %" PRIuz
 
  798              ", Expected: %" PRIuz 
", Difference: %" PRIuz 
"",
 
  799              scard_get_ioctl_string(ioControlCode, TRUE),
 
  800              scard_get_ioctl_string(ioControlCode, FALSE), ioControlCode,
 
  801              Stream_GetPosition(s), Stream_Length(s), difference);
 
  802    winpr_HexDump(TAG, WLOG_WARN, Stream_ConstPointer(s), difference);
 
  805  if (Stream_GetPosition(s) > Stream_Length(s))
 
  807    size_t difference = 0;
 
  808    difference = Stream_GetPosition(s) - Stream_Length(s);
 
  810              "IRP was parsed beyond its end %s (0x%08" PRIX32 
"): Actual: %" PRIuz
 
  811              ", Expected: %" PRIuz 
", Difference: %" PRIuz 
"",
 
  812              scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, Stream_GetPosition(s),
 
  813              Stream_Length(s), difference);
 
  821  for (UINT32 x = 0; x < cReaders; x++)
 
  824    free(state->szReader);
 
  827  free(rgReaderStates);
 
  832  for (UINT32 x = 0; x < cReaders; x++)
 
  835    free(state->szReader);
 
  838  free(rgReaderStates);
 
  845  switch (op->ioControlCode)
 
  847    case SCARD_IOCTL_CANCEL:
 
  848    case SCARD_IOCTL_ACCESSSTARTEDEVENT:
 
  849    case SCARD_IOCTL_RELEASETARTEDEVENT:
 
  850    case SCARD_IOCTL_LISTREADERGROUPSA:
 
  851    case SCARD_IOCTL_LISTREADERGROUPSW:
 
  852    case SCARD_IOCTL_RECONNECT:
 
  853    case SCARD_IOCTL_DISCONNECT:
 
  854    case SCARD_IOCTL_BEGINTRANSACTION:
 
  855    case SCARD_IOCTL_ENDTRANSACTION:
 
  856    case SCARD_IOCTL_STATE:
 
  857    case SCARD_IOCTL_STATUSA:
 
  858    case SCARD_IOCTL_STATUSW:
 
  859    case SCARD_IOCTL_ESTABLISHCONTEXT:
 
  860    case SCARD_IOCTL_RELEASECONTEXT:
 
  861    case SCARD_IOCTL_ISVALIDCONTEXT:
 
  862    case SCARD_IOCTL_GETATTRIB:
 
  863    case SCARD_IOCTL_GETTRANSMITCOUNT:
 
  866    case SCARD_IOCTL_LOCATECARDSA:
 
  869      free(call->mszCards);
 
  871      free_reader_states_a(call->rgReaderStates, call->cReaders);
 
  874    case SCARD_IOCTL_LOCATECARDSW:
 
  877      free(call->mszCards);
 
  879      free_reader_states_w(call->rgReaderStates, call->cReaders);
 
  883    case SCARD_IOCTL_LOCATECARDSBYATRA:
 
  887      free_reader_states_a(call->rgReaderStates, call->cReaders);
 
  890    case SCARD_IOCTL_LOCATECARDSBYATRW:
 
  893      free_reader_states_w(call->rgReaderStates, call->cReaders);
 
  896    case SCARD_IOCTL_FORGETREADERA:
 
  897    case SCARD_IOCTL_INTRODUCEREADERGROUPA:
 
  898    case SCARD_IOCTL_FORGETREADERGROUPA:
 
  905    case SCARD_IOCTL_FORGETREADERW:
 
  906    case SCARD_IOCTL_INTRODUCEREADERGROUPW:
 
  907    case SCARD_IOCTL_FORGETREADERGROUPW:
 
  914    case SCARD_IOCTL_INTRODUCEREADERA:
 
  915    case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
 
  916    case SCARD_IOCTL_ADDREADERTOGROUPA:
 
  925    case SCARD_IOCTL_INTRODUCEREADERW:
 
  926    case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
 
  927    case SCARD_IOCTL_ADDREADERTOGROUPW:
 
  936    case SCARD_IOCTL_LISTREADERSA:
 
  937    case SCARD_IOCTL_LISTREADERSW:
 
  940      free(call->mszGroups);
 
  943    case SCARD_IOCTL_GETSTATUSCHANGEA:
 
  946      free_reader_states_a(call->rgReaderStates, call->cReaders);
 
  950    case SCARD_IOCTL_GETSTATUSCHANGEW:
 
  953      free_reader_states_w(call->rgReaderStates, call->cReaders);
 
  956    case SCARD_IOCTL_GETREADERICON:
 
  959      free(call->szReaderName);
 
  962    case SCARD_IOCTL_GETDEVICETYPEID:
 
  965      free(call->szReaderName);
 
  968    case SCARD_IOCTL_CONNECTA:
 
  971      free(call->szReader);
 
  974    case SCARD_IOCTL_CONNECTW:
 
  977      free(call->szReader);
 
  980    case SCARD_IOCTL_SETATTRIB:
 
  981      free(op->call.setAttrib.pbAttr);
 
  983    case SCARD_IOCTL_TRANSMIT:
 
  986      free(call->pbSendBuffer);
 
  987      free(call->pioSendPci);
 
  988      free(call->pioRecvPci);
 
  991    case SCARD_IOCTL_CONTROL:
 
  994      free(call->pvInBuffer);
 
  997    case SCARD_IOCTL_READCACHEA:
 
 1000      free(call->szLookupName);
 
 1001      free(call->Common.CardIdentifier);
 
 1004    case SCARD_IOCTL_READCACHEW:
 
 1007      free(call->szLookupName);
 
 1008      free(call->Common.CardIdentifier);
 
 1011    case SCARD_IOCTL_WRITECACHEA:
 
 1014      free(call->szLookupName);
 
 1015      free(call->Common.CardIdentifier);
 
 1016      free(call->Common.pbData);
 
 1019    case SCARD_IOCTL_WRITECACHEW:
 
 1022      free(call->szLookupName);
 
 1023      free(call->Common.CardIdentifier);
 
 1024      free(call->Common.pbData);