From: Ken Raeburn Date: Wed, 1 Jan 2003 10:13:20 +0000 (+0000) Subject: Add IPv6 support to rshd test/debug code: X-Git-Tag: krb5-1.3-alpha1~199 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=0ec2f8bdb674e49958b0d2b9268d1bb12e533b66;p=krb5.git Add IPv6 support to rshd test/debug code: * compat_recv.c: Include sys/select.h and port-sockets.h. (krb5_compat_recvauth_version): Only attempt krb4 authentication if the source address is an IPv4 one. (accept_a_connection): New function, derived from old krshd.c. Listen on IPv6 as well as IPv4, if possible. * krshd.c (main): Call accept_a_connection. Change fromlen to a socklen_t. (doit): Initialize s. Change length passed to getsockname to a socklen_t. (recvauth): Change len to socklen_t. Cast peer IPv4 address before calling krb5_compat_recvauth_version. * defines.h: Include port-sockets.h. (accept_a_connection): Declare. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15075 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/appl/bsd/ChangeLog b/src/appl/bsd/ChangeLog index 34b9b5361..9eba96dc4 100644 --- a/src/appl/bsd/ChangeLog +++ b/src/appl/bsd/ChangeLog @@ -1,3 +1,19 @@ +2003-01-01 Ken Raeburn + + * compat_recv.c: Include sys/select.h and port-sockets.h. + (krb5_compat_recvauth_version): Only attempt krb4 authentication + if the source address is an IPv4 one. + (accept_a_connection): New function, derived from old krshd.c. + Listen on IPv6 as well as IPv4, if possible. + * krshd.c (main): Call accept_a_connection. Change fromlen to a + socklen_t. + (doit): Initialize s. Change length passed to getsockname to a + socklen_t. + (recvauth): Change len to socklen_t. Cast peer IPv4 address + before calling krb5_compat_recvauth_version. + * defines.h: Include port-sockets.h. + (accept_a_connection): Declare. + 2002-12-06 Ezra Peisach * configure.in: Quote the argument to AC_CHECK_HEADER. Autoconf diff --git a/src/appl/bsd/compat_recv.c b/src/appl/bsd/compat_recv.c index 7bb27feb1..5450c1c10 100644 --- a/src/appl/bsd/compat_recv.c +++ b/src/appl/bsd/compat_recv.c @@ -251,7 +251,8 @@ krb5_compat_recvauth_version(context, auth_context, return((retval < 0) ? errno : ECONNABORTED); #ifdef KRB5_KRB4_COMPAT - if (!strncmp(vers.vers, KRB_V4_SENDAUTH_VERS, 4)) { + if (v4_faddr->sin_family == AF_INET + && !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. @@ -456,3 +457,118 @@ mutual_fail: } #endif #endif + +#include +#include "port-sockets.h" + +int +accept_a_connection (int debug_port, struct sockaddr *from, + socklen_t *fromlenp) +{ + int n, s, fd, s4 = -1, s6 = -1, on = 1; + fd_set sockets; + + FD_ZERO(&sockets); + +#ifdef KRB5_USE_INET6 + { + struct sockaddr_in6 sock_in6; + + if ((s = socket(AF_INET6, SOCK_STREAM, PF_UNSPEC)) < 0) { + if (errno == EPROTONOSUPPORT) + goto skip_ipv6; + fprintf(stderr, "Error in socket(INET6): %s\n", strerror(errno)); + exit(2); + } + + memset((char *) &sock_in6, 0,sizeof(sock_in6)); + sock_in6.sin6_family = AF_INET6; + sock_in6.sin6_port = htons(debug_port); + sock_in6.sin6_addr = in6addr_any; + + (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + (char *)&on, sizeof(on)); + + if ((bind(s, (struct sockaddr *) &sock_in6, sizeof(sock_in6))) < 0) { + fprintf(stderr, "Error in bind(INET6): %s\n", strerror(errno)); + exit(2); + } + + if ((listen(s, 5)) < 0) { + fprintf(stderr, "Error in listen(INET6): %s\n", strerror(errno)); + exit(2); + } + s6 = s; + FD_SET(s, &sockets); + skip_ipv6: + ; + } +#endif + + { + struct sockaddr_in sock_in; + + if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) { + fprintf(stderr, "Error in socket: %s\n", strerror(errno)); + exit(2); + } + + memset((char *) &sock_in, 0,sizeof(sock_in)); + sock_in.sin_family = AF_INET; + sock_in.sin_port = htons(debug_port); + sock_in.sin_addr.s_addr = INADDR_ANY; + + (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + (char *)&on, sizeof(on)); + + if ((bind(s, (struct sockaddr *) &sock_in, sizeof(sock_in))) < 0) { + if (s6 >= 0 && errno == EADDRINUSE) + goto try_ipv6_only; + fprintf(stderr, "Error in bind: %s\n", strerror(errno)); + exit(2); + } + + if ((listen(s, 5)) < 0) { + fprintf(stderr, "Error in listen: %s\n", strerror(errno)); + exit(2); + } + s4 = s; + FD_SET(s, &sockets); + try_ipv6_only: + ; + } + if (s4 == -1 && s6 == -1) { + fprintf(stderr, "No valid sockets established, exiting\n"); + exit(2); + } + n = select(((s4 < s6) ? s6 : s4) + 1, &sockets, 0, 0, 0); + if (n < 0) { + fprintf(stderr, "select error: %s\n", strerror(errno)); + exit(2); + } else if (n == 0) { + fprintf(stderr, "internal error? select returns 0\n"); + exit(2); + } + if (s6 != -1 && FD_ISSET(s6, &sockets)) { + if (s4 != -1) + close(s4); + s = s6; + } else if (FD_ISSET(s4, &sockets)) { + if (s6 != -1) + close(s6); + s = s4; + } else { + fprintf(stderr, + "internal error? select returns positive, " + "but neither fd available\n"); + exit(2); + } + + if ((fd = accept(s, from, fromlenp)) < 0) { + fprintf(stderr, "Error in accept: %s\n", strerror(errno)); + exit(2); + } + + close(s); + return fd; +} diff --git a/src/appl/bsd/defines.h b/src/appl/bsd/defines.h index 6c4d9b871..ac7948ab9 100644 --- a/src/appl/bsd/defines.h +++ b/src/appl/bsd/defines.h @@ -93,3 +93,8 @@ krb5_compat_recvauth_version(krb5_context, krb5_auth_context *, char *, krb5_ticket **, krb5_int32*, AUTH_DAT **, Key_schedule, krb5_data *); #endif + +#include "port-sockets.h" + +int accept_a_connection (int debug_port, struct sockaddr *from, + socklen_t *fromlenp); diff --git a/src/appl/bsd/krshd.c b/src/appl/bsd/krshd.c index b3fea3a7a..2a67b7613 100644 --- a/src/appl/bsd/krshd.c +++ b/src/appl/bsd/krshd.c @@ -281,7 +281,8 @@ int main(argc, argv) #if defined(BSD) && BSD+0 >= 43 struct linger linger; #endif - int on = 1, fromlen; + int on = 1; + socklen_t fromlen; struct sockaddr_storage from; extern int opterr, optind; extern char *optarg; @@ -426,49 +427,19 @@ int main(argc, argv) fromlen = sizeof (from); - if (debug_port) { - int s; - struct sockaddr_in sock_in; - - if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) { - fprintf(stderr, "Error in socket: %s\n", strerror(errno)); - exit(2); - } - - memset((char *) &sock_in, 0,sizeof(sock_in)); - sock_in.sin_family = AF_INET; - sock_in.sin_port = htons(debug_port); - sock_in.sin_addr.s_addr = INADDR_ANY; - - (void) setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (char *)&on, sizeof(on)); - - if ((bind(s, (struct sockaddr *) &sock_in, sizeof(sock_in))) < 0) { - fprintf(stderr, "Error in bind: %s\n", strerror(errno)); - exit(2); - } - - if ((listen(s, 5)) < 0) { - fprintf(stderr, "Error in listen: %s\n", strerror(errno)); - exit(2); - } - - if ((fd = accept(s, (struct sockaddr *) &from, &fromlen)) < 0) { - fprintf(stderr, "Error in accept: %s\n", strerror(errno)); - exit(2); - } - - close(s); - } else { + if (debug_port) + fd = accept_a_connection(debug_port, (struct sockaddr *)&from, + &fromlen); + else { if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) { fprintf(stderr, "%s: ", progname); perror("getpeername"); _exit(1); } - + fd = 0; } - + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof (on)) < 0) syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m"); @@ -632,7 +603,7 @@ void doit(f, fromp) long packet_compart; /* Packet compartments */ #endif /* CRAY */ - int s; + int s = -1; char hostname[NI_MAXHOST]; char *sane_host; char hostaddra[NI_MAXHOST]; @@ -663,11 +634,11 @@ void doit(f, fromp) #endif /* IP_TOS */ { - int sin_len = sizeof (localaddr); - if (getsockname(f, (struct sockaddr*)&localaddr, &sin_len) < 0) { - perror("getsockname"); - exit(1); - } + socklen_t sin_len = sizeof (localaddr); + if (getsockname(f, (struct sockaddr*)&localaddr, &sin_len) < 0) { + perror("getsockname"); + exit(1); + } } #ifdef POSIX_SIGNALS @@ -1799,7 +1770,7 @@ recvauth(netfd, peersin, valid_checksum) krb5_auth_context auth_context = NULL; krb5_error_code status; struct sockaddr_in laddr; - int len; + socklen_t len; krb5_data inbuf; #ifdef KRB5_KRB4_COMPAT char v4_instance[INST_SZ]; /* V4 Instance */ @@ -1866,7 +1837,7 @@ recvauth(netfd, peersin, valid_checksum) 0, /* v4_opts */ "rcmd", /* v4_service */ v4_instance, /* v4_instance */ - peersin, /* foreign address */ + (struct sockaddr_in *)peersin, /* foreign address */ &laddr, /* our local address */ "", /* use default srvtab */ @@ -1882,7 +1853,6 @@ recvauth(netfd, peersin, valid_checksum) &version); /* application version string */ auth_sys = KRB5_RECVAUTH_V5; #endif - if (status) { if (auth_sys == KRB5_RECVAUTH_V5) { /*