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

Side by Side Diff: services/service_manager/service_manager.cc

Issue 2816393002: Implement Connector::ApplySpec() & use to enforce navigation:frame (Closed)
Patch Set: . Created 3 years, 8 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
« no previous file with comments | « services/service_manager/public/interfaces/connector.mojom ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "services/service_manager/service_manager.h" 5 #include "services/service_manager/service_manager.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/guid.h" 13 #include "base/guid.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/ptr_util.h" 16 #include "base/memory/ptr_util.h"
17 #include "base/process/process.h" 17 #include "base/process/process.h"
18 #include "base/process/process_handle.h" 18 #include "base/process/process_handle.h"
19 #include "base/stl_util.h" 19 #include "base/stl_util.h"
20 #include "base/strings/string_util.h" 20 #include "base/strings/string_util.h"
21 #include "base/trace_event/trace_event.h" 21 #include "base/trace_event/trace_event.h"
22 #include "mojo/public/cpp/bindings/associated_binding.h" 22 #include "mojo/public/cpp/bindings/associated_binding.h"
23 #include "mojo/public/cpp/bindings/binding.h" 23 #include "mojo/public/cpp/bindings/binding.h"
24 #include "mojo/public/cpp/bindings/binding_set.h" 24 #include "mojo/public/cpp/bindings/binding_set.h"
25 #include "mojo/public/cpp/bindings/strong_binding.h"
25 #include "services/catalog/public/interfaces/constants.mojom.h" 26 #include "services/catalog/public/interfaces/constants.mojom.h"
26 #include "services/service_manager/connect_util.h" 27 #include "services/service_manager/connect_util.h"
27 #include "services/service_manager/public/cpp/connector.h" 28 #include "services/service_manager/public/cpp/connector.h"
28 #include "services/service_manager/public/cpp/interface_registry.h" 29 #include "services/service_manager/public/cpp/interface_registry.h"
29 #include "services/service_manager/public/cpp/service.h" 30 #include "services/service_manager/public/cpp/service.h"
30 #include "services/service_manager/public/cpp/service_context.h" 31 #include "services/service_manager/public/cpp/service_context.h"
31 #include "services/service_manager/public/interfaces/connector.mojom.h" 32 #include "services/service_manager/public/interfaces/connector.mojom.h"
32 #include "services/service_manager/public/interfaces/constants.mojom.h" 33 #include "services/service_manager/public/interfaces/constants.mojom.h"
33 #include "services/service_manager/public/interfaces/service.mojom.h" 34 #include "services/service_manager/public/interfaces/service.mojom.h"
34 #include "services/service_manager/public/interfaces/service_control.mojom.h" 35 #include "services/service_manager/public/interfaces/service_control.mojom.h"
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 } 71 }
71 72
72 bool HasCapability(const InterfaceProviderSpec& spec, 73 bool HasCapability(const InterfaceProviderSpec& spec,
73 const std::string& capability) { 74 const std::string& capability) {
74 auto it = spec.requires.find(service_manager::mojom::kServiceName); 75 auto it = spec.requires.find(service_manager::mojom::kServiceName);
75 if (it == spec.requires.end()) 76 if (it == spec.requires.end())
76 return false; 77 return false;
77 return it->second.find(capability) != it->second.end(); 78 return it->second.find(capability) != it->second.end();
78 } 79 }
79 80
81 bool AllowsInterface(const Identity& source,
82 const InterfaceProviderSpec& source_spec,
83 const Identity& target,
84 const InterfaceProviderSpec& target_spec,
85 const std::string& interface_name) {
86 InterfaceSet exposed =
87 GetInterfacesToExpose(source_spec, target, target_spec);
88 bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) ||
89 exposed.count(interface_name) > 0;
90 if (!allowed) {
91 std::stringstream ss;
92 ss << "Connection InterfaceProviderSpec prevented service: "
93 << source.name() << " from binding interface: " << interface_name
94 << " exposed by: " << target.name();
95 LOG(ERROR) << ss.str();
96 }
97 return allowed;
98 }
99
80 // Encapsulates a connection to an instance of a service, tracked by the 100 // Encapsulates a connection to an instance of a service, tracked by the
81 // Service Manager. 101 // Service Manager.
82 class ServiceManager::Instance 102 class ServiceManager::Instance
83 : public mojom::Connector, 103 : public mojom::Connector,
84 public mojom::PIDReceiver, 104 public mojom::PIDReceiver,
85 public Service, 105 public Service,
86 public mojom::ServiceManager, 106 public mojom::ServiceManager,
87 public mojom::ServiceControl { 107 public mojom::ServiceControl {
88 public: 108 public:
89 Instance(service_manager::ServiceManager* service_manager, 109 Instance(service_manager::ServiceManager* service_manager,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 std::unique_ptr<ConnectParams> params(std::move(*in_params)); 158 std::unique_ptr<ConnectParams> params(std::move(*in_params));
139 InterfaceProviderSpecMap source_specs; 159 InterfaceProviderSpecMap source_specs;
140 InterfaceProviderSpec source_connection_spec; 160 InterfaceProviderSpec source_connection_spec;
141 Instance* source = 161 Instance* source =
142 service_manager_->GetExistingInstance(params->source()); 162 service_manager_->GetExistingInstance(params->source());
143 if (source) { 163 if (source) {
144 source_specs = source->interface_provider_specs_; 164 source_specs = source->interface_provider_specs_;
145 source_connection_spec = source->GetConnectionSpec(); 165 source_connection_spec = source->GetConnectionSpec();
146 } 166 }
147 167
148 InterfaceSet exposed = GetInterfacesToExpose(source_connection_spec, 168 if (!AllowsInterface(params->source(), source_connection_spec, identity_,
149 identity_, 169 GetConnectionSpec(), params->interface_name())) {
150 GetConnectionSpec());
151 bool allowed = (exposed.size() == 1 && exposed.count("*") == 1) ||
152 exposed.count(params->interface_name()) > 0;
153 if (!allowed) {
154 std::stringstream ss;
155 ss << "Connection InterfaceProviderSpec prevented service: "
156 << params->source().name() << " from binding interface: "
157 << params->interface_name() << " exposed by: " << identity_.name();
158 LOG(ERROR) << ss.str();
159 params->set_response_data(mojom::ConnectResult::ACCESS_DENIED, identity_); 170 params->set_response_data(mojom::ConnectResult::ACCESS_DENIED, identity_);
160 return false; 171 return false;
161 } 172 }
162 173
163 params->set_response_data(mojom::ConnectResult::SUCCEEDED, identity_); 174 params->set_response_data(mojom::ConnectResult::SUCCEEDED, identity_);
164 175
165 pending_service_connections_++; 176 pending_service_connections_++;
166 service_->OnBindInterface( 177 service_->OnBindInterface(
167 ServiceInfo(params->source(), source_specs), 178 ServiceInfo(params->source(), source_specs),
168 params->interface_name(), 179 params->interface_name(),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 219
209 mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const { 220 mojom::RunningServiceInfoPtr CreateRunningServiceInfo() const {
210 mojom::RunningServiceInfoPtr info(mojom::RunningServiceInfo::New()); 221 mojom::RunningServiceInfoPtr info(mojom::RunningServiceInfo::New());
211 info->id = id_; 222 info->id = id_;
212 info->identity = identity_; 223 info->identity = identity_;
213 info->pid = pid_; 224 info->pid = pid_;
214 return info; 225 return info;
215 } 226 }
216 227
217 const InterfaceProviderSpec& GetConnectionSpec() const { 228 const InterfaceProviderSpec& GetConnectionSpec() const {
218 auto it = interface_provider_specs_.find( 229 return GetSpec(mojom::kServiceManager_ConnectorSpec);
219 mojom::kServiceManager_ConnectorSpec); 230 }
231 bool HasSpec(const std::string& spec) const {
232 auto it = interface_provider_specs_.find(spec);
233 return it != interface_provider_specs_.end();
234 }
235 const InterfaceProviderSpec& GetSpec(const std::string& spec) const {
236 auto it = interface_provider_specs_.find(spec);
220 return it != interface_provider_specs_.end() ? it->second : empty_spec_; 237 return it != interface_provider_specs_.end() ? it->second : empty_spec_;
221 } 238 }
239
222 const Identity& identity() const { return identity_; } 240 const Identity& identity() const { return identity_; }
223 void set_identity(const Identity& identity) { identity_ = identity; } 241 void set_identity(const Identity& identity) { identity_ = identity; }
224 uint32_t id() const { return id_; } 242 uint32_t id() const { return id_; }
225 243
226 // Service: 244 // Service:
227 void OnBindInterface(const ServiceInfo& source_info, 245 void OnBindInterface(const ServiceInfo& source_info,
228 const std::string& interface_name, 246 const std::string& interface_name,
229 mojo::ScopedMessagePipeHandle interface_pipe) override { 247 mojo::ScopedMessagePipeHandle interface_pipe) override {
230 Instance* source = 248 Instance* source =
231 service_manager_->GetExistingInstance(source_info.identity); 249 service_manager_->GetExistingInstance(source_info.identity);
232 DCHECK(source); 250 DCHECK(source);
233 if (interface_name == mojom::ServiceManager::Name_ && 251 if (interface_name == mojom::ServiceManager::Name_ &&
234 HasCapability(source->GetConnectionSpec(), 252 HasCapability(source->GetConnectionSpec(),
235 kCapability_ServiceManager)) { 253 kCapability_ServiceManager)) {
236 mojom::ServiceManagerRequest request = 254 mojom::ServiceManagerRequest request =
237 mojo::MakeRequest<mojom::ServiceManager>(std::move(interface_pipe)); 255 mojo::MakeRequest<mojom::ServiceManager>(std::move(interface_pipe));
238 service_manager_bindings_.AddBinding(this, std::move(request)); 256 service_manager_bindings_.AddBinding(this, std::move(request));
239 } 257 }
240 } 258 }
241 259
242 private: 260 private:
243 enum class State { 261 enum class State {
244 // The service was not started yet. 262 // The service was not started yet.
245 IDLE, 263 IDLE,
246 264
247 // The service was started but the service manager hasn't received the 265 // The service was started but the service manager hasn't received the
248 // initial response from it yet. 266 // initial response from it yet.
249 STARTING, 267 STARTING,
250 268
251 // The service was started successfully. 269 // The service was started successfully.
252 STARTED 270 STARTED
253 }; 271 };
254 272
273 class InterfaceProviderImpl : public mojom::InterfaceProvider {
274 public:
275 InterfaceProviderImpl(const std::string& spec,
276 const Identity& source_identity,
277 const Identity& target_identity,
278 service_manager::ServiceManager* service_manager,
279 mojom::InterfaceProviderPtr target,
280 mojom::InterfaceProviderRequest source_request)
281 : spec_(spec),
282 source_identity_(source_identity),
283 target_identity_(target_identity),
284 service_manager_(service_manager),
285 target_(std::move(target)),
286 source_binding_(this, std::move(source_request)) {}
287 ~InterfaceProviderImpl() override {}
288
289 private:
290 // mojom::InterfaceProvider:
291 void GetInterface(const std::string& interface_name,
292 mojo::ScopedMessagePipeHandle interface_pipe) override {
293 Instance* source =
294 service_manager_->GetExistingInstance(source_identity_);
295 Instance* target =
296 service_manager_->GetExistingInstance(target_identity_);
297 if (!source || !target)
298 return;
299 if (!ValidateSpec(source) || !ValidateSpec(target))
300 return;
301
302 if (AllowsInterface(source_identity_, source->GetSpec(spec_),
303 target_identity_, target->GetSpec(spec_),
304 interface_name)) {
305 target_->GetInterface(interface_name, std::move(interface_pipe));
306 }
307 }
308
309 bool ValidateSpec(Instance* instance) const {
310 if (!instance->HasSpec(spec_)) {
311 LOG(ERROR) << "Instance for: " << instance->identity().name()
312 << " did not have spec named: " << spec_;
313 return false;
314 }
315 return true;
316 }
317
318 const std::string spec_;
319 const Identity source_identity_;
320 const Identity target_identity_;
321 const service_manager::ServiceManager* service_manager_;
322
323 mojom::InterfaceProviderPtr target_;
324 mojo::Binding<mojom::InterfaceProvider> source_binding_;
325
326 DISALLOW_COPY_AND_ASSIGN(InterfaceProviderImpl);
327 };
328
255 // mojom::Connector implementation: 329 // mojom::Connector implementation:
256 void BindInterface(const service_manager::Identity& in_target, 330 void BindInterface(const service_manager::Identity& in_target,
257 const std::string& interface_name, 331 const std::string& interface_name,
258 mojo::ScopedMessagePipeHandle interface_pipe, 332 mojo::ScopedMessagePipeHandle interface_pipe,
259 const BindInterfaceCallback& callback) override { 333 const BindInterfaceCallback& callback) override {
260 Identity target = in_target; 334 Identity target = in_target;
261 mojom::ConnectResult result = 335 mojom::ConnectResult result =
262 ValidateConnectParams(&target, nullptr, nullptr); 336 ValidateConnectParams(&target, nullptr, nullptr);
263 if (!Succeeded(result)) { 337 if (!Succeeded(result)) {
264 callback.Run(result, Identity()); 338 callback.Run(result, Identity());
265 return; 339 return;
266 } 340 }
267 341
268 std::unique_ptr<ConnectParams> params(new ConnectParams); 342 std::unique_ptr<ConnectParams> params(new ConnectParams);
269 params->set_source(identity_); 343 params->set_source(identity_);
270 params->set_target(target); 344 params->set_target(target);
271 params->set_interface_request_info(interface_name, 345 params->set_interface_request_info(interface_name,
272 std::move(interface_pipe)); 346 std::move(interface_pipe));
273 params->set_start_service_callback(callback); 347 params->set_start_service_callback(callback);
274 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); 348 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr());
275 } 349 }
276 350
277 void StartService(const Identity& in_target, 351 void StartService(const Identity& in_target,
278 const StartServiceCallback& callback) override { 352 const StartServiceCallback& callback) override {
279 Identity target = in_target; 353 Identity target = in_target;
280 mojom::ConnectResult result = 354 mojom::ConnectResult result =
281 ValidateConnectParams(&target, nullptr, nullptr); 355 ValidateConnectParams(&target, nullptr, nullptr);
282 if (!Succeeded(result)) { 356 if (!Succeeded(result)) {
283 callback.Run(result, Identity()); 357 callback.Run(result, Identity());
284 return; 358 return;
285 } 359 }
286 360
287 std::unique_ptr<ConnectParams> params(new ConnectParams); 361 std::unique_ptr<ConnectParams> params(new ConnectParams);
288 params->set_source(identity_); 362 params->set_source(identity_);
289 params->set_target(target); 363 params->set_target(target);
290 params->set_start_service_callback(callback); 364 params->set_start_service_callback(callback);
291 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); 365 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr());
292 } 366 }
293 367
294 void StartServiceWithProcess( 368 void StartServiceWithProcess(
295 const Identity& in_target, 369 const Identity& in_target,
296 mojo::ScopedMessagePipeHandle service_handle, 370 mojo::ScopedMessagePipeHandle service_handle,
297 mojom::PIDReceiverRequest pid_receiver_request, 371 mojom::PIDReceiverRequest pid_receiver_request,
298 const StartServiceWithProcessCallback& callback) override { 372 const StartServiceWithProcessCallback& callback) override {
299 Identity target = in_target; 373 Identity target = in_target;
300 mojom::ConnectResult result = 374 mojom::ConnectResult result =
301 ValidateConnectParams(&target, nullptr, nullptr); 375 ValidateConnectParams(&target, nullptr, nullptr);
302 if (!Succeeded(result)) { 376 if (!Succeeded(result)) {
303 callback.Run(result, Identity()); 377 callback.Run(result, Identity());
304 return; 378 return;
305 } 379 }
306 380
307 std::unique_ptr<ConnectParams> params(new ConnectParams); 381 std::unique_ptr<ConnectParams> params(new ConnectParams);
308 params->set_source(identity_); 382 params->set_source(identity_);
309 params->set_target(target); 383 params->set_target(target);
310 384
311 mojom::ServicePtr service; 385 mojom::ServicePtr service;
312 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0)); 386 service.Bind(mojom::ServicePtrInfo(std::move(service_handle), 0));
313 params->set_client_process_info(std::move(service), 387 params->set_client_process_info(std::move(service),
314 std::move(pid_receiver_request)); 388 std::move(pid_receiver_request));
315 params->set_start_service_callback(callback); 389 params->set_start_service_callback(callback);
316 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr()); 390 service_manager_->Connect(std::move(params), weak_factory_.GetWeakPtr());
317 } 391 }
318 392
319 void Clone(mojom::ConnectorRequest request) override { 393 void Clone(mojom::ConnectorRequest request) override {
320 connectors_.AddBinding(this, std::move(request)); 394 connectors_.AddBinding(this, std::move(request));
321 } 395 }
322 396
397 void FilterInterfaces(const std::string& spec,
398 const Identity& source,
399 mojom::InterfaceProviderRequest source_request,
400 mojom::InterfaceProviderPtr target) override {
401 filters_.push_back(base::MakeUnique<InterfaceProviderImpl>(
402 spec, source, identity_, service_manager_, std::move(target),
403 std::move(source_request)));
404 }
405
323 // mojom::PIDReceiver: 406 // mojom::PIDReceiver:
324 void SetPID(uint32_t pid) override { 407 void SetPID(uint32_t pid) override {
325 PIDAvailable(pid); 408 PIDAvailable(pid);
326 } 409 }
327 410
328 // mojom::ServiceManager implementation: 411 // mojom::ServiceManager implementation:
329 void AddListener(mojom::ServiceManagerListenerPtr listener) override { 412 void AddListener(mojom::ServiceManagerListenerPtr listener) override {
330 // TODO(beng): this should only track the instances matching this user, and 413 // TODO(beng): this should only track the instances matching this user, and
331 // root. 414 // root.
332 service_manager_->AddListener(std::move(listener)); 415 service_manager_->AddListener(std::move(listener));
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 const bool allow_any_application_; 576 const bool allow_any_application_;
494 std::unique_ptr<ServiceProcessLauncher> runner_; 577 std::unique_ptr<ServiceProcessLauncher> runner_;
495 mojom::ServicePtr service_; 578 mojom::ServicePtr service_;
496 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_; 579 mojo::Binding<mojom::PIDReceiver> pid_receiver_binding_;
497 mojo::BindingSet<mojom::Connector> connectors_; 580 mojo::BindingSet<mojom::Connector> connectors_;
498 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_; 581 mojo::BindingSet<mojom::ServiceManager> service_manager_bindings_;
499 mojo::AssociatedBinding<mojom::ServiceControl> control_binding_; 582 mojo::AssociatedBinding<mojom::ServiceControl> control_binding_;
500 base::ProcessId pid_ = base::kNullProcessId; 583 base::ProcessId pid_ = base::kNullProcessId;
501 State state_; 584 State state_;
502 585
586 std::vector<std::unique_ptr<InterfaceProviderImpl>> filters_;
587
503 // The number of outstanding OnBindInterface requests which are in flight. 588 // The number of outstanding OnBindInterface requests which are in flight.
504 int pending_service_connections_ = 0; 589 int pending_service_connections_ = 0;
505 590
506 base::WeakPtrFactory<Instance> weak_factory_; 591 base::WeakPtrFactory<Instance> weak_factory_;
507 592
508 DISALLOW_COPY_AND_ASSIGN(Instance); 593 DISALLOW_COPY_AND_ASSIGN(Instance);
509 }; 594 };
510 595
511 class ServiceManager::ServiceImpl : public Service { 596 class ServiceManager::ServiceImpl : public Service {
512 public: 597 public:
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 instance->identity()); 1085 instance->identity());
1001 if (params->HasInterfaceRequestInfo()) 1086 if (params->HasInterfaceRequestInfo())
1002 instance->CallOnBindInterface(&params); 1087 instance->CallOnBindInterface(&params);
1003 } 1088 }
1004 1089
1005 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() { 1090 base::WeakPtr<ServiceManager> ServiceManager::GetWeakPtr() {
1006 return weak_ptr_factory_.GetWeakPtr(); 1091 return weak_ptr_factory_.GetWeakPtr();
1007 } 1092 }
1008 1093
1009 } // namespace service_manager 1094 } // namespace service_manager
OLDNEW
« no previous file with comments | « services/service_manager/public/interfaces/connector.mojom ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698