aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authorrizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b>2006-10-23 15:45:36 +0000
committerrizzo <rizzo@f38db490-d61c-443f-a65b-d21fe96a405b>2006-10-23 15:45:36 +0000
commit3aec4109a4ad01617867f256e152c1909d61d8e2 (patch)
tree7a96e9033a91cb618fa17399fdcddcd12c4e73e0 /channels
parentaa8d8a3187dde357ea89feadf87c884f7f10f92f (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.c50
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.