This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
dexter gerrit-no-reply at lists.osmocom.orgdexter has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/23538 ) Change subject: pySim-shell: automatic ADM pin from CSV-File ...................................................................... pySim-shell: automatic ADM pin from CSV-File It can be hard to manage ADM pins when working with different cards at the same time. To make this easier, add an automatic way to determine the ADM pin for each card from a CSV file. - add a CardData clas model that can be extended to to get the data from various different sources. For now use CSV-Files. Also add a way how multiple CardData classes can be registered so that one global get function can query all registered CardData classes at once. - automatically check for CSV-File in home directory and use it as default CardData source unless the user specifies a CSV file via commandline argument. - extend the verify_adm command so that it automatically queries the ADM pin if no argument is given. Also do not try to authenticate if no ADM pin could be determined. Change-Id: I51835ccb16bcbce35e7f3765e8927a4451509e77 Related: OS#4963 --- M pySim-shell.py A pySim/card_data.py 2 files changed, 146 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/38/23538/1 diff --git a/pySim-shell.py b/pySim-shell.py index 41febd6..3f26ac5 100755 --- a/pySim-shell.py +++ b/pySim-shell.py @@ -29,6 +29,7 @@ import os import sys from optparse import OptionParser +from pathlib import Path from pySim.ts_51_011 import EF, DF, EF_SST_map, EF_AD_mode_map from pySim.ts_31_102 import EF_UST_map, EF_USIM_ADF_map @@ -47,6 +48,9 @@ from pySim.ts_31_102 import ADF_USIM from pySim.ts_31_103 import ADF_ISIM +from pySim.card_data import CardDataCsv, card_data_register, card_data_get_field + + class PysimApp(cmd2.Cmd): CUSTOM_CATEGORY = 'pySim Commands' def __init__(self, card, rs, script = None): @@ -56,6 +60,8 @@ self.intro = style('Welcome to pySim-shell!', fg=fg.red) self.default_category = 'pySim-shell built-in commands' self.card = card + iccid, sw = self.card.read_iccid() + self.iccid = iccid self.rs = rs self.py_locals = { 'card': self.card, 'rs' : self.rs } self.numeric_path = False @@ -78,8 +84,20 @@ @cmd2.with_category(CUSTOM_CATEGORY) def do_verify_adm(self, arg): """VERIFY the ADM1 PIN""" - pin_adm = sanitize_pin_adm(arg) - self.card.verify_adm(h2b(pin_adm)) + if arg: + # use specified ADM-PIN + pin_adm = sanitize_pin_adm(arg) + else: + # try to find an ADM-PIN if none is specified + result = card_data_get_field('ADM1', key='ICCID', value=self.iccid) + pin_adm = sanitize_pin_adm(result) + if pin_adm: + self.poutput("found adm-pin '%s' for ICCID '%s'" % (result, self.iccid)) + + if pin_adm: + self.card.verify_adm(h2b(pin_adm)) + else: + self.poutput("error: cannot authenticate, no adm-pin!") @cmd2.with_category(CUSTOM_CATEGORY) def do_desc(self, opts): @@ -289,6 +307,11 @@ default=None, ) + parser.add_option("--csv", dest="csv", metavar="FILE", + help="Read card data from CSV file", + default=None, + ) + parser.add_option("-a", "--pin-adm", dest="pin_adm", help="ADM PIN used for provisioning (overwrites default)", ) @@ -340,6 +363,14 @@ app = PysimApp(card, rs, opts.script) rs.select('MF', app) + # Register csv-file as card data provider, either from specified CSV + # or from CSV file in home directory + csv_default = str(Path.home()) + "/.pysim_shell_card_data.csv" + if opts.csv: + card_data_register(CardDataCsv(opts.csv)) + elif os.path.isfile(csv_default): + card_data_register(CardDataCsv(csv_default)) + # If the user supplies an ADM PIN at via commandline args authenticate # immediatley so that the user does not have to use the shell commands pin_adm = sanitize_pin_adm(opts.pin_adm, opts.pin_adm_hex) diff --git a/pySim/card_data.py b/pySim/card_data.py new file mode 100644 index 0000000..8feb84b --- /dev/null +++ b/pySim/card_data.py @@ -0,0 +1,113 @@ +# coding=utf-8 +"""Abstraction of card data that can be queried from external source + +(C) 2021 by Sysmocom s.f.m.c. GmbH +All Rights Reserved + +Author: Philipp Maier + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +""" + +import csv + +card_data_provider = [] + +class CardData(object): + + VALID_FIELD_NAMES = ['ICCID', 'ADM1', 'IMSI'] + + # check input parameters, but do nothing concrete yet + def get_data(self, fields=[], key='ICCID', value=""): + """abstract implementation of gst_data that only verifies the function parameters""" + + for f in fields: + if (f not in self.VALID_FIELD_NAMES): + raise ValueError("Requested field name '%s' is not a valid field name, valid field names are: %s" % + (f, str(self.VALID_FIELD_NAMES))) + + if (key not in self.VALID_FIELD_NAMES): + raise ValueError("Key field name '%s' is not a valid field name, valid field names are: %s" % + (key, str(self.VALID_FIELD_NAMES))) + + return {} + + def get_field(self, field, key='ICCID', value=""): + """get a single field from CSV file using a specified key/value pair""" + fields = [field] + result = self.get(fields, key, value) + return result.get(field) + + +class CardDataCsv(CardData): + """card data class that allows the user to query against a specified CSV file""" + csv_file = None + filename = None + + def __init__(self, filename): + self.csv_file = open(filename, 'r') + if not self.csv_file: + raise RuntimeError("Could not open CSV-File '%s'" % filename) + self.filename = filename + + def get(self, fields, key, value): + """get fields from CSV file using a specified key/value pair""" + super().get_data(fields, key, value) + + self.csv_file.seek(0) + cr = csv.DictReader(self.csv_file) + if not cr: + raise RuntimeError("Could not open DictReader for CSV-File '%s'" % self.filename) + cr.fieldnames = [ field.upper() for field in cr.fieldnames ] + + rc = {} + for row in cr: + if row[key] == value: + for f in fields: + if f in row: + rc.update({f : row[f]}) + else: + raise RuntimeError("CSV-File '%s' lacks column '%s'" % + (self.filename, f)) + return rc + + +def card_data_register(provider, provider_list=card_data_provider): + """Register a new card data provider""" + if not isinstance(provider, CardData): + raise ValueError("provider is not a card data provier") + provider_list.append(provider) + + +def card_data_get(fields, key, value, provider_list=card_data_provider): + """Query all registered card data providers""" + for p in provider_list: + if not isinstance(p, CardData): + raise ValueError("provider list contains provider, which is not a card data provier") + result = p.get(fields, key, value) + if result: + return result + return {} + + +def card_data_get_field(field, key, value, provider_list=card_data_provider): + """Query all registered card data providers for a single field""" + for p in provider_list: + if not isinstance(p, CardData): + raise ValueError("provider list contains provider, which is not a card data provier") + result = p.get_field(field, key, value) + if result: + return result + return None + -- To view, visit https://gerrit.osmocom.org/c/pysim/+/23538 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: I51835ccb16bcbce35e7f3765e8927a4451509e77 Gerrit-Change-Number: 23538 Gerrit-PatchSet: 1 Gerrit-Owner: dexter <pmaier at sysmocom.de> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210329/406f72a6/attachment.htm>