def __init__(self, option_name, rule): """ Args: option_name (str): Name of the config option this rule belongs to rule (dict): The rule as specified in the config """ action = rule["action"] user_id = rule.get("user_id", "*") room_id = rule.get("room_id", "*") alias = rule.get("alias", "*") if action in ("allow", "deny"): self.action = action else: raise ConfigError("%s rules can only have action of 'allow'" " or 'deny'" % (option_name, )) self._alias_matches_all = alias == "*" try: self._user_id_regex = glob_to_regex(user_id) self._alias_regex = glob_to_regex(alias) self._room_id_regex = glob_to_regex(room_id) except Exception as e: raise ConfigError("Failed to parse glob into regex: %s", e)
def __init__(self, option_name, rule): """ Args: option_name (str): Name of the config option this rule belongs to rule (dict): The rule as specified in the config """ action = rule["action"] user_id = rule.get("user_id", "*") room_id = rule.get("room_id", "*") alias = rule.get("alias", "*") if action in ("allow", "deny"): self.action = action else: raise ConfigError( "%s rules can only have action of 'allow'" " or 'deny'" % (option_name,) ) self._alias_matches_all = alias == "*" try: self._user_id_regex = glob_to_regex(user_id) self._alias_regex = glob_to_regex(alias) self._room_id_regex = glob_to_regex(room_id) except Exception as e: raise ConfigError("Failed to parse glob into regex: %s", e)
def _acl_entry_matches(server_name: str, acl_entry: str) -> Match: if not isinstance(acl_entry, str): logger.warning("Ignoring non-str ACL entry '%s' (is %s)", acl_entry, type(acl_entry)) return False regex = glob_to_regex(acl_entry) return regex.match(server_name)
def _acl_entry_matches(server_name, acl_entry): if not isinstance(acl_entry, six.string_types): logger.warn("Ignoring non-str ACL entry '%s' (is %s)", acl_entry, type(acl_entry)) return False regex = glob_to_regex(acl_entry) return regex.match(server_name)
def __init__(self, rule): action = rule["action"] user_id = rule["user_id"] alias = rule["alias"] if action in ("allow", "deny"): self.action = action else: raise ConfigError( "alias_creation_rules rules can only have action of 'allow'" " or 'deny'" ) try: self._user_id_regex = glob_to_regex(user_id) self._alias_regex = glob_to_regex(alias) except Exception as e: raise ConfigError("Failed to parse glob into regex: %s", e)
def test_multi_wildcard(self): """patterns with multiple wildcards in a row should match""" pat = glob_to_regex("**baz") self.assertTrue(pat.match("agsgsbaz"), "** should match any string") self.assertTrue(pat.match("baz"), "** should match the empty string") self.assertEqual(pat.pattern, r"\A.{0,}baz\Z") pat = glob_to_regex("*?baz") self.assertTrue(pat.match("agsgsbaz"), "*? should match any string") self.assertTrue(pat.match("abaz"), "*? should match a single char") self.assertFalse(pat.match("baz"), "*? should not match the empty string") self.assertEqual(pat.pattern, r"\A.{1,}baz\Z") pat = glob_to_regex("a?*?*?baz") self.assertTrue(pat.match("a g baz"), "?*?*? should match 3 chars") self.assertFalse(pat.match("a..baz"), "?*?*? should not match 2 chars") self.assertTrue(pat.match("a.gg.baz"), "?*?*? should match 4 chars") self.assertEqual(pat.pattern, r"\Aa.{3,}baz\Z")
def test_literal_match(self): """patterns without wildcards should match""" pat = glob_to_regex("foobaz") self.assertTrue( pat.match("FoobaZ"), "patterns should match and be case-insensitive" ) self.assertFalse( pat.match("x foobaz"), "pattern should not match at word boundaries" )
def test_wildcard_match(self): pat = glob_to_regex("f?o*baz") self.assertTrue( pat.match("FoobarbaZ"), "* should match string and pattern should be case-insensitive", ) self.assertTrue(pat.match("foobaz"), "* should match 0 characters") self.assertFalse(pat.match("fooxaz"), "the character after * must match") self.assertFalse(pat.match("fobbaz"), "? should not match 0 characters") self.assertFalse(pat.match("fiiobaz"), "? should not match 2 characters")
def _glob_matches(glob: str, value: str, word_boundary: bool = False) -> bool: """Tests if value matches glob. Args: glob value: String to test against glob. word_boundary: Whether to match against word boundaries or entire string. Defaults to False. """ try: r = regex_cache.get((glob, True, word_boundary), None) if not r: r = glob_to_regex(glob, word_boundary) regex_cache[(glob, True, word_boundary)] = r return bool(r.search(value)) except re.error: logger.warning("Failed to parse glob to regex: %r", glob) return False
def read_config(self, config: dict, config_dir_path: str, **kwargs): acme_config = config.get("acme", None) if acme_config is None: acme_config = {} self.acme_enabled = acme_config.get("enabled", False) if self.acme_enabled: logger.warning(ACME_SUPPORT_ENABLED_WARN) # hyperlink complains on py2 if this is not a Unicode self.acme_url = str( acme_config.get("url", "https://acme-v01.api.letsencrypt.org/directory")) self.acme_port = acme_config.get("port", 80) self.acme_bind_addresses = acme_config.get("bind_addresses", ["::", "0.0.0.0"]) self.acme_reprovision_threshold = acme_config.get( "reprovision_threshold", 30) self.acme_domain = acme_config.get("domain", config.get("server_name")) self.acme_account_key_file = self.abspath( acme_config.get("account_key_file", config_dir_path + "/client.key")) self.tls_certificate_file = self.abspath( config.get("tls_certificate_path")) self.tls_private_key_file = self.abspath( config.get("tls_private_key_path")) if self.root.server.has_tls_listener(): if not self.tls_certificate_file: raise ConfigError( "tls_certificate_path must be specified if TLS-enabled listeners are " "configured.") if not self.tls_private_key_file: raise ConfigError( "tls_private_key_path must be specified if TLS-enabled listeners are " "configured.") self._original_tls_fingerprints = config.get("tls_fingerprints", []) if self._original_tls_fingerprints is None: self._original_tls_fingerprints = [] self.tls_fingerprints = list(self._original_tls_fingerprints) # Whether to verify certificates on outbound federation traffic self.federation_verify_certificates = config.get( "federation_verify_certificates", True) # Minimum TLS version to use for outbound federation traffic self.federation_client_minimum_tls_version = str( config.get("federation_client_minimum_tls_version", 1)) if self.federation_client_minimum_tls_version not in [ "1", "1.1", "1.2", "1.3" ]: raise ConfigError( "federation_client_minimum_tls_version must be one of: 1, 1.1, 1.2, 1.3" ) # Prevent people shooting themselves in the foot here by setting it to # the biggest number blindly if self.federation_client_minimum_tls_version == "1.3": if getattr(SSL, "OP_NO_TLSv1_3", None) is None: raise ConfigError( ("federation_client_minimum_tls_version cannot be 1.3, " "your OpenSSL does not support it")) # Whitelist of domains to not verify certificates for fed_whitelist_entries = config.get( "federation_certificate_verification_whitelist", []) if fed_whitelist_entries is None: fed_whitelist_entries = [] # Support globs (*) in whitelist values self.federation_certificate_verification_whitelist = [ ] # type: List[str] for entry in fed_whitelist_entries: try: entry_regex = glob_to_regex( entry.encode("ascii").decode("ascii")) except UnicodeEncodeError: raise ConfigError( "IDNA domain names are not allowed in the " "federation_certificate_verification_whitelist: %s" % (entry, )) # Convert globs to regex self.federation_certificate_verification_whitelist.append( entry_regex) # List of custom certificate authorities for federation traffic validation custom_ca_list = config.get("federation_custom_ca_list", None) # Read in and parse custom CA certificates self.federation_ca_trust_root = None if custom_ca_list is not None: if len(custom_ca_list) == 0: # A trustroot cannot be generated without any CA certificates. # Raise an error if this option has been specified without any # corresponding certificates. raise ConfigError( "federation_custom_ca_list specified without " "any certificate files") certs = [] for ca_file in custom_ca_list: logger.debug("Reading custom CA certificate file: %s", ca_file) content = self.read_file(ca_file, "federation_custom_ca_list") # Parse the CA certificates try: cert_base = Certificate.loadPEM(content) certs.append(cert_base) except Exception as e: raise ConfigError( "Error parsing custom CA certificate file %s: %s" % (ca_file, e)) self.federation_ca_trust_root = trustRootFromCertificates(certs) # This config option applies to non-federation HTTP clients # (e.g. for talking to recaptcha, identity servers, and such) # It should never be used in production, and is intended for # use only when running tests. self.use_insecure_ssl_client_just_for_testing_do_not_use = config.get( "use_insecure_ssl_client_just_for_testing_do_not_use") self.tls_certificate = None self.tls_private_key = None
def __init__(self, entity, action, reason, kind): self.entity = entity self.regex = glob_to_regex(entity) self.action = recommendation_to_stable(action) self.reason = reason self.kind = rule_type_to_stable(kind)
def read_config(self, config): acme_config = config.get("acme", None) if acme_config is None: acme_config = {} self.acme_enabled = acme_config.get("enabled", False) # hyperlink complains on py2 if this is not a Unicode self.acme_url = six.text_type(acme_config.get( "url", u"https://acme-v01.api.letsencrypt.org/directory" )) self.acme_port = acme_config.get("port", 80) self.acme_bind_addresses = acme_config.get("bind_addresses", ['::', '0.0.0.0']) self.acme_reprovision_threshold = acme_config.get("reprovision_threshold", 30) self.acme_domain = acme_config.get("domain", config.get("server_name")) self.tls_certificate_file = self.abspath(config.get("tls_certificate_path")) self.tls_private_key_file = self.abspath(config.get("tls_private_key_path")) if self.has_tls_listener(): if not self.tls_certificate_file: raise ConfigError( "tls_certificate_path must be specified if TLS-enabled listeners are " "configured." ) if not self.tls_private_key_file: raise ConfigError( "tls_private_key_path must be specified if TLS-enabled listeners are " "configured." ) self._original_tls_fingerprints = config.get("tls_fingerprints", []) if self._original_tls_fingerprints is None: self._original_tls_fingerprints = [] self.tls_fingerprints = list(self._original_tls_fingerprints) # Whether to verify certificates on outbound federation traffic self.federation_verify_certificates = config.get( "federation_verify_certificates", True, ) # Whitelist of domains to not verify certificates for fed_whitelist_entries = config.get( "federation_certificate_verification_whitelist", [], ) # Support globs (*) in whitelist values self.federation_certificate_verification_whitelist = [] for entry in fed_whitelist_entries: # Convert globs to regex entry_regex = glob_to_regex(entry) self.federation_certificate_verification_whitelist.append(entry_regex) # List of custom certificate authorities for federation traffic validation custom_ca_list = config.get( "federation_custom_ca_list", None, ) # Read in and parse custom CA certificates self.federation_ca_trust_root = None if custom_ca_list is not None: if len(custom_ca_list) == 0: # A trustroot cannot be generated without any CA certificates. # Raise an error if this option has been specified without any # corresponding certificates. raise ConfigError("federation_custom_ca_list specified without " "any certificate files") certs = [] for ca_file in custom_ca_list: logger.debug("Reading custom CA certificate file: %s", ca_file) content = self.read_file(ca_file, "federation_custom_ca_list") # Parse the CA certificates try: cert_base = Certificate.loadPEM(content) certs.append(cert_base) except Exception as e: raise ConfigError("Error parsing custom CA certificate file %s: %s" % (ca_file, e)) self.federation_ca_trust_root = trustRootFromCertificates(certs) # This config option applies to non-federation HTTP clients # (e.g. for talking to recaptcha, identity servers, and such) # It should never be used in production, and is intended for # use only when running tests. self.use_insecure_ssl_client_just_for_testing_do_not_use = config.get( "use_insecure_ssl_client_just_for_testing_do_not_use" ) self.tls_certificate = None self.tls_private_key = None
def read_config(self, config: dict, config_dir_path: str, **kwargs): self.tls_certificate_file = self.abspath(config.get("tls_certificate_path")) self.tls_private_key_file = self.abspath(config.get("tls_private_key_path")) if self.root.server.has_tls_listener(): if not self.tls_certificate_file: raise ConfigError( "tls_certificate_path must be specified if TLS-enabled listeners are " "configured." ) if not self.tls_private_key_file: raise ConfigError( "tls_private_key_path must be specified if TLS-enabled listeners are " "configured." ) # Whether to verify certificates on outbound federation traffic self.federation_verify_certificates = config.get( "federation_verify_certificates", True ) # Minimum TLS version to use for outbound federation traffic self.federation_client_minimum_tls_version = str( config.get("federation_client_minimum_tls_version", 1) ) if self.federation_client_minimum_tls_version not in ["1", "1.1", "1.2", "1.3"]: raise ConfigError( "federation_client_minimum_tls_version must be one of: 1, 1.1, 1.2, 1.3" ) # Prevent people shooting themselves in the foot here by setting it to # the biggest number blindly if self.federation_client_minimum_tls_version == "1.3": if getattr(SSL, "OP_NO_TLSv1_3", None) is None: raise ConfigError( "federation_client_minimum_tls_version cannot be 1.3, " "your OpenSSL does not support it" ) # Whitelist of domains to not verify certificates for fed_whitelist_entries = config.get( "federation_certificate_verification_whitelist", [] ) if fed_whitelist_entries is None: fed_whitelist_entries = [] # Support globs (*) in whitelist values self.federation_certificate_verification_whitelist: List[Pattern] = [] for entry in fed_whitelist_entries: try: entry_regex = glob_to_regex(entry.encode("ascii").decode("ascii")) except UnicodeEncodeError: raise ConfigError( "IDNA domain names are not allowed in the " "federation_certificate_verification_whitelist: %s" % (entry,) ) # Convert globs to regex self.federation_certificate_verification_whitelist.append(entry_regex) # List of custom certificate authorities for federation traffic validation custom_ca_list = config.get("federation_custom_ca_list", None) # Read in and parse custom CA certificates self.federation_ca_trust_root = None if custom_ca_list is not None: if len(custom_ca_list) == 0: # A trustroot cannot be generated without any CA certificates. # Raise an error if this option has been specified without any # corresponding certificates. raise ConfigError( "federation_custom_ca_list specified without " "any certificate files" ) certs = [] for ca_file in custom_ca_list: logger.debug("Reading custom CA certificate file: %s", ca_file) content = self.read_file(ca_file, "federation_custom_ca_list") # Parse the CA certificates try: cert_base = Certificate.loadPEM(content) certs.append(cert_base) except Exception as e: raise ConfigError( "Error parsing custom CA certificate file %s: %s" % (ca_file, e) ) self.federation_ca_trust_root = trustRootFromCertificates(certs) # This config option applies to non-federation HTTP clients # (e.g. for talking to recaptcha, identity servers, and such) # It should never be used in production, and is intended for # use only when running tests. self.use_insecure_ssl_client_just_for_testing_do_not_use = config.get( "use_insecure_ssl_client_just_for_testing_do_not_use" ) self.tls_certificate: Optional[crypto.X509] = None self.tls_private_key: Optional[crypto.PKey] = None
def read_config(self, config): acme_config = config.get("acme", None) if acme_config is None: acme_config = {} self.acme_enabled = acme_config.get("enabled", False) # hyperlink complains on py2 if this is not a Unicode self.acme_url = six.text_type(acme_config.get( "url", u"https://acme-v01.api.letsencrypt.org/directory" )) self.acme_port = acme_config.get("port", 80) self.acme_bind_addresses = acme_config.get("bind_addresses", ['::', '0.0.0.0']) self.acme_reprovision_threshold = acme_config.get("reprovision_threshold", 30) self.acme_domain = acme_config.get("domain", config.get("server_name")) self.tls_certificate_file = self.abspath(config.get("tls_certificate_path")) self.tls_private_key_file = self.abspath(config.get("tls_private_key_path")) if self.has_tls_listener(): if not self.tls_certificate_file: raise ConfigError( "tls_certificate_path must be specified if TLS-enabled listeners are " "configured." ) if not self.tls_private_key_file: raise ConfigError( "tls_private_key_path must be specified if TLS-enabled listeners are " "configured." ) self._original_tls_fingerprints = config.get("tls_fingerprints", []) if self._original_tls_fingerprints is None: self._original_tls_fingerprints = [] self.tls_fingerprints = list(self._original_tls_fingerprints) # Whether to verify certificates on outbound federation traffic self.federation_verify_certificates = config.get( "federation_verify_certificates", False, ) # Whitelist of domains to not verify certificates for fed_whitelist_entries = config.get( "federation_certificate_verification_whitelist", [], ) # Support globs (*) in whitelist values self.federation_certificate_verification_whitelist = [] for entry in fed_whitelist_entries: # Convert globs to regex entry_regex = glob_to_regex(entry) self.federation_certificate_verification_whitelist.append(entry_regex) # List of custom certificate authorities for federation traffic validation custom_ca_list = config.get( "federation_custom_ca_list", None, ) # Read in and parse custom CA certificates self.federation_ca_trust_root = None if custom_ca_list is not None: if len(custom_ca_list) == 0: # A trustroot cannot be generated without any CA certificates. # Raise an error if this option has been specified without any # corresponding certificates. raise ConfigError("federation_custom_ca_list specified without " "any certificate files") certs = [] for ca_file in custom_ca_list: logger.debug("Reading custom CA certificate file: %s", ca_file) content = self.read_file(ca_file) # Parse the CA certificates try: cert_base = Certificate.loadPEM(content) certs.append(cert_base) except Exception as e: raise ConfigError("Error parsing custom CA certificate file %s: %s" % (ca_file, e)) self.federation_ca_trust_root = trustRootFromCertificates(certs) # This config option applies to non-federation HTTP clients # (e.g. for talking to recaptcha, identity servers, and such) # It should never be used in production, and is intended for # use only when running tests. self.use_insecure_ssl_client_just_for_testing_do_not_use = config.get( "use_insecure_ssl_client_just_for_testing_do_not_use" ) self.tls_certificate = None self.tls_private_key = None