blob: 7e06ae0d83ddbc64fbb0019cf807a90b55522163 [file] [log] [blame]
[email protected]6434bfe2013-05-22 09:00:231// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "remoting/protocol/pairing_host_authenticator.h"
6
7#include "base/bind.h"
8#include "base/logging.h"
9#include "remoting/base/constants.h"
10#include "remoting/base/rsa_key_pair.h"
11#include "remoting/protocol/channel_authenticator.h"
[email protected]6434bfe2013-05-22 09:00:2312#include "remoting/protocol/v2_authenticator.h"
13#include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
14
15namespace remoting {
16namespace protocol {
17
18PairingHostAuthenticator::PairingHostAuthenticator(
19 scoped_refptr<PairingRegistry> pairing_registry,
20 const std::string& local_cert,
21 scoped_refptr<RsaKeyPair> key_pair,
22 const std::string& pin)
23 : pairing_registry_(pairing_registry),
24 local_cert_(local_cert),
25 key_pair_(key_pair),
26 pin_(pin),
27 protocol_error_(false),
[email protected]40dade32013-06-14 07:08:1128 waiting_for_paired_secret_(false),
[email protected]6434bfe2013-05-22 09:00:2329 weak_factory_(this) {
30}
31
32PairingHostAuthenticator::~PairingHostAuthenticator() {
33}
34
35Authenticator::State PairingHostAuthenticator::state() const {
36 if (protocol_error_) {
37 return REJECTED;
[email protected]40dade32013-06-14 07:08:1138 } else if (waiting_for_paired_secret_) {
39 return PROCESSING_MESSAGE;
[email protected]6434bfe2013-05-22 09:00:2340 } else if (!v2_authenticator_) {
41 return WAITING_MESSAGE;
42 }
43 return PairingAuthenticatorBase::state();
44}
45
46Authenticator::RejectionReason
47PairingHostAuthenticator::rejection_reason() const {
48 if (protocol_error_) {
49 return PROTOCOL_ERROR;
50 }
51 return PairingAuthenticatorBase::rejection_reason();
52}
53
54void PairingHostAuthenticator::CreateV2AuthenticatorWithPIN(
55 State initial_state,
56 const SetAuthenticatorCallback& callback) {
57 callback.Run(V2Authenticator::CreateForHost(
58 local_cert_, key_pair_, pin_, initial_state));
59}
60
61void PairingHostAuthenticator::ProcessMessage(
62 const buzz::XmlElement* message,
63 const base::Closure& resume_callback) {
64 if (!v2_authenticator_) {
65 std::string client_id;
[email protected]6434bfe2013-05-22 09:00:2366
67 const buzz::XmlElement* pairing_tag = message->FirstNamed(kPairingInfoTag);
68 if (pairing_tag) {
69 client_id = pairing_tag->Attr(kClientIdAttribute);
70 }
71
72 if (client_id.empty()) {
73 LOG(ERROR) << "No client id specified.";
74 protocol_error_ = true;
75 } else {
[email protected]40dade32013-06-14 07:08:1176 waiting_for_paired_secret_ = true;
77 pairing_registry_->GetPairing(
78 client_id,
79 base::Bind(&PairingHostAuthenticator::ProcessMessageWithPairing,
80 weak_factory_.GetWeakPtr(),
81 base::Owned(new buzz::XmlElement(*message)),
82 resume_callback));
[email protected]6434bfe2013-05-22 09:00:2383 return;
84 }
85 }
86
87 PairingAuthenticatorBase::ProcessMessage(message, resume_callback);
88}
89
90void PairingHostAuthenticator::AddPairingElements(buzz::XmlElement* message) {
91 // Nothing to do here
92}
93
[email protected]40dade32013-06-14 07:08:1194void PairingHostAuthenticator::ProcessMessageWithPairing(
95 const buzz::XmlElement* message,
96 const base::Closure& resume_callback,
97 PairingRegistry::Pairing pairing) {
98 waiting_for_paired_secret_ = false;
[email protected]df5189f2013-06-18 12:12:0599 std::string paired_secret = pairing.shared_secret();
[email protected]40dade32013-06-14 07:08:11100 if (paired_secret.empty()) {
[email protected]5cbe3cf2013-11-25 17:05:04101 VLOG(0) << "Unknown client id";
[email protected]40dade32013-06-14 07:08:11102 error_message_ = "unknown-client-id";
103 }
104
105 using_paired_secret_ = !paired_secret.empty();
106 if (using_paired_secret_) {
107 v2_authenticator_ = V2Authenticator::CreateForHost(
108 local_cert_, key_pair_, paired_secret, WAITING_MESSAGE);
109 PairingAuthenticatorBase::ProcessMessage(message, resume_callback);
110 } else {
111 v2_authenticator_ = V2Authenticator::CreateForHost(
112 local_cert_, key_pair_, pin_, MESSAGE_READY);
113 // The client's optimistic SPAKE message is using a Paired Secret to
114 // which the host doesn't have access, so don't bother processing it.
115 resume_callback.Run();
116 }
117}
118
[email protected]6434bfe2013-05-22 09:00:23119} // namespace protocol
120} // namespace remoting