def test_block_ip_literals(self): e = _create_acl_event({"allow_ip_literals": False, "allow": ["*"]}) logging.info("ACL event: %s", e.content) self.assertFalse(server_matches_acl_event("1.2.3.4", e)) self.assertTrue(server_matches_acl_event("1a.2.3.4", e)) self.assertFalse(server_matches_acl_event("[1:2::]", e)) self.assertTrue(server_matches_acl_event("1:2:3:4", e))
def test_block_ip_literals(self): e = _create_acl_event({"allow_ip_literals": False, "allow": ["*"]}) logging.info("ACL event: %s", e.content) self.assertFalse(server_matches_acl_event("1.2.3.4", e)) self.assertTrue(server_matches_acl_event("1a.2.3.4", e)) self.assertFalse(server_matches_acl_event("[1:2::]", e)) self.assertTrue(server_matches_acl_event("1:2:3:4", e))
def test_blacklisted_server(self): e = _create_acl_event({"allow": ["*"], "deny": ["evil.com"]}) logging.info("ACL event: %s", e.content) self.assertFalse(server_matches_acl_event("evil.com", e)) self.assertFalse(server_matches_acl_event("EVIL.COM", e)) self.assertTrue(server_matches_acl_event("evil.com.au", e)) self.assertTrue(server_matches_acl_event("honestly.not.evil.com", e))
def test_blacklisted_server(self): e = _create_acl_event({"allow": ["*"], "deny": ["evil.com"]}) logging.info("ACL event: %s", e.content) self.assertFalse(server_matches_acl_event("evil.com", e)) self.assertFalse(server_matches_acl_event("EVIL.COM", e)) self.assertTrue(server_matches_acl_event("evil.com.au", e)) self.assertTrue(server_matches_acl_event("honestly.not.evil.com", e))
def validate_new(self, event: EventBase, config: HomeServerConfig): """Validates the event has roughly the right format Args: event: The event to validate. config: The homeserver's configuration. """ self.validate_builder(event) if event.format_version == EventFormatVersions.V1: EventID.from_string(event.event_id) required = [ "auth_events", "content", "hashes", "origin", "prev_events", "sender", "type", ] for k in required: if not hasattr(event, k): raise SynapseError(400, "Event does not have key %s" % (k,)) # Check that the following keys have string values event_strings = ["origin"] for s in event_strings: if not isinstance(getattr(event, s), str): raise SynapseError(400, "'%s' not a string type" % (s,)) # Depending on the room version, ensure the data is spec compliant JSON. if event.room_version.strict_canonicaljson: # Note that only the client controlled portion of the event is # checked, since we trust the portions of the event we created. validate_canonicaljson(event.content) if event.type == EventTypes.Aliases: if "aliases" in event.content: for alias in event.content["aliases"]: if len(alias) > MAX_ALIAS_LENGTH: raise SynapseError( 400, ( "Can't create aliases longer than" " %d characters" % (MAX_ALIAS_LENGTH,) ), Codes.INVALID_PARAM, ) if event.type == EventTypes.Retention: self._validate_retention(event) if event.type == EventTypes.ServerACL: if not server_matches_acl_event(config.server_name, event): raise SynapseError( 400, "Can't create an ACL event that denies the local server" )
def test_wildcard_matching(self): e = _create_acl_event({"allow": ["good*.com"]}) self.assertTrue( server_matches_acl_event("good.com", e), "* matches 0 characters", ) self.assertTrue( server_matches_acl_event("GOOD.COM", e), "pattern is case-insensitive", ) self.assertTrue( server_matches_acl_event("good.aa.com", e), "* matches several characters, including '.'", ) self.assertFalse( server_matches_acl_event("ishgood.com", e), "pattern does not allow prefixes", )
def validate_new(self, event: EventBase, config: HomeServerConfig) -> None: """Validates the event has roughly the right format Suitable for checking a locally-created event. It has stricter checks than is appropriate for an event received over federation (for which, see event_auth.validate_event_for_room_version) Args: event: The event to validate. config: The homeserver's configuration. """ self.validate_builder(event) if event.format_version == EventFormatVersions.V1: EventID.from_string(event.event_id) required = [ "auth_events", "content", "hashes", "origin", "prev_events", "sender", "type", ] for k in required: if k not in event: raise SynapseError(400, "Event does not have key %s" % (k, )) # Check that the following keys have string values event_strings = ["origin"] for s in event_strings: if not isinstance(getattr(event, s), str): raise SynapseError(400, "'%s' not a string type" % (s, )) # Depending on the room version, ensure the data is spec compliant JSON. if event.room_version.strict_canonicaljson: # Note that only the client controlled portion of the event is # checked, since we trust the portions of the event we created. validate_canonicaljson(event.content) if event.type == EventTypes.Aliases: if "aliases" in event.content: for alias in event.content["aliases"]: if len(alias) > MAX_ALIAS_LENGTH: raise SynapseError( 400, ("Can't create aliases longer than" " %d characters" % (MAX_ALIAS_LENGTH, )), Codes.INVALID_PARAM, ) if event.type == EventTypes.Retention: self._validate_retention(event) if event.type == EventTypes.ServerACL: if not server_matches_acl_event(config.server.server_name, event): raise SynapseError( 400, "Can't create an ACL event that denies the local server") if event.type == EventTypes.PowerLevels: try: jsonschema.validate( instance=event.content, schema=POWER_LEVELS_SCHEMA, cls=plValidator, ) except jsonschema.ValidationError as e: if e.path: # example: "users_default": '0' is not of type 'integer' # cast safety: path entries can be integers, if we fail to validate # items in an array. However the POWER_LEVELS_SCHEMA doesn't expect # to see any arrays. message = ( '"' + cast(str, e.path[-1]) + '": ' + e.message # noqa: B306 ) # jsonschema.ValidationError.message is a valid attribute else: # example: '0' is not of type 'integer' message = e.message # noqa: B306 # jsonschema.ValidationError.message is a valid attribute raise SynapseError( code=400, msg=message, errcode=Codes.BAD_JSON, )