]> Pileus Git - ~andy/fetchmail/commitdiff
Initial libpwmd commit obtained from fetchmail-6.3.14+libpwmd6-1.diff.
authorBen Kibbey <bjk@luxsci.net>
Fri, 12 Feb 2010 00:36:43 +0000 (19:36 -0500)
committerBen Kibbey <bjk@luxsci.net>
Fri, 12 Feb 2010 00:36:43 +0000 (19:36 -0500)
Makefile.am
README.PWMD [new file with mode: 0644]
configure.ac
fetchmail.c
fetchmail.h
options.c
rcfile_l.l
rcfile_y.y

index 3415a035751195a23ceebf8e6a59650f059980f9..7ae6a06a0b1f4c7753b415217f6c270f8d7a94d2 100644 (file)
@@ -16,6 +16,11 @@ dist_man1_MANS=              fetchmail.man
 pys=                   fetchmailconf.py
 pym=                   fetchmailconf.man
 
+if HAVE_LIBPWMD
+CFLAGS += @libpwmd_CFLAGS@
+LDFLAGS += @libpwmd_LIBS@
+endif
+
 if HAVE_PYTHON
 nodist_bin_SCRIPTS=    fetchmailconf
 python_PYTHON=         $(pys)
diff --git a/README.PWMD b/README.PWMD
new file mode 100644 (file)
index 0000000..a061015
--- /dev/null
@@ -0,0 +1,82 @@
+When compiled with pwmd (Password Manager Daemon) support (--enable-pwmd)
+fetchmail can retrieve server details from pwmd. pwmd v2.0 and libpwmd v6.0.0
+or later are required.
+
+Three new configuration parameters are added: pwmd_socket (optional) to
+specify the socket to connect to (default is ~/.pwmd/socket), pwmd_file
+(required) which specifies the filename on the server to open, and a global
+parameter pinentry_timeout (optional) which specifies the number of seconds
+until pinentry is cancelled while waiting for the password.
+
+Three new command line options are also added:
+    --pwmd-socket, -C     same as pwmd_socket
+    --pwmd-file, -G       same as pwmd_file
+    --pinentry_timeout, -O same as pinentry_timeout
+
+If no pinentry timeout value is specified then the server default will be
+used.
+
+The format of pwmd_socket and --pwmd-socket can be either a URL string in the
+form of:
+       file://[path/to/socket]
+       
+       or
+
+       ssh[46]://[username@]hostname[:port],identity_file,known_hosts_file
+
+If neither file:// or ssh[46]:// are specified it is assumed to be a local
+UNIX domain socket to connect to (file://~/.pwmd/socket).
+
+See the pwmc(1) manual page for details about the identity and known_hosts
+files. Note that if connecting to a remote pwmd server, pwmd's pinentry will
+be disabled and a local pinentry will be tried.
+
+The data that pwmd uses to serve clients is stored in an (encrypted) XML file.
+You'll need to create the file you want fetchmail to use by connecting to the
+server with a pwmd client (socat or pwmc from libpwmd) and send commands to
+store the data. See COMMANDS included with pwmd for details.
+
+The password, if any, to open the encrypted data file is either cached on the
+server (the file has been opened before), or gotten from pinentry(1). See the
+pwmd(1) manual page for information about the ~/.pwmd/pinentry.conf file which
+may contain DISPLAY and TTYNAME settings to let pinentry(1) know where to
+prompt for the password.
+
+An account (e.g., pollname) may be an element path. Instead of separating the
+elements with a TAB character, separate them with a '^'.
+
+Here are the elements that fetchmail uses:
+
+    [...]elements in the element path (^ separated)[...]
+    <pollname>
+       <username>              - Optional (--username/username)
+       <password>              - Optional (--password/password)
+       <POP3|IMAP|etc..>       - Server protocol (must match the protocol
+                                 keyword from the rcfile or command line)
+           <hostname>          - Required (servername/via)
+           <port>              - Required (--service/protocol)
+           <ssl>               - Optional (--ssl/ssl)
+           <sslfingerprint>    - Optional (--sslfingerprint/sslfingerprint)
+       </POP3|IMAP|etc..>
+    </pollname>
+
+
+A minimal fetchmailrc might look like this:
+
+    set pinentry_timeout 30
+    poll isp proto POP3:
+       pwmd_file default
+
+    poll myaccounts^isp proto IMAP:
+       pwmd_file default
+       pwmd_socket "ssh://user@host,~/.pwmd/fetchmail,~/.pwmd/known_hosts"
+
+
+Or from the command line:
+
+    fetchmail -f fetchmailrc isp
+    fetchmail --pwmd-file somefile -p POP3 isp
+
+
+Ben Kibbey <bjk@luxsci.net>
+http://bjk.sourceforge.net/pwmd/.
index 42d1a3c336f1560089c9f5a76f3db86cf6196703..c2d72fd5ad5e4b6b83d111d213461b493b2e9721 100644 (file)
@@ -287,6 +287,22 @@ done
 AC_MSG_RESULT(root-mode pid file will go in $dir)
 AC_DEFINE_UNQUOTED(PID_DIR, "$dir", directory for PID lock files)
 
+AC_ARG_ENABLE(pwmd,
+       [  --enable-pwmd           enable Password Manager Daemon support],
+       , [enable_pwmd=no])
+
+if test "$enable_pwmd" = "yes"; then
+    PKG_CHECK_EXISTS([libpwmd], have_libpwmd=1,
+                    AC_MSG_ERROR([Could not find libpwmd pkg-config module.]))
+
+
+    PKG_CHECK_MODULES([libpwmd], [libpwmd >= 6.0.0])
+    AM_CONDITIONAL(HAVE_LIBPWMD, true)
+    AC_DEFINE(HAVE_LIBPWMD, 1, [Define if you have libPWMD installed.])
+else
+    AM_CONDITIONAL(HAVE_LIBPWMD, false)
+fi
+
 # We may have a fallback MDA available in case the socket open to the 
 # local SMTP listener fails.  Best to use procmail for this, as we know
 # it won't try delivering through local SMTP and cause a mail loop.
index cb1bc9003fee72671cf8d23ebd04b1b7b878ebc3..98a79218ff071e3233d4d5ab676690b99b80235d 100644 (file)
@@ -87,6 +87,12 @@ static time_t parsetime;     /* time of last parse */
 static RETSIGTYPE terminate_run(int);
 static RETSIGTYPE terminate_poll(int);
 
+#ifdef HAVE_LIBPWMD
+static pwm_t *pwm;             /* the handle */
+static const char *pwmd_socket;        /* current socket */
+static const char *pwmd_file;  /* current file */
+#endif
+
 #if defined(__FreeBSD__) && defined(__FreeBSD_USE_KVM)
 /* drop SGID kmem privileage until we need it */
 static void dropprivs(void)
@@ -147,6 +153,282 @@ static void printcopyright(FILE *fp) {
 
 const char *iana_charset;
 
+#ifdef HAVE_LIBPWMD
+static void exit_with_pwmd_error(gpg_error_t error)
+{
+    gpg_err_code_t code = gpg_err_code(error);
+
+    report(stderr, GT_("pwmd: error %i: %s\n"), code, pwmd_strerror(error));
+
+    if (pwm) {
+       pwmd_close(pwm);
+       pwm = NULL;
+    }
+
+    /* Don't exit if daemonized. There may be other active accounts. */
+    if (isatty(1))
+       exit(PS_UNDEFINED);
+}
+
+static int do_pwmd_connect(const char *socketname, const char *filename)
+{
+    static int init;
+    gpg_error_t rc;
+    pwmd_socket_t s;
+
+    if (!init) {
+       pwmd_init();
+       init = 1;
+    }
+
+    if (!pwm || (pwm && socketname && !pwmd_socket) ||
+           (pwm && !socketname && pwmd_socket) ||
+           (pwm && socketname && pwmd_socket && strcmp(socketname, pwmd_socket))) {
+       if (pwm)
+           pwmd_close(pwm);
+
+       pwm = pwmd_new("Fetchmail");
+       rc = pwmd_connect_url(pwm, socketname);
+
+       if (rc) {
+           exit_with_pwmd_error(rc);
+           return 1;
+       }
+    }
+
+    if (run.pinentry_timeout > 0) {
+       rc = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_TIMEOUT,
+               run.pinentry_timeout);
+
+       if (rc) {
+           exit_with_pwmd_error(rc);
+           return 1;
+       }
+    }
+
+    rc = pwmd_socket_type(pwm, &s);
+
+    if (rc) {
+       exit_with_pwmd_error(rc);
+       return 1;
+    }
+
+    if (!pwmd_file || strcmp(filename, pwmd_file)) {
+       if (s == PWMD_SOCKET_SSH)
+           /* use a local pinentry since X11 forwarding is broken. */
+           rc = pwmd_open2(pwm, filename);
+       else
+           rc = pwmd_open(pwm, filename);
+
+       if (rc) {
+           exit_with_pwmd_error(rc);
+           return 1;
+       }
+    }
+
+    /* May be null to use the default of ~/.pwmd/socket. */
+    pwmd_socket = socketname;
+    pwmd_file = filename;
+    return 0;
+}
+
+static int get_pwmd_details(const char *pwmd_account, int protocol,
+       struct query *ctl)
+{
+    const char *prot = showproto(protocol);
+    gpg_error_t error;
+    char *result;
+    char *tmp = xstrdup(pwmd_account);
+    int i;
+
+    for (i = 0; tmp[i]; i++) {
+       if (i && tmp[i] == '^')
+           tmp[i] = '\t';
+    }
+
+    /*
+     * Get the hostname for this protocol. Element path must be
+     * account->[protocol]->hostname.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\thostname", tmp, prot);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->%s->hostname: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+           pwmd_close(pwm);
+           pwm = NULL;
+
+           if (isatty(1))
+               exit(PS_SYNTAX);
+
+           return 1;
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+
+    if (ctl->server.pollname != ctl->server.via)
+       xfree(ctl->server.via);
+
+    ctl->server.via = xstrdup(result);
+
+    if (ctl->server.queryname)
+       xfree(ctl->server.queryname);
+
+    ctl->server.queryname = xstrdup(ctl->server.via);
+
+    if (ctl->server.truename)
+       xfree(ctl->server.truename);
+
+    ctl->server.truename = xstrdup(ctl->server.queryname);
+    pwmd_free(result);
+
+    /*
+     * Server port. Fetchmail tries standard ports for known services so it
+     * should be alright if this element isn't found. ctl->server.protocol is
+     * already set. This sets ctl->server.service.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\tport", tmp, prot);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND)
+           report(stderr, GT_("pwmd: %s->%s->port: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       if (ctl->server.service)
+           xfree(ctl->server.service);
+
+       ctl->server.service = xstrdup(result);
+       pwmd_free(result);
+    }
+
+    /*
+     * Get the remote username. Element must be account->username.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\tusername", tmp);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->username: %s\n"), pwmd_account, pwmd_strerror(error));
+
+           if (!isatty(1)) {
+               pwmd_close(pwm);
+               pwm = NULL;
+               return 1;
+           }
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       if (ctl->remotename)
+           xfree(ctl->remotename);
+
+       if (ctl->server.esmtp_name)
+           xfree(ctl->server.esmtp_name);
+
+       ctl->remotename = xstrdup(result);
+       ctl->server.esmtp_name = xstrdup(result);
+       pwmd_free(result);
+    }
+
+    /*
+     * Get the remote password. Element must be account->password.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\tpassword", tmp);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->password: %s\n"), pwmd_account, pwmd_strerror(error));
+
+           if (!isatty(1)) {
+               pwmd_close(pwm);
+               pwm = NULL;
+               return 1;
+           }
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       if (ctl->password)
+           xfree(ctl->password);
+
+       ctl->password= xstrdup(result);
+       pwmd_free(result);
+    }
+
+#ifdef SSL_ENABLE
+    /*
+     * If there is a ssl element and set to 1, enable ssl for this account.
+     * Element path must be account->[protocol]->ssl.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\tssl", tmp, prot);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->%s->ssl: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+
+           if (!isatty(1)) {
+               pwmd_close(pwm);
+               pwm = NULL;
+               return 1;
+           }
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       ctl->use_ssl = atoi(result) >= 1 ? FLAG_TRUE : FLAG_FALSE;
+       pwmd_free(result);
+    }
+
+    /*
+     * account->[protocol]->sslfingerprint.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\tsslfingerprint", tmp, prot);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->%s->sslfingerprint: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+
+           if (!isatty(1)) {
+               pwmd_close(pwm);
+               pwm = NULL;
+               return 1;
+           }
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       if (ctl->sslfingerprint)
+           xfree(ctl->sslfingerprint);
+
+       ctl->sslfingerprint = xstrdup(result);
+       pwmd_free(result);
+    }
+#endif
+
+    xfree(tmp);
+    return 0;
+}
+#endif
+
 int main(int argc, char **argv)
 {
     int bkgd = FALSE;
@@ -280,6 +562,9 @@ int main(int argc, char **argv)
 #ifndef HAVE_RES_SEARCH
        "-DNS"
 #endif
+#ifdef HAVE_LIBPWMD
+       "+PWMD"
+#endif /* HAVE_LIBPWMD */
        ".\n";
        printf(GT_("This is fetchmail release %s"), VERSION);
        fputs(features, stdout);
@@ -639,6 +924,11 @@ int main(int argc, char **argv)
         * leaks...
         */
        struct stat     rcstat;
+#ifdef HAVE_LIBPWMD
+       time_t now;
+
+       time(&now);
+#endif
 
        if (strcmp(rcfile, "-") == 0) {
            /* do nothing */
@@ -648,7 +938,15 @@ int main(int argc, char **argv)
                       GT_("couldn't time-check %s (error %d)\n"),
                       rcfile, errno);
        }
+#ifdef HAVE_LIBPWMD
+       /*
+        * isatty() to make sure this is a background process since the
+        * lockfile is removed after each invokation.
+        */
+       else if (!isatty(1) && rcstat.st_mtime > parsetime)
+#else
        else if (rcstat.st_mtime > parsetime)
+#endif
        {
            report(stdout, GT_("restarting fetchmail (%s changed)\n"), rcfile);
 
@@ -741,6 +1039,19 @@ int main(int argc, char **argv)
 
                    dofastuidl = 0; /* this is reset in the driver if required */
 
+#ifdef HAVE_LIBPWMD
+                   /*
+                    * At each poll interval, check the pwmd server for
+                    * changes in host and auth settings.
+                    */
+                   if (ctl->pwmd_file) {
+                       if (do_pwmd_connect(ctl->pwmd_socket, ctl->pwmd_file))
+                           continue;
+
+                       if (get_pwmd_details(ctl->server.pollname, ctl->server.protocol, ctl))
+                           continue;
+                   }
+#endif
                    querystatus = query_host(ctl);
 
                    if (NUM_NONZERO(ctl->fastuidl))
@@ -809,6 +1120,13 @@ int main(int argc, char **argv)
                }
            }
 
+#ifdef HAVE_LIBPWMD
+       if (pwm) {
+           pwmd_close(pwm);
+           pwm = NULL;
+       }
+#endif
+
        /* close connections cleanly */
        terminate_poll(0);
 
@@ -1048,8 +1366,36 @@ static int load_params(int argc, char **argv, int optind)
 
     if ((implicitmode = (optind >= argc)))
     {
+#ifdef HAVE_LIBPWMD
+       for (ctl = querylist; ctl; ctl = ctl->next) {
+           ctl->active = !ctl->server.skip;
+
+           if (ctl->pwmd_file) {
+               /*
+                * Cannot get an element path without a service.
+                */
+               if (ctl->server.protocol <= 1) {
+                   report(stderr, GT_("fetchmail: %s configuration invalid, pwmd_file requires a protocol specification\n"),
+                           ctl->server.pollname);
+                   pwmd_close(pwm);
+                   exit(PS_SYNTAX);
+               }
+
+               if (do_pwmd_connect(ctl->pwmd_socket, ctl->pwmd_file))
+                   continue;
+
+               if (get_pwmd_details(ctl->server.pollname, ctl->server.protocol,
+                           ctl))
+                   continue;
+
+               time(&rcstat.st_mtime);
+           }
+       }
+
+#else
        for (ctl = querylist; ctl; ctl = ctl->next)
            ctl->active = !ctl->server.skip;
+#endif
     }
     else
        for (; optind < argc; optind++) 
@@ -1070,6 +1416,27 @@ static int load_params(int argc, char **argv, int optind)
                        fprintf(stderr,GT_("Warning: multiple mentions of host %s in config file\n"),argv[optind]);
                    ctl->active = TRUE;
                    predeclared = TRUE;
+
+#ifdef HAVE_LIBPWMD
+                   if (ctl->pwmd_file) {
+                       /*
+                        * Cannot get an element path without a service.
+                        */
+                       if (ctl->server.protocol <= 1) {
+                           report(stderr, GT_("%s configuration invalid, pwmd_file requires a protocol specification\n"),
+                                  ctl->server.pollname);
+                           exit(PS_SYNTAX);
+                       }
+
+                       fprintf(stderr, "%s(%i): %s\n", __FILE__, __LINE__, __FUNCTION__);
+                       if (do_pwmd_connect(ctl->pwmd_socket, ctl->pwmd_file))
+                           continue;
+
+                       if (get_pwmd_details(ctl->server.pollname,
+                                   ctl->server.protocol, ctl))
+                           continue;
+                   }
+#endif
                }
 
            if (!predeclared)
@@ -1080,8 +1447,32 @@ static int load_params(int argc, char **argv, int optind)
                 * call later on.
                 */
                ctl = hostalloc((struct query *)NULL);
-               ctl->server.via =
-                   ctl->server.pollname = xstrdup(argv[optind]);
+
+#ifdef HAVE_LIBPWMD
+               if (cmd_opts.pwmd_file) {
+                   /*
+                    * Cannot get an element path without a service.
+                    */
+                   if (cmd_opts.server.protocol == 0 || cmd_opts.server.protocol == 1) {
+                       report(stderr, GT_("Option --pwmd-file needs a service (-p) parameter.\n"));
+                       exit(PS_SYNTAX);
+                   }
+
+                       fprintf(stderr, "%s(%i): %s\n", __FILE__, __LINE__, __FUNCTION__);
+                   if (do_pwmd_connect(cmd_opts.pwmd_socket, cmd_opts.pwmd_file))
+                       continue;
+
+                   if (get_pwmd_details(argv[optind], cmd_opts.server.protocol,
+                           ctl))
+                       continue;
+               }
+               else
+                   ctl->server.via =
+                       ctl->server.pollname = xstrdup(argv[optind]);
+#else
+               ctl->server.via =
+                   ctl->server.pollname = xstrdup(argv[optind]);
+#endif
                ctl->active = TRUE;
                ctl->server.lead_server = (struct hostdata *)NULL;
            }
index d09913868d09ba0de6a682c5bb4557f82948d8f8..a31ddf0aba5345eef5498debfe15f0f1496a95a0 100644 (file)
@@ -39,6 +39,10 @@ struct addrinfo;
 #  include "trio/trio.h"
 #endif
 
+#ifdef HAVE_LIBPWMD
+#include <libpwmd.h>
+#endif
+
 /* We need this for strstr */
 #if !defined(HAVE_STRSTR) && !defined(strstr)
 char *strstr(const char *, const char *);
@@ -178,6 +182,9 @@ struct runctl
     char       *pidfile;       /** where to record the PID of daemon mode processes */
     char       *postmaster;
     char       *properties;
+#ifdef HAVE_LIBPWMD
+    int                pinentry_timeout;
+#endif
     int                poll_interval;  /** poll interval in seconds (daemon mode, 0 == off) */
     flag       bouncemail;
     flag       spambounce;
@@ -315,6 +322,11 @@ struct query
     char *password;            /* remote password to use */
     struct idlist *mailboxes;  /* list of mailboxes to check */
 
+#ifdef HAVE_LIBPWMD
+    char *pwmd_socket;         /* socket to connect to */
+    char *pwmd_file;           /* file to open on the server */
+#endif
+
     /* per-forwarding-target data */
     struct idlist *smtphunt;   /* list of SMTP hosts to try forwarding to */
     struct idlist *domainlist; /* domainlist to fetch from */
index e85682d56dfcdf4f3d16843afa9bfa3ab63ab96d..c32a7bdfa6e77e05c506d3d38b59e9955db7a21c 100644 (file)
--- a/options.c
+++ b/options.c
@@ -56,12 +56,22 @@ enum {
     LA_SOFTBOUNCE
 };
 
+#ifdef HAVE_LIBPWMD
+static const char *shortoptions = 
+       "O:C:G:?Vcsvd:NqL:f:i:p:UP:A:t:E:Q:u:akKFnl:r:S:Z:b:B:e:m:I:M:yw:D:";
+#else
 /* options still left: CgGhHjJoORTWxXYz */
 static const char *shortoptions = 
        "?Vcsvd:NqL:f:i:p:UP:A:t:E:Q:u:akKFnl:r:S:Z:b:B:e:m:I:M:yw:D:";
+#endif
 
 static const struct option longoptions[] = {
 /* this can be const because all flag fields are 0 and will never get set */
+#ifdef HAVE_LIBPWMD
+  {"pwmd-socket",      required_argument,         (int *) 0, 'C' },
+  {"pwmd-file",        required_argument,         (int *) 0, 'G' },
+  {"pinentry-timeout",    required_argument,         (int *) 0, 'O' },
+#endif
   {"help",     no_argument,       (int *) 0, '?' },
   {"version",  no_argument,       (int *) 0, 'V' },
   {"check",    no_argument,       (int *) 0, 'c' },
@@ -254,6 +264,17 @@ int parsecmdline (int argc /** argument count */,
                            longoptions, &option_index)) != -1)
     {
        switch (c) {
+#ifdef HAVE_LIBPWMD
+       case 'C':
+           ctl->pwmd_socket = prependdir(optarg, currentwd);
+           break;
+       case 'G':
+           ctl->pwmd_file = xstrdup(optarg);
+           break;
+       case 'O':
+           rctl->pinentry_timeout = atoi(optarg);
+           break;
+#endif
        case 'V':
            versioninfo = TRUE;
            break;
@@ -637,6 +658,12 @@ int parsecmdline (int argc /** argument count */,
        P(GT_("      --plugout     specify external command to open smtp connection\n"));
 
        P(GT_("  -p, --protocol    specify retrieval protocol (see man page)\n"));
+#ifdef HAVE_LIBPWMD
+        P(GT_("  -C, --pwmd-socket pwmd socket path (~/.pwmd/socket)\n"));
+        P(GT_("  -G, --pwmd-file   filename to use on the pwmd server\n"));
+        P(GT_("  -O, --pinentry-timeout   seconds until pinentry is canceled\n"));
+#endif
        P(GT_("  -U, --uidl        force the use of UIDLs (pop3 only)\n"));
        P(GT_("      --port        TCP port to connect to (obsolete, use --service)\n"));
        P(GT_("  -P, --service     TCP service to connect to (can be numeric TCP port)\n"));
index 67317a6bad7bf7088a2287e39dcd9006e82a40d7..8e77584313ae891cb59a7ecf320b44aee6cf6da7 100644 (file)
@@ -116,6 +116,9 @@ esmtppassword       { return ESMTPPASSWORD; }
 
 
 user(name)?    {SETSTATE(NAME); return USERNAME; }
+pwmd_socket    { return PWMD_SOCKET; }
+pwmd_file      { return PWMD_FILE; }
+pinentry_timeout       { return PINENTRY_TIMEOUT; }
 <INITIAL,NAME>pass(word)?      {SETSTATE(NAME); return PASSWORD; }
 folder(s)?     { return FOLDER; }
 smtp(host)?    { return SMTPHOST; }
index c28c6b42d015ec3583e1be0bd1ab119b1a945847..0850f717bf3df8722b020b66f708dcc05f969748 100644 (file)
@@ -63,7 +63,7 @@ extern char * yytext;
 
 %token DEFAULTS POLL SKIP VIA AKA LOCALDOMAINS PROTOCOL
 %token AUTHENTICATE TIMEOUT KPOP SDPS ENVELOPE QVIRTUAL
-%token USERNAME PASSWORD FOLDER SMTPHOST FETCHDOMAINS MDA BSMTP LMTP
+%token PINENTRY_TIMEOUT PWMD_SOCKET PWMD_FILE USERNAME PASSWORD FOLDER SMTPHOST FETCHDOMAINS MDA BSMTP LMTP
 %token SMTPADDRESS SMTPNAME SPAMRESPONSE PRECONNECT POSTCONNECT LIMIT WARNINGS
 %token INTERFACE MONITOR PLUGIN PLUGOUT
 %token IS HERE THERE TO MAP WILDCARD
@@ -111,6 +111,13 @@ statement  : SET LOGFILE optmap STRING     {run.logfile = prependdir ($4, rcfiledir);
                | SET NO INVISIBLE              {run.invisible = FALSE;}
                | SET SHOWDOTS                  {run.showdots = FLAG_TRUE;}
                | SET NO SHOWDOTS               {run.showdots = FLAG_FALSE;}
+               | SET PINENTRY_TIMEOUT optmap NUMBER {
+#ifdef HAVE_LIBPWMD
+                   run.pinentry_timeout = $4;
+#else
+                   yyerror(GT_("pwmd not enabled"));
+#endif 
+                   }
 
 /* 
  * The way the next two productions are written depends on the fact that
@@ -367,6 +374,22 @@ user_option        : TO localnames HERE
                | EXPUNGE NUMBER        {current.expunge     = NUM_VALUE_IN($2);}
 
                | PROPERTIES STRING     {current.properties  = xstrdup($2);}
+
+               | PWMD_SOCKET STRING    {
+#ifdef HAVE_LIBPWMD
+                   current.pwmd_socket = xstrdup($2);
+#else
+                   yyerror(GT_("pwmd not enabled"));
+#endif 
+                                       }
+
+               | PWMD_FILE STRING      {
+#ifdef HAVE_LIBPWMD
+                   current.pwmd_file = xstrdup($2);
+#else
+                   yyerror(GT_("pwmd not enabled"));
+#endif 
+                                       }
                ;
 %%