1 /*
2 * Copyright (C) 2001-2003 FhG Fokus
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 /** @file
23 * @brief Parser :: Parse URI's
24 *
25 * @ingroup parser
26 */
27
28
29 #include <stdint.h>
30
31 #include "../globals.h"
32 #include "parse_uri.h"
33 #include <string.h>
34 #include "../dprint.h"
35 #include "../ut.h" /* q_memchr */
36 #include "../error.h"
37 #include "../core_stats.h"
38
39 static char _sr_uri_empty_buf[2] = {0};
40 static str _sr_uri_empty = { _sr_uri_empty_buf, 0 };
41
42 /* extra chars that should be allowed in URI host */
43 char *_sr_uri_host_extra_chars = "";
44
uri_host_char_allowed(char c)45 int uri_host_char_allowed(char c)
46 {
47 int i = 0;
48
49 if(_sr_uri_host_extra_chars==NULL || _sr_uri_host_extra_chars[0]=='\0') {
50 return 0;
51 }
52 while(_sr_uri_host_extra_chars[i]!='\0') {
53 if(_sr_uri_host_extra_chars[i]==c) {
54 return 1;
55 }
56 i++;
57 }
58 return 0;
59 }
60
61 /* buf= pointer to begining of uri (sip:x@foo.bar:5060;a=b?h=i)
62 * len= len of uri
63 * returns: fills uri & returns <0 on error or 0 if ok
64 */
parse_uri(char * buf,int len,struct sip_uri * uri)65 int parse_uri(char* buf, int len, struct sip_uri* uri)
66 {
67 enum states { URI_INIT, URI_USER, URI_PASSWORD, URI_PASSWORD_ALPHA,
68 URI_HOST, URI_HOST_P,
69 URI_HOST6_P, URI_HOST6_END, URI_PORT,
70 URI_PARAM, URI_PARAM_P, URI_VAL_P, URI_HEADERS,
71 /* param states */
72 /* transport */
73 PT_T, PT_R, PT_A, PT_N, PT_S, PT_P, PT_O, PT_R2, PT_T2,
74 PT_eq,
75 /* ttl */
76 PTTL_T2, PTTL_L, PTTL_eq,
77 /* user */
78 PU_U, PU_S, PU_E, PU_R, PU_eq,
79 /* method */
80 PM_M, PM_E, PM_T, PM_H, PM_O, PM_D, PM_eq,
81 /* maddr */
82 PMA_A, PMA_D, PMA_D2, PMA_R, PMA_eq,
83 /* lr */
84 PLR_L, PLR_R_FIN, PLR_eq,
85 /* r2 */
86 PR2_R, PR2_2_FIN, PR2_eq,
87 /* gr */
88 PGR_G, PGR_R_FIN, PGR_eq,
89 #ifdef USE_COMP
90 /* comp */
91 PCOMP_C, PCOMP_O, PCOMP_M, PCOMP_P, PCOMP_eq,
92
93 /* comp values */
94 /* sigcomp */
95 VCOMP_S, VCOMP_SIGC_I, VCOMP_SIGC_G,
96 VCOMP_SIGC_C, VCOMP_SIGC_O, VCOMP_SIGC_M,
97 VCOMP_SIGC_P_FIN,
98 /* sergz */
99 VCOMP_SGZ_E, VCOMP_SGZ_R, VCOMP_SGZ_G,
100 VCOMP_SGZ_Z_FIN,
101 #endif
102
103 /* transport values */
104 /* udp */
105 VU_U, VU_D, VU_P_FIN,
106 /* tcp */
107 VT_T, VT_C, VT_P_FIN,
108 /* tls */
109 VTLS_L, VTLS_S_FIN,
110 /* sctp */
111 VS_S, VS_C, VS_T, VS_P_FIN,
112 /* ws */
113 VW_W, VW_S_FIN
114 };
115 register enum states state;
116 char* s;
117 char* b; /* param start */
118 char *v; /* value start */
119 str* param; /* current param */
120 str* param_val; /* current param val */
121 str user;
122 str password;
123 int port_no;
124 register char* p;
125 char* end;
126 char* pass;
127 int found_user;
128 int error_headers;
129 uint32_t scheme;
130 uri_type backup_urit;
131 uri_flags backup_urif;
132
133 #ifdef USE_COMP
134 str comp_str; /* not returned for now */
135 str comp_val; /* not returned for now */
136 #endif
137
138 #define SIP_SCH 0x3a706973
139 #define SIPS_SCH 0x73706973
140 #define TEL_SCH 0x3a6c6574
141 #define URN_SCH 0x3a6e7275
142
143 #define case_port( ch, var) \
144 case ch: \
145 (var)=(var)*10+ch-'0'; \
146 if((var) > MAX_PORT_VAL) { \
147 goto error_bad_port; \
148 }\
149 break
150
151 #define still_at_user \
152 if (found_user==0){ \
153 user.s=uri->host.s; \
154 if (pass){\
155 user.len=pass-user.s; \
156 password.s=pass+1; \
157 password.len=p-password.s; \
158 }else{ \
159 user.len=p-user.s; \
160 }\
161 /* save the uri type/scheme */ \
162 backup_urit=uri->type; \
163 backup_urif=uri->flags; \
164 /* everything else is 0 */ \
165 memset(uri, 0, sizeof(struct sip_uri)); \
166 /* restore the scheme & flags, copy user & pass */ \
167 uri->type=backup_urit; \
168 uri->flags=backup_urif; \
169 uri->user=user; \
170 if (pass) uri->passwd=password; \
171 s=p+1; \
172 found_user=1;\
173 error_headers=0; \
174 state=URI_HOST; \
175 }else goto error_bad_char
176
177 #define check_host_end \
178 case ':': \
179 /* found the host */ \
180 uri->host.s=s; \
181 uri->host.len=p-s; \
182 state=URI_PORT; \
183 s=p+1; \
184 break; \
185 case ';': \
186 uri->host.s=s; \
187 uri->host.len=p-s; \
188 state=URI_PARAM; \
189 s=p+1; \
190 break; \
191 case '?': \
192 uri->host.s=s; \
193 uri->host.len=p-s; \
194 state=URI_HEADERS; \
195 s=p+1; \
196 break; \
197 case '&': \
198 case '@': \
199 goto error_bad_char
200
201
202 #define param_set(t_start, v_start) \
203 param->s=(t_start);\
204 param->len=(p-(t_start));\
205 param_val->s=(v_start); \
206 param_val->len=(p-(v_start))
207
208 #define semicolon_case \
209 case';': \
210 if (pass){ \
211 found_user=1;/* no user, pass cannot contain ';'*/ \
212 pass=0; \
213 } \
214 state=URI_PARAM /* new param */
215
216 #define question_case \
217 case '?': \
218 uri->params.s=s; \
219 uri->params.len=p-s; \
220 state=URI_HEADERS; \
221 s=p+1; \
222 if (pass){ \
223 found_user=1;/* no user, pass cannot contain '?'*/ \
224 pass=0; \
225 }
226
227 #define colon_case \
228 case ':': \
229 if (found_user==0){ \
230 /*might be pass but only if user not found yet*/ \
231 if (pass){ \
232 found_user=1; /* no user */ \
233 pass=0; \
234 }else{ \
235 pass=p; \
236 } \
237 } \
238 state=URI_PARAM_P /* generic param */
239
240 #define param_common_cases \
241 case '@': \
242 /* ughhh, this is still the user */ \
243 still_at_user; \
244 break; \
245 semicolon_case; \
246 break; \
247 question_case; \
248 break; \
249 colon_case; \
250 break
251
252 #define value_common_cases \
253 case '@': \
254 /* ughhh, this is still the user */ \
255 still_at_user; \
256 break; \
257 semicolon_case; \
258 param_set(b, v); \
259 break; \
260 question_case; \
261 param_set(b, v); \
262 break; \
263 colon_case; \
264 state=URI_VAL_P; \
265 break
266
267 #define param_switch(old_state, c1, c2, new_state) \
268 case old_state: \
269 switch(*p){ \
270 case c1: \
271 case c2: \
272 state=(new_state); \
273 break; \
274 param_common_cases; \
275 default: \
276 state=URI_PARAM_P; \
277 } \
278 break
279 #define param_switch1(old_state, c1, new_state) \
280 case old_state: \
281 switch(*p){ \
282 case c1: \
283 state=(new_state); \
284 break; \
285 param_common_cases; \
286 default: \
287 state=URI_PARAM_P; \
288 } \
289 break
290 #define param_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
291 case old_state : \
292 switch(*p){ \
293 case c1: \
294 case c2: \
295 state=(new_state_c); \
296 break; \
297 case d1: \
298 case d2: \
299 state=(new_state_d); \
300 break; \
301 param_common_cases; \
302 default: \
303 state=URI_PARAM_P; \
304 } \
305 break
306 #define value_switch(old_state, c1, c2, new_state) \
307 case old_state: \
308 switch(*p){ \
309 case c1: \
310 case c2: \
311 state=(new_state); \
312 break; \
313 value_common_cases; \
314 default: \
315 state=URI_VAL_P; \
316 } \
317 break
318 #define value_switch_big(old_state, c1, c2, d1, d2, new_state_c, new_state_d) \
319 case old_state: \
320 switch(*p){ \
321 case c1: \
322 case c2: \
323 state=(new_state_c); \
324 break; \
325 case d1: \
326 case d2: \
327 state=(new_state_d); \
328 break; \
329 value_common_cases; \
330 default: \
331 state=URI_VAL_P; \
332 } \
333 break
334
335 #define transport_fin(c_state, proto_no) \
336 case c_state: \
337 switch(*p){ \
338 case '@': \
339 still_at_user; \
340 break; \
341 semicolon_case; \
342 param_set(b, v); \
343 uri->proto=(proto_no); \
344 break; \
345 question_case; \
346 param_set(b, v); \
347 uri->proto=(proto_no); \
348 break; \
349 colon_case; \
350 default: \
351 state=URI_VAL_P; \
352 break; \
353 } \
354 break
355
356
357 #ifdef USE_COMP
358 #define comp_fin(c_state, comp_no) \
359 case c_state: \
360 switch(*p){ \
361 case '@': \
362 still_at_user; \
363 break; \
364 semicolon_case; \
365 /* param_set(b, v); */ \
366 uri->comp=(comp_no); \
367 break; \
368 question_case; \
369 /* param_set(b, v) */; \
370 uri->comp=(comp_no); \
371 break; \
372 colon_case; \
373 default: \
374 state=URI_VAL_P; \
375 break; \
376 } \
377 break
378
379 #endif
380
381 /* init */
382 end=buf+len;
383 p=buf+4;
384 found_user=0;
385 error_headers=0;
386 b=v=0;
387 param=param_val=0;
388 pass=0;
389 password.s=0; /* fixes gcc 4.0 warning */
390 password.len=0;
391 port_no=0;
392 state=URI_INIT;
393 memset(uri, 0, sizeof(struct sip_uri)); /* zero it all, just to be sure*/
394 /*look for sip:, sips:, tel: or urn:*/
395 if (len<5) goto error_too_short;
396 scheme=((uint32_t)buf[0]) + (((uint32_t)buf[1])<<8)
397 + (((uint32_t)buf[2])<<16) + (((uint32_t)buf[3])<<24);
398 scheme|=0x20202020;
399 if (scheme==SIP_SCH){
400 uri->type=SIP_URI_T;
401 }else if(scheme==SIPS_SCH){
402 if(buf[4]==':'){ p++; uri->type=SIPS_URI_T;}
403 else goto error_bad_uri;
404 }else if (scheme==TEL_SCH){
405 uri->type=TEL_URI_T;
406 }else if (scheme==URN_SCH){
407 uri->type=URN_URI_T;
408 }else goto error_bad_uri;
409
410 s=p;
411 for(;p<end; p++){
412 switch((unsigned char)state){
413 case URI_INIT:
414 switch(*p){
415 case '[':
416 /* uri = [ipv6address]... */
417 state=URI_HOST6_P;
418 s=p;
419 break;
420 case ']':
421 /* invalid, no uri can start with ']' */
422 case ':':
423 /* the same as above for ':' */
424 goto error_bad_char;
425 case '@': /* error no user part, or
426 * be forgiving and accept it ? */
427 default:
428 state=URI_USER;
429 }
430 break;
431 case URI_USER:
432 switch(*p){
433 case '@':
434 /* found the user*/
435 uri->user.s=s;
436 uri->user.len=p-s;
437 state=URI_HOST;
438 found_user=1;
439 s=p+1; /* skip '@' */
440 break;
441 case ':':
442 /* found the user, or the host? */
443 uri->user.s=s;
444 uri->user.len=p-s;
445 state=URI_PASSWORD;
446 s=p+1; /* skip ':' */
447 break;
448 case ';':
449 /* this could be still the user or
450 * params?*/
451 uri->host.s=s;
452 uri->host.len=p-s;
453 state=URI_PARAM;
454 s=p+1;
455 break;
456 case '?': /* still user or headers? */
457 uri->host.s=s;
458 uri->host.len=p-s;
459 state=URI_HEADERS;
460 s=p+1;
461 break;
462 /* almost anything permitted in the user part */
463 case '.':
464 case '-':
465 case '(':
466 case ')':
467 /* tel uri visual separators, set flag meaning, that
468 * user should be normalized before usage
469 */
470 uri->flags|=URI_USER_NORMALIZE;
471 break;
472 case '[':
473 case ']': /* the user part cannot contain "[]" */
474 goto error_bad_char;
475 }
476 break;
477 case URI_PASSWORD: /* this can also be the port (missing user)*/
478 switch(*p){
479 case '@':
480 /* found the password*/
481 uri->passwd.s=s;
482 uri->passwd.len=p-s;
483 port_no=0;
484 state=URI_HOST;
485 found_user=1;
486 s=p+1; /* skip '@' */
487 break;
488 case ';':
489 /* upps this is the port */
490 uri->port.s=s;
491 uri->port.len=p-s;
492 uri->port_no=port_no;
493 /* user contains in fact the host */
494 uri->host.s=uri->user.s;
495 uri->host.len=uri->user.len;
496 uri->user.s=0;
497 uri->user.len=0;
498 state=URI_PARAM;
499 found_user=1; /* there is no user part */
500 s=p+1;
501 break;
502 case '?':
503 /* upps this is the port */
504 uri->port.s=s;
505 uri->port.len=p-s;
506 uri->port_no=port_no;
507 /* user contains in fact the host */
508 uri->host.s=uri->user.s;
509 uri->host.len=uri->user.len;
510 uri->user.s=0;
511 uri->user.len=0;
512 state=URI_HEADERS;
513 found_user=1; /* there is no user part */
514 s=p+1;
515 break;
516 case_port('0', port_no);
517 case_port('1', port_no);
518 case_port('2', port_no);
519 case_port('3', port_no);
520 case_port('4', port_no);
521 case_port('5', port_no);
522 case_port('6', port_no);
523 case_port('7', port_no);
524 case_port('8', port_no);
525 case_port('9', port_no);
526 case '[':
527 case ']':
528 case ':':
529 goto error_bad_char;
530 default:
531 /* it can't be the port, non number found */
532 port_no=0;
533 state=URI_PASSWORD_ALPHA;
534 }
535 break;
536 case URI_PASSWORD_ALPHA:
537 switch(*p){
538 case '@':
539 /* found the password*/
540 uri->passwd.s=s;
541 uri->passwd.len=p-s;
542 state=URI_HOST;
543 found_user=1;
544 s=p+1; /* skip '@' */
545 break;
546 case ';': /* contains non-numbers => cannot be port no*/
547 case '?':
548 goto error_bad_port;
549 case '[':
550 case ']':
551 case ':':
552 goto error_bad_char;
553 }
554 break;
555 case URI_HOST:
556 if(*p == '[') {
557 state = URI_HOST6_P;
558 } else {
559 if(isalnum(*p)) {
560 state = URI_HOST_P;
561 } else {
562 goto error_bad_host;
563 }
564 }
565 break;
566 case URI_HOST_P:
567 switch(*p) {
568 check_host_end;
569 default:
570 if(!isalnum(*p) && (*p != '.') && (*p != '-')
571 && !uri_host_char_allowed(*p)) {
572 goto error_bad_host;
573 }
574 }
575 break;
576 case URI_HOST6_END:
577 switch(*p){
578 check_host_end;
579 default: /*no chars allowed after [ipv6] */
580 goto error_bad_host;
581 }
582 break;
583 case URI_HOST6_P:
584 switch(*p){
585 case ']':
586 state=URI_HOST6_END;
587 break;
588 case '[':
589 case '&':
590 case '@':
591 case ';':
592 case '?':
593 goto error_bad_host;
594 }
595 break;
596 case URI_PORT:
597 switch(*p){
598 case ';':
599 uri->port.s=s;
600 uri->port.len=p-s;
601 uri->port_no=port_no;
602 state=URI_PARAM;
603 s=p+1;
604 break;
605 case '?':
606 uri->port.s=s;
607 uri->port.len=p-s;
608 uri->port_no=port_no;
609 state=URI_HEADERS;
610 s=p+1;
611 break;
612 case_port('0', port_no);
613 case_port('1', port_no);
614 case_port('2', port_no);
615 case_port('3', port_no);
616 case_port('4', port_no);
617 case_port('5', port_no);
618 case_port('6', port_no);
619 case_port('7', port_no);
620 case_port('8', port_no);
621 case_port('9', port_no);
622 case '&':
623 case '@':
624 case ':':
625 default:
626 goto error_bad_port;
627 }
628 break;
629 case URI_PARAM: /* beginning of a new param */
630 switch(*p){
631 param_common_cases;
632 /* recognized params */
633 case 't':
634 case 'T':
635 b=p;
636 state=PT_T;
637 break;
638 case 'u':
639 case 'U':
640 b=p;
641 state=PU_U;
642 break;
643 case 'm':
644 case 'M':
645 b=p;
646 state=PM_M;
647 break;
648 case 'l':
649 case 'L':
650 b=p;
651 state=PLR_L;
652 break;
653 case 'r':
654 case 'R':
655 b=p;
656 state=PR2_R;
657 break;
658 case 'g':
659 case 'G':
660 b=p;
661 state=PGR_G;
662 break;
663 #ifdef USE_COMP
664 case 'c':
665 case 'C':
666 b=p;
667 state=PCOMP_C;
668 break;
669 #endif
670 default:
671 state=URI_PARAM_P;
672 }
673 break;
674 case URI_PARAM_P: /* ignore current param */
675 /* supported params:
676 * maddr, transport, ttl, lr, user, method, r2 */
677 switch(*p){
678 param_common_cases;
679 };
680 break;
681 /* ugly but fast param names parsing */
682 /*transport */
683 param_switch_big(PT_T, 'r', 'R', 't', 'T', PT_R, PTTL_T2);
684 param_switch(PT_R, 'a', 'A', PT_A);
685 param_switch(PT_A, 'n', 'N', PT_N);
686 param_switch(PT_N, 's', 'S', PT_S);
687 param_switch(PT_S, 'p', 'P', PT_P);
688 param_switch(PT_P, 'o', 'O', PT_O);
689 param_switch(PT_O, 'r', 'R', PT_R2);
690 param_switch(PT_R2, 't', 'T', PT_T2);
691 param_switch1(PT_T2, '=', PT_eq);
692 /* value parsing */
693 case PT_eq:
694 param=&uri->transport;
695 param_val=&uri->transport_val;
696 switch (*p){
697 param_common_cases;
698 case 'u':
699 case 'U':
700 v=p;
701 state=VU_U;
702 break;
703 case 't':
704 case 'T':
705 v=p;
706 state=VT_T;
707 break;
708 case 's':
709 case 'S':
710 v=p;
711 state=VS_S;
712 break;
713 case 'w':
714 case 'W':
715 v=p;
716 state=VW_W;
717 break;
718 default:
719 v=p;
720 state=URI_VAL_P;
721 }
722 break;
723 /* generic value */
724 case URI_VAL_P:
725 switch(*p){
726 value_common_cases;
727 }
728 break;
729 /* udp */
730 value_switch(VU_U, 'd', 'D', VU_D);
731 value_switch(VU_D, 'p', 'P', VU_P_FIN);
732 transport_fin(VU_P_FIN, PROTO_UDP);
733 /* tcp */
734 value_switch_big(VT_T, 'c', 'C', 'l', 'L', VT_C, VTLS_L);
735 value_switch(VT_C, 'p', 'P', VT_P_FIN);
736 transport_fin(VT_P_FIN, PROTO_TCP);
737 /* tls */
738 value_switch(VTLS_L, 's', 'S', VTLS_S_FIN);
739 transport_fin(VTLS_S_FIN, PROTO_TLS);
740 /* sctp */
741 value_switch(VS_S, 'c', 'C', VS_C);
742 value_switch(VS_C, 't', 'T', VS_T);
743 value_switch(VS_T, 'p', 'P', VS_P_FIN);
744 transport_fin(VS_P_FIN, PROTO_SCTP);
745 /* ws */
746 value_switch(VW_W, 's', 'S', VW_S_FIN);
747 transport_fin(VW_S_FIN, PROTO_WS);
748
749 /* ttl */
750 param_switch(PTTL_T2, 'l', 'L', PTTL_L);
751 param_switch1(PTTL_L, '=', PTTL_eq);
752 case PTTL_eq:
753 param=&uri->ttl;
754 param_val=&uri->ttl_val;
755 switch(*p){
756 param_common_cases;
757 default:
758 v=p;
759 state=URI_VAL_P;
760 }
761 break;
762
763 /* user param */
764 param_switch(PU_U, 's', 'S', PU_S);
765 param_switch(PU_S, 'e', 'E', PU_E);
766 param_switch(PU_E, 'r', 'R', PU_R);
767 param_switch1(PU_R, '=', PU_eq);
768 case PU_eq:
769 param=&uri->user_param;
770 param_val=&uri->user_param_val;
771 switch(*p){
772 param_common_cases;
773 default:
774 v=p;
775 state=URI_VAL_P;
776 }
777 break;
778
779 /* method*/
780 param_switch_big(PM_M, 'e', 'E', 'a', 'A', PM_E, PMA_A);
781 param_switch(PM_E, 't', 'T', PM_T);
782 param_switch(PM_T, 'h', 'H', PM_H);
783 param_switch(PM_H, 'o', 'O', PM_O);
784 param_switch(PM_O, 'd', 'D', PM_D);
785 param_switch1(PM_D, '=', PM_eq);
786 case PM_eq:
787 param=&uri->method;
788 param_val=&uri->method_val;
789 switch(*p){
790 param_common_cases;
791 default:
792 v=p;
793 state=URI_VAL_P;
794 }
795 break;
796
797 /*maddr*/
798 param_switch(PMA_A, 'd', 'D', PMA_D);
799 param_switch(PMA_D, 'd', 'D', PMA_D2);
800 param_switch(PMA_D2, 'r', 'R', PMA_R);
801 param_switch1(PMA_R, '=', PMA_eq);
802 case PMA_eq:
803 param=&uri->maddr;
804 param_val=&uri->maddr_val;
805 switch(*p){
806 param_common_cases;
807 default:
808 v=p;
809 state=URI_VAL_P;
810 }
811 break;
812
813 /* lr */
814 param_switch(PLR_L, 'r', 'R', PLR_R_FIN);
815 case PLR_R_FIN:
816 switch(*p){
817 case '@':
818 still_at_user;
819 break;
820 case '=':
821 state=PLR_eq;
822 break;
823 semicolon_case;
824 uri->lr.s=b;
825 uri->lr.len=(p-b);
826 break;
827 question_case;
828 uri->lr.s=b;
829 uri->lr.len=(p-b);
830 break;
831 colon_case;
832 break;
833 default:
834 state=URI_PARAM_P;
835 }
836 break;
837 /* handle lr=something case */
838 case PLR_eq:
839 param=&uri->lr;
840 param_val=&uri->lr_val;
841 switch(*p){
842 param_common_cases;
843 default:
844 v=p;
845 state=URI_VAL_P;
846 }
847 break;
848 /* r2 */
849 param_switch1(PR2_R, '2', PR2_2_FIN);
850 case PR2_2_FIN:
851 switch(*p){
852 case '@':
853 still_at_user;
854 break;
855 case '=':
856 state=PR2_eq;
857 break;
858 semicolon_case;
859 uri->r2.s=b;
860 uri->r2.len=(p-b);
861 break;
862 question_case;
863 uri->r2.s=b;
864 uri->r2.len=(p-b);
865 break;
866 colon_case;
867 break;
868 default:
869 state=URI_PARAM_P;
870 }
871 break;
872 /* handle lr=something case */
873 case PR2_eq:
874 param=&uri->r2;
875 param_val=&uri->r2_val;
876 switch(*p){
877 param_common_cases;
878 default:
879 v=p;
880 state=URI_VAL_P;
881 }
882 break;
883 /* gr */
884 param_switch(PGR_G, 'r', 'R', PGR_R_FIN);
885 case PGR_R_FIN:
886 switch(*p){
887 case '@':
888 still_at_user;
889 break;
890 case '=':
891 state=PGR_eq;
892 break;
893 semicolon_case;
894 uri->gr.s=b;
895 uri->gr.len=(p-b);
896 break;
897 question_case;
898 uri->gr.s=b;
899 uri->gr.len=(p-b);
900 break;
901 colon_case;
902 break;
903 default:
904 state=URI_PARAM_P;
905 }
906 break;
907 /* handle gr=something case */
908 case PGR_eq:
909 param=&uri->gr;
910 param_val=&uri->gr_val;
911 switch(*p){
912 param_common_cases;
913 default:
914 v=p;
915 state=URI_VAL_P;
916 }
917 break;
918
919 #ifdef USE_COMP
920 param_switch(PCOMP_C, 'o', 'O' , PCOMP_O);
921 param_switch(PCOMP_O, 'm', 'M' , PCOMP_M);
922 param_switch(PCOMP_M, 'p', 'P' , PCOMP_P);
923 param_switch1(PCOMP_P, '=', PCOMP_eq);
924 /* value */
925 case PCOMP_eq:
926 param=&comp_str;
927 param_val=&comp_val;
928 switch (*p){
929 param_common_cases;
930 case 's':
931 case 'S':
932 v=p;
933 state=VCOMP_S;
934 break;
935 default:
936 v=p;
937 state=URI_VAL_P;
938 }
939 break;
940 /* sigcomp*/
941 value_switch_big(VCOMP_S, 'i', 'I', 'e', 'E',
942 VCOMP_SIGC_I, VCOMP_SGZ_E);
943 value_switch(VCOMP_SIGC_I, 'g', 'G', VCOMP_SIGC_G);
944 value_switch(VCOMP_SIGC_G, 'c', 'C', VCOMP_SIGC_C);
945 value_switch(VCOMP_SIGC_C, 'o', 'O', VCOMP_SIGC_O);
946 value_switch(VCOMP_SIGC_O, 'm', 'M', VCOMP_SIGC_M);
947 value_switch(VCOMP_SIGC_M, 'p', 'P', VCOMP_SIGC_P_FIN);
948 comp_fin(VCOMP_SIGC_P_FIN, COMP_SIGCOMP);
949
950 /* sergz*/
951 value_switch(VCOMP_SGZ_E, 'r', 'R', VCOMP_SGZ_R);
952 value_switch(VCOMP_SGZ_R, 'g', 'G', VCOMP_SGZ_G);
953 value_switch(VCOMP_SGZ_G, 'z', 'Z', VCOMP_SGZ_Z_FIN);
954 comp_fin(VCOMP_SGZ_Z_FIN, COMP_SERGZ);
955 #endif
956
957
958 case URI_HEADERS:
959 /* for now nobody needs them so we completely ignore the
960 * headers (they are not allowed in request uri) --andrei */
961 switch(*p){
962 case '@':
963 /* yak, we are still at user */
964 still_at_user;
965 break;
966 case ';':
967 /* we might be still parsing user, try it */
968 if (found_user) goto error_bad_char;
969 error_headers=1; /* if this is not the user
970 we have an error */
971 /* if pass is set => it cannot be user:pass
972 * => error (';') is illegal in a header */
973 if (pass) goto error_headers;
974 break;
975 case ':':
976 if (found_user==0){
977 /*might be pass but only if user not found yet*/
978 if (pass){
979 found_user=1; /* no user */
980 pass=0;
981 }else{
982 pass=p;
983 }
984 }
985 break;
986 case '?':
987 if (pass){
988 found_user=1; /* no user, pass cannot contain '?'*/
989 pass=0;
990 }
991 break;
992 }
993 break;
994 default:
995 goto error_bug;
996 }
997 }
998 /*end of uri */
999 switch (state){
1000 case URI_INIT: /* error empty uri */
1001 goto error_too_short;
1002 case URI_USER:
1003 /* this is the host, it can't be the user */
1004 if (found_user) goto error_bad_uri;
1005 uri->host.s=s;
1006 uri->host.len=p-s;
1007 state=URI_HOST;
1008 break;
1009 case URI_PASSWORD:
1010 /* this is the port, it can't be the passwd */
1011 if (found_user) goto error_bad_port;
1012 uri->port.s=s;
1013 uri->port.len=p-s;
1014 uri->port_no=port_no;
1015 uri->host=uri->user;
1016 uri->user.s=0;
1017 uri->user.len=0;
1018 break;
1019 case URI_PASSWORD_ALPHA:
1020 /* it might be an urn, check scheme and set host */
1021 if (scheme==URN_SCH){
1022 uri->host.s=s;
1023 uri->host.len=p-s;
1024 LM_DBG("parsed urn scheme with host: %.*s\n",
1025 uri->host.len, uri->host.s);
1026 /* this is the port, it can't be the passwd */
1027 }else goto error_bad_port;
1028 break;
1029 case URI_HOST_P:
1030 case URI_HOST6_END:
1031 uri->host.s=s;
1032 uri->host.len=p-s;
1033 break;
1034 case URI_HOST: /* error: null host */
1035 case URI_HOST6_P: /* error: unterminated ipv6 reference*/
1036 goto error_bad_host;
1037 case URI_PORT:
1038 uri->port.s=s;
1039 uri->port.len=p-s;
1040 uri->port_no=port_no;
1041 break;
1042 case URI_PARAM:
1043 case URI_PARAM_P:
1044 /* intermediate param states */
1045 case PT_T: /* transport */
1046 case PT_R:
1047 case PT_A:
1048 case PT_N:
1049 case PT_S:
1050 case PT_P:
1051 case PT_O:
1052 case PT_R2:
1053 case PT_T2:
1054 case PT_eq: /* ignore empty transport params */
1055 case PTTL_T2: /* ttl */
1056 case PTTL_L:
1057 case PTTL_eq:
1058 case PU_U: /* user */
1059 case PU_S:
1060 case PU_E:
1061 case PU_R:
1062 case PU_eq:
1063 case PM_M: /* method */
1064 case PM_E:
1065 case PM_T:
1066 case PM_H:
1067 case PM_O:
1068 case PM_D:
1069 case PM_eq:
1070 case PLR_L: /* lr */
1071 case PR2_R: /* r2 */
1072 case PGR_G: /* gr */
1073 #ifdef USE_COMP
1074 case PCOMP_C:
1075 case PCOMP_O:
1076 case PCOMP_M:
1077 case PCOMP_P:
1078 case PCOMP_eq:
1079 #endif
1080 uri->params.s=s;
1081 uri->params.len=p-s;
1082 break;
1083 /* fin param states */
1084 case PLR_R_FIN:
1085 case PLR_eq:
1086 uri->params.s=s;
1087 uri->params.len=p-s;
1088 uri->lr.s=b;
1089 uri->lr.len=p-b;
1090 break;
1091 case PR2_2_FIN:
1092 case PR2_eq:
1093 uri->params.s=s;
1094 uri->params.len=p-s;
1095 uri->r2.s=b;
1096 uri->r2.len=p-b;
1097 break;
1098 case PGR_R_FIN:
1099 case PGR_eq:
1100 uri->params.s=s;
1101 uri->params.len=p-s;
1102 uri->gr.s=b;
1103 uri->gr.len=p-b;
1104 break;
1105 case URI_VAL_P:
1106 /* intermediate value states */
1107 case VU_U:
1108 case VU_D:
1109 case VT_T:
1110 case VT_C:
1111 case VTLS_L:
1112 case VS_S:
1113 case VS_C:
1114 case VS_T:
1115 case VW_W:
1116 uri->params.s=s;
1117 uri->params.len=p-s;
1118 param_set(b, v);
1119 break;
1120 #ifdef USE_COMP
1121 case VCOMP_S:
1122 case VCOMP_SIGC_I:
1123 case VCOMP_SIGC_G:
1124 case VCOMP_SIGC_C:
1125 case VCOMP_SIGC_O:
1126 case VCOMP_SIGC_M:
1127 case VCOMP_SGZ_E:
1128 case VCOMP_SGZ_R:
1129 case VCOMP_SGZ_G:
1130 /* unrecognized comp method, assume none */
1131 uri->params.s=s;
1132 uri->params.len=p-s;
1133 /* uri->comp=COMP_NONE ; */
1134 break;
1135 #endif
1136 /* fin value states */
1137 case VU_P_FIN:
1138 uri->params.s=s;
1139 uri->params.len=p-s;
1140 param_set(b, v);
1141 uri->proto=PROTO_UDP;
1142 break;
1143 case VT_P_FIN:
1144 uri->params.s=s;
1145 uri->params.len=p-s;
1146 param_set(b, v);
1147 uri->proto=PROTO_TCP;
1148 break;
1149 case VTLS_S_FIN:
1150 uri->params.s=s;
1151 uri->params.len=p-s;
1152 param_set(b, v);
1153 uri->proto=PROTO_TLS;
1154 break;
1155 case VS_P_FIN:
1156 uri->params.s=s;
1157 uri->params.len=p-s;
1158 param_set(b, v);
1159 uri->proto=PROTO_SCTP;
1160 break;
1161 case VW_S_FIN:
1162 uri->params.s=s;
1163 uri->params.len=p-s;
1164 param_set(b, v);
1165 uri->proto=PROTO_WS;
1166 break;
1167 #ifdef USE_COMP
1168 case VCOMP_SIGC_P_FIN:
1169 uri->params.s=s;
1170 uri->params.len=p-s;
1171 /* param_set(b, v); */
1172 uri->comp=COMP_SIGCOMP;
1173 break;
1174 case VCOMP_SGZ_Z_FIN:
1175 uri->params.s=s;
1176 uri->params.len=p-s;
1177 /* param_set(b, v); */
1178 uri->comp=COMP_SERGZ;
1179 break;
1180 #endif
1181 /* headers */
1182 case URI_HEADERS:
1183 uri->headers.s=s;
1184 uri->headers.len=p-s;
1185 if (error_headers) goto error_headers;
1186 break;
1187 default:
1188 goto error_bug;
1189 }
1190 switch(uri->type){
1191 case SIPS_URI_T:
1192 case SIP_URI_T:
1193 /* save the original sip: URI parameters in sip_params */
1194 uri->sip_params=uri->params;
1195 if ((phone2tel) &&
1196 (uri->user_param_val.len == 5) &&
1197 (strncmp(uri->user_param_val.s, "phone", 5) == 0)
1198 ) {
1199 uri->type = TEL_URI_T;
1200 uri->flags |= URI_SIP_USER_PHONE;
1201 /* move params from user into uri->params */
1202 p=q_memchr(uri->user.s, ';', uri->user.len);
1203 if (p){
1204 /* NOTE:
1205 * specialized uri params (user, maddr, etc.) still hold
1206 * the values from the sip-uri envelope
1207 * while uri->params point to the params in the embedded tel uri
1208 */
1209 uri->params.s=p+1;
1210 uri->params.len=uri->user.s+uri->user.len-uri->params.s;
1211 uri->user.len=p-uri->user.s;
1212 } else {
1213 uri->params.s=0;
1214 uri->params.len=0;
1215 }
1216 } else {
1217 uri->flags&=~URI_USER_NORMALIZE;
1218 }
1219 break;
1220 case TEL_URI_T:
1221 case TELS_URI_T:
1222 /* fix tel uris, move the number in uri and empty the host */
1223 uri->user=uri->host;
1224 uri->host=_sr_uri_empty;
1225 break;
1226 /* urn: do nothing */
1227 case URN_URI_T:
1228 break;
1229 case ERROR_URI_T:
1230 LM_ERR("parse uri unexpected error (BUG?)\n");
1231 goto error_bad_uri;
1232 break; /* do nothing, avoids a compilation warning */
1233 }
1234
1235 if(uri->port.len>5)
1236 goto error_invalid_port;
1237
1238 #ifdef EXTRA_DEBUG
1239 /* do stuff */
1240 LM_DBG("parsed uri:\n type=%d user=<%.*s>(%d)\n passwd=<%.*s>(%d)\n"
1241 " host=<%.*s>(%d)\n port=<%.*s>(%d): %d\n params=<%.*s>(%d)\n"
1242 " headers=<%.*s>(%d)\n",
1243 uri->type,
1244 uri->user.len, ZSW(uri->user.s), uri->user.len,
1245 uri->passwd.len, ZSW(uri->passwd.s), uri->passwd.len,
1246 uri->host.len, ZSW(uri->host.s), uri->host.len,
1247 uri->port.len, ZSW(uri->port.s), uri->port.len, uri->port_no,
1248 uri->params.len, ZSW(uri->params.s), uri->params.len,
1249 uri->headers.len, ZSW(uri->headers.s), uri->headers.len
1250 );
1251 LM_DBG(" uri flags : ");
1252 if (uri->flags & URI_USER_NORMALIZE) LM_DBG("user_need_norm ");
1253 if (uri->flags & URI_SIP_USER_PHONE) LM_DBG("sip_user_phone ");
1254 LM_DBG(" value=%d\n",uri->flags);
1255 LM_DBG(" uri params:\n transport=<%.*s>, val=<%.*s>, proto=%d\n",
1256 uri->transport.len, ZSW(uri->transport.s), uri->transport_val.len,
1257 ZSW(uri->transport_val.s), uri->proto);
1258 LM_DBG(" user-param=<%.*s>, val=<%.*s>\n",
1259 uri->user_param.len, ZSW(uri->user_param.s),
1260 uri->user_param_val.len, ZSW(uri->user_param_val.s));
1261 LM_DBG(" method=<%.*s>, val=<%.*s>\n",
1262 uri->method.len, ZSW(uri->method.s),
1263 uri->method_val.len, ZSW(uri->method_val.s));
1264 LM_DBG(" ttl=<%.*s>, val=<%.*s>\n",
1265 uri->ttl.len, ZSW(uri->ttl.s),
1266 uri->ttl_val.len, ZSW(uri->ttl_val.s));
1267 LM_DBG(" maddr=<%.*s>, val=<%.*s>\n",
1268 uri->maddr.len, ZSW(uri->maddr.s),
1269 uri->maddr_val.len, ZSW(uri->maddr_val.s));
1270 LM_DBG(" lr=<%.*s>\n", uri->lr.len, ZSW(uri->lr.s));
1271 LM_DBG(" r2=<%.*s>\n", uri->r2.len, ZSW(uri->r2.s));
1272 #ifdef USE_COMP
1273 LM_DBG(" comp=%d\n", uri->comp);
1274 #endif
1275
1276 #endif
1277 return 0;
1278
1279 error_too_short:
1280 LM_DBG("uri too short: <%.*s> (%d)\n",
1281 len, ZSW(buf), len);
1282 goto error_exit;
1283 error_bad_char:
1284 LM_DBG("bad char '%c' in state %d"
1285 " parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1286 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1287 len, ZSW(buf), len);
1288 goto error_exit;
1289 error_bad_host:
1290 LM_DBG("bad host in uri (error at char %c in"
1291 " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1292 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1293 len, ZSW(buf), len);
1294 goto error_exit;
1295 error_bad_port:
1296 LM_DBG("bad port in uri (error at char %c in"
1297 " state %d) parsed: <%.*s>(%d) /<%.*s> (%d)\n",
1298 *p, state, (int)(p-buf), ZSW(buf), (int)(p-buf),
1299 len, ZSW(buf), len);
1300 goto error_exit;
1301 error_invalid_port:
1302 LM_DBG("bad port in uri: [%.*s] in <%.*s>\n",
1303 uri->port.len, uri->port.s, len, ZSW(buf));
1304 goto error_exit;
1305 error_bad_uri:
1306 LM_DBG("bad uri, state %d parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1307 state, (int)(p-buf), ZSW(buf), (int)(p-buf), len,
1308 ZSW(buf), len);
1309 goto error_exit;
1310 error_headers:
1311 LM_DBG("bad uri headers: <%.*s>(%d) / <%.*s>(%d)\n",
1312 uri->headers.len, ZSW(uri->headers.s), uri->headers.len,
1313 len, ZSW(buf), len);
1314 goto error_exit;
1315 error_bug:
1316 LM_CRIT("BUG: bad state %d parsed: <%.*s> (%d) / <%.*s> (%d)\n",
1317 state, (int)(p-buf), ZSW(buf), (int)(p-buf), len, ZSW(buf), len);
1318 error_exit:
1319 ser_error=E_BAD_URI;
1320 uri->type=ERROR_URI_T;
1321 STATS_BAD_URI();
1322 return E_BAD_URI;
1323 }
1324
1325
_parse_ruri(str * uri,int * status,struct sip_uri * parsed_uri)1326 static inline int _parse_ruri(str *uri,
1327 int *status, struct sip_uri *parsed_uri)
1328 {
1329 if (*status) return 1;
1330
1331 if (parse_uri(uri->s, uri->len, parsed_uri)<0) {
1332 LM_ERR("bad uri <%.*s>\n", uri->len, ZSW(uri->s));
1333 *status=0;
1334 return -1;
1335 }
1336 *status=1;
1337 return 1;
1338 }
1339
parse_sip_msg_uri(struct sip_msg * msg)1340 int parse_sip_msg_uri(struct sip_msg* msg)
1341 {
1342 char* tmp;
1343 int tmp_len;
1344 if (msg->parsed_uri_ok) return 1;
1345
1346 if (msg->new_uri.s){
1347 tmp=msg->new_uri.s;
1348 tmp_len=msg->new_uri.len;
1349 }else{
1350 tmp=msg->first_line.u.request.uri.s;
1351 tmp_len=msg->first_line.u.request.uri.len;
1352 }
1353 if (parse_uri(tmp, tmp_len, &msg->parsed_uri)<0){
1354 LM_DBG("bad uri <%.*s>\n", tmp_len, tmp);
1355 msg->parsed_uri_ok=0;
1356 return -1;
1357 }
1358 msg->parsed_uri_ok=1;
1359 return 1;
1360 }
1361
parse_orig_ruri(struct sip_msg * msg)1362 int parse_orig_ruri(struct sip_msg* msg)
1363 {
1364 int ret;
1365
1366 ret=_parse_ruri(&REQ_LINE(msg).uri,
1367 &msg->parsed_orig_ruri_ok, &msg->parsed_orig_ruri);
1368 if (ret<0) LM_ERR("parse orig ruri failed\n");
1369 return ret;
1370 }
1371
normalize_tel_user(char * res,str * src)1372 int normalize_tel_user(char* res, str* src)
1373 {
1374 int i, l;
1375 l=0;
1376 for (i=0; i<src->len; i++) {
1377 switch (src->s[i]) {
1378 case '-':
1379 case '.':
1380 case '(':
1381 case ')':
1382 break;
1383 default:
1384 res[l++]=src->s[i];
1385 }
1386 }
1387 return l;
1388 }
1389
1390
1391 str s_sip = STR_STATIC_INIT("sip");
1392 str s_sips = STR_STATIC_INIT("sips");
1393 str s_tel = STR_STATIC_INIT("tel");
1394 str s_tels = STR_STATIC_INIT("tels");
1395 str s_urn = STR_STATIC_INIT("urn");
1396 static str s_null = STR_STATIC_INIT("");
1397
uri_type_to_str(uri_type type,str * s)1398 void uri_type_to_str(uri_type type, str *s) {
1399 switch (type) {
1400 case SIP_URI_T:
1401 *s = s_sip;
1402 break;
1403 case SIPS_URI_T:
1404 *s = s_sips;
1405 break;
1406 case TEL_URI_T:
1407 *s = s_tel;
1408 break;
1409 case TELS_URI_T:
1410 *s = s_tels;
1411 break;
1412 case URN_URI_T:
1413 *s = s_urn;
1414 break;
1415 default:
1416 *s = s_null;
1417 }
1418 }
1419
1420 static str s_udp = STR_STATIC_INIT("udp");
1421 static str s_tcp = STR_STATIC_INIT("tcp");
1422 static str s_tls = STR_STATIC_INIT("tls");
1423 static str s_sctp = STR_STATIC_INIT("sctp");
1424 static str s_ws = STR_STATIC_INIT("ws");
1425
proto_type_to_str(unsigned short type,str * s)1426 void proto_type_to_str(unsigned short type, str *s) {
1427 switch (type) {
1428 case PROTO_UDP:
1429 *s = s_udp;
1430 break;
1431 case PROTO_TCP:
1432 *s = s_tcp;
1433 break;
1434 case PROTO_TLS:
1435 *s = s_tls;
1436 break;
1437 case PROTO_SCTP:
1438 *s = s_sctp;
1439 break;
1440 case PROTO_WS:
1441 case PROTO_WSS:
1442 *s = s_ws;
1443 break;
1444 default:
1445 *s = s_null;
1446 }
1447 }
1448