Exemple #1
0
    def _init_(self, **kwargs):
        """
        On startup, various libraries will need certs (webinterface, MQTT) for encryption. This
        module stores certificates in a directory so other programs can use certs as well. It's
        working data is stored in the database, while a backup is kept in the file system as well
        and is only used if the data is missing from the database.

        If a cert isn't avail for the requested sslname, it will receive a self-signed certificate.

        :return:
        """
        # Since SSL generation can take some time on slower devices, we use a simple queue system.
        self.generate_csr_queue = self._Queue.new(
            'library.sslcerts.generate_csr', self.generate_csr)
        self.hostname = gethostname()

        self.gateway_id = self._Configs.get('core', 'gwid', 'local', False)
        self.fqdn = self._Configs.get2('dns', 'fqdn', None, False)

        self.received_message_for_unknown = ExpiringDict(100, 600)
        self.self_signed_cert_file = self._Atoms.get(
            'yombo.path') + "/usr/etc/certs/sslcert_selfsigned.cert.pem"
        self.self_signed_key_file = self._Atoms.get(
            'yombo.path') + "/usr/etc/certs/sslcert_selfsigned.key.pem"
        self.self_signed_expires = self._Configs.get("sslcerts",
                                                     "self_signed_expires",
                                                     None, False)
        self.self_signed_created = self._Configs.get("sslcerts",
                                                     "self_signed_created",
                                                     None, False)

        if os.path.exists(self.self_signed_cert_file) is False or \
                self.self_signed_expires is None or \
                self.self_signed_expires < int(time() + (60*60*24*60)) or \
                self.self_signed_created is None or \
                not os.path.exists(self.self_signed_key_file):
            logger.info(
                "Generating a self signed cert for SSL. This can take a few moments."
            )
            yield self._create_self_signed_cert()

        self.self_signed_cert = yield read_file(self.self_signed_cert_file)
        self.self_signed_key = yield read_file(self.self_signed_key_file)

        self.managed_certs = yield self._SQLDict.get(
            self,
            "managed_certs",
            serializer=self.sslcert_serializer,
            unserializer=self.sslcert_unserializer)
        # for name, data in self.managed_certs.items():
        #     print("cert name: %s" % name)
        #     print("  cert data: %s" % data.__dict__)

        self.check_if_certs_need_update_loop = None
    def _init_(self, **kwargs):
        """
        On startup, various libraries will need certs (webinterface, MQTT) for encryption. This
        module stores certificates in a directory so other programs can use certs as well. It's
        working data is stored in the database, while a backup is kept in the file system as well
        and is only used if the data is missing from the database.

        If a cert isn't avail for the requested sslname, it will receive a self-signed certificate.

        :return:
        """
        # Since SSL generation can take some time on slower devices, we use a simple queue system.
        self.generate_csr_queue = self._Queue.new(
            "library.sslcerts.generate_csr", self.generate_csr)
        self.hostname = gethostname()

        self.local_gateway = self._Gateways.local

        self.self_signed_cert_file = self._Atoms.get(
            "working_dir") + "/etc/certs/sslcert_selfsigned.cert.pem"
        self.self_signed_key_file = self._Atoms.get(
            "working_dir") + "/etc/certs/sslcert_selfsigned.key.pem"
        self.self_signed_expires_at = self._Configs.get(
            "sslcerts", "self_signed_expires_at", None, False)
        self.self_signed_created_at = self._Configs.get(
            "sslcerts", "self_signed_created_at", None, False)
        self.default_key_size = self._Configs.get("sslcerts",
                                                  "default_key_size", 2048)

        if os.path.exists(self.self_signed_cert_file) is False or \
                self.self_signed_expires_at is None or \
                self.self_signed_expires_at < int(time() + (60*60*24*60)) or \
                self.self_signed_created_at is None or \
                not os.path.exists(self.self_signed_key_file):
            logger.info(
                "Generating a self signed cert for SSL. This can take a few moments."
            )
            yield self._create_self_signed_cert()

        self.self_signed_cert = yield read_file(self.self_signed_cert_file)
        self.self_signed_key = yield read_file(self.self_signed_key_file)

        self.managed_certs = yield self._SQLDict.get(
            self,
            "managed_certs",
            serializer=self.sslcert_serializer,
            unserializer=self.sslcert_unserializer)
        for key, item in self.managed_certs.items():
            print(f"Managed certs: {self.managed_certs}")

        self.check_if_certs_need_update_loop = None
Exemple #3
0
    def _init_(self, **kwargs):
        """
        Get the GnuPG subsystem up and loaded.
        """
        self.key_generation_status = None
        self._generating_key = False
        self._gpg_keys = {}
        self._generating_key_deferred = None
        self.sks_pools = [  # Send to a few to ensure we get our key seeded
            "ipv4.pool.sks-keyservers.net",
            "na.pool.sks-keyservers.net",
            "eu.pool.sks-keyservers.net",
            "oc.pool.sks-keyservers.net",
            "pool.sks-keyservers.net",
            "ha.pool.sks-keyservers.net"
        ]
        self.working_dir = settings.arguments["working_dir"]
        self.gpg = gnupg.GPG(gnupghome=f"{self.working_dir}/etc/gpg")

        self.__mypassphrase = None  # will be loaded by sync_keyring_to_db() calls

        secret_file = f"{self.working_dir}/etc/gpg/last.pass"
        if os.path.exists(secret_file):
            phrase = yield read_file(secret_file)
            self.__mypassphrase = bytes_to_unicode(phrase)
Exemple #4
0
        def home_index(webinterface, request, session):
            if webinterface.operating_mode == "config":
                return webinterface.redirect(request, "/misc/config")
            elif webinterface.operating_mode == "first_run":
                logger.info(
                    "Incoming request to /, but gateway needs setup. Redirecting to gateway_setup"
                )
                return webinterface.redirect(request, "/misc/gateway_setup")
            if session is None or session.enabled is False or session.is_valid(
            ) is False or session.has_user is False:
                return webinterface.redirect(request, "/user/login")

            print(f"file_cache: {webinterface.file_cache}")
            if "index" not in webinterface.file_cache:
                webinterface.file_cache["index"] = {}
                try:
                    webinterface.file_cache["index"]["data"] = yield read_file(
                        f"{webinterface.working_dir}/frontend/index.html")
                    webinterface.file_cache["index"]["headers"] = {
                        "Cache-Control": f"max-age=7200",
                        "Content-Type": "text/html"
                    }
                except:
                    return "Unable to process request."

            file = webinterface.file_cache["index"]
            if "headers" in file and len(file["headers"]) > 0:
                for header_name, header_content in file['headers'].items():
                    request.setHeader(header_name, header_content)
            return file["data"]
Exemple #5
0
        def home_service_worker(webinterface, request, session):
            """ Service worker file for authenticated users only. """
            print("got sw.js request...")
            if "sw.js" not in webinterface.file_cache:
                print("sw.js - loading cache...")
                webinterface.file_cache["sw.js"] = {}
                try:
                    webinterface.file_cache["sw.js"]["data"] = yield read_file(
                        f"{webinterface.working_dir}/frontend/sw.js")
                    webinterface.file_cache["sw.js"]["headers"] = {
                        "Cache-Control": f"max-age=60",
                        "Content-Type": "application/javascript"
                    }
                except:
                    return "Unable to process request."

            file = webinterface.file_cache["sw.js"]
            # print(webinterface.file_cache)
            # print(file)
            print("sw.js - setting headers")
            if "headers" in file and len(file["headers"]) > 0:
                for header_name, header_content in file['headers'].items():
                    request.setHeader(header_name, header_content)
            print("sw.js - send response.")
            return file["data"]
Exemple #6
0
 def load_passphrase(self, fingerprint=None):
     if fingerprint is None:
         fingerprint = self.myfingerprint()
     if fingerprint is not None:
         secret_file = f"{self.working_dir}/etc/gpg/{fingerprint}.pass"
         if os.path.exists(secret_file):
             phrase = yield read_file(secret_file)
             phrase = bytes_to_unicode(phrase)
             if fingerprint == self.myfingerprint():
                 self.__mypassphrase = phrase
             return phrase
     return None
Exemple #7
0
 def load_passphrase(self, keyid=None):
     if keyid is None:
         keyid = self.mykeyid()
     if keyid is not None:
         secret_file = "%s/usr/etc/gpg/%s.pass" % (
             self._Atoms.get('yombo.path'), keyid)
         if os.path.exists(secret_file):
             phrase = yield read_file(secret_file)
             if keyid == self.mykeyid():
                 self.__mypassphrase = phrase
             return bytes_to_unicode(phrase)
     return None
Exemple #8
0
    def locale_to_dict(self, locale=None):
        if locale is None:
            locale = self.default_lang()

        if locale not in self.files:
            raise YomboWarning(f"Invalid locale for locale_to_dict: {locale}")

        po_file = f"{self.locale_save_folder}{locale}/LC_MESSAGES/yombo.po"
        data = yield read_file(po_file, convert_to_unicode=True)
        tuples = re.findall(r'msgid "(.+)"\nmsgstr "(.+)"', data)

        po_dict = {}
        for tuple in tuples:
            po_dict[tuple[0]] = tuple[1]

        return po_dict
    def check_npm_running(self):
        """
        Checks if the builder process is running. First, it checks if the PID file is found. It then
        inspects that file and checks to make sure the actual process is running. If the process is running,
        return True. If not, remove file the PID file and return False.
        :return:
        """
        # Check if builder is already running:
        if path.isfile(
                f"{self.app_dir}/yombo/frontend/util/builder.pid") is False:
            return False

        pid = yield read_file(
            f"{self.app_dir}/yombo/frontend/util/builder.pid")
        try:
            kill(int(pid), 0)
            return True
        except OSError:
            unlink(f"{self.app_dir}/yombo/frontend/util/builder.pid")
            return False
    def set(self, content):
        """
        Set the content for the class. It can be bytes to represent the raw input, or it can be a string
        representing a file to load.

        :param content:
        :return:
        """
        if isinstance(content, bytes):  # we have a raw image:
            pass
        elif isinstance(content, str):  # we should have a file path:
            if os.path.exists(self.yombo_ini_path) is False:
                raise YomboWarning(
                    f"String types must be a path/filename to an file to load."
                )
            image = yield read_file(content)
        else:
            raise YomboWarning("Unknown input type.")

        content_type = yield mime_type_from_buffer(content)

        self.content_type = content_type["content_type"]
        self.charset = content_type["charset"]
        self._content = content
Exemple #11
0
    def read_configs(self):
        try:
            content = yield read_file('%s/config.json' % self.module_path)
        except Exception as e:
            logger.info(
                "Couldn't read existing config.json file for homebridge.")
            return False

        config_file = bytes_to_unicode(json.loads(content))

        if 'bridge' not in config_file:
            logger.warn(
                "'bridge' section missing from homebridge config.json file.")
            return False

        if 'username' in config_file['bridge']:
            self.username = config_file['bridge']['username']
        else:
            logger.warn(
                "'username' missing within 'bridge' section from homebridge config.json file."
            )
            return False

        if 'pin' in config_file['bridge']:
            self.pin_code = config_file['bridge']['pin']
        else:
            logger.warn(
                "'pin' missing within 'bridge' section from homebridge config.json file."
            )
            return False

        for idx, platform in enumerate(config_file['platforms']):
            if platform['platform'] == 'Yombo':
                config_file['platforms'][idx]['apiauth'] = self.apiauth.auth_id
                break
        self.config_file = config_file
Exemple #12
0
    def sync_from_filesystem(self):
        """
        Reads meta data and items from the file system. This allows us to restore data incase the database
        goes south. This is important since only the gateway has the private key and cannot be recovered.

        :return:
        """
        logger.info("Inspecting file system for certs, and loading them.")

        for label in ['current', 'next']:
            setattr(self, "%s_is_valid" % label, None)

            if os.path.exists('usr/etc/certs/%s.%s.meta' %
                              (self.sslname, label)):
                logger.debug("SSL Meta found for: {label} - {sslname}",
                             label=label,
                             sslname=self.sslname)
                file_content = yield read_file('usr/etc/certs/%s.%s.meta' %
                                               (self.sslname, label))
                meta = json.loads(file_content)
                # print("meta: %s" % meta)

                csr_read = False
                if label == 'next':
                    logger.debug("Looking for 'next' information.")
                    if os.path.exists('usr/etc/certs/%s.%s.csr.pem' %
                                      (self.sslname, label)):
                        if getattr(self, "%s_csr" % label) is None:
                            csr = yield read_file(
                                'usr/etc/certs/%s.%s.csr.pem' %
                                (self.sslname, label),
                                True,
                            )
                            if sha256(str(csr).encode(
                                    'utf-8')).hexdigest() == meta['csr']:
                                csr_read = True
                            else:
                                # print("%s = %s" % (
                                #     sha256(str(csr).encode('utf-8')).hexdigest(), meta['csr']
                                #     )
                                # )
                                logger.warn(
                                    "Appears that the file system has bad meta signatures (csr). Purging."
                                )
                                for file_to_delete in glob.glob(
                                        "usr/etc/certs/%s.%s.*" %
                                    (self.sslname, label)):
                                    logger.warn("Removing bad file: %s" %
                                                file_to_delete)
                                    os.remove(file_to_delete)
                                continue

                cert_read = False
                if getattr(self, "%s_cert" % label) is None:
                    if os.path.exists('usr/etc/certs/%s.%s.cert.pem' %
                                      (self.sslname, label)):
                        # print("setting cert!!!")
                        cert = yield read_file(
                            'usr/etc/certs/%s.%s.cert.pem' %
                            (self.sslname, label), True)
                        cert_read = True
                        # print("testing with this cert: %s" % cert)
                        if sha256(str(cert).encode(
                                'utf-8')).hexdigest() != meta['cert']:
                            # print("%s != %s" % (sha256(str(cert).encode('utf-8')).hexdigest(), meta['cert']))
                            logger.warn(
                                "Appears that the file system has bad meta signatures (cert). Purging."
                            )
                            for file_to_delete in glob.glob(
                                    "usr/etc/certs/%s.%s.*" %
                                (self.sslname, label)):
                                logger.warn("Removing bad file: %s" %
                                            file_to_delete)
                                os.remove(file_to_delete)
                            continue

                chain_read = False
                if getattr(self, "%s_chain" % label) is None:
                    if os.path.exists('usr/etc/certs/%s.%s.chain.pem' %
                                      (self.sslname, label)):
                        # print("setting chain!!!")
                        chain = yield read_file(
                            'usr/etc/certs/%s.%s.chain.pem' %
                            (self.sslname, label), True)
                        chain_read = True
                        if sha256(str(chain).encode(
                                'utf-8')).hexdigest() != meta['chain']:
                            logger.warn(
                                "Appears that the file system has bad meta signatures (chain). Purging."
                            )
                            for file_to_delete in glob.glob(
                                    "usr/etc/certs/%s.%s.*" %
                                (self.sslname, label)):
                                logger.warn("Removing bad file: %s" %
                                            file_to_delete)
                                os.remove(file_to_delete)
                            continue

                key_read = False
                if getattr(self, "%s_key" % label) is None:
                    if os.path.exists('usr/etc/certs/%s.%s.key.pem' %
                                      (self.sslname, label)):
                        key = yield read_file(
                            'usr/etc/certs/%s.%s.key.pem' %
                            (self.sslname, label), True)
                        key_read = True
                        if sha256(str(key).encode(
                                'utf-8')).hexdigest() != meta['key']:
                            logger.warn(
                                "Appears that the file system has bad meta signatures (key). Purging."
                            )
                            for file_to_delete in glob.glob(
                                    "usr/etc/certs/%s.%s.*" %
                                (self.sslname, label)):
                                logger.warn("Removing bad file: %s" %
                                            file_to_delete)
                                os.remove(file_to_delete)
                            continue

                logger.debug("Reading meta file for cert: {label}",
                             label=label)

                def return_int(the_input):
                    try:
                        return int(the_input)
                    except Exception as e:
                        return the_input

                if csr_read:
                    setattr(self, "%s_csr" % label, csr)
                if cert_read:
                    setattr(self, "%s_cert" % label, cert)
                if chain_read:
                    setattr(self, "%s_chain" % label, chain)
                if key_read:
                    setattr(self, "%s_key" % label, key)
                setattr(self, "%s_expires" % label,
                        return_int(meta['expires']))
                setattr(self, "%s_created" % label,
                        return_int(meta['created']))
                setattr(self, "%s_signed" % label, return_int(meta['signed']))
                setattr(self, "%s_submitted" % label,
                        return_int(meta['submitted']))
                setattr(self, "%s_fqdn" % label, return_int(meta['fqdn']))

                self.check_is_valid(label)
            else:
                setattr(self, "%s_is_valid" % label, False)
    def sync_from_filesystem(self):
        """
        Reads meta data and items from the file system. This allows us to restore data incase the database
        goes south. This is important since only the gateway has the private key and cannot be recovered.

        :return:
        """
        logger.debug("Inspecting file system for certs, and loading them for: {name}", name=self.sslname)

        for label in ["current", "next"]:
            setattr(self, f"{label}_is_valid", None)

            if os.path.exists(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.meta"):
                logger.debug("SSL Meta found for: {label} - {sslname}", label=label, sslname=self.sslname)
                file_content = yield read_file(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.meta")
                meta = json.loads(file_content)
                csr_read = False
                if label == "next":
                    logger.debug("Looking for 'next' information.")
                    if os.path.exists(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.csr.pem"):
                        if getattr(self, f"{label}_csr") is None:
                            csr = yield read_file(
                                f"{self.working_dir}/etc/certs/{self.sslname}.{label}.csr.pem",
                                True,
                            )
                            if sha256(str(csr).encode("utf-8")).hexdigest() == meta["csr"]:
                                csr_read = True
                            else:
                                logger.warn("Appears that the file system has bad meta signatures (csr). Purging.")
                                for file_to_delete in glob.glob(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.*"):
                                    logger.warn("Removing bad file: {file}", file=file_to_delete)
                                    os.remove(file_to_delete)
                                continue

                cert_read = False
                if getattr(self, f"{label}_cert") is None:
                    if os.path.exists(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.cert.pem"):
                        # print("setting cert!!!")
                        cert = yield read_file(
                            f"{self.working_dir}/etc/certs/{self.sslname}.{label}.cert.pem",
                            True
                        )
                        cert_read = True
                        # print("testing with this cert: %s" % cert)
                        if sha256(str(cert).encode("utf-8")).hexdigest() != meta["cert"]:
                            # print("%s != %s" % (sha256(str(cert).encode("utf-8")).hexdigest(), meta["cert"]))
                            logger.warn("Appears that the file system has bad meta signatures (cert). Purging.")
                            for file_to_delete in glob.glob(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.*"):
                                logger.warn("Removing bad file: {file}", file=file_to_delete)
                                os.remove(file_to_delete)
                            continue

                chain_read = False
                if getattr(self, f"{label}_chain") is None:
                    if os.path.exists(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.chain.pem"):
                        # print("setting chain!!!")
                        chain = yield read_file(
                            f"{self.working_dir}/etc/certs/{self.sslname}.{label}.chain.pem",
                            True
                        )
                        chain_read = True
                        if sha256(str(chain).encode("utf-8")).hexdigest() != meta["chain"]:
                            logger.warn("Appears that the file system has bad meta signatures (chain). Purging.")
                            for file_to_delete in glob.glob(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.*"):
                                logger.warn("Removing bad file: {file}", file=file_to_delete)
                                os.remove(file_to_delete)
                            continue

                key_read = False
                if getattr(self, f"{label}_key") is None:
                    if os.path.exists(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.key.pem"):
                        key = yield read_file(
                            f"{self.working_dir}/etc/certs/{self.sslname}.{label}.key.pem",
                            True
                        )
                        key_read = True
                        if sha256(str(key).encode("utf-8")).hexdigest() != meta["key"]:
                            logger.warn("Appears that the file system has bad meta signatures (key). Purging.")
                            for file_to_delete in glob.glob(f"{self.working_dir}/etc/certs/{self.sslname}.{label}.*"):
                                logger.warn("Removing bad file: {file}", file=file_to_delete)
                                os.remove(file_to_delete)
                            continue

                logger.debug("Reading meta file for cert: {label}", label=label)

                def return_int(the_input):
                    try:
                        return int(the_input)
                    except Exception as e:
                        return the_input

                if csr_read:
                    setattr(self, f"{label}_csr", csr)
                if cert_read:
                    setattr(self, f"{label}_cert", cert)
                if chain_read:
                    setattr(self, f"{label}_chain", chain)
                if key_read:
                    setattr(self, f"{label}_key", key)
                setattr(self, f"{label}_status", return_int(meta["status"]))
                setattr(self, f"{label}_status_msg", return_int(meta["status_msg"]))
                setattr(self, f"{label}_expires_at", return_int(meta["expires_at"]))
                setattr(self, f"{label}_created_at", return_int(meta["created_at"]))
                setattr(self, f"{label}_signed_at", return_int(meta["signed_at"]))
                setattr(self, f"{label}_submitted_at", return_int(meta["submitted_at"]))
                setattr(self, f"{label}_fqdn", return_int(meta["fqdn"]))

                self.check_is_valid(label)
            else:
                setattr(self, f"{label}_is_valid", False)
        self.set_crypto()