示例#1
0
    def generate_new_csr_done(self, results, args):
        """
        Our CSR has been generated. Lets save it, and maybe submit it.

        :param results: The CSR and KEY.
        :param args: Any args from the queue.
        :param submit: True if we should submit it to yombo for signing.
        :return:
        """
        # logger.warn("generate_new_csr_done: {sslname}", sslname=self.sslname)
        results = bytes_to_unicode(results)
        # logger.info("generate_new_csr_done:results: results {results}", results=results)
        # logger.info("generate_new_csr_done:results: args {results}", results=args)
        self.next_key = results['key']
        self.next_csr = results['csr']
        # print("generate_new_csr_done csr: %s " % self.next_csr)
        yield save_file('usr/etc/certs/%s.next.csr.pem' % self.sslname,
                        self.next_csr)
        yield save_file('usr/etc/certs/%s.next.key.pem' % self.sslname,
                        self.next_key)
        self.next_created = int(time())
        self.dirty = True
        self.next_csr_generation_in_progress = False
        logger.debug("generate_new_csr_done:args: {args}", args=args)
        if args['submit'] is True:
            # print("calling submit_csr from generate_new_csr_done")
            self.submit_csr()
示例#2
0
    def generate_csr(self, args):
        """
        This function shouldn't be called directly. Instead, use the queue
        "self.generate_csr_queue.put(request, callback, callback_args)" or
        "self._SSLCerts.generate_csr_queue.put()".
        
        Requests certs to be made. Will return right away with a request ID. A callback can be set to return
        the cert once it's complete.

        :return:
        """
        logger.info("Generate_CSR called with args: {args}", args=args)
        kwargs = self.check_csr_input(args)

        if kwargs['key_type'] == 'rsa':
            kwargs['key_type'] = crypto.TYPE_RSA
        else:
            kwargs['key_type'] = crypto.TYPE_DSA

        gwid = "gw_%s" % self.gateway_id[0:10]
        req = crypto.X509Req()
        req.get_subject().CN = kwargs['cn']
        req.get_subject().countryName = 'US'
        req.get_subject().stateOrProvinceName = 'California'
        req.get_subject().localityName = 'Sacramento'
        req.get_subject().organizationName = 'Yombo'
        req.get_subject().organizationalUnitName = gwid

        # Appends SAN to have 'DNS:'
        if kwargs['sans'] is not None:
            san_string = []
            for i in kwargs['sans']:
                san_string.append("DNS: %s" % i)
            san_string = ", ".join(san_string)

            x509_extensions = [
                crypto.X509Extension(b'subjectAltName', False,
                                     unicode_to_bytes(san_string))
            ]
            req.add_extensions(x509_extensions)

        key = yield threads.deferToThread(
            self._generate_key, **{
                'key_type': kwargs['key_type'],
                'key_size': kwargs['key_size']
            })
        req.set_pubkey(key)

        req.sign(key, "sha256")

        csr = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
        key_file = crypto.dump_privatekey(crypto.FILETYPE_PEM, key)

        if kwargs['csr_file'] is not None:
            save_file(kwargs['csr_file'], csr)
        if kwargs['key_file'] is not None:
            save_file(kwargs['key_file'], key_file)

        return {'csr': csr, 'key': key_file}
    def _create_self_signed_cert(self):
        """
        Creates a self signed cert. Shouldn't be called directly except by this library for its
        own use.
        """
        logger.debug("Creating self signed cert.")
        req = crypto.X509()

        req.get_subject().CN = "localhost"
        req.get_subject().countryName = "US"
        req.get_subject().stateOrProvinceName = "California"
        req.get_subject().localityName = "Self Signed"
        req.get_subject().organizationName = "Yombo"
        req.get_subject(
        ).organizationalUnitName = f"Gateway {self.gateway_id[0:15]} Self Signed"

        req.set_serial_number(int(time()))
        req.gmtime_adj_notBefore(0)
        req.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
        self.self_signed_expires_at = time() + (10 * 365 * 24 * 60 * 60)
        self.self_signed_created_at = time()
        self._Configs.set("sslcerts", "self_signed_expires_at",
                          self.self_signed_expires_at)
        self._Configs.set("sslcerts", "self_signed_created_at",
                          self.self_signed_created_at)
        req.set_issuer(req.get_subject())
        key = yield threads.deferToThread(
            self._generate_key, **{
                "key_type": crypto.TYPE_RSA,
                "key_size": self.default_key_size
            })
        req.set_pubkey(key)
        req.sign(key, "sha256")

        csr_key = crypto.dump_certificate(crypto.FILETYPE_PEM, req)
        key_file = crypto.dump_privatekey(crypto.FILETYPE_PEM, key)

        yield save_file(self.self_signed_cert_file, csr_key)
        yield save_file(self.self_signed_key_file, key_file)

        return {"csr_key": csr_key, "key": key_file}
示例#4
0
    def _create_self_signed_cert(self):
        """
        Creates a self signed cert. Shouldn't be called directly except by this library for its
        own use.
        """
        logger.debug("Creating self signed cert.")
        req = crypto.X509()
        gwid = "%s %s" % (self.gateway_id, self.hostname)
        req.get_subject().CN = 'localhost'
        req.get_subject().countryName = 'US'
        req.get_subject().stateOrProvinceName = 'California'
        req.get_subject().localityName = 'Sacramento'
        req.get_subject().organizationName = 'Yombo'
        req.get_subject().organizationalUnitName = gwid[0:63]

        req.set_serial_number(int(time()))
        req.gmtime_adj_notBefore(0)
        req.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60)
        self.self_signed_expires = time() + (10 * 365 * 24 * 60 * 60)
        self.self_signed_created = time()
        self._Configs.set("sslcerts", "self_signed_expires",
                          self.self_signed_expires)
        self._Configs.set("sslcerts", "self_signed_created",
                          self.self_signed_created)
        req.set_issuer(req.get_subject())
        key = yield threads.deferToThread(
            self._generate_key, **{
                'key_type': crypto.TYPE_RSA,
                'key_size': 4096
            })
        req.set_pubkey(key)
        req.sign(key, 'sha256')

        csr_key = crypto.dump_certificate(crypto.FILETYPE_PEM, req)
        key_file = crypto.dump_privatekey(crypto.FILETYPE_PEM, key)

        save_file(self.self_signed_cert_file, csr_key)
        save_file(self.self_signed_key_file, key_file)

        return {'csr_key': csr_key, 'key': key_file}
    def generate_csr(self, args):
        """
        This function shouldn't be called directly. Instead, use the queue
        "self.generate_csr_queue.put(request, callback, callback_args)" or
        "self._SSLCerts.generate_csr_queue.put()".
        
        Requests certs to be made. Will return right away with a request ID. A callback can be set to return
        the cert once it's complete.

        :return:
        """
        logger.debug("Generate_CSR called with args: {args}", args=args)
        kwargs = self.check_csr_input(args)

        if kwargs["key_type"] == "rsa":
            kwargs["key_type"] = crypto.TYPE_RSA
        else:
            kwargs["key_type"] = crypto.TYPE_DSA

        req = crypto.X509Req()
        req.get_subject().CN = kwargs["cn"]
        req.get_subject().countryName = "US"
        req.get_subject().stateOrProvinceName = "California"
        req.get_subject().localityName = "Sacramento"
        req.get_subject().organizationName = "Yombo"
        req.get_subject(
        ).organizationalUnitName = "Gateway " + self.gateway_id[0:15]

        # Appends SAN to have "DNS:"
        if kwargs["sans"] is not None:
            san_string = []
            for i in kwargs["sans"]:
                san_string.append(f"DNS: {i}")
            san_string = ", ".join(san_string)
            x509_extensions = [
                crypto.X509Extension(b"subjectAltName", False,
                                     unicode_to_bytes(san_string))
            ]
            req.add_extensions(x509_extensions)

        start = time()
        key = yield threads.deferToThread(
            self._generate_key, **{
                "key_type": kwargs["key_type"],
                "key_size": kwargs["key_size"]
            })
        duration = round(float(time()) - start, 4)
        self._Events.new("sslcerts", "generate_new",
                         (args["sslname"], kwargs["cn"], san_string, duration))

        req.set_pubkey(key)

        req.sign(key, "sha256")

        csr = crypto.dump_certificate_request(crypto.FILETYPE_PEM, req)
        key_file = crypto.dump_privatekey(crypto.FILETYPE_PEM, key)

        if kwargs["csr_file"] is not None:
            yield save_file(kwargs["csr_file"], csr)
        if kwargs["key_file"] is not None:
            yield save_file(kwargs["key_file"], key_file)

        return {
            "csr": csr,
            "csr_hash": sha256_compact(unicode_to_bytes(csr)),
            "key": key_file
        }
示例#6
0
 def save_configs(self):
     yield save_file('%s/config.json' % self.module_path,
                     json.dumps(self.config_file, indent=4))
    def _save_common(self, helper, dest_parts, dest_parts_thumb, file_id,
                     mangle_id, expires, public, extra, **kwargs):
        """
        An internal function that saves the data.

        :param helper:
        :param dest_parts:
        :param dest_parts_thumb:
        :param file_id:
        :param mangle_id:
        :param expires:
        :param public:
        :param extra:
        :param kwargs:
        :return:
        """

        destination = urllib.parse.urlunparse(dest_parts)
        file_path = destination.split("://")[1].split("?")[0].split("#")[0]
        final_path = f"{self.storage_path}/{file_path}"
        if isinstance(
                extra,
                dict) and "absolute" in extra and extra["absolute"] is True:
            final_path = file_path

        image = yield helper.get()
        yield save_file(final_path, image.content)

        url = self.generate_url(dest_parts, file_id, mangle_id)
        results = {
            "internal_url": self._WebInterface.internal_url + url,
            "external_url": self._WebInterface.external_url + url,
            "file_path": final_path,
        }

        try:
            thumbnail = yield helper.thumbnail()
            destination = urllib.parse.urlunparse(dest_parts_thumb)
            file_path = destination.split("://")[1].split("?")[0].split("#")[0]
            final_path = f"{self.storage_path}/{file_path}"
            if isinstance(
                    extra, dict
            ) and "absolute" in extra and extra["absolute"] is True:
                final_path = file_path
            yield save_file(final_path, thumbnail.content)
            url = self.generate_url(dest_parts_thumb,
                                    file_id,
                                    mangle_id,
                                    thumb=True)
            results.update({
                "internal_thumb_url":
                self._WebInterface.internal_url + url,
                "external_thumb_url":
                self._WebInterface.external_url + url,
                "file_path_thumb":
                final_path,
            })
        except YomboWarning:
            pass

        return results
示例#8
0
    def save(self, force_save=False, display_extra_warning=False):
        """
        Save the configuration configs to the INI file.

        #Todo: convert to fdesc for non-blocking. Need example of usage.
        """
        try:
            # If for some reason startup fails, we won't get _() defined. We just try to print _() and test...
            logger.debug("saving config file...")

            if self.exit_config_file is not None:
                yield save_file(self.yombo_ini_path, self.exit_config_file)

            elif self.configs_dirty is True or force_save is True:
                contents = yield self.generate_yombo_ini(display_extra_warning)
                yield save_file(self.yombo_ini_path, contents)

            Config = configparser.ConfigParser()
            for section, options in self.configs.items():
                Config.add_section(section)
                for item, data in options.items():
                    temp = self.configs[section][item].copy()
                    if "details" in temp:
                        del temp["details"]
                    if "value" in temp:
                        del temp["value"]
                    Config.set(section, item,
                               b64encode(msgpack.dumps(temp)).decode())
                if len(Config.options(
                        section)) == 0:  # Don"t save empty sections.
                    Config.remove_section(section)

            config_file = open(f"{self.working_dir}/etc/yombo.ini.info", "w")
            config_file.write("#\n")
            config_file.write(
                "# This file stores meta information about yombo.ini. Do not edit manually!\n"
            )
            config_file.write("#\n")
            Config.write(config_file)
            config_file.close()

        except Exception as E:
            logger.warn("Caught master error in saving ini file: {e}", e=E)
            logger.error(
                "--------------------------------------------------------")
            logger.error("{error}", error=sys.exc_info())
            logger.error(
                "---------------==(Traceback)==--------------------------")
            logger.error("{trace}", trace=traceback.print_exc(file=sys.stdout))
            logger.error(
                "--------------------------------------------------------")

        self.configs_dirty = False

        file_path = f"{self.working_dir}/bak/yombo_ini/"

        backup_files = os.listdir(os.path.dirname(file_path))
        if len(backup_files) > 5:
            for file in backup_files:  # remove old yombo.ini backup files.
                fullpath = os.path.join(
                    file_path,
                    file)  # turns "file1.txt" into "/path/to/file1.txt"
                timestamp = os.stat(fullpath).st_ctime  # get timestamp of file
                createtime = datetime.fromtimestamp(timestamp)
                now = datetime.now()
                delta = now - createtime
                if delta.days > 30:
                    os.remove(fullpath)
示例#9
0
    def _sync_to_filesystem(self):
        for label in ['current', 'next']:

            meta = {
                'created': getattr(self, "%s_created" % label),
                'expires': getattr(self, "%s_expires" % label),
                'signed': getattr(self, "%s_signed" % label),
                'submitted': getattr(self, "%s_submitted" % label),
                'fqdn': getattr(self, "%s_fqdn" % label),
                'key_type': self.key_type,
                'key_size': self.key_size,
            }

            if getattr(self, "%s_cert" % label) is None:
                meta['cert'] = None
                file = 'usr/etc/certs/%s.%s.cert.pem' % (self.sslname, label)
                if os.path.exists(file):
                    os.remove(file)
            else:
                meta['cert'] = sha256(
                    str(getattr(self, "%s_cert" %
                                label)).encode('utf-8')).hexdigest()
                yield save_file(
                    'usr/etc/certs/%s.%s.cert.pem' % (self.sslname, label),
                    getattr(self, "%s_cert" % label))

            if getattr(self, "%s_chain" % label) is None:
                meta['chain'] = None
                file = 'usr/etc/certs/%s.%s.chain.pem' % (self.sslname, label)
                if os.path.exists(file):
                    os.remove(file)
            else:
                meta['chain'] = sha256(
                    str(getattr(self, "%s_chain" %
                                label)).encode('utf-8')).hexdigest()
                yield save_file(
                    'usr/etc/certs/%s.%s.chain.pem' % (self.sslname, label),
                    getattr(self, "%s_chain" % label))

            if getattr(self, "%s_key" % label) is None:
                meta['key'] = None
                file = 'usr/etc/certs/%s.%s.key.pem' % (self.sslname, label)
                if os.path.exists(file):
                    os.remove(file)
            else:
                meta['key'] = sha256(
                    str(getattr(self, "%s_key" %
                                label)).encode('utf-8')).hexdigest()
                yield save_file(
                    'usr/etc/certs/%s.%s.key.pem' % (self.sslname, label),
                    getattr(self, "%s_key" % label))

            if label == 'next':
                if getattr(self, "%s_csr" % label) is None:
                    meta['csr'] = None
                    file = 'usr/etc/certs/%s.%s.csr.pem' % (self.sslname,
                                                            label)
                    if os.path.exists(file):
                        os.remove(file)
                else:
                    meta['csr'] = sha256(
                        str(getattr(self, "%s_csr" %
                                    label)).encode('utf-8')).hexdigest()
                    yield save_file(
                        'usr/etc/certs/%s.%s.csr.pem' % (self.sslname, label),
                        getattr(self, "%s_csr" % label))

            yield save_file('usr/etc/certs/%s.%s.meta' % (self.sslname, label),
                            json.dumps(meta, indent=4))

            yield save_file(
                'usr/etc/certs/%s.meta' % self.sslname,
                json.dumps({
                    'sans': self.sans,
                    'cn': self.cn,
                }, indent=4))
示例#10
0
    def generate_key(self, sync_when_done = None):
        """
        Generates a new GPG key pair. Updates yombo.ini and marks it to be sent when gateway
        connects to server again.
        """
        operating_mode = self._Loader.operating_mode
        if operating_mode != "run":
            logger.info("Not creating GPG key, in wrong run mode: {mode}", mode=operating_mode)

        if self._generating_key is True:
            return
        self._generating_key = True
        gwid = self.gateway_id
        gwuuid = self.gwuuid()
        if gwid is "local" or gwuuid is None:
            self.key_generation_status = "failed: gateway not setup, gateway id or uuid is missing"
            self._generating_key = False
            return
        passphrase = random_string(length=random_int(200, .1), char_set="extended")
        expire_date = "5y"
        # if self.debug_mode is True:
        #     logger.warn("Setting GPG key to expire in one day due to debug mode.")
        #     expire_date = "1d"
        input_data = self.gpg.gen_key_input(
            name_email=f"{gwid}@gw.gpg.yombo.net",
            name_real="Yombo Gateway",
            name_comment="Created by https://Yombo.net",
            key_type="RSA",
            key_length=4096,
            expire_date=expire_date,
            preferences="SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed",
            keyserver="hkp://gpg.nebrwesleyan.edu",
            revoker="1:9C69E1F8A7C39961C223C485BCEAA0E429FA3EF8",
            passphrase=passphrase)

        self.key_generation_status = "working"
        newkey = yield threads.deferToThread(self.do_generate_key, input_data)
        # print("bb 3: newkey: %s" % newkey)
        # print("bb 3: newkey: %s" % newkey.__dict__)
        # print("bb 3: newkey: %s" % type(newkey))
        self.key_generation_status = "done"

        if str(newkey) == "":
            logger.error("ERROR: Unable to generate GPG keys.... Is GPG installed and configured? Is it in your path?")
            self._generating_key = False
            raise YomboCritical("Error with python GPG interface.  Is it installed?")

        private_keys = yield self.get_keyring_keys(True)
        newfingerprint = ""

        for existing_key_id, key_data in private_keys.items():
            # print("inspecting key: %s" % existing_key_id)
            if key_data["fingerprint"] == str(newkey):
                newfingerprint = key_data["fingerprint"]
                break
        asciiArmoredPublicKey = self.gpg.export_keys(newfingerprint)
        print(f"saving new gpg fingerprint: {newfingerprint}")
        self._Configs.set("gpg", "fingerprint", newfingerprint)
        secret_file = f"{self._Atoms.get('working_dir')}/etc/gpg/{newfingerprint}.pass"
        # print("saveing pass to : %s" % secret_file)
        yield save_file(secret_file, passphrase)
        secret_file = f"{self._Atoms.get('working_dir')}/etc/gpg/last.pass"
        yield save_file(secret_file, passphrase)
        self.__mypassphrase = passphrase

        self._Configs.set("gpg", "last_sent_yombo", None)
        self._Configs.set("gpg", "last_sent_keyserver", None)
        self._Configs.set("gpg", "last_received_keyserver", None)

        yield self.sync_keyring_to_db()
        # self.send_my_gpg_key()
        #
        # gpg_keys = yield self.gpg.get_keyring_keys(keys=fingerprint)
        #
        # # print("keys: %s" % type(keys))
        # # print("newkey1: %s" % newkey)
        # print("newkey2: %s" % str(newkey))
        # print("keys: %s" % gpg_keys)
        #
        # mykey = gpg_keys[fingerprint]
        # mykey["publickey"] = asciiArmoredPublicKey
        # mykey["notes"] = "Autogenerated."
        # mykey["have_private"] = 1

        self._generating_key = False

        if self._generating_key_deferred is not None and self._generating_key_deferred.called is False:
            self._generating_key_deferred.callback(1)
示例#11
0
    def generate_key(self, sync_when_done=None):
        """
        Generates a new GPG key pair. Updates yombo.ini and marks it to be sent when gateway
        connects to server again.
        """
        operating_mode = self._Loader.operating_mode
        if operating_mode != "run":
            logger.info("Not creating GPG key, in wrong run mode: {mode}",
                        mode=operating_mode)

        if self._generating_key is True:
            return
        self._generating_key = True
        gwid = self.gateway_id()
        gwuuid = self.gwuuid()
        if gwid is 'local' or gwuuid is None:
            self.key_generation_status = 'failed-gateway not setup'
            self._generating_key = False
            return
        passphrase = random_string(length=120)
        expire_date = '1y'
        if self.debug_mode is True:
            logger.warn(
                'Setting GPG key to expire in one day due to debug mode.')
            expire_date = '1d'
        input_data = self.gpg.gen_key_input(
            name_email="*****@*****.**" % gwuuid,
            name_real="Yombo Gateway",
            name_comment="Created by https://Yombo.net Automation",
            key_type='RSA',
            key_length=4096,
            expire_date=expire_date,
            preferences=
            'SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed',
            keyserver='hkp://pool.sks-keyservers.net',
            revoker="1:9C69E1F8A7C39961C223C485BCEAA0E429FA3EF8",
            passphrase=passphrase)

        self.key_generation_status = 'working'
        newkey = yield threads.deferToThread(self._gen_key, input_data)
        # print("bb 3: newkey: %s" % newkey)
        # print("bb 3: newkey: %s" % newkey.__dict__)
        # print("bb 3: newkey: %s" % type(newkey))
        self.key_generation_status = 'done'

        if str(newkey) == '':
            logger.error(
                "ERROR: Unable to generate GPG keys.... Is GPG installed and configured? Is it in your path?"
            )
            self._generating_key = False
            raise YomboCritical(
                "Error with python GPG interface.  Is it installed?")

        private_keys = yield self.get_keyring_keys(True)
        newkeyid = ''

        for existing_key_id, key_data in private_keys.items():
            # print("inspecting key: %s" % existing_key_id)
            if key_data['fingerprint'] == str(newkey):
                newkeyid = key_data['keyid']
                break
        asciiArmoredPublicKey = self.gpg.export_keys(newkeyid)
        self._Configs.set('gpg', 'keyid', newkeyid)
        secret_file = "%s/usr/etc/gpg/%s.pass" % (
            self._Atoms.get('yombo.path'), newkeyid)
        # print("saveing pass to : %s" % secret_file)
        yield save_file(secret_file, passphrase)
        self.__mypassphrase = passphrase

        self._Configs.set('gpg', 'last_sent_yombo', None)
        self._Configs.set('gpg', 'last_sent_keyserver', None)
        self._Configs.set('gpg', 'last_received_keyserver', None)

        yield self.sync_keyring_to_db()
        # self.send_my_gpg_key()
        #
        # gpg_keys = yield self.gpg.get_keyring_keys(keys=keyid)
        #
        # # print("keys: %s" % type(keys))
        # # print("newkey1: %s" % newkey)
        # print("newkey2: %s" % str(newkey))
        # print("keys: %s" % gpg_keys)
        #
        # mykey = gpg_keys[keyid]
        # mykey['publickey'] = asciiArmoredPublicKey
        # mykey['notes'] = 'Autogenerated.'
        # mykey['have_private'] = 1

        self._generating_key = False

        if self._generating_key_deferred is not None and self._generating_key_deferred.called is False:
            self._generating_key_deferred.callback(1)
示例#12
0
    def _sync_to_file(self):
        """
        Sync current data to the file system. This allows for quick recovery if the database goes bad.
        :return:
        """
        logger.info("Backing up SSL Certs to file system.")

        for label in ['previous', 'current', 'next']:

            meta = {
                'created': getattr(self, "%s_created" % label),
                'expires': getattr(self, "%s_expires" % label),
                'signed': getattr(self, "%s_signed" % label),
                'submitted': getattr(self, "%s_submitted" % label),
                'key_type': self.key_type,
                'key_size': self.key_size,
            }

            if getattr(self, "cert_%s" % label) is None:
                meta['cert'] = None
                file = 'usr/etc/certs/%s.%s.cert.pem' % (self.sslname, label)
                if os.path.exists(file):
                    os.remove(file)
            else:
                meta['cert'] = sha256(
                    str(getattr(self, "cert_%s" %
                                label)).encode('utf-8')).hexdigest()
                save_file(
                    'usr/etc/certs/%s.%s.cert.pem' % (self.sslname, label),
                    getattr(self, "cert_%s" % label))

            if getattr(self, "chain_%s" % label) is None:
                meta['chain'] = None
                file = 'usr/etc/certs/%s.%s.chain.pem' % (self.sslname, label)
                if os.path.exists(file):
                    os.remove(file)
            else:
                meta['chain'] = sha256(
                    str(getattr(self, "chain_%s" %
                                label)).encode('utf-8')).hexdigest()
                save_file(
                    'usr/etc/certs/%s.%s.chain.pem' % (self.sslname, label),
                    getattr(self, "chain_%s" % label))

            if getattr(self, "key_%s" % label) is None:
                meta['key'] = None
                file = 'usr/etc/certs/%s.%s.key.pem' % (self.sslname, label)
                if os.path.exists(file):
                    os.remove(file)
            else:
                meta['key'] = sha256(
                    str(getattr(self, "key_%s" %
                                label)).encode('utf-8')).hexdigest()
                save_file(
                    'usr/etc/certs/%s.%s.key.pem' % (self.sslname, label),
                    getattr(self, "key_%s" % label))

            if label == 'next':
                if getattr(self, "csr_%s" % label) is None:
                    meta['csr'] = None
                    file = 'usr/etc/certs/%s.%s.csr.pem' % (self.sslname,
                                                            label)
                    if os.path.exists(file):
                        os.remove(file)
                else:
                    meta['csr'] = sha256(
                        str(getattr(self, "csr_%s" %
                                    label)).encode('utf-8')).hexdigest()
                    save_file(
                        'usr/etc/certs/%s.%s.csr.pem' % (self.sslname, label),
                        getattr(self, "csr_%s" % label))

            save_file('usr/etc/certs/%s.%s.meta' % (self.sslname, label),
                      json.dumps(meta, separators=(',', ':')))
示例#13
0
    def request_new_csr(self, submit=False, force_new=False):
        """
        Requests a new csr to be generated. This uses the base class to do the heavy lifting.

        We usually don't submit the CSR at the time generation. This allows the CSR to be genearted ahead
        of when we actually need.

        :param submit: If true, will also submit the csr.
        :param force_new: Will create a new CSR regardless of the current state.
        :return:
        """
        self.dirty = True
        # print("1 calling local generate_new_csr. Name: %s Force: %s.  Is valid: %s" % (
        #     self.sslname, force_new, self.next_is_valid
        #     )
        # )
        if force_new is True:
            self.clean_section("next")
        else:
            self.check_is_valid("next")

        if self.next_is_valid is not None:
            if submit is True:
                if self.next_csr_generation_in_progress is True:
                    self.next_csr_submit_after_generation = True
                else:
                    self.submit_csr()
            else:
                logger.info("Was asked to generate CSR, but we don't need it for: {sslname}", sslname=self.sslname)
            return

        logger.debug("generate_new_csr: {sslname}.  Submit: {submit}", sslname=self.sslname, submit=submit)
        # End local functions.
        request = {
            "sslname": self.sslname,
            "key_size": self.key_size,
            "key_type": self.key_type,
            "cn": self.cn,
            "sans": self.sans
        }
        logger.debug("request_new_csr: request: {request}", request=request)

        if self.next_csr_generation_in_progress is True:  # don't run twice!
            if submit is True:  # but if previously, we weren't going to submit it, we will now if requested.
                self.next_csr_submit_after_generation = True
            return

        self.next_csr_generation_in_progress = True
        self.next_csr_submit_after_generation = submit

        self.next_csr_generation_count = 0
        self.next_csr_generation_in_progress = True
        logger.debug("About to generate new csr request: {request}", request=request)

        try:
            the_job = yield self._Parent.generate_csr_queue.put(request)
            results = the_job.result
            self.next_fqdn = self._Parent.local_gateway.dns_name
        except Exception as e:
            self.next_csr_generation_error_count += 1
            if self.next_csr_generation_error_count < 5:
                logger.warn("Error generating new CSR for '{sslname}'. Will retry in 15 seconds. Exception : {failure}",
                            sslname=self.sslname, failure=e)
                reactor.callLater(15, self.request_new_csr, submit, force_new)
            else:
                logger.error(
                    "Error generating new CSR for '{sslname}'. Too many retries, perhaps something wrong with our request. Exception : {failure}",
                    sslname=self.sslname, failure=e)
                self.next_csr_generation_in_progress = False
            return False

        logger.debug("request_new_csr: {sslname}", sslname=self.sslname)
        results = bytes_to_unicode(results)
        self.next_status = "new"
        self.next_status_msg = "Created but unsent for signing. Will send when previous cert nears expiration."
        self.next_csr = results["csr"]
        self.next_csr_hash = results["csr_hash"]
        self.next_key = results["key"]
        # print("request_new_csr csr: %s " % self.next_csr)
        yield save_file(f"{self.working_dir}/etc/certs/{self.sslname}.next.csr.pem", self.next_csr)
        yield save_file(f"{self.working_dir}/etc/certs/{self.sslname}.next.key.pem", self.next_key)
        self.next_created_at = int(time())
        self.dirty = True
        self.next_csr_generation_in_progress = False
        if submit is True:
            # print("calling submit_csr from generate_new_csr_done")
            self.submit_csr()
示例#14
0
    def _sync_to_filesystem(self):
        for label in ["current", "next"]:

            meta = {
                "status": getattr(self, f"{label}_status"),
                "status_msg": getattr(self, f"{label}_status_msg"),
                "created_at": getattr(self, f"{label}_created_at"),
                "expires_at": getattr(self, f"{label}_expires_at"),
                "signed_at": getattr(self, f"{label}_signed_at"),
                "submitted_at": getattr(self, f"{label}_submitted_at"),
                "fqdn": getattr(self, f"{label}_fqdn"),
                "key_type": self.key_type,
                "key_size": self.key_size,
            }

            if getattr(self, f"{label}_cert") is None:
                meta["cert"] = None
                file = f"{self.working_dir}/etc/certs/{self.sslname}.{label}.cert.pem"
                if os.path.exists(file):
                    os.remove(file)
            else:
                meta["cert"] = sha256(str(getattr(self, f"{label}_cert")).encode("utf-8")).hexdigest()
                yield save_file(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.cert.pem",
                                getattr(self, f"{label}_cert"))

            if getattr(self, f"{label}_chain") is None:
                meta["chain"] = None
                file = f"{self.working_dir}/etc/certs/{self.sslname}.{label}.chain.pem"
                if os.path.exists(file):
                    os.remove(file)
            else:
                meta["chain"] = sha256(str(getattr(self, f"{label}_chain")).encode("utf-8")).hexdigest()
                yield save_file(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.chain.pem",
                                getattr(self, f"{label}_chain"))

            if getattr(self, f"{label}_key") is None:
                meta["key"] = None
                file = f"{self.working_dir}/etc/certs/{self.sslname}.{label}.key.pem"
                if os.path.exists(file):
                    os.remove(file)
            else:
                meta["key"] = sha256(str(getattr(self, f"{label}_key")).encode("utf-8")).hexdigest()
                yield save_file(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.key.pem",
                                getattr(self, f"{label}_key"))

            if label == "next":
                if getattr(self, f"{label}_csr") is None:
                    meta["csr"] = None
                    file = f"{self.working_dir}/etc/certs/{self.sslname}.{label}.csr.pem"
                    if os.path.exists(file):
                        os.remove(file)
                else:
                    meta["csr"] = sha256(str(getattr(self, f"{label}_csr")).encode("utf-8")).hexdigest()
                    yield save_file(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.csr.pem",
                                    getattr(self, f"{label}_csr"))

            yield save_file(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.meta",
                            json.dumps(meta, indent=4))

            yield save_file(f"{self.working_dir}/etc/certs/{self.sslname}.meta",
                            json.dumps({
                                "sans": self.sans,
                                "cn": self.cn,
                            }, indent=4))