// Copyright (c) 2011 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.

#ifndef NET_HTTP_MOCK_GSSAPI_LIBRARY_POSIX_H_
#define NET_HTTP_MOCK_GSSAPI_LIBRARY_POSIX_H_

#include <list>
#include <string>

#include "base/gtest_prod_util.h"
#include "net/http/http_auth_gssapi_posix.h"

#if defined(OS_MACOSX) && defined(MAC_OS_X_VERSION_10_9) && \
    MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
// Including gssapi.h directly is deprecated in the 10.9 SDK.
#include <GSS/gssapi.h>
#elif defined(OS_FREEBSD)
#include <gssapi/gssapi.h>
#else
#include <gssapi.h>
#endif

namespace net {

namespace test {

class GssContextMockImpl {
 public:
  GssContextMockImpl();
  GssContextMockImpl(const GssContextMockImpl& other);
  GssContextMockImpl(const char* src_name,
                     const char* targ_name,
                     OM_uint32 lifetime_rec,
                     const gss_OID_desc& mech_type,
                     OM_uint32 ctx_flags,
                     int locally_initiated,
                     int open);
  ~GssContextMockImpl();

  void Assign(const GssContextMockImpl& other);

  std::string src_name;
  std::string targ_name;
  OM_uint32 lifetime_rec;
  gss_OID_desc mech_type;
  OM_uint32 ctx_flags;
  int locally_initiated;
  int open;
};

// The MockGSSAPILibrary class is intended for unit tests which want to bypass
// the system GSSAPI library calls.
class MockGSSAPILibrary : public GSSAPILibrary {
 public:
  // Unit tests need access to this. "Friend"ing didn't help.
  struct SecurityContextQuery {
    SecurityContextQuery();
    SecurityContextQuery(const std::string& expected_package,
                         OM_uint32 response_code,
                         OM_uint32 minor_response_code,
                         const test::GssContextMockImpl& context_info,
                         const char* expected_input_token,
                         const char* output_token);
    ~SecurityContextQuery();

    std::string expected_package;
    OM_uint32 response_code;
    OM_uint32 minor_response_code;
    test::GssContextMockImpl context_info;
    gss_buffer_desc expected_input_token;
    gss_buffer_desc output_token;
  };

  MockGSSAPILibrary();
  ~MockGSSAPILibrary() override;

  // Establishes an expectation for a |init_sec_context()| call.
  //
  // Each expectation established by |ExpectSecurityContext()| must be
  // matched by a call to |init_sec_context()| during the lifetime of
  // the MockGSSAPILibrary. The |expected_package| argument must equal the
  // value associated with the |target_name| argument to |init_sec_context()|
  // for there to be a match. The expectations also establish an explicit
  // ordering.
  //
  // For example, this sequence will be successful.
  //   MockGSSAPILibrary lib;
  //   lib.ExpectSecurityContext("NTLM", ...)
  //   lib.ExpectSecurityContext("Negotiate", ...)
  //   lib.init_sec_context("NTLM", ...)
  //   lib.init_sec_context("Negotiate", ...)
  //
  // This sequence will fail since the queries do not occur in the order
  // established by the expectations.
  //   MockGSSAPILibrary lib;
  //   lib.ExpectSecurityContext("NTLM", ...)
  //   lib.ExpectSecurityContext("Negotiate", ...)
  //   lib.init_sec_context("Negotiate", ...)
  //   lib.init_sec_context("NTLM", ...)
  //
  // This sequence will fail because there were not enough queries.
  //   MockGSSAPILibrary lib;
  //   lib.ExpectSecurityContext("NTLM", ...)
  //   lib.ExpectSecurityContext("Negotiate", ...)
  //   lib.init_sec_context("NTLM", ...)
  //
  // |response_code| is used as the return value for |init_sec_context()|.
  // If |response_code| is GSS_S_COMPLETE,
  //
  // |context_info| is the expected value of the |**context_handle| in after
  // |init_sec_context()| returns.
  void ExpectSecurityContext(const std::string& expected_package,
                             OM_uint32 response_code,
                             OM_uint32 minor_response_code,
                             const test::GssContextMockImpl& context_info,
                             const gss_buffer_desc& expected_input_token,
                             const gss_buffer_desc& output_token);

  // GSSAPILibrary methods:

  // Initializes the library, including any necessary dynamic libraries.
  // This is done separately from construction (which happens at startup time)
  // in order to delay work until the class is actually needed.
  bool Init() override;

  // These methods match the ones in the GSSAPI library.
  OM_uint32 import_name(OM_uint32* minor_status,
                        const gss_buffer_t input_name_buffer,
                        const gss_OID input_name_type,
                        gss_name_t* output_name) override;
  OM_uint32 release_name(OM_uint32* minor_status,
                         gss_name_t* input_name) override;
  OM_uint32 release_buffer(OM_uint32* minor_status,
                           gss_buffer_t buffer) override;
  OM_uint32 display_name(OM_uint32* minor_status,
                         const gss_name_t input_name,
                         gss_buffer_t output_name_buffer,
                         gss_OID* output_name_type) override;
  OM_uint32 display_status(OM_uint32* minor_status,
                           OM_uint32 status_value,
                           int status_type,
                           const gss_OID mech_type,
                           OM_uint32* message_contex,
                           gss_buffer_t status_string) override;
  OM_uint32 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) override;
  OM_uint32 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) override;
  OM_uint32 delete_sec_context(OM_uint32* minor_status,
                               gss_ctx_id_t* context_handle,
                               gss_buffer_t output_token) override;
  OM_uint32 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) override;

 private:
  FRIEND_TEST_ALL_PREFIXES(HttpAuthGSSAPIPOSIXTest, GSSAPICycle);

  // |expected_security_queries| contains an ordered list of expected
  // |init_sec_context()| calls and the return values for those
  // calls.
  std::list<SecurityContextQuery> expected_security_queries_;
};

}  // namespace test

}  // namespace net

#endif  // NET_HTTP_MOCK_GSSAPI_LIBRARY_POSIX_H_

