From owner-freebsd-ports-bugs@FreeBSD.ORG Thu Apr 1 08:40:10 2004 Return-Path: Delivered-To: freebsd-ports-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1F72E16A4CF for ; Thu, 1 Apr 2004 08:40:10 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 101BB43D2D for ; Thu, 1 Apr 2004 08:40:10 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) i31Ge9bv059187 for ; Thu, 1 Apr 2004 08:40:09 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.10/8.12.10/Submit) id i31Ge9T0059182; Thu, 1 Apr 2004 08:40:09 -0800 (PST) (envelope-from gnats) Resent-Date: Thu, 1 Apr 2004 08:40:09 -0800 (PST) Resent-Message-Id: <200404011640.i31Ge9T0059182@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-ports-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Alex Vasylenko Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 3F04116A4CE for ; Thu, 1 Apr 2004 08:31:02 -0800 (PST) Received: from mix.omut.org (ool-43548ab5.dyn.optonline.net [67.84.138.181]) by mx1.FreeBSD.org (Postfix) with ESMTP id 8F53443D1F for ; Thu, 1 Apr 2004 08:31:01 -0800 (PST) (envelope-from lxv@mix.omut.org) Received: from mix.omut.org (IDENT:26/rbZqbAZKT/smxmj4uXX5WtLN11kcP@localhost [127.0.0.1]) by mix.omut.org (8.12.11/8.12.11) with ESMTP id i31GV05B026300; Thu, 1 Apr 2004 11:31:00 -0500 (EST) (envelope-from lxv@mix.omut.org) Received: (from lxv@localhost) by mix.omut.org (8.12.11/8.12.11/Submit) id i31GV0ZK026299; Thu, 1 Apr 2004 11:31:00 -0500 (EST) (envelope-from lxv) Message-Id: <200404011631.i31GV0ZK026299@mix.omut.org> Date: Thu, 1 Apr 2004 11:31:00 -0500 (EST) From: Alex Vasylenko To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 cc: rsync@lists.samba.org Subject: ports/65043: [patch] net/rsync: problems in client name lookup code X-BeenThere: freebsd-ports-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Alex Vasylenko List-Id: Ports bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 01 Apr 2004 16:40:10 -0000 >Number: 65043 >Category: ports >Synopsis: [patch] net/rsync: problems in client name lookup code >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-ports-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Apr 01 08:40:09 PST 2004 >Closed-Date: >Last-Modified: >Originator: Alex Vasylenko >Release: FreeBSD 4.8-RELEASE-p16 i386 >Organization: >Environment: System: FreeBSD 4.8-RELEASE-p16 >Description: rsync does reverse name lookups on a client address in lookup_name (called from client_name) in clientname.c The code in client_name does two things incorrectly: - fails to set ss_len member of struct sockaddr_storage, which when passed to getnameinfo causes the latter to fail; - detection of IPv6 via counting dots is plain silly and doesn't work; The attached patch attempts to address these two issues. >How-To-Repeat: The code in question gets exercised when "hosts allow" specifies a hostname >Fix: --- proto.h.orig Sat Dec 6 16:07:27 2003 +++ proto.h Thu Apr 1 10:54:19 2004 @@ -42,7 +42,6 @@ struct sockaddr_storage *ss, socklen_t *ss_len); int lookup_name(int fd, const struct sockaddr_storage *ss, - socklen_t ss_len, char *name_buf, size_t name_buf_len, char *port_buf, size_t port_buf_len); int compare_addrinfo_sockaddr(const struct addrinfo *ai, --- clientname.c.orig Fri Jan 10 21:05:56 2003 +++ clientname.c Thu Apr 1 10:57:05 2004 @@ -101,58 +101,58 @@ char *client_name(int fd) static char name_buf[100]; static char port_buf[100]; static int initialised; - struct sockaddr_storage ss, *ssp; - struct sockaddr_in sin; -#ifdef INET6 - struct sockaddr_in6 sin6; -#endif - socklen_t ss_len; + struct sockaddr_storage ss; - if (initialised) return name_buf; + if (initialised) + return name_buf; strcpy(name_buf, default_name); initialised = 1; + memset(&ss, 0, sizeof(ss)); + if (am_server) { /* daemon over --rsh mode */ char *addr = client_addr(fd); -#ifdef INET6 - int dots = 0; - char *p; - for (p = addr; *p && (dots <= 3); p++) { - if (*p == '.') - dots++; - } - if (dots > 3) { - /* more than 4 parts to IP address, must be ipv6 */ - ssp = (struct sockaddr_storage *) &sin6; - ss_len = sizeof sin6; - memset(ssp, 0, ss_len); - inet_pton(AF_INET6, addr, &sin6.sin6_addr); - sin6.sin6_family = AF_INET6; - } else -#endif - { - ssp = (struct sockaddr_storage *) &sin; - ss_len = sizeof sin; - memset(ssp, 0, ss_len); - inet_pton(AF_INET, addr, &sin.sin_addr); - sin.sin_family = AF_INET; + struct addrinfo hint; + struct addrinfo *answer; + int err; + + memset(&hint, 0, sizeof(hint)); + + hint.ai_flags = AI_NUMERICHOST; + hint.ai_socktype = SOCK_STREAM; + + err = getaddrinfo(addr, NULL, &hint, &answer); + if (err) { + rprintf(FERROR, RSYNC_NAME ": malformed address %s: %s\n", + addr, gai_strerror(err)); + return name_buf; } + switch (answer->ai_family) { + case AF_INET: + memcpy(&ss, answer->ai_addr, sizeof(struct sockaddr_in)); + break; +#ifdef INET6 + case AF_INET6: + memcpy(&ss, answer->ai_addr, sizeof(struct sockaddr_in6)); + break; + } +#endif + freeaddrinfo(answer); } else { - ss_len = sizeof ss; - ssp = &ss; + socklen_t ss_len = sizeof ss; client_sockaddr(fd, &ss, &ss_len); - + ss.ss_len = ss_len; } - if (!lookup_name(fd, ssp, ss_len, name_buf, sizeof name_buf, + if (!lookup_name(fd, &ss, name_buf, sizeof name_buf, port_buf, sizeof port_buf)) - check_name(fd, ssp, name_buf); + check_name(fd, &ss, name_buf); return name_buf; } @@ -216,14 +216,13 @@ void client_sockaddr(int fd, * @param fd file descriptor for client socket. **/ int lookup_name(int fd, const struct sockaddr_storage *ss, - socklen_t ss_len, char *name_buf, size_t name_buf_len, char *port_buf, size_t port_buf_len) { int name_err; /* reverse lookup */ - name_err = getnameinfo((struct sockaddr *) ss, ss_len, + name_err = getnameinfo((struct sockaddr *) ss, ss->ss_len, name_buf, name_buf_len, port_buf, port_buf_len, NI_NAMEREQD | NI_NUMERICSERV); >Release-Note: >Audit-Trail: >Unformatted: