Disable overview on alt-tab by default and update test expectation to match.
[chromium-blink-merge.git] / net / http / http_auth_gssapi_posix_unittest.cc
blob1c3d12b6c291915a89105db5e46f51543e4a0add
1 // Copyright (c) 2012 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.
5 #include "net/http/http_auth_gssapi_posix.h"
7 #include "base/basictypes.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/native_library.h"
11 #include "net/base/net_errors.h"
12 #include "net/http/mock_gssapi_library_posix.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace net {
17 namespace {
19 // gss_buffer_t helpers.
20 void ClearBuffer(gss_buffer_t dest) {
21 if (!dest)
22 return;
23 dest->length = 0;
24 delete [] reinterpret_cast<char*>(dest->value);
25 dest->value = NULL;
28 void SetBuffer(gss_buffer_t dest, const void* src, size_t length) {
29 if (!dest)
30 return;
31 ClearBuffer(dest);
32 if (!src)
33 return;
34 dest->length = length;
35 if (length) {
36 dest->value = new char[length];
37 memcpy(dest->value, src, length);
41 void CopyBuffer(gss_buffer_t dest, const gss_buffer_t src) {
42 if (!dest)
43 return;
44 ClearBuffer(dest);
45 if (!src)
46 return;
47 SetBuffer(dest, src->value, src->length);
50 const char kInitialAuthResponse[] = "Mary had a little lamb";
52 void EstablishInitialContext(test::MockGSSAPILibrary* library) {
53 test::GssContextMockImpl context_info(
54 "localhost", // Source name
55 "example.com", // Target name
56 23, // Lifetime
57 *CHROME_GSS_SPNEGO_MECH_OID_DESC, // Mechanism
58 0, // Context flags
59 1, // Locally initiated
60 0); // Open
61 gss_buffer_desc in_buffer = {0, NULL};
62 gss_buffer_desc out_buffer = {arraysize(kInitialAuthResponse),
63 const_cast<char*>(kInitialAuthResponse)};
64 library->ExpectSecurityContext(
65 "Negotiate",
66 GSS_S_CONTINUE_NEEDED,
68 context_info,
69 in_buffer,
70 out_buffer);
73 } // namespace
75 TEST(HttpAuthGSSAPIPOSIXTest, GSSAPIStartup) {
76 // TODO(ahendrickson): Manipulate the libraries and paths to test each of the
77 // libraries we expect, and also whether or not they have the interface
78 // functions we want.
79 scoped_ptr<GSSAPILibrary> gssapi(new GSSAPISharedLibrary(std::string()));
80 DCHECK(gssapi.get());
81 EXPECT_TRUE(gssapi.get()->Init());
84 #if defined(DLOPEN_KERBEROS)
85 TEST(HttpAuthGSSAPIPOSIXTest, GSSAPILoadCustomLibrary) {
86 scoped_ptr<GSSAPILibrary> gssapi(
87 new GSSAPISharedLibrary("/this/library/does/not/exist"));
88 EXPECT_FALSE(gssapi.get()->Init());
90 #endif // defined(DLOPEN_KERBEROS)
92 TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) {
93 scoped_ptr<test::MockGSSAPILibrary> mock_library(new test::MockGSSAPILibrary);
94 DCHECK(mock_library.get());
95 mock_library->Init();
96 const char kAuthResponse[] = "Mary had a little lamb";
97 test::GssContextMockImpl context1(
98 "localhost", // Source name
99 "example.com", // Target name
100 23, // Lifetime
101 *CHROME_GSS_SPNEGO_MECH_OID_DESC, // Mechanism
102 0, // Context flags
103 1, // Locally initiated
104 0); // Open
105 test::GssContextMockImpl context2(
106 "localhost", // Source name
107 "example.com", // Target name
108 23, // Lifetime
109 *CHROME_GSS_SPNEGO_MECH_OID_DESC, // Mechanism
110 0, // Context flags
111 1, // Locally initiated
112 1); // Open
113 test::MockGSSAPILibrary::SecurityContextQuery queries[] = {
114 test::MockGSSAPILibrary::SecurityContextQuery(
115 "Negotiate", // Package name
116 GSS_S_CONTINUE_NEEDED, // Major response code
117 0, // Minor response code
118 context1, // Context
119 NULL, // Expected input token
120 kAuthResponse), // Output token
121 test::MockGSSAPILibrary::SecurityContextQuery(
122 "Negotiate", // Package name
123 GSS_S_COMPLETE, // Major response code
124 0, // Minor response code
125 context2, // Context
126 kAuthResponse, // Expected input token
127 kAuthResponse) // Output token
130 for (size_t i = 0; i < arraysize(queries); ++i) {
131 mock_library->ExpectSecurityContext(queries[i].expected_package,
132 queries[i].response_code,
133 queries[i].minor_response_code,
134 queries[i].context_info,
135 queries[i].expected_input_token,
136 queries[i].output_token);
139 OM_uint32 major_status = 0;
140 OM_uint32 minor_status = 0;
141 gss_cred_id_t initiator_cred_handle = NULL;
142 gss_ctx_id_t context_handle = NULL;
143 gss_name_t target_name = NULL;
144 gss_OID mech_type = NULL;
145 OM_uint32 req_flags = 0;
146 OM_uint32 time_req = 25;
147 gss_channel_bindings_t input_chan_bindings = NULL;
148 gss_buffer_desc input_token = { 0, NULL };
149 gss_OID actual_mech_type= NULL;
150 gss_buffer_desc output_token = { 0, NULL };
151 OM_uint32 ret_flags = 0;
152 OM_uint32 time_rec = 0;
153 for (size_t i = 0; i < arraysize(queries); ++i) {
154 major_status = mock_library->init_sec_context(&minor_status,
155 initiator_cred_handle,
156 &context_handle,
157 target_name,
158 mech_type,
159 req_flags,
160 time_req,
161 input_chan_bindings,
162 &input_token,
163 &actual_mech_type,
164 &output_token,
165 &ret_flags,
166 &time_rec);
167 EXPECT_EQ(queries[i].response_code, major_status);
168 CopyBuffer(&input_token, &output_token);
169 ClearBuffer(&output_token);
171 ClearBuffer(&input_token);
172 major_status = mock_library->delete_sec_context(&minor_status,
173 &context_handle,
174 GSS_C_NO_BUFFER);
175 EXPECT_EQ(static_cast<OM_uint32>(GSS_S_COMPLETE), major_status);
178 TEST(HttpAuthGSSAPITest, ParseChallenge_FirstRound) {
179 // The first round should just consist of an unadorned "Negotiate" header.
180 test::MockGSSAPILibrary mock_library;
181 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
182 CHROME_GSS_SPNEGO_MECH_OID_DESC);
183 std::string challenge_text = "Negotiate";
184 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(),
185 challenge_text.end());
186 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
187 auth_gssapi.ParseChallenge(&challenge));
190 TEST(HttpAuthGSSAPITest, ParseChallenge_TwoRounds) {
191 // The first round should just have "Negotiate", and the second round should
192 // have a valid base64 token associated with it.
193 test::MockGSSAPILibrary mock_library;
194 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
195 CHROME_GSS_SPNEGO_MECH_OID_DESC);
196 std::string first_challenge_text = "Negotiate";
197 HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(),
198 first_challenge_text.end());
199 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
200 auth_gssapi.ParseChallenge(&first_challenge));
202 // Generate an auth token and create another thing.
203 EstablishInitialContext(&mock_library);
204 std::string auth_token;
205 EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
206 &auth_token));
208 std::string second_challenge_text = "Negotiate Zm9vYmFy";
209 HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
210 second_challenge_text.end());
211 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
212 auth_gssapi.ParseChallenge(&second_challenge));
215 TEST(HttpAuthGSSAPITest, ParseChallenge_UnexpectedTokenFirstRound) {
216 // If the first round challenge has an additional authentication token, it
217 // should be treated as an invalid challenge from the server.
218 test::MockGSSAPILibrary mock_library;
219 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
220 CHROME_GSS_SPNEGO_MECH_OID_DESC);
221 std::string challenge_text = "Negotiate Zm9vYmFy";
222 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(),
223 challenge_text.end());
224 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID,
225 auth_gssapi.ParseChallenge(&challenge));
228 TEST(HttpAuthGSSAPITest, ParseChallenge_MissingTokenSecondRound) {
229 // If a later-round challenge is simply "Negotiate", it should be treated as
230 // an authentication challenge rejection from the server or proxy.
231 test::MockGSSAPILibrary mock_library;
232 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
233 CHROME_GSS_SPNEGO_MECH_OID_DESC);
234 std::string first_challenge_text = "Negotiate";
235 HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(),
236 first_challenge_text.end());
237 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
238 auth_gssapi.ParseChallenge(&first_challenge));
240 EstablishInitialContext(&mock_library);
241 std::string auth_token;
242 EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
243 &auth_token));
244 std::string second_challenge_text = "Negotiate";
245 HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
246 second_challenge_text.end());
247 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT,
248 auth_gssapi.ParseChallenge(&second_challenge));
251 TEST(HttpAuthGSSAPITest, ParseChallenge_NonBase64EncodedToken) {
252 // If a later-round challenge has an invalid base64 encoded token, it should
253 // be treated as an invalid challenge.
254 test::MockGSSAPILibrary mock_library;
255 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate",
256 CHROME_GSS_SPNEGO_MECH_OID_DESC);
257 std::string first_challenge_text = "Negotiate";
258 HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(),
259 first_challenge_text.end());
260 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
261 auth_gssapi.ParseChallenge(&first_challenge));
263 EstablishInitialContext(&mock_library);
264 std::string auth_token;
265 EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com",
266 &auth_token));
267 std::string second_challenge_text = "Negotiate =happyjoy=";
268 HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(),
269 second_challenge_text.end());
270 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID,
271 auth_gssapi.ParseChallenge(&second_challenge));
274 } // namespace net