Coverage Report

Created: 2024-05-20 06:11

/src/FreeRDP/libfreerdp/utils/smartcard_operations.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Smartcard Device Service Virtual Channel
4
 *
5
 * Copyright (C) Alexi Volkov <alexi@myrealbox.com> 2006
6
 * Copyright 2011 O.S. Systems Software Ltda.
7
 * Copyright 2011 Anthony Tong <atong@trustedcs.com>
8
 * Copyright 2015 Thincast Technologies GmbH
9
 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
10
 * Copyright 2017 Armin Novak <armin.novak@thincast.com>
11
 * Copyright 2017 Thincast Technologies GmbH
12
 *
13
 * Licensed under the Apache License, Version 2.0 (the "License");
14
 * you may not use this file except in compliance with the License.
15
 * You may obtain a copy of the License at
16
 *
17
 *     http://www.apache.org/licenses/LICENSE-2.0
18
 *
19
 * Unless required by applicable law or agreed to in writing, software
20
 * distributed under the License is distributed on an "AS IS" BASIS,
21
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
 * See the License for the specific language governing permissions and
23
 * limitations under the License.
24
 */
25
26
#include <freerdp/config.h>
27
28
#include <winpr/assert.h>
29
30
#include <winpr/crt.h>
31
#include <winpr/print.h>
32
#include <winpr/stream.h>
33
#include <winpr/smartcard.h>
34
35
#include <freerdp/freerdp.h>
36
#include <freerdp/channels/rdpdr.h>
37
#include <freerdp/channels/scard.h>
38
39
#include <freerdp/utils/rdpdr_utils.h>
40
41
#include <freerdp/utils/smartcard_operations.h>
42
#include <freerdp/utils/smartcard_pack.h>
43
44
#include <freerdp/log.h>
45
0
#define TAG FREERDP_TAG("utils.smartcard.ops")
46
47
static LONG smartcard_call_to_operation_handle(SMARTCARD_OPERATION* operation)
48
0
{
49
0
  WINPR_ASSERT(operation);
50
51
0
  operation->hContext =
52
0
      smartcard_scard_context_native_from_redir(&(operation->call.handles.hContext));
53
0
  operation->hCard = smartcard_scard_handle_native_from_redir(&(operation->call.handles.hCard));
54
55
0
  return SCARD_S_SUCCESS;
56
0
}
57
58
static LONG smartcard_EstablishContext_Decode(wStream* s, SMARTCARD_OPERATION* operation)
59
0
{
60
0
  LONG status = 0;
61
62
0
  WINPR_ASSERT(s);
63
0
  WINPR_ASSERT(operation);
64
65
0
  status = smartcard_unpack_establish_context_call(s, &operation->call.establishContext);
66
0
  if (status != SCARD_S_SUCCESS)
67
0
  {
68
0
    return scard_log_status_error(TAG, "smartcard_unpack_establish_context_call", status);
69
0
  }
70
71
0
  return SCARD_S_SUCCESS;
72
0
}
73
74
static LONG smartcard_ReleaseContext_Decode(wStream* s, SMARTCARD_OPERATION* operation)
75
0
{
76
0
  LONG status = 0;
77
78
0
  WINPR_ASSERT(s);
79
0
  WINPR_ASSERT(operation);
80
81
0
  status = smartcard_unpack_context_call(s, &operation->call.context, "ReleaseContext");
82
0
  if (status != SCARD_S_SUCCESS)
83
0
    scard_log_status_error(TAG, "smartcard_unpack_context_call", status);
84
85
0
  return status;
86
0
}
87
88
static LONG smartcard_IsValidContext_Decode(wStream* s, SMARTCARD_OPERATION* operation)
89
0
{
90
0
  LONG status = 0;
91
92
0
  WINPR_ASSERT(s);
93
0
  WINPR_ASSERT(operation);
94
95
0
  status = smartcard_unpack_context_call(s, &operation->call.context, "IsValidContext");
96
97
0
  return status;
98
0
}
99
100
static LONG smartcard_ListReaderGroupsA_Decode(wStream* s, SMARTCARD_OPERATION* operation)
101
0
{
102
0
  LONG status = 0;
103
104
0
  WINPR_ASSERT(s);
105
0
  WINPR_ASSERT(operation);
106
107
0
  status = smartcard_unpack_list_reader_groups_call(s, &operation->call.listReaderGroups, FALSE);
108
109
0
  return status;
110
0
}
111
112
static LONG smartcard_ListReaderGroupsW_Decode(wStream* s, SMARTCARD_OPERATION* operation)
113
0
{
114
0
  LONG status = 0;
115
116
0
  WINPR_ASSERT(s);
117
0
  WINPR_ASSERT(operation);
118
119
0
  status = smartcard_unpack_list_reader_groups_call(s, &operation->call.listReaderGroups, TRUE);
120
121
0
  return status;
122
0
}
123
124
static LONG smartcard_ListReadersA_Decode(wStream* s, SMARTCARD_OPERATION* operation)
125
0
{
126
0
  LONG status = 0;
127
128
0
  WINPR_ASSERT(s);
129
0
  WINPR_ASSERT(operation);
130
131
0
  status = smartcard_unpack_list_readers_call(s, &operation->call.listReaders, FALSE);
132
133
0
  return status;
134
0
}
135
136
static LONG smartcard_ListReadersW_Decode(wStream* s, SMARTCARD_OPERATION* operation)
137
0
{
138
0
  LONG status = 0;
139
140
0
  WINPR_ASSERT(s);
141
0
  WINPR_ASSERT(operation);
142
143
0
  status = smartcard_unpack_list_readers_call(s, &operation->call.listReaders, TRUE);
144
145
0
  return status;
146
0
}
147
148
static LONG smartcard_context_and_two_strings_a_Decode(wStream* s, SMARTCARD_OPERATION* operation)
149
0
{
150
0
  LONG status = 0;
151
152
0
  WINPR_ASSERT(s);
153
0
  WINPR_ASSERT(operation);
154
155
0
  status =
156
0
      smartcard_unpack_context_and_two_strings_a_call(s, &operation->call.contextAndTwoStringA);
157
158
0
  return status;
159
0
}
160
161
static LONG smartcard_context_and_two_strings_w_Decode(wStream* s, SMARTCARD_OPERATION* operation)
162
0
{
163
0
  LONG status = 0;
164
165
0
  WINPR_ASSERT(s);
166
0
  WINPR_ASSERT(operation);
167
168
0
  status =
169
0
      smartcard_unpack_context_and_two_strings_w_call(s, &operation->call.contextAndTwoStringW);
170
171
0
  return status;
172
0
}
173
174
static LONG smartcard_context_and_string_a_Decode(wStream* s, SMARTCARD_OPERATION* operation)
175
0
{
176
0
  LONG status = 0;
177
178
0
  WINPR_ASSERT(s);
179
0
  WINPR_ASSERT(operation);
180
181
0
  status = smartcard_unpack_context_and_string_a_call(s, &operation->call.contextAndStringA);
182
183
0
  return status;
184
0
}
185
186
static LONG smartcard_context_and_string_w_Decode(wStream* s, SMARTCARD_OPERATION* operation)
187
0
{
188
0
  LONG status = 0;
189
190
0
  WINPR_ASSERT(s);
191
0
  WINPR_ASSERT(operation);
192
193
0
  status = smartcard_unpack_context_and_string_w_call(s, &operation->call.contextAndStringW);
194
195
0
  return status;
196
0
}
197
198
static LONG smartcard_LocateCardsA_Decode(wStream* s, SMARTCARD_OPERATION* operation)
199
0
{
200
0
  LONG status = 0;
201
202
0
  WINPR_ASSERT(s);
203
0
  WINPR_ASSERT(operation);
204
205
0
  status = smartcard_unpack_locate_cards_a_call(s, &operation->call.locateCardsA);
206
207
0
  return status;
208
0
}
209
210
static LONG smartcard_LocateCardsW_Decode(wStream* s, SMARTCARD_OPERATION* operation)
211
0
{
212
0
  LONG status = 0;
213
214
0
  WINPR_ASSERT(s);
215
0
  WINPR_ASSERT(operation);
216
217
0
  status = smartcard_unpack_locate_cards_w_call(s, &operation->call.locateCardsW);
218
219
0
  return status;
220
0
}
221
222
static LONG smartcard_GetStatusChangeA_Decode(wStream* s, SMARTCARD_OPERATION* operation)
223
0
{
224
0
  LONG status = 0;
225
226
0
  WINPR_ASSERT(s);
227
0
  WINPR_ASSERT(operation);
228
229
0
  status = smartcard_unpack_get_status_change_a_call(s, &operation->call.getStatusChangeA);
230
231
0
  return status;
232
0
}
233
234
static LONG smartcard_GetStatusChangeW_Decode(wStream* s, SMARTCARD_OPERATION* operation)
235
0
{
236
0
  LONG status = 0;
237
238
0
  WINPR_ASSERT(s);
239
0
  WINPR_ASSERT(operation);
240
241
0
  status = smartcard_unpack_get_status_change_w_call(s, &operation->call.getStatusChangeW);
242
243
0
  return status;
244
0
}
245
246
static LONG smartcard_Cancel_Decode(wStream* s, SMARTCARD_OPERATION* operation)
247
0
{
248
0
  LONG status = 0;
249
250
0
  WINPR_ASSERT(s);
251
0
  WINPR_ASSERT(operation);
252
253
0
  status = smartcard_unpack_context_call(s, &operation->call.context, "Cancel");
254
255
0
  return status;
256
0
}
257
258
static LONG smartcard_ConnectA_Decode(wStream* s, SMARTCARD_OPERATION* operation)
259
0
{
260
0
  LONG status = 0;
261
262
0
  WINPR_ASSERT(s);
263
0
  WINPR_ASSERT(operation);
264
265
0
  status = smartcard_unpack_connect_a_call(s, &operation->call.connectA);
266
267
0
  return status;
268
0
}
269
270
static LONG smartcard_ConnectW_Decode(wStream* s, SMARTCARD_OPERATION* operation)
271
0
{
272
0
  LONG status = 0;
273
274
0
  WINPR_ASSERT(s);
275
0
  WINPR_ASSERT(operation);
276
277
0
  status = smartcard_unpack_connect_w_call(s, &operation->call.connectW);
278
279
0
  return status;
280
0
}
281
282
static LONG smartcard_Reconnect_Decode(wStream* s, SMARTCARD_OPERATION* operation)
283
0
{
284
0
  LONG status = 0;
285
286
0
  WINPR_ASSERT(s);
287
0
  WINPR_ASSERT(operation);
288
289
0
  status = smartcard_unpack_reconnect_call(s, &operation->call.reconnect);
290
291
0
  return status;
292
0
}
293
294
static LONG smartcard_Disconnect_Decode(wStream* s, SMARTCARD_OPERATION* operation)
295
0
{
296
0
  LONG status = 0;
297
298
0
  WINPR_ASSERT(s);
299
0
  WINPR_ASSERT(operation);
300
301
0
  status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
302
0
                                                       "Disconnect");
303
304
0
  return status;
305
0
}
306
307
static LONG smartcard_BeginTransaction_Decode(wStream* s, SMARTCARD_OPERATION* operation)
308
0
{
309
0
  LONG status = 0;
310
311
0
  WINPR_ASSERT(s);
312
0
  WINPR_ASSERT(operation);
313
314
0
  status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
315
0
                                                       "BeginTransaction");
316
317
0
  return status;
318
0
}
319
320
static LONG smartcard_EndTransaction_Decode(wStream* s, SMARTCARD_OPERATION* operation)
321
0
{
322
0
  LONG status = 0;
323
324
0
  WINPR_ASSERT(s);
325
0
  WINPR_ASSERT(operation);
326
327
0
  status = smartcard_unpack_hcard_and_disposition_call(s, &operation->call.hCardAndDisposition,
328
0
                                                       "EndTransaction");
329
330
0
  return status;
331
0
}
332
333
static LONG smartcard_State_Decode(wStream* s, SMARTCARD_OPERATION* operation)
334
0
{
335
0
  LONG status = 0;
336
337
0
  WINPR_ASSERT(s);
338
0
  WINPR_ASSERT(operation);
339
340
0
  status = smartcard_unpack_state_call(s, &operation->call.state);
341
342
0
  return status;
343
0
}
344
345
static LONG smartcard_StatusA_Decode(wStream* s, SMARTCARD_OPERATION* operation)
346
0
{
347
0
  LONG status = 0;
348
349
0
  WINPR_ASSERT(s);
350
0
  WINPR_ASSERT(operation);
351
352
0
  status = smartcard_unpack_status_call(s, &operation->call.status, FALSE);
353
354
0
  return status;
355
0
}
356
357
static LONG smartcard_StatusW_Decode(wStream* s, SMARTCARD_OPERATION* operation)
358
0
{
359
0
  LONG status = 0;
360
361
0
  WINPR_ASSERT(s);
362
0
  WINPR_ASSERT(operation);
363
364
0
  status = smartcard_unpack_status_call(s, &operation->call.status, TRUE);
365
366
0
  return status;
367
0
}
368
369
static LONG smartcard_Transmit_Decode(wStream* s, SMARTCARD_OPERATION* operation)
370
0
{
371
0
  LONG status = 0;
372
373
0
  WINPR_ASSERT(s);
374
0
  WINPR_ASSERT(operation);
375
376
0
  status = smartcard_unpack_transmit_call(s, &operation->call.transmit);
377
378
0
  return status;
379
0
}
380
381
static LONG smartcard_Control_Decode(wStream* s, SMARTCARD_OPERATION* operation)
382
0
{
383
0
  LONG status = 0;
384
385
0
  WINPR_ASSERT(s);
386
0
  WINPR_ASSERT(operation);
387
388
0
  status = smartcard_unpack_control_call(s, &operation->call.control);
389
390
0
  return status;
391
0
}
392
393
static LONG smartcard_GetAttrib_Decode(wStream* s, SMARTCARD_OPERATION* operation)
394
0
{
395
0
  LONG status = 0;
396
397
0
  WINPR_ASSERT(s);
398
0
  WINPR_ASSERT(operation);
399
400
0
  status = smartcard_unpack_get_attrib_call(s, &operation->call.getAttrib);
401
402
0
  return status;
403
0
}
404
405
static LONG smartcard_SetAttrib_Decode(wStream* s, SMARTCARD_OPERATION* operation)
406
0
{
407
0
  LONG status = 0;
408
409
0
  WINPR_ASSERT(s);
410
0
  WINPR_ASSERT(operation);
411
412
0
  status = smartcard_unpack_set_attrib_call(s, &operation->call.setAttrib);
413
414
0
  return status;
415
0
}
416
417
static LONG smartcard_AccessStartedEvent_Decode(wStream* s, SMARTCARD_OPERATION* operation)
418
0
{
419
0
  WINPR_ASSERT(s);
420
0
  WINPR_ASSERT(operation);
421
422
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
423
0
    return SCARD_F_INTERNAL_ERROR;
424
425
0
  Stream_Read_INT32(s, operation->call.lng.LongValue); /* Unused (4 bytes) */
426
427
0
  return SCARD_S_SUCCESS;
428
0
}
429
430
static LONG smartcard_LocateCardsByATRA_Decode(wStream* s, SMARTCARD_OPERATION* operation)
431
0
{
432
0
  LONG status = 0;
433
434
0
  WINPR_ASSERT(s);
435
0
  WINPR_ASSERT(operation);
436
437
0
  status = smartcard_unpack_locate_cards_by_atr_a_call(s, &operation->call.locateCardsByATRA);
438
439
0
  return status;
440
0
}
441
442
static LONG smartcard_LocateCardsByATRW_Decode(wStream* s, SMARTCARD_OPERATION* operation)
443
0
{
444
0
  LONG status = 0;
445
446
0
  WINPR_ASSERT(s);
447
0
  WINPR_ASSERT(operation);
448
449
0
  status = smartcard_unpack_locate_cards_by_atr_w_call(s, &operation->call.locateCardsByATRW);
450
451
0
  return status;
452
0
}
453
454
static LONG smartcard_ReadCacheA_Decode(wStream* s, SMARTCARD_OPERATION* operation)
455
0
{
456
0
  LONG status = 0;
457
458
0
  WINPR_ASSERT(s);
459
0
  WINPR_ASSERT(operation);
460
461
0
  status = smartcard_unpack_read_cache_a_call(s, &operation->call.readCacheA);
462
463
0
  return status;
464
0
}
465
466
static LONG smartcard_ReadCacheW_Decode(wStream* s, SMARTCARD_OPERATION* operation)
467
0
{
468
0
  LONG status = 0;
469
470
0
  WINPR_ASSERT(s);
471
0
  WINPR_ASSERT(operation);
472
473
0
  status = smartcard_unpack_read_cache_w_call(s, &operation->call.readCacheW);
474
475
0
  return status;
476
0
}
477
478
static LONG smartcard_WriteCacheA_Decode(wStream* s, SMARTCARD_OPERATION* operation)
479
0
{
480
0
  LONG status = 0;
481
482
0
  WINPR_ASSERT(s);
483
0
  WINPR_ASSERT(operation);
484
485
0
  status = smartcard_unpack_write_cache_a_call(s, &operation->call.writeCacheA);
486
487
0
  return status;
488
0
}
489
490
static LONG smartcard_WriteCacheW_Decode(wStream* s, SMARTCARD_OPERATION* operation)
491
0
{
492
0
  LONG status = 0;
493
494
0
  WINPR_ASSERT(s);
495
0
  WINPR_ASSERT(operation);
496
497
0
  status = smartcard_unpack_write_cache_w_call(s, &operation->call.writeCacheW);
498
499
0
  return status;
500
0
}
501
502
static LONG smartcard_GetTransmitCount_Decode(wStream* s, SMARTCARD_OPERATION* operation)
503
0
{
504
0
  LONG status = 0;
505
506
0
  WINPR_ASSERT(s);
507
0
  WINPR_ASSERT(operation);
508
509
0
  status = smartcard_unpack_get_transmit_count_call(s, &operation->call.getTransmitCount);
510
511
0
  return status;
512
0
}
513
514
static LONG smartcard_ReleaseStartedEvent_Decode(wStream* s, SMARTCARD_OPERATION* operation)
515
0
{
516
0
  WINPR_UNUSED(s);
517
0
  WINPR_UNUSED(operation);
518
0
  WLog_WARN(TAG, "According to [MS-RDPESC] 3.1.4 Message Processing Events and Sequencing Rules "
519
0
                 "SCARD_IOCTL_RELEASETARTEDEVENT is not supported");
520
0
  return SCARD_E_UNSUPPORTED_FEATURE;
521
0
}
522
523
static LONG smartcard_GetReaderIcon_Decode(wStream* s, SMARTCARD_OPERATION* operation)
524
0
{
525
0
  LONG status = 0;
526
527
0
  WINPR_ASSERT(s);
528
0
  WINPR_ASSERT(operation);
529
530
0
  status = smartcard_unpack_get_reader_icon_call(s, &operation->call.getReaderIcon);
531
532
0
  return status;
533
0
}
534
535
static LONG smartcard_GetDeviceTypeId_Decode(wStream* s, SMARTCARD_OPERATION* operation)
536
0
{
537
0
  LONG status = 0;
538
539
0
  WINPR_ASSERT(s);
540
0
  WINPR_ASSERT(operation);
541
542
0
  status = smartcard_unpack_get_device_type_id_call(s, &operation->call.getDeviceTypeId);
543
544
0
  return status;
545
0
}
546
547
LONG smartcard_irp_device_control_decode(wStream* s, UINT32 CompletionId, UINT32 FileId,
548
                                         SMARTCARD_OPERATION* operation)
549
0
{
550
0
  LONG status = 0;
551
0
  UINT32 offset = 0;
552
0
  UINT32 ioControlCode = 0;
553
0
  UINT32 outputBufferLength = 0;
554
0
  UINT32 inputBufferLength = 0;
555
556
0
  WINPR_ASSERT(s);
557
0
  WINPR_ASSERT(operation);
558
559
  /* Device Control Request */
560
561
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 32))
562
0
    return SCARD_F_INTERNAL_ERROR;
563
564
0
  Stream_Read_UINT32(s, outputBufferLength); /* OutputBufferLength (4 bytes) */
565
0
  Stream_Read_UINT32(s, inputBufferLength);  /* InputBufferLength (4 bytes) */
566
0
  Stream_Read_UINT32(s, ioControlCode);      /* IoControlCode (4 bytes) */
567
0
  Stream_Seek(s, 20);                        /* Padding (20 bytes) */
568
0
  operation->ioControlCode = ioControlCode;
569
0
  operation->ioControlCodeName = scard_get_ioctl_string(ioControlCode, FALSE);
570
571
0
  if (Stream_Length(s) != (Stream_GetPosition(s) + inputBufferLength))
572
0
  {
573
0
    WLog_WARN(TAG, "InputBufferLength mismatch: Actual: %" PRIuz " Expected: %" PRIuz "",
574
0
              Stream_Length(s), Stream_GetPosition(s) + inputBufferLength);
575
0
    return SCARD_F_INTERNAL_ERROR;
576
0
  }
577
578
0
  WLog_DBG(TAG, "%s (0x%08" PRIX32 ") FileId: %" PRIu32 " CompletionId: %" PRIu32 "",
579
0
           scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, FileId, CompletionId);
580
581
0
  if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
582
0
      (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
583
0
  {
584
0
    status = smartcard_unpack_common_type_header(s);
585
0
    if (status != SCARD_S_SUCCESS)
586
0
      return status;
587
588
0
    status = smartcard_unpack_private_type_header(s);
589
0
    if (status != SCARD_S_SUCCESS)
590
0
      return status;
591
0
  }
592
593
  /* Decode */
594
0
  switch (ioControlCode)
595
0
  {
596
0
    case SCARD_IOCTL_ESTABLISHCONTEXT:
597
0
      status = smartcard_EstablishContext_Decode(s, operation);
598
0
      break;
599
600
0
    case SCARD_IOCTL_RELEASECONTEXT:
601
0
      status = smartcard_ReleaseContext_Decode(s, operation);
602
0
      break;
603
604
0
    case SCARD_IOCTL_ISVALIDCONTEXT:
605
0
      status = smartcard_IsValidContext_Decode(s, operation);
606
0
      break;
607
608
0
    case SCARD_IOCTL_LISTREADERGROUPSA:
609
0
      status = smartcard_ListReaderGroupsA_Decode(s, operation);
610
0
      break;
611
612
0
    case SCARD_IOCTL_LISTREADERGROUPSW:
613
0
      status = smartcard_ListReaderGroupsW_Decode(s, operation);
614
0
      break;
615
616
0
    case SCARD_IOCTL_LISTREADERSA:
617
0
      status = smartcard_ListReadersA_Decode(s, operation);
618
0
      break;
619
620
0
    case SCARD_IOCTL_LISTREADERSW:
621
0
      status = smartcard_ListReadersW_Decode(s, operation);
622
0
      break;
623
624
0
    case SCARD_IOCTL_INTRODUCEREADERGROUPA:
625
0
      status = smartcard_context_and_string_a_Decode(s, operation);
626
0
      break;
627
628
0
    case SCARD_IOCTL_INTRODUCEREADERGROUPW:
629
0
      status = smartcard_context_and_string_w_Decode(s, operation);
630
0
      break;
631
632
0
    case SCARD_IOCTL_FORGETREADERGROUPA:
633
0
      status = smartcard_context_and_string_a_Decode(s, operation);
634
0
      break;
635
636
0
    case SCARD_IOCTL_FORGETREADERGROUPW:
637
0
      status = smartcard_context_and_string_w_Decode(s, operation);
638
0
      break;
639
640
0
    case SCARD_IOCTL_INTRODUCEREADERA:
641
0
      status = smartcard_context_and_two_strings_a_Decode(s, operation);
642
0
      break;
643
644
0
    case SCARD_IOCTL_INTRODUCEREADERW:
645
0
      status = smartcard_context_and_two_strings_w_Decode(s, operation);
646
0
      break;
647
648
0
    case SCARD_IOCTL_FORGETREADERA:
649
0
      status = smartcard_context_and_string_a_Decode(s, operation);
650
0
      break;
651
652
0
    case SCARD_IOCTL_FORGETREADERW:
653
0
      status = smartcard_context_and_string_w_Decode(s, operation);
654
0
      break;
655
656
0
    case SCARD_IOCTL_ADDREADERTOGROUPA:
657
0
      status = smartcard_context_and_two_strings_a_Decode(s, operation);
658
0
      break;
659
660
0
    case SCARD_IOCTL_ADDREADERTOGROUPW:
661
0
      status = smartcard_context_and_two_strings_w_Decode(s, operation);
662
0
      break;
663
664
0
    case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
665
0
      status = smartcard_context_and_two_strings_a_Decode(s, operation);
666
0
      break;
667
668
0
    case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
669
0
      status = smartcard_context_and_two_strings_w_Decode(s, operation);
670
0
      break;
671
672
0
    case SCARD_IOCTL_LOCATECARDSA:
673
0
      status = smartcard_LocateCardsA_Decode(s, operation);
674
0
      break;
675
676
0
    case SCARD_IOCTL_LOCATECARDSW:
677
0
      status = smartcard_LocateCardsW_Decode(s, operation);
678
0
      break;
679
680
0
    case SCARD_IOCTL_GETSTATUSCHANGEA:
681
0
      status = smartcard_GetStatusChangeA_Decode(s, operation);
682
0
      break;
683
684
0
    case SCARD_IOCTL_GETSTATUSCHANGEW:
685
0
      status = smartcard_GetStatusChangeW_Decode(s, operation);
686
0
      break;
687
688
0
    case SCARD_IOCTL_CANCEL:
689
0
      status = smartcard_Cancel_Decode(s, operation);
690
0
      break;
691
692
0
    case SCARD_IOCTL_CONNECTA:
693
0
      status = smartcard_ConnectA_Decode(s, operation);
694
0
      break;
695
696
0
    case SCARD_IOCTL_CONNECTW:
697
0
      status = smartcard_ConnectW_Decode(s, operation);
698
0
      break;
699
700
0
    case SCARD_IOCTL_RECONNECT:
701
0
      status = smartcard_Reconnect_Decode(s, operation);
702
0
      break;
703
704
0
    case SCARD_IOCTL_DISCONNECT:
705
0
      status = smartcard_Disconnect_Decode(s, operation);
706
0
      break;
707
708
0
    case SCARD_IOCTL_BEGINTRANSACTION:
709
0
      status = smartcard_BeginTransaction_Decode(s, operation);
710
0
      break;
711
712
0
    case SCARD_IOCTL_ENDTRANSACTION:
713
0
      status = smartcard_EndTransaction_Decode(s, operation);
714
0
      break;
715
716
0
    case SCARD_IOCTL_STATE:
717
0
      status = smartcard_State_Decode(s, operation);
718
0
      break;
719
720
0
    case SCARD_IOCTL_STATUSA:
721
0
      status = smartcard_StatusA_Decode(s, operation);
722
0
      break;
723
724
0
    case SCARD_IOCTL_STATUSW:
725
0
      status = smartcard_StatusW_Decode(s, operation);
726
0
      break;
727
728
0
    case SCARD_IOCTL_TRANSMIT:
729
0
      status = smartcard_Transmit_Decode(s, operation);
730
0
      break;
731
732
0
    case SCARD_IOCTL_CONTROL:
733
0
      status = smartcard_Control_Decode(s, operation);
734
0
      break;
735
736
0
    case SCARD_IOCTL_GETATTRIB:
737
0
      status = smartcard_GetAttrib_Decode(s, operation);
738
0
      break;
739
740
0
    case SCARD_IOCTL_SETATTRIB:
741
0
      status = smartcard_SetAttrib_Decode(s, operation);
742
0
      break;
743
744
0
    case SCARD_IOCTL_ACCESSSTARTEDEVENT:
745
0
      status = smartcard_AccessStartedEvent_Decode(s, operation);
746
0
      break;
747
748
0
    case SCARD_IOCTL_LOCATECARDSBYATRA:
749
0
      status = smartcard_LocateCardsByATRA_Decode(s, operation);
750
0
      break;
751
752
0
    case SCARD_IOCTL_LOCATECARDSBYATRW:
753
0
      status = smartcard_LocateCardsByATRW_Decode(s, operation);
754
0
      break;
755
756
0
    case SCARD_IOCTL_READCACHEA:
757
0
      status = smartcard_ReadCacheA_Decode(s, operation);
758
0
      break;
759
760
0
    case SCARD_IOCTL_READCACHEW:
761
0
      status = smartcard_ReadCacheW_Decode(s, operation);
762
0
      break;
763
764
0
    case SCARD_IOCTL_WRITECACHEA:
765
0
      status = smartcard_WriteCacheA_Decode(s, operation);
766
0
      break;
767
768
0
    case SCARD_IOCTL_WRITECACHEW:
769
0
      status = smartcard_WriteCacheW_Decode(s, operation);
770
0
      break;
771
772
0
    case SCARD_IOCTL_GETTRANSMITCOUNT:
773
0
      status = smartcard_GetTransmitCount_Decode(s, operation);
774
0
      break;
775
776
0
    case SCARD_IOCTL_RELEASETARTEDEVENT:
777
0
      status = smartcard_ReleaseStartedEvent_Decode(s, operation);
778
0
      break;
779
780
0
    case SCARD_IOCTL_GETREADERICON:
781
0
      status = smartcard_GetReaderIcon_Decode(s, operation);
782
0
      break;
783
784
0
    case SCARD_IOCTL_GETDEVICETYPEID:
785
0
      status = smartcard_GetDeviceTypeId_Decode(s, operation);
786
0
      break;
787
788
0
    default:
789
0
      status = SCARD_F_INTERNAL_ERROR;
790
0
      break;
791
0
  }
792
793
0
  smartcard_call_to_operation_handle(operation);
794
795
0
  if ((ioControlCode != SCARD_IOCTL_ACCESSSTARTEDEVENT) &&
796
0
      (ioControlCode != SCARD_IOCTL_RELEASETARTEDEVENT))
797
0
  {
798
0
    offset = (RDPDR_DEVICE_IO_REQUEST_LENGTH + RDPDR_DEVICE_IO_CONTROL_REQ_HDR_LENGTH);
799
0
    smartcard_unpack_read_size_align(s, Stream_GetPosition(s) - offset, 8);
800
0
  }
801
802
0
  if (Stream_GetPosition(s) < Stream_Length(s))
803
0
  {
804
0
    SIZE_T difference = 0;
805
0
    difference = Stream_Length(s) - Stream_GetPosition(s);
806
0
    WLog_WARN(TAG,
807
0
              "IRP was not fully parsed %s (%s [0x%08" PRIX32 "]): Actual: %" PRIuz
808
0
              ", Expected: %" PRIuz ", Difference: %" PRIuz "",
809
0
              scard_get_ioctl_string(ioControlCode, TRUE),
810
0
              scard_get_ioctl_string(ioControlCode, FALSE), ioControlCode,
811
0
              Stream_GetPosition(s), Stream_Length(s), difference);
812
0
    winpr_HexDump(TAG, WLOG_WARN, Stream_ConstPointer(s), difference);
813
0
  }
814
815
0
  if (Stream_GetPosition(s) > Stream_Length(s))
816
0
  {
817
0
    SIZE_T difference = 0;
818
0
    difference = Stream_GetPosition(s) - Stream_Length(s);
819
0
    WLog_WARN(TAG,
820
0
              "IRP was parsed beyond its end %s (0x%08" PRIX32 "): Actual: %" PRIuz
821
0
              ", Expected: %" PRIuz ", Difference: %" PRIuz "",
822
0
              scard_get_ioctl_string(ioControlCode, TRUE), ioControlCode, Stream_GetPosition(s),
823
0
              Stream_Length(s), difference);
824
0
  }
825
826
0
  return status;
827
0
}
828
829
static void free_reader_states_a(LPSCARD_READERSTATEA rgReaderStates, UINT32 cReaders)
830
0
{
831
0
  for (UINT32 x = 0; x < cReaders; x++)
832
0
  {
833
0
    SCARD_READERSTATEA* state = &rgReaderStates[x];
834
0
    free(state->szReader);
835
0
  }
836
837
0
  free(rgReaderStates);
838
0
}
839
840
static void free_reader_states_w(LPSCARD_READERSTATEW rgReaderStates, UINT32 cReaders)
841
0
{
842
0
  for (UINT32 x = 0; x < cReaders; x++)
843
0
  {
844
0
    SCARD_READERSTATEW* state = &rgReaderStates[x];
845
0
    free(state->szReader);
846
0
  }
847
848
0
  free(rgReaderStates);
849
0
}
850
851
void smartcard_operation_free(SMARTCARD_OPERATION* op, BOOL allocated)
852
0
{
853
0
  if (!op)
854
0
    return;
855
0
  switch (op->ioControlCode)
856
0
  {
857
0
    case SCARD_IOCTL_CANCEL:
858
0
    case SCARD_IOCTL_ACCESSSTARTEDEVENT:
859
0
    case SCARD_IOCTL_RELEASETARTEDEVENT:
860
0
    case SCARD_IOCTL_LISTREADERGROUPSA:
861
0
    case SCARD_IOCTL_LISTREADERGROUPSW:
862
0
    case SCARD_IOCTL_RECONNECT:
863
0
    case SCARD_IOCTL_DISCONNECT:
864
0
    case SCARD_IOCTL_BEGINTRANSACTION:
865
0
    case SCARD_IOCTL_ENDTRANSACTION:
866
0
    case SCARD_IOCTL_STATE:
867
0
    case SCARD_IOCTL_STATUSA:
868
0
    case SCARD_IOCTL_STATUSW:
869
0
    case SCARD_IOCTL_ESTABLISHCONTEXT:
870
0
    case SCARD_IOCTL_RELEASECONTEXT:
871
0
    case SCARD_IOCTL_ISVALIDCONTEXT:
872
0
    case SCARD_IOCTL_GETATTRIB:
873
0
    case SCARD_IOCTL_GETTRANSMITCOUNT:
874
0
      break;
875
876
0
    case SCARD_IOCTL_LOCATECARDSA:
877
0
    {
878
0
      LocateCardsA_Call* call = &op->call.locateCardsA;
879
0
      free(call->mszCards);
880
881
0
      free_reader_states_a(call->rgReaderStates, call->cReaders);
882
0
    }
883
0
    break;
884
0
    case SCARD_IOCTL_LOCATECARDSW:
885
0
    {
886
0
      LocateCardsW_Call* call = &op->call.locateCardsW;
887
0
      free(call->mszCards);
888
889
0
      free_reader_states_w(call->rgReaderStates, call->cReaders);
890
0
    }
891
0
    break;
892
893
0
    case SCARD_IOCTL_LOCATECARDSBYATRA:
894
0
    {
895
0
      LocateCardsByATRA_Call* call = &op->call.locateCardsByATRA;
896
897
0
      free_reader_states_a(call->rgReaderStates, call->cReaders);
898
0
    }
899
0
    break;
900
0
    case SCARD_IOCTL_LOCATECARDSBYATRW:
901
0
    {
902
0
      LocateCardsByATRW_Call* call = &op->call.locateCardsByATRW;
903
0
      free_reader_states_w(call->rgReaderStates, call->cReaders);
904
0
    }
905
0
    break;
906
0
    case SCARD_IOCTL_FORGETREADERA:
907
0
    case SCARD_IOCTL_INTRODUCEREADERGROUPA:
908
0
    case SCARD_IOCTL_FORGETREADERGROUPA:
909
0
    {
910
0
      ContextAndStringA_Call* call = &op->call.contextAndStringA;
911
0
      free(call->sz);
912
0
    }
913
0
    break;
914
915
0
    case SCARD_IOCTL_FORGETREADERW:
916
0
    case SCARD_IOCTL_INTRODUCEREADERGROUPW:
917
0
    case SCARD_IOCTL_FORGETREADERGROUPW:
918
0
    {
919
0
      ContextAndStringW_Call* call = &op->call.contextAndStringW;
920
0
      free(call->sz);
921
0
    }
922
0
    break;
923
924
0
    case SCARD_IOCTL_INTRODUCEREADERA:
925
0
    case SCARD_IOCTL_REMOVEREADERFROMGROUPA:
926
0
    case SCARD_IOCTL_ADDREADERTOGROUPA:
927
928
0
    {
929
0
      ContextAndTwoStringA_Call* call = &op->call.contextAndTwoStringA;
930
0
      free(call->sz1);
931
0
      free(call->sz2);
932
0
    }
933
0
    break;
934
935
0
    case SCARD_IOCTL_INTRODUCEREADERW:
936
0
    case SCARD_IOCTL_REMOVEREADERFROMGROUPW:
937
0
    case SCARD_IOCTL_ADDREADERTOGROUPW:
938
939
0
    {
940
0
      ContextAndTwoStringW_Call* call = &op->call.contextAndTwoStringW;
941
0
      free(call->sz1);
942
0
      free(call->sz2);
943
0
    }
944
0
    break;
945
946
0
    case SCARD_IOCTL_LISTREADERSA:
947
0
    case SCARD_IOCTL_LISTREADERSW:
948
0
    {
949
0
      ListReaders_Call* call = &op->call.listReaders;
950
0
      free(call->mszGroups);
951
0
    }
952
0
    break;
953
0
    case SCARD_IOCTL_GETSTATUSCHANGEA:
954
0
    {
955
0
      GetStatusChangeA_Call* call = &op->call.getStatusChangeA;
956
0
      free_reader_states_a(call->rgReaderStates, call->cReaders);
957
0
    }
958
0
    break;
959
960
0
    case SCARD_IOCTL_GETSTATUSCHANGEW:
961
0
    {
962
0
      GetStatusChangeW_Call* call = &op->call.getStatusChangeW;
963
0
      free_reader_states_w(call->rgReaderStates, call->cReaders);
964
0
    }
965
0
    break;
966
0
    case SCARD_IOCTL_GETREADERICON:
967
0
    {
968
0
      GetReaderIcon_Call* call = &op->call.getReaderIcon;
969
0
      free(call->szReaderName);
970
0
    }
971
0
    break;
972
0
    case SCARD_IOCTL_GETDEVICETYPEID:
973
0
    {
974
0
      GetDeviceTypeId_Call* call = &op->call.getDeviceTypeId;
975
0
      free(call->szReaderName);
976
0
    }
977
0
    break;
978
0
    case SCARD_IOCTL_CONNECTA:
979
0
    {
980
0
      ConnectA_Call* call = &op->call.connectA;
981
0
      free(call->szReader);
982
0
    }
983
0
    break;
984
0
    case SCARD_IOCTL_CONNECTW:
985
0
    {
986
0
      ConnectW_Call* call = &op->call.connectW;
987
0
      free(call->szReader);
988
0
    }
989
0
    break;
990
0
    case SCARD_IOCTL_SETATTRIB:
991
0
      free(op->call.setAttrib.pbAttr);
992
0
      break;
993
0
    case SCARD_IOCTL_TRANSMIT:
994
0
    {
995
0
      Transmit_Call* call = &op->call.transmit;
996
0
      free(call->pbSendBuffer);
997
0
      free(call->pioSendPci);
998
0
      free(call->pioRecvPci);
999
0
    }
1000
0
    break;
1001
0
    case SCARD_IOCTL_CONTROL:
1002
0
    {
1003
0
      Control_Call* call = &op->call.control;
1004
0
      free(call->pvInBuffer);
1005
0
    }
1006
0
    break;
1007
0
    case SCARD_IOCTL_READCACHEA:
1008
0
    {
1009
0
      ReadCacheA_Call* call = &op->call.readCacheA;
1010
0
      free(call->szLookupName);
1011
0
      free(call->Common.CardIdentifier);
1012
0
    }
1013
0
    break;
1014
0
    case SCARD_IOCTL_READCACHEW:
1015
0
    {
1016
0
      ReadCacheW_Call* call = &op->call.readCacheW;
1017
0
      free(call->szLookupName);
1018
0
      free(call->Common.CardIdentifier);
1019
0
    }
1020
0
    break;
1021
0
    case SCARD_IOCTL_WRITECACHEA:
1022
0
    {
1023
0
      WriteCacheA_Call* call = &op->call.writeCacheA;
1024
0
      free(call->szLookupName);
1025
0
      free(call->Common.CardIdentifier);
1026
0
      free(call->Common.pbData);
1027
0
    }
1028
0
    break;
1029
0
    case SCARD_IOCTL_WRITECACHEW:
1030
0
    {
1031
0
      WriteCacheW_Call* call = &op->call.writeCacheW;
1032
0
      free(call->szLookupName);
1033
0
      free(call->Common.CardIdentifier);
1034
0
      free(call->Common.pbData);
1035
0
    }
1036
0
    break;
1037
0
    default:
1038
0
      break;
1039
0
  }
1040
1041
0
  {
1042
0
    SMARTCARD_OPERATION empty = { 0 };
1043
0
    *op = empty;
1044
0
  }
1045
1046
0
  if (allocated)
1047
0
    free(op);
1048
0
}