Commit 8a95cd7b authored by Eric S. Raymond's avatar Eric S. Raymond

Chris Hanson's Kerberos support, plus documentation.

svn path=/trunk/; revision=280
parent 72050c63
......@@ -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.
......
......@@ -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
......
......@@ -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)
......
......@@ -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 %[email protected]%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 %[email protected]%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:
......
......@@ -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 */
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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));
}
......
......@@ -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 */
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment