Browse code

core: new global parameter sip_parser_mode

- allow to control how sip parser behaves
- 0 - be less restrictive, to support more protocols
- 1 - be more strict on sip headers checks
- default 1

Daniel-Constantin Mierla authored on 10/10/2020 09:20:48
Showing 5 changed files
... ...
@@ -366,6 +366,7 @@ MEMJOIN		"mem_join"
366 366
 MEMSTATUSMODE		"mem_status_mode"
367 367
 CORELOG		"corelog"|"core_log"
368 368
 SIP_PARSER_LOG "sip_parser_log"
369
+SIP_PARSER_MODE "sip_parser_mode"
369 370
 SIP_WARNING sip_warning
370 371
 SERVER_SIGNATURE server_signature
371 372
 SERVER_HEADER server_header
... ...
@@ -817,6 +818,7 @@ IMPORTFILE      "import_file"
817 818
 <INITIAL>{MEMJOIN}	{ count(); yylval.strval=yytext; return MEMJOIN; }
818 819
 <INITIAL>{MEMSTATUSMODE}	{ count(); yylval.strval=yytext; return MEMSTATUSMODE; }
819 820
 <INITIAL>{SIP_PARSER_LOG}  { count(); yylval.strval=yytext; return SIP_PARSER_LOG; }
821
+<INITIAL>{SIP_PARSER_MODE}  { count(); yylval.strval=yytext; return SIP_PARSER_MODE; }
820 822
 <INITIAL>{CORELOG}	{ count(); yylval.strval=yytext; return CORELOG; }
821 823
 <INITIAL>{SIP_WARNING}	{ count(); yylval.strval=yytext; return SIP_WARNING; }
822 824
 <INITIAL>{USER}		{ count(); yylval.strval=yytext; return USER; }
... ...
@@ -391,6 +391,7 @@ extern char *default_routename;
391 391
 %token MEMJOIN
392 392
 %token MEMSTATUSMODE
393 393
 %token SIP_PARSER_LOG
394
+%token SIP_PARSER_MODE
394 395
 %token CORELOG
395 396
 %token SIP_WARNING
396 397
 %token SERVER_SIGNATURE
... ...
@@ -956,6 +957,8 @@ assign_stm:
956 957
 	| MEMSTATUSMODE EQUAL error { yyerror("int value expected"); }
957 958
 	| SIP_PARSER_LOG EQUAL intno { default_core_cfg.sip_parser_log=$3; }
958 959
 	| SIP_PARSER_LOG EQUAL error { yyerror("int value expected"); }
960
+	| SIP_PARSER_MODE EQUAL intno { ksr_sip_parser_mode=$3; }
961
+	| SIP_PARSER_MODE EQUAL error { yyerror("int value expected"); }
959 962
 	| CORELOG EQUAL intno { default_core_cfg.corelog=$3; }
960 963
 	| CORELOG EQUAL error { yyerror("int value expected"); }
961 964
 	| SIP_WARNING EQUAL NUMBER { sip_warning=$3; }
... ...
@@ -214,6 +214,7 @@ extern int ksr_verbose_startup;
214 214
 extern int ksr_route_locks_size;
215 215
 extern str _ksr_xavp_via_params;
216 216
 extern str _ksr_xavp_via_fields;
217
+extern int ksr_sip_parser_mode;
217 218
 
218 219
 extern char *_sr_uri_host_extra_chars;
219 220
 extern unsigned char *_ksr_hname_extra_chars;
... ...
@@ -66,6 +66,8 @@ int via_cnt;
66 66
 /* global request flags */
67 67
 unsigned int global_req_flags = 0;
68 68
 
69
+int ksr_sip_parser_mode = KSR_SIP_PARSER_MODE_STRICT;
70
+
69 71
 /* returns pointer to next header line, and fill hdr_f ;
70 72
  * if at end of header returns pointer to the last crlf  (always buf)*/
71 73
 char* get_hdr_field(char* const buf, char* const end, struct hdr_field* const hdr)
... ...
@@ -354,7 +356,13 @@ int parse_headers(struct sip_msg* const msg, const hdr_flags_t flags, const int
354 356
 				msg->parsed_flag|=HDR_T2F(hf->type);
355 357
 				break;
356 358
 			case HDR_CALLID_T:
357
-				if (msg->callid==0) msg->callid=hf;
359
+				if (msg->callid==0) {
360
+					msg->callid=hf;
361
+				} else if(ksr_sip_parser_mode & KSR_SIP_PARSER_MODE_STRICT) {
362
+					ERR("duplicate Call-ID header field [%.*s]\n",
363
+						(end-tmp>100)?100:(int)(end-tmp), tmp);
364
+					goto  error;
365
+				}
358 366
 				msg->parsed_flag|=HDR_CALLID_F;
359 367
 				break;
360 368
 			case HDR_SIPIFMATCH_T:
... ...
@@ -362,15 +370,33 @@ int parse_headers(struct sip_msg* const msg, const hdr_flags_t flags, const int
362 370
 				msg->parsed_flag|=HDR_SIPIFMATCH_F;
363 371
 				break;
364 372
 			case HDR_TO_T:
365
-				if (msg->to==0) msg->to=hf;
373
+				if (msg->to==0) {
374
+					msg->to=hf;
375
+				} else if(ksr_sip_parser_mode & KSR_SIP_PARSER_MODE_STRICT) {
376
+					ERR("duplicate To header field [%.*s]\n",
377
+						(end-tmp>100)?100:(int)(end-tmp), tmp);
378
+					goto  error;
379
+				}
366 380
 				msg->parsed_flag|=HDR_TO_F;
367 381
 				break;
368 382
 			case HDR_CSEQ_T:
369
-				if (msg->cseq==0) msg->cseq=hf;
383
+				if (msg->cseq==0) {
384
+					msg->cseq=hf;
385
+				} else if(ksr_sip_parser_mode & KSR_SIP_PARSER_MODE_STRICT) {
386
+					ERR("duplicate CSeq header field [%.*s]\n",
387
+						(end-tmp>100)?100:(int)(end-tmp), tmp);
388
+					goto  error;
389
+				}
370 390
 				msg->parsed_flag|=HDR_CSEQ_F;
371 391
 				break;
372 392
 			case HDR_FROM_T:
373
-				if (msg->from==0) msg->from=hf;
393
+				if (msg->from==0) {
394
+					msg->from=hf;
395
+				} else if(ksr_sip_parser_mode & KSR_SIP_PARSER_MODE_STRICT) {
396
+					ERR("duplicate From header field [%.*s]\n",
397
+						(end-tmp>100)?100:(int)(end-tmp), tmp);
398
+					goto  error;
399
+				}
374 400
 				msg->parsed_flag|=HDR_FROM_F;
375 401
 				break;
376 402
 			case HDR_CONTACT_T:
... ...
@@ -378,7 +404,13 @@ int parse_headers(struct sip_msg* const msg, const hdr_flags_t flags, const int
378 404
 				msg->parsed_flag|=HDR_CONTACT_F;
379 405
 				break;
380 406
 			case HDR_MAXFORWARDS_T:
381
-				if(msg->maxforwards==0) msg->maxforwards=hf;
407
+				if(msg->maxforwards==0) {
408
+					msg->maxforwards=hf;
409
+				} else {
410
+					ERR("duplicate Max-Forwards header field [%.*s]\n",
411
+						(end-tmp>100)?100:(int)(end-tmp), tmp);
412
+					goto  error;
413
+				}
382 414
 				msg->parsed_flag|=HDR_MAXFORWARDS_F;
383 415
 				break;
384 416
 			case HDR_ROUTE_T:
... ...
@@ -394,7 +426,13 @@ int parse_headers(struct sip_msg* const msg, const hdr_flags_t flags, const int
394 426
 				msg->parsed_flag|=HDR_CONTENTTYPE_F;
395 427
 				break;
396 428
 			case HDR_CONTENTLENGTH_T:
397
-				if (msg->content_length==0) msg->content_length = hf;
429
+				if (msg->content_length==0) {
430
+					msg->content_length = hf;
431
+				} else if(ksr_sip_parser_mode & KSR_SIP_PARSER_MODE_STRICT) {
432
+					ERR("duplicate Content-Length header field [%.*s]\n",
433
+						(end-tmp>100)?100:(int)(end-tmp), tmp);
434
+					goto  error;
435
+				}
398 436
 				msg->parsed_flag|=HDR_CONTENTLENGTH_F;
399 437
 				break;
400 438
 			case HDR_AUTHORIZATION_T:
... ...
@@ -127,6 +127,10 @@ typedef enum request_method {
127 127
 #define FL_MTU_FB_MASK  (FL_MTU_TCP_FB|FL_MTU_TLS_FB|FL_MTU_SCTP_FB)
128 128
 
129 129
 
130
+/* sip parser mode flags (1<<n) */
131
+#define KSR_SIP_PARSER_MODE_NONE 0
132
+#define KSR_SIP_PARSER_MODE_STRICT 1
133
+
130 134
 #define IFISMETHOD(methodname,firstchar)                                  \
131 135
 if (  (*tmp==(firstchar) || *tmp==((firstchar) | 32)) &&                  \
132 136
 		strncasecmp( tmp+1, &#methodname[1], methodname##_LEN-1)==0 &&     \