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

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

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

Powered by Google App Engine
This is Rietveld 408576698