Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / remoting / protocol / me2me_host_authenticator_factory.cc
blob4b07d83b0316d0448e0f20e67968a51f50bc1ec5
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 "remoting/signaling/jid_util.h"
14 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h"
16 namespace remoting {
17 namespace protocol {
19 namespace {
21 // Authenticator that accepts one message and rejects connection after that.
22 class RejectingAuthenticator : public Authenticator {
23 public:
24 RejectingAuthenticator()
25 : state_(WAITING_MESSAGE) {
27 ~RejectingAuthenticator() override {}
29 State state() const override { return state_; }
31 bool started() const override { return true; }
33 RejectionReason rejection_reason() const override {
34 DCHECK_EQ(state_, REJECTED);
35 return INVALID_CREDENTIALS;
38 void ProcessMessage(const buzz::XmlElement* message,
39 const base::Closure& resume_callback) override {
40 DCHECK_EQ(state_, WAITING_MESSAGE);
41 state_ = REJECTED;
42 resume_callback.Run();
45 scoped_ptr<buzz::XmlElement> GetNextMessage() override {
46 NOTREACHED();
47 return nullptr;
50 scoped_ptr<ChannelAuthenticator> CreateChannelAuthenticator() const override {
51 NOTREACHED();
52 return nullptr;
55 protected:
56 State state_;
59 } // namespace
61 // static
62 scoped_ptr<AuthenticatorFactory>
63 Me2MeHostAuthenticatorFactory::CreateWithSharedSecret(
64 bool use_service_account,
65 const std::string& host_owner,
66 const std::string& local_cert,
67 scoped_refptr<RsaKeyPair> key_pair,
68 const SharedSecretHash& shared_secret_hash,
69 scoped_refptr<PairingRegistry> pairing_registry) {
70 scoped_ptr<Me2MeHostAuthenticatorFactory> result(
71 new Me2MeHostAuthenticatorFactory());
72 result->use_service_account_ = use_service_account;
73 result->host_owner_ = host_owner;
74 result->local_cert_ = local_cert;
75 result->key_pair_ = key_pair;
76 result->shared_secret_hash_ = shared_secret_hash;
77 result->pairing_registry_ = pairing_registry;
78 return result.Pass();
82 // static
83 scoped_ptr<AuthenticatorFactory>
84 Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth(
85 bool use_service_account,
86 const std::string& host_owner,
87 const std::string& local_cert,
88 scoped_refptr<RsaKeyPair> key_pair,
89 scoped_ptr<TokenValidatorFactory>
90 token_validator_factory) {
91 scoped_ptr<Me2MeHostAuthenticatorFactory> result(
92 new Me2MeHostAuthenticatorFactory());
93 result->use_service_account_ = use_service_account;
94 result->host_owner_ = host_owner;
95 result->local_cert_ = local_cert;
96 result->key_pair_ = key_pair;
97 result->token_validator_factory_ = token_validator_factory.Pass();
98 return result.Pass();
101 Me2MeHostAuthenticatorFactory::Me2MeHostAuthenticatorFactory() {
104 Me2MeHostAuthenticatorFactory::~Me2MeHostAuthenticatorFactory() {
107 scoped_ptr<Authenticator> Me2MeHostAuthenticatorFactory::CreateAuthenticator(
108 const std::string& local_jid,
109 const std::string& remote_jid,
110 const buzz::XmlElement* first_message) {
112 std::string remote_jid_prefix;
114 if (!use_service_account_) {
115 // JID prefixes may not match the host owner email, for example, in cases
116 // where the host owner account does not have an email associated with it.
117 // In those cases, the only guarantee we have is that JIDs for the same
118 // account will have the same prefix.
119 if (!SplitJidResource(local_jid, &remote_jid_prefix, nullptr)) {
120 LOG(DFATAL) << "Invalid local JID:" << local_jid;
121 return make_scoped_ptr(new RejectingAuthenticator());
123 } else {
124 // TODO(rmsousa): This only works for cases where the JID prefix matches
125 // the host owner email. Figure out a way to verify the JID in other cases.
126 remote_jid_prefix = host_owner_;
129 // Verify that the client's jid is an ASCII string, and then check that the
130 // client JID has the expected prefix. Comparison is case insensitive.
131 if (!base::IsStringASCII(remote_jid) ||
132 !base::StartsWith(remote_jid, remote_jid_prefix + '/',
133 base::CompareCase::INSENSITIVE_ASCII)) {
134 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid;
135 return make_scoped_ptr(new RejectingAuthenticator());
138 if (!local_cert_.empty() && key_pair_.get()) {
139 if (token_validator_factory_) {
140 return NegotiatingHostAuthenticator::CreateWithThirdPartyAuth(
141 local_cert_, key_pair_,
142 token_validator_factory_->CreateTokenValidator(
143 local_jid, remote_jid));
146 return NegotiatingHostAuthenticator::CreateWithSharedSecret(
147 local_cert_, key_pair_, shared_secret_hash_.value,
148 shared_secret_hash_.hash_function, pairing_registry_);
151 return make_scoped_ptr(new RejectingAuthenticator());
154 } // namespace protocol
155 } // namespace remoting