// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_auth_gssapi_posix.h"

#include <limits>
#include <string>

#include "base/base64.h"
#include "base/files/file_path.h"
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/http/http_auth_challenge_tokenizer.h"

// These are defined for the GSSAPI library:
// Paraphrasing the comments from gssapi.h:
// "The implementation must reserve static storage for a
// gss_OID_desc object for each constant.  That constant
// should be initialized to point to that gss_OID_desc."
// These are encoded using ASN.1 BER encoding.
namespace {

static gss_OID_desc GSS_C_NT_USER_NAME_VAL = {
  10,
  const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x01")
};
static gss_OID_desc GSS_C_NT_MACHINE_UID_NAME_VAL = {
  10,
  const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x02")
};
static gss_OID_desc GSS_C_NT_STRING_UID_NAME_VAL = {
  10,
  const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x03")
};
static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_X_VAL = {
  6,
  const_cast<char*>("\x2b\x06\x01\x05\x06\x02")
};
static gss_OID_desc GSS_C_NT_HOSTBASED_SERVICE_VAL = {
  10,
  const_cast<char*>("\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")
};
static gss_OID_desc GSS_C_NT_ANONYMOUS_VAL = {
  6,
  const_cast<char*>("\x2b\x06\01\x05\x06\x03")
};
static gss_OID_desc GSS_C_NT_EXPORT_NAME_VAL = {
  6,
  const_cast<char*>("\x2b\x06\x01\x05\x06\x04")
};

}  // namespace

// Heimdal >= 1.4 will define the following as preprocessor macros.
// To avoid conflicting declarations, we have to undefine these.
#undef GSS_C_NT_USER_NAME
#undef GSS_C_NT_MACHINE_UID_NAME
#undef GSS_C_NT_STRING_UID_NAME
#undef GSS_C_NT_HOSTBASED_SERVICE_X
#undef GSS_C_NT_HOSTBASED_SERVICE
#undef GSS_C_NT_ANONYMOUS
#undef GSS_C_NT_EXPORT_NAME

gss_OID GSS_C_NT_USER_NAME = &GSS_C_NT_USER_NAME_VAL;
gss_OID GSS_C_NT_MACHINE_UID_NAME = &GSS_C_NT_MACHINE_UID_NAME_VAL;
gss_OID GSS_C_NT_STRING_UID_NAME = &GSS_C_NT_STRING_UID_NAME_VAL;
gss_OID GSS_C_NT_HOSTBASED_SERVICE_X = &GSS_C_NT_HOSTBASED_SERVICE_X_VAL;
gss_OID GSS_C_NT_HOSTBASED_SERVICE = &GSS_C_NT_HOSTBASED_SERVICE_VAL;
gss_OID GSS_C_NT_ANONYMOUS = &GSS_C_NT_ANONYMOUS_VAL;
gss_OID GSS_C_NT_EXPORT_NAME = &GSS_C_NT_EXPORT_NAME_VAL;

namespace net {

// Exported mechanism for GSSAPI. We always use SPNEGO:

// iso.org.dod.internet.security.mechanism.snego (1.3.6.1.5.5.2)
gss_OID_desc CHROME_GSS_SPNEGO_MECH_OID_DESC_VAL = {
  6,
  const_cast<char*>("\x2b\x06\x01\x05\x05\x02")
};

gss_OID CHROME_GSS_SPNEGO_MECH_OID_DESC =
    &CHROME_GSS_SPNEGO_MECH_OID_DESC_VAL;

// Debugging helpers.
namespace {

std::string DisplayStatus(OM_uint32 major_status,
                          OM_uint32 minor_status) {
  if (major_status == GSS_S_COMPLETE)
    return "OK";
  return base::StringPrintf("0x%08X 0x%08X", major_status, minor_status);
}

std::string DisplayCode(GSSAPILibrary* gssapi_lib,
                        OM_uint32 status,
                        OM_uint32 status_code_type) {
  const int kMaxDisplayIterations = 8;
  const size_t kMaxMsgLength = 4096;
  // msg_ctx needs to be outside the loop because it is invoked multiple times.
  OM_uint32 msg_ctx = 0;
  std::string rv = base::StringPrintf("(0x%08X)", status);

  // This loop should continue iterating until msg_ctx is 0 after the first
  // iteration. To be cautious and prevent an infinite loop, it stops after
  // a finite number of iterations as well. As an added sanity check, no
  // individual message may exceed |kMaxMsgLength|, and the final result
  // will not exceed |kMaxMsgLength|*2-1.
  for (int i = 0; i < kMaxDisplayIterations && rv.size() < kMaxMsgLength;
       ++i) {
    OM_uint32 min_stat;
    gss_buffer_desc_struct msg = GSS_C_EMPTY_BUFFER;
    OM_uint32 maj_stat =
        gssapi_lib->display_status(&min_stat, status, status_code_type,
                                   GSS_C_NULL_OID, &msg_ctx, &msg);
    if (maj_stat == GSS_S_COMPLETE) {
      int msg_len = (msg.length > kMaxMsgLength) ?
          static_cast<int>(kMaxMsgLength) :
          static_cast<int>(msg.length);
      if (msg_len > 0 && msg.value != NULL) {
        rv += base::StringPrintf(" %.*s", msg_len,
                                 static_cast<char*>(msg.value));
      }
    }
    gssapi_lib->release_buffer(&min_stat, &msg);
    if (!msg_ctx)
      break;
  }
  return rv;
}

std::string DisplayExtendedStatus(GSSAPILibrary* gssapi_lib,
                                  OM_uint32 major_status,
                                  OM_uint32 minor_status) {
  if (major_status == GSS_S_COMPLETE)
    return "OK";
  std::string major = DisplayCode(gssapi_lib, major_status, GSS_C_GSS_CODE);
  std::string minor = DisplayCode(gssapi_lib, minor_status, GSS_C_MECH_CODE);
  return base::StringPrintf("Major: %s | Minor: %s", major.c_str(),
                            minor.c_str());
}

// ScopedName releases a gss_name_t when it goes out of scope.
class ScopedName {
 public:
  ScopedName(gss_name_t name,
             GSSAPILibrary* gssapi_lib)
      : name_(name),
        gssapi_lib_(gssapi_lib) {
    DCHECK(gssapi_lib_);
  }

  ~ScopedName() {
    if (name_ != GSS_C_NO_NAME) {
      OM_uint32 minor_status = 0;
      OM_uint32 major_status =
          gssapi_lib_->release_name(&minor_status, &name_);
      if (major_status != GSS_S_COMPLETE) {
        LOG(WARNING) << "Problem releasing name. "
                     << DisplayStatus(major_status, minor_status);
      }
      name_ = GSS_C_NO_NAME;
    }
  }

 private:
  gss_name_t name_;
  GSSAPILibrary* gssapi_lib_;

  DISALLOW_COPY_AND_ASSIGN(ScopedName);
};

// ScopedBuffer releases a gss_buffer_t when it goes out of scope.
class ScopedBuffer {
 public:
  ScopedBuffer(gss_buffer_t buffer,
               GSSAPILibrary* gssapi_lib)
      : buffer_(buffer),
        gssapi_lib_(gssapi_lib) {
    DCHECK(gssapi_lib_);
  }

  ~ScopedBuffer() {
    if (buffer_ != GSS_C_NO_BUFFER) {
      OM_uint32 minor_status = 0;
      OM_uint32 major_status =
          gssapi_lib_->release_buffer(&minor_status, buffer_);
      if (major_status != GSS_S_COMPLETE) {
        LOG(WARNING) << "Problem releasing buffer. "
                     << DisplayStatus(major_status, minor_status);
      }
      buffer_ = GSS_C_NO_BUFFER;
    }
  }

 private:
  gss_buffer_t buffer_;
  GSSAPILibrary* gssapi_lib_;

  DISALLOW_COPY_AND_ASSIGN(ScopedBuffer);
};

namespace {

std::string AppendIfPredefinedValue(gss_OID oid,
                                    gss_OID predefined_oid,
                                    const char* predefined_oid_name) {
  DCHECK(oid);
  DCHECK(predefined_oid);
  DCHECK(predefined_oid_name);
  std::string output;
  if (oid->length != predefined_oid->length)
    return output;
  if (0 != memcmp(oid->elements,
                  predefined_oid->elements,
                  predefined_oid->length))
    return output;

  output += " (";
  output += predefined_oid_name;
  output += ")";
  return output;
}

}  // namespace

std::string DescribeOid(GSSAPILibrary* gssapi_lib, const gss_OID oid) {
  if (!oid)
    return "<NULL>";
  std::string output;
  const size_t kMaxCharsToPrint = 1024;
  OM_uint32 byte_length = oid->length;
  size_t char_length = byte_length / sizeof(char);
  if (char_length > kMaxCharsToPrint) {
    // This might be a plain ASCII string.
    // Check if the first |kMaxCharsToPrint| characters
    // contain only printable characters and are NULL terminated.
    const char* str = reinterpret_cast<const char*>(oid);
    size_t str_length = 0;
    for ( ; str_length < kMaxCharsToPrint; ++str_length) {
      if (!str[str_length] || !isprint(str[str_length]))
        break;
    }
    if (!str[str_length]) {
      output += base::StringPrintf("\"%s\"", str);
      return output;
    }
  }
  output = base::StringPrintf("(%u) \"", byte_length);
  if (!oid->elements) {
    output += "<NULL>";
    return output;
  }
  const unsigned char* elements =
      reinterpret_cast<const unsigned char*>(oid->elements);
  // Don't print more than |kMaxCharsToPrint| characters.
  size_t i = 0;
  for ( ; (i < byte_length) && (i < kMaxCharsToPrint); ++i) {
    output += base::StringPrintf("\\x%02X", elements[i]);
  }
  if (i >= kMaxCharsToPrint)
    output += "...";
  output += "\"";

  // Check if the OID is one of the predefined values.
  output += AppendIfPredefinedValue(oid,
                                    GSS_C_NT_USER_NAME,
                                    "GSS_C_NT_USER_NAME");
  output += AppendIfPredefinedValue(oid,
                                    GSS_C_NT_MACHINE_UID_NAME,
                                    "GSS_C_NT_MACHINE_UID_NAME");
  output += AppendIfPredefinedValue(oid,
                                    GSS_C_NT_STRING_UID_NAME,
                                    "GSS_C_NT_STRING_UID_NAME");
  output += AppendIfPredefinedValue(oid,
                                    GSS_C_NT_HOSTBASED_SERVICE_X,
                                    "GSS_C_NT_HOSTBASED_SERVICE_X");
  output += AppendIfPredefinedValue(oid,
                                    GSS_C_NT_HOSTBASED_SERVICE,
                                    "GSS_C_NT_HOSTBASED_SERVICE");
  output += AppendIfPredefinedValue(oid,
                                    GSS_C_NT_ANONYMOUS,
                                    "GSS_C_NT_ANONYMOUS");
  output += AppendIfPredefinedValue(oid,
                                    GSS_C_NT_EXPORT_NAME,
                                    "GSS_C_NT_EXPORT_NAME");

  return output;
}

std::string DescribeName(GSSAPILibrary* gssapi_lib, const gss_name_t name) {
  OM_uint32 major_status = 0;
  OM_uint32 minor_status = 0;
  gss_buffer_desc_struct output_name_buffer = GSS_C_EMPTY_BUFFER;
  gss_OID_desc output_name_type_desc = GSS_C_EMPTY_BUFFER;
  gss_OID output_name_type = &output_name_type_desc;
  major_status = gssapi_lib->display_name(&minor_status,
                                          name,
                                          &output_name_buffer,
                                          &output_name_type);
  ScopedBuffer scoped_output_name(&output_name_buffer, gssapi_lib);
  if (major_status != GSS_S_COMPLETE) {
    std::string error =
        base::StringPrintf("Unable to describe name 0x%p, %s",
                           name,
                           DisplayExtendedStatus(gssapi_lib,
                                                 major_status,
                                                 minor_status).c_str());
    return error;
  }
  int len = output_name_buffer.length;
  std::string description = base::StringPrintf(
      "%*s (Type %s)",
      len,
      reinterpret_cast<const char*>(output_name_buffer.value),
      DescribeOid(gssapi_lib, output_name_type).c_str());
  return description;
}

std::string DescribeContext(GSSAPILibrary* gssapi_lib,
                            const gss_ctx_id_t context_handle) {
  OM_uint32 major_status = 0;
  OM_uint32 minor_status = 0;
  gss_name_t src_name = GSS_C_NO_NAME;
  gss_name_t targ_name = GSS_C_NO_NAME;
  OM_uint32 lifetime_rec = 0;
  gss_OID mech_type = GSS_C_NO_OID;
  OM_uint32 ctx_flags = 0;
  int locally_initiated = 0;
  int open = 0;
  if (context_handle == GSS_C_NO_CONTEXT)
    return std::string("Context: GSS_C_NO_CONTEXT");
  major_status = gssapi_lib->inquire_context(&minor_status,
                                             context_handle,
                                             &src_name,
                                             &targ_name,
                                             &lifetime_rec,
                                             &mech_type,
                                             &ctx_flags,
                                             &locally_initiated,
                                             &open);
  ScopedName(src_name, gssapi_lib);
  ScopedName(targ_name, gssapi_lib);
  if (major_status != GSS_S_COMPLETE) {
    std::string error =
        base::StringPrintf("Unable to describe context 0x%p, %s",
                           context_handle,
                           DisplayExtendedStatus(gssapi_lib,
                                                 major_status,
                                                 minor_status).c_str());
    return error;
  }
  std::string source(DescribeName(gssapi_lib, src_name));
  std::string target(DescribeName(gssapi_lib, targ_name));
  std::string description = base::StringPrintf("Context 0x%p: "
                                               "Source \"%s\", "
                                               "Target \"%s\", "
                                                "lifetime %d, "
                                                "mechanism %s, "
                                                "flags 0x%08X, "
                                                "local %d, "
                                                "open %d",
                                                context_handle,
                                                source.c_str(),
                                                target.c_str(),
                                                lifetime_rec,
                                                DescribeOid(gssapi_lib,
                                                            mech_type).c_str(),
                                                ctx_flags,
                                                locally_initiated,
                                                open);
  return description;
}

}  // namespace

GSSAPISharedLibrary::GSSAPISharedLibrary(const std::string& gssapi_library_name)
    : initialized_(false),
      gssapi_library_name_(gssapi_library_name),
      gssapi_library_(NULL),
      import_name_(NULL),
      release_name_(NULL),
      release_buffer_(NULL),
      display_name_(NULL),
      display_status_(NULL),
      init_sec_context_(NULL),
      wrap_size_limit_(NULL),
      delete_sec_context_(NULL),
      inquire_context_(NULL) {
}

GSSAPISharedLibrary::~GSSAPISharedLibrary() {
  if (gssapi_library_) {
    base::UnloadNativeLibrary(gssapi_library_);
    gssapi_library_ = NULL;
  }
}

bool GSSAPISharedLibrary::Init() {
  if (!initialized_)
    InitImpl();
  return initialized_;
}

bool GSSAPISharedLibrary::InitImpl() {
  DCHECK(!initialized_);
#if defined(DLOPEN_KERBEROS)
  gssapi_library_ = LoadSharedLibrary();
  if (gssapi_library_ == NULL)
    return false;
#endif  // defined(DLOPEN_KERBEROS)
  initialized_ = true;
  return true;
}

base::NativeLibrary GSSAPISharedLibrary::LoadSharedLibrary() {
  const char* const* library_names;
  size_t num_lib_names;
  const char* user_specified_library[1];
  if (!gssapi_library_name_.empty()) {
    user_specified_library[0] = gssapi_library_name_.c_str();
    library_names = user_specified_library;
    num_lib_names = 1;
  } else {
    static const char* const kDefaultLibraryNames[] = {
#if defined(OS_MACOSX)
      "libgssapi_krb5.dylib"  // MIT Kerberos
#elif defined(OS_OPENBSD)
      "libgssapi.so"          // Heimdal - OpenBSD
#else
      "libgssapi_krb5.so.2",  // MIT Kerberos - FC, Suse10, Debian
      "libgssapi.so.4",       // Heimdal - Suse10, MDK
      "libgssapi.so.2",       // Heimdal - Gentoo
      "libgssapi.so.1"        // Heimdal - Suse9, CITI - FC, MDK, Suse10
#endif
    };
    library_names = kDefaultLibraryNames;
    num_lib_names = arraysize(kDefaultLibraryNames);
  }

  for (size_t i = 0; i < num_lib_names; ++i) {
    const char* library_name = library_names[i];
    base::FilePath file_path(library_name);

    // TODO(asanka): Move library loading to a separate thread.
    //               http://crbug.com/66702
    base::ThreadRestrictions::ScopedAllowIO allow_io_temporarily;
    base::NativeLibrary lib = base::LoadNativeLibrary(file_path, NULL);
    if (lib) {
      // Only return this library if we can bind the functions we need.
      if (BindMethods(lib))
        return lib;
      base::UnloadNativeLibrary(lib);
    }
  }
  LOG(WARNING) << "Unable to find a compatible GSSAPI library";
  return NULL;
}

#if defined(DLOPEN_KERBEROS)
#define BIND(lib, x)                                                    \
  DCHECK(lib);                                                          \
  gss_##x##_type x = reinterpret_cast<gss_##x##_type>(                  \
      base::GetFunctionPointerFromNativeLibrary(lib, "gss_" #x));       \
  if (x == NULL) {                                                      \
    LOG(WARNING) << "Unable to bind function \"" << "gss_" #x << "\"";  \
    return false;                                                       \
  }
#else
#define BIND(lib, x) gss_##x##_type x = gss_##x
#endif

bool GSSAPISharedLibrary::BindMethods(base::NativeLibrary lib) {
  BIND(lib, import_name);
  BIND(lib, release_name);
  BIND(lib, release_buffer);
  BIND(lib, display_name);
  BIND(lib, display_status);
  BIND(lib, init_sec_context);
  BIND(lib, wrap_size_limit);
  BIND(lib, delete_sec_context);
  BIND(lib, inquire_context);

  import_name_ = import_name;
  release_name_ = release_name;
  release_buffer_ = release_buffer;
  display_name_ = display_name;
  display_status_ = display_status;
  init_sec_context_ = init_sec_context;
  wrap_size_limit_ = wrap_size_limit;
  delete_sec_context_ = delete_sec_context;
  inquire_context_ = inquire_context;

  return true;
}

#undef BIND

OM_uint32 GSSAPISharedLibrary::import_name(
    OM_uint32* minor_status,
    const gss_buffer_t input_name_buffer,
    const gss_OID input_name_type,
    gss_name_t* output_name) {
  DCHECK(initialized_);
  return import_name_(minor_status, input_name_buffer, input_name_type,
                      output_name);
}

OM_uint32 GSSAPISharedLibrary::release_name(
    OM_uint32* minor_status,
    gss_name_t* input_name) {
  DCHECK(initialized_);
  return release_name_(minor_status, input_name);
}

OM_uint32 GSSAPISharedLibrary::release_buffer(
    OM_uint32* minor_status,
    gss_buffer_t buffer) {
  DCHECK(initialized_);
  return release_buffer_(minor_status, buffer);
}

OM_uint32 GSSAPISharedLibrary::display_name(
    OM_uint32* minor_status,
    const gss_name_t input_name,
    gss_buffer_t output_name_buffer,
    gss_OID* output_name_type) {
  DCHECK(initialized_);
  return display_name_(minor_status,
                       input_name,
                       output_name_buffer,
                       output_name_type);
}

OM_uint32 GSSAPISharedLibrary::display_status(
    OM_uint32* minor_status,
    OM_uint32 status_value,
    int status_type,
    const gss_OID mech_type,
    OM_uint32* message_context,
    gss_buffer_t status_string) {
  DCHECK(initialized_);
  return display_status_(minor_status, status_value, status_type, mech_type,
                         message_context, status_string);
}

OM_uint32 GSSAPISharedLibrary::init_sec_context(
    OM_uint32* minor_status,
    const gss_cred_id_t initiator_cred_handle,
    gss_ctx_id_t* context_handle,
    const gss_name_t target_name,
    const gss_OID mech_type,
    OM_uint32 req_flags,
    OM_uint32 time_req,
    const gss_channel_bindings_t input_chan_bindings,
    const gss_buffer_t input_token,
    gss_OID* actual_mech_type,
    gss_buffer_t output_token,
    OM_uint32* ret_flags,
    OM_uint32* time_rec) {
  DCHECK(initialized_);
  return init_sec_context_(minor_status,
                           initiator_cred_handle,
                           context_handle,
                           target_name,
                           mech_type,
                           req_flags,
                           time_req,
                           input_chan_bindings,
                           input_token,
                           actual_mech_type,
                           output_token,
                           ret_flags,
                           time_rec);
}

OM_uint32 GSSAPISharedLibrary::wrap_size_limit(
    OM_uint32* minor_status,
    const gss_ctx_id_t context_handle,
    int conf_req_flag,
    gss_qop_t qop_req,
    OM_uint32 req_output_size,
    OM_uint32* max_input_size) {
  DCHECK(initialized_);
  return wrap_size_limit_(minor_status,
                          context_handle,
                          conf_req_flag,
                          qop_req,
                          req_output_size,
                          max_input_size);
}

OM_uint32 GSSAPISharedLibrary::delete_sec_context(
    OM_uint32* minor_status,
    gss_ctx_id_t* context_handle,
    gss_buffer_t output_token) {
  // This is called from the owner class' destructor, even if
  // Init() is not called, so we can't assume |initialized_|
  // is set.
  if (!initialized_)
    return 0;
  return delete_sec_context_(minor_status,
                             context_handle,
                             output_token);
}

OM_uint32 GSSAPISharedLibrary::inquire_context(
    OM_uint32* minor_status,
    const gss_ctx_id_t context_handle,
    gss_name_t* src_name,
    gss_name_t* targ_name,
    OM_uint32* lifetime_rec,
    gss_OID* mech_type,
    OM_uint32* ctx_flags,
    int* locally_initiated,
    int* open) {
  DCHECK(initialized_);
  return inquire_context_(minor_status,
                          context_handle,
                          src_name,
                          targ_name,
                          lifetime_rec,
                          mech_type,
                          ctx_flags,
                          locally_initiated,
                          open);
}

ScopedSecurityContext::ScopedSecurityContext(GSSAPILibrary* gssapi_lib)
    : security_context_(GSS_C_NO_CONTEXT),
      gssapi_lib_(gssapi_lib) {
  DCHECK(gssapi_lib_);
}

ScopedSecurityContext::~ScopedSecurityContext() {
  if (security_context_ != GSS_C_NO_CONTEXT) {
    gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
    OM_uint32 minor_status = 0;
    OM_uint32 major_status = gssapi_lib_->delete_sec_context(
        &minor_status, &security_context_, &output_token);
    if (major_status != GSS_S_COMPLETE) {
      LOG(WARNING) << "Problem releasing security_context. "
                   << DisplayStatus(major_status, minor_status);
    }
    security_context_ = GSS_C_NO_CONTEXT;
  }
}

HttpAuthGSSAPI::HttpAuthGSSAPI(GSSAPILibrary* library,
                               const std::string& scheme,
                               gss_OID gss_oid)
    : scheme_(scheme),
      gss_oid_(gss_oid),
      library_(library),
      scoped_sec_context_(library),
      can_delegate_(false) {
  DCHECK(library_);
}

HttpAuthGSSAPI::~HttpAuthGSSAPI() {
}

bool HttpAuthGSSAPI::Init() {
  if (!library_)
    return false;
  return library_->Init();
}

bool HttpAuthGSSAPI::NeedsIdentity() const {
  return decoded_server_auth_token_.empty();
}

bool HttpAuthGSSAPI::AllowsExplicitCredentials() const {
  return false;
}

void HttpAuthGSSAPI::Delegate() {
  can_delegate_ = true;
}

HttpAuth::AuthorizationResult HttpAuthGSSAPI::ParseChallenge(
    HttpAuthChallengeTokenizer* tok) {
  // Verify the challenge's auth-scheme.
  if (!LowerCaseEqualsASCII(tok->scheme(), StringToLowerASCII(scheme_).c_str()))
    return HttpAuth::AUTHORIZATION_RESULT_INVALID;

  std::string encoded_auth_token = tok->base64_param();

  if (encoded_auth_token.empty()) {
    // If a context has already been established, an empty Negotiate challenge
    // should be treated as a rejection of the current attempt.
    if (scoped_sec_context_.get() != GSS_C_NO_CONTEXT)
      return HttpAuth::AUTHORIZATION_RESULT_REJECT;
    DCHECK(decoded_server_auth_token_.empty());
    return HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
  } else {
    // If a context has not already been established, additional tokens should
    // not be present in the auth challenge.
    if (scoped_sec_context_.get() == GSS_C_NO_CONTEXT)
      return HttpAuth::AUTHORIZATION_RESULT_INVALID;
  }

  // Make sure the additional token is base64 encoded.
  std::string decoded_auth_token;
  bool base64_rv = base::Base64Decode(encoded_auth_token, &decoded_auth_token);
  if (!base64_rv)
    return HttpAuth::AUTHORIZATION_RESULT_INVALID;
  decoded_server_auth_token_ = decoded_auth_token;
  return HttpAuth::AUTHORIZATION_RESULT_ACCEPT;
}

int HttpAuthGSSAPI::GenerateAuthToken(const AuthCredentials* credentials,
                                      const std::string& spn,
                                      std::string* auth_token) {
  DCHECK(auth_token);

  gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
  input_token.length = decoded_server_auth_token_.length();
  input_token.value = (input_token.length > 0) ?
      const_cast<char*>(decoded_server_auth_token_.data()) :
      NULL;
  gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
  ScopedBuffer scoped_output_token(&output_token, library_);
  int rv = GetNextSecurityToken(spn, &input_token, &output_token);
  if (rv != OK)
    return rv;

  // Base64 encode data in output buffer and prepend the scheme.
  std::string encode_input(static_cast<char*>(output_token.value),
                           output_token.length);
  std::string encode_output;
  base::Base64Encode(encode_input, &encode_output);
  *auth_token = scheme_ + " " + encode_output;
  return OK;
}


namespace {

// GSSAPI status codes consist of a calling error (essentially, a programmer
// bug), a routine error (defined by the RFC), and supplementary information,
// all bitwise-or'ed together in different regions of the 32 bit return value.
// This means a simple switch on the return codes is not sufficient.

int MapImportNameStatusToError(OM_uint32 major_status) {
  VLOG(1) << "import_name returned 0x" << std::hex << major_status;
  if (major_status == GSS_S_COMPLETE)
    return OK;
  if (GSS_CALLING_ERROR(major_status) != 0)
    return ERR_UNEXPECTED;
  OM_uint32 routine_error = GSS_ROUTINE_ERROR(major_status);
  switch (routine_error) {
    case GSS_S_FAILURE:
      // Looking at the MIT Kerberos implementation, this typically is returned
      // when memory allocation fails. However, the API does not guarantee
      // that this is the case, so using ERR_UNEXPECTED rather than
      // ERR_OUT_OF_MEMORY.
      return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS;
    case GSS_S_BAD_NAME:
    case GSS_S_BAD_NAMETYPE:
      return ERR_MALFORMED_IDENTITY;
    case GSS_S_DEFECTIVE_TOKEN:
      // Not mentioned in the API, but part of code.
      return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS;
    case GSS_S_BAD_MECH:
      return ERR_UNSUPPORTED_AUTH_SCHEME;
    default:
      return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS;
  }
}

int MapInitSecContextStatusToError(OM_uint32 major_status) {
  VLOG(1) << "init_sec_context returned 0x" << std::hex << major_status;
  // Although GSS_S_CONTINUE_NEEDED is an additional bit, it seems like
  // other code just checks if major_status is equivalent to it to indicate
  // that there are no other errors included.
  if (major_status == GSS_S_COMPLETE || major_status == GSS_S_CONTINUE_NEEDED)
    return OK;
  if (GSS_CALLING_ERROR(major_status) != 0)
    return ERR_UNEXPECTED;
  OM_uint32 routine_status = GSS_ROUTINE_ERROR(major_status);
  switch (routine_status) {
    case GSS_S_DEFECTIVE_TOKEN:
      return ERR_INVALID_RESPONSE;
    case GSS_S_DEFECTIVE_CREDENTIAL:
      // Not expected since this implementation uses the default credential.
      return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS;
    case GSS_S_BAD_SIG:
      // Probably won't happen, but it's a bad response.
      return ERR_INVALID_RESPONSE;
    case GSS_S_NO_CRED:
      return ERR_INVALID_AUTH_CREDENTIALS;
    case GSS_S_CREDENTIALS_EXPIRED:
      return ERR_INVALID_AUTH_CREDENTIALS;
    case GSS_S_BAD_BINDINGS:
      // This only happens with mutual authentication.
      return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS;
    case GSS_S_NO_CONTEXT:
      return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS;
    case GSS_S_BAD_NAMETYPE:
      return ERR_UNSUPPORTED_AUTH_SCHEME;
    case GSS_S_BAD_NAME:
      return ERR_UNSUPPORTED_AUTH_SCHEME;
    case GSS_S_BAD_MECH:
      return ERR_UNEXPECTED_SECURITY_LIBRARY_STATUS;
    case GSS_S_FAILURE:
      // This should be an "Unexpected Security Status" according to the
      // GSSAPI documentation, but it's typically used to indicate that
      // credentials are not correctly set up on a user machine, such
      // as a missing credential cache or hitting this after calling
      // kdestroy.
      // TODO(cbentzel): Use minor code for even better mapping?
      return ERR_MISSING_AUTH_CREDENTIALS;
    default:
      if (routine_status != 0)
        return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS;
      break;
  }
  OM_uint32 supplemental_status = GSS_SUPPLEMENTARY_INFO(major_status);
  // Replays could indicate an attack.
  if (supplemental_status & (GSS_S_DUPLICATE_TOKEN | GSS_S_OLD_TOKEN |
                             GSS_S_UNSEQ_TOKEN | GSS_S_GAP_TOKEN))
    return ERR_INVALID_RESPONSE;

  // At this point, every documented status has been checked.
  return ERR_UNDOCUMENTED_SECURITY_LIBRARY_STATUS;
}

}

int HttpAuthGSSAPI::GetNextSecurityToken(const std::string& spn,
                                         gss_buffer_t in_token,
                                         gss_buffer_t out_token) {
  // Create a name for the principal
  // TODO(cbentzel): Just do this on the first pass?
  std::string spn_principal = spn;
  gss_buffer_desc spn_buffer = GSS_C_EMPTY_BUFFER;
  spn_buffer.value = const_cast<char*>(spn_principal.c_str());
  spn_buffer.length = spn_principal.size() + 1;
  OM_uint32 minor_status = 0;
  gss_name_t principal_name = GSS_C_NO_NAME;
  OM_uint32 major_status = library_->import_name(
      &minor_status,
      &spn_buffer,
      GSS_C_NT_HOSTBASED_SERVICE,
      &principal_name);
  int rv = MapImportNameStatusToError(major_status);
  if (rv != OK) {
    LOG(ERROR) << "Problem importing name from "
               << "spn \"" << spn_principal << "\"\n"
               << DisplayExtendedStatus(library_, major_status, minor_status);
    return rv;
  }
  ScopedName scoped_name(principal_name, library_);

  // Continue creating a security context.
  OM_uint32 req_flags = 0;
  if (can_delegate_)
    req_flags |= GSS_C_DELEG_FLAG;
  major_status = library_->init_sec_context(
      &minor_status,
      GSS_C_NO_CREDENTIAL,
      scoped_sec_context_.receive(),
      principal_name,
      gss_oid_,
      req_flags,
      GSS_C_INDEFINITE,
      GSS_C_NO_CHANNEL_BINDINGS,
      in_token,
      NULL,  // actual_mech_type
      out_token,
      NULL,  // ret flags
      NULL);
  rv = MapInitSecContextStatusToError(major_status);
  if (rv != OK) {
    LOG(ERROR) << "Problem initializing context. \n"
               << DisplayExtendedStatus(library_, major_status, minor_status)
               << '\n'
               << DescribeContext(library_, scoped_sec_context_.get());
  }
  return rv;
}

}  // namespace net
