| // Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "shill/supplicant_eap_state_handler.h" |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| #include "shill/mock_log.h" |
| #include "shill/wpa_supplicant.h" |
| |
| using std::string; |
| using testing::_; |
| using testing::EndsWith; |
| using testing::Mock; |
| |
| namespace shill { |
| |
| class SupplicantEAPStateHandlerTest : public testing::Test { |
| public: |
| SupplicantEAPStateHandlerTest() : failure_(Service::kFailureUnknown) {} |
| virtual ~SupplicantEAPStateHandlerTest() {} |
| |
| protected: |
| void StartEAP() { |
| EXPECT_CALL(log_, Log(logging::LOG_INFO, _, |
| EndsWith("Authentication starting."))); |
| EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusStarted, "", |
| &failure_)); |
| Mock::VerifyAndClearExpectations(&log_); |
| } |
| |
| const string &GetTLSError() { return handler_.tls_error_; } |
| |
| SupplicantEAPStateHandler handler_; |
| Service::ConnectFailure failure_; |
| ScopedMockLog log_; |
| }; |
| |
| TEST_F(SupplicantEAPStateHandlerTest, Construct) { |
| EXPECT_FALSE(handler_.is_eap_in_progress()); |
| EXPECT_EQ("", GetTLSError()); |
| } |
| |
| TEST_F(SupplicantEAPStateHandlerTest, AuthenticationStarting) { |
| StartEAP(); |
| EXPECT_TRUE(handler_.is_eap_in_progress()); |
| EXPECT_EQ("", GetTLSError()); |
| EXPECT_EQ(Service::kFailureUnknown, failure_); |
| } |
| |
| TEST_F(SupplicantEAPStateHandlerTest, AcceptedMethod) { |
| StartEAP(); |
| const string kEAPMethod("EAP-ROCHAMBEAU"); |
| EXPECT_CALL(log_, Log(logging::LOG_INFO, _, |
| EndsWith("accepted method " + kEAPMethod))); |
| EXPECT_FALSE(handler_.ParseStatus( |
| WPASupplicant::kEAPStatusAcceptProposedMethod, kEAPMethod, &failure_)); |
| EXPECT_TRUE(handler_.is_eap_in_progress()); |
| EXPECT_EQ("", GetTLSError()); |
| EXPECT_EQ(Service::kFailureUnknown, failure_); |
| } |
| |
| TEST_F(SupplicantEAPStateHandlerTest, SuccessfulCompletion) { |
| StartEAP(); |
| EXPECT_CALL(log_, Log(_, _, |
| EndsWith("Completed authentication successfully."))); |
| EXPECT_TRUE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion, |
| WPASupplicant::kEAPParameterSuccess, |
| &failure_)); |
| EXPECT_FALSE(handler_.is_eap_in_progress()); |
| EXPECT_EQ("", GetTLSError()); |
| EXPECT_EQ(Service::kFailureUnknown, failure_); |
| } |
| |
| TEST_F(SupplicantEAPStateHandlerTest, EAPFailureGeneric) { |
| StartEAP(); |
| // An EAP failure without a previous TLS indication yields a generic failure. |
| EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion, |
| WPASupplicant::kEAPParameterFailure, |
| &failure_)); |
| |
| // Since it hasn't completed successfully, we must assume even in failure |
| // that wpa_supplicant is continuing the EAP authentication process. |
| EXPECT_TRUE(handler_.is_eap_in_progress()); |
| EXPECT_EQ("", GetTLSError()); |
| EXPECT_EQ(Service::kFailureEAPAuthentication, failure_); |
| } |
| |
| TEST_F(SupplicantEAPStateHandlerTest, EAPFailureLocalTLSIndication) { |
| StartEAP(); |
| // A TLS indication should be stored but a failure should not be returned. |
| EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusLocalTLSAlert, "", |
| &failure_)); |
| EXPECT_TRUE(handler_.is_eap_in_progress()); |
| EXPECT_EQ(WPASupplicant::kEAPStatusLocalTLSAlert, GetTLSError()); |
| EXPECT_EQ(Service::kFailureUnknown, failure_); |
| |
| // An EAP failure with a previous TLS indication yields a specific failure. |
| EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion, |
| WPASupplicant::kEAPParameterFailure, |
| &failure_)); |
| EXPECT_TRUE(handler_.is_eap_in_progress()); |
| EXPECT_EQ(Service::kFailureEAPLocalTLS, failure_); |
| } |
| |
| TEST_F(SupplicantEAPStateHandlerTest, EAPFailureRemoteTLSIndication) { |
| StartEAP(); |
| // A TLS indication should be stored but a failure should not be returned. |
| EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusRemoteTLSAlert, "", |
| &failure_)); |
| EXPECT_TRUE(handler_.is_eap_in_progress()); |
| EXPECT_EQ(WPASupplicant::kEAPStatusRemoteTLSAlert, GetTLSError()); |
| EXPECT_EQ(Service::kFailureUnknown, failure_); |
| |
| // An EAP failure with a previous TLS indication yields a specific failure. |
| EXPECT_FALSE(handler_.ParseStatus(WPASupplicant::kEAPStatusCompletion, |
| WPASupplicant::kEAPParameterFailure, |
| &failure_)); |
| EXPECT_TRUE(handler_.is_eap_in_progress()); |
| EXPECT_EQ(Service::kFailureEAPRemoteTLS, failure_); |
| } |
| |
| |
| TEST_F(SupplicantEAPStateHandlerTest, BadRemoteCertificateVerification) { |
| StartEAP(); |
| const string kStrangeParameter("ennui"); |
| EXPECT_CALL(log_, Log(logging::LOG_ERROR, _,EndsWith( |
| string("Unexpected ") + |
| WPASupplicant::kEAPStatusRemoteCertificateVerification + |
| " parameter: " + kStrangeParameter))); |
| EXPECT_FALSE(handler_.ParseStatus( |
| WPASupplicant::kEAPStatusRemoteCertificateVerification, kStrangeParameter, |
| &failure_)); |
| // Although we reported an error, this shouldn't mean failure. |
| EXPECT_TRUE(handler_.is_eap_in_progress()); |
| EXPECT_EQ("", GetTLSError()); |
| EXPECT_EQ(Service::kFailureUnknown, failure_); |
| } |
| |
| TEST_F(SupplicantEAPStateHandlerTest, ParameterNeeded) { |
| StartEAP(); |
| const string kAuthenticationParameter("nudge nudge say no more"); |
| EXPECT_CALL(log_, Log(logging::LOG_ERROR, _,EndsWith( |
| string("aborted due to missing authentication parameter: ") + |
| kAuthenticationParameter))); |
| EXPECT_FALSE(handler_.ParseStatus( |
| WPASupplicant::kEAPStatusParameterNeeded, kAuthenticationParameter, |
| &failure_)); |
| EXPECT_TRUE(handler_.is_eap_in_progress()); |
| EXPECT_EQ("", GetTLSError()); |
| EXPECT_EQ(Service::kFailureEAPAuthentication, failure_); |
| } |
| |
| } // namespace shill |