/*
 *  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-2018 OpenVPN 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; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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"
#include "forward.h"

#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)->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);
        openvpn_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
clear_user_pass_http(void)
{
    purge_user_pass(&static_proxy_user_pass, true);
}

static void
get_user_pass_http(struct http_proxy_info *p, const bool force)
{
    /*
     * in case of forced (re)load, make sure the static storage is set as
     * undefined, otherwise get_user_pass() won't try to load any credential
     */
    if (force)
    {
        clear_user_pass_http();
    }

    if (!static_proxy_user_pass.defined)
    {
        unsigned int flags = GET_USER_PASS_MANAGEMENT;
        if (p->queried_creds)
        {
            flags |= GET_USER_PASS_PREVIOUS_CREDS_FAILED;
        }
        if (p->options.inline_creds)
        {
            flags |= GET_USER_PASS_INLINE_CREDS;
        }
        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;
    }
}

#if 0
/* function only used in #if 0 debug statement */
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);
    }
}
#endif

/*
 * 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))
        {
            free(*data);
            *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 NTLM: '%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;

    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);
}

static 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 */
                              const char *port,          /* openvpn server port */
                              struct event_timeout *server_poll_timeout,
                              struct buffer *lookahead,
                              volatile int *signal_received)
{
    struct gc_arena gc = gc_new();
    char buf[512];
    char buf2[129];
    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;
        }

        if (!add_proxy_headers(p, sd, host, port))
        {
            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), get_server_poll_remaining_time(server_poll_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), get_server_poll_remaining_time(server_poll_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[128] = 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, */
            if (!add_proxy_headers(p, sd, host, port))
            {
                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), get_server_poll_remaining_time(server_poll_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 NTLM */
        }
#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);

                if ( !realm || !nonce )
                {
                    msg(D_LINK_ERRORS, "HTTP proxy: digest auth failed, malformed response "
                            "from server: realm= or nonce= missing" );
                    goto error;
                }

                /* 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, */
                if (!add_proxy_headers(p, sd, host, port))
                {
                    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), get_server_poll_remaining_time(server_poll_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 /* if PROXY_DIGEST_AUTH */
        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,
                                                      get_server_poll_remaining_time(server_poll_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");
                    free(pa);
                    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, get_server_poll_remaining_time(server_poll_timeout), signal_received);
#endif
        goto error;
    }

    /* SUCCESS */

    /* receive line from proxy and discard */
    if (!recv_line(sd, NULL, 0, get_server_poll_remaining_time(server_poll_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:
    if (!*signal_received)
    {
        *signal_received = SIGUSR1; /* SOFT-SIGUSR1 -- HTTP proxy error */
    }
    gc_free(&gc);
    return ret;
}
