mirror of
https://github.com/3proxy/3proxy.git
synced 2025-06-08 20:44:47 +08:00
删除除proxy外代码
On branch devel modified: src/Makefile.inc Untracked files: src/pstdint.h no changes added to commit (use "git add" and/or "git commit -a") On branch devel deleted: Makefile.Solaris Changes not staged for commit: modified: src/Makefile.inc Untracked files: src/tags On branch devel deleted: cfg/0.scenario.txt Untracked files: src/tags no changes added to commit (use "git add" and/or "git commit -a")
This commit is contained in:
parent
22adb5938b
commit
4dd0094304
@ -1,36 +0,0 @@
|
||||
#
|
||||
# 3 proxy Makefile for Solaris/SunCC
|
||||
#
|
||||
# You can try to remove -DWITH_STD_MALLOC to CFLAGS to use optimized malloc
|
||||
# libraries
|
||||
#
|
||||
# remove -DNOODBC from CFLAGS and add -lodbc to LDFLAGS to compile with ODBC
|
||||
# library support. Add -DSAFESQL for poorely written ODBC library / drivers.
|
||||
|
||||
BUILDDIR =
|
||||
CC = cc
|
||||
CFLAGS = -xO3 -c -D_SOLARIS -D_THREAD_SAFE -DGETHOSTBYNAME_R -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL
|
||||
COUT = -o ./
|
||||
LN = cc
|
||||
LDFLAGS = -xO3
|
||||
DCFLAGS = -fpic
|
||||
DLFLAGS = -shared
|
||||
DLSUFFICS = .ld.so
|
||||
LIBS = -lpthread -lsocket -lnsl -lresolv -ldl
|
||||
LIBSPREFIX = -l
|
||||
LIBSSUFFIX =
|
||||
LNOUT = -o ./
|
||||
EXESUFFICS =
|
||||
OBJSUFFICS = .o
|
||||
DEFINEOPTION = -D
|
||||
COMPFILES = *~
|
||||
REMOVECOMMAND = rm -f
|
||||
TYPECOMMAND = cat
|
||||
COMPATLIBS =
|
||||
MAKEFILE = Makefile.Solaris
|
||||
PLUGINS = StringsPlugin TrafficPlugin PCREPlugin
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
allplugins:
|
||||
@list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; cd ../.. ; done
|
@ -1,37 +0,0 @@
|
||||
#
|
||||
# 3 proxy Makefile for Solaris/gcc
|
||||
#
|
||||
# You can try to remove -DWITH_STD_MALLOC to CFLAGS to use optimized malloc
|
||||
# libraries
|
||||
#
|
||||
# remove -DNOODBC from CFLAGS and add -lodbc to LDFLAGS to compile with ODBC
|
||||
# library support. Add -DSAFESQL for poorely written ODBC library / drivers.
|
||||
|
||||
|
||||
BUILDDIR =
|
||||
CC = gcc
|
||||
CFLAGS = -O3 -c -D_SOLARIS -D_THREAD_SAFE -DGETHOSTBYNAME_R -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL
|
||||
COUT = -o ./
|
||||
LN = gcc
|
||||
LDFLAGS = -O3
|
||||
DCFLAGS = -fpic
|
||||
DLFLAGS = -shared
|
||||
DLSUFFICS = .ld.so
|
||||
LIBS = -lpthread -lsocket -lnsl -lresolv -ldl
|
||||
LIBSPREFIX = -l
|
||||
LIBSSUFFIX =
|
||||
LNOUT = -o ./
|
||||
EXESUFFICS =
|
||||
OBJSUFFICS = .o
|
||||
DEFINEOPTION = -D
|
||||
COMPFILES = *~
|
||||
REMOVECOMMAND = rm -f
|
||||
TYPECOMMAND = cat
|
||||
COMPATLIBS =
|
||||
MAKEFILE = Makefile.Solaris-gcc
|
||||
PLUGINS = StringsPlugin TrafficPlugin PCREPlugin
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
allplugins:
|
||||
@list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; cd ../.. ; done
|
@ -1,33 +0,0 @@
|
||||
#
|
||||
# 3 proxy Makefile for Intel C compiler for Windows (for both make and nmake)
|
||||
#
|
||||
# You can try to remove -DWITH_STD_MALLOC to CFLAGS to use optimized malloc
|
||||
# libraries
|
||||
#
|
||||
# Add /DSAFESQL to CFLAGS if you are using poorely written/tested ODBC driver
|
||||
|
||||
|
||||
BUILDDIR = ../bin/
|
||||
CC = icl
|
||||
CFLAGS = /nologo /MD /W3 /G6 /GX /O2 /D "WITH_STD_MALLOC" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /YX /FD /c
|
||||
COUT = /Fo
|
||||
LN = xilink
|
||||
LDFLAGS = /nologo /subsystem:console /incremental:no /machine:I386
|
||||
LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib
|
||||
DLFLAGS = /DLL
|
||||
DLSUFFICS = .dll
|
||||
LNOUT = /out:
|
||||
EXESUFFICS = .exe
|
||||
OBJSUFFICS = .obj
|
||||
DEFINEOPTION = /D
|
||||
COMPFILES = *.pch *.idb
|
||||
REMOVECOMMAND = del 2>NUL
|
||||
TYPECOMMAND = type
|
||||
COMPATLIBS =
|
||||
MAKEFILE = Makefile.intl
|
||||
PLUGINS = WindowsAuthentication TrafficPlugin PCREPlugin
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
allplugins:
|
||||
for /D %%i in ($(PLUGINS)) do (copy Makefile Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.obj *.idb &&cd ..\..)
|
@ -1,35 +0,0 @@
|
||||
#
|
||||
# 3 proxy Makefile for Microsoft Visual C compiler (for both make and nmake)
|
||||
#
|
||||
# You can try to remove -DWITH_STD_MALLOC to CFLAGS to use optimized malloc
|
||||
# libraries
|
||||
#
|
||||
# Add /DSAFESQL to CFLAGS if you are using poorely written/tested ODBC driver
|
||||
|
||||
BUILDDIR = ../bin/
|
||||
CC = cl
|
||||
CFLAGS = /DARM /D "NOODBC" /nologo /MT /W3 /Wp64 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "_WINCE" /D "WITH_STD_MALLOC" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c
|
||||
COUT = /Fo
|
||||
LN = link
|
||||
LDFLAGS = /nologo /subsystem:console /incremental:no
|
||||
DLFLAGS = /DLL
|
||||
DLSUFFICS = .dll
|
||||
LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib
|
||||
LIBEXT = .lib
|
||||
LNOUT = /out:
|
||||
EXESUFFICS = .exe
|
||||
OBJSUFFICS = .obj
|
||||
DEFINEOPTION = /D
|
||||
COMPFILES = *.pch *.idb
|
||||
REMOVECOMMAND = del 2>NUL >NUL
|
||||
TYPECOMMAND = type
|
||||
COMPATLIBS =
|
||||
MAKEFILE = Makefile.msvc
|
||||
PLUGINS = WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin
|
||||
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
allplugins:
|
||||
for /D %%i in ($(PLUGINS)) do (copy Makefile plugins\%%i && copy Makefile.var plugins\%%i && cd plugins\%%i && nmake && del *.obj *.idb &&cd ..\..)
|
||||
|
@ -1,59 +0,0 @@
|
||||
#
|
||||
# 3 proxy Makefile for GCC/Unix
|
||||
#
|
||||
# You can try to remove -DWITH_STD_MALLOC to CFLAGS to use optimized malloc
|
||||
# libraries
|
||||
#
|
||||
# remove -DNOODBC from CFLAGS and add -lodbc to LDFLAGS to compile with ODBC
|
||||
# library support. Add -DSAFESQL for poorely written ODBC library / drivers.
|
||||
|
||||
BUILDDIR =
|
||||
CC = gcc
|
||||
|
||||
# you may need -L/usr/pkg/lib for older NetBSD versions
|
||||
CFLAGS = -g -O2 -c -pthread -D_THREAD_SAFE -D_REENTRANT -DNOODBC -DWITH_STD_MALLOC -DFD_SETSIZE=4096 -DWITH_POLL
|
||||
COUT = -o
|
||||
LN = gcc
|
||||
LDFLAGS = -O2 -pthread
|
||||
# -lpthreads may be reuqired on some platforms instead of -pthreads
|
||||
# -ldl or -lld may be required for some platforms
|
||||
DCFLAGS = -fpic
|
||||
DLFLAGS = -shared
|
||||
DLSUFFICS = .ld.so
|
||||
LIBS =
|
||||
LIBSPREFIX = -l
|
||||
LIBSSUFFIX =
|
||||
LNOUT = -o
|
||||
EXESUFFICS =
|
||||
OBJSUFFICS = .o
|
||||
DEFINEOPTION = -D
|
||||
COMPFILES = *~
|
||||
REMOVECOMMAND = rm -f
|
||||
TYPECOMMAND = cat
|
||||
COMPATLIBS =
|
||||
MAKEFILE = Makefile.unix
|
||||
PLUGINS = StringsPlugin TrafficPlugin PCREPlugin PamAuth
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
install: all
|
||||
if [ ! -d /usr/local/etc/3proxy/bin ]; then mkdir -p /usr/local/etc/3proxy/bin/; fi
|
||||
install src/3proxy /usr/local/etc/3proxy/bin/3proxy
|
||||
install src/mycrypt /usr/local/etc/3proxy/bin/mycrypt
|
||||
install scripts/rc.d/proxy.sh /usr/local/etc/rc.d/proxy.sh
|
||||
install scripts/add3proxyuser.sh /usr/local/etc/3proxy/bin/
|
||||
if [ -s /usr/local/etc/3proxy/3proxy.cfg ]; then
|
||||
echo /usr/local/etc/3proxy/3proxy.cfg already exists
|
||||
else
|
||||
install scripts/3proxy.cfg /usr/local/etc/3proxy/
|
||||
if [ ! -d /var/log/3proxy/ ]; then
|
||||
mkdir /var/log/3proxy/
|
||||
fi
|
||||
touch /usr/local/etc/3proxy/passwd
|
||||
touch /usr/local/etc/3proxy/counters
|
||||
touch /usr/local/etc/3proxy/bandlimiters
|
||||
echo Run /usr/local/etc/3proxy/bin/add3proxyuser.sh to add \'admin\' user
|
||||
fi
|
||||
|
||||
allplugins:
|
||||
@list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; cd ../.. ; done
|
@ -1,60 +0,0 @@
|
||||
DESTDIR =
|
||||
prefix = /usr/local
|
||||
exec_prefix = $(prefix)
|
||||
man_prefix = $(prefix)/share
|
||||
|
||||
INSTALL = /usr/bin/install
|
||||
INSTALL_BIN = $(INSTALL) -m 755
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
INSTALL_OBJS = src/3proxy \
|
||||
src/dighosts \
|
||||
src/ftppr \
|
||||
src/mycrypt \
|
||||
src/pop3p \
|
||||
src/proxy \
|
||||
src/socks \
|
||||
src/tcppm \
|
||||
src/udppm \
|
||||
scripts/add3proxyuser.sh
|
||||
|
||||
INSTALL_CFG_OBJS = scripts/3proxy.cfg
|
||||
INSTALL_CFG_DEST = config
|
||||
|
||||
INSTALL_CFG_OBJS2 = passwd counters bandlimiters
|
||||
|
||||
MANDIR1 = $(DESTDIR)$(man_prefix)/man/man1
|
||||
MANDIR3 = $(DESTDIR)$(man_prefix)/man/man3
|
||||
MANDIR8 = $(DESTDIR)$(man_prefix)/man/man8
|
||||
BINDIR = $(DESTDIR)$(exec_prefix)/bin
|
||||
ETCDIR = $(DESTDIR)$(prefix)/etc/3proxy
|
||||
|
||||
install-bin:
|
||||
$(INSTALL_BIN) -d $(BINDIR)
|
||||
$(INSTALL_BIN) -s $(INSTALL_OBJS) $(BINDIR)
|
||||
|
||||
install-etc-dir:
|
||||
$(INSTALL_BIN) -d $(ETCDIR)
|
||||
|
||||
install-etc-default-config:
|
||||
if [ -f $(ETCDIR)/$(INSTALL_CFG_DEST) ]; then \
|
||||
: ; \
|
||||
else \
|
||||
$(INSTALL_DATA) $(INSTALL_CFG_OBJS) $(ETCDIR)/$(INSTALL_CFG_DEST) \
|
||||
fi
|
||||
|
||||
install-etc: install-etc-dir
|
||||
for file in $(INSTALL_CFG_OBJS2); \
|
||||
do \
|
||||
touch $(ETCDIR)/$$file; chmod 0600 $(ETCDIR)/$$file; \
|
||||
done;
|
||||
|
||||
install-man:
|
||||
$(INSTALL_BIN) -d $(MANDIR1)
|
||||
$(INSTALL_BIN) -d $(MANDIR3)
|
||||
$(INSTALL_BIN) -d $(MANDIR8)
|
||||
$(INSTALL_DATA) man/*.1 $(MANDIR1)
|
||||
$(INSTALL_DATA) man/*.3 $(MANDIR3)
|
||||
$(INSTALL_DATA) man/*.8 $(MANDIR8)
|
||||
|
||||
install: install-bin install-etc install-man
|
||||
|
36
Makefile.win
36
Makefile.win
@ -1,36 +0,0 @@
|
||||
#
|
||||
# 3 proxy Makefile for GCC/windows
|
||||
#
|
||||
# You can try to remove -DWITH_STD_MALLOC to CFLAGS to use optimized malloc
|
||||
# libraries
|
||||
#
|
||||
# remove -DNOODBC from CFLAGS and add -lodbc to LDFLAGS to compile with ODBC
|
||||
# library support
|
||||
|
||||
|
||||
BUILDDIR = ../bin/
|
||||
CC = gcc
|
||||
CFLAGS = -O2 -s -c -mthreads -DWITH_STD_MALLOC -DNOIPV6
|
||||
COUT = -o
|
||||
LN = gcc
|
||||
LDFLAGS = -O2 -s -mthreads
|
||||
DLFLAGS = -shared
|
||||
DLSUFFICS = .dll
|
||||
LIBS = -lws2_32 -lodbc32 -ladvapi32
|
||||
LIBSPREFIX = -l
|
||||
LIBSSUFFIX =
|
||||
LNOUT = -o
|
||||
EXESUFFICS = .exe
|
||||
OBJSUFFICS = .o
|
||||
DEFINEOPTION = -D
|
||||
COMPFILES = *.tmp
|
||||
REMOVECOMMAND = rm -f
|
||||
TYPECOMMAND = cat
|
||||
COMPATLIBS =
|
||||
MAKEFILE = Makefile.win
|
||||
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin PCREPlugin
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
allplugins:
|
||||
@list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; rm *.o ; cd ../.. ; done
|
@ -1,34 +0,0 @@
|
||||
#
|
||||
# 3 proxy Makefile for GCC/windows
|
||||
#
|
||||
# You can try to remove -DWITH_STD_MALLOC to CFLAGS to use optimized malloc
|
||||
# libraries
|
||||
#
|
||||
# remove -DNOODBC from CFLAGS and add -lodbc to LDFLAGS to compile with ODBC
|
||||
# library support
|
||||
|
||||
|
||||
BUILDDIR = ../bin/
|
||||
CC = /opt/cegcc/arm-wince-cegcc/bin/gcc
|
||||
CFLAGS = -O2 -s -c -mthreads -DWITH_STD_MALLOC -DNOODBC -D_WINCE -D_WIN32 -D__USE_W32_SOCKETS
|
||||
COUT = -o
|
||||
LN = /opt/cegcc/arm-wince-cegcc/bin/gcc
|
||||
LDFLAGS = -O2 -s -mthreads
|
||||
DLFLAGS = -shared
|
||||
DLSUFFICS = .dll
|
||||
LIBS = -lws2
|
||||
LNOUT = -o
|
||||
EXESUFFICS = .exe
|
||||
OBJSUFFICS = .o
|
||||
DEFINEOPTION = -D
|
||||
COMPFILES = *.tmp
|
||||
REMOVECOMMAND = rm -f
|
||||
TYPECOMMAND = more
|
||||
COMPATLIBS =
|
||||
MAKEFILE = Makefile.winCE
|
||||
PLUGINS = TrafficPlugin StringsPlugin PCREPlugin
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
allplugins:
|
||||
@list='$(PLUGINS)'; for p in $$list; do cp Makefile Makefile.var plugins/$$p; cd plugins/$$p ; make ; rm *.o ; cd ../.. ; done
|
@ -1,17 +0,0 @@
|
||||
Please read doc/config.txt before using 3proxy.
|
||||
|
||||
In all examples next scenario is used:
|
||||
|
||||
3proxy is installed on multihomed host. IP address of internal interface
|
||||
is 192.168.1.1. IP address of external interface is 10.1.1.1.
|
||||
Internal network has few subnetworks for 192.168.0.0/16.
|
||||
Users are named user1, user2, etc.
|
||||
|
||||
You use external DNS server 10.1.2.1 and 10.1.2.2
|
||||
|
||||
Provider has networks with free access. A list of networks is published
|
||||
on the provider's Web server.
|
||||
|
||||
Provider has proxy server 10.1.2.5. Traffic from proxy server is not free, but
|
||||
is cheaper than traffic from non-free networks.
|
||||
|
@ -1,201 +0,0 @@
|
||||
#!/usr/local/bin/3proxy
|
||||
# Yes, 3proxy.cfg can be executable, in this case you should place
|
||||
# something like
|
||||
#config /usr/local/3proxy/3proxy.cfg
|
||||
# to show which configuration 3proxy should re-read on realod.
|
||||
|
||||
#system "echo Hello world!"
|
||||
# you may use system to execute some external command if proxy starts
|
||||
|
||||
# We can configure nservers to avoid unsafe gethostbyname() usage
|
||||
nserver 10.1.2.1
|
||||
nserver 10.2.2.2
|
||||
# nscache is good to save speed, traffic and bandwidth
|
||||
nscache 65536
|
||||
|
||||
#nsrecord porno.security.nnov.ru 0.0.0.0
|
||||
# nobody will be able to access porno.security.nnov.ru by the name.
|
||||
#nsrecord wpad.security.nnov.ru www.security.nnov.ru
|
||||
# wpad.security.nnov.ru will resolve to www.security.nnov.ru for
|
||||
# clients
|
||||
|
||||
|
||||
timeouts 1 5 30 60 180 1800 15 60
|
||||
# Here we can change timeout values
|
||||
|
||||
users 3APA3A:CL:3apa3a "test:CR:$1$qwer$CHFTUFGqkjue9HyhcMHEe1"
|
||||
# note that "" required, overvise $... is treated as include file name.
|
||||
# $1$qwer$CHFTUFGqkjue9HyhcMHEe1 is 'test' in MD5 crypt format.
|
||||
#users $/usr/local/etc/3proxy/passwd
|
||||
# this example shows you how to include passwd file. For included files
|
||||
# <CR> and <LF> are treated as field separators.
|
||||
|
||||
#daemon
|
||||
# now we will not depend on any console (daemonize). daemon must be given
|
||||
# before any significant command on *nix.
|
||||
|
||||
service
|
||||
# service is required under NT if you want 3proxy to start as service
|
||||
|
||||
#log /usr/local/etc/3proxy/logs/3proxy.log D
|
||||
log c:\3proxy\logs\3proxy.log D
|
||||
# log allows to specify log file location and rotation, D means logfile
|
||||
# is created daily
|
||||
|
||||
#logformat "L%d-%m-%Y %H:%M:%S %z %N.%p %E %U %C:%c %R:%r %O %I %h %T"
|
||||
#logformat "Linsert into log (l_date, l_user, l_service, l_in, l_out, l_descr) values ('%d-%m-%Y %H:%M:%S', '%U', '%N', %I, %O, '%T')"
|
||||
#Compatible with Squid access.log:
|
||||
#
|
||||
#"- +_G%t.%. %D %C TCP_MISS/200 %I %1-1T %2-2T %U DIRECT/%R application/unknown"
|
||||
#or, more compatible format without %D
|
||||
#"- +_G%t.%. 1 %C TCP_MISS/200 %I %1-1T %2-2T %U DIRECT/%R application/unknown"
|
||||
#
|
||||
#Compatible with ISA 2000 proxy WEBEXTD.LOG (fields are TAB-delimited):
|
||||
#
|
||||
#"- + L%C %U Unknown Y %Y-%m-%d %H:%M:%S w3proxy 3PROXY - %n %R %r %D %O %I http TCP %1-1T %2-2T - - %E - - -"
|
||||
#
|
||||
#Compatible with ISA 2004 proxy WEB.w3c
|
||||
#
|
||||
#"- + L%C %U Unknown %Y-%m-%d %H:%M:%S 3PROXY - %n %R %r %D %O %I http %1-1T %2-2T - %E - - Internal External 0x0 Allowed"
|
||||
#
|
||||
#Compatible with ISA 2000/2004 firewall FWSEXTD.log (fields are TAB-delimited):
|
||||
#
|
||||
#"- + L%C %U unnknown:0:0.0 N %Y-%m-%d %H:%M:%S fwsrv 3PROXY - %n %R %r %D %O %I %r TCP Connect - - - %E - - - - -"
|
||||
#
|
||||
#Compatible with HTTPD standard log (Apache and others)
|
||||
#
|
||||
#"-""+_L%C - %U [%d/%o/%Y:%H:%M:%S %z] ""%T"" %E %I"
|
||||
#or more compatible without error code
|
||||
#"-""+_L%C - %U [%d/%o/%Y:%H:%M:%S %z] ""%T"" 200 %I"
|
||||
|
||||
# in log file we want to have underscores instead of spaces
|
||||
logformat "- +_L%t.%. %N.%p %E %U %C:%c %R:%r %O %I %h %T"
|
||||
|
||||
|
||||
#archiver gz /bin/gzip %F
|
||||
#archiver zip zip -m -qq %A %F
|
||||
#archiver zip pkzipc -add -silent -move %A %F
|
||||
archiver rar rar a -df -inul %A %F
|
||||
# if archiver specified log file will be compressed after closing.
|
||||
# you should specify extension, path to archiver and command line, %A will be
|
||||
# substituted with archive file name, %f - with original file name.
|
||||
# Original file will not be removed, so archiver should care about it.
|
||||
|
||||
rotate 30
|
||||
# We will keep last 30 log files
|
||||
|
||||
auth iponly
|
||||
#auth nbname
|
||||
#auth strong
|
||||
# auth specifies type of user authentication. If you specify none proxy
|
||||
# will not do anything to check name of the user. If you specify
|
||||
# nbname proxy will send NetBIOS name request packet to UDP/137 of
|
||||
# client and parse request for NetBIOS name of messanger service.
|
||||
# Strong means that proxy will check password. For strong authentication
|
||||
# unknown user will not be allowed to use proxy regardless of ACL.
|
||||
# If you do not want username to be checked but wanna ACL to work you should
|
||||
# specify auth iponly.
|
||||
|
||||
|
||||
#allow ADMINISTRATOR,root
|
||||
#allow * 127.0.0.1,192.168.1.1 * *
|
||||
#parent 1000 http 192.168.1.2 80 * * * 80
|
||||
#allow * 192.168.1.0/24 * 25,53,110,20-21,1024-65535
|
||||
# we will allow everything if username matches ADMINISTRATOR or root or
|
||||
# client ip is 127.0.0.1 or 192.168.1.1. Overwise we will redirect any request
|
||||
# to port 80 to our Web-server 192.168.0.2.
|
||||
# We will allow any outgoing connections from network 192.168.1.0/24 to
|
||||
# SMTP, POP3, FTP, DNS and unprivileged ports.
|
||||
# Note, that redirect may also be used with proxy or portmapper. It will
|
||||
# allow you to redirect requests to different ports or different server
|
||||
# for different clients.
|
||||
|
||||
# sharing access to internet
|
||||
|
||||
external 10.1.1.1
|
||||
# external is address 3proxy uses for outgoing connections. 0.0.0.0 means any
|
||||
# interface. Using 0.0.0.0 is not good because it allows to connect to 127.0.0.1
|
||||
|
||||
internal 192.168.1.1
|
||||
# internal is address of interface proxy will listen for incoming requests
|
||||
# 127.0.0.1 means only localhost will be able to use this proxy. This is
|
||||
# address you should specify for clients as proxy IP.
|
||||
# You MAY use 0.0.0.0 but you shouldn't, because it's a chance for you to
|
||||
# have open proxy in your network in this case.
|
||||
|
||||
auth none
|
||||
# no authentication is requires
|
||||
|
||||
dnspr
|
||||
|
||||
# dnsproxy listens on UDP/53 to answer client's DNS requests. It requires
|
||||
# nserver/nscache configuration.
|
||||
|
||||
|
||||
#external $./external.ip
|
||||
#internal $./internal.ip
|
||||
# this is just an alternative form fo giving external and internal address
|
||||
# allows you to read this addresses from files
|
||||
|
||||
auth strong
|
||||
# We want to protect internal interface
|
||||
deny * * 127.0.0.1,192.168.1.1
|
||||
# and llow HTTP and HTTPS traffic.
|
||||
allow * * * 80-88,8080-8088 HTTP
|
||||
allow * * * 443,8443 HTTPS
|
||||
proxy -n
|
||||
|
||||
auth none
|
||||
# pop3p will be used without any authentication. It's bad choice
|
||||
# because it's possible to use pop3p to access any port
|
||||
pop3p
|
||||
|
||||
tcppm 25 mail.my.provider 25
|
||||
#udppm -s 53 ns.my.provider 53
|
||||
# we can portmap port TCP/25 to provider's SMTP server and UDP/53
|
||||
# to provider's DNS.
|
||||
# Now we can use our proxy as SMTP and DNS server.
|
||||
# -s switch for UDP means "single packet" service - instead of setting
|
||||
# association for period of time association will only be set for 1 packet.
|
||||
# It's very userfull for services like DNS but not for some massive services
|
||||
# like multimedia streams or online games.
|
||||
|
||||
auth strong
|
||||
flush
|
||||
allow 3APA3A,test
|
||||
maxconn 20
|
||||
socks
|
||||
# for socks we will use password authentication and different access control -
|
||||
# we flush previously configured ACL list and create new one to allow users
|
||||
# test and 3APA3A to connect from any location
|
||||
|
||||
|
||||
auth strong
|
||||
flush
|
||||
internal 127.0.0.1
|
||||
allow 3APA3A 127.0.0.1
|
||||
maxconn 3
|
||||
admin
|
||||
#only allow acces to admin interface for user 3APA3A from 127.0.0.1 address
|
||||
#via 127.0.0.1 address.
|
||||
|
||||
# map external 80 and 443 ports to internal Web server
|
||||
# examples below show how to use 3proxy to publish Web server in internal
|
||||
# network to Internet. We must switch internal and external addresses and
|
||||
# flush any ACLs
|
||||
|
||||
#auth none
|
||||
#flush
|
||||
#external $./internal.ip
|
||||
#internal $./external.ip
|
||||
#maxconn 300
|
||||
#tcppm 80 websrv 80
|
||||
#tcppm 443 websrv 443
|
||||
|
||||
|
||||
#chroot /usr/local/jail
|
||||
#setgid 65535
|
||||
#setuid 65535
|
||||
# now we needn't any root rights. We can chroot and setgid/setuid.
|
||||
|
||||
|
@ -1,52 +0,0 @@
|
||||
# Scenario:
|
||||
# You're billed for traffic except internal networks
|
||||
# 192.168.0.0 mask 255.255.0.0 and 10.0.0.0 mask 255.0.0.0.
|
||||
# If you exceed 2Gb limit you will have very high penalty
|
||||
#
|
||||
# You want to have daily report about common amount of external traffic.
|
||||
# You also need to know amount of Web traffic for every user
|
||||
# You want to limit Web traffic to 100Mb/day to whole campus and
|
||||
# to 20MB/day to every user
|
||||
|
||||
# see explanations in 3proxy.cfg.sample
|
||||
internal 192.168.1.1
|
||||
external 10.1.1.1
|
||||
nserver 10.1.2.1
|
||||
nserver 10.2.2.2
|
||||
nscache 65536
|
||||
dnspr
|
||||
|
||||
# no logging will be used, only traffic reports
|
||||
|
||||
# use d:\3proxy\3profy.3cf to store counters data
|
||||
# generate daily traffic reports in d:\3proxy\traf\
|
||||
counter "d:\3proxy\3profy.3cf" D "d:\3proxy\traf\traf"
|
||||
|
||||
# define users
|
||||
users "user1:CL:password1" "user2:CL:password2" "user3:CL:password3"
|
||||
users "user4:CL:password4" "user5:CL:password5" "user6:CL:password6"
|
||||
# ...
|
||||
|
||||
# do not count traffic for 192.168.0.0/16,10.0.0.0/8
|
||||
nocountin * * 192.168.0.0/16,10.0.0.0/8
|
||||
# Count external traffic summary for all clients with limit to 100MB/day
|
||||
countin "1/Test 1" D 100 *
|
||||
# Count external Web traffic summary for all clients to 1Gb/month
|
||||
countin "2/Test 2" M 1024 vlad,3APA3A,test 127.0.0.1 * 80,81,8080-8088
|
||||
# For every user count and limit daily Web traffic to 20 Mb
|
||||
# There is no way to configure it in a single line, we need a line
|
||||
# for every user we have
|
||||
countin "3/User 1" D 20 user1 * * 80,81,8080-8088
|
||||
countin "4/User 2" D 20 user2 * * 80,81,8080-8088
|
||||
# ...
|
||||
countin "202/User 200" D 20 user200 * * 80,81,8080-8088
|
||||
|
||||
# enable proxy
|
||||
auth strong
|
||||
proxy
|
||||
|
||||
# enable administration to user1 from localhost
|
||||
internal 127.0.0.1
|
||||
allow user1
|
||||
admin
|
||||
|
@ -1,53 +0,0 @@
|
||||
# By Mark Dreuband
|
||||
nserver 10.1.2.1
|
||||
nscache 65536
|
||||
|
||||
# we can grab wpad file from provider and feed it to dighosts
|
||||
# to build list of free networks
|
||||
# system "c:\3proxy\dighosts.exe -m http://wpad.security.nnov.ru/wpad.dat c:\3proxy\freenetworks.net"
|
||||
|
||||
service
|
||||
|
||||
internal 192.168.1.1
|
||||
external 10.1.1.1
|
||||
|
||||
dnspr
|
||||
|
||||
log &3proxylog,root
|
||||
#log c:\3proxy\logs\proxy.log D
|
||||
#logformat "Linsert into log (timestamp, username, service, clientip, remoteip, remoteport, bytesin, bytesout,request,error) values (
|
||||
#logformat "%t '%U' '%N' '%C' '%R' %r %I %O '%T' %E"
|
||||
logformat "-\'+_Linsert into log (time, bytesin, bytesout, username, url, host, port, service) values ('%Y-%m-%d %H:%M:%S', %I, %O, '%U', '%T', '%n', %r, '%N');"
|
||||
archiver zip c:\3proxy\zip.exe -m -qq %A %F
|
||||
rotate 50
|
||||
|
||||
|
||||
auth strong
|
||||
users temp:CL:password root:CL:password
|
||||
|
||||
# access free networks directly
|
||||
allow * * $c:\3proxy\freenetworks.net
|
||||
# redirect web traffic for non-free networks to provider's proxy
|
||||
allow * * * 80
|
||||
parent 1000 http 10.1.2.5 3128
|
||||
# allow rest of traffic
|
||||
allow *
|
||||
proxy
|
||||
|
||||
flush
|
||||
|
||||
auth iponly
|
||||
allow *
|
||||
pop3p
|
||||
tcppm 25 mail.security.nnov.ru 25
|
||||
|
||||
flush
|
||||
# redirect port 80 traffic via SOCKS server to local HTTP proxy to
|
||||
# have URLs logged
|
||||
allow * * * 80
|
||||
parent 1000 http 0.0.0.0 0
|
||||
allow *
|
||||
socks
|
||||
|
||||
#daemon
|
||||
|
@ -1,56 +0,0 @@
|
||||
# Connection: localhost
|
||||
# Host: 127.0.0.1
|
||||
# Saved: 2004-04-09 18:53:52
|
||||
#
|
||||
# Host: 127.0.0.1
|
||||
# Database: 3proxy
|
||||
# Table: 'log'
|
||||
#
|
||||
CREATE TABLE `log` (
|
||||
`time` datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
`bytesin` int(11) NOT NULL default '0',
|
||||
`bytesout` int(11) NOT NULL default '0',
|
||||
`username` varchar(20) NOT NULL default '',
|
||||
`service` varchar(7) NOT NULL default '',
|
||||
`host` varchar(100) NOT NULL default '',
|
||||
`port` int(11) NOT NULL default '0',
|
||||
`url` varchar(255) NOT NULL default ''
|
||||
) TYPE=MyISAM;
|
||||
|
||||
CREATE TABLE `services` (
|
||||
`startport` int(11) NOT NULL default '0',
|
||||
`endport` int(11) NOT NULL default '0',
|
||||
`service` varchar(100) NOT NULL default '',
|
||||
`description` varchar(100) NOT NULL default ''
|
||||
) TYPE=MyISAM;
|
||||
|
||||
CREATE TABLE `timelimit` (
|
||||
`datefrom` datetime NOT NULL default '0000-00-00 00:00:00',
|
||||
`dateto` datetime NOT NULL default '0000-00-00 00:00:00'
|
||||
) TYPE=MyISAM;
|
||||
|
||||
INSERT INTO services (80, 80, NULL, 'Access to Web Server');
|
||||
|
||||
INSERT INTO services (443, 443, NULL, 'Secure Access to Web Server');
|
||||
|
||||
INSERT INTO services (3128, 3128, NULL, 'Access to Web server via external Proxy');
|
||||
INSERT INTO services (1080, 1080, NULL, 'Access to external SOCKS server');
|
||||
INSERT INTO services (5190, 5190, NULL, 'Access to ICQ');
|
||||
INSERT INTO services (6666, 6668, NULL, 'Access to IRC');
|
||||
|
||||
INSERT INTO services (119, 119, NULL, 'Access to news server');
|
||||
INSERT INTO services (25, 25, NULL, 'Sent Mail');
|
||||
|
||||
INSERT INTO services (0, 0, 'POP3P', 'Received Mail');
|
||||
INSERT INTO services (0, 0, 'SMTPP', 'Sent Mail');
|
||||
INSERT INTO services (0, 0, 'TCPPM', 'Access to external server via TCP');
|
||||
INSERT INTO services (0, 0, 'UDPPM', 'Access to external server via UDP');
|
||||
INSERT INTO services (0, 0, 'PROXY', 'Access to external server via Proxy');
|
||||
INSERT INTO services (0, 0, 'FTPPR', 'Access to external server via FTP Proxy');
|
||||
INSERT INTO services (0, 0, 'ICQPR', 'Access to external server via ICQ Proxy');
|
||||
INSERT INTO services (0, 0, 'SOCKS4', 'Access to external server via Socks v4');
|
||||
INSERT INTO services (0, 0, 'SOCKS5', 'Access to external server via Socks v5');
|
||||
INSERT INTO services (0, 0, 'DNSPR', 'Name resolution');
|
||||
INSERT INTO services (0, 0, NULL, 'Unknown');
|
||||
|
||||
|
Binary file not shown.
151
man/3proxy.8
151
man/3proxy.8
@ -1,151 +0,0 @@
|
||||
.TH 3proxy "8" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B 3proxy
|
||||
\- 3[APA3A] tiny proxy server, or trivial proxy server, or free proxy
|
||||
server
|
||||
.SH SYNOPSIS
|
||||
.B 3proxy
|
||||
.RI [ config_file ]
|
||||
.br
|
||||
.B 3proxy
|
||||
.RI [ \-\-install ]
|
||||
.br
|
||||
.B 3proxy
|
||||
.RI [ \-\-remove ]
|
||||
.SH DESCRIPTION
|
||||
.B 3proxy
|
||||
is universal proxy server. It can be used to provide internal users wuth
|
||||
fully controllable access to external resources or to provide external
|
||||
users with access to internal resources. 3proxy is not developed to replace
|
||||
.BR squid (8),
|
||||
but it can extend functionality of existing cashing proxy.
|
||||
It can be used to route requests between different types of clients and proxy
|
||||
servers. Think about it as application level
|
||||
gateway with configuration like hardware router has for network layer.
|
||||
It can establish multiple
|
||||
gateways with HTTP and HTTPS proxy with FTP over HTTP support, SOCKS v4,
|
||||
v4.5 and v5, POP3 proxy, UDP and TCP portmappers. Each gateway is started
|
||||
from configuration file like independant service
|
||||
.BR proxy (8)
|
||||
.BR socks (8)
|
||||
.BR pop3p (8)
|
||||
.BR tcppm (8)
|
||||
.BR udppm (8)
|
||||
.BR ftppr (8)
|
||||
.BR dnspr
|
||||
but
|
||||
.BR 3proxy
|
||||
is not a kind of wrapper or superserver for this daemons. It just has same
|
||||
code compiled in, but provides much more functionality. SOCKSv5
|
||||
implementatation allows to use 3proxy with any UDP or TCP based client
|
||||
applications designed without
|
||||
proxy support (with
|
||||
.IR SocksCAP ,
|
||||
.I FreeCAP
|
||||
or another client-side redirector under Windows of with socksification library
|
||||
under Unix). So you can play your favourite games, listen music, exchange
|
||||
files and messages and even accept incoming connections behind proxy server.
|
||||
.PP
|
||||
.I dnspr
|
||||
does not exist as independant service. It\' DNS caching proxy (it requires
|
||||
.I nscache
|
||||
and
|
||||
.I nserver
|
||||
to be set in configuration. Only A-records are cached. Please note, the
|
||||
this caching is mostly a 'hack' and has nothing to do with real
|
||||
DNS server, but it works perfectly for SOHO networks.
|
||||
|
||||
.PP
|
||||
3proxy supports access control lists (ACL) like network router. Source
|
||||
and destination networks and destination port can be specified. In addition,
|
||||
usernames and gateway action (for example GET or POST) can be used in ACLs.
|
||||
In order to filter request on username basis user must be authenticated somehow. There are few
|
||||
authentication types including password authentication and authentication by
|
||||
NetBIOS name for Windows clients (it\'s very like ident authentication).
|
||||
Depending on ACL action request can be allowed, denied or redirected to another
|
||||
host or to another proxy server or even to a chain of proxy servers.
|
||||
.PP
|
||||
It supports different types of logging: to logfiles,
|
||||
.BR syslog (3)
|
||||
(only under Unix) or to ODBC database. Logging format is turnable to provide
|
||||
compatibility with existing log file parsers. It makes it possible to use
|
||||
3proxy with IIS, ISA, Apache or Squid log parsers.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B config_file
|
||||
Name of config file. See
|
||||
.BR 3proxy.cfg (3)
|
||||
for configuration file format. Under Windows, if config_file is not specified,
|
||||
.BR 3proxy
|
||||
looks for file named
|
||||
.I 3proxy.cfg
|
||||
in the default location (in same directory with executable file and in current
|
||||
directory). Under Unix, if no config file is specified, 3proxy reads
|
||||
configuration from stdin. It makes it possible to use 3proxy.cfg file as
|
||||
executable script just by setting +x mode and adding
|
||||
.br
|
||||
#!/usr/local/3proxy/3proxy
|
||||
.br
|
||||
as a first line in 3proxy.cfg
|
||||
.TP
|
||||
.B --install
|
||||
(Windows NT family only) install
|
||||
.BR 3proxy
|
||||
as a system service
|
||||
.TP
|
||||
.B --remove
|
||||
(Windows NT family only) remove
|
||||
.BR 3proxy
|
||||
from system services
|
||||
.SH SIGNALS
|
||||
Under Unix there are few signals
|
||||
.BR 3proxy
|
||||
catches. See
|
||||
.BR kill (1).
|
||||
.TP
|
||||
.B SIGTERM
|
||||
cleanup connections and exit
|
||||
.TP
|
||||
.B SIGPAUSE
|
||||
stop to accept new connections, on second signal - start and re-read
|
||||
configuration
|
||||
.TP
|
||||
.B SIGCONT
|
||||
start to accept new conenctions
|
||||
.TP
|
||||
.B SIGUSR1
|
||||
reload configuration
|
||||
.PP
|
||||
Under Windows, if
|
||||
.BR 3proxy
|
||||
is installed as service you can standard service management to start, stop,
|
||||
pause and continue 3proxy service, for example:
|
||||
.br
|
||||
.BR "net start 3proxy"
|
||||
.br
|
||||
.BR "net stop 3proxy"
|
||||
.br
|
||||
.BR "net pause 3proxy"
|
||||
.br
|
||||
.BR "net continue 3proxy"
|
||||
.PP
|
||||
Web admin service can also be used to reload configuration. Use
|
||||
wget to automate this task.
|
||||
.SH FILES
|
||||
.TP
|
||||
.I "/usr/local/3proxy/3proxy.cfg (3proxy.cfg)"
|
||||
.BR 3proxy
|
||||
configuration file
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy.cfg(3), proxy(8), ftppr(8), socks(8), pop3p(8), tcppm(8), udppm(8),
|
||||
kill(1), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH TRIVIA
|
||||
3APA3A is pronounced as \`\`zaraza\'\'.
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
951
man/3proxy.cfg.3
951
man/3proxy.cfg.3
@ -1,951 +0,0 @@
|
||||
.TH 3proxy.cfg "3" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B 3proxy.cfg
|
||||
\- 3proxy configuration file
|
||||
.SH DESCRIPTION
|
||||
Common structure:
|
||||
.br
|
||||
Configuration file is a text file 3proxy reads configuration from. Each line
|
||||
of the file is a command executed immediately, as it was given from
|
||||
console. Sequence of commands is important. Configuration file as actually a
|
||||
script for 3proxy executable.
|
||||
Each line of the file is treated as a blank (space or tab) separated
|
||||
command line. Additional space characters are ignored.
|
||||
Think about 3proxy as "application level router" with console interface.
|
||||
|
||||
.br
|
||||
Comments:
|
||||
.br
|
||||
Any string beginning with space character or \'#\' character is comment. It\'s
|
||||
ignored. <LF>s are ignored. <CR> is end of command.
|
||||
|
||||
.br
|
||||
Quotation:
|
||||
.br
|
||||
Quotation character is " (double quote). Quotation must be used to quote
|
||||
spaces or another special characters. To use quotation character inside
|
||||
quotation character must be dubbed (BASIC convention). For example to use
|
||||
HELLO "WORLD" as an argument you should use it as "HELLO ""WORLD"""\.
|
||||
Good practice is to quote any argument you use.
|
||||
|
||||
.br
|
||||
File inclusion:
|
||||
.br
|
||||
You can include file by using $FILENAME macro (replace FILENAME with a path
|
||||
to file, for example $/usr/local/etc/3proxy/conf.incl or
|
||||
$"c:\\Program Files\\3proxy\\include.cfg" Quotation is
|
||||
required in last example because path contains space character.
|
||||
For included file <CR> (end of line characters) is treated as space character
|
||||
(arguments delimiter instead of end of command delimiter).
|
||||
Thus, include files are only useful to store long signle-line commands
|
||||
(like userlist, network lists, etc).
|
||||
To use dollar sign somewhere in argument it must be quoted.
|
||||
Recursion is not allowed.
|
||||
|
||||
.br
|
||||
Next commands start gateway services:
|
||||
.br
|
||||
|
||||
.br
|
||||
.B proxy
|
||||
[options]
|
||||
.br
|
||||
.B socks
|
||||
[options]
|
||||
.br
|
||||
.B pop3p
|
||||
[options]
|
||||
.br
|
||||
.B ftppr
|
||||
[options]
|
||||
.br
|
||||
.B admin
|
||||
[options]
|
||||
.br
|
||||
.B dnspr
|
||||
[options]
|
||||
.br
|
||||
.B tcppm
|
||||
[options]
|
||||
<SRCPORT> <DSTADDR> <DSTPORT>
|
||||
.br
|
||||
.B udppm
|
||||
[options]
|
||||
<SRCPORT> <DSTADDR> <DSTPORT>
|
||||
.br
|
||||
Descriptions:
|
||||
.br
|
||||
.B proxy
|
||||
\- HTTP/HTTPS proxy (default port 3128)
|
||||
.br
|
||||
.B socks
|
||||
\- SOCKS 4/4.5/5 proxy (default port 1080)
|
||||
.br
|
||||
.B pop3p
|
||||
\- POP3 proxy (default port 110)
|
||||
.br
|
||||
.B ftppr
|
||||
\- FTP proxy (default port 21)
|
||||
.br
|
||||
.B admin
|
||||
\- Web interface (default port 80)
|
||||
.br
|
||||
.B dnspr
|
||||
\- caching DNS proxy (default port 53)
|
||||
.br
|
||||
.B tcppm
|
||||
\- TCP portmapper
|
||||
.br
|
||||
.B udppm
|
||||
\- UDP portmapper
|
||||
.br
|
||||
|
||||
Options:
|
||||
.br
|
||||
.B -pNUMBER
|
||||
change default server port to NUMBER
|
||||
.br
|
||||
.B -n
|
||||
disable NTLM authentication (required if passwords are stored in Unix crypt format.
|
||||
.br
|
||||
.B -n1
|
||||
enable NTLMv1 authentication.
|
||||
.br
|
||||
.B -s
|
||||
(for admin) - secure, allow only secure operations (currently only traffic counters
|
||||
view without ability to reset).
|
||||
.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
|
||||
.br
|
||||
.B -u
|
||||
Never ask for username/password
|
||||
.br
|
||||
.B -u2
|
||||
(socks) require username/password in authentication methods
|
||||
.br
|
||||
.B -a
|
||||
(for proxy) - anonymous proxy (no information about client reported)
|
||||
.br
|
||||
.B -a1
|
||||
(for proxy) - anonymous proxy (random client information reported)
|
||||
.br
|
||||
.B -a2
|
||||
(for proxy) - generate Via: and X-Forwared-For: instead of Forwarded:
|
||||
.br
|
||||
.B -6
|
||||
Only resolve IPv6 addresses. IPv4 addresses are packed in IPv6 in IPV6_V6ONLY compatible way.
|
||||
.br
|
||||
.B -4
|
||||
Only resolve IPv4 addresses
|
||||
.br
|
||||
.B -46
|
||||
Resolve IPv6 addresses if IPv4 address is not resolvable
|
||||
.br
|
||||
.B -64
|
||||
Resolve IPv4 addresses if IPv6 address is not resolvable
|
||||
.br
|
||||
.B -RHOST:port
|
||||
listen on given local HOST:port for incoming connections instead of making remote outgoing connection. Can be used with another 3proxy service running -r option for connect back functionality. Most commonly used with tcppm. HOST can be given as IP or hostname, useful in case of dynamic DNS.
|
||||
.br
|
||||
.B -rHOST:port
|
||||
connect to given remote HOST:port instead of listening local connection on -p or default port. Can be used with another 3proxy service running -R option for connect back functionality. Most commonly used with proxy or socks. HOST can be given as IP or hostname, useful in case of dynamic DNS.
|
||||
.br
|
||||
Also, all options mentioned for
|
||||
.BR proxy (8)
|
||||
.BR socks (8)
|
||||
.BR pop3p (8)
|
||||
.BR tcppm (8)
|
||||
.BR udppm (8)
|
||||
.BR ftppr (8)
|
||||
are also supported.
|
||||
.br
|
||||
Portmapping services listen at SRCPORT and connect to DSTADDR:DSTPORT
|
||||
HTTP and SOCKS proxies are standard.
|
||||
.br
|
||||
POP3 proxy must be configured as POP3 server and requires username in the form of:
|
||||
pop3username@pop3server. If POP3 proxy access must be authenticated, you can
|
||||
specify username as proxy_username:proxy_password:POP3_username@pop3server
|
||||
.br
|
||||
DNS proxy resolves any types of records but only hostnames are cached. It
|
||||
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
|
||||
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
|
||||
.br
|
||||
FTPuser@FTPServer
|
||||
.br
|
||||
FTPuser:FTPpassword@FTPserver
|
||||
.br
|
||||
proxyuser:proxypassword:FTPuser:FTPpassword@FTPserver
|
||||
.br
|
||||
Please note, if you use FTP client interface for FTP proxy do not add FTPpassword and FTPServer to username, because FTP client does it for you. That is, if you use 3proxy with authentication use proxyuser:proxypassword:FTPuser as FTP username, otherwise do not change original FTP user name
|
||||
|
||||
.br
|
||||
.B include
|
||||
<path>
|
||||
.br
|
||||
Include config file
|
||||
|
||||
.br
|
||||
.B config
|
||||
<path>
|
||||
.br
|
||||
Path to configuration file to use on 3proxy restart or to save configuration.
|
||||
|
||||
.br
|
||||
.B writable
|
||||
.br
|
||||
ReOpens configuration file for write access via Web interface,
|
||||
and re-reads it. Usually should be first command on config file
|
||||
but in combination with "config" it can be used anywhere to open
|
||||
alternate config file. Think twice before using it.
|
||||
|
||||
.br
|
||||
.B end
|
||||
.br
|
||||
End of configuration
|
||||
|
||||
.br
|
||||
.B log
|
||||
[[@|&]logfile] [<LOGTYPE>]
|
||||
.br
|
||||
sets logfile for all gateways
|
||||
.br
|
||||
@ - (for Unix) use syslog, filename is used as ident name
|
||||
.br
|
||||
& - use ODBC, filename consists of comma-delimited datasource,username,password (username and password are optional)
|
||||
.br
|
||||
LOGTYPE is one of:
|
||||
.br
|
||||
M - Monthly
|
||||
.br
|
||||
W - Weekly (starting from Sunday)
|
||||
.br
|
||||
D - Daily
|
||||
.br
|
||||
H - Hourly
|
||||
.br
|
||||
if logfile is not specified logging goes to stdout. You can specify individual logging options for gateway by using
|
||||
-l option in gateway configuration.
|
||||
.br
|
||||
"log" command supports same format specifications for filename template
|
||||
as "logformat" (if filename contains '%' sign it's believed to be template).
|
||||
As with "logformat" filename must begin with 'L' or 'G' to specify Local or
|
||||
Grinwitch time zone for all time-based format specificators.
|
||||
|
||||
.br
|
||||
.B rotate
|
||||
<n>
|
||||
how many archived log files to keep
|
||||
|
||||
.br
|
||||
.B logformat
|
||||
<format>
|
||||
.br
|
||||
Format for log record. First symbol in format must be L (local time)
|
||||
or G (absolute Grinwitch time).
|
||||
It can be preceeded with -XXX+Y where XXX is list of characters to be
|
||||
filtered in user input (any non-printable characters are filtered too
|
||||
in this case) and Y is replacement character. For example, "-,%+ L" in
|
||||
the beginning of logformat means comma and percent are replaced
|
||||
with space and all time based elemnts are in local time zone.
|
||||
.br
|
||||
You can use:
|
||||
|
||||
.br
|
||||
%y - Year in 2 digit format
|
||||
.br
|
||||
%Y - Year in 4 digit format
|
||||
.br
|
||||
%m - Month number
|
||||
.br
|
||||
%o - Month abbriviature
|
||||
.br
|
||||
%d - Day
|
||||
.br
|
||||
%H - Hour
|
||||
.br
|
||||
%M - Minute
|
||||
.br
|
||||
%S - Second
|
||||
.br
|
||||
%t - Timstamp (in seconds since 01-Jan-1970)
|
||||
.br
|
||||
%. - milliseconds
|
||||
.br
|
||||
%z - timeZone (from Grinvitch)
|
||||
.br
|
||||
%D - request duration (in milliseconds)
|
||||
.br
|
||||
%b - average send rate per request (in Bytes per second) this speed is typically below connection speed shown by download manager.
|
||||
.br
|
||||
%B - average receive rate per request (in Bytes per second) this speed is typically below connection speed shown by download manager.
|
||||
.br
|
||||
%U - Username
|
||||
.br
|
||||
%N - service Name
|
||||
.br
|
||||
%p - service Port
|
||||
.br
|
||||
%E - Error code
|
||||
.br
|
||||
%C - Client IP
|
||||
.br
|
||||
%c - Client port
|
||||
.br
|
||||
%R - Remote IP
|
||||
.br
|
||||
%r - Remote port
|
||||
.br
|
||||
%e - External IP used to establish connection
|
||||
.br
|
||||
%Q - Requested IP
|
||||
.br
|
||||
%q - Requested port
|
||||
.br
|
||||
%n - requested hostname
|
||||
.br
|
||||
%I - bytes In
|
||||
.br
|
||||
%O - bytes Out
|
||||
.br
|
||||
%h - Hops (redirections) count
|
||||
.br
|
||||
%T - service specific Text
|
||||
.br
|
||||
%N1-N2T - (N1 and N2 are positive numbers) - log only fields from N1 thorugh N2 of service specific text
|
||||
.br
|
||||
in case of ODBC logging logformat specifies SQL statement, for exmample:
|
||||
.br
|
||||
logformat "-'+_Linsert into log (l_date, l_user, l_service, l_in, l_out, l_descr) values ('%d-%m-%Y %H:%M:%S', '%U', '%N', %I, %O, '%T')"
|
||||
|
||||
.br
|
||||
.B logdump
|
||||
<in_traffic_limit> <out_traffic_limit>
|
||||
.br
|
||||
Immediately creates additional log records if given amount of incoming/outgoing
|
||||
traffic is achieved for connection, without waiting for connection to finish.
|
||||
It may be useful to prevent information about long-lasting downloads on server
|
||||
shutdown.
|
||||
|
||||
.br
|
||||
.B archiver
|
||||
<ext> <commandline>
|
||||
.br
|
||||
Archiver to use for log files. <ext> is file extension produced by
|
||||
archiver. Filename will be last argument to archiver, optionally you
|
||||
can use %A as produced archive name and %F as filename.
|
||||
|
||||
.br
|
||||
.B timeouts
|
||||
<BYTE_SHORT> <BYTE_LONG> <STRING_SHORT> <STRING_LONG> <CONNECTION_SHORT> <CONNECTION_LONG> <DNS> <CHAIN>
|
||||
.br
|
||||
Sets timeout values
|
||||
.br
|
||||
BYTE_SHORT - short timeout for single byte, is usually used for receiving single byte from stream.
|
||||
.br
|
||||
BYTE_LONG - long timeout for single byte, is usually used for receiving first byte in frame (for example first byte in socks request).
|
||||
.br
|
||||
STRING_SHORT - short timeout, for character string within stream (for example to wait between 2 HTTP headers)
|
||||
.br
|
||||
STRING_LONG - long timeout, for first string in stream (for example to wait for HTTP request).
|
||||
.br
|
||||
CONNECTION_SHORT - inactivity timeout for short connections (HTTP, POP3, etc).
|
||||
.br
|
||||
CONNECTION_LONG - inactivity timeout for long connection (SOCKS, portmappers, etc).
|
||||
.br
|
||||
DNS - timeout for DNS request before requesting next server
|
||||
.br
|
||||
CHAIN - timeout for reading data from chained connection
|
||||
.br
|
||||
|
||||
.br
|
||||
.B nserver
|
||||
<ipaddr>[:port][/tcp]
|
||||
.br
|
||||
Nameserver to use for name resolutions. If none specified
|
||||
or name server fails system routines for name resolution will be
|
||||
used. It's better to specify nserver because gethostbyname() may
|
||||
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
|
||||
.B nscache
|
||||
<cachesize>
|
||||
.B nscache6
|
||||
<cachesize>
|
||||
.br
|
||||
Cache <cachesize> records for name resolution (nscache for IPv4,
|
||||
nscache6 for IPv6). Cachesize usually should be large enougth
|
||||
(for example 65536).
|
||||
|
||||
.br
|
||||
.B nsrecord
|
||||
<hostname> <hostaddr>
|
||||
.br
|
||||
Adds static record to nscache. nscache must be enabled. If 0.0.0.0
|
||||
is used as a hostaddr host will never resolve, it can be used to
|
||||
blacklist something or together with
|
||||
.B dialer
|
||||
command to set up UDL for dialing.
|
||||
|
||||
.br
|
||||
.B fakeresolve
|
||||
.br
|
||||
All names are resolved to 127.0.0.2 address. Usefull if all requests are
|
||||
redirected to parent proxy with http, socks4+, connect+ or socks5+.
|
||||
|
||||
.br
|
||||
.B dialer
|
||||
<progname>
|
||||
.br
|
||||
Execute progname if external name can't be resolved.
|
||||
Hint: if you use nscache, dialer may not work, because names will
|
||||
be resolved through cache. In this case you can use something like
|
||||
http://dial.right.now/ from browser to set up connection.
|
||||
|
||||
|
||||
.br
|
||||
.B internal
|
||||
<ipaddr>
|
||||
.br
|
||||
sets ip address of internal interface. This IP address will be used
|
||||
to bind gateways. Alternatively you can use -i option for individual
|
||||
gateways. Since 0.8 version, IPv6 address may be used.
|
||||
|
||||
.br
|
||||
.B external
|
||||
<ipaddr>
|
||||
.br
|
||||
sets ip address of external interface. This IP address will be source
|
||||
address for all connections made by proxy. Alternatively you can use
|
||||
-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
|
||||
.B maxconn
|
||||
<number>
|
||||
.br
|
||||
sets maximum number of simulationeous connections to each services
|
||||
started after this command. Default is 100.
|
||||
|
||||
.br
|
||||
.B service
|
||||
.br
|
||||
(depricated). Indicates 3proxy to behave as Windows 95/98/NT/2000/XP
|
||||
service, no effect for Unix. Not required for 3proxy 0.6 and above. If
|
||||
you upgraded from previous version of 3proxy use --remove and --install
|
||||
to reinstall service.
|
||||
|
||||
.br
|
||||
.B daemon
|
||||
.br
|
||||
Should be specified to close console. Do not use 'daemon' with 'service'.
|
||||
At least under FreeBSD 'daemon' should preceed any proxy service
|
||||
and log commands to avoid sockets problem. Always place it in the beginning
|
||||
of the configuration file.
|
||||
|
||||
.br
|
||||
.B auth
|
||||
<authtype> [...]
|
||||
.br
|
||||
Type of user authorization. Currently supported:
|
||||
.br
|
||||
none - no authentication or authorization required.
|
||||
.br
|
||||
Note: is auth is none any ip based limitation, redirection, etc will not work.
|
||||
This is default authentication type
|
||||
.br
|
||||
iponly - authentication by access control list with username ignored.
|
||||
Appropriate for most cases
|
||||
.br
|
||||
useronly - authentication by username without checking for any password with
|
||||
authorization by ACLs. Useful for e.g. SOCKSv4 proxy and icqpr (icqpr set UIN /
|
||||
AOL screen name as a username)
|
||||
.br
|
||||
dnsname - authentication by DNS hostnname with authorization by ACLs.
|
||||
DNS hostname is resolved via PTR (reverse) record and validated (resolved
|
||||
name must resolve to same IP address). It's recommended to use authcache by
|
||||
ip for this authentication.
|
||||
NB: there is no any password check, name may be spoofed.
|
||||
.br
|
||||
strong - username/password authentication required. It will work with
|
||||
SOCKSv5, FTP, POP3 and HTTP proxy.
|
||||
.br
|
||||
cache - cached authentication, may be used with 'authcache'.
|
||||
.br
|
||||
Plugins may add additional authentication types.
|
||||
.br
|
||||
|
||||
It's possible to use few authentication types in the same commands. E.g.
|
||||
.br
|
||||
auth iponly strong
|
||||
.br
|
||||
In this case 'strong' authentication will be used only in case resource
|
||||
access can not be performed with 'iponly' authentication, that is username is
|
||||
required in ACL. It's usefull to protect access to some resources with
|
||||
password allowing passwordless access to another resources, or to use
|
||||
IP-based authentication for dedicated laptops and request username/password for
|
||||
shared ones.
|
||||
|
||||
.br
|
||||
.B authcache
|
||||
<cachtype> <cachtime>
|
||||
.br
|
||||
Cache authentication information to given amount of time (cachetime) in seconds.
|
||||
Cahtype is one of:
|
||||
.br
|
||||
ip - after successful authentication all connections during caching time
|
||||
from same IP are assigned to the same user, username is not requested.
|
||||
.br
|
||||
ip,user username is requested and all connections from the same IP are
|
||||
assigned to the same user without actual authentication.
|
||||
.br
|
||||
user - same as above, but IP is not checked.
|
||||
.br
|
||||
user,password - both username and password are checked against cached ones.
|
||||
.br
|
||||
Use auth type 'cache' for cached authentication
|
||||
|
||||
.br
|
||||
.B allow
|
||||
<userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
<weekdayslist> <timeperiodslist>
|
||||
.br
|
||||
.B deny
|
||||
<userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
<weekdayslist> <timeperiodslist>
|
||||
.br
|
||||
Access control entries. All lists are comma-separated, no spaces are
|
||||
allowed. Usernames are case sensitive (if used with authtype nbname
|
||||
username must be in uppercase). Source and target lists may contain
|
||||
IP addresses (W.X.Y.Z), ranges A.B.C.D - W.X.Y.Z (since 0.8) or CIDRs
|
||||
(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
|
||||
*badcontent*. Hostname is only checked if hostname presents in request.
|
||||
Targetportlist may contain ports (X) or port ranges lists (X-Y). For any field
|
||||
* sign means "ANY" If access list is empty it's assumed to be
|
||||
.br
|
||||
allow *
|
||||
.br
|
||||
If access list is not empty last item in access list is assumed to be
|
||||
.br
|
||||
deny *
|
||||
.br
|
||||
You may want explicitly add "deny *" to the end of access list to prevent
|
||||
HTTP proxy from requesting user's password.
|
||||
Access lists are checked after user have requested any resource.
|
||||
If you want 3proxy to reject connections from specific addresses
|
||||
immediately without any conditions you should either bind proxy
|
||||
to appropriate interface only or to use ip filters.
|
||||
.br
|
||||
|
||||
Operation is one of:
|
||||
.br
|
||||
CONNECT - establish outgoing TCP connection
|
||||
.br
|
||||
BIND - bind TCP port for listening
|
||||
.br
|
||||
UDPASSOC - make UDP association
|
||||
.br
|
||||
ICMPASSOC - make ICMP association (for future use)
|
||||
.br
|
||||
HTTP_GET - HTTP GET request
|
||||
.br
|
||||
HTTP_PUT - HTTP PUT request
|
||||
.br
|
||||
HTTP_POST - HTTP POST request
|
||||
.br
|
||||
HTTP_HEAD - HTTP HEAD request
|
||||
.br
|
||||
HTTP_CONNECT - HTTP CONNECT request
|
||||
.br
|
||||
HTTP_OTHER - over HTTP request
|
||||
.br
|
||||
HTTP - matches any HTTP request except HTTP_CONNECT
|
||||
.br
|
||||
HTTPS - same as HTTP_CONNECT
|
||||
.br
|
||||
FTP_GET - FTP get request
|
||||
.br
|
||||
FTP_PUT - FTP put request
|
||||
.br
|
||||
FTP_LIST - FTP list request
|
||||
.br
|
||||
FTP_DATA - FTP data connection. Note: FTP_DATA requires access to dynamic
|
||||
non-ptivileged (1024-65535) ports on remote side.
|
||||
.br
|
||||
FTP - matches any FTP/FTP Data request
|
||||
.br
|
||||
ADMIN - access to administration interface
|
||||
.br
|
||||
Weeksdays are week days numbers or periods, 0 or 7 means Sunday, 1 is Monday, 1-5 means Monday through Friday. Timeperiodlists is a list of time
|
||||
periods in HH:MM:SS-HH:MM:SS format. For example, 00:00:00-08:00:00,17:00:00-24:00:00 lists non-working hours.
|
||||
|
||||
.br
|
||||
.B parent
|
||||
<weight> <type> <ip> <port> <username> <password>
|
||||
.br
|
||||
this command must follow "allow" rule. It extends last allow rule to
|
||||
build proxy chain. Proxies may be grouped. Proxy inside the
|
||||
group is selected randomly. If few groups are specified one proxy
|
||||
is randomly picked from each group and chain of proxies is created
|
||||
(that is second proxy connected through first one and so on).
|
||||
Weight is used to group proxies. Weigt is a number between 1 and 1000.
|
||||
Weights are summed and proxies are grouped together untill weight of
|
||||
group is 1000. That is:
|
||||
.br
|
||||
allow *
|
||||
.br
|
||||
parent 500 socks5 192.168.10.1 1080
|
||||
.br
|
||||
parent 500 connect 192.168.10.1 3128
|
||||
.br
|
||||
makes 3proxy to randomly choose between 2 proxies for all outgoing
|
||||
connections. These 2 proxies form 1 group (summarized weight is 1000).
|
||||
.br
|
||||
allow * * * 80
|
||||
.br
|
||||
parent 1000 socks5 192.168.10.1 1080
|
||||
.br
|
||||
parent 1000 connect 192.168.20.1 3128
|
||||
.br
|
||||
parent 300 socks4 192.168.30.1 1080
|
||||
.br
|
||||
parent 700 socks5 192.168.40.1 1080
|
||||
.br
|
||||
creates chain of 3 proxies: 192.168.10.1, 192.168.20.1 and third
|
||||
is (192.168.30.1 with probability of 0.3 or 192.168.40.1
|
||||
with probability of 0.7) for outgoing web connections.
|
||||
|
||||
.br
|
||||
type is one of:
|
||||
.br
|
||||
tcp - simply redirect connection. TCP is always last in chain.
|
||||
.br
|
||||
http - redirect to HTTP proxy. HTTP is always last chain.
|
||||
.br
|
||||
pop3 - redirect to POP3 proxy (only local redirection is supported, can not be
|
||||
used for chaining)
|
||||
.br
|
||||
ftp - redirect to FTP proxy (only local redirection is supported, can not be
|
||||
used for chaining)
|
||||
.br
|
||||
connect - parent is HTTP CONNECT method proxy
|
||||
.br
|
||||
connect+ - parent is HTTP CONNECT proxy with name resolution
|
||||
.br
|
||||
socks4 - parent is SOCKSv4 proxy
|
||||
.br
|
||||
socks4+ - parent is SOCKSv4 proxy with name resolution (SOCKSv4a)
|
||||
.br
|
||||
socks5 - parent is SOCKSv5 proxy
|
||||
.br
|
||||
socks5+ - parent is SOCKSv5 proxy with name resolution
|
||||
.br
|
||||
socks4b - parent is SOCKS4b (broken SOCKSv4 implementation with shortened
|
||||
server reply. I never saw this kind ofservers byt they say there are).
|
||||
Normally you should not use this option. Do not mess this option with
|
||||
SOCKSv4a (socks4+).
|
||||
.br
|
||||
socks5b - parent is SOCKS5b (broken SOCKSv5 implementation with shortened
|
||||
server reply. I think you will never find it useful). Never use this option
|
||||
unless you know exactly you need it.
|
||||
.br
|
||||
admin - redirect request to local 'admin' service (with -s parameter).
|
||||
.br
|
||||
Use "+" proxy only with "fakeresolve" option
|
||||
.br
|
||||
|
||||
IP and port are ip addres and port of parent proxy server.
|
||||
If IP is zero, ip is taken from original request, only port is changed.
|
||||
If port is zero, it's taken from original request, only IP is changed.
|
||||
If both IP and port are zero - it's a special case of local redirection,
|
||||
it works only with
|
||||
.B socks
|
||||
proxy. In case of local redirection request is redirected to different service,
|
||||
.B ftp
|
||||
locally redirects to
|
||||
.B ftppr
|
||||
.B pop3
|
||||
locally redirects to
|
||||
.B pop3p
|
||||
.B http
|
||||
locally redurects to
|
||||
.B proxy
|
||||
.B admin
|
||||
locally redirects to admin -s service.
|
||||
.br
|
||||
|
||||
Main purpose of local redirections is to have requested resource
|
||||
(URL or POP3 username) logged and protocol-specific filters to be applied.
|
||||
In case of local redirection ACLs are revied twice: first, by SOCKS proxy up to
|
||||
'parent' command and then with gateway service connection is
|
||||
redirected (HTTP, FTP or POP3) after 'parent' command. It means,
|
||||
additional 'allow' command is required for redirected requests, for
|
||||
example:
|
||||
.br
|
||||
allow * * * 80
|
||||
.br
|
||||
parent 1000 http 0.0.0.0 0
|
||||
.br
|
||||
allow * * * 80 HTTP_GET,HTTP_POST
|
||||
.br
|
||||
socks
|
||||
.br
|
||||
redirects all SOCKS requests with target port 80 to local HTTP proxy,
|
||||
local HTTP proxy parses requests and allows only GET and POST requests.
|
||||
.br
|
||||
parent 1000 http 1.2.3.4 0
|
||||
.br
|
||||
Changes external address for given connection to 1.2.3.4
|
||||
(an equivalent to -e1.2.3.4)
|
||||
.br
|
||||
Optional username and password are used to authenticate on parent
|
||||
proxy. Username of '*' means username must be supplied by user.
|
||||
|
||||
|
||||
.br
|
||||
.B nolog
|
||||
<n>
|
||||
.br
|
||||
extends last allow or deny command to prevent logging, e.g.
|
||||
.br
|
||||
allow * * 192.168.1.1
|
||||
.br
|
||||
nolog
|
||||
|
||||
|
||||
.br
|
||||
.B weight
|
||||
<n>
|
||||
.br
|
||||
extends last allow or deny command to set weight for this request
|
||||
.br
|
||||
allow * * 192.168.1.1
|
||||
.br
|
||||
weight 100
|
||||
.br
|
||||
Weight may be used for different purposes.
|
||||
|
||||
.br
|
||||
.B bandlimin
|
||||
<rate> <userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
.br
|
||||
.B nobandlimin
|
||||
<userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
.br
|
||||
.B bandlimout
|
||||
<rate> <userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
.br
|
||||
.B nobandlimout
|
||||
<userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
.br
|
||||
bandlim sets bandwith limitation filter to <rate> bps (bits per second)
|
||||
(if you want to specife bytes per second - multiply your value to 8).
|
||||
bandlim rules act in a same manner as allow/deny rules except
|
||||
one thing: bandwidth limiting is applied to all services, not to some
|
||||
specific service.
|
||||
bandlimin and nobandlimin applies to incoming traffic
|
||||
bandlimout and nobandlimout applies to outgoing traffic
|
||||
If tou want to ratelimit your clients with ip's 192.168.10.16/30 (4
|
||||
addresses) to 57600 bps you have to specify 4 rules like
|
||||
.br
|
||||
bandlimin 57600 * 192.168.10.16
|
||||
.br
|
||||
bandlimin 57600 * 192.168.10.17
|
||||
.br
|
||||
bandlimin 57600 * 192.168.10.18
|
||||
.br
|
||||
bandlimin 57600 * 192.168.10.19
|
||||
.br
|
||||
and every of you clients will have 56K channel. If you specify
|
||||
.br
|
||||
bandlimin 57600 * 192.168.10.16/30
|
||||
.br
|
||||
you will have 56K channel shared between all clients.
|
||||
if you want, for example, to limit all speed ecept access to POP3 you can use
|
||||
.br
|
||||
nobandlimin * * * 110
|
||||
.br
|
||||
before the rest of bandlim rules.
|
||||
|
||||
.br
|
||||
.B counter
|
||||
<filename> <reporttype> <repotname>
|
||||
.br
|
||||
.B countin
|
||||
<number> <type> <limit> <userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
.br
|
||||
.B nocountin
|
||||
<userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
.br
|
||||
.B countout
|
||||
<number> <type> <limit> <userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
.br
|
||||
.B nocountout
|
||||
<userlist> <sourcelist> <targetlist> <targetportlist> <operationlist>
|
||||
.br
|
||||
|
||||
counter, countin, nocountin, countout, noucountout commands are
|
||||
used to set traffic limit
|
||||
in MB for period of time (day, week or month). Filename is a path
|
||||
to a special file where traffic information is permanently stored.
|
||||
number is sequential number of record in this file. If number is 0
|
||||
no traffic information on this counter is saved in file (that is
|
||||
if proxy restarted all information is loosed) overwise it should be
|
||||
unique sequential number.
|
||||
Type specifies a type of counter. Type is one of:
|
||||
.br
|
||||
H - counter is resetted hourly
|
||||
.br
|
||||
D - counter is resetted daily
|
||||
.br
|
||||
W - counter is resetted weekly
|
||||
.br
|
||||
M - counter is resetted monthely
|
||||
.br
|
||||
reporttype/repotname may be used to generate traffic reports.
|
||||
Reporttype is one of D,W,M,H(hourly) and repotname specifies filename
|
||||
template for reports. Report is text file with counter values in
|
||||
format:
|
||||
.br
|
||||
<COUNTERNUMBER> <TRAF>
|
||||
.br
|
||||
The rest of parameters is identical to bandlim/nobandlim.
|
||||
|
||||
.br
|
||||
.B users
|
||||
username[:pwtype:password] ...
|
||||
.br
|
||||
pwtype is one of:
|
||||
.br
|
||||
none (empty) - use system authentication
|
||||
.br
|
||||
CL - password is cleartext
|
||||
.br
|
||||
CR - password is crypt-style password
|
||||
.br
|
||||
NT - password is NT password (in hex)
|
||||
.br
|
||||
example:
|
||||
.br
|
||||
users test1:CL:password1 "test2:CR:$1$lFDGlder$pLRb4cU2D7GAT58YQvY49."
|
||||
.br
|
||||
users test3:NT:BD7DFBF29A93F93C63CB84790DA00E63
|
||||
.br
|
||||
Note: double quotes are requiered because password contains $ sign.
|
||||
|
||||
.br
|
||||
.B flush
|
||||
.br
|
||||
empty active access list. Access list must be flushed avery time you creating
|
||||
new access list for new service. For example:
|
||||
.br
|
||||
allow *
|
||||
.br
|
||||
pop3p
|
||||
.br
|
||||
flush
|
||||
.br
|
||||
allow * 192.168.1.0/24
|
||||
.br
|
||||
socks
|
||||
.br
|
||||
sets different ACLs for
|
||||
.B pop3p
|
||||
and
|
||||
.B socks
|
||||
|
||||
.br
|
||||
.B system
|
||||
<command>
|
||||
.br
|
||||
execute system command
|
||||
|
||||
.br
|
||||
.B pidfile
|
||||
<filename>
|
||||
.br
|
||||
write pid of current process to file. It can be used to manipulate
|
||||
3proxy with signals under Unix. Currently next signals are available:
|
||||
|
||||
.br
|
||||
.B monitor
|
||||
<filename>
|
||||
.br
|
||||
If file monitored changes in modification time or size, 3proxy reloads
|
||||
configuration within one minute. Any number of files may be monitored.
|
||||
|
||||
.br
|
||||
.B setuid
|
||||
<uid>
|
||||
.br
|
||||
calls setuid(uid), uid must be numeric. Unix only. Warning: under some Linux
|
||||
kernels setuid() works onle for current thread. It makes it impossible to suid
|
||||
for all threads.
|
||||
|
||||
.br
|
||||
.B setgid
|
||||
<gid>
|
||||
.br
|
||||
calls setgid(gid), gid must be numeric. Unix only.
|
||||
|
||||
.br
|
||||
.B chroot
|
||||
<path>
|
||||
.br
|
||||
calls chroot(path). Unix only.
|
||||
|
||||
.br
|
||||
.B stacksize
|
||||
<value_to_add_to_default_stack_size>
|
||||
.br
|
||||
Change default size for threads stack. May be required in some situation,
|
||||
e.g. with non-default plugins, on on some platforms (some FreeBSD version
|
||||
may require adjusting stack size due to invalid defined value in system
|
||||
header files, this value is also oftent reqruied to be changed for ODBC and
|
||||
PAM support on Linux. If you experience 3proxy
|
||||
crash on request processing, try to set some positive value. You may start with
|
||||
stacksize 65536
|
||||
and then find the minimal value for service to work. If you experience
|
||||
memory shortage, you can try to experiment with negative values.
|
||||
.SH PLUGINS
|
||||
|
||||
.br
|
||||
.B plugin
|
||||
<path_to_shared_library> <function_to_call> [<arg1> ...]
|
||||
.br
|
||||
Loads specified library and calls given export function with given arguments,
|
||||
as
|
||||
.br
|
||||
int functions_to_call(struct pluginlink * pl, int argc, char * argv[]);
|
||||
.br
|
||||
function_to_call must return 0 in case of success, value > 0 to indicate error.
|
||||
|
||||
.br
|
||||
.B filtermaxsize
|
||||
<max_size_of_data_to_filter>
|
||||
.br
|
||||
If Content-length (or another data length) is greater than given value, no
|
||||
data filtering will be performed thorugh filtering plugins to avoid data
|
||||
corruption and/or Content-Length chaging. Default is 1MB (1048576).
|
||||
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy(8), proxy(8), ftppr(8), socks(8), pop3p(8), tcppm(8), udppm(8), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH TRIVIA
|
||||
3APA3A is pronounced as \`\`zaraza\'\'.
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
87
man/ftppr.8
87
man/ftppr.8
@ -1,87 +0,0 @@
|
||||
.TH ftppr "8" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B ftppr
|
||||
\- FTP proxy gateway service
|
||||
.SH SYNOPSIS
|
||||
.BR "ftppr " [ -d ]
|
||||
.IB \fR[ -l \fR[ \fR[ @ \fR] logfile \fR]]
|
||||
.IB \fR[ -p port\fR]
|
||||
.IB \fR[ -i internal_ip\fR]
|
||||
.IB \fR[ -e external_ip\fR]
|
||||
.IB \fR[ -h default_ip[:port]\fR]
|
||||
.SH DESCRIPTION
|
||||
.B ftppr
|
||||
is FTP gateway service to allow internal users to access external FTP
|
||||
servers.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -I
|
||||
Inetd mode. Standalone service only.
|
||||
.TP
|
||||
.B -d
|
||||
Daemonise. Detach service from console and run in the background.
|
||||
.TP
|
||||
.B -t
|
||||
Be silenT. Do not log start/stop/accept error records.
|
||||
.TP
|
||||
.B -u
|
||||
Never look for username authentication.
|
||||
.TP
|
||||
.B -e
|
||||
External address. IP address of interface proxy should initiate connections
|
||||
from.
|
||||
By default system will deside which address to use in accordance
|
||||
with routing table.
|
||||
.TP
|
||||
.B -i
|
||||
Internal address. IP address proxy accepts connections to.
|
||||
By default connection to any interface is accepted. It\'s usually unsafe.
|
||||
.TP
|
||||
.B -h
|
||||
Default destination. It's used if targed address is not specified by user.
|
||||
.TP
|
||||
.B -p
|
||||
Port. Port proxy listens for incoming connections. Default is 21.
|
||||
.TP
|
||||
.B -l
|
||||
Log. By default logging is to stdout. If
|
||||
.I logfile
|
||||
is specified logging is to file. Under Unix, if
|
||||
.RI \' @ \'
|
||||
preceeds
|
||||
.IR logfile ,
|
||||
syslog is used for logging.
|
||||
.TP
|
||||
.B -S
|
||||
Increase or decrease stack size. You may want to try something like -S8192 if you experience 3proxy
|
||||
crashes.
|
||||
.SH CLIENTS
|
||||
You can use any FTP client, regardless of FTP proxy support. For client with
|
||||
FTP proxy support configure
|
||||
.I internal_ip
|
||||
and
|
||||
.IR port
|
||||
in FTP proxy parameters.
|
||||
For clients without FTP proxy support use
|
||||
.I internal_ip
|
||||
and
|
||||
.IR port
|
||||
as FTP server. Address of real FTP server must be configured as a part of
|
||||
FTP username. Format for username is
|
||||
.IR username \fB@ server ,
|
||||
where
|
||||
.I server
|
||||
is address of FTP server and
|
||||
.I username
|
||||
is user\'s login on this FTP server. Login itself may contain \'@\' sign.
|
||||
Only cleartext authentication is currently supported.
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy(8), proxy(8), pop3p(8), socks(8), tcppm(8), udppm(8), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
80
man/icqpr.8
80
man/icqpr.8
@ -1,80 +0,0 @@
|
||||
.TH icqpr "8" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B icqpr
|
||||
\- ICQ (AOL OSCAR) proxy
|
||||
.SH SYNOPSIS
|
||||
.BR "icqpr " [ -d ]
|
||||
.IB \fR[ -l \fR[ \fR[ @ \fR] logfile \fR]]
|
||||
.IB \fR[ -i internal_ip\fR]
|
||||
.IB \fR[ -e external_ip\fR]
|
||||
.I local_port remote_host remote_port
|
||||
.SH DESCRIPTION
|
||||
.B icqpr
|
||||
forwards ICQ connections from local to remote ICQ host. Most usual is
|
||||
.B icqpr 5190 login.icq.com 5190
|
||||
Also, icqpr adds UIN / AOL screen name as a username. It makes it possible
|
||||
to control user's access to ICQ/AOL by UIN/screen name (use
|
||||
.B auth useronly
|
||||
in 3proxy).
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -I
|
||||
Inetd mode. Standalone service only.
|
||||
.TP
|
||||
.B -d
|
||||
Daemonise. Detach service from console and run in the background.
|
||||
.TP
|
||||
.B -t
|
||||
Be silenT. Do not log start/stop/accept error records.
|
||||
.TP
|
||||
.B -e
|
||||
External address. IP address of interface proxy should initiate connections
|
||||
from.
|
||||
By default system will deside which address to use in accordance
|
||||
with routing table.
|
||||
.TP
|
||||
.B -i
|
||||
Internal address. IP address proxy accepts connections to.
|
||||
By default connection to any interface is accepted. It\'s usually unsafe.
|
||||
.TP
|
||||
.B -l
|
||||
Log. By default logging is to stdout. If
|
||||
.I logfile
|
||||
is specified logging is to file. Under Unix, if
|
||||
.RI \' @ \'
|
||||
preceeds
|
||||
.IR logfile ,
|
||||
syslog is used for logging.
|
||||
.TP
|
||||
.B -S
|
||||
Increase or decrease stack size. You may want to try something like -S8192 if you experience 3proxy
|
||||
crashes.
|
||||
.SH ARGUMENTS
|
||||
.TP
|
||||
.I local_port
|
||||
- port icqpr accepts connection
|
||||
.TP
|
||||
.I remote_host
|
||||
- IP address of the host connection is forwarded to
|
||||
.TP
|
||||
.I remote_port
|
||||
- remote port connection is forwarded to
|
||||
.SH CLIENTS
|
||||
You can use any ICQ/AOL client where server address configuration is supported
|
||||
or spoof login server name (e.g. login.icq.com) with IP address of proxy server
|
||||
via DNS record or hosts file. Transparent redirection is also possible. Use
|
||||
.I internal_ip
|
||||
and
|
||||
.I local_port
|
||||
as a destination in client application. Connection is forwarded to
|
||||
.IR remote_host : remote_port
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy(8), proxy(8), ftppr(8), socks(8), pop3p(8), udppm(8), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
83
man/pop3p.8
83
man/pop3p.8
@ -1,83 +0,0 @@
|
||||
.TH pop3p "8" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B pop3p
|
||||
\- POP3 proxy gateway service
|
||||
.SH SYNOPSIS
|
||||
.BR "pop3p " [ -d ]
|
||||
.IB \fR[ -l \fR[ \fR[ @ \fR] logfile \fR]]
|
||||
.IB \fR[ -p port\fR]
|
||||
.IB \fR[ -i internal_ip\fR]
|
||||
.IB \fR[ -e external_ip\fR]
|
||||
.IB \fR[ -h default_ip[:port]\fR]
|
||||
.SH DESCRIPTION
|
||||
.B pop3p
|
||||
is POP3 gateway service to allow internal users to access external POP3
|
||||
servers.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -I
|
||||
Inetd mode. Standalone service only.
|
||||
.TP
|
||||
.B -d
|
||||
Daemonise. Detach service from console and run in the background.
|
||||
.TP
|
||||
.B -t
|
||||
Be silenT. Do not log start/stop/accept error records.
|
||||
.TP
|
||||
.B -u
|
||||
Never look for username authentication.
|
||||
.TP
|
||||
.B -e
|
||||
External address. IP address of interface proxy should initiate connections
|
||||
from.
|
||||
By default system will deside which address to use in accordance
|
||||
with routing table.
|
||||
.TP
|
||||
.B -i
|
||||
Internal address. IP address proxy accepts connections to.
|
||||
By default connection to any interface is accepted. It\'s usually unsafe.
|
||||
.TP
|
||||
.B -p
|
||||
Port. Port proxy listens for incoming connections. Default is 110.
|
||||
.TP
|
||||
.B -h
|
||||
Default destination. It's used if targed address is not specified by user.
|
||||
.TP
|
||||
.B -l
|
||||
Log. By default logging is to stdout. If
|
||||
.I logfile
|
||||
is specified logging is to file. Under Unix, if
|
||||
.RI \' @ \'
|
||||
preceeds
|
||||
.IR logfile ,
|
||||
syslog is used for logging.
|
||||
.TP
|
||||
.B -S
|
||||
Increase or decrease stack size. You may want to try something like -S8192 if you experience 3proxy
|
||||
crashes.
|
||||
.SH CLIENTS
|
||||
You can use any MUA (Mail User Agent) with POP3 support. Set client to use
|
||||
.I internal_ip
|
||||
and
|
||||
.IR port
|
||||
as a POP3 server. Address of real POP3 server must be configured as a part of
|
||||
POP3 username. Format for username is
|
||||
.IR username \fB@ server ,
|
||||
where
|
||||
.I server
|
||||
is address of POP3 server and
|
||||
.I username
|
||||
is user\'s login on this POP3 server. Login itself may contain \'@\' sign.
|
||||
Only cleartext authentication is supported, because challenge-response
|
||||
authentication (APOP, CRAM-MD5, etc) requires challenge from server before
|
||||
we know which server to connect.
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy(8), ftppr(8), proxy(8), socks(8), tcppm(8), udppm(8), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
78
man/proxy.8
78
man/proxy.8
@ -1,78 +0,0 @@
|
||||
.TH proxy "8" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B proxy
|
||||
\- HTTP proxy gateway service
|
||||
.SH SYNOPSIS
|
||||
.BR "proxy " [ -d ][ -a ]
|
||||
.IB \fR[ -l \fR[ \fR[ @ \fR] logfile \fR]]
|
||||
.IB \fR[ -p port\fR]
|
||||
.IB \fR[ -i internal_ip\fR]
|
||||
.IB \fR[ -e external_ip\fR]
|
||||
.SH DESCRIPTION
|
||||
.B proxy
|
||||
is HTTP gateway service with HTTPS and FTP over HTTPS support.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -I
|
||||
Inetd mode. Standalone service only.
|
||||
.TP
|
||||
.B -d
|
||||
Daemonise. Detach service from console and run in the background.
|
||||
.TP
|
||||
.B -t
|
||||
Be silenT. Do not log start/stop/accept error records.
|
||||
.TP
|
||||
.B -u
|
||||
Never ask for username authentication
|
||||
.TP
|
||||
.B -e
|
||||
External address. IP address of interface proxy should initiate connections
|
||||
from.
|
||||
By default system will deside which address to use in accordance
|
||||
with routing table.
|
||||
.TP
|
||||
.B -i
|
||||
Internal address. IP address proxy accepts connections to.
|
||||
By default connection to any interface is accepted. It\'s usually unsafe.
|
||||
.TP
|
||||
.B -a
|
||||
Anonymous. Hide information about client.
|
||||
.TP
|
||||
.B -a1
|
||||
Anonymous. Show fake information about client.
|
||||
.TP
|
||||
.B -p
|
||||
Port. Port proxy listens for incoming connections. Default is 3128.
|
||||
.TP
|
||||
.B -l
|
||||
Log. By default logging is to stdout. If
|
||||
.I logfile
|
||||
is specified logging is to file. Under Unix, if
|
||||
.RI \' @ \'
|
||||
preceeds
|
||||
.IR logfile ,
|
||||
syslog is used for logging.
|
||||
.TP
|
||||
.B -S
|
||||
Increase or decrease stack size. You may want to try something like -S8192 if you experience 3proxy
|
||||
crashes.
|
||||
.SH CLIENTS
|
||||
You should use client with HTTP proxy support or configure router to redirect
|
||||
HTTP traffic to proxy (transparent proxy). Configure client to connect to
|
||||
.I internal_ip
|
||||
and
|
||||
.IR port .
|
||||
HTTPS support allows to use almost any TCP based protocol. If you need to
|
||||
limit clients, use
|
||||
.BR 3proxy (8)
|
||||
instead.
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy(8), ftppr(8), socks(8), pop3p(8), tcppm(8), udppm(8), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
84
man/smtpp.8
84
man/smtpp.8
@ -1,84 +0,0 @@
|
||||
.TH smtpp "8" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B smtpp
|
||||
\- SMTP proxy gateway service
|
||||
.SH SYNOPSIS
|
||||
.BR "smtpp " [ -d ]
|
||||
.IB \fR[ -l \fR[ \fR[ @ \fR] logfile \fR]]
|
||||
.IB \fR[ -p port\fR]
|
||||
.IB \fR[ -i internal_ip\fR]
|
||||
.IB \fR[ -e external_ip\fR]
|
||||
.IB \fR[ -h default_ip[:port]\fR]
|
||||
.SH DESCRIPTION
|
||||
.B smtpp
|
||||
is SMTP gateway service to allow internal users to access external SMTP
|
||||
servers.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -I
|
||||
Inetd mode. Standalone service only.
|
||||
.TP
|
||||
.B -d
|
||||
Daemonise. Detach service from console and run in the background.
|
||||
.TP
|
||||
.B -t
|
||||
Be silenT. Do not log start/stop/accept error records.
|
||||
.TP
|
||||
.B -u
|
||||
Never look for username authentication.
|
||||
.TP
|
||||
.B -e
|
||||
External address. IP address of interface proxy should initiate connections
|
||||
from.
|
||||
By default system will deside which address to use in accordance
|
||||
with routing table.
|
||||
.TP
|
||||
.B -i
|
||||
Internal address. IP address proxy accepts connections to.
|
||||
By default connection to any interface is accepted. It\'s usually unsafe.
|
||||
.TP
|
||||
.B -p
|
||||
Port. Port proxy listens for incoming connections. Default is 25.
|
||||
.TP
|
||||
.B -h
|
||||
Default destination. It's used if targed address is not specified by user.
|
||||
.TP
|
||||
.B -l
|
||||
Log. By default logging is to stdout. If
|
||||
.I logfile
|
||||
is specified logging is to file. Under Unix, if
|
||||
.RI \' @ \'
|
||||
preceeds
|
||||
.IR logfile ,
|
||||
syslog is used for logging.
|
||||
.TP
|
||||
.B -S
|
||||
Increase or decrease stack size. You may want to try something like -S8192 if you experience 3proxy
|
||||
crashes.
|
||||
.SH CLIENTS
|
||||
You can use any MUA (Mail User Agent) with SMTP authentication support.
|
||||
Set client to use
|
||||
.I internal_ip
|
||||
and
|
||||
.IR port
|
||||
as a SMTP server. Address of real SMTP server must be configured as a part of
|
||||
SMTP username. Format for username is
|
||||
.IR username \fB@ server ,
|
||||
where
|
||||
.I server
|
||||
is address of SMTP server and
|
||||
.I username
|
||||
is user\'s login on this SMTP server. Login itself may contain \'@\' sign.
|
||||
Only cleartext authentication is supported, because challenge-response
|
||||
authentication (CRAM-MD5, SPA, etc) requires challenge from server before
|
||||
we know which server to connect.
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy(8), ftppr(8), proxy(8), socks(8), tcppm(8), udppm(8), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
79
man/socks.8
79
man/socks.8
@ -1,79 +0,0 @@
|
||||
.TH socks "8" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B socks
|
||||
\- SOCKS 4/4.5/5 gateway service
|
||||
.SH SYNOPSIS
|
||||
.BR "socks " [ -d ]
|
||||
.IB \fR[ -l \fR[ \fR[ @ \fR] logfile \fR]]
|
||||
.IB \fR[ -p port\fR]
|
||||
.IB \fR[ -i internal_ip\fR]
|
||||
.IB \fR[ -e external_ip\fR]
|
||||
.SH DESCRIPTION
|
||||
.B socks
|
||||
is SOCKS server. It supports SOCKSv4, SOCKSv4.5 (extension to v4 for
|
||||
server side name resolution) and SOCKSv5. SOCKSv5 specification allows both
|
||||
outgoing and reverse TCP connections and UDP portmapping.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -I
|
||||
Inetd mode. Standalone service only.
|
||||
.TP
|
||||
.B -d
|
||||
Daemonise. Detach service from console and run in the background.
|
||||
.TP
|
||||
.B -t
|
||||
Be silenT. Do not log start/stop/accept error records.
|
||||
.TP
|
||||
.B -u
|
||||
Never ask for username authentication
|
||||
.TP
|
||||
.B -e
|
||||
External address. IP address of interface proxy should initiate connections
|
||||
from. External IP must be specified if you need incoming connections.
|
||||
By default system will deside which address to use in accordance
|
||||
with routing table.
|
||||
.TP
|
||||
.B -i
|
||||
Internal address. IP address proxy accepts connections to.
|
||||
By default connection to any interface is accepted. It\'s usually unsafe.
|
||||
.TP
|
||||
.B -p
|
||||
Port. Port proxy listens for incoming connections. Default is 1080.
|
||||
.TP
|
||||
.B -l
|
||||
Log. By default logging is to stdout. If
|
||||
.I logfile
|
||||
is specified logging is to file. Under Unix, if
|
||||
.RI \' @ \'
|
||||
preceeds
|
||||
.IR logfile ,
|
||||
syslog is used for logging.
|
||||
.TP
|
||||
.B -S
|
||||
Increase or decrease stack size. You may want to try something like -S8192 if you experience 3proxy
|
||||
crashes.
|
||||
.SH CLIENTS
|
||||
You should use client with SOCKS support or use some socksification support
|
||||
(for example
|
||||
.I SocksCAP
|
||||
or
|
||||
.IR FreeCAP ).
|
||||
Configure client to use
|
||||
.I internal_ip
|
||||
and
|
||||
.IR port .
|
||||
SOCKS allows to use almost any application protocol without limitation. This
|
||||
implementation also allows to open priviledged port on server (if socks has
|
||||
sufficient privileges). If you need to control access use
|
||||
.BR 3proxy (8)
|
||||
instead.
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy(8), proxy(8), ftppr(8), pop3p(8), tcppm(8), udppm(8), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
73
man/tcppm.8
73
man/tcppm.8
@ -1,73 +0,0 @@
|
||||
.TH tcppm "8" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B tcppm
|
||||
\- TCP port mapper
|
||||
.SH SYNOPSIS
|
||||
.BR "tcppm " [ -d ]
|
||||
.IB \fR[ -l \fR[ \fR[ @ \fR] logfile \fR]]
|
||||
.IB \fR[ -i internal_ip\fR]
|
||||
.IB \fR[ -e external_ip\fR]
|
||||
.I local_port remote_host remote_port
|
||||
.SH DESCRIPTION
|
||||
.B tcppm
|
||||
forwards connections from local to remote TCP port
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -I
|
||||
Inetd mode. Standalone service only.
|
||||
.TP
|
||||
.B -d
|
||||
Daemonise. Detach service from console and run in the background.
|
||||
.TP
|
||||
.B -t
|
||||
Be silenT. Do not log start/stop/accept error records.
|
||||
.TP
|
||||
.B -e
|
||||
External address. IP address of interface proxy should initiate connections
|
||||
from.
|
||||
By default system will deside which address to use in accordance
|
||||
with routing table.
|
||||
.TP
|
||||
.B -i
|
||||
Internal address. IP address proxy accepts connections to.
|
||||
By default connection to any interface is accepted. It\'s usually unsafe.
|
||||
.TP
|
||||
.B -l
|
||||
Log. By default logging is to stdout. If
|
||||
.I logfile
|
||||
is specified logging is to file. Under Unix, if
|
||||
.RI \' @ \'
|
||||
preceeds
|
||||
.IR logfile ,
|
||||
syslog is used for logging.
|
||||
.TP
|
||||
.B -S
|
||||
Increase or decrease stack size. You may want to try something like -S8192 if you experience 3proxy
|
||||
crashes.
|
||||
.SH ARGUMENTS
|
||||
.TP
|
||||
.I local_port
|
||||
- port tcppm accepts connection
|
||||
.TP
|
||||
.I remote_host
|
||||
- IP address of the host connection is forwarded to
|
||||
.TP
|
||||
.I remote_port
|
||||
- remote port connection is forwarded to
|
||||
.SH CLIENTS
|
||||
Any TCP based application can be used as a client. Use
|
||||
.I internal_ip
|
||||
and
|
||||
.I local_port
|
||||
as a destination in client application. Connection is forwarded to
|
||||
.IR remote_host : remote_port
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy(8), proxy(8), ftppr(8), socks(8), pop3p(8), udppm(8), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
79
man/udppm.8
79
man/udppm.8
@ -1,79 +0,0 @@
|
||||
.TH udppm "8" "January 2016" "3proxy 0.8" "Universal proxy server"
|
||||
.SH NAME
|
||||
.B udppm
|
||||
\- UDP port mapper
|
||||
.SH SYNOPSIS
|
||||
.BR "pop3p " [ -ds ]
|
||||
.IB \fR[ -l \fR[ \fR[ @ \fR] logfile \fR]]
|
||||
.IB \fR[ -i internal_ip\fR]
|
||||
.IB \fR[ -e external_ip\fR]
|
||||
.I local_port remote_host remote_port
|
||||
.SH DESCRIPTION
|
||||
.B udppm
|
||||
forwards datagrams from local to remote UDP port
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B -I
|
||||
Inetd mode. Standalone service only.
|
||||
.TP
|
||||
.B -d
|
||||
Daemonise. Detach service from console and run in the background.
|
||||
.TP
|
||||
.B -t
|
||||
Be silenT. Do not log start/stop/accept error records.
|
||||
.TP
|
||||
.B -e
|
||||
External address. IP address of interface proxy should initiate datagrams
|
||||
from.
|
||||
By default system will deside which address to use in accordance
|
||||
with routing table.
|
||||
.TP
|
||||
.B -i
|
||||
Internal address. IP address proxy accepts datagrams to.
|
||||
By default connection to any interface is accepted. It\'s usually unsafe.
|
||||
.TP
|
||||
.B -l
|
||||
Log. By default logging is to stdout. If
|
||||
.I logfile
|
||||
is specified logging is to file. Under Unix, if
|
||||
.RI \' @ \'
|
||||
preceeds
|
||||
.IR logfile ,
|
||||
syslog is used for logging.
|
||||
.TP
|
||||
.B -s
|
||||
Single packet. By default only one client can use udppm service, but
|
||||
if -s is specified only one packet will be forwarded between client and server.
|
||||
It allows to share service between multiple clients for single packet services
|
||||
(for example name lookups).
|
||||
.TP
|
||||
.B -S
|
||||
Increase or decrease stack size. You may want to try something like -S8192 if you experience 3proxy
|
||||
crashes.
|
||||
.SH ARGUMENTS
|
||||
.TP
|
||||
.I local_port
|
||||
- port udppm accepts datagrams
|
||||
.TP
|
||||
.I remote_host
|
||||
- IP address of the host datagrams are forwarded to
|
||||
.TP
|
||||
.I remote_port
|
||||
- remote port datagrams are forwarded to
|
||||
.SH CLIENTS
|
||||
Any UDP based application can be used as a client. Use
|
||||
.I internal_ip
|
||||
and
|
||||
.I local_port
|
||||
as a destination in client application. All datagrams are forwarded to
|
||||
.IR remote_host : remote_port
|
||||
.SH BUGS
|
||||
Report all bugs to
|
||||
.BR 3proxy@3proxy.ru
|
||||
.SH SEE ALSO
|
||||
3proxy(8), proxy(8), ftppr(8), socks(8), pop3p(8), udppm(8), syslogd(8),
|
||||
.br
|
||||
http://3proxy.ru/
|
||||
.SH AUTHORS
|
||||
3proxy is designed by Vladimir 3APA3A Dubrovin
|
||||
.RI ( 3proxy@3proxy.ru )
|
@ -1,32 +0,0 @@
|
||||
#!/usr/local/etc/3proxy/bin/3proxy
|
||||
daemon
|
||||
pidfile /usr/local/etc/3proxy/3proxy.pid
|
||||
nscache 65536
|
||||
nserver 127.0.0.1
|
||||
|
||||
config /usr/local/etc/3proxy/3proxy.cfg
|
||||
monitor /usr/local/etc/3proxy/3proxy.cfg
|
||||
monitor /usr/local/etc/3proxy/counters
|
||||
monitor /usr/local/etc/3proxy/passwd
|
||||
monitor /usr/local/etc/3proxy/bandlimiters
|
||||
|
||||
log /usr/local/etc/3proxy/log/log D
|
||||
rotate 60
|
||||
counter /usr/local/etc/3proxy/3proxy.3cf
|
||||
|
||||
users $/usr/local/etc/3proxy/passwd
|
||||
|
||||
include /usr/local/etc/3proxy/counters
|
||||
include /usr/local/etc/3proxy/bandlimiters
|
||||
|
||||
auth strong
|
||||
deny * * 127.0.0.1
|
||||
allow *
|
||||
proxy -n
|
||||
socks
|
||||
flush
|
||||
allow admin
|
||||
|
||||
admin -p8080
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
if [ $4 ]; then
|
||||
echo $1:`/usr/local/etc/3proxy/bin/mycrypt $$ $2` >> /usr/local/etc/3proxy/passwd
|
||||
echo countin \"`wc -l /usr/local/etc/3proxy/counters|awk '{print $1}'`/$1\" D $3 $1 >> /usr/local/etc/3proxy/counters
|
||||
echo bandlimin $4 $1 >> /usr/local/etc/3proxy/bandlimiters
|
||||
else
|
||||
echo usage: $0 username password day_limit bandwidth
|
||||
echo " "day_limit - traffic limit in MB per day
|
||||
echo " "bandwidth - bandwith in bits per second 1048576 = 1Mbps
|
||||
fi
|
@ -1,21 +0,0 @@
|
||||
#!/bin/sh
|
||||
cd ..
|
||||
cp Makefile.unix Makefile
|
||||
make
|
||||
if [ ! -d /usr/local/etc/3proxy/bin ]; then mkdir -p /usr/local/etc/3proxy/bin/; fi
|
||||
install src/3proxy /usr/local/etc/3proxy/bin/3proxy
|
||||
install src/mycrypt /usr/local/etc/3proxy/bin/mycrypt
|
||||
install scripts/rc.d/proxy.sh /usr/local/etc/rc.d/proxy.sh
|
||||
install scripts/add3proxyuser.sh /usr/local/etc/3proxy/bin/
|
||||
if [ -s /usr/local/etc/3proxy/3proxy.cfg ]; then
|
||||
echo /usr/local/etc/3proxy/3proxy.cfg already exists
|
||||
else
|
||||
install scripts/3proxy.cfg /usr/local/etc/3proxy/
|
||||
if [ ! -d /var/log/3proxy/ ]; then
|
||||
mkdir /var/log/3proxy/
|
||||
fi
|
||||
touch /usr/local/etc/3proxy/passwd
|
||||
touch /usr/local/etc/3proxy/counters
|
||||
touch /usr/local/etc/3proxy/bandlimiters
|
||||
echo Run /usr/local/etc/3proxy/bin/add3proxyuser.sh to add \'admin\' user
|
||||
fi
|
@ -1,48 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# chkconfig: 2345 20 80
|
||||
# description: 3proxy tiny proxy server
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo Starting 3Proxy
|
||||
|
||||
/usr/local/etc/3proxy/bin/3proxy /usr/local/etc/3proxy/3proxy.cfg
|
||||
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL ]
|
||||
;;
|
||||
|
||||
stop)
|
||||
echo Stopping 3Proxy
|
||||
if [ /usr/local/etc/3proxy/3proxy.pid ]; then
|
||||
/bin/kill `cat /usr/local/etc/3proxy/3proxy.pid`
|
||||
else
|
||||
/usr/bin/killall 3proxy
|
||||
fi
|
||||
|
||||
RETVAL=$?
|
||||
echo
|
||||
[ $RETVAL ]
|
||||
;;
|
||||
|
||||
restart|reload)
|
||||
echo Reloading 3Proxy
|
||||
if [ /usr/local/etc/3proxy/3proxy.pid ]; then
|
||||
/bin/kill -s USR1 `cat /usr/local/etc/3proxy/3proxy.pid`
|
||||
else
|
||||
/usr/bin/killall -s USR1 3proxy
|
||||
fi
|
||||
;;
|
||||
|
||||
|
||||
*)
|
||||
echo Usage: $0 "{start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
exit 0
|
561
src/3proxy.c
561
src/3proxy.c
@ -1,561 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
|
||||
#include "proxy.h"
|
||||
#ifndef _WIN32
|
||||
#include <sys/resource.h>
|
||||
#ifndef NOPLUGINS
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULTCONFIG
|
||||
#define DEFAULTCONFIG conf.stringtable[25]
|
||||
#endif
|
||||
|
||||
FILE * confopen();
|
||||
extern unsigned char *strings[];
|
||||
extern FILE *writable;
|
||||
extern struct counter_header cheader;
|
||||
extern struct counter_record crecord;
|
||||
|
||||
|
||||
|
||||
time_t basetime = 0;
|
||||
|
||||
void doschedule(void);
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
OSVERSIONINFO osv;
|
||||
int service = 0;
|
||||
|
||||
void cyclestep(void);
|
||||
#ifndef _WINCE
|
||||
SERVICE_STATUS_HANDLE hSrv;
|
||||
DWORD dwCurrState;
|
||||
int SetStatus( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
|
||||
{
|
||||
SERVICE_STATUS srvStatus;
|
||||
srvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||
srvStatus.dwCurrentState = dwCurrState = dwState;
|
||||
srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
|
||||
srvStatus.dwWin32ExitCode = dwExitCode;
|
||||
srvStatus.dwServiceSpecificExitCode = 0;
|
||||
srvStatus.dwCheckPoint = dwProgress;
|
||||
srvStatus.dwWaitHint = 3000;
|
||||
return SetServiceStatus( hSrv, &srvStatus );
|
||||
}
|
||||
|
||||
void __stdcall CommandHandler( DWORD dwCommand )
|
||||
{
|
||||
switch( dwCommand )
|
||||
{
|
||||
case SERVICE_CONTROL_STOP:
|
||||
case SERVICE_CONTROL_SHUTDOWN:
|
||||
SetStatus( SERVICE_STOP_PENDING, 0, 1 );
|
||||
conf.timetoexit = 1;
|
||||
conf.paused++;
|
||||
Sleep(2000);
|
||||
SetStatus( SERVICE_STOPPED, 0, 0 );
|
||||
#ifndef NOODBC
|
||||
pthread_mutex_lock(&log_mutex);
|
||||
close_sql();
|
||||
pthread_mutex_unlock(&log_mutex);
|
||||
#endif
|
||||
break;
|
||||
case SERVICE_CONTROL_PAUSE:
|
||||
SetStatus( SERVICE_PAUSE_PENDING, 0, 1 );
|
||||
conf.paused++;
|
||||
SetStatus( SERVICE_PAUSED, 0, 0 );
|
||||
break;
|
||||
case SERVICE_CONTROL_CONTINUE:
|
||||
SetStatus( SERVICE_CONTINUE_PENDING, 0, 1 );
|
||||
conf.needreload = 1;
|
||||
SetStatus( SERVICE_RUNNING, 0, 0 );
|
||||
break;
|
||||
default: ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void __stdcall ServiceMain(int argc, unsigned char* argv[] )
|
||||
{
|
||||
|
||||
hSrv = RegisterServiceCtrlHandler((LPCSTR)conf.stringtable[1], (LPHANDLER_FUNCTION)CommandHandler);
|
||||
if( hSrv == 0 ) return;
|
||||
|
||||
SetStatus( SERVICE_START_PENDING, 0, 1 );
|
||||
SetStatus( SERVICE_RUNNING, 0, 0 );
|
||||
cyclestep();
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
|
||||
void mysigusr1 (int sig){
|
||||
conf.needreload = 1;
|
||||
}
|
||||
|
||||
int even = 0;
|
||||
|
||||
void mysigpause (int sig){
|
||||
|
||||
conf.paused++;
|
||||
even = !even;
|
||||
if(!even){
|
||||
conf.needreload = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void mysigterm (int sig){
|
||||
conf.paused++;
|
||||
usleep(999*SLEEPTIME);
|
||||
usleep(999*SLEEPTIME);
|
||||
#ifndef NOODBC
|
||||
pthread_mutex_lock(&log_mutex);
|
||||
close_sql();
|
||||
pthread_mutex_unlock(&log_mutex);
|
||||
#endif
|
||||
conf.timetoexit = 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void dumpmem(void);
|
||||
|
||||
struct schedule *schedule;
|
||||
|
||||
|
||||
int wday = 0;
|
||||
|
||||
int timechanged (time_t oldtime, time_t newtime, ROTATION lt){
|
||||
struct tm tmold;
|
||||
struct tm *tm;
|
||||
tm = localtime(&oldtime);
|
||||
tmold = *tm;
|
||||
tm = localtime(&newtime);
|
||||
switch(lt){
|
||||
case MINUTELY:
|
||||
if(tm->tm_min != tmold.tm_min)return 1;
|
||||
break;
|
||||
case HOURLY:
|
||||
if(tm->tm_hour != tmold.tm_hour)return 1;
|
||||
break;
|
||||
case DAILY:
|
||||
if(tm->tm_yday != tmold.tm_yday)return 1;
|
||||
break;
|
||||
case MONTHLY:
|
||||
if(tm->tm_mon != tmold.tm_mon)return 1;
|
||||
break;
|
||||
case ANNUALLY:
|
||||
if(tm->tm_year != tmold.tm_year)return 1;
|
||||
break;
|
||||
case WEEKLY:
|
||||
if(((newtime - oldtime) > (60*60*24*7))
|
||||
|| tm->tm_wday < tmold.tm_wday
|
||||
|| (tm->tm_wday == tmold.tm_wday && (newtime - oldtime) > (60*60*24*6))
|
||||
)return 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void doschedule(void){
|
||||
struct schedule *sched, *prevsched = NULL, *nextsched;
|
||||
int res;
|
||||
|
||||
conf.time = time(0);
|
||||
for(sched=schedule; sched; sched=sched->next){
|
||||
if(conf.needreload || conf.timetoexit || (conf.time > sched->start_time && timechanged(sched->start_time, conf.time, sched->type))){
|
||||
sched->start_time = conf.time;
|
||||
nextsched = sched->next;
|
||||
res = (*sched->function)(sched->data);
|
||||
switch(res){
|
||||
case 1:
|
||||
if(prevsched) prevsched->next = nextsched;
|
||||
else schedule = nextsched;
|
||||
break;
|
||||
}
|
||||
}
|
||||
prevsched = sched;
|
||||
}
|
||||
}
|
||||
|
||||
void dumpcounters(struct trafcount *tlin, int counterd){
|
||||
|
||||
unsigned char tmpbuf[8192];
|
||||
struct trafcount *tl;
|
||||
if(counterd >= 0 && tlin) {
|
||||
|
||||
conf.time = time(0);
|
||||
if(cheader.updated && conf.countertype && timechanged(cheader.updated, conf.time, conf.countertype)){
|
||||
FILE * cfp;
|
||||
|
||||
cfp = fopen((char *)dologname(tmpbuf, (unsigned char *)conf.counterfile, NULL, conf.countertype, cheader.updated), "w");
|
||||
if(cfp){
|
||||
for(tl = tlin; cfp && tl; tl = tl->next){
|
||||
if(tl->type >= conf.countertype)
|
||||
fprintf(cfp, "%05d %020"PRINTF_INT64_MODIFIER"u%s%s\n", tl->number, tl->traf64, tl->comment?" #" : "", tl->comment? tl->comment : "");
|
||||
}
|
||||
fclose(cfp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cheader.updated = conf.time;
|
||||
lseek(counterd, 0, SEEK_SET);
|
||||
write(counterd, &cheader, sizeof(struct counter_header));
|
||||
for(tl=tlin; tl; tl = tl->next){
|
||||
if(tl->number){
|
||||
lseek(counterd,
|
||||
sizeof(struct counter_header) + (tl->number - 1) * sizeof(struct counter_record),
|
||||
SEEK_SET);
|
||||
crecord.traf64 = tl->traf64;
|
||||
crecord.cleared = tl->cleared;
|
||||
crecord.updated = tl->updated;
|
||||
write(counterd, &crecord, sizeof(struct counter_record));
|
||||
}
|
||||
if(tl->type!=NEVER && timechanged(tl->cleared, conf.time, tl->type)){
|
||||
tl->cleared = conf.time;
|
||||
tl->traf64 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cyclestep(void){
|
||||
struct tm *tm;
|
||||
time_t minutecounter;
|
||||
unsigned char tmpbuf[8192];
|
||||
|
||||
minutecounter = time(0);
|
||||
for(;;){
|
||||
usleep(SLEEPTIME*999);
|
||||
|
||||
conf.time = time(0);
|
||||
if(conf.needreload) {
|
||||
doschedule();
|
||||
reload();
|
||||
conf.needreload = 0;
|
||||
}
|
||||
doschedule();
|
||||
if(conf.stdlog)fflush(conf.stdlog);
|
||||
if(timechanged(minutecounter, conf.time, MINUTELY)) {
|
||||
struct filemon *fm;
|
||||
struct stat sb;
|
||||
|
||||
for(fm=conf.fmon; fm; fm=fm->next){
|
||||
if(!stat(fm->path, &sb)){
|
||||
if(fm->sb.st_mtime != sb.st_mtime || fm->sb.st_size != sb.st_size){
|
||||
stat(fm->path, &fm->sb);
|
||||
conf.needreload = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(timechanged(basetime, conf.time, DAILY)) {
|
||||
tm = localtime(&conf.time);
|
||||
wday = (1 << tm->tm_wday);
|
||||
tm->tm_hour = tm->tm_min = tm->tm_sec = 0;
|
||||
basetime = mktime(tm);
|
||||
}
|
||||
if(conf.logname) {
|
||||
if(timechanged(conf.logtime, conf.time, conf.logtype)) {
|
||||
FILE *fp;
|
||||
fp = fopen((char *)dologname (tmpbuf, conf.logname, NULL, conf.logtype, conf.time), "a");
|
||||
if (fp) {
|
||||
pthread_mutex_lock(&log_mutex);
|
||||
fclose(conf.stdlog);
|
||||
conf.stdlog = fp;
|
||||
pthread_mutex_unlock(&log_mutex);
|
||||
}
|
||||
fseek(stdout, 0L, SEEK_END);
|
||||
usleep(SLEEPTIME);
|
||||
conf.logtime = conf.time;
|
||||
if(conf.logtype != NONE && conf.rotate) {
|
||||
int t;
|
||||
t = 1;
|
||||
switch(conf.logtype){
|
||||
case ANNUALLY:
|
||||
t = t * 12;
|
||||
case MONTHLY:
|
||||
t = t * 4;
|
||||
case WEEKLY:
|
||||
t = t * 7;
|
||||
case DAILY:
|
||||
t = t * 24;
|
||||
case HOURLY:
|
||||
t = t * 60;
|
||||
case MINUTELY:
|
||||
t = t * 60;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
dologname (tmpbuf, conf.logname, (conf.archiver)?conf.archiver[1]:NULL, conf.logtype, (conf.logtime - t * conf.rotate));
|
||||
remove ((char *) tmpbuf);
|
||||
if(conf.archiver) {
|
||||
int i;
|
||||
*tmpbuf = 0;
|
||||
for(i = 2; i < conf.archiverc && strlen((char *)tmpbuf) < 512; i++){
|
||||
strcat((char *)tmpbuf, " ");
|
||||
if(!strcmp((char *)conf.archiver[i], "%A")){
|
||||
strcat((char *)tmpbuf, "\"");
|
||||
dologname (tmpbuf + strlen((char *)tmpbuf), conf.logname, conf.archiver[1], conf.logtype, (conf.logtime - t));
|
||||
strcat((char *)tmpbuf, "\"");
|
||||
}
|
||||
else if(!strcmp((char *)conf.archiver[i], "%F")){
|
||||
strcat((char *)tmpbuf, "\"");
|
||||
dologname (tmpbuf+strlen((char *)tmpbuf), conf.logname, NULL, conf.logtype, (conf.logtime-t));
|
||||
strcat((char *)tmpbuf, "\"");
|
||||
}
|
||||
else
|
||||
strcat((char *)tmpbuf, (char *)conf.archiver[i]);
|
||||
}
|
||||
system((char *)tmpbuf+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(conf.counterd >= 0 && conf.trafcounter) {
|
||||
if(timechanged(cheader.updated, conf.time, MINUTELY)){
|
||||
dumpcounters(conf.trafcounter, conf.counterd);
|
||||
}
|
||||
}
|
||||
if(conf.timetoexit){
|
||||
conf.paused++;
|
||||
doschedule();
|
||||
usleep(SLEEPTIME*999);
|
||||
usleep(SLEEPTIME*999);
|
||||
usleep(SLEEPTIME*999);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define RETURN(x) {res = x; goto CLEARRETURN;}
|
||||
|
||||
|
||||
|
||||
#ifndef _WINCE
|
||||
int main(int argc, char * argv[]) {
|
||||
#else
|
||||
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow){
|
||||
int argc;
|
||||
char ** argv;
|
||||
WNDCLASS wc;
|
||||
HWND hwnd = 0;
|
||||
#endif
|
||||
|
||||
int res = 0;
|
||||
FILE * fp = NULL;
|
||||
|
||||
#ifdef _WIN32
|
||||
unsigned char * arg;
|
||||
WSADATA wd;
|
||||
unsigned char tmpbuf[8192];
|
||||
|
||||
WSAStartup(MAKEWORD( 1, 1 ), &wd);
|
||||
osv.dwOSVersionInfoSize = sizeof(osv);
|
||||
GetVersionEx(&osv);
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _WINCE
|
||||
argc = ceparseargs((char *)lpCmdLine);
|
||||
argv = ceargv;
|
||||
if(FindWindow(L"3proxy", L"3proxy")) return 0;
|
||||
ZeroMemory(&wc,sizeof(wc));
|
||||
wc.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
|
||||
wc.hInstance=hInstance;
|
||||
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
|
||||
wc.lpfnWndProc=DefWindowProc;
|
||||
wc.style=CS_HREDRAW|CS_VREDRAW;
|
||||
wc.lpszClassName=L"3proxy";
|
||||
RegisterClass(&wc);
|
||||
|
||||
hwnd = CreateWindowEx(0,L"3proxy",L"3proxy",WS_VISIBLE|WS_POPUP,0,0,0,0,0,0,hInstance,0);
|
||||
#endif
|
||||
|
||||
conf.stringtable = strings;
|
||||
#ifdef _WIN32
|
||||
#ifndef _WINCE
|
||||
if((argc == 2 || argc == 3)&& !strcmp((char *)argv[1], "--install")) {
|
||||
|
||||
sprintf((char *)tmpbuf, "%s will be installed and started.\n"
|
||||
"By clicking Yes you confirm you read and accepted License Agreement.\n"
|
||||
"You can use Administration/Services to control %s service.",
|
||||
conf.stringtable[1], conf.stringtable[2]);
|
||||
if(MessageBox(NULL, (LPCSTR)tmpbuf, (LPCSTR)conf.stringtable[2], MB_YESNO|MB_ICONASTERISK) != IDYES) return 1;
|
||||
|
||||
|
||||
*tmpbuf = '\"';
|
||||
if (!(res = SearchPath(NULL, argv[0], ".exe", 256, (char *)tmpbuf+1, (LPTSTR*)&arg))) {
|
||||
perror("Failed to find executable filename");
|
||||
RETURN(102);
|
||||
}
|
||||
strcat((char *)tmpbuf, "\" \"");
|
||||
if(!(res = GetFullPathName ((argc == 3)?argv[2]:(char*)DEFAULTCONFIG, 256, (char *)tmpbuf+res+4, (char **)&arg))){
|
||||
perror("Failed to find config filename");
|
||||
RETURN(103);
|
||||
}
|
||||
strcat((char *)tmpbuf, "\" --service");
|
||||
if(osv.dwPlatformId == VER_PLATFORM_WIN32_NT){
|
||||
SC_HANDLE sch;
|
||||
|
||||
if(!(sch = OpenSCManager(NULL, NULL, GENERIC_WRITE|SERVICE_START ))){
|
||||
perror("Failed to open Service Manager");
|
||||
RETURN(101);
|
||||
}
|
||||
if (!(sch = CreateService(sch, (LPCSTR)conf.stringtable[1], (LPCSTR)conf.stringtable[2], GENERIC_EXECUTE, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, (char *)tmpbuf, NULL, NULL, NULL, NULL, NULL))){
|
||||
perror("Failed to create service");
|
||||
RETURN(103);
|
||||
}
|
||||
if (!StartService(sch, 0, NULL)) {
|
||||
perror("Failed to start service");
|
||||
RETURN(103);
|
||||
}
|
||||
}
|
||||
else {
|
||||
HKEY runsrv;
|
||||
|
||||
if(RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
|
||||
0,
|
||||
KEY_ALL_ACCESS,
|
||||
&runsrv) != ERROR_SUCCESS){
|
||||
perror("Failed to open registry");
|
||||
RETURN(104);
|
||||
}
|
||||
if(RegSetValueEx( runsrv,
|
||||
(LPCSTR)conf.stringtable[1],
|
||||
0,
|
||||
REG_EXPAND_SZ,
|
||||
(BYTE *)tmpbuf,
|
||||
(int)strlen((char *)tmpbuf)+1)!=ERROR_SUCCESS){
|
||||
perror("Failed to set registry value");
|
||||
RETURN(105);
|
||||
}
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if((argc == 2 || argc == 3)&& !strcmp((char *)argv[1], "--remove")) {
|
||||
|
||||
if(osv.dwPlatformId == VER_PLATFORM_WIN32_NT){
|
||||
SC_HANDLE sch;
|
||||
|
||||
if(!(sch = OpenSCManager(NULL, NULL, GENERIC_WRITE))){
|
||||
perror("Failed to open Service Manager\n");
|
||||
RETURN(106);
|
||||
}
|
||||
if (!(sch = OpenService(sch, (LPCSTR)conf.stringtable[1], DELETE))){
|
||||
perror("Failed to open service");
|
||||
RETURN(107);
|
||||
}
|
||||
if (!DeleteService(sch)){
|
||||
perror("Failed to delete service");
|
||||
RETURN(108);
|
||||
}
|
||||
}
|
||||
else {
|
||||
HKEY runsrv;
|
||||
if(RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||||
"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
|
||||
0,
|
||||
KEY_ALL_ACCESS,
|
||||
&runsrv) != ERROR_SUCCESS){
|
||||
perror("Failed to open registry");
|
||||
RETURN(109);
|
||||
}
|
||||
if(RegDeleteValue(runsrv, (LPCSTR)conf.stringtable[1]) != ERROR_SUCCESS){
|
||||
perror("Failed to clear registry");
|
||||
RETURN(110);
|
||||
}
|
||||
}
|
||||
RETURN(0);
|
||||
}
|
||||
if(argc==3 && !strcmp(argv[2], "--service")){
|
||||
service = 1;
|
||||
argc = 2;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
conf.conffile = mystrdup((argc==2)?argv[1]:(char*)DEFAULTCONFIG);
|
||||
if(conf.conffile && *conf.conffile != '-') {
|
||||
fp = confopen();
|
||||
#ifndef _WIN32
|
||||
if(!fp) fp = stdin;
|
||||
#endif
|
||||
}
|
||||
if(argc > 2 || !(fp)) {
|
||||
|
||||
fprintf(stderr, "Usage: %s [conffile]\n", argv[0]);
|
||||
#ifdef _WIN32
|
||||
fprintf(stderr, "\n\t%s --install [conffile]\n\tto install as service\n"
|
||||
"\n\t%s --remove\n\tto remove service\n", argv[0], argv[0]);
|
||||
#else
|
||||
fprintf(stderr, "\n if conffile is missing, configuration is expected from stdin\n");
|
||||
#endif
|
||||
fprintf(stderr, "\n%s %s\n%s\n", conf.stringtable[2], conf.stringtable[3], copyright);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
pthread_mutex_init(&config_mutex, NULL);
|
||||
pthread_mutex_init(&bandlim_mutex, NULL);
|
||||
pthread_mutex_init(&hash_mutex, NULL);
|
||||
pthread_mutex_init(&tc_mutex, NULL);
|
||||
pthread_mutex_init(&pwl_mutex, NULL);
|
||||
pthread_mutex_init(&log_mutex, NULL);
|
||||
|
||||
freeconf(&conf);
|
||||
res = readconfig(fp);
|
||||
conf.version++;
|
||||
|
||||
if(res) RETURN(res);
|
||||
if(!writable)fclose(fp);
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef _WINCE
|
||||
if(service){
|
||||
SERVICE_TABLE_ENTRY ste[] =
|
||||
{
|
||||
{ (LPSTR)conf.stringtable[1], (LPSERVICE_MAIN_FUNCTION)ServiceMain},
|
||||
{ NULL, NULL }
|
||||
};
|
||||
if(!StartServiceCtrlDispatcher( ste ))cyclestep();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
cyclestep();
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
signal(SIGCONT, mysigpause);
|
||||
signal(SIGTERM, mysigterm);
|
||||
signal(SIGUSR1, mysigusr1);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
cyclestep();
|
||||
|
||||
#endif
|
||||
|
||||
CLEARRETURN:
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
126
src/Makefile.inc
126
src/Makefile.inc
@ -2,7 +2,7 @@
|
||||
# 3 proxy common Makefile
|
||||
#
|
||||
|
||||
all: $(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
|
||||
all: $(BUILDDIR)proxy$(EXESUFFICS)
|
||||
|
||||
|
||||
sockmap$(OBJSUFFICS): sockmap.c proxy.h structures.h
|
||||
@ -14,149 +14,25 @@ common$(OBJSUFFICS): common.c proxy.h structures.h
|
||||
myalloc$(OBJSUFFICS): myalloc.c proxy.h structures.h
|
||||
$(CC) $(CFLAGS) myalloc.c
|
||||
|
||||
plugins$(OBJSUFFICS): plugins.c proxy.h structures.h
|
||||
$(CC) $(CFLAGS) plugins.c
|
||||
|
||||
base64$(OBJSUFFICS): base64.c
|
||||
$(CC) $(CFLAGS) base64.c
|
||||
|
||||
ftp$(OBJSUFFICS): ftp.c proxy.h structures.h
|
||||
$(CC) $(CFLAGS) ftp.c
|
||||
|
||||
#$(COMPATLIBS):
|
||||
# $(CC) $(CFLAGS) strncasecmp.c
|
||||
|
||||
sockgetchar$(OBJSUFFICS): sockgetchar.c proxy.h structures.h
|
||||
$(CC) $(CFLAGS) sockgetchar.c
|
||||
|
||||
proxy$(OBJSUFFICS): proxy.c proxy.h structures.h proxymain.c
|
||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP $(DEFINEOPTION)ANONYMOUS proxy.c
|
||||
|
||||
pop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h proxymain.c
|
||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP pop3p.c
|
||||
|
||||
smtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h proxymain.c
|
||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP smtpp.c
|
||||
|
||||
ftppr$(OBJSUFFICS): ftppr.c proxy.h structures.h proxymain.c
|
||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP ftppr.c
|
||||
|
||||
tcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h proxymain.c
|
||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP tcppm.c
|
||||
|
||||
icqpr$(OBJSUFFICS): icqpr.c proxy.h structures.h proxymain.c
|
||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP icqpr.c
|
||||
|
||||
socks$(OBJSUFFICS): socks.c proxy.h structures.h proxymain.c
|
||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP socks.c
|
||||
|
||||
udppm$(OBJSUFFICS): udppm.c proxy.h structures.h proxymain.c
|
||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)PORTMAP udppm.c
|
||||
|
||||
3proxy$(OBJSUFFICS): 3proxy.c proxy.h structures.h
|
||||
$(CC) $(CFLAGS) 3proxy.c
|
||||
|
||||
$(BUILDDIR)proxy$(EXESUFFICS): sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)proxy$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||
|
||||
$(BUILDDIR)pop3p$(EXESUFFICS): sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)pop3p$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||
|
||||
$(BUILDDIR)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)smtpp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) base64$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||
|
||||
$(BUILDDIR)ftppr$(EXESUFFICS): sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) ftp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)ftppr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||
|
||||
$(BUILDDIR)socks$(EXESUFFICS): sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)socks$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
|
||||
|
||||
$(BUILDDIR)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)tcppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
|
||||
|
||||
$(BUILDDIR)icqpr$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) icqpr$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)icqpr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) icqpr$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
|
||||
|
||||
$(BUILDDIR)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)udppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
|
||||
|
||||
mainfunc$(OBJSUFFICS): proxy.h structures.h proxymain.c
|
||||
$(CC) $(COUT)mainfunc$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)MODULEMAINFUNC=mainfunc proxymain.c
|
||||
|
||||
|
||||
|
||||
srvproxy$(OBJSUFFICS): proxy.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvproxy$(OBJSUFFICS) $(CFLAGS) proxy.c
|
||||
|
||||
srvpop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvpop3p$(OBJSUFFICS) $(CFLAGS) pop3p.c
|
||||
|
||||
srvsmtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvsmtpp$(OBJSUFFICS) $(CFLAGS) smtpp.c
|
||||
|
||||
srvftppr$(OBJSUFFICS): ftppr.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvftppr$(OBJSUFFICS) $(CFLAGS) ftppr.c
|
||||
|
||||
srvtcppm$(OBJSUFFICS): tcppm.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvtcppm$(OBJSUFFICS) $(CFLAGS) tcppm.c
|
||||
|
||||
srvicqpr$(OBJSUFFICS): icqpr.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvicqpr$(OBJSUFFICS) $(CFLAGS) icqpr.c
|
||||
|
||||
srvsocks$(OBJSUFFICS): socks.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvsocks$(OBJSUFFICS) $(CFLAGS) socks.c
|
||||
|
||||
srvwebadmin$(OBJSUFFICS): webadmin.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvwebadmin$(OBJSUFFICS) $(CFLAGS) webadmin.c
|
||||
|
||||
srvudppm$(OBJSUFFICS): udppm.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvudppm$(OBJSUFFICS) $(CFLAGS) udppm.c
|
||||
|
||||
srvdnspr$(OBJSUFFICS): dnspr.c proxy.h structures.h
|
||||
$(CC) $(COUT)srvdnspr$(OBJSUFFICS) $(CFLAGS) dnspr.c
|
||||
|
||||
auth$(OBJSUFFICS): auth.c proxy.h structures.h
|
||||
$(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
|
||||
$(CC) $(COUT)datatypes$(OBJSUFFICS) $(CFLAGS) datatypes.c
|
||||
|
||||
mycrypt$(OBJSUFFICS): mycrypt.c
|
||||
$(CC) $(COUT)mycrypt$(OBJSUFFICS) $(CFLAGS) mycrypt.c
|
||||
|
||||
dighosts$(OBJSUFFICS): dighosts.c
|
||||
$(CC) $(COUT)dighosts$(OBJSUFFICS) $(CFLAGS) dighosts.c
|
||||
|
||||
$(BUILDDIR)dighosts$(EXESUFFICS): dighosts$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)dighosts$(EXESUFFICS) $(LDFLAGS) dighosts$(OBJSUFFICS) myalloc$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||
|
||||
mycryptmain$(OBJSUFFICS): mycrypt.c
|
||||
$(CC) $(COUT)mycryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN mycrypt.c
|
||||
|
||||
$(BUILDDIR)mycrypt$(EXESUFFICS): md4$(OBJSUFFICS) md5$(OBJSUFFICS) mycryptmain$(OBJSUFFICS) base64$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)$(BUILDDIR)mycrypt$(EXESUFFICS) $(LDFLAGS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) base64$(OBJSUFFICS) mycryptmain$(OBJSUFFICS)
|
||||
|
||||
|
||||
md4$(OBJSUFFICS): libs/md4.h libs/md4.c
|
||||
$(CC) $(COUT)md4$(OBJSUFFICS) $(CFLAGS) libs/md4.c
|
||||
|
||||
smbdes$(OBJSUFFICS): libs/smbdes.c
|
||||
$(CC) $(COUT)smbdes$(OBJSUFFICS) $(CFLAGS) libs/smbdes.c
|
||||
|
||||
md5$(OBJSUFFICS): libs/md5.h libs/md5.c
|
||||
$(CC) $(COUT)md5$(OBJSUFFICS) $(CFLAGS) libs/md5.c
|
||||
|
||||
ntlm$(OBJSUFFICS): ntlm.c
|
||||
$(CC) $(COUT)ntlm$(OBJSUFFICS) $(CFLAGS) ntlm.c
|
||||
|
||||
stringtable$(OBJSUFFICS): 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) 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) 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:
|
||||
@$(REMOVECOMMAND) *$(OBJSUFFICS) $(COMPFILES)
|
||||
|
1367
src/auth.c
1367
src/auth.c
File diff suppressed because it is too large
Load Diff
1708
src/conf.c
1708
src/conf.c
File diff suppressed because it is too large
Load Diff
817
src/datatypes.c
817
src/datatypes.c
@ -1,817 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2008 3APA3A
|
||||
*
|
||||
* please read License Agreement
|
||||
*
|
||||
*/
|
||||
|
||||
#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){
|
||||
char buf[16];
|
||||
if(node->value)(*cbf)(cb, buf, sprintf(buf, "%d", *(int *)node->value));
|
||||
}
|
||||
|
||||
static void pr_short(struct node *node, CBFUNC cbf, void*cb){
|
||||
char buf[8];
|
||||
if(node->value)(*cbf)(cb, buf, sprintf(buf, "%hu", *(unsigned short*)node->value));
|
||||
}
|
||||
|
||||
static void pr_char(struct node *node, CBFUNC cbf, void*cb){
|
||||
if(node->value)(*cbf)(cb, (char *)node->value, 1);
|
||||
}
|
||||
|
||||
|
||||
static void pr_unsigned(struct node *node, CBFUNC cbf, void*cb){
|
||||
char buf[16];
|
||||
if(node->value)(*cbf)(cb, buf, sprintf(buf, "%u", *(unsigned *)node->value));
|
||||
}
|
||||
|
||||
static void pr_traffic(struct node *node, CBFUNC cbf, void*cb){
|
||||
char buf[16];
|
||||
unsigned long u1, u2;
|
||||
if(node->value){
|
||||
u1 = ((unsigned long *)node->value)[0];
|
||||
u2 = ((unsigned long *)node->value)[0];
|
||||
(*cbf)(cb, buf, sprintf(buf, "%lu", (u1>>20) + (u2<<10)));
|
||||
}
|
||||
}
|
||||
|
||||
static void pr_port(struct node *node, CBFUNC cbf, void*cb){
|
||||
char buf[8];
|
||||
if(node->value)(*cbf)(cb, buf, sprintf(buf, "%hu", ntohs(*(unsigned short*)node->value)));
|
||||
}
|
||||
|
||||
static void pr_datetime(struct node *node, CBFUNC cbf, void*cb){
|
||||
char *s;
|
||||
if(node->value){
|
||||
s = ctime((time_t *)node->value);
|
||||
|
||||
(*cbf)(cb, s, (int)strlen(s)-1);
|
||||
}
|
||||
}
|
||||
|
||||
static void pr_ip(struct node *node, CBFUNC cbf, void*cb){
|
||||
char buf[16];
|
||||
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){
|
||||
char buf[16];
|
||||
int i, found = 0;
|
||||
if(node -> value)for(i = 0; i<8; i++){
|
||||
if( (1<<i) & *(int *)node -> value ) {
|
||||
sprintf(buf, "%s%d", found?",":"", i);
|
||||
(*cbf)(cb, buf, found? 2:1);
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pr_time(struct node *node, CBFUNC cbf, void*cb){
|
||||
char buf[16];
|
||||
int t = *(int *)node;
|
||||
|
||||
(*cbf)(cb, buf, sprintf(buf, "%02d:%02d:%02d", (t/3600)%24, (t/60)%60, t%60));
|
||||
}
|
||||
|
||||
int cidrprint(char *buf, unsigned long u){
|
||||
unsigned long u1 = 0xffffffff;
|
||||
int i;
|
||||
|
||||
u = ntohl(u);
|
||||
for(i = 32; i && (u1!=u); i--){
|
||||
u1 = (u1 << 1);
|
||||
}
|
||||
if (i == 32) {
|
||||
return 0;
|
||||
}
|
||||
return sprintf(buf, "/%d", i);
|
||||
}
|
||||
|
||||
static void pr_cidr(struct node *node, CBFUNC cbf, void*cb){
|
||||
char buf[4];
|
||||
int i;
|
||||
|
||||
if(node->value){
|
||||
if ((i = cidrprint(buf, *(unsigned *)node -> value)))
|
||||
(*cbf)(cb, buf, i);
|
||||
else (*cbf)(cb, "/32", 3);
|
||||
}
|
||||
}
|
||||
|
||||
static void pr_string(struct node *node, CBFUNC cbf, void*cb){
|
||||
if(node->value){
|
||||
(*cbf)(cb, (char*)node->value, (int)strlen((char*)node->value));
|
||||
}
|
||||
else (*cbf)(cb, "(NULL)", 6);
|
||||
}
|
||||
|
||||
static void pr_rotation(struct node *node, CBFUNC cbf, void*cb){
|
||||
char * lstrings[] = {
|
||||
"N", "C", "H", "D", "W", "M", "Y", "N"
|
||||
};
|
||||
int i;
|
||||
|
||||
if(node->value && (i = *(int*)node->value) > 1 && i < 6){
|
||||
(*cbf)(cb, lstrings[i], 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void pr_operations(struct node *node, CBFUNC cbf, void*cb){
|
||||
char buf[64];
|
||||
int operation;
|
||||
int delim = 0;
|
||||
|
||||
*buf = 0;
|
||||
if(!node->value || !(operation = *(int*)node->value)){
|
||||
(*cbf)(cb, "*", 1);
|
||||
return;
|
||||
}
|
||||
if(operation & HTTP){
|
||||
if((operation & HTTP) == HTTP)
|
||||
(*cbf)(cb, buf, sprintf(buf, "HTTP"));
|
||||
else
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s%s%s%s%s%s%s%s",
|
||||
(operation & HTTP_GET)? "HTTP_GET" : "",
|
||||
((operation & HTTP_GET) && (operation & (HTTP_PUT|HTTP_POST|HTTP_HEAD|HTTP_OTHER)))? "," : "",
|
||||
(operation & HTTP_PUT)? "HTTP_PUT" : "",
|
||||
((operation & HTTP_PUT) && (operation & (HTTP_POST|HTTP_HEAD|HTTP_OTHER)))? "," : "",
|
||||
(operation & HTTP_POST)? "HTTP_POST" : "",
|
||||
((operation & HTTP_POST) && (operation & (HTTP_HEAD|HTTP_OTHER)))? "," : "",
|
||||
(operation & HTTP_HEAD)? "HTTP_HEAD" : "",
|
||||
((operation & HTTP_HEAD) && (operation & HTTP_OTHER))? "," : "",
|
||||
(operation & HTTP_OTHER)? "HTTP_OTHER" : ""));
|
||||
delim = 1;
|
||||
}
|
||||
if(operation & HTTP_CONNECT){
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s", delim?",":"", "HTTP_CONNECT"));
|
||||
delim = 1;
|
||||
}
|
||||
if(operation & FTP) {
|
||||
if((operation & FTP) == FTP)
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s", delim?",":"", "FTP"));
|
||||
else
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s%s%s%s%s",
|
||||
delim? ",":"",
|
||||
(operation & FTP_GET)? "FTP_GET" : "",
|
||||
((operation & FTP_GET) && (operation & (FTP_PUT|FTP_LIST)))? ",":"",
|
||||
(operation & FTP_PUT)? "FTP_PUT" : "",
|
||||
((operation & FTP_PUT) && (operation & FTP_LIST))? ",":"",
|
||||
(operation & FTP_LIST)? "FTP_LIST" : ""));
|
||||
delim = 1;
|
||||
}
|
||||
if(operation & CONNECT){
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s", delim?",":"", "CONNECT"));
|
||||
delim = 1;
|
||||
}
|
||||
if(operation & BIND){
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s", delim?",":"", "BIND"));
|
||||
delim = 1;
|
||||
}
|
||||
if(operation & UDPASSOC){
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s", delim?",":"", "UDPASSOC"));
|
||||
delim = 1;
|
||||
}
|
||||
if(operation & ICMPASSOC){
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s", delim?",":"", "ICMPASSOC"));
|
||||
delim = 1;
|
||||
}
|
||||
if(operation & DNSRESOLVE){
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s", delim?",":"", "DNSRESOLVE"));
|
||||
delim = 1;
|
||||
}
|
||||
if(operation & ADMIN){
|
||||
(*cbf)(cb, buf, sprintf(buf, "%s%s", delim?",":"", "ADMIN"));
|
||||
}
|
||||
}
|
||||
|
||||
static void pr_portlist(struct node *node, CBFUNC cbf, void*cb){
|
||||
struct portlist *pl= (struct portlist *)node->value;
|
||||
char buf[16];
|
||||
if(!pl) {
|
||||
(*cbf)(cb, "*", 1);
|
||||
return;
|
||||
}
|
||||
for(; pl; pl = pl->next) {
|
||||
if(pl->startport == pl->endport)
|
||||
(*cbf)(cb, buf, sprintf(buf, "%hu", pl->startport));
|
||||
else
|
||||
(*cbf)(cb, buf, sprintf(buf, "%hu-%hu", pl->startport, pl->endport));
|
||||
if(pl->next)(*cbf)(cb, ",", 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void pr_userlist(struct node *node, CBFUNC cbf, void*cb){
|
||||
struct userlist *ul= (struct userlist *)node->value;
|
||||
if(!ul) {
|
||||
(*cbf)(cb, "*", 1);
|
||||
return;
|
||||
}
|
||||
for(; ul; ul = ul->next){
|
||||
(*cbf)(cb, (char *)ul->user, (int)strlen((char *)ul->user));
|
||||
if(ul->next)(*cbf)(cb, ",", 1);
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
char buf[128];
|
||||
struct iplist *il = (struct iplist *)node->value;
|
||||
|
||||
if(!il) {
|
||||
(*cbf)(cb, "*", 1);
|
||||
return;
|
||||
}
|
||||
for(; il; il = il->next){
|
||||
(*cbf)(cb, buf, printiple(buf, il));
|
||||
}
|
||||
}
|
||||
|
||||
static void * ef_portlist_next(struct node *node){
|
||||
return (((struct portlist *)node->value) -> next);
|
||||
}
|
||||
|
||||
|
||||
static void * ef_portlist_start(struct node *node){
|
||||
return &(((struct portlist *)node->value) -> startport);
|
||||
}
|
||||
|
||||
static void * ef_portlist_end(struct node *node){
|
||||
return &(((struct portlist *)node->value) -> endport);
|
||||
}
|
||||
|
||||
static void * ef_iplist_next(struct node *node){
|
||||
return (((struct iplist *)node->value) -> next);
|
||||
}
|
||||
|
||||
static void * ef_userlist_next(struct node * node){
|
||||
return (((struct userlist *)node->value) -> next);
|
||||
}
|
||||
|
||||
static void * ef_userlist_user(struct node * node){
|
||||
return (((struct userlist *)node->value) -> user);
|
||||
}
|
||||
|
||||
static void * ef_pwlist_next(struct node * node){
|
||||
return (((struct passwords *)node->value) -> next);
|
||||
}
|
||||
|
||||
static void * ef_pwlist_user(struct node * node){
|
||||
return (((struct passwords *)node->value) -> user);
|
||||
}
|
||||
|
||||
static void * ef_pwlist_password(struct node * node){
|
||||
return (((struct passwords *)node->value) -> password);
|
||||
}
|
||||
|
||||
static void * ef_pwlist_type(struct node * node){
|
||||
switch (((struct passwords *)node->value) -> pwtype) {
|
||||
case SYS:
|
||||
return "SYS";
|
||||
case CL:
|
||||
return "CL";
|
||||
case CR:
|
||||
return "CR";
|
||||
case NT:
|
||||
return "NT";
|
||||
case LM:
|
||||
return "LM";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static void * ef_chain_next(struct node * node){
|
||||
return ((struct chain *)node->value) -> next;
|
||||
}
|
||||
|
||||
static void * ef_chain_type(struct node * node){
|
||||
switch (((struct chain *)node->value) -> type) {
|
||||
case R_TCP:
|
||||
return "tcp";
|
||||
case R_CONNECT:
|
||||
return "connect";
|
||||
case R_SOCKS4:
|
||||
return "socks4";
|
||||
case R_SOCKS5:
|
||||
return "socks5";
|
||||
case R_HTTP:
|
||||
return "http";
|
||||
case R_FTP:
|
||||
return "ftp";
|
||||
case R_POP3:
|
||||
return "pop3";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
static void * ef_chain_addr(struct node * node){
|
||||
return &((struct chain *)node->value) -> addr;
|
||||
}
|
||||
|
||||
static void * ef_chain_weight(struct node * node){
|
||||
return &((struct chain *)node->value) -> weight;
|
||||
}
|
||||
|
||||
static void * ef_chain_user(struct node * node){
|
||||
return ((struct chain *)node->value) -> extuser;
|
||||
}
|
||||
|
||||
static void * ef_chain_password(struct node * node){
|
||||
return ((struct chain *)node->value) -> extpass;
|
||||
}
|
||||
|
||||
static void * ef_ace_next(struct node * node){
|
||||
return ((struct ace *)node->value) -> next;
|
||||
}
|
||||
|
||||
static void * ef_ace_type(struct node * node){
|
||||
switch (((struct ace *)node->value) -> action) {
|
||||
case ALLOW:
|
||||
case REDIRECT:
|
||||
return "allow";
|
||||
case DENY:
|
||||
return "deny";
|
||||
case BANDLIM:
|
||||
return "bandlim";
|
||||
case NOBANDLIM:
|
||||
return "nobandlim";
|
||||
case COUNTIN:
|
||||
return "countin";
|
||||
case NOCOUNTIN:
|
||||
return "nocountin";
|
||||
case COUNTOUT:
|
||||
return "countout";
|
||||
case NOCOUNTOUT:
|
||||
return "nocountout";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void * ef_ace_operations(struct node * node){
|
||||
if(!((struct ace *)node->value) -> operation) return NULL;
|
||||
return &((struct ace *)node->value) -> operation;
|
||||
}
|
||||
|
||||
static void * ef_ace_users(struct node * node){
|
||||
return ((struct ace *)node->value) -> users;
|
||||
}
|
||||
|
||||
static void * ef_ace_src(struct node * node){
|
||||
return ((struct ace *)node->value) -> src;
|
||||
}
|
||||
|
||||
|
||||
static void * ef_ace_dst(struct node * node){
|
||||
return ((struct ace *)node->value) -> dst;
|
||||
}
|
||||
|
||||
|
||||
static void * ef_ace_ports(struct node * node){
|
||||
return ((struct ace *)node->value) -> ports;
|
||||
}
|
||||
|
||||
static void * ef_ace_chain(struct node * node){
|
||||
return ((struct ace *)node->value) -> chains;
|
||||
}
|
||||
|
||||
static void * ef_ace_weekdays(struct node * node){
|
||||
return (((struct ace *)node->value) -> wdays) ? &((struct ace *)node->value) -> wdays : NULL;
|
||||
}
|
||||
|
||||
static void * ef_ace_period(struct node * node){
|
||||
return ((struct ace *)node->value) -> periods;
|
||||
}
|
||||
|
||||
|
||||
static void * ef_bandlimit_next(struct node * node){
|
||||
return ((struct bandlim *)node->value) -> next;
|
||||
}
|
||||
|
||||
static void * ef_bandlimit_ace(struct node * node){
|
||||
return ((struct bandlim *)node->value) -> ace;
|
||||
}
|
||||
|
||||
static void * ef_bandlimit_rate(struct node * node){
|
||||
return &((struct bandlim *)node->value) -> rate;
|
||||
}
|
||||
|
||||
static void * ef_trafcounter_next(struct node * node){
|
||||
return ((struct trafcount *)node->value) -> next;
|
||||
}
|
||||
|
||||
static void * ef_trafcounter_ace(struct node * node){
|
||||
return ((struct trafcount *)node->value) -> ace;
|
||||
}
|
||||
|
||||
static void * ef_trafcounter_number(struct node * node){
|
||||
return &((struct trafcount *)node->value) -> number;
|
||||
}
|
||||
|
||||
static void * ef_trafcounter_type(struct node * node){
|
||||
return &((struct trafcount *)node->value) -> type;
|
||||
}
|
||||
|
||||
static void * ef_trafcounter_traffic64(struct node * node){
|
||||
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_client_maxtrafout64(struct node * node){
|
||||
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){
|
||||
return &((struct trafcount *)node->value) -> cleared;
|
||||
}
|
||||
|
||||
static void * ef_trafcounter_updated(struct node * node){
|
||||
return &((struct trafcount *)node->value) -> updated;
|
||||
}
|
||||
|
||||
static void * ef_trafcounter_comment(struct node * node){
|
||||
return ((struct trafcount *)node->value) -> comment;
|
||||
}
|
||||
|
||||
static void * ef_trafcounter_disabled(struct node * node){
|
||||
return &((struct trafcount *)node->value) -> disabled;
|
||||
}
|
||||
|
||||
static void * ef_server_next(struct node * node){
|
||||
return ((struct srvparam *)node->value) -> next;
|
||||
}
|
||||
|
||||
static void * ef_server_type(struct node * node){
|
||||
int service = ((struct srvparam *)node->value) -> service;
|
||||
return (service>=0 && service < 15)? (void *)conf.stringtable[SERVICES + service] : (void *)"unknown";
|
||||
}
|
||||
|
||||
static void * ef_server_child(struct node * node){
|
||||
return ((struct srvparam *)node->value) -> child;
|
||||
}
|
||||
|
||||
static void * ef_server_auth(struct node * node){
|
||||
AUTHFUNC af = ((struct srvparam *)node->value) -> authfunc;
|
||||
|
||||
if(af == alwaysauth) return "none";
|
||||
if(af == ipauth) return "iponly";
|
||||
if(af == strongauth) return "strong";
|
||||
return "uknown";
|
||||
}
|
||||
|
||||
static void * ef_server_childcount(struct node * node){
|
||||
return &((struct srvparam *)node->value) -> childcount;
|
||||
}
|
||||
|
||||
static void * ef_server_log(struct node * node){
|
||||
if(((struct srvparam *)node->value) -> logfunc == lognone) return "none";
|
||||
else if(((struct srvparam *)node->value) -> logfunc == logstdout)
|
||||
return (((struct srvparam *)node->value) -> logtarget)?"file":"stdout";
|
||||
#ifndef _WIN32
|
||||
else if(((struct srvparam *)node->value) -> logfunc == logsyslog) return "syslog";
|
||||
#endif
|
||||
#ifndef NOODBC
|
||||
else if(((struct srvparam *)node->value) -> logfunc == logsql) return "odbc";
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void * ef_server_logformat(struct node * node){
|
||||
return ((struct srvparam *)node->value) -> logformat;
|
||||
}
|
||||
|
||||
static void * ef_server_nonprintable(struct node * node){
|
||||
return ((struct srvparam *)node->value) -> nonprintable;
|
||||
}
|
||||
|
||||
static void * ef_server_replacement(struct node * node){
|
||||
if(((struct srvparam *)node->value) -> nonprintable)return &((struct srvparam *)node->value) -> replace;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void * ef_server_logtarget(struct node * node){
|
||||
return ((struct srvparam *)node->value) -> logtarget;
|
||||
}
|
||||
|
||||
|
||||
static void * ef_server_target(struct node * node){
|
||||
return ((struct srvparam *)node->value) -> target;
|
||||
}
|
||||
|
||||
static void * ef_server_targetport(struct node * node){
|
||||
return &((struct srvparam *)node->value) -> targetport;
|
||||
}
|
||||
|
||||
static void * ef_server_intsa(struct node * node){
|
||||
return &((struct srvparam *)node->value) -> intsa;
|
||||
}
|
||||
|
||||
static void * ef_server_extsa(struct node * node){
|
||||
return &((struct srvparam *)node->value) -> extsa;
|
||||
}
|
||||
|
||||
#ifndef NOIPV6
|
||||
static void * ef_server_extsa6(struct node * node){
|
||||
return &((struct srvparam *)node->value) -> extsa6;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void * ef_server_acl(struct node * node){
|
||||
return ((struct srvparam *)node->value) -> acl;
|
||||
}
|
||||
|
||||
static void * ef_server_singlepacket(struct node * node){
|
||||
return &((struct srvparam *)node->value) -> singlepacket;
|
||||
}
|
||||
|
||||
static void * ef_server_usentlm(struct node * node){
|
||||
return &((struct srvparam *)node->value) -> usentlm;
|
||||
}
|
||||
|
||||
static void * ef_server_starttime(struct node * node){
|
||||
return &((struct srvparam *)node->value) -> time_start;
|
||||
}
|
||||
|
||||
|
||||
static void * ef_client_next(struct node * node){
|
||||
return ((struct clientparam *)node->value) -> next;
|
||||
}
|
||||
|
||||
static void * ef_client_type(struct node * node){
|
||||
int service = ((struct clientparam *)node->value) -> service;
|
||||
return (service>=0 && service < 15)? (void *)conf.stringtable[SERVICES + service] : (void *)"unknown";
|
||||
}
|
||||
|
||||
static void * ef_client_operation(struct node * node){
|
||||
if(!((struct clientparam *)node->value) -> operation) return NULL;
|
||||
return &((struct clientparam *)node->value) -> operation;
|
||||
|
||||
}
|
||||
|
||||
static void * ef_client_redirected(struct node * node){
|
||||
return &((struct clientparam *)node->value) -> redirected;
|
||||
|
||||
}
|
||||
|
||||
static void * ef_client_hostname(struct node * node){
|
||||
return ((struct clientparam *)node->value) -> hostname;
|
||||
}
|
||||
|
||||
static void * ef_client_username(struct node * node){
|
||||
return ((struct clientparam *)node->value) -> username;
|
||||
}
|
||||
|
||||
static void * ef_client_password(struct node * node){
|
||||
return ((struct clientparam *)node->value) -> password;
|
||||
}
|
||||
|
||||
static void * ef_client_extusername(struct node * node){
|
||||
return ((struct clientparam *)node->value) -> extusername;
|
||||
}
|
||||
|
||||
static void * ef_client_extpassword(struct node * node){
|
||||
return ((struct clientparam *)node->value) -> extpassword;
|
||||
}
|
||||
|
||||
static void * ef_client_clisa(struct node * node){
|
||||
return &((struct clientparam *)node->value) -> sincr;
|
||||
}
|
||||
|
||||
static void * ef_client_srvsa(struct node * node){
|
||||
return &((struct clientparam *)node->value) -> sinsr;
|
||||
}
|
||||
|
||||
static void * ef_client_reqsa(struct node * node){
|
||||
return &((struct clientparam *)node->value) -> req;
|
||||
}
|
||||
|
||||
static void * ef_client_pwtype(struct node * node){
|
||||
return &((struct clientparam *)node->value) -> pwtype;
|
||||
}
|
||||
|
||||
static void * ef_client_threadid(struct node * node){
|
||||
return &((struct clientparam *)node->value) -> threadid;
|
||||
}
|
||||
|
||||
static void * ef_client_starttime(struct node * node){
|
||||
return &((struct clientparam *)node->value) -> time_start;
|
||||
}
|
||||
|
||||
static void * ef_client_starttime_msec(struct node * node){
|
||||
return &((struct clientparam *)node->value) -> msec_start;
|
||||
}
|
||||
|
||||
static void * ef_period_fromtime(struct node * node){
|
||||
return &((struct period *)node->value) -> fromtime;
|
||||
}
|
||||
|
||||
static void * ef_period_totime(struct node * node){
|
||||
return &((struct period *)node->value) -> totime;
|
||||
}
|
||||
|
||||
static void * ef_period_next(struct node * node){
|
||||
return ((struct period *)node->value) -> next;
|
||||
}
|
||||
|
||||
static struct property prop_portlist[] = {
|
||||
{prop_portlist + 1, "start", ef_portlist_start, TYPE_PORT, "port range start"},
|
||||
{prop_portlist + 2, "end", ef_portlist_end, TYPE_PORT, "port range end"},
|
||||
{NULL, "next", ef_portlist_next, TYPE_PORTLIST, "next"}
|
||||
};
|
||||
|
||||
static struct property prop_userlist[] = {
|
||||
{prop_userlist+1, "user", ef_userlist_user, TYPE_STRING, "user name"},
|
||||
{NULL, "next", ef_userlist_next, TYPE_USERLIST, "next"}
|
||||
};
|
||||
|
||||
static struct property prop_pwlist[] = {
|
||||
{prop_pwlist + 1, "user", ef_pwlist_user, TYPE_STRING, "user name"},
|
||||
{prop_pwlist + 2, "password", ef_pwlist_password, TYPE_STRING, "password string"},
|
||||
{prop_pwlist + 3, "type", ef_pwlist_type, TYPE_STRING, "password type"},
|
||||
{NULL, "next", ef_pwlist_next, TYPE_PWLIST, "next"}
|
||||
};
|
||||
|
||||
static struct property prop_chain[] = {
|
||||
{prop_chain + 1, "addr", ef_chain_addr, TYPE_SA, "parent address"},
|
||||
{prop_chain + 2, "type", ef_chain_type, TYPE_STRING, "parent type"},
|
||||
{prop_chain + 3, "weight", ef_chain_weight, TYPE_SHORT, "parent weight 0-1000"},
|
||||
{prop_chain + 4, "user", ef_chain_user, TYPE_STRING, "parent login"},
|
||||
{prop_chain + 5, "password", ef_chain_password, TYPE_STRING, "parent password"},
|
||||
{NULL, "next", ef_chain_next, TYPE_CHAIN, "next"}
|
||||
};
|
||||
|
||||
static struct property prop_period[] = {
|
||||
{prop_period + 1, "fromtime", ef_period_fromtime, TYPE_TIME, "from time" },
|
||||
{prop_period + 2, "totime", ef_period_totime, TYPE_TIME, "to time" },
|
||||
{NULL, "next", ef_period_next, TYPE_PERIOD, "next"}
|
||||
};
|
||||
|
||||
static struct property prop_ace[] = {
|
||||
{prop_ace + 1, "type", ef_ace_type, TYPE_STRING, "ace action"},
|
||||
{prop_ace + 2, "operations", ef_ace_operations, TYPE_OPERATIONS, "request type"},
|
||||
{prop_ace + 3, "users", ef_ace_users, TYPE_USERLIST, "list of users"},
|
||||
{prop_ace + 4, "src", ef_ace_src, TYPE_IPLIST, "list of source ips"},
|
||||
{prop_ace + 5, "dst", ef_ace_dst, TYPE_IPLIST, "list of destination ips"},
|
||||
{prop_ace + 6, "ports", ef_ace_ports, TYPE_PORTLIST, "list of destination ports"},
|
||||
{prop_ace + 7, "chain", ef_ace_chain, TYPE_CHAIN, "redirect to parent(s)"},
|
||||
{prop_ace + 8, "wdays", ef_ace_weekdays, TYPE_WEEKDAYS, "days of week"},
|
||||
{prop_ace + 9, "periods", ef_ace_period, TYPE_PERIOD, "time of the day"},
|
||||
{NULL, "next", ef_ace_next, TYPE_ACE, "next"}
|
||||
};
|
||||
|
||||
static struct property prop_bandlimit[] = {
|
||||
{prop_bandlimit + 1, "ace", ef_bandlimit_ace, TYPE_ACE, "acl to apply"},
|
||||
{prop_bandlimit + 2, "rate", ef_bandlimit_rate, TYPE_UNSIGNED, "max allowed bandwidth"},
|
||||
{NULL, "next", ef_bandlimit_next, TYPE_BANDLIMIT, "next"}
|
||||
};
|
||||
|
||||
static struct property prop_trafcounter[] = {
|
||||
{prop_trafcounter + 1, "disabled", ef_trafcounter_disabled, TYPE_INTEGER, "counter status"},
|
||||
{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 + 4, "type", ef_trafcounter_type, TYPE_ROTATION, "rotation type"},
|
||||
|
||||
|
||||
{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 + 8, "updated", ef_trafcounter_updated, TYPE_DATETIME, "last updated"},
|
||||
{prop_trafcounter + 9, "comment", ef_trafcounter_comment, TYPE_STRING, "counter comment"},
|
||||
{NULL, "next", ef_trafcounter_next, TYPE_TRAFCOUNTER}
|
||||
};
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
static struct property prop_server[] = {
|
||||
{prop_server + 1, "servicetype", ef_server_type, TYPE_STRING, "type of the service/client"},
|
||||
{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 + 4, "starttime", ef_server_starttime, TYPE_DATETIME, "service started seconds"},
|
||||
{prop_server + 5, "intsa", ef_server_intsa, TYPE_SA, "ip address of internal interface"},
|
||||
{prop_server + 6, "extsa", ef_server_extsa, TYPE_SA, "ip address of external interface"},
|
||||
{prop_server + 7, "auth", ef_server_auth, TYPE_STRING, "service authentication type"},
|
||||
{prop_server + 8, "acl", ef_server_acl, TYPE_ACE, "access control list"},
|
||||
{prop_server + 9, "singlepacket", ef_server_singlepacket, TYPE_INTEGER, "is single packet redirection"},
|
||||
{prop_server + 10, "usentlm", ef_server_usentlm, TYPE_INTEGER, "allow NTLM authentication"},
|
||||
{prop_server + 11, "log", ef_server_log, TYPE_STRING, "type of logging"},
|
||||
{prop_server + 12, "logtarget", ef_server_logtarget, TYPE_STRING, "log target options"},
|
||||
{prop_server + 13, "logformat", ef_server_logformat, TYPE_STRING, "logging format string"},
|
||||
{prop_server + 14, "nonprintable", ef_server_nonprintable, TYPE_STRING, "non printable characters"},
|
||||
{prop_server + 15, "replacement", ef_server_replacement, TYPE_CHAR, "replacement character"},
|
||||
{prop_server + 16, "childcount", ef_server_childcount, TYPE_INTEGER, "number of servers connected"},
|
||||
{prop_server + 17, "child", ef_server_child, TYPE_CLIENT, "connected clients"},
|
||||
#ifndef NOIPV6
|
||||
{prop_server + 18, "extsa6", ef_server_extsa6, TYPE_SA, "ipv6 address of external interface"},
|
||||
#endif
|
||||
{NULL, "next", ef_server_next, TYPE_SERVER, "next"}
|
||||
};
|
||||
|
||||
|
||||
static struct property prop_client[] = {
|
||||
{prop_client + 1, "servicetype", ef_client_type, TYPE_STRING, "type of the client"},
|
||||
{prop_client + 2, "threadid", ef_client_threadid, TYPE_INTEGER, "process thread id"},
|
||||
{prop_client + 3, "starttime", ef_client_starttime, TYPE_DATETIME, "client started seconds"},
|
||||
{prop_client + 4, "starttime_msec", ef_client_starttime_msec, TYPE_UNSIGNED, "client started milliseconds"},
|
||||
{prop_client + 5, "redirected", ef_client_redirected, TYPE_INTEGER, "number of redirections"},
|
||||
{prop_client + 6, "operation", ef_client_operation, TYPE_OPERATIONS, "action requested by client"},
|
||||
{prop_client + 7, "hostname", ef_client_hostname, TYPE_STRING, "name of the requested host"},
|
||||
{prop_client + 8, "extusername", ef_client_extusername, TYPE_STRING, "username 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 + 11, "password", ef_client_password, TYPE_STRING, "client password"},
|
||||
{prop_client + 12, "clisa", ef_client_clisa, TYPE_SA, "client sa"},
|
||||
{prop_client + 13, "srvsa", ef_client_srvsa, TYPE_IP, "target server sa"},
|
||||
{prop_client + 14, "reqsa", ef_client_reqsa, TYPE_IP, "requested server sa"},
|
||||
{prop_client + 15, "bytesin", ef_client_bytesin64, TYPE_UNSIGNED64, "bytes from server to client"},
|
||||
{prop_client + 16, "bytesout", ef_client_bytesout64, TYPE_UNSIGNED64, "bytes from client to server"},
|
||||
{prop_client + 17, "maxtrafin", ef_client_maxtrafin64, TYPE_UNSIGNED64, "maximum traffic allowed for download"},
|
||||
{prop_client + 18, "maxtrafout", ef_client_maxtrafout64, TYPE_UNSIGNED64, "maximum traffic allowed for upload"},
|
||||
{prop_client + 19, "pwtype", ef_client_pwtype, TYPE_INTEGER, "type of client password"},
|
||||
{NULL, "next", ef_client_next, TYPE_CLIENT, "next"}
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct datatype datatypes[64] = {
|
||||
{"integer", NULL, pr_integer, NULL},
|
||||
{"short", NULL, pr_short, NULL},
|
||||
{"char", NULL, pr_char, NULL},
|
||||
{"unsigned", NULL, pr_unsigned, NULL},
|
||||
{"unsigned64", NULL, pr_unsigned64, NULL},
|
||||
{"traffic", NULL, pr_traffic, NULL},
|
||||
{"port", NULL, pr_port, NULL},
|
||||
{"ip", NULL, pr_ip, NULL},
|
||||
{"sa", NULL, pr_sa, NULL},
|
||||
{"cidr", NULL, pr_cidr, NULL},
|
||||
{"string", NULL, pr_string, NULL},
|
||||
{"datetime", NULL, pr_datetime, NULL},
|
||||
{"operations", NULL, pr_operations, NULL},
|
||||
{"rotation", NULL, pr_rotation, NULL},
|
||||
{"portlist", ef_portlist_next, pr_portlist, prop_portlist},
|
||||
{"iplist", ef_iplist_next, pr_iplist, NULL},
|
||||
{"userlist", ef_userlist_next, pr_userlist, prop_userlist},
|
||||
{"pwlist", ef_pwlist_next, NULL, prop_pwlist},
|
||||
{"chain", ef_chain_next, NULL, prop_chain},
|
||||
{"ace", ef_ace_next, NULL, prop_ace},
|
||||
{"bandlimit", ef_bandlimit_next, NULL, prop_bandlimit},
|
||||
{"trafcounter", ef_trafcounter_next, NULL, prop_trafcounter},
|
||||
{"client", ef_client_next, NULL, prop_client},
|
||||
{"weekdays", NULL, pr_wdays, NULL},
|
||||
{"time", NULL, pr_time, NULL},
|
||||
{"period", ef_period_next, NULL, prop_period},
|
||||
{"server", ef_server_next, NULL, prop_server}
|
||||
};
|
141
src/dighosts.c
141
src/dighosts.c
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2008 3APA3A
|
||||
*
|
||||
* please read License Agreement
|
||||
*
|
||||
*/
|
||||
|
||||
#include "proxy.h"
|
||||
pthread_mutex_t log_mutex;
|
||||
|
||||
|
||||
int sockgetchar(SOCKET sock, int timeosec, int timeousec){
|
||||
unsigned char buf;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = timeosec;
|
||||
tv.tv_usec = timeousec;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(sock, &fds);
|
||||
if (select (((int)sock)+1, &fds, NULL, NULL, &tv)!=1) return EOF;
|
||||
if (recv(sock, (char *)&buf, 1, 0)!=1) return EOF;
|
||||
return((int)buf);
|
||||
}
|
||||
|
||||
|
||||
int sockgetline(SOCKET sock, unsigned char * buf, int bufsize, int delim, int to){
|
||||
int c;
|
||||
int i=0, tos, tou;
|
||||
if(bufsize<2) return 0;
|
||||
c = sockgetchar(sock, to, 0);
|
||||
if (c == EOF) {
|
||||
return 0;
|
||||
}
|
||||
tos = to/16;
|
||||
tou = ((to * 1000) / bufsize)%1000;
|
||||
do {
|
||||
buf[i++] = c;
|
||||
if(delim != EOF && c == delim) break;
|
||||
}while(i < bufsize && (c = sockgetchar(sock, tos, tou)) != EOF);
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
unsigned char request[] = "GET %.1024s HTTP/1.0\r\nHost: %.256s\r\n\r\n";
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
unsigned char *host, *hostend;
|
||||
SOCKET sock;
|
||||
struct sockaddr_in sa;
|
||||
FILE *fp;
|
||||
unsigned char buf[16000];
|
||||
int i;
|
||||
unsigned x,y,z,w,cidr, x1,y1,z1,w1, mask;
|
||||
int first = 1;
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wd;
|
||||
WSAStartup(MAKEWORD( 1, 1 ), &wd);
|
||||
#endif
|
||||
|
||||
if(argc < 3 || argc > 4 || (argc == 4 && (argv[1][0] != '-' || argv[1][1] != 'm'))) {
|
||||
fprintf(stderr, "Usage: %s [-m] <URL> <FILE>\n"
|
||||
" program retrieves requested <URL> and builds comma delimited list of networks\n"
|
||||
" list than stored in <FILE>\n"
|
||||
" networks are searched in xxx.yyy.zzz.www/cidr format\n"
|
||||
" switches:\n"
|
||||
" -m networks are searched in xxx.yyy.zzz.www mmm.mmm.mmm.mmm format\n"
|
||||
"\n(c)2002 by 3APA3A\n",
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if(strncasecmp(argv[argc-2], "http://", 7)) {
|
||||
fprintf(stderr, "URL must be HTTP://\n");
|
||||
return 2;
|
||||
}
|
||||
hostend = (unsigned char *)strchr((char *)argv[argc-2] + 7, '/');
|
||||
if(!hostend) {
|
||||
fprintf(stderr, "Wrong URL syntaxis\n");
|
||||
return 3;
|
||||
}
|
||||
*hostend = 0;
|
||||
if(!(host = (unsigned char *)strdup((char *)argv[argc-2] + 7))) {
|
||||
return 4;
|
||||
}
|
||||
*hostend = '/';
|
||||
if(!getip46(4, host, (struct sockaddr *)&sa)) {
|
||||
fprintf(stderr, "Unable to resolve %s\n", host);
|
||||
return 5;
|
||||
}
|
||||
sa.sin_port = htons(80);
|
||||
if((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return 6;
|
||||
sprintf((char *)buf, (char *)request, hostend, host);
|
||||
if(connect(sock,(struct sockaddr *)&sa,sizeof(sa))) {
|
||||
fprintf(stderr, "Unable to connect: %s\n", host);
|
||||
return 8;
|
||||
}
|
||||
if(send(sock, (char *)buf, (int)strlen((char *)buf), 0) != (int)strlen((char *)buf)) return 9;
|
||||
while( (i = sockgetline(sock, buf, sizeof(buf) - 1, '\n', 30)) > 2);
|
||||
if(i<1) return 9;
|
||||
if(!(fp = fopen(argv[argc-1], "w"))) {
|
||||
fprintf(stderr, "Unable to open: %s\n", argv[2]);
|
||||
return 7;
|
||||
}
|
||||
while( (i = sockgetline(sock, buf, sizeof(buf) - 1, '\n', 30)) > 0){
|
||||
buf[i] = 0;
|
||||
for(i = 0; buf[i]; i++){
|
||||
if((buf[i]<'0' || buf[i] > '9') && buf[i] != '.' && buf[i] != '/')buf[i] = ' ';
|
||||
}
|
||||
if(argc == 3){
|
||||
if((i=sscanf((char *)buf, "%u.%u.%u.%u/%u", &x, &y, &z, &w, &cidr)) == 5 &&
|
||||
x<256 && y<256 && z<256 && w<256 &&
|
||||
cidr <= 32){
|
||||
if(!first)fprintf(fp, ",");
|
||||
fprintf(fp, "%u.%u.%u.%u/%u", x, y, z, w, cidr);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if((i = sscanf((char *)buf, "%u.%u.%u.%u %u.%u.%u.%u", &x, &y, &z, &w, &x1, &y1, &z1, &w1)) == 8 &&
|
||||
x<256 && y<256 && z<256 && w<256 &&
|
||||
x1<256 && y1<256 && z1<256 && w1<256
|
||||
){
|
||||
mask = (x1<<24)|(y1<<16)|(z1<<8)|w1;
|
||||
for(cidr = 0; cidr <= 32; cidr++)if((((unsigned long)(0xFFFFFFFF))<<(32-cidr)) == mask) break;
|
||||
if(cidr > 32) continue;
|
||||
if(!first)fprintf(fp, ",");
|
||||
fprintf(fp, "%u.%u.%u.%u/%u", x, y, z, w, cidr);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
#ifdef _WIN32
|
||||
closesocket(sock);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
211
src/dnspr.c
211
src/dnspr.c
@ -1,211 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
|
||||
#include "proxy.h"
|
||||
|
||||
#ifndef UDP
|
||||
#define UDP
|
||||
#endif
|
||||
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
||||
|
||||
#define BUFSIZE 16384
|
||||
|
||||
|
||||
void * dnsprchild(struct clientparam* param) {
|
||||
unsigned long ip = 0;
|
||||
unsigned char *bbuf;
|
||||
unsigned char *buf, *s1, *s2;
|
||||
char * host = NULL;
|
||||
unsigned char c;
|
||||
SASIZETYPE size;
|
||||
int res, i;
|
||||
int len;
|
||||
unsigned type=0;
|
||||
unsigned ttl;
|
||||
unsigned char addr[16];
|
||||
#ifdef _WIN32
|
||||
unsigned long ul = 1;
|
||||
#endif
|
||||
|
||||
|
||||
if(!(bbuf = myalloc(BUFSIZE+2))){
|
||||
param->srv->fds.events = POLLIN;
|
||||
RETURN (21);
|
||||
}
|
||||
buf = bbuf+2;
|
||||
size = sizeof(param->sincr);
|
||||
i = so._recvfrom(param->srv->srvsock, (char *)buf, BUFSIZE, 0, (struct sockaddr *)¶m->sincr, &size);
|
||||
size = sizeof(param->sinsl);
|
||||
getsockname(param->srv->srvsock, (struct sockaddr *)¶m->sincl, &size);
|
||||
#ifdef _WIN32
|
||||
if((param->clisock=so._socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
|
||||
RETURN(818);
|
||||
}
|
||||
ioctlsocket(param->clisock, FIONBIO, &ul);
|
||||
if(so._setsockopt(param->clisock, SOL_SOCKET, SO_REUSEADDR, (char *)&ul, sizeof(int))) {RETURN(820);};
|
||||
if(so._bind(param->clisock,(struct sockaddr *)¶m->sincl,SASIZE(¶m->sincl))) {
|
||||
RETURN(822);
|
||||
}
|
||||
|
||||
#else
|
||||
param->clisock = param->srv->srvsock;
|
||||
#endif
|
||||
param->srv->fds.events = POLLIN;
|
||||
|
||||
if(i < 0) {
|
||||
RETURN(813);
|
||||
}
|
||||
buf[BUFSIZE - 1] = 0;
|
||||
if(i<=13 || i>1000){
|
||||
RETURN (814);
|
||||
}
|
||||
param->operation = DNSRESOLVE;
|
||||
if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
|
||||
|
||||
if(buf[4]!=0 || buf[5]!=1) RETURN(816);
|
||||
for(len = 12; len<i; len+=(c+1)){
|
||||
c = buf[len];
|
||||
if(!c)break;
|
||||
buf[len] = '.';
|
||||
}
|
||||
if(len > (i-4)) {RETURN(817);}
|
||||
|
||||
host = mystrdup((char *)buf+13);
|
||||
if(!host) {RETURN(21);}
|
||||
|
||||
for(s2 = buf + 12; (s1 = (unsigned char *)strchr((char *)s2 + 1, '.')); s2 = s1)*s2 = (unsigned char)((s1 - s2) - 1);
|
||||
*s2 = (len - (int)(s2 - buf)) - 1;
|
||||
|
||||
type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2];
|
||||
if((type==0x01 || type==0x1c) && !param->srv->singlepacket){
|
||||
ip = udpresolve((type==0x1c)?AF_INET6:AF_INET, (unsigned char *)host, addr, &ttl, param, 0);
|
||||
}
|
||||
|
||||
len+=5;
|
||||
|
||||
if(ip){
|
||||
buf[2] = 0x85;
|
||||
buf[3] = 0x80;
|
||||
buf[6] = 0;
|
||||
buf[7] = 1;
|
||||
buf[8] = buf[9] = buf[10] = buf[11] = 0;
|
||||
memset(buf+len, 0, 16);
|
||||
buf[len] = 0xc0;
|
||||
buf[len+1] = 0x0c;
|
||||
buf[len+3] = type;
|
||||
buf[len+5] = 1;
|
||||
ttl = htonl(ttl);
|
||||
memcpy(buf + len + 6, &ttl, 4);
|
||||
buf[len+11] = type==1? 4:16;
|
||||
memcpy(buf+len+12,(void *)&addr,type==1? 4:16);
|
||||
len+=(type==1?16:28);
|
||||
}
|
||||
else if(type == 0x0c) {
|
||||
unsigned a, b, c, d;
|
||||
sscanf(host, "%u.%u.%u.%u", &a, &b, &c, &d);
|
||||
ip = htonl((d<<24) ^ (c<<16) ^ (b<<8) ^ a);
|
||||
if(*SAFAMILY(¶m->sincl) == AF_INET && ip == *(unsigned long*)SAADDR(¶m->sincl)){
|
||||
buf[2] = 0x85;
|
||||
buf[3] = 0x80;
|
||||
buf[6] = 0;
|
||||
buf[7] = 1;
|
||||
buf[8] = buf[9] = buf[10] = buf[11] = 0;
|
||||
memset(buf+len, 0, 20);
|
||||
buf[len] = 0xc0;
|
||||
buf[len+1] = 0x0c;
|
||||
buf[len+3] = 0x0c;
|
||||
buf[len+5] = 1;
|
||||
ttl = htonl(3600);
|
||||
memcpy(buf + len + 6, &ttl, 4);
|
||||
buf[len+11] = 7;
|
||||
buf[len+12] = 6;
|
||||
memcpy(buf+len+13,(void *)"3proxy",6);
|
||||
len+=20;
|
||||
}
|
||||
else ip = 0;
|
||||
}
|
||||
if(!ip && numservers){
|
||||
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);
|
||||
}
|
||||
memset(¶m->sinsl, 0, sizeof(param->sinsl));
|
||||
*SAFAMILY(¶m->sinsl) = *SAFAMILY(&nservers[0].addr);
|
||||
if(so._bind(param->remsock,(struct sockaddr *)¶m->sinsl,SASIZE(¶m->sinsl))) {
|
||||
RETURN(819);
|
||||
}
|
||||
param->sinsr = nservers[0].addr;
|
||||
if(nservers[0].usetcp) {
|
||||
if(so._connect(param->remsock,(struct sockaddr *)¶m->sinsr,SASIZE(¶m->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 *)¶m->sinsr, buf, i, conf.timeouts[SINGLEBYTE_L]*1000) != i){
|
||||
RETURN(820);
|
||||
}
|
||||
param->statscli64 += i;
|
||||
param->nwrites++;
|
||||
len = sockrecvfrom(param->remsock, (struct sockaddr *)¶m->sinsr, buf, BUFSIZE, conf.timeouts[DNS_TO]*1000);
|
||||
if(len <= 13) {
|
||||
RETURN(821);
|
||||
}
|
||||
param->statssrv64 += len;
|
||||
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(socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000) != len){
|
||||
RETURN(822);
|
||||
}
|
||||
RETURN(0);
|
||||
}
|
||||
|
||||
}
|
||||
if(!ip) {
|
||||
buf[2] = 0x85;
|
||||
buf[3] = 0x83;
|
||||
}
|
||||
res = socksendto(param->clisock, (struct sockaddr *)¶m->sincr, buf, len, conf.timeouts[SINGLEBYTE_L]*1000);
|
||||
if(res != len){RETURN(819);}
|
||||
if(!ip) {RETURN(888);}
|
||||
|
||||
CLEANRET:
|
||||
|
||||
if(param->res!=813){
|
||||
sprintf((char *)buf, "%04x/%s/",
|
||||
(unsigned)type,
|
||||
host?host:"");
|
||||
if((ip && type == 0x01) || type == 0x1c){
|
||||
myinet_ntop(type == 0x01? AF_INET:AF_INET6, addr, (char *)buf+strlen((char *)buf), 64);
|
||||
}
|
||||
(*param->srv->logfunc)(param, buf);
|
||||
}
|
||||
if(bbuf)myfree(bbuf);
|
||||
if(host)myfree(host);
|
||||
#ifndef _WIN32
|
||||
param->clisock = INVALID_SOCKET;
|
||||
#endif
|
||||
freeparam(param);
|
||||
return (NULL);
|
||||
}
|
||||
|
328
src/ftppr.c
328
src/ftppr.c
@ -1,328 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
|
||||
#include "proxy.h"
|
||||
|
||||
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
||||
#define BUFSIZE 2048
|
||||
|
||||
void * ftpprchild(struct clientparam* param) {
|
||||
int i=0, res;
|
||||
unsigned char *buf;
|
||||
unsigned char *se;
|
||||
int status = 0;
|
||||
int inbuf;
|
||||
int pasv = 0;
|
||||
SOCKET sc = INVALID_SOCKET, ss = INVALID_SOCKET, clidatasock = INVALID_SOCKET;
|
||||
SASIZETYPE sasize;
|
||||
char * req = NULL;
|
||||
struct linger lg;
|
||||
struct pollfd fds;
|
||||
|
||||
if(!(buf = myalloc(BUFSIZE))) RETURN(876);
|
||||
param->ctrlsock = param->clisock;
|
||||
param->operation = CONNECT;
|
||||
lg.l_onoff = 1;
|
||||
lg.l_linger = conf.timeouts[STRING_L];;
|
||||
if(socksend(param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);}
|
||||
for(;;){
|
||||
i = sockgetlinebuf(param, CLIENT, buf, BUFSIZE - 10, '\n', conf.timeouts[CONNECTION_S]);
|
||||
if(!i) {
|
||||
RETURN(0);
|
||||
}
|
||||
if(i<4) {RETURN(802);}
|
||||
buf[i] = 0;
|
||||
if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0;
|
||||
if (req) myfree (req);
|
||||
req = NULL;
|
||||
|
||||
if (!strncasecmp((char *)buf, "OPEN ", 5)){
|
||||
if(parsehostname((char *)buf+5, param, 21)){RETURN(803);}
|
||||
if(param->remsock != INVALID_SOCKET) {
|
||||
so._shutdown(param->remsock, SHUT_RDWR);
|
||||
so._closesocket(param->remsock);
|
||||
param->remsock = INVALID_SOCKET;
|
||||
}
|
||||
if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
|
||||
param->ctrlsocksrv = param->remsock;
|
||||
if(socksend(param->ctrlsock, (unsigned char *)"220 Ready\r\n", 11, conf.timeouts[STRING_S])!=11) {RETURN (801);}
|
||||
status = 1;
|
||||
}
|
||||
else if (!strncasecmp((char *)buf, "USER ", 5)){
|
||||
if(parseconnusername((char *)buf +5, param, 0, 21)){RETURN(804);}
|
||||
if(!status){
|
||||
if((res = (*param->srv->authfunc)(param))) {RETURN(res);}
|
||||
param->ctrlsocksrv = param->remsock;
|
||||
}
|
||||
if(socksend(param->ctrlsock, (unsigned char *)"331 ok\r\n", 8, conf.timeouts[STRING_S])!=8) {RETURN (807);}
|
||||
status = 2;
|
||||
|
||||
}
|
||||
else if (!strncasecmp((char *)buf, "PASS ", 5)){
|
||||
param->extpassword = (unsigned char *)mystrdup((char *)buf+5);
|
||||
inbuf = BUFSIZE;
|
||||
res = ftplogin(param, (char *)buf, &inbuf);
|
||||
param->res = res;
|
||||
if(inbuf && inbuf != BUFSIZE && socksend(param->ctrlsock, buf, inbuf, conf.timeouts[STRING_S])!=inbuf) {RETURN (807);}
|
||||
if(!res) status = 3;
|
||||
sprintf((char *)buf, "%.128s@%.128s%c%hu", param->extusername, param->hostname, (ntohs(*SAPORT(¶m->sinsr))==21)?0:':', ntohs(*SAPORT(¶m->sinsr)));
|
||||
req = mystrdup((char *)buf);
|
||||
#ifndef WITHMAIN
|
||||
{
|
||||
int action, reqbufsize, reqsize;
|
||||
reqbufsize = BUFSIZE;
|
||||
reqsize = (int)strlen((char *)buf) + 1;
|
||||
|
||||
action = handlereqfilters(param, &buf, &reqbufsize, 0, &reqsize);
|
||||
if(action == HANDLED){
|
||||
RETURN(0);
|
||||
}
|
||||
if(action != PASS) RETURN(877);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (status >= 3 && (
|
||||
(!strncasecmp((char *)buf, "PASV", 4) && (pasv = 1)) ||
|
||||
(!strncasecmp((char *)buf, "PORT ", 5) && !(pasv = 0))
|
||||
)){
|
||||
#ifndef WITHMAIN
|
||||
{
|
||||
int action, reqbufsize, reqsize;
|
||||
reqbufsize = BUFSIZE;
|
||||
reqsize = (int)strlen((char *)buf) + 1;
|
||||
|
||||
action = handlehdrfilterscli(param, &buf, &reqbufsize, 0, &reqsize);
|
||||
if(action == HANDLED){
|
||||
RETURN(0);
|
||||
}
|
||||
if(action != PASS) RETURN(878);
|
||||
}
|
||||
#endif
|
||||
if(sc != INVALID_SOCKET) {
|
||||
so._shutdown(sc, SHUT_RDWR);
|
||||
so._closesocket(sc);
|
||||
sc = INVALID_SOCKET;
|
||||
}
|
||||
if(ss != INVALID_SOCKET) {
|
||||
so._shutdown(ss, SHUT_RDWR);
|
||||
so._closesocket(ss);
|
||||
ss = INVALID_SOCKET;
|
||||
}
|
||||
if(clidatasock != INVALID_SOCKET) {
|
||||
so._shutdown(clidatasock, SHUT_RDWR);
|
||||
so._closesocket(clidatasock);
|
||||
clidatasock = INVALID_SOCKET;
|
||||
}
|
||||
if ((clidatasock=socket(SASOCK(¶m->sincl), SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {RETURN(821);}
|
||||
*SAPORT(¶m->sincl) = 0;
|
||||
if(so._bind(clidatasock, (struct sockaddr *)¶m->sincl, SASIZE(¶m->sincl))){RETURN(822);}
|
||||
if (pasv) {
|
||||
if(so._listen(clidatasock, 1)) {RETURN(823);}
|
||||
sasize = sizeof(param->sincl);
|
||||
if(so._getsockname(clidatasock, (struct sockaddr *)¶m->sincl, &sasize)){RETURN(824);}
|
||||
if(*SAFAMILY(¶m->sincl) == AF_INET)
|
||||
sprintf((char *)buf, "227 OK (%u,%u,%u,%u,%u,%u)\r\n",
|
||||
(unsigned)(((unsigned char *)(SAADDR(¶m->sincl)))[0]),
|
||||
(unsigned)(((unsigned char *)(SAADDR(¶m->sincl)))[1]),
|
||||
(unsigned)(((unsigned char *)(SAADDR(¶m->sincl)))[2]),
|
||||
(unsigned)(((unsigned char *)(SAADDR(¶m->sincl)))[3]),
|
||||
(unsigned)(((unsigned char *)(SAPORT(¶m->sincl)))[0]),
|
||||
(unsigned)(((unsigned char *)(SAPORT(¶m->sincl)))[1])
|
||||
);
|
||||
else sprintf((char *)buf, "227 OK (127,0,0,1,%u,%u)\r\n",
|
||||
(unsigned)(((unsigned char *)(SAPORT(¶m->sincl)))[0]),
|
||||
(unsigned)(((unsigned char *)(SAPORT(¶m->sincl)))[1])
|
||||
);
|
||||
}
|
||||
else {
|
||||
unsigned long b1, b2, b3, b4;
|
||||
unsigned short b5, b6;
|
||||
|
||||
if(sscanf((char *)buf+5, "%lu,%lu,%lu,%lu,%hu,%hu", &b1, &b2, &b3, &b4, &b5, &b6)!=6) {RETURN(828);}
|
||||
*SAPORT(¶m->sincr) = htons((unsigned short)((b5<<8)^b6));
|
||||
if(so._connect(clidatasock, (struct sockaddr *)¶m->sincr, SASIZE(¶m->sincr))) {
|
||||
so._closesocket(clidatasock);
|
||||
clidatasock = INVALID_SOCKET;
|
||||
RETURN(826);
|
||||
}
|
||||
sprintf((char *)buf, "200 OK\r\n");
|
||||
}
|
||||
#ifndef WITHMAIN
|
||||
{
|
||||
int action, reqbufsize, reqsize;
|
||||
reqbufsize = BUFSIZE;
|
||||
reqsize = (int)strlen((char *)buf) + 1;
|
||||
|
||||
action = handlehdrfilterssrv(param, &buf, &reqbufsize, 0, &reqsize);
|
||||
if(action == HANDLED){
|
||||
RETURN(0);
|
||||
}
|
||||
if(action != PASS) RETURN(879);
|
||||
}
|
||||
#endif
|
||||
if(socksend(param->ctrlsock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S])!=(int)strlen((char *)buf)) {RETURN (825);}
|
||||
status = 4;
|
||||
}
|
||||
else if (status == 4 && (
|
||||
!(strncasecmp((char *)buf, "RETR ", 5) && (param->operation = FTP_GET)) ||
|
||||
!(strncasecmp((char *)buf, "LIST", 4) && (param->operation = FTP_LIST))||
|
||||
!(strncasecmp((char *)buf, "NLST ", 5) && (param->operation = FTP_LIST)) ||
|
||||
!(strncasecmp((char *)buf, "MLSD", 4) && (param->operation = FTP_LIST)) ||
|
||||
!(strncasecmp((char *)buf, "APPE ", 5) && (param->operation = FTP_PUT)) ||
|
||||
!(strncasecmp((char *)buf, "STOR ", 5) && (param->operation = FTP_PUT))
|
||||
)){
|
||||
int arg = (buf[4] && buf[5])? 1:0;
|
||||
int ressent = 0;
|
||||
|
||||
|
||||
#ifndef WITHMAIN
|
||||
{
|
||||
int action, reqbufsize, reqsize;
|
||||
reqbufsize = BUFSIZE;
|
||||
reqsize = (int)strlen((char *)buf) + 1;
|
||||
|
||||
action = handlehdrfilterscli(param, &buf, &reqbufsize, 0, &reqsize);
|
||||
if(action == HANDLED){
|
||||
RETURN(0);
|
||||
}
|
||||
if(action != PASS) RETURN(880);
|
||||
}
|
||||
#endif
|
||||
if(clidatasock == INVALID_SOCKET) { RETURN (829);}
|
||||
if(pasv){
|
||||
|
||||
memset(&fds, 0, sizeof(fds));
|
||||
fds.fd = clidatasock;
|
||||
fds.events = POLLIN;
|
||||
|
||||
res = so._poll (&fds, 1, conf.timeouts[STRING_L]*1000);
|
||||
if(res != 1) {
|
||||
RETURN(857);
|
||||
}
|
||||
sasize = sizeof(param->sincr);
|
||||
ss = so._accept(clidatasock, (struct sockaddr *)¶m->sincr, &sasize);
|
||||
if (ss == INVALID_SOCKET) { RETURN (858);}
|
||||
so._shutdown(clidatasock, SHUT_RDWR);
|
||||
so._closesocket(clidatasock);
|
||||
clidatasock = ss;
|
||||
ss = INVALID_SOCKET;
|
||||
}
|
||||
if(clidatasock == INVALID_SOCKET){RETURN(828);}
|
||||
req = mystrdup((char *)buf);
|
||||
buf[4] = 0;
|
||||
status = 3;
|
||||
ss = ftpcommand(param, buf, arg? buf+5 : NULL);
|
||||
if (ss == INVALID_SOCKET) {
|
||||
so._shutdown(clidatasock, SHUT_RDWR);
|
||||
so._closesocket(clidatasock);
|
||||
clidatasock = INVALID_SOCKET;
|
||||
|
||||
if(socksend(param->ctrlsock, (unsigned char *)"550 err\r\n", 9, conf.timeouts[STRING_S])!=9) {RETURN (831);}
|
||||
continue;
|
||||
}
|
||||
|
||||
if(socksend(param->ctrlsock, (unsigned char *)"125 data\r\n", 10, conf.timeouts[STRING_S]) != 10) {
|
||||
param->remsock = INVALID_SOCKET;
|
||||
RETURN (832);
|
||||
}
|
||||
if(param->srvoffset < param->srvinbuf)while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', 0)) > 3){
|
||||
if(socksend(param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN(833);}
|
||||
if(isnumber(*buf) && buf[3] != '-') {
|
||||
ressent = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sc = param->remsock;
|
||||
param->remsock = ss;
|
||||
so._setsockopt(param->remsock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
||||
so._setsockopt(clidatasock, SOL_SOCKET, SO_LINGER, (char *)&lg, sizeof(lg));
|
||||
param->clisock = clidatasock;
|
||||
res = sockmap(param, conf.timeouts[CONNECTION_S]);
|
||||
if(param->remsock != INVALID_SOCKET) {
|
||||
so._shutdown (param->remsock, SHUT_RDWR);
|
||||
so._closesocket(param->remsock);
|
||||
}
|
||||
if(param->clisock != INVALID_SOCKET) {
|
||||
so._shutdown (param->clisock, SHUT_RDWR);
|
||||
so._closesocket(param->clisock);
|
||||
}
|
||||
param->clisock = param->ctrlsock;
|
||||
param->remsock = sc;
|
||||
sc = INVALID_SOCKET;
|
||||
ss = INVALID_SOCKET;
|
||||
clidatasock = INVALID_SOCKET;
|
||||
if(!ressent){
|
||||
while((i = sockgetlinebuf(param, SERVER, buf, BUFSIZE, '\n', conf.timeouts[STRING_L])) > 3){
|
||||
if(socksend(param->ctrlsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN(833);}
|
||||
if(isnumber(*buf) && buf[3] != '-') break;
|
||||
}
|
||||
if(i < 3) {RETURN(834);}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(status < 3) {
|
||||
if(socksend(param->remsock, (unsigned char *)"530 login\r\n", 11, conf.timeouts[STRING_S])!=1) {RETURN (810);}
|
||||
continue;
|
||||
}
|
||||
if(!strncasecmp((char *)buf, "QUIT", 4)) status = 5;
|
||||
if(!strncasecmp((char *)buf, "CWD ", 4)) req = mystrdup((char *)buf);
|
||||
i = (int)strlen((char *)buf);
|
||||
buf[i++] = '\r';
|
||||
buf[i++] = '\n';
|
||||
if(socksend(param->remsock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (811);}
|
||||
param->statscli64+=(i);
|
||||
param->nwrites++;
|
||||
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(i > 4 && isnumber(*buf) && buf[3] != '-') break;
|
||||
}
|
||||
if(status == 5) {RETURN (0);}
|
||||
if(i < 3) {RETURN (813);}
|
||||
}
|
||||
sasize = sizeof(param->sincr);
|
||||
if(so._getpeername(param->ctrlsock, (struct sockaddr *)¶m->sincr, &sasize)){RETURN(819);}
|
||||
if(req && (param->statscli64 || param->statssrv64)){
|
||||
(*param->srv->logfunc)(param, (unsigned char *)req);
|
||||
}
|
||||
}
|
||||
|
||||
CLEANRET:
|
||||
|
||||
if(sc != INVALID_SOCKET) {
|
||||
so._shutdown(sc, SHUT_RDWR);
|
||||
so._closesocket(sc);
|
||||
}
|
||||
if(ss != INVALID_SOCKET) {
|
||||
so._shutdown(ss, SHUT_RDWR);
|
||||
so._closesocket(ss);
|
||||
}
|
||||
if(clidatasock != INVALID_SOCKET) {
|
||||
so._shutdown(clidatasock, SHUT_RDWR);
|
||||
so._closesocket(clidatasock);
|
||||
}
|
||||
sasize = sizeof(param->sincr);
|
||||
so._getpeername(param->ctrlsock, (struct sockaddr *)¶m->sincr, &sasize);
|
||||
if(param->res != 0 || param->statscli64 || param->statssrv64 ){
|
||||
(*param->srv->logfunc)(param, (unsigned char *)((req && (param->res > 802))? req:NULL));
|
||||
}
|
||||
if(req) myfree(req);
|
||||
if(buf) myfree(buf);
|
||||
freeparam(param);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#ifdef WITHMAIN
|
||||
struct proxydef childdef = {
|
||||
ftpprchild,
|
||||
21,
|
||||
0,
|
||||
S_FTPPR,
|
||||
" -hdefault_host[:port] - use this host and port as default if no host specified\n"
|
||||
};
|
||||
#include "proxymain.c"
|
||||
#endif
|
529
src/icqpr.c
529
src/icqpr.c
@ -1,529 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
|
||||
#include "proxy.h"
|
||||
|
||||
#ifndef PORTMAP
|
||||
#define PORTMAP
|
||||
#endif
|
||||
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
||||
|
||||
static void hexdump(unsigned char *data, int len){
|
||||
for(; len; data++, len--){
|
||||
printf("%02x", (unsigned)*data);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
struct flap_header {
|
||||
unsigned char id;
|
||||
unsigned char chan;
|
||||
unsigned short seq;
|
||||
unsigned short size;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
struct snack_header {
|
||||
unsigned family;
|
||||
unsigned short flags;
|
||||
unsigned id;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
struct tlv_header {
|
||||
unsigned short type;
|
||||
unsigned short size;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
|
||||
typedef enum {
|
||||
ONBEGIN = 0,
|
||||
ONCHAN,
|
||||
ONSEQ1,
|
||||
ONSEQ2,
|
||||
ONSIZE1,
|
||||
ONSIZE2,
|
||||
ONDATA
|
||||
} ICQSTATE;
|
||||
|
||||
struct icqstate {
|
||||
ICQSTATE state;
|
||||
int leftinstate;
|
||||
unsigned short seq;
|
||||
unsigned short srvseq;
|
||||
unsigned short gotseq;
|
||||
unsigned short resyncseq;
|
||||
char channel;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
ICQUNKNOWN,
|
||||
ICQCLEAR,
|
||||
ICQMD5,
|
||||
ICQCOOKIE
|
||||
} LOGINTYPE;
|
||||
|
||||
|
||||
struct icq_cookie {
|
||||
struct icq_cookie *next;
|
||||
char *id;
|
||||
int size;
|
||||
char * cookie;
|
||||
char * connectstring;
|
||||
};
|
||||
|
||||
static struct icq_cookie *icq_cookies = NULL;
|
||||
pthread_mutex_t icq_cookie_mutex;
|
||||
int icq_cookie_mutex_init = 0;
|
||||
|
||||
|
||||
static void icq_clear(void *fo){
|
||||
};
|
||||
|
||||
static void addbuffer(int increment, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int * length_p){
|
||||
int bufsize = *length_p + increment + 40;
|
||||
unsigned char *newbuf;
|
||||
int len = 0;
|
||||
|
||||
|
||||
if(bufsize > *bufsize_p){
|
||||
newbuf = myalloc(bufsize);
|
||||
if(!newbuf) return;
|
||||
memcpy(newbuf, *buf_p, *length_p);
|
||||
myfree(*buf_p);
|
||||
*buf_p = newbuf;
|
||||
*bufsize_p = bufsize;
|
||||
}
|
||||
if(increment) len = sockrecvfrom(param->remsock, (struct sockaddr *)¶m->sinsr, *buf_p + *length_p, increment, conf.timeouts[STRING_S]*1000);
|
||||
if(len > 0) {
|
||||
*length_p += len;
|
||||
param->nreads++;
|
||||
param->statssrv64 += len;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int searchcookie(struct clientparam *param, struct flap_header * flap, int len, int * dif, struct tlv_header *tlv, int extra){
|
||||
struct icq_cookie *ic;
|
||||
char smallbuf[64];
|
||||
struct tlv_header *bostlv = NULL;
|
||||
struct sockaddr_in sa;
|
||||
SASIZETYPE size = sizeof(sa);
|
||||
int movelen = 0;
|
||||
|
||||
if(!icq_cookie_mutex_init){
|
||||
pthread_mutex_init(&icq_cookie_mutex, NULL);
|
||||
icq_cookie_mutex_init = 1;
|
||||
}
|
||||
pthread_mutex_lock(&icq_cookie_mutex);
|
||||
for(ic = icq_cookies; ic; ic = ic->next)if(!strcmp((char *)param->username, ic->id))break;
|
||||
if(!ic){
|
||||
ic = myalloc(sizeof(struct icq_cookie));
|
||||
memset(ic, 0, sizeof(struct icq_cookie));
|
||||
ic->id = mystrdup((char *)param->username);
|
||||
ic->next = icq_cookies;
|
||||
icq_cookies = ic;
|
||||
}
|
||||
for(; ntohs(tlv->size) < 65500 && len >= (ntohs(tlv->size) + 4); len -= (ntohs(tlv->size) + 4), tlv = (struct tlv_header *)(tlv->data + ntohs(tlv->size))){
|
||||
if(ntohs(tlv->type) == 0x0006){
|
||||
if(ic->cookie)myfree(ic->cookie);
|
||||
ic->cookie = myalloc(ntohs(tlv->size));
|
||||
memcpy(ic->cookie, tlv->data, ntohs(tlv->size));
|
||||
ic->size = tlv->size;
|
||||
}
|
||||
else if(ntohs(tlv->type) == 0x0005){
|
||||
if(ic->connectstring)myfree(ic->connectstring);
|
||||
ic->connectstring = myalloc(ntohs(tlv->size)+1);
|
||||
memcpy(ic->connectstring, tlv->data, ntohs(tlv->size));
|
||||
ic->connectstring[ntohs(tlv->size)] = 0;
|
||||
bostlv = tlv;
|
||||
movelen = extra + (len - 4) - ntohs(bostlv->size);
|
||||
}
|
||||
|
||||
}
|
||||
if(!ic->connectstring || !ic->cookie){
|
||||
if(ic->cookie)myfree(ic->cookie);
|
||||
if(ic->connectstring)myfree(ic->connectstring);
|
||||
ic->cookie = NULL;
|
||||
ic->connectstring = NULL;
|
||||
ic->size = 0;
|
||||
bostlv = NULL;
|
||||
}
|
||||
pthread_mutex_unlock(&icq_cookie_mutex);
|
||||
if(bostlv){
|
||||
if(so._getsockname(param->clisock, (struct sockaddr *)&sa, &size)==-1) return 1;
|
||||
len = myinet_ntop(*SAFAMILY(&sa),SAADDR(&sa), smallbuf, 64);
|
||||
if(strchr(ic->connectstring, ':'))sprintf(smallbuf+len, ":%hu", ntohs(sa.sin_port));
|
||||
len = (int)strlen(smallbuf);
|
||||
*dif = len - (int)ntohs(bostlv->size);
|
||||
if(*dif != 0 && movelen > 0){
|
||||
memmove(bostlv->data + len, bostlv->data + ntohs(bostlv->size), movelen);
|
||||
}
|
||||
memcpy(bostlv->data, smallbuf, len);
|
||||
bostlv->size = htons(len);
|
||||
len = ((int)ntohs(flap->size)) + *dif;
|
||||
flap->size = htons(len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static FILTER_ACTION icq_srv(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int ioffset, int * length_p){
|
||||
unsigned char * start = *buf_p + ioffset;
|
||||
int len = *length_p - ioffset;
|
||||
struct icqstate *state = (struct icqstate *)fc;
|
||||
int size;
|
||||
int offset;
|
||||
|
||||
while (len > 0){
|
||||
switch(state->state){
|
||||
case ONBEGIN:
|
||||
|
||||
if((*start) == 0x2A) {
|
||||
if(len < 6){
|
||||
offset = (int)(start - *buf_p);
|
||||
addbuffer(6-len, param, buf_p, bufsize_p, length_p);
|
||||
start = *buf_p + offset;
|
||||
len = (int)(*buf_p + *length_p - start);
|
||||
|
||||
}
|
||||
state->state = ONCHAN;
|
||||
}
|
||||
else {
|
||||
if(!state->leftinstate)param->srv->logfunc(param, (unsigned char *)"Warning: need resync");
|
||||
state->leftinstate++;
|
||||
if(state->leftinstate > 65535){
|
||||
param->srv->logfunc(param, (unsigned char *)"Out of Sync");
|
||||
return REJECT;
|
||||
}
|
||||
}
|
||||
start++;
|
||||
len--;
|
||||
break;
|
||||
case ONCHAN:
|
||||
if (*start >= 10){
|
||||
param->srv->logfunc(param, (unsigned char *)"Warning: Wrong channel");
|
||||
state->state = ONBEGIN;
|
||||
}
|
||||
else {
|
||||
state->state = ONSEQ1;
|
||||
state->channel = *start;
|
||||
start++;
|
||||
len--;
|
||||
}
|
||||
break;
|
||||
case ONSEQ1:
|
||||
state->gotseq = (((unsigned)*start) << 8);
|
||||
state->state = ONSEQ2;
|
||||
*(start) = (state->seq>>8);
|
||||
start++;
|
||||
len--;
|
||||
break;
|
||||
case ONSEQ2:
|
||||
state->gotseq += *start;
|
||||
if(state->gotseq != state->srvseq){
|
||||
unsigned char smallbuf[64];
|
||||
if(((state->gotseq < state->srvseq) || ((state->gotseq - state->srvseq) > 10 )) && (!state->resyncseq || state->gotseq != state->resyncseq)){
|
||||
sprintf((char *)smallbuf, "Warning: Wrong sequence, expected: %04hx got: %04hx", state->srvseq, state->gotseq);
|
||||
param->srv->logfunc(param, smallbuf);
|
||||
state->state = ONBEGIN;
|
||||
state->resyncseq = state->gotseq;
|
||||
break;
|
||||
}
|
||||
sprintf((char *)smallbuf, "Warning: %d flaps are lost on resync", state->gotseq - state->srvseq );
|
||||
param->srv->logfunc(param, smallbuf);
|
||||
state->srvseq = state->gotseq;
|
||||
*(start-1) = (state->seq>>8);
|
||||
}
|
||||
*start = (state->seq & 0x00FF);
|
||||
state->srvseq = state->srvseq + 1;
|
||||
state->seq = state->seq + 1;
|
||||
state->state = ONSIZE1;
|
||||
start++;
|
||||
len--;
|
||||
break;
|
||||
case ONSIZE1:
|
||||
state->leftinstate = (((unsigned)(*start))<<8);
|
||||
state->state = ONSIZE2;
|
||||
start++;
|
||||
len--;
|
||||
break;
|
||||
case ONSIZE2:
|
||||
state->leftinstate += *start;
|
||||
state->state = (state->leftinstate)?ONDATA:ONBEGIN;
|
||||
start++;
|
||||
len--;
|
||||
if(state->leftinstate > 30 && state->channel == 2) {
|
||||
|
||||
if(len < state->leftinstate) {
|
||||
offset = (int)(start - *buf_p);
|
||||
addbuffer(state->leftinstate - len, param, buf_p, bufsize_p, length_p);
|
||||
start = *buf_p + offset;
|
||||
len = (int)(*length_p - offset);
|
||||
|
||||
}
|
||||
size = 0;
|
||||
if ((start[4] & 0x80)) {
|
||||
size = htons(*(unsigned short *)(start+10)) + 2;
|
||||
if(size > 8) size = 0;
|
||||
}
|
||||
if (start[0] == 0 && start[1] == 1 &&
|
||||
((start[2] == 0 && start[3] == 5) || (start[2] == 1 && start[3] == 2))){
|
||||
int dif = 0;
|
||||
|
||||
offset = (int)(start - *buf_p);
|
||||
addbuffer(0, param, buf_p, bufsize_p, length_p);
|
||||
start = *buf_p + offset;
|
||||
searchcookie(param, (struct flap_header *) (start-6), state->leftinstate-(size+10), &dif, (struct tlv_header *) (start + size + 10), len - state->leftinstate);
|
||||
*length_p += dif;
|
||||
start += (state->leftinstate + dif);
|
||||
len -= state->leftinstate;
|
||||
state->leftinstate = 0;
|
||||
state->state = ONBEGIN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ONDATA:
|
||||
size = (state->leftinstate > len)? len : state->leftinstate;
|
||||
|
||||
start += size;
|
||||
len -= size;
|
||||
state->leftinstate -= size;
|
||||
if(!state->leftinstate) {
|
||||
state->state = ONBEGIN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
static struct filter icqfilter = {
|
||||
NULL,
|
||||
"icqfilter",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
*icq_srv,
|
||||
*icq_clear,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static int readflap(struct clientparam * param, int direction, unsigned char *buf, int buflen){
|
||||
int i, len;
|
||||
|
||||
struct flap_header *flap = (struct flap_header *)buf;
|
||||
|
||||
i = sockgetlinebuf(param, direction, buf, 6, EOF, conf.timeouts[STRING_L]);
|
||||
if(i!=6) return 1;
|
||||
if(flap->id != 0x2a) return 2;
|
||||
len = ntohs(flap->size);
|
||||
if(len > buflen-6) return 3;
|
||||
i = sockgetlinebuf(param, direction, (unsigned char *)flap->data, len, EOF, conf.timeouts[STRING_S]);
|
||||
if(len != i) return 4;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#define flap ((struct flap_header *)buf)
|
||||
#define snack ((struct snack_header *)(buf+6))
|
||||
void * icqprchild(struct clientparam* param) {
|
||||
int res;
|
||||
unsigned char tmpsend[1024];
|
||||
unsigned char *buf;
|
||||
int i,j,len,len1;
|
||||
int offset = 0;
|
||||
int buflen = 16384;
|
||||
LOGINTYPE logintype = ICQUNKNOWN;
|
||||
int greet = 0;
|
||||
struct icq_cookie *ic;
|
||||
struct tlv_header *tlv;
|
||||
struct icqstate mystate = {
|
||||
ONBEGIN,
|
||||
0, 0, 0,
|
||||
0
|
||||
};
|
||||
struct filterp icqfilterp = {
|
||||
&icqfilter,
|
||||
(void *)&mystate
|
||||
};
|
||||
struct filterp **newfilters;
|
||||
char handshake[] = {'\052', '\001', '\000', '\000', '\000', '\004', '\000', '\000', '\000', '\001'};
|
||||
|
||||
|
||||
|
||||
memcpy(tmpsend, handshake, 10);
|
||||
if(socksend(param->clisock, tmpsend, 10, conf.timeouts[STRING_S])!=10) {RETURN (1101);}
|
||||
buf = myalloc(65600);
|
||||
|
||||
if((res = readflap(param, CLIENT, buf, 1000))) {RETURN (1180 + res);}
|
||||
if(ntohs(flap->size) == 4 || ntohs(flap->size) == 12){
|
||||
tmpsend[2] = buf[2];
|
||||
tmpsend[3] = buf[3];
|
||||
greet = 1;
|
||||
if(readflap(param, CLIENT, buf, 65550)) {RETURN (110);}
|
||||
}
|
||||
if(flap->chan != 1 && (flap->chan != 2 || snack->family != htonl(0x00170006))){
|
||||
RETURN(1104);
|
||||
}
|
||||
|
||||
len = ntohs(flap->size);
|
||||
if(flap->chan == 1){
|
||||
tlv = (struct tlv_header *)(flap->data + 4);
|
||||
len -= 4;
|
||||
}
|
||||
else {
|
||||
tlv = (struct tlv_header *)(flap->data + 10);
|
||||
len -= 10;
|
||||
}
|
||||
|
||||
for(; len >= (ntohs(tlv->size) + 4); len -= (ntohs(tlv->size) + 4), tlv = (struct tlv_header *)(tlv->data + ntohs(tlv->size))){
|
||||
switch(ntohs(tlv->type)){
|
||||
case 0x0001:
|
||||
if(flap->chan == 2 && !logintype)logintype = ICQMD5;
|
||||
if(!param->username){
|
||||
param->username = myalloc(ntohs(tlv->size) + 1);
|
||||
for(i=0, j=0; i < ntohs(tlv->size); i++){
|
||||
if(!isspace(tlv->data[i]))param->username[j++]=tolower(tlv->data[i]);
|
||||
}
|
||||
param->username[j] = 0;
|
||||
}
|
||||
break;
|
||||
case 0x0002:
|
||||
logintype = ICQCLEAR;
|
||||
break;
|
||||
case 0x0006:
|
||||
logintype = ICQCOOKIE;
|
||||
|
||||
for(ic = icq_cookies; ic; ic=ic->next){
|
||||
if(ic->size && ic->size == tlv->size && !memcmp(ic->cookie, tlv->data, ntohs(tlv->size))){
|
||||
parsehostname((char *)ic->connectstring, param, ntohs(param->srv->targetport));
|
||||
if(!param->username && ic->id) param->username = (unsigned char *)mystrdup(ic->id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!ic) RETURN(1132);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!logintype) RETURN(1133);
|
||||
if(logintype != ICQCOOKIE) {
|
||||
parsehostname((char *)param->srv->target, param, ntohs(param->srv->targetport));
|
||||
}
|
||||
param->operation = CONNECT;
|
||||
res = (*param->srv->authfunc)(param);
|
||||
if(res) {RETURN(res);}
|
||||
|
||||
if(greet){
|
||||
if(socksend(param->remsock, tmpsend, 10, conf.timeouts[STRING_S])!=10) {RETURN (1105);}
|
||||
param->statscli64 += 10;
|
||||
}
|
||||
if(readflap(param, SERVER, tmpsend, 1024)) {RETURN (1111);}
|
||||
param->statssrv64 += (ntohs(((struct flap_header *)tmpsend)->size) + 6);
|
||||
mystate.srvseq = ntohs(((struct flap_header *)tmpsend)->seq) + 1;
|
||||
mystate.seq = 1;
|
||||
len = ntohs(flap->size) + 6;
|
||||
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);}
|
||||
offset = 0;
|
||||
param->statscli64 += len;
|
||||
|
||||
if(logintype == ICQMD5) {
|
||||
if(readflap(param, SERVER, buf, 65550)) {RETURN (1112);}
|
||||
mystate.srvseq = ntohs(flap->seq) + 1;
|
||||
flap->seq = htons(mystate.seq);
|
||||
mystate.seq++;
|
||||
len = ntohs(flap->size) + 6;
|
||||
if((res=handledatfltsrv(param, &buf, &buflen, offset, &len))!=PASS) RETURN(res);
|
||||
if(socksend(param->clisock, buf+offset, len, conf.timeouts[STRING_S])!=len) {RETURN (1113);}
|
||||
offset = 0;
|
||||
|
||||
if(readflap(param, CLIENT, buf, 65550)) {RETURN (1114);}
|
||||
len = ntohs(flap->size) + 6;
|
||||
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);}
|
||||
param->statscli64 += len;
|
||||
offset = 0;
|
||||
}
|
||||
if(logintype != ICQCOOKIE) {
|
||||
if(readflap(param, SERVER, buf, 65550)) {RETURN (1116);}
|
||||
mystate.srvseq = ntohs(flap->seq) + 1;
|
||||
flap->seq = htons(mystate.seq);
|
||||
mystate.seq++;
|
||||
len = ntohs(flap->size);
|
||||
|
||||
if(!param->username) {RETURN (1117);}
|
||||
if(flap->chan == 1 || flap->chan == 4){
|
||||
if(flap->data[0] == 0 && flap->data[1] == 0 && flap->data[2] == 0 && flap->data[3] == 1){
|
||||
tlv = (struct tlv_header *)(flap->data + 4);
|
||||
len -= 4;
|
||||
}
|
||||
else
|
||||
tlv = (struct tlv_header *)(flap->data);
|
||||
}
|
||||
else {
|
||||
tlv = (struct tlv_header *)(flap->data + 10);
|
||||
len -= 10;
|
||||
}
|
||||
|
||||
len1 = ntohs(flap->size);
|
||||
if(searchcookie(param, flap, len, &len1, tlv, 0)){RETURN (1118);}
|
||||
|
||||
len = ntohs(flap->size) + 6;
|
||||
if((res=handledatfltsrv(param, &buf, &buflen, offset, &len))!=PASS) RETURN(res);
|
||||
if(socksend(param->clisock, buf+offset, len, conf.timeouts[STRING_S])!=len) {RETURN (1117);}
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
param->ndatfilterssrv++;
|
||||
newfilters = myalloc(param->ndatfilterssrv * sizeof(struct filterp *));
|
||||
if(param->ndatfilterssrv > 1){
|
||||
memcpy(newfilters, param->datfilterssrv, (param->ndatfilterssrv - 1) * sizeof(struct filterp *));
|
||||
myfree(param->datfilterssrv);
|
||||
}
|
||||
param->datfilterssrv = newfilters;
|
||||
newfilters[param->ndatfilterssrv - 1] = &icqfilterp;
|
||||
|
||||
param->res = sockmap(param, conf.timeouts[CONNECTION_L]);
|
||||
|
||||
param->ndatfilterssrv--;
|
||||
|
||||
CLEANRET:
|
||||
|
||||
|
||||
(*param->srv->logfunc)(param, NULL);
|
||||
freeparam(param);
|
||||
if(buf) myfree(buf);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#ifdef WITHMAIN
|
||||
struct proxydef childdef = {
|
||||
icqprchild,
|
||||
0,
|
||||
0,
|
||||
S_ICQPR,
|
||||
""
|
||||
};
|
||||
#include "proxymain.c"
|
||||
#endif
|
199
src/mycrypt.c
199
src/mycrypt.c
@ -1,199 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
#include "libs/md5.h"
|
||||
#include "libs/md4.h"
|
||||
#include <string.h>
|
||||
|
||||
#define MD5_SIZE 16
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning (disable : 4996)
|
||||
#endif
|
||||
|
||||
|
||||
void tohex(unsigned char *in, unsigned char *out, int len);
|
||||
|
||||
static unsigned char itoa64[] =
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
void
|
||||
_crypt_to64(unsigned char *s, unsigned long v, int n)
|
||||
{
|
||||
while (--n >= 0) {
|
||||
*s++ = itoa64[v&0x3f];
|
||||
v >>= 6;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPassword, int ctohex)
|
||||
{
|
||||
unsigned char szUnicodePass[513];
|
||||
unsigned int nPasswordLen;
|
||||
MD4_CTX ctx;
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* NT passwords are unicode. Convert plain text password
|
||||
* to unicode by inserting a zero every other byte
|
||||
*/
|
||||
nPasswordLen = (int)strlen((char *)szPassword);
|
||||
if(nPasswordLen > 255)nPasswordLen = 255;
|
||||
for (i = 0; i < nPasswordLen; i++) {
|
||||
szUnicodePass[i << 1] = szPassword[i];
|
||||
szUnicodePass[(i << 1) + 1] = 0;
|
||||
}
|
||||
|
||||
/* Encrypt Unicode password to a 16-byte MD4 hash */
|
||||
MD4Init(&ctx);
|
||||
MD4Update(&ctx, szUnicodePass, (nPasswordLen<<1));
|
||||
MD4Final(szUnicodePass, &ctx);
|
||||
if (ctohex){
|
||||
tohex(szUnicodePass, szHash, 16);
|
||||
}
|
||||
else memcpy(szHash, szUnicodePass, 16);
|
||||
return szHash;
|
||||
}
|
||||
|
||||
|
||||
unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsigned char *passwd){
|
||||
|
||||
const unsigned char *ep;
|
||||
if(salt[0] == '$' && salt[1] == '1' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
|
||||
static unsigned char *magic = (unsigned char *)"$1$";
|
||||
unsigned char *p;
|
||||
const unsigned char *sp;
|
||||
unsigned char final[MD5_SIZE];
|
||||
int sl,pl,i;
|
||||
MD5_CTX ctx,ctx1;
|
||||
unsigned long l;
|
||||
|
||||
/* Refine the Salt first */
|
||||
sp = salt +3;
|
||||
|
||||
/* get the length of the true salt */
|
||||
sl = (int)(ep - sp);
|
||||
|
||||
MD5Init(&ctx);
|
||||
|
||||
/* The password first, since that is what is most unknown */
|
||||
MD5Update(&ctx,pw,strlen((char *)pw));
|
||||
|
||||
/* Then our magic string */
|
||||
MD5Update(&ctx,magic,strlen((char *)magic));
|
||||
|
||||
/* Then the raw salt */
|
||||
MD5Update(&ctx,sp,sl);
|
||||
|
||||
/* Then just as many unsigned characters of the MD5(pw,salt,pw) */
|
||||
MD5Init(&ctx1);
|
||||
MD5Update(&ctx1,pw,strlen((char *)pw));
|
||||
MD5Update(&ctx1,sp,sl);
|
||||
MD5Update(&ctx1,pw,strlen((char *)pw));
|
||||
MD5Final(final,&ctx1);
|
||||
for(pl = (int)strlen((char *)pw); pl > 0; pl -= MD5_SIZE)
|
||||
MD5Update(&ctx,final,pl>MD5_SIZE ? MD5_SIZE : pl);
|
||||
|
||||
/* Don't leave anything around in vm they could use. */
|
||||
memset(final,0,sizeof final);
|
||||
|
||||
/* Then something really weird... */
|
||||
for (i = (int)strlen((char *)pw); i ; i >>= 1)
|
||||
if(i&1)
|
||||
MD5Update(&ctx, final, 1);
|
||||
else
|
||||
MD5Update(&ctx, pw, 1);
|
||||
|
||||
/* Now make the output string */
|
||||
strcpy((char *)passwd,(char *)magic);
|
||||
strncat((char *)passwd,(char *)sp,sl);
|
||||
strcat((char *)passwd,"$");
|
||||
|
||||
MD5Final(final,&ctx);
|
||||
|
||||
/*
|
||||
* and now, just to make sure things don't run too fast
|
||||
* On a 60 Mhz Pentium this takes 34 msec, so you would
|
||||
* need 30 seconds to build a 1000 entry dictionary...
|
||||
*/
|
||||
for(i=0;i<1000;i++) {
|
||||
MD5Init(&ctx1);
|
||||
if(i & 1)
|
||||
MD5Update(&ctx1,pw,strlen((char *)pw));
|
||||
else
|
||||
MD5Update(&ctx1,final,MD5_SIZE);
|
||||
|
||||
if(i % 3)
|
||||
MD5Update(&ctx1,sp,sl);
|
||||
|
||||
if(i % 7)
|
||||
MD5Update(&ctx1,pw,strlen((char *)pw));
|
||||
|
||||
if(i & 1)
|
||||
MD5Update(&ctx1,final,MD5_SIZE);
|
||||
else
|
||||
MD5Update(&ctx1,pw,strlen((char *)pw));
|
||||
MD5Final(final,&ctx1);
|
||||
}
|
||||
|
||||
p = passwd + strlen((char *)passwd);
|
||||
|
||||
l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];
|
||||
_crypt_to64(p,l,4); p += 4;
|
||||
l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];
|
||||
_crypt_to64(p,l,4); p += 4;
|
||||
l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];
|
||||
_crypt_to64(p,l,4); p += 4;
|
||||
l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];
|
||||
_crypt_to64(p,l,4); p += 4;
|
||||
l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];
|
||||
_crypt_to64(p,l,4); p += 4;
|
||||
l = final[11] ;
|
||||
_crypt_to64(p,l,2); p += 2;
|
||||
*p = '\0';
|
||||
|
||||
/* Don't leave anything around in vm they could use. */
|
||||
memset(final,0,sizeof final);
|
||||
}
|
||||
else {
|
||||
*passwd = 0;
|
||||
}
|
||||
return passwd;
|
||||
}
|
||||
|
||||
#ifdef WITHMAIN
|
||||
|
||||
#include <stdio.h>
|
||||
int main(int argc, char* argv[]){
|
||||
unsigned char buf[1024];
|
||||
unsigned i;
|
||||
if(argc < 2 || argc > 3) {
|
||||
fprintf(stderr, "usage: \n"
|
||||
"\t%s <password>\n"
|
||||
"\t%s <salt> <password>\n"
|
||||
"Performs NT crypt if no salt specified, MD5 crypt with salt\n"
|
||||
"This software uses:\n"
|
||||
" RSA Data Security, Inc. MD4 Message-Digest Algorithm\n"
|
||||
" RSA Data Security, Inc. MD5 Message-Digest Algorithm\n",
|
||||
argv[0],
|
||||
argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if(argc == 2) {
|
||||
printf("NT:%s\n", ntpwdhash(buf, (unsigned char *)argv[1], 1));
|
||||
}
|
||||
else {
|
||||
i = (int)strlen((char *)argv[1]);
|
||||
if (i > 64) argv[1][64] = 0;
|
||||
sprintf((char *)buf, "$1$%s$", argv[1]);
|
||||
printf("CR:%s\n", mycrypt((unsigned char *)argv[2], buf, buf+256));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
88
src/ntlm.c
88
src/ntlm.c
@ -1,88 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
|
||||
#include "proxy.h"
|
||||
struct ntlmchal {
|
||||
unsigned char sig[8];
|
||||
unsigned char messtype[4];
|
||||
unsigned char dom_len[2];
|
||||
unsigned char dom_max_len[2];
|
||||
unsigned char dom_offset[4];
|
||||
unsigned char flags[4];
|
||||
unsigned char challenge[8];
|
||||
unsigned char reserved[8];
|
||||
unsigned char addr_len[2];
|
||||
unsigned char addr_max_len[2];
|
||||
unsigned char addr_offset[4];
|
||||
unsigned char data[1];
|
||||
};
|
||||
|
||||
struct ntlmreq {
|
||||
unsigned char sig[8];
|
||||
unsigned char messtype[4];
|
||||
unsigned char flags[4];
|
||||
unsigned char dom_len[2];
|
||||
unsigned char dom_max_len[2];
|
||||
unsigned char dom_offset[4];
|
||||
unsigned char pad1[2];
|
||||
unsigned char host_len[2];
|
||||
unsigned char host_max_len[2];
|
||||
unsigned char host_offset[4];
|
||||
unsigned char pad2[2];
|
||||
unsigned char data[1];
|
||||
};
|
||||
|
||||
int text2unicode(const char * text, char * buf, int buflen){
|
||||
int count = 0;
|
||||
buflen = ((buflen>>1)<<1);
|
||||
if(!text || !buflen) return 0;
|
||||
do {
|
||||
buf[count++] = toupper(*text++);
|
||||
buf[count++] = '\0';
|
||||
} while (*text && count < buflen);
|
||||
return count;
|
||||
}
|
||||
|
||||
void unicode2text(const char *unicode, char * buf, int len){
|
||||
int i;
|
||||
if(!unicode || !len) return;
|
||||
for(i=0; i<len; i++){
|
||||
buf[i] = unicode[(i<<1)];
|
||||
}
|
||||
buf[i] = 0;
|
||||
}
|
||||
|
||||
void genchallenge(struct clientparam *param, char * challenge, char *buf){
|
||||
struct ntlmchal *chal;
|
||||
char tmpbuf[1024];
|
||||
char hostname[128];
|
||||
int len, i;
|
||||
|
||||
|
||||
chal = (struct ntlmchal *)tmpbuf;
|
||||
memset(chal, 0, 1024);
|
||||
memcpy(chal->sig, "NTLMSSP", 8);
|
||||
chal->messtype[0] = 2;
|
||||
gethostname(hostname, 128);
|
||||
hostname[15] = 0;
|
||||
len = (((int)strlen(hostname)) << 1);
|
||||
chal->dom_len[0] = len;
|
||||
chal->dom_max_len[0] = len;
|
||||
chal->dom_offset[0] = (unsigned char)((unsigned char *)chal->data - (unsigned char *)chal);
|
||||
chal->flags[0] = 0x03;
|
||||
chal->flags[1] = 0x82;
|
||||
chal->flags[2] = 0x81;
|
||||
chal->flags[3] = 0xA0;
|
||||
text2unicode(hostname, (char *)chal->data, 64);
|
||||
time((time_t *)challenge);
|
||||
memcpy(challenge+4, SAADDR(¶m->sincr), 4);
|
||||
challenge[1]^=*SAPORT(¶m->sincr);
|
||||
for(i = 0; i < 8; i++) challenge[i] ^= myrand(challenge, 8);
|
||||
memcpy(chal->challenge, challenge, 8);
|
||||
en64((unsigned char *)tmpbuf, (unsigned char *)buf, (int)((unsigned char *)chal->data - (unsigned char *)chal) + len);
|
||||
}
|
142
src/plugins.c
142
src/plugins.c
@ -1,142 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2002-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
|
||||
#include "proxy.h"
|
||||
|
||||
unsigned bandlimitfunc(struct clientparam *param, unsigned nbytesin, unsigned nbytesout);
|
||||
void trafcountfunc(struct clientparam *param);
|
||||
int checkACL(struct clientparam * param);
|
||||
void nametohash(const unsigned char * name, unsigned char *hash);
|
||||
unsigned hashindex(const unsigned char* hash);
|
||||
void decodeurl(unsigned char *s, int allowcr);
|
||||
int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned char ** buff, int *inbuf, int *bufsize);
|
||||
struct ace * make_ace (int argc, unsigned char ** argv);
|
||||
extern char * proxy_stringtable[];
|
||||
extern char * admin_stringtable[];
|
||||
extern struct schedule * schedule;
|
||||
int start_proxy_thread(struct child * chp);
|
||||
|
||||
extern int linenum;
|
||||
extern char *conffile;
|
||||
|
||||
struct symbol symbols[] = {
|
||||
{symbols+1, "conf", (void *) &conf},
|
||||
{symbols+2, "socksend", (void *) socksend},
|
||||
{symbols+3, "socksendto", (void *) socksendto},
|
||||
{symbols+4, "sockrecvfrom", (void *) sockrecvfrom},
|
||||
{symbols+5, "sockgetcharcli", (void *) sockgetcharcli},
|
||||
{symbols+6, "sockgetcharsrv", (void *) sockgetcharsrv},
|
||||
{symbols+7, "sockgetlinebuf", (void *) sockgetlinebuf},
|
||||
{symbols+8, "myinet_ntop", (void *) myinet_ntop},
|
||||
{symbols+9, "dobuf", (void *) dobuf},
|
||||
{symbols+10, "scanaddr", (void *) scanaddr},
|
||||
{symbols+11, "getip46", (void *) getip46},
|
||||
{symbols+12, "sockmap", (void *) sockmap},
|
||||
{symbols+13, "sockfuncs", (void *) &so},
|
||||
{symbols+14, "ACLmatches", (void *) ACLmatches},
|
||||
{symbols+15, "bandlimitfunc", (void *) bandlimitfunc},
|
||||
{symbols+16, "trafcountfunc", (void *) trafcountfunc},
|
||||
{symbols+17, "alwaysauth", (void *) alwaysauth},
|
||||
{symbols+18, "ipauth", (void *) ipauth},
|
||||
{symbols+19, "strongauth", (void *) strongauth},
|
||||
{symbols+20, "checkACL", (void *) checkACL},
|
||||
{symbols+21, "nametohash", (void *) nametohash},
|
||||
{symbols+22, "hashindex", (void *) hashindex},
|
||||
{symbols+23, "nservers", (void *) nservers},
|
||||
{symbols+24, "udpresolve", (void *) udpresolve},
|
||||
{symbols+25, "bandlim_mutex", (void *) &bandlim_mutex},
|
||||
{symbols+26, "tc_mutex", (void *) &tc_mutex},
|
||||
{symbols+27, "hash_mutex", (void *) &hash_mutex},
|
||||
{symbols+28, "pwl_mutex", (void *) &pwl_mutex},
|
||||
{symbols+29, "linenum", (void *) &linenum},
|
||||
{symbols+30, "proxy_stringtable", (void *) proxy_stringtable},
|
||||
{symbols+31, "en64", (void *) en64},
|
||||
{symbols+32, "de64", (void *) de64},
|
||||
{symbols+33, "tohex", (void *) tohex},
|
||||
{symbols+34, "fromhex", (void *) fromhex},
|
||||
{symbols+35, "dnspr", (void *) dnsprchild},
|
||||
{symbols+36, "pop3p", (void *) pop3pchild},
|
||||
{symbols+37, "proxy", (void *) proxychild},
|
||||
{symbols+38, "socks", (void *) sockschild},
|
||||
{symbols+39, "tcppm", (void *) tcppmchild},
|
||||
{symbols+40, "udppm", (void *) udppmchild},
|
||||
{symbols+41, "admin", (void *) adminchild},
|
||||
{symbols+42, "ftppr", (void *) ftpprchild},
|
||||
{symbols+43, "smtpp", (void *) smtppchild},
|
||||
{symbols+44, "icqpr", (void *) icqprchild},
|
||||
/*
|
||||
{symbols+45, "msnpr", (void *) msnprchild},
|
||||
*/
|
||||
{symbols+45, "authfuncs", (void *) &authfuncs},
|
||||
{symbols+46, "commandhandlers", (void *) &commandhandlers},
|
||||
{symbols+47, "decodeurl", (void *) decodeurl},
|
||||
{symbols+48, "parsestr", (void *) parsestr},
|
||||
{symbols+49, "make_ace", (void *) make_ace},
|
||||
{symbols+50, "freeacl", (void *) freeacl},
|
||||
{NULL, "", NULL}
|
||||
};
|
||||
|
||||
static void * findbyname(const char *name){
|
||||
struct symbol * symbols;
|
||||
for(symbols = &pluginlink.symbols; symbols; symbols=symbols->next)
|
||||
if(!strcmp(symbols->name, name)) return symbols->value;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
struct pluginlink pluginlink = {
|
||||
{symbols, "", NULL},
|
||||
&conf,
|
||||
nservers,
|
||||
&linenum,
|
||||
authfuncs,
|
||||
commandhandlers,
|
||||
findbyname,
|
||||
socksend,
|
||||
socksendto,
|
||||
sockrecvfrom,
|
||||
sockgetcharcli,
|
||||
sockgetcharsrv,
|
||||
sockgetlinebuf,
|
||||
myinet_ntop,
|
||||
dobuf,
|
||||
dobuf2,
|
||||
scanaddr,
|
||||
getip46,
|
||||
sockmap,
|
||||
ACLmatches,
|
||||
alwaysauth,
|
||||
checkACL,
|
||||
nametohash,
|
||||
hashindex,
|
||||
en64,
|
||||
de64,
|
||||
tohex,
|
||||
fromhex,
|
||||
decodeurl,
|
||||
parsestr,
|
||||
make_ace,
|
||||
myalloc,
|
||||
myfree,
|
||||
myrealloc,
|
||||
mystrdup,
|
||||
trafcountfunc,
|
||||
proxy_stringtable,
|
||||
&schedule,
|
||||
freeacl,
|
||||
admin_stringtable,
|
||||
&childdef,
|
||||
start_proxy_thread,
|
||||
freeparam,
|
||||
parsehostname,
|
||||
parseusername,
|
||||
parseconnusername,
|
||||
&so,
|
||||
dologname
|
||||
};
|
||||
|
@ -1,917 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2007-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
|
||||
#include "../../structures.h"
|
||||
#include "FilePlugin.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#ifdef _WIN32
|
||||
#ifndef _WINCE
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <sys/unistd.h>
|
||||
#endif
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#define WINAPI
|
||||
#define fp_size_t size_t
|
||||
#else
|
||||
#define fp_size_t int
|
||||
#endif
|
||||
|
||||
static struct pluginlink * pl;
|
||||
|
||||
static pthread_mutex_t file_mutex;
|
||||
|
||||
unsigned long preview = 0;
|
||||
|
||||
char path[300];
|
||||
|
||||
static int counter = 0;
|
||||
static int timeo = 0;
|
||||
|
||||
static char * fp_stringtable[] = {
|
||||
/* 0 */ "HTTP/1.0 503 Service Unavailable\r\n"
|
||||
"Proxy-Connection: close\r\n"
|
||||
"Content-type: text/html; charset=us-ascii\r\n"
|
||||
"\r\n"
|
||||
"<html><head><title>503 Service Unavailable</title></head>\r\n"
|
||||
"<body><h2>503 Service Unavailable</h2><h3>HTTP policy violation: you have no permission to perform this action. Please conatct helpdesk or Administrator.</h3></body></html>\r\n",
|
||||
/* 1 */ "421 SMTP policy violation: you have no permission to perform this action. Please conatct helpdesk or Administrator.\r\n",
|
||||
/* 2 */ "421 FTP policy violation: you have no permission to perform this action. Please conatct helpdesk or Administrator.\r\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
enum states {
|
||||
STATE_INITIAL = 0,
|
||||
GOT_HTTP_REQUEST,
|
||||
GOT_HTTP_CLI_HDR,
|
||||
GOT_HTTP_SRV_HDR,
|
||||
GOT_HTTP_CLI_HDR2,
|
||||
GOT_HTTP_SRV_HDR2,
|
||||
GOT_HTTP_CLIDATA,
|
||||
GOT_HTTP_SRVDATA,
|
||||
GOT_SMTP_REQ,
|
||||
GOT_SMTP_DATA,
|
||||
GOT_FTP_REQ,
|
||||
GOT_FTP_CLIDATA,
|
||||
GOT_FTP_SRVDATA,
|
||||
FLUSH_DATA
|
||||
};
|
||||
|
||||
struct fp_callback {
|
||||
struct fp_callback *next;
|
||||
FP_CALLBACK callback;
|
||||
void * data;
|
||||
int what;
|
||||
int preview_size;
|
||||
int max_size;
|
||||
};
|
||||
|
||||
struct fp_stream {
|
||||
struct fp_stream *next;
|
||||
char * buf;
|
||||
int state;
|
||||
int what;
|
||||
int needsrvconnect;
|
||||
int preview_size;
|
||||
long bufsize;
|
||||
unsigned long clihdrwritten, clientwritten, clientsent, srvhdrwritten, serverwritten, serversent;
|
||||
struct fp_callback *callbacks;
|
||||
struct fp_filedata fpd;
|
||||
} *fp_streams = NULL;
|
||||
|
||||
struct sockfuncs sso;
|
||||
|
||||
|
||||
static void genpaths(struct fp_stream *fps){
|
||||
|
||||
if(fps->what & (FP_CLIDATA|FP_CLIHEADER)){
|
||||
if(fps->fpd.path_cli) free(fps->fpd.path_cli);
|
||||
fps->fpd.path_cli = malloc(strlen(path) + 10);
|
||||
sprintf(fps->fpd.path_cli, path, counter++);
|
||||
}
|
||||
if(fps->what & (FP_SRVDATA|FP_SRVHEADER)){
|
||||
if(fps->fpd.path_srv) free(fps->fpd.path_srv);
|
||||
fps->fpd.path_srv = malloc(strlen(path) + 10);
|
||||
sprintf(fps->fpd.path_srv, path, counter++);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
#ifdef _WIN32
|
||||
HANDLE
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
initclientfile(struct fp_stream *fps){
|
||||
|
||||
fps->clientwritten = fps->clientsent = 0;
|
||||
#ifdef _WIN32
|
||||
if(fps->fpd.h_cli != INVALID_HANDLE_VALUE){
|
||||
CloseHandle(fps->fpd.h_cli);
|
||||
}
|
||||
fps->fpd.h_cli = CreateFile(fps->fpd.path_cli, GENERIC_READ | GENERIC_WRITE, (fps->what & FP_SHAREFILE)? FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE:0, NULL, CREATE_ALWAYS, (fps->what & (FP_KEEPFILE|FP_SHAREFILE))? FILE_ATTRIBUTE_TEMPORARY : FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
return fps->fpd.h_cli;
|
||||
#else
|
||||
if(fps->fpd.fd_cli != -1) close(fps->fpd.fd_cli);
|
||||
fps->fpd.fd_cli = open(fps->fpd.path_cli, O_BINARY|O_RDWR|O_CREAT|O_TRUNC, 0600);
|
||||
return fps->fpd.fd_cli;
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
#ifdef _WIN32
|
||||
HANDLE
|
||||
#else
|
||||
int
|
||||
#endif
|
||||
initserverfile(struct fp_stream *fps){
|
||||
fps->serverwritten = fps->serversent = 0;
|
||||
#ifdef _WIN32
|
||||
if(fps->fpd.h_srv != INVALID_HANDLE_VALUE){
|
||||
CloseHandle(fps->fpd.h_srv);
|
||||
}
|
||||
fps->fpd.h_srv = CreateFile(fps->fpd.path_srv, GENERIC_READ | GENERIC_WRITE, (fps->what & FP_SHAREFILE)? FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE:0, NULL, CREATE_ALWAYS, (fps->what & (FP_KEEPFILE|FP_SHAREFILE))? FILE_ATTRIBUTE_TEMPORARY : FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
return fps->fpd.h_srv;
|
||||
#else
|
||||
if(fps->fpd.fd_srv != -1) close(fps->fpd.fd_srv);
|
||||
fps->fpd.fd_srv = open(fps->fpd.path_srv, O_BINARY|O_RDWR|O_CREAT|O_TRUNC, 0600);
|
||||
return fps->fpd.fd_srv;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void closefiles(struct fp_stream *fps){
|
||||
#ifdef _WIN32
|
||||
if(fps->fpd.h_cli != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(fps->fpd.h_cli);
|
||||
fps->fpd.h_cli = INVALID_HANDLE_VALUE;
|
||||
|
||||
if((fps->what & FP_SHAREFILE) && !(fps->what & FP_KEEPFILE)) DeleteFile(fps->fpd.path_cli);
|
||||
}
|
||||
if(fps->fpd.h_srv != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(fps->fpd.h_srv);
|
||||
fps->fpd.h_srv = INVALID_HANDLE_VALUE;
|
||||
|
||||
if((fps->what & FP_SHAREFILE) && !(fps->what & FP_KEEPFILE)) DeleteFile(fps->fpd.path_cli);
|
||||
}
|
||||
#else
|
||||
if(fps->fpd.fd_cli != -1) {
|
||||
close(fps->fpd.fd_cli);
|
||||
fps->fpd.fd_cli = -1;
|
||||
|
||||
if(!(fps->what & FP_KEEPFILE)) unlink(fps->fpd.path_cli);
|
||||
}
|
||||
if(fps->fpd.fd_srv != -1) {
|
||||
close(fps->fpd.fd_srv);
|
||||
fps->fpd.fd_srv = -1;
|
||||
if(!(fps->what & FP_KEEPFILE)) unlink(fps->fpd.path_srv);
|
||||
}
|
||||
#endif
|
||||
if(fps->fpd.path_cli) {
|
||||
free(fps->fpd.path_cli);
|
||||
fps->fpd.path_cli = NULL;
|
||||
}
|
||||
if(fps->fpd.path_srv) {
|
||||
free(fps->fpd.path_srv);
|
||||
fps->fpd.path_srv = NULL;
|
||||
}
|
||||
fps->clihdrwritten = fps->clientwritten = fps->clientsent = fps->srvhdrwritten = fps->serverwritten = fps->serversent = 0;
|
||||
}
|
||||
|
||||
static int searchsocket(SOCKET s, struct fp_stream **pfps){
|
||||
struct fp_stream *fps = NULL;
|
||||
int ret = 0;
|
||||
pthread_mutex_lock(&file_mutex);
|
||||
for(fps = fp_streams; fps; fps = fps->next){
|
||||
if(fps->fpd.cp->clisock == s) {
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
if(fps->fpd.cp->remsock == s) {
|
||||
ret = 2;
|
||||
break;
|
||||
}
|
||||
if(fps->fpd.cp->ctrlsock == s) {
|
||||
ret = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&file_mutex);
|
||||
*pfps = fps;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void freecallback(struct fp_stream * fps, struct fp_callback * fpc){
|
||||
if(fpc->next) freecallback(fps, fpc->next);
|
||||
if(fpc->what & FP_CALLONREMOVE) (*fpc->callback)(FP_CALLONREMOVE, fpc->data, &fps->fpd, NULL, 0);
|
||||
free(fpc);
|
||||
}
|
||||
|
||||
static void removefps(struct fp_stream * fps){
|
||||
if(!fp_streams) return;
|
||||
pthread_mutex_lock(&file_mutex);
|
||||
if(fp_streams == fps)fp_streams = fps->next;
|
||||
else {
|
||||
struct fp_stream *fps2;
|
||||
|
||||
for(fps2 = fp_streams; fps2->next; fps2 = fps2->next){
|
||||
if(fps2->next == fps){
|
||||
fps2->next = fps->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
pthread_mutex_unlock(&file_mutex);
|
||||
if(fps->callbacks){
|
||||
freecallback(fps, fps->callbacks);
|
||||
fps->callbacks = 0;
|
||||
}
|
||||
closefiles(fps);
|
||||
if(fps->buf) {
|
||||
free(fps->buf);
|
||||
fps->buf = NULL;
|
||||
}
|
||||
fps->state = 0;
|
||||
}
|
||||
|
||||
static int WINAPI fp_connect(SOCKET s, const struct sockaddr *name, fp_size_t namelen){
|
||||
return sso._connect(s, name, namelen);
|
||||
}
|
||||
|
||||
void processcallbacks(struct fp_stream *fps, int what, char *msg, int size){
|
||||
struct fp_callback *cb;
|
||||
int state;
|
||||
|
||||
state = fps->state;
|
||||
if(fps->what & what) {
|
||||
fps->what = 0;
|
||||
for(cb = fps->callbacks; cb; cb=cb->next){
|
||||
if(cb->what & what){
|
||||
cb->what = (*cb->callback)(what, cb->data, &(fps->fpd), msg, size);
|
||||
}
|
||||
fps->what |= cb->what;
|
||||
}
|
||||
}
|
||||
if(fps->what & FP_REJECT){
|
||||
switch(state){
|
||||
/*
|
||||
Fixme: handle different states
|
||||
*/
|
||||
case GOT_SMTP_REQ:
|
||||
case GOT_SMTP_DATA:
|
||||
fps->state = FLUSH_DATA;
|
||||
pl->socksend(fps->fpd.cp->clisock, fp_stringtable[1], (int)strlen(fp_stringtable[1]), pl->conf->timeouts[STRING_S]);
|
||||
fps->state = state;
|
||||
break;
|
||||
case GOT_HTTP_REQUEST:
|
||||
case GOT_HTTP_CLI_HDR:
|
||||
case GOT_HTTP_SRV_HDR:
|
||||
case GOT_HTTP_CLI_HDR2:
|
||||
case GOT_HTTP_SRV_HDR2:
|
||||
case GOT_HTTP_CLIDATA:
|
||||
case GOT_HTTP_SRVDATA:
|
||||
if(!fps->serversent){
|
||||
fps->state = FLUSH_DATA;
|
||||
pl->socksend(fps->fpd.cp->clisock, fp_stringtable[0], (int)strlen(fp_stringtable[0]), pl->conf->timeouts[STRING_S]);
|
||||
fps->state = state;
|
||||
}
|
||||
break;
|
||||
case GOT_FTP_CLIDATA:
|
||||
case GOT_FTP_REQ:
|
||||
case GOT_FTP_SRVDATA:
|
||||
fps->state = FLUSH_DATA;
|
||||
pl->socksend(fps->fpd.cp->ctrlsock, fp_stringtable[1], (int)strlen(fp_stringtable[1]), pl->conf->timeouts[STRING_S]);
|
||||
fps->state = state;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(fps->fpd.cp->remsock != INVALID_SOCKET)sso._closesocket(fps->fpd.cp->remsock);
|
||||
fps->fpd.cp->remsock = INVALID_SOCKET;
|
||||
if(fps->fpd.cp->clisock != INVALID_SOCKET)sso._closesocket(fps->fpd.cp->clisock);
|
||||
fps->fpd.cp->clisock = INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
static int copyfdtosock(struct fp_stream * fps, DIRECTION which, long len){
|
||||
int res;
|
||||
long toread;
|
||||
int state;
|
||||
#ifdef _WIN32
|
||||
HANDLE h;
|
||||
#else
|
||||
int fd;
|
||||
#endif
|
||||
SOCKET sock;
|
||||
long offset;
|
||||
int sendchunk = 0;
|
||||
|
||||
state = fps->state;
|
||||
fps->state = FLUSH_DATA;
|
||||
if(!fps->buf){
|
||||
fps->buf = malloc(2048);
|
||||
if(!fps->buf) return -2;
|
||||
fps->bufsize = 2048;
|
||||
}
|
||||
if(which == SERVER){
|
||||
offset = fps->clientsent;
|
||||
fps->clientsent += len;
|
||||
#ifdef _WIN32
|
||||
h = fps->fpd.h_cli;
|
||||
#else
|
||||
fd = fps->fpd.fd_cli;
|
||||
#endif
|
||||
sock = fps->fpd.cp->remsock;
|
||||
}
|
||||
else {
|
||||
if(fps->fpd.cp->chunked){
|
||||
if(fps->serversent < fps->srvhdrwritten && (fps->serversent + len) > fps->srvhdrwritten){
|
||||
len -= fps->srvhdrwritten - fps->serversent;
|
||||
if ((res = copyfdtosock(fps, which, fps->srvhdrwritten - fps->serversent))) return res;
|
||||
}
|
||||
if(fps->serversent >= fps->srvhdrwritten){
|
||||
sprintf(fps->buf, "%lx\r\n", len);
|
||||
sendchunk = (int)strlen(fps->buf);
|
||||
if(pl->socksend(fps->fpd.cp->clisock, fps->buf, sendchunk, pl->conf->timeouts[STRING_S]) != sendchunk){
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
}
|
||||
offset = fps->serversent;
|
||||
fps->serversent += len;
|
||||
#ifdef _WIN32
|
||||
h = fps->fpd.h_srv;
|
||||
#else
|
||||
fd = fps->fpd.fd_srv;
|
||||
#endif
|
||||
sock = fps->fpd.cp->clisock;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
if(SetFilePointer(h,offset,0,FILE_BEGIN)!=offset){
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if(lseek(fd, offset, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
while(len > 0){
|
||||
|
||||
|
||||
/*
|
||||
Fixme: prevent client/server timeouts
|
||||
*/
|
||||
toread = (len > fps->bufsize)? fps->bufsize:len;
|
||||
#ifdef _WIN32
|
||||
if(!ReadFile(h, fps->buf, (DWORD)toread,(DWORD *)&res,NULL)) {
|
||||
#else
|
||||
if((res = read(fd, fps->buf, toread)) <= 0) {
|
||||
#endif
|
||||
return -3;
|
||||
}
|
||||
if(pl->socksend(sock, fps->buf, res, pl->conf->timeouts[STRING_S]) != res) {
|
||||
return -4;
|
||||
}
|
||||
len -= res;
|
||||
}
|
||||
if(sendchunk){
|
||||
if(pl->socksend(sock, "\r\n", 2, pl->conf->timeouts[STRING_S]) != 2)
|
||||
return -4;
|
||||
}
|
||||
fps->state = state;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int WINAPI fp_poll(struct pollfd *fds, unsigned int nfds, int timeout){
|
||||
struct fp_stream *fps = NULL;
|
||||
int res;
|
||||
unsigned i;
|
||||
int to;
|
||||
|
||||
for(i = 0; i<nfds; i++){
|
||||
res = searchsocket(fds[i].fd, &fps);
|
||||
if(res == 2 && fps->state == GOT_SMTP_DATA){
|
||||
if(fds[i].events & POLLOUT){
|
||||
fds[i].revents = POLLOUT;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if(res == 2 && (((fps->what & FP_CLIHEADER) && (fps->state == GOT_HTTP_REQUEST || fps->state == GOT_HTTP_CLI_HDR2)) || ((fps->what & FP_CLIDATA) && fps->state == GOT_HTTP_CLIDATA))){
|
||||
|
||||
if(fds[i].events & POLLIN){
|
||||
processcallbacks(fps, (fps->state == GOT_HTTP_CLIDATA)?FP_CLIDATA:FP_CALLAFTERCLIHEADERS, NULL, 0);
|
||||
if(fps->clihdrwritten + fps->clientwritten > fps->clientsent) {
|
||||
if(copyfdtosock(fps, SERVER, (fps->clihdrwritten + fps->clientwritten) - fps->clientsent))
|
||||
return -2;
|
||||
}
|
||||
if(fps->state) {
|
||||
if(fps->what & FP_SRVHEADER) initserverfile(fps);
|
||||
fps->state = GOT_HTTP_SRV_HDR;
|
||||
}
|
||||
}
|
||||
|
||||
else if(fds[i].events & POLLOUT){
|
||||
fds[i].revents = POLLOUT;
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
else if(res == 1 && (fps->state == GOT_HTTP_SRVDATA || fps->state == GOT_HTTP_SRV_HDR || fps->state == GOT_HTTP_SRV_HDR2)&& (fds[i].events & POLLIN)){
|
||||
processcallbacks(fps, (fps->state == GOT_HTTP_SRVDATA)? FP_SRVDATA:FP_CALLAFTERSRVHEADERS, NULL, 0);
|
||||
if(fps->srvhdrwritten + fps->serverwritten > fps->serversent) {
|
||||
if(copyfdtosock(fps, CLIENT, (fps->srvhdrwritten + fps->serverwritten) - fps->serversent))
|
||||
return -2;
|
||||
}
|
||||
closefiles(fps);
|
||||
fps->state = 0;
|
||||
}
|
||||
|
||||
}
|
||||
return sso._poll(fds, nfds, timeout);
|
||||
}
|
||||
|
||||
static int WINAPI fp_send(SOCKET s, const char *msg, fp_size_t len, int flags){
|
||||
struct fp_stream *fps = NULL;
|
||||
int res;
|
||||
res = searchsocket(s, &fps);
|
||||
if(res == 2){
|
||||
if(fps->state == GOT_SMTP_DATA) {
|
||||
if(fps->clihdrwritten + fps->clientwritten > fps->clientsent) {
|
||||
processcallbacks(fps, FP_CLIDATA, NULL, 0);
|
||||
if(copyfdtosock(fps, SERVER, (fps->clihdrwritten + fps->clientwritten) - fps->clientsent)) {
|
||||
return -1;
|
||||
}
|
||||
fps->state = 0;
|
||||
}
|
||||
closefiles(fps);
|
||||
fps->state = 0;
|
||||
return sso._send(s, msg, len, flags);
|
||||
}
|
||||
if((((fps->what & FP_CLIHEADER) && (fps->state == GOT_HTTP_REQUEST || fps->state == GOT_HTTP_CLI_HDR2)) || ((fps->what & FP_CLIDATA) && fps->state == GOT_HTTP_CLIDATA))){
|
||||
#ifdef _WIN32
|
||||
if(SetFilePointer(fps->fpd.h_cli, fps->clientwritten + fps->clihdrwritten, 0, FILE_BEGIN) != (fps->clientwritten + fps->clihdrwritten)){
|
||||
return -1;
|
||||
}
|
||||
if(!WriteFile(fps->fpd.h_cli, msg, (DWORD)len,(DWORD *)&res,NULL) || res != len){
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if(lseek(fps->fpd.fd_cli, fps->clientwritten + fps->clihdrwritten, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if((res = write(fps->fpd.fd_cli, msg, len) != len)) return -1;
|
||||
#endif
|
||||
if(fps->state == GOT_HTTP_CLIDATA)fps->clientwritten += res;
|
||||
else fps->clihdrwritten += res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if(res == 1){
|
||||
if(((fps->what & FP_SRVDATA) && (fps->state == GOT_HTTP_SRVDATA || fps->state == GOT_HTTP_SRV_HDR) && fps->fpd.cp->chunked && len < 16 )){
|
||||
int hasnonzero = 0, i;
|
||||
|
||||
for(i=0; i < len; i++){
|
||||
char c = msg[i];
|
||||
|
||||
if(c == '\r' || c == '\n') continue;
|
||||
if((c<'0'|| c>'9') && (c<'A' || c>'F') && (c<'a' || c>'f')) {
|
||||
return sso._send(s, msg, len, flags);
|
||||
}
|
||||
if(c != '0') hasnonzero = 1;
|
||||
}
|
||||
if(i>2 && !hasnonzero){
|
||||
|
||||
if(fps->srvhdrwritten + fps->serverwritten > fps->serversent) {
|
||||
processcallbacks(fps, FP_SRVDATA, NULL, 0);
|
||||
if(copyfdtosock(fps, CLIENT, (fps->srvhdrwritten + fps->serverwritten) - fps->serversent)) {
|
||||
return -1;
|
||||
}
|
||||
fps->state = 0;
|
||||
}
|
||||
closefiles(fps);
|
||||
fps->state = 0;
|
||||
return sso._send(s, msg, len, flags);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
if(((fps->what & FP_SRVHEADER) && (fps->state == GOT_HTTP_SRV_HDR || fps->state == GOT_HTTP_SRV_HDR2))){
|
||||
#ifdef _WIN32
|
||||
if(SetFilePointer(fps->fpd.h_srv, fps->serverwritten + fps->srvhdrwritten, 0, FILE_BEGIN) != (fps->serverwritten + fps->srvhdrwritten)){
|
||||
return -1;
|
||||
}
|
||||
if(!WriteFile(fps->fpd.h_srv, msg, (DWORD)len,(DWORD *)&res,NULL) || res !=len){
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if(lseek(fps->fpd.fd_srv, fps->serverwritten + fps->srvhdrwritten, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if((res = write(fps->fpd.fd_srv, msg, len) != len)) return -1;
|
||||
#endif
|
||||
fps->srvhdrwritten += res;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return sso._send(s, msg, len, flags);
|
||||
}
|
||||
static int WINAPI fp_sendto(SOCKET s, const void *msg, int len, int flags, const struct sockaddr *to, fp_size_t tolen){
|
||||
struct fp_stream *fps = NULL;
|
||||
int res;
|
||||
res = searchsocket(s, &fps);
|
||||
if(res == 2) {
|
||||
switch(fps->state){
|
||||
case GOT_SMTP_REQ:
|
||||
if(!(fps->what & FP_CLIDATA)) break;
|
||||
fps->state = GOT_SMTP_DATA;
|
||||
initclientfile(fps);
|
||||
case GOT_FTP_REQ:
|
||||
if(fps->state == GOT_FTP_REQ){
|
||||
if(!(fps->what & FP_CLIDATA)) break;
|
||||
fps->state = GOT_FTP_CLIDATA;
|
||||
initclientfile(fps);
|
||||
}
|
||||
case GOT_HTTP_CLI_HDR2:
|
||||
if(fps->state == GOT_HTTP_CLI_HDR2){
|
||||
processcallbacks(fps, FP_CALLAFTERCLIHEADERS, NULL, 0);
|
||||
if ((fps->what & FP_REJECT)) return -1;
|
||||
if((fps->what & FP_CLIDATA) && !(fps->what & FP_CLIHEADER)) initclientfile(fps);
|
||||
else if(!(fps->what & FP_CLIDATA) && (fps->what & FP_CLIHEADER)){
|
||||
if(fps->clihdrwritten + fps->clientwritten > fps->clientsent) {
|
||||
if(copyfdtosock(fps, SERVER, (fps->clihdrwritten + fps->clientwritten) - fps->clientsent))
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
fps->state = GOT_HTTP_CLIDATA;
|
||||
}
|
||||
case GOT_HTTP_REQUEST:
|
||||
if(fps->state == GOT_HTTP_REQUEST && !(fps->what & FP_CLIHEADER)) break;
|
||||
case GOT_SMTP_DATA:
|
||||
case GOT_FTP_CLIDATA:
|
||||
case GOT_FTP_SRVDATA:
|
||||
case GOT_HTTP_CLIDATA:
|
||||
if((!fps->what & FP_CLIDATA)) break;
|
||||
#ifdef _WIN32
|
||||
if(SetFilePointer(fps->fpd.h_cli, fps->clientwritten + fps->clihdrwritten, 0, FILE_BEGIN) != (fps->clientwritten + fps->clihdrwritten)){
|
||||
return -1;
|
||||
}
|
||||
if(!WriteFile(fps->fpd.h_cli, msg, (DWORD)len,(DWORD *)&res,NULL) || res != len) {
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if(lseek(fps->fpd.fd_cli, fps->clientwritten + fps->clihdrwritten, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if((res = write(fps->fpd.fd_cli, msg, len) != len)) return -1;
|
||||
#endif
|
||||
if(fps->state == GOT_HTTP_REQUEST)fps->clihdrwritten += res;
|
||||
else fps->clientwritten += res;
|
||||
if(fps->preview_size && ((fps->clihdrwritten + fps->clientwritten) > (fps->clientsent + fps->preview_size))){
|
||||
if(!fps->clientsent){
|
||||
processcallbacks(fps, FP_PREVIEWCLI, NULL, 0);
|
||||
if ((fps->what & FP_REJECT)) return -1;
|
||||
}
|
||||
if(copyfdtosock(fps, SERVER, (fps->clihdrwritten + fps->clientwritten) - (fps->clientsent + fps->preview_size)))
|
||||
return -1;
|
||||
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
else if(res == 1){
|
||||
switch(fps->state){
|
||||
case GOT_HTTP_SRV_HDR2:
|
||||
processcallbacks(fps, FP_CALLAFTERSRVHEADERS, NULL, 0);
|
||||
if ((fps->what & FP_REJECT)) return REJECT;
|
||||
if((fps->what & FP_SRVDATA) && !(fps->what & FP_SRVHEADER)) initserverfile(fps);
|
||||
else if(!(fps->what & FP_SRVDATA) && (fps->what & FP_SRVHEADER)){
|
||||
if(fps->srvhdrwritten + fps->serverwritten > fps->serversent) {
|
||||
if(copyfdtosock(fps, CLIENT, (fps->srvhdrwritten + fps->serverwritten) - fps->serversent))
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
fps->state = GOT_HTTP_SRVDATA;
|
||||
case GOT_FTP_REQ:
|
||||
if(fps->state == GOT_FTP_REQ){
|
||||
if(!(fps->what & FP_SRVDATA)) break;
|
||||
fps->state = GOT_FTP_SRVDATA;
|
||||
initserverfile(fps);
|
||||
}
|
||||
case GOT_HTTP_SRV_HDR:
|
||||
if(fps->state == GOT_HTTP_SRV_HDR && !(fps->what & FP_SRVHEADER)) break;
|
||||
case GOT_HTTP_SRVDATA:
|
||||
case GOT_FTP_SRVDATA:
|
||||
case GOT_FTP_CLIDATA:
|
||||
if(!(fps->what & FP_SRVDATA)) break;
|
||||
#ifdef _WIN32
|
||||
if(SetFilePointer(fps->fpd.h_srv, fps->serverwritten + fps->srvhdrwritten, 0, FILE_BEGIN) != (fps->serverwritten + fps->srvhdrwritten)){
|
||||
return -1;
|
||||
}
|
||||
if(!WriteFile(fps->fpd.h_srv, msg, (DWORD)len,(DWORD *)&res,NULL) || res != len){
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if(lseek(fps->fpd.fd_srv, fps->serverwritten + fps->srvhdrwritten, SEEK_SET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if((res = write(fps->fpd.fd_srv, msg, len) != len)) return -1;
|
||||
#endif
|
||||
if(fps->state == GOT_HTTP_SRV_HDR)fps->srvhdrwritten += res;
|
||||
else fps->serverwritten += res;
|
||||
if(fps->preview_size && ((fps->srvhdrwritten + fps->serverwritten) > (fps->serversent + fps->preview_size))){
|
||||
if(!fps->serversent){
|
||||
processcallbacks(fps, FP_PREVIEWSRV, NULL, 0);
|
||||
if ((fps->what & FP_REJECT)) return -1;
|
||||
}
|
||||
if(copyfdtosock(fps, CLIENT, (fps->srvhdrwritten + fps->serverwritten) - (fps->serversent + fps->preview_size)))
|
||||
return -1;
|
||||
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return sso._sendto(s, msg, len, flags, to, tolen);
|
||||
}
|
||||
static int WINAPI fp_recv(SOCKET s, void *buf, fp_size_t len, int flags){
|
||||
return sso._recv(s, buf, len, flags);
|
||||
}
|
||||
static int WINAPI fp_recvfrom(SOCKET s, void * buf, fp_size_t len, int flags, struct sockaddr * from, fp_size_t * fromlen){
|
||||
return sso._recvfrom(s, buf, len, flags, from, fromlen);
|
||||
}
|
||||
static int WINAPI fp_shutdown(SOCKET s, int how){
|
||||
struct fp_stream *fps = NULL;
|
||||
|
||||
int res;
|
||||
res = searchsocket(s, &fps);
|
||||
if(res){
|
||||
if(fps->state == GOT_HTTP_SRV_HDR || fps->state == GOT_HTTP_SRVDATA || fps->state == GOT_FTP_SRVDATA){
|
||||
if(fps->srvhdrwritten + fps->serverwritten > fps->serversent) {
|
||||
processcallbacks(fps, FP_SRVDATA, NULL, 0);
|
||||
copyfdtosock(fps, CLIENT, (fps->srvhdrwritten + fps->serverwritten) - fps->serversent);
|
||||
}
|
||||
closefiles(fps);
|
||||
fps->state = 0;
|
||||
}
|
||||
else if(fps->state == GOT_FTP_CLIDATA){
|
||||
if(fps->clihdrwritten + fps->clientwritten > fps->clientsent) {
|
||||
processcallbacks(fps, FP_CLIDATA, NULL, 0);
|
||||
copyfdtosock(fps, SERVER, (fps->clihdrwritten + fps->clientwritten) - fps->clientsent);
|
||||
}
|
||||
closefiles(fps);
|
||||
fps->state = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return sso._shutdown(s, how);
|
||||
}
|
||||
static int WINAPI fp_closesocket(SOCKET s){
|
||||
return sso._closesocket(s);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct fp_stream * addfps(struct clientparam *cp){
|
||||
struct fp_stream *fps;
|
||||
|
||||
for(fps = fp_streams; fps && fps->fpd.cp != cp; fps = fps->next);
|
||||
if(!fps) {
|
||||
fps = malloc(sizeof(struct fp_stream));
|
||||
if(!fps){
|
||||
return NULL;
|
||||
}
|
||||
memset(fps, 0, sizeof(struct fp_stream));
|
||||
fps->fpd.cp = cp;
|
||||
fps->next = fp_streams;
|
||||
fp_streams = fps;
|
||||
#ifdef _WIN32
|
||||
fps->fpd.h_cli = fps->fpd.h_srv = INVALID_HANDLE_VALUE;
|
||||
#else
|
||||
fps->fpd.fd_cli = fps->fpd.fd_srv = -1;
|
||||
#endif
|
||||
}
|
||||
return fps;
|
||||
}
|
||||
|
||||
static int fp_registercallback (int what, int max_size, int preview_size, struct clientparam *cp, FP_CALLBACK cb, void *data){
|
||||
struct fp_callback * fpc;
|
||||
struct fp_stream *fps;
|
||||
|
||||
fpc = malloc(sizeof(struct fp_callback));
|
||||
if(!fpc) return 0;
|
||||
fpc->what = what;
|
||||
fpc->preview_size = preview_size;
|
||||
fpc->max_size = max_size;
|
||||
fpc->data = data;
|
||||
fpc->callback = cb;
|
||||
pthread_mutex_lock(&file_mutex);
|
||||
fps = addfps(cp);
|
||||
if(fps){
|
||||
fpc->next = fps->callbacks;
|
||||
fps->callbacks = fpc;
|
||||
fps->what |= fpc->what;
|
||||
if(preview_size > fps->preview_size) fps->preview_size = preview_size;
|
||||
}
|
||||
else free(fpc);
|
||||
pthread_mutex_unlock(&file_mutex);
|
||||
return fps?1:0;
|
||||
}
|
||||
|
||||
|
||||
static void * fp_open(void * idata, struct srvparam * param){
|
||||
return idata;
|
||||
}
|
||||
|
||||
|
||||
#define FC ((struct fp_stream *)fc)
|
||||
|
||||
static FILTER_ACTION fp_client(void *fo, struct clientparam * param, void** fc){
|
||||
|
||||
pthread_mutex_lock(&file_mutex);
|
||||
(*fc) = (void *)addfps(param);
|
||||
pthread_mutex_unlock(&file_mutex);
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
static FILTER_ACTION fp_request(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
||||
if(fc && (param->service == S_PROXY)){
|
||||
if(FC->state) {
|
||||
closefiles(FC);
|
||||
FC->state = 0;
|
||||
}
|
||||
processcallbacks(FC, FP_CALLONREQUEST, *buf_p + offset, *length_p - offset);
|
||||
if(FC->what &FP_REJECT) return REJECT;
|
||||
FC->state = GOT_HTTP_REQUEST;
|
||||
genpaths(FC);
|
||||
if(FC->what & FP_CLIHEADER) initclientfile(FC);
|
||||
|
||||
}
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
static FILTER_ACTION fp_hcli(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
||||
if(fc && param->service == S_SMTPP) {
|
||||
processcallbacks(FC, FP_CALLONREQUEST, *buf_p + offset, *length_p - offset);
|
||||
if(FC->what & FP_REJECT) return REJECT;
|
||||
if(!FC->state)genpaths(FC);
|
||||
FC->state = GOT_SMTP_REQ;
|
||||
}
|
||||
if(fc && param->service == S_FTPPR) {
|
||||
processcallbacks(FC, FP_CALLONREQUEST, *buf_p + offset, *length_p - offset);
|
||||
if(FC->what & FP_REJECT) return REJECT;
|
||||
genpaths(FC);
|
||||
FC->state = GOT_FTP_REQ;
|
||||
}
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
static FILTER_ACTION fp_hsrv(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
||||
if(fc && param->service == S_PROXY && (FC->state == GOT_HTTP_REQUEST || FC->state == GOT_HTTP_CLI_HDR || FC->state == GOT_HTTP_CLIDATA)){
|
||||
if(FC->what & FP_SRVHEADER) initserverfile(FC);
|
||||
FC->state = GOT_HTTP_SRV_HDR;
|
||||
|
||||
}
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
static FILTER_ACTION fp_dcli(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
||||
if(fc && FC->state == GOT_HTTP_REQUEST){
|
||||
FC->state = GOT_HTTP_CLI_HDR2;
|
||||
}
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
static FILTER_ACTION fp_dsrv(void *fc, struct clientparam * param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
||||
if(fc && (FC->state == GOT_HTTP_REQUEST || FC->state == GOT_HTTP_CLI_HDR || FC->state == GOT_HTTP_CLIDATA || FC->state == GOT_HTTP_CLIDATA || FC->state == GOT_HTTP_SRV_HDR)){
|
||||
FC->state = GOT_HTTP_SRV_HDR2;
|
||||
}
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
static void fp_clear(void *fc){
|
||||
removefps(FC);
|
||||
free(fc);
|
||||
}
|
||||
|
||||
static void fp_close(void *fo){
|
||||
}
|
||||
|
||||
|
||||
static struct filter fp_filter = {
|
||||
NULL,
|
||||
"filefilter",
|
||||
"filefilter",
|
||||
fp_open,
|
||||
fp_client,
|
||||
fp_request,
|
||||
fp_hcli,
|
||||
fp_hsrv,
|
||||
NULL,
|
||||
fp_dcli,
|
||||
fp_dsrv,
|
||||
fp_clear,
|
||||
fp_close,
|
||||
};
|
||||
|
||||
static struct symbol fp_symbols[] = {
|
||||
{fp_symbols + 1, "fp_registercallback", (void*) fp_registercallback},
|
||||
{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;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
|
||||
|
||||
int file_plugin (struct pluginlink * pluginlink,
|
||||
int argc, char** argv){
|
||||
|
||||
if(!file_loaded){
|
||||
pthread_mutex_init(&file_mutex, NULL);
|
||||
file_loaded = 1;
|
||||
pl = pluginlink;
|
||||
memcpy(&sso, pl->so, sizeof(struct sockfuncs));
|
||||
pl->so->_poll = fp_poll;
|
||||
pl->so->_send = fp_send;
|
||||
pl->so->_sendto = fp_sendto;
|
||||
pl->so->_recv = fp_recv;
|
||||
pl->so->_recvfrom = fp_recvfrom;
|
||||
pl->so->_shutdown = fp_shutdown;
|
||||
pl->so->_closesocket = fp_closesocket;
|
||||
fp_filter.next = pl->conf->filters;
|
||||
pl->conf->filters = &fp_filter;
|
||||
fp_symbols[1].next = pl->symbols.next;
|
||||
pl->symbols.next = fp_symbols;
|
||||
file_commandhandlers[1].next = pl->commandhandlers->next;
|
||||
pl->commandhandlers->next = file_commandhandlers;
|
||||
}
|
||||
h_cachedir(0, NULL);
|
||||
preview = 32768;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,41 +0,0 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#define FP_OK 0
|
||||
#define FP_REJECT 65536
|
||||
|
||||
#define FP_CLIDATA 1
|
||||
#define FP_SRVDATA 2
|
||||
#define FP_CLIHEADER 4
|
||||
#define FP_SRVHEADER 8
|
||||
#define FP_KEEPFILE 16
|
||||
#define FP_SHAREFILE 32
|
||||
#define FP_PREVIEWCLI 64
|
||||
#define FP_PREVIEWSRV 128
|
||||
#define FP_CALLONREQUEST 256
|
||||
#define FP_CALLAFTERCLIHEADERS 512
|
||||
#define FP_CALLAFTERSRVHEADERS 1024
|
||||
#define FP_CALLONREMOVE 2048
|
||||
|
||||
struct fp_filedata {
|
||||
struct clientparam *cp;
|
||||
#ifdef _WIN32
|
||||
HANDLE h_cli, h_srv;
|
||||
#else
|
||||
int fd_cli, fd_srv;
|
||||
#endif
|
||||
char *path_cli;
|
||||
char *path_srv;
|
||||
};
|
||||
|
||||
|
||||
typedef int (*FP_CALLBACK)(int what, void *data, struct fp_filedata *fpd, char *buf, int size);
|
||||
|
||||
typedef int (*FP_REGISTERCALBACK) (int what, int max_size, int preview_size, struct clientparam *cp, FP_CALLBACK cb, void *data);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1 +0,0 @@
|
||||
include Makefile.var
|
@ -1,7 +0,0 @@
|
||||
all: $(BUILDDIR)FilePlugin$(DLSUFFICS)
|
||||
|
||||
FilePlugin$(OBJSUFFICS): FilePlugin.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) FilePlugin.c
|
||||
|
||||
$(BUILDDIR)FilePlugin$(DLSUFFICS): FilePlugin$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)../../$(BUILDDIR)FilePlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) FilePlugin$(OBJSUFFICS)
|
@ -1 +0,0 @@
|
||||
include Makefile.var
|
@ -1,7 +0,0 @@
|
||||
all: $(BUILDDIR)lastFripper$(DLSUFFICS)
|
||||
|
||||
lastFripper$(OBJSUFFICS): lastFripper.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) lastFripper.c
|
||||
|
||||
$(BUILDDIR)lastFripper$(DLSUFFICS): lastFripper$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)../../$(BUILDDIR)lastFripper$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) lastFripper$(OBJSUFFICS)
|
@ -1,704 +0,0 @@
|
||||
/*
|
||||
released as a public domain
|
||||
std.denis, 2009
|
||||
*/
|
||||
#include "../../structures.h"
|
||||
#include "lastFripper.h"
|
||||
|
||||
#define strdup _strdup
|
||||
#define strnicmp _strnicmp
|
||||
#define ltoa _ltoa
|
||||
|
||||
#define mkdir _mkdir
|
||||
|
||||
#define PART_SUFFIX "_partial"
|
||||
|
||||
void my_mkdir( char* name )
|
||||
{
|
||||
char* pdir = name;
|
||||
|
||||
while( 1 ) {
|
||||
char ch;
|
||||
char* pnext = pdir;
|
||||
while( *pnext && *pnext != '\\' && *pnext != '/' )
|
||||
pnext++;
|
||||
if( *pnext == 0 )
|
||||
break;
|
||||
|
||||
ch = *pnext;
|
||||
*pnext = 0;
|
||||
mkdir( name );
|
||||
*pnext = ch;
|
||||
|
||||
pdir = pnext + 1;
|
||||
}
|
||||
mkdir( name );
|
||||
}
|
||||
|
||||
|
||||
__inline void myOutputDebugStringA1( char* str )
|
||||
{
|
||||
/* char fname[128];
|
||||
ltoa( GetCurrentThreadId(), fname, 10 );
|
||||
FILE* fp = fopen( fname, "ab" );
|
||||
fputs( str, fp );
|
||||
fputs( "\r\n", fp );
|
||||
fflush( fp );
|
||||
fclose( fp );
|
||||
*/
|
||||
}
|
||||
|
||||
__inline void myOutputDebugStringA( void* buf, int len )
|
||||
{
|
||||
/* char fname[128];
|
||||
ltoa( GetCurrentThreadId(), fname, 10 );
|
||||
FILE* fp = fopen( fname, "ab" );
|
||||
fwrite( buf, len, 1, fp );
|
||||
fputs( "\r\n", fp );
|
||||
fflush( fp );
|
||||
fclose( fp ); */
|
||||
}
|
||||
|
||||
#ifndef isnumber
|
||||
#define isnumber(i_n_arg) ((i_n_arg>='0')&&(i_n_arg<='9'))
|
||||
#endif
|
||||
|
||||
#define sizearr(x) (sizeof(x)/sizeof(x[0]))
|
||||
#define xmalloc( type, len ) ((type*)malloc( (len) * sizeof(type) ) )
|
||||
#define xcalloc( type, len ) ((type*)calloc( (len), sizeof(type) ) )
|
||||
|
||||
int clean_filename( char* filename )
|
||||
{
|
||||
int i;
|
||||
for( i = 0; filename[i]; i++ )
|
||||
switch( filename[i] ) {
|
||||
case '*':
|
||||
case '?':
|
||||
case '<':
|
||||
case '>':
|
||||
case '\\':
|
||||
case '/':
|
||||
case ':':
|
||||
case '"':
|
||||
filename[i] = '_';
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
static struct pluginlink * pl;
|
||||
static int lfm_loaded = 0;
|
||||
static char* g_folder = 0;
|
||||
static char* g_format = 0;
|
||||
|
||||
static int lfm_format_filename( struct playlist_item* p_item, char* p_filename, int n_filename )
|
||||
{
|
||||
int i = 0, j;
|
||||
char ch;
|
||||
char* fmt;
|
||||
char *ff = NULL;
|
||||
|
||||
if( g_folder && *g_folder ) {
|
||||
strncpy( p_filename, g_folder, n_filename );
|
||||
i = strlen( p_filename );
|
||||
if( i < n_filename-1 && p_filename[i-1] != '\\' )
|
||||
p_filename[i++] = '\\';
|
||||
}
|
||||
|
||||
fmt = g_format;
|
||||
if( fmt == NULL ) fmt = "%a\\%t.mp3";
|
||||
while( ( ch = *fmt++ ) != 0 ) {
|
||||
if( ch == '%' ) {
|
||||
char* p_sz = NULL;
|
||||
char a_sz[32];
|
||||
ch = *fmt++;
|
||||
switch( ch ) {
|
||||
case 0:
|
||||
fmt--; break;
|
||||
case '%':
|
||||
p_sz = "%";
|
||||
break;
|
||||
case 'n': {
|
||||
static unsigned ndx = 0;
|
||||
ltoa( ndx++, a_sz, 10 );
|
||||
p_sz = a_sz;
|
||||
break;
|
||||
}
|
||||
case 'a':
|
||||
p_sz = p_item->artist;
|
||||
break;
|
||||
case 't':
|
||||
p_sz = p_item->title;
|
||||
break;
|
||||
case 'l':
|
||||
p_sz = p_item->album;
|
||||
break;
|
||||
}
|
||||
if( p_sz ) {
|
||||
strncpy( p_filename+i, p_sz, n_filename-i );
|
||||
p_filename[n_filename-1] = 0;
|
||||
i += clean_filename( p_filename+i );
|
||||
}
|
||||
} else
|
||||
if( i < n_filename ) p_filename[i++] = ch;
|
||||
}
|
||||
|
||||
for( j = i-1; j >= 0; j-- )
|
||||
if( p_filename[j] == '\\' || p_filename[j] == '/' ) {
|
||||
ff = p_filename + j;
|
||||
break;
|
||||
}
|
||||
if( ff ) {
|
||||
char ch = *ff;
|
||||
*ff = 0;
|
||||
my_mkdir( p_filename );
|
||||
*ff = ch;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void lfm_close_request( struct lfm_client_data* p_client )
|
||||
{
|
||||
struct lfm_filter_data* p_data;
|
||||
if( p_client == NULL ) return;
|
||||
p_data = p_client->p_data;
|
||||
if( p_data == NULL ) return;
|
||||
|
||||
if( p_client->req_type == LFM_PLAYLIST ) {
|
||||
free( p_client->pl_xml );
|
||||
} else if( p_client->req_type == LFM_GET && p_client->fp ) {
|
||||
struct playlist_item* p_item = p_client->pl_item;
|
||||
if( p_item ) {
|
||||
char id3v1[128];
|
||||
memset( id3v1, 0, 128 );
|
||||
strcpy( id3v1, "TAG" );
|
||||
strncpy( id3v1+3, p_item->title, 30 );
|
||||
strncpy( id3v1+33, p_item->artist, 30 );
|
||||
strncpy( id3v1+63, p_item->album, 30 );
|
||||
id3v1[127] = -1;
|
||||
fwrite( id3v1, 128, 1, p_client->fp );
|
||||
}
|
||||
fclose( p_client->fp );
|
||||
/*
|
||||
if( p_item ) {
|
||||
char filename_part[512], filename[512];
|
||||
int i = lfm_format_filename( p_item, filename_part, sizearr(filename_part) );
|
||||
memcpy( filename, filename_part, sizeof(filename) );
|
||||
strncpy( filename_part+i, PART_SUFFIX, sizearr(filename_part)-i );
|
||||
rename( filename_part, filename );
|
||||
}
|
||||
*/
|
||||
pthread_mutex_lock( &p_data->mutex );
|
||||
if( p_data->playlist != NULL && p_item != NULL ) {
|
||||
if( p_data->playlist == p_item )
|
||||
p_data->playlist = p_item->next;
|
||||
else {
|
||||
struct playlist_item *p_last = p_data->playlist;
|
||||
|
||||
while( p_last->next != NULL && p_last->next != p_item )
|
||||
p_last = p_last->next;
|
||||
|
||||
if( p_last->next )
|
||||
p_last->next = p_item->next;
|
||||
}
|
||||
if( p_item->artist ) free( p_item->artist );
|
||||
if( p_item->title ) free( p_item->title );
|
||||
if( p_item->album ) free( p_item->album );
|
||||
if( p_item->url ) free( p_item->url );
|
||||
free( p_item );
|
||||
}
|
||||
pthread_mutex_unlock( &p_data->mutex );
|
||||
}
|
||||
p_client->req_type = LFM_NONE;
|
||||
}
|
||||
|
||||
static void* lfm_filter_open( void * idata, struct srvparam * param ){
|
||||
struct lfm_filter_data* pdata = (struct lfm_filter_data*)idata;
|
||||
if( pdata ){
|
||||
pthread_mutex_lock( &pdata->mutex );
|
||||
pdata->refs++;
|
||||
pthread_mutex_unlock( &pdata->mutex );
|
||||
} else {
|
||||
if( ( pdata = xcalloc( struct lfm_filter_data, 1 ) ) != NULL ) {
|
||||
pthread_mutex_init( &pdata->mutex, NULL );
|
||||
pdata->playlist = NULL;
|
||||
pdata->refs++;
|
||||
}
|
||||
}
|
||||
return pdata;
|
||||
}
|
||||
|
||||
static FILTER_ACTION lfm_filter_client( void *fo, struct clientparam* param, void** fc )
|
||||
{
|
||||
struct lfm_filter_data* p_data;
|
||||
struct lfm_client_data* p_client;
|
||||
*fc = NULL;
|
||||
if( fo == NULL ) return PASS;
|
||||
|
||||
p_data = (struct lfm_filter_data*)fo;
|
||||
p_client = xcalloc( struct lfm_client_data, 1 );
|
||||
if( p_client == NULL ) return PASS;
|
||||
|
||||
p_client->p_data = p_data;
|
||||
p_client->req_type = LFM_NONE;
|
||||
|
||||
*fc = p_client;
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
static void lfm_filter_clear( void *fc )
|
||||
{
|
||||
struct lfm_client_data* p_client;
|
||||
|
||||
p_client = (struct lfm_client_data*)fc;
|
||||
if( p_client == NULL ) return;
|
||||
|
||||
lfm_close_request( p_client );
|
||||
|
||||
free( p_client );
|
||||
}
|
||||
|
||||
static void lfm_filter_close(void *fo){
|
||||
struct lfm_filter_data* p_data;
|
||||
struct playlist_item* p_item;
|
||||
|
||||
p_data = (struct lfm_filter_data*)fo;
|
||||
if( p_data == NULL ) return;
|
||||
|
||||
if( --p_data->refs > 0 ) return;
|
||||
|
||||
pthread_mutex_destroy( &p_data->mutex );
|
||||
p_item = p_data->playlist;
|
||||
while( p_item ) {
|
||||
struct playlist_item* p_old = p_item;
|
||||
p_item = p_item->next;
|
||||
|
||||
if( p_old->artist ) free( p_old->artist );
|
||||
if( p_old->title ) free( p_old->title );
|
||||
if( p_old->album ) free( p_old->album );
|
||||
if( p_old->url ) free( p_old->url );
|
||||
free( p_old );
|
||||
}
|
||||
|
||||
free( p_data );
|
||||
}
|
||||
|
||||
static FILTER_ACTION lfm_filter_request( void *fc, struct clientparam *param, unsigned char** buf_p, int* bufsize_p, int offset, int* length_p )
|
||||
{
|
||||
char* p_buf = (char*)( *buf_p + offset );
|
||||
int n_buf = *length_p - offset;
|
||||
struct lfm_client_data* p_client;
|
||||
struct lfm_filter_data* p_data;
|
||||
|
||||
if( p_buf == NULL || n_buf < 5 ) return CONTINUE;
|
||||
|
||||
p_client = (struct lfm_client_data*)fc;
|
||||
if( p_client == NULL ) return CONTINUE;
|
||||
p_data = p_client->p_data;
|
||||
if( p_data == NULL ) return CONTINUE;
|
||||
|
||||
pl->conf->filtermaxsize = 0;
|
||||
|
||||
lfm_close_request( p_client );
|
||||
|
||||
p_client->req_type = LFM_NONE;
|
||||
p_client->fp = NULL;
|
||||
|
||||
if( strncasecmp( p_buf, "GET ", 4 ) != 0 ) return CONTINUE;
|
||||
|
||||
p_buf += 4;
|
||||
|
||||
if( strncasecmp( p_buf, "http://ws.audioscrobbler.com/radio/xspf.php?", 44 ) == 0 ) {
|
||||
myOutputDebugStringA1( "getting a playlist" );
|
||||
p_client->req_type = LFM_PLAYLIST;
|
||||
} else {
|
||||
char zzz[256];
|
||||
int i;
|
||||
struct playlist_item* p_item;
|
||||
for( i = 0; i < n_buf && i < 256; i++ ) {
|
||||
if( p_buf[i] == '\r' ) break;
|
||||
zzz[i] = p_buf[i];
|
||||
}
|
||||
zzz[i] = 0;
|
||||
myOutputDebugStringA1( zzz );
|
||||
pthread_mutex_lock( &p_data->mutex );
|
||||
p_item = p_data->playlist;
|
||||
while( p_item ) {
|
||||
if( strncasecmp( p_buf, p_item->url, p_item->url_len ) == 0 )
|
||||
break;
|
||||
p_item = p_item->next;
|
||||
}
|
||||
pthread_mutex_unlock( &p_data->mutex );
|
||||
if( p_item ) {
|
||||
myOutputDebugStringA1( "getting a known url: " );
|
||||
myOutputDebugStringA1( p_item->title );
|
||||
p_client->req_type = LFM_GET;
|
||||
p_client->pl_item = p_item;
|
||||
}
|
||||
}
|
||||
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
static FILTER_ACTION lfm_filter_header_srv( void *fc, struct clientparam *param, unsigned char** buf_p, int* bufsize_p, int offset, int* length_p )
|
||||
{
|
||||
char* p_buf = (char*)( *buf_p + offset );
|
||||
struct lfm_client_data* p_client;
|
||||
int n_buf = *length_p - offset;
|
||||
struct lfm_filter_data* p_data;
|
||||
char zzz[100];
|
||||
int code;
|
||||
|
||||
if( p_buf == NULL || n_buf < 9 ) return CONTINUE;
|
||||
|
||||
p_client = (struct lfm_client_data*)fc;
|
||||
if( p_client == NULL ) return CONTINUE;
|
||||
p_data = p_client->p_data;
|
||||
if( p_data == NULL ) return CONTINUE;
|
||||
|
||||
code = atoi( p_buf + 9 );
|
||||
sprintf( zzz, "http code: %d", code );
|
||||
myOutputDebugStringA1( zzz );
|
||||
myOutputDebugStringA( p_buf, n_buf );
|
||||
if( p_client->req_type == LFM_GET && ( code > 300 && code < 304 || code == 307 ) ) {
|
||||
p_client->req_type = LFM_REDIR;
|
||||
do {
|
||||
char* p_line = p_buf;
|
||||
int n_line;
|
||||
|
||||
for(; n_buf > 0 && *p_buf != '\r'; p_buf++, n_buf-- ) {};
|
||||
n_line = p_buf - p_line;
|
||||
if( n_line <= 0 ) break;
|
||||
if( n_line > 10 && strncasecmp( p_line, "location: ", 10 ) == 0 ) {
|
||||
myOutputDebugStringA1( "redir/location: " );
|
||||
myOutputDebugStringA( p_line + 10, n_line - 10 );
|
||||
if( p_client->pl_item ) {
|
||||
char* p_url = p_line + 10;
|
||||
int n_url = n_line - 10;
|
||||
pthread_mutex_lock( &p_data->mutex );
|
||||
if( p_client->pl_item->url ) free( p_client->pl_item->url );
|
||||
p_client->pl_item->url = xmalloc( char, n_url + 1 + 1 );
|
||||
memcpy( p_client->pl_item->url, p_url, n_url );
|
||||
p_client->pl_item->url[n_url] = ' ';
|
||||
p_client->pl_item->url[n_url+1] = 0;
|
||||
p_client->pl_item->url_len = n_url + 1;
|
||||
myOutputDebugStringA1( "got a url: " );
|
||||
myOutputDebugStringA1( p_client->pl_item->url );
|
||||
pthread_mutex_unlock( &p_data->mutex );
|
||||
}
|
||||
p_client->req_type = LFM_NONE;
|
||||
}
|
||||
for(; n_buf > 0 && ( *p_buf == '\n' || *p_buf == '\r' ); p_buf++, n_buf-- ) {};
|
||||
} while( n_buf > 0 );
|
||||
}
|
||||
|
||||
if( code == 200 && p_client->req_type == LFM_GET ) {
|
||||
struct playlist_item* p_item = p_client->pl_item;
|
||||
char filename[512];
|
||||
int i = lfm_format_filename( p_item, filename, sizearr(filename) );
|
||||
/*
|
||||
strncpy( filename + i, PART_SUFFIX, sizearr(filename)-i );
|
||||
*/
|
||||
p_client->fp = fopen( filename, "wb" );
|
||||
}
|
||||
else if( code == 200 && p_client->req_type == LFM_PLAYLIST ) {
|
||||
p_client->pl_xml = xcalloc( struct xml_state, 1 );
|
||||
}
|
||||
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
void playlist_analyze( struct lfm_client_data* p_client, const char* p_buf, int len );
|
||||
static FILTER_ACTION lfm_filter_data_srv( void *fc, struct clientparam *param, unsigned char** buf_p, int* bufsize_p, int offset, int* length_p )
|
||||
{
|
||||
char* p_buf = (char*)( *buf_p + offset );
|
||||
int n_buf = *length_p - offset;
|
||||
struct lfm_client_data* p_client;
|
||||
struct lfm_filter_data* p_data;
|
||||
|
||||
|
||||
myOutputDebugStringA1( "filter_data_srv" );
|
||||
myOutputDebugStringA( p_buf, n_buf );
|
||||
|
||||
if( p_buf == NULL || n_buf < 1 ) return CONTINUE;
|
||||
|
||||
p_client = (struct lfm_client_data*)fc;
|
||||
if( p_client == NULL ) return CONTINUE;
|
||||
p_data = p_client->p_data;
|
||||
if( p_data == NULL ) return CONTINUE;
|
||||
|
||||
if( p_client->req_type == LFM_PLAYLIST )
|
||||
myOutputDebugStringA1( "filter_data_srv: playlist" );
|
||||
else if( p_client->req_type == LFM_GET ) {
|
||||
myOutputDebugStringA1( "filter_data_srv: retrieving" );
|
||||
if( p_client->fp == NULL )
|
||||
myOutputDebugStringA1( "but no file allocated" );
|
||||
}
|
||||
|
||||
if( p_client->req_type == LFM_PLAYLIST )
|
||||
playlist_analyze( p_client, p_buf, n_buf );
|
||||
if( p_client->fp )
|
||||
fwrite( p_buf, n_buf, 1, p_client->fp );
|
||||
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
enum XmlState
|
||||
{
|
||||
XML_TEXT,
|
||||
XML_TAGNAME,
|
||||
XML_ATTRNAME_W,
|
||||
XML_ATTRNAME,
|
||||
XML_ATTRVALUE_W,
|
||||
XML_ATTRVALUE,
|
||||
XML_TAGCLOSE,
|
||||
XML_TAGOPENCLOSE,
|
||||
};
|
||||
|
||||
int xml_get_token_id( char** table, char* token )
|
||||
{
|
||||
int i;
|
||||
char* psz;
|
||||
for( psz = token; *psz; psz++ )
|
||||
*psz = tolower( *psz );
|
||||
for( i = 0; *table; i++, table++ )
|
||||
if( strcmp( *table, token ) == 0 ) return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
enum {
|
||||
XT_PLAYLIST,
|
||||
XT_TRACK_LIST,
|
||||
XT_TRACK,
|
||||
XT_LOCATION,
|
||||
XT_CREATOR,
|
||||
XT_ALBUM,
|
||||
XT_TITLE
|
||||
};
|
||||
|
||||
char* xt_list[] = {
|
||||
"playlist",
|
||||
"tracklist",
|
||||
"track",
|
||||
"location",
|
||||
"creator",
|
||||
"album",
|
||||
"title",
|
||||
NULL
|
||||
};
|
||||
|
||||
void playlist_analyze( struct lfm_client_data* p_client, const char* p_buf, int len )
|
||||
{
|
||||
struct xml_state* xs = p_client->pl_xml;
|
||||
int n_buf = len;
|
||||
|
||||
if( xs == NULL ) return;
|
||||
|
||||
while( n_buf > 0 ) {
|
||||
enum {
|
||||
XMS_NONE,
|
||||
XMS_TAG,
|
||||
XMS_ATTR_NAME,
|
||||
XMS_ATTR_VALUE,
|
||||
XMS_TEXT
|
||||
} gotta = XMS_NONE;
|
||||
char ch = *p_buf++;
|
||||
n_buf--;
|
||||
lbl_retry:
|
||||
switch( xs->state ) {
|
||||
case XML_TAGNAME:
|
||||
if( ch == '>' ) {
|
||||
xs->state = XML_TEXT;
|
||||
gotta = XMS_TAG;
|
||||
break;
|
||||
} else if( ch == '/' ) {
|
||||
if( xs->n_token == 0 )
|
||||
xs->closing = 1;
|
||||
else {
|
||||
xs->state = XML_ATTRNAME_W;
|
||||
gotta = XMS_TAG;
|
||||
xs->n_token--;
|
||||
}
|
||||
break;
|
||||
} else if( isspace( ch ) ) {
|
||||
xs->state = XML_ATTRNAME_W;
|
||||
gotta = XMS_TAG;
|
||||
break;
|
||||
}
|
||||
if( xs->n_token < TOKEN_MAXLEN ) xs->p_token[xs->n_token++] = ch;
|
||||
break;
|
||||
case XML_ATTRNAME_W:
|
||||
if( ch == '>' ) {
|
||||
xs->state = XML_TEXT;
|
||||
break;
|
||||
} else if( ch == '/' ) {
|
||||
xs->closing = 1;
|
||||
xs->state = XML_TEXT;
|
||||
gotta = XMS_TAG;
|
||||
break;
|
||||
} else if( !isspace( ch ) ) {
|
||||
xs->state = XML_ATTRNAME;
|
||||
goto lbl_retry;
|
||||
}
|
||||
break;
|
||||
case XML_ATTRNAME:
|
||||
if( ch == '=' ) {
|
||||
xs->state = XML_ATTRVALUE_W;
|
||||
gotta = XMS_ATTR_NAME;
|
||||
break;
|
||||
}
|
||||
if( xs->n_token < TOKEN_MAXLEN ) xs->p_token[xs->n_token++] = ch;
|
||||
break;
|
||||
case XML_ATTRVALUE_W:
|
||||
if( ch == '"' || ch == '\'' ) {
|
||||
xs->sep = ch;
|
||||
xs->state = XML_ATTRVALUE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case XML_ATTRVALUE:
|
||||
if( ch == xs->sep ) {
|
||||
xs->state = XML_ATTRNAME_W;
|
||||
gotta = XMS_ATTR_VALUE;
|
||||
break;
|
||||
}
|
||||
if( xs->n_token < TOKEN_MAXLEN ) xs->p_token[xs->n_token++] = ch;
|
||||
break;
|
||||
case XML_TEXT:
|
||||
if( ch == '<' ) {
|
||||
xs->state = XML_TAGNAME;
|
||||
gotta = XMS_TEXT;
|
||||
break;
|
||||
}
|
||||
if( xs->n_token < TOKEN_MAXLEN ) xs->p_token[xs->n_token++] = ch;
|
||||
break;
|
||||
}
|
||||
|
||||
if( gotta != XMS_NONE ) {
|
||||
xs->p_token[xs->n_token] = 0;
|
||||
|
||||
switch( gotta ) {
|
||||
case XMS_TAG: {
|
||||
int id = xml_get_token_id( xt_list, xs->p_token );
|
||||
if( !xs->closing ) {
|
||||
if( xs->level < sizeof(xs->tree) ) xs->tree[xs->level] = id;
|
||||
xs->level++;
|
||||
|
||||
if( id == XT_TRACK && xs->level == 3 && xs->tree[1] == XT_TRACK_LIST )
|
||||
xs->p_item = xcalloc( struct playlist_item, 1 );
|
||||
} else {
|
||||
if( xs->level > 0 ) xs->level--;
|
||||
if( id == XT_TRACK && xs->level == 2 && xs->tree[1] == XT_TRACK_LIST ) {
|
||||
char zzz[1024];
|
||||
_snprintf( zzz, 1024, "artist: <%s>, title: <%s>, url: <%s>",
|
||||
xs->p_item->artist, xs->p_item->title, xs->p_item->url );
|
||||
myOutputDebugStringA1( zzz );
|
||||
pthread_mutex_lock( &p_client->p_data->mutex );
|
||||
xs->p_item->next = p_client->p_data->playlist;
|
||||
p_client->p_data->playlist = xs->p_item;
|
||||
pthread_mutex_unlock( &p_client->p_data->mutex );
|
||||
}
|
||||
xs->closing = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case XMS_ATTR_NAME:
|
||||
break;
|
||||
case XMS_ATTR_VALUE:
|
||||
break;
|
||||
case XMS_TEXT:
|
||||
if( xs->level == 4 && xs->tree[1] == XT_TRACK_LIST && xs->tree[2] == XT_TRACK ) {
|
||||
struct playlist_item* item = xs->p_item;
|
||||
if( item )
|
||||
switch( xs->tree[3] ) {
|
||||
case XT_LOCATION:
|
||||
item->url_len = xs->n_token;
|
||||
item->url = xmalloc( char, item->url_len + 1 + 1);
|
||||
memcpy( item->url, xs->p_token, item->url_len );
|
||||
item->url[item->url_len++] = ' ';
|
||||
item->url[item->url_len] = 0;
|
||||
break;
|
||||
case XT_CREATOR:
|
||||
item->artist = strdup( xs->p_token );
|
||||
break;
|
||||
case XT_ALBUM:
|
||||
item->album = strdup( xs->p_token );
|
||||
break;
|
||||
case XT_TITLE:
|
||||
item->title = strdup( xs->p_token );
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
xs->n_token = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static struct filter lfm_filter = {
|
||||
NULL,
|
||||
"last.fm spy",
|
||||
NULL,
|
||||
|
||||
lfm_filter_open,
|
||||
lfm_filter_client,
|
||||
lfm_filter_request,
|
||||
NULL,
|
||||
lfm_filter_header_srv,
|
||||
NULL,
|
||||
NULL,
|
||||
lfm_filter_data_srv,
|
||||
lfm_filter_clear,
|
||||
lfm_filter_close
|
||||
};
|
||||
|
||||
static int h_lfm_folder( int argc, unsigned char **argv )
|
||||
{
|
||||
if( g_folder ) free( g_folder );
|
||||
g_folder = strdup( (char*)argv[1] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int h_lfm_format( int argc, unsigned char **argv )
|
||||
{
|
||||
if( g_format ) free( g_format );
|
||||
g_format = strdup( (char*)argv[1] );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct commands lfm_commandhandlers[] = {
|
||||
{lfm_commandhandlers+1, "lfm_folder", h_lfm_folder, 2, 2},
|
||||
{NULL, "lfm_format", h_lfm_format, 2, 2}
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
int lfm_plugin( struct pluginlink * pluginlink, int argc, char** argv )
|
||||
{
|
||||
pl = pluginlink;
|
||||
myOutputDebugStringA1( "lfm_plugin" );
|
||||
if( !lfm_loaded ) {
|
||||
lfm_loaded = 1;
|
||||
|
||||
lfm_filter.next = pl->conf->filters;
|
||||
pl->conf->filters = &lfm_filter;
|
||||
|
||||
lfm_commandhandlers[1].next = pl->commandhandlers->next;
|
||||
pl->commandhandlers->next = lfm_commandhandlers;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,66 +0,0 @@
|
||||
//
|
||||
// released as a public domain
|
||||
// std.denis, 2009
|
||||
//
|
||||
/*
|
||||
#include "direct.h"
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define strcasecmp stricmp
|
||||
#define strncasecmp strnicmp
|
||||
#else
|
||||
#define closesocket close
|
||||
extern pthread_attr_t pa;
|
||||
#endif
|
||||
|
||||
#ifndef SOCKET_ERROR
|
||||
#define SOCKET_ERROR -1
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum {
|
||||
LFM_NONE,
|
||||
LFM_PLAYLIST, // GET http://ws.audioscrobbler.com/radio/adjust.php(...)
|
||||
LFM_REDIR, // GET http://play.last.fm/user/(...)
|
||||
LFM_GET
|
||||
} LFM_CLASS;
|
||||
|
||||
struct playlist_item {
|
||||
struct playlist_item* next;
|
||||
|
||||
char* artist;
|
||||
char* title;
|
||||
char* album;
|
||||
char* url;
|
||||
int url_len;
|
||||
};
|
||||
|
||||
#define TOKEN_MAXLEN 1024
|
||||
struct xml_state {
|
||||
int state;
|
||||
int closing;
|
||||
char sep;
|
||||
|
||||
int level;
|
||||
char tree[128]; // 128 levels nesting
|
||||
|
||||
int n_token;
|
||||
char p_token[TOKEN_MAXLEN];
|
||||
|
||||
struct playlist_item* p_item;
|
||||
};
|
||||
|
||||
struct lfm_filter_data {
|
||||
pthread_mutex_t mutex;
|
||||
struct playlist_item* playlist;
|
||||
int refs;
|
||||
};
|
||||
struct lfm_client_data {
|
||||
struct lfm_filter_data* p_data;
|
||||
|
||||
int req_type;
|
||||
struct xml_state* pl_xml;
|
||||
struct playlist_item* pl_item;
|
||||
FILE* fp;
|
||||
};
|
@ -1,7 +0,0 @@
|
||||
all: $(BUILDDIR)ldapauth$(DLSUFFICS)
|
||||
|
||||
ldapauth$(OBJSUFFICS): ldapauth.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) ldapauth.c
|
||||
|
||||
$(BUILDDIR)ldapauth$(DLSUFFICS): ldapauth$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)../../$(BUILDDIR)ldapauth$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) $(LIBSPREFIX)ladp$(LIBSSUFFIX) ldapauth$(OBJSUFFICS)
|
@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
gcc -shared -o libldapauth.so ldapauth_new.c -DNOODBC -I/usr/include -L/usr/lib -lldap
|
||||
|
@ -1,4 +0,0 @@
|
||||
del ldapauth.dll
|
||||
gcc -o getldapuser getldapuser.c -DWIN32 -I"./ldapwindev" -L"./ldapwindev" -lldap
|
||||
gcc -shared -o ldapauth.dll ldapauth.c -DWIN32 -I"./ldapwindev" -L"./ldapwindev" -lldap
|
||||
|
@ -1,105 +0,0 @@
|
||||
/* Create list user for 3proxy ACL from LDAP server
|
||||
(c) Kirill Lopuchov lopuchov@mail.ru
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <ldap.h>
|
||||
|
||||
/*Create list user for 3proxy ACL from LDAP server*/
|
||||
|
||||
/* argv[1] = server
|
||||
argv[2] = basedn
|
||||
argv[3] = user_attribute
|
||||
argv[4] = filter
|
||||
argv[5] = user
|
||||
argv[6] = password
|
||||
*/
|
||||
|
||||
main(int argc, char *argv[])
|
||||
|
||||
{
|
||||
LDAP *ld = NULL;
|
||||
LDAPMessage *res = NULL;
|
||||
LDAPMessage *msg = NULL;
|
||||
BerElement *ber;
|
||||
char *getattr,**vals;
|
||||
|
||||
|
||||
char *attrs[] = { NULL, NULL };
|
||||
int i, rc = -1;
|
||||
int lderrno;
|
||||
unsigned char tmpbuf[1000];
|
||||
|
||||
if ( argc < 6 )
|
||||
{
|
||||
printf ("Create 3proxy ACL userlist from ldap server.\ngetldapuser < ldapserver sbasedn user_attribute filter user password > \n");
|
||||
printf ("Example: getldapuser 192.168.0.1 dc=domain,dc=com cn (memberOf=cn=internet,cn=Users,dc=domain,dc=com) cn=admin,cn=users,dc=domain,dc=com password \n");
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
attrs[0]=strdup(argv[3]);
|
||||
|
||||
/* init ldap ------------------------ */
|
||||
ld = ldap_init( argv[1] , 389 );
|
||||
|
||||
if ( ld == NULL )
|
||||
{
|
||||
/*perror( "ldap_init" );*/
|
||||
printf("Error init ldap") ;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* connect ------------------------ */
|
||||
|
||||
rc = ldap_bind_s( ld, argv[5], argv[6], LDAP_AUTH_SIMPLE );
|
||||
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
{
|
||||
ldap_perror( ld, "Error ldap_bind" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* search ------------------------ */
|
||||
|
||||
rc = ldap_search_s( ld,argv[2], LDAP_SCOPE_SUBTREE,
|
||||
argv[4], attrs, 0, &res );
|
||||
|
||||
/* get val ------------------------*/
|
||||
rc=ldap_count_entries(ld,res);
|
||||
|
||||
if (rc > 0)
|
||||
{
|
||||
|
||||
msg=ldap_first_entry(ld, res);
|
||||
getattr=ldap_first_attribute(ld, msg, &ber);
|
||||
while (rc > 0)
|
||||
{
|
||||
vals=ldap_get_values(ld, msg, getattr);
|
||||
if (vals != NULL && vals[0] != NULL )
|
||||
{
|
||||
i=ldap_count_values(vals);
|
||||
while(i>0)
|
||||
{
|
||||
printf("%s",vals[0]);
|
||||
i--;
|
||||
if (rc > 1) { printf(",",vals[0]); }
|
||||
}
|
||||
ldap_value_free(vals);
|
||||
}
|
||||
|
||||
msg=ldap_next_entry(ld, msg);
|
||||
rc--;
|
||||
}
|
||||
|
||||
} //end if (rc>0)
|
||||
|
||||
ldap_memfree(res);
|
||||
|
||||
ldap_unbind(ld);
|
||||
|
||||
}/*end else*/
|
||||
|
||||
}
|
@ -1,576 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ldap.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include "../../proxy.h"
|
||||
#include "../../structures.h"
|
||||
|
||||
struct counter_record
|
||||
{
|
||||
unsigned long traf;
|
||||
unsigned long trafgb;
|
||||
time_t cleared;
|
||||
time_t updated;
|
||||
};
|
||||
|
||||
|
||||
int already_loaded = 0;
|
||||
|
||||
static struct auth myalwaysauth;
|
||||
static struct commands ldap_serv_auth_handler;
|
||||
static struct commands ldap_access_handler;
|
||||
static struct commands ldap_sbase_handler;
|
||||
static struct commands ldap_userenv_handler;
|
||||
static struct commands ldap_trafgroup_handler;
|
||||
static struct commands ldap_attrsgroup_handler;
|
||||
static struct commands ldap_dircount_handler;
|
||||
|
||||
static char *attrs[] = { NULL, NULL};
|
||||
static char *ldap_group_attr;
|
||||
static char *ldap_access;
|
||||
static char *ldap_sbase;
|
||||
static char *ldap_serv;
|
||||
static char *ldap_user;
|
||||
static char *ldap_pass;
|
||||
static char *ldap_userenv;
|
||||
int ldap_userenv_size;
|
||||
static char *ldap_trafgroup;
|
||||
static char *ldap_dircount;
|
||||
static int usercaselow = 0;
|
||||
|
||||
struct pluginlink * mypluginlink;
|
||||
struct schedule myschedule;
|
||||
|
||||
#ifndef _WIN32
|
||||
void lower (char *string)
|
||||
{
|
||||
int length, i;
|
||||
|
||||
length = strlen(string);
|
||||
for (i=0; i<length; i++)
|
||||
{
|
||||
string[i] = tolower(string[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
int savecouters(void)
|
||||
{
|
||||
struct trafcount *tc=mypluginlink->conf->trafcounter;
|
||||
struct trafcount *tcd;
|
||||
struct counter_record wcounter;
|
||||
FILE *f;
|
||||
unsigned char *tmpbuf,pat_file[]="%s%s.lc";
|
||||
|
||||
|
||||
/* timetoexit !=0 - áóäåì çàâåðøàòüñÿ.*/
|
||||
while (tc != NULL)
|
||||
{
|
||||
tcd = tc;
|
||||
tc = tc->next;
|
||||
f=NULL;
|
||||
if(strcmp(tcd->comment,"ldapcounters")==0) {
|
||||
tmpbuf=mypluginlink->myalloc(strlen(pat_file)+strlen(ldap_dircount)+strlen(tcd->ace->users->user));
|
||||
sprintf(tmpbuf,pat_file,ldap_dircount,tcd->ace->users->user);
|
||||
f=fopen(tmpbuf,"w+b");
|
||||
fseek(f,0,SEEK_SET);
|
||||
fprintf(f,"%10lu %10lu %lu %lu\n",tcd->trafgb,tcd->traf,
|
||||
tcd->cleared,tcd->updated);
|
||||
|
||||
fclose(f);
|
||||
mypluginlink->myfree(tmpbuf);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*return 1 delete job , return 0 no delete job*/
|
||||
if (mypluginlink->conf->needreload !=0 )
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport) int start(struct pluginlink * pluginlink,
|
||||
int argc, char** argv);
|
||||
#else
|
||||
|
||||
int start(struct pluginlink * pluginlink,
|
||||
int argc, char** argv);
|
||||
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------------*/
|
||||
static int ldapfunc(struct clientparam *param)
|
||||
{
|
||||
|
||||
LDAP *ld = NULL;
|
||||
LDAPMessage *res = NULL;
|
||||
int rc = -1;
|
||||
char tmpbuf[1024];
|
||||
|
||||
/* test proxy user auth ------------------------*/
|
||||
if(!param->username || !param->password) return 4;
|
||||
if(strlen(param->password)==0) return 4;
|
||||
|
||||
/* init ldap ---------------------- */
|
||||
ld = ldap_init( ldap_serv, 389 );
|
||||
if ( ld == NULL )
|
||||
{
|
||||
param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
|
||||
/*ldap_perror( ld, "Error ldap_init" ); */
|
||||
return 7;
|
||||
}
|
||||
|
||||
|
||||
/* this code for Active Directory LDAP catalog :(
|
||||
detail see documentation for plugin */
|
||||
if (usercaselow > 0)
|
||||
#ifdef _WIN32
|
||||
{ CharLower(param->username); }
|
||||
#else
|
||||
{ lower(param->username); }
|
||||
#endif
|
||||
|
||||
|
||||
/* create user for test auth */
|
||||
sprintf(tmpbuf,"%.200s=%.200s,%.200s",attrs[0],param->username,ldap_userenv);
|
||||
|
||||
rc = ldap_bind_s( ld, tmpbuf, param->password, LDAP_AUTH_SIMPLE );
|
||||
|
||||
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
{
|
||||
param->srv->logfunc(param,"Error ldap_bind: No connect ldap catalog");
|
||||
ldap_unbind_s(ld);
|
||||
return 7;
|
||||
}
|
||||
|
||||
ldap_unbind_s(ld);
|
||||
|
||||
ld = ldap_init( ldap_serv, 389 );
|
||||
|
||||
if ( ld == NULL )
|
||||
{
|
||||
param->srv->logfunc(param,"Error ldap_init: No init lib ldap");
|
||||
/*ldap_perror( ld, "Error ldap_init" ); */
|
||||
return 7;
|
||||
}
|
||||
|
||||
rc = ldap_bind_s( ld, ldap_user, ldap_pass, LDAP_AUTH_SIMPLE );
|
||||
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
{
|
||||
param->srv->logfunc(param, "Error ldap_bind: Not authorize in ldap\
|
||||
catalog, checked option \'ldapconnect\' ");
|
||||
ldap_unbind_s(ld);
|
||||
return 7;
|
||||
}
|
||||
|
||||
/* test enter user in filter ------------------------------
|
||||
create filter for search*/
|
||||
|
||||
sprintf(tmpbuf,"(&(%.200s=%.200s)(%.200s=%.200s))",attrs[0],param->username,
|
||||
ldap_group_attr,ldap_access);
|
||||
|
||||
|
||||
/* search */
|
||||
rc = ldap_search_s( ld, ldap_sbase, LDAP_SCOPE_SUBTREE,
|
||||
tmpbuf, attrs, 0, &res );
|
||||
|
||||
rc=ldap_count_entries(ld,res);
|
||||
|
||||
ldap_msgfree(res);
|
||||
ldap_unbind_s(ld);
|
||||
|
||||
/* user not found */
|
||||
if (rc == 0)
|
||||
{ return 5; }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
handle command ldapserv */
|
||||
int h_ldapconnect(int argc, unsigned char ** argv)
|
||||
{
|
||||
LDAP *ld = NULL;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "Error in ldapconnect: See documentation of ldapauth plugin.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ldap_serv=mypluginlink->mystrdup(argv[1]);
|
||||
ldap_user=mypluginlink->mystrdup(argv[2]);
|
||||
|
||||
ld = ldap_init( ldap_serv, 389 );
|
||||
ldap_unbind_s(ld);
|
||||
|
||||
if (argc == 4)
|
||||
{
|
||||
ldap_pass= mypluginlink->mystrdup(argv[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
ldap_pass=NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* --------------------------------------------------------------------------
|
||||
handle command ldapaccess */
|
||||
int h_access(int argc, unsigned char ** argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
{
|
||||
fprintf(stderr, "Error in ldapaccess: See documentation of ldapauth plugin.\n");
|
||||
return 1;
|
||||
}
|
||||
ldap_access=mypluginlink->mystrdup(argv[1]);
|
||||
return 0;
|
||||
}
|
||||
/* --------------------------------------------------------------------------
|
||||
handle command ldapsbase
|
||||
searching base */
|
||||
int h_sbase(int argc, unsigned char ** argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
{
|
||||
fprintf(stderr, "Error in ldapsbase: See documentation of ldapauth plugin.\n");
|
||||
return 1;
|
||||
}
|
||||
ldap_sbase=mypluginlink->mystrdup(argv[1]);
|
||||
return 0;
|
||||
}
|
||||
/* --------------------------------------------------------------------------
|
||||
handle command ldapuserenv */
|
||||
int h_userenv(int argc, unsigned char ** argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
{
|
||||
fprintf(stderr, "Error in ldapsbase: See documentation of ldapauth plugin.\n");
|
||||
return 1;
|
||||
}
|
||||
ldap_userenv=mypluginlink->mystrdup(argv[1]);
|
||||
return 0;
|
||||
}
|
||||
/* --------------------------------------------------------------------------
|
||||
handle command ldaptrafgroup */
|
||||
int h_trafgroup(int argc, unsigned char ** argv)
|
||||
{
|
||||
struct trafcount *newtrafcount;
|
||||
struct bandlim *newbandlim;
|
||||
static struct ace *newace;
|
||||
static struct userlist *newuserlist;
|
||||
struct counter_record rcounter;
|
||||
|
||||
LDAP *ld = NULL;
|
||||
LDAPMessage *res = NULL;
|
||||
LDAPMessage *msg = NULL;
|
||||
BerElement *ber = NULL;
|
||||
int rc = -1;
|
||||
char *tmpbuf,pat_file[]="%s%s.lc",pat_group[]="(%s=%s)";
|
||||
char *getattr,**vals,buf[256];
|
||||
ROTATION rtype;
|
||||
unsigned long traflimit;
|
||||
int bandwidth ;
|
||||
|
||||
FILE *f;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
fprintf(stderr, "Error in ldaptrafgroup: See documentation of ldapauth plugin.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ld = ldap_init( ldap_serv, 389 );
|
||||
|
||||
if ( ld == NULL )
|
||||
{
|
||||
fprintf(stderr,"Error in ldaptrafgroup: ldap_init: No init lib ldap");
|
||||
return 7;
|
||||
}
|
||||
|
||||
rc = ldap_bind_s( ld, ldap_user, ldap_pass, LDAP_AUTH_SIMPLE );
|
||||
|
||||
if ( rc != LDAP_SUCCESS )
|
||||
{
|
||||
fprintf(stderr, "Error in ldaptrafgroup: ldap_bind: Not authorize in ldap\
|
||||
catalog, checked option \'ldapconnect\' ");
|
||||
ldap_unbind_s(ld);
|
||||
return 7;
|
||||
}
|
||||
|
||||
/* type traf limit */
|
||||
if(strcmp(argv[2],"MONTHLY")==0||strcmp(argv[2],"monthly")==0)
|
||||
{rtype=MONTHLY;}
|
||||
|
||||
if(strcmp(argv[2],"DAILY")==0||strcmp(argv[2],"daily")==0)
|
||||
{rtype=DAILY;}
|
||||
|
||||
if(strcmp(argv[2],"WEEKLY")==0||strcmp(argv[2],"weekly")==0)
|
||||
{rtype=WEEKLY;}
|
||||
|
||||
traflimit = atol((char *)argv[3]);
|
||||
bandwidth = atoi((char *)argv[4]);
|
||||
|
||||
/* name ldap group */
|
||||
tmpbuf=mypluginlink->myalloc(strlen(pat_group)+strlen(ldap_group_attr)+strlen(argv[1]));
|
||||
sprintf(tmpbuf,pat_group,ldap_group_attr,argv[1]);
|
||||
rc = ldap_search_s( ld, ldap_sbase, LDAP_SCOPE_SUBTREE,
|
||||
tmpbuf, attrs, 0, &res );
|
||||
mypluginlink->myfree(tmpbuf);
|
||||
|
||||
rc=ldap_count_entries(ld,res);
|
||||
|
||||
/* users found */
|
||||
if (rc > 0)
|
||||
{
|
||||
msg=ldap_first_entry(ld, res);
|
||||
getattr=ldap_first_attribute(ld, msg, &ber);
|
||||
|
||||
while (rc > 0)
|
||||
{
|
||||
vals=ldap_get_values(ld, msg, getattr);
|
||||
if (vals != NULL && vals[0] != NULL )
|
||||
{
|
||||
|
||||
/* -------------bandlim----------
|
||||
create user list */
|
||||
newuserlist = (*mypluginlink->myalloc)(sizeof (struct userlist));
|
||||
if (usercaselow > 0)
|
||||
#ifdef _WIN32
|
||||
{ CharLower(vals[0]); }
|
||||
#else
|
||||
{ lower(vals[0]); }
|
||||
#endif
|
||||
|
||||
newuserlist->user = (*mypluginlink->mystrdup)(vals[0]);
|
||||
newuserlist->next = NULL;
|
||||
/*create user rule */
|
||||
newace = (*mypluginlink->myalloc)(sizeof (struct ace));
|
||||
memset(newace, 0, sizeof(struct ace));
|
||||
newace->users = newuserlist;
|
||||
newace->action = BANDLIM;
|
||||
/*create user bandlim */
|
||||
newbandlim =(*mypluginlink->myalloc)(sizeof (struct bandlim));
|
||||
memset(newbandlim, 0, sizeof(struct bandlim));
|
||||
newbandlim->rate = bandwidth;
|
||||
newbandlim->ace = newace;
|
||||
newbandlim->next = mypluginlink->conf->bandlimiter;
|
||||
mypluginlink->conf->bandlimiter = newbandlim;
|
||||
|
||||
/* -------------counters----------
|
||||
create user list */
|
||||
newuserlist = (*mypluginlink->myalloc)(sizeof (struct userlist));
|
||||
if (usercaselow > 0)
|
||||
#ifdef _WIN32
|
||||
{ CharLower(vals[0]); }
|
||||
#else
|
||||
{ lower(vals[0]); }
|
||||
#endif
|
||||
newuserlist->user = (*mypluginlink->mystrdup)(vals[0]);
|
||||
newuserlist->next = NULL;
|
||||
/*create user rule */
|
||||
newace = (*mypluginlink->myalloc)(sizeof (struct ace));
|
||||
memset(newace, 0, sizeof(struct ace));
|
||||
newace->users = newuserlist;
|
||||
newace->action = COUNTIN;
|
||||
/*create user counter */
|
||||
newtrafcount =(*mypluginlink->myalloc)(sizeof (struct trafcount));
|
||||
memset(newtrafcount, 0, sizeof(struct trafcount));
|
||||
newtrafcount->ace = newace;
|
||||
newtrafcount->type=rtype;
|
||||
newtrafcount->traflimgb =(traflimit/(1024*4));
|
||||
newtrafcount->traflim = ((traflimit - (newtrafcount->traflimgb*(1024*4)))*(1024*1024));
|
||||
newtrafcount->comment=(*mypluginlink->mystrdup)("ldapcounters");
|
||||
newtrafcount->number=0;
|
||||
tmpbuf=(*mypluginlink->myalloc)(strlen(pat_file)+strlen(ldap_dircount)+strlen(vals[0]));
|
||||
sprintf(tmpbuf,pat_file,ldap_dircount,vals[0]);
|
||||
f=NULL;
|
||||
f=fopen(tmpbuf,"rb");
|
||||
if(f!=NULL)
|
||||
{
|
||||
|
||||
fseek(f,0,SEEK_SET);
|
||||
fgets(buf, 256, f);
|
||||
sscanf(buf,"%10lu %10lu %lu %lu\n",&rcounter.trafgb, &rcounter.traf,
|
||||
&rcounter.cleared, &rcounter.updated);
|
||||
|
||||
|
||||
newtrafcount->trafgb=rcounter.trafgb;
|
||||
newtrafcount->traf=rcounter.traf;
|
||||
newtrafcount->cleared=rcounter.cleared;
|
||||
newtrafcount->updated=rcounter.updated;
|
||||
fclose(f);
|
||||
}
|
||||
mypluginlink->myfree(tmpbuf);
|
||||
|
||||
newtrafcount->next = mypluginlink->conf->trafcounter;
|
||||
mypluginlink->conf->trafcounter = newtrafcount;
|
||||
|
||||
ldap_value_free(vals);
|
||||
}
|
||||
msg=ldap_next_entry(ld, msg);
|
||||
rc--;
|
||||
}
|
||||
|
||||
}/* end if (rc > 0) */
|
||||
|
||||
ldap_unbind_s(ld);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* --------------------------------------------------------------------------
|
||||
handle command ldapattrsgroup */
|
||||
int h_attrsgroup(int argc, unsigned char ** argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
{
|
||||
fprintf(stderr, "Error in ldapattr: See documentation of ldapauth plugin.\n");
|
||||
return 1;
|
||||
}
|
||||
attrs[0]=mypluginlink->mystrdup(argv[1]);
|
||||
ldap_group_attr=mypluginlink->mystrdup(argv[2]);
|
||||
|
||||
if(argc == 4)
|
||||
{ usercaselow=atoi(argv[3]); }
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* --------------------------------------------------------------------------
|
||||
handle command ldapdircount */
|
||||
int h_dircount(int argc, unsigned char ** argv)
|
||||
{
|
||||
if (argc < 1)
|
||||
{
|
||||
fprintf(stderr, "Error in ldapdircount: See documentation of ldapauth plugin.\n");
|
||||
return 1;
|
||||
}
|
||||
ldap_dircount=mypluginlink->mystrdup(argv[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*------------------------------- MAIN --------------------------------------
|
||||
start plugin init */
|
||||
int start(struct pluginlink * pluginlink, int argc, char** argv)
|
||||
{
|
||||
|
||||
|
||||
if (already_loaded != 0)
|
||||
{
|
||||
pluginlink->myfree(ldap_access);
|
||||
pluginlink->myfree(ldap_sbase);
|
||||
pluginlink->myfree(ldap_serv);
|
||||
pluginlink->myfree(ldap_user);
|
||||
pluginlink->myfree(ldap_pass);
|
||||
pluginlink->myfree(ldap_userenv);
|
||||
pluginlink->myfree(ldap_dircount);
|
||||
pluginlink->myfree(ldap_group_attr);
|
||||
pluginlink->myfree(attrs[0]);
|
||||
return (0);
|
||||
}
|
||||
|
||||
already_loaded = 1;
|
||||
|
||||
mypluginlink=pluginlink;
|
||||
|
||||
ldap_access=NULL;
|
||||
ldap_sbase=NULL;
|
||||
ldap_serv=NULL;
|
||||
ldap_user=NULL;
|
||||
ldap_pass=NULL;
|
||||
ldap_userenv=NULL;
|
||||
ldap_trafgroup=NULL;
|
||||
ldap_dircount=NULL;
|
||||
ldap_group_attr=NULL;
|
||||
|
||||
|
||||
|
||||
myalwaysauth.authenticate = ldapfunc;
|
||||
myalwaysauth.authorize = pluginlink->checkACL;
|
||||
myalwaysauth.desc = "ldap";
|
||||
myalwaysauth.next = pluginlink->authfuncs->next;
|
||||
pluginlink->authfuncs->next = &myalwaysauth;
|
||||
|
||||
/* add command: ldapconnect ipserv user_serv pass_serv */
|
||||
ldap_serv_auth_handler.minargs = 3;
|
||||
ldap_serv_auth_handler.maxargs = 4;
|
||||
ldap_serv_auth_handler.command = "ldapconnect";
|
||||
ldap_serv_auth_handler.handler = h_ldapconnect;
|
||||
ldap_serv_auth_handler.next = pluginlink->commandhandlers->next;
|
||||
pluginlink->commandhandlers->next = &ldap_serv_auth_handler;
|
||||
|
||||
/* add command: ldapaccess cn=internet,cn=users,dc=domain,dc=ru */
|
||||
ldap_access_handler.minargs = 2;
|
||||
ldap_access_handler.maxargs = 2;
|
||||
ldap_access_handler.command = "ldapaccess";
|
||||
ldap_access_handler.handler = h_access;
|
||||
ldap_access_handler.next = pluginlink->commandhandlers->next;
|
||||
pluginlink->commandhandlers->next = &ldap_access_handler;
|
||||
|
||||
/* add command: ldapsbase cn=users,dc=domain,dc=ru */
|
||||
ldap_sbase_handler.minargs = 2;
|
||||
ldap_sbase_handler.maxargs = 2;
|
||||
ldap_sbase_handler.command = "ldapsbase";
|
||||
ldap_sbase_handler.handler = h_sbase;
|
||||
ldap_sbase_handler.next = pluginlink->commandhandlers->next;
|
||||
pluginlink->commandhandlers->next = &ldap_sbase_handler;
|
||||
|
||||
/* add command: ldapuserenv (cn=users,dc=domain,dc=ru) */
|
||||
ldap_userenv_handler.minargs = 2;
|
||||
ldap_userenv_handler.maxargs = 2;
|
||||
ldap_userenv_handler.command = "ldapuserenv";
|
||||
ldap_userenv_handler.handler = h_userenv;
|
||||
ldap_userenv_handler.next = pluginlink->commandhandlers->next;
|
||||
pluginlink->commandhandlers->next = &ldap_userenv_handler;
|
||||
|
||||
/* add command: ldaptrafgroup cn=traf500,cn=users,dc=domain,dc=ru M 500 333 */
|
||||
ldap_trafgroup_handler.minargs = 5;
|
||||
ldap_trafgroup_handler.maxargs = 5;
|
||||
ldap_trafgroup_handler.command = "ldaptrafgroup";
|
||||
ldap_trafgroup_handler.handler = h_trafgroup;
|
||||
ldap_trafgroup_handler.next = pluginlink->commandhandlers->next;
|
||||
pluginlink->commandhandlers->next = &ldap_trafgroup_handler;
|
||||
|
||||
/* add command: ldapattr cn memberOf usercaselow=1 */
|
||||
ldap_attrsgroup_handler.minargs = 3;
|
||||
ldap_attrsgroup_handler.maxargs = 4;
|
||||
ldap_attrsgroup_handler.command = "ldapattr";
|
||||
ldap_attrsgroup_handler.handler = h_attrsgroup;
|
||||
ldap_attrsgroup_handler.next = pluginlink->commandhandlers->next;
|
||||
pluginlink->commandhandlers->next = &ldap_attrsgroup_handler;
|
||||
|
||||
/* add command: ldapdircount c:\3proxy\ */
|
||||
ldap_dircount_handler.minargs = 2;
|
||||
ldap_dircount_handler.maxargs = 2;
|
||||
ldap_dircount_handler.command = "ldapdircount";
|
||||
ldap_dircount_handler.handler = h_dircount;
|
||||
ldap_dircount_handler.next = pluginlink->commandhandlers->next;
|
||||
pluginlink->commandhandlers->next = &ldap_dircount_handler;
|
||||
|
||||
/*create job shedule for processing reload, save counters to file */
|
||||
memset(&myschedule,0,sizeof(struct schedule));
|
||||
myschedule.type=MINUTELY;
|
||||
myschedule.function=savecouters;
|
||||
myschedule.next = *pluginlink->schedule;
|
||||
*pluginlink->schedule=&myschedule;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,592 +0,0 @@
|
||||
----------------------------win1251------------------------------
|
||||
Плагин аутентификации в LDAP для сервера 3proxу (ОС windows,unix)
|
||||
(c) Lopuchov Kirill lopuchov@mail.ru
|
||||
|
||||
1. Краткое описание
|
||||
|
||||
* Поддерживается только аутентификация открытым текстом (basic)
|
||||
* Поддерживается создание лимитов по трафику для групп пользователей
|
||||
(в день,месяц,неделю)
|
||||
* Поддерживается создание лимитов по скорости для групп пользователей
|
||||
(пока лимиты только на входящий трафик)
|
||||
|
||||
* Отсутcтвует кеширование имен пользователей.
|
||||
|
||||
В качестве интерфейса доступа к ldap используется библиотека openldap,
|
||||
поэтому плагин может компилироваться и работать как на Windows 98/2000/XP
|
||||
так и на различных unix подобных системах например Linux,FreeBSD.
|
||||
Все тесты работоспособности проводились на сервере с Active Directory в
|
||||
ее реализации ldap но в принципе должно работать и на других ldap системах.
|
||||
|
||||
Для компиляции и тестирования под ОС Windows использовался пакет Dev-C++
|
||||
http://www.bloodshed.net/dev/ и часть библиотек OpenLDAP for Windows
|
||||
http://lucas.bergmans.us/hacks/openldap/
|
||||
версия openldap-2.2.29-db-4.3.29-openssl-0.9.8a-win32_Setup.exe,
|
||||
версия этой же библиотеки идет в комплекте к плагину.
|
||||
|
||||
под unix подобной ОС (Freebsd) использовался стандартный gcc.
|
||||
и библиотеки openldap-client.
|
||||
|
||||
|
||||
|
||||
2. Настройка плагина.
|
||||
|
||||
2.1 Для подключения к LDAP серверу используется комманда ldapconnect .
|
||||
Первый параметр определят ip адрес или host имя LDAP сервера ,
|
||||
второй параметр имя пользователя от имени корого будут совершиться
|
||||
вся дальнейшая работа с ldap каталогом такая как поиск пользователей
|
||||
и проверка их принадлежности к той или иной группе, третий параметр это
|
||||
пароль для этого пользователя.
|
||||
|
||||
У такого пользовате в контекстет Active Directory могут отсутсвовать
|
||||
права администратора для нормальной работы плагина. В классических Open Ldap
|
||||
серверах под xNIX таким пользователем может выступать anonymous.
|
||||
|
||||
Пример:
|
||||
ldapconnect 192.160.0.1 cn=ldap,cn=users,dc=domain,dc=ru ldap
|
||||
|
||||
2.2 Для определения в каком контексте искать пользователей и группы
|
||||
служит комманда ldapsbase
|
||||
Пример:
|
||||
ldapsbase cn=users,dc=domain,dc=ru
|
||||
|
||||
2.3 Комманда ldapattr служит для определния различных параметров плагина.
|
||||
a)первый параметр определяет атрибут "пользователь" в контексте ldap каталога
|
||||
в Active Directory это как правило "cn" , в других ldap серверах "uid".
|
||||
b)второй параметр опеределяет атрибут "группа" в контексте ldap каталога
|
||||
в Active Directory это как правило "memberof" , в других ldap серверах "ou".
|
||||
c)третий параметр может не обязательный и может содержать 0 или 1
|
||||
1 - означает, что при авторизации пользователя или создании для него
|
||||
орграничения по трафику его имя будет приводится к нижнему регистру
|
||||
(примечание: только для имен пользователей на английском) .
|
||||
Этот параметр создан для исключения случаев когда LDAP каталог при
|
||||
авторизации не отличает имен пользователей в регистрах.
|
||||
|
||||
Пример:
|
||||
ldapattr cn memberof 1
|
||||
|
||||
2.4 Комманда ldapaccess служит для определения "признака" доступности
|
||||
пользователю вообще пройти авторизацию на proxy сервере. В контексте
|
||||
ldap каталога это ЗНАЧЕНИЕ атрибута "группы" описанной в комманде ldapattr.
|
||||
|
||||
Пример:
|
||||
ldapaccess CN=internet,CN=Users,DC=domain,DC=ru
|
||||
|
||||
Например: для Active Directory это будет пользователь входящий в группу
|
||||
internet. Тоесть при проверке можно ли пользователю работать с proxy
|
||||
формируется фильтр он должен попасть в следующий фильтр:
|
||||
(&(cn=имяпользователя)(memberof=CN=internet,CN=Users,DC=domain,DC=ru))
|
||||
|
||||
2.5 Комманда ldapuserenv служит для формирования строки имени пользователя
|
||||
который пытается пройти авторизацию в ldap. Тоесть фактически это base DN
|
||||
для пользователя.
|
||||
|
||||
Пример:
|
||||
ldapuserenv cn=users,dc=domain,dc=ru
|
||||
|
||||
|
||||
2.7 Комманда ldaptrafgroup служит для создания лимитов
|
||||
ОНИ ОБЯЗАТЕЛЬНО ДОЛЖНА ИДТИ ПОСЛЕ ВСЕХ остальных комманд плагина.
|
||||
a) первый параметр это название группы (значение ldap атрибута ) в которую
|
||||
входит пользователь.
|
||||
b) второй параметр на какой период накладывается ограничение по объему
|
||||
трафика . Может иметь одно из следующих значений "MONTHLY","DAILY","WEEKLY".
|
||||
с) третий параметр это размер лимита в мегабайтах .
|
||||
в) четвертый параметр это ограничение по скорости в бит/сек.
|
||||
|
||||
Лимиты накладываются персонально на пользователя входящего в группу,
|
||||
а не НА группу в целом.
|
||||
В данном примере в Active Directory создана группа с именем traf200m
|
||||
куда ключенны все пользователи кторым необходим данный лимит 200 Мбайт,
|
||||
в месяц с входящей полосой 60000 бит/сек НА КАЖДОГО ПОЛЬЗОВАТЕЛЯ.
|
||||
|
||||
Пример:
|
||||
ldaptrafgroup CN=traf200m,CN=Users,DC=domain,DC=ru MONTHLY 200 60000
|
||||
|
||||
|
||||
Счетчики храняться для каждого пользователя в отдельном файле,имя которых
|
||||
формируется, как имя пользователя и расширение lc. Сохранение счетчиков
|
||||
происходит раз в минуту.
|
||||
|
||||
2.6 Комманда ldapdircount служит для указания директории куда будут
|
||||
сохраняться файлы с пользовательскими счетчиками. Путь к директории
|
||||
надо заканчивать слэшем, прямой или обратный в зависимости от ОС.
|
||||
|
||||
Пример:
|
||||
ldapdircount c:\3proxy\counter\
|
||||
ldapdircount /usr/3proxy/counter/
|
||||
|
||||
|
||||
Настройка 3proxy
|
||||
---------------------
|
||||
# ВНИМАНИЕ ! Не забывайте что daemon или service должен идти первой строкой
|
||||
# конфигурационного файла,то есть до загрузки любых плагинов
|
||||
daemon
|
||||
|
||||
# для win32
|
||||
plugin "с:\3proxy\ldapauth.dll" start
|
||||
# для unix
|
||||
plugin "/3proxy/libldapauth.so" start
|
||||
|
||||
ldapconnect 192.160.0.1 cn=ldap,cn=users,dc=domain,dc=ru ldap
|
||||
ldapsbase cn=users,dc=domain,dc=ru
|
||||
ldapaccess CN=internet,CN=Users,DC=domain,DC=ru
|
||||
ldapuserenv cn=users,dc=domain,dc=ru
|
||||
ldapdircount /3proxy/counter/
|
||||
ldapattr cn memberof 1
|
||||
|
||||
ldaptrafgroup CN=traf200m,CN=Users,DC=domain,DC=ru MONTHLY 200 60000
|
||||
ldaptrafgroup CN=traf60d,CN=Users,DC=domain,DC=ru DAILY 60 80000
|
||||
ldaptrafgroup CN=traf100w,CN=Users,DC=domain,DC=ru WEEKLY 100 80000
|
||||
|
||||
auth ldap
|
||||
allow * * * *
|
||||
proxy -p3128 -n
|
||||
--------------------
|
||||
|
||||
Так же возможна следующая конфигурация без учета трафика и ограничений
|
||||
по скорости.
|
||||
---------------------
|
||||
service
|
||||
|
||||
plugin "с:\3proxy\ldapauth.dll" start
|
||||
ldapconnect 192.160.0.1 cn=ldap,cn=users,dc=domain,dc=ru ldap
|
||||
ldapsbase cn=users,dc=domain,dc=ru
|
||||
ldapaccess CN=internet,CN=Users,DC=domain,DC=ru
|
||||
ldapuserenv cn=users,dc=domain,dc=ru
|
||||
ldapattr cn memberof 1
|
||||
auth ldap
|
||||
allow * * * *
|
||||
proxy -p3128 -n
|
||||
---------------------
|
||||
|
||||
Создание списков доступа
|
||||
|
||||
Чтобы можно было создавать ACL на основе списков пользователей входящих
|
||||
в различные группы каталога ldap существует утилита getldapuser
|
||||
Данной утилите могут переданы 5 параметров :
|
||||
|
||||
getldapuser < ldapserver basedn user_attribute filter user password >
|
||||
|
||||
ldapserver - имя или ip адрес LDAP сервера
|
||||
basedn - контекст подключения к LDAP (например: cn=users,dc=domain,dc=com)
|
||||
user_attribute - название пользовательского атрибута (например:
|
||||
в Active Directory это cn в других LDAP каталогах он может
|
||||
быт ou)
|
||||
filter - фильтр по какому пользователи будут отбираться из LDAP (например:
|
||||
для Active Directory вывести всех пользователей входящих в группу
|
||||
internet будет следующая строка
|
||||
(memberOf=cn=internet,cn=Users,dc=domain,dc=com) )
|
||||
|
||||
user - имя пользователя для подключения к серверу
|
||||
password - пароль (если есть)
|
||||
|
||||
Пример использования getldapuser в 3proxy.
|
||||
|
||||
Необходимо дать доступ к icq только определенным пользоватлям . Cоздаем
|
||||
в AD группу icquser заносим туда нужных пользователей.
|
||||
Создаем bat файл следующего содержания который будет формировать файл
|
||||
c:\3proxy\icquser со списком пользователей:
|
||||
-------------------------------------------
|
||||
getldapuser 192.168.0.1 dc=domain,dc=com cn (memberOf=cn=icquser,cn=Users,dc=domain,dc=com)
|
||||
cn=admin,cn=users,dc=domain,dc=com password > c:\3proxy\icquser
|
||||
-------------------------------------------
|
||||
Вставляем данный bat файл на периодическое выполнение.
|
||||
|
||||
Далее прописываем 3proxy.cfg след строки
|
||||
-------------------------------------------------
|
||||
monitor "c:\3proxy\icquser"
|
||||
|
||||
auth ldap
|
||||
allow $"c:\3proxy\icquser" * *icq.com
|
||||
deny * * *icq.com
|
||||
allow *
|
||||
proxy -n
|
||||
-------------------------------------------------
|
||||
|
||||
|
||||
Компиляция плагина на различных ОС
|
||||
|
||||
1) Win32 (windows 98/NT/XP/2000/2003)
|
||||
Для сборки и работы плагина в архиве с ним уже идут в каталоге ldapwindev
|
||||
следующие библиотеки (версия 2.2.29).
|
||||
|
||||
libcrypto.dll
|
||||
liblber.dll
|
||||
libldap.dll
|
||||
libssl.dll
|
||||
и заголовочные файлы
|
||||
lber.h
|
||||
lber_types.h
|
||||
ldap.h
|
||||
ldap_cdefs.h
|
||||
ldap_features.h
|
||||
ldap_schema.h
|
||||
ldap_utf8.h
|
||||
|
||||
Далее вам необходимо скачать и установить компилятор Dev-Cpp с сайта
|
||||
http://www.bloodshed.net/dev/
|
||||
|
||||
Далее скачать исходные тексты 3proxy отсюда:
|
||||
http://3proxy.ru/current/3proxy-0.6-devel.tgz и распаковать.
|
||||
В каталог \src\plugins скопировать каталог с исходными текстами
|
||||
плагина. Скорректировать com-win32.bat файл с учетом того где у Вас установлен
|
||||
компилятор gcc , например:
|
||||
-------------com-win32.bat----------------
|
||||
c:\Dev-Cpp\bin\gcc -shared -o ldapauth.dll ldapauth.c -DWIN32 -I"./ldapwindev" -L"./ldapwindev" -lldap
|
||||
------------------------------------------
|
||||
И запустить на выполнение com-win32.bat после этого у Вас должна появится
|
||||
библиотека ldapauth.dll и исполняемый файл getldapuser.exe .
|
||||
Для дальнейшей работы получившиеся файлы и все библиотеки dll из каталога
|
||||
ldapwindev скопировать в каталог с 3proxy.
|
||||
|
||||
2) xNIX (linux,freebsd и т.п. )
|
||||
|
||||
Перед компиляцией нужно проверить чтобы в системе был уcтановлен
|
||||
OpenLDAP client. В системе должны присутвовать следующие
|
||||
библиотеки:
|
||||
|
||||
liblber.a
|
||||
libldap.a
|
||||
liblber.so
|
||||
libldap.so
|
||||
|
||||
и заголовочные файлы
|
||||
lber.h
|
||||
lber_types.h
|
||||
ldap.h
|
||||
ldap_cdefs.h
|
||||
ldap_features.h
|
||||
ldap_schema.h
|
||||
ldap_utf8.h
|
||||
|
||||
Установка клиента под разными ОС это делается либо инсталяцией готового пакета
|
||||
либо самостоятельная сборка данного клиента из исходных текстов которые
|
||||
расположенны тут ftp://ftp.openldap.org/pub/OpenLDAP/openldap-release/
|
||||
|
||||
Чтобы собрать пакет, необходимо скачать архив
|
||||
wget ftp://ftp.openldap.org/pub/OpenLDAP/openldap-release/openldap-2.3.9.tgz
|
||||
|
||||
распаковываем архив
|
||||
tar xvzf openldap-2.3.9.tgz
|
||||
|
||||
и запускаем скрипт автоконфигурации со следующими
|
||||
параметрами:
|
||||
./configure --enable-backends=no --enable-slapd=no
|
||||
|
||||
далее
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
Далее скачать исходные тексты 3proxy отсюда:
|
||||
http://3proxy.ru/current/3proxy-0.6-devel.tgz и распаковать.
|
||||
В каталог \src\plugins скопировать каталог с исходными текстами
|
||||
плагина. Изменить пути в файле com-unix.sh параметрах компиляции -I и -L
|
||||
к заголовочным и библиотечным файлам ldap для Вашей системы.
|
||||
|
||||
Выполнить следующие комманды:
|
||||
chmod +x com-unix.sh
|
||||
com-unix.sh
|
||||
|
||||
И запустить на выполнение com-unix.sh после этого у Вас должна появится
|
||||
библиотека ldapauth.so и исполняемый файл getldapuser.
|
||||
|
||||
Получившиеся файлы скопировать в каталог с 3proxy.
|
||||
----------------------------win1251------------------------------
|
||||
----------------------------KOI8-R------------------------------
|
||||
рМБЗЙО БХФЕОФЙЖЙЛБГЙЙ Ч LDAP ДМС УЕТЧЕТБ 3proxХ (пу windows,unix)
|
||||
(c) Lopuchov Kirill lopuchov@mail.ru
|
||||
|
||||
1. лТБФЛПЕ ПРЙУБОЙЕ
|
||||
|
||||
* рПДДЕТЦЙЧБЕФУС ФПМШЛП БХФЕОФЙЖЙЛБГЙС ПФЛТЩФЩН ФЕЛУФПН (basic)
|
||||
* рПДДЕТЦЙЧБЕФУС УПЪДБОЙЕ МЙНЙФПЧ РП ФТБЖЙЛХ ДМС ЗТХРР РПМШЪПЧБФЕМЕК
|
||||
(Ч ДЕОШ,НЕУСГ,ОЕДЕМА)
|
||||
* рПДДЕТЦЙЧБЕФУС УПЪДБОЙЕ МЙНЙФПЧ РП УЛПТПУФЙ ДМС ЗТХРР РПМШЪПЧБФЕМЕК
|
||||
(РПЛБ МЙНЙФЩ ФПМШЛП ОБ ЧИПДСЭЙК ФТБЖЙЛ)
|
||||
|
||||
* пФУХФcФЧХЕФ ЛЕЫЙТПЧБОЙЕ ЙНЕО РПМШЪПЧБФЕМЕК.
|
||||
|
||||
ч ЛБЮЕУФЧЕ ЙОФЕТЖЕКУБ ДПУФХРБ Л ldap ЙУРПМШЪХЕФУС ВЙВМЙПФЕЛБ openldap,
|
||||
РПЬФПНХ РМБЗЙО НПЦЕФ ЛПНРЙМЙТПЧБФШУС Й ТБВПФБФШ ЛБЛ ОБ Windows 98/2000/XP
|
||||
ФБЛ Й ОБ ТБЪМЙЮОЩИ unix РПДПВОЩИ УЙУФЕНБИ ОБРТЙНЕТ Linux,FreeBSD.
|
||||
чУЕ ФЕУФЩ ТБВПФПУРПУПВОПУФЙ РТПЧПДЙМЙУШ ОБ УЕТЧЕТЕ У Active Directory Ч
|
||||
ЕЕ ТЕБМЙЪБГЙЙ ldap ОП Ч РТЙОГЙРЕ ДПМЦОП ТБВПФБФШ Й ОБ ДТХЗЙИ ldap УЙУФЕНБИ.
|
||||
|
||||
дМС ЛПНРЙМСГЙЙ Й ФЕУФЙТПЧБОЙС РПД пу Windows ЙУРПМШЪПЧБМУС РБЛЕФ Dev-C++
|
||||
http://www.bloodshed.net/dev/ Й ЮБУФШ ВЙВМЙПФЕЛ OpenLDAP for Windows
|
||||
http://lucas.bergmans.us/hacks/openldap/
|
||||
ЧЕТУЙС openldap-2.2.29-db-4.3.29-openssl-0.9.8a-win32_Setup.exe,
|
||||
ЧЕТУЙС ЬФПК ЦЕ ВЙВМЙПФЕЛЙ ЙДЕФ Ч ЛПНРМЕЛФЕ Л РМБЗЙОХ.
|
||||
|
||||
РПД unix РПДПВОПК пу (Freebsd) ЙУРПМШЪПЧБМУС УФБОДБТФОЩК gcc.
|
||||
Й ВЙВМЙПФЕЛЙ openldap-client.
|
||||
|
||||
|
||||
|
||||
2. оБУФТПКЛБ РМБЗЙОБ.
|
||||
|
||||
2.1 дМС РПДЛМАЮЕОЙС Л LDAP УЕТЧЕТХ ЙУРПМШЪХЕФУС ЛПННБОДБ ldapconnect .
|
||||
рЕТЧЩК РБТБНЕФТ ПРТЕДЕМСФ ip БДТЕУ ЙМЙ host ЙНС LDAP УЕТЧЕТБ ,
|
||||
ЧФПТПК РБТБНЕФТ ЙНС РПМШЪПЧБФЕМС ПФ ЙНЕОЙ ЛПТПЗП ВХДХФ УПЧЕТЫЙФШУС
|
||||
ЧУС ДБМШОЕКЫБС ТБВПФБ У ldap ЛБФБМПЗПН ФБЛБС ЛБЛ РПЙУЛ РПМШЪПЧБФЕМЕК
|
||||
Й РТПЧЕТЛБ ЙИ РТЙОБДМЕЦОПУФЙ Л ФПК ЙМЙ ЙОПК ЗТХРРЕ, ФТЕФЙК РБТБНЕФТ ЬФП
|
||||
РБТПМШ ДМС ЬФПЗП РПМШЪПЧБФЕМС.
|
||||
|
||||
х ФБЛПЗП РПМШЪПЧБФЕ Ч ЛПОФЕЛУФЕФ Active Directory НПЗХФ ПФУХФУЧПЧБФШ
|
||||
РТБЧБ БДНЙОЙУФТБФПТБ ДМС ОПТНБМШОПК ТБВПФЩ РМБЗЙОБ. ч ЛМБУУЙЮЕУЛЙИ Open Ldap
|
||||
УЕТЧЕТБИ РПД xNIX ФБЛЙН РПМШЪПЧБФЕМЕН НПЦЕФ ЧЩУФХРБФШ anonymous.
|
||||
|
||||
рТЙНЕТ:
|
||||
ldapconnect 192.160.0.1 cn=ldap,cn=users,dc=domain,dc=ru ldap
|
||||
|
||||
2.2 дМС ПРТЕДЕМЕОЙС Ч ЛБЛПН ЛПОФЕЛУФЕ ЙУЛБФШ РПМШЪПЧБФЕМЕК Й ЗТХРРЩ
|
||||
УМХЦЙФ ЛПННБОДБ ldapsbase
|
||||
рТЙНЕТ:
|
||||
ldapsbase cn=users,dc=domain,dc=ru
|
||||
|
||||
2.3 лПННБОДБ ldapattr УМХЦЙФ ДМС ПРТЕДЕМОЙС ТБЪМЙЮОЩИ РБТБНЕФТПЧ РМБЗЙОБ.
|
||||
a)РЕТЧЩК РБТБНЕФТ ПРТЕДЕМСЕФ БФТЙВХФ "РПМШЪПЧБФЕМШ" Ч ЛПОФЕЛУФЕ ldap ЛБФБМПЗБ
|
||||
Ч Active Directory ЬФП ЛБЛ РТБЧЙМП "cn" , Ч ДТХЗЙИ ldap УЕТЧЕТБИ "uid".
|
||||
b)ЧФПТПК РБТБНЕФТ ПРЕТЕДЕМСЕФ БФТЙВХФ "ЗТХРРБ" Ч ЛПОФЕЛУФЕ ldap ЛБФБМПЗБ
|
||||
Ч Active Directory ЬФП ЛБЛ РТБЧЙМП "memberof" , Ч ДТХЗЙИ ldap УЕТЧЕТБИ "ou".
|
||||
c)ФТЕФЙК РБТБНЕФТ НПЦЕФ ОЕ ПВСЪБФЕМШОЩК Й НПЦЕФ УПДЕТЦБФШ 0 ЙМЙ 1
|
||||
1 - ПЪОБЮБЕФ, ЮФП РТЙ БЧФПТЙЪБГЙЙ РПМШЪПЧБФЕМС ЙМЙ УПЪДБОЙЙ ДМС ОЕЗП
|
||||
ПТЗТБОЙЮЕОЙС РП ФТБЖЙЛХ ЕЗП ЙНС ВХДЕФ РТЙЧПДЙФУС Л ОЙЦОЕНХ ТЕЗЙУФТХ
|
||||
(РТЙНЕЮБОЙЕ: ФПМШЛП ДМС ЙНЕО РПМШЪПЧБФЕМЕК ОБ БОЗМЙКУЛПН) .
|
||||
ьФПФ РБТБНЕФТ УПЪДБО ДМС ЙУЛМАЮЕОЙС УМХЮБЕЧ ЛПЗДБ LDAP ЛБФБМПЗ РТЙ
|
||||
БЧФПТЙЪБГЙЙ ОЕ ПФМЙЮБЕФ ЙНЕО РПМШЪПЧБФЕМЕК Ч ТЕЗЙУФТБИ.
|
||||
|
||||
рТЙНЕТ:
|
||||
ldapattr cn memberof 1
|
||||
|
||||
2.4 лПННБОДБ ldapaccess УМХЦЙФ ДМС ПРТЕДЕМЕОЙС "РТЙЪОБЛБ" ДПУФХРОПУФЙ
|
||||
РПМШЪПЧБФЕМА ЧППВЭЕ РТПКФЙ БЧФПТЙЪБГЙА ОБ proxy УЕТЧЕТЕ. ч ЛПОФЕЛУФЕ
|
||||
ldap ЛБФБМПЗБ ЬФП ъобюеойе БФТЙВХФБ "ЗТХРРЩ" ПРЙУБООПК Ч ЛПННБОДЕ ldapattr.
|
||||
|
||||
рТЙНЕТ:
|
||||
ldapaccess CN=internet,CN=Users,DC=domain,DC=ru
|
||||
|
||||
оБРТЙНЕТ: ДМС Active Directory ЬФП ВХДЕФ РПМШЪПЧБФЕМШ ЧИПДСЭЙК Ч ЗТХРРХ
|
||||
internet. фПЕУФШ РТЙ РТПЧЕТЛЕ НПЦОП МЙ РПМШЪПЧБФЕМА ТБВПФБФШ У proxy
|
||||
ЖПТНЙТХЕФУС ЖЙМШФТ ПО ДПМЦЕО РПРБУФШ Ч УМЕДХАЭЙК ЖЙМШФТ:
|
||||
(&(cn=ЙНСРПМШЪПЧБФЕМС)(memberof=CN=internet,CN=Users,DC=domain,DC=ru))
|
||||
|
||||
2.5 лПННБОДБ ldapuserenv УМХЦЙФ ДМС ЖПТНЙТПЧБОЙС УФТПЛЙ ЙНЕОЙ РПМШЪПЧБФЕМС
|
||||
ЛПФПТЩК РЩФБЕФУС РТПКФЙ БЧФПТЙЪБГЙА Ч ldap. фПЕУФШ ЖБЛФЙЮЕУЛЙ ЬФП base DN
|
||||
ДМС РПМШЪПЧБФЕМС.
|
||||
|
||||
рТЙНЕТ:
|
||||
ldapuserenv cn=users,dc=domain,dc=ru
|
||||
|
||||
|
||||
2.7 лПННБОДБ ldaptrafgroup УМХЦЙФ ДМС УПЪДБОЙС МЙНЙФПЧ
|
||||
пой пвсъбфемшоп дпмцоб йдфй рпуме чуеи ПУФБМШОЩИ ЛПННБОД РМБЗЙОБ.
|
||||
a) РЕТЧЩК РБТБНЕФТ ЬФП ОБЪЧБОЙЕ ЗТХРРЩ (ЪОБЮЕОЙЕ ldap БФТЙВХФБ ) Ч ЛПФПТХА
|
||||
ЧИПДЙФ РПМШЪПЧБФЕМШ.
|
||||
b) ЧФПТПК РБТБНЕФТ ОБ ЛБЛПК РЕТЙПД ОБЛМБДЩЧБЕФУС ПЗТБОЙЮЕОЙЕ РП ПВЯЕНХ
|
||||
ФТБЖЙЛБ . нПЦЕФ ЙНЕФШ ПДОП ЙЪ УМЕДХАЭЙИ ЪОБЮЕОЙК "MONTHLY","DAILY","WEEKLY".
|
||||
У) ФТЕФЙК РБТБНЕФТ ЬФП ТБЪНЕТ МЙНЙФБ Ч НЕЗБВБКФБИ .
|
||||
Ч) ЮЕФЧЕТФЩК РБТБНЕФТ ЬФП ПЗТБОЙЮЕОЙЕ РП УЛПТПУФЙ Ч ВЙФ/УЕЛ.
|
||||
|
||||
мЙНЙФЩ ОБЛМБДЩЧБАФУС РЕТУПОБМШОП ОБ РПМШЪПЧБФЕМС ЧИПДСЭЕЗП Ч ЗТХРРХ,
|
||||
Б ОЕ об ЗТХРРХ Ч ГЕМПН.
|
||||
ч ДБООПН РТЙНЕТЕ Ч Active Directory УПЪДБОБ ЗТХРРБ У ЙНЕОЕН traf200m
|
||||
ЛХДБ ЛМАЮЕООЩ ЧУЕ РПМШЪПЧБФЕМЙ ЛФПТЩН ОЕПВИПДЙН ДБООЩК МЙНЙФ 200 нВБКФ,
|
||||
Ч НЕУСГ У ЧИПДСЭЕК РПМПУПК 60000 ВЙФ/УЕЛ об лбцдпзп рпмшъпчбфемс.
|
||||
|
||||
рТЙНЕТ:
|
||||
ldaptrafgroup CN=traf200m,CN=Users,DC=domain,DC=ru MONTHLY 200 60000
|
||||
|
||||
|
||||
уЮЕФЮЙЛЙ ИТБОСФШУС ДМС ЛБЦДПЗП РПМШЪПЧБФЕМС Ч ПФДЕМШОПН ЖБКМЕ,ЙНС ЛПФПТЩИ
|
||||
ЖПТНЙТХЕФУС, ЛБЛ ЙНС РПМШЪПЧБФЕМС Й ТБУЫЙТЕОЙЕ lc. уПИТБОЕОЙЕ УЮЕФЮЙЛПЧ
|
||||
РТПЙУИПДЙФ ТБЪ Ч НЙОХФХ.
|
||||
|
||||
2.6 лПННБОДБ ldapdircount УМХЦЙФ ДМС ХЛБЪБОЙС ДЙТЕЛФПТЙЙ ЛХДБ ВХДХФ
|
||||
УПИТБОСФШУС ЖБКМЩ У РПМШЪПЧБФЕМШУЛЙНЙ УЮЕФЮЙЛБНЙ. рХФШ Л ДЙТЕЛФПТЙЙ
|
||||
ОБДП ЪБЛБОЮЙЧБФШ УМЬЫЕН, РТСНПК ЙМЙ ПВТБФОЩК Ч ЪБЧЙУЙНПУФЙ ПФ пу.
|
||||
|
||||
рТЙНЕТ:
|
||||
ldapdircount c:\3proxy\counter\
|
||||
ldapdircount /usr/3proxy/counter/
|
||||
|
||||
|
||||
оБУФТПКЛБ 3proxy
|
||||
---------------------
|
||||
# чойнбойе ! оЕ ЪБВЩЧБКФЕ ЮФП daemon ЙМЙ service ДПМЦЕО ЙДФЙ РЕТЧПК УФТПЛПК
|
||||
# ЛПОЖЙЗХТБГЙПООПЗП ЖБКМБ,ФП ЕУФШ ДП ЪБЗТХЪЛЙ МАВЩИ РМБЗЙОПЧ
|
||||
daemon
|
||||
|
||||
# ДМС win32
|
||||
plugin "У:\3proxy\ldapauth.dll" start
|
||||
# ДМС unix
|
||||
plugin "/3proxy/libldapauth.so" start
|
||||
|
||||
ldapconnect 192.160.0.1 cn=ldap,cn=users,dc=domain,dc=ru ldap
|
||||
ldapsbase cn=users,dc=domain,dc=ru
|
||||
ldapaccess CN=internet,CN=Users,DC=domain,DC=ru
|
||||
ldapuserenv cn=users,dc=domain,dc=ru
|
||||
ldapdircount /3proxy/counter/
|
||||
ldapattr cn memberof 1
|
||||
|
||||
ldaptrafgroup CN=traf200m,CN=Users,DC=domain,DC=ru MONTHLY 200 60000
|
||||
ldaptrafgroup CN=traf60d,CN=Users,DC=domain,DC=ru DAILY 60 80000
|
||||
ldaptrafgroup CN=traf100w,CN=Users,DC=domain,DC=ru WEEKLY 100 80000
|
||||
|
||||
auth ldap
|
||||
allow * * * *
|
||||
proxy -p3128 -n
|
||||
--------------------
|
||||
|
||||
фБЛ ЦЕ ЧПЪНПЦОБ УМЕДХАЭБС ЛПОЖЙЗХТБГЙС ВЕЪ ХЮЕФБ ФТБЖЙЛБ Й ПЗТБОЙЮЕОЙК
|
||||
РП УЛПТПУФЙ.
|
||||
---------------------
|
||||
service
|
||||
|
||||
plugin "У:\3proxy\ldapauth.dll" start
|
||||
ldapconnect 192.160.0.1 cn=ldap,cn=users,dc=domain,dc=ru ldap
|
||||
ldapsbase cn=users,dc=domain,dc=ru
|
||||
ldapaccess CN=internet,CN=Users,DC=domain,DC=ru
|
||||
ldapuserenv cn=users,dc=domain,dc=ru
|
||||
ldapattr cn memberof 1
|
||||
auth ldap
|
||||
allow * * * *
|
||||
proxy -p3128 -n
|
||||
---------------------
|
||||
|
||||
уПЪДБОЙЕ УРЙУЛПЧ ДПУФХРБ
|
||||
|
||||
юФПВЩ НПЦОП ВЩМП УПЪДБЧБФШ ACL ОБ ПУОПЧЕ УРЙУЛПЧ РПМШЪПЧБФЕМЕК ЧИПДСЭЙИ
|
||||
Ч ТБЪМЙЮОЩЕ ЗТХРРЩ ЛБФБМПЗБ ldap УХЭЕУФЧХЕФ ХФЙМЙФБ getldapuser
|
||||
дБООПК ХФЙМЙФЕ НПЗХФ РЕТЕДБОЩ 5 РБТБНЕФТПЧ :
|
||||
|
||||
getldapuser < ldapserver basedn user_attribute filter user password >
|
||||
|
||||
ldapserver - ЙНС ЙМЙ ip БДТЕУ LDAP УЕТЧЕТБ
|
||||
basedn - ЛПОФЕЛУФ РПДЛМАЮЕОЙС Л LDAP (ОБРТЙНЕТ: cn=users,dc=domain,dc=com)
|
||||
user_attribute - ОБЪЧБОЙЕ РПМШЪПЧБФЕМШУЛПЗП БФТЙВХФБ (ОБРТЙНЕТ:
|
||||
Ч Active Directory ЬФП cn Ч ДТХЗЙИ LDAP ЛБФБМПЗБИ ПО НПЦЕФ
|
||||
ВЩФ ou)
|
||||
filter - ЖЙМШФТ РП ЛБЛПНХ РПМШЪПЧБФЕМЙ ВХДХФ ПФВЙТБФШУС ЙЪ LDAP (ОБРТЙНЕТ:
|
||||
ДМС Active Directory ЧЩЧЕУФЙ ЧУЕИ РПМШЪПЧБФЕМЕК ЧИПДСЭЙИ Ч ЗТХРРХ
|
||||
internet ВХДЕФ УМЕДХАЭБС УФТПЛБ
|
||||
(memberOf=cn=internet,cn=Users,dc=domain,dc=com) )
|
||||
|
||||
user - ЙНС РПМШЪПЧБФЕМС ДМС РПДЛМАЮЕОЙС Л УЕТЧЕТХ
|
||||
password - РБТПМШ (ЕУМЙ ЕУФШ)
|
||||
|
||||
рТЙНЕТ ЙУРПМШЪПЧБОЙС getldapuser Ч 3proxy.
|
||||
|
||||
оЕПВИПДЙНП ДБФШ ДПУФХР Л icq ФПМШЛП ПРТЕДЕМЕООЩН РПМШЪПЧБФМСН . CПЪДБЕН
|
||||
Ч AD ЗТХРРХ icquser ЪБОПУЙН ФХДБ ОХЦОЩИ РПМШЪПЧБФЕМЕК.
|
||||
уПЪДБЕН bat ЖБКМ УМЕДХАЭЕЗП УПДЕТЦБОЙС ЛПФПТЩК ВХДЕФ ЖПТНЙТПЧБФШ ЖБКМ
|
||||
c:\3proxy\icquser УП УРЙУЛПН РПМШЪПЧБФЕМЕК:
|
||||
-------------------------------------------
|
||||
getldapuser 192.168.0.1 dc=domain,dc=com cn (memberOf=cn=icquser,cn=Users,dc=domain,dc=com)
|
||||
cn=admin,cn=users,dc=domain,dc=com password > c:\3proxy\icquser
|
||||
-------------------------------------------
|
||||
чУФБЧМСЕН ДБООЩК bat ЖБКМ ОБ РЕТЙПДЙЮЕУЛПЕ ЧЩРПМОЕОЙЕ.
|
||||
|
||||
дБМЕЕ РТПРЙУЩЧБЕН 3proxy.cfg УМЕД УФТПЛЙ
|
||||
-------------------------------------------------
|
||||
monitor "c:\3proxy\icquser"
|
||||
|
||||
auth ldap
|
||||
allow $"c:\3proxy\icquser" * *icq.com
|
||||
deny * * *icq.com
|
||||
allow *
|
||||
proxy -n
|
||||
-------------------------------------------------
|
||||
|
||||
|
||||
лПНРЙМСГЙС РМБЗЙОБ ОБ ТБЪМЙЮОЩИ пу
|
||||
|
||||
1) Win32 (windows 98/NT/XP/2000/2003)
|
||||
дМС УВПТЛЙ Й ТБВПФЩ РМБЗЙОБ Ч БТИЙЧЕ У ОЙН ХЦЕ ЙДХФ Ч ЛБФБМПЗЕ ldapwindev
|
||||
УМЕДХАЭЙЕ ВЙВМЙПФЕЛЙ (ЧЕТУЙС 2.2.29).
|
||||
|
||||
libcrypto.dll
|
||||
liblber.dll
|
||||
libldap.dll
|
||||
libssl.dll
|
||||
Й ЪБЗПМПЧПЮОЩЕ ЖБКМЩ
|
||||
lber.h
|
||||
lber_types.h
|
||||
ldap.h
|
||||
ldap_cdefs.h
|
||||
ldap_features.h
|
||||
ldap_schema.h
|
||||
ldap_utf8.h
|
||||
|
||||
дБМЕЕ ЧБН ОЕПВИПДЙНП УЛБЮБФШ Й ХУФБОПЧЙФШ ЛПНРЙМСФПТ Dev-Cpp У УБКФБ
|
||||
http://www.bloodshed.net/dev/
|
||||
|
||||
дБМЕЕ УЛБЮБФШ ЙУИПДОЩЕ ФЕЛУФЩ 3proxy ПФУАДБ:
|
||||
http://3proxy.ru/current/3proxy-0.6-devel.tgz Й ТБУРБЛПЧБФШ.
|
||||
ч ЛБФБМПЗ \src\plugins УЛПРЙТПЧБФШ ЛБФБМПЗ У ЙУИПДОЩНЙ ФЕЛУФБНЙ
|
||||
РМБЗЙОБ. уЛПТТЕЛФЙТПЧБФШ com-win32.bat ЖБКМ У ХЮЕФПН ФПЗП ЗДЕ Х чБУ ХУФБОПЧМЕО
|
||||
ЛПНРЙМСФПТ gcc , ОБРТЙНЕТ:
|
||||
-------------com-win32.bat----------------
|
||||
c:\Dev-Cpp\bin\gcc -shared -o ldapauth.dll ldapauth.c -DWIN32 -I"./ldapwindev" -L"./ldapwindev" -lldap
|
||||
------------------------------------------
|
||||
й ЪБРХУФЙФШ ОБ ЧЩРПМОЕОЙЕ com-win32.bat РПУМЕ ЬФПЗП Х чБУ ДПМЦОБ РПСЧЙФУС
|
||||
ВЙВМЙПФЕЛБ ldapauth.dll Й ЙУРПМОСЕНЩК ЖБКМ getldapuser.exe .
|
||||
дМС ДБМШОЕКЫЕК ТБВПФЩ РПМХЮЙЧЫЙЕУС ЖБКМЩ Й ЧУЕ ВЙВМЙПФЕЛЙ dll ЙЪ ЛБФБМПЗБ
|
||||
ldapwindev УЛПРЙТПЧБФШ Ч ЛБФБМПЗ У 3proxy.
|
||||
|
||||
2) xNIX (linux,freebsd Й Ф.Р. )
|
||||
|
||||
рЕТЕД ЛПНРЙМСГЙЕК ОХЦОП РТПЧЕТЙФШ ЮФПВЩ Ч УЙУФЕНЕ ВЩМ ХcФБОПЧМЕО
|
||||
OpenLDAP client. ч УЙУФЕНЕ ДПМЦОЩ РТЙУХФЧПЧБФШ УМЕДХАЭЙЕ
|
||||
ВЙВМЙПФЕЛЙ:
|
||||
|
||||
liblber.a
|
||||
libldap.a
|
||||
liblber.so
|
||||
libldap.so
|
||||
|
||||
Й ЪБЗПМПЧПЮОЩЕ ЖБКМЩ
|
||||
lber.h
|
||||
lber_types.h
|
||||
ldap.h
|
||||
ldap_cdefs.h
|
||||
ldap_features.h
|
||||
ldap_schema.h
|
||||
ldap_utf8.h
|
||||
|
||||
хУФБОПЧЛБ ЛМЙЕОФБ РПД ТБЪОЩНЙ пу ЬФП ДЕМБЕФУС МЙВП ЙОУФБМСГЙЕК ЗПФПЧПЗП РБЛЕФБ
|
||||
МЙВП УБНПУФПСФЕМШОБС УВПТЛБ ДБООПЗП ЛМЙЕОФБ ЙЪ ЙУИПДОЩИ ФЕЛУФПЧ ЛПФПТЩЕ
|
||||
ТБУРПМПЦЕООЩ ФХФ ftp://ftp.openldap.org/pub/OpenLDAP/openldap-release/
|
||||
|
||||
юФПВЩ УПВТБФШ РБЛЕФ, ОЕПВИПДЙНП УЛБЮБФШ БТИЙЧ
|
||||
wget ftp://ftp.openldap.org/pub/OpenLDAP/openldap-release/openldap-2.3.9.tgz
|
||||
|
||||
ТБУРБЛПЧЩЧБЕН БТИЙЧ
|
||||
tar xvzf openldap-2.3.9.tgz
|
||||
|
||||
Й ЪБРХУЛБЕН УЛТЙРФ БЧФПЛПОЖЙЗХТБГЙЙ УП УМЕДХАЭЙНЙ
|
||||
РБТБНЕФТБНЙ:
|
||||
./configure --enable-backends=no --enable-slapd=no
|
||||
|
||||
ДБМЕЕ
|
||||
|
||||
make
|
||||
make install
|
||||
|
||||
дБМЕЕ УЛБЮБФШ ЙУИПДОЩЕ ФЕЛУФЩ 3proxy ПФУАДБ:
|
||||
http://3proxy.ru/current/3proxy-0.6-devel.tgz Й ТБУРБЛПЧБФШ.
|
||||
ч ЛБФБМПЗ \src\plugins УЛПРЙТПЧБФШ ЛБФБМПЗ У ЙУИПДОЩНЙ ФЕЛУФБНЙ
|
||||
РМБЗЙОБ. йЪНЕОЙФШ РХФЙ Ч ЖБКМЕ com-unix.sh РБТБНЕФТБИ ЛПНРЙМСГЙЙ -I Й -L
|
||||
Л ЪБЗПМПЧПЮОЩН Й ВЙВМЙПФЕЮОЩН ЖБКМБН ldap ДМС чБЫЕК УЙУФЕНЩ.
|
||||
|
||||
чЩРПМОЙФШ УМЕДХАЭЙЕ ЛПННБОДЩ:
|
||||
chmod +x com-unix.sh
|
||||
com-unix.sh
|
||||
|
||||
й ЪБРХУФЙФШ ОБ ЧЩРПМОЕОЙЕ com-unix.sh РПУМЕ ЬФПЗП Х чБУ ДПМЦОБ РПСЧЙФУС
|
||||
ВЙВМЙПФЕЛБ ldapauth.so Й ЙУРПМОСЕНЩК ЖБКМ getldapuser.
|
||||
|
||||
рПМХЮЙЧЫЙЕУС ЖБКМЩ УЛПРЙТПЧБФШ Ч ЛБФБМПЗ У 3proxy.
|
||||
----------------------------KOI8-R------------------------------
|
@ -1 +0,0 @@
|
||||
include Makefile.var
|
@ -1,71 +0,0 @@
|
||||
all: $(BUILDDIR)PCREPlugin$(DLSUFFICS)
|
||||
|
||||
|
||||
pcre_compile$(OBJSUFFICS): pcre_compile.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_compile.c
|
||||
|
||||
pcre_config$(OBJSUFFICS): pcre_config.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_config.c
|
||||
|
||||
pcre_dfa_exec$(OBJSUFFICS): pcre_dfa_exec.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_dfa_exec.c
|
||||
|
||||
pcre_exec$(OBJSUFFICS): pcre_exec.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_exec.c
|
||||
|
||||
pcre_fullinfo$(OBJSUFFICS): pcre_fullinfo.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_fullinfo.c
|
||||
|
||||
pcre_get$(OBJSUFFICS): pcre_get.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_get.c
|
||||
|
||||
pcre_globals$(OBJSUFFICS): pcre_globals.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_globals.c
|
||||
|
||||
pcre_info$(OBJSUFFICS): pcre_info.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_info.c
|
||||
|
||||
pcre_maketables$(OBJSUFFICS): pcre_maketables.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_maketables.c
|
||||
|
||||
pcre_newline$(OBJSUFFICS): pcre_newline.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_newline.c
|
||||
|
||||
pcre_ord2utf8$(OBJSUFFICS): pcre_ord2utf8.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_ord2utf8.c
|
||||
|
||||
pcre_refcount$(OBJSUFFICS): pcre_refcount.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_refcount.c
|
||||
|
||||
pcre_study$(OBJSUFFICS): pcre_study.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_study.c
|
||||
|
||||
pcre_tables$(OBJSUFFICS): pcre_tables.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_tables.c
|
||||
|
||||
pcre_try_flipped$(OBJSUFFICS): pcre_try_flipped.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_try_flipped.c
|
||||
|
||||
pcre_ucp_searchfuncs$(OBJSUFFICS): pcre_ucp_searchfuncs.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_ucp_searchfuncs.c
|
||||
|
||||
pcre_valid_utf8$(OBJSUFFICS): pcre_valid_utf8.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_valid_utf8.c
|
||||
|
||||
pcre_version$(OBJSUFFICS): pcre_version.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_version.c
|
||||
|
||||
pcre_xclass$(OBJSUFFICS): pcre_xclass.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_xclass.c
|
||||
|
||||
pcre_dftables$(OBJSUFFICS): pcre_dftables.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_dftables.c
|
||||
|
||||
pcre_plugin$(OBJSUFFICS): pcre_plugin.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcre_plugin.c
|
||||
|
||||
pcreposix$(OBJSUFFICS): pcreposix.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pcreposix.c
|
||||
|
||||
$(BUILDDIR)PCREPlugin$(DLSUFFICS): pcre_compile$(OBJSUFFICS) pcre_config$(OBJSUFFICS) pcre_dfa_exec$(OBJSUFFICS) pcre_exec$(OBJSUFFICS) pcre_fullinfo$(OBJSUFFICS) pcre_get$(OBJSUFFICS) pcre_globals$(OBJSUFFICS) pcre_info$(OBJSUFFICS) pcre_maketables$(OBJSUFFICS) pcre_newline$(OBJSUFFICS) pcre_ord2utf8$(OBJSUFFICS) pcre_refcount$(OBJSUFFICS) pcre_study$(OBJSUFFICS) pcre_tables$(OBJSUFFICS) pcre_try_flipped$(OBJSUFFICS) pcre_ucp_searchfuncs$(OBJSUFFICS) pcre_valid_utf8$(OBJSUFFICS) pcre_version$(OBJSUFFICS) pcre_xclass$(OBJSUFFICS) pcre_dftables$(OBJSUFFICS) pcre_plugin$(OBJSUFFICS) pcreposix$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)../../$(BUILDDIR)PCREPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) pcre_compile$(OBJSUFFICS) pcre_config$(OBJSUFFICS) pcre_dfa_exec$(OBJSUFFICS) pcre_exec$(OBJSUFFICS) pcre_fullinfo$(OBJSUFFICS) pcre_get$(OBJSUFFICS) pcre_globals$(OBJSUFFICS) pcre_info$(OBJSUFFICS) pcre_maketables$(OBJSUFFICS) pcre_newline$(OBJSUFFICS) pcre_ord2utf8$(OBJSUFFICS) pcre_refcount$(OBJSUFFICS) pcre_study$(OBJSUFFICS) pcre_tables$(OBJSUFFICS) pcre_try_flipped$(OBJSUFFICS) pcre_ucp_searchfuncs$(OBJSUFFICS) pcre_valid_utf8$(OBJSUFFICS) pcre_version$(OBJSUFFICS) pcre_xclass$(OBJSUFFICS) pcre_dftables$(OBJSUFFICS) pcre_plugin$(OBJSUFFICS) pcreposix$(OBJSUFFICS)
|
@ -1,145 +0,0 @@
|
||||
|
||||
/* On Unix-like systems config.in is converted by "configure" into config.h.
|
||||
Some other environments also support the use of "configure". PCRE is written in
|
||||
Standard C, but there are a few non-standard things it can cope with, allowing
|
||||
it to run on SunOS4 and other "close to standard" systems.
|
||||
|
||||
On a non-Unix-like system you should just copy this file into config.h, and set
|
||||
up the macros the way you need them. You should normally change the definitions
|
||||
of HAVE_STRERROR and HAVE_MEMMOVE to 1. Unfortunately, because of the way
|
||||
autoconf works, these cannot be made the defaults. If your system has bcopy()
|
||||
and not memmove(), change the definition of HAVE_BCOPY instead of HAVE_MEMMOVE.
|
||||
If your system has neither bcopy() nor memmove(), leave them both as 0; an
|
||||
emulation function will be used. */
|
||||
|
||||
/* If you are compiling for a system that uses EBCDIC instead of ASCII
|
||||
character codes, define this macro as 1. On systems that can use "configure",
|
||||
this can be done via --enable-ebcdic. */
|
||||
|
||||
#ifndef EBCDIC
|
||||
#define EBCDIC 0
|
||||
#endif
|
||||
|
||||
#define PCRE_STATIC
|
||||
|
||||
/* If you are compiling for a system other than a Unix-like system or Win32,
|
||||
and it needs some magic to be inserted before the definition of a function that
|
||||
is exported by the library, define this macro to contain the relevant magic. If
|
||||
you do not define this macro, it defaults to "extern" for a C compiler and
|
||||
"extern C" for a C++ compiler on non-Win32 systems. This macro apears at the
|
||||
start of every exported function that is part of the external API. It does not
|
||||
appear on functions that are "external" in the C sense, but which are internal
|
||||
to the library. */
|
||||
|
||||
/* #define PCRE_DATA_SCOPE */
|
||||
|
||||
/* Define the following macro to empty if the "const" keyword does not work. */
|
||||
|
||||
#undef const
|
||||
|
||||
/* Define the following macro to "unsigned" if <stddef.h> does not define
|
||||
size_t. */
|
||||
|
||||
#undef size_t
|
||||
|
||||
/* The following two definitions are mainly for the benefit of SunOS4, which
|
||||
does not have the strerror() or memmove() functions that should be present in
|
||||
all Standard C libraries. The macros HAVE_STRERROR and HAVE_MEMMOVE should
|
||||
normally be defined with the value 1 for other systems, but unfortunately we
|
||||
cannot make this the default because "configure" files generated by autoconf
|
||||
will only change 0 to 1; they won't change 1 to 0 if the functions are not
|
||||
found. */
|
||||
|
||||
#define HAVE_STRERROR 0
|
||||
#define HAVE_MEMMOVE 0
|
||||
|
||||
/* There are some non-Unix-like systems that don't even have bcopy(). If this
|
||||
macro is false, an emulation is used. If HAVE_MEMMOVE is set to 1, the value of
|
||||
HAVE_BCOPY is not relevant. */
|
||||
|
||||
#define HAVE_BCOPY 0
|
||||
|
||||
/* The value of NEWLINE determines the newline character. The default is to
|
||||
leave it up to the compiler, but some sites want to force a particular value.
|
||||
On Unix-like systems, "configure" can be used to override this default. */
|
||||
|
||||
#ifndef NEWLINE
|
||||
#define NEWLINE '\n'
|
||||
#endif
|
||||
|
||||
/* The value of LINK_SIZE determines the number of bytes used to store links as
|
||||
offsets within the compiled regex. The default is 2, which allows for compiled
|
||||
patterns up to 64K long. This covers the vast majority of cases. However, PCRE
|
||||
can also be compiled to use 3 or 4 bytes instead. This allows for longer
|
||||
patterns in extreme cases. On systems that support it, "configure" can be used
|
||||
to override this default. */
|
||||
|
||||
#ifndef LINK_SIZE
|
||||
#define LINK_SIZE 2
|
||||
#endif
|
||||
|
||||
/* When calling PCRE via the POSIX interface, additional working storage is
|
||||
required for holding the pointers to capturing substrings because PCRE requires
|
||||
three integers per substring, whereas the POSIX interface provides only two. If
|
||||
the number of expected substrings is small, the wrapper function uses space on
|
||||
the stack, because this is faster than using malloc() for each call. The
|
||||
threshold above which the stack is no longer used is defined by POSIX_MALLOC_
|
||||
THRESHOLD. On systems that support it, "configure" can be used to override this
|
||||
default. */
|
||||
|
||||
#ifndef POSIX_MALLOC_THRESHOLD
|
||||
#define POSIX_MALLOC_THRESHOLD 10
|
||||
#endif
|
||||
|
||||
/* PCRE uses recursive function calls to handle backtracking while matching.
|
||||
This can sometimes be a problem on systems that have stacks of limited size.
|
||||
Define NO_RECURSE to get a version that doesn't use recursion in the match()
|
||||
function; instead it creates its own stack by steam using pcre_recurse_malloc()
|
||||
to obtain memory from the heap. For more detail, see the comments and other
|
||||
stuff just above the match() function. On systems that support it, "configure"
|
||||
can be used to set this in the Makefile (use --disable-stack-for-recursion). */
|
||||
|
||||
/* #define NO_RECURSE */
|
||||
|
||||
/* The value of MATCH_LIMIT determines the default number of times the internal
|
||||
match() function can be called during a single execution of pcre_exec(). There
|
||||
is a runtime interface for setting a different limit. The limit exists in order
|
||||
to catch runaway regular expressions that take for ever to determine that they
|
||||
do not match. The default is set very large so that it does not accidentally
|
||||
catch legitimate cases. On systems that support it, "configure" can be used to
|
||||
override this default default. */
|
||||
|
||||
#ifndef MATCH_LIMIT
|
||||
#define MATCH_LIMIT 10000000
|
||||
#endif
|
||||
|
||||
/* The above limit applies to all calls of match(), whether or not they
|
||||
increase the recursion depth. In some environments it is desirable to limit the
|
||||
depth of recursive calls of match() more strictly, in order to restrict the
|
||||
maximum amount of stack (or heap, if NO_RECURSE is defined) that is used. The
|
||||
value of MATCH_LIMIT_RECURSION applies only to recursive calls of match(). To
|
||||
have any useful effect, it must be less than the value of MATCH_LIMIT. There is
|
||||
a runtime method for setting a different limit. On systems that support it,
|
||||
"configure" can be used to override this default default. */
|
||||
|
||||
#ifndef MATCH_LIMIT_RECURSION
|
||||
#define MATCH_LIMIT_RECURSION MATCH_LIMIT
|
||||
#endif
|
||||
|
||||
/* These three limits are parameterized just in case anybody ever wants to
|
||||
change them. Care must be taken if they are increased, because they guard
|
||||
against integer overflow caused by enormously large patterns. */
|
||||
|
||||
#ifndef MAX_NAME_SIZE
|
||||
#define MAX_NAME_SIZE 32
|
||||
#endif
|
||||
|
||||
#ifndef MAX_NAME_COUNT
|
||||
#define MAX_NAME_COUNT 10000
|
||||
#endif
|
||||
|
||||
#ifndef MAX_DUPLENGTH
|
||||
#define MAX_DUPLENGTH 30000
|
||||
#endif
|
||||
|
||||
/* End */
|
@ -1,304 +0,0 @@
|
||||
#include "config.h"
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* This is the public header file for the PCRE library, to be #included by
|
||||
applications that call the PCRE functions.
|
||||
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef _PCRE_H
|
||||
#define _PCRE_H
|
||||
|
||||
/* The current PCRE version information. */
|
||||
|
||||
#define PCRE_MAJOR 7
|
||||
#define PCRE_MINOR 4
|
||||
#define PCRE_PRERELEASE
|
||||
#define PCRE_DATE 2007-09-21
|
||||
|
||||
/* When an application links to a PCRE DLL in Windows, the symbols that are
|
||||
imported have to be identified as such. When building PCRE, the appropriate
|
||||
export setting is defined in pcre_internal.h, which includes this file. So we
|
||||
don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
|
||||
|
||||
#if defined(_WIN32) && !defined(PCRE_STATIC)
|
||||
# ifndef PCRE_EXP_DECL
|
||||
# define PCRE_EXP_DECL extern __declspec(dllimport)
|
||||
# endif
|
||||
# ifdef __cplusplus
|
||||
# ifndef PCRECPP_EXP_DECL
|
||||
# define PCRECPP_EXP_DECL extern __declspec(dllimport)
|
||||
# endif
|
||||
# ifndef PCRECPP_EXP_DEFN
|
||||
# define PCRECPP_EXP_DEFN __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* By default, we use the standard "extern" declarations. */
|
||||
|
||||
#ifndef PCRE_EXP_DECL
|
||||
# ifdef __cplusplus
|
||||
# define PCRE_EXP_DECL extern "C"
|
||||
# else
|
||||
# define PCRE_EXP_DECL extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# ifndef PCRECPP_EXP_DECL
|
||||
# define PCRECPP_EXP_DECL extern
|
||||
# endif
|
||||
# ifndef PCRECPP_EXP_DEFN
|
||||
# define PCRECPP_EXP_DEFN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Have to include stdlib.h in order to ensure that size_t is defined;
|
||||
it is needed here for malloc. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Allow for C++ users */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Options */
|
||||
|
||||
#define PCRE_CASELESS 0x00000001
|
||||
#define PCRE_MULTILINE 0x00000002
|
||||
#define PCRE_DOTALL 0x00000004
|
||||
#define PCRE_EXTENDED 0x00000008
|
||||
#define PCRE_ANCHORED 0x00000010
|
||||
#define PCRE_DOLLAR_ENDONLY 0x00000020
|
||||
#define PCRE_EXTRA 0x00000040
|
||||
#define PCRE_NOTBOL 0x00000080
|
||||
#define PCRE_NOTEOL 0x00000100
|
||||
#define PCRE_UNGREEDY 0x00000200
|
||||
#define PCRE_NOTEMPTY 0x00000400
|
||||
#define PCRE_UTF8 0x00000800
|
||||
#define PCRE_NO_AUTO_CAPTURE 0x00001000
|
||||
#define PCRE_NO_UTF8_CHECK 0x00002000
|
||||
#define PCRE_AUTO_CALLOUT 0x00004000
|
||||
#define PCRE_PARTIAL 0x00008000
|
||||
#define PCRE_DFA_SHORTEST 0x00010000
|
||||
#define PCRE_DFA_RESTART 0x00020000
|
||||
#define PCRE_FIRSTLINE 0x00040000
|
||||
#define PCRE_DUPNAMES 0x00080000
|
||||
#define PCRE_NEWLINE_CR 0x00100000
|
||||
#define PCRE_NEWLINE_LF 0x00200000
|
||||
#define PCRE_NEWLINE_CRLF 0x00300000
|
||||
#define PCRE_NEWLINE_ANY 0x00400000
|
||||
#define PCRE_NEWLINE_ANYCRLF 0x00500000
|
||||
#define PCRE_BSR_ANYCRLF 0x00800000
|
||||
#define PCRE_BSR_UNICODE 0x01000000
|
||||
|
||||
/* Exec-time and get/set-time error codes */
|
||||
|
||||
#define PCRE_ERROR_NOMATCH (-1)
|
||||
#define PCRE_ERROR_NULL (-2)
|
||||
#define PCRE_ERROR_BADOPTION (-3)
|
||||
#define PCRE_ERROR_BADMAGIC (-4)
|
||||
#define PCRE_ERROR_UNKNOWN_OPCODE (-5)
|
||||
#define PCRE_ERROR_UNKNOWN_NODE (-5) /* For backward compatibility */
|
||||
#define PCRE_ERROR_NOMEMORY (-6)
|
||||
#define PCRE_ERROR_NOSUBSTRING (-7)
|
||||
#define PCRE_ERROR_MATCHLIMIT (-8)
|
||||
#define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */
|
||||
#define PCRE_ERROR_BADUTF8 (-10)
|
||||
#define PCRE_ERROR_BADUTF8_OFFSET (-11)
|
||||
#define PCRE_ERROR_PARTIAL (-12)
|
||||
#define PCRE_ERROR_BADPARTIAL (-13)
|
||||
#define PCRE_ERROR_INTERNAL (-14)
|
||||
#define PCRE_ERROR_BADCOUNT (-15)
|
||||
#define PCRE_ERROR_DFA_UITEM (-16)
|
||||
#define PCRE_ERROR_DFA_UCOND (-17)
|
||||
#define PCRE_ERROR_DFA_UMLIMIT (-18)
|
||||
#define PCRE_ERROR_DFA_WSSIZE (-19)
|
||||
#define PCRE_ERROR_DFA_RECURSE (-20)
|
||||
#define PCRE_ERROR_RECURSIONLIMIT (-21)
|
||||
#define PCRE_ERROR_NULLWSLIMIT (-22) /* No longer actually used */
|
||||
#define PCRE_ERROR_BADNEWLINE (-23)
|
||||
|
||||
/* Request types for pcre_fullinfo() */
|
||||
|
||||
#define PCRE_INFO_OPTIONS 0
|
||||
#define PCRE_INFO_SIZE 1
|
||||
#define PCRE_INFO_CAPTURECOUNT 2
|
||||
#define PCRE_INFO_BACKREFMAX 3
|
||||
#define PCRE_INFO_FIRSTBYTE 4
|
||||
#define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */
|
||||
#define PCRE_INFO_FIRSTTABLE 5
|
||||
#define PCRE_INFO_LASTLITERAL 6
|
||||
#define PCRE_INFO_NAMEENTRYSIZE 7
|
||||
#define PCRE_INFO_NAMECOUNT 8
|
||||
#define PCRE_INFO_NAMETABLE 9
|
||||
#define PCRE_INFO_STUDYSIZE 10
|
||||
#define PCRE_INFO_DEFAULT_TABLES 11
|
||||
#define PCRE_INFO_OKPARTIAL 12
|
||||
#define PCRE_INFO_JCHANGED 13
|
||||
#define PCRE_INFO_HASCRORLF 14
|
||||
|
||||
/* Request types for pcre_config(). Do not re-arrange, in order to remain
|
||||
compatible. */
|
||||
|
||||
#define PCRE_CONFIG_UTF8 0
|
||||
#define PCRE_CONFIG_NEWLINE 1
|
||||
#define PCRE_CONFIG_LINK_SIZE 2
|
||||
#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3
|
||||
#define PCRE_CONFIG_MATCH_LIMIT 4
|
||||
#define PCRE_CONFIG_STACKRECURSE 5
|
||||
#define PCRE_CONFIG_UNICODE_PROPERTIES 6
|
||||
#define PCRE_CONFIG_MATCH_LIMIT_RECURSION 7
|
||||
#define PCRE_CONFIG_BSR 8
|
||||
|
||||
/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine
|
||||
these bits, just add new ones on the end, in order to remain compatible. */
|
||||
|
||||
#define PCRE_EXTRA_STUDY_DATA 0x0001
|
||||
#define PCRE_EXTRA_MATCH_LIMIT 0x0002
|
||||
#define PCRE_EXTRA_CALLOUT_DATA 0x0004
|
||||
#define PCRE_EXTRA_TABLES 0x0008
|
||||
#define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0x0010
|
||||
|
||||
/* Types */
|
||||
|
||||
struct real_pcre; /* declaration; the definition is private */
|
||||
typedef struct real_pcre pcre;
|
||||
|
||||
/* When PCRE is compiled as a C++ library, the subject pointer type can be
|
||||
replaced with a custom type. For conventional use, the public interface is a
|
||||
const char *. */
|
||||
|
||||
#ifndef PCRE_SPTR
|
||||
#define PCRE_SPTR const char *
|
||||
#endif
|
||||
|
||||
/* The structure for passing additional data to pcre_exec(). This is defined in
|
||||
such as way as to be extensible. Always add new fields at the end, in order to
|
||||
remain compatible. */
|
||||
|
||||
typedef struct pcre_extra {
|
||||
unsigned long int flags; /* Bits for which fields are set */
|
||||
void *study_data; /* Opaque data from pcre_study() */
|
||||
unsigned long int match_limit; /* Maximum number of calls to match() */
|
||||
void *callout_data; /* Data passed back in callouts */
|
||||
const unsigned char *tables; /* Pointer to character tables */
|
||||
unsigned long int match_limit_recursion; /* Max recursive calls to match() */
|
||||
} pcre_extra;
|
||||
|
||||
/* The structure for passing out data via the pcre_callout_function. We use a
|
||||
structure so that new fields can be added on the end in future versions,
|
||||
without changing the API of the function, thereby allowing old clients to work
|
||||
without modification. */
|
||||
|
||||
typedef struct pcre_callout_block {
|
||||
int version; /* Identifies version of block */
|
||||
/* ------------------------ Version 0 ------------------------------- */
|
||||
int callout_number; /* Number compiled into pattern */
|
||||
int *offset_vector; /* The offset vector */
|
||||
PCRE_SPTR subject; /* The subject being matched */
|
||||
int subject_length; /* The length of the subject */
|
||||
int start_match; /* Offset to start of this match attempt */
|
||||
int current_position; /* Where we currently are in the subject */
|
||||
int capture_top; /* Max current capture */
|
||||
int capture_last; /* Most recently closed capture */
|
||||
void *callout_data; /* Data passed in with the call */
|
||||
/* ------------------- Added for Version 1 -------------------------- */
|
||||
int pattern_position; /* Offset to next item in the pattern */
|
||||
int next_item_length; /* Length of next item in the pattern */
|
||||
/* ------------------------------------------------------------------ */
|
||||
} pcre_callout_block;
|
||||
|
||||
/* Indirection for store get and free functions. These can be set to
|
||||
alternative malloc/free functions if required. Special ones are used in the
|
||||
non-recursive case for "frames". There is also an optional callout function
|
||||
that is triggered by the (?) regex item. For Virtual Pascal, these definitions
|
||||
have to take another form. */
|
||||
|
||||
#ifndef VPCOMPAT
|
||||
PCRE_EXP_DECL void *(*pcre_malloc)(size_t);
|
||||
PCRE_EXP_DECL void (*pcre_free)(void *);
|
||||
PCRE_EXP_DECL void *(*pcre_stack_malloc)(size_t);
|
||||
PCRE_EXP_DECL void (*pcre_stack_free)(void *);
|
||||
PCRE_EXP_DECL int (*pcre_callout)(pcre_callout_block *);
|
||||
#else /* VPCOMPAT */
|
||||
PCRE_EXP_DECL void *pcre_malloc(size_t);
|
||||
PCRE_EXP_DECL void pcre_free(void *);
|
||||
PCRE_EXP_DECL void *pcre_stack_malloc(size_t);
|
||||
PCRE_EXP_DECL void pcre_stack_free(void *);
|
||||
PCRE_EXP_DECL int pcre_callout(pcre_callout_block *);
|
||||
#endif /* VPCOMPAT */
|
||||
|
||||
/* Exported PCRE functions */
|
||||
|
||||
PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
|
||||
const unsigned char *);
|
||||
PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
|
||||
int *, const unsigned char *);
|
||||
PCRE_EXP_DECL int pcre_config(int, void *);
|
||||
PCRE_EXP_DECL int pcre_copy_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, char *, int);
|
||||
PCRE_EXP_DECL int pcre_copy_substring(const char *, int *, int, int, char *,
|
||||
int);
|
||||
PCRE_EXP_DECL int pcre_dfa_exec(const pcre *, const pcre_extra *,
|
||||
const char *, int, int, int, int *, int , int *, int);
|
||||
PCRE_EXP_DECL int pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
|
||||
int, int, int, int *, int);
|
||||
PCRE_EXP_DECL void pcre_free_substring(const char *);
|
||||
PCRE_EXP_DECL void pcre_free_substring_list(const char **);
|
||||
PCRE_EXP_DECL int pcre_fullinfo(const pcre *, const pcre_extra *, int,
|
||||
void *);
|
||||
PCRE_EXP_DECL int pcre_get_named_substring(const pcre *, const char *,
|
||||
int *, int, const char *, const char **);
|
||||
PCRE_EXP_DECL int pcre_get_stringnumber(const pcre *, const char *);
|
||||
PCRE_EXP_DECL int pcre_get_stringtable_entries(const pcre *, const char *,
|
||||
char **, char **);
|
||||
PCRE_EXP_DECL int pcre_get_substring(const char *, int *, int, int,
|
||||
const char **);
|
||||
PCRE_EXP_DECL int pcre_get_substring_list(const char *, int *, int,
|
||||
const char ***);
|
||||
PCRE_EXP_DECL int pcre_info(const pcre *, int *, int *);
|
||||
PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
|
||||
PCRE_EXP_DECL int pcre_refcount(pcre *, int);
|
||||
PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
|
||||
PCRE_EXP_DECL const char *pcre_version(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* End of pcre.h */
|
File diff suppressed because it is too large
Load Diff
@ -1,128 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_config(). */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Return info about what features are configured *
|
||||
*************************************************/
|
||||
|
||||
/* This function has an extensible interface so that additional items can be
|
||||
added compatibly.
|
||||
|
||||
Arguments:
|
||||
what what information is required
|
||||
where where to put the information
|
||||
|
||||
Returns: 0 if data returned, negative on error
|
||||
*/
|
||||
|
||||
PCRE_EXP_DEFN int
|
||||
pcre_config(int what, void *where)
|
||||
{
|
||||
switch (what)
|
||||
{
|
||||
case PCRE_CONFIG_UTF8:
|
||||
#ifdef SUPPORT_UTF8
|
||||
*((int *)where) = 1;
|
||||
#else
|
||||
*((int *)where) = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_UNICODE_PROPERTIES:
|
||||
#ifdef SUPPORT_UCP
|
||||
*((int *)where) = 1;
|
||||
#else
|
||||
*((int *)where) = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_NEWLINE:
|
||||
*((int *)where) = NEWLINE;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_BSR:
|
||||
#ifdef BSR_ANYCRLF
|
||||
*((int *)where) = 1;
|
||||
#else
|
||||
*((int *)where) = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_LINK_SIZE:
|
||||
*((int *)where) = LINK_SIZE;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
|
||||
*((int *)where) = POSIX_MALLOC_THRESHOLD;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_MATCH_LIMIT:
|
||||
*((unsigned int *)where) = MATCH_LIMIT;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_MATCH_LIMIT_RECURSION:
|
||||
*((unsigned int *)where) = MATCH_LIMIT_RECURSION;
|
||||
break;
|
||||
|
||||
case PCRE_CONFIG_STACKRECURSE:
|
||||
#ifdef NO_RECURSE
|
||||
*((int *)where) = 0;
|
||||
#else
|
||||
*((int *)where) = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default: return PCRE_ERROR_BADOPTION;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End of pcre_config.c */
|
File diff suppressed because it is too large
Load Diff
@ -1,192 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* This file is automatically written by the dftables auxiliary
|
||||
program. If you edit it by hand, you might like to edit the Makefile to
|
||||
prevent its ever being regenerated.
|
||||
|
||||
This file contains the default tables for characters with codes less than
|
||||
128 (ASCII characters). These tables are used when no external tables are
|
||||
passed to PCRE.
|
||||
|
||||
The following #include is present because without it gcc 4.x may remove
|
||||
the array definition from the final binary if PCRE is built into a static
|
||||
library and dead code stripping is activated. This leads to link errors.
|
||||
Pulling in the header ensures that the array gets flagged as "someone
|
||||
outside this compilation unit might reference this" and so it will always
|
||||
be supplied to the linker. */
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
const unsigned char _pcre_default_tables[] = {
|
||||
|
||||
/* This table is a lower casing table. */
|
||||
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55,
|
||||
56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 97, 98, 99,100,101,102,103,
|
||||
104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,
|
||||
120,121,122, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99,100,101,102,103,
|
||||
104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,
|
||||
120,121,122,123,124,125,126,127,
|
||||
128,129,130,131,132,133,134,135,
|
||||
136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,
|
||||
152,153,154,155,156,157,158,159,
|
||||
160,161,162,163,164,165,166,167,
|
||||
168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,
|
||||
184,185,186,187,188,189,190,191,
|
||||
192,193,194,195,196,197,198,199,
|
||||
200,201,202,203,204,205,206,207,
|
||||
208,209,210,211,212,213,214,215,
|
||||
216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,
|
||||
232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,
|
||||
248,249,250,251,252,253,254,255,
|
||||
|
||||
/* This table is a case flipping table. */
|
||||
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23,
|
||||
24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39,
|
||||
40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55,
|
||||
56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 97, 98, 99,100,101,102,103,
|
||||
104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,
|
||||
120,121,122, 91, 92, 93, 94, 95,
|
||||
96, 65, 66, 67, 68, 69, 70, 71,
|
||||
72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87,
|
||||
88, 89, 90,123,124,125,126,127,
|
||||
128,129,130,131,132,133,134,135,
|
||||
136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,
|
||||
152,153,154,155,156,157,158,159,
|
||||
160,161,162,163,164,165,166,167,
|
||||
168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,
|
||||
184,185,186,187,188,189,190,191,
|
||||
192,193,194,195,196,197,198,199,
|
||||
200,201,202,203,204,205,206,207,
|
||||
208,209,210,211,212,213,214,215,
|
||||
216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,
|
||||
232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,
|
||||
248,249,250,251,252,253,254,255,
|
||||
|
||||
/* This table contains bit maps for various character classes.
|
||||
Each map is 32 bytes long and the bits run from the least
|
||||
significant end of each byte. The classes that have their own
|
||||
maps are: space, xdigit, digit, upper, lower, word, graph
|
||||
print, punct, and cntrl. Other classes are built from combinations. */
|
||||
|
||||
0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
|
||||
0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
|
||||
0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
|
||||
0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
|
||||
/* This table identifies various classes of character by individual bits:
|
||||
0x01 white space character
|
||||
0x02 letter
|
||||
0x04 decimal digit
|
||||
0x08 hexadecimal digit
|
||||
0x10 alphanumeric or '_'
|
||||
0x80 regular expression metacharacter or binary zero
|
||||
*/
|
||||
|
||||
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */
|
||||
0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */
|
||||
0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */
|
||||
0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */
|
||||
0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */
|
||||
0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */
|
||||
0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */
|
||||
0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */
|
||||
0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */
|
||||
0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /* X - _ */
|
||||
0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */
|
||||
0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */
|
||||
0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */
|
||||
0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
|
||||
|
||||
/* End of chartables.c */
|
File diff suppressed because it is too large
Load Diff
@ -1,165 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/*PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_fullinfo(), which returns
|
||||
information about a compiled pattern. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Return info about compiled pattern *
|
||||
*************************************************/
|
||||
|
||||
/* This is a newer "info" function which has an extensible interface so
|
||||
that additional items can be added compatibly.
|
||||
|
||||
Arguments:
|
||||
argument_re points to compiled code
|
||||
extra_data points extra data, or NULL
|
||||
what what information is required
|
||||
where where to put the information
|
||||
|
||||
Returns: 0 if data returned, negative on error
|
||||
*/
|
||||
|
||||
PCRE_EXP_DEFN int
|
||||
pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what,
|
||||
void *where)
|
||||
{
|
||||
real_pcre internal_re;
|
||||
pcre_study_data internal_study;
|
||||
const real_pcre *re = (const real_pcre *)argument_re;
|
||||
const pcre_study_data *study = NULL;
|
||||
|
||||
if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
|
||||
|
||||
if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
|
||||
study = (const pcre_study_data *)extra_data->study_data;
|
||||
|
||||
if (re->magic_number != MAGIC_NUMBER)
|
||||
{
|
||||
re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
|
||||
if (re == NULL) return PCRE_ERROR_BADMAGIC;
|
||||
if (study != NULL) study = &internal_study;
|
||||
}
|
||||
|
||||
switch (what)
|
||||
{
|
||||
case PCRE_INFO_OPTIONS:
|
||||
*((unsigned long int *)where) = re->options & PUBLIC_OPTIONS;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_SIZE:
|
||||
*((size_t *)where) = re->size;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_STUDYSIZE:
|
||||
*((size_t *)where) = (study == NULL)? 0 : study->size;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_CAPTURECOUNT:
|
||||
*((int *)where) = re->top_bracket;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_BACKREFMAX:
|
||||
*((int *)where) = re->top_backref;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_FIRSTBYTE:
|
||||
*((int *)where) =
|
||||
((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte :
|
||||
((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
|
||||
break;
|
||||
|
||||
/* Make sure we pass back the pointer to the bit vector in the external
|
||||
block, not the internal copy (with flipped integer fields). */
|
||||
|
||||
case PCRE_INFO_FIRSTTABLE:
|
||||
*((const uschar **)where) =
|
||||
(study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0)?
|
||||
((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_LASTLITERAL:
|
||||
*((int *)where) =
|
||||
((re->flags & PCRE_REQCHSET) != 0)? re->req_byte : -1;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_NAMEENTRYSIZE:
|
||||
*((int *)where) = re->name_entry_size;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_NAMECOUNT:
|
||||
*((int *)where) = re->name_count;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_NAMETABLE:
|
||||
*((const uschar **)where) = (const uschar *)re + re->name_table_offset;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_DEFAULT_TABLES:
|
||||
*((const uschar **)where) = (const uschar *)(_pcre_default_tables);
|
||||
break;
|
||||
|
||||
case PCRE_INFO_OKPARTIAL:
|
||||
*((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_JCHANGED:
|
||||
*((int *)where) = (re->flags & PCRE_JCHANGED) != 0;
|
||||
break;
|
||||
|
||||
case PCRE_INFO_HASCRORLF:
|
||||
*((int *)where) = (re->flags & PCRE_HASCRORLF) != 0;
|
||||
break;
|
||||
|
||||
default: return PCRE_ERROR_BADOPTION;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End of pcre_fullinfo.c */
|
@ -1,465 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains some convenience functions for extracting substrings
|
||||
from the subject string after a regex match has succeeded. The original idea
|
||||
for these functions came from Scott Wimer. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Find number for named string *
|
||||
*************************************************/
|
||||
|
||||
/* This function is used by the get_first_set() function below, as well
|
||||
as being generally available. It assumes that names are unique.
|
||||
|
||||
Arguments:
|
||||
code the compiled regex
|
||||
stringname the name whose number is required
|
||||
|
||||
Returns: the number of the named parentheses, or a negative number
|
||||
(PCRE_ERROR_NOSUBSTRING) if not found
|
||||
*/
|
||||
|
||||
int
|
||||
pcre_get_stringnumber(const pcre *code, const char *stringname)
|
||||
{
|
||||
int rc;
|
||||
int entrysize;
|
||||
int top, bot;
|
||||
uschar *nametable;
|
||||
|
||||
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
|
||||
return rc;
|
||||
if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
|
||||
|
||||
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
|
||||
return rc;
|
||||
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
|
||||
return rc;
|
||||
|
||||
bot = 0;
|
||||
while (top > bot)
|
||||
{
|
||||
int mid = (top + bot) / 2;
|
||||
uschar *entry = nametable + entrysize*mid;
|
||||
int c = strcmp(stringname, (char *)(entry + 2));
|
||||
if (c == 0) return (entry[0] << 8) + entry[1];
|
||||
if (c > 0) bot = mid + 1; else top = mid;
|
||||
}
|
||||
|
||||
return PCRE_ERROR_NOSUBSTRING;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Find (multiple) entries for named string *
|
||||
*************************************************/
|
||||
|
||||
/* This is used by the get_first_set() function below, as well as being
|
||||
generally available. It is used when duplicated names are permitted.
|
||||
|
||||
Arguments:
|
||||
code the compiled regex
|
||||
stringname the name whose entries required
|
||||
firstptr where to put the pointer to the first entry
|
||||
lastptr where to put the pointer to the last entry
|
||||
|
||||
Returns: the length of each entry, or a negative number
|
||||
(PCRE_ERROR_NOSUBSTRING) if not found
|
||||
*/
|
||||
|
||||
int
|
||||
pcre_get_stringtable_entries(const pcre *code, const char *stringname,
|
||||
char **firstptr, char **lastptr)
|
||||
{
|
||||
int rc;
|
||||
int entrysize;
|
||||
int top, bot;
|
||||
uschar *nametable, *lastentry;
|
||||
|
||||
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
|
||||
return rc;
|
||||
if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
|
||||
|
||||
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
|
||||
return rc;
|
||||
if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
|
||||
return rc;
|
||||
|
||||
lastentry = nametable + entrysize * (top - 1);
|
||||
bot = 0;
|
||||
while (top > bot)
|
||||
{
|
||||
int mid = (top + bot) / 2;
|
||||
uschar *entry = nametable + entrysize*mid;
|
||||
int c = strcmp(stringname, (char *)(entry + 2));
|
||||
if (c == 0)
|
||||
{
|
||||
uschar *first = entry;
|
||||
uschar *last = entry;
|
||||
while (first > nametable)
|
||||
{
|
||||
if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break;
|
||||
first -= entrysize;
|
||||
}
|
||||
while (last < lastentry)
|
||||
{
|
||||
if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break;
|
||||
last += entrysize;
|
||||
}
|
||||
*firstptr = (char *)first;
|
||||
*lastptr = (char *)last;
|
||||
return entrysize;
|
||||
}
|
||||
if (c > 0) bot = mid + 1; else top = mid;
|
||||
}
|
||||
|
||||
return PCRE_ERROR_NOSUBSTRING;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Find first set of multiple named strings *
|
||||
*************************************************/
|
||||
|
||||
/* This function allows for duplicate names in the table of named substrings.
|
||||
It returns the number of the first one that was set in a pattern match.
|
||||
|
||||
Arguments:
|
||||
code the compiled regex
|
||||
stringname the name of the capturing substring
|
||||
ovector the vector of matched substrings
|
||||
|
||||
Returns: the number of the first that is set,
|
||||
or the number of the last one if none are set,
|
||||
or a negative number on error
|
||||
*/
|
||||
|
||||
static int
|
||||
get_first_set(const pcre *code, const char *stringname, int *ovector)
|
||||
{
|
||||
const real_pcre *re = (const real_pcre *)code;
|
||||
int entrysize;
|
||||
char *first, *last;
|
||||
uschar *entry;
|
||||
if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
|
||||
return pcre_get_stringnumber(code, stringname);
|
||||
entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
|
||||
if (entrysize <= 0) return entrysize;
|
||||
for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize)
|
||||
{
|
||||
int n = (entry[0] << 8) + entry[1];
|
||||
if (ovector[n*2] >= 0) return n;
|
||||
}
|
||||
return (first[0] << 8) + first[1];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Copy captured string to given buffer *
|
||||
*************************************************/
|
||||
|
||||
/* This function copies a single captured substring into a given buffer.
|
||||
Note that we use memcpy() rather than strncpy() in case there are binary zeros
|
||||
in the string.
|
||||
|
||||
Arguments:
|
||||
subject the subject string that was matched
|
||||
ovector pointer to the offsets table
|
||||
stringcount the number of substrings that were captured
|
||||
(i.e. the yield of the pcre_exec call, unless
|
||||
that was zero, in which case it should be 1/3
|
||||
of the offset table size)
|
||||
stringnumber the number of the required substring
|
||||
buffer where to put the substring
|
||||
size the size of the buffer
|
||||
|
||||
Returns: if successful:
|
||||
the length of the copied string, not including the zero
|
||||
that is put on the end; can be zero
|
||||
if not successful:
|
||||
PCRE_ERROR_NOMEMORY (-6) buffer too small
|
||||
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
|
||||
*/
|
||||
|
||||
int
|
||||
pcre_copy_substring(const char *subject, int *ovector, int stringcount,
|
||||
int stringnumber, char *buffer, int size)
|
||||
{
|
||||
int yield;
|
||||
if (stringnumber < 0 || stringnumber >= stringcount)
|
||||
return PCRE_ERROR_NOSUBSTRING;
|
||||
stringnumber *= 2;
|
||||
yield = ovector[stringnumber+1] - ovector[stringnumber];
|
||||
if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
|
||||
memcpy(buffer, subject + ovector[stringnumber], yield);
|
||||
buffer[yield] = 0;
|
||||
return yield;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Copy named captured string to given buffer *
|
||||
*************************************************/
|
||||
|
||||
/* This function copies a single captured substring into a given buffer,
|
||||
identifying it by name. If the regex permits duplicate names, the first
|
||||
substring that is set is chosen.
|
||||
|
||||
Arguments:
|
||||
code the compiled regex
|
||||
subject the subject string that was matched
|
||||
ovector pointer to the offsets table
|
||||
stringcount the number of substrings that were captured
|
||||
(i.e. the yield of the pcre_exec call, unless
|
||||
that was zero, in which case it should be 1/3
|
||||
of the offset table size)
|
||||
stringname the name of the required substring
|
||||
buffer where to put the substring
|
||||
size the size of the buffer
|
||||
|
||||
Returns: if successful:
|
||||
the length of the copied string, not including the zero
|
||||
that is put on the end; can be zero
|
||||
if not successful:
|
||||
PCRE_ERROR_NOMEMORY (-6) buffer too small
|
||||
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
|
||||
*/
|
||||
|
||||
int
|
||||
pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,
|
||||
int stringcount, const char *stringname, char *buffer, int size)
|
||||
{
|
||||
int n = get_first_set(code, stringname, ovector);
|
||||
if (n <= 0) return n;
|
||||
return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Copy all captured strings to new store *
|
||||
*************************************************/
|
||||
|
||||
/* This function gets one chunk of store and builds a list of pointers and all
|
||||
of the captured substrings in it. A NULL pointer is put on the end of the list.
|
||||
|
||||
Arguments:
|
||||
subject the subject string that was matched
|
||||
ovector pointer to the offsets table
|
||||
stringcount the number of substrings that were captured
|
||||
(i.e. the yield of the pcre_exec call, unless
|
||||
that was zero, in which case it should be 1/3
|
||||
of the offset table size)
|
||||
listptr set to point to the list of pointers
|
||||
|
||||
Returns: if successful: 0
|
||||
if not successful:
|
||||
PCRE_ERROR_NOMEMORY (-6) failed to get store
|
||||
*/
|
||||
|
||||
int
|
||||
pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
|
||||
const char ***listptr)
|
||||
{
|
||||
int i;
|
||||
int size = sizeof(char *);
|
||||
int double_count = stringcount * 2;
|
||||
char **stringlist;
|
||||
char *p;
|
||||
|
||||
for (i = 0; i < double_count; i += 2)
|
||||
size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;
|
||||
|
||||
stringlist = (char **)(pcre_malloc)(size);
|
||||
if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
|
||||
|
||||
*listptr = (const char **)stringlist;
|
||||
p = (char *)(stringlist + stringcount + 1);
|
||||
|
||||
for (i = 0; i < double_count; i += 2)
|
||||
{
|
||||
int len = ovector[i+1] - ovector[i];
|
||||
memcpy(p, subject + ovector[i], len);
|
||||
*stringlist++ = p;
|
||||
p += len;
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
*stringlist = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Free store obtained by get_substring_list *
|
||||
*************************************************/
|
||||
|
||||
/* This function exists for the benefit of people calling PCRE from non-C
|
||||
programs that can call its functions, but not free() or (pcre_free)() directly.
|
||||
|
||||
Argument: the result of a previous pcre_get_substring_list()
|
||||
Returns: nothing
|
||||
*/
|
||||
|
||||
void
|
||||
pcre_free_substring_list(const char **pointer)
|
||||
{
|
||||
(pcre_free)((void *)pointer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Copy captured string to new store *
|
||||
*************************************************/
|
||||
|
||||
/* This function copies a single captured substring into a piece of new
|
||||
store
|
||||
|
||||
Arguments:
|
||||
subject the subject string that was matched
|
||||
ovector pointer to the offsets table
|
||||
stringcount the number of substrings that were captured
|
||||
(i.e. the yield of the pcre_exec call, unless
|
||||
that was zero, in which case it should be 1/3
|
||||
of the offset table size)
|
||||
stringnumber the number of the required substring
|
||||
stringptr where to put a pointer to the substring
|
||||
|
||||
Returns: if successful:
|
||||
the length of the string, not including the zero that
|
||||
is put on the end; can be zero
|
||||
if not successful:
|
||||
PCRE_ERROR_NOMEMORY (-6) failed to get store
|
||||
PCRE_ERROR_NOSUBSTRING (-7) substring not present
|
||||
*/
|
||||
|
||||
int
|
||||
pcre_get_substring(const char *subject, int *ovector, int stringcount,
|
||||
int stringnumber, const char **stringptr)
|
||||
{
|
||||
int yield;
|
||||
char *substring;
|
||||
if (stringnumber < 0 || stringnumber >= stringcount)
|
||||
return PCRE_ERROR_NOSUBSTRING;
|
||||
stringnumber *= 2;
|
||||
yield = ovector[stringnumber+1] - ovector[stringnumber];
|
||||
substring = (char *)(pcre_malloc)(yield + 1);
|
||||
if (substring == NULL) return PCRE_ERROR_NOMEMORY;
|
||||
memcpy(substring, subject + ovector[stringnumber], yield);
|
||||
substring[yield] = 0;
|
||||
*stringptr = substring;
|
||||
return yield;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Copy named captured string to new store *
|
||||
*************************************************/
|
||||
|
||||
/* This function copies a single captured substring, identified by name, into
|
||||
new store. If the regex permits duplicate names, the first substring that is
|
||||
set is chosen.
|
||||
|
||||
Arguments:
|
||||
code the compiled regex
|
||||
subject the subject string that was matched
|
||||
ovector pointer to the offsets table
|
||||
stringcount the number of substrings that were captured
|
||||
(i.e. the yield of the pcre_exec call, unless
|
||||
that was zero, in which case it should be 1/3
|
||||
of the offset table size)
|
||||
stringname the name of the required substring
|
||||
stringptr where to put the pointer
|
||||
|
||||
Returns: if successful:
|
||||
the length of the copied string, not including the zero
|
||||
that is put on the end; can be zero
|
||||
if not successful:
|
||||
PCRE_ERROR_NOMEMORY (-6) couldn't get memory
|
||||
PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
|
||||
*/
|
||||
|
||||
int
|
||||
pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,
|
||||
int stringcount, const char *stringname, const char **stringptr)
|
||||
{
|
||||
int n = get_first_set(code, stringname, ovector);
|
||||
if (n <= 0) return n;
|
||||
return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Free store obtained by get_substring *
|
||||
*************************************************/
|
||||
|
||||
/* This function exists for the benefit of people calling PCRE from non-C
|
||||
programs that can call its functions, but not free() or (pcre_free)() directly.
|
||||
|
||||
Argument: the result of a previous pcre_get_substring()
|
||||
Returns: nothing
|
||||
*/
|
||||
|
||||
void
|
||||
pcre_free_substring(const char *pointer)
|
||||
{
|
||||
(pcre_free)((void *)pointer);
|
||||
}
|
||||
|
||||
/* End of pcre_get.c */
|
@ -1,63 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains global variables that are exported by the PCRE library.
|
||||
PCRE is thread-clean and doesn't use any global variables in the normal sense.
|
||||
However, it calls memory allocation and freeing functions via the four
|
||||
indirections below, and it can optionally do callouts, using the fifth
|
||||
indirection. These values can be changed by the caller, but are shared between
|
||||
all threads. However, when compiling for Virtual Pascal, things are done
|
||||
differently, and global variables are not used (see pcre.in). */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
#ifndef VPCOMPAT
|
||||
PCRE_EXP_DATA_DEFN void *(*pcre_malloc)(size_t) = malloc;
|
||||
PCRE_EXP_DATA_DEFN void (*pcre_free)(void *) = free;
|
||||
PCRE_EXP_DATA_DEFN void *(*pcre_stack_malloc)(size_t) = malloc;
|
||||
PCRE_EXP_DATA_DEFN void (*pcre_stack_free)(void *) = free;
|
||||
PCRE_EXP_DATA_DEFN int (*pcre_callout)(pcre_callout_block *) = NULL;
|
||||
#endif
|
||||
|
||||
/* End of pcre_globals.c */
|
@ -1,93 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_info(), which gives some
|
||||
information about a compiled pattern. However, use of this function is now
|
||||
deprecated, as it has been superseded by pcre_fullinfo(). */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* (Obsolete) Return info about compiled pattern *
|
||||
*************************************************/
|
||||
|
||||
/* This is the original "info" function. It picks potentially useful data out
|
||||
of the private structure, but its interface was too rigid. It remains for
|
||||
backwards compatibility. The public options are passed back in an int - though
|
||||
the re->options field has been expanded to a long int, all the public options
|
||||
at the low end of it, and so even on 16-bit systems this will still be OK.
|
||||
Therefore, I haven't changed the API for pcre_info().
|
||||
|
||||
Arguments:
|
||||
argument_re points to compiled code
|
||||
optptr where to pass back the options
|
||||
first_byte where to pass back the first character,
|
||||
or -1 if multiline and all branches start ^,
|
||||
or -2 otherwise
|
||||
|
||||
Returns: number of capturing subpatterns
|
||||
or negative values on error
|
||||
*/
|
||||
|
||||
PCRE_EXP_DEFN int
|
||||
pcre_info(const pcre *argument_re, int *optptr, int *first_byte)
|
||||
{
|
||||
real_pcre internal_re;
|
||||
const real_pcre *re = (const real_pcre *)argument_re;
|
||||
if (re == NULL) return PCRE_ERROR_NULL;
|
||||
if (re->magic_number != MAGIC_NUMBER)
|
||||
{
|
||||
re = _pcre_try_flipped(re, &internal_re, NULL, NULL);
|
||||
if (re == NULL) return PCRE_ERROR_BADMAGIC;
|
||||
}
|
||||
if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_OPTIONS);
|
||||
if (first_byte != NULL)
|
||||
*first_byte = ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte :
|
||||
((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
|
||||
return re->top_bracket;
|
||||
}
|
||||
|
||||
/* End of pcre_info.c */
|
File diff suppressed because it is too large
Load Diff
@ -1,143 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_maketables(), which builds
|
||||
character tables for PCRE in the current locale. The file is compiled on its
|
||||
own as part of the PCRE library. However, it is also included in the
|
||||
compilation of dftables.c, in which case the macro DFTABLES is defined. */
|
||||
|
||||
|
||||
#ifndef DFTABLES
|
||||
# ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
# endif
|
||||
# include "pcre_internal.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Create PCRE character tables *
|
||||
*************************************************/
|
||||
|
||||
/* This function builds a set of character tables for use by PCRE and returns
|
||||
a pointer to them. They are build using the ctype functions, and consequently
|
||||
their contents will depend upon the current locale setting. When compiled as
|
||||
part of the library, the store is obtained via pcre_malloc(), but when compiled
|
||||
inside dftables, use malloc().
|
||||
|
||||
Arguments: none
|
||||
Returns: pointer to the contiguous block of data
|
||||
*/
|
||||
|
||||
const unsigned char *
|
||||
pcre_maketables(void)
|
||||
{
|
||||
unsigned char *yield, *p;
|
||||
int i;
|
||||
|
||||
#ifndef DFTABLES
|
||||
yield = (unsigned char*)(pcre_malloc)(tables_length);
|
||||
#else
|
||||
yield = (unsigned char*)malloc(tables_length);
|
||||
#endif
|
||||
|
||||
if (yield == NULL) return NULL;
|
||||
p = yield;
|
||||
|
||||
/* First comes the lower casing table */
|
||||
|
||||
for (i = 0; i < 256; i++) *p++ = tolower(i);
|
||||
|
||||
/* Next the case-flipping table */
|
||||
|
||||
for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i);
|
||||
|
||||
/* Then the character class tables. Don't try to be clever and save effort on
|
||||
exclusive ones - in some locales things may be different. Note that the table
|
||||
for "space" includes everything "isspace" gives, including VT in the default
|
||||
locale. This makes it work for the POSIX class [:space:]. Note also that it is
|
||||
possible for a character to be alnum or alpha without being lower or upper,
|
||||
such as "male and female ordinals" (\xAA and \xBA) in the fr_FR locale (at
|
||||
least under Debian Linux's locales as of 12/2005). So we must test for alnum
|
||||
specially. */
|
||||
|
||||
memset(p, 0, cbit_length);
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7);
|
||||
if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7);
|
||||
if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7);
|
||||
if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7);
|
||||
if (i == '_') p[cbit_word + i/8] |= 1 << (i&7);
|
||||
if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7);
|
||||
if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7);
|
||||
if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7);
|
||||
if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7);
|
||||
if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7);
|
||||
if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7);
|
||||
}
|
||||
p += cbit_length;
|
||||
|
||||
/* Finally, the character type table. In this, we exclude VT from the white
|
||||
space chars, because Perl doesn't recognize it as such for \s and for comments
|
||||
within regexes. */
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
int x = 0;
|
||||
if (i != 0x0b && isspace(i)) x += ctype_space;
|
||||
if (isalpha(i)) x += ctype_letter;
|
||||
if (isdigit(i)) x += ctype_digit;
|
||||
if (isxdigit(i)) x += ctype_xdigit;
|
||||
if (isalnum(i) || i == '_') x += ctype_word;
|
||||
|
||||
/* Note: strchr includes the terminating zero in the characters it considers.
|
||||
In this instance, that is ok because we want binary zero to be flagged as a
|
||||
meta-character, which in this sense is any character that terminates a run
|
||||
of data characters. */
|
||||
|
||||
if (strchr("\\*+?{^.$|()[", i) != 0) x += ctype_meta;
|
||||
*p++ = x;
|
||||
}
|
||||
|
||||
return yield;
|
||||
}
|
||||
|
||||
/* End of pcre_maketables.c */
|
@ -1,164 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains internal functions for testing newlines when more than
|
||||
one kind of newline is to be recognized. When a newline is found, its length is
|
||||
returned. In principle, we could implement several newline "types", each
|
||||
referring to a different set of newline characters. At present, PCRE supports
|
||||
only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,
|
||||
and NLTYPE_ANY. The full list of Unicode newline characters is taken from
|
||||
http://unicode.org/unicode/reports/tr18/. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Check for newline at given position *
|
||||
*************************************************/
|
||||
|
||||
/* It is guaranteed that the initial value of ptr is less than the end of the
|
||||
string that is being processed.
|
||||
|
||||
Arguments:
|
||||
ptr pointer to possible newline
|
||||
type the newline type
|
||||
endptr pointer to the end of the string
|
||||
lenptr where to return the length
|
||||
utf8 TRUE if in utf8 mode
|
||||
|
||||
Returns: TRUE or FALSE
|
||||
*/
|
||||
|
||||
BOOL
|
||||
_pcre_is_newline(const uschar *ptr, int type, const uschar *endptr,
|
||||
int *lenptr, BOOL utf8)
|
||||
{
|
||||
int c;
|
||||
if (utf8) { GETCHAR(c, ptr); } else c = *ptr;
|
||||
|
||||
if (type == NLTYPE_ANYCRLF) switch(c)
|
||||
{
|
||||
case 0x000a: *lenptr = 1; return TRUE; /* LF */
|
||||
case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
|
||||
return TRUE; /* CR */
|
||||
default: return FALSE;
|
||||
}
|
||||
|
||||
/* NLTYPE_ANY */
|
||||
|
||||
else switch(c)
|
||||
{
|
||||
case 0x000a: /* LF */
|
||||
case 0x000b: /* VT */
|
||||
case 0x000c: *lenptr = 1; return TRUE; /* FF */
|
||||
case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
|
||||
return TRUE; /* CR */
|
||||
case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */
|
||||
case 0x2028: /* LS */
|
||||
case 0x2029: *lenptr = 3; return TRUE; /* PS */
|
||||
default: return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Check for newline at previous position *
|
||||
*************************************************/
|
||||
|
||||
/* It is guaranteed that the initial value of ptr is greater than the start of
|
||||
the string that is being processed.
|
||||
|
||||
Arguments:
|
||||
ptr pointer to possible newline
|
||||
type the newline type
|
||||
startptr pointer to the start of the string
|
||||
lenptr where to return the length
|
||||
utf8 TRUE if in utf8 mode
|
||||
|
||||
Returns: TRUE or FALSE
|
||||
*/
|
||||
|
||||
BOOL
|
||||
_pcre_was_newline(const uschar *ptr, int type, const uschar *startptr,
|
||||
int *lenptr, BOOL utf8)
|
||||
{
|
||||
int c;
|
||||
ptr--;
|
||||
#ifdef SUPPORT_UTF8
|
||||
if (utf8)
|
||||
{
|
||||
BACKCHAR(ptr);
|
||||
GETCHAR(c, ptr);
|
||||
}
|
||||
else c = *ptr;
|
||||
#else /* no UTF-8 support */
|
||||
c = *ptr;
|
||||
#endif /* SUPPORT_UTF8 */
|
||||
|
||||
if (type == NLTYPE_ANYCRLF) switch(c)
|
||||
{
|
||||
case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
|
||||
return TRUE; /* LF */
|
||||
case 0x000d: *lenptr = 1; return TRUE; /* CR */
|
||||
default: return FALSE;
|
||||
}
|
||||
|
||||
else switch(c)
|
||||
{
|
||||
case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
|
||||
return TRUE; /* LF */
|
||||
case 0x000b: /* VT */
|
||||
case 0x000c: /* FF */
|
||||
case 0x000d: *lenptr = 1; return TRUE; /* CR */
|
||||
case 0x0085: *lenptr = utf8? 2 : 1; return TRUE; /* NEL */
|
||||
case 0x2028: /* LS */
|
||||
case 0x2029: *lenptr = 3; return TRUE; /* PS */
|
||||
default: return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* End of pcre_newline.c */
|
@ -1,85 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This file contains a private PCRE function that converts an ordinal
|
||||
character value into a UTF8 string. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Convert character value to UTF-8 *
|
||||
*************************************************/
|
||||
|
||||
/* This function takes an integer value in the range 0 - 0x7fffffff
|
||||
and encodes it as a UTF-8 character in 0 to 6 bytes.
|
||||
|
||||
Arguments:
|
||||
cvalue the character value
|
||||
buffer pointer to buffer for result - at least 6 bytes long
|
||||
|
||||
Returns: number of characters placed in the buffer
|
||||
*/
|
||||
|
||||
int
|
||||
_pcre_ord2utf8(int cvalue, uschar *buffer)
|
||||
{
|
||||
#ifdef SUPPORT_UTF8
|
||||
register int i, j;
|
||||
for (i = 0; i < _pcre_utf8_table1_size; i++)
|
||||
if (cvalue <= _pcre_utf8_table1[i]) break;
|
||||
buffer += i;
|
||||
for (j = i; j > 0; j--)
|
||||
{
|
||||
*buffer-- = 0x80 | (cvalue & 0x3f);
|
||||
cvalue >>= 6;
|
||||
}
|
||||
*buffer = _pcre_utf8_table2[i] | cvalue;
|
||||
return i + 1;
|
||||
#else
|
||||
return 0; /* Keep compiler happy; this function won't ever be */
|
||||
#endif /* called when SUPPORT_UTF8 is not defined. */
|
||||
}
|
||||
|
||||
/* End of pcre_ord2utf8.c */
|
@ -1,400 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2007-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
|
||||
#include "../../structures.h"
|
||||
#include <string.h>
|
||||
#include "pcre.h"
|
||||
#include "pcreposix.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef isnumber
|
||||
#define isnumber(i_n_arg) ((i_n_arg>='0')&&(i_n_arg<='9'))
|
||||
#endif
|
||||
|
||||
static struct pluginlink * pl;
|
||||
|
||||
static pthread_mutex_t pcre_mutex;
|
||||
|
||||
|
||||
static struct filter pcre_first_filter = {
|
||||
NULL,
|
||||
"Fake filter",
|
||||
NULL, NULL,
|
||||
NULL, NULL,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL
|
||||
};
|
||||
|
||||
static struct filter *pcre_last_filter;
|
||||
static int pcre_loaded = 0;
|
||||
static int pcre_options = 0;
|
||||
|
||||
static struct pcreopt {
|
||||
char * name;
|
||||
int value;
|
||||
} pcreopts[]= {
|
||||
|
||||
{"PCRE_CASELESS", 0x00000001},
|
||||
{"PCRE_MULTILINE", 0x00000002},
|
||||
{"PCRE_DOTALL", 0x00000004},
|
||||
{"PCRE_EXTENDED", 0x00000008},
|
||||
{"PCRE_ANCHORED", 0x00000010},
|
||||
{"PCRE_DOLLAR_ENDONLY", 0x00000020},
|
||||
{"PCRE_EXTRA", 0x00000040},
|
||||
{"PCRE_NOTBOL", 0x00000080},
|
||||
{"PCRE_NOTEOL", 0x00000100},
|
||||
{"PCRE_UNGREEDY", 0x00000200},
|
||||
{"PCRE_NOTEMPTY", 0x00000400},
|
||||
{"PCRE_UTF8", 0x00000800},
|
||||
{"PCRE_NO_AUTO_CAPTURE", 0x00001000},
|
||||
{"PCRE_NO_UTF8_CHECK", 0x00002000},
|
||||
{"PCRE_AUTO_CALLOUT", 0x00004000},
|
||||
{"PCRE_PARTIAL", 0x00008000},
|
||||
{"PCRE_DFA_SHORTEST", 0x00010000},
|
||||
{"PCRE_DFA_RESTART", 0x00020000},
|
||||
{"PCRE_FIRSTLINE", 0x00040000},
|
||||
{"PCRE_DUPNAMES", 0x00080000},
|
||||
{"PCRE_NEWLINE_CR", 0x00100000},
|
||||
{"PCRE_NEWLINE_LF", 0x00200000},
|
||||
{"PCRE_NEWLINE_CRLF", 0x00300000},
|
||||
{"PCRE_NEWLINE_ANY", 0x00400000},
|
||||
{"PCRE_NEWLINE_ANYCRLF", 0x00500000},
|
||||
{"PCRE_BSR_ANYCRLF", 0x00800000},
|
||||
{"PCRE_BSR_UNICODE", 0x01000000},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
struct pcre_filter_data {
|
||||
int users;
|
||||
pcre * re;
|
||||
int action;
|
||||
char * replace;
|
||||
struct ace *acl;
|
||||
};
|
||||
|
||||
static void pcre_data_free(struct pcre_filter_data *pcrefd){
|
||||
pthread_mutex_lock(&pcre_mutex);
|
||||
pcrefd->users--;
|
||||
if(!pcrefd->users){
|
||||
if(pcrefd->re) pl->myfree(pcrefd->re);
|
||||
if(pcrefd->acl) pl->freeacl(pcrefd->acl);
|
||||
if(pcrefd->replace) pl->myfree(pcrefd->replace);
|
||||
pl->myfree(pcrefd);
|
||||
}
|
||||
pthread_mutex_unlock(&pcre_mutex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void* pcre_filter_open(void * idata, struct srvparam * param){
|
||||
#define pcrefd ((struct pcre_filter_data *)idata)
|
||||
if(idata){
|
||||
pthread_mutex_lock(&pcre_mutex);
|
||||
pcrefd->users++;
|
||||
pthread_mutex_unlock(&pcre_mutex);
|
||||
}
|
||||
#undef pcrefd
|
||||
return idata;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static FILTER_ACTION pcre_filter_client(void *fo, struct clientparam * param, void** fc){
|
||||
int res;
|
||||
struct ace tmpace;
|
||||
|
||||
*fc = fo;
|
||||
if(!fo) return PASS;
|
||||
#define pcrefd ((struct pcre_filter_data *)fo)
|
||||
if(!pcrefd->acl) return CONTINUE;
|
||||
memset (&tmpace, 0, sizeof(struct ace));
|
||||
tmpace.src = pcrefd->acl->src;
|
||||
res = pl->ACLMatches(&tmpace, param);
|
||||
#undef pcrefd
|
||||
return (res)? CONTINUE:PASS;
|
||||
}
|
||||
|
||||
static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, unsigned char ** buf_p, int * bufsize_p, int offset, int * length_p){
|
||||
int ovector[48];
|
||||
int count = 0;
|
||||
struct ace *acl;
|
||||
int match = 0;
|
||||
int replen, num;
|
||||
char * replace;
|
||||
char * tmpbuf, *target, *newbuf;
|
||||
int nreplaces=0;
|
||||
#define pcrefd ((struct pcre_filter_data *)fc)
|
||||
|
||||
for(acl = pcrefd->acl; acl; acl=acl->next){
|
||||
if(pl->ACLMatches(pcrefd->acl, param)){
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!match) return CONTINUE;
|
||||
if(!pcrefd->re) return pcrefd->action;
|
||||
for(; offset < *length_p; nreplaces++){
|
||||
|
||||
count = pcre_exec(pcrefd->re, NULL, (char *)*buf_p, *length_p, offset, 0, ovector, 48);
|
||||
if(count <= 0) break;
|
||||
if(!(replace = pcrefd->replace) || param->nooverwritefilter) return pcrefd->action;
|
||||
|
||||
replen = *length_p - ovector[1];
|
||||
while(*replace){
|
||||
if(*replace == '\\' && *(replace +1)){
|
||||
replace+=2;
|
||||
++replen;
|
||||
}
|
||||
else if(*replace == '$' && isnumber(*(replace+1))){
|
||||
replace ++;
|
||||
num = atoi(replace);
|
||||
while(isnumber(*replace)) replace++;
|
||||
if(num > (count - 1)) continue;
|
||||
replen += (ovector[(num<<1) + 1] - ovector[(num<<1)]);
|
||||
}
|
||||
else {
|
||||
replace++;
|
||||
replen++;
|
||||
}
|
||||
}
|
||||
|
||||
tmpbuf = (*pl->myalloc)(replen);
|
||||
if(!tmpbuf) return CONTINUE;
|
||||
for(target = tmpbuf, replace = pcrefd->replace; *replace; ){
|
||||
if(*replace == '\\' && *(replace +1)){
|
||||
*target++ = replace[1];
|
||||
replace+=2;
|
||||
}
|
||||
else if(*replace == '$' && isnumber(*(replace+1))){
|
||||
replace ++;
|
||||
num = atoi(replace);
|
||||
if(num > (count - 1)) continue;
|
||||
memcpy(target, *buf_p + ovector[(num<<1)], ovector[(num<<1) + 1] - ovector[(num<<1)]);
|
||||
target += (ovector[(num<<1) + 1] - ovector[(num<<1)]);
|
||||
while(isnumber(*replace)) replace++;
|
||||
}
|
||||
else {
|
||||
*target++ = *replace++;
|
||||
}
|
||||
}
|
||||
memcpy(target, *buf_p + ovector[1], *length_p - ovector[1]);
|
||||
if((ovector[0] + replen + 1) > *bufsize_p){
|
||||
newbuf = (*pl->myalloc)(ovector[0] + replen + 1);
|
||||
if(!newbuf){
|
||||
(*pl->myfree)(tmpbuf);
|
||||
return CONTINUE;
|
||||
}
|
||||
memcpy(newbuf, *buf_p, ovector[0]);
|
||||
(*pl->myfree)(*buf_p);
|
||||
*buf_p = (unsigned char *)newbuf;
|
||||
*bufsize_p = ovector[0] + replen + 1;
|
||||
}
|
||||
memcpy(*buf_p + ovector[0], tmpbuf, replen);
|
||||
(*pl->myfree)(tmpbuf);
|
||||
(*buf_p)[ovector[0] + replen] = 0;
|
||||
*length_p = ovector[0] + replen;
|
||||
if(ovector[0] + replen <= offset){
|
||||
break;
|
||||
}
|
||||
offset = ovector[0] + (int)strlen(pcrefd->replace);
|
||||
}
|
||||
return nreplaces? pcrefd->action : CONTINUE;
|
||||
#undef pcrefd
|
||||
}
|
||||
|
||||
static void pcre_filter_clear(void *fo){
|
||||
}
|
||||
|
||||
static void pcre_filter_close(void *fo){
|
||||
if(!fo) return;
|
||||
pcre_data_free((struct pcre_filter_data *)fo);
|
||||
}
|
||||
|
||||
static int h_pcre(int argc, unsigned char **argv){
|
||||
int action = 0;
|
||||
pcre *re = NULL;
|
||||
struct ace *acl;
|
||||
int offset = 4;
|
||||
const char * errptr;
|
||||
struct pcre_filter_data *flt;
|
||||
struct filter *newf;
|
||||
char *replace = NULL;
|
||||
|
||||
if(!strncmp((char *)argv[2], "allow",5)) action = PASS;
|
||||
else if(!strncmp((char *)argv[2], "deny",4)) action = REJECT;
|
||||
else if(!strncmp((char *)argv[2], "remove",6)) action = REMOVE;
|
||||
else if(!strncmp((char *)argv[2], "dunno",5)) action = CONTINUE;
|
||||
else return 1;
|
||||
if(!strncmp((char *)argv[0], "pcre_rewrite", 12)) {
|
||||
int i,j;
|
||||
offset = 5;
|
||||
replace = pl->mystrdup((char *)argv[4]);
|
||||
if(!replace) return 9;
|
||||
for(i=0, j=0; replace[i]; i++, j++){
|
||||
if(replace[i] == '\\'){
|
||||
switch(replace[i+1]){
|
||||
case 'r':
|
||||
i++;
|
||||
replace[j] = '\r';
|
||||
break;
|
||||
case 'n':
|
||||
i++;
|
||||
replace[j] = '\n';
|
||||
break;
|
||||
case '0':
|
||||
i++;
|
||||
replace[j] = 0;
|
||||
break;
|
||||
case '\\':
|
||||
i++;
|
||||
default:
|
||||
replace[j] = '\\';
|
||||
break;
|
||||
}
|
||||
}
|
||||
else replace[j] = replace[i];
|
||||
}
|
||||
replace[j] = 0;
|
||||
}
|
||||
if(!(acl = pl->make_ace(argc - offset, argv + offset))) return 2;
|
||||
acl->nolog = (strstr((char *)argv[2],"log") == 0);
|
||||
if(*argv[3] && !(*argv[3] == '*' && !argv[3][1]) ){
|
||||
re = pcre_compile((char *)argv[3], pcre_options, &errptr, &offset, NULL);
|
||||
if(!re) {
|
||||
pl->myfree(acl);
|
||||
if(replace) pl->myfree(replace);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
flt = pl->myalloc(sizeof(struct pcre_filter_data));
|
||||
newf = pl->myalloc(sizeof(struct filter));
|
||||
|
||||
if(!flt || !newf) {
|
||||
pl->myfree(acl);
|
||||
pl->myfree(re);
|
||||
if(replace) pl->myfree(replace);
|
||||
if(flt) pl->myfree(flt);
|
||||
return 4;
|
||||
}
|
||||
memset(flt, 0, sizeof(struct pcre_filter_data));
|
||||
memset(newf, 0, sizeof(struct filter));
|
||||
flt->action = action;
|
||||
flt->re = re;
|
||||
flt->acl = acl;
|
||||
flt->replace = replace;
|
||||
flt->users = 1;
|
||||
newf->instance = "pcre";
|
||||
newf->data = flt;
|
||||
newf->filter_open = pcre_filter_open;
|
||||
newf->filter_client = pcre_filter_client;
|
||||
if(strstr((char *)argv[1], "request"))newf->filter_request = pcre_filter_buffer;
|
||||
if(strstr((char *)argv[1], "cliheader"))newf->filter_header_cli = pcre_filter_buffer;
|
||||
if(strstr((char *)argv[1], "clidata"))newf->filter_data_cli = pcre_filter_buffer;
|
||||
if(strstr((char *)argv[1], "srvheader"))newf->filter_header_srv = pcre_filter_buffer;
|
||||
if(strstr((char *)argv[1], "srvdata"))newf->filter_data_srv = pcre_filter_buffer;
|
||||
newf->filter_clear = pcre_filter_clear;
|
||||
newf->filter_close = pcre_filter_close;
|
||||
|
||||
if(!pcre_last_filter){
|
||||
newf->next = pcre_first_filter.next;
|
||||
pcre_first_filter.next=newf;
|
||||
}
|
||||
else {
|
||||
newf->next = pcre_last_filter->next;
|
||||
pcre_last_filter->next = newf;
|
||||
}
|
||||
pcre_last_filter=newf;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int h_pcre_extend(int argc, unsigned char **argv){
|
||||
struct ace *acl;
|
||||
if(!pcre_last_filter || !pcre_last_filter->data) return 1;
|
||||
acl = ((struct pcre_filter_data *)pcre_last_filter->data)->acl;
|
||||
if(!acl) return 2;
|
||||
for(; acl->next; acl=acl->next);
|
||||
acl->next = (*pl->make_ace)(argc - 1, argv + 1);
|
||||
if(!acl->next) return 3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int h_pcre_options(int argc, unsigned char **argv){
|
||||
int i,j;
|
||||
|
||||
pcre_options = 0;
|
||||
for(j=1; j<argc; j++)
|
||||
for(i=0; pcreopts[i].name; i++)
|
||||
if(!strcmp(pcreopts[i].name, (char *)argv[j]))
|
||||
pcre_options |= pcreopts[i].value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct commands pcre_commandhandlers[] = {
|
||||
{pcre_commandhandlers+1, "pcre", h_pcre, 4, 0},
|
||||
{pcre_commandhandlers+2, "pcre_rewrite", h_pcre, 5, 0},
|
||||
{pcre_commandhandlers+3, "pcre_extend", h_pcre_extend, 2, 0},
|
||||
{NULL, "pcre_options", h_pcre_options, 2, 0}
|
||||
};
|
||||
|
||||
static struct symbol regexp_symbols[] = {
|
||||
{regexp_symbols+1, "regcomp", (void*) regcomp},
|
||||
{regexp_symbols+2, "regexec", (void*) regexec},
|
||||
{regexp_symbols+3, "regerror", (void*) regerror},
|
||||
{regexp_symbols+4, "regfree", (void*) regfree},
|
||||
{regexp_symbols+5, "pcre_compile", (void*) pcre_compile},
|
||||
{regexp_symbols+6, "pcre_exec", (void*) pcre_exec},
|
||||
{NULL, "pcre_free", NULL},
|
||||
};
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
|
||||
int pcre_plugin (struct pluginlink * pluginlink,
|
||||
int argc, char** argv){
|
||||
struct filter *flt, *tmpflt;
|
||||
pl = pluginlink;
|
||||
pcre_options = 0;
|
||||
if(!pcre_loaded){
|
||||
pcre_malloc = pl->myalloc;
|
||||
pcre_free = pl->myfree;
|
||||
pcre_loaded = 1;
|
||||
pthread_mutex_init(&pcre_mutex, NULL);
|
||||
regexp_symbols[6].value = pl->myfree;
|
||||
regexp_symbols[6].next = pl->symbols.next;
|
||||
pl->symbols.next = regexp_symbols;
|
||||
pcre_commandhandlers[3].next = pl->commandhandlers->next;
|
||||
pl->commandhandlers->next = pcre_commandhandlers;
|
||||
pcre_first_filter.next = pl->conf->filters;
|
||||
pl->conf->filters = &pcre_first_filter;
|
||||
}
|
||||
else if(pcre_last_filter){
|
||||
pcre_first_filter.next = pcre_last_filter->next;
|
||||
flt = pcre_first_filter.next;
|
||||
for(; flt; flt = tmpflt){
|
||||
tmpflt = flt->next;
|
||||
if(flt->data)
|
||||
pcre_data_free((struct pcre_filter_data *)flt->data);
|
||||
pl->myfree(flt);
|
||||
if(flt == pcre_last_filter) break;
|
||||
}
|
||||
}
|
||||
pcre_last_filter = NULL;
|
||||
return 0;
|
||||
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,82 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_refcount(), which is an
|
||||
auxiliary function that can be used to maintain a reference count in a compiled
|
||||
pattern data block. This might be helpful in applications where the block is
|
||||
shared by different users. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Maintain reference count *
|
||||
*************************************************/
|
||||
|
||||
/* The reference count is a 16-bit field, initialized to zero. It is not
|
||||
possible to transfer a non-zero count from one host to a different host that
|
||||
has a different byte order - though I can't see why anyone in their right mind
|
||||
would ever want to do that!
|
||||
|
||||
Arguments:
|
||||
argument_re points to compiled code
|
||||
adjust value to add to the count
|
||||
|
||||
Returns: the (possibly updated) count value (a non-negative number), or
|
||||
a negative error number
|
||||
*/
|
||||
|
||||
PCRE_EXP_DEFN int
|
||||
pcre_refcount(pcre *argument_re, int adjust)
|
||||
{
|
||||
real_pcre *re = (real_pcre *)argument_re;
|
||||
if (re == NULL) return PCRE_ERROR_NULL;
|
||||
re->ref_count = (-adjust > re->ref_count)? 0 :
|
||||
(adjust + re->ref_count > 65535)? 65535 :
|
||||
re->ref_count + adjust;
|
||||
return re->ref_count;
|
||||
}
|
||||
|
||||
/* End of pcre_refcount.c */
|
@ -1,579 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_study(), along with local
|
||||
supporting functions. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/* Returns from set_start_bits() */
|
||||
|
||||
enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE };
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Set a bit and maybe its alternate case *
|
||||
*************************************************/
|
||||
|
||||
/* Given a character, set its bit in the table, and also the bit for the other
|
||||
version of a letter if we are caseless.
|
||||
|
||||
Arguments:
|
||||
start_bits points to the bit map
|
||||
c is the character
|
||||
caseless the caseless flag
|
||||
cd the block with char table pointers
|
||||
|
||||
Returns: nothing
|
||||
*/
|
||||
|
||||
static void
|
||||
set_bit(uschar *start_bits, unsigned int c, BOOL caseless, compile_data *cd)
|
||||
{
|
||||
start_bits[c/8] |= (1 << (c&7));
|
||||
if (caseless && (cd->ctypes[c] & ctype_letter) != 0)
|
||||
start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Create bitmap of starting bytes *
|
||||
*************************************************/
|
||||
|
||||
/* This function scans a compiled unanchored expression recursively and
|
||||
attempts to build a bitmap of the set of possible starting bytes. As time goes
|
||||
by, we may be able to get more clever at doing this. The SSB_CONTINUE return is
|
||||
useful for parenthesized groups in patterns such as (a*)b where the group
|
||||
provides some optional starting bytes but scanning must continue at the outer
|
||||
level to find at least one mandatory byte. At the outermost level, this
|
||||
function fails unless the result is SSB_DONE.
|
||||
|
||||
Arguments:
|
||||
code points to an expression
|
||||
start_bits points to a 32-byte table, initialized to 0
|
||||
caseless the current state of the caseless flag
|
||||
utf8 TRUE if in UTF-8 mode
|
||||
cd the block with char table pointers
|
||||
|
||||
Returns: SSB_FAIL => Failed to find any starting bytes
|
||||
SSB_DONE => Found mandatory starting bytes
|
||||
SSB_CONTINUE => Found optional starting bytes
|
||||
*/
|
||||
|
||||
static int
|
||||
set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
|
||||
BOOL utf8, compile_data *cd)
|
||||
{
|
||||
register int c;
|
||||
int yield = SSB_DONE;
|
||||
|
||||
#if 0
|
||||
/* ========================================================================= */
|
||||
/* The following comment and code was inserted in January 1999. In May 2006,
|
||||
when it was observed to cause compiler warnings about unused values, I took it
|
||||
out again. If anybody is still using OS/2, they will have to put it back
|
||||
manually. */
|
||||
|
||||
/* This next statement and the later reference to dummy are here in order to
|
||||
trick the optimizer of the IBM C compiler for OS/2 into generating correct
|
||||
code. Apparently IBM isn't going to fix the problem, and we would rather not
|
||||
disable optimization (in this module it actually makes a big difference, and
|
||||
the pcre module can use all the optimization it can get). */
|
||||
|
||||
volatile int dummy;
|
||||
/* ========================================================================= */
|
||||
#endif
|
||||
|
||||
do
|
||||
{
|
||||
const uschar *tcode = code + (((int)*code == OP_CBRA)? 3:1) + LINK_SIZE;
|
||||
BOOL try_next = TRUE;
|
||||
|
||||
while (try_next) /* Loop for items in this branch */
|
||||
{
|
||||
int rc;
|
||||
switch(*tcode)
|
||||
{
|
||||
/* Fail if we reach something we don't understand */
|
||||
|
||||
default:
|
||||
return SSB_FAIL;
|
||||
|
||||
/* If we hit a bracket or a positive lookahead assertion, recurse to set
|
||||
bits from within the subpattern. If it can't find anything, we have to
|
||||
give up. If it finds some mandatory character(s), we are done for this
|
||||
branch. Otherwise, carry on scanning after the subpattern. */
|
||||
|
||||
case OP_BRA:
|
||||
case OP_SBRA:
|
||||
case OP_CBRA:
|
||||
case OP_SCBRA:
|
||||
case OP_ONCE:
|
||||
case OP_ASSERT:
|
||||
rc = set_start_bits(tcode, start_bits, caseless, utf8, cd);
|
||||
if (rc == SSB_FAIL) return SSB_FAIL;
|
||||
if (rc == SSB_DONE) try_next = FALSE; else
|
||||
{
|
||||
do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
|
||||
tcode += 1 + LINK_SIZE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* If we hit ALT or KET, it means we haven't found anything mandatory in
|
||||
this branch, though we might have found something optional. For ALT, we
|
||||
continue with the next alternative, but we have to arrange that the final
|
||||
result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
|
||||
return SSB_CONTINUE: if this is the top level, that indicates failure,
|
||||
but after a nested subpattern, it causes scanning to continue. */
|
||||
|
||||
case OP_ALT:
|
||||
yield = SSB_CONTINUE;
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
case OP_KET:
|
||||
case OP_KETRMAX:
|
||||
case OP_KETRMIN:
|
||||
return SSB_CONTINUE;
|
||||
|
||||
/* Skip over callout */
|
||||
|
||||
case OP_CALLOUT:
|
||||
tcode += 2 + 2*LINK_SIZE;
|
||||
break;
|
||||
|
||||
/* Skip over lookbehind and negative lookahead assertions */
|
||||
|
||||
case OP_ASSERT_NOT:
|
||||
case OP_ASSERTBACK:
|
||||
case OP_ASSERTBACK_NOT:
|
||||
do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
|
||||
tcode += 1 + LINK_SIZE;
|
||||
break;
|
||||
|
||||
/* Skip over an option setting, changing the caseless flag */
|
||||
|
||||
case OP_OPT:
|
||||
caseless = (tcode[1] & PCRE_CASELESS) != 0;
|
||||
tcode += 2;
|
||||
break;
|
||||
|
||||
/* BRAZERO does the bracket, but carries on. */
|
||||
|
||||
case OP_BRAZERO:
|
||||
case OP_BRAMINZERO:
|
||||
if (set_start_bits(++tcode, start_bits, caseless, utf8, cd) == SSB_FAIL)
|
||||
return SSB_FAIL;
|
||||
/* =========================================================================
|
||||
See the comment at the head of this function concerning the next line,
|
||||
which was an old fudge for the benefit of OS/2.
|
||||
dummy = 1;
|
||||
========================================================================= */
|
||||
do tcode += GET(tcode,1); while (*tcode == OP_ALT);
|
||||
tcode += 1 + LINK_SIZE;
|
||||
break;
|
||||
|
||||
/* Single-char * or ? sets the bit and tries the next item */
|
||||
|
||||
case OP_STAR:
|
||||
case OP_MINSTAR:
|
||||
case OP_POSSTAR:
|
||||
case OP_QUERY:
|
||||
case OP_MINQUERY:
|
||||
case OP_POSQUERY:
|
||||
set_bit(start_bits, tcode[1], caseless, cd);
|
||||
tcode += 2;
|
||||
#ifdef SUPPORT_UTF8
|
||||
if (utf8 && tcode[-1] >= 0xc0)
|
||||
tcode += _pcre_utf8_table4[tcode[-1] & 0x3f];
|
||||
#endif
|
||||
break;
|
||||
|
||||
/* Single-char upto sets the bit and tries the next */
|
||||
|
||||
case OP_UPTO:
|
||||
case OP_MINUPTO:
|
||||
case OP_POSUPTO:
|
||||
set_bit(start_bits, tcode[3], caseless, cd);
|
||||
tcode += 4;
|
||||
#ifdef SUPPORT_UTF8
|
||||
if (utf8 && tcode[-1] >= 0xc0)
|
||||
tcode += _pcre_utf8_table4[tcode[-1] & 0x3f];
|
||||
#endif
|
||||
break;
|
||||
|
||||
/* At least one single char sets the bit and stops */
|
||||
|
||||
case OP_EXACT: /* Fall through */
|
||||
tcode += 2;
|
||||
|
||||
case OP_CHAR:
|
||||
case OP_CHARNC:
|
||||
case OP_PLUS:
|
||||
case OP_MINPLUS:
|
||||
case OP_POSPLUS:
|
||||
set_bit(start_bits, tcode[1], caseless, cd);
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
/* Single character type sets the bits and stops */
|
||||
|
||||
case OP_NOT_DIGIT:
|
||||
for (c = 0; c < 32; c++)
|
||||
start_bits[c] |= ~cd->cbits[c+cbit_digit];
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
case OP_DIGIT:
|
||||
for (c = 0; c < 32; c++)
|
||||
start_bits[c] |= cd->cbits[c+cbit_digit];
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to
|
||||
discard it. */
|
||||
|
||||
case OP_NOT_WHITESPACE:
|
||||
for (c = 0; c < 32; c++)
|
||||
{
|
||||
int d = cd->cbits[c+cbit_space];
|
||||
if (c == 1) d &= ~0x08;
|
||||
start_bits[c] |= ~d;
|
||||
}
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to
|
||||
discard it. */
|
||||
|
||||
case OP_WHITESPACE:
|
||||
for (c = 0; c < 32; c++)
|
||||
{
|
||||
int d = cd->cbits[c+cbit_space];
|
||||
if (c == 1) d &= ~0x08;
|
||||
start_bits[c] |= d;
|
||||
}
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
case OP_NOT_WORDCHAR:
|
||||
for (c = 0; c < 32; c++)
|
||||
start_bits[c] |= ~cd->cbits[c+cbit_word];
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
case OP_WORDCHAR:
|
||||
for (c = 0; c < 32; c++)
|
||||
start_bits[c] |= cd->cbits[c+cbit_word];
|
||||
try_next = FALSE;
|
||||
break;
|
||||
|
||||
/* One or more character type fudges the pointer and restarts, knowing
|
||||
it will hit a single character type and stop there. */
|
||||
|
||||
case OP_TYPEPLUS:
|
||||
case OP_TYPEMINPLUS:
|
||||
tcode++;
|
||||
break;
|
||||
|
||||
case OP_TYPEEXACT:
|
||||
tcode += 3;
|
||||
break;
|
||||
|
||||
/* Zero or more repeats of character types set the bits and then
|
||||
try again. */
|
||||
|
||||
case OP_TYPEUPTO:
|
||||
case OP_TYPEMINUPTO:
|
||||
case OP_TYPEPOSUPTO:
|
||||
tcode += 2; /* Fall through */
|
||||
|
||||
case OP_TYPESTAR:
|
||||
case OP_TYPEMINSTAR:
|
||||
case OP_TYPEPOSSTAR:
|
||||
case OP_TYPEQUERY:
|
||||
case OP_TYPEMINQUERY:
|
||||
case OP_TYPEPOSQUERY:
|
||||
switch(tcode[1])
|
||||
{
|
||||
case OP_ANY:
|
||||
return SSB_FAIL;
|
||||
|
||||
case OP_NOT_DIGIT:
|
||||
for (c = 0; c < 32; c++)
|
||||
start_bits[c] |= ~cd->cbits[c+cbit_digit];
|
||||
break;
|
||||
|
||||
case OP_DIGIT:
|
||||
for (c = 0; c < 32; c++)
|
||||
start_bits[c] |= cd->cbits[c+cbit_digit];
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to
|
||||
discard it. */
|
||||
|
||||
case OP_NOT_WHITESPACE:
|
||||
for (c = 0; c < 32; c++)
|
||||
{
|
||||
int d = cd->cbits[c+cbit_space];
|
||||
if (c == 1) d &= ~0x08;
|
||||
start_bits[c] |= ~d;
|
||||
}
|
||||
break;
|
||||
|
||||
/* The cbit_space table has vertical tab as whitespace; we have to
|
||||
discard it. */
|
||||
|
||||
case OP_WHITESPACE:
|
||||
for (c = 0; c < 32; c++)
|
||||
{
|
||||
int d = cd->cbits[c+cbit_space];
|
||||
if (c == 1) d &= ~0x08;
|
||||
start_bits[c] |= d;
|
||||
}
|
||||
break;
|
||||
|
||||
case OP_NOT_WORDCHAR:
|
||||
for (c = 0; c < 32; c++)
|
||||
start_bits[c] |= ~cd->cbits[c+cbit_word];
|
||||
break;
|
||||
|
||||
case OP_WORDCHAR:
|
||||
for (c = 0; c < 32; c++)
|
||||
start_bits[c] |= cd->cbits[c+cbit_word];
|
||||
break;
|
||||
}
|
||||
|
||||
tcode += 2;
|
||||
break;
|
||||
|
||||
/* Character class where all the information is in a bit map: set the
|
||||
bits and either carry on or not, according to the repeat count. If it was
|
||||
a negative class, and we are operating with UTF-8 characters, any byte
|
||||
with a value >= 0xc4 is a potentially valid starter because it starts a
|
||||
character with a value > 255. */
|
||||
|
||||
case OP_NCLASS:
|
||||
#ifdef SUPPORT_UTF8
|
||||
if (utf8)
|
||||
{
|
||||
start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
|
||||
memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
|
||||
}
|
||||
#endif
|
||||
/* Fall through */
|
||||
|
||||
case OP_CLASS:
|
||||
{
|
||||
tcode++;
|
||||
|
||||
/* In UTF-8 mode, the bits in a bit map correspond to character
|
||||
values, not to byte values. However, the bit map we are constructing is
|
||||
for byte values. So we have to do a conversion for characters whose
|
||||
value is > 127. In fact, there are only two possible starting bytes for
|
||||
characters in the range 128 - 255. */
|
||||
|
||||
#ifdef SUPPORT_UTF8
|
||||
if (utf8)
|
||||
{
|
||||
for (c = 0; c < 16; c++) start_bits[c] |= tcode[c];
|
||||
for (c = 128; c < 256; c++)
|
||||
{
|
||||
if ((tcode[c/8] && (1 << (c&7))) != 0)
|
||||
{
|
||||
int d = (c >> 6) | 0xc0; /* Set bit for this starter */
|
||||
start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */
|
||||
c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* In non-UTF-8 mode, the two bit maps are completely compatible. */
|
||||
|
||||
else
|
||||
#endif
|
||||
{
|
||||
for (c = 0; c < 32; c++) start_bits[c] |= tcode[c];
|
||||
}
|
||||
|
||||
/* Advance past the bit map, and act on what follows */
|
||||
|
||||
tcode += 32;
|
||||
switch (*tcode)
|
||||
{
|
||||
case OP_CRSTAR:
|
||||
case OP_CRMINSTAR:
|
||||
case OP_CRQUERY:
|
||||
case OP_CRMINQUERY:
|
||||
tcode++;
|
||||
break;
|
||||
|
||||
case OP_CRRANGE:
|
||||
case OP_CRMINRANGE:
|
||||
if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5;
|
||||
else try_next = FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
try_next = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break; /* End of bitmap class handling */
|
||||
|
||||
} /* End of switch */
|
||||
} /* End of try_next loop */
|
||||
|
||||
code += GET(code, 1); /* Advance to next branch */
|
||||
}
|
||||
while (*code == OP_ALT);
|
||||
return yield;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Study a compiled expression *
|
||||
*************************************************/
|
||||
|
||||
/* This function is handed a compiled expression that it must study to produce
|
||||
information that will speed up the matching. It returns a pcre_extra block
|
||||
which then gets handed back to pcre_exec().
|
||||
|
||||
Arguments:
|
||||
re points to the compiled expression
|
||||
options contains option bits
|
||||
errorptr points to where to place error messages;
|
||||
set NULL unless error
|
||||
|
||||
Returns: pointer to a pcre_extra block, with study_data filled in and the
|
||||
appropriate flag set;
|
||||
NULL on error or if no optimization possible
|
||||
*/
|
||||
|
||||
PCRE_EXP_DEFN pcre_extra *
|
||||
pcre_study(const pcre *external_re, int options, const char **errorptr)
|
||||
{
|
||||
uschar start_bits[32];
|
||||
pcre_extra *extra;
|
||||
pcre_study_data *study;
|
||||
const uschar *tables;
|
||||
uschar *code;
|
||||
compile_data compile_block;
|
||||
const real_pcre *re = (const real_pcre *)external_re;
|
||||
|
||||
*errorptr = NULL;
|
||||
|
||||
if (re == NULL || re->magic_number != MAGIC_NUMBER)
|
||||
{
|
||||
*errorptr = "argument is not a compiled regular expression";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
|
||||
{
|
||||
*errorptr = "unknown or incorrect option bit(s) set";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
code = (uschar *)re + re->name_table_offset +
|
||||
(re->name_count * re->name_entry_size);
|
||||
|
||||
/* For an anchored pattern, or an unanchored pattern that has a first char, or
|
||||
a multiline pattern that matches only at "line starts", no further processing
|
||||
at present. */
|
||||
|
||||
if ((re->options & PCRE_ANCHORED) != 0 ||
|
||||
(re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) != 0)
|
||||
return NULL;
|
||||
|
||||
/* Set the character tables in the block that is passed around */
|
||||
|
||||
tables = re->tables;
|
||||
if (tables == NULL)
|
||||
(void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
|
||||
(void *)(&tables));
|
||||
|
||||
compile_block.lcc = tables + lcc_offset;
|
||||
compile_block.fcc = tables + fcc_offset;
|
||||
compile_block.cbits = tables + cbits_offset;
|
||||
compile_block.ctypes = tables + ctypes_offset;
|
||||
|
||||
/* See if we can find a fixed set of initial characters for the pattern. */
|
||||
|
||||
memset(start_bits, 0, 32 * sizeof(uschar));
|
||||
if (set_start_bits(code, start_bits, (re->options & PCRE_CASELESS) != 0,
|
||||
(re->options & PCRE_UTF8) != 0, &compile_block) != SSB_DONE) return NULL;
|
||||
|
||||
/* Get a pcre_extra block and a pcre_study_data block. The study data is put in
|
||||
the latter, which is pointed to by the former, which may also get additional
|
||||
data set later by the calling program. At the moment, the size of
|
||||
pcre_study_data is fixed. We nevertheless save it in a field for returning via
|
||||
the pcre_fullinfo() function so that if it becomes variable in the future, we
|
||||
don't have to change that code. */
|
||||
|
||||
extra = (pcre_extra *)(pcre_malloc)
|
||||
(sizeof(pcre_extra) + sizeof(pcre_study_data));
|
||||
|
||||
if (extra == NULL)
|
||||
{
|
||||
*errorptr = "failed to get memory";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra));
|
||||
extra->flags = PCRE_EXTRA_STUDY_DATA;
|
||||
extra->study_data = study;
|
||||
|
||||
study->size = sizeof(pcre_study_data);
|
||||
study->options = PCRE_STUDY_MAPPED;
|
||||
memcpy(study->start_bits, start_bits, sizeof(start_bits));
|
||||
|
||||
return extra;
|
||||
}
|
||||
|
||||
/* End of pcre_study.c */
|
@ -1,318 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains some fixed tables that are used by more than one of the
|
||||
PCRE code modules. The tables are also #included by the pcretest program, which
|
||||
uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name
|
||||
clashes with the library. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
|
||||
the definition is next to the definition of the opcodes in pcre_internal.h. */
|
||||
|
||||
const uschar _pcre_OP_lengths[] = { OP_LENGTHS };
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Tables for UTF-8 support *
|
||||
*************************************************/
|
||||
|
||||
/* These are the breakpoints for different numbers of bytes in a UTF-8
|
||||
character. */
|
||||
|
||||
#ifdef SUPPORT_UTF8
|
||||
|
||||
const int _pcre_utf8_table1[] =
|
||||
{ 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
|
||||
|
||||
const int _pcre_utf8_table1_size = sizeof(_pcre_utf8_table1)/sizeof(int);
|
||||
|
||||
/* These are the indicator bits and the mask for the data bits to set in the
|
||||
first byte of a character, indexed by the number of additional bytes. */
|
||||
|
||||
const int _pcre_utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
|
||||
const int _pcre_utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
|
||||
|
||||
/* Table of the number of extra bytes, indexed by the first byte masked with
|
||||
0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
|
||||
|
||||
const uschar _pcre_utf8_table4[] = {
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
|
||||
|
||||
/* The pcre_utt[] table below translates Unicode property names into type and
|
||||
code values. It is searched by binary chop, so must be in collating sequence of
|
||||
name. Originally, the table contained pointers to the name strings in the first
|
||||
field of each entry. However, that leads to a large number of relocations when
|
||||
a shared library is dynamically loaded. A significant reduction is made by
|
||||
putting all the names into a single, large string and then using offsets in the
|
||||
table itself. Maintenance is more error-prone, but frequent changes to this
|
||||
data is unlikely. */
|
||||
|
||||
const char _pcre_utt_names[] =
|
||||
"Any\0"
|
||||
"Arabic\0"
|
||||
"Armenian\0"
|
||||
"Balinese\0"
|
||||
"Bengali\0"
|
||||
"Bopomofo\0"
|
||||
"Braille\0"
|
||||
"Buginese\0"
|
||||
"Buhid\0"
|
||||
"C\0"
|
||||
"Canadian_Aboriginal\0"
|
||||
"Cc\0"
|
||||
"Cf\0"
|
||||
"Cherokee\0"
|
||||
"Cn\0"
|
||||
"Co\0"
|
||||
"Common\0"
|
||||
"Coptic\0"
|
||||
"Cs\0"
|
||||
"Cuneiform\0"
|
||||
"Cypriot\0"
|
||||
"Cyrillic\0"
|
||||
"Deseret\0"
|
||||
"Devanagari\0"
|
||||
"Ethiopic\0"
|
||||
"Georgian\0"
|
||||
"Glagolitic\0"
|
||||
"Gothic\0"
|
||||
"Greek\0"
|
||||
"Gujarati\0"
|
||||
"Gurmukhi\0"
|
||||
"Han\0"
|
||||
"Hangul\0"
|
||||
"Hanunoo\0"
|
||||
"Hebrew\0"
|
||||
"Hiragana\0"
|
||||
"Inherited\0"
|
||||
"Kannada\0"
|
||||
"Katakana\0"
|
||||
"Kharoshthi\0"
|
||||
"Khmer\0"
|
||||
"L\0"
|
||||
"L&\0"
|
||||
"Lao\0"
|
||||
"Latin\0"
|
||||
"Limbu\0"
|
||||
"Linear_B\0"
|
||||
"Ll\0"
|
||||
"Lm\0"
|
||||
"Lo\0"
|
||||
"Lt\0"
|
||||
"Lu\0"
|
||||
"M\0"
|
||||
"Malayalam\0"
|
||||
"Mc\0"
|
||||
"Me\0"
|
||||
"Mn\0"
|
||||
"Mongolian\0"
|
||||
"Myanmar\0"
|
||||
"N\0"
|
||||
"Nd\0"
|
||||
"New_Tai_Lue\0"
|
||||
"Nko\0"
|
||||
"Nl\0"
|
||||
"No\0"
|
||||
"Ogham\0"
|
||||
"Old_Italic\0"
|
||||
"Old_Persian\0"
|
||||
"Oriya\0"
|
||||
"Osmanya\0"
|
||||
"P\0"
|
||||
"Pc\0"
|
||||
"Pd\0"
|
||||
"Pe\0"
|
||||
"Pf\0"
|
||||
"Phags_Pa\0"
|
||||
"Phoenician\0"
|
||||
"Pi\0"
|
||||
"Po\0"
|
||||
"Ps\0"
|
||||
"Runic\0"
|
||||
"S\0"
|
||||
"Sc\0"
|
||||
"Shavian\0"
|
||||
"Sinhala\0"
|
||||
"Sk\0"
|
||||
"Sm\0"
|
||||
"So\0"
|
||||
"Syloti_Nagri\0"
|
||||
"Syriac\0"
|
||||
"Tagalog\0"
|
||||
"Tagbanwa\0"
|
||||
"Tai_Le\0"
|
||||
"Tamil\0"
|
||||
"Telugu\0"
|
||||
"Thaana\0"
|
||||
"Thai\0"
|
||||
"Tibetan\0"
|
||||
"Tifinagh\0"
|
||||
"Ugaritic\0"
|
||||
"Yi\0"
|
||||
"Z\0"
|
||||
"Zl\0"
|
||||
"Zp\0"
|
||||
"Zs\0";
|
||||
|
||||
const ucp_type_table _pcre_utt[] = {
|
||||
{ 0, PT_ANY, 0 },
|
||||
{ 4, PT_SC, ucp_Arabic },
|
||||
{ 11, PT_SC, ucp_Armenian },
|
||||
{ 20, PT_SC, ucp_Balinese },
|
||||
{ 29, PT_SC, ucp_Bengali },
|
||||
{ 37, PT_SC, ucp_Bopomofo },
|
||||
{ 46, PT_SC, ucp_Braille },
|
||||
{ 54, PT_SC, ucp_Buginese },
|
||||
{ 63, PT_SC, ucp_Buhid },
|
||||
{ 69, PT_GC, ucp_C },
|
||||
{ 71, PT_SC, ucp_Canadian_Aboriginal },
|
||||
{ 91, PT_PC, ucp_Cc },
|
||||
{ 94, PT_PC, ucp_Cf },
|
||||
{ 97, PT_SC, ucp_Cherokee },
|
||||
{ 106, PT_PC, ucp_Cn },
|
||||
{ 109, PT_PC, ucp_Co },
|
||||
{ 112, PT_SC, ucp_Common },
|
||||
{ 119, PT_SC, ucp_Coptic },
|
||||
{ 126, PT_PC, ucp_Cs },
|
||||
{ 129, PT_SC, ucp_Cuneiform },
|
||||
{ 139, PT_SC, ucp_Cypriot },
|
||||
{ 147, PT_SC, ucp_Cyrillic },
|
||||
{ 156, PT_SC, ucp_Deseret },
|
||||
{ 164, PT_SC, ucp_Devanagari },
|
||||
{ 175, PT_SC, ucp_Ethiopic },
|
||||
{ 184, PT_SC, ucp_Georgian },
|
||||
{ 193, PT_SC, ucp_Glagolitic },
|
||||
{ 204, PT_SC, ucp_Gothic },
|
||||
{ 211, PT_SC, ucp_Greek },
|
||||
{ 217, PT_SC, ucp_Gujarati },
|
||||
{ 226, PT_SC, ucp_Gurmukhi },
|
||||
{ 235, PT_SC, ucp_Han },
|
||||
{ 239, PT_SC, ucp_Hangul },
|
||||
{ 246, PT_SC, ucp_Hanunoo },
|
||||
{ 254, PT_SC, ucp_Hebrew },
|
||||
{ 261, PT_SC, ucp_Hiragana },
|
||||
{ 270, PT_SC, ucp_Inherited },
|
||||
{ 280, PT_SC, ucp_Kannada },
|
||||
{ 288, PT_SC, ucp_Katakana },
|
||||
{ 297, PT_SC, ucp_Kharoshthi },
|
||||
{ 308, PT_SC, ucp_Khmer },
|
||||
{ 314, PT_GC, ucp_L },
|
||||
{ 316, PT_LAMP, 0 },
|
||||
{ 319, PT_SC, ucp_Lao },
|
||||
{ 323, PT_SC, ucp_Latin },
|
||||
{ 329, PT_SC, ucp_Limbu },
|
||||
{ 335, PT_SC, ucp_Linear_B },
|
||||
{ 344, PT_PC, ucp_Ll },
|
||||
{ 347, PT_PC, ucp_Lm },
|
||||
{ 350, PT_PC, ucp_Lo },
|
||||
{ 353, PT_PC, ucp_Lt },
|
||||
{ 356, PT_PC, ucp_Lu },
|
||||
{ 359, PT_GC, ucp_M },
|
||||
{ 361, PT_SC, ucp_Malayalam },
|
||||
{ 371, PT_PC, ucp_Mc },
|
||||
{ 374, PT_PC, ucp_Me },
|
||||
{ 377, PT_PC, ucp_Mn },
|
||||
{ 380, PT_SC, ucp_Mongolian },
|
||||
{ 390, PT_SC, ucp_Myanmar },
|
||||
{ 398, PT_GC, ucp_N },
|
||||
{ 400, PT_PC, ucp_Nd },
|
||||
{ 403, PT_SC, ucp_New_Tai_Lue },
|
||||
{ 415, PT_SC, ucp_Nko },
|
||||
{ 419, PT_PC, ucp_Nl },
|
||||
{ 422, PT_PC, ucp_No },
|
||||
{ 425, PT_SC, ucp_Ogham },
|
||||
{ 431, PT_SC, ucp_Old_Italic },
|
||||
{ 442, PT_SC, ucp_Old_Persian },
|
||||
{ 454, PT_SC, ucp_Oriya },
|
||||
{ 460, PT_SC, ucp_Osmanya },
|
||||
{ 468, PT_GC, ucp_P },
|
||||
{ 470, PT_PC, ucp_Pc },
|
||||
{ 473, PT_PC, ucp_Pd },
|
||||
{ 476, PT_PC, ucp_Pe },
|
||||
{ 479, PT_PC, ucp_Pf },
|
||||
{ 482, PT_SC, ucp_Phags_Pa },
|
||||
{ 491, PT_SC, ucp_Phoenician },
|
||||
{ 502, PT_PC, ucp_Pi },
|
||||
{ 505, PT_PC, ucp_Po },
|
||||
{ 508, PT_PC, ucp_Ps },
|
||||
{ 511, PT_SC, ucp_Runic },
|
||||
{ 517, PT_GC, ucp_S },
|
||||
{ 519, PT_PC, ucp_Sc },
|
||||
{ 522, PT_SC, ucp_Shavian },
|
||||
{ 530, PT_SC, ucp_Sinhala },
|
||||
{ 538, PT_PC, ucp_Sk },
|
||||
{ 541, PT_PC, ucp_Sm },
|
||||
{ 544, PT_PC, ucp_So },
|
||||
{ 547, PT_SC, ucp_Syloti_Nagri },
|
||||
{ 560, PT_SC, ucp_Syriac },
|
||||
{ 567, PT_SC, ucp_Tagalog },
|
||||
{ 575, PT_SC, ucp_Tagbanwa },
|
||||
{ 584, PT_SC, ucp_Tai_Le },
|
||||
{ 591, PT_SC, ucp_Tamil },
|
||||
{ 597, PT_SC, ucp_Telugu },
|
||||
{ 604, PT_SC, ucp_Thaana },
|
||||
{ 611, PT_SC, ucp_Thai },
|
||||
{ 616, PT_SC, ucp_Tibetan },
|
||||
{ 624, PT_SC, ucp_Tifinagh },
|
||||
{ 633, PT_SC, ucp_Ugaritic },
|
||||
{ 642, PT_SC, ucp_Yi },
|
||||
{ 645, PT_GC, ucp_Z },
|
||||
{ 647, PT_PC, ucp_Zl },
|
||||
{ 650, PT_PC, ucp_Zp },
|
||||
{ 653, PT_PC, ucp_Zs }
|
||||
};
|
||||
|
||||
const int _pcre_utt_size = sizeof(_pcre_utt)/sizeof(ucp_type_table);
|
||||
|
||||
#endif /* SUPPORT_UTF8 */
|
||||
|
||||
/* End of pcre_tables.c */
|
@ -1,137 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains an internal function that tests a compiled pattern to
|
||||
see if it was compiled with the opposite endianness. If so, it uses an
|
||||
auxiliary local function to flip the appropriate bytes. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Flip bytes in an integer *
|
||||
*************************************************/
|
||||
|
||||
/* This function is called when the magic number in a regex doesn't match, in
|
||||
order to flip its bytes to see if we are dealing with a pattern that was
|
||||
compiled on a host of different endianness. If so, this function is used to
|
||||
flip other byte values.
|
||||
|
||||
Arguments:
|
||||
value the number to flip
|
||||
n the number of bytes to flip (assumed to be 2 or 4)
|
||||
|
||||
Returns: the flipped value
|
||||
*/
|
||||
|
||||
static unsigned long int
|
||||
byteflip(unsigned long int value, int n)
|
||||
{
|
||||
if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
|
||||
return ((value & 0x000000ff) << 24) |
|
||||
((value & 0x0000ff00) << 8) |
|
||||
((value & 0x00ff0000) >> 8) |
|
||||
((value & 0xff000000) >> 24);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Test for a byte-flipped compiled regex *
|
||||
*************************************************/
|
||||
|
||||
/* This function is called from pcre_exec(), pcre_dfa_exec(), and also from
|
||||
pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that
|
||||
is, it was compiled on a system of opposite endianness. The function is called
|
||||
only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped,
|
||||
we flip all the relevant values into a different data block, and return it.
|
||||
|
||||
Arguments:
|
||||
re points to the regex
|
||||
study points to study data, or NULL
|
||||
internal_re points to a new regex block
|
||||
internal_study points to a new study block
|
||||
|
||||
Returns: the new block if is is indeed a byte-flipped regex
|
||||
NULL if it is not
|
||||
*/
|
||||
|
||||
real_pcre *
|
||||
_pcre_try_flipped(const real_pcre *re, real_pcre *internal_re,
|
||||
const pcre_study_data *study, pcre_study_data *internal_study)
|
||||
{
|
||||
if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER)
|
||||
return NULL;
|
||||
|
||||
*internal_re = *re; /* To copy other fields */
|
||||
internal_re->size = byteflip(re->size, sizeof(re->size));
|
||||
internal_re->options = byteflip(re->options, sizeof(re->options));
|
||||
internal_re->flags = (pcre_uint16)byteflip(re->flags, sizeof(re->flags));
|
||||
internal_re->top_bracket =
|
||||
(pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket));
|
||||
internal_re->top_backref =
|
||||
(pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref));
|
||||
internal_re->first_byte =
|
||||
(pcre_uint16)byteflip(re->first_byte, sizeof(re->first_byte));
|
||||
internal_re->req_byte =
|
||||
(pcre_uint16)byteflip(re->req_byte, sizeof(re->req_byte));
|
||||
internal_re->name_table_offset =
|
||||
(pcre_uint16)byteflip(re->name_table_offset, sizeof(re->name_table_offset));
|
||||
internal_re->name_entry_size =
|
||||
(pcre_uint16)byteflip(re->name_entry_size, sizeof(re->name_entry_size));
|
||||
internal_re->name_count =
|
||||
(pcre_uint16)byteflip(re->name_count, sizeof(re->name_count));
|
||||
|
||||
if (study != NULL)
|
||||
{
|
||||
*internal_study = *study; /* To copy other fields */
|
||||
internal_study->size = byteflip(study->size, sizeof(study->size));
|
||||
internal_study->options = byteflip(study->options, sizeof(study->options));
|
||||
}
|
||||
|
||||
return internal_re;
|
||||
}
|
||||
|
||||
/* End of pcre_tryflipped.c */
|
@ -1,179 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains code for searching the table of Unicode character
|
||||
properties. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
#include "ucp.h" /* Category definitions */
|
||||
#include "ucpinternal.h" /* Internal table details */
|
||||
#include "ucptable.h" /* The table itself */
|
||||
|
||||
|
||||
/* Table to translate from particular type value to the general value. */
|
||||
|
||||
static const int ucp_gentype[] = {
|
||||
ucp_C, ucp_C, ucp_C, ucp_C, ucp_C, /* Cc, Cf, Cn, Co, Cs */
|
||||
ucp_L, ucp_L, ucp_L, ucp_L, ucp_L, /* Ll, Lu, Lm, Lo, Lt */
|
||||
ucp_M, ucp_M, ucp_M, /* Mc, Me, Mn */
|
||||
ucp_N, ucp_N, ucp_N, /* Nd, Nl, No */
|
||||
ucp_P, ucp_P, ucp_P, ucp_P, ucp_P, /* Pc, Pd, Pe, Pf, Pi */
|
||||
ucp_P, ucp_P, /* Ps, Po */
|
||||
ucp_S, ucp_S, ucp_S, ucp_S, /* Sc, Sk, Sm, So */
|
||||
ucp_Z, ucp_Z, ucp_Z /* Zl, Zp, Zs */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Search table and return type *
|
||||
*************************************************/
|
||||
|
||||
/* Three values are returned: the category is ucp_C, ucp_L, etc. The detailed
|
||||
character type is ucp_Lu, ucp_Nd, etc. The script is ucp_Latin, etc.
|
||||
|
||||
Arguments:
|
||||
c the character value
|
||||
type_ptr the detailed character type is returned here
|
||||
script_ptr the script is returned here
|
||||
|
||||
Returns: the character type category
|
||||
*/
|
||||
|
||||
int
|
||||
_pcre_ucp_findprop(const unsigned int c, int *type_ptr, int *script_ptr)
|
||||
{
|
||||
int bot = 0;
|
||||
int top = sizeof(ucp_table)/sizeof(cnode);
|
||||
int mid;
|
||||
|
||||
/* The table is searched using a binary chop. You might think that using
|
||||
intermediate variables to hold some of the common expressions would speed
|
||||
things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it
|
||||
makes things a lot slower. */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (top <= bot)
|
||||
{
|
||||
*type_ptr = ucp_Cn;
|
||||
*script_ptr = ucp_Common;
|
||||
return ucp_C;
|
||||
}
|
||||
mid = (bot + top) >> 1;
|
||||
if (c == (ucp_table[mid].f0 & f0_charmask)) break;
|
||||
if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid;
|
||||
else
|
||||
{
|
||||
if ((ucp_table[mid].f0 & f0_rangeflag) != 0 &&
|
||||
c <= (ucp_table[mid].f0 & f0_charmask) +
|
||||
(ucp_table[mid].f1 & f1_rangemask)) break;
|
||||
bot = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Found an entry in the table. Set the script and detailed type values, and
|
||||
return the general type. */
|
||||
|
||||
*script_ptr = (ucp_table[mid].f0 & f0_scriptmask) >> f0_scriptshift;
|
||||
*type_ptr = (ucp_table[mid].f1 & f1_typemask) >> f1_typeshift;
|
||||
|
||||
return ucp_gentype[*type_ptr];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Search table and return other case *
|
||||
*************************************************/
|
||||
|
||||
/* If the given character is a letter, and there is another case for the
|
||||
letter, return the other case. Otherwise, return -1.
|
||||
|
||||
Arguments:
|
||||
c the character value
|
||||
|
||||
Returns: the other case or NOTACHAR if none
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
_pcre_ucp_othercase(const unsigned int c)
|
||||
{
|
||||
int bot = 0;
|
||||
int top = sizeof(ucp_table)/sizeof(cnode);
|
||||
int mid, offset;
|
||||
|
||||
/* The table is searched using a binary chop. You might think that using
|
||||
intermediate variables to hold some of the common expressions would speed
|
||||
things up, but tests with gcc 3.4.4 on Linux showed that, on the contrary, it
|
||||
makes things a lot slower. */
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (top <= bot) return -1;
|
||||
mid = (bot + top) >> 1;
|
||||
if (c == (ucp_table[mid].f0 & f0_charmask)) break;
|
||||
if (c < (ucp_table[mid].f0 & f0_charmask)) top = mid;
|
||||
else
|
||||
{
|
||||
if ((ucp_table[mid].f0 & f0_rangeflag) != 0 &&
|
||||
c <= (ucp_table[mid].f0 & f0_charmask) +
|
||||
(ucp_table[mid].f1 & f1_rangemask)) break;
|
||||
bot = mid + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Found an entry in the table. Return NOTACHAR for a range entry. Otherwise
|
||||
return the other case if there is one, else NOTACHAR. */
|
||||
|
||||
if ((ucp_table[mid].f0 & f0_rangeflag) != 0) return NOTACHAR;
|
||||
|
||||
offset = ucp_table[mid].f1 & f1_casemask;
|
||||
if ((offset & f1_caseneg) != 0) offset |= f1_caseneg;
|
||||
return (offset == 0)? NOTACHAR : c + offset;
|
||||
}
|
||||
|
||||
|
||||
/* End of pcre_ucp_searchfuncs.c */
|
@ -1,162 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains an internal function for validating UTF-8 character
|
||||
strings. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Validate a UTF-8 string *
|
||||
*************************************************/
|
||||
|
||||
/* This function is called (optionally) at the start of compile or match, to
|
||||
validate that a supposed UTF-8 string is actually valid. The early check means
|
||||
that subsequent code can assume it is dealing with a valid string. The check
|
||||
can be turned off for maximum performance, but the consequences of supplying
|
||||
an invalid string are then undefined.
|
||||
|
||||
Originally, this function checked according to RFC 2279, allowing for values in
|
||||
the range 0 to 0x7fffffff, up to 6 bytes long, but ensuring that they were in
|
||||
the canonical format. Once somebody had pointed out RFC 3629 to me (it
|
||||
obsoletes 2279), additional restrictions were applies. The values are now
|
||||
limited to be between 0 and 0x0010ffff, no more than 4 bytes long, and the
|
||||
subrange 0xd000 to 0xdfff is excluded.
|
||||
|
||||
Arguments:
|
||||
string points to the string
|
||||
length length of string, or -1 if the string is zero-terminated
|
||||
|
||||
Returns: < 0 if the string is a valid UTF-8 string
|
||||
>= 0 otherwise; the value is the offset of the bad byte
|
||||
*/
|
||||
|
||||
int
|
||||
_pcre_valid_utf8(const uschar *string, int length)
|
||||
{
|
||||
#ifdef SUPPORT_UTF8
|
||||
register const uschar *p;
|
||||
|
||||
if (length < 0)
|
||||
{
|
||||
for (p = string; *p != 0; p++);
|
||||
length = p - string;
|
||||
}
|
||||
|
||||
for (p = string; length-- > 0; p++)
|
||||
{
|
||||
register int ab;
|
||||
register int c = *p;
|
||||
if (c < 128) continue;
|
||||
if (c < 0xc0) return p - string;
|
||||
ab = _pcre_utf8_table4[c & 0x3f]; /* Number of additional bytes */
|
||||
if (length < ab || ab > 3) return p - string;
|
||||
length -= ab;
|
||||
|
||||
/* Check top bits in the second byte */
|
||||
if ((*(++p) & 0xc0) != 0x80) return p - string;
|
||||
|
||||
/* Check for overlong sequences for each different length, and for the
|
||||
excluded range 0xd000 to 0xdfff. */
|
||||
|
||||
switch (ab)
|
||||
{
|
||||
/* Check for xx00 000x (overlong sequence) */
|
||||
|
||||
case 1:
|
||||
if ((c & 0x3e) == 0) return p - string;
|
||||
continue; /* We know there aren't any more bytes to check */
|
||||
|
||||
/* Check for 1110 0000, xx0x xxxx (overlong sequence) or
|
||||
1110 1101, 1010 xxxx (0xd000 - 0xdfff) */
|
||||
|
||||
case 2:
|
||||
if ((c == 0xe0 && (*p & 0x20) == 0) ||
|
||||
(c == 0xed && *p >= 0xa0))
|
||||
return p - string;
|
||||
break;
|
||||
|
||||
/* Check for 1111 0000, xx00 xxxx (overlong sequence) or
|
||||
greater than 0x0010ffff (f4 8f bf bf) */
|
||||
|
||||
case 3:
|
||||
if ((c == 0xf0 && (*p & 0x30) == 0) ||
|
||||
(c > 0xf4 ) ||
|
||||
(c == 0xf4 && *p > 0x8f))
|
||||
return p - string;
|
||||
break;
|
||||
|
||||
#if 0
|
||||
/* These cases can no longer occur, as we restrict to a maximum of four
|
||||
bytes nowadays. Leave the code here in case we ever want to add an option
|
||||
for longer sequences. */
|
||||
|
||||
/* Check for 1111 1000, xx00 0xxx */
|
||||
case 4:
|
||||
if (c == 0xf8 && (*p & 0x38) == 0) return p - string;
|
||||
break;
|
||||
|
||||
/* Check for leading 0xfe or 0xff, and then for 1111 1100, xx00 00xx */
|
||||
case 5:
|
||||
if (c == 0xfe || c == 0xff ||
|
||||
(c == 0xfc && (*p & 0x3c) == 0)) return p - string;
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* Check for valid bytes after the 2nd, if any; all must start 10 */
|
||||
while (--ab > 0)
|
||||
{
|
||||
if ((*(++p) & 0xc0) != 0x80) return p - string;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* End of pcre_valid_utf8.c */
|
@ -1,90 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains the external function pcre_version(), which returns a
|
||||
string that identifies the PCRE version that is in use. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Return version string *
|
||||
*************************************************/
|
||||
|
||||
/* These macros are the standard way of turning unquoted text into C strings.
|
||||
They allow macros like PCRE_MAJOR to be defined without quotes, which is
|
||||
convenient for user programs that want to test its value. */
|
||||
|
||||
#define STRING(a) # a
|
||||
#define XSTRING(s) STRING(s)
|
||||
|
||||
/* A problem turned up with PCRE_PRERELEASE, which is defined empty for
|
||||
production releases. Originally, it was used naively in this code:
|
||||
|
||||
return XSTRING(PCRE_MAJOR)
|
||||
"." XSTRING(PCRE_MINOR)
|
||||
XSTRING(PCRE_PRERELEASE)
|
||||
" " XSTRING(PCRE_DATE);
|
||||
|
||||
However, when PCRE_PRERELEASE is empty, this leads to an attempted expansion of
|
||||
STRING(). The C standard states: "If (before argument substitution) any
|
||||
argument consists of no preprocessing tokens, the behavior is undefined." It
|
||||
turns out the gcc treats this case as a single empty string - which is what we
|
||||
really want - but Visual C grumbles about the lack of an argument for the
|
||||
macro. Unfortunately, both are within their rights. To cope with both ways of
|
||||
handling this, I had resort to some messy hackery that does a test at run time.
|
||||
I could find no way of detecting that a macro is defined as an empty string at
|
||||
pre-processor time. This hack uses a standard trick for avoiding calling
|
||||
the STRING macro with an empty argument when doing the test. */
|
||||
|
||||
PCRE_EXP_DEFN const char *
|
||||
pcre_version(void)
|
||||
{
|
||||
return (XSTRING(Z PCRE_PRERELEASE)[1] == 0)?
|
||||
XSTRING(PCRE_MAJOR.PCRE_MINOR PCRE_DATE) :
|
||||
XSTRING(PCRE_MAJOR.PCRE_MINOR) XSTRING(PCRE_PRERELEASE PCRE_DATE);
|
||||
}
|
||||
|
||||
/* End of pcre_version.c */
|
@ -1,148 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module contains an internal function that is used to match an extended
|
||||
class (one that contains characters whose values are > 255). It is used by both
|
||||
pcre_exec() and pcre_def_exec(). */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "pcre_internal.h"
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Match character against an XCLASS *
|
||||
*************************************************/
|
||||
|
||||
/* This function is called to match a character against an extended class that
|
||||
might contain values > 255.
|
||||
|
||||
Arguments:
|
||||
c the character
|
||||
data points to the flag byte of the XCLASS data
|
||||
|
||||
Returns: TRUE if character matches, else FALSE
|
||||
*/
|
||||
|
||||
BOOL
|
||||
_pcre_xclass(int c, const uschar *data)
|
||||
{
|
||||
int t;
|
||||
BOOL negated = (*data & XCL_NOT) != 0;
|
||||
|
||||
/* Character values < 256 are matched against a bitmap, if one is present. If
|
||||
not, we still carry on, because there may be ranges that start below 256 in the
|
||||
additional data. */
|
||||
|
||||
if (c < 256)
|
||||
{
|
||||
if ((*data & XCL_MAP) != 0 && (data[1 + c/8] & (1 << (c&7))) != 0)
|
||||
return !negated; /* char found */
|
||||
}
|
||||
|
||||
/* First skip the bit map if present. Then match against the list of Unicode
|
||||
properties or large chars or ranges that end with a large char. We won't ever
|
||||
encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */
|
||||
|
||||
if ((*data++ & XCL_MAP) != 0) data += 32;
|
||||
|
||||
while ((t = *data++) != XCL_END)
|
||||
{
|
||||
int x, y;
|
||||
if (t == XCL_SINGLE)
|
||||
{
|
||||
GETCHARINC(x, data);
|
||||
if (c == x) return !negated;
|
||||
}
|
||||
else if (t == XCL_RANGE)
|
||||
{
|
||||
GETCHARINC(x, data);
|
||||
GETCHARINC(y, data);
|
||||
if (c >= x && c <= y) return !negated;
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_UCP
|
||||
else /* XCL_PROP & XCL_NOTPROP */
|
||||
{
|
||||
int chartype, script;
|
||||
int category = _pcre_ucp_findprop(c, &chartype, &script);
|
||||
|
||||
switch(*data)
|
||||
{
|
||||
case PT_ANY:
|
||||
if (t == XCL_PROP) return !negated;
|
||||
break;
|
||||
|
||||
case PT_LAMP:
|
||||
if ((chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt) ==
|
||||
(t == XCL_PROP)) return !negated;
|
||||
break;
|
||||
|
||||
case PT_GC:
|
||||
if ((data[1] == category) == (t == XCL_PROP)) return !negated;
|
||||
break;
|
||||
|
||||
case PT_PC:
|
||||
if ((data[1] == chartype) == (t == XCL_PROP)) return !negated;
|
||||
break;
|
||||
|
||||
case PT_SC:
|
||||
if ((data[1] == script) == (t == XCL_PROP)) return !negated;
|
||||
break;
|
||||
|
||||
/* This should never occur, but compilers may mutter if there is no
|
||||
default. */
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data += 2;
|
||||
}
|
||||
#endif /* SUPPORT_UCP */
|
||||
}
|
||||
|
||||
return negated; /* char did not match */
|
||||
}
|
||||
|
||||
/* End of pcre_xclass.c */
|
@ -1,337 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
/* PCRE is a library of functions to support regular expressions whose syntax
|
||||
and semantics are as close as possible to those of the Perl 5 language.
|
||||
|
||||
Written by Philip Hazel
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/* This module is a wrapper that provides a POSIX API to the underlying PCRE
|
||||
functions. */
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* Ensure that the PCREPOSIX_EXP_xxx macros are set appropriately for
|
||||
compiling these functions. This must come before including pcreposix.h, where
|
||||
they are set for an application (using these functions) if they have not
|
||||
previously been set. */
|
||||
|
||||
#if defined(_WIN32) && !defined(PCRE_STATIC)
|
||||
# define PCREPOSIX_EXP_DECL extern __declspec(dllexport)
|
||||
# define PCREPOSIX_EXP_DEFN __declspec(dllexport)
|
||||
#endif
|
||||
|
||||
#include "pcre.h"
|
||||
#include "pcre_internal.h"
|
||||
#include "pcreposix.h"
|
||||
|
||||
|
||||
/* Table to translate PCRE compile time error codes into POSIX error codes. */
|
||||
|
||||
static const int eint[] = {
|
||||
0, /* no error */
|
||||
REG_EESCAPE, /* \ at end of pattern */
|
||||
REG_EESCAPE, /* \c at end of pattern */
|
||||
REG_EESCAPE, /* unrecognized character follows \ */
|
||||
REG_BADBR, /* numbers out of order in {} quantifier */
|
||||
REG_BADBR, /* number too big in {} quantifier */
|
||||
REG_EBRACK, /* missing terminating ] for character class */
|
||||
REG_ECTYPE, /* invalid escape sequence in character class */
|
||||
REG_ERANGE, /* range out of order in character class */
|
||||
REG_BADRPT, /* nothing to repeat */
|
||||
REG_BADRPT, /* operand of unlimited repeat could match the empty string */
|
||||
REG_ASSERT, /* internal error: unexpected repeat */
|
||||
REG_BADPAT, /* unrecognized character after (? */
|
||||
REG_BADPAT, /* POSIX named classes are supported only within a class */
|
||||
REG_EPAREN, /* missing ) */
|
||||
REG_ESUBREG, /* reference to non-existent subpattern */
|
||||
REG_INVARG, /* erroffset passed as NULL */
|
||||
REG_INVARG, /* unknown option bit(s) set */
|
||||
REG_EPAREN, /* missing ) after comment */
|
||||
REG_ESIZE, /* parentheses nested too deeply */
|
||||
REG_ESIZE, /* regular expression too large */
|
||||
REG_ESPACE, /* failed to get memory */
|
||||
REG_EPAREN, /* unmatched brackets */
|
||||
REG_ASSERT, /* internal error: code overflow */
|
||||
REG_BADPAT, /* unrecognized character after (?< */
|
||||
REG_BADPAT, /* lookbehind assertion is not fixed length */
|
||||
REG_BADPAT, /* malformed number or name after (?( */
|
||||
REG_BADPAT, /* conditional group contains more than two branches */
|
||||
REG_BADPAT, /* assertion expected after (?( */
|
||||
REG_BADPAT, /* (?R or (?[+-]digits must be followed by ) */
|
||||
REG_ECTYPE, /* unknown POSIX class name */
|
||||
REG_BADPAT, /* POSIX collating elements are not supported */
|
||||
REG_INVARG, /* this version of PCRE is not compiled with PCRE_UTF8 support */
|
||||
REG_BADPAT, /* spare error */
|
||||
REG_BADPAT, /* character value in \x{...} sequence is too large */
|
||||
REG_BADPAT, /* invalid condition (?(0) */
|
||||
REG_BADPAT, /* \C not allowed in lookbehind assertion */
|
||||
REG_EESCAPE, /* PCRE does not support \L, \l, \N, \U, or \u */
|
||||
REG_BADPAT, /* number after (?C is > 255 */
|
||||
REG_BADPAT, /* closing ) for (?C expected */
|
||||
REG_BADPAT, /* recursive call could loop indefinitely */
|
||||
REG_BADPAT, /* unrecognized character after (?P */
|
||||
REG_BADPAT, /* syntax error in subpattern name (missing terminator) */
|
||||
REG_BADPAT, /* two named subpatterns have the same name */
|
||||
REG_BADPAT, /* invalid UTF-8 string */
|
||||
REG_BADPAT, /* support for \P, \p, and \X has not been compiled */
|
||||
REG_BADPAT, /* malformed \P or \p sequence */
|
||||
REG_BADPAT, /* unknown property name after \P or \p */
|
||||
REG_BADPAT, /* subpattern name is too long (maximum 32 characters) */
|
||||
REG_BADPAT, /* too many named subpatterns (maximum 10,000) */
|
||||
REG_BADPAT, /* repeated subpattern is too long */
|
||||
REG_BADPAT, /* octal value is greater than \377 (not in UTF-8 mode) */
|
||||
REG_BADPAT, /* internal error: overran compiling workspace */
|
||||
REG_BADPAT, /* internal error: previously-checked referenced subpattern not found */
|
||||
REG_BADPAT, /* DEFINE group contains more than one branch */
|
||||
REG_BADPAT, /* repeating a DEFINE group is not allowed */
|
||||
REG_INVARG, /* inconsistent NEWLINE options */
|
||||
REG_BADPAT, /* \g is not followed followed by an (optionally braced) non-zero number */
|
||||
REG_BADPAT, /* (?+ or (?- must be followed by a non-zero number */
|
||||
REG_BADPAT /* number is too big */
|
||||
};
|
||||
|
||||
/* Table of texts corresponding to POSIX error codes */
|
||||
|
||||
static const char *const pstring[] = {
|
||||
"", /* Dummy for value 0 */
|
||||
"internal error", /* REG_ASSERT */
|
||||
"invalid repeat counts in {}", /* BADBR */
|
||||
"pattern error", /* BADPAT */
|
||||
"? * + invalid", /* BADRPT */
|
||||
"unbalanced {}", /* EBRACE */
|
||||
"unbalanced []", /* EBRACK */
|
||||
"collation error - not relevant", /* ECOLLATE */
|
||||
"bad class", /* ECTYPE */
|
||||
"bad escape sequence", /* EESCAPE */
|
||||
"empty expression", /* EMPTY */
|
||||
"unbalanced ()", /* EPAREN */
|
||||
"bad range inside []", /* ERANGE */
|
||||
"expression too big", /* ESIZE */
|
||||
"failed to get memory", /* ESPACE */
|
||||
"bad back reference", /* ESUBREG */
|
||||
"bad argument", /* INVARG */
|
||||
"match failed" /* NOMATCH */
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Translate error code to string *
|
||||
*************************************************/
|
||||
|
||||
PCREPOSIX_EXP_DEFN size_t
|
||||
regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
|
||||
{
|
||||
const char *message, *addmessage;
|
||||
size_t length, addlength;
|
||||
|
||||
message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))?
|
||||
"unknown error code" : pstring[errcode];
|
||||
length = strlen(message) + 1;
|
||||
|
||||
addmessage = " at offset ";
|
||||
addlength = (preg != NULL && (int)preg->re_erroffset != -1)?
|
||||
strlen(addmessage) + 6 : 0;
|
||||
|
||||
if (errbuf_size > 0)
|
||||
{
|
||||
if (addlength > 0 && errbuf_size >= length + addlength)
|
||||
sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset);
|
||||
else
|
||||
{
|
||||
strncpy(errbuf, message, errbuf_size - 1);
|
||||
errbuf[errbuf_size-1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return length + addlength;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Free store held by a regex *
|
||||
*************************************************/
|
||||
|
||||
PCREPOSIX_EXP_DEFN void
|
||||
regfree(regex_t *preg)
|
||||
{
|
||||
(pcre_free)(preg->re_pcre);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Compile a regular expression *
|
||||
*************************************************/
|
||||
|
||||
/*
|
||||
Arguments:
|
||||
preg points to a structure for recording the compiled expression
|
||||
pattern the pattern to compile
|
||||
cflags compilation flags
|
||||
|
||||
Returns: 0 on success
|
||||
various non-zero codes on failure
|
||||
*/
|
||||
|
||||
PCREPOSIX_EXP_DEFN int
|
||||
regcomp(regex_t *preg, const char *pattern, int cflags)
|
||||
{
|
||||
const char *errorptr;
|
||||
int erroffset;
|
||||
int errorcode;
|
||||
int options = 0;
|
||||
|
||||
if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS;
|
||||
if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE;
|
||||
if ((cflags & REG_DOTALL) != 0) options |= PCRE_DOTALL;
|
||||
if ((cflags & REG_NOSUB) != 0) options |= PCRE_NO_AUTO_CAPTURE;
|
||||
if ((cflags & REG_UTF8) != 0) options |= PCRE_UTF8;
|
||||
|
||||
preg->re_pcre = pcre_compile2(pattern, options, &errorcode, &errorptr,
|
||||
&erroffset, NULL);
|
||||
preg->re_erroffset = erroffset;
|
||||
|
||||
if (preg->re_pcre == NULL) return eint[errorcode];
|
||||
|
||||
preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Match a regular expression *
|
||||
*************************************************/
|
||||
|
||||
/* Unfortunately, PCRE requires 3 ints of working space for each captured
|
||||
substring, so we have to get and release working store instead of just using
|
||||
the POSIX structures as was done in earlier releases when PCRE needed only 2
|
||||
ints. However, if the number of possible capturing brackets is small, use a
|
||||
block of store on the stack, to reduce the use of malloc/free. The threshold is
|
||||
in a macro that can be changed at configure time.
|
||||
|
||||
If REG_NOSUB was specified at compile time, the PCRE_NO_AUTO_CAPTURE flag will
|
||||
be set. When this is the case, the nmatch and pmatch arguments are ignored, and
|
||||
the only result is yes/no/error. */
|
||||
|
||||
PCREPOSIX_EXP_DEFN int
|
||||
regexec(const regex_t *preg, const char *string, size_t nmatch,
|
||||
regmatch_t pmatch[], int eflags)
|
||||
{
|
||||
int rc;
|
||||
int options = 0;
|
||||
int *ovector = NULL;
|
||||
int small_ovector[POSIX_MALLOC_THRESHOLD * 3];
|
||||
BOOL allocated_ovector = FALSE;
|
||||
BOOL nosub =
|
||||
(((const pcre *)preg->re_pcre)->options & PCRE_NO_AUTO_CAPTURE) != 0;
|
||||
|
||||
if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
|
||||
if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
|
||||
|
||||
((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */
|
||||
|
||||
/* When no string data is being returned, ensure that nmatch is zero.
|
||||
Otherwise, ensure the vector for holding the return data is large enough. */
|
||||
|
||||
if (nosub) nmatch = 0;
|
||||
|
||||
else if (nmatch > 0)
|
||||
{
|
||||
if (nmatch <= POSIX_MALLOC_THRESHOLD)
|
||||
{
|
||||
ovector = &(small_ovector[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nmatch > INT_MAX/(sizeof(int) * 3)) return REG_ESPACE;
|
||||
ovector = (int *)malloc(sizeof(int) * nmatch * 3);
|
||||
if (ovector == NULL) return REG_ESPACE;
|
||||
allocated_ovector = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string, (int)strlen(string),
|
||||
0, options, ovector, nmatch * 3);
|
||||
|
||||
if (rc == 0) rc = nmatch; /* All captured slots were filled in */
|
||||
|
||||
if (rc >= 0)
|
||||
{
|
||||
size_t i;
|
||||
if (!nosub)
|
||||
{
|
||||
for (i = 0; i < (size_t)rc; i++)
|
||||
{
|
||||
pmatch[i].rm_so = ovector[i*2];
|
||||
pmatch[i].rm_eo = ovector[i*2+1];
|
||||
}
|
||||
if (allocated_ovector) free(ovector);
|
||||
for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (allocated_ovector) free(ovector);
|
||||
switch(rc)
|
||||
{
|
||||
case PCRE_ERROR_NOMATCH: return REG_NOMATCH;
|
||||
case PCRE_ERROR_NULL: return REG_INVARG;
|
||||
case PCRE_ERROR_BADOPTION: return REG_INVARG;
|
||||
case PCRE_ERROR_BADMAGIC: return REG_INVARG;
|
||||
case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT;
|
||||
case PCRE_ERROR_NOMEMORY: return REG_ESPACE;
|
||||
case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE;
|
||||
case PCRE_ERROR_BADUTF8: return REG_INVARG;
|
||||
case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG;
|
||||
default: return REG_ASSERT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* End of pcreposix.c */
|
@ -1,142 +0,0 @@
|
||||
/*************************************************
|
||||
* Perl-Compatible Regular Expressions *
|
||||
*************************************************/
|
||||
|
||||
#ifndef _PCREPOSIX_H
|
||||
#define _PCREPOSIX_H
|
||||
|
||||
/* This is the header for the POSIX wrapper interface to the PCRE Perl-
|
||||
Compatible Regular Expression library. It defines the things POSIX says should
|
||||
be there. I hope.
|
||||
|
||||
Copyright (c) 1997-2007 University of Cambridge
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* Neither the name of the University of Cambridge nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* Have to include stdlib.h in order to ensure that size_t is defined. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Allow for C++ users */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Options, mostly defined by POSIX, but with a couple of extras. */
|
||||
|
||||
#define REG_ICASE 0x0001
|
||||
#define REG_NEWLINE 0x0002
|
||||
#define REG_NOTBOL 0x0004
|
||||
#define REG_NOTEOL 0x0008
|
||||
#define REG_DOTALL 0x0010 /* NOT defined by POSIX. */
|
||||
#define REG_NOSUB 0x0020
|
||||
#define REG_UTF8 0x0040 /* NOT defined by POSIX. */
|
||||
|
||||
/* This is not used by PCRE, but by defining it we make it easier
|
||||
to slot PCRE into existing programs that make POSIX calls. */
|
||||
|
||||
#define REG_EXTENDED 0
|
||||
|
||||
/* Error values. Not all these are relevant or used by the wrapper. */
|
||||
|
||||
enum {
|
||||
REG_ASSERT = 1, /* internal error ? */
|
||||
REG_BADBR, /* invalid repeat counts in {} */
|
||||
REG_BADPAT, /* pattern error */
|
||||
REG_BADRPT, /* ? * + invalid */
|
||||
REG_EBRACE, /* unbalanced {} */
|
||||
REG_EBRACK, /* unbalanced [] */
|
||||
REG_ECOLLATE, /* collation error - not relevant */
|
||||
REG_ECTYPE, /* bad class */
|
||||
REG_EESCAPE, /* bad escape sequence */
|
||||
REG_EMPTY, /* empty expression */
|
||||
REG_EPAREN, /* unbalanced () */
|
||||
REG_ERANGE, /* bad range inside [] */
|
||||
REG_ESIZE, /* expression too big */
|
||||
REG_ESPACE, /* failed to get memory */
|
||||
REG_ESUBREG, /* bad back reference */
|
||||
REG_INVARG, /* bad argument */
|
||||
REG_NOMATCH /* match failed */
|
||||
};
|
||||
|
||||
|
||||
/* The structure representing a compiled regular expression. */
|
||||
|
||||
typedef struct {
|
||||
void *re_pcre;
|
||||
size_t re_nsub;
|
||||
size_t re_erroffset;
|
||||
} regex_t;
|
||||
|
||||
/* The structure in which a captured offset is returned. */
|
||||
|
||||
typedef int regoff_t;
|
||||
|
||||
typedef struct {
|
||||
regoff_t rm_so;
|
||||
regoff_t rm_eo;
|
||||
} regmatch_t;
|
||||
|
||||
/* When an application links to a PCRE DLL in Windows, the symbols that are
|
||||
imported have to be identified as such. When building PCRE, the appropriate
|
||||
export settings are needed, and are set in pcreposix.c before including this
|
||||
file. */
|
||||
|
||||
#if defined(_WIN32) && !defined(PCRE_STATIC) && !defined(PCREPOSIX_EXP_DECL)
|
||||
# define PCREPOSIX_EXP_DECL extern __declspec(dllimport)
|
||||
# define PCREPOSIX_EXP_DEFN __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
/* By default, we use the standard "extern" declarations. */
|
||||
|
||||
#ifndef PCREPOSIX_EXP_DECL
|
||||
# ifdef __cplusplus
|
||||
# define PCREPOSIX_EXP_DECL extern "C"
|
||||
# define PCREPOSIX_EXP_DEFN extern "C"
|
||||
# else
|
||||
# define PCREPOSIX_EXP_DECL extern
|
||||
# define PCREPOSIX_EXP_DEFN extern
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* The functions */
|
||||
|
||||
PCREPOSIX_EXP_DECL int regcomp(regex_t *, const char *, int);
|
||||
PCREPOSIX_EXP_DECL int regexec(const regex_t *, const char *, size_t,
|
||||
regmatch_t *, int);
|
||||
PCREPOSIX_EXP_DECL size_t regerror(int, const regex_t *, char *, size_t);
|
||||
PCREPOSIX_EXP_DECL void regfree(regex_t *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* End of pcreposix.h */
|
@ -1,133 +0,0 @@
|
||||
/*************************************************
|
||||
* Unicode Property Table handler *
|
||||
*************************************************/
|
||||
|
||||
#ifndef _UCP_H
|
||||
#define _UCP_H
|
||||
|
||||
/* This file contains definitions of the property values that are returned by
|
||||
the function _pcre_ucp_findprop(). New values that are added for new releases
|
||||
of Unicode should always be at the end of each enum, for backwards
|
||||
compatibility. */
|
||||
|
||||
/* These are the general character categories. */
|
||||
|
||||
enum {
|
||||
ucp_C, /* Other */
|
||||
ucp_L, /* Letter */
|
||||
ucp_M, /* Mark */
|
||||
ucp_N, /* Number */
|
||||
ucp_P, /* Punctuation */
|
||||
ucp_S, /* Symbol */
|
||||
ucp_Z /* Separator */
|
||||
};
|
||||
|
||||
/* These are the particular character types. */
|
||||
|
||||
enum {
|
||||
ucp_Cc, /* Control */
|
||||
ucp_Cf, /* Format */
|
||||
ucp_Cn, /* Unassigned */
|
||||
ucp_Co, /* Private use */
|
||||
ucp_Cs, /* Surrogate */
|
||||
ucp_Ll, /* Lower case letter */
|
||||
ucp_Lm, /* Modifier letter */
|
||||
ucp_Lo, /* Other letter */
|
||||
ucp_Lt, /* Title case letter */
|
||||
ucp_Lu, /* Upper case letter */
|
||||
ucp_Mc, /* Spacing mark */
|
||||
ucp_Me, /* Enclosing mark */
|
||||
ucp_Mn, /* Non-spacing mark */
|
||||
ucp_Nd, /* Decimal number */
|
||||
ucp_Nl, /* Letter number */
|
||||
ucp_No, /* Other number */
|
||||
ucp_Pc, /* Connector punctuation */
|
||||
ucp_Pd, /* Dash punctuation */
|
||||
ucp_Pe, /* Close punctuation */
|
||||
ucp_Pf, /* Final punctuation */
|
||||
ucp_Pi, /* Initial punctuation */
|
||||
ucp_Po, /* Other punctuation */
|
||||
ucp_Ps, /* Open punctuation */
|
||||
ucp_Sc, /* Currency symbol */
|
||||
ucp_Sk, /* Modifier symbol */
|
||||
ucp_Sm, /* Mathematical symbol */
|
||||
ucp_So, /* Other symbol */
|
||||
ucp_Zl, /* Line separator */
|
||||
ucp_Zp, /* Paragraph separator */
|
||||
ucp_Zs /* Space separator */
|
||||
};
|
||||
|
||||
/* These are the script identifications. */
|
||||
|
||||
enum {
|
||||
ucp_Arabic,
|
||||
ucp_Armenian,
|
||||
ucp_Bengali,
|
||||
ucp_Bopomofo,
|
||||
ucp_Braille,
|
||||
ucp_Buginese,
|
||||
ucp_Buhid,
|
||||
ucp_Canadian_Aboriginal,
|
||||
ucp_Cherokee,
|
||||
ucp_Common,
|
||||
ucp_Coptic,
|
||||
ucp_Cypriot,
|
||||
ucp_Cyrillic,
|
||||
ucp_Deseret,
|
||||
ucp_Devanagari,
|
||||
ucp_Ethiopic,
|
||||
ucp_Georgian,
|
||||
ucp_Glagolitic,
|
||||
ucp_Gothic,
|
||||
ucp_Greek,
|
||||
ucp_Gujarati,
|
||||
ucp_Gurmukhi,
|
||||
ucp_Han,
|
||||
ucp_Hangul,
|
||||
ucp_Hanunoo,
|
||||
ucp_Hebrew,
|
||||
ucp_Hiragana,
|
||||
ucp_Inherited,
|
||||
ucp_Kannada,
|
||||
ucp_Katakana,
|
||||
ucp_Kharoshthi,
|
||||
ucp_Khmer,
|
||||
ucp_Lao,
|
||||
ucp_Latin,
|
||||
ucp_Limbu,
|
||||
ucp_Linear_B,
|
||||
ucp_Malayalam,
|
||||
ucp_Mongolian,
|
||||
ucp_Myanmar,
|
||||
ucp_New_Tai_Lue,
|
||||
ucp_Ogham,
|
||||
ucp_Old_Italic,
|
||||
ucp_Old_Persian,
|
||||
ucp_Oriya,
|
||||
ucp_Osmanya,
|
||||
ucp_Runic,
|
||||
ucp_Shavian,
|
||||
ucp_Sinhala,
|
||||
ucp_Syloti_Nagri,
|
||||
ucp_Syriac,
|
||||
ucp_Tagalog,
|
||||
ucp_Tagbanwa,
|
||||
ucp_Tai_Le,
|
||||
ucp_Tamil,
|
||||
ucp_Telugu,
|
||||
ucp_Thaana,
|
||||
ucp_Thai,
|
||||
ucp_Tibetan,
|
||||
ucp_Tifinagh,
|
||||
ucp_Ugaritic,
|
||||
ucp_Yi,
|
||||
ucp_Balinese, /* New for Unicode 5.0.0 */
|
||||
ucp_Cuneiform, /* New for Unicode 5.0.0 */
|
||||
ucp_Nko, /* New for Unicode 5.0.0 */
|
||||
ucp_Phags_Pa, /* New for Unicode 5.0.0 */
|
||||
ucp_Phoenician /* New for Unicode 5.0.0 */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* End of ucp.h */
|
@ -1,92 +0,0 @@
|
||||
/*************************************************
|
||||
* Unicode Property Table handler *
|
||||
*************************************************/
|
||||
|
||||
#ifndef _UCPINTERNAL_H
|
||||
#define _UCPINTERNAL_H
|
||||
|
||||
/* Internal header file defining the layout of the bits in each pair of 32-bit
|
||||
words that form a data item in the table. */
|
||||
|
||||
typedef struct cnode {
|
||||
pcre_uint32 f0;
|
||||
pcre_uint32 f1;
|
||||
} cnode;
|
||||
|
||||
/* Things for the f0 field */
|
||||
|
||||
#define f0_scriptmask 0xff000000 /* Mask for script field */
|
||||
#define f0_scriptshift 24 /* Shift for script value */
|
||||
#define f0_rangeflag 0x00f00000 /* Flag for a range item */
|
||||
#define f0_charmask 0x001fffff /* Mask for code point value */
|
||||
|
||||
/* Things for the f1 field */
|
||||
|
||||
#define f1_typemask 0xfc000000 /* Mask for char type field */
|
||||
#define f1_typeshift 26 /* Shift for the type field */
|
||||
#define f1_rangemask 0x0000ffff /* Mask for a range offset */
|
||||
#define f1_casemask 0x0000ffff /* Mask for a case offset */
|
||||
#define f1_caseneg 0xffff8000 /* Bits for negation */
|
||||
|
||||
/* The data consists of a vector of structures of type cnode. The two unsigned
|
||||
32-bit integers are used as follows:
|
||||
|
||||
(f0) (1) The most significant byte holds the script number. The numbers are
|
||||
defined by the enum in ucp.h.
|
||||
|
||||
(2) The 0x00800000 bit is set if this entry defines a range of characters.
|
||||
It is not set if this entry defines a single character
|
||||
|
||||
(3) The 0x00600000 bits are spare.
|
||||
|
||||
(4) The 0x001fffff bits contain the code point. No Unicode code point will
|
||||
ever be greater than 0x0010ffff, so this should be OK for ever.
|
||||
|
||||
(f1) (1) The 0xfc000000 bits contain the character type number. The numbers are
|
||||
defined by an enum in ucp.h.
|
||||
|
||||
(2) The 0x03ff0000 bits are spare.
|
||||
|
||||
(3) The 0x0000ffff bits contain EITHER the unsigned offset to the top of
|
||||
range if this entry defines a range, OR the *signed* offset to the
|
||||
character's "other case" partner if this entry defines a single
|
||||
character. There is no partner if the value is zero.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
| script (8) |.|.|.| codepoint (21) || type (6) |.|.| spare (8) | offset (16) |
|
||||
-------------------------------------------------------------------------------
|
||||
| | | | |
|
||||
| | |-> spare | |-> spare
|
||||
| | |
|
||||
| |-> spare |-> spare
|
||||
|
|
||||
|-> range flag
|
||||
|
||||
The upper/lower casing information is set only for characters that come in
|
||||
pairs. The non-one-to-one mappings in the Unicode data are ignored.
|
||||
|
||||
When searching the data, proceed as follows:
|
||||
|
||||
(1) Set up for a binary chop search.
|
||||
|
||||
(2) If the top is not greater than the bottom, the character is not in the
|
||||
table. Its type must therefore be "Cn" ("Undefined").
|
||||
|
||||
(3) Find the middle vector element.
|
||||
|
||||
(4) Extract the code point and compare. If equal, we are done.
|
||||
|
||||
(5) If the test character is smaller, set the top to the current point, and
|
||||
goto (2).
|
||||
|
||||
(6) If the current entry defines a range, compute the last character by adding
|
||||
the offset, and see if the test character is within the range. If it is,
|
||||
we are done.
|
||||
|
||||
(7) Otherwise, set the bottom to one element past the current point and goto
|
||||
(2).
|
||||
*/
|
||||
|
||||
#endif /* _UCPINTERNAL_H */
|
||||
|
||||
/* End of ucpinternal.h */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
include Makefile.var
|
@ -1,7 +0,0 @@
|
||||
all: $(BUILDDIR)pamauth$(DLSUFFICS)
|
||||
|
||||
pamauth$(OBJSUFFICS): pamauth.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) pamauth.c
|
||||
|
||||
$(BUILDDIR)pamauth$(DLSUFFICS): pamauth$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)../../$(BUILDDIR)pamauth$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) $(LIBSPREFIX)pam$(LIBSSUFFIX) pamauth$(OBJSUFFICS)
|
@ -1,30 +0,0 @@
|
||||
Плагин PAM авторизации для 3proxy (ОС *NIX)
|
||||
(c) Kirill Lopuchov lopuchov@mail.ru
|
||||
|
||||
|
||||
Описание
|
||||
Работает только на *NIX системах . Работоспособность проверялась на
|
||||
freebsd 5.2 и Linux Debian 4.
|
||||
|
||||
|
||||
Настройка PAM
|
||||
|
||||
Настраиваем PAM сервис для 3proxy на примере для Linux debian 4 , создаем файл
|
||||
/etc/pam.d/3proxy. Прописываем в нем следующую строку
|
||||
|
||||
@include common-auth
|
||||
Настройка плагина
|
||||
|
||||
----------------------------3proxy.cfg-------------------------------
|
||||
# start - имя процедуры инициализации плагина
|
||||
# 3proxy - имя сервиса PAM
|
||||
|
||||
plugin "pamauth.so" start 3proxy
|
||||
|
||||
# рекомендуется включать кеширование авторизации
|
||||
authcache user,password 60
|
||||
auth cache pam
|
||||
allow *
|
||||
proxy -p3128
|
||||
|
||||
----------------------------3proxy.cfg-------------------------------
|
@ -1,140 +0,0 @@
|
||||
/* plugin for 3proxy with PAM auth only for *NIX (linux,*bsd)
|
||||
Kirill Lopuchov <lopuchov@mail.ru>
|
||||
|
||||
Compile with: gcc -shared -o pamauth.so pamauth.c -lpam -DNOODBC
|
||||
*/
|
||||
|
||||
#include "../../structures.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
|
||||
|
||||
|
||||
static int already_loaded = 0;
|
||||
|
||||
static struct auth pamauth;
|
||||
#ifdef USERCASE
|
||||
static int usercaselow = 0;
|
||||
#endif
|
||||
static unsigned char *service=NULL;
|
||||
static struct pluginlink * pl;
|
||||
|
||||
|
||||
|
||||
|
||||
static char *password = NULL;
|
||||
|
||||
|
||||
static int password_conversation ( int num_msg, const struct pam_message **msg,
|
||||
struct pam_response **resp,
|
||||
void *appdata_ptr)
|
||||
{
|
||||
if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)
|
||||
{
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
if (!appdata_ptr) appdata_ptr = password;
|
||||
if (!appdata_ptr)
|
||||
{
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
*resp = calloc (num_msg, sizeof (struct pam_response));
|
||||
if (!*resp)
|
||||
{
|
||||
return PAM_CONV_ERR;
|
||||
}
|
||||
(*resp)[0].resp = strdup ((char *) appdata_ptr);
|
||||
(*resp)[0].resp_retcode = 0;
|
||||
return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
|
||||
}
|
||||
|
||||
#ifdef USERCASE
|
||||
static void lower (char *string)
|
||||
{
|
||||
int length, i;
|
||||
|
||||
length = strlen(string);
|
||||
for (i=0; i<length; i++)
|
||||
{
|
||||
string[i] = tolower(string[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* --------------------------------------------------------------------------*/
|
||||
static int pamfunc(struct clientparam *param)
|
||||
{
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retval;
|
||||
int rc=0;
|
||||
|
||||
struct pam_conv conv = {
|
||||
&password_conversation,
|
||||
NULL };
|
||||
|
||||
/* test proxy user auth ------------------------*/
|
||||
if(!param->username || !param->password) return 4;
|
||||
/*if(strlen(param->password)==0) return 4;*/
|
||||
|
||||
#ifdef USERCASE
|
||||
if (usercaselow > 0)
|
||||
{ lower(param->username); }
|
||||
#endif
|
||||
|
||||
/*start process auth */
|
||||
conv.appdata_ptr = (char *) param->password;
|
||||
|
||||
if (!pamh)
|
||||
{
|
||||
retval = pam_start ((char *)service, "3proxy@" , &conv, &pamh);
|
||||
}
|
||||
if (retval == PAM_SUCCESS)
|
||||
retval = pam_set_item (pamh, PAM_USER, param->username);
|
||||
/*fprintf(stderr,"pam_set_item1 rc=%d\n",retval);*/
|
||||
if (retval == PAM_SUCCESS)
|
||||
retval = pam_set_item (pamh, PAM_CONV, &conv);
|
||||
/*fprintf(stderr,"pam_set_item2 rc=%d\n",retval); */
|
||||
if (retval == PAM_SUCCESS)
|
||||
retval = pam_authenticate (pamh, 0);
|
||||
/*fprintf(stderr,"pam_authenticate rc=%d\n",retval);*/
|
||||
|
||||
if (retval == PAM_SUCCESS) { /*auth OK*/ rc=0; }
|
||||
else { /*auth ERR*/ rc=5; }
|
||||
|
||||
if (pamh)
|
||||
retval = pam_end (pamh, retval);
|
||||
if (retval != PAM_SUCCESS)
|
||||
{ pamh = NULL; }
|
||||
|
||||
return rc;
|
||||
|
||||
}
|
||||
|
||||
/*------------------------------- MAIN --------------------------------------
|
||||
start plugin init */
|
||||
int start(struct pluginlink * pluginlink, int argc, unsigned char** argv)
|
||||
{
|
||||
|
||||
|
||||
if(argc < 2) return 1;
|
||||
pl = pluginlink;
|
||||
if(service) pl->myfree(service);
|
||||
service=(unsigned char *)pl->mystrdup((char *)argv[1]);
|
||||
|
||||
if (already_loaded) { return (0); }
|
||||
|
||||
already_loaded = 1;
|
||||
|
||||
pamauth.authenticate = pamfunc;
|
||||
pamauth.authorize = pluginlink->checkACL;
|
||||
pamauth.desc = "pam";
|
||||
pamauth.next = pluginlink->authfuncs->next;
|
||||
pluginlink->authfuncs->next = &pamauth;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1 +0,0 @@
|
||||
include Makefile.var
|
@ -1,14 +0,0 @@
|
||||
all: $(BUILDDIR)SSLPlugin$(DLSUFFICS)
|
||||
|
||||
|
||||
|
||||
ssl_plugin$(OBJSUFFICS): ssl_plugin.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) ssl_plugin.c
|
||||
|
||||
my_ssl$(OBJSUFFICS): my_ssl.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) my_ssl.c
|
||||
|
||||
|
||||
$(BUILDDIR)SSLPlugin$(DLSUFFICS): ssl_plugin$(OBJSUFFICS) my_ssl$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)../../$(BUILDDIR)SSLPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) ssl_plugin$(OBJSUFFICS) my_ssl$(OBJSUFFICS) $(LIBS)
|
||||
|
@ -1,474 +0,0 @@
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include "../../structures.h"
|
||||
#include <memory.h>
|
||||
#include <fcntl.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#include "../../proxy.h"
|
||||
#include "my_ssl.h"
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct _ssl_conn {
|
||||
SSL_CTX *ctx;
|
||||
SSL *ssl;
|
||||
} ssl_conn;
|
||||
|
||||
static X509 *CA_cert = NULL;
|
||||
static EVP_PKEY *CA_key = NULL;
|
||||
static EVP_PKEY *server_key = NULL;
|
||||
static X509_NAME *name = NULL;
|
||||
|
||||
pthread_mutex_t ssl_file_mutex;
|
||||
|
||||
|
||||
static char errbuf[256];
|
||||
|
||||
static char hexMap[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||
};
|
||||
|
||||
static BIO *bio_err=NULL;
|
||||
|
||||
|
||||
static size_t bin2hex (const unsigned char* bin, size_t bin_length, char* str, size_t str_length)
|
||||
{
|
||||
char *p;
|
||||
size_t i;
|
||||
|
||||
if ( str_length < ( bin_length+1) )
|
||||
return 0;
|
||||
|
||||
p = str;
|
||||
for ( i=0; i < bin_length; ++i )
|
||||
{
|
||||
*p++ = hexMap[*bin >> 4];
|
||||
*p++ = hexMap[*bin & 0xf];
|
||||
++bin;
|
||||
}
|
||||
|
||||
*p = 0;
|
||||
|
||||
return p - str;
|
||||
}
|
||||
|
||||
static int add_ext(X509 *cert, int nid, char *value)
|
||||
{
|
||||
X509_EXTENSION *ex;
|
||||
X509V3_CTX ctx;
|
||||
/* This sets the 'context' of the extensions. */
|
||||
/* No configuration database */
|
||||
X509V3_set_ctx_nodb(&ctx);
|
||||
/* Issuer and subject certs: both the target since it is self signed,
|
||||
* no request and no CRL
|
||||
*/
|
||||
X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
|
||||
ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
|
||||
if (!ex)
|
||||
return 0;
|
||||
|
||||
X509_add_ext(cert,ex,-1);
|
||||
X509_EXTENSION_free(ex);
|
||||
return 1;
|
||||
}
|
||||
|
||||
extern char *cert_path;
|
||||
|
||||
void del_ext(X509 *dst_cert, int nid, int where){
|
||||
int ex;
|
||||
|
||||
ex = X509_get_ext_by_NID(dst_cert, nid, where);
|
||||
if(ex>=0){
|
||||
X509_EXTENSION *ext;
|
||||
if((ext = X509_delete_ext(dst_cert, ex))) X509_EXTENSION_free(ext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SSL_CERT ssl_copy_cert(SSL_CERT cert)
|
||||
{
|
||||
int err = -1;
|
||||
FILE *fcache;
|
||||
X509 *src_cert = (X509 *) cert;
|
||||
X509 *dst_cert = NULL;
|
||||
|
||||
EVP_PKEY *pk = NULL;
|
||||
RSA *rsa = NULL;
|
||||
|
||||
unsigned char p1[] = "RU";
|
||||
unsigned char p2[] = "3proxy";
|
||||
unsigned char p3[] = "3proxy CA";
|
||||
|
||||
static char hash_name[sizeof(src_cert->sha1_hash)*2 + 1];
|
||||
static char cache_name[200];
|
||||
|
||||
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);
|
||||
/* check if certificate is already cached */
|
||||
fcache = fopen(cache_name, "rb");
|
||||
if ( fcache != NULL ) {
|
||||
#ifndef _WIN32
|
||||
flock(fileno(fcache), LOCK_SH);
|
||||
#endif
|
||||
dst_cert = PEM_read_X509(fcache, &dst_cert, NULL, NULL);
|
||||
#ifndef _WIN32
|
||||
flock(fileno(fcache), LOCK_UN);
|
||||
#endif
|
||||
fclose(fcache);
|
||||
if ( dst_cert != NULL ){
|
||||
return dst_cert;
|
||||
}
|
||||
}
|
||||
|
||||
/* proceed if certificate is not cached */
|
||||
dst_cert = X509_dup(src_cert);
|
||||
if ( dst_cert == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
del_ext(dst_cert, NID_crl_distribution_points, -1);
|
||||
del_ext(dst_cert, NID_info_access, -1);
|
||||
del_ext(dst_cert, NID_authority_key_identifier, -1);
|
||||
del_ext(dst_cert, NID_certificate_policies, 0);
|
||||
|
||||
err = X509_set_pubkey(dst_cert, server_key);
|
||||
if ( err == 0 ) {
|
||||
X509_free(dst_cert);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Its self signed so set the issuer name to be the same as the
|
||||
* subject.
|
||||
*/
|
||||
err = X509_set_issuer_name(dst_cert, name);
|
||||
if(!err){
|
||||
X509_free(dst_cert);
|
||||
return NULL;
|
||||
}
|
||||
err = X509_digest(dst_cert, EVP_sha1(), dst_cert->sha1_hash, NULL);
|
||||
if(!err){
|
||||
X509_free(dst_cert);
|
||||
return NULL;
|
||||
}
|
||||
err = X509_sign(dst_cert, CA_key, EVP_sha1());
|
||||
if(!err){
|
||||
X509_free(dst_cert);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* write to cache */
|
||||
|
||||
fcache = fopen(cache_name, "wb");
|
||||
if ( fcache != NULL ) {
|
||||
#ifndef _WIN32
|
||||
flock(fileno(fcache), LOCK_EX);
|
||||
#endif
|
||||
PEM_write_X509(fcache, dst_cert);
|
||||
#ifndef _WIN32
|
||||
flock(fileno(fcache), LOCK_UN);
|
||||
#endif
|
||||
fclose(fcache);
|
||||
}
|
||||
return dst_cert;
|
||||
}
|
||||
|
||||
|
||||
SSL_CONN ssl_handshake_to_server(SOCKET s, char * hostname, SSL_CERT *server_cert, char **errSSL)
|
||||
{
|
||||
int err = 0;
|
||||
X509 *cert;
|
||||
ssl_conn *conn;
|
||||
|
||||
*errSSL = NULL;
|
||||
|
||||
conn = (ssl_conn *)malloc(sizeof(ssl_conn));
|
||||
if ( conn == NULL ){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn->ctx = SSL_CTX_new(SSLv23_client_method());
|
||||
if ( conn->ctx == NULL ) {
|
||||
free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn->ssl = SSL_new(conn->ctx);
|
||||
if ( conn->ssl == NULL ) {
|
||||
SSL_CTX_free(conn->ctx);
|
||||
free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!SSL_set_fd(conn->ssl, s)){
|
||||
ssl_conn_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
if(hostname && *hostname)SSL_set_tlsext_host_name(conn->ssl, hostname);
|
||||
err = SSL_connect(conn->ssl);
|
||||
if ( err == -1 ) {
|
||||
*errSSL = ERR_error_string(ERR_get_error(), errbuf);
|
||||
ssl_conn_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cert = SSL_get_peer_certificate(conn->ssl);
|
||||
if(!cert) {
|
||||
ssl_conn_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO: Verify certificate */
|
||||
|
||||
*server_cert = cert;
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
SSL_CONN ssl_handshake_to_client(SOCKET s, SSL_CERT server_cert, char** errSSL)
|
||||
{
|
||||
int err = 0;
|
||||
X509 *cert;
|
||||
ssl_conn *conn;
|
||||
|
||||
*errSSL = NULL;
|
||||
|
||||
conn = (ssl_conn *)malloc(sizeof(ssl_conn));
|
||||
if ( conn == NULL )
|
||||
return NULL;
|
||||
|
||||
conn->ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
if ( conn->ctx == NULL ) {
|
||||
free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = SSL_CTX_use_certificate(conn->ctx, (X509 *) server_cert);
|
||||
if ( err <= 0 ) {
|
||||
SSL_CTX_free(conn->ctx);
|
||||
free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err = SSL_CTX_use_PrivateKey(conn->ctx, server_key);
|
||||
if ( err <= 0 ) {
|
||||
SSL_CTX_free(conn->ctx);
|
||||
free(conn);
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
err = SSL_CTX_load_verify_locations(conn->ctx, "3proxy.pem",
|
||||
NULL);
|
||||
if ( err <= 0 ) {
|
||||
SSL_CTX_free(conn->ctx);
|
||||
free(conn);
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
conn->ssl = SSL_new(conn->ctx);
|
||||
if ( conn->ssl == NULL ) {
|
||||
SSL_CTX_free(conn->ctx);
|
||||
free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSL_set_fd(conn->ssl, (int)s);
|
||||
err = SSL_accept(conn->ssl);
|
||||
if ( err <= 0 ) {
|
||||
*errSSL = ERR_error_string(ERR_get_error(), errbuf);
|
||||
ssl_conn_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// client certificate
|
||||
// TODO: is it required?
|
||||
//
|
||||
cert = SSL_get_peer_certificate(conn->ssl);
|
||||
|
||||
if ( cert != NULL )
|
||||
X509_free(cert);
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
int ssl_read(SSL_CONN connection, void * buf, int bufsize)
|
||||
{
|
||||
ssl_conn *conn = (ssl_conn *) connection;
|
||||
|
||||
return SSL_read(conn->ssl, buf, bufsize);
|
||||
}
|
||||
|
||||
int ssl_write(SSL_CONN connection, void * buf, int bufsize)
|
||||
{
|
||||
ssl_conn *conn = (ssl_conn *) connection;
|
||||
|
||||
return SSL_write(conn->ssl, buf, bufsize);
|
||||
}
|
||||
int ssl_pending(SSL_CONN connection)
|
||||
{
|
||||
ssl_conn *conn = (ssl_conn *) connection;
|
||||
|
||||
return SSL_pending(conn->ssl);
|
||||
}
|
||||
|
||||
void ssl_conn_free(SSL_CONN connection)
|
||||
{
|
||||
ssl_conn *conn = (ssl_conn *) connection;
|
||||
|
||||
if(conn){
|
||||
if(conn->ssl){
|
||||
SSL_shutdown(conn->ssl);
|
||||
SSL_free(conn->ssl);
|
||||
}
|
||||
if(conn->ctx) SSL_CTX_free(conn->ctx);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
|
||||
void _ssl_cert_free(SSL_CERT cert)
|
||||
{
|
||||
X509_free((X509 *)cert);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* This array will store all of the mutexes available to OpenSSL. */
|
||||
static pthread_mutex_t *mutex_buf= NULL;
|
||||
|
||||
|
||||
static void locking_function(int mode, int n, const char * file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
pthread_mutex_lock(mutex_buf + n);
|
||||
else
|
||||
pthread_mutex_unlock(mutex_buf + n);
|
||||
}
|
||||
|
||||
static unsigned long id_function(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return ((unsigned long)GetCurrentThreadId());
|
||||
#else
|
||||
return ((unsigned long)pthread_self());
|
||||
#endif
|
||||
}
|
||||
|
||||
int thread_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mutex_buf = malloc(CRYPTO_num_locks( ) * sizeof(pthread_mutex_t));
|
||||
if (!mutex_buf)
|
||||
return 0;
|
||||
for (i = 0; i < CRYPTO_num_locks( ); i++)
|
||||
pthread_mutex_init(mutex_buf +i, NULL);
|
||||
CRYPTO_set_id_callback(id_function);
|
||||
CRYPTO_set_locking_callback(locking_function);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int thread_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!mutex_buf)
|
||||
return 0;
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
for (i = 0; i < CRYPTO_num_locks( ); i++)
|
||||
pthread_mutex_destroy(mutex_buf +i);
|
||||
free(mutex_buf);
|
||||
mutex_buf = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ssl_file_init = 0;
|
||||
|
||||
|
||||
void ssl_init(void)
|
||||
{
|
||||
FILE *f;
|
||||
static char fname[200];
|
||||
|
||||
if(!ssl_file_init++)pthread_mutex_init(&ssl_file_mutex, NULL);
|
||||
|
||||
pthread_mutex_lock(&ssl_file_mutex);
|
||||
thread_setup();
|
||||
|
||||
SSLeay_add_ssl_algorithms();
|
||||
SSL_load_error_strings();
|
||||
|
||||
sprintf(fname, "%.128s3proxy.pem", cert_path);
|
||||
f = fopen(fname, "r");
|
||||
if ( f != NULL ) {
|
||||
PEM_read_X509(f, &CA_cert, NULL, NULL);
|
||||
fclose(f);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "failed to open: %s\n", fname);
|
||||
}
|
||||
name = X509_get_subject_name(CA_cert);
|
||||
|
||||
sprintf(fname, "%.128s3proxy.key", cert_path);
|
||||
f = fopen(fname, "rb");
|
||||
if ( f != NULL ) {
|
||||
CA_key = PEM_read_PrivateKey(f, &CA_key, NULL, NULL);
|
||||
fclose(f);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "failed to open: %s\n", fname);
|
||||
}
|
||||
|
||||
sprintf(fname, "%.128sserver.key", cert_path);
|
||||
f = fopen(fname, "rb");
|
||||
if ( f != NULL ) {
|
||||
server_key = PEM_read_PrivateKey(f, &server_key, NULL, NULL);
|
||||
fclose(f);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "failed to open: %s\n", fname);
|
||||
}
|
||||
if(!CA_cert || !CA_key || !server_key){
|
||||
fprintf(stderr, "failed to init SSL certificate / keys\n");
|
||||
}
|
||||
|
||||
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
|
||||
pthread_mutex_unlock(&ssl_file_mutex);
|
||||
}
|
||||
|
||||
void ssl_release(void)
|
||||
{
|
||||
pthread_mutex_lock(&ssl_file_mutex);
|
||||
if ( CA_cert != NULL ) {
|
||||
X509_free(CA_cert);
|
||||
CA_cert = NULL;
|
||||
}
|
||||
|
||||
if ( CA_key != NULL ) {
|
||||
EVP_PKEY_free(CA_key);
|
||||
CA_key = NULL;
|
||||
}
|
||||
|
||||
if ( server_key != NULL ) {
|
||||
EVP_PKEY_free(server_key);
|
||||
server_key = NULL;
|
||||
}
|
||||
thread_cleanup();
|
||||
pthread_mutex_unlock(&ssl_file_mutex);
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
#ifndef __my_ssl_h__
|
||||
#define __my_ssl_h__
|
||||
|
||||
//
|
||||
// opaque connection structure
|
||||
//
|
||||
typedef void *SSL_CONN;
|
||||
//
|
||||
// opaque certificate structure
|
||||
//
|
||||
typedef void *SSL_CERT;
|
||||
|
||||
//
|
||||
// Create copy of certificate signed by "other" CA
|
||||
//
|
||||
SSL_CERT ssl_copy_cert(SSL_CERT cert);
|
||||
|
||||
//
|
||||
// SSL/TLS handshakes
|
||||
//
|
||||
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/TLS Read/Write
|
||||
//
|
||||
int ssl_read(SSL_CONN connection, void * buf, int bufsize);
|
||||
int ssl_write(SSL_CONN connection, void * buf, int bufsize);
|
||||
int ssl_pending(SSL_CONN connection);
|
||||
|
||||
//
|
||||
// Release of opaque structures
|
||||
//
|
||||
void ssl_conn_free(SSL_CONN connection);
|
||||
void _ssl_cert_free(SSL_CERT cert);
|
||||
|
||||
//
|
||||
// Global (de)initialization
|
||||
//
|
||||
void ssl_init(void);
|
||||
void ssl_release(void);
|
||||
|
||||
#endif // __my_ssl_h__
|
@ -1,414 +0,0 @@
|
||||
/*
|
||||
3APA3A simpliest proxy server
|
||||
(c) 2007-2008 by ZARAZA <3APA3A@security.nnov.ru>
|
||||
|
||||
please read License Agreement
|
||||
|
||||
*/
|
||||
|
||||
#include "../../structures.h"
|
||||
#include <openssl/rsa.h> /* SSLeay stuff */
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include "../../proxy.h"
|
||||
#include "my_ssl.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#define WINAPI
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef isnumber
|
||||
#define isnumber(i_n_arg) ((i_n_arg>='0')&&(i_n_arg<='9'))
|
||||
#endif
|
||||
|
||||
PROXYFUNC tcppmfunc, proxyfunc, smtppfunc, ftpprfunc;
|
||||
|
||||
static struct pluginlink * pl;
|
||||
|
||||
pthread_mutex_t ssl_mutex;
|
||||
|
||||
static int ssl_loaded = 0;
|
||||
static int ssl_connect_timeout = 0;
|
||||
char *cert_path = "";
|
||||
|
||||
typedef struct _ssl_conn {
|
||||
struct SSL_CTX *ctx;
|
||||
struct SSL *ssl;
|
||||
} ssl_conn;
|
||||
|
||||
struct SSLqueue {
|
||||
struct SSLqueue *next;
|
||||
SOCKET s;
|
||||
SSL_CERT cert;
|
||||
SSL_CONN conn;
|
||||
struct clientparam* param;
|
||||
} *SSLq = NULL;
|
||||
|
||||
|
||||
/*
|
||||
TO DO: use hashtable
|
||||
*/
|
||||
static struct SSLqueue *searchSSL(SOCKET s){
|
||||
struct SSLqueue *sslq = NULL;
|
||||
pthread_mutex_lock(&ssl_mutex);
|
||||
for(sslq = SSLq; sslq; sslq = sslq->next)
|
||||
if(sslq->s == s) break;
|
||||
pthread_mutex_unlock(&ssl_mutex);
|
||||
return sslq;
|
||||
}
|
||||
|
||||
static void addSSL(SOCKET s, SSL_CERT cert, SSL_CONN conn, struct clientparam* param){
|
||||
struct SSLqueue *sslq;
|
||||
sslq = (struct SSLqueue *) malloc(sizeof(struct SSLqueue));
|
||||
sslq->s = s;
|
||||
sslq->cert = cert;
|
||||
sslq->conn = conn;
|
||||
pthread_mutex_lock(&ssl_mutex);
|
||||
sslq->next = SSLq;
|
||||
sslq->param = param;
|
||||
SSLq = sslq;
|
||||
pthread_mutex_unlock(&ssl_mutex);
|
||||
}
|
||||
|
||||
int delSSL(SOCKET s){
|
||||
struct SSLqueue *sqi, *sqt = NULL;
|
||||
if(!SSLq) return 0;
|
||||
pthread_mutex_lock(&ssl_mutex);
|
||||
if(SSLq){
|
||||
if(SSLq->s == s){
|
||||
sqt = SSLq;
|
||||
SSLq = SSLq->next;
|
||||
}
|
||||
else for(sqi = SSLq; sqi->next; sqi = sqi->next){
|
||||
if (sqi->next->s == s){
|
||||
sqt = sqi->next;
|
||||
sqi->next = sqt->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&ssl_mutex);
|
||||
if(sqt) {
|
||||
_ssl_cert_free(sqt->cert);
|
||||
ssl_conn_free(sqt->conn);
|
||||
free(sqt);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sockfuncs sso;
|
||||
|
||||
#ifdef _WIN32
|
||||
static int WINAPI ssl_send(SOCKET s, const void *msg, int len, int flags){
|
||||
#else
|
||||
static int ssl_send(SOCKET s, const void *msg, size_t len, int flags){
|
||||
#endif
|
||||
struct SSLqueue *sslq;
|
||||
|
||||
if ((sslq = searchSSL(s))){
|
||||
int i=0, res, err;
|
||||
do {
|
||||
if((res = ssl_write(sslq->conn, (void *)msg, len)) < 0) {
|
||||
err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
|
||||
usleep(10*SLEEPTIME);
|
||||
}
|
||||
} while (res < 0 && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) && ++i < 100);
|
||||
return res;
|
||||
}
|
||||
|
||||
return sso._send(s, msg, len, flags);
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
static int WINAPI ssl_sendto(SOCKET s, const void *msg, int len, int flags, const struct sockaddr *to, int tolen){
|
||||
#else
|
||||
static int ssl_sendto(SOCKET s, const void *msg, size_t len, int flags, const struct sockaddr *to, SASIZETYPE tolen){
|
||||
#endif
|
||||
struct SSLqueue *sslq;
|
||||
|
||||
if ((sslq = searchSSL(s))){
|
||||
int i=0, res, err;
|
||||
do {
|
||||
if((res = ssl_write(sslq->conn, (void *)msg, len)) < 0) {
|
||||
err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
|
||||
usleep(10*SLEEPTIME);
|
||||
}
|
||||
} while (res < 0 && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) && ++i < 100);
|
||||
return res;
|
||||
}
|
||||
|
||||
return sso._sendto(s, msg, len, flags, to, tolen);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static int WINAPI ssl_recvfrom(SOCKET s, void *msg, int len, int flags, struct sockaddr *from, int *fromlen){
|
||||
#else
|
||||
static int ssl_recvfrom(SOCKET s, void *msg, size_t len, int flags, struct sockaddr *from, SASIZETYPE *fromlen){
|
||||
#endif
|
||||
struct SSLqueue *sslq;
|
||||
|
||||
if ((sslq = searchSSL(s))){
|
||||
int i=0, res, err;
|
||||
do {
|
||||
if((res = ssl_read(sslq->conn, (void *)msg, len)) < 0) {
|
||||
err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
|
||||
usleep(10*SLEEPTIME);
|
||||
}
|
||||
} while (res < 0 && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) && ++i < 100);
|
||||
return res;
|
||||
}
|
||||
|
||||
return sso._recvfrom(s, msg, len, flags, from, fromlen);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
static int WINAPI ssl_recv(SOCKET s, void *msg, int len, int flags){
|
||||
#else
|
||||
static int WINAPI ssl_recv(SOCKET s, void *msg, size_t len, int flags){
|
||||
#endif
|
||||
struct SSLqueue *sslq;
|
||||
|
||||
if ((sslq = searchSSL(s))){
|
||||
int i=0, res, err;
|
||||
do {
|
||||
if((res = ssl_read(sslq->conn, (void *)msg, len)) < 0) {
|
||||
err = SSL_get_error((SSL *)((ssl_conn*)sslq->conn)->ssl, res);
|
||||
usleep(10*SLEEPTIME);
|
||||
}
|
||||
} while (res < 0 && (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) && ++i < 100);
|
||||
return res;
|
||||
}
|
||||
|
||||
return sso._recv(s, msg, len, flags);
|
||||
}
|
||||
|
||||
static int WINAPI ssl_closesocket(SOCKET s){
|
||||
delSSL(s);
|
||||
return sso._closesocket(s);
|
||||
}
|
||||
|
||||
static int WINAPI ssl_poll(struct pollfd *fds, unsigned int nfds, int timeout){
|
||||
struct SSLqueue *sslq = NULL;
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
for(i = 0; i < nfds; i++){
|
||||
if((fds[i].events & POLLIN) && (sslq = searchSSL(fds[i].fd)) && ssl_pending(sslq->conn)){
|
||||
fds[i].revents = POLLIN;
|
||||
ret++;
|
||||
}
|
||||
else fds[i].revents = 0;
|
||||
}
|
||||
if(ret) return ret;
|
||||
|
||||
ret = sso._poll(fds, nfds, timeout);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int dossl(struct clientparam* param, SSL_CONN* ServerConnp, SSL_CONN* ClientConnp){
|
||||
SSL_CERT ServerCert=NULL, FakeCert=NULL;
|
||||
SSL_CONN ServerConn, ClientConn;
|
||||
char *errSSL=NULL;
|
||||
unsigned long ul;
|
||||
|
||||
#ifdef _WIN32
|
||||
ul = 0;
|
||||
ioctlsocket(param->remsock, FIONBIO, &ul);
|
||||
ul = 0;
|
||||
ioctlsocket(param->clisock, FIONBIO, &ul);
|
||||
#else
|
||||
fcntl(param->remsock,F_SETFL,0);
|
||||
fcntl(param->clisock,F_SETFL,0);
|
||||
#endif
|
||||
|
||||
if(ssl_connect_timeout){
|
||||
ul = ((unsigned long)ssl_connect_timeout)*1000;
|
||||
setsockopt(param->remsock, SOL_SOCKET, SO_RCVTIMEO, (char *)&ul, 4);
|
||||
ul = ((unsigned long)ssl_connect_timeout)*1000;
|
||||
setsockopt(param->remsock, SOL_SOCKET, SO_SNDTIMEO, (char *)&ul, 4);
|
||||
}
|
||||
ServerConn = ssl_handshake_to_server(param->remsock, (char *)param->hostname, &ServerCert, &errSSL);
|
||||
if ( ServerConn == NULL || ServerCert == NULL ) {
|
||||
param->res = 8011;
|
||||
param->srv->logfunc(param, (unsigned char *)"SSL handshake to server failed");
|
||||
if(ServerConn == NULL) param->srv->logfunc(param, (unsigned char *)"ServerConn is NULL");
|
||||
if(ServerCert == NULL) param->srv->logfunc(param, (unsigned char *)"ServerCert is NULL");
|
||||
if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL);
|
||||
return 1;
|
||||
}
|
||||
FakeCert = ssl_copy_cert(ServerCert);
|
||||
if ( FakeCert == NULL ) {
|
||||
param->res = 8012;
|
||||
_ssl_cert_free(ServerCert);
|
||||
param->srv->logfunc(param, (unsigned char *)"Failed to create certificate copy");
|
||||
ssl_conn_free(ServerConn);
|
||||
return 2;
|
||||
}
|
||||
ClientConn = ssl_handshake_to_client(param->clisock, FakeCert, &errSSL);
|
||||
if ( ClientConn == NULL ) {
|
||||
param->res = 8012;
|
||||
param->srv->logfunc(param, (unsigned char *)"Handshake to client failed");
|
||||
if(errSSL)param->srv->logfunc(param, (unsigned char *)errSSL);
|
||||
_ssl_cert_free(ServerCert);
|
||||
_ssl_cert_free(FakeCert);
|
||||
ssl_conn_free(ServerConn);
|
||||
return 3;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
ul = 1;
|
||||
ioctlsocket(param->remsock, FIONBIO, &ul);
|
||||
ul = 1;
|
||||
ioctlsocket(param->clisock, FIONBIO, &ul);
|
||||
#else
|
||||
fcntl(param->remsock,F_SETFL,O_NONBLOCK);
|
||||
fcntl(param->clisock,F_SETFL,O_NONBLOCK);
|
||||
#endif
|
||||
|
||||
|
||||
SSL_set_mode((SSL *)((ssl_conn *)ServerConn)->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_AUTO_RETRY);
|
||||
SSL_set_mode((SSL *)((ssl_conn *)ClientConn)->ssl, SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_AUTO_RETRY);
|
||||
SSL_set_read_ahead((SSL *)((ssl_conn *)ServerConn)->ssl, 0);
|
||||
SSL_set_read_ahead((SSL *)((ssl_conn *)ClientConn)->ssl, 0);
|
||||
addSSL(param->remsock, ServerCert, ServerConn, param);
|
||||
addSSL(param->clisock, FakeCert, ClientConn, param);
|
||||
if(ServerConnp)*ServerConnp = ServerConn;
|
||||
if(ClientConnp)*ClientConnp = ClientConn;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void* ssl_filter_open(void * idata, struct srvparam * param){
|
||||
return idata;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static FILTER_ACTION ssl_filter_client(void *fo, struct clientparam * param, void** fc){
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
static FILTER_ACTION ssl_filter_predata(void *fo, struct clientparam * param){
|
||||
if(param->operation != HTTP_CONNECT) return PASS;
|
||||
if(dossl(param, NULL, NULL)) {
|
||||
return REJECT;
|
||||
}
|
||||
param->redirectfunc = proxyfunc;
|
||||
return HANDLED;
|
||||
}
|
||||
|
||||
|
||||
static void ssl_filter_clear(void *fo){
|
||||
}
|
||||
|
||||
static void ssl_filter_close(void *fo){
|
||||
}
|
||||
|
||||
static struct filter ssl_filter = {
|
||||
NULL,
|
||||
"ssl filter",
|
||||
"ssl filter",
|
||||
ssl_filter_open,
|
||||
ssl_filter_client,
|
||||
NULL, NULL, NULL, ssl_filter_predata, NULL, NULL,
|
||||
ssl_filter_clear,
|
||||
ssl_filter_close
|
||||
};
|
||||
|
||||
int mitm = 0;
|
||||
int ssl_inited = 0;
|
||||
|
||||
static int h_mitm(int argc, unsigned char **argv){
|
||||
if(!ssl_inited) {
|
||||
ssl_init();
|
||||
ssl_inited = 1;
|
||||
}
|
||||
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
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
|
||||
int ssl_plugin (struct pluginlink * pluginlink,
|
||||
int argc, char** argv){
|
||||
pl = pluginlink;
|
||||
if(!ssl_loaded){
|
||||
ssl_loaded = 1;
|
||||
pthread_mutex_init(&ssl_mutex, NULL);
|
||||
memcpy(&sso, pl->so, sizeof(struct sockfuncs));
|
||||
pl->so->_send = ssl_send;
|
||||
pl->so->_recv = ssl_recv;
|
||||
pl->so->_sendto = ssl_sendto;
|
||||
pl->so->_recvfrom = ssl_recvfrom;
|
||||
pl->so->_closesocket = ssl_closesocket;
|
||||
pl->so->_poll = ssl_poll;
|
||||
ssl_commandhandlers[2].next = pl->commandhandlers->next;
|
||||
pl->commandhandlers->next = ssl_commandhandlers;
|
||||
}
|
||||
else {
|
||||
ssl_release();
|
||||
ssl_inited = 0;
|
||||
}
|
||||
|
||||
tcppmfunc = (PROXYFUNC)pl->findbyname("tcppm");
|
||||
if(!tcppmfunc){return 13;}
|
||||
proxyfunc = (PROXYFUNC)pl->findbyname("proxy");
|
||||
if(!proxyfunc)proxyfunc = tcppmfunc;
|
||||
smtppfunc = (PROXYFUNC)pl->findbyname("smtpp");
|
||||
if(!smtppfunc)smtppfunc = tcppmfunc;
|
||||
ftpprfunc = (PROXYFUNC)pl->findbyname("ftppr");
|
||||
if(!ftpprfunc)ftpprfunc = tcppmfunc;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1 +0,0 @@
|
||||
include Makefile.var
|
@ -1,7 +0,0 @@
|
||||
all: $(BUILDDIR)StringsPlugin$(DLSUFFICS)
|
||||
|
||||
StringsPlugin$(OBJSUFFICS): StringsPlugin.c
|
||||
$(CC) $(DCFLAGS) $(CFLAGS) StringsPlugin.c
|
||||
|
||||
$(BUILDDIR)StringsPlugin$(DLSUFFICS): StringsPlugin$(OBJSUFFICS)
|
||||
$(LN) $(LNOUT)../../$(BUILDDIR)StringsPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) StringsPlugin$(OBJSUFFICS)
|
@ -1,63 +0,0 @@
|
||||
-------------------------windows-1251------------------------
|
||||
Плагин подменяющий строки в сервере 3proxу (ОС windows,unix)
|
||||
(c) Lopuchov Kirill lopuchov@mail.ru
|
||||
|
||||
1. Краткое описание описание
|
||||
|
||||
Используется для руссификации сообщений выдаваемых 3proxy.
|
||||
Для корректной работы требуется последняя 0.6 версия 3proxy (в интерфейсе
|
||||
plugin api которой появился job schedule ). Все сообщения были взяты из
|
||||
дистрибутива 3proxy и вынесенны в отдельный файл. Пример файла rus-win1251.3ps.
|
||||
Для каждого сервиса существуют свои блоки сообщений. Начало и конец блока
|
||||
разделены , на пример для сервиса ADMIN начало "[--admin--]" конец [/--admin--].
|
||||
Сами сообщения отделены между собой строкой "[end]", новая строка определяется
|
||||
строкой "\n" .
|
||||
От версии к версии количество сообщений в 3proxy может менятся.
|
||||
В этом случае необходимо либо добавить самостоятельно новые строки в
|
||||
соответсвеющие блоки rus-win1251.3ps, или ждать обновления :)
|
||||
|
||||
|
||||
Для компиляции и тестирования под ОС Windows использовался пакет Dev-C++
|
||||
http://www.bloodshed.net/dev/
|
||||
Для компиляции и тестирования под unix подобными использовался gcc
|
||||
|
||||
|
||||
Настройка 3proxy
|
||||
---------------------
|
||||
|
||||
plugin "string.dll" start c:\3proxy\rus-win1251.3ps
|
||||
|
||||
-------------------------windows-1251------------------------
|
||||
|
||||
---------------------------KOI8-R---------------------------
|
||||
рМБЗЙО РПДНЕОСАЭЙК УФТПЛЙ Ч УЕТЧЕТЕ 3proxХ (пу windows,unix)
|
||||
(c) Lopuchov Kirill lopuchov@mail.ru
|
||||
|
||||
1. лТБФЛПЕ ПРЙУБОЙЕ ПРЙУБОЙЕ
|
||||
|
||||
йУРПМШЪХЕФУС ДМС ТХУУЙЖЙЛБГЙЙ УППВЭЕОЙК ЧЩДБЧБЕНЩИ 3proxy.
|
||||
дМС ЛПТТЕЛФОПК ТБВПФЩ ФТЕВХЕФУС РПУМЕДОСС 0.6 ЧЕТУЙС 3proxy (Ч ЙОФЕТЖЕКУЕ
|
||||
plugin api ЛПФПТПК РПСЧЙМУС job schedule ). чУЕ УППВЭЕОЙС ВЩМЙ ЧЪСФЩ ЙЪ
|
||||
ДЙУФТЙВХФЙЧБ 3proxy Й ЧЩОЕУЕООЩ Ч ПФДЕМШОЩК ЖБКМ. рТЙНЕТ ЖБКМБ rus-win1251.3ps.
|
||||
дМС ЛБЦДПЗП УЕТЧЙУБ УХЭЕУФЧХАФ УЧПЙ ВМПЛЙ УППВЭЕОЙК. оБЮБМП Й ЛПОЕГ ВМПЛБ
|
||||
ТБЪДЕМЕОЩ , ОБ РТЙНЕТ ДМС УЕТЧЙУБ ADMIN ОБЮБМП "[--admin--]" ЛПОЕГ [/--admin--].
|
||||
уБНЙ УППВЭЕОЙС ПФДЕМЕОЩ НЕЦДХ УПВПК УФТПЛПК "[end]", ОПЧБС УФТПЛБ ПРТЕДЕМСЕФУС
|
||||
УФТПЛПК "\n" .
|
||||
пФ ЧЕТУЙЙ Л ЧЕТУЙЙ ЛПМЙЮЕУФЧП УППВЭЕОЙК Ч 3proxy НПЦЕФ НЕОСФУС.
|
||||
ч ЬФПН УМХЮБЕ ОЕПВИПДЙНП МЙВП ДПВБЧЙФШ УБНПУФПСФЕМШОП ОПЧЩЕ УФТПЛЙ Ч
|
||||
УППФЧЕФУЧЕАЭЙЕ ВМПЛЙ rus-win1251.3ps, ЙМЙ ЦДБФШ ПВОПЧМЕОЙС :)
|
||||
|
||||
|
||||
дМС ЛПНРЙМСГЙЙ Й ФЕУФЙТПЧБОЙС РПД пу Windows ЙУРПМШЪПЧБМУС РБЛЕФ Dev-C++
|
||||
http://www.bloodshed.net/dev/
|
||||
дМС ЛПНРЙМСГЙЙ Й ФЕУФЙТПЧБОЙС РПД unix РПДПВОЩНЙ ЙУРПМШЪПЧБМУС gcc
|
||||
|
||||
|
||||
оБУФТПКЛБ 3proxy
|
||||
---------------------
|
||||
|
||||
plugin "string.dll" start c:\3proxy\rus-win1251.3ps
|
||||
|
||||
---------------------------KOI8-R---------------------------
|
||||
|
||||
|
@ -1,254 +0,0 @@
|
||||
#include "../../structures.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct pluginlink * mypl;
|
||||
int count_load_str_proxy_from_file=0,count_load_str_admin_from_file=0;
|
||||
int count_str_proxy_in_3proxy=0,count_str_admin_in_3proxy=0;
|
||||
char ** old_proxy_table=NULL;
|
||||
char ** old_admin_table=NULL;
|
||||
struct schedule myschedule;
|
||||
|
||||
|
||||
char **load_string(FILE *f,int max_count_str, int *countloadstr,
|
||||
char *start,char *stop,char **table_3proxy)
|
||||
{
|
||||
int cstr=0,i=0;
|
||||
char tmpbuf1[1024],*rstr,*pt=NULL,*p=NULL;
|
||||
char **old_table;
|
||||
|
||||
tmpbuf1[0]='\0';
|
||||
|
||||
fseek(f,0,SEEK_SET);
|
||||
|
||||
/*find start service section*/
|
||||
while(!feof(f))
|
||||
{
|
||||
fgets(tmpbuf1, 1023,f);
|
||||
if ((strstr(tmpbuf1,start))!=NULL) { i++; break; }
|
||||
tmpbuf1[0]='\0';
|
||||
}
|
||||
|
||||
if (i==0){
|
||||
fprintf(stderr,"Error StringsPlugin: No start section %s strings! \n",start);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*create table for old strings */
|
||||
old_table=(char **)mypl->myalloc(max_count_str*sizeof(char *));
|
||||
memset(old_table,0,max_count_str*sizeof(char *));
|
||||
|
||||
/*load from file new strings */
|
||||
i=0;
|
||||
while ( !feof(f) || i< max_count_str)
|
||||
{
|
||||
fgets(tmpbuf1, 1023,f);
|
||||
|
||||
if ((strstr(tmpbuf1,stop))!=NULL) { break; }
|
||||
|
||||
if (strstr(tmpbuf1,"[end]")==NULL)
|
||||
{
|
||||
/* find and replace \n \r*/
|
||||
rstr = tmpbuf1;
|
||||
while (*rstr!='\0')
|
||||
{
|
||||
if (*rstr=='\r' || *rstr=='\n' )
|
||||
{ *rstr='\0'; rstr++; }
|
||||
rstr++;
|
||||
}
|
||||
|
||||
while ((rstr=strstr(tmpbuf1,"\\n")))
|
||||
{
|
||||
if (rstr!=NULL){ *rstr='\r'; rstr++; *rstr='\n'; }
|
||||
}
|
||||
|
||||
|
||||
/* add string */
|
||||
if (pt!=NULL) { cstr=cstr+(int)strlen(pt); }
|
||||
|
||||
cstr=cstr+(int)strlen(tmpbuf1)+1;
|
||||
|
||||
p = (char *)mypl->myalloc(cstr);
|
||||
|
||||
if (pt!=NULL)
|
||||
{
|
||||
strcpy(p, pt);
|
||||
strcat(p, tmpbuf1);
|
||||
mypl->myfree(pt);
|
||||
}
|
||||
else
|
||||
{ strcpy(p, tmpbuf1); }
|
||||
|
||||
pt=p; cstr=0;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* save old string */
|
||||
old_table[i]=table_3proxy[i];
|
||||
/* replace string */
|
||||
table_3proxy[i]=pt;
|
||||
pt=NULL; i++;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(pt)mypl->myfree(pt);
|
||||
*countloadstr=i;
|
||||
if (i==0) { mypl->myfree(old_table); old_table=NULL; }
|
||||
|
||||
return old_table;
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
static int restore_old_table(void * v)
|
||||
{
|
||||
int i; char *p=NULL;
|
||||
|
||||
/* restore old proxy table */
|
||||
if(old_proxy_table)
|
||||
{
|
||||
|
||||
for(i=0; i < count_str_proxy_in_3proxy; i++){
|
||||
p=mypl->proxy_table[i];
|
||||
mypl->proxy_table[i]=old_proxy_table[i];
|
||||
mypl->myfree(p);
|
||||
}
|
||||
mypl->myfree(old_proxy_table);
|
||||
old_proxy_table = NULL;
|
||||
|
||||
}
|
||||
|
||||
p=NULL;
|
||||
|
||||
/* restore old admin table */
|
||||
if(old_admin_table)
|
||||
{
|
||||
|
||||
for(i=0; i < count_str_admin_in_3proxy; i++){
|
||||
p=mypl->admin_table[i];
|
||||
mypl->admin_table[i]=old_admin_table[i];
|
||||
mypl->myfree(p);
|
||||
}
|
||||
mypl->myfree(old_admin_table);
|
||||
old_admin_table = NULL;
|
||||
}
|
||||
/*return 1 delete job, 0 no delete!!! :)*/
|
||||
return 1;
|
||||
}
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
#ifdef _WIN32
|
||||
__declspec(dllexport) int start(struct pluginlink * pluginlink,
|
||||
int argc, char** argv);
|
||||
BOOL WINAPI DllMain( HINSTANCE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
if (ul_reason_for_call == DLL_PROCESS_DETACH)
|
||||
{
|
||||
if(old_proxy_table) { restore_old_table(NULL); }
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
#else
|
||||
|
||||
int start(struct pluginlink * pluginlink,
|
||||
int argc, char** argv);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*---------------------- start plugin init ------------------------------ */
|
||||
int start(struct pluginlink * pluginlink, int argc, char** argv)
|
||||
{
|
||||
FILE *f=NULL;
|
||||
|
||||
mypl=pluginlink;
|
||||
|
||||
if(old_proxy_table||old_admin_table) restore_old_table(NULL);
|
||||
|
||||
if(!(f=fopen(argv[1],"r"))) return 1001;
|
||||
|
||||
/*count string service PROXY in 3proxy */
|
||||
count_str_proxy_in_3proxy=0;
|
||||
while( mypl->proxy_table[count_str_proxy_in_3proxy] != NULL )
|
||||
{ count_str_proxy_in_3proxy++; }
|
||||
|
||||
/*count string service ADMIN in 3proxy */
|
||||
count_str_admin_in_3proxy=0;
|
||||
while( mypl->admin_table[count_str_admin_in_3proxy] != NULL )
|
||||
{ count_str_admin_in_3proxy++; }
|
||||
|
||||
/*---- load string for PROXY service ----*/
|
||||
old_proxy_table=load_string(f,count_str_proxy_in_3proxy,
|
||||
&count_load_str_proxy_from_file,
|
||||
"[--proxy--]","[/--proxy--]",
|
||||
mypl->proxy_table);
|
||||
|
||||
|
||||
if (old_proxy_table == NULL)
|
||||
{
|
||||
fprintf(stderr,"Error StringsPlugin: No load string from file %s \
|
||||
for service PROXY !\n",argv[1]);
|
||||
}
|
||||
|
||||
if(count_str_proxy_in_3proxy!= count_load_str_proxy_from_file)
|
||||
{
|
||||
fprintf(stderr,"Warning StringsPlugin: Count string for service PROXY in\
|
||||
3proxy not equality count string in file %s \n",argv[1]);
|
||||
}
|
||||
|
||||
|
||||
/*---- load string for ADMIN service ----*/
|
||||
old_admin_table=load_string(f,count_str_admin_in_3proxy,
|
||||
&count_load_str_admin_from_file,
|
||||
"[--admin--]","[/--admin--]",
|
||||
mypl->admin_table);
|
||||
|
||||
|
||||
if (old_admin_table == NULL)
|
||||
{
|
||||
fprintf(stderr,"Error StringsPlugin: No load string from file %s \
|
||||
for service ADMIN !\n",argv[1]);
|
||||
}
|
||||
|
||||
if(count_str_admin_in_3proxy!= count_load_str_admin_from_file)
|
||||
{
|
||||
fprintf(stderr,"Warning StringsPlugin: Count string for service ADMIN in\
|
||||
3proxy not equality count string in file %s\n",argv[1]);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
/* create job shedule for processing reload */
|
||||
if(*pluginlink->schedule!=&myschedule){
|
||||
memset(&myschedule,0,sizeof(struct schedule));
|
||||
myschedule.type=NONE;
|
||||
myschedule.function=restore_old_table;
|
||||
myschedule.next = *pluginlink->schedule;
|
||||
*pluginlink->schedule=&myschedule;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern }
|
||||
#endif
|
@ -1,13 +0,0 @@
|
||||
========================================================================
|
||||
3proxy traffic plugin Changelog
|
||||
========================================================================
|
||||
v0.1.2 (2 января 2007 года)
|
||||
- Плугин обновлён в соответствии с обновлением 3proxy.
|
||||
- Добавлена опция debug.
|
||||
|
||||
v0.1.1
|
||||
- Теперь udp нельзя задавать proxy, tcppm, pop3p
|
||||
- Исправлена ошибка с выбором типа соединения.
|
||||
|
||||
v0.1.0 beta (10 июля 2006)
|
||||
Первый релиз.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user