| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/http_auth_gssapi_posix.h" | 5 #include "net/http/http_auth_gssapi_posix.h" |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/native_library.h" | 10 #include "base/native_library.h" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 SetBuffer(dest, src->value, src->length); | 47 SetBuffer(dest, src->value, src->length); |
| 48 } | 48 } |
| 49 | 49 |
| 50 const char kInitialAuthResponse[] = "Mary had a little lamb"; | 50 const char kInitialAuthResponse[] = "Mary had a little lamb"; |
| 51 | 51 |
| 52 void EstablishInitialContext(test::MockGSSAPILibrary* library) { | 52 void EstablishInitialContext(test::MockGSSAPILibrary* library) { |
| 53 test::GssContextMockImpl context_info( | 53 test::GssContextMockImpl context_info( |
| 54 "localhost", // Source name | 54 "localhost", // Source name |
| 55 "example.com", // Target name | 55 "example.com", // Target name |
| 56 23, // Lifetime | 56 23, // Lifetime |
| 57 *CHROME_GSS_C_NT_HOSTBASED_SERVICE, // Mechanism | 57 *CHROME_GSS_SPNEGO_MECH_OID_DESC, // Mechanism |
| 58 0, // Context flags | 58 0, // Context flags |
| 59 1, // Locally initiated | 59 1, // Locally initiated |
| 60 0); // Open | 60 0); // Open |
| 61 gss_buffer_desc in_buffer = {0, NULL}; | 61 gss_buffer_desc in_buffer = {0, NULL}; |
| 62 gss_buffer_desc out_buffer = {arraysize(kInitialAuthResponse), | 62 gss_buffer_desc out_buffer = {arraysize(kInitialAuthResponse), |
| 63 const_cast<char*>(kInitialAuthResponse)}; | 63 const_cast<char*>(kInitialAuthResponse)}; |
| 64 library->ExpectSecurityContext( | 64 library->ExpectSecurityContext( |
| 65 "Negotiate", | 65 "Negotiate", |
| 66 GSS_S_CONTINUE_NEEDED, | 66 GSS_S_CONTINUE_NEEDED, |
| 67 0, | 67 0, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 91 | 91 |
| 92 TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) { | 92 TEST(HttpAuthGSSAPIPOSIXTest, GSSAPICycle) { |
| 93 scoped_ptr<test::MockGSSAPILibrary> mock_library(new test::MockGSSAPILibrary); | 93 scoped_ptr<test::MockGSSAPILibrary> mock_library(new test::MockGSSAPILibrary); |
| 94 DCHECK(mock_library.get()); | 94 DCHECK(mock_library.get()); |
| 95 mock_library->Init(); | 95 mock_library->Init(); |
| 96 const char kAuthResponse[] = "Mary had a little lamb"; | 96 const char kAuthResponse[] = "Mary had a little lamb"; |
| 97 test::GssContextMockImpl context1( | 97 test::GssContextMockImpl context1( |
| 98 "localhost", // Source name | 98 "localhost", // Source name |
| 99 "example.com", // Target name | 99 "example.com", // Target name |
| 100 23, // Lifetime | 100 23, // Lifetime |
| 101 *CHROME_GSS_C_NT_HOSTBASED_SERVICE, // Mechanism | 101 *CHROME_GSS_SPNEGO_MECH_OID_DESC, // Mechanism |
| 102 0, // Context flags | 102 0, // Context flags |
| 103 1, // Locally initiated | 103 1, // Locally initiated |
| 104 0); // Open | 104 0); // Open |
| 105 test::GssContextMockImpl context2( | 105 test::GssContextMockImpl context2( |
| 106 "localhost", // Source name | 106 "localhost", // Source name |
| 107 "example.com", // Target name | 107 "example.com", // Target name |
| 108 23, // Lifetime | 108 23, // Lifetime |
| 109 *CHROME_GSS_C_NT_HOSTBASED_SERVICE, // Mechanism | 109 *CHROME_GSS_SPNEGO_MECH_OID_DESC, // Mechanism |
| 110 0, // Context flags | 110 0, // Context flags |
| 111 1, // Locally initiated | 111 1, // Locally initiated |
| 112 1); // Open | 112 1); // Open |
| 113 test::MockGSSAPILibrary::SecurityContextQuery queries[] = { | 113 test::MockGSSAPILibrary::SecurityContextQuery queries[] = { |
| 114 test::MockGSSAPILibrary::SecurityContextQuery( | 114 test::MockGSSAPILibrary::SecurityContextQuery( |
| 115 "Negotiate", // Package name | 115 "Negotiate", // Package name |
| 116 GSS_S_CONTINUE_NEEDED, // Major response code | 116 GSS_S_CONTINUE_NEEDED, // Major response code |
| 117 0, // Minor response code | 117 0, // Minor response code |
| 118 context1, // Context | 118 context1, // Context |
| 119 NULL, // Expected input token | 119 NULL, // Expected input token |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 major_status = mock_library->delete_sec_context(&minor_status, | 172 major_status = mock_library->delete_sec_context(&minor_status, |
| 173 &context_handle, | 173 &context_handle, |
| 174 GSS_C_NO_BUFFER); | 174 GSS_C_NO_BUFFER); |
| 175 EXPECT_EQ(static_cast<OM_uint32>(GSS_S_COMPLETE), major_status); | 175 EXPECT_EQ(static_cast<OM_uint32>(GSS_S_COMPLETE), major_status); |
| 176 } | 176 } |
| 177 | 177 |
| 178 TEST(HttpAuthGSSAPITest, ParseChallenge_FirstRound) { | 178 TEST(HttpAuthGSSAPITest, ParseChallenge_FirstRound) { |
| 179 // The first round should just consist of an unadorned "Negotiate" header. | 179 // The first round should just consist of an unadorned "Negotiate" header. |
| 180 test::MockGSSAPILibrary mock_library; | 180 test::MockGSSAPILibrary mock_library; |
| 181 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", | 181 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", |
| 182 CHROME_GSS_KRB5_MECH_OID_DESC); | 182 CHROME_GSS_SPNEGO_MECH_OID_DESC); |
| 183 std::string challenge_text = "Negotiate"; | 183 std::string challenge_text = "Negotiate"; |
| 184 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(), | 184 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(), |
| 185 challenge_text.end()); | 185 challenge_text.end()); |
| 186 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, | 186 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, |
| 187 auth_gssapi.ParseChallenge(&challenge)); | 187 auth_gssapi.ParseChallenge(&challenge)); |
| 188 } | 188 } |
| 189 | 189 |
| 190 TEST(HttpAuthGSSAPITest, ParseChallenge_TwoRounds) { | 190 TEST(HttpAuthGSSAPITest, ParseChallenge_TwoRounds) { |
| 191 // The first round should just have "Negotiate", and the second round should | 191 // The first round should just have "Negotiate", and the second round should |
| 192 // have a valid base64 token associated with it. | 192 // have a valid base64 token associated with it. |
| 193 test::MockGSSAPILibrary mock_library; | 193 test::MockGSSAPILibrary mock_library; |
| 194 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", | 194 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", |
| 195 CHROME_GSS_KRB5_MECH_OID_DESC); | 195 CHROME_GSS_SPNEGO_MECH_OID_DESC); |
| 196 std::string first_challenge_text = "Negotiate"; | 196 std::string first_challenge_text = "Negotiate"; |
| 197 HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(), | 197 HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(), |
| 198 first_challenge_text.end()); | 198 first_challenge_text.end()); |
| 199 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, | 199 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, |
| 200 auth_gssapi.ParseChallenge(&first_challenge)); | 200 auth_gssapi.ParseChallenge(&first_challenge)); |
| 201 | 201 |
| 202 // Generate an auth token and create another thing. | 202 // Generate an auth token and create another thing. |
| 203 EstablishInitialContext(&mock_library); | 203 EstablishInitialContext(&mock_library); |
| 204 std::string auth_token; | 204 std::string auth_token; |
| 205 EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com", | 205 EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com", |
| 206 &auth_token)); | 206 &auth_token)); |
| 207 | 207 |
| 208 std::string second_challenge_text = "Negotiate Zm9vYmFy"; | 208 std::string second_challenge_text = "Negotiate Zm9vYmFy"; |
| 209 HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(), | 209 HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(), |
| 210 second_challenge_text.end()); | 210 second_challenge_text.end()); |
| 211 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, | 211 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, |
| 212 auth_gssapi.ParseChallenge(&second_challenge)); | 212 auth_gssapi.ParseChallenge(&second_challenge)); |
| 213 } | 213 } |
| 214 | 214 |
| 215 TEST(HttpAuthGSSAPITest, ParseChallenge_UnexpectedTokenFirstRound) { | 215 TEST(HttpAuthGSSAPITest, ParseChallenge_UnexpectedTokenFirstRound) { |
| 216 // If the first round challenge has an additional authentication token, it | 216 // If the first round challenge has an additional authentication token, it |
| 217 // should be treated as an invalid challenge from the server. | 217 // should be treated as an invalid challenge from the server. |
| 218 test::MockGSSAPILibrary mock_library; | 218 test::MockGSSAPILibrary mock_library; |
| 219 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", | 219 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", |
| 220 CHROME_GSS_KRB5_MECH_OID_DESC); | 220 CHROME_GSS_SPNEGO_MECH_OID_DESC); |
| 221 std::string challenge_text = "Negotiate Zm9vYmFy"; | 221 std::string challenge_text = "Negotiate Zm9vYmFy"; |
| 222 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(), | 222 HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(), |
| 223 challenge_text.end()); | 223 challenge_text.end()); |
| 224 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID, | 224 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID, |
| 225 auth_gssapi.ParseChallenge(&challenge)); | 225 auth_gssapi.ParseChallenge(&challenge)); |
| 226 } | 226 } |
| 227 | 227 |
| 228 TEST(HttpAuthGSSAPITest, ParseChallenge_MissingTokenSecondRound) { | 228 TEST(HttpAuthGSSAPITest, ParseChallenge_MissingTokenSecondRound) { |
| 229 // If a later-round challenge is simply "Negotiate", it should be treated as | 229 // If a later-round challenge is simply "Negotiate", it should be treated as |
| 230 // an authentication challenge rejection from the server or proxy. | 230 // an authentication challenge rejection from the server or proxy. |
| 231 test::MockGSSAPILibrary mock_library; | 231 test::MockGSSAPILibrary mock_library; |
| 232 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", | 232 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", |
| 233 CHROME_GSS_KRB5_MECH_OID_DESC); | 233 CHROME_GSS_SPNEGO_MECH_OID_DESC); |
| 234 std::string first_challenge_text = "Negotiate"; | 234 std::string first_challenge_text = "Negotiate"; |
| 235 HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(), | 235 HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(), |
| 236 first_challenge_text.end()); | 236 first_challenge_text.end()); |
| 237 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, | 237 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, |
| 238 auth_gssapi.ParseChallenge(&first_challenge)); | 238 auth_gssapi.ParseChallenge(&first_challenge)); |
| 239 | 239 |
| 240 EstablishInitialContext(&mock_library); | 240 EstablishInitialContext(&mock_library); |
| 241 std::string auth_token; | 241 std::string auth_token; |
| 242 EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com", | 242 EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com", |
| 243 &auth_token)); | 243 &auth_token)); |
| 244 std::string second_challenge_text = "Negotiate"; | 244 std::string second_challenge_text = "Negotiate"; |
| 245 HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(), | 245 HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(), |
| 246 second_challenge_text.end()); | 246 second_challenge_text.end()); |
| 247 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, | 247 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT, |
| 248 auth_gssapi.ParseChallenge(&second_challenge)); | 248 auth_gssapi.ParseChallenge(&second_challenge)); |
| 249 } | 249 } |
| 250 | 250 |
| 251 TEST(HttpAuthGSSAPITest, ParseChallenge_NonBase64EncodedToken) { | 251 TEST(HttpAuthGSSAPITest, ParseChallenge_NonBase64EncodedToken) { |
| 252 // If a later-round challenge has an invalid base64 encoded token, it should | 252 // If a later-round challenge has an invalid base64 encoded token, it should |
| 253 // be treated as an invalid challenge. | 253 // be treated as an invalid challenge. |
| 254 test::MockGSSAPILibrary mock_library; | 254 test::MockGSSAPILibrary mock_library; |
| 255 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", | 255 HttpAuthGSSAPI auth_gssapi(&mock_library, "Negotiate", |
| 256 CHROME_GSS_KRB5_MECH_OID_DESC); | 256 CHROME_GSS_SPNEGO_MECH_OID_DESC); |
| 257 std::string first_challenge_text = "Negotiate"; | 257 std::string first_challenge_text = "Negotiate"; |
| 258 HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(), | 258 HttpAuth::ChallengeTokenizer first_challenge(first_challenge_text.begin(), |
| 259 first_challenge_text.end()); | 259 first_challenge_text.end()); |
| 260 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, | 260 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT, |
| 261 auth_gssapi.ParseChallenge(&first_challenge)); | 261 auth_gssapi.ParseChallenge(&first_challenge)); |
| 262 | 262 |
| 263 EstablishInitialContext(&mock_library); | 263 EstablishInitialContext(&mock_library); |
| 264 std::string auth_token; | 264 std::string auth_token; |
| 265 EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com", | 265 EXPECT_EQ(OK, auth_gssapi.GenerateAuthToken(NULL, L"HTTP/intranet.google.com", |
| 266 &auth_token)); | 266 &auth_token)); |
| 267 std::string second_challenge_text = "Negotiate =happyjoy="; | 267 std::string second_challenge_text = "Negotiate =happyjoy="; |
| 268 HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(), | 268 HttpAuth::ChallengeTokenizer second_challenge(second_challenge_text.begin(), |
| 269 second_challenge_text.end()); | 269 second_challenge_text.end()); |
| 270 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID, | 270 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID, |
| 271 auth_gssapi.ParseChallenge(&second_challenge)); | 271 auth_gssapi.ParseChallenge(&second_challenge)); |
| 272 } | 272 } |
| 273 | 273 |
| 274 } // namespace net | 274 } // namespace net |
| OLD | NEW |