2 * Amanda, The Advanced Maryland Automatic Network Disk Archiver
3 * Copyright (c) 1999 University of Maryland
6 * Permission to use, copy, modify, distribute, and sell this software and its
7 * documentation for any purpose is hereby granted without fee, provided that
8 * the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the name of U.M. not be used in advertising or
11 * publicity pertaining to distribution of the software without specific,
12 * written prior permission. U.M. makes no representations about the
13 * suitability of this software for any purpose. It is provided "as is"
14 * without express or implied warranty.
16 * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M.
18 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
21 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Authors: the Amanda Development Team. Its members are listed in a
24 * file named AUTHORS, in the root directory of this distribution.
28 * $Id: security-util.c,v 1.25 2006/07/22 12:04:47 martinea Exp $
30 * sec-security.c - security and transport over sec or a sec-like command.
32 * XXX still need to check for initial keyword on connect so we can skip
33 * over shell garbage and other stuff that sec might want to spew out.
42 #include "security-util.h"
45 #include "sockaddr-util.h"
48 * Magic values for sec_conn->handle
50 #define H_TAKEN -1 /* sec_conn->tok was already read */
51 #define H_EOF -2 /* this connection has been shut down */
54 * This is a queue of open connections
56 struct connq_s connq = {
57 TAILQ_HEAD_INITIALIZER(connq.tailq), 0
59 static int newhandle = 1;
60 static int newevent = 1;
65 static void recvpkt_callback(void *, void *, ssize_t);
66 static void stream_read_callback(void *);
67 static void stream_read_sync_callback(void *);
69 static void sec_tcp_conn_read_cancel(struct tcp_conn *);
70 static void sec_tcp_conn_read_callback(void *);
74 * Authenticate a stream
75 * Nothing needed for sec. The connection is authenticated by secd
82 (void)s; /* Quiet unused parameter warning */
87 * Returns the stream id for this stream. This is just the local
94 struct sec_stream *rs = s;
102 * Setup to handle new incoming connections
106 const security_driver_t *driver,
107 char *(*conf_fn)(char *, void *),
110 void (*fn)(security_handle_t *, pkt_t *),
115 rc = sec_tcp_conn_get("unknown",0);
120 rc->conf_fn = conf_fn;
122 sec_tcp_conn_read(rc);
126 * frees a handle allocated by the above
132 struct sec_handle *rh = inst;
136 auth_debug(1, _("sec: closing handle to %s\n"), rh->hostname);
138 if (rh->rs != NULL) {
139 /* This may be null if we get here on an error */
140 stream_recvpkt_cancel(rh);
141 security_stream_close(&rh->rs->secstr);
143 /* keep us from getting here again */
144 rh->sech.driver = NULL;
145 amfree(rh->hostname);
150 * Called when a sec connection is finished connecting and is ready
151 * to be authenticated.
154 sec_connect_callback(
157 struct sec_handle *rh = cookie;
159 event_release(rh->rs->ev_read);
160 rh->rs->ev_read = NULL;
161 event_release(rh->ev_timeout);
162 rh->ev_timeout = NULL;
164 (*rh->fn.connect)(rh->arg, &rh->sech, S_OK);
168 * Called if a connection times out before completion.
174 struct sec_handle *rh = cookie;
176 event_release(rh->rs->ev_read);
177 rh->rs->ev_read = NULL;
178 event_release(rh->ev_timeout);
179 rh->ev_timeout = NULL;
181 (*rh->fn.connect)(rh->arg, &rh->sech, S_TIMEOUT);
185 sec_close_connection_none(
206 struct sec_handle *rh = cookie;
213 auth_debug(1, _("sec: stream_sendpkt: enter\n"));
215 if (rh->rc->prefix_packet)
216 s = rh->rc->prefix_packet(rh, pkt);
219 len = strlen(pkt->body) + strlen(s) + 2;
221 buf[0] = (char)pkt->type;
222 strncpy(&buf[1], s, len - 1);
223 strncpy(&buf[1 + strlen(s)], pkt->body, (len - strlen(s) - 1));
228 _("sec: stream_sendpkt: %s (%d) pkt_t (len %zu) contains:\n\n\"%s\"\n\n"),
229 pkt_type2str(pkt->type), pkt->type, strlen(pkt->body), pkt->body);
231 if (security_stream_write(&rh->rs->secstr, buf, len) < 0) {
232 security_seterror(&rh->sech, "%s", security_stream_geterror(&rh->rs->secstr));
241 * Set up to receive a packet asyncronously, and call back when
247 void (*fn)(void *, pkt_t *, security_status_t),
251 struct sec_handle *rh = cookie;
255 auth_debug(1, _("sec: recvpkt registered for %s\n"), rh->hostname);
258 * Reset any pending timeout on this handle
260 if (rh->ev_timeout != NULL)
261 event_release(rh->ev_timeout);
264 * Negative timeouts mean no timeout
267 rh->ev_timeout = NULL;
269 rh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
270 stream_recvpkt_timeout, rh);
274 security_stream_read(&rh->rs->secstr, recvpkt_callback, rh);
278 * This is called when a handle times out before receiving a packet.
281 stream_recvpkt_timeout(
284 struct sec_handle *rh = cookie;
288 auth_debug(1, _("sec: recvpkt timeout for %s\n"), rh->hostname);
290 stream_recvpkt_cancel(rh);
291 (*rh->fn.recvpkt)(rh->arg, NULL, S_TIMEOUT);
295 * Remove a async receive request from the queue
298 stream_recvpkt_cancel(
301 struct sec_handle *rh = cookie;
303 auth_debug(1, _("sec: cancelling recvpkt for %s\n"), rh->hostname);
307 security_stream_read_cancel(&rh->rs->secstr);
308 if (rh->ev_timeout != NULL) {
309 event_release(rh->ev_timeout);
310 rh->ev_timeout = NULL;
315 * Write a chunk of data to a stream. Blocks until completion.
323 struct sec_stream *rs = s;
326 assert(rs->rc != NULL);
328 auth_debug(1, _("sec: stream_write: writing %zu bytes to %s:%d %d\n"),
329 size, rs->rc->hostname, rs->handle,
332 if (tcpm_send_token(rs->rc, rs->rc->write, rs->handle, &rs->rc->errmsg,
334 security_stream_seterror(&rs->secstr, "%s", rs->rc->errmsg);
341 * Submit a request to read some data. Calls back with the given
342 * function and arg when completed.
347 void (*fn)(void *, void *, ssize_t),
350 struct sec_stream *rs = s;
355 * Only one read request can be active per stream.
357 if (rs->ev_read == NULL) {
358 rs->ev_read = event_register((event_id_t)rs->rc->event_id, EV_WAIT,
359 stream_read_callback, rs);
360 sec_tcp_conn_read(rs->rc);
367 * Write a chunk of data to a stream. Blocks until completion.
370 tcpm_stream_read_sync(
374 struct sec_stream *rs = s;
379 * Only one read request can be active per stream.
381 if (rs->ev_read != NULL) {
384 rs->ev_read = event_register((event_id_t)rs->rc->event_id, EV_WAIT,
385 stream_read_sync_callback, rs);
386 sec_tcp_conn_read(rs->rc);
387 event_wait(rs->ev_read);
389 return (rs->rc->pktlen);
393 * Cancel a previous stream read request. It's ok if we didn't have a read
397 tcpm_stream_read_cancel(
400 struct sec_stream *rs = s;
404 if (rs->ev_read != NULL) {
405 event_release(rs->ev_read);
407 sec_tcp_conn_read_cancel(rs->rc);
412 * Transmits a chunk of data over a rsh_handle, adding
413 * the necessary headers to allow the remote end to decode it.
432 assert(SIZEOF(netlength) == 4);
434 auth_debug(1, "tcpm_send_token: write %zd bytes to handle %d\n",
438 * 32 bit length (network byte order)
439 * 32 bit handle (network byte order)
442 netlength = htonl(len);
443 iov[0].iov_base = (void *)&netlength;
444 iov[0].iov_len = SIZEOF(netlength);
446 nethandle = htonl((guint32)handle);
447 iov[1].iov_base = (void *)&nethandle;
448 iov[1].iov_len = SIZEOF(nethandle);
450 encbuf = (char *)buf;
457 if (rc->driver->data_encrypt == NULL) {
458 iov[2].iov_base = (void *)buf;
459 iov[2].iov_len = len;
461 /* (the extra (void *) cast is to quiet type-punning warnings) */
462 rc->driver->data_encrypt(rc, (void *)buf, len, (void **)(void *)&encbuf, &encsize);
463 iov[2].iov_base = (void *)encbuf;
464 iov[2].iov_len = encsize;
465 netlength = htonl(encsize);
470 rval = full_writev(fd, iov, nb_iov);
471 if (len != 0 && rc->driver->data_encrypt != NULL && buf != encbuf) {
477 *errmsg = newvstrallocf(*errmsg, _("write error to: %s"),
486 * return 0 on EOF: *handle = H_EOF && *size = 0 if socket closed
487 * return 0 on EOF: *handle = handle && *size = 0 if stream closed
488 * return size : *handle = handle && *size = size for data read
501 unsigned int netint[2];
503 assert(SIZEOF(netint) == 8);
505 switch (net_read(fd, &netint, SIZEOF(netint), timeout)) {
508 *errmsg = newvstrallocf(*errmsg, _("recv error: %s"), strerror(errno));
509 auth_debug(1, _("tcpm_recv_token: A return(-1)\n"));
514 *errmsg = newvstrallocf(*errmsg, _("SOCKET_EOF"));
515 auth_debug(1, _("tcpm_recv_token: A return(0)\n"));
521 *size = (ssize_t)ntohl(netint[0]);
522 *handle = (int)ntohl(netint[1]);
523 /* amanda protocol packet can be above NETWORK_BLOCK_BYTES */
524 if (*size > 128*NETWORK_BLOCK_BYTES || *size < 0) {
525 if (isprint((int)(*size ) & 0xFF) &&
526 isprint((int)(*size >> 8 ) & 0xFF) &&
527 isprint((int)(*size >> 16) & 0xFF) &&
528 isprint((int)(*size >> 24) & 0xFF) &&
529 isprint((*handle ) & 0xFF) &&
530 isprint((*handle >> 8 ) & 0xFF) &&
531 isprint((*handle >> 16) & 0xFF) &&
532 isprint((*handle >> 24) & 0xFF)) {
535 s[0] = ((int)(*size) >> 24) & 0xFF;
536 s[1] = ((int)(*size) >> 16) & 0xFF;
537 s[2] = ((int)(*size) >> 8) & 0xFF;
538 s[3] = ((int)(*size) ) & 0xFF;
539 s[4] = (*handle >> 24) & 0xFF;
540 s[5] = (*handle >> 16) & 0xFF;
541 s[6] = (*handle >> 8 ) & 0xFF;
542 s[7] = (*handle ) & 0xFF;
544 while(i<100 && isprint((int)s[i]) && s[i] != '\n') {
545 switch(net_read(fd, &s[i], 1, 0)) {
546 case -1: s[i] = '\0'; break;
547 case 0: s[i] = '\0'; break;
549 dbprintf(_("read: %c\n"), s[i]); i++; s[i]=' ';
554 *errmsg = newvstrallocf(*errmsg, _("tcpm_recv_token: invalid size: %s"), s);
555 dbprintf(_("tcpm_recv_token: invalid size %s\n"), s);
557 *errmsg = newvstrallocf(*errmsg, _("tcpm_recv_token: invalid size"));
558 dbprintf(_("tcpm_recv_token: invalid size %zd\n"), *size);
564 *buf = alloc((size_t)*size);
567 auth_debug(1, _("tcpm_recv_token: read EOF from %d\n"), *handle);
568 *errmsg = newvstrallocf(*errmsg, _("EOF"));
571 switch (net_read(fd, *buf, (size_t)*size, timeout)) {
574 *errmsg = newvstrallocf(*errmsg, _("recv error: %s"), strerror(errno));
575 auth_debug(1, _("tcpm_recv_token: B return(-1)\n"));
579 *errmsg = newvstrallocf(*errmsg, _("SOCKET_EOF"));
580 auth_debug(1, _("tcpm_recv_token: B return(0)\n"));
586 auth_debug(1, _("tcpm_recv_token: read %zd bytes from %d\n"), *size, *handle);
588 if (*size > 0 && rc->driver->data_decrypt != NULL) {
591 rc->driver->data_decrypt(rc, *buf, *size, &decbuf, &decsize);
592 if (*buf != (char *)decbuf) {
594 *buf = (char *)decbuf;
603 tcpm_close_connection(
607 struct sec_handle *rh = h;
611 if (rh && rh->rc && rh->rc->read >= 0 && rh->rc->toclose == 0) {
613 sec_tcp_conn_put(rh->rc);
620 * Accept an incoming connection on a stream_server socket
621 * Nothing needed for tcpma.
627 (void)s; /* Quiet unused parameter warning */
633 * Return a connected stream. For sec, this means setup a stream
634 * with the supplied handle.
641 struct sec_handle *rh = h;
642 struct sec_stream *rs;
647 security_seterror(&rh->sech,
648 _("%d: invalid security stream id"), id);
652 rs = alloc(SIZEOF(*rs));
653 security_streaminit(&rs->secstr, rh->sech.driver);
656 rs->closed_by_me = 0;
657 rs->closed_by_network = 0;
663 rs->rc = sec_tcp_conn_get(rh->hostname, 0);
664 rs->rc->driver = rh->sech.driver;
668 auth_debug(1, _("sec: stream_client: connected to stream %d\n"), id);
674 * Create the server end of a stream. For sec, this means setup a stream
675 * object and allocate a new handle for it.
681 struct sec_handle *rh = h;
682 struct sec_stream *rs;
686 rs = alloc(SIZEOF(*rs));
687 security_streaminit(&rs->secstr, rh->sech.driver);
688 rs->closed_by_me = 0;
689 rs->closed_by_network = 0;
695 rs->rc = sec_tcp_conn_get(rh->hostname, 0);
696 rs->rc->driver = rh->sech.driver;
700 * Stream should already be setup!
702 if (rs->rc->read < 0) {
703 sec_tcp_conn_put(rs->rc);
705 security_seterror(&rh->sech, _("lost connection to %s"), rh->hostname);
708 assert(strcmp(rh->hostname, rs->rc->hostname) == 0);
710 * so as not to conflict with the amanda server's handle numbers,
711 * we start at 500000 and work down
713 rs->handle = 500000 - newhandle++;
715 auth_debug(1, _("sec: stream_server: created stream %d\n"), rs->handle);
720 * Close and unallocate resources for a stream.
726 struct sec_stream *rs = s;
731 auth_debug(1, _("sec: tcpma_stream_close: closing stream %d\n"), rs->handle);
733 if(rs->closed_by_network == 0 && rs->rc->write != -1)
734 tcpm_stream_write(rs, &buf, 0);
735 security_stream_read_cancel(&rs->secstr);
736 if(rs->closed_by_network == 0)
737 sec_tcp_conn_put(rs->rc);
742 * Create the server end of a stream. For bsdudp, this means setup a tcp
743 * socket for receiving a connection.
749 struct sec_stream *rs = NULL;
750 struct sec_handle *rh = h;
754 rs = alloc(SIZEOF(*rs));
755 security_streaminit(&rs->secstr, rh->sech.driver);
756 rs->closed_by_me = 0;
757 rs->closed_by_network = 0;
760 rs->handle = 500000 - newhandle++;
762 rs->socket = 0; /* the socket is already opened */
765 rh->rc = sec_tcp_conn_get(rh->hostname, 1);
766 rh->rc->driver = rh->sech.driver;
768 rs->socket = stream_server(SU_GET_FAMILY(&rh->udp->peer), &rs->port,
769 STREAM_BUFSIZE, STREAM_BUFSIZE, 0);
770 if (rs->socket < 0) {
771 security_seterror(&rh->sech,
772 _("can't create server stream: %s"), strerror(errno));
776 rh->rc->read = rs->socket;
777 rh->rc->write = rs->socket;
778 rs->handle = (int)rs->port;
786 * Accepts a new connection on unconnected streams. Assumes it is ok to
793 struct sec_stream *bs = s;
796 assert(bs->socket != -1);
799 if (bs->socket > 0) {
800 bs->fd = stream_accept(bs->socket, 30, STREAM_BUFSIZE, STREAM_BUFSIZE);
802 security_stream_seterror(&bs->secstr,
803 _("can't accept new stream connection: %s"),
807 bs->rc->read = bs->fd;
808 bs->rc->write = bs->fd;
814 * Return a connected stream
821 struct sec_stream *rs = NULL;
822 struct sec_handle *rh = h;
826 rs = alloc(SIZEOF(*rs));
827 security_streaminit(&rs->secstr, rh->sech.driver);
830 rs->closed_by_me = 0;
831 rs->closed_by_network = 0;
837 rh->rc = sec_tcp_conn_get(rh->hostname, 1);
838 rh->rc->driver = rh->sech.driver;
840 rh->rc->read = stream_client(rh->hostname, (in_port_t)id,
841 STREAM_BUFSIZE, STREAM_BUFSIZE, &rs->port, 0);
842 if (rh->rc->read < 0) {
843 security_seterror(&rh->sech,
844 _("can't connect stream to %s port %d: %s"),
845 rh->hostname, id, strerror(errno));
849 rh->rc->write = rh->rc->read;
851 rs->socket = -1; /* we're a client */
862 struct sec_stream *rs = s;
866 if (full_write(rs->fd, buf, size) < size) {
867 security_stream_seterror(&rs->secstr,
868 _("write error on stream %d: %s"), rs->port, strerror(errno));
879 struct sec_handle *rh = h;
883 if (pkt->type != P_REQ)
886 if ((pwd = getpwuid(getuid())) == NULL) {
887 security_seterror(&rh->sech,
888 _("can't get login name for my uid %ld"),
892 buf = alloc(16+strlen(pwd->pw_name));
893 strncpy(buf, "SECURITY USER ", (16 + strlen(pwd->pw_name)));
894 strncpy(&buf[14], pwd->pw_name, (16 + strlen(pwd->pw_name) - 14));
895 buf[14 + strlen(pwd->pw_name)] = '\n';
896 buf[15 + strlen(pwd->pw_name)] = '\0';
903 * Check the security of a received packet. Returns negative on security
904 * violation, or returns 0 if ok. Removes the security info from the pkt_t.
907 bsd_recv_security_ok(
908 struct sec_handle * rh,
911 char *tok, *security, *body, *result;
912 char *service = NULL, *serviceX, *serviceY;
919 * Now, find the SECURITY line in the body, and parse it out
922 if (strncmp_const(pkt->body, "SECURITY ") == 0) {
923 security = pkt->body;
925 while(*security != '\n' && len < pkt->size) {
929 if(*security == '\n') {
932 security_line = stralloc(pkt->body);
933 security = pkt->body + strlen("SECURITY ");
936 security_line = NULL;
941 security_line = NULL;
946 * Now, find the SERVICE line in the body, and parse it out
950 if (strncmp_const_skip(s, "SERVICE ", s, ch) == 0) {
951 serviceX = stralloc(s);
952 serviceY = strtok(serviceX, "\n");
954 service = stralloc(serviceY);
959 * We need to do different things depending on which type of packet
965 * Request packets must come from a reserved port
967 port = SU_GET_PORT(&rh->peer);
968 if (port >= IPPORT_RESERVED) {
969 security_seterror(&rh->sech,
970 _("host %s: port %u not secure"), rh->hostname,
973 amfree(security_line);
978 security_seterror(&rh->sech,
979 _("packet as no SERVICE line"));
980 amfree(security_line);
985 * Request packets contain a remote username. We need to check
986 * that we allow it in.
988 * They will look like:
989 * SECURITY USER [username]
992 /* there must be some security info */
993 if (security == NULL) {
994 security_seterror(&rh->sech,
995 _("no bsd SECURITY for P_REQ"));
1000 /* second word must be USER */
1001 if ((tok = strtok(security, " ")) == NULL) {
1002 security_seterror(&rh->sech,
1003 _("SECURITY line: %s"), security_line);
1005 amfree(security_line);
1006 return (-1); /* default errmsg */
1008 if (strcmp(tok, "USER") != 0) {
1009 security_seterror(&rh->sech,
1010 _("REQ SECURITY line parse error, expecting USER, got %s"), tok);
1012 amfree(security_line);
1016 /* the third word is the username */
1017 if ((tok = strtok(NULL, "")) == NULL) {
1018 security_seterror(&rh->sech,
1019 _("SECURITY line: %s"), security_line);
1021 amfree(security_line);
1022 return (-1); /* default errmsg */
1024 if ((result = check_user(rh, tok, service)) != NULL) {
1025 security_seterror(&rh->sech, "%s", result);
1028 amfree(security_line);
1032 /* we're good to go */
1038 amfree(security_line);
1041 * If there is security info at the front of the packet, we need to
1042 * shift the rest of the data up and nuke it.
1044 if (body != pkt->body)
1045 memmove(pkt->body, body, strlen(body) + 1);
1050 * Transmit a packet. Add security information first.
1057 struct sec_handle *rh = cookie;
1061 assert(pkt != NULL);
1063 auth_debug(1, _("udpbsd_sendpkt: enter\n"));
1065 * Initialize this datagram, and add the header
1067 dgram_zero(&rh->udp->dgram);
1068 dgram_cat(&rh->udp->dgram, "%s", pkthdr2str(rh, pkt));
1071 * Add the security info. This depends on which kind of packet we're
1074 switch (pkt->type) {
1077 * Requests get sent with our username in the body
1079 if ((pwd = getpwuid(geteuid())) == NULL) {
1080 security_seterror(&rh->sech,
1081 _("can't get login name for my uid %ld"), (long)getuid());
1084 dgram_cat(&rh->udp->dgram, _("SECURITY USER %s\n"), pwd->pw_name);
1092 * Add the body, and send it
1094 dgram_cat(&rh->udp->dgram, "%s", pkt->body);
1097 _("sec: udpbsd_sendpkt: %s (%d) pkt_t (len %zu) contains:\n\n\"%s\"\n\n"),
1098 pkt_type2str(pkt->type), pkt->type, strlen(pkt->body), pkt->body);
1100 if (dgram_send_addr(&rh->peer, &rh->udp->dgram) != 0) {
1101 security_seterror(&rh->sech,
1102 _("send %s to %s failed: %s"), pkt_type2str(pkt->type),
1103 rh->hostname, strerror(errno));
1113 struct sec_handle *rh = cookie;
1115 if (rh->proto_handle == NULL) {
1119 auth_debug(1, _("udp: close handle '%s'\n"), rh->proto_handle);
1121 udp_recvpkt_cancel(rh);
1123 rh->next->prev = rh->prev;
1126 rh->udp->bh_last = rh->prev;
1129 rh->prev->next = rh->next;
1132 rh->udp->bh_first = rh->next;
1135 amfree(rh->proto_handle);
1136 amfree(rh->hostname);
1141 * Set up to receive a packet asynchronously, and call back when it has
1147 void (*fn)(void *, pkt_t *, security_status_t),
1151 struct sec_handle *rh = cookie;
1153 auth_debug(1, _("udp_recvpkt(cookie=%p, fn=%p, arg=%p, timeout=%u)\n"),
1154 cookie, fn, arg, timeout);
1160 * Subsequent recvpkt calls override previous ones
1162 if (rh->ev_read == NULL) {
1163 udp_addref(rh->udp, &udp_netfd_read_callback);
1164 rh->ev_read = event_register(rh->event_id, EV_WAIT,
1165 udp_recvpkt_callback, rh);
1167 if (rh->ev_timeout != NULL)
1168 event_release(rh->ev_timeout);
1170 rh->ev_timeout = NULL;
1172 rh->ev_timeout = event_register((event_id_t)timeout, EV_TIME,
1173 udp_recvpkt_timeout, rh);
1174 rh->fn.recvpkt = fn;
1179 * Remove a async receive request on this handle from the queue.
1180 * If it is the last one to be removed, then remove the event
1181 * handler for our network fd
1187 struct sec_handle *rh = cookie;
1191 if (rh->ev_read != NULL) {
1192 udp_delref(rh->udp);
1193 event_release(rh->ev_read);
1197 if (rh->ev_timeout != NULL) {
1198 event_release(rh->ev_timeout);
1199 rh->ev_timeout = NULL;
1204 * This is called when a handle is woken up because data read off of the
1208 udp_recvpkt_callback(
1211 struct sec_handle *rh = cookie;
1212 void (*fn)(void *, pkt_t *, security_status_t);
1215 auth_debug(1, _("udp: receive handle '%s' netfd '%s'\n"),
1216 rh->proto_handle, rh->udp->handle);
1219 /* if it doesn't correspond to this handle, something is wrong */
1220 assert(strcmp(rh->proto_handle, rh->udp->handle) == 0);
1222 /* if it didn't come from the same host/port, forget it */
1223 if (cmp_sockaddr(&rh->peer, &rh->udp->peer, 0) != 0) {
1224 amfree(rh->udp->handle);
1225 dbprintf(_("not from same host\n"));
1226 dump_sockaddr(&rh->peer);
1227 dump_sockaddr(&rh->udp->peer);
1232 * We need to cancel the recvpkt request before calling the callback
1233 * because the callback may reschedule us.
1235 fn = rh->fn.recvpkt;
1237 udp_recvpkt_cancel(rh);
1240 * Check the security of the packet. If it is bad, then pass NULL
1241 * to the packet handling function instead of a packet.
1243 if (rh->udp->recv_security_ok &&
1244 rh->udp->recv_security_ok(rh, &rh->udp->pkt) < 0) {
1245 (*fn)(arg, NULL, S_ERROR);
1247 (*fn)(arg, &rh->udp->pkt, S_OK);
1252 * This is called when a handle times out before receiving a packet.
1255 udp_recvpkt_timeout(
1258 struct sec_handle *rh = cookie;
1259 void (*fn)(void *, pkt_t *, security_status_t);
1264 assert(rh->ev_timeout != NULL);
1265 fn = rh->fn.recvpkt;
1267 udp_recvpkt_cancel(rh);
1268 (*fn)(arg, NULL, S_TIMEOUT);
1272 * Given a hostname and a port, setup a udp_handle
1277 struct sec_handle * rh,
1279 sockaddr_union *addr,
1285 * Save the hostname and port info
1287 auth_debug(1, _("udp_inithandle port %u handle %s sequence %d\n"),
1288 (unsigned int)ntohs(port), handle, sequence);
1289 assert(addr != NULL);
1291 rh->hostname = stralloc(hostname);
1292 copy_sockaddr(&rh->peer, addr);
1293 SU_SET_PORT(&rh->peer, port);
1296 rh->prev = udp->bh_last;
1298 rh->prev->next = rh;
1300 if (!udp->bh_first) {
1306 rh->sequence = sequence;
1307 rh->event_id = (event_id_t)newevent++;
1308 amfree(rh->proto_handle);
1309 rh->proto_handle = stralloc(handle);
1310 rh->fn.connect = NULL;
1313 rh->ev_timeout = NULL;
1315 auth_debug(1, _("udp: adding handle '%s'\n"), rh->proto_handle);
1322 * Callback for received packets. This is the function bsd_recvpkt
1323 * registers with the event handler. It is called when the event handler
1324 * realizes that data is waiting to be read on the network socket.
1327 udp_netfd_read_callback(
1330 struct udp_handle *udp = cookie;
1331 struct sec_handle *rh;
1333 char hostname[NI_MAXHOST];
1335 char *errmsg = NULL;
1338 auth_debug(1, _("udp_netfd_read_callback(cookie=%p)\n"), cookie);
1339 assert(udp != NULL);
1341 #ifndef TEST /* { */
1343 * Receive the packet.
1345 dgram_zero(&udp->dgram);
1346 if (dgram_recv(&udp->dgram, 0, &udp->peer) < 0)
1348 #endif /* !TEST */ /* } */
1353 if (str2pkthdr(udp) < 0)
1357 * If there are events waiting on this handle, we're done
1360 while(rh != NULL && (strcmp(rh->proto_handle, udp->handle) != 0 ||
1361 rh->sequence != udp->sequence ||
1362 cmp_sockaddr(&rh->peer, &udp->peer, 0) != 0)) {
1365 if (rh && event_wakeup(rh->event_id) > 0)
1369 * If we didn't find a handle, then check for a new incoming packet.
1370 * If no accept handler was setup, then just return.
1372 if (udp->accept_fn == NULL) {
1373 dbprintf(_("Receive packet from unknown source"));
1377 rh = alloc(SIZEOF(*rh));
1378 rh->proto_handle=NULL;
1381 security_handleinit(&rh->sech, udp->driver);
1383 result = getnameinfo((struct sockaddr *)&udp->peer, SS_LEN(&udp->peer),
1384 hostname, sizeof(hostname), NULL, 0, 0);
1386 dbprintf("getnameinfo failed: %s\n",
1387 gai_strerror(result));
1388 security_seterror(&rh->sech, "getnameinfo failed: %s",
1389 gai_strerror(result));
1392 if (check_name_give_sockaddr(hostname,
1393 (struct sockaddr *)&udp->peer, &errmsg) < 0) {
1394 security_seterror(&rh->sech, "%s",errmsg);
1400 port = SU_GET_PORT(&udp->peer);
1401 a = udp_inithandle(udp, rh,
1408 auth_debug(1, _("bsd: closeX handle '%s'\n"), rh->proto_handle);
1414 * Check the security of the packet. If it is bad, then pass NULL
1415 * to the accept function instead of a packet.
1417 if (rh->udp->recv_security_ok(rh, &udp->pkt) < 0)
1418 (*udp->accept_fn)(&rh->sech, NULL);
1420 (*udp->accept_fn)(&rh->sech, &udp->pkt);
1424 * Locate an existing connection to the given host, or create a new,
1425 * unconnected entry if none exists. The caller is expected to check
1426 * for the lack of a connection (rc->read == -1) and set one up.
1430 const char *hostname,
1433 struct tcp_conn *rc;
1435 auth_debug(1, _("sec_tcp_conn_get: %s\n"), hostname);
1437 if (want_new == 0) {
1438 for (rc = connq_first(); rc != NULL; rc = connq_next(rc)) {
1439 if (strcasecmp(hostname, rc->hostname) == 0)
1446 _("sec_tcp_conn_get: exists, refcnt to %s is now %d\n"),
1447 rc->hostname, rc->refcnt);
1452 auth_debug(1, _("sec_tcp_conn_get: creating new handle\n"));
1454 * We can't be creating a new handle if we are the client
1456 rc = alloc(SIZEOF(*rc));
1457 rc->read = rc->write = -1;
1463 strncpy(rc->hostname, hostname, SIZEOF(rc->hostname) - 1);
1464 rc->hostname[SIZEOF(rc->hostname) - 1] = '\0';
1469 rc->accept_fn = NULL;
1470 rc->recv_security_ok = NULL;
1471 rc->prefix_packet = NULL;
1475 rc->event_id = newevent++;
1481 * Delete a reference to a connection, and close it if it is the last
1486 struct tcp_conn * rc)
1490 assert(rc->refcnt > 0);
1492 auth_debug(1, _("sec_tcp_conn_put: decrementing refcnt for %s to %d\n"),
1493 rc->hostname, rc->refcnt);
1494 if (rc->refcnt > 0) {
1497 auth_debug(1, _("sec_tcp_conn_put: closing connection to %s\n"), rc->hostname);
1500 if (rc->write != -1)
1502 if (rc->pid != -1) {
1503 waitpid(rc->pid, &status, WNOHANG);
1505 if (rc->ev_read != NULL)
1506 event_release(rc->ev_read);
1507 if (rc->errmsg != NULL)
1511 if(!rc->donotclose) {
1513 /* a memory leak occurs, but freeing it lead to memory
1514 * corruption because it can still be used.
1515 * We need to find a good place to free 'rc'.
1521 * Turn on read events for a conn. Or, increase a ev_read_refcnt if we are
1522 * already receiving read events.
1526 struct tcp_conn * rc)
1528 assert (rc != NULL);
1530 if (rc->ev_read != NULL) {
1531 rc->ev_read_refcnt++;
1533 _("sec: conn_read: incremented ev_read_refcnt to %d for %s\n"),
1534 rc->ev_read_refcnt, rc->hostname);
1537 auth_debug(1, _("sec: conn_read registering event handler for %s\n"),
1539 rc->ev_read = event_register((event_id_t)rc->read, EV_READFD,
1540 sec_tcp_conn_read_callback, rc);
1541 rc->ev_read_refcnt = 1;
1545 sec_tcp_conn_read_cancel(
1546 struct tcp_conn * rc)
1549 --rc->ev_read_refcnt;
1551 _("sec: conn_read_cancel: decremented ev_read_refcnt to %d for %s\n"),
1552 rc->ev_read_refcnt, rc->hostname);
1553 if (rc->ev_read_refcnt > 0) {
1557 _("sec: conn_read_cancel: releasing event handler for %s\n"),
1559 event_release(rc->ev_read);
1564 * This is called when a handle is woken up because data read off of the
1574 struct sec_handle *rh = cookie;
1578 auth_debug(1, _("sec: recvpkt_callback: %zd\n"), bufsize);
1580 * We need to cancel the recvpkt request before calling
1581 * the callback because the callback may reschedule us.
1583 stream_recvpkt_cancel(rh);
1587 security_seterror(&rh->sech,
1588 _("EOF on read from %s"), rh->hostname);
1589 (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
1592 security_seterror(&rh->sech, "%s", security_stream_geterror(&rh->rs->secstr));
1593 (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
1599 parse_pkt(&pkt, buf, (size_t)bufsize);
1601 _("sec: received %s packet (%d) from %s, contains:\n\n\"%s\"\n\n"),
1602 pkt_type2str(pkt.type), pkt.type,
1603 rh->hostname, pkt.body);
1604 if (rh->rc->recv_security_ok && (rh->rc->recv_security_ok)(rh, &pkt) < 0)
1605 (*rh->fn.recvpkt)(rh->arg, NULL, S_ERROR);
1607 (*rh->fn.recvpkt)(rh->arg, &pkt, S_OK);
1612 * Callback for tcpm_stream_read_sync
1615 stream_read_sync_callback(
1618 struct sec_stream *rs = s;
1621 auth_debug(1, _("sec: stream_read_callback_sync: handle %d\n"), rs->handle);
1624 * Make sure this was for us. If it was, then blow away the handle
1625 * so it doesn't get claimed twice. Otherwise, leave it alone.
1627 * If the handle is EOF, pass that up to our callback.
1629 if (rs->rc->handle == rs->handle) {
1630 auth_debug(1, _("sec: stream_read_callback_sync: it was for us\n"));
1631 rs->rc->handle = H_TAKEN;
1632 } else if (rs->rc->handle != H_EOF) {
1633 auth_debug(1, _("sec: stream_read_callback_sync: not for us\n"));
1638 * Remove the event first, and then call the callback.
1639 * We remove it first because we don't want to get in their
1640 * way if they reschedule it.
1642 tcpm_stream_read_cancel(rs);
1644 if (rs->rc->pktlen <= 0) {
1645 auth_debug(1, _("sec: stream_read_sync_callback: %s\n"), rs->rc->errmsg);
1646 security_stream_seterror(&rs->secstr, "%s", rs->rc->errmsg);
1647 if(rs->closed_by_me == 0 && rs->closed_by_network == 0)
1648 sec_tcp_conn_put(rs->rc);
1649 rs->closed_by_network = 1;
1653 _("sec: stream_read_callback_sync: read %zd bytes from %s:%d\n"),
1654 rs->rc->pktlen, rs->rc->hostname, rs->handle);
1658 * Callback for tcpm_stream_read
1661 stream_read_callback(
1664 struct sec_stream *rs = arg;
1667 auth_debug(1, _("sec: stream_read_callback: handle %d\n"), rs->handle);
1670 * Make sure this was for us. If it was, then blow away the handle
1671 * so it doesn't get claimed twice. Otherwise, leave it alone.
1673 * If the handle is EOF, pass that up to our callback.
1675 if (rs->rc->handle == rs->handle) {
1676 auth_debug(1, _("sec: stream_read_callback: it was for us\n"));
1677 rs->rc->handle = H_TAKEN;
1678 } else if (rs->rc->handle != H_EOF) {
1679 auth_debug(1, _("sec: stream_read_callback: not for us\n"));
1684 * Remove the event first, and then call the callback.
1685 * We remove it first because we don't want to get in their
1686 * way if they reschedule it.
1688 tcpm_stream_read_cancel(rs);
1690 if (rs->rc->pktlen <= 0) {
1691 auth_debug(1, _("sec: stream_read_callback: %s\n"), rs->rc->errmsg);
1692 security_stream_seterror(&rs->secstr, "%s", rs->rc->errmsg);
1693 if(rs->closed_by_me == 0 && rs->closed_by_network == 0)
1694 sec_tcp_conn_put(rs->rc);
1695 rs->closed_by_network = 1;
1696 (*rs->fn)(rs->arg, NULL, rs->rc->pktlen);
1699 auth_debug(1, _("sec: stream_read_callback: read %zd bytes from %s:%d\n"),
1700 rs->rc->pktlen, rs->rc->hostname, rs->handle);
1701 (*rs->fn)(rs->arg, rs->rc->pkt, rs->rc->pktlen);
1702 auth_debug(1, _("sec: after callback stream_read_callback\n"));
1706 * The callback for the netfd for the event handler
1707 * Determines if this packet is for this security handle,
1708 * and does the real callback if so.
1711 sec_tcp_conn_read_callback(
1714 struct tcp_conn * rc = cookie;
1715 struct sec_handle * rh;
1720 assert(cookie != NULL);
1722 auth_debug(1, _("sec: conn_read_callback\n"));
1724 /* Read the data off the wire. If we get errors, shut down. */
1725 rval = tcpm_recv_token(rc, rc->read, &rc->handle, &rc->errmsg, &rc->pkt,
1727 auth_debug(1, _("sec: conn_read_callback: tcpm_recv_token returned %zd\n"),
1729 if (rval < 0 || rc->handle == H_EOF) {
1732 revent = event_wakeup((event_id_t)rc->event_id);
1733 auth_debug(1, _("sec: conn_read_callback: event_wakeup return %d\n"),
1735 /* delete our 'accept' reference */
1736 if (rc->accept_fn != NULL) {
1737 if(rc->refcnt != 1) {
1738 dbprintf(_("STRANGE, rc->refcnt should be 1, it is %d\n"),
1742 rc->accept_fn = NULL;
1743 sec_tcp_conn_put(rc);
1750 revent = event_wakeup((event_id_t)rc->event_id);
1752 _("sec: conn_read_callback: event_wakeup return %d\n"), revent);
1756 /* If there are events waiting on this handle, we're done */
1758 revent = event_wakeup((event_id_t)rc->event_id);
1759 auth_debug(1, _("sec: conn_read_callback: event_wakeup return %d\n"), revent);
1761 if (rc->handle == H_TAKEN || rc->pktlen == 0) {
1762 if(rc->refcnt == 0) amfree(rc);
1766 assert(rc->refcnt > 0);
1768 /* If there is no accept fn registered, then drop the packet */
1769 if (rc->accept_fn == NULL) {
1771 _("sec: conn_read_callback: %zd bytes for handle %d went unclaimed!"),
1772 rc->pktlen, rc->handle);
1776 rh = alloc(SIZEOF(*rh));
1777 security_handleinit(&rh->sech, rc->driver);
1778 rh->hostname = stralloc(rc->hostname);
1779 rh->ev_timeout = NULL;
1781 rh->peer = rc->peer;
1782 rh->rs = tcpma_stream_client(rh, rc->handle);
1784 auth_debug(1, _("sec: new connection\n"));
1786 parse_pkt(&pkt, rc->pkt, (size_t)rc->pktlen);
1787 auth_debug(1, _("sec: calling accept_fn\n"));
1788 if (rh->rc->recv_security_ok && (rh->rc->recv_security_ok)(rh, &pkt) < 0)
1789 (*rc->accept_fn)(&rh->sech, NULL);
1791 (*rc->accept_fn)(&rh->sech, &pkt);
1801 const unsigned char *bufp = buf;
1803 auth_debug(1, _("sec: parse_pkt: parsing buffer of %zu bytes\n"), bufsize);
1805 pkt->type = (pktype_t)*bufp++;
1808 pkt->packet_size = bufsize+1;
1809 pkt->body = alloc(pkt->packet_size);
1811 pkt->body[0] = '\0';
1813 memcpy(pkt->body, bufp, bufsize);
1814 pkt->body[pkt->packet_size - 1] = '\0';
1816 pkt->size = strlen(pkt->body);
1818 auth_debug(1, _("sec: parse_pkt: %s (%d): \"%s\"\n"), pkt_type2str(pkt->type),
1819 pkt->type, pkt->body);
1823 * Convert a packet header into a string
1827 const struct sec_handle * rh,
1830 static char retbuf[256];
1833 assert(pkt != NULL);
1835 g_snprintf(retbuf, SIZEOF(retbuf), _("Amanda %d.%d %s HANDLE %s SEQ %d\n"),
1836 VERSION_MAJOR, VERSION_MINOR, pkt_type2str(pkt->type),
1837 rh->proto_handle, rh->sequence);
1839 auth_debug(1, _("bsd: pkthdr2str handle '%s'\n"), rh->proto_handle);
1841 /* check for truncation. If only we had asprintf()... */
1842 assert(retbuf[strlen(retbuf) - 1] == '\n');
1848 * Parses out the header line in 'str' into the pkt and handle
1849 * Returns negative on parse error.
1861 assert(udp->dgram.cur != NULL);
1862 str = stralloc(udp->dgram.cur);
1864 /* "Amanda %d.%d <ACK,NAK,...> HANDLE %s SEQ %d\n" */
1866 /* Read in "Amanda" */
1867 if ((tok = strtok(str, " ")) == NULL || strcmp(tok, "Amanda") != 0)
1870 /* nothing is done with the major/minor numbers currently */
1871 if ((tok = strtok(NULL, " ")) == NULL || strchr(tok, '.') == NULL)
1874 /* Read in the packet type */
1875 if ((tok = strtok(NULL, " ")) == NULL)
1878 pkt_init_empty(pkt, pkt_str2type(tok));
1879 if (pkt->type == (pktype_t)-1)
1882 /* Read in "HANDLE" */
1883 if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "HANDLE") != 0)
1886 /* parse the handle */
1887 if ((tok = strtok(NULL, " ")) == NULL)
1889 amfree(udp->handle);
1890 udp->handle = stralloc(tok);
1893 if ((tok = strtok(NULL, " ")) == NULL || strcmp(tok, "SEQ") != 0)
1896 /* parse the sequence number */
1897 if ((tok = strtok(NULL, "\n")) == NULL)
1899 udp->sequence = atoi(tok);
1901 /* Save the body, if any */
1902 if ((tok = strtok(NULL, "")) != NULL)
1903 pkt_cat(pkt, "%s", tok);
1909 #if 0 /* XXX we have no way of passing this back up */
1910 security_seterror(&rh->sech,
1911 "parse error in packet header : '%s'", origstr);
1919 struct sec_handle * rh,
1920 const char * remoteuser,
1921 const char * service)
1925 char *result = NULL;
1926 char *localuser = NULL;
1928 /* lookup our local user name */
1929 if ((pwd = getpwnam(CLIENT_LOGIN)) == NULL) {
1930 return vstrallocf(_("getpwnam(%s) failed."), CLIENT_LOGIN);
1934 * Make a copy of the user name in case getpw* is called by
1935 * any of the lower level routines.
1937 localuser = stralloc(pwd->pw_name);
1939 #ifndef USE_AMANDAHOSTS
1940 r = check_user_ruserok(rh->hostname, pwd, remoteuser);
1942 r = check_user_amandahosts(rh->hostname, &rh->peer, pwd, remoteuser, service);
1945 result = vstrallocf(
1946 _("user %s from %s is not allowed to execute the service %s: %s"),
1947 remoteuser, rh->hostname, service, r);
1955 * See if a remote user is allowed in. This version uses ruserok()
1958 * Returns NULL on success, or error message on error.
1963 struct passwd * pwd,
1964 const char * remoteuser)
1975 uid_t myuid = getuid();
1978 * note that some versions of ruserok (eg SunOS 3.2) look in
1979 * "./.rhosts" rather than "~CLIENT_LOGIN/.rhosts", so we have to
1980 * chdir ourselves. Sigh.
1982 * And, believe it or not, some ruserok()'s try an initgroup just
1983 * for the hell of it. Since we probably aren't root at this point
1984 * it'll fail, and initgroup "helpfully" will blatt "Setgroups: Not owner"
1985 * into our stderr output even though the initgroup failure is not a
1986 * problem and is expected. Thanks a lot. Not.
1988 if (pipe(fd) != 0) {
1989 return stralloc2(_("pipe() fails: "), strerror(errno));
1991 if ((ruserok_pid = fork()) < 0) {
1992 return stralloc2(_("fork() fails: "), strerror(errno));
1993 } else if (ruserok_pid == 0) {
1997 fError = fdopen(fd[1], "w");
1999 error(_("Can't fdopen: %s"), strerror(errno));
2002 /* pamper braindead ruserok's */
2003 if (chdir(pwd->pw_dir) != 0) {
2004 g_fprintf(fError, _("chdir(%s) failed: %s"),
2005 pwd->pw_dir, strerror(errno));
2010 if (debug_auth >= 9) {
2011 char *dir = stralloc(pwd->pw_dir);
2013 auth_debug(9, _("bsd: calling ruserok(%s, %d, %s, %s)\n"), host,
2014 ((myuid == 0) ? 1 : 0), remoteuser, pwd->pw_name);
2016 auth_debug(9, _("bsd: because you are running as root, "));
2017 auth_debug(9, _("/etc/hosts.equiv will not be used\n"));
2019 show_stat_info("/etc/hosts.equiv", NULL);
2021 show_stat_info(dir, "/.rhosts");
2025 saved_stderr = dup(2);
2027 if (open("/dev/null", O_RDWR) == -1) {
2028 auth_debug(1, _("Could not open /dev/null: %s\n"), strerror(errno));
2031 ok = ruserok(host, myuid == 0, remoteuser, CLIENT_LOGIN);
2038 (void)dup2(saved_stderr,2);
2039 close(saved_stderr);
2043 fError = fdopen(fd[0], "r");
2045 error(_("Can't fdopen: %s"), strerror(errno));
2050 while ((es = agets(fError)) != NULL) {
2055 if (result == NULL) {
2056 result = stralloc("");
2058 strappend(result, ": ");
2060 strappend(result, es);
2065 pid = wait(&exitcode);
2066 while (pid != ruserok_pid) {
2067 if ((pid == (pid_t) -1) && (errno != EINTR)) {
2069 return vstrallocf(_("ruserok wait failed: %s"), strerror(errno));
2071 pid = wait(&exitcode);
2073 if (!WIFEXITED(exitcode) || WEXITSTATUS(exitcode) != 0) {
2075 result = str_exit_status("ruserok child", exitcode);
2084 * Check to see if a user is allowed in. This version uses .amandahosts
2085 * Returns an error message on failure, or NULL on success.
2088 check_user_amandahosts(
2090 sockaddr_union *addr,
2091 struct passwd * pwd,
2092 const char * remoteuser,
2093 const char * service)
2097 const char *fileuser;
2099 char *result = NULL;
2105 char *aservice = NULL;
2107 char ipstr[INET6_ADDRSTRLEN];
2109 char ipstr[INET_ADDRSTRLEN];
2112 auth_debug(1, _("check_user_amandahosts(host=%s, pwd=%p, "
2113 "remoteuser=%s, service=%s)\n"),
2114 host, pwd, remoteuser, service);
2116 ptmp = stralloc2(pwd->pw_dir, "/.amandahosts");
2117 if (debug_auth >= 9) {
2118 show_stat_info(ptmp, "");;
2120 if ((fp = fopen(ptmp, "r")) == NULL) {
2121 result = vstrallocf(_("cannot open %s: %s"), ptmp, strerror(errno));
2127 * Make sure the file is owned by the Amanda user and does not
2128 * have any group/other access allowed.
2130 if (fstat(fileno(fp), &sbuf) != 0) {
2131 result = vstrallocf(_("cannot fstat %s: %s"), ptmp, strerror(errno));
2134 if (sbuf.st_uid != pwd->pw_uid) {
2135 result = vstrallocf(_("%s: owned by id %ld, should be %ld"),
2136 ptmp, (long)sbuf.st_uid, (long)pwd->pw_uid);
2139 if ((sbuf.st_mode & 077) != 0) {
2140 result = vstrallocf(_("%s: incorrect permissions; file must be accessible only by its owner"), ptmp);
2145 * Now, scan the file for the host/user/service.
2148 while ((line = agets(fp)) != NULL) {
2154 auth_debug(9, _("bsd: processing line: <%s>\n"), line);
2155 /* get the host out of the file */
2156 if ((filehost = strtok(line, " \t")) == NULL) {
2161 /* get the username. If no user specified, then use the local user */
2162 if ((fileuser = strtok(NULL, " \t")) == NULL) {
2163 fileuser = pwd->pw_name;
2166 hostmatch = (strcasecmp(filehost, host) == 0);
2167 /* ok if addr=127.0.0.1 and
2168 * either localhost or localhost.domain is in .amandahost */
2170 (strcasecmp(filehost, "localhost")== 0 ||
2171 strcasecmp(filehost, "localhost.localdomain")== 0)) {
2173 if (SU_GET_FAMILY(addr) == (sa_family_t)AF_INET6)
2174 inet_ntop(AF_INET6, &addr->sin6.sin6_addr,
2175 ipstr, sizeof(ipstr));
2178 inet_ntop(AF_INET, &addr->sin.sin_addr,
2179 ipstr, sizeof(ipstr));
2180 if (strcmp(ipstr, "127.0.0.1") == 0 ||
2181 strcmp(ipstr, "::1") == 0)
2184 usermatch = (strcasecmp(fileuser, remoteuser) == 0);
2185 auth_debug(9, _("bsd: comparing \"%s\" with\n"), filehost);
2186 auth_debug(9, _("bsd: \"%s\" (%s)\n"), host,
2187 hostmatch ? _("match") : _("no match"));
2188 auth_debug(9, _("bsd: and \"%s\" with\n"), fileuser);
2189 auth_debug(9, _("bsd: \"%s\" (%s)\n"), remoteuser,
2190 usermatch ? _("match") : _("no match"));
2192 if (!hostmatch || !usermatch) {
2204 /* get the services. If no service specified, then use
2205 * noop/selfcheck/sendsize/sendbackup
2207 aservice = strtok(NULL, " \t,");
2209 if (strcmp(service,"noop") == 0 ||
2210 strcmp(service,"selfcheck") == 0 ||
2211 strcmp(service,"sendsize") == 0 ||
2212 strcmp(service,"sendbackup") == 0) {
2225 if (strcmp(aservice,service) == 0) {
2229 if (strcmp(aservice, "amdump") == 0 &&
2230 (strcmp(service, "noop") == 0 ||
2231 strcmp(service, "selfcheck") == 0 ||
2232 strcmp(service, "sendsize") == 0 ||
2233 strcmp(service, "sendbackup") == 0)) {
2237 } while((aservice = strtok(NULL, " \t,")) != NULL);
2239 if (aservice && strcmp(aservice, service) == 0) {
2248 if (strcmp(service, "amindexd") == 0 ||
2249 strcmp(service, "amidxtaped") == 0) {
2250 result = vstrallocf(_("Please add the line \"%s %s amindexd amidxtaped\" to %s on the server"), host, remoteuser, ptmp);
2251 } else if (strcmp(service, "amdump") == 0 ||
2252 strcmp(service, "noop") == 0 ||
2253 strcmp(service, "selfcheck") == 0 ||
2254 strcmp(service, "sendsize") == 0 ||
2255 strcmp(service, "sendbackup") == 0) {
2256 result = vstrallocf(_("Please add the line \"%s %s amdump\" to %s on the client"), host, remoteuser, ptmp);
2258 result = vstrallocf(_("%s: invalid service %s"), ptmp, service);
2270 /* return 1 on success, 0 on failure */
2273 sockaddr_union *addr,
2275 unsigned long cksum,
2278 char * remotehost = NULL, *remoteuser = NULL;
2279 char * bad_bsd = NULL;
2280 struct passwd * pwptr;
2285 char hostname[NI_MAXHOST];
2289 (void)cksum; /* Quiet unused parameter warning */
2292 _("check_security(addr=%p, str='%s', cksum=%lu, errstr=%p\n"),
2293 addr, str, cksum, errstr);
2294 dump_sockaddr(addr);
2298 /* what host is making the request? */
2299 if ((result = getnameinfo((struct sockaddr *)addr, SS_LEN(addr),
2300 hostname, NI_MAXHOST, NULL, 0, 0)) != 0) {
2301 dbprintf(_("getnameinfo failed: %s\n"),
2302 gai_strerror(result));
2303 *errstr = vstralloc("[", "addr ", str_sockaddr(addr), ": ",
2304 "getnameinfo failed: ", gai_strerror(result),
2308 remotehost = stralloc(hostname);
2309 if( check_name_give_sockaddr(hostname,
2310 (struct sockaddr *)addr, errstr) < 0) {
2316 /* next, make sure the remote port is a "reserved" one */
2317 port = SU_GET_PORT(addr);
2318 if (port >= IPPORT_RESERVED) {
2319 *errstr = vstrallocf(_("[host %s: port %u not secure]"),
2320 remotehost, (unsigned int)port);
2325 /* extract the remote user name from the message */
2330 bad_bsd = vstrallocf(_("[host %s: bad bsd security line]"), remotehost);
2332 if (strncmp_const_skip(s - 1, "USER ", s, ch) != 0) {
2339 skip_whitespace(s, ch);
2347 skip_non_whitespace(s, ch);
2349 remoteuser = stralloc(fp);
2353 /* lookup our local user name */
2356 if ((pwptr = getpwuid(myuid)) == NULL)
2357 error(_("error [getpwuid(%d) fails]"), (int)myuid);
2359 auth_debug(1, _("bsd security: remote host %s user %s local user %s\n"),
2360 remotehost, remoteuser, pwptr->pw_name);
2362 #ifndef USE_AMANDAHOSTS
2363 s = check_user_ruserok(remotehost, pwptr, remoteuser);
2365 s = check_user_amandahosts(remotehost, addr, pwptr, remoteuser, NULL);
2369 *errstr = vstrallocf(_("[access as %s not allowed from %s@%s: %s]"),
2370 pwptr->pw_name, remoteuser, remotehost, s);
2375 return *errstr == NULL;
2379 * Like read(), but waits until the entire buffer has been filled.
2388 char *buf = vbuf; /* ptr arith */
2390 size_t size = origsize;
2392 auth_debug(1, _("net_read: begin %zu\n"), origsize);
2395 auth_debug(1, _("net_read: while %zu\n"), size);
2396 nread = net_read_fillbuf(fd, timeout, buf, size);
2398 auth_debug(1, _("db: net_read: end return(-1)\n"));
2402 auth_debug(1, _("net_read: end return(0)\n"));
2408 auth_debug(1, _("net_read: end %zu\n"), origsize);
2409 return ((ssize_t)origsize);
2413 * net_read likes to do a lot of little reads. Buffer it.
2422 SELECT_ARG_TYPE readfds;
2426 auth_debug(1, _("net_read_fillbuf: begin\n"));
2428 FD_SET(fd, &readfds);
2429 tv.tv_sec = timeout;
2431 switch (select(fd + 1, &readfds, NULL, NULL, &tv)) {
2436 auth_debug(1, _("net_read_fillbuf: case -1\n"));
2439 auth_debug(1, _("net_read_fillbuf: case 1\n"));
2440 assert(FD_ISSET(fd, &readfds));
2443 auth_debug(1, _("net_read_fillbuf: case default\n"));
2447 nread = read(fd, buf, size);
2450 auth_debug(1, _("net_read_fillbuf: end %zd\n"), nread);
2456 * Display stat() information about a file.
2464 char *name = vstralloc(a, b, NULL);
2466 struct passwd *pwptr G_GNUC_UNUSED;
2467 struct passwd pw G_GNUC_UNUSED;
2469 struct group *grptr G_GNUC_UNUSED;
2470 struct group gr G_GNUC_UNUSED;
2472 int buflen G_GNUC_UNUSED;
2473 char *buf G_GNUC_UNUSED;
2475 if (stat(name, &sbuf) != 0) {
2476 auth_debug(1, _("bsd: cannot stat %s: %s\n"), name, strerror(errno));
2481 #ifdef _SC_GETPW_R_SIZE_MAX
2482 buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
2488 buf = malloc(buflen);
2490 #ifdef HAVE_GETPWUID_R
2491 if (getpwuid_r(sbuf.st_uid, &pw, buf, buflen, &pwptr) == 0 &&
2493 owner = stralloc(pwptr->pw_name);
2497 owner = alloc(NUM_STR_SIZE + 1);
2498 g_snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_uid);
2500 #ifdef HAVE_GETGRGID_R
2501 if (getgrgid_r(sbuf.st_gid, &gr, buf, buflen, &grptr) == 0 &&
2503 group = stralloc(grptr->gr_name);
2507 group = alloc(NUM_STR_SIZE + 1);
2508 g_snprintf(group, NUM_STR_SIZE, "%ld", (long)sbuf.st_gid);
2511 auth_debug(1, _("bsd: processing file: %s\n"), name);
2512 auth_debug(1, _("bsd: owner=%s group=%s mode=%03o\n"),
2514 (int) (sbuf.st_mode & 0777));
2522 check_name_give_sockaddr(
2523 const char *hostname,
2524 struct sockaddr *addr,
2528 struct addrinfo *res = NULL, *res1;
2531 result = resolve_hostname(hostname, 0, &res, &canonname);
2533 dbprintf(_("check_name_give_sockaddr: resolve_hostname('%s'): %s\n"), hostname, gai_strerror(result));
2534 *errstr = newvstrallocf(*errstr,
2535 _("check_name_give_sockaddr: resolve_hostname('%s'): %s"),
2536 hostname, gai_strerror(result));
2539 if (canonname == NULL) {
2540 dbprintf(_("resolve_hostname('%s') did not return a canonical name\n"), hostname);
2541 *errstr = newvstrallocf(*errstr,
2542 _("check_name_give_sockaddr: resolve_hostname('%s') did not return a canonical name"),
2547 if (strncasecmp(hostname, canonname, strlen(hostname)) != 0) {
2548 dbprintf(_("%s doesn't resolve to itself, it resolves to %s\n"),
2549 hostname, canonname);
2550 *errstr = newvstrallocf(*errstr,
2551 _("%s doesn't resolve to itself, it resolves to %s"),
2552 hostname, canonname);
2556 for(res1=res; res1 != NULL; res1 = res1->ai_next) {
2557 if (cmp_sockaddr((sockaddr_union *)res1->ai_addr, (sockaddr_union *)addr, 1) == 0) {
2564 dbprintf(_("%s doesn't resolve to %s"),
2565 hostname, str_sockaddr((sockaddr_union *)addr));
2566 *errstr = newvstrallocf(*errstr,
2567 "%s doesn't resolve to %s",
2568 hostname, str_sockaddr((sockaddr_union *)addr));
2570 if (res) freeaddrinfo(res);