From fc50ce3d9d7221d156aa0e4e8fc2ffad2e52599f Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Fri, 5 Jul 2002 19:56:15 +0000 Subject: [PATCH] Reduce or localize dependencies on address families. * kdc_util.h (ADDRTYPE2FAMILY): New macro. * do_as_req.c (process_as_req): Use inet_ntop instead of inet_ntoa. * do_tgs_req.c (process_tgs_req): Ditto. * dispatch.c (dispatch): Fix inet_ntop code, and use it always. * kerberos_v4.c (process_v4): Check address family before copying out an IPv4 address. Log if not IPv4, but continue. * network.c (set_sa_port): New function. (setup_port): Use it. Combine IPv4 and IPv6 paths; IPv6 still disabled for now. Modify supplied sockaddr instead of making a copy. (process_packet): SADDR is now sockaddr_storage. Use socket-utils macros instead of casting. Enable the IPv6 code. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@14602 dc483132-0cff-0310-8789-dd5450dbe970 --- src/kdc/ChangeLog | 16 +++++ src/kdc/dispatch.c | 13 +--- src/kdc/do_as_req.c | 12 ++-- src/kdc/do_tgs_req.c | 12 ++-- src/kdc/kdc_util.h | 8 +++ src/kdc/kerberos_v4.c | 14 ++-- src/kdc/network.c | 146 +++++++++++++++++++----------------------- 7 files changed, 114 insertions(+), 107 deletions(-) diff --git a/src/kdc/ChangeLog b/src/kdc/ChangeLog index a9b63ce9d..9e420e070 100644 --- a/src/kdc/ChangeLog +++ b/src/kdc/ChangeLog @@ -1,3 +1,19 @@ +2002-07-05 Ken Raeburn + + * kdc_util.h (ADDRTYPE2FAMILY): New macro. + * do_as_req.c (process_as_req): Use inet_ntop instead of + inet_ntoa. + * do_tgs_req.c (process_tgs_req): Ditto. + * dispatch.c (dispatch): Fix inet_ntop code, and use it always. + * kerberos_v4.c (process_v4): Check address family before copying + out an IPv4 address. Log if not IPv4, but continue. + * network.c (set_sa_port): New function. + (setup_port): Use it. Combine IPv4 and IPv6 paths; IPv6 still + disabled for now. Modify supplied sockaddr instead of making a + copy. + (process_packet): SADDR is now sockaddr_storage. Use socket-utils + macros instead of casting. Enable the IPv6 code. + 2002-07-02 Ken Raeburn * network.c (process_packet): Now static. Drop unused "portnum" diff --git a/src/kdc/dispatch.c b/src/kdc/dispatch.c index db5e72314..896229010 100644 --- a/src/kdc/dispatch.c +++ b/src/kdc/dispatch.c @@ -57,17 +57,8 @@ dispatch(pkt, from, response) const char *name = 0; char buf[46]; -#ifdef HAVE_INET_NTOP - name = inet_ntop (from->address->addrtype, from->address->contents, - buf, sizeof (buf)); -#else - if (from->address->addrtype == ADDRTYPE_INET) { - struct sockaddr_in *mysin - = (struct sockaddr_in *)from->address->contents; - strcpy (buf, inet_ntoa (mysin->sin_addr)); - name = buf; - } -#endif + name = inet_ntop (ADDRTYPE2FAMILY (from->address->addrtype), + from->address->contents, buf, sizeof (buf)); if (name == 0) name = "[unknown address type]"; krb5_klog_syslog(LOG_INFO, diff --git a/src/kdc/do_as_req.c b/src/kdc/do_as_req.c index 4cb982c58..d5eed2c73 100644 --- a/src/kdc/do_as_req.c +++ b/src/kdc/do_as_req.c @@ -55,7 +55,6 @@ process_as_req(request, from, response) const krb5_fulladdr *from; /* who sent it ? */ krb5_data **response; /* filled in with a response packet */ { - krb5_db_entry client, server; krb5_kdc_rep reply; krb5_enc_kdc_rep_part reply_encpart; @@ -76,9 +75,11 @@ process_as_req(request, from, response) krb5_data e_data; register int i; krb5_timestamp until, rtime; - char *cname = 0, *sname = 0, *fromstring = 0; + char *cname = 0, *sname = 0; + const char *fromstring = 0; char ktypestr[128]; char rep_etypestr[128]; + char fromstringbuf[70]; ticket_reply.enc_part.ciphertext.data = 0; e_data.data = 0; @@ -88,10 +89,9 @@ process_as_req(request, from, response) ktypes2str(ktypestr, sizeof(ktypestr), request->nktypes, request->ktype); -#ifdef HAVE_NETINET_IN_H - if (from->address->addrtype == ADDRTYPE_INET) - fromstring = (char *) inet_ntoa(*(struct in_addr *)from->address->contents); -#endif + fromstring = inet_ntop(ADDRTYPE2FAMILY (from->address->addrtype), + from->address->contents, + fromstringbuf, sizeof(fromstringbuf)); if (!fromstring) fromstring = ""; diff --git a/src/kdc/do_tgs_req.c b/src/kdc/do_tgs_req.c index ed33226dc..5b1d20b4d 100644 --- a/src/kdc/do_tgs_req.c +++ b/src/kdc/do_tgs_req.c @@ -76,7 +76,8 @@ process_tgs_req(pkt, from, response) krb5_timestamp until, rtime; krb5_keyblock encrypting_key; krb5_key_data *server_key; - char *cname = 0, *sname = 0, *tmp = 0, *fromstring = 0; + char *cname = 0, *sname = 0, *tmp = 0; + const char *fromstring = 0; krb5_last_req_entry *nolrarray[2], nolrentry; /* krb5_address *noaddrarray[1]; */ krb5_enctype useenctype; @@ -86,6 +87,7 @@ process_tgs_req(pkt, from, response) const char *status = 0; char ktypestr[128]; char rep_etypestr[128]; + char fromstringbuf[70]; session_key.contents = 0; @@ -101,11 +103,9 @@ process_tgs_req(pkt, from, response) if ((retval = setup_server_realm(request->server))) return retval; -#ifdef HAVE_NETINET_IN_H - if (from->address->addrtype == ADDRTYPE_INET) - fromstring = - (char *) inet_ntoa(*(struct in_addr *)from->address->contents); -#endif + fromstring = inet_ntop(ADDRTYPE2FAMILY(from->address->addrtype), + from->address->contents, + fromstringbuf, sizeof(fromstringbuf)); if (!fromstring) fromstring = ""; diff --git a/src/kdc/kdc_util.h b/src/kdc/kdc_util.h index 8e6625262..8e48932e4 100644 --- a/src/kdc/kdc_util.h +++ b/src/kdc/kdc_util.h @@ -184,4 +184,12 @@ void process_v4_mode (const char *, const char *); #define max(a, b) ((a) > (b) ? (a) : (b)) #endif +#ifdef KRB5_USE_INET6 +#define ADDRTYPE2FAMILY(X) \ + ((X) == ADDRTYPE_INET6 ? AF_INET6 : (X) == ADDRTYPE_INET ? AF_INET : -1) +#else +#define ADDRTYPE2FAMILY(X) \ + ((X) == ADDRTYPE_INET ? AF_INET : -1) +#endif + #endif /* __KRB5_KDC_UTIL__ */ diff --git a/src/kdc/kerberos_v4.c b/src/kdc/kerberos_v4.c index d584b9811..cf9fa9fee 100644 --- a/src/kdc/kerberos_v4.c +++ b/src/kdc/kerberos_v4.c @@ -213,9 +213,9 @@ void process_v4_mode(program_name, string) krb5_error_code process_v4( pkt, client_fulladdr, resp) -const krb5_data *pkt; -const krb5_fulladdr *client_fulladdr; -krb5_data **resp; + const krb5_data *pkt; + const krb5_fulladdr *client_fulladdr; + krb5_data **resp; { struct sockaddr_in client_sockaddr; krb5_address *addr = client_fulladdr->address; @@ -244,8 +244,12 @@ krb5_data **resp; */ client_sockaddr.sin_family = AF_INET; client_sockaddr.sin_port = client_fulladdr->port; - memcpy( &client_sockaddr.sin_addr, addr->contents, - sizeof client_sockaddr.sin_addr); + if (client_fulladdr->address->addrtype != ADDRTYPE_INET) { + klog(L_KRB_PERR, "got krb4 request from non-ipv4 address"); + client_sockaddr.sin_addr.s_addr = 0; + } else + memcpy(&client_sockaddr.sin_addr, addr->contents, + sizeof client_sockaddr.sin_addr); memset( client_sockaddr.sin_zero, 0, sizeof client_sockaddr.sin_zero); /* convert v5 packet structure to v4's. diff --git a/src/kdc/network.c b/src/kdc/network.c index babb676cf..76bf9a929 100644 --- a/src/kdc/network.c +++ b/src/kdc/network.c @@ -124,96 +124,84 @@ add_fd (struct socksetup *data, int sock) return 0; } +static void +set_sa_port(struct sockaddr *addr, int port) +{ + switch (addr->sa_family) { + case AF_INET: + sa2sin(addr)->sin_port = port; + break; +#ifdef KRB5_USE_INET6 + case AF_INET6: + sa2sin6(addr)->sin6_port = port; + break; +#endif + default: + break; + } +} + static int setup_port(void *P_data, struct sockaddr *addr) { struct socksetup *data = P_data; int sock = -1, i; + char haddrbuf[NI_MAXHOST]; + int err; + + err = getnameinfo(addr, socklen(addr), haddrbuf, sizeof(haddrbuf), + 0, 0, NI_NUMERICHOST); + if (err) + strcpy(haddrbuf, ""); switch (addr->sa_family) { case AF_INET: - { - struct sockaddr_in *sin4 = (struct sockaddr_in *) addr, psin; - for (i = 0; i < n_udp_ports; i++) { - sock = socket (PF_INET, SOCK_DGRAM, 0); - if (sock == -1) { - data->retval = errno; - com_err(data->prog, data->retval, - "Cannot create server socket for port %d address %s", - udp_port_nums[i], inet_ntoa (sin4->sin_addr)); - return 1; - } - psin = *sin4; - psin.sin_port = htons (udp_port_nums[i]); - if (bind (sock, (struct sockaddr *)&psin, sizeof (psin)) == -1) { - data->retval = errno; - com_err(data->prog, data->retval, - "Cannot bind server socket to port %d address %s", - udp_port_nums[i], inet_ntoa (sin4->sin_addr)); - return 1; - } - FD_SET (sock, &select_fds); - if (sock > select_nfds) - select_nfds = sock; - krb5_klog_syslog (LOG_INFO, "listening on fd %d: %s port %d", sock, - inet_ntoa (sin4->sin_addr), udp_port_nums[i]); - if (add_fd (data, sock)) - return 1; - } - } - break; + break; #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++) { - 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; - com_err(data->prog, data->retval, - "Cannot create server socket for port %d address %s", - udp_port_nums[i], addr_str); - return 1; - } - psin6 = *sin6; - psin6.sin6_port = htons (udp_port_nums[i]); - if (bind (sock, (struct sockaddr *)&psin6, sizeof (psin6)) == -1) { - data->retval = errno; - com_err(data->prog, data->retval, - "Cannot bind server socket to port %d address %s", - udp_port_nums[i], addr_str); - return 1; - } - FD_SET (sock, &select_fds); - if (sock > select_nfds) - 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 +#ifndef KRB5_USE_INET6x { static int first = 1; - if (!first) { + if (first) { krb5_klog_syslog (LOG_INFO, "skipping local ipv6 addresses"); first = 0; } + return 0; } -#endif /* use inet6 */ -#endif /* AF_INET6 */ +#else break; +#endif +#endif default: - break; + krb5_klog_syslog (LOG_INFO, + "skipping unrecognized local address family"); + return 0; + } + + for (i = 0; i < n_udp_ports; i++) { + sock = socket (addr->sa_family, SOCK_DGRAM, 0); + if (sock == -1) { + data->retval = errno; + com_err(data->prog, data->retval, + "Cannot create server socket for port %d address %s", + udp_port_nums[i], haddrbuf); + return 1; + } + set_sa_port(addr, htons(udp_port_nums[i])); + if (bind (sock, (struct sockaddr *)addr, socklen (addr)) == -1) { + data->retval = errno; + com_err(data->prog, data->retval, + "Cannot bind server socket to port %d address %s", + udp_port_nums[i], haddrbuf); + return 1; + } + FD_SET (sock, &select_fds); + if (sock > select_nfds) + select_nfds = sock; + krb5_klog_syslog (LOG_INFO, "listening on fd %d: %s port %d", sock, + haddrbuf, udp_port_nums[i]); + if (add_fd (data, sock)) + return 1; } return 0; } @@ -269,7 +257,7 @@ static void process_packet(port_fd, prog) int cc, saddr_len; krb5_fulladdr faddr; krb5_error_code retval; - struct sockaddr_in saddr; + struct sockaddr_storage saddr; krb5_address addr; krb5_data request; krb5_data *response; @@ -297,19 +285,19 @@ static void process_packet(port_fd, prog) request.length = cc; request.data = pktbuf; faddr.address = &addr; - switch (((struct sockaddr *)&saddr)->sa_family) { + switch (ss2sa(&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); + addr.contents = (krb5_octet *) &ss2sin(&saddr)->sin_addr; + faddr.port = ntohs(ss2sin(&saddr)->sin_port); break; -#ifdef KRB5_USE_INET6x +#ifdef KRB5_USE_INET6 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); + addr.contents = (krb5_octet *) &ss2sin6(&saddr)->sin6_addr; + faddr.port = ntohs(ss2sin6(&saddr)->sin6_port); break; #endif default: -- 2.26.2