[asterisk-commits] lmadsen: tag 1.6.1.25 r312795 - in /tags/1.6.1.25: configs/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 5 09:22:34 CDT 2011


Author: lmadsen
Date: Tue Apr  5 09:22:28 2011
New Revision: 312795

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=312795
Log:
AST-2011-005
(issue #18996)

Modified:
    tags/1.6.1.25/configs/manager.conf.sample
    tags/1.6.1.25/main/manager.c

Modified: tags/1.6.1.25/configs/manager.conf.sample
URL: http://svnview.digium.com/svn/asterisk/tags/1.6.1.25/configs/manager.conf.sample?view=diff&rev=312795&r1=312794&r2=312795
==============================================================================
--- tags/1.6.1.25/configs/manager.conf.sample (original)
+++ tags/1.6.1.25/configs/manager.conf.sample Tue Apr  5 09:22:28 2011
@@ -24,6 +24,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

Modified: tags/1.6.1.25/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/tags/1.6.1.25/main/manager.c?view=diff&rev=312795&r1=312794&r2=312795
==============================================================================
--- tags/1.6.1.25/main/manager.c (original)
+++ tags/1.6.1.25/main/manager.c Tue Apr  5 09:22:28 2011
@@ -119,6 +119,9 @@
 
 static AST_LIST_HEAD_STATIC(all_events, eventqent);
 
+#define DEFAULT_AUTHTIMEOUT 30
+#define DEFAULT_AUTHLIMIT 50
+
 static int displayconnects = 1;
 static int allowmultiplelogin = 1;
 static int timestampevents;
@@ -126,9 +129,12 @@
 static int broken_events_action = 0;
 static int manager_enabled = 0;
 static int webmanager_enabled = 0;
+static int authtimeout = DEFAULT_AUTHTIMEOUT;
+static int authlimit = DEFAULT_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 */
 
@@ -206,6 +212,7 @@
 	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;
@@ -1754,6 +1761,7 @@
 		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));
@@ -3071,6 +3079,8 @@
 	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
@@ -3098,6 +3108,20 @@
 	}
 	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) {
@@ -3108,7 +3132,7 @@
 		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;
@@ -3141,6 +3165,7 @@
 	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 */
@@ -3148,6 +3173,17 @@
 			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))
@@ -3171,13 +3207,22 @@
 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;
@@ -3207,6 +3252,13 @@
 	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)
@@ -3218,6 +3270,7 @@
 			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));
@@ -4184,6 +4237,24 @@
 			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);
+				authtimeout = DEFAULT_AUTHTIMEOUT;
+			} 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);
+				authlimit = DEFAULT_AUTHLIMIT;
+			} else {
+				authlimit = limit;
+			}
 		} else {
 			ast_log(LOG_NOTICE, "Invalid keyword <%s> = <%s> in manager.conf [general]\n",
 				var->name, val);




More information about the asterisk-commits mailing list