aboutsummaryrefslogtreecommitdiffstats
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
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
-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