Commit 604a2e59 authored by jehan's avatar jehan

Add better management of header parsing error in messages

parent 3a84a669
......@@ -131,6 +131,8 @@ message_header [belle_sip_message_t* message]
header_extension[TRUE] {
belle_sip_header_t* lheader = BELLE_SIP_HEADER($header_extension.ret);
do {
if (lheader == NULL) break; /*sanity check*/
belle_sip_message_add_header(message,lheader);
}
while((lheader=belle_sip_header_get_next(lheader)) != NULL); }
......
......@@ -72,6 +72,7 @@ belle_sip_message_t* belle_sip_message_parse (const char* value) {
size_t message_length;
return belle_sip_message_parse_raw(value,strlen(value),&message_length);
}
static int belle_sip_check_message_headers(const belle_sip_message_t* message);
belle_sip_message_t* belle_sip_message_parse_raw (const char* buff, size_t buff_length,size_t* message_length ) { \
pANTLR3_INPUT_STREAM input;
......@@ -91,6 +92,12 @@ belle_sip_message_t* belle_sip_message_parse_raw (const char* buff, size_t buff_
memcpy(l_parsed_object->body,buff+*message_length,l_parsed_object->body_length);
l_parsed_object->body[l_parsed_object->body_length]='\0';
}*/
/*check if message is valid*/
if (!belle_sip_check_message_headers(l_parsed_object)) {
/*error case*/
belle_sip_object_unref(l_parsed_object);
l_parsed_object=NULL;
}
parser ->free(parser);
tokens ->free(tokens);
lex ->free(lex);
......@@ -619,3 +626,128 @@ belle_sip_request_t * belle_sip_request_clone_with_body(const belle_sip_request_
}
return req;
}
typedef struct message_header_list {
const char* method;
const char* headers[10]; /*MAX headers*/
} message_header_list_t;
/**
RFC 3261 SIP: Session Initiation Protocol June 2002
Header field where proxy ACK BYE CAN INV OPT REG
__________________________________________________________________
Accept R - o - o m* o
Accept 2xx - - - o m* o
Accept 415 - c - c c c
Accept-Encoding R - o - o o o
Accept-Encoding 2xx - - - o m* o
Accept-Encoding 415 - c - c c c
Accept-Language R - o - o o o
Accept-Language 2xx - - - o m* o
Accept-Language 415 - c - c c c
Alert-Info R ar - - - o - -
Alert-Info 180 ar - - - o - -
Allow R - o - o o o
Allow 2xx - o - m* m* o
Allow r - o - o o o
Allow 405 - m - m m m
Authentication-Info 2xx - o - o o o
Authorization R o o o o o o
Call-ID c r m m m m m m
Call-Info ar - - - o o o
Contact R o - - m o o
Contact 1xx - - - o - -
Contact 2xx - - - m o o
Contact 3xx d - o - o o o
Contact 485 - o - o o o
Content-Disposition o o - o o o
Content-Encoding o o - o o o
Content-Language o o - o o o
Content-Length ar t t t t t t
Content-Type * * - * * *
CSeq c r m m m m m m
Date a o o o o o o
Error-Info 300-699 a - o o o o o
Expires - - - o - o
From c r m m m m m m
In-Reply-To R - - - o - -
Max-Forwards R amr m m m m m m
Min-Expires 423 - - - - - m
MIME-Version o o - o o o
Organization ar - - - o o o
Priority R ar - - - o - -
Proxy-Authenticate 407 ar - m - m m m
Proxy-Authenticate 401 ar - o o o o o
Proxy-Authorization R dr o o - o o o
Proxy-Require R ar - o - o o o
Record-Route R ar o o o o o -
Record-Route 2xx,18x mr - o o o o -
Reply-To - - - o - -
Require ar - c - c c c
Retry-After 404,413,480,486 - o o o o o
500,503 - o o o o o
600,603 - o o o o o
Route R adr c c c c c c
Server r - o o o o o
Subject R - - - o - -
Supported R - o o m* o o
Supported 2xx - o o m* m* o
Timestamp o o o o o o
To c(1) r m m m m m m
Unsupported 420 - m - m m m
User-Agent o o o o o o
Via R amr m m m m m m
Via rc dr m m m m m m
Warning r - o o o o o
WWW-Authenticate 401 ar - m - m m m
WWW-Authenticate 407 ar - o - o o o
Table 3: Summary of header fields, A--Z; (1): copied with possible
addition of tag
*/
static message_header_list_t mandatory_headers[] = {
{"REGISTER",{"Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
{"INVITE",{"Contact","Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
{"CANCEL",{"Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
{"BYE",{"Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
{"ACK",{"Call-ID","CSeq","From", "Max-Forwards","To","Via",NULL}},
{NULL,{NULL}}
};
/*static int belle_sip_message_is_mandatody_header(const char* method, const char* header_name) {
int i;
for (i=0;mandatory_headers[i].method!=NULL;i++) {
if (strcasecmp(method,mandatory_headers[i].method)==0) {
int j;
for(j=0;mandatory_headers[i].headers[j]!=NULL;j++) {
if (strcasecmp(header_name,mandatory_headers[i].headers[j])==0) {
return 1;
}
}
}
}
return 0;
}
*/
static int belle_sip_check_message_headers(const belle_sip_message_t* message) {
if (belle_sip_object_is_instance_of(BELLE_SIP_OBJECT(message),belle_sip_request_t_id)) {
int i;
const char * method = belle_sip_request_get_method(BELLE_SIP_REQUEST(message));
for (i=0;mandatory_headers[i].method!=NULL;i++) {
if (strcasecmp(method,mandatory_headers[i].method)==0) {
int j;
for(j=0;mandatory_headers[i].headers[j]!=NULL;j++) {
if (belle_sip_message_get_header(message,mandatory_headers[i].headers[j])==NULL) {
belle_sip_error("Missing mandatory header [%s] for message [%s]",mandatory_headers[i].headers[j],mandatory_headers[i].method);
return 0;
}
}
return 1;
}
}
}
/*else fixme should also check responses*/
return 1;
}
......@@ -253,6 +253,60 @@ static void test_sipfrag(void) {
}*/
static void testMalformedMessage(void) {
const char * raw_message= "INVITE sip:jehan@81.56.113.2:50343;transport=tcp;line=f18e0009dd6cc43 SIP/2.0\r\n"
"Via: SIP/2.0/UDP 192.168.1.12:15060;rport=15060;branch=z9hG4bK1596944937;received=81.56.113.2\r\n"
"Via: SIP/2.0/TCP 37.59.129.73;branch=z9hG4bK.SKvK9U327e8mU68XUv5rt144pg\r\n"
"Record-Route: <sip:37.59.129.73;lr;transport=tcp>\r\n"
"Record-Route: <sip:37.59.129.73;lr>\r\n"
"Max-Forwards: 70\r\n"
"From: <sip:jehan@sip.linphone.org>;tag=711138653\r\n"
"To: <sip:jehan@sip.linphone.org>\r\n"
"Call-ID: 977107319\r\n"
"CSeq: 21 INVITE\r\n"
"Contact: <sip:jehan-mac@192.168.1.8:5062>;pn-tok=/throttledthirdparty\r\n" /*Slash is not allowed for contact params*/\
"Subject: Phone call\r\n"
"User-Agent: Linphone/3.5.2 (eXosip2/3.6.0)\r\n"
"Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO\r\n"
"Content-Length: 0\r\n\r\n";
belle_sip_message_t* message = belle_sip_message_parse(raw_message);
CU_ASSERT_PTR_NULL(message);
}
static void testMalformedOptionnalHeaderInMessage(void) {
const char* raw_message = "REGISTER sip:192.168.0.20 SIP/2.0\r\n"\
"Via: SIP/2.0/UDP 192.168.1.8:5062;rport;branch=z9hG4bK1439638806\r\n"\
"From: <sip:jehan-mac@sip.linphone.org>;tag=465687829\r\n"\
"To: <sip:jehan-mac@sip.linphone.org>\r\n"\
"Call-ID: 1053183492\r\n"\
"CSeq: 1 REGISTER\r\n"\
"Contact: <sip:jehan-mac@192.168.1.8:5062>;pn-tok=/throttledthirdparty\r\n" /*Slash is not allowed for contact params*/\
"Max-Forwards: 70\r\n"\
"User-Agent: Linphone/3.3.99.10 (eXosip2/3.3.0)\r\n"\
"Expires: 3600\r\n"\
"Proxy-Authorization: Digest username=\"8117396\", realm=\"Realm\", nonce=\"MTMwNDAwMjIxMjA4NzVkODY4ZmZhODMzMzU4ZDJkOTA1NzM2NTQ2NDZlNmIz"\
", uri=\"sip:linphone.net\", response=\"eed376ff7c963441255ec66594e470e7\", algorithm=MD5, cnonce=\"0a4f113b\", qop=auth, nc=00000001\r\n"\
"Content-Length: 0\r\n\r\n";
belle_sip_request_t* request;
belle_sip_message_t* message = belle_sip_message_parse(raw_message);
char* encoded_message = belle_sip_object_to_string(BELLE_SIP_OBJECT(message));
belle_sip_object_unref(BELLE_SIP_OBJECT(message));
message = belle_sip_message_parse(encoded_message);
request = BELLE_SIP_REQUEST(message);
CU_ASSERT_STRING_EQUAL(belle_sip_request_get_method(request),"REGISTER");
CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Expires"));
CU_ASSERT_PTR_NOT_NULL(BELLE_SIP_HEADER_EXPIRES(belle_sip_message_get_header(message,"Expires")));
CU_ASSERT_PTR_NOT_NULL(belle_sip_message_get_header(message,"Proxy-Authorization"));
CU_ASSERT_PTR_NULL(belle_sip_message_get_header(message,"Contact")); /*contact is optionnal in register*/
check_uri_and_headers(message);
belle_sip_free(encoded_message);
belle_sip_object_unref(message);
}
/* NOTE - ORDER IS IMPORTANT - MUST TEST fread() AFTER fprintf() */
test_t message_tests[] = {
......@@ -263,6 +317,8 @@ test_t message_tests[] = {
{ "401 Response", test401Response },
{ "Origin extraction", test_extract_source },
{ "SIP frag", test_sipfrag },
{ "Malformed invite", testMalformedMessage },
{ "Malformed register", testMalformedOptionnalHeaderInMessage },
};
test_suite_t message_test_suite = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment