普通文本  |  90行  |  3.41 KB

//
// Copyright (C) 2013 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include "shill/supplicant/supplicant_eap_state_handler.h"

#include "shill/logging.h"
#include "shill/supplicant/wpa_supplicant.h"

namespace shill {

using std::string;

SupplicantEAPStateHandler::SupplicantEAPStateHandler()
    : is_eap_in_progress_(false) {}

SupplicantEAPStateHandler::~SupplicantEAPStateHandler() {}

bool SupplicantEAPStateHandler::ParseStatus(const string& status,
                                            const string& parameter,
                                            Service::ConnectFailure* failure) {
  if (status == WPASupplicant::kEAPStatusAcceptProposedMethod) {
    LOG(INFO) << "EAP: accepted method " << parameter;
  } else if (status == WPASupplicant::kEAPStatusCompletion) {
    if (parameter == WPASupplicant::kEAPParameterSuccess) {
      LOG(INFO) << "EAP: Completed authentication successfully.";
      is_eap_in_progress_ = false;
      return true;
    } else if (parameter == WPASupplicant::kEAPParameterFailure) {
      // If there was a TLS error, use this instead of the generic failure.
      if (tls_error_ == WPASupplicant::kEAPStatusLocalTLSAlert) {
        *failure = Service::kFailureEAPLocalTLS;
      } else if (tls_error_ ==
                 WPASupplicant::kEAPStatusRemoteTLSAlert) {
        *failure = Service::kFailureEAPRemoteTLS;
      } else {
        *failure = Service::kFailureEAPAuthentication;
      }
    } else {
      LOG(ERROR) << "EAP: Unexpected " << status << " parameter: " << parameter;
    }
  } else if (status == WPASupplicant::kEAPStatusLocalTLSAlert ||
             status == WPASupplicant::kEAPStatusRemoteTLSAlert) {
    tls_error_ = status;
  } else if (status ==
             WPASupplicant::kEAPStatusRemoteCertificateVerification) {
    if (parameter == WPASupplicant::kEAPParameterSuccess) {
      LOG(INFO) << "EAP: Completed remote certificate verification.";
    } else {
      // wpa_supplicant doesn't currently have a verification failure
      // message.  We will instead get a RemoteTLSAlert above.
      LOG(ERROR) << "EAP: Unexpected " << status << " parameter: " << parameter;
    }
  } else if (status == WPASupplicant::kEAPStatusParameterNeeded) {
    if (parameter == WPASupplicant::kEAPRequestedParameterPIN) {
      // wpa_supplicant could have erased the PIN.  Signal to WiFi that
      // it should supply one if possible.
      *failure = Service::kFailurePinMissing;
    } else {
      LOG(ERROR) << "EAP: Authentication aborted due to missing authentication "
                 << "parameter: " << parameter;
      *failure = Service::kFailureEAPAuthentication;
    }
  } else if (status == WPASupplicant::kEAPStatusStarted) {
    LOG(INFO) << "EAP: Authentication starting.";
    is_eap_in_progress_ = true;
  }

  return false;
}

void SupplicantEAPStateHandler::Reset() {
  is_eap_in_progress_ = false;
  tls_error_ = "";
}

}  // namespace shill