/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <time.h>

#if defined(WEBRTC_WIN)
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#define SECURITY_WIN32
#include <security.h>
#endif

#include <algorithm>

#include "rtc_base/arraysize.h"
#include "rtc_base/checks.h"
#include "rtc_base/cryptstring.h"
#include "rtc_base/httpcommon-inl.h"
#include "rtc_base/httpcommon.h"
#include "rtc_base/messagedigest.h"
#include "rtc_base/socketaddress.h"
#include "rtc_base/third_party/base64/base64.h"
#include "rtc_base/zero_memory.h"

namespace rtc {
namespace {
#if defined(WEBRTC_WIN)
///////////////////////////////////////////////////////////////////////////////
// ConstantToLabel can be used to easily generate string names from constant
// values.  This can be useful for logging descriptive names of error messages.
// Usage:
//   const ConstantToLabel LIBRARY_ERRORS[] = {
//     KLABEL(SOME_ERROR),
//     KLABEL(SOME_OTHER_ERROR),
//     ...
//     LASTLABEL
//   }
//
//   int err = LibraryFunc();
//   LOG(LS_ERROR) << "LibraryFunc returned: "
//                 << GetErrorName(err, LIBRARY_ERRORS);
struct ConstantToLabel {
  int value;
  const char* label;
};

const char* LookupLabel(int value, const ConstantToLabel entries[]) {
  for (int i = 0; entries[i].label; ++i) {
    if (value == entries[i].value) {
      return entries[i].label;
    }
  }
  return 0;
}

std::string GetErrorName(int err, const ConstantToLabel* err_table) {
  if (err == 0)
    return "No error";

  if (err_table != 0) {
    if (const char* value = LookupLabel(err, err_table))
      return value;
  }

  char buffer[16];
  snprintf(buffer, sizeof(buffer), "0x%08x", err);
  return buffer;
}

#define KLABEL(x) \
  { x, #x }
#define LASTLABEL \
  { 0, 0 }

const ConstantToLabel SECURITY_ERRORS[] = {
    KLABEL(SEC_I_COMPLETE_AND_CONTINUE),
    KLABEL(SEC_I_COMPLETE_NEEDED),
    KLABEL(SEC_I_CONTEXT_EXPIRED),
    KLABEL(SEC_I_CONTINUE_NEEDED),
    KLABEL(SEC_I_INCOMPLETE_CREDENTIALS),
    KLABEL(SEC_I_RENEGOTIATE),
    KLABEL(SEC_E_CERT_EXPIRED),
    KLABEL(SEC_E_INCOMPLETE_MESSAGE),
    KLABEL(SEC_E_INSUFFICIENT_MEMORY),
    KLABEL(SEC_E_INTERNAL_ERROR),
    KLABEL(SEC_E_INVALID_HANDLE),
    KLABEL(SEC_E_INVALID_TOKEN),
    KLABEL(SEC_E_LOGON_DENIED),
    KLABEL(SEC_E_NO_AUTHENTICATING_AUTHORITY),
    KLABEL(SEC_E_NO_CREDENTIALS),
    KLABEL(SEC_E_NOT_OWNER),
    KLABEL(SEC_E_OK),
    KLABEL(SEC_E_SECPKG_NOT_FOUND),
    KLABEL(SEC_E_TARGET_UNKNOWN),
    KLABEL(SEC_E_UNKNOWN_CREDENTIALS),
    KLABEL(SEC_E_UNSUPPORTED_FUNCTION),
    KLABEL(SEC_E_UNTRUSTED_ROOT),
    KLABEL(SEC_E_WRONG_PRINCIPAL),
    LASTLABEL};
#undef KLABEL
#undef LASTLABEL
#endif  // defined(WEBRTC_WIN)
}  // namespace

//////////////////////////////////////////////////////////////////////
// Enum - TODO: expose globally later?
//////////////////////////////////////////////////////////////////////

bool find_string(size_t& index,
                 const std::string& needle,
                 const char* const haystack[],
                 size_t max_index) {
  for (index = 0; index < max_index; ++index) {
    if (_stricmp(needle.c_str(), haystack[index]) == 0) {
      return true;
    }
  }
  return false;
}

template <class E>
struct Enum {
  static const char** Names;
  static size_t Size;

  static inline const char* Name(E val) { return Names[val]; }
  static inline bool Parse(E& val, const std::string& name) {
    size_t index;
    if (!find_string(index, name, Names, Size))
      return false;
    val = static_cast<E>(index);
    return true;
  }

  E val;

  inline operator E&() { return val; }
  inline Enum& operator=(E rhs) {
    val = rhs;
    return *this;
  }

  inline const char* name() const { return Name(val); }
  inline bool assign(const std::string& name) { return Parse(val, name); }
  inline Enum& operator=(const std::string& rhs) {
    assign(rhs);
    return *this;
  }
};

#define ENUM(e, n)                 \
  template <>                      \
  const char** Enum<e>::Names = n; \
  template <>                      \
  size_t Enum<e>::Size = sizeof(n) / sizeof(n[0])

//////////////////////////////////////////////////////////////////////
// HttpCommon
//////////////////////////////////////////////////////////////////////

static const char* kHttpVersions[HVER_LAST + 1] = {"1.0", "1.1", "Unknown"};
ENUM(HttpVersion, kHttpVersions);

static const char* kHttpHeaders[HH_LAST + 1] = {
    "Age",
    "Cache-Control",
    "Connection",
    "Content-Disposition",
    "Content-Length",
    "Content-Range",
    "Content-Type",
    "Cookie",
    "Date",
    "ETag",
    "Expires",
    "Host",
    "If-Modified-Since",
    "If-None-Match",
    "Keep-Alive",
    "Last-Modified",
    "Location",
    "Proxy-Authenticate",
    "Proxy-Authorization",
    "Proxy-Connection",
    "Range",
    "Set-Cookie",
    "TE",
    "Trailers",
    "Transfer-Encoding",
    "Upgrade",
    "User-Agent",
    "WWW-Authenticate",
};
ENUM(HttpHeader, kHttpHeaders);

const char* ToString(HttpVersion version) {
  return Enum<HttpVersion>::Name(version);
}

bool FromString(HttpVersion& version, const std::string& str) {
  return Enum<HttpVersion>::Parse(version, str);
}

const char* ToString(HttpHeader header) {
  return Enum<HttpHeader>::Name(header);
}

bool FromString(HttpHeader& header, const std::string& str) {
  return Enum<HttpHeader>::Parse(header, str);
}

bool HttpHeaderIsEndToEnd(HttpHeader header) {
  switch (header) {
    case HH_CONNECTION:
    case HH_KEEP_ALIVE:
    case HH_PROXY_AUTHENTICATE:
    case HH_PROXY_AUTHORIZATION:
    case HH_PROXY_CONNECTION:  // Note part of RFC... this is non-standard
                               // header
    case HH_TE:
    case HH_TRAILERS:
    case HH_TRANSFER_ENCODING:
    case HH_UPGRADE:
      return false;
    default:
      return true;
  }
}

bool HttpHeaderIsCollapsible(HttpHeader header) {
  switch (header) {
    case HH_SET_COOKIE:
    case HH_PROXY_AUTHENTICATE:
    case HH_WWW_AUTHENTICATE:
      return false;
    default:
      return true;
  }
}

bool HttpShouldKeepAlive(const HttpData& data) {
  std::string connection;
  if ((data.hasHeader(HH_PROXY_CONNECTION, &connection) ||
       data.hasHeader(HH_CONNECTION, &connection))) {
    return (_stricmp(connection.c_str(), "Keep-Alive") == 0);
  }
  return (data.version >= HVER_1_1);
}

namespace {

inline bool IsEndOfAttributeName(size_t pos, size_t len, const char* data) {
  if (pos >= len)
    return true;
  if (isspace(static_cast<unsigned char>(data[pos])))
    return true;
  // The reason for this complexity is that some attributes may contain trailing
  // equal signs (like base64 tokens in Negotiate auth headers)
  if ((pos + 1 < len) && (data[pos] == '=') &&
      !isspace(static_cast<unsigned char>(data[pos + 1])) &&
      (data[pos + 1] != '=')) {
    return true;
  }
  return false;
}

}  // anonymous namespace

void HttpParseAttributes(const char* data,
                         size_t len,
                         HttpAttributeList& attributes) {
  size_t pos = 0;
  while (true) {
    // Skip leading whitespace
    while ((pos < len) && isspace(static_cast<unsigned char>(data[pos]))) {
      ++pos;
    }

    // End of attributes?
    if (pos >= len)
      return;

    // Find end of attribute name
    size_t start = pos;
    while (!IsEndOfAttributeName(pos, len, data)) {
      ++pos;
    }

    HttpAttribute attribute;
    attribute.first.assign(data + start, data + pos);

    // Attribute has value?
    if ((pos < len) && (data[pos] == '=')) {
      ++pos;  // Skip '='
      // Check if quoted value
      if ((pos < len) && (data[pos] == '"')) {
        while (++pos < len) {
          if (data[pos] == '"') {
            ++pos;
            break;
          }
          if ((data[pos] == '\\') && (pos + 1 < len))
            ++pos;
          attribute.second.append(1, data[pos]);
        }
      } else {
        while ((pos < len) && !isspace(static_cast<unsigned char>(data[pos])) &&
               (data[pos] != ',')) {
          attribute.second.append(1, data[pos++]);
        }
      }
    }

    attributes.push_back(attribute);
    if ((pos < len) && (data[pos] == ','))
      ++pos;  // Skip ','
  }
}

bool HttpHasAttribute(const HttpAttributeList& attributes,
                      const std::string& name,
                      std::string* value) {
  for (HttpAttributeList::const_iterator it = attributes.begin();
       it != attributes.end(); ++it) {
    if (it->first == name) {
      if (value) {
        *value = it->second;
      }
      return true;
    }
  }
  return false;
}

bool HttpHasNthAttribute(HttpAttributeList& attributes,
                         size_t index,
                         std::string* name,
                         std::string* value) {
  if (index >= attributes.size())
    return false;

  if (name)
    *name = attributes[index].first;
  if (value)
    *value = attributes[index].second;
  return true;
}

bool HttpDateToSeconds(const std::string& date, time_t* seconds) {
  const char* const kTimeZones[] = {
      "UT",  "GMT", "EST", "EDT", "CST", "CDT", "MST", "MDT", "PST",
      "PDT", "A",   "B",   "C",   "D",   "E",   "F",   "G",   "H",
      "I",   "K",   "L",   "M",   "N",   "O",   "P",   "Q",   "R",
      "S",   "T",   "U",   "V",   "W",   "X",   "Y"};
  const int kTimeZoneOffsets[] = {
      0,  0,  -5,  -4,  -6,  -5, -7, -6, -8, -7, -1, -2, -3, -4, -5, -6, -7,
      -8, -9, -10, -11, -12, 1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12};

  RTC_DCHECK(nullptr != seconds);
  struct tm tval;
  memset(&tval, 0, sizeof(tval));
  char month[4], zone[6];
  memset(month, 0, sizeof(month));
  memset(zone, 0, sizeof(zone));

  if (7 != sscanf(date.c_str(), "%*3s, %d %3s %d %d:%d:%d %5c", &tval.tm_mday,
                  month, &tval.tm_year, &tval.tm_hour, &tval.tm_min,
                  &tval.tm_sec, zone)) {
    return false;
  }
  switch (toupper(month[2])) {
    case 'N':
      tval.tm_mon = (month[1] == 'A') ? 0 : 5;
      break;
    case 'B':
      tval.tm_mon = 1;
      break;
    case 'R':
      tval.tm_mon = (month[0] == 'M') ? 2 : 3;
      break;
    case 'Y':
      tval.tm_mon = 4;
      break;
    case 'L':
      tval.tm_mon = 6;
      break;
    case 'G':
      tval.tm_mon = 7;
      break;
    case 'P':
      tval.tm_mon = 8;
      break;
    case 'T':
      tval.tm_mon = 9;
      break;
    case 'V':
      tval.tm_mon = 10;
      break;
    case 'C':
      tval.tm_mon = 11;
      break;
  }
  tval.tm_year -= 1900;
  time_t gmt, non_gmt = mktime(&tval);
  if ((zone[0] == '+') || (zone[0] == '-')) {
    if (!isdigit(zone[1]) || !isdigit(zone[2]) || !isdigit(zone[3]) ||
        !isdigit(zone[4])) {
      return false;
    }
    int hours = (zone[1] - '0') * 10 + (zone[2] - '0');
    int minutes = (zone[3] - '0') * 10 + (zone[4] - '0');
    int offset = (hours * 60 + minutes) * 60;
    gmt = non_gmt + ((zone[0] == '+') ? offset : -offset);
  } else {
    size_t zindex;
    if (!find_string(zindex, zone, kTimeZones, arraysize(kTimeZones))) {
      return false;
    }
    gmt = non_gmt + kTimeZoneOffsets[zindex] * 60 * 60;
  }
// TODO: Android should support timezone, see b/2441195
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID) || \
    defined(BSD)
  tm* tm_for_timezone = localtime(&gmt);
  *seconds = gmt + tm_for_timezone->tm_gmtoff;
#else
#if defined(_MSC_VER) && _MSC_VER >= 1900
  long timezone = 0;
  _get_timezone(&timezone);
#endif
  *seconds = gmt - timezone;
#endif
  return true;
}

std::string HttpAddress(const SocketAddress& address, bool secure) {
  return (address.port() == HttpDefaultPort(secure)) ? address.hostname()
                                                     : address.ToString();
}

//////////////////////////////////////////////////////////////////////
// HttpData
//////////////////////////////////////////////////////////////////////

HttpData::HttpData() : version(HVER_1_1) {}

HttpData::~HttpData() = default;

void HttpData::clear(bool release_document) {
  // Clear headers first, since releasing a document may have far-reaching
  // effects.
  headers_.clear();
  if (release_document) {
    document.reset();
  }
}

void HttpData::changeHeader(const std::string& name,
                            const std::string& value,
                            HeaderCombine combine) {
  if (combine == HC_AUTO) {
    HttpHeader header;
    // Unrecognized headers are collapsible
    combine = !FromString(header, name) || HttpHeaderIsCollapsible(header)
                  ? HC_YES
                  : HC_NO;
  } else if (combine == HC_REPLACE) {
    headers_.erase(name);
    combine = HC_NO;
  }
  // At this point, combine is one of (YES, NO, NEW)
  if (combine != HC_NO) {
    HeaderMap::iterator it = headers_.find(name);
    if (it != headers_.end()) {
      if (combine == HC_YES) {
        it->second.append(",");
        it->second.append(value);
      }
      return;
    }
  }
  headers_.insert(HeaderMap::value_type(name, value));
}

size_t HttpData::clearHeader(const std::string& name) {
  return headers_.erase(name);
}

HttpData::iterator HttpData::clearHeader(iterator header) {
  iterator deprecated = header++;
  headers_.erase(deprecated);
  return header;
}

bool HttpData::hasHeader(const std::string& name, std::string* value) const {
  HeaderMap::const_iterator it = headers_.find(name);
  if (it == headers_.end()) {
    return false;
  } else if (value) {
    *value = it->second;
  }
  return true;
}

void HttpData::setContent(const std::string& content_type,
                          StreamInterface* document) {
  setHeader(HH_CONTENT_TYPE, content_type);
  setDocumentAndLength(document);
}

void HttpData::setDocumentAndLength(StreamInterface* document) {
  // TODO: Consider calling Rewind() here?
  RTC_DCHECK(!hasHeader(HH_CONTENT_LENGTH, nullptr));
  RTC_DCHECK(!hasHeader(HH_TRANSFER_ENCODING, nullptr));
  RTC_DCHECK(document != nullptr);
  this->document.reset(document);
  size_t content_length = 0;
  if (this->document->GetAvailable(&content_length)) {
    char buffer[32];
    sprintfn(buffer, sizeof(buffer), "%d", content_length);
    setHeader(HH_CONTENT_LENGTH, buffer);
  } else {
    setHeader(HH_TRANSFER_ENCODING, "chunked");
  }
}

//
// HttpRequestData
//

void HttpRequestData::clear(bool release_document) {
  path.clear();
  HttpData::clear(release_document);
}

size_t HttpRequestData::formatLeader(char* buffer, size_t size) const {
  RTC_DCHECK(path.find(' ') == std::string::npos);
  return sprintfn(buffer, size, "GET %.*s HTTP/%s", path.size(), path.data(),
                  ToString(version));
}

HttpError HttpRequestData::parseLeader(const char* line, size_t len) {
  unsigned int vmajor, vminor;
  int vend, dstart, dend;
  // sscanf isn't safe with strings that aren't null-terminated, and there is
  // no guarantee that |line| is. Create a local copy that is null-terminated.
  std::string line_str(line, len);
  line = line_str.c_str();
  if ((sscanf(line, "%*s%n %n%*s%n HTTP/%u.%u", &vend, &dstart, &dend, &vmajor,
              &vminor) != 2) ||
      (vmajor != 1)) {
    return HE_PROTOCOL;
  }
  if (vminor == 0) {
    version = HVER_1_0;
  } else if (vminor == 1) {
    version = HVER_1_1;
  } else {
    return HE_PROTOCOL;
  }
  if (vend != 3 || memcmp(line, "GET", 3)) {
    return HE_PROTOCOL;  // !?! HC_METHOD_NOT_SUPPORTED?
  }
  path.assign(line + dstart, line + dend);
  return HE_NONE;
}

bool HttpRequestData::getAbsoluteUri(std::string* uri) const {
  Url<char> url(path);
  if (url.valid()) {
    uri->assign(path);
    return true;
  }
  std::string host;
  if (!hasHeader(HH_HOST, &host))
    return false;
  url.set_address(host);
  url.set_full_path(path);
  uri->assign(url.url());
  return url.valid();
}

bool HttpRequestData::getRelativeUri(std::string* host,
                                     std::string* path) const {
  Url<char> url(this->path);
  if (url.valid()) {
    host->assign(url.address());
    path->assign(url.full_path());
    return true;
  }
  if (!hasHeader(HH_HOST, host))
    return false;
  path->assign(this->path);
  return true;
}

//
// HttpResponseData
//

void HttpResponseData::clear(bool release_document) {
  scode = HC_INTERNAL_SERVER_ERROR;
  message.clear();
  HttpData::clear(release_document);
}

void HttpResponseData::set_success(uint32_t scode) {
  this->scode = scode;
  message.clear();
  setHeader(HH_CONTENT_LENGTH, "0", false);
}

void HttpResponseData::set_error(uint32_t scode) {
  this->scode = scode;
  message.clear();
  setHeader(HH_CONTENT_LENGTH, "0", false);
}

size_t HttpResponseData::formatLeader(char* buffer, size_t size) const {
  size_t len = sprintfn(buffer, size, "HTTP/%s %lu", ToString(version), scode);
  if (!message.empty()) {
    len += sprintfn(buffer + len, size - len, " %.*s", message.size(),
                    message.data());
  }
  return len;
}

HttpError HttpResponseData::parseLeader(const char* line, size_t len) {
  size_t pos = 0;
  unsigned int vmajor, vminor, temp_scode;
  int temp_pos;
  // sscanf isn't safe with strings that aren't null-terminated, and there is
  // no guarantee that |line| is. Create a local copy that is null-terminated.
  std::string line_str(line, len);
  line = line_str.c_str();
  if (sscanf(line, "HTTP %u%n", &temp_scode, &temp_pos) == 1) {
    // This server's response has no version. :( NOTE: This happens for every
    // response to requests made from Chrome plugins, regardless of the server's
    // behaviour.
    RTC_LOG(LS_VERBOSE) << "HTTP version missing from response";
    version = HVER_UNKNOWN;
  } else if ((sscanf(line, "HTTP/%u.%u %u%n", &vmajor, &vminor, &temp_scode,
                     &temp_pos) == 3) &&
             (vmajor == 1)) {
    // This server's response does have a version.
    if (vminor == 0) {
      version = HVER_1_0;
    } else if (vminor == 1) {
      version = HVER_1_1;
    } else {
      return HE_PROTOCOL;
    }
  } else {
    return HE_PROTOCOL;
  }
  scode = temp_scode;
  pos = static_cast<size_t>(temp_pos);
  while ((pos < len) && isspace(static_cast<unsigned char>(line[pos])))
    ++pos;
  message.assign(line + pos, len - pos);
  return HE_NONE;
}

//////////////////////////////////////////////////////////////////////
// Http Authentication
//////////////////////////////////////////////////////////////////////

std::string quote(const std::string& str) {
  std::string result;
  result.push_back('"');
  for (size_t i = 0; i < str.size(); ++i) {
    if ((str[i] == '"') || (str[i] == '\\'))
      result.push_back('\\');
    result.push_back(str[i]);
  }
  result.push_back('"');
  return result;
}

#if defined(WEBRTC_WIN)
struct NegotiateAuthContext : public HttpAuthContext {
  CredHandle cred;
  CtxtHandle ctx;
  size_t steps;
  bool specified_credentials;

  NegotiateAuthContext(const std::string& auth, CredHandle c1, CtxtHandle c2)
      : HttpAuthContext(auth),
        cred(c1),
        ctx(c2),
        steps(0),
        specified_credentials(false) {}

  ~NegotiateAuthContext() override {
    DeleteSecurityContext(&ctx);
    FreeCredentialsHandle(&cred);
  }
};
#endif  // WEBRTC_WIN

HttpAuthResult HttpAuthenticate(const char* challenge,
                                size_t len,
                                const SocketAddress& server,
                                const std::string& method,
                                const std::string& uri,
                                const std::string& username,
                                const CryptString& password,
                                HttpAuthContext*& context,
                                std::string& response,
                                std::string& auth_method) {
  HttpAttributeList args;
  HttpParseAttributes(challenge, len, args);
  HttpHasNthAttribute(args, 0, &auth_method, nullptr);

  if (context && (context->auth_method != auth_method))
    return HAR_IGNORE;

  // BASIC
  if (_stricmp(auth_method.c_str(), "basic") == 0) {
    if (context)
      return HAR_CREDENTIALS;  // Bad credentials
    if (username.empty())
      return HAR_CREDENTIALS;  // Missing credentials

    context = new HttpAuthContext(auth_method);

    // TODO(bugs.webrtc.org/8905): Convert sensitive to a CryptString and also
    // return response as CryptString so contents get securely deleted
    // automatically.
    // std::string decoded = username + ":" + password;
    size_t len = username.size() + password.GetLength() + 2;
    char* sensitive = new char[len];
    size_t pos = strcpyn(sensitive, len, username.data(), username.size());
    pos += strcpyn(sensitive + pos, len - pos, ":");
    password.CopyTo(sensitive + pos, true);

    response = auth_method;
    response.append(" ");
    // TODO: create a sensitive-source version of Base64::encode
    response.append(Base64::Encode(sensitive));
    ExplicitZeroMemory(sensitive, len);
    delete[] sensitive;
    return HAR_RESPONSE;
  }

  // DIGEST
  if (_stricmp(auth_method.c_str(), "digest") == 0) {
    if (context)
      return HAR_CREDENTIALS;  // Bad credentials
    if (username.empty())
      return HAR_CREDENTIALS;  // Missing credentials

    context = new HttpAuthContext(auth_method);

    std::string cnonce, ncount;
    char buffer[256];
    sprintf(buffer, "%d", static_cast<int>(time(0)));
    cnonce = MD5(buffer);
    ncount = "00000001";

    std::string realm, nonce, qop, opaque;
    HttpHasAttribute(args, "realm", &realm);
    HttpHasAttribute(args, "nonce", &nonce);
    bool has_qop = HttpHasAttribute(args, "qop", &qop);
    bool has_opaque = HttpHasAttribute(args, "opaque", &opaque);

    // TODO(bugs.webrtc.org/8905): Convert sensitive to a CryptString and also
    // return response as CryptString so contents get securely deleted
    // automatically.
    // std::string A1 = username + ":" + realm + ":" + password;
    size_t len = username.size() + realm.size() + password.GetLength() + 3;
    char* sensitive = new char[len];  // A1
    size_t pos = strcpyn(sensitive, len, username.data(), username.size());
    pos += strcpyn(sensitive + pos, len - pos, ":");
    pos += strcpyn(sensitive + pos, len - pos, realm.c_str());
    pos += strcpyn(sensitive + pos, len - pos, ":");
    password.CopyTo(sensitive + pos, true);

    std::string A2 = method + ":" + uri;
    std::string middle;
    if (has_qop) {
      qop = "auth";
      middle = nonce + ":" + ncount + ":" + cnonce + ":" + qop;
    } else {
      middle = nonce;
    }
    std::string HA1 = MD5(sensitive);
    ExplicitZeroMemory(sensitive, len);
    delete[] sensitive;
    std::string HA2 = MD5(A2);
    std::string dig_response = MD5(HA1 + ":" + middle + ":" + HA2);

    std::stringstream ss;
    ss << auth_method;
    ss << " username=" << quote(username);
    ss << ", realm=" << quote(realm);
    ss << ", nonce=" << quote(nonce);
    ss << ", uri=" << quote(uri);
    if (has_qop) {
      ss << ", qop=" << qop;
      ss << ", nc=" << ncount;
      ss << ", cnonce=" << quote(cnonce);
    }
    ss << ", response=\"" << dig_response << "\"";
    if (has_opaque) {
      ss << ", opaque=" << quote(opaque);
    }
    response = ss.str();
    return HAR_RESPONSE;
  }

#if defined(WEBRTC_WIN)
#if 1
  bool want_negotiate = (_stricmp(auth_method.c_str(), "negotiate") == 0);
  bool want_ntlm = (_stricmp(auth_method.c_str(), "ntlm") == 0);
  // SPNEGO & NTLM
  if (want_negotiate || want_ntlm) {
    const size_t MAX_MESSAGE = 12000, MAX_SPN = 256;
    char out_buf[MAX_MESSAGE], spn[MAX_SPN];

#if 0  // Requires funky windows versions
    DWORD len = MAX_SPN;
    if (DsMakeSpn("HTTP", server.HostAsURIString().c_str(), nullptr,
                  server.port(),
                  0, &len, spn) != ERROR_SUCCESS) {
      RTC_LOG_F(WARNING) << "(Negotiate) - DsMakeSpn failed";
      return HAR_IGNORE;
    }
#else
    sprintfn(spn, MAX_SPN, "HTTP/%s", server.ToString().c_str());
#endif

    SecBuffer out_sec;
    out_sec.pvBuffer = out_buf;
    out_sec.cbBuffer = sizeof(out_buf);
    out_sec.BufferType = SECBUFFER_TOKEN;

    SecBufferDesc out_buf_desc;
    out_buf_desc.ulVersion = 0;
    out_buf_desc.cBuffers = 1;
    out_buf_desc.pBuffers = &out_sec;

    const ULONG NEG_FLAGS_DEFAULT =
        // ISC_REQ_ALLOCATE_MEMORY
        ISC_REQ_CONFIDENTIALITY
        //| ISC_REQ_EXTENDED_ERROR
        //| ISC_REQ_INTEGRITY
        | ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT
        //| ISC_REQ_STREAM
        //| ISC_REQ_USE_SUPPLIED_CREDS
        ;

    ::TimeStamp lifetime;
    SECURITY_STATUS ret = S_OK;
    ULONG ret_flags = 0, flags = NEG_FLAGS_DEFAULT;

    bool specify_credentials = !username.empty();
    size_t steps = 0;

    // uint32_t now = Time();

    NegotiateAuthContext* neg = static_cast<NegotiateAuthContext*>(context);
    if (neg) {
      const size_t max_steps = 10;
      if (++neg->steps >= max_steps) {
        RTC_LOG(WARNING) << "AsyncHttpsProxySocket::Authenticate(Negotiate) "
                            "too many retries";
        return HAR_ERROR;
      }
      steps = neg->steps;

      std::string challenge, decoded_challenge;
      if (HttpHasNthAttribute(args, 1, &challenge, nullptr) &&
          Base64::Decode(challenge, Base64::DO_STRICT, &decoded_challenge,
                         nullptr)) {
        SecBuffer in_sec;
        in_sec.pvBuffer = const_cast<char*>(decoded_challenge.data());
        in_sec.cbBuffer = static_cast<unsigned long>(decoded_challenge.size());
        in_sec.BufferType = SECBUFFER_TOKEN;

        SecBufferDesc in_buf_desc;
        in_buf_desc.ulVersion = 0;
        in_buf_desc.cBuffers = 1;
        in_buf_desc.pBuffers = &in_sec;

        ret = InitializeSecurityContextA(
            &neg->cred, &neg->ctx, spn, flags, 0, SECURITY_NATIVE_DREP,
            &in_buf_desc, 0, &neg->ctx, &out_buf_desc, &ret_flags, &lifetime);
        if (FAILED(ret)) {
          RTC_LOG(LS_ERROR) << "InitializeSecurityContext returned: "
                            << GetErrorName(ret, SECURITY_ERRORS);
          return HAR_ERROR;
        }
      } else if (neg->specified_credentials) {
        // Try again with default credentials
        specify_credentials = false;
        delete context;
        context = neg = 0;
      } else {
        return HAR_CREDENTIALS;
      }
    }

    if (!neg) {
      unsigned char userbuf[256], passbuf[256], domainbuf[16];
      SEC_WINNT_AUTH_IDENTITY_A auth_id, *pauth_id = 0;
      if (specify_credentials) {
        memset(&auth_id, 0, sizeof(auth_id));
        size_t len = password.GetLength() + 1;
        char* sensitive = new char[len];
        password.CopyTo(sensitive, true);
        std::string::size_type pos = username.find('\\');
        if (pos == std::string::npos) {
          auth_id.UserLength = static_cast<unsigned long>(
              std::min(sizeof(userbuf) - 1, username.size()));
          memcpy(userbuf, username.c_str(), auth_id.UserLength);
          userbuf[auth_id.UserLength] = 0;
          auth_id.DomainLength = 0;
          domainbuf[auth_id.DomainLength] = 0;
          auth_id.PasswordLength = static_cast<unsigned long>(
              std::min(sizeof(passbuf) - 1, password.GetLength()));
          memcpy(passbuf, sensitive, auth_id.PasswordLength);
          passbuf[auth_id.PasswordLength] = 0;
        } else {
          auth_id.UserLength = static_cast<unsigned long>(
              std::min(sizeof(userbuf) - 1, username.size() - pos - 1));
          memcpy(userbuf, username.c_str() + pos + 1, auth_id.UserLength);
          userbuf[auth_id.UserLength] = 0;
          auth_id.DomainLength =
              static_cast<unsigned long>(std::min(sizeof(domainbuf) - 1, pos));
          memcpy(domainbuf, username.c_str(), auth_id.DomainLength);
          domainbuf[auth_id.DomainLength] = 0;
          auth_id.PasswordLength = static_cast<unsigned long>(
              std::min(sizeof(passbuf) - 1, password.GetLength()));
          memcpy(passbuf, sensitive, auth_id.PasswordLength);
          passbuf[auth_id.PasswordLength] = 0;
        }
        ExplicitZeroMemory(sensitive, len);
        delete[] sensitive;
        auth_id.User = userbuf;
        auth_id.Domain = domainbuf;
        auth_id.Password = passbuf;
        auth_id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
        pauth_id = &auth_id;
        RTC_LOG(LS_VERBOSE)
            << "Negotiate protocol: Using specified credentials";
      } else {
        RTC_LOG(LS_VERBOSE) << "Negotiate protocol: Using default credentials";
      }

      CredHandle cred;
      ret = AcquireCredentialsHandleA(
          0, const_cast<char*>(want_negotiate ? NEGOSSP_NAME_A : NTLMSP_NAME_A),
          SECPKG_CRED_OUTBOUND, 0, pauth_id, 0, 0, &cred, &lifetime);
      if (ret != SEC_E_OK) {
        RTC_LOG(LS_ERROR) << "AcquireCredentialsHandle error: "
                          << GetErrorName(ret, SECURITY_ERRORS);
        return HAR_IGNORE;
      }

      // CSecBufferBundle<5, CSecBufferBase::FreeSSPI> sb_out;

      CtxtHandle ctx;
      ret = InitializeSecurityContextA(&cred, 0, spn, flags, 0,
                                       SECURITY_NATIVE_DREP, 0, 0, &ctx,
                                       &out_buf_desc, &ret_flags, &lifetime);
      if (FAILED(ret)) {
        RTC_LOG(LS_ERROR) << "InitializeSecurityContext returned: "
                          << GetErrorName(ret, SECURITY_ERRORS);
        FreeCredentialsHandle(&cred);
        return HAR_IGNORE;
      }

      RTC_DCHECK(!context);
      context = neg = new NegotiateAuthContext(auth_method, cred, ctx);
      neg->specified_credentials = specify_credentials;
      neg->steps = steps;
    }

    if ((ret == SEC_I_COMPLETE_NEEDED) ||
        (ret == SEC_I_COMPLETE_AND_CONTINUE)) {
      ret = CompleteAuthToken(&neg->ctx, &out_buf_desc);
      RTC_LOG(LS_VERBOSE) << "CompleteAuthToken returned: "
                          << GetErrorName(ret, SECURITY_ERRORS);
      if (FAILED(ret)) {
        return HAR_ERROR;
      }
    }

    std::string decoded(out_buf, out_buf + out_sec.cbBuffer);
    response = auth_method;
    response.append(" ");
    response.append(Base64::Encode(decoded));
    return HAR_RESPONSE;
  }
#endif
#endif  // WEBRTC_WIN

  return HAR_IGNORE;
}

//////////////////////////////////////////////////////////////////////

}  // namespace rtc
