diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml new file mode 100644 index 0000000..fa4e2a0 --- /dev/null +++ b/.github/workflows/cygwin.yml @@ -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 diff --git a/INSTALL.md b/INSTALL.md index a7db3fe..b91643d 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -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) . +``` diff --git a/Makefile b/Makefile index a925a89..d38b82e 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/README.md b/README.md index dc5836d..3227aa3 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/cmdline.c b/cmdline.c index 7e5db30..bc89020 100644 --- a/cmdline.c +++ b/cmdline.c @@ -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. */ diff --git a/cmdline.h b/cmdline.h index 93cf460..1ad3eb1 100644 --- a/cmdline.h +++ b/cmdline.h @@ -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 ); diff --git a/docs/proxytunnel.1.adoc b/docs/proxytunnel.1.adoc index 0e8e6b5..169987f 100644 --- a/docs/proxytunnel.1.adoc +++ b/docs/proxytunnel.1.adoc @@ -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 diff --git a/http.c b/http.c index 12e1956..51808c3 100644 --- a/http.c +++ b/http.c @@ -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 ) { diff --git a/io.c b/io.c index 56d516e..49e76d2 100644 --- a/io.c +++ b/io.c @@ -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 ); } diff --git a/proxytunnel.c b/proxytunnel.c index 4b57b0b..8d1eae6 100644 --- a/proxytunnel.c +++ b/proxytunnel.c @@ -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"); diff --git a/proxytunnel.h b/proxytunnel.h index 88a5471..3aea944 100644 --- a/proxytunnel.h +++ b/proxytunnel.h @@ -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 diff --git a/ptstream.c b/ptstream.c index d7c6424..a43498f 100644 --- a/ptstream.c +++ b/ptstream.c @@ -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; diff --git a/setproctitle.c b/setproctitle.c index 32ac246..4142ef6 100644 --- a/setproctitle.c +++ b/setproctitle.c @@ -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;