From 3f667792af2e70a344088b3dcf904fb72b888e4f Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20R=C4=99korajski?= Date: Wed, 13 Oct 2021 22:42:05 +0200 Subject: [PATCH] - up to 1.10.20210604 --- proxytunnel-git-openssl-warnings.patch | 28 - proxytunnel-git.patch | 1085 ------------------------ proxytunnel.spec | 12 +- 3 files changed, 4 insertions(+), 1121 deletions(-) delete mode 100644 proxytunnel-git-openssl-warnings.patch delete mode 100644 proxytunnel-git.patch diff --git a/proxytunnel-git-openssl-warnings.patch b/proxytunnel-git-openssl-warnings.patch deleted file mode 100644 index 9ac1112..0000000 --- a/proxytunnel-git-openssl-warnings.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit b8c15860719a3ca182b1e7689df231edc68899f5 -Author: Adam Gołębiowski -Date: Sun Sep 23 16:11:21 2018 +0200 - - ptstream.c: fix openssl-1.1 warnings - -diff --git a/ptstream.c b/ptstream.c -index d1c5f44..bf3995f 100644 ---- a/ptstream.c -+++ b/ptstream.c -@@ -208,7 +208,7 @@ int check_cert_names(X509 *cert, char *peer_host) { - for (i = 0; i < san_count; i++) { - gn = sk_GENERAL_NAME_value(gen_names, i); - if (gn->type == GEN_DNS && !(peer_host_is_ipv4 || peer_host_is_ipv6)) { -- if (check_cert_valid_host((char*)ASN1_STRING_data(gn->d.ia5), peer_host)) { -+ if (check_cert_valid_host((char*)ASN1_STRING_get0_data(gn->d.ia5), peer_host)) { - return 1; - } - } else if (gn->type == GEN_IPADD) { -@@ -254,7 +254,7 @@ int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) { - /* Initialise the connection */ - SSLeay_add_ssl_algorithms(); - if (args_info.enforcetls1_flag) { -- meth = TLSv1_client_method(); -+ meth = TLS_client_method(); - } else { - meth = SSLv23_client_method(); - } diff --git a/proxytunnel-git.patch b/proxytunnel-git.patch deleted file mode 100644 index 9ae9de1..0000000 --- a/proxytunnel-git.patch +++ /dev/null @@ -1,1085 +0,0 @@ -diff --git a/.gitignore b/.gitignore -new file mode 100644 -index 0000000..c15583a ---- /dev/null -+++ b/.gitignore -@@ -0,0 +1,4 @@ -+*.o -+*.exec -+proxytunnel.exe -+proxytunnel -diff --git a/.travis.yml b/.travis.yml -new file mode 100644 -index 0000000..1348562 ---- /dev/null -+++ b/.travis.yml -@@ -0,0 +1,14 @@ -+language: c -+compiler: -+ - clang -+ - gcc -+addons: -+ apt: -+ packages: -+ - asciidoc -+ - xmlto -+install: -+ - make clean -+script: -+ - make -+ - make docs -\ No newline at end of file -diff --git a/Makefile b/Makefile -index 006b5b1..57328e8 100644 ---- a/Makefile -+++ b/Makefile -@@ -5,17 +5,9 @@ - name = proxytunnel - version = $(shell awk 'BEGIN { FS="\"" } /^\#define VERSION / { print $$2 }' config.h) - --ifneq ($(wildcard .svn),) --revision = $(shell svnversion | awk 'BEGIN { RS=":" } { next } END { print $$1 }') --else --revision = $(shell echo '$$Revision$$' | sed -e 's/\$$Revision: \([0-9]\+\) \$$$$/\1/') --endif -- - CC ?= cc - CFLAGS ?= -Wall -O2 -ggdb - --OPTFLAGS = -DREVISION=\"$(revision)\" -- - # Comment on non-gnu systems - OPTFLAGS += -DHAVE_GETOPT_LONG - -@@ -46,9 +38,9 @@ OPTFLAGS += -DSO_REUSEPORT - - # END system dependant block - --SSL_LIBS := $(shell pkg-config --libs libssl 2>/dev/null) --ifeq ($(SSL_LIBS),) - 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 -@@ -63,8 +55,6 @@ mandir = $(datadir)/man - # Remove strlcpy/strlcat on (open)bsd/darwin systems - OBJ = proxytunnel.o \ - base64.o \ -- strlcpy.o \ -- strlcat.o \ - strzcat.o \ - setproctitle.o \ - io.o \ -@@ -76,9 +66,15 @@ OBJ = proxytunnel.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 -+all: proxytunnel - - docs: - $(MAKE) -C docs -@@ -91,7 +87,8 @@ clean: - $(MAKE) -C docs clean - - install: -- install -Dp -m0755 $(name) $(DESTDIR)$(bindir)/$(name) -+ install -d $(DESTDIR)$(bindir) -+ install -p -m555 $(name) $(DESTDIR)$(bindir) - $(MAKE) -C docs install - - .c.o: -diff --git a/README b/README -index 1c30836..bdb7fe3 100644 ---- a/README -+++ b/README -@@ -3,8 +3,6 @@ proxytunnel - ----------- - - Author: Jos Visser , Mark Janssen --Date: Mon Mar 3 22:49:43 CET 2008 --Version: 1.9.0 - - Hi all, - -@@ -22,27 +20,32 @@ Proxytunnel is very easy to use, when running proxytunnel with the help - option it specifies it's command-line options. - - $ ./proxytunnel --help --proxytunnel 1.9.0 (rev 224) Copyright 2001-2008 Proxytunnel Project -+proxytunnel 1.9.9 Copyright 2001-2018 Proxytunnel Project - Usage: proxytunnel [OPTIONS]... --Build generic tunnels trough HTTPS proxy's, supports HTTP authorization -+Build generic tunnels through HTTPS proxies using HTTP authentication - - Standard options: -- -i, --inetd Run from inetd (default=off) -+ -i, --inetd Run from inetd (default: off) - -a, --standalone=INT Run as standalone daemon on specified port - -p, --proxy=STRING Local proxy host:port combination - -r, --remproxy=STRING Remote proxy host:port combination (using 2 proxies) - -d, --dest=STRING Destination host:port combination - -e, --encrypt SSL encrypt data between local proxy and destination - -E, --encrypt-proxy SSL encrypt data between client and local proxy -- -X, --encrypt-remproxy Encrypt between 1st and 2nd proxy using SSL -+ -X, --encrypt-remproxy SSL encrypt data between local and remote proxy -+ -L (legacy) enforce TLSv1 connection -+ -T, --no-ssl3 Do not connect using SSLv3 - - Additional options for specific features: -+ -z, --no-check-certficate Don't verify server SSL certificate -+ -C, --cacert=STRING Path to trusted CA certificate or directory - -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 -+ -R, --remproxyauth=STRING Remote proxy auth credentials user:pass combination - -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 - -x, --proctitle=STRING Use a different process title - - Miscellaneous options: -@@ -51,7 +54,6 @@ Miscellaneous options: - -h, --help Print help and exit - -V, --version Print version and exit - -- - To use this program with OpenSSH to connect to a host somewhere, create - a $HOME/.ssh/config file with the following content: - -diff --git a/TODO b/TODO -index 4339a0f..45c19e4 100644 ---- a/TODO -+++ b/TODO -@@ -8,14 +8,11 @@ - - - ### SSL proxy support --- Lobby for the Apache project to allow CONNECT over SSL (much like GET, -- PUT and HEAD is supported over SSL) -- see: http://issues.apache.org/bugzilla/show_bug.cgi?id=29744 -+- Starting with Apache 2.4 using CONNECT over SSL is supported !! -+ See: http://issues.apache.org/bugzilla/show_bug.cgi?id=29744 - - - ### Code cleanup --- Fix permissions in subversion tree (some files are wrongly executable) -- - - Find some hardcore C experts to help us improve the code quality - - - Improve the error output, make it consistent throughout the program -diff --git a/cmdline.c b/cmdline.c -index 15ebe98..e1ee9b0 100644 ---- a/cmdline.c -+++ b/cmdline.c -@@ -38,14 +38,14 @@ 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 (rev %s) Copyright 2001-2008 Proxytunnel Project\n", PACKAGE, VERSION, REVISION); -+ printf ("%s %s Copyright 2001-2018 Proxytunnel Project\n", PACKAGE, VERSION); - } - - void cmdline_parser_print_help (void) { - cmdline_parser_print_version (); - printf( - "Usage: %s [OPTIONS]...\n" --"Build generic tunnels trough HTTPS proxies using HTTP authentication\n" -+"Build generic tunnels through HTTPS proxies using HTTP authentication\n" - "\n" - "Standard options:\n" - // FIXME: " -c, --config=FILE Read config options from file\n" -@@ -59,9 +59,15 @@ 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" -+" -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 -+" -z, --no-check-certficate Don't verify server SSL certificate\n" -+" -C, --cacert=STRING Path to trusted CA certificate or directory\n" -+#endif - " -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" -@@ -72,6 +78,7 @@ void cmdline_parser_print_help (void) { - " -N, --ntlm Use NTLM based authentication\n" - " -t, --domain=STRING NTLM domain (default: autodetect)\n" - " -H, --header=STRING Add additional HTTP headers to send to proxy\n" -+" -o STRING send custom Host Header\n" - #ifdef SETPROCTITLE - " -x, --proctitle=STRING Use a different process title\n" - #endif -@@ -132,6 +139,9 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar - args_info->encryptproxy_given = 0; - args_info->encryptremproxy_given = 0; - args_info->proctitle_given = 0; -+ args_info->enforcetls1_given = 0; -+ args_info->host_given = 0; -+ args_info->cacert_given = 0; - - /* No... we can't make this a function... -- Maniac */ - #define clear_args() \ -@@ -156,8 +166,13 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar - args_info->encrypt_flag = 0; \ - args_info->encryptproxy_flag = 0; \ - args_info->encryptremproxy_flag = 0; \ -+ args_info->no_ssl3_flag = 0; \ - args_info->proctitle_arg = NULL; \ --} -+ args_info->enforcetls1_flag = 0; \ -+ args_info->host_arg = NULL; \ -+ args_info->no_check_cert_flag = 0; \ -+ args_info->cacert_arg = NULL; \ -+} - - clear_args(); - -@@ -189,6 +204,8 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar - { "remproxy", 1, NULL, 'r' }, - { "remproxyauth", 1, NULL, 'R' }, - { "proctitle", 1, NULL, 'x' }, -+ { "host", 1, NULL, 'o' }, -+ { "tlsenforce", 1, NULL, 'L' }, - { "header", 1, NULL, 'H' }, - { "verbose", 0, NULL, 'v' }, - { "ntlm", 0, NULL, 'N' }, -@@ -198,12 +215,15 @@ 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' }, -+ { "no-ssl3", 0, NULL, 'T' }, -+ { "no-check-certificate",0,NULL,'z' }, -+ { "cacert", 1, NULL, 'C' }, - { NULL, 0, NULL, 0 } - }; - -- c = getopt_long (argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:nvNeEXq", long_options, &option_index); -+ c = getopt_long (argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:nvNeEXqLo:TzC:", long_options, &option_index); - #else -- c = getopt( argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:nvNeEXq" ); -+ c = getopt( argc, argv, "hVia:u:s:t:F:p:P:r:R:d:H:x:nvNeEXqLo:TzC:" ); - #endif - - if (c == -1) -@@ -262,6 +282,18 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar - args_info->proctitle_arg = gengetopt_strdup (optarg); - break; - -+ case 'L': -+ args_info->enforcetls1_given = 1; -+ message("Enforcing TLSv1"); -+ args_info->enforcetls1_flag = 1; -+ break; -+ -+ case 'o': -+ args_info->host_given = 1; -+ message("Host-header override enabled\n"); -+ args_info->host_arg = gengetopt_strdup (optarg); -+ break; -+ - case 'u': /* Username to send to HTTPS proxy for authentication. */ - if (args_info->user_given) { - fprintf (stderr, "%s: `--user' (`-u'), `--proxyauth' (`-P') or `--passfile' (`-F') option given more than once\n", PACKAGE); -@@ -370,6 +402,11 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar - message("SSL local to remote proxy enabled\n"); - break; - -+ case 'T': /* Turn off SSLv3 */ -+ args_info->no_ssl3_flag = !(args_info->no_ssl3_flag); -+ if( args_info->verbose_flag ) -+ message("SSLv3 disabled\n"); -+ break; - - case 'd': /* Destination host to built the tunnel to. */ - if (args_info->dest_given) { -@@ -403,6 +440,22 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar - args_info->quiet_flag = !(args_info->quiet_flag); - break; - -+ case 'z': /* Don't verify server SSL certificate */ -+ args_info->no_check_cert_flag = 1; -+ if( args_info->verbose_flag ) -+ message("Server SSL certificate verification disabled\n"); -+ break; -+ -+ case 'C': /* Trusted CA certificate (or directory) for server SSL certificate verification */ -+ if (args_info->cacert_given) { -+ fprintf (stderr, "%s: `--cacert' (`-C') option given more than once\n", PACKAGE); -+ clear_args (); -+ exit(1); -+ } -+ args_info->cacert_given = 1; -+ args_info->cacert_arg = gengetopt_strdup (optarg); -+ break; -+ - case 0: /* Long option with no short option */ - - case '?': /* Invalid option. */ -@@ -461,10 +514,11 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar - - if ( args_info->proxy_arg == NULL ) { - if ( ((tmp = getenv("http_proxy")) != NULL) || ((tmp = getenv("HTTP_PROXY")) != NULL) ) { -- int r; -+ //int r; - char * temp; - temp = malloc( 56+1 ); -- r = sscanf( tmp, "http://%56[^/]/", temp ); -+ sscanf( tmp, "http://%56[^/]/", temp ); -+ //r = sscanf( tmp, "http://%56[^/]/", temp ); - // message( "r = '%d'\ntemp = '%s'\n", r, temp); - - args_info->proxy_given = 1; -@@ -474,7 +528,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" ); -@@ -482,12 +536,23 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar - } - - if (args_info->proxy_given ) { -+ char proxy_arg_fmt[32]; -+ size_t proxy_arg_len; - char * phost; - int pport; - -- phost = malloc( 50+1 ); -- -- r = sscanf( args_info->proxy_arg, "%50[^:]:%5u", phost, &pport ); -+ proxy_arg_len = strlen( args_info->proxy_arg ); -+ if ( (phost = malloc( proxy_arg_len + 1 )) == NULL ) { -+ message( "Out of memory\n" ); -+ exit(1); -+ } -+ snprintf( proxy_arg_fmt, sizeof(proxy_arg_fmt), "%%%zu[^:]:%%5u", proxy_arg_len - 1 ); -+ r = sscanf( args_info->proxy_arg, proxy_arg_fmt, phost, &pport ); -+ if ( r != 2 ) { -+ /* try bracket-enclosed IPv6 literal */ -+ snprintf( proxy_arg_fmt, sizeof(proxy_arg_fmt), "[%%%zu[^]]]:%%5u", proxy_arg_len - 1 ); -+ r = sscanf( args_info->proxy_arg, proxy_arg_fmt, phost, &pport ); -+ } - if ( r == 2 ) { - args_info->proxyhost_arg = phost; - args_info->proxyport_arg = pport; -diff --git a/cmdline.h b/cmdline.h -index 2eccab7..cd85191 100644 ---- a/cmdline.h -+++ b/cmdline.h -@@ -47,7 +47,12 @@ struct gengetopt_args_info { - 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).*/ -+ 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 */ -+ char *host_arg; /* Optional Host Header */ -+ int no_check_cert_flag; /* Turn off server SSL certificate verification (default=on) */ -+ 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. */ - int user_given; /* Whether user was given. */ -@@ -71,6 +76,9 @@ struct gengetopt_args_info { - int encryptproxy_given; /* Whether encrypt was given */ - int encryptremproxy_given; /* Whether encrypt was given */ - int proctitle_given; /* Whether to override process title */ -+ int enforcetls1_given; /* Wheter to enforce TLSv1 */ -+ int host_given; /* Wheter we override the Host Header */ -+ int cacert_given; /* Whether cacert was given */ - }; - - int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *args_info ); -diff --git a/config.h b/config.h -index 4e73de1..204ded5 100644 ---- a/config.h -+++ b/config.h -@@ -17,7 +17,7 @@ - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - --#define VERSION "1.9.0" -+#define VERSION "1.9.9" - #define PACKAGE "proxytunnel" - #define PURPOSE "Build generic tunnels through HTTPS proxies" - #define AUTHORS "Jos Visser (Muppet) , Mark Janssen (Maniac) " -diff --git a/contrib/proxytunnel.spec b/contrib/proxytunnel.spec -index 0c0493d..69cd62e 100644 ---- a/contrib/proxytunnel.spec -+++ b/contrib/proxytunnel.spec -@@ -47,7 +47,7 @@ proxy authentication. - - %files - %defattr(-, root, root, 0755) --%doc CHANGES CREDITS INSTALL KNOWN_ISSUES LICENSE.txt README RELNOTES TODO docs/*.txt docs/*.html -+%doc CHANGES CREDITS INSTALL KNOWN_ISSUES LICENSE.txt README RELNOTES TODO docs/*.adoc docs/*.html - %doc %{_mandir}/man1/proxytunnel.1* - %{_bindir}/proxytunnel - -diff --git a/docs/Makefile b/docs/Makefile -index 09babbb..f313c38 100644 ---- a/docs/Makefile -+++ b/docs/Makefile -@@ -2,25 +2,26 @@ prefix = /usr/local - datadir = $(prefix)/share - mandir = $(datadir)/man - --txttargets = $(shell echo *.txt) --htmltargets = $(patsubst %.txt, %.html, $(txttargets)) -+adoctargets = $(shell echo *.adoc) -+htmltargets = $(patsubst %.adoc, %.html, $(adoctargets)) - - docs: proxytunnel.1 $(htmltargets) - - install: proxytunnel.1 -- install -Dp -m0644 proxytunnel.1 $(DESTDIR)$(mandir)/man1/proxytunnel.1 -+ install -d $(DESTDIR)$(mandir)/man1 -+ install -p proxytunnel.1 $(DESTDIR)$(mandir)/man1 - - clean: - rm -f proxytunnel.1 *.html *.xml - --%.1.html: %.1.txt -+%.1.html: %.1.adoc - asciidoc -d manpage $< - - %.1: %.1.xml - xmlto man $< - --%.html: %.txt -+%.html: %.adoc - asciidoc $< - --%.1.xml: %.1.txt -+%.1.xml: %.1.adoc - asciidoc -b docbook -d manpage $< -diff --git a/docs/proxytunnel-paper.txt b/docs/proxytunnel-paper.adoc -similarity index 100% -rename from docs/proxytunnel-paper.txt -rename to docs/proxytunnel-paper.adoc -diff --git a/docs/proxytunnel.1.txt b/docs/proxytunnel.1.adoc -similarity index 90% -rename from docs/proxytunnel.1.txt -rename to docs/proxytunnel.1.adoc -index 03fa427..a884207 100644 ---- a/docs/proxytunnel.1.txt -+++ b/docs/proxytunnel.1.adoc -@@ -49,6 +49,20 @@ also be used for other proxy-traversing purposes like proxy bouncing. - - == ADDITIONAL OPTIONS - -+*-T*, *--no-ssl3*:: -+ Prevent the use of SSLv3 in encrypted connections (default: enabled) -+ -+*-z*, *--no-check-certificate*:: -+ Do not verify server SSL certificate when establishing an SSL connection. -+ By default, the server SSL certficate is verified and the target host name -+ is checked against the server certificate's subject alternative names if -+ any are present, or common name if there are no subject alternative names. -+ -+*-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) -+ - *-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 -diff --git a/http.c b/http.c -index 3b7f6b9..3b85418 100644 ---- a/http.c -+++ b/http.c -@@ -105,11 +105,11 @@ void proxy_protocol(PTSTREAM *pts) { - if (args_info.remproxy_given ) { - if( args_info.verbose_flag ) - message( "\nTunneling to %s (remote proxy)\n", args_info.remproxy_arg ); -- sprintf( buf, "CONNECT %s HTTP/1.1\r\nHost: %s\r\n", args_info.remproxy_arg, args_info.remproxy_arg ); -+ sprintf( buf, "CONNECT %s HTTP/1.1\r\nHost: %s\r\n", args_info.remproxy_arg, args_info.host_arg ? args_info.host_arg : args_info.remproxy_arg ); - } 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.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 ); - } - - if ( args_info.user_given && args_info.pass_given ) { -@@ -157,13 +157,13 @@ void proxy_protocol(PTSTREAM *pts) { - while ( strcmp( buf, "\r\n" ) != 0 ) - readline(pts); - --/* If --encrypt-remproxy is specified, connect to the remote proxy using SSL */ -- if ( args_info.encryptremproxy_flag ) -- stream_enable_ssl(stunnel); -+ /* If --encrypt-remproxy is specified, connect to the remote proxy using SSL */ -+ if ( args_info.encryptremproxy_flag ) -+ stream_enable_ssl(stunnel, args_info.remproxy_arg); - - 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.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.dest_arg); - - if ( args_info.remuser_given && args_info.rempass_given ) - strzcat( buf, "Proxy-Authorization: Basic %s\r\n", basicauth(args_info.remuser_arg, args_info.rempass_arg )); -diff --git a/io.c b/io.c -index acbcde7..e8df31a 100644 ---- a/io.c -+++ b/io.c -@@ -29,6 +29,8 @@ - #include "proxytunnel.h" - #include "io.h" - -+#define ACTIVE 1 -+#define CLOSED 0 - - /* - * Read one line of data from the tunnel. Line is terminated by a -@@ -41,7 +43,7 @@ int readline(PTSTREAM *pts) { - - /* Read one character at a time into buf, until a newline is encountered. */ - while ( c != 10 && ( i < SIZE - 1 ) ) { -- if( stream_read( pts, &c ,1) < 0) { -+ if( stream_read( pts, &c ,1) <= 0) { - my_perror( "Socket read error" ); - exit( 1 ); - } -@@ -55,8 +57,8 @@ int readline(PTSTREAM *pts) { - - if( args_info.verbose_flag ) { - /* Copy line of data into dstr without trailing newline */ -- char *dstr = malloc(sizeof(buf) + 1); -- strlcpy( dstr, buf, strlen(buf) - 1); -+ char *dstr = malloc(strlen(buf) + 1); -+ strncpy( dstr, buf, strlen(buf)); - if (strcmp(dstr, "")) - message( " <- %s\n", dstr ); - } -@@ -81,11 +83,17 @@ void cpio(PTSTREAM *stream1, PTSTREAM *stream2) { - /* We are never interested in sockets being available for write */ - FD_ZERO( &writefds ); - -+ -+ /* experimental timeout */ -+ struct timeval select_timeout; -+ select_timeout.tv_sec = 30; /* should be fine */ -+ select_timeout.tv_usec = 0; -+ - if( args_info.verbose_flag ) - message( "\nTunnel established.\n" ); - -- /* Only diamonds are forever :-) */ -- while( 1==1 ) { -+ int stream_status = ACTIVE; -+ while( stream_status == ACTIVE ) { - /* Clear the interesting socket sets */ - FD_ZERO( &readfds ); - FD_ZERO( &exceptfds ); -@@ -99,32 +107,37 @@ void cpio(PTSTREAM *stream1, PTSTREAM *stream2) { - FD_SET( stream_get_outgoing_fd(stream1), &exceptfds ); - FD_SET( stream_get_incoming_fd(stream2), &exceptfds ); - FD_SET( stream_get_outgoing_fd(stream2), &exceptfds ); -- -- /* Wait until something happens on the registered sockets/files */ -- if ( select( max_fd + 1, &readfds, &writefds, &exceptfds, 0 ) < 0 ) { -+ -+ /* reset the timeout, since select() does modify this struct! */ -+ select_timeout.tv_sec = 30; -+ select_timeout.tv_usec = 0; -+ -+ /* Wait/timeout something happens on the registered sockets/files */ -+ int number_of_fds_ready; -+ number_of_fds_ready = select( max_fd + 1, &readfds, &writefds, &exceptfds, &select_timeout ); -+ if ( number_of_fds_ready < 0 ) { - perror("select error"); - exit(1); - } - -- /* -- * Is stream1 ready for read? If so, copy a block of data -- * from stream1 to stream2. Or else if stream2 -- * is ready for read, copy a block of data from the -- * stream2 to stream1. Otherwise an exceptional condition -- * is flagged and the program is terminated. -- */ -- if ( FD_ISSET( stream_get_incoming_fd(stream1), &readfds ) ) { -- if ( stream_copy(stream1, stream2 ) ) -- break; -- } else if( FD_ISSET( stream_get_incoming_fd(stream2), &readfds ) ) { -- if( stream_copy(stream2, stream1 ) ) -- break; -- } else { -- my_perror( "Exceptional condition" ); -- break; -- } -+ if (number_of_fds_ready > 0) { -+ /* Is stream1 ready for read? If so, copy a block of data -+ * from stream1 to stream2. Or else if stream2 -+ * is ready for read, copy a block of data from the -+ * stream2 to stream1. Otherwise an exceptional condition -+ * is flagged and the program is terminated. -+ */ -+ if ( FD_ISSET( stream_get_incoming_fd(stream1), &readfds ) ) { -+ if ( stream_copy(stream1, stream2 ) ) -+ stream_status = CLOSED; -+ } else if( FD_ISSET( stream_get_incoming_fd(stream2), &readfds ) ) { -+ if( stream_copy(stream2, stream1 ) ) -+ stream_status = CLOSED; -+ } else { -+ my_perror( "Exceptional condition" ); -+ stream_status = CLOSED; -+ } -+ } - } - closeall(); - } -- --// vim:noexpandtab:ts=4 -diff --git a/proxytunnel.c b/proxytunnel.c -index 9844e3d..18aa414 100644 ---- a/proxytunnel.c -+++ b/proxytunnel.c -@@ -66,45 +66,44 @@ void signal_handler( int signal ) { - * the socket that is connected to the proxy - */ - int tunnel_connect() { -- struct sockaddr_in sa; -- struct hostent *he; -+ struct addrinfo hints = { -+ .ai_family = AF_UNSPEC, -+ .ai_socktype = SOCK_STREAM, -+ .ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV, -+ .ai_protocol = 0 -+ }; -+ struct addrinfo * result, * rp; -+ int rc; -+ char service[6]; - int sd; - -- /* Create the socket */ -- if( ( sd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) { -- my_perror("Can not create socket"); -+ rc = snprintf( service, sizeof(service), "%d", args_info.proxyport_arg ); -+ if( ( rc < 0 ) || ( rc >= sizeof(service) ) ) { -+ /* this should never happen */ -+ message( "snprintf() failed" ); - exit(1); - } -- -- /* Lookup the IP address of the proxy */ -- if( ! ( he = gethostbyname( args_info.proxyhost_arg ) ) ) { --// FIXME: my_perror("Local proxy %s could not be resolved", args_info.proxyhost_arg); -- my_perror("Local proxy could not be resolved." ); -+ rc = getaddrinfo( args_info.proxyhost_arg, service, &hints, &result ); -+ if( rc != 0 ) { -+ message( "getaddrinfo() failed to resolve local proxy: %s\n", -+ gai_strerror( rc ) ); - exit(1); - } -- -- char ip[16]; -- snprintf(ip, 16, "%d.%d.%d.%d", he->h_addr[0] & 255, he->h_addr[1] & 255, he->h_addr[2] & 255, he->h_addr[3] & 255); -- if( args_info.verbose_flag && strcmp(args_info.proxyhost_arg, ip)) { -- message( "Local proxy %s resolves to %d.%d.%d.%d\n", -- args_info.proxyhost_arg, -- he->h_addr[0] & 255, -- he->h_addr[1] & 255, -- he->h_addr[2] & 255, -- he->h_addr[3] & 255 ); -+ for (rp = result; rp != NULL; rp = rp->ai_next) { -+ sd = socket( rp->ai_family, rp->ai_socktype, rp->ai_protocol ); -+ if( sd < 0 ) { -+ continue; -+ } -+ if( connect( sd, rp->ai_addr, rp->ai_addrlen ) == 0 ) { -+ break; -+ } -+ close(sd); - } -- -- /* Set up the structure to connect to the proxy port of the proxy host */ -- memset( &sa, '\0', sizeof( sa ) ); -- sa.sin_family = AF_INET; -- memcpy( &sa.sin_addr.s_addr, he->h_addr, 4); -- sa.sin_port = htons( args_info.proxyport_arg ); -- -- /* Connect the socket */ -- if( connect( sd, (struct sockaddr*) &sa, sizeof( sa ) ) < 0 ) { -- my_perror("connect() failed"); -+ if( rp == NULL ) { -+ my_perror( "failed to connect to local proxy" ); - exit(1); - } -+ freeaddrinfo(result); - - /* Increase interactivity of tunnel, patch by Ingo Molnar */ - int flag = 1; -@@ -266,7 +265,7 @@ void do_daemon() - #ifdef USE_SSL - /* If --encrypt-proxy is specified, connect to the proxy using SSL */ - if ( args_info.encryptproxy_flag ) -- stream_enable_ssl(stunnel); -+ stream_enable_ssl(stunnel, args_info.proxy_arg); - #endif /* USE_SSL */ - - /* Open the tunnel */ -@@ -275,7 +274,7 @@ void do_daemon() - #ifdef USE_SSL - /* If --encrypt is specified, wrap all traffic after the proxy handoff in SSL */ - if( args_info.encrypt_flag ) -- stream_enable_ssl(stunnel); -+ stream_enable_ssl(stunnel, args_info.dest_arg); - #endif /* USE_SSL */ - - #ifdef SETPROCTITLE -@@ -388,7 +387,7 @@ int main( int argc, char *argv[] ) { - /* If --encrypt-proxy is specified, connect to the proxy using SSL */ - #ifdef USE_SSL - if ( args_info.encryptproxy_flag ) -- stream_enable_ssl(stunnel); -+ stream_enable_ssl(stunnel, args_info.proxy_arg); - #endif /* USE_SSL */ - - /* Open the tunnel */ -@@ -397,7 +396,7 @@ int main( int argc, char *argv[] ) { - /* If --encrypt is specified, wrap all traffic after the proxy handoff in SSL */ - #ifdef USE_SSL - if( args_info.encrypt_flag ) -- stream_enable_ssl(stunnel); -+ stream_enable_ssl(stunnel, args_info.dest_arg); - #endif /* USE_SSL */ - - #ifdef SETPROCTITLE -diff --git a/proxytunnel.h b/proxytunnel.h -index b948be0..593cd7e 100644 ---- a/proxytunnel.h -+++ b/proxytunnel.h -@@ -26,14 +26,20 @@ void message( char *s, ... ); - void my_perror( char *msg ); - void signal_handler( int signal ); - int tunnel_connect(); --void analyze_HTTP(); --void proxy_protocol(); -+void analyze_HTTP(PTSTREAM *pts); -+void proxy_protocol(PTSTREAM *pts); - void closeall(); - void do_daemon(); - void initsetproctitle(int argc, char *argv[]); - void setproctitle(const char *fmt, ...); -+ -+#if defined(__APPLE__) && defined(__MACH__) -+/* Don't include strlcat and strlcpy since they are provided as macros on OSX */ -+#else - size_t strlcat(char *dst, const char *src, size_t siz); - size_t strlcpy(char *dst, const char *src, size_t siz); -+#endif -+ - size_t strzcat(char *dst, char *format, ...); - int main( int argc, char *argv[] ); - char * readpassphrase(const char *, char *, size_t, int); -diff --git a/ptstream.c b/ptstream.c -index 4c87c80..d1c5f44 100644 ---- a/ptstream.c -+++ b/ptstream.c -@@ -19,12 +19,15 @@ - - /* ptstream.c */ - -+#include -+#include - #include - #include - #include - #include - #include - #include -+#include - - #include "proxytunnel.h" - -@@ -142,24 +145,199 @@ int stream_copy(PTSTREAM *pts_from, PTSTREAM *pts_to) { - } - - -+/* Check the certificate host name against the expected host name */ -+/* Return 1 if peer hostname is valid, any other value indicates failure */ -+int check_cert_valid_host(const char *cert_host, const char *peer_host) { -+ if (cert_host == NULL || peer_host == NULL) { -+ return 0; -+ } -+ if (cert_host[0] == '*') { -+ if (strncmp(cert_host, "*.", 2) != 0) { -+ /* Invalid wildcard hostname */ -+ return 0; -+ } -+ /* Skip "*." */ -+ cert_host += 2; -+ /* Wildcards can only match the first subdomain component */ -+ while (*peer_host++ != '.' && *peer_host != '\0') -+ ;; -+ } -+ if (strlen(cert_host) == 0 || strlen(peer_host) == 0) { -+ return 0; -+ } -+ return strcmp(cert_host, peer_host) == 0; -+} -+ -+ -+int check_cert_valid_ip6(const unsigned char *cert_ip_data, const int cert_ip_len, const struct in6_addr *addr6) { -+ int i; -+ for (i = 0; i < cert_ip_len; i++) { -+ if (cert_ip_data[i] != addr6->s6_addr[i]) { -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+ -+int check_cert_valid_ip(const unsigned char *cert_ip_data, const int cert_ip_len, const struct in_addr *addr) { -+ int i; -+ for (i = 0; i < cert_ip_len; i++) { -+ if (cert_ip_data[i] != ((addr->s_addr >> (i * 8)) & 0xFF)) { -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+ -+int check_cert_names(X509 *cert, char *peer_host) { -+ char peer_cn[256]; -+ const GENERAL_NAME *gn; -+ STACK_OF(GENERAL_NAME) *gen_names; -+ struct in_addr addr; -+ struct in6_addr addr6; -+ int peer_host_is_ipv4 = 0, peer_host_is_ipv6 = 0; -+ int i, san_count; -+ -+ gen_names = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL); -+ san_count = sk_GENERAL_NAME_num(gen_names); -+ if (san_count > 0) { -+ peer_host_is_ipv4 = (inet_pton(AF_INET, peer_host, &addr) == 1); -+ peer_host_is_ipv6 = (peer_host_is_ipv4 ? 0 : inet_pton(AF_INET6, peer_host, &addr6) == 1); -+ for (i = 0; i < san_count; i++) { -+ gn = sk_GENERAL_NAME_value(gen_names, i); -+ if (gn->type == GEN_DNS && !(peer_host_is_ipv4 || peer_host_is_ipv6)) { -+ if (check_cert_valid_host((char*)ASN1_STRING_data(gn->d.ia5), peer_host)) { -+ return 1; -+ } -+ } else if (gn->type == GEN_IPADD) { -+ if (gn->d.ip->length == 4 && peer_host_is_ipv4) { -+ if (check_cert_valid_ip(gn->d.ip->data, gn->d.ip->length, &addr)) { -+ return 1; -+ } -+ } else if (gn->d.ip->length == 16 && peer_host_is_ipv6) { -+ if (check_cert_valid_ip6(gn->d.ip->data, gn->d.ip->length, &addr6)) { -+ return 1; -+ } -+ } -+ } -+ } -+ message("Host name %s does not match certificate subject alternative names\n", peer_host); -+ } else { -+ X509_NAME_get_text_by_NID(X509_get_subject_name(cert), NID_commonName, peer_cn, sizeof(peer_cn)); -+ message("Host name %s does not match certificate common name %s or any subject alternative names\n", peer_host, peer_cn); -+ return check_cert_valid_host(peer_cn, peer_host); -+ } -+ return 0; -+} -+ - /* Initiate an SSL handshake on this stream and encrypt all subsequent data */ --int stream_enable_ssl(PTSTREAM *pts) { -+int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg) { - #ifdef USE_SSL -- SSL_METHOD *meth; -+ const SSL_METHOD *meth; - SSL *ssl; - SSL_CTX *ctx; -- -+ long res = 1; -+ long ssl_options = 0; -+ -+ X509* cert = NULL; -+ int status; -+ struct stat st_buf; -+ const char *ca_file = NULL; -+ const char *ca_dir = "/etc/ssl/certs/"; /* Default cert directory if none given */ -+ long vresult; -+ char *peer_host = NULL; -+ char proxy_arg_fmt[32]; -+ size_t proxy_arg_len; -+ - /* Initialise the connection */ - SSLeay_add_ssl_algorithms(); -- meth = SSLv3_client_method(); -+ if (args_info.enforcetls1_flag) { -+ meth = TLSv1_client_method(); -+ } 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_CTX_set_options (ctx, ssl_options); -+ -+ if ( !args_info.no_check_cert_flag ) { -+ if ( args_info.cacert_given ) { -+ if ((status = stat(args_info.cacert_arg, &st_buf)) != 0) { -+ message("Error reading certificate path %s\n", args_info.cacert_arg); -+ goto fail; -+ } -+ if (S_ISDIR(st_buf.st_mode)) { -+ ca_dir = args_info.cacert_arg; -+ } else { -+ ca_dir = NULL; -+ ca_file = args_info.cacert_arg; -+ } -+ } -+ if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_dir)) { -+ message("Error loading certificate(s) from %s\n", args_info.cacert_arg); -+ goto fail; -+ } -+ } -+ - ssl = SSL_new (ctx); -+ - 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 ) { -+ goto fail; -+ } -+ -+ /* 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 < 0) { -+ message( "TLS SNI error, giving up: SSL_set_tlsext_host_name returned error message:\n %u\n", res ); -+ exit( 1 ); -+ } -+ - SSL_connect (ssl); - -+ if ( !args_info.no_check_cert_flag ) { -+ /* Make sure peer presented a certificate */ -+ cert = SSL_get_peer_certificate(ssl); -+ if (cert == NULL) { -+ message("No certificate presented\n"); -+ goto fail; -+ } -+ -+ /* Check that the certificate is valid */ -+ vresult = SSL_get_verify_result(ssl); -+ if (vresult != X509_V_OK) { -+ message("Certificate verification failed (%s)\n", -+ X509_verify_cert_error_string(vresult)); -+ goto fail; -+ } -+ -+ /* Verify the certificate name matches the host we are connecting to */ -+ if (!check_cert_names(cert, peer_host)) { -+ goto fail; -+ } -+ -+ free(peer_host); -+ X509_free(cert); -+ } -+ - /* Store ssl and ctx parameters */ - pts->ssl = ssl; - pts->ctx = ctx; -@@ -168,6 +346,17 @@ int stream_enable_ssl(PTSTREAM *pts) { - #endif /* USE_SSL */ - - return 1; -+ -+fail: -+#ifdef USE_SSL -+ if (cert != NULL) { -+ X509_free(cert); -+ } -+ if (peer_host != NULL) { -+ free(peer_host); -+ } -+#endif /* USE_SSL */ -+ exit(1); - } - - -diff --git a/ptstream.h b/ptstream.h -index e7efd43..ee36af2 100644 ---- a/ptstream.h -+++ b/ptstream.h -@@ -44,7 +44,7 @@ int stream_close(PTSTREAM *pts); - int stream_read(PTSTREAM *pts, void *buf, size_t len); - int stream_write(PTSTREAM *pts, void *buf, size_t len); - int stream_copy(PTSTREAM *pts_from, PTSTREAM *pts_to); --int stream_enable_ssl(PTSTREAM *pts); -+int stream_enable_ssl(PTSTREAM *pts, const char *proxy_arg); - int stream_get_incoming_fd(PTSTREAM *pts); - int stream_get_outgoing_fd(PTSTREAM *pts); - -diff --git a/readpassphrase.c b/readpassphrase.c -index 1870700..b107624 100644 ---- a/readpassphrase.c -+++ b/readpassphrase.c -@@ -135,8 +135,13 @@ restart: - oterm.c_lflag |= ECHO; - } - -- if (!(flags & RPP_STDIN)) -- (void)write(output, prompt, strlen(prompt)); -+ if (!(flags & RPP_STDIN)) { -+ ssize_t bytes_written = write(output, prompt, strlen(prompt)); -+ if (bytes_written != strlen(prompt)) { -+ message("Error on writing bytes to prompt\n"); -+ } -+ } -+ - end = buf + bufsiz - 1; - for (p = buf; (nr = read(input, &ch, 1)) == 1 && ch != '\n' && ch != '\r';) { - if (p < end) { -@@ -153,8 +158,12 @@ restart: - } - *p = '\0'; - save_errno = errno; -- if (!(term.c_lflag & ECHO)) -- (void)write(output, "\n", 1); -+ if (!(term.c_lflag & ECHO)) { -+ ssize_t bytes_written = write(output, "\n", 1); -+ if (bytes_written != 1) { -+ message("Error writing one byte to prompt\n"); -+ } -+ } - - /* Restore old terminal settings and signals. */ - if (memcmp(&term, &oterm, sizeof(term)) != 0) { diff --git a/proxytunnel.spec b/proxytunnel.spec index 45bc4c6..3c9b469 100644 --- a/proxytunnel.spec +++ b/proxytunnel.spec @@ -1,14 +1,12 @@ Summary: Proxy Tunnel ssh-over-https hack Summary(pl.UTF-8): Tunel proxy ssh-po-https Name: proxytunnel -Version: 1.9.1 +Version: 1.10.20210604 Release: 1 License: GPL Group: Applications -Source0: https://github.com/proxytunnel/proxytunnel/archive/%{version}.tar.gz -# Source0-md5: 9a844a735c9833b12c725d2118cd3e37 -Patch0: %{name}-git.patch -Patch1: %{name}-git-openssl-warnings.patch +Source0: https://github.com/proxytunnel/proxytunnel/archive/v%{version}/%{name}-%{version}.tar.gz +# Source0-md5: a8ca6a40c40b51681486e317c313d5fc URL: https://github.com/proxytunnel/proxytunnel BuildRequires: openssl-devel BuildRequires: pkgconfig @@ -43,8 +41,6 @@ aktualnie potrafi: %prep %setup -q -%patch0 -p1 -%patch1 -p1 %build %{__make} \ @@ -64,6 +60,6 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(644,root,root,755) -%doc CREDITS CHANGES README +%doc CREDITS CHANGES README.md %attr(755,root,root) %{_bindir}/* %{_mandir}/man1/* -- 2.43.0