Fix an issue that a browser seek is requested after decoder draining is interrupted.
[chromium-blink-merge.git] / remoting / protocol / me2me_host_authenticator_factory.cc
blob422a2bb29a2a4c21f79e8dd7b50a14aa935b720f
1 // Copyright (c) 2012 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.
5 #include "remoting/protocol/me2me_host_authenticator_factory.h"
7 #include "base/base64.h"
8 #include "base/strings/string_util.h"
9 #include "remoting/base/rsa_key_pair.h"
10 #include "remoting/protocol/channel_authenticator.h"
11 #include "remoting/protocol/negotiating_host_authenticator.h"
12 #include "remoting/protocol/token_validator.h"
13 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
15 namespace remoting {
16 namespace protocol {
18 namespace {
20 // Authenticator that accepts one message and rejects connection after that.
21 class RejectingAuthenticator : public Authenticator {
22 public:
23 RejectingAuthenticator()
24 : state_(WAITING_MESSAGE) {
26 ~RejectingAuthenticator() override {}
28 State state() const override { return state_; }
30 bool started() const override { return true; }
32 RejectionReason rejection_reason() const override {
33 DCHECK_EQ(state_, REJECTED);
34 return INVALID_CREDENTIALS;
37 void ProcessMessage(const buzz::XmlElement* message,
38 const base::Closure& resume_callback) override {
39 DCHECK_EQ(state_, WAITING_MESSAGE);
40 state_ = REJECTED;
41 resume_callback.Run();
44 scoped_ptr<buzz::XmlElement> GetNextMessage() override {
45 NOTREACHED();
46 return nullptr;
49 scoped_ptr<ChannelAuthenticator> CreateChannelAuthenticator() const override {
50 NOTREACHED();
51 return nullptr;
54 protected:
55 State state_;
58 } // namespace
60 // static
61 scoped_ptr<AuthenticatorFactory>
62 Me2MeHostAuthenticatorFactory::CreateWithSharedSecret(
63 bool use_service_account,
64 const std::string& host_owner,
65 const std::string& local_cert,
66 scoped_refptr<RsaKeyPair> key_pair,
67 const SharedSecretHash& shared_secret_hash,
68 scoped_refptr<PairingRegistry> pairing_registry) {
69 scoped_ptr<Me2MeHostAuthenticatorFactory> result(
70 new Me2MeHostAuthenticatorFactory());
71 result->use_service_account_ = use_service_account;
72 result->host_owner_ = host_owner;
73 result->local_cert_ = local_cert;
74 result->key_pair_ = key_pair;
75 result->shared_secret_hash_ = shared_secret_hash;
76 result->pairing_registry_ = pairing_registry;
77 return result.Pass();
81 // static
82 scoped_ptr<AuthenticatorFactory>
83 Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth(
84 bool use_service_account,
85 const std::string& host_owner,
86 const std::string& local_cert,
87 scoped_refptr<RsaKeyPair> key_pair,
88 scoped_ptr<TokenValidatorFactory>
89 token_validator_factory) {
90 scoped_ptr<Me2MeHostAuthenticatorFactory> result(
91 new Me2MeHostAuthenticatorFactory());
92 result->use_service_account_ = use_service_account;
93 result->host_owner_ = host_owner;
94 result->local_cert_ = local_cert;
95 result->key_pair_ = key_pair;
96 result->token_validator_factory_ = token_validator_factory.Pass();
97 return result.Pass();
100 // static
101 scoped_ptr<AuthenticatorFactory>
102 Me2MeHostAuthenticatorFactory::CreateRejecting() {
103 return make_scoped_ptr(new Me2MeHostAuthenticatorFactory());
106 Me2MeHostAuthenticatorFactory::Me2MeHostAuthenticatorFactory() {
109 Me2MeHostAuthenticatorFactory::~Me2MeHostAuthenticatorFactory() {
112 scoped_ptr<Authenticator> Me2MeHostAuthenticatorFactory::CreateAuthenticator(
113 const std::string& local_jid,
114 const std::string& remote_jid,
115 const buzz::XmlElement* first_message) {
117 std::string remote_jid_prefix;
119 if (!use_service_account_) {
120 // JID prefixes may not match the host owner email, for example, in cases
121 // where the host owner account does not have an email associated with it.
122 // In those cases, the only guarantee we have is that JIDs for the same
123 // account will have the same prefix.
124 size_t slash_pos = local_jid.find('/');
125 if (slash_pos == std::string::npos) {
126 LOG(DFATAL) << "Invalid local JID:" << local_jid;
127 return make_scoped_ptr(new RejectingAuthenticator());
129 remote_jid_prefix = local_jid.substr(0, slash_pos);
130 } else {
131 // TODO(rmsousa): This only works for cases where the JID prefix matches
132 // the host owner email. Figure out a way to verify the JID in other cases.
133 remote_jid_prefix = host_owner_;
136 // Verify that the client's jid is an ASCII string, and then check that the
137 // client JID has the expected prefix. Comparison is case insensitive.
138 if (!base::IsStringASCII(remote_jid) ||
139 !StartsWithASCII(remote_jid, remote_jid_prefix + '/', false)) {
140 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid;
141 return make_scoped_ptr(new RejectingAuthenticator());
144 if (!local_cert_.empty() && key_pair_.get()) {
145 if (token_validator_factory_) {
146 return NegotiatingHostAuthenticator::CreateWithThirdPartyAuth(
147 local_cert_, key_pair_,
148 token_validator_factory_->CreateTokenValidator(
149 local_jid, remote_jid));
152 return NegotiatingHostAuthenticator::CreateWithSharedSecret(
153 local_cert_, key_pair_, shared_secret_hash_.value,
154 shared_secret_hash_.hash_function, pairing_registry_);
157 return make_scoped_ptr(new RejectingAuthenticator());
160 } // namespace protocol
161 } // namespace remoting