From: Ken Raeburn Date: Tue, 25 Jun 2002 21:38:38 +0000 (+0000) Subject: Move compat_recv.c from krb5util library. Move some duplicated code into X-Git-Tag: krb5-1.3-alpha1~647 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=60c6e8b6ae6c7011d00b2024f6aba788925d0b4d;p=krb5.git Move compat_recv.c from krb5util library. Move some duplicated code into kcmd.c. Use getnameinfo and sockaddr_storage more. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14572 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index f4d438c84..6970a6988 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,5 +1,28 @@ 2002-06-25 Ken Raeburn + * 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. diff --git a/src/appl/bsd/Makefile.in b/src/appl/bsd/Makefile.in index 3f77cafd4..5db0bfc82 100644 --- a/src/appl/bsd/Makefile.in +++ b/src/appl/bsd/Makefile.in @@ -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 index 000000000..b60cdb00f --- /dev/null +++ b/src/appl/bsd/compat_recv.c @@ -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 +#include "com_err.h" +#include + +#include +#include + +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 diff --git a/src/appl/bsd/defines.h b/src/appl/bsd/defines.h index 93ef6ec62..3c7090ddf 100644 --- a/src/appl/bsd/defines.h +++ b/src/appl/bsd/defines.h @@ -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 diff --git a/src/appl/bsd/kcmd.c b/src/appl/bsd/kcmd.c index e252e03f6..0ad0c9d83 100644 --- a/src/appl/bsd/kcmd.c +++ b/src/appl/bsd/kcmd.c @@ -84,7 +84,7 @@ #include #include - + #include #include #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; +} + diff --git a/src/appl/bsd/krlogind.c b/src/appl/bsd/krlogind.c index 5adeb3a13..f8c751ee3 100644 --- a/src/appl/bsd/krlogind.c +++ b/src/appl/bsd/krlogind.c @@ -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 */ diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c index 6f7f447d9..0bb3f69c1 100644 --- a/src/appl/bsd/krshd.c +++ b/src/appl/bsd/krshd.c @@ -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);