mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-19 00:00:09 +00:00
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
This commit is contained in:
137
main/manager.c
137
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);
|
||||
/* 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 (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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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(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);
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user