Compare commits

..

No commits in common. "master" and "v1.10.20210128" have entirely different histories.

27 changed files with 495 additions and 963 deletions

View file

@ -1,56 +0,0 @@
name: Build for Windows
on:
push:
branches:
- '**'
paths-ignore:
- 'README.md'
- 'LICENSE.txt'
- 'RELNOTES'
- 'TODO'
pull_request:
release:
types: [published]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- uses: msys2/setup-msys2@v2
with:
msystem: msys
install: >-
mingw-w64-x86_64-toolchain
gcc
make
openssl
openssl-devel
zip
unzip
xmlto
asciidoc
curl
awk
bash
- name: Build
shell: msys2 {0}
run: |
make
make docs
ldd proxytunnel.exe | grep msys.*\.dll | awk '{print $3}' | xargs cp -t .
zip proxytunnel.zip proxytunnel.exe *.dll docs/proxytunnel.1 docs/*.html
- name: Upload CI Artifact
uses: actions/upload-artifact@v4
with:
name: proxytunnel-${{ github.sha }}-x86_64-windows-msys
path: proxytunnel.zip
- name: Upload to GitHub Release
uses: svenstaro/upload-release-action@v2
if: github.event_name == 'release'
with:
file: proxytunnel.zip
asset_name: proxytunnel-${{ github.ref_name }}-x86_64-windows-msys.zip
tag: ${{ github.ref }}
overwrite: true

4
.gitignore vendored
View file

@ -2,7 +2,3 @@
*.exec
proxytunnel.exe
proxytunnel
passfile
test.sh
docs/*.html
docs/*.1

82
CHANGES Normal file → Executable file
View file

@ -1,85 +1,3 @@
Changes to proxytunnel 1.12.3 -- Fri Mar 7 23:04:25 CET 2025
- PR #83 from https://github.com/tofurky to avoid printing unterminated string
in readline().
- PR #86 from https://github.com/e9hack to fix and improve ntlm authentication.
- PR #89 from https://github.com/njbraun to increase MAX_HEADER_SIZE to 4k.
- From Sven Geuer, https://github.com/68420948
- Chmode 755 to 644 for file CHANGES.
- Drop obsolete entry about SSL proxy support from file TODO.
Changes to proxytunnel 1.12.2 -- Mon Mar 25 14:50:38 CET 2024
- PRs #79 and #80 from https://github.com/hoilc implementing github action to
build windows binary.
Changes to proxytunnel 1.12.1 -- Tue Feb 6 17:36:38 CET 2024
[ Sven Geuer, https://github.com/68420948 ]
- -a/--standalone option:
- Use an AF_INET socket when binding to a specified IPv4 address. This makes
sure IPv4 works regardless of the IPV6_V6ONLY socket option being turned on
or off. Thanks to https://github.com/saper for noting the shortcoming.
- Fix logging of IPv6 clients.
- Close unneeded listening socket in worker.
- Deprecate -L/--tlsenforce and -T/--no-ssl3. SSLv3 has been disabled in likely
all distributions nowadays.
- Apply OPENSSL_VERSION_NUMBER to compile code matching the libssl version in
use. Consequently the file Makefile.ssl11 has been removed.
- Make sure no deprecated libssl functions are called, depending on the libssl
version in use.
- Replace calls to deprecated functions bzero()/bcopy() by memset()/memcpy().
- Update README.md to show recent --help output.
Changes to proxytunnel 1.12.0 -- Sun Dec 17 19:51:57 CET 2023
[ Sven Geuer, https://github.com/68420948 ]
- New: Support authentication by SSL client certificate on SSL encrypted
tunnels, thanks to https://github.com/yayo for providing an initial patch
with issue #76, closes also issue #51.
- New: Listen also for IPv6 connections in standalone mode.
- New: Extend -a/--standalone option to allow for binding to a specified IPv4
or IPv6 address, thanks to https://github.com/saper for providing an initial
implementation with PR #77.
- Honor -o/--host on determining the SNI host name.
- Fix loading REMPROXYUSER/REMPROXYPASS from the environment.
- Update manual page, correct errors, fix typos.
- Minor corrections to README.md
Changes to proxytunnel 1.11.1 -- Mon Oct 16 20:01:04 CEST 2023
[ Sven Geuer, https://github.com/68420948 ]
- Remediate the faulty patch for issue #57, thanks to https://github.com/e9hack
and https://github.com/yurivict for raising issues #59 and #69
- Fix NTLM based authentication on 64bit machines, thanks to
https://github.com/e9hack for raising issue #60
- Harmonize output of option --help and content of the manual page
- Correct formatting errors and typos in the manual page
- Make config.c central for setting version related information in the manual
page and the application
- Return to version number format major.minor.patch
Changes to proxytunnel 1.11 -- Sun Sep 3 12:04:27 AM CEST 2023
- Patch from https://github.com/68420948 to add -4 and -6 options
Changes to proxytunnel 1.10.20220528 -- Sat 28 May 2022 03:54:20 PM CEST
- Patch from https://github.com/ZjYwMj fixes
https://github.com/proxytunnel/proxytunnel/issues/57
Changes to proxytunnel 1.10.20210609 -- Wed Jun 9 11:55:54 CEST 2021
- No functional changes
- Builds have been migrated to travis-ci.com (from .org)
Changes to proxytunnel 1.10.20210128 -- Thu 28 Jan 2021 10:23:24 PM CET
- Changed version to 1.10.20210128
- Applied 2 more debian patches by Julian Gilbey <jdg@debian.org>
- Error handling on SSL_new / SSL_connect
- Allow for longer username/passwords fields (was 24 chars)
Changes to proxytunnel 1.10.20200507 -- Thu 07 May 2020 05:13:01 PM CEST
- Applied 3 patches from debian's package

View file

@ -10,55 +10,6 @@ to build simply run `make` and optionally `make install`.
If you manually want to install, copy proxytunnel to /usr/local/bin
and optionally the manual-page from the debian-subdirectory to your manpath
# Nix Flakes
> NOTE: The Nix Flake installation currently only supports the `x86_64-linux` platform, and has not been tested on other architectures.
A simple Nix Flake is included to allow for use via flake inputs. To create a temporary Nix Shell with access to the `proxytunnel` binary, you can run the command:
```console
nix develop github:proxytunnel/proxytunnel
```
If you instead want to include it as a flake input, the following `flake.nix` shows how to do so:
```nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# Add proxytunnel as an input
proxytunnel.url = "github:proxytunnel/proxytunnel";
};
outputs = {
nixpkgs,
proxytunnel,
...
}: let
system = "x86_64-linux";
pkgs = import nixpkgs {
system = "x86_64-linux";
overlays = [
# Add proxytunnel's default features to your nixpkgs
proxytunnel = proxytunnel.overlays.default;
# For a full list of override options, see `nix/proxytunnel.nix`
];
};
in {
devShells.${system}.default = pkgs.mkShell {
packages = [
# Make the `proxytunnel` binary available in a Nix Shell
# The above overlay adds it to nixpkgs. Without the overlay, use proxytunnel.packages.${system}.default
pkgs.proxytunnel
# And include any other packages as desired...
pkgs.gcc
# ...
];
};
};
}
```
# msys2
To install msys2 with [chocolatey](https://chocolatey.org/install):

View file

@ -14,15 +14,11 @@ OPTFLAGS += -DHAVE_GETOPT_LONG
# Comment if you don't have/want ssl
OPTFLAGS += -DUSE_SSL
# MSYS
# The current version of gcc from MSYS defines __MSYS__ and __CYGWIN__.
# To avoid to change the code, simply define CYGWIN additionally.
ifneq ($(filter $(MSYSTEM),MSYS MINGW32 MINGW64 UCRT64),)
CFLAGS += -DCYGWIN
else
# Most systems, MSYS definitely not
# Most systems
OPTFLAGS += -DSETPROCTITLE -DSPT_TYPE=2
endif
# Comment if you don't have this flag
OPTFLAGS += -DSO_REUSEPORT
# System dependant blocks... if your system is listed below, uncomment
# the relevant lines
@ -33,12 +29,6 @@ endif
# DARWIN
#OPTFLAGS += -DDARWIN
# DARWIN, continued, if compiling for macOS with Homebrew
#CFLAGS += -I/usr/local/opt/openssl/include
#LDFLAGS += -L/usr/local/opt/openssl/lib
#OPTFLAGS += -DDEFAULT_CA_FILE='"/usr/local/etc/openssl@1.1/cacert.pem"'
#OPTFLAGS += -DDEFAULT_CA_DIR=NULL
# CYGWIN
#OPTFLAGS += -DCYGWIN
@ -66,6 +56,7 @@ mandir = $(datadir)/man
OBJ = proxytunnel.o \
base64.o \
strzcat.o \
setproctitle.o \
io.o \
http.o \
basicauth.o \
@ -76,10 +67,6 @@ OBJ = proxytunnel.o \
ntlm.o \
ptstream.o
ifneq (,$(findstring -DSETPROCTITLE,$(OPTFLAGS)))
OBJ += setproctitle.o
endif
UNAME = $(shell uname)
ifneq ($(UNAME),Darwin)
OBJ += strlcpy.o \
@ -94,7 +81,7 @@ docs:
$(MAKE) -C docs
proxytunnel: $(OBJ)
$(CC) -o $(name) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $(OBJ) $(LDFLAGS)
$(CC) -o $(name) $(CFLAGS) $(OPTFLAGS) $(OBJ) $(LDFLAGS)
clean:
@rm -f $(name) $(OBJ)
@ -106,7 +93,7 @@ install:
$(MAKE) -C docs install
.c.o:
$(CC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) -c -o $@ $<
$(CC) $(CFLAGS) $(OPTFLAGS) -c -o $@ $<
dist: clean docs
sed -i -e 's/^Version:.*$$/Version: $(version)/' contrib/proxytunnel.spec

106
Makefile.ssl10 Normal file
View file

@ -0,0 +1,106 @@
# Makefile for proxytunnel
#
# Please uncomment the appropriate settings
name = proxytunnel
version = $(shell awk 'BEGIN { FS="\"" } /^\#define VERSION / { print $$2 }' config.h)
CC ?= cc
CFLAGS ?= -Wall -O2 -ggdb -DOPENSSL10
# Comment on non-gnu systems
OPTFLAGS += -DHAVE_GETOPT_LONG
# Comment if you don't have/want ssl
OPTFLAGS += -DUSE_SSL
# Most systems
OPTFLAGS += -DSETPROCTITLE -DSPT_TYPE=2
# Comment if you don't have this flag
OPTFLAGS += -DSO_REUSEPORT
# System dependant blocks... if your system is listed below, uncomment
# the relevant lines
# OpenBSD
#OPTFLAGS += -DHAVE_SYS_PSTAT_H
# DARWIN
#OPTFLAGS += -DDARWIN
# CYGWIN
#OPTFLAGS += -DCYGWIN
# SOLARIS
#LDFLAGS += -lsocket -lnsl
#LDFLAGS += -L/usr/local/ssl/lib # Path to your SSL lib dir
# END system dependant block
SSL_LIBS := $(shell pkg-config --libs openssl 2>/dev/null)
ifeq ($(SSL_LIBS),)
SSL_LIBS := $(shell pkg-config --libs libssl 2>/dev/null)
endif
ifeq ($(SSL_LIBS),)
SSL_LIBS := -lssl -lcrypto
endif
LDFLAGS += $(SSL_LIBS)
prefix = /usr/local
bindir = $(prefix)/bin
datadir = $(prefix)/share
mandir = $(datadir)/man
# Remove strlcpy/strlcat on (open)bsd/darwin systems
OBJ = proxytunnel.o \
base64.o \
strzcat.o \
setproctitle.o \
io.o \
http.o \
basicauth.o \
globals.o \
readpassphrase.o \
messages.o \
cmdline.o \
ntlm.o \
ptstream.o
UNAME = $(shell uname)
ifneq ($(UNAME),Darwin)
OBJ += strlcpy.o \
strlcat.o
endif
.PHONY: all clean docs install
all: proxytunnel
docs:
$(MAKE) -C docs
proxytunnel: $(OBJ)
$(CC) -o $(name) $(CFLAGS) $(OPTFLAGS) $(OBJ) $(LDFLAGS)
clean:
@rm -f $(name) $(OBJ)
$(MAKE) -C docs clean
install:
install -d $(DESTDIR)$(bindir)
install -p -m555 $(name) $(DESTDIR)$(bindir)
$(MAKE) -C docs install
.c.o:
$(CC) $(CFLAGS) $(OPTFLAGS) -c -o $@ $<
dist: clean docs
sed -i -e 's/^Version:.*$$/Version: $(version)/' contrib/proxytunnel.spec
find . ! -wholename '*/.svn*' | pax -d -w -x ustar -s ,^./,$(name)-$(version)/, | bzip2 >../$(name)-$(version).tar.bz2
rpm: dist
rpmbuild -tb --clean --rmsource --rmspec --define "_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" --define "_rpmdir ../" ../$(name)-$(version).tar.bz2
srpm: dist
rpmbuild -ts --clean --rmsource --rmspec --define "_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" --define "_srcrpmdir ../" ../$(name)-$(version).tar.bz2

106
Makefile.ssl11 Normal file
View file

@ -0,0 +1,106 @@
# Makefile for proxytunnel
#
# Please uncomment the appropriate settings
name = proxytunnel
version = $(shell awk 'BEGIN { FS="\"" } /^\#define VERSION / { print $$2 }' config.h)
CC ?= cc
CFLAGS ?= -Wall -O2 -ggdb -DOPENSSL11
# Comment on non-gnu systems
OPTFLAGS += -DHAVE_GETOPT_LONG
# Comment if you don't have/want ssl
OPTFLAGS += -DUSE_SSL
# Most systems
OPTFLAGS += -DSETPROCTITLE -DSPT_TYPE=2
# Comment if you don't have this flag
OPTFLAGS += -DSO_REUSEPORT
# System dependant blocks... if your system is listed below, uncomment
# the relevant lines
# OpenBSD
#OPTFLAGS += -DHAVE_SYS_PSTAT_H
# DARWIN
#OPTFLAGS += -DDARWIN
# CYGWIN
#OPTFLAGS += -DCYGWIN
# SOLARIS
#LDFLAGS += -lsocket -lnsl
#LDFLAGS += -L/usr/local/ssl/lib # Path to your SSL lib dir
# END system dependant block
SSL_LIBS := $(shell pkg-config --libs openssl 2>/dev/null)
ifeq ($(SSL_LIBS),)
SSL_LIBS := $(shell pkg-config --libs libssl 2>/dev/null)
endif
ifeq ($(SSL_LIBS),)
SSL_LIBS := -lssl -lcrypto
endif
LDFLAGS += $(SSL_LIBS)
prefix = /usr/local
bindir = $(prefix)/bin
datadir = $(prefix)/share
mandir = $(datadir)/man
# Remove strlcpy/strlcat on (open)bsd/darwin systems
OBJ = proxytunnel.o \
base64.o \
strzcat.o \
setproctitle.o \
io.o \
http.o \
basicauth.o \
globals.o \
readpassphrase.o \
messages.o \
cmdline.o \
ntlm.o \
ptstream.o
UNAME = $(shell uname)
ifneq ($(UNAME),Darwin)
OBJ += strlcpy.o \
strlcat.o
endif
.PHONY: all clean docs install
all: proxytunnel
docs:
$(MAKE) -C docs
proxytunnel: $(OBJ)
$(CC) -o $(name) $(CFLAGS) $(OPTFLAGS) $(OBJ) $(LDFLAGS)
clean:
@rm -f $(name) $(OBJ)
$(MAKE) -C docs clean
install:
install -d $(DESTDIR)$(bindir)
install -p -m555 $(name) $(DESTDIR)$(bindir)
$(MAKE) -C docs install
.c.o:
$(CC) $(CFLAGS) $(OPTFLAGS) -c -o $@ $<
dist: clean docs
sed -i -e 's/^Version:.*$$/Version: $(version)/' contrib/proxytunnel.spec
find . ! -wholename '*/.svn*' | pax -d -w -x ustar -s ,^./,$(name)-$(version)/, | bzip2 >../$(name)-$(version).tar.bz2
rpm: dist
rpmbuild -tb --clean --rmsource --rmspec --define "_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" --define "_rpmdir ../" ../$(name)-$(version).tar.bz2
srpm: dist
rpmbuild -ts --clean --rmsource --rmspec --define "_rpmfilename %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm" --define "_srcrpmdir ../" ../$(name)-$(version).tar.bz2

View file

@ -1,7 +1,5 @@
[![Build Status](https://travis-ci.org/proxytunnel/proxytunnel.svg?branch=master)](https://travis-ci.org/proxytunnel/proxytunnel)
[![Maintainers Wanted](https://img.shields.io/badge/maintainers-wanted-red.svg)](https://github.com/pickhardt/maintainers-wanted)
# Proxytunnel
@ -25,40 +23,37 @@ option it specifies it's command-line options.
```
$ ./proxytunnel --help
proxytunnel 1.12.1 Copyright 2001-2024 Proxytunnel Project
proxytunnel 1.9.9 Copyright 2001-2018 Proxytunnel Project
Usage: proxytunnel [OPTIONS]...
Build generic tunnels through HTTPS proxies using HTTP authentication
Standard options:
-i, --inetd Run from inetd (default: off)
-a, --standalone=STRING Run as standalone daemon on specified port or
address:port combination
-a, --standalone=INT Run as standalone daemon on specified port
-p, --proxy=STRING Local proxy host:port combination
-r, --remproxy=STRING Remote proxy host:port combination (using 2 proxies)
-d, --dest=STRING Destination host:port combination
-e, --encrypt SSL encrypt data between local proxy and destination
-E, --encrypt-proxy SSL encrypt data between client and local proxy
-X, --encrypt-remproxy SSL encrypt data between local and remote proxy
Additional options for specific features:
-W, --wa-bug-29744 Workaround ASF Bugzilla 29744: if SSL is active
stop using it after CONNECT (might not work on all
setups)
-W, --wa-bug-29744 workaround ASF Bugzilla 29744, if SSL is active stop
using it after CONNECT (might not work on all setups;
see /usr/share/doc/proxytunnel/README.Debian.gz)
-B, --buggy-encrypt-proxy Equivalent to -E -W, provided for backwards
compatibility
-L (legacy) enforce TLSv1 connection
-T, --no-ssl3 Do not connect using SSLv3
Additional options for specific features:
-z, --no-check-certificate Don't verify server SSL certificate
-C, --cacert=STRING Path to trusted CA certificate or directory
-4, --ipv4 Enforce IPv4 connection to local proxy
-6, --ipv6 Enforce IPv6 connection to local proxy
-F, --passfile=STRING File with credentials for proxy authentication
-P, --proxyauth=STRING Proxy auth credentials user:pass combination
-R, --remproxyauth=STRING Remote proxy auth credentials user:pass combination
-c, --cert=FILENAME client SSL certificate (chain)
-k, --key=FILENAME client SSL key
-N, --ntlm Use NTLM based authentication
-t, --domain=STRING NTLM domain (default: autodetect)
-H, --header=STRING Add additional HTTP headers to send to proxy
-o, --host=STRING Send custom Host Header/SNI
-o STRING send custom Host Header
-x, --proctitle=STRING Use a different process title
Miscellaneous options:
@ -74,14 +69,14 @@ a $HOME/.ssh/config file with the following content:
```
Host foobar
ProtocolKeepAlives 30
ProxyCommand /path/to/proxytunnel -E -p proxy:8080 -P username -d mybox.athome.nl:443
ProxyCommand /path/to/proxytunnel -p proxy:8080 -P username
-d mybox.athome.nl:443
```
With:
```
- foobar The symbolic name of the host you want to connect to
- -E Option to use encryption to communicate to the proxy (use https)
- proxy The host name of the proxy you want to connect through
- 8080 The port number where the proxy software listens to
- username Your proxy userid (password will be prompted)
@ -89,16 +84,12 @@ With:
- 443 The port number of the SSH daemon on mybox.athome.nl
```
Optional arguments:
```
- -z Don't verify server SSL certificate (for example in case of self-signed certificate)
```
If your proxy doesn't require the username and password for using it,
you can skip these options. If you don't provide the password on the
command-line (which is recommended) you will be prompted for it by
proxytunnel. If you are on a trusted system you can also put the
password in the environment variable PROXYPASS.
password in an environment variable, and tell proxytunnel where to
find it with '-S'.
If you want to run proxytunnel from inetd add the '--inetd' option.
@ -116,7 +107,8 @@ auto-detection doesn't work for you (which is usually doesn't)
If you want to have the first proxy connect to another http proxy (like
one you can control, specify -r proxy2:port. The first proxy will then
connect to this remote proxy, which will be asked to connect to the
requested destination. For more information regarding this feature, check
requested destination. Note that authentication doesn't (yet) work on
this remote proxy. For more information regarding this feature, check
out http://dag.wieers.com/howto/ssh-http-tunneling/
If your proxy is more advanced, and does protocol inspection it will

5
TODO
View file

@ -7,6 +7,11 @@
or: proxytunnel -p username:password@local-proxy:port -r username:password@remote-proxy:port -d %h:%p
### SSL proxy support
- Starting with Apache 2.4 using CONNECT over SSL is supported !!
See: http://issues.apache.org/bugzilla/show_bug.cgi?id=29744
### Code cleanup
- Find some hardcore C experts to help us improve the code quality

View file

@ -32,10 +32,10 @@
* is stored in basicauth.
*/
char *basicauth(char *user, char *pass) {
char *b64str = malloc(160);
char *b64str = malloc(80);
int len = strlen( user ) + strlen( pass ) + 2;
char *p = (char *) alloca( len );
char *p = (char *) malloc( len );
/* Set up the cookie in clear text */
sprintf( p, "%s:%s", user, pass );
@ -50,6 +50,8 @@ char *basicauth(char *user, char *pass) {
// message( "Proxy basic auth of %s is %s\n", p, basicauth );
// }
free( p );
return b64str;
}

View file

@ -4,13 +4,13 @@ echo "Build docs..."
make -C docs
echo "Build proxytunnel..."
make -f Makefile
strip -s proxytunnel.exe
make -f Makefile.ssl11
echo "Copy msys/openssl dll to build dir..."
cp /usr/bin/msys-2.0.dll /usr/bin/msys-crypto-1.1.dll /usr/bin/msys-ssl-1.1.dll /usr/bin/msys-z.dll .
echo "Generate proxytunnel.zip with docs, exe and msys/openssl dll..."
zip proxytunnel.zip proxytunnel.exe docs/proxytunnel.1 docs/proxytunnel.1.html docs/proxytunnel-paper.html
DLLS="$(ldd proxytunnel.exe | grep msys.*\.dll | awk '{print $3}' | xargs) /usr/lib/ossl-modules/legacy.dll"
zip proxytunnel.zip -j $DLLS
zip proxytunnel.zip proxytunnel.exe *.dll docs/proxytunnel.1 docs/proxytunnel.1.html docs/proxytunnel-paper.html
if [ ! -z "${TRAVIS_TAG}" ]; then
echo "Deploy proxytunnel.zip to github release tag:${TRAVIS_TAG}..."

239
cmdline.c
View file

@ -38,7 +38,7 @@ extern char * optarg;
static char *getCredentialsFromFile( const char* filename, char **user, char **pass, char **rem_user, char **rem_pass);
void cmdline_parser_print_version (void) {
printf ("%s %s Copyright 2001-%s Proxytunnel Project\n", PACKAGE, VERSION, VERSION_YEAR);
printf ("%s %s Copyright 2001-2020 Proxytunnel Project\n", PACKAGE, VERSION);
}
void cmdline_parser_print_help (void) {
@ -50,9 +50,8 @@ void cmdline_parser_print_help (void) {
"Standard options:\n"
// FIXME: " -c, --config=FILE Read config options from file\n"
" -i, --inetd Run from inetd (default: off)\n"
" -a, --standalone=STRING Run as standalone daemon on specified port or\n"
" address:port combination\n"
// FIXME: " -f, --nobackground Don't fork to background in standalone mode\n"
" -a, --standalone=INT Run as standalone daemon on specified port\n"
// FIXME: " -f, --nobackground Don't for tok background in standalone mode\n"
" -p, --proxy=STRING Local proxy host:port combination\n"
" -r, --remproxy=STRING Remote proxy host:port combination (using 2 proxies)\n"
" -d, --dest=STRING Destination host:port combination\n"
@ -60,29 +59,23 @@ void cmdline_parser_print_help (void) {
" -e, --encrypt SSL encrypt data between local proxy and destination\n"
" -E, --encrypt-proxy SSL encrypt data between client and local proxy\n"
" -X, --encrypt-remproxy SSL encrypt data between local and remote proxy\n"
" -W, --wa-bug-29744 Workaround ASF Bugzilla 29744: if SSL is active stop\n"
" using it after CONNECT (might not work on all setups; see\n"
" /usr/share/doc/proxytunnel/README.Debian.gz)\n"
" -B, --buggy-encrypt-proxy Equivalent to -E -W, provided for backwards\n"
" compatibility\n"
" -L (legacy) enforce TLSv1 connection\n"
" -T, --no-ssl3 Do not connect using SSLv3\n"
#endif
"\n"
"Additional options for specific features:\n"
#ifdef USE_SSL
" -W, --wa-bug-29744 Workaround ASF Bugzilla 29744: if SSL is active\n"
" stop using it after CONNECT (might not work on all\n"
" setups)\n"
" -B, --buggy-encrypt-proxy Equivalent to -E -W, provided for backwards\n"
" compatibility\n"
/*" -L, --tlsenforce Enforce TLSv1 connection (legacy)\n"
" -T, --no-ssl3 Do not connect using SSLv3 (legacy)\n"*/
" -z, --no-check-certificate Don't verify server SSL certificate\n"
" -C, --cacert=STRING Path to trusted CA certificate or directory\n"
#endif
" -4, --ipv4 Enforce IPv4 connection to local proxy\n"
" -6, --ipv6 Enforce IPv6 connection to local proxy\n"
" -F, --passfile=STRING File with credentials for proxy authentication\n"
" -P, --proxyauth=STRING Proxy auth credentials user:pass combination\n"
" -R, --remproxyauth=STRING Remote proxy auth credentials user:pass combination\n"
#ifdef USE_SSL
" -c, --cert=FILENAME client SSL certificate (chain)\n"
" -k, --key=FILENAME client SSL key\n"
#endif
// " -u, --user=STRING Username for proxy authentication\n"
// " -s, --pass=STRING Password for proxy authentication\n"
// " -U, --uservar=STRING Environment variable that holds username\n"
@ -90,11 +83,7 @@ void cmdline_parser_print_help (void) {
" -N, --ntlm Use NTLM based authentication\n"
" -t, --domain=STRING NTLM domain (default: autodetect)\n"
" -H, --header=STRING Add additional HTTP headers to send to proxy\n"
#ifdef USE_SSL
" -o, --host=STRING Send custom Host Header/SNI\n"
#else
" -o, --host=STRING Send custom Host Header\n"
#endif
" -o STRING send custom Host Header\n"
#ifdef SETPROCTITLE
" -x, --proctitle=STRING Use a different process title\n"
#endif
@ -146,22 +135,17 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
args_info->remproxy_given = 0;
args_info->remproxyauth_given = 0;
args_info->verbose_given = 0;
args_info->quiet_given = 0;
args_info->ntlm_given = 0;
args_info->inetd_given = 0;
args_info->standalone_given = 0;
args_info->standalone_addr_given = 0;
args_info->standalone_iface_given = 0;
args_info->quiet_given = 0;
args_info->header_given = 0;
args_info->domain_given = 0;
args_info->encrypt_given = 0;
args_info->encryptproxy_given = 0;
args_info->encryptremproxy_given = 0;
args_info->clientcert_given = 0;
args_info->clientkey_given = 0;
args_info->wa_bug_29744_given = 0;
args_info->proctitle_given = 0;
/* args_info->enforcetls1_given = 0; */
args_info->enforcetls1_given = 0;
args_info->host_given = 0;
args_info->cacert_given = 0;
@ -181,27 +165,20 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
args_info->remproxyauth_arg = NULL; \
args_info->header_arg[0] = '\0'; \
args_info->verbose_flag = 0; \
args_info->quiet_flag = 0; \
args_info->ntlm_flag = 0; \
args_info->inetd_flag = 0; \
args_info->standalone_arg = NULL; \
args_info->standalone_addr = NULL; \
args_info->standalone_iface = NULL; \
args_info->standalone_port = 0; \
args_info->quiet_flag = 0; \
args_info->standalone_arg = 0; \
args_info->encrypt_flag = 0; \
args_info->encryptproxy_flag = 0; \
args_info->encryptremproxy_flag = 0; \
args_info->clientcert_arg = NULL; \
args_info->clientkey_arg = NULL; \
args_info->wa_bug_29744_flag = 0; \
/* args_info->no_ssl3_flag = 0; */\
args_info->no_ssl3_flag = 0; \
args_info->proctitle_arg = NULL; \
/* args_info->enforcetls1_flag = 0; */\
args_info->enforcetls1_flag = 0; \
args_info->host_arg = NULL; \
args_info->no_check_cert_flag = 0; \
args_info->cacert_arg = NULL; \
args_info->enforceipv4_flag = 0; \
args_info->enforceipv6_flag = 0; \
}
clear_args();
@ -222,7 +199,11 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
static struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' },
{ "user", 1, NULL, 'u' },
{ "pass", 1, NULL, 's' },
{ "domain", 1, NULL, 't' },
// { "uservar", 1, NULL, 'U' },
// { "passvar", 1, NULL, 'S' },
{ "passfile", 1, NULL, 'F' },
{ "proxy", 1, NULL, 'p' },
{ "proxyauth", 1, NULL, 'P' },
@ -231,7 +212,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
{ "remproxyauth", 1, NULL, 'R' },
{ "proctitle", 1, NULL, 'x' },
{ "host", 1, NULL, 'o' },
{ "tlsenforce", 0, NULL, 'L' },
{ "tlsenforce", 1, NULL, 'L' },
{ "header", 1, NULL, 'H' },
{ "verbose", 0, NULL, 'v' },
{ "ntlm", 0, NULL, 'N' },
@ -241,21 +222,17 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
{ "encrypt", 0, NULL, 'e' },
{ "encrypt-proxy", 0, NULL, 'E' },
{ "encrypt-remproxy",0,NULL, 'X' },
{ "cert", 1, NULL, 'c' },
{ "key", 1, NULL, 'k' },
{ "wa-bug-29744", 0, NULL, 'W' },
{ "buggy-encrypt-proxy", 0, NULL, 'B' },
{ "no-ssl3", 0, NULL, 'T' },
{ "no-check-certificate",0,NULL,'z' },
{ "cacert", 1, NULL, 'C' },
{ "ipv4", 0, NULL, '4' },
{ "ipv6", 0, NULL, '6' },
{ NULL, 0, NULL, 0 }
};
c = getopt_long (argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:c:k:vNeEXWBqLo:TzC:46", long_options, &option_index);
c = getopt_long (argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:nvNeEXWBqLo:TzC:", long_options, &option_index);
#else
c = getopt( argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:c:k:vNeEXWBqLo:TzC:46" );
c = getopt( argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:nvNeEXWBqLo:TzC:" );
#endif
if (c == -1)
@ -280,26 +257,6 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
message("SSL client to proxy enabled\n");
break;
case 'c': /* client SSL certificate (chain) */
if (args_info->clientcert_given) {
fprintf (stderr, "%s: '--cert' ('-c') option given more than once\n", PACKAGE);
clear_args ();
exit(1);
}
args_info->clientcert_given = 1;
args_info->clientcert_arg = gengetopt_strdup (optarg);
break;
case 'k': /* client SSL key */
if (args_info->clientkey_given) {
fprintf (stderr, "%s: '--key' ('-k') option given more than once\n", PACKAGE);
clear_args ();
exit(1);
}
args_info->clientkey_given = 1;
args_info->clientkey_arg = gengetopt_strdup (optarg);
break;
case 'W': /* if SSL is active stop it after CONNECT */
args_info->wa_bug_29744_flag = !(args_info->wa_bug_29744_flag);
if( args_info->verbose_flag )
@ -324,18 +281,16 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
break;
case 'a': /* Run as standalone daemon */
if (args_info->standalone_given) {
fprintf (stderr, "%s: '--standalone' ('-a') option given more than once\n", PACKAGE);
clear_args ();
exit(1);
}
if ( args_info->inetd_flag ) {
fprintf( stderr, "%s: `--standalone' (`-a') conflicts with `--inetd' (`-i')\n", PACKAGE );
clear_args();
exit(1);
}
args_info->standalone_given = 1;
args_info->standalone_arg = gengetopt_strdup (optarg);
if ( ( args_info->standalone_arg = atoi( optarg ) ) < 1 ) {
fprintf( stderr, "%s: Illegal port value for `--standalone' (`-a')\n", PACKAGE);
clear_args();
exit(1);
}
break;
case 'V': /* Print version and exit. */
@ -350,18 +305,40 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
break;
case 'L':
/* args_info->enforcetls1_given = 1;
message("Enforcing TLSv1\n");
args_info->enforcetls1_flag = 1; */
message ("Option -L/--tlsenforce is deprecated and without effect\n");
args_info->enforcetls1_given = 1;
message("Enforcing TLSv1");
args_info->enforcetls1_flag = 1;
break;
case 'o':
args_info->host_given = 1;
message("Host-header/SNI override enabled\n");
message("Host-header override enabled\n");
args_info->host_arg = gengetopt_strdup (optarg);
break;
case 'u': /* Username to send to HTTPS proxy for authentication. */
if (args_info->user_given) {
fprintf (stderr, "%s: `--user' (`-u'), `--proxyauth' (`-P') or `--passfile' (`-F') option given more than once\n", PACKAGE);
clear_args ();
exit(1);
}
args_info->user_given = 1;
args_info->user_arg = gengetopt_strdup (optarg);
message ("Option -u/--user is deprecated, please use -P/--proxyauth user:pass\n");
break;
case 's': /* Password to send to HTTPS proxy for authentication. */
if (args_info->pass_given) {
fprintf (stderr, "%s: `--pass' (`-s') or `--passfile' (`-F') option given more than once\n", PACKAGE);
clear_args ();
exit(1);
}
args_info->pass_given = 1;
args_info->pass_arg = gengetopt_strdup (optarg);
message ("Option -s/--pass is deprecated, please use -P/--proxyauth user:pass\n");
break;
case 't': /* Env Var with NTLM DOMAIN (when overriding). */
if (args_info->domain_given) {
fprintf (stderr, "%s: `--domain' (`-t') option given more than once\n", PACKAGE);
@ -448,10 +425,9 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
break;
case 'T': /* Turn off SSLv3 */
/* args_info->no_ssl3_flag = !(args_info->no_ssl3_flag);
args_info->no_ssl3_flag = !(args_info->no_ssl3_flag);
if( args_info->verbose_flag )
message("SSLv3 disabled\n"); */
message ("Option -T/--no-ssl3 is deprecated and without effect\n");
message("SSLv3 disabled\n");
break;
case 'd': /* Destination host to built the tunnel to. */
@ -502,28 +478,6 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
args_info->cacert_arg = gengetopt_strdup (optarg);
break;
case '4': /* Enforce IPv4 */
if ( args_info->enforceipv6_flag ) {
fprintf( stderr, "%s: `--ipv4' (`-4') conflicts with `--ipv6' (`-6')\n", PACKAGE );
clear_args();
exit(1);
}
args_info->enforceipv4_flag = 1;
if( args_info->verbose_flag )
message("IPv4 enforced\n");
break;
case '6': /* Enforce IPv6 */
if ( args_info->enforceipv4_flag ) {
fprintf( stderr, "%s: `--ipv6' (`-6') conflicts with `--ipv4' (`-4')\n", PACKAGE );
clear_args();
exit(1);
}
args_info->enforceipv6_flag = 1;
if( args_info->verbose_flag )
message("IPv6 enforced\n");
break;
case 0: /* Long option with no short option */
case '?': /* Invalid option. */
@ -566,7 +520,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
if ( args_info->remuser_arg == NULL ) {
if ( (tmp = getenv("REMPROXYUSER")) != NULL ) {
args_info->remuser_given = 1;
args_info->remuser_arg = gengetopt_strdup (tmp);
args_info->user_arg = gengetopt_strdup (tmp);
if( args_info->verbose_flag )
message( "Found remote user '%s' in env variable REMPROXYPASS.\n", args_info->remuser_arg);
}
@ -574,7 +528,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
if ( args_info->rempass_arg == NULL ) {
if ( (tmp = getenv("REMPROXYPASS")) != NULL ) {
args_info->rempass_given = 1;
args_info->rempass_arg = gengetopt_strdup (tmp);
args_info->user_arg = gengetopt_strdup (tmp);
if( args_info->verbose_flag )
message( "Found remote password in env variable REMPROXYPASS.\n" );
}
@ -596,20 +550,13 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
}
}
if (! args_info->proxy_given || ! args_info->dest_given ) {
if (! args_info->proxy_given && ! args_info->dest_given ) {
clear_args ();
// cmdline_parser_print_help ();
message( "No proxy or destination given, exiting\nUse '--help' flag for usage info\n" );
exit(1);
}
if ( args_info->clientcert_given ^ args_info->clientkey_given ) {
clear_args ();
message( "Both of '--cert' ('-c') and '--key' ('-k') must be specified\n" );
exit(1);
}
/* Parse -p/--proxy information */
if (args_info->proxy_given ) {
char proxy_arg_fmt[32];
size_t proxy_arg_len;
@ -634,56 +581,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
args_info->proxyhost_given = 1;
args_info->proxyport_given = 1;
} else {
message( "parse_cmdline: specified proxy (%s) does not fit the expected pattern hostname/ip:port\n", args_info->proxy_arg );
missing_required_options++;
}
}
/* Parse -a/--standalone information */
if ( args_info->standalone_given ) {
char standalone_arg_fmt[32];
size_t standalone_arg_len;
char *aaddr;
char *aiface;
int aport;
standalone_arg_len = strlen( args_info->standalone_arg );
if ( (aaddr = malloc( standalone_arg_len + 1 )) == NULL ) {
message( "Out of memory\n" );
exit(1);
}
if ( (aiface = malloc( standalone_arg_len + 1 )) == NULL ) {
message( "Out of memory\n" );
exit(1);
}
/* try IPv4 literal and port */
snprintf( standalone_arg_fmt, sizeof(standalone_arg_fmt), "%%%zu[0-9.]:%%5u", standalone_arg_len - 1 );
r = sscanf( args_info->standalone_arg, standalone_arg_fmt, aaddr, &aport );
if ( r != 2 ) {
/* try bracket-enclosed IPv6 literal and port */
snprintf( standalone_arg_fmt, sizeof(standalone_arg_fmt), "[%%%zu[0-9A-Fa-f:]]:%%5u", standalone_arg_len - 1 );
r = sscanf( args_info->standalone_arg, standalone_arg_fmt, aaddr, &aport );
}
if ( r != 2 ) {
/* try bracket-enclosed IPv6 literal, interface and port */
snprintf( standalone_arg_fmt, sizeof(standalone_arg_fmt), "[%%%zu[0-9A-Fa-f:]%%%%%%%zu[^]]]:%%5u", standalone_arg_len - 1, standalone_arg_len - 1 );
if ( sscanf( args_info->standalone_arg, standalone_arg_fmt, aaddr, aiface, &aport ) == 3 )
r = 3;
}
if ( r == 3 ) {
args_info->standalone_iface = aiface;
args_info->standalone_iface_given = 1;
r--;
}
if ( r == 2 ) {
args_info->standalone_addr = aaddr;
args_info->standalone_port = aport;
args_info->standalone_addr_given = 1;
/* try port only */
} else if ( sscanf( args_info->standalone_arg, "%5u", &aport ) ) {
args_info->standalone_port = aport;
} else {
message( "parse_cmdline: specified standalone argument (%s) does not fit one of the expected patterns: port, ipv4:port, [ipv6]:port, [ipv6%%interface]:port\n", args_info->standalone_arg );
message( "parse_cmdline: could not find your proxy hostname/ip (%s)\n", args_info->proxy_arg );
missing_required_options++;
}
}
@ -693,10 +591,10 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
char *puser = NULL;
char *ppass = NULL;
puser = malloc( 80+1 );
ppass = malloc( 80+1 );
puser = malloc( 24+1 );
ppass = malloc( 24+1 );
r = sscanf( args_info->proxyauth_arg, "%80[^:]:%80s", puser, ppass );
r = sscanf( args_info->proxyauth_arg, "%24[^:]:%24s", puser, ppass );
if ( r == 2 ) {
args_info->user_arg = puser;
args_info->pass_arg = ppass;
@ -716,10 +614,10 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
char *ruser = NULL;
char *rpass = NULL;
ruser = malloc( 80+1 );
rpass = malloc( 80+1 );
ruser = malloc( 24+1 );
rpass = malloc( 24+1 );
r = sscanf( args_info->remproxyauth_arg, "%80[^:]:%80s", ruser, rpass );
r = sscanf( args_info->remproxyauth_arg, "%24[^:]:%24s", ruser, rpass );
if ( r == 2 ) {
args_info->remuser_arg = ruser;
args_info->rempass_arg = rpass;
@ -733,7 +631,6 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
missing_required_options++;
}
}
if ( missing_required_options )
exit(1);

View file

@ -23,7 +23,7 @@
#ifndef _cmdline_h
#define _cmdline_h
#define MAX_HEADER_SIZE 4096
#define MAX_HEADER_SIZE 1024
struct gengetopt_args_info {
char *user_arg; /* Username to send to HTTPS proxy for auth. */
@ -40,26 +40,19 @@ struct gengetopt_args_info {
char *remproxy_arg; /* Remote proxy to tunnel to. */
char *remproxyauth_arg; /* Remote proxy auth. */
int verbose_flag; /* Turn on verbosity (default=off). */
int quiet_flag; /* Turn on quiet mode (default=off). */
int ntlm_flag; /* Turn on ntlm (default=off). */
int inetd_flag; /* Turn on inetd (default=off). */
char *standalone_arg; /* Turn on standalone (-a) on [addr:]port */
char *standalone_addr;
char *standalone_iface;
int standalone_port;
int quiet_flag; /* Turn on quiet mode (default=off). */
int standalone_arg; /* Turn on stdalone (-a) on port */
int encrypt_flag; /* Turn on SSL encryption (default=off). */
int encryptproxy_flag; /* Turn on client to proxy SSL encryption (def=off).*/
int encryptremproxy_flag; /* Turn on local to remote proxy SSL encryption (def=off).*/
char *clientcert_arg; /* client SSL certificate */
char *clientkey_arg; /* client SSL key */
int wa_bug_29744_flag; /* Use SSL encryption only until CONNECT, if at all (def=off).*/
/* int no_ssl3_flag; Turn off SSLv3 (default=on) */
int no_ssl3_flag; /* Turn off SSLv3 (default=on) */
char *proctitle_arg; /* Override process title (default=off). */
/* int enforcetls1_flag; Override default and enforce TLSv1 */
int enforcetls1_flag; /* Override default and enforce TLSv1 */
char *host_arg; /* Optional Host Header */
int no_check_cert_flag; /* Turn off server SSL certificate verification (default=on) */
int enforceipv4_flag; /* Enforce IPv4 (default=off). */
int enforceipv6_flag; /* Enforce IPv6 (default=off). */
char *cacert_arg; /* Trusted CA certificate (or directory) for server SSL certificate verification */
int help_given; /* Whether help was given. */
int version_given; /* Whether version was given. */
@ -76,21 +69,16 @@ struct gengetopt_args_info {
int remproxy_given; /* Whether remproxy was given. */
int remproxyauth_given; /* Whether remproxy was given. */
int verbose_given; /* Whether verbose was given. */
int quiet_given; /* Whether quiet mode was given. */
int ntlm_given; /* Whether ntlm was given. */
int inetd_given; /* Whether inetd was given. */
int standalone_given; /* Whether standalone was given */
int standalone_addr_given; /* Whether standalone address was given */
int standalone_iface_given; /* Whether standalone interface was given */
int quiet_given; /* Whether quiet mode was given. */
int header_given; /* Whether extra headers are given */
int encrypt_given; /* Whether encrypt was given */
int encryptproxy_given; /* Whether encrypt was given */
int encryptremproxy_given; /* Whether encrypt was given */
int clientcert_given; /* Whether client SSL certificate was given */
int clientkey_given; /* Whether client SSL key was given */
int wa_bug_29744_given; /* Whether work around was given */
int proctitle_given; /* Whether to override process title */
/* int enforcetls1_given; Wheter to enforce TLSv1 */
int enforcetls1_given; /* Wheter to enforce TLSv1 */
int host_given; /* Wheter we override the Host Header */
int cacert_given; /* Whether cacert was given */
};

View file

@ -1,5 +1,5 @@
/* Proxytunnel - (C) 2001-2023 Jos Visser / Mark Janssen */
/* Contact: josv@osp.nl / mark@sig-io.nl */
/* Proxytunnel - (C) 2001-2008 Jos Visser / Mark Janssen */
/* Contact: josv@osp.nl / maniac@maniac.nl */
/*
* This program is free software; you can redistribute it and/or modify
@ -17,9 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define VERSION "1.12.3"
#define VERSION_YEAR "2025"
#define VERSION_DATE "2025-03-07"
#define VERSION "1.10.20210128"
#define PACKAGE "proxytunnel"
#define PURPOSE "Build generic tunnels through HTTPS proxies"
#define AUTHORS "Jos Visser (Muppet) <josv@osp.nl>, Mark Janssen (Maniac) <maniac@maniac.nl>"

View file

@ -5,9 +5,6 @@ mandir = $(datadir)/man
adoctargets = $(shell echo *.adoc)
htmltargets = $(patsubst %.adoc, %.html, $(adoctargets))
version = $(shell grep ' VERSION ' ../config.h | cut -d'"' -f2)
version_date = $(shell grep ' VERSION_DATE ' ../config.h | cut -d'"' -f2)
docs: proxytunnel.1 $(htmltargets)
install: proxytunnel.1
@ -18,7 +15,7 @@ clean:
rm -f proxytunnel.1 *.html *.xml
%.1.html: %.1.adoc
asciidoc -d manpage -arevnumber=$(version) -arevdate=$(version_date) $<
asciidoc -d manpage $<
%.1: %.1.xml
xmlto man $<
@ -27,4 +24,4 @@ clean:
asciidoc $<
%.1.xml: %.1.adoc
asciidoc -b docbook -d manpage -arevnumber=$(version) -arevdate=$(version_date) $<
asciidoc -b docbook -d manpage $<

View file

@ -1,4 +1,6 @@
= proxytunnel(1)
Proxytunnel developers
v1.9.0, Augustus 2008
== NAME
@ -6,7 +8,7 @@ proxytunnel - program to tunnel a connection through a standard HTTPS proxy
== SYNOPSIS
*proxytunnel* [_OPTION…_]
*proxytunnel* _[OPTION]_...
== DESCRIPTION
@ -19,48 +21,44 @@ also be used for other proxy-traversing purposes like proxy bouncing.
== OPTIONS
*-i*, *--inetd*::
Run from inetd (default: off).
Run from inetd (default: off)
*-a*, *--standalone*=++[++_address_++:]++_port_::
Run as standalone daemon on specified _address_ and _port_. _address_ may
be a IPv4 address, a bracket-enclosed IPv6 address or a bracket-enclosed
combination of IPv6 address, \'%' and interface name. The latter format is
only required with link-local IPv6 addresses. The daemon listens on any
address if _address_ is not given.
*Examples*:::
22, 123.45.67.89:22, [2001:db8::123:4567:89ab:cdef]:22,
[2001:db8::123:4567:89ab:cdef%eth0]:22
*-a*, *--standalone*=_port_::
Run as standalone daemon on specified _port_
*-p*, *--proxy*=_host_++:++_port_::
Use _host_ and _port_ as the local (primary) proxy to connect to, if not
specified the *HTTP_PROXY* environment variable, if set, will be used
instead. This option or the environment variable are mandatory.
*-p*, *--proxy*=_host_:_port_::
Use _host_ and _port_ as the local proxy to connect to, if not specified
the *HTTP_PROXY* environment variable, if set, will be used instead
*-r*, *--remproxy*=_host_++:++_port_::
Use _host_ and _port_ as the remote (secondary) proxy to connect to.
*-r*, *--remproxy*=_host_:_port_::
Use _host_ and _port_ as the remote (secondary) proxy to connect to
*-d*, *--dest*=_host_++:++_port_::
Use _host_ and _port_ as the destination for the tunnel. This is a
mandatory option.
*-d*, *--dest*=_host_:_port_::
Use _host_ and _port_ as the destination for the tunnel, you can also
specify them as the argument to the proxytunnel command
*-e*, *--encrypt*::
SSL encrypt data between local proxy and destination.
SSL encrypt data between local proxy and destination
*-E*, *--encrypt-proxy*::
SSL encrypt data between client and local proxy.
SSL encrypt data between client and local proxy
*-X*, *--encrypt-remproxy*::
SSL encrypt data between local and remote (secondary) proxy.
SSL encrypt data between local and remote (secondary) proxy
*-W*, *--wa-bug-29744*::
If SSL is in use (by *-e*, *-E*, *-X* options), stop using it
immediately after the CONNECT exchange to workaround apache server
bugs. (This might not work on all setups; see
/usr/share/doc/proxytunnel/README.Debian.gz for more details.)
*-B*, *--buggy-encrypt-proxy*::
Equivalent to *-E -W*. (Provided for backwards compatibility.)
== ADDITIONAL OPTIONS
*-W*, *--wa-bug-29744*::
Workaround ASF Bugzilla 29744: If SSL is in use (by *-e*, *-E*, *-X*
options), stop using it immediately after the CONNECT exchange to
workaround apache server bugs (This might not work on all setups).
*-B*, *--buggy-encrypt-proxy*::
Equivalent to *-E -W* (Provided for backwards compatibility).
*-T*, *--no-ssl3*::
Prevent the use of SSLv3 in encrypted connections (default: enabled)
*-z*, *--no-check-certificate*::
Do not verify server SSL certificate when establishing an SSL connection.
@ -71,84 +69,63 @@ also be used for other proxy-traversing purposes like proxy bouncing.
*-C*, *--cacert*=_filename/directory_::
Specify a CA certificate file (or directory containing CA certificate(s))
to trust when verifying a server SSL certificate. If a directory is provided,
it must be prepared with OpenSSL's c_rehash tool (default, unless changed at
compile time using DEFAULT_CA_FILE or DEFAULT_CA_DIR options: /etc/ssl/certs).
*-4*, *--ipv4*::
Enforce the use of IPv4 when connecting to the local proxy.
*-6*, *--ipv6*::
Enforce the use of IPv6 when connecting to the local proxy.
it must be prepared with OpenSSL's c_rehash tool. (default: /etc/ssl/certs)
*-F*, *--passfile*=_filename_::
Use _filename_ for reading username and password for HTTPS proxy
authentication, the file uses the same format as .wgetrc and can be shared
with wget. Use this option, or environment variables to hide the password
from other users.
from other users
*-P*, *--proxyauth*=_username_++:++_password_::
*-P*, *--proxyauth*=_username_:_password_::
Use _username_ and _password_ as credentials to authenticate against a
local HTTPS proxy, the username and password can also be specified in
the *PROXYUSER* and *PROXYPASS* environment variables to hide them from
other users.
If the _password_ is omitted and no *PROXYPASS* environment variable is
set, proxytunnel will prompt for a password.
set, proxytunnel will prompt for a password
*-R*, *--remproxyauth*=_username_++:++_password_::
*-R*, *--remproxyauth*=_username_:_password_::
Use _username_ and _password_ as credentials to authenticate against a
remote (secondary) HTTPS proxy, the username and password can also be
specified in the *REMPROXYUSER* and *REMPROXYPASS* environment variables
to hide them from other users.
If the _password_ is omitted and no *REMPROXYPASS* environment variable is
set, proxytunnel will prompt for a password.
*-c*, *--cert*=_filename_::
Provide the name of the file containing the SSL client certificate to
authenticate by client certificate against local proxy, remote proxy or
destination. The file must be in PEM format.
On top of this it may contain one or more intermediary certificates missing
at the servers's end, effectively forming a certificate chain.
Requires specification of *-k*, *--key* in addition.
Ignored if neither *-e*, *--encrypt* nor *-E*, *--encrypt-proxy* nor
*-X*, *--encrypt-remproxy* is given.
*-k*, *--key*=_filename_::
Provide the name of the file containing the SSL client key to authenticate
by client certificate against local proxy, remote proxy or destination. The
file must be in PEM format.
Requires specification of *-c*, *--cert* in addition.
Ignored if neither *-e*, *--encrypt* nor *-E*, *--encrypt-proxy* nor
*-X*, *--encrypt-remproxy* is given.
set, proxytunnel will prompt for a password
*-N*, *--ntlm*::
Use NTLM based authentication.
Use NTLM basd authentication
*-t*, *--domain*=_STRING_::
Specify NTLM domain (default: autodetect).
Specify NTLM domain (default: autodetect)
*-H*, *--header*=_STRING_::
Add additional HTTP headers to send to proxy.
*-o*, *--host*=_host_++[:++_port_]::
Send a custom Host header. With SSL connections _host_ is also sent as SNI.
Add additional HTTP headers to send to proxy
*-x*, *--proctitle*=_STRING_::
Use a different process title.
Use a different process title
== MISCELLANEOUS OPTIONS
*-v*, *--verbose*::
Turn on verbosity.
Turn on verbosity
*-q*, *--quiet*::
Suppress messages.
Suppress messages
*-h*, *--help*::
Print help and exit.
Print help and exit
*-V*, *--version*::
Print version and exit.
Print version and exit
== ARGUMENTS
_host_:_port_ is the destination hostname and port number combination
NOTE: Specifying the destination as arguments is exactly the same as
specifying them using the *-d* or *--dest* option.
== USAGE
@ -188,7 +165,7 @@ Host system.athome.nl
NOTE: The +ServerAliveInterval+ directive makes sure that idle connections are
not being dropped by intermediate firewalls that remove active sessions
aggressively. If you see your connection dropping out, try to lower the value
aggresively. If you see your connection dropping out, try to lower the value
even more.
To use the dynamic (SOCKS) portforwarding capability of the SSH client, you
@ -215,27 +192,27 @@ variables:
*HTTP_PROXY*::
If this environment variable is set, proxytunnel will use it as the
_local proxy_ if *-p* or *--proxy* is not provided.
_local proxy_ if *-p* or *--proxy* is not provided
*PROXYUSER*::
If this environment variable is set, proxytunnel will use it as the
_username_ for proxy authentication, unless specified using the *-P* or
*--proxyauth* option.
*--proxyauth* option
*PROXYPASS*::
If this environment variable is set, proxytunnel will use it as the
_password_ for proxy authentication, unless specified using the *-P* or
*--proxyauth* option.
*--proxyauth* option
*REMPROXYUSER*::
If this environment variable is set, proxytunnel will use it as the
_username_ for remote (secondary) proxy authentication, unless specified
using the *-R* or *--remproxyauth* option.
using the *-R* or *--remproxyauth* option
*REMPROXYPASS*::
If this environment variable is set, proxytunnel will use it as the
_password_ for remote (secondary) proxy authentication, unless specified
using the *-R* or *--remproxyauth* option.
using the *-R* or *--remproxyauth* option
== SEE ALSO
@ -244,8 +221,7 @@ variables:
== BUGS
This software is bug-free, at least we'd like to think so. If you do not
agree with us, please provide the proof with your friendly report at
https://github.com/proxytunnel/proxytunnel/issues :)
agree with us, please attach the proof to your friendly email :)
== AUTHOR
@ -254,4 +230,4 @@ This manpage was initially written by Loïc Le Guyader
asciidoc by Dag Wieërs <dag@wieers.com> and is now maintained by the
Proxytunnel developers.
Homepages at https://proxytunnel.sourceforge.io and https://github.com/proxytunnel/proxytunnel
Homepage at http://proxytunnel.sourceforge.net/

61
flake.lock generated
View file

@ -1,61 +0,0 @@
{
"nodes": {
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1743550720,
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1743583204,
"narHash": "sha256-F7n4+KOIfWrwoQjXrL2wD9RhFYLs2/GGe/MQY1sSdlE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "2c8d3f48d33929642c1c12cd243df4cc7d2ce434",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1743296961,
"narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixpkgs.lib",
"type": "github"
}
},
"root": {
"inputs": {
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

View file

@ -1,33 +0,0 @@
{
description = "Basic flake that provides proxytunnel as a package or as a binary in a nix shell";
inputs = {
flake-parts.url = "github:hercules-ci/flake-parts";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = inputs @ {flake-parts, ...}:
flake-parts.lib.mkFlake {inherit inputs;} {
# TODO: Add support for more systems once checked.
systems = ["x86_64-linux"];
imports = [inputs.flake-parts.flakeModules.easyOverlay];
perSystem = {
config,
pkgs,
...
}: {
overlayAttrs = {
inherit (config.packages) proxytunnel;
};
packages.proxytunnel = pkgs.callPackage ./nix/proxytunnel.nix {};
packages.default = config.packages.proxytunnel;
devShells.default = pkgs.mkShell {
packages = [config.packages.default];
};
};
};
}

18
http.c
View file

@ -37,16 +37,17 @@
* header
*/
void analyze_HTTP(PTSTREAM *pts) {
char *p;
char *p = strtok( buf, " ");
/* Strip html error pages for faulty proxies (Stephane Engel <steph[at]macchiati.org>) */
do {
if (readline(pts) <= 0) {
while (strncmp( p, "HTTP/", 5) != 0 ) {
if ( readline(pts) ) {
p = strtok( buf, " ");
} else {
message( "analyze_HTTP: readline failed: Connection closed by remote host\n" );
exit(2);
}
p = strtok( buf, " \t");
} while (strncmp( p, "HTTP/", 5) != 0 );
}
if (strcmp( p, "HTTP/1.0" ) != 0 && strcmp( p, "HTTP/1.1" ) != 0) {
message( "Unsupported HTTP version number %s\n", p );
@ -116,7 +117,6 @@ void proxy_protocol(PTSTREAM *pts) {
if (args_info.ntlm_flag) {
if (ntlm_challenge == 1) {
build_type3_response();
ntlm_challenge = 2;
strzcat( buf, "Proxy-Authorization: NTLM %s\r\n", ntlm_type3_buf );
} else if (ntlm_challenge == 0) {
strzcat( buf, "Proxy-Authorization: NTLM %s\r\n", ntlm_type1_buf );
@ -157,7 +157,7 @@ void proxy_protocol(PTSTREAM *pts) {
/* Read the first line of the response and analyze it */
analyze_HTTP(pts);
if (ntlm_challenge < 3 && args_info.remproxy_given ) {
if (args_info.remproxy_given ) {
/* Clean buffer for next analysis */
while ( strcmp( buf, "\r\n" ) != 0 )
readline(pts);
@ -209,8 +209,8 @@ void proxy_protocol(PTSTREAM *pts) {
* Then, repeat reading lines of the responses until a blank line
* (which signifies the end of the response) is encountered.
*/
if (ntlm_challenge == 2) {
ntlm_challenge = 3;
if (ntlm_challenge == 1) {
ntlm_challenge = 2;
} else {
do {
readline(pts);

2
io.c
View file

@ -57,7 +57,7 @@ int readline(PTSTREAM *pts) {
if( args_info.verbose_flag ) {
/* Copy line of data into dstr without trailing newline */
char *dstr = calloc(1, strlen(buf) + 1);
char *dstr = malloc(strlen(buf) + 1);
strncpy( dstr, buf, strlen(buf));
if (strcmp(dstr, ""))
message( " <- %s\n", dstr );

View file

@ -1,31 +0,0 @@
{
gnu-system ? true,
set-proc-title ? true,
pkgs,
}: let
optflags = "-DUSE_SSL ${
if gnu-system
then "-DHAVE_GETOPT_LONG"
else ""
} ${
if set-proc-title
then "-DSETPROCTITLE -DSPT_TYPE=2"
else ""
}";
in
pkgs.stdenv.mkDerivation {
pname = "proxytunnel";
version = "1.12.3";
src = ./..;
buildInputs = [pkgs.openssl];
buildPhase = ''
make OPTFLAGS="${optflags}"
'';
installPhase = ''
mkdir -p $out/bin
cp ./proxytunnel $out/bin
'';
}

146
ntlm.c
View file

@ -28,28 +28,14 @@
#include "proxytunnel.h"
#include <ctype.h>
#include <sys/time.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#ifdef CYGWIN
#include <unistd.h>
#endif
#include <openssl/provider.h>
#include <openssl/evp.h>
#else
#include <openssl/md4.h>
#include <openssl/md5.h>
#endif
#include <openssl/md4.h>
#include <openssl/md5.h>
#define TYPE1_DATA_SEG 8
#define TYPE2_BUF_SIZE 2048
#define DOMAIN_BUFLEN 256
#define LM2_DIGEST_LEN 24
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
const EVP_MD *md4alg;
const EVP_MD *md5alg;
EVP_MD_CTX *mdctx;
#endif
int ntlm_challenge = 0;
void message( char *s, ... );
int unicode = 0;
@ -68,72 +54,19 @@ int bloblen;
unsigned char *t_info;
int t_info_len;
uint32_t flags;
unsigned long flags;
unsigned char lm2digest[LM2_DIGEST_LEN];
void init_ntlm() {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PROVIDER *provider;
provider = OSSL_PROVIDER_load(NULL, "default");
if (!provider) {
my_perror("Loading default provider failed");
exit(1);
}
provider = OSSL_PROVIDER_load(NULL, "legacy");
#ifdef CYGWIN
if (!provider) {
// available at msys and git for windows
// the msys version has an additional dependency on libcrypto-3-x64.dll
provider = OSSL_PROVIDER_load(NULL, "/mingw64/lib/ossl-modules/legacy.dll");
}
if (!provider) {
// available at msys (without dependency on libcrypto-3-x64.dll)
provider = OSSL_PROVIDER_load(NULL, "/usr/lib/ossl-modules/legacy.dll");
}
if (!provider) {
// default installation path for additional tools
provider = OSSL_PROVIDER_load(NULL, "/usr/local/bin/legacy.dll");
}
if (!provider) {
// directory of proxytunnel itself
const char *p = strrchr(program_name, '/');
if (p) {
const int len = p - program_name;
char *tmp = (char*)alloca(len + sizeof("/legacy.dll"));
memcpy(tmp, program_name, len);
strcpy(tmp + len, "/legacy.dll");
provider = OSSL_PROVIDER_load(NULL, tmp);
}
}
if (!provider) {
// current working directory
char *cwd = getcwd(NULL, 0);
if (cwd) {
const int len = strlen(cwd);
char *tmp = (char*)alloca(len + sizeof("/legacy.dll"));
memcpy(tmp, cwd, len);
free(cwd);
strcpy(tmp + len, "/legacy.dll");
provider = OSSL_PROVIDER_load(NULL, tmp);
}
}
#endif
if (!provider) {
my_perror("Loading legacy provider failed");
exit(1);
}
md4alg = EVP_md4();
md5alg = EVP_md5();
mdctx = EVP_MD_CTX_new();
#endif
}
void build_type1() {
ntlm_type1 *type1;
int len = sizeof(ntlm_type1) + sizeof(unsigned char) * TYPE1_DATA_SEG;
type1 = (ntlm_type1 *)alloca(len);
type1 = (ntlm_type1 *)malloc(len);
if (!type1) {
message("Fatal Error in build type1, Malloc failed\n");
exit(-1);
}
memset(type1, 0, len);
type1->signature[0] = 'N';
@ -150,6 +83,7 @@ void build_type1() {
base64((unsigned char *)ntlm_type1_buf, (unsigned char *)type1, len);
free(type1);
return;
}
@ -247,7 +181,11 @@ void build_type3_response() {
len = sizeof(ntlm_type3) + sizeof(unsigned char) * (LM2_DIGEST_LEN + bloblen + (strlen(domain) + strlen(args_info.user_arg) + strlen(workstation)) * sp);
type3 = (ntlm_type3 *)alloca(len);
type3 = (ntlm_type3 *)malloc(len);
if (!type3) {
message("Fatal Error in build type3, Malloc failed\n");
exit(-1);
}
t3 = (unsigned char *) type3;
memset(type3, 0, len);
@ -293,6 +231,7 @@ void build_type3_response() {
base64((unsigned char *)ntlm_type3_buf, (unsigned char *)type3, len);
free(type3);
return;
}
@ -308,10 +247,7 @@ unsigned char* key; /* pointer to authentication key */
int key_len; /* length of authentication key */
unsigned char digest[16]; /* caller digest to be filled in */
{
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#else
MD5_CTX context;
#endif
unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
unsigned char k_opad[65]; /* outer padding - key XORd with opad */
unsigned char tk[16];
@ -319,15 +255,10 @@ unsigned char digest[16]; /* caller digest to be filled in */
/* if key is longer than 64 bytes reset it to key=MD5(key) */
if (key_len > 64) {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_DigestInit_ex(mdctx, md5alg, NULL);
EVP_DigestUpdate(mdctx, key, key_len);
EVP_DigestFinal_ex(mdctx, tk, NULL);
#else
MD5_Init(&context);
MD5_Update(&context, key, key_len);
MD5_Final(tk, &context);
#endif
MD5_CTX tctx;
MD5_Init( &tctx );
MD5_Update( &tctx, key, key_len );
MD5_Final( tk, &tctx );
key = tk;
key_len = 16;
}
@ -344,10 +275,10 @@ unsigned char digest[16]; /* caller digest to be filled in */
*/
/* start out by storing key in pads */
memset(k_ipad, 0, sizeof(k_ipad));
memset(k_opad, 0, sizeof(k_opad));
memcpy(k_ipad, key, key_len);
memcpy(k_opad, key, key_len);
bzero( k_ipad, sizeof k_ipad);
bzero( k_opad, sizeof k_opad);
bcopy( key, k_ipad, key_len);
bcopy( key, k_opad, key_len);
/* XOR key with ipad and opad values */
for (i=0; i<64; i++) {
@ -356,39 +287,22 @@ unsigned char digest[16]; /* caller digest to be filled in */
}
/* perform inner MD5 */
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_DigestInit_ex(mdctx, md5alg, NULL); /* init context for 1st pass */
EVP_DigestUpdate(mdctx, k_ipad, 64); /* start with inner pad */
EVP_DigestUpdate(mdctx, text, text_len); /* then text of datagram */
EVP_DigestFinal_ex(mdctx, digest, NULL); /* finish up 1st pass */
#else
MD5_Init(&context); /* init context for 1st pass */
MD5_Update(&context, k_ipad, 64); /* start with inner pad */
MD5_Update(&context, text, text_len); /* then text of datagram */
MD5_Final(digest, &context); /* finish up 1st pass */
#endif
/* perform outer MD5 */
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_DigestInit_ex(mdctx, md5alg, NULL); /* init context for 1st pass */
EVP_DigestUpdate(mdctx, k_opad, 64); /* start with inner pad */
EVP_DigestUpdate(mdctx, digest, 16); /* then text of datagram */
EVP_DigestFinal_ex(mdctx, digest, NULL); /* finish up 1st pass */
#else
MD5_Init(&context); /* init context for 2nd pass */
MD5_Update(&context, k_opad, 64); /* start with outer pad */
MD5_Update(&context, digest, 16); /* then results of 1st hash */
MD5_Final(digest, &context); /* finish up 2nd pass */
#endif
}
void build_ntlm2_response() {
int i, j;
int passlen = 0;
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#else
MD4_CTX passcontext;
#endif
unsigned char passdigest[16];
unsigned char *userdom;
int userdomlen;
@ -413,15 +327,9 @@ void build_ntlm2_response() {
}
}
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_DigestInit_ex(mdctx, md4alg, NULL);
EVP_DigestUpdate(mdctx, unipasswd, passlen);
EVP_DigestFinal_ex(mdctx, passdigest, NULL);
#else
MD4_Init (&passcontext);
MD4_Update (&passcontext, unipasswd, passlen);
MD4_Final (passdigest, &passcontext);
#endif
if( args_info.verbose_flag ) {
message("NTLM: MD4 of password is: ");
@ -431,8 +339,12 @@ void build_ntlm2_response() {
}
userdomlen = sizeof(unsigned char) * (strlen(args_info.user_arg) + strlen(domain)) * 2;
userdom = (unsigned char *)alloca(userdomlen);
userdom = (unsigned char *)malloc(userdomlen);
memset(userdom, 0, userdomlen);
if (!userdom) {
message("Fatal Error in build_ntlm2_response, Malloc failed\n");
exit(-1);
}
userdomlen = 0;
for (i = 0; i < strlen(args_info.user_arg); i++) {
@ -466,6 +378,8 @@ void build_ntlm2_response() {
hmac_md5(userdom, userdomlen, passdigest, 16, userdomdigest);
free(userdom);
if( args_info.verbose_flag ) {
message("HMAC_MD5 of userdom keyed with MD4 pass is: ");
for( i = 0; i < 16; i++)

54
ntlm.h
View file

@ -18,10 +18,6 @@
*/
/* ntlm.h */
#include <stdint.h>
void init_ntlm();
void build_type1();
int parse_type2(unsigned char *buf);
void build_type3_response();
@ -59,53 +55,53 @@ extern char ntlm_type3_buf[4096];
typedef struct {
uint16_t length;
uint16_t space;
uint32_t offset;
unsigned short length;
unsigned short space;
unsigned long offset;
} security_buf_t;
typedef struct {
uint8_t signature[8];
uint32_t message_type;
uint32_t flags;
unsigned char signature[8];
unsigned long message_type;
unsigned long flags;
security_buf_t domain;
security_buf_t workstation;
} ntlm_type1;
typedef struct {
uint8_t signature[8];
uint32_t message_type;
unsigned char signature[8];
unsigned long message_type;
security_buf_t target_name;
uint32_t flags;
uint8_t challenge[8];
uint32_t context1;
uint32_t context2;
unsigned long flags;
unsigned char challenge[8];
unsigned long context1;
unsigned long context2;
security_buf_t target_info;
uint8_t data_start;
unsigned char data_start;
} ntlm_type2;
typedef struct {
uint8_t signature[8];
uint32_t message_type;
unsigned char signature[8];
unsigned long message_type;
security_buf_t LM_response;
security_buf_t NTLM_response;
security_buf_t domain;
security_buf_t user;
security_buf_t workstation;
uint8_t session[8];
uint32_t flags;
uint8_t pad[8];
unsigned char session[8];
unsigned long flags;
unsigned char pad[8];
} ntlm_type3;
typedef struct {
uint8_t digest[16];
uint32_t signature;
uint32_t reserved;
uint64_t timestamp;
uint8_t client_challenge[8];
uint32_t unknown;
uint32_t data_start;
unsigned char digest[16];
unsigned long signature;
unsigned long reserved;
unsigned long long timestamp;
unsigned char client_challenge[8];
unsigned long unknown;
unsigned long data_start;
} blob;
// vim:noexpandtab:ts=4

View file

@ -29,11 +29,11 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netdb.h>
#include <signal.h>
#include <syslog.h>
#include <stdarg.h>
#include <stdlib.h>
#include "proxytunnel.h"
#include "io.h"
@ -77,10 +77,6 @@ int tunnel_connect() {
char service[6];
int sd;
if ( args_info.enforceipv4_flag )
hints.ai_family = AF_INET;
else if ( args_info.enforceipv6_flag )
hints.ai_family = AF_INET6;
rc = snprintf( service, sizeof(service), "%d", args_info.proxyport_arg );
if( ( rc < 0 ) || ( rc >= sizeof(service) ) ) {
/* this should never happen */
@ -159,110 +155,23 @@ void closeall() {
}
}
/* Get the filled in sockaddr structure to the standalone daemon */
void get_sa_serv(struct sockaddr **sa_serv_pp, socklen_t *sa_serv_len_p)
{
static union {
struct sockaddr_in v4;
struct sockaddr_in6 v6;
} sa_serv;
int set_addr_result = 1;
memset( &sa_serv, '\0', sizeof( sa_serv ) );
/* In case a standalone address has been specified ... */
if ( args_info.standalone_addr_given ) {
/* ... and it looks like a IPv6 address ... */
if ( strchr( args_info.standalone_addr, ':' ) ){
/* ... set IPv6 address family and port, ... */
sa_serv.v6.sin6_family = AF_INET6;
sa_serv.v6.sin6_port = htons( args_info.standalone_port );
/* ... in case a standalone interface has been specified ... */
if ( args_info.standalone_iface_given ) {
/* ... try to get and set the interface's index */
if ( !(sa_serv.v6.sin6_scope_id = if_nametoindex(args_info.standalone_iface)) ) {
set_addr_result = -2;
}
}
/* If no error happened regarding the interface ... */
if ( set_addr_result != -2 ) {
/* ... try to set the presumed IPv6 address. */
set_addr_result =
inet_pton(AF_INET6,
args_info.standalone_addr,
&sa_serv.v6.sin6_addr);
}
/* ... otherwise (if it does not look like a IPv6 address) ... */
} else {
/* ... set IPv4 address family and port, ... */
sa_serv.v4.sin_family = AF_INET;
sa_serv.v4.sin_port = htons( args_info.standalone_port );
/* ... try to set the presumed IPv4 address. */
set_addr_result =
inet_pton(AF_INET,
args_info.standalone_addr,
&sa_serv.v4.sin_addr);
}
/* In case no standalone address has been specified ... */
} else {
/* ... set IPv6 family, port and any address */
sa_serv.v6.sin6_family = AF_INET6;
sa_serv.v6.sin6_port = htons( args_info.standalone_port );
sa_serv.v6.sin6_addr = in6addr_any;
}
/* Bail out on errors */
switch (set_addr_result) {
case 0:
my_perror("Setting server socket IP address failed, possibly malformed");
exit(1);
case -1:
my_perror("Setting server socket address family failed.");
exit(1);
case -2:
my_perror("Setting server socket interface failed, possibly mis-spelled");
exit(1);
}
/* Return pointer to sockaddr struct and its size */
*sa_serv_pp = (struct sockaddr *)&sa_serv;
*sa_serv_len_p = sizeof( sa_serv );
return;
}
/* Log pid and IP address of client */
void log_client(int pid, struct sockaddr_storage *ss_client_p)
{
char buf[40];
inet_ntop(ss_client_p->ss_family,
ss_client_p->ss_family == AF_INET ?
(void *)&(((struct sockaddr_in *)ss_client_p)->sin_addr) :
(void *)&(((struct sockaddr_in6 *)ss_client_p)->sin6_addr),
buf,
sizeof(buf));
message( "Started tunnel pid=%d for connection from %s", pid, buf );
return;
}
/* Run as a standalone daemon */
void do_daemon()
{
int listen_sd;
int one = 1;
struct sockaddr *sa_serv_p;
socklen_t sa_serv_len;
struct sockaddr_storage sa_cli;
struct sockaddr_in sa_serv;
struct sockaddr_in sa_cli;
socklen_t client_len;
int pid = 0;
int sd_client;
char buf[80];
unsigned char addr[4];
/* Socket descriptor */
int sd;
get_sa_serv(&sa_serv_p, &sa_serv_len);
if ( ( listen_sd = socket( sa_serv_p->sa_family, SOCK_STREAM, IPPROTO_TCP ) ) < 0 ) {
if ( ( listen_sd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) < 0 ) {
my_perror( "Server socket creation failed" );
exit(1);
}
@ -272,7 +181,12 @@ void do_daemon()
#endif /* SO_REUSEPORT */
setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
if ( bind( listen_sd, sa_serv_p, sa_serv_len ) < 0) {
memset( &sa_serv, '\0', sizeof( sa_serv ) );
sa_serv.sin_family = AF_INET;
sa_serv.sin_addr.s_addr = htonl(INADDR_ANY);
sa_serv.sin_port = htons( args_info.standalone_arg );
if ( bind( listen_sd, (struct sockaddr * )&sa_serv, sizeof( struct sockaddr ) ) < 0) {
my_perror("Server socket bind failed");
exit(1);
}
@ -324,10 +238,6 @@ void do_daemon()
* we'll do it by default, can't hurt
*
* -- Maniac
*
* 2024/01/21: Not sure what makes up the workaround
*
* -- Sven
*/
client_len = sizeof( sa_cli );
@ -343,9 +253,6 @@ void do_daemon()
if ( ( pid = fork() ) < 0 ) {
my_perror( "Cannot fork worker" );
} else if ( pid == 0 ) {
/* As worker, we do not need to listen for new connections */
close(listen_sd);
read_fd = write_fd = sd_client;
/* Create a stdin/out stream */
@ -385,7 +292,9 @@ void do_daemon()
exit( 0 );
}
log_client(pid, &sa_cli);
memcpy( &addr, &sa_cli.sin_addr.s_addr, 4 );
snprintf( (char *) buf, 16, "%u.%u.%u.%u", addr[0], addr[1], addr[2], addr[3] );
message( "Started tunnel pid=%d for connection from %s", pid, buf );
close( sd_client );
}
}
@ -420,11 +329,6 @@ int main( int argc, char *argv[] ) {
signal( SIGHUP, signal_handler );
/* Initialize the NTLM module, if needed. */
if (args_info.ntlm_flag) {
init_ntlm();
}
/* If the usename is given, but password is not, prompt for it */
if( args_info.user_given && !args_info.pass_given ) {
char *cp;

View file

@ -30,10 +30,8 @@ void analyze_HTTP(PTSTREAM *pts);
void proxy_protocol(PTSTREAM *pts);
void closeall();
void do_daemon();
#ifdef SETPROCTITLE
void initsetproctitle(int argc, char *argv[]);
void setproctitle(const char *fmt, ...);
#endif
#if defined(__APPLE__) && defined(__MACH__)
/* Don't include strlcat and strlcpy since they are provided as macros on OSX */

View file

@ -222,10 +222,11 @@ int check_cert_names(X509 *cert, char *peer_host) {
for (i = 0; i < san_count; i++) {
gn = sk_GENERAL_NAME_value(gen_names, i);
if (gn->type == GEN_DNS && !(peer_host_is_ipv4 || peer_host_is_ipv6)) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
#ifdef OPENSSL11
if (check_cert_valid_host((char*)ASN1_STRING_get0_data(gn->d.ia5), peer_host)) {
#else
if (check_cert_valid_host((char*)ASN1_STRING_data(gn->d.ia5), peer_host)) {
#endif
return 1;
}
@ -262,33 +263,30 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) {
X509* cert = NULL;
int status;
struct stat st_buf;
#ifndef DEFAULT_CA_FILE
const char *ca_file = NULL;
#else
const char *ca_file = DEFAULT_CA_FILE; /* Default cert file from Makefile */
#endif /* !DEFAULT_CA_FILE */
#ifndef DEFAULT_CA_DIR
const char *ca_dir = "/etc/ssl/certs/"; /* Default cert directory if none given */
#else
const char *ca_dir = DEFAULT_CA_DIR; /* Default cert directory from Makefile */
#endif /* !DEFAULT_CA_DIR */
long vresult;
const char *peer_arg = NULL;
size_t peer_arg_len;
char peer_arg_fmt[32];
char *peer_host = NULL;
char proxy_arg_fmt[32];
size_t proxy_arg_len;
/* Initialise the connection */
SSLeay_add_ssl_algorithms();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
meth = TLS_client_method();
if (args_info.enforcetls1_flag) {
#ifdef OPENSSL11
meth = TLS_client_method();
#else
meth = SSLv23_client_method();
meth = TLSv1_client_method();
#endif
} else {
meth = SSLv23_client_method();
}
SSL_load_error_strings();
ctx = SSL_CTX_new (meth);
ssl_options |= SSL_OP_NO_SSLv3;
if (args_info.no_ssl3_flag) {
ssl_options |= SSL_OP_NO_SSLv3;
}
SSL_CTX_set_options (ctx, ssl_options);
if ( !args_info.no_check_cert_flag ) {
@ -310,33 +308,19 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) {
}
}
/* If given, load client certificate (chain) and key */
if ( args_info.clientcert_given && args_info.clientkey_given ) {
if ( 1 != SSL_CTX_use_certificate_chain_file(ctx, args_info.clientcert_arg) ) {
message("Error loading client certificate (chain) from %s\n", args_info.clientcert_arg);
goto fail;
}
if ( 1 != SSL_CTX_use_PrivateKey_file(ctx, args_info.clientkey_arg, SSL_FILETYPE_PEM) ) {
message("Error loading client key from %s, or key does not match certificate\n", args_info.clientkey_arg);
goto fail;
}
}
ssl = SSL_new (ctx);
if ( ssl == NULL ) {
message("SSL_new failed\n");
goto fail;
}
SSL_set_rfd (ssl, stream_get_incoming_fd(pts));
SSL_set_wfd (ssl, stream_get_outgoing_fd(pts));
/* Determine the host name we are connecting to */
peer_arg = args_info.host_given ? args_info.host_arg : proxy_arg;
peer_arg_len = strlen(peer_arg);
peer_host = alloca(peer_arg_len + 1);
snprintf( peer_arg_fmt, sizeof(peer_arg_fmt), peer_arg[0] == '[' ? "[%%%zu[^]]]" : "%%%zu[^:]", peer_arg_len);
if ( sscanf( peer_arg, peer_arg_fmt, peer_host ) != 1 ) {
proxy_arg_len = strlen(proxy_arg);
if ((peer_host = malloc(proxy_arg_len + 1)) == NULL) {
message("Out of memory\n");
goto fail;
}
snprintf( proxy_arg_fmt, sizeof(proxy_arg_fmt), proxy_arg[0] == '[' ? "[%%%zu[^]]]" : "%%%zu[^:]", proxy_arg_len - 1 );
if ( sscanf( proxy_arg, proxy_arg_fmt, peer_host ) != 1 ) {
goto fail;
}
@ -345,16 +329,12 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) {
message( "Set SNI hostname to %s\n", peer_host);
}
res = SSL_set_tlsext_host_name(ssl, peer_host);
if ( res != 1 ) {
message( "SSL_set_tlsext_host_name() failed for host name '%s'. "
"TLS SNI error, giving up\n", peer_host);
goto fail;
if (res < 0) {
message( "TLS SNI error, giving up: SSL_set_tlsext_host_name returned error message:\n %u\n", res );
exit( 1 );
}
if ( SSL_connect (ssl) <= 0) {
message( "SSL_connect failed\n");
goto fail;
}
SSL_connect (ssl);
if ( !args_info.no_check_cert_flag ) {
/* Make sure peer presented a certificate */
@ -377,6 +357,7 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) {
goto fail;
}
free(peer_host);
X509_free(cert);
}
@ -394,6 +375,9 @@ fail:
if (cert != NULL) {
X509_free(cert);
}
if (peer_host != NULL) {
free(peer_host);
}
#endif /* USE_SSL */
exit(1);
}

View file

@ -19,9 +19,7 @@
/* ptstream.h */
#include <stddef.h>
#ifdef USE_SSL
#include <openssl/opensslv.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>