Move compat_recv.c from krb5util library. Move some duplicated code into
authorKen Raeburn <raeburn@mit.edu>
Tue, 25 Jun 2002 21:38:38 +0000 (21:38 +0000)
committerKen Raeburn <raeburn@mit.edu>
Tue, 25 Jun 2002 21:38:38 +0000 (21:38 +0000)
kcmd.c.  Use getnameinfo and sockaddr_storage more.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14572 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/bsd/ChangeLog
src/appl/bsd/Makefile.in
src/appl/bsd/compat_recv.c [new file with mode: 0644]
src/appl/bsd/defines.h
src/appl/bsd/kcmd.c
src/appl/bsd/krlogind.c
src/appl/bsd/krshd.c

index f4d438c844b3a584b9760632718a0af43df878c0..6970a698817dbb321ee40c37296f5cfb2a25079c 100644 (file)
@@ -1,5 +1,28 @@
 2002-06-25  Ken Raeburn  <raeburn@mit.edu>
 
+       * compat_recv.c: New file, moved from lib/krb5util.
+       * Makefile.in (SRCS, OBJS): Include it.
+       (rcp, kshd, klogind): Link against it instead of krb5util
+       library.
+       * defines.h (krb5_compat_recvauth, krb5_compat_recvauth_version):
+       Move declarations here from include/k5-util.h.
+       (princ_maps_to_lname): Declare.
+
+       * kcmd.c (kcmd_connect): Use strdup when copying hostname.
+       (princ_maps_to_lname, default_realm): Move functions here...
+       * krlogind.c (princ_maps_to_lname, default_realm): ...from here.
+       (recvauth): Use sockaddr_storage to hold addresses.
+       * krshd.c (default_realm, princ_maps_to_lname): Deleted.
+       (recvauth): Take sockaddr pointer argument instead of
+       sockaddr_in.  Use getnameinfo to extract port number string.
+       (remote_addr, remote_port, local_addr, local_port): Make buffers
+       bigger.
+       (doit): Use sockaddr_storage for local address.  Get rid of all
+       settings of non_privileged, since it's never used.  Don't copy
+       remote address to local variable.  Use getnameinfo instead of
+       inet_ntoa to format addresses and port numbers for environment
+       variables.
+
        * krsh.c (SECURE_MESSAGE): Only indicate that input/output data
        are being encrypted, and don't automatically say it's with DES.
 
index 3f77cafd4830f205ad78178f637715756b6c6843..5db0bfc82bfe14977f3b22b955999bf3aeb8f87d 100644 (file)
@@ -16,10 +16,10 @@ V4RCPO=@V4RCPO@
 KRSHDLIBS=@KRSHDLIBS@
 
 SRCS= $(srcdir)/krcp.c $(srcdir)/krlogin.c $(srcdir)/krsh.c $(srcdir)/kcmd.c \
-       $(srcdir)/forward.c \
+       $(srcdir)/forward.c $(srcdir)/compat_recv.c \
        $(srcdir)/login.c $(srcdir)/krshd.c $(srcdir)/krlogind.c \
        $(srcdir)/v4rcp.c
-OBJS= krcp.o krlogin.o krsh.o kcmd.o forward.o  $(SETENVOBJ) \
+OBJS= krcp.o krlogin.o krsh.o kcmd.o forward.o compat_recv.o $(SETENVOBJ) \
        login.o krshd.o krlogind.o $(V4RCPO) $(LIBOBJS)
 
 UCB_RLOGIN = @UCB_RLOGIN@
@@ -42,8 +42,8 @@ clean::
 rsh: krsh.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB4COMPAT_DEPLIBS)
        $(CC_LINK) -o rsh krsh.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB4COMPAT_LIBS)
 
-rcp: krcp.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(UTIL_DEPLIB) $(KRB4COMATP_DEPLIBS)
-       $(CC_LINK) -o rcp krcp.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(UTIL_LIB) $(KRB4COMPAT_LIBS)
+rcp: krcp.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB4COMATP_DEPLIBS)
+       $(CC_LINK) -o rcp krcp.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRB4COMPAT_LIBS)
 
 v4rcp: v4rcp.o $(SETENVOBJ) $(LIBOBJS) $(KRB4COMPAT_DEPLIBS)
        $(CC_LINK) -o v4rcp v4rcp.o $(SETENVOBJ) $(LIBOBJS) $(KRB4COMPAT_LIBS)
@@ -66,11 +66,11 @@ install::
                ${DESTDIR}$(CLIENT_MANDIR)/`echo $$f|sed '$(transform)'`.1; \
        fi
 
-kshd: krshd.o kcmd.o  forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(UTIL_DEPLIB) $(KRB4COMPAT_DEPLIBS)
-       $(CC_LINK) -o kshd krshd.o kcmd.o  forward.o $(SETENVOBJ) $(LIBOBJS) $(KRSHDLIBS) $(PTY_LIB) $(UTIL_LIB) $(KRB4COMPAT_LIBS)
+kshd: krshd.o kcmd.o forward.o compat_recv.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(KRB4COMPAT_DEPLIBS)
+       $(CC_LINK) -o kshd krshd.o kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(KRSHDLIBS) $(PTY_LIB) $(KRB4COMPAT_LIBS)
 
-klogind: krlogind.o  kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(UTIL_DEPLIB) $(KRB4COMPAT_DEPLIBS)
-       $(CC_LINK) -o klogind krlogind.o  kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_LIB) $(UTIL_LIB) $(KRB4COMPAT_LIBS)
+klogind: krlogind.o kcmd.o forward.o compat_recv.o $(SETENVOBJ) $(LIBOBJS) $(PTY_DEPLIB) $(KRB4COMPAT_DEPLIBS)
+       $(CC_LINK) -o klogind krlogind.o  kcmd.o forward.o $(SETENVOBJ) $(LIBOBJS) $(PTY_LIB) $(KRB4COMPAT_LIBS)
 
 install::
        for f in kshd klogind; do \
@@ -101,9 +101,9 @@ kcmd.o krcp.o krlogin.o krlogind.o krsh.o krshd.o forward.o: defines.h
 # the Makefile.in file
 #
 $(OUTPRE)krcp.$(OBJEXT): krcp.c $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(SRCTOP)/include/port-sockets.h \
-  $(BUILDTOP)/include/krb5/autoconf.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
+  $(COM_ERR_DEPS) $(SRCTOP)/include/k5-util.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(SRCTOP)/include/port-sockets.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
   $(SRCTOP)/include/socket-utils.h
 $(OUTPRE)krlogin.$(OBJEXT): krlogin.c $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
@@ -115,16 +115,22 @@ $(OUTPRE)krsh.$(OBJEXT): krsh.c $(BUILDTOP)/include/krb5.h \
   $(SRCTOP)/include/kerberosIV/des.h $(SRCTOP)/include/port-sockets.h \
   $(BUILDTOP)/include/krb5/autoconf.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
   $(SRCTOP)/include/socket-utils.h
-$(OUTPRE)kcmd.$(OBJEXT): kcmd.c $(BUILDTOP)/include/krb5.h \
+$(OUTPRE)kcmd.$(OBJEXT): kcmd.c $(SRCTOP)/include/fake-addrinfo.h \
+  $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/socket-utils.h $(BUILDTOP)/include/krb5.h \
   $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(SRCTOP)/include/port-sockets.h \
-  $(BUILDTOP)/include/krb5/autoconf.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
-  $(SRCTOP)/include/socket-utils.h
+  $(SRCTOP)/include/kerberosIV/des.h defines.h
 $(OUTPRE)forward.$(OBJEXT): forward.c $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/krb5/kdb.h \
   $(BUILDTOP)/include/profile.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
   $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/socket-utils.h
+$(OUTPRE)compat_recv.$(OBJEXT): compat_recv.c $(SRCTOP)/include/k5-int.h \
+  $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/port-sockets.h \
+  $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \
+  $(BUILDTOP)/include/profile.h $(SRCTOP)/include/kerberosIV/krb.h \
+  $(SRCTOP)/include/kerberosIV/des.h
 $(OUTPRE)login.$(OBJEXT): login.c $(BUILDTOP)/include/libpty.h \
   $(SRCTOP)/include/syslog.h $(SRCTOP)/include/k5-int.h \
   $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \
@@ -140,14 +146,14 @@ $(OUTPRE)krshd.$(OBJEXT): krshd.c $(BUILDTOP)/include/libpty.h \
   $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-util.h \
   defines.h $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/socket-utils.h
 $(OUTPRE)krlogind.$(OBJEXT): krlogind.c $(SRCTOP)/include/syslog.h \
+  $(SRCTOP)/include/fake-addrinfo.h $(SRCTOP)/include/port-sockets.h \
+  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \
   $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(SRCTOP)/include/port-sockets.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(BUILDTOP)/include/libpty.h \
-  $(SRCTOP)/include/k5-util.h defines.h $(SRCTOP)/include/fake-addrinfo.h \
-  $(SRCTOP)/include/socket-utils.h
+  $(SRCTOP)/include/kerberosIV/des.h $(BUILDTOP)/include/libpty.h \
+  $(SRCTOP)/include/k5-util.h defines.h
 $(OUTPRE)v4rcp.$(OBJEXT): v4rcp.c $(BUILDTOP)/include/krb5.h \
-  $(COM_ERR_DEPS) $(SRCTOP)/include/k5-util.h $(SRCTOP)/include/kerberosIV/krb.h \
-  $(SRCTOP)/include/kerberosIV/des.h $(SRCTOP)/include/port-sockets.h \
-  $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/kerberosIV/krbports.h \
+  $(COM_ERR_DEPS) $(SRCTOP)/include/k5-util.h $(BUILDTOP)/include/krb5/autoconf.h \
+  $(SRCTOP)/include/kerberosIV/krb.h $(SRCTOP)/include/kerberosIV/des.h \
+  $(SRCTOP)/include/port-sockets.h $(SRCTOP)/include/kerberosIV/krbports.h \
   rpaths.h
 
diff --git a/src/appl/bsd/compat_recv.c b/src/appl/bsd/compat_recv.c
new file mode 100644 (file)
index 0000000..b60cdb0
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * lib/krb5/krb/compat_recv.c
+ *
+ * Copyright 1993 by the Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ * 
+ * WITHIN THAT CONSTRAINT, 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 appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ * 
+ *
+ * convenience sendauth/recvauth functions, with compatibility with V4
+ * recvauth.
+ *
+ * NOTE: linking in this function will pull in V4 kerberos routines.
+ *
+ * WARNING: In the V4-style arguments, the ticket and kdata arguments
+ * have different types than the V4 recvauth; in V4, they were KTEXT
+ * and AUTH_DAT *, respectively.  Here, they are KTEXT * and AUTH_DAT **
+ * and they are allocated by recvauth if and only if we end up talking
+ * to a V4 sendauth.
+ */
+
+#define NEED_SOCKETS
+#include "k5-int.h"
+#if !defined(_MACINTOSH)
+#include <kerberosIV/krb.h>
+#include "com_err.h"
+#include <errno.h>
+
+#include <stdio.h>
+#include <string.h>
+
+static int krb_v4_recvauth(long options, int fd, KTEXT ticket,
+                          char *service, char *instance, 
+                          struct sockaddr_in *faddr,
+                          struct sockaddr_in *laddr,
+                          AUTH_DAT *kdata,
+                          char *filename,
+                          Key_schedule schedule,
+                          char *version);
+
+#define        KRB_V4_SENDAUTH_VERS    "AUTHV0.1" /* MUST be 8 chars long */
+#define KRB_V5_SENDAUTH_VERS   "KRB5_SENDAUTH_V1.0"
+
+#define KRB5_RECVAUTH_V4       4
+#define KRB5_RECVAUTH_V5       5
+
+krb5_error_code
+krb5_compat_recvauth(context, auth_context,
+                    /* IN */
+                    fdp, appl_version, server, flags, keytab,
+                    v4_options, v4_service, v4_instance, v4_faddr, v4_laddr,
+                    v4_filename, 
+                    /* OUT */
+                    ticket,
+                    auth_sys, v4_kdata, v4_schedule, v4_version)
+    krb5_context context;
+    krb5_auth_context  *auth_context;
+       krb5_pointer    fdp;
+       char    *appl_version;
+       krb5_principal  server;
+       krb5_int32      flags;
+       krb5_keytab     keytab;
+       krb5_ticket  ** ticket;
+        krb5_int32      *auth_sys;
+
+       /*
+        * Version 4 arguments
+        */
+       krb5_int32 v4_options;   /* bit-pattern of options */
+       char *v4_service;        /* service expected */
+       char *v4_instance;       /* inst expected (may be filled in) */
+       struct sockaddr_in *v4_faddr; /* foreign address */
+       struct sockaddr_in *v4_laddr; /* local address */
+       AUTH_DAT **v4_kdata;     /* kerberos data (returned) */
+       char *v4_filename;       /* name of file with service keys */
+       Key_schedule v4_schedule; /* key schedule (return) */
+       char *v4_version;                /* version string (filled in) */
+{
+       union verslen {
+               krb5_int32      len;
+               char            vers[4];
+       } vers;
+       char    *buf;
+       int     len, length;
+       krb5_int32      retval;
+       int             fd = *( (int *) fdp);
+#ifdef KRB5_KRB4_COMPAT
+       KTEXT           v4_ticket;       /* storage for client's ticket */
+#endif
+               
+       if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4)
+               return((retval < 0) ? errno : ECONNABORTED);
+
+#ifdef KRB5_KRB4_COMPAT
+       if (!strncmp(vers.vers, KRB_V4_SENDAUTH_VERS, 4)) {
+               /*
+                * We must be talking to a V4 sendauth; read in the
+                * rest of the version string and make sure.
+                */
+               if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4)
+                       return((retval < 0) ? errno : ECONNABORTED);
+               
+               if (strncmp(vers.vers, KRB_V4_SENDAUTH_VERS+4, 4))
+                       return KRB5_SENDAUTH_BADAUTHVERS;
+
+               *auth_sys = KRB5_RECVAUTH_V4;
+
+               *v4_kdata = (AUTH_DAT *) malloc( sizeof(AUTH_DAT) );
+               v4_ticket = (KTEXT) malloc(sizeof(KTEXT_ST));
+
+               retval = krb_v4_recvauth(v4_options, fd, v4_ticket,
+                                        v4_service, v4_instance, v4_faddr,
+                                        v4_laddr, *v4_kdata, v4_filename,
+                                        v4_schedule, v4_version);
+               krb5_xfree(v4_ticket);
+               /*
+                * XXX error code translation?
+                */
+               switch (retval) {
+               case RD_AP_OK:
+                   return 0;
+               case RD_AP_TIME:
+                   return KRB5KRB_AP_ERR_SKEW;
+               case RD_AP_EXP:
+                   return KRB5KRB_AP_ERR_TKT_EXPIRED;
+               case RD_AP_NYV:
+                   return KRB5KRB_AP_ERR_TKT_NYV;
+               case RD_AP_NOT_US:
+                   return KRB5KRB_AP_ERR_NOT_US;
+               case RD_AP_UNDEC:
+                   return KRB5KRB_AP_ERR_BAD_INTEGRITY;
+               case RD_AP_REPEAT:
+                   return KRB5KRB_AP_ERR_REPEAT;
+               case RD_AP_MSG_TYPE:
+                   return KRB5KRB_AP_ERR_MSG_TYPE;
+               case RD_AP_MODIFIED:
+                   return KRB5KRB_AP_ERR_MODIFIED;
+               case RD_AP_ORDER:
+                   return KRB5KRB_AP_ERR_BADORDER;
+               case RD_AP_BADD:
+                   return KRB5KRB_AP_ERR_BADADDR;
+               default:
+                   return KRB5_SENDAUTH_BADRESPONSE;
+               }
+       }
+#endif
+
+       /*
+        * Assume that we're talking to a V5 recvauth; read in the
+        * the version string, and make sure it matches.
+        */
+       
+       len = (int) ntohl(vers.len);
+
+       if (len < 0 || len > 255)
+               return KRB5_SENDAUTH_BADAUTHVERS;
+
+       buf = malloc(len);
+       if (!buf)
+               return ENOMEM;
+       
+       length = krb5_net_read(context, fd, buf, len);
+       if (len != length) {
+               krb5_xfree(buf);
+               if (len < 0)
+                       return errno;
+               else
+                       return ECONNABORTED;
+       }
+
+       if (strcmp(buf, KRB_V5_SENDAUTH_VERS)) {
+               krb5_xfree(buf);
+               return KRB5_SENDAUTH_BADAUTHVERS;
+       }
+       krb5_xfree(buf);
+
+       *auth_sys = KRB5_RECVAUTH_V5;
+       
+       retval = krb5_recvauth(context, auth_context, fdp, appl_version, server,
+                              flags | KRB5_RECVAUTH_SKIP_VERSION, 
+                              keytab, ticket);
+
+       return retval;
+}
+
+krb5_error_code
+krb5_compat_recvauth_version(context, auth_context,
+                            /* IN */
+                            fdp, server, flags, keytab,
+                            v4_options, v4_service, v4_instance, v4_faddr,
+                            v4_laddr,
+                            v4_filename, 
+                            /* OUT */
+                            ticket,
+                            auth_sys, v4_kdata, v4_schedule,
+                            version)
+    krb5_context context;
+    krb5_auth_context  *auth_context;
+       krb5_pointer    fdp;
+       krb5_principal  server;
+       krb5_int32      flags;
+       krb5_keytab     keytab;
+       krb5_ticket  ** ticket;
+        krb5_int32      *auth_sys;
+
+       /*
+        * Version 4 arguments
+        */
+       krb5_int32 v4_options;   /* bit-pattern of options */
+       char *v4_service;        /* service expected */
+       char *v4_instance;       /* inst expected (may be filled in) */
+       struct sockaddr_in *v4_faddr; /* foreign address */
+       struct sockaddr_in *v4_laddr; /* local address */
+       AUTH_DAT **v4_kdata;     /* kerberos data (returned) */
+       char *v4_filename;       /* name of file with service keys */
+       Key_schedule v4_schedule; /* key schedule (return) */
+    krb5_data *version;                /* application version filled in */
+{
+       union verslen {
+               krb5_int32      len;
+               char            vers[4];
+       } vers;
+       char    *buf;
+       int     len, length;
+       krb5_int32      retval;
+       int             fd = *( (int *) fdp);
+#ifdef KRB5_KRB4_COMPAT
+       KTEXT           v4_ticket;       /* storage for client's ticket */
+#endif
+               
+       if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4)
+               return((retval < 0) ? errno : ECONNABORTED);
+
+#ifdef KRB5_KRB4_COMPAT
+       if (!strncmp(vers.vers, KRB_V4_SENDAUTH_VERS, 4)) {
+               /*
+                * We must be talking to a V4 sendauth; read in the
+                * rest of the version string and make sure.
+                */
+               if ((retval = krb5_net_read(context, fd, vers.vers, 4)) != 4)
+                       return((retval < 0) ? errno : ECONNABORTED);
+               
+               if (strncmp(vers.vers, KRB_V4_SENDAUTH_VERS+4, 4))
+                       return KRB5_SENDAUTH_BADAUTHVERS;
+
+               *auth_sys = KRB5_RECVAUTH_V4;
+
+               *v4_kdata = (AUTH_DAT *) malloc( sizeof(AUTH_DAT) );
+               v4_ticket = (KTEXT) malloc(sizeof(KTEXT_ST));
+
+               version->length = KRB_SENDAUTH_VLEN; /* no trailing \0! */
+               version->data = malloc (KRB_SENDAUTH_VLEN + 1);
+               version->data[KRB_SENDAUTH_VLEN] = 0;
+               if (version->data == 0)
+                   return errno;
+               retval = krb_v4_recvauth(v4_options, fd, v4_ticket,
+                                        v4_service, v4_instance, v4_faddr,
+                                        v4_laddr, *v4_kdata, v4_filename,
+                                        v4_schedule, version->data);
+               krb5_xfree(v4_ticket);
+               /*
+                * XXX error code translation?
+                */
+               switch (retval) {
+               case RD_AP_OK:
+                   return 0;
+               case RD_AP_TIME:
+                   return KRB5KRB_AP_ERR_SKEW;
+               case RD_AP_EXP:
+                   return KRB5KRB_AP_ERR_TKT_EXPIRED;
+               case RD_AP_NYV:
+                   return KRB5KRB_AP_ERR_TKT_NYV;
+               case RD_AP_NOT_US:
+                   return KRB5KRB_AP_ERR_NOT_US;
+               case RD_AP_UNDEC:
+                   return KRB5KRB_AP_ERR_BAD_INTEGRITY;
+               case RD_AP_REPEAT:
+                   return KRB5KRB_AP_ERR_REPEAT;
+               case RD_AP_MSG_TYPE:
+                   return KRB5KRB_AP_ERR_MSG_TYPE;
+               case RD_AP_MODIFIED:
+                   return KRB5KRB_AP_ERR_MODIFIED;
+               case RD_AP_ORDER:
+                   return KRB5KRB_AP_ERR_BADORDER;
+               case RD_AP_BADD:
+                   return KRB5KRB_AP_ERR_BADADDR;
+               default:
+                   return KRB5_SENDAUTH_BADRESPONSE;
+               }
+       }
+#endif
+
+       /*
+        * Assume that we're talking to a V5 recvauth; read in the
+        * the version string, and make sure it matches.
+        */
+       
+       len = (int) ntohl(vers.len);
+
+       if (len < 0 || len > 255)
+               return KRB5_SENDAUTH_BADAUTHVERS;
+
+       buf = malloc(len);
+       if (!buf)
+               return ENOMEM;
+       
+       length = krb5_net_read(context, fd, buf, len);
+       if (len != length) {
+               krb5_xfree(buf);
+               if (len < 0)
+                       return errno;
+               else
+                       return ECONNABORTED;
+       }
+
+       if (strcmp(buf, KRB_V5_SENDAUTH_VERS)) {
+               krb5_xfree(buf);
+               return KRB5_SENDAUTH_BADAUTHVERS;
+       }
+       krb5_xfree(buf);
+
+       *auth_sys = KRB5_RECVAUTH_V5;
+       
+       retval = krb5_recvauth_version(context, auth_context, fdp, server,
+                                      flags | KRB5_RECVAUTH_SKIP_VERSION, 
+                                      keytab, ticket, version);
+
+       return retval;
+}
+
+
+#ifndef max
+#define        max(a,b) (((a) > (b)) ? (a) : (b))
+#endif /* max */
+
+#ifdef KRB5_KRB4_COMPAT        
+static int
+krb_v4_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata,
+               filename, schedule, version)
+long options;                   /* bit-pattern of options */
+int fd;                                 /* file descr. to read from */
+KTEXT ticket;                   /* storage for client's ticket */
+char *service;                  /* service expected */
+char *instance;                         /* inst expected (may be filled in) */
+struct sockaddr_in *faddr;      /* address of foreign host on fd */
+struct sockaddr_in *laddr;      /* local address */
+AUTH_DAT *kdata;                /* kerberos data (returned) */
+char *filename;                         /* name of file with service keys */
+Key_schedule schedule;          /* key schedule (return) */
+char *version;                  /* version string (filled in) */
+{
+    int cc, old_vers = 0;
+    int rem;
+    krb5_int32 tkt_len, priv_len;
+    krb5_ui_4 cksum;
+    u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)];
+
+    /* read the application version string */
+    if ((krb_net_read(fd, version, KRB_SENDAUTH_VLEN) !=
+        KRB_SENDAUTH_VLEN))
+       return(errno);
+    version[KRB_SENDAUTH_VLEN] = '\0';
+
+    /* get the length of the ticket */
+    if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) !=
+       sizeof(tkt_len))
+       return(errno);
+    
+    /* sanity check */
+    ticket->length = ntohl((unsigned long)tkt_len);
+    if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) {
+       if (options & KOPT_DO_MUTUAL) {
+           rem = KFAILURE;
+           goto mutual_fail;
+       } else
+           return(KFAILURE); /* XXX there may still be junk on the fd? */
+    }          
+
+    /* read the ticket */
+    if (krb_net_read(fd, (char *) ticket->dat, ticket->length)
+       != ticket->length)
+       return(errno);
+
+    /*
+     * now have the ticket.  decrypt it to get the authenticated
+     * data.
+     */
+    rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr,
+                    kdata,filename);
+
+    if (old_vers) return(rem);  /* XXX can't do mutual with old client */
+
+    /* if we are doing mutual auth, compose a response */
+    if (options & KOPT_DO_MUTUAL) {
+       if (rem != KSUCCESS)
+           /* the krb_rd_req failed */
+           goto mutual_fail;
+
+       /* add one to the (formerly) sealed checksum, and re-seal it
+          for return to the client */
+       cksum = kdata->checksum + 1;
+       cksum = htonl(cksum);
+#ifndef NOENCRYPTION
+       key_sched(kdata->session,schedule);
+#endif /* !NOENCRYPTION */
+       priv_len = krb_mk_priv((unsigned char *)&cksum,
+                              tmp_buf,
+                              (unsigned long) sizeof(cksum),
+                              schedule,
+                              &kdata->session,
+                              laddr,
+                              faddr);
+       if (priv_len < 0) {
+           /* re-sealing failed; notify the client */
+           rem = KFAILURE;      /* XXX */
+mutual_fail:
+           priv_len = -1;
+           tkt_len = htonl((unsigned long) priv_len);
+           /* a length of -1 is interpreted as an authentication
+              failure by the client */
+           if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+               != sizeof(tkt_len))
+               return(cc);
+           return(rem);
+       } else {
+           /* re-sealing succeeded, send the private message */
+           tkt_len = htonl((unsigned long)priv_len);
+           if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len)))
+                != sizeof(tkt_len))
+               return(cc);
+           if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len))
+               != (int) priv_len)
+               return(cc);
+       }
+    }
+    return(rem);
+}
+#endif
+#endif
index 93ef6ec62d1e3d95d1e02f694a3952f6ce29a93d..3c7090ddf35b4f982eb158557bd5183cf116c6a7 100644 (file)
@@ -65,8 +65,30 @@ krb5_error_code rd_and_store_for_creds(krb5_context context,
                                       krb5_data *inbuf, krb5_ticket *ticket,
                                       krb5_ccache *ccache);
 
+
+int princ_maps_to_lname(krb5_principal principal, char *luser);
+
 #ifdef NEED_SETENV
 extern int setenv(char *, char *, int);
 #endif
 
 #include "fake-addrinfo.h"
+
+#ifdef KRB_DEFS
+krb5_error_code krb5_compat_recvauth(krb5_context, krb5_auth_context *,
+                                    krb5_pointer, char *, krb5_principal, 
+                                    krb5_int32, krb5_keytab,
+                                    krb5_int32, char *, char *,
+                                    struct sockaddr_in *, 
+                                    struct sockaddr_in *, char *,
+                                    krb5_ticket **, krb5_int32 *, 
+                                    AUTH_DAT **, Key_schedule, char *);
+
+krb5_error_code
+krb5_compat_recvauth_version(krb5_context, krb5_auth_context *,
+                            krb5_pointer, krb5_principal, krb5_int32, 
+                            krb5_keytab, krb5_int32, char *, char *,
+                            struct sockaddr_in *, struct sockaddr_in *,
+                            char *, krb5_ticket **, krb5_int32*, 
+                            AUTH_DAT **,  Key_schedule, krb5_data *);
+#endif
index e252e03f68ba2c363793b1f8bb046caa0f9cb2a6..0ad0c9d8347e7f57d1c7d760d42324a26134512a 100644 (file)
@@ -84,7 +84,7 @@
 
 #include <netinet/in.h>
 #include <netdb.h>
-     
+
 #include <errno.h>
 #include <krb5.h>
 #ifdef KRB5_KRB4_COMPAT
@@ -224,13 +224,7 @@ kcmd_connect (int *sp, int *addrfamilyp, struct sockaddr_in *sockinp,
        return -1;
     }
 
-    *host_save = malloc(strlen(ap->ai_canonname) + 1);
-    if (*host_save == NULL) {
-       fprintf(stderr, "kcmd: no memory\n");
-       freeaddrinfo(ap);
-       return -1;
-    }
-    strcpy(*host_save, ap->ai_canonname);
+    *host_save = strdup(ap->ai_canonname ? ap->ai_canonname : hname);
 
     for (ap2 = ap; ap; ap = ap->ai_next) {
        char hostbuf[NI_MAXHOST];
@@ -1272,5 +1266,43 @@ strsave(sp)
     (void) strcpy(ret,sp);
     return(ret);
 }
-
 #endif
+
+/* Server side authentication, etc */
+
+int princ_maps_to_lname(principal, luser)      
+     krb5_principal principal;
+     char *luser;
+{
+    char kuser[10];
+    if (!(krb5_aname_to_localname(bsd_context, principal,
+                                 sizeof(kuser), kuser))
+       && (strcmp(kuser, luser) == 0)) {
+       return 1;
+    }
+    return 0;
+}
+
+int default_realm(principal)
+     krb5_principal principal;
+{
+    char *def_realm;
+    unsigned int realm_length;
+    int retval;
+    
+    realm_length = krb5_princ_realm(bsd_context, principal)->length;
+    
+    if ((retval = krb5_get_default_realm(bsd_context, &def_realm))) {
+       return 0;
+    }
+    
+    if ((realm_length != strlen(def_realm)) ||
+       (memcmp(def_realm, krb5_princ_realm(bsd_context, principal)->data, 
+               realm_length))) {
+       free(def_realm);
+       return 0;
+    }  
+    free(def_realm);
+    return 1;
+}
+
index 5adeb3a13f2dd30d13095ed32ef383372ddbc062..f8c751ee3b52f8271fc19c61fca3a5e475890401 100644 (file)
@@ -1338,41 +1338,6 @@ void usage()
 
 
 #ifdef KERBEROS
-int princ_maps_to_lname(principal, luser)      
-     krb5_principal principal;
-     char *luser;
-{
-    char kuser[10];
-    if (!(krb5_aname_to_localname(bsd_context, principal,
-                                 sizeof(kuser), kuser))
-       && (strcmp(kuser, luser) == 0)) {
-       return 1;
-    }
-    return 0;
-}
-
-int default_realm(principal)
-     krb5_principal principal;
-{
-    char *def_realm;
-    unsigned int realm_length;
-    int retval;
-    
-    realm_length = krb5_princ_realm(bsd_context, principal)->length;
-    
-    if ((retval = krb5_get_default_realm(bsd_context, &def_realm))) {
-       return 0;
-    }
-    
-    if ((realm_length != strlen(def_realm)) ||
-       (memcmp(def_realm, krb5_princ_realm(bsd_context, principal)->data, realm_length))) {
-       free(def_realm);
-       return 0;
-    }  
-    free(def_realm);
-    return 1;
-}
-
 
 #ifndef KRB_SENDAUTH_VLEN
 #define        KRB_SENDAUTH_VLEN 8         /* length for version strings */
@@ -1387,7 +1352,7 @@ recvauth(valid_checksum)
 {
     krb5_auth_context auth_context = NULL;
     krb5_error_code status;
-    struct sockaddr_in peersin, laddr;
+    struct sockaddr_storage peersin, laddr;
     int len;
     krb5_data inbuf;
     char v4_instance[INST_SZ]; /* V4 Instance */
@@ -1448,8 +1413,8 @@ recvauth(valid_checksum)
                                  do_encrypt ? KOPT_DO_MUTUAL : 0, /*v4_opts*/
                                  "rcmd",       /* v4_service */
                                  v4_instance,  /* v4_instance */
-                                 &peersin,     /* foriegn address */
-                                 &laddr,       /* our local address */
+                                 ss2sin(&peersin), /* foriegn address */
+                                 ss2sin(&laddr), /* our local address */
                                  "",           /* use default srvtab */
 
                                  &ticket,      /* return ticket */
index 6f7f447d99b4b3729eefa844a38fc0ec80f5f652..0bb3f69c1cfd920d611db045c28eb4f9fec2289e 100644 (file)
@@ -200,10 +200,6 @@ krb5_context bsd_context;
 char *srvtab = NULL;
 krb5_keytab keytab = NULL;
 krb5_ccache ccache = NULL;
-int default_realm(krb5_principal principal);
-#if defined(KERBEROS) && defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS) 
-static int princ_maps_to_lname(krb5_principal principal, char *luser);
-#endif
 
 void fatal(int, const char *);
 
@@ -216,7 +212,7 @@ int maxhostlen = 0;
 int stripdomain = 1;
 int always_ip = 0;
 
-static krb5_error_code recvauth(int netfd, struct sockaddr_in peersin,
+static krb5_error_code recvauth(int netfd, struct sockaddr *peersin,
                                int *valid_checksum);
 
 #else /* !KERBEROS */
@@ -264,7 +260,7 @@ void        error (char *fmt, ...)
      ;
 
 void usage(void), getstr(int, char *, int, char *), 
-    doit(int, struct sockaddr_in *);
+    doit(int, struct sockaddr *);
 
 #ifndef HAVE_INITGROUPS
 int initgroups(char* name, gid_t basegid) {
@@ -492,7 +488,7 @@ int main(argc, argv)
        fatal(fd, "Configuration error: mutually exclusive options specified");
     }
 
-    doit(dup(fd), &from);
+    doit(dup(fd), (struct sockaddr *) &from);
     return 0;
 }
 
@@ -509,10 +505,10 @@ char      shell[64] = "SHELL=";
 char    term[64] = "TERM=network";
 char   path_rest[] = RPATH;
 
-char   remote_addr[64];        /* = "KRB5REMOTEADDR=" */
-char   remote_port[64];        /* = "KRB5REMOTEPORT=" */
-char   local_addr[64];         /* = "KRB5LOCALADDR=" */
-char   local_port[64];         /* = "KRB5LOCALPORT=" */
+char   remote_addr[64+NI_MAXHOST]; /* = "KRB5REMOTEADDR=" */
+char   remote_port[64+NI_MAXSERV]; /* = "KRB5REMOTEPORT=" */
+char   local_addr[64+NI_MAXHOST]; /* = "KRB5LOCALADDR=" */
+char   local_port[64+NI_MAXSERV]; /* = "KRB5LOCALPORT=" */
 #define ADDRPAD 0,0,0,0
 #define KRBPAD 0               /* KRB5CCNAME, optional */
 
@@ -609,7 +605,7 @@ cleanup(signumber)
 
 void doit(f, fromp)
      int f;
-     struct sockaddr_in *fromp;
+     struct sockaddr *fromp;
 {
     char *cp;
 #ifdef KERBEROS
@@ -648,9 +644,7 @@ void doit(f, fromp)
     int pv[2], pw[2], px[2], cc;
     fd_set ready, readfrom;
     char buf[RCMD_BUFSIZ], sig;
-    struct sockaddr_in fromaddr;
-    struct sockaddr_in localaddr;
-    int non_privileged = 0;
+    struct sockaddr_storage localaddr;
 #ifdef POSIX_SIGNALS
     struct sigaction sa;
 #endif
@@ -671,13 +665,12 @@ void doit(f, fromp)
 #endif /* IP_TOS */
     
     { 
-      int sin_len = sizeof (struct sockaddr_in);
+      int sin_len = sizeof (localaddr);
       if (getsockname(f, (struct sockaddr*)&localaddr, &sin_len) < 0) {
        perror("getsockname");
        exit(1);
       }
     }
-    fromaddr = *fromp;
 
 #ifdef POSIX_SIGNALS
     (void)sigemptyset(&sa.sa_mask);
@@ -706,9 +699,6 @@ void doit(f, fromp)
     }
 #ifdef KERBEROS
     netf = f;
-    if ( (fromp->sin_port >= IPPORT_RESERVED ||
-           fromp->sin_port < IPPORT_RESERVED/2))
-      non_privileged = 1;
 #else
     if (fromp->sin_port >= IPPORT_RESERVED ||
            fromp->sin_port < IPPORT_RESERVED/2) {
@@ -779,10 +769,7 @@ void doit(f, fromp)
                   "can't get stderr port: %m");
            exit(1);
        }
-#ifdef KERBEROS
-       if ( port >= IPPORT_RESERVED)
-           non_privileged = 1;
-#else
+#ifndef KERBEROS
        if (port >= IPPORT_RESERVED) {
            syslog(LOG_ERR , "2nd port not reserved\n");
            exit(1);
@@ -817,7 +804,7 @@ void doit(f, fromp)
        exit(1);
     }
 
-    if ((status = recvauth(f, fromaddr,&valid_checksum))) {
+    if ((status = recvauth(f, fromp, &valid_checksum))) {
        error("Authentication failed: %s\n", error_message(status));
        exit(1);
     }
@@ -1438,21 +1425,37 @@ if(port)
     {
       int i;
       /* these four are covered by ADDRPAD */
-      sprintf(local_addr,  "KRB5LOCALADDR=%s", inet_ntoa(localaddr.sin_addr));
-      for (i = 0; envinit[i]; i++);
-      envinit[i] =local_addr;
-
-      sprintf(local_port,  "KRB5LOCALPORT=%d", ntohs(localaddr.sin_port));
-      for (; envinit[i]; i++);
-      envinit[i] =local_port;
+      int aierr;
+      char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
 
-      sprintf(remote_addr, "KRB5REMOTEADDR=%s", inet_ntoa(fromp->sin_addr));
-      for (; envinit[i]; i++);
-      envinit[i] =remote_addr;
+      for (i = 0; envinit[i]; i++);
 
-      sprintf(remote_port, "KRB5REMOTEPORT=%d", ntohs(fromp->sin_port));
-      for (; envinit[i]; i++);
-      envinit[i] =remote_port;
+      aierr = getnameinfo((struct sockaddr *)&localaddr,
+                         socklen((struct sockaddr *)&localaddr),
+                         hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
+                         NI_NUMERICHOST | NI_NUMERICSERV);
+      if (aierr)
+         goto skip_localaddr_env;
+      sprintf(local_addr,  "KRB5LOCALADDR=%s", hbuf);
+      envinit[i++] =local_addr;
+
+      sprintf(local_port,  "KRB5LOCALPORT=%s", sbuf);
+      envinit[i++] =local_port;
+    skip_localaddr_env:
+
+      aierr = getnameinfo(fromp, socklen(fromp),
+                         hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
+                         NI_NUMERICHOST | NI_NUMERICSERV);
+      if (aierr)
+         goto skip_remoteaddr_env;
+      sprintf(remote_addr, "KRB5REMOTEADDR=%s", hbuf);
+      envinit[i++] =remote_addr;
+
+      sprintf(remote_port, "KRB5REMOTEPORT=%s", sbuf);
+      envinit[i++] =remote_port;
+
+    skip_remoteaddr_env:
+      ;
     }
 
     /* If we do anything else, make sure there is space in the array. */
@@ -1760,46 +1763,6 @@ void usage()
 }
 
 
-
-#if defined(KERBEROS) && defined(LOG_OTHER_USERS) && !defined(LOG_ALL_LOGINS) 
-static int princ_maps_to_lname(principal, luser)       
-     krb5_principal principal;
-     char *luser;
-{
-    char kuser[10];
-    if (!(krb5_aname_to_localname(bsd_context, principal,
-                                 sizeof(kuser), kuser))
-       && (strcmp(kuser, luser) == 0)) {
-       return 1;
-    }
-    return 0;
-}
-#endif
-
-
-int default_realm(principal)
-     krb5_principal principal;
-{
-    char *def_realm;
-    unsigned int realm_length;
-    int retval;
-    
-    realm_length = krb5_princ_realm(bsd_context, principal)->length;
-    
-    if ((retval = krb5_get_default_realm(bsd_context, &def_realm))) {
-       return 0;
-    }
-    
-    if ((realm_length != strlen(def_realm)) ||
-       (memcmp(def_realm, krb5_princ_realm(bsd_context, principal)->data, 
-               realm_length))) {
-       free(def_realm);
-       return 0;
-    }  
-    free(def_realm);
-    return 1;
-}
-
 #ifdef KERBEROS
 
 #ifndef KRB_SENDAUTH_VLEN
@@ -1812,7 +1775,7 @@ int default_realm(principal)
 static krb5_error_code
 recvauth(netfd, peersin, valid_checksum)
      int netfd;
-     struct sockaddr_in peersin;
+     struct sockaddr *peersin;
      int *valid_checksum;
 {
     krb5_auth_context auth_context = NULL;
@@ -1885,7 +1848,7 @@ recvauth(netfd, peersin, valid_checksum)
                                  0,            /* v4_opts */
                                  "rcmd",       /* v4_service */
                                  v4_instance,  /* v4_instance */
-                                 &peersin,     /* foreign address */
+                                 peersin,      /* foreign address */
                                  &laddr,       /* our local address */
                                  "",           /* use default srvtab */
 
@@ -1962,16 +1925,28 @@ recvauth(netfd, peersin, valid_checksum)
       return status;
     
     if (authenticator->checksum && !checksum_ignored) {
-       struct sockaddr_in adr;
-       int adr_length = sizeof(adr);
-       char * chksumbuf = (char *) malloc(strlen(cmdbuf)+strlen(locuser)+32);
+       struct sockaddr_storage adr;
+       unsigned int adr_length = sizeof(adr);
+       int e;
+       unsigned int buflen = strlen(cmdbuf)+strlen(locuser)+32;
+       char * chksumbuf = (char *) malloc(buflen);
 
        if (chksumbuf == 0)
            goto error_cleanup;
        if (getsockname(netfd, (struct sockaddr *) &adr, &adr_length) != 0)
            goto error_cleanup;
 
-       sprintf(chksumbuf,"%u:", ntohs(adr.sin_port));
+       e = getnameinfo((struct sockaddr *)&adr, adr_length, 0, 0,
+                       chksumbuf, buflen, NI_NUMERICSERV);
+       if (e) {
+           free(chksumbuf);
+           fatal(netfd, "local error: can't examine port number");
+       }
+       if (strlen(chksumbuf) > 30) {
+           free(chksumbuf);
+           fatal(netfd, "wacky local port number?!");
+       }
+       strcat(chksumbuf, ":");
        strcat(chksumbuf,cmdbuf);
        strcat(chksumbuf,locuser);