Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:bmwiedemann
tsocks
tsocks-1.8beta5-socks4a.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File tsocks-1.8beta5-socks4a.diff of Package tsocks
diff -Naurd tsocks-1.8/README.socks4a tsocks-1.8-socks4a/README.socks4a --- tsocks-1.8/README.socks4a 1970-01-01 01:00:00.000000000 +0100 +++ tsocks-1.8-socks4a/README.socks4a 2005-08-25 20:31:56.000000000 +0200 @@ -0,0 +1,12 @@ +To keep the patch small, the configure script was only modified in configure.in +for the patch, so you first need to regenerate configure using +'autoreconf -i -s'. +gethostbyname and getaddrinfo are intercepted and return virtual addresses in +the 127.0.0.0/8 space, which are translated back into domain names when sending +socks connect requests. The domain names are saved in files located at +~/.tsocks-socks4a/virtual-ips, and are not deleted automatically by tsocks. +Therefore, a cron script tmpreaper-tsocks-socks4a.cron is provided to clean up +unused domains after a week. tmpreaper +(http://ftp.debian.org/debian/pool/main/t/tmpreaper) is needed to run the +script. +Send comments to eezyy@gmx.net diff -Naurd tsocks-1.8/configure.in tsocks-1.8-socks4a/configure.in --- tsocks-1.8/configure.in 2002-07-16 00:51:03.000000000 +0200 +++ tsocks-1.8-socks4a/configure.in 2005-08-25 20:20:55.000000000 +0200 @@ -327,6 +327,46 @@ AC_MSG_RESULT([poll(${PROTO})]) AC_DEFINE_UNQUOTED(POLL_SIGNATURE, [${PROTO}]) +dnl Find the correct getaddrinfo prototype on this machine +AC_MSG_CHECKING(for correct getaddrinfo prototype) +PROTO= +for testproto in 'const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res' +do + if test "${PROTO}" = ""; then + AC_TRY_COMPILE([ + #include <sys/types.h> + #include <sys/socket.h> + #include <netdb.h> + int getaddrinfo($testproto); + ],,[PROTO="$testproto";],) + fi +done +if test "${PROTO}" = ""; then + AC_MSG_ERROR("no match found!") +fi +AC_MSG_RESULT([getaddrinfo(${PROTO})]) +AC_DEFINE_UNQUOTED(GETADDRINFO_SIGNATURE, [${PROTO}], + [calling signature for getaddrinfo()]) + +dnl Find the correct gethostbyname prototype on this machine +AC_MSG_CHECKING(for correct gethostbyname prototype) +PROTO= +for testproto in 'const char *name' +do + if test "${PROTO}" = ""; then + AC_TRY_COMPILE([ + #include <netdb.h> + struct hostent *gethostbyname($testproto); + ],,[PROTO="$testproto";],) + fi +done +if test "${PROTO}" = ""; then + AC_MSG_ERROR("no match found!") +fi +AC_MSG_RESULT([gethostbyname(${PROTO})]) +AC_DEFINE_UNQUOTED(GETHOSTBYNAME_SIGNATURE, [${PROTO}], + [calling signature for gethostbyname()]) + dnl Output the special librarys (libdl etc needed for tsocks) SPECIALLIBS=${LIBS} AC_SUBST(SPECIALLIBS) diff -Naurd tsocks-1.8/parser.c tsocks-1.8-socks4a/parser.c --- tsocks-1.8/parser.c 2002-03-13 13:34:22.000000000 +0100 +++ tsocks-1.8-socks4a/parser.c 2005-08-25 20:20:55.000000000 +0200 @@ -31,7 +31,7 @@ static int handle_local(struct parsedfile *, int, char *); static int handle_defuser(struct parsedfile *, int, char *); static int handle_defpass(struct parsedfile *, int, char *); -static int make_netent(char *value, struct netent **ent); +static int make_netent(char *value, struct tsocks_netent **ent); int read_config (char *filename, struct parsedfile *config) { FILE *conf; @@ -75,7 +75,7 @@ fclose(conf); /* Always add the 127.0.0.1/255.0.0.0 subnet to local */ - handle_local(config, 0, "127.0.0.0/255.0.0.0"); + handle_local(config, 0, "127.0.0.1/255.255.255.255"); /* Check default server */ check_server(&(config->defaultserver)); @@ -242,7 +242,7 @@ static int handle_reaches(struct parsedfile *config, int lineno, char *value) { int rc; - struct netent *ent; + struct tsocks_netent *ent; rc = make_netent(value, &ent); switch(rc) { @@ -420,7 +420,7 @@ static int handle_local(struct parsedfile *config, int lineno, char *value) { int rc; - struct netent *ent; + struct tsocks_netent *ent; if (currentcontext != &(config->defaultserver)) { show_msg(MSGERR, "Local networks cannot be specified in path " @@ -485,7 +485,7 @@ /* Construct a netent given a string like */ /* "198.126.0.1[:portno[-portno]]/255.255.255.0" */ -int make_netent(char *value, struct netent **ent) { +int make_netent(char *value, struct tsocks_netent **ent) { char *ip; char *subnet; char *startport = NULL; @@ -517,7 +517,7 @@ } /* Allocate the new entry */ - if ((*ent = (struct netent *) malloc(sizeof(struct netent))) + if ((*ent = (struct tsocks_netent *) malloc(sizeof(struct tsocks_netent))) == NULL) { /* If we couldn't malloc some storage, leave */ exit(1); @@ -578,7 +578,7 @@ } int is_local(struct parsedfile *config, struct in_addr *testip) { - struct netent *ent; + struct tsocks_netent *ent; for (ent = (config->localnets); ent != NULL; ent = ent -> next) { if ((testip->s_addr & ent->localnet.s_addr) == @@ -593,7 +593,7 @@ /* Find the appropriate server to reach an ip */ int pick_server(struct parsedfile *config, struct serverent **ent, struct in_addr *ip, unsigned int port) { - struct netent *net; + struct tsocks_netent *net; char ipbuf[64]; show_msg(MSGDEBUG, "Picking appropriate server for %s\n", inet_ntoa(*ip)); diff -Naurd tsocks-1.8/parser.h tsocks-1.8-socks4a/parser.h --- tsocks-1.8/parser.h 2002-02-10 08:26:27.000000000 +0100 +++ tsocks-1.8-socks4a/parser.h 2005-08-25 20:20:56.000000000 +0200 @@ -15,22 +15,22 @@ int type; /* Type of server (4/5) */ char *defuser; /* Default username for this socks server */ char *defpass; /* Default password for this socks server */ - struct netent *reachnets; /* Linked list of nets from this server */ + struct tsocks_netent *reachnets; /* Linked list of nets from this server */ struct serverent *next; /* Pointer to next server entry */ }; /* Structure representing a network */ -struct netent { +struct tsocks_netent { struct in_addr localip; /* Base IP of the network */ struct in_addr localnet; /* Mask for the network */ unsigned long startport; /* Range of ports for the */ unsigned long endport; /* network */ - struct netent *next; /* Pointer to next network entry */ + struct tsocks_netent *next; /* Pointer to next network entry */ }; /* Structure representing a complete parsed file */ struct parsedfile { - struct netent *localnets; + struct tsocks_netent *localnets; struct serverent defaultserver; struct serverent *paths; }; diff -Naurd tsocks-1.8/tmpreaper-tsocks-socks4a.cron tsocks-1.8-socks4a/tmpreaper-tsocks-socks4a.cron --- tsocks-1.8/tmpreaper-tsocks-socks4a.cron 1970-01-01 01:00:00.000000000 +0100 +++ tsocks-1.8-socks4a/tmpreaper-tsocks-socks4a.cron 2005-08-25 20:20:56.000000000 +0200 @@ -0,0 +1,3 @@ +#!/bin/sh +/usr/sbin/tmpreaper 168 `locate tsocks-socks4a/clean|sed\ + 's/clean$/virtual-ips/'` diff -Naurd tsocks-1.8/tsocks.c tsocks-1.8-socks4a/tsocks.c --- tsocks-1.8/tsocks.c 2002-07-16 00:50:52.000000000 +0200 +++ tsocks-1.8-socks4a/tsocks.c 2005-08-30 18:03:47.000000000 +0200 @@ -51,6 +51,8 @@ #ifdef USE_SOCKS_DNS #include <resolv.h> #endif +#include <netdb.h> +#include <time.h> #include <parser.h> #include <tsocks.h> @@ -58,6 +60,8 @@ #ifdef USE_SOCKS_DNS static int (*realresinit)(void); #endif +static int (*realgetaddrinfo)(GETADDRINFO_SIGNATURE); +static struct hostent*(*realgethostbyname)(GETHOSTBYNAME_SIGNATURE); static int (*realconnect)(CONNECT_SIGNATURE); static int (*realselect)(SELECT_SIGNATURE); static int (*realpoll)(POLL_SIGNATURE); @@ -66,9 +70,13 @@ static struct connreq *requests = NULL; static int suid = 0; static char *conffile = NULL; +static char *proxy_directory = NULL; +static int filename_length; /* Exported Function Prototypes */ void _init(void); +int getaddrinfo(GETADDRINFO_SIGNATURE); +struct hostent *gethostbyname(GETHOSTBYNAME_SIGNATURE); int connect(CONNECT_SIGNATURE); int select(SELECT_SIGNATURE); int poll(POLL_SIGNATURE); @@ -99,8 +107,13 @@ static int read_socksv4_req(struct connreq *conn); static int read_socksv5_connect(struct connreq *conn); static int read_socksv5_auth(struct connreq *conn); +static char*virtual_resolved_ip(const char*domain); +static int is_numeric_address(const char*domain); void _init(void) { + char*directory_suffix="/.tsocks-socks4a/virtual-ips"; + char*home=getenv("HOME"); + char*after_home; #ifdef USE_OLD_DLSYM void *lib; #endif @@ -113,6 +126,8 @@ suid = (getuid() != geteuid()); #ifndef USE_OLD_DLSYM + realgetaddrinfo = dlsym(RTLD_NEXT, "getaddrinfo"); + realgethostbyname = dlsym(RTLD_NEXT, "gethostbyname"); realconnect = dlsym(RTLD_NEXT, "connect"); realselect = dlsym(RTLD_NEXT, "select"); realpoll = dlsym(RTLD_NEXT, "poll"); @@ -122,6 +137,8 @@ #endif #else lib = dlopen(LIBCONNECT, RTLD_LAZY); + realgetaddrinfo = dlsym(lib, "getaddrinfo"); + realgethostbyname = dlsym(lib, "gethostbyname"); realconnect = dlsym(lib, "connect"); realselect = dlsym(lib, "select"); realpoll = dlsym(lib, "poll"); @@ -134,6 +151,18 @@ realclose = dlsym(lib, "close"); dlclose(lib); #endif + srandom(time(0)); + proxy_directory=malloc(strlen(home)+strlen(directory_suffix)+1); + strcpy(proxy_directory,home); + after_home=proxy_directory+strlen(home); + strcpy(after_home,"/.tsocks-socks4a"); + mkdir(proxy_directory,0777); + strcpy(after_home,"/.tsocks-socks4a/clean"); + close(creat(proxy_directory,0666)); + strcpy(after_home,directory_suffix); + mkdir(proxy_directory,0777); + filename_length=strlen(proxy_directory)+ + strlen("/127.255.255.255")+1; } static int get_environment() { @@ -187,6 +216,66 @@ } +char*virtual_resolved_ip(const char*domain) { + int proxy_address[3]={0,0,1}; + int digit; + int host_file_descriptor; + char*filename; + struct stat file_info; + size_t name_size; + filename=malloc(filename_length); + if(strcmp("localhost",domain)) { + do { + do + for(digit=0;digit<3;digit++) + proxy_address[digit]=random()%255; + while(proxy_address[0]==0&&proxy_address[1]==0&&proxy_address[2]==1); + snprintf(filename,filename_length,"%s/127.%d.%d.%d",proxy_directory, + proxy_address[0],proxy_address[1],proxy_address[2]); + } while(!stat(filename,&file_info)); + host_file_descriptor=creat(filename,0666); + name_size=strlen(domain)+1; + write(host_file_descriptor,&name_size,sizeof(name_size)); + write(host_file_descriptor,domain,name_size); + close(host_file_descriptor); + } + snprintf(filename,filename_length,"127.%d.%d.%d",proxy_address[0], + proxy_address[1],proxy_address[2]); + return filename; +} + +int is_numeric_address(const char*domain) { + char*scanned; + for(scanned=domain;*scanned;scanned++) + if(((*scanned<'0')||(*scanned>'9'))&&*scanned!='.') + return 0; + return 1; +} + +int getaddrinfo(GETADDRINFO_SIGNATURE) { + int result; + if(is_numeric_address(node)) + result=(*realgetaddrinfo)(node,service,hints,res); + else { + char*filename=virtual_resolved_ip(node); + result=(*realgetaddrinfo)(filename,service,hints,res); + free(filename); + } + return result; +} + +struct hostent*gethostbyname(GETHOSTBYNAME_SIGNATURE) { + struct hostent*result; + if(is_numeric_address(name)) + result=(*realgethostbyname)(name); + else { + char*filename=virtual_resolved_ip(name); + result=(*realgethostbyname)(filename); + free(filename); + } + return result; +} + int connect(CONNECT_SIGNATURE) { struct sockaddr_in *connaddr; struct sockaddr_in peer_address; @@ -883,16 +972,33 @@ static int send_socksv4_request(struct connreq *conn) { struct passwd *user; struct sockreq *thisreq; - + char*filename; + char*hostname=NULL; + int host_file_descriptor; + size_t hostname_length; + char*username; /* Determine the current username */ user = getpwuid(getuid()); thisreq = (struct sockreq *) conn->buffer; - - /* Check the buffer has enough space for the request */ - /* and the user name */ + filename=malloc(filename_length); + snprintf(filename,filename_length,"%s/%d.%d.%d.%d",proxy_directory, + ((unsigned char*)(&conn->connaddr.sin_addr.s_addr))[0], + ((unsigned char*)(&conn->connaddr.sin_addr.s_addr))[1], + ((unsigned char*)(&conn->connaddr.sin_addr.s_addr))[2], + ((unsigned char*)(&conn->connaddr.sin_addr.s_addr))[3]); + host_file_descriptor=open(filename,O_RDONLY); + if(-1!=host_file_descriptor) { + read(host_file_descriptor,&hostname_length,sizeof(hostname_length)); + hostname=malloc(hostname_length); + read(host_file_descriptor,hostname,hostname_length); + close(host_file_descriptor); + } + /* Check the buffer has enough space for the request, */ + /* the user name and the hostname */ conn->datalen = sizeof(struct sockreq) + - (user == NULL ? 0 : strlen(user->pw_name)) + 1; + (user == NULL ? 0 : strlen(user->pw_name)) + + (hostname == NULL ? 0 : hostname_length) + 1; if (sizeof(conn->buffer) < conn->datalen) { show_msg(MSGERR, "The SOCKS username is too long"); conn->state = FAILED; @@ -903,11 +1009,15 @@ thisreq->version = 4; thisreq->command = 1; thisreq->dstport = conn->connaddr.sin_port; - thisreq->dstip = conn->connaddr.sin_addr.s_addr; + thisreq->dstip = hostname ? htonl(1) : conn->connaddr.sin_addr.s_addr; /* Copy the username */ - strcpy((char *) thisreq + sizeof(struct sockreq), - (user == NULL ? "" : user->pw_name)); + username=(user == NULL ? "" : user->pw_name); + strcpy((char *) thisreq + sizeof(struct sockreq), username); + + if(hostname) + strcpy((char *) thisreq + sizeof(struct sockreq) + + strlen(username) + 1, hostname); conn->datadone = 0; conn->state = SENDING; diff -Naurd tsocks-1.8/validateconf.c tsocks-1.8-socks4a/validateconf.c --- tsocks-1.8/validateconf.c 2002-02-07 11:49:59.000000000 +0100 +++ tsocks-1.8-socks4a/validateconf.c 2005-08-25 20:20:56.000000000 +0200 @@ -126,7 +126,7 @@ } void show_conf(struct parsedfile *config) { - struct netent *net; + struct tsocks_netent *net; struct serverent *server; /* Show the local networks */ @@ -168,7 +168,7 @@ void show_server(struct parsedfile *config, struct serverent *server, int def) { struct in_addr res; - struct netent *net; + struct tsocks_netent *net; /* Show address */ if (server->address != NULL)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor