]> Pileus Git - ~andy/fetchmail/commitdiff
More authentication types.
authorEric S. Raymond <esr@thyrsus.com>
Tue, 20 Feb 2001 05:15:42 +0000 (05:15 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Tue, 20 Feb 2001 05:15:42 +0000 (05:15 -0000)
svn path=/trunk/; revision=3130

NEWS
conf.c
fetchmail.h
fetchmail.man
pop3.c

diff --git a/NEWS b/NEWS
index 97e97453ca3f2d8c46ed7fa13b46b6552f2702f1..6e1a40ab19f61c8a0461002755f76ef66531fde8 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@
 * `preauth' option changed back to `auth'
 * IMAP code now bails out if the server forces the mailbox read-only.
 * Fixed a core dump in Dave Zarzycki's new plugin code.
+* POP3 latency optimization: only do CAPA and set authentication capabilities
+  from it once at start of run.
 
 fetchmail-5.6.7 (Mon Feb 19 12:31:03 EST 2001), 20082 lines:
 
diff --git a/conf.c b/conf.c
index 3f6e7af109c8e765022126b1bbf4530b9be113b4..4b43b674364cb5af47c76cae870fdcfe251f1783 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -275,6 +275,10 @@ void dump_config(struct runctl *runp, struct query *querylist)
                stringdump("auth", "any");
            else if (ctl->server.authenticate == A_PASSWORD)
                stringdump("auth", "password");
+           else if (ctl->server.authenticate == A_OTP)
+               stringdump("auth", "otp");
+           else if (ctl->server.authenticate == A_CRAM_MD5)
+               stringdump("auth", "cram-md5");
            else if (ctl->server.authenticate == A_GSSAPI)
                stringdump("auth", "gssapi");
            else if (ctl->server.authenticate == A_KERBEROS_V4)
index e78e212170d67db43945aeba367f77eb1941a6e1..3c7d4b9bc910de36a075bf005b3ea431ba2a4559 100644 (file)
 
 /* authentication types */
 #define                A_ANY           0       /* use the first method that works */
-#define                A_PASSWORD      1       /* password or inline authentication */
-#define                A_KERBEROS_V4   2       /* authenticate w/ Kerberos V4 */
-#define                A_KERBEROS_V5   3       /* authenticate w/ Kerberos V5 */
-#define        A_GSSAPI        4       /* authenticate with GSSAPI */
-#define                A_SSH           5       /* authentication at session level */
+#define                A_PASSWORD      1       /* password authentication */
+#define                A_CRAM_MD5      2       /* CRAM-MD5 shrouding (RFC2195) */
+#define                A_OTP           3       /* One-time password (RFC1508) */
+#define                A_KERBEROS_V4   4       /* authenticate w/ Kerberos V4 */
+#define                A_KERBEROS_V5   5       /* authenticate w/ Kerberos V5 */
+#define        A_GSSAPI        6       /* authenticate with GSSAPI */
+#define                A_SSH           7       /* authentication at session level */
 
 /* some protocols (KERBEROS, GSSAPI, SSH) don't require a password */
-#define NO_PASSWORD(ctl)       ((ctl)->server.authenticate > A_PASSWORD || !MAILBOX_PROTOCOL(ctl))
+#define NO_PASSWORD(ctl)       ((ctl)->server.authenticate > A_OTP || !MAILBOX_PROTOCOL(ctl))
 
 /*
  * Definitions for buffer sizes.  We get little help on setting maxima
index 5342b8a5755a38dc60cb5fbe0b28c2dde019bf3f..9de9e9c90d6d994d1d25de3793f562c8a07b788b 100644 (file)
@@ -502,19 +502,21 @@ when interface data is being collected.
 This option permits you to specify an authentication type (see USER
 AUTHENTICATION below for details).  The possible values are \fBany\fR,
 \&`\fBpassword\fR', `\fBkerberos_v5\fR' and `\fBkerberos\fR' (or, for
-excruciating exactness, `\fBkerberos_v4\fR'), \fRgssapi\fR, and
-\fBssh\fR.  When \fBany\fR (the default) is specified, fetchmail tries
-first methods that don't require a password (GSSAPI, KERBEROS_IV);
-then it looks for methods that mask your password (CRAM-MD5, X-OTP);
-and only if it the server doesn't support any of those will it ship
-your password en clair.  Other values may be used to force various
-authentication methods (\fBssh\fR suppresses authentication).  Any
-value other than "password" suppresses fetchmail's normal inquiry for
-a password.  Specify \fBssh\fR when you are using an end-to-end secure
-connection such as an ssh tunnel; specify \fRgssapi\fR or
-\fBkerberos_v4\fR if you are using a protocol variant that employs
-GSSAPI or K4.  Choosing KPOP protocol automatically selects Kerberos
-authentication.  This option does not work with ETRN or ODMR.
+excruciating exactness, `\fBkerberos_v4\fR'), \fRgssapi\fR,
+\fIcram-md5\fR, \fIotp\fR, and \fBssh\fR.  When \fBany\fR (the
+default) is specified, fetchmail tries first methods that don't
+require a password (GSSAPI, KERBEROS_IV); then it looks for methods
+that mask your password (CRAM-MD5, X-OTP); and only if the server
+doesn't support any of those will it ship your password en clair.
+Other values may be used to force various authentication methods
+(\fBssh\fR suppresses authentication).  Any value other than
+\fIpassword\fR, \fIcram-md5\fR or \fIotp\fR suppresses fetchmail's
+normal inquiry for a password.  Specify \fBssh\fR when you are using
+an end-to-end secure connection such as an ssh tunnel; specify
+\fRgssapi\fR or \fBkerberos_v4\fR if you are using a protocol variant
+that employs GSSAPI or K4.  Choosing KPOP protocol automatically
+selects Kerberos authentication.  This option does not work with ETRN
+or ODMR.
 .SS Miscellaneous Options
 .TP
 .B \-f <pathname>, --fetchmailrc <pathname>
diff --git a/pop3.c b/pop3.c
index 7684b1a179ed3d1a3b9efab83f305202597e74d4..c5b6d58c09ebcf552c4177752d9cdf7a76d9493b 100644 (file)
--- a/pop3.c
+++ b/pop3.c
@@ -167,35 +167,12 @@ int pop3_getauth(int sock, struct query *ctl, char *greeting)
        }
 #endif /* RPA_ENABLE */
 
-#if OPIE_ENABLE
-       /* see RFC1938: A One-Time Password System */
-       if (challenge = strstr(lastok, "otp-")) {
-         char response[OPIE_RESPONSE_MAX+1];
-         int i;
-
-         i = opiegenerator(challenge, !strcmp(ctl->password, "opie") ? "" : ctl->password, response);
-         if ((i == -2) && !run.poll_interval) {
-           char secret[OPIE_SECRET_MAX+1];
-           fprintf(stderr, _("Secret pass phrase: "));
-           if (opiereadpass(secret, sizeof(secret), 0))
-             i = opiegenerator(challenge,  secret, response);
-           memset(secret, 0, sizeof(secret));
-         };
-
-         if (i) {
-           ok = PS_ERROR;
-           break;
-         };
-
-         ok = gen_transact(sock, "PASS %s", response);
-         break;
-       }
-#endif /* OPIE_ENABLE */
-
        /*
-        * CAPA command may return a list of available mechanisms.
-        * if it doesn't, no harm done, we just fall back to a 
-        * plain login.
+        * CAPA command may return a list including available
+        * authentication mechanisms.  if it doesn't, no harm done, we
+        * just fall back to a plain login.  Note that this code 
+        * latches the server's authentication type, so that in daemon mode
+        * the CAPA check only needs to be done once at start of run.
         *
         * APOP was introduced in RFC 1450, and CAPA not until
         * RFC2449. So the < check is an easy way to prevent CAPA from
@@ -204,7 +181,7 @@ int pop3_getauth(int sock, struct query *ctl, char *greeting)
         * it.  This certainly catches IMAP-2000's POP3 gateway.
         * 
         * These authentication methods are blessed by RFC1734,
-        * describing the POP3 AUTHentication command. 
+        * describing the POP3 AUTHentication command.
         */
        if (ctl->server.authenticate == A_ANY 
            && strchr(greeting, '<') 
@@ -235,35 +212,53 @@ int pop3_getauth(int sock, struct query *ctl, char *greeting)
                if (strstr(buffer, "KERBEROS_V4"))
                    has_kerberos = TRUE;
 #endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
-               if (strstr(buffer, "CRAM-MD5"))
-                   has_cram = TRUE;
 #ifdef OPIE_ENABLE
                if (strstr(buffer, "X-OTP"))
-                   has_opie = TRUE;
+                   has_otp = TRUE;
 #endif /* OPIE_ENABLE */
+               if (strstr(buffer, "CRAM-MD5"))
+                   has_cram = TRUE;
            }
 
+           /*
+            * Here's where we set priorities.  Note that we must do tests
+            * in *reverse* order of desirability.
+            */
+           if (has_cram)
+               ctl->server.authenticate = A_CRAM_MD5;
+#ifdef OPIE_ENABLE
+           if (has_opie)
+               ctl->server.authenticate = A_OTP;
+#endif /* OPIE_ENABLE */
 #if defined(GSSAPI)
-           if ((ctl->server.authenticate == A_ANY 
-                || ctl->server.authenticate==A_GSSAPI)
-               && has_gssapi)
-               return(do_gssauth(sock, "AUTH", 
-                                 ctl->server.truename, ctl->remotename));
+           if (has_gssapi)
+               ctl->server.authenticate = A_GSSAPI;
 #endif /* defined(GSSAPI) */
 #if defined(KERBEROS_V4) || defined(KERBEROS_V5)
-           if ((ctl->server.authenticate == A_ANY 
-                || ctl->server.authenticate==A_KERBEROS_V4
-                || ctl->server.authenticate==A_KERBEROS_V5)
-               && has_kerberos)
-               return(do_rfc1731(sock, "AUTH", ctl->server.truename));
+           if (has_kerberos)
+               ctl->server.authenticate = A_KERBEROS_V4;
 #endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
-           if (has_cram)
-               return(do_cram_md5(sock, "AUTH", ctl));
+       }
+
+       /*
+        * OK, we have an authentication type now.
+        */
+#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
+       if (ctl->server.authenticate == A_KERBEROS_V4
+               || ctl->server.authenticate == A_KERBEROS_V5)
+           return(do_rfc1731(sock, "AUTH", ctl->server.truename));
+#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
+#if defined(GSSAPI)
+       if (ctl->server.authenticate==A_GSSAPI))
+           return(do_gssauth(sock, "AUTH", 
+                             ctl->server.truename, ctl->remotename));
+#endif /* defined(GSSAPI) */
 #ifdef OPIE_ENABLE
-           if (has_opie)
-               do_otp(sock, "AUTH", ctl)
+       if (ctl->server.authenticate == A_OTP)
+           do_otp(sock, "AUTH", ctl)
 #endif /* OPIE_ENABLE */
-       }
+       if (ctl->server.authenticate == A_CRAM_MD5)
+           return(do_cram_md5(sock, "AUTH", ctl));
 
        /* ordinary validation, no one-time password or RPA */ 
        gen_transact(sock, "USER %s", ctl->remotename);