[asterisk-commits] wdoekes: branch 1.8 r375111 - /branches/1.8/channels/chan_sip.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Oct 16 16:41:23 CDT 2012
Author: wdoekes
Date: Tue Oct 16 16:41:16 2012
New Revision: 375111
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=375111
Log:
Fixes to the fd-oriented SIP TCP reads.
Don't crash on large user input. Allow SIP headers without space.
Optimize code a bit.
Review: https://reviewboard.asterisk.org/r/2162
Modified:
branches/1.8/channels/chan_sip.c
Modified: branches/1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/channels/chan_sip.c?view=diff&rev=375111&r1=375110&r2=375111
==============================================================================
--- branches/1.8/channels/chan_sip.c (original)
+++ branches/1.8/channels/chan_sip.c Tue Oct 16 16:41:16 2012
@@ -2668,54 +2668,50 @@
*/
static int read_raw_content_length(const char *message)
{
- char *end_of_line;
char *content_length_str;
- char *l_str;
- int content_length;
+ int content_length = -1;
+
+ struct ast_str *msg_copy;
char *msg;
+ /* Using a ast_str because lws2sws takes one of those */
+ if (!(msg_copy = ast_str_create(strlen(message) + 1))) {
+ return -1;
+ }
+ ast_str_set(&msg_copy, 0, "%s", message);
+
if (sip_cfg.pedanticsipchecking) {
- struct ast_str *msg_copy = ast_str_create(strlen(message));
- if (!msg_copy) {
- return -1;
- }
- ast_str_set(&msg_copy, 0, "%s", message);
lws2sws(msg_copy);
- msg = ast_strdupa(ast_str_buffer(msg_copy));
- ast_free(msg_copy);
+ }
+
+ msg = ast_str_buffer(msg_copy);
+
+ /* Let's find a Content-Length header */
+ if ((content_length_str = strcasestr(msg, "\nContent-Length:"))) {
+ content_length_str += sizeof("\nContent-Length:") - 1;
+ } else if ((content_length_str = strcasestr(msg, "\nl:"))) {
+ content_length_str += sizeof("\nl:") - 1;
} else {
- msg = ast_strdupa(message);
- }
-
- /* Let's find a Content-Length header */
- content_length_str = strcasestr(msg, "\nContent-Length:");
- if (!content_length_str && !(l_str = strcasestr(msg, "\nl:"))) {
/* RFC 3261 18.3
* "In the case of stream-oriented transports such as TCP, the Content-
* Length header field indicates the size of the body. The Content-
* Length header field MUST be used with stream oriented transports."
*/
- return -1;
- }
- if (content_length_str) {
- content_length_str += sizeof("\nContent-Length:");
- } else if (l_str) {
- content_length_str = l_str + sizeof("\nl:");
- } else {
- return -1;
- }
-
- end_of_line = strchr(content_length_str, '\n');
-
- if (!end_of_line) {
- return -1;
- }
-
- if (sscanf(content_length_str, "%30d", &content_length) == 1) {
- return content_length;
- }
-
- return -1;
+ goto done;
+ }
+
+ /* Double-check that this is a complete header */
+ if (!strchr(content_length_str, '\n')) {
+ goto done;
+ }
+
+ if (sscanf(content_length_str, "%30d", &content_length) != 1) {
+ content_length = -1;
+ }
+
+done:
+ ast_free(msg_copy);
+ return content_length;
}
/*!
@@ -2732,11 +2728,11 @@
*/
static enum message_integrity check_message_integrity(struct ast_str **request, struct ast_str **overflow)
{
- char *message = ast_strdupa(ast_str_buffer(*request));
+ char *message = ast_str_buffer(*request);
char *body;
int content_length;
+ int message_len = ast_str_strlen(*request);
int body_len;
- int message_len = strlen(message);
/* Important pieces to search for in a SIP request are \r\n\r\n. This
* marks either
@@ -2751,7 +2747,7 @@
return MESSAGE_FRAGMENT;
}
body += sizeof("\r\n\r\n") - 1;
- body_len = strlen(body);
+ body_len = message_len - (body - message);
body[-1] = '\0';
content_length = read_raw_content_length(message);
@@ -2767,8 +2763,8 @@
if (body_len == 0) {
return MESSAGE_COMPLETE;
} else {
+ ast_str_append(overflow, 0, "%s", body);
ast_str_truncate(*request, message_len - body_len);
- ast_str_append(overflow, 0, "%s", body);
return MESSAGE_FRAGMENT_COMPLETE;
}
}
@@ -2782,8 +2778,8 @@
/* We have the full message plus a fragment of a further
* message
*/
+ ast_str_append(overflow, 0, "%s", body + content_length);
ast_str_truncate(*request, message_len - (body_len - content_length));
- ast_str_append(overflow, 0, "%s", body + content_length);
return MESSAGE_FRAGMENT_COMPLETE;
} else {
/* Yay! Full message with no extra content */
@@ -31076,7 +31072,7 @@
"Contact: sip:127.0.0.1:5061\r\n"
"Max-Forwards: 70\r\n"
"Content-Type: application/sdp\r\n"
- "l: 130\r\n"
+ "l:130\r\n" /* intentionally no space */
"\r\n"
"v=0\r\n"
"o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
@@ -31102,7 +31098,7 @@
"Content-Type: application/sdp\r\n"
"DisContent-Length: 0\r\n"
"MalContent-Length: 60\r\n"
- "Content-Length: 130\r\n"
+ "Content-Length:130\r\n" /* intentionally no space */
"\r\n"
"v=0\r\n"
"o=user1 53655765 2353687637 IN IP4 127.0.0.1\r\n"
@@ -31192,7 +31188,7 @@
switch (cmd) {
case TEST_INIT:
info->name = "sip_tcp_message_fragmentation";
- info->category = "/main/sip/transport";
+ info->category = "/main/sip/transport/";
info->summary = "SIP TCP message fragmentation test";
info->description =
"Tests reception of different TCP messages that have been fragmented or"
More information about the asterisk-commits
mailing list