X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Fsecurity-util.c;h=ee2f99c6f7032216fb6d66bdacd88b9d49cd609b;hb=21170aaf9015a4c519265834456fc309932f24c0;hp=e326258d6dc208ac9633c0ef791917e9bec1f4c9;hpb=94a044f90357edefa6f4ae9f0b1d5885b0e34aee;p=debian%2Famanda diff --git a/common-src/security-util.c b/common-src/security-util.c index e326258..ee2f99c 100644 --- a/common-src/security-util.c +++ b/common-src/security-util.c @@ -229,7 +229,8 @@ stream_sendpkt( 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); @@ -330,7 +331,7 @@ tcpm_stream_write( 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); @@ -354,7 +355,7 @@ tcpm_stream_read( * 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); } @@ -380,7 +381,7 @@ tcpm_stream_read_sync( if (rs->ev_read != NULL) { return -1; } - 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_sync_callback, rs); sec_tcp_conn_read(rs->rc); event_wait(rs->ev_read); @@ -466,7 +467,7 @@ tcpm_send_token( nb_iov = 3; } - rval = net_writev(fd, iov, nb_iov); + rval = full_writev(fd, iov, nb_iov); if (len != 0 && rc->driver->data_encrypt != NULL && buf != encbuf) { amfree(encbuf); } @@ -607,7 +608,7 @@ tcpm_close_connection( (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); } @@ -764,7 +765,7 @@ tcp1_stream_server( 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, @@ -862,7 +863,7 @@ tcp_stream_write( assert(rs != NULL); - if (fullwrite(rs->fd, buf, size) < 0) { + 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); @@ -886,7 +887,7 @@ bsd_prefix_packet( security_seterror(&rh->sech, _("can't get login name for my uid %ld"), (long)getuid()); - return(NULL); + return ""; } buf = alloc(16+strlen(pwd->pw_name)); strncpy(buf, "SECURITY USER ", (16 + strlen(pwd->pw_name))); @@ -963,7 +964,7 @@ bsd_recv_security_ok( /* * 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, @@ -1016,6 +1017,7 @@ bsd_recv_security_ok( if ((tok = strtok(NULL, "")) == NULL) { security_seterror(&rh->sech, _("SECURITY line: %s"), security_line); + amfree(service); amfree(security_line); return (-1); /* default errmsg */ } @@ -1063,7 +1065,7 @@ udpbsd_sendpkt( * 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 @@ -1089,7 +1091,7 @@ udpbsd_sendpkt( /* * 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"), @@ -1274,7 +1276,7 @@ udp_inithandle( 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) @@ -1288,7 +1290,7 @@ udp_inithandle( 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; @@ -1395,7 +1397,7 @@ udp_netfd_read_callback( return; } - port = SS_GET_PORT(&udp->peer); + port = SU_GET_PORT(&udp->peer); a = udp_inithandle(udp, rh, hostname, &udp->peer, @@ -1470,6 +1472,7 @@ sec_tcp_conn_get( rc->auth = 0; rc->conf_fn = NULL; rc->datap = NULL; + rc->event_id = newevent++; connq_append(rc); return (rc); } @@ -1505,10 +1508,13 @@ sec_tcp_conn_put( amfree(rc->errmsg); connq_remove(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'. + */ + } } /* @@ -1583,7 +1589,7 @@ recvpkt_callback( (*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: @@ -1637,7 +1643,7 @@ stream_read_sync_callback( 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; @@ -1683,7 +1689,7 @@ stream_read_callback( 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; @@ -1723,7 +1729,7 @@ sec_tcp_conn_read_callback( 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 */ @@ -1741,7 +1747,7 @@ sec_tcp_conn_read_callback( 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; @@ -1749,8 +1755,8 @@ sec_tcp_conn_read_callback( /* 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); @@ -1760,8 +1766,12 @@ sec_tcp_conn_read_callback( 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)); security_handleinit(&rh->sech, rc->driver); @@ -2077,7 +2087,7 @@ check_user_ruserok( char * check_user_amandahosts( const char * host, - struct sockaddr_storage *addr, + sockaddr_union *addr, struct passwd * pwd, const char * remoteuser, const char * service) @@ -2160,12 +2170,12 @@ check_user_amandahosts( (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) @@ -2237,7 +2247,7 @@ check_user_amandahosts( 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 || @@ -2260,7 +2270,7 @@ common_exit: /* return 1 on success, 0 on failure */ int check_security( - struct sockaddr_storage *addr, + sockaddr_union *addr, char * str, unsigned long cksum, char ** errstr) @@ -2304,7 +2314,7 @@ check_security( /* 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); @@ -2365,57 +2375,6 @@ check_security( 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. */ @@ -2504,14 +2463,14 @@ show_stat_info( { 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)); @@ -2528,20 +2487,27 @@ show_stat_info( #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) { - group = alloc(NUM_STR_SIZE + 1); - g_snprintf(owner, NUM_STR_SIZE, "%ld", (long)sbuf.st_gid); - } else { +#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); } + auth_debug(1, _("bsd: processing file: %s\n"), name); auth_debug(1, _("bsd: owner=%s group=%s mode=%03o\n"), owner, group, @@ -2588,7 +2554,7 @@ check_name_give_sockaddr( } 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; @@ -2596,10 +2562,10 @@ check_name_give_sockaddr( } dbprintf(_("%s doesn't resolve to %s"), - hostname, str_sockaddr((struct sockaddr_storage *)addr)); + 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);