Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(790)

Side by Side Diff: chrome/browser/extensions/api/messaging/message_service.cc

Issue 591463003: Remote Assistance on Chrome OS Part III - NativeMessageHost (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@native_messaging
Patch Set: Address Sergey's feedback Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/browser/extensions/api/messaging/message_service.h" 5 #include "chrome/browser/extensions/api/messaging/message_service.h"
6 6
7 #include "base/atomic_sequence_num.h" 7 #include "base/atomic_sequence_num.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/json/json_writer.h" 10 #include "base/json/json_writer.h"
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/prefs/pref_service.h"
13 #include "base/stl_util.h" 14 #include "base/stl_util.h"
14 #include "base/values.h" 15 #include "base/values.h"
15 #include "chrome/browser/chrome_notification_types.h" 16 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" 17 #include "chrome/browser/extensions/api/messaging/extension_message_port.h"
17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" 18 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h"
18 #include "chrome/browser/extensions/api/messaging/native_message_port.h" 19 #include "chrome/browser/extensions/api/messaging/native_message_port.h"
19 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" 20 #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
20 #include "chrome/browser/extensions/extension_service.h" 21 #include "chrome/browser/extensions/extension_service.h"
21 #include "chrome/browser/extensions/extension_tab_util.h" 22 #include "chrome/browser/extensions/extension_tab_util.h"
22 #include "chrome/browser/extensions/extension_util.h" 23 #include "chrome/browser/extensions/extension_util.h"
23 #include "chrome/browser/profiles/profile.h" 24 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/tab_contents/tab_util.h" 25 #include "chrome/browser/tab_contents/tab_util.h"
25 #include "content/public/browser/notification_service.h" 26 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/render_process_host.h" 27 #include "content/public/browser/render_process_host.h"
27 #include "content/public/browser/render_view_host.h" 28 #include "content/public/browser/render_view_host.h"
28 #include "content/public/browser/render_widget_host.h" 29 #include "content/public/browser/render_widget_host.h"
29 #include "content/public/browser/render_widget_host_view.h" 30 #include "content/public/browser/render_widget_host_view.h"
30 #include "content/public/browser/site_instance.h" 31 #include "content/public/browser/site_instance.h"
31 #include "content/public/browser/web_contents.h" 32 #include "content/public/browser/web_contents.h"
32 #include "extensions/browser/extension_host.h" 33 #include "extensions/browser/extension_host.h"
33 #include "extensions/browser/extension_system.h" 34 #include "extensions/browser/extension_system.h"
34 #include "extensions/browser/extensions_browser_client.h" 35 #include "extensions/browser/extensions_browser_client.h"
35 #include "extensions/browser/lazy_background_task_queue.h" 36 #include "extensions/browser/lazy_background_task_queue.h"
37 #include "extensions/browser/pref_names.h"
36 #include "extensions/browser/process_manager.h" 38 #include "extensions/browser/process_manager.h"
37 #include "extensions/common/extension.h" 39 #include "extensions/common/extension.h"
38 #include "extensions/common/manifest_constants.h" 40 #include "extensions/common/manifest_constants.h"
39 #include "extensions/common/manifest_handlers/background_info.h" 41 #include "extensions/common/manifest_handlers/background_info.h"
40 #include "extensions/common/manifest_handlers/externally_connectable.h" 42 #include "extensions/common/manifest_handlers/externally_connectable.h"
41 #include "extensions/common/manifest_handlers/incognito_info.h" 43 #include "extensions/common/manifest_handlers/incognito_info.h"
42 #include "extensions/common/permissions/permissions_data.h" 44 #include "extensions/common/permissions/permissions_data.h"
43 #include "net/base/completion_callback.h" 45 #include "net/base/completion_callback.h"
44 #include "url/gurl.h" 46 #include "url/gurl.h"
45 47
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 } 366 }
365 367
366 if (!has_permission) { 368 if (!has_permission) {
367 DispatchOnDisconnect(source, receiver_port_id, kMissingPermissionError); 369 DispatchOnDisconnect(source, receiver_port_id, kMissingPermissionError);
368 return; 370 return;
369 } 371 }
370 372
371 PrefService* pref_service = profile->GetPrefs(); 373 PrefService* pref_service = profile->GetPrefs();
372 374
373 // Verify that the host is not blocked by policies. 375 // Verify that the host is not blocked by policies.
374 NativeMessageProcessHost::PolicyPermission policy_permission = 376 PolicyPermission policy_permission =
375 NativeMessageProcessHost::IsHostAllowed(pref_service, native_app_name); 377 IsHostAllowed(pref_service, native_app_name);
376 if (policy_permission == NativeMessageProcessHost::DISALLOW) { 378 if (policy_permission == DISALLOW) {
377 DispatchOnDisconnect(source, receiver_port_id, kProhibitedByPoliciesError); 379 DispatchOnDisconnect(source, receiver_port_id, kProhibitedByPoliciesError);
378 return; 380 return;
379 } 381 }
380 382
381 scoped_ptr<MessageChannel> channel(new MessageChannel()); 383 scoped_ptr<MessageChannel> channel(new MessageChannel());
382 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, 384 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL,
383 source_extension_id)); 385 source_extension_id));
384 386
385 // Get handle of the native view and pass it to the native messaging host. 387 // Get handle of the native view and pass it to the native messaging host.
386 gfx::NativeView native_view = 388 gfx::NativeView native_view =
387 content::RenderWidgetHost::FromID(source_process_id, source_routing_id)-> 389 content::RenderWidgetHost::FromID(source_process_id, source_routing_id)->
388 GetView()->GetNativeView(); 390 GetView()->GetNativeView();
389 391
390 scoped_ptr<NativeMessageProcessHost> native_process = 392 scoped_ptr<NativeMessageHost> native_host = NativeMessageHost::Create(
391 NativeMessageProcessHost::Create( 393 native_view,
392 native_view, 394 base::WeakPtr<NativeMessageHost::Client>(weak_factory_.GetWeakPtr()),
393 base::WeakPtr<NativeMessageProcessHost::Client>( 395 source_extension_id,
394 weak_factory_.GetWeakPtr()), 396 native_app_name,
395 source_extension_id, native_app_name, receiver_port_id, 397 receiver_port_id,
396 policy_permission == NativeMessageProcessHost::ALLOW_ALL); 398 policy_permission == ALLOW_ALL);
397 399
398 // Abandon the channel. 400 // Abandon the channel.
399 if (!native_process.get()) { 401 if (!native_host.get()) {
400 LOG(ERROR) << "Failed to create native process."; 402 LOG(ERROR) << "Failed to create native process.";
401 DispatchOnDisconnect( 403 DispatchOnDisconnect(
402 source, receiver_port_id, kReceivingEndDoesntExistError); 404 source, receiver_port_id, kReceivingEndDoesntExistError);
403 return; 405 return;
404 } 406 }
405 channel->receiver.reset(new NativeMessagePort(native_process.release())); 407 channel->receiver.reset(new NativeMessagePort(native_host.Pass()));
406 408
407 // Keep the opener alive until the channel is closed. 409 // Keep the opener alive until the channel is closed.
408 channel->opener->IncrementLazyKeepaliveCount(); 410 channel->opener->IncrementLazyKeepaliveCount();
409 411
410 AddChannel(channel.release(), receiver_port_id); 412 AddChannel(channel.release(), receiver_port_id);
411 #else // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) 413 #else // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX))
412 const char kNativeMessagingNotSupportedError[] = 414 const char kNativeMessagingNotSupportedError[] =
413 "Native Messaging is not supported on this platform."; 415 "Native Messaging is not supported on this platform.";
414 DispatchOnDisconnect( 416 DispatchOnDisconnect(
415 source, receiver_port_id, kNativeMessagingNotSupportedError); 417 source, receiver_port_id, kNativeMessagingNotSupportedError);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 if (iter == channels_.end()) { 557 if (iter == channels_.end()) {
556 // If this channel is pending, queue up the PostMessage to run once 558 // If this channel is pending, queue up the PostMessage to run once
557 // the channel opens. 559 // the channel opens.
558 EnqueuePendingMessage(source_port_id, channel_id, message); 560 EnqueuePendingMessage(source_port_id, channel_id, message);
559 return; 561 return;
560 } 562 }
561 563
562 DispatchMessage(source_port_id, iter->second, message); 564 DispatchMessage(source_port_id, iter->second, message);
563 } 565 }
564 566
565 void MessageService::PostMessageFromNativeProcess(int port_id, 567 void MessageService::PostMessageFromNativeHost(int port_id,
566 const std::string& message) { 568 const std::string& message) {
567 PostMessage(port_id, Message(message, false /* user_gesture */)); 569 PostMessage(port_id, Message(message, false /* user_gesture */));
568 } 570 }
569 571
570 void MessageService::Observe(int type, 572 void MessageService::Observe(int type,
571 const content::NotificationSource& source, 573 const content::NotificationSource& source,
572 const content::NotificationDetails& details) { 574 const content::NotificationDetails& details) {
573 switch (type) { 575 switch (type) {
574 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: 576 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED:
575 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { 577 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
576 content::RenderProcessHost* renderer = 578 content::RenderProcessHost* renderer =
577 content::Source<content::RenderProcessHost>(source).ptr(); 579 content::Source<content::RenderProcessHost>(source).ptr();
578 OnProcessClosed(renderer); 580 OnProcessClosed(renderer);
579 break; 581 break;
580 } 582 }
581 default: 583 default:
582 NOTREACHED(); 584 NOTREACHED();
583 return; 585 return;
584 } 586 }
585 } 587 }
586 588
589 // static
590 MessageService::PolicyPermission MessageService::IsHostAllowed(
591 const PrefService* pref_service,
592 const std::string& native_host_name) {
593 PolicyPermission allow_result = ALLOW_ALL;
594 if (pref_service->IsManagedPreference(
595 pref_names::kNativeMessagingUserLevelHosts)) {
596 if (!pref_service->GetBoolean(pref_names::kNativeMessagingUserLevelHosts))
597 allow_result = ALLOW_SYSTEM_ONLY;
598 }
599
600 // All native messaging hosts are allowed if there is no blacklist.
601 if (!pref_service->IsManagedPreference(pref_names::kNativeMessagingBlacklist))
602 return allow_result;
603 const base::ListValue* blacklist =
604 pref_service->GetList(pref_names::kNativeMessagingBlacklist);
605 if (!blacklist)
606 return allow_result;
607
608 // Check if the name or the wildcard is in the blacklist.
609 base::StringValue name_value(native_host_name);
610 base::StringValue wildcard_value("*");
611 if (blacklist->Find(name_value) == blacklist->end() &&
612 blacklist->Find(wildcard_value) == blacklist->end()) {
613 return allow_result;
614 }
615
616 // The native messaging host is blacklisted. Check the whitelist.
617 if (pref_service->IsManagedPreference(
618 pref_names::kNativeMessagingWhitelist)) {
619 const base::ListValue* whitelist =
620 pref_service->GetList(pref_names::kNativeMessagingWhitelist);
621 if (whitelist && whitelist->Find(name_value) != whitelist->end())
622 return allow_result;
623 }
624
625 return DISALLOW;
626 }
627
587 void MessageService::OnProcessClosed(content::RenderProcessHost* process) { 628 void MessageService::OnProcessClosed(content::RenderProcessHost* process) {
588 // Close any channels that share this renderer. We notify the opposite 629 // Close any channels that share this renderer. We notify the opposite
589 // port that his pair has closed. 630 // port that his pair has closed.
590 for (MessageChannelMap::iterator it = channels_.begin(); 631 for (MessageChannelMap::iterator it = channels_.begin();
591 it != channels_.end(); ) { 632 it != channels_.end(); ) {
592 MessageChannelMap::iterator current = it++; 633 MessageChannelMap::iterator current = it++;
593 634
594 content::RenderProcessHost* opener_process = 635 content::RenderProcessHost* opener_process =
595 current->second->opener->GetRenderProcessHost(); 636 current->second->opener->GetRenderProcessHost();
596 content::RenderProcessHost* receiver_process = 637 content::RenderProcessHost* receiver_process =
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 } 796 }
756 797
757 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, 798 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source,
758 int port_id, 799 int port_id,
759 const std::string& error_message) { 800 const std::string& error_message) {
760 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); 801 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, "");
761 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); 802 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message);
762 } 803 }
763 804
764 } // namespace extensions 805 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698