Friday, May 9, 2014

OS X and tsocks

I wanted to play around with tsocks, but it had multiple issues with compiling and working under OS X.  I downloaded 1.8 beta 5 (from 2002!) from http://tsocks.sourceforge.net/  Here are the patches that worked for me, collected from a number of places hiding on the web.
===================================================================
RCS file: RCS/Makefile.in,v
retrieving revision 1.1
diff -c -r1.1 Makefile.in
*** Makefile.in    2014/05/09 16:50:45    1.1
--- Makefile.in    2014/05/09 17:28:10
***************
*** 13,19 ****
  
  SHELL = /bin/sh
  MKINSTALLDIRS = ${SHELL} mkinstalldirs 
! SHCC = ${CC} -fPIC 
  INSPECT = inspectsocks
  SAVE = saveme
  LIB_NAME = libtsocks
--- 13,19 ----
  
  SHELL = /bin/sh
  MKINSTALLDIRS = ${SHELL} mkinstalldirs 
! SHCC = ${CC}
  INSPECT = inspectsocks
  SAVE = saveme
  LIB_NAME = libtsocks
***************
*** 23,29 ****
  SCRIPT = tsocks
  SHLIB_MAJOR = 1
  SHLIB_MINOR = 8
! SHLIB = ${LIB_NAME}.so.${SHLIB_MAJOR}.${SHLIB_MINOR}
  
  INSTALL = @INSTALL@
  INSTALL_DATA = @INSTALL_DATA@
--- 23,30 ----
  SCRIPT = tsocks
  SHLIB_MAJOR = 1
  SHLIB_MINOR = 8
! SHLIB = ${LIB_NAME}.dynlib
! DYNLIB_FLAGS=-dynamiclib
  
  INSTALL = @INSTALL@
  INSTALL_DATA = @INSTALL_DATA@
***************
*** 47,57 ****
      ${SHCC} ${CFLAGS} ${INCLUDES} -o ${INSPECT} ${INSPECT}.c ${COMMON}.o ${LIBS} 
  
  ${SAVE}: ${SAVE}.c
!     ${SHCC} ${CFLAGS} ${INCLUDES} -static -o ${SAVE} ${SAVE}.c
  
  ${SHLIB}: ${OBJS} ${COMMON}.o ${PARSER}.o
!     ${SHCC} ${CFLAGS} ${INCLUDES} -nostdlib -shared -o ${SHLIB} ${OBJS} ${COMMON}.o ${PARSER}.o ${DYNLIB_FLAGS} ${SPECIALLIBS} ${LIBS}
!     ln -sf ${SHLIB} ${LIB_NAME}.so
  
  %.so: %.c
      ${SHCC} ${CFLAGS} ${INCLUDES} -c ${CC_SWITCHES} $< -o $@
--- 48,57 ----
      ${SHCC} ${CFLAGS} ${INCLUDES} -o ${INSPECT} ${INSPECT}.c ${COMMON}.o ${LIBS} 
  
  ${SAVE}: ${SAVE}.c
!     ${SHCC} ${CFLAGS} ${INCLUDES} -o ${SAVE} ${SAVE}.c
  
  ${SHLIB}: ${OBJS} ${COMMON}.o ${PARSER}.o
!     ${SHCC} ${CFLAGS} ${INCLUDES} -o ${SHLIB} ${OBJS} ${COMMON}.o ${PARSER}.o ${DYNLIB_FLAGS} ${SPECIALLIBS} ${LIBS}
  
  %.so: %.c
      ${SHCC} ${CFLAGS} ${INCLUDES} -c ${CC_SWITCHES} $< -o $@
***************
*** 68,75 ****
  installlib:
      ${MKINSTALLDIRS} "${DESTDIR}${libdir}"
      ${INSTALL} ${SHLIB} ${DESTDIR}${libdir}
-     ln -sf ${SHLIB} ${DESTDIR}${libdir}/${LIB_NAME}.so.${SHLIB_MAJOR}
-     ln -sf ${LIB_NAME}.so.${SHLIB_MAJOR} ${DESTDIR}${libdir}/${LIB_NAME}.so
  
  installman:
      ${MKINSTALLDIRS} "${DESTDIR}${mandir}/man1"
--- 68,73 ----
===================================================================
RCS file: RCS/configure,v
retrieving revision 1.1
diff -c -r1.1 configure
*** configure    2014/05/09 16:42:31    1.1
--- configure    2014/05/09 16:42:45
***************
*** 4287,4293 ****
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct poll prototype" >&5
  $as_echo_n "checking for correct poll prototype... " >&6; }
  PROTO=
! for testproto in 'struct pollfd *ufds, unsigned long nfds, int timeout'
  do
    if test "${PROTO}" = ""; then
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
--- 4287,4293 ----
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct poll prototype" >&5
  $as_echo_n "checking for correct poll prototype... " >&6; }
  PROTO=
! for testproto in 'struct pollfd *ufds, nfds_t nfds, int timeout'
  do
    if test "${PROTO}" = ""; then
      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
===================================================================
RCS file: RCS/tsocks.c,v
retrieving revision 1.1
diff -c -r1.1 tsocks.c
*** tsocks.c    2014/05/09 16:45:58    1.1
--- tsocks.c    2014/05/09 17:25:16
***************
*** 68,74 ****
  static char *conffile = NULL;
  
  /* Exported Function Prototypes */
- void _init(void);
  int connect(CONNECT_SIGNATURE);
  int select(SELECT_SIGNATURE);
  int poll(POLL_SIGNATURE);
--- 68,73 ----
***************
*** 100,105 ****
--- 99,105 ----
  static int read_socksv5_connect(struct connreq *conn);
  static int read_socksv5_auth(struct connreq *conn);
  
+ __attribute__((constructor))
  void _init(void) {
  #ifdef USE_OLD_DLSYM
      void *lib;
***************
*** 191,199 ****
      struct sockaddr_in *connaddr;
      struct sockaddr_in peer_address;
      struct sockaddr_in server_address;
!    int gotvalidserver = 0, rc, namelen = sizeof(peer_address);
      int sock_type = -1;
!     int sock_type_len = sizeof(sock_type);
      unsigned int res = -1;
      struct serverent *path;
     struct connreq *newconn;
--- 191,200 ----
      struct sockaddr_in *connaddr;
      struct sockaddr_in peer_address;
      struct sockaddr_in server_address;
!     int gotvalidserver = 0, rc;
!     socklen_t namelen = sizeof(peer_address);
      int sock_type = -1;
!     socklen_t sock_type_len = sizeof(sock_type);
      unsigned int res = -1;
      struct serverent *path;
     struct connreq *newconn;
I also rewrote the actual tsocks shell script, fixing it up for OS X in the process.
#!/bin/sh
# Wrapper script for use of the tsocks(8) transparent socksification library
#
# There are three forms of usage for this script:
#
# /usr/bin/tsocks program [program arguments...]
#
# This form sets the users DYLD_INSERT_LIBRARIES environment variable so that tsocks(8) 
# will be loaded to socksify the application then executes the specified 
# program (with the provided arguments). The following simple example might 
# be used to telnet to www.foo.org via a tsocks.conf(5) configured socks server:
#
# /usr/bin/tsocks telnet www.foo.org
#
# The second form allows for tsocks(8) to be switched on and off for a 
# session (that is, it adds and removes tsocks from the DYLD_INSERT_LIBRARIES environment
# variable). This form must be _sourced_ into the user's existing session
# (and will only work with bourne shell users):
#
# . /usr/bin/tsocks on
# telnet www.foo.org 
# . /usr/bin/tsocks off
# 
# Or
# 
# source /usr/bin/tsocks on
# telnet www.foo.org
# source /usr/bin/tsocks off
#
# The third form creates a new shell with DYLD_INSERT_LIBRARIES set and is achieved
# simply by running the script with no arguments 
# 
# /usr/bin/tsocks
#
# When finished the user can simply terminate the shell with 'exit'
# 
# This script is originally from the debian tsocks package by 
# Tamas Szerb <toma@rulez.org>

if [ $# = 0 ] ; then
   echo "$0: insufficient arguments"
   exit
fi

case "$1" in
    on)
        export DYLD_FORCE_FLAT_NAMESPACE=1 
        export DYLD_INSERT_LIBRARIES="/lib/libtsocks.dynlib"
        ;;
    off)
        unset DYLD_FORCE_FLAT_NAMESPACE
        unset DYLD_INSERT_LIBRARIES
        ;;
    show|sh)
        echo "DYLD_INSERT_LIBRARIES=\"$DYLD_INSERT_LIBRARIES\""
        ;;
    -h|-?)
        echo "$0: Please see tsocks(1) or read comment at top of $0"
        ;;
    *)
        export DYLD_FORCE_FLAT_NAMESPACE=1 
        export DYLD_INSERT_LIBRARIES="/lib/libtsocks.dynlib"

        if [ $# = 0 ]
        then
            ${SHELL:-/bin/sh}
        fi

        if [ $# -gt 0 ]
        then
            exec "$@"
        fi
    ;;
esac

#EOF

Hope this helps someone.

No comments: