use new addr_families functions
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@3517 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
		
							
								
								
									
										135
									
								
								kdc/connect.c
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								kdc/connect.c
									
									
									
									
									
								
							@@ -151,19 +151,25 @@ struct descr {
 | 
				
			|||||||
static void 
 | 
					static void 
 | 
				
			||||||
init_socket(struct descr *d, int family, int type, int port)
 | 
					init_socket(struct descr *d, int family, int type, int port)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    krb5_error_code ret;
 | 
				
			||||||
    struct sockaddr *sa;
 | 
					    struct sockaddr *sa;
 | 
				
			||||||
    struct sockaddr_in sin;
 | 
					    char *sa_buf;
 | 
				
			||||||
#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6)
 | 
					 | 
				
			||||||
    struct sockaddr_in6 sin6;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    int sa_size;
 | 
					    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));
 | 
					    memset(d, 0, sizeof(*d));
 | 
				
			||||||
    d->s = socket(family, type, 0);
 | 
					    d->s = socket(family, type, 0);
 | 
				
			||||||
    if(d->s < 0){
 | 
					    if(d->s < 0){
 | 
				
			||||||
	krb5_warn(context, errno, "socket(%d, %d, 0)", family, type);
 | 
						krb5_warn(context, errno, "socket(%d, %d, 0)", family, type);
 | 
				
			||||||
	d->s = -1;
 | 
						d->s = -1;
 | 
				
			||||||
	return;
 | 
						goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#if defined(HAVE_SETSOCKOPT) && defined(SOL_SOCKET) && defined(SO_REUSEADDR)
 | 
					#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
 | 
					#endif
 | 
				
			||||||
    d->type = type;
 | 
					    d->type = type;
 | 
				
			||||||
    switch (family) {
 | 
					    ret = krb5_anyaddr (family, sa, &sa_size, port);
 | 
				
			||||||
    case AF_INET :
 | 
					    if (ret) {
 | 
				
			||||||
	memset(&sin, 0, sizeof(sin));
 | 
						krb5_warn(context, ret, "krb5_anyaddr");
 | 
				
			||||||
	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);
 | 
					 | 
				
			||||||
	close(d->s);
 | 
						close(d->s);
 | 
				
			||||||
	d->s = -1;
 | 
						d->s = -1;
 | 
				
			||||||
	return;
 | 
						goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(bind(d->s, sa, sa_size) < 0){
 | 
					    if(bind(d->s, sa, sa_size) < 0){
 | 
				
			||||||
	krb5_warn(context, errno, "bind(%d)", ntohs(port));
 | 
						krb5_warn(context, errno, "bind(%d)", ntohs(port));
 | 
				
			||||||
	close(d->s);
 | 
						close(d->s);
 | 
				
			||||||
	d->s = -1;
 | 
						d->s = -1;
 | 
				
			||||||
	return;
 | 
						goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(type == SOCK_STREAM && listen(d->s, SOMAXCONN) < 0){
 | 
					    if(type == SOCK_STREAM && listen(d->s, SOMAXCONN) < 0){
 | 
				
			||||||
	krb5_warn(context, errno, "listen");
 | 
						krb5_warn(context, errno, "listen");
 | 
				
			||||||
	close(d->s);
 | 
						close(d->s);
 | 
				
			||||||
	d->s = -1;
 | 
						d->s = -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
					    free (sa_buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int
 | 
					static int
 | 
				
			||||||
@@ -282,7 +272,7 @@ addr_to_string(struct sockaddr *addr, size_t addr_len, char *str, size_t len)
 | 
				
			|||||||
    case AF_INET:
 | 
					    case AF_INET:
 | 
				
			||||||
	strncpy(str, inet_ntoa(((struct sockaddr_in*)addr)->sin_addr), len);
 | 
						strncpy(str, inet_ntoa(((struct sockaddr_in*)addr)->sin_addr), len);
 | 
				
			||||||
	break;
 | 
						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 :
 | 
					    case AF_INET6 :
 | 
				
			||||||
	inet_ntop(AF_INET6, &((struct sockaddr_in6*)addr)->sin6_addr,
 | 
						inet_ntop(AF_INET6, &((struct sockaddr_in6*)addr)->sin6_addr,
 | 
				
			||||||
		  str, len);
 | 
							  str, len);
 | 
				
			||||||
@@ -317,22 +307,30 @@ static void
 | 
				
			|||||||
handle_udp(struct descr *d)
 | 
					handle_udp(struct descr *d)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned char *buf;
 | 
					    unsigned char *buf;
 | 
				
			||||||
#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6)
 | 
					    struct sockaddr *sa;
 | 
				
			||||||
    struct sockaddr_in6 from;
 | 
					    char *sa_buf;
 | 
				
			||||||
#else
 | 
					    int sa_size;
 | 
				
			||||||
    struct sockaddr_in from;
 | 
					    int from_len;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    int from_len = sizeof(from);
 | 
					 | 
				
			||||||
    size_t n;
 | 
					    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);
 | 
					    buf = malloc(max_request);
 | 
				
			||||||
    if(buf == NULL){
 | 
					    if(buf == NULL){
 | 
				
			||||||
	kdc_log(0, "Failed to allocate %u bytes", max_request);
 | 
						kdc_log(0, "Failed to allocate %u bytes", max_request);
 | 
				
			||||||
 | 
						free (sa_buf);
 | 
				
			||||||
	return;
 | 
						return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from_len = sa_size;
 | 
				
			||||||
    n = recvfrom(d->s, buf, max_request, 0, 
 | 
					    n = recvfrom(d->s, buf, max_request, 0, 
 | 
				
			||||||
		 (struct sockaddr*)&from, &from_len);
 | 
							 sa, &from_len);
 | 
				
			||||||
    if(n < 0){
 | 
					    if(n < 0){
 | 
				
			||||||
	krb5_warn(context, errno, "recvfrom");
 | 
						krb5_warn(context, errno, "recvfrom");
 | 
				
			||||||
	goto out;
 | 
						goto out;
 | 
				
			||||||
@@ -340,9 +338,10 @@ handle_udp(struct descr *d)
 | 
				
			|||||||
    if(n == 0){
 | 
					    if(n == 0){
 | 
				
			||||||
	goto out;
 | 
						goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    do_request(buf, n, d->s, (struct sockaddr*)&from, from_len);
 | 
					    do_request(buf, n, d->s, sa, from_len);
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
    free (buf);
 | 
					    free (buf);
 | 
				
			||||||
 | 
					    free (sa_buf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
@@ -363,57 +362,66 @@ handle_tcp(struct descr *d, int index, int min_free)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    unsigned char buf[1024];
 | 
					    unsigned char buf[1024];
 | 
				
			||||||
    char addr[32];
 | 
					    char addr[32];
 | 
				
			||||||
#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6)
 | 
					    char *sa_buf;
 | 
				
			||||||
    struct sockaddr_in6 from;
 | 
					    struct sockaddr *sa;
 | 
				
			||||||
#else
 | 
					    int sa_size;
 | 
				
			||||||
    struct sockaddr_in from;
 | 
					    int from_len;
 | 
				
			||||||
#endif    
 | 
					 | 
				
			||||||
    int from_len = sizeof(from);
 | 
					 | 
				
			||||||
    size_t n;
 | 
					    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){
 | 
					    if(d[index].timeout == 0){
 | 
				
			||||||
	int s;
 | 
						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){
 | 
						if(s < 0){
 | 
				
			||||||
	    krb5_warn(context, errno, "accept");
 | 
						    krb5_warn(context, errno, "accept");
 | 
				
			||||||
	    return;
 | 
						    goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if(min_free == -1){
 | 
						if(min_free == -1){
 | 
				
			||||||
	    close(s);
 | 
						    close(s);
 | 
				
			||||||
	    return;
 | 
						    goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	    
 | 
						    
 | 
				
			||||||
	d[min_free].s = s;
 | 
						d[min_free].s = s;
 | 
				
			||||||
	d[min_free].timeout = time(NULL) + TCP_TIMEOUT;
 | 
						d[min_free].timeout = time(NULL) + TCP_TIMEOUT;
 | 
				
			||||||
	d[min_free].type = SOCK_STREAM;
 | 
						d[min_free].type = SOCK_STREAM;
 | 
				
			||||||
	return;
 | 
						goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    from_len = sa_size;
 | 
				
			||||||
    n = recvfrom(d[index].s, buf, sizeof(buf), 0, 
 | 
					    n = recvfrom(d[index].s, buf, sizeof(buf), 0, 
 | 
				
			||||||
		 (struct sockaddr*)&from, &from_len);
 | 
							 sa, &from_len);
 | 
				
			||||||
    if(n < 0){
 | 
					    if(n < 0){
 | 
				
			||||||
	krb5_warn(context, errno, "recvfrom");
 | 
						krb5_warn(context, errno, "recvfrom");
 | 
				
			||||||
	return;
 | 
						goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    /* sometimes recvfrom doesn't return an address */
 | 
					    /* sometimes recvfrom doesn't return an address */
 | 
				
			||||||
    if(from_len == 0){
 | 
					    if(from_len == 0){
 | 
				
			||||||
	from_len = sizeof(from);
 | 
						from_len = sa_size;
 | 
				
			||||||
	getpeername(d[index].s, (struct sockaddr*)&from, &from_len);
 | 
						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){
 | 
					    if(d[index].size - d[index].len < n){
 | 
				
			||||||
	unsigned char *tmp;
 | 
						unsigned char *tmp;
 | 
				
			||||||
	d[index].size += 1024;
 | 
						d[index].size += 1024;
 | 
				
			||||||
	if(d[index].size >= max_request){
 | 
						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);
 | 
						    clear_descr(d + index);
 | 
				
			||||||
	    return;
 | 
						    goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	tmp = realloc(d[index].buf, d[index].size);
 | 
						tmp = realloc(d[index].buf, d[index].size);
 | 
				
			||||||
	if(tmp == NULL){
 | 
						if(tmp == NULL){
 | 
				
			||||||
	    kdc_log(0, "Failed to re-allocate %u bytes.", d[index].size);
 | 
						    kdc_log(0, "Failed to re-allocate %u bytes.", d[index].size);
 | 
				
			||||||
	    clear_descr(d + index);
 | 
						    clear_descr(d + index);
 | 
				
			||||||
	    return;
 | 
						    goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	d[index].buf = tmp;
 | 
						d[index].buf = tmp;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -444,9 +452,13 @@ handle_tcp(struct descr *d, int index, int min_free)
 | 
				
			|||||||
	if(t == NULL){
 | 
						if(t == NULL){
 | 
				
			||||||
	    kdc_log(0, "Malformed HTTP request from %s", addr);
 | 
						    kdc_log(0, "Malformed HTTP request from %s", addr);
 | 
				
			||||||
	    clear_descr(d + index);
 | 
						    clear_descr(d + index);
 | 
				
			||||||
	    return;
 | 
						    goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	data = malloc(strlen(t));
 | 
						data = malloc(strlen(t));
 | 
				
			||||||
 | 
						if (data == NULL) {
 | 
				
			||||||
 | 
						    kdc_log(0, "Failed to allocate %u bytes", strlen(t));
 | 
				
			||||||
 | 
						    goto out;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	len = base64_decode(t, data);
 | 
						len = base64_decode(t, data);
 | 
				
			||||||
	if(len < 0){
 | 
						if(len < 0){
 | 
				
			||||||
	    const char *msg = 
 | 
						    const char *msg = 
 | 
				
			||||||
@@ -462,7 +474,7 @@ handle_tcp(struct descr *d, int index, int min_free)
 | 
				
			|||||||
	    free(data);
 | 
						    free(data);
 | 
				
			||||||
	    clear_descr(d + index);
 | 
						    clear_descr(d + index);
 | 
				
			||||||
	    kdc_log(0, "HTTP request from %s is non KDC request", addr);
 | 
						    kdc_log(0, "HTTP request from %s is non KDC request", addr);
 | 
				
			||||||
	    return;
 | 
						    goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	    const char *msg = 
 | 
						    const char *msg = 
 | 
				
			||||||
@@ -479,13 +491,14 @@ handle_tcp(struct descr *d, int index, int min_free)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    if(n == 0){
 | 
					    if(n == 0){
 | 
				
			||||||
	do_request(d[index].buf, d[index].len, 
 | 
						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);
 | 
						clear_descr(d + index);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
					    free (sa_buf);
 | 
				
			||||||
 | 
					    return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void
 | 
					void
 | 
				
			||||||
loop(void)
 | 
					loop(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -132,81 +132,55 @@ krb5_auth_con_setaddrs(krb5_context context,
 | 
				
			|||||||
    return 0;
 | 
					    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_error_code
 | 
				
			||||||
krb5_auth_con_setaddrs_from_fd (krb5_context context,
 | 
					krb5_auth_con_setaddrs_from_fd (krb5_context context,
 | 
				
			||||||
				krb5_auth_context auth_context,
 | 
									krb5_auth_context auth_context,
 | 
				
			||||||
				int fd)
 | 
									int fd)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    krb5_address *lptr = NULL, *rptr = NULL;
 | 
					    krb5_error_code ret;
 | 
				
			||||||
    krb5_address local_k_address, remote_k_address;
 | 
					    krb5_address local_k_address, remote_k_address;
 | 
				
			||||||
#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6)
 | 
					    krb5_address *lptr = NULL, *rptr = NULL;
 | 
				
			||||||
    struct sockaddr_in6 local_addr, remote_addr;
 | 
					    size_t max_sz = krb5_max_sockaddr_size ();
 | 
				
			||||||
#else
 | 
					    char *buf1 = NULL, *buf2 = NULL;
 | 
				
			||||||
    struct sockaddr_in local_addr, remote_addr;
 | 
					    struct sockaddr *local, *remote;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    int len;
 | 
					    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) {
 | 
					    if (auth_context->local_address == NULL) {
 | 
				
			||||||
	len = sizeof (local_addr);
 | 
						len = max_sz;
 | 
				
			||||||
	if (getsockname (fd, (struct sockaddr *)&local_addr, &len) < 0)
 | 
						if(getsockname(fd, local, &len) < 0)
 | 
				
			||||||
	    return errno;
 | 
						    goto out;
 | 
				
			||||||
	sockaddr2krb5_address((struct sockaddr *)&local_addr,
 | 
						krb5_sockaddr2address (local, &local_k_address);
 | 
				
			||||||
			      &local_k_address);
 | 
					 | 
				
			||||||
	lptr = &local_k_address;
 | 
						lptr = &local_k_address;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (auth_context->remote_address == NULL) {
 | 
					    if (auth_context->remote_address == NULL) {
 | 
				
			||||||
	len = sizeof (remote_addr);
 | 
						len = max_sz;
 | 
				
			||||||
	if (getpeername (fd, (struct sockaddr *)&remote_addr, &len) < 0)
 | 
						if(getpeername(fd, remote, &len) < 0)
 | 
				
			||||||
	    return errno;
 | 
						    goto out;
 | 
				
			||||||
	sockaddr2krb5_address((struct sockaddr *)&remote_addr,
 | 
						krb5_sockaddr2address (remote, &remote_k_address);
 | 
				
			||||||
			      &remote_k_address);
 | 
					 | 
				
			||||||
	rptr = &remote_k_address;
 | 
						rptr = &remote_k_address;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    ret = krb5_auth_con_setaddrs (context,
 | 
				
			||||||
    return krb5_auth_con_setaddrs (context,
 | 
					 | 
				
			||||||
				  auth_context,
 | 
									  auth_context,
 | 
				
			||||||
				  lptr,
 | 
									  lptr,
 | 
				
			||||||
				  rptr);
 | 
									  rptr);
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
					    free (buf1);
 | 
				
			||||||
 | 
					    free (buf2);
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
krb5_error_code
 | 
					krb5_error_code
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -174,52 +174,13 @@ find_all_addresses (krb5_addresses *res, int loop,
 | 
				
			|||||||
	    || memcmp (sa, &sa_zero, sizeof(sa_zero)) == 0)
 | 
						    || memcmp (sa, &sa_zero, sizeof(sa_zero)) == 0)
 | 
				
			||||||
	     continue;
 | 
						     continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	 switch (sa->sa_family) {
 | 
						 if (krb5_sockaddr_uninteresting (sa))
 | 
				
			||||||
#ifdef AF_INET
 | 
						     continue;
 | 
				
			||||||
	 case AF_INET: {
 | 
					
 | 
				
			||||||
	     unsigned char addr[4];
 | 
						 ret = krb5_sockaddr2address (sa, &res->val[j]);
 | 
				
			||||||
	     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)
 | 
						 if (ret)
 | 
				
			||||||
	     goto error_out;
 | 
						     goto error_out;
 | 
				
			||||||
	 ++j;
 | 
						 ++j;
 | 
				
			||||||
	     break;
 | 
					 | 
				
			||||||
	 }
 | 
					 | 
				
			||||||
#endif /* AF_INET */
 | 
					 | 
				
			||||||
#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6)
 | 
					 | 
				
			||||||
	 case AF_INET6: {
 | 
					 | 
				
			||||||
	     struct in6_addr *sin6;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	     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;
 | 
					 | 
				
			||||||
	 }
 | 
					 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
     if (j != num) {
 | 
					     if (j != num) {
 | 
				
			||||||
	 void *tmp;
 | 
						 void *tmp;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -138,26 +138,36 @@ krb5_sendto_kdc (krb5_context context,
 | 
				
			|||||||
		 const krb5_realm *realm,
 | 
							 const krb5_realm *realm,
 | 
				
			||||||
		 krb5_data *receive)
 | 
							 krb5_data *receive)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
     krb5_error_code err;
 | 
					     krb5_error_code ret;
 | 
				
			||||||
     char **hostlist, **hp, *p;
 | 
					     char **hostlist, **hp, *p;
 | 
				
			||||||
     struct hostent *hostent;
 | 
					     struct hostent *hostent;
 | 
				
			||||||
     int fd;
 | 
					     int fd;
 | 
				
			||||||
     int port;
 | 
					     int port;
 | 
				
			||||||
     int i;
 | 
					     int i;
 | 
				
			||||||
 | 
					     char *buf;
 | 
				
			||||||
 | 
					     struct sockaddr *sa;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     port = krb5_getportbyname (context, "kerberos", "udp", 88);
 | 
					     port = krb5_getportbyname (context, "kerberos", "udp", 88);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     err = krb5_get_krbhst (context, realm, &hostlist);
 | 
					     ret = krb5_get_krbhst (context, realm, &hostlist);
 | 
				
			||||||
     if (err) {
 | 
					     if (ret) {
 | 
				
			||||||
	  close (fd);
 | 
						  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 (i = 0; i < context->max_retries; ++i)
 | 
				
			||||||
	 for (hp = hostlist; (p = *hp); ++hp) {
 | 
						 for (hp = hostlist; (p = *hp); ++hp) {
 | 
				
			||||||
	     char *addr;
 | 
						     char *addr;
 | 
				
			||||||
	     char *colon;
 | 
						     char *colon;
 | 
				
			||||||
	     int http_flag = 0;
 | 
						     int http_flag = 0;
 | 
				
			||||||
 | 
						     int sa_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	     if(strncmp(p, "http://", 7) == 0){
 | 
						     if(strncmp(p, "http://", 7) == 0){
 | 
				
			||||||
		 p += 7;
 | 
							 p += 7;
 | 
				
			||||||
@@ -178,46 +188,24 @@ krb5_sendto_kdc (krb5_context context,
 | 
				
			|||||||
	     if (colon)
 | 
						     if (colon)
 | 
				
			||||||
		 *colon++ = ':';
 | 
							 *colon++ = ':';
 | 
				
			||||||
	     while ((addr = *hostent->h_addr_list++)) {
 | 
						     while ((addr = *hostent->h_addr_list++)) {
 | 
				
			||||||
		 int ret;
 | 
							 int family = hostent->h_addrtype;
 | 
				
			||||||
		 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;
 | 
					 | 
				
			||||||
		    
 | 
							    
 | 
				
			||||||
		 if(http_flag)
 | 
							 if(http_flag)
 | 
				
			||||||
		     fd = socket(family, SOCK_STREAM, 0);
 | 
							     fd = socket(family, SOCK_STREAM, 0);
 | 
				
			||||||
		 else
 | 
							 else
 | 
				
			||||||
		     fd = socket(family, SOCK_DGRAM, 0);
 | 
							     fd = socket(family, SOCK_DGRAM, 0);
 | 
				
			||||||
		    
 | 
							    
 | 
				
			||||||
		 if(fd < 0)
 | 
							 if(fd < 0) {
 | 
				
			||||||
		     return errno;
 | 
							     ret = errno;
 | 
				
			||||||
		 switch (family) {
 | 
							     goto out;
 | 
				
			||||||
		 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;
 | 
					 | 
				
			||||||
		 }
 | 
							 }
 | 
				
			||||||
 | 
							 ret = krb5_h_addr2sockaddr (family,
 | 
				
			||||||
 | 
										     addr,
 | 
				
			||||||
 | 
										     sa,
 | 
				
			||||||
 | 
										     &sa_size,
 | 
				
			||||||
 | 
										     init_port(colon, port));
 | 
				
			||||||
 | 
							 if (ret)
 | 
				
			||||||
 | 
							     continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		 if(connect(fd, sa, sa_size) < 0) {
 | 
							 if(connect(fd, sa, sa_size) < 0) {
 | 
				
			||||||
		     close (fd);
 | 
							     close (fd);
 | 
				
			||||||
@@ -232,12 +220,13 @@ krb5_sendto_kdc (krb5_context context,
 | 
				
			|||||||
		     ret = send_and_recv (fd, context->kdc_timeout, 1,
 | 
							     ret = send_and_recv (fd, context->kdc_timeout, 1,
 | 
				
			||||||
					  send, receive);
 | 
										  send, receive);
 | 
				
			||||||
		 close (fd);
 | 
							 close (fd);
 | 
				
			||||||
		 if(ret == 0){
 | 
							 if(ret == 0)
 | 
				
			||||||
 | 
							     goto out;
 | 
				
			||||||
 | 
						     }
 | 
				
			||||||
 | 
						 }
 | 
				
			||||||
 | 
					     ret = KRB5_KDC_UNREACH;
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
     krb5_free_krbhst (context, hostlist);
 | 
					     krb5_free_krbhst (context, hostlist);
 | 
				
			||||||
		     return 0;
 | 
					     free (buf);
 | 
				
			||||||
		 }
 | 
					     return ret;
 | 
				
			||||||
	     }
 | 
					 | 
				
			||||||
	 }
 | 
					 | 
				
			||||||
     krb5_free_krbhst (context, hostlist);
 | 
					 | 
				
			||||||
     return KRB5_KDC_UNREACH;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,34 +48,31 @@ krb5_sock_to_principal (krb5_context context,
 | 
				
			|||||||
			krb5_principal *ret_princ)
 | 
								krb5_principal *ret_princ)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    krb5_error_code ret;
 | 
					    krb5_error_code ret;
 | 
				
			||||||
#if defined(AF_INET6) && defined(HAVE_SOCKADDR_IN6)
 | 
					    krb5_address address;
 | 
				
			||||||
    struct sockaddr_in6 addr;
 | 
					    int len = krb5_max_sockaddr_size ();
 | 
				
			||||||
#else
 | 
					    char *buf = malloc(len);
 | 
				
			||||||
    struct sockaddr_in addr;
 | 
					    struct sockaddr *sa;
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    int len = sizeof(addr);
 | 
					 | 
				
			||||||
    struct hostent *hostent;
 | 
					    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;
 | 
						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
 | 
					    family = sa->sa_family;
 | 
				
			||||||
    hostent = gethostbyaddr ((const char *)&addr.sin_addr,
 | 
					    
 | 
				
			||||||
			     sizeof(addr.sin_addr),
 | 
					    ret = krb5_sockaddr2address (sa, &address);
 | 
				
			||||||
			     addr.sin_family);
 | 
					    free (buf);
 | 
				
			||||||
#endif
 | 
					    if (ret)
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hostent = gethostbyaddr (address.address.data,
 | 
				
			||||||
 | 
								     address.address.length,
 | 
				
			||||||
 | 
								     family);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (hostent == NULL)
 | 
					    if (hostent == NULL)
 | 
				
			||||||
	return h_errno;
 | 
						return h_errno;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user