Compare commits

...

102 commits

Author SHA1 Message Date
Sven Geuer
7f32a099f9
Makefile: Fix issue #101 by not emitting '-DSETPROCTITLE' with MSYS2. 2025-12-09 16:58:00 +01:00
Sven Geuer
320ad4be83
More corrections to the manual page
- Drop sections "Arguments", it describes the non-existent positional parameter
  in detail.
2025-11-22 19:08:08 +01:00
Sven Geuer
c43ba13e02
Corrections to the manual page
- Drop mentioning of non-existent positional parameter.
- Mark -p (or HTTP_PROXY) and -d as mandatory
2025-11-22 15:52:05 +01:00
Sven Geuer
9203bdfef7
cmdline.c: Fix check of proxy and destination being given. 2025-11-22 15:49:53 +01:00
Mark Janssen
cd358101fb
Merge pull request #93 from zSuperx/nix-flake-basic-support
Nix flake basic support
2025-05-15 00:48:49 +02:00
zsuper
882a22d80d Reverted changes to ntlm.c 2025-05-14 14:41:01 -07:00
zsuper
9db6e3b3d3 Merge remote-tracking branch 'upstream/master' into nix-flake-basic-support 2025-05-14 14:40:18 -07:00
Mark Janssen
b4ddf94b45
Merge pull request #97 from proxytunnel/issue-96
Fix #96
2025-05-14 22:30:20 +02:00
Mark Janssen -- Sig-I/O Automatisering
77b9afda27
Fix #96 2025-05-14 22:24:24 +02:00
zsuper
b4ed20677c Removed use-ssl option as it does not make sense to disable SSL. Also added default overlay
updated INSTALL.md with flake overlay
2025-04-04 10:18:32 -07:00
zsuper
85eeaabe28 Updated INSTALL.md again 2025-04-03 21:29:38 -07:00
zsuper
2e61c609bb Updated INSTALL.md 2025-04-03 21:13:45 -07:00
zsuper
226c45c969 Added one more #ifdef for consistency 2025-04-03 20:00:14 -07:00
zsuper
2ef739f7c2 Fixed formatting issue that caused an error with OPTFLAGS 2025-04-03 19:51:48 -07:00
zsuper
f320f2bf63 Added preprocessor #ifdef USE_SSL around every instance of OPENSSL_VERSION_NUMBER 2025-04-03 19:50:31 -07:00
zsuper
ad8a6a1c7e Added options for gnu-systems & setproctitle to flake 2025-04-03 19:43:15 -07:00
zsuper
5e9a22d035 moved package mkDerivation to ./nix/proxytunnel.nix 2025-04-03 15:17:29 -07:00
zsuper
c4c6caafbb use callPackage 2025-04-03 11:20:21 -07:00
zsuper
4982420160 flake overlay test 2025-04-03 09:46:52 -07:00
Piyush Kumbhare
8ab065fca1
Update flake.nix version to match github Release v1.12.3 version 2025-04-01 23:39:13 -07:00
zsuper
3ec1efe42e Changed flake.nix to use flake-parts for modular arch support. Updated INSTALL.md 2025-04-01 23:09:45 -07:00
zsuper
20be023202 Extended flake so support can easily be added for diff archs in the future 2025-04-01 19:58:45 -07:00
zsuper
c5ab464877 Added basic flake support for x86_64-linux. 2025-04-01 19:27:26 -07:00
Sven Geuer
dc0945afb8
Update CHANGES and config.h for release 1.12.3 2025-03-07 23:04:56 +01:00
Sven Geuer
6b99bb7898
TODO: Drop note about SSL proxy support, it has been added meanwhile. 2025-03-07 22:27:28 +01:00
Sven Geuer
0e202442e5
CHANGES: chmode 755 to 644. 2025-03-07 22:23:12 +01:00
Mark Janssen
c31174f171
Merge pull request #89 from njbraun/increase-max-header-size-4k
Increase MAX_HEADER_SIZE
2025-01-04 19:28:17 +01:00
Nick Braun
fb9b85a40e
Increase MAX_HEADER_SIZE
Increases the MAX_HEADER_SIZE in cmdline to be 4K
2024-12-20 04:56:18 -08:00
Mark Janssen
92bec14931
Merge pull request #86 from e9hack/fix_and_improve_NTLM_authentication
Fix and improve ntlm authentication
2024-11-29 15:17:15 +01:00
e9hack
b6daf27b8f Fixed NTLM authentication
- analyse_HTTP: Read first something from the connection before analyse it
- analyse_HTTP: Accepte a TAB as a second delimiter during parsing an answer from a proxy.
- proxy_protocol(): In case of NTLM authentication, this function is called twice recursively.
  Use variable ntlm_challenge as marker of the state of the authentication to avoid endless
  recursive calls in case of an error and avoid to try to connect to the remote proxy twice.
2024-11-29 12:41:27 +01:00
e9hack
8ff6d58f1b Fixed loading of default and legacy provider
- Verify that the default and legacy provider was loaded successfully. If not bail out.
- On Windows, try to load the legacy.dll from multiple locations before bailing out.
- Added legacy.dll to the proxytunnel.zip archive.
2024-11-29 12:08:56 +01:00
Mark Janssen
8b2661ecd7
Merge pull request #83 from tofurky/unterminated_string_calloc
Avoid printing unterminated string in readline()
2024-09-16 12:53:42 +02:00
Matt Merhar
9df98a6e31 Avoid printing unterminated string in readline()
When running with -v, readline() in io.c uses strncpy() to copy a string
(*without* the terminating NULL) into an uninitialized buffer created by
malloc().

When message() then prints this, it can lead to garbage data being
emitted since it's potentially reading past the intended end of the
string. In practice, this appears to only be an additional byte or 2
before a NULL is encountered.

The issue was hit when readline() encountered "\r\n\r\n", not longer
strings, but I imagine it's dependent on things like compiler / libc /
the weather as to whether the end of the buffer returned by malloc()
will be zeroed or not; I've seen similar issues pop up with "working"
code running on newer distros.
2024-09-13 19:20:50 -04:00
Mark Janssen
84d44b608b
Merge pull request #80 from hoilc/patch-1
Fix typo in package name
2024-03-25 14:50:38 +01:00
hoilc
0d62ae5af3
Fix typo in package name 2024-03-25 21:25:00 +08:00
Mark Janssen
d55d9286a0
Merge pull request #79 from hoilc/enable-github-action
Enable GitHub Action for Windows Binary
2024-03-21 13:40:08 +01:00
hoilc
af80b39f2d enable github action 2024-03-20 13:18:20 +08:00
Sven Geuer
d2c636bef4
Prepare CHANGES and config.h for release. 2024-02-06 17:41:38 +01:00
Sven Geuer
08b84fe054
Update the --help output to the recent version. 2024-02-01 16:33:38 +01:00
Sven Geuer
e999ab0acd
Replace deprecated functions bzero/bcopy by memset/memcpy. 2024-02-01 16:14:56 +01:00
Sven Geuer
abb82a7807
Make sure no deprecated libssl functions are called. 2024-02-01 16:08:09 +01:00
Sven Geuer
351d2dffc3
Use OPENSSL_VERSION_NUMBER to compile code matching the applied libssl version.
This renders Makefile.ssl11 redundant.
2024-01-30 19:47:34 +01:00
Sven Geuer
945f205796
Deprecate -L/--tlsenforce and -T/--no-ssl3. 2024-01-30 19:46:15 +01:00
Sven Geuer
33399b3312
Remove deprecated options.
Remove options -u and -s deprecated since 2008.
Remove also commented remnants of options -U and -S.
2024-01-26 01:44:37 +01:00
Sven Geuer
cef27b8576
As worker, close the unneeded listening socket. 2024-01-21 23:04:33 +01:00
Sven Geuer
4690473fba
In standalone mode, fix logging of IPv6 clients. 2024-01-21 22:52:36 +01:00
Sven Geuer
65562596b7
Use an AF_INET socket when binding to a specified IPv4 address. 2024-01-21 21:06:38 +01:00
Sven Geuer
6adc78ec08 Prepare CHANGES and config.h for release 2023-12-17 19:50:52 +01:00
Sven Geuer
a0b916a177 client SSL * -> SSL client * 2023-12-17 19:49:28 +01:00
Sven Geuer
11f50d20c3 Update manual page regarding -a/--standalone 2023-12-17 01:25:40 +01:00
Sven Geuer
c9503273a7 Allow for binding to a link-local IPv6 address
Requires to also give the interface like ipv6%interface
2023-12-16 23:37:36 +01:00
Sven Geuer
3c3b5b0858 Remove Debian-specific reference 2023-12-16 19:31:06 +01:00
Sven Geuer
6f66537295 Remove sentence about not working authentication on remote proxies 2023-12-16 17:34:55 +01:00
Sven Geuer
4100c006f7 Replace reference to the already removed option -S 2023-12-16 17:32:59 +01:00
Sven Geuer
4cc6aa11db Corrections and updates to the manual page 2023-12-15 23:10:47 +01:00
Sven Geuer
002410f449 Remove Debian-specific reference from --help output 2023-12-15 22:51:48 +01:00
Sven Geuer
513c8a2fc9 In standalone mode, allow for binding to a specified IP address 2023-12-15 22:29:01 +01:00
Sven Geuer
ae7fcc8a1f Make sure stdlib.c is only included once 2023-12-15 15:42:49 +01:00
Sven Geuer
5f1674159b In standalone mode, allow also for IPv6 connections 2023-12-15 15:32:12 +01:00
Sven Geuer
a5b69f666c Minor corrections to the manpage. 2023-12-14 01:07:08 +01:00
Sven Geuer
65795065e6 Add a missing #include
noticed when trying to build without USE_SSL
2023-12-14 00:09:11 +01:00
Sven Geuer
8148cca521 Small fixes to the --help output 2023-12-14 00:08:09 +01:00
Sven Geuer
bd28fefd02 Bump VERSION and VERSION_DATE 2023-12-11 20:59:32 +01:00
Sven Geuer
b7aab076d2 Fix loading REMPROXYUSER/REMPROXYPASS from the environment 2023-12-11 19:10:32 +01:00
Sven Geuer
a425fa20d8 On SSL connections, introduce authentication by client certificate 2023-12-11 18:31:42 +01:00
Sven Geuer
a65239015d Correct derivation of peer_host
Combine the derivations from proxy_arg and args_info.host_arg.
2023-12-10 22:45:17 +01:00
Sven Geuer
51c3a0be03 Flag it as a version under development 2023-12-02 23:20:48 +01:00
Sven Geuer
5b0e803f25 Some more alloca() instead of malloc() 2023-12-02 21:15:23 +01:00
Sven Geuer
097a0a2453 Honor -o/--host on determining the SNI host name 2023-12-02 19:54:02 +01:00
Sven Geuer
470ac87f73 Use alloca() instead of malloc()
This make code more readable and spares us some explicit calls to
free().
2023-12-02 19:37:56 +01:00
Sven Geuer
8d69435854 Ignore generated documentation files 2023-12-02 19:02:24 +01:00
Sven Geuer
f2fdb5ee89 Fix a typo 2023-12-02 18:44:53 +01:00
Sven Geuer
b314a1c725 Fix configuration of option --tlsenforce 2023-12-02 18:33:33 +01:00
Sven Geuer
be12e0219a Add long options missing from --help and manual page 2023-12-02 18:28:13 +01:00
Sven Geuer
352c89cd5a
Bump version and changelogs 2023-10-16 21:01:01 +02:00
Sven Geuer
c76499093b Drop obsolete Makefile flavor. 2023-10-16 18:40:29 +02:00
Sven Geuer
0349635635 Harmonize output of --help and manual page
Also fix some typos and missing newlines.
2023-10-01 21:09:49 +02:00
Sven Geuer
62f57fd865 Quote colons (:) in _host_:_port_ and similar strings
This makes sure the substring after the colon is displayed with the
intended text styles.
2023-09-27 17:36:36 +02:00
Sven Geuer
5888c89a3c Submit VERSION and VERSION_DATE when generating the manual page 2023-09-27 17:04:22 +02:00
Sven Geuer
2f733348cc Use VERSION_YEAR to build an up-to-date copyright string 2023-09-27 17:01:00 +02:00
Sven Geuer
afbab76cf1 Add macros VERSION_YEAR and VERSION_DATE 2023-09-27 16:55:56 +02:00
Sven Geuer
70935051eb Remove the author and the revision line
The author line results in a second garbled author paragraph in addition
to the author paragraph already included in the document.
The revision line provides only static data. The attributes revnumber
and revdate will be set dynamically via command line instead.
2023-09-27 16:29:56 +02:00
Sven Geuer
620e08e5ce Fix NTLM based authentication on 64bit machines
See #60 for details.
2023-09-13 14:53:34 +02:00
Mark Janssen
ac7c1085d6
Merge pull request #75 from 68420948/master
Remediate faulty patch for #57
2023-09-04 15:29:55 +02:00
Sven Geuer
08d0552ef4 Remediate faulty patch for #57 2023-09-04 12:43:45 +02:00
Mark Janssen -- Sig-I/O Automatisering
a04b20de16
Bump version and changelogs 2023-09-03 00:05:19 +02:00
Mark Janssen
57a7663e58
Merge pull request #71 from 68420948/master
Add options to enforce IPv4 or IPv6 connections to the local proxy
2023-09-02 23:56:54 +02:00
Sven Geuer
20e1ea379a Add options to enforce IPv4 or IPv6 connections to the local proxy 2023-09-02 19:29:47 +02:00
Mark Janssen
16500d2628
Merge pull request #67 from yurivict/patch-1
Add practically important option descriptions to the example in README
2023-05-06 02:50:15 +02:00
yuri@FreeBSD
97d2f516ff
Add practically important option descriptions to the example in README
1. nginx with the http_proxy module doesn't by default (or ever) accept CONNECT through http, so https should be used. -E is added for this.

2. Many/most users would use self-signed certificates. -z is described for this.

This README change would potentially simplify the setup process for users.
2023-05-05 15:48:07 -07:00
Mark Janssen
09bf837c50
Update README.md
Looking for maintainer
2022-09-21 17:18:08 +02:00
Mark Janssen -- Sig-I/O Automatisering
e7fa825933
Close #58 2022-05-28 21:24:55 +02:00
Mark Janssen -- Sig-I/O Automatisering
4bac945fc7
Apply patch to fix: #57 2022-05-28 15:56:31 +02:00
Mark Janssen
e2a214d942
Merge pull request #54 from deFractal/local-ca-file
Optionally accept alternative default CA file and/or directory path at compile time
2021-08-06 10:29:37 +02:00
David
8cfcd00045 Document CA file & dir compiler options
and fix a trivia typo
2021-08-04 19:03:12 -07:00
David
a269b94ad8 Accept alt ca_file and ca_dir as compiler options 2021-08-04 18:13:37 -07:00
David
e448313d68 Add option for local default OpenSSL 1.1 CA file
Provides non-empty default for Homebrew on macOS
2021-08-04 17:06:14 -07:00
Mark Janssen -- Sig-I/O Automatisering
6014edcc61
Migrated builds to travis-ci.com 2021-06-09 11:56:36 +02:00
Mark Janssen -- Sig-I/O Automatisering
1026053ed2
Update changelog 2021-01-28 23:12:52 +01:00
Mark Janssen -- Sig-I/O Automatisering
c38722e87e
Allow for longer usernames and passwords on proxy-auth 2021-01-28 22:55:39 +01:00
Mark Janssen -- Sig-I/O Automatisering
69c48599e4
Error handling on SSL_new and SSL_connect 2021-01-28 22:55:15 +01:00
Mark Janssen -- Sig-I/O Automatisering
ab33f01fbd
Apply debian patches for Makefile 2021-01-28 22:14:02 +01:00
27 changed files with 963 additions and 495 deletions

56
.github/workflows/windows.yml vendored Normal file
View file

@ -0,0 +1,56 @@
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,3 +2,7 @@
*.exec
proxytunnel.exe
proxytunnel
passfile
test.sh
docs/*.html
docs/*.1

82
CHANGES Executable file → Normal file
View file

@ -1,3 +1,85 @@
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,6 +10,55 @@ 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,11 +14,15 @@ OPTFLAGS += -DHAVE_GETOPT_LONG
# Comment if you don't have/want ssl
OPTFLAGS += -DUSE_SSL
# Most systems
# 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
OPTFLAGS += -DSETPROCTITLE -DSPT_TYPE=2
# Comment if you don't have this flag
OPTFLAGS += -DSO_REUSEPORT
endif
# System dependant blocks... if your system is listed below, uncomment
# the relevant lines
@ -29,6 +33,12 @@ OPTFLAGS += -DSO_REUSEPORT
# 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
@ -56,7 +66,6 @@ mandir = $(datadir)/man
OBJ = proxytunnel.o \
base64.o \
strzcat.o \
setproctitle.o \
io.o \
http.o \
basicauth.o \
@ -67,6 +76,10 @@ OBJ = proxytunnel.o \
ntlm.o \
ptstream.o
ifneq (,$(findstring -DSETPROCTITLE,$(OPTFLAGS)))
OBJ += setproctitle.o
endif
UNAME = $(shell uname)
ifneq ($(UNAME),Darwin)
OBJ += strlcpy.o \
@ -81,7 +94,7 @@ docs:
$(MAKE) -C docs
proxytunnel: $(OBJ)
$(CC) -o $(name) $(CFLAGS) $(OPTFLAGS) $(OBJ) $(LDFLAGS)
$(CC) -o $(name) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) $(OBJ) $(LDFLAGS)
clean:
@rm -f $(name) $(OBJ)
@ -93,7 +106,7 @@ install:
$(MAKE) -C docs install
.c.o:
$(CC) $(CFLAGS) $(OPTFLAGS) -c -o $@ $<
$(CC) $(CPPFLAGS) $(CFLAGS) $(OPTFLAGS) -c -o $@ $<
dist: clean docs
sed -i -e 's/^Version:.*$$/Version: $(version)/' contrib/proxytunnel.spec

View file

@ -1,106 +0,0 @@
# 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

View file

@ -1,106 +0,0 @@
# 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,5 +1,7 @@
[![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
@ -23,37 +25,40 @@ option it specifies it's command-line options.
```
$ ./proxytunnel --help
proxytunnel 1.9.9 Copyright 2001-2018 Proxytunnel Project
proxytunnel 1.12.1 Copyright 2001-2024 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=INT Run as standalone daemon on specified port
-a, --standalone=STRING Run as standalone daemon on specified port or
address:port combination
-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
-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:
-W, --wa-bug-29744 Workaround ASF Bugzilla 29744: if SSL is active
stop using it after CONNECT (might not work on all
setups)
-B, --buggy-encrypt-proxy Equivalent to -E -W, provided for backwards
compatibility
-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 STRING send custom Host Header
-o, --host=STRING Send custom Host Header/SNI
-x, --proctitle=STRING Use a different process title
Miscellaneous options:
@ -69,14 +74,14 @@ a $HOME/.ssh/config file with the following content:
```
Host foobar
ProtocolKeepAlives 30
ProxyCommand /path/to/proxytunnel -p proxy:8080 -P username
-d mybox.athome.nl:443
ProxyCommand /path/to/proxytunnel -E -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)
@ -84,12 +89,16 @@ 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 an environment variable, and tell proxytunnel where to
find it with '-S'.
password in the environment variable PROXYPASS.
If you want to run proxytunnel from inetd add the '--inetd' option.
@ -107,8 +116,7 @@ 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. Note that authentication doesn't (yet) work on
this remote proxy. For more information regarding this feature, check
requested destination. 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,11 +7,6 @@
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(80);
char *b64str = malloc(160);
int len = strlen( user ) + strlen( pass ) + 2;
char *p = (char *) malloc( len );
char *p = (char *) alloca( len );
/* Set up the cookie in clear text */
sprintf( p, "%s:%s", user, pass );
@ -50,8 +50,6 @@ 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.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 .
make -f Makefile
strip -s proxytunnel.exe
echo "Generate proxytunnel.zip with docs, exe and msys/openssl dll..."
zip proxytunnel.zip proxytunnel.exe *.dll docs/proxytunnel.1 docs/proxytunnel.1.html docs/proxytunnel-paper.html
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
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-2020 Proxytunnel Project\n", PACKAGE, VERSION);
printf ("%s %s Copyright 2001-%s Proxytunnel Project\n", PACKAGE, VERSION, VERSION_YEAR);
}
void cmdline_parser_print_help (void) {
@ -50,8 +50,9 @@ 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=INT Run as standalone daemon on specified port\n"
// FIXME: " -f, --nobackground Don't for tok background in standalone mode\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"
" -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"
@ -59,23 +60,29 @@ 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"
@ -83,7 +90,11 @@ 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"
" -o STRING send custom Host Header\n"
#ifdef USE_SSL
" -o, --host=STRING Send custom Host Header/SNI\n"
#else
" -o, --host=STRING Send custom Host Header\n"
#endif
#ifdef SETPROCTITLE
" -x, --proctitle=STRING Use a different process title\n"
#endif
@ -135,17 +146,22 @@ 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->quiet_given = 0;
args_info->standalone_given = 0;
args_info->standalone_addr_given = 0;
args_info->standalone_iface_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;
@ -165,20 +181,27 @@ 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->quiet_flag = 0; \
args_info->standalone_arg = 0; \
args_info->standalone_arg = NULL; \
args_info->standalone_addr = NULL; \
args_info->standalone_iface = NULL; \
args_info->standalone_port = 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();
@ -199,11 +222,7 @@ 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' },
@ -212,7 +231,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", 1, NULL, 'L' },
{ "tlsenforce", 0, NULL, 'L' },
{ "header", 1, NULL, 'H' },
{ "verbose", 0, NULL, 'v' },
{ "ntlm", 0, NULL, 'N' },
@ -222,17 +241,21 @@ 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:nvNeEXWBqLo:TzC:", long_options, &option_index);
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);
#else
c = getopt( argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:nvNeEXWBqLo:TzC:" );
c = getopt( argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:c:k:vNeEXWBqLo:TzC:46" );
#endif
if (c == -1)
@ -257,6 +280,26 @@ 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 )
@ -281,16 +324,18 @@ 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);
}
if ( ( args_info->standalone_arg = atoi( optarg ) ) < 1 ) {
fprintf( stderr, "%s: Illegal port value for `--standalone' (`-a')\n", PACKAGE);
clear_args();
exit(1);
}
args_info->standalone_given = 1;
args_info->standalone_arg = gengetopt_strdup (optarg);
break;
case 'V': /* Print version and exit. */
@ -305,40 +350,18 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
break;
case 'L':
args_info->enforcetls1_given = 1;
message("Enforcing TLSv1");
args_info->enforcetls1_flag = 1;
/* args_info->enforcetls1_given = 1;
message("Enforcing TLSv1\n");
args_info->enforcetls1_flag = 1; */
message ("Option -L/--tlsenforce is deprecated and without effect\n");
break;
case 'o':
args_info->host_given = 1;
message("Host-header override enabled\n");
message("Host-header/SNI 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);
@ -425,9 +448,10 @@ 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("SSLv3 disabled\n"); */
message ("Option -T/--no-ssl3 is deprecated and without effect\n");
break;
case 'd': /* Destination host to built the tunnel to. */
@ -478,6 +502,28 @@ 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. */
@ -520,7 +566,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->user_arg = gengetopt_strdup (tmp);
args_info->remuser_arg = gengetopt_strdup (tmp);
if( args_info->verbose_flag )
message( "Found remote user '%s' in env variable REMPROXYPASS.\n", args_info->remuser_arg);
}
@ -528,7 +574,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->user_arg = gengetopt_strdup (tmp);
args_info->rempass_arg = gengetopt_strdup (tmp);
if( args_info->verbose_flag )
message( "Found remote password in env variable REMPROXYPASS.\n" );
}
@ -550,13 +596,20 @@ 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;
@ -581,7 +634,56 @@ 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: could not find your proxy hostname/ip (%s)\n", args_info->proxy_arg );
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 );
missing_required_options++;
}
}
@ -591,10 +693,10 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
char *puser = NULL;
char *ppass = NULL;
puser = malloc( 24+1 );
ppass = malloc( 24+1 );
puser = malloc( 80+1 );
ppass = malloc( 80+1 );
r = sscanf( args_info->proxyauth_arg, "%24[^:]:%24s", puser, ppass );
r = sscanf( args_info->proxyauth_arg, "%80[^:]:%80s", puser, ppass );
if ( r == 2 ) {
args_info->user_arg = puser;
args_info->pass_arg = ppass;
@ -614,10 +716,10 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
char *ruser = NULL;
char *rpass = NULL;
ruser = malloc( 24+1 );
rpass = malloc( 24+1 );
ruser = malloc( 80+1 );
rpass = malloc( 80+1 );
r = sscanf( args_info->remproxyauth_arg, "%24[^:]:%24s", ruser, rpass );
r = sscanf( args_info->remproxyauth_arg, "%80[^:]:%80s", ruser, rpass );
if ( r == 2 ) {
args_info->remuser_arg = ruser;
args_info->rempass_arg = rpass;
@ -631,6 +733,7 @@ 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 1024
#define MAX_HEADER_SIZE 4096
struct gengetopt_args_info {
char *user_arg; /* Username to send to HTTPS proxy for auth. */
@ -40,19 +40,26 @@ 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). */
int quiet_flag; /* Turn on quiet mode (default=off). */
int standalone_arg; /* Turn on stdalone (-a) on port */
char *standalone_arg; /* Turn on standalone (-a) on [addr:]port */
char *standalone_addr;
char *standalone_iface;
int standalone_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. */
@ -69,16 +76,21 @@ 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 quiet_given; /* Whether quiet mode 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 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-2008 Jos Visser / Mark Janssen */
/* Contact: josv@osp.nl / maniac@maniac.nl */
/* Proxytunnel - (C) 2001-2023 Jos Visser / Mark Janssen */
/* Contact: josv@osp.nl / mark@sig-io.nl */
/*
* This program is free software; you can redistribute it and/or modify
@ -17,7 +17,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define VERSION "1.10.20210128"
#define VERSION "1.12.3"
#define VERSION_YEAR "2025"
#define VERSION_DATE "2025-03-07"
#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,6 +5,9 @@ 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
@ -15,7 +18,7 @@ clean:
rm -f proxytunnel.1 *.html *.xml
%.1.html: %.1.adoc
asciidoc -d manpage $<
asciidoc -d manpage -arevnumber=$(version) -arevdate=$(version_date) $<
%.1: %.1.xml
xmlto man $<
@ -24,4 +27,4 @@ clean:
asciidoc $<
%.1.xml: %.1.adoc
asciidoc -b docbook -d manpage $<
asciidoc -b docbook -d manpage -arevnumber=$(version) -arevdate=$(version_date) $<

View file

@ -1,6 +1,4 @@
= proxytunnel(1)
Proxytunnel developers
v1.9.0, Augustus 2008
== NAME
@ -8,7 +6,7 @@ proxytunnel - program to tunnel a connection through a standard HTTPS proxy
== SYNOPSIS
*proxytunnel* _[OPTION]_...
*proxytunnel* [_OPTION…_]
== DESCRIPTION
@ -21,44 +19,48 @@ 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*=_port_::
Run as standalone daemon on specified _port_
*-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
*-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
*-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.
*-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, you can also
specify them as the argument to the proxytunnel command
*-d*, *--dest*=_host_++:++_port_::
Use _host_ and _port_ as the destination for the tunnel. This is a
mandatory option.
*-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
*-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.)
SSL encrypt data between local and remote (secondary) proxy.
== ADDITIONAL OPTIONS
*-T*, *--no-ssl3*::
Prevent the use of SSLv3 in encrypted connections (default: enabled)
*-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).
*-z*, *--no-check-certificate*::
Do not verify server SSL certificate when establishing an SSL connection.
@ -69,63 +71,84 @@ 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: /etc/ssl/certs)
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.
*-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
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.
*-N*, *--ntlm*::
Use NTLM basd authentication
Use NTLM based 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
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.
*-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
== 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.
Print version and exit.
== USAGE
@ -165,7 +188,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
aggresively. If you see your connection dropping out, try to lower the value
aggressively. 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
@ -192,27 +215,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
@ -221,7 +244,8 @@ variables:
== BUGS
This software is bug-free, at least we'd like to think so. If you do not
agree with us, please attach the proof to your friendly email :)
agree with us, please provide the proof with your friendly report at
https://github.com/proxytunnel/proxytunnel/issues :)
== AUTHOR
@ -230,4 +254,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.
Homepage at http://proxytunnel.sourceforge.net/
Homepages at https://proxytunnel.sourceforge.io and https://github.com/proxytunnel/proxytunnel

61
flake.lock generated Normal file
View file

@ -0,0 +1,61 @@
{
"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
}

33
flake.nix Normal file
View file

@ -0,0 +1,33 @@
{
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,17 +37,16 @@
* header
*/
void analyze_HTTP(PTSTREAM *pts) {
char *p = strtok( buf, " ");
char *p;
/* Strip html error pages for faulty proxies (Stephane Engel <steph[at]macchiati.org>) */
while (strncmp( p, "HTTP/", 5) != 0 ) {
if ( readline(pts) ) {
p = strtok( buf, " ");
} else {
do {
if (readline(pts) <= 0) {
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 );
@ -117,6 +116,7 @@ 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 (args_info.remproxy_given ) {
if (ntlm_challenge < 3 && 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 == 1) {
ntlm_challenge = 2;
if (ntlm_challenge == 2) {
ntlm_challenge = 3;
} 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 = malloc(strlen(buf) + 1);
char *dstr = calloc(1, strlen(buf) + 1);
strncpy( dstr, buf, strlen(buf));
if (strcmp(dstr, ""))
message( " <- %s\n", dstr );

31
nix/proxytunnel.nix Normal file
View file

@ -0,0 +1,31 @@
{
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,14 +28,28 @@
#include "proxytunnel.h"
#include <ctype.h>
#include <sys/time.h>
#include <openssl/md4.h>
#include <openssl/md5.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
#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;
@ -54,19 +68,72 @@ int bloblen;
unsigned char *t_info;
int t_info_len;
unsigned long flags;
uint32_t 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 *)malloc(len);
if (!type1) {
message("Fatal Error in build type1, Malloc failed\n");
exit(-1);
}
type1 = (ntlm_type1 *)alloca(len);
memset(type1, 0, len);
type1->signature[0] = 'N';
@ -83,7 +150,6 @@ void build_type1() {
base64((unsigned char *)ntlm_type1_buf, (unsigned char *)type1, len);
free(type1);
return;
}
@ -181,11 +247,7 @@ 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 *)malloc(len);
if (!type3) {
message("Fatal Error in build type3, Malloc failed\n");
exit(-1);
}
type3 = (ntlm_type3 *)alloca(len);
t3 = (unsigned char *) type3;
memset(type3, 0, len);
@ -231,7 +293,6 @@ void build_type3_response() {
base64((unsigned char *)ntlm_type3_buf, (unsigned char *)type3, len);
free(type3);
return;
}
@ -247,7 +308,10 @@ 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];
@ -255,10 +319,15 @@ 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) {
MD5_CTX tctx;
MD5_Init( &tctx );
MD5_Update( &tctx, key, key_len );
MD5_Final( tk, &tctx );
#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
key = tk;
key_len = 16;
}
@ -275,10 +344,10 @@ unsigned char digest[16]; /* caller digest to be filled in */
*/
/* start out by storing key in pads */
bzero( k_ipad, sizeof k_ipad);
bzero( k_opad, sizeof k_opad);
bcopy( key, k_ipad, key_len);
bcopy( key, k_opad, key_len);
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);
/* XOR key with ipad and opad values */
for (i=0; i<64; i++) {
@ -287,22 +356,39 @@ 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;
@ -327,9 +413,15 @@ 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: ");
@ -339,12 +431,8 @@ void build_ntlm2_response() {
}
userdomlen = sizeof(unsigned char) * (strlen(args_info.user_arg) + strlen(domain)) * 2;
userdom = (unsigned char *)malloc(userdomlen);
userdom = (unsigned char *)alloca(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++) {
@ -378,8 +466,6 @@ 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,6 +18,10 @@
*/
/* ntlm.h */
#include <stdint.h>
void init_ntlm();
void build_type1();
int parse_type2(unsigned char *buf);
void build_type3_response();
@ -55,53 +59,53 @@ extern char ntlm_type3_buf[4096];
typedef struct {
unsigned short length;
unsigned short space;
unsigned long offset;
uint16_t length;
uint16_t space;
uint32_t offset;
} security_buf_t;
typedef struct {
unsigned char signature[8];
unsigned long message_type;
unsigned long flags;
uint8_t signature[8];
uint32_t message_type;
uint32_t flags;
security_buf_t domain;
security_buf_t workstation;
} ntlm_type1;
typedef struct {
unsigned char signature[8];
unsigned long message_type;
uint8_t signature[8];
uint32_t message_type;
security_buf_t target_name;
unsigned long flags;
unsigned char challenge[8];
unsigned long context1;
unsigned long context2;
uint32_t flags;
uint8_t challenge[8];
uint32_t context1;
uint32_t context2;
security_buf_t target_info;
unsigned char data_start;
uint8_t data_start;
} ntlm_type2;
typedef struct {
unsigned char signature[8];
unsigned long message_type;
uint8_t signature[8];
uint32_t message_type;
security_buf_t LM_response;
security_buf_t NTLM_response;
security_buf_t domain;
security_buf_t user;
security_buf_t workstation;
unsigned char session[8];
unsigned long flags;
unsigned char pad[8];
uint8_t session[8];
uint32_t flags;
uint8_t pad[8];
} ntlm_type3;
typedef struct {
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;
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;
} 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,6 +77,10 @@ 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 */
@ -155,23 +159,110 @@ 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_in sa_serv;
struct sockaddr_in sa_cli;
struct sockaddr *sa_serv_p;
socklen_t sa_serv_len;
struct sockaddr_storage sa_cli;
socklen_t client_len;
int pid = 0;
int sd_client;
char buf[80];
unsigned char addr[4];
/* Socket descriptor */
int sd;
if ( ( listen_sd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) < 0 ) {
get_sa_serv(&sa_serv_p, &sa_serv_len);
if ( ( listen_sd = socket( sa_serv_p->sa_family, SOCK_STREAM, IPPROTO_TCP ) ) < 0 ) {
my_perror( "Server socket creation failed" );
exit(1);
}
@ -181,12 +272,7 @@ void do_daemon()
#endif /* SO_REUSEPORT */
setsockopt(listen_sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
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) {
if ( bind( listen_sd, sa_serv_p, sa_serv_len ) < 0) {
my_perror("Server socket bind failed");
exit(1);
}
@ -238,6 +324,10 @@ 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 );
@ -253,6 +343,9 @@ 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 */
@ -292,9 +385,7 @@ void do_daemon()
exit( 0 );
}
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 );
log_client(pid, &sa_cli);
close( sd_client );
}
}
@ -329,6 +420,11 @@ 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,8 +30,10 @@ 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,11 +222,10 @@ 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)) {
#ifdef OPENSSL11
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
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;
}
@ -263,30 +262,33 @@ 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 (args_info.enforcetls1_flag) {
#ifdef OPENSSL11
meth = TLS_client_method();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
meth = TLS_client_method();
#else
meth = TLSv1_client_method();
meth = SSLv23_client_method();
#endif
} else {
meth = SSLv23_client_method();
}
SSL_load_error_strings();
ctx = SSL_CTX_new (meth);
if (args_info.no_ssl3_flag) {
ssl_options |= SSL_OP_NO_SSLv3;
}
ssl_options |= SSL_OP_NO_SSLv3;
SSL_CTX_set_options (ctx, ssl_options);
if ( !args_info.no_check_cert_flag ) {
@ -308,19 +310,33 @@ 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 */
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 ) {
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 ) {
goto fail;
}
@ -329,12 +345,16 @@ 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 < 0) {
message( "TLS SNI error, giving up: SSL_set_tlsext_host_name returned error message:\n %u\n", res );
exit( 1 );
if ( res != 1 ) {
message( "SSL_set_tlsext_host_name() failed for host name '%s'. "
"TLS SNI error, giving up\n", peer_host);
goto fail;
}
SSL_connect (ssl);
if ( SSL_connect (ssl) <= 0) {
message( "SSL_connect failed\n");
goto fail;
}
if ( !args_info.no_check_cert_flag ) {
/* Make sure peer presented a certificate */
@ -357,7 +377,6 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) {
goto fail;
}
free(peer_host);
X509_free(cert);
}
@ -375,9 +394,6 @@ fail:
if (cert != NULL) {
X509_free(cert);
}
if (peer_host != NULL) {
free(peer_host);
}
#endif /* USE_SSL */
exit(1);
}

View file

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