From 6beb284fb38e0d28128f6572ef8434b5a22f5700 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Tue, 14 Mar 2000 16:13:53 +0000 Subject: [PATCH] * sock2p.c: New file. (inet_ntop): Define if system doesn't provide it. (sockaddr2p): New function. * Makefile.in (SRCS, OBJS): Add sock2p. * kdc_util.h (inet_ntop, sockaddr2p): Declare them. * network.c (add_fd): New function. Reallocate udp_port_fds array as needed here. (setup_port): Use add_fd to record new sockets. Use inet_ntop unconditionally. Disable ipv6 support until process_packet and friends will support it. (process_packet): Ignore ECONNREFUSED when reading UDP packets. Fill in port field of faddr properly, dependent on address family. Use sockaddr2p when logging source address. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@12109 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/ChangeLog | 21 ++++++++- src/kdc/Makefile.in | 2 + src/kdc/kdc_util.h | 7 +++ src/kdc/network.c | 86 +++++++++++++++++++++-------------- src/kdc/sock2p.c | 106 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 188 insertions(+), 34 deletions(-) create mode 100644 src/kdc/sock2p.c diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index d25a0ee8e..d0bbda281 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,3 +1,20 @@ +2000-03-14 Ken Raeburn + + * sock2p.c: New file. + (inet_ntop): Define if system doesn't provide it. + (sockaddr2p): New function. + * Makefile.in (SRCS, OBJS): Add sock2p. + * kdc_util.h (inet_ntop, sockaddr2p): Declare them. + + * network.c (add_fd): New function. Reallocate udp_port_fds array + as needed here. + (setup_port): Use add_fd to record new sockets. Use inet_ntop + unconditionally. Disable ipv6 support until process_packet and + friends will support it. + (process_packet): Ignore ECONNREFUSED when reading UDP packets. + Fill in port field of faddr properly, dependent on address + family. Use sockaddr2p when logging source address. + 2000-03-12 Ezra Peisach * replay.c, kdb_util.h (kdc_check_lookaside, kdc_insert_lookaside): @@ -43,7 +60,6 @@ with an ifdef. 2000-02-25 Ken Raeburn - Alec H. Peterson * configure.in: Invoke KRB5_AC_INET6. * network.c (max_udp_sockets): New variable. @@ -54,6 +70,9 @@ (process_packet): Handle inet6 addresses when building krb5_address structure. +2000-02-25 Ken Raeburn + Alec H. Peterson + * configure.in: Invoke KRB5_SOCKADDR_SA_LEN. * network.c: Include , , . (foreach_localaddr): New function, copied from diff --git a/src/kdc/Makefile.in b/src/kdc/Makefile.in index 4d9c4f4ef..d466e4918 100644 --- a/src/kdc/Makefile.in +++ b/src/kdc/Makefile.in @@ -27,6 +27,7 @@ SRCS= \ $(SRCTOP)/lib/kadm5/logger.c \ $(srcdir)/main.c \ $(srcdir)/network.c \ + $(srcdir)/sock2p.c \ $(srcdir)/policy.c \ $(srcdir)/extern.c \ $(srcdir)/replay.c \ @@ -42,6 +43,7 @@ OBJS= \ logger.o \ main.o \ network.o \ + sock2p.o \ policy.o \ extern.o \ replay.o \ diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index 362dc1fb4..ce2377e9d 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -157,6 +157,13 @@ krb5_boolean kdc_check_lookaside PROTOTYPE((krb5_data *, const krb5_fulladdr *, void kdc_insert_lookaside PROTOTYPE((krb5_data *, const krb5_fulladdr *, krb5_data *)); +/* sock2p.c */ +#ifndef HAVE_INET_NTOP +/* It's provided by sock2p.c in this case. */ +extern char *inet_ntop (int, const void *, char *, size_t); +#endif +extern void sockaddr2p (const struct sockaddr *, char *, size_t, int *); + /* which way to convert key? */ #define CONVERT_INTO_DB 0 #define CONVERT_OUTOF_DB 1 diff --git a/src/kdc/network.c b/src/kdc/network.c index e77a12110..502682a86 100644 --- a/src/kdc/network.c +++ b/src/kdc/network.c @@ -225,6 +225,25 @@ struct socksetup { krb5_error_code retval; }; +static int +add_fd (struct socksetup *data, int sock) +{ + if (n_sockets == max_udp_sockets) { + int *new_fds; + int new_max = max_udp_sockets + n_udp_ports; + new_fds = safe_realloc(udp_port_fds, new_max * sizeof(int)); + if (new_fds == 0) { + data->retval = errno; + com_err(data->prog, data->retval, "cannot save socket info"); + return 1; + } + udp_port_fds = new_fds; + max_udp_sockets = new_max; + } + udp_port_fds[n_sockets++] = sock; + return 0; +} + static int setup_port(void *P_data, struct sockaddr *addr) { @@ -258,25 +277,24 @@ setup_port(void *P_data, struct sockaddr *addr) select_nfds = sock; krb5_klog_syslog (LOG_INFO, "listening on fd %d: %s port %d", sock, inet_ntoa (sin->sin_addr), udp_port_nums[i]); + if (add_fd (data, sock)) + return 1; } } break; -#ifdef KRB5_USE_INET6 +#ifdef AF_INET6 case AF_INET6: +#ifdef KRB5_USE_INET6x /* Not ready yet -- fix process_packet and callees. */ /* XXX We really should be using a single AF_INET6 socket and specify/receive local address info through sendmsg/recvmsg control data. */ { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr, psin6; for (i = 0; i < n_udp_ports; i++) { -#ifdef HAVE_INET_NTOP - char abuf[46] = { 0 }; - const char *addr_str = 0; - addr_str = inet_ntop (sin6->sin6_family, &sin6->sin6_addr, abuf, - sizeof (abuf)); -#endif - if (addr_str == 0) - addr_str = "[some ipv6 address]"; + char addr_str[46] = { 0 }; + if (0 == inet_ntop (sin6->sin6_family, &sin6->sin6_addr, addr_str, + sizeof (addr_str))) + strcpy (addr_str, "?"); sock = socket (PF_INET6, SOCK_DGRAM, 0); if (sock == -1) { data->retval = errno; @@ -299,28 +317,24 @@ setup_port(void *P_data, struct sockaddr *addr) select_nfds = sock; krb5_klog_syslog (LOG_INFO, "listening on fd %d: %s port %d", sock, addr_str, udp_port_nums[i]); + if (add_fd (data, sock)) + return 1; + } + } +#else + { + static int first = 1; + if (!first) { + krb5_klog_syslog (LOG_INFO, "skipping local ipv6 addresses"); + first = 0; } } +#endif /* use inet6 */ +#endif /* AF_INET6 */ break; -#endif default: break; } - if (sock >= 0) { - if (n_sockets == max_udp_sockets) { - int *new_fds; - int new_max = max_udp_sockets + n_udp_ports; - new_fds = safe_realloc(udp_port_fds, new_max * sizeof(int)); - if (new_fds == 0) { - data->retval = errno; - com_err(data->prog, data->retval, "cannot save socket info"); - return 1; - } - udp_port_fds = new_fds; - max_udp_sockets = new_max; - } - udp_port_fds[n_sockets++] = sock; - } return 0; } @@ -376,11 +390,7 @@ void process_packet(port_fd, prog, portnum) int cc, saddr_len; krb5_fulladdr faddr; krb5_error_code retval; -#ifdef KRB5_USE_INET6 - struct sockaddr_storage saddr; -#else struct sockaddr_in saddr; -#endif krb5_address addr; krb5_data request; krb5_data *response; @@ -393,7 +403,12 @@ void process_packet(port_fd, prog, portnum) cc = recvfrom(port_fd, pktbuf, sizeof(pktbuf), 0, (struct sockaddr *)&saddr, &saddr_len); if (cc == -1) { - if (errno != EINTR) + if (errno != EINTR + /* This is how Linux indicates that a previous + transmission was refused, e.g., if the client timed out + before getting the response packet. */ + && errno != ECONNREFUSED + ) com_err(prog, errno, "while receiving from network"); return; } @@ -402,19 +417,20 @@ void process_packet(port_fd, prog, portnum) request.length = cc; request.data = pktbuf; - faddr.port = ntohs(saddr.sin_port); faddr.address = &addr; switch (((struct sockaddr *)&saddr)->sa_family) { case AF_INET: addr.addrtype = ADDRTYPE_INET; addr.length = 4; addr.contents = (krb5_octet *) &((struct sockaddr_in *)&saddr)->sin_addr; + faddr.port = ntohs(((struct sockaddr_in *)&saddr)->sin_port); break; -#ifdef KRB5_USE_INET6 +#ifdef KRB5_USE_INET6x case AF_INET6: addr.addrtype = ADDRTYPE_INET6; addr.length = 16; addr.contents = (krb5_octet *) &((struct sockaddr_in6 *)&saddr)->sin6_addr; + faddr.port = ntohs(((struct sockaddr_in6 *)&saddr)->sin6_port); break; #endif default: @@ -431,9 +447,13 @@ void process_packet(port_fd, prog, portnum) cc = sendto(port_fd, response->data, response->length, 0, (struct sockaddr *)&saddr, saddr_len); if (cc == -1) { + char addrbuf[46]; + int portno; krb5_free_data(kdc_context, response); + sockaddr2p ((struct sockaddr *) &saddr, addrbuf, sizeof (addrbuf), + &portno); com_err(prog, errno, "while sending reply to %s/%d", - inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port)); + addrbuf, ntohs(portno)); return; } if (cc != response->length) { diff --git a/src/kdc/sock2p.c b/src/kdc/sock2p.c new file mode 100644 index 000000000..a9763bd33 --- /dev/null +++ b/src/kdc/sock2p.c @@ -0,0 +1,106 @@ +/* + * kdc/sock2p.c + * + * Copyright 2000 by the Massachusetts Institute of Technology. + * + * 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. + * + * + * Network code for Kerberos v5 KDC. + */ + +#define NEED_SOCKETS +#include "k5-int.h" +#ifdef HAVE_NETINET_IN_H +#include +#include +#include + +#ifndef HAVE_INET_NTOP +char * +inet_ntop (int family, const void *address, char *buf, size_t bufsiz) +{ + char *p; + switch (family) { + case AF_INET: + { + p = inet_ntoa (*(const struct in_addr *)address); + try: + if (strlen (p) >= bufsiz) + return 0; + strcpy (buf, p); + break; + } +#ifdef KRB5_USE_INET6 + case AF_INET6: + { + char abuf[46]; + const unsigned char *byte = (const unsigned char *) + &((const struct in6_addr *)address)->s6_addr; + sprintf (abuf, "%x:%x:%x:%x:%x:%x:%x:%x", + byte[0] * 256 + byte[1], + byte[2] * 256 + byte[3], + byte[4] * 256 + byte[5], + byte[6] * 256 + byte[7], + byte[8] * 256 + byte[9], + byte[10] * 256 + byte[11], + byte[12] * 256 + byte[13], + byte[14] * 256 + byte[15]); + p = abuf; + goto try; + } +#endif /* KRB5_USE_INET6 */ + default: + return 0; + } + return buf; +} +#endif + +void +sockaddr2p (const struct sockaddr *s, char *buf, size_t bufsiz, int *port_p) +{ + const void *addr; + int port; + switch (s->sa_family) { + case AF_INET: + addr = &((const struct sockaddr_in *)s)->sin_addr; + port = ((const struct sockaddr_in *)s)->sin_port; + break; +#ifdef KRB5_USE_INET6 + case AF_INET6: + addr = &((const struct sockaddr_in6 *)s)->sin6_addr; + port = ((const struct sockaddr_in6 *)s)->sin6_port; + break; +#endif + default: + if (bufsiz >= 2) + strcpy (buf, "?"); + if (port_p) + *port_p = -1; + return; + } + if (inet_ntop (s->sa_family, addr, buf, bufsiz) == 0 && bufsiz >= 2) + strcpy (buf, "?"); + if (port_p) + *port_p = port; +} + +#endif /* INET */ -- 2.26.2