Now I can report on Fedoras patching. First off, their patch is from 2005, but the youngest code change is from 2001, originating in the USAGI project. The Fedora location is http://cvs.fedoraproject.org/viewvc/rpms/finger/devel/bsd-finger-0.17-usagi-ipv6.patch A simplified difference file, containing all relevant C-code, is appended to this message. It turns out that the USAGI patch uses practically the same technique as I myself used in the second form of my interdiff, but there are small differences that need to be brought into light and to be discussed. 1. USAGI uses code insertion that needs activation by a macro INET6 in order to be included. My suggestion does not introduce a conditional code alteration. At this point in time IPv6 should be mandatory, from my view point. 2. For protocol determination, USAGI uses PF_UNSPEC, I use AF_UNSPEC. 3. In fingerd/fingerd.c: USAGI replaces the use of gethostbyname() with getaddrinfo(). With intention I did not do this, in order to minimize code pollu- tion. The main reason is that the only use gethostbyname() has in this source file, is to retreive the host name of the local server on which 'in.fingerd' is running, thus nothing is gained. The only conceivable problem would be that a future IPv6-only stack might not cooperate at all with gethostbyname() in replacing even "localhost". 4. In order to achieve IP-stack independent code as far as possible, I have used the hints setup MEA: hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG whereas USAGI: hints.ai_flags = AI_CANONNAME My reason is that AI_ADDRCONFIG makes sure that getaddrinfo() can return addresses from either of IPv4 or IPv6 only if such traffic protocol is actually configured for a live network device. Thus no problem can arise if even if a single-protocol (like an old IPv4-stack) stack is in use. My conclusions are threefold: A. The compiler test on the macro INET6 should be avoided. B. Debian should use AI_ADDRCONFIG. C. Debian could either keep gethostbyname() in fingerd/fingerd.c, or can follow USAGI in using getaddrinfo() also there, but should then also add AI_ADDRCONFIG, thus going beyond USAGI. Mats Erik Andersson, fil. dr
diff -uNr bsd-finger-0.17/configure bsd-finger/configure --- bsd-finger-0.17/configure Sat Jul 29 21:00:27 2000 +++ bsd-finger/configure Sat Jan 27 06:14:52 2001 @@ -25,6 +25,7 @@ --daemonmode=mode Mode for daemon binaries [same as binmode] --manmode=mode Mode for manual pages [644] --with-c-compiler=cc Program for compiling C source [guessed] + --enable-ipv6 Enable IPv6 support EOF exit 0;; --verbose) ;; @@ -40,6 +41,11 @@ --daemonmode=*) DAEMONMODE=`echo $1 | sed 's/^[^=]*=//'` ;; --manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;; --with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;; + + --disable-ipv6) ENABLE_IPV6=no;; + --enable-ipv6=*) ENABLE_IPV6=`echo $1 | sed 's/^[^=]*=//'`;; + --enable-ipv6) ENABLE_IPV6=yes;; + *) echo "Unrecognized option: $1"; exit 1;; esac shift @@ -148,6 +154,42 @@ LDFLAGS= LIBS= + +rm -f __conftest* + +################################################## +## Enable IPv6 +echo -n "Whether to enable IPv6 support... " +if [ x"$ENABLE_IPV6" = x"yes" ]; then + echo yes + CFLAGS="$CFLAGS -DINET6" +else + echo no +fi + +rm -f __conftest* + +## Search IPv6 Library / Headers +if [ x"$ENABLE_IPV6" = x"yes" ]; then + echo -n "Search for IPv6 library... " + inet6libdirs="/usr/local/v6/lib /usr/local/lib /usr /usr/inet6/lib" + inet6libs="inet6" + inet6found=no + for inet6libdir in $inet6libdirs; do + for inet6lib in $inet6libs; do + if [ -d $inet6libdir ] && [ -f $inet6libdir/lib$inet6lib.a ]; then + inet6found=yes + break 2 + fi + done + done + if [ x"$inet6found" = x"yes" ]; then + echo "$inet6libdir/lib$inet6lib.a" + LIBS="$LIBS -L$inet6libdir -l$inet6lib" + else + echo "not found" + fi +fi rm -f __conftest* diff -uNr bsd-finger-0.17/finger/Makefile bsd-finger/finger/Makefile --- bsd-finger-0.17/finger/Makefile Sun Dec 12 20:04:52 1999 +++ bsd-finger/finger/Makefile Sat Jan 27 07:57:07 2001 @@ -10,7 +10,9 @@ finger.o: ../version.h install: finger + install -d $(INSTALLROOT)$(BINDIR) install -s -m$(BINMODE) finger $(INSTALLROOT)$(BINDIR) + install -d $(INSTALLROOT)$(MANDIR)/man1 install -m$(MANMODE) finger.1 $(INSTALLROOT)$(MANDIR)/man1 clean: diff -uNr bsd-finger-0.17/finger/finger.c bsd-finger/finger/finger.c --- bsd-finger-0.17/finger/finger.c Sat Dec 18 18:41:51 1999 +++ bsd-finger/finger/finger.c Sun Feb 11 11:33:52 2001 @@ -1,3 +1,5 @@ +/* $USAGI$ */ + /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. @@ -46,7 +48,7 @@ * from: @(#)finger.c 5.22 (Berkeley) 6/29/90 */ char finger_rcsid[] = \ - "$Id: finger.c,v 1.15 1999/12/18 16:41:51 dholland Exp $"; + "$Id: finger.c,v 1.3 2001/02/11 09:33:52 yoshfuji Exp $"; /* * Finger prints out information about users. It is not portable since @@ -74,7 +76,11 @@ #include <time.h> #include <getopt.h> #include "finger.h" +#ifdef _USAGI +#include "version.h" +#else #include "../version.h" +#endif static void loginlist(void); static void userlist(int argc, char *argv[]); @@ -92,8 +98,12 @@ int main(int argc, char *argv[]) { int ch; - struct sockaddr_in sin; - socklen_t slen = sizeof(sin); +#ifdef INET6 + struct sockaddr_storage sa; +#else + struct sockaddr sa; +#endif + socklen_t slen = sizeof(sa); while ((ch = getopt(argc, argv, "lmps")) != EOF) { switch(ch) { @@ -119,7 +129,7 @@ argc -= optind; argv += optind; - if (getsockname(STDOUT_FILENO, (struct sockaddr *)&sin, &slen)==0) { + if (getsockname(STDOUT_FILENO, (struct sockaddr *)&sa, &slen)==0) { /* * stdout is a socket. must be a network finger request, * so emit CRs with our LFs at the ends of lines. @@ -136,7 +146,7 @@ * Also check stdin for nofinger processing, because of older * fingerds that make stdout a pipe for CRLF handling. */ - if (getsockname(STDIN_FILENO, (struct sockaddr *)&sin, &slen)==0) { + if (getsockname(STDIN_FILENO, (struct sockaddr *)&sa, &slen)==0) { enable_nofinger = 1; } diff -uNr bsd-finger-0.17/finger/net.c bsd-finger/finger/net.c --- bsd-finger-0.17/finger/net.c Tue Sep 14 13:51:11 1999 +++ bsd-finger/finger/net.c Fri Jan 26 20:08:21 2001 @@ -1,3 +1,5 @@ +/* $USAGI: net.c,v 1.2 2000/11/17 08:00:44 yoshfuji Exp $ */ + /* * Copyright (c) 1989 The Regents of the University of California. * All rights reserved. @@ -36,7 +38,7 @@ #ifndef lint /*static char sccsid[] = "from: @(#)net.c 5.5 (Berkeley) 6/1/90";*/ -char net_rcsid[] = "$Id: net.c,v 1.9 1999/09/14 10:51:11 dholland Exp $"; +char net_rcsid[] = "$Id: net.c,v 1.3 2001/01/26 18:08:21 yoshfuji Exp $"; #endif /* not lint */ #include <sys/types.h> @@ -53,18 +55,53 @@ void netfinger(const char *name) { register FILE *fp; - struct in_addr defaddr; register int c, sawret, ateol; +#ifdef INET6 + struct addrinfo hints, *res0, *res; + int gai; +#else + struct in_addr defaddr; struct hostent *hp, def; struct servent *sp; struct sockaddr_in sn; + char *alist[1]; +#endif int s; - char *alist[1], *host; + char *host; host = strrchr(name, '@'); if (!host) return; *host++ = '\0'; +#ifdef INET6 + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + gai = getaddrinfo(host, "finger", &hints, &res0); + if (gai) { + eprintf("finger: %s: host '%s', service '%s'\n", + gai_strerror(gai), host, "finger"); + return; + } + s = -1; + errno = 0; + for (res=res0; res; res=res->ai_next) { + s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (s < 0) + continue; + if (connect(s, res->ai_addr, res->ai_addrlen) < 0){ + close(s); + s = -1; + continue; + } + break; + } + freeaddrinfo(res0); + if (s < 0) { + eprintf("finger: cannot create socket / connet host\n"); + return; + } +#else memset(&sn, 0, sizeof(sn)); sp = getservbyname("finger", "tcp"); @@ -106,6 +143,7 @@ close(s); return; } +#endif /* -l flag for remote fingerd */ if (lflag) write(s, "/W ", 3); diff -uNr bsd-finger-0.17/fingerd/Makefile bsd-finger/fingerd/Makefile --- bsd-finger-0.17/fingerd/Makefile Sun Dec 12 20:04:57 1999 +++ bsd-finger/fingerd/Makefile Sat Jan 27 07:57:07 2001 @@ -9,7 +9,9 @@ fingerd.o: pathnames.h ../version.h install: fingerd + install -d $(INSTALLROOT)$(SBINDIR) install -s -m$(DAEMONMODE) fingerd $(INSTALLROOT)$(SBINDIR)/in.fingerd + install -d $(INSTALLROOT)$(MANDIR)/man8 install -m$(MANMODE) fingerd.8 $(INSTALLROOT)$(MANDIR)/man8/in.fingerd.8 ln -sf in.fingerd.8 $(INSTALLROOT)$(MANDIR)/man8/fingerd.8 diff -uNr bsd-finger-0.17/fingerd/fingerd.c bsd-finger/fingerd/fingerd.c --- bsd-finger-0.17/fingerd/fingerd.c Sun Dec 12 20:46:28 1999 +++ bsd-finger/fingerd/fingerd.c Sun Feb 11 11:33:52 2001 @@ -1,3 +1,5 @@ +/* $USAGI: fingerd.c,v 1.3 2000/11/17 08:13:01 yoshfuji Exp $ */ + /* * Copyright (c) 1983 The Regents of the University of California. * All rights reserved. @@ -39,7 +41,7 @@ * from: @(#)fingerd.c 5.6 (Berkeley) 6/1/90" */ char rcsid[] = - "$Id: fingerd.c,v 1.23 1999/12/12 18:46:28 dholland Exp $"; + "$Id: fingerd.c,v 1.5 2001/02/11 09:33:52 yoshfuji Exp $"; #include <pwd.h> #include <grp.h> @@ -57,7 +59,11 @@ #include <sys/wait.h> #include "pathnames.h" +#ifdef _USAGI +#include "version.h" +#else #include "../version.h" +#endif #define ENTRIES 50 #define WS " \t\r\n" @@ -111,7 +117,11 @@ int k, nusers; char *s, *t; const char *fingerpath = NULL; - struct sockaddr_in sn; +#ifdef INET6 + struct sockaddr_storage sn; +#else + struct sockaddr sn; +#endif socklen_t sval = sizeof(sn); @@ -182,18 +192,35 @@ if (welcome) { char buf[256]; +#ifdef INET6 + struct addrinfo hints, *res0; +#else struct hostent *hp; +#endif struct utsname utsname; + const char *cname = buf; uname(&utsname); gethostname(buf, sizeof(buf)); +#ifdef INET6 + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_flags = AI_CANONNAME; + if (getaddrinfo(buf, NULL, &hints, &res0)) { + /* paranoia: dns spoofing? */ + cname = res0->ai_canonname; + } +#else if ((hp = gethostbyname(buf))) { /* paranoia: dns spoofing? */ - strncpy(buf, hp->h_name, sizeof(buf)); - buf[sizeof(buf)-1] = 0; + cname = hp->h_name; } +#endif printf("\r\nWelcome to %s version %s at %s !\r\n\n", - utsname.sysname, utsname.release, buf); + utsname.sysname, utsname.release, cname); +#ifdef INET6 + freeaddrinfo(res0); +#endif fflush(stdout); switch (fork()) { case -1: /* fork failed, oh well */
Attachment:
signature.asc
Description: Digital signature