*/
/*
- * $Id: bsdtcp-security.c,v 1.7.2.2 2006/09/29 11:28:55 martinea Exp $
+ * $Id: bsdtcp-security.c,v 1.7 2006/07/13 03:22:20 paddy_s Exp $
*
* bsdtcp-security.c - security and transport over bsdtcp or a bsdtcp-like command.
*
#ifdef BSDTCP_SECURITY
-/*#define BSDTCP_DEBUG*/
-
-#ifdef BSDTCP_DEBUG
-#define bsdtcpprintf(x) dbprintf(x)
-#else
-#define bsdtcpprintf(x)
-#endif
-
-
/*
* Number of seconds bsdtcp has to start up
*/
tcpm_stream_read_sync,
tcpm_stream_read_cancel,
tcpm_close_connection,
+ NULL,
+ NULL
};
static int newhandle = 1;
void * datap)
{
struct sec_handle *rh;
- struct hostent *he;
+ int result;
+ struct addrinfo hints;
+ struct addrinfo *res = NULL;
assert(fn != NULL);
assert(hostname != NULL);
(void)conf_fn; /* Quiet unused parameter warning */
(void)datap; /* Quiet unused parameter warning */
- bsdtcpprintf(("%s: bsdtcp: bsdtcp_connect: %s\n", debug_prefix_time(NULL),
- hostname));
+ auth_debug(1, ("%s: bsdtcp: bsdtcp_connect: %s\n", debug_prefix_time(NULL),
+ hostname));
rh = alloc(sizeof(*rh));
security_handleinit(&rh->sech, &bsdtcp_security_driver);
rh->ev_timeout = NULL;
rh->rc = NULL;
- if ((he = gethostbyname(hostname)) == NULL) {
- security_seterror(&rh->sech,
- "%s: could not resolve hostname", hostname);
+#ifdef WORKING_IPV6
+ hints.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ALL;
+ hints.ai_family = AF_UNSPEC;
+#else
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_INET;
+#endif
+ hints.ai_socktype = SOCK_DGRAM;
+ hints.ai_protocol = IPPROTO_UDP;
+ hints.ai_addrlen = 0;
+ hints.ai_addr = NULL;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ result = getaddrinfo(hostname, NULL, &hints, &res);
+#ifdef WORKING_IPV6
+ if (result != 0) {
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = AF_UNSPEC;
+ result = getaddrinfo(hostname, NULL, &hints, &res);
+ }
+#endif
+ if(result != 0) {
+ dbprintf(("getaddrinfo(%s): %s\n", hostname, gai_strerror(result)));
+ security_seterror(&rh->sech, "getaddrinfo(%s): %s\n", hostname,
+ gai_strerror(result));
(*fn)(arg, &rh->sech, S_ERROR);
return;
}
- rh->hostname = stralloc(he->h_name); /* will be replaced */
+ if (res->ai_canonname == NULL) {
+ dbprintf(("getaddrinfo(%s) did not return a canonical name\n", hostname));
+ security_seterror(&rh->sech,
+ _("getaddrinfo(%s) did not return a canonical name\n"), hostname);
+ (*fn)(arg, &rh->sech, S_ERROR);
+ return;
+ }
+
+ rh->hostname = stralloc(res->ai_canonname); /* will be replaced */
rh->rs = tcpma_stream_client(rh, newhandle++);
rh->rc->recv_security_ok = &bsd_recv_security_ok;
rh->rc->prefix_packet = &bsd_prefix_packet;
rh->ev_timeout = event_register(CONNECT_TIMEOUT, EV_TIME,
sec_connect_timeout, rh);
+ freeaddrinfo(res);
return;
error:
(*fn)(arg, &rh->sech, S_ERROR);
+ freeaddrinfo(res);
}
/*
int out,
void (*fn)(security_handle_t *, pkt_t *))
{
- struct sockaddr_in sin;
+ struct sockaddr_storage sin;
socklen_t len;
struct tcp_conn *rc;
- struct hostent *he;
+ char hostname[NI_MAXHOST];
+ int result;
+ char *errmsg = NULL;
len = sizeof(sin);
if (getpeername(in, (struct sockaddr *)&sin, &len) < 0) {
strerror(errno)));
return;
}
- he = gethostbyaddr((void *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET);
- if (he == NULL) {
- dbprintf(("%s: he returned NULL: h_errno = %d\n",
- debug_prefix_time(NULL), h_errno));
+ if ((result = getnameinfo((struct sockaddr *)&sin, len,
+ hostname, NI_MAXHOST, NULL, 0, 0) != 0)) {
+ dbprintf(("%s: getnameinfo failed: %s\n",
+ debug_prefix_time(NULL), gai_strerror(result)));
+ return;
+ }
+ if (check_name_give_sockaddr(hostname,
+ (struct sockaddr *)&sin, &errmsg) < 0) {
+ amfree(errmsg);
return;
}
- rc = sec_tcp_conn_get(he->h_name, 0);
+ rc = sec_tcp_conn_get(hostname, 0);
rc->recv_security_ok = &bsd_recv_security_ok;
rc->prefix_packet = &bsd_prefix_packet;
- memcpy(&rc->peer.sin_addr, he->h_addr, sizeof(rc->peer.sin_addr));
- rc->peer.sin_port = sin.sin_port;
+ memcpy(&rc->peer, &sin, sizeof(rc->peer));
rc->read = in;
rc->write = out;
rc->accept_fn = fn;