* sock2p.c: New file.
authorKen Raeburn <raeburn@mit.edu>
Tue, 14 Mar 2000 16:13:53 +0000 (16:13 +0000)
committerKen Raeburn <raeburn@mit.edu>
Tue, 14 Mar 2000 16:13:53 +0000 (16:13 +0000)
(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
src/kdc/Makefile.in
src/kdc/kdc_util.h
src/kdc/network.c
src/kdc/sock2p.c [new file with mode: 0644]

index d25a0ee8e7d5bdb09df0438834f9d685c8bb1e40..d0bbda28127c1bf7ea64cd441cd9ae288b974494 100644 (file)
@@ -1,3 +1,20 @@
+2000-03-14  Ken Raeburn  <raeburn@mit.edu>
+
+       * 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  <epeisach@mit.edu>
 
        * replay.c, kdb_util.h (kdc_check_lookaside, kdc_insert_lookaside): 
@@ -43,7 +60,6 @@
        with an ifdef.
 
 2000-02-25  Ken Raeburn  <raeburn@mit.edu>
-           Alec H. Peterson  <ahp@hilander.com>
 
        * 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  <raeburn@mit.edu>
+           Alec H. Peterson  <ahp@hilander.com>
+
        * configure.in: Invoke KRB5_SOCKADDR_SA_LEN.
        * network.c: Include <sys/ioctl.h>, <syslog.h>, <net/if.h>.
        (foreach_localaddr): New function, copied from
index 4d9c4f4efee4c94167514c3c58271c65fae1623f..d466e4918600d94d52a4a7967b5c54f7e0144442 100644 (file)
@@ -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 \
index 362dc1fb4379c87c218c3df13a824af520c68d36..ce2377e9d1d781d95472b3dc1ee93457b7171f69 100644 (file)
@@ -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
index e77a12110e74bb71a5499cbb4e6330bd132ac7e2..502682a863ff87e42c3840a81f136497f5657bf2 100644 (file)
@@ -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 (file)
index 0000000..a9763bd
--- /dev/null
@@ -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 <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+#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 */