aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--conf.c3
-rw-r--r--driver.c5
-rw-r--r--fetchmail-FAQ.html30
-rw-r--r--fetchmail.c11
-rw-r--r--fetchmail.h2
-rw-r--r--fetchmail.man22
-rwxr-xr-xfetchmailconf4
-rw-r--r--options.c22
-rw-r--r--rcfile_l.l2
-rw-r--r--rcfile_y.y4
-rw-r--r--sample.rcfile2
-rw-r--r--sink.c6
-rw-r--r--socket.c85
-rw-r--r--socket.h6
15 files changed, 166 insertions, 39 deletions
diff --git a/NEWS b/NEWS
index b8b52a72..3a7fefff 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ fetchmail-4.6.6 (Fri Oct 30 11:34:20 EST 1998):
* Fixed a core-dump bug in reply_hack with -v -v on.
* Fix fetchmailconf to be able to edit properties.
* Send calling user mail when password authentication fails in daemon mode.
+* Added plugin/plugout features from Felix von Leitner.
There are 247 people on fetchmail-friends and 308 on fetchmail-announce.
diff --git a/conf.c b/conf.c
index e9884f22..7625516b 100644
--- a/conf.c
+++ b/conf.c
@@ -270,6 +270,9 @@ void dump_config(struct runctl *runp, struct query *querylist)
stringdump("monitor", ctl->server.monitor);
#endif /* linux */
+ stringdump("plugin", ctl->server.plugin);
+ stringdump("plugout", ctl->server.plugout);
+
indent(0);
fputs("'users': ", stdout);
indent('[');
diff --git a/driver.c b/driver.c
index 33c3b48b..b1617fca 100644
--- a/driver.c
+++ b/driver.c
@@ -1446,9 +1446,10 @@ const struct method *proto; /* protocol method table */
#if INET6
if ((sock = SockOpen(realhost,
ctl->server.service ? ctl->server.service : protocol->service,
- ctl->server.netsec)) == -1)
+ ctl->server.netsec)) == -1, ctl->server.plugin
+ )
#else /* INET6 */
- if ((sock = SockOpen(realhost, port, NULL)) == -1)
+ if ((sock = SockOpen(realhost, port, NULL, ctl->server.plugin)) == -1)
#endif /* INET6 */
{
#if !INET6
diff --git a/fetchmail-FAQ.html b/fetchmail-FAQ.html
index c22d58ae..eeacab2f 100644
--- a/fetchmail-FAQ.html
+++ b/fetchmail-FAQ.html
@@ -10,7 +10,7 @@
<table width="100%" cellpadding=0><tr>
<td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
<td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 1998/10/29 18:21:39 $
+<td width="30%" align=right>$Date: 1998/11/02 16:25:06 $
</table>
<HR>
<H1>Frequently Asked Questions About Fetchmail</H1>
@@ -81,6 +81,7 @@ IP address?</a><br>
<a href="#K2">K2. How can I use fetchmail with IPv6 and IPsec?</a><br>
<a href="#K3">K3. How can I get fetchmail to work with ssh?</a><br>
<a href="#K4">K4. What do I have to do to use the IMAP-GSS protocol?</a><br>
+<a href="#K5">K5. How can I use fetchmail with SSL?</a><br>
<h1>Runtime fatal errors:</h1>
@@ -1468,6 +1469,31 @@ Now you don't have to worry about your password appearing in cleartext in
your .fetchmailrc, or across the network.<p>
<hr>
+<h2><a name="K5">K5. How can I use fetchmail with SSL?</a></h2>
+
+The U.S. government's never-to-be-sufficiently-damned EAR regulations
+prevent me from including SSL library hooks in the distribution.
+However, the First Amendment of the U.S. Constitution hasn't been
+eviscerated (not yet, anyway -- our would-be totalitarians are still
+working on trashing the Second Amendment).<P>
+
+I can therefore <em>tell</em> you, in documentation, that there
+appears to be a way to set up an SSL command chain using the `plugin'
+option (originally designed for handling proxy connections across
+firewalls).<P>
+
+Get your hands on the <a
+href="http://www.psy.uq.edu.au:8080/~ftp/Crypto/">SSLEay</a> code.
+Now make yourself a script called `ssl_connect' that calls the SSLeay
+utility `s_client' as follows:<P>
+
+<pre>
+/usr/local/ssl/bin/s_client -quiet -ssl2 -connect $1:$2
+</pre>
+
+Now add `plugin ssl_connect' to the server options for your connection.<P>
+
+<hr>
<h2><a name="R1">R1. Fetchmail isn't working, and -v shows `SMTP connect failed' messages.</a></h2>
Fetchmail itself is probably working, but your SMTP port 25 listener
@@ -2184,7 +2210,7 @@ Re-ordering messages is a user-agent function, anyway.<P>
<table width="100%" cellpadding=0><tr>
<td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
<td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 1998/10/29 18:21:39 $
+<td width="30%" align=right>$Date: 1998/11/02 16:25:06 $
</table>
<P><ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com">&lt;esr@snark.thyrsus.com&gt;</A></ADDRESS>
diff --git a/fetchmail.c b/fetchmail.c
index 75b9d573..ef40f0b9 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -759,6 +759,8 @@ static void optmerge(struct query *h2, struct query *h1, int force)
FLAG_MERGE(server.interface_pair);
#endif /* linux */
+ FLAG_MERGE(server.plugin);
+ FLAG_MERGE(server.plugout);
FLAG_MERGE(wildcard);
FLAG_MERGE(remotename);
FLAG_MERGE(password);
@@ -1491,6 +1493,15 @@ void dump_params (struct runctl *runp, struct query *querylist, flag implicit)
printf(" No monitor interface specified.\n");
#endif
+ if (ctl->server.plugin)
+ printf(" Server connections will be mode via plugin %s (--plugin %s).\n", ctl->server.plugin, ctl->server.plugin);
+ else if (outlevel >= O_VERBOSE)
+ printf(" No plugin command specified.\n");
+ if (ctl->server.plugout)
+ printf(" Listener connections will be mode via plugout %s (--plugout %s).\n", ctl->server.plugout, ctl->server.plugout);
+ else if (outlevel >= O_VERBOSE)
+ printf(" No plugout command specified.\n");
+
if (ctl->server.protocol > P_POP2 && (ctl->server.protocol != P_ETRN))
if (!ctl->oldsaved)
printf(" No UIDs saved from this host.\n");
diff --git a/fetchmail.h b/fetchmail.h
index 65780434..721a4b8a 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -199,6 +199,8 @@ struct hostdata /* shared among all user connections to given server */
struct interface_pair_s *interface_pair;
#endif /* linux */
+ char *plugin,*plugout;
+
/* computed for internal use */
const struct method *base_protocol; /* relevant protocol method table */
int poll_count; /* count of polls so far */
diff --git a/fetchmail.man b/fetchmail.man
index 0d33e005..27bdc69d 100644
--- a/fetchmail.man
+++ b/fetchmail.man
@@ -223,6 +223,20 @@ down host. This would be particularly annoying for a \fIfetchmail\fR
running in background. There is a default timeout which fetchmail -V
will report.
.TP
+.B \--plugin
+(Keyword: plugin)
+The plugin option allows you to use an external program to establish the
+TCP connection. This is useful if you want to use socks or need some
+special firewalling setup. The program will be looked up in $PATH and
+it will be passed two arguments: the name of the server and the name of
+the port.
+.TP
+.B \--plugout
+(Keyword: plugout)
+Identical to the plugin option above, but this one is used for the SMTP
+connections (which will probably not need it, so it has been separated
+from plugin).
+.TP
.B \-r folder, --folder folder
(Keyword: folder[s])
Causes a specified non-default mail folder on the mailserver (or
@@ -898,7 +912,7 @@ Turn off error logging through syslog(3).
T}
.TE
-Here are the legal user options:
+Here are the legal server options:
.TS
l l lw34.
@@ -938,6 +952,12 @@ T}
monitor -M T{
Specify IP address to monitor for activity
T}
+plugin \& T{
+Specify command through which to make server connections.
+T}
+plugout \& T{
+Specify command through which to make listener connections.
+T}
dns \& T{
Enable DNS lookup for multidrop (default)
T}
diff --git a/fetchmailconf b/fetchmailconf
index 5973f81b..52d01c95 100755
--- a/fetchmailconf
+++ b/fetchmailconf
@@ -71,6 +71,8 @@ class Server:
self.localdomains = [] # Domains to be considered local
self.interface = None # IP address and range
self.monitor = None # IP address and range
+ self.plugin = None # Plugin command for going to server
+ self.plugout = None # Plugin command for going to listener
self.netsec = None # IPV6 security options
self.users = [] # List of user entries for site
Server.typemap = (
@@ -92,6 +94,8 @@ class Server:
# leave localdomains out
('interface', 'String'),
('monitor', 'String'),
+ ('plugin', 'String'),
+ ('plugout', 'String'),
('netsec', 'String'))
def dump(self, folded):
diff --git a/options.c b/options.c
index f173dd3a..5a8d2c07 100644
--- a/options.c
+++ b/options.c
@@ -59,11 +59,13 @@
#define LA_EXPUNGE 37
#define LA_MDA 38
#define LA_BSMTP 39
-#define LA_NETSEC 40
-#define LA_INTERFACE 41
-#define LA_MONITOR 42
-#define LA_CONFIGDUMP 43
-#define LA_YYDEBUG 44
+#define LA_PLUGIN 40
+#define LA_PLUGOUT 41
+#define LA_NETSEC 42
+#define LA_INTERFACE 43
+#define LA_MONITOR 44
+#define LA_CONFIGDUMP 45
+#define LA_YYDEBUG 46
/* options still left: CDgGhHjJoORwWxXYz */
static const char *shortoptions =
@@ -126,6 +128,8 @@ static const struct option longoptions[] = {
{"interface", required_argument, (int *) 0, LA_INTERFACE },
{"monitor", required_argument, (int *) 0, LA_MONITOR },
#endif /* defined(linux) && !INET6 */
+ {"plugin", required_argument, (int *) 0, LA_PLUGIN },
+ {"plugout", required_argument, (int *) 0, LA_PLUGOUT },
{"configdump",no_argument, (int *) 0, LA_CONFIGDUMP },
@@ -495,6 +499,12 @@ struct query *ctl; /* option record to be initialized */
ctl->server.monitor = xstrdup(optarg);
break;
#endif /* defined(linux) && !INET6 */
+ case LA_PLUGIN:
+ ctl->server.plugin = xstrdup(optarg);
+ break;
+ case LA_PLUGOUT:
+ ctl->server.plugout = xstrdup(optarg);
+ break;
case 'y':
case LA_YYDEBUG:
@@ -550,6 +560,8 @@ struct query *ctl; /* option record to be initialized */
P(" -I, --interface interface required specification\n");
P(" -M, --monitor monitor interface for activity\n");
#endif
+ P(" --plugin specify external command to open connection\n");
+ P(" --plugout specify external command to open smtp connection\n");
P(" -p, --protocol specify retrieval protocol (see man page)\n");
P(" -U, --uidl force the use of UIDLs (pop3 only)\n");
diff --git a/rcfile_l.l b/rcfile_l.l
index ce67630f..f573c716 100644
--- a/rcfile_l.l
+++ b/rcfile_l.l
@@ -62,6 +62,8 @@ post(connect)? { return POSTCONNECT; }
netsec { return NETSEC; }
interface { return INTERFACE; }
monitor { return MONITOR; }
+plugin { return PLUGIN; }
+plugout { return PLUGIN; }
batchlimit { return BATCHLIMIT; }
fetchlimit { return FETCHLIMIT; }
expunge { return EXPUNGE; }
diff --git a/rcfile_y.y b/rcfile_y.y
index 044cf0c3..12851030 100644
--- a/rcfile_y.y
+++ b/rcfile_y.y
@@ -61,7 +61,7 @@ extern char * yytext;
%token AUTHENTICATE TIMEOUT KPOP SDPS KERBEROS4 KERBEROS5 KERBEROS
%token ENVELOPE QVIRTUAL USERNAME PASSWORD FOLDER SMTPHOST MDA BSMTP
%token SMTPADDRESS SPAMRESPONSE PRECONNECT POSTCONNECT LIMIT
-%token NETSEC INTERFACE MONITOR
+%token NETSEC INTERFACE MONITOR PLUGIN PLUGOUT
%token IS HERE THERE TO MAP WILDCARD
%token BATCHLIMIT FETCHLIMIT EXPUNGE PROPERTIES
%token SET LOGFILE DAEMON SYSLOG IDFILE INVISIBLE POSTMASTER WARNINGS
@@ -219,6 +219,8 @@ serv_option : AKA alias_list
fprintf(stderr, "fetchmail: monitor option is only supported under Linux\n");
#endif /* defined(linux) && !defined(INET6) */
}
+ | PLUGIN STRING { current.server.plugin = xstrdup($2); }
+ | PLUGOUT STRING { current.server.plugout = xstrdup($2); }
| DNS {current.server.dns = FLAG_TRUE;}
| NO DNS {current.server.dns = FLAG_FALSE;}
| NO ENVELOPE {current.server.envelope = STRING_DISABLED;}
diff --git a/sample.rcfile b/sample.rcfile
index 158b387b..5840292d 100644
--- a/sample.rcfile
+++ b/sample.rcfile
@@ -36,6 +36,8 @@
# localdomains -- must be followed by one or more domain names
# interface -- must be followed by device/IP address/mask
# monitor -- must be followed by device
+# plugin -- must be followed by a string command name
+# plugout -- must be followed by a string command name
# dns
# no dns
# checkalias -- do multidrop address comparison by IP address
diff --git a/sink.c b/sink.c
index 14aa8fc4..17e6406c 100644
--- a/sink.c
+++ b/sink.c
@@ -111,7 +111,8 @@ static int smtp_open(struct query *ctl)
#endif /* INET6 */
}
- if ((ctl->smtp_socket = SockOpen(parsed_host,portnum,NULL)) == -1)
+ if ((ctl->smtp_socket = SockOpen(parsed_host,portnum,NULL,
+ ctl->server.plugout)) == -1)
continue;
/* first, probe for ESMTP */
@@ -128,7 +129,8 @@ static int smtp_open(struct query *ctl)
ctl->smtp_socket = -1;
/* if opening for ESMTP failed, try SMTP */
- if ((ctl->smtp_socket = SockOpen(parsed_host,portnum,NULL)) == -1)
+ if ((ctl->smtp_socket = SockOpen(parsed_host,portnum,NULL,
+ ctl->server.plugout)) == -1)
continue;
if (SMTP_ok(ctl->smtp_socket) == SM_OK &&
diff --git a/socket.c b/socket.c
index 94d3e56b..5710796c 100644
--- a/socket.c
+++ b/socket.c
@@ -42,43 +42,73 @@ static int h_errno;
#include <net/security.h>
#endif /* NET_SECURITY */
+static int handle_plugin(const char *host,
+ const char *service, const char *plugin)
+/* get a socket mediated through a given external command */
+{
+ if (plugin)
+ {
+ int fds[2];
+ if (socketpair(AF_UNIX,SOCK_STREAM,0,fds))
+ {
+ error(0, 0, "fetchmail: socketpair failed: %s(%d)",strerror(errno),errno);
+ return -1;
+ }
+ if (!fork())
+ {
+ dup2(fds[0],0);
+ dup2(fds[0],1);
+ if (outlevel >= O_VERBOSE)
+ error(0, 0, "running %s %s %s", plugin, host, service);
+ execlp(plugin,plugin,host,service,0);
+ error(0, 0, "execl(%s) failed: %s (%d)",
+ plugin, strerror(errno), errno);
+ exit(0);
+ }
+ return fds[1];
+ }
+}
+
#if INET6
-int SockOpen(const char *host, const char *service, const char *options)
+int SockOpen(const char *host, const char *service, const char *options,
+ const char *plugin)
{
- int i;
- struct addrinfo *ai, req;
+ int i;
+ struct addrinfo *ai, req;
#if NET_SECURITY
- void *request = NULL;
- int requestlen;
+ void *request = NULL;
+ int requestlen;
#endif /* NET_SECURITY */
- memset(&req, 0, sizeof(struct addrinfo));
- req.ai_socktype = SOCK_STREAM;
+ if (plugin)
+ return handle_plugin(host,service,plugin);
+ memset(&req, 0, sizeof(struct addrinfo));
+ req.ai_socktype = SOCK_STREAM;
- if (i = getaddrinfo(host, service, &req, &ai)) {
- error(0, 0, "fetchmail: getaddrinfo(%s.%s): %s(%d)", host, service, gai_strerror(i), i);
- return -1;
- };
+ if (i = getaddrinfo(host, service, &req, &ai)) {
+ error(0, 0, "fetchmail: getaddrinfo(%s.%s): %s(%d)", host, service, gai_strerror(i), i);
+ return -1;
+ };
#if NET_SECURITY
- if (!options)
- requestlen = 0;
- else
- if (net_security_strtorequest((char *)options, &request, &requestlen))
- goto ret;
+ if (!options)
+ requestlen = 0;
+ else
+ if (net_security_strtorequest((char *)options, &request, &requestlen))
+ goto ret;
- i = inner_connect(ai, request, requestlen, NULL, NULL, "fetchmail", NULL);
- if (request)
- free(request);
+ i = inner_connect(ai, request, requestlen, NULL, NULL, "fetchmail", NULL);
+ if (request)
+ free(request);
-ret:
+ ret:
#else /* NET_SECURITY */
- i = inner_connect(ai, NULL, 0, NULL, NULL, "fetchmail", NULL);
+ i = inner_connect(ai, NULL, 0, NULL, NULL, "fetchmail", NULL);
#endif /* NET_SECURITY */
- freeaddrinfo(ai);
+ freeaddrinfo(ai);
- return i;
+ return i;
};
#else /* INET6 */
#ifndef HAVE_INET_ATON
@@ -91,7 +121,8 @@ ret:
#endif
#endif /* HAVE_INET_ATON */
-int SockOpen(const char *host, int clientPort, const char *options)
+int SockOpen(const char *host, int clientPort, const char *options,
+ const char *plugin)
{
int sock;
#ifndef HAVE_INET_ATON
@@ -100,6 +131,12 @@ int SockOpen(const char *host, int clientPort, const char *options)
struct sockaddr_in ad;
struct hostent *hp;
+ if (plugin) {
+ char buf[10];
+ sprintf(buf,"%d",clientPort);
+ return handle_plugin(host,buf,plugin);
+ }
+
memset(&ad, 0, sizeof(ad));
ad.sin_family = AF_INET;
diff --git a/socket.h b/socket.h
index a9882ce1..fdc395d9 100644
--- a/socket.h
+++ b/socket.h
@@ -9,9 +9,11 @@
/* Create a new client socket; returns (FILE *)NULL on error */
#if INET6
-int SockOpen(const char *host, const char *service, const char *options);
+int SockOpen(const char *host, const char *service, const char *options,
+ const char *plugin);
#else /* INET6 */
-int SockOpen(const char *host, int clientPort, const char *options);
+int SockOpen(const char *host, int clientPort, const char *options,
+ const char *plugin);
#endif /* INET6 */
/*