def certs_profile_1(certificate_dir, fqdn=None, num_server_certs=1, num_client_certs=3): """ Profile 1 generates the specified number of server and client certificates all signed by the same self-signed certificate. Usage: with certs_profile_1("/tmp/abc", 1, 2) as certs: ... :param certificate_dir: :return: """ certs = Certs(certificate_dir) data = { 'C': 'US', 'ST': 'Washington', 'L': 'Richland', 'O': 'pnnl', 'OU': 'volttron_test', 'CN': "myca" } ca_cert, ca_pk = certs.create_root_ca(**data) ns = SimpleNamespace(ca_cert=ca_cert, ca_key=ca_pk, ca_cert_file=certs.cert_file(certs.root_ca_name), ca_key_file=certs.private_key_file( certs.root_ca_name), server_certs=[], client_certs=[]) for x in range(num_server_certs): cert, key = certs.create_signed_cert_files(f"server{x}", cert_type="server", fqdn=fqdn) cert_ns = SimpleNamespace( key=key, cert=cert, cert_file=certs.cert_file(f"server{x}"), key_file=certs.private_key_file(f"server{x}")) ns.server_certs.append(cert_ns) for x in range(num_client_certs): cert, pk1 = certs.create_signed_cert_files(f"client{x}") cert_ns = SimpleNamespace( key=pk1, cert=cert, cert_file=certs.cert_file(f"client{x}"), key_file=certs.private_key_file(f"client{x}")) ns.client_certs.append(cert_ns) yield ns
def test_certificate_directories(temp_volttron_home): certs = Certs() paths = (certs.certs_pending_dir, certs.private_dir, certs.cert_dir, certs.remote_cert_dir, certs.csr_pending_dir, certs.ca_db_dir) for p in paths: assert os.path.exists(p)
def __init__(self, rmq_mgmt, ssl_public_key): self._rmq_mgmt = rmq_mgmt self._ssl_public_key = ssl_public_key self._userdict = None self.reload_userdict() self._observer = Observer() self._observer.schedule( FileReloader("web-users.json", self.reload_userdict), get_home()) self._observer.start() self._certs = Certs()
def vip_main(agent_class, identity=None, version='0.1', **kwargs): """Default main entry point implementation for VIP agents.""" try: # If stdout is a pipe, re-open it line buffered if isapipe(sys.stdout): # Hold a reference to the previous file object so it doesn't # get garbage collected and close the underlying descriptor. stdout = sys.stdout sys.stdout = os.fdopen(stdout.fileno(), 'w', 1) # Quiet printing of KeyboardInterrupt by greenlets Hub = gevent.hub.Hub Hub.NOT_ERROR = Hub.NOT_ERROR + (KeyboardInterrupt, ) config = os.environ.get('AGENT_CONFIG') identity = os.environ.get('AGENT_VIP_IDENTITY', identity) message_bus = os.environ.get('MESSAGEBUS', 'zmq') if identity is not None: if not is_valid_identity(identity): _log.warning('Deprecation warining') _log.warning( 'All characters in {identity} are not in the valid set.'. format(idenity=identity)) address = get_address() agent_uuid = os.environ.get('AGENT_UUID') volttron_home = get_home() from volttron.platform.certs import Certs certs = Certs() agent = agent_class(config_path=config, identity=identity, address=address, agent_uuid=agent_uuid, volttron_home=volttron_home, version=version, message_bus=message_bus, **kwargs) try: run = agent.run except AttributeError: run = agent.core.run task = gevent.spawn(run) try: task.join() finally: task.kill() except KeyboardInterrupt: pass
def certs_profile_2(certificate_dir, fqdn=None, num_server_certs=1, num_client_certs=3): """ Profile 2 generates the specified number of server and client certificates all signed by the same self-signed certificate. Usage: certs = certs_profile_1("/tmp/abc", 1, 2) ... :param certificate_dir: :return: ns """ certs = Certs(certificate_dir) data = {'C': 'US', 'ST': 'Washington', 'L': 'Richland', 'O': 'pnnl', 'OU': 'volttron_test', 'CN': "myca"} if not certs.ca_exists(): ca_cert, ca_pk = certs.create_root_ca(**data) # If the root ca already exists, get ca_cert and ca_pk from current root ca else: ca_cert = certs.cert(certs.root_ca_name) ca_pk = _load_key(certs.private_key_file(certs.root_ca_name)) # print(f"ca_cert: {ca_cert}") # print(f"ca_pk: {ca_pk}") # print(f"ca_pk_bytes: {certs.get_pk_bytes(certs.root_ca_name)}") ns = dict(ca_cert=ca_cert, ca_key=ca_pk, ca_cert_file=certs.cert_file(certs.root_ca_name), ca_key_file=certs.private_key_file(certs.root_ca_name), server_certs=[], client_certs=[]) for x in range(num_server_certs): cert, key = certs.create_signed_cert_files(f"server{x}", cert_type="server", fqdn=fqdn) cert_ns = dict(key=key, cert=cert, cert_file=certs.cert_file(f"server{x}"), key_file=certs.private_key_file(f"server{x}")) ns['server_certs'].append(cert_ns) for x in range(num_client_certs): cert, pk1 = certs.create_signed_cert_files(f"client{x}") cert_ns = dict(key=pk1, cert=cert, cert_file=certs.cert_file(f"client{x}"), key_file=certs.private_key_file(f"client{x}")) ns['client_certs'].append(cert_ns) return ns
def setup(self): """Creates paths for used directories for the instance.""" for path in [self.run_dir, self.config_dir, self.install_dir]: if not os.path.exists(path): # others should have read and execute access to these directory # so explicitly set to 755. _log.debug("Setting up 755 permissions for path {}".format( path)) os.makedirs(path) os.chmod(path, 0o755) # Create certificates directory and its subdirectory at start of platform # so if volttron is run in secure mode, the first agent install would already have # the directories ready. In secure mode, agents will be run as separate user and will # not have access to create these directories Certs()
def __init__(self, serverkey, identity, address, bind_web_address, aip, volttron_central_address=None, volttron_central_rmq_address=None, web_ssl_key=None, web_ssl_cert=None, **kwargs): """Initialize the discovery service with the serverkey serverkey is the public key in order to access this volttron's bus. """ super(MasterWebService, self).__init__(identity, address, **kwargs) self.bind_web_address = bind_web_address self.serverkey = serverkey self.instance_name = None self.registeredroutes = [] self.peerroutes = defaultdict(list) self.pathroutes = defaultdict(list) # These will be used if set rather than the # any of the internal agent's certificates self.web_ssl_key = web_ssl_key self.web_ssl_cert = web_ssl_cert # Maps from endpoint to peer. self.endpoints = {} self.aip = aip self.volttron_central_address = volttron_central_address self.volttron_central_rmq_address = volttron_central_rmq_address # If vc is this instance then make the vc address the same as # the web address. if not self.volttron_central_address: self.volttron_central_address = bind_web_address if not mimetypes.inited: mimetypes.init() self._certs = Certs() self._csr_endpoints = None self.appContainer = None self._server_greenlet = None self._admin_endpoints = None
def __init__(self, **kwargs): self.discovery_address = kwargs.pop('discovery_address') self.vip_address = kwargs.pop('vip-address', None) self.serverkey = kwargs.pop('serverkey', None) self.instance_name = kwargs.pop('instance-name') try: self.rmq_address = kwargs.pop('rmq-address') except KeyError: self.messagebus_type = 'zmq' else: self.messagebus_type = 'rmq' try: self.rmq_ca_cert = kwargs.pop('rmq-ca-cert') except KeyError: self.messagebus_type = 'zmq' else: self.messagebus_type = 'rmq' self.certs = Certs() assert len(kwargs) == 0
def __init__(self, core): self._core = weakref.ref(core) self._certs = Certs() self._auto_allow_csr = False
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
def test_create_root_ca(temp_volttron_home): certs = Certs() assert not certs.ca_exists() certs.create_root_ca() assert certs.ca_exists()
def get_user_claim_from_bearer(bearer): certs = Certs() pubkey = certs.get_cert_public_key(get_fq_identity(MASTER_WEB)) return jwt.decode(bearer, pubkey, algorithms='RS256')
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