From f56d3a4e5dec3aa75d25fae761a0642e6ebd7c3c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 11 Oct 2005 00:58:04 +0000 Subject: [PATCH] * rename avahi_is_valid_service_type() to avahi_is_valid_service_type_generic() * add avahi_is_valid_service_type_strict() which doesn't allow subtypes and other strange things to pass * fix protocol validity checks in server.c * add new API function avahi_get_type_from_subtype() git-svn-id: file:///home/lennart/svn/public/avahi/trunk@716 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-common/domain-test.c | 24 +++++++-- avahi-common/domain.c | 99 +++++++++++++++++++++++++++++++++++- avahi-common/domain.h | 17 ++++++- avahi-core/browse-service.c | 2 +- avahi-core/resolve-service.c | 2 +- avahi-core/server.c | 14 +++-- 6 files changed, 141 insertions(+), 17 deletions(-) diff --git a/avahi-common/domain-test.c b/avahi-common/domain-test.c index 444f553..f1313cb 100644 --- a/avahi-common/domain-test.c +++ b/avahi-common/domain-test.c @@ -84,9 +84,27 @@ int main(int argc, char *argv[]) { assert(avahi_domain_ends_with("foo.bar.\\065\\\\\\.aaaa", "\\065\\\\\\.aaaa")); - assert(avahi_is_valid_service_type("_foo._bar._waldo")); - assert(!avahi_is_valid_service_type("_foo._bar.waldo")); - assert(!avahi_is_valid_service_type("")); + assert(avahi_is_valid_service_type_generic("_foo._bar._waldo")); + assert(!avahi_is_valid_service_type_strict("_foo._bar._waldo")); + assert(!avahi_is_valid_service_subtype("_foo._bar._waldo")); + + assert(avahi_is_valid_service_type_generic("_foo._tcp")); + assert(avahi_is_valid_service_type_strict("_foo._tcp")); + assert(!avahi_is_valid_service_subtype("_foo._tcp")); + + assert(!avahi_is_valid_service_type_generic("_foo._bar.waldo")); + assert(!avahi_is_valid_service_type_strict("_foo._bar.waldo")); + assert(!avahi_is_valid_service_subtype("_foo._bar.waldo")); + + assert(!avahi_is_valid_service_type_generic("")); + assert(!avahi_is_valid_service_type_strict("")); + assert(!avahi_is_valid_service_subtype("")); + + assert(avahi_is_valid_service_type_generic("_foo._sub._bar._tcp")); + assert(!avahi_is_valid_service_type_strict("_foo._sub._bar._tcp")); + assert(avahi_is_valid_service_subtype("_foo._sub._bar._tcp")); + + printf("%s\n", avahi_get_type_from_subtype("_foo._sub._bar._tcp")); assert(!avahi_is_valid_host_name("sf.ooo.")); assert(avahi_is_valid_host_name("sfooo.")); diff --git a/avahi-common/domain.c b/avahi-common/domain.c index b72a898..f2e4395 100644 --- a/avahi-common/domain.c +++ b/avahi-common/domain.c @@ -293,7 +293,7 @@ int avahi_binary_domain_cmp(const char *a, const char *b) { } } -int avahi_is_valid_service_type(const char *t) { +int avahi_is_valid_service_type_generic(const char *t) { assert(t); if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t) @@ -313,6 +313,101 @@ int avahi_is_valid_service_type(const char *t) { return 1; } +int avahi_is_valid_service_type_strict(const char *t) { + char label[AVAHI_LABEL_MAX]; + assert(t); + + if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t) + return 0; + + /* Application name */ + + if (!(avahi_unescape_label(&t, label, sizeof(label)))) + return 0; + + if (strlen(label) <= 2 || label[0] != '_') + return 0; + + if (!*t) + return 0; + + /* _tcp or _udp boilerplate */ + + if (!(avahi_unescape_label(&t, label, sizeof(label)))) + return 0; + + if (strcasecmp(label, "_tcp") && strcasecmp(label, "_udp")) + return 0; + + if (*t) + return 0; + + return 1; +} + +const char *avahi_get_type_from_subtype(const char *t) { + char label[AVAHI_LABEL_MAX]; + const char *ret; + assert(t); + + if (strlen(t) >= AVAHI_DOMAIN_NAME_MAX || !*t) + return NULL; + + /* Subtype name */ + + if (!(avahi_unescape_label(&t, label, sizeof(label)))) + return NULL; + + if (strlen(label) <= 2 || label[0] != '_') + return NULL; + + if (!*t) + return NULL; + + /* String "_sub" */ + + if (!(avahi_unescape_label(&t, label, sizeof(label)))) + return NULL; + + if (strcasecmp(label, "_sub")) + return NULL; + + if (!*t) + return NULL; + + ret = t; + + /* Application name */ + + if (!(avahi_unescape_label(&t, label, sizeof(label)))) + return NULL; + + if (strlen(label) <= 2 || label[0] != '_') + return NULL; + + if (!*t) + return NULL; + + /* _tcp or _udp boilerplate */ + + if (!(avahi_unescape_label(&t, label, sizeof(label)))) + return NULL; + + if (strcasecmp(label, "_tcp") && strcasecmp(label, "_udp")) + return NULL; + + if (*t) + return NULL; + + return ret; +} + +int avahi_is_valid_service_subtype(const char *t) { + assert(t); + + return !!avahi_get_type_from_subtype(t); +} + int avahi_is_valid_domain_name(const char *t) { assert(t); @@ -407,7 +502,7 @@ int avahi_service_name_join(char *p, size_t size, const char *name, const char * if ((name && !avahi_is_valid_service_name(name))) return AVAHI_ERR_INVALID_SERVICE_NAME; - if (!avahi_is_valid_service_type(type)) + if (!avahi_is_valid_service_type_generic(type)) return AVAHI_ERR_INVALID_SERVICE_TYPE; if (!avahi_is_valid_domain_name(domain)) diff --git a/avahi-common/domain.h b/avahi-common/domain.h index bcd036e..26f4b73 100644 --- a/avahi-common/domain.h +++ b/avahi-common/domain.h @@ -75,8 +75,21 @@ char *avahi_unescape_label(const char **name, char *dest, size_t size); /** Escape the domain name in *src and write it to *ret_name */ char *avahi_escape_label(const char* src, size_t src_length, char **ret_name, size_t *ret_size); -/** Return 1 when the specified string contains a valid service type, 0 otherwise */ -int avahi_is_valid_service_type(const char *t); +/** Return 1 when the specified string contains a valid generic + * service type (i.e. a series of words starting with "_"), 0 + * otherwise */ +int avahi_is_valid_service_type_generic(const char *t); + +/** Return 1 when the specified string contains a valid strict service + * type (i.e. consisting of only two words, the latter being either + * _udp or _tcp), 0 otherwise */ +int avahi_is_valid_service_type_strict(const char *t); + +/** Return 1 when the specified string contains a valid service subtype, 0 otherwise */ +int avahi_is_valid_service_subtype(const char *t); + +/** Return a pointer to the type section of a subtype i.e. _foo._sub._bar._tcp => _bar._tcp */ +const char *avahi_get_type_from_subtype(const char *t); /** Return 1 when the specified string contains a valid domain name, 0 otherwise */ int avahi_is_valid_domain_name(const char *t); diff --git a/avahi-core/browse-service.c b/avahi-core/browse-service.c index d89ad7a..170a64f 100644 --- a/avahi-core/browse-service.c +++ b/avahi-core/browse-service.c @@ -99,7 +99,7 @@ AvahiSServiceBrowser *avahi_s_service_browser_new( AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL); AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS); - AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type(service_type), AVAHI_ERR_INVALID_SERVICE_TYPE); + AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type_generic(service_type), AVAHI_ERR_INVALID_SERVICE_TYPE); if (!domain) domain = server->domain_name; diff --git a/avahi-core/resolve-service.c b/avahi-core/resolve-service.c index 43b61d2..85ac3d5 100644 --- a/avahi-core/resolve-service.c +++ b/avahi-core/resolve-service.c @@ -409,7 +409,7 @@ AvahiSServiceResolver *avahi_s_service_resolver_new( AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(aprotocol), AVAHI_ERR_INVALID_PROTOCOL); AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !name || avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME); - AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type(type), AVAHI_ERR_INVALID_SERVICE_TYPE); + AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE); AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST|AVAHI_LOOKUP_NO_TXT|AVAHI_LOOKUP_NO_ADDRESS), AVAHI_ERR_INVALID_FLAGS); if (!domain) diff --git a/avahi-core/server.c b/avahi-core/server.c index fdc53d5..0c47cf8 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -1936,10 +1936,10 @@ static int server_add_service_strlst_nocopy( assert(name); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); - AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(interface), AVAHI_ERR_INVALID_PROTOCOL); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_IS_PROXY), AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME); - AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type(type), AVAHI_ERR_INVALID_SERVICE_TYPE); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !host || avahi_is_valid_domain_name(host), AVAHI_ERR_INVALID_HOST_NAME); @@ -2007,8 +2007,6 @@ fail: return ret; } - - int avahi_server_add_service_strlst( AvahiServer *s, AvahiSEntryGroup *g, @@ -2095,12 +2093,12 @@ int avahi_server_add_service_subtype( assert(subtype); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE); - AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(interface), AVAHI_ERR_INVALID_PROTOCOL); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_IS_PROXY), AVAHI_ERR_INVALID_FLAGS); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME); - AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type(type), AVAHI_ERR_INVALID_SERVICE_TYPE); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE); AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME); - AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type(subtype), AVAHI_ERR_INVALID_SERVICE_SUBTYPE); + AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_subtype(subtype), AVAHI_ERR_INVALID_SERVICE_SUBTYPE); if (!domain) domain = s->domain_name; @@ -2610,7 +2608,7 @@ int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex interface, AvahiP if (!avahi_is_valid_service_name(name)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_NAME); - if (!avahi_is_valid_service_type(type)) + if (!avahi_is_valid_service_type_strict(type)) return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_TYPE); if (domain && !avahi_is_valid_domain_name(domain)) -- 2.39.5