Version 1.5.0

Added NTLM support


git-svn-id: https://proxytunnel.svn.sourceforge.net/svnroot/proxytunnel/trunk/proxytunnel@71 bc163920-b10d-0410-b2c5-a5491ca2ceef
This commit is contained in:
Mark Janssen 2005-08-15 10:50:21 +00:00
parent 578ce3d94a
commit bf7f2a5b47
15 changed files with 185 additions and 18 deletions

View file

@ -1,3 +1,11 @@
Changes to proxytunnel version 1.5.0 -- Mon Aug 15 12:18:41 CEST 2005
- Allow overriding of NTLM 'DOMAIN', using -t
Changes to proxytunnel version 1.4.0 -- Mon Aug 15 11:40:18 CEST 2005
- Included version-2 of the NTLM patch by Paul Solomon
Changes to proxytunnel version 1.2.3 -- Tue Nov 2 17:03:00 CET 2004
- Patched a possible buffer overflow as reported by Dan Margolis

View file

@ -12,6 +12,7 @@ people.
Andrew Griffiths <nullptr@tasmail.com> - String format fixes
Dieter Heiliger <dieter.heiliger@gmx.de>- User-agent header idea
Fred Donck <fd0@donck.com> - User/Pass Env Vars
Paul Solomon <psolomon@tpg.com.au> - NTLM support
Furthermore we would like to thank the wonderful people at SourceForge

View file

@ -6,7 +6,7 @@ CC = gcc
CFLAGS = -Wall -DHAVE_GETOPT_LONG
LDFLAGS =
INSTALLPATH = $(DESTDIR)/usr/local/bin
MANPATH = $(DESTDIR)/usr/local/man/man1
MANPATH = $(DESTDIR)/usr/man/man1
PROGNAME = proxytunnel
OBJ = proxytunnel.o \
@ -15,7 +15,10 @@ OBJ = proxytunnel.o \
http.o \
basicauth.o \
messages.o \
cmdline.o
cmdline.o \
ntlm.o \
md4.o \
md5.o
proxytunnel: $(OBJ)
$(CC) -o $(PROGNAME) $(LDFLAGS) $(OBJ)

16
README
View file

@ -3,8 +3,8 @@ proxytunnel
-----------
Author: Jos Visser <josv@osp.nl>, Mark Janssen <maniac@maniac.nl>
Date: Thu Sep 30 11:22:03 CEST 2004
Version: 1.2.0
Date: Mon Aug 15 12:15:00 CEST 2005
Version: 1.5.0
Hi all,
@ -22,7 +22,7 @@ Proxytunnel is very easy to use, when running proxytunnel with the help
option it specifies it's command-line options.
$ ./proxytunnel --help
Proxytunnel 1.2.0
Proxytunnel 1.5.0
Jos Visser (Muppet) <josv@osp.nl>, Mark Janssen (Maniac) <maniac@maniac.nl>
Purpose:
@ -35,6 +35,7 @@ Usage: Proxytunnel [OPTIONS]...
-a INT --standalone=INT Run as standalone daemon on specified port
-u STRING --user=STRING Username to send to HTTPS proxy for auth
-s STRING --pass=STRING Password to send to HTTPS proxy for auth
-t STRING --domain=STRING NTLM Domain (default: autodetect)
-U STRING --uservar=STRING Env var with Username for HTTPS proxy auth
-S STRING --passvar=STRING Env var with Password for HTTPS proxy auth
-g STRING --proxyhost=STRING HTTPS Proxy host to connect to
@ -42,6 +43,7 @@ Usage: Proxytunnel [OPTIONS]...
-d STRING --desthost=STRING Destination host to built the tunnel to
-D INT --destport=INT Destination portnumber to built the tunnel to
-H STRING --header=STRING Add STRING to HTTP headers sent to proxy
-N --ntlm Use NTLM Based Authentication
-n --dottedquad Convert destination hostname to dotted quad
-v --verbose Turn on verbosity (default=off)
-q --quiet Suppress messages (default=off)
@ -52,7 +54,6 @@ Proxytunnel -i [ -u user -s pass ] -g host -G port -d host -D port [ -n ] [ -v |
Proxytunnel -i [ -U envvar -S envvar ] -g host -G port -d host -D port [ -n ] [ -v | -q ]
Proxytunnel -a port [ -u user -s pass ] -g host -G port -d host -D port [ -n ] [ -v | -q ]
To use this program with OpenSSH to connect to a host somewhere, create
a $HOME/.ssh/config file with the following content:
@ -88,6 +89,13 @@ and 563 (SNEWS), so some hacking is necessary to start the SSH daemon on
the required port. (On the server side add an extra Port statement in
the sshd_config file)
When your proxy uses NTLM authentication (like Microsoft IIS proxy)
you need to specify -N to enable NTLM, and then specify your username
and password (and optionally domain, if autodetection fails). Usename
and password can be specified on the commandline, or, more securely,
using environment variables. The domain can only be specified on the
commandline.
When all this is in place, execute an "ssh foobar" and you're in business!
Share and Enjoy!

View file

@ -21,11 +21,26 @@
#include "config.h"
#include "cmdline.h"
#include "base64.h"
#include <ctype.h>
/* Needed for base64 encoding... */
static const char base64digits[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define BAD -1
static const char base64val[] = {
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD,
BAD,BAD,BAD,BAD, BAD,BAD,BAD,BAD, BAD,BAD,BAD, 62, BAD,BAD,BAD, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61,BAD,BAD, BAD,BAD,BAD,BAD,
BAD, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,BAD, BAD,BAD,BAD,BAD,
BAD, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,BAD, BAD,BAD,BAD,BAD
};
#define DECODE64(c) (isascii(c) ? base64val[c] : BAD)
/*
* Small MAX macro
*/
@ -72,3 +87,53 @@ void base64(unsigned char *out, const unsigned char *in, int len)
}
*out = '\0';
}
int unbase64(char *out, const char *in, int maxlen)
/* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */
/* maxlen limits output buffer size, set to zero to ignore */
{
int len = 0;
register unsigned char digit1, digit2, digit3, digit4;
if (in[0] == '+' && in[1] == ' ')
in += 2;
if (*in == '\r')
return(0);
do {
digit1 = in[0];
if (DECODE64(digit1) == BAD)
return(-1);
digit2 = in[1];
if (DECODE64(digit2) == BAD)
return(-1);
digit3 = in[2];
if (digit3 != '=' && DECODE64(digit3) == BAD)
return(-1);
digit4 = in[3];
if (digit4 != '=' && DECODE64(digit4) == BAD)
return(-1);
in += 4;
++len;
if (maxlen && len > maxlen)
return(-1);
*out++ = (DECODE64(digit1) << 2) | (DECODE64(digit2) >> 4);
if (digit3 != '=')
{
++len;
if (maxlen && len > maxlen)
return(-1);
*out++ = ((DECODE64(digit2) << 4) & 0xf0) | (DECODE64(digit3) >> 2);
if (digit4 != '=')
{
++len;
if (maxlen && len > maxlen)
return(-1);
*out++ = ((DECODE64(digit3) << 6) & 0xc0) | DECODE64(digit4);
}
}
} while
(*in && *in != '\r' && digit4 != '=');
return (len);
}

View file

@ -20,3 +20,4 @@
/* base64.h */
void base64(unsigned char *out, const unsigned char *in, int len);
int unbase64(char *out, const char *in, int maxlen);

View file

@ -59,6 +59,7 @@ cmdline_parser_print_help (void)
#endif
" -u STRING --user=STRING Username to send to HTTPS proxy for auth\n"
" -s STRING --pass=STRING Password to send to HTTPS proxy for auth\n"
" -t STRING --domain=STRING NTLM Domain (default: autodetect)\n"
" -U STRING --uservar=STRING Env var with Username for HTTPS proxy auth\n"
" -S STRING --passvar=STRING Env var with Password for HTTPS proxy auth\n"
" -g STRING --proxyhost=STRING HTTPS Proxy host to connect to\n"
@ -66,6 +67,7 @@ cmdline_parser_print_help (void)
" -d STRING --desthost=STRING Destination host to built the tunnel to\n"
" -D INT --destport=INT Destination portnumber to built the tunnel to\n"
" -H STRING --header=STRING Add STRING to HTTP headers sent to proxy\n"
" -N --ntlm Use NTLM Based Authentication\n"
" -n --dottedquad Convert destination hostname to dotted quad\n"
" -v --verbose Turn on verbosity (default=off)\n"
" -q --quiet Suppress messages (default=off)\n", PACKAGE);
@ -116,20 +118,24 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
args_info->destport_given = 0;
args_info->dottedquad_given = 0;
args_info->verbose_given = 0;
args_info->ntlm_given = 0;
args_info->inetd_given = 0;
args_info->quiet_given = 0;
args_info->header_given = 0;
args_info->domain_given = 0;
/* No... we can't make this a function... -- Maniac */
#define clear_args() \
{ \
args_info->user_arg = NULL; \
args_info->pass_arg = NULL; \
args_info->domain_arg = NULL; \
args_info->proxyhost_arg = NULL; \
args_info->desthost_arg = NULL; \
args_info->header_arg = NULL; \
args_info->dottedquad_flag = 0; \
args_info->verbose_flag = 0; \
args_info->ntlm_flag = 0; \
args_info->inetd_flag = 0; \
args_info->quiet_flag = 0; \
args_info->standalone_arg = 0; \
@ -156,6 +162,7 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
{ "version", 0, NULL, 'V' },
{ "user", 1, NULL, 'u' },
{ "pass", 1, NULL, 's' },
{ "domain", 1, NULL, 't' },
{ "uservar", 1, NULL, 'U' },
{ "passvar", 1, NULL, 'S' },
{ "proxyhost", 1, NULL, 'g' },
@ -165,15 +172,16 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
{ "header", 1, NULL, 'H' },
{ "dottedquad", 0, NULL, 'n' },
{ "verbose", 0, NULL, 'v' },
{ "ntlm", 0, NULL, 'N' },
{ "inetd", 0, NULL, 'i' },
{ "standalone", 1, NULL, 'a' },
{ "quiet", 0, NULL, 'q' },
{ NULL, 0, NULL, 0 }
};
c = getopt_long (argc, argv, "hVia:u:s:U:S:g:G:d:D:H:nvq", long_options, &option_index);
c = getopt_long (argc, argv, "hVia:u:s:t:U:S:g:G:d:D:H:nvNq", long_options, &option_index);
#else
c = getopt( argc, argv, "hVia:u:s:U:S:g:G:d:D:H:nvq" );
c = getopt( argc, argv, "hVia:u:s:t:U:S:g:G:d:D:H:nvNq" );
#endif
if (c == -1) break; /* Exit from `while (1)' loop. */
@ -251,6 +259,17 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
args_info->pass_arg = gengetopt_strdup (optarg);
break;
case 't': /* Env Var with NTLM DOMAIN (when overriding). */
if (args_info->domain_given)
{
fprintf (stderr, "%s: `--domain' (`-t') option given more than once\n", PACKAGE);
clear_args ();
exit (1);
}
args_info->domain_given = 1;
args_info->domain_arg = gengetopt_strdup (optarg);
break;
case 'S': /* Env Var with Password to send to HTTPS proxy for authentication. */
if (args_info->pass_given)
{
@ -324,6 +343,10 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
case 'v': /* Turn on verbosity. */
args_info->verbose_flag = !(args_info->verbose_flag);
break;
case 'N': /* Turn on NTLM. */
args_info->ntlm_flag = !(args_info->ntlm_flag);
break;
case 'q': /* Suppress messages -- Quiet mode */
@ -342,6 +365,14 @@ int cmdline_parser( int argc, char * const *argv, struct gengetopt_args_info *ar
} /* switch */
} /* while */
if (! args_info->proxyhost_given && ! args_info->proxyport_given
&& ! args_info->desthost_given
&& ! args_info->destport_given )
{
clear_args ();
cmdline_parser_print_help ();
exit (0);
}
if (! args_info->proxyhost_given)
{
fprintf (stderr, "%s: `--proxyhost' (`-g') option required!\n", PACKAGE);

View file

@ -26,6 +26,7 @@
struct gengetopt_args_info {
char * user_arg; /* Username to send to HTTPS proxy for auth. */
char * pass_arg; /* Password to send to HTTPS proxy for auth. */
char * domain_arg; /* NTLM Domain override */
char * proxyhost_arg; /* HTTPS Proxy host to connect to. */
int proxyport_arg; /* HTTPS Proxy host portnumber to connect to. */
char * desthost_arg; /* Destination host to built the tunnel to. */
@ -33,6 +34,7 @@ struct gengetopt_args_info {
int destport_arg; /* Dest host portnumber to built the tunnel to. */
int dottedquad_flag; /* Resolve hostname to dottedquad notation. */
int verbose_flag; /* Turn on verbosity (default=off). */
int ntlm_flag; /* Turn on ntlm (default=off). */
int inetd_flag; /* Turn on inetd (default=off). */
int quiet_flag; /* Turn on quiet mode (default=off). */
int standalone_arg; /* Turn on stdalone (-a) on port */
@ -41,12 +43,14 @@ struct gengetopt_args_info {
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 proxyhost_given; /* Whether proxyhost was given. */
int proxyport_given; /* Whether proxyport was given. */
int desthost_given; /* Whether desthost was given. */
int destport_given; /* Whether destport was given. */
int dottedquad_given; /* Whether dottedquad 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 */

View file

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define VERSION "1.2.3"
#define VERSION "1.5.0"
#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>"

9
debian/changelog vendored
View file

@ -1,8 +1,15 @@
proxytunnel (1.5.0-1) unstable; urgency=high
* New version
* NTLM support
-- Mark Janssen <maniac@maniac.nl> Mon, 15 Aug 2005 12:24:00 +0200
proxytunnel (1.2.3-1) unstable; urgency=high
* Added security-patch from gentoo security team, fix buffer overflow
-- Mark Janssen <maniac@maniac.nl> Tue Nov 2 17:08:35 CET 2004
-- Mark Janssen <maniac@maniac.nl> Wed, 20 Nov 2002 15:12:10 +0200
proxytunnel (1.2.0-1) unstable; urgency=low

2
debian/copyright vendored
View file

@ -1,5 +1,5 @@
This package was debianized by Mark Janssen <maniac@maniac.nl> on
Tue Nov 2 17:08:57 CET 2004
Mon Aug 15 12:20:26 CEST 2005
It was downloaded from http://proxytunnel.sourceforge.net

1
debian/dirs vendored
View file

@ -1,2 +1,3 @@
usr/bin
usr/share/man
usr/man/man1

1
debian/docs vendored
View file

@ -1,2 +1,3 @@
CREDITS
README
CHANGES

40
http.c
View file

@ -29,6 +29,7 @@
#include "io.h"
#include "proxytunnel.h"
#include "basicauth.h"
#include "ntlm.h"
/*
* Analyze the proxy's HTTP response. This must be a HTTP/1.? 200 OK type
@ -51,6 +52,19 @@ void analyze_HTTP()
message( "HTTP return code: '%s'\n", p );
p += strlen( p ) + 1;
message( "%s\n", p );
if (!ntlm_challenge && strcmp( p, "407") != 0) {
do {
readline();
if (strncmp( buf, "Proxy-Authenticate: NTLM ", 25) == 0) {
if (parse_type2(&buf[25]) < 0)
exit(1);
}
} while ( strcmp( buf, "\r\n" ) != 0 );
}
if (ntlm_challenge == 1) {
return proxy_protocol();
}
exit( 1 );
}
}
@ -105,8 +119,19 @@ void proxy_protocol()
/*
* Create connect string including the authorization part
*/
sprintf( buf, "%sProxy-authorization: Basic %s\r\n",
buf, basicauth );
if (args_info.ntlm_flag) {
if (ntlm_challenge == 1) {
build_type3_response();
sprintf( buf, "%sProxy-Authorization: NTLM %s\r\n",
buf, ntlm_type3_buf );
} else if (ntlm_challenge == 0){
sprintf( buf, "%sProxy-Authorization: NTLM %s\r\n",
buf, ntlm_type1_buf );
}
} else {
sprintf( buf, "%sProxy-authorization: Basic %s\r\n",
buf, basicauth );
}
}
if ( args_info.header_given )
@ -130,7 +155,6 @@ void proxy_protocol()
my_perror( "Socket write error" );
exit( 1 );
}
/*
* Read the first line of the response and analyze it
*/
@ -141,7 +165,11 @@ void proxy_protocol()
* Then, repeat reading lines of the responses until a blank line
* (which signifies the end of the response) is encountered.
*/
do {
readline();
} while ( strcmp( buf, "\r\n" ) != 0 );
if (ntlm_challenge == 1) {
ntlm_challenge = 2;
} else {
do {
readline();
} while ( strcmp( buf, "\r\n" ) != 0 );
}
}

View file

@ -37,6 +37,7 @@
#include "cmdline.h"
#include "basicauth.h"
#include "proxytunnel.h"
#include "ntlm.h"
/* Define DARWIN if compiling on MacOS-X (Darwin), to work around some
* inconsistencies. (Darwin doesn't know socklen_t) */
@ -231,6 +232,10 @@ void do_daemon()
read_fd = write_fd = sd_client;
tunnel_connect();
proxy_protocol();
if (args_info.ntlm_flag) {
proxy_protocol();
proxy_protocol();
}
cpio();
exit( 0 );
}
@ -278,7 +283,11 @@ int main( int argc, char *argv[] )
if( args_info.user_given && args_info.pass_given )
{
make_basicauth();
if (args_info.ntlm_flag) {
build_type1();
message("Build Type 1 NTLM Message : %s\n", ntlm_type1_buf);
} else
make_basicauth();
}
/* Do we need to run as a standalone daemon? */