| OLD | NEW |
| 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 "mojo/shell/shell.h" | 5 #include "mojo/shell/shell.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 } | 48 } |
| 49 | 49 |
| 50 CapabilitySpec GetPermissiveCapabilities() { | 50 CapabilitySpec GetPermissiveCapabilities() { |
| 51 CapabilitySpec capabilities; | 51 CapabilitySpec capabilities; |
| 52 CapabilityRequest spec; | 52 CapabilityRequest spec; |
| 53 spec.interfaces.insert("*"); | 53 spec.interfaces.insert("*"); |
| 54 capabilities.required["*"] = spec; | 54 capabilities.required["*"] = spec; |
| 55 return capabilities; | 55 return capabilities; |
| 56 } | 56 } |
| 57 | 57 |
| 58 CapabilityRequest GetCapabilityRequest(const CapabilitySpec& source_spec, | 58 CapabilityRequest GetCapabilityRequest(const CapabilitySpec& spec, |
| 59 const Identity& target) { | 59 const Identity& identity) { |
| 60 // Start by looking for specs specific to the supplied identity. | 60 // Start by looking for specs specific to the supplied identity. |
| 61 auto it = source_spec.required.find(target.name()); | 61 auto it = spec.required.find(identity.name()); |
| 62 if (it != source_spec.required.end()) | 62 if (it != spec.required.end()) |
| 63 return it->second; | 63 return it->second; |
| 64 | 64 |
| 65 // Fall back to looking for a wildcard rule. | 65 // Fall back to looking for a wildcard rule. |
| 66 it = source_spec.required.find("*"); | 66 it = spec.required.find("*"); |
| 67 if (source_spec.required.size() == 1 && it != source_spec.required.end()) | 67 if (spec.required.size() == 1 && it != spec.required.end()) |
| 68 return it->second; | 68 return it->second; |
| 69 | 69 |
| 70 // Finally, nothing is allowed. | 70 // Finally, nothing is allowed. |
| 71 return CapabilityRequest(); | 71 return CapabilityRequest(); |
| 72 } | 72 } |
| 73 | 73 |
| 74 CapabilityRequest GenerateCapabilityRequestForConnection( | |
| 75 const CapabilitySpec& source_spec, | |
| 76 const Identity& target, | |
| 77 const CapabilitySpec& target_spec) { | |
| 78 CapabilityRequest request = GetCapabilityRequest(source_spec, target); | |
| 79 // Flatten all interfaces from classes requested by the source into the | |
| 80 // allowed interface set in the request. | |
| 81 for (const auto& class_name : request.classes) { | |
| 82 auto it = target_spec.provided.find(class_name); | |
| 83 if (it != target_spec.provided.end()) { | |
| 84 for (const auto& interface_name : it->second) | |
| 85 request.interfaces.insert(interface_name); | |
| 86 } | |
| 87 } | |
| 88 return request; | |
| 89 } | |
| 90 | |
| 91 // Encapsulates a connection to an instance of an application, tracked by the | 74 // Encapsulates a connection to an instance of an application, tracked by the |
| 92 // shell's Shell. | 75 // shell's Shell. |
| 93 class Shell::Instance : public mojom::Connector, | 76 class Shell::Instance : public mojom::Connector, |
| 94 public mojom::PIDReceiver, | 77 public mojom::PIDReceiver, |
| 95 public ShellClient, | 78 public ShellClient, |
| 96 public InterfaceFactory<mojom::Shell>, | 79 public InterfaceFactory<mojom::Shell>, |
| 97 public mojom::Shell { | 80 public mojom::Shell { |
| 98 public: | 81 public: |
| 99 Instance(mojom::ShellClientPtr shell_client, | 82 Instance(mojom::ShellClientPtr shell_client, |
| 100 mojo::shell::Shell* shell, | 83 mojo::shell::Shell* shell, |
| 101 const Identity& identity, | 84 const Identity& identity, |
| 102 const CapabilitySpec& capability_spec) | 85 const CapabilitySpec& capabilities) |
| 103 : shell_(shell), | 86 : shell_(shell), |
| 104 id_(GenerateUniqueID()), | 87 id_(GenerateUniqueID()), |
| 105 identity_(identity), | 88 identity_(identity), |
| 106 capability_spec_(capability_spec), | 89 capabilities_(capabilities), |
| 107 allow_any_application_(capability_spec.required.size() == 1 && | 90 allow_any_application_(capabilities.required.size() == 1 && |
| 108 capability_spec.required.count("*") == 1), | 91 capabilities.required.count("*") == 1), |
| 109 shell_client_(std::move(shell_client)), | 92 shell_client_(std::move(shell_client)), |
| 110 pid_receiver_binding_(this), | 93 pid_receiver_binding_(this), |
| 111 weak_factory_(this) { | 94 weak_factory_(this) { |
| 112 if (identity_.name() == "mojo:shell" || | 95 if (identity_.name() == "mojo:shell" || |
| 113 shell_->GetLoaderForName(identity_.name())) { | 96 shell_->GetLoaderForName(identity_.name())) { |
| 114 pid_ = base::Process::Current().Pid(); | 97 pid_ = base::Process::Current().Pid(); |
| 115 } | 98 } |
| 116 DCHECK_NE(mojom::kInvalidInstanceID, id_); | 99 DCHECK_NE(mojom::kInvalidInstanceID, id_); |
| 117 } | 100 } |
| 118 | 101 |
| 119 ~Instance() override {} | 102 ~Instance() override {} |
| 120 | 103 |
| 121 void InitializeClient() { | 104 void InitializeClient() { |
| 122 shell_client_->Initialize(connectors_.CreateInterfacePtrAndBind(this), | 105 shell_client_->Initialize(connectors_.CreateInterfacePtrAndBind(this), |
| 123 mojom::Identity::From(identity_), id_); | 106 mojom::Identity::From(identity_), id_); |
| 124 connectors_.set_connection_error_handler( | 107 connectors_.set_connection_error_handler( |
| 125 base::Bind(&mojo::shell::Shell::OnInstanceError, | 108 base::Bind(&mojo::shell::Shell::OnInstanceError, |
| 126 base::Unretained(shell_), base::Unretained(this))); | 109 base::Unretained(shell_), base::Unretained(this))); |
| 127 } | 110 } |
| 128 | 111 |
| 129 void ConnectToClient(scoped_ptr<ConnectParams> params) { | 112 void ConnectToClient(scoped_ptr<ConnectParams> params) { |
| 130 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, | 113 params->connect_callback().Run(mojom::ConnectResult::SUCCEEDED, |
| 131 identity_.user_id(), id_); | 114 identity_.user_id(), id_); |
| 132 uint32_t source_id = mojom::kInvalidInstanceID; | 115 uint32_t source_id = mojom::kInvalidInstanceID; |
| 133 CapabilityRequest spec; | 116 CapabilityRequest spec; |
| 134 spec.interfaces.insert("*"); | 117 spec.interfaces.insert("*"); |
| 135 Instance* source = shell_->GetExistingInstance(params->source()); | 118 Instance* source = shell_->GetExistingInstance(params->source()); |
| 136 if (source) { | 119 if (source) { |
| 137 spec = GenerateCapabilityRequestForConnection( | 120 spec = GetCapabilityRequest(source->capabilities_, identity_); |
| 138 source->capability_spec_, identity_, capability_spec_); | |
| 139 source_id = source->id(); | 121 source_id = source->id(); |
| 140 } | 122 } |
| 141 shell_client_->AcceptConnection( | 123 shell_client_->AcceptConnection( |
| 142 mojom::Identity::From(params->source()), source_id, | 124 mojom::Identity::From(params->source()), source_id, |
| 143 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), | 125 params->TakeRemoteInterfaces(), params->TakeLocalInterfaces(), |
| 144 mojom::CapabilityRequest::From(spec), params->target().name()); | 126 mojom::CapabilityRequest::From(spec), params->target().name()); |
| 145 } | 127 } |
| 146 | 128 |
| 147 void StartWithClientProcessConnection( | 129 void StartWithClientProcessConnection( |
| 148 mojom::ShellClientRequest request, | 130 mojom::ShellClientRequest request, |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 mojom::kInheritUserID, mojom::kInvalidInstanceID); | 260 mojom::kInheritUserID, mojom::kInvalidInstanceID); |
| 279 return false; | 261 return false; |
| 280 } | 262 } |
| 281 } | 263 } |
| 282 return true; | 264 return true; |
| 283 } | 265 } |
| 284 | 266 |
| 285 bool ValidateCapabilities(const Identity& target, | 267 bool ValidateCapabilities(const Identity& target, |
| 286 const ConnectCallback& callback) { | 268 const ConnectCallback& callback) { |
| 287 if (allow_any_application_ || | 269 if (allow_any_application_ || |
| 288 capability_spec_.required.find(target.name()) != | 270 capabilities_.required.find(target.name()) != |
| 289 capability_spec_.required.end()) { | 271 capabilities_.required.end()) { |
| 290 return true; | 272 return true; |
| 291 } | 273 } |
| 292 LOG(ERROR) << "Capabilities prevented connection from: " << | 274 LOG(ERROR) << "Capabilities prevented connection from: " << |
| 293 identity_.name() << " to: " << target.name(); | 275 identity_.name() << " to: " << target.name(); |
| 294 callback.Run(mojom::ConnectResult::ACCESS_DENIED, | 276 callback.Run(mojom::ConnectResult::ACCESS_DENIED, |
| 295 mojom::kInheritUserID, mojom::kInvalidInstanceID); | 277 mojom::kInheritUserID, mojom::kInvalidInstanceID); |
| 296 return false; | 278 return false; |
| 297 } | 279 } |
| 298 | 280 |
| 299 uint32_t GenerateUniqueID() const { | 281 uint32_t GenerateUniqueID() const { |
| 300 static uint32_t id = mojom::kInvalidInstanceID; | 282 static uint32_t id = mojom::kInvalidInstanceID; |
| 301 ++id; | 283 ++id; |
| 302 CHECK_NE(mojom::kInvalidInstanceID, id); | 284 CHECK_NE(mojom::kInvalidInstanceID, id); |
| 303 return id; | 285 return id; |
| 304 } | 286 } |
| 305 | 287 |
| 306 void PIDAvailable(base::ProcessId pid) { | 288 void PIDAvailable(base::ProcessId pid) { |
| 307 pid_ = pid; | 289 pid_ = pid; |
| 308 shell_->NotifyPIDAvailable(id_, pid_); | 290 shell_->NotifyPIDAvailable(id_, pid_); |
| 309 } | 291 } |
| 310 | 292 |
| 311 mojo::shell::Shell* const shell_; | 293 mojo::shell::Shell* const shell_; |
| 312 // An id that identifies this instance. Distinct from pid, as a single process | 294 // An id that identifies this instance. Distinct from pid, as a single process |
| 313 // may vend multiple application instances, and this object may exist before a | 295 // may vend multiple application instances, and this object may exist before a |
| 314 // process is launched. | 296 // process is launched. |
| 315 const uint32_t id_; | 297 const uint32_t id_; |
| 316 const Identity identity_; | 298 const Identity identity_; |
| 317 const CapabilitySpec capability_spec_; | 299 const CapabilitySpec capabilities_; |
| 318 const bool allow_any_application_; | 300 const bool allow_any_application_; |
| 319 mojom::ShellClientPtr shell_client_; | 301 mojom::ShellClientPtr shell_client_; |
| 320 Binding<mojom::PIDReceiver> pid_receiver_binding_; | 302 Binding<mojom::PIDReceiver> pid_receiver_binding_; |
| 321 BindingSet<mojom::Connector> connectors_; | 303 BindingSet<mojom::Connector> connectors_; |
| 322 BindingSet<mojom::Shell> shell_bindings_; | 304 BindingSet<mojom::Shell> shell_bindings_; |
| 323 mojom::ShellClientFactoryPtr factory_; | 305 mojom::ShellClientFactoryPtr factory_; |
| 324 NativeRunner* runner_ = nullptr; | 306 NativeRunner* runner_ = nullptr; |
| 325 base::ProcessId pid_ = base::kNullProcessId; | 307 base::ProcessId pid_ = base::kNullProcessId; |
| 326 base::WeakPtrFactory<Instance> weak_factory_; | 308 base::WeakPtrFactory<Instance> weak_factory_; |
| 327 | 309 |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { | 639 for (auto it = native_runners_.begin(); it != native_runners_.end(); ++it) { |
| 658 if (it->get() == runner) { | 640 if (it->get() == runner) { |
| 659 native_runners_.erase(it); | 641 native_runners_.erase(it); |
| 660 return; | 642 return; |
| 661 } | 643 } |
| 662 } | 644 } |
| 663 } | 645 } |
| 664 | 646 |
| 665 } // namespace shell | 647 } // namespace shell |
| 666 } // namespace mojo | 648 } // namespace mojo |
| OLD | NEW |