Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / remoting / protocol / me2me_host_authenticator_factory.cc
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.
4
5 #include "remoting/protocol/me2me_host_authenticator_factory.h"
6
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"
14
15 namespace remoting {
16 namespace protocol {
17
18 namespace {
19
20 // Authenticator that accepts one message and rejects connection after that.
21 class RejectingAuthenticator : public Authenticator {
22  public:
23   RejectingAuthenticator()
24       : state_(WAITING_MESSAGE) {
25   }
26   ~RejectingAuthenticator() override {}
27
28   State state() const override { return state_; }
29
30   bool started() const override { return true; }
31
32   RejectionReason rejection_reason() const override {
33     DCHECK_EQ(state_, REJECTED);
34     return INVALID_CREDENTIALS;
35   }
36
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();
42   }
43
44   scoped_ptr<buzz::XmlElement> GetNextMessage() override {
45     NOTREACHED();
46     return nullptr;
47   }
48
49   scoped_ptr<ChannelAuthenticator> CreateChannelAuthenticator() const override {
50     NOTREACHED();
51     return nullptr;
52   }
53
54  protected:
55   State state_;
56 };
57
58 }  // namespace
59
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();
78 }
79
80
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();
98 }
99
100 // static
101 scoped_ptr<AuthenticatorFactory>
102     Me2MeHostAuthenticatorFactory::CreateRejecting() {
103   return make_scoped_ptr(new Me2MeHostAuthenticatorFactory());
104 }
105
106 Me2MeHostAuthenticatorFactory::Me2MeHostAuthenticatorFactory() {
107 }
108
109 Me2MeHostAuthenticatorFactory::~Me2MeHostAuthenticatorFactory() {
110 }
111
112 scoped_ptr<Authenticator> Me2MeHostAuthenticatorFactory::CreateAuthenticator(
113     const std::string& local_jid,
114     const std::string& remote_jid,
115     const buzz::XmlElement* first_message) {
116
117   std::string remote_jid_prefix;
118
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());
128     }
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_;
134   }
135
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());
142   }
143
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));
150     }
151
152     return NegotiatingHostAuthenticator::CreateWithSharedSecret(
153         local_cert_, key_pair_, shared_secret_hash_.value,
154         shared_secret_hash_.hash_function, pairing_registry_);
155   }
156
157   return make_scoped_ptr(new RejectingAuthenticator());
158 }
159
160 }  // namespace protocol
161 }  // namespace remoting