1 /*
2  * Copyright (C) 2011 Crocodile RCS Ltd.
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * Kamailio is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  * Kamailio is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20 
21 
22 #include <stdio.h>
23 #include <libxml/parser.h>
24 
25 #include "../../core/parser/msg_parser.h"
26 #include "../../core/parser/parse_uri.h"
27 #include "../../core/str.h"
28 #include "../presence/event_list.h"
29 #include "pres_check.h"
30 #include "pidf.h"
31 #include "presence_xml.h"
32 
presxml_check_basic(struct sip_msg * msg,str presentity_uri,str status)33 int presxml_check_basic(struct sip_msg *msg, str presentity_uri, str status)
34 {
35 	str *presentity = NULL;
36 	struct sip_uri parsed_uri;
37 	pres_ev_t *ev;
38 	static str event = str_init("presence");
39 	int retval = -1;
40 	xmlDocPtr xmlDoc = NULL;
41 	xmlNodePtr tuple = NULL, basicNode = NULL;
42 	char *basicVal = NULL;
43 
44 	if(parse_uri(presentity_uri.s, presentity_uri.len, &parsed_uri) < 0) {
45 		LM_ERR("bad uri: %.*s\n", presentity_uri.len, presentity_uri.s);
46 		return -1;
47 	}
48 
49 	ev = psapi.contains_event(&event, NULL);
50 	if(ev == NULL) {
51 		LM_ERR("event presence is not registered\n");
52 		return -1;
53 	}
54 
55 	presentity = psapi.get_presentity(presentity_uri, ev, NULL, NULL);
56 
57 	if(presentity == NULL || presentity->len <= 0 || presentity->s == NULL) {
58 		LM_DBG("cannot get presentity for %.*s\n", presentity_uri.len,
59 				presentity_uri.s);
60 		return -1;
61 	}
62 
63 	if((xmlDoc = xmlParseMemory(presentity->s, presentity->len)) == NULL) {
64 		LM_ERR("while parsing XML memory\n");
65 		goto error;
66 	}
67 
68 	if((tuple = xmlDocGetNodeByName(xmlDoc, "tuple", NULL)) == NULL) {
69 		LM_ERR("unable to extract 'tuple'\n");
70 		goto error;
71 	}
72 
73 	while(tuple != NULL) {
74 		if(xmlStrcasecmp(tuple->name, (unsigned char *)"tuple") == 0) {
75 			if((basicNode = xmlNodeGetNodeByName(tuple, "basic", NULL))
76 					== NULL) {
77 				LM_ERR("while extracting 'basic' node\n");
78 				goto error;
79 			}
80 
81 			if((basicVal = (char *)xmlNodeGetContent(basicNode)) == NULL) {
82 				LM_ERR("while getting 'basic' content\n");
83 				goto error;
84 			}
85 
86 			if(strncasecmp(basicVal, status.s, status.len) == 0)
87 				retval = 1;
88 
89 			xmlFree(basicVal);
90 		}
91 		tuple = tuple->next;
92 	}
93 error:
94 	if(xmlDoc != NULL)
95 		xmlFreeDoc(xmlDoc);
96 	psapi.free_presentity(presentity, ev);
97 	return retval;
98 }
99 
presxml_check_activities(struct sip_msg * msg,str presentity_uri,str activity)100 int presxml_check_activities(
101 		struct sip_msg *msg, str presentity_uri, str activity)
102 {
103 	str *presentity = NULL;
104 	struct sip_uri parsed_uri;
105 	pres_ev_t *ev;
106 	static str event = str_init("presence");
107 	char *nodeName = NULL;
108 	int retval = -1;
109 	xmlDocPtr xmlDoc = NULL;
110 	xmlNodePtr person = NULL, activitiesNode = NULL, activityNode = NULL;
111 
112 	if(parse_uri(presentity_uri.s, presentity_uri.len, &parsed_uri) < 0) {
113 		LM_ERR("bad uri: %.*s\n", presentity_uri.len, presentity_uri.s);
114 		return -1;
115 	}
116 
117 	ev = psapi.contains_event(&event, NULL);
118 	if(ev == NULL) {
119 		LM_ERR("event presence is not registered\n");
120 		return -1;
121 	}
122 
123 	if((nodeName = pkg_malloc(activity.len + 1)) == NULL) {
124 		LM_ERR("cannot pkg_malloc for nodeName\n");
125 		return -1;
126 	}
127 	memcpy(nodeName, activity.s, activity.len);
128 	nodeName[activity.len] = '\0';
129 
130 	presentity = psapi.get_presentity(presentity_uri, ev, NULL, NULL);
131 
132 	if(presentity == NULL || presentity->len <= 0 || presentity->s == NULL) {
133 		LM_DBG("cannot get presentity for %.*s\n", presentity_uri.len,
134 				presentity_uri.s);
135 		goto error;
136 	}
137 
138 	if((xmlDoc = xmlParseMemory(presentity->s, presentity->len)) == NULL) {
139 		LM_ERR("while parsing XML memory\n");
140 		goto error;
141 	}
142 
143 	if((person = xmlDocGetNodeByName(xmlDoc, "person", NULL)) == NULL) {
144 		LM_DBG("unable to extract 'person'\n");
145 		retval = -2;
146 		goto error;
147 	}
148 
149 	while(person != NULL) {
150 		if(xmlStrcasecmp(person->name, (unsigned char *)"person") == 0) {
151 			if((activitiesNode =
152 							   xmlNodeGetNodeByName(person, "activities", NULL))
153 					== NULL) {
154 				LM_DBG("unable to extract 'activities' node\n");
155 				if(retval <= 0) {
156 					retval = -2;
157 				}
158 				break;
159 			}
160 
161 			if(activitiesNode->children == NULL) {
162 				LM_DBG("activities node has no children\n");
163 				if(retval <= 0) {
164 					retval = -2;
165 				}
166 				break;
167 			}
168 
169 			if((activityNode = xmlNodeGetNodeByName(
170 						activitiesNode, nodeName, NULL))
171 					!= NULL) {
172 				retval = 1;
173 			}
174 		}
175 		person = person->next;
176 	}
177 error:
178 	if(nodeName != NULL)
179 		pkg_free(nodeName);
180 	if(xmlDoc != NULL)
181 		xmlFreeDoc(xmlDoc);
182 	if(presentity != NULL)
183 		psapi.free_presentity(presentity, ev);
184 	return retval;
185 }
186