aboutsummaryrefslogtreecommitdiffstats
path: root/apps/app_voicemail.c
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-11-03 15:06:44 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2004-11-03 15:06:44 +0000
commitad4e6b9eae4c9d6e3b2a86f5e0941236106d66cb (patch)
treef4b41f7b793a0154c5a8c787600eefbcf5da25ea /apps/app_voicemail.c
parent31cd1f4bdaf11b78b67f661448d6c708face98fa (diff)
Add VMAuthenticate application (bug #2775)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@4155 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_voicemail.c')
-rwxr-xr-xapps/app_voicemail.c225
1 files changed, 142 insertions, 83 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 0d4cc37f5..cdfc57ebf 100755
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -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,72 +3260,11 @@ static int vm_browse_messages_pt(struct ast_channel *chan, struct vm_state *vms,
return cmd;
}
-static int vm_execmain(struct ast_channel *chan, void *data)
+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)
{
- /* XXX This is, admittedly, some pretty horrendus code. For some
- reason it just seemed a lot easier to do with GOTO's. I feel
- like I'm back in my GWBASIC days. XXX */
- int res=-1;
- int valid = 0;
- int prefix = 0;
- 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));
- memset(&vmus, 0, sizeof(vmus));
- strncpy(fmtc, vmfmts, sizeof(fmtc) - 1);
- if (chan->_state != AST_STATE_UP)
- ast_answer(chan);
-
- if (data && !ast_strlen_zero(data)) {
- strncpy(tmp, data, sizeof(tmp) - 1);
- ext = tmp;
-
- switch (*ext) {
- case 's':
- /* We should skip the user's password */
- valid++;
- ext++;
- break;
- case 'p':
- /* We should prefix the mailbox with the supplied data */
- prefix++;
- ext++;
- break;
- }
-
- context = strchr(ext, '@');
- if (context) {
- *context = '\0';
- context++;
- }
-
- if (prefix)
- strncpy(prefixstr, ext, sizeof(prefixstr) - 1);
- else
- strncpy(vms.username, ext, sizeof(vms.username) - 1);
- if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
- skipuser++;
- else
- valid = 0;
-
- }
+ 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);
@@ -3322,49 +3272,48 @@ static int vm_execmain(struct ast_channel *chan, void *data)
adsi_login(chan);
if (!skipuser && ast_streamfile(chan, "vm-login", chan->language)) {
ast_log(LOG_WARNING, "Couldn't stream login file\n");
- goto out;
+ 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, vms.username, sizeof(vms.username) - 1, 2000, 10000, "#") < 0) {
+ if (!skipuser && ast_readstring(chan, mailbox, mailbox_size - 1, 2000, 10000, "#") < 0) {
ast_log(LOG_WARNING, "Couldn't read username\n");
- goto out;
+ return -1;
}
- if (ast_strlen_zero(vms.username)) {
+ if (ast_strlen_zero(mailbox)) {
if (chan->cid.cid_num) {
- strncpy(vms.username, chan->cid.cid_num, sizeof(vms.username) - 1);
+ strncpy(mailbox, chan->cid.cid_num, mailbox_size);
} else {
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Username not entered\n");
- res = 0;
- goto out;
+ return -1;
}
}
if (useadsi)
adsi_password(chan);
if (!skipuser)
- vmu = find_user(&vmus, context, vms.username);
+ 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");
- goto out;
+ return -1;
}
if (ast_readstring(chan, password, sizeof(password) - 1, 2000, 10000, "#") < 0) {
ast_log(LOG_WARNING, "Unable to read password\n");
- goto out;
+ return -1;
}
}
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);
+ 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;
@@ -3374,9 +3323,9 @@ static int vm_execmain(struct ast_channel *chan, void *data)
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>");
+ ast_verbose( VERBOSE_PREFIX_3 "Incorrect password '%s' for user '%s' (context = %s)\n", password, mailbox, context ? context : "<any>");
if (prefix)
- strncpy(vms.username, empty, sizeof(vms.username) -1);
+ strncpy(mailbox, "", mailbox_size -1);
}
logretries++;
if (!valid) {
@@ -3394,11 +3343,92 @@ static int vm_execmain(struct ast_channel *chan, void *data)
}
if (!valid && (logretries >= maxlogins)) {
ast_stopstream(chan);
- res = ast_play_and_wait(chan, "vm-goodbye");
- if (res > 0)
- res = 0;
+ 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
+ reason it just seemed a lot easier to do with GOTO's. I feel
+ like I'm back in my GWBASIC days. XXX */
+ int res=-1;
+ int valid = 0;
+ int prefix = 0;
+ int cmd=0;
+ struct localuser *u;
+ char prefixstr[80] ="";
+ char ext_context[256]="";
+ int box;
+ int useadsi = 0;
+ int skipuser = 0;
+ char tmp[256], *ext;
+ char fmtc[256] = "";
+ struct vm_state vms;
+ struct ast_vm_user *vmu = NULL, vmus;
+ char *context=NULL;
+ int silentexit = 0;
+
+ LOCAL_USER_ADD(u);
+ memset(&vms, 0, sizeof(vms));
+ memset(&vmus, 0, sizeof(vmus));
+ strncpy(fmtc, vmfmts, sizeof(fmtc) - 1);
+ if (chan->_state != AST_STATE_UP)
+ ast_answer(chan);
+
+ if (data && !ast_strlen_zero(data)) {
+ strncpy(tmp, data, sizeof(tmp) - 1);
+ ext = tmp;
+
+ switch (*ext) {
+ case 's':
+ /* We should skip the user's password */
+ valid++;
+ ext++;
+ break;
+ case 'p':
+ /* We should prefix the mailbox with the supplied data */
+ prefix++;
+ ext++;
+ break;
+ }
+
+ context = strchr(ext, '@');
+ if (context) {
+ *context = '\0';
+ context++;
+ }
+
+ if (prefix)
+ strncpy(prefixstr, ext, sizeof(prefixstr) - 1);
+ else
+ strncpy(vms.username, ext, sizeof(vms.username) - 1);
+ if (!ast_strlen_zero(vms.username) && (vmu = find_user(&vmus, context ,vms.username)))
+ skipuser++;
+ else
+ valid = 0;
+
}
+ 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 (valid) {
/* Set language from config to override channel language */
if (vmu->language && !ast_strlen_zero(vmu->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);