+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):
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.
(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
$(SRCTOP)/lib/kadm5/logger.c \
$(srcdir)/main.c \
$(srcdir)/network.c \
+ $(srcdir)/sock2p.c \
$(srcdir)/policy.c \
$(srcdir)/extern.c \
$(srcdir)/replay.c \
logger.o \
main.o \
network.o \
+ sock2p.o \
policy.o \
extern.o \
replay.o \
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
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)
{
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;
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;
}
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;
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;
}
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:
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) {
--- /dev/null
+/*
+ * 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 */