diff -urN alpine-1.00+hesiod/imap/Makefile alpine-1.00+krb4/imap/Makefile
--- alpine-1.00+hesiod/imap/Makefile	2007-12-20 17:18:28.000000000 -0500
+++ alpine-1.00+krb4/imap/Makefile	2007-12-24 14:33:48.000000000 -0500
@@ -660,6 +660,7 @@
 	$(TOOLS)/$@ "$(LN)" src/c-client c-client
 	$(TOOLS)/$@ "$(LN)" src/ansilib c-client
 	$(TOOLS)/$@ "$(LN)" src/charset c-client
+	sh -c '(test -d src/kerberos) && ($(LN) `pwd`/src/kerberos/* c-client) || true'
 	$(TOOLS)/$@ "$(LN)" src/osdep/$(SYSTEM) c-client
 	$(TOOLS)/$@ "$(LN)" src/mtest mtest
 	$(TOOLS)/$@ "$(LN)" src/ipopd ipopd
diff -urN alpine-1.00+hesiod/imap/src/c-client/mail.c alpine-1.00+krb4/imap/src/c-client/mail.c
--- alpine-1.00+hesiod/imap/src/c-client/mail.c	2007-12-24 14:30:04.000000000 -0500
+++ alpine-1.00+krb4/imap/src/c-client/mail.c	2007-12-24 14:33:48.000000000 -0500
@@ -780,6 +780,12 @@
     }
   }
 
+#ifdef KERBEROS
+  /* kpop runs on a different port from pop3, so we have to set an override. */
+  if (!mb->port && mb->krbflag && !strcmp (mb->service,"pop3"))
+    mb->port = 1109;
+#endif
+
   hesiod_free_postoffice (hcontext,office);
   hesiod_end (hcontext);
 
@@ -878,6 +884,9 @@
 #ifdef HESIOD
 	else if (!compare_cstring (s,"hesiod")) mb->hesflag = T;
 #endif
+#ifdef KERBEROS
+	else if (!compare_cstring (s,"kerberos")) mb->krbflag = T;
+#endif
 	else if (!compare_cstring (s,"readonly")) mb->readonlyflag = T;
 	else if (!compare_cstring (s,"secure")) mb->secflag = T;
 	else if (!compare_cstring (s,"norsh")) mb->norsh = T;
diff -urN alpine-1.00+hesiod/imap/src/c-client/mail.h alpine-1.00+krb4/imap/src/c-client/mail.h
--- alpine-1.00+hesiod/imap/src/c-client/mail.h	2007-12-24 14:31:08.000000000 -0500
+++ alpine-1.00+krb4/imap/src/c-client/mail.h	2007-12-24 14:33:48.000000000 -0500
@@ -665,6 +665,9 @@
 #ifdef HESIOD
   unsigned int hesflag : 1;	/* Hesiod flag */
 #endif
+#ifdef KERBEROS
+  unsigned int krbflag : 1;    /* Kerberos flag */
+#endif
 } NETMBX;
 
 /* Item in an address list */
diff -urN alpine-1.00+hesiod/imap/src/c-client/pop3.c alpine-1.00+krb4/imap/src/c-client/pop3.c
--- alpine-1.00+hesiod/imap/src/c-client/pop3.c	2007-04-04 22:11:38.000000000 -0400
+++ alpine-1.00+krb4/imap/src/c-client/pop3.c	2007-12-24 14:33:48.000000000 -0500
@@ -561,6 +561,23 @@
   NETDRIVER *ssld = (NETDRIVER *) mail_parameters (NIL,GET_SSLDRIVER,NIL);
   sslstart_t stls = (sslstart_t) mail_parameters (NIL,GET_SSLSTART,NIL);
 				/* server has TLS? */
+
+#ifdef KERBEROS
+  if (mb->krbflag) {
+    /* We already took care of sending the ticket in tcp_unix.c, since
+     * that has to happen before the read of the server greeting.  So
+     * we just need to send the username here. */
+    if (mb->user && *mb->user)
+      strcpy (usr,mb->user);
+    else
+      strcpy (usr,myusername());
+    /* Send same PASS as USER. */
+    if (pop3_send (stream,"USER",usr) && pop3_send (stream,"PASS",usr))
+      return LONGT;		/* success */
+    else
+      return NIL;
+  }
+#endif
   if (stls && LOCAL->cap.stls && !mb->sslflag && !mb->notlsflag &&
       pop3_send (stream,"STLS",NIL)) {
     mb->tlsflag = T;		/* TLS OK, get into TLS at this end */
diff -urN alpine-1.00+hesiod/imap/src/kerberos/acte.c alpine-1.00+krb4/imap/src/kerberos/acte.c
--- alpine-1.00+hesiod/imap/src/kerberos/acte.c	1969-12-31 19:00:00.000000000 -0500
+++ alpine-1.00+krb4/imap/src/kerberos/acte.c	2007-12-24 14:33:48.000000000 -0500
@@ -0,0 +1,48 @@
+/* acte.c -- Common functions for SASL mechanisms 
+ *
+ *	(C) Copyright 1994 by Carnegie Mellon University
+ *
+ *                      All Rights Reserved
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ */
+
+#include "acte.h"
+
+char *acte_prottostring(protlevel)
+int protlevel;
+{
+    switch (protlevel) {
+    case ACTE_PROT_NONE:
+	return "no protection";
+
+    case ACTE_PROT_INTEGRITY:
+	return "integrity protection";
+
+    case ACTE_PROT_PRIVACY:
+	return "privacy protection";
+
+    default:
+	return "unknown";
+    }
+}
diff -urN alpine-1.00+hesiod/imap/src/kerberos/acte.h alpine-1.00+krb4/imap/src/kerberos/acte.h
--- alpine-1.00+hesiod/imap/src/kerberos/acte.h	1969-12-31 19:00:00.000000000 -0500
+++ alpine-1.00+krb4/imap/src/kerberos/acte.h	2007-12-24 14:33:48.000000000 -0500
@@ -0,0 +1,124 @@
+/* acte.h -- Interface for IMAP AUTHENTICATE mechanisms 
+ *
+ *	(C) Copyright 1994,1996 by Carnegie Mellon University
+ *
+ *                      All Rights Reserved
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ */
+
+#ifndef INCLUDED_ACTE_H
+#define INCLUDED_ACTE_H
+
+#ifndef P
+#ifdef __STDC__
+#define P(x) x
+#else
+#define P(x) ()
+#endif
+#endif
+
+#include <time.h>
+
+struct sockaddr;
+
+typedef const char *acte_encodefunc_t P((void *state,
+					  char *input, int inputlen,
+					  char *output, int *outputlen));
+typedef const char *acte_decodefunc_t P((void *state,
+					  char *input, int inputlen,
+					  char **output, int *outputlen));
+typedef int acte_authproc_t P((const char *user, const char *auth_identity,
+			       const char **reply));
+
+/* Client-side authentication mechanism */
+struct acte_client {
+    /* Name of authentication mechanism */
+    char *auth_type;
+
+    /* Start a client->server authentication */
+    int (*start) P((const char *service, const char *host, const char *user,
+		    int protallowed, int maxbufsize,
+		    struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+		    void **state, char *u_out));
+
+    /* Do an authentication protocol exchange */
+    int (*auth) P((void *state, int inputlen, char *input,
+		   int *outputlen, char **output));
+    
+    /* Query an authentication state */
+    void (*query_state) P((void *state, char **user, int *protlevel,
+			   acte_encodefunc_t **encodefunc,
+			   acte_decodefunc_t **decodefunc, int *maxplain));
+
+    /* Free an authentication state */
+    void (*free_state) P((void *state));
+    
+    /* Acquire daemon's credentials */
+    const char *(*new_cred) P((const char *service, time_t *lifetime));	
+
+    /* Free daemon's credentials */
+    void (*free_cred) P((void));
+};
+
+/* Server-side authentication mechanism */
+struct acte_server {
+    /* Name of authentication mechanism */
+    char *auth_type;		
+
+    /* Start an incoming authentication */
+    int (*start) P((const char *service, acte_authproc_t *authproc,
+		    int protallowed, int maxbufsize,
+		    struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+		    int *outputlen, char **output,
+		    void **state, const char ** reply));
+    
+    /* Do an authentication protocol exchange */
+    int (*auth) P((void *state, int inputlen, char *input,
+		   int *outputlen, char **output, const char **reply));
+
+    /* Query an authentication state */
+    void (*query_state) P((void *state, char **user, int *protlevel,
+			   acte_encodefunc_t **encodefunc,
+			   acte_decodefunc_t **decodefunc, int *maxplain));
+
+    /* Free an authentication state */
+    void (*free_state) P((void *state));
+    
+    /* Get a cacheid, if available */
+    char *(*get_cacheid) P((void *state));
+};
+
+/* Protection mechanisms */
+#define ACTE_PROT_NONE 1
+#define ACTE_PROT_INTEGRITY 2
+#define ACTE_PROT_PRIVACY 4
+#define ACTE_PROT_ANY (ACTE_PROT_NONE|ACTE_PROT_INTEGRITY|ACTE_PROT_PRIVACY)
+
+#define ACTE_FAIL 1		/* Authentication failed */
+
+#define ACTE_DONE 3		/* Server has authenticated user */
+
+extern char *acte_prottostring P((int protlevel));
+
+#endif /* INCLUDED_ACTE_H */
diff -urN alpine-1.00+hesiod/imap/src/kerberos/acte_krb.c alpine-1.00+krb4/imap/src/kerberos/acte_krb.c
--- alpine-1.00+hesiod/imap/src/kerberos/acte_krb.c	1969-12-31 19:00:00.000000000 -0500
+++ alpine-1.00+krb4/imap/src/kerberos/acte_krb.c	2007-12-24 14:33:48.000000000 -0500
@@ -0,0 +1,874 @@
+/* acte_krb.c -- KERBEROS_V4 authentication routines for IMAP.
+ *
+ *	(C) Copyright 1994 by Carnegie Mellon University
+ *
+ *                      All Rights Reserved
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of Carnegie
+ * Mellon University not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission.  Carnegie Mellon University makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied
+ * warranty.
+ *
+ * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <krb.h>
+
+#include "acte.h"
+
+#ifndef HAVE_KRB_GET_PHOST
+extern char *krb_get_phost P((char *));
+#endif
+
+#ifndef HAVE_KRB_REALMOFHOST
+extern char *krb_realmofhost P((char *));
+#endif
+
+static char *srvtab = "";	/* Srvtab filename */
+
+/* Maximum number of bytes of overhead the protection mechanisms use */
+#define PROTECTION_OVERHEAD 31
+
+/* Private state used by this mechanism */
+struct krb_state {
+    /* common */
+    char service[MAX_K_NAME_SZ+1];
+    int authstepno;
+    des_cblock session;	/* Our session key */
+    des_key_schedule schedule; /* Schedule for our session key */
+    long challenge;
+    char user[MAX_K_NAME_SZ+1];
+    int protallowed;
+    int maxbufsize;
+    struct sockaddr_in localaddr, remoteaddr;
+    long prot_time_sec;
+    char prot_time_5ms;
+    /* client */
+    char instance[INST_SZ];
+    char realm[REALM_SZ];
+    /* server */
+    int (*authproc)();
+    AUTH_DAT kdata;
+};
+
+/*
+ * Free the space used by an opaque state pointer
+ */
+static void
+krb_free_state(state)
+void *state;
+{
+    memset((char *)state, 0, sizeof(struct krb_state));
+    free((char *) state);
+}
+
+static acte_encodefunc_t krb_en_integrity;
+static acte_decodefunc_t krb_de_integrity;
+#ifndef NOPRIVACY
+static acte_encodefunc_t krb_en_privacy;
+static acte_decodefunc_t krb_de_privacy;
+#endif
+
+/*
+ * Query public values of the state pointer after authentiation
+ * complete.  Fills in buffers pointed to by the following arguments:
+ *
+ * user       -- IMAP userid authenticated as
+ * protlevel  -- bitmask for selected protection mechanism
+ * encodefunc -- if nonzero, protection mechanism function to encode
+ *               outgoing data with.
+ * decodefunc -- if nonzero, protection mechanism function to decode
+ *               incoming data with.
+ * maxplain   -- The maximum number of bytes that may be encoded by
+ *                the encodefunc at one time
+ */
+static void 
+krb_query_state(state, user, protlevel, encodefunc, decodefunc, maxplain)
+void *state;
+char **user;
+int *protlevel;
+acte_encodefunc_t **encodefunc;
+acte_decodefunc_t **decodefunc;
+int *maxplain;
+{
+    struct krb_state *kstate = (struct krb_state *)state;
+
+    *user = kstate->user;
+    *protlevel = kstate->protallowed;
+
+    switch (kstate->protallowed) {
+    case ACTE_PROT_NONE:
+	*encodefunc = 0;
+	*decodefunc = 0;
+	*maxplain = 0;
+	return;
+
+    case ACTE_PROT_INTEGRITY:
+	*encodefunc = krb_en_integrity;
+	*decodefunc = krb_de_integrity;
+	*maxplain = kstate->maxbufsize - PROTECTION_OVERHEAD;
+	return;
+
+#ifndef NOPRIVACY
+    case ACTE_PROT_PRIVACY:
+	*encodefunc = krb_en_privacy;
+	*decodefunc = krb_de_privacy;
+	*maxplain = kstate->maxbufsize - PROTECTION_OVERHEAD;
+	return;
+#endif
+
+    default:
+	abort();
+    }
+}
+
+/*
+ * Get the cacheid for 'state'
+ */
+static char *
+krb_get_cacheid(state)
+void *state;
+{
+    char *cacheid;
+
+    struct krb_state *kstate = (struct krb_state *)state;
+
+    cacheid = malloc(16);
+    if (!cacheid) return 0;
+
+    memset(cacheid, 0, sizeof(cacheid));
+    memcpy(cacheid, kstate->session, sizeof(kstate->session));
+    return cacheid;
+}
+
+/*
+ * Start the client side of an authentication exchange.
+ */
+static int krb_client_start(service, host, user, protallowed, maxbufsize,
+			    localaddr, remoteaddr, state, u_out)
+const char *service;		/* Name of service */
+const char *host;		/* Name of server host */
+const char *user;		/* (optional) user to log in as */
+int protallowed;		/* Protection mechanisms allowed */
+int maxbufsize;			/* Maximum ciphertext input buffer size */
+struct sockaddr *localaddr;	/* Network address of local side */
+struct sockaddr *remoteaddr;	/* Network address of remote side */
+void **state;			/* On success, filled in with state ptr */
+char *u_out;                    /* Output buffer for username 
+				 * if non-null must be atleast MAX_K_NAME_SZ+1                                  * large */
+{
+    struct hostent *host_name;
+    char userbuf[MAX_K_NAME_SZ+1];
+    char instance[INST_SZ];
+    char realm[REALM_SZ];
+    char uinst[INST_SZ];
+    char urealm[INST_SZ];
+    KTEXT_ST authent;
+    CREDENTIALS cr;
+    struct krb_state *kstate;
+    char *p;
+
+    protallowed &= ACTE_PROT_NONE|ACTE_PROT_INTEGRITY
+#ifndef NOPRIVACY
+	|ACTE_PROT_PRIVACY
+#endif
+	;
+    if (!localaddr || !remoteaddr) {
+	protallowed &= ACTE_PROT_NONE;
+    }
+    if (!protallowed) {
+	return ACTE_FAIL;
+    }
+    if (maxbufsize > 0xffffff) maxbufsize = 0xffffff;
+
+    /* Canonicalize hostname */
+    host_name = gethostbyname(host);
+    if (!host_name) {
+	return ACTE_FAIL;
+    }
+
+    strncpy(instance, host_name->h_name, sizeof(instance)-1);
+    instance[sizeof(instance)-1] = '\0';
+    /* downcase the instance */
+    p = instance;
+    do {
+      if (isupper(*p)) *p=tolower(*p);
+    } while (*p++);
+    strcpy(realm, krb_realmofhost(instance));
+    if (p = strchr(instance, '.')) *p = '\0';
+
+    /* Fetch imap.hostname service key */
+    (void) krb_mk_req(&authent, service, instance, realm, 0);
+    memset(&authent, 0, sizeof(authent));
+
+    if (krb_get_cred(service, instance, realm, &cr)) {
+	return ACTE_FAIL;
+    }
+    
+    if (!user || !user[0]) {
+	if (krb_get_tf_fullname(TKT_FILE, userbuf, uinst, urealm)) {
+	    memset(&cr, 0, sizeof(cr));
+	    return ACTE_FAIL;
+	}
+	if (uinst[0]) {
+	    strcat(userbuf, ".");
+	    strcat(userbuf, uinst);
+	}
+	if (strcmp(urealm, realm) != 0) {
+	    strcat(userbuf, "@");
+	    strcat(userbuf, urealm);
+	}
+	user = userbuf;
+    }
+    else if (strlen(user) > MAX_K_NAME_SZ) {
+	return ACTE_FAIL;
+    }
+
+    if(u_out) memcpy(u_out, user, strlen(userbuf) + 1);
+
+    kstate = (struct krb_state *)malloc(sizeof(struct krb_state));
+    if (!kstate) return ACTE_FAIL;
+    memset((char *)kstate, 0, sizeof(*kstate));
+    strcpy(kstate->service, service);
+    kstate->authstepno = 0;
+    memcpy(kstate->session, cr.session, sizeof(des_cblock));
+    des_key_sched(kstate->session, kstate->schedule);
+    strcpy(kstate->user, user);
+    kstate->protallowed = protallowed;
+    kstate->maxbufsize = maxbufsize;
+    if (localaddr && remoteaddr) {
+	kstate->localaddr = *(struct sockaddr_in *)localaddr;
+	kstate->remoteaddr = *(struct sockaddr_in *)remoteaddr;
+    }
+    strcpy(kstate->instance, instance);
+    strcpy(kstate->realm, realm);
+
+    memset(&cr, 0, sizeof(cr));
+    *state = (void *)kstate;
+    return 0;
+}
+
+/*
+ * Perform client-side authentication protocol exchange
+ * Returns ACTE_DONE if authentication can be complete after
+ * sending our client reply.
+ */
+static int krb_client_auth(state, inputlen, input, outputlen, output)
+void *state;			/* State of exchange */
+int inputlen;			/* Length of server response */
+char *input;			/* Server response data */
+int *outputlen;			/* Set to length of client reply */
+char **output;			/* Set to point to client reply data */
+{
+    static KTEXT_ST authent;
+    struct krb_state *kstate = (struct krb_state *)state;
+    char tmp[4];
+    int code;
+    int maxbufsize;
+
+    switch (kstate->authstepno++) {
+    case 0:
+	/* Server gave us challenge, respond with ticket+authenticator */
+	if (inputlen < 4) {
+	    kstate->authstepno = -1;
+	    return ACTE_FAIL;
+	}
+	memcpy(tmp, input, 4);
+	kstate->challenge = ntohl(*(int *)tmp);
+
+	code = krb_mk_req(&authent, kstate->service, kstate->instance,
+			  kstate->realm, kstate->challenge);
+	if (code) {
+	    kstate->authstepno = -1;
+	    return ACTE_FAIL;
+	}
+	*outputlen = authent.length;
+	*output = authent.dat;
+	return 0;
+
+    case 1:
+	/*
+	 * Server gave us mutual auth reply+available protection mechanisms.
+	 * Respond with challenge, desired protection mechanism, userid
+	 */
+	if (inputlen < 8) {
+	    kstate->authstepno = -1;
+	    return ACTE_FAIL;
+	}
+	des_ecb_encrypt(input, input, kstate->schedule, 0);
+	memcpy(tmp, input, 4);
+	if (ntohl(*(int *)tmp) != kstate->challenge + 1) {
+	    /* Server failed to mutually authenticte */
+	    kstate->authstepno = -1;
+	    return ACTE_FAIL;
+	}	    
+	memcpy(tmp, input+4, 4);
+	maxbufsize = ntohl(*(int *)tmp) & 0xfffff;
+	kstate->protallowed &= input[4];
+	if (maxbufsize <= PROTECTION_OVERHEAD) {
+	    /* Protection buffer too small */
+	    kstate->protallowed &= ACTE_PROT_NONE;
+	}
+#ifndef NOPRIVACY
+	if (kstate->protallowed & ACTE_PROT_PRIVACY) {
+	    kstate->protallowed = ACTE_PROT_PRIVACY;
+	}
+	else
+#endif
+	if (kstate->protallowed & ACTE_PROT_INTEGRITY) {
+	    kstate->protallowed = ACTE_PROT_INTEGRITY;
+	}
+	else if (kstate->protallowed & ACTE_PROT_NONE) {
+	    kstate->protallowed = ACTE_PROT_NONE;
+	}
+	else {
+	    /* No mutually agreeable protection mechanism */
+	    kstate->authstepno = -1;
+	    return ACTE_FAIL;
+	}
+
+	*(int *)authent.dat = htonl(kstate->challenge);
+	*(int *)(authent.dat+4) = htonl(kstate->maxbufsize);
+	authent.dat[4] = kstate->protallowed;
+	strcpy(&authent.dat[8], kstate->user);
+	authent.length = 8+strlen(kstate->user);
+	do {
+	    authent.dat[authent.length++] = '\0';
+	} while (authent.length & 7);
+	des_pcbc_encrypt(authent.dat, authent.dat, authent.length,
+			 kstate->schedule, kstate->session, 1);
+	*output = authent.dat;
+	*outputlen = authent.length;
+	if (maxbufsize < kstate->maxbufsize) kstate->maxbufsize = maxbufsize;
+	return ACTE_DONE;
+
+    default:
+	kstate->authstepno = -1;
+	return ACTE_FAIL;
+    }
+}
+
+/*
+ * Acquire daemon client credentials for 'service'.  Places lifetime
+ * of credentials in seconds in the buffer pointed to by 'lifetime'
+ * Returns error message on failure, NULL on success.
+ */
+static const char *
+krb_new_cred(service, lifetime)
+const char *service;
+time_t *lifetime;
+{
+    static int inited = 0;
+    char hostname[MAXHOSTNAMELEN+1];
+    char instance[MAXHOSTNAMELEN+1];
+    char realm[REALM_SZ];
+    char tktstring[256];
+    int r;
+    CREDENTIALS cr;
+
+    if (!inited++) {
+	sprintf(tktstring, "/tmp/tkt_pid_%d", getpid());
+	krb_set_tkt_string(tktstring);
+    }
+
+    if (krb_get_lrealm(realm,1) != KSUCCESS) {
+	return "cannot get local Kerberos realm";
+    }
+
+    gethostname(hostname, sizeof(hostname));
+    strcpy(instance, krb_get_phost(hostname));
+
+    r = krb_get_svc_in_tkt(service, instance, realm, "krbtgt", realm, 127,
+		       srvtab);
+
+    if (!r) {
+	r = krb_get_cred("krbtgt", realm, realm, &cr);
+	if (!r) *lifetime = cr.lifetime*5*60;
+	memset((char *)&cr, 0, sizeof(cr));
+    }
+
+    if (r) return krb_err_txt[r];
+    return 0;
+}
+    
+static void
+krb_free_cred()
+{
+    dest_tkt();
+}
+
+/* Exported definition of client-side authentication mechanism */
+struct acte_client krb_acte_client = {
+    "KERBEROS_V4",
+    krb_client_start,
+    krb_client_auth,
+    krb_query_state,
+    krb_free_state,
+    krb_new_cred,
+    krb_free_cred,
+};
+
+/*
+ * Start the server side of an authentication exchange
+ */
+static int
+krb_server_start(service, authproc, protallowed, maxbufsize,
+		 localaddr, remoteaddr, outputlen, output, state, reply)
+const char *service;
+acte_authproc_t *authproc;	/* (optional) function to decide
+				 * authoriztion to log in as given user
+				 */
+int protallowed;		/* Protection mechanisms allowed */
+int maxbufsize;			/* Maximum ciphertext input buffer size */
+struct sockaddr *localaddr;	/* Network address of local side */
+struct sockaddr *remoteaddr;	/* Network address of remote side */
+int *outputlen;			/* Set to length of initial reply */
+char **output;			/* Set to point to initial reply data */
+void **state;			/* On success, filled in with state ptr */
+const char **reply;		/* On failure, filled in with ptr to reason */
+{
+    static char outputbuf[4];
+    struct krb_state *kstate;
+
+    protallowed &= ACTE_PROT_NONE|ACTE_PROT_INTEGRITY
+#ifndef NOPRIVACY
+	|ACTE_PROT_PRIVACY
+#endif
+	;
+    if (!localaddr || !remoteaddr) {
+	protallowed &= ACTE_PROT_NONE;
+    }
+    if (!protallowed) {
+	*reply = "No suitable protection mechanism";
+	return ACTE_FAIL;
+    }
+    if (maxbufsize > 0xffffff) maxbufsize = 0xffffff;
+
+    kstate = (struct krb_state *)malloc(sizeof(struct krb_state));
+    if (!kstate) {
+	*reply = "Out of memory";
+	return ACTE_FAIL;
+    }
+    memset((char *)kstate, 0, sizeof(*kstate));
+    strcpy(kstate->service, service);
+    kstate->authstepno = 0;
+    kstate->challenge = time(0) ^ getpid();
+    kstate->protallowed = protallowed;
+    kstate->maxbufsize = maxbufsize;
+    if (localaddr && remoteaddr) {
+	kstate->localaddr = *(struct sockaddr_in *)localaddr;
+	kstate->remoteaddr = *(struct sockaddr_in *)remoteaddr;
+    }
+    kstate->authproc = authproc;
+
+    *(int *)outputbuf = htonl(kstate->challenge);
+    *output = outputbuf;
+    *outputlen = 4;
+    *state = (void *)kstate;
+    
+    return 0;
+}
+
+/*
+ * Perform server-side authentication protocol exchange.
+ * Returns 0 to continue exchange, ACTE_FAIL on failure, and ACTE_DONE
+ * if user is now successfully authenticated
+ */
+static int krb_server_auth(state, inputlen, input, outputlen, output, reply)
+void *state;			/* State of exchange */
+int inputlen;			/* Length of client response */
+char *input;			/* Client response data */
+int *outputlen;			/* Set to length of server reply */
+char **output;			/* Set to point to server reply data */
+const char ** reply;		/* On failure, filled in with ptr to reason */
+{
+    struct krb_state *kstate = (struct krb_state *)state;
+    static char outputbuf[8];
+    KTEXT_ST authent;
+    int code;
+    char tmp[4];
+    char instance[INST_SZ];
+    char realm[REALM_SZ];
+    int protallowed;
+    int maxbufsize;
+    char clientname[MAX_K_NAME_SZ+1];
+
+    switch (kstate->authstepno++) {
+    case 0:
+	/*
+	 * Client gave us ticket+authenticator
+	 * reply with mutual auth + supported protection mechanisms
+	 */
+	if (inputlen > MAX_KTXT_LEN) {
+	    kstate->authstepno = -1;
+	    *reply = "Kerberos authenticator too long";
+	    return ACTE_FAIL;
+	}
+	authent.length = inputlen;
+	memcpy(authent.dat, input, inputlen);
+	authent.mbz = 0;
+	strcpy(instance, "*");
+	code = krb_rd_req(&authent, kstate->service, instance, 0L,
+			  &kstate->kdata, srvtab);
+	if (code) {
+	    kstate->authstepno = -1;
+	    *reply = krb_err_txt[code];
+	    return ACTE_FAIL;
+	}
+	if (kstate->kdata.checksum != kstate->challenge) {
+	    kstate->authstepno = -1;
+	    *reply = "Incorrect checksum in Kerberos authenticator";
+	    return ACTE_FAIL;
+	}
+	memcpy(kstate->session, kstate->kdata.session, sizeof(des_cblock));
+	des_key_sched(kstate->session, kstate->schedule);
+	
+	*(int *)outputbuf = htonl(kstate->challenge+1);
+	*(int *)(outputbuf+4) = htonl(kstate->maxbufsize);
+	outputbuf[4] = kstate->protallowed;
+	des_ecb_encrypt(outputbuf, outputbuf, kstate->schedule, 1);
+	*output = outputbuf;
+	*outputlen = 8;
+
+	return 0;
+
+    case 1:
+	/* Client gave us selected protection mechanism + userid, we're done */
+	if (inputlen < 16 || inputlen & 7) {
+	    kstate->authstepno = -1;
+	    *reply = "Kerberos authenticator has incorrect length";
+	    return ACTE_FAIL;
+	}
+	des_pcbc_encrypt(input, input, inputlen,
+			 kstate->schedule, kstate->session, 0);
+	memcpy(tmp, input, 4);
+	if (ntohl(*(int *)tmp) != kstate->challenge) {
+	    kstate->authstepno = -1;
+	    *reply = "Incorrect checksum in Kerberos authenticator";
+	    return ACTE_FAIL;
+	}
+	memcpy(tmp, input+4, 4);
+	maxbufsize = ntohl(*(int *)tmp) & 0xfffff;
+	if (maxbufsize < kstate->maxbufsize) kstate->maxbufsize = maxbufsize;
+	protallowed = input[4];
+	if (!(protallowed & kstate->protallowed)) {
+	    kstate->authstepno = -1;
+	    *reply = "No suitable protection mechanism selected";
+	    return ACTE_FAIL;
+	}
+	if (
+#ifndef NOPRIVACY
+	    protallowed != ACTE_PROT_PRIVACY &&
+#endif
+	    protallowed != ACTE_PROT_INTEGRITY &&
+	    protallowed != ACTE_PROT_NONE) {
+	    kstate->authstepno = -1;
+	    *reply = "Multiple protection mechanisms selected";
+	    return ACTE_FAIL;
+	}
+	if (protallowed != ACTE_PROT_NONE &&
+	    kstate->maxbufsize <= PROTECTION_OVERHEAD) {
+	    /* Protection buffer too small */
+	    kstate->authstepno = -1;
+	    *reply = "Protection buffer size too small";
+	    return ACTE_FAIL;
+	}
+	kstate->protallowed = protallowed;
+
+	if (input[inputlen-1] != '\0') {
+	    *reply = "User name not nul-terminated";
+	    return ACTE_FAIL;
+	}
+	strcpy(kstate->user, input+8);
+
+	/* Check kerberos identity can log in as user */
+	if (krb_get_lrealm(realm,1)) {
+	    *reply = "Can't find local Kerberos realm";
+	    return ACTE_FAIL;
+	}
+	if (kstate->authproc) {
+	    strcpy(clientname, kstate->kdata.pname);
+	    if (kstate->kdata.pinst[0]) {
+		strcat(clientname, ".");
+		strcat(clientname, kstate->kdata.pinst);
+	    }
+	    if (kstate->kdata.prealm[0]) {
+		strcat(clientname, "@");
+		strcat(clientname, kstate->kdata.prealm);
+	    }
+	    if (kstate->authproc(kstate->user, clientname, reply) != 0) {
+		return ACTE_FAIL;
+	    }
+	}
+	else {
+	    if (strcmp(kstate->kdata.pname, kstate->user) != 0 ||
+		kstate->kdata.pinst[0] ||
+		strcmp(kstate->kdata.prealm, realm) != 0) {
+		*reply = "Kerberos ID does not match user name";
+		return ACTE_FAIL;
+	    }
+	}
+
+	return ACTE_DONE;
+
+    default:
+	*reply = "Internal error: invalid state in krb_server_auth";
+	return ACTE_FAIL;
+    }
+}
+
+/* Exported definition of server-side authentication mechanism */
+struct acte_server krb_acte_server = {
+    "KERBEROS_V4",
+    krb_server_start,
+    krb_server_auth,
+    krb_query_state,
+    krb_free_state,
+    krb_get_cacheid,
+};
+
+/*
+ * Apply integrity protection to the 'inputlen' bytes of data at 'input',
+ * using the state in 'state', placing the output data and length in the
+ * buffers pointed to by 'output' and 'outputlen' respectively.
+ */
+static const char *
+krb_en_integrity(state, input, inputlen, output, outputlen)
+void *state;
+char *input;
+int inputlen;
+char *output;
+int *outputlen;
+{
+    struct krb_state *kstate = (struct krb_state *)state;
+
+    *outputlen = krb_mk_safe(input, output, inputlen, kstate->session,
+			     &kstate->localaddr, &kstate->remoteaddr);
+    return 0;
+}
+
+/*
+ * Decode integrity protection on the 'inputlen' bytes of data at
+ * 'input', using the state in 'state', placing a pointer to the
+ * output data and length in the buffers pointed to by 'output' and
+ * 'outputlen' respectively.
+ */
+static const char *
+krb_de_integrity(state, input, inputlen, output, outputlen)
+void *state;
+char *input;
+int inputlen;
+char **output;
+int *outputlen;
+{
+    struct krb_state *kstate = (struct krb_state *)state;
+    int code;
+    MSG_DAT m_data;
+
+    code = krb_rd_safe(input, inputlen, kstate->session,
+		       &kstate->remoteaddr, &kstate->localaddr, &m_data);
+    if (code) return krb_err_txt[code];
+    if (m_data.time_sec < kstate->prot_time_sec ||
+	(m_data.time_sec == kstate->prot_time_sec &&
+	 m_data.time_5ms < kstate->prot_time_5ms)) {
+	return krb_err_txt[RD_AP_TIME];
+    }
+    kstate->prot_time_sec = m_data.time_sec;
+    kstate->prot_time_5ms = m_data.time_5ms;
+
+    *output = m_data.app_data;
+    *outputlen = m_data.app_length;
+    return 0;
+}
+
+#ifndef NOPRIVACY
+/*
+ * Apply privacy protection to the 'inputlen' bytes of data at 'input',
+ * using the state in 'state', placing the output data and length in the
+ * buffers pointed to by 'output' and 'outputlen' respectively.
+ */
+static const char *
+krb_en_privacy(state, input, inputlen, output, outputlen)
+void *state;
+char *input;
+int inputlen;
+char *output;
+int *outputlen;
+{
+    struct krb_state *kstate = (struct krb_state *)state;
+
+    *outputlen = krb_mk_priv(input, output, inputlen, kstate->schedule,
+			     kstate->session, &kstate->localaddr,
+			     &kstate->remoteaddr);
+    return 0;
+}
+
+/*
+ * Decode privacy protection on the 'inputlen' bytes of data at
+ * 'input', using the state in 'state', placing a pointer to the
+ * output data and length in the buffers pointed to by 'output' and
+ * 'outputlen' respectively.
+ */
+static const char *
+krb_de_privacy(state, input, inputlen, output, outputlen)
+void *state;
+char *input;
+int inputlen;
+char **output;
+int *outputlen;
+{
+    struct krb_state *kstate = (struct krb_state *)state;
+    int code;
+    MSG_DAT m_data;
+
+    code = krb_rd_priv(input, inputlen, kstate->schedule, kstate->session,
+		       &kstate->remoteaddr, &kstate->localaddr, &m_data);
+    if (code) return krb_err_txt[code];
+    if (m_data.time_sec < kstate->prot_time_sec ||
+	(m_data.time_sec == kstate->prot_time_sec &&
+	 m_data.time_5ms < kstate->prot_time_5ms)) {
+	return krb_err_txt[RD_AP_TIME];
+    }
+    kstate->prot_time_sec = m_data.time_sec;
+    kstate->prot_time_5ms = m_data.time_5ms;
+
+    *output = m_data.app_data;
+    *outputlen = m_data.app_length;
+    return 0;
+}
+#endif /* !NOPRIVACY */
+
+/*
+ * Kerberos set srvtab filename
+ * Accepts: name of srvtab file to use in reading authenticators
+ */
+int kerberos_set_srvtab(fname)
+char *fname;
+{
+    srvtab = fname;
+    return 0;
+}
+
+/*
+ * Kerberos get srvtab filename
+ * Returns: name of srvtab file to use in reading authenticators
+ */
+char *kerberos_get_srvtab()
+{
+    return srvtab;
+}
+
+static use_key(user, instance, realm, key, returned_key)
+char *user;
+char *instance;
+char *realm;
+des_cblock key;
+des_cblock returned_key;
+{
+    memcpy (returned_key, key, sizeof(des_cblock));
+    return 0;
+}
+
+/*
+ * Securely verify the plaintext password 'passwd' for user 'user'
+ * against the Kerberos database.  "service" is the name of a service
+ * we can verify the returned ticket against.  Returns 1 for success,
+ * 0 for failure.  On failure, 'reply' is filled in with a pointer to
+ * the reason.
+ */
+int kerberos_verify_password(user, passwd, service, reply)
+char *user;
+char *passwd;
+char *service;
+const char **reply;
+{
+    int result;
+    des_cblock key;
+    char tfname[40];
+    char realm[REALM_SZ];
+    char cell[REALM_SZ];
+    char hostname[MAXHOSTNAMELEN+1];
+    char phost[MAXHOSTNAMELEN+1];
+    KTEXT_ST authent;
+    char instance[INST_SZ];
+    AUTH_DAT kdata;
+
+    if (krb_get_lrealm(realm,1)) return 0;
+
+    sprintf(tfname, "/tmp/tkt_imapd_%d", getpid());
+    krb_set_tkt_string(tfname);
+
+    /* First try Kerberos string-to-key */
+    des_string_to_key(passwd, key);
+    
+    result = krb_get_in_tkt(user, "", realm,
+			    "krbtgt", realm, 1, use_key, NULL, key);
+
+    if (result == INTK_BADPW) {
+	/* Now try andrew string-to-key */
+	strcpy(cell, realm);
+	lcase(cell);
+	afs_string_to_key(passwd, cell, &key);
+    
+	result = krb_get_in_tkt(user, "", realm,
+				"krbtgt", realm, 1, use_key, NULL, key);
+    }
+
+    memset(key, 0, sizeof(key));
+
+    if (result != 0) {
+	dest_tkt();
+	*reply = krb_err_txt[result];
+	return 0;
+    }
+
+    /* Check validity of returned ticket */
+    gethostname(hostname, sizeof(hostname));
+    strcpy(phost, krb_get_phost(hostname));
+    result = krb_mk_req(&authent, service, phost, realm, 0);
+    if (result != 0) {
+	memset(&authent, 0, sizeof(authent));
+	dest_tkt();
+	*reply = krb_err_txt[result];
+	return 0;
+    }
+    strcpy(instance, "*");
+    result = krb_rd_req(&authent, service, instance, 0L, &kdata, srvtab);
+    memset(&authent, 0, sizeof(authent));
+    memset(kdata.session, 0, sizeof(kdata.session));
+    if (result != 0 || strcmp(kdata.pname, user) != 0 || kdata.pinst[0] ||
+	strcmp(kdata.prealm, realm) != 0) {
+	if (result != 0) {
+	    *reply = krb_err_txt[result];
+	}
+	else {
+	    *reply = "Kerberos ID does not match user name";
+	}
+	result = 0;
+    }
+    else result = 1;
+
+    dest_tkt();
+    return result;
+}
diff -urN alpine-1.00+hesiod/imap/src/kerberos/auth_krb.c alpine-1.00+krb4/imap/src/kerberos/auth_krb.c
--- alpine-1.00+hesiod/imap/src/kerberos/auth_krb.c	1969-12-31 19:00:00.000000000 -0500
+++ alpine-1.00+krb4/imap/src/kerberos/auth_krb.c	2007-12-24 14:33:48.000000000 -0500
@@ -0,0 +1,103 @@
+/*
+ * Program:	Kerberos authenticator
+ *
+ * Author:	Mark Crispin
+ *		Networks and Distributed Computing
+ *		Computing & Communications
+ *		University of Washington
+ *		Administration Building, AG-44
+ *		Seattle, WA  98195
+ *		Internet: MRC@CAC.Washington.EDU
+ *
+ * Date:	1 May 1996
+ * Last Edited:	1 December 1998
+ *
+ * Copyright 1998 by the University of Washington.
+ *
+ *  Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appears in all copies and that both the
+ * above copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the University of Washington not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  This software is made available
+ * "as is", and
+ * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+ * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
+ * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* Thanks to Daniel A. Root at CMU who contributed the original version */
+
+#include "acte_krb.c"
+
+long auth_krb_client P((authchallenge_t challenger,authrespond_t responder,
+			char *service,NETMBX *mb,void *stream,unsigned long *trial,
+			char *user));
+char *auth_krb_server P((authresponse_t responder,int argc,char *argv[]));
+
+AUTHENTICATOR auth_krb = {
+  AU_SECURE | AU_AUTHUSER,	/* secure authenticator */
+  "KERBEROS_V4",		/* authenticator name */
+  NIL,				/* always valid */
+  auth_krb_client,		/* client method */
+  NIL,				/* server method */
+  NIL				/* next authenticator */
+};
+
+/* Client authenticator
+ * Accepts: challenger function
+ *	    responder function
+ *	    parsed network mailbox structure
+ *	    stream argument for functions
+ *	    pointer to trial number
+ *	    returned user name
+ * Returns: T if success, NIL otherwise
+ */
+
+long auth_krb_client (challenger,responder,service,mb,stream,trial,user)
+     authchallenge_t challenger;
+     authrespond_t responder;
+     char *service;
+     NETMBX *mb;
+     void *stream;
+     unsigned long *trial;
+     char *user;
+{
+  struct acte_client *mech;
+  void *challenge;
+  char *response;
+  unsigned long clen, rlen;
+  struct krb_state *state;
+  int rc;
+  mech = &krb_acte_client;
+  *trial = 0;			/* don't retry if failure */
+				/* fetch proper service tickets */
+  if (mech->start (service,mb->host,0,ACTE_PROT_NONE,0,0,0,&state,user)) {
+      /* Grab Initial Challenge (note, if this fails, we don't care) */
+      (*challenger)(stream,&clen);
+      /* Cancel authentication */
+      (*responder) (stream,NIL,0);
+      return NIL;
+  }
+				/* get challenge/response */
+  do {				/* until ACTE_DONE or something fails */
+    if (!(challenge = (*challenger) (stream,&clen))) return NIL;
+    rc = mech->auth (state,clen,challenge,&rlen,&response);
+    if (rc == ACTE_FAIL) {
+      /* Cancel authentication */
+      (*responder) (stream,NIL,0);
+      return NIL;
+    }
+    fs_give ((void **) &challenge);
+    if (!((*responder) (stream,response,rlen))) return NIL;
+  } while (rc != ACTE_DONE);
+  mech->free_state (state);	/* clean up */
+  return T;
+}
diff -urN alpine-1.00+hesiod/imap/src/kerberos/ckp_krb.c alpine-1.00+krb4/imap/src/kerberos/ckp_krb.c
--- alpine-1.00+hesiod/imap/src/kerberos/ckp_krb.c	1969-12-31 19:00:00.000000000 -0500
+++ alpine-1.00+krb4/imap/src/kerberos/ckp_krb.c	2007-12-24 14:33:48.000000000 -0500
@@ -0,0 +1,53 @@
+/*
+ * Program:	Kerberos check password
+ *
+ * Author:	Mark Crispin
+ *		Networks and Distributed Computing
+ *		Computing & Communications
+ *		University of Washington
+ *		Administration Building, AG-44
+ *		Seattle, WA  98195
+ *		Internet: MRC@CAC.Washington.EDU
+ *
+ * Date:	1 August 1988
+ * Last Edited:	1 December 1998
+ *
+ * Copyright 1998 by the University of Washington
+ *
+ *  Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appears in all copies and that both the
+ * above copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the University of Washington not be
+ * used in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  This software is made available
+ * "as is", and
+ * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+ * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
+ * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
+ * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/* Check password
+ * Accepts: login passwd struct
+ *	    password string
+ *	    argument count
+ *	    argument vector
+ * Returns: passwd struct if password validated, NIL otherwise
+ */
+
+struct passwd *checkpw (pw,pass,argc,argv[])
+     struct passwd *pw;
+     char *pass;
+     int argc;
+     char *argv[];
+{
+  char *reply;
+  return kerberos_verify_password (pw->pw_name,pass,"imap",&reply) ? pw : NIL;
+}
+
diff -urN alpine-1.00+hesiod/imap/src/kerberos/Makefile.krb alpine-1.00+krb4/imap/src/kerberos/Makefile.krb
--- alpine-1.00+hesiod/imap/src/kerberos/Makefile.krb	1969-12-31 19:00:00.000000000 -0500
+++ alpine-1.00+krb4/imap/src/kerberos/Makefile.krb	2007-12-24 14:33:48.000000000 -0500
@@ -0,0 +1,41 @@
+# Program:	Kerberos IV makefile
+#
+# Author:	Mark Crispin
+#		Networks and Distributed Computing
+#		Computing & Communications
+#		University of Washington
+#		Administration Building, AG-44
+#		Seattle, WA  98195
+#		Internet: MRC@CAC.Washington.EDU
+#
+# Date:		11 May 1989
+# Last Edited:	13 October 1998
+#
+# Copyright 1998 by the University of Washington
+#
+#  Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose and without fee is hereby granted, provided
+# that the above copyright notice appears in all copies and that both the
+# above copyright notice and this permission notice appear in supporting
+# documentation, and that the name of the University of Washington not be
+# used in advertising or publicity pertaining to distribution of the software
+# without specific, written prior permission.  This software is made
+# available "as is", and
+# THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
+# WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
+# NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
+# INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
+# (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+
+# Extended flags needed for additional authenticators.  You may need to modify.
+
+KRBCFLAGS= -DHAVE_KRB_GET_PHOST -DHAVE_KRB_REALMOFHOST
+KRBLDFLAGS= -lkrb4 -ldes425 -lkrb5 -lk5crypto -lcom_err
+
+krb:	# Kerberos IV flags
+	echo $(KRBCFLAGS) >> OSCFLAGS
+	echo $(KRBLDFLAGS) >> LDFLAGS
diff -urN alpine-1.00+hesiod/imap/src/kerberos/README alpine-1.00+krb4/imap/src/kerberos/README
--- alpine-1.00+hesiod/imap/src/kerberos/README	1969-12-31 19:00:00.000000000 -0500
+++ alpine-1.00+krb4/imap/src/kerberos/README	2007-12-24 14:33:48.000000000 -0500
@@ -0,0 +1,26 @@
+		       Kerberos 4 IMAP Patchkit
+			   1 December 1998
+			     Mark Crispin
+
+     The Kerberos 4 IMAP patchkit consists of a set of modules and
+patches to the IMAP toolkit to enable Kerberos 4 client-only support
+in c-client.  There is server support.
+
+     This patchkit is completely unsupported.  Use it at your own
+risk.
+
+     To build the IMAP tookit with the Kerberos 4 IMAP patchkit, move
+the entire contents of the kerberos/ directory into
+imap-4.???/src/kerberos, then do a make command with krb listed as one
+of the EXTRAAUTHENTICATORS.
+
+     For example, assuming that you just obtained imap-4.5.tar.Z and
+this kerberos4-patches.tar.Z distribution and desire to build on a
+Digital UNIX 4.0 system.  You would follow a procedure somewhat like
+this:
+	% zcat imap-4.5.tar.Z | tar xf -
+	% zcat kerberos4-patches.tar.Z | tar xf -
+	% mv kerberos imap-4.5/src
+	% cd imap-4.5
+	% make os4 EXTRAAUTHENTICATORS=krb
+
diff -urN alpine-1.00+hesiod/imap/src/osdep/unix/tcp_unix.c alpine-1.00+krb4/imap/src/osdep/unix/tcp_unix.c
--- alpine-1.00+hesiod/imap/src/osdep/unix/tcp_unix.c	2007-08-16 15:43:35.000000000 -0400
+++ alpine-1.00+krb4/imap/src/osdep/unix/tcp_unix.c	2007-12-24 14:33:48.000000000 -0500
@@ -293,6 +293,20 @@
 	now = time (0);		/* fake timeout if interrupt & time expired */
 	if ((i < 0) && (errno == EINTR) && ti && (ti <= now)) i = 0;
       } while ((i < 0) && (errno == EINTR));
+#ifdef KERBEROS
+      if (port == 1109 && i > 0) {
+	/* For kpop, we have to send kerberos authentication before we
+	 * can read anything.  So we have to do it here instead of in
+	 * the pop3 code. */
+	KTEXT_ST ticket;
+
+	if (krb_sendauth (0,sock,&ticket,"pop",hst,krb_realmofhost (hst),
+			  0,NULL,NULL,NULL,NULL,NULL,"KPOPV0.1") != KSUCCESS) {
+	  close (sock);
+	  return -1;		/* failure */
+	}
+      }
+#endif  
       if (i > 0) {		/* success, make sure really connected */
 				/* restore blocking status */
 	fcntl (sock,F_SETFL,flgs);
