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

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"
18 #include "googleurl/src/gurl.h"
14 19
15 namespace extensions { 20 namespace extensions {
16 21
17 namespace { 22 namespace {
18 23
19 const char kNativeHostsDirectoryName[] = "native_hosts"; 24 const char kNativeHostsDirectoryName[] = "native_hosts";
20 25
26 base::FilePath GetHostManifestPathFromCommandLine(
27 const std::string& native_host_name) {
28 const std::string& value =
29 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
30 switches::kNativeMessagingHosts);
31 if (value.empty())
32 return base::FilePath();
33
34 std::vector<std::string> hosts;
35 base::SplitString(value, ',', &hosts);
36 for (size_t i = 0; i < hosts.size(); ++i) {
37 std::vector<std::string> key_and_value;
38 base::SplitString(hosts[i], '=', &key_and_value);
39 if (key_and_value.size() != 2)
40 continue;
41 if (key_and_value[0] == native_host_name)
42 return base::FilePath::FromUTF8Unsafe(key_and_value[1]);
43 }
44
45 return base::FilePath();
46 }
47
48
21 // Default implementation on NativeProcessLauncher interface. 49 // Default implementation on NativeProcessLauncher interface.
22 class NativeProcessLauncherImpl : public NativeProcessLauncher { 50 class NativeProcessLauncherImpl : public NativeProcessLauncher {
23 public: 51 public:
24 NativeProcessLauncherImpl(); 52 NativeProcessLauncherImpl();
25 virtual ~NativeProcessLauncherImpl(); 53 virtual ~NativeProcessLauncherImpl();
26 54
27 virtual void Launch(const std::string& native_host_name, 55 virtual void Launch(const GURL& origin,
56 const std::string& native_host_name,
28 LaunchedCallback callback) const OVERRIDE; 57 LaunchedCallback callback) const OVERRIDE;
29 58
30 private: 59 private:
31 class Core : public base::RefCountedThreadSafe<Core> { 60 class Core : public base::RefCountedThreadSafe<Core> {
32 public: 61 public:
33 Core(); 62 Core();
34 void Launch(const std::string& native_host_name, 63 void Launch(const GURL& origin,
64 const std::string& native_host_name,
35 LaunchedCallback callback); 65 LaunchedCallback callback);
36 void Detach(); 66 void Detach();
37 private: 67 private:
38 friend class base::RefCountedThreadSafe<Core>; 68 friend class base::RefCountedThreadSafe<Core>;
39 virtual ~Core(); 69 virtual ~Core();
40 70
41 void DoLaunchOnThreadPool(const std::string& native_host_name, 71 void DoLaunchOnThreadPool(const GURL& origin,
72 const std::string& native_host_name,
42 LaunchedCallback callback); 73 LaunchedCallback callback);
43 void CallCallbackOnIOThread(LaunchedCallback callback, 74 void CallCallbackOnIOThread(LaunchedCallback callback,
44 base::ProcessHandle native_process_handle, 75 base::ProcessHandle native_process_handle,
45 base::PlatformFile read_file, 76 base::PlatformFile read_file,
46 base::PlatformFile write_file); 77 base::PlatformFile write_file);
47 78
48 bool detached_; 79 bool detached_;
49 80
50 DISALLOW_COPY_AND_ASSIGN(Core); 81 DISALLOW_COPY_AND_ASSIGN(Core);
51 }; 82 };
(...skipping 10 matching lines...) Expand all
62 NativeProcessLauncherImpl::Core::~Core() { 93 NativeProcessLauncherImpl::Core::~Core() {
63 DCHECK(detached_); 94 DCHECK(detached_);
64 } 95 }
65 96
66 void NativeProcessLauncherImpl::Core::Detach() { 97 void NativeProcessLauncherImpl::Core::Detach() {
67 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 98 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
68 detached_ = true; 99 detached_ = true;
69 } 100 }
70 101
71 void NativeProcessLauncherImpl::Core::Launch( 102 void NativeProcessLauncherImpl::Core::Launch(
103 const GURL& origin,
72 const std::string& native_host_name, 104 const std::string& native_host_name,
73 LaunchedCallback callback) { 105 LaunchedCallback callback) {
74 content::BrowserThread::PostBlockingPoolTask( 106 content::BrowserThread::PostBlockingPoolTask(
75 FROM_HERE, base::Bind(&Core::DoLaunchOnThreadPool, this, 107 FROM_HERE, base::Bind(&Core::DoLaunchOnThreadPool, this,
76 native_host_name, callback)); 108 origin, native_host_name, callback));
77 } 109 }
78 110
79 void NativeProcessLauncherImpl::Core::DoLaunchOnThreadPool( 111 void NativeProcessLauncherImpl::Core::DoLaunchOnThreadPool(
112 const GURL& origin,
80 const std::string& native_host_name, 113 const std::string& native_host_name,
81 LaunchedCallback callback) { 114 LaunchedCallback callback) {
82 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); 115 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
83 116
84 base::FilePath native_host_program; 117 std::string error_message;
85 base::FilePath native_host_registry; 118 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 119
91 // Make sure that the client is not trying to invoke something outside of the 120 if (!NativeMessagingHostManifest::IsValidHostName(native_host_name)) {
92 // proper directory. Eg. '../../dangerous_something.exe'. 121 error_message = "Invalid native host name: " + native_host_name;
93 if (!file_util::ContainsPath(native_host_registry, native_host_program)) { 122 } else {
94 LOG(ERROR) << "Could not find native host: " << native_host_name; 123 // First check if the manifest location is specified in the command line.
124 base::FilePath path = GetHostManifestPathFromCommandLine(native_host_name);
125 if (!path.empty()) {
126 manifest = NativeMessagingHostManifest::Load(path, &error_message);
127 } else {
128 // Try loading the manifest from the default location.
129 manifest = FindAndLoadManifest(native_host_name, &error_message);
130 }
131
132 if (manifest && manifest->name() != native_host_name) {
133 error_message = "Name specified in the manifest does not match.";
134 manifest.reset();
135 }
136 }
137
138 if (!manifest) {
139 // TODO(sergeyu): Report the error to the application.
140 LOG(ERROR) << "Failed to load manifest for native messaging host "
141 << native_host_name << ": " << error_message;
95 content::BrowserThread::PostTask( 142 content::BrowserThread::PostTask(
96 content::BrowserThread::IO, FROM_HERE, 143 content::BrowserThread::IO, FROM_HERE,
97 base::Bind(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread, 144 base::Bind(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread,
98 this, callback, base::kNullProcessHandle, 145 this, callback, base::kNullProcessHandle,
99 base::kInvalidPlatformFileValue, 146 base::kInvalidPlatformFileValue,
100 base::kInvalidPlatformFileValue)); 147 base::kInvalidPlatformFileValue));
101 return; 148 return;
102 } 149 }
103 150
151 if (!manifest->allowed_origins().MatchesSecurityOrigin(origin)) {
152 // Not an allowed origin.
153 content::BrowserThread::PostTask(
154 content::BrowserThread::IO, FROM_HERE,
155 base::Bind(&NativeProcessLauncherImpl::Core::CallCallbackOnIOThread,
156 this, callback, base::kNullProcessHandle,
157 base::kInvalidPlatformFileValue,
158 base::kInvalidPlatformFileValue));
159 return;
160 }
161
162 FilePath native_host_program = manifest->path();
163
104 base::ProcessHandle native_process_handle; 164 base::ProcessHandle native_process_handle;
105 base::PlatformFile read_file; 165 base::PlatformFile read_file;
106 base::PlatformFile write_file; 166 base::PlatformFile write_file;
107 if (!NativeProcessLauncher::LaunchNativeProcess( 167 if (!NativeProcessLauncher::LaunchNativeProcess(
108 native_host_program, &native_process_handle, 168 native_host_program, &native_process_handle,
109 &read_file, &write_file)) { 169 &read_file, &write_file)) {
110 native_process_handle = base::kNullProcessHandle; 170 native_process_handle = base::kNullProcessHandle;
111 } 171 }
112 172
113 content::BrowserThread::PostTask( 173 content::BrowserThread::PostTask(
(...skipping 24 matching lines...) Expand all
138 } 198 }
139 199
140 NativeProcessLauncherImpl::NativeProcessLauncherImpl() 200 NativeProcessLauncherImpl::NativeProcessLauncherImpl()
141 : core_(new Core()) { 201 : core_(new Core()) {
142 } 202 }
143 203
144 NativeProcessLauncherImpl::~NativeProcessLauncherImpl() { 204 NativeProcessLauncherImpl::~NativeProcessLauncherImpl() {
145 core_->Detach(); 205 core_->Detach();
146 } 206 }
147 207
148 void NativeProcessLauncherImpl::Launch(const std::string& native_host_name, 208 void NativeProcessLauncherImpl::Launch(const GURL& origin,
209 const std::string& native_host_name,
149 LaunchedCallback callback) const { 210 LaunchedCallback callback) const {
150 core_->Launch(native_host_name, callback); 211 core_->Launch(origin, native_host_name, callback);
151 } 212 }
152 213
153 } // namespace 214 } // namespace
154 215
155 // static 216 // static
156 scoped_ptr<NativeProcessLauncher> NativeProcessLauncher::CreateDefault() { 217 scoped_ptr<NativeProcessLauncher> NativeProcessLauncher::CreateDefault() {
157 return scoped_ptr<NativeProcessLauncher>(new NativeProcessLauncherImpl()); 218 return scoped_ptr<NativeProcessLauncher>(new NativeProcessLauncherImpl());
158 } 219 }
159 220
160 } // namespace extensions 221 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698