diff options
-rw-r--r-- | fetchmail.c | 20 | ||||
-rw-r--r-- | fetchmail.man | 42 | ||||
-rw-r--r-- | interface.c | 14 |
3 files changed, 44 insertions, 32 deletions
diff --git a/fetchmail.c b/fetchmail.c index 7952523d..846c4ae7 100644 --- a/fetchmail.c +++ b/fetchmail.c @@ -169,7 +169,7 @@ int main (int argc, char **argv) printf("No SMTP message batch limit.\n"); #ifdef linux if (interface) - printf("TCP/IP interface requirements are %s.\n", interface); + printf("TCP/IP interface requirements for %s.\n", interface); else if (outlevel == O_VERBOSE) printf("No TCP/IP interface requirements specified.\n"); if (monitor) @@ -335,15 +335,19 @@ int main (int argc, char **argv) * reflect the status of that transaction. */ do { -#ifdef linux - if (poll_interval && monitor) - sleep(3); /* allow some time for the link to quiesce */ - - interface_note_activity(); -#endif - if (poll_interval) { +#ifdef linux + if (monitor) + { + /* + * Allow some time for the link to quiesce. + * Note: this delay is important! Don't remove it casually! + */ + sleep(3); + interface_note_activity(); + } +#endif if (outlevel == O_VERBOSE) { time_t now; diff --git a/fetchmail.man b/fetchmail.man index 17cc0386..1385bf78 100644 --- a/fetchmail.man +++ b/fetchmail.man @@ -107,26 +107,26 @@ Specify an alternate name for the .fetchids file used to save POP3 UIDs. .TP .B \-I specification, --interface specification -Require that a point-to-point connection to a given IP address be up -before polling. Normally fetchmail is used via a transient -point-to-point TCP/IP link established directly to a mailserver via -SLIP or PPP; this is a relatively secure channel. But when other -TCP/IP routes to the mailserver exist, your username and password may -be vulnerable to snooping (especially when daemon mode automatically -polls for mail, shipping a clear password over the net at predictable -intervals). The --interface option may be used to prevent this by -specifying an interface device and connection IP address (or range) -for the mailserver TCP/IP link. When the specified link is not up or -is not connected to a matching IP address, polling will be skipped. -The format is: +Require that a specific interface device be up and have a specific local +IP address (or range) before polling. Frequently +.I fetchmail +is used over a transient point-to-point TCP/IP link established directly +to a mailserver via SLIP or PPP. That is a relatively secure channel. +But when other TCP/IP routes to the mailserver exist (e.g. when the link +is connected to an alternate ISP), your username and password may be +vulnerable to snooping (especially when daemon mode automatically polls +for mail, shipping a clear password over the net at predictable +intervals). The --interface option may be used to prevent this. When +the specified link is not up or is not connected to a matching IP +address, polling will be skipped. The format is: .sp interface/iii.iii.iii.iii/mmm.mmm.mmm.mmm .sp The field before the first slash is the interface name (i.e. sl0, ppp0 -etc). The field before the second slash is the acceptable IP address. +etc.). The field before the second slash is the acceptable IP address. The field after the second slash is a mask which specifies a range of IP addresses to accept. If no mask is present 255.255.255.255 is -assumed (i.e. an exact match). This option is currently only supported +assumed (i.e. an exact match). This option is currently only supported under Linux. .TP .B \-M interface, --monitor interface @@ -704,9 +704,11 @@ your \fI.fetchmailrc\fR, declare \&`to esr fetchmail-friends here'. Then, when mail including `fetchmail-friends' in any of its recipient lines gets fetched, the list name will be appended to the list of recipients your SMTP listener sees. Therefore it will undergo alias -expansion locally. (Be sure to include `esr' in the local alias +expansion locally. Be sure to include `esr' in the local alias expansion of fetchmail-friends, or you'll never see mail sent only to -the list!) +the list. Also be sure that your listener has the "me-too" option set +(sendmail's -oXm command-line option or OXm declaration) so your name +isn't removed from alias expansions in messages you send. .PP This trick is not without its problems, however. You'll begin to see this when a message comes in that is addressed only to a mailing list @@ -828,10 +830,10 @@ that the program send unencrypted passwords over the TCP/IP connection to the mailserver. This creates a risk that name/password pairs might be snaffled with a packet sniffer or more sophisticated monitoring software. Under Linux, the --interface option can be used -to restrict polling to a specified point-to-point link, but snooping -is still possible if (a) either host has a network device that can be -opened in promiscuous mode, or (b) the intervening network link can -be tapped. +to restrict polling to availability of a specific interface device with +a specific local IP address, but snooping is still possible if (a) +either host has a network device that can be opened in promiscuous mode, +or (b) the intervening network link can be tapped. .PP Send comments, bug reports, gripes, and the like to Eric S. Raymond <esr@thyrsus.com>. diff --git a/interface.c b/interface.c index 85ca85d8..dce5267e 100644 --- a/interface.c +++ b/interface.c @@ -14,13 +14,11 @@ #ifdef linux #include <stdio.h> -#include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/ioctl.h> #include <netinet/in.h> #include <linux/netdevice.h> -#include <errno.h> #include "fetchmail.h" static struct in_addr interface_address; @@ -47,9 +45,8 @@ static int _get_ifinfo_(int socket_fd, FILE *stats_file, const char *ifname, /* see if the interface is up */ strcpy(request.ifr_name, ifname); - errno = 0; if (ioctl(socket_fd, SIOCGIFFLAGS, &request) < 0) - error(PS_IOERR, errno, "interface status check failed"); + return(FALSE); if (!(request.ifr_flags & IFF_RUNNING)) return(FALSE); @@ -106,7 +103,9 @@ static int get_ifinfo(const char *ifname, ifinfo_t *ifinfo) void interface_parse(void) { + int socket_fd = socket(AF_INET, SOCK_DGRAM, 0); char *cp1, *cp2; + struct ifreq request; /* in the event we point to a null string, make pointer null */ if (interface && !*interface) @@ -123,6 +122,13 @@ void interface_parse(void) (void) error(PS_SYNTAX, 0, "missing IP interface address"); *cp1++ = '\000'; + /* validate specified interface exists */ + strcpy(request.ifr_name, interface); + if (ioctl(socket_fd, SIOCGIFFLAGS, &request) < 0) + (void) error(PS_SYNTAX, 0, "no such interface device '%s'", + interface); + close(socket_fd); + /* find and isolate just the netmask */ if (!(cp2 = strchr(cp1, '/'))) cp2 = "255.255.255.255"; |