]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Make TwoStep (without TAN) work again
authorHenryk Plötz <henryk@ploetzli.ch>
Mon, 20 Aug 2018 00:11:58 +0000 (02:11 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Mon, 3 Dec 2018 18:34:29 +0000 (19:34 +0100)
fints/client.py
fints/security.py

index 00aee6630335d228f1443514435446f8160c688e..e146635af2309531f986919a8fe9c1ef846d9642 100644 (file)
@@ -10,12 +10,12 @@ from .connection import FinTSHTTPSConnection
 from .dialog import FinTSDialogOLD, FinTSDialog
 from .formals import TwoStepParametersCommon
 from .message import FinTSMessageOLD
-from .security import PinTanDummyEncryptionMechanism, PinTanOneStepAuthenticationMechanism
+from .security import PinTanDummyEncryptionMechanism, PinTanOneStepAuthenticationMechanism, PinTanTwoStepAuthenticationMechanism
 from .models import (
     SEPAAccount, TANChallenge, TANChallenge3,
     TANChallenge4, TANChallenge5, TANChallenge6,
 )
-from .segments import HIUPA4, HIBPA3
+from .segments import HIUPA4, HIBPA3, HIRMS2
 from .segments.accounts import HKSPA, HKSPA1, HISPA1
 from .segments.auth import HKTAB, HKTAN
 from .segments.dialog import HKSYN3, HISYN4
@@ -50,6 +50,8 @@ class FinTS3Client:
         self.upd_version = 0
         self.upa = None
         self.upd = []
+        self.allowed_security_functions = []
+        self.selected_security_function = None
         self.product_name = 'pyfints'
         self.product_version = '0.2'
 
@@ -81,6 +83,13 @@ class FinTS3Client:
                 message.find_segments('HIUPD')
             )
 
+        for seg in message.find_segments(HIRMS2):
+            for response in seg.responses:
+                if response.code == '3920':
+                    self.allowed_security_functions = response.parameters
+                    if self.selected_security_function is None:
+                        self.selected_security_function = self.allowed_security_functions[0]
+
     def find_bpd(self, type):
         for seg in self.bpd:
             if seg.header.type == type:
@@ -506,10 +515,21 @@ class FinTS3PinTanClient(FinTS3Client):
         if not lazy_init:
             self._ensure_system_id()
 
+        if not self.selected_security_function or self.selected_security_function == '999':
+            enc = PinTanDummyEncryptionMechanism(1)
+            auth = PinTanOneStepAuthenticationMechanism(self.pin)
+        else:
+            enc = PinTanDummyEncryptionMechanism(2)
+            auth = PinTanTwoStepAuthenticationMechanism(
+                self,
+                self.selected_security_function,
+                self.pin,
+            )
+
         return FinTSDialog(self, 
             lazy_init=lazy_init,
-            enc_mechanism=PinTanDummyEncryptionMechanism(1),
-            auth_mechanisms=[PinTanOneStepAuthenticationMechanism(self.pin)],
+            enc_mechanism=enc,
+            auth_mechanisms=[auth],
         )
 
     def _new_message(self, dialog: FinTSDialogOLD, segments, tan=None):
index dd2b685fd211c659e8b63dad68deb063dfe7e4a2..68acc5f105487d5696683d5fcaeb899feb338e89 100644 (file)
@@ -80,11 +80,12 @@ class PinTanDummyEncryptionMechanism(EncryptionMechanism):
         pass
 
 
-class PinTanOneStepAuthenticationMechanism(AuthenticationMechanism):
+class PinTanAuthenticationMechanism(AuthenticationMechanism):
     def __init__(self, pin, tan=None):
         self.pin=pin
         self.tan=tan
         self.pending_signature=None
+        self.security_function=None
 
     def sign_prepare(self, message: FinTSMessage):
         _now = datetime.datetime.now()
@@ -92,7 +93,7 @@ class PinTanOneStepAuthenticationMechanism(AuthenticationMechanism):
 
         self.pending_signature = HNSHK4(
             security_profile = SecurityProfile(SecurityMethod.PIN, 1),
-            security_function = '999',
+            security_function = self.security_function,
             security_reference = rand.randint(1000000, 9999999),
             security_application_area = SecurityApplicationArea.SHM,
             security_role = SecurityRole.ISS,
@@ -148,3 +149,14 @@ class PinTanOneStepAuthenticationMechanism(AuthenticationMechanism):
 
     def verify(self, message: FinTSMessage):
         pass
+
+class PinTanOneStepAuthenticationMechanism(PinTanAuthenticationMechanism):
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.security_function = '999'
+
+class PinTanTwoStepAuthenticationMechanism(PinTanAuthenticationMechanism):
+    def __init__(self, client, security_function, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.client = client
+        self.security_function = security_function