From 67c71112364b258053781cbf9e6f3665805ebe09 Mon Sep 17 00:00:00 2001 From: richterger Date: Tue, 2 Oct 2012 09:12:08 +0200 Subject: [PATCH] Add support for connection via http proxy Adds --proxy : commandline option Simple implementation, no proxy authentication --- include/freerdp/settings.h | 5 +++++ libfreerdp/core/transport.c | 41 ++++++++++++++++++++++++++++++++++++- libfreerdp/core/transport.h | 6 ++++++ libfreerdp/utils/args.c | 21 +++++++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 2baffa7b8..f6b079085 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -477,6 +477,11 @@ struct rdp_settings /* Extensions */ ALIGN64 int num_extensions; ALIGN64 struct rdp_ext_set extensions[16]; + + /* Proxy */ + ALIGN64 char * proxy_host; + ALIGN64 int proxy_port; + }; typedef struct rdp_settings rdpSettings; diff --git a/libfreerdp/core/transport.c b/libfreerdp/core/transport.c index 1073eb95f..272fc0ecd 100644 --- a/libfreerdp/core/transport.c +++ b/libfreerdp/core/transport.c @@ -204,7 +204,46 @@ boolean transport_connect(rdpTransport* transport, const char* hostname, uint16 } else { - status = tcp_connect(transport->tcp, hostname, port); + if(transport->settings->proxy_host) + { + status = tcp_connect(transport->tcp, transport->settings->proxy_host, transport->settings->proxy_port); + if(status) + { + char buf[8192]; + int bytes_read; + int n = snprintf(buf,sizeof(buf), "CONNECT %s:%d HTTP/1.0\r\n\r\n", hostname, port); + tcp_write(transport->tcp, buf, n); + + bytes_read = tcp_read(transport->tcp, buf, sizeof(buf)); + if(bytes_read > 12) + { + if( (strncmp(buf,"HTTP/1.0 200", 12) == 0) || + (strncmp(buf,"HTTP/1.1 200", 12) == 0) ) + { + printf("Connected via proxy\n"); + while (bytes_read > 0) + { + if (bytes_read > 4 && strncmp(buf + bytes_read - 4, "\r\n\r\n", 4) == 0) + break ; + bytes_read = tcp_read(transport->tcp, buf, sizeof(buf) - 1) ; + } + } + else + { + printf("Proxy connection failed: %s\n", buf); + return false; + } + } + else + { + return false; + } + } + } + else + { + status = tcp_connect(transport->tcp, hostname, port); + } } return status; diff --git a/libfreerdp/core/transport.h b/libfreerdp/core/transport.h index e082fc44e..683d549b2 100644 --- a/libfreerdp/core/transport.h +++ b/libfreerdp/core/transport.h @@ -43,6 +43,12 @@ typedef struct rdp_transport rdpTransport; #include #include +#ifdef _WIN32 +#ifndef snprintf +#define snprintf _snprintf +#endif +#endif + typedef boolean (*TransportRecv) (rdpTransport* transport, STREAM* stream, void* extra); struct rdp_transport diff --git a/libfreerdp/utils/args.c b/libfreerdp/utils/args.c index 503af4286..d55628073 100644 --- a/libfreerdp/utils/args.c +++ b/libfreerdp/utils/args.c @@ -91,6 +91,7 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, { int t; char* p; + char* cp; int i, j; int index = 1; int num_extensions = 0; @@ -163,6 +164,7 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, " --no-salted-checksum: disable salted checksums with Standard RDP encryption\n" " --pcid: preconnection id\n" " --pcb: preconnection blob\n" + " --proxy: : connect via http proxy\n" " --version: print version information\n" "\n", argv[0]); return FREERDP_ARGS_PARSE_HELP; /* TODO: What is the correct return? */ @@ -816,6 +818,25 @@ int freerdp_parse_args(rdpSettings* settings, int argc, char** argv, printf("This is FreeRDP version %s (git %s)\n", FREERDP_VERSION_FULL, GIT_REVISION); return FREERDP_ARGS_PARSE_VERSION; } + else if (strcmp("--proxy", argv[index]) == 0) + { + index++; + if (index == argc) + { + printf("missing proxy\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + // split in proxy and port + settings->proxy_host = xstrdup(argv[index]); + cp = strrchr(settings->proxy_host, ':'); + if( ! cp ) + { + printf("illegal proxy spec\n"); + return FREERDP_ARGS_PARSE_FAILURE; + } + *cp = 0; + settings->proxy_port = atoi(cp+1); + } else if (argv[index][0] != '-') { freerdp_parse_hostname(settings, argv[index]);