aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--acconfig.h5
-rw-r--r--configure.in17
-rw-r--r--driver.c16
-rw-r--r--etrn.c4
-rw-r--r--fetchmail.c33
-rw-r--r--fetchmail.h17
-rw-r--r--interface.c4
-rw-r--r--options.c30
-rw-r--r--pop3.c4
-rw-r--r--rcfile_l.l1
-rw-r--r--rcfile_y.y37
-rw-r--r--socket.c35
-rw-r--r--socket.h4
14 files changed, 189 insertions, 19 deletions
diff --git a/NEWS b/NEWS
index 2e31498a..4acb8a77 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,7 @@
* Allow -c -F to work to flush messages without retrieval.
* Read from /etc/fetchmailrc before ~/.fetchmailrc?
* Do is_host_alias checks by comparing IP addresses rather than names?
+* Make the antispam response configurable.
Other TO-DO items:
diff --git a/acconfig.h b/acconfig.h
index 53f2fa1d..f349fe48 100644
--- a/acconfig.h
+++ b/acconfig.h
@@ -70,6 +70,11 @@
/* Define if you want OPIE support compiled in */
#undef OPIE
+/* Define if you want IPv6 support compiled in */
+#undef INET6
+
+/* Define if you want network security support compiled in */
+#undef NETSEC
/* Leave that blank line there!! Autoheader needs it.
If you're adding to this file, keep in mind:
diff --git a/configure.in b/configure.in
index 44d453ce..50d653ae 100644
--- a/configure.in
+++ b/configure.in
@@ -190,6 +190,23 @@ AC_ARG_ENABLE(opie,
AC_DEFINE(OPIE,1) ],
[with_opie=no])
+AC_ARG_ENABLE(inet6,
+ [ --enable-inet6 support IPv6 (requires the inet6-apps library)],
+ [ unset ac_cv_lib_inet6_getaddrinfo; AC_CHECK_LIB(inet6, getaddrinfo,,
+ [ unset ac_cv_lib_inet6_getaddrinfo; LDFLAGS="$LDFLAGS -L/usr/inet6/lib"; AC_CHECK_LIB(inet6, getaddrinfo,,
+ [ echo 'configure: cannot find libinet6, which is required for IPv6 support.'; exit 1]) ])
+ AC_DEFINE(INET6, 1) ])
+
+AC_ARG_ENABLE(netsec,
+ [ --enable-netsec support network security (req. the inet6-apps library)],
+ [ unset ac_cv_lib_inet6_net_security_strtorequest; AC_CHECK_LIB(inet6, net_security_strtorequest,,
+ [ unset ac_cv_lib_inet6_net_security_strtorequest; LDFLAGS="$LDFLAGS -L/usr/inet6/lib"; AC_CHECK_LIB(inet6, net_security_strtorequest,,
+ [ echo 'configure: cannot find net_security_strtorequest in libinet6, which is required';
+ echo ' for network security support. Either it does not exist, or it was';
+ echo ' not built with network security support enabled.';
+ exit 1]) ])
+ AC_DEFINE(NETSEC, 1) ])
+
### use option --with-gssapi=DIR to compile in GSSAPI support
AC_ARG_WITH(gssapi,
[ --with-gssapi[=DIR] compile in GSSAPI support using libraries in DIR])
diff --git a/driver.c b/driver.c
index 3bf6df4d..cdfa866d 100644
--- a/driver.c
+++ b/driver.c
@@ -75,7 +75,11 @@
#define SIGCHLD SIGCLD
#endif
+#if INET6
+#define SMTP_PORT "smtp" /* standard SMTP service port */
+#else /* INET6 */
#define SMTP_PORT 25 /* standard SMTP service port */
+#endif /* INET6 */
#ifndef strstr /* glibc-2.1 declares this as a macro */
extern char *strstr(); /* needed on sysV68 R3V7.1. */
@@ -1639,7 +1643,11 @@ const struct method *proto; /* protocol method table */
{
char buf [POPBUFSIZE+1], *realhost;
int *msgsizes, len, num, count, new, deletions = 0;
+#if INET6
+ int fetches, dispatches;
+#else /* INET6 */
int port, fetches, dispatches;
+#endif /* INET6 */
struct idlist *idp;
/* execute pre-initialization command, if any */
@@ -1652,10 +1660,17 @@ const struct method *proto; /* protocol method table */
}
/* open a socket to the mail server */
+#if !INET6
port = ctl->server.port ? ctl->server.port : protocol->port;
+#endif /* !INET6 */
realhost = ctl->server.via ? ctl->server.via : ctl->server.pollname;
+#if INET6
+ if ((sock = SockOpen(realhost, ctl->server.service ? ctl->server.service : protocol->service)) == -1)
+#else /* INET6 */
if ((sock = SockOpen(realhost, port)) == -1)
+#endif /* INET6 */
{
+#if !INET6
#ifndef EHOSTUNREACH
#define EHOSTUNREACH (-1)
#endif
@@ -1678,6 +1693,7 @@ const struct method *proto; /* protocol method table */
#endif /* HAVE_RES_SEARCH */
error_complete(0, errno, "local error");
}
+#endif /* INET6 */
ok = PS_SOCKET;
goto closeUp;
}
diff --git a/etrn.c b/etrn.c
index 3c7d0f5f..26d30195 100644
--- a/etrn.c
+++ b/etrn.c
@@ -112,7 +112,11 @@ static int etrn_logout(int sock, struct query *ctl)
const static struct method etrn =
{
"ETRN", /* ESMTP ETRN extension */
+#if INET6
+ "smtp", /* standard SMTP port */
+#else /* INET6 */
25, /* standard SMTP port */
+#endif /* INET6 */
FALSE, /* this is not a tagged protocol */
FALSE, /* this does not use a message delimiter */
etrn_ok, /* parse command response */
diff --git a/fetchmail.c b/fetchmail.c
index 995da218..25bb42dc 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -72,6 +72,11 @@ char *home;
char *fetchmailhost; /* the name of the host running fetchmail */
char *program_name; /* the name to prefix error messages with */
+#if NETSEC
+void *request = NULL;
+int requestlen = 0;
+#endif /* NETSEC */
+
static char *lockfile; /* name of lockfile */
static int querystatus; /* status of query */
static int successes; /* count number of successful polls */
@@ -135,6 +140,15 @@ int main (int argc, char **argv)
#ifndef ETRN_ENABLE
printf("-ETRN");
#endif /* ETRN_ENABLE */
+#if OPIE
+ printf("+OPIE");
+#endif /* OPIE */
+#if INET6
+ printf("+INET6");
+#endif /* INET6 */
+#if NETSEC
+ printf("+NETSEC");
+#endif /* NETSEC */
putchar('\n');
/* this is an attempt to help remote debugging */
@@ -410,11 +424,11 @@ int main (int argc, char **argv)
}
}
-#ifdef linux
+#if defined(linux) && !INET6
/* interface_approve() does its own error logging */
if (!interface_approve(&ctl->server))
continue;
-#endif /* linux */
+#endif /* defined(linux) && !INET6 */
#ifdef HAVE_GETHOSTBYNAME
/*
@@ -462,7 +476,7 @@ int main (int argc, char **argv)
update_str_lists(ctl);
#endif /* POP3_ENABLE */
}
-#ifdef linux
+#if defined(linux) && !INET6
if (ctl->server.monitor)
{
/* Allow some time for the link to quiesce. One
@@ -472,7 +486,7 @@ int main (int argc, char **argv)
sleep(3);
interface_note_activity(&ctl->server);
}
-#endif
+#endif /* defined(linux) && !INET6 */
}
}
@@ -718,6 +732,7 @@ static int load_params(int argc, char **argv, int optind)
if (ctl->server.timeout == -1)
ctl->server.timeout = CLIENT_TIMEOUT;
+#if !INET6
/* sanity checks */
if (ctl->server.port < 0)
{
@@ -733,6 +748,7 @@ static int load_params(int argc, char **argv, int optind)
ctl->server.pollname);
exit(PS_SYNTAX);
}
+#endif /* !INET6 */
}
}
@@ -923,13 +939,22 @@ void dump_params (struct query *ctl)
else
printf(" Password = '%s'.\n", visbuf(ctl->password));
if (ctl->server.protocol == P_POP3
+#if INET6
+ && !strcmp(ctl->server.service, KPOP_PORT)
+#else /* INET6 */
&& ctl->server.port == KPOP_PORT
+#endif /* INET6 */
&& ctl->server.preauthenticate == A_KERBEROS_V4)
printf(" Protocol is KPOP");
else
printf(" Protocol is %s", showproto(ctl->server.protocol));
+#if INET6
+ if (ctl->server.service)
+ printf(" (using service %s)", ctl->server.service);
+#else /* INET6 */
if (ctl->server.port)
printf(" (using port %d)", ctl->server.port);
+#endif /* INET6 */
else if (outlevel == O_VERBOSE)
printf(" (using default port)");
if (ctl->server.uidl)
diff --git a/fetchmail.h b/fetchmail.h
index 72e59ed8..2b42de37 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -13,7 +13,11 @@
#define P_ETRN 8
#define P_IMAP_GSS 9
+#if INET6
+#define KPOP_PORT "kpop"
+#else /* INET6 */
#define KPOP_PORT 1109
+#endif /* INET6 */
/* preauthentication types */
#define A_PASSWORD 0 /* password or inline authentication */
@@ -93,7 +97,11 @@ struct hostdata /* shared among all user connections to given server */
struct idlist *akalist; /* server name first, then akas */
struct idlist *localdomains; /* list of pass-through domains */
int protocol; /* protocol type */
+#if INET6
+ char *service;
+#else /* INET6 */
int port; /* TCP/IP service port number */
+#endif /* INET6 */
int interval; /* # cycles to skip between polls */
int preauthenticate; /* preauthentication mode to try */
int timeout; /* inactivity timout in seconds */
@@ -181,7 +189,11 @@ struct query
struct method
{
char *name; /* protocol name */
+#if INET6
+ char *service;
+#else /* INET6 */
int port; /* service port */
+#endif /* INET6 */
flag tagged; /* if true, generate & expect command tags */
flag delimited; /* if true, accept "." message delimiter */
int (*parse_response)(); /* response_parsing function */
@@ -243,6 +255,11 @@ extern char *home; /* home directory of invoking user */
extern char *fetchmailhost; /* the name of the host running fetchmail */
extern int pass; /* number of re-polling pass */
+#if NETSEC
+extern void *request;
+extern int requestlen;
+#endif /* NETSEC */
+
/* prototypes for globally callable functions */
/* error.c: Error reporting */
diff --git a/interface.c b/interface.c
index 370d078d..62f14bfb 100644
--- a/interface.c
+++ b/interface.c
@@ -11,7 +11,7 @@
* Software Foundation; version 2, or (at your option) any later version.
*/
-#ifdef linux
+#if defined(linux) && !defined(INET6)
#include "config.h"
#include <stdio.h>
@@ -253,4 +253,4 @@ int interface_approve(struct hostdata *hp)
return(TRUE);
}
-#endif /* linux */
+#endif /* defined(linux) && !defined(INET6) */
diff --git a/options.c b/options.c
index 4d0aa0d1..be5089d9 100644
--- a/options.c
+++ b/options.c
@@ -102,10 +102,10 @@ static const struct option longoptions[] = {
{"expunge", required_argument, (int *) 0, LA_EXPUNGE },
{"mda", required_argument, (int *) 0, LA_MDA },
-#ifdef linux
+#if defined(linux) && !INET6
{"interface", required_argument, (int *) 0, LA_INTERFACE },
{"monitor", required_argument, (int *) 0, LA_MONITOR },
-#endif
+#endif /* defined(linux) && !INET6 */
{"yydebug", no_argument, (int *) 0, LA_YYDEBUG },
@@ -201,7 +201,11 @@ struct query *ctl; /* option record to be initialized */
else if (strcasecmp(optarg,"kpop") == 0)
{
ctl->server.protocol = P_POP3;
+#if INET6
+ ctl->server.service = KPOP_PORT;
+#else /* INET6 */
ctl->server.port = KPOP_PORT;
+#endif /* INET6 */
ctl->server.preauthenticate = A_KERBEROS_V4;
}
else if (strcasecmp(optarg,"imap") == 0)
@@ -223,7 +227,11 @@ struct query *ctl; /* option record to be initialized */
break;
case 'P':
case LA_PORT:
+#if INET6
+ ctl->server.service = optarg;
+#else /* INET6 */
ctl->server.port = atoi(optarg);
+#endif /* INET6 */
break;
case 'A':
case LA_AUTHENTICATE:
@@ -292,6 +300,13 @@ struct query *ctl; /* option record to be initialized */
((cp = strtok((char *)NULL, ",")));
break;
case 'S':
+#if NETSEC
+ if (net_security_strtorequest(optarg, request, &requestlen)) {
+ fprintf(stderr, "fetchmail: net_security_strtorequest(%s, ...) failed!\n", optarg);
+ errflag++;
+ };
+ break;
+#endif /* NETSEC */
case LA_SMTPHOST:
strcpy(buf, optarg);
cp = strtok(buf, ",");
@@ -326,7 +341,7 @@ struct query *ctl; /* option record to be initialized */
ocount++;
break;
-#ifdef linux
+#if defined(linux) && !INET6
case 'I':
case LA_INTERFACE:
interface_parse(optarg, &ctl->server);
@@ -335,7 +350,7 @@ struct query *ctl; /* option record to be initialized */
case LA_MONITOR:
ctl->server.monitor = xstrdup(optarg);
break;
-#endif
+#endif /* defined(linux) && !INET6 */
case 'y':
case LA_YYDEBUG:
@@ -371,7 +386,7 @@ struct query *ctl; /* option record to be initialized */
fputs(" --invisible suppress Received line & enable host spoofing\n", stderr);
fputs(" -f, --fetchmailrc specify alternate run control file\n", stderr);
fputs(" -i, --idfile specify alternate UIDs file\n", stderr);
-#ifdef linux
+#if defined(linux) && !INET6
fputs(" -I, --interface interface required specification\n",stderr);
fputs(" -M, --monitor monitor interface for activity\n",stderr);
#endif
@@ -396,7 +411,12 @@ struct query *ctl; /* option record to be initialized */
fputs(" -n, --norewrite don't rewrite header addresses\n", stderr);
fputs(" -l, --limit don't fetch messages over given size\n", stderr);
+#if NETSEC
+ fputs(" -S set security request\n", stderr);
+ fputs(" --smtphost set SMTP forwarding host\n", stderr);
+#else /* NETSEC */
fputs(" -S, --smtphost set SMTP forwarding host\n", stderr);
+#endif /* NETSEC */
fputs(" -D, --smtpaddress set SMTP delivery domain to use\n", stderr);
fputs(" -b, --batchlimit set batch limit for SMTP connections\n", stderr);
fputs(" -B, --fetchlimit set fetch limit for server connections\n", stderr);
diff --git a/pop3.c b/pop3.c
index 8a36d352..20d45b1c 100644
--- a/pop3.c
+++ b/pop3.c
@@ -519,7 +519,11 @@ static int pop3_logout(int sock, struct query *ctl)
const static struct method pop3 =
{
"POP3", /* Post Office Protocol v3 */
+#if INET6
+ "pop3", /* standard POP3 port */
+#else /* INET6 */
110, /* standard POP3 port */
+#endif /* INET6 */
FALSE, /* this is not a tagged protocol */
TRUE, /* this uses a message delimiter */
pop3_ok, /* parse command response */
diff --git a/rcfile_l.l b/rcfile_l.l
index 5d904f13..1c88b919 100644
--- a/rcfile_l.l
+++ b/rcfile_l.l
@@ -35,6 +35,7 @@ via { return VIA; }
aka { return AKA; }
local(domains) { return LOCALDOMAINS; }
proto(col)? { return PROTOCOL; }
+service { return SERVICE; }
port { return PORT; }
interval { return INTERVAL; }
auth(enticate)? { return AUTHENTICATE; }
diff --git a/rcfile_y.y b/rcfile_y.y
index 71d8ea4b..dd8b7654 100644
--- a/rcfile_y.y
+++ b/rcfile_y.y
@@ -68,7 +68,7 @@ extern char * yytext;
%token <sval> STRING
%token <number> NUMBER
%token NO KEEP FLUSH FETCHALL REWRITE FORCECR STRIPCR PASS8BITS DROPSTATUS
-%token DNS PORT UIDL INTERVAL
+%token DNS SERVICE PORT UIDL INTERVAL
%%
@@ -126,11 +126,24 @@ serv_option : AKA alias_list
| PROTOCOL KPOP {
current.server.protocol = P_POP3;
current.server.preauthenticate = A_KERBEROS_V4;
+#if INET6
+ current.server.service = KPOP_PORT;
+#else /* INET6 */
current.server.port = KPOP_PORT;
+#endif /* INET6 */
}
| UIDL {current.server.uidl = FLAG_TRUE;}
| NO UIDL {current.server.uidl = FLAG_FALSE;}
- | PORT NUMBER {current.server.port = $2;}
+ | SERVICE STRING {
+#if INET6
+ current.server.service = $2;
+#endif /* INET6 */
+ }
+ | PORT NUMBER {
+#if !INET6
+ current.server.port = $2;
+#endif /* !INET6 */
+ }
| INTERVAL NUMBER {current.server.interval = $2;}
| AUTHENTICATE PASSWORD {current.server.preauthenticate = A_PASSWORD;}
| AUTHENTICATE KERBEROS4 {current.server.preauthenticate = A_KERBEROS_V4;}
@@ -151,18 +164,18 @@ serv_option : AKA alias_list
| QVIRTUAL STRING {current.server.qvirtual = xstrdup($2);}
| INTERFACE STRING {
-#ifdef linux
+#if defined(linux) && !defined(INET6)
interface_parse($2, &current.server);
-#else
+#else /* defined(linux) && !defined(INET6) */
fprintf(stderr, "fetchmail: interface option is only supported under Linux\n");
-#endif /* linux */
+#endif /* defined(linux) && !defined(INET6) */
}
| MONITOR STRING {
-#ifdef linux
+#if defined(linux) && !defined(INET6)
current.server.monitor = xstrdup($2);
-#else
+#else /* defined(linux) && !defined(INET6) */
fprintf(stderr, "fetchmail: monitor option is only supported under Linux\n");
-#endif /* linux */
+#endif /* defined(linux) && !defined(INET6) */
}
| DNS {current.server.dns = FLAG_TRUE;}
| NO DNS {current.server.dns = FLAG_FALSE;}
@@ -412,7 +425,11 @@ static void record_current(void)
#define FLAG_FORCE(fld) if (cmd_opts.fld) current.fld = cmd_opts.fld
FLAG_FORCE(server.via);
FLAG_FORCE(server.protocol);
+#if INET6
+ FLAG_FORCE(server.service);
+#else /* INET6 */
FLAG_FORCE(server.port);
+#endif /* INET6 */
FLAG_FORCE(server.interval);
FLAG_FORCE(server.preauthenticate);
FLAG_FORCE(server.timeout);
@@ -471,7 +488,11 @@ void optmerge(struct query *h2, struct query *h1)
#define FLAG_MERGE(fld) if (!h2->fld) h2->fld = h1->fld
FLAG_MERGE(server.via);
FLAG_MERGE(server.protocol);
+#if INET6
+ FLAG_MERGE(server.service);
+#else /* INET6 */
FLAG_MERGE(server.port);
+#endif /* INET6 */
FLAG_MERGE(server.interval);
FLAG_MERGE(server.preauthenticate);
FLAG_MERGE(server.timeout);
diff --git a/socket.c b/socket.c
index 58ca8cfd..d2545123 100644
--- a/socket.c
+++ b/socket.c
@@ -28,6 +28,40 @@
#endif
#include "socket.h"
+#if NETSEC
+#if MAIN
+void *request = NULL;
+int requestlen = 0;
+#else /* MAIN */
+extern void *request;
+extern int requestlen;
+#endif /* MAIN */
+#endif /* NETSEC */
+
+#if INET6
+int SockOpen(const char *host, const char *service)
+{
+ int i;
+ struct addrinfo *ai, req;
+
+ memset(&req, 0, sizeof(struct addrinfo));
+ req.ai_socktype = SOCK_STREAM;
+
+ if (i = getaddrinfo(host, service, &req, &ai)) {
+ fprintf(stderr, "fetchmail: getaddrinfo(%s.%s): %s(%d)\n", host, service, gai_strerror(i), i);
+ return -1;
+ };
+
+#if NETSEC
+ i = inner_connect(ai, request, requestlen, NULL, NULL, "fetchmail", NULL);
+#else /* NETSEC */
+ i = inner_connect(ai, NULL, 0, NULL, NULL, "fetchmail", NULL);
+#endif /* NETSEC */
+ freeaddrinfo(ai);
+
+ return i;
+};
+#else /* INET6 */
#ifndef INET_ATON
#ifndef INADDR_NONE
#ifdef INADDR_BROADCAST
@@ -84,6 +118,7 @@ int SockOpen(const char *host, int clientPort)
return(sock);
}
+#endif /* INET6 */
#if defined(HAVE_STDARG_H)
diff --git a/socket.h b/socket.h
index 42f5c512..83e1b366 100644
--- a/socket.h
+++ b/socket.h
@@ -8,7 +8,11 @@
#define SOCKET__
/* Create a new client socket; returns (FILE *)NULL on error */
+#if INET6
+int SockOpen(const char *host, const char *service);
+#else /* INET6 */
int SockOpen(const char *host, int clientPort);
+#endif /* INET6 */
/*
Get a string terminated by an '\n' (matches interface of fgets).