diff --git a/helper/helper/oath.py b/helper/helper/oath.py index 32718e35..5aaccaea 100644 --- a/helper/helper/oath.py +++ b/helper/helper/oath.py @@ -91,6 +91,7 @@ class OathNode(RpcNode): def __init__(self, connection): super().__init__() self.session = OathSession(connection) + self._key_verifier = None if self.session.locked: key = self._get_access_key(self.session.device_id) @@ -162,12 +163,15 @@ class OathNode(RpcNode): return decode_bytes(params.pop("key")) raise ValueError("One of 'key' and 'password' must be provided.") - def _do_validate(self, key): - self.session.validate(key) + def _set_key_verifier(self, key): salt = os.urandom(32) digest = hmac.new(salt, key, "sha256").digest() self._key_verifier = (salt, digest) + def _do_validate(self, key): + self.session.validate(key) + self._set_key_verifier(key) + @action def validate(self, params, event, signal): remember = params.pop("remember", False) @@ -181,7 +185,7 @@ class OathNode(RpcNode): valid = False else: raise e - elif hasattr(self, "_key_verifier"): + elif self._key_verifier: salt, digest = self._key_verifier verify = hmac.new(salt, key, "sha256").digest() valid = hmac.compare_digest(digest, verify) @@ -198,18 +202,21 @@ class OathNode(RpcNode): remember = params.pop("remember", False) key = self._get_key(params) self.session.set_key(key) + self._set_key_verifier(key) remember &= self._remember_key(key if remember else None) return dict(remembered=remember) @action(condition=lambda self: self.session.has_key) def unset_key(self, params, event, signal): self.session.unset_key() + self._key_verifier = None self._remember_key(None) return dict() @action def reset(self, params, event, signal): self.session.reset() + self._key_verifier = None self._remember_key(None) return dict()