26 #include <freerdp/config.h>
28 #include <winpr/assert.h>
30 #include <winpr/crt.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);
227 WINPR_ASSERT(operation);
229 status = smartcard_unpack_get_status_change_a_call(s, &operation->call.getStatusChangeA);
239 WINPR_ASSERT(operation);
241 status = smartcard_unpack_get_status_change_w_call(s, &operation->call.getStatusChangeW);
251 WINPR_ASSERT(operation);
253 status = smartcard_unpack_context_call(s, &operation->call.context,
"Cancel");
263 WINPR_ASSERT(operation);
265 status = smartcard_unpack_connect_a_call(s, &operation->call.connectA);
275 WINPR_ASSERT(operation);
277 status = smartcard_unpack_connect_w_call(s, &operation->call.connectW);
287 WINPR_ASSERT(operation);
289 status = smartcard_unpack_reconnect_call(s, &operation->call.reconnect);
299 WINPR_ASSERT(operation);
301 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
312 WINPR_ASSERT(operation);
314 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
325 WINPR_ASSERT(operation);
327 status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
338 WINPR_ASSERT(operation);
340 status = smartcard_unpack_state_call(s, &operation->call.state);
350 WINPR_ASSERT(operation);
352 status = smartcard_unpack_status_call(s, &operation->call.status, FALSE);
362 WINPR_ASSERT(operation);
364 status = smartcard_unpack_status_call(s, &operation->call.status, TRUE);
374 WINPR_ASSERT(operation);
376 status = smartcard_unpack_transmit_call(s, &operation->call.transmit);
386 WINPR_ASSERT(operation);
388 status = smartcard_unpack_control_call(s, &operation->call.control);
398 WINPR_ASSERT(operation);
400 status = smartcard_unpack_get_attrib_call(s, &operation->call.getAttrib);
410 WINPR_ASSERT(operation);
412 status = smartcard_unpack_set_attrib_call(s, &operation->call.setAttrib);
420 WINPR_ASSERT(operation);
422 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
423 return SCARD_F_INTERNAL_ERROR;
425 Stream_Read_INT32(s, operation->call.lng.LongValue);
427 return SCARD_S_SUCCESS;
435 WINPR_ASSERT(operation);
437 status = smartcard_unpack_locate_cards_by_atr_a_call(s, &operation->call.locateCardsByATRA);
447 WINPR_ASSERT(operation);
449 status = smartcard_unpack_locate_cards_by_atr_w_call(s, &operation->call.locateCardsByATRW);
459 WINPR_ASSERT(operation);
461 status = smartcard_unpack_read_cache_a_call(s, &operation->call.readCacheA);
471 WINPR_ASSERT(operation);
473 status = smartcard_unpack_read_cache_w_call(s, &operation->call.readCacheW);
483 WINPR_ASSERT(operation);
485 status = smartcard_unpack_write_cache_a_call(s, &operation->call.writeCacheA);
495 WINPR_ASSERT(operation);
497 status = smartcard_unpack_write_cache_w_call(s, &operation->call.writeCacheW);
507 WINPR_ASSERT(operation);
509 status = smartcard_unpack_get_transmit_count_call(s, &operation->call.getTransmitCount);
517 WINPR_UNUSED(operation);
518 WLog_WARN(TAG,
"According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules "
519 "SCARD_IOCTL_RELEASETARTEDEVENT is not supported");
520 return SCARD_E_UNSUPPORTED_FEATURE;
528 WINPR_ASSERT(operation);
530 status = smartcard_unpack_get_reader_icon_call(s, &operation->call.getReaderIcon);
540 WINPR_ASSERT(operation);
542 status = smartcard_unpack_get_device_type_id_call(s, &operation->call.getDeviceTypeId);
547 LONG smartcard_irp_device_control_decode(
wStream* s, UINT32 CompletionId, UINT32 FileId,
552 UINT32 ioControlCode = 0;
553 UINT32 outputBufferLength = 0;
554 UINT32 inputBufferLength = 0;
557 WINPR_ASSERT(operation);
561 if (!Stream_CheckAndLogRequiredLength(TAG, s, 32))
562 return SCARD_F_INTERNAL_ERROR;
564 Stream_Read_UINT32(s, outputBufferLength);
565 Stream_Read_UINT32(s, inputBufferLength);
566 Stream_Read_UINT32(s, ioControlCode);
568 operation->ioControlCode = ioControlCode;
569 operation->ioControlCodeName = scard_get_ioctl_string(ioControlCode, FALSE);
571 if (Stream_Length(s) != (Stream_GetPosition(s) + inputBufferLength))
573 WLog_WARN(TAG,
"InputBufferLength mismatch: Actual: %" PRIuz
" Expected: %" PRIuz
"",
574 Stream_Length(s), Stream_GetPosition(s) + inputBufferLength);
575 return SCARD_F_INTERNAL_ERROR;
578 WLog_DBG(TAG,
"%s (0x%08" PRIX32
") FileId: %" PRIu32
" CompletionId: %" PRIu32
"",
579 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, FileId, CompletionId);
581 if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
582 (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
584 status = smartcard_unpack_common_type_header(s);
585 if (status != SCARD_S_SUCCESS)
588 status = smartcard_unpack_private_type_header(s);
589 if (status != SCARD_S_SUCCESS)
594 switch (ioControlCode)
596 case SCARD_IOCTL_ESTABLISHCONTEXT:
597 status = smartcard_EstablishContext_Decode(s, operation);
600 case SCARD_IOCTL_RELEASECONTEXT:
601 status = smartcard_ReleaseContext_Decode(s, operation);
604 case SCARD_IOCTL_ISVALIDCONTEXT:
605 status = smartcard_IsValidContext_Decode(s, operation);
608 case SCARD_IOCTL_LISTREADERGROUPSA:
609 status = smartcard_ListReaderGroupsA_Decode(s, operation);
612 case SCARD_IOCTL_LISTREADERGROUPSW:
613 status = smartcard_ListReaderGroupsW_Decode(s, operation);
616 case SCARD_IOCTL_LISTREADERSA:
617 status = smartcard_ListReadersA_Decode(s, operation);
620 case SCARD_IOCTL_LISTREADERSW:
621 status = smartcard_ListReadersW_Decode(s, operation);
624 case SCARD_IOCTL_INTRODUCEREADERGROUPA:
625 status = smartcard_context_and_string_a_Decode(s, operation);
628 case SCARD_IOCTL_INTRODUCEREADERGROUPW:
629 status = smartcard_context_and_string_w_Decode(s, operation);
632 case SCARD_IOCTL_FORGETREADERGROUPA:
633 status = smartcard_context_and_string_a_Decode(s, operation);
636 case SCARD_IOCTL_FORGETREADERGROUPW:
637 status = smartcard_context_and_string_w_Decode(s, operation);
640 case SCARD_IOCTL_INTRODUCEREADERA:
641 status = smartcard_context_and_two_strings_a_Decode(s, operation);
644 case SCARD_IOCTL_INTRODUCEREADERW:
645 status = smartcard_context_and_two_strings_w_Decode(s, operation);
648 case SCARD_IOCTL_FORGETREADERA:
649 status = smartcard_context_and_string_a_Decode(s, operation);
652 case SCARD_IOCTL_FORGETREADERW:
653 status = smartcard_context_and_string_w_Decode(s, operation);
656 case SCARD_IOCTL_ADDREADERTOGROUPA:
657 status = smartcard_context_and_two_strings_a_Decode(s, operation);
660 case SCARD_IOCTL_ADDREADERTOGROUPW:
661 status = smartcard_context_and_two_strings_w_Decode(s, operation);
664 case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
665 status = smartcard_context_and_two_strings_a_Decode(s, operation);
668 case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
669 status = smartcard_context_and_two_strings_w_Decode(s, operation);
672 case SCARD_IOCTL_LOCATECARDSA:
673 status = smartcard_LocateCardsA_Decode(s, operation);
676 case SCARD_IOCTL_LOCATECARDSW:
677 status = smartcard_LocateCardsW_Decode(s, operation);
680 case SCARD_IOCTL_GETSTATUSCHANGEA:
681 status = smartcard_GetStatusChangeA_Decode(s, operation);
684 case SCARD_IOCTL_GETSTATUSCHANGEW:
685 status = smartcard_GetStatusChangeW_Decode(s, operation);
688 case SCARD_IOCTL_CANCEL:
689 status = smartcard_Cancel_Decode(s, operation);
692 case SCARD_IOCTL_CONNECTA:
693 status = smartcard_ConnectA_Decode(s, operation);
696 case SCARD_IOCTL_CONNECTW:
697 status = smartcard_ConnectW_Decode(s, operation);
700 case SCARD_IOCTL_RECONNECT:
701 status = smartcard_Reconnect_Decode(s, operation);
704 case SCARD_IOCTL_DISCONNECT:
705 status = smartcard_Disconnect_Decode(s, operation);
708 case SCARD_IOCTL_BEGINTRANSACTION:
709 status = smartcard_BeginTransaction_Decode(s, operation);
712 case SCARD_IOCTL_ENDTRANSACTION:
713 status = smartcard_EndTransaction_Decode(s, operation);
716 case SCARD_IOCTL_STATE:
717 status = smartcard_State_Decode(s, operation);
720 case SCARD_IOCTL_STATUSA:
721 status = smartcard_StatusA_Decode(s, operation);
724 case SCARD_IOCTL_STATUSW:
725 status = smartcard_StatusW_Decode(s, operation);
728 case SCARD_IOCTL_TRANSMIT:
729 status = smartcard_Transmit_Decode(s, operation);
732 case SCARD_IOCTL_CONTROL:
733 status = smartcard_Control_Decode(s, operation);
736 case SCARD_IOCTL_GETATTRIB:
737 status = smartcard_GetAttrib_Decode(s, operation);
740 case SCARD_IOCTL_SETATTRIB:
741 status = smartcard_SetAttrib_Decode(s, operation);
744 case SCARD_IOCTL_ACCESSSTARTEDEVENT:
745 status = smartcard_AccessStartedEvent_Decode(s, operation);
748 case SCARD_IOCTL_LOCATECARDSBYATRA:
749 status = smartcard_LocateCardsByATRA_Decode(s, operation);
752 case SCARD_IOCTL_LOCATECARDSBYATRW:
753 status = smartcard_LocateCardsByATRW_Decode(s, operation);
756 case SCARD_IOCTL_READCACHEA:
757 status = smartcard_ReadCacheA_Decode(s, operation);
760 case SCARD_IOCTL_READCACHEW:
761 status = smartcard_ReadCacheW_Decode(s, operation);
764 case SCARD_IOCTL_WRITECACHEA:
765 status = smartcard_WriteCacheA_Decode(s, operation);
768 case SCARD_IOCTL_WRITECACHEW:
769 status = smartcard_WriteCacheW_Decode(s, operation);
772 case SCARD_IOCTL_GETTRANSMITCOUNT:
773 status = smartcard_GetTransmitCount_Decode(s, operation);
776 case SCARD_IOCTL_RELEASETARTEDEVENT:
777 status = smartcard_ReleaseStartedEvent_Decode(s, operation);
780 case SCARD_IOCTL_GETREADERICON:
781 status = smartcard_GetReaderIcon_Decode(s, operation);
784 case SCARD_IOCTL_GETDEVICETYPEID:
785 status = smartcard_GetDeviceTypeId_Decode(s, operation);
789 status = SCARD_F_INTERNAL_ERROR;
793 smartcard_call_to_operation_handle(operation);
795 if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
796 (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
798 offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH);
799 smartcard_unpack_read_size_align(s, Stream_GetPosition(s) - offset, 8);
802 if (Stream_GetPosition(s) < Stream_Length(s))
804 size_t difference = 0;
805 difference = Stream_Length(s) - Stream_GetPosition(s);
807 "IRP was not fully parsed %s (%s [0x%08" PRIX32
"]): Actual: %" PRIuz
808 ", Expected: %" PRIuz
", Difference: %" PRIuz
"",
809 scard_get_ioctl_string(ioControlCode, TRUE),
810 scard_get_ioctl_string(ioControlCode, FALSE), ioControlCode,
811 Stream_GetPosition(s), Stream_Length(s), difference);
812 winpr_HexDump(TAG, WLOG_WARN, Stream_ConstPointer(s), difference);
815 if (Stream_GetPosition(s) > Stream_Length(s))
817 size_t difference = 0;
818 difference = Stream_GetPosition(s) - Stream_Length(s);
820 "IRP was parsed beyond its end %s (0x%08" PRIX32
"): Actual: %" PRIuz
821 ", Expected: %" PRIuz
", Difference: %" PRIuz
"",
822 scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, Stream_GetPosition(s),
823 Stream_Length(s), difference);
831 for (UINT32 x = 0; x < cReaders; x++)
834 free(state->szReader);
837 free(rgReaderStates);
842 for (UINT32 x = 0; x < cReaders; x++)
845 free(state->szReader);
848 free(rgReaderStates);
855 switch (op->ioControlCode)
857 case SCARD_IOCTL_CANCEL:
858 case SCARD_IOCTL_ACCESSSTARTEDEVENT:
859 case SCARD_IOCTL_RELEASETARTEDEVENT:
860 case SCARD_IOCTL_LISTREADERGROUPSA:
861 case SCARD_IOCTL_LISTREADERGROUPSW:
862 case SCARD_IOCTL_RECONNECT:
863 case SCARD_IOCTL_DISCONNECT:
864 case SCARD_IOCTL_BEGINTRANSACTION:
865 case SCARD_IOCTL_ENDTRANSACTION:
866 case SCARD_IOCTL_STATE:
867 case SCARD_IOCTL_STATUSA:
868 case SCARD_IOCTL_STATUSW:
869 case SCARD_IOCTL_ESTABLISHCONTEXT:
870 case SCARD_IOCTL_RELEASECONTEXT:
871 case SCARD_IOCTL_ISVALIDCONTEXT:
872 case SCARD_IOCTL_GETATTRIB:
873 case SCARD_IOCTL_GETTRANSMITCOUNT:
876 case SCARD_IOCTL_LOCATECARDSA:
879 free(call->mszCards);
881 free_reader_states_a(call->rgReaderStates, call->cReaders);
884 case SCARD_IOCTL_LOCATECARDSW:
887 free(call->mszCards);
889 free_reader_states_w(call->rgReaderStates, call->cReaders);
893 case SCARD_IOCTL_LOCATECARDSBYATRA:
897 free_reader_states_a(call->rgReaderStates, call->cReaders);
900 case SCARD_IOCTL_LOCATECARDSBYATRW:
903 free_reader_states_w(call->rgReaderStates, call->cReaders);
906 case SCARD_IOCTL_FORGETREADERA:
907 case SCARD_IOCTL_INTRODUCEREADERGROUPA:
908 case SCARD_IOCTL_FORGETREADERGROUPA:
915 case SCARD_IOCTL_FORGETREADERW:
916 case SCARD_IOCTL_INTRODUCEREADERGROUPW:
917 case SCARD_IOCTL_FORGETREADERGROUPW:
924 case SCARD_IOCTL_INTRODUCEREADERA:
925 case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
926 case SCARD_IOCTL_ADDREADERTOGROUPA:
935 case SCARD_IOCTL_INTRODUCEREADERW:
936 case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
937 case SCARD_IOCTL_ADDREADERTOGROUPW:
946 case SCARD_IOCTL_LISTREADERSA:
947 case SCARD_IOCTL_LISTREADERSW:
950 free(call->mszGroups);
953 case SCARD_IOCTL_GETSTATUSCHANGEA:
956 free_reader_states_a(call->rgReaderStates, call->cReaders);
960 case SCARD_IOCTL_GETSTATUSCHANGEW:
963 free_reader_states_w(call->rgReaderStates, call->cReaders);
966 case SCARD_IOCTL_GETREADERICON:
969 free(call->szReaderName);
972 case SCARD_IOCTL_GETDEVICETYPEID:
975 free(call->szReaderName);
978 case SCARD_IOCTL_CONNECTA:
981 free(call->szReader);
984 case SCARD_IOCTL_CONNECTW:
987 free(call->szReader);
990 case SCARD_IOCTL_SETATTRIB:
991 free(op->call.setAttrib.pbAttr);
993 case SCARD_IOCTL_TRANSMIT:
996 free(call->pbSendBuffer);
997 free(call->pioSendPci);
998 free(call->pioRecvPci);
1001 case SCARD_IOCTL_CONTROL:
1004 free(call->pvInBuffer);
1007 case SCARD_IOCTL_READCACHEA:
1010 free(call->szLookupName);
1011 free(call->Common.CardIdentifier);
1014 case SCARD_IOCTL_READCACHEW:
1017 free(call->szLookupName);
1018 free(call->Common.CardIdentifier);
1021 case SCARD_IOCTL_WRITECACHEA:
1024 free(call->szLookupName);
1025 free(call->Common.CardIdentifier);
1026 free(call->Common.pbData);
1029 case SCARD_IOCTL_WRITECACHEW:
1032 free(call->szLookupName);
1033 free(call->Common.CardIdentifier);
1034 free(call->Common.pbData);