]> Pileus Git - ~andy/fetchmail/commitdiff
Kerberos V support.
authorEric S. Raymond <esr@thyrsus.com>
Tue, 3 Mar 1998 21:22:36 +0000 (21:22 -0000)
committerEric S. Raymond <esr@thyrsus.com>
Tue, 3 Mar 1998 21:22:36 +0000 (21:22 -0000)
svn path=/trunk/; revision=1682

12 files changed:
INSTALL
NEWS
configure.in
driver.c
fetchmail-features.html
fetchmail.c
fetchmail.h
fetchmail.man
options.c
rcfile_l.l
rcfile_y.y
sample.rcfile

diff --git a/INSTALL b/INSTALL
index 3fa58e6d85d63e68c62db718de0e47c89cb96f37..3e4c1530ca2d05b5750bae172a8b482d25b87e5d 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -70,10 +70,10 @@ will do that.
 
 Advanced configuration:
 
-Specifying --with-kerberos=DIR will tell the fetchmail build process to
-look in DIR for Kerberos support.  Configure normally looks in /usr/kerberos
-and /usr/athena; if you specify this option with an argument it will look
-in DIR first. 
+Specifying --with-kerberos=DIR or --with-kerberos5=DIR will tell the
+fetchmail build process to look in DIR for Kerberos support.
+Configure normally looks in /usr/kerberos and /usr/athena; if you
+specify this option with an argument it will look in DIR first.
 
 Unfortunately, there doesn't seem to be good standardization of where
 Kerberos lives.  If your configuration doesn't match one of the four
diff --git a/NEWS b/NEWS
index 42978eb3f2dbe34b3339a40b8efef4bbe2de09b7..fbebfaf534f10cceeb285a4662a3e2e1c631a093 100644 (file)
--- a/NEWS
+++ b/NEWS
 * Make the antispam response configurable.
 * Handle multi-homed hosts correctly.
 
-                               Other TO-DO items:
-
-* Get with Craig Metz to write a draft RFC on RFC1938 support in IMAP.
-
                                Release Notes:
 
 ------------------------------------------------------------------------------
@@ -22,6 +18,8 @@ fetchmail-4.4.0 ():
 * Relax the LOGIN capability check in IMAP.
 * John Stracke <francis@netscape.com> sent a workaround for SIGALRM flakiness
   under Red Hat 5.0.
+* Kerberos V support from Jon Dugan <jdugan@ncsa.uiuc.edu> and
+  Von Welch <vwelch@ncsa.uiuc.edu>.
 
 There are 269 people on fetchmail-friends and 144 on fetchmail-announce.
 
index 8fd6d8e7da67a3e79f6db9b22620fd12dae81c69..b9354b9457bc8107bd850e4b601d61378683d9ec 100644 (file)
@@ -265,6 +265,31 @@ else
     done
 fi
 
+###    use option --with-kerberos5=DIR to point at a Kerberos 5 directory
+AC_ARG_WITH(kerberos5,
+       [  --with-kerberos5=DIR  point fetchmail compilation at a Kerberos 5 directory])
+
+# The "then" arm (nonempty $with_kerberos5) is kind of a crock.  It works for
+# configuring the BSD/OS Kerberos IV support, though. 
+if test "$with_kerberos5" != "yes"
+then
+    # Path given
+    CEFLAGS="$CEFLAGS -DKERBEROS_V5 -I$with_kerberos5/include"
+    LDEFLAGS="$LDEFLAGS -L$with_kerberos5/lib"
+    LIBS="$LIBS -lkrb5 -lcrypto -lcom_err"
+else
+    for dir in /usr/kerberos /usr/local/krb5 /usr/athena
+    do
+      if test -f "$dir/include/krb5.h"
+      then
+        CEFLAGS="$CEFLAGS -DKERBEROS_V5 -I$dir/include"
+        LDEFLAGS="$LDEFLAGS -L$dir/lib"
+        LIBS="$LIBS -lkrb5 -lcrypto -lcom_err"
+        break
+      fi
+    done
+fi
+
 AC_OUTPUT(Makefile, [
        # The reason for this odd makedepend line is that we want
        # to have all dependencies evaluated relative to the source directory
index 07732a8770f69ad7e46a8d7e6874af054ee40e40..e697091cc6044680283e54bda44022d83f704a61 100644 (file)
--- a/driver.c
+++ b/driver.c
 #include <netinet/in.h>
 #include <netdb.h>
 #endif /* KERBEROS_V4 */
+#ifdef KERBEROS_V5
+#include <krb5.h>
+#include <com_err.h>
+#endif /* KEREROS_V5 */
+
 #include  "fetchmail.h"
 #include  "socket.h"
 #include  "smtp.h"
@@ -1593,6 +1598,72 @@ const char *canonical;   /* server name */
 }
 #endif /* KERBEROS_V4 */
 
+#ifdef KERBEROS_V5
+int
+kerberos5_auth(socket, canonical)
+/* authernticate to the server host using Kerberos V5 */
+int socket;             /* socket to server host */
+const char *canonical;  /* server name */
+{
+    krb5_error_code retval;
+    krb5_context context;
+    krb5_ccache ccdef;
+    krb5_principal client = NULL, server = NULL;
+    krb5_error *err_ret = NULL;
+
+    krb5_auth_context auth_context = NULL;
+
+    krb5_init_context(&context);
+    krb5_init_ets(context);
+    krb5_auth_con_init(context, &auth_context);
+
+    if (retval = krb5_cc_default(context, &ccdef)) {
+        error(0, 0, "krb5_cc_default: %s", error_message(retval));
+        return(PS_ERROR);
+    }
+
+    if (retval = krb5_cc_get_principal(context, ccdef, &client)) {
+        error(0, 0, "krb5_cc_get_principal: %s", error_message(retval));
+        return(PS_ERROR);
+    }
+
+    if (retval = krb5_sname_to_principal(context, canonical, "pop",
+           KRB5_NT_UNKNOWN,
+           &server)) {
+        error(0, 0, "krb5_sname_to_principal: %s", error_message(retval));
+        return(PS_ERROR);
+    }
+
+    retval = krb5_sendauth(context, &auth_context, (krb5_pointer) &socket,
+         "KPOPV1.0", client, server,
+         AP_OPTS_MUTUAL_REQUIRED,
+         NULL,  /* no data to checksum */
+         0,   /* no creds, use ccache instead */
+         ccdef,
+         &err_ret, 0,
+
+         NULL); /* don't need reply */
+
+    krb5_free_principal(context, server);
+    krb5_free_principal(context, client);
+    krb5_auth_con_free(context, auth_context);
+
+    if (retval) {
+      if (err_ret && err_ret->text.length) {
+          error(0, 0, "krb5_sendauth: %s [server says '%*s'] ",
+            error_message(retval),
+            err_ret->text.length,
+            err_ret->text.data);
+          krb5_free_error(context, err_ret);
+      } else
+          error(0, 0, "krb5_sendauth: %s", error_message(retval));
+      return(PS_ERROR);
+    }
+
+    return 0;
+}
+#endif /* KERBEROS_V5 */
+
 int do_protocol(ctl, proto)
 /* retrieve messages from server using given protocol method table */
 struct query *ctl;             /* parsed options with merged-in defaults */
@@ -1610,6 +1681,14 @@ const struct method *proto;      /* protocol method table */
     }
 #endif /* KERBEROS_V4 */
 
+#ifndef KERBEROS_V5
+    if (ctl->server.preauthenticate == A_KERBEROS_V5)
+    {
+       error(0, -1, "Kerberos V5 support not linked.");
+       return(PS_ERROR);
+    }
+#endif /* KERBEROS_V5 */
+
     /* lacking methods, there are some options that may fail */
     if (!proto->is_old)
     {
@@ -1738,6 +1817,16 @@ const struct method *proto;      /* protocol method table */
        }
 #endif /* KERBEROS_V4 */
 
+#ifdef KERBEROS_V5
+       if (ctl->server.preauthenticate == A_KERBEROS_V5)
+       {
+           ok = kerberos5_auth(sock, ctl->server.truename);
+           if (ok != 0)
+               goto cleanUp;
+           set_timeout(ctl->server.timeout);
+       }
+#endif /* KERBEROS_V5 */
+
        /* accept greeting message from mail server */
        ok = (protocol->parse_response)(sock, buf);
        if (ok != 0)
index 295f1e3637f719d7079b31b2e54323cec0c3bc83..42cbcf877bec45931b35009c1b719176458a8992 100644 (file)
@@ -10,7 +10,7 @@
 <table width="100%" cellpadding=0><tr>
 <td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
 <td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 1998/02/24 20:55:14 $
+<td width="30%" align=right>$Date: 1998/03/03 21:22:31 $
 </table>
 <HR>
 
@@ -21,6 +21,8 @@ are listed first. <P>
 
 <H2>Since 4.0:</H2>
 <UL>
+<LI> Support for Kerberos V authentication.
+
 <LI> Support for IMAP-OTP authentication using Craig Metz's patches 
      for UW IMAP.
 
@@ -139,7 +141,7 @@ get-mail, gwpop, pimp-1.0, pop-perl5-1.2, popc, popmail-1.6 and upop.<P>
 <table width="100%" cellpadding=0><tr>
 <td width="30%">Back to <a href="index.html">Fetchmail Home Page</a>
 <td width="30%" align=center>To <a href="/~esr/sitemap.html">Site Map</a>
-<td width="30%" align=right>$Date: 1998/02/24 20:55:14 $
+<td width="30%" align=right>$Date: 1998/03/03 21:22:31 $
 </table>
 
 <P><ADDRESS>Eric S. Raymond <A HREF="mailto:esr@thyrsus.com">&lt;esr@snark.thyrsus.com&gt;</A></ADDRESS>
index 629a95af0c2bf9f15d0742d15d06c1724b656740..7c4be484e0cee5c4cf83fc9102716be40d269030 100644 (file)
@@ -325,7 +325,10 @@ int main (int argc, char **argv)
     for (ctl = querylist; ctl; ctl = ctl->next)
        if (ctl->active && !(implicitmode && ctl->server.skip)&&!ctl->password)
        {
-           if (ctl->server.preauthenticate == A_KERBEROS_V4 || ctl->server.protocol == P_IMAP_K4 || ctl->server.protocol == P_IMAP_GSS)
+           if (ctl->server.preauthenticate == A_KERBEROS_V4 ||
+               ctl->server.preauthenticate == A_KERBEROS_V5 ||
+               ctl->server.protocol == P_IMAP_K4 ||
+               ctl->server.protocol == P_IMAP_GSS)
                /* Server won't care what the password is, but there
                   must be some non-null string here.  */
                ctl->password = ctl->remotename;
@@ -450,7 +453,9 @@ int main (int argc, char **argv)
                 * nameserver is still up.  The multidrop case
                 * (especially) needs it.
                 */
-               if (ctl->server.preauthenticate==A_KERBEROS_V4 || MULTIDROP(ctl))
+               if (ctl->server.preauthenticate==A_KERBEROS_V4 ||
+                   ctl->server.preauthenticate==A_KERBEROS_V5 ||
+                   MULTIDROP(ctl))
                {
                    struct hostent      *namerec;
 
@@ -997,7 +1002,8 @@ void dump_params (struct query *ctl)
 #else /* INET6 */
                && ctl->server.port == KPOP_PORT
 #endif /* INET6 */
-               && ctl->server.preauthenticate == A_KERBEROS_V4)
+               && (ctl->server.preauthenticate == A_KERBEROS_V4 ||
+                   ctl->server.preauthenticate == A_KERBEROS_V5))
        printf("  Protocol is KPOP");
     else
        printf("  Protocol is %s", showproto(ctl->server.protocol));
@@ -1018,6 +1024,8 @@ void dump_params (struct query *ctl)
     putchar('\n');
     if (ctl->server.preauthenticate == A_KERBEROS_V4)
            printf("  Kerberos V4 preauthentication enabled.\n");
+    if (ctl->server.preauthenticate == A_KERBEROS_V5)
+           printf("  Kerberos V5 preauthentication enabled.\n");
     if (ctl->server.timeout > 0)
        printf("  Server nonresponse timeout is %d seconds", ctl->server.timeout);
     if (ctl->server.timeout ==  CLIENT_TIMEOUT)
index 021df0369b1a6313ae7dfc1cf7a9c33fe7b506ee..b7eefb5b29f0427265bb42976e611fa1bfc7f352 100644 (file)
@@ -22,6 +22,7 @@
 /* preauthentication types */
 #define                A_PASSWORD      0       /* password or inline authentication */
 #define                A_KERBEROS_V4   1       /* preauthenticate w/ Kerberos V4 */
+#define                A_KERBEROS_V5   2       /* preauthenticate w/ Kerberos V5 */
 
 /*
  * Definitions for buffer sizes.  We get little help on setting maxima
index a339dea73ff04cbb318e31d1c3ed3b7ddeda107d..deded9db6c62db1c6f7e9e0b0ab26da33bf9f732 100644 (file)
@@ -328,16 +328,16 @@ no other activity has occurred on the link, then the poll will be
 skipped.  This option is currently only supported under Linux.
 .TP
 .B \-A, --auth
-(Keyword: auth[enticate])
+(Keyword: auth[enticate]) 
 This option permits you to specify a preauthentication type (see USER
 AUTHENTICATION below for details).  The possible values are
-\&`\fBpassword\fR' and `\fBkerberos\fR' (or, for excruciating
-exactness, `\fBkerberos_v4\fR').  This option is provided
+\&`\fBpassword\fR', `\fBkerberos_v5\fR' and `\fBkerberos\fR' (or, for
+excruciating exactness, `\fBkerberos_v4\fR').  This option is provided
 primarily for developers; choosing KPOP protocol automatically selects
-Kerberos preauthentication, and all other alternatives use
-password authentication (though APOP uses a generated one-time
-key as the password and IMAP-K4 uses RFC1731 Kerberos v4 authentication).
-This option does not work with ETRN.
+Kerberos preauthentication, and all other alternatives use password
+authentication (though APOP uses a generated one-time key as the
+password and IMAP-K4 uses RFC1731 Kerberos v4 authentication).  This
+option does not work with ETRN.
 .SS Miscellaneous Options
 .TP
 .B \-f pathname, --fetchmailrc pathname
index 9849299fe7156f05c0f6b0b5b5d472c812178c9e..b16d00418d7df07c40ebf8ae7cebd7d710010e69 100644 (file)
--- a/options.c
+++ b/options.c
@@ -211,7 +211,11 @@ struct query *ctl; /* option record to be initialized */
 #else /* INET6 */
                ctl->server.port = KPOP_PORT;
 #endif /* INET6 */
+#ifdef KERBEROS_V5
+               ctl->server.preauthenticate =  A_KERBEROS_V5;
+#else
                ctl->server.preauthenticate =  A_KERBEROS_V4;
+#endif /* KERBEROS_V5 */
            }
            else if (strcasecmp(optarg,"imap") == 0)
                ctl->server.protocol = P_IMAP;
@@ -243,9 +247,15 @@ struct query *ctl; /* option record to be initialized */
            if (strcmp(optarg, "password") == 0)
                ctl->server.preauthenticate = A_PASSWORD;
            else if (strcmp(optarg, "kerberos") == 0)
+#ifdef KERBEROS_V5
+               ctl->server.preauthenticate = A_KERBEROS_V5;
+           else if (strcmp(optarg, "kerberos_v5") == 0)
+               ctl->server.preauthenticate = A_KERBEROS_V5;
+#else
                ctl->server.preauthenticate = A_KERBEROS_V4;
            else if (strcmp(optarg, "kerberos_v4") == 0)
                ctl->server.preauthenticate = A_KERBEROS_V4;
+#endif /* KERBEROS_V5 */
            else {
                fprintf(stderr,"Invalid preauthentication `%s' specified.\n", optarg);
                errflag++;
index 4d19be5906e0d0bc58ee4d37af7b2c30cad39432..c55f718054dec4778339183aad4704174fb76244 100644 (file)
@@ -40,7 +40,8 @@ port          { return PORT; }
 interval       { return INTERVAL; }
 auth(enticate)?        { return AUTHENTICATE; }
 kerberos_v4    { return KERBEROS4; }
-kerberos       { return KERBEROS4; }
+kerberos       { return KERBEROS; }
+kerberos_v5     { return KERBEROS5; }
 timeout                { return TIMEOUT;}
 envelope       { return ENVELOPE; }
 qvirtual       { return QVIRTUAL; }
index cb63fbf1efdbb4cb67a3b81979af983797ca4579..110e80815213dd7b43645475570b56b2fc19dd72 100644 (file)
@@ -62,7 +62,7 @@ extern char * yytext;
 }
 
 %token DEFAULTS POLL SKIP VIA AKA LOCALDOMAINS PROTOCOL
-%token AUTHENTICATE TIMEOUT KPOP KERBEROS4
+%token AUTHENTICATE TIMEOUT KPOP KERBEROS4 KERBEROS5 KERBEROS
 %token ENVELOPE QVIRTUAL USERNAME PASSWORD FOLDER SMTPHOST MDA SMTPADDRESS
 %token PRECONNECT POSTCONNECT LIMIT
 %token IS HERE THERE TO MAP WILDCARD
@@ -129,7 +129,11 @@ serv_option        : AKA alias_list
                | PROTOCOL PROTO        {current.server.protocol = $2;}
                | PROTOCOL KPOP         {
                                            current.server.protocol = P_POP3;
+#ifdef KERBEROS_V5
+                                           current.server.preauthenticate = A_KERBEROS_V5;
+#else
                                            current.server.preauthenticate = A_KERBEROS_V4;
+#endif /* KERBEROS_V5 */
 #if INET6
                                            current.server.service = KPOP_PORT;
 #else /* INET6 */
@@ -151,6 +155,14 @@ serv_option        : AKA alias_list
                | INTERVAL NUMBER               {current.server.interval = $2;}
                | AUTHENTICATE PASSWORD {current.server.preauthenticate = A_PASSWORD;}
                | AUTHENTICATE KERBEROS4        {current.server.preauthenticate = A_KERBEROS_V4;}
+                | AUTHENTICATE KERBEROS5       {current.server.preauthenticate = A_KERBEROS_V5;}
+                | AUTHENTICATE KERBEROS         {
+#ifdef KERBEROS_V5
+                   current.server.preauthenticate = A_KERBEROS_V5;
+#else
+                   current.server.preauthenticate = A_KERBEROS_V4;
+#endif /* KERBEROS_V5 */
+               }
                | TIMEOUT NUMBER        {current.server.timeout = $2;}
 
                | ENVELOPE NUMBER STRING 
index 5f2846315f6a42a4f2f1723065d81e951e17249e..facb95c3a21319e1466f0096222560dfc6e975de 100644 (file)
@@ -83,6 +83,7 @@
 # Legal authentication types are
 #   login
 #   kerberos
+#   kerberos_v5
 #
 # Legal global option statements are
 #