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 "shill/logging.h"
20#include "shill/supplicant/wpa_supplicant.h"
21
22namespace shill {
23
24using std::string;
25
26SupplicantEAPStateHandler::SupplicantEAPStateHandler()
27    : is_eap_in_progress_(false) {}
28
29SupplicantEAPStateHandler::~SupplicantEAPStateHandler() {}
30
31bool SupplicantEAPStateHandler::ParseStatus(const string& status,
32                                            const string& parameter,
33                                            Service::ConnectFailure* failure) {
34  if (status == WPASupplicant::kEAPStatusAcceptProposedMethod) {
35    LOG(INFO) << "EAP: accepted method " << parameter;
36  } else if (status == WPASupplicant::kEAPStatusCompletion) {
37    if (parameter == WPASupplicant::kEAPParameterSuccess) {
38      LOG(INFO) << "EAP: Completed authentication successfully.";
39      is_eap_in_progress_ = false;
40      return true;
41    } else if (parameter == WPASupplicant::kEAPParameterFailure) {
42      // If there was a TLS error, use this instead of the generic failure.
43      if (tls_error_ == WPASupplicant::kEAPStatusLocalTLSAlert) {
44        *failure = Service::kFailureEAPLocalTLS;
45      } else if (tls_error_ ==
46                 WPASupplicant::kEAPStatusRemoteTLSAlert) {
47        *failure = Service::kFailureEAPRemoteTLS;
48      } else {
49        *failure = Service::kFailureEAPAuthentication;
50      }
51    } else {
52      LOG(ERROR) << "EAP: Unexpected " << status << " parameter: " << parameter;
53    }
54  } else if (status == WPASupplicant::kEAPStatusLocalTLSAlert ||
55             status == WPASupplicant::kEAPStatusRemoteTLSAlert) {
56    tls_error_ = status;
57  } else if (status ==
58             WPASupplicant::kEAPStatusRemoteCertificateVerification) {
59    if (parameter == WPASupplicant::kEAPParameterSuccess) {
60      LOG(INFO) << "EAP: Completed remote certificate verification.";
61    } else {
62      // wpa_supplicant doesn't currently have a verification failure
63      // message.  We will instead get a RemoteTLSAlert above.
64      LOG(ERROR) << "EAP: Unexpected " << status << " parameter: " << parameter;
65    }
66  } else if (status == WPASupplicant::kEAPStatusParameterNeeded) {
67    if (parameter == WPASupplicant::kEAPRequestedParameterPIN) {
68      // wpa_supplicant could have erased the PIN.  Signal to WiFi that
69      // it should supply one if possible.
70      *failure = Service::kFailurePinMissing;
71    } else {
72      LOG(ERROR) << "EAP: Authentication aborted due to missing authentication "
73                 << "parameter: " << parameter;
74      *failure = Service::kFailureEAPAuthentication;
75    }
76  } else if (status == WPASupplicant::kEAPStatusStarted) {
77    LOG(INFO) << "EAP: Authentication starting.";
78    is_eap_in_progress_ = true;
79  }
80
81  return false;
82}
83
84void SupplicantEAPStateHandler::Reset() {
85  is_eap_in_progress_ = false;
86  tls_error_ = "";
87}
88
89}  // namespace shill
90