aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorjpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b>2010-12-06 21:57:15 +0000
committerjpeeler <jpeeler@f38db490-d61c-443f-a65b-d21fe96a405b>2010-12-06 21:57:15 +0000
commit1296b9dcbd3c1bfbf0aa2f80754873cdad2a29f0 (patch)
tree76af46a87816153c263cf90d06add378bfd6058a /channels
parent7bfd49b0f5e37b2deb984187098d24cd923592da (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.c36
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