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); |
| 65 DCHECK_EQ(authenticator->state(), Authenticator::MESSAGE_READY); |
64 | 66 |
65 peer_jid_ = peer_jid; | 67 peer_jid_ = peer_jid; |
66 peer_public_key_ = peer_public_key; | 68 authenticator_.reset(authenticator); |
67 initiator_token_ = client_token; | |
68 candidate_config_.reset(config); | 69 candidate_config_.reset(config); |
69 state_change_callback_ = state_change_callback; | 70 state_change_callback_ = state_change_callback; |
70 | 71 |
71 // Generate random session ID. There are usually not more than 1 | 72 // Generate random session ID. There are usually not more than 1 |
72 // concurrent session per host, so a random 64-bit integer provides | 73 // concurrent session per host, so a random 64-bit integer provides |
73 // enough entropy. In the worst case connection will fail when two | 74 // enough entropy. In the worst case connection will fail when two |
74 // clients generate the same session ID concurrently. | 75 // clients generate the same session ID concurrently. |
75 session_id_ = base::Int64ToString(base::RandGenerator(kint64max)); | 76 session_id_ = base::Int64ToString(base::RandGenerator(kint64max)); |
76 | 77 |
77 // Send session-initiate message. | 78 // Send session-initiate message. |
78 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, | 79 JingleMessage message(peer_jid_, JingleMessage::SESSION_INITIATE, |
79 session_id_); | 80 session_id_); |
80 message.from = session_manager_->local_jid_; | 81 message.from = session_manager_->local_jid_; |
81 message.description.reset( | 82 message.description.reset( |
82 new ContentDescription(candidate_config_->Clone(), initiator_token_, "")); | 83 new ContentDescription(candidate_config_->Clone(), |
| 84 authenticator_->GetNextMessage())); |
83 initiate_request_.reset(session_manager_->iq_sender()->SendIq( | 85 initiate_request_.reset(session_manager_->iq_sender()->SendIq( |
84 message.ToXml(), | 86 message.ToXml(), |
85 base::Bind(&PepperSession::OnSessionInitiateResponse, | 87 base::Bind(&PepperSession::OnSessionInitiateResponse, |
86 base::Unretained(this)))); | 88 base::Unretained(this)))); |
87 | 89 |
88 SetState(CONNECTING); | 90 SetState(CONNECTING); |
89 } | 91 } |
90 | 92 |
91 void PepperSession::OnSessionInitiateResponse( | 93 void PepperSession::OnSessionInitiateResponse( |
92 const buzz::XmlElement* response) { | 94 const buzz::XmlElement* response) { |
(...skipping 12 matching lines...) Expand all Loading... |
105 void PepperSession::OnError(Error error) { | 107 void PepperSession::OnError(Error error) { |
106 error_ = error; | 108 error_ = error; |
107 CloseInternal(true); | 109 CloseInternal(true); |
108 } | 110 } |
109 | 111 |
110 void PepperSession::CreateStreamChannel( | 112 void PepperSession::CreateStreamChannel( |
111 const std::string& name, | 113 const std::string& name, |
112 const StreamChannelCallback& callback) { | 114 const StreamChannelCallback& callback) { |
113 DCHECK(!channels_[name]); | 115 DCHECK(!channels_[name]); |
114 | 116 |
115 PepperStreamChannel* channel = new PepperStreamChannel(this, name, callback); | 117 ChannelAuthenticator* channel_authenticator = |
| 118 authenticator_->CreateChannelAuthenticator(); |
| 119 PepperStreamChannel* channel = new PepperStreamChannel( |
| 120 this, name, callback); |
116 channels_[name] = channel; | 121 channels_[name] = channel; |
117 channel->Connect(session_manager_->pp_instance_, | 122 channel->Connect(session_manager_->pp_instance_, |
118 session_manager_->transport_config_, | 123 session_manager_->transport_config_, |
119 new V1ClientChannelAuthenticator( | 124 channel_authenticator); |
120 remote_cert_, shared_secret_)); | |
121 } | 125 } |
122 | 126 |
123 void PepperSession::CreateDatagramChannel( | 127 void PepperSession::CreateDatagramChannel( |
124 const std::string& name, | 128 const std::string& name, |
125 const DatagramChannelCallback& callback) { | 129 const DatagramChannelCallback& callback) { |
126 // TODO(sergeyu): Implement datagram channel support. | 130 // TODO(sergeyu): Implement datagram channel support. |
127 NOTREACHED(); | 131 NOTREACHED(); |
128 } | 132 } |
129 | 133 |
130 void PepperSession::CancelChannelCreation(const std::string& name) { | 134 void PepperSession::CancelChannelCreation(const std::string& name) { |
(...skipping 18 matching lines...) Expand all Loading... |
149 DCHECK(CalledOnValidThread()); | 153 DCHECK(CalledOnValidThread()); |
150 return config_; | 154 return config_; |
151 } | 155 } |
152 | 156 |
153 void PepperSession::set_config(const SessionConfig& config) { | 157 void PepperSession::set_config(const SessionConfig& config) { |
154 DCHECK(CalledOnValidThread()); | 158 DCHECK(CalledOnValidThread()); |
155 // set_config() should never be called on the client. | 159 // set_config() should never be called on the client. |
156 NOTREACHED(); | 160 NOTREACHED(); |
157 } | 161 } |
158 | 162 |
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() { | 163 void PepperSession::Close() { |
191 DCHECK(CalledOnValidThread()); | 164 DCHECK(CalledOnValidThread()); |
192 | 165 |
193 if (state_ == CONNECTING || state_ == CONNECTED) { | 166 if (state_ == CONNECTING || state_ == CONNECTED) { |
194 // Send session-terminate message. | 167 // Send session-terminate message. |
195 JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, | 168 JingleMessage message(peer_jid_, JingleMessage::SESSION_TERMINATE, |
196 session_id_); | 169 session_id_); |
197 scoped_ptr<IqRequest> terminate_request( | 170 scoped_ptr<IqRequest> terminate_request( |
198 session_manager_->iq_sender()->SendIq( | 171 session_manager_->iq_sender()->SendIq( |
199 message.ToXml(), IqSender::ReplyCallback())); | 172 message.ToXml(), IqSender::ReplyCallback())); |
(...skipping 30 matching lines...) Expand all Loading... |
230 } | 203 } |
231 } | 204 } |
232 | 205 |
233 void PepperSession::OnAccept(const JingleMessage& message, | 206 void PepperSession::OnAccept(const JingleMessage& message, |
234 JingleMessageReply* reply) { | 207 JingleMessageReply* reply) { |
235 if (state_ != CONNECTING) { | 208 if (state_ != CONNECTING) { |
236 *reply = JingleMessageReply(JingleMessageReply::UNEXPECTED_REQUEST); | 209 *reply = JingleMessageReply(JingleMessageReply::UNEXPECTED_REQUEST); |
237 return; | 210 return; |
238 } | 211 } |
239 | 212 |
| 213 const buzz::XmlElement* auth_message = |
| 214 message.description->authenticator_message(); |
| 215 if (!auth_message) { |
| 216 DLOG(WARNING) << "Received session-accept without authentication message " |
| 217 << auth_message->Str(); |
| 218 OnError(INCOMPATIBLE_PROTOCOL); |
| 219 return; |
| 220 } |
| 221 |
| 222 DCHECK(authenticator_->state() == Authenticator::WAITING_MESSAGE); |
| 223 authenticator_->ProcessMessage(auth_message); |
| 224 // Support for more than two auth message is not implemented yet. |
| 225 DCHECK(authenticator_->state() != Authenticator::WAITING_MESSAGE && |
| 226 authenticator_->state() != Authenticator::MESSAGE_READY); |
| 227 |
| 228 if (authenticator_->state() == Authenticator::REJECTED) { |
| 229 OnError(AUTHENTICATION_FAILED); |
| 230 return; |
| 231 } |
| 232 |
240 if (!InitializeConfigFromDescription(message.description.get())) { | 233 if (!InitializeConfigFromDescription(message.description.get())) { |
241 OnError(INCOMPATIBLE_PROTOCOL); | 234 OnError(INCOMPATIBLE_PROTOCOL); |
242 return; | 235 return; |
243 } | 236 } |
244 | 237 |
245 SetState(CONNECTED); | 238 SetState(CONNECTED); |
246 | 239 |
247 // In case there is transport information in the accept message. | 240 // In case there is transport information in the accept message. |
248 ProcessTransportInfo(message); | 241 ProcessTransportInfo(message); |
249 } | 242 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 return; | 283 return; |
291 } | 284 } |
292 | 285 |
293 LOG(WARNING) << "Received unexpected session-terminate message."; | 286 LOG(WARNING) << "Received unexpected session-terminate message."; |
294 } | 287 } |
295 | 288 |
296 bool PepperSession::InitializeConfigFromDescription( | 289 bool PepperSession::InitializeConfigFromDescription( |
297 const ContentDescription* description) { | 290 const ContentDescription* description) { |
298 DCHECK(description); | 291 DCHECK(description); |
299 | 292 |
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_)) { | 293 if (!description->config()->GetFinalConfig(&config_)) { |
307 LOG(ERROR) << "session-accept does not specify configuration"; | 294 LOG(ERROR) << "session-accept does not specify configuration"; |
308 return false; | 295 return false; |
309 } | 296 } |
310 if (!candidate_config()->IsSupported(config_)) { | 297 if (!candidate_config()->IsSupported(config_)) { |
311 LOG(ERROR) << "session-accept specifies an invalid configuration"; | 298 LOG(ERROR) << "session-accept specifies an invalid configuration"; |
312 return false; | 299 return false; |
313 } | 300 } |
314 | 301 |
315 return true; | 302 return true; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 DCHECK_NE(state_, FAILED); | 365 DCHECK_NE(state_, FAILED); |
379 | 366 |
380 state_ = new_state; | 367 state_ = new_state; |
381 if (!state_change_callback_.is_null()) | 368 if (!state_change_callback_.is_null()) |
382 state_change_callback_.Run(new_state); | 369 state_change_callback_.Run(new_state); |
383 } | 370 } |
384 } | 371 } |
385 | 372 |
386 } // namespace protocol | 373 } // namespace protocol |
387 } // namespace remoting | 374 } // namespace remoting |
OLD | NEW |