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: 34 SupplicantEAPStateHandlerTest() : failure_(Service::kFailureUnknown) {} 35 virtual ~SupplicantEAPStateHandlerTest() {} 36 37 protected: 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 46 const string& GetTLSError() { return handler_.tls_error_; } 47 48 SupplicantEAPStateHandler handler_; 49 Service::ConnectFailure failure_; 50 ScopedMockLog log_; 51 }; 52 53 TEST_F(SupplicantEAPStateHandlerTest, Construct) { 54 EXPECT_FALSE(handler_.is_eap_in_progress()); 55 EXPECT_EQ("", GetTLSError()); 56 } 57 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 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 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 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 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 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 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 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 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