From 56e2d1e2cd2c434def07bcaa04adc3661e90a581 Mon Sep 17 00:00:00 2001 From: Manoel Benedito Neto Date: Sun, 10 Mar 2024 22:12:28 -0300 Subject: [PATCH] Addition of OTS Token activation procedure This commit adds an OTS Token activation procedure to IPsec server implementation. With this implementation, OTS Token is activated when PKI Auth response message is sent from IPsec server to IPsec client. The Token expiry time was increased to 7 seconds due to Kubernetes API dependability that may delay IPsec Auth procedure in a few seconds, affecting OTS Token validation criterea. Test plan: PASS: Full build, system install, bootstrap and unlock DX system w/ unlocked enabled available status. PASS: In a DC system with available enabled active status with IPsec server being executed from controller-0. Run "ipsec-client pxecontroller --opcode 1" in worker-0. Observe that certificates, keys and swanctl.conf files are created in worker-0 node. Observe that a security association is established between the hosts via "sudo swanctl --list-sas" command. PASS: In a DC system with available enabled active status with IPsec server being executed from controller-0. Run "ipsec-client pxecontroller --opcode 2" in controller-1. Observe the previously created CertificateRequest was deleted and generated a new one for controller-1's node. The new certificate is sent to IPsec Client and stored with the swanctl rekey command executed sucessfully. Story: 2010940 Task: 49712 Change-Id: I1c65edf14fd7ae3f47309b35048a805e0306038d Signed-off-by: Manoel Benedito Neto --- .../sysinv/ipsec_auth/common/objects.py | 33 +++++++++++++++---- .../sysinv/sysinv/ipsec_auth/server/server.py | 4 +++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/common/objects.py b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/common/objects.py index 2c6342fb5e..28bb6e77be 100644 --- a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/common/objects.py +++ b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/common/objects.py @@ -11,6 +11,10 @@ import string import time import threading +from oslo_log import log as logging + +LOG = logging.getLogger(__name__) + class State(enum.Enum): STAGE_1 = 1 @@ -64,16 +68,17 @@ class State(enum.Enum): class Token(object): VERSION = int(1).to_bytes(1, 'little') - EXPIRY_TIME = 5000 + EXPIRY_TIME = 7000 def __init__(self): self.__nonce = secrets.token_bytes(16) # 128-bit nonce - self.__start_time = int(time.time() * 1000) # 64-bit utc time + self.__creation_time = int(time.time() * 1000) # 64-bit utc time self.__content = bytearray(self.VERSION + self.__nonce - + self.__start_time.to_bytes(8, 'little')) + + self.__creation_time.to_bytes(8, 'little')) self.__used = False self.__expired = False - self.__timer = self.__set_timer() + self.__start_time = 0 + self.__timer = None random.shuffle(self.__content) @@ -88,18 +93,32 @@ class Token(object): def __expire_token(self): self.__expired = True - self.__timer.cancel() + if self.__timer and self.__timer.is_alive(): + self.__timer.cancel() + LOG.info("OTS Token set as expired") + else: + LOG.info("OTS Token expired") + return None + + def activate(self): + '''Activate OTS Token timer.''' + self.__start_time = int(time.time() * 1000) + self.__timer = self.__set_timer() + LOG.info("OTS Token activated") return None def purge(self): '''Purge the token.''' self.__used = True - self.__expired = True self.__content = bytearray() + self.__expire_token() + LOG.info("OTS Token purged") + return None def set_as_used(self): '''Set token as used.''' self.__used = True + LOG.info("OTS Token set as used") return None def get_content(self): @@ -111,7 +130,7 @@ class Token(object): time and its usage flag.''' period = int(time.time() * 1000) - self.__start_time if period >= self.EXPIRY_TIME and not self.__expired: - self.__expired = True + self.__expire_token() return not (self.__expired or self.__used) diff --git a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/server/server.py b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/server/server.py index 3d50a183c1..bda8020813 100644 --- a/sysinv/sysinv/sysinv/sysinv/ipsec_auth/server/server.py +++ b/sysinv/sysinv/sysinv/sysinv/ipsec_auth/server/server.py @@ -114,9 +114,13 @@ class IPsecConnection(object): # A readable client socket has data LOG.debug("Received {!r}".format(data)) self.state = State.get_next_state(self.state) + LOG.debug("Preparing payload") msg = self._handle_write(data) sock.sendall(msg) + + if self.state == State.STAGE_2: + self.ots_token.activate() self.state = State.get_next_state(self.state) elif self.state == State.STAGE_5 or not data: self.ots_token.purge()