From 34b9099da1c08ada6c66a0b2c51ba3d6261964b3 Mon Sep 17 00:00:00 2001 From: sh_wang Date: Mon, 20 May 2024 15:20:54 +0800 Subject: [PATCH 1/4] [TACACS] Encrypt TACACS secret key with predefined shared key. Signed-off-by: sh_wang --- config/aaa.py | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/config/aaa.py b/config/aaa.py index fdb784dc4a..671df6804f 100644 --- a/config/aaa.py +++ b/config/aaa.py @@ -1,16 +1,26 @@ import click import ipaddress import re +import subprocess from swsscommon.swsscommon import ConfigDBConnector from .validated_config_db_connector import ValidatedConfigDBConnector from jsonpatch import JsonPatchConflict from jsonpointer import JsonPointerException import utilities_common.cli as clicommon +TAC_PLUS_PASSKEY_MAX_LEN = 65 ADHOC_VALIDATION = True RADIUS_MAXSERVERS = 8 RADIUS_PASSKEY_MAX_LEN = 65 VALID_CHARS_MSG = "Valid chars are ASCII printable except SPACE, '#', and ','" +TACPLUS_SECRET_PASSWORD = "ktbSJeed7apq9dZHOD1O5wW9cvSaRWjW767qLyFEurDTSNEvHdYspaCuEzZcMg8R" + +def encrypt_data(secret): + cmd = [ 'openssl', 'enc', '-aes-128-cbc', '-A', '-a', '-salt', '-pbkdf2', '-pass', 'pass:' + TACPLUS_SECRET_PASSWORD ] + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + outsecret, errs = p.communicate(input=secret) + return outsecret,errs + def is_secret(secret): return bool(re.match('^' + '[^ #,]*' + '$', secret)) @@ -240,7 +250,20 @@ def passkey(ctx, secret): if ctx.obj == 'default': del_table_key('TACPLUS', 'global', 'passkey') elif secret: - add_table_kv('TACPLUS', 'global', 'passkey', secret) + if len(secret) > TAC_PLUS_PASSKEY_MAX_LEN: + click.echo('Maximum of %d chars can be configured' % TAC_PLUS_PASSKEY_MAX_LEN) + return + elif not is_secret(secret): + click.echo(VALID_CHARS_MSG) + return + + outsecret, errs = encrypt_data(secret) + if not errs: + add_table_kv('TACPLUS', 'global', 'passkey', outsecret) + else: + click.echo('Key configuration failed' % errs) + return + else: click.echo('Argument "secret" is required') tacacs.add_command(passkey) @@ -278,7 +301,13 @@ def add(address, timeout, key, auth_type, port, pri, use_mgmt_vrf): if timeout is not None: data['timeout'] = str(timeout) if key is not None: - data['passkey'] = key + outsecret, errs = encrypt_data(key) + if not errs: + data['passkey'] = outsecret + else: + click.echo('Key configuration failed' % errs) + return + if use_mgmt_vrf : data['vrf'] = "mgmt" try: From fff012c66eee315f8dc366bc143669b9a1f8788a Mon Sep 17 00:00:00 2001 From: sh_wang Date: Mon, 20 May 2024 15:50:59 +0800 Subject: [PATCH 2/4] [TACACS] Encrypt TACACS secret key with predefined shared key. Signed-off-by: sh_wang --- config/aaa.py | 1 + 1 file changed, 1 insertion(+) diff --git a/config/aaa.py b/config/aaa.py index 671df6804f..d5752cdd68 100644 --- a/config/aaa.py +++ b/config/aaa.py @@ -15,6 +15,7 @@ VALID_CHARS_MSG = "Valid chars are ASCII printable except SPACE, '#', and ','" TACPLUS_SECRET_PASSWORD = "ktbSJeed7apq9dZHOD1O5wW9cvSaRWjW767qLyFEurDTSNEvHdYspaCuEzZcMg8R" + def encrypt_data(secret): cmd = [ 'openssl', 'enc', '-aes-128-cbc', '-A', '-a', '-salt', '-pbkdf2', '-pass', 'pass:' + TACPLUS_SECRET_PASSWORD ] p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) From cae1782a8b8d4eda47e59a37f43fa0481a2ba9cf Mon Sep 17 00:00:00 2001 From: sh_wang Date: Mon, 20 May 2024 15:54:53 +0800 Subject: [PATCH 3/4] [TACACS] Fix code according to code analysis. Signed-off-by: sh_wang --- config/aaa.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/config/aaa.py b/config/aaa.py index d5752cdd68..b01cfceaa8 100644 --- a/config/aaa.py +++ b/config/aaa.py @@ -17,10 +17,11 @@ def encrypt_data(secret): - cmd = [ 'openssl', 'enc', '-aes-128-cbc', '-A', '-a', '-salt', '-pbkdf2', '-pass', 'pass:' + TACPLUS_SECRET_PASSWORD ] - p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) + cmd = ['openssl', 'enc', '-aes-128-cbc', '-A', '-a', '-salt', '-pbkdf2', '-pass', 'pass:' + TACPLUS_SECRET_PASSWORD] + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, universal_newlines=True) outsecret, errs = p.communicate(input=secret) - return outsecret,errs + return outsecret, errs def is_secret(secret): From ed39116405f35e96d6d9c3241f59915487c519ce Mon Sep 17 00:00:00 2001 From: sh_wang Date: Mon, 20 May 2024 15:58:28 +0800 Subject: [PATCH 4/4] [TACACS] Fix code according to code analysis. Signed-off-by: sh_wang --- config/aaa.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/aaa.py b/config/aaa.py index b01cfceaa8..bd8260adc3 100644 --- a/config/aaa.py +++ b/config/aaa.py @@ -17,7 +17,8 @@ def encrypt_data(secret): - cmd = ['openssl', 'enc', '-aes-128-cbc', '-A', '-a', '-salt', '-pbkdf2', '-pass', 'pass:' + TACPLUS_SECRET_PASSWORD] + cmd = ['openssl', 'enc', '-aes-128-cbc', '-A', '-a', '-salt', '-pbkdf2', + '-pass', 'pass:' + TACPLUS_SECRET_PASSWORD] p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) outsecret, errs = p.communicate(input=secret)