commit 967ce31b1e82969140f508309d15b1b4866d1033
Author: Oswald Buddenhagen <[email protected]>
Date: Sat Jul 27 10:37:15 2013 +0200
add PassCmd option to query IMAP password dynamically
inspired by patches by
Aurélien Francillon <[email protected]>,
Martin Stenberg <[email protected]> and
[email protected].
src/drv_imap.c | 42 +++++++++++++++++++++++++++++++++++++++++-
src/mbsync.1 | 11 +++++++++--
src/mbsyncrc.sample | 5 +++++
3 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/src/drv_imap.c b/src/drv_imap.c
index e6b4009..1f40bf2 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -31,6 +31,7 @@
#include <limits.h>
#include <string.h>
#include <ctype.h>
+#include <sys/wait.h>
typedef struct imap_server_conf {
struct imap_server_conf *next;
@@ -38,6 +39,7 @@ typedef struct imap_server_conf {
server_conf_t sconf;
char *user;
char *pass;
+ char *pass_cmd;
int max_in_progress;
#ifdef HAVE_LIBSSL
unsigned require_ssl:1;
@@ -1404,7 +1406,35 @@ imap_open_store_authenticate2( imap_store_t *ctx )
error( "Skipping account %s, no user\n", srvc->name );
goto bail;
}
- if (!srvc->pass) {
+ if (srvc->pass_cmd) {
+ FILE *fp;
+ int ret;
+ char buffer[80];
+
+ if (!(fp = popen( srvc->pass_cmd, "r" ))) {
+ pipeerr:
+ sys_error( "Skipping account %s, password command
failed", srvc->name );
+ goto bail;
+ }
+ if (!fgets( buffer, sizeof(buffer), fp ))
+ buffer[0] = 0;
+ if ((ret = pclose( fp )) < 0)
+ goto pipeerr;
+ if (ret) {
+ if (WIFSIGNALED( ret ))
+ error( "Skipping account %s, password command
crashed\n", srvc->name );
+ else
+ error( "Skipping account %s, password command
exited with status %d\n", srvc->name, WEXITSTATUS( ret ) );
+ goto bail;
+ }
+ if (!buffer[0]) {
+ error( "Skipping account %s, password command produced
no output\n", srvc->name );
+ goto bail;
+ }
+ buffer[strcspn( buffer, "\n" )] = 0; /* Strip trailing newline
*/
+ free( srvc->pass ); /* From previous runs */
+ srvc->pass = nfstrdup( buffer );
+ } else if (!srvc->pass) {
char prompt[80];
sprintf( prompt, "Password (%s): ", srvc->name );
arg = getpass( prompt );
@@ -1958,6 +1988,8 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep )
server->user = nfstrdup( cfg->val );
else if (!strcasecmp( "Pass", cfg->cmd ))
server->pass = nfstrdup( cfg->val );
+ else if (!strcasecmp( "PassCmd", cfg->cmd ))
+ server->pass_cmd = nfstrdup( cfg->val );
else if (!strcasecmp( "Port", cfg->cmd ))
server->sconf.port = parse_int( cfg );
else if (!strcasecmp( "PipelineDepth", cfg->cmd )) {
@@ -2028,6 +2060,14 @@ imap_parse_store( conffile_t *cfg, store_conf_t **storep
)
cfg->err = 1;
return 1;
}
+ if (server->pass && server->pass_cmd) {
+ if (store)
+ error( "IMAP store '%s' has both Pass and
PassCmd\n", store->gen.name );
+ else
+ error( "IMAP account '%s' has both Pass and
PassCmd\n", server->name );
+ cfg->err = 1;
+ return 1;
+ }
}
if (store) {
if (!store->server) {
diff --git a/src/mbsync.1 b/src/mbsync.1
index af92444..1816aa7 100644
--- a/src/mbsync.1
+++ b/src/mbsync.1
@@ -249,8 +249,15 @@ Specify the login name on the IMAP server. (Default:
current local user)
\fBPass\fR \fIpassword\fR
Specify the password for \fIusername\fR on the IMAP server.
Note that this option is \fBNOT\fR required.
-If no password is specified in the configuration file, \fBmbsync\fR
-will prompt you for it.
+If neither a password nor a password command is specified in the
+configuration file, \fBmbsync\fR will prompt you for a password.
+..
+.TP
+\fBPassCmd\fR \fIcommand\fR
+Specify a shell command to obtain a password rather than specifying a
+password directly. This allows you to use password files and agents.
+The command must produce exactly one line on stdout; the trailing newline is
+optional.
..
.TP
\fBTunnel\fR \fIcommand\fR
diff --git a/src/mbsyncrc.sample b/src/mbsyncrc.sample
index fe0adb6..0948a35 100644
--- a/src/mbsyncrc.sample
+++ b/src/mbsyncrc.sample
@@ -11,7 +11,12 @@ Trash Trash
IMAPStore work
Host work.host.com
+User tehuser
Pass xxxxxxxx
+# Fetch password from .netrc:
+#PassCmd "sed -n -e 's,^machine work\.host\.com login tehuser password
\(.*\),\1,p' < $HOME/.netrc"
+# Fetch password from a gpg-encrypted file:
+#PassCmd "gpg --quiet --for-your-eyes-only --decrypt $HOME/imappassword.gpg"
CertificateFile /etc/ssl/certs/ca-certificates.crt
Channel work
------------------------------------------------------------------------------
See everything from the browser to the database with AppDynamics
Get end-to-end visibility with application monitoring from AppDynamics
Isolate bottlenecks and diagnose root cause in seconds.
Start your free trial of AppDynamics Pro today!
http://pubads.g.doubleclick.net/gampad/clk?id=48808831&iu=/4140/ostg.clktrk
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel