[sr-dev] git:master: modules/rls: added support for escaped chars in rls-services document

Juha Heinanen jh at tutpro.com
Fri May 3 18:56:15 CEST 2013


Module: sip-router
Branch: master
Commit: fa9b8664a3b7c7a035c738a37b8ef0ef44190cb8
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=fa9b8664a3b7c7a035c738a37b8ef0ef44190cb8

Author: Juha Heinanen <jh at tutpro.com>
Committer: Juha Heinanen <jh at 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




More information about the sr-dev mailing list