mirror of
https://github.com/3proxy/3proxy.git
synced 2026-08-13 12:19:17 +08:00
Compare commits
3 Commits
3bfabb29f8
...
44c47ee7d9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44c47ee7d9 | ||
|
|
5f1ed7363b | ||
|
|
c370635fc4 |
73
.dockerignore
Normal file
73
.dockerignore
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# Exclude top-level dirs not needed for build
|
||||||
|
/bin/
|
||||||
|
/bin64/
|
||||||
|
/build/
|
||||||
|
/cfg/
|
||||||
|
/cmake/
|
||||||
|
/CMakeFiles/
|
||||||
|
/debian/
|
||||||
|
/doc/
|
||||||
|
/man/
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
**/*.o
|
||||||
|
**/*.obj
|
||||||
|
**/*.so
|
||||||
|
**/*.dll
|
||||||
|
**/*.exe
|
||||||
|
**/*.exp
|
||||||
|
**/*.lib
|
||||||
|
**/*.pdb
|
||||||
|
**/*.ilk
|
||||||
|
**/*.idb
|
||||||
|
**/*.err
|
||||||
|
**/*.ld.so
|
||||||
|
**/*.dSYM
|
||||||
|
**/*.var
|
||||||
|
build*/
|
||||||
|
buildlinux.sh
|
||||||
|
tmp/
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Editor / IDE
|
||||||
|
**/*.swp
|
||||||
|
**/*.swo
|
||||||
|
**/*~
|
||||||
|
**/*.bak
|
||||||
|
**/*.tmp
|
||||||
|
**/*.log
|
||||||
|
.project
|
||||||
|
.cproject
|
||||||
|
.classpath
|
||||||
|
.settings/
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Claude / docs
|
||||||
|
CLAUDE.md
|
||||||
|
.claude/
|
||||||
|
|
||||||
|
# Generated version files
|
||||||
|
version
|
||||||
|
version.c
|
||||||
|
version.sh
|
||||||
|
verfile.sh
|
||||||
|
|
||||||
|
# Local config / keys
|
||||||
|
**/*.key
|
||||||
|
**/*.pem
|
||||||
|
**/*.pfx
|
||||||
|
3proxy.cfg
|
||||||
|
3proxy-ssl.cfg
|
||||||
|
3proxy-pcre.cfg
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
res
|
||||||
|
3proxy.res
|
||||||
|
copytgz.sh
|
||||||
35
.github/workflows/docker-test.yml
vendored
Normal file
35
.github/workflows/docker-test.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
name: Build Docker images (test, no publish)
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build ${{ matrix.file }} (${{ matrix.platform }})
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
file: [Dockerfile.minimal, Dockerfile.busybox, Dockerfile.full]
|
||||||
|
platform: [linux/amd64, linux/arm64]
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v4
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v4
|
||||||
|
|
||||||
|
- name: Build image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ${{ matrix.file }}
|
||||||
|
platforms: ${{ matrix.platform }}
|
||||||
|
push: false
|
||||||
|
load: ${{ matrix.platform == 'linux/amd64' }}
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -271,3 +271,4 @@ bin/3proxy_tcppm
|
|||||||
bin/3proxy_tlspr
|
bin/3proxy_tlspr
|
||||||
bin/3proxy_udppm
|
bin/3proxy_udppm
|
||||||
build*/*
|
build*/*
|
||||||
|
testcerts/
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
# 3proxy.full is fully functional 3proxy build based on busybox:glibc
|
# 3proxy.busybox is fully functional 3proxy build based on busybox:musl
|
||||||
|
# built against wolfSSL and PCRE2.
|
||||||
#
|
#
|
||||||
# Examples are for podman, for docker change 'podman' to 'docker'
|
# Examples are for podman, for docker change 'podman' to 'docker'
|
||||||
#
|
#
|
||||||
@ -19,11 +20,27 @@
|
|||||||
# configuration is supported for compatibility only.
|
# configuration is supported for compatibility only.
|
||||||
|
|
||||||
|
|
||||||
FROM docker.io/gcc AS buildenv
|
FROM docker.io/alpine:latest AS wolfssl
|
||||||
|
RUN apk add --no-cache build-base curl autoconf automake libtool
|
||||||
|
RUN TAG=$(curl -s https://api.github.com/repos/wolfSSL/wolfssl/releases/latest \
|
||||||
|
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p') && \
|
||||||
|
echo "wolfssl tag: $TAG" && \
|
||||||
|
curl -sL https://api.github.com/repos/wolfSSL/wolfssl/tarball/$TAG -o /tmp/w.tar.gz && \
|
||||||
|
mkdir /src && tar -xzf /tmp/w.tar.gz -C /src --strip-components=1 && \
|
||||||
|
cd /src && \
|
||||||
|
autoreconf -i && \
|
||||||
|
./configure --enable-opensslextra --enable-opensslall --enable-certgen \
|
||||||
|
--enable-tls13 --enable-sni --enable-session-ticket \
|
||||||
|
--enable-static --disable-shared --prefix=/usr/local && \
|
||||||
|
make -j$(nproc) && make install
|
||||||
|
|
||||||
|
FROM docker.io/alpine:latest AS buildenv
|
||||||
|
RUN apk add --no-cache gcc make musl-dev pcre2-dev
|
||||||
|
COPY --from=wolfssl /usr/local /usr/local
|
||||||
COPY . 3proxy
|
COPY . 3proxy
|
||||||
RUN cd 3proxy &&\
|
RUN cd 3proxy && mkdir -p bin &&\
|
||||||
apt --assume-yes update && apt --assume-yes install libssl-dev libpcre2-dev &&\
|
make -f Makefile.Linux LIBSTATIC=true PAM_CHECK=false WOLFSSL_CHECK=true \
|
||||||
make -f Makefile.Linux LIBSTATIC=true PAM_CHECK=false &&\
|
EXTRA_LDFLAGS="-L/usr/local/lib" &&\
|
||||||
strip bin/3proxy &&\
|
strip bin/3proxy &&\
|
||||||
strip bin/*so &&\
|
strip bin/*so &&\
|
||||||
mkdir /dist &&\
|
mkdir /dist &&\
|
||||||
@ -42,11 +59,9 @@ RUN cd /dist &&\
|
|||||||
ln -s /lib lib64 &&\
|
ln -s /lib lib64 &&\
|
||||||
ln -s /lib usr/lib &&\
|
ln -s /lib usr/lib &&\
|
||||||
ln -s /lib usr/lib64
|
ln -s /lib usr/lib64
|
||||||
RUN cp /lib/ld-*.so.* /dist/usr/local/3proxy/libexec || true
|
RUN cp /lib/ld-musl-*.so.* /dist/usr/local/3proxy/libexec || true
|
||||||
RUN cp /lib64/ld-*.so.* /dist/usr/local/3proxy/libexec || true
|
|
||||||
RUN cp "/lib/`gcc -dumpmachine`"/libdl.so.* /dist/usr/local/3proxy/libexec
|
|
||||||
|
|
||||||
FROM docker.io/busybox:glibc
|
FROM docker.io/busybox:musl
|
||||||
COPY --from=buildenv /dist /
|
COPY --from=buildenv /dist /
|
||||||
RUN ln -sf /usr/local/3proxy/libexec/* /lib/ && cd /usr/local/3proxy/ && ln -s libexec lib && ln -s libexec lib64 && mkdir usr && ln -s libexec usr/lib && ln -s libexec usr//lib64
|
RUN mkdir -p /lib /lib64 && ln -sf /usr/local/3proxy/libexec/* /lib/ && cd /usr/local/3proxy/ && ln -s libexec lib && ln -s libexec lib64 && mkdir usr && ln -s libexec usr/lib && ln -s libexec usr/lib64
|
||||||
CMD ["/bin/3proxy", "/etc/3proxy/3proxy.cfg"]
|
CMD ["/bin/3proxy", "/etc/3proxy/3proxy.cfg"]
|
||||||
|
|||||||
@ -23,6 +23,7 @@ FROM docker.io/gcc AS buildenv
|
|||||||
COPY . 3proxy
|
COPY . 3proxy
|
||||||
RUN cd 3proxy &&\
|
RUN cd 3proxy &&\
|
||||||
apt --assume-yes update && apt --assume-yes install libssl-dev libpcre2-dev &&\
|
apt --assume-yes update && apt --assume-yes install libssl-dev libpcre2-dev &&\
|
||||||
|
mkdir -p bin &&\
|
||||||
make -f Makefile.Linux LIBSTATIC=true PAM_CHECK=false &&\
|
make -f Makefile.Linux LIBSTATIC=true PAM_CHECK=false &&\
|
||||||
strip bin/3proxy &&\
|
strip bin/3proxy &&\
|
||||||
mkdir /dist &&\
|
mkdir /dist &&\
|
||||||
|
|||||||
@ -3,7 +3,8 @@
|
|||||||
#
|
#
|
||||||
# Examples are for podman. For docker change 'podman' to 'docker'.
|
# Examples are for podman. For docker change 'podman' to 'docker'.
|
||||||
#
|
#
|
||||||
# This is busybox based docker with only 3proxy static executable.
|
# This is a scratch-based docker with statically linked 3proxy executable
|
||||||
|
# built against musl and wolfSSL.
|
||||||
#
|
#
|
||||||
# Limitations for minimal version:
|
# Limitations for minimal version:
|
||||||
# no support for plugins and system resolver.
|
# no support for plugins and system resolver.
|
||||||
@ -25,10 +26,27 @@
|
|||||||
#<end
|
#<end
|
||||||
#
|
#
|
||||||
|
|
||||||
FROM docker.io/gcc AS buildenv
|
FROM docker.io/alpine:latest AS wolfssl
|
||||||
|
RUN apk add --no-cache build-base curl autoconf automake libtool
|
||||||
|
RUN TAG=$(curl -s https://api.github.com/repos/wolfSSL/wolfssl/releases/latest \
|
||||||
|
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p') && \
|
||||||
|
echo "wolfssl tag: $TAG" && \
|
||||||
|
curl -sL https://api.github.com/repos/wolfSSL/wolfssl/tarball/$TAG -o /tmp/w.tar.gz && \
|
||||||
|
mkdir /src && tar -xzf /tmp/w.tar.gz -C /src --strip-components=1 && \
|
||||||
|
cd /src && \
|
||||||
|
autoreconf -i && \
|
||||||
|
./configure --enable-opensslextra --enable-opensslall --enable-certgen \
|
||||||
|
--enable-tls13 --enable-sni --enable-session-ticket \
|
||||||
|
--enable-static --disable-shared --prefix=/usr/local && \
|
||||||
|
make -j$(nproc) && make install
|
||||||
|
|
||||||
|
FROM docker.io/alpine:latest AS buildenv
|
||||||
|
RUN apk add --no-cache gcc make musl-dev
|
||||||
|
COPY --from=wolfssl /usr/local /usr/local
|
||||||
COPY . 3proxy
|
COPY . 3proxy
|
||||||
RUN cd 3proxy &&\
|
RUN cd 3proxy && mkdir -p bin &&\
|
||||||
make -f Makefile.Linux STATIC=true &&\
|
make -f Makefile.Linux STATIC=true WOLFSSL_CHECK=true \
|
||||||
|
EXTRA_LDFLAGS="-L/usr/local/lib" &&\
|
||||||
strip bin/3proxy
|
strip bin/3proxy
|
||||||
|
|
||||||
FROM scratch
|
FROM scratch
|
||||||
|
|||||||
@ -16,6 +16,11 @@ COUT = -o
|
|||||||
LN ?= ${CC}
|
LN ?= ${CC}
|
||||||
LDFLAGS ?= -O3 -flto
|
LDFLAGS ?= -O3 -flto
|
||||||
LDFLAGS += -pthread -fno-strict-aliasing
|
LDFLAGS += -pthread -fno-strict-aliasing
|
||||||
|
# Use EXTRA_CFLAGS/EXTRA_LDFLAGS to add flags from the make command line.
|
||||||
|
# Setting CFLAGS or LDFLAGS there instead overrides every assignment in this
|
||||||
|
# makefile, including the += above and the STATIC/LIBSTATIC handling below.
|
||||||
|
CFLAGS += $(EXTRA_CFLAGS)
|
||||||
|
LDFLAGS += $(EXTRA_LDFLAGS)
|
||||||
# -lpthreads may be reuiured on some platforms instead of -pthreads
|
# -lpthreads may be reuiured on some platforms instead of -pthreads
|
||||||
# -ldl or -lld may be required for some platforms
|
# -ldl or -lld may be required for some platforms
|
||||||
DCFLAGS ?= -fPIC
|
DCFLAGS ?= -fPIC
|
||||||
|
|||||||
@ -16,6 +16,11 @@ LN ?= ${CC}
|
|||||||
DCFLAGS ?= -fPIC
|
DCFLAGS ?= -fPIC
|
||||||
LDFLAGS ?= -O3 -flto
|
LDFLAGS ?= -O3 -flto
|
||||||
LDFLAGS += -fno-strict-aliasing -pthread
|
LDFLAGS += -fno-strict-aliasing -pthread
|
||||||
|
# Use EXTRA_CFLAGS/EXTRA_LDFLAGS to add flags from the make command line.
|
||||||
|
# Setting CFLAGS or LDFLAGS there instead overrides every assignment in this
|
||||||
|
# makefile, including the += above and the STATIC/LIBSTATIC handling below.
|
||||||
|
CFLAGS += $(EXTRA_CFLAGS)
|
||||||
|
LDFLAGS += $(EXTRA_LDFLAGS)
|
||||||
DLFLAGS ?= -shared
|
DLFLAGS ?= -shared
|
||||||
DLSUFFICS = .ld.so
|
DLSUFFICS = .ld.so
|
||||||
# -lpthreads may be reuqired on some platforms instead of -pthreads
|
# -lpthreads may be reuqired on some platforms instead of -pthreads
|
||||||
|
|||||||
@ -18,6 +18,11 @@ COUT = -o
|
|||||||
LN ?= $(CC)
|
LN ?= $(CC)
|
||||||
LDFLAGS ?= -O3 -flto
|
LDFLAGS ?= -O3 -flto
|
||||||
LDFLAGS += -pthread -fno-strict-aliasing
|
LDFLAGS += -pthread -fno-strict-aliasing
|
||||||
|
# Use EXTRA_CFLAGS/EXTRA_LDFLAGS to add flags from the make command line.
|
||||||
|
# Setting CFLAGS or LDFLAGS there instead overrides every assignment in this
|
||||||
|
# makefile, including the += above and the STATIC/LIBSTATIC handling below.
|
||||||
|
CFLAGS += $(EXTRA_CFLAGS)
|
||||||
|
LDFLAGS += $(EXTRA_LDFLAGS)
|
||||||
# -lpthreads may be reuqired on some platforms instead of -pthreads
|
# -lpthreads may be reuqired on some platforms instead of -pthreads
|
||||||
# -ldl or -lld may be required for some platforms
|
# -ldl or -lld may be required for some platforms
|
||||||
DCFLAGS ?= -fPIC
|
DCFLAGS ?= -fPIC
|
||||||
|
|||||||
@ -15,6 +15,11 @@ COUT = -o
|
|||||||
LN ?= $(CC)
|
LN ?= $(CC)
|
||||||
LDFLAGS ?= -O3 -flto
|
LDFLAGS ?= -O3 -flto
|
||||||
LDFLAGS += -fno-strict-aliasing -mthreads
|
LDFLAGS += -fno-strict-aliasing -mthreads
|
||||||
|
# Use EXTRA_CFLAGS/EXTRA_LDFLAGS to add flags from the make command line.
|
||||||
|
# Setting CFLAGS or LDFLAGS there instead overrides every assignment in this
|
||||||
|
# makefile, including the += above and the STATIC/LIBSTATIC handling below.
|
||||||
|
CFLAGS += $(EXTRA_CFLAGS)
|
||||||
|
LDFLAGS += $(EXTRA_LDFLAGS)
|
||||||
DLFLAGS ?= -shared
|
DLFLAGS ?= -shared
|
||||||
DLSUFFICS = .dll
|
DLSUFFICS = .dll
|
||||||
LIBS += -lws2_32 -lodbc32 -ladvapi32 -luser32 -lbcrypt
|
LIBS += -lws2_32 -lodbc32 -ladvapi32 -luser32 -lbcrypt
|
||||||
|
|||||||
@ -1178,6 +1178,19 @@ crash on request processing, try to set some positive value. You may start with
|
|||||||
stacksize 65536
|
stacksize 65536
|
||||||
and then find the minimal value for the service to work. If you experience
|
and then find the minimal value for the service to work. If you experience
|
||||||
memory shortage, you can try to experiment with negative values.
|
memory shortage, you can try to experiment with negative values.
|
||||||
|
.br
|
||||||
|
With SQL logging (log &ODBC_string) the value is automatically raised to
|
||||||
|
32768 if it is smaller, because ODBC drivers require more stack. A
|
||||||
|
.BR stacksize
|
||||||
|
command placed after the
|
||||||
|
.BR log
|
||||||
|
command overrides this.
|
||||||
|
.br
|
||||||
|
The base stack size the value is added to is 49152. On FreeBSD, NetBSD,
|
||||||
|
OpenBSD and DragonFly it is 65536, because libc functions such as vfprintf()
|
||||||
|
called by syslog() use significantly more stack there. The result is never
|
||||||
|
lowered below PTHREAD_STACK_MIN, so a large negative value can not disable
|
||||||
|
the thread stack.
|
||||||
|
|
||||||
.SH PLUGINS
|
.SH PLUGINS
|
||||||
|
|
||||||
|
|||||||
@ -519,15 +519,10 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
|
|||||||
#ifndef NORADIUS
|
#ifndef NORADIUS
|
||||||
_3proxy_mutex_init(&rad_mutex);
|
_3proxy_mutex_init(&rad_mutex);
|
||||||
#endif
|
#endif
|
||||||
#ifdef _WIN32
|
if(_3proxy_sem_init(conf.threadinit, 1, 1)){
|
||||||
conf.threadinit = CreateSemaphore(NULL, 1, 1, NULL);
|
|
||||||
if(!conf.threadinit){
|
|
||||||
fprintf(stderr, "semaphore init failed\n");
|
fprintf(stderr, "semaphore init failed\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
_3proxy_mutex_init(&conf.threadinit);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WITH_SSL
|
#ifdef WITH_SSL
|
||||||
ssl_install();
|
ssl_install();
|
||||||
|
|||||||
@ -24,13 +24,13 @@ void * autochild(struct clientparam* param) {
|
|||||||
}
|
}
|
||||||
if(*param->clibuf == 4 || *param->clibuf == 5) {
|
if(*param->clibuf == 4 || *param->clibuf == 5) {
|
||||||
param->service = S_SOCKS;
|
param->service = S_SOCKS;
|
||||||
return sockschild(param);
|
return (void *)sockschild;
|
||||||
}
|
}
|
||||||
if(*param->clibuf == 22) {
|
if(*param->clibuf == 22) {
|
||||||
param->service = S_TLSPR;
|
param->service = S_TLSPR;
|
||||||
return tlsprchild(param);
|
return (void *)tlsprchild;
|
||||||
}
|
}
|
||||||
param->service = S_PROXY;
|
param->service = S_PROXY;
|
||||||
return proxychild(param);
|
return (void *)proxychild;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
45
src/common.c
45
src/common.c
@ -134,12 +134,47 @@ int timeouts[12] = {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
struct extparam conf = {
|
#ifndef _WIN32
|
||||||
#ifdef _WIN32
|
/* PTHREAD_STACK_MIN is 128K on glibc/aarch64 and glibc/powerpc and may be
|
||||||
.threadinit = NULL,
|
a sysconf() call with _GNU_SOURCE. pthread_attr_setstacksize() fails with
|
||||||
#else
|
EINVAL below it and the thread silently gets the 8M system default stack.
|
||||||
.threadinit = 0,
|
*/
|
||||||
|
size_t threadstacksize(int extra){
|
||||||
|
long size = BASESTACKSIZE + extra;
|
||||||
|
|
||||||
|
if(size < (long)PTHREAD_STACK_MIN) size = (long)PTHREAD_STACK_MIN;
|
||||||
|
return (size_t)size;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _3proxy_sem_init_f(_3proxy_sem_t *sem, unsigned count, unsigned maxcount){
|
||||||
|
sem->count = count;
|
||||||
|
sem->maxcount = maxcount;
|
||||||
|
if(pthread_mutex_init(&sem->mutex, NULL)) return 1;
|
||||||
|
if(pthread_cond_init(&sem->cond, NULL)){
|
||||||
|
pthread_mutex_destroy(&sem->mutex);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _3proxy_sem_lock_f(_3proxy_sem_t *sem){
|
||||||
|
pthread_mutex_lock(&sem->mutex);
|
||||||
|
while(!sem->count) pthread_cond_wait(&sem->cond, &sem->mutex);
|
||||||
|
sem->count--;
|
||||||
|
pthread_mutex_unlock(&sem->mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _3proxy_sem_unlock_f(_3proxy_sem_t *sem){
|
||||||
|
pthread_mutex_lock(&sem->mutex);
|
||||||
|
if(sem->count < sem->maxcount){
|
||||||
|
sem->count++;
|
||||||
|
pthread_cond_signal(&sem->cond);
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&sem->mutex);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct extparam conf = {
|
||||||
.timeouts = timeouts,
|
.timeouts = timeouts,
|
||||||
.acl = NULL,
|
.acl = NULL,
|
||||||
.conffile = NULL,
|
.conffile = NULL,
|
||||||
|
|||||||
@ -156,7 +156,7 @@ int start_proxy_thread(struct child * chp){
|
|||||||
if(h)CloseHandle(h);
|
if(h)CloseHandle(h);
|
||||||
#else
|
#else
|
||||||
pthread_attr_init(&pa);
|
pthread_attr_init(&pa);
|
||||||
pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + (32768+conf.stacksize));
|
pthread_attr_setstacksize(&pa,threadstacksize(conf.stacksize));
|
||||||
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
|
||||||
pthread_create(&thread, &pa, startsrv, (void *)chp);
|
pthread_create(&thread, &pa, startsrv, (void *)chp);
|
||||||
pthread_attr_destroy(&pa);
|
pthread_attr_destroy(&pa);
|
||||||
@ -301,6 +301,12 @@ static int h_external(int argc, unsigned char ** argv){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ODBC drivers require noticeably more stack than the file logger, raise
|
||||||
|
the client thread stack size unless a larger one is configured
|
||||||
|
explicitly. An explicit stacksize placed after the log command still wins.
|
||||||
|
*/
|
||||||
|
#define LOGSTACKSIZE 32768
|
||||||
|
|
||||||
static int h_log(int argc, unsigned char ** argv){
|
static int h_log(int argc, unsigned char ** argv){
|
||||||
unsigned char tmpbuf[8192];
|
unsigned char tmpbuf[8192];
|
||||||
int notchanged = 0;
|
int notchanged = 0;
|
||||||
@ -330,6 +336,7 @@ static int h_log(int argc, unsigned char ** argv){
|
|||||||
#ifdef WITH_ODBC
|
#ifdef WITH_ODBC
|
||||||
else if(*argv[1]=='&'){
|
else if(*argv[1]=='&'){
|
||||||
conf.logfunc = logsql;
|
conf.logfunc = logsql;
|
||||||
|
if(conf.stacksize < LOGSTACKSIZE) conf.stacksize = LOGSTACKSIZE;
|
||||||
if(notchanged) return 0;
|
if(notchanged) return 0;
|
||||||
_3proxy_mutex_lock(&log_mutex);
|
_3proxy_mutex_lock(&log_mutex);
|
||||||
close_sql();
|
close_sql();
|
||||||
|
|||||||
@ -222,7 +222,6 @@ CLEANRET:
|
|||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
param->clisock = INVALID_SOCKET;
|
param->clisock = INVALID_SOCKET;
|
||||||
#endif
|
#endif
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -325,7 +325,6 @@ CLEANRET:
|
|||||||
}
|
}
|
||||||
if(req) free(req);
|
if(req) free(req);
|
||||||
if(buf) free(buf);
|
if(buf) free(buf);
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -64,7 +64,7 @@ void * imappchild(struct clientparam* param) {
|
|||||||
if(socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]) <= 0) {RETURN(698);}
|
if(socksend(param, param->clisock, buf, (int)strlen((char *)buf), conf.timeouts[STRING_S]) <= 0) {RETURN(698);}
|
||||||
param->clientstarttls = S_IMAPP;
|
param->clientstarttls = S_IMAPP;
|
||||||
if(!param->srv->targetport) param->srv->targetport = htons(143);
|
if(!param->srv->targetport) param->srv->targetport = htons(143);
|
||||||
return tlsprchild(param);
|
return (void *)tlsprchild;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!strncasecmp((char *)cmd, "LOGIN ", 6)){
|
if(!strncasecmp((char *)cmd, "LOGIN ", 6)){
|
||||||
@ -238,7 +238,6 @@ CLEANRET:
|
|||||||
socksend(param, param->clisock, buf, (int)strlen((char *)buf),conf.timeouts[STRING_S]);
|
socksend(param, param->clisock, buf, (int)strlen((char *)buf),conf.timeouts[STRING_S]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -48,6 +48,13 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
} MD4_CTX;
|
} MD4_CTX;
|
||||||
|
|
||||||
|
/* Remap public symbols to a 3proxy-private namespace so the bundled
|
||||||
|
implementation does not collide with OpenSSL/libcrypto's MD4 symbols
|
||||||
|
when statically linked. Callers keep using the MD4_* names. */
|
||||||
|
#define MD4_Init _3proxy_MD4_Init
|
||||||
|
#define MD4_Update _3proxy_MD4_Update
|
||||||
|
#define MD4_Final _3proxy_MD4_Final
|
||||||
|
|
||||||
extern void MD4_Init(MD4_CTX *ctx);
|
extern void MD4_Init(MD4_CTX *ctx);
|
||||||
extern void MD4_Update(MD4_CTX *ctx, const void *data, size_t size);
|
extern void MD4_Update(MD4_CTX *ctx, const void *data, size_t size);
|
||||||
extern void MD4_Final(unsigned char *result, MD4_CTX *ctx);
|
extern void MD4_Final(unsigned char *result, MD4_CTX *ctx);
|
||||||
|
|||||||
@ -44,6 +44,13 @@ typedef struct {
|
|||||||
MD5_u32plus block[16];
|
MD5_u32plus block[16];
|
||||||
} MD5_CTX;
|
} MD5_CTX;
|
||||||
|
|
||||||
|
/* Remap public symbols to a 3proxy-private namespace so the bundled
|
||||||
|
implementation does not collide with OpenSSL/libcrypto's MD5 symbols
|
||||||
|
when statically linked. Callers keep using the MD5_* names. */
|
||||||
|
#define MD5_Init _3proxy_MD5_Init
|
||||||
|
#define MD5_Update _3proxy_MD5_Update
|
||||||
|
#define MD5_Final _3proxy_MD5_Final
|
||||||
|
|
||||||
extern void MD5_Init(MD5_CTX *ctx);
|
extern void MD5_Init(MD5_CTX *ctx);
|
||||||
extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
|
extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
|
||||||
extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
|
extern void MD5_Final(unsigned char *result, MD5_CTX *ctx);
|
||||||
|
|||||||
@ -338,7 +338,7 @@ void lognone(struct clientparam * param, const unsigned char *s) {
|
|||||||
clearstat(param);
|
clearstat(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
void logstdout(struct clientparam * param, const unsigned char *s) {
|
NOINLINE void logstdout(struct clientparam * param, const unsigned char *s) {
|
||||||
FILE *log;
|
FILE *log;
|
||||||
unsigned char tmpbuf[8192];
|
unsigned char tmpbuf[8192];
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@ void * pop3pchild(struct clientparam* param) {
|
|||||||
if(socksend(param, param->clisock, (unsigned char *)"+OK Begin TLS negotiation\r\n", 27, conf.timeouts[STRING_S])!=27) {RETURN(623);}
|
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;
|
param->clientstarttls = S_POP3P;
|
||||||
if(!param->srv->targetport) param->srv->targetport = htons(110);
|
if(!param->srv->targetport) param->srv->targetport = htons(110);
|
||||||
return tlsprchild(param);
|
return (void *)tlsprchild;
|
||||||
}
|
}
|
||||||
#endif
|
#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]);
|
||||||
@ -74,7 +74,6 @@ CLEANRET:
|
|||||||
if(param->clisock != INVALID_SOCKET) {
|
if(param->clisock != INVALID_SOCKET) {
|
||||||
if ((param->res > 0 && param->res < 100) || (param->res > 611 && param->res <700)) socksend(param, param->clisock, (unsigned char *)"-ERR\r\n", 6,conf.timeouts[STRING_S]);
|
if ((param->res > 0 && param->res < 100) || (param->res > 611 && param->res <700)) socksend(param, param->clisock, (unsigned char *)"-ERR\r\n", 6,conf.timeouts[STRING_S]);
|
||||||
}
|
}
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -864,7 +864,7 @@ for(;;){
|
|||||||
if(isconnect && param->redirtype != R_HTTP) {
|
if(isconnect && param->redirtype != R_HTTP) {
|
||||||
if(param->redirectfunc) {
|
if(param->redirectfunc) {
|
||||||
freeptr(&req); freeptr(&buf); freeptr(&ftpbase);
|
freeptr(&req); freeptr(&buf); freeptr(&ftpbase);
|
||||||
return (*param->redirectfunc)(param);
|
return (void *)param->redirectfunc;
|
||||||
}
|
}
|
||||||
param->res = mapsocket(param, conf.timeouts[CONNECTION_L]);
|
param->res = mapsocket(param, conf.timeouts[CONNECTION_L]);
|
||||||
RETURN(param->res);
|
RETURN(param->res);
|
||||||
@ -1226,7 +1226,6 @@ CLEANRET:
|
|||||||
}
|
}
|
||||||
logurl(param, (char *)buf, (char *)req, ftp);
|
logurl(param, (char *)buf, (char *)req, ftp);
|
||||||
freeptr(&req); freeptr(&buf); freeptr(&ftpbase);
|
freeptr(&req); freeptr(&buf); freeptr(&ftpbase);
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
48
src/proxy.h
48
src/proxy.h
@ -112,6 +112,33 @@ void daemonize(void);
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Keeps a callee with a large frame out of the caller's frame, e.g. the
|
||||||
|
8K log buffer of logstdout() out of dolog(), which calls it in a branch
|
||||||
|
taken only when there is no service.
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
#define NOINLINE __attribute__((noinline))
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define NOINLINE __declspec(noinline)
|
||||||
|
#else
|
||||||
|
#define NOINLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Thread stack size, stacksize command value is added to it. BSD libc uses
|
||||||
|
significantly more stack, e.g. in vfprintf() called by syslog().
|
||||||
|
*/
|
||||||
|
#ifndef BASESTACKSIZE
|
||||||
|
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
|
||||||
|
#define BASESTACKSIZE 65536
|
||||||
|
#else
|
||||||
|
#define BASESTACKSIZE 49152
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
size_t threadstacksize(int extra);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_ODBC
|
#ifdef WITH_ODBC
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sqltypes.h>
|
#include <sqltypes.h>
|
||||||
@ -198,7 +225,7 @@ void dolog(struct clientparam * param, const unsigned char *s);
|
|||||||
int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec);
|
int dobuf(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec);
|
||||||
int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
|
int dobuf2(struct clientparam * param, unsigned char * buf, const unsigned char *s, const unsigned char * doublec, struct tm* tm, char * format);
|
||||||
extern FILE * stdlog;
|
extern FILE * stdlog;
|
||||||
void logstdout(struct clientparam * param, const unsigned char *s);
|
NOINLINE void logstdout(struct clientparam * param, const unsigned char *s);
|
||||||
void logsyslog(struct clientparam * param, const unsigned char *s);
|
void logsyslog(struct clientparam * param, const unsigned char *s);
|
||||||
void lognone(struct clientparam * param, const unsigned char *s);
|
void lognone(struct clientparam * param, const unsigned char *s);
|
||||||
void logradius(struct clientparam * param, const unsigned char *s);
|
void logradius(struct clientparam * param, const unsigned char *s);
|
||||||
@ -248,14 +275,18 @@ 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);
|
||||||
void fromhex(unsigned char *in, unsigned char *out, int len);
|
void fromhex(unsigned char *in, unsigned char *out, int len);
|
||||||
|
|
||||||
|
extern _3proxy_sem_t udpinit;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
extern HANDLE udpinit;
|
#define _3proxy_sem_init(x, count, maxcount) (((x) = CreateSemaphore(NULL, (count), (maxcount), NULL))? 0 : 1)
|
||||||
#define _3proxy_sem_lock(x) WaitForSingleObject(x, INFINITE)
|
#define _3proxy_sem_lock(x) WaitForSingleObject(x, INFINITE)
|
||||||
#define _3proxy_sem_unlock(x) ReleaseSemaphore(x, 1, NULL)
|
#define _3proxy_sem_unlock(x) ReleaseSemaphore(x, 1, NULL)
|
||||||
#else
|
#else
|
||||||
extern _3proxy_mutex_t udpinit;
|
int _3proxy_sem_init_f(_3proxy_sem_t *sem, unsigned count, unsigned maxcount);
|
||||||
#define _3proxy_sem_lock(x) pthread_mutex_lock(&x)
|
void _3proxy_sem_lock_f(_3proxy_sem_t *sem);
|
||||||
#define _3proxy_sem_unlock(x) pthread_mutex_unlock(&x)
|
void _3proxy_sem_unlock_f(_3proxy_sem_t *sem);
|
||||||
|
#define _3proxy_sem_init(x, count, maxcount) _3proxy_sem_init_f(&x, (count), (maxcount))
|
||||||
|
#define _3proxy_sem_lock(x) _3proxy_sem_lock_f(&x)
|
||||||
|
#define _3proxy_sem_unlock(x) _3proxy_sem_unlock_f(&x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -338,6 +369,13 @@ void * udppmchild(struct clientparam * param);
|
|||||||
void * adminchild(struct clientparam * param);
|
void * adminchild(struct clientparam * param);
|
||||||
void * ftpprchild(struct clientparam * param);
|
void * ftpprchild(struct clientparam * param);
|
||||||
void * tlsprchild(struct clientparam * param);
|
void * tlsprchild(struct clientparam * param);
|
||||||
|
/* Child functions return the child to redirect the request to, or NULL if
|
||||||
|
the request is complete. childfunc() calls them and releases param.
|
||||||
|
Recursive redirection, e.g. a socks service redirected to socks5, used to
|
||||||
|
be limited by the stack size only, MAXCHILDREDIRECTS limits it now.
|
||||||
|
*/
|
||||||
|
#define MAXCHILDREDIRECTS 16
|
||||||
|
void * childfunc(struct clientparam * param);
|
||||||
|
|
||||||
|
|
||||||
struct datatype;
|
struct datatype;
|
||||||
|
|||||||
@ -11,6 +11,24 @@
|
|||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Child functions do not call each other, a child requesting redirection to
|
||||||
|
another child returns it instead of calling it, to keep the stack flat.
|
||||||
|
The child which completed the request returns NULL. param is logged by
|
||||||
|
the child and released here.
|
||||||
|
*/
|
||||||
|
void * childfunc(struct clientparam * param){
|
||||||
|
PROXYFUNC pf = param->srv->pf;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; pf && i < MAXCHILDREDIRECTS; i++) pf = (PROXYFUNC)(*pf)(param);
|
||||||
|
if(pf){
|
||||||
|
param->res = 101;
|
||||||
|
dolog(param, (unsigned char *)"Redirection loop");
|
||||||
|
}
|
||||||
|
freeparam(param);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#define param ((struct clientparam *) p)
|
#define param ((struct clientparam *) p)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD WINAPI threadfunc(LPVOID p) {
|
DWORD WINAPI threadfunc(LPVOID p) {
|
||||||
@ -121,7 +139,7 @@ void * threadfunc (void *p) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
((struct clientparam *) p)->srv->pf((struct clientparam *)p);
|
childfunc((struct clientparam *)p);
|
||||||
}
|
}
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return 0;
|
return 0;
|
||||||
@ -367,6 +385,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
if(!srv.udpbuf || !srv.udpbuf2) {
|
if(!srv.udpbuf || !srv.udpbuf2) {
|
||||||
#ifndef STDMAIN
|
#ifndef STDMAIN
|
||||||
haveerror = 2;
|
haveerror = 2;
|
||||||
|
_3proxy_sem_unlock(conf.threadinit);
|
||||||
#endif
|
#endif
|
||||||
return 11;
|
return 11;
|
||||||
}
|
}
|
||||||
@ -608,7 +627,6 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
if (error || i!=argc) {
|
if (error || i!=argc) {
|
||||||
#ifndef STDMAIN
|
#ifndef STDMAIN
|
||||||
haveerror = 1;
|
haveerror = 1;
|
||||||
_3proxy_sem_unlock(conf.threadinit);
|
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, "%s of %s\n"
|
fprintf(stderr, "%s of %s\n"
|
||||||
"Usage: %s options\n"
|
"Usage: %s options\n"
|
||||||
@ -628,6 +646,9 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
""
|
""
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
#ifndef STDMAIN
|
||||||
|
_3proxy_sem_unlock(conf.threadinit);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -640,7 +661,6 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv.intsa) = htons((uint16_t)atoi(argv[i])))==0 || (srv.targetport = htons((uint16_t)atoi(argv[i+2])))==0) {
|
if (error || argc != i+3 || *argv[i]=='-'|| (*SAPORT(&srv.intsa) = htons((uint16_t)atoi(argv[i])))==0 || (srv.targetport = htons((uint16_t)atoi(argv[i+2])))==0) {
|
||||||
#ifndef STDMAIN
|
#ifndef STDMAIN
|
||||||
haveerror = 1;
|
haveerror = 1;
|
||||||
_3proxy_sem_unlock(conf.threadinit);
|
|
||||||
#endif
|
#endif
|
||||||
fprintf(stderr, "%s of %s\n"
|
fprintf(stderr, "%s of %s\n"
|
||||||
"Usage: %s options"
|
"Usage: %s options"
|
||||||
@ -661,6 +681,9 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
""
|
""
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
|
#ifndef STDMAIN
|
||||||
|
_3proxy_sem_unlock(conf.threadinit);
|
||||||
|
#endif
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
srv.target = (unsigned char *)strdup(argv[i+1]);
|
srv.target = (unsigned char *)strdup(argv[i+1]);
|
||||||
@ -684,7 +707,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
return 2;
|
return 2;
|
||||||
};
|
};
|
||||||
*newparam = defparam;
|
*newparam = defparam;
|
||||||
return((*srv.pf)((void *)newparam)? 1:0);
|
return(childfunc(newparam)? 1:0);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -917,7 +940,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
pthread_attr_init(&pa);
|
pthread_attr_init(&pa);
|
||||||
pthread_attr_setstacksize(&pa,PTHREAD_STACK_MIN + (32768 + srv.stacksize));
|
pthread_attr_setstacksize(&pa,threadstacksize(srv.stacksize));
|
||||||
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
|
pthread_attr_setdetachstate(&pa,PTHREAD_CREATE_DETACHED);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1051,9 +1074,12 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
else {
|
else {
|
||||||
struct clientparam *toparam;
|
struct clientparam *toparam;
|
||||||
|
|
||||||
srv.udplen = sockrecvfrom(NULL, srv.srvsock, (struct sockaddr *)&defparam.sincr, srv.udpbuf, UDPBUFSIZE, 0);
|
|
||||||
if(srv.udplen <= 0) continue;
|
|
||||||
_3proxy_sem_lock(udpinit);
|
_3proxy_sem_lock(udpinit);
|
||||||
|
srv.udplen = sockrecvfrom(NULL, srv.srvsock, (struct sockaddr *)&defparam.sincr, srv.udpbuf, UDPBUFSIZE, 0);
|
||||||
|
if(srv.udplen <= 0) {
|
||||||
|
_3proxy_sem_unlock(udpinit);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if(hashresolv(&udp_table, &defparam, &toparam, NULL)) {
|
if(hashresolv(&udp_table, &defparam, &toparam, NULL)) {
|
||||||
int i, len=0;
|
int i, len=0;
|
||||||
|
|
||||||
@ -1172,12 +1198,7 @@ int MODULEMAINFUNC (int argc, char** argv){
|
|||||||
|
|
||||||
#ifndef NOUDPMAIN
|
#ifndef NOUDPMAIN
|
||||||
int udpinited = 0;
|
int udpinited = 0;
|
||||||
#ifdef _WIN32
|
_3proxy_sem_t udpinit;
|
||||||
HANDLE udpinit;
|
|
||||||
#else
|
|
||||||
_3proxy_mutex_t udpinit;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void srvinit(struct srvparam * srv, struct clientparam *param){
|
void srvinit(struct srvparam * srv, struct clientparam *param){
|
||||||
@ -1216,11 +1237,7 @@ void srvinit(struct srvparam * srv, struct clientparam *param){
|
|||||||
_3proxy_mutex_init(&srv->counter_mutex);
|
_3proxy_mutex_init(&srv->counter_mutex);
|
||||||
#ifndef NOUDPMAIN
|
#ifndef NOUDPMAIN
|
||||||
if(!udpinited){
|
if(!udpinited){
|
||||||
#ifdef _WIN32
|
(void)_3proxy_sem_init(udpinit, 1, 1);
|
||||||
udpinit = CreateSemaphore(NULL, 1, 1, NULL);
|
|
||||||
#else
|
|
||||||
_3proxy_mutex_init(&udpinit);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
udpinited = 1;
|
udpinited = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -132,7 +132,7 @@ void * smtppchild(struct clientparam* param) {
|
|||||||
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);}
|
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;
|
param->clientstarttls = S_SMTPP;
|
||||||
if(!param->srv->targetport) param->srv->targetport = htons(587);
|
if(!param->srv->targetport) param->srv->targetport = htons(587);
|
||||||
return tlsprchild(param);
|
return (void *)tlsprchild;
|
||||||
}
|
}
|
||||||
#endif
|
#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]);
|
||||||
@ -319,7 +319,6 @@ CLEANRET:
|
|||||||
if ((param->res > 0 && param->res < 100) || (param->res > 661 && param->res <700)) socksend(param, param->clisock, (unsigned char *)"571 \r\n", 6,conf.timeouts[STRING_S]);
|
if ((param->res > 0 && param->res < 100) || (param->res > 661 && param->res <700)) socksend(param, param->clisock, (unsigned char *)"571 \r\n", 6,conf.timeouts[STRING_S]);
|
||||||
}
|
}
|
||||||
if(command) free(command);
|
if(command) free(command);
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -385,9 +385,8 @@ fflush(stderr);
|
|||||||
switch(command) {
|
switch(command) {
|
||||||
case 1:
|
case 1:
|
||||||
if(param->redirectfunc){
|
if(param->redirectfunc){
|
||||||
void *ret = (*param->redirectfunc)(param);
|
|
||||||
if(buf)free(buf);
|
if(buf)free(buf);
|
||||||
return ret;
|
return (void *)param->redirectfunc;
|
||||||
}
|
}
|
||||||
param->res = mapsocket(param, conf.timeouts[CONNECTION_L]);
|
param->res = mapsocket(param, conf.timeouts[CONNECTION_L]);
|
||||||
break;
|
break;
|
||||||
@ -467,7 +466,6 @@ fflush(stderr);
|
|||||||
dolog(param, buf);
|
dolog(param, buf);
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
src/ssl.c
42
src/ssl.c
@ -490,6 +490,24 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx){
|
|||||||
return preverify_ok;
|
return preverify_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITH_WOLFSSL
|
||||||
|
/* wolfSSL's SSL_CTX_use_PrivateKey(EVP_PKEY*) compat is unreliable: it
|
||||||
|
* silently fails (returns 0, no error queued) for keys loaded via
|
||||||
|
* PEM_read_bio_PrivateKey. Export the key to DER and load via the
|
||||||
|
* native buffer API instead. */
|
||||||
|
static int ssl_ctx_use_pkey(SSL_CTX *ctx, EVP_PKEY *key){
|
||||||
|
unsigned char *der = NULL;
|
||||||
|
int len, rc;
|
||||||
|
len = i2d_PrivateKey(key, &der);
|
||||||
|
if(len <= 0 || !der) return 0;
|
||||||
|
rc = wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, (long)len, SSL_FILETYPE_ASN1);
|
||||||
|
OPENSSL_free(der);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define ssl_ctx_use_pkey(ctx, key) SSL_CTX_use_PrivateKey((ctx), (key))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
SSL_CTX * ssl_cli_ctx(SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_key, char** errSSL){
|
SSL_CTX * ssl_cli_ctx(SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_key, char** errSSL){
|
||||||
SSL_CTX *ctx;
|
SSL_CTX *ctx;
|
||||||
@ -516,12 +534,19 @@ SSL_CTX * ssl_cli_ctx(SSL_CONFIG *config, X509 *server_cert, EVP_PKEY *server_ke
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = SSL_CTX_use_PrivateKey(ctx, server_key);
|
/* Load the private key only when a cert is already loaded into ctx.
|
||||||
|
* wolfSSL validates the key against the cert and requires the cert
|
||||||
|
* to be present first; OpenSSL tolerates either order but is happy
|
||||||
|
* with cert-first too. When server_cert is NULL (serv path), the
|
||||||
|
* caller loads the cert chain and the key itself after this call. */
|
||||||
|
if(server_cert) {
|
||||||
|
err = ssl_ctx_use_pkey(ctx, server_key);
|
||||||
if ( err <= 0 ) {
|
if ( err <= 0 ) {
|
||||||
*errSSL = getSSLErr();
|
*errSSL = getSSLErr();
|
||||||
SSL_CTX_free(ctx);
|
SSL_CTX_free(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
SSL_CTX_set_session_id_context(ctx, (const unsigned char *)"3proxy", 6);
|
SSL_CTX_set_session_id_context(ctx, (const unsigned char *)"3proxy", 6);
|
||||||
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);
|
||||||
@ -655,6 +680,10 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
|
|||||||
fprintf(stderr, "failed to read server cert: %s\n", srvcert);
|
fprintf(stderr, "failed to read server cert: %s\n", srvcert);
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
if(ssl_ctx_use_pkey(sc->cli_ctx, sc->server_key) <= 0){
|
||||||
|
fprintf(stderr, "failed to use server key\n");
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
sc->serv = 1;
|
sc->serv = 1;
|
||||||
}
|
}
|
||||||
if(mitm || cli || serv){
|
if(mitm || cli || serv){
|
||||||
@ -678,7 +707,7 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
|
|||||||
}
|
}
|
||||||
if(sc->client_cert){
|
if(sc->client_cert){
|
||||||
SSL_CTX_use_certificate(sc->srv_ctx, (X509 *) sc->client_cert);
|
SSL_CTX_use_certificate(sc->srv_ctx, (X509 *) sc->client_cert);
|
||||||
SSL_CTX_use_PrivateKey(sc->srv_ctx, sc->client_key);
|
ssl_ctx_use_pkey(sc->srv_ctx, sc->client_key);
|
||||||
}
|
}
|
||||||
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);
|
||||||
@ -705,6 +734,15 @@ static void* ssl_filter_open(void * idata, struct srvparam * srv){
|
|||||||
SSL_CTX_set_default_verify_paths(sc->srv_ctx);
|
SSL_CTX_set_default_verify_paths(sc->srv_ctx);
|
||||||
SSL_CTX_set_verify(sc->srv_ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
SSL_CTX_set_verify(sc->srv_ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
|
||||||
}
|
}
|
||||||
|
#ifdef WITH_WOLFSSL
|
||||||
|
else {
|
||||||
|
/* wolfSSL defaults to peer verification; OpenSSL defaults to
|
||||||
|
* SSL_VERIFY_NONE. Make the no-verify intent explicit so the
|
||||||
|
* upstream handshake (ssl_cli / ssl_mitm) succeeds without a
|
||||||
|
* trusted CA store. */
|
||||||
|
SSL_CTX_set_verify(sc->srv_ctx, SSL_VERIFY_NONE, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef WITHSPLICE
|
#ifdef WITHSPLICE
|
||||||
srv->usesplice = 0;
|
srv->usesplice = 0;
|
||||||
|
|||||||
125
src/ssllib.c
125
src/ssllib.c
@ -45,8 +45,6 @@ static char hexMap[] = {
|
|||||||
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
|
||||||
};
|
};
|
||||||
|
|
||||||
static BIO *bio_err=NULL;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
char * getSSLErr(){
|
char * getSSLErr(){
|
||||||
@ -74,10 +72,23 @@ static size_t bin2hex (const unsigned char* bin, size_t bin_length, char* str, s
|
|||||||
return p - str;
|
return p - str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_ext(X509 *cert, int nid, char *value)
|
static int copy_ext(X509 *dst_cert, X509 *src_cert, int nid)
|
||||||
|
{
|
||||||
|
X509_EXTENSION *ext;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
idx = X509_get_ext_by_NID(src_cert, nid, -1);
|
||||||
|
if(idx < 0) return 0;
|
||||||
|
if(!(ext = X509_get_ext(src_cert, idx))) return 0;
|
||||||
|
return X509_add_ext(dst_cert, ext, -1) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef WITH_WOLFSSL
|
||||||
|
static int add_ext(X509 *cert, int nid, const char *value)
|
||||||
{
|
{
|
||||||
X509_EXTENSION *ex;
|
X509_EXTENSION *ex;
|
||||||
X509V3_CTX ctx;
|
X509V3_CTX ctx;
|
||||||
|
int err;
|
||||||
/* This sets the 'context' of the extensions. */
|
/* This sets the 'context' of the extensions. */
|
||||||
/* No configuration database */
|
/* No configuration database */
|
||||||
X509V3_set_ctx_nodb(&ctx);
|
X509V3_set_ctx_nodb(&ctx);
|
||||||
@ -85,25 +96,16 @@ static int add_ext(X509 *cert, int nid, char *value)
|
|||||||
* no request and no CRL
|
* no request and no CRL
|
||||||
*/
|
*/
|
||||||
X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
|
X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
|
||||||
ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
|
/* value is char * prior to OpenSSL 1.1.0 */
|
||||||
|
ex = X509V3_EXT_conf_nid(NULL, &ctx, nid, (char *)value);
|
||||||
if (!ex)
|
if (!ex)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
X509_add_ext(cert,ex,-1);
|
err = X509_add_ext(cert,ex,-1);
|
||||||
X509_EXTENSION_free(ex);
|
X509_EXTENSION_free(ex);
|
||||||
return 1;
|
return err > 0;
|
||||||
}
|
|
||||||
|
|
||||||
void del_ext(X509 *dst_cert, int nid, int where){
|
|
||||||
int ex;
|
|
||||||
|
|
||||||
ex = X509_get_ext_by_NID(dst_cert, nid, where);
|
|
||||||
if(ex>=0){
|
|
||||||
X509_EXTENSION *ext;
|
|
||||||
if((ext = X509_delete_ext(dst_cert, ex))) X509_EXTENSION_free(ext);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config)
|
SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config)
|
||||||
{
|
{
|
||||||
@ -112,8 +114,6 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config)
|
|||||||
X509 *src_cert = (X509 *) cert;
|
X509 *src_cert = (X509 *) cert;
|
||||||
X509 *dst_cert = NULL;
|
X509 *dst_cert = NULL;
|
||||||
|
|
||||||
EVP_PKEY *pk = NULL;
|
|
||||||
|
|
||||||
unsigned char hash_sha256[32];
|
unsigned char hash_sha256[32];
|
||||||
char hash_name_sha256[(16*2) + 1];
|
char hash_name_sha256[(16*2) + 1];
|
||||||
char cache_name[256];
|
char cache_name[256];
|
||||||
@ -142,28 +142,67 @@ SSL_CERT ssl_copy_cert(SSL_CERT cert, SSL_CONFIG *config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* proceed if certificate is not cached */
|
/* Build a fresh certificate instead of duplicating the source: only
|
||||||
dst_cert = X509_dup(src_cert);
|
* the fields required for a usable server cert are copied (version,
|
||||||
|
* serial, subject, validity, SAN). This avoids inheriting upstream
|
||||||
|
* extensions (AKI, CRL dist points, certificate policies, ...) that
|
||||||
|
* break chain validation, and works around wolfSSL's no-op
|
||||||
|
* X509_delete_ext compat shim. */
|
||||||
|
dst_cert = X509_new();
|
||||||
if ( dst_cert == NULL ) {
|
if ( dst_cert == NULL ) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
del_ext(dst_cert, NID_crl_distribution_points, -1);
|
/* v3 is required, extensions are added below */
|
||||||
del_ext(dst_cert, NID_info_access, -1);
|
X509_set_version(dst_cert, 2);
|
||||||
del_ext(dst_cert, NID_authority_key_identifier, -1);
|
if(!X509_set_serialNumber(dst_cert, X509_get_serialNumber(src_cert))
|
||||||
del_ext(dst_cert, NID_certificate_policies, 0);
|
|| !X509_set_subject_name(dst_cert, X509_get_subject_name(src_cert))
|
||||||
|
|| !X509_set_issuer_name(dst_cert, X509_get_subject_name(config->CA_cert))){
|
||||||
|
X509_free(dst_cert);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
err = X509_set_pubkey(dst_cert, config->server_key?config->server_key:config->CA_key);
|
err = X509_set_pubkey(dst_cert, config->server_key?config->server_key:config->CA_key);
|
||||||
if ( err == 0 ) {
|
if ( err == 0 ) {
|
||||||
X509_free(dst_cert);
|
X509_free(dst_cert);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* wolfSSL has no X509_set1_notBefore/X509_set1_notAfter before 5.7.2,
|
||||||
|
X509_set_notBefore/X509_set_notAfter are available in every version and
|
||||||
err = X509_set_issuer_name(dst_cert, X509_get_subject_name(config->CA_cert));
|
copy the time the same way.
|
||||||
if(!err){
|
*/
|
||||||
|
#if defined(WITH_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
if(!X509_set_notBefore(dst_cert, X509_get_notBefore(src_cert))
|
||||||
|
|| !X509_set_notAfter(dst_cert, X509_get_notAfter(src_cert))){
|
||||||
|
#else
|
||||||
|
if(!X509_set1_notBefore(dst_cert, X509_get0_notBefore(src_cert))
|
||||||
|
|| !X509_set1_notAfter(dst_cert, X509_get0_notAfter(src_cert))){
|
||||||
|
#endif
|
||||||
X509_free(dst_cert);
|
X509_free(dst_cert);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
/* Copy the extensions an end entity certificate is expected to have.
|
||||||
|
* The extensions which break chain validation (AKI, CRL distribution
|
||||||
|
* points, certificate policies, ...) are intentionally not copied.
|
||||||
|
* A copy may fail: wolfSSL keeps extKeyUsage in its own form and can
|
||||||
|
* not add back the one it returns, it is not fatal.
|
||||||
|
*/
|
||||||
|
copy_ext(dst_cert, src_cert, NID_subject_alt_name);
|
||||||
|
#ifndef WITH_WOLFSSL
|
||||||
|
/* Without EKU serverAuth Apple's TLS stack (and Chrome on macOS/iOS,
|
||||||
|
* which uses it) rejects the certificate, generate the extensions the
|
||||||
|
* server certificate has no usable ones to copy. keyUsage is not set:
|
||||||
|
* it depends on the type of the key reused for every generated
|
||||||
|
* certificate, and an absent keyUsage places no restriction.
|
||||||
|
* wolfSSL_X509V3_EXT_conf_nid() is a stub returning NULL in every
|
||||||
|
* wolfSSL version, the extensions can not be generated there.
|
||||||
|
*/
|
||||||
|
if(!copy_ext(dst_cert, src_cert, NID_basic_constraints))
|
||||||
|
add_ext(dst_cert, NID_basic_constraints, "critical,CA:FALSE");
|
||||||
|
if(!copy_ext(dst_cert, src_cert, NID_ext_key_usage))
|
||||||
|
add_ext(dst_cert, NID_ext_key_usage, "serverAuth");
|
||||||
|
#else
|
||||||
|
copy_ext(dst_cert, src_cert, NID_basic_constraints);
|
||||||
|
copy_ext(dst_cert, src_cert, NID_ext_key_usage);
|
||||||
|
#endif
|
||||||
err = X509_sign(dst_cert, config->CA_key, EVP_sha256());
|
err = X509_sign(dst_cert, config->CA_key, EVP_sha256());
|
||||||
if(!err){
|
if(!err){
|
||||||
X509_free(dst_cert);
|
X509_free(dst_cert);
|
||||||
@ -229,10 +268,18 @@ void _ssl_cert_free(SSL_CERT cert)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* OpenSSL before 1.1.0 requires the application to install threading
|
||||||
|
callbacks; OpenSSL >= 1.1.0 and wolfSSL handle locking internally. */
|
||||||
|
#if !defined(WITH_WOLFSSL) && defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||||
|
#define LEGACY_SSL_THREADING 1
|
||||||
|
#else
|
||||||
|
#define LEGACY_SSL_THREADING 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LEGACY_SSL_THREADING
|
||||||
/* This array will store all of the mutexes available to OpenSSL. */
|
/* This array will store all of the mutexes available to OpenSSL. */
|
||||||
static _3proxy_mutex_t *mutex_buf= NULL;
|
static _3proxy_mutex_t *mutex_buf= NULL;
|
||||||
|
|
||||||
|
|
||||||
static void locking_function(int mode, int n, const char * file, int line)
|
static void locking_function(int mode, int n, const char * file, int line)
|
||||||
{
|
{
|
||||||
if (mode & CRYPTO_LOCK)
|
if (mode & CRYPTO_LOCK)
|
||||||
@ -249,9 +296,11 @@ static unsigned long id_function(void)
|
|||||||
return ((unsigned long)pthread_self());
|
return ((unsigned long)pthread_self());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int thread_setup(void)
|
int thread_setup(void)
|
||||||
{
|
{
|
||||||
|
#if LEGACY_SSL_THREADING
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
mutex_buf = malloc(CRYPTO_num_locks( ) * sizeof(_3proxy_mutex_t));
|
mutex_buf = malloc(CRYPTO_num_locks( ) * sizeof(_3proxy_mutex_t));
|
||||||
@ -262,10 +311,14 @@ int thread_setup(void)
|
|||||||
CRYPTO_set_id_callback(id_function);
|
CRYPTO_set_id_callback(id_function);
|
||||||
CRYPTO_set_locking_callback(locking_function);
|
CRYPTO_set_locking_callback(locking_function);
|
||||||
return 1;
|
return 1;
|
||||||
|
#else
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int thread_cleanup(void)
|
int thread_cleanup(void)
|
||||||
{
|
{
|
||||||
|
#if LEGACY_SSL_THREADING
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!mutex_buf)
|
if (!mutex_buf)
|
||||||
@ -277,6 +330,9 @@ int thread_cleanup(void)
|
|||||||
free(mutex_buf);
|
free(mutex_buf);
|
||||||
mutex_buf = NULL;
|
mutex_buf = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
|
#else
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -291,9 +347,14 @@ void ssl_init()
|
|||||||
|
|
||||||
ssl_init_done = 1;
|
ssl_init_done = 1;
|
||||||
thread_setup();
|
thread_setup();
|
||||||
|
#ifdef WITH_WOLFSSL
|
||||||
|
wolfSSL_Init();
|
||||||
|
#elif defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||||
|
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||||
|
#else
|
||||||
SSLeay_add_ssl_algorithms();
|
SSLeay_add_ssl_algorithms();
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
|
#endif
|
||||||
_3proxy_mutex_init(&ssl_file_mutex);
|
_3proxy_mutex_init(&ssl_file_mutex);
|
||||||
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,6 +42,12 @@ extern "C" {
|
|||||||
#define _3proxy_mutex_destroy pthread_mutex_destroy
|
#define _3proxy_mutex_destroy pthread_mutex_destroy
|
||||||
#define _3proxy_mutex_lock pthread_mutex_lock
|
#define _3proxy_mutex_lock pthread_mutex_lock
|
||||||
#define _3proxy_mutex_unlock pthread_mutex_unlock
|
#define _3proxy_mutex_unlock pthread_mutex_unlock
|
||||||
|
typedef struct _3proxy_sem_s {
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pthread_cond_t cond;
|
||||||
|
unsigned count;
|
||||||
|
unsigned maxcount;
|
||||||
|
} _3proxy_sem_t;
|
||||||
#else
|
#else
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
@ -50,6 +56,7 @@ extern "C" {
|
|||||||
#define _3proxy_mutex_lock(x) EnterCriticalSection(x)
|
#define _3proxy_mutex_lock(x) EnterCriticalSection(x)
|
||||||
#define _3proxy_mutex_unlock(x) LeaveCriticalSection(x)
|
#define _3proxy_mutex_unlock(x) LeaveCriticalSection(x)
|
||||||
#define _3proxy_mutex_destroy(x) DeleteCriticalSection(x)
|
#define _3proxy_mutex_destroy(x) DeleteCriticalSection(x)
|
||||||
|
#define _3proxy_sem_t HANDLE
|
||||||
#ifdef MSVC
|
#ifdef MSVC
|
||||||
#pragma warning (disable : 4996)
|
#pragma warning (disable : 4996)
|
||||||
#endif
|
#endif
|
||||||
@ -682,11 +689,7 @@ struct filemon {
|
|||||||
|
|
||||||
|
|
||||||
struct extparam {
|
struct extparam {
|
||||||
#ifdef _WIN32
|
_3proxy_sem_t threadinit;
|
||||||
HANDLE threadinit;
|
|
||||||
#else
|
|
||||||
_3proxy_mutex_t threadinit;
|
|
||||||
#endif
|
|
||||||
int *timeouts;
|
int *timeouts;
|
||||||
struct ace * acl;
|
struct ace * acl;
|
||||||
char * conffile;
|
char * conffile;
|
||||||
|
|||||||
@ -40,14 +40,13 @@ void * tcppmchild(struct clientparam* param) {
|
|||||||
if(action != PASS) RETURN(19);
|
if(action != PASS) RETURN(19);
|
||||||
}
|
}
|
||||||
if(param->redirectfunc){
|
if(param->redirectfunc){
|
||||||
return (*param->redirectfunc)(param);
|
return (void *)param->redirectfunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN (mapsocket(param, conf.timeouts[CONNECTION_L]));
|
RETURN (mapsocket(param, conf.timeouts[CONNECTION_L]));
|
||||||
CLEANRET:
|
CLEANRET:
|
||||||
|
|
||||||
dolog(param, param->hostname);
|
dolog(param, param->hostname);
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -190,7 +190,7 @@ int clistarttls(struct clientparam *param, PROXYSERVICE proto){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!strncasecmp((char *)buf, "EHLO ", 5)){
|
if(!strncasecmp((char *)buf, "EHLO ", 5)){
|
||||||
socksend(param, param->clisock, (unsigned char *)"250-Proxy\r\n250 STARTTLS\r\n", 24, conf.timeouts[STRING_S]);
|
socksend(param, param->clisock, (unsigned char *)"250-Proxy\r\n250 STARTTLS\r\n", 25, conf.timeouts[STRING_S]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(!strncasecmp((char *)buf, "HELO ", 5)){
|
if(!strncasecmp((char *)buf, "HELO ", 5)){
|
||||||
@ -201,8 +201,10 @@ int clistarttls(struct clientparam *param, PROXYSERVICE proto){
|
|||||||
socksend(param, param->clisock, (unsigned char *)"221 Proxy\r\n", 11, conf.timeouts[STRING_S]);
|
socksend(param, param->clisock, (unsigned char *)"221 Proxy\r\n", 11, conf.timeouts[STRING_S]);
|
||||||
return -1;
|
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]);
|
socksend(param, param->clisock, (unsigned char *)"530 5.7.0 Must issue a STARTTLS command first\r\n", 47, conf.timeouts[STRING_S]);
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -394,7 +396,7 @@ void * tlsprchild(struct clientparam* param) {
|
|||||||
if(action != PASS) RETURN(19);
|
if(action != PASS) RETURN(19);
|
||||||
}
|
}
|
||||||
if(param->redirectfunc && param->redirectfunc != tlsprchild){
|
if(param->redirectfunc && param->redirectfunc != tlsprchild){
|
||||||
return (*param->redirectfunc)(param);
|
return (void *)param->redirectfunc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(stlsproto){
|
if(stlsproto){
|
||||||
@ -469,7 +471,6 @@ CLEANRET:
|
|||||||
|
|
||||||
sprintf(req, "%sv%d.%d %s %s", lv<0?"NONE":lv?"TLS":"SSL", lv<0?0:lv?1:3, lv<0?0:lv?lv-1:0, param->hostname?(char *)param->hostname:"-", proto);
|
sprintf(req, "%sv%d.%d %s %s", lv<0?"NONE":lv?"TLS":"SSL", lv<0?0:lv?1:3, lv<0?0:lv?lv-1:0, param->hostname?(char *)param->hostname:"-", proto);
|
||||||
dolog(param, (unsigned char *)req);
|
dolog(param, (unsigned char *)req);
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -87,7 +87,6 @@ CLEANRET:
|
|||||||
_3proxy_sem_unlock(udpinit);
|
_3proxy_sem_unlock(udpinit);
|
||||||
dolog(param, NULL);
|
dolog(param, NULL);
|
||||||
param->clisock = INVALID_SOCKET;
|
param->clisock = INVALID_SOCKET;
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -615,6 +615,5 @@ CLEANRET:
|
|||||||
if(buf) free(buf);
|
if(buf) free(buf);
|
||||||
dolog(param, (unsigned char *)req);
|
dolog(param, (unsigned char *)req);
|
||||||
if(req)free(req);
|
if(req)free(req);
|
||||||
freeparam(param);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user