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/host/chromoting_host.h" | 5 #include "remoting/host/chromoting_host.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 #include "remoting/base/constants.h" | 8 #include "remoting/base/constants.h" |
| 9 #include "remoting/base/encoder.h" | 9 #include "remoting/base/encoder.h" |
| 10 #include "remoting/base/encoder_row_based.h" | 10 #include "remoting/base/encoder_row_based.h" |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 176 const scoped_refptr<HostStatusObserver>& observer) { | 176 const scoped_refptr<HostStatusObserver>& observer) { |
| 177 DCHECK_EQ(state_, kInitial); | 177 DCHECK_EQ(state_, kInitial); |
| 178 status_observers_.push_back(observer); | 178 status_observers_.push_back(observer); |
| 179 } | 179 } |
| 180 | 180 |
| 181 //////////////////////////////////////////////////////////////////////////// | 181 //////////////////////////////////////////////////////////////////////////// |
| 182 // protocol::ConnectionToClient::EventHandler implementations | 182 // protocol::ConnectionToClient::EventHandler implementations |
| 183 void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) { | 183 void ChromotingHost::OnConnectionOpened(ConnectionToClient* connection) { |
| 184 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); | 184 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); |
| 185 VLOG(1) << "Connection to client established."; | 185 VLOG(1) << "Connection to client established."; |
| 186 // TODO(wez): ChromotingHost shouldn't need to know about Me2Mom. | |
| 186 if (is_me2mom_) { | 187 if (is_me2mom_) { |
| 187 // TODO(wez): Improve our authentication framework. | |
| 188 context_->main_message_loop()->PostTask( | 188 context_->main_message_loop()->PostTask( |
| 189 FROM_HERE, | 189 FROM_HERE, |
| 190 NewRunnableMethod(this, &ChromotingHost::ProcessPreAuthentication, | 190 NewRunnableMethod(this, &ChromotingHost::ProcessPreAuthentication, |
| 191 make_scoped_refptr(connection))); | 191 make_scoped_refptr(connection))); |
| 192 } | 192 } |
| 193 } | 193 } |
| 194 | 194 |
| 195 void ChromotingHost::OnConnectionClosed(ConnectionToClient* connection) { | 195 void ChromotingHost::OnConnectionClosed(ConnectionToClient* connection) { |
| 196 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); | 196 DCHECK_EQ(context_->network_message_loop(), MessageLoop::current()); |
| 197 | 197 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 273 | 273 |
| 274 void ChromotingHost::OnNewClientSession( | 274 void ChromotingHost::OnNewClientSession( |
| 275 protocol::Session* session, | 275 protocol::Session* session, |
| 276 protocol::SessionManager::IncomingSessionResponse* response) { | 276 protocol::SessionManager::IncomingSessionResponse* response) { |
| 277 base::AutoLock auto_lock(lock_); | 277 base::AutoLock auto_lock(lock_); |
| 278 if (state_ != kStarted) { | 278 if (state_ != kStarted) { |
| 279 *response = protocol::SessionManager::DECLINE; | 279 *response = protocol::SessionManager::DECLINE; |
| 280 return; | 280 return; |
| 281 } | 281 } |
| 282 | 282 |
| 283 // If we are running Me2Mom and already have an authenticated client then | |
| 284 // reject the connection immediately. | |
|
Jamie
2011/06/10 18:00:38
What's the concern here? If we're worried that a b
Wez
2011/06/13 20:30:35
The Access Code is one-shot by design, so from a s
| |
| 285 // TODO(wez): ChromotingHost shouldn't need to know about Me2Mom. | |
| 286 if (is_me2mom_ && AuthenticatedClientsCount() > 0) { | |
| 287 *response = protocol::SessionManager::DECLINE; | |
| 288 return; | |
| 289 } | |
| 290 | |
| 283 // Check that the client has access to the host. | 291 // Check that the client has access to the host. |
| 284 if (!access_verifier_->VerifyPermissions(session->jid(), | 292 if (!access_verifier_->VerifyPermissions(session->jid(), |
| 285 session->initiator_token())) { | 293 session->initiator_token())) { |
| 286 *response = protocol::SessionManager::DECLINE; | 294 *response = protocol::SessionManager::DECLINE; |
| 287 return; | 295 return; |
| 288 } | 296 } |
| 289 | 297 |
| 290 // TODO(simonmorris): The resolution is set in the video stream now, | 298 // TODO(simonmorris): The resolution is set in the video stream now, |
| 291 // so it doesn't need to be set here. | 299 // so it doesn't need to be set here. |
| 292 *protocol_config_->mutable_initial_resolution() = | 300 *protocol_config_->mutable_initial_resolution() = |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 if (client->get()->authenticated()) { | 368 if (client->get()->authenticated()) { |
| 361 recorder_->Stop(NULL); | 369 recorder_->Stop(NULL); |
| 362 recorder_ = NULL; | 370 recorder_ = NULL; |
| 363 } | 371 } |
| 364 } | 372 } |
| 365 | 373 |
| 366 // Close the connection to connection just to be safe. | 374 // Close the connection to connection just to be safe. |
| 367 connection->Disconnect(); | 375 connection->Disconnect(); |
| 368 | 376 |
| 369 // Also remove reference to ConnectionToClient from this object. | 377 // Also remove reference to ConnectionToClient from this object. |
| 378 int old_authenticated_clients = AuthenticatedClientsCount(); | |
| 370 clients_.erase(client); | 379 clients_.erase(client); |
| 371 | 380 |
| 372 if (!HasAuthenticatedClients()) { | 381 // Notify the observers of the change, if any. |
| 382 int authenticated_clients = AuthenticatedClientsCount(); | |
| 383 if (old_authenticated_clients != authenticated_clients) { | |
| 384 for (StatusObserverList::iterator it = status_observers_.begin(); | |
| 385 it != status_observers_.end(); ++it) { | |
| 386 (*it)->OnAuthenticatedClientsChanged(authenticated_clients); | |
| 387 } | |
| 388 } | |
| 389 | |
| 390 // Enable the "curtain", if at least one client is actually authenticated. | |
| 391 if (AuthenticatedClientsCount() > 0) { | |
| 373 EnableCurtainMode(false); | 392 EnableCurtainMode(false); |
| 393 // TODO(wez): ChromotingHost shouldn't need to know about Me2Mom. | |
| 374 if (is_me2mom_) | 394 if (is_me2mom_) |
| 375 desktop_environment_->disconnect_window()->Hide(); | 395 desktop_environment_->disconnect_window()->Hide(); |
| 376 } | 396 } |
| 377 } | 397 } |
| 378 | 398 |
| 379 // TODO(sergeyu): Move this to SessionManager? | 399 // TODO(sergeyu): Move this to SessionManager? |
| 380 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig* config) { | 400 Encoder* ChromotingHost::CreateEncoder(const protocol::SessionConfig* config) { |
| 381 const protocol::ChannelConfig& video_config = config->video_config(); | 401 const protocol::ChannelConfig& video_config = config->video_config(); |
| 382 | 402 |
| 383 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { | 403 if (video_config.codec == protocol::ChannelConfig::CODEC_VERBATIM) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 394 | 414 |
| 395 return NULL; | 415 return NULL; |
| 396 } | 416 } |
| 397 | 417 |
| 398 std::string ChromotingHost::GenerateHostAuthToken( | 418 std::string ChromotingHost::GenerateHostAuthToken( |
| 399 const std::string& encoded_client_token) { | 419 const std::string& encoded_client_token) { |
| 400 // TODO(ajwong): Return the signature of this instead. | 420 // TODO(ajwong): Return the signature of this instead. |
| 401 return encoded_client_token; | 421 return encoded_client_token; |
| 402 } | 422 } |
| 403 | 423 |
| 404 bool ChromotingHost::HasAuthenticatedClients() const { | 424 int ChromotingHost::AuthenticatedClientsCount() const { |
| 425 int authenticated_clients = 0; | |
| 405 for (ClientList::const_iterator it = clients_.begin(); it != clients_.end(); | 426 for (ClientList::const_iterator it = clients_.begin(); it != clients_.end(); |
| 406 ++it) { | 427 ++it) { |
| 407 if (it->get()->authenticated()) | 428 if (it->get()->authenticated()) |
| 408 return true; | 429 ++authenticated_clients; |
| 409 } | 430 } |
| 410 return false; | 431 return authenticated_clients; |
| 411 } | 432 } |
| 412 | 433 |
| 413 void ChromotingHost::EnableCurtainMode(bool enable) { | 434 void ChromotingHost::EnableCurtainMode(bool enable) { |
| 414 // TODO(jamiewalch): This will need to be more sophisticated when we think | 435 // TODO(jamiewalch): This will need to be more sophisticated when we think |
| 415 // about proper crash recovery and daemon mode. | 436 // about proper crash recovery and daemon mode. |
| 437 // TODO(wez): CurtainMode shouldn't be driven directly by ChromotingHost. | |
|
Jamie
2011/06/10 18:00:38
+1
Wez
2011/06/13 20:30:35
As requested, I've removed the dups of this commen
| |
| 416 if (is_me2mom_ || enable == is_curtained_) | 438 if (is_me2mom_ || enable == is_curtained_) |
| 417 return; | 439 return; |
| 418 desktop_environment_->curtain()->EnableCurtainMode(enable); | 440 desktop_environment_->curtain()->EnableCurtainMode(enable); |
| 419 is_curtained_ = enable; | 441 is_curtained_ = enable; |
| 420 } | 442 } |
| 421 | 443 |
| 422 void ChromotingHost::LocalLoginSucceeded( | 444 void ChromotingHost::LocalLoginSucceeded( |
| 423 scoped_refptr<ConnectionToClient> connection) { | 445 scoped_refptr<ConnectionToClient> connection) { |
| 424 if (MessageLoop::current() != context_->main_message_loop()) { | 446 if (MessageLoop::current() != context_->main_message_loop()) { |
| 425 context_->main_message_loop()->PostTask( | 447 context_->main_message_loop()->PostTask( |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 459 context_->encode_message_loop(), | 481 context_->encode_message_loop(), |
| 460 context_->network_message_loop(), | 482 context_->network_message_loop(), |
| 461 desktop_environment_->capturer(), | 483 desktop_environment_->capturer(), |
| 462 encoder); | 484 encoder); |
| 463 } | 485 } |
| 464 | 486 |
| 465 // Immediately add the connection and start the session. | 487 // Immediately add the connection and start the session. |
| 466 recorder_->AddConnection(connection); | 488 recorder_->AddConnection(connection); |
| 467 recorder_->Start(); | 489 recorder_->Start(); |
| 468 EnableCurtainMode(true); | 490 EnableCurtainMode(true); |
| 491 // TODO(wez): ChromotingHost shouldn't need to know about Me2Mom. | |
| 469 if (is_me2mom_) { | 492 if (is_me2mom_) { |
| 470 std::string username = connection->session()->jid(); | 493 std::string username = connection->session()->jid(); |
| 471 size_t pos = username.find('/'); | 494 size_t pos = username.find('/'); |
| 472 if (pos != std::string::npos) | 495 if (pos != std::string::npos) |
| 473 username.replace(pos, std::string::npos, ""); | 496 username.replace(pos, std::string::npos, ""); |
| 474 desktop_environment_->disconnect_window()->Show(this, username); | 497 desktop_environment_->disconnect_window()->Show(this, username); |
| 475 } | 498 } |
| 499 | |
| 500 // Notify observers that there is at least one authenticated client. | |
| 501 for (StatusObserverList::iterator it = status_observers_.begin(); | |
| 502 it != status_observers_.end(); ++it) { | |
| 503 (*it)->OnAuthenticatedClientsChanged(AuthenticatedClientsCount()); | |
| 504 } | |
| 476 } | 505 } |
| 477 | 506 |
| 478 void ChromotingHost::LocalLoginFailed( | 507 void ChromotingHost::LocalLoginFailed( |
| 479 scoped_refptr<ConnectionToClient> connection) { | 508 scoped_refptr<ConnectionToClient> connection) { |
| 480 if (MessageLoop::current() != context_->main_message_loop()) { | 509 if (MessageLoop::current() != context_->main_message_loop()) { |
| 481 context_->main_message_loop()->PostTask( | 510 context_->main_message_loop()->PostTask( |
| 482 FROM_HERE, | 511 FROM_HERE, |
| 483 NewRunnableMethod(this, &ChromotingHost::LocalLoginFailed, connection)); | 512 NewRunnableMethod(this, &ChromotingHost::LocalLoginFailed, connection)); |
| 484 return; | 513 return; |
| 485 } | 514 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 497 ClientList::iterator client; | 526 ClientList::iterator client; |
| 498 for (client = clients_.begin(); client != clients_.end(); ++client) { | 527 for (client = clients_.begin(); client != clients_.end(); ++client) { |
| 499 if (client->get()->connection() == connection) | 528 if (client->get()->connection() == connection) |
| 500 break; | 529 break; |
| 501 } | 530 } |
| 502 CHECK(client != clients_.end()); | 531 CHECK(client != clients_.end()); |
| 503 client->get()->OnAuthorizationComplete(true); | 532 client->get()->OnAuthorizationComplete(true); |
| 504 } | 533 } |
| 505 | 534 |
| 506 } // namespace remoting | 535 } // namespace remoting |
| OLD | NEW |