Add an option that lets you only allow one connection at a time for each
authorRussell Bryant <russell@russellbryant.com>
Thu, 17 May 2007 17:12:23 +0000 (17:12 +0000)
committerRussell Bryant <russell@russellbryant.com>
Thu, 17 May 2007 17:12:23 +0000 (17:12 +0000)
manager user.  (issue #8664, reported and original patch by ssokol, patch
updated by bkruse, and further updated by me)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@64786 65c4cc65-6c06-0410-ace0-fbb531ad65f3

configs/manager.conf.sample
main/manager.c

index 11ba373..04305e0 100644 (file)
@@ -45,6 +45,10 @@ bindaddr = 0.0.0.0
 ;   sslcert=/tmp/asterisk.pem  ; path to the certificate.
 
 
+;
+;allowmultiplelogin = yes              ; IF set to no, rejects manager logins that are already in use.
+;                               ; The default is yes.
+;
 ;displayconnects = yes
 ;
 ; Add a Unix epoch timestamp to events (not action responses)
index b96eeba..1fc5b05 100644 (file)
@@ -111,6 +111,7 @@ struct eventqent {
 static AST_LIST_HEAD_STATIC(all_events, eventqent);
 
 static int displayconnects = 1;
+static int allowmultiplelogin;
 static int timestampevents;
 static int httptimeout = 60;
 static int manager_enabled = 0;
@@ -417,6 +418,21 @@ static char *complete_show_mancmd(const char *line, const char *word, int pos, i
        return ret;
 }
 
+static int check_manager_session_inuse(const char *name)
+{
+       struct mansession *session = NULL;
+
+       AST_LIST_LOCK(&sessions);
+       AST_LIST_TRAVERSE(&sessions, session, list) {
+               if (!strcasecmp(session->username, name)) 
+                       break;
+       }
+       AST_LIST_UNLOCK(&sessions);
+
+       return session ? 1 : 0;
+}
+
+
 /*!
  * lookup an entry in the list of registered users.
  * must be called with the list lock held.
@@ -2266,6 +2282,7 @@ static int process_message(struct mansession *s, const struct message *m)
        char action[80] = "";
        int ret = 0;
        struct manager_action *tmp;
+       const char *user = astman_get_header(m, "Username");
 
        ast_copy_string(action, astman_get_header(m, "Action"), sizeof(action));
        if (option_debug)
@@ -2282,6 +2299,16 @@ static int process_message(struct mansession *s, const struct message *m)
                ast_mutex_unlock(&s->__lock);
                return 0;
        }
+
+       if (!allowmultiplelogin && !s->authenticated && user &&
+               (!strcasecmp(action, "Login") || !strcasecmp(action, "Challenge"))) {
+               if (check_manager_session_inuse(user)) {
+                       sleep(1);
+                       astman_send_error(s, m, "Login Already In Use");
+                       return -1;
+               }
+       }
+
        ast_rwlock_rdlock(&actionlock); 
        for (tmp = first_action ; tmp; tmp = tmp->next) {
                if (strcasecmp(action, tmp->action))
@@ -3276,6 +3303,8 @@ int init_manager(void)
                                ast_log(LOG_WARNING, "Invalid address '%s' specified, using 0.0.0.0\n", val);
                                memset(&ami_desc.sin.sin_addr, 0, sizeof(ami_desc.sin.sin_addr));
                        }
+               } else if (!strcasecmp(var->name, "allowmultiplelogin")) { 
+                       allowmultiplelogin = ast_true(val);
                } else if (!strcasecmp(var->name, "displayconnects")) {
                        displayconnects = ast_true(val);
                } else if (!strcasecmp(var->name, "timestampevents")) {