| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/setup/me2me_native_messaging_host.h" | 5 #include "remoting/host/setup/me2me_native_messaging_host.h" |
| 6 #include <string> | 6 #include <string> |
| 7 | 7 |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 response->Set("supportedFeatures", supported_features_list.release()); | 167 response->Set("supportedFeatures", supported_features_list.release()); |
| 168 channel_->SendMessage(response.Pass()); | 168 channel_->SendMessage(response.Pass()); |
| 169 } | 169 } |
| 170 | 170 |
| 171 void Me2MeNativeMessagingHost::ProcessClearPairedClients( | 171 void Me2MeNativeMessagingHost::ProcessClearPairedClients( |
| 172 scoped_ptr<base::DictionaryValue> message, | 172 scoped_ptr<base::DictionaryValue> message, |
| 173 scoped_ptr<base::DictionaryValue> response) { | 173 scoped_ptr<base::DictionaryValue> response) { |
| 174 DCHECK(thread_checker_.CalledOnValidThread()); | 174 DCHECK(thread_checker_.CalledOnValidThread()); |
| 175 | 175 |
| 176 if (needs_elevation_) { | 176 if (needs_elevation_) { |
| 177 DelegateToElevatedHost(message.Pass(), response.Pass()); | 177 if (!DelegateToElevatedHost(message.Pass())) |
| 178 SendBooleanResult(response.Pass(), false); |
| 178 return; | 179 return; |
| 179 } | 180 } |
| 180 | 181 |
| 181 if (pairing_registry_) { | 182 if (pairing_registry_) { |
| 182 pairing_registry_->ClearAllPairings( | 183 pairing_registry_->ClearAllPairings( |
| 183 base::Bind(&Me2MeNativeMessagingHost::SendBooleanResult, weak_ptr_, | 184 base::Bind(&Me2MeNativeMessagingHost::SendBooleanResult, weak_ptr_, |
| 184 base::Passed(&response))); | 185 base::Passed(&response))); |
| 185 } else { | 186 } else { |
| 186 SendBooleanResult(response.Pass(), false); | 187 SendBooleanResult(response.Pass(), false); |
| 187 } | 188 } |
| 188 } | 189 } |
| 189 | 190 |
| 190 void Me2MeNativeMessagingHost::ProcessDeletePairedClient( | 191 void Me2MeNativeMessagingHost::ProcessDeletePairedClient( |
| 191 scoped_ptr<base::DictionaryValue> message, | 192 scoped_ptr<base::DictionaryValue> message, |
| 192 scoped_ptr<base::DictionaryValue> response) { | 193 scoped_ptr<base::DictionaryValue> response) { |
| 193 DCHECK(thread_checker_.CalledOnValidThread()); | 194 DCHECK(thread_checker_.CalledOnValidThread()); |
| 194 | 195 |
| 195 if (needs_elevation_) { | 196 if (needs_elevation_) { |
| 196 DelegateToElevatedHost(message.Pass(), response.Pass()); | 197 if (!DelegateToElevatedHost(message.Pass())) |
| 198 SendBooleanResult(response.Pass(), false); |
| 197 return; | 199 return; |
| 198 } | 200 } |
| 199 | 201 |
| 200 std::string client_id; | 202 std::string client_id; |
| 201 if (!message->GetString(protocol::PairingRegistry::kClientIdKey, | 203 if (!message->GetString(protocol::PairingRegistry::kClientIdKey, |
| 202 &client_id)) { | 204 &client_id)) { |
| 203 LOG(ERROR) << "'" << protocol::PairingRegistry::kClientIdKey | 205 LOG(ERROR) << "'" << protocol::PairingRegistry::kClientIdKey |
| 204 << "' string not found."; | 206 << "' string not found."; |
| 205 OnError(); | 207 OnError(); |
| 206 return; | 208 return; |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 494 | 496 |
| 495 void Me2MeNativeMessagingHost::Stop() { | 497 void Me2MeNativeMessagingHost::Stop() { |
| 496 DCHECK(thread_checker_.CalledOnValidThread()); | 498 DCHECK(thread_checker_.CalledOnValidThread()); |
| 497 | 499 |
| 498 if (!quit_closure_.is_null()) | 500 if (!quit_closure_.is_null()) |
| 499 base::ResetAndReturn(&quit_closure_).Run(); | 501 base::ResetAndReturn(&quit_closure_).Run(); |
| 500 } | 502 } |
| 501 | 503 |
| 502 #if defined(OS_WIN) | 504 #if defined(OS_WIN) |
| 503 | 505 |
| 504 void Me2MeNativeMessagingHost::DelegateToElevatedHost( | 506 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( |
| 505 scoped_ptr<base::DictionaryValue> message, | 507 scoped_ptr<base::DictionaryValue> message) { |
| 506 scoped_ptr<base::DictionaryValue> response) { | |
| 507 DCHECK(thread_checker_.CalledOnValidThread()); | 508 DCHECK(thread_checker_.CalledOnValidThread()); |
| 508 | 509 |
| 509 EnsureElevatedHostCreated(); | 510 EnsureElevatedHostCreated(); |
| 510 | 511 |
| 511 DCHECK(elevated_channel_); | 512 // elevated_channel_ will be null if user rejects the UAC request. |
| 512 elevated_channel_->SendMessage(message.Pass()); | 513 if (elevated_channel_) |
| 514 elevated_channel_->SendMessage(message.Pass()); |
| 515 |
| 516 return elevated_channel_ != NULL; |
| 513 } | 517 } |
| 514 | 518 |
| 515 void Me2MeNativeMessagingHost::EnsureElevatedHostCreated() { | 519 void Me2MeNativeMessagingHost::EnsureElevatedHostCreated() { |
| 516 DCHECK(thread_checker_.CalledOnValidThread()); | 520 DCHECK(thread_checker_.CalledOnValidThread()); |
| 517 DCHECK(needs_elevation_); | 521 DCHECK(needs_elevation_); |
| 518 | 522 |
| 519 if (elevated_channel_) | 523 if (elevated_channel_) |
| 520 return; | 524 return; |
| 521 | 525 |
| 522 // presubmit: allow wstring | 526 // presubmit: allow wstring |
| (...skipping 19 matching lines...) Expand all Loading... |
| 542 | 546 |
| 543 SECURITY_ATTRIBUTES security_attributes = {0}; | 547 SECURITY_ATTRIBUTES security_attributes = {0}; |
| 544 security_attributes.nLength = sizeof(security_attributes); | 548 security_attributes.nLength = sizeof(security_attributes); |
| 545 security_attributes.lpSecurityDescriptor = sd.get(); | 549 security_attributes.lpSecurityDescriptor = sd.get(); |
| 546 security_attributes.bInheritHandle = FALSE; | 550 security_attributes.bInheritHandle = FALSE; |
| 547 | 551 |
| 548 // Generate a unique name for the input channel. | 552 // Generate a unique name for the input channel. |
| 549 std::string input_pipe_name(kChromePipeNamePrefix); | 553 std::string input_pipe_name(kChromePipeNamePrefix); |
| 550 input_pipe_name.append(IPC::Channel::GenerateUniqueRandomChannelID()); | 554 input_pipe_name.append(IPC::Channel::GenerateUniqueRandomChannelID()); |
| 551 | 555 |
| 552 delegate_write_handle_.Set(CreateNamedPipe( | 556 base::win::ScopedHandle delegate_write_handle(::CreateNamedPipe( |
| 553 base::ASCIIToUTF16(input_pipe_name).c_str(), | 557 base::ASCIIToUTF16(input_pipe_name).c_str(), |
| 554 PIPE_ACCESS_OUTBOUND, | 558 PIPE_ACCESS_OUTBOUND, |
| 555 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS, | 559 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS, |
| 556 1, | 560 1, |
| 557 kBufferSize, | 561 kBufferSize, |
| 558 kBufferSize, | 562 kBufferSize, |
| 559 kTimeOutMilliseconds, | 563 kTimeOutMilliseconds, |
| 560 &security_attributes)); | 564 &security_attributes)); |
| 561 | 565 |
| 562 if (!delegate_write_handle_.IsValid()) { | 566 if (!delegate_write_handle.IsValid()) { |
| 563 LOG_GETLASTERROR(ERROR) << | 567 LOG_GETLASTERROR(ERROR) << |
| 564 "Failed to create named pipe '" << input_pipe_name << "'"; | 568 "Failed to create named pipe '" << input_pipe_name << "'"; |
| 565 OnError(); | 569 OnError(); |
| 566 return; | 570 return; |
| 567 } | 571 } |
| 568 | 572 |
| 569 // Generate a unique name for the input channel. | 573 // Generate a unique name for the input channel. |
| 570 std::string output_pipe_name(kChromePipeNamePrefix); | 574 std::string output_pipe_name(kChromePipeNamePrefix); |
| 571 output_pipe_name.append(IPC::Channel::GenerateUniqueRandomChannelID()); | 575 output_pipe_name.append(IPC::Channel::GenerateUniqueRandomChannelID()); |
| 572 | 576 |
| 573 delegate_read_handle_.Set(CreateNamedPipe( | 577 base::win::ScopedHandle delegate_read_handle(::CreateNamedPipe( |
| 574 base::ASCIIToUTF16(output_pipe_name).c_str(), | 578 base::ASCIIToUTF16(output_pipe_name).c_str(), |
| 575 PIPE_ACCESS_INBOUND, | 579 PIPE_ACCESS_INBOUND, |
| 576 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS, | 580 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_REJECT_REMOTE_CLIENTS, |
| 577 1, | 581 1, |
| 578 kBufferSize, | 582 kBufferSize, |
| 579 kBufferSize, | 583 kBufferSize, |
| 580 kTimeOutMilliseconds, | 584 kTimeOutMilliseconds, |
| 581 &security_attributes)); | 585 &security_attributes)); |
| 582 | 586 |
| 583 if (!delegate_read_handle_.IsValid()) { | 587 if (!delegate_read_handle.IsValid()) { |
| 584 LOG_GETLASTERROR(ERROR) << | 588 LOG_GETLASTERROR(ERROR) << |
| 585 "Failed to create named pipe '" << output_pipe_name << "'"; | 589 "Failed to create named pipe '" << output_pipe_name << "'"; |
| 586 OnError(); | 590 OnError(); |
| 587 return; | 591 return; |
| 588 } | 592 } |
| 589 | 593 |
| 590 const CommandLine* current_command_line = CommandLine::ForCurrentProcess(); | 594 const CommandLine* current_command_line = CommandLine::ForCurrentProcess(); |
| 591 const CommandLine::SwitchMap& switches = current_command_line->GetSwitches(); | 595 const CommandLine::SwitchMap& switches = current_command_line->GetSwitches(); |
| 592 CommandLine::StringVector args = current_command_line->GetArgs(); | 596 CommandLine::StringVector args = current_command_line->GetArgs(); |
| 593 | 597 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 615 // Launch the child process requesting elevation. | 619 // Launch the child process requesting elevation. |
| 616 SHELLEXECUTEINFO info; | 620 SHELLEXECUTEINFO info; |
| 617 memset(&info, 0, sizeof(info)); | 621 memset(&info, 0, sizeof(info)); |
| 618 info.cbSize = sizeof(info); | 622 info.cbSize = sizeof(info); |
| 619 info.lpVerb = L"runas"; | 623 info.lpVerb = L"runas"; |
| 620 info.lpFile = binary.value().c_str(); | 624 info.lpFile = binary.value().c_str(); |
| 621 info.lpParameters = parameters.c_str(); | 625 info.lpParameters = parameters.c_str(); |
| 622 info.nShow = SW_SHOWNORMAL; | 626 info.nShow = SW_SHOWNORMAL; |
| 623 | 627 |
| 624 if (!ShellExecuteEx(&info)) { | 628 if (!ShellExecuteEx(&info)) { |
| 629 DWORD error = ::GetLastError(); |
| 625 LOG_GETLASTERROR(ERROR) << "Unable to launch '" << binary.value() << "'"; | 630 LOG_GETLASTERROR(ERROR) << "Unable to launch '" << binary.value() << "'"; |
| 626 OnError(); | 631 if (error != ERROR_CANCELLED) { |
| 632 OnError(); |
| 633 } |
| 627 return; | 634 return; |
| 628 } | 635 } |
| 629 | 636 |
| 630 if (!ConnectNamedPipe(delegate_write_handle_.Get(), NULL)) { | 637 if (!::ConnectNamedPipe(delegate_write_handle.Get(), NULL)) { |
| 631 DWORD error = ::GetLastError(); | 638 DWORD error = ::GetLastError(); |
| 632 if (error != ERROR_PIPE_CONNECTED) { | 639 if (error != ERROR_PIPE_CONNECTED) { |
| 633 LOG(ERROR) << "Unable to connect '" << input_pipe_name << "': " << error; | 640 LOG_GETLASTERROR(ERROR) << "Unable to connect '" |
| 641 << input_pipe_name << "'"; |
| 634 OnError(); | 642 OnError(); |
| 635 return; | 643 return; |
| 636 } | 644 } |
| 637 } | 645 } |
| 638 | 646 |
| 639 if (!ConnectNamedPipe(delegate_read_handle_.Get(), NULL)) { | 647 if (!::ConnectNamedPipe(delegate_read_handle.Get(), NULL)) { |
| 640 DWORD error = ::GetLastError(); | 648 DWORD error = ::GetLastError(); |
| 641 if (error != ERROR_PIPE_CONNECTED) { | 649 if (error != ERROR_PIPE_CONNECTED) { |
| 642 LOG(ERROR) << "Unable to connect '" << output_pipe_name << "': " << error; | 650 LOG_GETLASTERROR(ERROR) << "Unable to connect '" |
| 651 << output_pipe_name << "'"; |
| 643 OnError(); | 652 OnError(); |
| 644 return; | 653 return; |
| 645 } | 654 } |
| 646 } | 655 } |
| 647 | 656 |
| 648 // Set up the native messaging channel to talk to the elevated host. | 657 // Set up the native messaging channel to talk to the elevated host. |
| 649 // Note that input for the elevate channel is output forthe elevated host. | 658 // Note that input for the elevate channel is output forthe elevated host. |
| 650 elevated_channel_.reset(new NativeMessagingChannel( | 659 elevated_channel_.reset(new NativeMessagingChannel( |
| 651 delegate_read_handle_.Get(), delegate_write_handle_.Get())); | 660 delegate_read_handle.Take(), delegate_write_handle.Take())); |
| 652 | 661 |
| 653 elevated_channel_->Start( | 662 elevated_channel_->Start( |
| 654 base::Bind(&Me2MeNativeMessagingHost::ProcessDelegateResponse, weak_ptr_), | 663 base::Bind(&Me2MeNativeMessagingHost::ProcessDelegateResponse, weak_ptr_), |
| 655 base::Bind(&Me2MeNativeMessagingHost::Stop, weak_ptr_)); | 664 base::Bind(&Me2MeNativeMessagingHost::Stop, weak_ptr_)); |
| 656 } | 665 } |
| 657 | 666 |
| 658 void Me2MeNativeMessagingHost::ProcessDelegateResponse( | 667 void Me2MeNativeMessagingHost::ProcessDelegateResponse( |
| 659 scoped_ptr<base::DictionaryValue> message) { | 668 scoped_ptr<base::DictionaryValue> message) { |
| 660 DCHECK(thread_checker_.CalledOnValidThread()); | 669 DCHECK(thread_checker_.CalledOnValidThread()); |
| 661 | 670 |
| 662 // Simply pass along the response from the elevated host to the client. | 671 // Simply pass along the response from the elevated host to the client. |
| 663 channel_->SendMessage(message.Pass()); | 672 channel_->SendMessage(message.Pass()); |
| 664 } | 673 } |
| 665 | 674 |
| 666 #else // defined(OS_WIN) | 675 #else // defined(OS_WIN) |
| 667 | 676 |
| 668 void Me2MeNativeMessagingHost::DelegateToElevatedHost( | 677 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( |
| 669 scoped_ptr<base::DictionaryValue> message, | 678 scoped_ptr<base::DictionaryValue> message) { |
| 670 scoped_ptr<base::DictionaryValue> response) { | |
| 671 NOTREACHED(); | 679 NOTREACHED(); |
| 680 return false; |
| 672 } | 681 } |
| 673 | 682 |
| 674 #endif // !defined(OS_WIN) | 683 #endif // !defined(OS_WIN) |
| 675 | 684 |
| 676 } // namespace remoting | 685 } // namespace remoting |
| OLD | NEW |