diff options
author | Eric S. Raymond <esr@thyrsus.com> | 1998-11-02 16:25:09 +0000 |
---|---|---|
committer | Eric S. Raymond <esr@thyrsus.com> | 1998-11-02 16:25:09 +0000 |
commit | 4ee8d22351243e9a79bb40f181786e5650abae47 (patch) | |
tree | fdea4ac21bbe7f5c248a6085645069994c64621e | |
parent | e98f220bcfa290b355c724b62b4c8c3c15da8e9c (diff) | |
download | fetchmail-4ee8d22351243e9a79bb40f181786e5650abae47.tar.gz fetchmail-4ee8d22351243e9a79bb40f181786e5650abae47.tar.bz2 fetchmail-4ee8d22351243e9a79bb40f181786e5650abae47.zip |
Added plugin/plugout option.
svn path=/trunk/; revision=2168
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | conf.c | 3 | ||||
-rw-r--r-- | driver.c | 5 | ||||
-rw-r--r-- | fetchmail-FAQ.html | 30 | ||||
-rw-r--r-- | fetchmail.c | 11 | ||||
-rw-r--r-- | fetchmail.h | 2 | ||||
-rw-r--r-- | fetchmail.man | 22 | ||||
-rwxr-xr-x | fetchmailconf | 4 | ||||
-rw-r--r-- | options.c | 22 | ||||
-rw-r--r-- | rcfile_l.l | 2 | ||||
-rw-r--r-- | rcfile_y.y | 4 | ||||
-rw-r--r-- | sample.rcfile | 2 | ||||
-rw-r--r-- | sink.c | 6 | ||||
-rw-r--r-- | socket.c | 85 | ||||
-rw-r--r-- | socket.h | 6 |
15 files changed, 166 insertions, 39 deletions
@@ -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. @@ -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('['); @@ -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"><esr@snark.thyrsus.com></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): @@ -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"); @@ -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; } @@ -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 @@ -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 && @@ -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; @@ -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 */ /* |