[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: An independent IPv6 patching of bsd-finger



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


Reply to: