mirror of
https://github.com/proxytunnel/proxytunnel.git
synced 2026-01-23 02:34:59 +00:00
- Applied (reworked) changes from Mark Cave-Ayland to support -E option
encrypting data to the proxy with SSL (untested by me) - Change version to 1.6.4 git-svn-id: https://proxytunnel.svn.sourceforge.net/svnroot/proxytunnel/trunk/proxytunnel@143 bc163920-b10d-0410-b2c5-a5491ca2ceef
This commit is contained in:
parent
42913f3c39
commit
bbda7f9734
13 changed files with 479 additions and 303 deletions
4
CHANGES
4
CHANGES
|
|
@ -1,4 +1,4 @@
|
|||
Changes to proxytunnel version 1.6.4 -- xxx
|
||||
Changes to proxytunnel version 1.6.4 -- Mon Feb 12 21:45:06 CEST 2007
|
||||
|
||||
- Allow multiple '-H' options (headers), total size of the headers
|
||||
should not exceed 1k.
|
||||
|
|
@ -10,6 +10,8 @@ Changes to proxytunnel version 1.6.4 -- xxx
|
|||
- Change error message on 'connection closed' in analyze_HTTP
|
||||
- Reworked debug-output (dag-)
|
||||
- Signal handling (dag-)
|
||||
- Applied (reworked) changes from Mark Cave-Ayland to support -E option
|
||||
encrypting data to the proxy with SSL (untested by me)
|
||||
|
||||
Changes to proxytunnel version 1.6.3 -- Mon Apr 10 12:48:02 CEST 2006
|
||||
|
||||
|
|
|
|||
2
CREDITS
2
CREDITS
|
|
@ -18,7 +18,7 @@ people.
|
|||
Stephane Engel at macchiati.org - Fix for broken proxy
|
||||
Mike Frysinger <vapier@gentoo.org> - Makefile fix, 64bit fix
|
||||
Alex Peuchert proxytunnel@peuchert.de - SSL/Encrypt support
|
||||
|
||||
Mark.Cave-Ayland @ ilande.co.uk - SSL to Proxy, Streams
|
||||
|
||||
Furthermore we would like to thank the wonderful people at SourceForge
|
||||
for hosting our development.
|
||||
|
|
|
|||
3
Makefile
3
Makefile
|
|
@ -50,7 +50,8 @@ OBJ = proxytunnel.o \
|
|||
readpassphrase.o \
|
||||
messages.o \
|
||||
cmdline.o \
|
||||
ntlm.o
|
||||
ntlm.o \
|
||||
ptstream.o
|
||||
|
||||
proxytunnel: $(OBJ)
|
||||
$(CC) -o $(PROGNAME) $(CFLAGS) $(OBJ) $(LDFLAGS)
|
||||
|
|
|
|||
54
cmdline.c
54
cmdline.c
|
|
@ -59,6 +59,7 @@ cmdline_parser_print_help (void)
|
|||
#endif
|
||||
#ifdef USE_SSL
|
||||
" -e --encrypt encrypt the communication using SSL\n"
|
||||
" -E --encrypt-proxy encrypt the communitation between the client and the proxy using SSL\n"
|
||||
#endif
|
||||
#ifdef SETPROCTITLE
|
||||
" -x STRING --proctitle=STRING Set the process-title to STRING\n"
|
||||
|
|
@ -132,6 +133,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
|
|||
args_info->header_given = 0;
|
||||
args_info->domain_given = 0;
|
||||
args_info->encrypt_given = 0;
|
||||
args_info->encryptproxy_given = 0;
|
||||
args_info->proctitle_given = 0;
|
||||
|
||||
/* No... we can't make this a function... -- Maniac */
|
||||
|
|
@ -151,6 +153,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
|
|||
args_info->quiet_flag = 0; \
|
||||
args_info->standalone_arg = 0; \
|
||||
args_info->encrypt_flag = 0; \
|
||||
args_info->encryptproxy_flag = 0; \
|
||||
args_info->proctitle_arg = NULL; \
|
||||
}
|
||||
|
||||
|
|
@ -171,32 +174,33 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
|
|||
|
||||
/* Struct option: Name, Has_arg, Flag, Value */
|
||||
static struct option long_options[] = {
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "version", 0, NULL, 'V' },
|
||||
{ "user", 1, NULL, 'u' },
|
||||
{ "pass", 1, NULL, 's' },
|
||||
{ "domain", 1, NULL, 't' },
|
||||
{ "uservar", 1, NULL, 'U' },
|
||||
{ "passvar", 1, NULL, 'S' },
|
||||
{ "proxy", 1, NULL, 'p' },
|
||||
{ "proxyhost", 1, NULL, 'g' },
|
||||
{ "proxyport", 1, NULL, 'G' },
|
||||
{ "dest", 1, NULL, 'd' },
|
||||
{ "remproxy", 1, NULL, 'r' },
|
||||
{ "proctitle", 1, NULL, 'x' },
|
||||
{ "header", 1, NULL, 'H' },
|
||||
{ "verbose", 0, NULL, 'v' },
|
||||
{ "ntlm", 0, NULL, 'N' },
|
||||
{ "inetd", 0, NULL, 'i' },
|
||||
{ "standalone", 1, NULL, 'a' },
|
||||
{ "quiet", 0, NULL, 'q' },
|
||||
{ "encrypt", 0, NULL, 'e' },
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "version", 0, NULL, 'V' },
|
||||
{ "user", 1, NULL, 'u' },
|
||||
{ "pass", 1, NULL, 's' },
|
||||
{ "domain", 1, NULL, 't' },
|
||||
{ "uservar", 1, NULL, 'U' },
|
||||
{ "passvar", 1, NULL, 'S' },
|
||||
{ "proxy", 1, NULL, 'p' },
|
||||
{ "proxyhost", 1, NULL, 'g' },
|
||||
{ "proxyport", 1, NULL, 'G' },
|
||||
{ "dest", 1, NULL, 'd' },
|
||||
{ "remproxy", 1, NULL, 'r' },
|
||||
{ "proctitle", 1, NULL, 'x' },
|
||||
{ "header", 1, NULL, 'H' },
|
||||
{ "verbose", 0, NULL, 'v' },
|
||||
{ "ntlm", 0, NULL, 'N' },
|
||||
{ "inetd", 0, NULL, 'i' },
|
||||
{ "standalone", 1, NULL, 'a' },
|
||||
{ "quiet", 0, NULL, 'q' },
|
||||
{ "encrypt", 0, NULL, 'e' },
|
||||
{ "encrypt-proxy", 0, NULL, 'E' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "hVia:u:s:t:U:S:p:r:d:H:x:nvNeq", long_options, &option_index);
|
||||
c = getopt_long (argc, argv, "hVia:u:s:t:U:S:p:r:d:H:x:nvNeEq", long_options, &option_index);
|
||||
#else
|
||||
c = getopt( argc, argv, "hVia:u:s:t:U:S:p:r:d:H:x:nvNeq" );
|
||||
c = getopt( argc, argv, "hVia:u:s:t:U:S:p:r:d:H:x:nvNeEq" );
|
||||
#endif
|
||||
|
||||
if (c == -1) break; /* Exit from `while (1)' loop. */
|
||||
|
|
@ -214,6 +218,12 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
|
|||
if( args_info->verbose_flag )
|
||||
message("SSL enabled\n");
|
||||
break;
|
||||
|
||||
case 'E': /* Turn on client to proxy SSL encryption */
|
||||
args_info->encryptproxy_flag = !(args_info->encryptproxy_flag);
|
||||
if( args_info->verbose_flag )
|
||||
message("SSL client to proxy enabled\n");
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 'i': /* Run from inetd. */
|
||||
|
|
|
|||
37
cmdline.h
37
cmdline.h
|
|
@ -41,25 +41,28 @@ struct gengetopt_args_info {
|
|||
int quiet_flag; /* Turn on quiet mode (default=off). */
|
||||
int standalone_arg; /* Turn on stdalone (-a) on port */
|
||||
int encrypt_flag; /* Turn on SSL encryption (default=off). */
|
||||
int encryptproxy_flag;/* Turn on client to proxy SSL encryption (def=off).*/
|
||||
|
||||
char * proctitle_arg; /* Override process title (default=off). */
|
||||
|
||||
int help_given; /* Whether help was given. */
|
||||
int version_given; /* Whether version was given. */
|
||||
int user_given; /* Whether user was given. */
|
||||
int pass_given; /* Whether pass was given. */
|
||||
int domain_given; /* Whether domain was given. */
|
||||
int proxy_given; /* Whether proxyhost was given. */
|
||||
int proxyhost_given; /* Whether proxyhost was given. */
|
||||
int proxyport_given; /* Whether proxyport was given. */
|
||||
int dest_given; /* Whether dest was given. */
|
||||
int remproxy_given; /* Whether remproxy was given. */
|
||||
int verbose_given; /* Whether verbose was given. */
|
||||
int ntlm_given; /* Whether ntlm was given. */
|
||||
int inetd_given; /* Whether inetd was given. */
|
||||
int quiet_given; /* Whether quiet mode was given. */
|
||||
int header_given; /* Whenther extra headers are given */
|
||||
int encrypt_given; /* Whether encrypt was given */
|
||||
int proctitle_given; /* Whether to override process title */
|
||||
int help_given; /* Whether help was given. */
|
||||
int version_given; /* Whether version was given. */
|
||||
int user_given; /* Whether user was given. */
|
||||
int pass_given; /* Whether pass was given. */
|
||||
int domain_given; /* Whether domain was given. */
|
||||
int proxy_given; /* Whether proxyhost was given. */
|
||||
int proxyhost_given; /* Whether proxyhost was given. */
|
||||
int proxyport_given; /* Whether proxyport was given. */
|
||||
int dest_given; /* Whether dest was given. */
|
||||
int remproxy_given; /* Whether remproxy was given. */
|
||||
int verbose_given; /* Whether verbose was given. */
|
||||
int ntlm_given; /* Whether ntlm was given. */
|
||||
int inetd_given; /* Whether inetd was given. */
|
||||
int quiet_given; /* Whether quiet mode was given. */
|
||||
int header_given; /* Whether extra headers are given */
|
||||
int encrypt_given; /* Whether encrypt was given */
|
||||
int encryptproxy_given; /* Whether encrypt was given */
|
||||
int proctitle_given; /* Whether to override process title */
|
||||
} ;
|
||||
|
||||
int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *args_info );
|
||||
|
|
|
|||
2
config.h
2
config.h
|
|
@ -17,7 +17,7 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#define VERSION "1.6.3"
|
||||
#define VERSION "1.6.4"
|
||||
#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>"
|
||||
|
|
|
|||
24
http.c
24
http.c
|
|
@ -26,8 +26,8 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "io.h"
|
||||
#include "proxytunnel.h"
|
||||
#include "io.h"
|
||||
#include "basicauth.h"
|
||||
#include "ntlm.h"
|
||||
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
* Analyze the proxy's HTTP response. This must be a HTTP/1.? 200 OK type
|
||||
* header
|
||||
*/
|
||||
void analyze_HTTP()
|
||||
void analyze_HTTP(PTSTREAM *pts)
|
||||
{
|
||||
char *p = strtok( buf, " ");
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ void analyze_HTTP()
|
|||
*/
|
||||
while (strncmp( p, "HTTP/", 5) != 0 )
|
||||
{
|
||||
if ( readline() )
|
||||
if ( readline(pts) )
|
||||
p = strtok( buf, " ");
|
||||
else
|
||||
{
|
||||
|
|
@ -76,7 +76,7 @@ void analyze_HTTP()
|
|||
{
|
||||
do
|
||||
{
|
||||
readline();
|
||||
readline(pts);
|
||||
if (strncmp( buf, "Proxy-Authenticate: NTLM ", 25) == 0)
|
||||
{
|
||||
if (parse_type2((unsigned char *)&buf[25]) < 0)
|
||||
|
|
@ -86,7 +86,7 @@ void analyze_HTTP()
|
|||
}
|
||||
if (ntlm_challenge == 1)
|
||||
{
|
||||
proxy_protocol();
|
||||
proxy_protocol(pts);
|
||||
return;
|
||||
}
|
||||
exit( 1 );
|
||||
|
|
@ -111,7 +111,7 @@ void print_line_prefix(char *buf, char *prefix)
|
|||
* Execute the basic proxy protocol of CONNECT and response, until the
|
||||
* last line of the response has been read. The tunnel is then open.
|
||||
*/
|
||||
void proxy_protocol()
|
||||
void proxy_protocol(PTSTREAM *pts)
|
||||
{
|
||||
/*
|
||||
* Create the proxy CONNECT command into buf
|
||||
|
|
@ -170,7 +170,7 @@ void proxy_protocol()
|
|||
/*
|
||||
* Send the CONNECT instruction to the proxy
|
||||
*/
|
||||
if( send( sd, buf, strlen( buf ), 0 ) < 0 )
|
||||
if( stream_write( pts, buf, strlen( buf )) < 0 )
|
||||
{
|
||||
my_perror( "Socket write error" );
|
||||
exit( 1 );
|
||||
|
|
@ -181,14 +181,14 @@ void proxy_protocol()
|
|||
if( args_info.verbose_flag )
|
||||
message( "Data received from local proxy:\n");
|
||||
|
||||
analyze_HTTP();
|
||||
analyze_HTTP(pts);
|
||||
|
||||
if (args_info.remproxy_given )
|
||||
{
|
||||
/*
|
||||
* Clean buffer for next analysis
|
||||
*/
|
||||
while ( strcmp( buf, "\r\n" ) != 0 ) readline();
|
||||
while ( strcmp( buf, "\r\n" ) != 0 ) readline(pts);
|
||||
|
||||
if( args_info.verbose_flag )
|
||||
message( "Tunneling to %s (destination)\n", args_info.dest_arg );
|
||||
|
|
@ -212,7 +212,7 @@ void proxy_protocol()
|
|||
/*
|
||||
* Send the CONNECT instruction to the proxy
|
||||
*/
|
||||
if( send( sd, buf, strlen( buf ), 0 ) < 0 )
|
||||
if( stream_write( pts, buf, strlen( buf )) < 0 )
|
||||
{
|
||||
my_perror( "Socket write error" );
|
||||
exit( 1 );
|
||||
|
|
@ -224,7 +224,7 @@ void proxy_protocol()
|
|||
if( args_info.verbose_flag )
|
||||
message( "Received from remote proxy:\n");
|
||||
|
||||
analyze_HTTP();
|
||||
analyze_HTTP(pts);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -235,7 +235,7 @@ void proxy_protocol()
|
|||
ntlm_challenge = 2;
|
||||
} else {
|
||||
do {
|
||||
readline();
|
||||
readline(pts);
|
||||
} while ( strcmp( buf, "\r\n" ) != 0 );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
193
io.c
193
io.c
|
|
@ -29,19 +29,12 @@
|
|||
#include "proxytunnel.h"
|
||||
#include "io.h"
|
||||
|
||||
#ifdef USE_SSL /* Override copy functions */
|
||||
#define COPY_TO(fd) copy_to_SSL(fd, ssl)
|
||||
#define COPY_FROM(fd) copy_from_SSL(ssl, fd)
|
||||
#else
|
||||
#define COPY_TO(fd) copy(fd, sd)
|
||||
#define COPY_FROM(fd) copy(sd, fd)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Read one line of data from the tunnel. Line is terminated by a
|
||||
* newline character. Result is stored in buf.
|
||||
*/
|
||||
int readline()
|
||||
int readline(PTSTREAM *pts)
|
||||
{
|
||||
char *p = buf;
|
||||
char c = 0;
|
||||
|
|
@ -53,7 +46,7 @@ int readline()
|
|||
*/
|
||||
while ( c != 10 && ( i < SIZE - 1 ) )
|
||||
{
|
||||
if( recv( sd, &c ,1 ,0 ) < 0)
|
||||
if( stream_read( pts, &c ,1) < 0)
|
||||
{
|
||||
my_perror( "Socket read error" );
|
||||
exit( 1 );
|
||||
|
|
@ -76,144 +69,26 @@ int readline()
|
|||
return strlen( buf );
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a block of data from one socket descriptor to another. A true
|
||||
* return code signifies EOF on the from socket descriptor.
|
||||
*/
|
||||
int copy(int from, int to)
|
||||
{
|
||||
int n;
|
||||
|
||||
/*
|
||||
* Read a buffer from the source socket
|
||||
*/
|
||||
if ( ( n = read( from, buf, SIZE ) ) < 0 )
|
||||
{
|
||||
my_perror( "Socket read error" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have read 0 bytes, there is an EOF on src
|
||||
*/
|
||||
if( n==0 )
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Write the buffer to the destination socket
|
||||
*/
|
||||
if ( write( to, buf, n ) != n )
|
||||
{
|
||||
my_perror( "Socket write error" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not yet at EOF
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_SSL
|
||||
int copy_to_SSL(int from, SSL* to)
|
||||
{
|
||||
int n;
|
||||
|
||||
/*
|
||||
* Read a buffer from the source socket
|
||||
*/
|
||||
if ( ( n = read( from, buf, SIZE ) ) < 0 )
|
||||
{
|
||||
my_perror( "Socket read error" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have read 0 bytes, there is an EOF on src
|
||||
*/
|
||||
if( n==0 )
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Write the buffer to the destination socket
|
||||
*/
|
||||
if ( SSL_write( to, buf, n ) != n )
|
||||
{
|
||||
my_perror( "Socket write error" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not yet at EOF
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
int copy_from_SSL(SSL* from, int to)
|
||||
{
|
||||
int n;
|
||||
|
||||
/*
|
||||
* Read a buffer from the source socket
|
||||
*/
|
||||
if ( ( n = SSL_read( from, buf, SIZE ) ) < 0 )
|
||||
{
|
||||
my_perror( "Socket read error" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have read 0 bytes, there is an EOF on src
|
||||
*/
|
||||
if( n==0 )
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Write the buffer to the destination socket
|
||||
*/
|
||||
if ( write( to, buf, n ) != n )
|
||||
{
|
||||
my_perror( "Socket write error" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not yet at EOF
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE_SSL */
|
||||
|
||||
|
||||
/*
|
||||
* Move into a loop of copying data to and from the tunnel.
|
||||
* stdin (fd 0) and stdout (fd 1) are the file descriptors
|
||||
* for the connected application, sd is the file descriptor
|
||||
* of the tunnel.
|
||||
* Bond stream1 and stream2 together; any data received in stream1 is relayed
|
||||
* to stream2, and vice-versa.
|
||||
*/
|
||||
void cpio()
|
||||
void cpio(PTSTREAM *stream1, PTSTREAM *stream2)
|
||||
{
|
||||
fd_set readfds;
|
||||
fd_set writefds;
|
||||
fd_set exceptfds;
|
||||
int max_fd;
|
||||
int out_fd;
|
||||
int in_max_fd, out_max_fd, max_fd;
|
||||
|
||||
#ifdef USE_SSL
|
||||
if( args_info.encrypt_flag )
|
||||
out_fd = SSL_get_fd(ssl);
|
||||
else
|
||||
out_fd = sd;
|
||||
#else
|
||||
out_fd = sd;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Find the biggest file descriptor for select()
|
||||
*/
|
||||
max_fd = MAX( read_fd,write_fd );
|
||||
max_fd = MAX( max_fd, out_fd );
|
||||
|
||||
in_max_fd = MAX(stream_get_incoming_fd(stream1), stream_get_incoming_fd(stream2));
|
||||
out_max_fd = MAX(stream_get_outgoing_fd(stream1), stream_get_outgoing_fd(stream2));
|
||||
max_fd = MAX(in_max_fd, out_max_fd);
|
||||
|
||||
/*
|
||||
* We're never interested in sockets being available for write.
|
||||
|
|
@ -235,18 +110,18 @@ void cpio()
|
|||
FD_ZERO( &exceptfds );
|
||||
|
||||
/*
|
||||
* We want to know whether stdin or sd is ready for reading
|
||||
* We want to know whether stream1 or stream2 is ready for reading
|
||||
*/
|
||||
FD_SET( read_fd, &readfds );
|
||||
FD_SET( out_fd, &readfds );
|
||||
FD_SET( stream_get_incoming_fd(stream1), &readfds );
|
||||
FD_SET( stream_get_incoming_fd(stream2), &readfds );
|
||||
|
||||
/*
|
||||
* And we want to know about exceptional conditions on either
|
||||
* stdin, stdout or the tunnel
|
||||
* And we want to know about exceptional conditions on either stream
|
||||
*/
|
||||
FD_SET( read_fd, &exceptfds );
|
||||
FD_SET( write_fd, &exceptfds );
|
||||
FD_SET( out_fd, &exceptfds );
|
||||
FD_SET( stream_get_incoming_fd(stream1), &exceptfds );
|
||||
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 one of the registered
|
||||
|
|
@ -260,37 +135,21 @@ void cpio()
|
|||
}
|
||||
|
||||
/*
|
||||
* Is stdin ready for read? If so, copy a block of data
|
||||
* from stdin to the tunnel. Or else if the tunnel socket
|
||||
* 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
|
||||
* tunnel to stdout. Otherwise an exceptional condition
|
||||
* stream2 to stream1. Otherwise an exceptional condition
|
||||
* is flagged and the program is terminated.
|
||||
*/
|
||||
if ( FD_ISSET( read_fd, &readfds ) )
|
||||
if ( FD_ISSET( stream_get_incoming_fd(stream1), &readfds ) )
|
||||
{
|
||||
if( args_info.encrypt_flag )
|
||||
{
|
||||
if ( COPY_TO(read_fd ) )
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( copy(read_fd, sd ) )
|
||||
break;
|
||||
}
|
||||
if ( stream_copy(stream1, stream2 ) )
|
||||
break;
|
||||
}
|
||||
else if( FD_ISSET( sd, &readfds ) )
|
||||
else if( FD_ISSET( stream_get_incoming_fd(stream2), &readfds ) )
|
||||
{
|
||||
if( args_info.encrypt_flag )
|
||||
{
|
||||
if( COPY_FROM(write_fd ) )
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( copy(sd,write_fd ) )
|
||||
break;
|
||||
}
|
||||
if( stream_copy(stream2, stream1 ) )
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
6
io.h
6
io.h
|
|
@ -18,7 +18,5 @@
|
|||
*/
|
||||
|
||||
/* io.h */
|
||||
int readline();
|
||||
int copy(int from, int to);
|
||||
void cpio();
|
||||
|
||||
int readline(PTSTREAM *pts);
|
||||
void cpio(PTSTREAM *stream1, PTSTREAM *stream2);
|
||||
|
|
|
|||
142
proxytunnel.c
142
proxytunnel.c
|
|
@ -33,11 +33,11 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "proxytunnel.h"
|
||||
#include "io.h"
|
||||
#include "config.h"
|
||||
#include "cmdline.h"
|
||||
#include "basicauth.h"
|
||||
#include "proxytunnel.h"
|
||||
#include "ntlm.h"
|
||||
|
||||
/* Define DARWIN if compiling on MacOS-X (Darwin), to work around some
|
||||
|
|
@ -50,12 +50,6 @@
|
|||
int read_fd=0; /* The file descriptor to read from */
|
||||
int write_fd=1; /* The file destriptor to write to */
|
||||
|
||||
#ifdef USE_SSL
|
||||
SSL_CTX* ctx;
|
||||
SSL* ssl;
|
||||
SSL_METHOD *meth;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Kill the program (signal handler)
|
||||
*/
|
||||
|
|
@ -67,12 +61,13 @@ void signal_handler( int signal )
|
|||
}
|
||||
|
||||
/*
|
||||
* Create and connect the socket that connects to the proxy. After
|
||||
* this routine the sd socket is connected to the proxy.
|
||||
* Create and connect the socket that connects to the proxy. Returns
|
||||
* the socket that is connected to the proxy
|
||||
*/
|
||||
void tunnel_connect() {
|
||||
int tunnel_connect() {
|
||||
struct sockaddr_in sa;
|
||||
struct hostent *he;
|
||||
int sd;
|
||||
|
||||
/*
|
||||
* Create the socket
|
||||
|
|
@ -131,26 +126,11 @@ void tunnel_connect() {
|
|||
|
||||
/* Make sure we get warned when someone hangs up on us */
|
||||
signal(SIGHUP,signal_handler);
|
||||
|
||||
/* Return the socket */
|
||||
return sd;
|
||||
}
|
||||
|
||||
#ifdef USE_SSL
|
||||
/*
|
||||
* Do the SSL handshake.
|
||||
*/
|
||||
void do_ssl()
|
||||
{
|
||||
SSLeay_add_ssl_algorithms();
|
||||
meth = SSLv2_client_method();
|
||||
SSL_load_error_strings();
|
||||
|
||||
ctx = SSL_CTX_new (meth);
|
||||
|
||||
ssl = SSL_new (ctx);
|
||||
|
||||
SSL_set_fd (ssl, sd);
|
||||
SSL_connect (ssl);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Leave a goodbye message
|
||||
|
|
@ -171,30 +151,12 @@ void closeall() {
|
|||
#endif
|
||||
|
||||
/*
|
||||
* Close all files we deal with
|
||||
* Close all streams
|
||||
*/
|
||||
close(0);
|
||||
close(1);
|
||||
|
||||
if ( sd != 0 )
|
||||
close( sd );
|
||||
|
||||
|
||||
#ifdef USE_SSL
|
||||
if( args_info.encrypt_flag )
|
||||
{
|
||||
SSL_free (ssl);
|
||||
SSL_CTX_free (ctx);
|
||||
}
|
||||
#else
|
||||
close( sd );
|
||||
#endif
|
||||
|
||||
if( read_fd != write_fd ) /* When not running from inetd */
|
||||
{
|
||||
close( write_fd );
|
||||
}
|
||||
close( read_fd );
|
||||
if (stunnel)
|
||||
stream_close(stunnel);
|
||||
if (std)
|
||||
stream_close(std);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -211,6 +173,10 @@ void do_daemon()
|
|||
char buf[80];
|
||||
unsigned char addr[4];
|
||||
|
||||
/* Socket descriptor */
|
||||
int sd;
|
||||
|
||||
|
||||
if ( ( listen_sd = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 )
|
||||
{
|
||||
my_perror( "Server socket creation failed" );
|
||||
|
|
@ -297,12 +263,26 @@ void do_daemon()
|
|||
{
|
||||
read_fd = write_fd = sd_client;
|
||||
|
||||
/* Main processing */
|
||||
tunnel_connect();
|
||||
proxy_protocol();
|
||||
/* Create a stdin/out stream */
|
||||
std = stream_open(read_fd, write_fd);
|
||||
|
||||
/* Create a tunnel stream */
|
||||
sd = tunnel_connect();
|
||||
stunnel = stream_open(sd, sd);
|
||||
|
||||
/* If --encrypt-proxy is specified, connect to the proxy using SSL */
|
||||
#ifdef USE_SSL
|
||||
if ( args_info.encryptproxy_flag )
|
||||
stream_enable_ssl(stunnel);
|
||||
#endif
|
||||
|
||||
/* Open the tunnel */
|
||||
proxy_protocol(stunnel);
|
||||
|
||||
/* If --encrypt is specified, wrap all traffic after the proxy handoff in SSL */
|
||||
#ifdef USE_SSL
|
||||
if( args_info.encrypt_flag )
|
||||
do_ssl();
|
||||
stream_enable_ssl(stunnel);
|
||||
#endif
|
||||
#ifdef SETPROCTITLE
|
||||
if( ! args_info.proctitle_given )
|
||||
|
|
@ -313,8 +293,9 @@ void do_daemon()
|
|||
if( args_info.proctitle_given )
|
||||
message( "Setting process-title is not supported in this build\n");
|
||||
#endif
|
||||
|
||||
cpio();
|
||||
|
||||
/* Run the tunnel - we should stay here indefinitely */
|
||||
cpio(std, stunnel);
|
||||
/////
|
||||
exit( 0 );
|
||||
}
|
||||
|
|
@ -339,6 +320,13 @@ void do_daemon()
|
|||
*/
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
/* Socket descriptor */
|
||||
int sd;
|
||||
|
||||
/* Clear all stream variables (so we know whether we need to clear up) */
|
||||
stunnel = NULL;
|
||||
std = NULL;
|
||||
|
||||
program_name = argv[0];
|
||||
|
||||
/*
|
||||
|
|
@ -356,7 +344,7 @@ int main( int argc, char *argv[] )
|
|||
* different mainline is needed...
|
||||
* - Set a signal for the hangup (HUP) signal
|
||||
* - Optionally create the proxy basic authentication cookie
|
||||
* - Connect the sd socket to the proxy
|
||||
* - Connect to the proxy
|
||||
* - Execute the proxy protocol to connect it to the origin server
|
||||
* - Enter copy in-out mode to channel data hence and forth
|
||||
*/
|
||||
|
|
@ -386,6 +374,16 @@ int main( int argc, char *argv[] )
|
|||
make_basicauth();
|
||||
}
|
||||
|
||||
/*
|
||||
* Only one of -E (SSL encrypt client to proxy connection) or -e (SSL encrypt tunnel data)
|
||||
* can be specified.
|
||||
*/
|
||||
if (args_info.encryptproxy_flag && args_info.encrypt_flag)
|
||||
{
|
||||
message("Error: only one of --encrypt-proxy and --encrypt can be specified for a tunnel\n");
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/* Do we need to run as a standalone daemon? */
|
||||
if ( args_info.standalone_arg > 0 )
|
||||
{
|
||||
|
|
@ -400,12 +398,26 @@ int main( int argc, char *argv[] )
|
|||
write_fd=0;
|
||||
}
|
||||
|
||||
/* Main processing */
|
||||
tunnel_connect();
|
||||
proxy_protocol();
|
||||
/* Create a stdin/out stream */
|
||||
std = stream_open(read_fd, write_fd);
|
||||
|
||||
/* Create a tunnel stream */
|
||||
sd = tunnel_connect();
|
||||
stunnel = stream_open(sd, sd);
|
||||
|
||||
/* If --encrypt-proxy is specified, connect to the proxy using SSL */
|
||||
#ifdef USE_SSL
|
||||
if ( args_info.encryptproxy_flag )
|
||||
stream_enable_ssl(stunnel);
|
||||
#endif
|
||||
|
||||
/* Open the tunnel */
|
||||
proxy_protocol(stunnel);
|
||||
|
||||
/* If --encrypt is specified, wrap all traffic after the proxy handoff in SSL */
|
||||
#ifdef USE_SSL
|
||||
if( args_info.encrypt_flag )
|
||||
do_ssl();
|
||||
stream_enable_ssl(stunnel);
|
||||
#endif
|
||||
#ifdef SETPROCTITLE
|
||||
if( ! args_info.proctitle_given )
|
||||
|
|
@ -417,8 +429,12 @@ int main( int argc, char *argv[] )
|
|||
message( "Setting process-title is not supported in this build\n");
|
||||
#endif
|
||||
|
||||
cpio();
|
||||
/* Run the tunnel - we should stay here indefinitely */
|
||||
cpio(std, stunnel);
|
||||
}
|
||||
|
||||
/* If we do happen to get here, clean up */
|
||||
closeall();
|
||||
|
||||
exit( 0 );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,22 +19,15 @@
|
|||
|
||||
/* proxytunnel.h */
|
||||
|
||||
#ifdef USE_SSL
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
#include "cmdline.h"
|
||||
#include "ptstream.h"
|
||||
|
||||
void message( char *s, ... );
|
||||
void my_perror( char *msg );
|
||||
void signal_handler( int signal );
|
||||
void tunnel_connect();
|
||||
int tunnel_connect();
|
||||
void analyze_HTTP();
|
||||
void proxy_protocol();
|
||||
void do_ssl();
|
||||
void closeall();
|
||||
void do_daemon();
|
||||
void initsetproctitle(int argc, char *argv[]);
|
||||
|
|
@ -46,16 +39,13 @@ char * readpassphrase(const char *, char *, size_t, int);
|
|||
char * getpass_x(const char *prompt);
|
||||
|
||||
/* Globals */
|
||||
int sd; /* The tunnel's socket descriptor */
|
||||
int read_fd; /* The file descriptor to read from */
|
||||
int write_fd; /* The file destriptor to write to */
|
||||
char *program_name; /* Guess what? */
|
||||
int i_am_daemon; /* Also... */
|
||||
|
||||
#ifdef USE_SSL
|
||||
SSL_CTX* ctx;
|
||||
SSL* ssl;
|
||||
#endif
|
||||
PTSTREAM *stunnel; /* The stream representing the socket from us to the proxy */
|
||||
PTSTREAM *std; /* The stream representing stdin/stdout */
|
||||
|
||||
/*
|
||||
* All the command line options
|
||||
|
|
|
|||
247
ptstream.c
Normal file
247
ptstream.c
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
/* Proxytunnel - (C) 2001-2006 Jos Visser / Mark Janssen */
|
||||
/* Contact: josv@osp.nl / maniac@maniac.nl */
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ptstream.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "proxytunnel.h"
|
||||
|
||||
|
||||
/*
|
||||
* Open a stream for incoming and outgoing data with the specified fds
|
||||
*/
|
||||
|
||||
PTSTREAM *stream_open(int incoming_fd, int outgoing_fd)
|
||||
{
|
||||
PTSTREAM *pts;
|
||||
|
||||
/* Initialise the structure and store the file descriptor */
|
||||
pts = malloc(sizeof(PTSTREAM));
|
||||
pts->incoming_fd = incoming_fd;
|
||||
pts->outgoing_fd = outgoing_fd;
|
||||
pts->ssl = NULL;
|
||||
pts->ctx = NULL;
|
||||
|
||||
/* Return a pointer to the structure */
|
||||
return pts;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Close a stream
|
||||
*/
|
||||
|
||||
int stream_close(PTSTREAM *pts)
|
||||
{
|
||||
/* Close the incoming fd */
|
||||
if (pts->incoming_fd != 0)
|
||||
close(pts->incoming_fd);
|
||||
|
||||
/* Close the outgoing fd */
|
||||
if (pts->outgoing_fd != 0)
|
||||
close(pts->outgoing_fd);
|
||||
|
||||
/* Destroy the SSL context */
|
||||
if (pts->ssl)
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
SSL_free (pts->ssl);
|
||||
SSL_CTX_free (pts->ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Free the structure */
|
||||
free(pts);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read from a stream
|
||||
*/
|
||||
|
||||
int stream_read(PTSTREAM *pts, void *buf, size_t len)
|
||||
{
|
||||
/* Read up to the specified number of bytes into the buffer */
|
||||
int bytes_read;
|
||||
|
||||
if (!pts->ssl)
|
||||
{
|
||||
/* For a non-SSL stream... */
|
||||
bytes_read = read(pts->incoming_fd, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
/* For an SSL stream... */
|
||||
bytes_read = SSL_read(pts->ssl, buf, len);
|
||||
#else
|
||||
/* No SSL support, so must use a non-SSL stream */
|
||||
bytes_read = read(pts->incoming_fd, buf, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write to a stream
|
||||
*/
|
||||
|
||||
int stream_write(PTSTREAM *pts, void *buf, size_t len)
|
||||
{
|
||||
/* Write the specified number of bytes from the buffer */
|
||||
int bytes_written;
|
||||
|
||||
if (!pts->ssl)
|
||||
{
|
||||
/* For a non-SSL stream... */
|
||||
bytes_written = write(pts->outgoing_fd, buf, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
/* For an SSL stream... */
|
||||
bytes_written = SSL_write(pts->ssl, buf, len);
|
||||
#else
|
||||
/* No SSL support, so must use a non-SSL stream */
|
||||
bytes_written = write(pts->outgoing_fd, buf, len);
|
||||
#endif
|
||||
}
|
||||
|
||||
return bytes_written;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy a block of data from one stream to another. A true
|
||||
* return code signifies EOF on the from socket descriptor.
|
||||
*/
|
||||
|
||||
int stream_copy(PTSTREAM *pts_from, PTSTREAM *pts_to)
|
||||
{
|
||||
char buf[SIZE];
|
||||
int n;
|
||||
|
||||
/*
|
||||
* Read a buffer from the source socket
|
||||
*/
|
||||
if ( ( n = stream_read( pts_from, buf, SIZE ) ) < 0 )
|
||||
{
|
||||
my_perror( "Socket read error" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have read 0 bytes, there is an EOF on src
|
||||
*/
|
||||
if( n==0 )
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Write the buffer to the destination socket
|
||||
*/
|
||||
if ( stream_write( pts_to, buf, n ) != n )
|
||||
{
|
||||
my_perror( "Socket write error" );
|
||||
exit( 1 );
|
||||
}
|
||||
|
||||
/*
|
||||
* We're not yet at EOF
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initiate an SSL handshake on this stream and encrypt all subsequent data
|
||||
*/
|
||||
|
||||
int stream_enable_ssl(PTSTREAM *pts)
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
SSL_METHOD *meth;
|
||||
SSL *ssl;
|
||||
SSL_CTX *ctx;
|
||||
|
||||
/* Initialise the connection */
|
||||
SSLeay_add_ssl_algorithms();
|
||||
meth = SSLv2_client_method();
|
||||
SSL_load_error_strings();
|
||||
|
||||
ctx = SSL_CTX_new (meth);
|
||||
ssl = SSL_new (ctx);
|
||||
SSL_set_rfd (ssl, stream_get_incoming_fd(pts));
|
||||
SSL_set_wfd (ssl, stream_get_outgoing_fd(pts));
|
||||
SSL_connect (ssl);
|
||||
|
||||
/* Store ssl and ctx parameters */
|
||||
pts->ssl = ssl;
|
||||
pts->ctx = ctx;
|
||||
#else
|
||||
message("Warning: stream_open(): SSL stream requested but no SSL support available; using unencrypted connection");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the incoming_fd for a given stream
|
||||
*/
|
||||
|
||||
int stream_get_incoming_fd(PTSTREAM *pts)
|
||||
{
|
||||
|
||||
if (!pts->ssl)
|
||||
return pts->incoming_fd;
|
||||
else
|
||||
#ifdef USE_SSL
|
||||
return SSL_get_fd(pts->ssl);
|
||||
#else
|
||||
return pts->incoming_fd;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the outgoing_fd for a given stream
|
||||
*/
|
||||
|
||||
int stream_get_outgoing_fd(PTSTREAM *pts)
|
||||
{
|
||||
|
||||
if (!pts->ssl)
|
||||
return pts->outgoing_fd;
|
||||
else
|
||||
#ifdef USE_SSL
|
||||
return SSL_get_fd(pts->ssl);
|
||||
#else
|
||||
return pts->outgoing_fd;
|
||||
#endif
|
||||
}
|
||||
50
ptstream.h
Normal file
50
ptstream.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* Proxytunnel - (C) 2001-2006 Jos Visser / Mark Janssen */
|
||||
/* Contact: josv@osp.nl / maniac@maniac.nl */
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ptstream.h */
|
||||
|
||||
#ifdef USE_SSL
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#endif
|
||||
|
||||
typedef struct ptstream
|
||||
{
|
||||
int incoming_fd;
|
||||
int outgoing_fd;
|
||||
#ifdef USE_SSL
|
||||
SSL *ssl;
|
||||
SSL_CTX *ctx;
|
||||
#else
|
||||
void *ssl;
|
||||
void *ctx;
|
||||
#endif
|
||||
} PTSTREAM;
|
||||
|
||||
|
||||
PTSTREAM *stream_open(int incoming_fd, int outgoing_fd);
|
||||
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_get_incoming_fd(PTSTREAM *pts);
|
||||
int stream_get_outgoing_fd(PTSTREAM *pts);
|
||||
Loading…
Add table
Add a link
Reference in a new issue