| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #if defined(__clang__) |
| #pragma clang diagnostic push |
| #pragma clang diagnostic ignored "-Wunused-private-field" |
| #elif defined(_MSC_VER) |
| #pragma warning(push) |
| #pragma warning(disable:4056) |
| #pragma warning(disable:4065) |
| #pragma warning(disable:4756) |
| #endif |
| |
| #include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom-blink.h" |
| |
| #include <math.h> |
| #include <stdint.h> |
| #include <utility> |
| |
| #include "base/logging.h" |
| #include "base/trace_event/trace_event.h" |
| #include "mojo/public/cpp/bindings/lib/message_builder.h" |
| #include "mojo/public/cpp/bindings/lib/serialization_util.h" |
| #include "mojo/public/cpp/bindings/lib/validate_params.h" |
| #include "mojo/public/cpp/bindings/lib/validation_context.h" |
| #include "mojo/public/cpp/bindings/lib/validation_errors.h" |
| #include "mojo/public/interfaces/bindings/interface_control_messages.mojom.h" |
| #include "mojo/public/cpp/bindings/lib/wtf_serialization.h" |
| namespace chrome_cleaner { |
| namespace mojom { |
| namespace blink { |
| ObservedBehaviours::ObservedBehaviours() |
| : ad_injector(), |
| settings_hijacker(), |
| extensions_injector(), |
| dropper() {} |
| |
| ObservedBehaviours::ObservedBehaviours( |
| bool ad_injector_in, |
| bool settings_hijacker_in, |
| bool extensions_injector_in, |
| bool dropper_in) |
| : ad_injector(std::move(ad_injector_in)), |
| settings_hijacker(std::move(settings_hijacker_in)), |
| extensions_injector(std::move(extensions_injector_in)), |
| dropper(std::move(dropper_in)) {} |
| |
| ObservedBehaviours::~ObservedBehaviours() = default; |
| size_t ObservedBehaviours::Hash(size_t seed) const { |
| seed = mojo::internal::WTFHash(seed, this->ad_injector); |
| seed = mojo::internal::WTFHash(seed, this->settings_hijacker); |
| seed = mojo::internal::WTFHash(seed, this->extensions_injector); |
| seed = mojo::internal::WTFHash(seed, this->dropper); |
| return seed; |
| } |
| |
| bool ObservedBehaviours::Validate( |
| const void* data, |
| mojo::internal::ValidationContext* validation_context) { |
| return Data_::Validate(data, validation_context); |
| } |
| UwS::UwS() |
| : id(), |
| name(), |
| observed_behaviours(), |
| files_to_delete() {} |
| |
| UwS::UwS( |
| int32_t id_in, |
| const WTF::String& name_in, |
| ObservedBehavioursPtr observed_behaviours_in, |
| WTF::Vector<::mojo::common::mojom::blink::FilePathPtr> files_to_delete_in) |
| : id(std::move(id_in)), |
| name(std::move(name_in)), |
| observed_behaviours(std::move(observed_behaviours_in)), |
| files_to_delete(std::move(files_to_delete_in)) {} |
| |
| UwS::~UwS() = default; |
| |
| bool UwS::Validate( |
| const void* data, |
| mojo::internal::ValidationContext* validation_context) { |
| return Data_::Validate(data, validation_context); |
| } |
| const char ChromePrompt::Name_[] = "chrome_cleaner::mojom::ChromePrompt"; |
| |
| class ChromePrompt_PromptUser_ForwardToCallback |
| : public mojo::MessageReceiver { |
| public: |
| ChromePrompt_PromptUser_ForwardToCallback( |
| const ChromePrompt::PromptUserCallback& callback |
| ) : callback_(std::move(callback)) { |
| } |
| bool Accept(mojo::Message* message) override; |
| private: |
| ChromePrompt::PromptUserCallback callback_; |
| DISALLOW_COPY_AND_ASSIGN(ChromePrompt_PromptUser_ForwardToCallback); |
| }; |
| bool ChromePrompt_PromptUser_ForwardToCallback::Accept( |
| mojo::Message* message) { |
| internal::ChromePrompt_PromptUser_ResponseParams_Data* params = |
| reinterpret_cast<internal::ChromePrompt_PromptUser_ResponseParams_Data*>( |
| message->mutable_payload()); |
| |
| mojo::internal::SerializationContext serialization_context; |
| serialization_context.handles.Swap((message)->mutable_handles()); |
| serialization_context.associated_endpoint_handles.swap( |
| *(message)->mutable_associated_endpoint_handles()); |
| bool success = true; |
| PromptAcceptance p_prompt_acceptance{}; |
| ChromePrompt_PromptUser_ResponseParamsDataView input_data_view(params, &serialization_context); |
| |
| if (!input_data_view.ReadPromptAcceptance(&p_prompt_acceptance)) |
| success = false; |
| if (!success) { |
| ReportValidationErrorForMessage( |
| message, |
| mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED, |
| "ChromePrompt::PromptUser response deserializer"); |
| return false; |
| } |
| if (!callback_.is_null()) { |
| mojo::internal::MessageDispatchContext context(message); |
| std::move(callback_).Run( |
| std::move(p_prompt_acceptance)); |
| } |
| return true; |
| } |
| |
| ChromePromptProxy::ChromePromptProxy(mojo::MessageReceiverWithResponder* receiver) |
| : receiver_(receiver) { |
| } |
| |
| void ChromePromptProxy::PromptUser( |
| WTF::Vector<UwSPtr> in_removable_uws_found, ElevationStatus in_elevation_status, const PromptUserCallback& callback) { |
| mojo::internal::SerializationContext serialization_context; |
| size_t size = sizeof(::chrome_cleaner::mojom::internal::ChromePrompt_PromptUser_Params_Data); |
| size += mojo::internal::PrepareToSerialize<mojo::ArrayDataView<::chrome_cleaner::mojom::UwSDataView>>( |
| in_removable_uws_found, &serialization_context); |
| constexpr uint32_t kFlags = mojo::Message::kFlagExpectsResponse; |
| mojo::internal::MessageBuilder builder( |
| internal::kChromePrompt_PromptUser_Name, kFlags, size, |
| serialization_context.associated_endpoint_count); |
| |
| auto params = |
| ::chrome_cleaner::mojom::internal::ChromePrompt_PromptUser_Params_Data::New(builder.buffer()); |
| ALLOW_UNUSED_LOCAL(params); |
| typename decltype(params->removable_uws_found)::BaseType* removable_uws_found_ptr; |
| const mojo::internal::ContainerValidateParams removable_uws_found_validate_params( |
| 0, false, nullptr); |
| mojo::internal::Serialize<mojo::ArrayDataView<::chrome_cleaner::mojom::UwSDataView>>( |
| in_removable_uws_found, builder.buffer(), &removable_uws_found_ptr, &removable_uws_found_validate_params, |
| &serialization_context); |
| params->removable_uws_found.Set(removable_uws_found_ptr); |
| MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING( |
| params->removable_uws_found.is_null(), |
| mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER, |
| "null removable_uws_found in ChromePrompt.PromptUser request"); |
| mojo::internal::Serialize<::chrome_cleaner::mojom::ElevationStatus>( |
| in_elevation_status, ¶ms->elevation_status); |
| (&serialization_context)->handles.Swap( |
| builder.message()->mutable_handles()); |
| (&serialization_context)->associated_endpoint_handles.swap( |
| *builder.message()->mutable_associated_endpoint_handles()); |
| std::unique_ptr<mojo::MessageReceiver> responder( |
| new ChromePrompt_PromptUser_ForwardToCallback( |
| std::move(callback))); |
| ignore_result(receiver_->AcceptWithResponder(builder.message(), |
| std::move(responder))); |
| } |
| class ChromePrompt_PromptUser_ProxyToResponder { |
| public: |
| static ChromePrompt::PromptUserCallback CreateCallback( |
| uint64_t request_id, |
| bool is_sync, |
| std::unique_ptr<mojo::MessageReceiverWithStatus> responder) { |
| std::unique_ptr<ChromePrompt_PromptUser_ProxyToResponder> proxy( |
| new ChromePrompt_PromptUser_ProxyToResponder( |
| request_id, is_sync, std::move(responder))); |
| return base::Bind(&ChromePrompt_PromptUser_ProxyToResponder::Run, |
| base::Passed(&proxy)); |
| } |
| |
| ~ChromePrompt_PromptUser_ProxyToResponder() { |
| #if DCHECK_IS_ON() |
| if (responder_) { |
| // Is the Service destroying the callback without running it |
| // and without first closing the pipe? |
| responder_->DCheckInvalid("The callback passed to " |
| "ChromePrompt::PromptUser() was never run."); |
| } |
| #endif |
| // If the Callback was dropped then deleting the responder will close |
| // the pipe so the calling application knows to stop waiting for a reply. |
| responder_ = nullptr; |
| } |
| |
| private: |
| ChromePrompt_PromptUser_ProxyToResponder( |
| uint64_t request_id, |
| bool is_sync, |
| std::unique_ptr<mojo::MessageReceiverWithStatus> responder) |
| : request_id_(request_id), |
| is_sync_(is_sync), |
| responder_(std::move(responder)) { |
| } |
| |
| void Run( |
| PromptAcceptance in_prompt_acceptance); |
| |
| uint64_t request_id_; |
| bool is_sync_; |
| std::unique_ptr<mojo::MessageReceiverWithStatus> responder_; |
| |
| DISALLOW_COPY_AND_ASSIGN(ChromePrompt_PromptUser_ProxyToResponder); |
| }; |
| |
| void ChromePrompt_PromptUser_ProxyToResponder::Run( |
| PromptAcceptance in_prompt_acceptance) { |
| mojo::internal::SerializationContext serialization_context; |
| size_t size = sizeof(::chrome_cleaner::mojom::internal::ChromePrompt_PromptUser_ResponseParams_Data); |
| |
| uint32_t flags = (is_sync_ ? mojo::Message::kFlagIsSync : 0) | |
| mojo::Message::kFlagIsResponse; |
| mojo::internal::MessageBuilder builder( |
| internal::kChromePrompt_PromptUser_Name, flags, size, |
| serialization_context.associated_endpoint_count); |
| builder.message()->set_request_id(request_id_); |
| |
| auto params = |
| ::chrome_cleaner::mojom::internal::ChromePrompt_PromptUser_ResponseParams_Data::New(builder.buffer()); |
| ALLOW_UNUSED_LOCAL(params); |
| mojo::internal::Serialize<::chrome_cleaner::mojom::PromptAcceptance>( |
| in_prompt_acceptance, ¶ms->prompt_acceptance); |
| (&serialization_context)->handles.Swap( |
| builder.message()->mutable_handles()); |
| (&serialization_context)->associated_endpoint_handles.swap( |
| *builder.message()->mutable_associated_endpoint_handles()); |
| ignore_result(responder_->Accept(builder.message())); |
| // TODO(darin): Accept() returning false indicates a malformed message, and |
| // that may be good reason to close the connection. However, we don't have a |
| // way to do that from here. We should add a way. |
| responder_ = nullptr; |
| } |
| |
| // static |
| bool ChromePromptStubDispatch::Accept( |
| ChromePrompt* impl, |
| mojo::Message* message) { |
| switch (message->header()->name) { |
| case internal::kChromePrompt_PromptUser_Name: { |
| break; |
| } |
| } |
| return false; |
| } |
| |
| // static |
| bool ChromePromptStubDispatch::AcceptWithResponder( |
| ChromePrompt* impl, |
| mojo::Message* message, |
| std::unique_ptr<mojo::MessageReceiverWithStatus> responder) { |
| switch (message->header()->name) { |
| case internal::kChromePrompt_PromptUser_Name: { |
| internal::ChromePrompt_PromptUser_Params_Data* params = |
| reinterpret_cast<internal::ChromePrompt_PromptUser_Params_Data*>( |
| message->mutable_payload()); |
| |
| mojo::internal::SerializationContext serialization_context; |
| serialization_context.handles.Swap((message)->mutable_handles()); |
| serialization_context.associated_endpoint_handles.swap( |
| *(message)->mutable_associated_endpoint_handles()); |
| bool success = true; |
| WTF::Vector<UwSPtr> p_removable_uws_found{}; |
| ElevationStatus p_elevation_status{}; |
| ChromePrompt_PromptUser_ParamsDataView input_data_view(params, &serialization_context); |
| |
| if (!input_data_view.ReadRemovableUwsFound(&p_removable_uws_found)) |
| success = false; |
| if (!input_data_view.ReadElevationStatus(&p_elevation_status)) |
| success = false; |
| if (!success) { |
| ReportValidationErrorForMessage( |
| message, |
| mojo::internal::VALIDATION_ERROR_DESERIALIZATION_FAILED, |
| "ChromePrompt::PromptUser deserializer"); |
| return false; |
| } |
| ChromePrompt::PromptUserCallback callback = |
| ChromePrompt_PromptUser_ProxyToResponder::CreateCallback( |
| message->request_id(), |
| message->has_flag(mojo::Message::kFlagIsSync), |
| std::move(responder)); |
| // A null |impl| means no implementation was bound. |
| assert(impl); |
| TRACE_EVENT0("mojom", "ChromePrompt::PromptUser"); |
| mojo::internal::MessageDispatchContext context(message); |
| impl->PromptUser( |
| std::move(p_removable_uws_found), |
| std::move(p_elevation_status), std::move(callback)); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| bool ChromePromptRequestValidator::Accept(mojo::Message* message) { |
| if (mojo::internal::ControlMessageHandler::IsControlMessage(message)) |
| return true; |
| |
| mojo::internal::ValidationContext validation_context( |
| message->payload(), message->payload_num_bytes(), |
| message->handles()->size(), message->payload_num_interface_ids(), message, |
| "ChromePrompt RequestValidator"); |
| |
| switch (message->header()->name) { |
| case internal::kChromePrompt_PromptUser_Name: { |
| if (!mojo::internal::ValidateMessageIsRequestExpectingResponse( |
| message, &validation_context)) { |
| return false; |
| } |
| if (!mojo::internal::ValidateMessagePayload< |
| internal::ChromePrompt_PromptUser_Params_Data>( |
| message, &validation_context)) { |
| return false; |
| } |
| return true; |
| } |
| default: |
| break; |
| } |
| |
| // Unrecognized message. |
| ReportValidationError( |
| &validation_context, |
| mojo::internal::VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD); |
| return false; |
| } |
| |
| bool ChromePromptResponseValidator::Accept(mojo::Message* message) { |
| if (mojo::internal::ControlMessageHandler::IsControlMessage(message)) |
| return true; |
| |
| mojo::internal::ValidationContext validation_context( |
| message->payload(), message->payload_num_bytes(), |
| message->handles()->size(), message->payload_num_interface_ids(), message, |
| "ChromePrompt ResponseValidator"); |
| |
| if (!mojo::internal::ValidateMessageIsResponse(message, &validation_context)) |
| return false; |
| switch (message->header()->name) { |
| case internal::kChromePrompt_PromptUser_Name: { |
| if (!mojo::internal::ValidateMessagePayload< |
| internal::ChromePrompt_PromptUser_ResponseParams_Data>( |
| message, &validation_context)) { |
| return false; |
| } |
| return true; |
| } |
| default: |
| break; |
| } |
| |
| // Unrecognized message. |
| ReportValidationError( |
| &validation_context, |
| mojo::internal::VALIDATION_ERROR_MESSAGE_HEADER_UNKNOWN_METHOD); |
| return false; |
| } |
| } // namespace blink |
| } // namespace mojom |
| } // namespace chrome_cleaner |
| |
| namespace mojo { |
| |
| |
| // static |
| bool StructTraits<::chrome_cleaner::mojom::blink::ObservedBehaviours::DataView, ::chrome_cleaner::mojom::blink::ObservedBehavioursPtr>::Read( |
| ::chrome_cleaner::mojom::blink::ObservedBehaviours::DataView input, |
| ::chrome_cleaner::mojom::blink::ObservedBehavioursPtr* output) { |
| bool success = true; |
| ::chrome_cleaner::mojom::blink::ObservedBehavioursPtr result(::chrome_cleaner::mojom::blink::ObservedBehaviours::New()); |
| |
| result->ad_injector = input.ad_injector(); |
| result->settings_hijacker = input.settings_hijacker(); |
| result->extensions_injector = input.extensions_injector(); |
| result->dropper = input.dropper(); |
| *output = std::move(result); |
| return success; |
| } |
| |
| |
| // static |
| bool StructTraits<::chrome_cleaner::mojom::blink::UwS::DataView, ::chrome_cleaner::mojom::blink::UwSPtr>::Read( |
| ::chrome_cleaner::mojom::blink::UwS::DataView input, |
| ::chrome_cleaner::mojom::blink::UwSPtr* output) { |
| bool success = true; |
| ::chrome_cleaner::mojom::blink::UwSPtr result(::chrome_cleaner::mojom::blink::UwS::New()); |
| |
| result->id = input.id(); |
| if (!input.ReadName(&result->name)) |
| success = false; |
| if (!input.ReadObservedBehaviours(&result->observed_behaviours)) |
| success = false; |
| if (!input.ReadFilesToDelete(&result->files_to_delete)) |
| success = false; |
| *output = std::move(result); |
| return success; |
| } |
| |
| } // namespace mojo |
| |
| #if defined(__clang__) |
| #pragma clang diagnostic pop |
| #elif defined(_MSC_VER) |
| #pragma warning(pop) |
| #endif |