In case anybody is interested, here's a patch to store voicemail passwords as an md5sum in the astdb. Change the first character of the password field in voicemail.conf to a '!' in order to use.
-Tilghman
Index: apps/app_voicemail.c =================================================================== RCS file: /usr/cvsroot/asterisk/apps/app_voicemail.c,v retrieving revision 1.79 diff -c -r1.79 app_voicemail.c *** apps/app_voicemail.c 6 Mar 2003 17:17:38 -0000 1.79 --- apps/app_voicemail.c 17 Mar 2003 22:26:20 -0000 *************** *** 23,28 **** --- 23,29 ---- #include <asterisk/adsi.h> #include <asterisk/app.h> #include <asterisk/manager.h> + #include <asterisk/astdb.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> *************** *** 32,37 **** --- 33,39 ---- #include <sys/time.h> #include <sys/stat.h> #include <time.h> + #include <openssl/md5.h> #include <pthread.h> #include "../asterisk.h" *************** *** 125,201 **** static int vm_change_password(char *username, char *password, char *newpassword) { ! /* There's probably a better way of doing this. */ ! /* That's why I've put the password change in a separate function. */ ! FILE *configin; ! FILE *configout; ! char inbuf[256]; ! char orig[256]; ! char tmpin[AST_CONFIG_MAX_PATH]; ! char tmpout[AST_CONFIG_MAX_PATH]; ! char *user, *pass, *rest, *trim; snprintf((char *)tmpin, sizeof(tmpin)-1, "%s/voicemail.conf",(char *)ast_config_AST_CONFIG_DIR); snprintf((char *)tmpout, sizeof(tmpout)-1, "%s/voicemail.conf.new",(char *)ast_config_AST_CONFIG_DIR); ! configin = fopen((char *)tmpin,"r"); ! configout = fopen((char *)tmpout,"w+"); ! while (!feof(configin)) { ! /* Read in the line */ ! fgets(inbuf, sizeof(inbuf), configin); ! if (!feof(configin)) { ! /* Make a backup of it */ ! memcpy(orig, inbuf, sizeof(orig)); ! /* Strip trailing \n and comment */ ! inbuf[strlen(inbuf) - 1] = '\0'; ! user = strchr(inbuf, ';'); ! if (user) ! *user = '\0'; ! user=inbuf; ! while(*user < 33) ! user++; ! pass = strchr(user, '='); ! if (pass > user) { ! trim = pass - 1; ! while(*trim && *trim < 33) { ! *trim = '\0'; ! trim--; ! } } ! if (pass) { ! *pass = '\0'; pass++; ! if (*pass == '>') ! pass++; ! while(*pass && *pass < 33) ! pass++; } ! if (pass) { ! rest = strchr(pass,','); ! if (rest) { ! *rest = '\0'; ! rest++; ! } ! } else ! rest = NULL; ! if (user && pass && *user && *pass && !strcmp(user, username) && !strcmp(pass, password)) { ! /* This is the line */ ! if (rest) { ! fprintf(configout, "%s => %s,%s\n", username,newpassword,rest); ! } else { ! fprintf(configout, "%s => %s\n", username,newpassword); ! } } else { ! /* Put it back like it was */ ! fprintf(configout, orig); } } ! } ! fclose(configin); ! fclose(configout); ! unlink((char *)tmpin); ! rename((char *)tmpout,(char *)tmpin); return(1); } --- 127,220 ---- static int vm_change_password(char *username, char *password, char *newpassword) { ! /* There's probably a better way of doing this. */ ! /* That's why I've put the password change in a separate function. */ ! FILE *configin; ! FILE *configout; ! char inbuf[256]; ! char orig[256]; ! char tmpin[AST_CONFIG_MAX_PATH]; ! char tmpout[AST_CONFIG_MAX_PATH]; ! char *user, *pass, *rest, *trim; snprintf((char *)tmpin, sizeof(tmpin)-1, "%s/voicemail.conf",(char *)ast_config_AST_CONFIG_DIR); snprintf((char *)tmpout, sizeof(tmpout)-1, "%s/voicemail.conf.new",(char *)ast_config_AST_CONFIG_DIR); ! configin = fopen((char *)tmpin,"r"); ! configout = fopen((char *)tmpout,"w+"); ! while (!feof(configin)) { ! /* Read in the line */ ! fgets(inbuf, sizeof(inbuf), configin); ! if (!feof(configin)) { ! /* Make a backup of it */ ! memcpy(orig, inbuf, sizeof(orig)); ! /* Strip trailing \n and comment */ ! inbuf[strlen(inbuf) - 1] = '\0'; ! user = strchr(inbuf, ';'); ! if (user) ! *user = '\0'; ! user=inbuf; ! /* Leading spaces and/or control characters */ ! while(*user < 33) ! user++; ! pass = strchr(user, '='); ! if (pass > user) { ! trim = pass - 1; ! while(*trim && *trim < 33) { ! *trim = '\0'; ! trim--; } ! } ! if (pass) { ! *pass = '\0'; ! pass++; ! if (*pass == '>') pass++; ! while(*pass && *pass < 33) ! pass++; ! } ! if (pass) { ! rest = strchr(pass,','); ! if (rest) { ! *rest = '\0'; ! rest++; } ! } else ! rest = NULL; ! if (user && pass && *user && *pass && !strcmp(user, username) && !strcmp(pass, password)) { ! /* This is the line */ ! if (rest) { ! fprintf(configout, "%s => %s,%s\n", username,newpassword,rest); } else { ! fprintf(configout, "%s => %s\n", username,newpassword); } + } else if (user && pass && *user && *pass && !strcmp(user, username) && !strcmp(pass, "!")) { + /* We want MD5 passwords */ + char passkey[80] = "password/"; + unsigned char passval[17]; + /* Can't store raw MD5, as it could have a valid 00 in the middle */ + char passval_hex[33]; + int i; + + fprintf(configout, orig); + + strncpy(passkey + strnlen(passkey,80), user, 80 - strnlen(passkey,80)); + MD5(newpassword,strlen(newpassword),passval); + for (i=0;i<16;i++) + sprintf(passval_hex + i * 2, "%02x", (int)passval[i]); + passval_hex[32] = '\0'; + ast_db_put("vm",passkey,passval_hex); + } else { + /* Put it back like it was */ + fprintf(configout, orig); } ! } ! } ! fclose(configin); ! fclose(configout); ! unlink((char *)tmpin); ! rename((char *)tmpout,(char *)tmpin); return(1); } *************** *** 1815,1821 **** copy = strdup(copy); stringp=copy; strsep(&stringp, ","); ! if (!strcmp(password,copy)) valid++; else { if (option_verbose > 2) --- 1834,1864 ---- copy = strdup(copy); stringp=copy; strsep(&stringp, ","); ! /* Is the password no longer stored in voicemail.conf? */ ! if (!strncmp("!",copy,1)) { ! char passkey[80] = "password/"; ! unsigned char passhash[33]; ! ! /* password/<exten> */ ! strncpy(passkey + strnlen(passkey,80),username,80 - strnlen(passkey,80)); ! if (!ast_db_get("vm",passkey,passhash,33)) { ! unsigned char checkhash[17]; ! char checkhash_hex[33]; ! int i; ! ! MD5(password,strlen(password),checkhash); ! /* Can't compare raw MD5 because it could have a valid 00 in the middle */ ! for (i=0;i<16;i++) { ! sprintf(checkhash_hex + i * 2,"%02x",(int)checkhash[i]); ! } ! checkhash_hex[32] = '\0'; ! if (!strcmp(passhash,checkhash_hex)) ! valid++; ! } else { ! ast_log(LOG_WARNING, "Unable to read crypted password\n"); ! goto out; ! } ! } else if (!strcmp(password,copy)) valid++; else { if (option_verbose > 2)