diff -ruN fetchmail-6.3.8.orig/configure.ac fetchmail-6.3.8/configure.ac
--- fetchmail-6.3.8.orig/configure.ac	2007-04-06 14:10:58.000000000 -0400
+++ fetchmail-6.3.8/configure.ac	2007-07-21 15:09:48.000000000 -0400
@@ -256,6 +256,22 @@
 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 >= 4.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.
diff -ruN fetchmail-6.3.8.orig/fetchmail.c fetchmail-6.3.8/fetchmail.c
--- fetchmail-6.3.8.orig/fetchmail.c	2007-03-30 03:52:16.000000000 -0400
+++ fetchmail-6.3.8/fetchmail.c	2007-07-21 15:18:21.000000000 -0400
@@ -146,6 +146,92 @@
 
 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);
+
+    exit(PS_UNDEFINED);
+}
+
+static void set_pwmd_pinentry_strings(const char *filename)
+{
+    char buf[255];
+    gpg_error_t error;
+
+    /*
+     * Use pinentry for password retrieval. Since version 0.3 of pwmd
+     * there is an option to push files into the file cache when the
+     * server starts up. For a daemonized fetchmail, this may be
+     * required because there won't be a way to get the key without a
+     * tty that pinentry requires.
+     */
+    error = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY, 1);
+
+    if (error)
+	exit_with_pwmd_error(error);
+
+    if (pwmd_pinentry_path) {
+	error = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_PATH, pwmd_pinentry_path);
+
+	if (error)
+	    exit_with_pwmd_error(error);
+    }
+
+    /*
+     * Set the text to be used in the pinentry dialog.
+     */
+    error = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_TITLE, 
+		    GT_("Password Manager Daemon: Fetchmail"));
+
+    if (error)
+	exit_with_pwmd_error(error);
+
+    snprintf(buf, sizeof(buf), 
+	    GT_("A password is needed to open the file \"%s\". Please\n"
+	    "enter the password below."), filename);
+
+    error = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_DESC, buf);
+
+    if (error)
+	exit_with_pwmd_error(error);
+}
+
+static void pwmd_do_connect(const char *socketname, const char *filename)
+{
+    static int init;
+    gpg_error_t error;
+
+    if (!init) {
+	pwmd_init();
+	init = 1;
+    }
+
+    /*
+     * Try and connect to pwmd.
+     */
+    if ((pwm = pwmd_connect(socketname, &error)) == NULL)
+	exit_with_pwmd_error(error);
+
+    set_pwmd_pinentry_strings(filename);
+
+    /*
+     * Try and open the file so we can later get account/server credentials. If
+     * the file is not cached on the server, pinentry(1) will ask for the
+     * password.
+     */
+    error = pwmd_open(pwm, filename);
+
+    if (error)
+	exit_with_pwmd_error(error);
+}
+#endif
+
 int main(int argc, char **argv)
 {
     int bkgd = FALSE;
@@ -276,6 +362,9 @@
 #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);
@@ -988,6 +1077,166 @@
 #undef FLAG_MERGE
 }
 
+#ifdef HAVE_LIBPWMD
+static char *protocol_to_service(int protocol)
+{
+    switch (protocol) {
+#ifdef POP2_ENABLE
+	case P_POP2:
+	    return "POP2";
+#endif
+#ifdef POP3_ENABLE
+	case P_POP3:
+	    return "POP3";
+#endif
+#ifdef IMAP_ENABLE
+	case P_IMAP:
+	    return "IMAP";
+#endif
+	case P_APOP:
+	    return "APOP";
+	case P_RPOP:
+	    return "RPOP";
+	case P_ETRN:
+	    return "ETRN";
+	case P_ODMR:
+	    return "ODMR";
+	default:
+	    return NULL;
+    }
+
+    return NULL;
+}
+
+static int get_pwmd_details(const char *pwmd_account, int protocol,
+	struct query *ctl)
+{
+    char *prot = protocol_to_service(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) == EPWMD_ELEMENT_NOT_FOUND) {
+	    report(stderr, GT_("pwmd: %s->%s->hostname: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+	    pwmd_close(pwm);
+	    exit(PS_SYNTAX);
+	}
+	else 
+	    exit_with_pwmd_error(error);
+    }
+
+    ctl->server.pollname = xstrdup(pwmd_account);
+    ctl->server.via = xstrdup(result);
+    pwmd_free_result(result);
+
+    /*
+     * Server port. Element path must be account->[protocol]->port. Should be
+     * required because the element path wouldn't exist with out it. But
+     * maybe not because fetchmail trys standard ports if not specified. This
+     * may be a security risk. Might be better to have 'ssl' required.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\tport", tmp, prot);
+
+    if (error) {
+	if (gpg_err_code(error) == EPWMD_ELEMENT_NOT_FOUND) {
+	    report(stderr, GT_("pwmd: %s->%s->port: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+	    pwmd_close(pwm);
+	    exit(PS_SYNTAX);
+	}
+	else
+	    exit_with_pwmd_error(error);
+    }
+
+    ctl->server.service = xstrdup(result);
+    pwmd_free_result(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) == EPWMD_ELEMENT_NOT_FOUND)
+	    report(stderr, GT_("pwmd: %s->username: %s\n"), pwmd_account, pwmd_strerror(error));
+	else
+	    exit_with_pwmd_error(error);
+    }
+    else {
+	ctl->remotename = xstrdup(result);
+	ctl->server.esmtp_name = xstrdup(result);
+	pwmd_free_result(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) == EPWMD_ELEMENT_NOT_FOUND)
+	    report(stderr, GT_("pwmd: %s->password: %s\n"), pwmd_account, pwmd_strerror(error));
+	else
+	    exit_with_pwmd_error(error);
+    }
+    else {
+	ctl->password= xstrdup(result);
+	pwmd_free_result(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) == EPWMD_ELEMENT_NOT_FOUND)
+	    report(stderr, GT_("pwmd: %s->%s->ssl: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+	else
+	    exit_with_pwmd_error(error);
+    }
+    else {
+	ctl->use_ssl = atoi(result);
+	ctl->use_ssl = (ctl->use_ssl >= 1) ? FLAG_TRUE : FLAG_FALSE;
+	pwmd_free_result(result);
+    }
+
+    /*
+     * account->[protocol]->sslfingerprint.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\tsslfingerprint", tmp, prot);
+
+    if (error) {
+	if (gpg_err_code(error) == EPWMD_ELEMENT_NOT_FOUND)
+	    report(stderr, GT_("pwmd: %s->%s->sslfingerprint: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+	else
+	    exit_with_pwmd_error(error);
+    }
+    else {
+	ctl->sslfingerprint = xstrdup(result);
+	pwmd_free_result(result);
+    }
+#endif
+
+    xfree(tmp);
+    return 0;
+}
+#endif
+
 /** Load configuration files.
  * \return - true if no servers found on the command line
  *         - false if servers found on the command line */
@@ -1045,8 +1294,31 @@
 
     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);
+		}
+
+		pwmd_do_connect(ctl->pwmd_socket, ctl->pwmd_file);
+		get_pwmd_details(ctl->server.pollname, 
+			ctl->server.protocol, ctl);
+		pwmd_close(pwm);
+	    }
+	}
+#else
 	for (ctl = querylist; ctl; ctl = ctl->next)
 	    ctl->active = !ctl->server.skip;
+#endif
     }
     else
 	for (; optind < argc; optind++) 
@@ -1067,6 +1339,24 @@
 			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);
+			}
+
+			pwmd_do_connect(ctl->pwmd_socket, ctl->pwmd_file);
+			get_pwmd_details(ctl->server.pollname, 
+				ctl->server.protocol, ctl);
+			pwmd_close(pwm);
+		    }
+#endif
 		}
 
 	    if (!predeclared)
@@ -1077,8 +1367,29 @@
 		 * 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);
+		    }
+
+		    pwmd_do_connect(cmd_opts.pwmd_socket, cmd_opts.pwmd_file);
+		    get_pwmd_details(argv[optind], cmd_opts.server.protocol,
+			    ctl);
+		    pwmd_close(pwm);
+		}
+		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;
 	    }
diff -ruN fetchmail-6.3.8.orig/fetchmail.h fetchmail-6.3.8/fetchmail.h
--- fetchmail-6.3.8.orig/fetchmail.h	2007-03-17 21:11:43.000000000 -0400
+++ fetchmail-6.3.8/fetchmail.h	2007-07-21 15:09:50.000000000 -0400
@@ -39,6 +39,10 @@
 #  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 *);
@@ -313,6 +317,11 @@
     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 */
@@ -455,6 +464,10 @@
 extern char *sdps_envfrom;
 extern char *sdps_envto;
 #endif /* SDPS_ENABLE */
+#ifdef HAVE_LIBPWMD
+pwm_t *pwm;			/* the handle */
+char *pwmd_pinentry_path;	/* location of the pinentry binary */
+#endif
 
 extern const char *iana_charset;	/* IANA assigned charset name */
 
diff -ruN fetchmail-6.3.8.orig/Makefile.am fetchmail-6.3.8/Makefile.am
--- fetchmail-6.3.8.orig/Makefile.am	2007-04-06 14:09:17.000000000 -0400
+++ fetchmail-6.3.8/Makefile.am	2007-07-21 15:09:50.000000000 -0400
@@ -18,6 +18,11 @@
 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 -ruN fetchmail-6.3.8.orig/options.c fetchmail-6.3.8/options.c
--- fetchmail-6.3.8.orig/options.c	2006-08-14 19:04:02.000000000 -0400
+++ fetchmail-6.3.8/options.c	2007-07-21 15:09:50.000000000 -0400
@@ -53,12 +53,22 @@
     LA_IDLE
 };
 
+#ifdef HAVE_LIBPWMD
+static const char *shortoptions = 
+	"C:G:Y:?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-path",    required_argument,         (int *) 0, 'Y' },
+#endif
   {"help",	no_argument,	   (int *) 0, '?' },
   {"version",	no_argument,	   (int *) 0, 'V' },
   {"check",	no_argument,	   (int *) 0, 'c' },
@@ -248,6 +258,17 @@
 			    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 'Y':
+	    pwmd_pinentry_path = xstrdup(optarg);
+	    break;
+#endif
 	case 'V':
 	    versioninfo = TRUE;
 	    break;
@@ -618,6 +639,12 @@
 	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_("  -Y, --pinentry-path   path of the pinentry binary\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"));
diff -ruN fetchmail-6.3.8.orig/rcfile_l.l fetchmail-6.3.8/rcfile_l.l
--- fetchmail-6.3.8.orig/rcfile_l.l	2006-08-14 19:04:02.000000000 -0400
+++ fetchmail-6.3.8/rcfile_l.l	2007-07-21 15:09:50.000000000 -0400
@@ -114,6 +114,8 @@
 
 
 user(name)?	{SETSTATE(NAME); return USERNAME; }
+pwmd_socket	{ return PWMD_SOCKET; }
+pwmd_file	{ return PWMD_FILE; }
 <INITIAL,NAME>pass(word)?	{SETSTATE(NAME); return PASSWORD; }
 folder(s)? 	{ return FOLDER; }
 smtp(host)?	{ return SMTPHOST; }
diff -ruN fetchmail-6.3.8.orig/rcfile_y.y fetchmail-6.3.8/rcfile_y.y
--- fetchmail-6.3.8.orig/rcfile_y.y	2006-12-08 07:09:09.000000000 -0500
+++ fetchmail-6.3.8/rcfile_y.y	2007-07-21 15:09:50.000000000 -0400
@@ -63,7 +63,7 @@
 
 %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 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
@@ -243,6 +243,20 @@
 userdef		: USERNAME STRING	{current.remotename = xstrdup($2);}
 		| USERNAME mapping_list HERE
 		| USERNAME STRING THERE	{current.remotename = 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 
+					}
 		;
 
 user0opts	: /* EMPTY */
diff -ruN fetchmail-6.3.8.orig/README.pwmd fetchmail-6.3.8/README.pwmd
--- fetchmail-6.3.8.orig/README.pwmd	1969-12-31 19:00:00.000000000 -0500
+++ fetchmail-6.3.8/README.pwmd	2007-07-21 17:17:55.000000000 -0400
@@ -0,0 +1,45 @@
+When compiled with pwmd (Password Manager Daemon) support (--enable-pwmd),
+fetchmail can retrieve server details from pwmd. Two new configuration
+parameters are added: pwmd_socket (optional) to specify the socket to connect
+to (default is ~/.pwmd/socket) and pwmd_file (required) which specifies the
+filename on the server to open.
+
+Three new command line options are added:
+    --pwmd-socket, -C	same as pwmd_socket
+    --pwmd-file, -G	same as pwmd_file
+    --pinentry-path, -Y the full path of the pinentry program
+			(/usr/bin/pinentry)
+
+The data that fetchmail will use is stored in an encrypted XML file and has
+the following structure:
+
+    <account name="pollname">
+	<username>		- Optional (--username/username)
+	<password>		- Optional (--password/password)
+	<protocol>		- POP3/IMAP/etc.
+	    <hostname>		- Required (servername/via)
+	    <port>		- Required (--service/protocol)
+	    <ssl>		- Optional (--ssl/ssl)
+	    <sslfingerprint>	- Optional (--sslfingerprint/sslfingerprint)
+	</protocol>
+    </account>
+
+An account (pollname) may be an element path. Instead of separating the
+elements with a TAB character, separate them with a '!'. A minimal fetchmailrc
+might look like this:
+
+poll isp proto POP3:
+    pwmd_file default
+
+poll myaccounts!isp proto POP3:
+    pwmd_file default
+
+Or from the command line:
+    fetchmail -f fetchmailrc isp
+    fetchmail --pwmd-file somefile -p POP3 isp
+
+The password to open the encrypted data file is either cached on the server
+(the file has been opened before), or gotten from pinentry(1).
+
+Ben Kibbey <bjk@luxsci.net>
+http://bjk.sourceforge.net/pwmd/.
