From 2ca944d2bc989363e624b837a7c418c703a2c1f0 Mon Sep 17 00:00:00 2001 From: Assar Westerlund Date: Sun, 21 Sep 1997 13:24:31 +0000 Subject: [PATCH] use new addr_families functions git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3517 ec53bebd-3082-4978-b11e-865c3cabbd6b --- kdc/connect.c | 137 +++++++++++++++++++++----------------- lib/krb5/auth_context.c | 96 ++++++++++---------------- lib/krb5/get_addrs.c | 51 ++------------ lib/krb5/send_to_kdc.c | 73 +++++++++----------- lib/krb5/sock_principal.c | 45 ++++++------- 5 files changed, 168 insertions(+), 234 deletions(-) diff --git a/kdc/connect.c b/kdc/connect.c index 5d2d44d59..b7d78691c 100644 --- a/kdc/connect.c +++ b/kdc/connect.c @@ -151,19 +151,25 @@ struct descr { static void init_socket(struct descr *d, int family, int type, int port) { + krb5_error_code ret; struct sockaddr *sa; - struct sockaddr_in sin; -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - struct sockaddr_in6 sin6; -#endif + char *sa_buf; int sa_size; + sa_size = krb5_max_sockaddr_size (); + sa_buf = malloc(sa_size); + if (sa_buf == NULL) { + kdc_log(0, "Failed to allocate %u bytes", sa_size); + return; + } + sa = (struct sockaddr *)sa_buf; + memset(d, 0, sizeof(*d)); d->s = socket(family, type, 0); if(d->s < 0){ krb5_warn(context, errno, "socket(%d, %d, 0)", family, type); d->s = -1; - return; + goto out; } #if defined(HAVE_SETSOCKOPT) && defined(SOL_SOCKET) && defined(SO_REUSEADDR) { @@ -172,43 +178,27 @@ init_socket(struct descr *d, int family, int type, int port) } #endif d->type = type; - switch (family) { - case AF_INET : - memset(&sin, 0, sizeof(sin)); - sin.sin_family = family; - sin.sin_port = port; - sin.sin_addr.s_addr = INADDR_ANY; - sa = (struct sockaddr *)&sin; - sa_size = sizeof(sin); - break; -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - case AF_INET6 : - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_family = family; - sin6.sin6_port = port; - sin6.sin6_addr = in6addr_any; - sa = (struct sockaddr *)&sin6; - sa_size = sizeof(sin6); - break; -#endif - default : - krb5_warnx(context, "Unknown family: %d", family); + ret = krb5_anyaddr (family, sa, &sa_size, port); + if (ret) { + krb5_warn(context, ret, "krb5_anyaddr"); close(d->s); d->s = -1; - return; + goto out; } - + if(bind(d->s, sa, sa_size) < 0){ krb5_warn(context, errno, "bind(%d)", ntohs(port)); close(d->s); d->s = -1; - return; + goto out; } if(type == SOCK_STREAM && listen(d->s, SOMAXCONN) < 0){ krb5_warn(context, errno, "listen"); close(d->s); d->s = -1; } +out: + free (sa_buf); } static int @@ -282,7 +272,7 @@ addr_to_string(struct sockaddr *addr, size_t addr_len, char *str, size_t len) case AF_INET: strncpy(str, inet_ntoa(((struct sockaddr_in*)addr)->sin_addr), len); break; -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) && defined(HAVE_INET_NTOP) +#if defined(AF_INET6) && defined(HAVE_STRUCT_SOCKADDR_IN6) && defined(HAVE_INET_NTOP) case AF_INET6 : inet_ntop(AF_INET6, &((struct sockaddr_in6*)addr)->sin6_addr, str, len); @@ -317,22 +307,30 @@ static void handle_udp(struct descr *d) { unsigned char *buf; -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - struct sockaddr_in6 from; -#else - struct sockaddr_in from; -#endif - int from_len = sizeof(from); + struct sockaddr *sa; + char *sa_buf; + int sa_size; + int from_len; size_t n; + + sa_size = krb5_max_sockaddr_size (); + sa_buf = malloc(sa_size); + if (sa_buf == NULL) { + kdc_log(0, "Failed to allocate %u bytes", sa_size); + return; + } + sa = (struct sockaddr *)sa_buf; buf = malloc(max_request); if(buf == NULL){ kdc_log(0, "Failed to allocate %u bytes", max_request); + free (sa_buf); return; } + from_len = sa_size; n = recvfrom(d->s, buf, max_request, 0, - (struct sockaddr*)&from, &from_len); + sa, &from_len); if(n < 0){ krb5_warn(context, errno, "recvfrom"); goto out; @@ -340,9 +338,10 @@ handle_udp(struct descr *d) if(n == 0){ goto out; } - do_request(buf, n, d->s, (struct sockaddr*)&from, from_len); + do_request(buf, n, d->s, sa, from_len); out: free (buf); + free (sa_buf); } static void @@ -363,57 +362,66 @@ handle_tcp(struct descr *d, int index, int min_free) { unsigned char buf[1024]; char addr[32]; -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - struct sockaddr_in6 from; -#else - struct sockaddr_in from; -#endif - int from_len = sizeof(from); + char *sa_buf; + struct sockaddr *sa; + int sa_size; + int from_len; size_t n; + sa_size = krb5_max_sockaddr_size (); + sa_buf = malloc(sa_size); + if (sa_buf == NULL) { + kdc_log(0, "Failed to allocate %u bytes", sa_size); + return; + } + sa = (struct sockaddr *)sa_buf; + if(d[index].timeout == 0){ int s; - from_len = sizeof(from); - s = accept(d[index].s, (struct sockaddr*)&from, &from_len); + + from_len = sa_size; + s = accept(d[index].s, sa, &from_len); if(s < 0){ krb5_warn(context, errno, "accept"); - return; + goto out; } if(min_free == -1){ close(s); - return; + goto out; } d[min_free].s = s; d[min_free].timeout = time(NULL) + TCP_TIMEOUT; d[min_free].type = SOCK_STREAM; - return; + goto out; } + from_len = sa_size; n = recvfrom(d[index].s, buf, sizeof(buf), 0, - (struct sockaddr*)&from, &from_len); + sa, &from_len); if(n < 0){ krb5_warn(context, errno, "recvfrom"); - return; + goto out; } /* sometimes recvfrom doesn't return an address */ if(from_len == 0){ - from_len = sizeof(from); - getpeername(d[index].s, (struct sockaddr*)&from, &from_len); + from_len = sa_size; + getpeername(d[index].s, sa, &from_len); } - addr_to_string((struct sockaddr*)&from, from_len, addr, sizeof(addr)); + addr_to_string(sa, from_len, addr, sizeof(addr)); if(d[index].size - d[index].len < n){ unsigned char *tmp; d[index].size += 1024; if(d[index].size >= max_request){ - kdc_log(0, "Request exceeds max request size (%u bytes).", d[index].size); + kdc_log(0, "Request exceeds max request size (%u bytes).", + d[index].size); clear_descr(d + index); - return; + goto out; } tmp = realloc(d[index].buf, d[index].size); if(tmp == NULL){ kdc_log(0, "Failed to re-allocate %u bytes.", d[index].size); clear_descr(d + index); - return; + goto out; } d[index].buf = tmp; } @@ -444,9 +452,13 @@ handle_tcp(struct descr *d, int index, int min_free) if(t == NULL){ kdc_log(0, "Malformed HTTP request from %s", addr); clear_descr(d + index); - return; + goto out; } data = malloc(strlen(t)); + if (data == NULL) { + kdc_log(0, "Failed to allocate %u bytes", strlen(t)); + goto out; + } len = base64_decode(t, data); if(len < 0){ const char *msg = @@ -462,7 +474,7 @@ handle_tcp(struct descr *d, int index, int min_free) free(data); clear_descr(d + index); kdc_log(0, "HTTP request from %s is non KDC request", addr); - return; + goto out; } { const char *msg = @@ -479,13 +491,14 @@ handle_tcp(struct descr *d, int index, int min_free) } if(n == 0){ do_request(d[index].buf, d[index].len, - d[index].s, (struct sockaddr*)&from, from_len); + d[index].s, sa, from_len); clear_descr(d + index); } +out: + free (sa_buf); + return; } - - void loop(void) { diff --git a/lib/krb5/auth_context.c b/lib/krb5/auth_context.c index ea7715ea4..31b9f908b 100644 --- a/lib/krb5/auth_context.c +++ b/lib/krb5/auth_context.c @@ -132,81 +132,55 @@ krb5_auth_con_setaddrs(krb5_context context, return 0; } -static void -sockaddr2krb5_address (struct sockaddr *sa, - krb5_address *ka) -{ - switch (sa->sa_family) { - case AF_INET: { - struct sockaddr_in *sin = (struct sockaddr_in *)sa; - - ka->addr_type = AF_INET; - ka->address.length = sizeof(sin->sin_addr); - ka->address.data = &sin->sin_addr; - break; - } -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - case AF_INET6: { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa; - - if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { - ka->addr_type = AF_INET; - ka->address.length = sizeof(struct in_addr); -#ifndef IN6_ADDR_V6_TO_V4 -#define IN6_ADDR_V6_TO_V4(x) (&IN6_EXTRACT_V4ADDR(x)) -#endif - - ka->address.data = IN6_ADDR_V6_TO_V4(&sin6->sin6_addr); - } else { - ka->addr_type = AF_INET6; - ka->address.length = sizeof(sin6->sin6_addr); - ka->address.data = &sin6->sin6_addr; - } - break; - } -#endif - default: - break; - } -} - - krb5_error_code krb5_auth_con_setaddrs_from_fd (krb5_context context, krb5_auth_context auth_context, int fd) { - krb5_address *lptr = NULL, *rptr = NULL; + krb5_error_code ret; krb5_address local_k_address, remote_k_address; -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - struct sockaddr_in6 local_addr, remote_addr; -#else - struct sockaddr_in local_addr, remote_addr; -#endif + krb5_address *lptr = NULL, *rptr = NULL; + size_t max_sz = krb5_max_sockaddr_size (); + char *buf1 = NULL, *buf2 = NULL; + struct sockaddr *local, *remote; int len; + buf1 = malloc(max_sz); + if (buf1 == NULL) { + ret = ENOMEM; + goto out; + } + local = (struct sockaddr *)buf1; + + buf2 = malloc(max_sz); + if (buf2 == NULL) { + ret = ENOMEM; + goto out; + } + remote = (struct sockaddr *)buf2; + if (auth_context->local_address == NULL) { - len = sizeof (local_addr); - if (getsockname (fd, (struct sockaddr *)&local_addr, &len) < 0) - return errno; - sockaddr2krb5_address((struct sockaddr *)&local_addr, - &local_k_address); + len = max_sz; + if(getsockname(fd, local, &len) < 0) + goto out; + krb5_sockaddr2address (local, &local_k_address); lptr = &local_k_address; } - if (auth_context->remote_address == NULL) { - len = sizeof (remote_addr); - if (getpeername (fd, (struct sockaddr *)&remote_addr, &len) < 0) - return errno; - sockaddr2krb5_address((struct sockaddr *)&remote_addr, - &remote_k_address); + len = max_sz; + if(getpeername(fd, remote, &len) < 0) + goto out; + krb5_sockaddr2address (remote, &remote_k_address); rptr = &remote_k_address; } - - return krb5_auth_con_setaddrs (context, - auth_context, - lptr, - rptr); + ret = krb5_auth_con_setaddrs (context, + auth_context, + lptr, + rptr); +out: + free (buf1); + free (buf2); + return ret; } krb5_error_code diff --git a/lib/krb5/get_addrs.c b/lib/krb5/get_addrs.c index 7aacd1bbb..b0e39a36b 100644 --- a/lib/krb5/get_addrs.c +++ b/lib/krb5/get_addrs.c @@ -174,52 +174,13 @@ find_all_addresses (krb5_addresses *res, int loop, || memcmp (sa, &sa_zero, sizeof(sa_zero)) == 0) continue; - switch (sa->sa_family) { -#ifdef AF_INET - case AF_INET: { - unsigned char addr[4]; - struct sockaddr_in *sin; - res->val[j].addr_type = AF_INET; - /* This is somewhat XXX */ - sin = (struct sockaddr_in*)sa; - memcpy(addr, &sin->sin_addr, 4); - ret = krb5_data_copy(&res->val[j].address, - addr, 4); - if (ret) - goto error_out; - ++j; - break; - } -#endif /* AF_INET */ -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - case AF_INET6: { - struct in6_addr *sin6; + if (krb5_sockaddr_uninteresting (sa)) + continue; - sin6 = &((struct sockaddr_in6 *)(&ifr->ifr_addr))->sin6_addr; - -#ifndef IN6_IS_ADDR_LOOPBACK -#define IN6_IS_ADDR_LOOPBACK(x) IN6_IS_LOOPBACK(*x) -#endif - - if (IN6_IS_ADDR_LOOPBACK(sin6) - || IN6_IS_ADDR_LINKLOCAL(sin6) - || IN6_IS_ADDR_V4COMPAT(sin6)) { - break; - } else { - res->val[j].addr_type = AF_INET6; - ret = krb5_data_copy(&res->val[j].address, - sin6, - sizeof(struct in6_addr)); - } - if (ret) - goto error_out; - ++j; - break; - } -#endif /* AF_INET6 */ - default: - break; - } + ret = krb5_sockaddr2address (sa, &res->val[j]); + if (ret) + goto error_out; + ++j; } if (j != num) { void *tmp; diff --git a/lib/krb5/send_to_kdc.c b/lib/krb5/send_to_kdc.c index 37f80be75..09c837e06 100644 --- a/lib/krb5/send_to_kdc.c +++ b/lib/krb5/send_to_kdc.c @@ -138,26 +138,36 @@ krb5_sendto_kdc (krb5_context context, const krb5_realm *realm, krb5_data *receive) { - krb5_error_code err; + krb5_error_code ret; char **hostlist, **hp, *p; struct hostent *hostent; int fd; int port; int i; + char *buf; + struct sockaddr *sa; port = krb5_getportbyname (context, "kerberos", "udp", 88); - err = krb5_get_krbhst (context, realm, &hostlist); - if (err) { + ret = krb5_get_krbhst (context, realm, &hostlist); + if (ret) { close (fd); - return err; + return ret; } + buf = malloc(krb5_max_sockaddr_size ()); + if (buf == NULL) { + ret = ENOMEM; + goto out; + } + sa = (struct sockaddr *)buf; + for (i = 0; i < context->max_retries; ++i) for (hp = hostlist; (p = *hp); ++hp) { char *addr; char *colon; int http_flag = 0; + int sa_size; if(strncmp(p, "http://", 7) == 0){ p += 7; @@ -178,46 +188,24 @@ krb5_sendto_kdc (krb5_context context, if (colon) *colon++ = ':'; while ((addr = *hostent->h_addr_list++)) { - int ret; - int family; - struct sockaddr *sa; - int sa_size; - struct sockaddr_in sin; -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - struct sockaddr_in6 sin6; -#endif - - family = hostent->h_addrtype; + int family = hostent->h_addrtype; if(http_flag) fd = socket(family, SOCK_STREAM, 0); else fd = socket(family, SOCK_DGRAM, 0); - if(fd < 0) - return errno; - switch (family) { - case AF_INET : - memset(&sin, 0, sizeof(sin)); - sa_size = sizeof(sin); - sa = (struct sockaddr *)&sin; - sin.sin_family = family; - sin.sin_port = init_port(colon, port); - sin.sin_addr = *((struct in_addr *)addr); - break; -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - case AF_INET6: - memset(&sin6, 0, sizeof(sin6)); - sa_size = sizeof(sin6); - sa = (struct sockaddr *)&sin6; - sin6.sin6_family = family; - sin6.sin6_port = init_port(colon, port); - sin6.sin6_addr = *((struct in6_addr *)addr); - break; -#endif - default: - continue; + if(fd < 0) { + ret = errno; + goto out; } + ret = krb5_h_addr2sockaddr (family, + addr, + sa, + &sa_size, + init_port(colon, port)); + if (ret) + continue; if(connect(fd, sa, sa_size) < 0) { close (fd); @@ -232,12 +220,13 @@ krb5_sendto_kdc (krb5_context context, ret = send_and_recv (fd, context->kdc_timeout, 1, send, receive); close (fd); - if(ret == 0){ - krb5_free_krbhst (context, hostlist); - return 0; - } + if(ret == 0) + goto out; } } + ret = KRB5_KDC_UNREACH; +out: krb5_free_krbhst (context, hostlist); - return KRB5_KDC_UNREACH; + free (buf); + return ret; } diff --git a/lib/krb5/sock_principal.c b/lib/krb5/sock_principal.c index 8ddec8674..3433eae71 100644 --- a/lib/krb5/sock_principal.c +++ b/lib/krb5/sock_principal.c @@ -48,34 +48,31 @@ krb5_sock_to_principal (krb5_context context, krb5_principal *ret_princ) { krb5_error_code ret; -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - struct sockaddr_in6 addr; -#else - struct sockaddr_in addr; -#endif - int len = sizeof(addr); + krb5_address address; + int len = krb5_max_sockaddr_size (); + char *buf = malloc(len); + struct sockaddr *sa; struct hostent *hostent; + int family; - if (getsockname (sock, (struct sockaddr *)&addr, &len) < 0) + if (buf == NULL) + return ENOMEM; + sa = (struct sockaddr *)buf; + + if (getsockname (sock, sa, &len) < 0) { + free (buf); return errno; - -#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6) - if(len == sizeof(struct sockaddr_in6)) - hostent = gethostbyaddr ((const char *)&addr.sin6_addr, - sizeof(addr.sin6_addr), - addr.sin6_family); - else { - struct sockaddr_in *foo = (struct sockaddr_in *)&addr; - - hostent = gethostbyaddr ((const char *)&foo->sin_addr, - sizeof(foo->sin_addr), - foo->sin_family); } -#else - hostent = gethostbyaddr ((const char *)&addr.sin_addr, - sizeof(addr.sin_addr), - addr.sin_family); -#endif + family = sa->sa_family; + + ret = krb5_sockaddr2address (sa, &address); + free (buf); + if (ret) + return ret; + + hostent = gethostbyaddr (address.address.data, + address.address.length, + family); if (hostent == NULL) return h_errno;