#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)
+ if (getpeername(in, (struct sockaddr *)&sin, &len) < 0) {
+ dbprintf(("%s: getpeername returned: %s\n", debug_prefix_time(NULL),
+ strerror(errno)));
return;
- he = gethostbyaddr((void *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET);
- if (he == NULL)
+ }
+ 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;
uid_t euid;
struct tcp_conn * rc = rh->rc;
- if ((sp = getservbyname("amanda", "tcp")) == NULL) {
+ if ((sp = getservbyname(AMANDA_SERVICE_NAME, "tcp")) == NULL) {
error("%s/tcp unknown protocol", "amanda");
}