Module: sip-router
Branch: master
Commit: fa9b8664a3b7c7a035c738a37b8ef0ef44190cb8
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fa9b866…
Author: Juha Heinanen <jh(a)tutpro.com>
Committer: Juha Heinanen <jh(a)tutpro.com>
Date: Fri May 3 19:53:12 2013 +0300
modules/rls: added support for escaped chars in rls-services document
---
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 3bedf65..d15a601 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