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

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

Issue 12285015: Require manifests for native messaging hosts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 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 | Annotate | Revision Log
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_process_launcher.h" 5 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/command_line.h"
8 #include "base/logging.h" 9 #include "base/logging.h"
9 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
10 #include "base/path_service.h" 11 #include "base/path_service.h"
11 #include "base/process_util.h" 12 #include "base/process_util.h"
13 #include "base/string_split.h"
12 #include "base/threading/sequenced_worker_pool.h" 14 #include "base/threading/sequenced_worker_pool.h"
15 #include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest .h"
13 #include "chrome/common/chrome_paths.h" 16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_switches.h"
14 18
15 namespace extensions { 19 namespace extensions {
16 20
17 namespace { 21 namespace {
18 22
19 const char kNativeHostsDirectoryName[] = "native_hosts"; 23 const char kNativeHostsDirectoryName[] = "native_hosts";
20 24
25 scoped_ptr<NativeMessagingHostManifest> LoadHostManifestFromCommandLine(
26 const std::string& native_host_name) {
27 const std::string& value =
28 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
29 switches::kNativeMessagingHosts);
30 if (value.empty())
31 return scoped_ptr<NativeMessagingHostManifest>(NULL);
32
33 std::vector<std::string> hosts;
34 base::SplitString(value, ',', &hosts);
Matt Perry 2013/02/16 02:00:51 note this means that you can't have commas or equa
Sergey Ulanov 2013/02/20 00:05:36 Current design doc says that these names should be
35 for (size_t i = 0; i < hosts.size(); ++i) {
36 std::vector<std::string> key_and_value;
37 base::SplitString(hosts[i], '=', &key_and_value);
38 if (key_and_value.size() != 2)
39 continue;
40 if (key_and_value[0] == native_host_name) {
41 std::string error_message;
42 scoped_ptr<NativeMessagingHostManifest> result =
43 NativeMessagingHostManifest::Load(
44 FilePath::FromUTF8Unsafe(key_and_value[1]),
45 &error_message);
46 if (!result) {
47 LOG(ERROR) << "Failed to load Native Messaging Host manifest "
48 << key_and_value[1] << " " << error_message;
49 }
50 return result.Pass();
51 }
52 }
53
54 return scoped_ptr<NativeMessagingHostManifest>(NULL);
55 }
56
57
21 // Default implementation on NativeProcessLauncher interface. 58 // Default implementation on NativeProcessLauncher interface.
22 class NativeProcessLauncherImpl : public NativeProcessLauncher { 59 class NativeProcessLauncherImpl : public NativeProcessLauncher {
23 public: 60 public:
24 NativeProcessLauncherImpl(); 61 NativeProcessLauncherImpl();
25 virtual ~NativeProcessLauncherImpl(); 62 virtual ~NativeProcessLauncherImpl();
26 63
27 virtual void Launch(const std::string& native_host_name, 64 virtual void Launch(const std::string& origin,
65 const std::string& native_host_name,
28 LaunchedCallback callback) const OVERRIDE; 66 LaunchedCallback callback) const OVERRIDE;
29 67
30 private: 68 private:
31 class Core : public base::RefCountedThreadSafe<Core> { 69 class Core : public base::RefCountedThreadSafe<Core> {
32 public: 70 public:
33 Core(); 71 Core();
34 void Launch(const std::string& native_host_name, 72 void Launch(const std::string& origin,
73 const std::string& native_host_name,
35 LaunchedCallback callback); 74 LaunchedCallback callback);
36 void Detach(); 75 void Detach();
37 private: 76 private:
38 friend class base::RefCountedThreadSafe<Core>; 77 friend class base::RefCountedThreadSafe<Core>;
39 virtual ~Core(); 78 virtual ~Core();
40 79
41 void DoLaunchOnThreadPool(const std::string& native_host_name, 80 void DoLaunchOnThreadPool(const std::string& origin,
81 const std::string& native_host_name,
42 LaunchedCallback callback); 82 LaunchedCallback callback);
43 void CallCallbackOnIOThread(LaunchedCallback callback, 83 void CallCallbackOnIOThread(LaunchedCallback callback,
44 base::ProcessHandle native_process_handle, 84 base::ProcessHandle native_process_handle,
45 base::PlatformFile read_file, 85 base::PlatformFile read_file,
46 base::PlatformFile write_file); 86 base::PlatformFile write_file);
47 87
48 bool detached_; 88 bool detached_;
49 89
50 DISALLOW_COPY_AND_ASSIGN(Core); 90 DISALLOW_COPY_AND_ASSIGN(Core);
51 }; 91 };
(...skipping 10 matching lines...) Expand all
62 NativeProcessLauncherImpl::Core::~Core() { 102 NativeProcessLauncherImpl::Core::~Core() {
63 DCHECK(detached_); 103 DCHECK(detached_);
64 } 104 }
65 105
66 void NativeProcessLauncherImpl::Core::Detach() { 106 void NativeProcessLauncherImpl::Core::Detach() {
67 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 107 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
68 detached_ = true; 108 detached_ = true;
69 } 109 }
70 110
71 void NativeProcessLauncherImpl::Core::Launch( 111 void NativeProcessLauncherImpl::Core::Launch(
112 const std::string& origin,
72 const std::string& native_host_name, 113 const std::string& native_host_name,
73 LaunchedCallback callback) { 114 LaunchedCallback callback) {
74 content::BrowserThread::PostBlockingPoolTask( 115 content::BrowserThread::PostBlockingPoolTask(
75 FROM_HERE, base::Bind(&Core::DoLaunchOnThreadPool, this, 116 FROM_HERE, base::Bind(&Core::DoLaunchOnThreadPool, this,
76 native_host_name, callback)); 117 origin, native_host_name, callback));
77 } 118 }
78 119
79 void NativeProcessLauncherImpl::Core::DoLaunchOnThreadPool( 120 void NativeProcessLauncherImpl::Core::DoLaunchOnThreadPool(
121 const std::string& origin,
80 const std::string& native_host_name, 122 const std::string& native_host_name,
81 LaunchedCallback callback) { 123 LaunchedCallback callback) {
82 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 124 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
83 125
84 base::FilePath native_host_program; 126 std::string error_message;
85 base::FilePath native_host_registry; 127 scoped_ptr<NativeMessagingHostManifest> manifest;
86 CHECK(PathService::Get(chrome::DIR_USER_DATA, &native_host_registry));
87 native_host_registry =
88 native_host_registry.AppendASCII(kNativeHostsDirectoryName);
89 native_host_program = native_host_registry.AppendASCII(native_host_name);
90 128
91 // Make sure that the client is not trying to invoke something outside of the 129 // First try loading the host from the location specified in the command line.
92 // proper directory. Eg. '../../dangerous_something.exe'. 130 manifest = LoadHostManifestFromCommandLine(native_host_name);
93 if (!file_util::ContainsPath(native_host_registry, native_host_program)) { 131
94 LOG(ERROR) << "Could not find native host: " << native_host_name; 132 // If the manifest location wasn't specified in the command line then load it
133 // from the default location.
134 if (!manifest)
135 manifest = FindAndLoadManifest(native_host_name, &error_message);
136
137 if (manifest && manifest->name() != native_host_name) {
138 error_message = "Invalid name specified in the manifest.";
Matt Perry 2013/02/16 02:00:51 "Name specified in the manifest does not match"?
Sergey Ulanov 2013/02/20 00:05:36 Done.
139 manifest.reset();
140 }
141
142 if (!manifest) {
143 // TODO(sergeyu): Report the error to the application.
144 LOG(ERROR) << "Failed to load manifest for native messaging host "
145 << native_host_name << ": " << error_message;
95 content::BrowserThread::PostTask( 146 content::BrowserThread::PostTask(
96 content::BrowserThread::IO, FROM_HERE, 147 content::BrowserThread::IO, FROM_HERE,
97 base::Bind(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread, 148 base::Bind(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread,
98 this, callback, base::kNullProcessHandle, 149 this, callback, base::kNullProcessHandle,
99 base::kInvalidPlatformFileValue, 150 base::kInvalidPlatformFileValue,
100 base::kInvalidPlatformFileValue)); 151 base::kInvalidPlatformFileValue));
101 return; 152 return;
102 } 153 }
103 154
155 if (!manifest->IsAllowedOrigin(origin)) {
156 // Not an allowed origin
157 content::BrowserThread::PostTask(
158 content::BrowserThread::IO, FROM_HERE,
159 base::Bind(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread,
160 this, callback, base::kNullProcessHandle,
161 base::kInvalidPlatformFileValue,
162 base::kInvalidPlatformFileValue));
163 return;
164 }
165
166 FilePath native_host_program = manifest->path();
167
104 base::ProcessHandle native_process_handle; 168 base::ProcessHandle native_process_handle;
105 base::PlatformFile read_file; 169 base::PlatformFile read_file;
106 base::PlatformFile write_file; 170 base::PlatformFile write_file;
107 if (!NativeProcessLauncher::LaunchNativeProcess( 171 if (!NativeProcessLauncher::LaunchNativeProcess(
108 native_host_program, &native_process_handle, 172 native_host_program, &native_process_handle,
109 &read_file, &write_file)) { 173 &read_file, &write_file)) {
110 native_process_handle = base::kNullProcessHandle; 174 native_process_handle = base::kNullProcessHandle;
111 } 175 }
112 176
113 content::BrowserThread::PostTask( 177 content::BrowserThread::PostTask(
(...skipping 24 matching lines...) Expand all
138 } 202 }
139 203
140 NativeProcessLauncherImpl::NativeProcessLauncherImpl() 204 NativeProcessLauncherImpl::NativeProcessLauncherImpl()
141 : core_(new Core()) { 205 : core_(new Core()) {
142 } 206 }
143 207
144 NativeProcessLauncherImpl::~NativeProcessLauncherImpl() { 208 NativeProcessLauncherImpl::~NativeProcessLauncherImpl() {
145 core_->Detach(); 209 core_->Detach();
146 } 210 }
147 211
148 void NativeProcessLauncherImpl::Launch(const std::string& native_host_name, 212 void NativeProcessLauncherImpl::Launch(const std::string& origin,
213 const std::string& native_host_name,
149 LaunchedCallback callback) const { 214 LaunchedCallback callback) const {
150 core_->Launch(native_host_name, callback); 215 core_->Launch(origin, native_host_name, callback);
151 } 216 }
152 217
153 } // namespace 218 } // namespace
154 219
155 // static 220 // static
156 scoped_ptr<NativeProcessLauncher> NativeProcessLauncher::CreateDefault() { 221 scoped_ptr<NativeProcessLauncher> NativeProcessLauncher::CreateDefault() {
157 return scoped_ptr<NativeProcessLauncher>(new NativeProcessLauncherImpl()); 222 return scoped_ptr<NativeProcessLauncher>(new NativeProcessLauncherImpl());
158 } 223 }
159 224
160 } // namespace extensions 225 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698