X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=common-src%2Fsecurity-util.c;h=bc108cdd0fbfcd4747579ce02ce4f933bdd728c9;hb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;hp=4fa750d4e8c26826e9bb5b95cf073623a5f09ce8;hpb=fd48f3e498442f0cbff5f3606c7c403d0566150e;p=debian%2Famanda diff --git a/common-src/security-util.c b/common-src/security-util.c index 4fa750d..bc108cd 100644 --- a/common-src/security-util.c +++ b/common-src/security-util.c @@ -42,12 +42,6 @@ #include "stream.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 */ @@ -108,7 +102,7 @@ sec_accept( { 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; @@ -432,11 +426,18 @@ tcpm_send_token( 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) @@ -487,6 +488,7 @@ tcpm_send_token( } /* + * 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 @@ -500,93 +502,118 @@ tcpm_recv_token( 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); @@ -654,7 +681,7 @@ tcpma_stream_client( 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; @@ -688,7 +715,7 @@ tcpma_stream_server( 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; @@ -740,6 +767,7 @@ tcpma_stream_close( 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); } @@ -756,7 +784,7 @@ tcp1_stream_server( 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; @@ -828,7 +856,7 @@ tcp1_stream_client( 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; @@ -865,9 +893,16 @@ tcp_stream_write( size_t size) { struct sec_stream *rs = s; + time_t logtime; assert(rs != NULL); + 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)); @@ -1379,7 +1414,7 @@ udp_netfd_read_callback( return; } - rh = alloc(SIZEOF(*rh)); + rh = g_new0(struct sec_handle, 1); rh->proto_handle=NULL; rh->udp = udp; rh->rc = NULL; @@ -1460,7 +1495,7 @@ sec_tcp_conn_get( /* * 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; @@ -1673,8 +1708,15 @@ stream_read_callback( 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); /* @@ -1734,9 +1776,14 @@ sec_tcp_conn_read_callback( /* 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; @@ -1784,7 +1831,7 @@ sec_tcp_conn_read_callback( 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; @@ -2572,7 +2619,7 @@ check_name_give_sockaddr( } } - dbprintf(_("%s doesn't resolve to %s"), + g_debug("%s doesn't resolve to %s", hostname, str_sockaddr((sockaddr_union *)addr)); *errstr = newvstrallocf(*errstr, "%s doesn't resolve to %s", @@ -2612,3 +2659,20 @@ find_port_for_service( 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; +}