From 8e63fb21da872dd77b34aab54b0568e9d953267b Mon Sep 17 00:00:00 2001 From: Luigi Rizzo Date: Wed, 18 Oct 2006 12:38:24 +0000 Subject: another batch of simplifications to authenticate() (they are committed a bit at a time so it is easier to revert them in case we find a bug at a later time). git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@45529 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/manager.c | 135 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 65 deletions(-) diff --git a/main/manager.c b/main/manager.c index 45b816b80..d43f36b94 100644 --- a/main/manager.c +++ b/main/manager.c @@ -852,22 +852,23 @@ static int set_eventmask(struct mansession *s, char *eventmask) static int authenticate(struct mansession *s, struct message *m) { char *user = astman_get_header(m, "Username"); - char *pass = astman_get_header(m, "Secret"); - char *authtype = astman_get_header(m, "AuthType"); - char *key = astman_get_header(m, "Key"); - char *events = astman_get_header(m, "Events"); - char *cat = NULL; - struct ast_config *cfg = ast_config_load("manager.conf"); - int ret = -1; /* default: error return */ - struct ast_variable *v; + int error = -1; struct ast_ha *ha = NULL; char *password = NULL; + int readperm = 0, writeperm = 0; + if (ast_strlen_zero(user)) /* missing username */ + return -1; + + { /* - * XXX there is no need to scan the config file again here, + * XXX there should be no need to scan the config file again here, * suffices to call ast_get_manager_by_name_locked() to fetch * the user's entry. */ + struct ast_config *cfg = ast_config_load("manager.conf"); + char *cat = NULL; + struct ast_variable *v; if (!cfg) return -1; @@ -879,68 +880,72 @@ static int authenticate(struct mansession *s, struct message *m) if (!cat) { ast_log(LOG_NOTICE, "%s tried to authenticate with nonexistent user '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); ast_config_destroy(cfg); - return ret; + return -1; } - /* collect parameters for the user's entry */ - for (v = ast_variable_browse(cfg, cat); v; v = v->next) { - if (!strcasecmp(v->name, "secret")) { - password = v->value; - } else if (!strcasecmp(v->name, "permit") || - !strcasecmp(v->name, "deny")) { - ha = ast_append_ha(v->name, v->value, ha); - } else if (!strcasecmp(v->name, "writetimeout")) { - int val = atoi(v->value); - - if (val < 100) - ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno); - else - s->writetimeout = val; - } - + /* collect parameters for the user's entry */ + for (v = ast_variable_browse(cfg, cat); v; v = v->next) { + if (!strcasecmp(v->name, "secret")) + password = ast_strdupa(v->value); + else if (!strcasecmp(v->name, "read")) + readperm = get_perm(v->value); + else if (!strcasecmp(v->name, "write")) + writeperm = get_perm(v->value); + else if (!strcasecmp(v->name, "permit") || + !strcasecmp(v->name, "deny")) { + ha = ast_append_ha(v->name, v->value, ha); + } else if (!strcasecmp(v->name, "writetimeout")) { + int val = atoi(v->value); + + if (val < 100) + ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno); + else + s->writetimeout = val; } - if (ha) { - if (!ast_apply_ha(ha, &(s->sin))) { - ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); - ast_free_ha(ha); - goto error; - } - ast_free_ha(ha); + } + ast_config_destroy(cfg); + } + + if (ha) { + int good = ast_apply_ha(ha, &(s->sin)); + ast_free_ha(ha); + if (!good) { + ast_log(LOG_NOTICE, "%s failed to pass IP ACL as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); + return -1; } - if (!strcasecmp(authtype, "MD5")) { - if (!ast_strlen_zero(key) && s->challenge) { - int x; - int len = 0; - char md5key[256] = ""; - struct MD5Context md5; - unsigned char digest[16]; - MD5Init(&md5); - MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge)); - MD5Update(&md5, (unsigned char *) password, strlen(password)); - MD5Final(digest, &md5); - for (x=0; x<16; x++) - len += sprintf(md5key + len, "%2.2x", digest[x]); - if (!strcmp(md5key, key)) - goto ok; - } - } else if (password) { - if (!strcmp(password, pass)) - goto ok; + } + if (!strcasecmp(astman_get_header(m, "AuthType"), "MD5")) { + char *key = astman_get_header(m, "Key"); + if (!ast_strlen_zero(key) && !ast_strlen_zero(s->challenge)) { + int x; + int len = 0; + char md5key[256] = ""; + struct MD5Context md5; + unsigned char digest[16]; + + MD5Init(&md5); + MD5Update(&md5, (unsigned char *) s->challenge, strlen(s->challenge)); + MD5Update(&md5, (unsigned char *) password, strlen(password)); + MD5Final(digest, &md5); + for (x=0; x<16; x++) + len += sprintf(md5key + len, "%2.2x", digest[x]); + if (!strcmp(md5key, key)) + error = 0; } + } else if (password) { + char *pass = astman_get_header(m, "Secret"); + if (!strcmp(password, pass)) + error = 0; + } + if (error) { ast_log(LOG_NOTICE, "%s failed to authenticate as '%s'\n", ast_inet_ntoa(s->sin.sin_addr), user); - goto error; - -ok: - ast_copy_string(s->username, cat, sizeof(s->username)); - s->readperm = get_perm(ast_variable_retrieve(cfg, cat, "read")); - s->writeperm = get_perm(ast_variable_retrieve(cfg, cat, "write")); - if (events) - set_eventmask(s, events); - ret = 0; - -error: - ast_config_destroy(cfg); - return ret; + return -1; + } + ast_copy_string(s->username, user, sizeof(s->username)); + s->readperm = readperm; + s->writeperm = writeperm; + set_eventmask(s, astman_get_header(m, "Events")); + return 0; } /*! \brief Manager PING */ -- cgit v1.2.3