Move PCRE/SSL to main code

This commit is contained in:
Vladimir Dubrovin 2026-05-01 15:11:08 +03:00
parent a3fb7aff07
commit 8107f03062
42 changed files with 1088 additions and 1121 deletions

1
.gitignore vendored
View File

@ -267,3 +267,4 @@ bin/3proxy_socks
bin/3proxy_tcppm
bin/3proxy_tlspr
bin/3proxy_udppm
build*/*

View File

@ -105,7 +105,6 @@ if(WIN32)
# MSVC-specific settings
add_compile_definitions(
MSVC
WITH_SSL
)
# Use static runtime library
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
@ -123,7 +122,6 @@ if(WIN32)
# clang-cl (Clang with MSVC frontend)
add_compile_definitions(
MSVC
WITH_SSL
)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
add_compile_options(
@ -254,14 +252,14 @@ endif()
# OpenSSL
set(OPENSSL_FOUND FALSE)
if(3PROXY_USE_OPENSSL)
find_package(OpenSSL QUIET)
find_package(OpenSSL REQUIRED)
if(OpenSSL_FOUND)
set(OPENSSL_FOUND TRUE)
add_compile_definitions(WITH_SSL)
message(STATUS "OpenSSL found: ${OPENSSL_VERSION}")
else()
message(STATUS "OpenSSL not found, SSLPlugin will not be built")
endif()
else()
message(STATUS "OpenSSL disabled by user request")
endif()
# PCRE2
@ -269,9 +267,10 @@ set(PCRE2_FOUND FALSE)
if(3PROXY_USE_PCRE2)
find_package(PCRE2 QUIET)
if(PCRE2_FOUND)
add_compile_definitions(WITH_PCRE)
message(STATUS "PCRE2 found: ${PCRE2_VERSION}")
else()
message(STATUS "PCRE2 not found, PCREPlugin will not be built")
message(STATUS "PCRE2 not found, PCRE support will not be built")
endif()
endif()
@ -302,6 +301,11 @@ if(NOT ODBC_FOUND)
add_compile_definitions(NOODBC)
endif()
# Set NORADIUS if OpenSSL is not available (RADIUS requires MD5 from OpenSSL)
if(NOT OPENSSL_FOUND)
add_compile_definitions(NORADIUS)
endif()
# Source files for 3proxy core
set(3PROXY_CORE_SOURCES
src/3proxy.c
@ -320,10 +324,8 @@ set(3PROXY_CORE_SOURCES
src/stringtable.c
)
# MD4/MD5/BLAKE2 sources for 3proxy_crypt
# BLAKE2 source for 3proxy_crypt
set(MD_SOURCES
src/libs/md4.c
src/libs/md5.c
src/libs/blake2b-ref.c
)
@ -372,6 +374,10 @@ target_include_directories(srvudppm_obj PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# UDP socket relay (used by 3proxy, socks, udppm)
add_library(udpsockmap_obj OBJECT src/udpsockmap.c)
target_include_directories(udpsockmap_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
# mainfunc object (proxymain.c compiled with MODULEMAINFUNC=mainfunc for 3proxy)
add_library(mainfunc OBJECT src/proxymain.c)
target_include_directories(mainfunc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
@ -384,6 +390,9 @@ target_include_directories(ftp_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
# 3proxy_crypt object for 3proxy (without WITHMAIN)
add_library(3proxy_crypt_obj OBJECT src/3proxy_crypt.c)
target_include_directories(3proxy_crypt_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
if(OpenSSL_FOUND)
target_include_directories(3proxy_crypt_obj PRIVATE ${OPENSSL_INCLUDE_DIR})
endif()
# ============================================================================
# Main 3proxy executable
@ -397,15 +406,30 @@ add_executable(3proxy
$<TARGET_OBJECTS:srvudppm_obj>
$<TARGET_OBJECTS:mainfunc>
$<TARGET_OBJECTS:common_obj>
$<TARGET_OBJECTS:udpsockmap_obj>
$<TARGET_OBJECTS:base64_obj>
$<TARGET_OBJECTS:ftp_obj>
$<TARGET_OBJECTS:3proxy_crypt_obj>
)
if(OpenSSL_FOUND)
target_sources(3proxy PRIVATE src/ssllib.c src/ssl.c)
endif()
if(PCRE2_FOUND)
target_sources(3proxy PRIVATE src/pcre.c)
endif()
target_include_directories(3proxy PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/libs
)
if(OpenSSL_FOUND)
target_include_directories(3proxy PRIVATE ${OPENSSL_INCLUDE_DIR})
endif()
if(PCRE2_FOUND)
target_include_directories(3proxy PRIVATE ${PCRE2_INCLUDE_DIRS})
endif()
target_link_libraries(3proxy PRIVATE Threads::Threads)
@ -417,19 +441,52 @@ if(ODBC_FOUND)
endif()
endif()
if(OpenSSL_FOUND)
target_link_libraries(3proxy PRIVATE OpenSSL::SSL OpenSSL::Crypto)
endif()
# PCRE2 linking (try static first on Linux/FreeBSD, fallback to dynamic)
if(PCRE2_FOUND)
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR
CMAKE_SYSTEM_NAME MATCHES "FreeBSD|OpenBSD|NetBSD" OR
CMAKE_SYSTEM_NAME STREQUAL "Unix")
# Try static linking for Linux/BSD
find_library(PCRE2_STATIC_LIB
NAMES pcre2-8-static libpcre2-8.a pcre2-8.a
PATHS ${PC_PCRE2_LIBRARY_DIRS}
/usr/lib/x86_64-linux-gnu
/usr/lib
/usr/local/lib
/lib
)
if(PCRE2_STATIC_LIB AND PCRE2_STATIC_LIB MATCHES "\\.a$")
target_link_libraries(3proxy PRIVATE
-Wl,-Bstatic
${PCRE2_STATIC_LIB}
-Wl,-Bdynamic
)
message(STATUS "Using static PCRE2: ${PCRE2_STATIC_LIB}")
elseif(TARGET PCRE2::PCRE2)
target_link_libraries(3proxy PRIVATE PCRE2::PCRE2)
message(STATUS "Using dynamic PCRE2 (PCRE2::PCRE2)")
else()
target_link_libraries(3proxy PRIVATE ${PCRE2_LIBRARIES})
message(STATUS "Using dynamic PCRE2: ${PCRE2_LIBRARIES}")
endif()
elseif(TARGET PCRE2::PCRE2)
target_link_libraries(3proxy PRIVATE PCRE2::PCRE2)
else()
target_link_libraries(3proxy PRIVATE ${PCRE2_LIBRARIES})
endif()
endif()
if(WIN32)
target_link_libraries(3proxy PRIVATE ${WINDOWS_LIBS})
if(OpenSSL_FOUND)
target_link_libraries(3proxy PRIVATE OpenSSL::SSL OpenSSL::Crypto)
endif()
if(COMPILER_IS_MSVC AND EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/3proxy.rc)
target_sources(3proxy PRIVATE 3proxy.rc)
endif()
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_link_libraries(3proxy PRIVATE dl)
if(OpenSSL_FOUND)
target_link_libraries(3proxy PRIVATE OpenSSL::SSL OpenSSL::Crypto)
endif()
endif()
# Build 3proxy_crypt utility
@ -443,7 +500,13 @@ target_include_directories(3proxy_crypt PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/libs
)
if(OpenSSL_FOUND)
target_include_directories(3proxy_crypt PRIVATE ${OPENSSL_INCLUDE_DIR})
endif()
target_link_libraries(3proxy_crypt PRIVATE Threads::Threads)
if(OpenSSL_FOUND)
target_link_libraries(3proxy_crypt PRIVATE OpenSSL::SSL OpenSSL::Crypto)
endif()
if("${3PROXY_BINARY_PREFIX}" STREQUAL "")
set_target_properties(3proxy_crypt PROPERTIES OUTPUT_NAME "mycrypt")
else()
@ -509,6 +572,10 @@ foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
if(PROXY_NAME STREQUAL "udppm")
target_sources(${PROXY_NAME} PRIVATE src/hash.c)
endif()
if(PROXY_NAME STREQUAL "socks" OR PROXY_NAME STREQUAL "udppm")
target_sources(${PROXY_NAME} PRIVATE src/udpsockmap.c)
endif()
endforeach()
# Plugin output directory
@ -527,26 +594,12 @@ foreach(PLUGIN ${DEFAULT_PLUGINS})
add_subdirectory(src/plugins/${PLUGIN})
endforeach()
if(OPENSSL_FOUND)
add_subdirectory(src/plugins/SSLPlugin)
endif()
if(PCRE2_FOUND)
add_subdirectory(src/plugins/PCREPlugin)
endif()
if(PAM_FOUND)
add_subdirectory(src/plugins/PamAuth)
endif()
# Build full list of plugins to be built
set(ALL_PLUGINS ${DEFAULT_PLUGINS})
if(OPENSSL_FOUND)
list(APPEND ALL_PLUGINS SSLPlugin)
endif()
if(PCRE2_FOUND)
list(APPEND ALL_PLUGINS PCREPlugin)
endif()
if(PAM_FOUND)
list(APPEND ALL_PLUGINS PamAuth)
endif()

View File

@ -36,11 +36,14 @@ PLUGINS ?= StringsPlugin TrafficPlugin TransparentPlugin FilePlugin
OPENSSL_CHECK = $(shell echo "\#include <openssl/ssl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testssl.o - 2>/dev/null && $(CC) $(LDFLAGS) -otestssl testssl.o -lcrypto -lssl 2>/dev/null && rm testssl testssl.o && echo true||echo false)
ifeq ($(OPENSSL_CHECK), true)
LIBS += -l crypto -l ssl
PLUGINS += SSLPlugin
CFLAGS += -DWITH_SSL
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
endif
PCRE_CHECK = $(shell echo "\#define PCRE2_CODE_UNIT_WIDTH 8\\n\#include <pcre2.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testpcre.o - 2>/dev/null && $(CC) -o testpcre testpcre.o $(LDFLAGS) -lpcre2-8 2>/dev/null && rm testpcre testpcre.o && echo true||echo false)
ifeq ($(PCRE_CHECK), true)
PLUGINS += PCREPlugin
CFLAGS += -DWITH_PCRE
PCRE_OBJS = pcre$(OBJSUFFICS)
PCRE_LIBS = -lpcre2-8
endif
PAM_CHECK = $(shell echo "\#include <security/pam_appl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testpam.o - 2>/dev/null && $(CC) $(LDFLAGS) -o testpam testpam.o -lpam 2>/dev/null && rm testpam testpam.o && echo true||echo false)
ifeq ($(PAM_CHECK), true)

View File

@ -38,11 +38,14 @@ PLUGINS ?= StringsPlugin TrafficPlugin TransparentPlugin FilePlugin
OPENSSL_CHECK = $(shell echo "\#include <openssl/ssl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testssl.o - 2>/dev/null && $(CC) $(LDFLAGS) -otestssl testssl.o -lcrypto -lssl 2>/dev/null && rm testssl testssl.o && echo true||echo false)
ifeq ($(OPENSSL_CHECK), true)
LIBS += -l crypto -l ssl
PLUGINS += SSLPlugin
CFLAGS += -DWITH_SSL
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
endif
PCRE_CHECK = $(shell echo "\#define PCRE2_CODE_UNIT_WIDTH 8\\n\#include <pcre2.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testpcre.o - 2>/dev/null && $(CC) -o testpcre testpcre.o $(LDFLAGS) -lpcre2-8 2>/dev/null && rm testpcre testpcre.o && echo true||echo false)
PCRE_CHECK = $(shell echo "\#define PCRE2_CODE_UNIT_WIDTH 8\\n\#include <pcre2.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testpcre.o - 2>/dev/null && $(CC) -o testpcre testpcre.o $(LDFLAGS) -Wl,-Bstatic -lpcre2-8 -Wl,-Bdynamic 2>/dev/null && rm testpcre testpcre.o && echo true||echo false)
ifeq ($(PCRE_CHECK), true)
PLUGINS += PCREPlugin
CFLAGS += -DWITH_PCRE
PCRE_OBJS = pcre$(OBJSUFFICS)
PCRE_LIBS = -Wl,-Bstatic -lpcre2-8 -Wl,-Bdynamic
endif
PAM_CHECK = $(shell echo "\#include <security/pam_appl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testpam.o - 2>/dev/null && $(CC) $(LDFLAGS) -o testpam testpam.o -lpam 2>/dev/null && rm testpam testpam.o && echo true||echo false)
ifeq ($(PAM_CHECK), true)

View File

@ -27,7 +27,20 @@ AFTERCLEAN = (find . -type f -name "*.o" -delete && find src/ -type f -name "Mak
TYPECOMMAND = cat
COMPATLIBS =
MAKEFILE = Makefile.Solaris
PLUGINS = StringsPlugin TrafficPlugin
PLUGINS = StringsPlugin TrafficPlugin TransparentPlugin FilePlugin
OPENSSL_CHECK = $(shell echo "\#include <openssl/ssl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testssl.o - 2>/dev/null && $(CC) $(LDFLAGS) -o testssl testssl.o -lcrypto -lssl 2>/dev/null && rm testssl testssl.o && echo true||echo false)
ifeq ($(OPENSSL_CHECK), true)
LIBS += -l crypto -l ssl
CFLAGS += -DWITH_SSL
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
endif
PCRE_CHECK = $(shell echo "\#define PCRE2_CODE_UNIT_WIDTH 8\\n\#include <pcre2.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testpcre.o - 2>/dev/null && $(CC) -o testpcre testpcre.o $(LDFLAGS) -Wl,-Bstatic -lpcre2-8 -Wl,-Bdynamic 2>/dev/null && rm testpcre testpcre.o && echo true||echo false)
ifeq ($(PCRE_CHECK), true)
CFLAGS += -DWITH_PCRE
PCRE_OBJS = pcre$(OBJSUFFICS)
PCRE_LIBS = -Wl,-Bstatic -lpcre2-8 -Wl,-Bdynamic
endif
include Makefile.inc

View File

@ -8,13 +8,13 @@ BUILDDIR = ../bin/
CC = cl
VERSION = $(VERSION)
BUILDDATE = $(BUILDDATE)
CFLAGS = /nologo /MT /W3 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "WITH_SSL" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(BUILDDATE) $(VERSION)
CFLAGS = /nologo /MT /W3 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" /D "WITH_SSL" /D "WITH_PCRE" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(BUILDDATE) $(VERSION)
COUT = /Fo
LN = link
LDFLAGS = /nologo /subsystem:console /incremental:no
DLFLAGS = /DLL
DLSUFFICS = .dll
LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib kernel32.lib Gdi32.lib Crypt32.lib libcrypto.lib libssl.lib
LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib kernel32.lib Gdi32.lib Crypt32.lib libcrypto.lib libssl.lib pcre2-8.lib
LIBSPREFIX =
LIBSSUFFIX = .lib
LIBEXT = .lib
@ -27,7 +27,9 @@ REMOVECOMMAND = del
TYPECOMMAND = type
COMPATLIBS =
MAKEFILE = Makefile.msvc
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin FilePlugin SSLPlugin PCREPlugin
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin FilePlugin
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
PCRE_OBJS = pcre$(OBJSUFFICS)
VERFILE = 3proxy.res $(VERFILE)
VERSIONDEP = 3proxy.res $(VERSIONDEP)
AFTERCLEAN = if exist src\*.res (del src\*.res) && if exist src\*.err (del src\*.err)

View File

@ -38,11 +38,14 @@ PLUGINS ?= StringsPlugin TrafficPlugin TransparentPlugin FilePlugin
OPENSSL_CHECK = $(shell echo "\#include <openssl/ssl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testssl.o - 2>/dev/null && $(CC) $(LDFLAGS) -otestssl testssl.o -lcrypto -lssl 2>/dev/null && rm testssl testssl.o && echo true||echo false)
ifeq ($(OPENSSL_CHECK), true)
LIBS += -l crypto -l ssl
PLUGINS += SSLPlugin
CFLAGS += -DWITH_SSL
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
endif
PCRE_CHECK = $(shell echo "\#define PCRE2_CODE_UNIT_WIDTH 8\\n\#include <pcre2.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testpcre.o - 2>/dev/null && $(CC) -o testpcre testpcre.o $(LDFLAGS) -lpcre2-8 2>/dev/null && rm testpcre testpcre.o && echo true||echo false)
PCRE_CHECK = $(shell echo "\#define PCRE2_CODE_UNIT_WIDTH 8\\n\#include <pcre2.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testpcre.o - 2>/dev/null && $(CC) -o testpcre testpcre.o $(LDFLAGS) -Wl,-Bstatic -lpcre2-8 -Wl,-Bdynamic 2>/dev/null && rm testpcre testpcre.o && echo true||echo false)
ifeq ($(PCRE_CHECK), true)
PLUGINS += PCREPlugin
CFLAGS += -DWITH_PCRE
PCRE_OBJS = pcre$(OBJSUFFICS)
PCRE_LIBS = -Wl,-Bstatic -lpcre2-8 -Wl,-Bdynamic
endif
PAM_CHECK = $(shell echo "\#include <security/pam_appl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testpam.o - 2>/dev/null && $(CC) $(LDFLAGS) -o testpam testpam.o -lpam 2>/dev/null && rm testpam testpam.o && echo true||echo false)
ifeq ($(PAM_CHECK), true)

View File

@ -27,6 +27,8 @@ TYPECOMMAND = type
COMPATLIBS =
MAKEFILE = Makefile.watcom
PLUGINS = utf8tocp1251 WindowsAuthentication TrafficPlugin StringsPlugin
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
PCRE_OBJS = pcre$(OBJSUFFICS)
VERFILE = $(VERFILE)
VERSION = $(VERSION)
VERSIONDEP = 3proxy.res $(VERSIONDEP)

View File

@ -37,7 +37,8 @@ ifndef OPENSSL_CHECK
OPENSSL_CHECK = $(shell echo "\#include <openssl/ssl.h>\\n int main(){return 0;}" | tr -d '\\\\' | cc -x c $(CFLAGS) $(LDFLAGS) -l crypto -l ssl -o testssl - 2>/dev/null && rm testssl && echo true||echo false)
ifeq ($(OPENSSL_CHECK), true)
LIBS += -l crypto -l ssl
PLUGINS += SSLPlugin
CFLAGS += -DWITH_SSL
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
endif
PAM_CHECK = $(shell echo "\#include <security/pam_appl.h>\\n int main(){return 0;}" | tr -d '\\\\' | cc -x c $(CFLAGS) $(LDFLAGS) -l pam -o testpam - 2>/dev/null && rm testpam && echo true||echo false)
ifeq ($(PAM_CHECK), true)
@ -45,7 +46,9 @@ ifeq ($(PAM_CHECK), true)
endif
PCRE_CHECK = $(shell echo "\#define PCRE2_CODE_UNIT_WIDTH 8\\n#include <pcre2.h>\\n int main(){return 0;}" | tr -d '\\\\' | cc -x c $(CFLAGS) $(LDFLAGS) -lpcre2-8 -o testpcre - 2>/dev/null && rm testpcre && echo true||echo false)
ifeq ($(PCRE_CHECK), true)
PLUGINS += PCREPlugin
CFLAGS += -DWITH_PCRE
PCRE_OBJS = pcre$(OBJSUFFICS)
PCRE_LIBS = -lpcre2-8
endif
endif

View File

@ -33,8 +33,9 @@
<li><a href="#NAMES">How to resolve names through a parent proxy</a></li>
<li><a href="#ISFTP">How to set up an FTP proxy</a></li>
<li><a href="#TLSPR">How to set up an SNI proxy (tlspr)</a></li>
<li><a href="#SSLPLUGIN">How to set up TLS/SSL with SSLPlugin (https proxy, mTLS)</a></li>
<li><a href="#CERTIFICATES">How to create CA and certificates for SSLPlugin</a></li>
<li><a href="#SSLPLUGIN">How to set up TLS/SSL (https proxy, mTLS)</a></li>
<li><a href="#CERTIFICATES">How to create CA and certificates for SSL</a></li>
<li><a href="#PCRE">How to use PCRE filtering (regular expressions)</a></li>
<li><A HREF="#AUTH">How to limit service access</A>
<li><A HREF="#USERS">How to create a user list</A>
<li><A HREF="#ACL">How to limit user access to resources</A>
@ -639,9 +640,12 @@ allow *
proxy
</pre>
</p>
<li><a name="SSLPLUGIN"><i>How to set up TLS/SSL with SSLPlugin (https proxy, mTLS)</i></a>
<li><a name="SSLPLUGIN"><i>How to set up TLS/SSL (https proxy, mTLS)</i></a>
<p>
SSLPlugin provides TLS/SSL support for 3proxy. It can be used to:
Since version 0.9.7, SSL/TLS support is built into 3proxy when compiled with OpenSSL
(WITH_SSL). Previously available as SSLPlugin, the functionality is now integrated
into the main binary. The plugin line is no longer required.
SSL/TLS support can be used to:
<ul>
<li>Create an https:// proxy (TLS-encrypted connection between client and proxy)</li>
<li>Implement MITM for TLS traffic inspection</li>
@ -654,7 +658,6 @@ SSLPlugin provides TLS/SSL support for 3proxy. It can be used to:
<br>To create an https:// proxy, you need a server certificate and key. The certificate must not be self-signed
and should contain Subject Alternative Names (SAN) for the proxy hostname/IP.
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_server_cert /etc/3proxy/certs/server.crt
ssl_server_key /etc/3proxy/certs/server.key
ssl_serv
@ -670,7 +673,6 @@ Configure clients to use https://proxy-host:3129/ as the proxy URL.
<b>Client certificate authentication (mTLS):</b>
<br>To require clients to authenticate with a certificate, use ssl_server_verify and provide the CA certificate:
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_server_cert /etc/3proxy/certs/server.crt
ssl_server_key /etc/3proxy/certs/server.key
ssl_server_ca_file /etc/3proxy/certs/ca.crt
@ -685,7 +687,6 @@ Only clients with a valid certificate signed by the CA can connect.
<b>MITM for TLS traffic inspection:</b>
<br>To intercept and decrypt TLS traffic, you need a CA certificate to generate spoofed server certificates:
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_server_ca_file /etc/3proxy/certs/ca.crt
ssl_server_ca_key /etc/3proxy/certs/ca.key
ssl_client_verify
@ -703,7 +704,6 @@ Without ssl_client_verify, the proxy is vulnerable to MITM attacks.
<b>TLS client (connect to upstream via TLS):</b>
<br>To connect to upstream servers via TLS with client certificate authentication:
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_client_cert /etc/3proxy/certs/client.crt
ssl_client_key /etc/3proxy/certs/client.key
ssl_client_verify
@ -715,7 +715,6 @@ proxy -p3128
<b>Conditional TLS for parent proxy (ssl_client_mode 3):</b>
<br>With ssl_client_mode 3, TLS handshake to parent proxy is performed only if the parent type ends with 's' (secure types). This allows mixing secure and non-secure parent proxies in the same configuration:
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_server_cert /etc/3proxy/certs/server.crt
ssl_server_key /etc/3proxy/certs/server.key
ssl_client_mode 3
@ -734,7 +733,7 @@ ssl_nocli
<p>
This creates an HTTPS proxy (ssl_serv) that accepts TLS connections from clients. For parent proxy connections, user1's traffic goes through an https parent with TLS encryption (secure type), while user2's traffic goes through a regular socks5 parent without TLS. Secure parent types include: tcps, https, connects, connect+s, socks4s, socks5s, socks4+s, socks5+s, pop3s, smtps, ftps.
</p>
<li><a name="CERTIFICATES"><i>How to create CA and certificates for SSLPlugin</i></a>
<li><a name="CERTIFICATES"><i>How to create CA and certificates for SSL</i></a>
<p>
<b>Creating a Certificate Authority (CA):</b>
<br>For MITM or mTLS, you need a CA. Generate a CA private key and certificate:
@ -849,6 +848,65 @@ openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key \
openssl pkcs12 -export -out client.p12 -passout pass: \
-inkey client.key -in client.crt -certfile ca.crt
</pre>
<li><a name="PCRE"><i>How to use PCRE filtering (regular expressions)</i></a>
<p>
Since version 0.9.7, PCRE (Perl Compatible Regular Expressions) filtering is built into
3proxy when compiled with PCRE2 support (WITH_PCRE). Previously available as PCREPlugin,
the functionality is now integrated into the main binary. The plugin line is no longer required.
</p>
<p>
PCRE filtering can be used to create matching and replacement rules with regular expressions
for client requests, client and server headers, and client and server data.
</p>
<p>
<b>Commands:</b>
</p><pre>
pcre TYPE FILTER_ACTION REGEXP [ACE]
pcre_rewrite TYPE FILTER_ACTION REGEXP REWRITE_EXPRESSION [ACE]
pcre_extend FILTER_ACTION [ACE]
pcre_options OPTION1 [...]
</pre>
<p>
<ul>
<li><b>TYPE</b> - type of filtered data (comma-delimited list):
<ul>
<li><b>request</b> - content of the client's request (e.g., HTTP GET request string)
<li><b>cliheader</b> - content of the client request headers
<li><b>srvheader</b> - content of the server's reply headers
<li><b>clidata</b> - data received from the client (e.g., HTTP POST data)
<li><b>srvdata</b> - data received from the server (e.g., HTML page)
</ul>
<li><b>FILTER_ACTION</b> - action on match:
<ul>
<li><b>allow</b> - allow this request without checking the rest of the rules
<li><b>deny</b> - deny this request without checking the rest of the rules
<li><b>dunno</b> - continue with the rest of the rules (useful with pcre_rewrite)
</ul>
<li><b>REGEXP</b> - PCRE (Perl) regular expression. Use * if no regexp matching is required.
<li><b>REWRITE_EXPRESSION</b> - substitution string. May contain Perl-style substrings
$1, $2, etc. $0 means the whole matched string. \r and \n may be used to insert new lines.
<li><b>ACE</b> - access control entry (user names, source IPs, destination IPs, ports, etc.),
identical to allow/deny/bandlimin commands. The regular expression is only matched if the ACL
matches the connection data.
</ul>
</p>
<p>
<b>Examples:</b>
</p><pre>
# Block requests containing specific keywords for certain users
pcre request deny "porn|sex" user1,user2,user3 192.168.0.0/16
# Block responses with specific content type
pcre srvheader deny "Content-type: application"
# Replace content in both directions (censorship)
pcre_rewrite clidata,srvdata dunno "porn|sex|pussy" "***" baduser
pcre_extend deny * 192.168.0.1/16
</pre>
<p>
<b>Note:</b> Regular expressions don't require authentication and cannot replace
authentication and/or allow/deny ACLs.
</p>
<li><A NAME="AUTH">How to limit service access</A>
<p>
First, always specify the internal interface to accept incoming connections with the

View File

@ -33,8 +33,9 @@
<li><a href="#NAMES">Как разрешать имена на родительском прокси?</a></li>
<li><a href="#ISFTP">Как настроить FTP прокси?</a></li>
<li><a href="#TLSPR">Как настроить SNI proxy (tlspr)</a></li>
<li><a href="#SSLPLUGIN">Как настроить TLS/SSL с помощью SSLPlugin (https прокси, mTLS)</a></li>
<li><a href="#CERTIFICATES">Как создать CA и сертификаты для SSLPlugin</a></li>
<li><a href="#SSLPLUGIN">Как настроить TLS/SSL (https прокси, mTLS)</a></li>
<li><a href="#CERTIFICATES">Как создать CA и сертификаты для SSL</a></li>
<li><a href="#PCRE">Как использовать PCRE-фильтрацию (регулярные выражения)</a></li>
<li><a href="#AUTH">Как ограничить доступ к службе</a>
<li><a href="#USERS">Как создать список пользователей</a>
<li><a href="#ACL">Как ограничить доступ пользователей к ресурсам</a>
@ -648,9 +649,12 @@ proxy
</pre>
</p>
<li><a name="SSLPLUGIN"><i>Как настроить TLS/SSL с помощью SSLPlugin (https прокси, mTLS)</i></a>
<li><a name="SSLPLUGIN"><i>Как настроить TLS/SSL (https прокси, mTLS)</i></a>
<p>
SSLPlugin обеспечивает поддержку TLS/SSL для 3proxy. Он может использоваться для:
Начиная с версии 0.9.7 поддержка TLS/SSL встроена в 3proxy при компиляции с OpenSSL
(WITH_SSL). Ранее доступная как SSLPlugin, функциональность теперь интегрирована
в основной бинарный файл. Строка plugin больше не нужна.
TLS/SSL может использоваться для:
<ul>
<li>Создания https:// прокси (TLS-шифрованное соединение между клиентом и прокси)</li>
<li>Реализации MITM для инспекции TLS-трафика</li>
@ -663,7 +667,6 @@ SSLPlugin обеспечивает поддержку TLS/SSL для 3proxy. О
<br>Для создания https:// прокси требуется сертификат и ключ сервера. Сертификат не должен быть самоподписанным
и должен содержать альтернативные имена (SAN) для имени хоста/IP прокси.
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_server_cert /etc/3proxy/certs/server.crt
ssl_server_key /etc/3proxy/certs/server.key
ssl_serv
@ -679,7 +682,6 @@ proxy -p3128
<b>Аутентификация по клиентскому сертификату (mTLS):</b>
<br>Чтобы требовать от клиентов аутентификацию по сертификату, используйте ssl_server_verify и укажите CA-сертификат:
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_server_cert /etc/3proxy/certs/server.crt
ssl_server_key /etc/3proxy/certs/server.key
ssl_server_ca_file /etc/3proxy/certs/ca.crt
@ -694,7 +696,6 @@ proxy -p3129
<b>MITM для инспекции TLS-трафика:</b>
<br>Для перехвата и расшифровки TLS-трафика требуется CA-сертификат для генерации подделанных серверных сертификатов:
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_server_ca_file /etc/3proxy/certs/ca.crt
ssl_server_ca_key /etc/3proxy/certs/ca.key
ssl_client_verify
@ -712,7 +713,6 @@ CA-сертификат должен быть доверенным для кли
<b>TLS-клиент (соединение с вышестоящим сервером через TLS):</b>
<br>Для соединения с вышестоящими серверами через TLS с аутентификацией по клиентскому сертификату:
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_client_cert /etc/3proxy/certs/client.crt
ssl_client_key /etc/3proxy/certs/client.key
ssl_client_verify
@ -724,7 +724,6 @@ proxy -p3128
<b>Условное TLS для parent прокси (ssl_client_mode 3):</b>
<br>При ssl_client_mode 3 TLS-рукопожатие с родительским прокси выполняется только если тип parent прокси заканчивается на 's' (защищённые типы). Это позволяет смешивать защищённые и незащищённые родительские прокси в одной конфигурации:
</p><pre>
plugin /path/to/SSLPlugin.ld.so ssl_plugin
ssl_server_cert /etc/3proxy/certs/server.crt
ssl_server_key /etc/3proxy/certs/server.key
ssl_client_mode 3
@ -743,7 +742,7 @@ ssl_nocli
<p>
Создаётся HTTPS-прокси (ssl_serv), принимающий TLS-соединения от клиентов. Для соединений с родительским прокси трафик user1 идёт через https родитель с TLS-шифрованием (защищённый тип), а трафик user2 — через обычный socks5 родитель без TLS. Защищённые типы parent прокси: tcps, https, connects, connect+s, socks4s, socks5s, socks4+s, socks5+s, pop3s, smtps, ftps.
</p>
<li><a name="CERTIFICATES"><i>Как создать CA и сертификаты для SSLPlugin</i></a>
<li><a name="CERTIFICATES"><i>Как создать CA и сертификаты для SSL</i></a>
<p>
<b>Создание удостоверяющего центра (CA):</b>
<br>Для MITM или mTLS требуется CA. Сгенерируйте закрытый ключ CA и сертификат:
@ -859,6 +858,66 @@ openssl pkcs12 -export -out client.p12 -passout pass: \
-inkey client.key -in client.crt -certfile ca.crt
</pre>
<li><a name="PCRE"><i>Как использовать PCRE-фильтрацию (регулярные выражения)</i></a>
<p>
Начиная с версии 0.9.7 фильтрация PCRE встроена в 3proxy при компиляции с поддержкой
PCRE2 (WITH_PCRE). Ранее доступная как PCREPlugin, функциональность теперь интегрирована
в основной бинарный файл. Строка plugin больше не нужна.
</p>
<p>
PCRE-фильтрация может использоваться для создания правил поиска и замены с регулярными
выражениями для запросов клиентов, заголовков клиента и сервера, а также данных.
</p>
<p>
<b>Команды:</b>
</p><pre>
pcre TYPE FILTER_ACTION REGEXP [ACE]
pcre_rewrite TYPE FILTER_ACTION REGEXP REWRITE_EXPRESSION [ACE]
pcre_extend FILTER_ACTION [ACE]
pcre_options OPTION1 [...]
</pre>
<p>
<ul>
<li><b>TYPE</b> - тип фильтруемых данных (список через запятую):
<ul>
<li><b>request</b> - содержимое запроса клиента (например, строка HTTP GET-запроса)
<li><b>cliheader</b> - содержимое заголовков запроса клиента
<li><b>srvheader</b> - содержимое заголовков ответа сервера
<li><b>clidata</b> - данные полученные от клиента (например, данные POST-запроса)
<li><b>srvdata</b> - данные полученные от сервера (например, HTML-страница)
</ul>
<li><b>FILTER_ACTION</b> - действие при совпадении:
<ul>
<li><b>allow</b> - разрешить запрос без проверки остальных правил
<li><b>deny</b> - запретить запрос без проверки остальных правил
<li><b>dunno</b> - продолжить проверку правил (полезно для pcre_rewrite)
</ul>
<li><b>REGEXP</b> - регулярное выражение PCRE (Perl). Используйте * если проверка не требуется.
<li><b>REWRITE_EXPRESSION</b> - строка замены. Может содержать Perl-подстановки
$1, $2 и т.д. $0 - вся найденная подстрока. \r и \n для вставки новых строк.
<li><b>ACE</b> - элемент списка контроля доступа (имена пользователей, IP источника,
IP назначения, порты и т.д.), аналогичный командам allow/deny/bandlimin.
Регулярное выражение проверяется только при совпадении ACL с данными соединения.
</ul>
</p>
<p>
<b>Примеры:</b>
</p><pre>
# Блокировать запросы с определёнными ключевыми словами для некоторых пользователей
pcre request deny "porn|sex" user1,user2,user3 192.168.0.0/16
# Блокировать ответы с определённым content-type
pcre srvheader deny "Content-type: application"
# Замена содержимого в обоих направлениях (цензура)
pcre_rewrite clidata,srvdata dunno "porn|sex|pussy" "***" baduser
pcre_extend deny * 192.168.0.1/16
</pre>
<p>
<b>Примечание:</b> Регулярные выражения не требуют авторизации и не могут заменить
авторизацию и/или ACL allow/deny.
</p>
<li><a name="AUTH"><i>Как ограничить доступ к службе</i></a>
<p>
Во-первых, для ограничения доступа необходимо указать внутренний интерфейс,

View File

@ -10,6 +10,14 @@
<a href="#NAME">NAME</a><br>
<a href="#DESCRIPTION">DESCRIPTION</a><br>
<a href="#PLUGINS">PLUGINS</a><br>
<a href="#SSL/TLS SUPPORT">SSL/TLS SUPPORT</a><br>
<a href="#MITM Commands">MITM Commands</a><br>
<a href="#Server TLS Commands">Server TLS Commands</a><br>
<a href="#Client TLS Commands">Client TLS Commands</a><br>
<a href="#SSL Parameters">SSL Parameters</a><br>
<a href="#PCRE FILTERING">PCRE FILTERING</a><br>
<a href="#PCRE Commands">PCRE Commands</a><br>
<a href="#PCRE Parameters">PCRE Parameters</a><br>
<a href="#BUGS">BUGS</a><br>
<a href="#SEE ALSO">SEE ALSO</a><br>
<a href="#TRIVIA">TRIVIA</a><br>
@ -1017,6 +1025,220 @@ the given value, no data filtering will be performed through
filtering plugins to avoid data corruption and/or
Content-Length changing. Default is 1MB (1048576).</p>
<h2>SSL/TLS SUPPORT
<a name="SSL/TLS SUPPORT"></a>
</h2>
<p style="margin-left:6%; margin-top: 1em">SSL/TLS support
is built into 3proxy (since 0.9.7) when compiled with
OpenSSL (WITH_SSL). Previously available as SSLPlugin, the
functionality is now integrated into the main binary. The
plugin line is no longer required.</p>
<p style="margin-left:6%; margin-top: 1em">SSL/TLS can be
used for: - transparent MITM (Man-in-the-Middle) for TLS
traffic inspection - https:// proxy (TLS-encrypted
connection between client and proxy) - TLS client
connections to upstream servers with certificate
authentication - mTLS (mutual TLS) requiring client
certificates</p>
<h3>MITM Commands
<a name="MITM Commands"></a>
</h3>
<p style="margin-left:6%; margin-top: 1em"><b>ssl_mitm</b>
- spoof certificates for services started below. Usage
without ssl_client_verify is insecure. <b><br>
ssl_nomitm</b> - do not spoof certificates for services
started below</p>
<h3>Server TLS Commands
<a name="Server TLS Commands"></a>
</h3>
<p style="margin-left:6%; margin-top: 1em"><b>ssl_serv</b>
(or ssl_server) - require TLS connection from clients for
services below <b><br>
ssl_noserv</b> (or ssl_noserver) - do not require TLS
connection from clients for services below</p>
<h3>Client TLS Commands
<a name="Client TLS Commands"></a>
</h3>
<p style="margin-left:6%; margin-top: 1em"><b>ssl_cli</b>
(or ssl_client) - establish TLS connection to upstream
server for services below <b><br>
ssl_nocli</b> (or ssl_noclient) - do not establish TLS
connection to upstream server for services below</p>
<h3>SSL Parameters
<a name="SSL Parameters"></a>
</h3>
<p style="margin-left:6%; margin-top: 1em"><b>ssl_server_cert</b>
<i>/path/to/cert</i> - Server certificate (should not be
self-signed, must contain SAN) for ssl_serv <b><br>
ssl_server_key</b> <i>/path/to/key</i> - Server certificate
key for ssl_server_cert or generated MITM certificate
<b><br>
ssl_client_cert</b> <i>/path/to/cert</i> - Client
certificate for authentication on upstream server (used with
ssl_cli) <b><br>
ssl_client_key</b> <i>/path/to/key</i> - Client certificate
key for ssl_client_cert <b><br>
ssl_client_ciphersuites</b> <i>ciphersuites_list</i> - TLS
client ciphers for TLS 1.3 <b><br>
ssl_server_ciphersuites</b> <i>ciphersuites_list</i> - TLS
server ciphers for TLS 1.3 <b><br>
ssl_client_cipher_list</b> <i>ciphers_list</i> - TLS client
ciphers for TLS 1.2 and below <b><br>
ssl_server_cipher_list</b> <i>ciphers_list</i> - TLS server
ciphers for TLS 1.2 and below <b><br>
ssl_client_min_proto_version</b> <i>tls_version</i> - TLS
client minimum TLS version (e.g., TLSv1.2) <b><br>
ssl_server_min_proto_version</b> <i>tls_version</i> - TLS
server minimum TLS version <b><br>
ssl_client_max_proto_version</b> <i>tls_version</i> - TLS
client maximum TLS version <b><br>
ssl_server_max_proto_version</b> <i>tls_version</i> - TLS
server maximum TLS version <b><br>
ssl_client_verify</b> - verify the certificate for the
upstream server (used with ssl_mitm or ssl_cli) <b><br>
ssl_client_no_verify</b> - do not verify the certificate for
the upstream server (default) <b><br>
ssl_server_verify</b> - require client certificate
authentication (mTLS) for ssl_serv <b><br>
ssl_server_no_verify</b> - do not require client certificate
(default) <b><br>
ssl_server_ca_file</b> <i>/path/to/cafile</i> - CA
certificate file for MITM <b><br>
ssl_server_ca_key</b> <i>/path/to/cakey</i> - key for
ssl_server_ca_file MITM CA <b><br>
ssl_server_ca_dir</b> <i>/path/to/cadir</i> - CA directory
for ssl_server_verify <b><br>
ssl_server_ca_store</b> <i>/path/to/castore</i> - CA store
for ssl_server_verify (OpenSSL 3.0+) <b><br>
ssl_client_ca_file</b> <i>/path/to/cafile</i> - CA file for
ssl_client_verify <b><br>
ssl_client_ca_dir</b> <i>/path/to/cadir</i> - CA directory
for ssl_client_verify <b><br>
ssl_client_ca_store</b> <i>/path/to/castore</i> - CA store
for ssl_client_verify (OpenSSL 3.0+) <b><br>
ssl_client_sni</b> <i>hostname</i> - SNI hostname to send to
upstream server <b><br>
ssl_client_alpn</b> <i>protocol1 protocol2 ...</i> - ALPN
protocols to negotiate with upstream server <b><br>
ssl_client_mode</b> <i>mode</i> - when to establish TLS
connection: 0 - on connect (default), 1 - after
authentication, 2 - before data, 3 - only for secure parent
types (ending with &rsquo;s&rsquo;) <b><br>
ssl_certcache</b> <i>/path/to/cache/</i> - location for the
generated MITM certificates cache</p>
<h2>PCRE FILTERING
<a name="PCRE FILTERING"></a>
</h2>
<p style="margin-left:6%; margin-top: 1em">PCRE (Perl
Compatible Regular Expressions) filtering is built into
3proxy (since 0.9.7) when compiled with PCRE2 support
(WITH_PCRE). Previously available as PCREPlugin, the
functionality is now integrated into the main binary. The
plugin line is no longer required.</p>
<p style="margin-left:6%; margin-top: 1em">PCRE filtering
allows creating matching and replacement rules with regular
expressions for client requests, headers, and data.</p>
<h3>PCRE Commands
<a name="PCRE Commands"></a>
</h3>
<p style="margin-left:6%; margin-top: 1em"><b>pcre</b>
<i>TYPE FILTER_ACTION REGEXP [ACE]</i> <br>
Apply a rule for matching regular expression. <b><br>
pcre_rewrite</b> <i>TYPE FILTER_ACTION REGEXP
REWRITE_EXPRESSION [ACE]</i> <br>
Match and replace with rewrite expression. <b><br>
pcre_extend</b> <i>FILTER_ACTION [ACE]</i> <br>
Extend the ACL of the last pcre or pcre_rewrite command by
adding an additional ACE. <b><br>
pcre_options</b> <i>OPTION1 [OPTION2 ...]</i> <br>
Set matching options. Both PCRE2 native options and PCRE
compatibility options are supported. PCRE options are mapped
to their PCRE2 equivalents for backward compatibility. <br>
PCRE2 options: PCRE2_CASELESS, PCRE2_MULTILINE,
PCRE2_DOTALL, PCRE2_EXTENDED, PCRE2_DOLLAR_ENDONLY,
PCRE2_UNGREEDY, PCRE2_UTF, PCRE2_UCP, PCRE2_NO_AUTO_CAPTURE,
PCRE2_FIRSTLINE, PCRE2_DUPNAMES, PCRE2_MATCH_UNSET_BACKREF,
PCRE2_ALT_BSUX, PCRE2_ALT_CIRCUMFLEX, PCRE2_ALT_VERBNAMES,
PCRE2_USE_OFFSET_LIMIT, PCRE2_EXTENDED_MORE, PCRE2_LITERAL,
PCRE2_MATCH_INVALID_UTF. <br>
PCRE compatibility options: PCRE_CASELESS, PCRE_MULTILINE,
PCRE_DOTALL, PCRE_EXTENDED, PCRE_ANCHORED,
PCRE_DOLLAR_ENDONLY, PCRE_EXTRA, PCRE_NOTBOL, PCRE_NOTEOL,
PCRE_UNGREEDY, PCRE_NOTEMPTY, PCRE_UTF8,
PCRE_NO_AUTO_CAPTURE, PCRE_NO_UTF8_CHECK, PCRE_AUTO_CALLOUT,
PCRE_PARTIAL, PCRE_DFA_SHORTEST, PCRE_DFA_RESTART,
PCRE_FIRSTLINE, PCRE_DUPNAMES, PCRE_NEWLINE_CR,
PCRE_NEWLINE_LF, PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANY,
PCRE_NEWLINE_ANYCRLF, PCRE_BSR_ANYCRLF,
PCRE_BSR_UNICODE.</p>
<h3>PCRE Parameters
<a name="PCRE Parameters"></a>
</h3>
<p style="margin-left:6%; margin-top: 1em">TYPE - type of
filtered data (comma-delimited list): <br>
request - content of the client&rsquo;s request (e.g., HTTP
GET request string) <br>
cliheader - content of the client request headers <br>
srvheader - content of the server&rsquo;s reply headers <br>
clidata - data received from the client (e.g., HTTP POST
data) <br>
srvdata - data received from the server (e.g., HTML
page)</p>
<p style="margin-left:6%; margin-top: 1em">FILTER_ACTION -
action on match: <br>
allow - allow this request without checking the rest of the
rules <br>
deny - deny this request without checking the rest of the
rules <br>
dunno - continue with the rest of the rules (useful with
pcre_rewrite)</p>
<p style="margin-left:6%; margin-top: 1em">REGEXP - PCRE
(Perl) regular expression. Use * if no regexp matching is
required.</p>
<p style="margin-left:6%; margin-top: 1em">REWRITE_EXPRESSION
- substitution string. May contain Perl-style substrings $1,
$2, etc. $0 means the whole matched string. \r and \n may be
used to insert new lines; the string may be empty
(&quot;&quot;).</p>
<p style="margin-left:6%; margin-top: 1em">ACE - access
control entry (user names, source IPs, destination IPs,
ports, etc.), identical to allow/deny/bandlimin commands.
The regular expression is only matched if the ACL matches
the connection data. Warning: Regular expressions
don&rsquo;t require authentication and cannot replace
authentication and/or allow/deny ACLs.</p>
<h2>BUGS
<a name="BUGS"></a>
</h2>

View File

@ -1,10 +1,13 @@
<h3>3proxy PCRE (Perl Compatible Regular Expressions) Filtering</h3>
<h3>3proxy Perl Compatible Regular Expressions (PCRE) Plugin</h3>
<p><b>Note:</b> Since version 0.9.7, PCRE filtering is built into 3proxy and does not require
a separate plugin. All pcre_* commands are available directly when 3proxy is compiled with
PCRE2 support (WITH_PCRE). The plugin line is no longer needed.</p>
This filtering plugin can be used to create matching and replacement
<p>This filtering functionality can be used to create matching and replacement
rules with regular expressions for client requests, client and
server headers, and client and server data. It adds 3 additional
configuration commands:
configuration commands:</p>
<pre>
pcre TYPE FILTER_ACTION REGEXP [ACE]
@ -78,16 +81,10 @@ authentication and/or allow/deny ACLs.
<h4>Example:</h4>
<pre>
plugin PCREPlugin.dll pcre_plugin
pcre request deny "porn|sex" user1,user2,user3 192.168.0.0/16
pcre srvheader deny "Content-type: application"
pcre_rewrite clidata,srvdata dunno "porn|sex|pussy" "***" baduser
pcre_extend deny * 192.168.0.1/16
</pre>
<h4>Download:</h4>
<ul>
<li>Plugin is included in the 3proxy 0.6 binary and source distribution
<li>Example configuration (by Dennis Garber): <A HREF="NoPornLitest.cfg.txt">NoPornLitest.cfg</A>
</li></ul>
&copy; Vladimir Dubrovin, License: BSD style

View File

@ -1,8 +1,12 @@
<h3>Плагин регулярных выражений совместимых с Perl (PCRE) для 3proxy</h3>
<h3>Фильтрация PCRE (Perl Compatible Regular Expressions) в 3proxy</h3>
Фильтрующий плагин используется для создания правил поиска и замены
<p><b>Примечание:</b> Начиная с версии 0.9.7 фильтрация PCRE встроена в 3proxy и не требует
отдельного плагина. Все команды pcre_* доступны напрямую при компиляции 3proxy с поддержкой
PCRE2 (WITH_PCRE). Строка plugin больше не нужна.</p>
<p>Фильтрующий плагин используется для создания правил поиска и замены
регулярных выражений в запросе, заголовков запроса и ответа и данных.
Добавляет поддержку 3х новых команд в файле конфигурации:
Добавляет поддержку 3х новых команд в файле конфигурации:</p>
<pre>
pcre TYPE FILTER_ACTION REGEXP [ACE]
@ -76,15 +80,10 @@ PCRE_BSR_UNICODE
<h4>Пример:</h4>
<pre>
plugin PCREPlugin.dll pcre_plugin
pcre request deny "porn|sex" user1,user2,user3 192.168.0.0/16
pcre srvheader deny "Content-type: application"
pcre_rewrite clidata,srvdata dunno "porn|sex|pussy" "***" baduser
pcre_extend deny * 192.168.0.1/16
</pre>
<h4>Загрузить:</h4>
<ul>
<li>Плагин включен в дистрибутив 3proxy 0.6
<li>Пример конфигурации (by Dennis Garber): <A HREF="NoPornLitest.cfg.txt">NoPornLitest.cfg</A>
</li></ul>
&copy; Vladimir Dubrovin, License: BSD style

View File

@ -1,6 +1,11 @@
<h3>3proxy SSL/TLS Plugin</h3>
<h3>3proxy SSL/TLS Support</h3>
This plugin can be used to transparently decrypt SSL/TLS data, provide TLS encryption for proxy traffic, and authenticate using client certificates.
<p><b>Note:</b> Since version 0.9.7, SSL/TLS support is built into 3proxy and does not require
a separate plugin. All ssl_* commands are available directly when 3proxy is compiled with
OpenSSL support (WITH_SSL). The plugin line is no longer needed.</p>
<p>SSL/TLS support can be used to transparently decrypt SSL/TLS data, provide TLS encryption
for proxy traffic, and authenticate using client certificates.</p>
<h4>For transparent certificate spoofing (MITM):</h4>
@ -55,7 +60,6 @@ Generated certificates are placed in the same path.
<h4>MITM example:</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_server_ca_file /path/to/cafile
ssl_server_ca_key /path/to/cakey
ssl_mitm
@ -67,7 +71,6 @@ MITM's traffic with a spoofed certificate for the port 3128 proxy.
<h4>https:// proxy example:</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_server_cert path_to_cert
ssl_server_key path_to_key
ssl_serv
@ -79,7 +82,6 @@ Creates an https:// proxy on port 33128 and an http:// proxy on port 3128
<h4>TLS client example (connect to upstream via TLS):</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_client_cert /path/to/client.crt
ssl_client_key /path/to/client.key
ssl_client_verify
@ -91,7 +93,6 @@ Creates an HTTP proxy that connects to upstream servers via TLS with client cert
<h4>Conditional TLS for parent proxy (ssl_client_mode 3):</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_server_cert /path/to/server.crt
ssl_server_key /path/to/key
ssl_client_mode 3
@ -111,7 +112,6 @@ Creates an HTTP proxy on port 3128 that uses TLS for client connections (ssl_ser
<h4>mTLS example (require client certificate):</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_server_cert /path/to/server.crt
ssl_server_key /path/to/server.key
ssl_server_ca_file /path/to/ca.crt

View File

@ -1,6 +1,10 @@
<h3>3proxy SSL/TLS плагин</h3>
<h3>3proxy SSL/TLS поддержка</h3>
Плагин можно использовать для перехвата и дешифровки SSL/TLS трафика, для шифрования трафика прокси-сервера и аутентификации с помощью клиентских сертификатов.
<p><b>Примечание:</b> Начиная с версии 0.9.7 поддержка SSL/TLS встроена в 3proxy и не требует
отдельного плагина. Все команды ssl_* доступны напрямую при компиляции 3proxy с поддержкой
OpenSSL (WITH_SSL). Строка plugin больше не нужна.</p>
<p>Плагин можно использовать для перехвата и дешифровки SSL/TLS трафика, для шифрования трафика прокси-сервера и аутентификации с помощью клиентских сертификатов.</p>
<h4>Для прозрачного перехвата трафика (MITM):</h4>
@ -52,7 +56,6 @@ ssl_server_ca_key и ssl_server_key соответственно, если он
<h4>Пример MITM:</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_server_ca_file /path/to/cafile
ssl_server_ca_key /path/to/cakey
ssl_mitm
@ -64,7 +67,6 @@ proxy -p3129
<h4>Пример конфигурации https:// прокси:</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_server_cert path_to_cert
ssl_server_key path_to_key
ssl_serv
@ -76,7 +78,6 @@ proxy -p3128
<h4>Пример TLS-клиента (соединение к вышестоящему серверу через TLS):</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_client_cert /path/to/client.crt
ssl_client_key /path/to/client.key
ssl_client_verify
@ -88,7 +89,6 @@ proxy -p3128
<h4>Условное TLS для parent прокси (ssl_client_mode 3):</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_server_cert /path/to/server.crt
ssl_server_key /path/to/key
ssl_client_mode 3
@ -108,7 +108,6 @@ ssl_nocli
<h4>Пример mTLS (требование клиентского сертификата):</h4>
<pre>
plugin /path/to/SSLPlugin.so ssl_plugin
ssl_server_cert /path/to/server.crt
ssl_server_key /path/to/server.key
ssl_server_ca_file /path/to/ca.crt

View File

@ -1149,6 +1149,203 @@ as
data filtering will be performed through filtering plugins to avoid data
corruption and/or Content-Length changing. Default is 1MB (1048576).
.SH SSL/TLS SUPPORT
SSL/TLS support is built into 3proxy (since 0.9.7) when compiled with OpenSSL
(WITH_SSL). Previously available as SSLPlugin, the functionality is now integrated
into the main binary. The plugin line is no longer required.
SSL/TLS can be used for:
- transparent MITM (Man-in-the-Middle) for TLS traffic inspection
- https:// proxy (TLS-encrypted connection between client and proxy)
- TLS client connections to upstream servers with certificate authentication
- mTLS (mutual TLS) requiring client certificates
.SS MITM Commands
.br
.BR ssl_mitm
- spoof certificates for services started below. Usage without ssl_client_verify is insecure.
.br
.BR ssl_nomitm
- do not spoof certificates for services started below
.SS Server TLS Commands
.br
.BR ssl_serv
(or ssl_server) - require TLS connection from clients for services below
.br
.BR ssl_noserv
(or ssl_noserver) - do not require TLS connection from clients for services below
.SS Client TLS Commands
.br
.BR ssl_cli
(or ssl_client) - establish TLS connection to upstream server for services below
.br
.BR ssl_nocli
(or ssl_noclient) - do not establish TLS connection to upstream server for services below
.SS SSL Parameters
.br
.BR ssl_server_cert
\fI/path/to/cert\fR - Server certificate (should not be self-signed, must contain SAN) for ssl_serv
.br
.BR ssl_server_key
\fI/path/to/key\fR - Server certificate key for ssl_server_cert or generated MITM certificate
.br
.BR ssl_client_cert
\fI/path/to/cert\fR - Client certificate for authentication on upstream server (used with ssl_cli)
.br
.BR ssl_client_key
\fI/path/to/key\fR - Client certificate key for ssl_client_cert
.br
.BR ssl_client_ciphersuites
\fIciphersuites_list\fR - TLS client ciphers for TLS 1.3
.br
.BR ssl_server_ciphersuites
\fIciphersuites_list\fR - TLS server ciphers for TLS 1.3
.br
.BR ssl_client_cipher_list
\fIciphers_list\fR - TLS client ciphers for TLS 1.2 and below
.br
.BR ssl_server_cipher_list
\fIciphers_list\fR - TLS server ciphers for TLS 1.2 and below
.br
.BR ssl_client_min_proto_version
\fItls_version\fR - TLS client minimum TLS version (e.g., TLSv1.2)
.br
.BR ssl_server_min_proto_version
\fItls_version\fR - TLS server minimum TLS version
.br
.BR ssl_client_max_proto_version
\fItls_version\fR - TLS client maximum TLS version
.br
.BR ssl_server_max_proto_version
\fItls_version\fR - TLS server maximum TLS version
.br
.BR ssl_client_verify
- verify the certificate for the upstream server (used with ssl_mitm or ssl_cli)
.br
.BR ssl_client_no_verify
- do not verify the certificate for the upstream server (default)
.br
.BR ssl_server_verify
- require client certificate authentication (mTLS) for ssl_serv
.br
.BR ssl_server_no_verify
- do not require client certificate (default)
.br
.BR ssl_server_ca_file
\fI/path/to/cafile\fR - CA certificate file for MITM
.br
.BR ssl_server_ca_key
\fI/path/to/cakey\fR - key for ssl_server_ca_file MITM CA
.br
.BR ssl_server_ca_dir
\fI/path/to/cadir\fR - CA directory for ssl_server_verify
.br
.BR ssl_server_ca_store
\fI/path/to/castore\fR - CA store for ssl_server_verify (OpenSSL 3.0+)
.br
.BR ssl_client_ca_file
\fI/path/to/cafile\fR - CA file for ssl_client_verify
.br
.BR ssl_client_ca_dir
\fI/path/to/cadir\fR - CA directory for ssl_client_verify
.br
.BR ssl_client_ca_store
\fI/path/to/castore\fR - CA store for ssl_client_verify (OpenSSL 3.0+)
.br
.BR ssl_client_sni
\fIhostname\fR - SNI hostname to send to upstream server
.br
.BR ssl_client_alpn
\fIprotocol1 protocol2 ...\fR - ALPN protocols to negotiate with upstream server
.br
.BR ssl_client_mode
\fImode\fR - when to establish TLS connection: 0 - on connect (default), 1 - after authentication, 2 - before data, 3 - only for secure parent types (ending with 's')
.br
.BR ssl_certcache
\fI/path/to/cache/\fR - location for the generated MITM certificates cache
.SH PCRE FILTERING
PCRE (Perl Compatible Regular Expressions) filtering is built into 3proxy
(since 0.9.7) when compiled with PCRE2 support (WITH_PCRE). Previously
available as PCREPlugin, the functionality is now integrated into the main
binary. The plugin line is no longer required.
PCRE filtering allows creating matching and replacement rules with regular
expressions for client requests, headers, and data.
.SS PCRE Commands
.br
.BR pcre
\fITYPE FILTER_ACTION REGEXP [ACE]\fR
.br
Apply a rule for matching regular expression.
.br
.BR pcre_rewrite
\fITYPE FILTER_ACTION REGEXP REWRITE_EXPRESSION [ACE]\fR
.br
Match and replace with rewrite expression.
.br
.BR pcre_extend
\fIFILTER_ACTION [ACE]\fR
.br
Extend the ACL of the last pcre or pcre_rewrite command by adding an additional ACE.
.br
.BR pcre_options
\fIOPTION1 [OPTION2 ...]\fR
.br
Set matching options. Both PCRE2 native options and PCRE compatibility options
are supported. PCRE options are mapped to their PCRE2 equivalents for backward
compatibility.
.br
PCRE2 options: PCRE2_CASELESS, PCRE2_MULTILINE, PCRE2_DOTALL, PCRE2_EXTENDED,
PCRE2_DOLLAR_ENDONLY, PCRE2_UNGREEDY, PCRE2_UTF, PCRE2_UCP, PCRE2_NO_AUTO_CAPTURE,
PCRE2_FIRSTLINE, PCRE2_DUPNAMES, PCRE2_MATCH_UNSET_BACKREF, PCRE2_ALT_BSUX,
PCRE2_ALT_CIRCUMFLEX, PCRE2_ALT_VERBNAMES, PCRE2_USE_OFFSET_LIMIT, PCRE2_EXTENDED_MORE,
PCRE2_LITERAL, PCRE2_MATCH_INVALID_UTF.
.br
PCRE compatibility options: PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, PCRE_EXTENDED,
PCRE_ANCHORED, PCRE_DOLLAR_ENDONLY, PCRE_EXTRA, PCRE_NOTBOL, PCRE_NOTEOL, PCRE_UNGREEDY,
PCRE_NOTEMPTY, PCRE_UTF8, PCRE_NO_AUTO_CAPTURE, PCRE_NO_UTF8_CHECK, PCRE_AUTO_CALLOUT,
PCRE_PARTIAL, PCRE_DFA_SHORTEST, PCRE_DFA_RESTART, PCRE_FIRSTLINE, PCRE_DUPNAMES,
PCRE_NEWLINE_CR, PCRE_NEWLINE_LF, PCRE_NEWLINE_CRLF, PCRE_NEWLINE_ANY, PCRE_NEWLINE_ANYCRLF,
PCRE_BSR_ANYCRLF, PCRE_BSR_UNICODE.
.SS PCRE Parameters
TYPE - type of filtered data (comma-delimited list):
.br
request - content of the client's request (e.g., HTTP GET request string)
.br
cliheader - content of the client request headers
.br
srvheader - content of the server's reply headers
.br
clidata - data received from the client (e.g., HTTP POST data)
.br
srvdata - data received from the server (e.g., HTML page)
FILTER_ACTION - action on match:
.br
allow - allow this request without checking the rest of the rules
.br
deny - deny this request without checking the rest of the rules
.br
dunno - continue with the rest of the rules (useful with pcre_rewrite)
REGEXP - PCRE (Perl) regular expression. Use * if no regexp matching is required.
REWRITE_EXPRESSION - substitution string. May contain Perl-style substrings
$1, $2, etc. $0 means the whole matched string. \er and \en may be used
to insert new lines; the string may be empty ("").
ACE - access control entry (user names, source IPs, destination IPs, ports, etc.),
identical to allow/deny/bandlimin commands. The regular expression is only
matched if the ACL matches the connection data.
Warning: Regular expressions don't require authentication and cannot replace
authentication and/or allow/deny ACLs.
.SH BUGS
Report all bugs to
.BR 3proxy@3proxy.org

View File

@ -7,6 +7,12 @@
*/
#include "proxy.h"
#ifdef WITH_SSL
void ssl_install(void);
#endif
#ifdef WITH_PCRE
void pcre_install(void);
#endif
#ifndef _WIN32
#include <sys/resource.h>
#ifndef NOPLUGINS
@ -523,6 +529,13 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
_3proxy_mutex_init(&conf.threadinit);
#endif
#ifdef WITH_SSL
ssl_install();
#endif
#ifdef WITH_PCRE
pcre_install();
#endif
freeconf(&conf);
res = readconfig(fp);
conf.version++;

View File

@ -5,11 +5,13 @@
please read License Agreement
*/
#include "blake2_compat.h"
#ifdef WITH_SSL
#include <openssl/evp.h>
#ifndef WITHMAIN
#include "libs/md5.h"
/* MD5 needed for $1$ crypt */
#endif
#endif
#include "libs/md4.h"
#include "libs/blake2.h"
#include <string.h>
#define MD5_SIZE 16
@ -24,6 +26,12 @@ void tohex(unsigned char *in, unsigned char *out, int len);
static unsigned char itoa64[] =
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
#if defined(WITH_SSL)
EVP_MD *md4 = NULL;
EVP_MD *md5 = NULL;
#endif
void
_crypt_to64(unsigned char *s, unsigned long v, int n)
{
@ -34,11 +42,13 @@ _crypt_to64(unsigned char *s, unsigned long v, int n)
}
#ifdef WITH_SSL
unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPassword, int ctohex)
{
unsigned char szUnicodePass[513];
unsigned int nPasswordLen;
MD4_CTX ctx;
EVP_MD_CTX *ctx;
unsigned int len=sizeof(szUnicodePass);
unsigned int i;
/*
@ -53,15 +63,20 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
}
/* Encrypt Unicode password to a 16-byte MD4 hash */
MD4Init(&ctx);
MD4Update(&ctx, szUnicodePass, (nPasswordLen<<1));
MD4Final(szUnicodePass, &ctx);
ctx = EVP_MD_CTX_new();
if(!EVP_DigestInit_ex(ctx, md4, NULL)){
fprintf(stderr, "Failed to init MD4 digest\n");
}
EVP_DigestUpdate(ctx, szUnicodePass, (nPasswordLen<<1));
EVP_DigestFinal_ex(ctx, szUnicodePass, &len);
EVP_MD_CTX_free(ctx);
if (ctohex){
tohex(szUnicodePass, szHash, 16);
}
else memcpy(szHash, szUnicodePass, 16);
return szHash;
}
#endif
unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsigned char *passwd){
@ -74,34 +89,38 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
int sl;
unsigned long l;
#ifndef WITHMAIN
#if defined(WITH_SSL)
if(salt[0] == '$' && salt[1] == '1' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
MD5_CTX ctx,ctx1;
EVP_MD_CTX *ctx, *ctx1;
unsigned int len;
int pl, i;
sp = salt +3;
sl = (int)(ep - sp);
magic = (unsigned char *)"$1$";
MD5Init(&ctx);
ctx = EVP_MD_CTX_new();
EVP_DigestInit_ex(ctx, md5, NULL);
/* The password first, since that is what is most unknown */
MD5Update(&ctx,pw,strlen((char *)pw));
EVP_DigestUpdate(ctx,pw,strlen((char *)pw));
/* Then our magic string */
MD5Update(&ctx,magic,strlen((char *)magic));
EVP_DigestUpdate(ctx,magic,strlen((char *)magic));
/* Then the raw salt */
MD5Update(&ctx,sp,sl);
EVP_DigestUpdate(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);
ctx1 = EVP_MD_CTX_new();
EVP_DigestInit_ex(ctx1, EVP_md5(), NULL);
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
EVP_DigestUpdate(ctx1,sp,sl);
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
EVP_DigestFinal_ex(ctx1,final,&len);
EVP_MD_CTX_free(ctx1);
for(pl = (int)strlen((char *)pw); pl > 0; pl -= MD5_SIZE)
MD5Update(&ctx,final,pl>MD5_SIZE ? MD5_SIZE : pl);
EVP_DigestUpdate(ctx,final,pl>MD5_SIZE ? MD5_SIZE : pl);
/* Don't leave anything around in vm they could use. */
memset(final,0,sizeof final);
@ -109,12 +128,13 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
/* Then something really weird... */
for (i = (int)strlen((char *)pw); i ; i >>= 1)
if(i&1)
MD5Update(&ctx, final, 1);
EVP_DigestUpdate(ctx, final, 1);
else
MD5Update(&ctx, pw, 1);
EVP_DigestUpdate(ctx, pw, 1);
MD5Final(final,&ctx);
EVP_DigestFinal_ex(ctx,final,&len);
EVP_MD_CTX_free(ctx);
/*
* and now, just to make sure things don't run too fast
@ -122,23 +142,25 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
* need 30 seconds to build a 1000 entry dictionary...
*/
for(i=0;i<1000;i++) {
MD5Init(&ctx1);
ctx1 = EVP_MD_CTX_new();
EVP_DigestInit_ex(ctx1, md5, NULL);
if(i & 1)
MD5Update(&ctx1,pw,strlen((char *)pw));
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
else
MD5Update(&ctx1,final,MD5_SIZE);
EVP_DigestUpdate(ctx1,final,MD5_SIZE);
if(i % 3)
MD5Update(&ctx1,sp,sl);
EVP_DigestUpdate(ctx1,sp,sl);
if(i % 7)
MD5Update(&ctx1,pw,strlen((char *)pw));
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
if(i & 1)
MD5Update(&ctx1,final,MD5_SIZE);
EVP_DigestUpdate(ctx1,final,MD5_SIZE);
else
MD5Update(&ctx1,pw,strlen((char *)pw));
MD5Final(final,&ctx1);
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
EVP_DigestFinal_ex(ctx1,final,&len);
EVP_MD_CTX_free(ctx1);
}
@ -151,7 +173,13 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
sp = salt +3;
sl = (int)(ep - sp);
magic = (unsigned char *)"$3$";
blake2b(final, MD5_SIZE, pw, strlen((char *)pw), sp, sl);
{
blake2b_state S;
blake2b_init(&S, MD5_SIZE);
blake2b_update(&S, pw, strlen((char *)pw) + 1);
blake2b_update(&S, sp, sl);
blake2b_final(&S, final, MD5_SIZE);
}
}
else {
*passwd = 0;
@ -180,25 +208,55 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
}
#ifdef WITHMAIN
#ifdef WITH_SSL
OSSL_LIB_CTX *library_ctx = NULL;
#include <openssl/provider.h>
#endif
#include <stdio.h>
int main(int argc, char* argv[]){
unsigned char buf[1024];
unsigned i;
if(argc < 2 || argc > 3) {
fprintf(stderr, "usage: \n"
#ifdef WITH_SSL
"\t%s <password>\n"
#endif
"\t%s <salt> <password>\n"
#ifdef WITH_SSL
"Performs NT crypt if no salt specified, BLAKE2 crypt with salt\n"
#else
"Performs BLAKE2 crypt with salt\n"
#endif
"This software uses:\n"
" RSA Data Security, Inc. MD4 Message-Digest Algorithm\n"
" RSA Data Security, Inc. MD5 Message-Digest Algorithm\n",
#ifdef WITH_SSL
" OpenSSL EVP (MD4, MD5, BLAKE2b)\n"
#else
" BLAKE2 reference implementation\n"
#endif
,
argv[0],
argv[0]);
return 1;
}
#ifdef WITH_SSL
library_ctx = OSSL_LIB_CTX_new();
OSSL_PROVIDER_load(library_ctx, "legacy");
OSSL_PROVIDER_load(library_ctx, "default");
md4 = EVP_MD_fetch(library_ctx, "MD4", NULL);
if (md4 == NULL) {
fprintf(stderr, "Error fetching MD4\n");
}
md5 = EVP_MD_fetch(library_ctx, "MD5", NULL);
if (md5 == NULL) {
fprintf(stderr, "Error fetching MD5\n");
}
#endif
if(argc == 2) {
#ifdef WITH_SSL
printf("NT:%s\n", ntpwdhash(buf, (unsigned char *)argv[1], 1));
#else
fprintf(stderr, "NT crypt not available (compiled without OpenSSL)\n");
#endif
}
else {
i = (int)strlen((char *)argv[1]);

View File

@ -7,6 +7,9 @@ all: $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS)
sockmap$(OBJSUFFICS): sockmap.c proxy.h structures.h
$(CC) $(CFLAGS) sockmap.c
udpsockmap$(OBJSUFFICS): udpsockmap.c proxy.h structures.h
$(CC) $(COUT)udpsockmap$(OBJSUFFICS) $(CFLAGS) udpsockmap.c
common$(OBJSUFFICS): common.c proxy.h structures.h
$(CC) $(CFLAGS) common.c
@ -65,14 +68,14 @@ $(BUILDDIR)$(PREFIX)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS)
$(BUILDDIR)$(PREFIX)ftppr$(EXESUFFICS): sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) ftp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) $(COMPATLIBS)
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)ftppr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) ftppr$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) ftp$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
$(BUILDDIR)$(PREFIX)socks$(EXESUFFICS): sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)socks$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)$(PREFIX)socks$(EXESUFFICS): sockmap$(OBJSUFFICS) udpsockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)socks$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) udpsockmap$(OBJSUFFICS) socks$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)$(PREFIX)tcppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)tcppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tcppm$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)$(PREFIX)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) hash$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)udppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) hash$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)$(PREFIX)udppm$(EXESUFFICS): sockmap$(OBJSUFFICS) udpsockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) hash$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)udppm$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) udpsockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) udppm$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) hash$(OBJSUFFICS) $(LIBS)
$(BUILDDIR)$(PREFIX)tlspr$(EXESUFFICS): sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tlspr$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)tlspr$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) tlspr$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(LIBS)
@ -152,21 +155,24 @@ datatypes$(OBJSUFFICS): datatypes.c proxy.h structures.h
3proxy_cryptmain$(OBJSUFFICS): 3proxy_crypt.c
$(CC) $(COUT)3proxy_cryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN 3proxy_crypt.c
md4$(OBJSUFFICS): libs/md4.h libs/md4.c
$(CC) $(COUT)md4$(OBJSUFFICS) $(CFLAGS) libs/md4.c
md5$(OBJSUFFICS): libs/md5.h libs/md5.c
$(CC) $(COUT)md5$(OBJSUFFICS) $(CFLAGS) libs/md5.c
blake2$(OBJSUFFICS): libs/blake2.h libs/blake2-impl.h libs/blake2b-ref.c
$(CC) $(COUT)blake2$(OBJSUFFICS) $(CFLAGS) libs/blake2b-ref.c
$(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS): md4$(OBJSUFFICS) blake2$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) base64$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS) $(LDFLAGS) md4$(OBJSUFFICS) blake2$(OBJSUFFICS) base64$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS)
$(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS): blake2$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) base64$(OBJSUFFICS)
$(LN) $(LNOUT)$(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS) $(LDFLAGS) blake2$(OBJSUFFICS) base64$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) $(LIBS)
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) srvtlspr$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) acl$(OBJSUFFICS) limiter$(OBJSUFFICS) redirect$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) hashtables$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) 3proxy_crypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(VERSIONDEP)
$(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) acl$(OBJSUFFICS) limiter$(OBJSUFFICS) redirect$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) hashtables$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) 3proxy_crypt$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) md4$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
ssllib$(OBJSUFFICS): ssllib.c
$(CC) $(COUT)ssllib$(OBJSUFFICS) $(CFLAGS) ssllib.c
ssl$(OBJSUFFICS): ssl.c
$(CC) $(COUT)ssl$(OBJSUFFICS) $(CFLAGS) ssl.c
pcre$(OBJSUFFICS): pcre.c
$(CC) $(COUT)pcre$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITH_PCRE pcre.c
$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) udpsockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) auth$(OBJSUFFICS) acl$(OBJSUFFICS) limiter$(OBJSUFFICS) redirect$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) hashtables$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) log$(OBJSUFFICS) datatypes$(OBJSUFFICS) blake2$(OBJSUFFICS) 3proxy_crypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(SSL_OBJS) $(PCRE_OBJS) $(COMPATLIBS) $(VERSIONDEP)
$(LN) $(LNOUT)$(BUILDDIR)3proxy$(EXESUFFICS) $(LDFLAGS) $(VERFILE) 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) auth$(OBJSUFFICS) acl$(OBJSUFFICS) limiter$(OBJSUFFICS) redirect$(OBJSUFFICS) authradius$(OBJSUFFICS) hash$(OBJSUFFICS) hashtables$(OBJSUFFICS) resolve$(OBJSUFFICS) sql$(OBJSUFFICS) conf$(OBJSUFFICS) datatypes$(OBJSUFFICS) srvauto$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvsmtpp$(OBJSUFFICS) srvftppr$(OBJSUFFICS) srvsocks$(OBJSUFFICS) srvtcppm$(OBJSUFFICS) srvtlspr$(OBJSUFFICS) srvudppm$(OBJSUFFICS) sockmap$(OBJSUFFICS) udpsockmap$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) 3proxy_crypt$(OBJSUFFICS) blake2$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) $(SSL_OBJS) $(PCRE_OBJS) $(COMPATLIBS) $(LIBS) $(PCRE_LIBS)

View File

@ -223,8 +223,10 @@ int strongauth(struct clientparam * param){
if (!param->pwtype && param->password) {
if (pw_table.ihashtable && hashresolv(&pw_table, param, &dummy, NULL))
return 0;
#ifdef WITH_SSL
if (pwnt_table.ihashtable && hashresolv(&pwnt_table, param, &dummy, NULL))
return 0;
#endif
#ifndef NOCRYPT
if (pwcr_table.ihashtable && hashresolv(&pwcr_table, param, cryptpw, NULL)) {
if (!strcmp(cryptpw, (char *)mycrypt(param->password, (unsigned char *)cryptpw, buf)))

View File

@ -8,7 +8,7 @@
#ifndef NORADIUS
#include "proxy.h"
#include "libs/md5.h"
#include <openssl/evp.h>
#define AUTH_VECTOR_LEN 16
#define MAX_STRING_LEN 254
@ -183,14 +183,19 @@ char *strNcpy(char *dest, const char *src, int n)
return dest;
}
extern EVP_MD *md4;
extern EVP_MD *md5;
void md5_calc(unsigned char *output, unsigned char *input,
unsigned int inlen)
{
MD5_CTX context;
MD5Init(&context);
MD5Update(&context, input, inlen);
MD5Final(output, &context);
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
unsigned int len = 0;
EVP_DigestInit_ex(ctx, md5, NULL);
EVP_DigestUpdate(ctx, input, inlen);
EVP_DigestFinal_ex(ctx, output, &len);
EVP_MD_CTX_free(ctx);
}

76
src/blake2_compat.h Normal file
View File

@ -0,0 +1,76 @@
#ifndef BLAKE2_COMPAT_H
#define BLAKE2_COMPAT_H
#if defined(WITH_SSL)
#include <openssl/opensslv.h>
#endif
#if defined(WITH_SSL) && OPENSSL_VERSION_NUMBER >= 0x10100000L
#include <openssl/evp.h>
#include <string.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#include <openssl/params.h>
#include <openssl/core_names.h>
#endif
/*
* OpenSSL 1.1.0+ BLAKE2b implementation.
* Provides the same streaming API as libs/blake2.h but uses EVP internally.
*
* OpenSSL 3.0+: uses OSSL_DIGEST_PARAM_SIZE for proper custom output sizes.
* OpenSSL 1.1.x: computes full 64-byte output and truncates in blake2b_final.
*/
typedef EVP_MD_CTX *blake2b_state;
static int blake2b_init(blake2b_state *S, size_t outlen) {
*S = EVP_MD_CTX_new();
if (!*S) return -1;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
size_t sz = outlen;
OSSL_PARAM params[2];
params[0] = OSSL_PARAM_construct_size_t(OSSL_DIGEST_PARAM_SIZE, &sz);
params[1] = OSSL_PARAM_construct_end();
if (!EVP_DigestInit_ex2(*S, EVP_blake2b512(), params)) {
#else
(void)outlen;
if (!EVP_DigestInit_ex(*S, EVP_blake2b512(), NULL)) {
#endif
EVP_MD_CTX_free(*S);
*S = NULL;
return -1;
}
return 0;
}
static int blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
if (inlen == 0) return 0;
return EVP_DigestUpdate(*S, in, inlen) ? 0 : -1;
}
static int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
unsigned int len = 0;
int ret = EVP_DigestFinal_ex(*S, out, &len) ? 0 : -1;
#else
unsigned char tmp[64];
unsigned int len = 0;
int ret = EVP_DigestFinal_ex(*S, tmp, &len) ? 0 : -1;
if (ret == 0) memcpy(out, tmp, outlen);
#endif
EVP_MD_CTX_free(*S);
*S = NULL;
return ret;
}
#else
#include "libs/blake2.h"
#endif
#endif /* BLAKE2_COMPAT_H */

View File

@ -7,6 +7,12 @@
*/
#include "proxy.h"
#ifdef WITH_SSL
void ssl_install(void);
#endif
#ifdef WITH_PCRE
void pcre_install(void);
#endif
#ifndef _WIN32
#include <sys/resource.h>
#include <pwd.h>
@ -526,9 +532,11 @@ static int h_users(int argc, unsigned char **argv){
if (arg[1] && arg[2] && arg[3] == ':') {
pw[1] = (char *)(arg + 4);
if (arg[1] == 'N' && arg[2] == 'T') {
#ifdef WITH_SSL
if (!pwnt_table.ihashtable && inithashtable(&pwnt_table, 16, 32, 1048576))
return 3;
hashadd(&pwnt_table, pw, &dummy, MAX_COUNTER_TIME);
#endif
continue;
}
if (arg[1] == 'C' && arg[2] == 'R') {
@ -1447,6 +1455,16 @@ static int h_authcache(int argc, unsigned char **argv){
}
static int h_plugin(int argc, unsigned char **argv){
#ifdef WITH_SSL
if(argc >= 3 && !strcmp((char *)argv[2], "ssl_plugin")){
return 0;
}
#endif
#ifdef WITH_PCRE
if(argc >= 3 && !strcmp((char *)argv[2], "pcre_plugin")){
return 0;
}
#endif
#ifdef NOPLUGINS
return 999;
#else
@ -1875,7 +1893,9 @@ void freeconf(struct extparam *confp){
_3proxy_mutex_unlock(&connlim_mutex);
destroyhashtable(&pw_table);
#ifdef WITH_SSL
destroyhashtable(&pwnt_table);
#endif
destroyhashtable(&pwcr_table);
confp->logfunc = lognone;
@ -1946,6 +1966,12 @@ int reload (void){
int error = -2;
_3proxy_mutex_lock(&config_mutex);
#ifdef WITH_SSL
ssl_install();
#endif
#ifdef WITH_PCRE
pcre_install();
#endif
conf.paused++;
freeconf(&conf);
conf.paused++;

View File

@ -1,11 +1,13 @@
#include "proxy.h"
#include "libs/blake2.h"
#include "blake2_compat.h"
static void char_index2hash(const struct hashtable *ht, void *index, uint8_t *hash){
char* name = index;
blake2b_state S;
blake2b(hash, ht->hash_size, index, strlen((const char*)index), NULL, 0);
blake2b_init(&S, ht->hash_size);
blake2b_update(&S, index, strlen((const char*)index) + 1);
blake2b_final(&S, hash, ht->hash_size);
}
static void param2hash_add(const struct hashtable *ht, void *index, uint8_t *hash){
@ -36,7 +38,11 @@ void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
static void user2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
struct clientparam *param = (struct clientparam *)index;
blake2b(hash, ht->hash_size, param->username, strlen((const char *)param->username), NULL, 0);
blake2b_state S;
blake2b_init(&S, ht->hash_size);
blake2b_update(&S, param->username, strlen((const char *)param->username) + 1);
blake2b_final(&S, hash, ht->hash_size);
}
static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash){
@ -80,6 +86,7 @@ static void pwnt2hash_add(const struct hashtable *ht, void *index, uint8_t *hash
}
#ifdef WITH_SSL
static void pwnt2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
struct clientparam *param = (struct clientparam *)index;
unsigned char pass[40];
@ -88,6 +95,7 @@ static void pwnt2hash_search(const struct hashtable *ht, void *index, uint8_t *h
ntpwdhash(pass, param->password, 1);
pwnt2hash_add(ht, pw, hash);
}
#endif
@ -95,5 +103,7 @@ struct hashtable dns_table = {char_index2hash, char_index2hash, 4, 12};
struct hashtable dns6_table = {char_index2hash, char_index2hash, 16, 12};
struct hashtable auth_table = {param2hash_add, param2hash_search, sizeof(struct authcache), 12};
struct hashtable pw_table = {pw2hash_add, pw2hash_search, 0, 12};
#ifdef WITH_SSL
struct hashtable pwnt_table = {pwnt2hash_add, pwnt2hash_search, 0, 12};
#endif
struct hashtable pwcr_table = {char_index2hash, user2hash_search, 64, 12};

View File

@ -1,290 +0,0 @@
/*
* md4c.c MD4 message-digest algorithm
*
* License to copy and use this software is granted provided that it
* is identified as the "RSA Data Security, Inc. MD4 Message-Digest
* Algorithm" in all material mentioning or referencing this software
* or this function.
*
* License is also granted to make and use derivative works provided
* that such works are identified as "derived from the RSA Data
* Security, Inc. MD4 Message-Digest Algorithm" in all material
* mentioning or referencing the derived work.
*
* RSA Data Security, Inc. makes no representations concerning either
* the merchantability of this software or the suitability of this
* software for any particular purpose. It is provided "as is"
* without express or implied warranty of any kind.
*
* These notices must be retained in any copies of any part of this
* documentation and/or software.
*
* Copyright 1990,1991,1992 RSA Data Security, Inc.
*/
#include "md4.h"
/* Constants for MD4Transform routine.
*/
#define S11 3
#define S12 7
#define S13 11
#define S14 19
#define S21 3
#define S22 5
#define S23 9
#define S24 13
#define S31 3
#define S32 9
#define S33 11
#define S34 15
static void MD4Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, unsigned char *, unsigned int));
static void MD4_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
static void MD4_memset PROTO_LIST ((POINTER, int, unsigned int));
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G and H are basic MD4 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
/* Rotation is separate from addition to prevent recomputation */
#define FF(a, b, c, d, x, s) { \
(a) += F ((b), (c), (d)) + (x); \
(a) = ROTATE_LEFT ((a), (s)); \
}
#define GG(a, b, c, d, x, s) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
(a) = ROTATE_LEFT ((a), (s)); \
}
#define HH(a, b, c, d, x, s) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
(a) = ROTATE_LEFT ((a), (s)); \
}
void md4_calc(unsigned char *output, unsigned char *input, unsigned inlen)
{
MD4_CTX context;
MD4Init(&context);
MD4Update(&context, input, inlen);
MD4Final(output, &context);
}
/* MD4 initialization. Begins an MD4 operation, writing a new context.
*/
void MD4Init ( MD4_CTX *context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD4 block update operation. Continues an MD4 message-digest
operation, processing another message block, and updating the
context.
*/
void MD4Update (MD4_CTX *context, unsigned char *input, unsigned inputLen)
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD4_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD4Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD4Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD4_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD4 finalization. Ends an MD4 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD4Final (unsigned char digest[16], MD4_CTX *context)
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD4Update (context, PADDING, padLen);
/* Append length (before padding) */
MD4Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD4_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD4 basic transformation. Transforms state based on block.
*/
static void MD4Transform (UINT4 state[4], unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11); /* 1 */
FF (d, a, b, c, x[ 1], S12); /* 2 */
FF (c, d, a, b, x[ 2], S13); /* 3 */
FF (b, c, d, a, x[ 3], S14); /* 4 */
FF (a, b, c, d, x[ 4], S11); /* 5 */
FF (d, a, b, c, x[ 5], S12); /* 6 */
FF (c, d, a, b, x[ 6], S13); /* 7 */
FF (b, c, d, a, x[ 7], S14); /* 8 */
FF (a, b, c, d, x[ 8], S11); /* 9 */
FF (d, a, b, c, x[ 9], S12); /* 10 */
FF (c, d, a, b, x[10], S13); /* 11 */
FF (b, c, d, a, x[11], S14); /* 12 */
FF (a, b, c, d, x[12], S11); /* 13 */
FF (d, a, b, c, x[13], S12); /* 14 */
FF (c, d, a, b, x[14], S13); /* 15 */
FF (b, c, d, a, x[15], S14); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 0], S21); /* 17 */
GG (d, a, b, c, x[ 4], S22); /* 18 */
GG (c, d, a, b, x[ 8], S23); /* 19 */
GG (b, c, d, a, x[12], S24); /* 20 */
GG (a, b, c, d, x[ 1], S21); /* 21 */
GG (d, a, b, c, x[ 5], S22); /* 22 */
GG (c, d, a, b, x[ 9], S23); /* 23 */
GG (b, c, d, a, x[13], S24); /* 24 */
GG (a, b, c, d, x[ 2], S21); /* 25 */
GG (d, a, b, c, x[ 6], S22); /* 26 */
GG (c, d, a, b, x[10], S23); /* 27 */
GG (b, c, d, a, x[14], S24); /* 28 */
GG (a, b, c, d, x[ 3], S21); /* 29 */
GG (d, a, b, c, x[ 7], S22); /* 30 */
GG (c, d, a, b, x[11], S23); /* 31 */
GG (b, c, d, a, x[15], S24); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 0], S31); /* 33 */
HH (d, a, b, c, x[ 8], S32); /* 34 */
HH (c, d, a, b, x[ 4], S33); /* 35 */
HH (b, c, d, a, x[12], S34); /* 36 */
HH (a, b, c, d, x[ 2], S31); /* 37 */
HH (d, a, b, c, x[10], S32); /* 38 */
HH (c, d, a, b, x[ 6], S33); /* 39 */
HH (b, c, d, a, x[14], S34); /* 40 */
HH (a, b, c, d, x[ 1], S31); /* 41 */
HH (d, a, b, c, x[ 9], S32); /* 42 */
HH (c, d, a, b, x[ 5], S33); /* 43 */
HH (b, c, d, a, x[13], S34); /* 44 */
HH (a, b, c, d, x[ 3], S31); /* 45 */
HH (d, a, b, c, x[11], S32); /* 46 */
HH (c, d, a, b, x[ 7], S33); /* 47 */
HH (b, c, d, a, x[15], S34); /* 48 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD4_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (unsigned char *output, UINT4 *input, unsigned len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (UINT4 *output, unsigned char *input, unsigned len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD4_memcpy (POINTER output, POINTER input, unsigned len)
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD4_memset (POINTER output, int value, unsigned len)
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}

View File

@ -1,83 +0,0 @@
#ifndef _LRAD_MD4_H
#define _LRAD_MD4_H
#ifndef _LRAD_PROTO_H
#define _LRAD_PROTO_H
/* GLOBAL.H - RSAREF types and constants
*/
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
# if __STDC__
# define PROTOTYPES 1
# else
# define PROTOTYPES 0
# endif
#endif
/* POINTER defines a generic pointer type */
typedef unsigned char *POINTER;
#define _POINTER_T
/* UINT2 defines a two byte word */
typedef unsigned short int UINT2;
#define _UINT2_T
/* UINT4 defines a four byte word */
typedef unsigned int UINT4;
#define _UINT4_T
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif
#endif /* _LRAD_PROTO_H */
/* MD4.H - header file for MD4C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD4 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD4 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* MD4 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD4_CTX;
void md4_calc (unsigned char *, unsigned char *, unsigned int);
void MD4Init PROTO_LIST ((MD4_CTX *));
void MD4Update PROTO_LIST
((MD4_CTX *, unsigned char *, unsigned int));
void MD4Final PROTO_LIST ((unsigned char [16], MD4_CTX *));
#endif /* _LRAD_MD4_H */

View File

@ -1,325 +0,0 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
void librad_md5_calc(unsigned char *output, unsigned char *input,
unsigned int inputlen);
static void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64]));
static void Encode PROTO_LIST
((unsigned char *, UINT4 *, unsigned int));
static void Decode PROTO_LIST
((UINT4 *, const unsigned char *, unsigned int));
static void MD5_memcpy PROTO_LIST ((POINTER, CONSTPOINTER, unsigned int));
static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
static const unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
void librad_md5_calc(unsigned char *output, unsigned char *input,
unsigned int inlen)
{
MD5_CTX context;
MD5Init(&context);
MD5Update(&context, input, inlen);
MD5Final(output, &context);
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (MD5_CTX *context)
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (MD5_CTX *context, const unsigned char *input, unsigned inputLen)
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (CONSTPOINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (CONSTPOINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (unsigned char digest[16], MD5_CTX *context)
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (UINT4 state[4], const unsigned char block[64])
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (unsigned char *output, UINT4 *input, unsigned len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (UINT4 *output, const unsigned char *input, unsigned len)
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (POINTER output, CONSTPOINTER input, unsigned len)
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (POINTER output, int value, unsigned len)
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}

View File

@ -1,94 +0,0 @@
#ifndef _LRAD_MD5_H
#define _LRAD_MD5_H
#ifndef _LRAD_PROTO_H
#define _LRAD_PROTO_H
/* GLOBAL.H - RSAREF types and constants
*/
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
The following makes PROTOTYPES default to 0 if it has not already
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
# if __STDC__
# define PROTOTYPES 1
# else
# define PROTOTYPES 0
# endif
#endif
/* POINTER defines a generic pointer type */
#ifndef _POINTER_T
typedef unsigned char *POINTER;
#endif
typedef const unsigned char *CONSTPOINTER;
/* UINT2 defines a two byte word */
#ifndef _UINT2_T
typedef unsigned short int UINT2;
#endif
/* UINT4 defines a four byte word */
#ifndef _UINT4_T
typedef unsigned int UINT4;
#endif
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
returns an empty list.
*/
#if PROTOTYPES
#define PROTO_LIST(list) list
#else
#define PROTO_LIST(list) ()
#endif
#endif /* _LRAD_PROTO_H */
/*
* FreeRADIUS defines to ensure globally unique MD5 function names,
* so that we don't pick up vendor-specific broken MD5 libraries.
*/
#define MD5_CTX librad_MD5_CTX
#define MD5Init librad_MD5Init
#define MD5Update librad_MD5Update
#define MD5Final librad_MD5Final
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CTX;
void MD5Init PROTO_LIST ((MD5_CTX *));
void MD5Update PROTO_LIST
((MD5_CTX *, const unsigned char *, unsigned int));
void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
#endif /* _LRAD_MD5_H */

View File

@ -5,7 +5,7 @@
*/
#include "../../structures.h"
#include "structures.h"
#include <string.h>
#define PCRE2_CODE_UNIT_WIDTH 8
#define PCRE2_STATIC
@ -261,7 +261,7 @@ static int h_pcre(int argc, unsigned char **argv){
PCRE2_SIZE erroffset;
struct pcre_filter_data *flt;
struct filter *newf;
char *replace = NULL;
char * replace = NULL;
if(!strncmp((char *)argv[2], "allow",5)) action = PASS;
else if(!strncmp((char *)argv[2], "deny",4)) action = REJECT;
@ -368,7 +368,7 @@ static int h_pcre_rewrite(int argc, unsigned char **argv){
PCRE2_SIZE erroffset;
struct pcre_filter_data *flt;
struct filter *newf;
char *replace = NULL;
char * replace = NULL;
if(!strncmp((char *)argv[2], "allow",5)) action = PASS;
else if(!strncmp((char *)argv[2], "deny",4)) action = REJECT;
@ -503,17 +503,11 @@ static struct symbol regexp_symbols[] = {
{NULL, "pcre_options", (void *)&pcre_options},
};
#ifdef WATCOM
#pragma aux pcre_plugin "*" parm caller [ ] value struct float struct routine [eax] modify [eax ecx edx]
#undef PLUGINCALL
#define PLUGINCALL
#endif
PLUGINAPI int PLUGINCALL pcre_plugin (struct pluginlink * pluginlink,
int argc, char** argv){
void pcre_install(void){
struct filter *flt, *tmpflt;
pl = pluginlink;
pl = &pluginlink;
pcre_options = 0;
if(!pcre_loaded){
pcre_loaded = 1;
@ -537,9 +531,8 @@ PLUGINAPI int PLUGINCALL pcre_plugin (struct pluginlink * pluginlink,
}
}
pcre_last_filter = NULL;
return 0;
}
#ifdef __cplusplus
}
#endif

6
src/pcre.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __pcre_h__
#define __pcre_h__
void pcre_install(void);
#endif /* __pcre_h__ */

View File

@ -1,20 +0,0 @@
# PCREPlugin - requires PCRE2
if(NOT PCRE2_FOUND)
message(STATUS "PCREPlugin requires PCRE2, skipping")
return()
endif()
add_3proxy_plugin(PCREPlugin
SOURCES pcre_plugin.c
COMPILE_DEFINITIONS PCRE2_CODE_UNIT_WIDTH=8
)
if(TARGET PCRE2::PCRE2)
target_link_libraries(PCREPlugin PRIVATE PCRE2::PCRE2)
else()
target_link_libraries(PCREPlugin PRIVATE ${PCRE2_LIBRARIES})
if(PCRE2_INCLUDE_DIRS)
target_include_directories(PCREPlugin PRIVATE ${PCRE2_INCLUDE_DIRS})
endif()
endif()

View File

@ -1 +0,0 @@
include Makefile.var

View File

@ -1,8 +0,0 @@
all: $(BUILDDIR)PCREPlugin$(DLSUFFICS)
pcre_plugin$(OBJSUFFICS): pcre_plugin.c
$(CC) $(DCFLAGS) $(CFLAGS) pcre_plugin.c
$(BUILDDIR)PCREPlugin$(DLSUFFICS): pcre_plugin$(OBJSUFFICS)
$(LN) $(LNOUT)../../$(BUILDDIR)PCREPlugin$(DLSUFFICS) $(LDFLAGS) $(DLFLAGS) pcre_plugin$(OBJSUFFICS) $(LIBSPREFIX)pcre2-8$(LIBSSUFFIX)

View File

@ -1,17 +0,0 @@
# SSLPlugin - requires OpenSSL
if(NOT TARGET OpenSSL::SSL)
message(STATUS "SSLPlugin requires OpenSSL, skipping")
return()
endif()
add_3proxy_plugin(SSLPlugin
SOURCES
ssl_plugin.c
my_ssl.c
LIBRARIES
OpenSSL::SSL
OpenSSL::Crypto
COMPILE_DEFINITIONS
WITH_SSL
)

View File

@ -1 +0,0 @@
include Makefile.var

View File

@ -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)

View File

@ -15,6 +15,12 @@
#ifndef _3PROXY_H_
#define _3PROXY_H_
#include "version.h"
#ifndef WITH_SSL
#ifndef NORADIUS
#define NORADIUS
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -169,6 +175,7 @@ extern struct extparam conf;
extern int timeouts[12];
int sockmap(struct clientparam * param, int timeo, int usesplice);
int udpsockmap(struct clientparam * param, int timeo);
int socksend(struct clientparam *param, SOCKET sock, unsigned char * buf, int bufsize, int to);
int socksendto(struct clientparam *param, SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
int sockrecvfrom(struct clientparam *param, SOCKET sock, struct sockaddr * sin, unsigned char * buf, int bufsize, int to);
@ -232,7 +239,9 @@ extern int paused;
extern int demon;
unsigned char * mycrypt(const unsigned char *key, const unsigned char *salt, unsigned char *buf);
#ifdef WITH_SSL
unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPassword, int tohex);
#endif
int de64 (const unsigned char *in, unsigned char *out, int maxlen);
unsigned char* en64 (const unsigned char *in, unsigned char *out, int inlen);
void tohex(unsigned char *in, unsigned char *out, int len);

View File

@ -5,23 +5,19 @@
*/
#include "../../structures.h"
#include "structures.h"
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "../../proxy.h"
#include "my_ssl.h"
#include "proxy.h"
#include "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
@ -62,11 +58,6 @@ static char * server_cipher_list = NULL;
static char * client_sni = NULL;
static int client_mode = 0;
typedef struct _ssl_conn {
SSL_CTX *ctx;
SSL *ssl;
} ssl_conn;
struct SSLsock {
SOCKET s;
@ -1178,21 +1169,13 @@ static struct symbol ssl_symbols[] = {
};
#ifdef WATCOM
#pragma aux ssl_plugin "*" parm caller [ ] value struct float struct routine [eax] modify [eax ecx edx]
#undef PLUGINCALL
#define PLUGINCALL
#endif
PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink,
int argc, char** argv){
void ssl_install(void){
h_nomitm(0, NULL);
h_noserv(0, NULL);
h_nocli(0, NULL);
pl = pluginlink;
pl = &pluginlink;
free(certcache);
certcache = NULL;
@ -1245,7 +1228,7 @@ PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink,
}
tcppmfunc = (PROXYFUNC)pl->findbyname("tcppm");
if(!tcppmfunc){return 13;}
if(!tcppmfunc) return;
proxyfunc = (PROXYFUNC)pl->findbyname("proxy");
if(!proxyfunc)proxyfunc = tcppmfunc;
smtppfunc = (PROXYFUNC)pl->findbyname("smtpp");
@ -1253,9 +1236,4 @@ PLUGINAPI int PLUGINCALL ssl_plugin (struct pluginlink * pluginlink,
ftpprfunc = (PROXYFUNC)pl->findbyname("ftppr");
if(!ftpprfunc)ftpprfunc = tcppmfunc;
return 0;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
#ifndef __my_ssl_h__
#define __my_ssl_h__
#ifndef __ssl_h__
#define __ssl_h__
//
// opaque connection structure
@ -10,6 +10,11 @@ typedef void *SSL_CONN;
//
typedef void *SSL_CERT;
typedef struct _ssl_conn {
SSL_CTX *ctx;
SSL *ssl;
} ssl_conn;
struct alpn {
unsigned char *protos;
unsigned int protos_len;
@ -83,5 +88,10 @@ void _ssl_cert_free(SSL_CERT cert);
void ssl_init(void);
char * getSSLErr(void);
//
// Built-in SSL installation (called from 3proxy.c)
//
void ssl_install(void);
extern struct sockfuncs sso;
#endif // __my_ssl_h__
#endif // __ssl_h__

View File

@ -7,7 +7,7 @@
#define _CRT_SECURE_NO_WARNINGS
#include "../../structures.h"
#include "structures.h"
#include <memory.h>
#include <fcntl.h>
#ifndef _WIN32
@ -20,18 +20,12 @@
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/provider.h>
#include "../../proxy.h"
#include "my_ssl.h"
#include "proxy.h"
#include "ssl.h"
typedef struct _ssl_conn {
SSL_CTX *ctx;
SSL *ssl;
} ssl_conn;
_3proxy_mutex_t ssl_file_mutex;
@ -284,15 +278,31 @@ int ssl_file_init = 0;
int ssl_init_done = 0;
OSSL_LIB_CTX *library_ctx = NULL;
extern EVP_MD *md4;
extern EVP_MD *md5;
void ssl_init()
{
if(!ssl_init_done){
ssl_init_done = 1;
thread_setup();
SSLeay_add_ssl_algorithms();
SSL_load_error_strings();
_3proxy_mutex_init(&ssl_file_mutex);
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
}
library_ctx = OSSL_LIB_CTX_new();
OSSL_PROVIDER_load(library_ctx, "legacy");
OSSL_PROVIDER_load(library_ctx, "default");
md4 = EVP_MD_fetch(library_ctx, "MD4", NULL);
if (md4 == NULL) {
printf("Error fetching MD4\n");
}
md5 = EVP_MD_fetch(library_ctx, "MD5", NULL);
if (md5 == NULL) {
printf("Error fetching MD5\n");
}
}
}

View File

@ -651,6 +651,8 @@ struct clientparam {
struct bandlim *bandlims[MAXBANDLIMS],
*bandlimsout[MAXBANDLIMS];
PROXYSOCKADDRTYPE udp_relay[3];
int udp_nhops;
time_t time_start;
};
@ -771,7 +773,9 @@ extern struct hashtable dns_table;
extern struct hashtable dns6_table;
extern struct hashtable auth_table;
extern struct hashtable pw_table;
#ifdef WITH_SSL
extern struct hashtable pwnt_table;
#endif
extern struct hashtable pwcr_table;
extern struct hashtable udp_table;