[Pkg-voip-commits] r8848 - in /asterisk/branches/lenny-security/debian: changelog patches/AST-2011-005 patches/manager_bugfix_reload patches/series
tzafrir at alioth.debian.org
tzafrir at alioth.debian.org
Wed Apr 6 20:27:03 UTC 2011
Author: tzafrir
Date: Wed Apr 6 20:27:02 2011
New Revision: 8848
URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=8848
Log:
* Patch AST-2011-005: Resource exhaustion in Asterisk Manager Interface
* Patches AST-2011-003, manager_manager_bugfix_reload - its pre-requirements.
Added:
asterisk/branches/lenny-security/debian/patches/AST-2011-005
asterisk/branches/lenny-security/debian/patches/manager_bugfix_reload
Modified:
asterisk/branches/lenny-security/debian/changelog
asterisk/branches/lenny-security/debian/patches/series
Modified: asterisk/branches/lenny-security/debian/changelog
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny-security/debian/changelog?rev=8848&op=diff
==============================================================================
--- asterisk/branches/lenny-security/debian/changelog (original)
+++ asterisk/branches/lenny-security/debian/changelog Wed Apr 6 20:27:02 2011
@@ -2,8 +2,9 @@
* AST-2011-002 (CVE-2011-1147): Multiple crash vulnerabilities in UDPTL code
(Closes: #614580).
- * AST-2011-003: Resource exhaustion in Asterisk Manager Interface
+ * Patch AST-2011-005: Resource exhaustion in Asterisk Manager Interface
(Closes: #618790).
+ * Patches AST-2011-003, manager_manager_bugfix_reload - its pre-requirements.
* My new @debian.org address
-- Tzafrir Cohen <tzafrir at debian.org> Thu, 17 Mar 2011 12:21:06 +0200
Added: asterisk/branches/lenny-security/debian/patches/AST-2011-005
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny-security/debian/patches/AST-2011-005?rev=8848&op=file
==============================================================================
--- asterisk/branches/lenny-security/debian/patches/AST-2011-005 (added)
+++ asterisk/branches/lenny-security/debian/patches/AST-2011-005 Wed Apr 6 20:27:02 2011
@@ -1,0 +1,247 @@
+From: Matthew Nicholson <mnicholson at digium.com>
+Date: Tue, 5 Apr 2011 14:10:34 +0000
+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=312761
+
+Keeping many open manager connections at the initial unauthenticated
+stage can cause Asterisk to exhaust available CPU and memory resources.
+
+The manager interface is disabled by default in upstream, but enabled
+by default (listening on localhost only) in the version in Debian 5.0 (Lenny)
+and 6.0 (Squeeze).
+
+See also http://downloads.asterisk.org/pub/security/AST-2011-005.html
+
+---
+ configs/manager.conf.sample | 11 +++++
+ main/manager.c | 87 +++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 95 insertions(+), 3 deletions(-)
+
+--- a/configs/manager.conf.sample
++++ b/configs/manager.conf.sample
+@@ -26,6 +26,17 @@ enabled = no
+ ;webenabled = yes
+ port = 5038
+
++; 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)
++
++;authtimeout = 30
++
++; authlimit specifies the maximum number of unauthenticated sessions that will
++; be allowed to connect at any given time.
++
++;authlimit = 50
++
+ ;httptimeout = 60
+ ; a) httptimeout sets the Max-Age of the http cookie
+ ; b) httptimeout is the amount of time the webserver waits
+--- a/main/manager.c
++++ b/main/manager.c
+@@ -106,6 +106,8 @@ static const int DEFAULT_DISPLAYCONNECTS
+ static const int DEFAULT_TIMESTAMPEVENTS = 0; /*!< Default setting for timestampevents */
+ static const int DEFAULT_HTTPTIMEOUT = 60; /*!< Default manager http timeout */
+ static const int DEFAULT_BROKENEVENTSACTION = 0; /*!< Default setting for brokeneventsaction */
++static const int DEFAULT_AUTHTIMEOUT = 30; /*!< Default setting for authtimeout */
++static const int DEFAULT_AUTHLIMIT = 50; /*!< Default setting for authlimit */
+
+
+ static int enabled;
+@@ -114,10 +116,13 @@ static int asock = -1;
+ static int displayconnects;
+ static int timestampevents;
+ static int httptimeout;
++static int authtimeout;
++static int authlimit;
+
+ static pthread_t t;
+ static int block_sockets;
+ static int num_sessions;
++static int unauth_sessions = 0;
+
+ /* Protected by the sessions list lock */
+ struct eventqent *master_eventq = NULL;
+@@ -193,6 +198,7 @@ struct mansession {
+ struct eventqent *eventq;
+ /* Timeout for ast_carefulwrite() */
+ int writetimeout;
++ time_t authstart;
+ int pending_event; /*!< Pending events indicator in case when waiting_thread is NULL */
+ AST_LIST_ENTRY(mansession) list;
+ int write_error:1;
+@@ -2290,6 +2296,7 @@ static int process_message(struct manses
+ return -1;
+ } else {
+ s->authenticated = 1;
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ if (option_verbose > 1) {
+ if (displayconnects) {
+ ast_verbose(VERBOSE_PREFIX_2 "%sManager '%s' logged on from %s\n",
+@@ -2336,6 +2343,8 @@ static int get_input(struct mansession *
+ int res;
+ int x;
+ struct pollfd fds[1];
++ int timeout = -1;
++ time_t now;
+ for (x = 1; x < s->inlen; x++) {
+ if ((s->inbuf[x] == '\n') && (s->inbuf[x-1] == '\r')) {
+ /* Copy output data up to and including \r\n */
+@@ -2354,7 +2363,22 @@ static int get_input(struct mansession *
+ }
+ fds[0].fd = s->fd;
+ fds[0].events = POLLIN;
++
+ do {
++ /* calculate a timeout if we are not authenticated */
++ if (!s->authenticated) {
++ if(time(&now) == -1) {
++ ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++ return -1;
++ }
++
++ timeout = (authtimeout - (now - s->authstart)) * 1000;
++ if (timeout < 0) {
++ /* we have timed out */
++ return 0;
++ }
++ }
++
+ ast_mutex_lock(&s->__lock);
+ if (s->pending_event) {
+ s->pending_event = 0;
+@@ -2364,7 +2388,7 @@ static int get_input(struct mansession *
+ s->waiting_thread = pthread_self();
+ ast_mutex_unlock(&s->__lock);
+
+- res = poll(fds, 1, -1);
++ res = poll(fds, 1, timeout);
+
+ ast_mutex_lock(&s->__lock);
+ s->waiting_thread = AST_PTHREADT_NULL;
+@@ -2382,6 +2406,9 @@ static int get_input(struct mansession *
+ if (res < 1)
+ return -1;
+ break;
++ } else {
++ /* timeout */
++ return 0;
+ }
+ } while(1);
+ s->inlen += res;
+@@ -2394,6 +2421,7 @@ static int do_message(struct mansession
+ struct message m = { 0 };
+ char header_buf[sizeof(s->inbuf)] = { '\0' };
+ int res;
++ time_t now;
+
+ for (;;) {
+ /* Check if any events are pending and do them if needed */
+@@ -2403,6 +2431,17 @@ static int do_message(struct mansession
+ }
+ res = get_input(s, header_buf);
+ if (res == 0) {
++ if (!s->authenticated) {
++ if(time(&now) == -1) {
++ ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++ return -1;
++ }
++
++ if (now - s->authstart > authtimeout) {
++ ast_log(LOG_EVENT, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->sin.sin_addr), authtimeout);
++ return -1;
++ }
++ }
+ continue;
+ } else if (res > 0) {
+ /* Strip trailing \r\n */
+@@ -2436,6 +2475,7 @@ static void *session_do(void *data)
+ }
+ ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", s->username, ast_inet_ntoa(s->sin.sin_addr));
+ } else {
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ if (option_verbose > 1) {
+ if (displayconnects)
+ ast_verbose(VERBOSE_PREFIX_2 "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(s->sin.sin_addr));
+@@ -2515,14 +2555,25 @@ 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) >= authlimit) {
++ close(as);
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
++ ast_log(LOG_WARNING, "manager connection rejected, too many unauthenticated sessions.\n");
++ 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 manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
+ }
+ }
+- if (!(s = ast_calloc(1, sizeof(*s))))
++ if (!(s = ast_calloc(1, sizeof(*s)))) {
++ close(as);
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ continue;
++ }
+
+ memcpy(&s->sin, &sin, sizeof(sin));
+ s->writetimeout = 100;
+@@ -2549,8 +2600,16 @@ static void *accept_thread(void *ignore)
+ s->eventq = s->eventq->next;
+ ast_atomic_fetchadd_int(&s->eventq->usecount, 1);
+ AST_LIST_UNLOCK(&sessions);
+- if (ast_pthread_create_background(&s->t, &attr, session_do, s))
++ if(time(&s->authstart) == -1) {
++ ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ destroy_session(s);
++ continue;
++ }
++ if (ast_pthread_create_background(&s->t, &attr, session_do, s)) {
++ ast_atomic_fetchadd_int(&unauth_sessions, -1);
++ destroy_session(s);
++ }
+ }
+ pthread_attr_destroy(&attr);
+ return NULL;
+@@ -3037,6 +3096,8 @@ int init_manager(void)
+ block_sockets = DEFAULT_BLOCKSOCKETS;
+ timestampevents = DEFAULT_TIMESTAMPEVENTS;
+ httptimeout = DEFAULT_HTTPTIMEOUT;
++ authtimeout = DEFAULT_AUTHTIMEOUT;
++ authlimit = DEFAULT_AUTHLIMIT;
+
+ cfg = ast_config_load("manager.conf");
+ if (!cfg) {
+@@ -3071,6 +3132,26 @@ int init_manager(void)
+ if ((val = ast_variable_retrieve(cfg, "general", "httptimeout")))
+ newhttptimeout = atoi(val);
+
++ if ((val = ast_variable_retrieve(cfg, "general", "authtimeout"))) {
++ int timeout = atoi(val);
++
++ if (timeout < 1) {
++ ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", val);
++ } else {
++ authtimeout = timeout;
++ }
++ }
++
++ if ((val = ast_variable_retrieve(cfg, "general", "authlimit"))) {
++ int limit = atoi(val);
++
++ if (limit < 1) {
++ ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", val);
++ } else {
++ authlimit = limit;
++ }
++ }
++
+ memset(&ba, 0, sizeof(ba));
+ ba.sin_family = AF_INET;
+ ba.sin_port = htons(portno);
Added: asterisk/branches/lenny-security/debian/patches/manager_bugfix_reload
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny-security/debian/patches/manager_bugfix_reload?rev=8848&op=file
==============================================================================
--- asterisk/branches/lenny-security/debian/patches/manager_bugfix_reload (added)
+++ asterisk/branches/lenny-security/debian/patches/manager_bugfix_reload Wed Apr 6 20:27:02 2011
@@ -1,0 +1,67 @@
+From: Brett Bryant <bbryant at digium.com>
+Date: Thu, 2 Sep 2010 20:25:03 +0000
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=284777
+Bug: https://issues.asterisk.org/view.php?id=17917
+Subject: Properly reset default manager.conf values on reload
+
+Fixes a bug in manager.c where the default configuration values weren't
+reset when the manager configuration was reloaded.
+
+This is a simple bugfix required for cleanly applying AST-2011-005
+
+---
+ main/manager.c | 28 +++++++++++++++++++++-------
+ 1 files changed, 21 insertions(+), 7 deletions(-)
+
+--- a/main/manager.c
++++ b/main/manager.c
+@@ -99,12 +99,21 @@ struct eventqent {
+ char eventdata[1];
+ };
+
++static const int DEFAULT_ENABLED = 0; /*!< Default setting for manager to be enabled */
++static const int DEFAULT_WEBENABLED = 0; /*!< Default setting for the web interface to be enabled */
++static const int DEFAULT_BLOCKSOCKETS = 0; /*!< Default setting for block-sockets */
++static const int DEFAULT_DISPLAYCONNECTS = 1; /*!< Default setting for displaying manager connections */
++static const int DEFAULT_TIMESTAMPEVENTS = 0; /*!< Default setting for timestampevents */
++static const int DEFAULT_HTTPTIMEOUT = 60; /*!< Default manager http timeout */
++static const int DEFAULT_BROKENEVENTSACTION = 0; /*!< Default setting for brokeneventsaction */
++
++
+ static int enabled;
+ static int portno = DEFAULT_MANAGER_PORT;
+ static int asock = -1;
+-static int displayconnects = 1;
++static int displayconnects;
+ static int timestampevents;
+-static int httptimeout = 60;
++static int httptimeout;
+
+ static pthread_t t;
+ static int block_sockets;
+@@ -2989,8 +2998,8 @@ int init_manager(void)
+ static struct sockaddr_in ba;
+ int x = 1;
+ int flags;
+- int webenabled = 0;
+- int newhttptimeout = 60;
++ int webenabled = DEFAULT_WEBENABLED;
++ int newhttptimeout = DEFAULT_HTTPTIMEOUT;
+ struct ast_manager_user *user = NULL;
+
+ if (!registered) {
+@@ -3022,8 +3031,13 @@ int init_manager(void)
+ /* Append placeholder event so master_eventq never runs dry */
+ append_event("Event: Placeholder\r\n\r\n", 0);
+ }
++
+ portno = DEFAULT_MANAGER_PORT;
+- displayconnects = 1;
++ displayconnects = DEFAULT_DISPLAYCONNECTS;
++ block_sockets = DEFAULT_BLOCKSOCKETS;
++ timestampevents = DEFAULT_TIMESTAMPEVENTS;
++ httptimeout = DEFAULT_HTTPTIMEOUT;
++
+ cfg = ast_config_load("manager.conf");
+ if (!cfg) {
+ ast_log(LOG_NOTICE, "Unable to open management configuration manager.conf. Call management disabled.\n");
Modified: asterisk/branches/lenny-security/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/lenny-security/debian/patches/series?rev=8848&op=diff
==============================================================================
--- asterisk/branches/lenny-security/debian/patches/series (original)
+++ asterisk/branches/lenny-security/debian/patches/series Wed Apr 6 20:27:02 2011
@@ -104,3 +104,5 @@
AST-2011-001
AST-2011-002
AST-2011-003
+manager_bugfix_reload
+AST-2011-005
More information about the Pkg-voip-commits
mailing list