--- Begin Message ---
Package: tsocks
Version: 1.8beta5-1.1
Severity: normal
Tags: patch
If we are not done setting up the connection yet, getpeername() should
return -1 and ENOTCONN.
This is necessary since some applications, when using non-blocking connect,
(like ircII) use getpeername() to find out if they are connected already.
This results in races sometimes, where the client sends data to the socket
before we are done with the socks connection setup. Another solution would
be to intercept send().
This could be extended to actually set the peername to the peer the
client application has requested, but not for now.
diff -ur tsocks-1.8beta5.orig/acconfig.h tsocks-1.8beta5.clean/acconfig.h
--- tsocks-1.8beta5.orig/acconfig.h Sat May 18 06:59:38 2002
+++ tsocks-1.8beta5.clean/acconfig.h Sat Mar 27 11:12:03 2004
@@ -43,6 +43,9 @@
/* Prototype and function header for close function */
#undef CLOSE_SIGNATURE
+/* Prototype and function header for getpeername function */
+#undef GETPEERNAME_SIGNATURE
+
/* Work out which function we have for conversion from string IPs to
numerical ones */
#undef HAVE_INET_ADDR
diff -ur tsocks-1.8beta5.orig/config.h.in tsocks-1.8beta5.clean/config.h.in
--- tsocks-1.8beta5.orig/config.h.in Sat May 18 06:59:42 2002
+++ tsocks-1.8beta5.clean/config.h.in Sat Mar 27 11:21:58 2004
@@ -46,6 +46,9 @@
/* Prototype and function header for close function */
#undef CLOSE_SIGNATURE
+/* Prototype and function header for close function */
+#undef GETPEERNAME_SIGNATURE
+
/* Work out which function we have for conversion from string IPs to
numerical ones */
#undef HAVE_INET_ADDR
diff -ur tsocks-1.8beta5.orig/config.status tsocks-1.8beta5.clean/config.status
--- tsocks-1.8beta5.orig/config.status Sat Mar 27 11:25:17 2004
+++ tsocks-1.8beta5.clean/config.status Sat Mar 27 11:22:01 2004
@@ -2,9 +2,9 @@
# Generated automatically by configure.
# Run this file to recreate the current configuration.
# This directory was configured as follows,
-# on host inky:
+# on host seppia:
#
-# ./configure --prefix=/usr --libdir=/usr/lib --mandir=/usr/share/man
--with-conf=/etc/tsocks.conf --enable-socksdns --enable-hostnames
+# ./configure
#
# Compiler output produced by configure, useful for debugging
# configure, is in ./config.log if it exists.
@@ -14,8 +14,8 @@
do
case "$ac_option" in
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
- echo "running ${CONFIG_SHELL-/bin/sh} ./configure --prefix=/usr
--libdir=/usr/lib --mandir=/usr/share/man --with-conf=/etc/tsocks.conf
--enable-socksdns --enable-hostnames --no-create --no-recursion"
- exec ${CONFIG_SHELL-/bin/sh} ./configure --prefix=/usr --libdir=/usr/lib
--mandir=/usr/share/man --with-conf=/etc/tsocks.conf --enable-socksdns
--enable-hostnames --no-create --no-recursion ;;
+ echo "running ${CONFIG_SHELL-/bin/sh} ./configure --no-create
--no-recursion"
+ exec ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion ;;
-version | --version | --versio | --versi | --vers | --ver | --ve | --v)
echo "./config.status generated by autoconf version 2.13"
exit 0 ;;
@@ -53,11 +53,11 @@
[EMAIL PROTECTED]@%${prefix}/etc%g
[EMAIL PROTECTED]@%${prefix}/com%g
[EMAIL PROTECTED]@%${prefix}/var%g
[EMAIL PROTECTED]@%/usr/lib%g
[EMAIL PROTECTED]@%/lib%g
[EMAIL PROTECTED]@%${prefix}/include%g
[EMAIL PROTECTED]@%/usr/include%g
[EMAIL PROTECTED]@%${prefix}/info%g
[EMAIL PROTECTED]@%/usr/share/man%g
[EMAIL PROTECTED]@%${prefix}/man%g
[EMAIL PROTECTED]@%i686-pc-linux-gnu%g
[EMAIL PROTECTED]@%i686-pc-linux-gnu%g
[EMAIL PROTECTED]@%i686%g
@@ -255,15 +255,15 @@
mv conftest.out conftest.in
cat > conftest.frag <<CEOF
-${ac_dA}USE_SOCKS_DNS${ac_dB}USE_SOCKS_DNS${ac_dC}1${ac_dD}
-${ac_uA}USE_SOCKS_DNS${ac_uB}USE_SOCKS_DNS${ac_uC}1${ac_uD}
-${ac_eA}USE_SOCKS_DNS${ac_eB}USE_SOCKS_DNS${ac_eC}1${ac_eD}
${ac_dA}ALLOW_ENV_CONFIG${ac_dB}ALLOW_ENV_CONFIG${ac_dC}1${ac_dD}
${ac_uA}ALLOW_ENV_CONFIG${ac_uB}ALLOW_ENV_CONFIG${ac_uC}1${ac_uD}
${ac_eA}ALLOW_ENV_CONFIG${ac_eB}ALLOW_ENV_CONFIG${ac_eC}1${ac_eD}
${ac_dA}ALLOW_MSG_OUTPUT${ac_dB}ALLOW_MSG_OUTPUT${ac_dC}1${ac_dD}
${ac_uA}ALLOW_MSG_OUTPUT${ac_uB}ALLOW_MSG_OUTPUT${ac_uC}1${ac_uD}
${ac_eA}ALLOW_MSG_OUTPUT${ac_eB}ALLOW_MSG_OUTPUT${ac_eC}1${ac_eD}
+${ac_dA}HOSTNAMES${ac_dB}HOSTNAMES${ac_dC}1${ac_dD}
+${ac_uA}HOSTNAMES${ac_uB}HOSTNAMES${ac_uC}1${ac_uD}
+${ac_eA}HOSTNAMES${ac_eB}HOSTNAMES${ac_eC}1${ac_eD}
${ac_dA}SELECT_SIGNATURE${ac_dB}SELECT_SIGNATURE${ac_dC}int n, fd_set
*readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout${ac_dD}
${ac_uA}SELECT_SIGNATURE${ac_uB}SELECT_SIGNATURE${ac_uC}int n, fd_set
*readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout${ac_uD}
${ac_eA}SELECT_SIGNATURE${ac_eB}SELECT_SIGNATURE${ac_eC}int n, fd_set
*readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout${ac_eD}
@@ -282,15 +282,18 @@
${ac_dA}CLOSE_SIGNATURE${ac_dB}CLOSE_SIGNATURE${ac_dC}int fd${ac_dD}
${ac_uA}CLOSE_SIGNATURE${ac_uB}CLOSE_SIGNATURE${ac_uC}int fd${ac_uD}
${ac_eA}CLOSE_SIGNATURE${ac_eB}CLOSE_SIGNATURE${ac_eC}int fd${ac_eD}
-${ac_dA}POLL_SIGNATURE${ac_dB}POLL_SIGNATURE${ac_dC}struct pollfd *ufds,
unsigned long nfds, int timeout${ac_dD}
-${ac_uA}POLL_SIGNATURE${ac_uB}POLL_SIGNATURE${ac_uC}struct pollfd *ufds,
unsigned long nfds, int timeout${ac_uD}
-${ac_eA}POLL_SIGNATURE${ac_eB}POLL_SIGNATURE${ac_eC}struct pollfd *ufds,
unsigned long nfds, int timeout${ac_eD}
+${ac_dA}GETPEERNAME_SIGNATURE${ac_dB}GETPEERNAME_SIGNATURE${ac_dC}int __fd,
struct sockaddr * __name, socklen_t *__namelen${ac_dD}
+${ac_uA}GETPEERNAME_SIGNATURE${ac_uB}GETPEERNAME_SIGNATURE${ac_uC}int __fd,
struct sockaddr * __name, socklen_t *__namelen${ac_uD}
+${ac_eA}GETPEERNAME_SIGNATURE${ac_eB}GETPEERNAME_SIGNATURE${ac_eC}int __fd,
struct sockaddr * __name, socklen_t *__namelen${ac_eD}
CEOF
sed -f conftest.frag conftest.in > conftest.out
rm -f conftest.in
mv conftest.out conftest.in
cat > conftest.frag <<CEOF
+${ac_dA}POLL_SIGNATURE${ac_dB}POLL_SIGNATURE${ac_dC}struct pollfd *ufds,
unsigned long nfds, int timeout${ac_dD}
+${ac_uA}POLL_SIGNATURE${ac_uB}POLL_SIGNATURE${ac_uC}struct pollfd *ufds,
unsigned long nfds, int timeout${ac_uD}
+${ac_eA}POLL_SIGNATURE${ac_eB}POLL_SIGNATURE${ac_eC}struct pollfd *ufds,
unsigned long nfds, int timeout${ac_eD}
s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
CEOF
sed -f conftest.frag conftest.in > conftest.out
diff -ur tsocks-1.8beta5.orig/configure tsocks-1.8beta5.clean/configure
--- tsocks-1.8beta5.orig/configure Tue Jul 16 00:51:08 2002
+++ tsocks-1.8beta5.clean/configure Sat Mar 27 11:12:05 2004
@@ -2225,14 +2225,60 @@
EOF
+
+echo $ac_n "checking for correct getpeername prototype""... $ac_c" 1>&6
+echo "configure:2231: checking for correct getpeername prototype" >&5
+PROTO=
+PROTO1='int __fd, const struct sockaddr * __name, int *__namelen'
+PROTO2='int __fd, const struct sockaddr_in * __name, socklen_t *__namelen'
+PROTO3='int __fd, struct sockaddr * __name, socklen_t *__namelen'
+PROTO4='int __fd, const struct sockaddr * __name, socklen_t *__namelen'
+for testproto in "${PROTO1}" \
+ "${PROTO2}" \
+ "${PROTO3}" \
+ "${PROTO4}"
+do
+ if test "${PROTO}" = ""; then
+ cat > conftest.$ac_ext <<EOF
+#line 2244 "configure"
+#include "confdefs.h"
+
+ #include <sys/socket.h>
+ int getpeername($testproto);
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2254: \"$ac_compile\") 1>&5; (eval $ac_compile)
2>&5; }; then
+ rm -rf conftest*
+ PROTO="$testproto";
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ fi
+done
+if test "${PROTO}" = ""; then
+ { echo "configure: error: "no match found!"" 1>&2; exit 1; }
+fi
+echo "$ac_t""getpeername(${PROTO})" 1>&6
+cat >> confdefs.h <<EOF
+#define GETPEERNAME_SIGNATURE ${PROTO}
+EOF
+
+
+
+
echo $ac_n "checking for correct poll prototype""... $ac_c" 1>&6
-echo "configure:2230: checking for correct poll prototype" >&5
+echo "configure:2276: checking for correct poll prototype" >&5
PROTO=
for testproto in 'struct pollfd *ufds, unsigned long nfds, int timeout'
do
if test "${PROTO}" = ""; then
cat > conftest.$ac_ext <<EOF
-#line 2236 "configure"
+#line 2282 "configure"
#include "confdefs.h"
#include <sys/poll.h>
@@ -2242,7 +2288,7 @@
; return 0; }
EOF
-if { (eval echo configure:2246: \"$ac_compile\") 1>&5; (eval $ac_compile)
2>&5; }; then
+if { (eval echo configure:2292: \"$ac_compile\") 1>&5; (eval $ac_compile)
2>&5; }; then
rm -rf conftest*
PROTO="$testproto";
else
diff -ur tsocks-1.8beta5.orig/configure.in tsocks-1.8beta5.clean/configure.in
--- tsocks-1.8beta5.orig/configure.in Tue Jul 16 00:51:03 2002
+++ tsocks-1.8beta5.clean/configure.in Sat Mar 27 11:11:02 2004
@@ -309,6 +309,34 @@
AC_MSG_RESULT([close(${PROTO})])
AC_DEFINE_UNQUOTED(CLOSE_SIGNATURE, [${PROTO}])
+
+dnl Find the correct getpeername prototype on this machine
+AC_MSG_CHECKING(for correct getpeername prototype)
+PROTO=
+PROTO1='int __fd, const struct sockaddr * __name, int *__namelen'
+PROTO2='int __fd, const struct sockaddr_in * __name, socklen_t *__namelen'
+PROTO3='int __fd, struct sockaddr * __name, socklen_t *__namelen'
+PROTO4='int __fd, const struct sockaddr * __name, socklen_t *__namelen'
+for testproto in "${PROTO1}" \
+ "${PROTO2}" \
+ "${PROTO3}" \
+ "${PROTO4}"
+do
+ if test "${PROTO}" = ""; then
+ AC_TRY_COMPILE([
+ #include <sys/socket.h>
+ int getpeername($testproto);
+ ],,[PROTO="$testproto";],)
+ fi
+done
+if test "${PROTO}" = ""; then
+ AC_MSG_ERROR("no match found!")
+fi
+AC_MSG_RESULT([getpeername(${PROTO})])
+AC_DEFINE_UNQUOTED(GETPEERNAME_SIGNATURE, [${PROTO}])
+
+
+
dnl Find the correct poll prototype on this machine
AC_MSG_CHECKING(for correct poll prototype)
PROTO=
Only in tsocks-1.8beta5.clean: ld-pre
Only in tsocks-1.8beta5.clean: sel
diff -ur tsocks-1.8beta5.orig/tsocks.c tsocks-1.8beta5.clean/tsocks.c
--- tsocks-1.8beta5.orig/tsocks.c Tue Jul 16 00:50:52 2002
+++ tsocks-1.8beta5.clean/tsocks.c Sat Mar 27 11:31:54 2004
@@ -62,6 +62,7 @@
static int (*realselect)(SELECT_SIGNATURE);
static int (*realpoll)(POLL_SIGNATURE);
static int (*realclose)(CLOSE_SIGNATURE);
+static int (*realgetpeername)(GETPEERNAME_SIGNATURE);
static struct parsedfile *config;
static struct connreq *requests = NULL;
static int suid = 0;
@@ -73,6 +74,7 @@
int select(SELECT_SIGNATURE);
int poll(POLL_SIGNATURE);
int close(CLOSE_SIGNATURE);
+int getpeername(GETPEERNAME_SIGNATURE);
#ifdef USE_SOCKS_DNS
int res_init(void);
#endif
@@ -109,14 +111,15 @@
/* most programs that are run won't use our services, so */
/* we do our general initialization on first call */
- /* Determine the logging level */
- suid = (getuid() != geteuid());
+ /* Determine the logging level */
+ suid = (getuid() != geteuid());
#ifndef USE_OLD_DLSYM
realconnect = dlsym(RTLD_NEXT, "connect");
realselect = dlsym(RTLD_NEXT, "select");
realpoll = dlsym(RTLD_NEXT, "poll");
realclose = dlsym(RTLD_NEXT, "close");
+ realgetpeername = dlsym(RTLD_NEXT, "getpeername");
#ifdef USE_SOCKS_DNS
realresinit = dlsym(RTLD_NEXT, "res_init");
#endif
@@ -125,14 +128,15 @@
realconnect = dlsym(lib, "connect");
realselect = dlsym(lib, "select");
realpoll = dlsym(lib, "poll");
+ realgetpeername = dlsym(lib, "getpeername");
#ifdef USE_SOCKS_DNS
realresinit = dlsym(lib, "res_init");
#endif
- dlclose(lib);
+ dlclose(lib);
lib = dlopen(LIBC, RTLD_LAZY);
- realclose = dlsym(lib, "close");
- dlclose(lib);
+ realclose = dlsym(lib, "close");
+ dlclose(lib);
#endif
}
@@ -348,8 +352,10 @@
/* If we're not currently managing any requests we can just
* leave here */
- if (!requests)
+ if (!requests) {
+ show_msg(MSGDEBUG, "No requests waiting, calling real select\n");
return(realselect(n, readfds, writefds, exceptfds, timeout));
+ }
get_environment();
@@ -703,6 +709,42 @@
return(rc);
}
+/* If we are not done setting up the connection yet, return
+ * -1 and ENOTCONN, otherwise call getpeername
+ *
+ * This is necessary since some applications, when using non-blocking connect,
+ * (like ircII) use getpeername() to find out if they are connected already.
+ *
+ * This results in races sometimes, where the client sends data to the socket
+ * before we are done with the socks connection setup. Another solution would
+ * be to intercept send().
+ *
+ * This could be extended to actually set the peername to the peer the
+ * client application has requested, but not for now.
+ *
+ * PP, Sat, 27 Mar 2004 11:30:23 +0100
+ */
+int getpeername(GETPEERNAME_SIGNATURE) {
+ struct connreq *newconn;
+
+ if (realgetpeername == NULL) {
+ show_msg(MSGERR, "Unresolved symbol: getpeername\n");
+ return(-1);
+ }
+
+ show_msg(MSGDEBUG, "Call to getpeername for fd %d\n", __fd);
+
+ /* Are we already handling this connect? */
+ if ((newconn = find_socks_request(__fd, 1))) {
+ if (newconn->state == CONNECTING) {
+ errno = ENOTCONN;
+ return(-1);
+ }
+ }
+
+ return (realgetpeername(__fd, __name, __namelen));
+}
+
static struct connreq *new_socks_request(int sockid, struct sockaddr_in
*connaddr,
struct sockaddr_in *serveraddr,
struct serverent *path) {
@@ -852,7 +894,7 @@
sizeof(conn->serveraddr));
show_msg(MSGDEBUG, "Connect returned %d, errno is %d\n", rc, errno);
- if (rc) {
+ if (rc) {
if (errno != EINPROGRESS) {
show_msg(MSGERR, "Error %d attempting to connect to SOCKS "
"server (%s)\n", errno, strerror(errno));
signature.asc
Description: Digital signature
--- End Message ---