|
Lines 23-31
Link Here
|
| 23 |
import os |
23 |
import os |
| 24 |
import signal |
24 |
import signal |
| 25 |
import time |
25 |
import time |
| 26 |
from Queue import Queue |
|
|
| 27 |
from threading import Thread |
26 |
from threading import Thread |
| 28 |
from operator import attrgetter |
27 |
from operator import attrgetter |
|
|
28 |
try: |
| 29 |
from Queue import Queue |
| 30 |
except ImportError: |
| 31 |
from queue import Queue |
| 29 |
|
32 |
|
| 30 |
|
33 |
|
| 31 |
def hexdump(data_buffer, width=16): |
34 |
def hexdump(data_buffer, width=16): |
|
Lines 93-101
class PCSCspy(object):
Link Here
|
| 93 |
delta_sec -= 1 |
96 |
delta_sec -= 1 |
| 94 |
delta_usec += 1000000 |
97 |
delta_usec += 1000000 |
| 95 |
if self.diffable: |
98 |
if self.diffable: |
| 96 |
time = " [??.??]" |
99 |
t = " [??.??]" |
| 97 |
else: |
100 |
else: |
| 98 |
time = " [%d.%09d]" % (delta_sec, delta_usec) |
101 |
t = " [%d.%09d]" % (delta_sec, delta_usec) |
| 99 |
self.execution_time = delta_sec + delta_usec / 1000000. |
102 |
self.execution_time = delta_sec + delta_usec / 1000000. |
| 100 |
|
103 |
|
| 101 |
rvs = { |
104 |
rvs = { |
|
Lines 164-190
class PCSCspy(object):
Link Here
|
| 164 |
data = " => " + code + " (" + rv_text + " [" + rv + "]) " |
167 |
data = " => " + code + " (" + rv_text + " [" + rv + "]) " |
| 165 |
if "0x00000000" != rv: |
168 |
if "0x00000000" != rv: |
| 166 |
if self.color: |
169 |
if self.color: |
| 167 |
print self.indent + PCSCspy.color_red + data + PCSCspy.color_normal + time |
170 |
print(self.indent + PCSCspy.color_red + data + PCSCspy.color_normal + t) |
| 168 |
else: |
171 |
else: |
| 169 |
print self.indent + data + time |
172 |
print(self.indent + data + t) |
| 170 |
else: |
173 |
else: |
| 171 |
print self.indent + data + time |
174 |
print(self.indent + data + t) |
| 172 |
|
175 |
|
| 173 |
return rv_text |
176 |
return rv_text |
| 174 |
|
177 |
|
| 175 |
def log_in(self, line): |
178 |
def log_in(self, line): |
| 176 |
""" generic log for IN line """ |
179 |
""" generic log for IN line """ |
| 177 |
if self.color: |
180 |
if self.color: |
| 178 |
print self.indent + PCSCspy.color_green + " i " + line + PCSCspy.color_normal |
181 |
print(self.indent + PCSCspy.color_green + " i " + line + PCSCspy.color_normal) |
| 179 |
else: |
182 |
else: |
| 180 |
print self.indent + " i " + line |
183 |
print(self.indent + " i " + line) |
| 181 |
|
184 |
|
| 182 |
def log_out(self, line): |
185 |
def log_out(self, line): |
| 183 |
""" generic log for OUT line """ |
186 |
""" generic log for OUT line """ |
| 184 |
if self.color: |
187 |
if self.color: |
| 185 |
print self.indent + PCSCspy.color_magenta + " o " + line + PCSCspy.color_normal |
188 |
print(self.indent + PCSCspy.color_magenta + " o " + line + PCSCspy.color_normal) |
| 186 |
else: |
189 |
else: |
| 187 |
print self.indent + " o " + line |
190 |
print(self.indent + " o " + line) |
| 188 |
|
191 |
|
| 189 |
def log_in_multi(self, lines, padding=""): |
192 |
def log_in_multi(self, lines, padding=""): |
| 190 |
""" generic log for IN lines """ |
193 |
""" generic log for IN lines """ |
|
Lines 386-394
class PCSCspy(object):
Link Here
|
| 386 |
def log_name(self, name): |
389 |
def log_name(self, name): |
| 387 |
""" log function name """ |
390 |
""" log function name """ |
| 388 |
if self.color: |
391 |
if self.color: |
| 389 |
print self.indent + PCSCspy.color_blue + name + PCSCspy.color_normal |
392 |
print(self.indent + PCSCspy.color_blue + name + PCSCspy.color_normal) |
| 390 |
else: |
393 |
else: |
| 391 |
print self.indent + name |
394 |
print(self.indent + name) |
| 392 |
|
395 |
|
| 393 |
def _log_readers(self, readers, direction): |
396 |
def _log_readers(self, readers, direction): |
| 394 |
""" log SCARD_READERSTATE structure """ |
397 |
""" log SCARD_READERSTATE structure """ |
|
Lines 522-528
class PCSCspy(object):
Link Here
|
| 522 |
return [int(x, 16) for x in data.split(" ")] |
525 |
return [int(x, 16) for x in data.split(" ")] |
| 523 |
|
526 |
|
| 524 |
if dwControlCode == self.CM_IOCTL_GET_FEATURE_REQUEST: |
527 |
if dwControlCode == self.CM_IOCTL_GET_FEATURE_REQUEST: |
| 525 |
print " parsing CM_IOCTL_GET_FEATURE_REQUEST results:" |
528 |
print(" parsing CM_IOCTL_GET_FEATURE_REQUEST results:") |
| 526 |
bRecvLength = int(bRecvLength, 16) |
529 |
bRecvLength = int(bRecvLength, 16) |
| 527 |
|
530 |
|
| 528 |
bRecvBuffer = hex2int(bRecvBuffer, bRecvLength) |
531 |
bRecvBuffer = hex2int(bRecvBuffer, bRecvLength) |
|
Lines 540-552
class PCSCspy(object):
Link Here
|
| 540 |
except KeyError: |
543 |
except KeyError: |
| 541 |
self.ControlCodes[value_int] = "UNKNOWN" |
544 |
self.ControlCodes[value_int] = "UNKNOWN" |
| 542 |
|
545 |
|
| 543 |
print " Tag %s is 0x%X" % (self.ControlCodes[value_int], |
546 |
print(" Tag %s is 0x%X" % (self.ControlCodes[value_int], |
| 544 |
value_int) |
547 |
value_int)) |
| 545 |
|
548 |
|
| 546 |
bRecvBuffer = bRecvBuffer[2 + length:] |
549 |
bRecvBuffer = bRecvBuffer[2 + length:] |
| 547 |
|
550 |
|
| 548 |
elif dwControlCode == self.FEATURE_GET_TLV_PROPERTIES: |
551 |
elif dwControlCode == self.FEATURE_GET_TLV_PROPERTIES: |
| 549 |
print " parsing FEATURE_GET_TLV_PROPERTIES results:" |
552 |
print(" parsing FEATURE_GET_TLV_PROPERTIES results:") |
| 550 |
bRecvLength = int(bRecvLength, 16) |
553 |
bRecvLength = int(bRecvLength, 16) |
| 551 |
|
554 |
|
| 552 |
bRecvBuffer = hex2int(bRecvBuffer, bRecvLength) |
555 |
bRecvBuffer = hex2int(bRecvBuffer, bRecvLength) |
|
Lines 573-618
class PCSCspy(object):
Link Here
|
| 573 |
except KeyError: |
576 |
except KeyError: |
| 574 |
tag_text = "UNKNOWN" |
577 |
tag_text = "UNKNOWN" |
| 575 |
|
578 |
|
| 576 |
print " Tag:", tag_text |
579 |
print(" Tag:", tag_text) |
| 577 |
print " Length: ", length |
580 |
print(" Length: ", length) |
| 578 |
print " Value:", value |
581 |
print(" Value:", value) |
| 579 |
|
582 |
|
| 580 |
bRecvBuffer = bRecvBuffer[2 + length:] |
583 |
bRecvBuffer = bRecvBuffer[2 + length:] |
| 581 |
|
584 |
|
| 582 |
elif dwControlCode == self.FEATURE_IFD_PIN_PROPERTIES: |
585 |
elif dwControlCode == self.FEATURE_IFD_PIN_PROPERTIES: |
| 583 |
print " parsing FEATURE_IFD_PIN_PROPERTIES results:" |
586 |
print(" parsing FEATURE_IFD_PIN_PROPERTIES results:") |
| 584 |
bRecvBuffer = hex2int(bRecvBuffer, int(bRecvLength, 16)) |
587 |
bRecvBuffer = hex2int(bRecvBuffer, int(bRecvLength, 16)) |
| 585 |
|
588 |
|
| 586 |
print " wLcdLayout:", bRecvBuffer[0], bRecvBuffer[1] |
589 |
print(" wLcdLayout:", bRecvBuffer[0], bRecvBuffer[1]) |
| 587 |
print " bEntryValidationCondition:", bRecvBuffer[2] |
590 |
print(" bEntryValidationCondition:", bRecvBuffer[2]) |
| 588 |
print " bTimeOut2:", bRecvBuffer[3] |
591 |
print(" bTimeOut2:", bRecvBuffer[3]) |
| 589 |
|
592 |
|
| 590 |
elif dwControlCode == self.FEATURE_VERIFY_PIN_DIRECT: |
593 |
elif dwControlCode == self.FEATURE_VERIFY_PIN_DIRECT: |
| 591 |
print " parsing FEATURE_VERIFY_PIN_DIRECT:" |
594 |
print(" parsing FEATURE_VERIFY_PIN_DIRECT:") |
| 592 |
bSendBuffer = hex2int(bSendBuffer, int(bSendLength, 16)) |
595 |
bSendBuffer = hex2int(bSendBuffer, int(bSendLength, 16)) |
| 593 |
|
596 |
|
| 594 |
print " bTimerOut:", bSendBuffer[0] |
597 |
print(" bTimerOut:", bSendBuffer[0]) |
| 595 |
print " bTimerOut2:", bSendBuffer[1] |
598 |
print(" bTimerOut2:", bSendBuffer[1]) |
| 596 |
print " bmFormatString:", bSendBuffer[2] |
599 |
print(" bmFormatString:", bSendBuffer[2]) |
| 597 |
print " bmPINBlockString:", bSendBuffer[3] |
600 |
print(" bmPINBlockString:", bSendBuffer[3]) |
| 598 |
print " bmPINLengthFormat:", bSendBuffer[4] |
601 |
print(" bmPINLengthFormat:", bSendBuffer[4]) |
| 599 |
print " wPINMaxExtraDigit: 0x%02X%02X" % (bSendBuffer[6], |
602 |
print(" wPINMaxExtraDigit: 0x%02X%02X" % (bSendBuffer[6], |
| 600 |
bSendBuffer[5]) |
603 |
bSendBuffer[5])) |
| 601 |
print " Min:", bSendBuffer[6] |
604 |
print(" Min:", bSendBuffer[6]) |
| 602 |
print " Max:", bSendBuffer[5] |
605 |
print(" Max:", bSendBuffer[5]) |
| 603 |
print " bEntryValidationCondition:", bSendBuffer[7] |
606 |
print(" bEntryValidationCondition:", bSendBuffer[7]) |
| 604 |
print " bNumberMessage:", bSendBuffer[8] |
607 |
print(" bNumberMessage:", bSendBuffer[8]) |
| 605 |
print " wLangId: 0x%02X%02X" % (bSendBuffer[10], bSendBuffer[9]) |
608 |
print(" wLangId: 0x%02X%02X" % (bSendBuffer[10], bSendBuffer[9])) |
| 606 |
print " bMsgIndex:", bSendBuffer[11] |
609 |
print(" bMsgIndex:", bSendBuffer[11]) |
| 607 |
print " bTeoPrologue:", bSendBuffer[12], bSendBuffer[13], \ |
610 |
print(" bTeoPrologue:", bSendBuffer[12], bSendBuffer[13], \ |
| 608 |
bSendBuffer[14] |
611 |
bSendBuffer[14]) |
| 609 |
print " ulDataLength:", bSendBuffer[15] + \ |
612 |
print(" ulDataLength:", bSendBuffer[15] + \ |
| 610 |
bSendBuffer[16] * 256 + bSendBuffer[17] * 2 ** 16 + \ |
613 |
bSendBuffer[16] * 256 + bSendBuffer[17] * 2 ** 16 + \ |
| 611 |
bSendBuffer[18] * 2 ** 24 |
614 |
bSendBuffer[18] * 2 ** 24) |
| 612 |
print " APDU:" |
615 |
print(" APDU:") |
| 613 |
result = hexdump(bSendBuffer[19:]) |
616 |
result = hexdump(bSendBuffer[19:]) |
| 614 |
for line in result: |
617 |
for line in result: |
| 615 |
print " ", line |
618 |
print(" ", line) |
| 616 |
|
619 |
|
| 617 |
def _SCardGetAttrib(self): |
620 |
def _SCardGetAttrib(self): |
| 618 |
""" SCardGetAttrib """ |
621 |
""" SCardGetAttrib """ |
|
Lines 733-739
class PCSCspy(object):
Link Here
|
| 733 |
if line == 'EXIT': |
736 |
if line == 'EXIT': |
| 734 |
return |
737 |
return |
| 735 |
else: |
738 |
else: |
| 736 |
print "Garbage: ", line |
739 |
print("Garbage: ", line) |
| 737 |
else: |
740 |
else: |
| 738 |
# dispatch |
741 |
# dispatch |
| 739 |
(direction, sec, usec, fct) = line.strip().split('|') |
742 |
(direction, sec, usec, fct) = line.strip().split('|') |
|
Lines 776-782
class PCSCspy(object):
Link Here
|
| 776 |
elif fct == 'SCardCancel': |
779 |
elif fct == 'SCardCancel': |
| 777 |
self._SCardCancel() |
780 |
self._SCardCancel() |
| 778 |
else: |
781 |
else: |
| 779 |
print "Unknown function:", fct |
782 |
print("Unknown function:", fct) |
| 780 |
|
783 |
|
| 781 |
try: |
784 |
try: |
| 782 |
record = self.stats[fct] |
785 |
record = self.stats[fct] |
|
Lines 799-805
class PCSCdemultiplexer(object):
Link Here
|
| 799 |
try: |
802 |
try: |
| 800 |
os.mkfifo(logfile) |
803 |
os.mkfifo(logfile) |
| 801 |
except (OSError): |
804 |
except (OSError): |
| 802 |
print "fifo %s already present. Reusing it." % logfile |
805 |
print("fifo %s already present. Reusing it." % logfile) |
| 803 |
|
806 |
|
| 804 |
self.sec = self.usec = 0 |
807 |
self.sec = self.usec = 0 |
| 805 |
|
808 |
|
|
Lines 835-843
class PCSCdemultiplexer(object):
Link Here
|
| 835 |
res = tail.strip().split('|') |
838 |
res = tail.strip().split('|') |
| 836 |
# check the first line format |
839 |
# check the first line format |
| 837 |
if res[0] != ">": |
840 |
if res[0] != ">": |
| 838 |
print "Wrong format!" |
841 |
print("Wrong format!") |
| 839 |
print "First line Should start with a '>' but got:" |
842 |
print("First line Should start with a '>' but got:") |
| 840 |
print tail |
843 |
print(tail) |
| 841 |
return |
844 |
return |
| 842 |
(direction, sec, usec, fct) = res |
845 |
(direction, sec, usec, fct) = res |
| 843 |
|
846 |
|
|
Lines 893-905
class PCSCdemultiplexer(object):
Link Here
|
| 893 |
|
896 |
|
| 894 |
# display statistics sorted by total_time |
897 |
# display statistics sorted by total_time |
| 895 |
print |
898 |
print |
| 896 |
print "Results sorted by total execution time" |
899 |
print("Results sorted by total execution time") |
| 897 |
print "total time: %f sec" % total_time |
900 |
print("total time: %f sec" % total_time) |
| 898 |
for record in sorted(records, key=attrgetter('total_time'), |
901 |
for record in sorted(records, key=attrgetter('total_time'), |
| 899 |
reverse=True): |
902 |
reverse=True): |
| 900 |
print "%f sec (%3d calls) %5.2f%% %s" % (record.total_time, |
903 |
print("%f sec (%3d calls) %5.2f%% %s" % (record.total_time, |
| 901 |
record.occurences, record.total_time / total_time * 100., |
904 |
record.occurences, record.total_time / total_time * 100., |
| 902 |
record.name) |
905 |
record.name)) |
| 903 |
|
906 |
|
| 904 |
|
907 |
|
| 905 |
def main(logfile=None, color=True, diffable=False): |
908 |
def main(logfile=None, color=True, diffable=False): |
|
Lines 909-920
def main(logfile=None, color=True, diffa
Link Here
|
| 909 |
|
912 |
|
| 910 |
|
913 |
|
| 911 |
def signal_handler(sig, frame): |
914 |
def signal_handler(sig, frame): |
| 912 |
print 'Ctrl-C, exiting.' |
915 |
print('Ctrl-C, exiting.') |
| 913 |
os.kill(os.getpid(), signal.SIGQUIT) |
916 |
os.kill(os.getpid(), signal.SIGQUIT) |
| 914 |
|
917 |
|
| 915 |
|
918 |
|
| 916 |
def print_usage(): |
919 |
def print_usage(): |
| 917 |
print "Usage: pcsc-spy [-n|--nocolor] [-d|--diffable] [-h|--help] [-v|--version]" |
920 |
print("Usage: pcsc-spy [-n|--nocolor] [-d|--diffable] [-h|--help] [-v|--version]") |
| 918 |
|
921 |
|
| 919 |
if __name__ == "__main__": |
922 |
if __name__ == "__main__": |
| 920 |
import sys |
923 |
import sys |
|
Lines 939-946
if __name__ == "__main__":
Link Here
|
| 939 |
print_usage() |
942 |
print_usage() |
| 940 |
sys.exit(1) |
943 |
sys.exit(1) |
| 941 |
if o == "-v" or o == "--version": |
944 |
if o == "-v" or o == "--version": |
| 942 |
print "pcsc-spy version 1.0" |
945 |
print("pcsc-spy version 1.0") |
| 943 |
print "Copyright (c) 2011-2012, Ludovic Rousseau <ludovic.rousseau@free.fr>" |
946 |
print("Copyright (c) 2011-2012, Ludovic Rousseau <ludovic.rousseau@free.fr>") |
| 944 |
print |
947 |
print |
| 945 |
sys.exit(1) |
948 |
sys.exit(1) |
| 946 |
|
949 |
|