aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--README2
-rw-r--r--driver.c15
-rw-r--r--fetchmail.c19
-rw-r--r--fetchmail.h2
-rw-r--r--fetchmail.man9
-rw-r--r--options.c15
-rw-r--r--pop3.c70
-rw-r--r--rcfile_l.l1
-rw-r--r--sample.rcfile1
10 files changed, 129 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 3af9c487..37d4aa1c 100644
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,11 @@ features --
* Linux packagers: building fetchmail now generates an RPM specfile for it.
+* Kerberos support via KPOP protocol (thanks to Chris Hanson).
+
+* New --check option for asking server whether there is mail without
+ actually retrieving or deleting it.
+
bugs --
* Fix buggy getopt specification of P and p options.
diff --git a/README b/README
index 5847f8ad..ea26b76b 100644
--- a/README
+++ b/README
@@ -32,6 +32,8 @@ with **.
* **POP2, POP3, **APOP, **IMAP support.
+ ** Support for Kerberos user authentication.
+
** Host is auto-probed for a working server if no protocol is
specified for the connection. Thus you don't need to know
what servers are running on your mail host in advance; the
diff --git a/driver.c b/driver.c
index 55e071f1..409632b6 100644
--- a/driver.c
+++ b/driver.c
@@ -534,6 +534,15 @@ struct method *proto;
goto closeUp;
}
+#ifdef KERBEROS_V4
+ if (queryctl->protocol == P_KPOP)
+ {
+ ok = (pop3_kerberos_auth (socket, queryctl));
+ if (ok != 0)
+ goto cleanUp;
+ }
+#endif
+
/* accept greeting message from mail server */
ok = (protocol->parse_response)(socket, buf);
if (alarmed || ok != 0)
@@ -560,7 +569,7 @@ struct method *proto;
count, count > 1 ? "s" : "",
queryctl->servername);
- if (count > 0)
+ if ((count > 0) && (!check_only))
{
if (queryctl->mda[0] == '\0')
if ((mboxfd = Socket(queryctl->smtphost, SMTP_PORT)) < 0
@@ -659,6 +668,10 @@ struct method *proto;
close(socket);
goto closeUp;
}
+ else if (check_only) {
+ ok = ((count > 0) ? PS_SUCCESS : PS_NOMAIL);
+ goto closeUp;
+ }
else {
ok = gen_transact(socket, protocol->exit_cmd);
if (ok == 0)
diff --git a/fetchmail.c b/fetchmail.c
index 8be194b9..b86878d5 100644
--- a/fetchmail.c
+++ b/fetchmail.c
@@ -54,6 +54,7 @@ int yydebug; /* enable parse debugging */
int poll_interval; /* poll interval in seconds */
char *logfile; /* log file for daemon mode */
int quitmode; /* if --quit was set */
+int check_only; /* if --probe was set */
/* miscellaneous global controls */
char *rcfile; /* path name of rc file */
@@ -309,10 +310,18 @@ char **argv;
for (hostp = hostlist; hostp; hostp = hostp->next)
if (hostp->active && !(implicitmode && hostp->skip) && !hostp->password[0])
{
- (void) sprintf(tmpbuf, "Enter password for %s@%s: ",
- hostp->remotename, hostp->servername);
- (void) strncpy(hostp->password,
- (char *)getpassword(tmpbuf),PASSWORDLEN-1);
+ if (hostp->protocol == P_KPOP)
+ /* Server doesn't care what the password is, but there
+ must be some non-null string here. */
+ (void) strncpy(hostp->password,
+ hostp->remotename, PASSWORDLEN-1);
+ else
+ {
+ (void) sprintf(tmpbuf, "Enter password for %s@%s: ",
+ hostp->remotename, hostp->servername);
+ (void) strncpy(hostp->password,
+ (char *)getpassword(tmpbuf),PASSWORDLEN-1);
+ }
}
/*
@@ -386,6 +395,7 @@ int proto;
case P_POP3: return("POP3"); break;
case P_IMAP: return("IMAP"); break;
case P_APOP: return("APOP"); break;
+ case P_KPOP: return("KPOP"); break;
default: return("unknown?!?"); break;
}
}
@@ -425,6 +435,7 @@ struct hostrec *queryctl;
break;
case P_POP3:
case P_APOP:
+ case P_KPOP:
return(doPOP3(queryctl));
break;
case P_IMAP:
diff --git a/fetchmail.h b/fetchmail.h
index 99f16c87..d2bfc6d1 100644
--- a/fetchmail.h
+++ b/fetchmail.h
@@ -17,6 +17,7 @@
#define P_POP3 3
#define P_IMAP 4
#define P_APOP 5
+#define P_KPOP 6
/* definitions for buffer sizes -- somewhat arbitrary */
#define POPBUFSIZE 512 /* per RFC 937 */
@@ -110,6 +111,7 @@ extern int yydebug; /* enable parse debugging */
extern int poll_interval; /* poll interval in seconds */
extern char *logfile; /* log file for daemon mode */
extern int quitmode; /* if --quit was set */
+extern int check_only; /* if --check was set */
/* miscellaneous global controls */
extern char *rcfile; /* path name of rc file */
diff --git a/fetchmail.man b/fetchmail.man
index 2027b1b0..39ba3594 100644
--- a/fetchmail.man
+++ b/fetchmail.man
@@ -76,6 +76,10 @@ machine).
POP3/IMAP only. Delete old (previously retrieved) messages from the mailserver
before retrieving new messages.
.TP
+.B \-c, --check
+Return a status code to indicate whether there is mail waiting,
+without actually fetching or deleting mail (see EXIT CODES below).
+.TP
.B \-f pathname, --fetchmailrc pathname
Specify a non-default name for the
.I .fetchmailrc
@@ -110,6 +114,8 @@ Post Office Protocol 2
Post Office Protocol 3
.IP APOP
Use POP3 with MD5 authentication.
+.IP KPOP
+POP3 with Kerberos authentication.
.RE
.TP
.B \-P, --port
@@ -124,7 +130,7 @@ behavior when no folder is specified.
.TP
.B \-s, --silent
Silent mode. Suppresses all progress/status messages that are normally
-echoed to stderr during a fetch. If both the
+echoed to standard error during a fetch. If both the
.B silent
and
.B verbose
@@ -380,6 +386,7 @@ Legal protocol identifiers are
pop3 (or POP3)
imap (or IMAP)
apop (or APOP)
+ kpop (or APOP)
.PP
You can use the `noise' keywords \fBand\fR, \fBwith\fR,
\fBhas\fR, \fBwants\fR, and \fBoptions\fR anywhere in an entry to make
diff --git a/options.c b/options.c
index 4f7d3777..4818e9ff 100644
--- a/options.c
+++ b/options.c
@@ -37,8 +37,9 @@
#define LA_LOGFILE 17
#define LA_QUIT 18
#define LA_NOREWRITE 19
-#define LA_HELP 20
-#define LA_YYDEBUG 21
+#define LA_CHECK 20
+#define LA_HELP 21
+#define LA_YYDEBUG 22
static char *shortoptions = "P:p:VaKkvS:m:sFd:f:u:r:L:qN?";
static struct option longoptions[] = {
@@ -62,6 +63,7 @@ static struct option longoptions[] = {
{"logfile", required_argument, (int *) 0, LA_LOGFILE },
{"quit", no_argument, (int *) 0, LA_QUIT },
{"norewrite", no_argument, (int *) 0, LA_NOREWRITE },
+ {"check", no_argument, (int *) 0, LA_CHECK },
{"help", no_argument, (int *) 0, LA_HELP },
{"yydebug", no_argument, (int *) 0, LA_YYDEBUG },
{(char *) 0, no_argument, (int *) 0, 0 }
@@ -150,6 +152,8 @@ struct hostrec *queryctl;
queryctl->protocol = P_IMAP;
else if (strcasecmp(optarg,"apop") == 0)
queryctl->protocol = P_APOP;
+ else if (strcasecmp(optarg,"kpop") == 0)
+ queryctl->protocol = P_KPOP;
else {
fprintf(stderr,"Invalid protocol '%s'\n specified.\n", optarg);
errflag++;
@@ -201,6 +205,10 @@ struct hostrec *queryctl;
case LA_NOREWRITE:
queryctl->norewrite = 1;
break;
+ case 'c':
+ case LA_CHECK:
+ check_only = 1;
+ break;
case LA_YYDEBUG:
yydebug = 1;
break;
@@ -216,7 +224,7 @@ struct hostrec *queryctl;
fputs("usage: fetchmail [options] [server ...]\n", stderr);
fputs(" Options are as follows:\n",stderr);
fputs(" -?, --help display this option help\n", stderr);
- fputs(" -p, --protocol specify pop2, pop3, imap, apop\n", stderr);
+ fputs(" -p, --protocol specify pop2, pop3, imap, apop, rpop, kpop\n", stderr);
fputs(" -V, --version display version info\n", stderr);
fputs(" -a, --all retrieve old and new messages\n", stderr);
fputs(" -F, --flush delete old messages from server\n", stderr);
@@ -231,6 +239,7 @@ struct hostrec *queryctl;
fputs(" -u, --username specify users's login on server\n", stderr);
fputs(" -r, --remote specify remote folder name\n", stderr);
fputs(" -L, --logfile specify logfile name\n", stderr);
+ fputs(" -c, --check check for messages without retrieving\n", stderr);
return(-1);
}
diff --git a/pop3.c b/pop3.c
index 66f08d6a..47c0bc17 100644
--- a/pop3.c
+++ b/pop3.c
@@ -14,6 +14,15 @@
#include <config.h>
#include <stdio.h>
+
+#ifdef KERBEROS_V4
+#include <krb.h>
+#include <des.h>
+/* <netinet/in.h> must be included before "socket.h". */
+#include <netinet/in.h>
+#include <netdb.h>
+#endif
+
#include "socket.h"
#include "fetchmail.h"
@@ -99,6 +108,12 @@ char *greeting;
}
switch (queryctl->protocol) {
+ case P_KPOP:
+#ifndef KERBEROS_V4
+ strcat (buf, "KPOP support not compiled into this executable.\n");
+ return(PS_ERROR);
+#endif
+
case P_POP3:
if ((gen_transact(socket,"USER %s", queryctl->remotename)) != 0)
return(PS_ERROR);
@@ -121,6 +136,54 @@ char *greeting;
return(0);
}
+#ifdef KERBEROS_V4
+int
+pop3_kerberos_auth (socket, queryctl)
+ int socket;
+ struct hostrec * queryctl;
+{
+ char * host_primary;
+ KTEXT ticket;
+ MSG_DAT msg_data;
+ CREDENTIALS cred;
+ Key_schedule schedule;
+ int rem;
+
+ /* Get the primary name of the host. */
+ {
+ struct hostent * hp = (gethostbyname (queryctl->servername));
+ if (hp == 0)
+ {
+ fprintf (stderr, "MAILHOST unknown: %s\n", queryctl->servername);
+ return (PS_ERROR);
+ }
+ host_primary = ((char *) (malloc ((strlen (hp -> h_name)) + 1)));
+ strcpy (host_primary, (hp -> h_name));
+ }
+
+ ticket = ((KTEXT) (malloc (sizeof (KTEXT_ST))));
+ rem
+ = (krb_sendauth (0L, socket, ticket, "pop",
+ host_primary,
+ ((char *) (krb_realmofhost (host_primary))),
+ ((unsigned long) 0),
+ (&msg_data),
+ (&cred),
+ (schedule),
+ ((struct sockaddr_in *) 0),
+ ((struct sockaddr_in *) 0),
+ "KPOPV0.1"));
+ free (ticket);
+ free (host_primary);
+ if (rem != KSUCCESS)
+ {
+ fprintf (stderr, "kerberos error: %s\n", (krb_get_err_text (rem)));
+ return (PS_ERROR);
+ }
+ return (0);
+}
+#endif /* KERBEROS_V4 */
+
static pop3_getrange(socket, queryctl, countp)
/* get range of messages to be fetched */
int socket;
@@ -213,7 +276,12 @@ struct hostrec *queryctl;
fprintf(stderr,"Option --remote is not supported with POP3\n");
return(PS_SYNTAX);
}
-
+ if (queryctl->protocol == P_KPOP)
+ {
+ struct method kpop_method = pop3;
+ kpop_method.port = 1109;
+ return(do_protocol(queryctl, &kpop_method));
+ }
return(do_protocol(queryctl, &pop3));
}
diff --git a/rcfile_l.l b/rcfile_l.l
index 0d0752f2..e22dcb75 100644
--- a/rcfile_l.l
+++ b/rcfile_l.l
@@ -60,6 +60,7 @@ options {/* EMPTY */}
(pop3)|(POP3) { yylval.proto = P_POP3; return PROTO; }
(imap)|(IMAP) { yylval.proto = P_IMAP; return PROTO; }
(apop)|(APOP) { yylval.proto = P_APOP; return PROTO; }
+(kpop)|(KPOP) { yylval.proto = P_KPOP; return PROTO; }
(#.*)?\\?\n { prc_lineno++; } /* newline is ignored */
diff --git a/sample.rcfile b/sample.rcfile
index 8457576d..29bdfd90 100644
--- a/sample.rcfile
+++ b/sample.rcfile
@@ -45,6 +45,7 @@
# pop3 (or POP3)
# imap (or IMAP)
# apop (or APOP)
+# kpop (or KPOP)
#
# Basic format is
# server SERVERNAME protocol PROTOCOL username NAME password PASSWORD