From 7eef411ab7112d468fb1070c0009943fa9451563 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Thu, 23 Jan 2025 15:00:39 -0600 Subject: [PATCH] Add pki-server password-set/unset The pki-server password-set/unset have been added to replace pki-server password-add/del so it will be more consistent with pki-server -config-set/unset. The pki-server password-set supports reading the password from file and from console, and also overwriting existing passwords. --- .../workflows/ca-clone-replicated-ds-test.yml | 2 +- .github/workflows/ca-existing-ds-test.yml | 2 +- .github/workflows/ca-existing-hsm-test.yml | 2 +- .../kra-clone-replicated-ds-test.yml | 2 +- .github/workflows/kra-existing-ds-test.yml | 2 +- .github/workflows/kra-existing-hsm-test.yml | 2 +- base/server/python/pki/server/cli/password.py | 169 +++++++++++++++++- docs/changes/v11.6.0/Tools-Changes.adoc | 7 + 8 files changed, 180 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ca-clone-replicated-ds-test.yml b/.github/workflows/ca-clone-replicated-ds-test.yml index 11c4e98bb0f..aeb520af8c0 100644 --- a/.github/workflows/ca-clone-replicated-ds-test.yml +++ b/.github/workflows/ca-clone-replicated-ds-test.yml @@ -119,7 +119,7 @@ jobs: - name: Configure connection to CA database run: | # store DS password - docker exec secondary pki-server password-add \ + docker exec secondary pki-server password-set \ --password Secret.123 \ internaldb diff --git a/.github/workflows/ca-existing-ds-test.yml b/.github/workflows/ca-existing-ds-test.yml index 5afec2b386b..b1ac92e325b 100644 --- a/.github/workflows/ca-existing-ds-test.yml +++ b/.github/workflows/ca-existing-ds-test.yml @@ -142,7 +142,7 @@ jobs: - name: Configure connection to CA database run: | # store DS password - docker exec pki pki-server password-add \ + docker exec pki pki-server password-set \ --password Secret.123 \ internaldb diff --git a/.github/workflows/ca-existing-hsm-test.yml b/.github/workflows/ca-existing-hsm-test.yml index 91485cda086..16c2e28c0aa 100644 --- a/.github/workflows/ca-existing-hsm-test.yml +++ b/.github/workflows/ca-existing-hsm-test.yml @@ -70,7 +70,7 @@ jobs: docker exec pki pki-server create docker exec pki pki-server nss-create --no-password - docker exec pki pki-server password-add "hardware-HSM" --password "Secret.HSM" + docker exec pki pki-server password-set "hardware-HSM" --password "Secret.HSM" docker exec pki cat /var/lib/pki/pki-tomcat/conf/password.conf - name: Create CA signing cert diff --git a/.github/workflows/kra-clone-replicated-ds-test.yml b/.github/workflows/kra-clone-replicated-ds-test.yml index 45ae2d34ef7..72270e3d6c8 100644 --- a/.github/workflows/kra-clone-replicated-ds-test.yml +++ b/.github/workflows/kra-clone-replicated-ds-test.yml @@ -136,7 +136,7 @@ jobs: - name: Configure connection to CA database run: | # store DS password - docker exec secondary pki-server password-add \ + docker exec secondary pki-server password-set \ --password Secret.123 \ internaldb diff --git a/.github/workflows/kra-existing-ds-test.yml b/.github/workflows/kra-existing-ds-test.yml index c2bd24b57d1..086d377f2ed 100644 --- a/.github/workflows/kra-existing-ds-test.yml +++ b/.github/workflows/kra-existing-ds-test.yml @@ -319,7 +319,7 @@ jobs: - name: Configure connection to KRA database run: | # store DS password - docker exec kra pki-server password-add \ + docker exec kra pki-server password-set \ --password Secret.123 \ internaldb diff --git a/.github/workflows/kra-existing-hsm-test.yml b/.github/workflows/kra-existing-hsm-test.yml index b2020731191..600203173f7 100644 --- a/.github/workflows/kra-existing-hsm-test.yml +++ b/.github/workflows/kra-existing-hsm-test.yml @@ -111,7 +111,7 @@ jobs: docker exec kra pki-server create docker exec kra pki-server nss-create --password Secret.123 - docker exec kra pki-server password-add "hardware-HSM" --password "Secret.HSM" + docker exec kra pki-server password-set "hardware-HSM" --password "Secret.HSM" docker exec kra cat /var/lib/pki/pki-tomcat/conf/password.conf - name: Issue KRA storage cert diff --git a/base/server/python/pki/server/cli/password.py b/base/server/python/pki/server/cli/password.py index dea0df74c8e..221c069d000 100644 --- a/base/server/python/pki/server/cli/password.py +++ b/base/server/python/pki/server/cli/password.py @@ -18,10 +18,13 @@ # All rights reserved. # +import getpass import logging import pki.cli +logger = logging.getLogger(__name__) + class PasswordCLI(pki.cli.CLI): @@ -31,6 +34,8 @@ def __init__(self): self.add_module(PasswordFindCLI()) self.add_module(PasswordAddCLI()) self.add_module(PasswordRemoveCLI()) + self.add_module(PasswordSetCLI()) + self.add_module(PasswordUnsetCLI()) @staticmethod def print_password(name): @@ -110,7 +115,7 @@ def execute(self, argv, args=None): class PasswordAddCLI(pki.cli.CLI): def __init__(self): - super().__init__('add', 'Add password') + super().__init__('add', 'Add password', deprecated=True) def create_parser(self, subparsers=None): @@ -146,6 +151,10 @@ def print_help(self): def execute(self, argv, args=None): + logger.warning( + 'The pki-server password-add has been deprecated. ' + 'Use pki-server password-set instead.') + if not args: args = self.parser.parse_args(args=argv) @@ -180,7 +189,7 @@ def execute(self, argv, args=None): class PasswordRemoveCLI(pki.cli.CLI): def __init__(self): - super().__init__('del', 'Remove password') + super().__init__('del', 'Remove password', deprecated=True) def create_parser(self, subparsers=None): @@ -212,6 +221,162 @@ def print_help(self): print(' --help Show help message.') print() + def execute(self, argv, args=None): + + logger.warning( + 'The pki-server password-del has been deprecated. ' + 'Use pki-server password-unset instead.') + + if not args: + args = self.parser.parse_args(args=argv) + + if args.help: + self.print_help() + return + + if args.debug: + logging.getLogger().setLevel(logging.DEBUG) + + elif args.verbose: + logging.getLogger().setLevel(logging.INFO) + + instance_name = args.instance + name = args.name + + instance = pki.server.PKIServerFactory.create(instance_name) + + if not instance.exists(): + raise Exception('Invalid instance: %s' % instance_name) + + instance.load() + + instance.passwords.pop(name) + instance.store_passwords() + + +class PasswordSetCLI(pki.cli.CLI): + + def __init__(self): + super().__init__('set', 'Set password') + + def create_parser(self, subparsers=None): + + self.parser = subparsers.add_parser( + self.get_full_name(), + add_help=False) + self.parser.add_argument( + '-i', + '--instance', + default='pki-tomcat') + self.parser.add_argument('--password') + self.parser.add_argument('--password-file') + self.parser.add_argument( + '--force', + action='store_true') + self.parser.add_argument( + '-v', + '--verbose', + action='store_true') + self.parser.add_argument( + '--debug', + action='store_true') + self.parser.add_argument( + '--help', + action='store_true') + self.parser.add_argument('name') + + def print_help(self): + print('Usage: pki-server password-set [OPTIONS] ') + print() + print(' -i, --instance Instance ID (default: pki-tomcat).') + print(' --password Password.') + print(' --password-file Password file.') + print(' --force Overwrite existing password.') + print(' -v, --verbose Run in verbose mode.') + print(' --debug Run in debug mode.') + print(' --help Show help message.') + print() + + def execute(self, argv, args=None): + + if not args: + args = self.parser.parse_args(args=argv) + + if args.help: + self.print_help() + return + + if args.debug: + logging.getLogger().setLevel(logging.DEBUG) + + elif args.verbose: + logging.getLogger().setLevel(logging.INFO) + + instance_name = args.instance + password = args.password + password_file = args.password_file + force = args.force + name = args.name + + instance = pki.server.PKIServerFactory.create(instance_name) + + if not instance.exists(): + raise Exception('Invalid instance: %s' % instance_name) + + instance.load() + + if name in instance.passwords and not force: + raise Exception('Password already exists: %s' % name) + + if password is not None: + pass + + elif password_file is not None: + with open(password_file, encoding='utf-8') as f: + password = f.read().splitlines()[0] + + else: + password = getpass.getpass(prompt='Enter password: ') + + instance.passwords[name] = password + instance.store_passwords() + + +class PasswordUnsetCLI(pki.cli.CLI): + + def __init__(self): + super().__init__('unset', 'Unset password') + + def create_parser(self, subparsers=None): + + self.parser = subparsers.add_parser( + self.get_full_name(), + add_help=False) + self.parser.add_argument( + '-i', + '--instance', + default='pki-tomcat') + self.parser.add_argument( + '-v', + '--verbose', + action='store_true') + self.parser.add_argument( + '--debug', + action='store_true') + self.parser.add_argument( + '--help', + action='store_true') + self.parser.add_argument('name') + + def print_help(self): + print('Usage: pki-server password-unset [OPTIONS] ') + print() + print(' -i, --instance Instance ID (default: pki-tomcat).') + print(' -v, --verbose Run in verbose mode.') + print(' --debug Run in debug mode.') + print(' --help Show help message.') + print() + def execute(self, argv, args=None): if not args: diff --git a/docs/changes/v11.6.0/Tools-Changes.adoc b/docs/changes/v11.6.0/Tools-Changes.adoc index f96ec5fce0c..c77dbf921de 100644 --- a/docs/changes/v11.6.0/Tools-Changes.adoc +++ b/docs/changes/v11.6.0/Tools-Changes.adoc @@ -65,3 +65,10 @@ The `pkispawn` command has been updated to include ACME and EST subsystem deploy == Update pkidestroy The `pkidestroy` command has been updated to include ACME and EST subsystem removal. + +== Add pki-server pki-server password-set/unset == + +The `pki-server password-set/unset` commands have been added +to replace `pki-server password-add/del`. + +The `pki-server password-add/del` commands have been deprecated.