]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Improve handling of REGISTER requests with multiple contact headers.
authorJeff Peeler <jpeeler@digium.com>
Mon, 6 Dec 2010 21:57:15 +0000 (21:57 +0000)
committerJeff Peeler <jpeeler@digium.com>
Mon, 6 Dec 2010 21:57:15 +0000 (21:57 +0000)
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: https://origsvn.digium.com/svn/asterisk/branches/1.4@297603 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c

index f42a7cc81d85822591107028598886772ad57725..bdc375ce42bb5c8f1a6fac89347990756c1a290c 100644 (file)
@@ -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