[Asterisk-Dev] [patch] Function to check passcode
against vmpasscode
Gil Kloepfer
astr-dev at kloepfer.org
Wed Jan 18 12:37:02 MST 2006
Okay, here is an updated patch against trunk/8190
asterisk/apps/app_voicemail.c that adds passcode checking for an
already-known passcode to app VMAuthenticate.
I also rewrote much of VMAuthenticate to utilize the Asterisk
arg/option parsing library rather than doing its own parsing.
This makes it easier to add additional options later on if needed.
It works as follows: If you have a passcode in variable "passvar"
that you want to check against the passcode for mailbox 1234, you
would execute code as follows:
VMAuthenticate(1234,p(${passvar}))
GotoIf(${AUTH_STATUS}?good:bad)
The AUTH_STATUS variable is set to 1 for successful, 0 for failed.
I also updated the descriptive text for VMAuthenticate to include these
changes.
Feedback appreciated. Thanks!
---
Gil Kloepfer
astr-dev at kloepfer.org
-- Cut Here -- -- Cut Here -- -- Cut Here -- -- Cut Here -- -- Cut Here --
--- asterisk/apps/app_voicemail.c.ORIG 2006-01-17 16:04:49.000000000 -0600
+++ asterisk/apps/app_voicemail.c 2006-01-18 13:19:52.000000000 -0600
@@ -353,13 +353,21 @@
"Authenticate with Voicemail passwords";
static char *descrip_vmauthenticate =
-" VMAuthenticate([mailbox][@context][|options]): This application behaves the\n"
-"same way as the Authenticate application, but 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\n"
+" VMAuthenticate([mailbox][@context][|options]): This application allows\n"
+"authentication against the passcodes in the voicemail system.\n"
+" Unless the 'p' option is provided, it normally behaves the same way\n"
+"as the Authenticate application except that the passcodes are taken\n"
+"from the voicemail system. If the mailbox is specified, only that\n"
+"mailbox's passcode will be considered valid. If the mailbox is not\n"
+"specified, the channel variable AUTH_MAILBOX and AUTH_CONTEXT be set\n"
+"with the authenticated mailbox and context.\n\n"
+" When the 'p' option is provided, the passcode for the specified\n"
+"mailbox/context is simply checked against the passcode in the\n"
+"voicemail system and AUTH_STATUS is set to 1 for a matched passcode\n"
+"or 0 if the passcodes do not match or the specified mailbox does\n"
+"not exist.\n\n"
" Options:\n"
+" p(passcode) - Provide passcode to check against voicemail system\n"
" s - Skip playing the initial prompts.\n";
/* Leave a message */
@@ -5644,48 +5652,117 @@
return 0;
}
+enum {
+ OPT_VMA_PASSCHECK = (1 << 0),
+ OPT_VMA_SILENT = (1 << 1),
+} vma_option_flags;
+
+enum {
+ OPT_VMA_ARG_PASSCHECK = 0,
+ OPT_VMA_ARG_ARRAY_SIZE = 1,
+} vma_option_args;
+
+AST_APP_OPTIONS(vma_app_options, {
+ AST_APP_OPTION_ARG('p', OPT_VMA_PASSCHECK, OPT_VMA_ARG_PASSCHECK),
+ AST_APP_OPTION('s', OPT_VMA_SILENT),
+});
+
static int vmauthenticate(struct ast_channel *chan, void *data)
{
+
+ char *argv[2], *tmp;
+ int argc;
+ char *opts[OPT_VMA_ARG_ARRAY_SIZE];
+ struct ast_flags flags = { 0 };
+ char *vmpass;
struct localuser *u;
- char *s = data, *user=NULL, *context=NULL, mailbox[AST_MAX_EXTENSION] = "";
- struct ast_vm_user vmus;
- char *options = NULL;
- int silent = 0, skipuser = 0;
- int res = -1;
+ struct ast_vm_user vmus, *vmu = NULL;
+
+ int silent = 0;
+ int skipuser = 0;
+ char *passprovided = NULL;
+ char mailbox[AST_MAX_EXTENSION];
+ char *context = NULL;
LOCAL_USER_ADD(u);
-
- if (s) {
- s = ast_strdupa(s);
- if (!s) {
- ast_log(LOG_ERROR, "Out of memory\n");
- return -1;
+
+ /* Parse arguments and options */
+
+ mailbox[0] = '\0';
+
+ if (!ast_strlen_zero(data)) {
+ tmp = ast_strdupa(data);
+ argc = ast_app_separate_args(tmp, '|', argv, sizeof(argv) / sizeof(argv[0]));
+
+ /* parse optional mailbox at context */
+ if (argc >= 1 ) {
+ if (!ast_strlen_zero(argv[0])) {
+ /* Parse off context first so mailbox copy doesn't include context */
+ context = strchr(argv[0], '@');
+ if (context)
+ *context++ = '\0';
+
+ ast_copy_string(mailbox, argv[0], sizeof(mailbox));
+ }
}
- user = strsep(&s, "|");
- options = strsep(&s, "|");
- if (user) {
- s = user;
- user = strsep(&s, "@");
- context = strsep(&s, "");
- if (!ast_strlen_zero(user))
- skipuser++;
- ast_copy_string(mailbox, user, sizeof(mailbox));
+
+ if (!ast_strlen_zero(mailbox))
+ skipuser++;
+
+ /* parse optional args */
+ if (argc == 2) {
+ if (ast_app_parse_options(vma_app_options, &flags, opts, argv[1]))
+ goto error;
+
+ if (ast_test_flag(&flags, OPT_VMA_SILENT))
+ silent++;
+
+ if (ast_test_flag(&flags, OPT_VMA_PASSCHECK)) {
+ if (ast_strlen_zero(mailbox)) {
+ ast_log(LOG_WARNING, "Checking pre-provided password requires a mailbox\n");
+ goto error;
+ }
+ passprovided = opts[OPT_VMA_ARG_PASSCHECK];
+ if (passprovided == NULL || ast_strlen_zero(passprovided)) {
+ ast_log(LOG_WARNING, "Password check requested but no password provided\n");
+ goto error;
+ }
+ }
}
}
- if (options) {
- silent = (strchr(options, 's')) != NULL;
- }
-
- if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
- pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
- pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
- ast_play_and_wait(chan, "auth-thankyou");
- res = 0;
+ /*
+ * If we're providing a pre-provided password, use a VERY silent
+ * method of verifying the password. Otherwise, authenticate using
+ * vm_authenticate, which requests the info from the caller.
+ */
+
+ if (passprovided) {
+ pbx_builtin_setvar_helper(chan, "AUTH_STATUS", "0");
+ vmu = find_user(&vmus, context, mailbox);
+ if (vmu) {
+ vmpass = vmu->password;
+ if (*vmpass == '-')
+ vmpass++;
+
+ if (*vmpass != '\0' && strcmp(passprovided, vmpass) == 0)
+ pbx_builtin_setvar_helper(chan, "AUTH_STATUS", "1");
+ }
+ } else {
+ if (!vm_authenticate(chan, mailbox, sizeof(mailbox), &vmus, context, NULL, skipuser, 3, silent)) {
+ pbx_builtin_setvar_helper(chan, "AUTH_MAILBOX", mailbox);
+ pbx_builtin_setvar_helper(chan, "AUTH_CONTEXT", vmus.context);
+ ast_play_and_wait(chan, "auth-thankyou");
+ } else
+ goto error;
}
LOCAL_USER_REMOVE(u);
- return res;
+ return 0;
+
+error:
+ LOCAL_USER_REMOVE(u);
+ return -1;
}
static char show_voicemail_users_help[] =
-- Cut Here -- -- Cut Here -- -- Cut Here -- -- Cut Here -- -- Cut Here --
More information about the asterisk-dev
mailing list