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

Side by Side Diff: chrome/browser/extensions/api/messaging/native_message_process_host.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: Created 6 years, 2 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/native_message_process_host.h" 5 #include "chrome/browser/extensions/api/messaging/native_message_process_host.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/files/file_path.h" 8 #include "base/files/file_path.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/process/kill.h" 10 #include "base/process/kill.h"
12 #include "base/threading/sequenced_worker_pool.h" 11 #include "base/threading/sequenced_worker_pool.h"
13 #include "base/values.h"
14 #include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest .h" 12 #include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest .h"
15 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h" 13 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h"
16 #include "chrome/common/chrome_version_info.h" 14 #include "chrome/common/chrome_version_info.h"
17 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/browser_thread.h"
18 #include "extensions/browser/pref_names.h"
19 #include "extensions/common/constants.h" 16 #include "extensions/common/constants.h"
20 #include "extensions/common/features/feature.h" 17 #include "extensions/common/features/feature.h"
21 #include "net/base/file_stream.h" 18 #include "net/base/file_stream.h"
22 #include "net/base/io_buffer.h" 19 #include "net/base/io_buffer.h"
23 #include "net/base/net_errors.h" 20 #include "net/base/net_errors.h"
24 #include "net/base/net_util.h" 21 #include "net/base/net_util.h"
25 #include "url/gurl.h" 22 #include "url/gurl.h"
26 23
27 namespace { 24 namespace {
28 25
(...skipping 15 matching lines...) Expand all
44 const char kNotFoundError[] = "Specified native messaging host not found."; 41 const char kNotFoundError[] = "Specified native messaging host not found.";
45 const char kForbiddenError[] = 42 const char kForbiddenError[] =
46 "Access to the specified native messaging host is forbidden."; 43 "Access to the specified native messaging host is forbidden.";
47 const char kHostInputOuputError[] = 44 const char kHostInputOuputError[] =
48 "Error when communicating with the native messaging host."; 45 "Error when communicating with the native messaging host.";
49 46
50 } // namespace 47 } // namespace
51 48
52 namespace extensions { 49 namespace extensions {
53 50
54 // static
55 NativeMessageProcessHost::PolicyPermission
56 NativeMessageProcessHost::IsHostAllowed(const PrefService* pref_service,
57 const std::string& native_host_name) {
58 NativeMessageProcessHost::PolicyPermission allow_result = ALLOW_ALL;
59 if (pref_service->IsManagedPreference(
60 pref_names::kNativeMessagingUserLevelHosts)) {
61 if (!pref_service->GetBoolean(pref_names::kNativeMessagingUserLevelHosts))
62 allow_result = ALLOW_SYSTEM_ONLY;
63 }
64
65 // All native messaging hosts are allowed if there is no blacklist.
66 if (!pref_service->IsManagedPreference(pref_names::kNativeMessagingBlacklist))
67 return allow_result;
68 const base::ListValue* blacklist =
69 pref_service->GetList(pref_names::kNativeMessagingBlacklist);
70 if (!blacklist)
71 return allow_result;
72
73 // Check if the name or the wildcard is in the blacklist.
74 base::StringValue name_value(native_host_name);
75 base::StringValue wildcard_value("*");
76 if (blacklist->Find(name_value) == blacklist->end() &&
77 blacklist->Find(wildcard_value) == blacklist->end()) {
78 return allow_result;
79 }
80
81 // The native messaging host is blacklisted. Check the whitelist.
82 if (pref_service->IsManagedPreference(
83 pref_names::kNativeMessagingWhitelist)) {
84 const base::ListValue* whitelist =
85 pref_service->GetList(pref_names::kNativeMessagingWhitelist);
86 if (whitelist && whitelist->Find(name_value) != whitelist->end())
87 return allow_result;
88 }
89
90 return DISALLOW;
91 }
92
93 NativeMessageProcessHost::NativeMessageProcessHost( 51 NativeMessageProcessHost::NativeMessageProcessHost(
94 base::WeakPtr<Client> weak_client_ui,
95 const std::string& source_extension_id, 52 const std::string& source_extension_id,
96 const std::string& native_host_name, 53 const std::string& native_host_name,
97 int destination_port,
98 scoped_ptr<NativeProcessLauncher> launcher) 54 scoped_ptr<NativeProcessLauncher> launcher)
99 : weak_client_ui_(weak_client_ui), 55 : source_extension_id_(source_extension_id),
100 source_extension_id_(source_extension_id),
101 native_host_name_(native_host_name), 56 native_host_name_(native_host_name),
102 destination_port_(destination_port),
103 launcher_(launcher.Pass()), 57 launcher_(launcher.Pass()),
104 closed_(false), 58 closed_(false),
105 process_handle_(base::kNullProcessHandle), 59 process_handle_(base::kNullProcessHandle),
106 #if defined(OS_POSIX) 60 #if defined(OS_POSIX)
107 read_file_(-1), 61 read_file_(-1),
108 #endif 62 #endif
109 read_pending_(false), 63 read_pending_(false),
110 write_pending_(false) { 64 write_pending_(false) {
111 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 65 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
112 66
113 // It's safe to use base::Unretained() here because NativeMessagePort always 67 // It's safe to use base::Unretained() here because NativeMessagePort always
114 // deletes us on the IO thread. 68 // deletes us on the IO thread.
115 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, 69 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
116 base::Bind(&NativeMessageProcessHost::LaunchHostProcess, 70 base::Bind(&NativeMessageProcessHost::LaunchHostProcess,
117 base::Unretained(this))); 71 base::Unretained(this)));
118 } 72 }
119 73
120 NativeMessageProcessHost::~NativeMessageProcessHost() { 74 NativeMessageProcessHost::~NativeMessageProcessHost() {
121 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 75 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
122 Close(std::string()); 76 Close(std::string());
123 } 77 }
124 78
125 // static 79 // static
126 scoped_ptr<NativeMessageProcessHost> NativeMessageProcessHost::Create( 80 scoped_ptr<NativeMessageHost> NativeMessageHost::Create(
127 gfx::NativeView native_view, 81 gfx::NativeView native_view,
128 base::WeakPtr<Client> weak_client_ui,
129 const std::string& source_extension_id, 82 const std::string& source_extension_id,
130 const std::string& native_host_name, 83 const std::string& native_host_name,
131 int destination_port,
132 bool allow_user_level) { 84 bool allow_user_level) {
133 return CreateWithLauncher(weak_client_ui, source_extension_id, 85 return NativeMessageProcessHost::CreateWithLauncher(
134 native_host_name, destination_port, 86 source_extension_id,
135 NativeProcessLauncher::CreateDefault( 87 native_host_name,
136 allow_user_level, native_view)); 88 NativeProcessLauncher::CreateDefault(allow_user_level, native_view));
137 } 89 }
138 90
139 // static 91 // static
140 scoped_ptr<NativeMessageProcessHost> 92 scoped_ptr<NativeMessageHost> NativeMessageProcessHost::CreateWithLauncher(
141 NativeMessageProcessHost::CreateWithLauncher(
142 base::WeakPtr<Client> weak_client_ui,
143 const std::string& source_extension_id, 93 const std::string& source_extension_id,
144 const std::string& native_host_name, 94 const std::string& native_host_name,
145 int destination_port,
146 scoped_ptr<NativeProcessLauncher> launcher) { 95 scoped_ptr<NativeProcessLauncher> launcher) {
147 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 96 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
148 97
149 scoped_ptr<NativeMessageProcessHost> process(new NativeMessageProcessHost( 98 scoped_ptr<NativeMessageHost> process(
150 weak_client_ui, source_extension_id, native_host_name, 99 new NativeMessageProcessHost(source_extension_id,
151 destination_port, launcher.Pass())); 100 native_host_name,
101 launcher.Pass()));
152 102
153 return process.Pass(); 103 return process.Pass();
154 } 104 }
155 105
156 void NativeMessageProcessHost::LaunchHostProcess() { 106 void NativeMessageProcessHost::LaunchHostProcess() {
157 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 107 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
158 108
159 GURL origin(std::string(kExtensionScheme) + "://" + source_extension_id_); 109 GURL origin(std::string(kExtensionScheme) + "://" + source_extension_id_);
160 launcher_->Launch(origin, native_host_name_, 110 launcher_->Launch(origin, native_host_name_,
161 base::Bind(&NativeMessageProcessHost::OnHostProcessLaunched, 111 base::Bind(&NativeMessageProcessHost::OnHostProcessLaunched,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 // Push new message to the write queue. 172 // Push new message to the write queue.
223 write_queue_.push(buffer); 173 write_queue_.push(buffer);
224 174
225 // Send() may be called before the host process is started. In that case the 175 // Send() may be called before the host process is started. In that case the
226 // message will be written when OnHostProcessLaunched() is called. If it's 176 // message will be written when OnHostProcessLaunched() is called. If it's
227 // already started then write the message now. 177 // already started then write the message now.
228 if (write_stream_) 178 if (write_stream_)
229 DoWrite(); 179 DoWrite();
230 } 180 }
231 181
182 void NativeMessageProcessHost::set_client(base::WeakPtr<Client> client) {
183 weak_client_ = client;
184 }
185
232 #if defined(OS_POSIX) 186 #if defined(OS_POSIX)
233 void NativeMessageProcessHost::OnFileCanReadWithoutBlocking(int fd) { 187 void NativeMessageProcessHost::OnFileCanReadWithoutBlocking(int fd) {
234 DCHECK_EQ(fd, read_file_); 188 DCHECK_EQ(fd, read_file_);
235 DoRead(); 189 DoRead();
236 } 190 }
237 191
238 void NativeMessageProcessHost::OnFileCanWriteWithoutBlocking(int fd) { 192 void NativeMessageProcessHost::OnFileCanWriteWithoutBlocking(int fd) {
239 NOTREACHED(); 193 NOTREACHED();
240 } 194 }
241 #endif // !defined(OS_POSIX) 195 #endif // !defined(OS_POSIX)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 if (message_size > kMaximumMessageSize) { 275 if (message_size > kMaximumMessageSize) {
322 LOG(ERROR) << "Native Messaging host tried sending a message that is " 276 LOG(ERROR) << "Native Messaging host tried sending a message that is "
323 << message_size << " bytes long."; 277 << message_size << " bytes long.";
324 Close(kHostInputOuputError); 278 Close(kHostInputOuputError);
325 return; 279 return;
326 } 280 }
327 281
328 if (incoming_data_.size() < message_size + kMessageHeaderSize) 282 if (incoming_data_.size() < message_size + kMessageHeaderSize)
329 return; 283 return;
330 284
331 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 285 content::BrowserThread::PostTask(
332 base::Bind(&Client::PostMessageFromNativeProcess, weak_client_ui_, 286 content::BrowserThread::UI,
333 destination_port_, 287 FROM_HERE,
334 incoming_data_.substr(kMessageHeaderSize, message_size))); 288 base::Bind(&Client::PostMessageFromNativeHost,
289 weak_client_,
290 incoming_data_.substr(kMessageHeaderSize, message_size)));
335 291
336 incoming_data_.erase(0, kMessageHeaderSize + message_size); 292 incoming_data_.erase(0, kMessageHeaderSize + message_size);
337 } 293 }
338 } 294 }
339 295
340 void NativeMessageProcessHost::DoWrite() { 296 void NativeMessageProcessHost::DoWrite() {
341 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 297 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
342 298
343 while (!write_pending_ && !closed_) { 299 while (!write_pending_ && !closed_) {
344 if (!current_write_buffer_.get() || 300 if (!current_write_buffer_.get() ||
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 DoWrite(); 341 DoWrite();
386 } 342 }
387 343
388 void NativeMessageProcessHost::Close(const std::string& error_message) { 344 void NativeMessageProcessHost::Close(const std::string& error_message) {
389 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 345 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
390 346
391 if (!closed_) { 347 if (!closed_) {
392 closed_ = true; 348 closed_ = true;
393 read_stream_.reset(); 349 read_stream_.reset();
394 write_stream_.reset(); 350 write_stream_.reset();
395 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, 351 content::BrowserThread::PostTask(
396 base::Bind(&Client::CloseChannel, weak_client_ui_, 352 content::BrowserThread::UI,
397 destination_port_, error_message)); 353 FROM_HERE,
354 base::Bind(&Client::CloseChannel, weak_client_, error_message));
398 } 355 }
399 356
400 if (process_handle_ != base::kNullProcessHandle) { 357 if (process_handle_ != base::kNullProcessHandle) {
401 // Kill the host process if necessary to make sure we don't leave zombies. 358 // Kill the host process if necessary to make sure we don't leave zombies.
402 // On OSX base::EnsureProcessTerminated() may block, so we have to post a 359 // On OSX base::EnsureProcessTerminated() may block, so we have to post a
403 // task on the blocking pool. 360 // task on the blocking pool.
404 #if defined(OS_MACOSX) 361 #if defined(OS_MACOSX)
405 content::BrowserThread::PostBlockingPoolTask( 362 content::BrowserThread::PostBlockingPoolTask(
406 FROM_HERE, base::Bind(&base::EnsureProcessTerminated, process_handle_)); 363 FROM_HERE, base::Bind(&base::EnsureProcessTerminated, process_handle_));
407 #else 364 #else
408 base::EnsureProcessTerminated(process_handle_); 365 base::EnsureProcessTerminated(process_handle_);
409 #endif 366 #endif
410 process_handle_ = base::kNullProcessHandle; 367 process_handle_ = base::kNullProcessHandle;
411 } 368 }
412 } 369 }
413 370
414 } // namespace extensions 371 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698