1// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_HTTP_MOCK_GSSAPI_LIBRARY_POSIX_H_
6#define NET_HTTP_MOCK_GSSAPI_LIBRARY_POSIX_H_
7
8#include <list>
9#include <string>
10
11#include "base/gtest_prod_util.h"
12#include "net/http/http_auth_gssapi_posix.h"
13
14#if defined(OS_MACOSX) && defined(MAC_OS_X_VERSION_10_9) && \
15    MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9
16// Including gssapi.h directly is deprecated in the 10.9 SDK.
17#include <GSS/gssapi.h>
18#else
19#include <gssapi.h>
20#endif
21
22namespace net {
23
24namespace test {
25
26class GssContextMockImpl {
27 public:
28  GssContextMockImpl();
29  GssContextMockImpl(const GssContextMockImpl& other);
30  GssContextMockImpl(const char* src_name,
31                     const char* targ_name,
32                     OM_uint32 lifetime_rec,
33                     const gss_OID_desc& mech_type,
34                     OM_uint32 ctx_flags,
35                     int locally_initiated,
36                     int open);
37  ~GssContextMockImpl();
38
39  void Assign(const GssContextMockImpl& other);
40
41  std::string src_name;
42  std::string targ_name;
43  OM_uint32 lifetime_rec;
44  gss_OID_desc mech_type;
45  OM_uint32 ctx_flags;
46  int locally_initiated;
47  int open;
48};
49
50// The MockGSSAPILibrary class is intended for unit tests which want to bypass
51// the system GSSAPI library calls.
52class MockGSSAPILibrary : public GSSAPILibrary {
53 public:
54  // Unit tests need access to this. "Friend"ing didn't help.
55  struct SecurityContextQuery {
56    SecurityContextQuery();
57    SecurityContextQuery(const std::string& expected_package,
58                         OM_uint32 response_code,
59                         OM_uint32 minor_response_code,
60                         const test::GssContextMockImpl& context_info,
61                         const char* expected_input_token,
62                         const char* output_token);
63    ~SecurityContextQuery();
64
65    std::string expected_package;
66    OM_uint32 response_code;
67    OM_uint32 minor_response_code;
68    test::GssContextMockImpl context_info;
69    gss_buffer_desc expected_input_token;
70    gss_buffer_desc output_token;
71  };
72
73  MockGSSAPILibrary();
74  virtual ~MockGSSAPILibrary();
75
76  // Establishes an expectation for a |init_sec_context()| call.
77  //
78  // Each expectation established by |ExpectSecurityContext()| must be
79  // matched by a call to |init_sec_context()| during the lifetime of
80  // the MockGSSAPILibrary. The |expected_package| argument must equal the
81  // value associated with the |target_name| argument to |init_sec_context()|
82  // for there to be a match. The expectations also establish an explicit
83  // ordering.
84  //
85  // For example, this sequence will be successful.
86  //   MockGSSAPILibrary lib;
87  //   lib.ExpectSecurityContext("NTLM", ...)
88  //   lib.ExpectSecurityContext("Negotiate", ...)
89  //   lib.init_sec_context("NTLM", ...)
90  //   lib.init_sec_context("Negotiate", ...)
91  //
92  // This sequence will fail since the queries do not occur in the order
93  // established by the expectations.
94  //   MockGSSAPILibrary lib;
95  //   lib.ExpectSecurityContext("NTLM", ...)
96  //   lib.ExpectSecurityContext("Negotiate", ...)
97  //   lib.init_sec_context("Negotiate", ...)
98  //   lib.init_sec_context("NTLM", ...)
99  //
100  // This sequence will fail because there were not enough queries.
101  //   MockGSSAPILibrary lib;
102  //   lib.ExpectSecurityContext("NTLM", ...)
103  //   lib.ExpectSecurityContext("Negotiate", ...)
104  //   lib.init_sec_context("NTLM", ...)
105  //
106  // |response_code| is used as the return value for |init_sec_context()|.
107  // If |response_code| is GSS_S_COMPLETE,
108  //
109  // |context_info| is the expected value of the |**context_handle| in after
110  // |init_sec_context()| returns.
111  void ExpectSecurityContext(const std::string& expected_package,
112                             OM_uint32 response_code,
113                             OM_uint32 minor_response_code,
114                             const test::GssContextMockImpl& context_info,
115                             const gss_buffer_desc& expected_input_token,
116                             const gss_buffer_desc& output_token);
117
118  // GSSAPILibrary methods:
119
120  // Initializes the library, including any necessary dynamic libraries.
121  // This is done separately from construction (which happens at startup time)
122  // in order to delay work until the class is actually needed.
123  virtual bool Init() OVERRIDE;
124
125  // These methods match the ones in the GSSAPI library.
126  virtual OM_uint32 import_name(
127      OM_uint32* minor_status,
128      const gss_buffer_t input_name_buffer,
129      const gss_OID input_name_type,
130      gss_name_t* output_name) OVERRIDE;
131  virtual OM_uint32 release_name(
132      OM_uint32* minor_status,
133      gss_name_t* input_name) OVERRIDE;
134  virtual OM_uint32 release_buffer(
135      OM_uint32* minor_status,
136      gss_buffer_t buffer) OVERRIDE;
137  virtual OM_uint32 display_name(
138      OM_uint32* minor_status,
139      const gss_name_t input_name,
140      gss_buffer_t output_name_buffer,
141      gss_OID* output_name_type) OVERRIDE;
142  virtual OM_uint32 display_status(
143      OM_uint32* minor_status,
144      OM_uint32 status_value,
145      int status_type,
146      const gss_OID mech_type,
147      OM_uint32* message_contex,
148      gss_buffer_t status_string) OVERRIDE;
149  virtual OM_uint32 init_sec_context(
150      OM_uint32* minor_status,
151      const gss_cred_id_t initiator_cred_handle,
152      gss_ctx_id_t* context_handle,
153      const gss_name_t target_name,
154      const gss_OID mech_type,
155      OM_uint32 req_flags,
156      OM_uint32 time_req,
157      const gss_channel_bindings_t input_chan_bindings,
158      const gss_buffer_t input_token,
159      gss_OID* actual_mech_type,
160      gss_buffer_t output_token,
161      OM_uint32* ret_flags,
162      OM_uint32* time_rec) OVERRIDE;
163  virtual OM_uint32 wrap_size_limit(
164      OM_uint32* minor_status,
165      const gss_ctx_id_t context_handle,
166      int conf_req_flag,
167      gss_qop_t qop_req,
168      OM_uint32 req_output_size,
169      OM_uint32* max_input_size) OVERRIDE;
170  virtual OM_uint32 delete_sec_context(
171      OM_uint32* minor_status,
172      gss_ctx_id_t* context_handle,
173      gss_buffer_t output_token) OVERRIDE;
174  virtual OM_uint32 inquire_context(
175      OM_uint32* minor_status,
176      const gss_ctx_id_t context_handle,
177      gss_name_t* src_name,
178      gss_name_t* targ_name,
179      OM_uint32* lifetime_rec,
180      gss_OID* mech_type,
181      OM_uint32* ctx_flags,
182      int* locally_initiated,
183      int* open) OVERRIDE;
184
185 private:
186  FRIEND_TEST_ALL_PREFIXES(HttpAuthGSSAPIPOSIXTest, GSSAPICycle);
187
188  // |expected_security_queries| contains an ordered list of expected
189  // |init_sec_context()| calls and the return values for those
190  // calls.
191  std::list<SecurityContextQuery> expected_security_queries_;
192};
193
194}  // namespace test
195
196}  // namespace net
197
198#endif  // NET_HTTP_MOCK_GSSAPI_LIBRARY_POSIX_H_
199
200