1 //
2 // Copyright (C) 2013 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/supplicant/supplicant_eap_state_handler.h"
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include "shill/mock_log.h"
23 #include "shill/supplicant/wpa_supplicant.h"
24
25 using std::string;
26 using testing::_;
27 using testing::EndsWith;
28 using testing::Mock;
29
30 namespace shill {
31
32 class SupplicantEAPStateHandlerTest : public testing::Test {
33 public:
SupplicantEAPStateHandlerTest()34 SupplicantEAPStateHandlerTest() : failure_(Service::kFailureUnknown) {}
~SupplicantEAPStateHandlerTest()35 virtual ~SupplicantEAPStateHandlerTest() {}
36
37 protected:
StartEAP()38 void StartEAP() {
39 EXPECT_CALL(log_, Log(logging::LOG_INFO, _,
40 EndsWith("Authentication starting.")));
41 EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusStarted, "",
42 &failure_));
43 Mock::VerifyAndClearExpectations(&log_);
44 }
45
GetTLSError()46 const string& GetTLSError() { return handler_.tls_error_; }
47
48 SupplicantEAPStateHandler handler_;
49 Service::ConnectFailure failure_;
50 ScopedMockLog log_;
51 };
52
TEST_F(SupplicantEAPStateHandlerTest,Construct)53 TEST_F(SupplicantEAPStateHandlerTest, Construct) {
54 EXPECT_FALSE(handler_.is_eap_in_progress());
55 EXPECT_EQ("", GetTLSError());
56 }
57
TEST_F(SupplicantEAPStateHandlerTest,AuthenticationStarting)58 TEST_F(SupplicantEAPStateHandlerTest, AuthenticationStarting) {
59 StartEAP();
60 EXPECT_TRUE(handler_.is_eap_in_progress());
61 EXPECT_EQ("", GetTLSError());
62 EXPECT_EQ(Service::kFailureUnknown, failure_);
63 }
64
TEST_F(SupplicantEAPStateHandlerTest,AcceptedMethod)65 TEST_F(SupplicantEAPStateHandlerTest, AcceptedMethod) {
66 StartEAP();
67 const string kEAPMethod("EAP-ROCHAMBEAU");
68 EXPECT_CALL(log_, Log(logging::LOG_INFO, _,
69 EndsWith("accepted method " + kEAPMethod)));
70 EXPECT_FALSE(handler_.ParseStatus(
71 WPASupplicant::kEAPStatusAcceptProposedMethod, kEAPMethod, &failure_));
72 EXPECT_TRUE(handler_.is_eap_in_progress());
73 EXPECT_EQ("", GetTLSError());
74 EXPECT_EQ(Service::kFailureUnknown, failure_);
75 }
76
TEST_F(SupplicantEAPStateHandlerTest,SuccessfulCompletion)77 TEST_F(SupplicantEAPStateHandlerTest, SuccessfulCompletion) {
78 StartEAP();
79 EXPECT_CALL(log_, Log(_, _,
80 EndsWith("Completed authentication successfully.")));
81 EXPECT_TRUE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion,
82 WPASupplicant::kEAPParameterSuccess,
83 &failure_));
84 EXPECT_FALSE(handler_.is_eap_in_progress());
85 EXPECT_EQ("", GetTLSError());
86 EXPECT_EQ(Service::kFailureUnknown, failure_);
87 }
88
TEST_F(SupplicantEAPStateHandlerTest,EAPFailureGeneric)89 TEST_F(SupplicantEAPStateHandlerTest, EAPFailureGeneric) {
90 StartEAP();
91 // An EAP failure without a previous TLS indication yields a generic failure.
92 EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion,
93 WPASupplicant::kEAPParameterFailure,
94 &failure_));
95
96 // Since it hasn't completed successfully, we must assume even in failure
97 // that wpa_supplicant is continuing the EAP authentication process.
98 EXPECT_TRUE(handler_.is_eap_in_progress());
99 EXPECT_EQ("", GetTLSError());
100 EXPECT_EQ(Service::kFailureEAPAuthentication, failure_);
101 }
102
TEST_F(SupplicantEAPStateHandlerTest,EAPFailureLocalTLSIndication)103 TEST_F(SupplicantEAPStateHandlerTest, EAPFailureLocalTLSIndication) {
104 StartEAP();
105 // A TLS indication should be stored but a failure should not be returned.
106 EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusLocalTLSAlert, "",
107 &failure_));
108 EXPECT_TRUE(handler_.is_eap_in_progress());
109 EXPECT_EQ(WPASupplicant::kEAPStatusLocalTLSAlert, GetTLSError());
110 EXPECT_EQ(Service::kFailureUnknown, failure_);
111
112 // An EAP failure with a previous TLS indication yields a specific failure.
113 EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion,
114 WPASupplicant::kEAPParameterFailure,
115 &failure_));
116 EXPECT_TRUE(handler_.is_eap_in_progress());
117 EXPECT_EQ(Service::kFailureEAPLocalTLS, failure_);
118 }
119
TEST_F(SupplicantEAPStateHandlerTest,EAPFailureRemoteTLSIndication)120 TEST_F(SupplicantEAPStateHandlerTest, EAPFailureRemoteTLSIndication) {
121 StartEAP();
122 // A TLS indication should be stored but a failure should not be returned.
123 EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusRemoteTLSAlert, "",
124 &failure_));
125 EXPECT_TRUE(handler_.is_eap_in_progress());
126 EXPECT_EQ(WPASupplicant::kEAPStatusRemoteTLSAlert, GetTLSError());
127 EXPECT_EQ(Service::kFailureUnknown, failure_);
128
129 // An EAP failure with a previous TLS indication yields a specific failure.
130 EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion,
131 WPASupplicant::kEAPParameterFailure,
132 &failure_));
133 EXPECT_TRUE(handler_.is_eap_in_progress());
134 EXPECT_EQ(Service::kFailureEAPRemoteTLS, failure_);
135 }
136
137
TEST_F(SupplicantEAPStateHandlerTest,BadRemoteCertificateVerification)138 TEST_F(SupplicantEAPStateHandlerTest, BadRemoteCertificateVerification) {
139 StartEAP();
140 const string kStrangeParameter("ennui");
141 EXPECT_CALL(log_, Log(logging::LOG_ERROR, _, EndsWith(
142 string("Unexpected ") +
143 WPASupplicant::kEAPStatusRemoteCertificateVerification +
144 " parameter: " + kStrangeParameter)));
145 EXPECT_FALSE(handler_.ParseStatus(
146 WPASupplicant::kEAPStatusRemoteCertificateVerification, kStrangeParameter,
147 &failure_));
148 // Although we reported an error, this shouldn't mean failure.
149 EXPECT_TRUE(handler_.is_eap_in_progress());
150 EXPECT_EQ("", GetTLSError());
151 EXPECT_EQ(Service::kFailureUnknown, failure_);
152 }
153
TEST_F(SupplicantEAPStateHandlerTest,ParameterNeeded)154 TEST_F(SupplicantEAPStateHandlerTest, ParameterNeeded) {
155 StartEAP();
156 const string kAuthenticationParameter("nudge nudge say no more");
157 EXPECT_CALL(log_, Log(logging::LOG_ERROR, _, EndsWith(
158 string("aborted due to missing authentication parameter: ") +
159 kAuthenticationParameter)));
160 EXPECT_FALSE(handler_.ParseStatus(
161 WPASupplicant::kEAPStatusParameterNeeded, kAuthenticationParameter,
162 &failure_));
163 EXPECT_TRUE(handler_.is_eap_in_progress());
164 EXPECT_EQ("", GetTLSError());
165 EXPECT_EQ(Service::kFailureEAPAuthentication, failure_);
166 }
167
TEST_F(SupplicantEAPStateHandlerTest,ParameterNeededPin)168 TEST_F(SupplicantEAPStateHandlerTest, ParameterNeededPin) {
169 StartEAP();
170 EXPECT_FALSE(handler_.ParseStatus(
171 WPASupplicant::kEAPStatusParameterNeeded,
172 WPASupplicant::kEAPRequestedParameterPIN,
173 &failure_));
174 EXPECT_TRUE(handler_.is_eap_in_progress());
175 EXPECT_EQ("", GetTLSError());
176 EXPECT_EQ(Service::kFailurePinMissing, failure_);
177 }
178
179 } // namespace shill
180