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:
137
kdc/connect.c
137
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];
|
|
||||||
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;
|
|
||||||
|
|
||||||
sin6 = &((struct sockaddr_in6 *)(&ifr->ifr_addr))->sin6_addr;
|
ret = krb5_sockaddr2address (sa, &res->val[j]);
|
||||||
|
if (ret)
|
||||||
#ifndef IN6_IS_ADDR_LOOPBACK
|
goto error_out;
|
||||||
#define IN6_IS_ADDR_LOOPBACK(x) IN6_IS_LOOPBACK(*x)
|
++j;
|
||||||
#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)
|
||||||
krb5_free_krbhst (context, hostlist);
|
goto out;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ret = KRB5_KDC_UNREACH;
|
||||||
|
out:
|
||||||
krb5_free_krbhst (context, hostlist);
|
krb5_free_krbhst (context, hostlist);
|
||||||
return KRB5_KDC_UNREACH;
|
free (buf);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
@@ -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