From: jik@Aktis.COM (Jonathan I. Kamens)
Newsgroups: comp.mail.mh,comp.protocols.kerberos
Subject: mh 6.8 changes: Kerberos V5 & NeXT support
Date: 5 Jan 93 21:24:16 GMT
Followup-To: comp.mail.mh
Organization: Aktis, Inc.
NNTP-Posting-Host: pit-manager.mit.edu

The patches below do four things:

1) Add support for Kerberos V5, rather than Kerberos V4, by adding the K5POP
option, which should be used instead of (rather than in addition to) the KPOP
option.

2) Clean up the Kerberos V4 configuration stuff (some of which is used for
Kerberos V5 as well).  The two biggest elements in the cleanup were making some
global variables that didn't need to be global local in some files, and fixing
the linking order of libraries when linking against Kerberos libraries.

3) Add support for compiling under NeXTSTEP 3 with gcc2.  This involved only a
minor change to h/strings.h.

4) Add a "dldflag" configuration parameter, defaulting to "dldflag: -pic". 
This is necessary, for example, when building shared libraries using gcc2 under
SunOS; in that case, it would be "dldflag: -fPIC".

I haven't updated the documentation, but the changes are straightforward.

NOTE: We're using the popper that was shipped with the Kerberos V5 beta release
(after fixing it to make it actually work; eventually, we'll be posting those
patches as well), not the one that's in the MH distribution.  I've patched the
MH popd so that it looks like the one in the Kerberos V5 distribution and so
that it compiles, but I haven't tested it.  I have, however, tested the client
Kerberos patches (inc, msgchk), and they appear to work just fine.

*** 1.1	1992/12/31 20:25:48
--- conf/config/mts.c	1992/12/31 21:25:44
***************
*** 475,481 ****
  char   *getusr () {
      register char  *cp,
                     *np;
! #ifdef KPOP
      int uid;
  #endif /* KPOP */
      register struct passwd *pw;
--- 475,481 ----
  char   *getusr () {
      register char  *cp,
                     *np;
! #if defined(KPOP) || defined(K5POP)
      int uid;
  #endif /* KPOP */
      register struct passwd *pw;
***************
*** 483,493 ****
      if (username[0])
  	return username;
  
! #ifndef KPOP
      if ((pw = getpwuid (getuid ())) == NULL
  	    || pw -> pw_name == NULL
  	    || *pw -> pw_name == NULL) {
! #else /* KPOP */
      uid = getuid ();
      if (uid == geteuid () && (cp = getenv ("USER")) != NULL
  	&& (pw = getpwnam (cp)) != NULL)
--- 483,493 ----
      if (username[0])
  	return username;
  
! #if !defined(KPOP) && !defined(K5POP)
      if ((pw = getpwuid (getuid ())) == NULL
  	    || pw -> pw_name == NULL
  	    || *pw -> pw_name == NULL) {
! #else /* KPOP || K5POP */
      uid = getuid ();
      if (uid == geteuid () && (cp = getenv ("USER")) != NULL
  	&& (pw = getpwnam (cp)) != NULL)
***************
*** 495,501 ****
      else if ((pw = getpwuid (uid)) == NULL
  	     || pw -> pw_name == NULL
  	     || *pw -> pw_name == '\0') {
! #endif /* KPOP */
  	(void) strcpy (username, "unknown");
  	(void) sprintf (fullname, "The Unknown User-ID (%d)", getuid ());
  	return username;
--- 495,501 ----
      else if ((pw = getpwuid (uid)) == NULL
  	     || pw -> pw_name == NULL
  	     || *pw -> pw_name == '\0') {
! #endif /* KPOP || K5POP */
  	(void) strcpy (username, "unknown");
  	(void) sprintf (fullname, "The Unknown User-ID (%d)", getuid ());
  	return username;
*** 1.1	1992/12/31 19:39:55
--- conf/makefiles/support/pop	1992/12/31 21:21:57
***************
*** 12,17 ****
--- 12,23 ----
  OPTIONS	=	@(MHOPTIONS) @(POPUUMBOX) -I..
  LDOPTIONS=	@(LDOPTIONS)
  LDOPTLIB=	@(LDOPTLIB)
+ @BEGIN: KPOP
+ KRBLIB=		-lkrb -ldes
+ @END: KPOP
+ @BEGIN: K5POP
+ KRBLIB=		-lkrb5 -lcrypto -lisode -lcom_err
+ @END: K5POP
  @BEGIN: MPOP
  LDCURSES=	@(LDCURSES)
  @END: MPOP
***************
*** 51,57 ****
  @BEGIN: STDLIB
  LIBES2	=	../../config/config.o ../../sbr/libmh.a $(LIBES1)
  LDLIBS1	=	$(LIBES1) $(LDOPTLIB)
! LDLIBS2	=	$(LIBES2) ../../config/version.o $(LDOPTLIB)
  @END: STDLIB
  @BEGIN: SUN4SHLIB
  SLIBVER	=	.@(SLIBVER)
--- 57,63 ----
  @BEGIN: STDLIB
  LIBES2	=	../../config/config.o ../../sbr/libmh.a $(LIBES1)
  LDLIBS1	=	$(LIBES1) $(LDOPTLIB)
! LDLIBS2	=	$(LIBES2) ../../config/version.o $(KRBLIB) $(LDOPTLIB)
  @END: STDLIB
  @BEGIN: SUN4SHLIB
  SLIBVER	=	.@(SLIBVER)
***************
*** 60,66 ****
  LIBES2	=	../../config/config.o ../../sbr/libmh.so $(LIBES1)
  LDLIBS1	=	$(LIBES1) $(LDOPTLIB)
  LDLIBS2	=	../../config/config.o ../../config/version.o \
! 		-Bdynamic @(SLDFLAG) -lmh$(SLIBVER) $(LIBES1) $(LDOPTLIB)
  @END: SHAREDLIB
  
  LINT	=	lint
--- 66,73 ----
  LIBES2	=	../../config/config.o ../../sbr/libmh.so $(LIBES1)
  LDLIBS1	=	$(LIBES1) $(LDOPTLIB)
  LDLIBS2	=	../../config/config.o ../../config/version.o \
! 		@(DLDFLAG) @(SLDFLAG) -lmh$(SLIBVER) $(LIBES1) \
! 		$(KRBLIB) $(LDOPTLIB)
  @END: SHAREDLIB
  
  LINT	=	lint
*** 1.1	1992/12/31 19:51:18
--- conf/makefiles/support/bboards	1992/12/31 19:52:04
***************
*** 55,61 ****
  LDLIBS1	=	$(LIBES1) $(LDOPTLIB)
  LDLIBS2	=	$(LIBES2) $(LDOPTLIB)
  LDLIBS2	=	../../config/config.o ../../config/version.o \
! 		-Bdynamic @(SLDFLAG) -lmh$(SLIBVER) $(LIBES1) $(LDOPTLIB)
  @END: SHAREDLIB
  
  LINT	=	lint
--- 55,61 ----
  LDLIBS1	=	$(LIBES1) $(LDOPTLIB)
  LDLIBS2	=	$(LIBES2) $(LDOPTLIB)
  LDLIBS2	=	../../config/config.o ../../config/version.o \
! 		@(DLDFLAG) @(SLDFLAG) -lmh$(SLIBVER) $(LIBES1) $(LDOPTLIB)
  @END: SHAREDLIB
  
  LINT	=	lint
*** 1.1	1992/12/31 19:28:03
--- conf/makefiles/uip	1992/12/31 21:21:16
***************
*** 84,89 ****
--- 84,92 ----
  @BEGIN: KPOP
  KRBLIB  =       -lkrb -ldes
  @END: KPOP
+ @BEGIN: K5POP
+ KRBLIB=		-lkrb5 -lcrypto -lisode -lcom_err
+ @END: K5POP
  @BEGIN: BPOP
  PSHLIB	=	popsbr.o
  PSHLLIBS=	popsbr.c 
***************
*** 132,138 ****
  @BEGIN: STDLIB
  LIBES	=	../config/config.o ../sbr/libmh.a ../mts/libmts.a \
  		../zotnet/libzot.a
! LDLIBS	=	$(LIBES) ../config/version.o $(LDOPTLIB)
  @END: STDLIB
  @BEGIN: SUN4SHLIB
  SLIBVER	=	.@(SLIBVER)
--- 135,141 ----
  @BEGIN: STDLIB
  LIBES	=	../config/config.o ../sbr/libmh.a ../mts/libmts.a \
  		../zotnet/libzot.a
! LDLIBS	=	$(LIBES) ../config/version.o $(KRBLIB) $(HESLIB) $(LDOPTLIB)
  @END: STDLIB
  @BEGIN: SUN4SHLIB
  SLIBVER	=	.@(SLIBVER)
***************
*** 140,148 ****
  @BEGIN: SHAREDLIB
  LIBES	=	../config/config.o ../sbr/libmh.so ../mts/libmts.a \
  		../zotnet/libzot.a
! LDLIBES	=	../config/config.o -Bdynamic @(SLDFLAG) -lmh$(SLIBVER) \
  		../mts/libmts.a  ../zotnet/libzot.a
! LDLIBS	=	$(LDLIBES) ../config/version.o $(LDOPTLIB)
  @END: SHAREDLIB
  LINT	=	lint
  LFLAGS	=	-bhu $(OPTIONS) $(TMAOPTS)
--- 143,151 ----
  @BEGIN: SHAREDLIB
  LIBES	=	../config/config.o ../sbr/libmh.so ../mts/libmts.a \
  		../zotnet/libzot.a
! LDLIBES	=	../config/config.o @(DLDFLAG) @(SLDFLAG) -lmh$(SLIBVER) \
  		../mts/libmts.a  ../zotnet/libzot.a
! LDLIBS	=	$(LDLIBES) ../config/version.o $(KRBLIB) $(HESLIB) $(LDOPTLIB)
  @END: SHAREDLIB
  LINT	=	lint
  LFLAGS	=	-bhu $(OPTIONS) $(TMAOPTS)
***************
*** 568,574 ****
  xinc:		inc.o scansbr.o dropsbr.o trmsbr.o \
  			$(POPLIB) $(TMALIB) $(LIBES)
  		$(LD) $(LDFLAGS) -o $@ inc.o scansbr.o dropsbr.o \
! 			trmsbr.o $(POPLIB) $(TMALIB) $(KRBLIB) $(HESLIB) \
  			$(LDLIBS) $(LDCURSES)
  
  l-inc:;		$(LINT) $(LFLAGS) inc.c scansbr.c \
--- 571,577 ----
  xinc:		inc.o scansbr.o dropsbr.o trmsbr.o \
  			$(POPLIB) $(TMALIB) $(LIBES)
  		$(LD) $(LDFLAGS) -o $@ inc.o scansbr.o dropsbr.o \
! 			trmsbr.o $(POPLIB) $(TMALIB) \
  			$(LDLIBS) $(LDCURSES)
  
  l-inc:;		$(LINT) $(LFLAGS) inc.c scansbr.c \
***************
*** 734,741 ****
  msgchk:		xmsgchk
  
  xmsgchk:	msgchk.o $(POPLIB) $(LIBES)
! 		$(LD) $(LDFLAGS) -o $@ msgchk.o $(POPLIB) \
! 					$(KRBLIB) $(HESLIB) $(LDLIBS)
  
  l-msgchk:;	$(LINT) $(LFLAGS) msgchk.c $(POPLLIBS) $(LLIBS)
  
--- 737,743 ----
  msgchk:		xmsgchk
  
  xmsgchk:	msgchk.o $(POPLIB) $(LIBES)
! 		$(LD) $(LDFLAGS) -o $@ msgchk.o $(POPLIB) $(LDLIBS)
  
  l-msgchk:;	$(LINT) $(LFLAGS) msgchk.c $(POPLLIBS) $(LLIBS)
  
*** 1.1	1992/12/31 19:52:28
--- conf/mhconfig.c	1992/12/31 20:23:19
***************
*** 91,96 ****
--- 91,97 ----
  static char *signl = "int";
  static char *slibdir = "/usr/local/lib";
  static char *slflags = "-pic";
+ static char *dldflag = "-Bdynamic";
  static char *sprntf = NULL;
  
  /*  */
***************
*** 132,137 ****
--- 133,139 ----
      "APOP", 0,	/* authenticated pop */
      "BSD43", 0,	/* sgid ttys */
      "KPOP", 0, 	/* KERBEROS pop */
+     "K5POP", 0, /* KERBEROS V5 pop */
      "HESIOD", 0,
      "MIME", 0,	/* multi-media extensions */
      "MPOP", 0,	/* mobile pop */
***************
*** 187,192 ****
--- 189,195 ----
  			"sharedlib", &sharedlib, BD_NIL,
  			"signal", &signl, BD_NIL,
  			"slflags", &slflags, BD_NIL,
+ 			"dldflag", &dldflag, BD_NIL,
  			"slibdir", &slibdir, BD_NIL,
  			"sprintf", &sprntf, BD_NIL,
                          NULL
***************
*** 433,438 ****
--- 436,442 ----
  	fprintf (fp, "s%%@(SLIBDIR)%%%s%%g\n", slibdir);
  	fprintf (fp, "s%%@(SLIBVER)%%%s%%g\n", MHSLIBVER);
  	fprintf (fp, "s%%@(SLFLAGS)%%%s%%g\n", SVAL(slflags));
+ 	fprintf (fp, "s%%@(DLDFLAG)%%%s%%g\n", SVAL(dldflag));
  	if (strcmp (sharedlib, "secure") == 0)
  	    fprintf (fp, "s%%@(SLDFLAG)%%-L%s%%g\n",slibdir);
  	else
*** 1.1	1993/01/04 20:15:17
--- h/strings.h	1993/01/05 01:21:01
***************
*** 3,10 ****
  
  #ifndef	_STRINGS		/* once-only... */
  #define	_STRINGS
  
! #ifdef AUX
  #include <stdlib.h>
  #endif
  
--- 3,10 ----
  
  #ifndef	_STRINGS		/* once-only... */
  #define	_STRINGS
  
! #if defined(AUX) || defined(NeXT)
  #include <stdlib.h>
  #endif
  
***************
*** 51,57 ****
  char   *strncpy ();
  #endif
  
! #ifndef	SVR4
  char   *getenv ();
  char   *calloc (), *malloc (), *realloc ();
  #endif	/* SVR4 */
--- 51,57 ----
  char   *strncpy ();
  #endif
  
! #if !(defined(SVR4)  || defined(NeXT))
  char   *getenv ();
  char   *calloc (), *malloc (), *realloc ();
  #endif	/* SVR4 */
*** 1.1	1992/12/31 20:15:28
--- uip/inc.c	1992/12/31 20:24:02
***************
*** 18,26 ****
  #include "../h/mh.h"
  #ifdef	POP
  #include "../h/dropsbr.h"
- #endif
- #ifdef KPOP
- #include <krb.h>
  #endif
  #ifdef HESIOD
  #include <hesiod.h>
--- 18,23 ----
*** 1.1	1992/12/31 21:48:15
--- uip/popsbr.c	1992/12/31 21:48:57
***************
*** 142,148 ****
  #endif	/* APOP */
  
  #ifndef NNTP
! #ifndef	KPOP
      if ((fd1 = client (host, "tcp", POPSERVICE, rpop, response)) == NOTOK)
  #else	/* KPOP */
      (void) sprintf (buffer, "%s/%s", POPSERVICE, "kpop");
--- 142,148 ----
  #endif	/* APOP */
  
  #ifndef NNTP
! #if !defined(KPOP) && !defined(K5POP)
      if ((fd1 = client (host, "tcp", POPSERVICE, rpop, response)) == NOTOK)
  #else	/* KPOP */
      (void) sprintf (buffer, "%s/%s", POPSERVICE, "kpop");
*** 1.1	1992/12/31 21:48:15
--- uip/pshsbr.c	1992/12/31 21:48:58
***************
*** 142,148 ****
  #endif	/* APOP */
  
  #ifndef NNTP
! #ifndef	KPOP
      if ((fd1 = client (host, "tcp", POPSERVICE, rpop, response)) == NOTOK)
  #else	/* KPOP */
      (void) sprintf (buffer, "%s/%s", POPSERVICE, "kpop");
--- 142,148 ----
  #endif	/* APOP */
  
  #ifndef NNTP
! #if !defined(KPOP) && !defined(K5POP)
      if ((fd1 = client (host, "tcp", POPSERVICE, rpop, response)) == NOTOK)
  #else	/* KPOP */
      (void) sprintf (buffer, "%s/%s", POPSERVICE, "kpop");
*** 1.1	1992/12/31 21:04:34
--- zotnet/mts/client.c	1992/12/31 21:39:01
***************
*** 27,32 ****
--- 27,35 ----
  #endif
  
  #ifdef KPOP
+ #ifdef K5POP
+ "Can't use both KPOP and K5POP!"
+ #endif
  #include <krb.h>
  #include <ctype.h>
  
***************
*** 35,40 ****
--- 38,51 ----
  static KTEXT ticket = (KTEXT)NULL;
  static Key_schedule schedule;
  #endif	/* KPOP */
+ #ifdef K5POP
+ #include <krb5/krb5.h>
+ #include <krb5/ext-proto.h>
+ #include <ctype.h>
+ #endif /* K5POP */
+ #if defined(KPOP) || defined(K5POP)
+ static char *kservice;		/* "pop" if using kpop */
+ #endif
  
  #define	NOTOK	(-1)
  #define	OK	0
***************
*** 74,85 ****
  static struct addrent *he, *hz;
  static struct addrent hosts[MAXHOSTS];
  
- #ifdef KPOP
- char krb_realm[REALM_SZ];
- char *PrincipalHostname();
- static char *kservice;		/* "pop" if using kpop */
- #endif /* KPOP */
- 
  #ifdef __STDC__
  static int rcaux (struct servent *, struct hostent *, int, char *);
  static int getport (int, int, char *);
--- 85,90 ----
***************
*** 108,114 ****
      register struct netent *np;
  #endif
      register struct servent *sp;
! #ifdef	KPOP
      char *cp;
  
      if (cp = index (kservice = service, '/')) {	/* "pop/kpop" */
--- 113,119 ----
      register struct netent *np;
  #endif
      register struct servent *sp;
! #if defined(KPOP) || defined(K5POP)
      char *cp;
  
      if (cp = index (kservice = service, '/')) {	/* "pop/kpop" */
***************
*** 117,123 ****
      }
      else
  	kservice = NULL;	/* not using KERBEROS */
! #endif	/* KPOP */
      
  
      if ((sp = getservbyname (service, protocol)) == NULL) {
--- 122,128 ----
      }
      else
  	kservice = NULL;	/* not using KERBEROS */
! #endif	/* KPOP || K5POP */
      
  
      if ((sp = getservbyname (service, protocol)) == NULL) {
***************
*** 208,213 ****
--- 213,226 ----
  #ifdef KPOP
      int rem;
  #endif	/* KPOP */
+ #ifdef K5POP
+      krb5_error_code rem;
+      krb5_ccache ccdef;
+      krb5_principal client, server;
+      krb5_error *err_ret;
+      register char *cp;
+ #endif /* K5POP */
+     char *error_string = "Post office refused connection: ";
  
      for (ap = nets; ap < ne; ap++)
  	if (ap -> a_addrtype == hp -> h_addrtype && inet (hp, ap -> a_net))
***************
*** 262,274 ****
  			   "KPOPV0.1");
  	if (rem != KSUCCESS) {
  	    close(sd);
! 	    (void) strcpy(response, "Post office refused connection: ");
  	    (void) strcat(response, krb_err_txt[rem]);
  	    return OOPS2;
  	}
      }
  #endif	/* KPOP */
  
      return sd;
  }
  
--- 275,344 ----
  			   "KPOPV0.1");
  	if (rem != KSUCCESS) {
  	    close(sd);
! 	    (void) strcpy(response, error_string);
  	    (void) strcat(response, krb_err_txt[rem]);
  	    return OOPS2;
  	}
      }
  #endif	/* KPOP */
+ #ifdef K5POP
+     if (kservice) {
+ 	krb5_init_ets();
+ 
+ 	if (rem = krb5_cc_default(&ccdef)) {
+ 	krb5error:
+ 	    close(sd);
+ 	    (void) strcpy(response, error_string);
+ 	    (void) strcat(response, error_message(rem));
+ 	    return OOPS2;
+ 	}
+ 
+ 	if (rem = krb5_cc_get_principal(ccdef, &client)) {
+ 	    goto krb5error;
+ 	}
+ 
+ 	for (cp = hp->h_name; *cp; cp++) {
+ 	    if (isupper(*cp)) {
+ 		*cp = tolower(*cp);
+ 	    }
+ 	}
  
+ 	if (rem = krb5_sname_to_principal(hp->h_name, kservice,
+ 					  FALSE, &server)) {
+ 	    goto krb5error;
+ 	}
+ 
+ 	rem = krb5_sendauth((krb5_pointer) &sd, "KPOPV1.0", client, server,
+ 			    AP_OPTS_MUTUAL_REQUIRED,
+ 			    0,	/* no checksum */
+ 			    0,	/* no creds, use ccache instead */
+ 			    ccdef,
+ 			    0,	/* don't need seq # */
+ 			    0,	/* don't need subsession key */
+ 			    &err_ret,
+ 			    0); /* don't need reply */
+ 	krb5_free_principal(server);
+ 		/* XXX It's really stupid to assume that response is */
+ 		/* big enough to hold errors, but I wasn't the first */
+ 		/* person to do that in this code, so I'm following  */
+ 		/* the other guy's lead.			     */
+ 	if (rem) {
+ 	    (void) strcpy(response, error_string);
+ 	    (void) strcat(response, error_message(rem));
+ 	    if (err_ret && err_ret->text.length) {
+ 		(void) strcat(response, " [server says '");
+ 		(void) strncat(response, err_ret->text.data,
+ 			       err_ret->text.length);
+ 		(void) strcat(response, "']");
+ 	    }
+ 	    if (err_ret) {
+ 		krb5_free_error(err_ret);
+ 	    }
+ 	    (void) close(sd);
+ 	    return OOPS2;
+ 	}
+     }
+ #endif /* K5POP */
      return sd;
  }
  
***************
*** 297,306 ****
  		: "unknown error");
  	return NOTOK;
      }
! #ifdef KPOP
      if (kservice)	/* "pop" */
  	return(sd);
! #endif	/* KPOP */
      if (!rproto)
  	return sd;
  
--- 367,376 ----
  		: "unknown error");
  	return NOTOK;
      }
! #if defined(KPOP) || defined(K5POP)
      if (kservice)	/* "pop" */
  	return(sd);
! #endif	/* KPOP || K5POP */
      if (!rproto)
  	return sd;
  
*** 1.1	1992/12/31 20:29:21
--- support/pop/popd.c	1992/12/31 21:43:23
***************
*** 32,43 ****
  #include <netdb.h>
  #include <arpa/inet.h>
  #ifdef KPOP
  #include <krb.h>
- 
- static Key_schedule schedule;
- static KTEXT_ST ticket;
- static AUTH_DAT kdata;
  #endif
  #ifdef	SYS5
  #include <fcntl.h>
  #endif
--- 32,48 ----
  #include <netdb.h>
  #include <arpa/inet.h>
  #ifdef KPOP
+ #ifdef K5POP
+ "Can't use both KPOP and K5POP!"
+ #endif /* K5POP */
  #include <krb.h>
  #endif
+ #ifdef K5POP
+ #include <krb5/krb5.h>
+ #include <krb5/ext-proto.h>
+ #include <com_err.h>
+ #include <ctype.h>
+ #endif /* K5POP */
  #ifdef	SYS5
  #include <fcntl.h>
  #endif
***************
*** 79,88 ****
  static struct sockaddr_in   in_socket;
  static struct sockaddr_in  *isock = &in_socket;
  
- #ifdef KPOP
- static AUTH_DAT kdata;
- #endif
- 
  static int	chldser ();
  void	padios (), padvise ();
  
--- 84,89 ----
***************
*** 96,102 ****
  char  **argv,
        **envp;
  {
! #ifdef KPOP
      int     i;
  #else
      int     fd,
--- 97,103 ----
  char  **argv,
        **envp;
  {
! #if defined(KPOP) || defined(K5POP)
      int     i;
  #else
      int     fd,
***************
*** 107,113 ****
                         *osock = &out_socket;
  #endif
  
! #ifdef KPOP
      i = sizeof(in_socket);
      if (getpeername(0, &in_socket, &i) < 0)
        padios("getpeername", "bad status");
--- 108,114 ----
                         *osock = &out_socket;
  #endif
  
! #if defined(KPOP) || defined(K5POP)
      i = sizeof(in_socket);
      if (getpeername(0, &in_socket, &i) < 0)
        padios("getpeername", "bad status");
***************
*** 121,127 ****
      arginit (argv);
      envinit ();
  
! #ifndef KPOP
  #ifdef	RESTART
      for (;;) {
  	char    reason[BUFSIZ];
--- 122,128 ----
      arginit (argv);
      envinit ();
  
! #if !defined(KPOP) && !defined(K5POP)
  #ifdef	RESTART
      for (;;) {
  	char    reason[BUFSIZ];
***************
*** 192,202 ****
      (void) signal (SIGCHLD, chldser);
  #endif	/* SIGCHLD */
      (void) listen (sd, SOMAXCONN);
! #endif /* KPOP */
  #ifdef	FAST
      popinit ();
  #endif	/* FAST */
! #ifndef KPOP
      for (;;) {
  	int     i = sizeof *osock;
  
--- 193,203 ----
      (void) signal (SIGCHLD, chldser);
  #endif	/* SIGCHLD */
      (void) listen (sd, SOMAXCONN);
! #endif /* ! (KPOP || K5POP) */
  #ifdef	FAST
      popinit ();
  #endif	/* FAST */
! #if !defined(KPOP) && !defined(K5POP)
      for (;;) {
  	int     i = sizeof *osock;
  
***************
*** 210,216 ****
  #ifdef	FAST
  	popassert ();
  #endif	/* FAST */
! #ifndef KPOP
  	switch (fork ()) {
  	    case OK: 
  		(void) close (sd);
--- 211,217 ----
  #ifdef	FAST
  	popassert ();
  #endif	/* FAST */
! #if !defined(KPOP) && !defined(K5POP)
  	switch (fork ()) {
  	    case OK: 
  		(void) close (sd);
***************
*** 248,253 ****
--- 249,268 ----
      char instance[INST_SZ];
      char version[9];
      char user[ANAME_SZ];
+     KTEXT_ST ticket;
+     Key_schedule schedule;
+     AUTH_DAT kdata;
+ #endif
+ #ifdef K5POP
+     int retval;
+     int sock = 0;
+     krb5_principal server, ext_client;
+     krb5_data *tmpdata;
+     char user[100]; /* I can't find anywhere in the V5 sources a       */
+ 		    /* constant that sets the maximum length of a      */
+ 		    /* component in a principal. XXX I'm assuming that */
+ 		    /* there's nobody out there with a username longer */
+ 		    /* than 99 characters.  So shoot me.               */
  #endif
  
      closelog ();
***************
*** 288,296 ****
        kpop (0, 1, user, (hp ? hp -> h_name : NULLCP), 0);
      }
  #else
      pop (0, 1, sin -> sin_family == AF_INET && port < IPPORT_RESERVED && hp,
  	    hp ? hp -> h_name : NULLCP);
! #endif
  }
  	
  /*  */
--- 303,349 ----
        kpop (0, 1, user, (hp ? hp -> h_name : NULLCP), 0);
      }
  #else
+ #ifdef K5POP
+     krb5_init_ets();
+ 
+     if (retval = krb5_sname_to_principal(myhost, "pop", KRB5_NT_SRV_HST,
+ 					 &server)) {
+ 	padvise(NULLCP, LOG_ERR,
+ 		"server mis-configured, can't get principal--%s",
+ 		error_message(retval));
+ 	kpop(0, 1, NULLCP, NULLCP, retval);
+ 	return;
+     }
+ 
+     if (retval = krb5_recvauth((krb5_pointer)&sock,
+ 			       "KPOPV1.0",
+ 			       server,
+ 			       0,	/* ignore peer address */
+ 			       0, 0, 0,	/* no fetchfrom, keyproc or arg */
+ 			       0,	/* default rc type */
+ 			       0,	/* don't need seq number */
+ 			       &ext_client,
+ 			       0, 0	/* don't care about ticket or
+ 					   authenticator */
+ 			       )) {
+ 	padvise(NULLCP, LOG_INFO, "bad kerberos data, not ok'ing");
+ 	kpop(0, 1, NULLCP, NULLCP, retval);
+ 	return;
+     }
+     krb5_free_principal(server);
+ 
+     tmpdata = krb5_princ_component(ext_client, 0);
+     if (tmpdata->length >= sizeof(user)) {
+ 	tmpdata->length - sizeof(user) - 1;
+     }
+     strncpy(user, tmpdata->data, tmpdata->length);
+     user[tmpdata->length] = '\0';
+     kpop(0, 1, user, (hp ? hp->h_name : NULLCP), 0);
+ #else
      pop (0, 1, sin -> sin_family == AF_INET && port < IPPORT_RESERVED && hp,
  	    hp ? hp -> h_name : NULLCP);
! #endif /* K5POP */
! #endif /* KPOP */
  }
  	
  /*  */
***************
*** 342,348 ****
  /*  */
  
  static  envinit () {
! #ifndef KPOP
      int     i,
              sd;
  
--- 395,401 ----
  /*  */
  
  static  envinit () {
! #if !defined(KPOP) && !defined(K5POP)
      int     i,
              sd;
  
***************
*** 381,387 ****
  
      for (sd = 3; sd < nbits; sd++)
  	(void) close (sd);
! #endif /* KPOP */
  
      (void) signal (SIGPIPE, SIG_IGN);
  
--- 434,440 ----
  
      for (sd = 3; sd < nbits; sd++)
  	(void) close (sd);
! #endif /* ! (KPOP || K5POP) */
  
      (void) signal (SIGPIPE, SIG_IGN);
  
***************
*** 398,404 ****
  
  /*  */
  
! #ifndef KPOP
  
  /* ARGSUSED */
  
--- 451,457 ----
  
  /*  */
  
! #if !defined(KPOP) && !defined(K5POP)
  
  /* ARGSUSED */
  
***************
*** 420,426 ****
  }
  
  #endif /* SIGCHLD */
! #endif /* KPOP */
  
  /*  */
  
--- 473,479 ----
  }
  
  #endif /* SIGCHLD */
! #endif /* ! (KPOP || K5POP) */
  
  /*  */
  
*** 1.1	1992/12/31 20:29:21
--- support/pop/popser.c	1992/12/31 21:04:19
***************
*** 22,29 ****
--- 22,38 ----
  #include <sys/types.h>
  #include <sys/stat.h>
  #ifdef KPOP
+ #ifdef K5POP
+ "Can't use both KPOP and K5POP!"
+ #endif
  #include <krb.h>
  #endif	/* KPOP */
+ #ifdef K5POP
+ #include <krb5/krb5.h>
+ #include <krb5/ext-proto.h>
+ #include <com_err.h>
+ #include <ctype.h>
+ #endif /* K5POP */
  #ifdef	SYS5
  #include <fcntl.h>
  #endif	/* SYS5 */
***************
*** 313,319 ****
  
  /*  */
  
! #ifdef KPOP
  static char *kusername;
  
  kpop (in, out, principal, rhost, auth)
--- 322,328 ----
  
  /*  */
  
! #if defined(KPOP) || defined(K5POP)
  static char *kusername;
  
  kpop (in, out, principal, rhost, auth)
***************
*** 340,352 ****
      mts_init (myname);
  
      hostname = rhost;
! #ifdef KPOP
      rproto = 1;
      (void) sprintf (server, "%s KPOP server", myhost);
  #else
      rproto = priv;
      (void) sprintf (server, "%s server", priv ? "RPOP" : "POP");
! #endif	/* KPOP */
  
      if ((input = fdopen (in, "r")) == NULL
  	    || (output = fdopen (out, "w")) == NULL) {/* you lose big */
--- 349,361 ----
      mts_init (myname);
  
      hostname = rhost;
! #if defined(KPOP) || defined(K5POP)
      rproto = 1;
      (void) sprintf (server, "%s KPOP server", myhost);
  #else
      rproto = priv;
      (void) sprintf (server, "%s server", priv ? "RPOP" : "POP");
! #endif	/* KPOP || K5POP */
  
      if ((input = fdopen (in, "r")) == NULL
  	    || (output = fdopen (out, "w")) == NULL) {/* you lose big */
***************
*** 354,369 ****
  	return;
      }
      (void) signal (SIGPIPE, pipeser);
! #ifdef KPOP
      if (principal == NULLCP) {
  	char buf[512];
  	strcpy(buf,  "Authentication failed: ");
  	strcat(buf, krb_err_txt[auth]);
  	(void) respond (NOTOK, buf);
  	return;
      }
      kusername = principal;
! #endif	/* KPOP */
  
  #ifdef	DPOP
      if ((pw = getpwnam (POPUID)) == NULL || !setpwinfo (pw, POPDB, 1)) {
--- 363,382 ----
  	return;
      }
      (void) signal (SIGPIPE, pipeser);
! #if defined(KPOP) || defined(K5POP)
      if (principal == NULLCP) {
  	char buf[512];
  	strcpy(buf,  "Authentication failed: ");
+ #ifdef KPOP
  	strcat(buf, krb_err_txt[auth]);
+ #else
+ 	strcat(buf, error_message(auth));
+ #endif
  	(void) respond (NOTOK, buf);
  	return;
      }
      kusername = principal;
! #endif	/* KPOP || K5POP */
  
  #ifdef	DPOP
      if ((pw = getpwnam (POPUID)) == NULL || !setpwinfo (pw, POPDB, 1)) {
***************
*** 425,431 ****
  register char  **vec;
  {
      make_lower (username, vec[1]);
! #ifdef KPOP
      if (!strcmp(username, kusername))
        return respond (OK, "Kerberos authentication succeeded. Send username as password (%s)", username);
      else {
--- 438,444 ----
  register char  **vec;
  {
      make_lower (username, vec[1]);
! #if defined(KPOP) || defined(K5POP)
      if (!strcmp(username, kusername))
        return respond (OK, "Kerberos authentication succeeded. Send username as password (%s)", username);
      else {
***************
*** 453,459 ****
      register struct bboard *pw;
  #endif	/* DPOP */
  
! #ifdef KPOP
  #ifndef DPOP
      if ((pw = getpwnam (username)) != NULL)
        return setup(pw, FALSE);
--- 466,472 ----
      register struct bboard *pw;
  #endif	/* DPOP */
  
! #if defined(KPOP) || defined(K5POP)
  #ifndef DPOP
      if ((pw = getpwnam (username)) != NULL)
        return setup(pw, FALSE);
***************
*** 471,477 ****
        return setup(pw, FALSE);
      }
  #endif
! #else	/* KPOP */
  
  #ifndef	DPOP
  #ifdef	BPOP
--- 484,490 ----
        return setup(pw, FALSE);
      }
  #endif
! #else	/* KPOP || K5POP */
  
  #ifndef	DPOP
  #ifdef	BPOP
***************
*** 540,546 ****
  	return respond (NOTOK, "permission denied");
  #endif	/* TRUSTED */
      return setup (pw, guest);
! #endif /* KPOP */
  }
  
  /*  */
--- 553,559 ----
  	return respond (NOTOK, "permission denied");
  #endif	/* TRUSTED */
      return setup (pw, guest);
! #endif /* KPOP || K5POP */
  }
  
  /*  */

-- 
Jonathan Kamens                                       jik@Aktis.COM
Aktis, Inc.                                 Moderator, news.answers