+2003-01-01 Ken Raeburn <raeburn@mit.edu>
+
+ * 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 <epeisach@bu.edu>
* configure.in: Quote the argument to AC_CHECK_HEADER. Autoconf
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.
}
#endif
#endif
+
+#include <sys/select.h>
+#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;
+}
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);
#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;
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");
long packet_compart; /* Packet compartments */
#endif /* CRAY */
- int s;
+ int s = -1;
char hostname[NI_MAXHOST];
char *sane_host;
char hostaddra[NI_MAXHOST];
#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
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 */
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 */
&version); /* application version string */
auth_sys = KRB5_RECVAUTH_V5;
#endif
-
if (status) {
if (auth_sys == KRB5_RECVAUTH_V5) {
/*