fixed a couple of bugs, warnings, added basic gethostbyaddr support and a plain Makefile

This commit is contained in:
rofl0r 2011-09-04 01:45:16 +02:00
parent a6792b937d
commit 5095296ddf
6 changed files with 368 additions and 201 deletions

1
.gitignore vendored
View File

@ -8,5 +8,4 @@
# Autoconf stuff # Autoconf stuff
libtool libtool
config.* config.*
Makefile
stamp-h stamp-h

76
Makefile Normal file
View File

@ -0,0 +1,76 @@
#
# Makefile for proxychains (requires GNU make), stolen from musl
#
# Use config.mak to override any of the following variables.
# Do not make changes here.
#
exec_prefix = /usr/local
bindir = $(exec_prefix)/bin
prefix = /usr/local/
includedir = $(prefix)/include
libdir = $(prefix)/lib
syslibdir = /lib
SRCS = $(sort $(wildcard src/*.c))
OBJS = $(SRCS:.c=.o)
LOBJS = $(OBJS:.o=.lo)
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe
LDFLAGS = -shared -fPIC -ldl
INC =
PIC = -fPIC -O0
AR = $(CROSS_COMPILE)ar
RANLIB = $(CROSS_COMPILE)ranlib
SHARED_LIBS = lib/libproxychains.so
ALL_LIBS = $(SHARED_LIBS)
ALL_TOOLS = proxychains
LDSO_PATHNAME = libproxychains.so.3
-include config.mak
CFLAGS_MAIN=-DLIB_DIR=\"$(libdir)\"
all: $(ALL_LIBS) $(ALL_TOOLS)
#install: $(ALL_LIBS:lib/%=$(DESTDIR)$(libdir)/%) $(DESTDIR)$(LDSO_PATHNAME)
install:
install -D -m 644 proxychains $(bindir)
install -D -m 644 src/proxyresolv $(bindir)
install -D -m 644 lib/libproxychains.so $(libdir)
ln -sf $(libdir)/libproxychains.so $(libdir)/libproxychains.so.3
clean:
rm -f $(OBJS)
rm -f $(LOBJS)
rm -f $(ALL_LIBS) lib/*.[ao] lib/*.so
%.o: %.c
$(CC) $(CFLAGS) $(CFLAGS_MAIN) $(INC) -c -o $@ $<
%.lo: %.c
$(CC) $(CFLAGS) $(CFLAGS_MAIN) $(INC) $(PIC) -c -o $@ $<
lib/libproxychains.so: $(LOBJS)
$(CC) $(LDFLAGS) -Wl,-soname=libproxychains.so -o $@ $(LOBJS) -lgcc
lib/%.o:
cp $< $@
$(ALL_TOOLS): $(OBJS)
$(CC) src/main.o -o proxychains
$(DESTDIR)$(libdir)/%.so: lib/%.so
install -D -m 755 $< $@
$(DESTDIR)$(libdir)/%: lib/%
install -D -m 644 $< $@
$(DESTDIR)$(LDSO_PATHNAME): lib/libproxychains.so
ln -sf $(libdir)/libproxychains.so $@ || true
.PHONY: all clean install

View File

@ -126,57 +126,36 @@ int proxychains_write_log(char *str,...)
static int write_n_bytes(int fd,char *buff,size_t size) static int write_n_bytes(int fd,char *buff,size_t size)
{ {
int i=0,wrote=0; int i=0;
for(;;) size_t wrote=0;
{ for(;;) {
i=write(fd,&buff[wrote],size-wrote); i = write(fd,&buff[wrote],size-wrote);
if(i<=0) if(i<=0)
return i; return i;
wrote+=i; wrote += i;
if(wrote==size) if(wrote==size)
return wrote; return wrote;
} }
}
static int read_line(int fd, char *buff, size_t size)
{
int i,ready;
struct pollfd pfd[1];
pfd[0].fd=fd;
pfd[0].events=POLLIN;
for(i=0;i<size-1;i++)
{
pfd[0].revents=0;
ready=poll_retry(pfd,1,tcp_read_time_out);
if(ready!=1 || !(pfd[0].revents&POLLIN) || 1!=read(fd,&buff[i],1))
return -1;
else if(buff[i]=='\n')
{
buff[i+1]=0;
return (i+1);
}
}
return -1;
} }
static int read_n_bytes(int fd,char *buff, size_t size) static int read_n_bytes(int fd,char *buff, size_t size)
{ {
int i,ready; int ready;
struct pollfd pfd[1]; size_t i;
struct pollfd pfd[1];
pfd[0].fd=fd; pfd[0].fd=fd;
pfd[0].events=POLLIN; pfd[0].events=POLLIN;
for(i=0; i < size; i++) { for(i=0; i < size; i++) {
pfd[0].revents=0; pfd[0].revents = 0;
ready=poll_retry(pfd,1,tcp_read_time_out); ready = poll_retry(pfd, 1, tcp_read_time_out);
if(ready!=1 || !(pfd[0].revents&POLLIN) || 1!=read(fd,&buff[i],1)) if(ready != 1 || !(pfd[0].revents&POLLIN) || 1 != read(fd,&buff[i],1))
return -1; return -1;
} }
return size; return (int) size;
} }
static int timed_connect(int sock, const struct sockaddr *addr, unsigned int len) static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len)
{ {
int ret, value; int ret, value;
socklen_t value_len; socklen_t value_len;
@ -185,15 +164,24 @@ static int timed_connect(int sock, const struct sockaddr *addr, unsigned int len
pfd[0].fd=sock; pfd[0].fd=sock;
pfd[0].events=POLLOUT; pfd[0].events=POLLOUT;
fcntl(sock, F_SETFL, O_NONBLOCK); fcntl(sock, F_SETFL, O_NONBLOCK);
ret=true_connect(sock, addr, len); ret = true_connect(sock, addr, len);
// printf("\nconnect ret=%d\n",ret);fflush(stdout); #ifdef DEBUG
if(ret == -1) perror("true_connect");
printf("\nconnect ret=%d\n",ret);
fflush(stdout);
#endif
if(ret==-1 && errno==EINPROGRESS) { if(ret==-1 && errno==EINPROGRESS) {
ret=poll_retry(pfd,1,tcp_connect_time_out); ret=poll_retry(pfd,1,tcp_connect_time_out);
//printf("\npoll ret=%d\n",ret);fflush(stdout); #ifdef DEBUG
printf("\npoll ret=%d\n",ret);fflush(stdout);
#endif
if(ret == 1) { if(ret == 1) {
value_len=sizeof(socklen_t); value_len=sizeof(socklen_t);
getsockopt(sock,SOL_SOCKET,SO_ERROR,&value,&value_len) ; getsockopt(sock,SOL_SOCKET,SO_ERROR,&value,&value_len) ;
//printf("\nvalue=%d\n",value);fflush(stdout); #ifdef DEBUG
printf("\nvalue=%d\n",value);fflush(stdout);
#endif
if(!value) if(!value)
ret=0; ret=0;
else else
@ -212,6 +200,9 @@ static int timed_connect(int sock, const struct sockaddr *addr, unsigned int len
static int tunnel_to(int sock, unsigned int ip, unsigned short port, proxy_type pt,char *user,char *pass) static int tunnel_to(int sock, unsigned int ip, unsigned short port, proxy_type pt,char *user,char *pass)
{ {
#ifdef DEBUG
PDEBUG("tunnel to\n");
#endif
int len; int len;
char buff[BUFF_SIZE]; char buff[BUFF_SIZE];
memset (buff, 0, sizeof(buff)); memset (buff, 0, sizeof(buff));
@ -428,60 +419,60 @@ error:
} }
static proxy_data * select_proxy(select_type how, static proxy_data * select_proxy(select_type how,
proxy_data *pd, int proxy_count, int *offset) proxy_data *pd, unsigned int proxy_count, unsigned int *offset)
{ {
int i=0,k=0; unsigned int i=0, k=0;
if(*offset>=proxy_count) if(*offset >= proxy_count)
return NULL; return NULL;
switch(how) { switch(how) {
case RANDOMLY: case RANDOMLY:
srand(time(NULL)); srand(time(NULL));
do { do {
k++; k++;
i = 0 + (int) (proxy_count*1.0*rand()/ i = 0 + (unsigned int) (proxy_count * 1.0 * rand()/
(RAND_MAX+1.0)); (RAND_MAX + 1.0));
} while (pd[i].ps!=PLAY_STATE && k<proxy_count*100 ); } while (pd[i].ps != PLAY_STATE && k < proxy_count*100 );
break; break;
case FIFOLY: case FIFOLY:
for(i=*offset;i<proxy_count;i++) { for(i=*offset; i<proxy_count; i++) {
if(pd[i].ps==PLAY_STATE) { if(pd[i].ps == PLAY_STATE) {
*offset=i; *offset = i;
break; break;
} }
} }
default: default:
break; break;
} }
if (i>=proxy_count) if (i >= proxy_count)
i=0; i = 0;
return pd[i].ps==PLAY_STATE?&pd[i]:NULL; return (pd[i].ps == PLAY_STATE)? &pd[i] : NULL;
} }
static void release_all(proxy_data *pd, int proxy_count) static void release_all(proxy_data *pd, unsigned int proxy_count)
{ {
int i; unsigned int i;
for(i=0;i<proxy_count;i++) for(i=0; i<proxy_count; i++)
pd[i].ps=PLAY_STATE; pd[i].ps = PLAY_STATE;
return; return;
} }
static void release_busy(proxy_data *pd, int proxy_count) static void release_busy(proxy_data *pd, unsigned int proxy_count)
{ {
int i; unsigned int i;
for(i=0;i<proxy_count;i++) for(i=0; i<proxy_count; i++)
if(pd[i].ps==BUSY_STATE) if(pd[i].ps == BUSY_STATE)
pd[i].ps=PLAY_STATE; pd[i].ps = PLAY_STATE;
return; return;
} }
static int calc_alive(proxy_data *pd, int proxy_count) static unsigned int calc_alive(proxy_data *pd, unsigned int proxy_count)
{ {
int i; unsigned int i;
int alive_count=0; int alive_count=0;
release_busy(pd,proxy_count); release_busy(pd, proxy_count);
for(i=0;i<proxy_count;i++) for(i=0; i<proxy_count; i++)
if(pd[i].ps==PLAY_STATE) if(pd[i].ps == PLAY_STATE)
alive_count++; alive_count++;
return alive_count; return alive_count;
} }
@ -490,6 +481,9 @@ static int calc_alive(proxy_data *pd, int proxy_count)
static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto) static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto)
{ {
int retcode=-1; int retcode=-1;
#ifdef DEBUG
PDEBUG("chain_step()\n");
#endif
proxychains_write_log("<>-%s:%d-", proxychains_write_log("<>-%s:%d-",
inet_ntoa(*(struct in_addr*)&pto->ip), inet_ntoa(*(struct in_addr*)&pto->ip),
@ -517,14 +511,14 @@ static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto)
int connect_proxy_chain( int sock, unsigned int target_ip, int connect_proxy_chain( int sock, unsigned int target_ip,
unsigned short target_port, proxy_data *pd, unsigned short target_port, proxy_data *pd,
unsigned int proxy_count, chain_type ct, int max_chain ) unsigned int proxy_count, chain_type ct, unsigned int max_chain )
{ {
proxy_data p4; proxy_data p4;
proxy_data *p1,*p2,*p3; proxy_data *p1,*p2,*p3;
int ns=-1; int ns=-1;
int offset=0; unsigned int offset=0;
int alive_count=0; unsigned int alive_count=0;
int curr_len=0; unsigned int curr_len=0;
#define TP "<>" #define TP "<>"
#define DT "|D-chain|" #define DT "|D-chain|"
@ -532,8 +526,12 @@ int connect_proxy_chain( int sock, unsigned int target_ip,
#define RT "|R-chain|" #define RT "|R-chain|"
p3=&p4; p3=&p4;
#ifdef DEBUG
PDEBUG("connect_proxy_chain\n");
#endif
again: again:
switch(ct) { switch(ct) {
case DYNAMIC_TYPE: case DYNAMIC_TYPE:
alive_count=calc_alive(pd,proxy_count); alive_count=calc_alive(pd,proxy_count);
@ -541,13 +539,17 @@ again:
do { do {
if(!(p1=select_proxy(FIFOLY,pd,proxy_count,&offset))) if(!(p1=select_proxy(FIFOLY,pd,proxy_count,&offset)))
goto error_more; goto error_more;
} while(SUCCESS!=start_chain(&ns,p1,DT) && offset<proxy_count); } while(SUCCESS!=start_chain(&ns,p1,DT) && offset < proxy_count);
for(;;) { for(;;) {
p2=select_proxy(FIFOLY,pd,proxy_count,&offset); p2=select_proxy(FIFOLY,pd,proxy_count,&offset);
if(!p2) if(!p2)
break; break;
if(SUCCESS!=chain_step(ns,p1,p2)) if(SUCCESS!=chain_step(ns,p1,p2)) {
#ifdef DEBUG
PDEBUG("GOTO AGAIN 1\n");
#endif
goto again; goto again;
}
p1=p2; p1=p2;
} }
proxychains_write_log(TP); proxychains_write_log(TP);
@ -558,17 +560,29 @@ again:
break; break;
case STRICT_TYPE: case STRICT_TYPE:
alive_count=calc_alive(pd,proxy_count); alive_count=calc_alive(pd, proxy_count);
offset=0; offset=0;
if(!(p1=select_proxy(FIFOLY,pd,proxy_count,&offset))) if(!(p1=select_proxy(FIFOLY, pd, proxy_count, &offset))) {
#ifdef DEBUG
PDEBUG("select_proxy failed\n");
#endif
goto error_strict; goto error_strict;
if(SUCCESS!=start_chain(&ns,p1,ST)) }
if(SUCCESS!=start_chain(&ns, p1, ST)) {
#ifdef DEBUG
PDEBUG("start_chain failed\n");
#endif
goto error_strict; goto error_strict;
while(offset<proxy_count) { }
if(!(p2=select_proxy(FIFOLY,pd,proxy_count,&offset))) while(offset < proxy_count) {
if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
break; break;
if(SUCCESS!=chain_step(ns,p1,p2)) if(SUCCESS!=chain_step(ns, p1, p2)) {
#ifdef DEBUG
PDEBUG("chain_step failed\n");
#endif
goto error_strict; goto error_strict;
}
p1=p2; p1=p2;
} }
proxychains_write_log(TP); proxychains_write_log(TP);
@ -590,8 +604,12 @@ again:
while(++curr_len<max_chain) { while(++curr_len<max_chain) {
if(!(p2=select_proxy(RANDOMLY,pd,proxy_count,&offset))) if(!(p2=select_proxy(RANDOMLY,pd,proxy_count,&offset)))
goto error_more; goto error_more;
if(SUCCESS!=chain_step(ns,p1,p2)) if(SUCCESS!=chain_step(ns,p1,p2)) {
#ifdef DEBUG
PDEBUG("GOTO AGAIN 2\n");
#endif
goto again; goto again;
}
p1=p2; p1=p2;
} }
proxychains_write_log(TP); proxychains_write_log(TP);
@ -602,7 +620,6 @@ again:
} }
done:
proxychains_write_log("<><>-OK\n"); proxychains_write_log("<><>-OK\n");
dup2(ns,sock); dup2(ns,sock);
close(ns); close(ns);
@ -616,6 +633,9 @@ error:
error_more: error_more:
proxychains_write_log("\n!!!need more proxies!!!\n"); proxychains_write_log("\n!!!need more proxies!!!\n");
error_strict: error_strict:
#ifdef DEBUG
PDEBUG("error\n");
#endif
release_all(pd,proxy_count); release_all(pd,proxy_count);
if(ns!=-1) if(ns!=-1)
close(ns); close(ns);
@ -648,7 +668,7 @@ struct hostent* proxy_gethostbyname(const char *name)
// TODO: this works only once, so cache it ... // TODO: this works only once, so cache it ...
// later // later
while (hp=gethostent()) while ((hp=gethostent()))
if (!strcmp(hp->h_name,name)) if (!strcmp(hp->h_name,name))
return hp; return hp;
@ -679,7 +699,7 @@ struct hostent* proxy_gethostbyname(const char *name)
close(pipe_fd[0]); close(pipe_fd[0]);
got_buff: got_buff:
addr = inet_addr(buff); addr = inet_addr(buff);
if (addr == -1) if (addr == (in_addr_t) (-1))
goto err_dns; goto err_dns;
memcpy(*(hostent_space.h_addr_list), memcpy(*(hostent_space.h_addr_list),
&addr ,sizeof(struct in_addr)); &addr ,sizeof(struct in_addr));
@ -690,7 +710,8 @@ got_buff:
name, inet_ntoa(*(struct in_addr*)&addr)); name, inet_ntoa(*(struct in_addr*)&addr));
return &hostent_space; return &hostent_space;
err_dns: err_dns:
proxychains_write_log("|DNS-response|: %s is not exist\n", name); proxychains_write_log("|DNS-response|: %s does not exist\n", name);
perror("err_dns");
err: err:
return NULL; return NULL;
} }

View File

@ -41,18 +41,16 @@ typedef struct
unsigned short port; unsigned short port;
} localaddr_arg; } localaddr_arg;
typedef struct typedef struct {
{ unsigned int ip;
unsigned int ip; unsigned short port;
unsigned short port; proxy_type pt;
proxy_type pt; proxy_state ps;
proxy_state ps; char user[256];
char user[256]; char pass[256];
char pass[256];
} proxy_data; } proxy_data;
typedef struct typedef struct {
{
proxy_data *pd; proxy_data *pd;
chain_type ct; chain_type ct;
unsigned int proxy_count; unsigned int proxy_count;
@ -68,7 +66,7 @@ int connect_proxy_chain (
proxy_data * pd, proxy_data * pd,
unsigned int proxy_count, unsigned int proxy_count,
chain_type ct, chain_type ct,
int max_chain ); unsigned int max_chain );
int proxychains_write_log(char *str,...); int proxychains_write_log(char *str,...);
struct hostent* proxy_gethostbyname(const char *name); struct hostent* proxy_gethostbyname(const char *name);
@ -103,10 +101,10 @@ int proxy_getaddrinfo(const char *node, const char *service,
struct hostent* proxy_gethostbyname(const char *name); struct hostent* proxy_gethostbyname(const char *name);
#if 0 #ifdef DEBUG
#define PDEBUG(fmt, args...) fprintf(stderr,"DEBUG:"fmt, ## args) # define PDEBUG(fmt, args...) fprintf(stderr,"DEBUG:"fmt, ## args)
#else #else
#define PDEBUG(fmt, args...) # define PDEBUG(fmt, args...)
#endif #endif
#endif #endif

View File

@ -14,10 +14,10 @@
* (at your option) any later version. * * (at your option) any later version. *
* * * *
***************************************************************************/ ***************************************************************************/
#undef _GNU_SOURCE
#define _GNU_SOURCE #define _GNU_SOURCE
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
@ -46,9 +46,9 @@ int tcp_read_time_out;
int tcp_connect_time_out; int tcp_connect_time_out;
chain_type proxychains_ct; chain_type proxychains_ct;
proxy_data proxychains_pd[MAX_CHAIN]; proxy_data proxychains_pd[MAX_CHAIN];
int proxychains_proxy_count = 0; unsigned int proxychains_proxy_count = 0;
int proxychains_got_chain_data = 0; int proxychains_got_chain_data = 0;
int proxychains_max_chain = 1; unsigned int proxychains_max_chain = 1;
int proxychains_quiet_mode = 0; int proxychains_quiet_mode = 0;
int proxychains_resolver = 0; int proxychains_resolver = 0;
static int init_l = 0; static int init_l = 0;
@ -61,20 +61,28 @@ static void init_lib(void);
static void init_lib(void) static void init_lib(void)
{ {
// proxychains_write_log("ProxyChains-"VERSION proxychains_write_log("ProxyChains-3.1 (http://proxychains.sf.net)\n");
// " (http://proxychains.sf.net)\n");
get_chain_data(proxychains_pd,&proxychains_proxy_count,&proxychains_ct); get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
true_connect = (connect_t) dlsym(RTLD_NEXT, "connect"); true_connect = (connect_t) dlsym(RTLD_NEXT, "connect");
if (!true_connect) { if (!true_connect) {
fprintf(stderr, "Cannot load symbol 'connect' %s\n", dlerror()); fprintf(stderr, "Cannot load symbol 'connect' %s\n", dlerror());
exit(1); exit(1);
} else { } else {
// PDEBUG( "loaded symbol 'connect'" #ifdef DEBUG
// " real addr %p wrapped addr %p\n", PDEBUG( "loaded symbol 'connect'"
// true_connect, connect); " real addr %p wrapped addr %p\n",
true_connect, connect);
#endif
} }
if(connect==true_connect) {
#ifdef DEBUG
PDEBUG("circular reference detected, aborting!\n");
#endif
abort();
}
true_gethostbyname = (gethostbyname_t) true_gethostbyname = (gethostbyname_t)
dlsym(RTLD_NEXT, "gethostbyname"); dlsym(RTLD_NEXT, "gethostbyname");
@ -83,9 +91,11 @@ static void init_lib(void)
dlerror()); dlerror());
exit(1); exit(1);
} else { } else {
// PDEBUG( "loaded symbol 'gethostbyname'" #ifdef DEBUG
// " real addr %p wrapped addr %p\n", PDEBUG( "loaded symbol 'gethostbyname'"
// true_gethostbyname, gethostbyname); " real addr %p wrapped addr %p\n",
true_gethostbyname, gethostbyname);
#endif
} }
true_getaddrinfo = (getaddrinfo_t) true_getaddrinfo = (getaddrinfo_t)
dlsym(RTLD_NEXT, "getaddrinfo"); dlsym(RTLD_NEXT, "getaddrinfo");
@ -95,9 +105,11 @@ static void init_lib(void)
dlerror()); dlerror());
exit(1); exit(1);
} else { } else {
// PDEBUG( "loaded symbol 'getaddrinfo'" #ifdef DEBUG
// " real addr %p wrapped addr %p\n", PDEBUG( "loaded symbol 'getaddrinfo'"
// true_getaddrinfo, getaddrinfo); " real addr %p wrapped addr %p\n",
true_getaddrinfo, getaddrinfo);
#endif
} }
true_freeaddrinfo = (freeaddrinfo_t) true_freeaddrinfo = (freeaddrinfo_t)
dlsym(RTLD_NEXT, "freeaddrinfo"); dlsym(RTLD_NEXT, "freeaddrinfo");
@ -107,9 +119,11 @@ static void init_lib(void)
dlerror()); dlerror());
exit(1); exit(1);
} else { } else {
// PDEBUG( "loaded symbol 'freeaddrinfo'" #ifdef DEBUG
// " real addr %p wrapped addr %p\n", PDEBUG( "loaded symbol 'freeaddrinfo'"
// true_freeaddrinfo, freeaddrinfo); " real addr %p wrapped addr %p\n",
true_freeaddrinfo, freeaddrinfo);
#endif
} }
true_gethostbyaddr = (gethostbyaddr_t) true_gethostbyaddr = (gethostbyaddr_t)
dlsym(RTLD_NEXT, "gethostbyaddr"); dlsym(RTLD_NEXT, "gethostbyaddr");
@ -119,9 +133,11 @@ static void init_lib(void)
dlerror()); dlerror());
exit(1); exit(1);
} else { } else {
// PDEBUG( "loaded symbol 'gethostbyaddr'" #ifdef DEBUG
// " real addr %p wrapped addr %p\n", PDEBUG( "loaded symbol 'gethostbyaddr'"
// true_gethostbyaddr, gethostbyaddr); " real addr %p wrapped addr %p\n",
true_gethostbyaddr, gethostbyaddr);
#endif
} }
true_getnameinfo = (getnameinfo_t) true_getnameinfo = (getnameinfo_t)
dlsym(RTLD_NEXT, "getnameinfo"); dlsym(RTLD_NEXT, "getnameinfo");
@ -131,9 +147,11 @@ static void init_lib(void)
dlerror()); dlerror());
exit(1); exit(1);
} else { } else {
// PDEBUG( "loaded symbol 'getnameinfo'" #ifdef DEBUG
// " real addr %p wrapped addr %p\n", PDEBUG( "loaded symbol 'getnameinfo'"
// true_getnameinfo, getnameinfo); " real addr %p wrapped addr %p\n",
true_getnameinfo, getnameinfo);
#endif
} }
init_l = 1; init_l = 1;
} }
@ -160,9 +178,9 @@ static inline void get_chain_data(
return; return;
//Some defaults //Some defaults
tcp_read_time_out=4*1000; tcp_read_time_out = 4*1000;
tcp_connect_time_out=10*1000; tcp_connect_time_out = 10*1000;
*ct=DYNAMIC_TYPE; *ct = DYNAMIC_TYPE;
env = NULL; env = NULL;
@ -184,7 +202,7 @@ static inline void get_chain_data(
} }
while(fgets(buff,sizeof(buff),file)) { while(fgets(buff,sizeof(buff),file)) {
if(buff[strspn(buff," ")]!='#') { if(buff[0] != '\n' && buff[strspn(buff," ")]!='#') {
if(list) { if(list) {
memset(&pd[count], 0, sizeof(proxy_data)); memset(&pd[count], 0, sizeof(proxy_data));
pd[count].ps=PLAY_STATE; pd[count].ps=PLAY_STATE;
@ -201,7 +219,7 @@ static inline void get_chain_data(
pd[count].pt=SOCKS5_TYPE; pd[count].pt=SOCKS5_TYPE;
}else continue; }else continue;
if( pd[count].ip && pd[count].ip!=-1 && port_n) if( pd[count].ip && (int) pd[count].ip != -1 && port_n)
if(++count==MAX_CHAIN) if(++count==MAX_CHAIN)
break; break;
} else { } else {
@ -278,16 +296,19 @@ static inline void get_chain_data(
} }
} }
fclose(file); fclose(file);
*proxy_count=count; *proxy_count = count;
proxychains_got_chain_data=1; proxychains_got_chain_data = 1;
} }
int connect (int sock, const struct sockaddr *addr, unsigned int len) int connect (int sock, const struct sockaddr *addr, unsigned int len)
{ {
int socktype=0,optlen=0,flags=0,ret=0; int socktype=0, flags=0, ret=0;
socklen_t optlen = 0;
#ifdef DEBUG
char str[256]; char str[256];
#endif
struct in_addr *p_addr_in; struct in_addr *p_addr_in;
unsigned short port; unsigned short port;
size_t i; size_t i;
@ -302,10 +323,12 @@ int connect (int sock, const struct sockaddr *addr, unsigned int len)
p_addr_in = &((struct sockaddr_in *)addr)->sin_addr; p_addr_in = &((struct sockaddr_in *)addr)->sin_addr;
port = ntohs(((struct sockaddr_in *)addr)->sin_port); port = ntohs(((struct sockaddr_in *)addr)->sin_port);
//PDEBUG("localnet: %s; ", inet_ntop(AF_INET,&in_addr_localnet, str, sizeof(str))); #ifdef DEBUG
//PDEBUG("netmask: %s; " , inet_ntop(AF_INET, &in_addr_netmask, str, sizeof(str))); // PDEBUG("localnet: %s; ", inet_ntop(AF_INET,&in_addr_localnet, str, sizeof(str)));
//PDEBUG("target: %s\n", inet_ntop(AF_INET, p_addr_in, str, sizeof(str))); // PDEBUG("netmask: %s; " , inet_ntop(AF_INET, &in_addr_netmask, str, sizeof(str)));
//PDEBUG("port: %d\n", port); PDEBUG("target: %s\n", inet_ntop(AF_INET, p_addr_in, str, sizeof(str)));
PDEBUG("port: %d\n", port);
#endif
for (i = 0; i < num_localnet_addr; i++) { for (i = 0; i < num_localnet_addr; i++) {
if ((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr) if ((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr)
== (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr)) == (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr))
@ -327,7 +350,7 @@ int connect (int sock, const struct sockaddr *addr, unsigned int len)
proxychains_pd, proxychains_pd,
proxychains_proxy_count, proxychains_proxy_count,
proxychains_ct, proxychains_ct,
proxychains_max_chain ); proxychains_max_chain );
fcntl(sock, F_SETFL, flags); fcntl(sock, F_SETFL, flags);
if(ret!=SUCCESS) if(ret!=SUCCESS)
errno=ECONNREFUSED; errno=ECONNREFUSED;
@ -346,6 +369,7 @@ struct hostent *gethostbyname(const char *name)
return NULL; return NULL;
} }
int getaddrinfo(const char *node, const char *service, int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, const struct addrinfo *hints,
struct addrinfo **res) struct addrinfo **res)
@ -361,6 +385,7 @@ int getaddrinfo(const char *node, const char *service,
return ret; return ret;
} }
void freeaddrinfo(struct addrinfo *res) void freeaddrinfo(struct addrinfo *res)
{ {
PDEBUG("freeaddrinfo %p \n",res); PDEBUG("freeaddrinfo %p \n",res);
@ -375,12 +400,20 @@ void freeaddrinfo(struct addrinfo *res)
return; return;
} }
#ifdef __GLIBC__
int getnameinfo (const struct sockaddr * sa,
socklen_t salen, char * host,
socklen_t hostlen, char * serv,
socklen_t servlen, unsigned int flags)
#else
int getnameinfo (const struct sockaddr * sa, int getnameinfo (const struct sockaddr * sa,
socklen_t salen, char * host, socklen_t salen, char * host,
socklen_t hostlen, char * serv, socklen_t hostlen, char * serv,
socklen_t servlen, int flags) socklen_t servlen, int flags)
#endif
{ {
int ret = 0; int ret = 0;
PDEBUG("getnameinfo: %s %s\n", host, serv);
if(!init_l) if(!init_l)
init_lib(); init_lib();
if(!proxychains_resolver) { if(!proxychains_resolver) {
@ -392,17 +425,55 @@ int getnameinfo (const struct sockaddr * sa,
if(servlen) if(servlen)
snprintf(serv, servlen,"%d",ntohs(SOCKPORT(*sa))); snprintf(serv, servlen,"%d",ntohs(SOCKPORT(*sa)));
} }
PDEBUG("getnameinfo: %s %s\n", host, serv);
return ret; return ret;
} }
// stolen from libulz (C) rofl0r
static void pc_stringfromipv4(unsigned char* ip_buf_4_bytes, char* outbuf_16_bytes) {
unsigned char* p;
char *o = outbuf_16_bytes;
unsigned char n;
for(p = ip_buf_4_bytes; p < ip_buf_4_bytes + 4; p++) {
n = *p;
if(*p >= 100) {
if(*p >= 200) *(o++) = '2';
else *(o++) = '1';
n %= 100;
}
if(*p >= 10) {
*(o++) = (n / 10) + '0';
n %= 10;
}
*(o++) = n + '0';
*(o++) = '.';
}
o[-1] = 0;
}
struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type) struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type)
{ {
PDEBUG("TODO: gethostbyaddr hook\n"); static char buf[16];
static char ipv4[4];
static char* list[2];
static struct hostent he;
PDEBUG("TODO: proper gethostbyaddr hook\n");
if(!init_l) if(!init_l)
init_lib(); init_lib();
if(!proxychains_resolver) if(!proxychains_resolver)
return true_gethostbyaddr(addr,len,type); return true_gethostbyaddr(addr,len,type);
else {
if(len != 4) return NULL;
he.h_name = buf;
memcpy(ipv4, addr, 4);
list[0] = ipv4;
list[1] = NULL;
he.h_addr_list = list;
he.h_addrtype = AF_INET;
he.h_aliases = NULL;
he.h_length = 4;
pc_stringfromipv4((unsigned char*)addr, buf);
return &he;
}
return NULL; return NULL;
} }

View File

@ -1,9 +1,9 @@
/*************************************************************************** /***************************************************************************
main.c - description main.c - description
q -------------------
begin : Tue May 14 2002 begin : Tue May 14 2002
copyright : netcreature (C) 2002 copyright : netcreature (C) 2002
email : netcreature@users.sourceforge.net email : netcreature@users.sourceforge.net
***************************************************************************/ ***************************************************************************/
/* GPL */ /* GPL */
/*************************************************************************** /***************************************************************************
@ -15,71 +15,73 @@
* * * *
***************************************************************************/ ***************************************************************************/
/*
* well ... actually this file could be a shell script ... but C rulez :).
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <memory.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
extern char *optarg; extern char *optarg;
extern int optind, opterr, optopt extern int optind, opterr, optopt;
/* #define PROXYCHAINS_CONF_FILE "proxychains.conf"
* XXX. Same thing is defined in proxychains main.c it
* needs to be changed, too.
*/
#define PROXYCHAINS_CONF_FILE "PROXYCHAINS_CONF_FILE"
static usage(void) static void usage(char** argv) {
{ printf("\nUsage: %s [h] [f] config_file program_name [arguments]\n"
"\t for example : proxychains telnet somehost.com\n"
printf("\nUsage: %s [h] [f] config_file program_name [arguments]\n" "More help in README file\n", argv[0]);
"\t for example : proxychains telnet somehost.com\n"
"More help in README file\n", argv[0], );
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[]) {
{ char *path = NULL;
char *path; char buf[256];
char pbuf[256];
int opt;
path = NULL; while ((opt = getopt(argc, argv, "fh:")) != -1) {
switch (opt) {
case 'h':
usage(argv);
break;
case 'f':
path = (char *)optarg;
break;
default: /* '?' */
usage(argv);
exit(EXIT_FAILURE);
}
}
while ((opt = getopt(argc, argv, "fh:")) != -1) { if(!path) {
switch (opt) { if(!(path = getenv("PROXYCHAINS_CONF_FILE")))
case 'h': path = getcwd(buf, sizeof(buf));
usage(); else if(access(path, R_OK) != -1) goto have;
break; if(!path ||
case 'f': !snprintf(pbuf, sizeof(pbuf), "%s/%s", path, PROXYCHAINS_CONF_FILE) ||
path = (char *)optarg; access(pbuf, R_OK) == -1
break; )
default: /* '?' */ path = "/etc/proxychains.conf";
usage(); else
exit(EXIT_FAILURE); path = pbuf;
} }
} if(access(path, R_OK) == -1) {
perror("couldnt find configuration file");
return 1;
}
have:
printf("Proxychains are going to use %s as config file.\n", path); printf("Proxychains is going to use %s as config file.\n", path);
printf("argv = %s\n", argv[1]); printf("argv = %s\n", argv[1]);
/* Set PROXYCHAINS_CONF_FILE to get proxychains lib to /* Set PROXYCHAINS_CONF_FILE to get proxychains lib to use new config file. */
use new config file. */ setenv("PROXYCHAINS_CONF_FILE", path, 1);
setenv(PROXYCHAINS_CONF_FILE, path, 1);
snprintf(buf, sizeof(buf), "LD_PRELOAD=%s/libproxychains.so", LIB_DIR);
putenv(buf);
execvp(argv[1], &argv[1]);
perror("proxychains can't load process....");
/*XXX. proxychains might be installed in some different location */ return EXIT_SUCCESS;
putenv("LD_PRELOAD=/usr/lib/libproxychains.so");
execvp(argv[1],&argv[1]);
perror("proxychains can't load process....");
return EXIT_SUCCESS;
} }