[Pkg-voip-commits] r8880 - in /asterisk/branches/squeeze/debian: changelog patches/AST-2011-005 patches/AST-2011-006 patches/series
tzafrir at alioth.debian.org
tzafrir at alioth.debian.org
Thu Apr 21 20:43:32 UTC 2011
Author: tzafrir
Date: Thu Apr 21 20:43:31 2011
New Revision: 8880
URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=8880
Log:
Patch AST-2011-006: Resource exhaustion in chan_skinny and AJAM
Added:
asterisk/branches/squeeze/debian/patches/AST-2011-006
Modified:
asterisk/branches/squeeze/debian/changelog
asterisk/branches/squeeze/debian/patches/AST-2011-005
asterisk/branches/squeeze/debian/patches/series
Modified: asterisk/branches/squeeze/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/squeeze/debian/changelog?rev=8880&op=diff
==============================================================================
--- asterisk/branches/squeeze/debian/changelog (original)
+++ asterisk/branches/squeeze/debian/changelog Thu Apr 21 20:43:31 2011
@@ -3,12 +3,13 @@
* Patch AST-2011-002 (CVE-2011-1147): Multiple crash vulnerabilities in
UDPTL code (Closes: #614580).
* Patch AST-2011-005: Resource exhaustion in Asterisk Manager Interface
+ * Patch AST-2011-006: Resource exhaustion in chan_skinny and AJAM
(Closes: #618790).
* Patches AST-2011-003, manager_manager_bugfix_reload - its pre-requirements.
* Patch AST-2011-004: Remote crash vulnerability in TCP/TLS server
(Closes: #618791).
- -- Tzafrir Cohen <tzafrir at debian.org> Fri, 18 Mar 2011 16:32:57 +0200
+ -- Tzafrir Cohen <tzafrir at debian.org> Thu, 21 Apr 2011 23:41:46 +0300
asterisk (1:1.6.2.9-2+squeeze1) stable-security; urgency=high
Modified: asterisk/branches/squeeze/debian/patches/AST-2011-005
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/squeeze/debian/patches/AST-2011-005?rev=8880&op=diff
==============================================================================
--- asterisk/branches/squeeze/debian/patches/AST-2011-005 (original)
+++ asterisk/branches/squeeze/debian/patches/AST-2011-005 Thu Apr 21 20:43:31 2011
@@ -1,6 +1,6 @@
From: Matthew Nicholson <mnicholson at digium.com>
Date: Tue, 5 Apr 2011 14:13:07 +0000
-Subject: Limit the number of unauthenticated manager and their time
+Subject: Limit the number of unauthenticated manager and their time
Bug: https://issues.asterisk.org/view.php?id=18996
Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=312764
Added: asterisk/branches/squeeze/debian/patches/AST-2011-006
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/squeeze/debian/patches/AST-2011-006?rev=8880&op=file
==============================================================================
--- asterisk/branches/squeeze/debian/patches/AST-2011-006 (added)
+++ asterisk/branches/squeeze/debian/patches/AST-2011-006 Thu Apr 21 20:43:31 2011
@@ -1,0 +1,646 @@
+From: Matthew Nicholson <mnicholson at digium.com>
+Date: Thu, 21 Apr 2011 18:22:19 +0000
+Bug: https://issues.asterisk.org/view.php?id=18787
+Subject: limits unauthenticated TCP sessions
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=314620
+
+Added limits to the number of unauthenticated sessions TCP based protocols
+are allowed to have open simultaneously. Also added timeouts for
+unauthenticated sessions where it made sense to do so.
+
+Unrelated, the manager interface now properly checks if the user has the
+"system" privilege before executing shell commands via the Originate action.
+
+This is a followup to AST-2011-005. It applies a similar fix to chan_skinny
+and to manager interface over HTTP.
+
+Skinny, or SCCP, is enabled by default (though not used in most settings).
+To disable: 'noload => chan_skinny.so' in /etc/asterisk/modules.conf .
+
+Manager over HTTP is not enabled by default on Debian.
+
+See also:
+ https://issues.asterisk.org/view.php?id=18996
+ http://downloads.asterisk.org/pub/security/AST-2011-005.html
+ http://downloads.asterisk.org/pub/security/AST-2011-006.html
+
+---
+ channels/chan_sip.c | 162 ++++++++++++++++++++++++++++++++++++++++++--
+ channels/chan_skinny.c | 78 ++++++++++++++++++++-
+ configs/http.conf.sample | 5 ++
+ configs/sip.conf.sample | 10 +++
+ configs/skinny.conf.sample | 9 +++
+ main/http.c | 15 ++++
+ main/manager.c | 34 +++++----
+ 7 files changed, 288 insertions(+), 25 deletions(-)
+
+diff --git a/channels/chan_sip.c b/channels/chan_sip.c
+index fdf1ffc..95a3017 100644
+--- a/channels/chan_sip.c
++++ b/channels/chan_sip.c
+@@ -500,6 +500,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+ #define DEFAULT_MWI_EXPIRY 3600
+ #define DEFAULT_REGISTRATION_TIMEOUT 20
+ #define DEFAULT_MAX_FORWARDS "70"
++#define DEFAULT_AUTHLIMIT 100
++#define DEFAULT_AUTHTIMEOUT 30
+
+ /* guard limit must be larger than guard secs */
+ /* guard min must be < 1000, and should be >= 250 */
+@@ -552,6 +554,10 @@ static int mwi_expiry = DEFAULT_MWI_EXPIRY;
+
+ #define SDP_MAX_RTPMAP_CODECS 32 /*!< Maximum number of codecs allowed in received SDP */
+
++static int unauth_sessions = 0;
++static int authlimit = DEFAULT_AUTHLIMIT;
++static int authtimeout = DEFAULT_AUTHTIMEOUT;
++
+ /*! \brief Global jitterbuffer configuration - by default, jb is disabled */
+ static struct ast_jb_conf default_jbconf =
+ {
+@@ -1205,6 +1211,7 @@ struct sip_request {
+ char debug; /*!< print extra debugging if non zero */
+ char has_to_tag; /*!< non-zero if packet has To: tag */
+ char ignore; /*!< if non-zero This is a re-transmit, ignore it */
++ char authenticated; /*!< non-zero if this request was authenticated */
+ /* Array of offsets into the request string of each SIP header*/
+ ptrdiff_t header[SIP_MAX_HEADERS];
+ /* Array of offsets into the request string of each SDP line*/
+@@ -2913,21 +2920,48 @@ static void *sip_tcp_worker_fn(void *data)
+ return _sip_tcp_helper_thread(NULL, tcptls_session);
+ }
+
++/*! \brief Check if the authtimeout has expired.
++ * \param start the time when the session started
++ *
++ * \retval 0 the timeout has expired
++ * \retval -1 error
++ * \return the number of milliseconds until the timeout will expire
++ */
++static int sip_check_authtimeout(time_t start)
++{
++ int timeout;
++ time_t now;
++ if(time(&now) == -1) {
++ ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++ return -1;
++ }
++
++ timeout = (authtimeout - (now - start)) * 1000;
++ if (timeout < 0) {
++ /* we have timed out */
++ return 0;
++ }
++
++ return timeout;
++}
++
+ /*! \brief SIP TCP thread management function
+ This function reads from the socket, parses the packet into a request
+ */
+ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session)
+ {
+- int res, cl;
++ int res, cl, timeout = -1, authenticated = 0, flags;
++ time_t start;
+ struct sip_request req = { 0, } , reqcpy = { 0, };
+ struct sip_threadinfo *me = NULL;
+ char buf[1024] = "";
+ struct pollfd fds[2] = { { 0 }, { 0 }, };
+ struct ast_tcptls_session_args *ca = NULL;
+
+- /* If this is a server session, then the connection has already been setup,
+- * simply create the threadinfo object so we can access this thread for writing.
+- *
++ /* If this is a server session, then the connection has already been
++ * setup. Check if the authlimit has been reached and if not create the
++ * threadinfo object so we can access this thread for writing.
++ *
+ * if this is a client connection more work must be done.
+ * 1. We own the parent session args for a client connection. This pointer needs
+ * to be held on to so we can decrement it's ref count on thread destruction.
+@@ -2936,6 +2970,22 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
+ * 3. Last, the tcptls_session must be started.
+ */
+ if (!tcptls_session->client) {
++ if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
++ /* unauth_sessions is decremented in the cleanup code */
++ goto cleanup;
++ }
++
++ if ((flags = fcntl(tcptls_session->fd, F_GETFL)) == -1) {
++ ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
++ goto cleanup;
++ }
++
++ flags |= O_NONBLOCK;
++ if (fcntl(tcptls_session->fd, F_SETFL, flags) == -1) {
++ ast_log(LOG_ERROR, "error setting socket to non blocking mode, fcntl() failed: %s\n", strerror(errno));
++ goto cleanup;
++ }
++
+ if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) {
+ goto cleanup;
+ }
+@@ -2965,14 +3015,41 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
+ if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET)))
+ goto cleanup;
+
++ if(time(&start) == -1) {
++ ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++ goto cleanup;
++ }
++
+ for (;;) {
+ struct ast_str *str_save;
+
+- res = ast_poll(fds, 2, -1); /* polls for both socket and alert_pipe */
++ if (!tcptls_session->client && req.authenticated && !authenticated) {
++ authenticated = 1;
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
++ }
++
++ /* calculate the timeout for unauthenticated server sessions */
++ if (!tcptls_session->client && !authenticated ) {
++ if ((timeout = sip_check_authtimeout(start)) < 0) {
++ goto cleanup;
++ }
++
++ if (timeout == 0) {
++ ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
++ goto cleanup;
++ }
++ } else {
++ timeout = -1;
++ }
+
++ 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);
+ goto cleanup;
++ } else if (res == 0) {
++ /* timeout */
++ ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
++ goto cleanup;
+ }
+
+ /* handle the socket event, check for both reads from the socket fd,
+@@ -3005,6 +3082,29 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
+
+ /* Read in headers one line at a time */
+ while (req.len < 4 || strncmp(REQ_OFFSET_TO_STR(&req, len - 4), "\r\n\r\n", 4)) {
++ if (!tcptls_session->client && !authenticated ) {
++ if ((timeout = sip_check_authtimeout(start)) < 0) {
++ goto cleanup;
++ }
++
++ if (timeout == 0) {
++ ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
++ goto cleanup;
++ }
++ } else {
++ timeout = -1;
++ }
++
++ res = ast_wait_for_input(tcptls_session->fd, timeout);
++ if (res < 0) {
++ ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
++ goto cleanup;
++ } else if (res == 0) {
++ /* timeout */
++ ast_debug(2, "SIP %s server timed out\n", tcptls_session->ssl ? "SSL": "TCP");
++ goto cleanup;
++ }
++
+ ast_mutex_lock(&tcptls_session->lock);
+ if (!fgets(buf, sizeof(buf), tcptls_session->f)) {
+ ast_mutex_unlock(&tcptls_session->lock);
+@@ -3022,6 +3122,29 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
+ if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) {
+ while (cl > 0) {
+ size_t bytes_read;
++ if (!tcptls_session->client && !authenticated ) {
++ if ((timeout = sip_check_authtimeout(start)) < 0) {
++ goto cleanup;
++ }
++
++ if (timeout == 0) {
++ ast_debug(2, "SIP %s server timed out", tcptls_session->ssl ? "SSL": "TCP");
++ goto cleanup;
++ }
++ } else {
++ timeout = -1;
++ }
++
++ res = ast_wait_for_input(tcptls_session->fd, timeout);
++ if (res < 0) {
++ ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
++ goto cleanup;
++ } else if (res == 0) {
++ /* timeout */
++ ast_debug(2, "SIP %s server timed out", tcptls_session->ssl ? "SSL": "TCP");
++ goto cleanup;
++ }
++
+ ast_mutex_lock(&tcptls_session->lock);
+ if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) {
+ ast_mutex_unlock(&tcptls_session->lock);
+@@ -3080,6 +3203,10 @@ static void *_sip_tcp_helper_thread(struct sip_pvt *pvt, struct ast_tcptls_sessi
+ ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
+
+ cleanup:
++ if (!tcptls_session->client && !authenticated) {
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
++ }
++
+ if (me) {
+ ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing");
+ ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref");
+@@ -20474,6 +20601,8 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
+ }
+ }
+
++ req->authenticated = 1;
++
+ /* We have a succesful authentication, process the SDP portion if there is one */
+ if (find_sdp(req)) {
+ if (process_sdp(p, req, SDP_T38_INITIATE)) {
+@@ -22047,8 +22176,10 @@ static int handle_request_register(struct sip_pvt *p, struct sip_request *req, s
+ get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
+ reason);
+ append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
+- } else
++ } else {
++ req->authenticated = 1;
+ append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
++ }
+
+ if (res < 1) {
+ /* Destroy the session, but keep us around for just a bit in case they don't
+@@ -22503,6 +22634,11 @@ static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin)
+ }
+ p->recv = *sin;
+
++ /* if we have an owner, then this request has been authenticated */
++ if (p->owner) {
++ req->authenticated = 1;
++ }
++
+ if (p->do_history) /* This is a request or response, note what it was for */
+ append_history(p, "Rx", "%s / %s / %s", req->data->str, get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2));
+
+@@ -25064,6 +25200,8 @@ static int reload_config(enum channelreloadreason reason)
+ global_qualifyfreq = DEFAULT_QUALIFYFREQ;
+ global_t38_maxdatagram = -1;
+ global_shrinkcallerid = 1;
++ authlimit = DEFAULT_AUTHLIMIT;
++ authtimeout = DEFAULT_AUTHTIMEOUT;
+
+ sip_cfg.matchexterniplocally = DEFAULT_MATCHEXTERNIPLOCALLY;
+
+@@ -25310,6 +25448,18 @@ static int reload_config(enum channelreloadreason reason)
+ mwi_expiry = atoi(v->value);
+ if (mwi_expiry < 1)
+ mwi_expiry = DEFAULT_MWI_EXPIRY;
++ } else if (!strcasecmp(v->name, "tcpauthtimeout")) {
++ if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
++ &authtimeout, DEFAULT_AUTHTIMEOUT, 1, INT_MAX)) {
++ ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
++ v->name, v->value, v->lineno, config);
++ }
++ } else if (!strcasecmp(v->name, "tcpauthlimit")) {
++ if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
++ &authlimit, DEFAULT_AUTHLIMIT, 1, INT_MAX)) {
++ ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n",
++ v->name, v->value, v->lineno, config);
++ }
+ } else if (!strcasecmp(v->name, "sipdebug")) {
+ if (ast_true(v->value))
+ sipdebug |= sip_debug_config;
+diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
+index dd3f963..425f79d 100644
+--- a/channels/chan_skinny.c
++++ b/channels/chan_skinny.c
+@@ -100,6 +100,8 @@ enum skinny_codecs {
+ #define DEFAULT_SKINNY_PORT 2000
+ #define DEFAULT_SKINNY_BACKLOG 2
+ #define SKINNY_MAX_PACKET 1000
++#define DEFAULT_AUTH_TIMEOUT 30
++#define DEFAULT_AUTH_LIMIT 50
+
+ static struct {
+ unsigned int tos;
+@@ -111,6 +113,9 @@ static struct {
+ } qos = { 0, 0, 0, 0, 0, 0 };
+
+ static int keep_alive = 120;
++static int auth_timeout = DEFAULT_AUTH_TIMEOUT;
++static int auth_limit = DEFAULT_AUTH_LIMIT;
++static int unauth_sessions = 0;
+ static char global_vmexten[AST_MAX_EXTENSION]; /* Voicemail pilot number */
+ static char used_context[AST_MAX_EXTENSION]; /* placeholder to check if context are already used in regcontext */
+ static char regcontext[AST_MAX_CONTEXT]; /* Context for auto-extension */
+@@ -1307,6 +1312,7 @@ static struct ast_jb_conf global_jbconf;*/
+ struct skinnysession {
+ pthread_t t;
+ ast_mutex_t lock;
++ time_t start;
+ struct sockaddr_in sin;
+ int fd;
+ char inbuf[SKINNY_MAX_PACKET];
+@@ -4558,6 +4564,8 @@ static int handle_register_message(struct skinny_req *req, struct skinnysession
+
+ return 0;
+ }
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
++
+ ast_verb(3, "Device '%s' successfully registered\n", name);
+
+ d = s->device;
+@@ -6244,6 +6252,9 @@ static void destroy_session(struct skinnysession *s)
+ if (s->fd > -1)
+ close(s->fd);
+
++ if (!s->device)
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
++
+ ast_mutex_destroy(&s->lock);
+
+ ast_free(s);
+@@ -6259,13 +6270,30 @@ static int get_input(struct skinnysession *s)
+ {
+ int res;
+ int dlen = 0;
++ int timeout = keep_alive * 1100;
++ time_t now;
+ int *bufaddr;
+ struct pollfd fds[1];
+
++ if (!s->device) {
++ if(time(&now) == -1) {
++ ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++ return -1;
++ }
++
++ timeout = (auth_timeout - (now - s->start)) * 1000;
++ if (timeout < 0) {
++ /* we have timed out */
++ if (skinnydebug)
++ ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
++ return -1;
++ }
++ }
++
+ fds[0].fd = s->fd;
+ fds[0].events = POLLIN;
+ fds[0].revents = 0;
+- res = ast_poll(fds, 1, (keep_alive * 1100)); /* If nothing has happen, client is dead */
++ res = ast_poll(fds, 1, timeout); /* If nothing has happen, client is dead */
+ /* we add 10% to the keep_alive to deal */
+ /* with network delays, etc */
+ if (res < 0) {
+@@ -6274,8 +6302,13 @@ static int get_input(struct skinnysession *s)
+ return res;
+ }
+ } else if (res == 0) {
+- if (skinnydebug)
+- ast_verb(1, "Skinny Client was lost, unregistering\n");
++ if (skinnydebug) {
++ if (s->device) {
++ ast_verb(1, "Skinny Client was lost, unregistering\n");
++ } else {
++ ast_verb(1, "Skinny Client failed to authenticate in %d seconds\n", auth_timeout);
++ }
++ }
+ skinny_unregister(NULL, s);
+ return -1;
+ }
+@@ -6408,18 +6441,35 @@ static void *accept_thread(void *ignore)
+ ast_log(LOG_NOTICE, "Accept returned -1: %s\n", strerror(errno));
+ continue;
+ }
++
++ if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= auth_limit) {
++ close(as);
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
++ continue;
++ }
++
+ p = getprotobyname("tcp");
+ if(p) {
+ if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
+ ast_log(LOG_WARNING, "Failed to set Skinny tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
+ }
+ }
+- if (!(s = ast_calloc(1, sizeof(struct skinnysession))))
++ if (!(s = ast_calloc(1, sizeof(struct skinnysession)))) {
++ close(as);
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ continue;
++ }
+
+ memcpy(&s->sin, &sin, sizeof(sin));
+ ast_mutex_init(&s->lock);
+ s->fd = as;
++
++ if(time(&s->start) == -1) {
++ ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
++ destroy_session(s);
++ continue;
++ }
++
+ AST_LIST_LOCK(&sessions);
+ AST_LIST_INSERT_HEAD(&sessions, s, list);
+ AST_LIST_UNLOCK(&sessions);
+@@ -6573,6 +6623,26 @@ static struct ast_channel *skinny_request(const char *type, int format, void *da
+ } else if (!strcasecmp(v->name, "keepalive")) {
+ keep_alive = atoi(v->value);
+ continue;
++ } else if (!strcasecmp(v->name, "authtimeout")) {
++ int timeout = atoi(v->value);
++
++ if (timeout < 1) {
++ ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", v->value);
++ auth_timeout = DEFAULT_AUTH_TIMEOUT;
++ } else {
++ auth_timeout = timeout;
++ }
++ continue;
++ } else if (!strcasecmp(v->name, "authlimit")) {
++ int limit = atoi(v->value);
++
++ if (limit < 1) {
++ ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", v->value);
++ auth_limit = DEFAULT_AUTH_LIMIT;
++ } else {
++ auth_limit = limit;
++ }
++ continue;
+ } else if (!strcasecmp(v->name, "regcontext")) {
+ ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
+ stringp = newcontexts;
+diff --git a/configs/http.conf.sample b/configs/http.conf.sample
+index f15c9cf..6da4ca6 100644
+--- a/configs/http.conf.sample
++++ b/configs/http.conf.sample
+@@ -32,6 +32,11 @@ bindaddr=127.0.0.1
+ ;
+ ;prefix=asterisk
+ ;
++; sessionlimit specifies the maximum number of httpsessions that will be
++; allowed to exist at any given time. (default: 100)
++;
++;sessionlimit=100
++;
+ ; Whether Asterisk should serve static content from http-static
+ ; Default is no.
+ ;
+diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample
+index edc8500..1eafdb6 100644
+--- a/configs/sip.conf.sample
++++ b/configs/sip.conf.sample
+@@ -144,6 +144,16 @@ tcpbindaddr=0.0.0.0 ; IP address for TCP server to bind to (0.0.0.0
+ ; A list of valid SSL cipher strings can be found at:
+ ; http://www.openssl.org/docs/apps/ciphers.html#CIPHER_STRINGS
+
++;tcpauthtimeout = 30 ; tcpauthtimeout specifies the maximum number
++ ; of seconds a client has to authenticate. If
++ ; the client does not authenticate beofre this
++ ; timeout expires, the client will be
++ ; disconnected. (default: 30 seconds)
++
++;tcpauthlimit = 100 ; tcpauthlimit specifies the maximum number of
++ ; unauthenticated sessions that will be allowed
++ ; to connect at any given time. (default: 100)
++
+ srvlookup=yes ; Enable DNS SRV lookups on outbound calls
+ ; Note: Asterisk only uses the first host
+ ; in SRV records
+diff --git a/configs/skinny.conf.sample b/configs/skinny.conf.sample
+index 2c26e6b..1fdf4cb 100644
+--- a/configs/skinny.conf.sample
++++ b/configs/skinny.conf.sample
+@@ -9,6 +9,15 @@ dateformat=M-D-Y ; M,D,Y in any order (6 chars max)
+ ; Use M for month, D for day, Y for year, A for 12-hour time.
+ keepalive=120
+
++;authtimeout = 30 ; authtimeout specifies the maximum number of seconds a
++ ; client has to authenticate. If the client does not
++ ; authenticate beofre this timeout expires, the client
++ ; will be disconnected. (default: 30 seconds)
++
++;authlimit = 50 ; authlimit specifies the maximum number of
++ ; unauthenticated sessions that will be allowed to
++ ; connect at any given time. (default: 50)
++
+ ;vmexten=8500 ; Systemwide voicemailmain pilot number
+ ; It must be in the same context as the calling
+ ; device/line
+diff --git a/main/http.c b/main/http.c
+index ad68896..a8e17e3 100644
+--- a/main/http.c
++++ b/main/http.c
+@@ -53,12 +53,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+ #include "asterisk/astobj2.h"
+
+ #define MAX_PREFIX 80
++#define DEFAULT_SESSION_LIMIT 100
+
+ /* See http.h for more information about the SSL implementation */
+ #if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE))
+ #define DO_SSL /* comment in/out if you want to support ssl */
+ #endif
+
++static int session_limit = DEFAULT_SESSION_LIMIT;
++static int session_count = 0;
++
+ static struct ast_tls_config http_tls_cfg;
+
+ static void *httpd_helper_thread(void *arg);
+@@ -677,6 +681,10 @@ static void *httpd_helper_thread(void *data)
+ unsigned int static_content = 0;
+ struct ast_variable *tail = headers;
+
++ if (ast_atomic_fetchadd_int(&session_count, +1) >= session_limit) {
++ goto done;
++ }
++
+ if (!fgets(buf, sizeof(buf), ser->f)) {
+ goto done;
+ }
+@@ -787,6 +795,7 @@ static void *httpd_helper_thread(void *data)
+ }
+
+ done:
++ ast_atomic_fetchadd_int(&session_count, -1);
+ fclose(ser->f);
+ ao2_ref(ser, -1);
+ ser = NULL;
+@@ -936,6 +945,12 @@ static int __ast_http_load(int reload)
+ }
+ } else if (!strcasecmp(v->name, "redirect")) {
+ add_redirect(v->value);
++ } else if (!strcasecmp(v->name, "sessionlimit")) {
++ if (ast_parse_arg(v->value, PARSE_INT32|PARSE_DEFAULT|PARSE_IN_RANGE,
++ &session_limit, DEFAULT_SESSION_LIMIT, 1, INT_MAX)) {
++ ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of http.conf\n",
++ v->name, v->value, v->lineno);
++ }
+ } else {
+ ast_log(LOG_WARNING, "Ignoring unknown option '%s' in http.conf\n", v->name);
+ }
+diff --git a/main/manager.c b/main/manager.c
+index 400394c..da7f03a 100644
+--- a/main/manager.c
++++ b/main/manager.c
+@@ -2515,6 +2515,25 @@ static int action_originate(struct mansession *s, const struct message *m)
+ format = 0;
+ ast_parse_allow_disallow(NULL, &format, codecs, 1);
+ }
++ if (!ast_strlen_zero(app)) {
++ /* To run the System application (or anything else that goes to
++ * shell), you must have the additional System privilege */
++ if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
++ && (
++ strcasestr(app, "system") || /* System(rm -rf /)
++ TrySystem(rm -rf /) */
++ strcasestr(app, "exec") || /* Exec(System(rm -rf /))
++ TryExec(System(rm -rf /)) */
++ strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /)
++ EAGI(/bin/rm,-rf /) */
++ strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */
++ strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
++ )) {
++ astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
++ return 0;
++ }
++ }
++
+ if (ast_true(async)) {
+ struct fast_originate_helper *fast = ast_calloc(1, sizeof(*fast));
+ if (!fast) {
+@@ -2548,21 +2567,6 @@ static int action_originate(struct mansession *s, const struct message *m)
+ }
+ }
+ } else if (!ast_strlen_zero(app)) {
+- /* To run the System application (or anything else that goes to shell), you must have the additional System privilege */
+- if (!(s->session->writeperm & EVENT_FLAG_SYSTEM)
+- && (
+- strcasestr(app, "system") == 0 || /* System(rm -rf /)
+- TrySystem(rm -rf /) */
+- strcasestr(app, "exec") || /* Exec(System(rm -rf /))
+- TryExec(System(rm -rf /)) */
+- strcasestr(app, "agi") || /* AGI(/bin/rm,-rf /)
+- EAGI(/bin/rm,-rf /) */
+- strstr(appdata, "SHELL") || /* NoOp(${SHELL(rm -rf /)}) */
+- strstr(appdata, "EVAL") /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
+- )) {
+- astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
+- return 0;
+- }
+ res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
+ } else {
+ if (exten && context && pi)
+--
+1.7.4.1
+
Modified: asterisk/branches/squeeze/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/squeeze/debian/patches/series?rev=8880&op=diff
==============================================================================
--- asterisk/branches/squeeze/debian/patches/series (original)
+++ asterisk/branches/squeeze/debian/patches/series Thu Apr 21 20:43:31 2011
@@ -32,3 +32,4 @@
AST-2011-003
AST-2011-004
AST-2011-005
+AST-2011-006
More information about the Pkg-voip-commits
mailing list