#include "util.h"
#include "event.h"
#include "packet.h"
-#include "queue.h"
#include "security.h"
#include "security-util.h"
#include "stream.h"
-#include "version.h"
#include "sockaddr-util.h"
-/*
- * Magic values for sec_conn->handle
- */
-#define H_TAKEN -1 /* sec_conn->tok was already read */
-#define H_EOF -2 /* this connection has been shut down */
-
/*
* This is a queue of open connections
*/
-struct connq_s connq = {
- TAILQ_HEAD_INITIALIZER(connq.tailq), 0
-};
+GSList *connq = NULL;
static int newhandle = 1;
static int newevent = 1;
{
struct tcp_conn *rc;
- rc = sec_tcp_conn_get("unknown",0);
+ rc = sec_tcp_conn_get("",0); /* no hostname yet */
rc->read = in;
rc->write = out;
rc->accept_fn = fn;
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));
+ security_seterror(&rh->sech, "%s", security_stream_geterror(&rh->rs->secstr));
+ amfree(buf);
return (-1);
}
amfree(buf);
if (tcpm_send_token(rs->rc, rs->rc->write, rs->handle, &rs->rc->errmsg,
buf, size)) {
- security_stream_seterror(&rs->secstr, rs->rc->errmsg);
+ security_stream_seterror(&rs->secstr, "%s", rs->rc->errmsg);
return (-1);
}
return (0);
* Only one read request can be active per stream.
*/
if (rs->ev_read == NULL) {
- rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
+ rs->ev_read = event_register((event_id_t)rs->rc->event_id, EV_WAIT,
stream_read_callback, rs);
sec_tcp_conn_read(rs->rc);
}
rs->arg = arg;
}
+/* buffer for tcpm_stream_read_sync function */
+static ssize_t sync_pktlen;
+static void *sync_pkt;
+
/*
* Write a chunk of data to a stream. Blocks until completion.
*/
if (rs->ev_read != NULL) {
return -1;
}
- rs->ev_read = event_register((event_id_t)rs->rc, EV_WAIT,
+ sync_pktlen = 0;
+ sync_pkt = NULL;
+ rs->ev_read = event_register((event_id_t)rs->rc->event_id, EV_WAIT,
stream_read_sync_callback, rs);
sec_tcp_conn_read(rs->rc);
event_wait(rs->ev_read);
- *buf = rs->rc->pkt;
- return (rs->rc->pktlen);
+ /* Can't use rs or rc, they can be freed */
+ *buf = sync_pkt;
+ return (sync_pktlen);
}
/*
int rval;
char *encbuf;
ssize_t encsize;
+ int save_errno;
+ time_t logtime;
assert(SIZEOF(netlength) == 4);
+ logtime = time(NULL);
+ if (rc && logtime > rc->logstamp + 10) {
+ g_debug("tcpm_send_token: data is still flowing");
+ rc->logstamp = logtime;
+ }
+
auth_debug(1, "tcpm_send_token: write %zd bytes to handle %d\n",
- len, handle);
+ len, handle);
/*
* Format is:
* 32 bit length (network byte order)
nb_iov = 3;
}
- rval = net_writev(fd, iov, nb_iov);
+ rval = full_writev(fd, iov, nb_iov);
+ save_errno = errno;
if (len != 0 && rc->driver->data_encrypt != NULL && buf != encbuf) {
amfree(encbuf);
}
if (rval < 0) {
if (errmsg)
*errmsg = newvstrallocf(*errmsg, _("write error to: %s"),
- strerror(errno));
+ strerror(save_errno));
return (-1);
}
return (0);
}
/*
+ * return -2 for incomplete packet
* return -1 on error
* return 0 on EOF: *handle = H_EOF && *size = 0 if socket closed
* return 0 on EOF: *handle = handle && *size = 0 if stream closed
int * handle,
char ** errmsg,
char ** buf,
- ssize_t * size,
- int timeout)
+ ssize_t * size)
{
- unsigned int netint[2];
-
- assert(SIZEOF(netint) == 8);
-
- switch (net_read(fd, &netint, SIZEOF(netint), timeout)) {
- case -1:
- if (errmsg)
- *errmsg = newvstrallocf(*errmsg, _("recv error: %s"), strerror(errno));
- auth_debug(1, _("tcpm_recv_token: A return(-1)\n"));
- return (-1);
- case 0:
- *size = 0;
- *handle = H_EOF;
- *errmsg = newvstrallocf(*errmsg, _("SOCKET_EOF"));
- auth_debug(1, _("tcpm_recv_token: A return(0)\n"));
- return (0);
- default:
- break;
- }
-
- *size = (ssize_t)ntohl(netint[0]);
- *handle = (int)ntohl(netint[1]);
- /* amanda protocol packet can be above NETWORK_BLOCK_BYTES */
- if (*size > 128*NETWORK_BLOCK_BYTES || *size < 0) {
- 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] = ((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;
- s[7] = (*handle ) & 0xFF;
- i = 8; s[i] = ' ';
- while(i<100 && isprint((int)s[i]) && s[i] != '\n') {
- switch(net_read(fd, &s[i], 1, 0)) {
- case -1: s[i] = '\0'; break;
- case 0: s[i] = '\0'; break;
- default:
+ ssize_t rval;
+
+ assert(SIZEOF(rc->netint) == 8);
+ if (rc->size_header_read < (ssize_t)SIZEOF(rc->netint)) {
+ rval = read(fd, ((char *)&rc->netint) + rc->size_header_read,
+ SIZEOF(rc->netint) - rc->size_header_read);
+ if (rval == -1) {
+ if (errmsg)
+ *errmsg = newvstrallocf(*errmsg, _("recv error: %s"),
+ strerror(errno));
+ auth_debug(1, _("tcpm_recv_token: A return(-1)\n"));
+ return(-1);
+ } else if (rval == 0) {
+ *size = 0;
+ *handle = H_EOF;
+ *errmsg = newvstrallocf(*errmsg, _("SOCKET_EOF"));
+ auth_debug(1, _("tcpm_recv_token: A return(0)\n"));
+ return(0);
+ } else if (rval < (ssize_t)SIZEOF(rc->netint) - rc->size_header_read) {
+ rc->size_header_read += rval;
+ return(-2);
+ }
+ rc->size_header_read += rval;
+ amfree(rc->buffer);
+ *size = (ssize_t)ntohl(rc->netint[0]);
+ *handle = (int)ntohl(rc->netint[1]);
+ rc->buffer = NULL;
+ rc->size_buffer_read = 0;
+
+ /* amanda protocol packet can be above NETWORK_BLOCK_BYTES */
+ if (*size > 128*NETWORK_BLOCK_BYTES || *size < 0) {
+ 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[201];
+ char *s1;
+ int i;
+ 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;
+ s[7] = (*handle ) & 0xFF;
+ i = 8; s[i] = ' ';
+ while(i<200 && isprint((int)s[i]) && s[i] != '\n') {
+ switch(net_read(fd, &s[i], 1, 0)) {
+ case -1: s[i] = '\0'; break;
+ case 0: s[i] = '\0'; break;
+ default:
dbprintf(_("read: %c\n"), s[i]); i++; s[i]=' ';
break;
+ }
}
+ s[i] = '\0';
+ s1 = quote_string(s);
+ *errmsg = newvstrallocf(*errmsg,
+ _("tcpm_recv_token: invalid size: %s"), s1);
+ dbprintf(_("tcpm_recv_token: invalid size %s\n"), s1);
+ amfree(s1);
+ } else {
+ *errmsg = newvstrallocf(*errmsg,
+ _("tcpm_recv_token: invalid size"));
+ dbprintf(_("tcpm_recv_token: invalid size %zd\n"), *size);
}
- s[i] = '\0';
- *errmsg = newvstrallocf(*errmsg, _("tcpm_recv_token: invalid size: %s"), s);
- dbprintf(_("tcpm_recv_token: invalid size %s\n"), s);
- } else {
- *errmsg = newvstrallocf(*errmsg, _("tcpm_recv_token: invalid size"));
- dbprintf(_("tcpm_recv_token: invalid size %zd\n"), *size);
+ *size = -1;
+ return -1;
}
- *size = -1;
- return -1;
- }
- amfree(*buf);
- *buf = alloc((size_t)*size);
+ rc->buffer = alloc((size_t)*size);
- if(*size == 0) {
- auth_debug(1, _("tcpm_recv_token: read EOF from %d\n"), *handle);
- *errmsg = newvstrallocf(*errmsg, _("EOF"));
- return 0;
+ if (*size == 0) {
+ auth_debug(1, _("tcpm_recv_token: read EOF from %d\n"), *handle);
+ *errmsg = newvstrallocf(*errmsg, _("EOF"));
+ rc->size_header_read = 0;
+ return 0;
+ }
}
- switch (net_read(fd, *buf, (size_t)*size, timeout)) {
- case -1:
+
+ *size = (ssize_t)ntohl(rc->netint[0]);
+ *handle = (int)ntohl(rc->netint[1]);
+
+ rval = read(fd, rc->buffer + rc->size_buffer_read,
+ (size_t)*size - rc->size_buffer_read);
+ if (rval == -1) {
if (errmsg)
- *errmsg = newvstrallocf(*errmsg, _("recv error: %s"), strerror(errno));
+ *errmsg = newvstrallocf(*errmsg, _("recv error: %s"),
+ strerror(errno));
auth_debug(1, _("tcpm_recv_token: B return(-1)\n"));
return (-1);
- case 0:
+ } else if (rval == 0) {
*size = 0;
*errmsg = newvstrallocf(*errmsg, _("SOCKET_EOF"));
auth_debug(1, _("tcpm_recv_token: B return(0)\n"));
return (0);
- default:
- break;
+ } else if (rval < (ssize_t)*size - rc->size_buffer_read) {
+ rc->size_buffer_read += rval;
+ return (-2);
}
+ rc->size_buffer_read += rval;
+ amfree(*buf);
+ *buf = rc->buffer;
+ rc->size_header_read = 0;
+ rc->size_buffer_read = 0;
+ rc->buffer = NULL;
auth_debug(1, _("tcpm_recv_token: read %zd bytes from %d\n"), *size, *handle);
(void)hostname;
- if (rh && rh->rc && rh->rc->toclose == 0) {
+ if (rh && rh->rc && rh->rc->read >= 0 && rh->rc->toclose == 0) {
rh->rc->toclose = 1;
sec_tcp_conn_put(rh->rc);
}
return (NULL);
}
- rs = alloc(SIZEOF(*rs));
+ rs = g_new0(struct sec_stream, 1);
security_streaminit(&rs->secstr, rh->sech.driver);
rs->handle = id;
rs->ev_read = NULL;
assert(rh != NULL);
- rs = alloc(SIZEOF(*rs));
+ rs = g_new0(struct sec_stream, 1);
security_streaminit(&rs->secstr, rh->sech.driver);
rs->closed_by_me = 0;
rs->closed_by_network = 0;
security_stream_read_cancel(&rs->secstr);
if(rs->closed_by_network == 0)
sec_tcp_conn_put(rs->rc);
+ amfree(((security_stream_t *)rs)->error);
amfree(rs);
}
assert(rh != NULL);
- rs = alloc(SIZEOF(*rs));
+ rs = g_new0(struct sec_stream, 1);
security_streaminit(&rs->secstr, rh->sech.driver);
rs->closed_by_me = 0;
rs->closed_by_network = 0;
rh->rc = sec_tcp_conn_get(rh->hostname, 1);
rh->rc->driver = rh->sech.driver;
rs->rc = rh->rc;
- rs->socket = stream_server(rh->udp->peer.ss_family, &rs->port,
+ rs->socket = stream_server(SU_GET_FAMILY(&rh->udp->peer), &rs->port,
STREAM_BUFSIZE, STREAM_BUFSIZE, 0);
if (rs->socket < 0) {
security_seterror(&rh->sech,
assert(rh != NULL);
- rs = alloc(SIZEOF(*rs));
+ rs = g_new0(struct sec_stream, 1);
security_streaminit(&rs->secstr, rh->sech.driver);
rs->handle = id;
rs->ev_read = NULL;
size_t size)
{
struct sec_stream *rs = s;
+ time_t logtime;
assert(rs != NULL);
- if (fullwrite(rs->fd, buf, size) < 0) {
+ logtime = time(NULL);
+ if (rs && rs->rc && logtime > rs->rc->logstamp + 10) {
+ g_debug("tcp_stream_write: data is still flowing");
+ rs->rc->logstamp = logtime;
+ }
+
+ if (full_write(rs->fd, buf, size) < size) {
security_stream_seterror(&rs->secstr,
_("write error on stream %d: %s"), rs->port, strerror(errno));
return (-1);
if (pkt->type != P_REQ)
return "";
- if ((pwd = getpwuid(getuid())) == NULL) {
+ if ((pwd = getpwuid(geteuid())) == NULL) {
security_seterror(&rh->sech,
_("can't get login name for my uid %ld"),
- (long)getuid());
- return(NULL);
+ (long)geteuid());
+ return "";
}
buf = alloc(16+strlen(pwd->pw_name));
strncpy(buf, "SECURITY USER ", (16 + strlen(pwd->pw_name)));
/*
* Request packets must come from a reserved port
*/
- port = SS_GET_PORT(&rh->peer);
+ port = SU_GET_PORT(&rh->peer);
if (port >= IPPORT_RESERVED) {
security_seterror(&rh->sech,
_("host %s: port %u not secure"), rh->hostname,
if ((tok = strtok(NULL, "")) == NULL) {
security_seterror(&rh->sech,
_("SECURITY line: %s"), security_line);
+ amfree(service);
amfree(security_line);
return (-1); /* default errmsg */
}
* Initialize this datagram, and add the header
*/
dgram_zero(&rh->udp->dgram);
- dgram_cat(&rh->udp->dgram, pkthdr2str(rh, pkt));
+ dgram_cat(&rh->udp->dgram, "%s", pkthdr2str(rh, pkt));
/*
* Add the security info. This depends on which kind of packet we're
/*
* Add the body, and send it
*/
- dgram_cat(&rh->udp->dgram, pkt->body);
+ dgram_cat(&rh->udp->dgram, "%s", pkt->body);
auth_debug(1,
_("sec: udpbsd_sendpkt: %s (%d) pkt_t (len %zu) contains:\n\n\"%s\"\n\n"),
udp_handle_t * udp,
struct sec_handle * rh,
char * hostname,
- struct sockaddr_storage *addr,
+ sockaddr_union *addr,
in_port_t port,
char * handle,
int sequence)
rh->hostname = stralloc(hostname);
copy_sockaddr(&rh->peer, addr);
- SS_SET_PORT(&rh->peer, port);
+ SU_SET_PORT(&rh->peer, port);
rh->prev = udp->bh_last;
return;
}
- rh = alloc(SIZEOF(*rh));
+ rh = g_new0(struct sec_handle, 1);
rh->proto_handle=NULL;
rh->udp = udp;
rh->rc = NULL;
return;
}
- port = SS_GET_PORT(&udp->peer);
+ port = SU_GET_PORT(&udp->peer);
a = udp_inithandle(udp, rh,
hostname,
&udp->peer,
const char *hostname,
int want_new)
{
- struct tcp_conn *rc;
+ GSList *iter;
+ struct tcp_conn *rc = NULL;
auth_debug(1, _("sec_tcp_conn_get: %s\n"), hostname);
if (want_new == 0) {
- for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
+ for (iter = connq; iter != NULL; iter = iter->next) {
+ rc = (struct tcp_conn *)iter->data;
if (strcasecmp(hostname, rc->hostname) == 0)
break;
}
- if (rc != NULL) {
+ if (iter != NULL) {
rc->refcnt++;
auth_debug(1,
_("sec_tcp_conn_get: exists, refcnt to %s is now %d\n"),
/*
* We can't be creating a new handle if we are the client
*/
- rc = alloc(SIZEOF(*rc));
+ rc = g_new0(struct tcp_conn, 1);
rc->read = rc->write = -1;
rc->driver = NULL;
rc->pid = -1;
rc->auth = 0;
rc->conf_fn = NULL;
rc->datap = NULL;
- connq_append(rc);
+ rc->event_id = newevent++;
+ connq = g_slist_append(connq, rc);
return (rc);
}
event_release(rc->ev_read);
if (rc->errmsg != NULL)
amfree(rc->errmsg);
- connq_remove(rc);
+ connq = g_slist_remove(connq, rc);
amfree(rc->pkt);
- if(!rc->donotclose)
- amfree(rc); /* someone might still use it */
- /* eg. in sec_tcp_conn_read_callback if */
- /* event_wakeup call us. */
+ if(!rc->donotclose) {
+ /* amfree(rc) */
+ /* a memory leak occurs, but freeing it lead to memory
+ * corruption because it can still be used.
+ * We need to find a good place to free 'rc'.
+ */
+ }
}
/*
(*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
return;
case -1:
- security_seterror(&rh->sech, security_stream_geterror(&rh->rs->secstr));
+ security_seterror(&rh->sech, "%s", security_stream_geterror(&rh->rs->secstr));
(*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
return;
default:
*/
tcpm_stream_read_cancel(rs);
+ sync_pktlen = rs->rc->pktlen;
+ sync_pkt = malloc(sync_pktlen);
+ memcpy(sync_pkt, rs->rc->pkt, sync_pktlen);
+
if (rs->rc->pktlen <= 0) {
auth_debug(1, _("sec: stream_read_sync_callback: %s\n"), rs->rc->errmsg);
- security_stream_seterror(&rs->secstr, rs->rc->errmsg);
+ security_stream_seterror(&rs->secstr, "%s", 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;
void * arg)
{
struct sec_stream *rs = arg;
+ time_t logtime;
+
assert(rs != NULL);
+ logtime = time(NULL);
+ if (rs && rs->rc && logtime > rs->rc->logstamp + 10) {
+ g_debug("stream_read_callback: data is still flowing");
+ rs->rc->logstamp = logtime;
+ }
auth_debug(1, _("sec: stream_read_callback: handle %d\n"), rs->handle);
/*
if (rs->rc->pktlen <= 0) {
auth_debug(1, _("sec: stream_read_callback: %s\n"), rs->rc->errmsg);
- security_stream_seterror(&rs->secstr, rs->rc->errmsg);
+ security_stream_seterror(&rs->secstr, "%s", 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;
/* Read the data off the wire. If we get errors, shut down. */
rval = tcpm_recv_token(rc, rc->read, &rc->handle, &rc->errmsg, &rc->pkt,
- &rc->pktlen, 60);
+ &rc->pktlen);
auth_debug(1, _("sec: conn_read_callback: tcpm_recv_token returned %zd\n"),
rval);
+
+ if (rval == -2) {
+ return;
+ }
+
if (rval < 0 || rc->handle == H_EOF) {
rc->pktlen = rval;
rc->handle = H_EOF;
- revent = event_wakeup((event_id_t)rc);
+ revent = event_wakeup((event_id_t)rc->event_id);
auth_debug(1, _("sec: conn_read_callback: event_wakeup return %d\n"),
revent);
/* delete our 'accept' reference */
if(rval == 0) {
rc->pktlen = 0;
- revent = event_wakeup((event_id_t)rc);
+ revent = event_wakeup((event_id_t)rc->event_id);
auth_debug(1,
_("sec: conn_read_callback: event_wakeup return %d\n"), revent);
return;
/* If there are events waiting on this handle, we're done */
rc->donotclose = 1;
- revent = event_wakeup((event_id_t)rc);
- auth_debug(1, _("sec: conn_read_callback: event_wakeup return %zd\n"), rval);
+ revent = event_wakeup((event_id_t)rc->event_id);
+ auth_debug(1, _("sec: conn_read_callback: event_wakeup return %d\n"), revent);
rc->donotclose = 0;
if (rc->handle == H_TAKEN || rc->pktlen == 0) {
if(rc->refcnt == 0) amfree(rc);
assert(rc->refcnt > 0);
/* If there is no accept fn registered, then drop the packet */
- if (rc->accept_fn == NULL)
+ if (rc->accept_fn == NULL) {
+ g_warning(
+ _("sec: conn_read_callback: %zd bytes for handle %d went unclaimed!"),
+ rc->pktlen, rc->handle);
return;
+ }
- rh = alloc(SIZEOF(*rh));
+ rh = g_new0(struct sec_handle, 1);
security_handleinit(&rh->sech, rc->driver);
rh->hostname = stralloc(rc->hostname);
rh->ev_timeout = NULL;
char *
check_user_amandahosts(
const char * host,
- struct sockaddr_storage *addr,
+ sockaddr_union *addr,
struct passwd * pwd,
const char * remoteuser,
const char * service)
(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,
+ if (SU_GET_FAMILY(addr) == (sa_family_t)AF_INET6)
+ inet_ntop(AF_INET6, &addr->sin6.sin6_addr,
ipstr, sizeof(ipstr));
else
#endif
- inet_ntop(AF_INET, &((struct sockaddr_in *)addr)->sin_addr,
+ inet_ntop(AF_INET, &addr->sin.sin_addr,
ipstr, sizeof(ipstr));
if (strcmp(ipstr, "127.0.0.1") == 0 ||
strcmp(ipstr, "::1") == 0)
if (! found) {
if (strcmp(service, "amindexd") == 0 ||
strcmp(service, "amidxtaped") == 0) {
- result = vstrallocf(_("Please add the line \"%s %s amindexd amidxtaped\" to %s on the client"), host, remoteuser, ptmp);
+ result = vstrallocf(_("Please add the line \"%s %s amindexd amidxtaped\" to %s on the server"), host, remoteuser, ptmp);
} else if (strcmp(service, "amdump") == 0 ||
strcmp(service, "noop") == 0 ||
strcmp(service, "selfcheck") == 0 ||
/* return 1 on success, 0 on failure */
int
check_security(
- struct sockaddr_storage *addr,
+ sockaddr_union *addr,
char * str,
unsigned long cksum,
char ** errstr)
/* next, make sure the remote port is a "reserved" one */
- port = SS_GET_PORT(addr);
+ port = SU_GET_PORT(addr);
if (port >= IPPORT_RESERVED) {
*errstr = vstrallocf(_("[host %s: port %u not secure]"),
remotehost, (unsigned int)port);
return *errstr == NULL;
}
-/*
- * Writes out the entire iovec
- */
-ssize_t
-net_writev(
- int fd,
- struct iovec * iov,
- int iovcnt)
-{
- ssize_t delta, n, total;
-
- assert(iov != NULL);
-
- total = 0;
- while (iovcnt > 0) {
- /*
- * Write the iovec
- */
- n = writev(fd, iov, iovcnt);
- if (n < 0) {
- if (errno != EINTR)
- return (-1);
- auth_debug(1, _("net_writev got EINTR\n"));
- }
- else if (n == 0) {
- errno = EIO;
- return (-1);
- } else {
- total += n;
- /*
- * Iterate through each iov. Figure out what we still need
- * to write out.
- */
- for (; n > 0; iovcnt--, iov++) {
- /* 'delta' is the bytes written from this iovec */
- delta = ((size_t)n < (size_t)iov->iov_len) ? n : (ssize_t)iov->iov_len;
- /* subtract from the total num bytes written */
- n -= delta;
- assert(n >= 0);
- /* subtract from this iovec */
- iov->iov_len -= delta;
- iov->iov_base = (char *)iov->iov_base + delta;
- /* if this iovec isn't empty, run the writev again */
- if (iov->iov_len > 0)
- break;
- }
- }
- }
- return (total);
-}
-
/*
* Like read(), but waits until the entire buffer has been filled.
*/
{
char *name = vstralloc(a, b, NULL);
struct stat sbuf;
- struct passwd *pwptr;
- struct passwd pw;
+ struct passwd *pwptr G_GNUC_UNUSED;
+ struct passwd pw G_GNUC_UNUSED;
char *owner;
- struct group *grptr;
- struct group gr;
+ struct group *grptr G_GNUC_UNUSED;
+ struct group gr G_GNUC_UNUSED;
char *group;
- int buflen;
- char *buf;
+ int buflen G_GNUC_UNUSED;
+ char *buf G_GNUC_UNUSED;
if (stat(name, &sbuf) != 0) {
auth_debug(1, _("bsd: cannot stat %s: %s\n"), name, strerror(errno));
#endif
buf = malloc(buflen);
- if (getpwuid_r(sbuf.st_uid, &pw, buf, buflen, &pwptr) != 0 ||
- pwptr == NULL) {
+#ifdef HAVE_GETPWUID_R
+ if (getpwuid_r(sbuf.st_uid, &pw, buf, buflen, &pwptr) == 0 &&
+ pwptr != NULL) {
+ owner = stralloc(pwptr->pw_name);
+ } else
+#endif
+ {
owner = alloc(NUM_STR_SIZE + 1);
g_snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_uid);
- } else {
- owner = stralloc(pwptr->pw_name);
}
- if (getgrgid_r(sbuf.st_gid, &gr, buf, buflen, &grptr) != 0 ||
- grptr == NULL) {
+#ifdef HAVE_GETGRGID_R
+ if (getgrgid_r(sbuf.st_gid, &gr, buf, buflen, &grptr) == 0 &&
+ grptr != NULL) {
+ group = stralloc(grptr->gr_name);
+ } else
+#endif
+ {
group = alloc(NUM_STR_SIZE + 1);
g_snprintf(group, NUM_STR_SIZE, "%ld", (long)sbuf.st_gid);
- } else {
- group = stralloc(grptr->gr_name);
}
+
auth_debug(1, _("bsd: processing file: %s\n"), name);
auth_debug(1, _("bsd: owner=%s group=%s mode=%03o\n"),
owner, group,
}
for(res1=res; res1 != NULL; res1 = res1->ai_next) {
- if (cmp_sockaddr((struct sockaddr_storage *)res1->ai_addr, (struct sockaddr_storage *)addr, 1) == 0) {
+ if (cmp_sockaddr((sockaddr_union *)res1->ai_addr, (sockaddr_union *)addr, 1) == 0) {
freeaddrinfo(res);
amfree(canonname);
return 0;
}
}
- dbprintf(_("%s doesn't resolve to %s"),
- hostname, str_sockaddr((struct sockaddr_storage *)addr));
+ g_debug("%s doesn't resolve to %s",
+ hostname, str_sockaddr((sockaddr_union *)addr));
*errstr = newvstrallocf(*errstr,
"%s doesn't resolve to %s",
- hostname, str_sockaddr((struct sockaddr_storage *)addr));
+ hostname, str_sockaddr((sockaddr_union *)addr));
error:
if (res) freeaddrinfo(res);
amfree(canonname);
return -1;
}
+
+in_port_t
+find_port_for_service(
+ char *service,
+ char *proto)
+{
+ in_port_t port;
+ char *s;
+ int all_numeric = 1;
+
+ for (s=service; *s != '\0'; s++) {
+ if (!isdigit((int)*s)) {
+ all_numeric = 0;
+ }
+ }
+
+ if (all_numeric == 1) {
+ port = atoi(service);
+ } else {
+ struct servent *sp;
+
+ if ((sp = getservbyname(service, proto)) == NULL) {
+ port = 0;
+ } else {
+ port = (in_port_t)(ntohs((in_port_t)sp->s_port));
+ }
+ }
+
+ return port;
+}
+
+char *
+sec_get_authenticated_peer_name_localhost(
+ security_handle_t *hdl G_GNUC_UNUSED)
+{
+ return "localhost";
+}
+
+char *
+sec_get_authenticated_peer_name_hostname(
+ security_handle_t *hdl)
+{
+ char *hostname = ((struct sec_handle *)hdl)->hostname;
+ if (!hostname)
+ hostname = "";
+ return hostname;
+}