OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/me2me_host_authenticator_factory.h" | 5 #include "remoting/protocol/me2me_host_authenticator_factory.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
11 #include "remoting/base/rsa_key_pair.h" | 11 #include "remoting/base/rsa_key_pair.h" |
12 #include "remoting/protocol/channel_authenticator.h" | 12 #include "remoting/protocol/channel_authenticator.h" |
13 #include "remoting/protocol/negotiating_host_authenticator.h" | 13 #include "remoting/protocol/negotiating_host_authenticator.h" |
| 14 #include "remoting/protocol/rejecting_authenticator.h" |
14 #include "remoting/protocol/token_validator.h" | 15 #include "remoting/protocol/token_validator.h" |
15 #include "remoting/signaling/jid_util.h" | 16 #include "remoting/signaling/jid_util.h" |
16 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" | 17 #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" |
17 | 18 |
18 namespace remoting { | 19 namespace remoting { |
19 namespace protocol { | 20 namespace protocol { |
20 | 21 |
21 namespace { | |
22 | |
23 // Authenticator that accepts one message and rejects connection after that. | |
24 class RejectingAuthenticator : public Authenticator { | |
25 public: | |
26 RejectingAuthenticator() | |
27 : state_(WAITING_MESSAGE) { | |
28 } | |
29 ~RejectingAuthenticator() override {} | |
30 | |
31 State state() const override { return state_; } | |
32 | |
33 bool started() const override { return true; } | |
34 | |
35 RejectionReason rejection_reason() const override { | |
36 DCHECK_EQ(state_, REJECTED); | |
37 return INVALID_CREDENTIALS; | |
38 } | |
39 | |
40 void ProcessMessage(const buzz::XmlElement* message, | |
41 const base::Closure& resume_callback) override { | |
42 DCHECK_EQ(state_, WAITING_MESSAGE); | |
43 state_ = REJECTED; | |
44 resume_callback.Run(); | |
45 } | |
46 | |
47 scoped_ptr<buzz::XmlElement> GetNextMessage() override { | |
48 NOTREACHED(); | |
49 return nullptr; | |
50 } | |
51 | |
52 const std::string& GetAuthKey() const override { | |
53 NOTREACHED(); | |
54 return auth_key_; | |
55 }; | |
56 | |
57 scoped_ptr<ChannelAuthenticator> CreateChannelAuthenticator() const override { | |
58 NOTREACHED(); | |
59 return nullptr; | |
60 } | |
61 | |
62 protected: | |
63 State state_; | |
64 std::string auth_key_; | |
65 }; | |
66 | |
67 } // namespace | |
68 | |
69 // static | 22 // static |
70 scoped_ptr<AuthenticatorFactory> | 23 scoped_ptr<AuthenticatorFactory> |
71 Me2MeHostAuthenticatorFactory::CreateWithSharedSecret( | 24 Me2MeHostAuthenticatorFactory::CreateWithSharedSecret( |
72 bool use_service_account, | 25 bool use_service_account, |
73 const std::string& host_owner, | 26 const std::string& host_owner, |
74 const std::string& local_cert, | 27 const std::string& local_cert, |
75 scoped_refptr<RsaKeyPair> key_pair, | 28 scoped_refptr<RsaKeyPair> key_pair, |
| 29 const std::string& required_client_domain, |
76 const SharedSecretHash& shared_secret_hash, | 30 const SharedSecretHash& shared_secret_hash, |
77 scoped_refptr<PairingRegistry> pairing_registry) { | 31 scoped_refptr<PairingRegistry> pairing_registry) { |
78 scoped_ptr<Me2MeHostAuthenticatorFactory> result( | 32 scoped_ptr<Me2MeHostAuthenticatorFactory> result( |
79 new Me2MeHostAuthenticatorFactory()); | 33 new Me2MeHostAuthenticatorFactory()); |
80 result->use_service_account_ = use_service_account; | 34 result->use_service_account_ = use_service_account; |
81 result->host_owner_ = host_owner; | 35 result->host_owner_ = host_owner; |
82 result->local_cert_ = local_cert; | 36 result->local_cert_ = local_cert; |
83 result->key_pair_ = key_pair; | 37 result->key_pair_ = key_pair; |
| 38 result->required_client_domain_ = required_client_domain; |
84 result->shared_secret_hash_ = shared_secret_hash; | 39 result->shared_secret_hash_ = shared_secret_hash; |
85 result->pairing_registry_ = pairing_registry; | 40 result->pairing_registry_ = pairing_registry; |
86 return std::move(result); | 41 return std::move(result); |
87 } | 42 } |
88 | 43 |
89 | 44 |
90 // static | 45 // static |
91 scoped_ptr<AuthenticatorFactory> | 46 scoped_ptr<AuthenticatorFactory> |
92 Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth( | 47 Me2MeHostAuthenticatorFactory::CreateWithThirdPartyAuth( |
93 bool use_service_account, | 48 bool use_service_account, |
94 const std::string& host_owner, | 49 const std::string& host_owner, |
95 const std::string& local_cert, | 50 const std::string& local_cert, |
96 scoped_refptr<RsaKeyPair> key_pair, | 51 scoped_refptr<RsaKeyPair> key_pair, |
| 52 const std::string& required_client_domain, |
97 scoped_ptr<TokenValidatorFactory> | 53 scoped_ptr<TokenValidatorFactory> |
98 token_validator_factory) { | 54 token_validator_factory) { |
99 scoped_ptr<Me2MeHostAuthenticatorFactory> result( | 55 scoped_ptr<Me2MeHostAuthenticatorFactory> result( |
100 new Me2MeHostAuthenticatorFactory()); | 56 new Me2MeHostAuthenticatorFactory()); |
101 result->use_service_account_ = use_service_account; | 57 result->use_service_account_ = use_service_account; |
102 result->host_owner_ = host_owner; | 58 result->host_owner_ = host_owner; |
103 result->local_cert_ = local_cert; | 59 result->local_cert_ = local_cert; |
104 result->key_pair_ = key_pair; | 60 result->key_pair_ = key_pair; |
| 61 result->required_client_domain_ = required_client_domain; |
105 result->token_validator_factory_ = std::move(token_validator_factory); | 62 result->token_validator_factory_ = std::move(token_validator_factory); |
106 return std::move(result); | 63 return std::move(result); |
107 } | 64 } |
108 | 65 |
109 Me2MeHostAuthenticatorFactory::Me2MeHostAuthenticatorFactory() { | 66 Me2MeHostAuthenticatorFactory::Me2MeHostAuthenticatorFactory() { |
110 } | 67 } |
111 | 68 |
112 Me2MeHostAuthenticatorFactory::~Me2MeHostAuthenticatorFactory() { | 69 Me2MeHostAuthenticatorFactory::~Me2MeHostAuthenticatorFactory() { |
113 } | 70 } |
114 | 71 |
115 scoped_ptr<Authenticator> Me2MeHostAuthenticatorFactory::CreateAuthenticator( | 72 scoped_ptr<Authenticator> Me2MeHostAuthenticatorFactory::CreateAuthenticator( |
116 const std::string& local_jid, | 73 const std::string& local_jid, |
117 const std::string& remote_jid, | 74 const std::string& remote_jid, |
118 const buzz::XmlElement* first_message) { | 75 const buzz::XmlElement* first_message) { |
119 | 76 |
120 std::string remote_jid_prefix; | 77 std::string remote_jid_prefix; |
121 | 78 |
122 if (!use_service_account_) { | 79 if (!use_service_account_) { |
123 // JID prefixes may not match the host owner email, for example, in cases | 80 // JID prefixes may not match the host owner email, for example, in cases |
124 // where the host owner account does not have an email associated with it. | 81 // where the host owner account does not have an email associated with it. |
125 // In those cases, the only guarantee we have is that JIDs for the same | 82 // In those cases, the only guarantee we have is that JIDs for the same |
126 // account will have the same prefix. | 83 // account will have the same prefix. |
127 if (!SplitJidResource(local_jid, &remote_jid_prefix, nullptr)) { | 84 if (!SplitJidResource(local_jid, &remote_jid_prefix, nullptr)) { |
128 LOG(DFATAL) << "Invalid local JID:" << local_jid; | 85 LOG(DFATAL) << "Invalid local JID:" << local_jid; |
129 return make_scoped_ptr(new RejectingAuthenticator()); | 86 return make_scoped_ptr( |
| 87 new RejectingAuthenticator(Authenticator::INVALID_CREDENTIALS)); |
130 } | 88 } |
131 } else { | 89 } else { |
132 // TODO(rmsousa): This only works for cases where the JID prefix matches | 90 // TODO(rmsousa): This only works for cases where the JID prefix matches |
133 // the host owner email. Figure out a way to verify the JID in other cases. | 91 // the host owner email. Figure out a way to verify the JID in other cases. |
134 remote_jid_prefix = host_owner_; | 92 remote_jid_prefix = host_owner_; |
135 } | 93 } |
136 | 94 |
137 // Verify that the client's jid is an ASCII string, and then check that the | 95 // Verify that the client's jid is an ASCII string, and then check that the |
138 // client JID has the expected prefix. Comparison is case insensitive. | 96 // client JID has the expected prefix. Comparison is case insensitive. |
139 if (!base::IsStringASCII(remote_jid) || | 97 if (!base::IsStringASCII(remote_jid) || |
140 !base::StartsWith(remote_jid, remote_jid_prefix + '/', | 98 !base::StartsWith(remote_jid, remote_jid_prefix + '/', |
141 base::CompareCase::INSENSITIVE_ASCII)) { | 99 base::CompareCase::INSENSITIVE_ASCII)) { |
142 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid; | 100 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid |
143 return make_scoped_ptr(new RejectingAuthenticator()); | 101 << ": Prefix mismatch."; |
| 102 return make_scoped_ptr( |
| 103 new RejectingAuthenticator(Authenticator::INVALID_CREDENTIALS)); |
| 104 } |
| 105 |
| 106 // If necessary, verify that the client's jid belongs to the correct domain. |
| 107 if (!required_client_domain_.empty()) { |
| 108 std::string client_username = remote_jid; |
| 109 size_t pos = client_username.find('/'); |
| 110 if (pos != std::string::npos) { |
| 111 client_username.replace(pos, std::string::npos, ""); |
| 112 } |
| 113 if (!base::EndsWith(client_username, |
| 114 std::string("@") + required_client_domain_, |
| 115 base::CompareCase::INSENSITIVE_ASCII)) { |
| 116 LOG(ERROR) << "Rejecting incoming connection from " << remote_jid |
| 117 << ": Domain mismatch."; |
| 118 return make_scoped_ptr( |
| 119 new RejectingAuthenticator(Authenticator::INVALID_CREDENTIALS)); |
| 120 } |
144 } | 121 } |
145 | 122 |
146 if (!local_cert_.empty() && key_pair_.get()) { | 123 if (!local_cert_.empty() && key_pair_.get()) { |
147 if (token_validator_factory_) { | 124 if (token_validator_factory_) { |
148 return NegotiatingHostAuthenticator::CreateWithThirdPartyAuth( | 125 return NegotiatingHostAuthenticator::CreateWithThirdPartyAuth( |
149 local_cert_, key_pair_, | 126 local_cert_, key_pair_, |
150 token_validator_factory_->CreateTokenValidator( | 127 token_validator_factory_->CreateTokenValidator( |
151 local_jid, remote_jid)); | 128 local_jid, remote_jid)); |
152 } | 129 } |
153 | 130 |
154 return NegotiatingHostAuthenticator::CreateWithSharedSecret( | 131 return NegotiatingHostAuthenticator::CreateWithSharedSecret( |
155 local_cert_, key_pair_, shared_secret_hash_.value, | 132 local_cert_, key_pair_, shared_secret_hash_.value, |
156 shared_secret_hash_.hash_function, pairing_registry_); | 133 shared_secret_hash_.hash_function, pairing_registry_); |
157 } | 134 } |
158 | 135 |
159 return make_scoped_ptr(new RejectingAuthenticator()); | 136 return make_scoped_ptr( |
| 137 new RejectingAuthenticator(Authenticator::INVALID_CREDENTIALS)); |
160 } | 138 } |
161 | 139 |
162 } // namespace protocol | 140 } // namespace protocol |
163 } // namespace remoting | 141 } // namespace remoting |
OLD | NEW |