OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/protocol/pairing_host_authenticator.h" | 5 #include "remoting/protocol/pairing_host_authenticator.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "remoting/base/constants.h" | 9 #include "remoting/base/constants.h" |
10 #include "remoting/protocol/channel_authenticator.h" | 10 #include "remoting/protocol/channel_authenticator.h" |
11 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" | 11 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" |
12 | 12 |
13 namespace remoting { | 13 namespace remoting { |
14 namespace protocol { | 14 namespace protocol { |
15 | 15 |
16 PairingHostAuthenticator::PairingHostAuthenticator( | 16 PairingHostAuthenticator::PairingHostAuthenticator( |
17 scoped_refptr<PairingRegistry> pairing_registry, | 17 scoped_refptr<PairingRegistry> pairing_registry, |
18 const CreateBaseAuthenticatorCallback& create_base_authenticator_callback, | 18 const CreateBaseAuthenticatorCallback& create_base_authenticator_callback, |
19 const std::string& pin) | 19 const std::string& pin) |
20 : pairing_registry_(pairing_registry), | 20 : pairing_registry_(pairing_registry), |
21 create_base_authenticator_callback_(create_base_authenticator_callback), | 21 create_base_authenticator_callback_(create_base_authenticator_callback), |
22 pin_(pin), | 22 pin_(pin), |
23 weak_factory_(this) {} | 23 weak_factory_(this) {} |
24 | 24 |
| 25 void PairingHostAuthenticator::Initialize( |
| 26 const std::string& client_id, |
| 27 Authenticator::State preferred_initial_state, |
| 28 const base::Closure& resume_callback) { |
| 29 DCHECK(!spake2_authenticator_); |
| 30 |
| 31 if (client_id.empty()) { |
| 32 using_paired_secret_ = false; |
| 33 error_message_ = "client-id-unknown"; |
| 34 spake2_authenticator_ = |
| 35 create_base_authenticator_callback_.Run(pin_, MESSAGE_READY); |
| 36 resume_callback.Run(); |
| 37 return; |
| 38 } |
| 39 |
| 40 using_paired_secret_ = true; |
| 41 waiting_for_paired_secret_ = true; |
| 42 pairing_registry_->GetPairing( |
| 43 client_id, base::Bind(&PairingHostAuthenticator::InitializeWithPairing, |
| 44 weak_factory_.GetWeakPtr(), preferred_initial_state, |
| 45 resume_callback)); |
| 46 } |
| 47 |
25 PairingHostAuthenticator::~PairingHostAuthenticator() {} | 48 PairingHostAuthenticator::~PairingHostAuthenticator() {} |
26 | 49 |
27 Authenticator::State PairingHostAuthenticator::state() const { | 50 Authenticator::State PairingHostAuthenticator::state() const { |
28 if (protocol_error_) { | 51 if (protocol_error_) { |
29 return REJECTED; | 52 return REJECTED; |
30 } else if (waiting_for_paired_secret_) { | 53 } else if (waiting_for_paired_secret_) { |
31 return PROCESSING_MESSAGE; | 54 return PROCESSING_MESSAGE; |
32 } else if (!spake2_authenticator_) { | |
33 return WAITING_MESSAGE; | |
34 } | 55 } |
35 return PairingAuthenticatorBase::state(); | 56 return PairingAuthenticatorBase::state(); |
36 } | 57 } |
37 | 58 |
38 Authenticator::RejectionReason | 59 Authenticator::RejectionReason |
39 PairingHostAuthenticator::rejection_reason() const { | 60 PairingHostAuthenticator::rejection_reason() const { |
40 if (protocol_error_) { | 61 if (protocol_error_) { |
41 return PROTOCOL_ERROR; | 62 return PROTOCOL_ERROR; |
42 } | 63 } |
43 return PairingAuthenticatorBase::rejection_reason(); | 64 return PairingAuthenticatorBase::rejection_reason(); |
44 } | 65 } |
45 | 66 |
46 void PairingHostAuthenticator::CreateSpakeAuthenticatorWithPin( | 67 void PairingHostAuthenticator::CreateSpakeAuthenticatorWithPin( |
47 State initial_state, | 68 State initial_state, |
48 const base::Closure& resume_callback) { | 69 const base::Closure& resume_callback) { |
49 spake2_authenticator_ = | 70 spake2_authenticator_ = |
50 create_base_authenticator_callback_.Run(pin_, initial_state); | 71 create_base_authenticator_callback_.Run(pin_, initial_state); |
51 resume_callback.Run(); | 72 resume_callback.Run(); |
52 } | 73 } |
53 | 74 |
54 void PairingHostAuthenticator::ProcessMessage( | 75 void PairingHostAuthenticator::InitializeWithPairing( |
55 const buzz::XmlElement* message, | 76 Authenticator::State preferred_initial_state, |
56 const base::Closure& resume_callback) { | |
57 if (!spake2_authenticator_) { | |
58 std::string client_id; | |
59 | |
60 const buzz::XmlElement* pairing_tag = message->FirstNamed(kPairingInfoTag); | |
61 if (pairing_tag) { | |
62 client_id = pairing_tag->Attr(kClientIdAttribute); | |
63 } | |
64 | |
65 if (client_id.empty()) { | |
66 LOG(ERROR) << "No client id specified."; | |
67 protocol_error_ = true; | |
68 return; | |
69 } | |
70 | |
71 waiting_for_paired_secret_ = true; | |
72 pairing_registry_->GetPairing( | |
73 client_id, | |
74 base::Bind(&PairingHostAuthenticator::ProcessMessageWithPairing, | |
75 weak_factory_.GetWeakPtr(), | |
76 base::Owned(new buzz::XmlElement(*message)), | |
77 resume_callback)); | |
78 return; | |
79 } | |
80 | |
81 PairingAuthenticatorBase::ProcessMessage(message, resume_callback); | |
82 } | |
83 | |
84 void PairingHostAuthenticator::AddPairingElements(buzz::XmlElement* message) { | |
85 // Nothing to do here | |
86 } | |
87 | |
88 void PairingHostAuthenticator::ProcessMessageWithPairing( | |
89 const buzz::XmlElement* message, | |
90 const base::Closure& resume_callback, | 77 const base::Closure& resume_callback, |
91 PairingRegistry::Pairing pairing) { | 78 PairingRegistry::Pairing pairing) { |
| 79 DCHECK(waiting_for_paired_secret_); |
92 waiting_for_paired_secret_ = false; | 80 waiting_for_paired_secret_ = false; |
93 std::string paired_secret = pairing.shared_secret(); | 81 std::string pairing_secret = pairing.shared_secret(); |
94 if (paired_secret.empty()) { | 82 if (pairing_secret.empty()) { |
95 VLOG(0) << "Unknown client id"; | 83 VLOG(0) << "Unknown client id"; |
96 error_message_ = "unknown-client-id"; | 84 error_message_ = "unknown-client-id"; |
97 } | 85 using_paired_secret_ = false; |
98 | 86 // If pairing wasn't found then always start in the MESSAGE_READY state. |
99 using_paired_secret_ = !paired_secret.empty(); | |
100 if (using_paired_secret_) { | |
101 spake2_authenticator_ = | |
102 create_base_authenticator_callback_.Run(paired_secret, WAITING_MESSAGE); | |
103 PairingAuthenticatorBase::ProcessMessage(message, resume_callback); | |
104 } else { | |
105 spake2_authenticator_ = | 87 spake2_authenticator_ = |
106 create_base_authenticator_callback_.Run(pin_, MESSAGE_READY); | 88 create_base_authenticator_callback_.Run(pin_, MESSAGE_READY); |
107 // The client's optimistic SPAKE message is using a Paired Secret to | 89 } else { |
108 // which the host doesn't have access, so don't bother processing it. | 90 using_paired_secret_ = true; |
109 resume_callback.Run(); | 91 spake2_authenticator_ = create_base_authenticator_callback_.Run( |
| 92 pairing_secret, preferred_initial_state); |
110 } | 93 } |
| 94 resume_callback.Run(); |
111 } | 95 } |
112 | 96 |
113 } // namespace protocol | 97 } // namespace protocol |
114 } // namespace remoting | 98 } // namespace remoting |
OLD | NEW |