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)
libesmtp/gethostbyname.h libesmtp/gethostbyname.c \
smbtypes.h fm_getaddrinfo.c tls.c rfc822valid.c \
xmalloc.h sdump.h sdump.c x509_name_match.c \
- fm_strl.h
+ fm_strl.h md5c.c
if NTLM_ENABLE
libfm_a_SOURCES += ntlmsubr.c
endif
# MAJOR CHANGES
* The UIDL handler code is now much faster, especially noticable with lots of
mail kept on a POP3 server. Where the 6.3.X code was of O(n^2) complexity,
- we're down to O(n log n). (Rainer Weikusat, MAD Partners Ltd./MSS GmbH).
+ we're down to O(n log n).
+ Contributed by Rainer Weikusat, MAD Partners Ltd./MSS GmbH.
+* Fetchmail can now retrieve credentials from PWMD. This needs to be enabled at
+ compile-time and requires run-time configuration. See README.PWMD for details.
+ Contributed by Ben Kibbey, author of libpwmd and pwmd.
# REMOVED FEATURES
* POP2 and RPOP were long obsolete and removed
--------------------------------------------------------------------------------
-not yet released:
+fetchmail-6.3.20 (not yet released):
+
+# CHANGES
+* fetchmail now always uses its own MD5 implementation. The library and header
+ variants are too diverse, and we've been bitten before -- and configure
+ complains noisily on Cyrus-SASL's RFC1321 md5.h.
# TRANSLATION UPDATES
[ja] Japanese (Takeshi Hamasaki)
--- /dev/null
+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/.
AC_MSG_ERROR(no SUS compliant shell found - on Solaris, install SUNWxcu4)
fi
-
-AC_CHECK_HEADERS([arpa/nameser.h md5.h])
+AC_CHECK_HEADERS([arpa/nameser.h])
AC_CHECK_HEADERS([resolv.h],,,[
#include <sys/types.h>
AC_REPLACE_FUNCS([stpcpy strlcpy strlcat])
-have_md5=no
-if test "$ac_cv_header_md5_h" != no ; then
- AC_SEARCH_LIBS(MD5Init, [md], [have_md5=yes])
-fi
-
-if test "$have_md5" != yes ; then
- AC_LIBSOURCE(md5c.c)
- EXTRAOBJ="$EXTRAOBJ md5c.\$(OBJEXT)"
-fi
-
AC_CHECK_FUNC(getopt_long, [],
[AC_LIBSOURCES([getopt.c, getopt1.c])
EXTRAOBJ="$EXTRAOBJ getopt.\$(OBJEXT) getopt1.\$(OBJEXT)"])
AC_DEFINE_UNQUOTED(PID_DIR, "/var/run", 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.
static void terminate_run(int);
static void 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)
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;
#ifdef KERBEROS_V5
"+KRB5"
#endif /* KERBEROS_V5 */
+#ifdef HAVE_LIBPWMD
+ "+PWMD"
+#endif /* HAVE_LIBPWMD */
".\n";
printf(GT_("This is fetchmail release %s"), VERSION);
fputs(features, stdout);
* leaks...
*/
struct stat rcstat;
+#ifdef HAVE_LIBPWMD
+ time_t now;
+
+ time(&now);
+#endif
if (strcmp(rcfile, "-") == 0) {
/* do nothing */
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);
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))
}
}
+#ifdef HAVE_LIBPWMD
+ if (pwm) {
+ pwmd_close(pwm);
+ pwm = NULL;
+ }
+#endif
+
/* close connections cleanly */
terminate_poll(0);
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++)
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)
* call later on.
*/
ctl = hostalloc((struct query *)NULL);
+
+#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;
}
#include "uid_db.h"
+#ifdef HAVE_LIBPWMD
+#include <libpwmd.h>
+#endif
+
/* constants designating the various supported protocols */
#define P_AUTO 1
#define P_POP3 3
char *pidfile; /** where to record the PID of daemon mode processes */
const 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;
struct idlist *akalist; /* server name first, then akas */
struct idlist *localdomains; /* list of pass-through domains */
int protocol; /* protocol type */
- const char *service; /* service name */
+ char *service; /* service name */
int interval; /* # cycles to skip between polls */
int authenticate; /* authentication mode to try */
int timeout; /* inactivity timout in seconds */
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 */
void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, const void *buf, unsigned len);
void MD5Final(void *digest, struct MD5Context *context);
-void MD5Transform(uint32_t buf[], uint32_t const in[]);
+void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
/*
* This is needed to make RSAREF happy on some MS-DOS compilers.
LA_RETRIEVEERROR
};
-/* options still left: CgGhHjJoORTWxXYz */
-static const char *shortoptions =
+static const char *shortoptions =
+/* options still left: ghHjJoRTWxXYz */
+#ifdef HAVE_LIBPWMD
+ "O:C:G:"
+#endif
"?Vcsvd:NqL:f:i:p:UP:A:t:E:Q:u:akKFnl:r:S:Z:b:B:e:m:I:M:yw:D:";
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' },
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;
" specify policy for processing messages with retrieve errors\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"));
markseen { return MARKSEEN; }
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; }
%token DEFAULTS POLL SKIP VIA AKA LOCALDOMAINS PROTOCOL
%token AUTHENTICATE TIMEOUT KPOP SDPS ENVELOPE QVIRTUAL
+%token PINENTRY_TIMEOUT PWMD_SOCKET PWMD_FILE
%token USERNAME PASSWORD FOLDER SMTPHOST FETCHDOMAINS MDA BSMTP LMTP
%token SMTPADDRESS SMTPNAME SPAMRESPONSE PRECONNECT POSTCONNECT LIMIT WARNINGS
%token INTERFACE MONITOR PLUGIN PLUGOUT
| 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
| EXPUNGE NUMBER {current.expunge = NUM_VALUE_IN($2);}
| PROPERTIES STRING {current.properties = $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
+ }
;
%%