// 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 "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/native_library.h"
#include "net/base/net_errors.h"
#include "net/http/mock_gssapi_library_posix.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

// gss_buffer_t helpers.
void ClearBuffer(gss_buffer_t dest) {
  if (!dest)
    return;
  dest->length = 0;
  delete [] reinterpret_cast<char*>(dest->value);
  dest->value = NULL;
}

void SetBuffer(gss_buffer_t dest, const void* src, size_t length) {
  if (!dest)
    return;
  ClearBuffer(dest);
  if (!src)
    return;
  dest->length = length;
  if (length) {
    dest->value = new char[length];
    memcpy(dest->value, src, length);
  }
}

void CopyBuffer(gss_buffer_t dest, const gss_buffer_t src) {
  if (!dest)
    return;
  ClearBuffer(dest);
  if (!src)
    return;
  SetBuffer(dest, src->value, src->length);
}

const char kInitialAuthResponse[] = "Mary had a little lamb";

void EstablishInitialContext(test::MockGSSAPILibrary* library) {
  test::GssContextMockImpl context_info(
      "localhost",                         // Source name
      "example.com",                       // Target name
      23,                                  // Lifetime
      *CHROME_GSS_SPNEGO_MECH_OID_DESC,    // Mechanism
      0,                                   // Context flags
      1,                                   // Locally initiated
      0);                                  // Open
  gss_buffer_desc in_buffer = {0, NULL};
  gss_buffer_desc out_buffer = {arraysize(kInitialAuthResponse),
                                const_cast<char*>(kInitialAuthResponse)};
  library->ExpectSecurityContext(
      "Negotiate",
      GSS_S_CONTINUE_NEEDED,
      0,
      context_info,
      in_buffer,
      out_buffer);
}

}  // namespace

TEST(HttpAuthGSSAPIPOSIXTest, GSSAPIStartup) {
  // TODO(ahendrickson): Manipulate the libraries and paths to test each of the
  // libraries we expect, and also whether or not they have the interface
  // functions we want.
  scoped_ptr<GSSAPILibrary> gssapi(new GSSAPISharedLibrary(""));
  DCHECK(gssapi.get());
  EXPECT_TRUE(gssapi.get()->Init());
}

#if defined(DLOPEN_KERBEROS)
TEST(HttpAuthGSSAPIPOSIXTest, GSSAPILoadCustomLibrary) {
  scoped_ptr<GSSAPILibrary> gssapi(
      new GSSAPISharedLibrary("/this/library/does/not/exist"));
  EXPECT_FALSE(gssapi.get()->Init());
}
#endif  // defined(DLOPEN_KERBEROS)

TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) {
  scoped_ptr<test::MockGSSAPILibrary> mock_library(new test::MockGSSAPILibrary);
  DCHECK(mock_library.get());
  mock_library->Init();
  const char kAuthResponse[] = "Mary had a little lamb";
  test::GssContextMockImpl context1(
      "localhost",                         // Source name
      "example.com",                       // Target name
      23,                                  // Lifetime
      *CHROME_GSS_SPNEGO_MECH_OID_DESC,    // Mechanism
      0,                                   // Context flags
      1,                                   // Locally initiated
      0);                                  // Open
  test::GssContextMockImpl context2(
      "localhost",                         // Source name
      "example.com",                       // Target name
      23,                                  // Lifetime
      *CHROME_GSS_SPNEGO_MECH_OID_DESC,    // Mechanism
      0,                                   // Context flags
      1,                                   // Locally initiated
      1);                                  // Open
  test::MockGSSAPILibrary::SecurityContextQuery queries[] = {
    test::MockGSSAPILibrary::SecurityContextQuery(
        "Negotiate",            // Package name
        GSS_S_CONTINUE_NEEDED,  // Major response code
        0,                      // Minor response code
        context1,               // Context
        NULL,                   // Expected input token
        kAuthResponse),         // Output token
    test::MockGSSAPILibrary::SecurityContextQuery(
        "Negotiate",            // Package name
        GSS_S_COMPLETE,         // Major response code
        0,                      // Minor response code
        context2,               // Context
        kAuthResponse,          // Expected input token
        kAuthResponse)          // Output token
  };

  for (size_t i = 0; i < arraysize(queries); ++i) {
    mock_library->ExpectSecurityContext(queries[i].expected_package,
                                        queries[i].response_code,
                                        queries[i].minor_response_code,
                                        queries[i].context_info,
                                        queries[i].expected_input_token,
                                        queries[i].output_token);
  }

  OM_uint32 major_status = 0;
  OM_uint32 minor_status = 0;
  gss_cred_id_t initiator_cred_handle = NULL;
  gss_ctx_id_t context_handle = NULL;
  gss_name_t target_name = NULL;
  gss_OID mech_type = NULL;
  OM_uint32 req_flags = 0;
  OM_uint32 time_req = 25;
  gss_channel_bindings_t input_chan_bindings = NULL;
  gss_buffer_desc input_token = { 0, NULL };
  gss_OID actual_mech_type= NULL;
  gss_buffer_desc output_token = { 0, NULL };
  OM_uint32 ret_flags = 0;
  OM_uint32 time_rec = 0;
  for (size_t i = 0; i < arraysize(queries); ++i) {
    major_status = mock_library->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);
    EXPECT_EQ(queries[i].response_code, major_status);
    CopyBuffer(&input_token, &output_token);
    ClearBuffer(&output_token);
  }
  ClearBuffer(&input_token);
  major_status = mock_library->delete_sec_context(&minor_status,
                                                  &context_handle,
                                                  GSS_C_NO_BUFFER);
  EXPECT_EQ(static_cast<OM_uint32>(GSS_S_COMPLETE), major_status);
}

TEST(HttpAuthGSSAPITest, ParseChallenge_FirstRound) {
  // The first round should just consist of an unadorned "Negotiate" header.
  test::MockGSSAPILibrary mock_library;
  HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
                             CHROME_GSS_SPNEGO_MECH_OID_DESC);
  std::string challenge_text = "Negotiate";
  HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(),
                                         challenge_text.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
            auth_gssapi.ParseChallenge(&challenge));
}

TEST(HttpAuthGSSAPITest, ParseChallenge_TwoRounds) {
  // The first round should just have "Negotiate", and the second round should
  // have a valid base64 token associated with it.
  test::MockGSSAPILibrary mock_library;
  HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
                             CHROME_GSS_SPNEGO_MECH_OID_DESC);
  std::string first_challenge_text = "Negotiate";
  HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(),
                                               first_challenge_text.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
            auth_gssapi.ParseChallenge(&first_challenge));

  // Generate an auth token and create another thing.
  EstablishInitialContext(&mock_library);
  std::string auth_token;
  EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
                                              &auth_token));

  std::string second_challenge_text = "Negotiate Zm9vYmFy";
  HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
                                                second_challenge_text.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
            auth_gssapi.ParseChallenge(&second_challenge));
}

TEST(HttpAuthGSSAPITest, ParseChallenge_UnexpectedTokenFirstRound) {
  // If the first round challenge has an additional authentication token, it
  // should be treated as an invalid challenge from the server.
  test::MockGSSAPILibrary mock_library;
  HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
                             CHROME_GSS_SPNEGO_MECH_OID_DESC);
  std::string challenge_text = "Negotiate Zm9vYmFy";
  HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(),
                                         challenge_text.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID,
            auth_gssapi.ParseChallenge(&challenge));
}

TEST(HttpAuthGSSAPITest, ParseChallenge_MissingTokenSecondRound) {
  // If a later-round challenge is simply "Negotiate", it should be treated as
  // an authentication challenge rejection from the server or proxy.
  test::MockGSSAPILibrary mock_library;
  HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
                             CHROME_GSS_SPNEGO_MECH_OID_DESC);
  std::string first_challenge_text = "Negotiate";
  HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(),
                                               first_challenge_text.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
            auth_gssapi.ParseChallenge(&first_challenge));

  EstablishInitialContext(&mock_library);
  std::string auth_token;
  EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
                                              &auth_token));
  std::string second_challenge_text = "Negotiate";
  HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
                                                second_challenge_text.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT,
            auth_gssapi.ParseChallenge(&second_challenge));
}

TEST(HttpAuthGSSAPITest, ParseChallenge_NonBase64EncodedToken) {
  // If a later-round challenge has an invalid base64 encoded token, it should
  // be treated as an invalid challenge.
  test::MockGSSAPILibrary mock_library;
  HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
                             CHROME_GSS_SPNEGO_MECH_OID_DESC);
  std::string first_challenge_text = "Negotiate";
  HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(),
                                               first_challenge_text.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
            auth_gssapi.ParseChallenge(&first_challenge));

  EstablishInitialContext(&mock_library);
  std::string auth_token;
  EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
                                              &auth_token));
  std::string second_challenge_text = "Negotiate =happyjoy=";
  HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
                                                second_challenge_text.end());
  EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID,
            auth_gssapi.ParseChallenge(&second_challenge));
}

}  // namespace net
