mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Require an ipa-ca SAN on 3rd party certs if ACME is enabled
ACME requires an ipa-ca SAN to have a fixed URL to connect to. If the Apache certificate is replaced by a 3rd party cert then it must provide this SAN otherwise it will break ACME. https://pagure.io/freeipa/issue/8498 Signed-off-by: Rob Crittenden <rcritten@redhat.com> Reviewed-By: Fraser Tweedale <ftweedal@redhat.com> Reviewed-By: Mohammad Rizwan <myusuf@redhat.com>
This commit is contained in:
@@ -31,6 +31,7 @@ import ldap
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import ssl
|
||||
import sys
|
||||
import syslog
|
||||
import time
|
||||
@@ -2271,6 +2272,30 @@ def import_ra_key(custodia):
|
||||
CAInstance.configure_agent_renewal()
|
||||
|
||||
|
||||
def check_ipa_ca_san(cert):
|
||||
"""
|
||||
Test whether the certificate has an ipa-ca SAN
|
||||
|
||||
:param cert: x509.IPACertificate
|
||||
|
||||
This SAN is necessary for ACME.
|
||||
|
||||
The caller is responsible for initializing the api.
|
||||
|
||||
On success returns None, on failure raises ValidationError
|
||||
"""
|
||||
expect = f'{ipalib.constants.IPA_CA_RECORD}.' \
|
||||
f'{ipautil.format_netloc(api.env.domain)}'
|
||||
|
||||
try:
|
||||
cert.match_hostname(expect)
|
||||
except ssl.CertificateError:
|
||||
raise errors.ValidationError(
|
||||
name='certificate',
|
||||
error='Does not have a \'{}\' SAN'.format(expect)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
standard_logging_setup("install.log")
|
||||
ds = dsinstance.DsInstance()
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import enum
|
||||
|
||||
from ipalib import api, errors
|
||||
from ipalib import api, errors, x509
|
||||
from ipalib import _
|
||||
from ipalib.facts import is_ipa_configured
|
||||
from ipaplatform.paths import paths
|
||||
@@ -90,6 +90,13 @@ class IPAACMEManage(AdminTool):
|
||||
except ValueError:
|
||||
self.option_parser.error(f'unknown command "{self.args[0]}"')
|
||||
|
||||
def check_san_status(self):
|
||||
"""
|
||||
Require the Apache cert to have ipa-ca.$DOMAIN SAN
|
||||
"""
|
||||
cert = x509.load_certificate_from_file(paths.HTTPD_CERT_FILE)
|
||||
cainstance.check_ipa_ca_san(cert)
|
||||
|
||||
def run(self):
|
||||
if not is_ipa_configured():
|
||||
print("IPA is not configured.")
|
||||
@@ -106,6 +113,7 @@ class IPAACMEManage(AdminTool):
|
||||
state = acme_state(api)
|
||||
with state as ca_api:
|
||||
if self.command == Command.ENABLE:
|
||||
self.check_san_status()
|
||||
ca_api.enable()
|
||||
elif self.command == Command.DISABLE:
|
||||
ca_api.disable()
|
||||
|
||||
@@ -27,12 +27,13 @@ import optparse # pylint: disable=deprecated-module
|
||||
from ipalib import x509
|
||||
from ipalib.install import certmonger
|
||||
from ipaplatform.paths import paths
|
||||
from ipapython import admintool
|
||||
from ipapython import admintool, dogtag
|
||||
from ipapython.certdb import NSSDatabase, get_ca_nickname
|
||||
from ipapython.dn import DN
|
||||
from ipapython import ipaldap
|
||||
from ipalib import api, errors
|
||||
from ipaserver.install import certs, dsinstance, installutils, krbinstance
|
||||
from ipaserver.install import cainstance
|
||||
|
||||
|
||||
class ServerCertInstall(admintool.AdminTool):
|
||||
@@ -105,11 +106,22 @@ class ServerCertInstall(admintool.AdminTool):
|
||||
raise admintool.ScriptError(
|
||||
"Private key unlock password required")
|
||||
|
||||
def validate_http_cert(self):
|
||||
if dogtag.acme_status():
|
||||
cert, unused, _unused = self.load_pkcs12(
|
||||
ca_chain_fname=paths.IPA_CA_CRT,
|
||||
host_name=api.env.host
|
||||
)
|
||||
cainstance.check_ipa_ca_san(cert)
|
||||
|
||||
def run(self):
|
||||
api.bootstrap(in_server=True, confdir=paths.ETC_IPA)
|
||||
api.finalize()
|
||||
api.Backend.ldap2.connect(bind_pw=self.options.dirman_password)
|
||||
|
||||
if self.options.http:
|
||||
self.validate_http_cert()
|
||||
|
||||
if self.options.dirsrv:
|
||||
self.install_dirsrv_cert()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user