mirror of
https://github.com/3proxy/3proxy.git
synced 2026-07-23 20:20:10 +08:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01f85cf755 | ||
|
|
305f9932ac | ||
|
|
c94766dff7 | ||
|
|
87fc8ae4ee | ||
|
|
9ab2e820b5 | ||
|
|
7798f78137 | ||
|
|
d60ac723a5 | ||
|
|
afb2ec0696 | ||
|
|
f18a751f89 | ||
|
|
8de071aa87 | ||
|
|
f173f8860d | ||
|
|
3a66c0a4c0 | ||
|
|
66ee250e5c | ||
|
|
c893e866bd | ||
|
|
fbc0953d5c | ||
|
|
37b1ab8169 | ||
|
|
b7769d05af | ||
|
|
fdda69c1f4 | ||
|
|
a757fae617 | ||
|
|
1c9577b9a9 | ||
|
|
b59c044663 | ||
|
|
de5acb2abd | ||
|
|
d6dea13a6f | ||
|
|
a04cd67eaa |
1
.github/workflows/build-watcom.yml
vendored
1
.github/workflows/build-watcom.yml
vendored
@ -88,6 +88,7 @@ jobs:
|
|||||||
run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-lite.zip
|
run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-lite.zip
|
||||||
- name: Upload to release
|
- name: Upload to release
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
TAG: ${{ github.event.release.tag_name }}
|
TAG: ${{ github.event.release.tag_name }}
|
||||||
|
|||||||
72
.github/workflows/build-win-msys2-ucrt64.yml
vendored
Normal file
72
.github/workflows/build-win-msys2-ucrt64.yml
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
name: Build 3proxy with MSYS2 UCRT64
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
ci:
|
||||||
|
name: "msys2-ucrt64"
|
||||||
|
runs-on: windows-2022
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
- name: Setup MSYS2 (UCRT64)
|
||||||
|
uses: msys2/setup-msys2@v2
|
||||||
|
with:
|
||||||
|
msystem: UCRT64
|
||||||
|
update: true
|
||||||
|
install: >-
|
||||||
|
make
|
||||||
|
mingw-w64-ucrt-x86_64-gcc
|
||||||
|
mingw-w64-ucrt-x86_64-pcre2
|
||||||
|
mingw-w64-ucrt-x86_64-openssl
|
||||||
|
mingw-w64-ucrt-x86_64-zlib
|
||||||
|
- name: set date
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$NOW = Get-Date -Format "yyMMddHHmmss"
|
||||||
|
$RELEASE = Get-Content -Path "RELEASE" -Raw
|
||||||
|
echo "NOW=$NOW" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
|
echo "RELEASE=$RELEASE" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
|
- name: make Windows (Makefile.win)
|
||||||
|
shell: msys2 {0}
|
||||||
|
env:
|
||||||
|
LIBSTATIC: 'true'
|
||||||
|
run: make -f Makefile.win
|
||||||
|
- name: make dist dir
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
mkdir dist
|
||||||
|
mkdir dist\3proxy
|
||||||
|
mkdir dist\3proxy\bin
|
||||||
|
mkdir dist\3proxy\cfg
|
||||||
|
mkdir dist\3proxy\cfg\sql
|
||||||
|
mkdir dist\3proxy\doc
|
||||||
|
mkdir dist\3proxy\doc\ru
|
||||||
|
mkdir dist\3proxy\doc\html
|
||||||
|
mkdir dist\3proxy\doc\html\plugins
|
||||||
|
mkdir dist\3proxy\doc\html\man5
|
||||||
|
mkdir dist\3proxy\doc\html\man8
|
||||||
|
mkdir dist\3proxy\doc\html\devel
|
||||||
|
copy bin\3proxy.exe dist\3proxy\bin\
|
||||||
|
copy bin\*.dll dist\3proxy\bin\
|
||||||
|
copy bin\3proxy_crypt.exe dist\3proxy\bin\
|
||||||
|
copy cfg\*.* dist\3proxy\cfg\
|
||||||
|
copy cfg\sql\*.* dist\3proxy\cfg\sql\
|
||||||
|
copy doc\ru\*.* dist\3proxy\doc\ru\
|
||||||
|
copy doc\html\*.* dist\3proxy\doc\html\
|
||||||
|
copy doc\html\plugins\*.* dist\3proxy\doc\html\plugins\
|
||||||
|
copy doc\html\man8\*.* dist\3proxy\doc\html\man8\
|
||||||
|
copy doc\html\man5\*.* dist\3proxy\doc\html\man5\
|
||||||
|
copy doc\html\devel\*.* dist\3proxy\doc\html\devel\
|
||||||
|
copy copying dist\3proxy\
|
||||||
|
copy authors dist\3proxy\
|
||||||
|
copy README.md dist\3proxy\
|
||||||
|
copy rus.3ps dist\3proxy\
|
||||||
|
- name: Get artifact
|
||||||
|
uses: actions/upload-artifact@v7
|
||||||
|
with:
|
||||||
|
name: "3proxy-${{ env.RELEASE }}-msys2-ucrt64"
|
||||||
|
path: dist/
|
||||||
7
.github/workflows/build-win32.yml
vendored
7
.github/workflows/build-win32.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
|||||||
echo "VERSION=/D `"VERSION=\`"3proxy-$RELEASE\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
echo "VERSION=/D `"VERSION=\`"3proxy-$RELEASE\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
echo "BUILDDATE=/D `"BUILDDATE=\`"$NOW\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
echo "BUILDDATE=/D `"BUILDDATE=\`"$NOW\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
- name: install packages
|
- name: install packages
|
||||||
run: vcpkg install pcre2:x86-windows-static openssl:x86-windows-static
|
run: vcpkg install pcre2:x86-windows-static wolfssl:x86-windows-static
|
||||||
- name: Add msbuild to PATH
|
- name: Add msbuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v3
|
uses: microsoft/setup-msbuild@v3
|
||||||
- name: make Windows MSVC
|
- name: make Windows MSVC
|
||||||
@ -41,7 +41,7 @@ jobs:
|
|||||||
set "LIB=%LIB%;c:/vcpkg/installed/x86-windows-static/lib"
|
set "LIB=%LIB%;c:/vcpkg/installed/x86-windows-static/lib"
|
||||||
set "INCLUDE=%INCLUDE%;c:/vcpkg/installed/x86-windows-static/include"
|
set "INCLUDE=%INCLUDE%;c:/vcpkg/installed/x86-windows-static/include"
|
||||||
echo "volatile char VerSion[]=^"3APA3A-3proxy-Internal-Build: 3proxy-%RELEASE%-%NOW%\r\nCode certificate: https://3proxy.org/3proxy.cer\r\n^";" >>src/3proxy.c
|
echo "volatile char VerSion[]=^"3APA3A-3proxy-Internal-Build: 3proxy-%RELEASE%-%NOW%\r\nCode certificate: https://3proxy.org/3proxy.cer\r\n^";" >>src/3proxy.c
|
||||||
nmake /F Makefile.msvc
|
nmake /F Makefile.msvc WOLFSSL=1
|
||||||
- name: Decode Certificate
|
- name: Decode Certificate
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
@ -95,7 +95,7 @@ jobs:
|
|||||||
- name: Get artifact
|
- name: Get artifact
|
||||||
uses: actions/upload-artifact@v7
|
uses: actions/upload-artifact@v7
|
||||||
with:
|
with:
|
||||||
name: "3proxy-${{ env.RELEASE }}"
|
name: "3proxy-${{ env.RELEASE }}-x86"
|
||||||
path: dist/
|
path: dist/
|
||||||
- name: Create zip
|
- name: Create zip
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
@ -103,6 +103,7 @@ jobs:
|
|||||||
run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-x86.zip
|
run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-x86.zip
|
||||||
- name: Upload to release
|
- name: Upload to release
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
TAG: ${{ github.event.release.tag_name }}
|
TAG: ${{ github.event.release.tag_name }}
|
||||||
|
|||||||
5
.github/workflows/build-win64.yml
vendored
5
.github/workflows/build-win64.yml
vendored
@ -29,7 +29,7 @@ jobs:
|
|||||||
echo "VERSION=/D `"VERSION=\`"3proxy-$RELEASE\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
echo "VERSION=/D `"VERSION=\`"3proxy-$RELEASE\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
echo "BUILDDATE=/D `"BUILDDATE=\`"$NOW\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
echo "BUILDDATE=/D `"BUILDDATE=\`"$NOW\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
- name: install packages
|
- name: install packages
|
||||||
run: vcpkg install pcre2:x64-windows-static openssl:x64-windows-static
|
run: vcpkg install pcre2:x64-windows-static wolfssl:x64-windows-static
|
||||||
- name: Add msbuild to PATH
|
- name: Add msbuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v3
|
uses: microsoft/setup-msbuild@v3
|
||||||
- name: make Windows MSVC
|
- name: make Windows MSVC
|
||||||
@ -42,7 +42,7 @@ jobs:
|
|||||||
set "INCLUDE=%INCLUDE%;c:/vcpkg/installed/x64-windows-static/include"
|
set "INCLUDE=%INCLUDE%;c:/vcpkg/installed/x64-windows-static/include"
|
||||||
echo "volatile char VerSion[]=^"3APA3A-3proxy-Internal-Build: 3proxy-%RELEASE%-%NOW%\r\nCode certificate: https://3proxy.org/3proxy.cer\r\n^";" >>src/3proxy.c
|
echo "volatile char VerSion[]=^"3APA3A-3proxy-Internal-Build: 3proxy-%RELEASE%-%NOW%\r\nCode certificate: https://3proxy.org/3proxy.cer\r\n^";" >>src/3proxy.c
|
||||||
echo %NOW% / %RELEASE% / %BUILDDATE% / %VERSION%
|
echo %NOW% / %RELEASE% / %BUILDDATE% / %VERSION%
|
||||||
nmake /F Makefile.msvc
|
nmake /F Makefile.msvc WOLFSSL=1
|
||||||
- name: Decode Certificate
|
- name: Decode Certificate
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
@ -104,6 +104,7 @@ jobs:
|
|||||||
run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-x64.zip
|
run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-x64.zip
|
||||||
- name: Upload to release
|
- name: Upload to release
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
TAG: ${{ github.event.release.tag_name }}
|
TAG: ${{ github.event.release.tag_name }}
|
||||||
|
|||||||
5
.github/workflows/build-winarm64.yml
vendored
5
.github/workflows/build-winarm64.yml
vendored
@ -28,7 +28,7 @@ jobs:
|
|||||||
echo "VERSION=/D `"VERSION=\`"3proxy-$RELEASE\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
echo "VERSION=/D `"VERSION=\`"3proxy-$RELEASE\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
echo "BUILDDATE=/D `"BUILDDATE=\`"$NOW\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
echo "BUILDDATE=/D `"BUILDDATE=\`"$NOW\`"`"" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||||
- name: install packages
|
- name: install packages
|
||||||
run: vcpkg install pcre2:arm64-windows-static openssl:arm64-windows-static
|
run: vcpkg install pcre2:arm64-windows-static wolfssl:arm64-windows-static
|
||||||
- name: Add msbuild to PATH
|
- name: Add msbuild to PATH
|
||||||
uses: microsoft/setup-msbuild@v3
|
uses: microsoft/setup-msbuild@v3
|
||||||
- name: make Windows MSVC
|
- name: make Windows MSVC
|
||||||
@ -41,7 +41,7 @@ jobs:
|
|||||||
set "LIB=%LIB%;c:/vcpkg/installed/arm64-windows-static/lib"
|
set "LIB=%LIB%;c:/vcpkg/installed/arm64-windows-static/lib"
|
||||||
set "INCLUDE=%INCLUDE%;c:/vcpkg/installed/arm64-windows-static/include"
|
set "INCLUDE=%INCLUDE%;c:/vcpkg/installed/arm64-windows-static/include"
|
||||||
echo "volatile char VerSion[]=^"3APA3A-3proxy-Internal-Build: 3proxy-%RELEASE%-%NOW%\r\nCode certificate: https://3proxy.org/3proxy.cer\r\n^";" >>src/3proxy.c
|
echo "volatile char VerSion[]=^"3APA3A-3proxy-Internal-Build: 3proxy-%RELEASE%-%NOW%\r\nCode certificate: https://3proxy.org/3proxy.cer\r\n^";" >>src/3proxy.c
|
||||||
nmake /F Makefile.msvc
|
nmake /F Makefile.msvc WOLFSSL=1
|
||||||
- name: Decode Certificate
|
- name: Decode Certificate
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
run: |
|
run: |
|
||||||
@ -103,6 +103,7 @@ jobs:
|
|||||||
run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-arm64.zip
|
run: Compress-Archive -Path dist/* -DestinationPath 3proxy-${{ env.RELEASE }}-arm64.zip
|
||||||
- name: Upload to release
|
- name: Upload to release
|
||||||
if: github.event_name == 'release'
|
if: github.event_name == 'release'
|
||||||
|
shell: bash
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ github.token }}
|
GH_TOKEN: ${{ github.token }}
|
||||||
TAG: ${{ github.event.release.tag_name }}
|
TAG: ${{ github.event.release.tag_name }}
|
||||||
|
|||||||
8
.github/workflows/c-cpp-Windows.yml
vendored
8
.github/workflows/c-cpp-Windows.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v7
|
- uses: actions/checkout@v7
|
||||||
- name: install Windows libraries
|
- name: install Windows libraries
|
||||||
run: vcpkg install pcre2:x64-windows && c:\msys64\usr\bin\pacman.exe -S --noconfirm mingw-w64-x86_64-pcre2 mingw-w64-x86_64-openssl
|
run: vcpkg install pcre2:x64-windows wolfssl:x64-windows-static && c:\msys64\usr\bin\pacman.exe -S --noconfirm mingw-w64-x86_64-pcre2 mingw-w64-x86_64-wolfssl
|
||||||
- name: make Windows
|
- name: make Windows
|
||||||
run: make -f Makefile.win
|
run: make -f Makefile.win
|
||||||
env:
|
env:
|
||||||
@ -37,7 +37,7 @@ jobs:
|
|||||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||||
D:
|
D:
|
||||||
cd "D:/a/3proxy/3proxy"
|
cd "D:/a/3proxy/3proxy"
|
||||||
set "LIB=%LIB%;c:/program files/openssl/lib/VC/x64/MT;c:/vcpkg/installed/x64-windows/lib"
|
set "LIB=%LIB%;c:/vcpkg/installed/x64-windows-static/lib;c:/vcpkg/installed/x64-windows/lib"
|
||||||
set "INCLUDE=%INCLUDE%;c:/program files/openssl/include;c:/vcpkg/installed/x64-windows/include"
|
set "INCLUDE=%INCLUDE%;c:/vcpkg/installed/x64-windows-static/include;c:/vcpkg/installed/x64-windows/include"
|
||||||
nmake /F Makefile.msvc
|
nmake /F Makefile.msvc WOLFSSL=1
|
||||||
nmake /F Makefile.msvc clean
|
nmake /F Makefile.msvc clean
|
||||||
|
|||||||
15
.github/workflows/c-cpp-cmake.yml
vendored
15
.github/workflows/c-cpp-cmake.yml
vendored
@ -57,3 +57,18 @@ jobs:
|
|||||||
cmake --build .
|
cmake --build .
|
||||||
cd ..
|
cd ..
|
||||||
rmdir /s /q build
|
rmdir /s /q build
|
||||||
|
|
||||||
|
wolfssl:
|
||||||
|
name: "ubuntu-latest (wolfSSL)"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v7
|
||||||
|
- name: Install wolfSSL
|
||||||
|
run: sudo apt install -y libwolfssl-dev
|
||||||
|
- name: make with CMake (wolfSSL preferred)
|
||||||
|
run: |
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake ..
|
||||||
|
cmake --build .
|
||||||
|
cd .. && rm -rf build/
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -18,6 +18,7 @@ bin/socks
|
|||||||
bin/tcppm
|
bin/tcppm
|
||||||
bin/udppm
|
bin/udppm
|
||||||
bin/pop3p
|
bin/pop3p
|
||||||
|
bin/imapp
|
||||||
bin/smtpp
|
bin/smtpp
|
||||||
bin/ftppr
|
bin/ftppr
|
||||||
bin/mycrypt
|
bin/mycrypt
|
||||||
@ -45,6 +46,7 @@ src/socks
|
|||||||
src/tcppm
|
src/tcppm
|
||||||
src/udppm
|
src/udppm
|
||||||
src/pop3p
|
src/pop3p
|
||||||
|
src/imapp
|
||||||
src/smtpp
|
src/smtpp
|
||||||
src/ftppr
|
src/ftppr
|
||||||
src/icqpr
|
src/icqpr
|
||||||
@ -261,6 +263,7 @@ CLAUDE.md
|
|||||||
bin/3proxy_crypt
|
bin/3proxy_crypt
|
||||||
bin/3proxy_ftppr
|
bin/3proxy_ftppr
|
||||||
bin/3proxy_pop3p
|
bin/3proxy_pop3p
|
||||||
|
bin/3proxy_imapp
|
||||||
bin/3proxy_proxy
|
bin/3proxy_proxy
|
||||||
bin/3proxy_smtpp
|
bin/3proxy_smtpp
|
||||||
bin/3proxy_socks
|
bin/3proxy_socks
|
||||||
|
|||||||
152
CMakeLists.txt
152
CMakeLists.txt
@ -46,7 +46,8 @@ endif()
|
|||||||
|
|
||||||
# Options
|
# Options
|
||||||
option(3PROXY_BUILD_SHARED "Build shared libraries for plugins" ON)
|
option(3PROXY_BUILD_SHARED "Build shared libraries for plugins" ON)
|
||||||
option(3PROXY_USE_OPENSSL "Enable TLS/SSL support (requires OpenSSL)" ON)
|
option(3PROXY_USE_WOLFSSL "Enable TLS/SSL support via wolfSSL (preferred when detected)" ON)
|
||||||
|
option(3PROXY_USE_OPENSSL "Enable TLS/SSL support via OpenSSL (fallback when wolfSSL unavailable)" ON)
|
||||||
option(3PROXY_USE_PCRE2 "Enable PCRE2 regex filtering" ON)
|
option(3PROXY_USE_PCRE2 "Enable PCRE2 regex filtering" ON)
|
||||||
option(3PROXY_USE_PAM "Enable PAM/PamAuth" ON)
|
option(3PROXY_USE_PAM "Enable PAM/PamAuth" ON)
|
||||||
option(3PROXY_USE_ODBC "Enable ODBC support (Unix only, always ON on Windows)" OFF)
|
option(3PROXY_USE_ODBC "Enable ODBC support (Unix only, always ON on Windows)" OFF)
|
||||||
@ -69,6 +70,7 @@ option(3PROXY_BUILD_NONE "Do not build standalone binaries" OFF)
|
|||||||
option(3PROXY_BUILD_PROXY "Build standalone proxy binary" ON)
|
option(3PROXY_BUILD_PROXY "Build standalone proxy binary" ON)
|
||||||
option(3PROXY_BUILD_SOCKS "Build standalone socks binary" ON)
|
option(3PROXY_BUILD_SOCKS "Build standalone socks binary" ON)
|
||||||
option(3PROXY_BUILD_POP3P "Build standalone pop3p binary" ON)
|
option(3PROXY_BUILD_POP3P "Build standalone pop3p binary" ON)
|
||||||
|
option(3PROXY_BUILD_IMAPP "Build standalone imapp binary" ON)
|
||||||
option(3PROXY_BUILD_SMTPP "Build standalone smtpp binary" ON)
|
option(3PROXY_BUILD_SMTPP "Build standalone smtpp binary" ON)
|
||||||
option(3PROXY_BUILD_FTPPR "Build standalone ftppr binary" ON)
|
option(3PROXY_BUILD_FTPPR "Build standalone ftppr binary" ON)
|
||||||
option(3PROXY_BUILD_TCPPM "Build standalone tcppm binary" ON)
|
option(3PROXY_BUILD_TCPPM "Build standalone tcppm binary" ON)
|
||||||
@ -76,7 +78,7 @@ option(3PROXY_BUILD_UDPPM "Build standalone udppm binary" ON)
|
|||||||
option(3PROXY_BUILD_TLSPR "Build standalone tlspr binary" ON)
|
option(3PROXY_BUILD_TLSPR "Build standalone tlspr binary" ON)
|
||||||
|
|
||||||
if(3PROXY_BUILD_NONE)
|
if(3PROXY_BUILD_NONE)
|
||||||
foreach(_M PROXY SOCKS POP3P SMTPP FTPPR TCPPM UDPPM TLSPR)
|
foreach(_M PROXY SOCKS POP3P IMAPP SMTPP FTPPR TCPPM UDPPM TLSPR)
|
||||||
set(3PROXY_BUILD_${_M} OFF)
|
set(3PROXY_BUILD_${_M} OFF)
|
||||||
endforeach()
|
endforeach()
|
||||||
endif()
|
endif()
|
||||||
@ -253,17 +255,38 @@ endif()
|
|||||||
|
|
||||||
# Find dependencies
|
# Find dependencies
|
||||||
|
|
||||||
# OpenSSL
|
# TLS/SSL backend: prefer wolfSSL when detected, fall back to OpenSSL.
|
||||||
|
set(3PROXY_SSL_ENABLED FALSE)
|
||||||
|
set(3PROXY_SSL_WOLFSSL FALSE)
|
||||||
set(OPENSSL_FOUND FALSE)
|
set(OPENSSL_FOUND FALSE)
|
||||||
if(3PROXY_USE_OPENSSL)
|
set(WOLFSSL_FOUND FALSE)
|
||||||
|
|
||||||
|
if(3PROXY_USE_WOLFSSL)
|
||||||
|
find_path(WOLFSSL_INCLUDE_DIR NAMES wolfssl/options.h wolfssl/ssl.h)
|
||||||
|
find_library(WOLFSSL_LIBRARIES NAMES wolfssl)
|
||||||
|
if(WOLFSSL_INCLUDE_DIR AND WOLFSSL_LIBRARIES)
|
||||||
|
set(WOLFSSL_FOUND TRUE)
|
||||||
|
set(3PROXY_SSL_ENABLED TRUE)
|
||||||
|
set(3PROXY_SSL_WOLFSSL TRUE)
|
||||||
|
add_compile_definitions(WITH_SSL WITH_WOLFSSL)
|
||||||
|
message(STATUS "wolfSSL found: ${WOLFSSL_LIBRARIES} (preferred backend)")
|
||||||
|
else()
|
||||||
|
message(STATUS "wolfSSL not found, falling back to OpenSSL if enabled")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT 3PROXY_SSL_ENABLED AND 3PROXY_USE_OPENSSL)
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
if(OpenSSL_FOUND)
|
if(OpenSSL_FOUND)
|
||||||
set(OPENSSL_FOUND TRUE)
|
set(OPENSSL_FOUND TRUE)
|
||||||
|
set(3PROXY_SSL_ENABLED TRUE)
|
||||||
add_compile_definitions(WITH_SSL)
|
add_compile_definitions(WITH_SSL)
|
||||||
message(STATUS "OpenSSL found: ${OPENSSL_VERSION}")
|
message(STATUS "OpenSSL found: ${OPENSSL_VERSION}")
|
||||||
endif()
|
endif()
|
||||||
else()
|
elseif(NOT 3PROXY_SSL_ENABLED)
|
||||||
message(STATUS "OpenSSL disabled by user request")
|
message(STATUS "SSL disabled (neither wolfSSL nor OpenSSL enabled/found)")
|
||||||
|
elseif(3PROXY_SSL_WOLFSSL)
|
||||||
|
message(STATUS "OpenSSL skipped (wolfSSL in use)")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# PCRE2
|
# PCRE2
|
||||||
@ -305,8 +328,9 @@ if(ODBC_FOUND)
|
|||||||
add_compile_definitions(WITH_ODBC)
|
add_compile_definitions(WITH_ODBC)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Set NORADIUS if OpenSSL is not available (RADIUS requires MD5 from OpenSSL)
|
# Set NORADIUS if no SSL backend is available (RADIUS MD5 uses bundled md5, but
|
||||||
if(NOT OPENSSL_FOUND)
|
# keep the historical gate tied to SSL availability).
|
||||||
|
if(NOT 3PROXY_SSL_ENABLED)
|
||||||
add_compile_definitions(NORADIUS)
|
add_compile_definitions(NORADIUS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -328,10 +352,8 @@ set(3PROXY_CORE_SOURCES
|
|||||||
src/stringtable.c
|
src/stringtable.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# BLAKE2 source for 3proxy_crypt
|
# Bundled hash implementations (md4.c, md5.c, blake2b-ref.c) self-disable
|
||||||
set(MD_SOURCES
|
# via preprocessor guards when wolfSSL provides them natively.
|
||||||
src/libs/blake2b-ref.c
|
|
||||||
)
|
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Object libraries for common sources (shared between executables)
|
# Object libraries for common sources (shared between executables)
|
||||||
@ -350,6 +372,14 @@ target_include_directories(common_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
|||||||
add_library(base64_obj OBJECT src/base64.c)
|
add_library(base64_obj OBJECT src/base64.c)
|
||||||
target_include_directories(base64_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
target_include_directories(base64_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
# mdhash object library. md4.c/md5.c self-disable via NO_MD4/NO_MD5 guards
|
||||||
|
# when wolfSSL provides them; always compiled for fallback.
|
||||||
|
add_library(mdhash_obj OBJECT src/mdhash.c src/libs/md4.c src/libs/md5.c src/libs/blake2b-ref.c)
|
||||||
|
target_include_directories(mdhash_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
|
if(3PROXY_SSL_WOLFSSL)
|
||||||
|
target_include_directories(mdhash_obj PRIVATE ${WOLFSSL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
# Object libraries for 3proxy (compiled WITHOUT WITHMAIN)
|
# Object libraries for 3proxy (compiled WITHOUT WITHMAIN)
|
||||||
# These are used by the main 3proxy executable
|
# These are used by the main 3proxy executable
|
||||||
@ -359,6 +389,7 @@ target_include_directories(base64_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
|||||||
add_library(srv_modules OBJECT
|
add_library(srv_modules OBJECT
|
||||||
src/proxy.c
|
src/proxy.c
|
||||||
src/pop3p.c
|
src/pop3p.c
|
||||||
|
src/imapp.c
|
||||||
src/smtpp.c
|
src/smtpp.c
|
||||||
src/ftppr.c
|
src/ftppr.c
|
||||||
src/tcppm.c
|
src/tcppm.c
|
||||||
@ -394,8 +425,12 @@ target_include_directories(ftp_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
|||||||
# 3proxy_crypt object for 3proxy (without WITHMAIN)
|
# 3proxy_crypt object for 3proxy (without WITHMAIN)
|
||||||
add_library(3proxy_crypt_obj OBJECT src/3proxy_crypt.c)
|
add_library(3proxy_crypt_obj OBJECT src/3proxy_crypt.c)
|
||||||
target_include_directories(3proxy_crypt_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
target_include_directories(3proxy_crypt_obj PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||||
if(OpenSSL_FOUND)
|
if(3PROXY_SSL_ENABLED)
|
||||||
|
if(3PROXY_SSL_WOLFSSL)
|
||||||
|
target_include_directories(3proxy_crypt_obj PRIVATE ${WOLFSSL_INCLUDE_DIR})
|
||||||
|
else()
|
||||||
target_include_directories(3proxy_crypt_obj PRIVATE ${OPENSSL_INCLUDE_DIR})
|
target_include_directories(3proxy_crypt_obj PRIVATE ${OPENSSL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# ============================================================================
|
# ============================================================================
|
||||||
@ -411,12 +446,12 @@ add_executable(3proxy
|
|||||||
$<TARGET_OBJECTS:common_obj>
|
$<TARGET_OBJECTS:common_obj>
|
||||||
$<TARGET_OBJECTS:udpsockmap_obj>
|
$<TARGET_OBJECTS:udpsockmap_obj>
|
||||||
$<TARGET_OBJECTS:base64_obj>
|
$<TARGET_OBJECTS:base64_obj>
|
||||||
|
$<TARGET_OBJECTS:mdhash_obj>
|
||||||
$<TARGET_OBJECTS:ftp_obj>
|
$<TARGET_OBJECTS:ftp_obj>
|
||||||
$<TARGET_OBJECTS:3proxy_crypt_obj>
|
$<TARGET_OBJECTS:3proxy_crypt_obj>
|
||||||
)
|
)
|
||||||
target_sources(3proxy PRIVATE ${MD_SOURCES})
|
|
||||||
|
|
||||||
if(OpenSSL_FOUND)
|
if(3PROXY_SSL_ENABLED)
|
||||||
target_sources(3proxy PRIVATE src/ssllib.c src/ssl.c)
|
target_sources(3proxy PRIVATE src/ssllib.c src/ssl.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -428,8 +463,12 @@ target_include_directories(3proxy PRIVATE
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/libs
|
${CMAKE_CURRENT_SOURCE_DIR}/src/libs
|
||||||
)
|
)
|
||||||
if(OpenSSL_FOUND)
|
if(3PROXY_SSL_ENABLED)
|
||||||
|
if(3PROXY_SSL_WOLFSSL)
|
||||||
|
target_include_directories(3proxy PRIVATE ${WOLFSSL_INCLUDE_DIR})
|
||||||
|
else()
|
||||||
target_include_directories(3proxy PRIVATE ${OPENSSL_INCLUDE_DIR})
|
target_include_directories(3proxy PRIVATE ${OPENSSL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(PCRE2_FOUND)
|
if(PCRE2_FOUND)
|
||||||
target_include_directories(3proxy PRIVATE ${PCRE2_INCLUDE_DIRS})
|
target_include_directories(3proxy PRIVATE ${PCRE2_INCLUDE_DIRS})
|
||||||
@ -445,10 +484,16 @@ if(ODBC_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# OpenSSL linking
|
# SSL linking
|
||||||
if(OpenSSL_FOUND)
|
if(3PROXY_SSL_ENABLED)
|
||||||
|
if(3PROXY_SSL_WOLFSSL)
|
||||||
if(3PROXY_STATIC_LINK)
|
if(3PROXY_STATIC_LINK)
|
||||||
# Will be linked statically below (if static libraries are found)
|
# Will be linked statically below (if static library is found)
|
||||||
|
else()
|
||||||
|
target_link_libraries(3proxy PRIVATE ${WOLFSSL_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
elseif(3PROXY_STATIC_LINK)
|
||||||
|
# OpenSSL static linking handled below
|
||||||
else()
|
else()
|
||||||
target_link_libraries(3proxy PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
target_link_libraries(3proxy PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||||
endif()
|
endif()
|
||||||
@ -465,14 +510,19 @@ if(PCRE2_FOUND)
|
|||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Static linking of OpenSSL and PCRE2 (when option is enabled)
|
# Static linking of SSL backend and PCRE2 (when option is enabled)
|
||||||
if(3PROXY_STATIC_LINK AND (OpenSSL_FOUND OR PCRE2_FOUND))
|
if(3PROXY_STATIC_LINK AND ((3PROXY_SSL_ENABLED AND NOT 3PROXY_SSL_WOLFSSL) OR (3PROXY_SSL_WOLFSSL) OR PCRE2_FOUND))
|
||||||
set(_saved_cmake_find_library_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
set(_saved_cmake_find_library_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||||
|
|
||||||
set(_static_libs "")
|
set(_static_libs "")
|
||||||
|
|
||||||
if(OpenSSL_FOUND)
|
if(3PROXY_SSL_WOLFSSL)
|
||||||
|
find_library(_wolfssl_static_lib NAMES wolfssl)
|
||||||
|
if(_wolfssl_static_lib)
|
||||||
|
list(APPEND _static_libs ${_wolfssl_static_lib})
|
||||||
|
endif()
|
||||||
|
elseif(OpenSSL_FOUND)
|
||||||
find_library(_ssl_static_lib ssl)
|
find_library(_ssl_static_lib ssl)
|
||||||
find_library(_crypto_static_lib crypto)
|
find_library(_crypto_static_lib crypto)
|
||||||
if(_ssl_static_lib AND _crypto_static_lib)
|
if(_ssl_static_lib AND _crypto_static_lib)
|
||||||
@ -491,10 +541,12 @@ if(3PROXY_STATIC_LINK AND (OpenSSL_FOUND OR PCRE2_FOUND))
|
|||||||
|
|
||||||
if(_static_libs)
|
if(_static_libs)
|
||||||
target_link_libraries(3proxy PRIVATE -Wl,-Bstatic ${_static_libs} -Wl,-Bdynamic)
|
target_link_libraries(3proxy PRIVATE -Wl,-Bstatic ${_static_libs} -Wl,-Bdynamic)
|
||||||
message(STATUS "Static linking enabled for OpenSSL/PCRE2")
|
message(STATUS "Static linking enabled for SSL backend/PCRE2")
|
||||||
else()
|
else()
|
||||||
message(WARNING "3PROXY_STATIC_LINK is ON but static libraries not found, falling back to dynamic")
|
message(WARNING "3PROXY_STATIC_LINK is ON but static libraries not found, falling back to dynamic")
|
||||||
if(OpenSSL_FOUND)
|
if(3PROXY_SSL_WOLFSSL)
|
||||||
|
target_link_libraries(3proxy PRIVATE ${WOLFSSL_LIBRARIES})
|
||||||
|
elseif(OpenSSL_FOUND)
|
||||||
target_link_libraries(3proxy PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
target_link_libraries(3proxy PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||||
endif()
|
endif()
|
||||||
if(PCRE2_FOUND)
|
if(PCRE2_FOUND)
|
||||||
@ -520,18 +572,39 @@ endif()
|
|||||||
add_executable(3proxy_crypt
|
add_executable(3proxy_crypt
|
||||||
src/3proxy_crypt.c
|
src/3proxy_crypt.c
|
||||||
$<TARGET_OBJECTS:base64_obj>
|
$<TARGET_OBJECTS:base64_obj>
|
||||||
|
$<TARGET_OBJECTS:mdhash_obj>
|
||||||
)
|
)
|
||||||
target_sources(3proxy_crypt PRIVATE ${MD_SOURCES})
|
|
||||||
target_compile_definitions(3proxy_crypt PRIVATE WITHMAIN)
|
target_compile_definitions(3proxy_crypt PRIVATE WITHMAIN)
|
||||||
target_include_directories(3proxy_crypt PRIVATE
|
target_include_directories(3proxy_crypt PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/src/libs
|
${CMAKE_CURRENT_SOURCE_DIR}/src/libs
|
||||||
)
|
)
|
||||||
if(OpenSSL_FOUND)
|
if(3PROXY_SSL_ENABLED)
|
||||||
|
if(3PROXY_SSL_WOLFSSL)
|
||||||
|
target_include_directories(3proxy_crypt PRIVATE ${WOLFSSL_INCLUDE_DIR})
|
||||||
|
else()
|
||||||
target_include_directories(3proxy_crypt PRIVATE ${OPENSSL_INCLUDE_DIR})
|
target_include_directories(3proxy_crypt PRIVATE ${OPENSSL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
target_link_libraries(3proxy_crypt PRIVATE Threads::Threads)
|
target_link_libraries(3proxy_crypt PRIVATE Threads::Threads)
|
||||||
if(OpenSSL_FOUND)
|
if(3PROXY_SSL_ENABLED)
|
||||||
|
if(3PROXY_SSL_WOLFSSL)
|
||||||
|
if(3PROXY_STATIC_LINK)
|
||||||
|
set(_saved_cmake_find_library_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||||
|
find_library(_wolfssl_static_lib_c NAMES wolfssl)
|
||||||
|
set(CMAKE_FIND_LIBRARY_SUFFIXES ${_saved_cmake_find_library_suffixes})
|
||||||
|
if(_wolfssl_static_lib_c)
|
||||||
|
target_link_libraries(3proxy_crypt PRIVATE -Wl,-Bstatic ${_wolfssl_static_lib_c} -Wl,-Bdynamic)
|
||||||
|
message(STATUS "3proxy_crypt: static wolfSSL")
|
||||||
|
else()
|
||||||
|
message(WARNING "3PROXY_STATIC_LINK is ON but static wolfSSL not found, using dynamic")
|
||||||
|
target_link_libraries(3proxy_crypt PRIVATE ${WOLFSSL_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
target_link_libraries(3proxy_crypt PRIVATE ${WOLFSSL_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
if(3PROXY_STATIC_LINK)
|
if(3PROXY_STATIC_LINK)
|
||||||
set(_saved_cmake_find_library_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
set(_saved_cmake_find_library_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
||||||
@ -548,6 +621,7 @@ if(OpenSSL_FOUND)
|
|||||||
else()
|
else()
|
||||||
target_link_libraries(3proxy_crypt PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
target_link_libraries(3proxy_crypt PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if("${3PROXY_BINARY_PREFIX}" STREQUAL "")
|
if("${3PROXY_BINARY_PREFIX}" STREQUAL "")
|
||||||
set_target_properties(3proxy_crypt PROPERTIES OUTPUT_NAME "mycrypt")
|
set_target_properties(3proxy_crypt PROPERTIES OUTPUT_NAME "mycrypt")
|
||||||
@ -556,7 +630,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Build standalone proxy executables
|
# Build standalone proxy executables
|
||||||
foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
|
foreach(PROXY_NAME proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr)
|
||||||
string(TOUPPER "${PROXY_NAME}" _MODULE_OPT)
|
string(TOUPPER "${PROXY_NAME}" _MODULE_OPT)
|
||||||
if(NOT 3PROXY_BUILD_${_MODULE_OPT})
|
if(NOT 3PROXY_BUILD_${_MODULE_OPT})
|
||||||
continue()
|
continue()
|
||||||
@ -607,7 +681,7 @@ foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
|
|||||||
target_link_libraries(${PROXY_NAME} PRIVATE ${WINDOWS_LIBS})
|
target_link_libraries(${PROXY_NAME} PRIVATE ${WINDOWS_LIBS})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(PROXY_NAME STREQUAL "proxy" OR PROXY_NAME STREQUAL "smtpp")
|
if(PROXY_NAME STREQUAL "proxy" OR PROXY_NAME STREQUAL "smtpp" OR PROXY_NAME STREQUAL "imapp")
|
||||||
target_sources(${PROXY_NAME} PRIVATE $<TARGET_OBJECTS:base64_obj>)
|
target_sources(${PROXY_NAME} PRIVATE $<TARGET_OBJECTS:base64_obj>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -651,7 +725,7 @@ install(TARGETS 3proxy 3proxy_crypt
|
|||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
|
foreach(PROXY_NAME proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr)
|
||||||
string(TOUPPER "${PROXY_NAME}" _MODULE_OPT)
|
string(TOUPPER "${PROXY_NAME}" _MODULE_OPT)
|
||||||
if(3PROXY_BUILD_${_MODULE_OPT})
|
if(3PROXY_BUILD_${_MODULE_OPT})
|
||||||
install(TARGETS ${PROXY_NAME}
|
install(TARGETS ${PROXY_NAME}
|
||||||
@ -661,16 +735,18 @@ foreach(PROXY_NAME proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
|
|||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# Install plugins
|
# Install plugins
|
||||||
file(GLOB PLUGINFILES "${PLUGIN_OUTPUT_DIR}/*${PLUGIN_SUFFIX}")
|
# Use install(DIRECTORY ... FILES_MATCHING) so the glob resolves at install
|
||||||
|
# time, after plugin targets have been built. A configure-time file(GLOB)
|
||||||
|
# would run before any plugin exists and install nothing.
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
install(FILES
|
install(DIRECTORY ${PLUGIN_OUTPUT_DIR}/
|
||||||
${PLUGINFILES}
|
|
||||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
FILES_MATCHING PATTERN "*${PLUGIN_SUFFIX}"
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
install(FILES
|
install(DIRECTORY ${PLUGIN_OUTPUT_DIR}/
|
||||||
${PLUGINFILES}
|
|
||||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/3proxy
|
DESTINATION ${CMAKE_INSTALL_LIBDIR}/3proxy
|
||||||
|
FILES_MATCHING PATTERN "*${PLUGIN_SUFFIX}"
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@ -812,7 +888,7 @@ if(NOT WIN32)
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
# Module man pages — installed with binary prefix only if module is built
|
# Module man pages — installed with binary prefix only if module is built
|
||||||
foreach(_MAN proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
|
foreach(_MAN proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr)
|
||||||
string(TOUPPER "${_MAN}" _MODULE_OPT)
|
string(TOUPPER "${_MAN}" _MODULE_OPT)
|
||||||
if(3PROXY_BUILD_${_MODULE_OPT})
|
if(3PROXY_BUILD_${_MODULE_OPT})
|
||||||
set(_MAN_SRC "${CMAKE_CURRENT_SOURCE_DIR}/man/${_MAN}.8")
|
set(_MAN_SRC "${CMAKE_CURRENT_SOURCE_DIR}/man/${_MAN}.8")
|
||||||
@ -836,6 +912,7 @@ message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
|
|||||||
message(STATUS "")
|
message(STATUS "")
|
||||||
message(STATUS " Options:")
|
message(STATUS " Options:")
|
||||||
message(STATUS " BUILD_SHARED: ${3PROXY_BUILD_SHARED}")
|
message(STATUS " BUILD_SHARED: ${3PROXY_BUILD_SHARED}")
|
||||||
|
message(STATUS " USE_WOLFSSL: ${3PROXY_USE_WOLFSSL}")
|
||||||
message(STATUS " USE_OPENSSL: ${3PROXY_USE_OPENSSL}")
|
message(STATUS " USE_OPENSSL: ${3PROXY_USE_OPENSSL}")
|
||||||
message(STATUS " USE_PCRE2: ${3PROXY_USE_PCRE2}")
|
message(STATUS " USE_PCRE2: ${3PROXY_USE_PCRE2}")
|
||||||
message(STATUS " USE_PAM: ${3PROXY_USE_PAM}")
|
message(STATUS " USE_PAM: ${3PROXY_USE_PAM}")
|
||||||
@ -853,6 +930,7 @@ if(WIN32)
|
|||||||
endif()
|
endif()
|
||||||
message(STATUS "")
|
message(STATUS "")
|
||||||
message(STATUS " Libraries found:")
|
message(STATUS " Libraries found:")
|
||||||
|
message(STATUS " wolfSSL: ${WOLFSSL_FOUND}")
|
||||||
message(STATUS " OpenSSL: ${OPENSSL_FOUND}")
|
message(STATUS " OpenSSL: ${OPENSSL_FOUND}")
|
||||||
message(STATUS " PCRE2: ${PCRE2_FOUND}")
|
message(STATUS " PCRE2: ${PCRE2_FOUND}")
|
||||||
message(STATUS " PAM: ${PAM_FOUND}")
|
message(STATUS " PAM: ${PAM_FOUND}")
|
||||||
@ -862,7 +940,7 @@ message(STATUS " Plugins to build: ${ALL_PLUGINS}")
|
|||||||
message(STATUS "")
|
message(STATUS "")
|
||||||
message(STATUS " Standalone modules:")
|
message(STATUS " Standalone modules:")
|
||||||
message(STATUS " Binary prefix: \"${3PROXY_BINARY_PREFIX}\"")
|
message(STATUS " Binary prefix: \"${3PROXY_BINARY_PREFIX}\"")
|
||||||
foreach(_M proxy socks pop3p smtpp ftppr tcppm udppm tlspr)
|
foreach(_M proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr)
|
||||||
string(TOUPPER "${_M}" _MO)
|
string(TOUPPER "${_M}" _MO)
|
||||||
message(STATUS " BUILD_${_MO}: ${3PROXY_BUILD_${_MO}}")
|
message(STATUS " BUILD_${_MO}: ${3PROXY_BUILD_${_MO}}")
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|||||||
@ -47,6 +47,13 @@ ifeq ($(LIBSTATIC), true)
|
|||||||
STATIC_SUFFIX = -Wl,-Bdynamic
|
STATIC_SUFFIX = -Wl,-Bdynamic
|
||||||
ZLIB = -lz -lzstd
|
ZLIB = -lz -lzstd
|
||||||
endif
|
endif
|
||||||
|
WOLFSSL_CHECK ?= $(shell echo "\#include <wolfssl/options.h>\\n\#include <wolfssl/openssl/ssl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testwssl.o - 2>/dev/null && $(CC) $(LDFLAGS) -otestwssl testwssl.o $(STATIC_PREFIX) -lwolfssl $(STATIC_SUFFIX) 2>/dev/null && rm testwssl testwssl.o && echo true||echo false)
|
||||||
|
ifeq ($(WOLFSSL_CHECK), true)
|
||||||
|
LIBS += $(STATIC_PREFIX) -lwolfssl $(STATIC_SUFFIX)
|
||||||
|
CFLAGS += -DWITH_SSL -DWITH_WOLFSSL
|
||||||
|
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
|
||||||
|
ZLIB :=
|
||||||
|
else
|
||||||
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 $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX) 2>/dev/null && rm testssl testssl.o && echo true||echo false)
|
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 $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX) 2>/dev/null && rm testssl testssl.o && echo true||echo false)
|
||||||
ifeq ($(OPENSSL_CHECK), true)
|
ifeq ($(OPENSSL_CHECK), true)
|
||||||
LIBS += $(STATIC_PREFIX) $(ZLIB) -l crypto -l ssl $(STATIC_SUFFIX)
|
LIBS += $(STATIC_PREFIX) $(ZLIB) -l crypto -l ssl $(STATIC_SUFFIX)
|
||||||
@ -55,6 +62,7 @@ ifeq ($(OPENSSL_CHECK), true)
|
|||||||
else
|
else
|
||||||
ZLIB :=
|
ZLIB :=
|
||||||
endif
|
endif
|
||||||
|
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) -lpcre2-8 2>/dev/null && rm testpcre testpcre.o && echo true||echo false)
|
||||||
ifeq ($(PCRE_CHECK), true)
|
ifeq ($(PCRE_CHECK), true)
|
||||||
CFLAGS += -DWITH_PCRE
|
CFLAGS += -DWITH_PCRE
|
||||||
@ -76,7 +84,7 @@ install: all
|
|||||||
if [ ! -d "$(DESTDIR)$(BINPREFIX)" ]; then mkdir -p $(DESTDIR)$(BINPREFIX)/; fi
|
if [ ! -d "$(DESTDIR)$(BINPREFIX)" ]; then mkdir -p $(DESTDIR)$(BINPREFIX)/; fi
|
||||||
install bin/3proxy $(DESTDIR)$(BINPREFIX)/3proxy
|
install bin/3proxy $(DESTDIR)$(BINPREFIX)/3proxy
|
||||||
install bin/$(CRYPT_PREFIX)crypt $(DESTDIR)$(BINPREFIX)/$(CRYPT_PREFIX)crypt
|
install bin/$(CRYPT_PREFIX)crypt $(DESTDIR)$(BINPREFIX)/$(CRYPT_PREFIX)crypt
|
||||||
for f in proxy socks pop3p smtpp ftppr tcppm udppm tlspr; do \
|
for f in proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr; do \
|
||||||
if [ -f bin/$(PREFIX)$$f ]; then install bin/$(PREFIX)$$f $(DESTDIR)$(BINPREFIX)/$(PREFIX)$$f; fi; \
|
if [ -f bin/$(PREFIX)$$f ]; then install bin/$(PREFIX)$$f $(DESTDIR)$(BINPREFIX)/$(PREFIX)$$f; fi; \
|
||||||
done
|
done
|
||||||
install -d $(DESTDIR)$(prefix)/etc/3proxy/conf
|
install -d $(DESTDIR)$(prefix)/etc/3proxy/conf
|
||||||
@ -93,7 +101,7 @@ install: all
|
|||||||
touch $(DESTDIR)$(prefix)/etc/3proxy/conf/bandlimiters
|
touch $(DESTDIR)$(prefix)/etc/3proxy/conf/bandlimiters
|
||||||
install -d $(DESTDIR)$(MANDIR)/man8
|
install -d $(DESTDIR)$(MANDIR)/man8
|
||||||
install -m 644 man/3proxy.8 $(DESTDIR)$(MANDIR)/man8/3proxy.8
|
install -m 644 man/3proxy.8 $(DESTDIR)$(MANDIR)/man8/3proxy.8
|
||||||
for f in proxy socks pop3p smtpp ftppr tcppm udppm tlspr; do \
|
for f in proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr; do \
|
||||||
if [ -f man/$$f.8 ]; then install -m 644 man/$$f.8 $(DESTDIR)$(MANDIR)/man8/$(PREFIX)$$f.8; fi; \
|
if [ -f man/$$f.8 ]; then install -m 644 man/$$f.8 $(DESTDIR)$(MANDIR)/man8/$(PREFIX)$$f.8; fi; \
|
||||||
done
|
done
|
||||||
install -m 644 man/3proxy_crypt.8 $(DESTDIR)$(MANDIR)/man8/$(CRYPT_PREFIX)crypt.8
|
install -m 644 man/3proxy_crypt.8 $(DESTDIR)$(MANDIR)/man8/$(CRYPT_PREFIX)crypt.8
|
||||||
|
|||||||
@ -51,6 +51,13 @@ ifeq ($(LIBSTATIC), true)
|
|||||||
ZLIB = -lz -lzstd
|
ZLIB = -lz -lzstd
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
WOLFSSL_CHECK ?= $(shell echo "\#include <wolfssl/options.h>\\n\#include <wolfssl/openssl/ssl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testwssl.o - 2>/dev/null && $(CC) $(LDFLAGS) -otestwssl testwssl.o $(STATIC_PREFIX) -lwolfssl $(STATIC_SUFFIX) 2>/dev/null && rm testwssl testwssl.o && echo true||echo false)
|
||||||
|
ifeq ($(WOLFSSL_CHECK), true)
|
||||||
|
LIBS += $(STATIC_PREFIX) -lwolfssl $(STATIC_SUFFIX)
|
||||||
|
CFLAGS += -DWITH_SSL -DWITH_WOLFSSL
|
||||||
|
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
|
||||||
|
ZLIB :=
|
||||||
|
else
|
||||||
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 $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX) 2>/dev/null && rm testssl testssl.o && echo true||echo false)
|
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 $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX) 2>/dev/null && rm testssl testssl.o && echo true||echo false)
|
||||||
ifeq ($(OPENSSL_CHECK), true)
|
ifeq ($(OPENSSL_CHECK), true)
|
||||||
LIBS += $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX)
|
LIBS += $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX)
|
||||||
@ -59,6 +66,7 @@ ifeq ($(OPENSSL_CHECK), true)
|
|||||||
else
|
else
|
||||||
ZLIB :=
|
ZLIB :=
|
||||||
endif
|
endif
|
||||||
|
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) $(STATIC_PREFIX) -lpcre2-8 $(STATIC_SUFFIX) 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) $(STATIC_PREFIX) -lpcre2-8 $(STATIC_SUFFIX) 2>/dev/null && rm testpcre testpcre.o && echo true||echo false)
|
||||||
ifeq ($(PCRE_CHECK), true)
|
ifeq ($(PCRE_CHECK), true)
|
||||||
CFLAGS += -DWITH_PCRE
|
CFLAGS += -DWITH_PCRE
|
||||||
@ -86,6 +94,7 @@ INSTALL_DATA = $(INSTALL) -m 644
|
|||||||
INSTALL_OBJS = bin/3proxy \
|
INSTALL_OBJS = bin/3proxy \
|
||||||
bin/$(CRYPT_PREFIX)crypt \
|
bin/$(CRYPT_PREFIX)crypt \
|
||||||
bin/$(PREFIX)ftppr \
|
bin/$(PREFIX)ftppr \
|
||||||
|
bin/$(PREFIX)imapp \
|
||||||
bin/$(PREFIX)pop3p \
|
bin/$(PREFIX)pop3p \
|
||||||
bin/$(PREFIX)proxy \
|
bin/$(PREFIX)proxy \
|
||||||
bin/$(PREFIX)smtpp \
|
bin/$(PREFIX)smtpp \
|
||||||
@ -149,7 +158,7 @@ install-man:
|
|||||||
$(INSTALL_BIN) -d $(MANDIR8)
|
$(INSTALL_BIN) -d $(MANDIR8)
|
||||||
$(INSTALL_DATA) man/3proxy.cfg.5 $(MANDIR5)
|
$(INSTALL_DATA) man/3proxy.cfg.5 $(MANDIR5)
|
||||||
$(INSTALL_DATA) man/3proxy.8 $(MANDIR8)
|
$(INSTALL_DATA) man/3proxy.8 $(MANDIR8)
|
||||||
for f in proxy socks pop3p smtpp ftppr tcppm udppm tlspr; do \
|
for f in proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr; do \
|
||||||
if [ -f man/$$f.8 ]; then $(INSTALL_DATA) man/$$f.8 $(MANDIR8)/$(PREFIX)$$f.8; fi; \
|
if [ -f man/$$f.8 ]; then $(INSTALL_DATA) man/$$f.8 $(MANDIR8)/$(PREFIX)$$f.8; fi; \
|
||||||
done
|
done
|
||||||
$(INSTALL_DATA) man/3proxy_crypt.8 $(MANDIR8)/$(CRYPT_PREFIX)crypt.8
|
$(INSTALL_DATA) man/3proxy_crypt.8 $(MANDIR8)/$(CRYPT_PREFIX)crypt.8
|
||||||
|
|||||||
@ -31,12 +31,19 @@ COMPATLIBS =
|
|||||||
MAKEFILE = Makefile.Solaris
|
MAKEFILE = Makefile.Solaris
|
||||||
PLUGINS = StringsPlugin TrafficPlugin TransparentPlugin FilePlugin
|
PLUGINS = StringsPlugin TrafficPlugin TransparentPlugin FilePlugin
|
||||||
|
|
||||||
|
WOLFSSL_CHECK = $(shell echo "\#include <wolfssl/options.h>\\n\#include <wolfssl/openssl/ssl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testwssl.o - 2>/dev/null && $(CC) $(LDFLAGS) -o testwssl testwssl.o -lwolfssl 2>/dev/null && rm testwssl testwssl.o && echo true||echo false)
|
||||||
|
ifeq ($(WOLFSSL_CHECK), true)
|
||||||
|
LIBS += -lwolfssl
|
||||||
|
CFLAGS += -DWITH_SSL -DWITH_WOLFSSL
|
||||||
|
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
|
||||||
|
else
|
||||||
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)
|
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)
|
ifeq ($(OPENSSL_CHECK), true)
|
||||||
LIBS += -l crypto -l ssl
|
LIBS += -l crypto -l ssl
|
||||||
CFLAGS += -DWITH_SSL
|
CFLAGS += -DWITH_SSL
|
||||||
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
|
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
|
||||||
endif
|
endif
|
||||||
|
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)
|
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)
|
ifeq ($(PCRE_CHECK), true)
|
||||||
CFLAGS += -DWITH_PCRE
|
CFLAGS += -DWITH_PCRE
|
||||||
|
|||||||
@ -11,13 +11,20 @@ CRYPT_PREFIX = 3proxy_
|
|||||||
CC = cl
|
CC = cl
|
||||||
VERSION = $(VERSION)
|
VERSION = $(VERSION)
|
||||||
BUILDDATE = $(BUILDDATE)
|
BUILDDATE = $(BUILDDATE)
|
||||||
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 "WITH_ODBC" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(BUILDDATE) $(VERSION)
|
!IFDEF WOLFSSL
|
||||||
|
SSL_DEFS = /D "WITH_SSL" /D "WITH_WOLFSSL"
|
||||||
|
SSL_LIBS = wolfssl.lib
|
||||||
|
!ELSE
|
||||||
|
SSL_DEFS = /D "WITH_SSL"
|
||||||
|
SSL_LIBS = libcrypto.lib libssl.lib
|
||||||
|
!ENDIF
|
||||||
|
CFLAGS = /nologo /MT /W3 /Ox /GS /EHs- /GA /GF /D "MSVC" /D "WITH_WSAPOLL" /D "NDEBUG" /D "WIN32" $(SSL_DEFS) /D "WITH_PCRE" /D "WITH_ODBC" /D "_CONSOLE" /D "_MBCS" /D "_WIN32" /Fp"proxy.pch" /FD /c $(BUILDDATE) $(VERSION)
|
||||||
COUT = /Fo
|
COUT = /Fo
|
||||||
LN = link
|
LN = link
|
||||||
LDFLAGS = /nologo /subsystem:console /incremental:no
|
LDFLAGS = /nologo /subsystem:console /incremental:no
|
||||||
DLFLAGS = /DLL
|
DLFLAGS = /DLL
|
||||||
DLSUFFICS = .dll
|
DLSUFFICS = .dll
|
||||||
LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib kernel32.lib Gdi32.lib Crypt32.lib libcrypto.lib libssl.lib pcre2-8.lib
|
LIBS = ws2_32.lib advapi32.lib odbc32.lib user32.lib kernel32.lib Gdi32.lib Crypt32.lib $(SSL_LIBS) pcre2-8.lib
|
||||||
LIBSPREFIX =
|
LIBSPREFIX =
|
||||||
LIBSSUFFIX = .lib
|
LIBSSUFFIX = .lib
|
||||||
LIBEXT = .lib
|
LIBEXT = .lib
|
||||||
|
|||||||
@ -49,6 +49,13 @@ ifeq ($(LIBSTATIC), true)
|
|||||||
STATIC_SUFFIX = -Wl,-Bdynamic
|
STATIC_SUFFIX = -Wl,-Bdynamic
|
||||||
ZLIB = -lz -lzstd
|
ZLIB = -lz -lzstd
|
||||||
endif
|
endif
|
||||||
|
WOLFSSL_CHECK ?= $(shell echo "\#include <wolfssl/options.h>\\n\#include <wolfssl/openssl/ssl.h>\\n int main(){return 0;}" | tr -d \\\\ | $(CC) -x c $(CFLAGS) -o testwssl.o - 2>/dev/null && $(CC) $(LDFLAGS) -otestwssl testwssl.o $(STATIC_PREFIX) -lwolfssl $(STATIC_SUFFIX) 2>/dev/null && rm testwssl testwssl.o && echo true||echo false)
|
||||||
|
ifeq ($(WOLFSSL_CHECK), true)
|
||||||
|
LIBS += $(STATIC_PREFIX) -lwolfssl $(STATIC_SUFFIX)
|
||||||
|
CFLAGS += -DWITH_SSL -DWITH_WOLFSSL
|
||||||
|
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
|
||||||
|
ZLIB :=
|
||||||
|
else
|
||||||
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 $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX) 2>/dev/null && rm testssl testssl.o && echo true||echo false)
|
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 $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX) 2>/dev/null && rm testssl testssl.o && echo true||echo false)
|
||||||
ifeq ($(OPENSSL_CHECK), true)
|
ifeq ($(OPENSSL_CHECK), true)
|
||||||
LIBS += $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX)
|
LIBS += $(STATIC_PREFIX) $(ZLIB) -lcrypto -lssl $(STATIC_SUFFIX)
|
||||||
@ -57,6 +64,7 @@ ifeq ($(OPENSSL_CHECK), true)
|
|||||||
else
|
else
|
||||||
ZLIB :=
|
ZLIB :=
|
||||||
endif
|
endif
|
||||||
|
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) $(STATIC_PREFIX) -lpcre2-8 $(STATIC_SUFFIX) 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) $(STATIC_PREFIX) -lpcre2-8 $(STATIC_SUFFIX) 2>/dev/null && rm testpcre testpcre.o && echo true||echo false)
|
||||||
ifeq ($(PCRE_CHECK), true)
|
ifeq ($(PCRE_CHECK), true)
|
||||||
CFLAGS += -DWITH_PCRE
|
CFLAGS += -DWITH_PCRE
|
||||||
@ -78,7 +86,7 @@ install: all
|
|||||||
if [ ! -d "$(DESTDIR)$(BINPREFIX)" ]; then mkdir -p $(DESTDIR)$(BINPREFIX)/; fi
|
if [ ! -d "$(DESTDIR)$(BINPREFIX)" ]; then mkdir -p $(DESTDIR)$(BINPREFIX)/; fi
|
||||||
install bin/3proxy $(DESTDIR)$(BINPREFIX)/3proxy
|
install bin/3proxy $(DESTDIR)$(BINPREFIX)/3proxy
|
||||||
install bin/$(CRYPT_PREFIX)crypt $(DESTDIR)$(BINPREFIX)/$(CRYPT_PREFIX)crypt
|
install bin/$(CRYPT_PREFIX)crypt $(DESTDIR)$(BINPREFIX)/$(CRYPT_PREFIX)crypt
|
||||||
for f in proxy socks pop3p smtpp ftppr tcppm udppm tlspr; do \
|
for f in proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr; do \
|
||||||
if [ -f bin/$(PREFIX)$$f ]; then install bin/$(PREFIX)$$f $(DESTDIR)$(BINPREFIX)/$(PREFIX)$$f; fi; \
|
if [ -f bin/$(PREFIX)$$f ]; then install bin/$(PREFIX)$$f $(DESTDIR)$(BINPREFIX)/$(PREFIX)$$f; fi; \
|
||||||
done
|
done
|
||||||
install -d $(DESTDIR)$(prefix)/etc/3proxy/conf
|
install -d $(DESTDIR)$(prefix)/etc/3proxy/conf
|
||||||
@ -95,7 +103,7 @@ install: all
|
|||||||
touch $(DESTDIR)$(prefix)/etc/3proxy/conf/bandlimiters
|
touch $(DESTDIR)$(prefix)/etc/3proxy/conf/bandlimiters
|
||||||
install -d $(DESTDIR)$(MANDIR)/man8
|
install -d $(DESTDIR)$(MANDIR)/man8
|
||||||
install -m 644 man/3proxy.8 $(DESTDIR)$(MANDIR)/man8/3proxy.8
|
install -m 644 man/3proxy.8 $(DESTDIR)$(MANDIR)/man8/3proxy.8
|
||||||
for f in proxy socks pop3p smtpp ftppr tcppm udppm tlspr; do \
|
for f in proxy socks pop3p imapp smtpp ftppr tcppm udppm tlspr; do \
|
||||||
if [ -f man/$$f.8 ]; then install -m 644 man/$$f.8 $(DESTDIR)$(MANDIR)/man8/$(PREFIX)$$f.8; fi; \
|
if [ -f man/$$f.8 ]; then install -m 644 man/$$f.8 $(DESTDIR)$(MANDIR)/man8/$(PREFIX)$$f.8; fi; \
|
||||||
done
|
done
|
||||||
install -m 644 man/3proxy_crypt.8 $(DESTDIR)$(MANDIR)/man8/$(CRYPT_PREFIX)crypt.8
|
install -m 644 man/3proxy_crypt.8 $(DESTDIR)$(MANDIR)/man8/$(CRYPT_PREFIX)crypt.8
|
||||||
|
|||||||
25
Makefile.win
25
Makefile.win
@ -37,21 +37,36 @@ BUILDDATE := $(BUILDDATE)
|
|||||||
AFTERCLEAN = (find . -type f -name "*.o" -delete && find . -type f -name "*.res" -delete && find src/ -type f -name "Makefile.var" -delete && find bin/ -type f -executable -delete) || true
|
AFTERCLEAN = (find . -type f -name "*.o" -delete && find . -type f -name "*.res" -delete && find src/ -type f -name "Makefile.var" -delete && find bin/ -type f -executable -delete) || true
|
||||||
|
|
||||||
ifndef OPENSSL_CHECK
|
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 ($(LIBSTATIC), true)
|
||||||
|
STATIC_PREFIX = -Wl,-Bstatic
|
||||||
|
STATIC_SUFFIX = -Wl,-Bdynamic
|
||||||
|
ZLIB = -lz
|
||||||
|
endif
|
||||||
|
WOLFSSL_CHECK = $(shell echo "\#include <wolfssl/options.h>\\n\#include <wolfssl/openssl/ssl.h>\\n int main(){return 0;}" | tr -d '\\\\' | $(CC) -x c $(CFLAGS) $(LDFLAGS) $(STATIC_PREFIX) -lwolfssl $(STATIC_SUFFIX) -o testwssl - 2>/dev/null && rm testwssl && echo true||echo false)
|
||||||
|
ifeq ($(WOLFSSL_CHECK), true)
|
||||||
|
LIBS += $(STATIC_PREFIX) -lwolfssl $(STATIC_SUFFIX) -lws2_32
|
||||||
|
CFLAGS += -DWITH_SSL -DWITH_WOLFSSL
|
||||||
|
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
|
||||||
|
ZLIB :=
|
||||||
|
else
|
||||||
|
OPENSSL_CHECK = $(shell echo "\#include <openssl/ssl.h>\\n int main(){return 0;}" | tr -d '\\\\' | $(CC) -x c $(CFLAGS) $(LDFLAGS) $(STATIC_PREFIX) $(ZLIB) -l crypto -l ssl $(STATIC_SUFFIX) -o testssl - 2>/dev/null && rm testssl && echo true||echo false)
|
||||||
ifeq ($(OPENSSL_CHECK), true)
|
ifeq ($(OPENSSL_CHECK), true)
|
||||||
LIBS += -l crypto -l ssl
|
LIBS += $(STATIC_PREFIX) $(ZLIB) -l crypto -l ssl $(STATIC_SUFFIX) -lcrypt32
|
||||||
CFLAGS += -DWITH_SSL
|
CFLAGS += -DWITH_SSL
|
||||||
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
|
SSL_OBJS = ssllib$(OBJSUFFICS) ssl$(OBJSUFFICS)
|
||||||
|
else
|
||||||
|
ZLIB :=
|
||||||
endif
|
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)
|
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)
|
ifeq ($(PAM_CHECK), true)
|
||||||
PLUGINS += PamAuth
|
PLUGINS += PamAuth
|
||||||
endif
|
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)
|
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) $(STATIC_PREFIX) -lpcre2-8 $(STATIC_SUFFIX) -o testpcre - 2>/dev/null && rm testpcre && echo true||echo false)
|
||||||
ifeq ($(PCRE_CHECK), true)
|
ifeq ($(PCRE_CHECK), true)
|
||||||
CFLAGS += -DWITH_PCRE
|
CFLAGS += -DWITH_PCRE
|
||||||
PCRE_OBJS = pcre$(OBJSUFFICS)
|
PCRE_OBJS = pcre$(OBJSUFFICS)
|
||||||
PCRE_LIBS = -lpcre2-8
|
PCRE_LIBS = $(STATIC_PREFIX) -lpcre2-8 $(STATIC_SUFFIX)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
<li><a href="#NAMES">How to resolve names through a parent proxy</a></li>
|
<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="#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="#TLSPR">How to set up an SNI proxy (tlspr)</a></li>
|
||||||
|
<li><a href="#DNSPR">How to set up a DNS proxy (dnspr)</a></li>
|
||||||
<li><a href="#SSLPLUGIN">How to set up TLS/SSL (https proxy, mTLS)</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="#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="#PCRE">How to use PCRE filtering (regular expressions)</a></li>
|
||||||
@ -582,6 +583,7 @@ proxy -p8080 -i192.168.2.1
|
|||||||
An SNI proxy can be used to transparently redirect any TLS traffic with an external router or via local redirection rules. It can also be used
|
An SNI proxy can be used to transparently redirect any TLS traffic with an external router or via local redirection rules. It can also be used
|
||||||
to extract hostnames from TLS to use in ACLs in combination with SOCKS or HTTP(s) proxy and/or the Transparent plugin. It can also be used to require TLS or mTLS between services. The TLS handshake contains no
|
to extract hostnames from TLS to use in ACLs in combination with SOCKS or HTTP(s) proxy and/or the Transparent plugin. It can also be used to require TLS or mTLS between services. The TLS handshake contains no
|
||||||
port information; if tlspr is used as a standalone service, the destination port may be either detected with the Transparent plugin or configured with the -P option (default 443).
|
port information; if tlspr is used as a standalone service, the destination port may be either detected with the Transparent plugin or configured with the -P option (default 443).
|
||||||
|
Note: tlspr does not support user authentication (there are no credentials in the TLS handshake to authenticate against); use ACLs by IP or a parent proxy with authentication if access control is required.
|
||||||
</p><p>
|
</p><p>
|
||||||
<b>Options:</b>
|
<b>Options:</b>
|
||||||
</p><pre>
|
</p><pre>
|
||||||
@ -592,8 +594,54 @@ proxy -p8080 -i192.168.2.1
|
|||||||
2 - require TLS, check both client and server HELLO
|
2 - require TLS, check both client and server HELLO
|
||||||
3 - require TLS, check that the server sends a certificate (not compatible with TLS 1.3)
|
3 - require TLS, check that the server sends a certificate (not compatible with TLS 1.3)
|
||||||
4 - require mutual TLS, check that the server sends a certificate request and the client sends a certificate (not compatible with TLS 1.3)
|
4 - require mutual TLS, check that the server sends a certificate request and the client sends a certificate (not compatible with TLS 1.3)
|
||||||
|
-Ximap | -Xpop3 | -Xsmtp - explicit TLS (STARTTLS) mode: tlspr speaks the plaintext
|
||||||
|
protocol with the client (greeting, STARTTLS command), then upgrades both sides to TLS
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
|
<b>Implicit vs explicit TLS:</b>
|
||||||
|
</p><p>
|
||||||
|
Implicit TLS means TLS from the first byte of the connection: https (443), imaps (993), SMTP submission secure (submissions) (465).
|
||||||
|
Explicit TLS means the connection starts in plaintext and is upgraded with a STARTTLS/STLS command: imap (143), SMTP submission (587), pop3 (110).
|
||||||
|
tlspr supports both: for implicit TLS the destination host is taken from SNI and the port from -P; for explicit TLS
|
||||||
|
the -X option makes tlspr speak the plaintext protocol phase with the client (greeting, STARTTLS command) before
|
||||||
|
upgrading both sides to TLS. Example:
|
||||||
|
</p><pre>
|
||||||
|
# https (implicit)
|
||||||
|
tlspr -p443 -P443 -c1
|
||||||
|
# imaps (implicit)
|
||||||
|
tlspr -p993 -P993 -c1
|
||||||
|
# submissions (implicit)
|
||||||
|
tlspr -p465 -P465 -c1
|
||||||
|
# imap STARTTLS (explicit)
|
||||||
|
tlspr -p143 -P143 -Ximap
|
||||||
|
# submission STARTTLS (explicit)
|
||||||
|
tlspr -p587 -P587 -Xsmtp
|
||||||
|
# pop3 STLS (explicit)
|
||||||
|
tlspr -p110 -P110 -Xpop3
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Note: for explicit TLS the protocol services smtpp, imapp and pop3p can be used instead of tlspr -X; they also
|
||||||
|
support STARTTLS.
|
||||||
|
</p><p>
|
||||||
|
<b>Recommended setup - traffic redirection:</b> the most universal configuration is to redirect TLS traffic
|
||||||
|
(ports 443, 993, 465, 143, 587, 110) to tlspr with external router rules or local redirection (Transparent plugin).
|
||||||
|
The original destination address and port are preserved, no -P or per-port services are required, and both implicit
|
||||||
|
and explicit TLS work with the same installation.
|
||||||
|
</p><pre>
|
||||||
|
auth iponly
|
||||||
|
allow *
|
||||||
|
tlspr -p1443 -c1
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
with, for example, iptables:
|
||||||
|
</p><pre>
|
||||||
|
iptables -t nat -A PREROUTING -p tcp -m multiport --dports 443,993,465 -j REDIRECT --to-port 1443
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Alternatively, if clients use dnspr as their DNS resolver, traffic can be redirected via DNS —
|
||||||
|
see <a href="#DNSPR">How to set up a DNS proxy (dnspr)</a>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
<b>SNI Break (DPI Bypass):</b>
|
<b>SNI Break (DPI Bypass):</b>
|
||||||
<br>tlspr can be used as a parent with the "tls" type to implement SNI splitting for DPI bypass (similar to NoDPI/GoodByeDPI).
|
<br>tlspr can be used as a parent with the "tls" type to implement SNI splitting for DPI bypass (similar to NoDPI/GoodByeDPI).
|
||||||
The client sends the first part of the TLS ClientHello, tlspr splits it at the SNI extension and sends it in two TCP packets,
|
The client sends the first part of the TLS ClientHello, tlspr splits it at the SNI extension and sends it in two TCP packets,
|
||||||
@ -638,6 +686,47 @@ parent 1000 tls 0.0.0.0 0
|
|||||||
deny * * blocked.example.com
|
deny * * blocked.example.com
|
||||||
allow *
|
allow *
|
||||||
proxy
|
proxy
|
||||||
|
</pre>
|
||||||
|
</p>
|
||||||
|
<li><a name="DNSPR"><i>How to set up a DNS proxy (dnspr)</i></a></li>
|
||||||
|
<p>
|
||||||
|
dnspr is a DNS forwarding service. It answers queries from the 3proxy name cache (including static nsrecord
|
||||||
|
entries), forwards other queries to the resolvers configured with nserver, and caches the results if
|
||||||
|
nscache/nscache6 are configured. Options:
|
||||||
|
</p><pre>
|
||||||
|
-s - simple DNS forwarding: do not use 3proxy resolver / name cache
|
||||||
|
-F<ip> - fake: answer all A (or AAAA) queries with the given IP address.
|
||||||
|
May be given twice - once with an IPv4 and once with an IPv6 address.
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
dnspr can be used to redirect traffic by hostname, e.g. to point mail clients to a
|
||||||
|
<a href="#TLSPR">tlspr</a> installation, by adding nsrecord entries for the service hostnames
|
||||||
|
(nscache/nscache6 keep the answers for all other names intact):
|
||||||
|
</p><pre>
|
||||||
|
nscache 65536
|
||||||
|
nscache6 65536
|
||||||
|
dnspr -p53
|
||||||
|
|
||||||
|
# google
|
||||||
|
nsrecord smtp.gmail.com 10.0.0.1
|
||||||
|
nsrecord imap.gmail.com 10.0.0.1
|
||||||
|
nsrecord pop.gmail.com 10.0.0.1
|
||||||
|
# mail.ru
|
||||||
|
nsrecord smtp.mail.ru 10.0.0.1
|
||||||
|
nsrecord imap.mail.ru 10.0.0.1
|
||||||
|
nsrecord pop.mail.ru 10.0.0.1
|
||||||
|
# yandex.ru
|
||||||
|
nsrecord smtp.yandex.ru 10.0.0.1
|
||||||
|
nsrecord imap.yandex.ru 10.0.0.1
|
||||||
|
nsrecord pop.yandex.ru 10.0.0.1
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
where 10.0.0.1 is the address tlspr listens on. If every hostname must be redirected, a single fake
|
||||||
|
address can be used instead of individual nsrecords:
|
||||||
|
</p><pre>
|
||||||
|
nscache 65536
|
||||||
|
nscache6 65536
|
||||||
|
dnspr -p53 -F10.0.0.1
|
||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
<li><a name="SSLPLUGIN"><i>How to set up TLS/SSL (https proxy, mTLS)</i></a>
|
<li><a name="SSLPLUGIN"><i>How to set up TLS/SSL (https proxy, mTLS)</i></a>
|
||||||
@ -1383,16 +1472,19 @@ socks -H -p1080
|
|||||||
<p>
|
<p>
|
||||||
<b>Sending PROXY protocol header to parent proxy:</b>
|
<b>Sending PROXY protocol header to parent proxy:</b>
|
||||||
<br>Use the <code>ha</code> parent type to send a PROXY protocol v1 header to
|
<br>Use the <code>ha</code> parent type to send a PROXY protocol v1 header to
|
||||||
the parent proxy. This must be the last parent in the chain:
|
the parent proxy. Place <code>ha</code> before the parent that should receive
|
||||||
|
the header; after the header is sent, parent protocol negotiation continues:
|
||||||
</p><pre>
|
</p><pre>
|
||||||
allow *
|
allow *
|
||||||
parent 1000 ha
|
parent 1000 ha 0.0.0.0 0
|
||||||
parent 1000 socks5 parent.example.com 1080
|
parent 1000 socks5 parent.example.com 1080
|
||||||
socks
|
proxy
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
This configuration sends the client IP information to the SOCKS5 parent proxy
|
This configuration connects to the SOCKS5 parent, sends the PROXY protocol
|
||||||
via the PROXY protocol.
|
header with the original client IP, then performs SOCKS5 negotiation before
|
||||||
|
relaying the client payload. The parent should use <code>-H</code> to accept
|
||||||
|
the header (for example <code>socks -H</code>).
|
||||||
</p>
|
</p>
|
||||||
<li><a name="MAXSEG"><i>How to set TCP maximum segment size (MSS)</i></a>
|
<li><a name="MAXSEG"><i>How to set TCP maximum segment size (MSS)</i></a>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
<li><a href="#NAMES">Как разрешать имена на родительском прокси?</a></li>
|
<li><a href="#NAMES">Как разрешать имена на родительском прокси?</a></li>
|
||||||
<li><a href="#ISFTP">Как настроить FTP прокси?</a></li>
|
<li><a href="#ISFTP">Как настроить FTP прокси?</a></li>
|
||||||
<li><a href="#TLSPR">Как настроить SNI proxy (tlspr)</a></li>
|
<li><a href="#TLSPR">Как настроить SNI proxy (tlspr)</a></li>
|
||||||
|
<li><a href="#DNSPR">Как настроить DNS proxy (dnspr)</a></li>
|
||||||
<li><a href="#SSLPLUGIN">Как настроить TLS/SSL (https прокси, mTLS)</a></li>
|
<li><a href="#SSLPLUGIN">Как настроить TLS/SSL (https прокси, mTLS)</a></li>
|
||||||
<li><a href="#CERTIFICATES">Как создать CA и сертификаты для SSL</a></li>
|
<li><a href="#CERTIFICATES">Как создать CA и сертификаты для SSL</a></li>
|
||||||
<li><a href="#PCRE">Как использовать PCRE-фильтрацию (регулярные выражения)</a></li>
|
<li><a href="#PCRE">Как использовать PCRE-фильтрацию (регулярные выражения)</a></li>
|
||||||
@ -590,6 +591,7 @@
|
|||||||
Еще одна задача которую может решать модуль - требование наличия TLS или mTLS (mutual TLS).
|
Еще одна задача которую может решать модуль - требование наличия TLS или mTLS (mutual TLS).
|
||||||
Если tlspr используется как отдельный сервис без использования плагина Transparent, то необходимо задать порт назначения через опцию -P (по умолчанию 443),
|
Если tlspr используется как отдельный сервис без использования плагина Transparent, то необходимо задать порт назначения через опцию -P (по умолчанию 443),
|
||||||
т.к. TLS хендшейк не содержит информации о порте назначения.
|
т.к. TLS хендшейк не содержит информации о порте назначения.
|
||||||
|
Примечание: tlspr не поддерживает аутентификацию пользователей (в TLS-хендшейке нет учетных данных); используйте ACL по IP или родительский прокси с аутентификацией, если требуется контроль доступа.
|
||||||
</p><p>
|
</p><p>
|
||||||
<b>Опции:</b>
|
<b>Опции:</b>
|
||||||
</p><pre>
|
</p><pre>
|
||||||
@ -600,8 +602,54 @@
|
|||||||
2 - требовать TLS, проверять наличие client и server HELLO
|
2 - требовать TLS, проверять наличие client и server HELLO
|
||||||
3 - требовать TLS, проверять наличие серверного сертификата (не совместим с TLS 1.3+)
|
3 - требовать TLS, проверять наличие серверного сертификата (не совместим с TLS 1.3+)
|
||||||
4 - требовать взаимный (mutual) TLS, проверять что сервер запрашивает сертификат и клиент его отправляет (не совместим с TLS 1.3+)
|
4 - требовать взаимный (mutual) TLS, проверять что сервер запрашивает сертификат и клиент его отправляет (не совместим с TLS 1.3+)
|
||||||
|
-Ximap | -Xpop3 | -Xsmtp - режим explicit TLS (STARTTLS): tlspr говорит с клиентом
|
||||||
|
на plaintext-протоколе (приветствие, команда STARTTLS), затем поднимает TLS с обеих сторон
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
|
<b>Implicit и explicit TLS:</b>
|
||||||
|
</p><p>
|
||||||
|
Implicit TLS означает TLS с первого байта соединения: https (443), imaps (993), SMTP submission secure (submissions) (465).
|
||||||
|
Explicit TLS означает, что соединение начинается в plaintext и поднимается до TLS командой STARTTLS/STLS: imap (143), SMTP submission (587), pop3 (110).
|
||||||
|
tlspr поддерживает оба варианта: для implicit TLS хост назначения берется из SNI, а порт из -P; для explicit TLS
|
||||||
|
опция -X заставляет tlspr говорить с клиентом на plaintext-фазе протокола (приветствие, команда STARTTLS) перед
|
||||||
|
поднятием TLS с обеих сторон. Пример:
|
||||||
|
</p><pre>
|
||||||
|
# https (implicit)
|
||||||
|
tlspr -p443 -P443 -c1
|
||||||
|
# imaps (implicit)
|
||||||
|
tlspr -p993 -P993 -c1
|
||||||
|
# submissions (implicit)
|
||||||
|
tlspr -p465 -P465 -c1
|
||||||
|
# imap STARTTLS (explicit)
|
||||||
|
tlspr -p143 -P143 -Ximap
|
||||||
|
# submission STARTTLS (explicit)
|
||||||
|
tlspr -p587 -P587 -Xsmtp
|
||||||
|
# pop3 STLS (explicit)
|
||||||
|
tlspr -p110 -P110 -Xpop3
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Примечание: для explicit TLS вместо tlspr -X можно использовать протокольные сервисы smtpp, imapp и pop3p; они
|
||||||
|
также поддерживают STARTTLS.
|
||||||
|
</p><p>
|
||||||
|
<b>Рекомендуемая конфигурация - перенаправление трафика:</b> наиболее универсальная конфигурация - перенаправлять
|
||||||
|
TLS-трафик (порты 443, 993, 465, 143, 587, 110) на tlspr правилами внешнего маршрутизатора или локальными
|
||||||
|
правилами (плагин Transparent). Исходные адрес и порт назначения сохраняются, -P и отдельные сервисы для каждого
|
||||||
|
порта не требуются, implicit и explicit TLS работают в рамках одной установки.
|
||||||
|
</p><pre>
|
||||||
|
auth iponly
|
||||||
|
allow *
|
||||||
|
tlspr -p1443 -c1
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
например, с iptables:
|
||||||
|
</p><pre>
|
||||||
|
iptables -t nat -A PREROUTING -p tcp -m multiport --dports 443,993,465 -j REDIRECT --to-port 1443
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
Также, если клиенты используют dnspr в качестве DNS-резолвера, трафик можно перенаправлять через DNS —
|
||||||
|
см. <a href="#DNSPR">Как настроить DNS proxy (dnspr)</a>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
<b>SNI Break (обход DPI):</b>
|
<b>SNI Break (обход DPI):</b>
|
||||||
<br>tlspr может использоваться как родительский прокси типа "tls" для реализации SNI-фрагментации (аналог NoDPI/GoodByeDPI).
|
<br>tlspr может использоваться как родительский прокси типа "tls" для реализации SNI-фрагментации (аналог NoDPI/GoodByeDPI).
|
||||||
Клиент отправляет первую часть TLS ClientHello, tlspr разбивает его на расширении SNI и отправляет двумя TCP-пакетами,
|
Клиент отправляет первую часть TLS ClientHello, tlspr разбивает его на расширении SNI и отправляет двумя TCP-пакетами,
|
||||||
@ -649,6 +697,48 @@ proxy
|
|||||||
</pre>
|
</pre>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<li><a name="DNSPR"><i>Как настроить DNS proxy (dnspr)</i></a></li>
|
||||||
|
<p>
|
||||||
|
dnspr - сервис пересылки DNS-запросов. Он отвечает на запросы из кэша имен 3proxy (включая статические записи
|
||||||
|
nsrecord), пересылает остальные запросы на резолверы, заданные командой nserver, и кэширует результаты, если
|
||||||
|
настроены nscache/nscache6. Опции:
|
||||||
|
</p><pre>
|
||||||
|
-s - простая пересылка DNS: не использовать резолвер / кэш имен 3proxy
|
||||||
|
-F<ip> - fake: отвечать на все A (или AAAA) запросы заданным IP-адресом.
|
||||||
|
Может быть указана дважды - один раз с IPv4 и один раз с IPv6 адресом.
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
dnspr можно использовать для перенаправления трафика по имени хоста, например, чтобы направить почтовых
|
||||||
|
клиентов на установку <a href="#TLSPR">tlspr</a>, добавив записи nsrecord для имен почтовых сервисов
|
||||||
|
(nscache/nscache6 сохраняют ответы для всех остальных имен):
|
||||||
|
</p><pre>
|
||||||
|
nscache 65536
|
||||||
|
nscache6 65536
|
||||||
|
dnspr -p53
|
||||||
|
|
||||||
|
# google
|
||||||
|
nsrecord smtp.gmail.com 10.0.0.1
|
||||||
|
nsrecord imap.gmail.com 10.0.0.1
|
||||||
|
nsrecord pop.gmail.com 10.0.0.1
|
||||||
|
# mail.ru
|
||||||
|
nsrecord smtp.mail.ru 10.0.0.1
|
||||||
|
nsrecord imap.mail.ru 10.0.0.1
|
||||||
|
nsrecord pop.mail.ru 10.0.0.1
|
||||||
|
# yandex.ru
|
||||||
|
nsrecord smtp.yandex.ru 10.0.0.1
|
||||||
|
nsrecord imap.yandex.ru 10.0.0.1
|
||||||
|
nsrecord pop.yandex.ru 10.0.0.1
|
||||||
|
</pre>
|
||||||
|
<p>
|
||||||
|
где 10.0.0.1 - адрес, на котором слушает tlspr. Если перенаправлять нужно все имена, вместо отдельных
|
||||||
|
записей nsrecord можно использовать один fake-адрес:
|
||||||
|
</p><pre>
|
||||||
|
nscache 65536
|
||||||
|
nscache6 65536
|
||||||
|
dnspr -p53 -F10.0.0.1
|
||||||
|
</pre>
|
||||||
|
</p>
|
||||||
|
|
||||||
<li><a name="SSLPLUGIN"><i>Как настроить TLS/SSL (https прокси, mTLS)</i></a>
|
<li><a name="SSLPLUGIN"><i>Как настроить TLS/SSL (https прокси, mTLS)</i></a>
|
||||||
<p>
|
<p>
|
||||||
Начиная с версии 0.9.7 поддержка TLS/SSL встроена в 3proxy при компиляции с OpenSSL
|
Начиная с версии 0.9.7 поддержка TLS/SSL встроена в 3proxy при компиляции с OpenSSL
|
||||||
@ -1441,16 +1531,20 @@ socks -H -p1080
|
|||||||
<p>
|
<p>
|
||||||
<b>Отправка заголовка PROXY протокола родительскому прокси:</b>
|
<b>Отправка заголовка PROXY протокола родительскому прокси:</b>
|
||||||
<br>Используйте тип родительского прокси <code>ha</code> для отправки заголовка
|
<br>Используйте тип родительского прокси <code>ha</code> для отправки заголовка
|
||||||
PROXY протокола v1 родительскому прокси. Это должен быть последний родитель в цепочке:
|
PROXY протокола v1 родительскому прокси. Укажите <code>ha</code> перед родителем,
|
||||||
|
который должен получить заголовок; после отправки заголовка продолжается
|
||||||
|
хендшейк протокола родителя:
|
||||||
</p><pre>
|
</p><pre>
|
||||||
allow *
|
allow *
|
||||||
parent 1000 ha
|
parent 1000 ha 0.0.0.0 0
|
||||||
parent 1000 socks5 parent.example.com 1080
|
parent 1000 socks5 parent.example.com 1080
|
||||||
socks
|
proxy
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
Эта конфигурация отправляет информацию об IP-адресе клиента SOCKS5 родительскому
|
Эта конфигурация подключается к SOCKS5 родителю, отправляет PROXY заголовок
|
||||||
прокси через PROXY протокол.
|
с исходным IP клиента, затем выполняет SOCKS5-хендшейк и только после этого
|
||||||
|
передаёт полезную нагрузку. Родитель должен использовать <code>-H</code>
|
||||||
|
(например <code>socks -H</code>).
|
||||||
</p>
|
</p>
|
||||||
<li><a name="MAXSEG"><i>Как установить максимальный размер сегмента TCP (MSS)</i></a>
|
<li><a name="MAXSEG"><i>Как установить максимальный размер сегмента TCP (MSS)</i></a>
|
||||||
<p>
|
<p>
|
||||||
|
|||||||
@ -8,6 +8,7 @@
|
|||||||
<br><A HREF="man8/3proxy_crypt.8.html">3proxy_crypt.8</A>
|
<br><A HREF="man8/3proxy_crypt.8.html">3proxy_crypt.8</A>
|
||||||
<br><A HREF="man8/3proxy.8.html">3proxy.8</A>
|
<br><A HREF="man8/3proxy.8.html">3proxy.8</A>
|
||||||
<br><A HREF="man8/ftppr.8.html">ftppr.8</A>
|
<br><A HREF="man8/ftppr.8.html">ftppr.8</A>
|
||||||
|
<br><A HREF="man8/imapp.8.html">imapp.8</A>
|
||||||
<br><A HREF="man8/pop3p.8.html">pop3p.8</A>
|
<br><A HREF="man8/pop3p.8.html">pop3p.8</A>
|
||||||
<br><A HREF="man8/proxy.8.html">proxy.8</A>
|
<br><A HREF="man8/proxy.8.html">proxy.8</A>
|
||||||
<br><A HREF="man8/smtpp.8.html">smtpp.8</A>
|
<br><A HREF="man8/smtpp.8.html">smtpp.8</A>
|
||||||
|
|||||||
@ -87,6 +87,7 @@ start gateway services:</p>
|
|||||||
[options] <b><br>
|
[options] <b><br>
|
||||||
socks</b> [options] <b><br>
|
socks</b> [options] <b><br>
|
||||||
pop3p</b> [options] <b><br>
|
pop3p</b> [options] <b><br>
|
||||||
|
imapp</b> [options] <b><br>
|
||||||
smtpp</b> [options] <b><br>
|
smtpp</b> [options] <b><br>
|
||||||
ftppr</b> [options] <b><br>
|
ftppr</b> [options] <b><br>
|
||||||
admin</b> [options] <b><br>
|
admin</b> [options] <b><br>
|
||||||
@ -104,6 +105,7 @@ handshake), may be used to redirect any TLS-based traffic
|
|||||||
auto</b> Proxy with protocol autoselection between proxy /
|
auto</b> Proxy with protocol autoselection between proxy /
|
||||||
socks / tlspr <b><br>
|
socks / tlspr <b><br>
|
||||||
pop3p</b> POP3 proxy (default port 110) <b><br>
|
pop3p</b> POP3 proxy (default port 110) <b><br>
|
||||||
|
imapp</b> IMAPv4 proxy (default port 143) <b><br>
|
||||||
smtpp</b> SMTP proxy (default port 25) <b><br>
|
smtpp</b> SMTP proxy (default port 25) <b><br>
|
||||||
ftppr</b> FTP proxy (default port 21) <b><br>
|
ftppr</b> FTP proxy (default port 21) <b><br>
|
||||||
admin</b> Web interface (default port 80) <b><br>
|
admin</b> Web interface (default port 80) <b><br>
|
||||||
@ -220,8 +222,8 @@ information reported) <b><br>
|
|||||||
-a2</b> (for proxy) generate Via: and X-Forwarded-For:
|
-a2</b> (for proxy) generate Via: and X-Forwarded-For:
|
||||||
instead of Forwarded: <br>
|
instead of Forwarded: <br>
|
||||||
Also, all options mentioned for <b>proxy</b>(8)
|
Also, all options mentioned for <b>proxy</b>(8)
|
||||||
<b>socks</b>(8) <b>pop3p</b>(8) <b>tcppm</b>(8)
|
<b>socks</b>(8) <b>pop3p</b>(8) <b>imapp</b>(8)
|
||||||
<b>udppm</b>(8) <b>ftppr</b>(8) <br>
|
<b>tcppm</b>(8) <b>udppm</b>(8) <b>ftppr</b>(8) <br>
|
||||||
are also supported. <br>
|
are also supported. <br>
|
||||||
Portmapping services listen at SRCPORT and connect to
|
Portmapping services listen at SRCPORT and connect to
|
||||||
DSTADDR:DSTPORT HTTP and SOCKS proxies are standard. <br>
|
DSTADDR:DSTPORT HTTP and SOCKS proxies are standard. <br>
|
||||||
@ -757,10 +759,15 @@ useful). Never use this option unless you know exactly you
|
|||||||
need it. <b><br>
|
need it. <b><br>
|
||||||
admin</b> redirect request to local ´admin´
|
admin</b> redirect request to local ´admin´
|
||||||
service (with -s parameter). <b><br>
|
service (with -s parameter). <b><br>
|
||||||
ha</b> send HAProxy PROXY protocol v1 header to parent
|
ha</b> send HAProxy PROXY protocol v1 header to the next
|
||||||
proxy. Must be the last in the proxy chain. Useful for
|
parent proxy (or to the destination if <b>ha</b> is used
|
||||||
passing client IP information to the parent proxy. Example:
|
alone). Place <b>ha</b> before the parent that should
|
||||||
parent 1000 ha <br>
|
receive the header; after the header is sent, negotiation
|
||||||
|
of that parent protocol continues (SOCKS, CONNECT, etc.).
|
||||||
|
Useful for passing client IP information to the parent
|
||||||
|
proxy. Example: <br>
|
||||||
|
parent 1000 ha 0.0.0.0 0 <br>
|
||||||
|
parent 1000 socks5 parent.example.com 1080 <br>
|
||||||
Use "+" proxy only with <b>fakeresolve</b> option
|
Use "+" proxy only with <b>fakeresolve</b> option
|
||||||
<br>
|
<br>
|
||||||
Any parent type above can be suffixed with <b>s</b> (e.g.
|
Any parent type above can be suffixed with <b>s</b> (e.g.
|
||||||
@ -779,8 +786,9 @@ special case of local redirection, it works only with
|
|||||||
<b>socks</b> proxy. In case of local redirection request is
|
<b>socks</b> proxy. In case of local redirection request is
|
||||||
redirected to different service, <b>ftp</b> locally
|
redirected to different service, <b>ftp</b> locally
|
||||||
redirects to <b>ftppr pop3</b> locally redirects to <b>pop3p
|
redirects to <b>ftppr pop3</b> locally redirects to <b>pop3p
|
||||||
http</b> locally redirects to <b>proxy admin</b> locally
|
imap</b> locally redirects to <b>imapp http</b> locally
|
||||||
redirects to the admin -s service. <br>
|
redirects to <b>proxy admin</b> locally redirects to the
|
||||||
|
admin -s service. <br>
|
||||||
Unix domain sockets can be used instead of IP address with
|
Unix domain sockets can be used instead of IP address with
|
||||||
the syntax <i>unix:/path/to/socket</i> (e.g., parent 1000
|
the syntax <i>unix:/path/to/socket</i> (e.g., parent 1000
|
||||||
socks5 unix:/var/run/parent.sock 1080). On Linux, abstract
|
socks5 unix:/var/run/parent.sock 1080). On Linux, abstract
|
||||||
@ -1294,7 +1302,8 @@ to <b>3proxy@3proxy.org</b></p>
|
|||||||
|
|
||||||
<p style="margin-left:6%; margin-top: 1em">3proxy(8),
|
<p style="margin-left:6%; margin-top: 1em">3proxy(8),
|
||||||
3proxy_crypt(8), proxy(8), ftppr(8), socks(8), pop3p(8),
|
3proxy_crypt(8), proxy(8), ftppr(8), socks(8), pop3p(8),
|
||||||
smtpp(8), tlspr(8), tcppm(8), udppm(8), syslogd(8), <br>
|
imapp(8), smtpp(8), tlspr(8), tcppm(8), udppm(8),
|
||||||
|
syslogd(8), <br>
|
||||||
https://3proxy.org/</p>
|
https://3proxy.org/</p>
|
||||||
|
|
||||||
<h2>AUTHORS
|
<h2>AUTHORS
|
||||||
|
|||||||
@ -58,11 +58,11 @@ multiple gateways with HTTP and HTTPS proxy with FTP over
|
|||||||
HTTP support, SOCKS v4, v4.5 and v5, POP3 proxy, UDP and TCP
|
HTTP support, SOCKS v4, v4.5 and v5, POP3 proxy, UDP and TCP
|
||||||
portmappers. Each gateway is started from the configuration
|
portmappers. Each gateway is started from the configuration
|
||||||
file like an independent service <b>proxy</b>(8)
|
file like an independent service <b>proxy</b>(8)
|
||||||
<b>socks</b>(8) <b>pop3p</b>(8) <b>tcppm</b>(8)
|
<b>socks</b>(8) <b>pop3p</b>(8) <b>imapp</b>(8)
|
||||||
<b>udppm</b>(8) <b>ftppr</b>(8) <b>dnspr</b> but
|
<b>tcppm</b>(8) <b>udppm</b>(8) <b>ftppr</b>(8) <b>dnspr</b>
|
||||||
<b>3proxy</b> is not a kind of wrapper or superserver for
|
but <b>3proxy</b> is not a kind of wrapper or superserver
|
||||||
these daemons. It just has the same code compiled in, but
|
for these daemons. It just has the same code compiled in,
|
||||||
provides much more functionality. SOCKSv5 implementation
|
but provides much more functionality. SOCKSv5 implementation
|
||||||
allows you to use 3proxy with any UDP or TCP based client
|
allows you to use 3proxy with any UDP or TCP based client
|
||||||
applications designed without proxy support (with
|
applications designed without proxy support (with
|
||||||
<i>SocksCAP</i>, <i>FreeCAP</i> or another client-side
|
<i>SocksCAP</i>, <i>FreeCAP</i> or another client-side
|
||||||
@ -195,8 +195,8 @@ to <b>3proxy@3proxy.org</b></p>
|
|||||||
|
|
||||||
|
|
||||||
<p style="margin-left:6%; margin-top: 1em">3proxy.cfg(5),
|
<p style="margin-left:6%; margin-top: 1em">3proxy.cfg(5),
|
||||||
proxy(8), ftppr(8), socks(8), pop3p(8), tcppm(8), udppm(8),
|
proxy(8), ftppr(8), socks(8), pop3p(8), imapp(8), tcppm(8),
|
||||||
kill(1), syslogd(8), <br>
|
udppm(8), kill(1), syslogd(8), <br>
|
||||||
https://3proxy.org/</p>
|
https://3proxy.org/</p>
|
||||||
|
|
||||||
<h2>AUTHORS
|
<h2>AUTHORS
|
||||||
|
|||||||
287
doc/html/man8/imapp.8.html
Normal file
287
doc/html/man8/imapp.8.html
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
<!-- Creator : groff version 1.24.1 -->
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1 align="center">imapp</h1>
|
||||||
|
|
||||||
|
<a href="#NAME">NAME</a><br>
|
||||||
|
<a href="#SYNOPSIS">SYNOPSIS</a><br>
|
||||||
|
<a href="#DESCRIPTION">DESCRIPTION</a><br>
|
||||||
|
<a href="#OPTIONS">OPTIONS</a><br>
|
||||||
|
<a href="#CLIENTS">CLIENTS</a><br>
|
||||||
|
<a href="#BUGS">BUGS</a><br>
|
||||||
|
<a href="#SEE ALSO">SEE ALSO</a><br>
|
||||||
|
<a href="#AUTHORS">AUTHORS</a><br>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
|
||||||
|
<h2>NAME
|
||||||
|
<a name="NAME"></a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-left:6%; margin-top: 1em"><b>imapp</b> -
|
||||||
|
IMAPv4 proxy gateway service</p>
|
||||||
|
|
||||||
|
<h2>SYNOPSIS
|
||||||
|
<a name="SYNOPSIS"></a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-left:6%; margin-top: 1em"><b>imapp</b>
|
||||||
|
[<b>-d</b>] [<b>-l</b>[[<i>@</i>]<i>logfile</i>]]
|
||||||
|
[<b>-p</b><i>port</i>] [<b>-i</b><i>internal_ip</i>]
|
||||||
|
[<b>-e</b><i>external_ip</i>]
|
||||||
|
[<b>-h</b><i>default_ip[:port]</i>] [<b>-x</b><i>]</i></p>
|
||||||
|
|
||||||
|
<h2>DESCRIPTION
|
||||||
|
<a name="DESCRIPTION"></a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-left:6%; margin-top: 1em"><i><b>imapp</b></i>
|
||||||
|
is IMAPv4 (IMAP4rev1) gateway service to allow internal
|
||||||
|
users to access external IMAP servers.</p>
|
||||||
|
|
||||||
|
<h2>OPTIONS
|
||||||
|
<a name="OPTIONS"></a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<table width="100%" border="0" rules="none" frame="void"
|
||||||
|
cellspacing="0" cellpadding="0">
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-I</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Inetd mode. Standalone service
|
||||||
|
only.</p> </td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-d</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Daemonize. Detach service from
|
||||||
|
console and run in the background.</p></td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-t</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Be silenT. Do not log
|
||||||
|
start/stop/accept error records.</p></td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-u</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Never look for username
|
||||||
|
authentication.</p> </td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-e</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">External address. IP address of
|
||||||
|
the interface the proxy should initiate connections from. By
|
||||||
|
default, the system will decide which address to use in
|
||||||
|
accordance with the routing table.</p></td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-left:6%;"><b>-ni</b><i>PATH</i></p>
|
||||||
|
|
||||||
|
<p style="margin-left:15%;">(Linux only) Switch to the
|
||||||
|
network namespace identified by <i>PATH</i> before opening
|
||||||
|
the listening socket. The current namespace is saved and
|
||||||
|
restored immediately after binding, so outgoing connections
|
||||||
|
run in the original namespace unless <b>-ne</b> is also
|
||||||
|
given.</p>
|
||||||
|
|
||||||
|
<p style="margin-left:6%;"><b>-ne</b><i>PATH</i></p>
|
||||||
|
|
||||||
|
<p style="margin-left:15%;">(Linux only) Switch to the
|
||||||
|
network namespace identified by <i>PATH</i> after the
|
||||||
|
listening socket has been bound (and after restoring from
|
||||||
|
<b>-ni</b> if applicable). Both options accept any namespace
|
||||||
|
file path (e.g. <i>/var/run/netns/myns</i> or
|
||||||
|
<i>/proc/PID/ns/net</i>) and require
|
||||||
|
<b>CAP_SYS_ADMIN</b>.</p>
|
||||||
|
|
||||||
|
<table width="100%" border="0" rules="none" frame="void"
|
||||||
|
cellspacing="0" cellpadding="0">
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p><b>-i</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p>Internal address. IP address the proxy accepts
|
||||||
|
connections to. By default, connections to any interface are
|
||||||
|
accepted. It´s usually unsafe. Unix domain sockets can
|
||||||
|
be specified with <i>-iunix:/path/to/socket</i> syntax
|
||||||
|
(e.g., -iunix:/var/run/imapp.sock). On Linux, abstract
|
||||||
|
sockets use <i>-iunix:@socketname</i> syntax.</p></td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-p</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Port. Port proxy listens for
|
||||||
|
incoming connections. Default is 143.</p></td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-h</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Default destination. It’s
|
||||||
|
used if the target address is not specified by the user.</p></td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-x</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Disable STARTTLS support.
|
||||||
|
STARTTLS is not announced in the CAPABILITY response and the
|
||||||
|
STARTTLS command is not accepted.</p></td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-l</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Log. By default logging is to
|
||||||
|
stdout. If <i>logfile</i> is specified logging is to file.
|
||||||
|
Under Unix, if ´<i>@</i>´ precedes
|
||||||
|
<i>logfile</i>, syslog is used for logging.</p></td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-S</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Increase or decrease stack size.
|
||||||
|
You may want to try something like -S8192 if you experience
|
||||||
|
3proxy crashes.</p></td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h2>CLIENTS
|
||||||
|
<a name="CLIENTS"></a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-left:6%; margin-top: 1em">You can use any
|
||||||
|
MUA (Mail User Agent) with IMAPv4 support. Set the client to
|
||||||
|
use <i>internal_ip</i> and <i>port</i> as an IMAP server.
|
||||||
|
The address of the real IMAP server must be configured as a
|
||||||
|
part of the IMAP username. The format for the username is
|
||||||
|
<i>username</i>@<i>server</i>, where <i>server</i> is the
|
||||||
|
address of the IMAP server and <i>username</i> is the
|
||||||
|
user´s login on this IMAP server. The login itself may
|
||||||
|
contain an ´@´ sign. Supported client
|
||||||
|
authentication methods are the LOGIN command, AUTHENTICATE
|
||||||
|
PLAIN and AUTHENTICATE LOGIN. With the server, the proxy
|
||||||
|
authenticates using the method chosen by the client if the
|
||||||
|
server supports it (as advertised in the CAPABILITY
|
||||||
|
response); otherwise it falls back to AUTHENTICATE LOGIN,
|
||||||
|
AUTHENTICATE PLAIN or the LOGIN command, in this order of
|
||||||
|
preference. Challenge-response authentication (CRAM-MD5,
|
||||||
|
etc.) is not supported, because it requires a challenge from
|
||||||
|
the server before we know which server to connect to. When
|
||||||
|
running as a 3proxy service (not as a standalone binary),
|
||||||
|
STARTTLS is supported and announced in the CAPABILITY
|
||||||
|
response unless disabled with <b>-x</b>. After the client
|
||||||
|
issues STARTTLS, the connection is handled by
|
||||||
|
<b>tlspr</b>(8): the destination host is taken from the SNI
|
||||||
|
of the client TLS handshake (or from the -h option), the
|
||||||
|
proxy performs STARTTLS negotiation with the destination
|
||||||
|
server, and then transparently passes TLS traffic between
|
||||||
|
the client and the server. If the destination server does
|
||||||
|
not support STARTTLS, the TLS handshake with the client
|
||||||
|
fails.</p>
|
||||||
|
|
||||||
|
<h2>BUGS
|
||||||
|
<a name="BUGS"></a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-left:6%; margin-top: 1em">Report all bugs
|
||||||
|
to <b>3proxy@3proxy.org</b></p>
|
||||||
|
|
||||||
|
<h2>SEE ALSO
|
||||||
|
<a name="SEE ALSO"></a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-left:6%; margin-top: 1em">3proxy(8),
|
||||||
|
ftppr(8), pop3p(8), proxy(8), smtpp(8), socks(8), tcppm(8),
|
||||||
|
tlspr(8), udppm(8), syslogd(8), <br>
|
||||||
|
https://3proxy.org/</p>
|
||||||
|
|
||||||
|
<h2>AUTHORS
|
||||||
|
<a name="AUTHORS"></a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-left:6%; margin-top: 1em">3proxy is
|
||||||
|
designed by Vladimir Dubrovin <vlad@3proxy.org></p>
|
||||||
|
<hr>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -36,15 +36,16 @@ POP3 proxy gateway service</p>
|
|||||||
[<b>-d</b>] [<b>-l</b>[[<i>@</i>]<i>logfile</i>]]
|
[<b>-d</b>] [<b>-l</b>[[<i>@</i>]<i>logfile</i>]]
|
||||||
[<b>-p</b><i>port</i>] [<b>-i</b><i>internal_ip</i>]
|
[<b>-p</b><i>port</i>] [<b>-i</b><i>internal_ip</i>]
|
||||||
[<b>-e</b><i>external_ip</i>]
|
[<b>-e</b><i>external_ip</i>]
|
||||||
[<b>-h</b><i>default_ip[:port]</i>]</p>
|
[<b>-h</b><i>default_ip[:port]</i>] [<b>-x</b><i>]</i></p>
|
||||||
|
|
||||||
<h2>DESCRIPTION
|
<h2>DESCRIPTION
|
||||||
<a name="DESCRIPTION"></a>
|
<a name="DESCRIPTION"></a>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
<p style="margin-left:6%; margin-top: 1em"><b>pop3p</b> is
|
|
||||||
POP3 gateway service to allow internal users to access
|
<p style="margin-left:6%; margin-top: 1em"><i><b>pop3p</b></i>
|
||||||
|
is POP3 gateway service to allow internal users to access
|
||||||
external POP3 servers.</p>
|
external POP3 servers.</p>
|
||||||
|
|
||||||
<h2>OPTIONS
|
<h2>OPTIONS
|
||||||
@ -184,6 +185,19 @@ used if the target address is not specified by the user.</p></td></tr>
|
|||||||
<td width="3%">
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-x</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Disable STARTTLS (STLS) support.
|
||||||
|
STLS is not announced in the CAPA response and the STLS
|
||||||
|
command is not accepted.</p></td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
<p style="margin-top: 1em"><b>-l</b></p></td>
|
<p style="margin-top: 1em"><b>-l</b></p></td>
|
||||||
<td width="6%"></td>
|
<td width="6%"></td>
|
||||||
<td width="85%">
|
<td width="85%">
|
||||||
@ -224,8 +238,17 @@ user´s login on this POP3 server. The login itself may
|
|||||||
contain an ´@´ sign. Only cleartext
|
contain an ´@´ sign. Only cleartext
|
||||||
authentication is supported, because challenge-response
|
authentication is supported, because challenge-response
|
||||||
authentication (APOP, CRAM-MD5, etc.) requires a challenge
|
authentication (APOP, CRAM-MD5, etc.) requires a challenge
|
||||||
from the server before we know which server to connect
|
from the server before we know which server to connect to.
|
||||||
to.</p>
|
When running as a 3proxy service (not as a standalone
|
||||||
|
binary), STLS is supported and announced in the CAPA
|
||||||
|
response unless disabled with <b>-x</b>. After the client
|
||||||
|
issues STLS, the connection is handled by <b>tlspr</b>(8):
|
||||||
|
the destination host is taken from the SNI of the client TLS
|
||||||
|
handshake (or from the -h option), the proxy performs STLS
|
||||||
|
negotiation with the destination server, and then
|
||||||
|
transparently passes TLS traffic between the client and the
|
||||||
|
server. If the destination server does not support STLS, the
|
||||||
|
TLS handshake with the client fails.</p>
|
||||||
|
|
||||||
<h2>BUGS
|
<h2>BUGS
|
||||||
<a name="BUGS"></a>
|
<a name="BUGS"></a>
|
||||||
|
|||||||
@ -36,15 +36,16 @@ SMTP proxy gateway service</p>
|
|||||||
[<b>-d</b>] [<b>-l</b>[[<i>@</i>]<i>logfile</i>]]
|
[<b>-d</b>] [<b>-l</b>[[<i>@</i>]<i>logfile</i>]]
|
||||||
[<b>-p</b><i>port</i>] [<b>-i</b><i>internal_ip</i>]
|
[<b>-p</b><i>port</i>] [<b>-i</b><i>internal_ip</i>]
|
||||||
[<b>-e</b><i>external_ip</i>]
|
[<b>-e</b><i>external_ip</i>]
|
||||||
[<b>-h</b><i>default_ip[:port]</i>]</p>
|
[<b>-h</b><i>default_ip[:port]</i>] [<b>-x</b><i>]</i></p>
|
||||||
|
|
||||||
<h2>DESCRIPTION
|
<h2>DESCRIPTION
|
||||||
<a name="DESCRIPTION"></a>
|
<a name="DESCRIPTION"></a>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
|
||||||
<p style="margin-left:6%; margin-top: 1em"><b>smtpp</b> is
|
|
||||||
SMTP gateway service to allow internal users to access
|
<p style="margin-left:6%; margin-top: 1em"><i><b>smtpp</b></i>
|
||||||
|
is SMTP gateway service to allow internal users to access
|
||||||
external SMTP servers.</p>
|
external SMTP servers.</p>
|
||||||
|
|
||||||
<h2>OPTIONS
|
<h2>OPTIONS
|
||||||
@ -166,7 +167,7 @@ sockets use <i>-iunix:@socketname</i> syntax.</p></td></tr>
|
|||||||
|
|
||||||
|
|
||||||
<p style="margin-top: 1em">Port. Port proxy listens for
|
<p style="margin-top: 1em">Port. Port proxy listens for
|
||||||
incoming connections. Default is 25.</p></td></tr>
|
incoming connections. Default is 587.</p></td></tr>
|
||||||
<tr valign="top" align="left">
|
<tr valign="top" align="left">
|
||||||
<td width="6%"></td>
|
<td width="6%"></td>
|
||||||
<td width="3%">
|
<td width="3%">
|
||||||
@ -184,6 +185,19 @@ used if the target address is not specified by the user.</p></td></tr>
|
|||||||
<td width="3%">
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em"><b>-x</b></p></td>
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
<p style="margin-top: 1em">Disable STARTTLS support.
|
||||||
|
STARTTLS is not announced in the EHLO response and the
|
||||||
|
STARTTLS command is not accepted.</p></td></tr>
|
||||||
|
<tr valign="top" align="left">
|
||||||
|
<td width="6%"></td>
|
||||||
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
<p style="margin-top: 1em"><b>-l</b></p></td>
|
<p style="margin-top: 1em"><b>-l</b></p></td>
|
||||||
<td width="6%"></td>
|
<td width="6%"></td>
|
||||||
<td width="85%">
|
<td width="85%">
|
||||||
@ -225,7 +239,17 @@ server. The login itself may contain an ´@´
|
|||||||
sign. Only cleartext authentication is supported, because
|
sign. Only cleartext authentication is supported, because
|
||||||
challenge-response authentication (CRAM-MD5, SPA, etc.)
|
challenge-response authentication (CRAM-MD5, SPA, etc.)
|
||||||
requires a challenge from the server before we know which
|
requires a challenge from the server before we know which
|
||||||
server to connect to.</p>
|
server to connect to. When running as a 3proxy service (not
|
||||||
|
as a standalone binary), STARTTLS is supported and announced
|
||||||
|
in the EHLO response unless disabled with <b>-x</b>. After
|
||||||
|
the client issues STARTTLS, the connection is handled by
|
||||||
|
<b>tlspr</b>(8): the destination host is taken from the SNI
|
||||||
|
of the client TLS handshake (or from the -h option), the
|
||||||
|
proxy performs STARTTLS negotiation with the destination
|
||||||
|
server, and then transparently passes TLS traffic between
|
||||||
|
the client and the server. If the destination server does
|
||||||
|
not support STARTTLS, the TLS handshake with the client
|
||||||
|
fails.</p>
|
||||||
|
|
||||||
<h2>BUGS
|
<h2>BUGS
|
||||||
<a name="BUGS"></a>
|
<a name="BUGS"></a>
|
||||||
|
|||||||
@ -49,7 +49,9 @@ SNI proxy gateway service</p>
|
|||||||
an SNI gateway service (destination host is taken from TLS
|
an SNI gateway service (destination host is taken from TLS
|
||||||
handshake). The destination port must be specified via the
|
handshake). The destination port must be specified via the
|
||||||
-P option (or it may be detected with the Transparent
|
-P option (or it may be detected with the Transparent
|
||||||
plugin).</p>
|
plugin). tlspr does not support user authentication; use
|
||||||
|
ACLs by client IP or a parent proxy with authentication if
|
||||||
|
access control is required.</p>
|
||||||
|
|
||||||
<h2>OPTIONS
|
<h2>OPTIONS
|
||||||
<a name="OPTIONS"></a>
|
<a name="OPTIONS"></a>
|
||||||
@ -241,27 +243,45 @@ with TLS 1.3)</p></td></tr>
|
|||||||
packet across multiple TCP segments to make SNI-based DPI
|
packet across multiple TCP segments to make SNI-based DPI
|
||||||
detection harder. An optional numeric value can follow (e.g.
|
detection harder. An optional numeric value can follow (e.g.
|
||||||
<b>-s1</b>) to control the splitting behaviour.</p></td></tr>
|
<b>-s1</b>) to control the splitting behaviour.</p></td></tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p style="margin-left:6%;"><b>-Ximap | -Xpop3 |
|
||||||
|
-Xsmtp</b></p>
|
||||||
|
|
||||||
|
<p style="margin-left:15%;">STARTTLS mode for the given
|
||||||
|
protocol. The proxy speaks the plaintext protocol with the
|
||||||
|
client (greeting, capability advertisement with STARTTLS
|
||||||
|
only, STARTTLS command), then, after the client issues
|
||||||
|
STARTTLS and sends a TLS Client HELLO, connects to the
|
||||||
|
destination taken from SNI (default port 143/110/587),
|
||||||
|
performs STARTTLS negotiation with the destination server
|
||||||
|
and transparently passes TLS traffic. If the destination
|
||||||
|
server does not support STARTTLS, the TLS handshake with the
|
||||||
|
client fails.</p>
|
||||||
|
|
||||||
|
<table width="100%" border="0" rules="none" frame="void"
|
||||||
|
cellspacing="0" cellpadding="0">
|
||||||
<tr valign="top" align="left">
|
<tr valign="top" align="left">
|
||||||
<td width="6%"></td>
|
<td width="6%"></td>
|
||||||
<td width="4%">
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
<p style="margin-top: 1em"><b>-l</b></p></td>
|
<p><b>-l</b></p></td>
|
||||||
<td width="5%"></td>
|
<td width="6%"></td>
|
||||||
<td width="85%">
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
<p style="margin-top: 1em">Log. By default logging is to
|
<p>Log. By default logging is to stdout. If <i>logfile</i>
|
||||||
stdout. If <i>logfile</i> is specified logging is to file.
|
is specified logging is to file. Under Unix, if
|
||||||
Under Unix, if ´<i>@</i>´ precedes
|
´<i>@</i>´ precedes <i>logfile</i>, syslog is
|
||||||
<i>logfile</i>, syslog is used for logging.</p></td></tr>
|
used for logging.</p></td></tr>
|
||||||
<tr valign="top" align="left">
|
<tr valign="top" align="left">
|
||||||
<td width="6%"></td>
|
<td width="6%"></td>
|
||||||
<td width="4%">
|
<td width="3%">
|
||||||
|
|
||||||
|
|
||||||
<p style="margin-top: 1em"><b>-S</b></p></td>
|
<p style="margin-top: 1em"><b>-S</b></p></td>
|
||||||
<td width="5%"></td>
|
<td width="6%"></td>
|
||||||
<td width="85%">
|
<td width="85%">
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,7 @@ from the configuration file like an independent service
|
|||||||
.BR proxy (8)
|
.BR proxy (8)
|
||||||
.BR socks (8)
|
.BR socks (8)
|
||||||
.BR pop3p (8)
|
.BR pop3p (8)
|
||||||
|
.BR imapp (8)
|
||||||
.BR tcppm (8)
|
.BR tcppm (8)
|
||||||
.BR udppm (8)
|
.BR udppm (8)
|
||||||
.BR ftppr (8)
|
.BR ftppr (8)
|
||||||
@ -140,7 +141,7 @@ configuration file
|
|||||||
Report all bugs to
|
Report all bugs to
|
||||||
.BR 3proxy@3proxy.org
|
.BR 3proxy@3proxy.org
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
3proxy.cfg(5), proxy(8), ftppr(8), socks(8), pop3p(8), tcppm(8), udppm(8),
|
3proxy.cfg(5), proxy(8), ftppr(8), socks(8), pop3p(8), imapp(8), tcppm(8), udppm(8),
|
||||||
kill(1), syslogd(8),
|
kill(1), syslogd(8),
|
||||||
.br
|
.br
|
||||||
https://3proxy.org/
|
https://3proxy.org/
|
||||||
|
|||||||
@ -55,6 +55,9 @@ Recursion is not allowed.
|
|||||||
.B pop3p
|
.B pop3p
|
||||||
[options]
|
[options]
|
||||||
.br
|
.br
|
||||||
|
.B imapp
|
||||||
|
[options]
|
||||||
|
.br
|
||||||
.B smtpp
|
.B smtpp
|
||||||
[options]
|
[options]
|
||||||
.br
|
.br
|
||||||
@ -92,6 +95,9 @@ Proxy with protocol autoselection between proxy / socks / tlspr
|
|||||||
.B pop3p
|
.B pop3p
|
||||||
POP3 proxy (default port 110)
|
POP3 proxy (default port 110)
|
||||||
.br
|
.br
|
||||||
|
.B imapp
|
||||||
|
IMAPv4 proxy (default port 143)
|
||||||
|
.br
|
||||||
.B smtpp
|
.B smtpp
|
||||||
SMTP proxy (default port 25)
|
SMTP proxy (default port 25)
|
||||||
.br
|
.br
|
||||||
@ -209,6 +215,7 @@ Never ask for username/password
|
|||||||
.BR proxy (8)
|
.BR proxy (8)
|
||||||
.BR socks (8)
|
.BR socks (8)
|
||||||
.BR pop3p (8)
|
.BR pop3p (8)
|
||||||
|
.BR imapp (8)
|
||||||
.BR tcppm (8)
|
.BR tcppm (8)
|
||||||
.BR udppm (8)
|
.BR udppm (8)
|
||||||
.BR ftppr (8)
|
.BR ftppr (8)
|
||||||
@ -821,9 +828,16 @@ unless you know exactly you need it.
|
|||||||
.br
|
.br
|
||||||
\fBadmin\fR redirect request to local \'admin\' service (with -s parameter).
|
\fBadmin\fR redirect request to local \'admin\' service (with -s parameter).
|
||||||
.br
|
.br
|
||||||
\fBha\fR send HAProxy PROXY protocol v1 header to parent proxy. Must be the last
|
\fBha\fR send HAProxy PROXY protocol v1 header to the next parent proxy (or to
|
||||||
in the proxy chain. Useful for passing client IP information to the parent proxy.
|
the destination if \fBha\fR is used alone). Place \fBha\fR before the parent
|
||||||
Example: parent 1000 ha
|
that should receive the header; after the header is sent, negotiation of that
|
||||||
|
parent protocol continues (SOCKS, CONNECT, etc.). Useful for passing client IP
|
||||||
|
information to the parent proxy.
|
||||||
|
Example:
|
||||||
|
.br
|
||||||
|
parent 1000 ha 0.0.0.0 0
|
||||||
|
.br
|
||||||
|
parent 1000 socks5 parent.example.com 1080
|
||||||
.br
|
.br
|
||||||
Use "+" proxy only with \fBfakeresolve\fR option
|
Use "+" proxy only with \fBfakeresolve\fR option
|
||||||
.br
|
.br
|
||||||
@ -847,6 +861,9 @@ locally redirects to
|
|||||||
.B pop3
|
.B pop3
|
||||||
locally redirects to
|
locally redirects to
|
||||||
.B pop3p
|
.B pop3p
|
||||||
|
.B imap
|
||||||
|
locally redirects to
|
||||||
|
.B imapp
|
||||||
.B http
|
.B http
|
||||||
locally redirects to
|
locally redirects to
|
||||||
.B proxy
|
.B proxy
|
||||||
@ -1384,7 +1401,7 @@ authentication and/or allow/deny ACLs.
|
|||||||
Report all bugs to
|
Report all bugs to
|
||||||
.BR 3proxy@3proxy.org
|
.BR 3proxy@3proxy.org
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
3proxy(8), 3proxy_crypt(8), proxy(8), ftppr(8), socks(8), pop3p(8), smtpp(8), tlspr(8), tcppm(8), udppm(8), syslogd(8),
|
3proxy(8), 3proxy_crypt(8), proxy(8), ftppr(8), socks(8), pop3p(8), imapp(8), smtpp(8), tlspr(8), tcppm(8), udppm(8), syslogd(8),
|
||||||
.br
|
.br
|
||||||
https://3proxy.org/
|
https://3proxy.org/
|
||||||
.SH AUTHORS
|
.SH AUTHORS
|
||||||
|
|||||||
124
man/imapp.8
Normal file
124
man/imapp.8
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
.TH imapp "8" "July 2026" "3proxy 0.9" "Universal proxy server"
|
||||||
|
.SH NAME
|
||||||
|
.B imapp
|
||||||
|
\- IMAPv4 proxy gateway service
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.BR "imapp " [ -d ]
|
||||||
|
.IB \fR[ -l \fR[ \fR[ @ \fR] logfile \fR]]
|
||||||
|
.IB \fR[ -p port\fR]
|
||||||
|
.IB \fR[ -i internal_ip\fR]
|
||||||
|
.IB \fR[ -e external_ip\fR]
|
||||||
|
.IB \fR[ -h default_ip[:port]\fR]
|
||||||
|
.IB \fR[ -x ]
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.B imapp
|
||||||
|
is IMAPv4 (IMAP4rev1) gateway service to allow internal users to access external
|
||||||
|
IMAP servers.
|
||||||
|
.SH OPTIONS
|
||||||
|
.TP
|
||||||
|
.B -I
|
||||||
|
Inetd mode. Standalone service only.
|
||||||
|
.TP
|
||||||
|
.B -d
|
||||||
|
Daemonize. Detach service from console and run in the background.
|
||||||
|
.TP
|
||||||
|
.B -t
|
||||||
|
Be silenT. Do not log start/stop/accept error records.
|
||||||
|
.TP
|
||||||
|
.B -u
|
||||||
|
Never look for username authentication.
|
||||||
|
.TP
|
||||||
|
.B -e
|
||||||
|
External address. IP address of the interface the proxy should initiate connections
|
||||||
|
from.
|
||||||
|
By default, the system will decide which address to use in accordance
|
||||||
|
with the routing table.
|
||||||
|
.TP
|
||||||
|
.B \-ni\fIPATH\fR
|
||||||
|
(Linux only) Switch to the network namespace identified by
|
||||||
|
.I PATH
|
||||||
|
before opening the listening socket. The current namespace is saved and restored
|
||||||
|
immediately after binding, so outgoing connections run in the original namespace
|
||||||
|
unless
|
||||||
|
.B \-ne
|
||||||
|
is also given.
|
||||||
|
.TP
|
||||||
|
.B \-ne\fIPATH\fR
|
||||||
|
(Linux only) Switch to the network namespace identified by
|
||||||
|
.I PATH
|
||||||
|
after the listening socket has been bound (and after restoring from
|
||||||
|
.B \-ni
|
||||||
|
if applicable). Both options accept any namespace file path
|
||||||
|
(e.g.\& \fI/var/run/netns/myns\fR or \fI/proc/PID/ns/net\fR)
|
||||||
|
and require \fBCAP_SYS_ADMIN\fR.
|
||||||
|
.TP
|
||||||
|
.B -i
|
||||||
|
Internal address. IP address the proxy accepts connections to.
|
||||||
|
By default, connections to any interface are accepted. It\'s usually unsafe.
|
||||||
|
Unix domain sockets can be specified with
|
||||||
|
.I -iunix:/path/to/socket
|
||||||
|
syntax (e.g., -iunix:/var/run/imapp.sock). On Linux, abstract sockets use
|
||||||
|
.I -iunix:@socketname
|
||||||
|
syntax.
|
||||||
|
.TP
|
||||||
|
.B -p
|
||||||
|
Port. Port proxy listens for incoming connections. Default is 143.
|
||||||
|
.TP
|
||||||
|
.B -h
|
||||||
|
Default destination. It's used if the target address is not specified by the user.
|
||||||
|
.TP
|
||||||
|
.B -x
|
||||||
|
Disable STARTTLS support. STARTTLS is not announced in the CAPABILITY
|
||||||
|
response and the STARTTLS command is not accepted.
|
||||||
|
.TP
|
||||||
|
.B -l
|
||||||
|
Log. By default logging is to stdout. If
|
||||||
|
.I logfile
|
||||||
|
is specified logging is to file. Under Unix, if
|
||||||
|
.RI \' @ \'
|
||||||
|
precedes
|
||||||
|
.IR logfile ,
|
||||||
|
syslog is used for logging.
|
||||||
|
.TP
|
||||||
|
.B -S
|
||||||
|
Increase or decrease stack size. You may want to try something like -S8192 if you experience 3proxy
|
||||||
|
crashes.
|
||||||
|
.SH CLIENTS
|
||||||
|
You can use any MUA (Mail User Agent) with IMAPv4 support. Set the client to use
|
||||||
|
.I internal_ip
|
||||||
|
and
|
||||||
|
.IR port
|
||||||
|
as an IMAP server. The address of the real IMAP server must be configured as a part of
|
||||||
|
the IMAP username. The format for the username is
|
||||||
|
.IR username @ server ,
|
||||||
|
where
|
||||||
|
.I server
|
||||||
|
is the address of the IMAP server and
|
||||||
|
.I username
|
||||||
|
is the user\'s login on this IMAP server. The login itself may contain an \'@\' sign.
|
||||||
|
Supported client authentication methods are the LOGIN command, AUTHENTICATE PLAIN
|
||||||
|
and AUTHENTICATE LOGIN. With the server, the proxy authenticates using the method
|
||||||
|
chosen by the client if the server supports it (as advertised in the CAPABILITY
|
||||||
|
response); otherwise it falls back to AUTHENTICATE LOGIN, AUTHENTICATE PLAIN or
|
||||||
|
the LOGIN command, in this order of preference. Challenge-response authentication
|
||||||
|
(CRAM-MD5, etc.) is not supported, because it requires a challenge from the server
|
||||||
|
before we know which server to connect to.
|
||||||
|
When running as a 3proxy service (not as a standalone binary), STARTTLS is
|
||||||
|
supported and announced in the CAPABILITY response unless disabled with
|
||||||
|
.BR -x .
|
||||||
|
After the client issues STARTTLS, the connection is handled by
|
||||||
|
.BR tlspr (8):
|
||||||
|
the destination host is taken from the SNI of the client TLS handshake (or from
|
||||||
|
the -h option), the proxy performs STARTTLS negotiation with the destination
|
||||||
|
server, and then transparently passes TLS traffic between the client and the
|
||||||
|
server. If the destination server does not support STARTTLS, the TLS handshake
|
||||||
|
with the client fails.
|
||||||
|
.SH BUGS
|
||||||
|
Report all bugs to
|
||||||
|
.BR 3proxy@3proxy.org
|
||||||
|
.SH SEE ALSO
|
||||||
|
3proxy(8), ftppr(8), pop3p(8), proxy(8), smtpp(8), socks(8), tcppm(8), tlspr(8), udppm(8), syslogd(8),
|
||||||
|
.br
|
||||||
|
https://3proxy.org/
|
||||||
|
.SH AUTHORS
|
||||||
|
3proxy is designed by Vladimir Dubrovin <vlad@3proxy.org>
|
||||||
15
man/pop3p.8
15
man/pop3p.8
@ -9,6 +9,7 @@
|
|||||||
.IB \fR[ -i internal_ip\fR]
|
.IB \fR[ -i internal_ip\fR]
|
||||||
.IB \fR[ -e external_ip\fR]
|
.IB \fR[ -e external_ip\fR]
|
||||||
.IB \fR[ -h default_ip[:port]\fR]
|
.IB \fR[ -h default_ip[:port]\fR]
|
||||||
|
.IB \fR[ -x ]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B pop3p
|
.B pop3p
|
||||||
is POP3 gateway service to allow internal users to access external POP3
|
is POP3 gateway service to allow internal users to access external POP3
|
||||||
@ -66,6 +67,10 @@ Port. Port proxy listens for incoming connections. Default is 110.
|
|||||||
.B -h
|
.B -h
|
||||||
Default destination. It's used if the target address is not specified by the user.
|
Default destination. It's used if the target address is not specified by the user.
|
||||||
.TP
|
.TP
|
||||||
|
.B -x
|
||||||
|
Disable STARTTLS (STLS) support. STLS is not announced in the CAPA response
|
||||||
|
and the STLS command is not accepted.
|
||||||
|
.TP
|
||||||
.B -l
|
.B -l
|
||||||
Log. By default logging is to stdout. If
|
Log. By default logging is to stdout. If
|
||||||
.I logfile
|
.I logfile
|
||||||
@ -94,6 +99,16 @@ is the user\'s login on this POP3 server. The login itself may contain an \'@\'
|
|||||||
Only cleartext authentication is supported, because challenge-response
|
Only cleartext authentication is supported, because challenge-response
|
||||||
authentication (APOP, CRAM-MD5, etc.) requires a challenge from the server before
|
authentication (APOP, CRAM-MD5, etc.) requires a challenge from the server before
|
||||||
we know which server to connect to.
|
we know which server to connect to.
|
||||||
|
When running as a 3proxy service (not as a standalone binary), STLS is
|
||||||
|
supported and announced in the CAPA response unless disabled with
|
||||||
|
.BR -x .
|
||||||
|
After the client issues STLS, the connection is handled by
|
||||||
|
.BR tlspr (8):
|
||||||
|
the destination host is taken from the SNI of the client TLS handshake (or from
|
||||||
|
the -h option), the proxy performs STLS negotiation with the destination
|
||||||
|
server, and then transparently passes TLS traffic between the client and the
|
||||||
|
server. If the destination server does not support STLS, the TLS handshake
|
||||||
|
with the client fails.
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
Report all bugs to
|
Report all bugs to
|
||||||
.BR 3proxy@3proxy.org
|
.BR 3proxy@3proxy.org
|
||||||
|
|||||||
17
man/smtpp.8
17
man/smtpp.8
@ -9,6 +9,7 @@
|
|||||||
.IB \fR[ -i internal_ip\fR]
|
.IB \fR[ -i internal_ip\fR]
|
||||||
.IB \fR[ -e external_ip\fR]
|
.IB \fR[ -e external_ip\fR]
|
||||||
.IB \fR[ -h default_ip[:port]\fR]
|
.IB \fR[ -h default_ip[:port]\fR]
|
||||||
|
.IB \fR[ -x ]
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B smtpp
|
.B smtpp
|
||||||
is SMTP gateway service to allow internal users to access external SMTP
|
is SMTP gateway service to allow internal users to access external SMTP
|
||||||
@ -61,11 +62,15 @@ syntax (e.g., -iunix:/var/run/smtpp.sock). On Linux, abstract sockets use
|
|||||||
syntax.
|
syntax.
|
||||||
.TP
|
.TP
|
||||||
.B -p
|
.B -p
|
||||||
Port. Port proxy listens for incoming connections. Default is 25.
|
Port. Port proxy listens for incoming connections. Default is 587.
|
||||||
.TP
|
.TP
|
||||||
.B -h
|
.B -h
|
||||||
Default destination. It's used if the target address is not specified by the user.
|
Default destination. It's used if the target address is not specified by the user.
|
||||||
.TP
|
.TP
|
||||||
|
.B -x
|
||||||
|
Disable STARTTLS support. STARTTLS is not announced in the EHLO response
|
||||||
|
and the STARTTLS command is not accepted.
|
||||||
|
.TP
|
||||||
.B -l
|
.B -l
|
||||||
Log. By default logging is to stdout. If
|
Log. By default logging is to stdout. If
|
||||||
.I logfile
|
.I logfile
|
||||||
@ -95,6 +100,16 @@ is the user\'s login on this SMTP server. The login itself may contain an \'@\'
|
|||||||
Only cleartext authentication is supported, because challenge-response
|
Only cleartext authentication is supported, because challenge-response
|
||||||
authentication (CRAM-MD5, SPA, etc.) requires a challenge from the server before
|
authentication (CRAM-MD5, SPA, etc.) requires a challenge from the server before
|
||||||
we know which server to connect to.
|
we know which server to connect to.
|
||||||
|
When running as a 3proxy service (not as a standalone binary), STARTTLS is
|
||||||
|
supported and announced in the EHLO response unless disabled with
|
||||||
|
.BR -x .
|
||||||
|
After the client issues STARTTLS, the connection is handled by
|
||||||
|
.BR tlspr (8):
|
||||||
|
the destination host is taken from the SNI of the client TLS handshake (or from
|
||||||
|
the -h option), the proxy performs STARTTLS negotiation with the destination
|
||||||
|
server, and then transparently passes TLS traffic between the client and the
|
||||||
|
server. If the destination server does not support STARTTLS, the TLS handshake
|
||||||
|
with the client fails.
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
Report all bugs to
|
Report all bugs to
|
||||||
.BR 3proxy@3proxy.org
|
.BR 3proxy@3proxy.org
|
||||||
|
|||||||
10
man/tlspr.8
10
man/tlspr.8
@ -13,6 +13,7 @@
|
|||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B tlspr
|
.B tlspr
|
||||||
is an SNI gateway service (destination host is taken from TLS handshake). The destination port must be specified via the -P option (or it may be detected with the Transparent plugin).
|
is an SNI gateway service (destination host is taken from TLS handshake). The destination port must be specified via the -P option (or it may be detected with the Transparent plugin).
|
||||||
|
tlspr does not support user authentication; use ACLs by client IP or a parent proxy with authentication if access control is required.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
.TP
|
.TP
|
||||||
.B -I
|
.B -I
|
||||||
@ -78,6 +79,15 @@ TLS_CHECK_LEVEL. 0 (default) - allow non-TLS traffic to pass, 1 - require TLS, o
|
|||||||
.B -s
|
.B -s
|
||||||
Split the TLS Client HELLO packet across multiple TCP segments to make SNI-based DPI detection harder. An optional numeric value can follow (e.g. \fB-s1\fR) to control the splitting behaviour.
|
Split the TLS Client HELLO packet across multiple TCP segments to make SNI-based DPI detection harder. An optional numeric value can follow (e.g. \fB-s1\fR) to control the splitting behaviour.
|
||||||
.TP
|
.TP
|
||||||
|
.B -Ximap | -Xpop3 | -Xsmtp
|
||||||
|
STARTTLS mode for the given protocol. The proxy speaks the plaintext protocol
|
||||||
|
with the client (greeting, capability advertisement with STARTTLS only, STARTTLS
|
||||||
|
command), then, after the client issues STARTTLS and sends a TLS Client HELLO,
|
||||||
|
connects to the destination taken from SNI (default port 143/110/587), performs
|
||||||
|
STARTTLS negotiation with the destination server and transparently passes TLS
|
||||||
|
traffic. If the destination server does not support STARTTLS, the TLS handshake
|
||||||
|
with the client fails.
|
||||||
|
.TP
|
||||||
.B -l
|
.B -l
|
||||||
Log. By default logging is to stdout. If
|
Log. By default logging is to stdout. If
|
||||||
.I logfile
|
.I logfile
|
||||||
|
|||||||
@ -537,6 +537,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
freeconf(&conf);
|
freeconf(&conf);
|
||||||
|
initcommands();
|
||||||
res = readconfig(fp);
|
res = readconfig(fp);
|
||||||
conf.version++;
|
conf.version++;
|
||||||
|
|
||||||
|
|||||||
@ -5,14 +5,7 @@
|
|||||||
please read License Agreement
|
please read License Agreement
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#include "libs/blake2.h"
|
#include "mdhash.h"
|
||||||
#ifdef WITH_SSL
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
#include <openssl/params.h>
|
|
||||||
#include <openssl/core_names.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define MD5_SIZE 16
|
#define MD5_SIZE 16
|
||||||
@ -28,11 +21,6 @@ static unsigned char itoa64[] =
|
|||||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
|
||||||
#if defined(WITH_SSL) && OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
EVP_MD *md4_hash = NULL;
|
|
||||||
EVP_MD *md5_hash = NULL;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_crypt_to64(unsigned char *s, unsigned long v, int n)
|
_crypt_to64(unsigned char *s, unsigned long v, int n)
|
||||||
{
|
{
|
||||||
@ -43,21 +31,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 * ntpwdhash (unsigned char *szHash, const unsigned char *szPassword, int ctohex)
|
||||||
{
|
{
|
||||||
unsigned char szUnicodePass[513];
|
unsigned char szUnicodePass[513];
|
||||||
unsigned int nPasswordLen;
|
unsigned int nPasswordLen;
|
||||||
EVP_MD_CTX *ctx;
|
unsigned int len = 16;
|
||||||
unsigned int len=sizeof(szUnicodePass);
|
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
mdh_ctx *ctx;
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
const EVP_MD *md4 = md4_hash;
|
|
||||||
#else
|
|
||||||
const EVP_MD *md4 = EVP_md4();
|
|
||||||
#endif
|
|
||||||
if(md4 == NULL) return NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NT passwords are unicode. Convert plain text password
|
* NT passwords are unicode. Convert plain text password
|
||||||
@ -71,15 +51,14 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Encrypt Unicode password to a 16-byte MD4 hash */
|
/* Encrypt Unicode password to a 16-byte MD4 hash */
|
||||||
ctx = EVP_MD_CTX_new();
|
ctx = mdh_init(MDH_MD4, 16);
|
||||||
if(!ctx) return NULL;
|
if(!ctx) return NULL;
|
||||||
if(!EVP_DigestInit_ex(ctx, md4, NULL)){
|
mdh_update(ctx, szUnicodePass, (nPasswordLen<<1));
|
||||||
EVP_MD_CTX_free(ctx);
|
if(!mdh_final(ctx, szUnicodePass, &len)) {
|
||||||
|
mdh_free(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EVP_DigestUpdate(ctx, szUnicodePass, (nPasswordLen<<1));
|
mdh_free(ctx);
|
||||||
EVP_DigestFinal_ex(ctx, szUnicodePass, &len);
|
|
||||||
EVP_MD_CTX_free(ctx);
|
|
||||||
if (ctohex){
|
if (ctohex){
|
||||||
tohex(szUnicodePass, szHash, 16);
|
tohex(szUnicodePass, szHash, 16);
|
||||||
}
|
}
|
||||||
@ -87,7 +66,6 @@ unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPasswor
|
|||||||
memset(szUnicodePass, 0, sizeof szUnicodePass);
|
memset(szUnicodePass, 0, sizeof szUnicodePass);
|
||||||
return szHash;
|
return szHash;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsigned char *passwd){
|
unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsigned char *passwd){
|
||||||
@ -100,57 +78,44 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
|
|||||||
int sl;
|
int sl;
|
||||||
unsigned long l;
|
unsigned long l;
|
||||||
|
|
||||||
#if defined(WITH_SSL)
|
|
||||||
#ifndef WITHMAIN
|
#ifndef WITHMAIN
|
||||||
if(salt[0] == '$' && salt[1] == '1' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
|
if(salt[0] == '$' && salt[1] == '1' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
|
||||||
EVP_MD_CTX *ctx, *ctx1;
|
mdh_ctx *ctx, *ctx1;
|
||||||
unsigned int len;
|
unsigned int len = MD5_SIZE;
|
||||||
int pl, i;
|
int pl, i;
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
const EVP_MD *md5 = md5_hash;
|
|
||||||
#else
|
|
||||||
const EVP_MD *md5 = EVP_md5();
|
|
||||||
#endif
|
|
||||||
if(md5 == NULL) {
|
|
||||||
*passwd = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
sp = salt +3;
|
sp = salt +3;
|
||||||
sl = (int)(ep - sp);
|
sl = (int)(ep - sp);
|
||||||
magic = (unsigned char *)"$1$";
|
magic = (unsigned char *)"$1$";
|
||||||
|
|
||||||
ctx = EVP_MD_CTX_new();
|
ctx = mdh_init(MDH_MD5, 16);
|
||||||
if(!ctx) {
|
if(!ctx) {
|
||||||
*passwd = 0;
|
*passwd = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EVP_DigestInit_ex(ctx, md5, NULL);
|
|
||||||
|
|
||||||
/* The password first, since that is what is most unknown */
|
/* The password first, since that is what is most unknown */
|
||||||
EVP_DigestUpdate(ctx,pw,strlen((char *)pw));
|
mdh_update(ctx, pw, (unsigned int)strlen((char *)pw));
|
||||||
|
|
||||||
/* Then our magic string */
|
/* Then our magic string */
|
||||||
EVP_DigestUpdate(ctx,magic,strlen((char *)magic));
|
mdh_update(ctx, magic, (unsigned int)strlen((char *)magic));
|
||||||
|
|
||||||
/* Then the raw salt */
|
/* Then the raw salt */
|
||||||
EVP_DigestUpdate(ctx,sp,sl);
|
mdh_update(ctx, sp, (unsigned int)sl);
|
||||||
|
|
||||||
/* Then just as many unsigned characters of the MD5(pw,salt,pw) */
|
/* Then just as many unsigned characters of the MD5(pw,salt,pw) */
|
||||||
ctx1 = EVP_MD_CTX_new();
|
ctx1 = mdh_init(MDH_MD5, 16);
|
||||||
if(!ctx1) {
|
if(!ctx1) {
|
||||||
EVP_MD_CTX_free(ctx);
|
mdh_free(ctx);
|
||||||
*passwd = 0;
|
*passwd = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
EVP_DigestInit_ex(ctx1, md5, NULL);
|
mdh_update(ctx1, pw, (unsigned int)strlen((char *)pw));
|
||||||
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
|
mdh_update(ctx1, sp, (unsigned int)sl);
|
||||||
EVP_DigestUpdate(ctx1,sp,sl);
|
mdh_update(ctx1, pw, (unsigned int)strlen((char *)pw));
|
||||||
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
|
mdh_final(ctx1, final, &len);
|
||||||
EVP_DigestFinal_ex(ctx1,final,&len);
|
|
||||||
for(pl = (int)strlen((char *)pw); pl > 0; pl -= MD5_SIZE)
|
for(pl = (int)strlen((char *)pw); pl > 0; pl -= MD5_SIZE)
|
||||||
EVP_DigestUpdate(ctx,final,pl>MD5_SIZE ? MD5_SIZE : pl);
|
mdh_update(ctx, final, (unsigned int)(pl>MD5_SIZE ? MD5_SIZE : pl));
|
||||||
|
|
||||||
/* Don't leave anything around in vm they could use. */
|
/* Don't leave anything around in vm they could use. */
|
||||||
memset(final,0,sizeof final);
|
memset(final,0,sizeof final);
|
||||||
@ -158,13 +123,13 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
|
|||||||
/* Then something really weird... */
|
/* Then something really weird... */
|
||||||
for (i = (int)strlen((char *)pw); i ; i >>= 1)
|
for (i = (int)strlen((char *)pw); i ; i >>= 1)
|
||||||
if(i&1)
|
if(i&1)
|
||||||
EVP_DigestUpdate(ctx, final, 1);
|
mdh_update(ctx, final, 1);
|
||||||
else
|
else
|
||||||
EVP_DigestUpdate(ctx, pw, 1);
|
mdh_update(ctx, pw, 1);
|
||||||
|
|
||||||
|
|
||||||
EVP_DigestFinal_ex(ctx,final,&len);
|
mdh_final(ctx, final, &len);
|
||||||
EVP_MD_CTX_free(ctx);
|
mdh_free(ctx);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* and now, just to make sure things don't run too fast
|
* and now, just to make sure things don't run too fast
|
||||||
@ -172,43 +137,46 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
|
|||||||
* need 30 seconds to build a 1000 entry dictionary...
|
* need 30 seconds to build a 1000 entry dictionary...
|
||||||
*/
|
*/
|
||||||
for(i=0;i<1000;i++) {
|
for(i=0;i<1000;i++) {
|
||||||
EVP_MD_CTX_reset(ctx1);
|
mdh_free(ctx1);
|
||||||
EVP_DigestInit_ex(ctx1, md5, NULL);
|
ctx1 = mdh_init(MDH_MD5, 16);
|
||||||
|
if(!ctx1) { *passwd = 0; return NULL; }
|
||||||
if(i & 1)
|
if(i & 1)
|
||||||
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
|
mdh_update(ctx1, pw, (unsigned int)strlen((char *)pw));
|
||||||
else
|
else
|
||||||
EVP_DigestUpdate(ctx1,final,MD5_SIZE);
|
mdh_update(ctx1, final, MD5_SIZE);
|
||||||
|
|
||||||
if(i % 3)
|
if(i % 3)
|
||||||
EVP_DigestUpdate(ctx1,sp,sl);
|
mdh_update(ctx1, sp, (unsigned int)sl);
|
||||||
|
|
||||||
if(i % 7)
|
if(i % 7)
|
||||||
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
|
mdh_update(ctx1, pw, (unsigned int)strlen((char *)pw));
|
||||||
|
|
||||||
if(i & 1)
|
if(i & 1)
|
||||||
EVP_DigestUpdate(ctx1,final,MD5_SIZE);
|
mdh_update(ctx1, final, MD5_SIZE);
|
||||||
else
|
else
|
||||||
EVP_DigestUpdate(ctx1,pw,strlen((char *)pw));
|
mdh_update(ctx1, pw, (unsigned int)strlen((char *)pw));
|
||||||
EVP_DigestFinal_ex(ctx1,final,&len);
|
mdh_final(ctx1, final, &len);
|
||||||
}
|
}
|
||||||
EVP_MD_CTX_free(ctx1);
|
mdh_free(ctx1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
if(salt[0] == '$' && salt[1] == '3' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
|
if(salt[0] == '$' && salt[1] == '3' && salt[2] == '$' && (ep = (unsigned char *)strchr((char *)salt+3, '$'))) {
|
||||||
sp = salt +3;
|
sp = salt +3;
|
||||||
sl = (int)(ep - sp);
|
sl = (int)(ep - sp);
|
||||||
magic = (unsigned char *)"$3$";
|
magic = (unsigned char *)"$3$";
|
||||||
{
|
{
|
||||||
blake2b_state S;
|
mdh_ctx *bctx = mdh_init(MDH_BLAKE2, MD5_SIZE);
|
||||||
if(blake2b_init(&S, MD5_SIZE) != 0 ||
|
unsigned int blen = MD5_SIZE;
|
||||||
blake2b_update(&S, pw, strlen((char *)pw) + 1) != 0 ||
|
if(!bctx ||
|
||||||
blake2b_update(&S, sp, sl) != 0 ||
|
!mdh_update(bctx, pw, (unsigned int)(strlen((char *)pw) + 1)) ||
|
||||||
blake2b_final(&S, final, MD5_SIZE) != 0) {
|
!mdh_update(bctx, sp, (unsigned int)sl) ||
|
||||||
|
!mdh_final(bctx, final, &blen)) {
|
||||||
|
mdh_free(bctx);
|
||||||
*passwd = 0;
|
*passwd = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
mdh_free(bctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -238,9 +206,6 @@ unsigned char * mycrypt(const unsigned char *pw, const unsigned char *salt, unsi
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITHMAIN
|
#ifdef WITHMAIN
|
||||||
#if defined(WITH_SSL) && OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
#include <openssl/provider.h>
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
int main(int argc, char* argv[]){
|
int main(int argc, char* argv[]){
|
||||||
unsigned char buf1[128];
|
unsigned char buf1[128];
|
||||||
@ -248,37 +213,17 @@ int main(int argc, char* argv[]){
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
if(argc < 2 || argc > 3) {
|
if(argc < 2 || argc > 3) {
|
||||||
fprintf(stderr, "usage: \n"
|
fprintf(stderr, "usage: \n"
|
||||||
#ifdef WITH_SSL
|
|
||||||
"\t%s <password>\n"
|
"\t%s <password>\n"
|
||||||
#endif
|
|
||||||
"\t%s <salt> <password>\n"
|
"\t%s <salt> <password>\n"
|
||||||
#ifdef WITH_SSL
|
|
||||||
"Performs NT crypt if no salt specified, BLAKE2 crypt with salt\n"
|
"Performs NT crypt if no salt specified, BLAKE2 crypt with salt\n"
|
||||||
#else
|
|
||||||
"Performs BLAKE2 crypt with salt\n"
|
|
||||||
#endif
|
|
||||||
,
|
,
|
||||||
#ifdef WITH_SSL
|
|
||||||
argv[0],
|
argv[0],
|
||||||
#endif
|
|
||||||
argv[0]);
|
argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#if defined(WITH_SSL) && OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
OSSL_PROVIDER_load(NULL, "legacy");
|
|
||||||
OSSL_PROVIDER_load(NULL, "default");
|
|
||||||
md4_hash = EVP_MD_fetch(NULL, "MD4", NULL);
|
|
||||||
if (md4_hash == NULL) {
|
|
||||||
fprintf(stderr, "Error fetching MD4\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if(argc == 2) {
|
if(argc == 2) {
|
||||||
#ifdef WITH_SSL
|
|
||||||
{ unsigned char *nt = ntpwdhash(buf1, (unsigned char *)argv[1], 1);
|
{ unsigned char *nt = ntpwdhash(buf1, (unsigned char *)argv[1], 1);
|
||||||
if(nt) printf("NT:%s\n", nt); }
|
if(nt) printf("NT:%s\n", nt); }
|
||||||
#else
|
|
||||||
fprintf(stderr, "NT crypt not available (compiled without OpenSSL)\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned char *cr;
|
unsigned char *cr;
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
# 3 proxy common Makefile
|
# 3 proxy common Makefile
|
||||||
#
|
#
|
||||||
|
|
||||||
all: $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS) $(BUILDDIR)$(PREFIX)pop3p$(EXESUFFICS) $(BUILDDIR)$(PREFIX)smtpp$(EXESUFFICS) $(BUILDDIR)$(PREFIX)ftppr$(EXESUFFICS) $(BUILDDIR)$(PREFIX)tcppm$(EXESUFFICS) $(BUILDDIR)$(PREFIX)udppm$(EXESUFFICS) $(BUILDDIR)$(PREFIX)tlspr$(EXESUFFICS) $(BUILDDIR)$(PREFIX)socks$(EXESUFFICS) $(BUILDDIR)$(PREFIX)proxy$(EXESUFFICS) allplugins
|
all: $(BUILDDIR)3proxy$(EXESUFFICS) $(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS) $(BUILDDIR)$(PREFIX)pop3p$(EXESUFFICS) $(BUILDDIR)$(PREFIX)imapp$(EXESUFFICS) $(BUILDDIR)$(PREFIX)smtpp$(EXESUFFICS) $(BUILDDIR)$(PREFIX)ftppr$(EXESUFFICS) $(BUILDDIR)$(PREFIX)tcppm$(EXESUFFICS) $(BUILDDIR)$(PREFIX)udppm$(EXESUFFICS) $(BUILDDIR)$(PREFIX)tlspr$(EXESUFFICS) $(BUILDDIR)$(PREFIX)socks$(EXESUFFICS) $(BUILDDIR)$(PREFIX)proxy$(EXESUFFICS) allplugins
|
||||||
|
|
||||||
sockmap$(OBJSUFFICS): sockmap.c proxy.h structures.h
|
sockmap$(OBJSUFFICS): sockmap.c proxy.h structures.h
|
||||||
$(CC) $(CFLAGS) sockmap.c
|
$(CC) $(CFLAGS) sockmap.c
|
||||||
@ -31,6 +31,9 @@ proxy$(OBJSUFFICS): proxy.c proxy.h structures.h proxymain.c
|
|||||||
pop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h proxymain.c
|
pop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h proxymain.c
|
||||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP $(DEFINEOPTION)NOUDPMAIN pop3p.c
|
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP $(DEFINEOPTION)NOUDPMAIN pop3p.c
|
||||||
|
|
||||||
|
imapp$(OBJSUFFICS): imapp.c proxy.h structures.h proxymain.c
|
||||||
|
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP $(DEFINEOPTION)NOUDPMAIN imapp.c
|
||||||
|
|
||||||
smtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h proxymain.c
|
smtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h proxymain.c
|
||||||
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP $(DEFINEOPTION)NOUDPMAIN smtpp.c
|
$(CC) $(CFLAGS) $(DEFINEOPTION)WITHMAIN $(DEFINEOPTION)NOPORTMAP $(DEFINEOPTION)NOUDPMAIN smtpp.c
|
||||||
|
|
||||||
@ -59,6 +62,9 @@ $(BUILDDIR)$(PREFIX)proxy$(EXESUFFICS): sockmap$(OBJSUFFICS) proxy$(OBJSUFFICS)
|
|||||||
$(BUILDDIR)$(PREFIX)pop3p$(EXESUFFICS): sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) $(COMPATLIBS)
|
$(BUILDDIR)$(PREFIX)pop3p$(EXESUFFICS): sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) $(COMPATLIBS)
|
||||||
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)pop3p$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)pop3p$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) pop3p$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||||
|
|
||||||
|
$(BUILDDIR)$(PREFIX)imapp$(EXESUFFICS): sockmap$(OBJSUFFICS) imapp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
|
||||||
|
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)imapp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) imapp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||||
|
|
||||||
$(BUILDDIR)$(PREFIX)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
|
$(BUILDDIR)$(PREFIX)smtpp$(EXESUFFICS): sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) common$(OBJSUFFICS) log$(OBJSUFFICS) base64$(OBJSUFFICS) $(COMPATLIBS)
|
||||||
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)smtpp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) base64$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
$(LN) $(LNOUT)$(BUILDDIR)$(PREFIX)smtpp$(EXESUFFICS) $(LDFLAGS) sockmap$(OBJSUFFICS) smtpp$(OBJSUFFICS) sockgetchar$(OBJSUFFICS) base64$(OBJSUFFICS) log$(OBJSUFFICS) common$(OBJSUFFICS) $(COMPATLIBS) $(LIBS)
|
||||||
|
|
||||||
@ -86,6 +92,9 @@ srvproxy$(OBJSUFFICS): proxy.c proxy.h structures.h
|
|||||||
srvpop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h
|
srvpop3p$(OBJSUFFICS): pop3p.c proxy.h structures.h
|
||||||
$(CC) $(COUT)srvpop3p$(OBJSUFFICS) $(CFLAGS) pop3p.c
|
$(CC) $(COUT)srvpop3p$(OBJSUFFICS) $(CFLAGS) pop3p.c
|
||||||
|
|
||||||
|
srvimapp$(OBJSUFFICS): imapp.c proxy.h structures.h
|
||||||
|
$(CC) $(COUT)srvimapp$(OBJSUFFICS) $(CFLAGS) imapp.c
|
||||||
|
|
||||||
srvsmtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h
|
srvsmtpp$(OBJSUFFICS): smtpp.c proxy.h structures.h
|
||||||
$(CC) $(COUT)srvsmtpp$(OBJSUFFICS) $(CFLAGS) smtpp.c
|
$(CC) $(COUT)srvsmtpp$(OBJSUFFICS) $(CFLAGS) smtpp.c
|
||||||
|
|
||||||
@ -134,7 +143,7 @@ hashtables$(OBJSUFFICS): hashtables.c proxy.h structures.h libs/blake2.h
|
|||||||
resolve$(OBJSUFFICS): resolve.c proxy.h structures.h
|
resolve$(OBJSUFFICS): resolve.c proxy.h structures.h
|
||||||
$(CC) $(COUT)resolve$(OBJSUFFICS) $(CFLAGS) resolve.c
|
$(CC) $(COUT)resolve$(OBJSUFFICS) $(CFLAGS) resolve.c
|
||||||
|
|
||||||
authradius$(OBJSUFFICS): authradius.c proxy.h structures.h
|
authradius$(OBJSUFFICS): authradius.c proxy.h structures.h mdhash.h
|
||||||
$(CC) $(COUT)authradius$(OBJSUFFICS) $(CFLAGS) authradius.c
|
$(CC) $(COUT)authradius$(OBJSUFFICS) $(CFLAGS) authradius.c
|
||||||
|
|
||||||
conf$(OBJSUFFICS): conf.c proxy.h structures.h
|
conf$(OBJSUFFICS): conf.c proxy.h structures.h
|
||||||
@ -146,17 +155,26 @@ log$(OBJSUFFICS): log.c proxy.h structures.h
|
|||||||
datatypes$(OBJSUFFICS): datatypes.c proxy.h structures.h
|
datatypes$(OBJSUFFICS): datatypes.c proxy.h structures.h
|
||||||
$(CC) $(COUT)datatypes$(OBJSUFFICS) $(CFLAGS) datatypes.c
|
$(CC) $(COUT)datatypes$(OBJSUFFICS) $(CFLAGS) datatypes.c
|
||||||
|
|
||||||
3proxy_crypt$(OBJSUFFICS): 3proxy_crypt.c libs/blake2.h
|
3proxy_crypt$(OBJSUFFICS): 3proxy_crypt.c libs/blake2.h mdhash.h
|
||||||
$(CC) $(COUT)3proxy_crypt$(OBJSUFFICS) $(CFLAGS) 3proxy_crypt.c
|
$(CC) $(COUT)3proxy_crypt$(OBJSUFFICS) $(CFLAGS) 3proxy_crypt.c
|
||||||
|
|
||||||
3proxy_cryptmain$(OBJSUFFICS): 3proxy_crypt.c libs/blake2.h
|
3proxy_cryptmain$(OBJSUFFICS): 3proxy_crypt.c libs/blake2.h mdhash.h
|
||||||
$(CC) $(COUT)3proxy_cryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN 3proxy_crypt.c
|
$(CC) $(COUT)3proxy_cryptmain$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITHMAIN 3proxy_crypt.c
|
||||||
|
|
||||||
blake2$(OBJSUFFICS): libs/blake2b-ref.c
|
blake2$(OBJSUFFICS): libs/blake2b-ref.c
|
||||||
$(CC) $(COUT)blake2$(OBJSUFFICS) $(CFLAGS) libs/blake2b-ref.c
|
$(CC) $(COUT)blake2$(OBJSUFFICS) $(CFLAGS) libs/blake2b-ref.c
|
||||||
|
|
||||||
$(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS): blake2$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) base64$(OBJSUFFICS)
|
mdhash$(OBJSUFFICS): mdhash.c mdhash.h proxy.h structures.h
|
||||||
$(LN) $(LNOUT)$(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS) $(LDFLAGS) blake2$(OBJSUFFICS) base64$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) $(LIBS)
|
$(CC) $(COUT)mdhash$(OBJSUFFICS) $(CFLAGS) mdhash.c
|
||||||
|
|
||||||
|
md4$(OBJSUFFICS): libs/md4.c libs/md4.h
|
||||||
|
$(CC) $(COUT)md4$(OBJSUFFICS) $(CFLAGS) libs/md4.c
|
||||||
|
|
||||||
|
md5$(OBJSUFFICS): libs/md5.c libs/md5.h
|
||||||
|
$(CC) $(COUT)md5$(OBJSUFFICS) $(CFLAGS) libs/md5.c
|
||||||
|
|
||||||
|
$(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS): md4$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) base64$(OBJSUFFICS) mdhash$(OBJSUFFICS)
|
||||||
|
$(LN) $(LNOUT)$(BUILDDIR)$(CRYPT_PREFIX)crypt$(EXESUFFICS) $(LDFLAGS) md4$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) base64$(OBJSUFFICS) mdhash$(OBJSUFFICS) 3proxy_cryptmain$(OBJSUFFICS) $(LIBS)
|
||||||
|
|
||||||
stringtable$(OBJSUFFICS): stringtable.c
|
stringtable$(OBJSUFFICS): stringtable.c
|
||||||
$(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c
|
$(CC) $(COUT)stringtable$(OBJSUFFICS) $(CFLAGS) stringtable.c
|
||||||
@ -170,6 +188,6 @@ ssl$(OBJSUFFICS): ssl.c structures.h proxy.h ssl.h
|
|||||||
pcre$(OBJSUFFICS): pcre.c structures.h
|
pcre$(OBJSUFFICS): pcre.c structures.h
|
||||||
$(CC) $(COUT)pcre$(OBJSUFFICS) $(CFLAGS) $(DEFINEOPTION)WITH_PCRE 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)
|
$(BUILDDIR)3proxy$(EXESUFFICS): 3proxy$(OBJSUFFICS) mainfunc$(OBJSUFFICS) srvproxy$(OBJSUFFICS) srvpop3p$(OBJSUFFICS) srvimapp$(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) md4$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) 3proxy_crypt$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) mdhash$(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)
|
$(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) srvimapp$(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) md4$(OBJSUFFICS) md5$(OBJSUFFICS) blake2$(OBJSUFFICS) base64$(OBJSUFFICS) ftp$(OBJSUFFICS) stringtable$(OBJSUFFICS) srvwebadmin$(OBJSUFFICS) srvdnspr$(OBJSUFFICS) plugins$(OBJSUFFICS) mdhash$(OBJSUFFICS) $(SSL_OBJS) $(PCRE_OBJS) $(COMPATLIBS) $(LIBS) $(PCRE_LIBS)
|
||||||
|
|
||||||
|
|||||||
40
src/auth.c
40
src/auth.c
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
#include "libs/blake2.h"
|
#include "mdhash.h"
|
||||||
|
|
||||||
void initbandlims(struct clientparam *param);
|
void initbandlims(struct clientparam *param);
|
||||||
|
|
||||||
@ -216,6 +216,24 @@ int dnsauth(struct clientparam * param){
|
|||||||
return param->username? 0:3;
|
return param->username? 0:3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ctmemcmp(const void *a, const void *b, size_t len){
|
||||||
|
const unsigned char *pa = (const unsigned char *)a, *pb = (const unsigned char *)b;
|
||||||
|
unsigned char diff = 0;
|
||||||
|
size_t i;
|
||||||
|
for(i = 0; i < len; i++) diff |= (unsigned char)(pa[i] ^ pb[i]);
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ctstrcmp(const char *a, const char *b, size_t maxlen){
|
||||||
|
unsigned char diff = 0;
|
||||||
|
size_t i;
|
||||||
|
for(i = 0; i < maxlen; i++){
|
||||||
|
diff |= (unsigned char)((unsigned char)a[i] ^ (unsigned char)b[i]);
|
||||||
|
if(!a[i] && !b[i]) break;
|
||||||
|
}
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
int strongauth(struct clientparam * param){
|
int strongauth(struct clientparam * param){
|
||||||
static char dummy;
|
static char dummy;
|
||||||
unsigned char buf[256];
|
unsigned char buf[256];
|
||||||
@ -229,27 +247,31 @@ int strongauth(struct clientparam * param){
|
|||||||
int pwlen = strlen((char *)param->password);
|
int pwlen = strlen((char *)param->password);
|
||||||
if(pwlen > 255) pwlen = 255;
|
if(pwlen > 255) pwlen = 255;
|
||||||
if((unsigned)pwlen < pwl_table.recsize) {
|
if((unsigned)pwlen < pwl_table.recsize) {
|
||||||
if(!strncmp(pass + 1, (char *)param->password, pwl_table.recsize - 1)) return 0;
|
if(strlen(pass + 1) == strlen((char *)param->password) && !ctmemcmp(pass + 1, param->password, pwl_table.recsize - 1)) return 0;
|
||||||
} else {
|
} else {
|
||||||
blake2b_state S;
|
mdh_ctx *bctx;
|
||||||
unsigned hashsz;
|
unsigned hashsz;
|
||||||
|
unsigned int blen;
|
||||||
hashsz = pwl_table.recsize - 1 < 64 ? pwl_table.recsize - 1 : 64;
|
hashsz = pwl_table.recsize - 1 < 64 ? pwl_table.recsize - 1 : 64;
|
||||||
memset(buf, 0, pwl_table.recsize - 1);
|
memset(buf, 0, pwl_table.recsize - 1);
|
||||||
blake2b_init(&S, hashsz);
|
bctx = mdh_init(MDH_BLAKE2, hashsz);
|
||||||
blake2b_update(&S, param->password, pwlen + 1);
|
if(!bctx) return 6;
|
||||||
blake2b_final(&S, buf, hashsz);
|
mdh_update(bctx, param->password, pwlen + 1);
|
||||||
if(!memcmp(pass + 1, buf, pwl_table.recsize - 1)) return 0;
|
blen = hashsz;
|
||||||
|
mdh_final(bctx, buf, &blen);
|
||||||
|
mdh_free(bctx);
|
||||||
|
if(!ctmemcmp(pass + 1, buf, pwl_table.recsize - 1)) return 0;
|
||||||
}
|
}
|
||||||
return 6;
|
return 6;
|
||||||
}
|
}
|
||||||
case CR:
|
case CR:
|
||||||
if (mycrypt(param->password, (unsigned char *)pass + 1, buf) &&
|
if (mycrypt(param->password, (unsigned char *)pass + 1, buf) &&
|
||||||
!strcmp(pass + 1, (char *)buf))
|
!ctstrcmp(pass + 1, (char *)buf, sizeof(pass) - 1))
|
||||||
return 0;
|
return 0;
|
||||||
else return 7;
|
else return 7;
|
||||||
#ifdef WITH_SSL
|
#ifdef WITH_SSL
|
||||||
case NT:
|
case NT:
|
||||||
if(ntpwdhash(buf, param->password, 1) && !strcmp(pass + 1, (char *)buf)) return 0;
|
if(ntpwdhash(buf, param->password, 1) && !ctstrcmp(pass + 1, (char *)buf, sizeof(pass) - 1)) return 0;
|
||||||
else return 8;
|
else return 8;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#ifndef NORADIUS
|
#ifndef NORADIUS
|
||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
#include <openssl/evp.h>
|
#include "mdhash.h"
|
||||||
|
|
||||||
#define AUTH_VECTOR_LEN 16
|
#define AUTH_VECTOR_LEN 16
|
||||||
#define MAX_STRING_LEN 254
|
#define MAX_STRING_LEN 254
|
||||||
@ -185,25 +185,15 @@ char *strNcpy(char *dest, const char *src, int n)
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
extern EVP_MD *md4_hash;
|
|
||||||
extern EVP_MD *md5_hash;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void md5_calc(unsigned char *output, unsigned char *input,
|
void md5_calc(unsigned char *output, unsigned char *input,
|
||||||
unsigned int inlen)
|
unsigned int inlen)
|
||||||
{
|
{
|
||||||
EVP_MD_CTX *ctx = EVP_MD_CTX_new();
|
mdh_ctx *ctx = mdh_init(MDH_MD5, 16);
|
||||||
unsigned int len = 0;
|
unsigned int len = 16;
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
if(!ctx) return;
|
||||||
EVP_DigestInit_ex(ctx, md5_hash, NULL);
|
mdh_update(ctx, input, inlen);
|
||||||
#else
|
mdh_final(ctx, output, &len);
|
||||||
EVP_DigestInit_ex(ctx, EVP_md5(), NULL);
|
mdh_free(ctx);
|
||||||
#endif
|
|
||||||
EVP_DigestUpdate(ctx, input, inlen);
|
|
||||||
EVP_DigestFinal_ex(ctx, output, &len);
|
|
||||||
EVP_MD_CTX_free(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
35
src/common.c
35
src/common.c
@ -17,6 +17,8 @@ char * copyright = COPYRIGHT;
|
|||||||
# define MYRAND_ARC4RANDOM 1
|
# define MYRAND_ARC4RANDOM 1
|
||||||
#elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 36)))
|
#elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 36)))
|
||||||
# define MYRAND_ARC4RANDOM 1
|
# define MYRAND_ARC4RANDOM 1
|
||||||
|
#elif defined(__GLIBC__) && ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 25)))
|
||||||
|
# define MYRAND_FALLBACK 1
|
||||||
#elif defined(__linux__)
|
#elif defined(__linux__)
|
||||||
# define MYRAND_GETRANDOM 1
|
# define MYRAND_GETRANDOM 1
|
||||||
# include <sys/random.h>
|
# include <sys/random.h>
|
||||||
@ -497,6 +499,14 @@ int parsehostname(char *hostname, struct clientparam *param, uint16_t port){
|
|||||||
if(se){
|
if(se){
|
||||||
*se = 0;
|
*se = 0;
|
||||||
}
|
}
|
||||||
|
if(!*hostname){
|
||||||
|
if(sp){
|
||||||
|
port = atoi(sp+1);
|
||||||
|
*sp = ':';
|
||||||
|
}
|
||||||
|
*SAPORT(¶m->req) = htons(port);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if(hostname != (char *)param->hostname){
|
if(hostname != (char *)param->hostname){
|
||||||
if(param->hostname) free(param->hostname);
|
if(param->hostname) free(param->hostname);
|
||||||
param->hostname = (unsigned char *)strdup(hostname + (se!=0));
|
param->hostname = (unsigned char *)strdup(hostname + (se!=0));
|
||||||
@ -551,14 +561,14 @@ int parseconnusername(char *username, struct clientparam *param, int extpasswd,
|
|||||||
if(!username || !*username) return 1;
|
if(!username || !*username) return 1;
|
||||||
if ((sb=strchr(username, conf.delimchar)) == NULL){
|
if ((sb=strchr(username, conf.delimchar)) == NULL){
|
||||||
if(!param->hostname && param->remsock == INVALID_SOCKET) return 2;
|
if(!param->hostname && param->remsock == INVALID_SOCKET) return 2;
|
||||||
if(param->hostname)parsehostname((char *)param->hostname, param, port);
|
if(param->hostname)parsehostname((char *)param->hostname, param, *SAPORT(¶m->req)? ntohs(*SAPORT(¶m->req)) : port);
|
||||||
return parseusername(username, param, extpasswd);
|
return parseusername(username, param, extpasswd);
|
||||||
}
|
}
|
||||||
while ((se=strchr(sb+1, conf.delimchar)))sb=se;
|
while ((se=strchr(sb+1, conf.delimchar)))sb=se;
|
||||||
*(sb) = 0;
|
*(sb) = 0;
|
||||||
if(parseusername(username, param, extpasswd)) return 3;
|
if(parseusername(username, param, extpasswd)) return 3;
|
||||||
*(sb) = conf.delimchar;
|
*(sb) = conf.delimchar;
|
||||||
if(parsehostname(sb+1, param, port)) return 4;
|
if(parsehostname(sb+1, param, *SAPORT(¶m->req)? ntohs(*SAPORT(¶m->req)) : port)) return 4;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,6 +667,9 @@ int doconnect(struct clientparam * param){
|
|||||||
if(!idx || (*SAFAMILY(¶m->sinsl) == AF_INET && param->srv->so._setsockopt(param->sostate, param->remsock, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx))))
|
if(!idx || (*SAFAMILY(¶m->sinsl) == AF_INET && param->srv->so._setsockopt(param->sostate, param->remsock, IPPROTO_IP, IP_BOUND_IF, &idx, sizeof(idx))))
|
||||||
return 12;
|
return 12;
|
||||||
#ifndef NOIPV6
|
#ifndef NOIPV6
|
||||||
|
#ifndef IPV6_BOUND_IF
|
||||||
|
#define IPV6_BOUND_IF 125
|
||||||
|
#endif
|
||||||
if(*SAFAMILY(¶m->sinsl) == AF_INET6 && param->srv->so._setsockopt(param->sostate, param->remsock, IPPROTO_IPV6, IPV6_BOUND_IF, &idx, sizeof(idx))) return 12;
|
if(*SAFAMILY(¶m->sinsl) == AF_INET6 && param->srv->so._setsockopt(param->sostate, param->remsock, IPPROTO_IPV6, IPV6_BOUND_IF, &idx, sizeof(idx))) return 12;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -867,3 +880,21 @@ uint32_t getip46(int family, unsigned char *name, struct sockaddr *sa){
|
|||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hascap(const unsigned char *line, const char *cap){
|
||||||
|
int len = (int)strlen(cap);
|
||||||
|
for(; *line; line++) if(!strncasecmp((char *)line, cap, len)) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getmultiline(struct clientparam *param, DIRECTION which, unsigned char *buf, int bufsize, const char *cap, int *found){
|
||||||
|
int i;
|
||||||
|
do {
|
||||||
|
i = sockgetlinebuf(param, which, buf, bufsize, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i > 0 && cap && found && !*found){
|
||||||
|
buf[i] = 0;
|
||||||
|
if(hascap(buf, cap)) *found = 1;
|
||||||
|
}
|
||||||
|
} while (i > 3 && buf[3] == '-');
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|||||||
190
src/conf.c
190
src/conf.c
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
#include "libs/blake2.h"
|
#include "mdhash.h"
|
||||||
#ifdef WITH_SSL
|
#ifdef WITH_SSL
|
||||||
void ssl_install(void);
|
void ssl_install(void);
|
||||||
#endif
|
#endif
|
||||||
@ -191,14 +191,21 @@ static int h_proxy(int argc, unsigned char ** argv){
|
|||||||
childdef.port = 110;
|
childdef.port = 110;
|
||||||
childdef.isudp = 0;
|
childdef.isudp = 0;
|
||||||
childdef.service = S_POP3P;
|
childdef.service = S_POP3P;
|
||||||
childdef.helpmessage = " -hdefault_host[:port] - use this host and port as default if no host specified\n";
|
childdef.helpmessage = " -hdefault_host[:port] - use this host and port as default if no host specified\n -x - disable STARTTLS\n";
|
||||||
|
}
|
||||||
|
else if(!strcmp((char *)argv[0], "imapp")) {
|
||||||
|
childdef.pf = imappchild;
|
||||||
|
childdef.port = 143;
|
||||||
|
childdef.isudp = 0;
|
||||||
|
childdef.service = S_IMAPP;
|
||||||
|
childdef.helpmessage = " -hdefault_host[:port] - use this host and port as default if no host specified\n -x - disable STARTTLS\n";
|
||||||
}
|
}
|
||||||
else if(!strcmp((char *)argv[0], "smtpp")) {
|
else if(!strcmp((char *)argv[0], "smtpp")) {
|
||||||
childdef.pf = smtppchild;
|
childdef.pf = smtppchild;
|
||||||
childdef.port = 25;
|
childdef.port = 587;
|
||||||
childdef.isudp = 0;
|
childdef.isudp = 0;
|
||||||
childdef.service = S_SMTPP;
|
childdef.service = S_SMTPP;
|
||||||
childdef.helpmessage = " -hdefault_host[:port] - use this host and port as default if no host specified\n";
|
childdef.helpmessage = " -hdefault_host[:port] - use this host and port as default if no host specified\n -x - disable STARTTLS\n";
|
||||||
}
|
}
|
||||||
else if(!strcmp((char *)argv[0], "ftppr")) {
|
else if(!strcmp((char *)argv[0], "ftppr")) {
|
||||||
childdef.pf = ftpprchild;
|
childdef.pf = ftpprchild;
|
||||||
@ -257,7 +264,7 @@ static int h_proxy(int argc, unsigned char ** argv){
|
|||||||
childdef.port = 53;
|
childdef.port = 53;
|
||||||
childdef.isudp = 1;
|
childdef.isudp = 1;
|
||||||
childdef.service = S_DNSPR;
|
childdef.service = S_DNSPR;
|
||||||
childdef.helpmessage = " -s - simple DNS forwarding - do not use 3proxy resolver / name cache\n";
|
childdef.helpmessage = " -s - simple DNS forwarding - do not use 3proxy resolver / name cache\n -Fip - fake: answer all A queries with this IP\n";
|
||||||
#ifndef NOIPV6
|
#ifndef NOIPV6
|
||||||
if(!resolvfunc || (resolvfunc == myresolver && !dns_table.poolsize) || resolvfunc == fakeresolver){
|
if(!resolvfunc || (resolvfunc == myresolver && !dns_table.poolsize) || resolvfunc == fakeresolver){
|
||||||
fprintf(stderr, "[line %d] Warning: no nserver/nscache configured, dnspr will not work as expected\n", linenum);
|
fprintf(stderr, "[line %d] Warning: no nserver/nscache configured, dnspr will not work as expected\n", linenum);
|
||||||
@ -543,13 +550,17 @@ static int h_users(int argc, unsigned char **argv){
|
|||||||
l = strlen(pw[1]);
|
l = strlen(pw[1]);
|
||||||
if(l > 255) l = 255;
|
if(l > 255) l = 255;
|
||||||
if((unsigned)l >= pwl_table.recsize) {
|
if((unsigned)l >= pwl_table.recsize) {
|
||||||
blake2b_state S;
|
mdh_ctx *bctx;
|
||||||
unsigned hashsz;
|
unsigned hashsz;
|
||||||
|
unsigned int blen;
|
||||||
if(*pass != CL) continue;
|
if(*pass != CL) continue;
|
||||||
hashsz = pwl_table.recsize - 1 < 64 ? pwl_table.recsize - 1 : 64;
|
hashsz = pwl_table.recsize - 1 < 64 ? pwl_table.recsize - 1 : 64;
|
||||||
blake2b_init(&S, hashsz);
|
bctx = mdh_init(MDH_BLAKE2, hashsz);
|
||||||
blake2b_update(&S, pw[1], l + 1);
|
if(!bctx) continue;
|
||||||
blake2b_final(&S, pass+1, hashsz);
|
mdh_update(bctx, pw[1], l + 1);
|
||||||
|
blen = hashsz;
|
||||||
|
mdh_final(bctx, (unsigned char *)pass+1, &blen);
|
||||||
|
mdh_free(bctx);
|
||||||
} else {
|
} else {
|
||||||
memcpy(pass + 1, pw[1], l);
|
memcpy(pass + 1, pw[1], l);
|
||||||
}
|
}
|
||||||
@ -739,6 +750,7 @@ struct redirdesc redirs[] = {
|
|||||||
{R_SOCKS5, "socks5", sockschild},
|
{R_SOCKS5, "socks5", sockschild},
|
||||||
{R_HTTP, "http", proxychild},
|
{R_HTTP, "http", proxychild},
|
||||||
{R_POP3, "pop3", pop3pchild},
|
{R_POP3, "pop3", pop3pchild},
|
||||||
|
{R_IMAP, "imap", imappchild},
|
||||||
{R_SMTP, "smtp", smtppchild},
|
{R_SMTP, "smtp", smtppchild},
|
||||||
{R_FTP, "ftp", ftpprchild},
|
{R_FTP, "ftp", ftpprchild},
|
||||||
{R_CONNECTP, "connect+", proxychild},
|
{R_CONNECTP, "connect+", proxychild},
|
||||||
@ -1599,88 +1611,94 @@ static int h_chroot(int argc, unsigned char **argv){
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct commands specificcommands[]={
|
struct commands commandhandlers[]={
|
||||||
|
{NULL, "", h_noop, 1, 0},
|
||||||
|
{NULL, "proxy", h_proxy, 1, 0},
|
||||||
|
{NULL, "pop3p", h_proxy, 1, 0},
|
||||||
|
{NULL, "imapp", h_proxy, 1, 0},
|
||||||
|
{NULL, "ftppr", h_proxy, 1, 0},
|
||||||
|
{NULL, "socks", h_proxy, 1, 0},
|
||||||
|
{NULL, "tcppm", h_proxy, 4, 0},
|
||||||
|
{NULL, "udppm", h_proxy, 4, 0},
|
||||||
|
{NULL, "admin", h_proxy, 1, 0},
|
||||||
|
{NULL, "dnspr", h_proxy, 1, 0},
|
||||||
|
{NULL, "internal", h_internal, 2, 2},
|
||||||
|
{NULL, "external", h_external, 2, 2},
|
||||||
|
{NULL, "log", h_log, 1, 0},
|
||||||
|
{NULL, "service", h_service, 1, 1},
|
||||||
|
{NULL, "daemon", h_daemon, 1, 1},
|
||||||
|
{NULL, "config", h_config, 2, 2},
|
||||||
|
{NULL, "include", h_include, 2, 2},
|
||||||
|
{NULL, "archiver", h_archiver, 3, 0},
|
||||||
|
{NULL, "counter", h_counter, 2, 4},
|
||||||
|
{NULL, "rotate", h_rotate, 2, 2},
|
||||||
|
{NULL, "logformat", h_logformat, 2, 2},
|
||||||
|
{NULL, "timeouts", h_timeouts, 2, 0},
|
||||||
|
{NULL, "auth", h_auth, 2, 0},
|
||||||
|
{NULL, "users", h_users, 1, 0},
|
||||||
|
{NULL, "maxconn", h_maxconn, 2, 2},
|
||||||
|
{NULL, "flush", h_flush, 1, 1},
|
||||||
|
{NULL, "nserver", h_nserver, 2, 2},
|
||||||
|
{NULL, "fakeresolve", h_fakeresolve, 1, 1},
|
||||||
|
{NULL, "nscache", h_nscache, 2, 2},
|
||||||
|
{NULL, "nscache6", h_nscache6, 2, 2},
|
||||||
|
{NULL, "nsrecord", h_nsrecord, 3, 3},
|
||||||
|
{NULL, "dialer", h_dialer, 2, 2},
|
||||||
|
{NULL, "system", h_system, 2, 2},
|
||||||
|
{NULL, "pidfile", h_pidfile, 2, 2},
|
||||||
|
{NULL, "monitor", h_monitor, 2, 2},
|
||||||
|
{NULL, "parent", h_parent, 5, 0},
|
||||||
|
{NULL, "allow", h_ace, 1, 0},
|
||||||
|
{NULL, "deny", h_ace, 1, 0},
|
||||||
|
{NULL, "redirect", h_ace, 3, 0},
|
||||||
|
{NULL, "bandlimin", h_ace, 2, 0},
|
||||||
|
{NULL, "bandlimout", h_ace, 2, 0},
|
||||||
|
{NULL, "nobandlimin", h_ace, 1, 0},
|
||||||
|
{NULL, "nobandlimout", h_ace, 1, 0},
|
||||||
|
{NULL, "countin", h_ace, 4, 0},
|
||||||
|
{NULL, "nocountin", h_ace, 1, 0},
|
||||||
|
{NULL, "countout", h_ace, 4, 0},
|
||||||
|
{NULL, "nocountout", h_ace, 1, 0},
|
||||||
|
{NULL, "countall", h_ace, 4, 0},
|
||||||
|
{NULL, "nocountall", h_ace, 1, 0},
|
||||||
|
{NULL, "connlim", h_ace, 4, 0},
|
||||||
|
{NULL, "noconnlim", h_ace, 1, 0},
|
||||||
|
{NULL, "plugin", h_plugin, 3, 0},
|
||||||
|
{NULL, "logdump", h_logdump, 2, 3},
|
||||||
|
{NULL, "filtermaxsize", h_filtermaxsize, 2, 2},
|
||||||
|
{NULL, "nolog", h_nolog, 1, 1},
|
||||||
|
{NULL, "weight", h_nolog, 2, 2},
|
||||||
|
{NULL, "authcache", h_authcache, 2, 4},
|
||||||
|
{NULL, "smtpp", h_proxy, 1, 0},
|
||||||
|
{NULL, "delimchar",h_delimchar, 2, 2},
|
||||||
|
{NULL, "authnserver", h_authnserver, 2, 2},
|
||||||
|
{NULL, "stacksize", h_stacksize, 2, 2},
|
||||||
|
{NULL, "force", h_force, 1, 1},
|
||||||
|
{NULL, "noforce", h_noforce, 1, 1},
|
||||||
|
{NULL, "parentretries", h_parentretries, 2, 2},
|
||||||
|
{NULL, "auto", h_proxy, 1, 0},
|
||||||
|
{NULL, "backlog", h_backlog, 2, 2},
|
||||||
|
{NULL, "tlspr", h_proxy, 1, 0},
|
||||||
|
{NULL, "maxseg", h_maxseg, 2, 2},
|
||||||
|
#ifndef NORADIUS
|
||||||
|
{NULL, "radius", h_radius, 3, 0},
|
||||||
|
#endif
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
{specificcommands+1, "setuid", h_setuid, 2, 2},
|
{NULL, "setuid", h_setuid, 2, 2},
|
||||||
{specificcommands+2, "setgid", h_setgid, 2, 2},
|
{NULL, "setgid", h_setgid, 2, 2},
|
||||||
{specificcommands+3, "chroot", h_chroot, 2, 4},
|
{NULL, "chroot", h_chroot, 2, 4},
|
||||||
#endif
|
#endif
|
||||||
{NULL, "", h_noop, 1, 0}
|
{NULL, "", h_noop, 1, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct commands commandhandlers[]={
|
void initcommands(void){
|
||||||
{commandhandlers+1, "", h_noop, 1, 0},
|
static int initialized = 0;
|
||||||
{commandhandlers+2, "proxy", h_proxy, 1, 0},
|
unsigned i;
|
||||||
{commandhandlers+3, "pop3p", h_proxy, 1, 0},
|
if(initialized) return;
|
||||||
{commandhandlers+4, "ftppr", h_proxy, 1, 0},
|
initialized = 1;
|
||||||
{commandhandlers+5, "socks", h_proxy, 1, 0},
|
for(i = 0; i + 1 < sizeof(commandhandlers)/sizeof(commandhandlers[0]); i++)
|
||||||
{commandhandlers+6, "tcppm", h_proxy, 4, 0},
|
commandhandlers[i].next = commandhandlers + i + 1;
|
||||||
{commandhandlers+7, "udppm", h_proxy, 4, 0},
|
}
|
||||||
{commandhandlers+8, "admin", h_proxy, 1, 0},
|
|
||||||
{commandhandlers+9, "dnspr", h_proxy, 1, 0},
|
|
||||||
{commandhandlers+10, "internal", h_internal, 2, 2},
|
|
||||||
{commandhandlers+11, "external", h_external, 2, 2},
|
|
||||||
{commandhandlers+12, "log", h_log, 1, 0},
|
|
||||||
{commandhandlers+13, "service", h_service, 1, 1},
|
|
||||||
{commandhandlers+14, "daemon", h_daemon, 1, 1},
|
|
||||||
{commandhandlers+15, "config", h_config, 2, 2},
|
|
||||||
{commandhandlers+16, "include", h_include, 2, 2},
|
|
||||||
{commandhandlers+17, "archiver", h_archiver, 3, 0},
|
|
||||||
{commandhandlers+18, "counter", h_counter, 2, 4},
|
|
||||||
{commandhandlers+19, "rotate", h_rotate, 2, 2},
|
|
||||||
{commandhandlers+20, "logformat", h_logformat, 2, 2},
|
|
||||||
{commandhandlers+21, "timeouts", h_timeouts, 2, 0},
|
|
||||||
{commandhandlers+22, "auth", h_auth, 2, 0},
|
|
||||||
{commandhandlers+23, "users", h_users, 1, 0},
|
|
||||||
{commandhandlers+24, "maxconn", h_maxconn, 2, 2},
|
|
||||||
{commandhandlers+25, "flush", h_flush, 1, 1},
|
|
||||||
{commandhandlers+26, "nserver", h_nserver, 2, 2},
|
|
||||||
{commandhandlers+27, "fakeresolve", h_fakeresolve, 1, 1},
|
|
||||||
{commandhandlers+28, "nscache", h_nscache, 2, 2},
|
|
||||||
{commandhandlers+29, "nscache6", h_nscache6, 2, 2},
|
|
||||||
{commandhandlers+30, "nsrecord", h_nsrecord, 3, 3},
|
|
||||||
{commandhandlers+31, "dialer", h_dialer, 2, 2},
|
|
||||||
{commandhandlers+32, "system", h_system, 2, 2},
|
|
||||||
{commandhandlers+33, "pidfile", h_pidfile, 2, 2},
|
|
||||||
{commandhandlers+34, "monitor", h_monitor, 2, 2},
|
|
||||||
{commandhandlers+35, "parent", h_parent, 5, 0},
|
|
||||||
{commandhandlers+36, "allow", h_ace, 1, 0},
|
|
||||||
{commandhandlers+37, "deny", h_ace, 1, 0},
|
|
||||||
{commandhandlers+38, "redirect", h_ace, 3, 0},
|
|
||||||
{commandhandlers+39, "bandlimin", h_ace, 2, 0},
|
|
||||||
{commandhandlers+40, "bandlimout", h_ace, 2, 0},
|
|
||||||
{commandhandlers+41, "nobandlimin", h_ace, 1, 0},
|
|
||||||
{commandhandlers+42, "nobandlimout", h_ace, 1, 0},
|
|
||||||
{commandhandlers+43, "countin", h_ace, 4, 0},
|
|
||||||
{commandhandlers+44, "nocountin", h_ace, 1, 0},
|
|
||||||
{commandhandlers+45, "countout", h_ace, 4, 0},
|
|
||||||
{commandhandlers+46, "nocountout", h_ace, 1, 0},
|
|
||||||
{commandhandlers+47, "countall", h_ace, 4, 0},
|
|
||||||
{commandhandlers+48, "nocountall", h_ace, 1, 0},
|
|
||||||
{commandhandlers+49, "connlim", h_ace, 4, 0},
|
|
||||||
{commandhandlers+50, "noconnlim", h_ace, 1, 0},
|
|
||||||
{commandhandlers+51, "plugin", h_plugin, 3, 0},
|
|
||||||
{commandhandlers+52, "logdump", h_logdump, 2, 3},
|
|
||||||
{commandhandlers+53, "filtermaxsize", h_filtermaxsize, 2, 2},
|
|
||||||
{commandhandlers+54, "nolog", h_nolog, 1, 1},
|
|
||||||
{commandhandlers+55, "weight", h_nolog, 2, 2},
|
|
||||||
{commandhandlers+56, "authcache", h_authcache, 2, 4},
|
|
||||||
{commandhandlers+57, "smtpp", h_proxy, 1, 0},
|
|
||||||
{commandhandlers+58, "delimchar",h_delimchar, 2, 2},
|
|
||||||
{commandhandlers+59, "authnserver", h_authnserver, 2, 2},
|
|
||||||
{commandhandlers+60, "stacksize", h_stacksize, 2, 2},
|
|
||||||
{commandhandlers+61, "force", h_force, 1, 1},
|
|
||||||
{commandhandlers+62, "noforce", h_noforce, 1, 1},
|
|
||||||
{commandhandlers+63, "parentretries", h_parentretries, 2, 2},
|
|
||||||
{commandhandlers+64, "auto", h_proxy, 1, 0},
|
|
||||||
{commandhandlers+65, "backlog", h_backlog, 2, 2},
|
|
||||||
{commandhandlers+66, "tlspr", h_proxy, 1, 0},
|
|
||||||
{commandhandlers+67, "maxseg", h_maxseg, 2, 2},
|
|
||||||
#ifndef NORADIUS
|
|
||||||
{commandhandlers+68, "radius", h_radius, 3, 0},
|
|
||||||
#endif
|
|
||||||
{specificcommands, "", h_noop, 1, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned char ** buff, int *inbuf, int *bufsize){
|
int parsestr (unsigned char *str, unsigned char **argm, int nitems, unsigned char ** buff, int *inbuf, int *bufsize){
|
||||||
#define buf (*buff)
|
#define buf (*buff)
|
||||||
|
|||||||
@ -523,7 +523,7 @@ static void * ef_server_next(struct node * node){
|
|||||||
|
|
||||||
static void * ef_server_type(struct node * node){
|
static void * ef_server_type(struct node * node){
|
||||||
int service = ((struct srvparam *)node->value) -> service;
|
int service = ((struct srvparam *)node->value) -> service;
|
||||||
return (service>=0 && service < 15)? (void *)conf.stringtable[SERVICES + service] : (void *)"unknown";
|
return (service>=0 && service < MAX_SERVICE)? (void *)conf.stringtable[SERVICES + service] : (void *)"unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * ef_server_child(struct node * node){
|
static void * ef_server_child(struct node * node){
|
||||||
@ -682,7 +682,7 @@ static void * ef_client_next(struct node * node){
|
|||||||
|
|
||||||
static void * ef_client_type(struct node * node){
|
static void * ef_client_type(struct node * node){
|
||||||
int service = ((struct clientparam *)node->value) -> service;
|
int service = ((struct clientparam *)node->value) -> service;
|
||||||
return (service>=0 && service < 15)? (void *)conf.stringtable[SERVICES + service] : (void *)"unknown";
|
return (service>=0 && service < MAX_SERVICE)? (void *)conf.stringtable[SERVICES + service] : (void *)"unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * ef_client_operation(struct node * node){
|
static void * ef_client_operation(struct node * node){
|
||||||
|
|||||||
23
src/dnspr.c
23
src/dnspr.c
@ -25,6 +25,7 @@ void * dnsprchild(struct clientparam* param) {
|
|||||||
SASIZETYPE size;
|
SASIZETYPE size;
|
||||||
int res, i;
|
int res, i;
|
||||||
int len;
|
int len;
|
||||||
|
int semlocked = 1;
|
||||||
unsigned type=0;
|
unsigned type=0;
|
||||||
uint32_t ttl;
|
uint32_t ttl;
|
||||||
unsigned char addr[16];
|
unsigned char addr[16];
|
||||||
@ -38,10 +39,13 @@ void * dnsprchild(struct clientparam* param) {
|
|||||||
RETURN (21);
|
RETURN (21);
|
||||||
}
|
}
|
||||||
buf = bbuf+2;
|
buf = bbuf+2;
|
||||||
size = sizeof(param->sincr);
|
|
||||||
i = param->srv->so._recvfrom(param->sostate, param->srv->srvsock, (char *)buf, BUFSIZE, 0, (struct sockaddr *)¶m->sincr, &size);
|
|
||||||
size = sizeof(param->sinsl);
|
size = sizeof(param->sinsl);
|
||||||
getsockname(param->srv->srvsock, (struct sockaddr *)¶m->sincl, &size);
|
getsockname(param->srv->srvsock, (struct sockaddr *)¶m->sincl, &size);
|
||||||
|
i = param->srv->udplen;
|
||||||
|
if(i > BUFSIZE) i = BUFSIZE;
|
||||||
|
memcpy(buf, param->srv->udpbuf, i);
|
||||||
|
_3proxy_sem_unlock(udpinit);
|
||||||
|
semlocked = 0;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if((param->clisock=param->srv->so._socket(param->sostate, AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
|
if((param->clisock=param->srv->so._socket(param->sostate, AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
|
||||||
RETURN(818);
|
RETURN(818);
|
||||||
@ -82,7 +86,19 @@ void * dnsprchild(struct clientparam* param) {
|
|||||||
*s2 = (len - (int)(s2 - buf)) - 1;
|
*s2 = (len - (int)(s2 - buf)) - 1;
|
||||||
|
|
||||||
type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2];
|
type = ((unsigned)buf[len+1])*256 + (unsigned)buf[len+2];
|
||||||
if((type==0x01 || type==0x1c) && !param->srv->s_option){
|
if(type==0x01 && param->srv->fakeip){
|
||||||
|
ip = 1;
|
||||||
|
ttl = 3600;
|
||||||
|
*(uint32_t *)addr = param->srv->fakeip;
|
||||||
|
}
|
||||||
|
#ifndef NOIPV6
|
||||||
|
else if(type==0x1c && *(uint32_t *)param->srv->fakeip6){
|
||||||
|
ip = 1;
|
||||||
|
ttl = 3600;
|
||||||
|
memcpy(addr, param->srv->fakeip6, 16);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if((type==0x01 || type==0x1c) && !param->srv->s_option){
|
||||||
ip = udpresolve((type==0x1c)?AF_INET6:AF_INET, (unsigned char *)host, addr, &ttl, param, 0);
|
ip = udpresolve((type==0x1c)?AF_INET6:AF_INET, (unsigned char *)host, addr, &ttl, param, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,6 +207,7 @@ void * dnsprchild(struct clientparam* param) {
|
|||||||
|
|
||||||
CLEANRET:
|
CLEANRET:
|
||||||
|
|
||||||
|
if(semlocked) _3proxy_sem_unlock(udpinit);
|
||||||
if(param->res!=813){
|
if(param->res!=813){
|
||||||
sprintf((char *)buf, "%04x/%s/",
|
sprintf((char *)buf, "%04x/%s/",
|
||||||
(unsigned)type,
|
(unsigned)type,
|
||||||
|
|||||||
@ -197,6 +197,7 @@ void hashadd(struct hashtable *ht, void* name, void* value, time_t expires){
|
|||||||
|
|
||||||
if(!ht->ihashempty){
|
if(!ht->ihashempty){
|
||||||
hashgrow(ht);
|
hashgrow(ht);
|
||||||
|
index = hashindex(ht, ht->tablesize, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ht->ihashempty){
|
if(ht->ihashempty){
|
||||||
|
|||||||
@ -1,18 +1,21 @@
|
|||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
#include "libs/blake2.h"
|
#include "mdhash.h"
|
||||||
|
|
||||||
|
|
||||||
static void char_index2hash(const struct hashtable *ht, void *index, uint8_t *hash){
|
static void char_index2hash(const struct hashtable *ht, void *index, uint8_t *hash){
|
||||||
blake2b_state S;
|
|
||||||
int len;
|
int len;
|
||||||
|
unsigned int blen;
|
||||||
|
|
||||||
len = strlen((const char*)index);
|
len = strlen((const char*)index);
|
||||||
memset(hash, 0, ht->hash_size);
|
memset(hash, 0, ht->hash_size);
|
||||||
if(len <= ht->hash_size) memcpy(hash, index, len);
|
if(len <= ht->hash_size) memcpy(hash, index, len);
|
||||||
else {
|
else {
|
||||||
blake2b_init(&S, ht->hash_size);
|
mdh_ctx *bctx = mdh_init(MDH_BLAKE2, ht->hash_size);
|
||||||
blake2b_update(&S, index, strlen((const char*)index) + 1);
|
if(!bctx) return;
|
||||||
blake2b_final(&S, hash, ht->hash_size);
|
mdh_update(bctx, index, (unsigned int)(strlen((const char*)index) + 1));
|
||||||
|
blen = ht->hash_size;
|
||||||
|
mdh_final(bctx, hash, &blen);
|
||||||
|
mdh_free(bctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +26,6 @@ static void param2hash_add(const struct hashtable *ht, void *index, uint8_t *has
|
|||||||
}
|
}
|
||||||
|
|
||||||
void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
|
void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
|
||||||
blake2b_state S;
|
|
||||||
struct clientparam *param = (struct clientparam *)index;
|
struct clientparam *param = (struct clientparam *)index;
|
||||||
unsigned type = param->srv->authcachetype;
|
unsigned type = param->srv->authcachetype;
|
||||||
int len = 0, oplen = 0, acllen = 0, ulen = 0, plen = 0, hlen = 0, a1len = 0, a2len = 0, a3len = 0, p1len=0, p2len = 0;
|
int len = 0, oplen = 0, acllen = 0, ulen = 0, plen = 0, hlen = 0, a1len = 0, a2len = 0, a3len = 0, p1len=0, p2len = 0;
|
||||||
@ -55,31 +57,36 @@ void param2hash_search(const struct hashtable *ht, void *index, uint8_t *hash){
|
|||||||
if((type & 2048)){ memcpy(hash + offset, SAPORT(¶m->srv->intsa), p2len); offset += 2; }
|
if((type & 2048)){ memcpy(hash + offset, SAPORT(¶m->srv->intsa), p2len); offset += 2; }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
blake2b_init(&S, ht->hash_size);
|
mdh_ctx *bctx = mdh_init(MDH_BLAKE2, ht->hash_size);
|
||||||
if((type & 2) && param->username)blake2b_update(&S, param->username, ulen);
|
unsigned int blen = ht->hash_size;
|
||||||
if((type & 4) && param->password)blake2b_update(&S, param->password, plen);
|
if(!bctx) { memcpy(param->hash, hash, ht->hash_size); return; }
|
||||||
if((type & 1) && !(type & 8))blake2b_update(&S, SAADDR(¶m->sincr), a1len);
|
if((type & 2) && param->username)mdh_update(bctx, param->username, ulen);
|
||||||
if((type & 16))blake2b_update(&S, ¶m->srv->acl, acllen);
|
if((type & 4) && param->password)mdh_update(bctx, param->password, plen);
|
||||||
if((type & 64))blake2b_update(&S, SAADDR(¶m->req), a2len);
|
if((type & 1) && !(type & 8))mdh_update(bctx, SAADDR(¶m->sincr), a1len);
|
||||||
if((type & 128))blake2b_update(&S, SAPORT(¶m->req), 2);
|
if((type & 16))mdh_update(bctx, ¶m->srv->acl, acllen);
|
||||||
if((type & 256) && param->hostname)blake2b_update(&S, param->hostname, hlen);
|
if((type & 64))mdh_update(bctx, SAADDR(¶m->req), a2len);
|
||||||
if((type & 512))blake2b_update(&S, ¶m->operation, sizeof(param->operation));
|
if((type & 128))mdh_update(bctx, SAPORT(¶m->req), 2);
|
||||||
if((type & 1024))blake2b_update(&S, SAADDR(¶m->srv->intsa), a3len);
|
if((type & 256) && param->hostname)mdh_update(bctx, param->hostname, hlen);
|
||||||
if((type & 2048))blake2b_update(&S, SAPORT(¶m->srv->intsa), 2);
|
if((type & 512))mdh_update(bctx, ¶m->operation, sizeof(param->operation));
|
||||||
blake2b_final(&S, hash, ht->hash_size);
|
if((type & 1024))mdh_update(bctx, SAADDR(¶m->srv->intsa), a3len);
|
||||||
|
if((type & 2048))mdh_update(bctx, SAPORT(¶m->srv->intsa), 2);
|
||||||
|
mdh_final(bctx, hash, &blen);
|
||||||
|
mdh_free(bctx);
|
||||||
}
|
}
|
||||||
memcpy(param->hash, hash, ht->hash_size);
|
memcpy(param->hash, hash, ht->hash_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash){
|
static void udpparam2hash(const struct hashtable *ht, void *index, uint8_t *hash){
|
||||||
struct clientparam *param = (struct clientparam *)index;
|
struct clientparam *param = (struct clientparam *)index;
|
||||||
blake2b_state S;
|
mdh_ctx *bctx = mdh_init(MDH_BLAKE2, ht->hash_size);
|
||||||
blake2b_init(&S, ht->hash_size);
|
unsigned int blen = ht->hash_size;
|
||||||
blake2b_update(&S, SAADDR(¶m->srv->intsa), SAADDRLEN(¶m->srv->intsa));
|
if(!bctx) return;
|
||||||
blake2b_update(&S, SAPORT(¶m->srv->intsa), 2);
|
mdh_update(bctx, SAADDR(¶m->srv->intsa), SAADDRLEN(¶m->srv->intsa));
|
||||||
blake2b_update(&S, SAADDR(¶m->sincr), SAADDRLEN(¶m->sincr));
|
mdh_update(bctx, SAPORT(¶m->srv->intsa), 2);
|
||||||
blake2b_update(&S, SAPORT(¶m->sincr), 2);
|
mdh_update(bctx, SAADDR(¶m->sincr), SAADDRLEN(¶m->sincr));
|
||||||
blake2b_final(&S, hash, ht->hash_size);
|
mdh_update(bctx, SAPORT(¶m->sincr), 2);
|
||||||
|
mdh_final(bctx, hash, &blen);
|
||||||
|
mdh_free(bctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hashtable dns_table = {char_index2hash, char_index2hash, 4, 32};
|
struct hashtable dns_table = {char_index2hash, char_index2hash, 4, 32};
|
||||||
|
|||||||
255
src/imapp.c
Normal file
255
src/imapp.c
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
/*
|
||||||
|
3APA3A simplest proxy server
|
||||||
|
(c) 2002-2026 by Vladimir Dubrovin <vlad@3proxy.org>
|
||||||
|
|
||||||
|
please read License Agreement
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "proxy.h"
|
||||||
|
|
||||||
|
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
||||||
|
|
||||||
|
#define CL_LOGINCMD 0
|
||||||
|
#define CL_PLAIN 1
|
||||||
|
#define CL_LOGIN 2
|
||||||
|
|
||||||
|
#define CAP_PLAIN 1
|
||||||
|
#define CAP_LOGIN 2
|
||||||
|
|
||||||
|
#ifdef WITHMAIN
|
||||||
|
#define NOSTARTTLS 1
|
||||||
|
#else
|
||||||
|
#define NOSTARTTLS param->srv->nostarttls
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void * imappchild(struct clientparam* param) {
|
||||||
|
int i=0, res, method=CL_LOGINCMD, caps=0;
|
||||||
|
unsigned char buf[2048];
|
||||||
|
unsigned char srvbuf[1024];
|
||||||
|
unsigned char ibuf[2048];
|
||||||
|
unsigned char tag[64];
|
||||||
|
unsigned char ub[320];
|
||||||
|
unsigned char pb[320];
|
||||||
|
unsigned char *se, *cmd, *user, *pass, *p1, *p2;
|
||||||
|
|
||||||
|
*tag = 0;
|
||||||
|
i = sprintf((char *)buf, "* OK [CAPABILITY IMAP4rev1%s AUTH=PLAIN AUTH=LOGIN] IMAP4rev1 Proxy Ready\r\n", NOSTARTTLS?"":" STARTTLS");
|
||||||
|
if(socksend(param, param->clisock, buf, i, conf.timeouts[STRING_S])!=i) {RETURN (691);}
|
||||||
|
for(;;){
|
||||||
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
|
if(i < 4) {RETURN(692);}
|
||||||
|
buf[i] = 0;
|
||||||
|
if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0;
|
||||||
|
if (!(se=(unsigned char *)strchr((char *)buf, ' ')) || (se - buf) >= (int)(sizeof(tag) - 1)) {RETURN(692);}
|
||||||
|
memcpy(tag, buf, se - buf);
|
||||||
|
tag[se - buf] = 0;
|
||||||
|
cmd = se + 1;
|
||||||
|
if(!strncasecmp((char *)cmd, "LOGOUT", 6)){
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"* BYE\r\n", 7, conf.timeouts[STRING_S]);
|
||||||
|
sprintf((char *)buf, "%.60s OK LOGOUT completed\r\n", (char *)tag);
|
||||||
|
socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]);
|
||||||
|
RETURN(0);
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)cmd, "CAPABILITY", 10)){
|
||||||
|
i = sprintf((char *)buf, "* CAPABILITY IMAP4rev1%s AUTH=PLAIN AUTH=LOGIN\r\n", NOSTARTTLS?"":" STARTTLS");
|
||||||
|
socksend(param, param->clisock, buf, i, conf.timeouts[STRING_S]);
|
||||||
|
sprintf((char *)buf, "%.60s OK CAPABILITY completed\r\n", (char *)tag);
|
||||||
|
socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#ifndef WITHMAIN
|
||||||
|
if(!strncasecmp((char *)cmd, "STARTTLS", 8) && !param->srv->nostarttls){
|
||||||
|
sprintf((char *)buf, "%.60s OK Begin TLS negotiation\r\n", (char *)tag);
|
||||||
|
if(socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]) <= 0) {RETURN(698);}
|
||||||
|
param->clientstarttls = S_IMAPP;
|
||||||
|
if(!param->srv->targetport) param->srv->targetport = htons(143);
|
||||||
|
return tlsprchild(param);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if(!strncasecmp((char *)cmd, "LOGIN ", 6)){
|
||||||
|
user = cmd + 6;
|
||||||
|
if(*user == '"') {
|
||||||
|
user++;
|
||||||
|
if (!(se=(unsigned char *)strchr((char *)user, '"'))) {RETURN(693);}
|
||||||
|
*se = 0;
|
||||||
|
pass = se + 1;
|
||||||
|
if(*pass == ' ') pass++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!(se=(unsigned char *)strchr((char *)user, ' '))) {RETURN(693);}
|
||||||
|
*se = 0;
|
||||||
|
pass = se + 1;
|
||||||
|
}
|
||||||
|
if(strlen((char *)user) >= sizeof(ub) || strlen((char *)pass) >= sizeof(pb)) {RETURN(693);}
|
||||||
|
strcpy((char *)ub, (char *)user);
|
||||||
|
strcpy((char *)pb, (char *)pass);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)cmd, "AUTHENTICATE PLAIN", 18)){
|
||||||
|
method = CL_PLAIN;
|
||||||
|
se = cmd + 18;
|
||||||
|
if(*se == ' ') se++; else se = NULL;
|
||||||
|
if(!se || !*se){
|
||||||
|
if(socksend(param, param->clisock, (unsigned char *)"+ \r\n", 4, conf.timeouts[STRING_S])!=4) {RETURN(698);}
|
||||||
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
|
if(i < 1) {RETURN(698);}
|
||||||
|
buf[i] = 0;
|
||||||
|
if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0;
|
||||||
|
se = buf;
|
||||||
|
}
|
||||||
|
i = de64(se, ibuf, (int)sizeof(ibuf) - 1);
|
||||||
|
if(i < 3) {RETURN(693);}
|
||||||
|
ibuf[i] = 0;
|
||||||
|
p1 = (unsigned char *)memchr(ibuf, 0, i);
|
||||||
|
if(!p1 || p1 == ibuf + i - 1) {RETURN(693);}
|
||||||
|
p2 = (unsigned char *)memchr(p1 + 1, 0, i - (int)(p1 + 1 - ibuf));
|
||||||
|
if(p2){
|
||||||
|
user = p1 + 1;
|
||||||
|
pass = p2 + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
user = ibuf;
|
||||||
|
pass = p1 + 1;
|
||||||
|
}
|
||||||
|
if(strlen((char *)user) >= sizeof(ub) || strlen((char *)pass) >= sizeof(pb)) {RETURN(693);}
|
||||||
|
strcpy((char *)ub, (char *)user);
|
||||||
|
strcpy((char *)pb, (char *)pass);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)cmd, "AUTHENTICATE LOGIN", 18)){
|
||||||
|
method = CL_LOGIN;
|
||||||
|
se = cmd + 18;
|
||||||
|
if(*se == ' ') se++; else se = NULL;
|
||||||
|
if(se && *se){
|
||||||
|
i = de64(se, ub, (int)sizeof(ub) - 1);
|
||||||
|
if(i < 0) {RETURN(693);}
|
||||||
|
ub[i] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(socksend(param, param->clisock, (unsigned char *)"+ VXNlcm5hbWU6\r\n", 16, conf.timeouts[STRING_S])!=16) {RETURN(698);}
|
||||||
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
|
if(i < 1) {RETURN(698);}
|
||||||
|
buf[i] = 0;
|
||||||
|
if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0;
|
||||||
|
i = de64(buf, ub, (int)sizeof(ub) - 1);
|
||||||
|
if(i < 0) {RETURN(693);}
|
||||||
|
ub[i] = 0;
|
||||||
|
}
|
||||||
|
if(socksend(param, param->clisock, (unsigned char *)"+ UGFzc3dvcmQ6\r\n", 16, conf.timeouts[STRING_S])!=16) {RETURN(698);}
|
||||||
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
|
if(i < 1) {RETURN(698);}
|
||||||
|
buf[i] = 0;
|
||||||
|
if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0;
|
||||||
|
i = de64(buf, pb, (int)sizeof(pb) - 1);
|
||||||
|
if(i < 0) {RETURN(693);}
|
||||||
|
pb[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sprintf((char *)buf, "%.60s BAD need LOGIN first\r\n", (char *)tag);
|
||||||
|
socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]);
|
||||||
|
}
|
||||||
|
if(parseconnusername((char *)ub, param, 0, 143)){RETURN(694);}
|
||||||
|
if(*pb && !param->password) param->password = (unsigned char *)strdup((char *)pb);
|
||||||
|
param->operation = CONNECT;
|
||||||
|
res = (*param->srv->authfunc)(param);
|
||||||
|
if(res) {RETURN(res);}
|
||||||
|
i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if( i < 4 ) {RETURN(695);}
|
||||||
|
srvbuf[i] = 0;
|
||||||
|
if(strncasecmp((char *)srvbuf, "* OK", 4)||strstr((char *)srvbuf, "IMAP4rev1 Proxy Ready")){RETURN(696);}
|
||||||
|
if((se = (unsigned char *)strstr((char *)srvbuf, "[CAPABILITY "))){
|
||||||
|
if(hascap(se, "AUTH=PLAIN")) caps |= CAP_PLAIN;
|
||||||
|
if(hascap(se, "AUTH=LOGIN")) caps |= CAP_LOGIN;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(socksend(param, param->remsock, (unsigned char *)"zz CAPABILITY\r\n", 15, conf.timeouts[STRING_S])!=15) {RETURN(697);}
|
||||||
|
for(;;){
|
||||||
|
i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 3) {RETURN(697);}
|
||||||
|
srvbuf[i] = 0;
|
||||||
|
if(!strncasecmp((char *)srvbuf, "* CAPABILITY", 12)){
|
||||||
|
if(hascap(srvbuf, "AUTH=PLAIN")) caps |= CAP_PLAIN;
|
||||||
|
if(hascap(srvbuf, "AUTH=LOGIN")) caps |= CAP_LOGIN;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)srvbuf, "zz ", 3)) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(method == CL_PLAIN && !(caps & CAP_PLAIN)) method = (caps & CAP_LOGIN)? CL_LOGIN : CL_LOGINCMD;
|
||||||
|
else if(method == CL_LOGIN && !(caps & CAP_LOGIN)) method = (caps & CAP_PLAIN)? CL_PLAIN : CL_LOGINCMD;
|
||||||
|
else if(method == CL_LOGINCMD && caps) method = (caps & CAP_PLAIN)? CL_PLAIN : CL_LOGIN;
|
||||||
|
if(method == CL_PLAIN){
|
||||||
|
i = (int)strlen((char *)param->extusername);
|
||||||
|
res = (int)strlen((char *)pb);
|
||||||
|
if(((i + res + 4) / 3) * 4 + 1 > (int)sizeof(srvbuf)) {RETURN(693);}
|
||||||
|
ibuf[0] = 0;
|
||||||
|
memcpy(ibuf + 1, param->extusername, i);
|
||||||
|
ibuf[i + 1] = 0;
|
||||||
|
memcpy(ibuf + i + 2, pb, res);
|
||||||
|
en64(ibuf, srvbuf, i + res + 2);
|
||||||
|
if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), conf.timeouts[STRING_S]) <= 0 ||
|
||||||
|
socksend(param, param->remsock, (unsigned char *)" AUTHENTICATE PLAIN ", 20, conf.timeouts[STRING_S])!= 20 ||
|
||||||
|
socksend(param, param->remsock, srvbuf, (int)strlen((char *)srvbuf), conf.timeouts[STRING_S]) <= 0 ||
|
||||||
|
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2)
|
||||||
|
{RETURN(699);}
|
||||||
|
}
|
||||||
|
else if(method == CL_LOGIN){
|
||||||
|
if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), conf.timeouts[STRING_S]) <= 0 ||
|
||||||
|
socksend(param, param->remsock, (unsigned char *)" AUTHENTICATE LOGIN\r\n", 21, conf.timeouts[STRING_S])!= 21)
|
||||||
|
{RETURN(699);}
|
||||||
|
i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 1 || *srvbuf != '+') {RETURN(699);}
|
||||||
|
if(((int)strlen((char *)param->extusername) + 2) / 3 * 4 + 1 > (int)sizeof(ibuf) - 3) {RETURN(693);}
|
||||||
|
en64(param->extusername, ibuf, (int)strlen((char *)param->extusername));
|
||||||
|
if( socksend(param, param->remsock, ibuf, (int)strlen((char *)ibuf), conf.timeouts[STRING_S]) <= 0 ||
|
||||||
|
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2)
|
||||||
|
{RETURN(699);}
|
||||||
|
i = sockgetlinebuf(param, SERVER, srvbuf, sizeof(srvbuf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 1 || *srvbuf != '+') {RETURN(699);}
|
||||||
|
if(((int)strlen((char *)pb) + 2) / 3 * 4 + 1 > (int)sizeof(ibuf) - 3) {RETURN(693);}
|
||||||
|
en64(pb, ibuf, (int)strlen((char *)pb));
|
||||||
|
if( socksend(param, param->remsock, ibuf, (int)strlen((char *)ibuf), conf.timeouts[STRING_S]) <= 0 ||
|
||||||
|
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2)
|
||||||
|
{RETURN(699);}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if( socksend(param, param->remsock, tag, (int)strlen((char *)tag), conf.timeouts[STRING_S]) <= 0 ||
|
||||||
|
socksend(param, param->remsock, (unsigned char *)" LOGIN ", 7, conf.timeouts[STRING_S])!= 7 ||
|
||||||
|
socksend(param, param->remsock, param->extusername, (int)strlen((char *)param->extusername), conf.timeouts[STRING_S]) <= 0 ||
|
||||||
|
socksend(param, param->remsock, (unsigned char *)" ", 1, conf.timeouts[STRING_S])!= 1 ||
|
||||||
|
socksend(param, param->remsock, pb, (int)strlen((char *)pb), conf.timeouts[STRING_S]) <= 0 ||
|
||||||
|
socksend(param, param->remsock, (unsigned char *)"\r\n", 2, conf.timeouts[STRING_S])!=2)
|
||||||
|
{RETURN(699);}
|
||||||
|
}
|
||||||
|
param->statscli64 += (uint64_t)(strlen((char *)tag) + strlen((char *)param->extusername) + strlen((char *)pb) + 11);
|
||||||
|
param->nwrites++;
|
||||||
|
RETURN (mapsocket(param, 180));
|
||||||
|
CLEANRET:
|
||||||
|
|
||||||
|
if(param->hostname&¶m->extusername) {
|
||||||
|
sprintf((char *)buf, "%.128s@%.128s%c%hu", param->extusername, param->hostname, (*SAPORT(¶m->sinsr)==143)?0:':', ntohs(*SAPORT(¶m->sinsr)));
|
||||||
|
dolog(param, buf);
|
||||||
|
}
|
||||||
|
else dolog(param, NULL);
|
||||||
|
if(param->clisock != INVALID_SOCKET) {
|
||||||
|
if ((param->res > 0 && param->res < 100) || (param->res > 691 && param->res <700)) {
|
||||||
|
sprintf((char *)buf, "%.60s NO proxy error\r\n", *tag? (char *)tag : "*");
|
||||||
|
socksend(param, param->clisock, buf, (int)strlen((char *)buf),conf.timeouts[STRING_S]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
freeparam(param);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WITHMAIN
|
||||||
|
struct proxydef childdef = {
|
||||||
|
imappchild,
|
||||||
|
143,
|
||||||
|
0,
|
||||||
|
S_IMAPP,
|
||||||
|
" -hdefault_host[:port] - use this host and port as default if no host specified\n -x - disable STARTTLS\n"
|
||||||
|
|
||||||
|
};
|
||||||
|
#include "proxymain.c"
|
||||||
|
#endif
|
||||||
@ -13,6 +13,12 @@
|
|||||||
https://blake2.net.
|
https://blake2.net.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if defined(WITH_WOLFSSL)
|
||||||
|
#include <wolfssl/options.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_BLAKE2B
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -377,3 +383,5 @@ fail:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /* !HAVE_BLAKE2B */
|
||||||
|
|||||||
276
src/libs/md4.c
Normal file
276
src/libs/md4.c
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
/*
|
||||||
|
* This is an OpenSSL API compatible (but not ABI compatible) implementation
|
||||||
|
* of the RSA Data Security, Inc. MD4 Message-Digest Algorithm (RFC 1320).
|
||||||
|
*
|
||||||
|
* Homepage:
|
||||||
|
* https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||||
|
*
|
||||||
|
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||||
|
* claimed, and the software is hereby placed in the public domain.
|
||||||
|
* In case this attempt to disclaim copyright and place the software in the
|
||||||
|
* public domain is deemed null and void, then the software is
|
||||||
|
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||||
|
* general public under the following terms:
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||||
|
*
|
||||||
|
* (This is a heavily cut-down "BSD license".)
|
||||||
|
*
|
||||||
|
* This differs from Colin Plumb's older public domain implementation in that
|
||||||
|
* no exactly 32-bit integer data type is required (any 32-bit or wider
|
||||||
|
* unsigned integer data type will do), there's no compile-time endianness
|
||||||
|
* configuration, and the function prototypes match OpenSSL's. No code from
|
||||||
|
* Colin Plumb's implementation has been reused; this comment merely compares
|
||||||
|
* the properties of the two independent implementations.
|
||||||
|
*
|
||||||
|
* The primary goals of this implementation are portability and ease of use.
|
||||||
|
* It is meant to be fast, but not as fast as possible. Some known
|
||||||
|
* optimizations are not included to reduce source code size and avoid
|
||||||
|
* compile-time configuration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(WITH_WOLFSSL)
|
||||||
|
#include <wolfssl/options.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(WITH_WOLFSSL) || defined(NO_MD4)
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "md4.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The basic MD4 functions.
|
||||||
|
*
|
||||||
|
* F and G are optimized compared to their RFC 1320 definitions, with the
|
||||||
|
* optimization for F borrowed from Colin Plumb's MD5 implementation.
|
||||||
|
*/
|
||||||
|
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||||
|
#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
|
||||||
|
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MD4 transformation for all three rounds.
|
||||||
|
*/
|
||||||
|
#define STEP(f, a, b, c, d, x, s) \
|
||||||
|
(a) += f((b), (c), (d)) + (x); \
|
||||||
|
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SET reads 4 input bytes in little-endian byte order and stores them in a
|
||||||
|
* properly aligned word in host byte order.
|
||||||
|
*
|
||||||
|
* The check for little-endian architectures that tolerate unaligned memory
|
||||||
|
* accesses is just an optimization. Nothing will break if it fails to detect
|
||||||
|
* a suitable architecture.
|
||||||
|
*
|
||||||
|
* Unfortunately, this optimization may be a C strict aliasing rules violation
|
||||||
|
* if the caller's data buffer has effective type that cannot be aliased by
|
||||||
|
* MD4_u32plus. In practice, this problem may occur if these MD4 routines are
|
||||||
|
* inlined into a calling function, or with future and dangerously advanced
|
||||||
|
* link-time optimizations. For the time being, keeping these MD4 routines in
|
||||||
|
* their own translation unit avoids the problem.
|
||||||
|
*/
|
||||||
|
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
|
||||||
|
#define SET(n) \
|
||||||
|
(*(MD4_u32plus *)&ptr[(n) * 4])
|
||||||
|
#define GET(n) \
|
||||||
|
SET(n)
|
||||||
|
#else
|
||||||
|
#define SET(n) \
|
||||||
|
(ctx->block[(n)] = \
|
||||||
|
(MD4_u32plus)ptr[(n) * 4] | \
|
||||||
|
((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
|
||||||
|
((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
|
||||||
|
((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
|
||||||
|
#define GET(n) \
|
||||||
|
(ctx->block[(n)])
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This processes one or more 64-byte data blocks, but does NOT update the bit
|
||||||
|
* counters. There are no alignment requirements.
|
||||||
|
*/
|
||||||
|
static const void *body(MD4_CTX *ctx, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
const unsigned char *ptr;
|
||||||
|
MD4_u32plus a, b, c, d;
|
||||||
|
MD4_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||||
|
const MD4_u32plus ac1 = 0x5a827999, ac2 = 0x6ed9eba1;
|
||||||
|
|
||||||
|
ptr = (const unsigned char *)data;
|
||||||
|
|
||||||
|
a = ctx->a;
|
||||||
|
b = ctx->b;
|
||||||
|
c = ctx->c;
|
||||||
|
d = ctx->d;
|
||||||
|
|
||||||
|
do {
|
||||||
|
saved_a = a;
|
||||||
|
saved_b = b;
|
||||||
|
saved_c = c;
|
||||||
|
saved_d = d;
|
||||||
|
|
||||||
|
/* Round 1 */
|
||||||
|
STEP(F, a, b, c, d, SET(0), 3)
|
||||||
|
STEP(F, d, a, b, c, SET(1), 7)
|
||||||
|
STEP(F, c, d, a, b, SET(2), 11)
|
||||||
|
STEP(F, b, c, d, a, SET(3), 19)
|
||||||
|
STEP(F, a, b, c, d, SET(4), 3)
|
||||||
|
STEP(F, d, a, b, c, SET(5), 7)
|
||||||
|
STEP(F, c, d, a, b, SET(6), 11)
|
||||||
|
STEP(F, b, c, d, a, SET(7), 19)
|
||||||
|
STEP(F, a, b, c, d, SET(8), 3)
|
||||||
|
STEP(F, d, a, b, c, SET(9), 7)
|
||||||
|
STEP(F, c, d, a, b, SET(10), 11)
|
||||||
|
STEP(F, b, c, d, a, SET(11), 19)
|
||||||
|
STEP(F, a, b, c, d, SET(12), 3)
|
||||||
|
STEP(F, d, a, b, c, SET(13), 7)
|
||||||
|
STEP(F, c, d, a, b, SET(14), 11)
|
||||||
|
STEP(F, b, c, d, a, SET(15), 19)
|
||||||
|
|
||||||
|
/* Round 2 */
|
||||||
|
STEP(G, a, b, c, d, GET(0) + ac1, 3)
|
||||||
|
STEP(G, d, a, b, c, GET(4) + ac1, 5)
|
||||||
|
STEP(G, c, d, a, b, GET(8) + ac1, 9)
|
||||||
|
STEP(G, b, c, d, a, GET(12) + ac1, 13)
|
||||||
|
STEP(G, a, b, c, d, GET(1) + ac1, 3)
|
||||||
|
STEP(G, d, a, b, c, GET(5) + ac1, 5)
|
||||||
|
STEP(G, c, d, a, b, GET(9) + ac1, 9)
|
||||||
|
STEP(G, b, c, d, a, GET(13) + ac1, 13)
|
||||||
|
STEP(G, a, b, c, d, GET(2) + ac1, 3)
|
||||||
|
STEP(G, d, a, b, c, GET(6) + ac1, 5)
|
||||||
|
STEP(G, c, d, a, b, GET(10) + ac1, 9)
|
||||||
|
STEP(G, b, c, d, a, GET(14) + ac1, 13)
|
||||||
|
STEP(G, a, b, c, d, GET(3) + ac1, 3)
|
||||||
|
STEP(G, d, a, b, c, GET(7) + ac1, 5)
|
||||||
|
STEP(G, c, d, a, b, GET(11) + ac1, 9)
|
||||||
|
STEP(G, b, c, d, a, GET(15) + ac1, 13)
|
||||||
|
|
||||||
|
/* Round 3 */
|
||||||
|
STEP(H, a, b, c, d, GET(0) + ac2, 3)
|
||||||
|
STEP(H, d, a, b, c, GET(8) + ac2, 9)
|
||||||
|
STEP(H, c, d, a, b, GET(4) + ac2, 11)
|
||||||
|
STEP(H, b, c, d, a, GET(12) + ac2, 15)
|
||||||
|
STEP(H, a, b, c, d, GET(2) + ac2, 3)
|
||||||
|
STEP(H, d, a, b, c, GET(10) + ac2, 9)
|
||||||
|
STEP(H, c, d, a, b, GET(6) + ac2, 11)
|
||||||
|
STEP(H, b, c, d, a, GET(14) + ac2, 15)
|
||||||
|
STEP(H, a, b, c, d, GET(1) + ac2, 3)
|
||||||
|
STEP(H, d, a, b, c, GET(9) + ac2, 9)
|
||||||
|
STEP(H, c, d, a, b, GET(5) + ac2, 11)
|
||||||
|
STEP(H, b, c, d, a, GET(13) + ac2, 15)
|
||||||
|
STEP(H, a, b, c, d, GET(3) + ac2, 3)
|
||||||
|
STEP(H, d, a, b, c, GET(11) + ac2, 9)
|
||||||
|
STEP(H, c, d, a, b, GET(7) + ac2, 11)
|
||||||
|
STEP(H, b, c, d, a, GET(15) + ac2, 15)
|
||||||
|
|
||||||
|
a += saved_a;
|
||||||
|
b += saved_b;
|
||||||
|
c += saved_c;
|
||||||
|
d += saved_d;
|
||||||
|
|
||||||
|
ptr += 64;
|
||||||
|
} while (size -= 64);
|
||||||
|
|
||||||
|
ctx->a = a;
|
||||||
|
ctx->b = b;
|
||||||
|
ctx->c = c;
|
||||||
|
ctx->d = d;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MD4_Init(MD4_CTX *ctx)
|
||||||
|
{
|
||||||
|
ctx->a = 0x67452301;
|
||||||
|
ctx->b = 0xefcdab89;
|
||||||
|
ctx->c = 0x98badcfe;
|
||||||
|
ctx->d = 0x10325476;
|
||||||
|
|
||||||
|
ctx->lo = 0;
|
||||||
|
ctx->hi = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MD4_Update(MD4_CTX *ctx, const void *data, size_t size)
|
||||||
|
{
|
||||||
|
MD4_u32plus saved_lo;
|
||||||
|
size_t used, available;
|
||||||
|
|
||||||
|
saved_lo = ctx->lo;
|
||||||
|
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
|
||||||
|
ctx->hi++;
|
||||||
|
ctx->hi += (MD4_u32plus)(size >> 29);
|
||||||
|
|
||||||
|
used = saved_lo & 0x3f;
|
||||||
|
|
||||||
|
if (used) {
|
||||||
|
available = 64 - used;
|
||||||
|
|
||||||
|
if (size < available) {
|
||||||
|
memcpy(&ctx->buffer[used], data, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&ctx->buffer[used], data, available);
|
||||||
|
data = (const unsigned char *)data + available;
|
||||||
|
size -= available;
|
||||||
|
body(ctx, ctx->buffer, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size >= 64) {
|
||||||
|
data = body(ctx, data, size & ~(size_t)0x3f);
|
||||||
|
size &= 0x3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ctx->buffer, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OUT(dst, src) \
|
||||||
|
(dst)[0] = (unsigned char)(src); \
|
||||||
|
(dst)[1] = (unsigned char)((src) >> 8); \
|
||||||
|
(dst)[2] = (unsigned char)((src) >> 16); \
|
||||||
|
(dst)[3] = (unsigned char)((src) >> 24);
|
||||||
|
|
||||||
|
void MD4_Final(unsigned char *result, MD4_CTX *ctx)
|
||||||
|
{
|
||||||
|
size_t used, available;
|
||||||
|
|
||||||
|
used = ctx->lo & 0x3f;
|
||||||
|
|
||||||
|
ctx->buffer[used++] = 0x80;
|
||||||
|
|
||||||
|
available = 64 - used;
|
||||||
|
|
||||||
|
if (available < 8) {
|
||||||
|
memset(&ctx->buffer[used], 0, available);
|
||||||
|
body(ctx, ctx->buffer, 64);
|
||||||
|
used = 0;
|
||||||
|
available = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&ctx->buffer[used], 0, available - 8);
|
||||||
|
|
||||||
|
ctx->lo <<= 3;
|
||||||
|
OUT(&ctx->buffer[56], ctx->lo)
|
||||||
|
OUT(&ctx->buffer[60], ctx->hi)
|
||||||
|
|
||||||
|
body(ctx, ctx->buffer, 64);
|
||||||
|
|
||||||
|
OUT(&result[0], ctx->a)
|
||||||
|
OUT(&result[4], ctx->b)
|
||||||
|
OUT(&result[8], ctx->c)
|
||||||
|
OUT(&result[12], ctx->d)
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !WITH_WOLFSSL || NO_MD4 */
|
||||||
57
src/libs/md4.h
Normal file
57
src/libs/md4.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* This is an OpenSSL API compatible (but not ABI compatible) implementation
|
||||||
|
* of the RSA Data Security, Inc. MD4 Message-Digest Algorithm (RFC 1320).
|
||||||
|
*
|
||||||
|
* Homepage:
|
||||||
|
* https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||||
|
*
|
||||||
|
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||||
|
* claimed, and the software is hereby placed in the public domain.
|
||||||
|
* In case this attempt to disclaim copyright and place the software in the
|
||||||
|
* public domain is deemed null and void, then the software is
|
||||||
|
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||||
|
* general public under the following terms:
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||||
|
*
|
||||||
|
* See md4.c for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MD4_H
|
||||||
|
#define _MD4_H
|
||||||
|
|
||||||
|
#ifdef WITH_WOLFSSL
|
||||||
|
#include <wolfssl/options.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WITH_WOLFSSL) && !defined(NO_MD4)
|
||||||
|
#include <wolfssl/openssl/md4.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <stddef.h> /* for size_t */
|
||||||
|
|
||||||
|
/* Any 32-bit or wider unsigned integer data type will do */
|
||||||
|
typedef unsigned int MD4_u32plus;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MD4_u32plus lo, hi;
|
||||||
|
MD4_u32plus a, b, c, d;
|
||||||
|
unsigned char buffer[64];
|
||||||
|
#if !(defined(__i386__) || defined(__x86_64__) || defined(__vax__))
|
||||||
|
MD4_u32plus block[16];
|
||||||
|
#endif
|
||||||
|
} MD4_CTX;
|
||||||
|
|
||||||
|
extern void MD4_Init(MD4_CTX *ctx);
|
||||||
|
extern void MD4_Update(MD4_CTX *ctx, const void *data, size_t size);
|
||||||
|
extern void MD4_Final(unsigned char *result, MD4_CTX *ctx);
|
||||||
|
|
||||||
|
#endif /* !WITH_WOLFSSL */
|
||||||
|
|
||||||
|
#endif
|
||||||
295
src/libs/md5.c
Normal file
295
src/libs/md5.c
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
/*
|
||||||
|
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||||
|
* MD5 Message-Digest Algorithm (RFC 1321).
|
||||||
|
*
|
||||||
|
* Homepage:
|
||||||
|
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||||
|
*
|
||||||
|
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||||
|
* claimed, and the software is hereby placed in the public domain.
|
||||||
|
* In case this attempt to disclaim copyright and place the software in the
|
||||||
|
* public domain is deemed null and void, then the software is
|
||||||
|
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||||
|
* general public under the following terms:
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||||
|
*
|
||||||
|
* (This is a heavily cut-down "BSD license".)
|
||||||
|
*
|
||||||
|
* This differs from Colin Plumb's older public domain implementation in that
|
||||||
|
* no exactly 32-bit integer data type is required (any 32-bit or wider
|
||||||
|
* unsigned integer data type will do), there's no compile-time endianness
|
||||||
|
* configuration, and the function prototypes match OpenSSL's. No code from
|
||||||
|
* Colin Plumb's implementation has been reused; this comment merely compares
|
||||||
|
* the properties of the two independent implementations.
|
||||||
|
*
|
||||||
|
* The primary goals of this implementation are portability and ease of use.
|
||||||
|
* It is meant to be fast, but not as fast as possible. Some known
|
||||||
|
* optimizations are not included to reduce source code size and avoid
|
||||||
|
* compile-time configuration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(WITH_WOLFSSL)
|
||||||
|
#include <wolfssl/options.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(WITH_WOLFSSL) || defined(NO_MD5)
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "md5.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The basic MD5 functions.
|
||||||
|
*
|
||||||
|
* F and G are optimized compared to their RFC 1321 definitions for
|
||||||
|
* architectures that lack an AND-NOT instruction, just like in Colin Plumb's
|
||||||
|
* implementation.
|
||||||
|
*/
|
||||||
|
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
|
||||||
|
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
|
||||||
|
#define H(x, y, z) (((x) ^ (y)) ^ (z))
|
||||||
|
#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
|
||||||
|
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The MD5 transformation for all four rounds.
|
||||||
|
*/
|
||||||
|
#define STEP(f, a, b, c, d, x, t, s) \
|
||||||
|
(a) += f((b), (c), (d)) + (x) + (t); \
|
||||||
|
(a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
|
||||||
|
(a) += (b);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SET reads 4 input bytes in little-endian byte order and stores them in a
|
||||||
|
* properly aligned word in host byte order.
|
||||||
|
*
|
||||||
|
* The check for little-endian architectures that tolerate unaligned memory
|
||||||
|
* accesses is just an optimization. Nothing will break if it fails to detect
|
||||||
|
* a suitable architecture.
|
||||||
|
*
|
||||||
|
* Unfortunately, this optimization may be a C strict aliasing rules violation
|
||||||
|
* if the caller's data buffer has effective type that cannot be aliased by
|
||||||
|
* MD5_u32plus. In practice, this problem may occur if these MD5 routines are
|
||||||
|
* inlined into a calling function, or with future and dangerously advanced
|
||||||
|
* link-time optimizations. For the time being, keeping these MD5 routines in
|
||||||
|
* their own translation unit avoids the problem.
|
||||||
|
*/
|
||||||
|
#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
|
||||||
|
#define SET(n) \
|
||||||
|
(*(MD5_u32plus *)&ptr[(n) * 4])
|
||||||
|
#define GET(n) \
|
||||||
|
SET(n)
|
||||||
|
#else
|
||||||
|
#define SET(n) \
|
||||||
|
(ctx->block[(n)] = \
|
||||||
|
(MD5_u32plus)ptr[(n) * 4] | \
|
||||||
|
((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
|
||||||
|
((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
|
||||||
|
((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
|
||||||
|
#define GET(n) \
|
||||||
|
(ctx->block[(n)])
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This processes one or more 64-byte data blocks, but does NOT update the bit
|
||||||
|
* counters. There are no alignment requirements.
|
||||||
|
*/
|
||||||
|
static const void *body(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||||
|
{
|
||||||
|
const unsigned char *ptr;
|
||||||
|
MD5_u32plus a, b, c, d;
|
||||||
|
MD5_u32plus saved_a, saved_b, saved_c, saved_d;
|
||||||
|
|
||||||
|
ptr = (const unsigned char *)data;
|
||||||
|
|
||||||
|
a = ctx->a;
|
||||||
|
b = ctx->b;
|
||||||
|
c = ctx->c;
|
||||||
|
d = ctx->d;
|
||||||
|
|
||||||
|
do {
|
||||||
|
saved_a = a;
|
||||||
|
saved_b = b;
|
||||||
|
saved_c = c;
|
||||||
|
saved_d = d;
|
||||||
|
|
||||||
|
/* Round 1 */
|
||||||
|
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
|
||||||
|
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
|
||||||
|
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
|
||||||
|
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
|
||||||
|
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
|
||||||
|
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
|
||||||
|
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
|
||||||
|
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
|
||||||
|
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
|
||||||
|
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
|
||||||
|
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
|
||||||
|
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
|
||||||
|
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
|
||||||
|
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
|
||||||
|
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
|
||||||
|
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
|
||||||
|
|
||||||
|
/* Round 2 */
|
||||||
|
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
|
||||||
|
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
|
||||||
|
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
|
||||||
|
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
|
||||||
|
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
|
||||||
|
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
|
||||||
|
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
|
||||||
|
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
|
||||||
|
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
|
||||||
|
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
|
||||||
|
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
|
||||||
|
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
|
||||||
|
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
|
||||||
|
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
|
||||||
|
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
|
||||||
|
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
|
||||||
|
|
||||||
|
/* Round 3 */
|
||||||
|
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
|
||||||
|
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
|
||||||
|
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
|
||||||
|
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
|
||||||
|
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
|
||||||
|
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
|
||||||
|
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
|
||||||
|
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
|
||||||
|
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
|
||||||
|
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
|
||||||
|
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
|
||||||
|
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
|
||||||
|
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
|
||||||
|
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
|
||||||
|
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
|
||||||
|
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
|
||||||
|
|
||||||
|
/* Round 4 */
|
||||||
|
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
|
||||||
|
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
|
||||||
|
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
|
||||||
|
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
|
||||||
|
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
|
||||||
|
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
|
||||||
|
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
|
||||||
|
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
|
||||||
|
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
|
||||||
|
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
|
||||||
|
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
|
||||||
|
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
|
||||||
|
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
|
||||||
|
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
|
||||||
|
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
|
||||||
|
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
|
||||||
|
|
||||||
|
a += saved_a;
|
||||||
|
b += saved_b;
|
||||||
|
c += saved_c;
|
||||||
|
d += saved_d;
|
||||||
|
|
||||||
|
ptr += 64;
|
||||||
|
} while (size -= 64);
|
||||||
|
|
||||||
|
ctx->a = a;
|
||||||
|
ctx->b = b;
|
||||||
|
ctx->c = c;
|
||||||
|
ctx->d = d;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MD5_Init(MD5_CTX *ctx)
|
||||||
|
{
|
||||||
|
ctx->a = 0x67452301;
|
||||||
|
ctx->b = 0xefcdab89;
|
||||||
|
ctx->c = 0x98badcfe;
|
||||||
|
ctx->d = 0x10325476;
|
||||||
|
|
||||||
|
ctx->lo = 0;
|
||||||
|
ctx->hi = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size)
|
||||||
|
{
|
||||||
|
MD5_u32plus saved_lo;
|
||||||
|
unsigned long used, available;
|
||||||
|
|
||||||
|
saved_lo = ctx->lo;
|
||||||
|
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
|
||||||
|
ctx->hi++;
|
||||||
|
ctx->hi += size >> 29;
|
||||||
|
|
||||||
|
used = saved_lo & 0x3f;
|
||||||
|
|
||||||
|
if (used) {
|
||||||
|
available = 64 - used;
|
||||||
|
|
||||||
|
if (size < available) {
|
||||||
|
memcpy(&ctx->buffer[used], data, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&ctx->buffer[used], data, available);
|
||||||
|
data = (const unsigned char *)data + available;
|
||||||
|
size -= available;
|
||||||
|
body(ctx, ctx->buffer, 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size >= 64) {
|
||||||
|
data = body(ctx, data, size & ~(unsigned long)0x3f);
|
||||||
|
size &= 0x3f;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ctx->buffer, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OUT(dst, src) \
|
||||||
|
(dst)[0] = (unsigned char)(src); \
|
||||||
|
(dst)[1] = (unsigned char)((src) >> 8); \
|
||||||
|
(dst)[2] = (unsigned char)((src) >> 16); \
|
||||||
|
(dst)[3] = (unsigned char)((src) >> 24);
|
||||||
|
|
||||||
|
void MD5_Final(unsigned char *result, MD5_CTX *ctx)
|
||||||
|
{
|
||||||
|
unsigned long used, available;
|
||||||
|
|
||||||
|
used = ctx->lo & 0x3f;
|
||||||
|
|
||||||
|
ctx->buffer[used++] = 0x80;
|
||||||
|
|
||||||
|
available = 64 - used;
|
||||||
|
|
||||||
|
if (available < 8) {
|
||||||
|
memset(&ctx->buffer[used], 0, available);
|
||||||
|
body(ctx, ctx->buffer, 64);
|
||||||
|
used = 0;
|
||||||
|
available = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&ctx->buffer[used], 0, available - 8);
|
||||||
|
|
||||||
|
ctx->lo <<= 3;
|
||||||
|
OUT(&ctx->buffer[56], ctx->lo)
|
||||||
|
OUT(&ctx->buffer[60], ctx->hi)
|
||||||
|
|
||||||
|
body(ctx, ctx->buffer, 64);
|
||||||
|
|
||||||
|
OUT(&result[0], ctx->a)
|
||||||
|
OUT(&result[4], ctx->b)
|
||||||
|
OUT(&result[8], ctx->c)
|
||||||
|
OUT(&result[12], ctx->d)
|
||||||
|
|
||||||
|
memset(ctx, 0, sizeof(*ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !WITH_WOLFSSL || NO_MD5 */
|
||||||
53
src/libs/md5.h
Normal file
53
src/libs/md5.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
|
||||||
|
* MD5 Message-Digest Algorithm (RFC 1321).
|
||||||
|
*
|
||||||
|
* Homepage:
|
||||||
|
* http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
|
||||||
|
*
|
||||||
|
* Author:
|
||||||
|
* Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
|
||||||
|
*
|
||||||
|
* This software was written by Alexander Peslyak in 2001. No copyright is
|
||||||
|
* claimed, and the software is hereby placed in the public domain.
|
||||||
|
* In case this attempt to disclaim copyright and place the software in the
|
||||||
|
* public domain is deemed null and void, then the software is
|
||||||
|
* Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
|
||||||
|
* general public under the following terms:
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted.
|
||||||
|
*
|
||||||
|
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||||
|
*
|
||||||
|
* See md5.c for more information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _MD5_H
|
||||||
|
#define _MD5_H
|
||||||
|
|
||||||
|
#ifdef WITH_WOLFSSL
|
||||||
|
#include <wolfssl/options.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WITH_WOLFSSL) && !defined(NO_MD5)
|
||||||
|
#include <wolfssl/openssl/md5.h>
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Any 32-bit or wider unsigned integer data type will do */
|
||||||
|
typedef unsigned int MD5_u32plus;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MD5_u32plus lo, hi;
|
||||||
|
MD5_u32plus a, b, c, d;
|
||||||
|
unsigned char buffer[64];
|
||||||
|
MD5_u32plus block[16];
|
||||||
|
} MD5_CTX;
|
||||||
|
|
||||||
|
extern void MD5_Init(MD5_CTX *ctx);
|
||||||
|
extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
|
||||||
|
extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
|
||||||
|
|
||||||
|
#endif /* !WITH_WOLFSSL */
|
||||||
|
|
||||||
|
#endif
|
||||||
211
src/mdhash.c
Normal file
211
src/mdhash.c
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
3APA3A simplest proxy server
|
||||||
|
(c) 2002-2026 by Vladimir Dubrovin <vlad@3proxy.org>
|
||||||
|
|
||||||
|
please read License Agreement
|
||||||
|
|
||||||
|
MD4/MD5/BLAKE2 hash implementation.
|
||||||
|
- Windows (no wolfSSL): CryptoAPI (CAPI) for MD4/MD5; bundled BLAKE2.
|
||||||
|
- wolfSSL: wolfCrypt for MD4/MD5 (OpenSSL compat) and BLAKE2 (native wc_*).
|
||||||
|
- Other: bundled public-domain MD4/MD5 + bundled BLAKE2 reference.
|
||||||
|
*/
|
||||||
|
#include "mdhash.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/* ----- BLAKE2 backend selection ----- */
|
||||||
|
/* wolfSSL may provide BLAKE2 natively (HAVE_BLAKE2B). If not enabled
|
||||||
|
(e.g. vcpkg port), fall back to the bundled reference implementation. */
|
||||||
|
#ifdef WITH_WOLFSSL
|
||||||
|
#include <wolfssl/options.h>
|
||||||
|
#ifdef HAVE_BLAKE2B
|
||||||
|
#include <wolfssl/wolfcrypt/blake2.h>
|
||||||
|
#define MDH_BLAKE2_BACKEND_WOLFSSL
|
||||||
|
#else
|
||||||
|
#include "libs/blake2.h"
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#include "libs/blake2.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ----- MD4/MD5 backend selection ----- */
|
||||||
|
#if defined(_WIN32) && !defined(WITH_WOLFSSL)
|
||||||
|
#define MDH_MD_BACKEND_CAPI
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <wincrypt.h>
|
||||||
|
#else
|
||||||
|
#include "libs/md4.h"
|
||||||
|
#include "libs/md5.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct mdh_ctx {
|
||||||
|
mdh_alg alg;
|
||||||
|
unsigned int outlen;
|
||||||
|
#ifdef MDH_MD_BACKEND_CAPI
|
||||||
|
HCRYPTPROV hProv;
|
||||||
|
HCRYPTHASH hHash;
|
||||||
|
#else
|
||||||
|
union {
|
||||||
|
MD4_CTX md4;
|
||||||
|
MD5_CTX md5;
|
||||||
|
} u;
|
||||||
|
#endif
|
||||||
|
#ifdef MDH_BLAKE2_BACKEND_WOLFSSL
|
||||||
|
Blake2b blake2;
|
||||||
|
#else
|
||||||
|
blake2b_state blake2;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
mdh_ctx *mdh_init(mdh_alg alg, unsigned int outlen)
|
||||||
|
{
|
||||||
|
mdh_ctx *c = (mdh_ctx *)malloc(sizeof(mdh_ctx));
|
||||||
|
if(!c) return NULL;
|
||||||
|
memset(c, 0, sizeof(*c));
|
||||||
|
c->alg = alg;
|
||||||
|
c->outlen = outlen;
|
||||||
|
|
||||||
|
switch(alg) {
|
||||||
|
case MDH_MD4:
|
||||||
|
#ifdef MDH_MD_BACKEND_CAPI
|
||||||
|
if(!CryptAcquireContext(&c->hProv, NULL, NULL, PROV_RSA_FULL,
|
||||||
|
CRYPT_VERIFYCONTEXT)) {
|
||||||
|
free(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!CryptCreateHash(c->hProv, CALG_MD4, 0, 0, &c->hHash)) {
|
||||||
|
CryptReleaseContext(c->hProv, 0);
|
||||||
|
free(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
MD4_Init(&c->u.md4);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case MDH_MD5:
|
||||||
|
#ifdef MDH_MD_BACKEND_CAPI
|
||||||
|
if(!CryptAcquireContext(&c->hProv, NULL, NULL, PROV_RSA_FULL,
|
||||||
|
CRYPT_VERIFYCONTEXT)) {
|
||||||
|
free(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!CryptCreateHash(c->hProv, CALG_MD5, 0, 0, &c->hHash)) {
|
||||||
|
CryptReleaseContext(c->hProv, 0);
|
||||||
|
free(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
MD5_Init(&c->u.md5);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case MDH_BLAKE2:
|
||||||
|
if(!outlen || outlen > 64) {
|
||||||
|
free(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#ifdef MDH_BLAKE2_BACKEND_WOLFSSL
|
||||||
|
if(wc_InitBlake2b(&c->blake2, outlen) != 0) {
|
||||||
|
free(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if(blake2b_init(&c->blake2, outlen) != 0) {
|
||||||
|
free(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
free(c);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mdh_update(mdh_ctx *c, const void *data, unsigned int len)
|
||||||
|
{
|
||||||
|
if(!c) return 0;
|
||||||
|
if(len == 0) return 1;
|
||||||
|
switch(c->alg) {
|
||||||
|
case MDH_MD4:
|
||||||
|
#ifdef MDH_MD_BACKEND_CAPI
|
||||||
|
return CryptHashData(c->hHash, (BYTE *)data, len, 0) ? 1 : 0;
|
||||||
|
#else
|
||||||
|
MD4_Update(&c->u.md4, data, (size_t)len);
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
case MDH_MD5:
|
||||||
|
#ifdef MDH_MD_BACKEND_CAPI
|
||||||
|
return CryptHashData(c->hHash, (BYTE *)data, len, 0) ? 1 : 0;
|
||||||
|
#else
|
||||||
|
MD5_Update(&c->u.md5, data, (unsigned long)len);
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
case MDH_BLAKE2:
|
||||||
|
#ifdef MDH_BLAKE2_BACKEND_WOLFSSL
|
||||||
|
return wc_Blake2bUpdate(&c->blake2, (const byte *)data, len) == 0;
|
||||||
|
#else
|
||||||
|
return blake2b_update(&c->blake2, data, len) == 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mdh_final(mdh_ctx *c, unsigned char *out, unsigned int *outlen)
|
||||||
|
{
|
||||||
|
if(!c || !outlen) return 0;
|
||||||
|
switch(c->alg) {
|
||||||
|
case MDH_MD4:
|
||||||
|
#ifdef MDH_MD_BACKEND_CAPI
|
||||||
|
{
|
||||||
|
DWORD l = (DWORD)*outlen;
|
||||||
|
if(!CryptGetHashParam(c->hHash, HP_HASHVAL, out, &l, 0))
|
||||||
|
return 0;
|
||||||
|
*outlen = (unsigned int)l;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
MD4_Final(out, &c->u.md4);
|
||||||
|
*outlen = 16;
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
case MDH_MD5:
|
||||||
|
#ifdef MDH_MD_BACKEND_CAPI
|
||||||
|
{
|
||||||
|
DWORD l = (DWORD)*outlen;
|
||||||
|
if(!CryptGetHashParam(c->hHash, HP_HASHVAL, out, &l, 0))
|
||||||
|
return 0;
|
||||||
|
*outlen = (unsigned int)l;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
MD5_Final(out, &c->u.md5);
|
||||||
|
*outlen = 16;
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
case MDH_BLAKE2:
|
||||||
|
if(*outlen < c->outlen) return 0;
|
||||||
|
#ifdef MDH_BLAKE2_BACKEND_WOLFSSL
|
||||||
|
if(wc_Blake2bFinal(&c->blake2, out, c->outlen) != 0)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
if(blake2b_final(&c->blake2, out, c->outlen) != 0)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
*outlen = c->outlen;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mdh_free(mdh_ctx *c)
|
||||||
|
{
|
||||||
|
if(!c) return;
|
||||||
|
#ifdef MDH_MD_BACKEND_CAPI
|
||||||
|
if(c->hHash) CryptDestroyHash(c->hHash);
|
||||||
|
if(c->hProv) CryptReleaseContext(c->hProv, 0);
|
||||||
|
#endif
|
||||||
|
memset(c, 0, sizeof(*c));
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
35
src/mdhash.h
Normal file
35
src/mdhash.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
3APA3A simplest proxy server
|
||||||
|
(c) 2002-2026 by Vladimir Dubrovin <vlad@3proxy.org>
|
||||||
|
|
||||||
|
please read License Agreement
|
||||||
|
|
||||||
|
Internal MD4/MD5/BLAKE2 hash abstraction.
|
||||||
|
- Windows (no wolfSSL): CryptoAPI (CAPI) for MD4/MD5; bundled BLAKE2.
|
||||||
|
- wolfSSL: wolfCrypt for MD4/MD5 (OpenSSL compat) and BLAKE2 (native).
|
||||||
|
- Other: bundled public-domain MD4/MD5 + bundled BLAKE2 reference.
|
||||||
|
*/
|
||||||
|
#ifndef _MDHASH_H
|
||||||
|
#define _MDHASH_H
|
||||||
|
|
||||||
|
typedef enum { MDH_MD4, MDH_MD5, MDH_BLAKE2 } mdh_alg;
|
||||||
|
|
||||||
|
typedef struct mdh_ctx mdh_ctx;
|
||||||
|
|
||||||
|
/* alg selects the hash. outlen selects digest size:
|
||||||
|
- MD4/MD5: outlen ignored (fixed 16 bytes).
|
||||||
|
- BLAKE2: outlen is the requested digest length (1..64).
|
||||||
|
Returns NULL on failure. */
|
||||||
|
mdh_ctx *mdh_init(mdh_alg alg, unsigned int outlen);
|
||||||
|
|
||||||
|
/* Returns 1 on success, 0 on failure. */
|
||||||
|
int mdh_update(mdh_ctx *c, const void *data, unsigned int len);
|
||||||
|
|
||||||
|
/* outlen is in/out: caller passes buffer size, receives hash length.
|
||||||
|
Returns 1 on success, 0 on failure. */
|
||||||
|
int mdh_final(mdh_ctx *c, unsigned char *out, unsigned int *outlen);
|
||||||
|
|
||||||
|
/* Safe to call with NULL. */
|
||||||
|
void mdh_free(mdh_ctx *c);
|
||||||
|
|
||||||
|
#endif /* _MDHASH_H */
|
||||||
32
src/pcre.c
32
src/pcre.c
@ -214,6 +214,7 @@ struct pcre_filter_data {
|
|||||||
int users;
|
int users;
|
||||||
pcre2_code * re;
|
pcre2_code * re;
|
||||||
pcre2_match_data * match_data;
|
pcre2_match_data * match_data;
|
||||||
|
pcre2_match_context * match_context;
|
||||||
int action;
|
int action;
|
||||||
char * replace;
|
char * replace;
|
||||||
struct ace *acl;
|
struct ace *acl;
|
||||||
@ -223,6 +224,7 @@ static void pcre_data_free(struct pcre_filter_data *pcrefd){
|
|||||||
_3proxy_mutex_lock(&pcre_mutex);
|
_3proxy_mutex_lock(&pcre_mutex);
|
||||||
pcrefd->users--;
|
pcrefd->users--;
|
||||||
if(!pcrefd->users){
|
if(!pcrefd->users){
|
||||||
|
if(pcrefd->match_context) pcre2_match_context_free(pcrefd->match_context);
|
||||||
if(pcrefd->match_data) pcre2_match_data_free(pcrefd->match_data);
|
if(pcrefd->match_data) pcre2_match_data_free(pcrefd->match_data);
|
||||||
if(pcrefd->re) pcre2_code_free(pcrefd->re);
|
if(pcrefd->re) pcre2_code_free(pcrefd->re);
|
||||||
if(pcrefd->acl) pl->freeacl(pcrefd->acl);
|
if(pcrefd->acl) pl->freeacl(pcrefd->acl);
|
||||||
@ -283,10 +285,12 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
|
|||||||
if(!match) return CONTINUE;
|
if(!match) return CONTINUE;
|
||||||
if(!pcrefd->re) return pcrefd->action;
|
if(!pcrefd->re) return pcrefd->action;
|
||||||
for(; offset < *length_p; nreplaces++){
|
for(; offset < *length_p; nreplaces++){
|
||||||
|
int repsz;
|
||||||
|
|
||||||
count = pcre2_match(pcrefd->re, (PCRE2_SPTR)*buf_p, *length_p, offset, 0, pcrefd->match_data, NULL);
|
count = pcre2_match(pcrefd->re, (PCRE2_SPTR)*buf_p, *length_p, offset, 0, pcrefd->match_data, pcrefd->match_context);
|
||||||
if(count <= 0) break;
|
if(count <= 0) break;
|
||||||
ovector = pcre2_get_ovector_pointer(pcrefd->match_data);
|
ovector = pcre2_get_ovector_pointer(pcrefd->match_data);
|
||||||
|
if(ovector[0] > (PCRE2_SIZE)*length_p || ovector[1] > (PCRE2_SIZE)*length_p || ovector[1] < ovector[0]) break;
|
||||||
if(!(replace = pcrefd->replace) || param->nooverwritefilter) return pcrefd->action;
|
if(!(replace = pcrefd->replace) || param->nooverwritefilter) return pcrefd->action;
|
||||||
|
|
||||||
replen = *length_p - ovector[1];
|
replen = *length_p - ovector[1];
|
||||||
@ -300,6 +304,8 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
|
|||||||
num = atoi(replace);
|
num = atoi(replace);
|
||||||
while(isnumber(*replace)) replace++;
|
while(isnumber(*replace)) replace++;
|
||||||
if(num > (count - 1)) continue;
|
if(num > (count - 1)) continue;
|
||||||
|
if(ovector[(num<<1)] == PCRE2_UNSET) continue;
|
||||||
|
if(ovector[(num<<1) + 1] > (PCRE2_SIZE)*length_p || ovector[(num<<1)] > ovector[(num<<1) + 1]) continue;
|
||||||
replen += (ovector[(num<<1) + 1] - ovector[(num<<1)]);
|
replen += (ovector[(num<<1) + 1] - ovector[(num<<1)]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -319,6 +325,8 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
|
|||||||
replace ++;
|
replace ++;
|
||||||
num = atoi(replace);
|
num = atoi(replace);
|
||||||
if(num > (count - 1)) continue;
|
if(num > (count - 1)) continue;
|
||||||
|
if(ovector[(num<<1)] == PCRE2_UNSET) continue;
|
||||||
|
if(ovector[(num<<1) + 1] > (PCRE2_SIZE)*length_p || ovector[(num<<1)] > ovector[(num<<1) + 1]) continue;
|
||||||
memcpy(target, *buf_p + ovector[(num<<1)], ovector[(num<<1) + 1] - ovector[(num<<1)]);
|
memcpy(target, *buf_p + ovector[(num<<1)], ovector[(num<<1) + 1] - ovector[(num<<1)]);
|
||||||
target += (ovector[(num<<1) + 1] - ovector[(num<<1)]);
|
target += (ovector[(num<<1) + 1] - ovector[(num<<1)]);
|
||||||
while(isnumber(*replace)) replace++;
|
while(isnumber(*replace)) replace++;
|
||||||
@ -327,6 +335,7 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
|
|||||||
*target++ = *replace++;
|
*target++ = *replace++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
repsz = (int)(target - tmpbuf);
|
||||||
memcpy(target, *buf_p + ovector[1], *length_p - ovector[1]);
|
memcpy(target, *buf_p + ovector[1], *length_p - ovector[1]);
|
||||||
if((ovector[0] + replen + 1) > *bufsize_p){
|
if((ovector[0] + replen + 1) > *bufsize_p){
|
||||||
newbuf = pl->mallocfunc(ovector[0] + replen + 1);
|
newbuf = pl->mallocfunc(ovector[0] + replen + 1);
|
||||||
@ -343,10 +352,11 @@ static FILTER_ACTION pcre_filter_buffer(void *fc, struct clientparam *param, uns
|
|||||||
pl->freefunc(tmpbuf);
|
pl->freefunc(tmpbuf);
|
||||||
(*buf_p)[ovector[0] + replen] = 0;
|
(*buf_p)[ovector[0] + replen] = 0;
|
||||||
*length_p = ovector[0] + replen;
|
*length_p = ovector[0] + replen;
|
||||||
if(ovector[0] + replen <= offset){
|
offset = ovector[0] + repsz;
|
||||||
break;
|
if(ovector[1] == ovector[0] && offset <= (int)ovector[0]){
|
||||||
|
/* zero-width match with empty replacement: force progress */
|
||||||
|
offset = ovector[1] + 1;
|
||||||
}
|
}
|
||||||
offset = ovector[0] + (int)strlen(pcrefd->replace);
|
|
||||||
}
|
}
|
||||||
return nreplaces? pcrefd->action : CONTINUE;
|
return nreplaces? pcrefd->action : CONTINUE;
|
||||||
#undef pcrefd
|
#undef pcrefd
|
||||||
@ -442,6 +452,13 @@ static int h_pcre(int argc, unsigned char **argv){
|
|||||||
flt->acl = acl;
|
flt->acl = acl;
|
||||||
flt->replace = replace;
|
flt->replace = replace;
|
||||||
flt->users = 1;
|
flt->users = 1;
|
||||||
|
if(re){
|
||||||
|
flt->match_context = pcre2_match_context_create(NULL);
|
||||||
|
if(flt->match_context){
|
||||||
|
pcre2_set_match_limit(flt->match_context, 1000000);
|
||||||
|
pcre2_set_depth_limit(flt->match_context, 10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
newf->instance = "pcre";
|
newf->instance = "pcre";
|
||||||
newf->data = flt;
|
newf->data = flt;
|
||||||
newf->filter_open = pcre_filter_open;
|
newf->filter_open = pcre_filter_open;
|
||||||
@ -549,6 +566,13 @@ static int h_pcre_rewrite(int argc, unsigned char **argv){
|
|||||||
flt->acl = acl;
|
flt->acl = acl;
|
||||||
flt->replace = replace;
|
flt->replace = replace;
|
||||||
flt->users = 1;
|
flt->users = 1;
|
||||||
|
if(re){
|
||||||
|
flt->match_context = pcre2_match_context_create(NULL);
|
||||||
|
if(flt->match_context){
|
||||||
|
pcre2_set_match_limit(flt->match_context, 1000000);
|
||||||
|
pcre2_set_depth_limit(flt->match_context, 10000);
|
||||||
|
}
|
||||||
|
}
|
||||||
newf->instance = "pcre";
|
newf->instance = "pcre";
|
||||||
newf->data = flt;
|
newf->data = flt;
|
||||||
newf->filter_open = pcre_filter_open;
|
newf->filter_open = pcre_filter_open;
|
||||||
|
|||||||
@ -71,6 +71,7 @@ struct symbol symbols[] = {
|
|||||||
{symbols+46, "make_ace", (void *) make_ace},
|
{symbols+46, "make_ace", (void *) make_ace},
|
||||||
{symbols+47, "freeacl", (void *) freeacl},
|
{symbols+47, "freeacl", (void *) freeacl},
|
||||||
{symbols+48, "handleredirect", (void *) handleredirect},
|
{symbols+48, "handleredirect", (void *) handleredirect},
|
||||||
|
{symbols+49, "imapp", (void *) imappchild},
|
||||||
{NULL, "", NULL}
|
{NULL, "", NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -51,8 +51,56 @@ void lower (char *string)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* RFC 4514 escaping for DN attribute values. Returns dst, NULL on overflow. */
|
||||||
|
static char * ldap_escape_dn(const char *src, char *dst, int dstlen)
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
unsigned char c;
|
||||||
|
for (; *src; src++){
|
||||||
|
c = (unsigned char)*src;
|
||||||
|
if(c == ',' || c == '+' || c == '"' || c == '\\' || c == '<' || c == '>' || c == ';' || c == '=' || c < 0x20 || c == 0x7f){
|
||||||
|
if(j + 3 >= dstlen) return NULL;
|
||||||
|
sprintf(dst + j, "\\%02X", c);
|
||||||
|
j += 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(j + 1 >= dstlen) return NULL;
|
||||||
|
dst[j++] = (char)c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst[j] = 0;
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RFC 4515 escaping for search filter values. Returns dst, NULL on overflow. */
|
||||||
|
static char * ldap_escape_filter(const char *src, char *dst, int dstlen)
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
unsigned char c;
|
||||||
|
for (; *src; src++){
|
||||||
|
c = (unsigned char)*src;
|
||||||
|
if(c == '*' || c == '(' || c == ')' || c == '\\' || c == 0 || c < 0x20 || c >= 0x7f){
|
||||||
|
if(j + 3 >= dstlen) return NULL;
|
||||||
|
sprintf(dst + j, "\\%02X", c);
|
||||||
|
j += 3;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if(j + 1 >= dstlen) return NULL;
|
||||||
|
dst[j++] = (char)c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst[j] = 0;
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reject names unsafe for use in filesystem paths */
|
||||||
|
static int unsafe_filename(const char *name)
|
||||||
|
{
|
||||||
|
return (strchr(name, '/') || strchr(name, '\\') || strstr(name, "..") || !*name);
|
||||||
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------- */
|
||||||
int savecounters(void)
|
int savecounters(void *v)
|
||||||
{
|
{
|
||||||
struct trafcount *tc=mypluginlink->conf->trafcounter;
|
struct trafcount *tc=mypluginlink->conf->trafcounter;
|
||||||
struct trafcount *tcd;
|
struct trafcount *tcd;
|
||||||
@ -67,8 +115,8 @@ int savecounters(void)
|
|||||||
tcd = tc;
|
tcd = tc;
|
||||||
tc = tc->next;
|
tc = tc->next;
|
||||||
f=NULL;
|
f=NULL;
|
||||||
if(strcmp(tcd->comment,"ldapcounters")==0) {
|
if(strcmp(tcd->comment,"ldapcounters")==0 && !unsafe_filename(tcd->ace->users->user)) {
|
||||||
tmpbuf=malloc(strlen(pat_file)+strlen(ldap_dircount)+strlen(tcd->ace->users->user));
|
tmpbuf=malloc(strlen(ldap_dircount)+strlen(tcd->ace->users->user)+sizeof(".lc"));
|
||||||
sprintf(tmpbuf,pat_file,ldap_dircount,tcd->ace->users->user);
|
sprintf(tmpbuf,pat_file,ldap_dircount,tcd->ace->users->user);
|
||||||
f=fopen(tmpbuf,"w+b");
|
f=fopen(tmpbuf,"w+b");
|
||||||
fseek(f,0,SEEK_SET);
|
fseek(f,0,SEEK_SET);
|
||||||
@ -100,6 +148,7 @@ static int ldapfunc(struct clientparam *param)
|
|||||||
LDAPMessage *res = NULL;
|
LDAPMessage *res = NULL;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
char tmpbuf[1024];
|
char tmpbuf[1024];
|
||||||
|
char escuser[512];
|
||||||
|
|
||||||
/* test proxy user auth ------------------------*/
|
/* test proxy user auth ------------------------*/
|
||||||
if(!param->username || !param->password) return 4;
|
if(!param->username || !param->password) return 4;
|
||||||
@ -126,7 +175,12 @@ static int ldapfunc(struct clientparam *param)
|
|||||||
|
|
||||||
|
|
||||||
/* create user for test auth */
|
/* create user for test auth */
|
||||||
sprintf(tmpbuf,"%.200s=%.200s,%.200s",attrs[0],param->username,ldap_userenv);
|
if(!ldap_escape_dn(param->username, escuser, sizeof(escuser)))
|
||||||
|
{
|
||||||
|
ldap_unbind_s(ld);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
snprintf(tmpbuf, sizeof(tmpbuf), "%.200s=%.510s,%.200s",attrs[0],escuser,ldap_userenv);
|
||||||
|
|
||||||
rc = ldap_bind_s( ld, tmpbuf, param->password, LDAP_AUTH_SIMPLE );
|
rc = ldap_bind_s( ld, tmpbuf, param->password, LDAP_AUTH_SIMPLE );
|
||||||
|
|
||||||
@ -162,7 +216,12 @@ static int ldapfunc(struct clientparam *param)
|
|||||||
/* test enter user in filter ------------------------------
|
/* test enter user in filter ------------------------------
|
||||||
create filter for search*/
|
create filter for search*/
|
||||||
|
|
||||||
sprintf(tmpbuf,"(&(%.200s=%.200s)(%.200s=%.200s))",attrs[0],param->username,
|
if(!ldap_escape_filter(param->username, escuser, sizeof(escuser)))
|
||||||
|
{
|
||||||
|
ldap_unbind_s(ld);
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
snprintf(tmpbuf, sizeof(tmpbuf), "(&(%.200s=%.510s)(%.200s=%.200s))",attrs[0],escuser,
|
||||||
ldap_group_attr,ldap_access);
|
ldap_group_attr,ldap_access);
|
||||||
|
|
||||||
|
|
||||||
@ -326,7 +385,7 @@ int h_trafgroup(int argc, unsigned char ** argv)
|
|||||||
while (rc > 0)
|
while (rc > 0)
|
||||||
{
|
{
|
||||||
vals=ldap_get_values(ld, msg, getattr);
|
vals=ldap_get_values(ld, msg, getattr);
|
||||||
if (vals != NULL && vals[0] != NULL )
|
if (vals != NULL && vals[0] != NULL && !unsafe_filename(vals[0]) )
|
||||||
{
|
{
|
||||||
|
|
||||||
/* -------------bandlim----------
|
/* -------------bandlim----------
|
||||||
@ -378,7 +437,7 @@ int h_trafgroup(int argc, unsigned char ** argv)
|
|||||||
newtrafcount->traflim64 = traflimit;
|
newtrafcount->traflim64 = traflimit;
|
||||||
newtrafcount->comment=(*mypluginlink->strdupfunc)("ldapcounters");
|
newtrafcount->comment=(*mypluginlink->strdupfunc)("ldapcounters");
|
||||||
newtrafcount->number=0;
|
newtrafcount->number=0;
|
||||||
tmpbuf=malloc(strlen(pat_file)+strlen(ldap_dircount)+strlen(vals[0]));
|
tmpbuf=malloc(strlen(ldap_dircount)+strlen(vals[0])+sizeof(".lc"));
|
||||||
sprintf(tmpbuf,pat_file,ldap_dircount,vals[0]);
|
sprintf(tmpbuf,pat_file,ldap_dircount,vals[0]);
|
||||||
f=NULL;
|
f=NULL;
|
||||||
f=fopen(tmpbuf,"rb");
|
f=fopen(tmpbuf,"rb");
|
||||||
|
|||||||
@ -49,9 +49,13 @@ char **load_string(FILE *f,int max_count_str, int *countloadstr,
|
|||||||
|
|
||||||
/*load from file new strings */
|
/*load from file new strings */
|
||||||
i=0;
|
i=0;
|
||||||
while ( !feof(f) || i< max_count_str)
|
while ( !feof(f) && i < max_count_str)
|
||||||
{
|
{
|
||||||
if(!fgets(tmpbuf1, 1023,f)) return NULL;
|
if(!fgets(tmpbuf1, 1023,f)){
|
||||||
|
if(pt) free(pt);
|
||||||
|
free(old_table);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((strstr(tmpbuf1,stop))!=NULL) { break; }
|
if ((strstr(tmpbuf1,stop))!=NULL) { break; }
|
||||||
|
|
||||||
|
|||||||
21
src/pop3p.c
21
src/pop3p.c
@ -10,6 +10,12 @@
|
|||||||
|
|
||||||
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
||||||
|
|
||||||
|
#ifdef WITHMAIN
|
||||||
|
#define NOSTARTTLS 1
|
||||||
|
#else
|
||||||
|
#define NOSTARTTLS param->srv->nostarttls
|
||||||
|
#endif
|
||||||
|
|
||||||
void * pop3pchild(struct clientparam* param) {
|
void * pop3pchild(struct clientparam* param) {
|
||||||
int i=0, res;
|
int i=0, res;
|
||||||
unsigned char buf[320];
|
unsigned char buf[320];
|
||||||
@ -22,6 +28,19 @@ void * pop3pchild(struct clientparam* param) {
|
|||||||
socksend(param, param->clisock, (unsigned char *)"+OK\r\n", 5,conf.timeouts[STRING_S]);
|
socksend(param, param->clisock, (unsigned char *)"+OK\r\n", 5,conf.timeouts[STRING_S]);
|
||||||
RETURN(0);
|
RETURN(0);
|
||||||
}
|
}
|
||||||
|
if(!strncasecmp((char *)buf, "CAPA", 4) && !NOSTARTTLS){
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"+OK Capability list follows\r\nSTLS\r\n.\r\n", 38, conf.timeouts[STRING_S]);
|
||||||
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#ifndef WITHMAIN
|
||||||
|
if(!strncasecmp((char *)buf, "STLS", 4) && !param->srv->nostarttls){
|
||||||
|
if(socksend(param, param->clisock, (unsigned char *)"+OK Begin TLS negotiation\r\n", 27, conf.timeouts[STRING_S])!=27) {RETURN(623);}
|
||||||
|
param->clientstarttls = S_POP3P;
|
||||||
|
if(!param->srv->targetport) param->srv->targetport = htons(110);
|
||||||
|
return tlsprchild(param);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
socksend(param, param->clisock, (unsigned char *)"-ERR need USER first\r\n", 22, conf.timeouts[STRING_S]);
|
socksend(param, param->clisock, (unsigned char *)"-ERR need USER first\r\n", 22, conf.timeouts[STRING_S]);
|
||||||
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
}
|
}
|
||||||
@ -65,7 +84,7 @@ struct proxydef childdef = {
|
|||||||
110,
|
110,
|
||||||
0,
|
0,
|
||||||
S_POP3P,
|
S_POP3P,
|
||||||
" -hdefault_host[:port] - use this host and port as default if no host specified\n"
|
" -hdefault_host[:port] - use this host and port as default if no host specified\n -x - disable STARTTLS\n"
|
||||||
|
|
||||||
};
|
};
|
||||||
#include "proxymain.c"
|
#include "proxymain.c"
|
||||||
|
|||||||
79
src/proxy.c
79
src/proxy.c
@ -240,6 +240,9 @@ void * proxychild(struct clientparam* param) {
|
|||||||
int keepalive = 0;
|
int keepalive = 0;
|
||||||
uint64_t contentlength64 = 0;
|
uint64_t contentlength64 = 0;
|
||||||
int hascontent =0;
|
int hascontent =0;
|
||||||
|
int clhdrofs = -1;
|
||||||
|
int chunkedcli = 0;
|
||||||
|
int clhdrofs_req = -1;
|
||||||
int isconnect = 0;
|
int isconnect = 0;
|
||||||
int redirect = 0;
|
int redirect = 0;
|
||||||
int prefix = 0, ckeepalive=0;
|
int prefix = 0, ckeepalive=0;
|
||||||
@ -266,6 +269,9 @@ void * proxychild(struct clientparam* param) {
|
|||||||
for(;;){
|
for(;;){
|
||||||
memset(buf, 0, bufsize);
|
memset(buf, 0, bufsize);
|
||||||
inbuf = 0;
|
inbuf = 0;
|
||||||
|
chunkedcli = 0;
|
||||||
|
clhdrofs_req = -1;
|
||||||
|
param->nolongdatfilter = 0;
|
||||||
|
|
||||||
|
|
||||||
if(keepalive && (param->cliinbuf == param->clioffset) && (param->remsock != INVALID_SOCKET)){
|
if(keepalive && (param->cliinbuf == param->clioffset) && (param->remsock != INVALID_SOCKET)){
|
||||||
@ -413,6 +419,10 @@ for(;;){
|
|||||||
param->password = (unsigned char *)strdup((char *)sb+1);
|
param->password = (unsigned char *)strdup((char *)sb+1);
|
||||||
param->pwtype = 0;
|
param->pwtype = 0;
|
||||||
}
|
}
|
||||||
|
else if(param->password){
|
||||||
|
free(param->password);
|
||||||
|
param->password = NULL;
|
||||||
|
}
|
||||||
if(param->username)free(param->username);
|
if(param->username)free(param->username);
|
||||||
param->username = (unsigned char *)strdup((char *)username);
|
param->username = (unsigned char *)strdup((char *)username);
|
||||||
continue;
|
continue;
|
||||||
@ -458,13 +468,14 @@ for(;;){
|
|||||||
if(parsehostname((char *)sb, param, 80)) RETURN(100);
|
if(parsehostname((char *)sb, param, 80)) RETURN(100);
|
||||||
}
|
}
|
||||||
newbuf = malloc(strlen((char *)req) + strlen((char *)(buf+inbuf)) + 8);
|
newbuf = malloc(strlen((char *)req) + strlen((char *)(buf+inbuf)) + 8);
|
||||||
if(newbuf){
|
|
||||||
sp = (unsigned char *)strchr((char *)req+1, '/');
|
sp = (unsigned char *)strchr((char *)req+1, '/');
|
||||||
|
if(newbuf && sp){
|
||||||
memcpy(newbuf, req, (sp - req));
|
memcpy(newbuf, req, (sp - req));
|
||||||
sprintf((char*)newbuf + (sp - req), "http://%s%s",sb,sp);
|
sprintf((char*)newbuf + (sp - req), "http://%s%s",sb,sp);
|
||||||
free(req);
|
free(req);
|
||||||
req = newbuf;
|
req = newbuf;
|
||||||
}
|
}
|
||||||
|
else if(newbuf) free(newbuf);
|
||||||
if(se)*se = c;
|
if(se)*se = c;
|
||||||
}
|
}
|
||||||
if(ftp && i > 13 && (!strncasecmp((char *)(buf+inbuf), "authorization", 13))){
|
if(ftp && i > 13 && (!strncasecmp((char *)(buf+inbuf), "authorization", 13))){
|
||||||
@ -485,12 +496,17 @@ for(;;){
|
|||||||
if(param->extpassword)free(param->extpassword);
|
if(param->extpassword)free(param->extpassword);
|
||||||
param->extpassword = (unsigned char *)strdup((char *)sb+1);
|
param->extpassword = (unsigned char *)strdup((char *)sb+1);
|
||||||
}
|
}
|
||||||
|
else if(param->extpassword){
|
||||||
|
free(param->extpassword);
|
||||||
|
param->extpassword = NULL;
|
||||||
|
}
|
||||||
if(param->extusername)free(param->extusername);
|
if(param->extusername)free(param->extusername);
|
||||||
param->extusername = (unsigned char *)strdup((char *)username);
|
param->extusername = (unsigned char *)strdup((char *)username);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(i> 15 && (!strncasecmp((char *)(buf+inbuf), "content-length", 14))){
|
if(i> 15 && (!strncasecmp((char *)(buf+inbuf), "content-length", 14))){
|
||||||
|
if(chunkedcli) continue;
|
||||||
sb = (unsigned char *)strchr((char *)(buf+inbuf), ':');
|
sb = (unsigned char *)strchr((char *)(buf+inbuf), ':');
|
||||||
if(!sb)continue;
|
if(!sb)continue;
|
||||||
++sb;
|
++sb;
|
||||||
@ -500,6 +516,23 @@ for(;;){
|
|||||||
RETURN(10);
|
RETURN(10);
|
||||||
}
|
}
|
||||||
if(param->ndatfilterscli > 0 && contentlength64 > 0) continue;
|
if(param->ndatfilterscli > 0 && contentlength64 > 0) continue;
|
||||||
|
clhdrofs_req = inbuf;
|
||||||
|
}
|
||||||
|
else if(i>25 && (!strncasecmp((char *)(buf+inbuf), "transfer-encoding", 17))){
|
||||||
|
sb = (unsigned char *)strchr((char *)(buf+inbuf), ':');
|
||||||
|
if(sb){
|
||||||
|
++sb;
|
||||||
|
while(isspace(*sb))sb++;
|
||||||
|
if(!strncasecmp((char *)sb, "chunked", 7)){
|
||||||
|
chunkedcli = 1;
|
||||||
|
if(clhdrofs_req >= 0){
|
||||||
|
buf[clhdrofs_req] = 'X';
|
||||||
|
clhdrofs_req = -1;
|
||||||
|
}
|
||||||
|
contentlength64 = 0;
|
||||||
|
param->nolongdatfilter = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
inbuf += i;
|
inbuf += i;
|
||||||
if((bufsize - inbuf) < LINESIZE){
|
if((bufsize - inbuf) < LINESIZE){
|
||||||
@ -565,7 +598,7 @@ for(;;){
|
|||||||
if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) {
|
if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) {
|
||||||
param->nolongdatfilter = 1;
|
param->nolongdatfilter = 1;
|
||||||
}
|
}
|
||||||
else if(param->ndatfilterscli > 0 && contentlength64 > 0){
|
else if(param->ndatfilterscli > 0 && contentlength64 > 0 && contentlength64 == (uint64_t)(unsigned long)contentlength64){
|
||||||
uint64_t newlen64;
|
uint64_t newlen64;
|
||||||
newlen64 = (uint64_t) sockfillbuffcli(param, (unsigned long)contentlength64, CONNECTION_S);
|
newlen64 = (uint64_t) sockfillbuffcli(param, (unsigned long)contentlength64, CONNECTION_S);
|
||||||
if(newlen64 == contentlength64) {
|
if(newlen64 == contentlength64) {
|
||||||
@ -906,7 +939,35 @@ for(;;){
|
|||||||
if(param->bandlimfunc) {
|
if(param->bandlimfunc) {
|
||||||
sleeptime = param->bandlimfunc(param, 0, (int)strlen((char *)buf));
|
sleeptime = param->bandlimfunc(param, 0, (int)strlen((char *)buf));
|
||||||
}
|
}
|
||||||
if(contentlength64 > 0){
|
if(chunkedcli || contentlength64 > 0){
|
||||||
|
if(chunkedcli){
|
||||||
|
do {
|
||||||
|
unsigned char smallbuf[32];
|
||||||
|
while ((i = sockgetlinebuf(param, CLIENT, smallbuf, 30, '\n', conf.timeouts[STRING_S])) == 2) {
|
||||||
|
if (socksend(param, param->remsock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(536);
|
||||||
|
if(chunkedcli == 2) break;
|
||||||
|
}
|
||||||
|
if(i<3) break;
|
||||||
|
if (socksend(param, param->remsock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(536);
|
||||||
|
if(chunkedcli == 2) {
|
||||||
|
if((i = sockgetlinebuf(param, CLIENT, smallbuf, 30, '\n', conf.timeouts[STRING_S])) != 2) RETURN(537);
|
||||||
|
if (socksend(param, param->remsock, smallbuf, i, conf.timeouts[STRING_S]) != i) RETURN(536);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
smallbuf[i] = 0;
|
||||||
|
contentlength64 = 0;
|
||||||
|
sscanf((char *)smallbuf, "%"SCNx64"", &contentlength64);
|
||||||
|
if(contentlength64 == 0) chunkedcli = 2;
|
||||||
|
else {
|
||||||
|
param->waitclient64 = contentlength64;
|
||||||
|
res = mapsocket(param, conf.timeouts[CONNECTION_S]);
|
||||||
|
param->waitclient64 = 0;
|
||||||
|
if(res != 99) RETURN(res);
|
||||||
|
}
|
||||||
|
} while(chunkedcli);
|
||||||
|
res = 99;
|
||||||
|
}
|
||||||
|
else {
|
||||||
param->waitclient64 = contentlength64;
|
param->waitclient64 = contentlength64;
|
||||||
res = mapsocket(param, conf.timeouts[CONNECTION_S]);
|
res = mapsocket(param, conf.timeouts[CONNECTION_S]);
|
||||||
param->waitclient64 = 0;
|
param->waitclient64 = 0;
|
||||||
@ -914,6 +975,7 @@ for(;;){
|
|||||||
RETURN(res);
|
RETURN(res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
contentlength64 = 0;
|
contentlength64 = 0;
|
||||||
inbuf = 0;
|
inbuf = 0;
|
||||||
ckeepalive = keepalive;
|
ckeepalive = keepalive;
|
||||||
@ -921,6 +983,7 @@ for(;;){
|
|||||||
authenticate = 0;
|
authenticate = 0;
|
||||||
param->chunked = 0;
|
param->chunked = 0;
|
||||||
hascontent = 0;
|
hascontent = 0;
|
||||||
|
clhdrofs = -1;
|
||||||
|
|
||||||
while( (i = sockgetlinebuf(param, SERVER, buf + inbuf, LINESIZE - 1, '\n', conf.timeouts[(res)?STRING_S:STRING_L])) > 2) {
|
while( (i = sockgetlinebuf(param, SERVER, buf + inbuf, LINESIZE - 1, '\n', conf.timeouts[(res)?STRING_S:STRING_L])) > 2) {
|
||||||
if(!res && i>9)param->status = res = atoi((char *)buf + inbuf + 9);
|
if(!res && i>9)param->status = res = atoi((char *)buf + inbuf + 9);
|
||||||
@ -942,6 +1005,7 @@ for(;;){
|
|||||||
authenticate = 1;
|
authenticate = 1;
|
||||||
}
|
}
|
||||||
else if(i > 15 && (!strncasecmp((char *)(buf+inbuf), "content-length", 14))){
|
else if(i > 15 && (!strncasecmp((char *)(buf+inbuf), "content-length", 14))){
|
||||||
|
if(param->chunked) continue;
|
||||||
buf[inbuf+i]=0;
|
buf[inbuf+i]=0;
|
||||||
sb = (unsigned char *)strchr((char *)(buf+inbuf), ':');
|
sb = (unsigned char *)strchr((char *)(buf+inbuf), ':');
|
||||||
if(!sb)continue;
|
if(!sb)continue;
|
||||||
@ -949,6 +1013,7 @@ for(;;){
|
|||||||
while(isspace(*sb))sb++;
|
while(isspace(*sb))sb++;
|
||||||
sscanf((char *)sb, "%"SCNu64"", &contentlength64);
|
sscanf((char *)sb, "%"SCNu64"", &contentlength64);
|
||||||
hascontent = 1;
|
hascontent = 1;
|
||||||
|
clhdrofs = inbuf;
|
||||||
if(param->unsafefilter && param->ndatfilterssrv > 0) {
|
if(param->unsafefilter && param->ndatfilterssrv > 0) {
|
||||||
hascontent = 2;
|
hascontent = 2;
|
||||||
continue;
|
continue;
|
||||||
@ -965,6 +1030,12 @@ for(;;){
|
|||||||
while(isspace(*sb))sb++;
|
while(isspace(*sb))sb++;
|
||||||
if(!strncasecmp((char *)sb, "chunked", 7)){
|
if(!strncasecmp((char *)sb, "chunked", 7)){
|
||||||
param->chunked = 1;
|
param->chunked = 1;
|
||||||
|
if(clhdrofs >= 0){
|
||||||
|
buf[clhdrofs] = 'X';
|
||||||
|
clhdrofs = -1;
|
||||||
|
contentlength64 = 0;
|
||||||
|
hascontent = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inbuf += i;
|
inbuf += i;
|
||||||
@ -1009,7 +1080,7 @@ for(;;){
|
|||||||
if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) {
|
if (conf.filtermaxsize && contentlength64 > (uint64_t)conf.filtermaxsize) {
|
||||||
param->nolongdatfilter = 1;
|
param->nolongdatfilter = 1;
|
||||||
}
|
}
|
||||||
else if(param->ndatfilterssrv > 0 && contentlength64 > 0 && param->operation != HTTP_HEAD && res != 204 && res != 304){
|
else if(param->ndatfilterssrv > 0 && contentlength64 > 0 && contentlength64 == (uint64_t)(unsigned long)contentlength64 && param->operation != HTTP_HEAD && res != 204 && res != 304){
|
||||||
uint64_t newlen;
|
uint64_t newlen;
|
||||||
newlen = (uint64_t)sockfillbuffsrv(param, (unsigned long) contentlength64, CONNECTION_S);
|
newlen = (uint64_t)sockfillbuffsrv(param, (unsigned long) contentlength64, CONNECTION_S);
|
||||||
if(newlen == contentlength64) {
|
if(newlen == contentlength64) {
|
||||||
|
|||||||
@ -188,6 +188,8 @@ unsigned long sockfillbuffcli(struct clientparam * param, unsigned long size, in
|
|||||||
unsigned long sockfillbuffsrv(struct clientparam * param, unsigned long size, int timeosec);
|
unsigned long sockfillbuffsrv(struct clientparam * param, unsigned long size, int timeosec);
|
||||||
|
|
||||||
int sockgetlinebuf(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to);
|
int sockgetlinebuf(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, int delim, int to);
|
||||||
|
int getmultiline(struct clientparam * param, DIRECTION which, unsigned char * buf, int bufsize, const char *cap, int *found);
|
||||||
|
int hascap(const unsigned char *line, const char *cap);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -240,9 +242,7 @@ extern int paused;
|
|||||||
extern int demon;
|
extern int demon;
|
||||||
|
|
||||||
unsigned char * mycrypt(const unsigned char *key, const unsigned char *salt, unsigned char *buf);
|
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);
|
unsigned char * ntpwdhash (unsigned char *szHash, const unsigned char *szPassword, int tohex);
|
||||||
#endif
|
|
||||||
int de64 (const unsigned char *in, unsigned char *out, int maxlen);
|
int de64 (const unsigned char *in, unsigned char *out, int maxlen);
|
||||||
unsigned char* en64 (const unsigned char *in, unsigned char *out, int inlen);
|
unsigned char* en64 (const unsigned char *in, unsigned char *out, int inlen);
|
||||||
void tohex(unsigned char *in, unsigned char *out, int len);
|
void tohex(unsigned char *in, unsigned char *out, int len);
|
||||||
@ -314,6 +314,7 @@ void srvinit2(struct srvparam * srv, struct clientparam *param);
|
|||||||
void srvfree(struct srvparam * srv);
|
void srvfree(struct srvparam * srv);
|
||||||
unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
|
unsigned char * dologname (unsigned char *buf, unsigned char *name, const unsigned char *ext, ROTATION lt, time_t t);
|
||||||
int readconfig(FILE * fp);
|
int readconfig(FILE * fp);
|
||||||
|
void initcommands(void);
|
||||||
int connectwithpoll(struct clientparam *param, SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to);
|
int connectwithpoll(struct clientparam *param, SOCKET sock, struct sockaddr *sa, SASIZETYPE size, int to);
|
||||||
|
|
||||||
|
|
||||||
@ -327,6 +328,7 @@ extern char *copyright;
|
|||||||
|
|
||||||
void * dnsprchild(struct clientparam * param);
|
void * dnsprchild(struct clientparam * param);
|
||||||
void * pop3pchild(struct clientparam * param);
|
void * pop3pchild(struct clientparam * param);
|
||||||
|
void * imappchild(struct clientparam * param);
|
||||||
void * smtppchild(struct clientparam * param);
|
void * smtppchild(struct clientparam * param);
|
||||||
void * proxychild(struct clientparam * param);
|
void * proxychild(struct clientparam * param);
|
||||||
void * sockschild(struct clientparam * param);
|
void * sockschild(struct clientparam * param);
|
||||||
|
|||||||
@ -528,6 +528,27 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
srv.needuser = 0;
|
srv.needuser = 0;
|
||||||
if(*(argv[i] + 2)) srv.needuser = atoi(argv[i] + 2);
|
if(*(argv[i] + 2)) srv.needuser = atoi(argv[i] + 2);
|
||||||
break;
|
break;
|
||||||
|
case 'x':
|
||||||
|
srv.nostarttls = 1;
|
||||||
|
break;
|
||||||
|
case 'X':
|
||||||
|
if(!strncasecmp(argv[i]+2, "imap", 4)) srv.srvstarttls = S_IMAPP;
|
||||||
|
else if(!strncasecmp(argv[i]+2, "pop3", 4)) srv.srvstarttls = S_POP3P;
|
||||||
|
else if(!strncasecmp(argv[i]+2, "smtp", 4)) srv.srvstarttls = S_SMTPP;
|
||||||
|
else error = 1;
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
|
{
|
||||||
|
PROXYSOCKADDRTYPE fsa;
|
||||||
|
memset(&fsa, 0, sizeof(fsa));
|
||||||
|
if(!getip46(46, (unsigned char *)argv[i]+2, (struct sockaddr *)&fsa)) error = 1;
|
||||||
|
else if(*SAFAMILY(&fsa) == AF_INET) srv.fakeip = *(uint32_t *)SAADDR(&fsa);
|
||||||
|
#ifndef NOIPV6
|
||||||
|
else if(*SAFAMILY(&fsa) == AF_INET6) memcpy(srv.fakeip6, SAADDR(&fsa), 16);
|
||||||
|
#endif
|
||||||
|
else error = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'T':
|
case 'T':
|
||||||
srv.transparent = 1;
|
srv.transparent = 1;
|
||||||
break;
|
break;
|
||||||
@ -772,6 +793,9 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
return -12;
|
return -12;
|
||||||
}
|
}
|
||||||
#ifndef NOIPV6
|
#ifndef NOIPV6
|
||||||
|
#ifndef IPV6_BOUND_IF
|
||||||
|
#define IPV6_BOUND_IF 125
|
||||||
|
#endif
|
||||||
if((*SAFAMILY(&srv.intsa) == AF_INET6 && srv.so._setsockopt(srv.so.state, sock, IPPROTO_IPV6, IPV6_BOUND_IF, &idx, sizeof(idx)))) {
|
if((*SAFAMILY(&srv.intsa) == AF_INET6 && srv.so._setsockopt(srv.so.state, sock, IPPROTO_IPV6, IPV6_BOUND_IF, &idx, sizeof(idx)))) {
|
||||||
dolog(&defparam, (unsigned char *)"failed to bind device");
|
dolog(&defparam, (unsigned char *)"failed to bind device");
|
||||||
return -12;
|
return -12;
|
||||||
|
|||||||
@ -47,6 +47,7 @@ int clientnegotiate(struct chain * redir, struct clientparam * param, struct soc
|
|||||||
switch(redir->type){
|
switch(redir->type){
|
||||||
case R_TCP:
|
case R_TCP:
|
||||||
case R_HTTP:
|
case R_HTTP:
|
||||||
|
case R_IMAP:
|
||||||
return 0;
|
return 0;
|
||||||
case R_CONNECT:
|
case R_CONNECT:
|
||||||
case R_CONNECTP:
|
case R_CONNECTP:
|
||||||
@ -374,7 +375,7 @@ int handleredirect(struct clientparam * param, struct ace * acentry){
|
|||||||
ntohs(*SAPORT(¶m->sincl))
|
ntohs(*SAPORT(¶m->sincl))
|
||||||
);
|
);
|
||||||
if(socksend(param, param->remsock, (unsigned char *)buf, len, conf.timeouts[CHAIN_TO])!=len) return 39;
|
if(socksend(param, param->remsock, (unsigned char *)buf, len, conf.timeouts[CHAIN_TO])!=len) return 39;
|
||||||
return 0;
|
if(cur->type == R_HA) return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
40
src/smtpp.c
40
src/smtpp.c
@ -10,11 +10,23 @@
|
|||||||
|
|
||||||
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
#define RETURN(xxx) { param->res = xxx; goto CLEANRET; }
|
||||||
|
|
||||||
|
#ifdef WITHMAIN
|
||||||
|
#define NOSTARTTLS 1
|
||||||
|
#else
|
||||||
|
#define NOSTARTTLS param->srv->nostarttls
|
||||||
|
#endif
|
||||||
|
|
||||||
char ehlo[] = "250-Proxy\r\n"
|
char ehlo[] = "250-Proxy\r\n"
|
||||||
"250-AUTH PLAIN LOGIN\r\n"
|
"250-AUTH PLAIN LOGIN\r\n"
|
||||||
"250-8BITMIME\r\n"
|
"250-8BITMIME\r\n"
|
||||||
"250 DSN\r\n";
|
"250 DSN\r\n";
|
||||||
|
|
||||||
|
char ehlotls[] = "250-Proxy\r\n"
|
||||||
|
"250-AUTH PLAIN LOGIN\r\n"
|
||||||
|
"250-8BITMIME\r\n"
|
||||||
|
"250-STARTTLS\r\n"
|
||||||
|
"250 DSN\r\n";
|
||||||
|
|
||||||
int readreply (struct clientparam* param) {
|
int readreply (struct clientparam* param) {
|
||||||
unsigned char * buf;
|
unsigned char * buf;
|
||||||
int res, i, bufsize = 640;
|
int res, i, bufsize = 640;
|
||||||
@ -112,8 +124,17 @@ void * smtppchild(struct clientparam* param) {
|
|||||||
socksend(param, param->clisock, (unsigned char *)"250 Proxy\r\n", 11,conf.timeouts[STRING_S]);
|
socksend(param, param->clisock, (unsigned char *)"250 Proxy\r\n", 11,conf.timeouts[STRING_S]);
|
||||||
}
|
}
|
||||||
else if(!strncasecmp((char *)buf, "EHLO ", 5)){
|
else if(!strncasecmp((char *)buf, "EHLO ", 5)){
|
||||||
socksend(param, param->clisock, (unsigned char *)ehlo, sizeof(ehlo) - 1,conf.timeouts[STRING_S]);
|
if(!NOSTARTTLS) socksend(param, param->clisock, (unsigned char *)ehlotls, sizeof(ehlotls) - 1,conf.timeouts[STRING_S]);
|
||||||
|
else socksend(param, param->clisock, (unsigned char *)ehlo, sizeof(ehlo) - 1,conf.timeouts[STRING_S]);
|
||||||
}
|
}
|
||||||
|
#ifndef WITHMAIN
|
||||||
|
else if(!strncasecmp((char *)buf, "STARTTLS", 8) && !param->srv->nostarttls){
|
||||||
|
if(socksend(param, param->clisock, (unsigned char *)"220 2.0.0 Ready to start TLS\r\n", 30, conf.timeouts[STRING_S])!=30) {RETURN(673);}
|
||||||
|
param->clientstarttls = S_SMTPP;
|
||||||
|
if(!param->srv->targetport) param->srv->targetport = htons(587);
|
||||||
|
return tlsprchild(param);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if(!param->hostname) socksend(param, param->clisock, (unsigned char *)"571 need AUTH first\r\n", 22, conf.timeouts[STRING_S]);
|
else if(!param->hostname) socksend(param, param->clisock, (unsigned char *)"571 need AUTH first\r\n", 22, conf.timeouts[STRING_S]);
|
||||||
else {
|
else {
|
||||||
login = -1;
|
login = -1;
|
||||||
@ -132,7 +153,7 @@ void * smtppchild(struct clientparam* param) {
|
|||||||
i = de64(buf,username,255);
|
i = de64(buf,username,255);
|
||||||
if(i < 1) {RETURN(664);}
|
if(i < 1) {RETURN(664);}
|
||||||
username[i] = 0;
|
username[i] = 0;
|
||||||
parseconnusername((char *)username, param, 0, 25);
|
parseconnusername((char *)username, param, 0, 587);
|
||||||
socksend(param, param->clisock, (unsigned char *)"334 UGFzc3dvcmQ6\r\n", 18,conf.timeouts[STRING_S]);
|
socksend(param, param->clisock, (unsigned char *)"334 UGFzc3dvcmQ6\r\n", 18,conf.timeouts[STRING_S]);
|
||||||
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
if(i < 2) {RETURN(665);}
|
if(i < 2) {RETURN(665);}
|
||||||
@ -157,7 +178,7 @@ void * smtppchild(struct clientparam* param) {
|
|||||||
}
|
}
|
||||||
if(i < 3 || *username) {RETURN(668);}
|
if(i < 3 || *username) {RETURN(668);}
|
||||||
username[i] = 0;
|
username[i] = 0;
|
||||||
parseconnusername((char *)username+1, param, 0, 25);
|
parseconnusername((char *)username+1, param, 0, 587);
|
||||||
res = (int)strlen((char *)username+1) + 2;
|
res = (int)strlen((char *)username+1) + 2;
|
||||||
if(res < i){
|
if(res < i){
|
||||||
if(param->extpassword) free(param->extpassword);
|
if(param->extpassword) free(param->extpassword);
|
||||||
@ -180,9 +201,7 @@ void * smtppchild(struct clientparam* param) {
|
|||||||
param->operation = CONNECT;
|
param->operation = CONNECT;
|
||||||
res = (*param->srv->authfunc)(param);
|
res = (*param->srv->authfunc)(param);
|
||||||
if(res) {RETURN(res);}
|
if(res) {RETURN(res);}
|
||||||
do {
|
i = getmultiline(param, SERVER, buf, sizeof(buf) - 1, NULL, NULL);
|
||||||
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
|
|
||||||
} while (i > 3 && buf[3] == '-');
|
|
||||||
if( i < 3 ) {RETURN(671);}
|
if( i < 3 ) {RETURN(671);}
|
||||||
buf[i] = 0;
|
buf[i] = 0;
|
||||||
if(strncasecmp((char *)buf, "220", 3)||!strncasecmp((char *)buf+4, "PROXY", 5)){RETURN(672);}
|
if(strncasecmp((char *)buf, "220", 3)||!strncasecmp((char *)buf+4, "PROXY", 5)){RETURN(672);}
|
||||||
@ -233,9 +252,10 @@ void * smtppchild(struct clientparam* param) {
|
|||||||
if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(682);}
|
if(i<4 || strncasecmp((char *)buf, "334", 3)) {RETURN(682);}
|
||||||
*username = 0;
|
*username = 0;
|
||||||
i = (int)strlen((char *)param->extusername) + 1;
|
i = (int)strlen((char *)param->extusername) + 1;
|
||||||
|
res = (int)strlen((char *)param->extpassword);
|
||||||
|
if(i + 1 + res >= (int)sizeof(username) || ((i + 1 + res + 2) / 3) * 4 + 1 > (int)sizeof(buf)) {RETURN(683);}
|
||||||
memcpy(username+1, param->extusername, i);
|
memcpy(username+1, param->extusername, i);
|
||||||
i++;
|
i++;
|
||||||
res = (int)strlen((char *)param->extpassword);
|
|
||||||
memcpy(username + i, param->extpassword, res);
|
memcpy(username + i, param->extpassword, res);
|
||||||
i+=res;
|
i+=res;
|
||||||
en64(username, buf, i);
|
en64(username, buf, i);
|
||||||
@ -291,7 +311,7 @@ void * smtppchild(struct clientparam* param) {
|
|||||||
CLEANRET:
|
CLEANRET:
|
||||||
|
|
||||||
if(param->hostname&¶m->extusername) {
|
if(param->hostname&¶m->extusername) {
|
||||||
sprintf((char *)buf, "%.128s@%.128s%c%hu", param->extusername, param->hostname, *SAPORT(¶m->sinsr)==25?0:':',ntohs(*SAPORT(¶m->sinsr)));
|
sprintf((char *)buf, "%.128s@%.128s%c%hu", param->extusername, param->hostname, *SAPORT(¶m->sinsr)==587?0:':',ntohs(*SAPORT(¶m->sinsr)));
|
||||||
dolog(param, buf);
|
dolog(param, buf);
|
||||||
}
|
}
|
||||||
else dolog(param, NULL);
|
else dolog(param, NULL);
|
||||||
@ -306,10 +326,10 @@ CLEANRET:
|
|||||||
#ifdef WITHMAIN
|
#ifdef WITHMAIN
|
||||||
struct proxydef childdef = {
|
struct proxydef childdef = {
|
||||||
smtppchild,
|
smtppchild,
|
||||||
25,
|
587,
|
||||||
0,
|
0,
|
||||||
S_SMTPP,
|
S_SMTPP,
|
||||||
" -hdefault_host[:port] - use this host and port as default if no host specified\n"
|
" -hdefault_host[:port] - use this host and port as default if no host specified\n -x - disable STARTTLS\n"
|
||||||
|
|
||||||
};
|
};
|
||||||
#include "proxymain.c"
|
#include "proxymain.c"
|
||||||
|
|||||||
29
src/ssl.c
29
src/ssl.c
@ -6,11 +6,20 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "structures.h"
|
#include "structures.h"
|
||||||
|
#ifdef WITH_WOLFSSL
|
||||||
|
#include <wolfssl/options.h>
|
||||||
|
#include <wolfssl/openssl/crypto.h>
|
||||||
|
#include <wolfssl/openssl/x509.h>
|
||||||
|
#include <wolfssl/openssl/pem.h>
|
||||||
|
#include <wolfssl/openssl/ssl.h>
|
||||||
|
#include <wolfssl/openssl/err.h>
|
||||||
|
#else
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
|
#endif
|
||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
#include "ssl.h"
|
#include "ssl.h"
|
||||||
|
|
||||||
@ -487,7 +496,7 @@ SSL_CTX * ssl_cli_ctx(SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_ke
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
#if !defined(WITH_WOLFSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
ctx = SSL_CTX_new(SSLv23_server_method());
|
ctx = SSL_CTX_new(SSLv23_server_method());
|
||||||
#else
|
#else
|
||||||
ctx = SSL_CTX_new(TLS_server_method());
|
ctx = SSL_CTX_new(TLS_server_method());
|
||||||
@ -517,14 +526,17 @@ SSL_CTX * ssl_cli_ctx(SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_ke
|
|||||||
if(config->server_min_proto_version)SSL_CTX_set_min_proto_version(ctx, config->server_min_proto_version);
|
if(config->server_min_proto_version)SSL_CTX_set_min_proto_version(ctx, config->server_min_proto_version);
|
||||||
if(config->server_max_proto_version)SSL_CTX_set_max_proto_version(ctx, config->server_max_proto_version);
|
if(config->server_max_proto_version)SSL_CTX_set_max_proto_version(ctx, config->server_max_proto_version);
|
||||||
if(config->server_cipher_list)SSL_CTX_set_cipher_list(ctx, config->server_cipher_list);
|
if(config->server_cipher_list)SSL_CTX_set_cipher_list(ctx, config->server_cipher_list);
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
|
#if !defined(WITH_WOLFSSL) && OPENSSL_VERSION_NUMBER >= 0x10101000L
|
||||||
if(config->server_ciphersuites)SSL_CTX_set_ciphersuites(ctx, config->server_ciphersuites);
|
if(config->server_ciphersuites)SSL_CTX_set_ciphersuites(ctx, config->server_ciphersuites);
|
||||||
|
#elif defined(WITH_WOLFSSL)
|
||||||
|
/* wolfSSL has no separate TLS1.3 ciphersuites API; route to cipher list. */
|
||||||
|
if(config->server_ciphersuites)wolfSSL_CTX_set_cipher_list(ctx, config->server_ciphersuites);
|
||||||
#endif
|
#endif
|
||||||
if(config->server_verify){
|
if(config->server_verify){
|
||||||
if(config->server_ca_file || config->server_ca_dir){
|
if(config->server_ca_file || config->server_ca_dir){
|
||||||
SSL_CTX_load_verify_locations(ctx, config->server_ca_file, config->server_ca_dir);
|
SSL_CTX_load_verify_locations(ctx, config->server_ca_file, config->server_ca_dir);
|
||||||
}
|
}
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
#if !defined(WITH_WOLFSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
else if(config->server_ca_store){
|
else if(config->server_ca_store){
|
||||||
SSL_CTX_load_verify_store(ctx, config->server_ca_store);
|
SSL_CTX_load_verify_store(ctx, config->server_ca_store);
|
||||||
}
|
}
|
||||||
@ -655,7 +667,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
|
|||||||
srv->so._poll = ssl_poll;
|
srv->so._poll = ssl_poll;
|
||||||
}
|
}
|
||||||
if(sc && (sc->mitm || sc->cli)){
|
if(sc && (sc->mitm || sc->cli)){
|
||||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
#if !defined(WITH_WOLFSSL) && OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
sc->srv_ctx = SSL_CTX_new(SSLv23_client_method());
|
sc->srv_ctx = SSL_CTX_new(SSLv23_client_method());
|
||||||
#else
|
#else
|
||||||
sc->srv_ctx = SSL_CTX_new(TLS_client_method());
|
sc->srv_ctx = SSL_CTX_new(TLS_client_method());
|
||||||
@ -671,17 +683,20 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
|
|||||||
if(sc->client_min_proto_version)SSL_CTX_set_min_proto_version(sc->srv_ctx, sc->client_min_proto_version);
|
if(sc->client_min_proto_version)SSL_CTX_set_min_proto_version(sc->srv_ctx, sc->client_min_proto_version);
|
||||||
if(sc->client_max_proto_version)SSL_CTX_set_max_proto_version(sc->srv_ctx, sc->client_max_proto_version);
|
if(sc->client_max_proto_version)SSL_CTX_set_max_proto_version(sc->srv_ctx, sc->client_max_proto_version);
|
||||||
if(sc->client_cipher_list)SSL_CTX_set_cipher_list(sc->srv_ctx, sc->client_cipher_list);
|
if(sc->client_cipher_list)SSL_CTX_set_cipher_list(sc->srv_ctx, sc->client_cipher_list);
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10101000L
|
#if !defined(WITH_WOLFSSL) && OPENSSL_VERSION_NUMBER >= 0x10101000L
|
||||||
if(sc->client_ciphersuites)SSL_CTX_set_ciphersuites(sc->srv_ctx, sc->client_ciphersuites);
|
if(sc->client_ciphersuites)SSL_CTX_set_ciphersuites(sc->srv_ctx, sc->client_ciphersuites);
|
||||||
|
#elif defined(WITH_WOLFSSL)
|
||||||
|
/* wolfSSL has no separate TLS1.3 ciphersuites API; route to cipher list. */
|
||||||
|
if(sc->client_ciphersuites)wolfSSL_CTX_set_cipher_list(sc->srv_ctx, sc->client_ciphersuites);
|
||||||
#endif
|
#endif
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10200000L
|
#if (defined(WITH_WOLFSSL) && defined(HAVE_ALPN) && LIBWOLFSSL_VERSION_HEX >= 0x03007000) || (!defined(WITH_WOLFSSL) && OPENSSL_VERSION_NUMBER >= 0x10200000L)
|
||||||
if(sc->client_alpn_protos.protos_len)SSL_CTX_set_alpn_protos(sc->srv_ctx, sc->client_alpn_protos.protos, sc->client_alpn_protos.protos_len);
|
if(sc->client_alpn_protos.protos_len)SSL_CTX_set_alpn_protos(sc->srv_ctx, sc->client_alpn_protos.protos, sc->client_alpn_protos.protos_len);
|
||||||
#endif
|
#endif
|
||||||
if(sc->client_verify){
|
if(sc->client_verify){
|
||||||
if(sc->client_ca_file || sc->client_ca_dir){
|
if(sc->client_ca_file || sc->client_ca_dir){
|
||||||
SSL_CTX_load_verify_locations(sc->srv_ctx, sc->client_ca_file, sc->client_ca_dir);
|
SSL_CTX_load_verify_locations(sc->srv_ctx, sc->client_ca_file, sc->client_ca_dir);
|
||||||
}
|
}
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
#if !defined(WITH_WOLFSSL) && OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||||
else if(sc->client_ca_store){
|
else if(sc->client_ca_store){
|
||||||
SSL_CTX_load_verify_store(sc->srv_ctx, sc->client_ca_store);
|
SSL_CTX_load_verify_store(sc->srv_ctx, sc->client_ca_store);
|
||||||
}
|
}
|
||||||
|
|||||||
41
src/ssllib.c
41
src/ssllib.c
@ -14,14 +14,21 @@
|
|||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef WITH_WOLFSSL
|
||||||
|
#include <wolfssl/options.h>
|
||||||
|
#include <wolfssl/openssl/crypto.h>
|
||||||
|
#include <wolfssl/openssl/x509.h>
|
||||||
|
#include <wolfssl/openssl/x509v3.h>
|
||||||
|
#include <wolfssl/openssl/pem.h>
|
||||||
|
#include <wolfssl/openssl/ssl.h>
|
||||||
|
#include <wolfssl/openssl/err.h>
|
||||||
|
#else
|
||||||
#include <openssl/crypto.h>
|
#include <openssl/crypto.h>
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/x509v3.h>
|
#include <openssl/x509v3.h>
|
||||||
#include <openssl/pem.h>
|
#include <openssl/pem.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
#include <openssl/provider.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "proxy.h"
|
#include "proxy.h"
|
||||||
@ -106,21 +113,19 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config)
|
|||||||
X509 *dst_cert = NULL;
|
X509 *dst_cert = NULL;
|
||||||
|
|
||||||
EVP_PKEY *pk = NULL;
|
EVP_PKEY *pk = NULL;
|
||||||
RSA *rsa = NULL;
|
|
||||||
|
|
||||||
int hash_size = 20;
|
unsigned char hash_sha256[32];
|
||||||
unsigned char hash_sha1[20];
|
char hash_name_sha256[(16*2) + 1];
|
||||||
char hash_name_sha1[(20*2) + 1];
|
|
||||||
char cache_name[256];
|
char cache_name[256];
|
||||||
|
|
||||||
err = X509_digest(src_cert, EVP_sha1(), hash_sha1, NULL);
|
err = X509_digest(src_cert, EVP_sha256(), hash_sha256, NULL);
|
||||||
if(!err){
|
if(!err){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(config->certcache){
|
if(config->certcache){
|
||||||
bin2hex(hash_sha1, 20, hash_name_sha1, sizeof(hash_name_sha1));
|
bin2hex(hash_sha256, 16, hash_name_sha256, sizeof(hash_name_sha256));
|
||||||
sprintf(cache_name, "%s%s.pem", config->certcache, hash_name_sha1);
|
sprintf(cache_name, "%s%s.pem", config->certcache, hash_name_sha256);
|
||||||
/* check if certificate is already cached */
|
/* check if certificate is already cached */
|
||||||
fcache = BIO_new_file(cache_name, "rb");
|
fcache = BIO_new_file(cache_name, "rb");
|
||||||
if ( fcache != NULL ) {
|
if ( fcache != NULL ) {
|
||||||
@ -280,12 +285,6 @@ int ssl_file_init = 0;
|
|||||||
|
|
||||||
int ssl_init_done = 0;
|
int ssl_init_done = 0;
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
extern EVP_MD *md4_hash;
|
|
||||||
extern EVP_MD *md5_hash;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
void ssl_init()
|
void ssl_init()
|
||||||
{
|
{
|
||||||
if(!ssl_init_done){
|
if(!ssl_init_done){
|
||||||
@ -296,17 +295,5 @@ void ssl_init()
|
|||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
_3proxy_mutex_init(&ssl_file_mutex);
|
_3proxy_mutex_init(&ssl_file_mutex);
|
||||||
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
|
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
|
||||||
OSSL_PROVIDER_load(NULL, "legacy");
|
|
||||||
OSSL_PROVIDER_load(NULL, "default");
|
|
||||||
md4_hash = EVP_MD_fetch(NULL, "MD4", NULL);
|
|
||||||
if (md4_hash == NULL) {
|
|
||||||
fprintf(stderr, "Error fetching MD4\n");
|
|
||||||
}
|
|
||||||
md5_hash = EVP_MD_fetch(NULL, "MD5", NULL);
|
|
||||||
if (md5_hash == NULL) {
|
|
||||||
fprintf(stderr, "Error fetching MD5\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,8 +30,8 @@ unsigned char * strings[] = {
|
|||||||
/* 17 */ (unsigned char *)"SMTPP",
|
/* 17 */ (unsigned char *)"SMTPP",
|
||||||
/* 18 */ (unsigned char *)"AUTO",
|
/* 18 */ (unsigned char *)"AUTO",
|
||||||
/* 19 */ (unsigned char *)"TLSPR",
|
/* 19 */ (unsigned char *)"TLSPR",
|
||||||
/* 20 */ (unsigned char *)"ZOMBIE",
|
/* 20 */ (unsigned char *)"IMAPP",
|
||||||
/* 21 */ NULL,
|
/* 21 */ (unsigned char *)"ZOMBIE",
|
||||||
/* 22 */ NULL,
|
/* 22 */ NULL,
|
||||||
/* 23 */ NULL,
|
/* 23 */ NULL,
|
||||||
/* 24 */ NULL,
|
/* 24 */ NULL,
|
||||||
|
|||||||
@ -208,6 +208,7 @@ typedef enum {
|
|||||||
S_SMTPP,
|
S_SMTPP,
|
||||||
S_AUTO,
|
S_AUTO,
|
||||||
S_TLSPR,
|
S_TLSPR,
|
||||||
|
S_IMAPP,
|
||||||
S_ZOMBIE
|
S_ZOMBIE
|
||||||
}PROXYSERVICE;
|
}PROXYSERVICE;
|
||||||
|
|
||||||
@ -304,7 +305,8 @@ typedef enum {
|
|||||||
R_EXTIP,
|
R_EXTIP,
|
||||||
R_TLS,
|
R_TLS,
|
||||||
R_HA,
|
R_HA,
|
||||||
R_DNS
|
R_DNS,
|
||||||
|
R_IMAP
|
||||||
} REDIRTYPE;
|
} REDIRTYPE;
|
||||||
|
|
||||||
struct redirdesc {
|
struct redirdesc {
|
||||||
@ -535,6 +537,10 @@ struct srvparam {
|
|||||||
int gracetraf, gracenum, gracedelay;
|
int gracetraf, gracenum, gracedelay;
|
||||||
int requirecert;
|
int requirecert;
|
||||||
int haproxy;
|
int haproxy;
|
||||||
|
int nostarttls;
|
||||||
|
PROXYSERVICE srvstarttls;
|
||||||
|
uint32_t fakeip;
|
||||||
|
unsigned char fakeip6[16];
|
||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
int usesplice;
|
int usesplice;
|
||||||
#endif
|
#endif
|
||||||
@ -594,6 +600,8 @@ struct clientparam {
|
|||||||
|
|
||||||
PROXYSERVICE service;
|
PROXYSERVICE service;
|
||||||
|
|
||||||
|
PROXYSERVICE clientstarttls;
|
||||||
|
|
||||||
SOCKET clisock,
|
SOCKET clisock,
|
||||||
remsock,
|
remsock,
|
||||||
ctrlsock,
|
ctrlsock,
|
||||||
|
|||||||
189
src/tlspr.c
189
src/tlspr.c
@ -37,6 +37,176 @@ int readtls(struct clientparam *param, int direction, unsigned char *buf, int bu
|
|||||||
#define SNILEN (256)
|
#define SNILEN (256)
|
||||||
#define PROTOLEN (32)
|
#define PROTOLEN (32)
|
||||||
|
|
||||||
|
int srvstarttls(struct clientparam *param, PROXYSERVICE proto){
|
||||||
|
unsigned char buf[1024];
|
||||||
|
int i, found = 0;
|
||||||
|
|
||||||
|
switch(proto){
|
||||||
|
case S_IMAPP:
|
||||||
|
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 4) return 1;
|
||||||
|
buf[i] = 0;
|
||||||
|
if(strncasecmp((char *)buf, "* OK", 4)) return 1;
|
||||||
|
found = hascap(buf, "STARTTLS");
|
||||||
|
if(!found){
|
||||||
|
if(socksend(param, param->remsock, (unsigned char *)"zz CAPABILITY\r\n", 15, conf.timeouts[STRING_S])!=15) return 2;
|
||||||
|
for(;;){
|
||||||
|
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 3) return 2;
|
||||||
|
buf[i] = 0;
|
||||||
|
if(!strncasecmp((char *)buf, "* CAPABILITY", 12) && hascap(buf, "STARTTLS")) found = 1;
|
||||||
|
if(!strncasecmp((char *)buf, "zz ", 3)) break;
|
||||||
|
}
|
||||||
|
if(!found) return 3;
|
||||||
|
}
|
||||||
|
if(socksend(param, param->remsock, (unsigned char *)"zz STARTTLS\r\n", 13, conf.timeouts[STRING_S])!=13) return 2;
|
||||||
|
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 5) return 2;
|
||||||
|
buf[i] = 0;
|
||||||
|
if(strncasecmp((char *)buf, "zz OK", 5)) return 3;
|
||||||
|
break;
|
||||||
|
case S_POP3P:
|
||||||
|
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 3) return 1;
|
||||||
|
buf[i] = 0;
|
||||||
|
if(strncasecmp((char *)buf, "+OK", 3)) return 1;
|
||||||
|
if(socksend(param, param->remsock, (unsigned char *)"CAPA\r\n", 6, conf.timeouts[STRING_S])!=6) return 2;
|
||||||
|
for(;;){
|
||||||
|
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 1) return 2;
|
||||||
|
buf[i] = 0;
|
||||||
|
if(buf[0] == '.') break;
|
||||||
|
if(!strncasecmp((char *)buf, "-ERR", 4)) return 2;
|
||||||
|
if(hascap(buf, "STLS")) found = 1;
|
||||||
|
}
|
||||||
|
if(!found) return 3;
|
||||||
|
if(socksend(param, param->remsock, (unsigned char *)"STLS\r\n", 6, conf.timeouts[STRING_S])!=6) return 2;
|
||||||
|
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 3) return 2;
|
||||||
|
buf[i] = 0;
|
||||||
|
if(strncasecmp((char *)buf, "+OK", 3)) return 3;
|
||||||
|
break;
|
||||||
|
case S_SMTPP:
|
||||||
|
i = getmultiline(param, SERVER, buf, sizeof(buf) - 1, NULL, NULL);
|
||||||
|
if(i < 3) return 1;
|
||||||
|
buf[i] = 0;
|
||||||
|
if(strncasecmp((char *)buf, "220", 3)) return 1;
|
||||||
|
i = sprintf((char *)buf, "EHLO [");
|
||||||
|
i += myinet_ntop(*SAFAMILY(¶m->sinsl), SAADDR(¶m->sinsl), (char *)buf+strlen((char *)buf), 64);
|
||||||
|
i += sprintf((char *)buf+strlen((char *)buf), "]\r\n");
|
||||||
|
if(socksend(param, param->remsock, buf, i, conf.timeouts[STRING_S])!= i) return 2;
|
||||||
|
i = getmultiline(param, SERVER, buf, sizeof(buf) - 1, "STARTTLS", &found);
|
||||||
|
if(i < 3) return 2;
|
||||||
|
buf[i] = 0;
|
||||||
|
if(strncasecmp((char *)buf, "250", 3)) return 2;
|
||||||
|
if(!found) return 3;
|
||||||
|
if(socksend(param, param->remsock, (unsigned char *)"STARTTLS\r\n", 10, conf.timeouts[STRING_S])!= 10) return 2;
|
||||||
|
i = sockgetlinebuf(param, SERVER, buf, sizeof(buf) - 1, '\n', conf.timeouts[STRING_L]);
|
||||||
|
if(i < 3) return 2;
|
||||||
|
buf[i] = 0;
|
||||||
|
if(strncasecmp((char *)buf, "220", 3)) return 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t starttlsport(PROXYSERVICE proto){
|
||||||
|
switch(proto){
|
||||||
|
case S_IMAPP: return 143;
|
||||||
|
case S_POP3P: return 110;
|
||||||
|
case S_SMTPP: return 587;
|
||||||
|
default: return 443;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int clistarttls(struct clientparam *param, PROXYSERVICE proto){
|
||||||
|
unsigned char buf[1024];
|
||||||
|
unsigned char tag[64];
|
||||||
|
unsigned char *se, *cmd;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch(proto){
|
||||||
|
case S_IMAPP:
|
||||||
|
i = sprintf((char *)buf, "* OK [CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED] IMAP4rev1 Proxy Ready\r\n");
|
||||||
|
if(socksend(param, param->clisock, buf, i, conf.timeouts[STRING_S])!=i) return 1;
|
||||||
|
for(;;){
|
||||||
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
|
if(i < 4) return 1;
|
||||||
|
buf[i] = 0;
|
||||||
|
if ((se=(unsigned char *)strchr((char *)buf, '\r'))) *se = 0;
|
||||||
|
if (!(se=(unsigned char *)strchr((char *)buf, ' ')) || (se - buf) >= (int)(sizeof(tag) - 1)) return 1;
|
||||||
|
memcpy(tag, buf, se - buf);
|
||||||
|
tag[se - buf] = 0;
|
||||||
|
cmd = se + 1;
|
||||||
|
if(!strncasecmp((char *)cmd, "LOGOUT", 6)){
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"* BYE\r\n", 7, conf.timeouts[STRING_S]);
|
||||||
|
sprintf((char *)buf, "%.60s OK LOGOUT completed\r\n", (char *)tag);
|
||||||
|
socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)cmd, "CAPABILITY", 10)){
|
||||||
|
i = sprintf((char *)buf, "* CAPABILITY IMAP4rev1 STARTTLS LOGINDISABLED\r\n");
|
||||||
|
socksend(param, param->clisock, buf, i, conf.timeouts[STRING_S]);
|
||||||
|
sprintf((char *)buf, "%.60s OK CAPABILITY completed\r\n", (char *)tag);
|
||||||
|
socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)cmd, "STARTTLS", 8)){
|
||||||
|
sprintf((char *)buf, "%.60s OK Begin TLS negotiation\r\n", (char *)tag);
|
||||||
|
if(socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]) <= 0) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sprintf((char *)buf, "%.60s BAD need STARTTLS first\r\n", (char *)tag);
|
||||||
|
socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]);
|
||||||
|
}
|
||||||
|
case S_POP3P:
|
||||||
|
if(socksend(param, param->clisock, (unsigned char *)"+OK Proxy\r\n", 11, conf.timeouts[STRING_S])!=11) return 1;
|
||||||
|
for(;;){
|
||||||
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
|
if(i < 4) return 1;
|
||||||
|
if(!strncasecmp((char *)buf, "STLS", 4)){
|
||||||
|
if(socksend(param, param->clisock, (unsigned char *)"+OK Begin TLS negotiation\r\n", 27, conf.timeouts[STRING_S])!=27) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)buf, "CAPA", 4)){
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"+OK Capability list follows\r\nSTLS\r\n.\r\n", 38, conf.timeouts[STRING_S]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)buf, "QUIT", 4)){
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"+OK\r\n", 5, conf.timeouts[STRING_S]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"-ERR need STLS first\r\n", 22, conf.timeouts[STRING_S]);
|
||||||
|
}
|
||||||
|
case S_SMTPP:
|
||||||
|
if(socksend(param, param->clisock, (unsigned char *)"220 Proxy\r\n", 11, conf.timeouts[STRING_S])!=11) return 1;
|
||||||
|
for(;;){
|
||||||
|
i = sockgetlinebuf(param, CLIENT, buf, sizeof(buf) - 10, '\n', conf.timeouts[STRING_S]);
|
||||||
|
if(i < 4) return 1;
|
||||||
|
if(!strncasecmp((char *)buf, "STARTTLS", 8)){
|
||||||
|
if(socksend(param, param->clisock, (unsigned char *)"220 2.0.0 Ready to start TLS\r\n", 30, conf.timeouts[STRING_S])!=30) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)buf, "EHLO ", 5)){
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"250-Proxy\r\n250 STARTTLS\r\n", 24, conf.timeouts[STRING_S]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)buf, "HELO ", 5)){
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"250 Proxy\r\n", 11, conf.timeouts[STRING_S]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(!strncasecmp((char *)buf, "QUIT", 4)){
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"221 Proxy\r\n", 11, conf.timeouts[STRING_S]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"530 5.7.0 Must issue a STARTTLS command first\r\n", 45, conf.timeouts[STRING_S]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int parsehello(int type, unsigned char *hello, unsigned len, char *sni, int * snipos, int *lv, char * proto){
|
int parsehello(int type, unsigned char *hello, unsigned len, char *sni, int * snipos, int *lv, char * proto){
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
@ -69,7 +239,7 @@ int parsehello(int type, unsigned char *hello, unsigned len, char *sni, int * sn
|
|||||||
elen = size16(hello+offset);
|
elen = size16(hello+offset);
|
||||||
offset += 2;
|
offset += 2;
|
||||||
if(elen+offset != len) return -9;
|
if(elen+offset != len) return -9;
|
||||||
while(elen > 1){
|
while(elen > 3){
|
||||||
unsigned xlen;
|
unsigned xlen;
|
||||||
xlen = size16(hello+offset+2);
|
xlen = size16(hello+offset+2);
|
||||||
if(xlen+4 > elen) return -10;
|
if(xlen+4 > elen) return -10;
|
||||||
@ -176,6 +346,13 @@ void * tlsprchild(struct clientparam* param) {
|
|||||||
int lv=-1;
|
int lv=-1;
|
||||||
char proto[PROTOLEN]="-";
|
char proto[PROTOLEN]="-";
|
||||||
int snipos = 0;
|
int snipos = 0;
|
||||||
|
PROXYSERVICE stlsproto = param->clientstarttls? param->clientstarttls : param->srv->srvstarttls;
|
||||||
|
|
||||||
|
if(!param->clientstarttls && stlsproto){
|
||||||
|
res = clistarttls(param, stlsproto);
|
||||||
|
if(res > 0) RETURN(364);
|
||||||
|
if(res < 0) RETURN(0);
|
||||||
|
}
|
||||||
|
|
||||||
res = tlstobufcli(param);
|
res = tlstobufcli(param);
|
||||||
if(res <= 0 || param->clibuf[0] != 22){
|
if(res <= 0 || param->clibuf[0] != 22){
|
||||||
@ -189,7 +366,7 @@ void * tlsprchild(struct clientparam* param) {
|
|||||||
free(param->hostname);
|
free(param->hostname);
|
||||||
param->hostname = NULL;
|
param->hostname = NULL;
|
||||||
}
|
}
|
||||||
else if (parsehostname(sni, param, param->srv->targetport? ntohs(param->srv->targetport):443)) RETURN (100);
|
else if (parsehostname(sni, param, param->srv->targetport? ntohs(param->srv->targetport):starttlsport(stlsproto))) RETURN (100);
|
||||||
if (!param->hostname)param->hostname = (unsigned char *)strdup(sni);
|
if (!param->hostname)param->hostname = (unsigned char *)strdup(sni);
|
||||||
if(param->srv->s_option && snipos && res > 1){
|
if(param->srv->s_option && snipos && res > 1){
|
||||||
int len;
|
int len;
|
||||||
@ -220,6 +397,14 @@ void * tlsprchild(struct clientparam* param) {
|
|||||||
return (*param->redirectfunc)(param);
|
return (*param->redirectfunc)(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(stlsproto){
|
||||||
|
res = srvstarttls(param, stlsproto);
|
||||||
|
if(res){
|
||||||
|
socksend(param, param->clisock, (unsigned char *)"\x15\x03\x01\x00\x02\x02\x28", 7, conf.timeouts[STRING_S]);
|
||||||
|
RETURN(360+res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(param->srv->requirecert > 1){
|
if(param->srv->requirecert > 1){
|
||||||
res = tlstobufsrv(param);
|
res = tlstobufsrv(param);
|
||||||
if(res <= 0 || param->srvbuf[0] != 22) RETURN(340-res);
|
if(res <= 0 || param->srvbuf[0] != 22) RETURN(340-res);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user