Exemplo n.º 1
0
 def _closeup(self):
     x509cert = pki_utils.x509_load_cert(
         oenginecons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_CA_CERT,
     )
     self.dialog.note(
         text=_('Internal CA fingerprint: SHA256: {fingerprint}').format(
             fingerprint=re.sub(
                 r'(..)',
                 r':\1',
                 binascii.b2a_hex(
                     x509cert.fingerprint(
                         algorithm=hashes.SHA256()
                     )
                 ).decode().upper()
             )[1:],
         )
     )
     for ca_file in self._renewed_ca_files:
         self.logger.warning(
             _(
                 'CA %s was renewed, please refresh manually '
                 'distributed copies'
             ),
             ca_file
         )
Exemplo n.º 2
0
    def _customization_upgrade(self):
        if True in [
                pki_utils.cert_expires(pki_utils.x509_load_cert(cert))
                for cert in self._CA_FILES if os.path.exists(cert)
        ] + [
                self._ok_to_renew_cert(
                    os.path.join(
                        oenginecons.FileLocations.OVIRT_ENGINE_PKIKEYSDIR,
                        '%s.p12' % entry['name']), entry['name'],
                    entry['extract'])
                for entry in self.environment[oenginecons.PKIEnv.ENTITIES]
        ]:
            if self.environment[oenginecons.PKIEnv.RENEW] is None:
                self.environment[oenginecons.PKIEnv.RENEW] = dialog.queryBoolean(
                    dialog=self.dialog,
                    name='OVESETUP_RENEW_PKI',
                    note=_(
                        'One or more of the certificates should be renewed, '
                        'because they expire soon, or include an invalid '
                        'expiry date, or they were created with validity '
                        'period longer than 398 days, or do not include the '
                        'subjectAltName extension, which can cause them to be '
                        'rejected by recent browsers and up to date hosts.\n'
                        'See {url} for more details.\n'
                        'Renew certificates? '
                        '(@VALUES@) [@DEFAULT@]: ').format(
                            url=self.environment[
                                oenginecons.ConfigEnv.PKI_RENEWAL_DOC_URL], ),
                    prompt=True,
                    default=None,
                )

                if not self.environment[oenginecons.PKIEnv.RENEW]:
                    skip_renewal = dialog.queryBoolean(
                        dialog=self.dialog,
                        name='OVESETUP_SKIP_RENEW_PKI_CONFIRM',
                        note=_(
                            'Are you really sure that you want to skip the '
                            'PKI renewal process?\n'
                            'Please notice that recent openssl and gnutls '
                            'upgrades can lead hosts refusing this CA cert '
                            'making them unusable.\n'
                            'If you choose "Yes", setup will continue and you '
                            'will be asked again the next '
                            'time you run this Setup. Otherwise, this process '
                            'will abort and you will be expected to plan a '
                            'proper upgrade according to {url}.\n'
                            'Skip PKI renewal process? '
                            '(@VALUES@) [@DEFAULT@]: ').format(
                                url=self.environment[oenginecons.ConfigEnv.
                                                     PKI_RENEWAL_DOC_URL], ),
                        prompt=True,
                        default=False,
                    )
                    if not skip_renewal:
                        raise RuntimeError('Aborted by user')
Exemplo n.º 3
0
 def _ok_to_renew_cert(self, pkcs12, name, extract):
     # input:
     # - pkcs12: A PKCS#12 file name
     # - name: A base name (--name param of pki-* scripts)
     # - extract: bool. If True, we need to check the extracted cert
     # return: bool
     self.logger.debug("processing: '%s'", name)
     return os.path.exists(pkcs12) and pki_utils.ok_to_renew_cert(
         self.logger,
         self._extractPKCS12Certificate(pkcs12),
         pki_utils.x509_load_cert(
             oenginecons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_CA_CERT),
         name,
         extract,
     )
Exemplo n.º 4
0
    def _miscUpgrade(self):
        #
        # In <3.6 setup did not store the organization and
        # country in post install file. Load it from CA certificate.
        #
        if self.environment[oenginecons.PKIEnv.ORG] is None:
            ca = pki_utils.x509_load_cert(
                oenginecons.FileLocations.
                OVIRT_ENGINE_PKI_ENGINE_CA_CERT
            )
            self.environment[
                oenginecons.PKIEnv.ORG
            ] = ca.subject.get_attributes_for_oid(
                x509.oid.NameOID.ORGANIZATION_NAME
            )[0].value
            self.environment[
                oenginecons.PKIEnv.COUNTRY
            ] = ca.subject.get_attributes_for_oid(
                x509.oid.NameOID.COUNTRY_NAME
            )[0].value

        self.logger.info(_('Upgrading CA'))

        #
        # LEGACY NOTE
        # Since 3.0 and maybe before the method of
        # allowing user to override AIA was to explict
        # edit files. Until we rewrite the entire PKI
        # we must preserve this approach.
        # The template may change over time, so regenerate.
        #
        def _template_aia(template):
            aia = None
            if os.path.exists(template):
                with open(template) as f:
                    PREFIX = 'caIssuers;URI:'
                    for line in f.read().splitlines():
                        if line.startswith('authorityInfoAccess'):
                            aia = line[line.find(PREFIX)+len(PREFIX):]
                            break
            return aia

        engine_aia = _template_aia(_CERT_TEMPLATE)
        qemu_aia = _template_aia(_QEMU_CERT_TEMPLATE)
        if qemu_aia is None:
            qemu_aia = self._calculated_aia(
                oenginecons.Const.ENGINE_PKI_QEMU_CA_URI
            )

        if engine_aia and 'resource=qemu-ca-certificate' in engine_aia:
            # In the past, we had a single template for both engine and qemu
            # CAs, and it pointed at qemu cert.
            uninstall_info = self.environment[
                osetupcons.CoreEnv.UNINSTALL_FILES_INFO
            ].get(_CERT_TEMPLATE)
            if uninstall_info and not uninstall_info.get("changed"):
                # It was written by engine-setup and not changed since.
                # It should be safe to replace it.
                engine_aia = self._calculated_aia(
                    oenginecons.Const.ENGINE_PKI_CA_URI
                )
                self.logger.info(_('Fixing {}'.format(_CERT_TEMPLATE)))
                self.dialog.note(_(
                    'This does not fix existing certificates.'
                ))
            else:
                self.logger.warn(
                    _(
                        '{template} has wrong data, but was manually changed '
                        'after previous engine-setup'
                    ).format(
                        template=_CERT_TEMPLATE,
                    )
                )
                self.dialog.note(_('Not fixing it.'))
            self.dialog.note(_(
                'Please see also: https://bugzilla.redhat.com/1875386'
            ))

        uninstall_files = []
        self._setupUninstall(uninstall_files)
        self._update_templates(
            engine_aia,
            _ENGINE_TEMPLATES_MAP,
            uninstall_files,
        )
        self._update_templates(
            qemu_aia,
            _QEMU_TEMPLATES_MAP,
            uninstall_files,
        )

        if self.environment[oenginecons.PKIEnv.RENEW]:
            for ca_file in self._CA_FILES:
                if (
                    os.path.exists(ca_file) and
                    pki_utils.cert_expires(pki_utils.x509_load_cert(ca_file))
                ):
                    self._renewed_ca_files.add(ca_file)
                    self.logger.info(_('Renewing CA: %s'), ca_file)
                    args = (
                        oenginecons.FileLocations.OVIRT_ENGINE_PKI_CA_CREATE,
                        '--renew',
                        '--keystore-password=%s' % (
                            self.environment[oenginecons.PKIEnv.STORE_PASS],
                        ),
                        '--ca-file=%s' % (self._ca_file_name(ca_file),),
                    )
                    self.execute(
                        args=args,
                        envAppend={
                            'JAVA_HOME': self.environment[
                                oengcommcons.ConfigEnv.JAVA_HOME
                            ],
                        },
                    )

            self._enrollCertificates(True, uninstall_files)

        # Also enroll missing parts on upgrade
        # We check just Engine CA, QEMU certificates are only on hosts
        if os.path.exists(
                oenginecons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_CA_CERT
        ):
            self._enrollCertificates(False, uninstall_files)
Exemplo n.º 5
0
    def enroll_cert(self):
        self.logger.debug('enroll_cert')

        cert = None
        self._need_cert = True
        if os.path.exists(self._cert_file):
            self._need_cert = False
            cert = pki_utils.x509_load_cert(self._cert_file)
            if pki_utils.ok_to_renew_cert(
                    self.logger,
                    cert,
                    None,
                    self._base_name,
                    True,
            ):
                self._need_cert = True

        private_key = None
        self._need_key = True
        if os.path.exists(self._key_file):
            with open(self._key_file, 'rb') as f:
                private_key = serialization.load_pem_private_key(
                    f.read(),
                    password=None,
                    backend=default_backend(),
                )
            self._need_key = False
        else:
            self._need_cert = True

        self._key, self._csr, self._pubkey = self._genCsr(private_key)

        if self._need_cert:
            self._remote_name = '{name}-{fqdn}'.format(
                name=self._base_name,
                fqdn=self.environment[osetupcons.ConfigEnv.FQDN],
            )
            self._enroll_command = (
                " /usr/share/ovirt-engine/bin/pki-enroll-request.sh \\\n"
                "     --name={remote_name} \\\n"
                "     --subject=\""
                "$(openssl x509 -in {engine_ca_cert_file} -text "
                "| sed -n 's; *DirName:\\(.*\\)/CN=.*;\\1;p')"
                "/CN={fqdn}\" \\\n"
                "     --san=DNS:{fqdn}").format(
                    remote_name=self._remote_name,
                    engine_ca_cert_file=self._engine_ca_cert_file,
                    fqdn=self.environment[osetupcons.ConfigEnv.FQDN],
                )
            self._remote_engine.configure(fqdn=self._engine_fqdn)
            # TODO
            # This is ugly - we rely on having these two plugins
            # and do not support others. A good fix will:
            # 1. Be completely pluggable
            # 2. Will not duplicate the code in this function
            # 3. Will be nice to the user in every style
            # 4. Have a clearly-defined interface where relevant
            # Perhaps we'll have to give up on some of these, not sure
            # Also, for the meantime, we might/should implement
            # manual_inline and have another function for that,
            # or perhaps make _enroll_cert_manual_files work with both.
            cert = {
                osetupcons.Const.REMOTE_ENGINE_SETUP_STYLE_AUTO_SSH:
                (self._enroll_cert_auto_ssh),
                osetupcons.Const.REMOTE_ENGINE_SETUP_STYLE_MANUAL_FILES:
                (self._enroll_cert_manual_files),
            }[self._remote_engine.style().name]()
        self._cert = cert
Exemplo n.º 6
0
def _refresh_needed(cert_path, check_cert=True):
    ca_cert_path = oenginecons.FileLocations.OVIRT_ENGINE_PKI_ENGINE_CA_CERT
    return (not os.path.exists(cert_path)
            or os.stat(ca_cert_path).st_mtime > os.stat(cert_path).st_mtime or
            (check_cert
             and pki_utils.cert_expires(pki_utils.x509_load_cert(cert_path))))