mirror of
https://gitea.osmocom.org/sim-card/pysim.git
synced 2026-03-18 19:38:34 +03:00
Compare commits
4 Commits
master
...
pmaier/fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5f56dd35f | ||
|
|
c3edcf7294 | ||
|
|
858c9eb421 | ||
|
|
a48b9e565a |
@@ -285,10 +285,7 @@ if __name__ == '__main__':
|
|||||||
option_parser.add_argument("--admin", action='store_true', help="perform action as admin", default=False)
|
option_parser.add_argument("--admin", action='store_true', help="perform action as admin", default=False)
|
||||||
opts = option_parser.parse_args()
|
opts = option_parser.parse_args()
|
||||||
|
|
||||||
PySimLogger.setup(print, {logging.WARN: "\033[33m"})
|
PySimLogger.setup(print, {logging.WARN: "\033[33m"}, opts.verbose)
|
||||||
if (opts.verbose):
|
|
||||||
PySimLogger.set_verbose(True)
|
|
||||||
PySimLogger.set_level(logging.DEBUG)
|
|
||||||
|
|
||||||
# Open CSV file
|
# Open CSV file
|
||||||
cr = open_csv(opts)
|
cr = open_csv(opts)
|
||||||
|
|||||||
@@ -44,6 +44,11 @@ from pySim.legacy.ts_51_011 import EF
|
|||||||
from pySim.card_handler import *
|
from pySim.card_handler import *
|
||||||
from pySim.utils import *
|
from pySim.utils import *
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
import logging
|
||||||
|
from pySim.log import PySimLogger
|
||||||
|
|
||||||
|
log = PySimLogger.get(Path(__file__).stem)
|
||||||
|
|
||||||
def parse_options():
|
def parse_options():
|
||||||
|
|
||||||
@@ -185,6 +190,7 @@ def parse_options():
|
|||||||
default=False, action="store_true")
|
default=False, action="store_true")
|
||||||
parser.add_argument("--card_handler", dest="card_handler_config", metavar="FILE",
|
parser.add_argument("--card_handler", dest="card_handler_config", metavar="FILE",
|
||||||
help="Use automatic card handling machine")
|
help="Use automatic card handling machine")
|
||||||
|
parser.add_argument("--verbose", help="Enable verbose logging", action='store_true', default=False)
|
||||||
|
|
||||||
options = parser.parse_args()
|
options = parser.parse_args()
|
||||||
|
|
||||||
@@ -770,6 +776,9 @@ if __name__ == '__main__':
|
|||||||
# Parse options
|
# Parse options
|
||||||
opts = parse_options()
|
opts = parse_options()
|
||||||
|
|
||||||
|
# Setup logger
|
||||||
|
PySimLogger.setup(print, {logging.WARN: "\033[33m"}, opts.verbose)
|
||||||
|
|
||||||
# Init card reader driver
|
# Init card reader driver
|
||||||
sl = init_reader(opts)
|
sl = init_reader(opts)
|
||||||
|
|
||||||
|
|||||||
@@ -46,11 +46,17 @@ from pySim.utils import dec_imsi, dec_iccid
|
|||||||
from pySim.legacy.utils import format_xplmn_w_act, dec_st, dec_msisdn
|
from pySim.legacy.utils import format_xplmn_w_act, dec_st, dec_msisdn
|
||||||
from pySim.ts_51_011 import EF_SMSP
|
from pySim.ts_51_011 import EF_SMSP
|
||||||
|
|
||||||
|
from pathlib import Path
|
||||||
|
import logging
|
||||||
|
from pySim.log import PySimLogger
|
||||||
|
|
||||||
|
log = PySimLogger.get(Path(__file__).stem)
|
||||||
|
|
||||||
option_parser = argparse.ArgumentParser(description='Legacy tool for reading some parts of a SIM card',
|
option_parser = argparse.ArgumentParser(description='Legacy tool for reading some parts of a SIM card',
|
||||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||||
|
option_parser.add_argument("--verbose", help="Enable verbose logging", action='store_true', default=False)
|
||||||
argparse_add_reader_args(option_parser)
|
argparse_add_reader_args(option_parser)
|
||||||
|
|
||||||
|
|
||||||
def select_app(adf: str, card: SimCard):
|
def select_app(adf: str, card: SimCard):
|
||||||
"""Select application by its AID"""
|
"""Select application by its AID"""
|
||||||
sw = 0
|
sw = 0
|
||||||
@@ -75,6 +81,9 @@ if __name__ == '__main__':
|
|||||||
# Parse options
|
# Parse options
|
||||||
opts = option_parser.parse_args()
|
opts = option_parser.parse_args()
|
||||||
|
|
||||||
|
# Setup logger
|
||||||
|
PySimLogger.setup(print, {logging.WARN: "\033[33m"}, opts.verbose)
|
||||||
|
|
||||||
# Init card reader driver
|
# Init card reader driver
|
||||||
sl = init_reader(opts)
|
sl = init_reader(opts)
|
||||||
|
|
||||||
|
|||||||
@@ -107,12 +107,12 @@ Online manual available at https://downloads.osmocom.org/docs/pysim/master/html/
|
|||||||
kwargs = {'include_ipy': True}
|
kwargs = {'include_ipy': True}
|
||||||
|
|
||||||
self.verbose = verbose
|
self.verbose = verbose
|
||||||
self._onchange_verbose('verbose', False, self.verbose);
|
PySimLogger.setup(self.poutput, {logging.WARN: YELLOW})
|
||||||
|
self._onchange_verbose('verbose', False, self.verbose)
|
||||||
|
|
||||||
# pylint: disable=unexpected-keyword-arg
|
# pylint: disable=unexpected-keyword-arg
|
||||||
super().__init__(persistent_history_file='~/.pysim_shell_history', allow_cli_args=False,
|
super().__init__(persistent_history_file='~/.pysim_shell_history', allow_cli_args=False,
|
||||||
auto_load_commands=False, startup_script=script, **kwargs)
|
auto_load_commands=False, startup_script=script, **kwargs)
|
||||||
PySimLogger.setup(self.poutput, {logging.WARN: YELLOW})
|
|
||||||
self.intro = style(self.BANNER, fg=RED)
|
self.intro = style(self.BANNER, fg=RED)
|
||||||
self.default_category = 'pySim-shell built-in commands'
|
self.default_category = 'pySim-shell built-in commands'
|
||||||
self.card = None
|
self.card = None
|
||||||
@@ -1175,13 +1175,7 @@ if __name__ == '__main__':
|
|||||||
opts = option_parser.parse_args()
|
opts = option_parser.parse_args()
|
||||||
|
|
||||||
# Ensure that we are able to print formatted warnings from the beginning.
|
# Ensure that we are able to print formatted warnings from the beginning.
|
||||||
PySimLogger.setup(print, {logging.WARN: YELLOW})
|
PySimLogger.setup(print, {logging.WARN: YELLOW}, opts.verbose)
|
||||||
if opts.verbose:
|
|
||||||
PySimLogger.set_verbose(True)
|
|
||||||
PySimLogger.set_level(logging.DEBUG)
|
|
||||||
else:
|
|
||||||
PySimLogger.set_verbose(False)
|
|
||||||
PySimLogger.set_level(logging.INFO)
|
|
||||||
|
|
||||||
# Register csv-file as card data provider, either from specified CSV
|
# Register csv-file as card data provider, either from specified CSV
|
||||||
# or from CSV file in home directory
|
# or from CSV file in home directory
|
||||||
|
|||||||
12
pySim/log.py
12
pySim/log.py
@@ -63,7 +63,7 @@ class PySimLogger:
|
|||||||
raise RuntimeError('static class, do not instantiate')
|
raise RuntimeError('static class, do not instantiate')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def setup(print_callback = None, colors:dict = {}):
|
def setup(print_callback = None, colors:dict = {}, verbose_debug:bool = False):
|
||||||
"""
|
"""
|
||||||
Set a print callback function and color scheme. This function call is optional. In case this method is not
|
Set a print callback function and color scheme. This function call is optional. In case this method is not
|
||||||
called, default settings apply.
|
called, default settings apply.
|
||||||
@@ -72,10 +72,20 @@ class PySimLogger:
|
|||||||
have the following format: print_callback(message:str)
|
have the following format: print_callback(message:str)
|
||||||
colors : An optional dict through which certain log levels can be assigned a color.
|
colors : An optional dict through which certain log levels can be assigned a color.
|
||||||
(e.g. {logging.WARN: YELLOW})
|
(e.g. {logging.WARN: YELLOW})
|
||||||
|
verbose_debug: Enable verbose logging and set the loglevel DEBUG when set to true. Otherwise the
|
||||||
|
non-verbose logging is used and the loglevel is set to INFO. This setting can be changed
|
||||||
|
using the set_verbose and set_level methods at any time.
|
||||||
"""
|
"""
|
||||||
PySimLogger.print_callback = print_callback
|
PySimLogger.print_callback = print_callback
|
||||||
PySimLogger.colors = colors
|
PySimLogger.colors = colors
|
||||||
|
|
||||||
|
if (verbose_debug):
|
||||||
|
PySimLogger.set_verbose(True)
|
||||||
|
PySimLogger.set_level(logging.DEBUG)
|
||||||
|
else:
|
||||||
|
PySimLogger.set_verbose(False)
|
||||||
|
PySimLogger.set_level(logging.INFO)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_verbose(verbose:bool = False):
|
def set_verbose(verbose:bool = False):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -301,24 +301,53 @@ class LinkBaseTpdu(LinkBase):
|
|||||||
|
|
||||||
prev_tpdu = tpdu
|
prev_tpdu = tpdu
|
||||||
data, sw = self.send_tpdu(tpdu)
|
data, sw = self.send_tpdu(tpdu)
|
||||||
|
log.debug("T0: case #%u TPDU: %s => %s %s", case, tpdu, data or "(no data)", sw or "(no status word)")
|
||||||
|
|
||||||
# When we have sent the first APDU, the SW may indicate that there are response bytes
|
# After sending the APDU/TPDU the UICC/eUICC or SIM may response with a status word that indicates that further
|
||||||
# available. There are two SWs commonly used for this 9fxx (sim) and 61xx (usim), where
|
# TPDUs have to be sent in order to complete the task.
|
||||||
# xx is the number of response bytes available.
|
|
||||||
# See also:
|
|
||||||
if sw is not None:
|
if sw is not None:
|
||||||
while (sw[0:2] in ['9f', '61', '62', '63']):
|
if case == 4 or self.apdu_strict == False:
|
||||||
# SW1=9F: 3GPP TS 51.011 9.4.1, Responses to commands which are correctly executed
|
# In case the APDU is a case #4 APDU, the UICC/eUICC/SIM may indicate that there is response data
|
||||||
# SW1=61: ISO/IEC 7816-4, Table 5 — General meaning of the interindustry values of SW1-SW2
|
# available which has to be retrieved using a GET RESPONSE command TPDU.
|
||||||
# SW1=62: ETSI TS 102 221 7.3.1.1.4 Clause 4b): 62xx, 63xx, 9xxx != 9000
|
#
|
||||||
tpdu_gr = tpdu[0:2] + 'c00000' + sw[2:4]
|
# ETSI TS 102 221, section 7.3.1.1.4 is very cleare about the fact that the GET RESPONSE mechanism
|
||||||
prev_tpdu = tpdu_gr
|
# shall only apply on case #4 APDUs but unfortunately it is impossible to distinguish between case #3
|
||||||
d, sw = self.send_tpdu(tpdu_gr)
|
# and case #4 when the APDU format is not strictly followed. In order to be able to detect case #4
|
||||||
data += d
|
# correctly the Le byte (usually 0x00) must be present, is often forgotten. To avoid problems with
|
||||||
|
# legacy scripts that use raw APDU strings, we will still loosely apply GET RESPONSE based on what
|
||||||
|
# the status word indicates. Unless the user explicitly enables the strict mode (set apdu_strict true)
|
||||||
|
while True:
|
||||||
|
if sw in ['9000', '9100']:
|
||||||
|
# A status word of 9000 (or 9100 in case there is pending data from a proactive SIM command)
|
||||||
|
# indicates that either no response data was returnd or all response data has been retrieved
|
||||||
|
# successfully. We may discontinue the processing at this point.
|
||||||
|
break;
|
||||||
|
if sw[0:2] in ['61', '9f']:
|
||||||
|
# A status word of 61xx or 9fxx indicates that there is (still) response data available. We
|
||||||
|
# send a GET RESPONSE command with the length value indicated in the second byte of the status
|
||||||
|
# word. (see also ETSI TS 102 221, section 7.3.1.1.4, clause 4a and 3GPP TS 51.011 9.4.1 and
|
||||||
|
# ISO/IEC 7816-4, Table 5)
|
||||||
|
le_gr = sw[2:4]
|
||||||
|
elif sw[0:2] in ['62', '63']:
|
||||||
|
# There are corner cases (status word is 62xx or 63xx) where the UICC/eUICC/SIM asks us
|
||||||
|
# to send a dummy GET RESPONSE command. We send a GET RESPONSE command with a length of 0.
|
||||||
|
# (see also ETSI TS 102 221, section 7.3.1.1.4, clause 4b and ETSI TS 151 011, section 9.4.1)
|
||||||
|
le_gr = '00'
|
||||||
|
else:
|
||||||
|
# A status word other then the ones covered by the above logic may indicate an error. In this
|
||||||
|
# case we will discontinue the processing as well.
|
||||||
|
# (see also ETSI TS 102 221, section 7.3.1.1.4, clause 4c)
|
||||||
|
break
|
||||||
|
tpdu_gr = tpdu[0:2] + 'c00000' + le_gr
|
||||||
|
prev_tpdu = tpdu_gr
|
||||||
|
data_gr, sw = self.send_tpdu(tpdu_gr)
|
||||||
|
log.debug("T0: GET RESPONSE TPDU: %s => %s %s", tpdu_gr, data_gr or "(no data)", sw or "(no status word)")
|
||||||
|
data += data_gr
|
||||||
if sw[0:2] == '6c':
|
if sw[0:2] == '6c':
|
||||||
# SW1=6C: ETSI TS 102 221 Table 7.1: Procedure byte coding
|
# SW1=6C: ETSI TS 102 221 Table 7.1: Procedure byte coding
|
||||||
tpdu_gr = prev_tpdu[0:8] + sw[2:4]
|
tpdu_gr = prev_tpdu[0:8] + sw[2:4]
|
||||||
data, sw = self.send_tpdu(tpdu_gr)
|
data, sw = self.send_tpdu(tpdu_gr)
|
||||||
|
log.debug("T0: repated case #%u TPDU: %s => %s %s", case, tpdu_gr, data or "(no data)", sw or "(no status word)")
|
||||||
|
|
||||||
return data, sw
|
return data, sw
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Using PC/SC reader interface
|
INFO: Using PC/SC reader interface
|
||||||
Reading ...
|
Reading ...
|
||||||
Autodetected card type: Fairwaves-SIM
|
Autodetected card type: Fairwaves-SIM
|
||||||
ICCID: 8988219000000117833
|
ICCID: 8988219000000117833
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Using PC/SC reader interface
|
INFO: Using PC/SC reader interface
|
||||||
Reading ...
|
Reading ...
|
||||||
Autodetected card type: Wavemobile-SIM
|
Autodetected card type: Wavemobile-SIM
|
||||||
ICCID: 89445310150011013678
|
ICCID: 89445310150011013678
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Using PC/SC reader interface
|
INFO: Using PC/SC reader interface
|
||||||
Reading ...
|
Reading ...
|
||||||
Autodetected card type: fakemagicsim
|
Autodetected card type: fakemagicsim
|
||||||
ICCID: 1122334455667788990
|
ICCID: 1122334455667788990
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Using PC/SC reader interface
|
INFO: Using PC/SC reader interface
|
||||||
Reading ...
|
Reading ...
|
||||||
Autodetected card type: sysmoISIM-SJA2
|
Autodetected card type: sysmoISIM-SJA2
|
||||||
ICCID: 8988211000000467343
|
ICCID: 8988211000000467343
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Using PC/SC reader interface
|
INFO: Using PC/SC reader interface
|
||||||
Reading ...
|
Reading ...
|
||||||
Autodetected card type: sysmoISIM-SJA5
|
Autodetected card type: sysmoISIM-SJA5
|
||||||
ICCID: 8949440000001155314
|
ICCID: 8949440000001155314
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Using PC/SC reader interface
|
INFO: Using PC/SC reader interface
|
||||||
Reading ...
|
Reading ...
|
||||||
Autodetected card type: sysmoUSIM-SJS1
|
Autodetected card type: sysmoUSIM-SJS1
|
||||||
ICCID: 8988211320300000028
|
ICCID: 8988211320300000028
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Using PC/SC reader interface
|
INFO: Using PC/SC reader interface
|
||||||
Reading ...
|
Reading ...
|
||||||
Autodetected card type: sysmosim-gr1
|
Autodetected card type: sysmosim-gr1
|
||||||
ICCID: 2222334455667788990
|
ICCID: 2222334455667788990
|
||||||
|
|||||||
Reference in New Issue
Block a user