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