mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 15:40:01 -06:00
b3d650370c
The goal of the last test in test_crlgen_manage is to ensure that ipa-server-install --uninstall can proceed if the server is the last one in the topology, even if it is the CRL generation master. The current code is wrong because it tries to uninstall the master (which has already been uninstalled in the prev test), It should rather uninstall replicas[0]. Signed-off-by: Florence Blanc-Renaud <flo@redhat.com> Reviewed-By: Sergey Orlov <sorlov@redhat.com> Reviewed-By: Christian Heimes <cheimes@redhat.com>
310 lines
12 KiB
Python
310 lines
12 KiB
Python
#
|
|
# Copyright (C) 2018 FreeIPA Contributors see COPYING for license
|
|
#
|
|
|
|
"""
|
|
Module provides tests for the ipa-crlgen-manage command.
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import os
|
|
from cryptography.hazmat.backends import default_backend
|
|
from cryptography import x509
|
|
|
|
from ipaplatform.paths import paths
|
|
from ipatests.pytest_ipa.integration import tasks
|
|
from ipatests.test_integration.base import IntegrationTest
|
|
|
|
CRLGEN_STATUS_ENABLED = 'enabled'
|
|
CRLGEN_STATUS_DISABLED = 'disabled'
|
|
CRL_FILENAME = os.path.join(paths.PKI_CA_PUBLISH_DIR, 'MasterCRL.bin')
|
|
|
|
|
|
def check_crlgen_status(host, rc=0, msg=None, enabled=True, check_crl=False):
|
|
"""Checks that CRLGen is configured as expected
|
|
|
|
:param host: The host where ;ipa-crlgen-manage status' command is run
|
|
:param rc: the expected result code
|
|
:param msg: the expected msg in stderr
|
|
:param enabled: the expected status
|
|
:param check_crl: if True we expect a Master.bin CRL file
|
|
|
|
If enabled:
|
|
ipa-crlgen-manage status must return 'CRL generation: enabled'
|
|
and print the last CRL update date and number if crl_present=True.
|
|
If disabled:
|
|
ipa-crlgen-manage status must return 'CRL generation: disabled'
|
|
"""
|
|
result = host.run_command(['ipa-crlgen-manage', 'status'],
|
|
raiseonerr=False)
|
|
|
|
assert result.returncode == rc
|
|
if msg:
|
|
assert msg in result.stderr_text
|
|
|
|
if rc == 0:
|
|
status = CRLGEN_STATUS_ENABLED if enabled else CRLGEN_STATUS_DISABLED
|
|
assert 'CRL generation: {}'.format(status) in result.stdout_text
|
|
|
|
if check_crl and enabled:
|
|
# We expect CRL generation to be enabled and need to check for
|
|
# MasterCRL.bin
|
|
crl_content = host.get_file_contents(CRL_FILENAME)
|
|
crl = x509.load_der_x509_crl(crl_content, default_backend())
|
|
last_update_msg = 'Last CRL update: {}'.format(crl.last_update)
|
|
assert last_update_msg in result.stdout_text
|
|
|
|
for ext in crl.extensions:
|
|
if ext.oid == x509.oid.ExtensionOID.CRL_NUMBER:
|
|
number_msg = "Last CRL Number: {}".format(
|
|
ext.value.crl_number)
|
|
assert number_msg in result.stdout_text
|
|
|
|
|
|
def check_crlgen_enable(host, rc=0, msg=None, check_crl=False):
|
|
"""Check ipa-crlgen-manage enable command
|
|
|
|
Launch ipa-crlgen-manage command and check the result code and output
|
|
"""
|
|
result = host.run_command(['ipa-crlgen-manage', 'enable'],
|
|
raiseonerr=False)
|
|
assert result.returncode == rc
|
|
if msg:
|
|
assert msg in result.stderr_text
|
|
if rc == 0:
|
|
# check ipa-crlgen-manage status is consistent
|
|
check_crlgen_status(host, enabled=True, check_crl=check_crl)
|
|
|
|
|
|
def check_crlgen_disable(host, rc=0, msg=None):
|
|
"""Check ipa-crlgen-manage disable command
|
|
|
|
Launch ipa-crlgen-manage command and check the result code and output
|
|
"""
|
|
result = host.run_command(['ipa-crlgen-manage', 'disable'],
|
|
raiseonerr=False)
|
|
assert result.returncode == rc
|
|
if msg:
|
|
assert msg in result.stderr_text
|
|
if rc == 0:
|
|
# check ipa-crlgen-manage status is consistent
|
|
check_crlgen_status(host, enabled=False)
|
|
|
|
|
|
def break_crlgen_with_rewriterule(host):
|
|
"""Create an inconsistent configuration on a CRL master
|
|
|
|
In the file /etc/httpd/conf.d/ipa-pki-proxy.conf, add a RewriteRule that
|
|
should be present only on non-CRL master"""
|
|
content = host.get_file_contents(paths.HTTPD_IPA_PKI_PROXY_CONF,
|
|
encoding='utf-8')
|
|
new_content = content + "\nRewriteRule ^/ipa/crl/MasterCRL.bin " \
|
|
"https://{}/ca/ee/ca/getCRL?op=getCRL&crlIssuingPoint=MasterCRL " \
|
|
"[L,R=301,NC]".format(host.hostname)
|
|
host.put_file_contents(paths.HTTPD_IPA_PKI_PROXY_CONF, new_content)
|
|
|
|
check_crlgen_status(host, rc=1, msg="Configuration is inconsistent")
|
|
|
|
|
|
def break_crlgen_with_CS_cfg(host):
|
|
"""Create an inconsistent configuration on a CRL master
|
|
|
|
Add a enableCRLUpdates=false directive that should be present only on
|
|
non-CRL master"""
|
|
content = host.get_file_contents(paths.CA_CS_CFG_PATH,
|
|
encoding='utf-8')
|
|
new_lines = []
|
|
for line in content.split('\n'):
|
|
if line.startswith('ca.crl.MasterCRL.enableCRLCache'):
|
|
new_lines.append("ca.crl.MasterCRL.enableCRLCache=false")
|
|
else:
|
|
new_lines.append(line)
|
|
host.put_file_contents(paths.CA_CS_CFG_PATH, '\n'.join(new_lines))
|
|
|
|
check_crlgen_status(host, rc=1, msg="Configuration is inconsistent")
|
|
|
|
|
|
class TestCRLGenManage(IntegrationTest):
|
|
"""Tests the ipa-crlgen-manage command.
|
|
|
|
ipa-crlgen-manage can be used to enable, disable or check
|
|
the status of CRL generation.
|
|
"""
|
|
|
|
num_replicas = 1
|
|
|
|
@classmethod
|
|
def install(cls, mh):
|
|
# Install a master and check CRL status (=enabled)
|
|
tasks.install_master(cls.master)
|
|
# We don't check for MasterCRL.bin presence because it may not
|
|
# be generated right after the install
|
|
check_crlgen_status(cls.master, enabled=True)
|
|
|
|
def test_master_enable_crlgen_already_enabled(self):
|
|
"""Test ipa-crlgen-manage enable on an already enabled instance"""
|
|
# We don't check for MasterCRL.bin presence because it may not
|
|
# be generated right after the install
|
|
check_crlgen_enable(
|
|
self.master, rc=0,
|
|
msg="Nothing to do, CRL generation already enabled")
|
|
|
|
def test_master_disable_crlgen(self):
|
|
"""Test ipa-crlgen-manage disable on an enabled instance"""
|
|
check_crlgen_disable(
|
|
self.master, rc=0,
|
|
msg="make sure to configure CRL generation on another master")
|
|
|
|
def test_master_disable_crlgen_already_disabled(self):
|
|
"""Test ipa-crlgen-manage disable on an enabled instance"""
|
|
check_crlgen_disable(
|
|
self.master, rc=0,
|
|
msg="Nothing to do, CRL generation already disabled")
|
|
|
|
def test_master_enable_crlgen(self):
|
|
"""Test ipa-crlgen-manage enable on a disabled instance"""
|
|
# This time we check that MasterCRL.bin is present
|
|
check_crlgen_enable(
|
|
self.master, rc=0,
|
|
msg="make sure to have only a single CRL generation master",
|
|
check_crl=True)
|
|
|
|
def test_crlgen_status_on_replica(self):
|
|
"""Test crlgen status on a replica without CA
|
|
|
|
Install a replica without CA
|
|
then call ipa-crlgen-manage status.
|
|
"""
|
|
tasks.install_replica(self.master, self.replicas[0], setup_ca=False)
|
|
check_crlgen_status(self.replicas[0], enabled=False)
|
|
|
|
def test_crlgen_disable_on_caless_replica(self):
|
|
"""Test crlgen disable on a replica without CA"""
|
|
check_crlgen_disable(
|
|
self.replicas[0], rc=0,
|
|
msg="Warning: Dogtag CA is not installed on this server")
|
|
|
|
def test_crlgen_enable_on_caless_replica(self):
|
|
"""Test crlgen enable on a replica without CA"""
|
|
check_crlgen_enable(
|
|
self.replicas[0], rc=1,
|
|
msg="Dogtag CA is not installed. Please install a CA first")
|
|
|
|
def test_crlgen_enable_on_ca_replica(self):
|
|
"""Test crlgen enable on a replica with CA
|
|
|
|
Install a CA clone and enable CRLgen"""
|
|
tasks.install_ca(self.replicas[0])
|
|
check_crlgen_enable(
|
|
self.replicas[0], rc=0,
|
|
msg="make sure to have only a single CRL generation master",
|
|
check_crl=True)
|
|
|
|
def test_crlgen_enable_on_broken_master(self):
|
|
"""Test crlgen enable on master with inconsistent config
|
|
|
|
Break the (enabled) master config by setting the rewriterule
|
|
and call enable"""
|
|
# Make sure the config is enabled
|
|
check_crlgen_enable(self.master)
|
|
# Break the config with RewriteRule
|
|
break_crlgen_with_rewriterule(self.master)
|
|
# Call enable to repair
|
|
check_crlgen_enable(
|
|
self.master, rc=0,
|
|
msg="CRL generation is partially enabled, repairing...",
|
|
check_crl=True)
|
|
|
|
def test_crlgen_disable_on_broken_master(self):
|
|
"""Test crlgen disable on master with inconsistent config
|
|
|
|
Break the (enabled) master config by setting the rewriterule
|
|
and call disable"""
|
|
# Make sure the config is enabled
|
|
check_crlgen_enable(self.master)
|
|
# Break the config with RewriteRule
|
|
break_crlgen_with_rewriterule(self.master)
|
|
# Call disable to repair
|
|
check_crlgen_disable(
|
|
self.master, rc=0,
|
|
msg="CRL generation is partially enabled, repairing...")
|
|
|
|
def test_crlgen_enable_on_broken_replica(self):
|
|
"""Test crlgen enable on replica with inconsistent config
|
|
|
|
Break the (enabled) replica config by setting enableCRLUpdates=false
|
|
and call enable"""
|
|
# Make sure the config is enabled
|
|
check_crlgen_enable(self.replicas[0])
|
|
# Break the config with RewriteRule
|
|
break_crlgen_with_CS_cfg(self.replicas[0])
|
|
# Call enable to repair
|
|
check_crlgen_enable(
|
|
self.replicas[0], rc=0,
|
|
msg="CRL generation is partially enabled, repairing...",
|
|
check_crl=True)
|
|
|
|
def test_crlgen_disable_on_broken_replica(self):
|
|
"""Test crlgen disable on replica with inconsistent config
|
|
|
|
Break the (enabled) replica config by setting enableCRLUpdates=false
|
|
and call disable"""
|
|
# Make sure the config is enabled
|
|
check_crlgen_enable(self.replicas[0])
|
|
# Break the config with RewriteRule
|
|
break_crlgen_with_CS_cfg(self.replicas[0])
|
|
# Call disable to repair
|
|
check_crlgen_disable(
|
|
self.replicas[0], rc=0,
|
|
msg="CRL generation is partially enabled, repairing...")
|
|
|
|
def test_uninstall_without_ignore_last_of_role(self):
|
|
"""Test uninstallation of the CRL generation master
|
|
|
|
If --ignore-last-of-role is not provided, uninstall prints a msg
|
|
and exits on error.
|
|
"""
|
|
# Make sure CRL gen is enabled on the master
|
|
check_crlgen_enable(self.master)
|
|
# call uninstall without --ignore-last-of-role, should be refused
|
|
result = self.master.run_command(
|
|
['ipa-server-install', '--uninstall', '-U'], raiseonerr=False)
|
|
assert result.returncode == 1
|
|
expected_msg = "Deleting this server will leave your installation " \
|
|
"without a CRL generation master"
|
|
assert expected_msg in result.stdout_text
|
|
|
|
def test_uninstall_with_ignore_last_of_role(self):
|
|
"""Test uninstallation of the CRL generation master
|
|
|
|
When --ignore-last-of-role is provided, uninstall prints a msg but
|
|
gets executed.
|
|
"""
|
|
# Make sure CRL gen is enabled on the master
|
|
check_crlgen_enable(self.master)
|
|
# call uninstall with --ignore-last-of-role, should be OK
|
|
result = self.master.run_command(
|
|
['ipa-server-install', '--uninstall', '-U',
|
|
'--ignore-last-of-role'])
|
|
expected_msg = "Deleting this server will leave your installation " \
|
|
"without a CRL generation master"
|
|
assert expected_msg in result.stdout_text
|
|
tasks.run_server_del(
|
|
self.replicas[0], self.master.hostname, force=True,
|
|
ignore_topology_disconnect=True,
|
|
ignore_last_of_role=True)
|
|
|
|
def test_uninstall_last_master_does_not_require_ignore_last_of_role(self):
|
|
"""Test uninstallation of the last master
|
|
|
|
Even if the host is CRL generation master, uninstall must proceed
|
|
even without --ignore-last-of-role because we are removing the last
|
|
master.
|
|
"""
|
|
# Make sure CRL gen is enabled on the replica
|
|
check_crlgen_enable(self.replicas[0])
|
|
# call uninstall without --ignore-last-of-role, should be OK
|
|
self.replicas[0].run_command(
|
|
['ipa-server-install', '--uninstall', '-U'])
|