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)

Reply via email to