summaryrefslogtreecommitdiff
path: root/apps/app_voicemail.c
diff options
context:
space:
mode:
authorTilghman Lesher <tilghman@meg.abyt.es>2009-10-22 19:10:04 +0000
committerTilghman Lesher <tilghman@meg.abyt.es>2009-10-22 19:10:04 +0000
commitd9f72c18936b73f3b174ff6666a7dd2c325407e9 (patch)
treef5168bb7b002e7fa8ac186ecb6c5abb55ce7327e /apps/app_voicemail.c
parentbe796e703ae8a05dde29c26f92f545b5ec0c40bc (diff)
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 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@225406 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_voicemail.c')
-rw-r--r--apps/app_voicemail.c228
1 files changed, 173 insertions, 55 deletions
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 422590fe8..9fad4744d 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -471,6 +471,12 @@ enum vm_option_args {
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 @@ struct ast_vm_user {
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 maxgreet;
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 make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in
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 char *strip_control(const char *input, char *buf, size_t buflen)
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 @@ static void apply_option(struct ast_vm_user *vmu, const char *var, const char *v
}
} 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 @@ static void vm_change_password(struct ast_vm_user *vmu, const char *newpassword)
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");
- 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;
+ /* 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;
}
- ast_variable_update(cat, vmu->mailbox, new, NULL, 0);
+ }
+ /* 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;
}
}
- /* 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");
+ /* 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;
}
- if (!var)
- ast_variable_update(cat, "vmsecret", new, NULL, 0);
- else
- ast_variable_append(cat, var);
+ }
+ /* 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");
}
}
- /* 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");
}
}
@@ -9860,25 +9906,37 @@ static int append_mailbox(const char *context, const char *box, const char *data
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 @@ static int load_config(int reload)
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 @@ static int load_config(int reload)
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 @@ static int load_config(int reload)
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 @@ static int sayname(struct ast_channel *chan, const char *mailbox, const char *co
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);