From bbdb82268026821cd6a00edae09cc30079effd30 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Tue, 8 Mar 2022 15:19:09 -0600 Subject: [PATCH] Fix pki-server migrate CLI The pki-server migrate CLI has been modified to configure the AJP connectors with either secret or requiredSecret parameter (mutually exclusive) depending on the Tomcat version. https://bugzilla.redhat.com/show_bug.cgi?id=2061458 --- base/server/python/pki/server/cli/migrate.py | 60 ---------- base/server/python/pki/server/instance.py | 118 +++++++++++++++++++ 2 files changed, 118 insertions(+), 60 deletions(-) diff --git a/base/server/python/pki/server/cli/migrate.py b/base/server/python/pki/server/cli/migrate.py index 2005004c4e..6e0ed6c2a7 100644 --- a/base/server/python/pki/server/cli/migrate.py +++ b/base/server/python/pki/server/cli/migrate.py @@ -23,7 +23,6 @@ from __future__ import print_function import getopt import logging -import re import sys from lxml import etree @@ -104,62 +103,3 @@ class MigrateCLI(pki.cli.CLI): for instance in instances: instance.init() - - # update AJP connectors for Tomcat 9.0.31 or later - - tomcat_version = pki.server.Tomcat.get_version() - if tomcat_version >= pki.util.Version('9.0.31'): - - for instance in instances: - self.update_ajp_connectors(instance) - - def update_ajp_connectors(self, instance): - - logger.info('Updating AJP connectors in %s', instance.server_xml) - - document = etree.parse(instance.server_xml, self.parser) - server = document.getroot() - - # replace 'requiredSecret' with 'secret' in comments - - services = server.findall('Service') - for service in services: - - children = list(service) - for child in children: - - if not isinstance(child, etree._Comment): # pylint: disable=protected-access - # not a comment -> skip - continue - - if 'protocol="AJP/1.3"' not in child.text: - # not an AJP connector -> skip - continue - - child.text = re.sub(r'requiredSecret=', - r'secret=', - child.text, - flags=re.MULTILINE) - - # replace 'requiredSecret' with 'secret' in Connectors - - connectors = server.findall('Service/Connector') - for connector in connectors: - - if connector.get('protocol') != 'AJP/1.3': - # not an AJP connector -> skip - continue - - if connector.get('secret'): - # already has a 'secret' -> skip - continue - - if connector.get('requiredSecret') is None: - # does not have a 'requiredSecret' -> skip - continue - - value = connector.attrib.pop('requiredSecret') - connector.set('secret', value) - - with open(instance.server_xml, 'wb') as f: - document.write(f, pretty_print=True, encoding='utf-8') diff --git a/base/server/python/pki/server/instance.py b/base/server/python/pki/server/instance.py index ad938b841d..ff43dae8ec 100644 --- a/base/server/python/pki/server/instance.py +++ b/base/server/python/pki/server/instance.py @@ -836,9 +836,127 @@ class PKIInstance(pki.server.PKIServer): nssdb.close() shutil.rmtree(tmpdir) + def configure_ajp_connectors_secret(self): + + logger.info('Configuring AJP connectors secret') + + document = etree.parse(self.server_xml, parser) + server = document.getroot() + + # replace 'requiredSecret' with 'secret' in comments + + services = server.findall('Service') + for service in services: + + children = list(service) + for child in children: + + if not isinstance(child, etree._Comment): # pylint: disable=protected-access + # not a comment -> skip + continue + + if 'protocol="AJP/1.3"' not in child.text: + # not an AJP connector -> skip + continue + + child.text = re.sub(r'requiredSecret=', + r'secret=', + child.text, + flags=re.MULTILINE) + + # replace 'requiredSecret' with 'secret' in Connectors + + connectors = server.findall('Service/Connector') + for connector in connectors: + + if connector.get('protocol') != 'AJP/1.3': + # not an AJP connector -> skip + continue + + # remove existing 'requiredSecret' if any + value = connector.attrib.pop('requiredSecret', None) + print('AJP connector requiredSecret: %s' % value) + + if connector.get('secret'): + # already has a 'secret' -> skip + continue + + if not value: + raise Exception('Missing AJP connector secret in %s' % self.server_xml) + + # store 'secret' + connector.set('secret', value) + + with open(self.server_xml, 'wb') as f: + document.write(f, pretty_print=True, encoding='utf-8') + + def configure_ajp_connectors_required_secret(self): + + logger.info('Configuring AJP connectors requiredSecret') + + document = etree.parse(self.server_xml, parser) + server = document.getroot() + + # replace 'secret' with 'requiredSecret' in comments + + services = server.findall('Service') + for service in services: + + children = list(service) + for child in children: + + if not isinstance(child, etree._Comment): # pylint: disable=protected-access + # not a comment -> skip + continue + + if 'protocol="AJP/1.3"' not in child.text: + # not an AJP connector -> skip + continue + + child.text = re.sub(r'secret=', + r'requiredSecret=', + child.text, + flags=re.MULTILINE) + + # replace 'secret' with 'requiredSecret' in Connectors + + connectors = server.findall('Service/Connector') + for connector in connectors: + + if connector.get('protocol') != 'AJP/1.3': + # not an AJP connector -> skip + continue + + # remove existing 'secret' if any + value = connector.attrib.pop('secret', None) + print('AJP connector secret: %s' % value) + + if connector.get('requiredSecret'): + # already has a 'requiredSecret' -> skip + continue + + if not value: + raise Exception('Missing AJP connector requiredSecret in %s' % self.server_xml) + + # store 'requiredSecret' + connector.set('requiredSecret', value) + + with open(self.server_xml, 'wb') as f: + document.write(f, pretty_print=True, encoding='utf-8') + + def configure_ajp_connectors(self): + + tomcat_version = pki.server.Tomcat.get_version() + + if tomcat_version >= pki.util.Version('9.0.31'): + self.configure_ajp_connectors_secret() + else: + self.configure_ajp_connectors_required_secret() + def init(self): super(PKIInstance, self).init() self.validate_banner() + self.configure_ajp_connectors() @classmethod def instances(cls): -- 2.33.1