summaryrefslogtreecommitdiff
path: root/app/openvpn/src/openvpn/proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/openvpn/src/openvpn/proxy.c')
-rw-r--r--app/openvpn/src/openvpn/proxy.c907
1 files changed, 0 insertions, 907 deletions
diff --git a/app/openvpn/src/openvpn/proxy.c b/app/openvpn/src/openvpn/proxy.c
deleted file mode 100644
index 17748504..00000000
--- a/app/openvpn/src/openvpn/proxy.c
+++ /dev/null
@@ -1,907 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single TCP/UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * 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 (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#elif defined(_MSC_VER)
-#include "config-msvc.h"
-#endif
-
-#include "syshead.h"
-
-#include "common.h"
-#include "misc.h"
-#include "crypto.h"
-#include "win32.h"
-#include "socket.h"
-#include "fdmisc.h"
-#include "proxy.h"
-#include "base64.h"
-#include "httpdigest.h"
-#include "ntlm.h"
-#include "memdbg.h"
-
-#ifdef ENABLE_HTTP_PROXY
-
-#define UP_TYPE_PROXY "HTTP Proxy"
-
-struct http_proxy_options *
-init_http_proxy_options_once (struct http_proxy_options **hpo,
- struct gc_arena *gc)
-{
- if (!*hpo)
- {
- ALLOC_OBJ_CLEAR_GC (*hpo, struct http_proxy_options, gc);
- /* http proxy defaults */
- (*hpo)->timeout = 5;
- (*hpo)->http_version = "1.0";
- }
- return *hpo;
-}
-
-
-/* cached proxy username/password */
-static struct user_pass static_proxy_user_pass;
-
-static bool
-recv_line (socket_descriptor_t sd,
- char *buf,
- int len,
- const int timeout_sec,
- const bool verbose,
- struct buffer *lookahead,
- volatile int *signal_received)
-{
- struct buffer la;
- int lastc = 0;
-
- CLEAR (la);
- if (lookahead)
- la = *lookahead;
-
- while (true)
- {
- int status;
- ssize_t size;
- fd_set reads;
- struct timeval tv;
- uint8_t c;
-
- if (buf_defined (&la))
- {
- ASSERT (buf_init (&la, 0));
- }
-
- FD_ZERO (&reads);
- FD_SET (sd, &reads);
- tv.tv_sec = timeout_sec;
- tv.tv_usec = 0;
-
- status = select (sd + 1, &reads, NULL, NULL, &tv);
-
- get_signal (signal_received);
- if (*signal_received)
- goto error;
-
- /* timeout? */
- if (status == 0)
- {
- if (verbose)
- msg (D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read timeout expired");
- goto error;
- }
-
- /* error */
- if (status < 0)
- {
- if (verbose)
- msg (D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read failed on select()");
- goto error;
- }
-
- /* read single char */
- size = recv (sd, &c, 1, MSG_NOSIGNAL);
-
- /* error? */
- if (size != 1)
- {
- if (verbose)
- msg (D_LINK_ERRORS | M_ERRNO, "recv_line: TCP port read failed on recv()");
- goto error;
- }
-
-#if 0
- if (isprint(c))
- msg (M_INFO, "PROXY: read '%c' (%d)", c, (int)c);
- else
- msg (M_INFO, "PROXY: read (%d)", (int)c);
-#endif
-
- /* store char in buffer */
- if (len > 1)
- {
- *buf++ = c;
- --len;
- }
-
- /* also store char in lookahead buffer */
- if (buf_defined (&la))
- {
- buf_write_u8 (&la, c);
- if (!isprint(c) && !isspace(c)) /* not ascii? */
- {
- if (verbose)
- msg (D_LINK_ERRORS | M_ERRNO, "recv_line: Non-ASCII character (%d) read on recv()", (int)c);
- *lookahead = la;
- return false;
- }
- }
-
- /* end of line? */
- if (lastc == '\r' && c == '\n')
- break;
-
- lastc = c;
- }
-
- /* append trailing null */
- if (len > 0)
- *buf++ = '\0';
-
- return true;
-
- error:
- return false;
-}
-
-static bool
-send_line (socket_descriptor_t sd,
- const char *buf)
-{
- const ssize_t size = send (sd, buf, strlen (buf), MSG_NOSIGNAL);
- if (size != (ssize_t) strlen (buf))
- {
- msg (D_LINK_ERRORS | M_ERRNO, "send_line: TCP port write failed on send()");
- return false;
- }
- return true;
-}
-
-static bool
-send_line_crlf (socket_descriptor_t sd,
- const char *src)
-{
- bool ret;
-
- struct buffer buf = alloc_buf (strlen (src) + 3);
- ASSERT (buf_write (&buf, src, strlen (src)));
- ASSERT (buf_write (&buf, "\r\n", 3));
- ret = send_line (sd, BSTR (&buf));
- free_buf (&buf);
- return ret;
-}
-
-static bool
-send_crlf (socket_descriptor_t sd)
-{
- return send_line_crlf (sd, "");
-}
-
-uint8_t *
-make_base64_string2 (const uint8_t *str, int src_len, struct gc_arena *gc)
-{
- uint8_t *ret = NULL;
- char *b64out = NULL;
- ASSERT (openvpn_base64_encode ((const void *)str, src_len, &b64out) >= 0);
- ret = (uint8_t *) string_alloc (b64out, gc);
- free (b64out);
- return ret;
-}
-
-uint8_t *
-make_base64_string (const uint8_t *str, struct gc_arena *gc)
-{
- return make_base64_string2 (str, strlen ((const char *)str), gc);
-}
-
-static const char *
-username_password_as_base64 (const struct http_proxy_info *p,
- struct gc_arena *gc)
-{
- struct buffer out = alloc_buf_gc (strlen (p->up.username) + strlen (p->up.password) + 2, gc);
- ASSERT (strlen (p->up.username) > 0);
- buf_printf (&out, "%s:%s", p->up.username, p->up.password);
- return (const char *)make_base64_string ((const uint8_t*)BSTR (&out), gc);
-}
-
-static void
-get_user_pass_http (struct http_proxy_info *p, const bool force)
-{
- if (!static_proxy_user_pass.defined || force)
- {
- unsigned int flags = GET_USER_PASS_MANAGEMENT;
- if (p->queried_creds)
- flags |= GET_USER_PASS_PREVIOUS_CREDS_FAILED;
- get_user_pass (&static_proxy_user_pass,
- p->options.auth_file,
- UP_TYPE_PROXY,
- flags);
- p->queried_creds = true;
- p->up = static_proxy_user_pass;
- }
-}
-static void
-clear_user_pass_http (void)
-{
- purge_user_pass (&static_proxy_user_pass, true);
-}
-
-static void
-dump_residual (socket_descriptor_t sd,
- int timeout,
- volatile int *signal_received)
-{
- char buf[256];
- while (true)
- {
- if (!recv_line (sd, buf, sizeof (buf), timeout, true, NULL, signal_received))
- return;
- chomp (buf);
- msg (D_PROXY, "PROXY HEADER: '%s'", buf);
- }
-}
-
-/*
- * Extract the Proxy-Authenticate header from the stream.
- * Consumes all headers.
- */
-static int
-get_proxy_authenticate (socket_descriptor_t sd,
- int timeout,
- char **data,
- struct gc_arena *gc,
- volatile int *signal_received)
-{
- char buf[256];
- int ret = HTTP_AUTH_NONE;
- while (true)
- {
- if (!recv_line (sd, buf, sizeof (buf), timeout, true, NULL, signal_received))
- {
- *data = NULL;
- return HTTP_AUTH_NONE;
- }
- chomp (buf);
- if (!strlen(buf))
- return ret;
- if (ret == HTTP_AUTH_NONE && !strncmp(buf, "Proxy-Authenticate: ", 20))
- {
- if (!strncmp(buf+20, "Basic ", 6))
- {
- msg (D_PROXY, "PROXY AUTH BASIC: '%s'", buf);
- *data = string_alloc(buf+26, gc);
- ret = HTTP_AUTH_BASIC;
- }
-#if PROXY_DIGEST_AUTH
- else if (!strncmp(buf+20, "Digest ", 7))
- {
- msg (D_PROXY, "PROXY AUTH DIGEST: '%s'", buf);
- *data = string_alloc(buf+27, gc);
- ret = HTTP_AUTH_DIGEST;
- }
-#endif
-#if NTLM
- else if (!strncmp(buf+20, "NTLM", 4))
- {
- msg (D_PROXY, "PROXY AUTH HTLM: '%s'", buf);
- *data = NULL;
- ret = HTTP_AUTH_NTLM;
- }
-#endif
- }
- }
-}
-
-static void
-store_proxy_authenticate (struct http_proxy_info *p, char *data)
-{
- if (p->proxy_authenticate)
- free (p->proxy_authenticate);
- p->proxy_authenticate = data;
-}
-
-/*
- * Parse out key/value pairs from Proxy-Authenticate string.
- * Return true on success, or false on parse failure.
- */
-static bool
-get_key_value(const char *str, /* source string */
- char *key, /* key stored here */
- char *value, /* value stored here */
- int max_key_len,
- int max_value_len,
- const char **endptr) /* next search position */
-{
- int c;
- bool starts_with_quote = false;
- bool escape = false;
-
- for (c = max_key_len-1; (*str && (*str != '=') && c--); )
- *key++ = *str++;
- *key = '\0';
-
- if('=' != *str++)
- /* no key/value found */
- return false;
-
- if('\"' == *str)
- {
- /* quoted string */
- str++;
- starts_with_quote = true;
- }
-
- for (c = max_value_len-1; *str && c--; str++)
- {
- switch (*str)
- {
- case '\\':
- if (!escape)
- {
- /* possibly the start of an escaped quote */
- escape = true;
- *value++ = '\\'; /* even though this is an escape character, we still
- store it as-is in the target buffer */
- continue;
- }
- break;
- case ',':
- if (!starts_with_quote)
- {
- /* this signals the end of the value if we didn't get a starting quote
- and then we do "sloppy" parsing */
- c=0; /* the end */
- continue;
- }
- break;
- case '\r':
- case '\n':
- /* end of string */
- c=0;
- continue;
- case '\"':
- if (!escape && starts_with_quote)
- {
- /* end of string */
- c=0;
- continue;
- }
- break;
- }
- escape = false;
- *value++ = *str;
- }
- *value = '\0';
-
- *endptr = str;
-
- return true; /* success */
-}
-
-static char *
-get_pa_var (const char *key, const char *pa, struct gc_arena *gc)
-{
- char k[64];
- char v[256];
- const char *content = pa;
-
- while (true)
- {
- const int status = get_key_value(content, k, v, sizeof(k), sizeof(v), &content);
- if (status)
- {
- if (!strcmp(key, k))
- return string_alloc(v, gc);
- }
- else
- return NULL;
-
- /* advance to start of next key */
- if (*content == ',')
- ++content;
- while (*content && isspace(*content))
- ++content;
- }
-}
-
-struct http_proxy_info *
-http_proxy_new (const struct http_proxy_options *o)
-{
- struct http_proxy_info *p;
- struct http_proxy_options opt;
-
- if (!o || !o->server)
- msg (M_FATAL, "HTTP_PROXY: server not specified");
-
- ASSERT ( o->port);
-
- ALLOC_OBJ_CLEAR (p, struct http_proxy_info);
- p->options = *o;
-
- /* parse authentication method */
- p->auth_method = HTTP_AUTH_NONE;
- if (o->auth_method_string)
- {
- if (!strcmp (o->auth_method_string, "none"))
- p->auth_method = HTTP_AUTH_NONE;
- else if (!strcmp (o->auth_method_string, "basic"))
- p->auth_method = HTTP_AUTH_BASIC;
-#if NTLM
- else if (!strcmp (o->auth_method_string, "ntlm"))
- p->auth_method = HTTP_AUTH_NTLM;
- else if (!strcmp (o->auth_method_string, "ntlm2"))
- p->auth_method = HTTP_AUTH_NTLM2;
-#endif
- else
- msg (M_FATAL, "ERROR: unknown HTTP authentication method: '%s'",
- o->auth_method_string);
- }
-
- /* only basic and NTLM/NTLMv2 authentication supported so far */
- if (p->auth_method == HTTP_AUTH_BASIC || p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2)
- {
- get_user_pass_http (p, true);
- }
-
-#if !NTLM
- if (p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2)
- msg (M_FATAL, "Sorry, this version of " PACKAGE_NAME " was built without NTLM Proxy support.");
-#endif
-
- p->defined = true;
- return p;
-}
-
-void
-http_proxy_close (struct http_proxy_info *hp)
-{
- free (hp);
-}
-
-bool
-establish_http_proxy_passthru (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 */
- struct buffer *lookahead,
- volatile int *signal_received)
-{
- struct gc_arena gc = gc_new ();
- char buf[512];
- char buf2[128];
- char get[80];
- int status;
- int nparms;
- bool ret = false;
- bool processed = false;
-
- /* get user/pass if not previously given */
- if (p->auth_method == HTTP_AUTH_BASIC
- || p->auth_method == HTTP_AUTH_DIGEST
- || p->auth_method == HTTP_AUTH_NTLM)
- get_user_pass_http (p, false);
-
- /* are we being called again after getting the digest server nonce in the previous transaction? */
- if (p->auth_method == HTTP_AUTH_DIGEST && p->proxy_authenticate)
- {
- nparms = 1;
- status = 407;
- }
- else
- {
- /* format HTTP CONNECT message */
- openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%s HTTP/%s",
- host,
- port,
- p->options.http_version);
-
- msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
-
- /* send HTTP CONNECT message to proxy */
- 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;
- }
-
- /* auth specified? */
- switch (p->auth_method)
- {
- case HTTP_AUTH_NONE:
- break;
-
- case HTTP_AUTH_BASIC:
- openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: Basic %s",
- username_password_as_base64 (p, &gc));
- msg (D_PROXY, "Attempting Basic Proxy-Authorization");
- dmsg (D_SHOW_KEYS, "Send to HTTP proxy: '%s'", buf);
- if (!send_line_crlf (sd, buf))
- goto error;
- break;
-
-#if NTLM
- case HTTP_AUTH_NTLM:
- case HTTP_AUTH_NTLM2:
- /* keep-alive connection */
- openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: Keep-Alive");
- if (!send_line_crlf (sd, buf))
- goto error;
-
- openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s",
- ntlm_phase_1 (p, &gc));
- msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 1");
- dmsg (D_SHOW_KEYS, "Send to HTTP proxy: '%s'", buf);
- if (!send_line_crlf (sd, buf))
- goto error;
- break;
-#endif
-
- default:
- ASSERT (0);
- }
-
- /* send empty CR, LF */
- if (!send_crlf (sd))
- goto error;
-
- /* receive reply from proxy */
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
- goto error;
-
- /* remove trailing CR, LF */
- chomp (buf);
-
- msg (D_PROXY, "HTTP proxy returned: '%s'", buf);
-
- /* parse return string */
- nparms = sscanf (buf, "%*s %d", &status);
-
- }
-
- /* check for a "407 Proxy Authentication Required" response */
- while (nparms >= 1 && status == 407)
- {
- msg (D_PROXY, "Proxy requires authentication");
-
- if (p->auth_method == HTTP_AUTH_BASIC && !processed)
- {
- processed = true;
- }
- else if ((p->auth_method == HTTP_AUTH_NTLM || p->auth_method == HTTP_AUTH_NTLM2) && !processed) /* check for NTLM */
- {
-#if NTLM
- /* look for the phase 2 response */
-
- while (true)
- {
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
- goto error;
- chomp (buf);
- msg (D_PROXY, "HTTP proxy returned: '%s'", buf);
-
- openvpn_snprintf (get, sizeof get, "%%*s NTLM %%%ds", (int) sizeof (buf2) - 1);
- nparms = sscanf (buf, get, buf2);
- buf2[127] = 0; /* we only need the beginning - ensure it's null terminated. */
-
- /* check for "Proxy-Authenticate: NTLM TlRM..." */
- if (nparms == 1)
- {
- /* parse buf2 */
- msg (D_PROXY, "auth string: '%s'", buf2);
- break;
- }
- }
- /* if we are here then auth string was got */
- msg (D_PROXY, "Received NTLM Proxy-Authorization phase 2 response");
-
- /* receive and discard everything else */
- while (recv_line (sd, NULL, 0, 2, true, NULL, signal_received))
- ;
-
- /* now send the phase 3 reply */
-
- /* format HTTP CONNECT message */
- openvpn_snprintf (buf, sizeof(buf), "CONNECT %s:%s HTTP/%s",
- host,
- port,
- p->options.http_version);
-
- msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
-
- /* send HTTP CONNECT message to proxy */
- if (!send_line_crlf (sd, buf))
- goto error;
-
- /* keep-alive connection */
- openvpn_snprintf (buf, sizeof(buf), "Proxy-Connection: Keep-Alive");
- 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;
-
- msg (D_PROXY, "Attempting NTLM Proxy-Authorization phase 3");
- {
- const char *np3 = ntlm_phase_3 (p, buf2, &gc);
- if (!np3)
- {
- msg (D_PROXY, "NTLM Proxy-Authorization phase 3 failed: received corrupted data from proxy server");
- goto error;
- }
- openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: NTLM %s", np3);
- }
-
- msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
- if (!send_line_crlf (sd, buf))
- goto error;
- /* ok so far... */
- /* send empty CR, LF */
- if (!send_crlf (sd))
- goto error;
-
- /* receive reply from proxy */
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
- goto error;
-
- /* remove trailing CR, LF */
- chomp (buf);
-
- msg (D_PROXY, "HTTP proxy returned: '%s'", buf);
-
- /* parse return string */
- nparms = sscanf (buf, "%*s %d", &status);
- processed = true;
-#endif
- }
-#if PROXY_DIGEST_AUTH
- else if (p->auth_method == HTTP_AUTH_DIGEST && !processed)
- {
- char *pa = p->proxy_authenticate;
- const int method = p->auth_method;
- ASSERT(pa);
-
- if (method == HTTP_AUTH_DIGEST)
- {
- const char *http_method = "CONNECT";
- const char *nonce_count = "00000001";
- const char *qop = "auth";
- const char *username = p->up.username;
- const char *password = p->up.password;
- char *opaque_kv = "";
- char uri[128];
- uint8_t cnonce_raw[8];
- uint8_t *cnonce;
- HASHHEX session_key;
- HASHHEX response;
-
- const char *realm = get_pa_var("realm", pa, &gc);
- const char *nonce = get_pa_var("nonce", pa, &gc);
- const char *algor = get_pa_var("algorithm", pa, &gc);
- const char *opaque = get_pa_var("opaque", pa, &gc);
-
- /* generate a client nonce */
- ASSERT(rand_bytes(cnonce_raw, sizeof(cnonce_raw)));
- cnonce = make_base64_string2(cnonce_raw, sizeof(cnonce_raw), &gc);
-
-
- /* build the digest response */
- openvpn_snprintf (uri, sizeof(uri), "%s:%s",
- host,
- port);
-
- if (opaque)
- {
- const int len = strlen(opaque)+16;
- opaque_kv = gc_malloc(len, false, &gc);
- openvpn_snprintf (opaque_kv, len, ", opaque=\"%s\"", opaque);
- }
-
- DigestCalcHA1(algor,
- username,
- realm,
- password,
- nonce,
- (char *)cnonce,
- session_key);
- DigestCalcResponse(session_key,
- nonce,
- nonce_count,
- (char *)cnonce,
- qop,
- http_method,
- uri,
- NULL,
- response);
-
- /* format HTTP CONNECT message */
- openvpn_snprintf (buf, sizeof(buf), "%s %s HTTP/%s",
- http_method,
- uri,
- p->options.http_version);
-
- msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
-
- /* send HTTP CONNECT message to proxy */
- 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;
-
- /* send digest response */
- openvpn_snprintf (buf, sizeof(buf), "Proxy-Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", qop=%s, nc=%s, cnonce=\"%s\", response=\"%s\"%s",
- username,
- realm,
- nonce,
- uri,
- qop,
- nonce_count,
- cnonce,
- response,
- opaque_kv
- );
- msg (D_PROXY, "Send to HTTP proxy: '%s'", buf);
- if (!send_line_crlf (sd, buf))
- goto error;
- if (!send_crlf (sd))
- goto error;
-
- /* receive reply from proxy */
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
- goto error;
-
- /* remove trailing CR, LF */
- chomp (buf);
-
- msg (D_PROXY, "HTTP proxy returned: '%s'", buf);
-
- /* parse return string */
- nparms = sscanf (buf, "%*s %d", &status);
- processed = true;
- }
- else
- {
- msg (D_PROXY, "HTTP proxy: digest method not supported");
- goto error;
- }
- }
-#endif
- else if (p->options.auth_retry)
- {
- /* figure out what kind of authentication the proxy needs */
- char *pa = NULL;
- const int method = get_proxy_authenticate(sd,
- p->options.timeout,
- &pa,
- NULL,
- signal_received);
- if (method != HTTP_AUTH_NONE)
- {
- if (pa)
- msg (D_PROXY, "HTTP proxy authenticate '%s'", pa);
- if (p->options.auth_retry == PAR_NCT && method == HTTP_AUTH_BASIC)
- {
- msg (D_PROXY, "HTTP proxy: support for basic auth and other cleartext proxy auth methods is disabled");
- goto error;
- }
- p->auth_method = method;
- store_proxy_authenticate(p, pa);
- ret = true;
- goto done;
- }
- else
- {
- msg (D_PROXY, "HTTP proxy: do not recognize the authentication method required by proxy");
- free (pa);
- goto error;
- }
- }
- else
- {
- if (!processed)
- msg (D_PROXY, "HTTP proxy: no support for proxy authentication method");
- goto error;
- }
-
- /* clear state */
- if (p->options.auth_retry)
- clear_user_pass_http();
- store_proxy_authenticate(p, NULL);
- }
-
- /* check return code, success = 200 */
- if (nparms < 1 || status != 200)
- {
- msg (D_LINK_ERRORS, "HTTP proxy returned bad status");
-#if 0
- /* DEBUGGING -- show a multi-line HTTP error response */
- dump_residual(sd, p->options.timeout, signal_received);
-#endif
- goto error;
- }
-
- /* SUCCESS */
-
- /* receive line from proxy and discard */
- if (!recv_line (sd, NULL, 0, p->options.timeout, true, NULL, signal_received))
- goto error;
-
- /*
- * Toss out any extraneous chars, but don't throw away the
- * start of the OpenVPN data stream (put it in lookahead).
- */
- while (recv_line (sd, NULL, 0, 2, false, lookahead, signal_received))
- ;
-
- /* reset queried_creds so that we don't think that the next creds request is due to an auth error */
- p->queried_creds = false;
-
-#if 0
- if (lookahead && BLEN (lookahead))
- msg (M_INFO, "HTTP PROXY: lookahead: %s", format_hex (BPTR (lookahead), BLEN (lookahead), 0));
-#endif
-
- done:
- gc_free (&gc);
- return ret;
-
- error:
- /* on error, should we exit or restart? */
- if (!*signal_received)
- *signal_received = (p->options.retry ? SIGUSR1 : SIGTERM); /* SOFT-SIGUSR1 -- HTTP proxy error */
- gc_free (&gc);
- return ret;
-}
-
-#else
-static void dummy(void) {}
-#endif /* ENABLE_HTTP_PROXY */
-