diff options
author | rizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-10-23 15:45:36 +0000 |
---|---|---|
committer | rizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-10-23 15:45:36 +0000 |
commit | 3aec4109a4ad01617867f256e152c1909d61d8e2 (patch) | |
tree | 7a96e9033a91cb618fa17399fdcddcd12c4e73e0 /channels | |
parent | aa8d8a3187dde357ea89feadf87c884f7f10f92f (diff) |
+ make sure parse_uri never returns NULL pointers - this
simplifies its usage.
+ add another client for parse_uri, in handling Contact: strings
(on passing, document the content of the "fullcontact" field);
+ in register_verify(), mark with XXX what i believe is another
misinterpretation on the URI format when '@' is missing.
No code changed here, so no fixes applied.
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@45977 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_sip.c | 50 |
1 files changed, 17 insertions, 33 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index fb87cf7d7..4e8e1e828 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -912,6 +912,7 @@ struct sip_pvt { AST_STRING_FIELD(cid_name); /*!< Caller*ID name */ AST_STRING_FIELD(via); /*!< Via: header */ AST_STRING_FIELD(fullcontact); /*!< The Contact: that the UA registers with us */ + /* we only store the part in <brackets> in this field. */ AST_STRING_FIELD(our_contact); /*!< Our contact header */ AST_STRING_FIELD(rpid); /*!< Our RPID header */ AST_STRING_FIELD(rpid_from); /*!< Our RPID From header */ @@ -2242,7 +2243,7 @@ static char *get_in_brackets(char *tmp) * name:pass and domain:port. * It is safe to call with ret_name, pass, domain, port * pointing all to the same place. - * + * Init pointers to empty string so we never get NULL dereferencing. * Overwrites the string. * return 0 on success, other values on error. */ @@ -2254,9 +2255,9 @@ static int parse_uri(char *uri, char *scheme, /* init field as required */ if (*pass) - *pass = NULL; + *pass = ""; if (*port) - *port = NULL; + *port = ""; name = strsep(&uri, ";"); /* remove options */ if (scheme) { int l = strlen(scheme); @@ -2275,12 +2276,12 @@ static int parse_uri(char *uri, char *scheme, /* store the result in a temp. variable to avoid it being * overwritten if arguments point to the same place. */ - char *c, *dom = NULL; + char *c, *dom = ""; if ((c = strchr(name, '@')) == NULL) { /* domain-only URI, according to the SIP RFC. */ dom = name; - name = NULL; + name = ""; } else { *c++ = '\0'; dom = c; @@ -2289,7 +2290,7 @@ static int parse_uri(char *uri, char *scheme, *c++ = '\0'; *port = c; } - if (name && pass && (c = strchr(name, ':'))) { /* user:password */ + if (pass && (c = strchr(name, ':'))) { /* user:password */ *c++ = '\0'; *pass = c; } @@ -2298,7 +2299,7 @@ static int parse_uri(char *uri, char *scheme, if (ret_name) /* same as for domain, store the result only at the end */ *ret_name = name; if (options) - *options = uri; + *options = uri ? uri : ""; return error; } @@ -7590,7 +7591,7 @@ static int set_address_from_contact(struct sip_pvt *pvt) struct hostent *hp; struct ast_hostent ahp; int port; - char *c, *host, *pt; + char *host, *pt; char *contact; @@ -7604,32 +7605,12 @@ static int set_address_from_contact(struct sip_pvt *pvt) /* Work on a copy */ contact = ast_strdupa(pvt->fullcontact); + /* We have only the part in <brackets> here so we just need to parse a SIP URI.*/ - /* XXX this code is repeated all over */ - /* Make sure it's a SIP URL */ - if (strncasecmp(contact, "sip:", 4)) { + if (parse_uri(contact, "sip:", &contact, NULL, &host, &pt, NULL)) ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); - } else - contact += 4; - - /* Ditch arguments */ - /* XXX this code is replicated also shortly below */ - contact = strsep(&contact, ";"); /* trim ; and beyond */ - - /* Grab host */ - host = strchr(contact, '@'); - if (!host) { /* No username part */ - host = contact; - c = NULL; - } else { - *host++ = '\0'; - } - pt = strchr(host, ':'); - if (pt) { - *pt++ = '\0'; - port = atoi(pt); - } else - port = STANDARD_SIP_PORT; + port = !ast_strlen_zero(pt) ? atoi(pt) : STANDARD_SIP_PORT; + ast_verbose("--- set_address_from_contact host '%s'\n", host); /* XXX This could block for a long time XXX */ /* We should only do this if it's a name, not an IP */ @@ -8193,6 +8174,9 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct sockaddr ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); } + /* XXX here too we interpret a missing @domain as a name-only + * URI, whereas the RFC says this is a domain-only uri. + */ /* Strip off the domain name */ if ((c = strchr(name, '@'))) { *c++ = '\0'; @@ -9233,7 +9217,7 @@ static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_requ if (parse_uri(of, "sip:", &of, &dummy, &domain, &dummy, &dummy)) { ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); } - if (of == NULL) { + if (ast_strlen_zero(of)) { /* XXX note: the original code considered a missing @host * as a username-only URI. The SIP RFC (19.1.1) says that * this is wrong, and it should be considered as a domain-only URI. |