diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/openvpn/options.c | 37 | ||||
-rw-r--r-- | src/openvpn/proxy.c | 88 | ||||
-rw-r--r-- | src/openvpn/proxy.h | 7 |
3 files changed, 111 insertions, 21 deletions
diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 4d0271f..e925397 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -1295,6 +1295,7 @@ option_iroute_ipv6 (struct options *o, static void show_http_proxy_options (const struct http_proxy_options *o) { + int i; msg (D_SHOW_PARMS, "BEGIN http_proxy"); SHOW_STR (server); SHOW_INT (port); @@ -1304,6 +1305,15 @@ show_http_proxy_options (const struct http_proxy_options *o) SHOW_INT (timeout); SHOW_STR (http_version); SHOW_STR (user_agent); + for (i=0; i < MAX_CUSTOM_HTTP_HEADER && o->custom_headers[i].name;i++) + { + if (o->custom_headers[i].content) + msg (D_SHOW_PARMS, " custom_header[%d] = %s: %s", i, + o->custom_headers[i].name, o->custom_headers[i].content); + else + msg (D_SHOW_PARMS, " custom_header[%d] = %s", i, + o->custom_headers[i].name); + } msg (D_SHOW_PARMS, "END http_proxy"); } #endif @@ -5061,6 +5071,33 @@ add_option (struct options *options, { ho->user_agent = p[2]; } + else if ((streq (p[1], "EXT1") || streq(p[1], "EXT2") || streq(p[1], "CUSTOM-HEADER")) + && p[2]) + { + /* In the wild patched versions use both EXT1/2 and CUSTOM-HEADER + * with either two argument or one */ + + struct http_custom_header *custom_header = NULL; + int i; + /* Find the first free header */ + for (i=0; i < MAX_CUSTOM_HTTP_HEADER; i++) { + if (!ho->custom_headers[i].name) { + custom_header = &ho->custom_headers[i]; + break; + } + } + if (!custom_header) + { + msg (msglevel, "Cannot use more than %d http-proxy-option CUSTOM-HEADER : '%s'", MAX_CUSTOM_HTTP_HEADER, p[1]); + } + else + { + /* We will save p[2] and p[3], the proxy code will detect if + * p[3] is NULL */ + custom_header->name = p[2]; + custom_header->content = p[3]; + } + } else { msg (msglevel, "Bad http-proxy-option or missing parameter: '%s'", p[1]); diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c index 04ed421..ed4aedd 100644 --- a/src/openvpn/proxy.c +++ b/src/openvpn/proxy.c @@ -489,6 +489,67 @@ http_proxy_close (struct http_proxy_info *hp) } bool +add_proxy_headers (struct http_proxy_info *p, + socket_descriptor_t sd, /* already open to proxy */ + const char *host, /* openvpn server remote */ + const char *port /* openvpn server port */ + ) +{ + char buf[512]; + int i; + bool host_header_sent=false; + + /* + * Send custom headers if provided + * If content is NULL the whole header is in name + * Also remember if we already sent a Host: header + */ + for (i=0; i < MAX_CUSTOM_HTTP_HEADER && p->options.custom_headers[i].name;i++) + { + if (p->options.custom_headers[i].content) + { + openvpn_snprintf (buf, sizeof(buf), "%s: %s", + p->options.custom_headers[i].name, + p->options.custom_headers[i].content); + if (!strcasecmp(p->options.custom_headers[i].name, "Host")) + host_header_sent=true; + } + else + { + openvpn_snprintf (buf, sizeof(buf), "%s", + p->options.custom_headers[i].name); + if (!strncasecmp(p->options.custom_headers[i].name, "Host:", 5)) + host_header_sent=true; + } + + msg (D_PROXY, "Send to HTTP proxy: '%s'", buf); + if (!send_line_crlf (sd, buf)) + return false; + } + + if (!host_header_sent) + { + openvpn_snprintf (buf, sizeof(buf), "Host: %s", host); + msg (D_PROXY, "Send to HTTP proxy: '%s'", buf); + if (!send_line_crlf(sd, buf)) + return false; + } + + /* send User-Agent string if provided */ + if (p->options.user_agent) + { + openvpn_snprintf (buf, sizeof(buf), "User-Agent: %s", + p->options.user_agent); + msg (D_PROXY, "Send to HTTP proxy: '%s'", buf); + if (!send_line_crlf (sd, buf)) + return false; + } + + return true; +} + + +bool establish_http_proxy_passthru (struct http_proxy_info *p, socket_descriptor_t sd, /* already open to proxy */ const char *host, /* openvpn server remote */ @@ -531,18 +592,8 @@ establish_http_proxy_passthru (struct http_proxy_info *p, if (!send_line_crlf (sd, buf)) goto error; - openvpn_snprintf(buf, sizeof(buf), "Host: %s", host); - if (!send_line_crlf(sd, buf)) - goto error; - - /* send User-Agent string if provided */ - if (p->options.user_agent) - { - openvpn_snprintf (buf, sizeof(buf), "User-Agent: %s", - p->options.user_agent); - if (!send_line_crlf (sd, buf)) - goto error; - } + if (!add_proxy_headers (p, sd, host, port)) + goto error; /* auth specified? */ switch (p->auth_method) @@ -657,14 +708,11 @@ establish_http_proxy_passthru (struct http_proxy_info *p, if (!send_line_crlf (sd, buf)) goto error; - /* send HOST etc, */ - openvpn_snprintf (buf, sizeof(buf), "Host: %s", host); - msg (D_PROXY, "Send to HTTP proxy: '%s'", buf); - if (!send_line_crlf (sd, buf)) - goto error; + if (!add_proxy_headers (p, sd, host, port)) + goto error; - msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 3"); + msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 3"); { const char *np3 = ntlm_phase_3 (p, buf2, &gc); if (!np3) @@ -770,9 +818,7 @@ establish_http_proxy_passthru (struct http_proxy_info *p, goto error; /* send HOST etc, */ - openvpn_snprintf (buf, sizeof(buf), "Host: %s", host); - msg (D_PROXY, "Send to HTTP proxy: '%s'", buf); - if (!send_line_crlf (sd, buf)) + if (!add_proxy_headers (p, sd, host, port)) goto error; /* send digest response */ diff --git a/src/openvpn/proxy.h b/src/openvpn/proxy.h index 5e476f1..b72748f 100644 --- a/src/openvpn/proxy.h +++ b/src/openvpn/proxy.h @@ -38,6 +38,12 @@ #define HTTP_AUTH_NTLM2 4 #define HTTP_AUTH_N 5 /* number of HTTP_AUTH methods */ +struct http_custom_header { + const char *name; + const char *content; +}; + +#define MAX_CUSTOM_HTTP_HEADER 10 struct http_proxy_options { const char *server; int port; @@ -53,6 +59,7 @@ struct http_proxy_options { const char *auth_file; const char *http_version; const char *user_agent; + struct http_custom_header custom_headers[MAX_CUSTOM_HTTP_HEADER]; }; struct http_proxy_options_simple { |