*/
/*
- * $Id: security-util.c,v 1.25.2.10 2007/01/24 00:35:14 martinea Exp $
+ * $Id: security-util.c,v 1.25 2006/07/22 12:04:47 martinea Exp $
*
* sec-security.c - security and transport over sec or a sec-like command.
*
#include "stream.h"
#include "version.h"
-/* #define SEC_DEBUG */
-#define SHOW_SECURITY_DETAIL
-
-#ifdef SEC_DEBUG
-# define secprintf(x) dbprintf(x)
-#else
-# ifdef __lint
-# define secprintf(x) (void)(x)
-# else
-# define secprintf(x)
-# endif
-#endif
-
/*
* Magic values for sec_conn->handle
*/
assert(rh != NULL);
- secprintf(("%s: sec: closing handle to %s\n", debug_prefix_time(NULL),
- rh->hostname));
+ auth_debug(1, ("%s: sec: closing handle to %s\n", debug_prefix_time(NULL),
+ rh->hostname));
if (rh->rs != NULL) {
/* This may be null if we get here on an error */
assert(rh != NULL);
assert(pkt != NULL);
- secprintf(("%s: sec: stream_sendpkt: enter\n", debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec: stream_sendpkt: enter\n",
+ debug_prefix_time(NULL)));
if (rh->rc->prefix_packet)
s = rh->rc->prefix_packet(rh, pkt);
if (strlen(s) > 0)
amfree(s);
- secprintf((
- "%s: sec: stream_sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n",
- debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->type,
- strlen(pkt->body), pkt->body));
+ auth_debug(1,
+ ("%s: sec: stream_sendpkt: %s (%d) pkt_t (len " SIZE_T_FMT ") contains:\n\n\"%s\"\n\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->type,
+ strlen(pkt->body), pkt->body));
if (security_stream_write(&rh->rs->secstr, buf, len) < 0) {
security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
assert(rh != NULL);
- secprintf(("%s: sec: recvpkt registered for %s\n",
- debug_prefix_time(NULL), rh->hostname));
+ auth_debug(1, ("%s: sec: recvpkt registered for %s\n",
+ debug_prefix_time(NULL), rh->hostname));
/*
* Reset any pending timeout on this handle
assert(rh != NULL);
- secprintf(("%s: sec: recvpkt timeout for %s\n",
- debug_prefix_time(NULL), rh->hostname));
+ auth_debug(1, ("%s: sec: recvpkt timeout for %s\n",
+ debug_prefix_time(NULL), rh->hostname));
stream_recvpkt_cancel(rh);
(*rh->fn.recvpkt)(rh->arg, NULL, S_TIMEOUT);
{
struct sec_handle *rh = cookie;
- secprintf(("%s: sec: cancelling recvpkt for %s\n",
- debug_prefix_time(NULL), rh->hostname));
+ auth_debug(1, ("%s: sec: cancelling recvpkt for %s\n",
+ debug_prefix_time(NULL), rh->hostname));
assert(rh != NULL);
assert(rs != NULL);
assert(rs->rc != NULL);
- secprintf(("%s: sec: stream_write: writing %d bytes to %s:%d %d\n",
- debug_prefix_time(NULL), size, rs->rc->hostname, rs->handle,
- rs->rc->write));
+ auth_debug(1, ("%s: sec: stream_write: writing " SIZE_T_FMT " bytes to %s:%d %d\n",
+ debug_prefix_time(NULL), size, rs->rc->hostname, rs->handle,
+ rs->rc->write));
- if (tcpm_send_token(rs->rc->write, rs->handle, &rs->rc->errmsg,
+ if (tcpm_send_token(rs->rc, rs->rc->write, rs->handle, &rs->rc->errmsg,
buf, size)) {
security_stream_seterror(&rs->secstr, rs->rc->errmsg);
return (-1);
*/
ssize_t
tcpm_send_token(
+ struct tcp_conn *rc,
int fd,
int handle,
char ** errmsg,
uint32_t netlength;
struct iovec iov[3];
int nb_iov = 3;
+ int rval;
+ char *encbuf;
+ ssize_t encsize;
assert(SIZEOF(netlength) == 4);
+ auth_debug(1, ("%s: tcpm_send_token: write %zd bytes to handle %d\n",
+ debug_prefix_time(NULL), len, handle));
/*
* Format is:
* 32 bit length (network byte order)
iov[1].iov_base = (void *)&nethandle;
iov[1].iov_len = SIZEOF(nethandle);
+ encbuf = (char *)buf;
+ encsize = len;
+
if(len == 0) {
nb_iov = 2;
}
else {
- iov[2].iov_base = (void *)buf;
- iov[2].iov_len = len;
+ if (rc->driver->data_encrypt == NULL) {
+ iov[2].iov_base = (void *)buf;
+ iov[2].iov_len = len;
+ } else {
+ /* (the extra (void *) cast is to quiet type-punning warnings) */
+ rc->driver->data_encrypt(rc, (void *)buf, len, (void **)(void *)&encbuf, &encsize);
+ iov[2].iov_base = (void *)encbuf;
+ iov[2].iov_len = encsize;
+ netlength = htonl(encsize);
+ }
nb_iov = 3;
}
- if (net_writev(fd, iov, nb_iov) < 0) {
+ rval = net_writev(fd, iov, nb_iov);
+ if (len != 0 && rc->driver->data_encrypt != NULL && buf != encbuf) {
+ amfree(encbuf);
+ }
+
+ if (rval < 0) {
if (errmsg)
*errmsg = newvstralloc(*errmsg, "write error to ",
": ", strerror(errno), NULL);
ssize_t
tcpm_recv_token(
+ struct tcp_conn *rc,
int fd,
int * handle,
char ** errmsg,
if (errmsg)
*errmsg = newvstralloc(*errmsg, "recv error: ", strerror(errno),
NULL);
- secprintf(("%s: tcpm_recv_token: A return(-1)\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: tcpm_recv_token: A return(-1)\n",
+ debug_prefix_time(NULL)));
return (-1);
case 0:
*size = 0;
*handle = H_EOF;
*errmsg = newvstralloc(*errmsg, "SOCKET_EOF", NULL);
- secprintf(("%s: tcpm_recv_token: A return(0)\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: tcpm_recv_token: A return(0)\n",
+ debug_prefix_time(NULL)));
return (0);
default:
break;
*handle = (int)ntohl(netint[1]);
/* amanda protocol packet can be above NETWORK_BLOCK_BYTES */
if (*size > 128*NETWORK_BLOCK_BYTES || *size < 0) {
- if (isprint((*size ) & 0xFF) &&
- isprint((*size >> 8 ) & 0xFF) &&
- isprint((*size >> 16) & 0xFF) &&
- isprint((*size >> 24) & 0xFF) &&
+ if (isprint((int)(*size ) & 0xFF) &&
+ isprint((int)(*size >> 8 ) & 0xFF) &&
+ isprint((int)(*size >> 16) & 0xFF) &&
+ isprint((int)(*size >> 24) & 0xFF) &&
isprint((*handle ) & 0xFF) &&
isprint((*handle >> 8 ) & 0xFF) &&
isprint((*handle >> 16) & 0xFF) &&
isprint((*handle >> 24) & 0xFF)) {
char s[101];
int i;
- s[0] = (*size >> 24) & 0xFF;
- s[1] = (*size >> 16) & 0xFF;
- s[2] = (*size >> 8) & 0xFF;
- s[3] = (*size ) & 0xFF;
+ s[0] = ((int)(*size) >> 24) & 0xFF;
+ s[1] = ((int)(*size) >> 16) & 0xFF;
+ s[2] = ((int)(*size) >> 8) & 0xFF;
+ s[3] = ((int)(*size) ) & 0xFF;
s[4] = (*handle >> 24) & 0xFF;
s[5] = (*handle >> 16) & 0xFF;
s[6] = (*handle >> 8 ) & 0xFF;
} else {
*errmsg = newvstralloc(*errmsg, "tcpm_recv_token: invalid size",
NULL);
- dbprintf(("%s: tcpm_recv_token: invalid size %zd\n",
+ dbprintf(("%s: tcpm_recv_token: invalid size " SSIZE_T_FMT "\n",
debug_prefix_time(NULL), *size));
}
*size = -1;
*buf = alloc((size_t)*size);
if(*size == 0) {
- secprintf(("%s: tcpm_recv_token: read EOF from %d\n",
- debug_prefix_time(NULL), *handle));
+ auth_debug(1, ("%s: tcpm_recv_token: read EOF from %d\n",
+ debug_prefix_time(NULL), *handle));
*errmsg = newvstralloc(*errmsg, "EOF",
NULL);
return 0;
if (errmsg)
*errmsg = newvstralloc(*errmsg, "recv error: ", strerror(errno),
NULL);
- secprintf(("%s: tcpm_recv_token: B return(-1)\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: tcpm_recv_token: B return(-1)\n",
+ debug_prefix_time(NULL)));
return (-1);
case 0:
*size = 0;
*errmsg = newvstralloc(*errmsg, "SOCKET_EOF", NULL);
- secprintf(("%s: tcpm_recv_token: B return(0)\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: tcpm_recv_token: B return(0)\n",
+ debug_prefix_time(NULL)));
return (0);
default:
break;
}
- secprintf(("%s: tcpm_recv_token: read %zd bytes from %d\n",
- debug_prefix_time(NULL), *size, *handle));
+ auth_debug(1, ("%s: tcpm_recv_token: read " SSIZE_T_FMT " bytes from %d\n",
+ debug_prefix_time(NULL), *size, *handle));
+
+ if (*size > 0 && rc->driver->data_decrypt != NULL) {
+ char *decbuf;
+ ssize_t decsize;
+ /* (the extra (void *) cast is to quiet type-punning warnings) */
+ rc->driver->data_decrypt(rc, *buf, *size, (void **)(void *)&decbuf, &decsize);
+ if (*buf != decbuf) {
+ amfree(*buf);
+ *buf = decbuf;
+ }
+ *size = decsize;
+ }
+
return((*size));
}
{
struct sec_handle *rh = h;
- hostname = hostname;
+ (void)hostname;
- if(rh->rc->toclose == 0) {
+ if (rh && rh->rc && rh->rc->toclose == 0) {
rh->rc->toclose = 1;
sec_tcp_conn_put(rh->rc);
}
rh->rc = rs->rc;
}
- secprintf(("%s: sec: stream_client: connected to stream %d\n",
- debug_prefix_time(NULL), id));
+ auth_debug(1, ("%s: sec: stream_client: connected to stream %d\n",
+ debug_prefix_time(NULL), id));
return (rs);
}
*/
rs->handle = 500000 - newhandle++;
rs->ev_read = NULL;
- secprintf(("%s: sec: stream_server: created stream %d\n",
- debug_prefix_time(NULL), rs->handle));
+ auth_debug(1, ("%s: sec: stream_server: created stream %d\n",
+ debug_prefix_time(NULL), rs->handle));
return (rs);
}
assert(rs != NULL);
- secprintf(("%s: sec: tcpma_stream_close: closing stream %d\n",
- debug_prefix_time(NULL), rs->handle));
+ auth_debug(1, ("%s: sec: tcpma_stream_close: closing stream %d\n",
+ debug_prefix_time(NULL), rs->handle));
if(rs->closed_by_network == 0 && rs->rc->write != -1)
tcpm_stream_write(rs, &buf, 0);
}
else {
rh->rc = sec_tcp_conn_get(rh->hostname, 1);
+ rh->rc->driver = rh->sech.driver;
rs->rc = rh->rc;
rh->rc->read = stream_client(rh->hostname, (in_port_t)id,
STREAM_BUFSIZE, STREAM_BUFSIZE, &rs->port, 0);
char *tok, *security, *body, *result;
char *service = NULL, *serviceX, *serviceY;
char *security_line;
+ char *s, ch;
size_t len;
+ in_port_t port;
/*
* Now, find the SECURITY line in the body, and parse it out
* into an argv.
*/
- if (strncmp(pkt->body, "SECURITY ", SIZEOF("SECURITY ") - 1) == 0) {
+ if (strncmp_const(pkt->body, "SECURITY ") == 0) {
security = pkt->body;
len = 0;
while(*security != '\n' && len < pkt->size) {
* Now, find the SERVICE line in the body, and parse it out
* into an argv.
*/
- if (strncmp(body, "SERVICE", SIZEOF("SERVICE") - 1) == 0) {
- serviceX = stralloc(body + strlen("SERVICE "));
+ s = body;
+ if (strncmp_const_skip(s, "SERVICE ", s, ch) == 0) {
+ serviceX = stralloc(s);
serviceY = strtok(serviceX, "\n");
if (serviceY)
service = stralloc(serviceY);
/*
* Request packets must come from a reserved port
*/
- if (ntohs(rh->peer.sin_port) >= IPPORT_RESERVED) {
+ port = SS_GET_PORT(&rh->peer);
+ if (port >= IPPORT_RESERVED) {
security_seterror(&rh->sech,
- "host %s: port %d not secure", rh->hostname,
- ntohs(rh->peer.sin_port));
+ "host %s: port %u not secure", rh->hostname,
+ (unsigned int)port);
amfree(service);
amfree(security_line);
return (-1);
assert(rh != NULL);
assert(pkt != NULL);
- secprintf(("%s: udpbsd_sendpkt: enter\n", get_pname()));
+ auth_debug(1, ("%s: udpbsd_sendpkt: enter\n", get_pname()));
/*
* Initialize this datagram, and add the header
*/
*/
dgram_cat(&rh->udp->dgram, pkt->body);
- secprintf((
- "%s: sec: udpbsd_sendpkt: %s (%d) pkt_t (len %d) contains:\n\n\"%s\"\n\n",
- debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->type,
- strlen(pkt->body), pkt->body));
+ auth_debug(1,
+ ("%s: sec: udpbsd_sendpkt: %s (%d) pkt_t (len " SIZE_T_FMT ") contains:\n\n\"%s\"\n\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type), pkt->type,
+ strlen(pkt->body), pkt->body));
- if (dgram_send_addr(rh->peer, &rh->udp->dgram) != 0) {
+ if (dgram_send_addr(&rh->peer, &rh->udp->dgram) != 0) {
security_seterror(&rh->sech,
"send %s to %s failed: %s", pkt_type2str(pkt->type),
rh->hostname, strerror(errno));
return;
}
- secprintf(("%s: udp: close handle '%s'\n",
- debug_prefix_time(NULL), rh->proto_handle));
+ auth_debug(1, ("%s: udp: close handle '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle));
udp_recvpkt_cancel(rh);
if (rh->next) {
{
struct sec_handle *rh = cookie;
- secprintf(("%s: udp_recvpkt(cookie=%p, fn=%p, arg=%p, timeout=%u)\n",
- debug_prefix(NULL), cookie, fn, arg, timeout));
+ auth_debug(1, ("%s: udp_recvpkt(cookie=%p, fn=%p, arg=%p, timeout=%u)\n",
+ debug_prefix_time(NULL), cookie, fn, arg, timeout));
assert(rh != NULL);
assert(fn != NULL);
void (*fn)(void *, pkt_t *, security_status_t);
void *arg;
- secprintf(("%s: udp: receive handle '%s' netfd '%s'\n",
- debug_prefix_time(NULL), rh->proto_handle, rh->udp->handle));
+ auth_debug(1, ("%s: udp: receive handle '%s' netfd '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle, rh->udp->handle));
assert(rh != NULL);
- if (strcmp(rh->proto_handle, rh->udp->handle) != 0) assert(1);
+ /* if it doesn't correspond to this handle, something is wrong */
+ assert(strcmp(rh->proto_handle, rh->udp->handle) == 0);
+
/* if it didn't come from the same host/port, forget it */
- if (memcmp(&rh->peer.sin_addr, &rh->udp->peer.sin_addr,
- SIZEOF(rh->udp->peer.sin_addr)) != 0 ||
- rh->peer.sin_port != rh->udp->peer.sin_port) {
+ if (cmp_sockaddr(&rh->peer, &rh->udp->peer, 0) != 0) {
amfree(rh->udp->handle);
+ dbprintf(("not form same host\n"));
+ dump_sockaddr(&rh->peer);
+ dump_sockaddr(&rh->udp->peer);
return;
}
* to the packet handling function instead of a packet.
*/
if (rh->udp->recv_security_ok &&
- rh->udp->recv_security_ok(rh, &rh->udp->pkt) < 0)
+ rh->udp->recv_security_ok(rh, &rh->udp->pkt) < 0) {
(*fn)(arg, NULL, S_ERROR);
- else
+ } else {
(*fn)(arg, &rh->udp->pkt, S_OK);
+ }
}
/*
udp_inithandle(
udp_handle_t * udp,
struct sec_handle * rh,
- struct hostent * he,
+ char * hostname,
+ struct sockaddr_storage *addr,
in_port_t port,
char * handle,
int sequence)
{
- int i;
-
/*
* Save the hostname and port info
*/
- secprintf(("%s: udp_inithandle port %u handle %s sequence %d\n",
- debug_prefix_time(NULL), (unsigned int)ntohs(port),
- handle, sequence));
- assert(he != NULL);
-
- rh->hostname = stralloc(he->h_name);
- memcpy(&rh->peer.sin_addr, he->h_addr, SIZEOF(rh->peer.sin_addr));
- rh->peer.sin_port = port;
- rh->peer.sin_family = (sa_family_t)AF_INET;
-
- /*
- * Do a forward lookup of the hostname. This is unnecessary if we
- * are initiating the connection, but is very serious if we are
- * receiving. We want to make sure the hostname
- * resolves back to the remote ip for security reasons.
- */
- if ((he = gethostbyname(rh->hostname)) == NULL) {
- secprintf(("%s: udp: bb\n", debug_prefix_time(NULL)));
- security_seterror(&rh->sech,
- "%s: could not resolve hostname", rh->hostname);
- return (-1);
- }
-
- /*
- * Make sure the hostname matches. This should always work.
- */
- if (strncasecmp(rh->hostname, he->h_name, strlen(rh->hostname)) != 0) {
- secprintf(("%s: udp: cc\n", debug_prefix_time(NULL)));
- security_seterror(&rh->sech,
- "%s: did not resolve to itself, it resolv to %s",
- rh->hostname, he->h_name);
- return (-1);
- }
-
- /*
- * Now look for a matching ip address.
- */
- for (i = 0; he->h_addr_list[i] != NULL; i++) {
- if (memcmp(&rh->peer.sin_addr, he->h_addr_list[i],
- SIZEOF(struct in_addr)) == 0) {
- break;
- }
- }
+ auth_debug(1, ("%s: udp_inithandle port %u handle %s sequence %d\n",
+ debug_prefix_time(NULL), (unsigned int)ntohs(port),
+ handle, sequence));
+ assert(addr != NULL);
- /*
- * If we didn't find it, try the aliases. This is a workaround for
- * Solaris if DNS goes over NIS.
- */
- if (he->h_addr_list[i] == NULL) {
- const char *ipstr = inet_ntoa(rh->peer.sin_addr);
- for (i = 0; he->h_aliases[i] != NULL; i++) {
- if (strcmp(he->h_aliases[i], ipstr) == 0)
- break;
- }
- /*
- * No aliases either. Failure. Someone is fooling with us or
- * DNS is messed up.
- */
- if (he->h_aliases[i] == NULL) {
- security_seterror(&rh->sech,
- "DNS check failed: no matching ip address for %s",
- rh->hostname);
- return (-1);
- }
- }
+ rh->hostname = stralloc(hostname);
+ memcpy(&rh->peer, addr, SIZEOF(rh->peer));
+ SS_SET_PORT(&rh->peer, port);
rh->prev = udp->bh_last;
if (udp->bh_last) {
rh->ev_read = NULL;
rh->ev_timeout = NULL;
- secprintf(("%s: udp: adding handle '%s'\n",
- debug_prefix_time(NULL), rh->proto_handle));
+ auth_debug(1, ("%s: udp: adding handle '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle));
return(0);
}
{
struct udp_handle *udp = cookie;
struct sec_handle *rh;
- struct hostent *he;
int a;
+ char hostname[NI_MAXHOST];
+ in_port_t port;
+ char *errmsg = NULL;
+ int result;
- secprintf(("%s: udp_netfd_read_callback(cookie=%p)\n",
- debug_prefix(NULL), cookie));
+ auth_debug(1, ("%s: udp_netfd_read_callback(cookie=%p)\n",
+ debug_prefix_time(NULL), cookie));
assert(udp != NULL);
#ifndef TEST /* { */
rh = udp->bh_first;
while(rh != NULL && (strcmp(rh->proto_handle, udp->handle) != 0 ||
rh->sequence != udp->sequence ||
- rh->peer.sin_addr.s_addr != udp->peer.sin_addr.s_addr ||
- rh->peer.sin_port != udp->peer.sin_port)) {
+ cmp_sockaddr(&rh->peer, &udp->peer, 0) != 0)) {
rh = rh->next;
}
if (rh && event_wakeup(rh->event_id) > 0)
* If we didn't find a handle, then check for a new incoming packet.
* If no accept handler was setup, then just return.
*/
- if (udp->accept_fn == NULL)
+ if (udp->accept_fn == NULL) {
+ dbprintf(("%s: Receive packet from unknown source", debug_prefix_time(NULL)));
return;
+ }
- he = gethostbyaddr((void *)&udp->peer.sin_addr,
- (socklen_t)sizeof(udp->peer.sin_addr), AF_INET);
- if (he == NULL)
- return;
rh = alloc(SIZEOF(*rh));
rh->proto_handle=NULL;
rh->udp = udp;
rh->rc = NULL;
security_handleinit(&rh->sech, udp->driver);
+
+ result = getnameinfo((struct sockaddr *)&udp->peer, SS_LEN(&udp->peer),
+ hostname, sizeof(hostname), NULL, 0, 0);
+ if (result != 0) {
+ dbprintf(("%s: getnameinfo failed: %s\n",
+ debug_prefix_time(NULL), gai_strerror(result)));
+ security_seterror(&rh->sech, "getnameinfo failed: %s",
+ gai_strerror(result));
+ return;
+ }
+ if (check_name_give_sockaddr(hostname,
+ (struct sockaddr *)&udp->peer, &errmsg) < 0) {
+ security_seterror(&rh->sech, "%s",errmsg);
+ amfree(errmsg);
+ amfree(rh);
+ return;
+ }
+
+ port = SS_GET_PORT(&udp->peer);
a = udp_inithandle(udp, rh,
- he,
- udp->peer.sin_port,
+ hostname,
+ &udp->peer,
+ port,
udp->handle,
udp->sequence);
if (a < 0) {
- secprintf(("%s: bsd: closeX handle '%s'\n",
- debug_prefix_time(NULL), rh->proto_handle));
+ auth_debug(1, ("%s: bsd: closeX handle '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle));
amfree(rh);
return;
{
struct tcp_conn *rc;
- secprintf(("%s: sec_tcp_conn_get: %s\n", debug_prefix_time(NULL), hostname));
+ auth_debug(1, ("%s: sec_tcp_conn_get: %s\n",
+ debug_prefix_time(NULL), hostname));
if (want_new == 0) {
- for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
- if (strcasecmp(hostname, rc->hostname) == 0)
- break;
- }
+ for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
+ if (strcasecmp(hostname, rc->hostname) == 0)
+ break;
+ }
- if (rc != NULL) {
- rc->refcnt++;
- secprintf(("%s: sec_tcp_conn_get: exists, refcnt to %s is now %d\n",
- debug_prefix_time(NULL),
- rc->hostname, rc->refcnt));
- return (rc);
- }
+ if (rc != NULL) {
+ rc->refcnt++;
+ auth_debug(1,
+ ("%s: sec_tcp_conn_get: exists, refcnt to %s is now %d\n",
+ debug_prefix_time(NULL),
+ rc->hostname, rc->refcnt));
+ return (rc);
+ }
}
- secprintf(("%s: sec_tcp_conn_get: creating new handle\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec_tcp_conn_get: creating new handle\n",
+ debug_prefix_time(NULL)));
/*
* We can't be creating a new handle if we are the client
*/
rc->accept_fn = NULL;
rc->recv_security_ok = NULL;
rc->prefix_packet = NULL;
+ rc->auth = 0;
connq_append(rc);
return (rc);
}
assert(rc->refcnt > 0);
--rc->refcnt;
- secprintf(("%s: sec_tcp_conn_put: decrementing refcnt for %s to %d\n",
- debug_prefix_time(NULL),
+ auth_debug(1, ("%s: sec_tcp_conn_put: decrementing refcnt for %s to %d\n",
+ debug_prefix_time(NULL),
rc->hostname, rc->refcnt));
if (rc->refcnt > 0) {
return;
}
- secprintf(("%s: sec_tcp_conn_put: closing connection to %s\n",
- debug_prefix_time(NULL), rc->hostname));
+ auth_debug(1, ("%s: sec_tcp_conn_put: closing connection to %s\n",
+ debug_prefix_time(NULL), rc->hostname));
if (rc->read != -1)
aclose(rc->read);
if (rc->write != -1)
if (rc->ev_read != NULL) {
rc->ev_read_refcnt++;
- secprintf((
- "%s: sec: conn_read: incremented ev_read_refcnt to %d for %s\n",
+ auth_debug(1,
+ ("%s: sec: conn_read: incremented ev_read_refcnt to %d for %s\n",
debug_prefix_time(NULL), rc->ev_read_refcnt, rc->hostname));
return;
}
- secprintf(("%s: sec: conn_read registering event handler for %s\n",
- debug_prefix_time(NULL), rc->hostname));
+ auth_debug(1, ("%s: sec: conn_read registering event handler for %s\n",
+ debug_prefix_time(NULL), rc->hostname));
rc->ev_read = event_register((event_id_t)rc->read, EV_READFD,
sec_tcp_conn_read_callback, rc);
rc->ev_read_refcnt = 1;
{
--rc->ev_read_refcnt;
- secprintf((
- "%s: sec: conn_read_cancel: decremented ev_read_refcnt to %d for %s\n",
+ auth_debug(1,
+ ("%s: sec: conn_read_cancel: decremented ev_read_refcnt to %d for %s\n",
debug_prefix_time(NULL),
rc->ev_read_refcnt, rc->hostname));
if (rc->ev_read_refcnt > 0) {
return;
}
- secprintf(("%s: sec: conn_read_cancel: releasing event handler for %s\n",
- debug_prefix_time(NULL), rc->hostname));
+ auth_debug(1,
+ ("%s: sec: conn_read_cancel: releasing event handler for %s\n",
+ debug_prefix_time(NULL), rc->hostname));
event_release(rc->ev_read);
rc->ev_read = NULL;
}
assert(rh != NULL);
- secprintf(("%s: sec: recvpkt_callback: %d\n",
- debug_prefix_time(NULL), bufsize));
+ auth_debug(1, ("%s: sec: recvpkt_callback: " SSIZE_T_FMT "\n",
+ debug_prefix_time(NULL), bufsize));
/*
* We need to cancel the recvpkt request before calling
* the callback because the callback may reschedule us.
}
parse_pkt(&pkt, buf, (size_t)bufsize);
- secprintf((
- "%s: sec: received %s packet (%d) from %s, contains:\n\n\"%s\"\n\n",
+ auth_debug(1,
+ ("%s: sec: received %s packet (%d) from %s, contains:\n\n\"%s\"\n\n",
debug_prefix_time(NULL), pkt_type2str(pkt.type), pkt.type,
rh->hostname, pkt.body));
if (rh->rc->recv_security_ok && (rh->rc->recv_security_ok)(rh, &pkt) < 0)
struct sec_stream *rs = s;
assert(rs != NULL);
- secprintf(("%s: sec: stream_read_callback_sync: handle %d\n",
- debug_prefix_time(NULL), rs->handle));
+ auth_debug(1, ("%s: sec: stream_read_callback_sync: handle %d\n",
+ debug_prefix_time(NULL), rs->handle));
/*
* Make sure this was for us. If it was, then blow away the handle
* If the handle is EOF, pass that up to our callback.
*/
if (rs->rc->handle == rs->handle) {
- secprintf(("%s: sec: stream_read_callback_sync: it was for us\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec: stream_read_callback_sync: it was for us\n",
+ debug_prefix_time(NULL)));
rs->rc->handle = H_TAKEN;
} else if (rs->rc->handle != H_EOF) {
- secprintf(("%s: sec: stream_read_callback_sync: not for us\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec: stream_read_callback_sync: not for us\n",
+ debug_prefix_time(NULL)));
return;
}
tcpm_stream_read_cancel(rs);
if (rs->rc->pktlen <= 0) {
- secprintf(("%s: sec: stream_read_sync_callback: %s\n",
- debug_prefix_time(NULL), rs->rc->errmsg));
+ auth_debug(1, ("%s: sec: stream_read_sync_callback: %s\n",
+ debug_prefix_time(NULL), rs->rc->errmsg));
security_stream_seterror(&rs->secstr, rs->rc->errmsg);
if(rs->closed_by_me == 0 && rs->closed_by_network == 0)
sec_tcp_conn_put(rs->rc);
rs->closed_by_network = 1;
return;
}
- secprintf((
- "%s: sec: stream_read_callback_sync: read %zd bytes from %s:%d\n",
+ auth_debug(1,
+ ("%s: sec: stream_read_callback_sync: read " SSIZE_T_FMT " bytes from %s:%d\n",
debug_prefix_time(NULL),
rs->rc->pktlen, rs->rc->hostname, rs->handle));
}
struct sec_stream *rs = arg;
assert(rs != NULL);
- secprintf(("%s: sec: stream_read_callback: handle %d\n",
- debug_prefix_time(NULL), rs->handle));
+ auth_debug(1, ("%s: sec: stream_read_callback: handle %d\n",
+ debug_prefix_time(NULL), rs->handle));
/*
* Make sure this was for us. If it was, then blow away the handle
* If the handle is EOF, pass that up to our callback.
*/
if (rs->rc->handle == rs->handle) {
- secprintf(("%s: sec: stream_read_callback: it was for us\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec: stream_read_callback: it was for us\n",
+ debug_prefix_time(NULL)));
rs->rc->handle = H_TAKEN;
} else if (rs->rc->handle != H_EOF) {
- secprintf(("%s: sec: stream_read_callback: not for us\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec: stream_read_callback: not for us\n",
+ debug_prefix_time(NULL)));
return;
}
tcpm_stream_read_cancel(rs);
if (rs->rc->pktlen <= 0) {
- secprintf(("%s: sec: stream_read_callback: %s\n",
- debug_prefix_time(NULL), rs->rc->errmsg));
+ auth_debug(1, ("%s: sec: stream_read_callback: %s\n",
+ debug_prefix_time(NULL), rs->rc->errmsg));
security_stream_seterror(&rs->secstr, rs->rc->errmsg);
if(rs->closed_by_me == 0 && rs->closed_by_network == 0)
sec_tcp_conn_put(rs->rc);
(*rs->fn)(rs->arg, NULL, rs->rc->pktlen);
return;
}
- secprintf(("%s: sec: stream_read_callback: read %zd bytes from %s:%d\n",
- debug_prefix_time(NULL),
+ auth_debug(1, ("%s: sec: stream_read_callback: read " SSIZE_T_FMT " bytes from %s:%d\n",
+ debug_prefix_time(NULL),
rs->rc->pktlen, rs->rc->hostname, rs->handle));
(*rs->fn)(rs->arg, rs->rc->pkt, rs->rc->pktlen);
- secprintf(("%s: sec: after callback stream_read_callback\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec: after callback stream_read_callback\n",
+ debug_prefix_time(NULL)));
}
/*
assert(cookie != NULL);
- secprintf(("%s: sec: conn_read_callback\n", debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec: conn_read_callback\n", debug_prefix_time(NULL)));
/* Read the data off the wire. If we get errors, shut down. */
- rval = tcpm_recv_token(rc->read, &rc->handle, &rc->errmsg, &rc->pkt,
+ rval = tcpm_recv_token(rc, rc->read, &rc->handle, &rc->errmsg, &rc->pkt,
&rc->pktlen, 60);
- secprintf(("%s: sec: conn_read_callback: tcpm_recv_token returned %d\n",
- debug_prefix_time(NULL), rval));
+ auth_debug(1, ("%s: sec: conn_read_callback: tcpm_recv_token returned " SSIZE_T_FMT "\n",
+ debug_prefix_time(NULL), rval));
if (rval < 0 || rc->handle == H_EOF) {
rc->pktlen = rval;
rc->handle = H_EOF;
revent = event_wakeup((event_id_t)rc);
- secprintf(("%s: sec: conn_read_callback: event_wakeup return %d\n",
- debug_prefix_time(NULL), revent));
+ auth_debug(1, ("%s: sec: conn_read_callback: event_wakeup return %d\n",
+ debug_prefix_time(NULL), revent));
/* delete our 'accept' reference */
if (rc->accept_fn != NULL) {
if(rc->refcnt != 1) {
if(rval == 0) {
rc->pktlen = 0;
revent = event_wakeup((event_id_t)rc);
- secprintf(("%s: 0 sec: conn_read_callback: event_wakeup return %d\n",
- debug_prefix_time(NULL), revent));
+ auth_debug(1,
+ ("%s: 0 sec: conn_read_callback: event_wakeup return %d\n",
+ debug_prefix_time(NULL), revent));
return;
}
/* If there are events waiting on this handle, we're done */
rc->donotclose = 1;
revent = event_wakeup((event_id_t)rc);
- secprintf(("%s: sec: conn_read_callback: event_wakeup return %d\n",
- debug_prefix_time(NULL), rval));
+ auth_debug(1, ("%s: sec: conn_read_callback: event_wakeup return " SSIZE_T_FMT "\n",
+ debug_prefix_time(NULL), rval));
rc->donotclose = 0;
if (rc->handle == H_TAKEN || rc->pktlen == 0) {
if(rc->refcnt == 0) amfree(rc);
rh->peer = rc->peer;
rh->rs = tcpma_stream_client(rh, rc->handle);
- secprintf(("%s: sec: new connection\n", debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec: new connection\n", debug_prefix_time(NULL)));
pkt.body = NULL;
parse_pkt(&pkt, rc->pkt, (size_t)rc->pktlen);
- secprintf(("%s: sec: calling accept_fn\n", debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: sec: calling accept_fn\n", debug_prefix_time(NULL)));
if (rh->rc->recv_security_ok && (rh->rc->recv_security_ok)(rh, &pkt) < 0)
(*rc->accept_fn)(&rh->sech, NULL);
else
{
const unsigned char *bufp = buf;
- secprintf(("%s: sec: parse_pkt: parsing buffer of %d bytes\n",
- debug_prefix_time(NULL), bufsize));
+ auth_debug(1, ("%s: sec: parse_pkt: parsing buffer of " SSIZE_T_FMT " bytes\n",
+ debug_prefix_time(NULL), bufsize));
pkt->type = (pktype_t)*bufp++;
bufsize--;
}
pkt->size = strlen(pkt->body);
- secprintf(("%s: sec: parse_pkt: %s (%d): \"%s\"\n",
- debug_prefix_time(NULL), pkt_type2str(pkt->type),
- pkt->type, pkt->body));
+ auth_debug(1, ("%s: sec: parse_pkt: %s (%d): \"%s\"\n",
+ debug_prefix_time(NULL), pkt_type2str(pkt->type),
+ pkt->type, pkt->body));
}
/*
VERSION_MAJOR, VERSION_MINOR, pkt_type2str(pkt->type),
rh->proto_handle, rh->sequence);
- secprintf(("%s: bsd: pkthdr2str handle '%s'\n",
- debug_prefix_time(NULL), rh->proto_handle));
+ auth_debug(1, ("%s: bsd: pkthdr2str handle '%s'\n",
+ debug_prefix_time(NULL), rh->proto_handle));
/* check for truncation. If only we had asprintf()... */
assert(retbuf[strlen(retbuf) - 1] == '\n');
#ifndef USE_AMANDAHOSTS
r = check_user_ruserok(rh->hostname, pwd, remoteuser);
#else
- r = check_user_amandahosts(rh->hostname, rh->peer.sin_addr, pwd, remoteuser, service);
+ r = check_user_amandahosts(rh->hostname, &rh->peer, pwd, remoteuser, service);
#endif
if (r != NULL) {
result = vstralloc("user ", remoteuser, " from ", rh->hostname,
exit(1);
}
-#if defined(SHOW_SECURITY_DETAIL) /* { */
- {
- char *dir = stralloc(pwd->pw_dir);
+ if (debug_auth >= 9) {
+ char *dir = stralloc(pwd->pw_dir);
- secprintf(("%s: bsd: calling ruserok(%s, %d, %s, %s)\n",
- debug_prefix_time(NULL),
- host, ((myuid == 0) ? 1 : 0), remoteuser, pwd->pw_name));
- if (myuid == 0) {
- secprintf(("%s: bsd: because you are running as root, ",
- debug_prefix(NULL)));
- secprintf(("/etc/hosts.equiv will not be used\n"));
- } else {
- show_stat_info("/etc/hosts.equiv", NULL);
- }
- show_stat_info(dir, "/.rhosts");
- amfree(dir);
+ auth_debug(9, ("%s: bsd: calling ruserok(%s, %d, %s, %s)\n",
+ debug_prefix_time(NULL), host,
+ ((myuid == 0) ? 1 : 0), remoteuser, pwd->pw_name));
+ if (myuid == 0) {
+ auth_debug(9, ("%s: bsd: because you are running as root, ",
+ debug_prefix_time(NULL)));
+ auth_debug(9, ("/etc/hosts.equiv will not be used\n"));
+ } else {
+ show_stat_info("/etc/hosts.equiv", NULL);
+ }
+ show_stat_info(dir, "/.rhosts");
+ amfree(dir);
}
-#endif /* } */
saved_stderr = dup(2);
close(2);
if (open("/dev/null", O_RDWR) == -1) {
- secprintf(("%s: Could not open /dev/null: %s\n",
- debug_prefix(NULL), strerror(errno)));
+ auth_debug(1, ("%s: Could not open /dev/null: %s\n",
+ debug_prefix_time(NULL), strerror(errno)));
ec = 1;
} else {
ok = ruserok(host, myuid == 0, remoteuser, CLIENT_LOGIN);
char *
check_user_amandahosts(
const char * host,
- struct in_addr addr,
+ struct sockaddr_storage *addr,
struct passwd * pwd,
const char * remoteuser,
const char * service)
int hostmatch;
int usermatch;
char *aservice = NULL;
+#ifdef WORKING_IPV6
+ char ipstr[INET6_ADDRSTRLEN];
+#else
+ char ipstr[INET_ADDRSTRLEN];
+#endif
- secprintf(("check_user_amandahosts(host=%s, pwd=%p, "
- "remoteuser=%s, service=%s)\n",
- host, pwd, remoteuser, service));
+ auth_debug(1, ("check_user_amandahosts(host=%s, pwd=%p, "
+ "remoteuser=%s, service=%s)\n",
+ host, pwd, remoteuser, service));
ptmp = stralloc2(pwd->pw_dir, "/.amandahosts");
-#if defined(SHOW_SECURITY_DETAIL) /* { */
- show_stat_info(ptmp, "");;
-#endif /* } */
+ if (debug_auth >= 9) {
+ show_stat_info(ptmp, "");;
+ }
if ((fp = fopen(ptmp, "r")) == NULL) {
result = vstralloc("cannot open ", ptmp, ": ", strerror(errno), NULL);
amfree(ptmp);
continue;
}
-#if defined(SHOW_SECURITY_DETAIL) /* { */
- secprintf(("%s: bsd: processing line: <%s>\n", debug_prefix(NULL), line));
-#endif /* } */
+ auth_debug(9, ("%s: bsd: processing line: <%s>\n",
+ debug_prefix_time(NULL), line));
/* get the host out of the file */
if ((filehost = strtok(line, " \t")) == NULL) {
amfree(line);
hostmatch = (strcasecmp(filehost, host) == 0);
/* ok if addr=127.0.0.1 and
- * either localhost or localhost.domain is in .amandahost */
- if ( !hostmatch ) {
- if (strcmp(inet_ntoa(addr), "127.0.0.1")== 0 &&
- (strcasecmp(filehost, "localhost")== 0 ||
- strcasecmp(filehost, "localhost.localdomain")== 0))
- {
- hostmatch = 1;
- }
- }
+ * either localhost or localhost.domain is in .amandahost */
+ if (!hostmatch &&
+ (strcasecmp(filehost, "localhost")== 0 ||
+ strcasecmp(filehost, "localhost.localdomain")== 0)) {
+#ifdef WORKING_IPV6
+ if (addr->ss_family == (sa_family_t)AF_INET6)
+ inet_ntop(AF_INET6, &((struct sockaddr_in6 *)addr)->sin6_addr,
+ ipstr, sizeof(ipstr));
+ else
+#endif
+ inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr,
+ ipstr, sizeof(ipstr));
+ if (strcmp(ipstr, "127.0.0.1") == 0 ||
+ strcmp(ipstr, "::1") == 0)
+ hostmatch = 1;
+ }
usermatch = (strcasecmp(fileuser, remoteuser) == 0);
-#if defined(SHOW_SECURITY_DETAIL) /* { */
- secprintf(("%s: bsd: comparing \"%s\" with\n", debug_prefix(NULL), filehost));
- secprintf(("%s: bsd: \"%s\" (%s)\n", host,
- debug_prefix(NULL), hostmatch ? "match" : "no match"));
- secprintf(("%s: bsd: and \"%s\" with\n", fileuser, debug_prefix(NULL)));
- secprintf(("%s: bsd: \"%s\" (%s)\n", remoteuser,
- debug_prefix(NULL), usermatch ? "match" : "no match"));
-#endif /* } */
+ auth_debug(9, ("%s: bsd: comparing \"%s\" with\n",
+ debug_prefix_time(NULL), filehost));
+ auth_debug(9, ("%s: bsd: \"%s\" (%s)\n", host,
+ debug_prefix_time(NULL), hostmatch ? "match" : "no match"));
+ auth_debug(9, ("%s: bsd: and \"%s\" with\n",
+ fileuser, debug_prefix_time(NULL)));
+ auth_debug(9, ("%s: bsd: \"%s\" (%s)\n", remoteuser,
+ debug_prefix_time(NULL), usermatch ? "match" : "no match"));
/* compare */
if (!hostmatch || !usermatch) {
amfree(line);
if (strcmp(service, "amindexd") == 0 ||
strcmp(service, "amidxtaped") == 0) {
result = vstralloc("Please add \"amindexd amidxtaped\" to "
- "the line in ", ptmp, NULL);
+ "the line in ", ptmp, " on the client", NULL);
} else if (strcmp(service, "amdump") == 0 ||
strcmp(service, "noop") == 0 ||
strcmp(service, "selfcheck") == 0 ||
strcmp(service, "sendsize") == 0 ||
strcmp(service, "sendbackup") == 0) {
result = vstralloc("Please add \"amdump\" to the line in ",
- ptmp, NULL);
+ ptmp, " on the client", NULL);
} else {
result = vstralloc(ptmp, ": ",
"invalid service ", service, NULL);
/* return 1 on success, 0 on failure */
int
check_security(
- struct sockaddr_in *addr,
+ struct sockaddr_storage *addr,
char * str,
unsigned long cksum,
char ** errstr)
{
char * remotehost = NULL, *remoteuser = NULL;
char * bad_bsd = NULL;
- struct hostent * hp;
struct passwd * pwptr;
uid_t myuid;
- int i;
- int j;
char * s;
char * fp;
int ch;
+ char hostname[NI_MAXHOST];
+ in_port_t port;
+ int result;
(void)cksum; /* Quiet unused parameter warning */
- secprintf(("%s: check_security(addr=%p, str='%s', cksum=%ul, errstr=%p\n",
- debug_prefix(NULL), addr, str, cksum, errstr));
+ auth_debug(1,
+ ("%s: check_security(addr=%p, str='%s', cksum=%lu, errstr=%p\n",
+ debug_prefix_time(NULL), addr, str, cksum, errstr));
dump_sockaddr(addr);
*errstr = NULL;
/* what host is making the request? */
-
- hp = gethostbyaddr((char *)&addr->sin_addr, SIZEOF(addr->sin_addr),
- AF_INET);
- if (hp == NULL) {
- /* XXX include remote address in message */
- *errstr = vstralloc("[",
- "addr ", inet_ntoa(addr->sin_addr), ": ",
- "hostname lookup failed",
- "]", NULL);
- return 0;
- }
- remotehost = stralloc(hp->h_name);
-
- /* Now let's get the hostent for that hostname */
- hp = gethostbyname( remotehost );
- if (hp == NULL) {
- /* XXX include remote hostname in message */
- *errstr = vstralloc("[",
- "host ", remotehost, ": ",
- "hostname lookup failed",
+ if ((result = getnameinfo((struct sockaddr *)addr, SS_LEN(addr),
+ hostname, NI_MAXHOST, NULL, 0, 0) != 0)) {
+ dbprintf(("%s: getnameinfo failed: %s\n",
+ debug_prefix_time(NULL), gai_strerror(result)));
+ *errstr = vstralloc("[", "addr ", str_sockaddr(addr), ": ",
+ "getnameinfo failed: ", gai_strerror(result),
"]", NULL);
- amfree(remotehost);
return 0;
}
-
- /* Verify that the hostnames match -- they should theoretically */
- if (strncasecmp( remotehost, hp->h_name, strlen(remotehost)+1 ) != 0 ) {
- *errstr = vstralloc("[",
- "hostnames do not match: ",
- remotehost, " ", hp->h_name,
- "]", NULL);
+ remotehost = stralloc(hostname);
+ if( check_name_give_sockaddr(hostname,
+ (struct sockaddr *)addr, errstr) < 0) {
amfree(remotehost);
return 0;
}
- /* Now let's verify that the ip which gave us this hostname
- * is really an ip for this hostname; or is someone trying to
- * break in? (THIS IS THE CRUCIAL STEP)
- */
- for (i = 0; hp->h_addr_list[i]; i++) {
- if (memcmp(hp->h_addr_list[i],
- (char *) &addr->sin_addr, SIZEOF(addr->sin_addr)) == 0)
- break; /* name is good, keep it */
- }
-
- /* If we did not find it, your DNS is messed up or someone is trying
- * to pull a fast one on you. :(
- */
-
- /* Check even the aliases list. Work around for Solaris if dns goes over NIS */
-
- if (!hp->h_addr_list[i] ) {
- for (j = 0; hp->h_aliases[j] !=0 ; j++) {
- if (strcmp(hp->h_aliases[j],inet_ntoa(addr->sin_addr)) == 0)
- break; /* name is good, keep it */
- }
- if (!hp->h_aliases[j] ) {
- *errstr = vstralloc("[",
- "ip address ", inet_ntoa(addr->sin_addr),
- " is not in the ip list for ", remotehost,
- "]",
- NULL);
- amfree(remotehost);
- return 0;
- }
- }
-
/* next, make sure the remote port is a "reserved" one */
-
- if (ntohs(addr->sin_port) >= IPPORT_RESERVED) {
+ port = SS_GET_PORT(addr);
+ if (port >= IPPORT_RESERVED) {
char number[NUM_STR_SIZE];
- snprintf(number, SIZEOF(number), "%u",
- (unsigned int)ntohs(addr->sin_port));
+ snprintf(number, SIZEOF(number), "%u", (unsigned int)port);
*errstr = vstralloc("[",
"host ", remotehost, ": ",
"port ", number, " not secure",
"bad bsd security line",
"]", NULL);
-#define sc "USER "
- if (strncmp(s - 1, sc, SIZEOF(sc)-1) != 0) {
+ if (strncmp_const_skip(s - 1, "USER ", s, ch) != 0) {
*errstr = bad_bsd;
bad_bsd = NULL;
amfree(remotehost);
return 0;
}
- s += SIZEOF(sc)-1;
- ch = s[-1];
-#undef sc
skip_whitespace(s, ch);
if (ch == '\0') {
if ((pwptr = getpwuid(myuid)) == NULL)
error("error [getpwuid(%d) fails]", myuid);
- secprintf(("%s: bsd security: remote host %s user %s local user %s\n",
- debug_prefix(NULL), remotehost, remoteuser, pwptr->pw_name));
+ auth_debug(1, ("%s: bsd security: remote host %s user %s local user %s\n",
+ debug_prefix_time(NULL), remotehost, remoteuser, pwptr->pw_name));
#ifndef USE_AMANDAHOSTS
s = check_user_ruserok(remotehost, pwptr, remoteuser);
#else
- s = check_user_amandahosts(remotehost, addr->sin_addr, pwptr, remoteuser, NULL);
+ s = check_user_amandahosts(remotehost, addr, pwptr, remoteuser, NULL);
#endif
if (s != NULL) {
if (n < 0) {
if (errno != EINTR)
return (-1);
- secprintf(("%s: net_writev got EINTR\n",
- debug_prefix(NULL)));
+ auth_debug(1, ("%s: net_writev got EINTR\n",
+ debug_prefix_time(NULL)));
}
else if (n == 0) {
errno = EIO;
ssize_t nread;
size_t size = origsize;
- secprintf(("%s: net_read: begin %d\n", debug_prefix_time(NULL), origsize));
+ auth_debug(1, ("%s: net_read: begin " SIZE_T_FMT "\n",
+ debug_prefix_time(NULL), origsize));
while (size > 0) {
- secprintf(("%s: net_read: while %d\n",
- debug_prefix_time(NULL), size));
+ auth_debug(1, ("%s: net_read: while " SIZE_T_FMT "\n",
+ debug_prefix_time(NULL), size));
nread = net_read_fillbuf(fd, timeout, buf, size);
if (nread < 0) {
- secprintf(("%s: db: net_read: end return(-1)\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: db: net_read: end return(-1)\n",
+ debug_prefix_time(NULL)));
return (-1);
}
if (nread == 0) {
- secprintf(("%s: net_read: end return(0)\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: net_read: end return(0)\n",
+ debug_prefix_time(NULL)));
return (0);
}
buf += nread;
size -= nread;
}
- secprintf(("%s: net_read: end %d\n",
- debug_prefix_time(NULL), origsize));
+ auth_debug(1, ("%s: net_read: end " SIZE_T_FMT "\n",
+ debug_prefix_time(NULL), origsize));
return ((ssize_t)origsize);
}
void * buf,
size_t size)
{
- fd_set readfds;
+ SELECT_ARG_TYPE readfds;
struct timeval tv;
ssize_t nread;
- secprintf(("%s: net_read_fillbuf: begin\n", debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: net_read_fillbuf: begin\n", debug_prefix_time(NULL)));
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
tv.tv_sec = timeout;
errno = ETIMEDOUT;
/* FALLTHROUGH */
case -1:
- secprintf(("%s: net_read_fillbuf: case -1\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: net_read_fillbuf: case -1\n",
+ debug_prefix_time(NULL)));
return (-1);
case 1:
- secprintf(("%s: net_read_fillbuf: case 1\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: net_read_fillbuf: case 1\n",
+ debug_prefix_time(NULL)));
assert(FD_ISSET(fd, &readfds));
break;
default:
- secprintf(("%s: net_read_fillbuf: case default\n",
- debug_prefix_time(NULL)));
+ auth_debug(1, ("%s: net_read_fillbuf: case default\n",
+ debug_prefix_time(NULL)));
assert(0);
break;
}
nread = read(fd, buf, size);
if (nread < 0)
return (-1);
- secprintf(("%s: net_read_fillbuf: end %d\n",
- debug_prefix_time(NULL), nread));
+ auth_debug(1, ("%s: net_read_fillbuf: end " SSIZE_T_FMT "\n",
+ debug_prefix_time(NULL), nread));
return (nread);
}
char *group;
if (stat(name, &sbuf) != 0) {
- secprintf(("%s: bsd: cannot stat %s: %s\n",
- debug_prefix_time(NULL), name, strerror(errno)));
+ auth_debug(1, ("%s: bsd: cannot stat %s: %s\n",
+ debug_prefix_time(NULL), name, strerror(errno)));
amfree(name);
return;
}
} else {
group = stralloc(grptr->gr_name);
}
- secprintf(("%s: bsd: processing file: %s\n", debug_prefix(NULL), name));
- secprintf(("%s: bsd: owner=%s group=%s mode=%03o\n",
- debug_prefix(NULL), owner, group, (int) (sbuf.st_mode & 0777)));
+ auth_debug(1, ("%s: bsd: processing file: %s\n", debug_prefix_time(NULL), name));
+ auth_debug(1, ("%s: bsd: owner=%s group=%s mode=%03o\n",
+ debug_prefix_time(NULL), owner, group,
+ (int) (sbuf.st_mode & 0777)));
amfree(name);
amfree(owner);
amfree(group);
}
+
+int
+check_name_give_sockaddr(
+ const char *hostname,
+ struct sockaddr *addr,
+ char **errstr)
+{
+ struct addrinfo *res = NULL, *res1;
+ struct addrinfo hints;
+ int result;
+
+#ifdef WORKING_IPV6
+ if ((addr)->sa_family == AF_INET6)
+ hints.ai_flags = AI_CANONNAME | AI_V4MAPPED | AI_ALL;
+ else
+#endif
+ hints.ai_flags = AI_CANONNAME;
+ hints.ai_family = addr->sa_family;
+ hints.ai_socktype = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_addr = NULL;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ result = getaddrinfo(hostname, NULL, &hints, &res);
+ if (result != 0) {
+ dbprintf(("check_name_give_sockaddr: getaddrinfo(%s): %s\n", hostname, gai_strerror(result)));
+ *errstr = newvstralloc(*errstr,
+ " getaddrinfo(", hostname, "): ",
+ gai_strerror(result), NULL);
+ return -1;
+ }
+ if (res->ai_canonname == NULL) {
+ dbprintf(("getaddrinfo(%s) did not return a canonical name\n", hostname));
+ *errstr = newvstralloc(*errstr,
+ " getaddrinfo(", hostname, ") did not return a canonical name", NULL);
+ return -1;
+ }
+
+ if (strncasecmp(hostname, res->ai_canonname, strlen(hostname)) != 0) {
+ auth_debug(1, ("%s: %s doesn't resolve to itself, it resolves to %s\n",
+ debug_prefix_time(NULL),
+ hostname, res->ai_canonname));
+ *errstr = newvstralloc(*errstr, hostname,
+ _(" doesn't resolve to itself, it resolves to "),
+ res->ai_canonname, NULL);
+ return -1;
+ }
+
+ for(res1=res; res1 != NULL; res1 = res1->ai_next) {
+ if (res1->ai_addr->sa_family == addr->sa_family) {
+ if (cmp_sockaddr((struct sockaddr_storage *)res1->ai_addr, (struct sockaddr_storage *)addr, 1) == 0) {
+ freeaddrinfo(res);
+ return 0;
+ }
+ }
+ }
+
+ *errstr = newvstralloc(*errstr,
+ str_sockaddr((struct sockaddr_storage *)addr),
+ " doesn't resolve to ",
+ hostname, NULL);
+ freeaddrinfo(res);
+ return -1;
+}
+
+
+int
+check_addrinfo_give_name(
+ struct addrinfo *res,
+ const char *hostname,
+ char **errstr)
+{
+ if (strncasecmp(hostname, res->ai_canonname, strlen(hostname)) != 0) {
+ dbprintf(("%s: %s doesn't resolve to itself, it resolv to %s\n",
+ debug_prefix_time(NULL),
+ hostname, res->ai_canonname));
+ *errstr = newvstralloc(*errstr, hostname,
+ " doesn't resolve to itself, it resolv to ",
+ res->ai_canonname, NULL);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Try resolving the hostname, just to catch any potential
+ * problems down the road. This is used from most security_connect
+ * methods, many of which also want the canonical name. Returns
+ * 0 on success.
+ */
+int
+try_resolving_hostname(
+ const char *hostname,
+ char **canonname)
+{
+ struct addrinfo hints;
+ struct addrinfo *gaires;
+ int res;
+
+#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 = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_addr = NULL;
+ hints.ai_canonname = NULL;
+ hints.ai_next = NULL;
+ if ((res = getaddrinfo(hostname, NULL, &hints, &gaires)) != 0) {
+ return -1;
+ }
+ if (canonname && gaires && gaires->ai_canonname)
+ *canonname = stralloc(gaires->ai_canonname);
+ if (gaires) freeaddrinfo(gaires);
+
+ return 0;
+}