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, ¶ms) < 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, ¶ms) < 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, ¶ms) < 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, ¶ms) < 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