diff options
author | jpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-12-06 21:57:15 +0000 |
---|---|---|
committer | jpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b> | 2010-12-06 21:57:15 +0000 |
commit | 1296b9dcbd3c1bfbf0aa2f80754873cdad2a29f0 (patch) | |
tree | 76af46a87816153c263cf90d06add378bfd6058a /channels | |
parent | 7bfd49b0f5e37b2deb984187098d24cd923592da (diff) |
Improve handling of REGISTER requests with multiple contact headers.
The changes here attempt to more strictly follow RFC 3261 section 10.3.
Basically the following will now cause a 400 Bad Response to be returned, if:
- multiple Contact headers are present with one set to expire all bindings ("*")
- wildcard parameter is specified for Contact without Expires header or Expires
header is not set to zero.
ABE-2442
ABE-2443
git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@297603 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_sip.c | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index f42a7cc81..bdc375ce4 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -8812,8 +8812,12 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st struct hostent *hp; struct ast_hostent ahp; struct sockaddr_in oldsin, testsin; + char *firstcuri = NULL; + int start = 0; + int wildcard_found = 0; + int single_binding_found; - ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact)); + ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); if (ast_strlen_zero(expires)) { /* No expires header */ expires = strcasestr(contact, ";expires="); @@ -8828,11 +8832,31 @@ static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, st } } - /* Look for brackets */ - curi = contact; - if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ - strsep(&curi, ";"); /* This is Header options, not URI options */ - curi = get_in_brackets(contact); + do { + /* Look for brackets */ + curi = contact; + if (strchr(contact, '<') == NULL) /* No <, check for ; and strip it */ + strsep(&curi, ";"); /* This is Header options, not URI options */ + curi = get_in_brackets(contact); + if (!firstcuri) { + firstcuri = ast_strdupa(curi); + } + + if (!strcasecmp(curi, "*")) { + wildcard_found = 1; + } else { + single_binding_found = 1; + } + + if (wildcard_found && (ast_strlen_zero(expires) || expiry != 0 || single_binding_found)) { + /* Contact header parameter "*" detected, so punt if: Expires header is missing, + * Expires value is not zero, or another Contact header is present. */ + return PARSE_REGISTER_FAILED; + } + + ast_copy_string(contact, __get_header(req, "Contact", &start), sizeof(contact)); + } while (!ast_strlen_zero(contact)); + curi = firstcuri; /* if they did not specify Contact: or Expires:, they are querying what we currently have stored as their contact address, so return |