[svn-commits] rmudgett: branch rmudgett/dahdi_facility r225441 - in /team/rmudgett/dahdi_fa...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Oct 22 14:33:39 CDT 2009


Author: rmudgett
Date: Thu Oct 22 14:33:35 2009
New Revision: 225441

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=225441
Log:
Merged revisions 225405-225406 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
  r225405 | kpfleming | 2009-10-22 13:41:47 -0500 (Thu, 22 Oct 2009) | 9 lines
  
  Fix a refcount error introduced by yesterday's OBJ_MULTIPLE commit.
  
  When an object is being unlinked from its container *and* being returned to
  the caller, we do not want to decrement the reference count after unlinking
  it from the container, as the reference that the container held is what we
  are returning to the caller... and if it was the only remaining reference to
  the object, that could result in the object being destroyed.
........
  r225406 | tilghman | 2009-10-22 14:10:04 -0500 (Thu, 22 Oct 2009) | 7 lines
  
  Permit storage of voicemail secrets in a separate file, located within the spool directory.
  (closes issue #14276)
   Reported by: klaus3000
   Patches: 
         app_voicemail.c-svn-trunk-r214898.txt uploaded by klaus3000 (license 65)
   Tested by: jamesgolovich
........

Modified:
    team/rmudgett/dahdi_facility/   (props changed)
    team/rmudgett/dahdi_facility/CHANGES
    team/rmudgett/dahdi_facility/apps/app_voicemail.c
    team/rmudgett/dahdi_facility/configs/voicemail.conf.sample
    team/rmudgett/dahdi_facility/main/astobj2.c

Propchange: team/rmudgett/dahdi_facility/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Thu Oct 22 14:33:35 2009
@@ -1,1 +1,1 @@
-/trunk:1-225403
+/trunk:1-225433

Modified: team/rmudgett/dahdi_facility/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/dahdi_facility/CHANGES?view=diff&rev=225441&r1=225440&r2=225441
==============================================================================
--- team/rmudgett/dahdi_facility/CHANGES (original)
+++ team/rmudgett/dahdi_facility/CHANGES Thu Oct 22 14:33:35 2009
@@ -8,9 +8,9 @@
 ===
 ======================================================================
 
-***** Anticipated changes for 1.6.4 *****************************************
+***** Anticipated changes for 1.10 *******************************************
 ------------------------------------------------------------------------------
---- Functionality changes from Asterisk 1.6.3 to Asterisk 1.6.4  -------------
+--- Functionality changes from Asterisk 1.8 to Asterisk 1.10 -----------------
 ------------------------------------------------------------------------------
 
 libpri channel driver (chan_dahdi) DAHDI changes
@@ -27,7 +27,7 @@
    Access any received keypad digits in SETUP message by: ${CHANNEL(keypad_digits)}
 
 ------------------------------------------------------------------------------
---- Functionality changes from Asterisk 1.6.2 to Asterisk 1.6.3  -------------
+--- Functionality changes from Asterisk 1.6.2 to Asterisk 1.8 ----------------
 ------------------------------------------------------------------------------
 
 SIP Changes
@@ -101,6 +101,10 @@
  * The MeetMe application now turns on the DENOISE() function by default, for
    each participant.  In our tests, this has significantly decreased background
    noise (especially noisy data centers).
+ * Voicemail now permits storage of secrets in a separate file, located in the
+   spool directory of each individual user.  The control for this is located in
+   the "passwordlocation" option in voicemail.conf.  Please see the sample
+   configuration for more information.
 
 Dialplan Functions
 ------------------

Modified: team/rmudgett/dahdi_facility/apps/app_voicemail.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/dahdi_facility/apps/app_voicemail.c?view=diff&rev=225441&r1=225440&r2=225441
==============================================================================
--- team/rmudgett/dahdi_facility/apps/app_voicemail.c (original)
+++ team/rmudgett/dahdi_facility/apps/app_voicemail.c Thu Oct 22 14:33:35 2009
@@ -471,6 +471,12 @@
 	OPT_ARG_ARRAY_SIZE = 3,
 };
 
+enum vm_passwordlocation {
+	OPT_PWLOC_VOICEMAILCONF = 0,
+	OPT_PWLOC_SPOOLDIR      = 1,
+	OPT_PWLOC_USERSCONF     = 2,
+};
+
 AST_APP_OPTIONS(vm_app_options, {
 	AST_APP_OPTION('s', OPT_SILENT),
 	AST_APP_OPTION('b', OPT_BUSY_GREETING),
@@ -601,6 +607,7 @@
 	int maxmsg;                      /*!< Maximum number of msgs per folder for this mailbox */
 	int maxdeletedmsg;               /*!< Maximum number of deleted msgs saved for this mailbox */
 	int maxsecs;                     /*!< Maximum number of seconds per message for this mailbox */
+	int passwordlocation;            /*!< Storage location of the password */
 #ifdef IMAP_STORAGE
 	char imapuser[80];               /*!< IMAP server login */
 	char imappassword[80];           /*!< IMAP server password if authpassword not defined */
@@ -738,6 +745,7 @@
 static int skipms;
 static int maxlogins;
 static int minpassword;
+static int passwordlocation;
 
 /*! Poll mailboxes for changes since there is something external to
  *  app_voicemail that may change them. */
@@ -838,6 +846,8 @@
 static void apply_options(struct ast_vm_user *vmu, const char *options);
 static int add_email_attachment(FILE *p, struct ast_vm_user *vmu, char *format, char *attach, char *greeting_attachment, char *mailbox, char *bound, char *filename, int last, int msgnum);
 static int is_valid_dtmf(const char *key);
+static void read_password_from_file(const char *secretfn, char *password, int passwordlen);
+static int write_password_to_file(const char *secretfn, const char *password);
 
 #if !(defined(ODBC_STORAGE) || defined(IMAP_STORAGE))
 static int __has_voicemail(const char *context, const char *mailbox, const char *folder, int shortcircuit);
@@ -875,6 +885,7 @@
 static void populate_defaults(struct ast_vm_user *vmu)
 {
 	ast_copy_flags(vmu, (&globalflags), AST_FLAGS_ALL);	
+	vmu->passwordlocation = passwordlocation;
 	if (saydurationminfo)
 		vmu->saydurationm = saydurationminfo;
 	ast_copy_string(vmu->callback, callcontext, sizeof(vmu->callback));
@@ -996,6 +1007,12 @@
 		}
 	} else if (!strcasecmp(var, "volgain")) {
 		sscanf(value, "%30lf", &vmu->volgain);
+	} else if (!strcasecmp(var, "passwordlocation")) {
+		if (!strcasecmp(value, "spooldir")) {
+			vmu->passwordlocation = OPT_PWLOC_SPOOLDIR;
+		} else {
+			vmu->passwordlocation = OPT_PWLOC_VOICEMAILCONF;
+		}
 	} else if (!strcasecmp(var, "options")) {
 		apply_options(vmu, value);
 	}
@@ -1316,65 +1333,94 @@
 	char *category = NULL, *value = NULL, *new = NULL;
 	const char *tmp = NULL;
 	struct ast_flags config_flags = { CONFIG_FLAG_WITHCOMMENTS };
+	char secretfn[PATH_MAX] = "";
+	int found = 0;
+
 	if (!change_password_realtime(vmu, newpassword))
 		return;
 
-	/* check voicemail.conf */
-	if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) {
-		while ((category = ast_category_browse(cfg, category))) {
-			if (!strcasecmp(category, vmu->context)) {
-				if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) {
-					ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n");
+	/* check if we should store the secret in the spool directory next to the messages */
+	switch (vmu->passwordlocation) {
+	case OPT_PWLOC_SPOOLDIR:
+		snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox);
+		if (write_password_to_file(secretfn, newpassword) == 0) {
+			ast_verb(4, "Writing voicemail password to file %s succeeded\n", secretfn);
+			reset_user_pw(vmu->context, vmu->mailbox, newpassword);
+			ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
+			break;
+		} else {
+			ast_verb(4, "Writing voicemail password to file %s failed, falling back to config file\n", secretfn);
+		}
+		/* Fall-through */
+	case OPT_PWLOC_VOICEMAILCONF:
+		if ((cfg = ast_config_load(VOICEMAIL_CONFIG, config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) {
+			while ((category = ast_category_browse(cfg, category))) {
+				if (!strcasecmp(category, vmu->context)) {
+					if (!(tmp = ast_variable_retrieve(cfg, category, vmu->mailbox))) {
+						ast_log(AST_LOG_WARNING, "We could not find the mailbox.\n");
+						break;
+					}
+					value = strstr(tmp, ",");
+					if (!value) {
+						ast_log(AST_LOG_WARNING, "variable has bad format.\n");
+						break;
+					}
+					new = alloca((strlen(value) + strlen(newpassword) + 1));
+					sprintf(new, "%s%s", newpassword, value);
+					if (!(cat = ast_category_get(cfg, category))) {
+						ast_log(AST_LOG_WARNING, "Failed to get category structure.\n");
+						break;
+					}
+					ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
+					found = 1;
+				}
+			}
+			/* save the results */
+			if (found) {
+				reset_user_pw(vmu->context, vmu->mailbox, newpassword);
+				ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
+				ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
+				break;
+			}
+		}
+		/* Fall-through */
+	case OPT_PWLOC_USERSCONF:
+		/* check users.conf and update the password stored for the mailbox */
+		/* if no vmsecret entry exists create one. */
+		if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) {
+			ast_debug(4, "we are looking for %s\n", vmu->mailbox);
+			for (category = ast_category_browse(cfg, NULL); category; category = ast_category_browse(cfg, category)) {
+				ast_debug(4, "users.conf: %s\n", category);
+				if (!strcasecmp(category, vmu->mailbox)) {
+					if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
+						ast_debug(3, "looks like we need to make vmsecret!\n");
+						var = ast_variable_new("vmsecret", newpassword, "");
+					} else {
+						var = NULL;
+					}
+					new = alloca(strlen(newpassword) + 1);
+					sprintf(new, "%s", newpassword);
+					if (!(cat = ast_category_get(cfg, category))) {
+						ast_debug(4, "failed to get category!\n");
+						ast_free(var);
+						break;
+					}
+					if (!var) {
+						ast_variable_update(cat, "vmsecret", new, NULL, 0);
+					} else {
+						ast_variable_append(cat, var);
+					}
+					found = 1;
 					break;
 				}
-				value = strstr(tmp, ",");
-				if (!value) {
-					ast_log(AST_LOG_WARNING, "variable has bad format.\n");
-					break;
-				}
-				new = alloca((strlen(value)+strlen(newpassword)+1));
-				sprintf(new, "%s%s", newpassword, value);
-				if (!(cat = ast_category_get(cfg, category))) {
-					ast_log(AST_LOG_WARNING, "Failed to get category structure.\n");
-					break;
-				}
-				ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
-			}
-		}
-		/* save the results */
-		reset_user_pw(vmu->context, vmu->mailbox, newpassword);
-		ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
-		ast_config_text_file_save(VOICEMAIL_CONFIG, cfg, "AppVoicemail");
-	}
-	category = NULL;
-	var = NULL;
-	/* check users.conf and update the password stored for the mailbox*/
-	/* if no vmsecret entry exists create one. */
-	if ((cfg = ast_config_load("users.conf", config_flags)) && cfg != CONFIG_STATUS_FILEINVALID) {
-		ast_debug(4, "we are looking for %s\n", vmu->mailbox);
-		while ((category = ast_category_browse(cfg, category))) {
-			ast_debug(4, "users.conf: %s\n", category);
-			if (!strcasecmp(category, vmu->mailbox)) {
-				if (!(tmp = ast_variable_retrieve(cfg, category, "vmsecret"))) {
-					ast_debug(3, "looks like we need to make vmsecret!\n");
-					var = ast_variable_new("vmsecret", newpassword, "");
-				} 
-				new = alloca(strlen(newpassword)+1);
-				sprintf(new, "%s", newpassword);
-				if (!(cat = ast_category_get(cfg, category))) {
-					ast_debug(4, "failed to get category!\n");
-					break;
-				}
-				if (!var)		
-					ast_variable_update(cat, "vmsecret", new, NULL, 0);
-				else
-					ast_variable_append(cat, var);
-			}
-		}
-		/* save the results and clean things up */
-		reset_user_pw(vmu->context, vmu->mailbox, newpassword);	
-		ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
-		ast_config_text_file_save("users.conf", cfg, "AppVoicemail");
+			}
+			/* save the results and clean things up */
+			if (found) {
+				reset_user_pw(vmu->context, vmu->mailbox, newpassword);
+				ast_copy_string(vmu->password, newpassword, sizeof(vmu->password));
+				ast_config_text_file_save("users.conf", cfg, "AppVoicemail");
+			}
+		}
 	}
 }
 
@@ -9860,25 +9906,37 @@
 	struct ast_vm_user *vmu;
 	char *mailbox_full;
 	int new = 0, old = 0, urgent = 0;
+	char secretfn[PATH_MAX] = "";
 
 	tmp = ast_strdupa(data);
 
 	if (!(vmu = find_or_create(context, box)))
 		return -1;
-	
+
 	populate_defaults(vmu);
 
 	stringp = tmp;
-	if ((s = strsep(&stringp, ","))) 
+	if ((s = strsep(&stringp, ","))) {
 		ast_copy_string(vmu->password, s, sizeof(vmu->password));
-	if (stringp && (s = strsep(&stringp, ","))) 
+	}
+	if (stringp && (s = strsep(&stringp, ","))) {
 		ast_copy_string(vmu->fullname, s, sizeof(vmu->fullname));
-	if (stringp && (s = strsep(&stringp, ","))) 
+	}
+	if (stringp && (s = strsep(&stringp, ","))) {
 		ast_copy_string(vmu->email, s, sizeof(vmu->email));
-	if (stringp && (s = strsep(&stringp, ","))) 
+	}
+	if (stringp && (s = strsep(&stringp, ","))) {
 		ast_copy_string(vmu->pager, s, sizeof(vmu->pager));
-	if (stringp && (s = strsep(&stringp, ","))) 
+	}
+	if (stringp && (s = strsep(&stringp, ","))) {
 		apply_options(vmu, s);
+	}
+
+	switch (vmu->passwordlocation) {
+	case OPT_PWLOC_SPOOLDIR:
+		snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, vmu->context, vmu->mailbox);
+		read_password_from_file(secretfn, vmu->password, sizeof(vmu->password));
+	}
 
 	mailbox_full = alloca(strlen(box) + strlen(context) + 1);
 	strcpy(mailbox_full, box);
@@ -10563,6 +10621,7 @@
 	int x;
 	int tmpadsi[4];
 	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+	char secretfn[PATH_MAX] = "";
 
 	ast_unload_realtime("voicemail");
 	ast_unload_realtime("voicemail_data");
@@ -11061,6 +11120,15 @@
 			val = "no";
 		ast_set2_flag((&globalflags), ast_true(val), VM_DIRECFORWARD);	
 
+		if (!(val = ast_variable_retrieve(cfg, "general", "passwordlocation"))) {
+			val = "voicemail.conf";
+		}
+		if (!(strcmp(val, "spooldir"))) {
+			passwordlocation = OPT_PWLOC_SPOOLDIR;
+		} else {
+			passwordlocation = OPT_PWLOC_VOICEMAILCONF;
+		}
+
 		poll_freq = DEFAULT_POLL_FREQ;
 		if ((val = ast_variable_retrieve(cfg, "general", "pollfreq"))) {
 			if (sscanf(val, "%30u", &poll_freq) != 1) {
@@ -11081,6 +11149,15 @@
 					populate_defaults(current);
 					apply_options_full(current, ast_variable_browse(ucfg, cat));
 					ast_copy_string(current->context, userscontext, sizeof(current->context));
+					if (!ast_strlen_zero(current->password) && current->passwordlocation == OPT_PWLOC_VOICEMAILCONF) {
+						current->passwordlocation = OPT_PWLOC_USERSCONF;
+					}
+
+					switch (current->passwordlocation) {
+					case OPT_PWLOC_SPOOLDIR:
+						snprintf(secretfn, sizeof(secretfn), "%s%s/%s/secret.conf", VM_SPOOL_DIR, current->context, current->mailbox);
+						read_password_from_file(secretfn, current->password, sizeof(current->password));
+					}
 				}
 			}
 			ast_config_destroy(ucfg);
@@ -11216,6 +11293,47 @@
 	return res;
 }
 
+static void read_password_from_file(const char *secretfn, char *password, int passwordlen) {
+	struct ast_config *pwconf;
+	struct ast_flags config_flags = { 0 };
+
+	pwconf = ast_config_load(secretfn, config_flags);
+	if (pwconf) {
+		const char *val = ast_variable_retrieve(pwconf, "general", "password");
+		if (val) {
+			ast_copy_string(password, val, passwordlen);
+ 			return;
+		}
+	}
+	ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn);
+}
+
+static int write_password_to_file(const char *secretfn, const char *password) {
+	struct ast_config *conf;
+	struct ast_category *cat;
+	struct ast_variable *var;
+
+	if (!(conf=ast_config_new())) {
+		ast_log(LOG_ERROR, "Error creating new config structure\n");
+		return -1;
+	}
+	if (!(cat=ast_category_new("general","",1))) {
+		ast_log(LOG_ERROR, "Error creating new category structure\n");
+		return -1;
+	}
+	if (!(var=ast_variable_new("password",password,""))) {
+		ast_log(LOG_ERROR, "Error creating new variable structure\n");
+		return -1;
+	}
+	ast_category_append(conf,cat);
+	ast_variable_append(cat,var);
+	if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) {
+		ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn);
+		return -1;
+	}
+	return 0;
+}
+
 static int reload(void)
 {
 	return load_config(1);

Modified: team/rmudgett/dahdi_facility/configs/voicemail.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/dahdi_facility/configs/voicemail.conf.sample?view=diff&rev=225441&r1=225440&r2=225441
==============================================================================
--- team/rmudgett/dahdi_facility/configs/voicemail.conf.sample (original)
+++ team/rmudgett/dahdi_facility/configs/voicemail.conf.sample Thu Oct 22 14:33:35 2009
@@ -274,9 +274,28 @@
 			;     The default is "no".
 ; tempgreetwarn=yes	; Remind the user that their temporary greeting is set
 
-;messagewrap=no	; Enable next/last message to wrap around to
-			; first (from last) and last (from first) message
-			; The default is "no".
+; passwordlocation=spooldir
+                    ; Usually the voicemail password (vmsecret) is stored in
+                    ; this configuration file.  By setting this option you can
+                    ; specify where Asterisk should read/write the vmsecret.
+                    ; Supported options:
+                    ;   voicemail.conf:
+                    ;     This is the default option.  The secret is read from
+                    ;     and written to voicemail.conf (or users.conf).
+                    ;   spooldir:
+                    ;     The secret is stored in a separate file in the user's
+                    ;     voicemail spool directory in a file named secret.conf.
+                    ;     Please ensure that normal Linux users are not
+                    ;     permitted to access Asterisk's spool directory as the
+                    ;     secret is stored in plain text.  If a secret is not
+                    ;     found in this directory, the password in
+                    ;     voicemail.conf (or users.conf) will be used.
+                    ; Note that this option does not affect password storage for
+                    ; realtime users, which are still stored in the realtime
+                    ; backend.
+; messagewrap=no    ; Enable next/last message to wrap around to
+                    ; first (from last) and last (from first) message
+                    ; The default is "no".
 ; minpassword=0 ; Enforce minimum password length
 
 ; vm-password=custom_sound

Modified: team/rmudgett/dahdi_facility/main/astobj2.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/dahdi_facility/main/astobj2.c?view=diff&rev=225441&r1=225440&r2=225441
==============================================================================
--- team/rmudgett/dahdi_facility/main/astobj2.c (original)
+++ team/rmudgett/dahdi_facility/main/astobj2.c Thu Oct 22 14:33:35 2009
@@ -685,7 +685,6 @@
 				match &= cb_default(EXTERNAL_OBJ(cur->astobj), arg, flags);
 			}
 
-			/* we found the object, performing operations according flags */
 			if (match == 0) {	/* no match, no stop, continue */
 				continue;
 			} else if (match == CMP_STOP) {	/* no match but stop, we are done */
@@ -693,6 +692,7 @@
 				break;
 			}
 
+			/* we found the object, performing operations according flags */
 			/* we have a match (CMP_MATCH) here */
 			if (!(flags & OBJ_NODATA)) {	/* if must return the object, record the value */
 				/* it is important to handle this case before the unlink */
@@ -719,12 +719,6 @@
 				AST_LIST_REMOVE_CURRENT(entry);
 				/* update number of elements */
 				ast_atomic_fetchadd_int(&c->elements, -1);
-				if (!(flags & OBJ_NODATA)) {
-					if (tag)
-						__ao2_ref_debug(EXTERNAL_OBJ(cur->astobj), -1, tag, file, line, funcname);
-					else
-						__ao2_ref(EXTERNAL_OBJ(cur->astobj), -1);
-				}
 				ast_free(cur);	/* free the link record */
 			}
 




More information about the svn-commits mailing list