OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/pepper_session.h" | 5 #include "remoting/protocol/pepper_session.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/rand_util.h" | 8 #include "base/rand_util.h" |
9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
10 #include "base/string_number_conversions.h" | 10 #include "base/string_number_conversions.h" |
11 #include "remoting/base/constants.h" | 11 #include "remoting/base/constants.h" |
12 #include "remoting/jingle_glue/iq_sender.h" | 12 #include "remoting/jingle_glue/iq_sender.h" |
13 #include "remoting/protocol/authenticator.h" | |
13 #include "remoting/protocol/content_description.h" | 14 #include "remoting/protocol/content_description.h" |
14 #include "remoting/protocol/jingle_messages.h" | 15 #include "remoting/protocol/jingle_messages.h" |
15 #include "remoting/protocol/pepper_session_manager.h" | 16 #include "remoting/protocol/pepper_session_manager.h" |
16 #include "remoting/protocol/pepper_stream_channel.h" | 17 #include "remoting/protocol/pepper_stream_channel.h" |
17 #include "remoting/protocol/v1_client_channel_authenticator.h" | 18 #include "remoting/protocol/v1_client_channel_authenticator.h" |
18 #include "third_party/libjingle/source/talk/p2p/base/candidate.h" | 19 #include "third_party/libjingle/source/talk/p2p/base/candidate.h" |
19 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" | 20 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
20 | 21 |
21 using buzz::XmlElement; | 22 using buzz::XmlElement; |
22 | 23 |
(...skipping 26 matching lines...) Expand all Loading... | |
49 state_change_callback_ = callback; | 50 state_change_callback_ = callback; |
50 } | 51 } |
51 | 52 |
52 Session::Error PepperSession::error() { | 53 Session::Error PepperSession::error() { |
53 DCHECK(CalledOnValidThread()); | 54 DCHECK(CalledOnValidThread()); |
54 return error_; | 55 return error_; |
55 } | 56 } |
56 | 57 |
57 void PepperSession::StartConnection( | 58 void PepperSession::StartConnection( |
58 const std::string& peer_jid, | 59 const std::string& peer_jid, |
59 const std::string& peer_public_key, | 60 Authenticator* authenticator, |
60 const std::string& client_token, | |
61 CandidateSessionConfig* config, | 61 CandidateSessionConfig* config, |
62 const StateChangeCallback& state_change_callback) { | 62 const StateChangeCallback& state_change_callback) { |
63 DCHECK(CalledOnValidThread()); | 63 DCHECK(CalledOnValidThread()); |
64 DCHECK(authenticator); | |
64 | 65 |
65 peer_jid_ = peer_jid; | 66 peer_jid_ = peer_jid; |
66 peer_public_key_ = peer_public_key; | 67 authenticator_.reset(authenticator); |
67 initiator_token_ = client_token; | |
68 candidate_config_.reset(config); | 68 candidate_config_.reset(config); |
69 state_change_callback_ = state_change_callback; | 69 state_change_callback_ = state_change_callback; |
70 | 70 |
71 // Generate random session ID. There are usually not more than 1 | 71 // Generate random session ID. There are usually not more than 1 |
72 // concurrent session per host, so a random 64-bit integer provides | 72 // concurrent session per host, so a random 64-bit integer provides |
73 // enough entropy. In the worst case connection will fail when two | 73 // enough entropy. In the worst case connection will fail when two |
74 // clients generate the same session ID concurrently. | 74 // clients generate the same session ID concurrently. |
75 session_id_ = base::Int64ToString(base::RandGenerator(kint64max)); | 75 session_id_ = base::Int64ToString(base::RandGenerator(kint64max)); |
76 | 76 |
77 // Send session-initiate message. | 77 // Send session-initiate message. |
78 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, | 78 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, |
79 session_id_); | 79 session_id_); |
80 message.from = session_manager_->local_jid_; | 80 message.from = session_manager_->local_jid_; |
81 message.description.reset( | 81 message.description.reset( |
82 new ContentDescription(candidate_config_->Clone(), initiator_token_, "")); | 82 new ContentDescription(candidate_config_->Clone(), |
83 authenticator_->GetNextMessage())); | |
Wez
2011/11/25 06:54:11
We should only call GetNextMessage() if the authen
Sergey Ulanov
2011/11/28 18:55:16
Authenticators for outgoing connections are expect
| |
83 initiate_request_.reset(session_manager_->iq_sender()->SendIq( | 84 initiate_request_.reset(session_manager_->iq_sender()->SendIq( |
84 message.ToXml(), | 85 message.ToXml(), |
85 base::Bind(&PepperSession::OnSessionInitiateResponse, | 86 base::Bind(&PepperSession::OnSessionInitiateResponse, |
86 base::Unretained(this)))); | 87 base::Unretained(this)))); |
87 | 88 |
88 SetState(CONNECTING); | 89 SetState(CONNECTING); |
89 } | 90 } |
90 | 91 |
91 void PepperSession::OnSessionInitiateResponse( | 92 void PepperSession::OnSessionInitiateResponse( |
92 const buzz::XmlElement* response) { | 93 const buzz::XmlElement* response) { |
(...skipping 12 matching lines...) Expand all Loading... | |
105 void PepperSession::OnError(Error error) { | 106 void PepperSession::OnError(Error error) { |
106 error_ = error; | 107 error_ = error; |
107 CloseInternal(true); | 108 CloseInternal(true); |
108 } | 109 } |
109 | 110 |
110 void PepperSession::CreateStreamChannel( | 111 void PepperSession::CreateStreamChannel( |
111 const std::string& name, | 112 const std::string& name, |
112 const StreamChannelCallback& callback) { | 113 const StreamChannelCallback& callback) { |
113 DCHECK(!channels_[name]); | 114 DCHECK(!channels_[name]); |
114 | 115 |
115 PepperStreamChannel* channel = new PepperStreamChannel(this, name, callback); | 116 ChannelAuthenticator* channel_authenticator = |
117 authenticator_->CreateChannelAuthenticator(); | |
118 PepperStreamChannel* channel = new PepperStreamChannel( | |
119 this, name, callback); | |
116 channels_[name] = channel; | 120 channels_[name] = channel; |
117 channel->Connect(session_manager_->pp_instance_, | 121 channel->Connect(session_manager_->pp_instance_, |
118 session_manager_->transport_config_, | 122 session_manager_->transport_config_, |
119 new V1ClientChannelAuthenticator( | 123 channel_authenticator); |
120 remote_cert_, shared_secret_)); | |
121 } | 124 } |
122 | 125 |
123 void PepperSession::CreateDatagramChannel( | 126 void PepperSession::CreateDatagramChannel( |
124 const std::string& name, | 127 const std::string& name, |
125 const DatagramChannelCallback& callback) { | 128 const DatagramChannelCallback& callback) { |
126 // TODO(sergeyu): Implement datagram channel support. | 129 // TODO(sergeyu): Implement datagram channel support. |
127 NOTREACHED(); | 130 NOTREACHED(); |
128 } | 131 } |
129 | 132 |
130 void PepperSession::CancelChannelCreation(const std::string& name) { | 133 void PepperSession::CancelChannelCreation(const std::string& name) { |
(...skipping 18 matching lines...) Expand all Loading... | |
149 DCHECK(CalledOnValidThread()); | 152 DCHECK(CalledOnValidThread()); |
150 return config_; | 153 return config_; |
151 } | 154 } |
152 | 155 |
153 void PepperSession::set_config(const SessionConfig& config) { | 156 void PepperSession::set_config(const SessionConfig& config) { |
154 DCHECK(CalledOnValidThread()); | 157 DCHECK(CalledOnValidThread()); |
155 // set_config() should never be called on the client. | 158 // set_config() should never be called on the client. |
156 NOTREACHED(); | 159 NOTREACHED(); |
157 } | 160 } |
158 | 161 |
159 const std::string& PepperSession::initiator_token() { | |
160 DCHECK(CalledOnValidThread()); | |
161 return initiator_token_; | |
162 } | |
163 | |
164 void PepperSession::set_initiator_token(const std::string& initiator_token) { | |
165 DCHECK(CalledOnValidThread()); | |
166 initiator_token_ = initiator_token; | |
167 } | |
168 | |
169 const std::string& PepperSession::receiver_token() { | |
170 DCHECK(CalledOnValidThread()); | |
171 return receiver_token_; | |
172 } | |
173 | |
174 void PepperSession::set_receiver_token(const std::string& receiver_token) { | |
175 DCHECK(CalledOnValidThread()); | |
176 // set_receiver_token() should not be called on the client side. | |
177 NOTREACHED(); | |
178 } | |
179 | |
180 void PepperSession::set_shared_secret(const std::string& secret) { | |
181 DCHECK(CalledOnValidThread()); | |
182 shared_secret_ = secret; | |
183 } | |
184 | |
185 const std::string& PepperSession::shared_secret() { | |
186 DCHECK(CalledOnValidThread()); | |
187 return shared_secret_; | |
188 } | |
189 | |
190 void PepperSession::Close() { | 162 void PepperSession::Close() { |
191 DCHECK(CalledOnValidThread()); | 163 DCHECK(CalledOnValidThread()); |
192 | 164 |
193 if (state_ == CONNECTING || state_ == CONNECTED) { | 165 if (state_ == CONNECTING || state_ == CONNECTED) { |
194 // Send session-terminate message. | 166 // Send session-terminate message. |
195 JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, | 167 JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, |
196 session_id_); | 168 session_id_); |
197 scoped_ptr<IqRequest> terminate_request( | 169 scoped_ptr<IqRequest> terminate_request( |
198 session_manager_->iq_sender()->SendIq( | 170 session_manager_->iq_sender()->SendIq( |
199 message.ToXml(), IqSender::ReplyCallback())); | 171 message.ToXml(), IqSender::ReplyCallback())); |
(...skipping 30 matching lines...) Expand all Loading... | |
230 } | 202 } |
231 } | 203 } |
232 | 204 |
233 void PepperSession::OnAccept(const JingleMessage& message, | 205 void PepperSession::OnAccept(const JingleMessage& message, |
234 JingleMessageReply* reply) { | 206 JingleMessageReply* reply) { |
235 if (state_ != CONNECTING) { | 207 if (state_ != CONNECTING) { |
236 *reply = JingleMessageReply(JingleMessageReply::UNEXPECTED_REQUEST); | 208 *reply = JingleMessageReply(JingleMessageReply::UNEXPECTED_REQUEST); |
237 return; | 209 return; |
238 } | 210 } |
239 | 211 |
212 const buzz::XmlElement* auth_message = | |
213 message.description->authenticator_message(); | |
214 if (!auth_message) { | |
215 DLOG(WARNING) << "Received session-accept without authentication message " | |
216 << auth_message->Str(); | |
217 OnError(INCOMPATIBLE_PROTOCOL); | |
218 return; | |
219 } | |
220 | |
221 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); | |
222 authenticator_->ProcessMessage(auth_message); | |
223 // Support for more than two auth message is not implemented yet. | |
224 DCHECK(authenticator_->state() != Authenticator::WAITING_MESSAGE && | |
225 authenticator_->state() != Authenticator::MESSAGE_READY); | |
226 | |
227 if (authenticator_->state() == Authenticator::REJECTED) { | |
228 OnError(AUTHENTICATION_FAILED); | |
229 return; | |
230 } | |
231 | |
240 if (!InitializeConfigFromDescription(message.description.get())) { | 232 if (!InitializeConfigFromDescription(message.description.get())) { |
241 OnError(INCOMPATIBLE_PROTOCOL); | 233 OnError(INCOMPATIBLE_PROTOCOL); |
242 return; | 234 return; |
243 } | 235 } |
244 | 236 |
245 SetState(CONNECTED); | 237 SetState(CONNECTED); |
246 | 238 |
247 // In case there is transport information in the accept message. | 239 // In case there is transport information in the accept message. |
248 ProcessTransportInfo(message); | 240 ProcessTransportInfo(message); |
249 } | 241 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
290 return; | 282 return; |
291 } | 283 } |
292 | 284 |
293 LOG(WARNING) << "Received unexpected session-terminate message."; | 285 LOG(WARNING) << "Received unexpected session-terminate message."; |
294 } | 286 } |
295 | 287 |
296 bool PepperSession::InitializeConfigFromDescription( | 288 bool PepperSession::InitializeConfigFromDescription( |
297 const ContentDescription* description) { | 289 const ContentDescription* description) { |
298 DCHECK(description); | 290 DCHECK(description); |
299 | 291 |
300 remote_cert_ = description->certificate(); | |
301 if (remote_cert_.empty()) { | |
302 LOG(ERROR) << "session-accept does not specify certificate"; | |
303 return false; | |
304 } | |
305 | |
306 if (!description->config()->GetFinalConfig(&config_)) { | 292 if (!description->config()->GetFinalConfig(&config_)) { |
307 LOG(ERROR) << "session-accept does not specify configuration"; | 293 LOG(ERROR) << "session-accept does not specify configuration"; |
308 return false; | 294 return false; |
309 } | 295 } |
310 if (!candidate_config()->IsSupported(config_)) { | 296 if (!candidate_config()->IsSupported(config_)) { |
311 LOG(ERROR) << "session-accept specifies an invalid configuration"; | 297 LOG(ERROR) << "session-accept specifies an invalid configuration"; |
312 return false; | 298 return false; |
313 } | 299 } |
314 | 300 |
315 return true; | 301 return true; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 DCHECK_NE(state_, FAILED); | 364 DCHECK_NE(state_, FAILED); |
379 | 365 |
380 state_ = new_state; | 366 state_ = new_state; |
381 if (!state_change_callback_.is_null()) | 367 if (!state_change_callback_.is_null()) |
382 state_change_callback_.Run(new_state); | 368 state_change_callback_.Run(new_state); |
383 } | 369 } |
384 } | 370 } |
385 | 371 |
386 } // namespace protocol | 372 } // namespace protocol |
387 } // namespace remoting | 373 } // namespace remoting |
OLD | NEW |