laforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/42734?usp=email )
Change subject: card_key_provider: move boiler-plate code into helper functions ......................................................................
card_key_provider: move boiler-plate code into helper functions
in pySim-shell.py we add the commandline options for the card key provider and do the setup accordingly. Let's put this boilerplate code into helper functions instead, so that we can re-use it in other pySim programs as well. Let's use pySim.transport as a pattern.
Related: SYS#6959 Change-Id: I6d095cbb644e608f4a751a1d0749b1484cdc781d --- M pySim-shell.py M pySim/card_key_provider.py 2 files changed, 53 insertions(+), 24 deletions(-)
Approvals: Jenkins Builder: Verified laforge: Looks good to me, approved
diff --git a/pySim-shell.py b/pySim-shell.py index 29ed3a5..66f39fc 100755 --- a/pySim-shell.py +++ b/pySim-shell.py @@ -69,8 +69,8 @@ from pySim.gsm_r import DF_EIRENE from pySim.cat import ProactiveCommand
-from pySim.card_key_provider import CardKeyProviderCsv, CardKeyProviderPgsql -from pySim.card_key_provider import card_key_provider_register, card_key_provider_get_field, card_key_provider_get +from pySim.card_key_provider import card_key_provider_argparse_add_args, card_key_provider_init +from pySim.card_key_provider import card_key_provider_get_field, card_key_provider_get
from pySim.app import init_card
@@ -1146,18 +1146,6 @@ global_group.add_argument("--verbose", help="Enable verbose logging", action='store_true', default=False)
-card_key_group = option_parser.add_argument_group('Card Key Provider Options') -card_key_group.add_argument('--csv', metavar='FILE', - default="~/.osmocom/pysim/card_data.csv", - help='Read card data from CSV file') -card_key_group.add_argument('--pgsql', metavar='FILE', - default="~/.osmocom/pysim/card_data_pgsql.cfg", - help='Read card data from PostgreSQL database (config file)') -card_key_group.add_argument('--csv-column-key', metavar='FIELD:AES_KEY_HEX', default=[], action='append', - help=argparse.SUPPRESS, dest='column_key') -card_key_group.add_argument('--column-key', metavar='FIELD:AES_KEY_HEX', default=[], action='append', - help='per-column AES transport key', dest='column_key') - adm_group = global_group.add_mutually_exclusive_group() adm_group.add_argument('-a', '--pin-adm', metavar='PIN_ADM1', dest='pin_adm', default=None, help='ADM PIN used for provisioning (overwrites default)') @@ -1170,6 +1158,7 @@ help="A pySim-shell command that would optionally be executed at startup") option_parser.add_argument('command_args', nargs=argparse.REMAINDER, help="Optional Arguments for command") +card_key_provider_argparse_add_args(option_parser)
if __name__ == '__main__': startup_errors = False @@ -1178,16 +1167,8 @@ # Ensure that we are able to print formatted warnings from the beginning. PySimLogger.setup(print, {logging.WARN: YELLOW}, opts.verbose)
- # Register csv-file as card data provider, either from specified CSV - # or from CSV file in home directory - column_keys = {} - for par in opts.column_key: - name, key = par.split(':') - column_keys[name] = key - if os.path.isfile(os.path.expanduser(opts.csv)): - card_key_provider_register(CardKeyProviderCsv(os.path.expanduser(opts.csv), column_keys)) - if os.path.isfile(os.path.expanduser(opts.pgsql)): - card_key_provider_register(CardKeyProviderPgsql(os.path.expanduser(opts.pgsql), column_keys)) + # Init card key provider for automatic card key retrieval + card_key_provider_init(opts)
# Init card reader driver sl = init_reader(opts, proactive_handler = Proact()) diff --git a/pySim/card_key_provider.py b/pySim/card_key_provider.py index 06a6b2b..49a2a96 100644 --- a/pySim/card_key_provider.py +++ b/pySim/card_key_provider.py @@ -33,10 +33,12 @@ from osmocom.utils import h2b, b2h from pySim.log import PySimLogger
+import os import abc import csv import logging import yaml +import argparse
log = PySimLogger.get(__name__)
@@ -130,6 +132,14 @@ cipher = AES.new(h2b(self.transport_keys[field_name.upper()]), AES.MODE_CBC, self.__IV) return b2h(cipher.encrypt(h2b(plaintext_val)))
+ @staticmethod + def argparse_add_args(arg_parser: argparse.ArgumentParser): + arg_parser.add_argument('--column-key', metavar='FIELD:AES_KEY_HEX', default=[], action='append', + help='per-column AES transport key', dest='column_key') + # Depprecated argument, replaced by --column-key (see above) + arg_parser.add_argument('--csv-column-key', metavar='FIELD:AES_KEY_HEX', default=[], action='append', + help=argparse.SUPPRESS, dest='column_key') + class CardKeyProvider(abc.ABC): """Base class, not containing any concrete implementation."""
@@ -148,6 +158,15 @@ fond None shall be returned. """
+ @staticmethod + def argparse_add_args(arg_parser: argparse.ArgumentParser): + """ + Add the commandline arguments relevant for this card key provider. + + Args: + arg_parser : argument parser group + """ + def __str__(self): return type(self).__name__
@@ -188,6 +207,12 @@ return None return return_dict
+ @staticmethod + def argparse_add_args(arg_parser: argparse.ArgumentParser): + arg_parser.add_argument('--csv', metavar='FILE', + default="~/.osmocom/pysim/card_data.csv", + help='Read card data from CSV file') + class CardKeyProviderPgsql(CardKeyProvider): """Card key provider implementation that allows to query against a specified PostgreSQL database table."""
@@ -252,6 +277,11 @@ result[k] = self.crypt.decrypt_field(k, result.get(k)) return result
+ @staticmethod + def argparse_add_args(arg_parser: argparse.ArgumentParser): + arg_parser.add_argument('--pgsql', metavar='FILE', + default="~/.osmocom/pysim/card_data_pgsql.cfg", + help='Read card data from PostgreSQL database (config file)')
def card_key_provider_register(provider: CardKeyProvider, provider_list=card_key_providers): """Register a new card key provider. @@ -305,3 +335,21 @@ fields = [field] result = card_key_provider_get(fields, key, value, card_key_providers) return result.get(field.upper()) + +def card_key_provider_argparse_add_args(arg_parser: argparse.ArgumentParser): + """Add card key provider commandline options to the given argument parser""" + card_key_group = arg_parser.add_argument_group('Card Key Provider Options') + CardKeyProviderCsv.argparse_add_args(card_key_group) + CardKeyProviderPgsql.argparse_add_args(card_key_group) + CardKeyFieldCryptor.argparse_add_args(card_key_group) + +def card_key_provider_init(opts: argparse.Namespace): + """Initialize card key provider depending on the user provided commandline options""" + column_keys = {} + for par in opts.column_key: + name, key = par.split(':') + column_keys[name] = key + if os.path.isfile(os.path.expanduser(opts.csv)): + card_key_provider_register(CardKeyProviderCsv(os.path.expanduser(opts.csv), column_keys)) + if os.path.isfile(os.path.expanduser(opts.pgsql)): + card_key_provider_register(CardKeyProviderPgsql(os.path.expanduser(opts.pgsql), column_keys))