Пример #1
0
    def request_cert(
            self,
            csr_server,
            fully_qualified_local_identity,
            discovery_info
    ):
        """
        Get a signed csr from the csr_server endpoint

        This method will create a csr request that is going to be sent to the
        signing server.

        :param csr_server: the http(s) location of the server to connect to.
        :return:
        """
        if get_messagebus() != "rmq":
            raise ValueError(
                "Only can create csr for rabbitmq based platform in ssl mode."
            )

        # from volttron.platform.web import DiscoveryInfo
        config = RMQConfig()

        if not config.is_ssl:
            raise ValueError(
                "Only can create csr for rabbitmq based platform in ssl mode."
            )

        # info = discovery_info
        # if info is None:
        #     info = DiscoveryInfo.request_discovery_info(csr_server)

        certs = Certs()
        csr_request = certs.create_csr(
            fully_qualified_local_identity, discovery_info.instance_name
        )
        # The csr request requires the fully qualified identity that is
        # going to be connected to the external instance.
        #
        # The remote instance id is the instance name of the remote platform
        # concatenated with the identity of the local fully quallified
        # identity.
        remote_cert_name = "{}.{}".format(
            discovery_info.instance_name, fully_qualified_local_identity
        )
        remote_ca_name = discovery_info.instance_name + "_ca"

        # if certs.cert_exists(remote_cert_name, True):
        #     return certs.cert(remote_cert_name, True)

        json_request = dict(
            csr=csr_request.decode("utf-8"),
            identity=remote_cert_name,
            # get_platform_instance_name()+"."+self._core().identity,
            hostname=config.hostname,
        )
        request = grequests.post(
            csr_server + "/csr/request_new",
            json=jsonapi.dumps(json_request),
            verify=False,
        )
        response = grequests.map([request])

        if response and isinstance(response, list):
            response[0].raise_for_status()
        response = response[0]
        # response = requests.post(csr_server + "/csr/request_new",
        #                          json=jsonapi.dumps(json_request),
        #                          verify=False)

        _log.debug("The response: %s", response)

        j = response.json()
        status = j.get("status")
        cert = j.get("cert")
        message = j.get("message", "")
        remote_certs_dir = self.get_remote_certs_dir()
        if status == "SUCCESSFUL" or status == "APPROVED":
            certs.save_agent_remote_info(
                remote_certs_dir,
                fully_qualified_local_identity,
                remote_cert_name,
                cert.encode("utf-8"),
                remote_ca_name,
                discovery_info.rmq_ca_cert.encode("utf-8"),
            )
            os.environ["REQUESTS_CA_BUNDLE"] = os.path.join(
                remote_certs_dir, "requests_ca_bundle"
            )
            _log.debug(
                "Set os.environ requests ca bundle to %s",
                os.environ["REQUESTS_CA_BUNDLE"],
            )
        elif status == "PENDING":
            _log.debug("Pending CSR request for {}".format(remote_cert_name))
        elif status == "DENIED":
            _log.error("Denied from remote machine.  Shutting down agent.")
            status = Status.build(
                BAD_STATUS,
                context="Administrator denied remote "
                "connection.  "
                "Shutting down",
            )
            self._owner.vip.health.set_status(status.status, status.context)
            self._owner.vip.health.send_alert(
                self._core().identity + "_DENIED", status
            )
            self._core().stop()
            return None
        elif status == "ERROR":
            err = "Error retrieving certificate from {}\n".format(
                config.hostname
            )
            err += "{}".format(message)
            raise ValueError(err)
        else:  # No resposne
            return None

        certfile = os.path.join(remote_certs_dir, remote_cert_name + ".crt")
        if os.path.exists(certfile):
            return certfile
        else:
            return status, message
Пример #2
0
    def request_cert(self, csr_server, fully_qualified_local_identity,
                     discovery_info):
        """ Get a signed csr from the csr_server endpoint

        This method will create a csr request that is going to be sent to the
        signing server.

        :param csr_server: the http(s) location of the server to connect to.
        :return:
        """

        if get_messagebus() != 'rmq':
            raise ValueError(
                "Only can create csr for rabbitmq based platform in ssl mode.")

        # from volttron.platform.web import DiscoveryInfo
        config = RMQConfig()

        if not config.is_ssl:
            raise ValueError(
                "Only can create csr for rabbitmq based platform in ssl mode.")

        # info = discovery_info
        # if info is None:
        #     info = DiscoveryInfo.request_discovery_info(csr_server)

        certs = Certs()
        csr_request = certs.create_csr(fully_qualified_local_identity,
                                       discovery_info.instance_name)
        # The csr request requires the fully qualified identity that is
        # going to be connected to the external instance.
        #
        # The remote instance id is the instance name of the remote platform
        # concatenated with the identity of the local fully quallified identity.
        remote_cert_name = "{}.{}".format(discovery_info.instance_name,
                                          fully_qualified_local_identity)
        remote_ca_name = discovery_info.instance_name + "_ca"

        # if certs.cert_exists(remote_cert_name, True):
        #     return certs.cert(remote_cert_name, True)

        json_request = dict(
            csr=csr_request,
            identity=
            remote_cert_name,  # get_platform_instance_name()+"."+self._core().identity,
            hostname=config.hostname)
        response = requests.post(csr_server + "/csr/request_new",
                                 json=json.dumps(json_request),
                                 verify=False)

        _log.debug("The response: {}".format(response))
        # from pprint import pprint
        # pprint(response.json())
        j = response.json()
        status = j.get('status')
        cert = j.get('cert')
        message = j.get('message', '')

        if status == 'SUCCESSFUL' or status == 'APPROVED':
            certs.save_remote_info(fully_qualified_local_identity,
                                   remote_cert_name, cert, remote_ca_name,
                                   discovery_info.rmq_ca_cert)

        elif status == 'PENDING':
            _log.debug("Pending CSR request for {}".format(remote_cert_name))
        elif status == 'DENIED':
            _log.error("Denied from remote machine.  Shutting down agent.")
            status = Status.build(
                BAD_STATUS,
                context="Administrator denied remote connection.  Shutting down"
            )
            self._owner.vip.health.set_status(status.status, status.context)
            self._owner.vip.health.send_alert(
                self._core().identity + "_DENIED", status)
            self._core().stop()
            return None
        elif status == 'ERROR':
            err = "Error retrieving certificate from {}\n".format(
                config.hostname)
            err += "{}".format(message)
            raise ValueError(err)
        else:  # No resposne
            return None

        certfile = certs.cert_file(remote_cert_name, remote=True)

        if certs.cert_exists(remote_cert_name, remote=True):
            return certfile
        else:
            return status, message