summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--channels/chan_sip.c58
-rw-r--r--channels/sip/include/sip.h1
-rw-r--r--main/http.c20
-rw-r--r--res/res_jabber.c5
4 files changed, 60 insertions, 24 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index e1dfd5ddd..b2b3395c7 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -2718,19 +2718,20 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
int authenticated, time_t start, struct sip_threadinfo *me)
{
int res, content_length, after_poll = 1, need_poll = 1;
+ size_t datalen = ast_str_strlen(req->data);
char buf[1024] = "";
int timeout = -1;
-
- /* Read in headers one line at a time */
- while (ast_str_strlen(req->data) < 4 || strncmp(REQ_OFFSET_TO_STR(req, data->used - 4), "\r\n\r\n", 4)) {
- if (!tcptls_session->client && !authenticated) {
- if ((timeout = sip_check_authtimeout(start)) < 0) {
- ast_debug(2, "SIP SSL server failed to determine authentication timeout\n");
+
+ /* Read in headers one line at a time */
+ while (datalen < 4 || strncmp(REQ_OFFSET_TO_STR(req, data->used - 4), "\r\n\r\n", 4)) {
+ if (!tcptls_session->client && !authenticated) {
+ if ((timeout = sip_check_authtimeout(start)) < 0) {
+ ast_debug(2, "SIP TLS server failed to determine authentication timeout\n");
return -1;
}
if (timeout == 0) {
- ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+ ast_debug(2, "SIP TLS server timed out\n");
return -1;
}
} else {
@@ -2745,11 +2746,11 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
after_poll = 1;
res = ast_wait_for_input(tcptls_session->fd, timeout);
if (res < 0) {
- ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+ ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res);
return -1;
} else if (res == 0) {
/* timeout */
- ast_debug(2, "SIP TCP server timed out\n");
+ ast_debug(2, "SIP TLS server timed out\n");
return -1;
}
}
@@ -2770,6 +2771,13 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
return -1;
}
ast_str_append(&req->data, 0, "%s", buf);
+
+ datalen = ast_str_strlen(req->data);
+ if (datalen > SIP_MAX_PACKET_SIZE) {
+ ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n",
+ ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+ return -1;
+ }
}
copy_request(reqcpy, req);
parse_request(reqcpy);
@@ -2783,7 +2791,7 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
}
if (timeout == 0) {
- ast_debug(2, "SIP SSL server timed out\n");
+ ast_debug(2, "SIP TLS server timed out\n");
return -1;
}
} else {
@@ -2795,11 +2803,11 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
after_poll = 1;
res = ast_wait_for_input(tcptls_session->fd, timeout);
if (res < 0) {
- ast_debug(2, "SIP TCP server :: ast_wait_for_input returned %d\n", res);
+ ast_debug(2, "SIP TLS server :: ast_wait_for_input returned %d\n", res);
return -1;
} else if (res == 0) {
/* timeout */
- ast_debug(2, "SIP TCP server timed out\n");
+ ast_debug(2, "SIP TLS server timed out\n");
return -1;
}
}
@@ -2822,6 +2830,13 @@ static int sip_tls_read(struct sip_request *req, struct sip_request *reqcpy, str
}
content_length -= strlen(buf);
ast_str_append(&req->data, 0, "%s", buf);
+
+ datalen = ast_str_strlen(req->data);
+ if (datalen > SIP_MAX_PACKET_SIZE) {
+ ast_log(LOG_WARNING, "Rejecting TLS packet from '%s' because way too large: %zu\n",
+ ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+ return -1;
+ }
}
}
/*! \todo XXX If there's no Content-Length or if the content-length and what
@@ -2995,6 +3010,8 @@ static int sip_tcp_read(struct sip_request *req, struct ast_tcptls_session_insta
enum message_integrity message_integrity = MESSAGE_FRAGMENT;
while (message_integrity == MESSAGE_FRAGMENT) {
+ size_t datalen;
+
if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
char readbuf[4097];
int timeout;
@@ -3034,6 +3051,13 @@ static int sip_tcp_read(struct sip_request *req, struct ast_tcptls_session_insta
ast_str_append(&req->data, 0, "%s", ast_str_buffer(tcptls_session->overflow_buf));
ast_str_reset(tcptls_session->overflow_buf);
}
+
+ datalen = ast_str_strlen(req->data);
+ if (datalen > SIP_MAX_PACKET_SIZE) {
+ ast_log(LOG_WARNING, "Rejecting TCP packet from '%s' because way too large: %zu\n",
+ ast_sockaddr_stringify(&tcptls_session->remote_address), datalen);
+ return -1;
+ }
message_integrity = check_message_integrity(&req->data, &tcptls_session->overflow_buf);
}
@@ -3105,7 +3129,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
}
me->threadid = pthread_self();
- ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
+ ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP");
/* set up pollfd to watch for reads on both the socket and the alert_pipe */
fds[0].fd = tcptls_session->fd;
@@ -3139,7 +3163,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
}
if (timeout == 0) {
- ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+ ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP");
goto cleanup;
}
} else {
@@ -3149,11 +3173,11 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
if (ast_str_strlen(tcptls_session->overflow_buf) == 0) {
res = ast_poll(fds, 2, timeout); /* polls for both socket and alert_pipe */
if (res < 0) {
- ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
+ ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "TLS": "TCP", res);
goto cleanup;
} else if (res == 0) {
/* timeout */
- ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
+ ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "TLS": "TCP");
goto cleanup;
}
}
@@ -3235,7 +3259,7 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
}
}
- ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
+ ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "TLS" : "TCP");
cleanup:
if (tcptls_session && !tcptls_session->client && !authenticated) {
diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h
index 9a818553b..f51ac7749 100644
--- a/channels/sip/include/sip.h
+++ b/channels/sip/include/sip.h
@@ -101,6 +101,7 @@
#define SIP_MAX_HEADERS 64 /*!< Max amount of SIP headers to read */
#define SIP_MAX_LINES 256 /*!< Max amount of lines in SIP attachment (like SDP) */
+#define SIP_MAX_PACKET_SIZE 20480 /*!< Max SIP packet size */
#define SIP_MIN_PACKET 4096 /*!< Initialize size of memory to allocate for packets */
#define MAX_HISTORY_ENTRIES 50 /*!< Max entires in the history list for a sip_pvt */
diff --git a/main/http.c b/main/http.c
index 44148edf8..fc2931290 100644
--- a/main/http.c
+++ b/main/http.c
@@ -611,6 +611,7 @@ struct ast_variable *ast_http_get_post_vars(
int content_length = 0;
struct ast_variable *v, *post_vars=NULL, *prev = NULL;
char *buf, *var, *val;
+ int res;
for (v = headers; v; v = v->next) {
if (!strcasecmp(v->name, "Content-Type")) {
@@ -623,20 +624,28 @@ struct ast_variable *ast_http_get_post_vars(
for (v = headers; v; v = v->next) {
if (!strcasecmp(v->name, "Content-Length")) {
- content_length = atoi(v->value) + 1;
+ content_length = atoi(v->value);
break;
}
}
- if (!content_length) {
+ if (content_length <= 0) {
return NULL;
}
- buf = ast_alloca(content_length);
- if (!fgets(buf, content_length, ser->f)) {
+ buf = ast_malloc(content_length + 1);
+ if (!buf) {
return NULL;
}
+ res = fread(buf, 1, content_length, ser->f);
+ if (res < content_length) {
+ /* Error, distinguishable by ferror() or feof(), but neither
+ * is good. */
+ goto done;
+ }
+ buf[content_length] = '\0';
+
while ((val = strsep(&buf, "&"))) {
var = strsep(&val, "=");
if (val) {
@@ -654,6 +663,9 @@ struct ast_variable *ast_http_get_post_vars(
prev = v;
}
}
+
+done:
+ ast_free(buf);
return post_vars;
}
diff --git a/res/res_jabber.c b/res/res_jabber.c
index fa6bbfdbf..fa45fdf6d 100644
--- a/res/res_jabber.c
+++ b/res/res_jabber.c
@@ -785,7 +785,7 @@ static struct ast_custom_function jabberstatus_function = {
*/
static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, char *data, char *buf, size_t buflen)
{
- char *aux = NULL, *parse = NULL;
+ char *parse = NULL;
int timeout;
int jidlen, resourcelen;
struct timeval start;
@@ -902,7 +902,7 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
continue;
}
found = 1;
- aux = ast_strdupa(tmp->message);
+ ast_copy_string(buf, tmp->message, buflen);
AST_LIST_REMOVE_CURRENT(list);
aji_message_destroy(tmp);
break;
@@ -927,7 +927,6 @@ static int acf_jabberreceive_read(struct ast_channel *chan, const char *name, ch
ast_log(LOG_NOTICE, "Timed out : no message received from %s\n", args.jid);
return -1;
}
- ast_copy_string(buf, aux, buflen);
return 0;
}