blob: 7416209f6ae79097141e73325771a5bd45f89e1a [file] [log] [blame]
// 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_);
}
TEST_F(SupplicantEAPStateHandlerTest, ParameterNeededPin) {
StartEAP();
EXPECT_FALSE(handler_.ParseStatus(
WPASupplicant::kEAPStatusParameterNeeded,
WPASupplicant::kEAPRequestedParameterPIN,
&failure_));
EXPECT_TRUE(handler_.is_eap_in_progress());
EXPECT_EQ("", GetTLSError());
EXPECT_EQ(Service::kFailurePinMissing, failure_);
}
} // namespace shill