Compare commits

...

33 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
16 changed files with 281 additions and 41 deletions

15
CHANGES Executable file → Normal file
View file

@ -1,3 +1,18 @@
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 ]

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,8 +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
endif
# System dependant blocks... if your system is listed below, uncomment
# the relevant lines
@ -59,7 +66,6 @@ mandir = $(datadir)/man
OBJ = proxytunnel.o \
base64.o \
strzcat.o \
setproctitle.o \
io.o \
http.o \
basicauth.o \
@ -70,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 \

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

@ -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}..."

View file

@ -596,7 +596,7 @@ 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" );

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. */

View file

@ -17,9 +17,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define VERSION "1.12.1"
#define VERSION_YEAR "2024"
#define VERSION_DATE "2024-02-06"
#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

@ -6,7 +6,7 @@ proxytunnel - program to tunnel a connection through a standard HTTPS proxy
== SYNOPSIS
*proxytunnel* [_OPTION…_] [_host_++:++_port_]
*proxytunnel* [_OPTION…_]
== DESCRIPTION
@ -32,15 +32,16 @@ also be used for other proxy-traversing purposes like proxy bouncing.
[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.
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.
*-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.
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.
@ -150,13 +151,6 @@ also be used for other proxy-traversing purposes like proxy bouncing.
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
Depending on your situation you might want to do any of the following things:

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
'';
}

54
ntlm.c
View file

@ -29,6 +29,9 @@
#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
@ -71,8 +74,55 @@ unsigned char lm2digest[LM2_DIGEST_LEN];
void init_ntlm() {
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PROVIDER_load(NULL, "default");
OSSL_PROVIDER_load(NULL, "legacy");
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();

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 */