mirror of
https://github.com/proxytunnel/proxytunnel.git
synced 2026-07-17 16:34:53 +00:00
Merge pull request #11 from protonet/master
fix for 100% CPU bug, two new options, bugfixes, less compiler warnings
This commit is contained in:
commit
e0ae50f789
6 changed files with 91 additions and 40 deletions
31
cmdline.c
31
cmdline.c
|
|
@ -45,7 +45,7 @@ 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,6 +59,7 @@ 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"
|
||||
#endif
|
||||
"\n"
|
||||
"Additional options for specific features:\n"
|
||||
|
|
@ -72,6 +73,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 +134,8 @@ 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;
|
||||
|
||||
/* No... we can't make this a function... -- Maniac */
|
||||
#define clear_args() \
|
||||
|
|
@ -157,6 +161,8 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
|
|||
args_info->encryptproxy_flag = 0; \
|
||||
args_info->encryptremproxy_flag = 0; \
|
||||
args_info->proctitle_arg = NULL; \
|
||||
args_info->enforcetls1_flag = 0; \
|
||||
args_info->host_arg = NULL; \
|
||||
}
|
||||
|
||||
clear_args();
|
||||
|
|
@ -189,6 +195,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' },
|
||||
|
|
@ -201,9 +209,9 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
|
|||
{ 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", 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" );
|
||||
#endif
|
||||
|
||||
if (c == -1)
|
||||
|
|
@ -262,6 +270,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);
|
||||
|
|
@ -461,10 +481,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;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ struct gengetopt_args_info {
|
|||
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 *proctitle_arg; /* Override process title (default=off). */
|
||||
int enforcetls1_flag; /* Override default and enforce TLSv1 */
|
||||
char *host_arg; /* Optional Host Header */
|
||||
int help_given; /* Whether help was given. */
|
||||
int version_given; /* Whether version was given. */
|
||||
int user_given; /* Whether user was given. */
|
||||
|
|
@ -71,6 +73,8 @@ 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 cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *args_info );
|
||||
|
|
|
|||
6
http.c
6
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.dest_arg );
|
||||
}
|
||||
|
||||
if ( args_info.user_given && args_info.pass_given ) {
|
||||
|
|
@ -163,7 +163,7 @@ void proxy_protocol(PTSTREAM *pts) {
|
|||
|
||||
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 ));
|
||||
|
|
|
|||
65
io.c
65
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 );
|
||||
|
||||
/* reset the timeout, since select() does modify this struct! */
|
||||
select_timeout.tv_sec = 30;
|
||||
select_timeout.tv_usec = 0;
|
||||
|
||||
/* Wait until something happens on the registered sockets/files */
|
||||
if ( select( max_fd + 1, &readfds, &writefds, &exceptfds, 0 ) < 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
|
||||
|
|
|
|||
|
|
@ -145,13 +145,17 @@ int stream_copy(PTSTREAM *pts_from, PTSTREAM *pts_to) {
|
|||
/* Initiate an SSL handshake on this stream and encrypt all subsequent data */
|
||||
int stream_enable_ssl(PTSTREAM *pts) {
|
||||
#ifdef USE_SSL
|
||||
SSL_METHOD *meth;
|
||||
const SSL_METHOD *meth;
|
||||
SSL *ssl;
|
||||
SSL_CTX *ctx;
|
||||
|
||||
/* Initialise the connection */
|
||||
SSLeay_add_ssl_algorithms();
|
||||
meth = SSLv23_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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue