Change in pysim[master]: filesystem: allow selection of arbitrary files

laforge gerrit-no-reply at lists.osmocom.org
Fri Apr 2 14:33:23 UTC 2021


laforge has submitted this change. ( https://gerrit.osmocom.org/c/pysim/+/23533 )

Change subject: filesystem: allow selection of arbitrary files
......................................................................

filesystem: allow selection of arbitrary files

Some cards may have additional propritary EF files which pySim-shell
does not support. If the user knows the exact FID the file can still be
selected and it is possible to read the file type and memory model from
the select response. This info can be used to create a new file object
at runtime that will work like any other EF/DF.

Change-Id: Iafff97443130f8bb8c5bc68f51d2fe1d93fff07c
Related: OS#4963
---
M pySim/filesystem.py
1 file changed, 51 insertions(+), 11 deletions(-)

Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified



diff --git a/pySim/filesystem.py b/pySim/filesystem.py
index cb39b94..9f3b221 100644
--- a/pySim/filesystem.py
+++ b/pySim/filesystem.py
@@ -130,12 +130,19 @@
 
 class CardDF(CardFile):
     """DF (Dedicated File) in the smart card filesystem.  Those are basically sub-directories."""
+
+    @with_default_category('DF/ADF Commands')
+    class ShellCommands(CommandSet):
+        def __init__(self):
+            super().__init__()
+
     def __init__(self, **kwargs):
         if not isinstance(self, CardADF):
             if not 'fid' in kwargs:
                 raise TypeError('fid is mandatory for all DF')
         super().__init__(**kwargs)
         self.children = dict()
+        self.shell_commands = [self.ShellCommands()]
 
     def __str__(self):
         return "DF(%s)" % (super().__str__())
@@ -614,17 +621,48 @@
         else:
             return self.profile.interpret_sw(sw)
 
+    def probe_file(self, fid, cmd_app=None):
+        """
+	blindly try to select a file and automatically add a matching file
+	object if the file actually exists
+	"""
+        if not is_hex(fid, 4, 4):
+            raise ValueError("Cannot select unknown file by name %s, only hexadecimal 4 digit FID is allowed" % fid)
+
+        try:
+            (data, sw) = self.card._scc.select_file(fid)
+        except SwMatchError as swm:
+            k = self.interpret_sw(swm.sw_actual)
+            if not k:
+                raise(swm)
+            raise RuntimeError("%s: %s - %s" % (swm.sw_actual, k[0], k[1]))
+
+        select_resp = self.selected_file.decode_select_response(data)
+        if (select_resp['file_descriptor']['file_type'] == 'df'):
+            f = CardDF(fid=fid, sfid=None, name="DF." + str(fid).upper(), desc="dedicated file, manually added at runtime")
+        else:
+            if (select_resp['file_descriptor']['structure'] == 'transparent'):
+                f = TransparentEF(fid=fid, sfid=None, name="EF." + str(fid).upper(), desc="elementry file, manually added at runtime")
+            else:
+                f = LinFixedEF(fid=fid, sfid=None, name="EF." + str(fid).upper(), desc="elementry file, manually added at runtime")
+
+        self.selected_file.add_files([f])
+        self.selected_file = f
+        return select_resp
+
     def select(self, name, cmd_app=None):
         """Change current directory"""
         sels = self.selected_file.get_selectables()
         if is_hex(name):
             name = name.lower()
+
+        # unregister commands of old file
+        if cmd_app and self.selected_file.shell_commands:
+            for c in self.selected_file.shell_commands:
+                cmd_app.unregister_command_set(c)
+
         if name in sels:
             f = sels[name]
-            # unregister commands of old file
-            if cmd_app and self.selected_file.shell_commands:
-                for c in self.selected_file.shell_commands:
-                    cmd_app.unregister_command_set(c)
             try:
                 if isinstance(f, CardADF):
                     (data, sw) = self.card._scc.select_adf(f.aid)
@@ -636,14 +674,16 @@
                 if not k:
                     raise(swm)
                 raise RuntimeError("%s: %s - %s" % (swm.sw_actual, k[0], k[1]))
-            # register commands of new file
-            if cmd_app and self.selected_file.shell_commands:
-                for c in self.selected_file.shell_commands:
-                    cmd_app.register_command_set(c)
-            return f.decode_select_response(data)
-        #elif looks_like_fid(name):
+            select_resp = f.decode_select_response(data)
         else:
-            raise ValueError("Cannot select unknown %s" % (name))
+            select_resp = self.probe_file(name, cmd_app)
+
+        # register commands of new file
+        if cmd_app and self.selected_file.shell_commands:
+            for c in self.selected_file.shell_commands:
+                cmd_app.register_command_set(c)
+
+        return select_resp
 
     def read_binary(self, length=None, offset=0):
         if not isinstance(self.selected_file, TransparentEF):

-- 
To view, visit https://gerrit.osmocom.org/c/pysim/+/23533
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: Iafff97443130f8bb8c5bc68f51d2fe1d93fff07c
Gerrit-Change-Number: 23533
Gerrit-PatchSet: 4
Gerrit-Owner: dexter <pmaier at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: daniel <dwillmann at sysmocom.de>
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-Reviewer: pespin <pespin at sysmocom.de>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210402/6f501a45/attachment.htm>


More information about the gerrit-log mailing list