From d0cb816cf8be68359617b61a55799f6330901f6a Mon Sep 17 00:00:00 2001 From: Arne Schwabe Date: Fri, 25 Oct 2013 10:02:23 +0200 Subject: Implement custom HTTP header for http-proxy, and always send user-agent: There are some patched OpenVPN versions out there without source code (e.g. NDMVPN) that support adding custom http header. This patch adds custom header to OpenVPN and supports the syntax that the "in the wild" variants use. Patch v3 also prints all custom headers with other http options in --verb 5 Patch v4 does clean up the add_proxy_header function Acked-by: Gert Doering Message-Id: <1382688143-17247-1-git-send-email-arne@rfc2549.org> URL: http://article.gmane.org/gmane.network.openvpn.devel/7946 Signed-off-by: Gert Doering --- src/openvpn/proxy.c | 88 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 21 deletions(-) (limited to 'src/openvpn/proxy.c') 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 */ -- cgit v1.1