Chromium Code Reviews| 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 |