diff options
Diffstat (limited to 'eBones/lib/libkrb')
-rw-r--r-- | eBones/lib/libkrb/Makefile | 5 | ||||
-rw-r--r-- | eBones/lib/libkrb/krb.3 | 58 | ||||
-rw-r--r-- | eBones/lib/libkrb/krb_err.et | 14 | ||||
-rw-r--r-- | eBones/lib/libkrb/krb_err_txt.c | 12 | ||||
-rw-r--r-- | eBones/lib/libkrb/krb_sendauth.3 | 12 | ||||
-rw-r--r-- | eBones/lib/libkrb/send_to_kdc.c | 140 |
6 files changed, 223 insertions, 18 deletions
diff --git a/eBones/lib/libkrb/Makefile b/eBones/lib/libkrb/Makefile index eefe1a5..829fbea 100644 --- a/eBones/lib/libkrb/Makefile +++ b/eBones/lib/libkrb/Makefile @@ -1,5 +1,5 @@ # From: @(#)Makefile 5.1 (Berkeley) 6/25/90 -# $Id: Makefile,v 1.8 1995/09/13 17:23:55 markm Exp $ +# $Id: Makefile,v 1.9 1995/09/14 04:05:02 gibbs Exp $ LIB= krb CFLAGS+=-DKERBEROS -DCRYPT -DDEBUG -DBSD42 @@ -31,7 +31,8 @@ MAN3= krb.3 krb_realmofhost.3 krb_sendauth.3 krb_set_tkt_string.3 \ MLINKS= krb.3 krb_mk_req.3 krb.3 krb_rd_req.3 krb.3 krb_kntoln.3 \ krb.3 krb_set_key.3 krb.3 krb_get_cred.3 krb.3 krb_mk_priv.3 \ krb.3 krb_rd_priv.3 krb.3 krb_mk_safe.3 krb.3 krb_rd_safe.3 \ - krb.3 krb_mk_err.3 krb.3 krb_rd_err.3 krb.3 krb_ck_repl.3 + krb.3 krb_mk_err.3 krb.3 krb_rd_err.3 krb.3 krb_ck_repl.3 \ + krb.3 krb_get_local_addr.3 krb.3 krb_bind_local_addr.3 MLINKS+=krb_realmofhost.3 krb_get_phost.3 krb_realmofhost.3 krb_get_krbhst.3 \ krb_realmofhost.3 krb_get_admhst.3 krb_realmofhost.3 krb_get_lrealm.3 diff --git a/eBones/lib/libkrb/krb.3 b/eBones/lib/libkrb/krb.3 index 10e20e9..f2061cd 100644 --- a/eBones/lib/libkrb/krb.3 +++ b/eBones/lib/libkrb/krb.3 @@ -1,6 +1,6 @@ -.\" $Source: /usr/cvs/src/eBones/krb/krb.3,v $ -.\" $Author: mark $ -.\" $Header: /usr/cvs/src/eBones/krb/krb.3,v 1.2 1995/07/18 16:40:57 mark Exp $ +.\" $Source: /home/ncvs/src/eBones/lib/libkrb/krb.3,v $ +.\" $Author: markm $ +.\" $Header: /home/ncvs/src/eBones/lib/libkrb/krb.3,v 1.3 1995/09/13 17:23:55 markm Exp $ .\" Copyright 1989 by the Massachusetts Institute of Technology. .\" .\" For copying and distribution information, @@ -8,9 +8,12 @@ .\" .TH KERBEROS 3 "Kerberos Version 4.0" "MIT Project Athena" .SH NAME -krb_mk_req, krb_rd_req, krb_kntoln, krb_set_key, krb_get_cred, -krb_mk_priv, krb_rd_priv, krb_mk_safe, krb_rd_safe, krb_mk_err, -krb_rd_err, krb_ck_repl \- Kerberos authentication library +Kerberos authentication library +.PP +krb_mk_req, krb_rd_req, krb_kntoln, krb_set_key, +krb_get_cred, krb_mk_priv, krb_rd_priv, krb_mk_safe, +krb_rd_safe, krb_mk_err, krb_rd_err, krb_ck_repl +krb_get_local_addr, krb_bind_local_addr .SH SYNOPSIS .nf .nj @@ -105,6 +108,14 @@ u_char *in; u_long length; long code; MSG_DAT *msg_data; +.PP +.ft B +int krb_get_local_addr(address) +struct sockaddr_in *address; +.PP +.ft B +int krb_bind_local_addr(socket) +int socket; .fi .ft R .SH DESCRIPTION @@ -114,6 +125,17 @@ in this man page, but they are not intended to be used directly. Instead, they are called by the routines that are described, the authentication server and the login program. .PP +The original MIT implementation of the krb library could fail when used on +multi-homed client machines. Two functions, +.I krb_get_local_addr +and +.I krb_bind_local_addr, +are provided to overcome this limitation. Any +application expected to function in a multi-homed environment (clients +with more than one network interface) that opens sockets to perform +authenticated or encrypted transactions must use one of these functions +to bind its sockets to the local address used and authenticated by Kerberos. +.PP .I krb_err_txt[] contains text string descriptions of various Kerberos error codes returned by some of the routines below. @@ -412,6 +434,30 @@ care of). The routine returns zero if the error message has been successfully received, or a Kerberos error code. .PP +.I krb_get_local_addr +retrieves the address of the local interface used for +all kerberos transactions and copies it to the sockaddr_in pointed to +by +.I address. +This information is usually used to bind additional sockets in client +programs to the kerberos authenticated local address so transactions +to kerberos services on remote machines succeed. This routine may be called +at any time and the address returned will not change during the lifetime of +the program. + +The routine returns zero on success or a Kerberos error code. +.PP +.I krb_bind_local_addr +binds +.I socket +to the address of the local interface used for all kerberos +transactions. The bind allows the system to assign a port for the socket, +so programs wishing to specify an explicit port should use +.I krb_get_local_addr +and perform the bind manually. + +The routine returns zero on success or a Kerberos error code. +.PP The .I KTEXT structure is used to pass around text of varying lengths. It consists diff --git a/eBones/lib/libkrb/krb_err.et b/eBones/lib/libkrb/krb_err.et index 7d2baef..6200280 100644 --- a/eBones/lib/libkrb/krb_err.et +++ b/eBones/lib/libkrb/krb_err.et @@ -3,7 +3,7 @@ # "Copyright.MIT". # # from: krb_err.et,v 4.1 89/09/26 09:24:20 jtkohl Exp $ -# $Id: krb_err.et,v 1.3 1995/07/18 16:39:00 mark Exp $ +# $Id: krb_err.et,v 1.3 1995/09/07 21:38:09 markm Exp $ # error_table krb @@ -253,5 +253,17 @@ ec KRBET_KNAME_FMT, "Bad Kerberos name format" + ec KRBET_GT_LADDR_NOSOCK, + "Can't open socket" + + ec KRBET_GT_LADDR_IFLIST, + "Can't retrieve local interface list" + + ec KRBET_GT_LADDR_NVI, + "No valid local interface found" + + ec KRBET_BND_LADDR_BIND, + "Can't bind local address" + end diff --git a/eBones/lib/libkrb/krb_err_txt.c b/eBones/lib/libkrb/krb_err_txt.c index 2c8c0ca..040727b 100644 --- a/eBones/lib/libkrb/krb_err_txt.c +++ b/eBones/lib/libkrb/krb_err_txt.c @@ -4,13 +4,13 @@ * <Copyright.MIT>. * * from: krb_err_txt.c,v 4.7 88/12/01 14:10:14 jtkohl Exp $ - * $Id: krb_err_txt.c,v 1.3 1995/07/18 16:39:02 mark Exp $ + * $Id: krb_err_txt.c,v 1.3 1995/09/07 21:38:10 markm Exp $ */ #if 0 #ifndef lint static char rcsid[] = -"$Id: krb_err_txt.c,v 1.3 1995/07/18 16:39:02 mark Exp $"; +"$Id: krb_err_txt.c,v 1.3 1995/09/07 21:38:10 markm Exp $"; #endif lint #endif @@ -103,10 +103,10 @@ char *krb_err_txt[256] = { "Bad ticket file format (tf_util)", /* 079 */ "Read ticket file before tf_init (tf_util)", /* 080 */ "Bad Kerberos name format (kname_parse)", /* 081 */ - "(reserved)", - "(reserved)", - "(reserved)", - "(reserved)", + "Can't open socket", /* 082 */ + "Can't retrieve local interface list", /* 083 */ + "No valid local interface found", /* 084 */ + "Can't bind local address", /* 085 */ "(reserved)", "(reserved)", "(reserved)", diff --git a/eBones/lib/libkrb/krb_sendauth.3 b/eBones/lib/libkrb/krb_sendauth.3 index 5608255..8f250a5 100644 --- a/eBones/lib/libkrb/krb_sendauth.3 +++ b/eBones/lib/libkrb/krb_sendauth.3 @@ -1,5 +1,5 @@ .\" from: krb_sendauth.3,v 4.1 89/01/23 11:10:58 jtkohl Exp $ -.\" $Id: krb_sendauth.3,v 1.3 1995/07/18 16:41:03 mark Exp $ +.\" $Id: krb_sendauth.3,v 1.3 1995/09/13 17:23:57 markm Exp $ .\" Copyright 1988 by the Massachusetts Institute of Technology. .\" .\" For copying and distribution information, @@ -82,6 +82,13 @@ The function receives the ticket from the client by reading from a network socket. +To ensure proper behavior on multi-homed systems (machines with more +than one network interface) all sockets used with these routines should +be bound to the same address as that used by the Kerberos library via +.I krb_get_local_addr +or +.I krb_bind_local_addr. + .SH KRB_SENDAUTH .PP This function writes the ticket to @@ -338,7 +345,8 @@ will not work properly on sockets set to non-blocking I/O mode. .SH SEE ALSO -krb_mk_req(3), krb_rd_req(3), krb_get_phost(3) +krb_mk_req(3), krb_rd_req(3), krb_get_phost(3), krb_get_local_addr(3), +krb_bind_local_addr(3) .SH AUTHOR John T. Kohl, MIT Project Athena diff --git a/eBones/lib/libkrb/send_to_kdc.c b/eBones/lib/libkrb/send_to_kdc.c index 521ba9a..c9f4355 100644 --- a/eBones/lib/libkrb/send_to_kdc.c +++ b/eBones/lib/libkrb/send_to_kdc.c @@ -4,7 +4,7 @@ * <Copyright.MIT>. * * from: send_to_kdc.c,v 4.20 90/01/02 13:40:37 jtkohl Exp $ - * $Id: send_to_kdc.c,v 1.8 1995/09/14 20:58:35 gibbs Exp $ + * $Id: send_to_kdc.c,v 1.9 1995/09/16 23:11:25 gibbs Exp $ */ #if 0 @@ -22,11 +22,15 @@ static char rcsid_send_to_kdc_c[] = #include <stdio.h> #include <errno.h> #include <sys/time.h> +#include <sys/param.h> #include <sys/types.h> #ifdef lint #include <sys/uio.h> /* struct iovec to make lint happy */ #endif /* lint */ +#include <sys/sysctl.h> #include <sys/socket.h> +#include <net/if.h> +#include <net/route.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> @@ -34,6 +38,11 @@ static char rcsid_send_to_kdc_c[] = #define S_AD_SZ sizeof(struct sockaddr_in) +/* Used for extracting addresses from routing messages */ +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sin_len)) + extern int errno; extern int krb_debug; @@ -41,6 +50,10 @@ extern char *malloc(), *calloc(), *realloc(); int krb_udp_port = 0; +static struct sockaddr_in local_addr = { S_AD_SZ, + AF_INET + }; + /* CLIENT_KRB_TIMEOUT indicates the time to wait before * retrying a server. It's defined in "krb.h". */ @@ -222,6 +235,11 @@ send_to_kdc(pkt,rpkt,realm) bcopy(host->h_addr, (char *)&to.sin_addr, host->h_length); to.sin_port = krb_udp_port; + if ((retval = krb_bind_local_addr(f)) != KSUCCESS) { + fprintf(stderr, "krb_bind_local_addr: %s", krb_err_txt[retval]); + retval = SKDC_CANT; + goto rtn; + } if (send_recv(pkt, rpkt, f, &to, hostlist)) { retval = KSUCCESS; goto rtn; @@ -389,3 +407,123 @@ send_recv(pkt,rpkt,f,_to,addrs) "send_to_kdc(send_rcv)", inet_ntoa(from.sin_addr)); return 0; } + + +static int +setfixedaddr(s) + int s; +{ + struct ifa_msghdr *ifa, *ifa0, *ifa_end; + struct sockaddr_in *cur_addr; + int tries; + int i; + u_long loopback; + int mib[6] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_IFLIST, 0 }; + size_t len; + + /* Get information about our interfaces */ +#define NUMTRIES 10 + tries = 0; + +retry: + len = 0; + if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { + perror("setfixedaddr: Can't get size of interface table: sysctl"); + return GT_LADDR_IFLIST; + } + ifa = (struct ifa_msghdr *)malloc(len); + if (!ifa) { + fprintf(stderr, "setfixedaddr: Cannot malloc\n"); + return (KFAILURE); + } + if (sysctl(mib, 6, ifa, &len, NULL, 0) < 0) { + free(ifa); + if (errno == ENOMEM && tries < NUMTRIES) { + /* Table grew between calls */ + tries++; + goto retry; + } + else { + perror("setfixedaddr: Can't get interface table: sysctl"); + return GT_LADDR_IFLIST; + } + } + loopback = inet_addr("127.0.0.1"); + + ifa0 = ifa; + for(ifa_end = (struct ifa_msghdr *)((caddr_t)ifa + len); + ifa < ifa_end; + (caddr_t)ifa += ifa->ifam_msglen) { + /* Ignore interface name messages and ensure we have an address */ + if (ifa->ifam_type == RTM_IFINFO || !(ifa->ifam_addrs & RTAX_IFA)) + continue; + cur_addr = (struct sockaddr_in *)(ifa + 1); + for (i = 0; i < RTAX_IFA; i++) { + if (ifa->ifam_addrs & (1 << i)) + ADVANCE((caddr_t)cur_addr, cur_addr); + } + if (cur_addr->sin_addr.s_addr != loopback) { + local_addr.sin_addr.s_addr = cur_addr->sin_addr.s_addr; + break; + } + } + free(ifa0); + if (ifa >= ifa_end) { + return GT_LADDR_NVI; + } + if (krb_debug) { + fprintf(stderr, "setfixedaddr: using local address %s\n", + inet_ntoa(local_addr.sin_addr)); + } + return (KSUCCESS); +} + +int +krb_bind_local_addr(s) + int s; +{ + int retval; + if (local_addr.sin_addr.s_addr == INADDR_ANY) { + /* + * We haven't determined the local interface to use + * for kerberos server interactions. Do so now. + */ + if ((retval = setfixedaddr(s)) != KSUCCESS) + return (retval); + } + if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) { + perror("krb_bind_local_addr: bind"); + return BND_LADDR_BIND; + } + if (krb_debug) + printf("local_addr = %s\n", inet_ntoa(local_addr.sin_addr)); + return(KSUCCESS); +} + +int +krb_get_local_addr(returned_addr) + struct sockaddr_in *returned_addr; +{ + int retval; + if (local_addr.sin_addr.s_addr == INADDR_ANY) { + /* + * We haven't determined the local interface to use + * for kerberos server interactions. Do so now. + */ + int s; + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + return GT_LADDR_NOSOCK; + } + if ((retval = setfixedaddr(s)) != KSUCCESS) { + close(s); + return (retval); + } + close(s); + } + if (!returned_addr) + return(KFAILURE); + *returned_addr = local_addr; + if (krb_debug) + printf("local_addr = %s\n", inet_ntoa(local_addr.sin_addr)); + return (KSUCCESS); +} |