Index: apps/app_voicemail.c =================================================================== --- apps/app_voicemail.c (revision 104026) +++ apps/app_voicemail.c (working copy) @@ -196,6 +196,7 @@ #define MAXMSG 100 #define MAXMSGLIMIT 9999 +#define MINPASSWORD 0 #define BASELINELEN 72 #define BASEMAXINLINE 256 @@ -576,6 +577,7 @@ static int maxgreet; static int skipms; static int maxlogins; +static int minpassword; /*! Poll mailboxes for changes since there is something external to * app_voicemail that may change them. */ @@ -623,6 +625,7 @@ /* custom password sounds */ static char vm_password[80] = "vm-password"; static char vm_newpassword[80] = "vm-newpassword"; +static char vm_invalid_password[80] = "vm-invalid-password"; static char vm_passchanged[80] = "vm-passchanged"; static char vm_reenterpassword[80] = "vm-reenterpassword"; static char vm_mismatch[80] = "vm-mismatch"; @@ -782,6 +785,15 @@ } } +/* Check that password meets minimum requirements */ +static int check_password(char *password) +{ + /* check minimum length */ + if (strlen(password) < minpassword) + return 1; + return 0; +} + static int change_password_realtime(struct ast_vm_user *vmu, const char *password) { int res; @@ -6458,19 +6470,25 @@ cmd = ast_readstring(chan, newpassword + strlen(newpassword), sizeof(newpassword) - 1, 2000, 10000, "#"); if (cmd < 0 || cmd == 't' || cmd == '#') return cmd; - newpassword2[1] = '\0'; - newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); - if (cmd == '#') - newpassword2[0] = '\0'; - if (cmd < 0 || cmd == 't' || cmd == '#') - return cmd; - cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); - if (cmd < 0 || cmd == 't' || cmd == '#') - return cmd; - if (!strcmp(newpassword, newpassword2)) - break; - ast_log(LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); - cmd = ast_play_and_wait(chan, vm_mismatch); + cmd = check_password(newpassword); /* perform password validation */ + if (cmd != 0) { + ast_log(LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); + cmd = ast_play_and_wait(chan, vm_invalid_password); + } else { + newpassword2[1] = '\0'; + newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); + if (cmd == '#') + newpassword2[0] = '\0'; + if (cmd < 0 || cmd == 't' || cmd == '#') + return cmd; + cmd = ast_readstring(chan, newpassword2 + strlen(newpassword2), sizeof(newpassword2) - 1, 2000, 10000, "#"); + if (cmd < 0 || cmd == 't' || cmd == '#') + return cmd; + if (!strcmp(newpassword, newpassword2)) + break; + ast_log(LOG_NOTICE, "Password mismatch for user %s (%s != %s)\n", vms->username, newpassword, newpassword2); + cmd = ast_play_and_wait(chan, vm_mismatch); + } if (++tries == 3) return -1; } @@ -6591,6 +6609,13 @@ break; } } + + cmd = check_password(newpassword); /* perform password validation */ + if (cmd != 0) { + ast_log(LOG_NOTICE, "Invalid password for user %s (%s)\n", vms->username, newpassword); + cmd = ast_play_and_wait(chan, vm_invalid_password); + break; + } newpassword2[1] = '\0'; newpassword2[0] = cmd = ast_play_and_wait(chan, vm_reenterpassword); if (cmd == '#') @@ -8498,6 +8523,15 @@ } } + minpassword = MINPASSWORD; + if ((s = ast_variable_retrieve(cfg, "general", "minpassword"))) { + if (sscanf(s, "%d", &x) == 1) { + minpassword = x; + } else { + ast_log(LOG_WARNING, "Invalid minimum password length. Default to %d\n", minpassword); + } + } + /* Force new user to record name ? */ if (!(val = ast_variable_retrieve(cfg, "general", "forcename"))) val = "no"; @@ -8615,6 +8649,8 @@ ast_copy_string(vm_password, val, sizeof(vm_password)); if ((val = ast_variable_retrieve(cfg, "general", "vm-newpassword"))) ast_copy_string(vm_newpassword, val, sizeof(vm_newpassword)); + if ((val = ast_variable_retrieve(cfg, "general", "vm-invalid-password"))) + ast_copy_string(vm_invalid_password, val, sizeof(vm_invalid_password)); if ((val = ast_variable_retrieve(cfg, "general", "vm-passchanged"))) ast_copy_string(vm_passchanged, val, sizeof(vm_passchanged)); if ((val = ast_variable_retrieve(cfg, "general", "vm-reenterpassword"))) Index: configs/voicemail.conf.sample =================================================================== --- configs/voicemail.conf.sample (revision 104026) +++ configs/voicemail.conf.sample (working copy) @@ -241,6 +241,8 @@ ; hidefromdir=yes ; Hide this mailbox from the directory produced by app_directory ; The default is "no". ; tempgreetwarn=yes ; Remind the user that their temporary greeting is set +; minpassword=0 ; Enforce minimum password lengths. + ; The default minimum is 0, which disables checking. ; vm-password=custom_sound ; Customize which sound file is used instead of the default ; prompt that says: "password"