예제 #1
0
    def post(self, certpath):
        uploaded_file = request.files["file"]
        if not uploaded_file:
            raise InvalidRequest("Missing certificate file")

        # Save the certificate.
        certpath = pathvalidate.sanitize_filename(certpath)
        if not certpath.endswith(".crt"):
            raise InvalidRequest("Invalid certificate file: must have suffix `.crt`")

        logger.debug("Saving custom certificate %s", certpath)
        cert_full_path = config_provider.get_volume_path(EXTRA_CA_DIRECTORY, certpath)
        config_provider.save_volume_file(cert_full_path, uploaded_file)
        logger.debug("Saved custom certificate %s", certpath)

        # Validate the certificate.
        try:
            logger.debug("Loading custom certificate %s", certpath)
            with config_provider.get_volume_file(cert_full_path) as f:
                load_certificate(f.read())
        except CertInvalidException:
            logger.exception("Got certificate invalid error for cert %s", certpath)
            return "", 204
        except IOError:
            logger.exception("Got IO error for cert %s", certpath)
            return "", 204

        # Call the update script with config dir location to install the certificate immediately.
        if not app.config["TESTING"]:
            cert_dir = os.path.join(config_provider.get_config_dir_path(), EXTRA_CA_DIRECTORY)
            if (
                subprocess.call(
                    [os.path.join(INIT_SCRIPTS_LOCATION, "certs_install.sh")],
                    env={"CERTDIR": cert_dir},
                )
                != 0
            ):
                raise Exception("Could not install certificates")

        return "", 204
예제 #2
0
    def get(self):
        has_extra_certs_path = config_provider.volume_file_exists(
            EXTRA_CA_DIRECTORY)
        extra_certs_found = config_provider.list_volume_directory(
            EXTRA_CA_DIRECTORY)
        if extra_certs_found is None:
            return {
                "status": "file" if has_extra_certs_path else "none",
            }

        cert_views = []
        for extra_cert_path in extra_certs_found:
            try:
                cert_full_path = config_provider.get_volume_path(
                    EXTRA_CA_DIRECTORY, extra_cert_path)
                with config_provider.get_volume_file(cert_full_path) as f:
                    certificate = load_certificate(f.read())
                    cert_views.append({
                        "path": extra_cert_path,
                        "names": list(certificate.names),
                        "expired": certificate.expired,
                    })
            except CertInvalidException as cie:
                cert_views.append({
                    "path": extra_cert_path,
                    "error": cie.message,
                })
            except IOError as ioe:
                cert_views.append({
                    "path": extra_cert_path,
                    "error": ioe.message,
                })

        return {
            "status": "directory",
            "certs": cert_views,
        }
예제 #3
0
    def post(self, certpath):
        uploaded_file = request.files["file"]
        if not uploaded_file:
            raise InvalidRequest("Missing certificate file")

        # Save the certificate.
        certpath = pathvalidate.sanitize_filename(certpath)
        if not certpath.endswith(".crt"):
            raise InvalidRequest(
                "Invalid certificate file: must have suffix `.crt`")

        logger.debug("Saving custom certificate %s", certpath)
        cert_full_path = config_provider.get_volume_path(
            EXTRA_CA_DIRECTORY, certpath)
        filename = config_provider.save_volume_file(cert_full_path,
                                                    uploaded_file)
        logger.debug("Saved custom certificate %s to %s", certpath, filename)

        # Validate the certificate.
        try:
            logger.debug("Loading custom certificate %s", certpath)
            with config_provider.get_volume_file(cert_full_path) as f:
                load_certificate(f.read())
        except CertInvalidException:
            logger.exception("Got certificate invalid error for cert %s",
                             certpath)
            return "", 204
        except IOError:
            logger.exception("Got IO error for cert %s", certpath)
            return "", 204

        # Call the update script with config dir location to install the certificate immediately.
        # This is needed by the configuration application to verify connections to external services
        # which require a self-signed or otherwise user-managed certificate.
        if not app.config["TESTING"]:

            try:
                cert_dir = os.path.join(config_provider.get_config_dir_path(),
                                        EXTRA_CA_DIRECTORY)
                script_env = {"CERTDIR": cert_dir}
                logger.debug("Installing certificates from the directory: %s" %
                             cert_dir)

                script_filename = os.path.join(INIT_SCRIPTS_LOCATION,
                                               "certs_install.sh")
                logger.debug("Running script to install all certificates: %s",
                             script_filename)

                process = Popen([script_filename],
                                stderr=PIPE,
                                stdout=PIPE,
                                env=script_env)
                output, err = process.communicate()
                return_code = process.returncode

                if return_code != 0:
                    raise Exception(
                        "Could not install certificates. Output: %s" % output)
                else:
                    logger.debug(
                        "Successfully installed certificates. Output: %s",
                        output)

            except Exception as e:
                logger.exception(
                    "Unable to install certificates. Unexpected error: %s", e)

        else:
            msg = (
                "Quay is using the test configuration. Certificates will not be installed. "
                "This may break the configuration app's ability to verify certificates."
            )
            logger.warning(msg)

        return "", 204