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

Reply via email to