blob: 586822d2ef774862c5317300a433813a90252e12 [file] [log] [blame]
[email protected]f3cf9802011-10-28 18:44:581// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]7da0b332010-01-08 14:56:562// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/basictypes.h"
[email protected]7c46fa572010-02-25 16:05:346#include "net/base/net_errors.h"
[email protected]df41d0d82014-03-13 00:43:247#include "net/http/http_auth_challenge_tokenizer.h"
[email protected]7da0b332010-01-08 14:56:568#include "net/http/http_auth_sspi_win.h"
[email protected]5c2471b2010-04-20 17:25:099#include "net/http/mock_sspi_library_win.h"
[email protected]7da0b332010-01-08 14:56:5610#include "testing/gtest/include/gtest/gtest.h"
11
12namespace net {
13
[email protected]7c46fa572010-02-25 16:05:3414namespace {
15
[email protected]7da0b332010-01-08 14:56:5616void MatchDomainUserAfterSplit(const std::wstring& combined,
17 const std::wstring& expected_domain,
18 const std::wstring& expected_user) {
19 std::wstring actual_domain;
20 std::wstring actual_user;
21 SplitDomainAndUser(combined, &actual_domain, &actual_user);
22 EXPECT_EQ(expected_domain, actual_domain);
23 EXPECT_EQ(expected_user, actual_user);
24}
25
[email protected]eca50e122010-09-11 14:03:3026const ULONG kMaxTokenLength = 100;
27
[email protected]7c46fa572010-02-25 16:05:3428} // namespace
29
30TEST(HttpAuthSSPITest, SplitUserAndDomain) {
[email protected]7da0b332010-01-08 14:56:5631 MatchDomainUserAfterSplit(L"foobar", L"", L"foobar");
32 MatchDomainUserAfterSplit(L"FOO\\bar", L"FOO", L"bar");
33}
34
[email protected]7c46fa572010-02-25 16:05:3435TEST(HttpAuthSSPITest, DetermineMaxTokenLength_Normal) {
36 SecPkgInfoW package_info;
37 memset(&package_info, 0x0, sizeof(package_info));
38 package_info.cbMaxToken = 1337;
39
[email protected]5c2471b2010-04-20 17:25:0940 MockSSPILibrary mock_library;
[email protected]7c46fa572010-02-25 16:05:3441 mock_library.ExpectQuerySecurityPackageInfo(L"NTLM", SEC_E_OK, &package_info);
[email protected]eca50e122010-09-11 14:03:3042 ULONG max_token_length = kMaxTokenLength;
[email protected]7c46fa572010-02-25 16:05:3443 int rv = DetermineMaxTokenLength(&mock_library, L"NTLM", &max_token_length);
44 EXPECT_EQ(OK, rv);
45 EXPECT_EQ(1337, max_token_length);
46}
47
48TEST(HttpAuthSSPITest, DetermineMaxTokenLength_InvalidPackage) {
[email protected]5c2471b2010-04-20 17:25:0949 MockSSPILibrary mock_library;
[email protected]7c46fa572010-02-25 16:05:3450 mock_library.ExpectQuerySecurityPackageInfo(L"Foo", SEC_E_SECPKG_NOT_FOUND,
51 NULL);
[email protected]eca50e122010-09-11 14:03:3052 ULONG max_token_length = kMaxTokenLength;
[email protected]7c46fa572010-02-25 16:05:3453 int rv = DetermineMaxTokenLength(&mock_library, L"Foo", &max_token_length);
54 EXPECT_EQ(ERR_UNSUPPORTED_AUTH_SCHEME, rv);
55 // |DetermineMaxTokenLength()| interface states that |max_token_length| should
56 // not change on failure.
57 EXPECT_EQ(100, max_token_length);
58}
59
[email protected]eca50e122010-09-11 14:03:3060TEST(HttpAuthSSPITest, ParseChallenge_FirstRound) {
61 // The first round should just consist of an unadorned "Negotiate" header.
62 MockSSPILibrary mock_library;
63 HttpAuthSSPI auth_sspi(&mock_library, "Negotiate",
64 NEGOSSP_NAME, kMaxTokenLength);
65 std::string challenge_text = "Negotiate";
[email protected]df41d0d82014-03-13 00:43:2466 HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
67 challenge_text.end());
[email protected]eca50e122010-09-11 14:03:3068 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
69 auth_sspi.ParseChallenge(&challenge));
70}
71
72TEST(HttpAuthSSPITest, ParseChallenge_TwoRounds) {
73 // The first round should just have "Negotiate", and the second round should
74 // have a valid base64 token associated with it.
75 MockSSPILibrary mock_library;
76 HttpAuthSSPI auth_sspi(&mock_library, "Negotiate",
77 NEGOSSP_NAME, kMaxTokenLength);
78 std::string first_challenge_text = "Negotiate";
[email protected]df41d0d82014-03-13 00:43:2479 HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
80 first_challenge_text.end());
[email protected]eca50e122010-09-11 14:03:3081 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
82 auth_sspi.ParseChallenge(&first_challenge));
83
84 // Generate an auth token and create another thing.
85 std::string auth_token;
[email protected]bc4e5512013-12-06 07:18:4986 EXPECT_EQ(OK, auth_sspi.GenerateAuthToken(NULL, "HTTP/intranet.google.com",
[email protected]eca50e122010-09-11 14:03:3087 &auth_token));
88
89 std::string second_challenge_text = "Negotiate Zm9vYmFy";
[email protected]df41d0d82014-03-13 00:43:2490 HttpAuthChallengeTokenizer second_challenge(second_challenge_text.begin(),
91 second_challenge_text.end());
[email protected]eca50e122010-09-11 14:03:3092 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
93 auth_sspi.ParseChallenge(&second_challenge));
94}
95
96TEST(HttpAuthSSPITest, ParseChallenge_UnexpectedTokenFirstRound) {
97 // If the first round challenge has an additional authentication token, it
98 // should be treated as an invalid challenge from the server.
99 MockSSPILibrary mock_library;
100 HttpAuthSSPI auth_sspi(&mock_library, "Negotiate",
101 NEGOSSP_NAME, kMaxTokenLength);
102 std::string challenge_text = "Negotiate Zm9vYmFy";
[email protected]df41d0d82014-03-13 00:43:24103 HttpAuthChallengeTokenizer challenge(challenge_text.begin(),
104 challenge_text.end());
[email protected]eca50e122010-09-11 14:03:30105 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID,
106 auth_sspi.ParseChallenge(&challenge));
107}
108
109TEST(HttpAuthSSPITest, ParseChallenge_MissingTokenSecondRound) {
110 // If a later-round challenge is simply "Negotiate", it should be treated as
111 // an authentication challenge rejection from the server or proxy.
112 MockSSPILibrary mock_library;
113 HttpAuthSSPI auth_sspi(&mock_library, "Negotiate",
114 NEGOSSP_NAME, kMaxTokenLength);
115 std::string first_challenge_text = "Negotiate";
[email protected]df41d0d82014-03-13 00:43:24116 HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
117 first_challenge_text.end());
[email protected]eca50e122010-09-11 14:03:30118 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
119 auth_sspi.ParseChallenge(&first_challenge));
120
121 std::string auth_token;
[email protected]bc4e5512013-12-06 07:18:49122 EXPECT_EQ(OK, auth_sspi.GenerateAuthToken(NULL, "HTTP/intranet.google.com",
[email protected]eca50e122010-09-11 14:03:30123 &auth_token));
124 std::string second_challenge_text = "Negotiate";
[email protected]df41d0d82014-03-13 00:43:24125 HttpAuthChallengeTokenizer second_challenge(second_challenge_text.begin(),
126 second_challenge_text.end());
[email protected]eca50e122010-09-11 14:03:30127 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_REJECT,
128 auth_sspi.ParseChallenge(&second_challenge));
129}
130
131TEST(HttpAuthSSPITest, ParseChallenge_NonBase64EncodedToken) {
132 // If a later-round challenge has an invalid base64 encoded token, it should
133 // be treated as an invalid challenge.
134 MockSSPILibrary mock_library;
135 HttpAuthSSPI auth_sspi(&mock_library, "Negotiate",
136 NEGOSSP_NAME, kMaxTokenLength);
137 std::string first_challenge_text = "Negotiate";
[email protected]df41d0d82014-03-13 00:43:24138 HttpAuthChallengeTokenizer first_challenge(first_challenge_text.begin(),
139 first_challenge_text.end());
[email protected]eca50e122010-09-11 14:03:30140 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_ACCEPT,
141 auth_sspi.ParseChallenge(&first_challenge));
142
143 std::string auth_token;
[email protected]bc4e5512013-12-06 07:18:49144 EXPECT_EQ(OK, auth_sspi.GenerateAuthToken(NULL, "HTTP/intranet.google.com",
[email protected]eca50e122010-09-11 14:03:30145 &auth_token));
146 std::string second_challenge_text = "Negotiate =happyjoy=";
[email protected]df41d0d82014-03-13 00:43:24147 HttpAuthChallengeTokenizer second_challenge(second_challenge_text.begin(),
148 second_challenge_text.end());
[email protected]eca50e122010-09-11 14:03:30149 EXPECT_EQ(HttpAuth::AUTHORIZATION_RESULT_INVALID,
150 auth_sspi.ParseChallenge(&second_challenge));
151}
152
[email protected]7da0b332010-01-08 14:56:56153} // namespace net