Merge pull request #102 from denischanc/master

Add option to disable SNI; build under Cygwin; correction on Host header; correction on protocol display on console.
This commit is contained in:
Sven Geuer 2026-04-20 18:21:50 +02:00 committed by GitHub
commit 2827a6647e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 95 additions and 42 deletions

19
.github/workflows/cygwin.yml vendored Normal file
View file

@ -0,0 +1,19 @@
name: Build for Windows (Cygwin)
on:
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v6.0.2
- uses: cygwin/cygwin-install-action@v6.1
with:
packages: gcc-core make binutils libssl-devel xmlto asciidoc docbook-xml45
- name: Build
shell: bash {0}
run: make && make docs
- name: Check
shell: bash {0}
run: ldd proxytunnel.exe | awk '{print $3}' | grep -vi windows/system32 | sort | uniq

View file

@ -1,7 +1,7 @@
# Short guide to installing proxytunnel
On most modern **unix systems**, use the normal Makefile, possibly uncommenting
the section related to your system (darwin/cygwin/solaris/openbsd)
the section related to your system (darwin/solaris/openbsd)
If you want to enable setproctitle functionality, add a CFLAGS define
-DSETPROCTITLE (uncomment sample in Makefile)
@ -94,15 +94,20 @@ me@mymachine MSYS ~ cp /usr/bin/msys-2.0.dll /usr/bin/msys-crypto-1.1.dll /usr/
# Cygwin :
Currently cygwin's openssl isn't in a compilable state, change md4.h and
md5.h in /usr/include
and replace 'size_t' with 'unsigned long'
Install Cygwin from [cygwin web site](https://cygwin.com).
To link the final executable:
gcc -o proxytunnel *.o /lib/libcrypto.dll.a /lib/libssl.dll.a
Following packages are required :
```
$ setup-x86_64.exe -n -q -P gcc-core,make,binutils,libssl-devel,xmlto,asciidoc,docbook-xml45
```
To run, copy the required dll's from the cygwin-bin dir to the windows
system dir, or the proxytunnel directory (cygcrypto-0.9.8.dll,
cygssl-0.9.8.dll, cygwin1.dll )
To build :
```
$ make
$ make docs
```
Setproctitle doesn't work on cygwin (afaik)
To use `proxytunnel.exe` from windows, copy cygwin and openssl dll to the same directory as proxytunnel.exe (use `ldd` cmd to see what dll are used by `proxytunnel.exe`) cmd:
```
$ cp $(ldd proxytunnel.exe | awk '{print $3}' | grep -vi windows/system32 | sort | uniq) .
```

View file

@ -14,12 +14,14 @@ OPTFLAGS += -DHAVE_GETOPT_LONG
# Comment if you don't have/want ssl
OPTFLAGS += -DUSE_SSL
# MSYS
# The current version of gcc from MSYS defines __MSYS__ and __CYGWIN__.
# To avoid to change the code, simply define CYGWIN additionally.
ifneq ($(filter $(MSYSTEM),MSYS MINGW32 MINGW64 UCRT64),)
CFLAGS += -DCYGWIN
else
# MSYS/CYGWIN
# The current version of gcc from MSYS defines __MSYS__ and __CYGWIN__, from CYGWIN defines __CYGWIN__.
# To avoid to change the code, simply define CYGWIN additionally.
ifneq ($(filter $(shell uname -o),Msys Cygwin),)
OPTFLAGS += -DCYGWIN
endif
ifeq ($(filter $(shell uname -o),Msys),)
# Most systems, MSYS definitely not
OPTFLAGS += -DSETPROCTITLE -DSPT_TYPE=2
endif
@ -39,9 +41,6 @@ endif
#OPTFLAGS += -DDEFAULT_CA_FILE='"/usr/local/etc/openssl@1.1/cacert.pem"'
#OPTFLAGS += -DDEFAULT_CA_DIR=NULL
# CYGWIN
#OPTFLAGS += -DCYGWIN
# SOLARIS
#LDFLAGS += -lsocket -lnsl
#LDFLAGS += -L/usr/local/ssl/lib # Path to your SSL lib dir

View file

@ -60,6 +60,7 @@ Additional options for specific features:
-H, --header=STRING Add additional HTTP headers to send to proxy
-o, --host=STRING Send custom Host Header/SNI
-x, --proctitle=STRING Use a different process title
-I, --no-sni Disable SNI
Miscellaneous options:
-v, --verbose Turn on verbosity

View file

@ -98,6 +98,7 @@ void cmdline_parser_print_help (void) {
#ifdef SETPROCTITLE
" -x, --proctitle=STRING Use a different process title\n"
#endif
" -I, --no-sni Disable SNI\n"
"\n"
"Miscellaneous options:\n"
" -v, --verbose Turn on verbosity\n"
@ -164,6 +165,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
/* args_info->enforcetls1_given = 0; */
args_info->host_given = 0;
args_info->cacert_given = 0;
args_info->no_sni_flag = 0;
/* No... we can't make this a function... -- Maniac */
#define clear_args() \
@ -202,6 +204,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
args_info->cacert_arg = NULL; \
args_info->enforceipv4_flag = 0; \
args_info->enforceipv6_flag = 0; \
args_info->no_sni_flag = 0; \
}
clear_args();
@ -250,12 +253,13 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
{ "cacert", 1, NULL, 'C' },
{ "ipv4", 0, NULL, '4' },
{ "ipv6", 0, NULL, '6' },
{ "no-sni", 0, NULL, 'I' },
{ NULL, 0, NULL, 0 }
};
c = getopt_long (argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:c:k:vNeEXWBqLo:TzC:46", long_options, &option_index);
c = getopt_long (argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:c:k:vNeEXWBqLo:TzC:46I", long_options, &option_index);
#else
c = getopt( argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:c:k:vNeEXWBqLo:TzC:46" );
c = getopt( argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:c:k:vNeEXWBqLo:TzC:46I" );
#endif
if (c == -1)
@ -524,6 +528,12 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
message("IPv6 enforced\n");
break;
case 'I': /* Disable SNI */
args_info->no_sni_flag = 1;
if( args_info->verbose_flag )
message("Disable SNI\n");
break;
case 0: /* Long option with no short option */
case '?': /* Invalid option. */

View file

@ -93,6 +93,7 @@ struct gengetopt_args_info {
/* int enforcetls1_given; Wheter to enforce TLSv1 */
int host_given; /* Wheter we override the Host Header */
int cacert_given; /* Whether cacert was given */
int no_sni_flag; /* Disable SNI */
};
int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *args_info );

View file

@ -135,6 +135,9 @@ also be used for other proxy-traversing purposes like proxy bouncing.
*-x*, *--proctitle*=_STRING_::
Use a different process title.
*-I*, *--no-sni*::
Disable SNI.
== MISCELLANEOUS OPTIONS

2
http.c
View file

@ -108,7 +108,7 @@ void proxy_protocol(PTSTREAM *pts) {
} else {
if( args_info.verbose_flag )
message( "\nTunneling to %s (destination)\n", args_info.dest_arg );
sprintf( buf, "CONNECT %s HTTP/1.1\r\nHost: %s\r\n", args_info.dest_arg, args_info.host_arg ? args_info.host_arg : args_info.proxyhost_arg );
sprintf( buf, "CONNECT %s HTTP/1.1\r\nHost: %s\r\n", args_info.dest_arg, args_info.host_arg ? args_info.host_arg : args_info.dest_arg );
}
if ( args_info.user_given && args_info.pass_given ) {

9
io.c
View file

@ -57,10 +57,11 @@ int readline(PTSTREAM *pts) {
if( args_info.verbose_flag ) {
/* Copy line of data into dstr without trailing newline */
char *dstr = calloc(1, strlen(buf) + 1);
strncpy( dstr, buf, strlen(buf));
if (strcmp(dstr, ""))
message( " <- %s\n", dstr );
int len = strlen(buf);
buf[len - 2] = 0;
if (strcmp(buf, ""))
message( " <- %s\n", buf );
buf[len - 2] = '\r';
}
return strlen( buf );
}

View file

@ -284,9 +284,9 @@ void do_daemon()
#ifdef SETPROCTITLE
if( ! args_info.proctitle_given )
setproctitle( "[daemon]\0" );
setproctitle( "[daemon]" );
else
setproctitle( "\0" );
setproctitle( "" );
#else
if( args_info.proctitle_given )
message( "Setting process-title is not supported in this build\n");
@ -374,9 +374,9 @@ void do_daemon()
#ifdef SETPROCTITLE
if( ! args_info.proctitle_given )
setproctitle( "[cpio]\0" );
setproctitle( "[cpio]" );
else
setproctitle( "\0" );
setproctitle( "" );
#else
if( args_info.proctitle_given )
message( "Setting process-title is not supported in this build\n");
@ -406,7 +406,11 @@ int main( int argc, char *argv[] ) {
cmdline_parser( argc, argv, &args_info );
#ifdef SETPROCTITLE
#ifndef CYGWIN
initsetproctitle( argc, argv );
#else
initsetproctitlecygwin( argc, argv );
#endif
#endif
/*
@ -499,9 +503,9 @@ int main( int argc, char *argv[] ) {
#ifdef SETPROCTITLE
if( ! args_info.proctitle_given )
setproctitle( "[cpio]\0" );
setproctitle( "[cpio]" );
else
setproctitle( "\0" );
setproctitle( "" );
#else
if( args_info.proctitle_given )
message( "Setting process-title is not supported in this build\n");

View file

@ -31,7 +31,11 @@ void proxy_protocol(PTSTREAM *pts);
void closeall();
void do_daemon();
#ifdef SETPROCTITLE
#ifndef CYGWIN
void initsetproctitle(int argc, char *argv[]);
#else
void initsetproctitlecygwin(int argc, char *argv[]);
#endif
void setproctitle(const char *fmt, ...);
#endif

View file

@ -340,17 +340,19 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) {
goto fail;
}
/* SNI support */
if ( args_info.verbose_flag ) {
message( "Set SNI hostname to %s\n", peer_host);
if(!args_info.no_sni_flag) {
/* SNI support */
if ( args_info.verbose_flag ) {
message( "Set SNI hostname to %s\n", peer_host);
}
res = SSL_set_tlsext_host_name(ssl, peer_host);
if ( res != 1 ) {
message( "SSL_set_tlsext_host_name() failed for host name '%s'. "
"TLS SNI error, giving up\n", peer_host);
goto fail;
}
}
res = SSL_set_tlsext_host_name(ssl, peer_host);
if ( res != 1 ) {
message( "SSL_set_tlsext_host_name() failed for host name '%s'. "
"TLS SNI error, giving up\n", peer_host);
goto fail;
}
if ( SSL_connect (ssl) <= 0) {
message( "SSL_connect failed\n");
goto fail;

View file

@ -67,7 +67,11 @@ static size_t argv_env_len = 0;
#endif /* HAVE_SETPROCTITLE */
#ifndef CYGWIN
void initsetproctitle(int argc, char *argv[]) {
#else
void initsetproctitlecygwin(int argc, char *argv[]) {
#endif
#if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV
extern char **environ;
char *lastargv = NULL;