[Pkg-voip-commits] r8847 - in /asterisk/branches/squeeze/debian: changelog patches/AST-2011-003 patches/AST-2011-005 patches/manager_bugfix_reload patches/series

tzafrir at alioth.debian.org tzafrir at alioth.debian.org
Wed Apr 6 18:12:52 UTC 2011


Author: tzafrir
Date: Wed Apr  6 18:12:50 2011
New Revision: 8847

URL: http://svn.debian.org/wsvn/pkg-voip/?sc=1&rev=8847
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/squeeze/debian/patches/AST-2011-005
    asterisk/branches/squeeze/debian/patches/manager_bugfix_reload
Modified:
    asterisk/branches/squeeze/debian/changelog
    asterisk/branches/squeeze/debian/patches/AST-2011-003
    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=8847&op=diff
==============================================================================
--- asterisk/branches/squeeze/debian/changelog (original)
+++ asterisk/branches/squeeze/debian/changelog Wed Apr  6 18:12:50 2011
@@ -1,10 +1,11 @@
 asterisk (1:1.6.2.9-2+squeeze2) stable-security; urgency=high
 
-  * 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-002 (CVE-2011-1147): Multiple crash vulnerabilities in
+    UDPTL code (Closes: #614580).
+  * Patch AST-2011-005: Resource exhaustion in Asterisk Manager Interface
     (Closes: #618790).
-  * AST-2011-004: Remote crash vulnerability in TCP/TLS server
+  * 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

Modified: asterisk/branches/squeeze/debian/patches/AST-2011-003
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/squeeze/debian/patches/AST-2011-003?rev=8847&op=diff
==============================================================================
--- asterisk/branches/squeeze/debian/patches/AST-2011-003 (original)
+++ asterisk/branches/squeeze/debian/patches/AST-2011-003 Wed Apr  6 18:12:50 2011
@@ -10,9 +10,12 @@
 
 See also http://downloads.asterisk.org/pub/security/AST-2011-003.html
 
+FIXME: Probably now that useful on its own, but still pre-requirement for
+AST_2011-005. Fix description.
+
 --- a/main/manager.c
 +++ b/main/manager.c
-@@ -220,6 +220,7 @@ struct mansession {
+@@ -228,6 +228,7 @@ struct mansession {
  	struct mansession_session *session;
  	FILE *f;
  	int fd;
@@ -20,7 +23,7 @@
  };
  
  #define NEW_EVENT(m)	(AST_LIST_NEXT(m->session->last_ev, eq_next))
-@@ -944,11 +945,15 @@ struct ast_variable *astman_get_variable
+@@ -952,11 +953,15 @@ struct ast_variable *astman_get_variable
   */
  static int send_string(struct mansession *s, char *string)
  {
@@ -40,7 +43,7 @@
  }
  
  /*!
-@@ -3232,7 +3237,7 @@ static void *session_do(void *data)
+@@ -3240,7 +3245,7 @@ static void *session_do(void *data)
  
  	astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION);	/* welcome prompt */
  	for (;;) {

Added: 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=8847&op=file
==============================================================================
--- asterisk/branches/squeeze/debian/patches/AST-2011-005 (added)
+++ asterisk/branches/squeeze/debian/patches/AST-2011-005 Wed Apr  6 18:12:50 2011
@@ -1,0 +1,231 @@
+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
+Bug: https://issues.asterisk.org/view.php?id=18996
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=312764
+
+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              |   76 +++++++++++++++++++++++++++++++++++++++++--
+ 2 files changed, 84 insertions(+), 3 deletions(-)
+
+diff --git a/configs/manager.conf.sample b/configs/manager.conf.sample
+index acb7da9..30dcd64 100644
+--- a/configs/manager.conf.sample
++++ b/configs/manager.conf.sample
+@@ -25,6 +25,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 
+diff --git a/main/manager.c b/main/manager.c
+index 2edf258..400394c 100644
+--- a/main/manager.c
++++ b/main/manager.c
+@@ -127,6 +127,8 @@ static const int DEFAULT_DISPLAYCONNECTS	= 1;	/*!< Default setting for displayin
+ 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 displayconnects;
+ static int allowmultiplelogin = 1;
+@@ -135,9 +137,12 @@ static int httptimeout;
+ static int broken_events_action;
+ static int manager_enabled = 0;
+ static int webmanager_enabled = 0;
++static int authtimeout;
++static int authlimit;
+ 
+ static int block_sockets;
+ static int num_sessions;
++static int unauth_sessions = 0;
+ 
+ static int manager_debug;	/*!< enable some debugging code in the manager */
+ 
+@@ -214,6 +219,7 @@ struct mansession_session {
+ 	int send_events;	/*!<  XXX what ? */
+ 	struct eventqent *last_ev;	/*!< last event processed. */
+ 	int writetimeout;	/*!< Timeout for ast_carefulwrite() */
++	time_t authstart;
+ 	int pending_event;         /*!< Pending events indicator in case when waiting_thread is NULL */
+ 	AST_LIST_HEAD_NOLOCK(mansession_datastores, ast_datastore) datastores; /*!< Data stores on the session */
+ 	AST_LIST_ENTRY(mansession_session) list;
+@@ -1792,6 +1798,7 @@ static int action_login(struct mansession *s, const struct message *m)
+ 		return -1;
+ 	}
+ 	s->session->authenticated = 1;
++	ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ 	if (manager_displayconnects(s->session))
+ 		ast_verb(2, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr));
+ 	ast_log(LOG_EVENT, "%sManager '%s' logged on from %s\n", (s->session->managerid ? "HTTP " : ""), s->session->username, ast_inet_ntoa(s->session->sin.sin_addr));
+@@ -3130,6 +3137,8 @@ static int get_input(struct mansession *s, char *output)
+ 	int res, x;
+ 	int maxlen = sizeof(s->session->inbuf) - 1;
+ 	char *src = s->session->inbuf;
++	int timeout = -1;
++	time_t now;
+ 
+ 	/*
+ 	 * Look for \r\n within the buffer. If found, copy to the output
+@@ -3157,6 +3166,20 @@ static int get_input(struct mansession *s, char *output)
+ 	}
+ 	res = 0;
+ 	while (res == 0) {
++		/* calculate a timeout if we are not authenticated */
++		if (!s->session->authenticated) {
++			if(time(&now) == -1) {
++				ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++				return -1;
++			}
++
++			timeout = (authtimeout - (now - s->session->authstart)) * 1000;
++			if (timeout < 0) {
++				/* we have timed out */
++				return 0;
++			}
++		}
++
+ 		/* XXX do we really need this locking ? */
+ 		ast_mutex_lock(&s->session->__lock);
+ 		if (s->session->pending_event) {
+@@ -3167,7 +3190,7 @@ static int get_input(struct mansession *s, char *output)
+ 		s->session->waiting_thread = pthread_self();
+ 		ast_mutex_unlock(&s->session->__lock);
+ 
+-		res = ast_wait_for_input(s->session->fd, -1);	/* return 0 on timeout ? */
++		res = ast_wait_for_input(s->session->fd, timeout);
+ 
+ 		ast_mutex_lock(&s->session->__lock);
+ 		s->session->waiting_thread = AST_PTHREADT_NULL;
+@@ -3200,6 +3223,7 @@ static int do_message(struct mansession *s)
+ 	struct message m = { 0 };
+ 	char header_buf[sizeof(s->session->inbuf)] = { '\0' };
+ 	int res;
++	time_t now;
+ 
+ 	for (;;) {
+ 		/* Check if any events are pending and do them if needed */
+@@ -3207,6 +3231,17 @@ static int do_message(struct mansession *s)
+ 			return -1;
+ 		res = get_input(s, header_buf);
+ 		if (res == 0) {
++			if (!s->session->authenticated) {
++				if(time(&now) == -1) {
++					ast_log(LOG_ERROR, "error executing time(): %s\n", strerror(errno));
++					return -1;
++				}
++
++				if (now - s->session->authstart > authtimeout) {
++					ast_log(LOG_EVENT, "Client from %s, failed to authenticate in %d seconds\n", ast_inet_ntoa(s->session->sin.sin_addr), authtimeout);
++					return -1;
++				}
++			}
+ 			continue;
+ 		} else if (res > 0) {
+ 			if (ast_strlen_zero(header_buf))
+@@ -3230,13 +3265,22 @@ static int do_message(struct mansession *s)
+ static void *session_do(void *data)
+ {
+ 	struct ast_tcptls_session_instance *ser = data;
+-	struct mansession_session *session = ast_calloc(1, sizeof(*session));
++	struct mansession_session *session = NULL;
+ 	struct mansession s = {.session = NULL, };
+ 	int flags;
+ 	int res;
+ 
+-	if (session == NULL)
++	if (ast_atomic_fetchadd_int(&unauth_sessions, +1) >= authlimit) {
++		fclose(ser->f);
++		ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ 		goto done;
++	}
++
++	if ((session = ast_calloc(1, sizeof(*session))) == NULL) {
++		fclose(ser->f);
++		ast_atomic_fetchadd_int(&unauth_sessions, -1);
++		goto done;
++	}
+ 
+ 	session->writetimeout = 100;
+ 	session->waiting_thread = AST_PTHREADT_NULL;
+@@ -3280,6 +3324,13 @@ static void *session_do(void *data)
+ 	ast_atomic_fetchadd_int(&num_sessions, 1);
+ 	AST_LIST_UNLOCK(&sessions);
+ 
++	if(time(&session->authstart) == -1) {
++		ast_log(LOG_ERROR, "error executing time(): %s; disconnecting client\n", strerror(errno));
++		ast_atomic_fetchadd_int(&unauth_sessions, -1);
++		destroy_session(session);
++		goto done;
++	}
++
+ 	astman_append(&s, "Asterisk Call Manager/%s\r\n", AMI_VERSION);	/* welcome prompt */
+ 	for (;;) {
+ 		if ((res = do_message(&s)) < 0 || s.write_error)
+@@ -3291,6 +3342,7 @@ static void *session_do(void *data)
+ 			ast_verb(2, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
+ 		ast_log(LOG_EVENT, "Manager '%s' logged off from %s\n", session->username, ast_inet_ntoa(session->sin.sin_addr));
+ 	} else {
++		ast_atomic_fetchadd_int(&unauth_sessions, -1);
+ 			if (displayconnects)
+ 			ast_verb(2, "Connect attempt from '%s' unable to authenticate\n", ast_inet_ntoa(session->sin.sin_addr));
+ 		ast_log(LOG_EVENT, "Failed attempt from %s\n", ast_inet_ntoa(session->sin.sin_addr));
+@@ -4186,6 +4238,8 @@ static int __init_manager(int reload)
+ 	block_sockets = DEFAULT_BLOCKSOCKETS;
+ 	timestampevents = DEFAULT_TIMESTAMPEVENTS;
+ 	httptimeout = DEFAULT_HTTPTIMEOUT;
++	authtimeout = DEFAULT_AUTHTIMEOUT;
++	authlimit = DEFAULT_AUTHLIMIT;
+ 
+ 	if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
+ 		ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid. Asterisk management interface (AMI) disabled.\n");
+@@ -4250,6 +4304,22 @@ static int __init_manager(int reload)
+ 			manager_debug = ast_true(val);
+ 		} else if (!strcasecmp(var->name, "httptimeout")) {
+ 			newhttptimeout = atoi(val);
++		} else if (!strcasecmp(var->name, "authtimeout")) {
++			int timeout = atoi(var->value);
++
++			if (timeout < 1) {
++				ast_log(LOG_WARNING, "Invalid authtimeout value '%s', using default value\n", var->value);
++			} else {
++				authtimeout = timeout;
++			}
++		} else if (!strcasecmp(var->name, "authlimit")) {
++			int limit = atoi(var->value);
++
++			if (limit < 1) {
++				ast_log(LOG_WARNING, "Invalid authlimit value '%s', using default value\n", var->value);
++			} else {
++				authlimit = limit;
++			}
+ 		} else {
+ 			ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
+ 				var->name, val);
+-- 
+1.7.4.1
+

Added: asterisk/branches/squeeze/debian/patches/manager_bugfix_reload
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/squeeze/debian/patches/manager_bugfix_reload?rev=8847&op=file
==============================================================================
--- asterisk/branches/squeeze/debian/patches/manager_bugfix_reload (added)
+++ asterisk/branches/squeeze/debian/patches/manager_bugfix_reload Wed Apr  6 18:12:50 2011
@@ -1,0 +1,76 @@
+From: Brett Bryant <bbryant at digium.com>
+Date: Thu, 2 Sep 2010 20:54:33 +0000
+Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=284778
+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 |   30 +++++++++++++++++++++---------
+ 1 files changed, 21 insertions(+), 9 deletions(-)
+
+--- a/main/manager.c
++++ b/main/manager.c
+@@ -119,11 +119,19 @@ struct eventqent {
+ 
+ static AST_LIST_HEAD_STATIC(all_events, eventqent);
+ 
+-static int displayconnects = 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 displayconnects;
+ static int allowmultiplelogin = 1;
+ static int timestampevents;
+-static int httptimeout = 60;
+-static int broken_events_action = 0;
++static int httptimeout;
++static int broken_events_action;
+ static int manager_enabled = 0;
+ static int webmanager_enabled = 0;
+ 
+@@ -4088,16 +4096,14 @@ static int __init_manager(int reload)
+ 	struct ast_config *ucfg = NULL, *cfg = NULL;
+ 	const char *val;
+ 	char *cat = NULL;
+-	int newhttptimeout = 60;
++	int newhttptimeout = DEFAULT_HTTPTIMEOUT;
+ 	int have_sslbindaddr = 0;
+ 	struct hostent *hp;
+ 	struct ast_hostent ahp;
+ 	struct ast_manager_user *user = NULL;
+ 	struct ast_variable *var;
+ 	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+-
+-	manager_enabled = 0;
+-
++	
+ 	if (!registered) {
+ 		/* Register default actions */
+ 		ast_manager_register2("Ping", 0, action_ping, "Keepalive command", mandescr_ping);
+@@ -4142,8 +4148,14 @@ static int __init_manager(int reload)
+ 	if ((cfg = ast_config_load2("manager.conf", "manager", config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
+ 		return 0;
+ 
+-	displayconnects = 1;
+-	broken_events_action = 0;
++	manager_enabled = DEFAULT_ENABLED;
++	webmanager_enabled = DEFAULT_WEBENABLED;
++	displayconnects = DEFAULT_DISPLAYCONNECTS;
++	broken_events_action = DEFAULT_BROKENEVENTSACTION;
++	block_sockets = DEFAULT_BLOCKSOCKETS;
++	timestampevents = DEFAULT_TIMESTAMPEVENTS;
++	httptimeout = DEFAULT_HTTPTIMEOUT;
++
+ 	if (!cfg || cfg == CONFIG_STATUS_FILEINVALID) {
+ 		ast_log(LOG_NOTICE, "Unable to open AMI configuration manager.conf, or configuration is invalid. Asterisk management interface (AMI) disabled.\n");
+ 		return 0;

Modified: asterisk/branches/squeeze/debian/patches/series
URL: http://svn.debian.org/wsvn/pkg-voip/asterisk/branches/squeeze/debian/patches/series?rev=8847&op=diff
==============================================================================
--- asterisk/branches/squeeze/debian/patches/series (original)
+++ asterisk/branches/squeeze/debian/patches/series Wed Apr  6 18:12:50 2011
@@ -28,5 +28,7 @@
 
 AST-2011-001
 AST-2011-002
+manager_bugfix_reload
 AST-2011-003
 AST-2011-004
+AST-2011-005




More information about the Pkg-voip-commits mailing list