1 /*
2  * Various URI checks and URI manipulation
3  *
4  * Copyright (C) 2001-2003 FhG Fokus
5  *
6  * Copyright (C) 2004-2010 Juha Heinanen
7  *
8  * This file is part of Kamailio, a free SIP server.
9  *
10  * Kamailio is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version
14  *
15  * Kamailio is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  *
24  */
25 
26 /*!
27  * \file
28  * \brief SIP-utils :: Various URI checks and Request URI manipulation
29  * \ingroup siputils
30  * - Module; \ref siputils
31  */
32 
33 
34 #include <string.h>
35 #include "../../core/str.h"
36 #include "../../core/dprint.h"               /* Debugging */
37 #include "../../core/mem/mem.h"
38 #include "../../core/parser/digest/digest.h" /* get_authorized_cred */
39 #include "../../core/parser/parse_from.h"
40 #include "../../core/parser/parse_uri.h"
41 #include "../../core/parser/parse_param.h"
42 #include "../../core/ut.h"                   /* Handy utilities */
43 #include "../../lib/srdb1/db.h"                /* Database API */
44 #include "../../core/dset.h"
45 #include "../../core/pvar.h"
46 #include "../../core/lvalue.h"
47 #include "../../core/sr_module.h"
48 #include "../../core/mod_fix.h"
49 #include "checks.h"
50 
51 /**
52  * return 1 (true) if the SIP message type is request
53  */
w_is_request(struct sip_msg * msg,char * foo,char * bar)54 int w_is_request(struct sip_msg* msg, char *foo, char *bar)
55 {
56 	if(msg==NULL)
57 		return -1;
58 
59 	if(msg->first_line.type == SIP_REQUEST)
60 		return 1;
61 
62 	return -1;
63 }
64 
is_request(struct sip_msg * msg)65 int is_request(struct sip_msg* msg)
66 {
67 	if(msg==NULL)
68 		return -1;
69 
70 	if(msg->first_line.type == SIP_REQUEST)
71 		return 1;
72 
73 	return -1;
74 }
75 
76 /**
77  * return 1 (true) if the SIP message type is reply
78  */
w_is_reply(struct sip_msg * msg,char * foo,char * bar)79 int w_is_reply(struct sip_msg* msg, char *foo, char *bar)
80 {
81 	if(msg==NULL)
82 		return -1;
83 
84 	if(msg->first_line.type == SIP_REPLY)
85 		return 1;
86 
87 	return -1;
88 }
89 
is_reply(struct sip_msg * msg)90 int is_reply(struct sip_msg* msg)
91 {
92 	if(msg==NULL)
93 		return -1;
94 
95 	if(msg->first_line.type == SIP_REPLY)
96 		return 1;
97 
98 	return -1;
99 }
100 
101 
102 /*
103  * Checks if From includes a To-tag -- good to identify
104  * if a request creates a new dialog
105  */
has_totag(struct sip_msg * _m)106 int has_totag(struct sip_msg* _m)
107 {
108 	str tag;
109 
110 	if (!_m->to && parse_headers(_m, HDR_TO_F,0)==-1) {
111 		LM_ERR("To parsing failed\n");
112 		return -1;
113 	}
114 	if (!_m->to) {
115 		LM_ERR("no To\n");
116 		return -1;
117 	}
118 	tag=get_to(_m)->tag_value;
119 	if (tag.s==0 || tag.len==0) {
120 		LM_DBG("no totag\n");
121 		return -1;
122 	}
123 	LM_DBG("totag found\n");
124 	return 1;
125 }
126 
w_has_totag(struct sip_msg * _m,char * _foo,char * _bar)127 int w_has_totag(struct sip_msg* _m, char* _foo, char* _bar)
128 {
129 	return has_totag(_m);
130 }
131 
132 /*
133  * Check if pseudo variable contains a valid uri
134  */
is_uri(struct sip_msg * _m,char * _sp,char * _s2)135 int is_uri(struct sip_msg* _m, char* _sp, char* _s2)
136 {
137 	sip_uri_t turi;
138 	str uval;
139 
140 	if(fixup_get_svalue(_m, (gparam_t*)_sp, &uval)!=0) {
141 		LM_ERR("cannot get parameter value\n");
142 		return -1;
143 	}
144 	if(parse_uri(uval.s, uval.len, &turi)!=0) {
145 		return -1;
146 	}
147 	return 1;
148 }
149 
150 /*
151  * Check if the username matches the username in credentials
152  */
ki_is_user(sip_msg_t * _m,str * suser)153 int ki_is_user(sip_msg_t *_m, str *suser)
154 {
155 	struct hdr_field* h;
156 	auth_body_t* c;
157 
158 	get_authorized_cred(_m->authorization, &h);
159 	if (!h) {
160 		get_authorized_cred(_m->proxy_auth, &h);
161 		if (!h) {
162 			LM_ERR("no authorized credentials found (error in scripts)\n");
163 			LM_ERR("Call {www,proxy}_authorize before calling is_user function !\n");
164 			return -1;
165 		}
166 	}
167 
168 	c = (auth_body_t*)(h->parsed);
169 
170 	if (!c->digest.username.user.len) {
171 		LM_DBG("username not found in credentials\n");
172 		return -1;
173 	}
174 
175 	if (suser->len != c->digest.username.user.len) {
176 		LM_DBG("username length does not match\n");
177 		return -1;
178 	}
179 
180 	if (!memcmp(suser->s, c->digest.username.user.s, suser->len)) {
181 		LM_DBG("username matches\n");
182 		return 1;
183 	} else {
184 		LM_DBG("username differs\n");
185 		return -1;
186 	}
187 }
188 
is_user(struct sip_msg * _m,char * _user,char * _str2)189 int is_user(struct sip_msg* _m, char* _user, char* _str2)
190 {
191 	str suser;
192 
193 	if(fixup_get_svalue(_m, (gparam_t*)_user, &suser)<0) {
194 		LM_ERR("failed to get user param\n");
195 		return -1;
196 	}
197 
198 	return ki_is_user(_m, &suser);
199 }
200 
201 /*
202  * Find if Request URI has a given parameter with no value
203  */
uri_param_1(struct sip_msg * _msg,char * _param,char * _str2)204 int uri_param_1(struct sip_msg* _msg, char* _param, char* _str2)
205 {
206 	str sparam;
207 	if(fixup_get_svalue(_msg, (gparam_t*)_param, &sparam)<0) {
208 		LM_ERR("failed to get parameter\n");
209 		return -1;
210 	}
211 	return ki_uri_param_value(_msg, &sparam, NULL);
212 }
213 
214 /*
215  * Find if Request URI has a given parameter with matching value
216  */
uri_param_2(struct sip_msg * _msg,char * _param,char * _value)217 int uri_param_2(struct sip_msg* _msg, char* _param, char* _value)
218 {
219 	str sparam;
220 	str svalue;
221 	if(fixup_get_svalue(_msg, (gparam_t*)_param, &sparam)<0) {
222 		LM_ERR("failed to get parameter\n");
223 		return -1;
224 	}
225 	if(fixup_get_svalue(_msg, (gparam_t*)_value, &svalue)<0) {
226 		LM_ERR("failed to get value\n");
227 		return -1;
228 	}
229 	return ki_uri_param_value(_msg, &sparam, &svalue);
230 }
231 
232 /*
233  * Find if Request URI has a given parameter with matching value
234  */
ki_uri_param_value(sip_msg_t * _msg,str * sparam,str * svalue)235 int ki_uri_param_value(sip_msg_t *_msg, str *sparam, str *svalue)
236 {
237 	str t;
238 
239 	param_hooks_t hooks;
240 	param_t* params, *pit;
241 
242 	if (parse_sip_msg_uri(_msg) < 0) {
243 		LM_ERR("ruri parsing failed\n");
244 		return -1;
245 	}
246 
247 	t = _msg->parsed_uri.params;
248 
249 	if (parse_params(&t, CLASS_ANY, &hooks, &params) < 0) {
250 		LM_ERR("ruri parameter parsing failed\n");
251 		return -1;
252 	}
253 
254 	for (pit = params; pit; pit = pit->next) {
255 		if ((pit->name.len == sparam->len) &&
256 				(strncmp(pit->name.s, sparam->s, sparam->len) == 0)) {
257 			if (svalue) {
258 				if ((svalue->len == pit->body.len) &&
259 						strncmp(svalue->s, pit->body.s, svalue->len) == 0) {
260 					goto ok;
261 				} else {
262 					goto nok;
263 				}
264 			} else {
265 				if (pit->body.len > 0) {
266 					goto nok;
267 				} else {
268 					goto ok;
269 				}
270 			}
271 		}
272 	}
273 
274 nok:
275 	free_params(params);
276 	return -1;
277 
278 ok:
279 	free_params(params);
280 	return 1;
281 }
282 
283 
284 /**
285  *
286  */
ki_uri_param(sip_msg_t * _msg,str * sparam)287 int ki_uri_param(sip_msg_t *_msg, str *sparam)
288 {
289 	return ki_uri_param_value(_msg, sparam, NULL);
290 }
291 
292 /*
293  * Check if param with or without value exists in Request URI
294  */
ki_uri_param_any(sip_msg_t * msg,str * sparam)295 int ki_uri_param_any(sip_msg_t *msg, str *sparam)
296 {
297 	str t;
298 	str ouri;
299 	sip_uri_t puri;
300 	param_hooks_t hooks;
301 	param_t* params, *pit;
302 
303 	if((msg->new_uri.s == NULL) || (msg->new_uri.len == 0)) {
304 		ouri = msg->first_line.u.request.uri;
305 		if(ouri.s == NULL) {
306 			LM_ERR("r-uri not found\n");
307 			return -1;
308 		}
309 	} else {
310 		ouri = msg->new_uri;
311 	}
312 
313 	if (parse_uri(ouri.s, ouri.len, &puri) < 0) {
314 		LM_ERR("failed to parse r-uri [%.*s]\n", ouri.len, ouri.s);
315 		return -1;
316 	}
317 	if(puri.sip_params.len>0) {
318 		t = puri.sip_params;
319 	} else if(puri.params.len>0) {
320 		t = puri.params;
321 	} else {
322 		LM_DBG("no uri params [%.*s]\n", ouri.len, ouri.s);
323 		return -1;
324 	}
325 
326 	if (parse_params(&t, CLASS_ANY, &hooks, &params) < 0) {
327 		LM_ERR("ruri parameter parsing failed\n");
328 		return -1;
329 	}
330 
331 	for (pit = params; pit; pit = pit->next) {
332 		if ((pit->name.len == sparam->len)
333 				&& (strncasecmp(pit->name.s, sparam->s, sparam->len) == 0)) {
334 			break;
335 		}
336 	}
337 	if(pit==NULL) {
338 		free_params(params);
339 		return -1;
340 	}
341 
342 	free_params(params);
343 	return 1;
344 }
345 
346 /*
347  * Find if Request URI has a given parameter with or without value
348  */
w_uri_param_any(struct sip_msg * _msg,char * _param,char * _str2)349 int w_uri_param_any(struct sip_msg* _msg, char* _param, char* _str2)
350 {
351 	str sparam;
352 	if(fixup_get_svalue(_msg, (gparam_t*)_param, &sparam)<0) {
353 		LM_ERR("failed to get parameter\n");
354 		return -1;
355 	}
356 	return ki_uri_param_any(_msg, &sparam);
357 }
358 
359 /*
360  * Adds a new parameter to Request URI
361  */
add_uri_param(struct sip_msg * _msg,char * _param,char * _s2)362 int add_uri_param(struct sip_msg* _msg, char* _param, char* _s2)
363 {
364 	str *param, *cur_uri, new_uri;
365 	struct sip_uri *parsed_uri;
366 	char *at;
367 
368 	param = (str*)_param;
369 
370 	if (param->len == 0) {
371 		return 1;
372 	}
373 
374 	if (parse_sip_msg_uri(_msg) < 0) {
375 		LM_ERR("ruri parsing failed\n");
376 		return -1;
377 	}
378 
379 	parsed_uri = &(_msg->parsed_uri);
380 
381 	/* if current ruri has no headers, pad param at the end */
382 	if (parsed_uri->headers.len == 0) {
383 		cur_uri =  GET_RURI(_msg);
384 		new_uri.len = cur_uri->len + param->len + 1;
385 		if (new_uri.len > MAX_URI_SIZE) {
386 			LM_ERR("new ruri too long\n");
387 			return -1;
388 		}
389 		new_uri.s = pkg_malloc(new_uri.len);
390 		if (new_uri.s == 0) {
391 			LM_ERR("add_uri_param(): Memory allocation failure\n");
392 			return -1;
393 		}
394 		memcpy(new_uri.s, cur_uri->s, cur_uri->len);
395 		*(new_uri.s + cur_uri->len) = ';';
396 		memcpy(new_uri.s + cur_uri->len + 1, param->s, param->len);
397 		if (rewrite_uri(_msg, &new_uri ) == 1) {
398 			goto ok;
399 		} else {
400 			goto nok;
401 		}
402 	}
403 
404 	/* otherwise take the long path */
405 	new_uri.len = 4 +
406 		(parsed_uri->user.len ? parsed_uri->user.len + 1 : 0) +
407 		(parsed_uri->passwd.len ? parsed_uri->passwd.len + 1 : 0) +
408 		parsed_uri->host.len +
409 		(parsed_uri->port.len ? parsed_uri->port.len + 1 : 0) +
410 		parsed_uri->params.len + param->len + 1 +
411 		parsed_uri->headers.len + 1;
412 	if (new_uri.len > MAX_URI_SIZE) {
413 		LM_ERR("new ruri too long\n");
414 		return -1;
415 	}
416 
417 	new_uri.s = pkg_malloc(new_uri.len);
418 	if (new_uri.s == 0) {
419 		LM_ERR("no more pkg memory\n");
420 		return -1;
421 	}
422 
423 	at = new_uri.s;
424 	memcpy(at, "sip:", 4);
425 	at = at + 4;
426 	if (parsed_uri->user.len) {
427 		memcpy(at, parsed_uri->user.s, parsed_uri->user.len);
428 		if (parsed_uri->passwd.len) {
429 			*at = ':';
430 			at = at + 1;
431 			memcpy(at, parsed_uri->passwd.s, parsed_uri->passwd.len);
432 			at = at + parsed_uri->passwd.len;
433 		};
434 		*at = '@';
435 		at = at + 1;
436 	}
437 	memcpy(at, parsed_uri->host.s, parsed_uri->host.len);
438 	at = at + parsed_uri->host.len;
439 	if (parsed_uri->port.len) {
440 		*at = ':';
441 		at = at + 1;
442 		memcpy(at, parsed_uri->port.s, parsed_uri->port.len);
443 		at = at + parsed_uri->port.len;
444 	}
445 	memcpy(at, parsed_uri->params.s, parsed_uri->params.len);
446 	at = at + parsed_uri->params.len;
447 	*at = ';';
448 	at = at + 1;
449 	memcpy(at, param->s, param->len);
450 	at = at + param->len;
451 	*at = '?';
452 	at = at + 1;
453 	memcpy(at, parsed_uri->headers.s, parsed_uri->headers.len);
454 
455 	if (rewrite_uri(_msg, &new_uri) == 1) {
456 		goto ok;
457 	}
458 
459 nok:
460 	pkg_free(new_uri.s);
461 	return -1;
462 
463 ok:
464 	pkg_free(new_uri.s);
465 	return 1;
466 }
467 
468 /*
469  * Remove param from Request URI
470  */
ki_uri_param_rm(sip_msg_t * msg,str * sparam)471 int ki_uri_param_rm(sip_msg_t *msg, str *sparam)
472 {
473 	str t;
474 	char buri[MAX_URI_SIZE];
475 	str ouri;
476 	str nuri;
477 	sip_uri_t puri;
478 	param_hooks_t hooks;
479 	param_t* params, *pit;
480 
481 	if((msg->new_uri.s == NULL) || (msg->new_uri.len == 0)) {
482 		ouri = msg->first_line.u.request.uri;
483 		if(ouri.s == NULL) {
484 			LM_ERR("r-uri not found\n");
485 			return -1;
486 		}
487 	} else {
488 		ouri = msg->new_uri;
489 	}
490 	if(ouri.len>=MAX_URI_SIZE) {
491 		LM_ERR("r-uri is too long (%d)\n", ouri.len);
492 		return -1;
493 	}
494 
495 	if (parse_uri(ouri.s, ouri.len, &puri) < 0) {
496 		LM_ERR("failed to parse r-uri [%.*s]\n", ouri.len, ouri.s);
497 		return -1;
498 	}
499 	if(puri.sip_params.len>0) {
500 		t = puri.sip_params;
501 	} else if(puri.params.len>0) {
502 		t = puri.params;
503 	} else {
504 		LM_DBG("no uri params [%.*s]\n", ouri.len, ouri.s);
505 		return 1;
506 	}
507 
508 	if (parse_params(&t, CLASS_ANY, &hooks, &params) < 0) {
509 		LM_ERR("ruri parameter parsing failed\n");
510 		return -1;
511 	}
512 
513 	for (pit = params; pit; pit = pit->next) {
514 		if ((pit->name.len == sparam->len) &&
515 				(strncasecmp(pit->name.s, sparam->s, sparam->len) == 0)) {
516 			break;
517 		}
518 	}
519 	if(pit==NULL) {
520 		free_params(params);
521 		return 1;
522 	}
523 
524 	nuri.s = pit->name.s;
525 	while(nuri.s > ouri.s && *nuri.s != ';') {
526 		nuri.s--;
527 	}
528 	memcpy(buri, ouri.s, nuri.s - ouri.s);
529 	nuri.len = nuri.s - ouri.s;
530 	nuri.s = buri;
531 	if(pit->body.len>0) {
532 		if(pit->body.s + pit->body.len < ouri.s + ouri.len) {
533 			memcpy(nuri.s + nuri.len, pit->body.s + pit->body.len,
534 					ouri.s + ouri.len - pit->body.s - pit->body.len);
535 			nuri.len += ouri.s + ouri.len - pit->body.s - pit->body.len;
536 		}
537 	} else {
538 		if(pit->name.s + pit->name.len < ouri.s + ouri.len) {
539 			memcpy(nuri.s + nuri.len, pit->name.s + pit->name.len,
540 					ouri.s + ouri.len - pit->name.s - pit->name.len);
541 			nuri.len += ouri.s + ouri.len - pit->name.s - pit->name.len;
542 		}
543 	}
544 
545 	free_params(params);
546 	if(rewrite_uri(msg, &nuri) < 0) {
547 		return -1;
548 	}
549 	return 1;
550 
551 }
552 
553 /*
554  * Remove param from Request URI
555  */
w_uri_param_rm(struct sip_msg * _msg,char * _param,char * _str2)556 int w_uri_param_rm(struct sip_msg* _msg, char* _param, char* _str2)
557 {
558 	str sparam;
559 	if(fixup_get_svalue(_msg, (gparam_t*)_param, &sparam)<0) {
560 		LM_ERR("failed to get parameter\n");
561 		return -1;
562 	}
563 	return ki_uri_param_rm(_msg, &sparam);
564 }
565 
566 /*
567  * Converts URI, if it is tel URI, to SIP URI.  Returns 1, if
568  * conversion succeeded and 2 if no conversion was needed, i.e., URI was not
569  * tel URI.  Returns -1, if conversion failed.  Takes SIP URI hostpart from
570  * second parameter and (if needed) writes the result to third paramater.
571  */
tel2sip(struct sip_msg * _msg,char * _uri,char * _hostpart,char * _res)572 int tel2sip(struct sip_msg* _msg, char* _uri, char* _hostpart, char* _res)
573 {
574 	str uri, hostpart, tel_uri, sip_uri;
575 	char *at;
576 	int i, j, in_tel_parameters = 0;
577 	pv_spec_t *res;
578 	pv_value_t res_val;
579 
580 	/* get parameters */
581 	if (get_str_fparam(&uri, _msg, (fparam_t*)_uri) < 0) {
582 		LM_ERR("failed to get uri value\n");
583 		return -1;
584 	}
585 	if (get_str_fparam(&hostpart, _msg, (fparam_t*)_hostpart) < 0) {
586 		LM_ERR("failed to get hostpart value\n");
587 		return -1;
588 	}
589 	res = (pv_spec_t *)_res;
590 
591 	/* check if anything needs to be done */
592 	if (uri.len < 4) return 2;
593 	if (strncasecmp(uri.s, "tel:", 4) != 0) return 2;
594 
595 	/* reserve memory for clean tel uri */
596 	tel_uri.s = pkg_malloc(uri.len+1);
597 	if (tel_uri.s == 0) {
598 		LM_ERR("no more pkg memory\n");
599 		return -1;
600 	}
601 
602 	/* Remove visual separators before converting to SIP URI. Don't remove
603 	 * visual separators in TEL URI parameters (after the first ";") */
604 	for (i=0, j=0; i < uri.len; i++) {
605 		if (in_tel_parameters == 0) {
606 			if (uri.s[i] == ';')
607 				in_tel_parameters = 1;
608 		}
609 		if (in_tel_parameters == 0) {
610 			if ((uri.s[i] != '-') && (uri.s[i] != '.') &&
611 					(uri.s[i] != '(') && (uri.s[i] != ')'))
612 				tel_uri.s[j++] = tolower(uri.s[i]);
613 		} else {
614 			tel_uri.s[j++] = tolower(uri.s[i]);
615 		}
616 	}
617 	tel_uri.s[j] = '\0';
618 	tel_uri.len = strlen(tel_uri.s);
619 
620 	/* reserve memory for resulting sip uri */
621 	sip_uri.len = 4 + tel_uri.len - 4 + 1 + hostpart.len + 1 + 10;
622 	sip_uri.s = pkg_malloc(sip_uri.len+1);
623 	if (sip_uri.s == 0) {
624 		LM_ERR("no more pkg memory\n");
625 		pkg_free(tel_uri.s);
626 		return -1;
627 	}
628 
629 	/* create resulting sip uri */
630 	at = sip_uri.s;
631 	append_str(at, "sip:", 4);
632 	append_str(at, tel_uri.s + 4, tel_uri.len - 4);
633 	append_chr(at, '@');
634 	append_str(at, hostpart.s, hostpart.len);
635 	append_chr(at, ';');
636 	append_str(at, "user=phone", 10);
637 
638 	/* tel_uri is not needed anymore */
639 	pkg_free(tel_uri.s);
640 
641 	/* set result pv value and write sip uri to result pv */
642 	res_val.rs = sip_uri;
643 	res_val.flags = PV_VAL_STR;
644 	if (res->setf(_msg, &res->pvp, (int)EQ_T, &res_val) != 0) {
645 		LM_ERR("failed to set result pvar\n");
646 		pkg_free(sip_uri.s);
647 		return -1;
648 	}
649 
650 	/* free allocated pkg memory and return */
651 	pkg_free(sip_uri.s);
652 	return 1;
653 }
654 
655 
656 /*
657  * Check if parameter is an e164 number.
658  */
e164_check(str * _user)659 static inline int e164_check(str* _user)
660 {
661 	int i;
662 	char c;
663 
664 	if ((_user->len > 2) && (_user->len < 17) && ((_user->s)[0] == '+')) {
665 		for (i = 1; i < _user->len; i++) {
666 			c = (_user->s)[i];
667 			if (c < '0' || c > '9') return -1;
668 		}
669 		return 1;
670 	}
671 	return -1;
672 }
673 
674 
675 /*
676  * Check if user part of URI in pseudo variable is an e164 number
677  */
is_e164(struct sip_msg * _m,char * _sp,char * _s2)678 int is_e164(struct sip_msg* _m, char* _sp, char* _s2)
679 {
680 	pv_spec_t *sp;
681 	pv_value_t pv_val;
682 
683 	sp = (pv_spec_t *)_sp;
684 
685 	if (sp && (pv_get_spec_value(_m, sp, &pv_val) == 0)) {
686 		if (pv_val.flags & PV_VAL_STR) {
687 			if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
688 				LM_DBG("missing argument\n");
689 				return -1;
690 			}
691 			return e164_check(&(pv_val.rs));
692 		} else {
693 			LM_ERR("pseudo variable value is not string\n");
694 			return -1;
695 		}
696 	} else {
697 		LM_ERR("failed to get pseudo variable value\n");
698 		return -1;
699 	}
700 }
701 
702 
703 /*
704  * Check if user part of URI in pseudo variable is an e164 number
705  */
w_is_uri_user_e164(struct sip_msg * _m,char * _sp,char * _s2)706 int w_is_uri_user_e164(struct sip_msg* _m, char* _sp, char* _s2)
707 {
708 	pv_spec_t *sp;
709 	pv_value_t pv_val;
710 
711 	sp = (pv_spec_t *)_sp;
712 
713 	if (sp && (pv_get_spec_value(_m, sp, &pv_val) == 0)) {
714 		if (pv_val.flags & PV_VAL_STR) {
715 			if (pv_val.rs.len == 0 || pv_val.rs.s == NULL) {
716 				LM_DBG("missing uri\n");
717 				return -1;
718 			}
719 			return is_uri_user_e164(&pv_val.rs);
720 		} else {
721 			LM_ERR("pseudo variable value is not string\n");
722 			return -1;
723 		}
724 	} else {
725 		LM_ERR("failed to get pseudo variable value\n");
726 		return -1;
727 	}
728 }
729 
730 
is_uri_user_e164(str * uri)731 int is_uri_user_e164(str *uri)
732 {
733 	char *chr;
734 	str user;
735 
736 	chr = memchr(uri->s, ':', uri->len);
737 	if (chr == NULL) {
738 		LM_ERR("parsing URI failed\n");
739 		return -1;
740 	};
741 	user.s = chr + 1;
742 	chr = memchr(user.s, '@', uri->len - (user.s - uri->s));
743 	if (chr == NULL) return -1;
744 	user.len = chr - user.s;
745 
746 	return e164_check(&user);
747 }
748 
749 /*
750  * Set userpart of URI
751  */
set_uri_user(struct sip_msg * _m,char * _uri,char * _value)752 int set_uri_user(struct sip_msg* _m, char* _uri, char* _value)
753 {
754 	pv_spec_t *uri_pv, *value_pv;
755 	pv_value_t uri_val, value_val, res_val;
756 	str uri, value;
757 	char *at, *colon, *c;
758 	char new_uri[MAX_URI_SIZE + 1];
759 
760 	uri_pv = (pv_spec_t *)_uri;
761 	if (uri_pv && (pv_get_spec_value(_m, uri_pv, &uri_val) == 0)) {
762 		if (uri_val.flags & PV_VAL_STR) {
763 			if (uri_val.rs.len == 0 || uri_val.rs.s == NULL) {
764 				LM_ERR("missing uri value\n");
765 				return -1;
766 			}
767 		} else {
768 			LM_ERR("uri value is not string\n");
769 			return -1;
770 		}
771 	} else {
772 		LM_ERR("failed to get uri value\n");
773 		return -1;
774 	}
775 	uri = uri_val.rs;
776 
777 	value_pv = (pv_spec_t *)_value;
778 	if (value_pv && (pv_get_spec_value(_m, value_pv, &value_val) == 0)) {
779 		if (value_val.flags & PV_VAL_STR) {
780 			if (value_val.rs.s == NULL) {
781 				LM_ERR("missing uriuser value\n");
782 				return -1;
783 			}
784 		} else {
785 			LM_ERR("uriuser value is not string\n");
786 			return -1;
787 		}
788 	} else {
789 		LM_ERR("failed to get uriuser value\n");
790 		return -1;
791 	}
792 	value = value_val.rs;
793 
794 	colon = strchr(uri.s, ':');
795 	if (colon == NULL) {
796 		LM_ERR("uri does not contain ':' character\n");
797 		return -1;
798 	}
799 	at = strchr(uri.s, '@');
800 	c = &(new_uri[0]);
801 	if (at == NULL) {
802 		if (value.len == 0) return 1;
803 		if (uri.len + value.len > MAX_URI_SIZE) {
804 			LM_ERR("resulting uri would be too large\n");
805 			return -1;
806 		}
807 		append_str(c, uri.s, colon - uri.s + 1);
808 		append_str(c, value.s, value.len);
809 		append_chr(c, '@');
810 		append_str(c, colon + 1, uri.len - (colon - uri.s + 1));
811 		res_val.rs.len = uri.len + value.len + 1;
812 	} else {
813 		if (value.len == 0) {
814 			append_str(c, uri.s, colon - uri.s + 1);
815 			append_str(c, at + 1, uri.len - (at - uri.s + 1));
816 			res_val.rs.len = uri.len - (at - colon);
817 		} else {
818 			if (uri.len + value.len - (at - colon - 1) > MAX_URI_SIZE) {
819 				LM_ERR("resulting uri would be too large\n");
820 				return -1;
821 			}
822 			append_str(c, uri.s, colon - uri.s + 1);
823 			append_str(c, value.s, value.len);
824 			append_str(c, at, uri.len - (at - uri.s));
825 			res_val.rs.len = uri.len + value.len - (at - colon - 1);
826 		}
827 	}
828 
829 	res_val.rs.s = &(new_uri[0]);
830 	LM_DBG("resulting uri: %.*s\n", res_val.rs.len, res_val.rs.s);
831 	res_val.flags = PV_VAL_STR;
832 	uri_pv->setf(_m, &uri_pv->pvp, (int)EQ_T, &res_val);
833 
834 	return 1;
835 }
836 
837 /*
838  * Set hostpart of URI
839  */
set_uri_host(struct sip_msg * _m,char * _uri,char * _value)840 int set_uri_host(struct sip_msg* _m, char* _uri, char* _value)
841 {
842 	pv_spec_t *uri_pv, *value_pv;
843 	pv_value_t uri_val, value_val, res_val;
844 	str uri, value;
845 	char *at, *colon, *c, *next;
846 	unsigned int host_len;
847 	char new_uri[MAX_URI_SIZE + 1];
848 
849 	uri_pv = (pv_spec_t *)_uri;
850 	if (uri_pv && (pv_get_spec_value(_m, uri_pv, &uri_val) == 0)) {
851 		if (uri_val.flags & PV_VAL_STR) {
852 			if (uri_val.rs.len == 0 || uri_val.rs.s == NULL) {
853 				LM_ERR("missing uri value\n");
854 				return -1;
855 			}
856 		} else {
857 			LM_ERR("uri value is not string\n");
858 			return -1;
859 		}
860 	} else {
861 		LM_ERR("failed to get uri value\n");
862 		return -1;
863 	}
864 	uri = uri_val.rs;
865 
866 	value_pv = (pv_spec_t *)_value;
867 	if (value_pv && (pv_get_spec_value(_m, value_pv, &value_val) == 0)) {
868 		if (value_val.flags & PV_VAL_STR) {
869 			if (value_val.rs.s == NULL) {
870 				LM_ERR("missing uri value\n");
871 				return -1;
872 			}
873 		} else {
874 			LM_ERR("uri value is not string\n");
875 			return -1;
876 		}
877 	} else {
878 		LM_ERR("failed to get uri value\n");
879 		return -1;
880 	}
881 	value = value_val.rs;
882 
883 	if (value.len == 0) {
884 		LM_ERR("hostpart of uri cannot be empty\n");
885 		return -1;
886 	}
887 	if (uri.len + value.len > MAX_URI_SIZE) {
888 		LM_ERR("resulting uri would be too large\n");
889 		return -1;
890 	}
891 
892 	colon = strchr(uri.s, ':');
893 	if (colon == NULL) {
894 		LM_ERR("uri does not contain ':' character\n");
895 		return -1;
896 	}
897 	c = &(new_uri[0]);
898 	at = strchr(colon + 1, '@');
899 	if (at == NULL) {
900 		next = colon + 1;
901 	} else {
902 		next = at + 1;
903 	}
904 	append_str(c, uri.s, next - uri.s);
905 	host_len = strcspn(next, ":;?");
906 	append_str(c, value.s, value.len);
907 	strcpy(c, next + host_len);
908 	res_val.rs.len = uri.len + value.len - host_len;
909 	res_val.rs.s = &(new_uri[0]);
910 
911 	LM_DBG("resulting uri: %.*s\n", res_val.rs.len, res_val.rs.s);
912 	res_val.flags = PV_VAL_STR;
913 	uri_pv->setf(_m, &uri_pv->pvp, (int)EQ_T, &res_val);
914 
915 	return 1;
916 }
917 
918 /**
919  * Find if Request URI has a given parameter and returns the value.
920  */
get_uri_param(struct sip_msg * _msg,char * _param,char * _value)921 int get_uri_param(struct sip_msg* _msg, char* _param, char* _value)
922 {
923 	str *param, t;
924 	pv_spec_t* dst;
925 	pv_value_t val;
926 
927 	param_hooks_t hooks;
928 	param_t* params;
929 
930 	param = (str*)_param;
931 	dst = (pv_spec_t *) _value;
932 
933 	if (parse_sip_msg_uri(_msg) < 0) {
934 		LM_ERR("ruri parsing failed\n");
935 		return -1;
936 	}
937 
938 	t = _msg->parsed_uri.params;
939 
940 	if (parse_params(&t, CLASS_ANY, &hooks, &params) < 0) {
941 		LM_ERR("ruri parameter parsing failed\n");
942 		return -1;
943 	}
944 
945 	while (params) {
946 		if ((params->name.len == param->len)
947 				&& (strncmp(params->name.s, param->s, param->len) == 0)) {
948 			memset(&val, 0, sizeof(pv_value_t));
949 			val.rs.s = params->body.s;
950 			val.rs.len = params->body.len;
951 			val.flags = PV_VAL_STR;
952 			dst->setf(_msg, &dst->pvp, (int)EQ_T, &val);
953 			goto found;
954 		} else {
955 			params = params->next;
956 		}
957 	}
958 
959 	free_params(params);
960 	return -1;
961 
962 found:
963 	free_params(params);
964 	return 1;
965 }
966 
967 
968 /*
969  * Check if the parameter is a valid telephone number
970  * - optional leading + followed by digits only
971  */
ki_is_tel_number(sip_msg_t * msg,str * tval)972 int ki_is_tel_number(sip_msg_t *msg, str *tval)
973 {
974 	int i;
975 
976 	if(tval==NULL || tval->len<1)
977 		return -2;
978 
979 	i = 0;
980 	if(tval->s[0]=='+') {
981 		if(tval->len<2)
982 			return -2;
983 		if(tval->s[1]<'1' || tval->s[1]>'9')
984 			return -2;
985 		i = 2;
986 	}
987 
988 	for(; i<tval->len; i++) {
989 		if(tval->s[i]<'0' || tval->s[i]>'9')
990 			return -2;
991 	}
992 
993 	return 1;
994 }
995 
996 
997 /*
998  * Check if the parameter is a valid telephone number
999  * - optional leading + followed by digits only
1000  */
is_tel_number(sip_msg_t * msg,char * _sp,char * _s2)1001 int is_tel_number(sip_msg_t *msg, char *_sp, char* _s2)
1002 {
1003 	str tval = {0, 0};
1004 
1005 	if(fixup_get_svalue(msg, (gparam_t*)_sp, &tval)!=0) {
1006 		LM_ERR("cannot get parameter value\n");
1007 		return -1;
1008 	}
1009 
1010 	return ki_is_tel_number(msg, &tval);
1011 }
1012 
1013 
1014 /*
1015  * Check if the parameter contains decimal digits only
1016  */
ki_is_numeric(sip_msg_t * msg,str * tval)1017 int ki_is_numeric(sip_msg_t *msg, str *tval)
1018 {
1019 	int i;
1020 
1021 	if(tval==NULL || tval->len<=0)
1022 		return -2;
1023 
1024 	i = 0;
1025 	for(; i<tval->len; i++) {
1026 		if(tval->s[i]<'0' || tval->s[i]>'9')
1027 			return -2;
1028 	}
1029 
1030 	return 1;
1031 }
1032 
1033 
1034 /*
1035  * Check if the parameter contains decimal digits only
1036  */
is_numeric(sip_msg_t * msg,char * _sp,char * _s2)1037 int is_numeric(sip_msg_t *msg, char *_sp, char* _s2)
1038 {
1039 	str tval = {0, 0};
1040 
1041 	if(fixup_get_svalue(msg, (gparam_t*)_sp, &tval)!=0) {
1042 		LM_ERR("cannot get parameter value\n");
1043 		return -1;
1044 	}
1045 
1046 	return ki_is_numeric(msg, &tval);
1047 }
1048 
1049 
1050 /*
1051  * Check if the parameter contains alphanumeric characters
1052  */
ki_is_alphanum(sip_msg_t * msg,str * tval)1053 int ki_is_alphanum(sip_msg_t *msg, str *tval)
1054 {
1055 	int i;
1056 
1057 	if(tval==NULL || tval->len<=0)
1058 		return -2;
1059 
1060 	i = 0;
1061 	for(; i<tval->len; i++) {
1062 		if( !((tval->s[i]>='0' && tval->s[i]<='9')
1063 				|| (tval->s[i]>='A' && tval->s[i]<='Z')
1064 				|| (tval->s[i]>='a' && tval->s[i]<='z')) )
1065 			return -3;
1066 	}
1067 
1068 	return 1;
1069 }
1070 
1071 /*
1072  * Check if the parameter contains alphanumeric characters
1073  */
ksr_is_alphanum(sip_msg_t * msg,char * _sp,char * _s2)1074 int ksr_is_alphanum(sip_msg_t *msg, char *_sp, char* _s2)
1075 {
1076 	str tval = {0, 0};
1077 
1078 	if(fixup_get_svalue(msg, (gparam_t*)_sp, &tval)!=0) {
1079 		LM_ERR("cannot get parameter value\n");
1080 		return -1;
1081 	}
1082 
1083 	return ki_is_alphanum(msg, &tval);
1084 }
1085 
1086 /*
1087  * Check if the parameter contains alphanumeric characters or are part of
1088  * the second parameter
1089  */
ki_is_alphanumex(sip_msg_t * msg,str * tval,str * eset)1090 int ki_is_alphanumex(sip_msg_t *msg, str *tval, str *eset)
1091 {
1092 	int i;
1093 	int j;
1094 	int found;
1095 
1096 	if(tval==NULL || tval->len<=0)
1097 		return -2;
1098 
1099 	i = 0;
1100 	for(; i<tval->len; i++) {
1101 		if( !((tval->s[i]>='0' && tval->s[i]<='9')
1102 				|| (tval->s[i]>='A' && tval->s[i]<='Z')
1103 				|| (tval->s[i]>='a' && tval->s[i]<='z')) ) {
1104 			if(eset==NULL || eset->len<=0) {
1105 				return -3;
1106 			}
1107 			found = 0;
1108 			for(j=0; j<eset->len; j++) {
1109 				if(tval->s[i]==eset->s[j]) {
1110 					found = 1;
1111 					break;
1112 				}
1113 			}
1114 			if(found==0) {
1115 				return -3;
1116 			}
1117 		}
1118 	}
1119 
1120 	return 1;
1121 }
1122 
1123 /*
1124  * Check if the parameter contains alphanumeric characters or are part of
1125  * the second parameter
1126  */
ksr_is_alphanumex(sip_msg_t * msg,char * _sp,char * _se)1127 int ksr_is_alphanumex(sip_msg_t *msg, char *_sp, char* _se)
1128 {
1129 	str tval = {0, 0};
1130 	str eset = {0, 0};
1131 
1132 	if(fixup_get_svalue(msg, (gparam_t*)_sp, &tval)!=0) {
1133 		LM_ERR("cannot get tval parameter value\n");
1134 		return -1;
1135 	}
1136 	if(fixup_get_svalue(msg, (gparam_t*)_se, &eset)!=0) {
1137 		LM_ERR("cannot get eset parameter value\n");
1138 		return -1;
1139 	}
1140 
1141 	return ki_is_alphanumex(msg, &tval, &eset);
1142 }
1143