2005-09-29 03:39:27 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# -*- coding: iso-8859-1 -*-
|
|
|
|
|
2006-05-04 23:58:28 +00:00
|
|
|
import pycsc, utils, cards, os, re, binascii, sys, exceptions, traceback, getopt
|
2005-10-09 02:06:32 +00:00
|
|
|
from shell import Shell
|
2005-09-30 04:13:34 +00:00
|
|
|
print_backtrace = True
|
2005-09-29 03:39:27 +00:00
|
|
|
|
2005-09-29 15:00:26 +00:00
|
|
|
def cmd_atr(card, *args):
|
2005-10-09 02:06:32 +00:00
|
|
|
"""Print the ATR of the currently inserted card."""
|
2005-09-29 15:00:26 +00:00
|
|
|
print "ATR: %s" % utils.hexdump(card.card.status()['ATR'], short=True)
|
2005-09-29 03:39:27 +00:00
|
|
|
|
2006-05-22 03:26:13 +00:00
|
|
|
def cmd_close(card, *args):
|
|
|
|
"Close the connection to the currently inserted card"
|
|
|
|
shell.unregister_post_hook(_print_sw)
|
|
|
|
shell.fallback = None
|
|
|
|
shell.unregister_pre_hook(_clear_sw)
|
|
|
|
shell.unregister_pre_hook(_update_prompt)
|
|
|
|
shell.unregister_commands(card)
|
|
|
|
shell.unregister_commands(card, COMMANDS)
|
|
|
|
card.close_card()
|
|
|
|
shell.set_prompt("(No card) ")
|
|
|
|
|
2005-09-29 14:41:20 +00:00
|
|
|
COMMANDS = {
|
2006-05-22 03:26:13 +00:00
|
|
|
"atr": cmd_atr,
|
|
|
|
"close_card": cmd_close,
|
2005-09-29 14:41:20 +00:00
|
|
|
}
|
2005-09-29 03:39:27 +00:00
|
|
|
|
2006-05-04 23:58:28 +00:00
|
|
|
def list_readers():
|
|
|
|
for index, name in enumerate(pycsc.listReader()):
|
|
|
|
print "%i: %s" % (index, name)
|
|
|
|
|
|
|
|
|
|
|
|
OPTIONS = "r:l"
|
|
|
|
LONG_OPTIONS = ["reader=", "list-readers"]
|
|
|
|
reader = 0
|
|
|
|
exit_now = False
|
|
|
|
|
2005-09-29 14:41:20 +00:00
|
|
|
if __name__ == "__main__":
|
2005-09-29 03:39:27 +00:00
|
|
|
|
2006-05-04 23:58:28 +00:00
|
|
|
(options, arguments) = getopt.gnu_getopt(sys.argv[1:], OPTIONS, LONG_OPTIONS)
|
|
|
|
|
|
|
|
for (option, value) in options:
|
|
|
|
if option in ("-r","--reader"):
|
|
|
|
if value.isdigit():
|
|
|
|
reader = int(value)
|
|
|
|
else:
|
|
|
|
reader = value
|
|
|
|
if option in ("-l","--list-readers"):
|
|
|
|
list_readers()
|
|
|
|
exit_now = True
|
|
|
|
|
|
|
|
if exit_now:
|
|
|
|
sys.exit()
|
|
|
|
del exit_now
|
|
|
|
|
|
|
|
if isinstance(reader, int):
|
|
|
|
readerName = pycsc.listReader()[reader]
|
|
|
|
else:
|
|
|
|
readerName = reader
|
|
|
|
del reader
|
|
|
|
|
2005-09-29 14:41:20 +00:00
|
|
|
newState = pycsc.getStatusChange(ReaderStates=[{'Reader': readerName, 'CurrentState':pycsc.SCARD_STATE_UNAWARE}])
|
2005-09-29 03:39:27 +00:00
|
|
|
|
2005-09-29 14:41:20 +00:00
|
|
|
print "Cyberflex shell"
|
|
|
|
print "Using reader: %s" % readerName
|
|
|
|
print "Card present: %s" % ((newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT) and "yes" or "no")
|
|
|
|
|
|
|
|
if not newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT:
|
|
|
|
print "Please insert card ..."
|
2005-09-29 03:39:27 +00:00
|
|
|
|
2005-09-29 14:41:20 +00:00
|
|
|
while not newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT \
|
|
|
|
or newState[0]['EventState'] & pycsc.SCARD_STATE_MUTE:
|
|
|
|
|
|
|
|
newState = pycsc.getStatusChange(ReaderStates=[{'Reader': readerName, 'CurrentState':newState[0]['EventState']}])
|
|
|
|
|
|
|
|
if newState[0]['EventState'] & pycsc.SCARD_STATE_MUTE:
|
|
|
|
print "Card is mute, please retry ..."
|
|
|
|
|
|
|
|
print "Card present: %s" % ((newState[0]['EventState'] & pycsc.SCARD_STATE_PRESENT) and "yes" or "no")
|
|
|
|
|
|
|
|
print "ATR: %s" % utils.hexdump(newState[0]['Atr'], short = True)
|
|
|
|
|
2006-05-04 23:58:28 +00:00
|
|
|
pycsc_card = pycsc.pycsc(reader = readerName, protocol = pycsc.SCARD_PROTOCOL_ANY)
|
2005-10-12 02:09:15 +00:00
|
|
|
card = cards.new_card_object(pycsc_card)
|
|
|
|
|
2005-10-09 02:06:32 +00:00
|
|
|
shell = Shell("cyberflex-shell")
|
|
|
|
shell.register_commands(card, COMMANDS)
|
|
|
|
shell.register_commands(card)
|
2005-09-29 14:41:20 +00:00
|
|
|
|
2005-10-09 02:06:32 +00:00
|
|
|
def _update_prompt():
|
|
|
|
shell.set_prompt(card.get_prompt() + " ")
|
|
|
|
shell.register_pre_hook(_update_prompt)
|
2005-09-29 14:41:20 +00:00
|
|
|
|
2005-10-09 02:06:32 +00:00
|
|
|
def _clear_sw():
|
2005-09-29 17:16:27 +00:00
|
|
|
card.sw_changed = False
|
2005-10-09 02:06:32 +00:00
|
|
|
shell.register_pre_hook(_clear_sw)
|
|
|
|
|
|
|
|
apduregex = re.compile(r'^\s*([0-9a-f]{2}\s*){4,}$', re.I)
|
|
|
|
def do_raw_apdu(*args):
|
|
|
|
apdu_string = "".join(args)
|
|
|
|
if not apduregex.match(apdu_string):
|
|
|
|
raise NotImplementedError
|
2005-09-29 17:16:27 +00:00
|
|
|
|
2005-10-09 02:06:32 +00:00
|
|
|
apdu_binary = binascii.a2b_hex("".join(apdu_string.split()))
|
2006-05-18 15:45:07 +00:00
|
|
|
apdu = utils.C_APDU(apdu_binary)
|
2005-10-09 02:06:32 +00:00
|
|
|
response = card.send_apdu(apdu)
|
2006-05-17 18:50:18 +00:00
|
|
|
|
2006-05-18 15:45:07 +00:00
|
|
|
if len(response.data) > 0: ## The SW is already printed by _print_sw as a post_hook
|
|
|
|
print utils.hexdump(response.data)
|
2005-09-29 17:16:27 +00:00
|
|
|
|
2005-10-09 02:06:32 +00:00
|
|
|
shell.fallback = do_raw_apdu
|
|
|
|
|
|
|
|
def _print_sw():
|
2005-09-29 17:16:27 +00:00
|
|
|
if card.sw_changed:
|
2006-05-18 02:16:15 +00:00
|
|
|
print card.decode_statusword()
|
2005-10-09 02:06:32 +00:00
|
|
|
shell.register_post_hook(_print_sw)
|
|
|
|
|
|
|
|
shell.run()
|