Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 07 Mar 2000 10:27:07 +0900
From:      Yoshinobu Inoue <shin@nd.net.fujitsu.co.jp>
To:        imp@village.org
Cc:        kris@hub.freebsd.org, jepace@pobox.com, current@FreeBSD.ORG
Subject:   Re: /usr/bin/ssh and SOCKS 
Message-ID:  <20000307102707G.shin@nd.net.fujitsu.co.jp>
In-Reply-To: <200003062309.QAA88816@harmony.village.org>
References:  <Pine.BSF.4.21.0003061452500.83999-100000@hub.freebsd.org> <200003062309.QAA88816@harmony.village.org>

next in thread | previous in thread | raw e-mail | index | archive | help
> : I'd like to get this committed - I'll try and take a look at it tonight,
> : time permitting. I would definitely like to allow SSH to work with dante,
> : though, since that's a better (BSDL) alternative than the restricted NEC
> : version.

I don't know well about dante, but if it is one of socks
implementation, then I think it will also need getaddrinfo
wrapper support.

In socks5 port case, the following patches are already added,
so it should be able to support apps which use getaddrinfo().

Cheers,
Yoshinobu Inoue


--- lib/rld.c.orig	Wed Aug  4 04:59:28 1999
+++ lib/rld.c	Mon Feb 21 03:55:45 2000
@@ -197,6 +197,26 @@
     lsInRLDFunctions = 0;
     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: gethostbyname2 results: %s %s", name, hp?hp->h_name:"???");
     return hp;
+}
+#endif
+
+#ifdef HAVE_GETADDRINFO
+int REAL(getaddrinfo)(const char *hostname, const char *servname,
+		      const struct addrinfo *hints, struct addrinfo **aip) {
+    int error;
+    static void *func = NULL;
+
+    S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: getaddrinfo: %s", hostname);
+    GetOriginalFunc(&func, "_getaddrinfo", TRY_LIBC | TRY_LIBNSL | TRY_LIBRESOLV);
+    if (!func || func == (void *)-1) return NULL;
+
+    lsInRLDFunctions = 1;
+    error = ((int (*)P((const char *, const char *, const struct addrinfo *,
+			struct addrinfo **)))func)(hostname, servname,
+						   hints, aip);
+    lsInRLDFunctions = 0;
+    S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "RLD: getaddrinfo results: %s %s", hostname, (*aip&&(*aip)->ai_canonname)?(*aip)->ai_canonname:"???");
+    return error;
 }
 #endif
 
--- lib/hostname.c.orig	Wed Aug  4 04:59:29 1999
+++ lib/hostname.c	Tue Feb 22 09:51:48 2000
@@ -17,6 +17,10 @@
 #define S5_HOSTLIST_SIZE    256
 #define S5_HOSTALIASES_SIZE 16
 #define S5_FAKEHOSTFILE     ".s5fakehost"
+
+#ifndef NI_WITHSCOPEID
+#define	NI_WITHSCOPEID	0
+#endif
  
 struct hostEntry {
     char name[S5_HOSTNAME_SIZE];
@@ -402,6 +406,129 @@
 }
 #endif
 
+#if defined(HAVE_GETADDRINFO) && defined(HAVE_GETNAMEINFO)
+/* wrapper around the getaddrinfo call.                                      */
+/* similar to getaddrinfo() except for:                                      */
+/* *** if getaddrinfo() fails, then it returns a pointer to a addrinfo       */
+/*     structure filled with a special value, so that SOCKSxxxxxx() will     */
+/*     realize that this host was unresolved and fill in the protocol        */
+/*     accordingly...                                                        */
+/*                                                                           */
+/* returns an error number on failure; 0 on success   */
+int LIBPREFIX(getaddrinfo)(const char *hostname, const char *servname,
+			    const struct addrinfo *hints,
+			    struct addrinfo **aip) {
+    static char numaddrbuf[MAXHOSTNAMELEN];
+    static struct addrinfo *ai;
+    char *local, *fake;
+    int error = 0, i;
+    int addrlen, namelen, family;
+
+#ifdef FOR_SHARED_LIBRARY
+    if (lsInRLDFunctions || lsInWrapFunction || lsInWrapHostname) return REAL(getaddrinfo)(hostname, servname, hints, aip);
+#endif
+
+    lsInWrapFunction = 1;
+    lsInWrapHostname = 1;
+    LIBPREFIX2(init)("libsocks5");
+    S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS getaddrinfo: looking up %s", hostname);
+
+    fake  = getenv("SOCKS5_FAKEALLHOSTS");
+    local = getenv("SOCKS5_LOCALDNSONLY");
+
+    if (!fake &&
+	(error = REAL(getaddrinfo)(hostname, servname, hints, aip)) == NULL) {
+        getnameinfo((*aip)->ai_addr, (*aip)->ai_addrlen, numaddrbuf,
+		    sizeof(numaddrbuf) - 1, NULL, 0,
+		    NI_NUMERICHOST|NI_WITHSCOPEID);
+	S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS getaddrinfo: REAL: %s", numaddrbuf);
+
+        lsInWrapFunction = 0;
+        lsInWrapHostname = 0;
+	return error;
+    }
+
+    /* If your DNS is the same as the socks server, don't fake a correct     */
+    /* lookup when you know it won't work...                                 */
+    if (local) {
+	S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS getaddrinfo: REAL: Fake not configured");
+        lsInWrapFunction = 0;
+        lsInWrapHostname = 0;
+	return (error != 0) ? error : EAI_FAIL;
+    }
+
+    /* Fill in some UNRESOLVED values and let the daemon resolve it          */
+    if ((i = GetFakeHost(hostname)) <= 0) {
+        S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "SOCKS getaddrinfo: Get fake host failed");
+        lsInWrapFunction = 0;
+        lsInWrapHostname = 0;
+	return (error != 0) ? error : EAI_FAIL;
+    }
+
+    /* create fake for AF_INET. Fake for AF_INET6 is not yet */
+    if (hints->ai_family == AF_UNSPEC || hints->ai_family == AF_INET) {
+        addrlen = sizeof(struct sockaddr_in);
+	family = AF_INET;
+        ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + addrlen);
+	if (ai == NULL)
+	    return EAI_MEMORY;
+	memcpy(ai, hints, sizeof(struct addrinfo));
+	ai->ai_family = family;
+	ai->ai_addr = (struct sockaddr *)(ai + 1);
+	memset(ai->ai_addr, 0, addrlen);
+	ai->ai_addr->sa_len = addrlen;
+	ai->ai_addrlen = addrlen;
+	ai->ai_addr->sa_family = family;
+	if (servname != NULL) {
+	    struct servent *sp;
+	    const char *p;
+	    int is_number, port;
+
+	    p = servname;
+	    is_number = 1;
+	    while (*p) {
+	        if (!isdigit(*p))
+		    is_number = 0;
+		p++;
+	    }
+	    if (is_number) {
+	        port = htons(atoi(servname));
+		if (port < 0 || port > 65535) {
+		    free(ai);
+		    return EAI_SERVICE;
+		}
+	    } else {
+	        sp = getservbyname(servname, NULL);
+		if (sp == NULL) {
+		    free(ai);
+		    return EAI_SERVICE;
+		}
+	        port = sp->s_port;		
+	    }
+	    ((struct sockaddr_in *)ai->ai_addr)->sin_port = port;
+	}
+	((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr = htonl(i);
+	if ((hints->ai_flags & AI_CANONNAME) != 0) {
+	    ai->ai_canonname = (char *)malloc(strlen(hostname) + 1);
+	    if (ai->ai_canonname == NULL) {
+	        free(ai);
+		return EAI_MEMORY;
+	    }
+	    strncpy(ai->ai_canonname, hostname, strlen(hostname) + 1);
+	}
+    } else
+        return EAI_FAMILY;
+    *aip = ai;
+
+    getnameinfo((*aip)->ai_addr, (*aip)->ai_addrlen, numaddrbuf,
+		sizeof(numaddrbuf) - 1, NULL, 0, NI_NUMERICHOST);
+    S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "SOCKS getaddrinfo: FAKE: %s",  numaddrbuf);
+    lsInWrapFunction = 0;
+    lsInWrapHostname = 0;
+    return 0;
+}
+#endif
+
 int lsGetCachedAddress(const char *name, S5NetAddr *na) {
     int i;
     char hostname[S5_HOSTNAME_SIZE];
--- configure.in.orig	Tue Aug  3 00:00:50 1999
+++ configure.in	Sun Feb 20 21:24:32 2000
@@ -120,6 +120,7 @@
 
 AC_CHECK_FUNCS(gethostbyname2)
 AC_CHECK_FUNCS(gethostbyname_r gethostbyaddr_r getpwuid_r getservbyname_r)
+AC_CHECK_FUNCS(getaddrinfo getnameinfo)
 AC_CHECK_FUNCS(memset memcmp memmove strchr strrchr strdup strerror)
 AC_CHECK_FUNCS(bcopy bcmp bzero index rindex)
 AC_CHECK_FUNCS(setenv putenv unsetenv getenv)
--- include/config.h.in.orig	Mon Aug  2 23:57:28 1999
+++ include/config.h.in	Sun Feb 20 21:20:53 2000
@@ -133,6 +133,12 @@
 /* Define if you have the gethostbyname_r function.  */
 #undef HAVE_GETHOSTBYNAME_R
 
+/* Define if you have the getaddrinfo function.  */
+#undef HAVE_GETADDRINFO
+
+/* Define if you have the getnameinfo function.  */
+#undef HAVE_GETNAMEINFO
+
 /* Define if you have the getifaddrs function.  */
 #undef HAVE_GETIFADDRS
 
--- include/hide.h.orig	Wed Aug  4 04:59:30 1999
+++ include/hide.h	Mon Feb 21 14:41:49 2000
@@ -19,6 +19,7 @@
 #ifdef HAVE_GETHOSTBYNAME2
 #define gethostbyname2 HIDE(gethostbyname2)
 #endif
+#define getaddrinfo   HIDE(getaddrinfo)
 #define gethostbyname HIDE(gethostbyname)
 #define getpeername   HIDE(getpeername)
 #define getsockname   HIDE(getsockname)
@@ -53,6 +54,7 @@
 #ifdef HAVE_GETHOSTBYNAME2
 #undef gethostbyname2 
 #endif
+#undef getaddrinfo
 #undef gethostbyname 
 #undef getpeername   
 #undef getsockname   
--- include/socks.h.orig	Wed Aug  4 04:59:30 1999
+++ include/socks.h	Mon Feb 21 14:44:03 2000
@@ -52,6 +52,9 @@
 #ifdef HAVE_GETHOSTBYNAME2
 extern struct hostent *LIBPREFIX(gethostbyname2) P((char *, int));
 #endif
+extern int LIBPREFIX(getaddrinfo) P((const char *, const char *,
+				     const struct addrinfo *,
+				     struct addrinfo **));
 #endif /* include prototypes */
 
 #ifndef LIBPREFIX
@@ -93,6 +96,7 @@
 #ifdef HAVE_GETHOSTBYNAME2
 #define gethostbyname2 LIBPREFIX(gethostbyname2)
 #endif
+#define getaddrinfo   LIBPREFIX(getaddrinfo)
 #define gethostbyname LIBPREFIX(gethostbyname)
 #define rresvport     LIBPREFIX(rresvport)
 #define connect       LIBPREFIX(connect)
--- include/system.h.orig	Wed Aug  4 04:59:30 1999
+++ include/system.h	Mon Feb 21 14:43:42 2000
@@ -24,6 +24,9 @@
 #ifdef HAVE_GETHOSTBYNAME2
 struct hostent * REAL(gethostbyname2) P((const char *, int));
 #endif
+int		 REAL(getaddrinfo) P((const char *, const char *,
+				      const struct addrinfo *,
+			 	      struct addrinfo **));
 struct hostent * REAL(gethostbyname) P((const char *));
 struct hostent * REAL(gethostbyaddr) P((const void *, int, int));
 struct servent * REAL(getservbyname) P((const char *, const char *)); 


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000307102707G.shin>