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 |