mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-03 12:25:35 +00:00
Add VMAuthenticate application (bug #2775)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4155 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -214,6 +214,16 @@ static char *descrip_vm_box_exists =
|
||||
" MailboxExists(mailbox[@context]): Conditionally branches to priority n+101\n"
|
||||
"if the specified voice mailbox exists.\n";
|
||||
|
||||
static char *synopsis_vmauthenticate =
|
||||
"Authenticate off voicemail passwords";
|
||||
|
||||
static char *descrip_vmauthenticate =
|
||||
" VMAuthenticate([mailbox][@context]): Behaves identically to the Authenticate\n"
|
||||
"application, with the exception that the passwords are taken from\n"
|
||||
"voicemail.conf.\n"
|
||||
" If the mailbox is specified, only that mailbox's password will be considered\n"
|
||||
"valid. If the mailbox is not specified, the channel variable AUTH_MAILBOX will\n"
|
||||
"be set with the authenticated mailbox.\n";
|
||||
|
||||
/* Leave a message */
|
||||
static char *app = "VoiceMail";
|
||||
@@ -222,6 +232,7 @@ static char *app = "VoiceMail";
|
||||
static char *app2 = "VoiceMailMain";
|
||||
|
||||
static char *app3 = "MailboxExists";
|
||||
static char *app4 = "VMAuthenticate";
|
||||
|
||||
AST_MUTEX_DEFINE_STATIC(vmlock);
|
||||
struct ast_vm_user *users;
|
||||
@@ -3249,6 +3260,98 @@ static int vm_browse_messages_pt(struct ast_channel *chan, struct vm_state *vms,
|
||||
return cmd;
|
||||
}
|
||||
|
||||
static int vm_authenticate(struct ast_channel *chan, char *mailbox, int mailbox_size, struct ast_vm_user *res_vmu, const char *context, const char *prefix, int skipuser, int maxlogins)
|
||||
{
|
||||
int useadsi, valid=0, logretries=0;
|
||||
char password[AST_MAX_EXTENSION]="", *passptr;
|
||||
struct ast_vm_user vmus, *vmu = NULL;
|
||||
|
||||
/* If ADSI is supported, setup login screen */
|
||||
adsi_begin(chan, &useadsi);
|
||||
if (!skipuser && useadsi)
|
||||
adsi_login(chan);
|
||||
if (!skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
|
||||
ast_log(LOG_WARNING, "Couldn't stream login file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Authenticate them and get their mailbox/password */
|
||||
|
||||
while (!valid && (logretries < maxlogins)) {
|
||||
/* Prompt for, and read in the username */
|
||||
if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
|
||||
ast_log(LOG_WARNING, "Couldn't read username\n");
|
||||
return -1;
|
||||
}
|
||||
if (ast_strlen_zero(mailbox)) {
|
||||
if (chan->cid.cid_num) {
|
||||
strncpy(mailbox, chan->cid.cid_num, mailbox_size);
|
||||
} else {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (useadsi)
|
||||
adsi_password(chan);
|
||||
if (!skipuser)
|
||||
vmu = find_user(&vmus, context, mailbox);
|
||||
if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
|
||||
/* saved password is blank, so don't bother asking */
|
||||
password[0] = '\0';
|
||||
} else {
|
||||
if (ast_streamfile(chan, "vm-password", chan->language)) {
|
||||
ast_log(LOG_WARNING, "Unable to stream password file\n");
|
||||
return -1;
|
||||
}
|
||||
if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to read password\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (prefix) {
|
||||
char fullusername[80] = "";
|
||||
strncpy(fullusername, prefix, sizeof(fullusername) - 1);
|
||||
strncat(fullusername, mailbox, sizeof(fullusername) - 1 - strlen(fullusername));
|
||||
strncpy(mailbox, fullusername, mailbox_size - 1);
|
||||
}
|
||||
if (vmu) {
|
||||
passptr = vmu->password;
|
||||
if (passptr[0] == '-') passptr++;
|
||||
}
|
||||
if (vmu && !strcmp(passptr, password))
|
||||
valid++;
|
||||
else {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "<any>");
|
||||
if (prefix)
|
||||
strncpy(mailbox, "", mailbox_size -1);
|
||||
}
|
||||
logretries++;
|
||||
if (!valid) {
|
||||
if (skipuser || logretries >= maxlogins) {
|
||||
if (ast_streamfile(chan, "vm-incorrect", chan->language))
|
||||
break;
|
||||
} else {
|
||||
if (useadsi)
|
||||
adsi_login(chan);
|
||||
if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language))
|
||||
break;
|
||||
}
|
||||
ast_waitstream(chan, "");
|
||||
}
|
||||
}
|
||||
if (!valid && (logretries >= maxlogins)) {
|
||||
ast_stopstream(chan);
|
||||
ast_play_and_wait(chan, "vm-goodbye");
|
||||
return -1;
|
||||
}
|
||||
if (!skipuser) {
|
||||
memcpy(res_vmu, vmu, sizeof(struct ast_vm_user));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vm_execmain(struct ast_channel *chan, void *data)
|
||||
{
|
||||
/* XXX This is, admittedly, some pretty horrendus code. For some
|
||||
@@ -3260,20 +3363,16 @@ static int vm_execmain(struct ast_channel *chan, void *data)
|
||||
int cmd=0;
|
||||
struct localuser *u;
|
||||
char prefixstr[80] ="";
|
||||
char empty[80] = "";
|
||||
char ext_context[256]="";
|
||||
int box;
|
||||
int useadsi = 0;
|
||||
int skipuser = 0;
|
||||
char tmp[256], *ext;
|
||||
char fmtc[256] = "";
|
||||
char password[80];
|
||||
struct vm_state vms;
|
||||
int logretries = 0;
|
||||
struct ast_vm_user *vmu = NULL, vmus;
|
||||
char *context=NULL;
|
||||
int silentexit = 0;
|
||||
char *passptr;
|
||||
|
||||
LOCAL_USER_ADD(u);
|
||||
memset(&vms, 0, sizeof(vms));
|
||||
@@ -3316,88 +3415,19 @@ static int vm_execmain(struct ast_channel *chan, void *data)
|
||||
|
||||
}
|
||||
|
||||
res = vm_authenticate(chan, vms.username, sizeof(vms.username), &vmus, context, prefixstr, skipuser, maxlogins);
|
||||
|
||||
if (!res) {
|
||||
valid = 1;
|
||||
if (!skipuser) {
|
||||
vmu = &vmus;
|
||||
}
|
||||
} else {
|
||||
res = 0;
|
||||
}
|
||||
|
||||
/* If ADSI is supported, setup login screen */
|
||||
adsi_begin(chan, &useadsi);
|
||||
if (!skipuser && useadsi)
|
||||
adsi_login(chan);
|
||||
if (!skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
|
||||
ast_log(LOG_WARNING, "Couldn't stream login file\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Authenticate them and get their mailbox/password */
|
||||
|
||||
while (!valid && (logretries < maxlogins)) {
|
||||
/* Prompt for, and read in the username */
|
||||
if (!skipuser && ast_readstring(chan, vms.username, sizeof(vms.username) - 1, 2000, 10000, "#") < 0) {
|
||||
ast_log(LOG_WARNING, "Couldn't read username\n");
|
||||
goto out;
|
||||
}
|
||||
if (ast_strlen_zero(vms.username)) {
|
||||
if (chan->cid.cid_num) {
|
||||
strncpy(vms.username, chan->cid.cid_num, sizeof(vms.username) - 1);
|
||||
} else {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (useadsi)
|
||||
adsi_password(chan);
|
||||
if (!skipuser)
|
||||
vmu = find_user(&vmus, context, vms.username);
|
||||
if (vmu && (vmu->password[0] == '\0' || (vmu->password[0] == '-' && vmu->password[1] == '\0'))) {
|
||||
/* saved password is blank, so don't bother asking */
|
||||
password[0] = '\0';
|
||||
} else {
|
||||
if (ast_streamfile(chan, "vm-password", chan->language)) {
|
||||
ast_log(LOG_WARNING, "Unable to stream password file\n");
|
||||
goto out;
|
||||
}
|
||||
if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
|
||||
ast_log(LOG_WARNING, "Unable to read password\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (prefix) {
|
||||
char fullusername[80] = "";
|
||||
strncpy(fullusername, prefixstr, sizeof(fullusername) - 1);
|
||||
strncat(fullusername, vms.username, sizeof(fullusername) - 1);
|
||||
strncpy(vms.username, fullusername, sizeof(vms.username) - 1);
|
||||
}
|
||||
if (vmu) {
|
||||
passptr = vmu->password;
|
||||
if (passptr[0] == '-') passptr++;
|
||||
}
|
||||
if (vmu && !strcmp(passptr, password))
|
||||
valid++;
|
||||
else {
|
||||
if (option_verbose > 2)
|
||||
ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, vms.username, context ? context : "<any>");
|
||||
if (prefix)
|
||||
strncpy(vms.username, empty, sizeof(vms.username) -1);
|
||||
}
|
||||
logretries++;
|
||||
if (!valid) {
|
||||
if (skipuser || logretries >= maxlogins) {
|
||||
if (ast_streamfile(chan, "vm-incorrect", chan->language))
|
||||
break;
|
||||
} else {
|
||||
if (useadsi)
|
||||
adsi_login(chan);
|
||||
if (ast_streamfile(chan, "vm-incorrect-mailbox", chan->language))
|
||||
break;
|
||||
}
|
||||
ast_waitstream(chan, "");
|
||||
}
|
||||
}
|
||||
if (!valid && (logretries >= maxlogins)) {
|
||||
ast_stopstream(chan);
|
||||
res = ast_play_and_wait(chan, "vm-goodbye");
|
||||
if (res > 0)
|
||||
res = 0;
|
||||
}
|
||||
|
||||
if (valid) {
|
||||
/* Set language from config to override channel language */
|
||||
@@ -3861,6 +3891,33 @@ static int vm_box_exists(struct ast_channel *chan, void *data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vmauthenticate(struct ast_channel *chan, void *data) {
|
||||
struct localuser *u;
|
||||
char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION];
|
||||
struct ast_vm_user vmus;
|
||||
|
||||
if (s) {
|
||||
s = ast_strdupa(s);
|
||||
if (!s) {
|
||||
ast_log(LOG_ERROR, "Out of memory\n");
|
||||
return -1;
|
||||
}
|
||||
user = strsep(&s, "@");
|
||||
context = strsep(&s, "");
|
||||
}
|
||||
LOCAL_USER_ADD(u);
|
||||
|
||||
if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, 0, 3)) {
|
||||
pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
|
||||
pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return 0;
|
||||
} else {
|
||||
LOCAL_USER_REMOVE(u);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static char show_voicemail_users_help[] =
|
||||
"Usage: show voicemail users [for <context>]\n"
|
||||
" Lists all mailboxes currently set up\n";
|
||||
@@ -4371,6 +4428,7 @@ int unload_module(void)
|
||||
res = ast_unregister_application(app);
|
||||
res |= ast_unregister_application(app2);
|
||||
res |= ast_unregister_application(app3);
|
||||
res |= ast_unregister_application(app4);
|
||||
ast_cli_unregister(&show_voicemail_users_cli);
|
||||
ast_cli_unregister(&show_voicemail_zones_cli);
|
||||
return res;
|
||||
@@ -4382,6 +4440,7 @@ int load_module(void)
|
||||
res = ast_register_application(app, vm_exec, synopsis_vm, descrip_vm);
|
||||
res |= ast_register_application(app2, vm_execmain, synopsis_vmain, descrip_vmain);
|
||||
res |= ast_register_application(app3, vm_box_exists, synopsis_vm_box_exists, descrip_vm_box_exists);
|
||||
res |= ast_register_application(app4, vmauthenticate, synopsis_vmauthenticate, descrip_vmauthenticate);
|
||||
if (res)
|
||||
return(res);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user