Module: sip-router Branch: 4.0 Commit: e7a8752ad427f8f23df25edc6bd2e7ba531ac6c4 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e7a8752a...
Author: Juha Heinanen jh@tutpro.com Committer: Juha Heinanen jh@tutpro.com Date: Fri May 3 19:53:12 2013 +0300
modules/rls: added support for escaped chars in rls-services document (cherry picked from commit fa9b8664a3b7c7a035c738a37b8ef0ef44190cb8)
---
modules/rls/notify.c | 61 ++++++++++++++++++++++++---------------------- modules/rls/subscribe.c | 46 +++++++++++++++++++++++++++------- modules/rls/utils.c | 54 +++++++++++++++++++++++++++++++++++++++++ modules/rls/utils.h | 31 ++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 39 deletions(-)
diff --git a/modules/rls/notify.c b/modules/rls/notify.c index f0ec0aa..7b5bec3 100644 --- a/modules/rls/notify.c +++ b/modules/rls/notify.c @@ -48,6 +48,7 @@ #include "../../hashes.h" #include "rls.h" #include "notify.h" +#include "utils.h" #include <libxml/xpath.h> #include <libxml/xpathInternals.h>
@@ -1003,7 +1004,7 @@ int process_list_and_exec(xmlNodePtr list_node, str username, str domain, list_func_t function, void* param) { xmlNodePtr node; - char* uri = NULL; + str uri; int res = 0;
for(node= list_node->children; node; node= node->next) @@ -1014,16 +1015,33 @@ int process_list_and_exec(xmlNodePtr list_node, str username, str domain, unsigned short port = 0; xmlNodePtr rl_node = NULL; xmlDocPtr rl_doc = NULL; + str unescaped_uri; + char buf[MAX_URI_SIZE]; +
- uri= XMLNodeGetNodeContentByName(node, "resource-list", NULL); - - if (uri == NULL) + uri.s = XMLNodeGetNodeContentByName(node, "resource-list", NULL); + if (uri.s == NULL) { LM_ERR("when extracting URI from node\n"); return -1; } + uri.len = strlen(uri.s); + if (uri.len > MAX_URI_SIZE-1) { + LM_ERR("XCAP URI is too long\n"); + return -1; + } + LM_DBG("got resource-list uri <%.*s>\n", uri.len, uri.s); + + unescaped_uri.s = buf; + unescaped_uri.len = 0; + if (un_escape(&uri, &unescaped_uri) < 0) { + LM_ERR("Error un-escaping XCAP URI\n"); + return -1; + } + unescaped_uri.s[unescaped_uri.len] = 0; + LM_DBG("got unescaped uri <%s>\n", unescaped_uri.s);
- if(parse_xcap_uri(uri, &hostname, &port, &rl_uri)>0) + if(parse_xcap_uri(unescaped_uri.s, &hostname, &port, &rl_uri)>0) { if (rls_integrated_xcap_server == 1 && (hostname.len == 0 @@ -1034,13 +1052,13 @@ int process_list_and_exec(xmlNodePtr list_node, str username, str domain, { LM_DBG("calling myself for rl_node\n"); res = process_list_and_exec(rl_node, username, domain, function, param); - xmlFree(uri); + xmlFree(uri.s); xmlFreeDoc(rl_doc); } else { LM_ERR("<resource-list/> not found\n"); - xmlFree(uri); + xmlFree(uri.s); return -1; } @@ -1048,7 +1066,7 @@ int process_list_and_exec(xmlNodePtr list_node, str username, str domain, else { LM_ERR("<resource-list/> is not local - unsupported at this time\n"); - xmlFree(uri); + xmlFree(uri.s); return -1; } } @@ -1061,20 +1079,20 @@ int process_list_and_exec(xmlNodePtr list_node, str username, str domain, else if(xmlStrcasecmp(node->name,(unsigned char*)"entry")== 0) { - uri= XMLNodeGetAttrContentByName(node, "uri"); - if(uri== NULL) + uri.s = XMLNodeGetAttrContentByName(node, "uri"); + if(uri.s== NULL) { LM_ERR("when extracting entry uri attribute\n"); return -1; } - LM_DBG("uri= %s\n", uri); - if(function(uri, param)< 0) + LM_DBG("uri= %s\n", uri.s); + if(function(uri.s, param)< 0) { LM_ERR("in function given as a parameter\n"); - xmlFree(uri); + xmlFree(uri.s); return -1; } - xmlFree(uri); + xmlFree(uri.s); } else if(xmlStrcasecmp(node->name,(unsigned char*)"list")== 0) @@ -1253,21 +1271,6 @@ int rls_get_resource_list(str *rl_uri, str *username, str *domain, path.len += 7; checked++; } - else if (checked <= rl_uri->len - 3 && strncmp(rl_uri->s + checked, "%5b", 3) == 0) - { - path.s[path.len++] = '['; - checked += 3; - } - else if (checked <= rl_uri->len - 3 && strncmp(rl_uri->s + checked, "%5d", 3) == 0) - { - path.s[path.len++] = ']'; - checked += 3; - } - else if (checked <= rl_uri->len - 3 && strncmp(rl_uri->s + checked, "%22", 3) == 0) - { - path.s[path.len++] = '"'; - checked += 3; - } else { path.s[path.len++] = rl_uri->s[checked]; diff --git a/modules/rls/subscribe.c b/modules/rls/subscribe.c index e022c43..5ebd739 100644 --- a/modules/rls/subscribe.c +++ b/modules/rls/subscribe.c @@ -51,6 +51,7 @@ #include "rls.h" #include "../../mod_fix.h" #include "list.h" +#include "utils.h"
int counter= 0;
@@ -72,10 +73,12 @@ int remove_expired_rlsubs( subs_t* subs,unsigned int hash_code); /** * return the XML node for rls-services matching uri */ -xmlNodePtr rls_get_by_service_uri(xmlDocPtr doc, str* uri) +xmlNodePtr rls_get_by_service_uri(xmlDocPtr doc, str* service_uri) { xmlNodePtr root, node; - char* val; + struct sip_uri sip_uri; + str uri, uri_str; + str *normalized_uri;
root = XMLDocGetNodeByName(doc, "rls-services", NULL); if(root==NULL) @@ -88,16 +91,39 @@ xmlNodePtr rls_get_by_service_uri(xmlDocPtr doc, str* uri) { if(xmlStrcasecmp(node->name, (unsigned char*)"service")==0) { - val = XMLNodeGetAttrContentByName(node, "uri"); - if(val!=NULL) + uri.s = XMLNodeGetAttrContentByName(node, "uri"); + if (uri.s == NULL) { - if((uri->len==strlen(val)) && (strncmp(val, uri->s, uri->len)==0)) - { - xmlFree(val); - return node; - } - xmlFree(val); + LM_DBG("failed to fetch 'uri' in service [invalid XML from XCAP]\n"); + continue; + } + uri.len = strlen(uri.s); + normalized_uri = normalize_sip_uri(&uri); + if (normalized_uri->s == NULL || normalized_uri->len == 0) + { + LM_ERR("failed to normalize service URI\n"); + xmlFree(uri.s); + return NULL; + } + xmlFree(uri.s); + if(parse_uri(normalized_uri->s, normalized_uri->len, &sip_uri)< 0) + { + LM_ERR("failed to parse uri\n"); + return NULL; + } + if(uandd_to_uri(sip_uri.user, sip_uri.host, &uri_str)< 0) + { + LM_ERR("failed to construct uri from user and domain\n"); + return NULL; + } + if(uri_str.len== service_uri->len && + strncmp(uri_str.s, service_uri->s, uri_str.len) == 0) + { + pkg_free(uri_str.s); + return node; } + LM_DBG("match not found, service-uri = [%.*s]\n", uri_str.len, uri_str.s); + pkg_free(uri_str.s); } } return NULL; diff --git a/modules/rls/utils.c b/modules/rls/utils.c new file mode 100644 index 0000000..161529c --- /dev/null +++ b/modules/rls/utils.c @@ -0,0 +1,54 @@ +/* + * rls module - resource list server + * + * Copyright (C) 2012 AG Projects + * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * Kamailio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "../../ut.h" + +#define SIP_PREFIX "sip:" +#define SIP_PREFIX_LEN sizeof(SIP_PREFIX)-1 + +str* normalize_sip_uri(const str *uri) +{ + static str normalized_uri; + static str null_str = {NULL, 0}; + static char buf[MAX_URI_SIZE]; + + normalized_uri.s = buf; + if (un_escape((str *)uri, &normalized_uri) < 0) + { + LM_ERR("un-escaping URI\n"); + return &null_str; + } + + normalized_uri.s[normalized_uri.len] = '\0'; + if (strncasecmp(normalized_uri.s, SIP_PREFIX, SIP_PREFIX_LEN) != 0 && strchr(normalized_uri.s, '@') != NULL) + { + memmove(normalized_uri.s+SIP_PREFIX_LEN, normalized_uri.s, normalized_uri.len+1); + memcpy(normalized_uri.s, SIP_PREFIX, SIP_PREFIX_LEN); + normalized_uri.len += SIP_PREFIX_LEN; + } + + return &normalized_uri; +} + +#undef SIP_PREFIX +#undef SIP_PREFIX_LEN diff --git a/modules/rls/utils.h b/modules/rls/utils.h new file mode 100644 index 0000000..4b245e7 --- /dev/null +++ b/modules/rls/utils.h @@ -0,0 +1,31 @@ +/* + * rls module - resource list server + * + * Copyright (C) 2012 AG Projects + * + * This file is part of Kamailio, a free SIP server. + * + * Kamailio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version + * + * Kamailio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef RLS_URILS_H +#define RLS_UTILS_H + +#include "../../ut.h" + +extern str* normalize_sip_uri(const str *uri); + +#endif