1
0
mirror of https://github.com/rofl0r/proxychains-ng synced 2026-05-13 17:03:07 +08:00

Compare commits

...

151 Commits

64 changed files with 2916 additions and 43687 deletions
+15
View File
@@ -0,0 +1,15 @@
*.o
*.so
*.la
*.lo
.deps/
.libs/
*.rcb
*.out
*~
*.patch
# Autoconf stuff
libtool
config.*
stamp-h
+20 -2
View File
@@ -1,5 +1,23 @@
original code up to version 3.1
N3E7CR34TUR3.
http://proxychains.sourceforge.net
netcreature@users.sourceforge.net
web site: proxychains.sourceforge.net
email: netcreature@users.sourceforge.net
main.c, remote-dns, thread safety, bugfixes, build system,
cleanups, mac support
rofl0r.
https://github.com/rofl0r/proxychains
localnet, bugfixes
jianing yang.
https://github.com/jianingy/proxychains
https://sourceforge.net/projects/proxychains/forums/forum/644747/topic/3498696
poll_retry (fixes for signal handling)
colin cross.
https://sourceforge.net/projects/proxychains/forums/forum/644747/topic/2367923
collecting patches from px forum and putting it into a repo
adam hamsik.
https://github.com/haad/proxychains
-13
View File
@@ -1,13 +0,0 @@
ProxyChains ver 3.1 Installation
=======================
If you have installed other ver of proxychains "make uninstall" before installing this distribution
unpack the .tar.gz , 'cd' to distribution directory and
run following commands (as root)
-------------------------------------
./configure
make
make install
-------------------------------------
that's all
+75
View File
@@ -0,0 +1,75 @@
#
# 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
sysconfdir=$(prefix)/etc
SRCS = $(sort $(wildcard src/*.c))
OBJS = $(SRCS:.c=.o)
LOBJS = src/nameinfo.o \
src/core.o src/common.o src/libproxychains.o src/shm.o \
src/allocator_thread.o src/ip_type.o src/stringdump.o \
src/hostentdb.o src/hash.o
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe
NO_AS_NEEDED = -Wl,--no-as-needed
LIBDL = -ldl
LDFLAGS = -shared -fPIC $(NO_AS_NEEDED) $(LIBDL) -lpthread
INC =
PIC = -fPIC
AR = $(CROSS_COMPILE)ar
RANLIB = $(CROSS_COMPILE)ranlib
LDSO_SUFFIX = so
LD_SET_SONAME = -Wl,-soname=
INSTALL_FLAGS = -D -m
LDSO_PATHNAME = libproxychains4.$(LDSO_SUFFIX)
SHARED_LIBS = $(LDSO_PATHNAME)
ALL_LIBS = $(SHARED_LIBS)
PXCHAINS = proxychains4
ALL_TOOLS = $(PXCHAINS)
-include config.mak
CFLAGS+=$(USER_CFLAGS) $(MAC_CFLAGS)
CFLAGS_MAIN=-DLIB_DIR=\"$(libdir)\" -DSYSCONFDIR=\"$(sysconfdir)\" -DDLL_NAME=\"$(LDSO_PATHNAME)\"
all: $(ALL_LIBS) $(ALL_TOOLS)
install-config:
install -d $(DESTDIR)$(sysconfdir)
install $(INSTALL_FLAGS) 644 src/proxychains.conf $(DESTDIR)$(sysconfdir)/
install:
install -d $(DESTDIR)$(bindir)/ $(DESTDIR)$(libdir)/
install $(INSTALL_FLAGS) 755 $(ALL_TOOLS) $(DESTDIR)$(bindir)/
install $(INSTALL_FLAGS) 644 $(ALL_LIBS) $(DESTDIR)$(libdir)/
clean:
rm -f $(ALL_LIBS)
rm -f $(ALL_TOOLS)
rm -f $(OBJS)
%.o: %.c
$(CC) $(CFLAGS) $(CFLAGS_MAIN) $(INC) $(PIC) -c -o $@ $<
$(LDSO_PATHNAME): $(LOBJS)
$(CC) $(LDFLAGS) $(LD_SET_SONAME)$(LDSO_PATHNAME) -o $@ $(LOBJS)
$(ALL_TOOLS): $(OBJS)
$(CC) src/main.o src/common.o -o $(PXCHAINS)
.PHONY: all clean install install-config
-8
View File
@@ -1,8 +0,0 @@
SUBDIRS = proxychains
EXTRA_DIST = AUTHORS COPYING ChangeLog INSTALL README TODO proxychains.lsm
AUTOMAKE_OPTIONS = foreign 1.4
-385
View File
@@ -1,385 +0,0 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
AR = @AR@
AS = @AS@
CC = @CC@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
GCJ = @GCJ@
GCJFLAGS = @GCJFLAGS@
HAVE_LIB = @HAVE_LIB@
LIB = @LIB@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIB = @LTLIB@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
RC = @RC@
STRIP = @STRIP@
VERSION = @VERSION@
SUBDIRS = proxychains
EXTRA_DIST = AUTHORS COPYING ChangeLog INSTALL README TODO proxychains.lsm
AUTOMAKE_OPTIONS = foreign 1.4
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
DIST_COMMON = README ./stamp-h.in AUTHORS COPYING ChangeLog INSTALL \
Makefile.am Makefile.in TODO aclocal.m4 config.guess config.h.in \
config.sub configure configure.in install-sh ltconfig ltmain.sh missing \
mkinstalldirs
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
$(ACLOCAL_M4): configure.in
cd $(srcdir) && $(ACLOCAL)
config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
config.h: stamp-h
@if test ! -f $@; then \
rm -f stamp-h; \
$(MAKE) stamp-h; \
else :; fi
stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES= CONFIG_HEADERS=config.h \
$(SHELL) ./config.status
@echo timestamp > stamp-h 2> /dev/null
$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
@if test ! -f $@; then \
rm -f $(srcdir)/stamp-h.in; \
$(MAKE) $(srcdir)/stamp-h.in; \
else :; fi
$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOHEADER)
@echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
mostlyclean-hdr:
clean-hdr:
distclean-hdr:
-rm -f config.h
maintainer-clean-hdr:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
test "$$subdir" != "." || dot_seen=yes; \
done; \
test "$$dot_seen" = "no" && rev=". $$rev"; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
-rm -rf $(distdir)
GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
mkdir $(distdir)/=build
mkdir $(distdir)/=inst
dc_install_base=`cd $(distdir)/=inst && pwd`; \
cd $(distdir)/=build \
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) dist
-rm -rf $(distdir)
@banner="$(distdir).tar.gz is ready for distribution"; \
dashes=`echo "$$banner" | sed s/./=/g`; \
echo "$$dashes"; \
echo "$$banner"; \
echo "$$dashes"
dist: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
dist-all: distdir
-chmod -R a+r $(distdir)
GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
-rm -rf $(distdir)
distdir: $(DISTFILES)
-rm -rf $(distdir)
mkdir $(distdir)
-chmod 777 $(distdir)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
for subdir in $(SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
fi; \
done
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
all-recursive-am: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
install-exec-am:
install-exec: install-exec-recursive
install-data-am:
install-data: install-data-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-recursive
uninstall-am:
uninstall: uninstall-recursive
all-am: Makefile config.h
all-redirect: all-recursive-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs: installdirs-recursive
installdirs-am:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic
mostlyclean: mostlyclean-recursive
clean-am: clean-hdr clean-tags clean-generic mostlyclean-am
clean: clean-recursive
distclean-am: distclean-hdr distclean-tags distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
-rm -f config.status
maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \
maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-recursive
-rm -f config.status
.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
install-data-recursive uninstall-data-recursive install-exec-recursive \
uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
all-recursive check-recursive installcheck-recursive info-recursive \
dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \
install-exec-am install-exec install-data-am install-data install-am \
install uninstall-am uninstall all-redirect all-am all installdirs-am \
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
+118 -26
View File
@@ -1,18 +1,96 @@
ProxyChains ver 3.1 README
======================
ProxyChains-NG ver 4.5 README
=============================
This is Unix version only.
ProxyChains is a UNIX program, that hooks network-related libc functions
in DYNAMICALLY LINKED programs via a preloaded DLL (dlsym(), LD_PRELOAD)
and redirects the connections through SOCKS4a/5 or HTTP proxies.
It supports TCP only (no UDP/ICMP etc).
How to mess with sources - How to Install : read INSTALL !!!!!!
The way it works is basically a HACK; so it is possible that it doesn't
work with your program, especially when it's a script, or starts
numerous processes like background daemons or uses dlopen() to load
"modules" (bug in glibc dynlinker).
It should work with simple compiled (C/C++) dynamically linked programs
though.
This program forces any tcp connection made by any given tcp client
to follow through proxy (or proxy chain). It is a kind of proxifier.
It acts like sockscap / permeo / eborder driver ( intercepts TCP calls )
It is FREE.
If your program doesn't work with proxychains, consider using an
iptables based solution instead; this is much more robust.
This version (3.x) introduces support for DNS resolving through proxy
it supports SOCKS4, SOCKS5 and HTTP CONNECT proxy servers.
Auth-types: socks - "user/pass" , http - "basic".
Supported Platforms: Linux, BSD, Mac.
*********** ATTENTION ***********
this program can be used to circumvent censorship.
doing so can be VERY DANGEROUS in certain countries.
ALWAYS MAKE SURE THAT PROXYCHAINS WORKS AS EXPECTED
BEFORE USING IT FOR ANYTHING SERIOUS.
this involves both the program and the proxy that you're going to
use.
for example, you can connect to some "what is my ip" service
like ifconfig.me to make sure that it's not using your real ip.
ONLY USE PROXYCHAINS IF YOU KNOW WHAT YOU'RE DOING.
THE AUTHORS AND MAINTAINERS OF PROXYCHAINS DO NOT TAKE ANY
RESPONSIBILITY FOR ANY ABUSE OR MISUSE OF THIS SOFTWARE AND
THE RESULTING CONSEQUENCES.
*** Installation ***
# needs a working C compiler, preferably gcc
./configure --prefix=/usr --sysconfdir=/etc
make
[optional] sudo make install
[optional] sudo make install-config (installs proxychains.conf)
if you dont install, you can use proxychains from the build directory
like this: ./proxychains4 -f src/proxychains.conf telnet google.com 80
Changelog:
----------
Version 4.5:
- hook close() to prevent OpenSSH from messing with internal infrastructure.
this caused ssh client to segfault when proxified.
Version 4.4:
- FreeBSD port
- fixes some installation issues on Debian and Mac.
Version 4.3:
- fixes programs that do dns-lookups in child processes (fork()ed),
like irssi. to achieve this, support for compilation without pthreads
was sacrified.
- fixes thread safety for gethostent() calls.
- improved DNS handling speed, since hostent db is cached.
Version 4.2:
- fixes compilation issues with ubuntu 12.04 toolchain
- fixes segfault in rare codepath
Version 4.1
- support for mac os x (all archs)
- all internal functions are threadsafe when compiled with -DTHREAD_SAFE
(default).
Version 4.0
- replaced dnsresolver script (which required a dynamically linked "dig"
binary to be present) with remote DNS lookup.
this speeds up any operation involving DNS, as the old script had to use TCP.
additionally it allows to use .onion urls when used with TOR.
- removed broken autoconf build system with a simple Makefile.
there's a ./configure script though for convenience.
it also adds support for a config file passed via command line switches/
environment variables.
Version 3.0
- support for DNS resolving through proxy
supports SOCKS4, SOCKS5 and HTTP CONNECT proxy servers.
Auth-types: socks - "user/pass" , http - "basic".
When to use it ?
1) When the only way to get "outside" from your LAN is through proxy server.
@@ -21,7 +99,8 @@ When to use it ?
like: your_host <--> proxy1 <--> proxy2 <--> target_host
4) To "proxify" some program with no proxy support built-in (like telnet)
5) Access intranet from outside via proxy.
5) To use DNS behind proxy.
6) To use DNS behind proxy.
7) To access hidden tor onion services.
Some cool features:
@@ -31,34 +110,47 @@ Some cool features:
random order from the list ( user defined length of chain ).
exact order (as they appear in the list )
dynamic order (smart exclude dead proxies from chain)
* You can use it with any TCP client application, even network scanners
yes, yes - you can make portscan via proxy (or chained proxies)
for example with Nmap scanner by fyodor (www.insecire.org/nmap).
proxychains nmap -sT -PO -p 80 -iR (find some webservers through proxy)
* You can use it with most TCP client applications, possibly even network
scanners, as long as they use standard libc functionality.
pcap based scanning does not work.
* You can use it with servers, like squid, sendmail, or whatever.
* DNS resolving through proxy.
Configuration:
proxychains looks for config file in following order:
1) ./proxychains.conf
2) $(HOME)/.proxychains/proxychains.conf
3) /etc/proxychains.conf **
**see more in /etc/proxychains.conf
Configuration:
--------------
proxychains looks for config file in following order:
1) file listed in environment variable PROXYCHAINS_CONF_FILE or
provided as a -f argument to proxychains script or binary.
2) ./proxychains.conf
3) $(HOME)/.proxychains/proxychains.conf
4) $(sysconfdir)/proxychains.conf **
** usually /etc/proxychains.conf
Usage Example:
bash$ proxychains telnet targethost.com
$ proxychains telnet targethost.com
in this example it will run telnet through proxy(or chained proxies)
specified by proxychains.conf
Usage Example:
bash$ proxyresolv targethost.com
$ proxychains -f /etc/proxychains-other.conf targethost2.com
in this example it will use different configuration file then proxychains.conf
to connect to targethost2.com host.
Usage Example:
$ proxyresolv targethost.com
in this example it will resolve targethost.com through proxy(or chained proxies)
specified by proxychains.conf
NOTE:
to run suid/sgid programs(like ssh) through proxychains you have to be root
Community:
----------
#proxychains on irc.freenode.net
+3 -3
View File
@@ -1,7 +1,7 @@
ProxyChains ver 3.1 TODO
ProxyChains ver 4.0 TODO
===================
stable DNS resolver ....
hooks for reentrant dns functions, i.e. gethostbyaddr_r
Vendored
-7433
View File
File diff suppressed because it is too large Load Diff
-1495
View File
File diff suppressed because it is too large Load Diff
-55
View File
@@ -1,55 +0,0 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Version number of package */
#undef VERSION
Vendored
-1627
View File
File diff suppressed because it is too large Load Diff
Vendored
+68 -19636
View File
File diff suppressed because it is too large Load Diff
-32
View File
@@ -1,32 +0,0 @@
dnl without this order in this file, autoconf will not work!
dnl the argument is a source file out of your sources. But
dnl acinclude.m4 makes the job for all programs ;-)
AC_INIT(proxychains,3.1)
dnl enable the following if you want to use autoconf/automake
dnl framework from a certain directory (like kde-common)
dnl AC_CONFIG_AUX_DIR(admin)
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE
AC_PREFIX_DEFAULT(/)
dnl without this order in this file, automake will be confused!
dnl
AM_CONFIG_HEADER(config.h)
AC_PROG_CC
AC_PROG_LIBTOOL
dnl create only shared libtool-libraries
AC_ENABLE_SHARED(yes)
dnl set the following to yes, if you want to create static
dnl libtool-libraries
AC_ENABLE_STATIC(no)
dnl add here all your Makefiles. These will be created by configure
AC_OUTPUT(Makefile proxychains/Makefile proxychains/docs/Makefile proxychains/docs/en/Makefile )
+11
View File
@@ -0,0 +1,11 @@
### config.mak template for proxychains
#######################################
# just copy into proxychains root dir and adapt to your needs.
prefix = /usr/local/
libdir = $(prefix)/lib
exec_prefix = /usr/local
bindir = $(exec_prefix)/bin
-250
View File
@@ -1,250 +0,0 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0
-3108
View File
File diff suppressed because it is too large Load Diff
-6971
View File
File diff suppressed because it is too large Load Diff
-238
View File
@@ -1,238 +0,0 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997, 1999 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing 0.2 - GNU automake"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`configure.in'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`configure.in'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`configure.in'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
tar)
shift
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
fi
# we have already tried tar in the generic part
gnutar ${1+"$@"} && exit 0
gtar ${1+"$@"} && exit 0
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" ${1+"$@"} && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" ${1+"$@"} && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequirements for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
-40
View File
@@ -1,40 +0,0 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
# $Id: mkinstalldirs,v 1.2 2004/03/22 00:29:19 netcreature Exp $
errstatus=0
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here
-14
View File
@@ -1,14 +0,0 @@
Begin3
Title: ProxyChains
Version: 3.0
Entered-date:
Description:
Keywords:
Author: <N37CR347UR3>
Maintained-by: <NetCreature>
Primary-site:
Home-page: http://proxychains.sourceforge.net
Original-site:
Platforms: Linux and other Unices
Copying-policy: GNU Public License
End
-38
View File
@@ -1,38 +0,0 @@
SUBDIRS = docs
EXTRA_DIST = proxychains.conf core.c core.h libproxychains.c
sysconf_DATA=$(srcdir)/proxychains.conf
install-data-local:
$(mkinstalldirs) ${DESTDIR}${bindir}
${INSTALL} $(srcdir)/proxychains ${DESTDIR}${bindir}/proxychains
${INSTALL} $(srcdir)/proxyresolv ${DESTDIR}${bindir}/proxyresolv
uninstall-local:
-rm -f ${DESTDIR}${bindir}/proxychains
-rm -f ${DESTDIR}${bindir}/proxyresolv
#bin_PROGRAMS = proxychains
#proxychains_SOURCES = main.c
# set the include path found by configure
INCLUDES= $(all_includes)
#proxychains_LDFLAGS = $(all_libraries)
lib_LTLIBRARIES = libproxychains.la
libproxychains_la_LDFLAGS = -version-info 3:0:0 $(all_libraries)
libproxychains_la_LIBADD= -ldl
noinst_HEADERS = core.h
libproxychains_la_SOURCES= libproxychains.c core.c
libproxychains_la_METASOURCES = USE_AUTOMOC
#install-private: install
# $(mkinstalldirs) $(HOME)/bin
# $(INSTALL_DATA) $(srcdir)/proxychains $(HOME)/bin/proxychains
#
#uninstall-private: uninstall
# -rm -f $(HOME)/bin/proxychains
-496
View File
@@ -1,496 +0,0 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
AR = @AR@
AS = @AS@
CC = @CC@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
GCJ = @GCJ@
GCJFLAGS = @GCJFLAGS@
HAVE_LIB = @HAVE_LIB@
LIB = @LIB@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIB = @LTLIB@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
RC = @RC@
STRIP = @STRIP@
VERSION = @VERSION@
SUBDIRS = docs
EXTRA_DIST = proxychains.conf core.c core.h libproxychains.c
sysconf_DATA = $(srcdir)/proxychains.conf
#bin_PROGRAMS = proxychains
#proxychains_SOURCES = main.c
# set the include path found by configure
INCLUDES = $(all_includes)
#proxychains_LDFLAGS = $(all_libraries)
lib_LTLIBRARIES = libproxychains.la
libproxychains_la_LDFLAGS = -version-info 3:0:0 $(all_libraries)
libproxychains_la_LIBADD = -ldl
noinst_HEADERS = core.h
libproxychains_la_SOURCES = libproxychains.c core.c
libproxychains_la_METASOURCES = USE_AUTOMOC
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(lib_LTLIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir) -I..
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
libproxychains_la_DEPENDENCIES =
libproxychains_la_OBJECTS = libproxychains.lo core.lo
CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DATA = $(sysconf_DATA)
HEADERS = $(noinst_HEADERS)
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
DEP_FILES = .deps/core.P .deps/libproxychains.P
SOURCES = $(libproxychains_la_SOURCES)
OBJECTS = $(libproxychains_la_OBJECTS)
all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .obj .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu proxychains/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
mostlyclean-libLTLIBRARIES:
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
distclean-libLTLIBRARIES:
maintainer-clean-libLTLIBRARIES:
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(libdir)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
list='$(lib_LTLIBRARIES)'; for p in $$list; do \
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
done
# FIXME: We should only use cygpath when building on Windows,
# and only if it is available.
.c.obj:
$(COMPILE) -c `cygpath -w $<`
.s.o:
$(COMPILE) -c $<
.S.o:
$(COMPILE) -c $<
mostlyclean-compile:
-rm -f *.o core *.core
-rm -f *.$(OBJEXT)
clean-compile:
distclean-compile:
-rm -f *.tab.c
maintainer-clean-compile:
.s.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
.S.lo:
$(LIBTOOL) --mode=compile $(COMPILE) -c $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
maintainer-clean-libtool:
libproxychains.la: $(libproxychains_la_OBJECTS) $(libproxychains_la_DEPENDENCIES)
$(LINK) -rpath $(libdir) $(libproxychains_la_LDFLAGS) $(libproxychains_la_OBJECTS) $(libproxychains_la_LIBADD) $(LIBS)
install-sysconfDATA: $(sysconf_DATA)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(sysconfdir)
@list='$(sysconf_DATA)'; for p in $$list; do \
if test -f $(srcdir)/$$p; then \
echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$p"; \
$(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(sysconfdir)/$$p; \
else if test -f $$p; then \
echo " $(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$p"; \
$(INSTALL_DATA) $$p $(DESTDIR)$(sysconfdir)/$$p; \
fi; fi; \
done
uninstall-sysconfDATA:
@$(NORMAL_UNINSTALL)
list='$(sysconf_DATA)'; for p in $$list; do \
rm -f $(DESTDIR)$(sysconfdir)/$$p; \
done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
test "$$subdir" != "." || dot_seen=yes; \
done; \
test "$$dot_seen" = "no" && rev=". $$rev"; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = proxychains
distdir: $(DISTFILES)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(top_distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu proxychains/Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
for subdir in $(SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
fi; \
done
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
-include $(DEP_FILES)
mostlyclean-depend:
clean-depend:
distclean-depend:
-rm -rf .deps
maintainer-clean-depend:
%.o: %.c
@echo '$(COMPILE) -c $<'; \
$(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-cp .deps/$(*F).pp .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*F).P; \
rm .deps/$(*F).pp
%.lo: %.c
@echo '$(LTCOMPILE) -c $<'; \
$(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
@-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
< .deps/$(*F).pp > .deps/$(*F).P; \
tr ' ' '\012' < .deps/$(*F).pp \
| sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
>> .deps/$(*F).P; \
rm -f .deps/$(*F).pp
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
install-exec-am: install-libLTLIBRARIES install-sysconfDATA
install-exec: install-exec-recursive
install-data-am: install-data-local
install-data: install-data-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-recursive
uninstall-am: uninstall-libLTLIBRARIES uninstall-sysconfDATA \
uninstall-local
uninstall: uninstall-recursive
all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS)
all-redirect: all-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(sysconfdir)
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
mostlyclean-generic
mostlyclean: mostlyclean-recursive
clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
clean-depend clean-generic mostlyclean-am
clean: clean-recursive
distclean-am: distclean-libLTLIBRARIES distclean-compile \
distclean-libtool distclean-tags distclean-depend \
distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-tags maintainer-clean-depend \
maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-recursive
.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
distclean-compile clean-compile maintainer-clean-compile \
mostlyclean-libtool distclean-libtool clean-libtool \
maintainer-clean-libtool uninstall-sysconfDATA install-sysconfDATA \
install-data-recursive uninstall-data-recursive install-exec-recursive \
uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
all-recursive check-recursive installcheck-recursive info-recursive \
dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir \
mostlyclean-depend distclean-depend clean-depend \
maintainer-clean-depend info-am info dvi-am dvi check check-am \
installcheck-am installcheck install-exec-am install-exec \
install-data-local install-data-am install-data install-am install \
uninstall-local uninstall-am uninstall all-redirect all-am all \
installdirs-am installdirs mostlyclean-generic distclean-generic \
clean-generic maintainer-clean-generic clean mostlyclean distclean \
maintainer-clean
install-data-local:
$(mkinstalldirs) ${DESTDIR}${bindir}
${INSTALL} $(srcdir)/proxychains ${DESTDIR}${bindir}/proxychains
${INSTALL} $(srcdir)/proxyresolv ${DESTDIR}${bindir}/proxyresolv
uninstall-local:
-rm -f ${DESTDIR}${bindir}/proxychains
-rm -f ${DESTDIR}${bindir}/proxyresolv
#install-private: install
# $(mkinstalldirs) $(HOME)/bin
# $(INSTALL_DATA) $(srcdir)/proxychains $(HOME)/bin/proxychains
#
#uninstall-private: uninstall
# -rm -f $(HOME)/bin/proxychains
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
-733
View File
@@ -1,733 +0,0 @@
/***************************************************************************
core.c - description
-------------------
begin : Tue May 14 2002
copyright : netcreature (C) 2002
email : netcreature@users.sourceforge.net
***************************************************************************/
/* GPL */
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#include <netdb.h>
#include <sys/utsname.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <time.h>
#include <stdarg.h>
#include "core.h"
extern int tcp_read_time_out;
extern int tcp_connect_time_out;
extern int proxychains_quiet_mode;
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void encode_base_64(char* src,char* dest,int max_len)
{
int n,l,i;
l=strlen(src);
max_len=(max_len-1)/4;
for ( i=0;i<max_len;i++,src+=3,l-=3)
{
switch (l) {
case 0:
break;
case 1:
n=src[0] << 16;
*dest++=base64[(n >> 18) & 077];
*dest++=base64[(n >> 12) & 077];
*dest++='=';
*dest++='=';
break;
case 2:
n=src[0] << 16 | src[1] << 8;
*dest++=base64[(n >> 18) & 077];
*dest++=base64[(n >> 12) & 077];
*dest++=base64[(n >> 6) & 077];
*dest++='=';
break;
default:
n=src[0] << 16 | src[1] << 8 | src[2];
*dest++=base64[(n >> 18) & 077];
*dest++=base64[(n >> 12) & 077];
*dest++=base64[(n >> 6) & 077];
*dest++=base64[n & 077];
}
if (l<3) break;
}
*dest++=0;
}
#define LOG_BUFF 1024*20
int proxychains_write_log(char *str,...)
{
char buff[LOG_BUFF];
va_list arglist;
FILE * log_file;
log_file=stderr;
if (!proxychains_quiet_mode)
{
va_start(arglist,str);
vsprintf(buff,str,arglist);
va_end(arglist);
fprintf(log_file,"%s",buff);
fflush(log_file);
}
return EXIT_SUCCESS;
}
static int write_n_bytes(int fd,char *buff,size_t size)
{
int i=0,wrote=0;
for(;;)
{
i=write(fd,&buff[wrote],size-wrote);
if(i<=0)
return i;
wrote+=i;
if(wrote==size)
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(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)
{
int i,ready;
struct pollfd pfd[1];
pfd[0].fd=fd;
pfd[0].events=POLLIN;
for(i=0;i<size;i++)
{
pfd[0].revents=0;
ready=poll(pfd,1,tcp_read_time_out);
if(ready!=1 || !(pfd[0].revents&POLLIN) || 1!=read(fd,&buff[i],1))
return -1;
}
return size;
}
static int timed_connect(int sock, const struct sockaddr *addr, unsigned int len)
{
int ret,value,value_len;
struct pollfd pfd[1];
pfd[0].fd=sock;
pfd[0].events=POLLOUT;
fcntl(sock, F_SETFL, O_NONBLOCK);
ret=true_connect(sock, addr, len);
// printf("\nconnect ret=%d\n",ret);fflush(stdout);
if(ret==-1 && errno==EINPROGRESS)
{
ret=poll(pfd,1,tcp_connect_time_out);
// printf("\npoll ret=%d\n",ret);fflush(stdout);
if(ret==1)
{
value_len=sizeof(int);
getsockopt(sock,SOL_SOCKET,SO_ERROR,&value,&value_len) ;
// printf("\nvalue=%d\n",value);fflush(stdout);
if(!value)
ret=0;
else
ret=-1;
}
else
ret=-1;
}
else if (ret==0)
;
else
ret=-1;
fcntl(sock, F_SETFL, !O_NONBLOCK);
return ret;
}
static int tunnel_to(int sock, unsigned int ip, unsigned short port, proxy_type pt,char *user,char *pass)
{
int len;
char buff[BUFF_SIZE];
bzero (buff,sizeof(buff));
switch(pt)
{
case HTTP_TYPE:
{
sprintf(buff,"CONNECT %s:%d HTTP/1.0\r\n",
inet_ntoa( * (struct in_addr *) &ip),
ntohs(port));
if (user[0])
{
char src[256];
char dst[512];
strcpy(src,user);
strcat(src,":");
strcat(src,pass);
encode_base_64(src,dst,512);
strcat(buff,"Proxy-Authorization: Basic ");
strcat(buff,dst);
strcat(buff,"\r\n\r\n");
}
else
strcat(buff,"\r\n");
len=strlen(buff);
if(len!=send(sock,buff,len,0))
return SOCKET_ERROR;
bzero(buff,sizeof(buff));
len=0 ;
// read header byte by byte.
while(len<BUFF_SIZE)
{
if(1==read_n_bytes(sock,buff+len,1))
len++;
else
return SOCKET_ERROR;
if ( len > 4 &&
buff[len-1]=='\n' &&
buff[len-2]=='\r' &&
buff[len-3]=='\n' &&
buff[len-4]=='\r' )
break;
}
// if not ok (200) or response greather than BUFF_SIZE return BLOCKED;
if ( (len==BUFF_SIZE) ||
! ( buff[9] =='2' &&
buff[10]=='0' &&
buff[11]=='0' ))
return BLOCKED;
return SUCCESS;
}
break;
case SOCKS4_TYPE:
{
memset(buff,0,sizeof(buff));
buff[0]=4; // socks version
buff[1]=1; // connect command
memcpy(&buff[2],&port,2); // dest port
memcpy(&buff[4],&ip,4); // dest host
len=strlen(user)+1; // username
if(len>1)
strcpy(&buff[8],user);
if((len+8)!=write_n_bytes(sock,buff,(8+len)))
return SOCKET_ERROR;
if(8!=read_n_bytes(sock,buff,8))
return SOCKET_ERROR;
if (buff[0]!=0||buff[1]!=90)
return BLOCKED;
return SUCCESS;
}
break;
case SOCKS5_TYPE:
{
if(user)
{
buff[0]=5; //version
buff[1]=2; //nomber of methods
buff[2]=0; // no auth method
buff[3]=2; /// auth method -> username / password
if(4!=write_n_bytes(sock,buff,4))
return SOCKET_ERROR;
}
else
{
buff[0]=5; //version
buff[1]=1; //nomber of methods
buff[2]=0; // no auth method
if(3!=write_n_bytes(sock,buff,3))
return SOCKET_ERROR;
}
memset(buff,0,sizeof(buff));
if(2!=read_n_bytes(sock,buff,2))
return SOCKET_ERROR;
if (buff[0]!=5||(buff[1]!=0&&buff[1]!=2))
{
if((buff[0]==0x05)&&(buff[1]==(char)0xFF))
return BLOCKED;
else
return SOCKET_ERROR;
}
if (buff[1]==2)
{
// authentication
char in[2];
char out[515]; char* cur=out;
int c;
*cur++=1; // version
c=strlen(user);
*cur++=c;
strncpy(cur,user,c);
cur+=c;
c=strlen(pass);
*cur++=c;
strncpy(cur,pass,c);
cur+=c;
if((cur-out)!=write_n_bytes(sock,out,cur-out))
return SOCKET_ERROR;
if(2!=read_n_bytes(sock,in,2))
return SOCKET_ERROR;
if(in[0]!=1||in[1]!=0)
{
if(in[0]!=1)
return SOCKET_ERROR;
else
return BLOCKED;
}
}
buff[0]=5; // version
buff[1]=1; // connect
buff[2]=0; // reserved
buff[3]=1; // ip v4
memcpy(&buff[4],&ip,4); // dest host
memcpy(&buff[8],&port,2); // dest port
if(10!=write_n_bytes(sock,buff,10))
return SOCKET_ERROR;
if(4!=read_n_bytes(sock,buff,4))
return SOCKET_ERROR;
if (buff[0]!=5||buff[1]!=0)
return SOCKET_ERROR;
switch (buff[3])
{
case 1: len=4; break;
case 4: len=16; break;
case 3: len=0;
if(1!=read_n_bytes(sock,(char*)&len,1))
return SOCKET_ERROR;
break;
default:
return SOCKET_ERROR;
}
if((len+2)!=read_n_bytes(sock,buff,(len+2)))
return SOCKET_ERROR;
return SUCCESS;
}
break;
}
return SOCKET_ERROR;
}
static int start_chain(int *fd, proxy_data *pd, char* begin_mark)
{
struct sockaddr_in addr;
*fd=socket(PF_INET,SOCK_STREAM,0);
if(*fd==-1)
goto error;
proxychains_write_log("%s-<>-%s:%d-",
begin_mark,
inet_ntoa(*(struct in_addr*)&pd->ip),
htons(pd->port));
pd->ps=PLAY_STATE;
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = pd->ip;
addr.sin_port = pd->port;
if (timed_connect (*fd ,(struct sockaddr*)&addr,sizeof(addr))) {
pd->ps=DOWN_STATE;
goto error1;
}
pd->ps=BUSY_STATE;
return SUCCESS;
error1:
proxychains_write_log("<--timeout\n");
error:
if(*fd!=-1)
close(*fd);
return SOCKET_ERROR;
}
static proxy_data * select_proxy(select_type how,
proxy_data *pd, int proxy_count, int *offset)
{
int i=0,k=0;
if(*offset>=proxy_count)
return NULL;
switch(how) {
case RANDOMLY:
srand(time(NULL));
do {
k++;
i = 0 + (int) (proxy_count*1.0*rand()/
(RAND_MAX+1.0));
} while (pd[i].ps!=PLAY_STATE && k<proxy_count*100 );
break;
case FIFOLY:
for(i=*offset;i<proxy_count;i++) {
if(pd[i].ps==PLAY_STATE) {
*offset=i;
break;
}
}
default:
break;
}
if (i>=proxy_count)
i=0;
return pd[i].ps==PLAY_STATE?&pd[i]:NULL;
}
static void release_all(proxy_data *pd, int proxy_count)
{
int i;
for(i=0;i<proxy_count;i++)
pd[i].ps=PLAY_STATE;
return;
}
static void release_busy(proxy_data *pd, int proxy_count)
{
int i;
for(i=0;i<proxy_count;i++)
if(pd[i].ps==BUSY_STATE)
pd[i].ps=PLAY_STATE;
return;
}
static int calc_alive(proxy_data *pd, int proxy_count)
{
int i;
int alive_count=0;
release_busy(pd,proxy_count);
for(i=0;i<proxy_count;i++)
if(pd[i].ps==PLAY_STATE)
alive_count++;
return alive_count;
}
static int chain_step(int ns, proxy_data *pfrom, proxy_data *pto)
{
int retcode=-1;
proxychains_write_log("<>-%s:%d-",
inet_ntoa(*(struct in_addr*)&pto->ip),
htons(pto->port));
retcode =
tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user,
pfrom->pass);
switch(retcode) {
case SUCCESS:
pto->ps=BUSY_STATE;
break;
case BLOCKED:
pto->ps=BLOCKED_STATE;
proxychains_write_log("<--denied\n");
close(ns);
break;
case SOCKET_ERROR:
pto->ps=DOWN_STATE;
proxychains_write_log("<--timeout\n");
close(ns);
break;
}
return retcode;
}
int connect_proxy_chain( int sock, unsigned int target_ip,
unsigned short target_port, proxy_data *pd,
unsigned int proxy_count, chain_type ct, int max_chain )
{
proxy_data p4;
proxy_data *p1,*p2,*p3;
int ns=-1;
int offset=0;
int alive_count=0;
int curr_len=0;
#define TP "<>"
#define DT "|D-chain|"
#define ST "|S-chain|"
#define RT "|R-chain|"
p3=&p4;
again:
switch(ct) {
case DYNAMIC_TYPE:
alive_count=calc_alive(pd,proxy_count);
offset=0;
do {
if(!(p1=select_proxy(FIFOLY,pd,proxy_count,&offset)))
goto error_more;
} while(SUCCESS!=start_chain(&ns,p1,DT) && offset<proxy_count);
for(;;) {
p2=select_proxy(FIFOLY,pd,proxy_count,&offset);
if(!p2)
break;
if(SUCCESS!=chain_step(ns,p1,p2))
goto again;
p1=p2;
}
proxychains_write_log(TP);
p3->ip=target_ip;
p3->port=target_port;
if(SUCCESS!=chain_step(ns,p1,p3))
goto error;
break;
case STRICT_TYPE:
alive_count=calc_alive(pd,proxy_count);
offset=0;
if(!(p1=select_proxy(FIFOLY,pd,proxy_count,&offset)))
goto error_strict;
if(SUCCESS!=start_chain(&ns,p1,ST))
goto error_strict;
while(offset<proxy_count) {
if(!(p2=select_proxy(FIFOLY,pd,proxy_count,&offset)))
break;
if(SUCCESS!=chain_step(ns,p1,p2))
goto error_strict;
p1=p2;
}
proxychains_write_log(TP);
p3->ip=target_ip;
p3->port=target_port;
if(SUCCESS!=chain_step(ns,p1,p3))
goto error;
break;
case RANDOM_TYPE:
alive_count=calc_alive(pd,proxy_count);
if(alive_count<max_chain)
goto error_more;
curr_len=offset=0;
do {
if(!(p1=select_proxy(RANDOMLY,pd,proxy_count,&offset)))
goto error_more;
} while(SUCCESS!=start_chain(&ns,p1,RT) && offset<max_chain);
while(++curr_len<max_chain) {
if(!(p2=select_proxy(RANDOMLY,pd,proxy_count,&offset)))
goto error_more;
if(SUCCESS!=chain_step(ns,p1,p2))
goto again;
p1=p2;
}
proxychains_write_log(TP);
p3->ip=target_ip;
p3->port=target_port;
if(SUCCESS!=chain_step(ns,p1,p3))
goto error;
}
done:
proxychains_write_log("<><>-OK\n");
dup2(ns,sock);
close(ns);
return 0;
error:
if(ns!=-1)
close(ns);
errno = ECONNREFUSED; // for nmap ;)
return -1;
error_more:
proxychains_write_log("\n!!!need more proxies!!!\n");
error_strict:
release_all(pd,proxy_count);
if(ns!=-1)
close(ns);
errno = ETIMEDOUT;
return -1;
}
static struct hostent hostent_space;
static in_addr_t resolved_addr;
static char* resolved_addr_p;
static char addr_name[1024*8];
struct hostent* proxy_gethostbyname(const char *name)
{
int pipe_fd[2];
char buff[256];
in_addr_t addr;
pid_t pid;
int status;
struct hostent* hp;
hostent_space.h_addr_list = &resolved_addr_p;
*hostent_space.h_addr_list = (char*)&resolved_addr;
resolved_addr = 0;
gethostname(buff,sizeof(buff));
if(!strcmp(buff,name))
goto got_buff;
bzero(buff,sizeof(buff));
// TODO: this works only once, so cache it ...
// later
while (hp=gethostent())
if (!strcmp(hp->h_name,name))
return hp;
if(pipe(pipe_fd))
goto err;
pid = fork();
switch(pid) {
case 0: // child
proxychains_write_log("|DNS-request| %s \n", name);
dup2(pipe_fd[1],1);
//dup2(pipe_fd[1],2);
// putenv("LD_PRELOAD=");
execlp("proxyresolv","proxyresolv",name,NULL);
perror("can't exec proxyresolv");
exit(2);
case -1: //error
close(pipe_fd[0]);
close(pipe_fd[1]);
perror("can't fork");
goto err;
default:
close(pipe_fd[1]);
waitpid(pid, &status, 0);
read(pipe_fd[0],&buff,sizeof(buff));
close(pipe_fd[0]);
got_buff:
addr = inet_addr(buff);
if (addr == -1)
goto err_dns;
memcpy(*(hostent_space.h_addr_list),
&addr ,sizeof(struct in_addr));
hostent_space.h_name = addr_name;
hostent_space.h_length = sizeof (in_addr_t);
}
proxychains_write_log("|DNS-response| %s is %s\n",
name, inet_ntoa(*(struct in_addr*)&addr));
return &hostent_space;
err_dns:
proxychains_write_log("|DNS-response|: %s is not exist\n", name);
err:
return NULL;
}
int proxy_getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res)
{
struct servent *se = NULL;
struct hostent *hp = NULL;
struct sockaddr* sockaddr_space = NULL;
struct addrinfo* addrinfo_space = NULL;
// printf("proxy_getaddrinfo node %s service %s\n",node,service);
addrinfo_space = malloc(sizeof(struct addrinfo));
if(!addrinfo_space)
goto err1;
sockaddr_space = malloc(sizeof(struct sockaddr));
if(!sockaddr_space)
goto err2;
bzero(sockaddr_space, sizeof(*sockaddr_space));
bzero(addrinfo_space, sizeof(*addrinfo_space));
if (node &&
!inet_aton(node,&((struct sockaddr_in*)sockaddr_space)->sin_addr)) {
hp = proxy_gethostbyname(node);
if (hp)
memcpy(&((struct sockaddr_in*)sockaddr_space)->sin_addr,
*(hp->h_addr_list),
sizeof(in_addr_t));
else
goto err3;
}
if (service)
se = getservbyname(service, NULL);
if (!se) {
((struct sockaddr_in*)sockaddr_space)->sin_port =
htons(atoi(service?:"0"));
} else
((struct sockaddr_in*)sockaddr_space)->sin_port = se->s_port;
*res = addrinfo_space;
(*res)->ai_addr = sockaddr_space;
if (node)
strcpy(addr_name, node);
(*res)->ai_canonname = addr_name;
(*res)->ai_next = NULL;
(*res)->ai_family = sockaddr_space->sa_family = AF_INET;
(*res)->ai_socktype = hints->ai_socktype;
(*res)->ai_flags = hints->ai_flags;
(*res)->ai_protocol = hints->ai_protocol;
(*res)->ai_addrlen = sizeof(*sockaddr_space);
goto out;
err3:
free(sockaddr_space);
err2:
free(addrinfo_space);
err1:
return 1;
out:
return 0;
}
-105
View File
@@ -1,105 +0,0 @@
/***************************************************************************
core.h - description
-------------------
begin : Tue May 14 2002
copyright : netcreature (C) 2002
email : netcreature@users.sourceforge.net
***************************************************************************/
/* GPL */
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef __CORE_HEADER
#define __CORE_HEADER
#define BUFF_SIZE 8*1024 // used to read responses from proxies.
/*error codes*/
typedef enum
{
SUCCESS=0,
MEMORY_FAIL, // malloc failed
SOCKET_ERROR, // look errno for more
CHAIN_DOWN, // no proxy in chain responds to tcp
CHAIN_EMPTY, // if proxy_count = 0
BLOCKED // target's port blocked on last proxy in the chain
} ERR_CODE;
typedef enum {HTTP_TYPE,SOCKS4_TYPE,SOCKS5_TYPE} proxy_type;
typedef enum {DYNAMIC_TYPE,STRICT_TYPE,RANDOM_TYPE} chain_type;
typedef enum {PLAY_STATE,DOWN_STATE,BLOCKED_STATE,BUSY_STATE} proxy_state;
typedef enum {RANDOMLY,FIFOLY} select_type;
typedef struct
{
unsigned int ip;
unsigned short port;
proxy_type pt;
proxy_state ps;
char user[256];
char pass[256];
} proxy_data;
typedef struct
{
proxy_data *pd;
chain_type ct;
unsigned int proxy_count;
int sock;
struct sockaddr addr;
int flags;
} thread_arg;
int connect_proxy_chain (
int sock,
unsigned int target_ip,
unsigned short target_port,
proxy_data * pd,
unsigned int proxy_count,
chain_type ct,
int max_chain );
int proxychains_write_log(char *str,...);
struct hostent* proxy_gethostbyname(const char *name);
typedef int (*connect_t)(int, const struct sockaddr *, socklen_t);
connect_t true_connect;
typedef struct hostent* (*gethostbyname_t)(const char *);
gethostbyname_t true_gethostbyname;
typedef int (*getaddrinfo_t)(const char *, const char *,
const struct addrinfo *,
struct addrinfo **);
getaddrinfo_t true_getaddrinfo;
typedef int (*freeaddrinfo_t)(struct addrinfo *);
freeaddrinfo_t true_freeaddrinfo;
typedef int (*getnameinfo_t) (const struct sockaddr *,
socklen_t, char *,
socklen_t, char *,
socklen_t, unsigned int);
getnameinfo_t true_getnameinfo;
typedef struct hostent *(*gethostbyaddr_t) (const void *, socklen_t, int);
gethostbyaddr_t true_gethostbyaddr;
int proxy_getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res);
struct hostent* proxy_gethostbyname(const char *name);
#if 0
#define PDEBUG(fmt, args...) fprintf(stderr,"DEBUG:"fmt, ## args)
#else
#define PDEBUG(fmt, args...)
#endif
#endif
-5
View File
@@ -1,5 +0,0 @@
####### kdevelop will overwrite this part!!! (begin)##########
SUBDIRS = en
####### kdevelop will overwrite this part!!! (end)############
-308
View File
@@ -1,308 +0,0 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
####### kdevelop will overwrite this part!!! (begin)##########
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
AR = @AR@
AS = @AS@
CC = @CC@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
GCJ = @GCJ@
GCJFLAGS = @GCJFLAGS@
HAVE_LIB = @HAVE_LIB@
LIB = @LIB@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIB = @LTLIB@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
RC = @RC@
STRIP = @STRIP@
VERSION = @VERSION@
SUBDIRS = en
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../config.h
CONFIG_CLEAN_FILES =
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu proxychains/docs/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
@SET_MAKE@
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
test "$$subdir" != "." || dot_seen=yes; \
done; \
test "$$dot_seen" = "no" && rev=". $$rev"; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
here=`pwd` && cd $(srcdir) \
&& mkid -f$$here/ID $$unique $(LISP)
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS)'; \
unique=`for i in $$list; do echo $$i; done | \
awk ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
|| (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
mostlyclean-tags:
clean-tags:
distclean-tags:
-rm -f TAGS ID
maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = proxychains/docs
distdir: $(DISTFILES)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(top_distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu proxychains/docs/Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
for subdir in $(SUBDIRS); do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
chmod 777 $(distdir)/$$subdir; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \
|| exit 1; \
fi; \
done
info-am:
info: info-recursive
dvi-am:
dvi: dvi-recursive
check-am: all-am
check: check-recursive
installcheck-am:
installcheck: installcheck-recursive
install-exec-am:
install-exec: install-exec-recursive
install-data-am:
install-data: install-data-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-recursive
uninstall-am:
uninstall: uninstall-recursive
all-am: Makefile
all-redirect: all-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs: installdirs-recursive
installdirs-am:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-tags mostlyclean-generic
mostlyclean: mostlyclean-recursive
clean-am: clean-tags clean-generic mostlyclean-am
clean: clean-recursive
distclean-am: distclean-tags distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-recursive
.PHONY: install-data-recursive uninstall-data-recursive \
install-exec-recursive uninstall-exec-recursive installdirs-recursive \
uninstalldirs-recursive all-recursive check-recursive \
installcheck-recursive info-recursive dvi-recursive \
mostlyclean-recursive distclean-recursive clean-recursive \
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
install-exec install-data-am install-data install-am install \
uninstall-am uninstall all-redirect all-am all installdirs-am \
installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
####### kdevelop will overwrite this part!!! (end)############
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
-4
View File
@@ -1,4 +0,0 @@
####### kdevelop will overwrite this part!!! (begin)##########
####### kdevelop will overwrite this part!!! (end)############
-202
View File
@@ -1,202 +0,0 @@
# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
####### kdevelop will overwrite this part!!! (begin)##########
####### kdevelop will overwrite this part!!! (end)############
SHELL = @SHELL@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
libexecdir = @libexecdir@
datadir = @datadir@
sysconfdir = @sysconfdir@
sharedstatedir = @sharedstatedir@
localstatedir = @localstatedir@
libdir = @libdir@
infodir = @infodir@
mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
DESTDIR =
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
ACLOCAL = @ACLOCAL@
AUTOCONF = @AUTOCONF@
AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
transform = @program_transform_name@
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_alias = @build_alias@
build_triplet = @build@
host_alias = @host_alias@
host_triplet = @host@
target_alias = @target_alias@
target_triplet = @target@
AR = @AR@
AS = @AS@
CC = @CC@
CXX = @CXX@
CXXCPP = @CXXCPP@
DLLTOOL = @DLLTOOL@
ECHO = @ECHO@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
GCJ = @GCJ@
GCJFLAGS = @GCJFLAGS@
HAVE_LIB = @HAVE_LIB@
LIB = @LIB@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIB = @LTLIB@
MAKEINFO = @MAKEINFO@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
RC = @RC@
STRIP = @STRIP@
VERSION = @VERSION@
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../../config.h
CONFIG_CLEAN_FILES =
DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu proxychains/docs/en/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
tags: TAGS
TAGS:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = proxychains/docs/en
distdir: $(DISTFILES)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(top_distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu proxychains/docs/en/Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \
|| cp -p $$d/$$file $(distdir)/$$file || :; \
fi; \
done
info-am:
info: info-am
dvi-am:
dvi: dvi-am
check-am: all-am
check: check-am
installcheck-am:
installcheck: installcheck-am
install-exec-am:
install-exec: install-exec-am
install-data-am:
install-data: install-data-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
install: install-am
uninstall-am:
uninstall: uninstall-am
all-am: Makefile
all-redirect: all-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
installdirs:
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
mostlyclean-am: mostlyclean-generic
mostlyclean: mostlyclean-am
clean-am: clean-generic mostlyclean-am
clean: clean-am
distclean-am: distclean-generic clean-am
-rm -f libtool
distclean: distclean-am
maintainer-clean-am: maintainer-clean-generic distclean-am
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
maintainer-clean: maintainer-clean-am
.PHONY: tags distdir info-am info dvi-am dvi check check-am \
installcheck-am installcheck install-exec-am install-exec \
install-data-am install-data install-am install uninstall-am uninstall \
all-redirect all-am all installdirs mostlyclean-generic \
distclean-generic clean-generic maintainer-clean-generic clean \
mostlyclean distclean maintainer-clean
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
-321
View File
@@ -1,321 +0,0 @@
/***************************************************************************
libproxychains.c - description
-------------------
begin : Tue May 14 2002
copyright : netcreature (C) 2002
email : netcreature@users.sourceforge.net
***************************************************************************/
/* GPL */
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#define _GNU_SOURCE
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/fcntl.h>
#include <dlfcn.h>
#include "core.h"
#define satosin(x) ((struct sockaddr_in *) &(x))
#define SOCKADDR(x) (satosin(x)->sin_addr.s_addr)
#define SOCKADDR_2(x) (satosin(x)->sin_addr)
#define SOCKPORT(x) (satosin(x)->sin_port)
#define SOCKFAMILY(x) (satosin(x)->sin_family)
#define MAX_CHAIN 30*1024
int tcp_read_time_out;
int tcp_connect_time_out;
chain_type proxychains_ct;
proxy_data proxychains_pd[MAX_CHAIN];
int proxychains_proxy_count = 0;
int proxychains_got_chain_data = 0;
int proxychains_max_chain = 1;
int proxychains_quiet_mode = 0;
int proxychains_resolver = 0;
static int init_l = 0;
static inline void get_chain_data(
proxy_data *pd,
unsigned int *proxy_count,
chain_type *ct);
static void init_lib()
{
// proxychains_write_log("ProxyChains-"VERSION
// " (http://proxychains.sf.net)\n");
get_chain_data(proxychains_pd,&proxychains_proxy_count,&proxychains_ct);
true_connect = (connect_t) dlsym(RTLD_NEXT, "connect");
if (!true_connect) {
fprintf(stderr, "Cannot load symbol 'connect' %s\n", dlerror());
exit(1);
} else {
// PDEBUG( "loaded symbol 'connect'"
// " real addr %p wrapped addr %p\n",
// true_connect, connect);
}
true_gethostbyname = (gethostbyname_t)
dlsym(RTLD_NEXT, "gethostbyname");
if (!true_gethostbyname) {
fprintf(stderr, "Cannot load symbol 'gethostbyname' %s\n",
dlerror());
exit(1);
} else {
// PDEBUG( "loaded symbol 'gethostbyname'"
// " real addr %p wrapped addr %p\n",
// true_gethostbyname, gethostbyname);
}
true_getaddrinfo = (getaddrinfo_t)
dlsym(RTLD_NEXT, "getaddrinfo");
if (!true_getaddrinfo) {
fprintf(stderr, "Cannot load symbol 'getaddrinfo' %s\n",
dlerror());
exit(1);
} else {
// PDEBUG( "loaded symbol 'getaddrinfo'"
// " real addr %p wrapped addr %p\n",
// true_getaddrinfo, getaddrinfo);
}
true_freeaddrinfo = (freeaddrinfo_t)
dlsym(RTLD_NEXT, "freeaddrinfo");
if (!true_freeaddrinfo) {
fprintf(stderr, "Cannot load symbol 'freeaddrinfo' %s\n",
dlerror());
exit(1);
} else {
// PDEBUG( "loaded symbol 'freeaddrinfo'"
// " real addr %p wrapped addr %p\n",
// true_freeaddrinfo, freeaddrinfo);
}
true_gethostbyaddr = (gethostbyaddr_t)
dlsym(RTLD_NEXT, "gethostbyaddr");
if (!true_gethostbyaddr) {
fprintf(stderr, "Cannot load symbol 'gethostbyaddr' %s\n",
dlerror());
exit(1);
} else {
// PDEBUG( "loaded symbol 'gethostbyaddr'"
// " real addr %p wrapped addr %p\n",
// true_gethostbyaddr, gethostbyaddr);
}
true_getnameinfo = (getnameinfo_t)
dlsym(RTLD_NEXT, "getnameinfo");
if (!true_getnameinfo) {
fprintf(stderr, "Cannot load symbol 'getnameinfo' %s\n",
dlerror());
exit(1);
} else {
// PDEBUG( "loaded symbol 'getnameinfo'"
// " real addr %p wrapped addr %p\n",
// true_getnameinfo, getnameinfo);
}
init_l = 1;
}
static inline void get_chain_data(
proxy_data *pd,
unsigned int *proxy_count,
chain_type *ct)
{
int count=0,port_n=0,list=0;
char buff[1024],type[1024],host[1024],user[1024];
FILE* file;
if(proxychains_got_chain_data)
return;
//Some defaults
tcp_read_time_out=4*1000;
tcp_connect_time_out=10*1000;
*ct=DYNAMIC_TYPE;
snprintf(buff,256,"%s/.proxychains/proxychains.conf",getenv("HOME"));
if(!(file=fopen("./proxychains.conf","r")))
if(!(file=fopen(buff,"r")))
if(!(file=fopen("/etc/proxychains.conf","r")))
{
perror("Can't locate proxychains.conf");
exit(1);
}
while(fgets(buff,sizeof(buff),file)) {
if(buff[strspn(buff," ")]!='#') {
if(list) {
bzero(&pd[count], sizeof(proxy_data));
pd[count].ps=PLAY_STATE;
port_n=0;
sscanf(buff,"%s %s %d %s %s", type,host,&port_n,
pd[count].user,pd[count].pass);
pd[count].ip=inet_addr(host);
pd[count].port=htons((unsigned short)port_n);
if(!strcmp(type,"http")) {
pd[count].pt=HTTP_TYPE;
}else if(!strcmp(type,"socks4")) {
pd[count].pt=SOCKS4_TYPE;
}else if(!strcmp(type,"socks5")) {
pd[count].pt=SOCKS5_TYPE;
}else continue;
if( pd[count].ip && pd[count].ip!=-1 && port_n)
if(++count==MAX_CHAIN)
break;
} else {
if(strstr(buff,"[ProxyList]")) {
list=1;
} else if(strstr(buff,"random_chain")) {
*ct=RANDOM_TYPE;
} else if(strstr(buff,"strict_chain")) {
*ct=STRICT_TYPE;
} else if(strstr(buff,"dynamic_chain")) {
*ct=DYNAMIC_TYPE;
}else if(strstr(buff,"tcp_read_time_out")){
sscanf(buff,"%s %d",user,&tcp_read_time_out) ;
}else if(strstr(buff,"tcp_connect_time_out")){
sscanf(buff,"%s %d",user,&tcp_connect_time_out) ;
}else if(strstr(buff,"chain_len")){
char *pc;int len;
pc=strchr(buff,'=');
len=atoi(++pc);
proxychains_max_chain=(len?len:1);
}else if(strstr(buff,"quiet_mode")){
proxychains_quiet_mode=1;
}else if(strstr(buff,"proxy_dns")){
proxychains_resolver=1;
}
}
}
}
fclose(file);
*proxy_count=count;
proxychains_got_chain_data=1;
}
int connect (int sock, const struct sockaddr *addr, unsigned int len)
{
int socktype=0,optlen=0,flags=0,ret=0;
if(!init_l)
init_lib();
optlen=sizeof(socktype);
getsockopt(sock,SOL_SOCKET,SO_TYPE,&socktype,&optlen);
if (! (SOCKFAMILY(*addr)==AF_INET && socktype==SOCK_STREAM))
return true_connect(sock,addr,len);
flags=fcntl(sock, F_GETFL, 0);
if(flags & O_NONBLOCK)
fcntl(sock, F_SETFL, !O_NONBLOCK);
ret=connect_proxy_chain(
sock,
SOCKADDR(*addr),
SOCKPORT(*addr),
proxychains_pd,
proxychains_proxy_count,
proxychains_ct,
proxychains_max_chain );
fcntl(sock, F_SETFL, flags);
if(ret!=SUCCESS)
errno=ECONNREFUSED;
return ret;
}
struct hostent *gethostbyname(const char *name)
{
PDEBUG("gethostbyname: %s\n",name);
if(!init_l)
init_lib();
if(proxychains_resolver)
return proxy_gethostbyname(name);
else
return true_gethostbyname(name);
return NULL;
}
int getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints,
struct addrinfo **res)
{
int ret = 0;
PDEBUG("getaddrinfo: %s %s\n",node ,service);
if(!init_l)
init_lib();
if(proxychains_resolver)
ret = proxy_getaddrinfo(node, service, hints, res);
else
ret = true_getaddrinfo(node, service, hints, res);
return ret;
}
void freeaddrinfo(struct addrinfo *res)
{
PDEBUG("freeaddrinfo %p \n",res);
if(!init_l)
init_lib();
if(!proxychains_resolver)
true_freeaddrinfo(res);
else {
free(res->ai_addr);
free(res);
}
return;
}
int getnameinfo (const struct sockaddr * sa,
socklen_t salen, char * host,
socklen_t hostlen, char * serv,
socklen_t servlen, unsigned int flags)
{
int ret = 0;
if(!init_l)
init_lib();
if(!proxychains_resolver) {
ret = true_getnameinfo(sa,salen,host,hostlen,
serv,servlen,flags);
} else {
if(hostlen)
strncpy(host, inet_ntoa(SOCKADDR_2(*sa)),hostlen);
if(servlen)
snprintf(serv, servlen,"%d",ntohs(SOCKPORT(*sa)));
}
PDEBUG("getnameinfo: %s %s\n", host, serv);
return ret;
}
struct hostent *gethostbyaddr (const void *addr, socklen_t len,
int type)
{
PDEBUG("TODO: gethostbyaddr hook\n");
if(!init_l)
init_lib();
if(!proxychains_resolver)
return true_gethostbyaddr(addr,len,type);
return NULL;
}
-48
View File
@@ -1,48 +0,0 @@
/***************************************************************************
main.c - description
-------------------
begin : Tue May 14 2002
copyright : netcreature (C) 2002
email : netcreature@users.sourceforge.net
***************************************************************************/
/* GPL */
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/*
* well ... actually this file could be a shell script ... but C rulez :).
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
if(argc<2)
{
printf("\nUsage: proxychains program_name [arguments]\n"
"\t for example : proxychains telnet somehost.com\n"
"More help in README file\n");
return 0 ;
}
putenv("LD_PRELOAD=/usr/lib/libproxychains.so");
execvp(argv[1],&argv[1]);
perror("proxychains can't load process....");
return EXIT_SUCCESS;
}
-9
View File
@@ -1,9 +0,0 @@
#!/bin/sh
echo "ProxyChains-3.1 (http://proxychains.sf.net)"
if [ $# = 0 ] ; then
echo " usage:"
echo " proxychains <prog> [args]"
exit
fi
export LD_PRELOAD=libproxychains.so
exec "$@"
-65
View File
@@ -1,65 +0,0 @@
# proxychains.conf VER 3.1
#
# HTTP, SOCKS4, SOCKS5 tunneling proxifier with DNS.
#
# The option below identifies how the ProxyList is treated.
# only one option should be uncommented at time,
# otherwise the last appearing option will be accepted
#
#dynamic_chain
#
# Dynamic - Each connection will be done via chained proxies
# all proxies chained in the order as they appear in the list
# at least one proxy must be online to play in chain
# (dead proxies are skipped)
# otherwise EINTR is returned to the app
#
strict_chain
#
# Strict - Each connection will be done via chained proxies
# all proxies chained in the order as they appear in the list
# all proxies must be online to play in chain
# otherwise EINTR is returned to the app
#
#random_chain
#
# Random - Each connection will be done via random proxy
# (or proxy chain, see chain_len) from the list.
# this option is good to test your IDS :)
# Make sense only if random_chain
#chain_len = 2
# Quiet mode (no output from library)
#quiet_mode
# Proxy DNS requests - no leak for DNS data
proxy_dns
# Some timeouts in milliseconds
tcp_read_time_out 15000
tcp_connect_time_out 8000
# ProxyList format
# type host port [user pass]
# (values separated by 'tab' or 'blank')
#
#
# Examples:
#
# socks5 192.168.67.78 1080 lamer secret
# http 192.168.89.3 8080 justu hidden
# socks4 192.168.1.49 1080
# http 192.168.39.93 8080
#
#
# proxy types: http, socks4, socks5
# ( auth types supported: "basic"-http "user/pass"-socks )
#
[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
socks4 127.0.0.1 9050
-16
View File
@@ -1,16 +0,0 @@
#!/bin/sh
# This script is called by proxychains to resolve DNS names
# DNS server used to resolve names
DNS_SERVER=4.2.2.2
if [ $# = 0 ] ; then
echo " usage:"
echo " proxyresolv <hostname> "
exit
fi
export LD_PRELOAD=libproxychains.so
dig $1 @$DNS_SERVER +tcp | awk '/A.+[0-9]+\.[0-9]+\.[0-9]/{print $5;}'
+296
View File
@@ -0,0 +1,296 @@
#include <pthread.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/select.h>
#include <assert.h>
#include <string.h>
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
#include "allocator_thread.h"
#include "shm.h"
#include "debug.h"
#include "ip_type.h"
#include "mutex.h"
#include "hash.h"
#include "stringdump.h"
/* stuff for our internal translation table */
typedef struct {
uint32_t hash;
char* string;
} string_hash_tuple;
typedef struct {
uint32_t counter;
uint32_t capa;
string_hash_tuple** list;
} internal_ip_lookup_table;
pthread_mutex_t internal_ips_lock;
internal_ip_lookup_table *internal_ips = NULL;
internal_ip_lookup_table internal_ips_buf;
uint32_t index_from_internal_ip(ip_type internalip) {
PFUNC();
ip_type tmp = internalip;
uint32_t ret;
ret = tmp.octet[3] + (tmp.octet[2] << 8) + (tmp.octet[1] << 16);
ret -= 1;
return ret;
}
char *string_from_internal_ip(ip_type internalip) {
PFUNC();
char *res = NULL;
uint32_t index = index_from_internal_ip(internalip);
if(index < internal_ips->counter)
res = internal_ips->list[index]->string;
return res;
}
extern unsigned int remote_dns_subnet;
ip_type make_internal_ip(uint32_t index) {
ip_type ret;
index++; // so we can start at .0.0.1
if(index > 0xFFFFFF)
return ip_type_invalid;
ret.octet[0] = remote_dns_subnet & 0xFF;
ret.octet[1] = (index & 0xFF0000) >> 16;
ret.octet[2] = (index & 0xFF00) >> 8;
ret.octet[3] = index & 0xFF;
return ret;
}
static ip_type ip_from_internal_list(char* name, size_t len) {
uint32_t hash = dalias_hash((char *) name);
size_t i;
ip_type res;
void* new_mem;
// see if we already have this dns entry saved.
if(internal_ips->counter) {
for(i = 0; i < internal_ips->counter; i++) {
if(internal_ips->list[i]->hash == hash && !strcmp(name, internal_ips->list[i]->string)) {
res = make_internal_ip(i);
PDEBUG("got cached ip for %s\n", name);
goto have_ip;
}
}
}
// grow list if needed.
if(internal_ips->capa < internal_ips->counter + 1) {
PDEBUG("realloc\n");
new_mem = realloc(internal_ips->list, (internal_ips->capa + 16) * sizeof(void *));
if(new_mem) {
internal_ips->capa += 16;
internal_ips->list = new_mem;
} else {
oom:
PDEBUG("out of mem\n");
goto err_plus_unlock;
}
}
res = make_internal_ip(internal_ips->counter);
if(res.as_int == ip_type_invalid.as_int)
goto err_plus_unlock;
string_hash_tuple tmp = { 0 };
new_mem = dumpstring((char*) &tmp, sizeof(string_hash_tuple));
if(!new_mem)
goto oom;
PDEBUG("creating new entry %d for ip of %s\n", (int) internal_ips->counter, name);
internal_ips->list[internal_ips->counter] = new_mem;
internal_ips->list[internal_ips->counter]->hash = hash;
new_mem = dumpstring((char*) name, len + 1);
if(!new_mem) {
internal_ips->list[internal_ips->counter] = 0;
goto oom;
}
internal_ips->list[internal_ips->counter]->string = new_mem;
internal_ips->counter += 1;
have_ip:
return res;
err_plus_unlock:
PDEBUG("return err\n");
return ip_type_invalid;
}
/* stuff for communication with the allocator thread */
enum at_msgtype {
ATM_GETIP,
ATM_GETNAME,
ATM_EXIT,
};
enum at_direction {
ATD_SERVER = 0,
ATD_CLIENT,
ATD_MAX,
};
struct at_msghdr {
enum at_msgtype msgtype;
size_t datalen;
};
static pthread_t allocator_thread;
static pthread_attr_t allocator_thread_attr;
int req_pipefd[2];
int resp_pipefd[2];
static int wait_data(int readfd) {
PFUNC();
fd_set fds;
FD_ZERO(&fds);
FD_SET(readfd, &fds);
int ret;
while((ret = select(readfd+1, &fds, NULL, NULL, NULL)) <= 0) {
if(ret < 0) {
int e = errno;
if(e == EINTR) continue;
#ifdef __GLIBC__
char emsg[1024];
char* x = strerror_r(errno, emsg, sizeof emsg);
dprintf(2, "select2: %s\n", x);
#endif
return 0;
}
}
return 1;
}
static int sendmessage(enum at_direction dir, struct at_msghdr *hdr, void* data) {
static int* destfd[ATD_MAX] = { [ATD_SERVER] = &req_pipefd[1], [ATD_CLIENT] = &resp_pipefd[1] };
int ret = write(*destfd[dir], hdr, sizeof *hdr) == sizeof *hdr;
if(ret && hdr->datalen) {
assert(hdr->datalen <= MSG_LEN_MAX);
ret = write(*destfd[dir], data, hdr->datalen) == hdr->datalen;
}
return ret;
}
static int getmessage(enum at_direction dir, struct at_msghdr *hdr, void* data) {
static int* readfd[ATD_MAX] = { [ATD_SERVER] = &req_pipefd[0], [ATD_CLIENT] = &resp_pipefd[0] };
int ret;
if((ret = wait_data(*readfd[dir]))) {
ret = read(*readfd[dir], hdr, sizeof *hdr) == sizeof(*hdr);
assert(hdr->datalen <= MSG_LEN_MAX);
if(ret && hdr->datalen) {
ret = read(*readfd[dir], data, hdr->datalen) == hdr->datalen;
}
}
return ret;
}
static void* threadfunc(void* x) {
(void) x;
int ret;
struct at_msghdr msg;
union {
char host[MSG_LEN_MAX];
ip_type ip;
} readbuf;
while((ret = getmessage(ATD_SERVER, &msg, &readbuf))) {
switch(msg.msgtype) {
case ATM_GETIP:
/* client wants an ip for a DNS name. iterate our list and check if we have an existing entry.
* if not, create a new one. */
readbuf.ip = ip_from_internal_list(readbuf.host, msg.datalen - 1);
msg.datalen = sizeof(ip_type);
break;
case ATM_GETNAME: {
char *host = string_from_internal_ip(readbuf.ip);
if(host) {
size_t l = strlen(host);
assert(l < MSG_LEN_MAX);
memcpy(readbuf.host, host, l + 1);
msg.datalen = l + 1;
}
break;
}
case ATM_EXIT:
return 0;
default:
abort();
}
ret = sendmessage(ATD_CLIENT, &msg, &readbuf);
}
return 0;
}
/* API to access the internal ip mapping */
ip_type at_get_ip_for_host(char* host, size_t len) {
ip_type readbuf;
MUTEX_LOCK(&internal_ips_lock);
if(len > MSG_LEN_MAX) goto inv;
struct at_msghdr msg = {.msgtype = ATM_GETIP, .datalen = len + 1 };
if(sendmessage(ATD_SERVER, &msg, host) &&
getmessage(ATD_CLIENT, &msg, &readbuf));
else {
inv:
readbuf = ip_type_invalid;
}
MUTEX_UNLOCK(&internal_ips_lock);
return readbuf;
}
size_t at_get_host_for_ip(ip_type ip, char* readbuf) {
struct at_msghdr msg = {.msgtype = ATM_GETNAME, .datalen = sizeof(ip_type) };
size_t res = 0;
MUTEX_LOCK(&internal_ips_lock);
if(sendmessage(ATD_SERVER, &msg, &ip) && getmessage(ATD_CLIENT, &msg, readbuf)) {
if((ptrdiff_t) msg.datalen <= 0) res = 0;
else res = msg.datalen - 1;
}
MUTEX_UNLOCK(&internal_ips_lock);
return res;
}
static void initpipe(int* fds) {
if(pipe(fds) == -1) {
perror("pipe");
exit(1);
}
}
/* initialize with pointers to shared memory. these will
* be used to place responses and arguments */
void at_init(void) {
PFUNC();
MUTEX_INIT(&internal_ips_lock);
internal_ips = &internal_ips_buf;
memset(internal_ips, 0, sizeof *internal_ips);
initpipe(req_pipefd);
initpipe(resp_pipefd);
pthread_attr_init(&allocator_thread_attr);
pthread_attr_setstacksize(&allocator_thread_attr, 16 * 1024);
pthread_create(&allocator_thread, &allocator_thread_attr, threadfunc, 0);
}
void at_close(void) {
PFUNC();
const int msg = ATM_EXIT;
write(req_pipefd[1], &msg, sizeof(int));
pthread_join(allocator_thread, NULL);
close(req_pipefd[0]);
close(req_pipefd[1]);
close(resp_pipefd[0]);
close(resp_pipefd[1]);
pthread_attr_destroy(&allocator_thread_attr);
MUTEX_DESTROY(&internal_ips_lock);
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef ALLOCATOR_THREAD_H
#define ALLOCATOR_THREAD_H
#include <unistd.h>
#include "ip_type.h"
#define MSG_LEN_MAX 256
extern int req_pipefd[2];
extern int resp_pipefd[2];
void at_init(void);
void at_close(void);
size_t at_get_host_for_ip(ip_type ip, char* readbuf);
ip_type at_get_ip_for_host(char* host, size_t len);
//RcB: DEP "allocator_thread.c"
#endif
+78
View File
@@ -0,0 +1,78 @@
#include "common.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
// stolen from libulz (C) rofl0r
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;
}
static int check_path(char *path) {
if(!path)
return 0;
return access(path, R_OK) != -1;
}
char *get_config_path(char* default_path, char* pbuf, size_t bufsize) {
char buf[512];
// top priority: user defined path
char *path = default_path;
if(check_path(path))
goto have;
// priority 1: env var PROXYCHAINS_CONF_FILE
path = getenv(PROXYCHAINS_CONF_FILE_ENV_VAR);
if(check_path(path))
goto have;
// priority 2; proxychains conf in actual dir
path = getcwd(buf, sizeof(buf));
snprintf(pbuf, bufsize, "%s/%s", path, PROXYCHAINS_CONF_FILE);
path = pbuf;
if(check_path(path))
goto have;
// priority 3; $HOME/.proxychains/proxychains.conf
path = getenv("HOME");
snprintf(pbuf, bufsize, "%s/.proxychains/%s", path, PROXYCHAINS_CONF_FILE);
path = pbuf;
if(check_path(path))
goto have;
// priority 4: $SYSCONFDIR/proxychains.conf
path = SYSCONFDIR "/" PROXYCHAINS_CONF_FILE;
if(check_path(path))
goto have;
// priority 5: /etc/proxychains.conf
path = "/etc/" PROXYCHAINS_CONF_FILE;
if(check_path(path))
goto have;
perror("couldnt find configuration file");
exit(1);
return NULL;
have:
return path;
}
+18
View File
@@ -0,0 +1,18 @@
#ifndef COMMON_H
#define COMMON_H
#define PROXYCHAINS_CONF_FILE_ENV_VAR "PROXYCHAINS_CONF_FILE"
#define PROXYCHAINS_QUIET_MODE_ENV_VAR "PROXYCHAINS_QUIET_MODE"
#define PROXYCHAINS_CONF_FILE "proxychains.conf"
#define LOG_PREFIX "[proxychains] "
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
#include <stddef.h>
char *get_config_path(char* default_path, char* pbuf, size_t bufsize);
void pc_stringfromipv4(unsigned char *ip_buf_4_bytes, char *outbuf_16_bytes);
//RcB: DEP "common.c"
#endif
+813
View File
@@ -0,0 +1,813 @@
/***************************************************************************
core.c - description
-------------------
begin : Tue May 14 2002
copyright : netcreature (C) 2002
email : netcreature@users.sourceforge.net
***************************************************************************
* GPL *
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <sys/utsname.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <time.h>
#include <sys/time.h>
#include <stdarg.h>
#include <assert.h>
#include "core.h"
#include "common.h"
#include "shm.h"
#include "allocator_thread.h"
extern int tcp_read_time_out;
extern int tcp_connect_time_out;
extern int proxychains_quiet_mode;
extern unsigned int remote_dns_subnet;
static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout) {
int ret;
int time_remain = timeout;
int time_elapsed = 0;
struct timeval start_time;
struct timeval tv;
gettimeofday(&start_time, NULL);
do {
//printf("Retry %d\n", time_remain);
ret = poll(fds, nfsd, time_remain);
gettimeofday(&tv, NULL);
time_elapsed = ((tv.tv_sec - start_time.tv_sec) * 1000 + (tv.tv_usec - start_time.tv_usec) / 1000);
//printf("Time elapsed %d\n", time_elapsed);
time_remain = timeout - time_elapsed;
} while(ret == -1 && errno == EINTR && time_remain > 0);
//if (ret == -1)
//printf("Return %d %d %s\n", ret, errno, strerror(errno));
return ret;
}
static void encode_base_64(char *src, char *dest, int max_len) {
static const char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int n, l, i;
l = strlen(src);
max_len = (max_len - 1) / 4;
for(i = 0; i < max_len; i++, src += 3, l -= 3) {
switch (l) {
case 0:
break;
case 1:
n = src[0] << 16;
*dest++ = base64[(n >> 18) & 077];
*dest++ = base64[(n >> 12) & 077];
*dest++ = '=';
*dest++ = '=';
break;
case 2:
n = src[0] << 16 | src[1] << 8;
*dest++ = base64[(n >> 18) & 077];
*dest++ = base64[(n >> 12) & 077];
*dest++ = base64[(n >> 6) & 077];
*dest++ = '=';
break;
default:
n = src[0] << 16 | src[1] << 8 | src[2];
*dest++ = base64[(n >> 18) & 077];
*dest++ = base64[(n >> 12) & 077];
*dest++ = base64[(n >> 6) & 077];
*dest++ = base64[n & 077];
}
if(l < 3)
break;
}
*dest++ = 0;
}
void proxychains_write_log(char *str, ...) {
char buff[1024*20];
va_list arglist;
if(!proxychains_quiet_mode) {
va_start(arglist, str);
vsnprintf(buff, sizeof(buff), str, arglist);
va_end(arglist);
fprintf(stderr, "%s", buff);
fflush(stderr);
}
}
static int write_n_bytes(int fd, char *buff, size_t size) {
int i = 0;
size_t wrote = 0;
for(;;) {
i = write(fd, &buff[wrote], size - wrote);
if(i <= 0)
return i;
wrote += i;
if(wrote == size)
return wrote;
}
}
static int read_n_bytes(int fd, char *buff, size_t size) {
int ready;
size_t i;
struct pollfd pfd[1];
pfd[0].fd = fd;
pfd[0].events = POLLIN;
for(i = 0; i < size; 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;
}
return (int) size;
}
static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) {
int ret, value;
socklen_t value_len;
struct pollfd pfd[1];
PFUNC();
pfd[0].fd = sock;
pfd[0].events = POLLOUT;
fcntl(sock, F_SETFL, O_NONBLOCK);
ret = true_connect(sock, addr, len);
PDEBUG("\nconnect ret=%d\n", ret);
if(ret == -1 && errno == EINPROGRESS) {
ret = poll_retry(pfd, 1, tcp_connect_time_out);
PDEBUG("\npoll ret=%d\n", ret);
if(ret == 1) {
value_len = sizeof(socklen_t);
getsockopt(sock, SOL_SOCKET, SO_ERROR, &value, &value_len);
PDEBUG("\nvalue=%d\n", value);
if(!value)
ret = 0;
else
ret = -1;
} else {
ret = -1;
}
} else {
#ifdef DEBUG
if(ret == -1)
perror("true_connect");
#endif
if(ret != 0)
ret = -1;
}
fcntl(sock, F_SETFL, !O_NONBLOCK);
return ret;
}
#define INVALID_INDEX 0xFFFFFFFFU
static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, char *user, char *pass) {
char *dns_name = NULL;
char hostnamebuf[MSG_LEN_MAX];
size_t dns_len = 0;
PFUNC();
// we use ip addresses with 224.* to lookup their dns name in our table, to allow remote DNS resolution
// the range 224-255.* is reserved, and it won't go outside (unless the app does some other stuff with
// the results returned from gethostbyname et al.)
// the hardcoded number 224 can now be changed using the config option remote_dns_subnet to i.e. 127
if(ip.octet[0] == remote_dns_subnet) {
dns_len = at_get_host_for_ip(ip, hostnamebuf);
if(!dns_len) goto err;
else dns_name = hostnamebuf;
}
PDEBUG("host dns %s\n", dns_name ? dns_name : "<NULL>");
size_t ulen = strlen(user);
size_t passlen = strlen(pass);
if(ulen > 0xFF || passlen > 0xFF || dns_len > 0xFF) {
proxychains_write_log(LOG_PREFIX "error: maximum size of 255 for user/pass or domain name!\n");
goto err;
}
int len;
unsigned char buff[BUFF_SIZE];
char ip_buf[16];
//memset (buff, 0, sizeof(buff));
switch (pt) {
case HTTP_TYPE:{
if(!dns_len) {
pc_stringfromipv4(&ip.octet[0], ip_buf);
dns_name = ip_buf;
}
snprintf((char *) buff, sizeof(buff), "CONNECT %s:%d HTTP/1.0\r\n", dns_name,
ntohs(port));
if(user[0]) {
#define HTTP_AUTH_MAX ((0xFF * 2) + 1 + 1)
// 2 * 0xff: username and pass, plus 1 for ':' and 1 for zero terminator.
char src[HTTP_AUTH_MAX];
char dst[(4 * HTTP_AUTH_MAX)];
memcpy(src, user, ulen);
memcpy(src + ulen, ":", 1);
memcpy(src + ulen + 1, pass, passlen);
src[ulen + 1 + passlen] = 0;
encode_base_64(src, dst, sizeof(dst));
strcat((char *) buff, "Proxy-Authorization: Basic ");
strcat((char *) buff, dst);
strcat((char *) buff, "\r\n\r\n");
} else
strcat((char *) buff, "\r\n");
len = strlen((char *) buff);
if(len != send(sock, buff, len, 0))
goto err;
len = 0;
// read header byte by byte.
while(len < BUFF_SIZE) {
if(1 == read_n_bytes(sock, (char *) (buff + len), 1))
len++;
else
goto err;
if(len > 4 &&
buff[len - 1] == '\n' &&
buff[len - 2] == '\r' && buff[len - 3] == '\n' && buff[len - 4] == '\r')
break;
}
// if not ok (200) or response greather than BUFF_SIZE return BLOCKED;
if(len == BUFF_SIZE || !(buff[9] == '2' && buff[10] == '0' && buff[11] == '0'))
return BLOCKED;
return SUCCESS;
}
break;
case SOCKS4_TYPE:{
buff[0] = 4; // socks version
buff[1] = 1; // connect command
memcpy(&buff[2], &port, 2); // dest port
if(dns_len) {
ip.octet[0] = 0;
ip.octet[1] = 0;
ip.octet[2] = 0;
ip.octet[3] = 1;
}
memcpy(&buff[4], &ip, 4); // dest host
len = ulen + 1; // username
if(len > 1)
memcpy(&buff[8], user, len);
else {
buff[8] = 0;
}
// do socksv4a dns resolution on the server
if(dns_len) {
memcpy(&buff[8 + len], dns_name, dns_len + 1);
len += dns_len + 1;
}
if((len + 8) != write_n_bytes(sock, (char *) buff, (8 + len)))
goto err;
if(8 != read_n_bytes(sock, (char *) buff, 8))
goto err;
if(buff[0] != 0 || buff[1] != 90)
return BLOCKED;
return SUCCESS;
}
break;
case SOCKS5_TYPE:{
if(user) {
buff[0] = 5; //version
buff[1] = 2; //nomber of methods
buff[2] = 0; // no auth method
buff[3] = 2; /// auth method -> username / password
if(4 != write_n_bytes(sock, (char *) buff, 4))
goto err;
} else {
buff[0] = 5; //version
buff[1] = 1; //nomber of methods
buff[2] = 0; // no auth method
if(3 != write_n_bytes(sock, (char *) buff, 3))
goto err;
}
if(2 != read_n_bytes(sock, (char *) buff, 2))
goto err;
if(buff[0] != 5 || (buff[1] != 0 && buff[1] != 2)) {
if(buff[0] == 5 && buff[1] == 0xFF)
return BLOCKED;
else
goto err;
}
if(buff[1] == 2) {
// authentication
char in[2];
char out[515];
char *cur = out;
size_t c;
*cur++ = 1; // version
c = ulen & 0xFF;
*cur++ = c;
memcpy(cur, user, c);
cur += c;
c = passlen & 0xFF;
*cur++ = c;
memcpy(cur, pass, c);
cur += c;
if((cur - out) != write_n_bytes(sock, out, cur - out))
goto err;
if(2 != read_n_bytes(sock, in, 2))
goto err;
if(in[0] != 1 || in[1] != 0) {
if(in[0] != 1)
goto err;
else
return BLOCKED;
}
}
int buff_iter = 0;
buff[buff_iter++] = 5; // version
buff[buff_iter++] = 1; // connect
buff[buff_iter++] = 0; // reserved
if(!dns_len) {
buff[buff_iter++] = 1; // ip v4
memcpy(buff + buff_iter, &ip, 4); // dest host
buff_iter += 4;
} else {
buff[buff_iter++] = 3; //dns
buff[buff_iter++] = dns_len & 0xFF;
memcpy(buff + buff_iter, dns_name, dns_len);
buff_iter += dns_len;
}
memcpy(buff + buff_iter, &port, 2); // dest port
buff_iter += 2;
if(buff_iter != write_n_bytes(sock, (char *) buff, buff_iter))
goto err;
if(4 != read_n_bytes(sock, (char *) buff, 4))
goto err;
if(buff[0] != 5 || buff[1] != 0)
goto err;
switch (buff[3]) {
case 1:
len = 4;
break;
case 4:
len = 16;
break;
case 3:
len = 0;
if(1 != read_n_bytes(sock, (char *) &len, 1))
goto err;
break;
default:
goto err;
}
if(len + 2 != read_n_bytes(sock, (char *) buff, len + 2))
goto err;
return SUCCESS;
}
break;
}
err:
return SOCKET_ERROR;
}
#define TP " ... "
#define DT "Dynamic chain"
#define ST "Strict chain"
#define RT "Random chain"
static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
struct sockaddr_in addr;
char ip_buf[16];
*fd = socket(PF_INET, SOCK_STREAM, 0);
if(*fd == -1)
goto error;
pc_stringfromipv4(&pd->ip.octet[0], ip_buf);
proxychains_write_log(LOG_PREFIX "%s " TP " %s:%d ",
begin_mark, ip_buf, htons(pd->port));
pd->ps = PLAY_STATE;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = (in_addr_t) pd->ip.as_int;
addr.sin_port = pd->port;
if(timed_connect(*fd, (struct sockaddr *) &addr, sizeof(addr))) {
pd->ps = DOWN_STATE;
goto error1;
}
pd->ps = BUSY_STATE;
return SUCCESS;
error1:
proxychains_write_log(TP " timeout\n");
error:
if(*fd != -1)
close(*fd);
return SOCKET_ERROR;
}
static proxy_data *select_proxy(select_type how, proxy_data * pd, unsigned int proxy_count, unsigned int *offset) {
unsigned int i = 0, k = 0;
if(*offset >= proxy_count)
return NULL;
switch (how) {
case RANDOMLY:
do {
k++;
i = 0 + (unsigned int) (proxy_count * 1.0 * rand() / (RAND_MAX + 1.0));
} while(pd[i].ps != PLAY_STATE && k < proxy_count * 100);
break;
case FIFOLY:
for(i = *offset; i < proxy_count; i++) {
if(pd[i].ps == PLAY_STATE) {
*offset = i;
break;
}
}
default:
break;
}
if(i >= proxy_count)
i = 0;
return (pd[i].ps == PLAY_STATE) ? &pd[i] : NULL;
}
static void release_all(proxy_data * pd, unsigned int proxy_count) {
unsigned int i;
for(i = 0; i < proxy_count; i++)
pd[i].ps = PLAY_STATE;
return;
}
static void release_busy(proxy_data * pd, unsigned int proxy_count) {
unsigned int i;
for(i = 0; i < proxy_count; i++)
if(pd[i].ps == BUSY_STATE)
pd[i].ps = PLAY_STATE;
return;
}
static unsigned int calc_alive(proxy_data * pd, unsigned int proxy_count) {
unsigned int i;
int alive_count = 0;
release_busy(pd, proxy_count);
for(i = 0; i < proxy_count; i++)
if(pd[i].ps == PLAY_STATE)
alive_count++;
return alive_count;
}
static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
int retcode = -1;
char *hostname;
char hostname_buf[MSG_LEN_MAX];
char ip_buf[16];
PFUNC();
if(pto->ip.octet[0] == remote_dns_subnet) {
if(!at_get_host_for_ip(pto->ip, hostname_buf)) goto usenumericip;
else hostname = hostname_buf;
} else {
usenumericip:
pc_stringfromipv4(&pto->ip.octet[0], ip_buf);
hostname = ip_buf;
}
proxychains_write_log(TP " %s:%d ", hostname, htons(pto->port));
retcode = tunnel_to(ns, pto->ip, pto->port, pfrom->pt, pfrom->user, pfrom->pass);
switch (retcode) {
case SUCCESS:
pto->ps = BUSY_STATE;
break;
case BLOCKED:
pto->ps = BLOCKED_STATE;
proxychains_write_log("<--denied\n");
close(ns);
break;
case SOCKET_ERROR:
pto->ps = DOWN_STATE;
proxychains_write_log("<--socket error or timeout!\n");
close(ns);
break;
}
return retcode;
}
int connect_proxy_chain(int sock, ip_type target_ip,
unsigned short target_port, proxy_data * pd,
unsigned int proxy_count, chain_type ct, unsigned int max_chain) {
proxy_data p4;
proxy_data *p1, *p2, *p3;
int ns = -1;
unsigned int offset = 0;
unsigned int alive_count = 0;
unsigned int curr_len = 0;
p3 = &p4;
PFUNC();
again:
switch (ct) {
case DYNAMIC_TYPE:
alive_count = calc_alive(pd, proxy_count);
offset = 0;
do {
if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
goto error_more;
} while(SUCCESS != start_chain(&ns, p1, DT) && offset < proxy_count);
for(;;) {
p2 = select_proxy(FIFOLY, pd, proxy_count, &offset);
if(!p2)
break;
if(SUCCESS != chain_step(ns, p1, p2)) {
PDEBUG("GOTO AGAIN 1\n");
goto again;
}
p1 = p2;
}
//proxychains_write_log(TP);
p3->ip = target_ip;
p3->port = target_port;
if(SUCCESS != chain_step(ns, p1, p3))
goto error;
break;
case STRICT_TYPE:
alive_count = calc_alive(pd, proxy_count);
offset = 0;
if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) {
PDEBUG("select_proxy failed\n");
goto error_strict;
}
if(SUCCESS != start_chain(&ns, p1, ST)) {
PDEBUG("start_chain failed\n");
goto error_strict;
}
while(offset < proxy_count) {
if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
break;
if(SUCCESS != chain_step(ns, p1, p2)) {
PDEBUG("chain_step failed\n");
goto error_strict;
}
p1 = p2;
}
//proxychains_write_log(TP);
p3->ip = target_ip;
p3->port = target_port;
if(SUCCESS != chain_step(ns, p1, p3))
goto error;
break;
case RANDOM_TYPE:
alive_count = calc_alive(pd, proxy_count);
if(alive_count < max_chain)
goto error_more;
curr_len = offset = 0;
do {
if(!(p1 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
goto error_more;
} while(SUCCESS != start_chain(&ns, p1, RT) && offset < max_chain);
while(++curr_len < max_chain) {
if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
goto error_more;
if(SUCCESS != chain_step(ns, p1, p2)) {
PDEBUG("GOTO AGAIN 2\n");
goto again;
}
p1 = p2;
}
//proxychains_write_log(TP);
p3->ip = target_ip;
p3->port = target_port;
if(SUCCESS != chain_step(ns, p1, p3))
goto error;
}
proxychains_write_log(TP " OK\n");
dup2(ns, sock);
close(ns);
return 0;
error:
if(ns != -1)
close(ns);
errno = ECONNREFUSED; // for nmap ;)
return -1;
error_more:
proxychains_write_log("\n!!!need more proxies!!!\n");
error_strict:
PDEBUG("error\n");
release_all(pd, proxy_count);
if(ns != -1)
close(ns);
errno = ETIMEDOUT;
return -1;
}
#include "hostentdb.h"
struct hostent_list hl;
void core_initialize(void) {
hdb_init(&hl);
}
void core_unload(void) {
}
static void gethostbyname_data_setstring(struct gethostbyname_data* data, char* name) {
snprintf(data->addr_name, sizeof(data->addr_name), "%s", name);
data->hostent_space.h_name = data->addr_name;
}
struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) {
PFUNC();
char buff[256];
data->resolved_addr_p[0] = (char *) &data->resolved_addr;
data->resolved_addr_p[1] = NULL;
data->hostent_space.h_addr_list = data->resolved_addr_p;
// let aliases point to the NULL member, mimicking an empty list.
data->hostent_space.h_aliases = &data->resolved_addr_p[1];
data->resolved_addr = 0;
data->hostent_space.h_addrtype = AF_INET;
data->hostent_space.h_length = sizeof(in_addr_t);
gethostname(buff, sizeof(buff));
if(!strcmp(buff, name)) {
data->resolved_addr = inet_addr(buff);
if(data->resolved_addr == (in_addr_t) (-1))
data->resolved_addr = (in_addr_t) (ip_type_localhost.as_int);
goto retname;
}
memset(buff, 0, sizeof(buff));
// this iterates over the "known hosts" db, usually /etc/hosts
ip_type hdb_res = hdb_get(&hl, (char*) name);
if(hdb_res.as_int != ip_type_invalid.as_int) {
data->resolved_addr = hdb_res.as_int;
goto retname;
}
data->resolved_addr = at_get_ip_for_host((char*) name, strlen(name)).as_int;
if(data->resolved_addr == (in_addr_t) ip_type_invalid.as_int) return NULL;
retname:
gethostbyname_data_setstring(data, (char*) name);
PDEBUG("return hostent space\n");
return &data->hostent_space;
}
struct addrinfo_data {
struct addrinfo addrinfo_space;
struct sockaddr sockaddr_space;
char addr_name[256];
};
void proxy_freeaddrinfo(struct addrinfo *res) {
PFUNC();
free(res);
}
#ifdef IS_MAC
/* getservbyname on mac is using thread local storage, so we dont need mutex */
static int getservbyname_r(const char* name, const char* proto, struct servent* result_buf,
char* buf, size_t buflen, struct servent** result) {
PFUNC();
struct servent *res;
int ret;
(void) buf; (void) buflen;
res = getservbyname(name, proto);
if(res) {
*result_buf = *res;
*result = result_buf;
ret = 0;
} else {
*result = NULL;
ret = ENOENT;
}
return ret;
}
#endif
int proxy_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
struct gethostbyname_data ghdata;
struct addrinfo_data *space;
struct servent *se = NULL;
struct hostent *hp = NULL;
struct servent se_buf;
struct addrinfo *p;
char buf[1024];
int port;
PFUNC();
// printf("proxy_getaddrinfo node %s service %s\n",node,service);
space = calloc(1, sizeof(struct addrinfo_data));
if(!space) goto err1;
if(node && !inet_aton(node, &((struct sockaddr_in *) &space->sockaddr_space)->sin_addr)) {
hp = proxy_gethostbyname(node, &ghdata);
if(hp)
memcpy(&((struct sockaddr_in *) &space->sockaddr_space)->sin_addr,
*(hp->h_addr_list), sizeof(in_addr_t));
else
goto err2;
}
if(service) getservbyname_r(service, NULL, &se_buf, buf, sizeof(buf), &se);
port = se ? se->s_port : htons(atoi(service ? service : "0"));
((struct sockaddr_in *) &space->sockaddr_space)->sin_port = port;
*res = p = &space->addrinfo_space;
assert((size_t)p == (size_t) space);
p->ai_addr = &space->sockaddr_space;
if(node)
strncpy(space->addr_name, node, sizeof(space->addr_name));
p->ai_canonname = space->addr_name;
p->ai_next = NULL;
p->ai_family = space->sockaddr_space.sa_family = AF_INET;
p->ai_addrlen = sizeof(space->sockaddr_space);
if(hints) {
p->ai_socktype = hints->ai_socktype;
p->ai_flags = hints->ai_flags;
p->ai_protocol = hints->ai_protocol;
} else {
p->ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
}
goto out;
err2:
free(space);
err1:
return 1;
out:
return 0;
}
+128
View File
@@ -0,0 +1,128 @@
/***************************************************************************
core.h - description
-------------------
begin : Tue May 14 2002
copyright : netcreature (C) 2002
email : netcreature@users.sourceforge.net
***************************************************************************
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include <unistd.h>
#include <stdint.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#ifndef __CORE_HEADER
#define __CORE_HEADER
#define BUFF_SIZE 8*1024 // used to read responses from proxies.
#define MAX_LOCALNET 64
#include "ip_type.h"
/*error codes*/
typedef enum {
SUCCESS=0,
MEMORY_FAIL, // malloc failed
SOCKET_ERROR, // look errno for more
CHAIN_DOWN, // no proxy in chain responds to tcp
CHAIN_EMPTY, // if proxy_count = 0
BLOCKED // target's port blocked on last proxy in the chain
} ERR_CODE;
typedef enum {
HTTP_TYPE,
SOCKS4_TYPE,
SOCKS5_TYPE
} proxy_type;
typedef enum {
DYNAMIC_TYPE,
STRICT_TYPE,
RANDOM_TYPE}
chain_type;
typedef enum {
PLAY_STATE,
DOWN_STATE,
BLOCKED_STATE,
BUSY_STATE
} proxy_state;
typedef enum {
RANDOMLY,
FIFOLY
} select_type;
typedef struct {
struct in_addr in_addr, netmask;
unsigned short port;
} localaddr_arg;
typedef struct {
ip_type ip;
unsigned short port;
proxy_type pt;
proxy_state ps;
char user[256];
char pass[256];
} proxy_data;
int connect_proxy_chain (int sock, ip_type target_ip, unsigned short target_port,
proxy_data * pd, unsigned int proxy_count, chain_type ct,
unsigned int max_chain );
void proxychains_write_log(char *str, ...);
typedef int (*close_t)(int);
typedef int (*connect_t)(int, const struct sockaddr *, socklen_t);
typedef struct hostent* (*gethostbyname_t)(const char *);
typedef int (*freeaddrinfo_t)(struct addrinfo *);
typedef struct hostent *(*gethostbyaddr_t) (const void *, socklen_t, int);
typedef int (*getaddrinfo_t)(const char *, const char *, const struct addrinfo *,
struct addrinfo **);
typedef int (*getnameinfo_t) (const struct sockaddr *, socklen_t, char *,
socklen_t, char *, socklen_t, int);
extern connect_t true_connect;
extern gethostbyname_t true_gethostbyname;
extern getaddrinfo_t true_getaddrinfo;
extern freeaddrinfo_t true_freeaddrinfo;
extern getnameinfo_t true_getnameinfo;
extern gethostbyaddr_t true_gethostbyaddr;
struct gethostbyname_data {
struct hostent hostent_space;
in_addr_t resolved_addr;
char *resolved_addr_p[2];
char addr_name[1024 * 8];
};
struct hostent* proxy_gethostbyname(const char *name, struct gethostbyname_data *data);
int proxy_getaddrinfo(const char *node, const char *service,
const struct addrinfo *hints, struct addrinfo **res);
void proxy_freeaddrinfo(struct addrinfo *res);
void core_initialize(void);
void core_unload(void);
#include "debug.h"
#endif
//RcB: DEP "core.c"
//RcB: DEP "libproxychains.c"
//RcB: LINK "-Wl,--no-as-needed -ldl -lpthread"
+14
View File
@@ -0,0 +1,14 @@
#ifndef DEBUG_H
#define DEBUG_H
#ifdef DEBUG
# include <stdio.h>
# define PDEBUG(fmt, args...) do { dprintf(2,"DEBUG:"fmt, ## args); } while(0)
#else
# define PDEBUG(fmt, args...) do {} while (0)
#endif
# define PFUNC() do { PDEBUG("pid[%d]:%s\n", getpid(), __FUNCTION__); } while(0)
#endif
+12
View File
@@ -0,0 +1,12 @@
#include "hash.h"
/* dalias' version of the elf hash */
uint32_t dalias_hash(char *s0) {
unsigned char *s = (void *) s0;
uint_fast32_t h = 0;
while(*s) {
h = 16 * h + *s++;
h ^= h >> 24 & 0xf0;
}
return h & 0xfffffff;
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef HASH_H
#define HASH_H
#include <stdint.h>
uint32_t dalias_hash(char *s0);
//RcB: DEP "hash.c"
#endif
+63
View File
@@ -0,0 +1,63 @@
#include <stdint.h>
#include <string.h>
#include <netdb.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "ip_type.h"
#include "hash.h"
#include "stringdump.h"
#include "hostentdb.h"
#include "common.h"
#include "debug.h"
#define STEP 16
static void hdb_add(struct hostent_list* hl, char* host, ip_type ip) {
if(hl->count +1 > hl->capa) {
void * nu = realloc(hl->entries, (hl->capa + STEP) * sizeof(struct hostent_entry));
if(!nu) return;
hl->entries = nu;
hl->capa += STEP;
}
struct hostent_entry *h = &hl->entries[hl->count];
h->hash = dalias_hash(host);
h->ip.as_int = ip.as_int;
h->str = dumpstring(host, strlen(host) + 1);
if(h->str) hl->count++;
}
static void hdb_fill(struct hostent_list *hl) {
#ifndef IS_BSD
struct hostent* hp;
while((hp = gethostent()))
if(hp->h_addrtype == AF_INET && hp->h_length == sizeof(in_addr_t)) {
hdb_add(hl, hp->h_name, (ip_type) { .as_int = *((in_addr_t*)(hp->h_addr_list[0])) });
}
#else
/* FreeBSD hangs on gethostent(). since this feature is not crucial, we just do nothing */
(void) hl;
#endif
}
void hdb_init(struct hostent_list *hl) {
memset(hl, 0, sizeof *hl);
hdb_fill(hl);
}
ip_type hdb_get(struct hostent_list *hl, char* host) {
size_t i;
PFUNC();
uint32_t hash = dalias_hash(host);
for(i = 0; i < hl->count; i++) {
if(hl->entries[i].hash == hash && !strcmp(hl->entries[i].str, host)) {
#ifdef DEBUG
char ipbuf[16];
pc_stringfromipv4(hl->entries[i].ip.octet, ipbuf);
PDEBUG("got ip %s for hostent entry %s\n", ipbuf, host);
#endif
return hl->entries[i].ip;
}
}
return ip_type_invalid;
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef HOSTENTDB_H
#define HOSTENTDB_H
#include "ip_type.h"
#include <unistd.h>
struct hostent_entry {
uint32_t hash;
ip_type ip;
char* str;
};
struct hostent_list {
size_t count;
size_t capa;
struct hostent_entry *entries;
};
void hdb_init(struct hostent_list *hl);
ip_type hdb_get(struct hostent_list *hl, char* host);
//RcB: DEP "hostendb.c"
#endif
+5
View File
@@ -0,0 +1,5 @@
#include "ip_type.h"
const ip_type ip_type_invalid = { .as_int = -1 };
const ip_type ip_type_localhost = { {127, 0, 0, 1} };
+15
View File
@@ -0,0 +1,15 @@
#ifndef IP_TYPE_H
#define IP_TYPE_H
#include <stdint.h>
typedef union {
unsigned char octet[4];
uint32_t as_int;
} ip_type;
extern const ip_type ip_type_invalid;
extern const ip_type ip_type_localhost;
//RcB: DEP "ip_type.c"
#endif
+465
View File
@@ -0,0 +1,465 @@
/***************************************************************************
libproxychains.c - description
-------------------
begin : Tue May 14 2002
copyright : netcreature (C) 2002
email : netcreature@users.sourceforge.net
***************************************************************************/
/* GPL */
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <netdb.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <pthread.h>
#include "core.h"
#include "common.h"
#define satosin(x) ((struct sockaddr_in *) &(x))
#define SOCKADDR(x) (satosin(x)->sin_addr.s_addr)
#define SOCKADDR_2(x) (satosin(x)->sin_addr)
#define SOCKPORT(x) (satosin(x)->sin_port)
#define SOCKFAMILY(x) (satosin(x)->sin_family)
#define MAX_CHAIN 512
close_t true_close;
connect_t true_connect;
gethostbyname_t true_gethostbyname;
getaddrinfo_t true_getaddrinfo;
freeaddrinfo_t true_freeaddrinfo;
getnameinfo_t true_getnameinfo;
gethostbyaddr_t true_gethostbyaddr;
int tcp_read_time_out;
int tcp_connect_time_out;
chain_type proxychains_ct;
proxy_data proxychains_pd[MAX_CHAIN];
unsigned int proxychains_proxy_count = 0;
int proxychains_got_chain_data = 0;
unsigned int proxychains_max_chain = 1;
int proxychains_quiet_mode = 0;
int proxychains_resolver = 0;
localaddr_arg localnet_addr[MAX_LOCALNET];
size_t num_localnet_addr = 0;
unsigned int remote_dns_subnet = 224;
pthread_once_t init_once = PTHREAD_ONCE_INIT;
static int init_l = 0;
static inline void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_type * ct);
static void* load_sym(char* symname, void* proxyfunc) {
void *funcptr = dlsym(RTLD_NEXT, symname);
if(!funcptr) {
fprintf(stderr, "Cannot load symbol '%s' %s\n", symname, dlerror());
exit(1);
} else {
PDEBUG("loaded symbol '%s'" " real addr %p wrapped addr %p\n", symname, funcptr, proxyfunc);
}
if(funcptr == proxyfunc) {
PDEBUG("circular reference detected, aborting!\n");
abort();
}
return funcptr;
}
#define INIT() init_lib_wrapper(__FUNCTION__)
#define SETUP_SYM(X) do { true_ ## X = load_sym( # X, X ); } while(0)
#include "shm.h"
#include "allocator_thread.h"
#include "stringdump.h"
static void do_init(void) {
srand(time(NULL));
dumpstring_init(); // global string garbage can
core_initialize();
at_init();
/* read the config file */
get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
proxychains_write_log(LOG_PREFIX "DLL init\n");
SETUP_SYM(connect);
SETUP_SYM(gethostbyname);
SETUP_SYM(getaddrinfo);
SETUP_SYM(freeaddrinfo);
SETUP_SYM(gethostbyaddr);
SETUP_SYM(getnameinfo);
SETUP_SYM(close);
init_l = 1;
}
#if 0
/* FIXME this is currently unused.
* it is not strictly needed.
* maybe let it be called by a gcc destructor, if that doesnt
* have negative consequences (e.g. when a child calles exit) */
static void unload(void) {
at_close();
core_unload();
}
#endif
static void init_lib_wrapper(const char* caller) {
#ifndef DEBUG
(void) caller;
#endif
if(!init_l) PDEBUG("%s called from %s\n", __FUNCTION__, caller);
pthread_once(&init_once, do_init);
}
/* if we use gcc >= 3, we can instruct the dynamic loader
* to call init_lib at link time. otherwise it gets loaded
* lazily, which has the disadvantage that there's a potential
* race condition if 2 threads call it before init_l is set
* and PTHREAD support was disabled */
#if __GNUC__ > 2
__attribute__((constructor))
static void gcc_init(void) {
INIT();
}
#endif
/* get configuration from config file */
static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_type * ct) {
int count = 0, port_n = 0, list = 0;
char buff[1024], type[1024], host[1024], user[1024];
char *env;
char local_in_addr_port[32];
char local_in_addr[32], local_in_port[32], local_netmask[32];
FILE *file = NULL;
if(proxychains_got_chain_data)
return;
//Some defaults
tcp_read_time_out = 4 * 1000;
tcp_connect_time_out = 10 * 1000;
*ct = DYNAMIC_TYPE;
env = get_config_path(getenv(PROXYCHAINS_CONF_FILE_ENV_VAR), buff, sizeof(buff));
if( ( file = fopen(env, "r") ) == NULL )
{
perror("couldnt read configuration file");
exit(1);
}
env = getenv(PROXYCHAINS_QUIET_MODE_ENV_VAR);
if(env && *env == '1')
proxychains_quiet_mode = 1;
while(fgets(buff, sizeof(buff), file)) {
if(buff[0] != '\n' && buff[strspn(buff, " ")] != '#') {
/* proxylist has to come last */
if(list) {
if(count >= MAX_CHAIN)
break;
memset(&pd[count], 0, sizeof(proxy_data));
pd[count].ps = PLAY_STATE;
port_n = 0;
sscanf(buff, "%s %s %d %s %s", type, host, &port_n, pd[count].user, pd[count].pass);
in_addr_t host_ip = inet_addr(host);
if(host_ip == INADDR_NONE) {
fprintf(stderr, "proxy %s has invalid value or is not numeric\n", host);
exit(1);
}
pd[count].ip.as_int = (uint32_t) host_ip;
pd[count].port = htons((unsigned short) port_n);
if(!strcmp(type, "http")) {
pd[count].pt = HTTP_TYPE;
} else if(!strcmp(type, "socks4")) {
pd[count].pt = SOCKS4_TYPE;
} else if(!strcmp(type, "socks5")) {
pd[count].pt = SOCKS5_TYPE;
} else
continue;
if(pd[count].ip.as_int && port_n && pd[count].ip.as_int != (uint32_t) - 1)
count++;
} else {
if(strstr(buff, "[ProxyList]")) {
list = 1;
} else if(strstr(buff, "random_chain")) {
*ct = RANDOM_TYPE;
} else if(strstr(buff, "strict_chain")) {
*ct = STRICT_TYPE;
} else if(strstr(buff, "dynamic_chain")) {
*ct = DYNAMIC_TYPE;
} else if(strstr(buff, "tcp_read_time_out")) {
sscanf(buff, "%s %d", user, &tcp_read_time_out);
} else if(strstr(buff, "tcp_connect_time_out")) {
sscanf(buff, "%s %d", user, &tcp_connect_time_out);
} else if(strstr(buff, "remote_dns_subnet")) {
sscanf(buff, "%s %d", user, &remote_dns_subnet);
if(remote_dns_subnet >= 256) {
fprintf(stderr,
"remote_dns_subnet: invalid value. requires a number between 0 and 255.\n");
exit(1);
}
} else if(strstr(buff, "localnet")) {
if(sscanf(buff, "%s %21[^/]/%15s", user, local_in_addr_port, local_netmask) < 3) {
fprintf(stderr, "localnet format error");
exit(1);
}
/* clean previously used buffer */
memset(local_in_port, 0, sizeof(local_in_port) / sizeof(local_in_port[0]));
if(sscanf(local_in_addr_port, "%15[^:]:%5s", local_in_addr, local_in_port) < 2) {
PDEBUG("added localnet: netaddr=%s, netmask=%s\n",
local_in_addr, local_netmask);
} else {
PDEBUG("added localnet: netaddr=%s, port=%s, netmask=%s\n",
local_in_addr, local_in_port, local_netmask);
}
if(num_localnet_addr < MAX_LOCALNET) {
int error;
error =
inet_pton(AF_INET, local_in_addr,
&localnet_addr[num_localnet_addr].in_addr);
if(error <= 0) {
fprintf(stderr, "localnet address error\n");
exit(1);
}
error =
inet_pton(AF_INET, local_netmask,
&localnet_addr[num_localnet_addr].netmask);
if(error <= 0) {
fprintf(stderr, "localnet netmask error\n");
exit(1);
}
if(local_in_port[0]) {
localnet_addr[num_localnet_addr].port =
(short) atoi(local_in_port);
} else {
localnet_addr[num_localnet_addr].port = 0;
}
++num_localnet_addr;
} else {
fprintf(stderr, "# of localnet exceed %d.\n", MAX_LOCALNET);
}
} else if(strstr(buff, "chain_len")) {
char *pc;
int len;
pc = strchr(buff, '=');
len = atoi(++pc);
proxychains_max_chain = (len ? len : 1);
} else if(strstr(buff, "quiet_mode")) {
proxychains_quiet_mode = 1;
} else if(strstr(buff, "proxy_dns")) {
proxychains_resolver = 1;
}
}
}
}
fclose(file);
*proxy_count = count;
proxychains_got_chain_data = 1;
}
/******* HOOK FUNCTIONS *******/
int close(int fd) {
/* prevent rude programs (like ssh) from closing our pipes */
if(fd != req_pipefd[0] && fd != req_pipefd[1] &&
fd != resp_pipefd[0] && fd != resp_pipefd[1]) {
return true_close(fd);
}
errno = EINTR;
return -1;
}
int connect(int sock, const struct sockaddr *addr, unsigned int len) {
PFUNC();
int socktype = 0, flags = 0, ret = 0;
socklen_t optlen = 0;
ip_type dest_ip;
#ifdef DEBUG
char str[256];
#endif
struct in_addr *p_addr_in;
unsigned short port;
size_t i;
int remote_dns_connect = 0;
INIT();
optlen = sizeof(socktype);
getsockopt(sock, SOL_SOCKET, SO_TYPE, &socktype, &optlen);
if(!(SOCKFAMILY(*addr) == AF_INET && socktype == SOCK_STREAM))
return true_connect(sock, addr, len);
p_addr_in = &((struct sockaddr_in *) addr)->sin_addr;
port = ntohs(((struct sockaddr_in *) addr)->sin_port);
#ifdef DEBUG
// PDEBUG("localnet: %s; ", inet_ntop(AF_INET,&in_addr_localnet, str, sizeof(str)));
// PDEBUG("netmask: %s; " , inet_ntop(AF_INET, &in_addr_netmask, str, sizeof(str)));
PDEBUG("target: %s\n", inet_ntop(AF_INET, p_addr_in, str, sizeof(str)));
PDEBUG("port: %d\n", port);
#endif
// check if connect called from proxydns
remote_dns_connect = (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet);
for(i = 0; i < num_localnet_addr && !remote_dns_connect; i++) {
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)) {
if(!localnet_addr[i].port || localnet_addr[i].port == port) {
PDEBUG("accessing localnet using true_connect\n");
return true_connect(sock, addr, len);
}
}
}
flags = fcntl(sock, F_GETFL, 0);
if(flags & O_NONBLOCK)
fcntl(sock, F_SETFL, !O_NONBLOCK);
dest_ip.as_int = SOCKADDR(*addr);
ret = connect_proxy_chain(sock,
dest_ip,
SOCKPORT(*addr),
proxychains_pd, proxychains_proxy_count, proxychains_ct, proxychains_max_chain);
fcntl(sock, F_SETFL, flags);
if(ret != SUCCESS)
errno = ECONNREFUSED;
return ret;
}
static struct gethostbyname_data ghbndata;
struct hostent *gethostbyname(const char *name) {
INIT();
PDEBUG("gethostbyname: %s\n", name);
if(proxychains_resolver)
return proxy_gethostbyname(name, &ghbndata);
else
return true_gethostbyname(name);
return NULL;
}
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
int ret = 0;
INIT();
PDEBUG("getaddrinfo: %s %s\n", node ? node : "null", service ? service : "null");
if(proxychains_resolver)
ret = proxy_getaddrinfo(node, service, hints, res);
else
ret = true_getaddrinfo(node, service, hints, res);
return ret;
}
void freeaddrinfo(struct addrinfo *res) {
INIT();
PDEBUG("freeaddrinfo %p \n", res);
if(!proxychains_resolver)
true_freeaddrinfo(res);
else
proxy_freeaddrinfo(res);
return;
}
int pc_getnameinfo(const struct sockaddr *sa, socklen_t salen,
char *host, socklen_t hostlen, char *serv,
socklen_t servlen, int flags)
{
char ip_buf[16];
int ret = 0;
INIT();
PFUNC();
if(!proxychains_resolver) {
ret = true_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
} else {
if(salen < sizeof(struct sockaddr_in) || SOCKFAMILY(*sa) != AF_INET)
return EAI_FAMILY;
if(hostlen) {
pc_stringfromipv4((unsigned char*) &(SOCKADDR_2(*sa)), ip_buf);
if(snprintf(host, hostlen, "%s", ip_buf) >= hostlen)
return EAI_OVERFLOW;
}
if(servlen) {
if(snprintf(serv, servlen, "%d", ntohs(SOCKPORT(*sa))) >= servlen)
return EAI_OVERFLOW;
}
}
return ret;
}
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) {
static char buf[16];
static char ipv4[4];
static char *list[2];
static char *aliases[1];
static struct hostent he;
INIT();
PDEBUG("TODO: proper gethostbyaddr hook\n");
if(!proxychains_resolver)
return true_gethostbyaddr(addr, len, type);
else {
PDEBUG("len %u\n", len);
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;
aliases[0] = NULL;
he.h_aliases = aliases;
he.h_length = 4;
pc_stringfromipv4((unsigned char *) addr, buf);
return &he;
}
return NULL;
}
+137
View File
@@ -0,0 +1,137 @@
/* (C) 2011, 2012 rofl0r
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#undef _XOPEN_SOURCE
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "common.h"
static int usage(char **argv) {
printf("\nUsage:\t%s -q -f config_file program_name [arguments]\n"
"\t-q makes proxychains quiet - this overrides the config setting\n"
"\t-f allows to manually specify a configfile to use\n"
"\tfor example : proxychains telnet somehost.com\n" "More help in README file\n\n", argv[0]);
return EXIT_FAILURE;
}
static const char *dll_name = DLL_NAME;
static char own_dir[256];
static const char *dll_dirs[] = {
".",
own_dir,
LIB_DIR,
"/lib",
"/usr/lib",
"/usr/local/lib",
"/lib64",
NULL
};
static void set_own_dir(const char *argv0) {
size_t l = strlen(argv0);
while(l && argv0[l - 1] != '/')
l--;
if(l == 0)
memcpy(own_dir, ".", 2);
else {
memcpy(own_dir, argv0, l - 1);
own_dir[l] = 0;
}
}
#define MAX_COMMANDLINE_FLAGS 2
int main(int argc, char *argv[]) {
char *path = NULL;
char buf[256];
char pbuf[256];
int start_argv = 1;
int quiet = 0;
size_t i;
const char *prefix = NULL;
for(i = 0; i < MAX_COMMANDLINE_FLAGS; i++) {
if(start_argv < argc && argv[start_argv][0] == '-') {
if(argv[start_argv][1] == 'q') {
quiet = 1;
start_argv++;
} else if(argv[start_argv][1] == 'f') {
if(start_argv + 1 < argc)
path = argv[start_argv + 1];
else
return usage(argv);
start_argv += 2;
}
} else
break;
}
if(start_argv >= argc)
return usage(argv);
/* check if path of config file has not been passed via command line */
path = get_config_path(path, pbuf, sizeof(pbuf));
if(!quiet)
fprintf(stderr, LOG_PREFIX "config file found: %s\n", path);
/* Set PROXYCHAINS_CONF_FILE to get proxychains lib to use new config file. */
setenv(PROXYCHAINS_CONF_FILE_ENV_VAR, path, 1);
if(quiet)
setenv(PROXYCHAINS_QUIET_MODE_ENV_VAR, "1", 1);
// search DLL
set_own_dir(argv[0]);
i = 0;
while(dll_dirs[i]) {
snprintf(buf, sizeof(buf), "%s/%s", dll_dirs[i], dll_name);
if(access(buf, R_OK) != -1) {
prefix = dll_dirs[i];
break;
}
i++;
}
if(!prefix) {
fprintf(stderr, "couldnt locate %s\n", dll_name);
return EXIT_FAILURE;
}
if(!quiet)
fprintf(stderr, LOG_PREFIX "preloading %s/%s\n", prefix, dll_name);
#ifndef IS_MAC
snprintf(buf, sizeof(buf), "LD_PRELOAD=%s/%s", prefix, dll_name);
putenv(buf);
#else
snprintf(buf, sizeof(buf), "DYLD_INSERT_LIBRARIES=%s/%s", prefix, dll_name);
putenv(buf);
putenv("DYLD_FORCE_FLAT_NAMESPACE=1");
#endif
execvp(argv[start_argv], &argv[start_argv]);
perror("proxychains can't load process....");
return EXIT_FAILURE;
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef MUTEX_H
#define MUTEX_H
#include <pthread.h>
# define MUTEX_LOCK(x) pthread_mutex_lock(x)
# define MUTEX_UNLOCK(x) pthread_mutex_unlock(x)
# define MUTEX_INIT(x) pthread_mutex_init(x, NULL)
# define MUTEX_DESTROY(x) pthread_mutex_destroy(x)
#endif
+13
View File
@@ -0,0 +1,13 @@
#include <sys/socket.h>
extern int pc_getnameinfo(const void *sa, socklen_t salen,
char *host, socklen_t hostlen, char *serv,
socklen_t servlen, int flags);
int getnameinfo(const void *sa, socklen_t salen,
char *host, socklen_t hostlen, char *serv,
socklen_t servlen, int flags) {
return pc_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
}
+102
View File
@@ -0,0 +1,102 @@
# proxychains.conf VER 4.x
#
# HTTP, SOCKS4a, SOCKS5 tunneling proxifier with DNS.
# The option below identifies how the ProxyList is treated.
# only one option should be uncommented at time,
# otherwise the last appearing option will be accepted
#
#dynamic_chain
#
# Dynamic - Each connection will be done via chained proxies
# all proxies chained in the order as they appear in the list
# at least one proxy must be online to play in chain
# (dead proxies are skipped)
# otherwise EINTR is returned to the app
#
strict_chain
#
# Strict - Each connection will be done via chained proxies
# all proxies chained in the order as they appear in the list
# all proxies must be online to play in chain
# otherwise EINTR is returned to the app
#
#random_chain
#
# Random - Each connection will be done via random proxy
# (or proxy chain, see chain_len) from the list.
# this option is good to test your IDS :)
# Make sense only if random_chain
#chain_len = 2
# Quiet mode (no output from library)
#quiet_mode
# Proxy DNS requests - no leak for DNS data
proxy_dns
# set the class A subnet number to use for the internal remote DNS mapping
# we use the reserved 224.x.x.x range by default,
# if the proxified app does a DNS request, we will return an IP from that range.
# on further accesses to this ip we will send the saved DNS name to the proxy.
# in case some control-freak app checks the returned ip, and denies to
# connect, you can use another subnet, e.g. 10.x.x.x or 127.x.x.x.
# of course you should make sure that the proxified app does not need
# *real* access to this subnet.
# i.e. dont use the same subnet then in the localnet section
#remote_dns_subnet 127
#remote_dns_subnet 10
remote_dns_subnet 224
# Some timeouts in milliseconds
tcp_read_time_out 15000
tcp_connect_time_out 8000
### Examples for localnet exclusion
## localnet ranges will *not* use a proxy to connect.
## Exclude connections to 192.168.1.0/24 with port 80
# localnet 192.168.1.0:80/255.255.255.0
## Exclude connections to 192.168.100.0/24
# localnet 192.168.100.0/255.255.255.0
## Exclude connections to ANYwhere with port 80
# localnet 0.0.0.0:80/0.0.0.0
## RFC5735 Loopback address range
## if you enable this, you have to make sure remote_dns_subnet is not 127
## you'll need to enable it if you want to use an application that
## connects to localhost.
# localnet 127.0.0.0/255.0.0.0
## RFC1918 Private Address Ranges
# localnet 10.0.0.0/255.0.0.0
# localnet 172.16.0.0/255.240.0.0
# localnet 192.168.0.0/255.255.0.0
# ProxyList format
# type ip port [user pass]
# (values separated by 'tab' or 'blank')
#
# only numeric ipv4 addresses are valid
#
#
# Examples:
#
# socks5 192.168.67.78 1080 lamer secret
# http 192.168.89.3 8080 justu hidden
# socks4 192.168.1.49 1080
# http 192.168.39.93 8080
#
#
# proxy types: http, socks4, socks5
# ( auth types supported: "basic"-http "user/pass"-socks )
#
[ProxyList]
# add proxy here ...
# meanwile
# defaults set to "tor"
socks4 127.0.0.1 9050
+18
View File
@@ -0,0 +1,18 @@
#!/bin/sh
# This is a legacy script that uses "dig" to do DNS lookups via TCP.
# it is not actively maintained since proxychains no longer depends
# on it. i leave it here as a bonus.
# DNS server used to resolve names
DNS_SERVER=8.8.8.8
if [ $# = 0 ] ; then
echo " usage:"
echo " proxyresolv <hostname> "
exit
fi
export LD_PRELOAD=libproxychains4.so
dig $1 @$DNS_SERVER +tcp | awk '/A.?[0-9]+\.[0-9]+\.[0-9]/{print $5;}'
+53
View File
@@ -0,0 +1,53 @@
#include <assert.h>
#include <string.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096
#endif
#include "shm.h"
#include "debug.h"
#if 0
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/shm.h>
/* allocates shared memory which can be accessed from the parent and its childs */
void *shm_realloc(void* old, size_t old_size, size_t new_size) {
//PFUNC();
void *nu = mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if(old) {
if(!nu) return NULL;
assert(new_size >= old_size);
memcpy(nu, old, old_size);
munmap(old, old_size);
}
return nu;
}
#endif
void stringpool_init(struct stringpool* sp) {
PFUNC();
memset(sp, 0, sizeof *sp);
}
char* stringpool_add(struct stringpool *sp, char* s, size_t len) {
//PFUNC();
if(len > sp->alloced - sp->used) {
size_t newsz = sp->used + len;
size_t inc = PAGE_SIZE - (newsz % PAGE_SIZE);
newsz += (inc == PAGE_SIZE) ? 0 : inc;
void* p = realloc(sp->start, newsz);
if(p) {
sp->start = p;
sp->alloced = newsz;
} else
return 0;
}
char* ret = sp->start + sp->used;
memcpy(ret, s, len);
sp->used += len;
return ret;
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef SHM_H
#define SHM_H
#include <unistd.h>
struct stringpool {
size_t alloced;
size_t used;
char* start;
};
void stringpool_init(struct stringpool* sp);
char* stringpool_add(struct stringpool *sp, char* s, size_t len);
#if 0
void *shm_realloc(void* old, size_t old_size, size_t new_size);
#endif
//RcB: DEP "shm.c"
#endif
+13
View File
@@ -0,0 +1,13 @@
#include "stringdump.h"
#include "debug.h"
struct stringpool mem;
char *dumpstring(char* s, size_t len) {
PFUNC();
return stringpool_add(&mem, s, len);
}
void dumpstring_init(void) {
stringpool_init(&mem);
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef STRINGDUMP_H
#define STRINGDUMP_H
#include "shm.h"
#include <unistd.h>
char *dumpstring(char* s, size_t len);
void dumpstring_init(void);
//RcB: DEP "stringdump.h"
#endif
-1
View File
@@ -1 +0,0 @@
timestamp
+41
View File
@@ -0,0 +1,41 @@
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif
int main(void) {
struct addrinfo *result;
struct addrinfo *res;
int error;
/* resolve the domain name into a list of addresses */
error = getaddrinfo("www.example.com", NULL, NULL, &result);
if (error != 0)
{
fprintf(stderr, "error in getaddrinfo: %s\n", gai_strerror(error));
return EXIT_FAILURE;
}
/* loop over all returned results and do inverse lookup */
for (res = result; res != NULL; res = res->ai_next)
{
char hostname[NI_MAXHOST] = "";
error = getnameinfo(res->ai_addr, res->ai_addrlen, hostname, NI_MAXHOST, NULL, 0, 0);
if (error != 0)
{
fprintf(stderr, "error in getnameinfo: %s\n", gai_strerror(error));
continue;
}
if (*hostname != '\0')
printf("hostname: %s\n", hostname);
}
freeaddrinfo(result);
return EXIT_SUCCESS;
}
+24
View File
@@ -0,0 +1,24 @@
#include <netdb.h>
#include <stdio.h>
#include "../src/common.h"
void printhostent(struct hostent *hp) {
char ipbuf[16];
pc_stringfromipv4(hp->h_addr_list[0], ipbuf);
printf("alias: %p, len: %d, name: %s, addrlist: %p, addrtype: %d, ip: %s\n",
hp->h_aliases,
hp->h_length,
hp->h_name,
hp->h_addr_list,
hp->h_addrtype,
ipbuf
);
}
int main(int argc, char** argv) {
struct hostent *hp;
while((hp = gethostent())) {
printhostent(hp);
}
return 0;
}
+61
View File
@@ -0,0 +1,61 @@
#include <netdb.h>
#include <stdio.h>
#include <errno.h>
#include "../src/common.h"
/*
int gethostent_r(
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop);
Glibc2 also has reentrant versions gethostent_r(), gethostbyaddr_r(),
gethostbyname_r() and gethostbyname2_r().
The caller supplies a hostent structure ret which will be filled in on success,
and a temporary work buffer buf of size buflen.
After the call, result will point to the result on success.
In case of an error or if no entry is found result will be NULL.
The functions return 0 on success and a nonzero error number on failure.
In addition to the errors returned by the nonreentrant versions of these functions,
if buf is too small, the functions will return ERANGE, and the call should be retried
with a larger buffer.
The global variable h_errno is not modified, but the address of a variable in which
to store error numbers is passed in h_errnop.
*/
void printhostent(struct hostent *hp) {
char ipbuf[16];
pc_stringfromipv4(hp->h_addr_list[0], ipbuf);
printf("alias: %p, len: %d, name: %s, addrlist: %p, addrtype: %d, ip: %s\n",
hp->h_aliases,
hp->h_length,
hp->h_name,
hp->h_addr_list,
hp->h_addrtype,
ipbuf
);
}
int main(int argc, char** argv) {
struct hostent he_buf;
struct hostent *he_res;
char h_buf[1024];
int ch_errno;
int ret;
do {
ret = gethostent_r(&he_buf, h_buf, sizeof(h_buf), &he_res, &ch_errno);
printf("ret: %d, h_errno: %d\n", ret, ch_errno);
if(ret != 0) {
errno = ret;
ret = -1;
}
if(ret == -1) {
perror("gethostent_r");
break;
}
if(he_res) {
printhostent(he_res);
}
} while (he_res);
return 0;
}
+83
View File
@@ -0,0 +1,83 @@
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define satosin(x) ((struct sockaddr_in *) &(x))
#define SOCKADDR(x) (satosin(x)->sin_addr.s_addr)
#define SOCKADDR_2(x) (satosin(x)->sin_addr)
#define SOCKPORT(x) (satosin(x)->sin_port)
#define SOCKFAMILY(x) (satosin(x)->sin_family)
int main() {
struct sockaddr a = {0}, *sa = &a;
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
SOCKPORT(a) = htons(80);
memcpy( &( (struct sockaddr_in*) sa ) ->sin_addr , (char[]) {127,0,0,1}, 4);
int ret;
if ((ret = getnameinfo(sa, 0, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == EAI_FAMILY);
if ((ret = getnameinfo(sa, sizeof a, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == EAI_FAMILY);
SOCKFAMILY(a) = AF_INET;
if ((ret = getnameinfo(sa, sizeof a, hbuf, 1, sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == EAI_OVERFLOW);
if ((ret = getnameinfo(sa, sizeof a, hbuf, 0, sbuf,
1, NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == EAI_OVERFLOW);
if ((ret = getnameinfo(sa, sizeof a, hbuf, 0, sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == 0);
if ((ret = getnameinfo(sa, sizeof a, hbuf, sizeof hbuf, sbuf,
0, NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == 0);
if ((ret = getnameinfo(sa, sizeof a, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == 0);
return 0;
}
+24
View File
@@ -0,0 +1,24 @@
#include "../src/core.h"
#include "../src/common.h"
#include <stdio.h>
void printhostent(struct hostent *hp) {
char ipbuf[16];
pc_stringfromipv4(hp->h_addr_list[0], ipbuf);
printf("alias: %p, len: %d, name: %s, addrlist: %p, addrtype: %d, ip: %s\n",
hp->h_aliases,
hp->h_length,
hp->h_name,
hp->h_addr_list,
hp->h_addrtype,
ipbuf
);
}
int main(int argc, char**argv) {
struct hostent* ret;
struct gethostbyname_data data;
if(argc == 1) return 1;
ret = proxy_gethostbyname(argv[1], &data);
if(ret) printhostent(ret);
return 0;
}
+39
View File
@@ -0,0 +1,39 @@
#include "../src/shm.h"
#include <assert.h>
#define s(A) (sizeof(A) - 1)
#define ss(A) (A), s(A)
int main() {
char buf4096[4096];
struct stringpool sp;
stringpool_init(&sp);
char *r;
size_t pos = 0;
r = stringpool_add(&sp, ss("AAAAA"));
assert(r == sp.start);
pos += s("AAAAA");
assert(sp.alloced == 4096);
assert(sp.used == pos);
r = stringpool_add(&sp, buf4096, sizeof(buf4096));
assert(r == sp.start + pos);
pos += sizeof(buf4096);
assert(sp.alloced == 4096 * 2);
assert(sp.used == pos);
r = stringpool_add(&sp, buf4096, 4096 - s("AAAAA"));
assert(r == sp.start + pos);
pos += 4096 - s("AAAAA");
assert(pos == 4096 * 2);
assert(sp.alloced == 4096 * 2);
assert(sp.used == pos);
return 0;
}