Copy to master from devel - ready for 0.8

This commit is contained in:
z3APA3A 2016-01-13 00:20:50 +03:00
parent db169c48c3
commit 5287278fa5
74 changed files with 5163 additions and 4637 deletions

1
.gitignore vendored
View File

@ -25,6 +25,7 @@ doc/html/index.html
verfile.sh verfile.sh
Makefile Makefile
Changelog Changelog
res
copytgz.sh copytgz.sh
*~.nib *~.nib
local.properties local.properties

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -3,8 +3,8 @@
LANGUAGE 0x09, 0x01 LANGUAGE 0x09, 0x01
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 0,7,0,0 FILEVERSION 0,8,0,0
PRODUCTVERSION 0,7,0,0 PRODUCTVERSION 0,8,0,0
FILETYPE 0x1L FILETYPE 0x1L
FILESUBTYPE 0x0L FILESUBTYPE 0x0L
BEGIN BEGIN

View File

@ -1,4 +1,3 @@
#$Id: Makefile.Linux,v 1.24 2014-04-07 20:34:57 vlad Exp $
# #
# 3 proxy Makefile for GCC/Linux/Cygwin # 3 proxy Makefile for GCC/Linux/Cygwin
# #
@ -11,17 +10,15 @@
BUILDDIR = BUILDDIR =
CC = gcc CC = gcc
CFLAGS = -Wall -g -O2 -c -pthread -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL CFLAGS = -g -O2 -c -pthread -DGETHOSTBYNAME_R -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL
COUT = -o COUT = -o
LN = gcc LN = gcc
DCFLAGS = -fpic DCFLAGS = -fpic
LDFLAGS = -Wall -O2 -pthread LDFLAGS = -O2 -pthread
DLFLAGS = -shared DLFLAGS = -shared
DLSUFFICS = .ld.so DLSUFFICS = .ld.so
# -lpthreads may be reuqired on some platforms instead of -pthreads # -lpthreads may be reuqired on some platforms instead of -pthreads
#LIBS = -lcrypto -lssl -ldl LIBS = -lcrypto -lssl -ldl
# libcrypto and libssl are required for SSLPlugin
LIBS = -ldl
LNOUT = -o LNOUT = -o
EXESUFFICS = EXESUFFICS =
OBJSUFFICS = .o OBJSUFFICS = .o
@ -31,9 +28,7 @@ REMOVECOMMAND = rm -f
TYPECOMMAND = cat TYPECOMMAND = cat
COMPATLIBS = COMPATLIBS =
MAKEFILE = Makefile.Linux MAKEFILE = Makefile.Linux
#PLUGINS = SSLPlugin StringsPlugin TrafficPlugin PCREPlugin TransparentPlugin PLUGINS = SSLPlugin StringsPlugin TrafficPlugin PCREPlugin TransparentPlugin
# SSLPlugin is not built by default because of external dependencies
PLUGINS = StringsPlugin TrafficPlugin PCREPlugin TransparentPlugin
include Makefile.inc include Makefile.inc
@ -49,7 +44,6 @@ INSTALL = /usr/bin/install
INSTALL_BIN = $(INSTALL) -m 755 INSTALL_BIN = $(INSTALL) -m 755
INSTALL_DATA = $(INSTALL) -m 644 INSTALL_DATA = $(INSTALL) -m 644
INSTALL_OBJS = src/3proxy \ INSTALL_OBJS = src/3proxy \
src/countersutil \
src/dighosts \ src/dighosts \
src/ftppr \ src/ftppr \
src/mycrypt \ src/mycrypt \

View File

@ -1,4 +1,3 @@
#$Id: Makefile.Solaris,v 1.18 2008/09/30 13:58:44 vlad Exp $
# #
# 3 proxy Makefile for Solaris/SunCC # 3 proxy Makefile for Solaris/SunCC
# #

View File

@ -1,4 +1,3 @@
#$Id: Makefile.Solaris-gcc,v 1.14 2008/09/30 13:58:44 vlad Exp $
# #
# 3 proxy Makefile for Solaris/gcc # 3 proxy Makefile for Solaris/gcc
# #

View File

@ -1,4 +1,3 @@
#$Id: Makefile.ccc,v 1.12 2007/04/10 16:29:25 vlad Exp $
# #
# 3 proxy Makefile for Compaq C Compiler # 3 proxy Makefile for Compaq C Compiler
# #
@ -10,10 +9,10 @@
BUILDDIR = BUILDDIR =
CC = ccc CC = ccc
CFLAGS = -Wall -O2 -c -pthread -D_THREAD_SAFE -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -WITH_POLL CFLAGS = -O2 -c -pthread -D_THREAD_SAFE -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -WITH_POLL
COUT = -o COUT = -o
LN = ccc LN = ccc
LDFLAGS = -Wall -O2 -pthread LDFLAGS = -O2 -pthread
DCFLAGS = -fpic DCFLAGS = -fpic
DLFLAGS = -shared DLFLAGS = -shared
DLSUFFICS = .ld.so DLSUFFICS = .ld.so

View File

@ -1,4 +1,3 @@
#$Id: Makefile.debug,v 1.7 2007/04/18 05:33:19 vlad Exp $
# #
# 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake) # 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake)
# #

View File

@ -1,4 +1,3 @@
#$Id: Makefile.inc,v 1.3 2007/01/23 16:00:26 vlad Exp $
# #
# 3 proxy common Makefile # 3 proxy common Makefile
# #

View File

@ -1,4 +1,3 @@
#$Id: Makefile.intl,v 1.8 2007/07/21 18:47:00 vlad Exp $
# #
# 3 proxy Makefile for Intel C compiler for Windows (for both make and nmake) # 3 proxy Makefile for Intel C compiler for Windows (for both make and nmake)
# #

View File

@ -1,4 +1,3 @@
#$Id: Makefile.msvc,v 1.17 2010-11-11 14:44:11 v.dubrovin Exp $
# #
# 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake) # 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake)
# #
@ -15,7 +14,7 @@ LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no /machine:I386 LDFLAGS = /nologo /subsystem:console /incremental:no /machine:I386
DLFLAGS = /DLL DLFLAGS = /DLL
DLSUFFICS = .dll DLSUFFICS = .dll
LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib kernel32.lib Gdi32.lib LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib kernel32.lib Gdi32.lib libeay32MT.lib ssleay32MT.lib
LIBSOLD = libeay32MT.lib ssleay32MT.lib LIBSOLD = libeay32MT.lib ssleay32MT.lib
LIBEXT = .lib LIBEXT = .lib
LNOUT = /out: LNOUT = /out:
@ -27,8 +26,8 @@ REMOVECOMMAND = del 2>NUL >NUL
TYPECOMMAND = type TYPECOMMAND = type
COMPATLIBS = COMPATLIBS =
MAKEFILE = Makefile.msvc MAKEFILE = Makefile.msvc
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin lastFripper FilePlugin PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin FilePlugin SSLPlugin
VERFILE = 3proxyres.obj $(VERFILE) VERFILE = $(VERFILE)
include Makefile.inc include Makefile.inc
@ -36,7 +35,7 @@ include Makefile.inc
rc /fo../3proxy.res ../3proxy.rc rc /fo../3proxy.res ../3proxy.rc
3proxyres.obj: ../3proxy.res 3proxyres.obj: ../3proxy.res
cvtres /out:3proxyres.obj /MACHINE:X86 ../3proxy.res cvtres /out:3proxyres.obj /MACHINE:I386 ../3proxy.res
allplugins: allplugins:
for /D %%i in ($(PLUGINS)) do (copy Makefile plugins\%%i && copy Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.obj *.idb &&cd ..\..) for /D %%i in ($(PLUGINS)) do (copy Makefile plugins\%%i && copy Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.obj *.idb &&cd ..\..)

View File

@ -1,4 +1,3 @@
#$Id: Makefile.msvc64,v 1.14 2007/07/21 18:47:05 vlad Exp $
# #
# 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake) # 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake)
# #
@ -15,7 +14,7 @@ LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no /machine:x64 LDFLAGS = /nologo /subsystem:console /incremental:no /machine:x64
DLFLAGS = /DLL DLFLAGS = /DLL
DLSUFFICS = .dll DLSUFFICS = .dll
LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib kernel32.lib Gdi32.lib LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib kernel32.lib Gdi32.lib libeay32MT.lib ssleay32MT.lib
LIBSOLD = libeay32MT.lib ssleay32MT.lib LIBSOLD = libeay32MT.lib ssleay32MT.lib
LIBEXT = .lib LIBEXT = .lib
LNOUT = /out: LNOUT = /out:
@ -27,8 +26,14 @@ REMOVECOMMAND = del 2>NUL >NUL
TYPECOMMAND = type TYPECOMMAND = type
COMPATLIBS = COMPATLIBS =
MAKEFILE = Makefile.msvc64 MAKEFILE = Makefile.msvc64
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin FilePlugin SSLPlugin
VERFILE = 3proxyres.obj $(VERFILE) VERFILE = $(VERFILE)
#../3proxy.res:
# rc /fo../3proxy.res ../3proxy.rc
#3proxyres.obj: ../3proxy.res
# cvtres /out:3proxyres.obj /MACHINE:X64 ../3proxy.res
include Makefile.inc include Makefile.inc
@ -36,7 +41,8 @@ include Makefile.inc
rc /fo../3proxy.res ../3proxy.rc rc /fo../3proxy.res ../3proxy.rc
3proxyres.obj: ../3proxy.res 3proxyres.obj: ../3proxy.res
cvtres /out:3proxyres.obj /MACHINE:X64 ../3proxy.res cvtres /out:3proxyres.obj /machine:x64 ../3proxy.res
allplugins: allplugins:
for /D %%i in ($(PLUGINS)) do (copy Makefile plugins\%%i && copy Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.obj *.idb &&cd ..\..) for /D %%i in ($(PLUGINS)) do (copy Makefile plugins\%%i && copy Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.obj *.idb &&cd ..\..)

View File

@ -1,4 +1,3 @@
#$Id: Makefile.msvc,v 1.14 2007/07/21 18:47:02 vlad Exp $
# #
# 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake) # 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake)
# #

View File

@ -1,4 +1,3 @@
#$Id: Makefile.unix,v 1.20 2007/04/10 16:29:25 vlad Exp $
# #
# 3 proxy Makefile for GCC/Unix # 3 proxy Makefile for GCC/Unix
# #
@ -12,10 +11,10 @@ BUILDDIR =
CC = gcc CC = gcc
# you may need -L/usr/pkg/lib for older NetBSD versions # you may need -L/usr/pkg/lib for older NetBSD versions
CFLAGS = -Wall -g -O2 -c -pthread -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL CFLAGS = -g -O2 -c -pthread -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL
COUT = -o COUT = -o
LN = gcc LN = gcc
LDFLAGS = -Wall -O2 -pthread LDFLAGS = -O2 -pthread
# -lpthreads may be reuqired on some platforms instead of -pthreads # -lpthreads may be reuqired on some platforms instead of -pthreads
# -ldl or -lld may be required for some platforms # -ldl or -lld may be required for some platforms
DCFLAGS = -fpic DCFLAGS = -fpic

View File

@ -7,7 +7,6 @@ INSTALL = /usr/bin/install
INSTALL_BIN = $(INSTALL) -m 755 INSTALL_BIN = $(INSTALL) -m 755
INSTALL_DATA = $(INSTALL) -m 644 INSTALL_DATA = $(INSTALL) -m 644
INSTALL_OBJS = src/3proxy \ INSTALL_OBJS = src/3proxy \
src/countersutil \
src/dighosts \ src/dighosts \
src/ftppr \ src/ftppr \
src/mycrypt \ src/mycrypt \

View File

@ -1,4 +1,3 @@
#$Id: Makefile.win,v 1.9 2007/08/20 15:26:27 vlad Exp $
# #
# 3 proxy Makefile for GCC/windows # 3 proxy Makefile for GCC/windows
# #
@ -11,7 +10,7 @@
BUILDDIR = ../bin/ BUILDDIR = ../bin/
CC = gcc CC = gcc
CFLAGS = -O2 -s -c -mthreads -DWITH_STD_MALLOC CFLAGS = -O2 -s -c -mthreads -DWITH_STD_MALLOC -DNOIPV6
COUT = -o COUT = -o
LN = gcc LN = gcc
LDFLAGS = -O2 -s -mthreads LDFLAGS = -O2 -s -mthreads

View File

@ -1,4 +1,3 @@
#$Id: Makefile.win,v 1.9 2007/08/20 15:26:27 vlad Exp $
# #
# 3 proxy Makefile for GCC/windows # 3 proxy Makefile for GCC/windows
# #
@ -11,10 +10,10 @@
BUILDDIR = ../bin/ BUILDDIR = ../bin/
CC = /opt/cegcc/arm-wince-cegcc/bin/gcc CC = /opt/cegcc/arm-wince-cegcc/bin/gcc
CFLAGS = -Wall -O2 -s -c -mthreads -DWITH_STD_MALLOC -DNOODBC -D_WINCE -D_WIN32 -D__USE_W32_SOCKETS CFLAGS = -O2 -s -c -mthreads -DWITH_STD_MALLOC -DNOODBC -D_WINCE -D_WIN32 -D__USE_W32_SOCKETS
COUT = -o COUT = -o
LN = /opt/cegcc/arm-wince-cegcc/bin/gcc LN = /opt/cegcc/arm-wince-cegcc/bin/gcc
LDFLAGS = -Wall -O2 -s -mthreads LDFLAGS = -O2 -s -mthreads
DLFLAGS = -shared DLFLAGS = -shared
DLSUFFICS = .dll DLSUFFICS = .dll
LIBS = -lws2 LIBS = -lws2

6
README
View File

@ -1,6 +1,6 @@
/* /*
3APA3A 3proxy tiny proxy server 3APA3A 3proxy tiny proxy server
(c) 2002-2014 by Vladimir '3APA3A' Dubrovin <3proxy@3proxy.ru> (c) 2002-2016 by Vladimir '3APA3A' Dubrovin <3proxy@3proxy.ru>
please read License Agreement please read License Agreement
*/ */
@ -39,7 +39,6 @@ smtpp SMTP proxy server, binds to port 25. You must specify
icqpr ICQ/AIM proxy. Maps some TCP port to TCP port of ICQ icqpr ICQ/AIM proxy. Maps some TCP port to TCP port of ICQ
server and performs packets translation. Example: server and performs packets translation. Example:
icqpr 5190 login.icq.com 5190 icqpr 5190 login.icq.com 5190
msnpr MSN proxy (beta)
tcppm TCP port mapping. Maps some TCP port on local machine to tcppm TCP port mapping. Maps some TCP port on local machine to
TCP port on remote host. TCP port on remote host.
udppm UDP port mapping. Maps some UDP port on local machine to udppm UDP port mapping. Maps some UDP port on local machine to
@ -56,9 +55,10 @@ mycrypt Program to obtain crypted password fro cleartext. Supports
mycrypt salt password mycrypt salt password
produces MD5/crypt password with salt "salt". produces MD5/crypt password with salt "salt".
dighosts Utility for building networks list from web page. dighosts Utility for building networks list from web page.
countersutil Utility to manage counters file
Run utility with --help option for command line reference. Run utility with --help option for command line reference.
Latest version is available from http://3proxy.ru/ Latest version is available from http://3proxy.ru/
Want to donate the project? http://3proxy.ru/donations/

View File

@ -104,4 +104,3 @@
- Addon antiviral, HTTP cache filters modules, authentication - Addon antiviral, HTTP cache filters modules, authentication
modules for different protocols (RADIUS, PAM etc). modules for different protocols (RADIUS, PAM etc).
$Id: Release.notes,v 1.9 2014-04-07 21:24:42 vlad Exp $

View File

@ -15,4 +15,3 @@ on the provider's Web server.
Provider has proxy server 10.1.2.5. Traffic from proxy server is not free, but Provider has proxy server 10.1.2.5. Traffic from proxy server is not free, but
is cheaper than traffic from non-free networks. is cheaper than traffic from non-free networks.
$Id: 0.scenario.txt,v 1.2 2004/07/23 13:33:39 vlad Exp $

View File

@ -199,4 +199,3 @@ admin
# now we needn't any root rights. We can chroot and setgid/setuid. # now we needn't any root rights. We can chroot and setgid/setuid.
###$Id: 3proxy.cfg.sample,v 1.7 2006/11/18 14:37:06 vlad Exp $#######

View File

@ -50,4 +50,3 @@ internal 127.0.0.1
allow user1 allow user1
admin admin
#$Id: counters.sample,v 1.2 2004/07/23 13:33:39 vlad Exp $

View File

@ -59,4 +59,3 @@ terms of compatible license, including:
http://www.gnu.org/licenses/lgpl.txt http://www.gnu.org/licenses/lgpl.txt
$Id: License,v 1.3 2007/04/05 11:59:47 vlad Exp $

View File

@ -153,6 +153,3 @@ A: First, I'm not programmer. Second, 3proxy was 'proof of concept' in reply for
<p><i>Q: Why do you use insecure strcpy, sprintf, etc?</i></p> <p><i>Q: Why do you use insecure strcpy, sprintf, etc?</i></p>
A: Why not? I try to use insecure function in secure manner. You're welcome to look for vulnerabilities. A: Why not? I try to use insecure function in secure manner. You're welcome to look for vulnerabilities.
<pre>
$Id: faqe.html,v 1.10 2007/07/31 08:42:38 vlad Exp $
</pre>

View File

@ -278,6 +278,3 @@
пугать. пугать.
</p> </p>
</ul> </ul>
<pre>
$Id: faqr.html,v 1.28 2007/09/25 09:47:13 vlad Exp $
</pre>

View File

@ -832,4 +832,3 @@ You can control 3proxy service via "Services" administration ot via "net" comman
</ul> </ul>
<pre>$Id: howtoe.html,v 1.41 2009/02/02 10:04:49 vlad Exp $</pre>

View File

@ -1026,6 +1026,3 @@
Только не пытайтесь задавать какие-либо вопросы, если вы просто не поняли этот Только не пытайтесь задавать какие-либо вопросы, если вы просто не поняли этот
HowTo. HowTo.
</ul> </ul>
<pre>
$Id: howtor.html,v 1.40 2010/01/21 13:34:20 v.dubrovin Exp $
</pre>

View File

@ -1,10 +1,10 @@
<h3>3proxy security considirations</h3> <h3>3proxy security considirations</h3>
</ul> </ul>
<ol> <ul>
<li>Never install 3proxy suid. If you need it to run suid write some <li>Never install 3proxy suid. If you need it to run suid write some
wrapper with fixed configuration file. wrapper with fixed configuration file.
<li>Make configuration file only available to account 3proxy starts with. <li>Make configuration file only available to account 3proxy starts with.
<li>Under Windows NT/2000/XP/2003 if 3proxy is used as service create new <li>Under Windows if 3proxy is used as service create new
unprivileged local account without "logon locally" right. Assign this account unprivileged local account without "logon locally" right. Assign this account
to 3proxy service. to 3proxy service.
<li>Under unix use chroot to jail 3proxy (make sure files included in <li>Under unix use chroot to jail 3proxy (make sure files included in
@ -20,9 +20,8 @@ authentication method is currently available.
<li>Always limit connections to internal network and localhost (to 127.0.0.1 and <li>Always limit connections to internal network and localhost (to 127.0.0.1 and
all interfaces) with ACLs. Be carefull, because BIND command in SOCKS requies all interfaces) with ACLs. Be carefull, because BIND command in SOCKS requies
BIND method with external interface IP address to be allowed. BIND method with external interface IP address to be allowed.
<li> Always use nserver and nscache under Unix, overwise DoS attack is possible <li> Before 3proxy 0.8 always use nserver and nscache under Unix, overwise DoS attack is possible
with unreachable DNS server (because gethostbyname will block over threads). with unreachable DNS server (because gethostbyname will block over threads).
<li>Remember, that 'nbname' authentication is not reliable and can be spoofed.
<li>Keep logs in secure location, because some confidential information from <li>Keep logs in secure location, because some confidential information from
user's request can be logged. user's request can be logged.
<li>Use -xyz+A character filtering sequences for 'logformat', especially with <li>Use -xyz+A character filtering sequences for 'logformat', especially with
@ -31,7 +30,6 @@ ODBC logging to prevent SQL and log record injections.
<li>Participate in code audit :) <li>Participate in code audit :)
</ol> </ol>
</ol> </ul>
<p> <p>
<pre>$Id: securityen.html,v 1.4 2007/05/07 09:16:51 vlad Exp $</pre>

File diff suppressed because one or more lines are too long

View File

@ -96,4 +96,3 @@ setuid 65534
đĎÓĚĹ ÔĎÇĎ ËÁË ÍŮ ÓĎÚÄÁĚÉ ËĎÎĆÉÇŐŇÁĂÉĎÎÎŮĘ ĆÁĘĚ ÓĹŇ×ĹŇÁ, ÚÁĐŐÓËÁĹÍ 3proxy ËĎÍÁÎÄĎĘ: đĎÓĚĹ ÔĎÇĎ ËÁË ÍŮ ÓĎÚÄÁĚÉ ËĎÎĆÉÇŐŇÁĂÉĎÎÎŮĘ ĆÁĘĚ ÓĹŇ×ĹŇÁ, ÚÁĐŐÓËÁĹÍ 3proxy ËĎÍÁÎÄĎĘ:
/usr/local/3proxy/3proxy /usr/local/3proxy/3proxy.cfg /usr/local/3proxy/3proxy /usr/local/3proxy/3proxy.cfg
$Id: example1.txt,v 1.7 2007/04/20 19:58:42 vlad Exp $

View File

@ -98,4 +98,3 @@ LIBS = -L /usr/local/lib -lodbc
make clean make clean
make -f Makefile.unix make -f Makefile.unix
$Id: iodbc.txt,v 1.3 2006/02/08 17:59:07 vlad Exp $

View File

@ -103,15 +103,29 @@ change default server port to NUMBER
.B -n .B -n
disable NTLM authentication (required if passwords are stored in Unix crypt format. disable NTLM authentication (required if passwords are stored in Unix crypt format.
.br .br
.B -n1
enable NTLMv1 authentication.
.br
.B -s .B -s
(for admin) - allow only secure operations (currently only traffic counters (for admin) - secure, allow only secure operations (currently only traffic counters
view without ability to reset). view without ability to reset).
.br .br
(for dnspr) - simple, do not use 'resolver' and 3proxy cache, always use external DNS server.
.br
(for udppm) - singlepacket, expect only one packet from both client and server
.B -a .B -a
(for proxy) - anonymous proxy (no information about client reported) (for proxy) - anonymous proxy (no information about client reported)
.br .br
.B -a1 .B -a1
(for proxy) - anonymous proxy (random client information reported) (for proxy) - anonymous proxy (random client information reported)
.B -6
Only resolve IPv6 addresses
.B -4
Only resolve IPv4 addresses
.B -46
Resolve IPv6 addresses if IPv4 address is not resolvable
.B -64
Resolve IPv4 addresses if IPv6 address is not resolvable
.br .br
Also, all options mentioned for Also, all options mentioned for
.BR proxy (8) .BR proxy (8)
@ -130,7 +144,9 @@ pop3username@pop3server. If POP3 proxy access must be authenticated, you can
specify username as proxy_username:proxy_password:POP3_username@pop3server specify username as proxy_username:proxy_password:POP3_username@pop3server
.br .br
DNS proxy resolves any types of records but only hostnames are cached. It DNS proxy resolves any types of records but only hostnames are cached. It
requires nserver/nscache to be configured. requires nserver/nscache to be configured. If nserver is configured as TCP,
redirections are applied on connection, so parent proxy may be used to resolve
names to IP.
.br .br
FTP proxy can be used as FTP server in any FTP client or configured as FTP FTP proxy can be used as FTP server in any FTP client or configured as FTP
proxy on a client with FTP proxy support. Username format is one of proxy on a client with FTP proxy support. Username format is one of
@ -328,20 +344,25 @@ Sets timeout values
.br .br
.B nserver .B nserver
<ipaddr> <ipaddr>[:port][/tcp]
.br .br
Nameserver to use for name resolutions. If none spcified system Nameserver to use for name resolutions. If none specified
or name server fails system routines for name resolution will be or name server fails system routines for name resolution will be
used. It's better to specify nserver because gethostbyname() may used. It's better to specify nserver because gethostbyname() may
be thread unsafe. be thread unsafe. Optional port number may be specified.
If optional /tcp is added to IP address, name resolution will be
performed over TCP.
.br .br
.B nscache .B nscache
<cachesize> <cachesize>
.B nscache6
<cachesize>
.br .br
Cache <cachesize> records for name resolution. Cachesize usually Cache <cachesize> records for name resolution (nscache for IPv4,
should be large enougth (for example 65536). nscache6 for IPv6). Cachesize usually should be large enougth
(for example 65536).
.br .br
.B nsrecord .B nsrecord
@ -375,7 +396,7 @@ http://dial.right.now/ from browser to set up connection.
.br .br
sets ip address of internal interface. This IP address will be used sets ip address of internal interface. This IP address will be used
to bind gateways. Alternatively you can use -i option for individual to bind gateways. Alternatively you can use -i option for individual
gateways gateways. Since 0.8 version, IPv6 address may be used.
.br .br
.B external .B external
@ -383,7 +404,8 @@ gateways
.br .br
sets ip address of external interface. This IP address will be source sets ip address of external interface. This IP address will be source
address for all connections made by proxy. Alternatively you can use address for all connections made by proxy. Alternatively you can use
-e option to specify individual address for gateway. -e option to specify individual address for gateway. Since 0.8 version
External or -e can be given twice: once with IPv4 and once with IPv6 address.
.br .br
.B maxconn .B maxconn
@ -486,8 +508,9 @@ Use auth type 'cache' for cached authentication
Access control entries. All lists are comma-separated, no spaces are Access control entries. All lists are comma-separated, no spaces are
allowed. Usernames are case sensitive (if used with authtype nbname allowed. Usernames are case sensitive (if used with authtype nbname
username must be in uppercase). Source and target lists may contain username must be in uppercase). Source and target lists may contain
IP addresses (W.X.Y.Z) or CIDRs (W.X.Y.Z/L). Since 0.6, targetlist may also IP addresses (W.X.Y.Z), ranges A.B.C.D - W.X.Y.Z (since 0.8) or CIDRs
contain host names, instead of addresses. It's possible to use wildmask in (W.X.Y.Z/L). Since 0.6, targetlist may also contain host names,
instead of addresses. It's possible to use wildmask in
the begginning and in the the end of hostname, e.g. *badsite.com or the begginning and in the the end of hostname, e.g. *badsite.com or
*badcontent*. Hostname is only checked if hostname presents in request. *badcontent*. Hostname is only checked if hostname presents in request.
Targetportlist may contain ports (X) or port ranges lists (X-Y). For any field Targetportlist may contain ports (X) or port ranges lists (X-Y). For any field

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,8 @@
#$Id: Makefile.inc,v 1.19 2008/12/10 13:12:10 vlad Exp $
# #
# 3 proxy common Makefile # 3 proxy common Makefile
# #
all: pre $(VERFILE) $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)mycrypt$(EXESUFFICS) $(BUILDDIR)dighosts$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)icqpr$(EXESUFFICS) $(BUILDDIR)msnpr$(EXESUFFICS) $(BUILDDIR)udppm$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) $(BUILDDIR)countersutil$(EXESUFFICS) allplugins all: pre $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)mycrypt$(EXESUFFICS) $(BUILDDIR)dighosts$(EXESUFFICS) $(BUILDDIR)pop3p$(EXESUFFICS) $(BUILDDIR)smtpp$(EXESUFFICS) $(BUILDDIR)ftppr$(EXESUFFICS) $(BUILDDIR)tcppm$(EXESUFFICS) $(BUILDDIR)icqpr$(EXESUFFICS) $(BUILDDIR)udppm$(EXESUFFICS) $(BUILDDIR)socks$(EXESUFFICS) $(BUILDDIR)proxy$(EXESUFFICS) allplugins
pre: pre:
@ -53,9 +52,6 @@ tcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h proxymain.c
icqpr$(OBJSUFFICS): icqpr.c proxy.h structures.h proxymain.c icqpr$(OBJSUFFICS): icqpr.c proxy.h structures.h proxymain.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP icqpr.c $(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP icqpr.c
msnpr$(OBJSUFFICS): msnpr.c proxy.h structures.h proxymain.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP msnpr.c
socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP socks.c $(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP socks.c
@ -86,9 +82,6 @@ $(BUILDDIR)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcp
$(BUILDDIR)icqpr$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) icqpr$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(BUILDDIR)icqpr$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) icqpr$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)icqpr$(EXESUFFICS) $(LDFLAGS) $(VERFILE) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) icqpr$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS) $(LN) $(LNOUT)$(BUILDDIR)icqpr$(EXESUFFICS) $(LDFLAGS) $(VERFILE) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) icqpr$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)msnpr$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) msnpr$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)msnpr$(EXESUFFICS) $(LDFLAGS) $(VERFILE) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) msnpr$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(BUILDDIR)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)udppm$(EXESUFFICS) $(LDFLAGS) $(VERFILE) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS) $(LN) $(LNOUT)$(BUILDDIR)udppm$(EXESUFFICS) $(LDFLAGS) $(VERFILE) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
@ -115,9 +108,6 @@ srvtcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h
srvicqpr$(OBJSUFFICS): icqpr.c proxy.h structures.h srvicqpr$(OBJSUFFICS): icqpr.c proxy.h structures.h
$(CC) $(COUT)srvicqpr$(OBJSUFFICS) $(CFLAGS) icqpr.c $(CC) $(COUT)srvicqpr$(OBJSUFFICS) $(CFLAGS) icqpr.c
srvmsnpr$(OBJSUFFICS): msnpr.c proxy.h structures.h
$(CC) $(COUT)srvmsnpr$(OBJSUFFICS) $(CFLAGS) msnpr.c
srvsocks$(OBJSUFFICS): socks.c proxy.h structures.h srvsocks$(OBJSUFFICS): socks.c proxy.h structures.h
$(CC) $(COUT)srvsocks$(OBJSUFFICS) $(CFLAGS) socks.c $(CC) $(COUT)srvsocks$(OBJSUFFICS) $(CFLAGS) socks.c
@ -133,6 +123,9 @@ srvdnspr$(OBJSUFFICS): dnspr.c proxy.h structures.h
auth$(OBJSUFFICS): auth.c proxy.h structures.h auth$(OBJSUFFICS): auth.c proxy.h structures.h
$(CC) $(COUT)auth$(OBJSUFFICS) $(CFLAGS) auth.c $(CC) $(COUT)auth$(OBJSUFFICS) $(CFLAGS) auth.c
conf$(OBJSUFFICS): conf.c proxy.h structures.h
$(CC) $(COUT)conf$(OBJSUFFICS) $(CFLAGS) conf.c
datatypes$(OBJSUFFICS): datatypes.c proxy.h structures.h datatypes$(OBJSUFFICS): datatypes.c proxy.h structures.h
$(CC) $(COUT)datatypes$(OBJSUFFICS) $(CFLAGS) datatypes.c $(CC) $(COUT)datatypes$(OBJSUFFICS) $(CFLAGS) datatypes.c
@ -145,13 +138,6 @@ dighosts$(OBJSUFFICS): dighosts.c
$(BUILDDIR)dighosts$(EXESUFFICS): dighosts$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(BUILDDIR)dighosts$(EXESUFFICS): dighosts$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)dighosts$(EXESUFFICS) $(LDFLAGS) $(VERFILE) dighosts$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS) $(LN) $(LNOUT)$(BUILDDIR)dighosts$(EXESUFFICS) $(LDFLAGS) $(VERFILE) dighosts$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
countersutil$(OBJSUFFICS): countersutil.c
$(CC) $(COUT)countersutil$(OBJSUFFICS) $(CFLAGS) countersutil.c
$(BUILDDIR)countersutil$(EXESUFFICS): countersutil$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)countersutil$(EXESUFFICS) $(LDFLAGS) $(VERFILE) countersutil$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
mycryptmain$(OBJSUFFICS): mycrypt.c mycryptmain$(OBJSUFFICS): mycrypt.c
$(CC) $(COUT)mycryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN mycrypt.c $(CC) $(COUT)mycryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN mycrypt.c
@ -174,8 +160,8 @@ ntlm$(OBJSUFFICS): ntlm.c
stringtable$(OBJSUFFICS): stringtable.c stringtable$(OBJSUFFICS): stringtable.c
$(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c $(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c
$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvicqpr$(OBJSUFFICS) srvmsnpr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycrypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) smbdes$(OBJSUFFICS) ntlm$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvicqpr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycrypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) smbdes$(OBJSUFFICS) ntlm$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvicqpr$(OBJSUFFICS) srvmsnpr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) mycrypt$(OBJSUFFICS) md5$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) smbdes$(OBJSUFFICS) ntlm$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS) $(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvicqpr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) mycrypt$(OBJSUFFICS) md5$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) smbdes$(OBJSUFFICS) ntlm$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
clean: clean:
@$(REMOVECOMMAND) *$(OBJSUFFICS) $(COMPFILES) @$(REMOVECOMMAND) *$(OBJSUFFICS) $(COMPFILES)

View File

@ -4,83 +4,28 @@
please read License Agreement please read License Agreement
$Id: auth.c,v 1.108 2012-04-11 23:01:18 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
#define HEADERSIZE 57
#define RECORDSIZE 18
unsigned char request[] = { int clientnegotiate(struct chain * redir, struct clientparam * param, struct sockaddr * addr){
0xa2, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, unsigned char *buf;
0x00, 0x00, 0x00, 0x00, 0x20, 0x43, 0x4b, 0x41, unsigned char *username;
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x21,
0x00, 0x01};
unsigned char * getNetBIOSnamebyip(unsigned long ip){
unsigned char buf[1024];
struct sockaddr_in sins;
int res;
SOCKET sock;
unsigned char * username = NULL;
int i;
int j;
int nnames;
int type;
if ( (sock=so._socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP)) == INVALID_SOCKET) return NULL;
memset(&sins, 0, sizeof(sins));
sins.sin_family = AF_INET;
sins.sin_port = htons(0);
sins.sin_addr.s_addr = INADDR_ANY;
if(so._bind(sock,(struct sockaddr *)&sins,sizeof(sins))) {
so._closesocket(sock);
return NULL;
}
sins.sin_family = AF_INET;
sins.sin_addr.s_addr = ip;
sins.sin_port = htons(137);
res=socksendto(sock, &sins, request, sizeof(request), conf.timeouts[SINGLEBYTE_L]*1000);
if(res <= 0) {
so._closesocket(sock);
return NULL;
}
res = sockrecvfrom(sock, &sins, buf, sizeof(buf), conf.timeouts[SINGLEBYTE_L]*1000);
so._closesocket(sock);
if(res < (HEADERSIZE + RECORDSIZE)) {
return NULL;
}
nnames = buf[HEADERSIZE-1];
if (res < (HEADERSIZE + (nnames * RECORDSIZE))) return NULL;
for (i = 0; i < nnames; i++){
type = buf[HEADERSIZE + (i*RECORDSIZE) + 15];
if( type == 3) {
for(j = 14; j && buf[HEADERSIZE + (i*RECORDSIZE) + j] == ' '; j--)
buf[HEADERSIZE + (i*RECORDSIZE) + j] = 0;
if(username)myfree(username);
username = (unsigned char *)mystrdup((char *)buf + HEADERSIZE + i*RECORDSIZE);
}
buf[HEADERSIZE + (i*RECORDSIZE) + 15] = 0;
}
return username;
}
int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned long ip, unsigned short port){
unsigned char buf[1024];
struct in_addr ina;
int res; int res;
int len=0; int len=0;
unsigned char * user, *pass; unsigned char * user, *pass;
ina.s_addr = ip;
user = redir->extuser; user = redir->extuser;
pass = redir->extpass; pass = redir->extpass;
if (param->srvinbuf < 4096){
if(param->srvbuf)myfree(param->srvbuf);
param->srvbuf = myalloc(4096);
param->srvbufsize = 4096;
}
buf = param->srvbuf;
username = buf + 2048;
if(user) { if(user) {
if (*user == '*') { if (*user == '*') {
if(!param->username) return 4; if(!param->username) return 4;
@ -95,17 +40,22 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
case R_CONNECT: case R_CONNECT:
case R_CONNECTP: case R_CONNECTP:
{ {
sprintf((char *)buf, "CONNECT "); len = sprintf((char *)buf, "CONNECT ");
if(redir->type == R_CONNECTP && param->hostname) { if(redir->type == R_CONNECTP && param->hostname) {
len = 8 + sprintf((char *)buf + 8, "%.256s", param->hostname); char * needreplace;
needreplace = strchr(param->hostname, ':');
if(needreplace) buf[len++] = '[';
len =+ sprintf((char *)buf + len, "%.256s", param->hostname);
if(needreplace) buf[len++] = ']';
} }
else { else {
len = 8 + myinet_ntoa(ina, (char *)buf+8); if(*SAFAMILY(addr) == AF_INET6) buf[len++] = '[';
len += myinet_ntop(*SAFAMILY(addr), SAADDR(addr), (char *)buf+len, 256);
if(*SAFAMILY(addr) == AF_INET6) buf[len++] = ']';
} }
len += sprintf((char *)buf + len, len += sprintf((char *)buf + len,
":%hu HTTP/1.0\r\nProxy-Connection: keep-alive\r\n", ntohs(port)); ":%hu HTTP/1.0\r\nProxy-Connection: keep-alive\r\n", ntohs(*SAPORT(addr)));
if(user){ if(user){
unsigned char username[256];
len += sprintf((char *)buf + len, "Proxy-authorization: basic "); len += sprintf((char *)buf + len, "Proxy-authorization: basic ");
sprintf((char *)username, "%.128s:%.64s", user, pass?pass:(unsigned char *)""); sprintf((char *)username, "%.128s:%.64s", user, pass?pass:(unsigned char *)"");
en64(username, buf+len, (int)strlen((char *)username)); en64(username, buf+len, (int)strlen((char *)username));
@ -115,7 +65,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
len += sprintf((char *)buf + len, "\r\n"); len += sprintf((char *)buf + len, "\r\n");
if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != (int)strlen((char *)buf)) if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != (int)strlen((char *)buf))
return 31; return 31;
param->statssrv+=len; param->statssrv64+=len;
param->nwrites++; param->nwrites++;
if((res = sockgetlinebuf(param, SERVER,buf,13,'\n',conf.timeouts[CHAIN_TO])) < 13) if((res = sockgetlinebuf(param, SERVER,buf,13,'\n',conf.timeouts[CHAIN_TO])) < 13)
return 32; return 32;
@ -129,14 +79,15 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
case R_SOCKS4B: case R_SOCKS4B:
{ {
if(*SAFAMILY(addr) != AF_INET) return 44;
buf[0] = 4; buf[0] = 4;
buf[1] = 1; buf[1] = 1;
memcpy(buf+2, &port, 2); memcpy(buf+2, SAPORT(addr), 2);
if(redir->type == R_SOCKS4P && param->hostname) { if(redir->type == R_SOCKS4P && param->hostname) {
buf[4] = buf[5] = buf[6] = 0; buf[4] = buf[5] = buf[6] = 0;
buf[7] = 3; buf[7] = 3;
} }
else memcpy(buf+4, &ip, 4); else memcpy(buf+4, SAADDR(addr), 4);
if(!user)user = (unsigned char *)"anonymous"; if(!user)user = (unsigned char *)"anonymous";
len = (int)strlen((char *)user) + 1; len = (int)strlen((char *)user) + 1;
memcpy(buf+8, user, len); memcpy(buf+8, user, len);
@ -152,7 +103,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) < len){ if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) < len){
return 41; return 41;
} }
param->statssrv+=len; param->statssrv64+=len;
param->nwrites++; param->nwrites++;
if((len = sockgetlinebuf(param, SERVER, buf, (redir->type == R_SOCKS4B)? 3:8, EOF, conf.timeouts[CHAIN_TO])) != ((redir->type == R_SOCKS4B)? 3:8)){ if((len = sockgetlinebuf(param, SERVER, buf, (redir->type == R_SOCKS4B)? 3:8, EOF, conf.timeouts[CHAIN_TO])) != ((redir->type == R_SOCKS4B)? 3:8)){
return 42; return 42;
@ -175,7 +126,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
if(socksend(param->remsock, buf, 3, conf.timeouts[CHAIN_TO]) != 3){ if(socksend(param->remsock, buf, 3, conf.timeouts[CHAIN_TO]) != 3){
return 51; return 51;
} }
param->statssrv+=len; param->statssrv64+=len;
param->nwrites++; param->nwrites++;
if(sockgetlinebuf(param, SERVER, buf, 2, EOF, conf.timeouts[CHAIN_TO]) != 2){ if(sockgetlinebuf(param, SERVER, buf, 2, EOF, conf.timeouts[CHAIN_TO]) != 2){
return 52; return 52;
@ -197,7 +148,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
if(socksend(param->remsock, buf, inbuf, conf.timeouts[CHAIN_TO]) != inbuf){ if(socksend(param->remsock, buf, inbuf, conf.timeouts[CHAIN_TO]) != inbuf){
return 51; return 51;
} }
param->statssrv+=inbuf; param->statssrv64+=inbuf;
param->nwrites++; param->nwrites++;
if(sockgetlinebuf(param, SERVER, buf, 2, EOF, 60) != 2){ if(sockgetlinebuf(param, SERVER, buf, 2, EOF, 60) != 2){
return 55; return 55;
@ -218,16 +169,17 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, unsigned l
len += 5; len += 5;
} }
else { else {
buf[3] = 1; len = 3;
memcpy(buf+4, &ip, 4); buf[len++] = (*SAFAMILY(addr) == AF_INET)? 1 : 4;
len = 8; memcpy(buf+len, SAADDR(addr), SAADDRLEN(addr));
len += SAADDRLEN(addr);
} }
memcpy(buf+len, &port, 2); memcpy(buf+len, SAPORT(addr), 2);
len += 2; len += 2;
if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != len){ if(socksend(param->remsock, buf, len, conf.timeouts[CHAIN_TO]) != len){
return 51; return 51;
} }
param->statssrv+=len; param->statssrv64+=len;
param->nwrites++; param->nwrites++;
if(sockgetlinebuf(param, SERVER, buf, 4, EOF, conf.timeouts[CHAIN_TO]) != 4){ if(sockgetlinebuf(param, SERVER, buf, 4, EOF, conf.timeouts[CHAIN_TO]) != 4){
return 57; return 57;
@ -261,16 +213,14 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
int done = 0; int done = 0;
struct chain * cur; struct chain * cur;
struct chain * redir = NULL; struct chain * redir = NULL;
unsigned long targetip;
unsigned short targetport;
int r2; int r2;
if(param->remsock != INVALID_SOCKET) { if(param->remsock != INVALID_SOCKET) {
return 0; return 0;
} }
targetip = param->req.sin_addr.s_addr; if(SAISNULL(&param->req) || !*SAPORT(&param->req)) {
targetport = param->req.sin_port; return 100;
if(!targetip || !targetport) return 100; }
r2 = (myrand(param, sizeof(struct clientparam))%1000); r2 = (myrand(param, sizeof(struct clientparam))%1000);
@ -291,7 +241,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
r2 = (myrand(param, sizeof(struct clientparam))%1000); r2 = (myrand(param, sizeof(struct clientparam))%1000);
} }
if(!connected){ if(!connected){
if(!cur->redirip && !cur->redirport){ if(SAISNULL(&cur->addr) && !*SAPORT(&cur->addr)){
if(cur->extuser){ if(cur->extuser){
if(param->extusername) if(param->extusername)
myfree(param->extusername); myfree(param->extusername);
@ -316,19 +266,25 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
case R_ICQ: case R_ICQ:
param->redirectfunc = icqprchild; param->redirectfunc = icqprchild;
break; break;
/*
case R_MSN: case R_MSN:
param->redirectfunc = msnprchild; param->redirectfunc = msnprchild;
break; break;
*/
default: default:
param->redirectfunc = proxychild; param->redirectfunc = proxychild;
} }
if(cur->next)continue;
return 0; return 0;
} }
else if(!cur->redirip && cur->redirport) param->extport = cur->redirport; else if(!*SAPORT(&cur->addr) && !SAISNULL(&cur->addr)) {
else if(!cur->redirport && cur->redirip) param->extip = cur->redirip; unsigned short port = *SAPORT(&param->sinsr);
memcpy(&param->sinsr, &cur->addr, SASIZE(&cur->addr));
*SAPORT(&param->sinsr) = port;
}
else if(SAISNULL(&cur->addr) && *SAPORT(&cur->addr)) *SAPORT(&param->sinsr) = *SAPORT(&cur->addr);
else { else {
param->sins.sin_port = cur->redirport; memcpy(&param->sinsr, &cur->addr, SASIZE(&cur->addr));
param->sins.sin_addr.s_addr = cur->redirip;
} }
if((res = alwaysauth(param))){ if((res = alwaysauth(param))){
@ -336,7 +292,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
} }
} }
else { else {
res = redir?clientnegotiate(redir, param, cur->redirip, cur->redirport):0; res = (redir)?clientnegotiate(redir, param, (struct sockaddr *)&cur->addr):0;
if(res) return res; if(res) return res;
} }
redir = cur; redir = cur;
@ -359,9 +315,25 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
} }
if(!connected) return 9; if(!connected) return 9;
return redir?clientnegotiate(redir, param, targetip, targetport):0; return (redir)?clientnegotiate(redir, param, (struct sockaddr *)&param->req):0;
} }
int IPInentry(struct sockaddr *sa, struct iplist *ipentry){
int addrlen;
unsigned char *ip, *ipf, *ipt;
ip = (unsigned char *)SAADDR(sa);
ipf = (unsigned char *)&ipentry->ip_from;
ipt = (unsigned char *)&ipentry->ip_to;
if(!sa || ! ipentry || *SAFAMILY(sa) != ipentry->family) return 0;
addrlen = SAADDRLEN(sa);
if(memcmp(ip,ipf,addrlen) < 0 || memcmp(ip,ipt,addrlen) > 0) return 0;
return 1;
}
int ACLmatches(struct ace* acentry, struct clientparam * param){ int ACLmatches(struct ace* acentry, struct clientparam * param){
struct userlist * userentry; struct userlist * userentry;
@ -376,14 +348,14 @@ int ACLmatches(struct ace* acentry, struct clientparam * param){
username = param->username?param->username:(unsigned char *)"-"; username = param->username?param->username:(unsigned char *)"-";
if(acentry->src) { if(acentry->src) {
for(ipentry = acentry->src; ipentry; ipentry = ipentry->next) for(ipentry = acentry->src; ipentry; ipentry = ipentry->next)
if(ipentry->ip == (param->sinc.sin_addr.s_addr & ipentry->mask)) { if(IPInentry((struct sockaddr *)&param->sincr, ipentry)) {
break; break;
} }
if(!ipentry) return 0; if(!ipentry) return 0;
} }
if((acentry->dst && param->req.sin_addr.s_addr) || (acentry->dstnames && param->hostname)) { if((acentry->dst && SAISNULL(&param->req)) || (acentry->dstnames && param->hostname)) {
for(ipentry = acentry->dst; ipentry; ipentry = ipentry->next) for(ipentry = acentry->dst; ipentry; ipentry = ipentry->next)
if(ipentry->ip == (param->req.sin_addr.s_addr & ipentry->mask)) { if(IPInentry((struct sockaddr *)&param->req, ipentry)) {
break; break;
} }
if(!ipentry) { if(!ipentry) {
@ -416,10 +388,10 @@ int ACLmatches(struct ace* acentry, struct clientparam * param){
} }
if(!ipentry && !hstentry) return 0; if(!ipentry && !hstentry) return 0;
} }
if(acentry->ports && param->req.sin_port) { if(acentry->ports && *SAPORT(&param->req)) {
for (portentry = acentry->ports; portentry; portentry = portentry->next) for (portentry = acentry->ports; portentry; portentry = portentry->next)
if(ntohs(param->req.sin_port) >= portentry->startport && if(ntohs(*SAPORT(&param->req)) >= portentry->startport &&
ntohs(param->req.sin_port) <= portentry->endport) { ntohs(*SAPORT(&param->req)) <= portentry->endport) {
break; break;
} }
if(!portentry) return 0; if(!portentry) return 0;
@ -496,6 +468,7 @@ unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nb
sec = tv.tv_sec; sec = tv.tv_sec;
msec = tv.tv_usec; msec = tv.tv_usec;
#endif #endif
if(!nbytesin && !nbytesout) return 0; if(!nbytesin && !nbytesout) return 0;
pthread_mutex_lock(&bandlim_mutex); pthread_mutex_lock(&bandlim_mutex);
if(param->srv->version != conf.paused){ if(param->srv->version != conf.paused){
@ -541,7 +514,6 @@ unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nb
void trafcountfunc(struct clientparam *param){ void trafcountfunc(struct clientparam *param){
struct trafcount * tc; struct trafcount * tc;
unsigned long val;
int countout = 0; int countout = 0;
pthread_mutex_lock(&tc_mutex); pthread_mutex_lock(&tc_mutex);
@ -553,9 +525,7 @@ void trafcountfunc(struct clientparam *param){
countout = 1; countout = 1;
continue; continue;
} }
val = tc->traf + param->statssrv; tc->traf64 += param->statssrv64;
if(val < tc->traf) tc->trafgb++;
tc->traf = val;
time(&t); time(&t);
tc->updated = t; tc->updated = t;
} }
@ -567,9 +537,7 @@ void trafcountfunc(struct clientparam *param){
if(tc->ace->action != COUNTOUT) { if(tc->ace->action != COUNTOUT) {
continue; continue;
} }
val = tc->traf + param->statscli; tc->traf64 += param->statscli64;
if(val < tc->traf) tc->trafgb++;
tc->traf = val;
time(&t); time(&t);
tc->updated = t; tc->updated = t;
} }
@ -596,15 +564,9 @@ int alwaysauth(struct clientparam * param){
continue; continue;
} }
if((tc->traflimgb < tc->trafgb) || if(tc->traflim64 <= tc->traf64) return 10;
((tc->traflimgb == tc->trafgb) && (tc->traflim < tc->traf))
) return 10;
param->trafcountfunc = conf.trafcountfunc; param->trafcountfunc = conf.trafcountfunc;
if(tc->traflimgb - tc->trafgb < 1 || ((tc->traflimgb - tc->trafgb) == 1 && tc->traf > tc->traflim)){ param->maxtrafin64 = tc->traflim64 - tc->traf64;
unsigned maxtraf = tc->traflim - tc->traf;
if(!param->maxtrafin || param->maxtrafin > maxtraf) param->maxtrafin = maxtraf;
}
if((tc->trafgb > tc->traflimgb) || (tc->trafgb == tc->traflimgb && tc->traf >= tc->traflim)) param->maxtrafin = 1;
} }
} }
if(countout)for(tc = conf.trafcounter; tc; tc = tc->next) { if(countout)for(tc = conf.trafcounter; tc; tc = tc->next) {
@ -615,15 +577,9 @@ int alwaysauth(struct clientparam * param){
continue; continue;
} }
if((tc->traflimgb < tc->trafgb) || if(tc->traflim64 <= tc->traf64) return 10;
((tc->traflimgb == tc->trafgb) && (tc->traflim < tc->traf))
) return 10;
param->trafcountfunc = conf.trafcountfunc; param->trafcountfunc = conf.trafcountfunc;
if(tc->traflimgb - tc->trafgb < 1 || ((tc->traflimgb - tc->trafgb) == 1 && tc->traf > tc->traflim)){ param->maxtrafout64 = tc->traflim64 - tc->traf64;
unsigned maxtraf = tc->traflim - tc->traf;
if(!param->maxtrafout || param->maxtrafout > maxtraf) param->maxtrafout = maxtraf;
}
if((tc->trafgb > tc->traflimgb) || (tc->trafgb == tc->traflimgb && tc->traf >= tc->traflim)) param->maxtrafout = 1;
} }
} }
@ -647,7 +603,7 @@ int checkACL(struct clientparam * param){
if(param->operation < 256 && !(param->operation & CONNECT)){ if(param->operation < 256 && !(param->operation & CONNECT)){
continue; continue;
} }
if(param->redirected && acentry->chains && !acentry->chains->redirip && !acentry->chains->redirport) { if(param->redirected && acentry->chains && SAISNULL(&acentry->chains->addr) && !*SAPORT(&acentry->chains->addr)) {
continue; continue;
} }
memcpy(&dup, acentry, sizeof(struct ace)); memcpy(&dup, acentry, sizeof(struct ace));
@ -663,7 +619,11 @@ struct authcache {
char * username; char * username;
char * password; char * password;
time_t expires; time_t expires;
unsigned long ip; #ifndef NOIPV6
struct sockaddr_in6 sa;
#else
struct sockaddr_in sa;
#endif
struct authcache *next; struct authcache *next;
} *authc = NULL; } *authc = NULL;
@ -690,7 +650,7 @@ int cacheauth(struct clientparam * param){
} }
if(((!(conf.authcachetype&2)) || (param->username && ac->username && !strcmp(ac->username, param->username))) && if(((!(conf.authcachetype&2)) || (param->username && ac->username && !strcmp(ac->username, param->username))) &&
((!(conf.authcachetype&1)) || ac->ip == param->sinc.sin_addr.s_addr) && ((!(conf.authcachetype&1)) || (*SAFAMILY(&ac->sa) == *SAFAMILY(&param->sincr) && !memcmp(SAADDR(&ac->sa), &param->sincr, SAADDRLEN(&ac->sa)))) &&
(!(conf.authcachetype&4) || (ac->password && param->password && !strcmp(ac->password, param->password)))) { (!(conf.authcachetype&4) || (ac->password && param->password && !strcmp(ac->password, param->password)))) {
if(param->username){ if(param->username){
myfree(param->username); myfree(param->username);
@ -724,7 +684,7 @@ int doauth(struct clientparam * param){
pthread_mutex_lock(&hash_mutex); pthread_mutex_lock(&hash_mutex);
for(ac = authc; ac; ac = ac->next){ for(ac = authc; ac; ac = ac->next){
if((!(conf.authcachetype&2) || !strcmp(ac->username, param->username)) && if((!(conf.authcachetype&2) || !strcmp(ac->username, param->username)) &&
(!(conf.authcachetype&1) || ac->ip == param->sinc.sin_addr.s_addr) && (!(conf.authcachetype&1) || (*SAFAMILY(&ac->sa) == *SAFAMILY(&param->sincr) && !memcmp(SAADDR(&ac->sa), &param->sincr, SAADDRLEN(&ac->sa)))) &&
(!(conf.authcachetype&4) || (ac->password && !strcmp(ac->password, param->password)))) { (!(conf.authcachetype&4) || (ac->password && !strcmp(ac->password, param->password)))) {
ac->expires = conf.time + conf.authcachetime; ac->expires = conf.time + conf.authcachetime;
if(strcmp(ac->username, param->username)){ if(strcmp(ac->username, param->username)){
@ -737,7 +697,7 @@ int doauth(struct clientparam * param){
ac->password = mystrdup(param->password); ac->password = mystrdup(param->password);
myfree(tmp); myfree(tmp);
} }
ac->ip = param->sinc.sin_addr.s_addr; memcpy(&ac->sa, &param->sincr, SASIZE(&param->sincr));
break; break;
} }
} }
@ -746,7 +706,7 @@ int doauth(struct clientparam * param){
if(ac){ if(ac){
ac->expires = conf.time + conf.authcachetime; ac->expires = conf.time + conf.authcachetime;
ac->username = mystrdup(param->username); ac->username = mystrdup(param->username);
ac->ip = param->sinc.sin_addr.s_addr; memcpy(&ac->sa, &param->sincr, SASIZE(&param->sincr));
ac->password = NULL; ac->password = NULL;
if((conf.authcachetype&4) && param->password) ac->password = mystrdup(param->password); if((conf.authcachetype&4) && param->password) ac->password = mystrdup(param->password);
} }
@ -781,28 +741,37 @@ int userauth(struct clientparam * param){
return (param->username)? 0:4; return (param->username)? 0:4;
} }
int nbnameauth(struct clientparam * param){
unsigned char * name = getNetBIOSnamebyip(param->sinc.sin_addr.s_addr);
if (param->username) myfree (param->username);
param->username = name;
return name? 0:4;
}
int dnsauth(struct clientparam * param){ int dnsauth(struct clientparam * param){
char buf[32]; char buf[128];
unsigned u = ntohl(param->sinc.sin_addr.s_addr); char addr[16];
char dig[]="0123456789abcdef";
unsigned u;
int i;
if(*SAFAMILY(&param->sincr)!=AF_INET){
char *s = buf;
for(i=15; i>=0; i--){
unsigned char c=((unsigned char *)SAADDR(&param->sincr))[i];
*s++ = dig[(c&0xf)];
*s++ = '.';
*s++ = dig[(c>>4)];
*s++ = '.';
}
sprintf(s, "ip6.arpa");
}
else {
u = ntohl(*(unsigned long *)SAADDR(&param->sincr));
sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", sprintf(buf, "%u.%u.%u.%u.in-addr.arpa",
((u&0x000000FF)), ((u&0x000000FF)),
((u&0x0000FF00)>>8), ((u&0x0000FF00)>>8),
((u&0x00FF0000)>>16), ((u&0x00FF0000)>>16),
((u&0xFF000000)>>24)); ((u&0xFF000000)>>24));
}
if(param->sinc.sin_addr.s_addr != udpresolve(buf, NULL, param, 1)) return 6; if(!udpresolve(*SAFAMILY(&param->sincr), buf, addr, NULL, param, 1)) return 6;
if(!memcmp(SAADDR(&param->sincr), addr, SAADDRLEN(&param->sincr))) return 6;
return param->username? 0:4; return param->username? 0:4;
} }
@ -872,25 +841,29 @@ struct auth authfuncs[] = {
{authfuncs+1, NULL, NULL, ""}, {authfuncs+1, NULL, NULL, ""},
{authfuncs+2, ipauth, NULL, "iponly"}, {authfuncs+2, ipauth, NULL, "iponly"},
{authfuncs+3, userauth, checkACL, "useronly"}, {authfuncs+3, userauth, checkACL, "useronly"},
{authfuncs+4, nbnameauth, checkACL, "nbname"}, {authfuncs+4, dnsauth, checkACL, "dnsname"},
{authfuncs+5, dnsauth, checkACL, "dnsname"}, {authfuncs+5, strongauth, checkACL, "strong"},
{authfuncs+6, strongauth, checkACL, "strong"}, {authfuncs+6, cacheauth, checkACL, "cache"},
{authfuncs+7, cacheauth, checkACL, "cache"}, {authfuncs+7, NULL, NULL, "none"},
{authfuncs+8, NULL, NULL, "none"},
{NULL, NULL, NULL, ""} {NULL, NULL, NULL, ""}
}; };
struct hashtable dns_table = {0, NULL, NULL, NULL};
struct hashtable dns_table = {0, 4, {0,0,0,0}, NULL, NULL, NULL};
struct hashtable dns6_table = {0, 16, {0,0,0,0}, NULL, NULL, NULL};
void nametohash(const unsigned char * name, unsigned char *hash){ void nametohash(const unsigned char * name, unsigned char *hash, unsigned char *rnd){
unsigned i, j; unsigned i, j, k;
memset(hash, 0, sizeof(unsigned)*4); memcpy(hash, rnd, sizeof(unsigned)*4);
for(i=0, j=0; name[j]; j++){ for(i=0, j=0, k=0; name[j]; j++){
hash[i] += toupper(name[j]) - 32; hash[i] += (toupper(name[j]) - 32)+rnd[((toupper(name[j]))*29277+rnd[(k+j+i)%16]+k+j+i)%16];
if(++i == sizeof(unsigned)*4) i = 0; if(++i == sizeof(unsigned)*4) {
i = 0;
k++;
}
} }
} }
@ -918,8 +891,23 @@ void destroyhashtable(struct hashtable *ht){
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
} }
#define hvalue(I) ((struct hashentry *)((char *)ht->hashvalues + (I)*(sizeof(struct hashentry) + ht->recsize - 4)))
int inithashtable(struct hashtable *ht, unsigned nhashsize){ int inithashtable(struct hashtable *ht, unsigned nhashsize){
unsigned i; unsigned i;
clock_t c;
#ifdef _WIN32
struct timeb tb;
ftime(&tb);
#else
struct timeval tb;
struct timezone tz;
gettimeofday(&tb, &tz);
#endif
c = clock();
if(nhashsize<4) return 1; if(nhashsize<4) return 1;
pthread_mutex_lock(&hash_mutex); pthread_mutex_lock(&hash_mutex);
@ -936,78 +924,86 @@ int inithashtable(struct hashtable *ht, unsigned nhashsize){
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
return 2; return 2;
} }
if(!(ht->hashvalues = myalloc(nhashsize * sizeof(struct hashentry)))){ if(!(ht->hashvalues = myalloc(nhashsize * (sizeof(struct hashentry) + (ht->recsize-4))))){
myfree(ht->hashtable); myfree(ht->hashtable);
ht->hashtable = NULL; ht->hashtable = NULL;
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
return 3; return 3;
} }
ht->hashsize = nhashsize; ht->hashsize = nhashsize;
ht->rnd[0] = myrand(&tb, sizeof(tb));
ht->rnd[1] = myrand(ht->hashtable, sizeof(ht->hashtable));
ht->rnd[2] = myrand(&c, sizeof(c));
ht->rnd[3] = myrand(ht->hashvalues,sizeof(ht->hashvalues));
memset(ht->hashtable, 0, (ht->hashsize>>2) * sizeof(struct hashentry *)); memset(ht->hashtable, 0, (ht->hashsize>>2) * sizeof(struct hashentry *));
memset(ht->hashvalues, 0, ht->hashsize * sizeof(struct hashentry)); memset(ht->hashvalues, 0, ht->hashsize * (sizeof(struct hashentry) + ht->recsize -4));
for(i = 0; i< (ht->hashsize - 1); i++) { for(i = 0; i< (ht->hashsize - 1); i++) {
(ht->hashvalues + i)->next = ht->hashvalues + i + 1; hvalue(i)->next = hvalue(i+1);
} }
ht->hashempty = ht->hashvalues; ht->hashempty = ht->hashvalues;
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
return 0; return 0;
} }
int initdnshashtable(unsigned nhashsize){ void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires){
return inithashtable(&dns_table, nhashsize); struct hashentry * hen, *he;
} struct hashentry ** hep;
void hashadd(struct hashtable *ht, const unsigned char* name, unsigned long value, time_t expires){
struct hashentry * he;
unsigned index; unsigned index;
pthread_mutex_lock(&hash_mutex); pthread_mutex_lock(&hash_mutex);
if(!value||!name||!ht->hashtable||!ht->hashempty){ if(!ht||!value||!name||!ht->hashtable||!ht->hashempty) {
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
return; return;
} }
he = ht->hashempty; hen = ht->hashempty;
ht->hashempty = ht->hashempty->next; ht->hashempty = ht->hashempty->next;
nametohash(name, he->hash); nametohash(name, hen->hash, (unsigned char *)ht->rnd);
he->value = value; memcpy(hen->value, value, ht->recsize);
he->expires = expires; hen->expires = expires;
he->next = NULL; hen->next = NULL;
index = hashindex(ht, he->hash); index = hashindex(ht, hen->hash);
if(!ht->hashtable[index] || !memcmp(he->hash, ht->hashtable[index]->hash, sizeof(he->hash))){
he->next = ht->hashtable[index]; for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
ht->hashtable[index] = he; if(he->expires < conf.time || !memcmp(hen->hash, he->hash, sizeof(he->hash))) {
} (*hep) = he->next;
else { he->expires = 0;
memset(he, 0, sizeof(struct hashentry));
he->next = ht->hashempty; he->next = ht->hashempty;
ht->hashempty = he; ht->hashempty = he;
} }
else hep=&(he->next);
}
hen->next = ht->hashtable[index];
ht->hashtable[index] = hen;
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
} }
unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsigned *ttl){ unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsigned char* value, unsigned *ttl){
unsigned char hash[sizeof(unsigned)*4]; unsigned char hash[sizeof(unsigned)*4];
struct hashentry ** hep; struct hashentry ** hep;
struct hashentry *he; struct hashentry *he;
unsigned index; unsigned index;
time_t t;
if(!ht->hashtable || !name) return 0;
time(&t);
nametohash(name, hash);
index = hashindex(ht, hash);
pthread_mutex_lock(&hash_mutex); pthread_mutex_lock(&hash_mutex);
if(!ht || !ht->hashtable || !name) {
pthread_mutex_unlock(&hash_mutex);
return 0;
}
nametohash(name, hash, (unsigned char *)ht->rnd);
index = hashindex(ht, hash);
for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){ for(hep = ht->hashtable + index; (he = *hep)!=NULL; ){
if((unsigned long)he->expires < (unsigned long)t) { if(he->expires < conf.time) {
(*hep) = he->next; (*hep) = he->next;
he->expires = 0; he->expires = 0;
he->next = ht->hashempty; he->next = ht->hashempty;
ht->hashempty = he; ht->hashempty = he;
} }
else if(!memcmp(hash, he->hash, sizeof(unsigned)*4)){ else if(!memcmp(hash, he->hash, sizeof(unsigned)*4)){
if(ttl) *ttl = (unsigned)(he->expires - conf.time);
memcpy(value, he->value, ht->recsize);
pthread_mutex_unlock(&hash_mutex); pthread_mutex_unlock(&hash_mutex);
if(ttl) *ttl = (unsigned)(he->expires - t); return 1;
return he->value;
} }
else hep=&(he->next); else hep=&(he->next);
} }
@ -1015,48 +1011,76 @@ unsigned long hashresolv(struct hashtable *ht, const unsigned char* name, unsign
return 0; return 0;
} }
unsigned long nservers[MAXNSERVERS] = {0, 0, 0, 0, 0}; struct nserver nservers[MAXNSERVERS] = {{{0},0}, {{0},0}, {{0},0}, {{0},0}, {{0},0}};
struct nserver authnserver;
unsigned long authnserver;
unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientparam* param, int makeauth){ unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, unsigned *retttl, struct clientparam* param, int makeauth){
int i; int i,n;
unsigned long retval; unsigned long retval;
if((retval = hashresolv(&dns_table, name, retttl))) { if((af == AF_INET) && (retval = hashresolv(&dns_table, name, value, retttl))) {
return retval; return retval;
} }
if((af == AF_INET6) && (retval = hashresolv(&dns6_table, name, value, retttl))) {
for(i=0; (i<(makeauth && authnserver)? 1 : MAXNSERVERS) && ((makeauth && authnserver) || nservers[i]); i++){ return retval;
unsigned short nquery, nq, na; }
unsigned char buf[4096], *s1, *s2; n = (makeauth && !SAISNULL(&authnserver.addr))? 1 : numservers;
for(i=0; i<n; i++){
unsigned short nq, na;
unsigned char b[4098], *buf, *s1, *s2;
int j, k, len, flen; int j, k, len, flen;
SOCKET sock; SOCKET sock;
unsigned ttl; unsigned ttl;
time_t t; #ifndef NOIPV6
struct sockaddr_in sin, *sinsp; struct sockaddr_in6 addr;
#else
struct sockaddr_in addr;
#endif
struct sockaddr *sinsr, *sinsl;
int usetcp = 0;
unsigned short serial = 1;
memset(&sin, 0, sizeof(sin)); buf = b+2;
sinsp = (param && !makeauth)? &param->sins : &sin;
sinsl = (param && !makeauth)? (struct sockaddr *)&param->sinsl : (struct sockaddr *)&addr;
sinsr = (param && !makeauth)? (struct sockaddr *)&param->sinsr : (struct sockaddr *)&addr;
memset(sinsl, 0, sizeof(addr));
memset(sinsr, 0, sizeof(addr));
if((sock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) break; if(makeauth && !SAISNULL(&authnserver.addr)){
sinsp->sin_family = AF_INET; usetcp = authnserver.usetcp;
sinsp->sin_port = htons(0); *SAFAMILY(sinsl) = *SAFAMILY(&authnserver.addr);
sinsp->sin_addr.s_addr = htonl(0); }
if(so._bind(sock,(struct sockaddr *)sinsp,sizeof(struct sockaddr_in))) { else {
usetcp = nservers[i].usetcp;
*SAFAMILY(sinsl) = *SAFAMILY(&nservers[i].addr);
}
if((sock=so._socket(SASOCK(sinsl), usetcp?SOCK_STREAM:SOCK_DGRAM, usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) break;
if(so._bind(sock,sinsl,sizeof(addr))){
so._shutdown(sock, SHUT_RDWR); so._shutdown(sock, SHUT_RDWR);
so._closesocket(sock); so._closesocket(sock);
break; break;
} }
sinsp->sin_addr.s_addr = (makeauth && authnserver)?authnserver : nservers[i]; if(makeauth && !SAISNULL(&authnserver.addr)){
sinsp->sin_port = htons(53); memcpy(sinsr, &authnserver.addr, sizeof(addr));
}
else {
memcpy(sinsr, &nservers[i].addr, sizeof(addr));
}
if(usetcp){
if(so._connect(sock,sinsr,sizeof(addr))) {
so._shutdown(sock, SHUT_RDWR);
so._closesocket(sock);
break;
}
}
len = (int)strlen((char *)name); len = (int)strlen((char *)name);
nquery = myrand(name, len);
*(unsigned short*)buf = nquery; /* query id */ serial = myrand(name,len);
*(unsigned short*)buf = serial; /* query id */
buf[2] = 1; /* recursive */ buf[2] = 1; /* recursive */
buf[3] = 0; buf[3] = 0;
buf[4] = 0; buf[4] = 0;
@ -1074,21 +1098,38 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
*s2 = (len - (int)(s2 - buf)) - 1; *s2 = (len - (int)(s2 - buf)) - 1;
len++; len++;
buf[len++] = 0; buf[len++] = 0;
buf[len++] = (makeauth == 1)? 0x0c : 0x01; /* PTR:host address */ buf[len++] = (makeauth == 1)? 0x0c : (af==AF_INET6? 0x1c:0x01); /* PTR:host address */
buf[len++] = 0; buf[len++] = 0;
buf[len++] = 1; /* INET */ buf[len++] = 1; /* INET */
if(socksendto(sock, sinsp, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){ if(usetcp){
buf-=2;
*(unsigned short*)buf = htons(len);
len+=2;
}
if(socksendto(sock, sinsr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
so._shutdown(sock, SHUT_RDWR); so._shutdown(sock, SHUT_RDWR);
so._closesocket(sock); so._closesocket(sock);
continue; continue;
} }
if(param) param->statscli += len; if(param) param->statscli64 += len;
len = sockrecvfrom(sock, sinsp, buf, 4096, 15000); len = sockrecvfrom(sock, sinsr, buf, 4096, 15000);
so._shutdown(sock, SHUT_RDWR); so._shutdown(sock, SHUT_RDWR);
so._closesocket(sock); so._closesocket(sock);
if(len <= 13) continue; if(len <= 13) {
if(param) param->statssrv += len; continue;
if(*(unsigned short *)buf != nquery)continue; }
if(param) param->statssrv64 += len;
if(usetcp){
unsigned short us;
us = ntohs(*(unsigned short*)buf);
len-=2;
buf+=2;
if(us > 4096 || us < len || (us > len && sockrecvfrom(sock, sinsr, buf+len, us-len, 15000) != us-len)) {
continue;
}
}
if(*(unsigned short *)buf != serial)continue;
if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) { if((na = buf[7] + (((unsigned short)buf[6])<<8)) < 1) {
return 0; return 0;
} }
@ -1105,25 +1146,27 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
k += 4; k += 4;
if(na > 255) na = 255; /* somebody is very evil */ if(na > 255) na = 255; /* somebody is very evil */
for (j = 0; j < na; j++) { /* now there should be answers */ for (j = 0; j < na; j++) { /* now there should be answers */
if((k+16) > len) { if((k+(af == AF_INET6?28:16)) > len) {
break; break;
} }
flen = buf[k+11] + (((unsigned short)buf[k+10])<<8); flen = buf[k+11] + (((unsigned short)buf[k+10])<<8);
if((k+12+flen) > len) break; if((k+12+flen) > len) {
break;
}
if(makeauth != 1){ if(makeauth != 1){
if(buf[k+2] != 0 || buf[k+3] != 0x01 || flen != 4) { if(buf[k+2] != 0 || buf[k+3] != (af == AF_INET6?0x1c:0x1) || flen != (af == AF_INET6?16:4)) {
k+= (12 + flen); k+= (12 + flen);
continue; /* we need A IPv4 */ continue; /* we need A IPv4 */
} }
retval = *(unsigned long *)(buf + k + 12);
ttl = ntohl(*(unsigned long *)(buf + k + 6)); ttl = ntohl(*(unsigned long *)(buf + k + 6));
t = time(0); memcpy(value, buf + k + 12, af == AF_INET6? 16:4);
if(ttl < 60 || ((unsigned)t)+ttl < ttl) ttl = 300; if(ttl < 60 || ttl > (3600*12)) ttl = 300;
if(ttl){ if(ttl){
hashadd(&dns_table, name, retval, ((unsigned)t)+ttl); hashadd(af == AF_INET6?&dns6_table:&dns_table, name, value, conf.time+ttl);
} }
if(retttl) *retttl = ttl; if(retttl) *retttl = ttl;
return retval; return 1;
} }
else { else {
@ -1140,19 +1183,30 @@ unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientpa
if(param->username)myfree(param->username); if(param->username)myfree(param->username);
param->username = mystrdup (buf + k + 13); param->username = mystrdup (buf + k + 13);
return udpresolve(param->username, NULL, NULL, 2); return udpresolve(af,param->username, value, NULL, NULL, 2);
} }
} }
} }
return 0; return 0;
} }
unsigned long myresolver(unsigned char * name){ unsigned long myresolver(int af, unsigned char * name, unsigned char * value){
return udpresolve(name, NULL, NULL, 0); return udpresolve(af, name, value, NULL, NULL, 0);
} }
unsigned long fakeresolver (unsigned char *name){ unsigned long fakeresolver (int af, unsigned char *name, unsigned char * value){
return htonl(0x7F000002); memset(value, 0, af == AF_INET6? 16 : 4);
if(af == AF_INET6){
memset(value, 0, 16);
value[15] = 2;
}
else {
value[0] = 127;
value[1] = 0;
value[2] = 0;
value[3] = 2;
}
return 1;
} }
#ifndef NOODBC #ifndef NOODBC
@ -1254,46 +1308,45 @@ void sqlerr (char *buf){
fprintf(conf.stdlog, "%s\n", buf); fprintf(conf.stdlog, "%s\n", buf);
fflush(conf.stdlog); fflush(conf.stdlog);
} }
pthread_mutex_unlock(&odbc_mutex); pthread_mutex_unlock(&log_mutex);
} }
void logsql(struct clientparam * param, const unsigned char *s) { void logsql(struct clientparam * param, const unsigned char *s) {
unsigned char buf[4096];
SQLRETURN ret; SQLRETURN ret;
int len; int len;
len = dobuf(param, buf, s, "\'");
if(param->nolog) return; if(param->nolog) return;
pthread_mutex_lock(&odbc_mutex); pthread_mutex_lock(&log_mutex);
len = dobuf(param, tmpbuf, s, "\'");
if(attempt > 5){ if(attempt > 5){
time_t t; time_t t;
t = time(0); t = time(0);
if (t - attempt_time < 180){ if (t - attempt_time < 180){
sqlerr(buf); sqlerr(tmpbuf);
return; return;
} }
} }
if(!hstmt){ if(!hstmt){
if(!init_sql(sqlstring)) { if(!init_sql(sqlstring)) {
sqlerr(buf); sqlerr(tmpbuf);
return; return;
} }
} }
if(hstmt){ if(hstmt){
ret = SQLExecDirect(hstmt, (SQLCHAR *)buf, (SQLINTEGER)len); ret = SQLExecDirect(hstmt, (SQLCHAR *)tmpbuf, (SQLINTEGER)len);
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){ if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
close_sql(); close_sql();
if(!init_sql(sqlstring)){ if(!init_sql(sqlstring)){
sqlerr(buf); sqlerr(tmpbuf);
return; return;
} }
if(hstmt) { if(hstmt) {
ret = SQLExecDirect(hstmt, (SQLCHAR *)buf, (SQLINTEGER)len); ret = SQLExecDirect(hstmt, (SQLCHAR *)tmpbuf, (SQLINTEGER)len);
if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){ if(ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO){
sqlerr(buf); sqlerr(tmpbuf);
return; return;
} }
attempt = 0; attempt = 0;
@ -1301,22 +1354,8 @@ void logsql(struct clientparam * param, const unsigned char *s) {
} }
attempt = 0; attempt = 0;
} }
pthread_mutex_unlock(&odbc_mutex); pthread_mutex_unlock(&log_mutex);
} }
#endif #endif
#ifdef WITHMAIN
int main(int argc, unsigned char * argv[]) {
unsigned ip = 0;
WSADATA wd;
WSAStartup(MAKEWORD( 1, 1 ), &wd);
if(argc == 2)ip=getip(argv[1]);
if(!hp) {
printf("Not found");
return 0;
}
printf("Name: '%s'\n", getnamebyip(ip);
return 0;
}
#endif

View File

@ -3,7 +3,6 @@
* *
* please read License Agreement * please read License Agreement
* *
* $Id: base64.c,v 1.6 2008/01/08 21:46:36 vlad Exp $
*/ */
#include <string.h> #include <string.h>

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: common.c,v 1.94 2014-04-07 21:24:45 vlad Exp $
*/ */
@ -22,13 +21,22 @@ int randomizer = 1;
unsigned char **stringtable = NULL; unsigned char **stringtable = NULL;
int myinet_ntoa(struct in_addr in, char * buf){ int myinet_ntop(int af, void *src, char *dst, socklen_t size){
unsigned u = ntohl(in.s_addr); #ifndef NOIPV6
return sprintf(buf, "%u.%u.%u.%u", if(af != AF_INET6){
#endif
unsigned u = ntohl(((struct in_addr *)src)->s_addr);
return sprintf(dst, "%u.%u.%u.%u",
((u&0xFF000000)>>24), ((u&0xFF000000)>>24),
((u&0x00FF0000)>>16), ((u&0x00FF0000)>>16),
((u&0x0000FF00)>>8), ((u&0x0000FF00)>>8),
((u&0x000000FF))); ((u&0x000000FF)));
#ifndef NOIPV6
}
*dst = 0;
inet_ntop(af, src, dst, size);
return (int)strlen(dst);
#endif
} }
char *rotations[] = { char *rotations[] = {
@ -56,8 +64,11 @@ struct extparam conf = {
NULL, NULL, NULL, NULL,
NONE, NONE, NONE, NONE,
NULL, NULL,
INADDR_ANY, INADDR_ANY, #ifndef NOIPV6
0, 0, {AF_INET},{AF_INET6},{AF_INET},
#else
{AF_INET},{AF_INET},
#endif
NULL, NULL,
NULL, NULL,
doconnect, doconnect,
@ -76,6 +87,10 @@ struct extparam conf = {
'@' '@'
}; };
int numservers=0;
char* NULLADDR="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
int myrand(void * entropy, int len){ int myrand(void * entropy, int len){
int i; int i;
unsigned short init; unsigned short init;
@ -201,23 +216,45 @@ int ceparseargs(const char *str){
#endif #endif
int parsehostname(char *hostname, struct clientparam *param, unsigned short port){ void parsehost(int family, char *host, struct sockaddr *sa){
char *sp; char *sp=NULL,*se=NULL;
unsigned short port;
if(!hostname || !*hostname)return 1; if(*host == '[') se=strchr(host, ']');
if ( (sp = strchr(hostname, ':')) ) *sp = 0; if ( (sp = strchr(se?se:host, ':')) ) *sp = 0;
if(hostname != param->hostname){ if(se){
if(param->hostname) myfree(param->hostname); *se = 0;
param->hostname = (unsigned char *)mystrdup(hostname);
} }
if(sp){ if(sp){
port = atoi(sp+1); port = atoi(sp+1);
*sp = ':';
} }
param->req.sin_port=htons(port); getip46(family, host + (se!=0), (struct sockaddr *)sa);
param->req.sin_addr.s_addr = getip(param->hostname); if(se) *se = ']';
param->sins.sin_addr.s_addr = 0; if(sp) *sp = ':';
param->sins.sin_port = 0; *SAPORT(sa) = htons(port);
}
int parsehostname(char *hostname, struct clientparam *param, unsigned short port){
char *sp=NULL,*se=NULL;
if(!hostname || !*hostname)return 1;
if(*hostname == '[') se=strchr(hostname, ']');
if ( (sp = strchr(se?se:hostname, ':')) ) *sp = 0;
if(se){
*se = 0;
}
if(hostname != (char *)param->hostname){
if(param->hostname) myfree(param->hostname);
param->hostname = (unsigned char *)mystrdup(hostname + (se!=0));
}
if(sp){
port = atoi(sp+1);
}
getip46(param->srv->family, param->hostname, (struct sockaddr *)&param->req);
if(se) *se = ']';
if(sp) *sp = ':';
*SAPORT(&param->req) = htons(port);
memset(&param->sinsr, 0, sizeof(param->sinsr));
return 0; return 0;
} }
@ -260,6 +297,7 @@ int parseconnusername(char *username, struct clientparam *param, int extpasswd,
if(!username || !*username) return 1; if(!username || !*username) return 1;
if ((sb=strchr(username, conf.delimchar)) == NULL){ if ((sb=strchr(username, conf.delimchar)) == NULL){
if(!param->hostname && param->remsock == INVALID_SOCKET) return 2; if(!param->hostname && param->remsock == INVALID_SOCKET) return 2;
if(param->hostname)parsehostname(param->hostname, param, port);
return parseusername(username, param, extpasswd); return parseusername(username, param, extpasswd);
} }
while ((se=strchr(sb+1, conf.delimchar)))sb=se; while ((se=strchr(sb+1, conf.delimchar)))sb=se;
@ -287,7 +325,7 @@ void clearstat(struct clientparam * param) {
param->time_start = (time_t)tv.tv_sec; param->time_start = (time_t)tv.tv_sec;
param->msec_start = (tv.tv_usec / 1000); param->msec_start = (tv.tv_usec / 1000);
#endif #endif
param->statscli = param->statssrv = param->nreads = param->nwrites = param->statscli64 = param->statssrv64 = param->nreads = param->nwrites =
param->nconnects = 0; param->nconnects = 0;
} }
@ -306,7 +344,6 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
long timezone; long timezone;
unsigned delay; unsigned delay;
struct in_addr tmpia;
@ -378,10 +415,10 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
i+=10; i+=10;
break; break;
case 'b': case 'b':
i+=sprintf((char *)buf+i, "%u", delay?(unsigned)(param->statscli * 1000./delay):0); i+=sprintf((char *)buf+i, "%u", delay?(unsigned)(param->statscli64 * 1000./delay):0);
break; break;
case 'B': case 'B':
i+=sprintf((char *)buf+i, "%u", delay?(unsigned)(param->statssrv * 1000./delay):0); i+=sprintf((char *)buf+i, "%u", delay?(unsigned)(param->statssrv64 * 1000./delay):0);
break; break;
case 'D': case 'D':
i+=sprintf((char *)buf+i, "%u", delay); i+=sprintf((char *)buf+i, "%u", delay);
@ -412,7 +449,7 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
break; break;
case 'n': case 'n':
len = param->hostname? (int)strlen((char *)param->hostname) : 0; len = param->hostname? (int)strlen((char *)param->hostname) : 0;
if (len > 0) for(len = 0; param->hostname[len] && i < 4000; len++, i++){ if (len > 0 && !strchr((char *)param->hostname, ':')) for(len = 0; param->hostname[len] && i < 4000; len++, i++){
buf[i] = param->hostname[len]; buf[i] = param->hostname[len];
if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace; if(param->srv->nonprintable && (buf[i] < 0x20 || strchr((char *)param->srv->nonprintable, buf[i]))) buf[i] = param->srv->replace;
if(doublec && strchr((char *)doublec, buf[i])) { if(doublec && strchr((char *)doublec, buf[i])) {
@ -420,7 +457,12 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
i++; i++;
} }
} }
else i += myinet_ntoa(param->sins.sin_addr, (char *)buf + i); else {
buf[i++] = '[';
i += myinet_ntop(*SAFAMILY(&param->req), SAADDR(&param->req), (char *)buf + i, 64);
buf[i++] = ']';
buf[i++] = 0;
}
break; break;
case 'N': case 'N':
@ -449,40 +491,39 @@ int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char
} }
break; break;
case 'e': case 'e':
tmpia.s_addr = param->extip; i += myinet_ntop(*SAFAMILY(&param->sinsl), SAADDR(&param->sinsl), (char *)buf + i, 64);
i += myinet_ntoa(tmpia, (char *)buf + i);
break; break;
case 'C': case 'C':
i += myinet_ntoa(param->sinc.sin_addr, (char *)buf + i); i += myinet_ntop(*SAFAMILY(&param->sincr), SAADDR(&param->sincr), (char *)buf + i, 64);
break; break;
case 'R': case 'R':
i += myinet_ntoa(param->sins.sin_addr, (char *)buf + i); i += myinet_ntop(*SAFAMILY(&param->sinsr), SAADDR(&param->sinsr), (char *)buf + i, 64);
break; break;
case 'Q': case 'Q':
i += myinet_ntoa(param->req.sin_addr, (char *)buf + i); i += myinet_ntop(*SAFAMILY(&param->req), SAADDR(&param->req), (char *)buf + i, 64);
break; break;
case 'p': case 'p':
sprintf((char *)buf+i, "%hu", ntohs(param->srv->intport)); sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(&param->srv->intsa)));
i += (int)strlen((char *)buf+i); i += (int)strlen((char *)buf+i);
break; break;
case 'c': case 'c':
sprintf((char *)buf+i, "%hu", ntohs(param->sinc.sin_port)); sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(&param->sincr)));
i += (int)strlen((char *)buf+i); i += (int)strlen((char *)buf+i);
break; break;
case 'r': case 'r':
sprintf((char *)buf+i, "%hu", ntohs(param->sins.sin_port)); sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(&param->sinsr)));
i += (int)strlen((char *)buf+i); i += (int)strlen((char *)buf+i);
break; break;
case 'q': case 'q':
sprintf((char *)buf+i, "%hu", ntohs(param->req.sin_port)); sprintf((char *)buf+i, "%hu", ntohs(*SAPORT(&param->req)));
i += (int)strlen((char *)buf+i); i += (int)strlen((char *)buf+i);
break; break;
case 'I': case 'I':
sprintf((char *)buf+i, "%lu", param->statssrv); sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->statssrv64);
i += (int)strlen((char *)buf+i); i += (int)strlen((char *)buf+i);
break; break;
case 'O': case 'O':
sprintf((char *)buf+i, "%lu", param->statscli); sprintf((char *)buf+i, "%"PRINTF_INT64_MODIFIER"u", param->statscli64);
i += (int)strlen((char *)buf+i); i += (int)strlen((char *)buf+i);
break; break;
case 'h': case 'h':
@ -560,77 +601,94 @@ void lognone(struct clientparam * param, const unsigned char *s) {
if(param->trafcountfunc)(*param->trafcountfunc)(param); if(param->trafcountfunc)(*param->trafcountfunc)(param);
clearstat(param); clearstat(param);
} }
pthread_mutex_t log_mutex;
int logmutexinit = 0;
unsigned char tmpbuf[8192];
void logstdout(struct clientparam * param, const unsigned char *s) { void logstdout(struct clientparam * param, const unsigned char *s) {
unsigned char buf[4096];
FILE *log; FILE *log;
if(!logmutexinit){
pthread_mutex_init(&log_mutex, NULL);
logmutexinit = 1;
}
pthread_mutex_lock(&log_mutex);
log = param->srv->stdlog?param->srv->stdlog:conf.stdlog?conf.stdlog:stdout; log = param->srv->stdlog?param->srv->stdlog:conf.stdlog?conf.stdlog:stdout;
dobuf(param, buf, s, NULL); dobuf(param, tmpbuf, s, NULL);
if(!param->nolog)if(fprintf(log, "%s\n", buf) < 0) { if(!param->nolog)if(fprintf(log, "%s\n", tmpbuf) < 0) {
perror("printf()"); perror("printf()");
}; };
if(log != conf.stdlog)fflush(log); if(log != conf.stdlog)fflush(log);
pthread_mutex_unlock(&log_mutex);
} }
#ifndef _WIN32 #ifndef _WIN32
void logsyslog(struct clientparam * param, const unsigned char *s) { void logsyslog(struct clientparam * param, const unsigned char *s) {
unsigned char buf[4096];
dobuf(param, buf, s, NULL); if(!logmutexinit){
if(!param->nolog)syslog(LOG_INFO, "%s", buf); pthread_mutex_init(&log_mutex, NULL);
logmutexinit = 1;
}
pthread_mutex_lock(&log_mutex);
dobuf(param, tmpbuf, s, NULL);
if(!param->nolog)syslog(LOG_INFO, "%s", tmpbuf);
pthread_mutex_unlock(&log_mutex);
} }
#endif #endif
int doconnect(struct clientparam * param){ int doconnect(struct clientparam * param){
SASIZETYPE size = sizeof(param->sins); SASIZETYPE size = sizeof(param->sinsr);
struct sockaddr_in bindsa;
if (*SAFAMILY(&param->sincr) == *SAFAMILY(&param->req) && !memcmp(SAADDR(&param->sincr), SAADDR(&param->req), SAADDRLEN(&param->req)) &&
*SAPORT(&param->sincr) == *SAPORT(&param->req)) return 519;
if (param->operation == ADMIN || param->operation == DNSRESOLVE || param->operation == BIND || param->operation == UDPASSOC) if (param->operation == ADMIN || param->operation == DNSRESOLVE || param->operation == BIND || param->operation == UDPASSOC)
return 0; return 0;
if (param->remsock != INVALID_SOCKET){ if (param->remsock != INVALID_SOCKET){
if(so._getpeername(param->remsock, (struct sockaddr *)&param->sins, &size)==-1) {return (15);} if(so._getpeername(param->remsock, (struct sockaddr *)&param->sinsr, &size)==-1) {return (15);}
} }
else { else {
struct linger lg; struct linger lg = {1,conf.timeouts[SINGLEBYTE_S]};
int opt = 1;
if(!param->sins.sin_addr.s_addr) if(SAISNULL(&param->sinsr)){
if(!(param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr)) return 100; if(SAISNULL(&param->req)) {
if(!param->sins.sin_port)param->sins.sin_port = param->req.sin_port; return 100;
if ((param->remsock=so._socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);} }
*SAFAMILY(&param->sinsr) = *SAFAMILY(&param->req);
memcpy(SAADDR(&param->sinsr), SAADDR(&param->req), SAADDRLEN(&param->req));
}
if(!*SAPORT(&param->sinsr))*SAPORT(&param->sinsr) = *SAPORT(&param->req);
if ((param->remsock=so._socket(SASOCK(&param->sinsr), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {return (11);}
so._setsockopt(param->remsock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg)); so._setsockopt(param->remsock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg));
memset(&bindsa, 0, sizeof(bindsa)); so._setsockopt(param->remsock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int));
bindsa.sin_family = AF_INET;
bindsa.sin_port = param->extport; #ifndef NOIPV6
bindsa.sin_addr.s_addr = param->extip; if(*SAFAMILY(&param->sinsr) == AF_INET6) memcpy(&param->sinsl, &param->srv->extsa6, sizeof(param->srv->extsa6));
if (param->srv->targetport && !bindsa.sin_port && ntohs(param->sinc.sin_port) > 1023) bindsa.sin_port = param->sinc.sin_port; else
if(so._bind(param->remsock, (struct sockaddr*)&bindsa, sizeof(bindsa))==-1) { #endif
memset(&bindsa, 0, sizeof(bindsa)); memcpy(&param->sinsl, &param->srv->extsa, sizeof(param->srv->extsa));
bindsa.sin_family = AF_INET; if (param->srv->targetport && !*SAPORT(&param->sinsl) && ntohs(*SAPORT(&param->sincr)) > 1023) *SAPORT(&param->sinsl) = *SAPORT(&param->sincr);
bindsa.sin_addr.s_addr = param->extip; if(so._bind(param->remsock, (struct sockaddr*)&param->sinsl, sizeof(param->sinsl))==-1) {
bindsa.sin_port = 0; *SAPORT(&param->sinsl) = 0;
if(so._bind(param->remsock, (struct sockaddr*)&bindsa, sizeof(bindsa))==-1) { if(so._bind(param->remsock, (struct sockaddr*)&param->sinsl, sizeof(param->sinsl))==-1) {
return 12; return 12;
} }
} }
param->sins.sin_family = AF_INET;
if(param->operation >= 256 || (param->operation & CONNECT)){ if(param->operation >= 256 || (param->operation & CONNECT)){
#ifdef _WIN32 #ifdef _WIN32
unsigned long ul = 1; unsigned long ul = 1;
#endif #endif
if(so._connect(param->remsock,(struct sockaddr *)&param->sins,sizeof(param->sins))) {return (13);} if(so._connect(param->remsock,(struct sockaddr *)&param->sinsr,sizeof(param->sinsr))) {return (13);}
param->nconnects++; param->nconnects++;
#ifdef _WIN32 #ifdef _WIN32
ioctlsocket(param->remsock, FIONBIO, &ul); ioctlsocket(param->remsock, FIONBIO, &ul);
#else #else
fcntl(param->remsock,F_SETFL,O_NONBLOCK); fcntl(param->remsock,F_SETFL,O_NONBLOCK);
#endif #endif
if(so._getsockname(param->remsock, (struct sockaddr *)&bindsa, &size)==-1) {return (15);} size = sizeof(param->sinsl);
param->extip = bindsa.sin_addr.s_addr;
}
else {
if(so._getsockname(param->remsock, (struct sockaddr *)&param->sins, &size)==-1) {return (15);}
} }
if(so._getsockname(param->remsock, (struct sockaddr *)&param->sinsl, &size)==-1) {return (15);}
} }
return 0; return 0;
} }
@ -667,11 +725,13 @@ struct hostent * my_gethostbyname(char *name, char *buf, struct hostent *hp){
} }
#endif #endif
#ifdef NOIPV6
unsigned long getip(unsigned char *name){ unsigned long getip(unsigned char *name){
unsigned long retval; unsigned long retval;
int i; int i;
int ndots = 0; int ndots = 0;
struct hostent *hp=NULL; struct hostent *hp=NULL;
RESOLVFUNC tmpresolv;
#ifdef GETHOSTBYNAME_R #ifdef GETHOSTBYNAME_R
struct hostent he; struct hostent he;
@ -688,15 +748,14 @@ unsigned long getip(unsigned char *name){
if(name[i] <'0' || name[i] >'9') break; if(name[i] <'0' || name[i] >'9') break;
} }
if(!name[i] && ndots == 3){ if(!name[i] && ndots == 3){
unsigned long ip; if(scanaddr(name, &retval, NULL) == 4){
if(scanaddr(name, &ip, NULL) == 4){ return retval;
return ip;
} }
} }
if(resolvfunc){ if((tmpresolv=resolvfunc)){
if((retval = (*resolvfunc)(name))) return retval; if((*tmpresolv)(AF_INET, name, (unsigned char *)&retval)) return retval;
if(conf.demanddialprog) system(conf.demanddialprog); if(conf.demanddialprog) system(conf.demanddialprog);
return (*resolvfunc)(name); return (*tmpresolv)(AF_INET, name, (unsigned char *)&retval)?retval:0;
} }
#if !defined(_WIN32) && !defined(GETHOSTBYNAME_R) #if !defined(_WIN32) && !defined(GETHOSTBYNAME_R)
if(!ghbn_init){ if(!ghbn_init){
@ -719,3 +778,80 @@ unsigned long getip(unsigned char *name){
#endif #endif
return retval; return retval;
} }
#endif
unsigned long getip46(int family, unsigned char *name, struct sockaddr *sa){
#ifndef NOIPV6
int ndots=0, ncols=0, nhex=0;
struct addrinfo *ai, hint;
int i;
RESOLVFUNC tmpresolv;
if(!sa) return 0;
if(!family) {
family = 4;
#else
((struct sockaddr_in *)sa)->sin_family = AF_INET;
return (((struct sockaddr_in *)sa)->sin_addr.s_addr = getip(name))? AF_INET:0;
#endif
#ifndef NOIPV6
}
for(i=0; name[i]; i++){
if(name[i] == '.'){
if(++ndots > 3) {
break;
}
}
else if(name[i] == ':'){
if(++ncols > 7) {
break;
}
}
else if(name[i] == '%' || (name[i] >= 'a' && name[i] <= 'f') || (name[i] >= 'A' && name[i] <= 'F')){
nhex++;
}
else if(name[i] <'0' || name[i] >'9') {
break;
}
}
if(!name[i]){
if(ndots == 3 && ncols == 0 && nhex == 0){
*SAFAMILY(sa)=(family == 6)?AF_INET6 : AF_INET;
return inet_pton(*SAFAMILY(sa), name, SAADDR(sa))? *SAFAMILY(sa) : 0;
}
if(ncols >= 2) {
*SAFAMILY(sa)=AF_INET6;
return inet_pton(AF_INET6, name, SAADDR(sa))?(family==4? 0:AF_INET6) : 0;
}
}
if((tmpresolv = resolvfunc)){
int f = (family == 6 || family == 64)?AF_INET6:AF_INET;
*SAFAMILY(sa) = f;
if(tmpresolv(f, name, SAADDR(sa))) return f;
if(family == 4 || family == 6) return 0;
f = (family == 46)? AF_INET6 : AF_INET;
*SAFAMILY(sa) = f;
if(tmpresolv(f, name, SAADDR(sa))) return f;
return 0;
}
memset(&hint, 0, sizeof(hint));
hint.ai_family = (family == 6 || family == 64)?AF_INET6:AF_INET;
if (getaddrinfo(name, NULL, &hint, &ai)) {
if(family == 64 || family == 46){
hint.ai_family = (family == 64)?AF_INET:AF_INET6;
if (getaddrinfo(name, NULL, &hint, &ai)) return 0;
}
else return 0;
}
if(ai){
if(ai->ai_addr->sa_family == AF_INET || ai->ai_addr->sa_family == AF_INET6){
*SAFAMILY(sa)=ai->ai_addr->sa_family;
memcpy(SAADDR(sa), SAADDR(ai->ai_addr), SAADDRLEN(ai->ai_addr));
freeaddrinfo(ai);
return *SAFAMILY(sa);
}
freeaddrinfo(ai);
}
return 0;
#endif
}

1685
src/conf.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -3,11 +3,15 @@
* *
* please read License Agreement * please read License Agreement
* *
* $Id: datatypes.c,v 1.28 2009/08/14 09:56:21 v.dubrovin Exp $
*/ */
#include "proxy.h" #include "proxy.h"
static void pr_unsigned64(struct node *node, CBFUNC cbf, void*cb){
char buf[32];
if(node->value)(*cbf)(cb, buf, sprintf(buf, "%"PRINTF_INT64_MODIFIER"u", *(uint64_t *)node->value));
}
static void pr_integer(struct node *node, CBFUNC cbf, void*cb){ static void pr_integer(struct node *node, CBFUNC cbf, void*cb){
char buf[16]; char buf[16];
if(node->value)(*cbf)(cb, buf, sprintf(buf, "%d", *(int *)node->value)); if(node->value)(*cbf)(cb, buf, sprintf(buf, "%d", *(int *)node->value));
@ -52,19 +56,27 @@ static void pr_datetime(struct node *node, CBFUNC cbf, void*cb){
} }
} }
int ipprint(char *buf, unsigned uu){
unsigned u = ntohl(uu);
return sprintf(buf, "%u.%u.%u.%u",
((u&0xFF000000)>>24),
((u&0x00FF0000)>>16),
((u&0x0000FF00)>>8),
((u&0x000000FF)));
}
static void pr_ip(struct node *node, CBFUNC cbf, void*cb){ static void pr_ip(struct node *node, CBFUNC cbf, void*cb){
char buf[16]; char buf[16];
if(node->value)(*cbf)(cb, buf, ipprint(buf, *(unsigned *)node -> value)); if(node->value)(*cbf)(cb, buf, myinet_ntop(AF_INET, node -> value, buf, 4));
}
static void pr_ip6(struct node *node, CBFUNC cbf, void*cb){
char buf[64];
if(node->value)(*cbf)(cb, buf, myinet_ntop(AF_INET6, node -> value, buf, 16));
}
static void pr_sa(struct node *node, CBFUNC cbf, void*cb){
#ifdef NOIPV6
if(node->value)return pr_ip(node, cbf, cb);
#else
char buf[64];
buf[0] = '[';
buf[1] = 0;
inet_ntop(*SAFAMILY(node->value), node->value, buf+1, sizeof(buf)-10);
sprintf(buf + strlen(buf), "]:hu", (unsigned short)*SAPORT(node->value));
if(node->value)(*cbf)(cb, buf, strlen(buf));
#endif
} }
static void pr_wdays(struct node *node, CBFUNC cbf, void*cb){ static void pr_wdays(struct node *node, CBFUNC cbf, void*cb){
@ -225,9 +237,22 @@ static void pr_userlist(struct node *node, CBFUNC cbf, void*cb){
} }
} }
int printiple(char *buf, struct iplist* ipl){
int addrlen = (ipl->family == AF_INET6)?16:4, i;
i = myinet_ntop(ipl->family, &ipl->ip_from, buf, addrlen);
if(memcmp(&ipl->ip_from, &ipl->ip_to, addrlen)){
buf[i++] = '-';
i += myinet_ntop(ipl->family, &ipl->ip_from, buf+i, addrlen);
}
if(ipl->next){
buf[i++] = ',';
buf[i++] = ' ';
}
return i;
}
static void pr_iplist(struct node *node, CBFUNC cbf, void*cb){ static void pr_iplist(struct node *node, CBFUNC cbf, void*cb){
char buf[20]; char buf[128];
int i;
struct iplist *il = (struct iplist *)node->value; struct iplist *il = (struct iplist *)node->value;
if(!il) { if(!il) {
@ -235,10 +260,7 @@ static void pr_iplist(struct node *node, CBFUNC cbf, void*cb){
return; return;
} }
for(; il; il = il->next){ for(; il; il = il->next){
i = ipprint(buf, il->ip); (*cbf)(cb, buf, printiple(buf, il));
i += cidrprint(buf+i, il->mask);
if(il->next)buf[i++] = ',';
(*cbf)(cb, buf, i);
} }
} }
@ -259,18 +281,6 @@ static void * ef_iplist_next(struct node *node){
return (((struct iplist *)node->value) -> next); return (((struct iplist *)node->value) -> next);
} }
static void * ef_iplist_ip(struct node *node){
return &(((struct iplist *)node->value) -> ip);
}
static void * ef_iplist_cidr(struct node *node){
return &(((struct iplist *)node->value) -> mask);
}
static void * ef_iplist_mask(struct node *node){
return &(((struct iplist *)node->value) -> mask);
}
static void * ef_userlist_next(struct node * node){ static void * ef_userlist_next(struct node * node){
return (((struct userlist *)node->value) -> next); return (((struct userlist *)node->value) -> next);
} }
@ -333,12 +343,8 @@ static void * ef_chain_type(struct node * node){
} }
} }
static void * ef_chain_ip(struct node * node){ static void * ef_chain_addr(struct node * node){
return &((struct chain *)node->value) -> redirip; return &((struct chain *)node->value) -> addr;
}
static void * ef_chain_port(struct node * node){
return &((struct chain *)node->value) -> redirport;
} }
static void * ef_chain_weight(struct node * node){ static void * ef_chain_weight(struct node * node){
@ -446,12 +452,26 @@ static void * ef_trafcounter_type(struct node * node){
return &((struct trafcount *)node->value) -> type; return &((struct trafcount *)node->value) -> type;
} }
static void * ef_trafcounter_traffic(struct node * node){ static void * ef_trafcounter_traffic64(struct node * node){
return &((struct trafcount *)node->value) -> traf; return &((struct trafcount *)node->value) -> traf64;
}
static void * ef_trafcounter_limit64(struct node * node){
return &((struct trafcount *)node->value) -> traflim64;
}
static void * ef_client_maxtrafin64(struct node * node){
return &((struct clientparam *)node->value) -> maxtrafin64;
} }
static void * ef_trafcounter_limit(struct node * node){ static void * ef_client_maxtrafout64(struct node * node){
return &((struct trafcount *)node->value) -> traflim; return &((struct clientparam *)node->value) -> maxtrafout64;
}
static void * ef_client_bytesin64(struct node * node){
return &((struct clientparam *)node->value) -> statssrv64;
}
static void * ef_client_bytesout64(struct node * node){
return &((struct clientparam *)node->value) -> statscli64;
} }
static void * ef_trafcounter_cleared(struct node * node){ static void * ef_trafcounter_cleared(struct node * node){
@ -487,7 +507,6 @@ static void * ef_server_auth(struct node * node){
AUTHFUNC af = ((struct srvparam *)node->value) -> authfunc; AUTHFUNC af = ((struct srvparam *)node->value) -> authfunc;
if(af == alwaysauth) return "none"; if(af == alwaysauth) return "none";
if(af == nbnameauth) return "nbname";
if(af == ipauth) return "iponly"; if(af == ipauth) return "iponly";
if(af == strongauth) return "strong"; if(af == strongauth) return "strong";
return "uknown"; return "uknown";
@ -536,21 +555,19 @@ static void * ef_server_targetport(struct node * node){
return &((struct srvparam *)node->value) -> targetport; return &((struct srvparam *)node->value) -> targetport;
} }
static void * ef_server_intip(struct node * node){ static void * ef_server_intsa(struct node * node){
return &((struct srvparam *)node->value) -> intip; return &((struct srvparam *)node->value) -> intsa;
} }
static void * ef_server_extip(struct node * node){ static void * ef_server_extsa(struct node * node){
return &((struct srvparam *)node->value) -> extip; return &((struct srvparam *)node->value) -> extsa;
} }
static void * ef_server_intport(struct node * node){ #ifndef NOIPV6
return &((struct srvparam *)node->value) -> intport; static void * ef_server_extsa6(struct node * node){
} return &((struct srvparam *)node->value) -> extsa6;
static void * ef_server_extport(struct node * node){
return &((struct srvparam *)node->value) -> extport;
} }
#endif
static void * ef_server_acl(struct node * node){ static void * ef_server_acl(struct node * node){
return ((struct srvparam *)node->value) -> acl; return ((struct srvparam *)node->value) -> acl;
@ -573,14 +590,6 @@ static void * ef_client_next(struct node * node){
return ((struct clientparam *)node->value) -> next; return ((struct clientparam *)node->value) -> next;
} }
static void * ef_client_maxtrafin(struct node * node){
return &((struct clientparam *)node->value) -> maxtrafin;
}
static void * ef_client_maxtrafout(struct node * node){
return &((struct clientparam *)node->value) -> maxtrafout;
}
static void * ef_client_type(struct node * node){ static void * ef_client_type(struct node * node){
int service = ((struct clientparam *)node->value) -> service; int service = ((struct clientparam *)node->value) -> service;
return (service>=0 && service < 15)? (void *)conf.stringtable[SERVICES + service] : (void *)"unknown"; return (service>=0 && service < 15)? (void *)conf.stringtable[SERVICES + service] : (void *)"unknown";
@ -617,36 +626,16 @@ static void * ef_client_extpassword(struct node * node){
return ((struct clientparam *)node->value) -> extpassword; return ((struct clientparam *)node->value) -> extpassword;
} }
static void * ef_client_cliip(struct node * node){ static void * ef_client_clisa(struct node * node){
return &((struct clientparam *)node->value) -> sinc.sin_addr.s_addr; return &((struct clientparam *)node->value) -> sincr;
} }
static void * ef_client_srvip(struct node * node){ static void * ef_client_srvsa(struct node * node){
return &((struct clientparam *)node->value) -> sins.sin_addr.s_addr; return &((struct clientparam *)node->value) -> sinsr;
} }
static void * ef_client_reqip(struct node * node){ static void * ef_client_reqsa(struct node * node){
return &((struct clientparam *)node->value) -> req.sin_addr.s_addr; return &((struct clientparam *)node->value) -> req;
}
static void * ef_client_reqport(struct node * node){
return &((struct clientparam *)node->value) -> req.sin_port;
}
static void * ef_client_srvport(struct node * node){
return &((struct clientparam *)node->value) -> sins.sin_port;
}
static void * ef_client_cliport(struct node * node){
return &((struct clientparam *)node->value) -> sinc.sin_port;
}
static void * ef_client_bytesin(struct node * node){
return &((struct clientparam *)node->value) -> statssrv;
}
static void * ef_client_bytesout(struct node * node){
return &((struct clientparam *)node->value) -> statscli;
} }
static void * ef_client_pwtype(struct node * node){ static void * ef_client_pwtype(struct node * node){
@ -695,20 +684,12 @@ static struct property prop_pwlist[] = {
{NULL, "next", ef_pwlist_next, TYPE_PWLIST, "next"} {NULL, "next", ef_pwlist_next, TYPE_PWLIST, "next"}
}; };
static struct property prop_iplist[] = {
{prop_iplist + 1, "ip", ef_iplist_ip, TYPE_IP, "ip address"},
{prop_iplist + 2, "cidr", ef_iplist_cidr, TYPE_CIDR, "ip mask length"},
{prop_iplist + 3, "mask", ef_iplist_mask, TYPE_IP, "ip mask"},
{NULL, "next", ef_iplist_next, TYPE_IPLIST, "next"}
};
static struct property prop_chain[] = { static struct property prop_chain[] = {
{prop_chain + 1, "ip", ef_chain_ip, TYPE_IP, "parent ip address"}, {prop_chain + 1, "addr", ef_chain_addr, TYPE_SA, "parent address"},
{prop_chain + 2, "port", ef_chain_port, TYPE_PORT, "parent port"}, {prop_chain + 2, "type", ef_chain_type, TYPE_STRING, "parent type"},
{prop_chain + 3, "type", ef_chain_type, TYPE_STRING, "parent type"}, {prop_chain + 3, "weight", ef_chain_weight, TYPE_SHORT, "parent weight 0-1000"},
{prop_chain + 4, "weight", ef_chain_weight, TYPE_SHORT, "parent weight 0-1000"}, {prop_chain + 4, "user", ef_chain_user, TYPE_STRING, "parent login"},
{prop_chain + 5, "user", ef_chain_user, TYPE_STRING, "parent login"}, {prop_chain + 5, "password", ef_chain_password, TYPE_STRING, "parent password"},
{prop_chain + 6, "password", ef_chain_password, TYPE_STRING, "parent password"},
{NULL, "next", ef_chain_next, TYPE_CHAIN, "next"} {NULL, "next", ef_chain_next, TYPE_CHAIN, "next"}
}; };
@ -742,8 +723,10 @@ static struct property prop_trafcounter[] = {
{prop_trafcounter + 2, "ace", ef_trafcounter_ace, TYPE_ACE, "traffic to count"}, {prop_trafcounter + 2, "ace", ef_trafcounter_ace, TYPE_ACE, "traffic to count"},
{prop_trafcounter + 3, "number", ef_trafcounter_number, TYPE_UNSIGNED, "counter number"}, {prop_trafcounter + 3, "number", ef_trafcounter_number, TYPE_UNSIGNED, "counter number"},
{prop_trafcounter + 4, "type", ef_trafcounter_type, TYPE_ROTATION, "rotation type"}, {prop_trafcounter + 4, "type", ef_trafcounter_type, TYPE_ROTATION, "rotation type"},
{prop_trafcounter + 5, "traffic", ef_trafcounter_traffic, TYPE_TRAFFIC, "counter value"},
{prop_trafcounter + 6, "limit", ef_trafcounter_limit, TYPE_TRAFFIC, "counter limit"},
{prop_trafcounter + 5, "traffic", ef_trafcounter_traffic64, TYPE_UNSIGNED64, "counter value"},
{prop_trafcounter + 6, "limit", ef_trafcounter_limit64, TYPE_UNSIGNED64, "counter limit"},
{prop_trafcounter + 7, "cleared", ef_trafcounter_cleared, TYPE_DATETIME, "last rotated"}, {prop_trafcounter + 7, "cleared", ef_trafcounter_cleared, TYPE_DATETIME, "last rotated"},
{prop_trafcounter + 8, "updated", ef_trafcounter_updated, TYPE_DATETIME, "last updated"}, {prop_trafcounter + 8, "updated", ef_trafcounter_updated, TYPE_DATETIME, "last updated"},
{prop_trafcounter + 9, "comment", ef_trafcounter_comment, TYPE_STRING, "counter comment"}, {prop_trafcounter + 9, "comment", ef_trafcounter_comment, TYPE_STRING, "counter comment"},
@ -758,21 +741,22 @@ static struct property prop_server[] = {
{prop_server + 2, "target", ef_server_target, TYPE_STRING, "portmapper target ip"}, {prop_server + 2, "target", ef_server_target, TYPE_STRING, "portmapper target ip"},
{prop_server + 3, "targetport", ef_server_targetport, TYPE_PORT, "portmapper target port"}, {prop_server + 3, "targetport", ef_server_targetport, TYPE_PORT, "portmapper target port"},
{prop_server + 4, "starttime", ef_server_starttime, TYPE_DATETIME, "service started seconds"}, {prop_server + 4, "starttime", ef_server_starttime, TYPE_DATETIME, "service started seconds"},
{prop_server + 5, "intip", ef_server_intip, TYPE_IP, "ip address of internal interface"}, {prop_server + 5, "intsa", ef_server_intsa, TYPE_SA, "ip address of internal interface"},
{prop_server + 6, "extip", ef_server_extip, TYPE_IP, "ip address of external interface"}, {prop_server + 6, "extsa", ef_server_extsa, TYPE_SA, "ip address of external interface"},
{prop_server + 7, "intport", ef_server_intport, TYPE_PORT, "port to listen"}, {prop_server + 7, "auth", ef_server_auth, TYPE_STRING, "service authentication type"},
{prop_server + 8, "extport", ef_server_extport, TYPE_PORT, "port to use for outgoing connection"}, {prop_server + 8, "acl", ef_server_acl, TYPE_ACE, "access control list"},
{prop_server + 9, "auth", ef_server_auth, TYPE_STRING, "service authentication type"}, {prop_server + 9, "singlepacket", ef_server_singlepacket, TYPE_INTEGER, "is single packet redirection"},
{prop_server + 10, "acl", ef_server_acl, TYPE_ACE, "access control list"}, {prop_server + 10, "usentlm", ef_server_usentlm, TYPE_INTEGER, "allow NTLM authentication"},
{prop_server + 11, "singlepacket", ef_server_singlepacket, TYPE_INTEGER, "is single packet redirection"}, {prop_server + 11, "log", ef_server_log, TYPE_STRING, "type of logging"},
{prop_server + 12, "usentlm", ef_server_usentlm, TYPE_INTEGER, "allow NTLM authentication"}, {prop_server + 12, "logtarget", ef_server_logtarget, TYPE_STRING, "log target options"},
{prop_server + 13, "log", ef_server_log, TYPE_STRING, "type of logging"}, {prop_server + 13, "logformat", ef_server_logformat, TYPE_STRING, "logging format string"},
{prop_server + 14, "logtarget", ef_server_logtarget, TYPE_STRING, "log target options"}, {prop_server + 14, "nonprintable", ef_server_nonprintable, TYPE_STRING, "non printable characters"},
{prop_server + 15, "logformat", ef_server_logformat, TYPE_STRING, "logging format string"}, {prop_server + 15, "replacement", ef_server_replacement, TYPE_CHAR, "replacement character"},
{prop_server + 16, "nonprintable", ef_server_nonprintable, TYPE_STRING, "non printable characters"}, {prop_server + 16, "childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"},
{prop_server + 17, "replacement", ef_server_replacement, TYPE_CHAR, "replacement character"}, {prop_server + 17, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
{prop_server + 18, "childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"}, #ifndef NOIPV6
{prop_server + 19, "child", ef_server_child, TYPE_CLIENT, "connected clients"}, {prop_server + 18, "extsa6", ef_server_extsa6, TYPE_SA, "ipv6 address of external interface"},
#endif
{NULL, "next", ef_server_next, TYPE_SERVER, "next"} {NULL, "next", ef_server_next, TYPE_SERVER, "next"}
}; };
@ -789,17 +773,14 @@ static struct property prop_client[] = {
{prop_client + 9, "extpassword", ef_client_extpassword, TYPE_STRING, "password for requested host"}, {prop_client + 9, "extpassword", ef_client_extpassword, TYPE_STRING, "password for requested host"},
{prop_client + 10, "username", ef_client_username, TYPE_STRING, "client username"}, {prop_client + 10, "username", ef_client_username, TYPE_STRING, "client username"},
{prop_client + 11, "password", ef_client_password, TYPE_STRING, "client password"}, {prop_client + 11, "password", ef_client_password, TYPE_STRING, "client password"},
{prop_client + 12, "cliip", ef_client_cliip, TYPE_IP, "client ip"}, {prop_client + 12, "clisa", ef_client_clisa, TYPE_SA, "client sa"},
{prop_client + 13, "cliport", ef_client_cliport, TYPE_PORT, "client port"}, {prop_client + 13, "srvsa", ef_client_srvsa, TYPE_IP, "target server sa"},
{prop_client + 14, "srvip", ef_client_srvip, TYPE_IP, "target server ip"}, {prop_client + 14, "reqsa", ef_client_reqsa, TYPE_IP, "requested server sa"},
{prop_client + 15, "srvport", ef_client_srvport, TYPE_PORT, "target server port"}, {prop_client + 15, "bytesin", ef_client_bytesin64, TYPE_UNSIGNED64, "bytes from server to client"},
{prop_client + 16, "reqip", ef_client_reqip, TYPE_IP, "requested server ip"}, {prop_client + 16, "bytesout", ef_client_bytesout64, TYPE_UNSIGNED64, "bytes from client to server"},
{prop_client + 17, "reqport", ef_client_reqport, TYPE_PORT, "requested server port"}, {prop_client + 17, "maxtrafin", ef_client_maxtrafin64, TYPE_UNSIGNED64, "maximum traffic allowed for download"},
{prop_client + 18, "bytesin", ef_client_bytesin, TYPE_UNSIGNED, "bytes from server to client"}, {prop_client + 18, "maxtrafout", ef_client_maxtrafout64, TYPE_UNSIGNED64, "maximum traffic allowed for upload"},
{prop_client + 19, "bytesout", ef_client_bytesout, TYPE_UNSIGNED, "bytes from client to server"}, {prop_client + 19, "pwtype", ef_client_pwtype, TYPE_INTEGER, "type of client password"},
{prop_client + 20, "pwtype", ef_client_pwtype, TYPE_INTEGER, "type of client password"},
{prop_client + 21, "maxtrafin", ef_client_maxtrafin, TYPE_UNSIGNED, "maximum traffic allowed for download"},
{prop_client + 22, "maxtrafout", ef_client_maxtrafout, TYPE_UNSIGNED, "maximum traffic allowed for upload"},
{NULL, "next", ef_client_next, TYPE_CLIENT, "next"} {NULL, "next", ef_client_next, TYPE_CLIENT, "next"}
@ -810,16 +791,18 @@ struct datatype datatypes[64] = {
{"short", NULL, pr_short, NULL}, {"short", NULL, pr_short, NULL},
{"char", NULL, pr_char, NULL}, {"char", NULL, pr_char, NULL},
{"unsigned", NULL, pr_unsigned, NULL}, {"unsigned", NULL, pr_unsigned, NULL},
{"unsigned64", NULL, pr_unsigned64, NULL},
{"traffic", NULL, pr_traffic, NULL}, {"traffic", NULL, pr_traffic, NULL},
{"port", NULL, pr_port, NULL}, {"port", NULL, pr_port, NULL},
{"ip", NULL, pr_ip, NULL}, {"ip", NULL, pr_ip, NULL},
{"sa", NULL, pr_sa, NULL},
{"cidr", NULL, pr_cidr, NULL}, {"cidr", NULL, pr_cidr, NULL},
{"string", NULL, pr_string, NULL}, {"string", NULL, pr_string, NULL},
{"datetime", NULL, pr_datetime, NULL}, {"datetime", NULL, pr_datetime, NULL},
{"operations", NULL, pr_operations, NULL}, {"operations", NULL, pr_operations, NULL},
{"rotation", NULL, pr_rotation, NULL}, {"rotation", NULL, pr_rotation, NULL},
{"portlist", ef_portlist_next, pr_portlist, prop_portlist}, {"portlist", ef_portlist_next, pr_portlist, prop_portlist},
{"iplist", ef_iplist_next, pr_iplist, prop_iplist}, {"iplist", ef_iplist_next, pr_iplist, NULL},
{"userlist", ef_userlist_next, pr_userlist, prop_userlist}, {"userlist", ef_userlist_next, pr_userlist, prop_userlist},
{"pwlist", ef_pwlist_next, NULL, prop_pwlist}, {"pwlist", ef_pwlist_next, NULL, prop_pwlist},
{"chain", ef_chain_next, NULL, prop_chain}, {"chain", ef_chain_next, NULL, prop_chain},

View File

@ -3,7 +3,6 @@
* *
* please read License Agreement * please read License Agreement
* *
* $Id: dighosts.c,v 1.10 2009/10/06 08:38:00 v.dubrovin Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -84,12 +83,11 @@ int main(int argc, char *argv[]){
return 4; return 4;
} }
*hostend = '/'; *hostend = '/';
if(!(sa.sin_addr.s_addr = getip(host))) { if(!getip46(4, host, (struct sockaddr *)&sa)) {
fprintf(stderr, "Unable to resolve %s\n", host); fprintf(stderr, "Unable to resolve %s\n", host);
return 5; return 5;
} }
sa.sin_port = htons(80); sa.sin_port = htons(80);
sa.sin_family = AF_INET;
if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return 6; if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return 6;
sprintf((char *)buf, (char *)request, hostend, host); sprintf((char *)buf, (char *)request, hostend, host);
if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))) { if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))) {

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: dnspr.c,v 1.22 2009/09/17 12:21:05 v.dubrovin Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -14,11 +13,12 @@
#endif #endif
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; } #define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
#define BUFSIZE 4096 #define BUFSIZE 16384
void * dnsprchild(struct clientparam* param) { void * dnsprchild(struct clientparam* param) {
unsigned long ip = 0; unsigned long ip = 0;
unsigned char *bbuf;
unsigned char *buf, *s1, *s2; unsigned char *buf, *s1, *s2;
char * host = NULL; char * host = NULL;
unsigned char c; unsigned char c;
@ -27,26 +27,28 @@ void * dnsprchild(struct clientparam* param) {
int len; int len;
unsigned type=0; unsigned type=0;
unsigned ttl; unsigned ttl;
unsigned char addr[16];
#ifdef _WIN32 #ifdef _WIN32
unsigned long ul = 1; unsigned long ul = 1;
#endif #endif
if(!(buf = myalloc(BUFSIZE))){ if(!(bbuf = myalloc(BUFSIZE+2))){
param->srv->fds.events = POLLIN; param->srv->fds.events = POLLIN;
RETURN (21); RETURN (21);
} }
size = sizeof(struct sockaddr_in); buf = bbuf+2;
i = so._recvfrom(param->srv->srvsock, buf, BUFSIZE, 0, (struct sockaddr *)&param->sinc, &size); size = sizeof(param->sincr);
i = so._recvfrom(param->srv->srvsock, buf, BUFSIZE, 0, (struct sockaddr *)&param->sincr, &size);
size = sizeof(param->sinsl);
getsockname(param->srv->srvsock, (struct sockaddr *)&param->sincl, &size);
#ifdef _WIN32 #ifdef _WIN32
if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
RETURN(818); RETURN(818);
} }
ioctlsocket(param->clisock, FIONBIO, &ul); ioctlsocket(param->clisock, FIONBIO, &ul);
size = sizeof(struct sockaddr_in);
if(so._getsockname(param->srv->srvsock, (struct sockaddr *)&param->sins, &size)) {RETURN(21);};
if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);}; if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);};
if(so._bind(param->clisock,(struct sockaddr *)&param->sins,sizeof(struct sockaddr_in))) { if(so._bind(param->clisock,(struct sockaddr *)&param->sincl,sizeof(param->sincl))) {
RETURN(822); RETURN(822);
} }
@ -80,8 +82,8 @@ void * dnsprchild(struct clientparam* param) {
*s2 = (len - (int)(s2 - buf)) - 1; *s2 = (len - (int)(s2 - buf)) - 1;
type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2]; type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2];
if(type==1){ if((type==0x01 || type==0x1c) && !param->srv->singlepacket){
ip = udpresolve((unsigned char *)host, &ttl, param, 0); ip = udpresolve((type==0x1c)?AF_INET6:AF_INET, (unsigned char *)host, addr, &ttl, param, 0);
} }
len+=5; len+=5;
@ -95,19 +97,19 @@ void * dnsprchild(struct clientparam* param) {
memset(buf+len, 0, 16); memset(buf+len, 0, 16);
buf[len] = 0xc0; buf[len] = 0xc0;
buf[len+1] = 0x0c; buf[len+1] = 0x0c;
buf[len+3] = 1; buf[len+3] = type;
buf[len+5] = 1; buf[len+5] = 1;
ttl = htonl(ttl); ttl = htonl(ttl);
memcpy(buf + len + 6, &ttl, 4); memcpy(buf + len + 6, &ttl, 4);
buf[len+11] = 4; buf[len+11] = type==1? 4:16;
memcpy(buf+len+12,(void *)&ip,4); memcpy(buf+len+12,(void *)&addr,type==1? 4:16);
len+=16; len+=(type==1?16:28);
} }
if(type == 0x0c) { else if(type == 0x0c) {
unsigned a, b, c, d; unsigned a, b, c, d;
sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d); sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d);
ip = htonl((d<<24) ^ (c<<16) ^ (b<<8) ^ a); ip = htonl((d<<24) ^ (c<<16) ^ (b<<8) ^ a);
if(ip == param->srv->intip){ if(*SAFAMILY(&param->sincl) == AF_INET && ip == *(unsigned long*)SAADDR(&param->sincl)){
buf[2] = 0x85; buf[2] = 0x85;
buf[3] = 0x80; buf[3] = 0x80;
buf[6] = 0; buf[6] = 0;
@ -127,36 +129,52 @@ void * dnsprchild(struct clientparam* param) {
} }
else ip = 0; else ip = 0;
} }
if(!ip && nservers[0] && type!=1){ if(!ip && numservers){
if((param->remsock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { if((param->remsock=so._socket(SASOCK(&nservers[0].addr), nservers[0].usetcp? SOCK_STREAM:SOCK_DGRAM, nservers[0].usetcp?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {
RETURN(818); RETURN(818);
} }
#ifdef _WIN32 memset(&param->sinsl, 0, sizeof(param->sinsl));
ioctlsocket(param->remsock, FIONBIO, &ul); *SAFAMILY(&param->sinsl) = *SAFAMILY(&nservers[0].addr);
#else if(so._bind(param->remsock,(struct sockaddr *)&param->sinsl,sizeof(param->sinsl))) {
fcntl(param->remsock,F_SETFL,O_NONBLOCK);
#endif
param->sins.sin_family = AF_INET;
param->sins.sin_port = htons(0);
param->sins.sin_addr.s_addr = htonl(0);
if(so._bind(param->remsock,(struct sockaddr *)&param->sins,sizeof(struct sockaddr_in))) {
RETURN(819); RETURN(819);
} }
param->sins.sin_addr.s_addr = nservers[0]; memcpy(&param->sinsr, &nservers[0].addr, sizeof(param->sinsr));
param->sins.sin_port = htons(53); if(nservers[0].usetcp) {
if(socksendto(param->remsock, &param->sins, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){ if(so._connect(param->remsock,(struct sockaddr *)&param->sinsr,sizeof(param->sinsr))) RETURN(830);
buf-=2;
*(unsigned short*)buf = htons(i);
i+=2;
}
else {
#ifdef _WIN32
/* ioctlsocket(param->remsock, FIONBIO, &ul); */
#else
/* fcntl(param->remsock,F_SETFL,O_NONBLOCK); */
#endif
}
if(socksendto(param->remsock, (struct sockaddr *)&param->sinsr, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){
RETURN(820); RETURN(820);
} }
param->statscli += i; param->statscli64 += i;
param->nwrites++; param->nwrites++;
len = sockrecvfrom(param->remsock, &param->sins, buf, BUFSIZE, 15000); len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sinsr, buf, BUFSIZE, 15000);
if(len <= 13) { if(len <= 13) {
RETURN(821); RETURN(821);
} }
param->statssrv += len; param->statssrv64 += len;
param->nreads++; param->nreads++;
if(nservers[0].usetcp) {
unsigned short us;
us = ntohs(*(unsigned short *)buf);
if(us > 4096) RETURN(833);
buf += 2;
len -= 2;
if(len < us) len += sockgetlinebuf(param, SERVER, buf+len, us - len, 0, conf.timeouts[SINGLEBYTE_L]);
if(len != us) RETURN(832);
}
if(buf[6] || buf[7]){ if(buf[6] || buf[7]){
if(socksendto(param->clisock, &param->sinc, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){ if(socksendto(param->clisock, (struct sockaddr *)&param->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
RETURN(822); RETURN(822);
} }
RETURN(0); RETURN(0);
@ -167,25 +185,22 @@ void * dnsprchild(struct clientparam* param) {
buf[2] = 0x85; buf[2] = 0x85;
buf[3] = 0x83; buf[3] = 0x83;
} }
usleep(SLEEPTIME); res = socksendto(param->clisock, (struct sockaddr *)&param->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000);
res = socksendto(param->clisock, &param->sinc, buf, len, conf.timeouts[SINGLEBYTE_L]*1000);
if(res != len){RETURN(819);} if(res != len){RETURN(819);}
if(!ip) {RETURN(888);} if(!ip) {RETURN(888);}
CLEANRET: CLEANRET:
if(param->res!=813){ if(param->res!=813){
sprintf((char *)buf, "%04x/%s(%u.%u.%u.%u)", sprintf((char *)buf, "%04x/%s/",
(unsigned)type, (unsigned)type,
host?host:"", host?host:"");
(unsigned)(ntohl(ip)&0xff000000)>>24, if(ip && type == 0x01 || type == 0x1c){
(unsigned)(ntohl(ip)&0x00ff0000)>>16, myinet_ntop(type == 0x01? AF_INET:AF_INET6, addr, buf+strlen(buf), 64);
(unsigned)(ntohl(ip)&0x0000ff00)>>8, }
(unsigned)(ntohl(ip)&0x000000ff)
);
(*param->srv->logfunc)(param, buf); (*param->srv->logfunc)(param, buf);
} }
if(buf)myfree(buf); if(bbuf)myfree(bbuf);
if(host)myfree(host); if(host)myfree(host);
#ifndef _WIN32 #ifndef _WIN32
param->clisock = INVALID_SOCKET; param->clisock = INVALID_SOCKET;

View File

@ -3,7 +3,6 @@
* *
* please read License Agreement * please read License Agreement
* *
* $Id: ftp.c,v 1.34 2009/09/17 12:21:06 v.dubrovin Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -33,7 +32,7 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) {
if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){ if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
return 703; return 703;
} }
param->statscli += (int)strlen(buf); param->statscli64 += (int)strlen(buf);
param->nwrites++; param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){ while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
} }
@ -50,7 +49,7 @@ int ftplogin(struct clientparam *param, char *nbuf, int *innbuf) {
if((int)socksend(param->remsock, (unsigned char *)buf, res, conf.timeouts[STRING_S]) != (int)strlen(buf)){ if((int)socksend(param->remsock, (unsigned char *)buf, res, conf.timeouts[STRING_S]) != (int)strlen(buf)){
return 705; return 705;
} }
param->statscli += res; param->statscli64 += res;
param->nwrites++; param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0){ while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0){
buf[i] = 0; buf[i] = 0;
@ -81,7 +80,7 @@ int ftpcd(struct clientparam *param, unsigned char* path, char *nbuf, int *innbu
if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){ if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
return 711; return 711;
} }
param->statscli += (int)strlen(buf); param->statscli64 += (int)strlen(buf);
param->nwrites++; param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){ while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
if(nbuf && innbuf && inbuf + i < *innbuf && i > 6) { if(nbuf && innbuf && inbuf + i < *innbuf && i > 6) {
@ -114,7 +113,7 @@ int ftpsyst(struct clientparam *param, unsigned char *buf, unsigned len){
if(socksend(param->remsock, (unsigned char *)"SYST\r\n", 6, conf.timeouts[STRING_S]) != 6){ if(socksend(param->remsock, (unsigned char *)"SYST\r\n", 6, conf.timeouts[STRING_S]) != 6){
return 721; return 721;
} }
param->statscli+=6; param->statscli64 += 6;
param->nwrites++; param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){ while((i = sockgetlinebuf(param, SERVER, buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
} }
@ -133,7 +132,7 @@ int ftppwd(struct clientparam *param, unsigned char *buf, unsigned len){
if(socksend(param->remsock, (unsigned char *)"PWD\r\n", 5, conf.timeouts[STRING_S]) != 5){ if(socksend(param->remsock, (unsigned char *)"PWD\r\n", 5, conf.timeouts[STRING_S]) != 5){
return 731; return 731;
} }
param->statscli += 5; param->statscli64 += 5;
param->nwrites++; param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){ while((i = sockgetlinebuf(param, SERVER, buf, len - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
} }
@ -158,7 +157,7 @@ int ftptype(struct clientparam *param, unsigned char* f_type){
if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){ if((int)socksend(param->remsock, (unsigned char *)buf, (int)strlen(buf), conf.timeouts[STRING_S]) != (int)strlen(buf)){
return 741; return 741;
} }
param->statscli += (int)strlen(buf); param->statscli64 += (int)strlen(buf);
param->nwrites++; param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){ while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
} }
@ -179,7 +178,7 @@ SOCKET ftpdata(struct clientparam *param){
if(socksend(param->remsock, (unsigned char *)"PASV\r\n", 6, conf.timeouts[STRING_S]) != 6){ if(socksend(param->remsock, (unsigned char *)"PASV\r\n", 6, conf.timeouts[STRING_S]) != 6){
return INVALID_SOCKET; return INVALID_SOCKET;
} }
param->statscli+=6; param->statscli64 += 6;
param->nwrites++; param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){ while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
} }
@ -190,12 +189,14 @@ SOCKET ftpdata(struct clientparam *param){
if(sscanf(sb+1, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) return INVALID_SOCKET; if(sscanf(sb+1, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) return INVALID_SOCKET;
rem = param->remsock; rem = param->remsock;
param->remsock = INVALID_SOCKET; param->remsock = INVALID_SOCKET;
param->req.sin_family = AF_INET; memcpy(&param->req,&param->sinsr,sizeof(param->req));
param->req.sin_port = param->sins.sin_port = htons((unsigned short)((b5<<8)^b6)); *SAPORT(&param->req) = *SAPORT(&param->sinsr) = htons((unsigned short)((b5<<8)^b6));
param->req.sin_addr.s_addr = param->sins.sin_addr.s_addr = htonl((b1<<24)^(b2<<16)^(b3<<8)^b4);
i = param->operation; i = param->operation;
param->operation = FTP_DATA; param->operation = FTP_DATA;
if((param->res = (*param->srv->authfunc)(param))) return INVALID_SOCKET; if((param->res = (*param->srv->authfunc)(param))) {
param->remsock = rem;
return INVALID_SOCKET;
}
param->operation = i; param->operation = i;
s = param->remsock; s = param->remsock;
param->remsock = rem; param->remsock = rem;
@ -217,7 +218,7 @@ SOCKET ftpcommand(struct clientparam *param, unsigned char * command, unsigned c
so._closesocket(s); so._closesocket(s);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
param->statscli += (int)strlen(buf); param->statscli64 += (int)strlen(buf);
param->nwrites++; param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){ while((i = sockgetlinebuf(param, SERVER, (unsigned char *)buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L])) > 0 && (i < 3 || !isnumber(*buf) || buf[3] == '-')){
} }

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: ftppr.c,v 1.45 2011-08-15 19:52:27 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -71,7 +70,7 @@ void * ftpprchild(struct clientparam* param) {
param->res = res; param->res = res;
if(inbuf && inbuf != BUFSIZE && socksend(param->ctrlsock, buf, inbuf, conf.timeouts[STRING_S])!=inbuf) {RETURN (807);} if(inbuf && inbuf != BUFSIZE && socksend(param->ctrlsock, buf, inbuf, conf.timeouts[STRING_S])!=inbuf) {RETURN (807);}
if(!res) status = 3; if(!res) status = 3;
sprintf((char *)buf, "%.64s@%.128s%c%hu", param->extusername, param->hostname, (ntohs(param->sins.sin_port)==21)?0:':', ntohs(param->sins.sin_port)); sprintf((char *)buf, "%.64s@%.128s%c%hu", param->extusername, param->hostname, (ntohs(*SAPORT(&param->sinsr))==21)?0:':', ntohs(*SAPORT(&param->sinsr)));
req = mystrdup((char *)buf); req = mystrdup((char *)buf);
#ifndef WITHMAIN #ifndef WITHMAIN
{ {
@ -119,21 +118,25 @@ void * ftpprchild(struct clientparam* param) {
so._closesocket(clidatasock); so._closesocket(clidatasock);
clidatasock = INVALID_SOCKET; clidatasock = INVALID_SOCKET;
} }
if ((clidatasock=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN(821);} if ((clidatasock=socket(SASOCK(&param->sincl), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN(821);}
sasize = sizeof(struct sockaddr_in); sasize = sizeof(param->sincl);
if(so._getsockname(param->ctrlsock, (struct sockaddr *)&param->sinc, &sasize)){RETURN(824);} *SAPORT(&param->sincl) = 0;
param->sinc.sin_port = 0; if(so._bind(clidatasock, (struct sockaddr *)&param->sincl, sasize)){RETURN(822);}
if(so._bind(clidatasock, (struct sockaddr *)&param->sinc, sasize)){RETURN(822);}
if (pasv) { if (pasv) {
if(so._listen(clidatasock, 1)) {RETURN(823);} if(so._listen(clidatasock, 1)) {RETURN(823);}
if(so._getsockname(clidatasock, (struct sockaddr *)&param->sinc, &sasize)){RETURN(824);} if(so._getsockname(clidatasock, (struct sockaddr *)&param->sincl, &sasize)){RETURN(824);}
if(*SAFAMILY(&param->sincl) == AF_INET)
sprintf((char *)buf, "227 OK (%u,%u,%u,%u,%u,%u)\r\n", sprintf((char *)buf, "227 OK (%u,%u,%u,%u,%u,%u)\r\n",
(unsigned)(((unsigned char *)(&param->sinc.sin_addr.s_addr))[0]), (unsigned)(((unsigned char *)(SAADDR(&param->sincl)))[0]),
(unsigned)(((unsigned char *)(&param->sinc.sin_addr.s_addr))[1]), (unsigned)(((unsigned char *)(SAADDR(&param->sincl)))[1]),
(unsigned)(((unsigned char *)(&param->sinc.sin_addr.s_addr))[2]), (unsigned)(((unsigned char *)(SAADDR(&param->sincl)))[2]),
(unsigned)(((unsigned char *)(&param->sinc.sin_addr.s_addr))[3]), (unsigned)(((unsigned char *)(SAADDR(&param->sincl)))[3]),
(unsigned)(((unsigned char *)(&param->sinc.sin_port))[0]), (unsigned)(((unsigned char *)(SAPORT(&param->sincl)))[0]),
(unsigned)(((unsigned char *)(&param->sinc.sin_port))[1]) (unsigned)(((unsigned char *)(SAPORT(&param->sincl)))[1])
);
else sprintf((char *)buf, "227 OK (127,0,0,1,%u,%u)\r\n",
(unsigned)(((unsigned char *)(SAPORT(&param->sincl)))[0]),
(unsigned)(((unsigned char *)(SAPORT(&param->sincl)))[1])
); );
} }
else { else {
@ -141,10 +144,9 @@ void * ftpprchild(struct clientparam* param) {
unsigned short b5, b6; unsigned short b5, b6;
if(sscanf((char *)buf+5, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) {RETURN(828);} if(sscanf((char *)buf+5, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) {RETURN(828);}
param->sinc.sin_family = AF_INET; *SAPORT(&param->sincr) = htons((unsigned short)((b5<<8)^b6));
param->sinc.sin_port = htons((unsigned short)((b5<<8)^b6)); sasize = sizeof(param->sincr);
param->sinc.sin_addr.s_addr = htonl((b1<<24)^(b2<<16)^(b3<<8)^b4); if(so._connect(clidatasock, (struct sockaddr *)&param->sincr, sasize)) {
if(so._connect(clidatasock, (struct sockaddr *)&param->sinc, sasize)) {
so._closesocket(clidatasock); so._closesocket(clidatasock);
clidatasock = INVALID_SOCKET; clidatasock = INVALID_SOCKET;
RETURN(826); RETURN(826);
@ -203,8 +205,8 @@ void * ftpprchild(struct clientparam* param) {
if(res != 1) { if(res != 1) {
RETURN(857); RETURN(857);
} }
sasize = sizeof(struct sockaddr_in); sasize = sizeof(param->sincr);
ss = so._accept(clidatasock, (struct sockaddr *)&param->sinc, &sasize); ss = so._accept(clidatasock, (struct sockaddr *)&param->sincr, &sasize);
if (ss == INVALID_SOCKET) { RETURN (858);} if (ss == INVALID_SOCKET) { RETURN (858);}
so._shutdown(clidatasock, SHUT_RDWR); so._shutdown(clidatasock, SHUT_RDWR);
so._closesocket(clidatasock); so._closesocket(clidatasock);
@ -274,7 +276,7 @@ void * ftpprchild(struct clientparam* param) {
buf[i++] = '\r'; buf[i++] = '\r';
buf[i++] = '\n'; buf[i++] = '\n';
if(socksend(param->remsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (811);} if(socksend(param->remsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (811);}
param->statscli += i; param->statscli64+=(i);
param->nwrites++; param->nwrites++;
while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', conf.timeouts[STRING_L])) > 0){ while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', conf.timeouts[STRING_L])) > 0){
if(socksend(param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (812);} if(socksend(param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (812);}
@ -283,9 +285,9 @@ void * ftpprchild(struct clientparam* param) {
if(status == 5) {RETURN (0);} if(status == 5) {RETURN (0);}
if(i < 3) {RETURN (813);} if(i < 3) {RETURN (813);}
} }
sasize = sizeof(struct sockaddr_in); sasize = sizeof(param->sincr);
if(so._getpeername(param->ctrlsock, (struct sockaddr *)&param->sinc, &sasize)){RETURN(819);} if(so._getpeername(param->ctrlsock, (struct sockaddr *)&param->sincr, &sasize)){RETURN(819);}
if(req && (param->statscli || param->statssrv)){ if(req && (param->statscli64 || param->statssrv64)){
(*param->srv->logfunc)(param, (unsigned char *)req); (*param->srv->logfunc)(param, (unsigned char *)req);
} }
} }
@ -304,9 +306,9 @@ CLEANRET:
so._shutdown(clidatasock, SHUT_RDWR); so._shutdown(clidatasock, SHUT_RDWR);
so._closesocket(clidatasock); so._closesocket(clidatasock);
} }
sasize = sizeof(struct sockaddr_in); sasize = sizeof(param->sincr);
so._getpeername(param->ctrlsock, (struct sockaddr *)&param->sinc, &sasize); so._getpeername(param->ctrlsock, (struct sockaddr *)&param->sincr, &sasize);
if(param->res != 0 || param->statscli || param->statssrv ){ if(param->res != 0 || param->statscli64 || param->statssrv64 ){
(*param->srv->logfunc)(param, (unsigned char *)((req && (param->res > 802))? req:NULL)); (*param->srv->logfunc)(param, (unsigned char *)((req && (param->res > 802))? req:NULL));
} }
if(req) myfree(req); if(req) myfree(req);

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: icqpr.c,v 1.30 2012-04-11 23:01:19 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -105,11 +104,11 @@ static void addbuffer(int increment, struct clientparam * param, unsigned char *
*buf_p = newbuf; *buf_p = newbuf;
*bufsize_p = bufsize; *bufsize_p = bufsize;
} }
if(increment) len = sockrecvfrom(param->remsock, &param->sins, *buf_p + *length_p, increment, conf.timeouts[STRING_S]*1000); if(increment) len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sinsr, *buf_p + *length_p, increment, conf.timeouts[STRING_S]*1000);
if(len > 0) { if(len > 0) {
*length_p += len; *length_p += len;
param->nreads++; param->nreads++;
param->statssrv += len; param->statssrv64 += len;
} }
return; return;
} }
@ -118,7 +117,7 @@ static void addbuffer(int increment, struct clientparam * param, unsigned char *
static int searchcookie(struct clientparam *param, struct flap_header * flap, int len, int * dif, struct tlv_header *tlv, int extra){ static int searchcookie(struct clientparam *param, struct flap_header * flap, int len, int * dif, struct tlv_header *tlv, int extra){
struct icq_cookie *ic; struct icq_cookie *ic;
char smallbuf[32]; char smallbuf[64];
struct tlv_header *bostlv = NULL; struct tlv_header *bostlv = NULL;
struct sockaddr_in sa; struct sockaddr_in sa;
SASIZETYPE size = sizeof(sa); SASIZETYPE size = sizeof(sa);
@ -165,7 +164,7 @@ static int searchcookie(struct clientparam *param, struct flap_header * flap, in
pthread_mutex_unlock(&icq_cookie_mutex); pthread_mutex_unlock(&icq_cookie_mutex);
if(bostlv){ if(bostlv){
if(so._getsockname(param->clisock, (struct sockaddr *)&sa, &size)==-1) return 1; if(so._getsockname(param->clisock, (struct sockaddr *)&sa, &size)==-1) return 1;
len = myinet_ntoa(sa.sin_addr, smallbuf); len = myinet_ntop(*SAFAMILY(&sa),SAADDR(&sa), smallbuf, 64);
if(strchr(ic->connectstring, ':'))sprintf(smallbuf+len, ":%hu", ntohs(sa.sin_port)); if(strchr(ic->connectstring, ':'))sprintf(smallbuf+len, ":%hu", ntohs(sa.sin_port));
len = (int)strlen(smallbuf); len = (int)strlen(smallbuf);
*dif = len - (int)ntohs(bostlv->size); *dif = len - (int)ntohs(bostlv->size);
@ -437,20 +436,17 @@ void * icqprchild(struct clientparam* param) {
if(greet){ if(greet){
if(socksend(param->remsock, tmpsend, 10, conf.timeouts[STRING_S])!=10) {RETURN (1105);} if(socksend(param->remsock, tmpsend, 10, conf.timeouts[STRING_S])!=10) {RETURN (1105);}
param->statscli += 10; param->statscli64 += 10;
} }
if(readflap(param, SERVER, tmpsend, 1024)) {RETURN (1111);} if(readflap(param, SERVER, tmpsend, 1024)) {RETURN (1111);}
param->statssrv += (ntohs(((struct flap_header *)tmpsend)->size) + 6); param->statssrv64 += (ntohs(((struct flap_header *)tmpsend)->size) + 6);
mystate.srvseq = ntohs(((struct flap_header *)tmpsend)->seq) + 1; mystate.srvseq = ntohs(((struct flap_header *)tmpsend)->seq) + 1;
mystate.seq = 1; mystate.seq = 1;
len = ntohs(flap->size) + 6; len = ntohs(flap->size) + 6;
if((res=handledatfltcli(param, &buf, &buflen, offset, &len))!=PASS) RETURN(res); if((res=handledatfltcli(param, &buf, &buflen, offset, &len))!=PASS) RETURN(res);
if(socksend(param->remsock, buf+offset, len, conf.timeouts[STRING_S])!=(ntohs(flap->size)+6)) {RETURN (1106);} if(socksend(param->remsock, buf+offset, len, conf.timeouts[STRING_S])!=(ntohs(flap->size)+6)) {RETURN (1106);}
offset = 0; offset = 0;
param->statscli += len; param->statscli64 += len;
if(logintype == ICQMD5) { if(logintype == ICQMD5) {
if(readflap(param, SERVER, buf, 65550)) {RETURN (1112);} if(readflap(param, SERVER, buf, 65550)) {RETURN (1112);}
@ -466,7 +462,7 @@ void * icqprchild(struct clientparam* param) {
len = ntohs(flap->size) + 6; len = ntohs(flap->size) + 6;
if((res=handledatfltcli(param, &buf, &buflen, offset, &len))!=PASS) RETURN(res); if((res=handledatfltcli(param, &buf, &buflen, offset, &len))!=PASS) RETURN(res);
if(socksend(param->remsock, buf+offset, len, conf.timeouts[STRING_S])!=len) {RETURN (1115);} if(socksend(param->remsock, buf+offset, len, conf.timeouts[STRING_S])!=len) {RETURN (1115);}
param->statscli += len; param->statscli64 += len;
offset = 0; offset = 0;
} }
if(logintype != ICQCOOKIE) { if(logintype != ICQCOOKIE) {

View File

@ -1,8 +1,6 @@
/* /*
* md4c.c MD4 message-digest algorithm * md4c.c MD4 message-digest algorithm
* *
* Version: $Id: md4.c,v 1.1 2010-11-11 11:32:32 v.dubrovin Exp $
*
* License to copy and use this software is granted provided that it * License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD4 Message-Digest * is identified as the "RSA Data Security, Inc. MD4 Message-Digest
* Algorithm" in all material mentioning or referencing this software * Algorithm" in all material mentioning or referencing this software

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: myalloc.c,v 1.5 2008/01/08 21:46:38 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -333,7 +332,7 @@ void *myrealloc(void *ptr, size_t size){
if(size <= memsizes[l]) return ptr; if(size <= memsizes[l]) return ptr;
p = myalloc(size); p = myalloc(size);
if(p){ if(p){
memcpy(p,ptr,size); memmove(p,ptr,size);
myfree(ptr); myfree(ptr);
} }
return p; return p;

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: mycrypt.c,v 1.8 2008/01/08 21:46:38 vlad Exp $
*/ */
#include "libs/md5.h" #include "libs/md5.h"
#include "libs/md4.h" #include "libs/md4.h"

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: ntlm.c,v 1.9 2008/01/08 21:46:38 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -81,8 +80,8 @@ void genchallenge(struct clientparam *param, char * challenge, char *buf){
chal->flags[3] = 0xA0; chal->flags[3] = 0xA0;
text2unicode(hostname, (char *)chal->data, 64); text2unicode(hostname, (char *)chal->data, 64);
time((time_t *)challenge); time((time_t *)challenge);
memcpy(challenge+4, &param->sinc.sin_addr.s_addr, 4); memcpy(challenge+4, SAADDR(&param->sincr), 4);
challenge[1]^=param->sinc.sin_port; challenge[1]^=*SAPORT(&param->sincr);
for(i = 0; i < 8; i++) challenge[i] ^= myrand(challenge, 8); for(i = 0; i < 8; i++) challenge[i] ^= myrand(challenge, 8);
memcpy(chal->challenge, challenge, 8); memcpy(chal->challenge, challenge, 8);
en64((unsigned char *)tmpbuf, (unsigned char *)buf, (int)((unsigned char *)chal->data - (unsigned char *)chal) + len); en64((unsigned char *)tmpbuf, (unsigned char *)buf, (int)((unsigned char *)chal->data - (unsigned char *)chal) + len);

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: ntlm.c,v 1.8 2007/12/27 13:20:04 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -33,10 +32,10 @@ struct symbol symbols[] = {
{symbols+5, "sockgetcharcli", (void *) sockgetcharcli}, {symbols+5, "sockgetcharcli", (void *) sockgetcharcli},
{symbols+6, "sockgetcharsrv", (void *) sockgetcharsrv}, {symbols+6, "sockgetcharsrv", (void *) sockgetcharsrv},
{symbols+7, "sockgetlinebuf", (void *) sockgetlinebuf}, {symbols+7, "sockgetlinebuf", (void *) sockgetlinebuf},
{symbols+8, "myinet_ntoa", (void *) myinet_ntoa}, {symbols+8, "myinet_ntop", (void *) myinet_ntop},
{symbols+9, "dobuf", (void *) dobuf}, {symbols+9, "dobuf", (void *) dobuf},
{symbols+10, "scanaddr", (void *) scanaddr}, {symbols+10, "scanaddr", (void *) scanaddr},
{symbols+11, "getip", (void *) getip}, {symbols+11, "getip46", (void *) getip46},
{symbols+12, "sockmap", (void *) sockmap}, {symbols+12, "sockmap", (void *) sockmap},
{symbols+13, "sockfuncs", (void *) &so}, {symbols+13, "sockfuncs", (void *) &so},
{symbols+14, "ACLmatches", (void *) ACLmatches}, {symbols+14, "ACLmatches", (void *) ACLmatches},
@ -44,40 +43,41 @@ struct symbol symbols[] = {
{symbols+16, "trafcountfunc", (void *) trafcountfunc}, {symbols+16, "trafcountfunc", (void *) trafcountfunc},
{symbols+17, "alwaysauth", (void *) alwaysauth}, {symbols+17, "alwaysauth", (void *) alwaysauth},
{symbols+18, "ipauth", (void *) ipauth}, {symbols+18, "ipauth", (void *) ipauth},
{symbols+19, "nbnameauth", (void *) nbnameauth}, {symbols+19, "strongauth", (void *) strongauth},
{symbols+20, "strongauth", (void *) strongauth}, {symbols+20, "checkACL", (void *) checkACL},
{symbols+21, "checkACL", (void *) checkACL}, {symbols+21, "nametohash", (void *) nametohash},
{symbols+22, "nametohash", (void *) nametohash}, {symbols+22, "hashindex", (void *) hashindex},
{symbols+23, "hashindex", (void *) hashindex}, {symbols+23, "nservers", (void *) nservers},
{symbols+24, "nservers", (void *) nservers}, {symbols+24, "udpresolve", (void *) udpresolve},
{symbols+25, "udpresolve", (void *) udpresolve}, {symbols+25, "bandlim_mutex", (void *) &bandlim_mutex},
{symbols+26, "bandlim_mutex", (void *) &bandlim_mutex}, {symbols+26, "tc_mutex", (void *) &tc_mutex},
{symbols+27, "tc_mutex", (void *) &tc_mutex}, {symbols+27, "hash_mutex", (void *) &hash_mutex},
{symbols+28, "hash_mutex", (void *) &hash_mutex}, {symbols+28, "pwl_mutex", (void *) &pwl_mutex},
{symbols+29, "pwl_mutex", (void *) &pwl_mutex}, {symbols+29, "linenum", (void *) &linenum},
{symbols+30, "linenum", (void *) &linenum}, {symbols+30, "proxy_stringtable", (void *) proxy_stringtable},
{symbols+31, "proxy_stringtable", (void *) proxy_stringtable}, {symbols+31, "en64", (void *) en64},
{symbols+32, "en64", (void *) en64}, {symbols+32, "de64", (void *) de64},
{symbols+33, "de64", (void *) de64}, {symbols+33, "tohex", (void *) tohex},
{symbols+34, "tohex", (void *) tohex}, {symbols+34, "fromhex", (void *) fromhex},
{symbols+35, "fromhex", (void *) fromhex}, {symbols+35, "dnspr", (void *) dnsprchild},
{symbols+36, "dnspr", (void *) dnsprchild}, {symbols+36, "pop3p", (void *) pop3pchild},
{symbols+37, "pop3p", (void *) pop3pchild}, {symbols+37, "proxy", (void *) proxychild},
{symbols+38, "proxy", (void *) proxychild}, {symbols+38, "socks", (void *) sockschild},
{symbols+39, "socks", (void *) sockschild}, {symbols+39, "tcppm", (void *) tcppmchild},
{symbols+40, "tcppm", (void *) tcppmchild}, {symbols+40, "udppm", (void *) udppmchild},
{symbols+41, "udppm", (void *) udppmchild}, {symbols+41, "admin", (void *) adminchild},
{symbols+42, "admin", (void *) adminchild}, {symbols+42, "ftppr", (void *) ftpprchild},
{symbols+43, "ftppr", (void *) ftpprchild}, {symbols+43, "smtpp", (void *) smtppchild},
{symbols+44, "smtpp", (void *) smtppchild}, {symbols+44, "icqpr", (void *) icqprchild},
{symbols+45, "icqpr", (void *) icqprchild}, /*
{symbols+46, "msnpr", (void *) msnprchild}, {symbols+45, "msnpr", (void *) msnprchild},
{symbols+47, "authfuncs", (void *) &authfuncs}, */
{symbols+48, "commandhandlers", (void *) &commandhandlers}, {symbols+45, "authfuncs", (void *) &authfuncs},
{symbols+49, "decodeurl", (void *) decodeurl}, {symbols+46, "commandhandlers", (void *) &commandhandlers},
{symbols+50, "parsestr", (void *) parsestr}, {symbols+47, "decodeurl", (void *) decodeurl},
{symbols+51, "make_ace", (void *) make_ace}, {symbols+48, "parsestr", (void *) parsestr},
{symbols+52, "freeacl", (void *) freeacl}, {symbols+49, "make_ace", (void *) make_ace},
{symbols+50, "freeacl", (void *) freeacl},
{NULL, "", NULL} {NULL, "", NULL}
}; };
@ -103,11 +103,11 @@ struct pluginlink pluginlink = {
sockgetcharcli, sockgetcharcli,
sockgetcharsrv, sockgetcharsrv,
sockgetlinebuf, sockgetlinebuf,
myinet_ntoa, myinet_ntop,
dobuf, dobuf,
dobuf2, dobuf2,
scanaddr, scanaddr,
getip, getip46,
sockmap, sockmap,
ACLmatches, ACLmatches,
alwaysauth, alwaysauth,

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: FilePlugin.c,v 1.8 2012-04-11 23:01:22 vlad Exp $
*/ */
#include "../../structures.h" #include "../../structures.h"
@ -847,6 +846,36 @@ static struct symbol fp_symbols[] = {
{NULL, "fp_stringtable", (void*) fp_stringtable} {NULL, "fp_stringtable", (void*) fp_stringtable}
}; };
static int h_cachedir(int argc, unsigned char **argv){
char * dirp;
size_t len;
dirp = (argc > 1)? argv[1] : getenv("TEMP");
len = strlen(dirp);
if(!dirp || !len || len > 200 || strchr(dirp, '%')) {
fprintf(stderr, "FilePlugin: invalid directory path: %s\n", dirp);
return (1);
}
#ifdef _WIN32
if(dirp[len-1] == '\\') dirp[len-1] = 0;
sprintf(path, "%.256s\\%%07d.tmp", dirp);
#else
if(dirp[len-1] == '/') dirp[len-1] = 0;
sprintf(path, "%.256s/%%07d.tmp", dirp);
#endif
return 0;
}
static int h_preview(int argc, unsigned char **argv){
preview = atoi(argv[1]);
return 0;
}
static struct commands file_commandhandlers[] = {
{file_commandhandlers + 1, "file_cachedir", h_cachedir, 2, 2},
{NULL, "file_preview", h_preview, 2, 2},
};
static int file_loaded=0; static int file_loaded=0;
@ -858,7 +887,6 @@ __declspec(dllexport)
int file_plugin (struct pluginlink * pluginlink, int file_plugin (struct pluginlink * pluginlink,
int argc, char** argv){ int argc, char** argv){
char * dirp;
if(!file_loaded){ if(!file_loaded){
pthread_mutex_init(&file_mutex, NULL); pthread_mutex_init(&file_mutex, NULL);
file_loaded = 1; file_loaded = 1;
@ -875,19 +903,11 @@ __declspec(dllexport)
pl->conf->filters = &fp_filter; pl->conf->filters = &fp_filter;
fp_symbols[1].next = pl->symbols.next; fp_symbols[1].next = pl->symbols.next;
pl->symbols.next = fp_symbols; pl->symbols.next = fp_symbols;
file_commandhandlers[1].next = pl->commandhandlers->next;
pl->commandhandlers->next = file_commandhandlers;
} }
dirp = (argc > 1)? argv[1] : getenv("TEMP"); h_cachedir(0, NULL);
if(strlen(dirp) > 200 || strchr(dirp, '%')) { preview = 32768;
fprintf(stderr, "FilePlugin: invalid directory path: %s\n", dirp);
return (13001);
}
#ifdef _WIN32
sprintf(path, "%.256s\\%%07d.tmp", dirp);
#else
sprintf(path, "%.256s/%%07d.tmp", dirp);
#endif
if(argc > 2) preview = atoi(argv[2]);
if(!preview) preview = 32768;
return 0; return 0;

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: pcre_plugin.c,v 1.11 2012-04-25 18:17:22 vlad Exp $
*/ */
#include "../../structures.h" #include "../../structures.h"
@ -230,12 +229,12 @@ static int h_pcre(int argc, unsigned char **argv){
struct filter *newf; struct filter *newf;
char *replace = NULL; char *replace = NULL;
if(!strcmp(argv[2], "allow")) action = PASS; if(!strncmp(argv[2], "allow",5)) action = PASS;
else if(!strcmp(argv[2], "deny")) action = REJECT; else if(!strncmp(argv[2], "deny",4)) action = REJECT;
else if(!strcmp(argv[2], "remove")) action = REMOVE; else if(!strncmp(argv[2], "remove",6)) action = REMOVE;
else if(!strcmp(argv[2], "dunno")) action = CONTINUE; else if(!strncmp(argv[2], "dunno",5)) action = CONTINUE;
else return 1; else return 1;
if(!strcmp(argv[0], "pcre_rewrite")) { if(!strncmp(argv[0], "pcre_rewrite", 12)) {
int i,j; int i,j;
offset = 5; offset = 5;
replace = pl->mystrdup(argv[4]); replace = pl->mystrdup(argv[4]);
@ -267,6 +266,7 @@ static int h_pcre(int argc, unsigned char **argv){
replace[j] = 0; replace[j] = 0;
} }
if(!(acl = pl->make_ace(argc - offset, argv + offset))) return 2; if(!(acl = pl->make_ace(argc - offset, argv + offset))) return 2;
acl->nolog = (strstr(argv[2],"log") == 0);
if(*argv[3] && !(*argv[3] == '*' && !argv[3][1]) ){ if(*argv[3] && !(*argv[3] == '*' && !argv[3][1]) ){
re = pcre_compile((char *)argv[3], pcre_options, &errptr, &offset, NULL); re = pcre_compile((char *)argv[3], pcre_options, &errptr, &offset, NULL);
if(!re) { if(!re) {

View File

@ -19,7 +19,7 @@ static int already_loaded = 0;
static struct auth pamauth; static struct auth pamauth;
#ifdef USERCASE #ifdef USERCASE
static int usercaselow = 0; static int usercaselow = 0;
#edif #endif
static unsigned char *service=NULL; static unsigned char *service=NULL;
static struct pluginlink * pl; static struct pluginlink * pl;

View File

@ -2,12 +2,11 @@
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#include "../../structures.h" #include "../../structures.h"
#include "../../proxy.h"
#include "my_ssl.h"
#include <memory.h> #include <memory.h>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#ifndef _WIN32
#include <sys/file.h>
#endif
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/x509.h> #include <openssl/x509.h>
@ -16,6 +15,12 @@
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
#include "../../proxy.h"
#include "my_ssl.h"
typedef struct _ssl_conn { typedef struct _ssl_conn {
SSL_CTX *ctx; SSL_CTX *ctx;
SSL *ssl; SSL *ssl;
@ -110,20 +115,23 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert)
static char hash_name[sizeof(src_cert->sha1_hash)*2 + 1]; static char hash_name[sizeof(src_cert->sha1_hash)*2 + 1];
static char cache_name[200]; static char cache_name[200];
pthread_mutex_lock(&ssl_file_mutex);
bin2hex(src_cert->sha1_hash, sizeof(src_cert->sha1_hash), hash_name, sizeof(hash_name)); bin2hex(src_cert->sha1_hash, sizeof(src_cert->sha1_hash), hash_name, sizeof(hash_name));
sprintf(cache_name, "%s%s.pem", cert_path, hash_name); sprintf(cache_name, "%s%s.pem", cert_path, hash_name);
/* check if certificate is already cached */ /* check if certificate is already cached */
fcache = fopen(cache_name, "rb"); fcache = fopen(cache_name, "rb");
if ( fcache != NULL ) { if ( fcache != NULL ) {
#ifndef _WIN32
flock(fileno(fcache), LOCK_SH);
#endif
dst_cert = PEM_read_X509(fcache, &dst_cert, NULL, NULL); dst_cert = PEM_read_X509(fcache, &dst_cert, NULL, NULL);
#ifndef _WIN32
flock(fileno(fcache), LOCK_UN);
#endif
fclose(fcache); fclose(fcache);
if ( dst_cert != NULL ){ if ( dst_cert != NULL ){
pthread_mutex_unlock(&ssl_file_mutex);
return dst_cert; return dst_cert;
} }
} }
pthread_mutex_unlock(&ssl_file_mutex);
/* proceed if certificate is not cached */ /* proceed if certificate is not cached */
dst_cert = X509_dup(src_cert); dst_cert = X509_dup(src_cert);
@ -163,18 +171,22 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert)
/* write to cache */ /* write to cache */
pthread_mutex_lock(&ssl_file_mutex);
fcache = fopen(cache_name, "wb"); fcache = fopen(cache_name, "wb");
if ( fcache != NULL ) { if ( fcache != NULL ) {
#ifndef _WIN32
flock(fileno(fcache), LOCK_EX);
#endif
PEM_write_X509(fcache, dst_cert); PEM_write_X509(fcache, dst_cert);
#ifndef _WIN32
flock(fileno(fcache), LOCK_UN);
#endif
fclose(fcache); fclose(fcache);
} }
pthread_mutex_unlock(&ssl_file_mutex);
return dst_cert; return dst_cert;
} }
SSL_CONN ssl_handshake_to_server(SOCKET s, SSL_CERT *server_cert, char **errSSL) SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CERT *server_cert, char **errSSL)
{ {
int err = 0; int err = 0;
X509 *cert; X509 *cert;
@ -204,6 +216,7 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, SSL_CERT *server_cert, char **errSSL)
ssl_conn_free(conn); ssl_conn_free(conn);
return NULL; return NULL;
} }
if(hostname && *hostname)SSL_set_tlsext_host_name(conn->ssl, hostname);
err = SSL_connect(conn->ssl); err = SSL_connect(conn->ssl);
if ( err == -1 ) { if ( err == -1 ) {
*errSSL = ERR_error_string(ERR_get_error(), errbuf); *errSSL = ERR_error_string(ERR_get_error(), errbuf);
@ -212,6 +225,10 @@ SSL_CONN ssl_handshake_to_server(SOCKET s, SSL_CERT *server_cert, char **errSSL)
} }
cert = SSL_get_peer_certificate(conn->ssl); cert = SSL_get_peer_certificate(conn->ssl);
if(!cert) {
ssl_conn_free(conn);
return NULL;
}
/* TODO: Verify certificate */ /* TODO: Verify certificate */
@ -312,11 +329,15 @@ void ssl_conn_free(SSL_CONN connection)
{ {
ssl_conn *conn = (ssl_conn *) connection; ssl_conn *conn = (ssl_conn *) connection;
if(conn){
if(conn->ssl){
SSL_shutdown(conn->ssl); SSL_shutdown(conn->ssl);
SSL_free(conn->ssl); SSL_free(conn->ssl);
SSL_CTX_free(conn->ctx); }
if(conn->ctx) SSL_CTX_free(conn->ctx);
free(conn); free(conn);
} }
}
void _ssl_cert_free(SSL_CERT cert) void _ssl_cert_free(SSL_CERT cert)
{ {

View File

@ -18,7 +18,7 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert);
// //
// SSL/TLS handshakes // SSL/TLS handshakes
// //
SSL_CONN ssl_handshake_to_server(SOCKET s, SSL_CERT *server_cert, char **errSSL); SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CERT *server_cert, char **errSSL);
SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CERT server_cert, char **errSSL); SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CERT server_cert, char **errSSL);
// //

View File

@ -4,17 +4,15 @@
please read License Agreement please read License Agreement
$Id: ssl_plugin.c,v 1.9 2010-11-11 11:32:33 v.dubrovin Exp $
*/ */
#include "../../structures.h" #include "../../structures.h"
#include "../../proxy.h"
#include <openssl/rsa.h> /* SSLeay stuff */ #include <openssl/rsa.h> /* SSLeay stuff */
#include <openssl/crypto.h> #include <openssl/crypto.h>
#include <openssl/x509.h> #include <openssl/x509.h>
#include <openssl/pem.h> #include <openssl/pem.h>
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include "../../proxy.h"
#include "my_ssl.h" #include "my_ssl.h"
#ifndef _WIN32 #ifndef _WIN32
@ -54,13 +52,15 @@ struct SSLqueue {
/* /*
Todo: use hashtable TO DO: use hashtable
*/ */
static struct SSLqueue *searchSSL(SOCKET s){ static struct SSLqueue *searchSSL(SOCKET s){
struct SSLqueue *sslq; struct SSLqueue *sslq = NULL;
pthread_mutex_lock(&ssl_mutex);
for(sslq = SSLq; sslq; sslq = sslq->next) for(sslq = SSLq; sslq; sslq = sslq->next)
if(sslq->s == s) return sslq; if(sslq->s == s) break;
return NULL; pthread_mutex_unlock(&ssl_mutex);
return sslq;
} }
static void addSSL(SOCKET s, SSL_CERT cert, SSL_CONN conn, struct clientparam* param){ static void addSSL(SOCKET s, SSL_CERT cert, SSL_CONN conn, struct clientparam* param){
@ -235,7 +235,7 @@ int dossl(struct clientparam* param, SSL_CONN* ServerConnp, SSL_CONN* ClientConn
ul = ((unsigned long)ssl_connect_timeout)*1000; ul = ((unsigned long)ssl_connect_timeout)*1000;
setsockopt(param->remsock, SOL_SOCKET, SO_SNDTIMEO, (char *)&ul, 4); setsockopt(param->remsock, SOL_SOCKET, SO_SNDTIMEO, (char *)&ul, 4);
} }
ServerConn = ssl_handshake_to_server(param->remsock, &ServerCert, &errSSL); ServerConn = ssl_handshake_to_server(param->remsock, (char *)param->hostname, &ServerCert, &errSSL);
if ( ServerConn == NULL || ServerCert == NULL ) { if ( ServerConn == NULL || ServerCert == NULL ) {
param->res = 8011; param->res = 8011;
param->srv->logfunc(param, (unsigned char *)"SSL handshake to server failed"); param->srv->logfunc(param, (unsigned char *)"SSL handshake to server failed");
@ -325,6 +325,47 @@ static struct filter ssl_filter = {
ssl_filter_close ssl_filter_close
}; };
int mitm = 0;
static int h_mitm(int argc, unsigned char **argv){
if((mitm&1)) return 1;
if(mitm) usleep(100*SLEEPTIME);
ssl_filter.next = pl->conf->filters;
pl->conf->filters = &ssl_filter;
mitm++;
return 0;
}
static int h_nomitm(int argc, unsigned char **argv){
struct filter * sf;
if(!(mitm&1)) return 1;
if(mitm) usleep(100*SLEEPTIME);
if(pl->conf->filters == &ssl_filter) pl->conf->filters = ssl_filter.next;
else for(sf = pl->conf->filters; sf && sf->next; sf=sf->next){
if(sf->next == &ssl_filter) {
sf->next = ssl_filter.next;
break;
}
}
mitm++;
return 0;
}
static int h_certpath(int argc, unsigned char **argv){
size_t len;
len = strlen(argv[1]);
if(!len || (argv[1][len - 1] != '/' && argv[1][len - 1] != '\\')) return 1;
if(cert_path && *cert_path) free(cert_path);
cert_path = strdup(argv[1]);
return 0;
}
static struct commands ssl_commandhandlers[] = {
{ssl_commandhandlers+1, "ssl_mitm", h_mitm, 1, 1},
{ssl_commandhandlers+2, "ssl_nomitm", h_nomitm, 1, 1},
{NULL, "ssl_certcache", h_certpath, 2, 2},
};
#ifdef _WIN32 #ifdef _WIN32
__declspec(dllexport) __declspec(dllexport)
@ -333,15 +374,9 @@ __declspec(dllexport)
int ssl_plugin (struct pluginlink * pluginlink, int ssl_plugin (struct pluginlink * pluginlink,
int argc, char** argv){ int argc, char** argv){
pl = pluginlink; pl = pluginlink;
if(argc > 1) {
if(cert_path && *cert_path) free(cert_path);
cert_path = strdup(argv[1]);
}
if(!ssl_loaded){ if(!ssl_loaded){
ssl_loaded = 1; ssl_loaded = 1;
pthread_mutex_init(&ssl_mutex, NULL); pthread_mutex_init(&ssl_mutex, NULL);
ssl_filter.next = pl->conf->filters;
pl->conf->filters = &ssl_filter;
memcpy(&sso, pl->so, sizeof(struct sockfuncs)); memcpy(&sso, pl->so, sizeof(struct sockfuncs));
pl->so->_send = ssl_send; pl->so->_send = ssl_send;
pl->so->_recv = ssl_recv; pl->so->_recv = ssl_recv;
@ -349,10 +384,13 @@ __declspec(dllexport)
pl->so->_recvfrom = ssl_recvfrom; pl->so->_recvfrom = ssl_recvfrom;
pl->so->_closesocket = ssl_closesocket; pl->so->_closesocket = ssl_closesocket;
pl->so->_poll = ssl_poll; pl->so->_poll = ssl_poll;
ssl_commandhandlers[2].next = pl->commandhandlers->next;
pl->commandhandlers->next = ssl_commandhandlers;
} }
else { else {
ssl_release(); ssl_release();
} }
ssl_init(); ssl_init();
tcppmfunc = (PROXYFUNC)pl->findbyname("tcppm"); tcppmfunc = (PROXYFUNC)pl->findbyname("tcppm");
if(!tcppmfunc){return 13;} if(!tcppmfunc){return 13;}

View File

@ -179,18 +179,27 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
int port; int port;
int rule = 0; int rule = 0;
struct trafcorrect * starttrafcorrect = firsttrafcorrect; struct trafcorrect * starttrafcorrect = firsttrafcorrect;
int statssrv_before, statscli_before; #ifndef NOPSTDINT
uint64_t statssrv_before, statscli_before;
#else
unsigned long statssrv_before, statscli_before;
#endif
int ok = 0; int ok = 0;
for (;starttrafcorrect != NULL; starttrafcorrect = starttrafcorrect->next) { for (;starttrafcorrect != NULL; starttrafcorrect = starttrafcorrect->next) {
port = starttrafcorrect->port; port = starttrafcorrect->port;
g_s = starttrafcorrect->p_service; g_s = starttrafcorrect->p_service;
if (starttrafcorrect->p_service == S_NOSERVICE) g_s = param->service; if (starttrafcorrect->p_service == S_NOSERVICE) g_s = param->service;
if (starttrafcorrect->port <= 0) port = myhtons(param->sins.sin_port); if (starttrafcorrect->port <= 0) port = myhtons(*SAPORT(&param->sinsr));
#ifndef NOPSTDINT
statssrv_before = param->statssrv64;
statscli_before = param->statscli64;
#else
statssrv_before = param->statssrv; statssrv_before = param->statssrv;
statscli_before = param->statscli; statscli_before = param->statscli;
#endif
rule++; rule++;
if (((g_s == param->service) && (port == myhtons(param->sins.sin_port))) || if (((g_s == param->service) && (port == myhtons(*SAPORT(&param->sinsr)))) ||
( ((starttrafcorrect->type == UDP) && ( ((starttrafcorrect->type == UDP) &&
((param->operation == UDPASSOC)|| ((param->operation == UDPASSOC)||
(param->operation == DNSRESOLVE)|| (param->operation == DNSRESOLVE)||
@ -201,28 +210,47 @@ void mylogfunc(struct clientparam * param, const unsigned char * pz) {
/* ôèëüòð ïîäîø¸ë. ìîæíî èçìåíÿòü çíà÷åíèå òðàôôèêà /* ôèëüòð ïîäîø¸ë. ìîæíî èçìåíÿòü çíà÷åíèå òðàôôèêà
äîìíîæàåì íà ÷èñëî */ äîìíîæàåì íà ÷èñëî */
if (starttrafcorrect->type == MULTIPLAY) { if (starttrafcorrect->type == MULTIPLAY) {
#ifndef NOPSTDINT
param->statssrv64 = (unsigned)((double)param->statssrv64 *starttrafcorrect->coeff);
param->statscli64 = (unsigned)((double)param->statscli64 * starttrafcorrect->coeff);
#else
param->statssrv = (unsigned)((double)param->statssrv *starttrafcorrect->coeff); param->statssrv = (unsigned)((double)param->statssrv *starttrafcorrect->coeff);
param->statscli = (unsigned)((double)param->statscli * starttrafcorrect->coeff); param->statscli = (unsigned)((double)param->statscli * starttrafcorrect->coeff);
#endif
} }
/* ñ ó÷¸òîì ïàêåòîâ */ /* ñ ó÷¸òîì ïàêåòîâ */
if (starttrafcorrect->type == IPCORRECT) { if (starttrafcorrect->type == IPCORRECT) {
if (starttrafcorrect->con_type == TCP) { if (starttrafcorrect->con_type == TCP) {
#ifndef NOPSTDINT
param->statssrv64+=(param->nreads + 3*param->nconnects)*starttrafcorrect->psize;
param->statscli64+=(param->nwrites + 3*param->nconnects)*starttrafcorrect->psize;
#else
param->statssrv+=(param->nreads + 3*param->nconnects)*starttrafcorrect->psize; param->statssrv+=(param->nreads + 3*param->nconnects)*starttrafcorrect->psize;
param->statscli+=(param->nwrites + 3*param->nconnects)*starttrafcorrect->psize; param->statscli+=(param->nwrites + 3*param->nconnects)*starttrafcorrect->psize;
#endif
} else { } else {
#ifndef NOPSTDINT
param->statssrv64+=param->nreads*starttrafcorrect->psize;
param->statscli64+=param->nwrites*starttrafcorrect->psize;
#else
param->statssrv+=param->nreads*starttrafcorrect->psize; param->statssrv+=param->nreads*starttrafcorrect->psize;
param->statscli+=param->nwrites*starttrafcorrect->psize; param->statscli+=param->nwrites*starttrafcorrect->psize;
#endif
} }
} }
if (DBGLEVEL == 1) { if (DBGLEVEL == 1) {
fprintf(stdout, "Port=%hd; Before: srv=%d, cli=%d; After: srv=%ld, cli=%ld; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(param->sins.sin_port), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule); #ifndef NOPSTDINT
fprintf(stdout, "Port=%hd; Before: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; After: srv=%"PRINTF_INT64_MODIFIER"d, cli=%"PRINTF_INT64_MODIFIER"d; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(*SAPORT(&param->sinsr)), statssrv_before, statscli_before, param->statssrv64, param->statscli64,param->nreads,param->nwrites,rule);
#else
fprintf(stdout, "Port=%hd; Before: srv=%lu, cli=%lu; After: srv=%lu, cli=%lu; nreads=%ld; nwrites=%ld; Rule=%d\n",myhtons(param->sins.sin_port), statssrv_before, statscli_before, param->statssrv, param->statscli,param->nreads,param->nwrites,rule);
#endif
} }
ok = 1; ok = 1;
break; break;
} }
} }
if ((!ok) && (DBGLEVEL == 1)) { if ((!ok) && (DBGLEVEL == 1)) {
fprintf(stdout, "No rules specifed: service=%d, port=%d, operation=%d", param->service, param->sins.sin_port,param->operation); fprintf(stdout, "No rules specifed: service=%d, port=%d, operation=%d", param->service, *SAPORT(&param->sinsr),param->operation);
} }
origlogfunc(param, pz); origlogfunc(param, pz);
} }

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: transparent_plugin.c,v 1.9 2010-11-11 11:32:33 v.dubrovin Exp $
*/ */
#include <sys/utsname.h> #include <sys/utsname.h>

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: WindowsAuthentication.c,v 1.12 2011-04-12 13:05:58 v.dubrovin Exp $
*/ */
#include "../../structures.h" #include "../../structures.h"

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: utf8tocp1251.c,v 1.9 2009/09/03 05:32:56 v.dubrovin Exp $
*/ */
#include "../../structures.h" #include "../../structures.h"

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: pop3p.c,v 1.17 2008/01/08 21:46:38 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -43,13 +42,13 @@ void * pop3pchild(struct clientparam* param) {
socksend(param->remsock, param->extusername, (int)strlen((char *)param->extusername), conf.timeouts[STRING_S]) <= 0 || socksend(param->remsock, param->extusername, (int)strlen((char *)param->extusername), conf.timeouts[STRING_S]) <= 0 ||
socksend(param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2) socksend(param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2)
{RETURN(623);} {RETURN(623);}
param->statscli += (int)(strlen((char *)param->extusername) + 7); param->statscli64 += (uint64_t)(strlen((char *)param->extusername) + 7);
param->nwrites++; param->nwrites++;
RETURN (sockmap(param, 180)); RETURN (sockmap(param, 180));
CLEANRET: CLEANRET:
if(param->hostname&&param->extusername) { if(param->hostname&&param->extusername) {
sprintf((char *)buf, "%.64s@%.128s%c%hu", param->extusername, param->hostname, (ntohs(param->sins.sin_port)==110)?0:':', ntohs(param->sins.sin_port)); sprintf((char *)buf, "%.64s@%.128s%c%hu", param->extusername, param->hostname, (*SAPORT(&param->sinsr)==110)?0:':', ntohs(*SAPORT(&param->sinsr)));
(*param->srv->logfunc)(param, buf); (*param->srv->logfunc)(param, buf);
} }
else (*param->srv->logfunc)(param, NULL); else (*param->srv->logfunc)(param, NULL);

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: proxy.c,v 1.107 2014-04-07 20:35:07 vlad Exp $
*/ */
@ -132,8 +131,9 @@ char * proxy_stringtable[] = {
NULL NULL
}; };
#define BUFSIZE 8192
#define LINESIZE 4096 #define LINESIZE 4096
#define BUFSIZE (LINESIZE*2) #define FTPBUFSIZE 1536
static void logurl(struct clientparam * param, char * buf, char * req, int ftp){ static void logurl(struct clientparam * param, char * buf, char * req, int ftp){
char *sb; char *sb;
@ -217,7 +217,7 @@ void * proxychild(struct clientparam* param) {
unsigned char *ftpbase=NULL; unsigned char *ftpbase=NULL;
unsigned char username[1024]; unsigned char username[1024];
int keepalive = 0; int keepalive = 0;
unsigned long contentlength = 0; uint64_t contentlength64 = 0;
int hascontent =0; int hascontent =0;
int isconnect = 0; int isconnect = 0;
int redirect = 0; int redirect = 0;
@ -229,7 +229,8 @@ void * proxychild(struct clientparam* param) {
int authenticate; int authenticate;
struct pollfd fds[2]; struct pollfd fds[2];
SOCKET ftps; SOCKET ftps;
SASIZETYPE sasize; char ftpbuf[FTPBUFSIZE];
int inftpbuf = 0;
#ifndef WITHMAIN #ifndef WITHMAIN
FILTER_ACTION action; FILTER_ACTION action;
#endif #endif
@ -241,7 +242,7 @@ void * proxychild(struct clientparam* param) {
bufsize = BUFSIZE; bufsize = BUFSIZE;
anonymous = param->srv->singlepacket; anonymous = param->srv->singlepacket;
for(;;){ for(;;){
memset(buf, 0, BUFSIZE); memset(buf, 0, bufsize);
inbuf = 0; inbuf = 0;
@ -260,8 +261,6 @@ for(;;){
ckeepalive = 0; ckeepalive = 0;
so._shutdown(param->remsock, SHUT_RDWR); so._shutdown(param->remsock, SHUT_RDWR);
so._closesocket(param->remsock); so._closesocket(param->remsock);
param->sins.sin_addr.s_addr = 0;
param->sins.sin_port = 0;
param->remsock = INVALID_SOCKET; param->remsock = INVALID_SOCKET;
param->redirected = 0; param->redirected = 0;
param->redirtype = 0; param->redirtype = 0;
@ -282,8 +281,6 @@ for(;;){
so._shutdown(param->remsock, SHUT_RDWR); so._shutdown(param->remsock, SHUT_RDWR);
so._closesocket(param->remsock); so._closesocket(param->remsock);
} }
param->sins.sin_addr.s_addr = 0;
param->sins.sin_port = 0;
param->remsock = INVALID_SOCKET; param->remsock = INVALID_SOCKET;
param->redirected = 0; param->redirected = 0;
param->redirtype = 0; param->redirtype = 0;
@ -388,14 +385,14 @@ for(;;){
while( (i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, '\n', conf.timeouts[STRING_S])) > 2){ while( (i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, '\n', conf.timeouts[STRING_S])) > 2){
if(i> 15 && (!strncasecmp((char *)(buf), "content-length", 14))){ if(i> 15 && (!strncasecmp((char *)(buf), "content-length", 14))){
buf[i]=0; buf[i]=0;
sscanf((char *)buf + 15, "%lu", &contentlength); sscanf((char *)buf + 15, "%"PRINTF_INT64_MODIFIER"u", &contentlength64);
} }
} }
while( contentlength > 0 && (i = sockgetlinebuf(param, CLIENT, buf, (BUFSIZE < contentlength)? BUFSIZE - 1:contentlength, '\n', conf.timeouts[STRING_S])) > 0){ while( contentlength64 > 0 && (i = sockgetlinebuf(param, CLIENT, buf, (BUFSIZE < contentlength64)? BUFSIZE - 1:(int)contentlength64, '\n', conf.timeouts[STRING_S])) > 0){
if ((unsigned long)i > contentlength) break; if ((uint64_t)i > contentlength64) break;
contentlength-=i; contentlength64-=i;
} }
contentlength = 0; contentlength64 = 0;
if(param->password)myfree(param->password); if(param->password)myfree(param->password);
param->password = myalloc(32); param->password = myalloc(32);
param->pwtype = 2; param->pwtype = 2;
@ -492,15 +489,15 @@ for(;;){
if(!sb)continue; if(!sb)continue;
++sb; ++sb;
while(isspace(*sb))sb++; while(isspace(*sb))sb++;
sscanf(sb, "%lu",&contentlength); sscanf(sb, "%"PRINTF_INT64_MODIFIER"u",&contentlength64);
if(param->maxtrafout && (param->maxtrafout < param->statscli || (unsigned)contentlength > param->maxtrafout - param->statscli)){ if(param->maxtrafout64 && (param->maxtrafout64 < param->statscli64 || contentlength64 > param->maxtrafout64 - param->statscli64)){
RETURN(10); RETURN(10);
} }
if(param->ndatfilterscli > 0 && contentlength > 0) continue; if(param->ndatfilterscli > 0 && contentlength64 > 0) continue;
} }
inbuf += i; inbuf += i;
if((bufsize - inbuf) < LINESIZE){ if((bufsize - inbuf) < LINESIZE){
if (bufsize > 20000){ if (bufsize > (LINESIZE * 16)){
RETURN (516); RETURN (516);
} }
if(!(newbuf = myrealloc(buf, bufsize + BUFSIZE))){RETURN (21);} if(!(newbuf = myrealloc(buf, bufsize + BUFSIZE))){RETURN (21);}
@ -527,48 +524,35 @@ for(;;){
RETURN(0); RETURN(0);
} }
if(action != PASS) RETURN(517); if(action != PASS) RETURN(517);
if(param->ndatfilterscli > 0 && contentlength > 0){ if(param->ndatfilterscli > 0 && contentlength64 > 0){
unsigned long newlen; uint64_t newlen64;
newlen = sockfillbuffcli(param, contentlength, CONNECTION_S); newlen64 = sockfillbuffcli(param, (unsigned long)contentlength64, CONNECTION_S);
if(newlen == contentlength) { if(newlen64 == contentlength64) {
action = handledatfltcli(param, &param->clibuf, &param->clibufsize, 0, &param->cliinbuf); action = handledatfltcli(param, &param->clibuf, &param->clibufsize, 0, &param->cliinbuf);
if(action == HANDLED){ if(action == HANDLED){
RETURN(0); RETURN(0);
} }
if(action != PASS) RETURN(517); if(action != PASS) RETURN(517);
contentlength = param->cliinbuf; contentlength64 = param->cliinbuf;
param->ndatfilterscli = 0; param->ndatfilterscli = 0;
} }
sprintf((char*)buf+strlen((char *)buf), "Content-Length: %lu\r\n", contentlength); sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRINTF_INT64_MODIFIER"u\r\n", contentlength64);
} }
#endif #endif
if((res = (*param->srv->authfunc)(param))) {RETURN(res);} if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
if (param->sins.sin_addr.s_addr == param->srv->intip && param->sins.sin_port == param->srv->intport) {
RETURN(519);
}
sasize = sizeof(struct sockaddr_in);
if(so._getpeername(param->remsock, (struct sockaddr *)&param->sins, &sasize)){
RETURN(520);
}
#define FTPBUFSIZE 1536
if(ftp && param->redirtype != R_HTTP){ if(ftp && param->redirtype != R_HTTP){
SOCKET s; SOCKET s;
int mode = 0; int mode = 0;
int i=0; int i=0;
char ftpbuf[FTPBUFSIZE];
int inftpbuf = 0;
inftpbuf = 0;
if(!ckeepalive){ if(!ckeepalive){
inftpbuf = FTPBUFSIZE - 20; inftpbuf = FTPBUFSIZE - 20;
res = ftplogin(param, ftpbuf, &inftpbuf); res = ftplogin(param, ftpbuf, &inftpbuf);
if(res){ if(res){
if (res == 700 || res == 701){
socksend(param->clisock, (unsigned char *)proxy_stringtable[16], (int)strlen(proxy_stringtable[16]), conf.timeouts[STRING_S]);
socksend(param->clisock, (unsigned char *)ftpbuf, inftpbuf, conf.timeouts[STRING_S]);
}
RETURN(res); RETURN(res);
} }
} }
@ -619,7 +603,7 @@ for(;;){
socksend(param->clisock, (unsigned char *)proxy_stringtable[8], (int)strlen(proxy_stringtable[8]), conf.timeouts[STRING_S]); socksend(param->clisock, (unsigned char *)proxy_stringtable[8], (int)strlen(proxy_stringtable[8]), conf.timeouts[STRING_S]);
s = param->remsock; s = param->remsock;
param->remsock = ftps; param->remsock = ftps;
if((param->operation == FTP_PUT) && (contentlength > 0)) param->waitclient = contentlength; if((param->operation == FTP_PUT) && (contentlength64 > 0)) param->waitclient64 = contentlength64;
res = sockmap(param, conf.timeouts[CONNECTION_L]); res = sockmap(param, conf.timeouts[CONNECTION_L]);
if (res == 99) res = 0; if (res == 99) res = 0;
so._closesocket(ftps); so._closesocket(ftps);
@ -821,23 +805,31 @@ for(;;){
if(socksend(param->remsock, req , (res = (int)strlen((char *)req)), conf.timeouts[STRING_L]) != res) { if(socksend(param->remsock, req , (res = (int)strlen((char *)req)), conf.timeouts[STRING_L]) != res) {
RETURN(518); RETURN(518);
} }
param->statscli += res; param->statscli64 += res;
param->nwrites++; param->nwrites++;
} }
inbuf = 0; inbuf = 0;
#ifndef ANONYMOUS #ifndef ANONYMOUS
if(anonymous!=1){ if(!anonymous){
int len = strlen((char *)buf);
len += sprintf((char*)buf + len, "Forwarded: for=");
if(*SAFAMILY(&param->sincr) == AF_INET6) len += sprintf((char*)buf + len, "\"[");
len += myinet_ntop(*SAFAMILY(&param->sincr), SAADDR(&param->sincr), (char *)buf + len, 128);
if(*SAFAMILY(&param->sincr) == AF_INET6) len += sprintf((char*)buf + len, "]:%d\";by=", (int)ntohs(*SAPORT(&param->sincr)));
else len += sprintf((char*)buf + len, ":%d;by=", (int)ntohs(*SAPORT(&param->sincr)));
gethostname((char *)(buf + len), 256);
sprintf((char*)buf+strlen((char *)buf), ":%d\r\n", (int)ntohs(*SAPORT(&param->sincl)));
}
else if(anonymous>1){
sprintf((char*)buf+strlen((char *)buf), "Via: 1.1 "); sprintf((char*)buf+strlen((char *)buf), "Via: 1.1 ");
gethostname((char *)(buf+strlen((char *)buf)), 256); gethostname((char *)(buf+strlen((char *)buf)), 256);
sprintf((char*)buf+strlen((char *)buf), ":%d (%s %s)\r\nX-Forwarded-For: ", (int)ntohs(param->srv->intport), conf.stringtable?conf.stringtable[2]:(unsigned char *)"", conf.stringtable?conf.stringtable[3]:(unsigned char *)""); sprintf((char*)buf+strlen((char *)buf), ":%d (%s %s)\r\nX-Forwarded-For: ", (int)ntohs(*SAPORT(&param->srv->intsa)), conf.stringtable?conf.stringtable[2]:(unsigned char *)"", conf.stringtable?conf.stringtable[3]:(unsigned char *)"");
if(!anonymous)myinet_ntoa(param->sinc.sin_addr, (char *)buf + strlen((char *)buf)); if(anonymous != 2)myinet_ntop(*SAFAMILY(&param->sincr), SAADDR(&param->sincr), (char *)buf + strlen((char *)buf), 128);
else { else {
unsigned long tmp; unsigned long tmp;
tmp = param->sinc.sin_addr.s_addr; tmp = ((unsigned long)myrand(param, sizeof(struct clientparam))<<16)^(unsigned long)rand();
param->sinc.sin_addr.s_addr = ((unsigned long)myrand(param, sizeof(struct clientparam))<<16)^(unsigned long)rand(); myinet_ntop(AF_INET, &tmp, (char *)buf + strlen((char *)buf), 64);
myinet_ntoa(param->sinc.sin_addr, (char *)buf + strlen((char *)buf));
param->sinc.sin_addr.s_addr = tmp;
} }
sprintf((char*)buf+strlen((char *)buf), "\r\n"); sprintf((char*)buf+strlen((char *)buf), "\r\n");
} }
@ -845,7 +837,7 @@ for(;;){
if(keepalive <= 1) sprintf((char*)buf+strlen((char *)buf), "%s: %s\r\n", (param->redirtype == R_HTTP)?"Proxy-Connection":"Connection", keepalive? "keep-alive":"close"); if(keepalive <= 1) sprintf((char*)buf+strlen((char *)buf), "%s: %s\r\n", (param->redirtype == R_HTTP)?"Proxy-Connection":"Connection", keepalive? "keep-alive":"close");
if(param->extusername){ if(param->extusername){
sprintf((char*)buf + strlen((char *)buf), "%s: basic ", (redirect)?"Proxy-Authorization":"Authorization"); sprintf((char*)buf + strlen((char *)buf), "%s: basic ", (redirect)?"Proxy-Authorization":"Authorization");
sprintf((char*)username, "%.32s:%.64s", param->extusername, param->extpassword?param->extpassword:(unsigned char*)""); sprintf((char*)username, "%.128s:%.64s", param->extusername, param->extpassword?param->extpassword:(unsigned char*)"");
en64(username, buf+strlen((char *)buf), (int)strlen((char *)username)); en64(username, buf+strlen((char *)buf), (int)strlen((char *)username));
sprintf((char*)buf + strlen((char *)buf), "\r\n"); sprintf((char*)buf + strlen((char *)buf), "\r\n");
} }
@ -853,21 +845,21 @@ for(;;){
if ((res = socksend(param->remsock, buf+reqlen, (int)strlen((char *)buf+reqlen), conf.timeouts[STRING_S])) != (int)strlen((char *)buf+reqlen)) { if ((res = socksend(param->remsock, buf+reqlen, (int)strlen((char *)buf+reqlen), conf.timeouts[STRING_S])) != (int)strlen((char *)buf+reqlen)) {
RETURN(518); RETURN(518);
} }
param->statscli += res; param->statscli64 += res;
param->nwrites++; param->nwrites++;
if(param->bandlimfunc) { if(param->bandlimfunc) {
sleeptime = param->bandlimfunc(param, 0, (int)strlen((char *)buf)); sleeptime = param->bandlimfunc(param, 0, (int)strlen((char *)buf));
} }
if(contentlength > 0){ if(contentlength64 > 0){
param->nolongdatfilter = 0; param->nolongdatfilter = 0;
param->waitclient = contentlength; param->waitclient64 = contentlength64;
res = sockmap(param, conf.timeouts[CONNECTION_S]); res = sockmap(param, conf.timeouts[CONNECTION_S]);
param->waitclient = 0; param->waitclient64 = 0;
if(res != 99) { if(res != 99) {
RETURN(res); RETURN(res);
} }
} }
contentlength = 0; contentlength64 = 0;
inbuf = 0; inbuf = 0;
ckeepalive = keepalive; ckeepalive = keepalive;
res = 0; res = 0;
@ -900,13 +892,13 @@ for(;;){
if(!sb)continue; if(!sb)continue;
++sb; ++sb;
while(isspace(*sb))sb++; while(isspace(*sb))sb++;
sscanf(sb, "%lu", &contentlength); sscanf(sb, "%"PRINTF_INT64_MODIFIER"u", &contentlength64);
hascontent = 1; hascontent = 1;
if(param->unsafefilter && param->ndatfilterssrv > 0) { if(param->unsafefilter && param->ndatfilterssrv > 0) {
hascontent = 2; hascontent = 2;
continue; continue;
} }
if(param->maxtrafin && (param->maxtrafin < param->statssrv || (unsigned)contentlength > param->maxtrafin - param->statssrv)){ if(param->maxtrafin64 && (param->maxtrafin64 < param->statssrv64 || contentlength64 + param->statssrv64 > param->maxtrafin64)){
RETURN(10); RETURN(10);
} }
} }
@ -935,7 +927,7 @@ for(;;){
} }
if((res == 304 || res == 204) && !hascontent){ if((res == 304 || res == 204) && !hascontent){
hascontent = 1; hascontent = 1;
contentlength = 0; contentlength64 = 0;
} }
if(param->bandlimfunc) { if(param->bandlimfunc) {
int st1; int st1;
@ -959,25 +951,25 @@ for(;;){
param->nolongdatfilter = 0; param->nolongdatfilter = 0;
if (conf.filtermaxsize && contentlength > (unsigned long)conf.filtermaxsize) { if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) {
param->nolongdatfilter = 1; param->nolongdatfilter = 1;
} }
else if(param->unsafefilter && param->ndatfilterssrv > 0 && contentlength > 0 && param->operation != HTTP_HEAD && res != 204 && res != 304){ else if(param->unsafefilter && param->ndatfilterssrv > 0 && contentlength64 > 0 && param->operation != HTTP_HEAD && res != 204 && res != 304){
unsigned long newlen; uint64_t newlen;
newlen = sockfillbuffsrv(param, (unsigned long) contentlength, CONNECTION_S); newlen = (uint64_t)sockfillbuffsrv(param, (unsigned long) contentlength64, CONNECTION_S);
if(newlen == contentlength) { if(newlen == contentlength64) {
action = handledatfltsrv(param, &param->srvbuf, &param->srvbufsize, 0, &param->srvinbuf); action = handledatfltsrv(param, &param->srvbuf, &param->srvbufsize, 0, &param->srvinbuf);
param->nolongdatfilter = 1; param->nolongdatfilter = 1;
if(action == HANDLED){ if(action == HANDLED){
RETURN(0); RETURN(0);
} }
if(action != PASS) RETURN(517); if(action != PASS) RETURN(517);
contentlength = param->srvinbuf; contentlength64 = param->srvinbuf;
sprintf((char*)buf+strlen((char *)buf), "Content-Length: %lu\r\n", contentlength); sprintf((char*)buf+strlen((char *)buf), "Content-Length: %"PRINTF_INT64_MODIFIER"u\r\n", contentlength64);
hascontent = 1; hascontent = 1;
} }
} }
if (contentlength > 0 && hascontent != 1) ckeepalive = 0; if (contentlength64 > 0 && hascontent != 1) ckeepalive = 0;
#else #else
#endif #endif
if(!isconnect || param->operation){ if(!isconnect || param->operation){
@ -996,7 +988,7 @@ for(;;){
RETURN(521); RETURN(521);
} }
} }
if((param->chunked || contentlength > 0) && param->operation != HTTP_HEAD && res != 204 && res != 304) { if((param->chunked || contentlength64 > 0) && param->operation != HTTP_HEAD && res != 204 && res != 304) {
do { do {
if(param->chunked){ if(param->chunked){
char smallbuf[32]; char smallbuf[32];
@ -1021,18 +1013,18 @@ for(;;){
break; break;
} }
smallbuf[i] = 0; smallbuf[i] = 0;
contentlength = 0; contentlength64 = 0;
sscanf(smallbuf, "%lx", &contentlength); sscanf(smallbuf, "%"PRINTF_INT64_MODIFIER"x", &contentlength64);
if(contentlength == 0) { if(contentlength64 == 0) {
param->chunked = 2; param->chunked = 2;
} }
} }
if(param->chunked != 2){ if(param->chunked != 2){
param->waitserver = contentlength; param->waitserver64 = contentlength64;
if((res = sockmap(param, conf.timeouts[CONNECTION_S])) != 98){ if((res = sockmap(param, conf.timeouts[CONNECTION_S])) != 98){
RETURN(res); RETURN(res);
} }
param->waitserver = 0; param->waitserver64 = 0;
} }
} while(param->chunked); } while(param->chunked);
} }
@ -1045,8 +1037,7 @@ for(;;){
else if(!hascontent && !param->chunked) { else if(!hascontent && !param->chunked) {
RETURN(sockmap(param, conf.timeouts[CONNECTION_S])); RETURN(sockmap(param, conf.timeouts[CONNECTION_S]));
} }
contentlength = 0; contentlength64 = 0;
REQUESTEND: REQUESTEND:
if((!ckeepalive || !keepalive) && param->remsock != INVALID_SOCKET){ if((!ckeepalive || !keepalive) && param->remsock != INVALID_SOCKET){
@ -1068,6 +1059,10 @@ CLEANRET:
if(param->res == 10) { if(param->res == 10) {
socksend(param->clisock, (unsigned char *)proxy_stringtable[2], (int)strlen(proxy_stringtable[2]), conf.timeouts[STRING_S]); socksend(param->clisock, (unsigned char *)proxy_stringtable[2], (int)strlen(proxy_stringtable[2]), conf.timeouts[STRING_S]);
} }
else if (res == 700 || res == 701){
socksend(param->clisock, (unsigned char *)proxy_stringtable[16], (int)strlen(proxy_stringtable[16]), conf.timeouts[STRING_S]);
socksend(param->clisock, (unsigned char *)ftpbuf, inftpbuf, conf.timeouts[STRING_S]);
}
else if(param->res == 100 || (param->res >10 && param->res < 20) || (param->res >701 && param->res <= 705)) { else if(param->res == 100 || (param->res >10 && param->res < 20) || (param->res >701 && param->res <= 705)) {
socksend(param->clisock, (unsigned char *)proxy_stringtable[1], (int)strlen(proxy_stringtable[1]), conf.timeouts[STRING_S]); socksend(param->clisock, (unsigned char *)proxy_stringtable[1], (int)strlen(proxy_stringtable[1]), conf.timeouts[STRING_S]);
} }

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: proxy.h,v 1.92 2012-04-11 23:01:20 vlad Exp $
*/ */
#define COPYRIGHT "(c)2000-2009 3APA3A, Vladimir Dubrovin & 3proxy.ru\n"\ #define COPYRIGHT "(c)2000-2009 3APA3A, Vladimir Dubrovin & 3proxy.ru\n"\
@ -42,7 +41,7 @@
#define NOCOUNTOUT 8 #define NOCOUNTOUT 8
#define UDPBUFSIZE 16384 #define UDPBUFSIZE 16384
#define TCPBUFSIZE 4096 #define TCPBUFSIZE 8192
#ifdef _WIN32 #ifdef _WIN32
@ -59,13 +58,13 @@
#ifndef FD_SETSIZE #ifndef FD_SETSIZE
#define FD_SETSIZE 4096 #define FD_SETSIZE 4096
#endif #endif
#include <errno.h>
#include <signal.h> #include <signal.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/time.h> #include <sys/time.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h> #include <pthread.h>
#include <syslog.h> #include <syslog.h>
#include <errno.h>
#endif #endif
#ifdef __CYGWIN__ #ifdef __CYGWIN__
@ -78,7 +77,13 @@
#undef errno #undef errno
#endif #endif
#define errno WSAGetLastError() #define errno WSAGetLastError()
#ifdef EAGAIN
#undef EAGAIN
#endif
#define EAGAIN WSAEWOULDBLOCK #define EAGAIN WSAEWOULDBLOCK
#ifdef EINTR
#undef EINTR
#endif
#define EINTR WSAEWOULDBLOCK #define EINTR WSAEWOULDBLOCK
#define SLEEPTIME 1 #define SLEEPTIME 1
#define usleep Sleep #define usleep Sleep
@ -148,8 +153,8 @@ extern struct extparam conf;
int sockmap(struct clientparam * param, int timeo); int sockmap(struct clientparam * param, int timeo);
int socksend(SOCKET sock, unsigned char * buf, int bufsize, int to); int socksend(SOCKET sock, unsigned char * buf, int bufsize, int to);
int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to); int socksendto(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
int sockrecvfrom(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to); int sockrecvfrom(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec); int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec);
@ -174,7 +179,6 @@ int init_sql(char * s);
void close_sql(); void close_sql();
#endif #endif
int doconnect(struct clientparam * param); int doconnect(struct clientparam * param);
int nbnameauth(struct clientparam * param);
int alwaysauth(struct clientparam * param); int alwaysauth(struct clientparam * param);
int ipauth(struct clientparam * param); int ipauth(struct clientparam * param);
int doauth(struct clientparam * param); int doauth(struct clientparam * param);
@ -184,13 +188,14 @@ unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nb
int scanaddr(const unsigned char *s, unsigned long * ip, unsigned long * mask); int scanaddr(const unsigned char *s, unsigned long * ip, unsigned long * mask);
int myinet_ntoa(struct in_addr in, char * buf); int myinet_ntop(int af, void *src, char *dst, socklen_t size);
extern unsigned long nservers[MAXNSERVERS]; extern struct nserver nservers[MAXNSERVERS];
extern unsigned long authnserver; struct nserver authnserver;
unsigned long getip(unsigned char *name); unsigned long getip(unsigned char *name);
unsigned long myresolver(unsigned char *); unsigned long getip46(int family, unsigned char *name, struct sockaddr *sa);
unsigned long fakeresolver (unsigned char *name); unsigned long myresolver(int, unsigned char *, unsigned char *);
int initdnshashtable(unsigned nhashsize); unsigned long fakeresolver (int, unsigned char *, unsigned char*);
int inithashtable(struct hashtable *hashtable, unsigned nhashsize);
void freeparam(struct clientparam * param); void freeparam(struct clientparam * param);
void clearstat(struct clientparam * param); void clearstat(struct clientparam * param);
void dumpcounters(struct trafcount *tl, int counterd); void dumpcounters(struct trafcount *tl, int counterd);
@ -228,17 +233,20 @@ void mschap(const unsigned char *win_password,
const unsigned char *challenge, unsigned char *response); const unsigned char *challenge, unsigned char *response);
struct hashtable; struct hashtable;
void hashadd(struct hashtable *ht, const unsigned char* name, unsigned long value, time_t expires); void hashadd(struct hashtable *ht, const unsigned char* name, unsigned char* value, time_t expires);
void parsehost(int family, char *host, struct sockaddr *sa);
int parsehostname(char *hostname, struct clientparam *param, unsigned short port); int parsehostname(char *hostname, struct clientparam *param, unsigned short port);
int parseusername(char *username, struct clientparam *param, int extpasswd); int parseusername(char *username, struct clientparam *param, int extpasswd);
int parseconnusername(char *username, struct clientparam *param, int extpasswd, unsigned short port); int parseconnusername(char *username, struct clientparam *param, int extpasswd, unsigned short port);
int ACLmatches(struct ace* acentry, struct clientparam * param); int ACLmatches(struct ace* acentry, struct clientparam * param);
int checkACL(struct clientparam * param);
unsigned long udpresolve(unsigned char * name, unsigned *retttl, struct clientparam* param, int makeauth); unsigned long udpresolve(int af, unsigned char * name, unsigned char * value, unsigned *retttl, struct clientparam* param, int makeauth);
struct ace * copyacl (struct ace *ac); struct ace * copyacl (struct ace *ac);
struct auth * copyauth (struct auth *); struct auth * copyauth (struct auth *);
void * itfree(void *data, void * retval);
void freeacl(struct ace *ac); void freeacl(struct ace *ac);
void freeauth(struct auth *); void freeauth(struct auth *);
void freefilter(struct filter *filter); void freefilter(struct filter *filter);
@ -258,6 +266,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param);
void srvinit2(struct srvparam * srv, struct clientparam *param); void srvinit2(struct srvparam * srv, struct clientparam *param);
void srvfree(struct srvparam * srv); void srvfree(struct srvparam * srv);
unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t); unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
int readconfig(FILE * fp);
int myrand(void * entropy, int len); int myrand(void * entropy, int len);
@ -300,16 +309,14 @@ struct datatype;
struct dictionary; struct dictionary;
struct node; struct node;
struct property; struct property;
extern unsigned char tmpbuf[8192];
extern pthread_mutex_t config_mutex;
extern pthread_mutex_t bandlim_mutex; extern pthread_mutex_t bandlim_mutex;
extern pthread_mutex_t hash_mutex; extern pthread_mutex_t hash_mutex;
extern pthread_mutex_t tc_mutex; extern pthread_mutex_t tc_mutex;
extern pthread_mutex_t pwl_mutex; extern pthread_mutex_t pwl_mutex;
#ifndef NOODBC extern pthread_mutex_t log_mutex;
extern pthread_mutex_t odbc_mutex; extern int logmutexinit;
#endif
extern struct hashtable dns_table;
extern struct datatype datatypes[64]; extern struct datatype datatypes[64];

View File

@ -4,14 +4,60 @@
please read License Agreement please read License Agreement
$Id: proxymain.c,v 1.85 2012-04-15 22:46:09 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
#define param ((struct clientparam *) p)
#ifdef _WIN32
DWORD WINAPI threadfunc(LPVOID p) {
#else
void * threadfunc (void *p) {
#endif
int i = 0;
if(param->srv->cbsock != INVALID_SOCKET){
SASIZETYPE size = sizeof(param->sinsr);
for(i=0; i<3; i++){
param->remsock = so._accept(param->srv->cbsock, (struct sockaddr*)&param->sinsr, &size);
if(param->remsock == INVALID_SOCKET) {
param->res = 13;
param->srv->logfunc(param, "Connect back accept() failed");
continue;
}
#ifndef WITHMAIN
memcpy(&param->req, &param->sinsr, size);
if(param->srv->acl) param->res = checkACL(param);
if(param->res){
param->srv->logfunc(param, "Connect back ACL failed");
so._closesocket(param->remsock);
param->remsock = INVALID_SOCKET;
continue;
}
#endif
if(so._sendto(param->remsock, "C", 1, 0, (struct sockaddr*)&param->sinsr, size) != 1){
param->srv->logfunc(param, "Connect back sending command failed");
so._closesocket(param->remsock);
param->remsock = INVALID_SOCKET;
continue;
}
break;
}
}
if(i == 3){
freeparam(param);
}
else {
((struct clientparam *) p)->srv->pf((struct clientparam *)p);
}
#ifdef _WIN32
return 0;
#else
return NULL;
#endif
}
#undef param
@ -43,7 +89,7 @@ int MODULEMAINFUNC (int argc, char** argv){
SOCKET sock = INVALID_SOCKET; SOCKET sock = INVALID_SOCKET, new_sock = INVALID_SOCKET;
int i=0; int i=0;
SASIZETYPE size; SASIZETYPE size;
pthread_t thread; pthread_t thread;
@ -54,8 +100,15 @@ int MODULEMAINFUNC (int argc, char** argv){
unsigned sleeptime; unsigned sleeptime;
unsigned char buf[256]; unsigned char buf[256];
char *hostname=NULL; char *hostname=NULL;
int opt = 1, isudp; int opt = 1, isudp = 0, iscbl = 0, iscbc = 0;
unsigned char *cbc_string = NULL, *cbl_string = NULL;
#ifndef NOIPV6
struct sockaddr_in6 cbsa;
#else
struct sockaddr_in cbsa;
#endif
FILE *fp = NULL; FILE *fp = NULL;
struct linger lg;
int nlog = 5000; int nlog = 5000;
char loghelp[] = char loghelp[] =
#ifdef STDMAIN #ifdef STDMAIN
@ -73,7 +126,13 @@ int MODULEMAINFUNC (int argc, char** argv){
" -bBUFSIZE size of network buffer (default 4096 for TCP, 16384 for UDP)\n" " -bBUFSIZE size of network buffer (default 4096 for TCP, 16384 for UDP)\n"
" -t be silent (do not log service start/stop)\n" " -t be silent (do not log service start/stop)\n"
" -iIP ip address or internal interface (clients are expected to connect)\n" " -iIP ip address or internal interface (clients are expected to connect)\n"
" -eIP ip address or external interface (outgoing connection will have this)\n"; " -eIP ip address or external interface (outgoing connection will have this)\n"
" -rIP:PORT Use IP:port for connect back proxy instead of listen port\n"
" -RPORT Use PORT to listen connect back proxy connection to pass data to\n"
" -4 Use IPv4 for outgoing connections\n"
" -6 Use IPv6 for outgoing connections\n"
" -46 Prefer IPv4 for outgoing connections, use both IPv4 and IPv6\n"
" -64 Prefer IPv6 for outgoing connections, use both IPv4 and IPv6\n";
#ifdef _WIN32 #ifdef _WIN32
unsigned long ul = 1; unsigned long ul = 1;
@ -82,8 +141,6 @@ int MODULEMAINFUNC (int argc, char** argv){
int inetd = 0; int inetd = 0;
#endif #endif
#endif #endif
SOCKET new_sock = INVALID_SOCKET;
struct linger lg;
#ifdef _WIN32 #ifdef _WIN32
HANDLE h; HANDLE h;
#endif #endif
@ -116,7 +173,7 @@ int MODULEMAINFUNC (int argc, char** argv){
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
pthread_attr_init(&pa); pthread_attr_init(&pa);
pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + 16384); pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + 8192);
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
#endif #endif
#endif #endif
@ -150,7 +207,8 @@ int MODULEMAINFUNC (int argc, char** argv){
break; break;
case 'l': case 'l':
srv.logfunc = logstdout; srv.logfunc = logstdout;
srv.logtarget = (unsigned char*)argv[i] + 2; if(srv.logtarget) myfree(srv.logtarget);
srv.logtarget = mystrdup((unsigned char*)argv[i] + 2);
if(argv[i][2]) { if(argv[i][2]) {
if(argv[i][2]=='@'){ if(argv[i][2]=='@'){
@ -173,13 +231,25 @@ int MODULEMAINFUNC (int argc, char** argv){
} }
break; break;
case 'i': case 'i':
srv.intip = getip((unsigned char *)argv[i]+2); getip46(46, argv[i]+2, (struct sockaddr *)&srv.intsa);
break; break;
case 'e': case 'e':
srv.extip = getip((unsigned char *)argv[i]+2); {
#ifndef NOIPV6
struct sockaddr_in6 sa6;
error = !getip46(46, argv[i]+2, (struct sockaddr *)&sa6);
if(!error) memcpy((*SAFAMILY(&sa6)==AF_INET)?(void *)&srv.extsa:(void *)&srv.extsa6, &sa6, SASIZE(&sa6));
#else
error = !getip46(46, argv[i]+2, (struct sockaddr *)&srv.extsa);
#endif
}
break; break;
case 'p': case 'p':
srv.intport = htons(atoi(argv[i]+2)); *SAPORT(&srv.intsa) = htons(atoi(argv[i]+2));
break;
case '4':
case '6':
srv.family = atoi(argv[i]+1);
break; break;
case 'b': case 'b':
srv.bufsize = atoi(argv[i]+2); srv.bufsize = atoi(argv[i]+2);
@ -190,16 +260,17 @@ int MODULEMAINFUNC (int argc, char** argv){
#ifdef STDMAIN #ifdef STDMAIN
#ifndef _WIN32 #ifndef _WIN32
case 'I': case 'I':
size = sizeof(defparam.sinc); size = sizeof(defparam.sincl);
if(so._getsockname(0, (struct sockaddr*)&defparam.sinc, &size) || if(so._getsockname(0, (struct sockaddr*)&defparam.sincl, &size) ||
defparam.sinc.sin_family != AF_INET) error = 1; SAFAMILY(&defparam.sincl) != AF_INET) error = 1;
else inetd = 1; else inetd = 1;
break; break;
#endif #endif
#endif #endif
case 'f': case 'f':
srv.logformat = (unsigned char *)argv[i] + 2; if(srv.logformat)myfree(srv.logformat);
srv.logformat = mystrdup((unsigned char *)argv[i] + 2);
break; break;
case 't': case 't':
srv.silent = 1; srv.silent = 1;
@ -207,6 +278,14 @@ int MODULEMAINFUNC (int argc, char** argv){
case 'h': case 'h':
hostname = argv[i] + 2; hostname = argv[i] + 2;
break; break;
case 'r':
cbc_string = mystrdup(argv[i] + 2);
iscbc = 1;
break;
case 'R':
cbl_string = mystrdup(argv[i] + 2);
iscbl = 1;
break;
case 'u': case 'u':
srv.nouser = 1; srv.nouser = 1;
break; break;
@ -240,6 +319,8 @@ int MODULEMAINFUNC (int argc, char** argv){
"Available options are:\n" "Available options are:\n"
"%s" "%s"
" -pPORT - service port to accept connections\n" " -pPORT - service port to accept connections\n"
" -RIP:PORT - connect back IP:PORT to listen and accept connections\n"
" -rIP:PORT - connect back IP:PORT to establish connect back connection\n"
"%s" "%s"
"\tExample: %s -i127.0.0.1\n\n" "\tExample: %s -i127.0.0.1\n\n"
"%s", "%s",
@ -259,7 +340,7 @@ int MODULEMAINFUNC (int argc, char** argv){
else { else {
#endif #endif
#ifndef NOPORTMAP #ifndef NOPORTMAP
if (error || argc != i+3 || *argv[i]=='-'|| (srv.intport = htons((unsigned short)atoi(argv[i])))==0 || (srv.targetport = htons((unsigned short)atoi(argv[i+2])))==0) { if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv.intsa) = htons((unsigned short)atoi(argv[i])))==0 || (srv.targetport = htons((unsigned short)atoi(argv[i+2])))==0) {
#ifndef STDMAIN #ifndef STDMAIN
haveerror = 1; haveerror = 1;
conf.threadinit = 0; conf.threadinit = 0;
@ -269,6 +350,8 @@ int MODULEMAINFUNC (int argc, char** argv){
" [-e<external_ip>] <port_to_bind>" " [-e<external_ip>] <port_to_bind>"
" <target_hostname> <target_port>\n" " <target_hostname> <target_port>\n"
"Available options are:\n" "Available options are:\n"
" -RIP:PORT - connect back IP:PORT to listen and accept connections\n"
" -rIP:PORT - connect back IP:PORT to establish connect back connection\n"
"%s" "%s"
"%s" "%s"
"\tExample: %s -d -i127.0.0.1 6666 serv.somehost.ru 6666\n\n" "\tExample: %s -d -i127.0.0.1 6666 serv.somehost.ru 6666\n\n"
@ -311,8 +394,12 @@ int MODULEMAINFUNC (int argc, char** argv){
srvinit2(&srv, &defparam); srvinit2(&srv, &defparam);
if(!srv.intport) srv.intport = htons(childdef.port); if(!*SAFAMILY(&srv.intsa)) *SAFAMILY(&srv.intsa) = AF_INET;
if(!defparam.sinc.sin_port) defparam.sinc.sin_port = htons(childdef.port); if(!*SAPORT(&srv.intsa)) *SAPORT(&srv.intsa) = htons(childdef.port);
*SAFAMILY(&srv.extsa) = AF_INET;
#ifndef NOIPV6
*SAFAMILY(&srv.extsa6) = AF_INET6;
#endif
if(hostname)parsehostname(hostname, &defparam, childdef.port); if(hostname)parsehostname(hostname, &defparam, childdef.port);
@ -324,15 +411,18 @@ int MODULEMAINFUNC (int argc, char** argv){
#endif #endif
if (!iscbc) {
if(srv.srvsock == INVALID_SOCKET){ if(srv.srvsock == INVALID_SOCKET){
if(!isudp){ if(!isudp){
lg.l_onoff = 1; lg.l_onoff = 1;
lg.l_linger = conf.timeouts[STRING_L]; lg.l_linger = conf.timeouts[STRING_L];
sock=so._socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); sock=so._socket(SASOCK(&srv.intsa), SOCK_STREAM, IPPROTO_TCP);
} }
else { else {
sock=so._socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); sock=so._socket(SASOCK(&srv.intsa), SOCK_DGRAM, IPPROTO_UDP);
} }
if( sock == INVALID_SOCKET) { if( sock == INVALID_SOCKET) {
perror("socket()"); perror("socket()");
@ -344,14 +434,15 @@ int MODULEMAINFUNC (int argc, char** argv){
fcntl(sock,F_SETFL,O_NONBLOCK); fcntl(sock,F_SETFL,O_NONBLOCK);
#endif #endif
srv.srvsock = sock; srv.srvsock = sock;
opt = 1;
if(so._setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int)))perror("setsockopt()"); if(so._setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int)))perror("setsockopt()");
#ifdef SO_REUSEPORT #ifdef SO_REUSEPORT
opt = 1;
so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int)); so._setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
#endif #endif
} }
size = sizeof(srv.intsa);
size = sizeof(defparam.sinc); for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&srv.intsa, size)==-1; usleep(sleeptime)) {
for(sleeptime = SLEEPTIME * 100; so._bind(sock, (struct sockaddr*)&defparam.sinc, size)==-1; usleep(sleeptime)) {
sprintf((char *)buf, "bind(): %s", strerror(errno)); sprintf((char *)buf, "bind(): %s", strerror(errno));
if(!srv.silent)(*srv.logfunc)(&defparam, buf); if(!srv.silent)(*srv.logfunc)(&defparam, buf);
sleeptime = (sleeptime<<1); sleeptime = (sleeptime<<1);
@ -370,12 +461,33 @@ int MODULEMAINFUNC (int argc, char** argv){
else else
defparam.clisock = sock; defparam.clisock = sock;
if(!srv.silent){ if(!srv.silent && !iscbc){
sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self()); sprintf((char *)buf, "Accepting connections [%u/%u]", (unsigned)getpid(), (unsigned)pthread_self());
(*srv.logfunc)(&defparam, buf); (*srv.logfunc)(&defparam, buf);
} }
defparam.sinc.sin_addr.s_addr = defparam.sins.sin_addr.s_addr = 0; }
defparam.sinc.sin_port = defparam.sins.sin_port = 0; if(iscbl){
parsehost(srv.family, cbl_string, (struct sockaddr *)&cbsa);
if((srv.cbsock=so._socket(SASOCK(&cbsa), SOCK_STREAM, IPPROTO_TCP))==INVALID_SOCKET) {
(*srv.logfunc)(&defparam, "Failed to allocate connect back socket");
return -6;
}
opt = 1;
so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&opt, sizeof(int));
#ifdef SO_REUSEPORT
opt = 1;
so._setsockopt(srv.cbsock, SOL_SOCKET, SO_REUSEPORT, (unsigned char *)&opt, sizeof(int));
#endif
if(so._bind(srv.cbsock, (struct sockaddr*)&cbsa, sizeof(cbsa))==-1) {
(*srv.logfunc)(&defparam, "Failed to bind connect back socket");
return -7;
}
if(so._listen(srv.cbsock, 1 + (srv.maxchild>>4))==-1) {
(*srv.logfunc)(&defparam, "Failed to listen connect back socket");
return -8;
}
}
srv.fds.fd = sock; srv.fds.fd = sock;
srv.fds.events = POLLIN; srv.fds.events = POLLIN;
@ -392,6 +504,7 @@ int MODULEMAINFUNC (int argc, char** argv){
} }
usleep(SLEEPTIME); usleep(SLEEPTIME);
} }
if (iscbc) break;
if (conf.paused != srv.version) break; if (conf.paused != srv.version) break;
if (srv.fds.events & POLLIN) { if (srv.fds.events & POLLIN) {
error = so._poll(&srv.fds, 1, 1000); error = so._poll(&srv.fds, 1, 1000);
@ -407,17 +520,46 @@ int MODULEMAINFUNC (int argc, char** argv){
if(!srv.silent)(*srv.logfunc)(&defparam, buf); if(!srv.silent)(*srv.logfunc)(&defparam, buf);
break; break;
} }
continue;
} }
if((conf.paused != srv.version) || (error < 0)) break; if((conf.paused != srv.version) || (error < 0)) break;
if(!isudp){ if(!isudp){
size = sizeof(defparam.sinc); size = sizeof(defparam.sincr);
new_sock = so._accept(sock, (struct sockaddr*)&defparam.sinc, &size); if(iscbc){
new_sock=so._socket(SASOCK(&defparam.sincr), SOCK_STREAM, IPPROTO_TCP);
if(new_sock != INVALID_SOCKET){
parsehost(srv.family, cbc_string, (struct sockaddr *)&defparam.sincr);
if(so._connect(new_sock,(struct sockaddr *)&defparam.sincr,sizeof(defparam.sincr))) {
so._closesocket(new_sock);
new_sock = INVALID_SOCKET;
usleep(SLEEPTIME);
continue;
}
if(so._recvfrom(new_sock,buf,1,0,(struct sockaddr*)&defparam.sincr, &size) != 1) {
so._closesocket(new_sock);
new_sock = INVALID_SOCKET;
usleep(SLEEPTIME);
continue;
}
}
else {
usleep(SLEEPTIME);
continue;
}
}
else {
new_sock = so._accept(sock, (struct sockaddr*)&defparam.sincr, &size);
if(new_sock == INVALID_SOCKET){ if(new_sock == INVALID_SOCKET){
sprintf((char *)buf, "accept(): %s", strerror(errno)); sprintf((char *)buf, "accept(): %s", strerror(errno));
if(!srv.silent)(*srv.logfunc)(&defparam, buf); if(!srv.silent)(*srv.logfunc)(&defparam, buf);
continue; continue;
} }
}
size = sizeof(defparam.sincl);
if(so._getsockname(new_sock, (struct sockaddr *)&defparam.sincl, &size)){
sprintf((char *)buf, "getsockname(): %s", strerror(errno));
if(!srv.silent)(*srv.logfunc)(&defparam, buf);
continue;
}
#ifdef _WIN32 #ifdef _WIN32
ioctlsocket(new_sock, FIONBIO, &ul); ioctlsocket(new_sock, FIONBIO, &ul);
#else #else
@ -426,8 +568,9 @@ int MODULEMAINFUNC (int argc, char** argv){
so._setsockopt(new_sock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg)); so._setsockopt(new_sock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg));
so._setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (unsigned char *)&opt, sizeof(int)); so._setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (unsigned char *)&opt, sizeof(int));
} }
else else {
srv.fds.events = 0; srv.fds.events = 0;
}
if(! (newparam = myalloc (sizeof(defparam)))){ if(! (newparam = myalloc (sizeof(defparam)))){
if(!isudp) so._closesocket(new_sock); if(!isudp) so._closesocket(new_sock);
defparam.res = 21; defparam.res = 21;
@ -456,9 +599,9 @@ int MODULEMAINFUNC (int argc, char** argv){
} }
#ifdef _WIN32 #ifdef _WIN32
#ifndef _WINCE #ifndef _WINCE
h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)16384, (BEGINTHREADFUNC)srv.pf, (void *) newparam, 0, &thread); h = (HANDLE)_beginthreadex((LPSECURITY_ATTRIBUTES )NULL, (unsigned)16384, threadfunc, (void *) newparam, 0, &thread);
#else #else
h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)32768, (BEGINTHREADFUNC)srv.pf, (void *) newparam, 0, &thread); h = (HANDLE)CreateThread((LPSECURITY_ATTRIBUTES )NULL, (unsigned)16384, threadfunc, (void *) newparam, 0, &thread);
#endif #endif
srv.childcount++; srv.childcount++;
if (h) { if (h) {
@ -472,7 +615,7 @@ int MODULEMAINFUNC (int argc, char** argv){
} }
#else #else
error = pthread_create(&thread, &pa, (PTHREADFUNC)srv.pf, (void *)newparam); error = pthread_create(&thread, &pa, threadfunc, (void *)newparam);
srv.childcount++; srv.childcount++;
if(error){ if(error){
sprintf((char *)buf, "pthread_create(): %s", strerror(error)); sprintf((char *)buf, "pthread_create(): %s", strerror(error));
@ -484,22 +627,28 @@ int MODULEMAINFUNC (int argc, char** argv){
} }
#endif #endif
pthread_mutex_unlock(&srv.counter_mutex); pthread_mutex_unlock(&srv.counter_mutex);
memset(&defparam.sinc, 0, sizeof(defparam.sinc)); memset(&defparam.sincl, 0, sizeof(defparam.sincl));
memset(&defparam.sincr, 0, sizeof(defparam.sincr));
if(isudp) while(!srv.fds.events)usleep(SLEEPTIME); if(isudp) while(!srv.fds.events)usleep(SLEEPTIME);
} }
if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread"); if(!srv.silent) srv.logfunc(&defparam, (unsigned char *)"Exiting thread");
if(fp) fclose(fp); if(fp) fclose(fp);
srvfree(&srv); srvfree(&srv);
if(defparam.hostname)myfree(defparam.hostname);
#ifndef STDMAIN #ifndef STDMAIN
pthread_mutex_lock(&config_mutex);
if(srv.next)srv.next->prev = srv.prev; if(srv.next)srv.next->prev = srv.prev;
if(srv.prev)srv.prev->next = srv.next; if(srv.prev)srv.prev->next = srv.next;
else conf.services = srv.next; else conf.services = srv.next;
freeacl(srv.acl); pthread_mutex_unlock(&config_mutex);
freeauth(srv.authfuncs);
#endif #endif
if(defparam.hostname)myfree(defparam.hostname);
if(cbc_string)myfree(cbc_string);
if(cbl_string)myfree(cbl_string);
return 0; return 0;
} }
@ -509,48 +658,66 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
memset(srv, 0, sizeof(struct srvparam)); memset(srv, 0, sizeof(struct srvparam));
srv->version = conf.paused; srv->version = conf.paused;
srv->logfunc = conf.logfunc; srv->logfunc = conf.logfunc;
srv->logformat = conf.logformat; if(srv->logformat)myfree(srv->logformat);
srv->logformat = conf.logformat? mystrdup(conf.logformat) : NULL;
srv->authfunc = conf.authfunc; srv->authfunc = conf.authfunc;
srv->usentlm = 0; srv->usentlm = 0;
srv->maxchild = conf.maxchild; srv->maxchild = conf.maxchild;
srv->time_start = time(NULL); srv->time_start = time(NULL);
srv->logtarget = conf.logtarget; if(conf.logtarget){
if(srv->logtarget) myfree(srv->logtarget);
srv->logtarget = mystrdup(conf.logtarget);
}
srv->srvsock = INVALID_SOCKET; srv->srvsock = INVALID_SOCKET;
srv->logdumpsrv = conf.logdumpsrv; srv->logdumpsrv = conf.logdumpsrv;
srv->logdumpcli = conf.logdumpcli; srv->logdumpcli = conf.logdumpcli;
srv->cbsock = INVALID_SOCKET;
memset(param, 0, sizeof(struct clientparam)); memset(param, 0, sizeof(struct clientparam));
param->srv = srv; param->srv = srv;
param->remsock = param->clisock = param->ctrlsock = param->ctrlsocksrv = INVALID_SOCKET; param->remsock = param->clisock = param->ctrlsock = param->ctrlsocksrv = INVALID_SOCKET;
param->req.sin_family = param->sins.sin_family = param->sinc.sin_family = AF_INET; *SAFAMILY(&param->req) = *SAFAMILY(&param->sinsl) = *SAFAMILY(&param->sinsr) = *SAFAMILY(&param->sincr) = *SAFAMILY(&param->sincl) = AF_INET;
pthread_mutex_init(&srv->counter_mutex, NULL); pthread_mutex_init(&srv->counter_mutex, NULL);
memcpy(&srv->intsa, &conf.intsa, sizeof(srv->intsa));
memcpy(&srv->extsa, &conf.extsa, sizeof(srv->extsa));
#ifndef NOIPV6
memcpy(&srv->extsa6, &conf.extsa6, sizeof(srv->extsa6));
#endif
} }
void srvinit2(struct srvparam * srv, struct clientparam *param){ void srvinit2(struct srvparam * srv, struct clientparam *param){
if(srv->logformat){ if(srv->logformat){
char *s; char *s;
if(*srv->logformat == '-' && (s = strchr((char *)srv->logformat + 1, '+')) && s[1]){ if(*srv->logformat == '-' && (s = strchr((char *)srv->logformat + 1, '+')) && s[1]){
char* logformat = srv->logformat;
*s = 0; *s = 0;
srv->nonprintable = (unsigned char *)mystrdup((char *)srv->logformat + 1); srv->nonprintable = (unsigned char *)mystrdup((char *)srv->logformat + 1);
srv->replace = s[1]; srv->replace = s[1];
srv->logformat = (unsigned char *)mystrdup(s + 2); srv->logformat = (unsigned char *)mystrdup(s + 2);
*s = '+'; *s = '+';
myfree(logformat);
} }
else srv->logformat = (unsigned char *)mystrdup((char *)srv->logformat);
} }
if(srv->logtarget) srv->logtarget = (unsigned char *)mystrdup((char *)srv->logtarget); memset(&param->sinsl, 0, sizeof(param->sinsl));
if(!srv->intip) srv->intip = conf.intip; memset(&param->sinsr, 0, sizeof(param->sinsr));
param->sinc.sin_addr.s_addr = srv->intip; memset(&param->req, 0, sizeof(param->req));
param->sinc.sin_port = srv->intport; *SAFAMILY(&param->sinsl) = AF_INET;
if(!srv->extip) srv->extip = conf.extip; *SAFAMILY(&param->sinsr) = AF_INET;
param->sins.sin_addr.s_addr = param->extip = srv->extip; *SAFAMILY(&param->req) = AF_INET;
if(!srv->extport) srv->extport = htons(conf.extport); memcpy(&param->sincr, &srv->intsa, sizeof(param->sincr));
param->sins.sin_port = param->extport = srv->extport; memcpy(&param->sincl, &srv->intsa, sizeof(param->sincl));
#ifndef NOIPV6
memcpy(&param->sinsr, (srv->family == 6 || srv->family == 64)? (void *)&srv->extsa6: (void *)&srv->extsa, sizeof(param->sinsl));
#else
memcpy(&param->sinsr, &srv->extsa, sizeof(param->sinsl));
#endif
} }
void srvfree(struct srvparam * srv){ void srvfree(struct srvparam * srv){
if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock); if(srv->srvsock != INVALID_SOCKET) so._closesocket(srv->srvsock);
srv->srvsock = INVALID_SOCKET; srv->srvsock = INVALID_SOCKET;
if(srv->cbsock != INVALID_SOCKET) so._closesocket(srv->cbsock);
srv->cbsock = INVALID_SOCKET;
srv->service = S_ZOMBIE; srv->service = S_ZOMBIE;
while(srv->child) usleep(SLEEPTIME * 100); while(srv->child) usleep(SLEEPTIME * 100);
#ifndef STDMAIN #ifndef STDMAIN
@ -563,6 +730,9 @@ void srvfree(struct srvparam * srv){
} }
myfree(srv->filter); myfree(srv->filter);
} }
if(srv->acl)freeacl(srv->acl);
if(srv->authfuncs)freeauth(srv->authfuncs);
#endif #endif
pthread_mutex_destroy(&srv->counter_mutex); pthread_mutex_destroy(&srv->counter_mutex);
if(srv->target) myfree(srv->target); if(srv->target) myfree(srv->target);
@ -746,18 +916,11 @@ FILTER_ACTION makefilters (struct srvparam *srv, struct clientparam *param){
return res; return res;
} }
static void * itfree(void *data, void * retval){ void * itfree(void *data, void * retval){
myfree(data); myfree(data);
return retval; return retval;
} }
void freepwl(struct passwords *pwl){
for(; pwl; pwl = (struct passwords *)itfree(pwl, pwl->next)){
if(pwl->user)myfree(pwl->user);
if(pwl->password)myfree(pwl->password);
}
}
void freeauth(struct auth * authfuncs){ void freeauth(struct auth * authfuncs){
for(; authfuncs; authfuncs = (struct auth *)itfree(authfuncs, authfuncs->next)); for(; authfuncs; authfuncs = (struct auth *)itfree(authfuncs, authfuncs->next));
} }
@ -787,104 +950,6 @@ void freeacl(struct ace *ac){
} }
} }
void freeconf(struct extparam *confp){
struct bandlim * bl;
struct bandlim * blout;
struct trafcount * tc;
struct passwords *pw;
struct ace *acl;
struct filemon *fm;
int counterd, archiverc;
unsigned char *logname, *logtarget;
unsigned char **archiver;
unsigned char * logformat;
int i;
pthread_mutex_lock(&tc_mutex);
confp->trafcountfunc = NULL;
tc = confp->trafcounter;
confp->trafcounter = NULL;
counterd = confp->counterd;
confp->counterd = -1;
pthread_mutex_unlock(&tc_mutex);
if(tc)dumpcounters(tc,counterd);
for(; tc; tc = (struct trafcount *) itfree(tc, tc->next)){
if(tc->comment)myfree(tc->comment);
freeacl(tc->ace);
}
confp->countertype = NONE;
logtarget = confp->logtarget;
confp->logtarget = NULL;
logformat = confp->logformat;
confp->logformat = NULL;
pthread_mutex_lock(&bandlim_mutex);
bl = confp->bandlimiter;
blout = confp->bandlimiterout;
confp->bandlimiter = NULL;
confp->bandlimiterout = NULL;
confp->bandlimfunc = NULL;
pthread_mutex_unlock(&bandlim_mutex);
logname = confp->logname;
confp->logname = NULL;
archiverc = confp->archiverc;
confp->archiverc = 0;
archiver = confp->archiver;
confp->archiver = NULL;
fm = confp->fmon;
confp->fmon = NULL;
pw = confp->pwl;
confp->pwl = NULL;
confp->rotate = 0;
confp->logtype = NONE;
confp->authfunc = ipauth;
confp->bandlimfunc = NULL;
confp->intip = confp->extip = 0;
confp->intport = confp->extport = 0;
confp->singlepacket = 0;
confp->maxchild = 100;
resolvfunc = NULL;
acl = confp->acl;
confp->acl = NULL;
confp->logtime = confp->time = 0;
usleep(SLEEPTIME);
freeacl(acl);
freepwl(pw);
for(; bl; bl = (struct bandlim *) itfree(bl, bl->next)) freeacl(bl->ace);
for(; blout; blout = (struct bandlim *) itfree(blout, blout->next))freeacl(blout->ace);
if(counterd != -1) {
close(counterd);
}
for(; fm; fm = (struct filemon *)itfree(fm, fm->next)){
if(fm->path) myfree(fm->path);
}
if(logtarget) {
myfree(logtarget);
}
if(logname) {
myfree(logname);
}
if(logformat) {
myfree(logformat);
}
if(archiver) {
for(i = 0; i < archiverc; i++) myfree(archiver[i]);
myfree(archiver);
}
}
FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){ FILTER_ACTION handlereqfilters(struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
FILTER_ACTION action; FILTER_ACTION action;
int i; int i;

View File

@ -191,7 +191,7 @@
* do nothing else. On the Mac OS X version of gcc this is _STDINT_H_. * do nothing else. On the Mac OS X version of gcc this is _STDINT_H_.
*/ */
#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED) #if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ <= 4)) )) && !defined (_PSTDINT_H_INCLUDED)
#include <stdint.h> #include <stdint.h>
#define _PSTDINT_H_INCLUDED #define _PSTDINT_H_INCLUDED
# ifndef PRINTF_INT64_MODIFIER # ifndef PRINTF_INT64_MODIFIER

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: smtpp.c,v 1.13 2011-06-10 20:48:46 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -83,7 +82,7 @@ int readdata (struct clientparam* param) {
return -1; return -1;
} }
#endif #endif
socksendto(param->remsock, &param->sins, buf, i, conf.timeouts[STRING_S]); socksendto(param->remsock, (struct sockaddr *)&param->sinsr, buf, i, conf.timeouts[STRING_S]);
} }
if(i < 1) { if(i < 1) {
myfree(buf); myfree(buf);
@ -99,7 +98,6 @@ void * smtppchild(struct clientparam* param) {
int i=0, res; int i=0, res;
unsigned char buf[320]; unsigned char buf[320];
unsigned char username[256]; unsigned char username[256];
unsigned long ul;
char * command = NULL; char * command = NULL;
int login = 0; int login = 0;
@ -188,10 +186,11 @@ void * smtppchild(struct clientparam* param) {
if( i < 3 ) {RETURN(671);} if( i < 3 ) {RETURN(671);}
buf[i] = 0; buf[i] = 0;
if(strncasecmp((char *)buf, "220", 3)||!strncasecmp((char *)buf+4, "PROXY", 5)){RETURN(672);} if(strncasecmp((char *)buf, "220", 3)||!strncasecmp((char *)buf+4, "PROXY", 5)){RETURN(672);}
ul = param->extip; i = sprintf(buf, "EHLO [");
i = sprintf(buf, "EHLO [%lu.%lu.%lu.%lu]\r\n", ((ul&0xFF000000)>>24), ((ul&0x00FF0000)>>16), ((ul&0x0000FF00)>>8), ((ul&0x000000FF))); i += myinet_ntop(*SAFAMILY(&param->sinsl), SAADDR(&param->sinsl), buf+strlen(buf), 64);
i += sprintf(buf+strlen(buf), "]\r\n");
if(socksend(param->remsock, buf, i, conf.timeouts[STRING_S])!= i) {RETURN(673);} if(socksend(param->remsock, buf, i, conf.timeouts[STRING_S])!= i) {RETURN(673);}
param->statscli+=i; param->statscli64+=i;
param->nwrites++; param->nwrites++;
login = 0; login = 0;
do { do {
@ -209,26 +208,26 @@ void * smtppchild(struct clientparam* param) {
} }
if ((login & 1)) { if ((login & 1)) {
socksend(param->remsock, "AUTH LOGIN\r\n", 12, conf.timeouts[STRING_S]); socksend(param->remsock, "AUTH LOGIN\r\n", 12, conf.timeouts[STRING_S]);
param->statscli+=12; param->statscli64+=12;
param->nwrites++; param->nwrites++;
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(680);} if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(680);}
en64(param->extusername, buf, (int)strlen(param->extusername)); en64(param->extusername, buf, (int)strlen(param->extusername));
socksend(param->remsock, buf, (int)strlen(buf), conf.timeouts[STRING_S]); socksend(param->remsock, buf, (int)strlen(buf), conf.timeouts[STRING_S]);
socksend(param->remsock, "\r\n", 2, conf.timeouts[STRING_S]); socksend(param->remsock, "\r\n", 2, conf.timeouts[STRING_S]);
param->statscli+=(i+2); param->statscli64+=(i+2);
param->nwrites+=2; param->nwrites+=2;
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(681);} if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(681);}
en64(param->extpassword, buf, (int)strlen(param->extpassword)); en64(param->extpassword, buf, (int)strlen(param->extpassword));
socksend(param->remsock, buf, (int)strlen(buf), conf.timeouts[STRING_S]); socksend(param->remsock, buf, (int)strlen(buf), conf.timeouts[STRING_S]);
socksend(param->remsock, "\r\n", 2, conf.timeouts[STRING_S]); socksend(param->remsock, "\r\n", 2, conf.timeouts[STRING_S]);
param->statscli+=(i+2); param->statscli64+=(i+2);
param->nwrites+=2; param->nwrites+=2;
} }
else if((login & 2)){ else if((login & 2)){
socksend(param->remsock, "AUTH PLAIN\r\n", 12, conf.timeouts[STRING_S]); socksend(param->remsock, "AUTH PLAIN\r\n", 12, conf.timeouts[STRING_S]);
param->statscli+=12; param->statscli64+=(12);
param->nwrites++; param->nwrites++;
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]); i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(682);} if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(682);}
@ -243,7 +242,7 @@ void * smtppchild(struct clientparam* param) {
i = (int)strlen(buf); i = (int)strlen(buf);
socksend(param->remsock, buf, i, conf.timeouts[STRING_S]); socksend(param->remsock, buf, i, conf.timeouts[STRING_S]);
socksend(param->remsock, "\r\n", 2, conf.timeouts[STRING_S]); socksend(param->remsock, "\r\n", 2, conf.timeouts[STRING_S]);
param->statscli+=(i+2); param->statscli64+=(i+2);
param->nwrites+=2; param->nwrites+=2;
} }
if(command) { if(command) {
@ -257,7 +256,7 @@ void * smtppchild(struct clientparam* param) {
if(!strncasecmp(command, "MAIL", 4) || !strncasecmp(command, "RCPT", 4) || !strncasecmp(command, "STARTTLS", 8) || !strncasecmp(command, "TURN", 4)){ if(!strncasecmp(command, "MAIL", 4) || !strncasecmp(command, "RCPT", 4) || !strncasecmp(command, "STARTTLS", 8) || !strncasecmp(command, "TURN", 4)){
res = (int)strlen(command); res = (int)strlen(command);
command[res] = 0; command[res] = 0;
res = handlehdrfilterscli(param, &command, &res, 0, &res); res = handlehdrfilterscli(param, (unsigned char **)&command, &res, 0, &res);
if(res != PASS) { if(res != PASS) {
if(res == HANDLED) res = 2; if(res == HANDLED) res = 2;
else RETURN(677); else RETURN(677);
@ -292,7 +291,7 @@ void * smtppchild(struct clientparam* param) {
CLEANRET: CLEANRET:
if(param->hostname&&param->extusername) { if(param->hostname&&param->extusername) {
sprintf((char *)buf, "%.64s@%.128s%c%hu", param->extusername, param->hostname, (ntohs(param->sins.sin_port)==25)?0:':', ntohs(param->sins.sin_port)); sprintf((char *)buf, "%.64s@%.128s%c%hu", param->extusername, param->hostname, *SAPORT(&param->sinsr)==25?0:':',ntohs(*SAPORT(&param->sinsr)));
(*param->srv->logfunc)(param, buf); (*param->srv->logfunc)(param, buf);
} }
else (*param->srv->logfunc)(param, NULL); else (*param->srv->logfunc)(param, NULL);

View File

@ -33,7 +33,7 @@ int socksend(SOCKET sock, unsigned char * buf, int bufsize, int to){
} }
int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to){ int socksendto(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to){
int sent = 0; int sent = 0;
int res; int res;
struct pollfd fds; struct pollfd fds;
@ -45,7 +45,7 @@ int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int b
res = so._poll(&fds, 1, to); res = so._poll(&fds, 1, to);
if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue; if(res < 0 && (errno == EAGAIN || errno == EINTR)) continue;
if(res < 1) break; if(res < 1) break;
res = so._sendto(sock, buf + sent, bufsize - sent, 0, (struct sockaddr *)sin, sizeof(struct sockaddr_in)); res = so._sendto(sock, buf + sent, bufsize - sent, 0, sin, SASIZE(sin));
if(res < 0) { if(res < 0) {
if(errno != EAGAIN && errno != EINTR) break; if(errno != EAGAIN && errno != EINTR) break;
continue; continue;
@ -55,7 +55,7 @@ int socksendto(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int b
return sent; return sent;
} }
int sockrecvfrom(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to){ int sockrecvfrom(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to){
struct pollfd fds; struct pollfd fds;
SASIZETYPE sasize; SASIZETYPE sasize;
int res; int res;
@ -64,7 +64,7 @@ int sockrecvfrom(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int
fds.events = POLLIN; fds.events = POLLIN;
if(conf.timetoexit) return EOF; if(conf.timetoexit) return EOF;
if (so._poll(&fds, 1, to)<1) return 0; if (so._poll(&fds, 1, to)<1) return 0;
sasize = sizeof(struct sockaddr_in); sasize = SASIZE(sin);
do { do {
res = so._recvfrom(sock, buf, bufsize, 0, (struct sockaddr *)sin, &sasize); res = so._recvfrom(sock, buf, bufsize, 0, (struct sockaddr *)sin, &sasize);
} while (res < 0 && (errno == EAGAIN || errno == EINTR)); } while (res < 0 && (errno == EAGAIN || errno == EINTR));
@ -83,7 +83,7 @@ int sockgetcharcli(struct clientparam * param, int timeosec, int timeousec){
return (int)param->clibuf[param->clioffset++]; return (int)param->clibuf[param->clioffset++];
} }
param->clioffset = param->cliinbuf = 0; param->clioffset = param->cliinbuf = 0;
if ((len = sockrecvfrom(param->clisock, &param->sinc, param->clibuf, param->clibufsize, timeosec*1000 + timeousec))<=0) return EOF; if ((len = sockrecvfrom(param->clisock, (struct sockaddr *)&param->sincr, param->clibuf, param->clibufsize, timeosec*1000 + timeousec))<=0) return EOF;
param->cliinbuf = len; param->cliinbuf = len;
param->clioffset = 1; param->clioffset = 1;
return (int)*param->clibuf; return (int)*param->clibuf;
@ -103,7 +103,7 @@ int sockfillbuffcli(struct clientparam * param, unsigned long size, int timeosec
} }
if(size <= param->cliinbuf) return size; if(size <= param->cliinbuf) return size;
size -= param->cliinbuf; size -= param->cliinbuf;
if((len = sockrecvfrom(param->clisock, &param->sinc, param->clibuf + param->cliinbuf, (param->clibufsize - param->cliinbuf) < size? param->clibufsize - param->cliinbuf:size, timeosec*1000)) > 0){ if((len = sockrecvfrom(param->clisock, (struct sockaddr *)&param->sincr, param->clibuf + param->cliinbuf, (param->clibufsize - param->cliinbuf) < size? param->clibufsize - param->cliinbuf:size, timeosec*1000)) > 0){
param->cliinbuf += len; param->cliinbuf += len;
} }
return param->cliinbuf; return param->cliinbuf;
@ -123,10 +123,10 @@ int sockfillbuffsrv(struct clientparam * param, unsigned long size, int timeosec
} }
if(size <= param->srvinbuf) return size; if(size <= param->srvinbuf) return size;
size -= param->srvinbuf; size -= param->srvinbuf;
if((len = sockrecvfrom(param->remsock, &param->sinc, param->srvbuf + param->srvinbuf, (param->srvbufsize - param->srvinbuf) < size? param->srvbufsize - param->srvinbuf:size, timeosec*1000)) > 0){ if((len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sinsr, param->srvbuf + param->srvinbuf, (param->srvbufsize - param->srvinbuf) < size? param->srvbufsize - param->srvinbuf:size, timeosec*1000)) > 0){
param->srvinbuf += len; param->srvinbuf += len;
param->nreads++; param->nreads++;
param->statssrv += len; param->statssrv64 += len;
} }
return param->srvinbuf; return param->srvinbuf;
} }
@ -148,11 +148,11 @@ int sockgetcharsrv(struct clientparam * param, int timeosec, int timeousec){
return (int)param->srvbuf[param->srvoffset++]; return (int)param->srvbuf[param->srvoffset++];
} }
param->srvoffset = param->srvinbuf = 0; param->srvoffset = param->srvinbuf = 0;
if ((len = sockrecvfrom(param->remsock, &param->sins, param->srvbuf, param->srvbufsize, timeosec*1000 + timeousec))<=0) return EOF; if ((len = sockrecvfrom(param->remsock, (struct sockaddr *)&param->sinsr, param->srvbuf, param->srvbufsize, timeosec*1000 + timeousec))<=0) return EOF;
param->srvinbuf = len; param->srvinbuf = len;
param->srvoffset = 1; param->srvoffset = 1;
param->nreads++; param->nreads++;
param->statssrv += len; param->statssrv64 += len;
return (int)*param->srvbuf; return (int)*param->srvbuf;
} }

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: sockmap.c,v 1.64 2014-04-07 20:35:09 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -13,7 +12,7 @@
int sockmap(struct clientparam * param, int timeo){ int sockmap(struct clientparam * param, int timeo){
int res=0; int res=0;
unsigned sent=0, received=0; uint64_t sent=0, received=0;
SASIZETYPE sasize; SASIZETYPE sasize;
struct pollfd fds[2]; struct pollfd fds[2];
int sleeptime = 0, stop = 0; int sleeptime = 0, stop = 0;
@ -32,12 +31,12 @@ int sockmap(struct clientparam * param, int timeo){
#if DEBUGLEVEL > 2 #if DEBUGLEVEL > 2
(*param->srv->logfunc)(param, "Starting sockets mapping"); (*param->srv->logfunc)(param, "Starting sockets mapping");
#endif #endif
if(!param->waitclient){ if(!param->waitclient64){
if(!param->srvbuf && (!(param->srvbuf=myalloc(bufsize)) || !(param->srvbufsize = bufsize))){ if(!param->srvbuf && (!(param->srvbuf=myalloc(bufsize)) || !(param->srvbufsize = bufsize))){
return (21); return (21);
} }
} }
if(!param->waitserver){ if(!param->waitserver64){
if(!param->clibuf && (!(param->clibuf=myalloc(bufsize)) || !(param->clibufsize = bufsize))){ if(!param->clibuf && (!(param->clibuf=myalloc(bufsize)) || !(param->clibufsize = bufsize))){
return (21); return (21);
} }
@ -69,33 +68,33 @@ int sockmap(struct clientparam * param, int timeo){
while (!stop&&!conf.timetoexit){ while (!stop&&!conf.timetoexit){
sasize = sizeof(struct sockaddr_in); sasize = sizeof(struct sockaddr_in);
if((param->maxtrafin && param->statssrv >= param->maxtrafin) || (param->maxtrafout && param->statscli >= param->maxtrafout)){ if((param->maxtrafin64 && param->statssrv64 >= param->maxtrafin64) || (param->maxtrafout64 && param->statscli64 >= param->maxtrafout64)){
return (10); return (10);
} }
if((param->srv->logdumpsrv && (param->statssrv > param->srv->logdumpsrv)) || if((param->srv->logdumpsrv && (param->statssrv64 > param->srv->logdumpsrv)) ||
(param->srv->logdumpcli && (param->statscli > param->srv->logdumpcli))) (param->srv->logdumpcli && (param->statscli64 > param->srv->logdumpcli)))
(*param->srv->logfunc)(param, NULL); (*param->srv->logfunc)(param, NULL);
fds[0].events = fds[1].events = 0; fds[0].events = fds[1].events = 0;
if(param->srvinbuf > param->srvoffset && !param->waitclient) { if(param->srvinbuf > param->srvoffset && !param->waitclient64) {
#if DEBUGLEVEL > 2 #if DEBUGLEVEL > 2
(*param->srv->logfunc)(param, "will send to client"); (*param->srv->logfunc)(param, "will send to client");
#endif #endif
fds[0].events |= POLLOUT; fds[0].events |= POLLOUT;
} }
if((param->srvbufsize - param->srvinbuf) > minsize && !param->waitclient && (!param->waitserver ||(received + param->srvinbuf - param->srvoffset < param->waitserver))) { if((param->srvbufsize - param->srvinbuf) > minsize && !param->waitclient64 && (!param->waitserver64 ||(received + param->srvinbuf - param->srvoffset < param->waitserver64))) {
#if DEBUGLEVEL > 2 #if DEBUGLEVEL > 2
(*param->srv->logfunc)(param, "Will recv from server"); (*param->srv->logfunc)(param, "Will recv from server");
#endif #endif
fds[1].events |= POLLIN; fds[1].events |= POLLIN;
} }
if(param->cliinbuf > param->clioffset && !param->waitserver) { if(param->cliinbuf > param->clioffset && !param->waitserver64) {
#if DEBUGLEVEL > 2 #if DEBUGLEVEL > 2
(*param->srv->logfunc)(param, "Will send to server"); (*param->srv->logfunc)(param, "Will send to server");
#endif #endif
fds[1].events |= POLLOUT; fds[1].events |= POLLOUT;
} }
if((param->clibufsize - param->cliinbuf) > minsize && !param->waitserver &&(!param->srv->singlepacket || param->service != S_UDPPM) ) { if((param->clibufsize - param->cliinbuf) > minsize && !param->waitserver64 &&(!param->srv->singlepacket || param->service != S_UDPPM) ) {
#if DEBUGLEVEL > 2 #if DEBUGLEVEL > 2
(*param->srv->logfunc)(param, "Will recv from client"); (*param->srv->logfunc)(param, "Will recv from client");
#endif #endif
@ -128,7 +127,7 @@ int sockmap(struct clientparam * param, int timeo){
if(param->bandlimfunc) { if(param->bandlimfunc) {
sleeptime = (*param->bandlimfunc)(param, param->srvinbuf - param->srvoffset, 0); sleeptime = (*param->bandlimfunc)(param, param->srvinbuf - param->srvoffset, 0);
} }
res = so._sendto(param->clisock, param->srvbuf + param->srvoffset,(!param->waitserver || ((unsigned)param->waitserver - received) > (param->srvinbuf - param->srvoffset))? param->srvinbuf - param->srvoffset : param->waitserver - received, 0, (struct sockaddr*)&param->sinc, sasize); res = so._sendto(param->clisock, param->srvbuf + param->srvoffset,(!param->waitserver64 || (param->waitserver64 - received) > (param->srvinbuf - param->srvoffset))? param->srvinbuf - param->srvoffset : (int)(param->waitserver64 - received), 0, (struct sockaddr*)&param->sincr, sasize);
if(res < 0) { if(res < 0) {
if(errno != EAGAIN && errno != EINTR) return 96; if(errno != EAGAIN && errno != EINTR) return 96;
if(errno == EINTR) usleep(SLEEPTIME); if(errno == EINTR) usleep(SLEEPTIME);
@ -137,7 +136,7 @@ int sockmap(struct clientparam * param, int timeo){
param->srvoffset += res; param->srvoffset += res;
received += res; received += res;
if(param->srvoffset == param->srvinbuf) param->srvoffset = param->srvinbuf = 0; if(param->srvoffset == param->srvinbuf) param->srvoffset = param->srvinbuf = 0;
if(param->waitserver && param->waitserver<= received){ if(param->waitserver64 && param->waitserver64<= received){
return (98); return (98);
} }
if(param->service == S_UDPPM && param->srv->singlepacket) { if(param->service == S_UDPPM && param->srv->singlepacket) {
@ -154,18 +153,18 @@ int sockmap(struct clientparam * param, int timeo){
sl1 = (*param->bandlimfunc)(param, 0, param->cliinbuf - param->clioffset); sl1 = (*param->bandlimfunc)(param, 0, param->cliinbuf - param->clioffset);
if(sl1 > sleeptime) sleeptime = sl1; if(sl1 > sleeptime) sleeptime = sl1;
} }
res = so._sendto(param->remsock, param->clibuf + param->clioffset, (!param->waitclient || ((unsigned)param->waitclient - sent) > (param->cliinbuf - param->clioffset))? param->cliinbuf - param->clioffset : param->waitclient - sent, 0, (struct sockaddr*)&param->sins, sasize); res = so._sendto(param->remsock, param->clibuf + param->clioffset, (!param->waitclient64 || (param->waitclient64 - sent) > (param->cliinbuf - param->clioffset))? param->cliinbuf - param->clioffset : (int)(param->waitclient64 - sent), 0, (struct sockaddr*)&param->sinsr, sasize);
if(res < 0) { if(res < 0) {
if(errno != EAGAIN && errno != EINTR) return 97; if(errno != EAGAIN && errno != EINTR) return 97;
if(errno == EINTR) usleep(SLEEPTIME); if(errno == EINTR) usleep(SLEEPTIME);
continue; continue;
} }
param->clioffset += res; param->clioffset += res;
sent += res;
param->statscli += res;
param->nwrites++;
if(param->clioffset == param->cliinbuf) param->clioffset = param->cliinbuf = 0; if(param->clioffset == param->cliinbuf) param->clioffset = param->cliinbuf = 0;
if(param->waitclient && param->waitclient<= sent) { sent += res;
param->nwrites++;
param->statscli64 += res;
if(param->waitclient64 && param->waitclient64<= sent) {
return (99); return (99);
} }
} }
@ -173,7 +172,7 @@ int sockmap(struct clientparam * param, int timeo){
#if DEBUGLEVEL > 2 #if DEBUGLEVEL > 2
(*param->srv->logfunc)(param, "recv from client"); (*param->srv->logfunc)(param, "recv from client");
#endif #endif
res = so._recvfrom(param->clisock, param->clibuf + param->cliinbuf, param->clibufsize - param->cliinbuf, 0, (struct sockaddr *)&param->sinc, &sasize); res = so._recvfrom(param->clisock, param->clibuf + param->cliinbuf, param->clibufsize - param->cliinbuf, 0, (struct sockaddr *)&param->sincr, &sasize);
if (res==0) { if (res==0) {
so._shutdown(param->clisock, SHUT_RDWR); so._shutdown(param->clisock, SHUT_RDWR);
so._closesocket(param->clisock); so._closesocket(param->clisock);
@ -219,7 +218,7 @@ int sockmap(struct clientparam * param, int timeo){
} }
param->srvinbuf += res; param->srvinbuf += res;
param->nreads++; param->nreads++;
param->statssrv += res; param->statssrv64 += res;
if(!param->nolongdatfilter){ if(!param->nolongdatfilter){
action = handledatfltsrv(param, &param->srvbuf, &param->srvbufsize, param->srvinbuf - res, &param->srvinbuf); action = handledatfltsrv(param, &param->srvbuf, &param->srvbufsize, param->srvinbuf - res, &param->srvinbuf);
if(action == HANDLED){ if(action == HANDLED){
@ -241,26 +240,26 @@ int sockmap(struct clientparam * param, int timeo){
#if DEBUGLEVEL > 2 #if DEBUGLEVEL > 2
(*param->srv->logfunc)(param, "finished with mapping"); (*param->srv->logfunc)(param, "finished with mapping");
#endif #endif
while(!param->waitclient && param->srvinbuf > param->srvoffset && param->clisock != INVALID_SOCKET){ while(!param->waitclient64 && param->srvinbuf > param->srvoffset && param->clisock != INVALID_SOCKET){
#if DEBUGLEVEL > 2 #if DEBUGLEVEL > 2
(*param->srv->logfunc)(param, "flushing buffer to client"); (*param->srv->logfunc)(param, "flushing buffer to client");
#endif #endif
res = socksendto(param->clisock, &param->sinc, param->srvbuf + param->srvoffset, param->srvinbuf - param->srvoffset, conf.timeouts[STRING_S] * 1000); res = socksendto(param->clisock, (struct sockaddr *)&param->sincr, param->srvbuf + param->srvoffset, param->srvinbuf - param->srvoffset, conf.timeouts[STRING_S] * 1000);
if(res > 0){ if(res > 0){
param->srvoffset += res; param->srvoffset += res;
param->statssrv += res; param->statssrv64 += res;
if(param->srvoffset == param->srvinbuf) param->srvoffset = param->srvinbuf = 0; if(param->srvoffset == param->srvinbuf) param->srvoffset = param->srvinbuf = 0;
} }
else break; else break;
} }
while(!param->waitserver && param->cliinbuf > param->clioffset && param->remsock != INVALID_SOCKET){ while(!param->waitserver64 && param->cliinbuf > param->clioffset && param->remsock != INVALID_SOCKET){
#if DEBUGLEVEL > 2 #if DEBUGLEVEL > 2
(*param->srv->logfunc)(param, "flushing buffer to server"); (*param->srv->logfunc)(param, "flushing buffer to server");
#endif #endif
res = socksendto(param->remsock, &param->sins, param->clibuf + param->clioffset, param->cliinbuf - param->clioffset, conf.timeouts[STRING_S] * 1000); res = socksendto(param->remsock, (struct sockaddr *)&param->sinsr, param->clibuf + param->clioffset, param->cliinbuf - param->clioffset, conf.timeouts[STRING_S] * 1000);
if(res > 0){ if(res > 0){
param->clioffset += res; param->clioffset += res;
param->statscli += res; param->statscli64 += res;
if(param->cliinbuf == param->clioffset) param->cliinbuf = param->clioffset = 0; if(param->cliinbuf == param->clioffset) param->cliinbuf = param->clioffset = 0;
} }
else break; else break;

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: socks.c,v 1.34 2009/09/17 12:21:09 v.dubrovin Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -22,17 +21,21 @@ void * sockschild(struct clientparam* param) {
SOCKET s; SOCKET s;
unsigned size; unsigned size;
SASIZETYPE sasize; SASIZETYPE sasize;
unsigned short port = 0;
unsigned char * buf=NULL; unsigned char * buf=NULL;
unsigned char c; unsigned char c;
unsigned char command=0; unsigned char command=0;
struct pollfd fds[3]; struct pollfd fds[3];
int ver=0; int ver=0;
int havepass = 0; int havepass = 0;
struct sockaddr_in sin; #ifndef NOIPV6
struct sockaddr_in6 sin = {AF_INET6};
#else
struct sockaddr_in sin = {AF_INET};
#endif
int len; int len;
param->req.sin_addr.s_addr = 0;
param->service = S_SOCKS; param->service = S_SOCKS;
if(!(buf = myalloc(BUFSIZE))) {RETURN(21);} if(!(buf = myalloc(BUFSIZE))) {RETURN(21);}
@ -44,29 +47,29 @@ void * sockschild(struct clientparam* param) {
if(ver == 5){ if(ver == 5){
if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} /* nmethods */ if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);} /* nmethods */
for (; i; i--) { for (; i; i--) {
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(442);} if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
if (res == 2 && !param->srv->nouser) { if (res == 2 && !param->srv->nouser) {
havepass = res; havepass = res;
} }
} }
buf[0] = 5; buf[0] = 5;
buf[1] = havepass; buf[1] = havepass;
if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(402);} if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(401);}
if (havepass) { if (havepass) {
if (((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0))) != 1) { if (((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0))) != 1) {
RETURN(412); RETURN(412);
} }
if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(443);} if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);}
if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(444);}; if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(441);};
buf[i] = 0; buf[i] = 0;
if(!param->username)param->username = (unsigned char *)mystrdup((char *)buf); if(!param->username)param->username = (unsigned char *)mystrdup((char *)buf);
if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(445);} if ((i = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(445);}
if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(446);}; if (i && (unsigned)(res = sockgetlinebuf(param, CLIENT, buf, i, 0, conf.timeouts[STRING_S])) != i){RETURN(441);};
buf[i] = 0; buf[i] = 0;
if(!param->password)param->password = (unsigned char *)mystrdup((char *)buf); if(!param->password)param->password = (unsigned char *)mystrdup((char *)buf);
buf[0] = 1; buf[0] = 1;
buf[1] = 0; buf[1] = 0;
if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(402);} if(socksend(param->clisock, buf, 2, conf.timeouts[STRING_S])!=2){RETURN(481);}
} }
if ((c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5) { if ((c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_L], 0)) != 5) {
RETURN(421); RETURN(421);
@ -78,113 +81,134 @@ void * sockschild(struct clientparam* param) {
c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0); /* atype */ c = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0); /* atype */
} }
else { else {
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(448);} if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
buf[0] = (unsigned char) res; buf[0] = (unsigned char) res;
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(449);} if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
buf[1] = (unsigned char) res; buf[1] = (unsigned char) res;
param->sins.sin_port = param->req.sin_port = *(unsigned short*)buf; port = *(unsigned short*)buf;
c = 1; c = 1;
} }
size = 4;
*SAFAMILY(&param->sinsr) = *SAFAMILY(&param->req) = AF_INET;
switch(c) { switch(c) {
#ifndef NOIPV6
case 4:
if(param->srv->family == 4) RETURN(997);
size = 16;
*SAFAMILY(&param->sinsr) = *SAFAMILY(&param->req) = AF_INET6;
#endif
case 1: case 1:
for (i = 0; i<4; i++){ for (i = 0; i<size; i++){
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(450);} if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
buf[i] = (unsigned char)res; buf[i] = (unsigned char)res;
} }
param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr = *(unsigned long *)buf; #ifndef NOIPV6
if(command==1 && !param->req.sin_addr.s_addr) { if (c == 1 && param->srv->family==6){
RETURN(422); char prefix[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255};
*SAFAMILY(&param->sinsr) = *SAFAMILY(&param->req) = AF_INET6;
memcpy(SAADDR(&param->sinsr), prefix, 12);
memcpy(12 + (char *)SAADDR(&param->sinsr), buf, 4);
memcpy(SAADDR(&param->req), prefix, 12);
memcpy(12 + (char *)SAADDR(&param->req), buf, 4);
} }
myinet_ntoa(param->sins.sin_addr, (char *)buf); else {
#endif
memcpy(SAADDR(&param->sinsr), buf, size);
memcpy(SAADDR(&param->req), buf, size);
#ifndef NOIPV6
}
#endif
if(SAISNULL(&param->req)) {
RETURN(421);
}
myinet_ntop(*SAFAMILY(&param->sinsr), SAADDR(&param->sinsr), (char *)buf, 64);
break; break;
case 3: case 3:
if ((size = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} /* nmethods */ if ((size = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);} /* nmethods */
for (i=0; i<size; i++){ /* size < 256 */ for (i=0; i<size; i++){ /* size < 256 */
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(452);} if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(451);}
buf[i] = (unsigned char)res; buf[i] = (unsigned char)res;
} }
buf[i] = 0; buf[i] = 0;
param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr = getip(buf); if(!getip46(param->srv->family, buf, (struct sockaddr *) &param->req)) RETURN(100);
if(command==1 && !param->req.sin_addr.s_addr) { memcpy(&param->sinsr, &param->req, sizeof(param->req));
RETURN(100);
}
break; break;
default: default:
RETURN(998); RETURN(997);
} }
if(param->hostname)myfree(param->hostname); if(param->hostname)myfree(param->hostname);
param->hostname = (unsigned char *)mystrdup((char *)buf); param->hostname = (unsigned char *)mystrdup((char *)buf);
if (ver == 5) { if (ver == 5) {
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(453);} if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
buf[0] = (unsigned char) res; buf[0] = (unsigned char) res;
if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(454);} if ((res = sockgetcharcli(param, conf.timeouts[SINGLEBYTE_S], 0)) == EOF) {RETURN(441);}
buf[1] = (unsigned char) res; buf[1] = (unsigned char) res;
param->sins.sin_port = param->req.sin_port = *(unsigned short*)buf; port = *(unsigned short*)buf;
} }
else { else {
sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]); sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]);
buf[127] = 0; buf[127] = 0;
if(!param->srv->nouser && *buf && !param->username)param->username = (unsigned char *)mystrdup((char *)buf); if(!param->srv->nouser && *buf && !param->username)param->username = (unsigned char *)mystrdup((char *)buf);
if(param->sins.sin_addr.s_addr && ntohl(param->sins.sin_addr.s_addr)<256){ if(!memcmp(SAADDR(&param->req), "\0\0\0", 3)){
param->service = S_SOCKS45; param->service = S_SOCKS45;
sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]); sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 1, 0, conf.timeouts[STRING_S]);
buf[127] = 0; buf[127] = 0;
if(param->hostname)myfree(param->hostname); if(param->hostname)myfree(param->hostname);
param->hostname = (unsigned char *)mystrdup((char *)buf); param->hostname = (unsigned char *)mystrdup((char *)buf);
param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr = getip(buf); if(!getip46(param->srv->family, buf, (struct sockaddr *) &param->req)) RETURN(100);
memcpy(&param->sinsr, &param->req, sizeof(&param->req));
} }
} }
if(command == 1 && !param->req.sin_port) {RETURN(424);}
param->sins.sin_family = AF_INET; *SAPORT(&param->sinsr) = *SAPORT(&param->req) = port;
if(command == 1 && !*SAPORT(&param->sinsr)) {RETURN(421);}
switch(command) { switch(command) {
case 1: case 1:
param->operation = CONNECT; param->operation = CONNECT;
break; break;
case 2: case 2:
param->sins.sin_addr.s_addr = param->extip;
param->sins.sin_port = param->extport?param->extport:param->req.sin_port;
if ((param->remsock=so._socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN (11);}
param->operation = BIND;
break;
case 3: case 3:
param->sins.sin_port = param->extport?param->extport:param->req.sin_port;
param->sins.sin_addr.s_addr = param->extip; #ifndef NOIPV6
if ((param->remsock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);} memcpy(&param->sinsl, *SAFAMILY(&param->req)==AF_INET6? (struct sockaddr *)&param->srv->extsa6:(struct sockaddr *)&param->srv->extsa, SASIZE(&param->req));
param->operation = UDPASSOC; #else
memcpy(&param->sinsl, &param->srv->extsa, SASIZE(&param->req));
#endif
if ((param->remsock=so._socket(SASOCK(&param->req), command == 2? SOCK_STREAM:SOCK_DGRAM, command == 2?IPPROTO_TCP:IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
param->operation = command == 2?BIND:UDPASSOC;
break; break;
default: default:
RETURN(997); RETURN(997);
} }
if((res = (*param->srv->authfunc)(param))) {RETURN(res);} if((res = (*param->srv->authfunc)(param))) {
RETURN(res);
}
if(command > 1) { if(command > 1) {
if(so._bind(param->remsock,(struct sockaddr *)&param->sins,sizeof(param->sins))) { if(so._bind(param->remsock,(struct sockaddr *)&param->sinsl,SASIZE(&param->sinsl))) {
param->sins.sin_port = 0; *SAPORT(&param->sinsl) = 0;
if(so._bind(param->remsock,(struct sockaddr *)&param->sins,sizeof(param->sins)))RETURN (12); if(so._bind(param->remsock,(struct sockaddr *)&param->sinsl,SASIZE(&param->sinsl)))RETURN (12);
#if SOCKSTRACE > 0 #if SOCKSTRACE > 0
fprintf(stderr, "%s:%hu binded to communicate with server\n", fprintf(stderr, "%hu binded to communicate with server\n", *SAPORT(&param->sins));
inet_ntoa(param->sins.sin_addr),
ntohs(param->sins.sin_port)
);
fflush(stderr); fflush(stderr);
#endif #endif
} }
sasize = sizeof(struct sockaddr_in); sasize = SASIZE(&param->sinsl);
so._getsockname(param->remsock, (struct sockaddr *)&param->sins, &sasize); so._getsockname(param->remsock, (struct sockaddr *)&param->sinsl, &sasize);
if(command == 3) { if(command == 3) {
param->ctrlsock = param->clisock; param->ctrlsock = param->clisock;
param->clisock = so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); param->clisock = so._socket(SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP);
if(param->clisock == INVALID_SOCKET) {RETURN(11);} if(param->clisock == INVALID_SOCKET) {RETURN(11);}
sin.sin_family = AF_INET; memcpy(&sin, &param->sincl, sizeof(&sin));
sin.sin_addr.s_addr = param->srv->intip; *SAPORT(&sin) = 0;
sin.sin_port = htons(0); if(so._bind(param->clisock,(struct sockaddr *)&sin,sizeof(sin))) {RETURN (12);}
if(so._bind(param->clisock,(struct sockaddr *)&sin,sizeof(struct sockaddr_in))) {RETURN (12);}
#if SOCKSTRACE > 0 #if SOCKSTRACE > 0
fprintf(stderr, "%s:%hu binded to communicate with client\n", fprintf(stderr, "%hu binded to communicate with client\n",
inet_ntoa(sin.sin_addr), ntohs(*SAPORT(&sin))
ntohs(sin.sin_port)
); );
fflush(stderr); fflush(stderr);
#endif #endif
@ -195,7 +219,9 @@ fflush(stderr);
CLEANRET: CLEANRET:
if(param->clisock != INVALID_SOCKET){ if(param->clisock != INVALID_SOCKET){
sasize = sizeof(struct sockaddr_in); int repcode;
sasize = sizeof(sin);
if(command != 3) so._getsockname(param->remsock, (struct sockaddr *)&sin, &sasize); if(command != 3) so._getsockname(param->remsock, (struct sockaddr *)&sin, &sasize);
else so._getsockname(param->clisock, (struct sockaddr *)&sin, &sasize); else so._getsockname(param->clisock, (struct sockaddr *)&sin, &sasize);
#if SOCKSTRACE > 0 #if SOCKSTRACE > 0
@ -207,20 +233,27 @@ fprintf(stderr, "Sending confirmation to client with code %d for %s with %s:%hu\
); );
fflush(stderr); fflush(stderr);
#endif #endif
if(!param->res) repcode = 0;
else if(param->res <= 10) repcode = 2;
else if (param->res < 20) repcode = 5;
else if (param->res < 30) repcode = 1;
else if (param->res < 100) repcode = 4;
else repcode = param->res%10;
if(ver == 5){ if(ver == 5){
buf[0] = 5; buf[0] = 5;
buf[1] = param->res%10; buf[1] = repcode;
buf[2] = 0; buf[2] = 0;
buf[3] = 1; buf[3] = (*SAFAMILY(&sin) == AF_INET)?1:4;
memcpy(buf+4, &sin.sin_addr.s_addr, 4); memcpy(buf+4, SAADDR(&sin), SAADDRLEN(&sin));
memcpy(buf+8, &sin.sin_port, 2); memcpy(buf+4+SAADDRLEN(&sin), SAPORT(&sin), 2);
socksend((command == 3)?param->ctrlsock:param->clisock, buf, 10, conf.timeouts[STRING_S]); socksend((command == 3)?param->ctrlsock:param->clisock, buf, 6+SAADDRLEN(&sin), conf.timeouts[STRING_S]);
} }
else{ else{
buf[0] = 0; buf[0] = 0;
buf[1] = 90 + (param->res%10); buf[1] = 90 + !!(repcode);
memcpy(buf+2, &sin.sin_port, 2); memcpy(buf+2, SAPORT(&sin), 2);
memcpy(buf+4, &sin.sin_addr.s_addr, 4); memcpy(buf+4, SAADDR(&sin), 4);
socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]); socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]);
} }
@ -239,48 +272,48 @@ fflush(stderr);
fds[0].fd = param->remsock; fds[0].fd = param->remsock;
fds[1].fd = param->clisock; fds[1].fd = param->clisock;
fds[0].events = fds[1].events = POLLIN; fds[0].events = fds[1].events = POLLIN;
res = so._poll(fds, 2, conf.timeouts[(param->req.sin_addr.s_addr)?CONNECTION_S:CONNECTION_L] * 1000); res = so._poll(fds, 2, conf.timeouts[CONNECTION_L] * 1000);
if (res < 1 || fds[1].revents) { if (res < 1 || fds[1].revents) {
res = 460; res = 460;
break; break;
} }
sasize = sizeof(param->sins); sasize = sizeof(param->sinsr);
s = so._accept(param->remsock, (struct sockaddr *)&param->sins, &sasize); s = so._accept(param->remsock, (struct sockaddr *)&param->sinsr, &sasize);
so._closesocket(param->remsock); so._closesocket(param->remsock);
param->remsock = s; param->remsock = s;
if(s == INVALID_SOCKET) { if(s == INVALID_SOCKET) {
param->res = 462; param->res = 462;
break; break;
} }
if(param->req.sin_addr.s_addr && param->req.sin_addr.s_addr != param->sins.sin_addr.s_addr) { if(SAISNULL(&param->req) &&
memcmp(SAADDR(&param->req),SAADDR(&param->sinsr),SAADDRLEN(&param->req))) {
param->res = 470; param->res = 470;
break; break;
} }
#if SOCKSTRACE > 0 #if SOCKSTRACE > 0
fprintf(stderr, "Sending incoming connection to client with code %d for %s with %s:%hu\n", fprintf(stderr, "Sending incoming connection to client with code %d for %s with %hu\n",
param->res, param->res,
commands[command], commands[command],
inet_ntoa(param->sins.sin_addr), *SAPORT(param->sins);
ntohs(param->sins.sin_port)
); );
fflush(stderr); fflush(stderr);
#endif #endif
if(ver == 5){ if(ver == 5){
memcpy (buf+4, &param->sins.sin_addr, 4); buf[3] = (*SAFAMILY(&param->sinsr) == AF_INET)?1:4;
memcpy (buf+8, &param->sins.sin_port, 2); memcpy(buf+4, SAADDR(&param->sinsr), SAADDRLEN(&param->sinsr));
socksend(param->clisock, buf, 10, conf.timeouts[STRING_S]); memcpy(buf+4+SAADDRLEN(&param->sinsr), SAPORT(&param->sinsr), 2);
socksend(param->clisock, buf, 6+SAADDRLEN(&param->sinsr), conf.timeouts[STRING_S]);
} }
else { else {
memcpy (buf+2, &param->sins.sin_port, 2); memcpy (buf+2, SAPORT(&param->sinsr), 2);
memcpy (buf+4, &param->sins.sin_addr, 4); memcpy (buf+4, SAADDR(&param->sinsr), 4);
socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]); socksend(param->clisock, buf, 8, conf.timeouts[STRING_S]);
} }
param->res = sockmap(param, conf.timeouts[CONNECTION_S]); param->res = sockmap(param, conf.timeouts[CONNECTION_S]);
break; break;
case 3: case 3:
param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr; memcpy(&param->sinsr, &param->req, sizeof(param->sinsr));
param->sins.sin_port = param->req.sin_port;
myfree(buf); myfree(buf);
if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);} if(!(buf = myalloc(LARGEBUFSIZE))) {RETURN(21);}
@ -300,12 +333,12 @@ fflush(stderr);
break; break;
} }
if (fds[1].revents) { if (fds[1].revents) {
sasize = sizeof(struct sockaddr_in); sasize = sizeof(sin);
if((len = so._recvfrom(param->clisock, buf, 65535, 0, (struct sockaddr *)&sin, &sasize)) <= 10) { if((len = so._recvfrom(param->clisock, buf, 65535, 0, (struct sockaddr *)&sin, &sasize)) <= 10) {
param->res = 464; param->res = 464;
break; break;
} }
if(sin.sin_addr.s_addr != param->sinc.sin_addr.s_addr){ if(SAADDRLEN(&sin) != SAADDRLEN(&param->sincr) || memcmp(SAADDR(&sin), SAADDR(&param->sincr), SAADDRLEN(&sin))){
param->res = 465; param->res = 465;
break; break;
} }
@ -313,10 +346,14 @@ fflush(stderr);
param->res = 466; param->res = 466;
break; break;
} }
size = 4;
switch(buf[3]) { switch(buf[3]) {
case 4:
size = 16;
case 1: case 1:
i = 8; i = 4+size;
memcpy(&param->sins.sin_addr.s_addr, buf+4, 4); memcpy(SAADDR(&param->sinsr), buf+4, size);
*SAFAMILY(&param->sinsr) = (size == 4)?AF_INET:AF_INET6;
break; break;
case 3: case 3:
size = buf[4]; size = buf[4];
@ -324,22 +361,22 @@ fflush(stderr);
buf[i] = buf[i+1]; buf[i] = buf[i+1];
} }
buf[i++] = 0; buf[i++] = 0;
param->sins.sin_addr.s_addr = getip(buf+4); if(!getip46(param->srv->family, buf, (struct sockaddr *) &param->sinsr)) RETURN(100);
break; break;
default: default:
RETURN(996); RETURN(997);
} }
memcpy(&param->sins.sin_port, buf+i, 2); memcpy(SAPORT(&param->sinsr), buf+i, 2);
i+=2; i+=2;
sasize = sizeof(param->sins); sasize = sizeof(param->sinsr);
if(len > (int)i){ if(len > (int)i){
if(socksendto(param->remsock, &param->sins, buf+i, len - i, conf.timeouts[SINGLEBYTE_L]*1000) <= 0){ if(socksendto(param->remsock, (struct sockaddr *)&param->sinsr, buf+i, len - i, conf.timeouts[SINGLEBYTE_L]*1000) <= 0){
param->res = 467; param->res = 467;
break; break;
} }
param->statscli+=(len - i); param->statscli64+=(len - i);
param->nwrites++; param->nwrites++;
#if SOCKSTRACE > 1 #if SOCKSTRACE > 1
fprintf(stderr, "UDP packet relayed from client to %s:%hu size %d, header %d\n", fprintf(stderr, "UDP packet relayed from client to %s:%hu size %d, header %d\n",
@ -358,27 +395,25 @@ fflush(stderr);
} }
if (fds[0].revents) { if (fds[0].revents) {
struct sockaddr_in tsin; sasize = sizeof(param->sinsr);
sasize = sizeof(tsin);
buf[0]=buf[1]=buf[2]=0; buf[0]=buf[1]=buf[2]=0;
buf[3]=1; buf[3]=(*SAFAMILY(&param->sinsl) == AF_INET)?1:4;
if((len = so._recvfrom(param->remsock, buf+10, 65535 - 10, 0, (struct sockaddr *)&tsin, &sasize)) <= 0) { if((len = so._recvfrom(param->remsock, buf+6+SAADDRLEN(&param->sinsl), 65535 - 10, 0, (struct sockaddr *)&param->sinsr, &sasize)) <= 0) {
param->res = 468; param->res = 468;
break; break;
} }
param->statssrv+=len; param->statssrv64+=len;
param->nreads++; param->nreads++;
memcpy(buf+4, &tsin.sin_addr.s_addr, 4); memcpy(buf+4, SAADDR(&param->sinsr), SAADDRLEN(&param->sinsr));
memcpy(buf+8, &tsin.sin_port, 2); memcpy(buf+4+SAADDRLEN(&param->sinsr), SAPORT(&param->sinsr), 2);
sasize = sizeof(param->sins); sasize = sizeof(sin);
if(socksendto(param->clisock, &sin, buf, len + 10, conf.timeouts[SINGLEBYTE_L]*1000) <=0){ if(socksendto(param->clisock, (struct sockaddr *)&sin, buf, len + 6 + SAADDRLEN(&param->sinsr), conf.timeouts[SINGLEBYTE_L]*1000) <=0){
param->res = 469; param->res = 469;
break; break;
} }
#if SOCKSTRACE > 1 #if SOCKSTRACE > 1
fprintf(stderr, "UDP packet relayed to client from %s:%hu size %d\n", fprintf(stderr, "UDP packet relayed to client from %hu size %d\n",
inet_ntoa(tsin.sin_addr), ntohs(*SAPORT(&param->sinsr)),
ntohs(tsin.sin_port),
len len
); );
fflush(stderr); fflush(stderr);
@ -400,8 +435,9 @@ fflush(stderr);
if(param->hostname){ if(param->hostname){
sprintf((char *)buf + strlen((char *)buf), "%.265s", param->hostname); sprintf((char *)buf + strlen((char *)buf), "%.265s", param->hostname);
} }
else myinet_ntoa(param->req.sin_addr, (char *)buf+strlen((char *)buf)); else
sprintf((char *)buf+strlen((char *)buf), ":%hu", ntohs(param->req.sin_port)); myinet_ntop(*SAFAMILY(&param->req), SAADDR(&param->req), (char *)buf + strlen((char *)buf), 64);
sprintf((char *)buf+strlen((char *)buf), ":%hu", ntohs(*SAPORT(&param->req)));
(*param->srv->logfunc)(param, buf); (*param->srv->logfunc)(param, buf);
myfree(buf); myfree(buf);
} }

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: stringtable.c,v 1.16 2009/07/20 18:16:03 v.dubrovin Exp $
*/ */
#include <stdio.h> #include <stdio.h>
@ -30,8 +29,9 @@ unsigned char * strings[] = {
/* 16 */ (unsigned char *)"FTPPR", /* 16 */ (unsigned char *)"FTPPR",
/* 17 */ (unsigned char *)"SMTPP", /* 17 */ (unsigned char *)"SMTPP",
/* 18 */ (unsigned char *)"ICQPR", /* 18 */ (unsigned char *)"ICQPR",
/* 19 */ (unsigned char *)"MSNPR", /* 19 (unsigned char *)"MSNPR", */
/* 20 */ (unsigned char *)"ZOMBIE", /* 19 */ (unsigned char *)"ZOMBIE",
/* 20 */ NULL,
/* 21 */ NULL, /* 21 */ NULL,
/* 22 */ NULL, /* 22 */ NULL,
/* 23 */ NULL, /* 23 */ NULL,

View File

@ -6,6 +6,12 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#ifndef NOPSTDINT
#include "pstdint.h"
#else
typedef unsigned long uint64_t
#define PRINTF_INT64_MODIFIER "l"
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -22,12 +28,12 @@ extern "C" {
#define INVALID_SOCKET (-1) #define INVALID_SOCKET (-1)
#else #else
#include <winsock2.h> #include <winsock2.h>
#include <Ws2tcpip.h>
#define pthread_mutex_t CRITICAL_SECTION #define pthread_mutex_t CRITICAL_SECTION
#define pthread_mutex_init(x, y) InitializeCriticalSection(x) #define pthread_mutex_init(x, y) InitializeCriticalSection(x)
#define pthread_mutex_lock(x) EnterCriticalSection(x) #define pthread_mutex_lock(x) EnterCriticalSection(x)
#define pthread_mutex_unlock(x) LeaveCriticalSection(x) #define pthread_mutex_unlock(x) LeaveCriticalSection(x)
#define pthread_mutex_destroy(x) DeleteCriticalSection(x) #define pthread_mutex_destroy(x) DeleteCriticalSection(x)
typedef unsigned (__stdcall *BEGINTHREADFUNC)(void *);
#ifdef MSVC #ifdef MSVC
#pragma warning (disable : 4996) #pragma warning (disable : 4996)
#endif #endif
@ -92,6 +98,26 @@ int
#define IM_MSN 0x00400000 #define IM_MSN 0x00400000
#define ADMIN 0x01000000 #define ADMIN 0x01000000
#define SAFAMILY(sa) (&(((struct sockaddr_in *)sa)->sin_family))
#ifndef NOIPV6
#define SAPORT(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? &((struct sockaddr_in6 *)sa)->sin6_port : &((struct sockaddr_in *)sa)->sin_port)
#define SAADDR(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? (unsigned char *)&((struct sockaddr_in6 *)sa)->sin6_addr : (unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr)
#define SAADDRLEN(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4)
#define SASOCK(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? PF_INET6:PF_INET)
#define SASIZE(sa) (((struct sockaddr_in *)sa)->sin_family == AF_INET6? sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in))
#define SAISNULL(sa) (!memcmp(((struct sockaddr_in *)sa)->sin_family == AF_INET6? (unsigned char *)&((struct sockaddr_in6 *)sa)->sin6_addr : (unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr, NULLADDR, (((struct sockaddr_in *)sa)->sin_family == AF_INET6? 16:4)))
#else
#define SAPORT(sa) (&((struct sockaddr_in *)sa)->sin_port)
#define SAADDR(sa) ((unsigned char *)&((struct sockaddr_in *)sa)->sin_addr.s_addr)
#define SAADDRLEN(sa) (4)
#define SASOCK(sa) (PF_INET)
#define SASIZE(sa) (sizeof(struct sockaddr_in))
#define SAISNULL(sa) (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0)
#endif
extern char* NULLADDR;
typedef enum { typedef enum {
CLIENT, CLIENT,
SERVER SERVER
@ -113,7 +139,11 @@ typedef enum {
S_FTPPR, S_FTPPR,
S_SMTPP, S_SMTPP,
S_ICQPR, S_ICQPR,
S_REVLI,
S_REVCO,
/*
S_MSNPR, S_MSNPR,
*/
S_ZOMBIE S_ZOMBIE
}PROXYSERVICE; }PROXYSERVICE;
@ -126,14 +156,13 @@ struct srvparam;
typedef void (*LOGFUNC)(struct clientparam * param, const unsigned char *); typedef void (*LOGFUNC)(struct clientparam * param, const unsigned char *);
typedef int (*AUTHFUNC)(struct clientparam * param); typedef int (*AUTHFUNC)(struct clientparam * param);
typedef void * (*REDIRECTFUNC)(struct clientparam * param); typedef void * (*REDIRECTFUNC)(struct clientparam * param);
typedef unsigned long (*RESOLVFUNC)(unsigned char *); typedef unsigned long (*RESOLVFUNC)(int af, unsigned char *name, unsigned char *value);
typedef unsigned (*BANDLIMFUNC)(struct clientparam * param, unsigned nbytesin, unsigned nbytesout); typedef unsigned (*BANDLIMFUNC)(struct clientparam * param, unsigned nbytesin, unsigned nbytesout);
typedef void (*TRAFCOUNTFUNC)(struct clientparam * param); typedef void (*TRAFCOUNTFUNC)(struct clientparam * param);
typedef void * (*EXTENDFUNC) (struct node *node); typedef void * (*EXTENDFUNC) (struct node *node);
typedef void (*CBFUNC)(void *cb, char * buf, int inbuf); typedef void (*CBFUNC)(void *cb, char * buf, int inbuf);
typedef void (*PRINTFUNC) (struct node *node, CBFUNC cbf, void*cb); typedef void (*PRINTFUNC) (struct node *node, CBFUNC cbf, void*cb);
typedef int (*PLUGINFUNC) (struct pluginlink *pluginlink, int argc, char** argv); typedef int (*PLUGINFUNC) (struct pluginlink *pluginlink, int argc, char** argv);
typedef void * (*PTHREADFUNC)(void *);
struct auth { struct auth {
struct auth *next; struct auth *next;
@ -144,8 +173,14 @@ struct auth {
struct iplist { struct iplist {
struct iplist *next; struct iplist *next;
unsigned long ip; int family;
unsigned long mask; #ifndef NOIPV6
struct in6_addr ip_from;
struct in6_addr ip_to;
#else
struct in_addr ip_from;
struct in_addr ip_to;
#endif
}; };
struct portlist { struct portlist {
@ -196,8 +231,11 @@ typedef enum {
struct chain { struct chain {
struct chain * next; struct chain * next;
int type; int type;
unsigned long redirip; #ifndef NOIPV6
unsigned short redirport; struct sockaddr_in6 addr;
#else
struct sockaddr_in addr;
#endif
unsigned short weight; unsigned short weight;
unsigned char * extuser; unsigned char * extuser;
unsigned char * extpass; unsigned char * extpass;
@ -257,16 +295,24 @@ struct trafcount {
struct ace *ace; struct ace *ace;
unsigned number; unsigned number;
ROTATION type; ROTATION type;
unsigned long traf; uint64_t traf64;
unsigned long trafgb; uint64_t traflim64;
unsigned long traflim;
unsigned long traflimgb;
char * comment; char * comment;
int disabled; int disabled;
time_t cleared; time_t cleared;
time_t updated; time_t updated;
}; };
struct nserver {
#ifndef NOIPV6
struct sockaddr_in6 addr;
#else
struct sockaddr_in addr;
#endif
int usetcp;
};
extern int numservers;
typedef void * (* PROXYFUNC)(struct clientparam *); typedef void * (* PROXYFUNC)(struct clientparam *);
typedef enum { typedef enum {
@ -314,7 +360,7 @@ struct srvparam {
LOGFUNC logfunc; LOGFUNC logfunc;
AUTHFUNC authfunc; AUTHFUNC authfunc;
PROXYFUNC pf; PROXYFUNC pf;
SOCKET srvsock; SOCKET srvsock, cbsock;
int childcount; int childcount;
int maxchild; int maxchild;
int version; int version;
@ -324,10 +370,17 @@ struct srvparam {
int silent; int silent;
int transparent; int transparent;
int nfilters, nreqfilters, nhdrfilterscli, nhdrfilterssrv, npredatfilters, ndatfilterscli, ndatfilterssrv; int nfilters, nreqfilters, nhdrfilterscli, nhdrfilterssrv, npredatfilters, ndatfilterscli, ndatfilterssrv;
int family;
unsigned bufsize; unsigned bufsize;
unsigned logdumpsrv, logdumpcli; unsigned logdumpsrv, logdumpcli;
unsigned long intip; #ifndef NOIPV6
unsigned long extip; struct sockaddr_in6 intsa;
struct sockaddr_in6 extsa6;
struct sockaddr_in6 extsa;
#else
struct sockaddr_in intsa;
struct sockaddr_in extsa;
#endif
pthread_mutex_t counter_mutex; pthread_mutex_t counter_mutex;
struct pollfd fds; struct pollfd fds;
FILE *stdlog; FILE *stdlog;
@ -340,8 +393,6 @@ struct srvparam {
unsigned char * logformat; unsigned char * logformat;
unsigned char * logtarget; unsigned char * logtarget;
unsigned char * nonprintable; unsigned char * nonprintable;
unsigned short intport;
unsigned short extport;
unsigned short targetport; unsigned short targetport;
unsigned char replace; unsigned char replace;
time_t time_start; time_t time_start;
@ -377,8 +428,8 @@ struct clientparam {
int res, int res,
status; status;
unsigned waitclient, uint64_t waitclient64,
waitserver; waitserver64;
int pwtype, int pwtype,
threadid, threadid,
weight, weight,
@ -402,26 +453,26 @@ struct clientparam {
srvoffset, srvoffset,
clibufsize, clibufsize,
srvbufsize, srvbufsize,
msec_start, msec_start;
maxtrafin, uint64_t
maxtrafout; maxtrafin64,
maxtrafout64;
#ifndef NOIPV6
struct sockaddr_in6 sincl, sincr, sinsl, sinsr, req;
#else
struct sockaddr_in sincl, sincr, sinsl, sinsr, req;
#endif
struct sockaddr_in sinc, uint64_t statscli64,
sins, statssrv64;
req; unsigned long
unsigned long statscli,
statssrv,
nreads, nreads,
nwrites, nwrites,
nconnects, nconnects;
extip;
struct bandlim *bandlims[MAXBANDLIMS], struct bandlim *bandlims[MAXBANDLIMS],
*bandlimsout[MAXBANDLIMS]; *bandlimsout[MAXBANDLIMS];
unsigned short extport;
time_t time_start; time_t time_start;
}; };
@ -446,8 +497,14 @@ struct extparam {
unsigned char *logname, **archiver; unsigned char *logname, **archiver;
ROTATION logtype, countertype; ROTATION logtype, countertype;
char * counterfile; char * counterfile;
unsigned long intip, extip; #ifndef NOIPV6
unsigned short intport, extport; struct sockaddr_in6 intsa;
struct sockaddr_in6 extsa6;
struct sockaddr_in6 extsa;
#else
struct sockaddr_in intsa;
struct sockaddr_in extsa;
#endif
struct passwords *pwl; struct passwords *pwl;
struct auth * authenticate; struct auth * authenticate;
AUTHFUNC authfunc; AUTHFUNC authfunc;
@ -525,6 +582,25 @@ struct child {
unsigned char **argv; unsigned char **argv;
}; };
struct hashentry {
unsigned char hash[sizeof(unsigned)*4];
time_t expires;
struct hashentry *next;
char value[4];
};
struct hashtable {
unsigned hashsize;
unsigned recsize;
unsigned rnd[4];
struct hashentry ** hashtable;
void * hashvalues;
struct hashentry * hashempty;
};
extern struct hashtable dns_table;
extern struct hashtable dns6_table;
struct sockfuncs { struct sockfuncs {
#ifdef _WIN32 #ifdef _WIN32
SOCKET (WINAPI *_socket)(int domain, int type, int protocol); SOCKET (WINAPI *_socket)(int domain, int type, int protocol);
@ -567,22 +643,22 @@ extern struct sockfuncs so;
struct pluginlink { struct pluginlink {
struct symbol symbols; struct symbol symbols;
struct extparam *conf; struct extparam *conf;
unsigned long *nservers; struct nserver *nservers;
int * linenum; int * linenum;
struct auth *authfuncs; struct auth *authfuncs;
struct commands * commandhandlers; struct commands * commandhandlers;
void * (*findbyname)(const char *name); void * (*findbyname)(const char *name);
int (*socksend)(SOCKET sock, unsigned char * buf, int bufsize, int to); int (*socksend)(SOCKET sock, unsigned char * buf, int bufsize, int to);
int (*socksendto)(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to); int (*socksendto)(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
int (*sockrecvfrom)(SOCKET sock, struct sockaddr_in * sin, unsigned char * buf, int bufsize, int to); int (*sockrecvfrom)(SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
int (*sockgetcharcli)(struct clientparam * param, int timeosec, int timeousec); int (*sockgetcharcli)(struct clientparam * param, int timeosec, int timeousec);
int (*sockgetcharsrv)(struct clientparam * param, int timeosec, int timeousec); int (*sockgetcharsrv)(struct clientparam * param, int timeosec, int timeousec);
int (*sockgetlinebuf)(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to); int (*sockgetlinebuf)(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to);
int (*myinet_ntoa)(struct in_addr in, char * buf); int (*myinet_ntop)(int af, void *src, char *dst, socklen_t size);
int (*dobuf)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec); int (*dobuf)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec);
int (*dobuf2)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format); int (*dobuf2)(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
int (*scanaddr)(const unsigned char *s, unsigned long * ip, unsigned long * mask); int (*scanaddr)(const unsigned char *s, unsigned long * ip, unsigned long * mask);
unsigned long (*getip)(unsigned char *name); unsigned long (*getip46)(int family, unsigned char *name, struct sockaddr *sa);
int (*sockmap)(struct clientparam * param, int timeo); int (*sockmap)(struct clientparam * param, int timeo);
int (*ACLMatches)(struct ace* acentry, struct clientparam * param); int (*ACLMatches)(struct ace* acentry, struct clientparam * param);
int (*alwaysauth)(struct clientparam * param); int (*alwaysauth)(struct clientparam * param);
@ -615,6 +691,17 @@ struct pluginlink {
unsigned char * (*dologname) (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t); unsigned char * (*dologname) (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
}; };
struct counter_header {
unsigned char sig[4];
time_t updated;
};
struct counter_record {
uint64_t traf64;
time_t cleared;
time_t updated;
};
extern struct pluginlink pluginlink; extern struct pluginlink pluginlink;
extern char *rotations[]; extern char *rotations[];
@ -634,9 +721,11 @@ typedef enum {
TYPE_SHORT, TYPE_SHORT,
TYPE_CHAR, TYPE_CHAR,
TYPE_UNSIGNED, TYPE_UNSIGNED,
TYPE_UNSIGNED64,
TYPE_TRAFFIC, TYPE_TRAFFIC,
TYPE_PORT, TYPE_PORT,
TYPE_IP, TYPE_IP,
TYPE_SA,
TYPE_CIDR, TYPE_CIDR,
TYPE_STRING, TYPE_STRING,
TYPE_DATETIME, TYPE_DATETIME,
@ -657,19 +746,7 @@ typedef enum {
TYPE_SERVER TYPE_SERVER
}DATA_TYPE; }DATA_TYPE;
struct hashentry {
unsigned char hash[sizeof(unsigned)*4];
unsigned long value;
time_t expires;
struct hashentry *next;
};
struct hashtable {
unsigned hashsize;
struct hashentry ** hashtable;
struct hashentry * hashvalues;
struct hashentry * hashempty;
};
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: tcppm.c,v 1.15 2012-02-05 22:29:02 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: udppm.c,v 1.27 2012-02-05 22:29:03 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -40,7 +39,7 @@ void * udppmchild(struct clientparam* param) {
if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport)); if(!param->hostname)parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
if (!param->req.sin_addr.s_addr) { if (SAISNULL(&param->req)) {
param->srv->fds.events = POLLIN; param->srv->fds.events = POLLIN;
RETURN (100); RETURN (100);
} }
@ -49,7 +48,7 @@ void * udppmchild(struct clientparam* param) {
RETURN (21); RETURN (21);
} }
param->cliinbuf = param->clioffset = 0; param->cliinbuf = param->clioffset = 0;
i = sockrecvfrom(param->srv->srvsock, &param->sinc, param->clibuf, param->clibufsize, 0); i = sockrecvfrom(param->srv->srvsock, (struct sockaddr *)&param->sincr, param->clibuf, param->clibufsize, 0);
if(i<=0){ if(i<=0){
param->srv->fds.events = POLLIN; param->srv->fds.events = POLLIN;
RETURN (214); RETURN (214);
@ -57,32 +56,34 @@ void * udppmchild(struct clientparam* param) {
param->cliinbuf = i; param->cliinbuf = i;
#ifdef _WIN32 #ifdef _WIN32
if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) { if((param->clisock=so._socket(SASOCK(&param->sincr), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
RETURN(818); RETURN(818);
} }
if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);}; if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (unsigned char *)&ul, sizeof(int))) {RETURN(820);};
ioctlsocket(param->clisock, FIONBIO, &ul); ioctlsocket(param->clisock, FIONBIO, &ul);
size = sizeof(struct sockaddr_in); size = sizeof(param->sinsl);
if(so._getsockname(param->srv->srvsock, (struct sockaddr *)&param->sins, &size)) {RETURN(21);}; if(so._getsockname(param->srv->srvsock, (struct sockaddr *)&param->sinsl, &size)) {RETURN(21);};
if(so._bind(param->clisock,(struct sockaddr *)&param->sins,sizeof(struct sockaddr_in))) { if(so._bind(param->clisock,(struct sockaddr *)&param->sinsl,sizeof(struct sockaddr_in))) {
RETURN(822); RETURN(822);
} }
#else #else
param->clisock = param->srv->srvsock; param->clisock = param->srv->srvsock;
#endif #endif
param->sins.sin_family = AF_INET; #ifndef NOIPV6
param->sins.sin_port = htons(0); memcpy(&param->sinsl, *SAFAMILY(&param->req) == AF_INET? (struct sockaddr *)&param->srv->extsa : (struct sockaddr *)&param->srv->extsa6, SASIZE(&param->req));
param->sins.sin_addr.s_addr = param->extip; #else
if ((param->remsock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);} memcpy(&param->sinsl, &param->srv->extsa, SASIZE(&param->req));
if(so._bind(param->remsock,(struct sockaddr *)&param->sins,sizeof(param->sins))) {RETURN (12);} #endif
*SAPORT(&param->sinsl) = 0;
if ((param->remsock=so._socket(SASOCK(&param->sinsl), SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {RETURN (11);}
if(so._bind(param->remsock,(struct sockaddr *)&param->sinsl,sizeof(param->sinsl))) {RETURN (12);}
#ifdef _WIN32 #ifdef _WIN32
ioctlsocket(param->remsock, FIONBIO, &ul); ioctlsocket(param->remsock, FIONBIO, &ul);
#else #else
fcntl(param->remsock,F_SETFL,O_NONBLOCK); fcntl(param->remsock,F_SETFL,O_NONBLOCK);
#endif #endif
param->sins.sin_addr.s_addr = param->req.sin_addr.s_addr; memcpy(&param->sinsr, &param->req, sizeof(param->req));
param->sins.sin_port = param->req.sin_port;
param->operation = UDPASSOC; param->operation = UDPASSOC;
if((res = (*param->srv->authfunc)(param))) {RETURN(res);} if((res = (*param->srv->authfunc)(param))) {RETURN(res);}

View File

@ -1,2 +1,2 @@
#define VERSION "3proxy-0.7.1.3" #define VERSION "3proxy-0.8b-devel"
#define BUILDDATE "150916004303" #define BUILDDATE "160107200335"

View File

@ -4,7 +4,6 @@
please read License Agreement please read License Agreement
$Id: webadmin.c,v 1.44 2014-04-07 20:35:12 vlad Exp $
*/ */
#include "proxy.h" #include "proxy.h"
@ -319,21 +318,15 @@ static int printuserlist(char *buf, int bufsize, struct userlist* ul, char * del
return printed; return printed;
} }
int printiple(char *buf, struct iplist* ipl);
static int printiplist(char *buf, int bufsize, struct iplist* ipl, char * delim){ static int printiplist(char *buf, int bufsize, struct iplist* ipl, char * delim){
int printed = 0; int printed = 0;
for(; ipl; ipl = ipl->next){ for(; ipl; ipl = ipl->next){
if(printed > (bufsize - 64)) break; if(printed > (bufsize - 128)) break;
printed += sprintf(buf+printed, "%u.%u.%u.%u mask %u.%u.%u.%u%s", printed += printiple(buf+printed, ipl);
(unsigned)(ntohl(ipl->ip)&0xff000000)>>24, if(printed > (bufsize - 128)) {
(unsigned)(ntohl(ipl->ip)&0x00ff0000)>>16,
(unsigned)(ntohl(ipl->ip)&0x0000ff00)>>8,
(unsigned)(ntohl(ipl->ip)&0x000000ff),
(unsigned)(ntohl(ipl->mask)&0xff000000)>>24,
(unsigned)(ntohl(ipl->mask)&0x00ff0000)>>16,
(unsigned)(ntohl(ipl->mask)&0x0000ff00)>>8,
(unsigned)(ntohl(ipl->mask)&0x000000ff),
ipl->next?delim:"");
if(printed > (bufsize - 64)) {
printed += sprintf(buf+printed, "..."); printed += sprintf(buf+printed, "...");
break; break;
} }
@ -476,13 +469,13 @@ void * adminchild(struct clientparam* param) {
} }
else { else {
inbuf += sprintf(buf+inbuf, inbuf += sprintf(buf+inbuf,
"</td><td>%.3f</td>" "</td><td>%"PRINTF_INT64_MODIFIER"u</td>"
"<td>MB%s</td>" "<td>MB%s</td>"
"<td>%.3f MB</td>" "<td>%"PRINTF_INT64_MODIFIER"u</td>"
"<td>%s</td>", "<td>%s</td>",
(4 * 1024.0 * (float)cp->traflimgb) + (float)cp->traflim/(1024.*1024.), cp->traflim64,
rotations[cp->type], rotations[cp->type],
(4 * 1024.0 * (float)cp->trafgb) + (float)cp->traf/(1024.*1024.), cp->traf64,
cp->cleared?ctime(&cp->cleared):"never" cp->cleared?ctime(&cp->cleared):"never"
); );
inbuf += sprintf(buf + inbuf, inbuf += sprintf(buf + inbuf,