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 
22 namespace shill {
23 
24 using std::string;
25 
SupplicantEAPStateHandler()26 SupplicantEAPStateHandler::SupplicantEAPStateHandler()
27     : is_eap_in_progress_(false) {}
28 
~SupplicantEAPStateHandler()29 SupplicantEAPStateHandler::~SupplicantEAPStateHandler() {}
30 
ParseStatus(const string & status,const string & parameter,Service::ConnectFailure * failure)31 bool 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 
Reset()84 void SupplicantEAPStateHandler::Reset() {
85   is_eap_in_progress_ = false;
86   tls_error_ = "";
87 }
88 
89 }  // namespace shill
90