| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "remoting/host/setup/me2me_native_messaging_host.h" | 5 #include "remoting/host/setup/me2me_native_messaging_host.h" |
| 6 | 6 |
| 7 #include <cstdint> | 7 #include <cstdint> |
| 8 #include <memory> | 8 #include <memory> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <utility> | 10 #include <utility> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/callback_helpers.h" | |
| 15 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/json/json_reader.h" |
| 16 #include "base/json/json_writer.h" |
| 16 #include "base/logging.h" | 17 #include "base/logging.h" |
| 17 #include "base/macros.h" | 18 #include "base/macros.h" |
| 19 #include "base/single_thread_task_runner.h" |
| 18 #include "base/strings/stringize_macros.h" | 20 #include "base/strings/stringize_macros.h" |
| 19 #include "base/values.h" | 21 #include "base/values.h" |
| 20 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 21 #include "google_apis/gaia/gaia_oauth_client.h" | 23 #include "google_apis/gaia/gaia_oauth_client.h" |
| 22 #include "google_apis/google_api_keys.h" | 24 #include "google_apis/google_api_keys.h" |
| 23 #include "net/base/network_interfaces.h" | 25 #include "net/base/network_interfaces.h" |
| 26 #include "remoting/base/auto_thread_task_runner.h" |
| 24 #include "remoting/base/rsa_key_pair.h" | 27 #include "remoting/base/rsa_key_pair.h" |
| 28 #include "remoting/host/chromoting_host_context.h" |
| 29 #include "remoting/host/native_messaging/log_message_handler.h" |
| 25 #include "remoting/host/native_messaging/pipe_messaging_channel.h" | 30 #include "remoting/host/native_messaging/pipe_messaging_channel.h" |
| 26 #include "remoting/host/pin_hash.h" | 31 #include "remoting/host/pin_hash.h" |
| 27 #include "remoting/host/setup/oauth_client.h" | 32 #include "remoting/host/setup/oauth_client.h" |
| 28 #include "remoting/host/switches.h" | 33 #include "remoting/host/switches.h" |
| 29 #include "remoting/protocol/pairing_registry.h" | 34 #include "remoting/protocol/pairing_registry.h" |
| 30 | 35 |
| 31 #if defined(OS_WIN) | 36 #if defined(OS_WIN) |
| 32 #include "base/win/scoped_handle.h" | 37 #include "base/win/scoped_handle.h" |
| 33 #include "base/win/win_util.h" | 38 #include "base/win/win_util.h" |
| 34 #include "remoting/host/win/launch_native_messaging_host_process.h" | 39 #include "remoting/host/win/launch_native_messaging_host_process.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 52 }; | 57 }; |
| 53 | 58 |
| 54 // Helper to extract the "config" part of a message as a DictionaryValue. | 59 // Helper to extract the "config" part of a message as a DictionaryValue. |
| 55 // Returns nullptr on failure, and logs an error message. | 60 // Returns nullptr on failure, and logs an error message. |
| 56 std::unique_ptr<base::DictionaryValue> ConfigDictionaryFromMessage( | 61 std::unique_ptr<base::DictionaryValue> ConfigDictionaryFromMessage( |
| 57 std::unique_ptr<base::DictionaryValue> message) { | 62 std::unique_ptr<base::DictionaryValue> message) { |
| 58 std::unique_ptr<base::DictionaryValue> result; | 63 std::unique_ptr<base::DictionaryValue> result; |
| 59 const base::DictionaryValue* config_dict; | 64 const base::DictionaryValue* config_dict; |
| 60 if (message->GetDictionary("config", &config_dict)) { | 65 if (message->GetDictionary("config", &config_dict)) { |
| 61 result = config_dict->CreateDeepCopy(); | 66 result = config_dict->CreateDeepCopy(); |
| 62 } else { | |
| 63 LOG(ERROR) << "'config' dictionary not found"; | |
| 64 } | 67 } |
| 65 return result; | 68 return result; |
| 66 } | 69 } |
| 67 | 70 |
| 68 } // namespace | 71 } // namespace |
| 69 | 72 |
| 70 namespace remoting { | 73 namespace remoting { |
| 71 | 74 |
| 72 Me2MeNativeMessagingHost::Me2MeNativeMessagingHost( | 75 Me2MeNativeMessagingHost::Me2MeNativeMessagingHost( |
| 73 bool needs_elevation, | 76 bool needs_elevation, |
| 74 intptr_t parent_window_handle, | 77 intptr_t parent_window_handle, |
| 75 std::unique_ptr<extensions::NativeMessagingChannel> channel, | 78 std::unique_ptr<ChromotingHostContext> host_context, |
| 76 scoped_refptr<DaemonController> daemon_controller, | 79 scoped_refptr<DaemonController> daemon_controller, |
| 77 scoped_refptr<protocol::PairingRegistry> pairing_registry, | 80 scoped_refptr<protocol::PairingRegistry> pairing_registry, |
| 78 std::unique_ptr<OAuthClient> oauth_client) | 81 std::unique_ptr<OAuthClient> oauth_client) |
| 79 : needs_elevation_(needs_elevation), | 82 : needs_elevation_(needs_elevation), |
| 80 #if defined(OS_WIN) | 83 #if defined(OS_WIN) |
| 81 parent_window_handle_(parent_window_handle), | 84 parent_window_handle_(parent_window_handle), |
| 82 #endif | 85 #endif |
| 83 channel_(std::move(channel)), | 86 host_context_(std::move(host_context)), |
| 84 log_message_handler_( | |
| 85 base::Bind(&extensions::NativeMessagingChannel::SendMessage, | |
| 86 base::Unretained(channel_.get()))), | |
| 87 daemon_controller_(daemon_controller), | 87 daemon_controller_(daemon_controller), |
| 88 pairing_registry_(pairing_registry), | 88 pairing_registry_(pairing_registry), |
| 89 oauth_client_(std::move(oauth_client)), | 89 oauth_client_(std::move(oauth_client)), |
| 90 weak_factory_(this) { | 90 weak_factory_(this) { |
| 91 weak_ptr_ = weak_factory_.GetWeakPtr(); | 91 weak_ptr_ = weak_factory_.GetWeakPtr(); |
| 92 } | 92 } |
| 93 | 93 |
| 94 Me2MeNativeMessagingHost::~Me2MeNativeMessagingHost() { | 94 Me2MeNativeMessagingHost::~Me2MeNativeMessagingHost() { |
| 95 DCHECK(thread_checker_.CalledOnValidThread()); | 95 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 96 } | 96 } |
| 97 | 97 |
| 98 void Me2MeNativeMessagingHost::Start( | 98 void Me2MeNativeMessagingHost::OnMessage(const std::string& message) { |
| 99 const base::Closure& quit_closure) { | 99 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 100 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 101 DCHECK(!quit_closure.is_null()); | |
| 102 | 100 |
| 103 quit_closure_ = quit_closure; | 101 std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue()); |
| 104 | 102 std::unique_ptr<base::Value> message_value = base::JSONReader::Read(message); |
| 105 channel_->Start(this); | 103 if (!message_value->IsType(base::Value::TYPE_DICTIONARY)) { |
| 106 } | 104 OnError("Received a message that's not a dictionary."); |
| 107 | |
| 108 void Me2MeNativeMessagingHost::OnMessage(std::unique_ptr<base::Value> message) { | |
| 109 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 110 | |
| 111 if (!message->IsType(base::Value::TYPE_DICTIONARY)) { | |
| 112 LOG(ERROR) << "Received a message that's not a dictionary."; | |
| 113 channel_->SendMessage(nullptr); | |
| 114 return; | 105 return; |
| 115 } | 106 } |
| 116 | 107 |
| 117 std::unique_ptr<base::DictionaryValue> message_dict( | 108 std::unique_ptr<base::DictionaryValue> message_dict( |
| 118 static_cast<base::DictionaryValue*>(message.release())); | 109 static_cast<base::DictionaryValue*>(message_value.release())); |
| 119 std::unique_ptr<base::DictionaryValue> response(new base::DictionaryValue()); | |
| 120 | 110 |
| 121 // If the client supplies an ID, it will expect it in the response. This | 111 // If the client supplies an ID, it will expect it in the response. This |
| 122 // might be a string or a number, so cope with both. | 112 // might be a string or a number, so cope with both. |
| 123 const base::Value* id; | 113 const base::Value* id; |
| 124 if (message_dict->Get("id", &id)) | 114 if (message_dict->Get("id", &id)) |
| 125 response->Set("id", id->CreateDeepCopy()); | 115 response->Set("id", id->CreateDeepCopy()); |
| 126 | 116 |
| 127 std::string type; | 117 std::string type; |
| 128 if (!message_dict->GetString("type", &type)) { | 118 if (!message_dict->GetString("type", &type)) { |
| 129 LOG(ERROR) << "'type' not found"; | 119 OnError("'type' not found"); |
| 130 channel_->SendMessage(nullptr); | |
| 131 return; | 120 return; |
| 132 } | 121 } |
| 133 | 122 |
| 134 response->SetString("type", type + "Response"); | 123 response->SetString("type", type + "Response"); |
| 135 | 124 |
| 136 if (type == "hello") { | 125 if (type == "hello") { |
| 137 ProcessHello(std::move(message_dict), std::move(response)); | 126 ProcessHello(std::move(message_dict), std::move(response)); |
| 138 } else if (type == "clearPairedClients") { | 127 } else if (type == "clearPairedClients") { |
| 139 ProcessClearPairedClients(std::move(message_dict), std::move(response)); | 128 ProcessClearPairedClients(std::move(message_dict), std::move(response)); |
| 140 } else if (type == "deletePairedClient") { | 129 } else if (type == "deletePairedClient") { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 161 ProcessGetDaemonState(std::move(message_dict), std::move(response)); | 150 ProcessGetDaemonState(std::move(message_dict), std::move(response)); |
| 162 } else if (type == "getHostClientId") { | 151 } else if (type == "getHostClientId") { |
| 163 ProcessGetHostClientId(std::move(message_dict), std::move(response)); | 152 ProcessGetHostClientId(std::move(message_dict), std::move(response)); |
| 164 } else if (type == "getCredentialsFromAuthCode") { | 153 } else if (type == "getCredentialsFromAuthCode") { |
| 165 ProcessGetCredentialsFromAuthCode( | 154 ProcessGetCredentialsFromAuthCode( |
| 166 std::move(message_dict), std::move(response), true); | 155 std::move(message_dict), std::move(response), true); |
| 167 } else if (type == "getRefreshTokenFromAuthCode") { | 156 } else if (type == "getRefreshTokenFromAuthCode") { |
| 168 ProcessGetCredentialsFromAuthCode( | 157 ProcessGetCredentialsFromAuthCode( |
| 169 std::move(message_dict), std::move(response), false); | 158 std::move(message_dict), std::move(response), false); |
| 170 } else { | 159 } else { |
| 171 LOG(ERROR) << "Unsupported request type: " << type; | 160 OnError("Unsupported request type: " + type); |
| 172 OnError(); | |
| 173 } | 161 } |
| 174 } | 162 } |
| 175 | 163 |
| 176 void Me2MeNativeMessagingHost::OnDisconnect() { | 164 void Me2MeNativeMessagingHost::Start(Client* client) { |
| 177 if (!quit_closure_.is_null()) | 165 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 178 base::ResetAndReturn(&quit_closure_).Run(); | 166 client_ = client; |
| 167 log_message_handler_.reset(new LogMessageHandler( |
| 168 base::Bind(&Me2MeNativeMessagingHost::SendMessageToClient, weak_ptr_))); |
| 169 } |
| 170 |
| 171 scoped_refptr<base::SingleThreadTaskRunner> |
| 172 Me2MeNativeMessagingHost::task_runner() const { |
| 173 return host_context_->ui_task_runner(); |
| 179 } | 174 } |
| 180 | 175 |
| 181 void Me2MeNativeMessagingHost::ProcessHello( | 176 void Me2MeNativeMessagingHost::ProcessHello( |
| 182 std::unique_ptr<base::DictionaryValue> message, | 177 std::unique_ptr<base::DictionaryValue> message, |
| 183 std::unique_ptr<base::DictionaryValue> response) { | 178 std::unique_ptr<base::DictionaryValue> response) { |
| 184 DCHECK(thread_checker_.CalledOnValidThread()); | 179 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 185 | 180 |
| 186 response->SetString("version", STRINGIZE(VERSION)); | 181 response->SetString("version", STRINGIZE(VERSION)); |
| 187 std::unique_ptr<base::ListValue> supported_features_list( | 182 std::unique_ptr<base::ListValue> supported_features_list( |
| 188 new base::ListValue()); | 183 new base::ListValue()); |
| 189 supported_features_list->AppendStrings(std::vector<std::string>( | 184 supported_features_list->AppendStrings(std::vector<std::string>( |
| 190 kSupportedFeatures, kSupportedFeatures + arraysize(kSupportedFeatures))); | 185 kSupportedFeatures, kSupportedFeatures + arraysize(kSupportedFeatures))); |
| 191 response->Set("supportedFeatures", supported_features_list.release()); | 186 response->Set("supportedFeatures", supported_features_list.release()); |
| 192 channel_->SendMessage(std::move(response)); | 187 SendMessageToClient(std::move(response)); |
| 193 } | 188 } |
| 194 | 189 |
| 195 void Me2MeNativeMessagingHost::ProcessClearPairedClients( | 190 void Me2MeNativeMessagingHost::ProcessClearPairedClients( |
| 196 std::unique_ptr<base::DictionaryValue> message, | 191 std::unique_ptr<base::DictionaryValue> message, |
| 197 std::unique_ptr<base::DictionaryValue> response) { | 192 std::unique_ptr<base::DictionaryValue> response) { |
| 198 DCHECK(thread_checker_.CalledOnValidThread()); | 193 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 199 | 194 |
| 200 if (needs_elevation_) { | 195 if (needs_elevation_) { |
| 201 if (!DelegateToElevatedHost(std::move(message))) | 196 if (!DelegateToElevatedHost(std::move(message))) |
| 202 SendBooleanResult(std::move(response), false); | 197 SendBooleanResult(std::move(response), false); |
| 203 return; | 198 return; |
| 204 } | 199 } |
| 205 | 200 |
| 206 if (pairing_registry_.get()) { | 201 if (pairing_registry_.get()) { |
| 207 pairing_registry_->ClearAllPairings( | 202 pairing_registry_->ClearAllPairings( |
| 208 base::Bind(&Me2MeNativeMessagingHost::SendBooleanResult, weak_ptr_, | 203 base::Bind(&Me2MeNativeMessagingHost::SendBooleanResult, weak_ptr_, |
| 209 base::Passed(&response))); | 204 base::Passed(&response))); |
| 210 } else { | 205 } else { |
| 211 SendBooleanResult(std::move(response), false); | 206 SendBooleanResult(std::move(response), false); |
| 212 } | 207 } |
| 213 } | 208 } |
| 214 | 209 |
| 215 void Me2MeNativeMessagingHost::ProcessDeletePairedClient( | 210 void Me2MeNativeMessagingHost::ProcessDeletePairedClient( |
| 216 std::unique_ptr<base::DictionaryValue> message, | 211 std::unique_ptr<base::DictionaryValue> message, |
| 217 std::unique_ptr<base::DictionaryValue> response) { | 212 std::unique_ptr<base::DictionaryValue> response) { |
| 218 DCHECK(thread_checker_.CalledOnValidThread()); | 213 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 219 | 214 |
| 220 if (needs_elevation_) { | 215 if (needs_elevation_) { |
| 221 if (!DelegateToElevatedHost(std::move(message))) | 216 if (!DelegateToElevatedHost(std::move(message))) |
| 222 SendBooleanResult(std::move(response), false); | 217 SendBooleanResult(std::move(response), false); |
| 223 return; | 218 return; |
| 224 } | 219 } |
| 225 | 220 |
| 226 std::string client_id; | 221 std::string client_id; |
| 227 if (!message->GetString(protocol::PairingRegistry::kClientIdKey, | 222 if (!message->GetString(protocol::PairingRegistry::kClientIdKey, |
| 228 &client_id)) { | 223 &client_id)) { |
| 229 LOG(ERROR) << "'" << protocol::PairingRegistry::kClientIdKey | 224 OnError("'" + std::string(protocol::PairingRegistry::kClientIdKey) + |
| 230 << "' string not found."; | 225 "' string not found."); |
| 231 OnError(); | |
| 232 return; | 226 return; |
| 233 } | 227 } |
| 234 | 228 |
| 235 if (pairing_registry_.get()) { | 229 if (pairing_registry_.get()) { |
| 236 pairing_registry_->DeletePairing( | 230 pairing_registry_->DeletePairing( |
| 237 client_id, base::Bind(&Me2MeNativeMessagingHost::SendBooleanResult, | 231 client_id, base::Bind(&Me2MeNativeMessagingHost::SendBooleanResult, |
| 238 weak_ptr_, base::Passed(&response))); | 232 weak_ptr_, base::Passed(&response))); |
| 239 } else { | 233 } else { |
| 240 SendBooleanResult(std::move(response), false); | 234 SendBooleanResult(std::move(response), false); |
| 241 } | 235 } |
| 242 } | 236 } |
| 243 | 237 |
| 244 void Me2MeNativeMessagingHost::ProcessGetHostName( | 238 void Me2MeNativeMessagingHost::ProcessGetHostName( |
| 245 std::unique_ptr<base::DictionaryValue> message, | 239 std::unique_ptr<base::DictionaryValue> message, |
| 246 std::unique_ptr<base::DictionaryValue> response) { | 240 std::unique_ptr<base::DictionaryValue> response) { |
| 247 DCHECK(thread_checker_.CalledOnValidThread()); | 241 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 248 | 242 |
| 249 response->SetString("hostname", net::GetHostName()); | 243 response->SetString("hostname", net::GetHostName()); |
| 250 channel_->SendMessage(std::move(response)); | 244 SendMessageToClient(std::move(response)); |
| 251 } | 245 } |
| 252 | 246 |
| 253 void Me2MeNativeMessagingHost::ProcessGetPinHash( | 247 void Me2MeNativeMessagingHost::ProcessGetPinHash( |
| 254 std::unique_ptr<base::DictionaryValue> message, | 248 std::unique_ptr<base::DictionaryValue> message, |
| 255 std::unique_ptr<base::DictionaryValue> response) { | 249 std::unique_ptr<base::DictionaryValue> response) { |
| 256 DCHECK(thread_checker_.CalledOnValidThread()); | 250 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 257 | 251 |
| 258 std::string host_id; | 252 std::string host_id; |
| 259 if (!message->GetString("hostId", &host_id)) { | 253 if (!message->GetString("hostId", &host_id)) { |
| 260 LOG(ERROR) << "'hostId' not found: " << message.get(); | 254 std::string message_json; |
| 261 OnError(); | 255 base::JSONWriter::Write(*message, &message_json); |
| 256 OnError("'hostId' not found: " + message_json); |
| 262 return; | 257 return; |
| 263 } | 258 } |
| 264 std::string pin; | 259 std::string pin; |
| 265 if (!message->GetString("pin", &pin)) { | 260 if (!message->GetString("pin", &pin)) { |
| 266 LOG(ERROR) << "'pin' not found: " << message.get(); | 261 std::string message_json; |
| 267 OnError(); | 262 base::JSONWriter::Write(*message, &message_json); |
| 263 OnError("'pin' not found: " + message_json); |
| 268 return; | 264 return; |
| 269 } | 265 } |
| 270 response->SetString("hash", MakeHostPinHash(host_id, pin)); | 266 response->SetString("hash", MakeHostPinHash(host_id, pin)); |
| 271 channel_->SendMessage(std::move(response)); | 267 SendMessageToClient(std::move(response)); |
| 272 } | 268 } |
| 273 | 269 |
| 274 void Me2MeNativeMessagingHost::ProcessGenerateKeyPair( | 270 void Me2MeNativeMessagingHost::ProcessGenerateKeyPair( |
| 275 std::unique_ptr<base::DictionaryValue> message, | 271 std::unique_ptr<base::DictionaryValue> message, |
| 276 std::unique_ptr<base::DictionaryValue> response) { | 272 std::unique_ptr<base::DictionaryValue> response) { |
| 277 DCHECK(thread_checker_.CalledOnValidThread()); | 273 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 278 | 274 |
| 279 scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::Generate(); | 275 scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::Generate(); |
| 280 response->SetString("privateKey", key_pair->ToString()); | 276 response->SetString("privateKey", key_pair->ToString()); |
| 281 response->SetString("publicKey", key_pair->GetPublicKey()); | 277 response->SetString("publicKey", key_pair->GetPublicKey()); |
| 282 channel_->SendMessage(std::move(response)); | 278 SendMessageToClient(std::move(response)); |
| 283 } | 279 } |
| 284 | 280 |
| 285 void Me2MeNativeMessagingHost::ProcessUpdateDaemonConfig( | 281 void Me2MeNativeMessagingHost::ProcessUpdateDaemonConfig( |
| 286 std::unique_ptr<base::DictionaryValue> message, | 282 std::unique_ptr<base::DictionaryValue> message, |
| 287 std::unique_ptr<base::DictionaryValue> response) { | 283 std::unique_ptr<base::DictionaryValue> response) { |
| 288 DCHECK(thread_checker_.CalledOnValidThread()); | 284 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 289 | 285 |
| 290 if (needs_elevation_) { | 286 if (needs_elevation_) { |
| 291 if (!DelegateToElevatedHost(std::move(message))) | 287 if (!DelegateToElevatedHost(std::move(message))) |
| 292 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); | 288 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); |
| 293 return; | 289 return; |
| 294 } | 290 } |
| 295 | 291 |
| 296 std::unique_ptr<base::DictionaryValue> config_dict = | 292 std::unique_ptr<base::DictionaryValue> config_dict = |
| 297 ConfigDictionaryFromMessage(std::move(message)); | 293 ConfigDictionaryFromMessage(std::move(message)); |
| 298 if (!config_dict) { | 294 if (!config_dict) { |
| 299 OnError(); | 295 OnError("'config' dictionary not found"); |
| 300 return; | 296 return; |
| 301 } | 297 } |
| 302 | 298 |
| 303 daemon_controller_->UpdateConfig( | 299 daemon_controller_->UpdateConfig( |
| 304 std::move(config_dict), | 300 std::move(config_dict), |
| 305 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, | 301 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, |
| 306 base::Passed(&response))); | 302 base::Passed(&response))); |
| 307 } | 303 } |
| 308 | 304 |
| 309 void Me2MeNativeMessagingHost::ProcessGetDaemonConfig( | 305 void Me2MeNativeMessagingHost::ProcessGetDaemonConfig( |
| 310 std::unique_ptr<base::DictionaryValue> message, | 306 std::unique_ptr<base::DictionaryValue> message, |
| 311 std::unique_ptr<base::DictionaryValue> response) { | 307 std::unique_ptr<base::DictionaryValue> response) { |
| 312 DCHECK(thread_checker_.CalledOnValidThread()); | 308 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 313 | 309 |
| 314 daemon_controller_->GetConfig( | 310 daemon_controller_->GetConfig( |
| 315 base::Bind(&Me2MeNativeMessagingHost::SendConfigResponse, weak_ptr_, | 311 base::Bind(&Me2MeNativeMessagingHost::SendConfigResponse, weak_ptr_, |
| 316 base::Passed(&response))); | 312 base::Passed(&response))); |
| 317 } | 313 } |
| 318 | 314 |
| 319 void Me2MeNativeMessagingHost::ProcessGetPairedClients( | 315 void Me2MeNativeMessagingHost::ProcessGetPairedClients( |
| 320 std::unique_ptr<base::DictionaryValue> message, | 316 std::unique_ptr<base::DictionaryValue> message, |
| 321 std::unique_ptr<base::DictionaryValue> response) { | 317 std::unique_ptr<base::DictionaryValue> response) { |
| 322 DCHECK(thread_checker_.CalledOnValidThread()); | 318 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 323 | 319 |
| 324 if (pairing_registry_.get()) { | 320 if (pairing_registry_.get()) { |
| 325 pairing_registry_->GetAllPairings( | 321 pairing_registry_->GetAllPairings( |
| 326 base::Bind(&Me2MeNativeMessagingHost::SendPairedClientsResponse, | 322 base::Bind(&Me2MeNativeMessagingHost::SendPairedClientsResponse, |
| 327 weak_ptr_, base::Passed(&response))); | 323 weak_ptr_, base::Passed(&response))); |
| 328 } else { | 324 } else { |
| 329 std::unique_ptr<base::ListValue> no_paired_clients(new base::ListValue); | 325 std::unique_ptr<base::ListValue> no_paired_clients(new base::ListValue); |
| 330 SendPairedClientsResponse(std::move(response), | 326 SendPairedClientsResponse(std::move(response), |
| 331 std::move(no_paired_clients)); | 327 std::move(no_paired_clients)); |
| 332 } | 328 } |
| 333 } | 329 } |
| 334 | 330 |
| 335 void Me2MeNativeMessagingHost::ProcessGetUsageStatsConsent( | 331 void Me2MeNativeMessagingHost::ProcessGetUsageStatsConsent( |
| 336 std::unique_ptr<base::DictionaryValue> message, | 332 std::unique_ptr<base::DictionaryValue> message, |
| 337 std::unique_ptr<base::DictionaryValue> response) { | 333 std::unique_ptr<base::DictionaryValue> response) { |
| 338 DCHECK(thread_checker_.CalledOnValidThread()); | 334 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 339 | 335 |
| 340 daemon_controller_->GetUsageStatsConsent( | 336 daemon_controller_->GetUsageStatsConsent( |
| 341 base::Bind(&Me2MeNativeMessagingHost::SendUsageStatsConsentResponse, | 337 base::Bind(&Me2MeNativeMessagingHost::SendUsageStatsConsentResponse, |
| 342 weak_ptr_, base::Passed(&response))); | 338 weak_ptr_, base::Passed(&response))); |
| 343 } | 339 } |
| 344 | 340 |
| 345 void Me2MeNativeMessagingHost::ProcessStartDaemon( | 341 void Me2MeNativeMessagingHost::ProcessStartDaemon( |
| 346 std::unique_ptr<base::DictionaryValue> message, | 342 std::unique_ptr<base::DictionaryValue> message, |
| 347 std::unique_ptr<base::DictionaryValue> response) { | 343 std::unique_ptr<base::DictionaryValue> response) { |
| 348 DCHECK(thread_checker_.CalledOnValidThread()); | 344 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 349 | 345 |
| 350 if (needs_elevation_) { | 346 if (needs_elevation_) { |
| 351 if (!DelegateToElevatedHost(std::move(message))) | 347 if (!DelegateToElevatedHost(std::move(message))) |
| 352 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); | 348 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); |
| 353 return; | 349 return; |
| 354 } | 350 } |
| 355 | 351 |
| 356 bool consent; | 352 bool consent; |
| 357 if (!message->GetBoolean("consent", &consent)) { | 353 if (!message->GetBoolean("consent", &consent)) { |
| 358 LOG(ERROR) << "'consent' not found."; | 354 OnError("'consent' not found."); |
| 359 OnError(); | |
| 360 return; | 355 return; |
| 361 } | 356 } |
| 362 | 357 |
| 363 std::unique_ptr<base::DictionaryValue> config_dict = | 358 std::unique_ptr<base::DictionaryValue> config_dict = |
| 364 ConfigDictionaryFromMessage(std::move(message)); | 359 ConfigDictionaryFromMessage(std::move(message)); |
| 365 if (!config_dict) { | 360 if (!config_dict) { |
| 366 OnError(); | 361 OnError("'config' dictionary not found"); |
| 367 return; | 362 return; |
| 368 } | 363 } |
| 369 | 364 |
| 370 daemon_controller_->SetConfigAndStart( | 365 daemon_controller_->SetConfigAndStart( |
| 371 std::move(config_dict), consent, | 366 std::move(config_dict), consent, |
| 372 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, | 367 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, |
| 373 base::Passed(&response))); | 368 base::Passed(&response))); |
| 374 } | 369 } |
| 375 | 370 |
| 376 void Me2MeNativeMessagingHost::ProcessStopDaemon( | 371 void Me2MeNativeMessagingHost::ProcessStopDaemon( |
| 377 std::unique_ptr<base::DictionaryValue> message, | 372 std::unique_ptr<base::DictionaryValue> message, |
| 378 std::unique_ptr<base::DictionaryValue> response) { | 373 std::unique_ptr<base::DictionaryValue> response) { |
| 379 DCHECK(thread_checker_.CalledOnValidThread()); | 374 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 380 | 375 |
| 381 if (needs_elevation_) { | 376 if (needs_elevation_) { |
| 382 if (!DelegateToElevatedHost(std::move(message))) | 377 if (!DelegateToElevatedHost(std::move(message))) |
| 383 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); | 378 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); |
| 384 return; | 379 return; |
| 385 } | 380 } |
| 386 | 381 |
| 387 daemon_controller_->Stop( | 382 daemon_controller_->Stop( |
| 388 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, | 383 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, |
| 389 base::Passed(&response))); | 384 base::Passed(&response))); |
| 390 } | 385 } |
| 391 | 386 |
| 392 void Me2MeNativeMessagingHost::ProcessGetDaemonState( | 387 void Me2MeNativeMessagingHost::ProcessGetDaemonState( |
| 393 std::unique_ptr<base::DictionaryValue> message, | 388 std::unique_ptr<base::DictionaryValue> message, |
| 394 std::unique_ptr<base::DictionaryValue> response) { | 389 std::unique_ptr<base::DictionaryValue> response) { |
| 395 DCHECK(thread_checker_.CalledOnValidThread()); | 390 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 396 | 391 |
| 397 DaemonController::State state = daemon_controller_->GetState(); | 392 DaemonController::State state = daemon_controller_->GetState(); |
| 398 switch (state) { | 393 switch (state) { |
| 399 case DaemonController::STATE_NOT_IMPLEMENTED: | 394 case DaemonController::STATE_NOT_IMPLEMENTED: |
| 400 response->SetString("state", "NOT_IMPLEMENTED"); | 395 response->SetString("state", "NOT_IMPLEMENTED"); |
| 401 break; | 396 break; |
| 402 case DaemonController::STATE_STOPPED: | 397 case DaemonController::STATE_STOPPED: |
| 403 response->SetString("state", "STOPPED"); | 398 response->SetString("state", "STOPPED"); |
| 404 break; | 399 break; |
| 405 case DaemonController::STATE_STARTING: | 400 case DaemonController::STATE_STARTING: |
| 406 response->SetString("state", "STARTING"); | 401 response->SetString("state", "STARTING"); |
| 407 break; | 402 break; |
| 408 case DaemonController::STATE_STARTED: | 403 case DaemonController::STATE_STARTED: |
| 409 response->SetString("state", "STARTED"); | 404 response->SetString("state", "STARTED"); |
| 410 break; | 405 break; |
| 411 case DaemonController::STATE_STOPPING: | 406 case DaemonController::STATE_STOPPING: |
| 412 response->SetString("state", "STOPPING"); | 407 response->SetString("state", "STOPPING"); |
| 413 break; | 408 break; |
| 414 case DaemonController::STATE_UNKNOWN: | 409 case DaemonController::STATE_UNKNOWN: |
| 415 response->SetString("state", "UNKNOWN"); | 410 response->SetString("state", "UNKNOWN"); |
| 416 break; | 411 break; |
| 417 } | 412 } |
| 418 channel_->SendMessage(std::move(response)); | 413 SendMessageToClient(std::move(response)); |
| 419 } | 414 } |
| 420 | 415 |
| 421 void Me2MeNativeMessagingHost::ProcessGetHostClientId( | 416 void Me2MeNativeMessagingHost::ProcessGetHostClientId( |
| 422 std::unique_ptr<base::DictionaryValue> message, | 417 std::unique_ptr<base::DictionaryValue> message, |
| 423 std::unique_ptr<base::DictionaryValue> response) { | 418 std::unique_ptr<base::DictionaryValue> response) { |
| 424 DCHECK(thread_checker_.CalledOnValidThread()); | 419 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 425 | 420 |
| 426 response->SetString("clientId", google_apis::GetOAuth2ClientID( | 421 response->SetString("clientId", google_apis::GetOAuth2ClientID( |
| 427 google_apis::CLIENT_REMOTING_HOST)); | 422 google_apis::CLIENT_REMOTING_HOST)); |
| 428 channel_->SendMessage(std::move(response)); | 423 SendMessageToClient(std::move(response)); |
| 429 } | 424 } |
| 430 | 425 |
| 431 void Me2MeNativeMessagingHost::ProcessGetCredentialsFromAuthCode( | 426 void Me2MeNativeMessagingHost::ProcessGetCredentialsFromAuthCode( |
| 432 std::unique_ptr<base::DictionaryValue> message, | 427 std::unique_ptr<base::DictionaryValue> message, |
| 433 std::unique_ptr<base::DictionaryValue> response, | 428 std::unique_ptr<base::DictionaryValue> response, |
| 434 bool need_user_email) { | 429 bool need_user_email) { |
| 435 DCHECK(thread_checker_.CalledOnValidThread()); | 430 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 436 | 431 |
| 437 std::string auth_code; | 432 std::string auth_code; |
| 438 if (!message->GetString("authorizationCode", &auth_code)) { | 433 if (!message->GetString("authorizationCode", &auth_code)) { |
| 439 LOG(ERROR) << "'authorizationCode' string not found."; | 434 OnError("'authorizationCode' string not found."); |
| 440 OnError(); | |
| 441 return; | 435 return; |
| 442 } | 436 } |
| 443 | 437 |
| 444 gaia::OAuthClientInfo oauth_client_info = { | 438 gaia::OAuthClientInfo oauth_client_info = { |
| 445 google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING_HOST), | 439 google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING_HOST), |
| 446 google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING_HOST), | 440 google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING_HOST), |
| 447 kServiceAccountRedirectUri | 441 kServiceAccountRedirectUri |
| 448 }; | 442 }; |
| 449 | 443 |
| 450 oauth_client_->GetCredentialsFromAuthCode( | 444 oauth_client_->GetCredentialsFromAuthCode( |
| 451 oauth_client_info, auth_code, need_user_email, base::Bind( | 445 oauth_client_info, auth_code, need_user_email, base::Bind( |
| 452 &Me2MeNativeMessagingHost::SendCredentialsResponse, weak_ptr_, | 446 &Me2MeNativeMessagingHost::SendCredentialsResponse, weak_ptr_, |
| 453 base::Passed(&response))); | 447 base::Passed(&response))); |
| 454 } | 448 } |
| 455 | 449 |
| 456 void Me2MeNativeMessagingHost::SendConfigResponse( | 450 void Me2MeNativeMessagingHost::SendConfigResponse( |
| 457 std::unique_ptr<base::DictionaryValue> response, | 451 std::unique_ptr<base::DictionaryValue> response, |
| 458 std::unique_ptr<base::DictionaryValue> config) { | 452 std::unique_ptr<base::DictionaryValue> config) { |
| 459 DCHECK(thread_checker_.CalledOnValidThread()); | 453 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 460 | 454 |
| 461 if (config) { | 455 if (config) { |
| 462 response->Set("config", config.release()); | 456 response->Set("config", config.release()); |
| 463 } else { | 457 } else { |
| 464 response->Set("config", base::Value::CreateNullValue()); | 458 response->Set("config", base::Value::CreateNullValue()); |
| 465 } | 459 } |
| 466 channel_->SendMessage(std::move(response)); | 460 SendMessageToClient(std::move(response)); |
| 467 } | 461 } |
| 468 | 462 |
| 469 void Me2MeNativeMessagingHost::SendPairedClientsResponse( | 463 void Me2MeNativeMessagingHost::SendPairedClientsResponse( |
| 470 std::unique_ptr<base::DictionaryValue> response, | 464 std::unique_ptr<base::DictionaryValue> response, |
| 471 std::unique_ptr<base::ListValue> pairings) { | 465 std::unique_ptr<base::ListValue> pairings) { |
| 472 DCHECK(thread_checker_.CalledOnValidThread()); | 466 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 473 | 467 |
| 474 response->Set("pairedClients", pairings.release()); | 468 response->Set("pairedClients", pairings.release()); |
| 475 channel_->SendMessage(std::move(response)); | 469 SendMessageToClient(std::move(response)); |
| 476 } | 470 } |
| 477 | 471 |
| 478 void Me2MeNativeMessagingHost::SendUsageStatsConsentResponse( | 472 void Me2MeNativeMessagingHost::SendUsageStatsConsentResponse( |
| 479 std::unique_ptr<base::DictionaryValue> response, | 473 std::unique_ptr<base::DictionaryValue> response, |
| 480 const DaemonController::UsageStatsConsent& consent) { | 474 const DaemonController::UsageStatsConsent& consent) { |
| 481 DCHECK(thread_checker_.CalledOnValidThread()); | 475 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 482 | 476 |
| 483 response->SetBoolean("supported", consent.supported); | 477 response->SetBoolean("supported", consent.supported); |
| 484 response->SetBoolean("allowed", consent.allowed); | 478 response->SetBoolean("allowed", consent.allowed); |
| 485 response->SetBoolean("setByPolicy", consent.set_by_policy); | 479 response->SetBoolean("setByPolicy", consent.set_by_policy); |
| 486 channel_->SendMessage(std::move(response)); | 480 SendMessageToClient(std::move(response)); |
| 487 } | 481 } |
| 488 | 482 |
| 489 void Me2MeNativeMessagingHost::SendAsyncResult( | 483 void Me2MeNativeMessagingHost::SendAsyncResult( |
| 490 std::unique_ptr<base::DictionaryValue> response, | 484 std::unique_ptr<base::DictionaryValue> response, |
| 491 DaemonController::AsyncResult result) { | 485 DaemonController::AsyncResult result) { |
| 492 DCHECK(thread_checker_.CalledOnValidThread()); | 486 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 493 | 487 |
| 494 switch (result) { | 488 switch (result) { |
| 495 case DaemonController::RESULT_OK: | 489 case DaemonController::RESULT_OK: |
| 496 response->SetString("result", "OK"); | 490 response->SetString("result", "OK"); |
| 497 break; | 491 break; |
| 498 case DaemonController::RESULT_FAILED: | 492 case DaemonController::RESULT_FAILED: |
| 499 response->SetString("result", "FAILED"); | 493 response->SetString("result", "FAILED"); |
| 500 break; | 494 break; |
| 501 case DaemonController::RESULT_CANCELLED: | 495 case DaemonController::RESULT_CANCELLED: |
| 502 response->SetString("result", "CANCELLED"); | 496 response->SetString("result", "CANCELLED"); |
| 503 break; | 497 break; |
| 504 } | 498 } |
| 505 channel_->SendMessage(std::move(response)); | 499 SendMessageToClient(std::move(response)); |
| 506 } | 500 } |
| 507 | 501 |
| 508 void Me2MeNativeMessagingHost::SendBooleanResult( | 502 void Me2MeNativeMessagingHost::SendBooleanResult( |
| 509 std::unique_ptr<base::DictionaryValue> response, | 503 std::unique_ptr<base::DictionaryValue> response, |
| 510 bool result) { | 504 bool result) { |
| 511 DCHECK(thread_checker_.CalledOnValidThread()); | 505 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 512 | 506 |
| 513 response->SetBoolean("result", result); | 507 response->SetBoolean("result", result); |
| 514 channel_->SendMessage(std::move(response)); | 508 SendMessageToClient(std::move(response)); |
| 515 } | 509 } |
| 516 | 510 |
| 517 void Me2MeNativeMessagingHost::SendCredentialsResponse( | 511 void Me2MeNativeMessagingHost::SendCredentialsResponse( |
| 518 std::unique_ptr<base::DictionaryValue> response, | 512 std::unique_ptr<base::DictionaryValue> response, |
| 519 const std::string& user_email, | 513 const std::string& user_email, |
| 520 const std::string& refresh_token) { | 514 const std::string& refresh_token) { |
| 521 DCHECK(thread_checker_.CalledOnValidThread()); | 515 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 522 | 516 |
| 523 if (!user_email.empty()) { | 517 if (!user_email.empty()) { |
| 524 response->SetString("userEmail", user_email); | 518 response->SetString("userEmail", user_email); |
| 525 } | 519 } |
| 526 response->SetString("refreshToken", refresh_token); | 520 response->SetString("refreshToken", refresh_token); |
| 527 channel_->SendMessage(std::move(response)); | 521 SendMessageToClient(std::move(response)); |
| 528 } | 522 } |
| 529 | 523 |
| 530 void Me2MeNativeMessagingHost::OnError() { | 524 void Me2MeNativeMessagingHost::SendMessageToClient( |
| 531 // Trigger a host shutdown by sending a nullptr message. | 525 std::unique_ptr<base::Value> message) const { |
| 532 channel_->SendMessage(nullptr); | 526 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 527 std::string message_json; |
| 528 base::JSONWriter::Write(*message, &message_json); |
| 529 client_->PostMessageFromNativeHost(message_json); |
| 533 } | 530 } |
| 534 | 531 |
| 535 void Me2MeNativeMessagingHost::Stop() { | 532 void Me2MeNativeMessagingHost::OnError(const std::string& error_message) { |
| 536 DCHECK(thread_checker_.CalledOnValidThread()); | 533 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 537 | 534 |
| 538 if (!quit_closure_.is_null()) | 535 if (!error_message.empty()) { |
| 539 base::ResetAndReturn(&quit_closure_).Run(); | 536 LOG(ERROR) << error_message; |
| 537 } |
| 538 |
| 539 // Trigger a host shutdown by sending an empty message. |
| 540 client_->CloseChannel(std::string()); |
| 540 } | 541 } |
| 541 | 542 |
| 542 #if defined(OS_WIN) | 543 #if defined(OS_WIN) |
| 543 Me2MeNativeMessagingHost::ElevatedChannelEventHandler:: | 544 Me2MeNativeMessagingHost::ElevatedChannelEventHandler:: |
| 544 ElevatedChannelEventHandler(Me2MeNativeMessagingHost* host) | 545 ElevatedChannelEventHandler(extensions::NativeMessageHost::Client* client) |
| 545 : parent_(host) { | 546 : client_(client) {} |
| 546 } | |
| 547 | 547 |
| 548 void Me2MeNativeMessagingHost::ElevatedChannelEventHandler::OnMessage( | 548 void Me2MeNativeMessagingHost::ElevatedChannelEventHandler::OnMessage( |
| 549 std::unique_ptr<base::Value> message) { | 549 std::unique_ptr<base::Value> message) { |
| 550 DCHECK(parent_->thread_checker_.CalledOnValidThread()); | 550 DCHECK(thread_checker_.CalledOnValidThread()); |
| 551 | 551 |
| 552 // Simply pass along the response from the elevated host to the client. | 552 // Simply pass along the response from the elevated host to the client. |
| 553 parent_->channel_->SendMessage(std::move(message)); | 553 std::string message_json; |
| 554 base::JSONWriter::Write(*message, &message_json); |
| 555 client_->PostMessageFromNativeHost(message_json); |
| 554 } | 556 } |
| 555 | 557 |
| 556 void Me2MeNativeMessagingHost::ElevatedChannelEventHandler::OnDisconnect() { | 558 void Me2MeNativeMessagingHost::ElevatedChannelEventHandler::OnDisconnect() { |
| 557 parent_->OnDisconnect(); | 559 DCHECK(thread_checker_.CalledOnValidThread()); |
| 560 client_->CloseChannel(std::string()); |
| 558 } | 561 } |
| 559 | 562 |
| 560 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( | 563 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( |
| 561 std::unique_ptr<base::DictionaryValue> message) { | 564 std::unique_ptr<base::DictionaryValue> message) { |
| 562 DCHECK(thread_checker_.CalledOnValidThread()); | 565 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 563 | 566 |
| 564 EnsureElevatedHostCreated(); | 567 EnsureElevatedHostCreated(); |
| 565 | 568 |
| 566 // elevated_channel_ will be null if user rejects the UAC request. | 569 // elevated_channel_ will be null if user rejects the UAC request. |
| 567 if (elevated_channel_) | 570 if (elevated_channel_) |
| 568 elevated_channel_->SendMessage(std::move(message)); | 571 elevated_channel_->SendMessage(std::move(message)); |
| 569 | 572 |
| 570 return elevated_channel_ != nullptr; | 573 return elevated_channel_ != nullptr; |
| 571 } | 574 } |
| 572 | 575 |
| 573 void Me2MeNativeMessagingHost::EnsureElevatedHostCreated() { | 576 void Me2MeNativeMessagingHost::EnsureElevatedHostCreated() { |
| 574 DCHECK(thread_checker_.CalledOnValidThread()); | 577 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 575 DCHECK(needs_elevation_); | 578 DCHECK(needs_elevation_); |
| 576 | 579 |
| 577 if (elevated_channel_) | 580 if (elevated_channel_) |
| 578 return; | 581 return; |
| 579 | 582 |
| 580 base::win::ScopedHandle read_handle; | 583 base::win::ScopedHandle read_handle; |
| 581 base::win::ScopedHandle write_handle; | 584 base::win::ScopedHandle write_handle; |
| 582 // Get the name of the binary to launch. | 585 // Get the name of the binary to launch. |
| 583 base::FilePath binary = base::CommandLine::ForCurrentProcess()->GetProgram(); | 586 base::FilePath binary = base::CommandLine::ForCurrentProcess()->GetProgram(); |
| 584 ProcessLaunchResult result = LaunchNativeMessagingHostProcess( | 587 ProcessLaunchResult result = LaunchNativeMessagingHostProcess( |
| 585 binary, parent_window_handle_, | 588 binary, parent_window_handle_, |
| 586 /*elevate_process=*/true, &read_handle, &write_handle); | 589 /*elevate_process=*/true, &read_handle, &write_handle); |
| 587 if (result != PROCESS_LAUNCH_RESULT_SUCCESS) { | 590 if (result != PROCESS_LAUNCH_RESULT_SUCCESS) { |
| 588 if (result != PROCESS_LAUNCH_RESULT_CANCELLED) { | 591 if (result != PROCESS_LAUNCH_RESULT_CANCELLED) { |
| 589 OnError(); | 592 OnError(std::string()); |
| 590 } | 593 } |
| 591 return; | 594 return; |
| 592 } | 595 } |
| 593 | 596 |
| 594 // Set up the native messaging channel to talk to the elevated host. | 597 // Set up the native messaging channel to talk to the elevated host. |
| 595 // Note that input for the elevated channel is output for the elevated host. | 598 // Note that input for the elevated channel is output for the elevated host. |
| 596 elevated_channel_.reset(new PipeMessagingChannel( | 599 elevated_channel_.reset(new PipeMessagingChannel( |
| 597 base::File(read_handle.Take()), base::File(write_handle.Take()))); | 600 base::File(read_handle.Take()), base::File(write_handle.Take()))); |
| 598 | 601 |
| 599 elevated_channel_event_handler_.reset( | 602 elevated_channel_event_handler_.reset( |
| 600 new Me2MeNativeMessagingHost::ElevatedChannelEventHandler(this)); | 603 new Me2MeNativeMessagingHost::ElevatedChannelEventHandler(client_)); |
| 601 elevated_channel_->Start(elevated_channel_event_handler_.get()); | 604 elevated_channel_->Start(elevated_channel_event_handler_.get()); |
| 602 | 605 |
| 603 elevated_host_timer_.Start( | 606 elevated_host_timer_.Start( |
| 604 FROM_HERE, base::TimeDelta::FromSeconds(kElevatedHostTimeoutSeconds), | 607 FROM_HERE, base::TimeDelta::FromSeconds(kElevatedHostTimeoutSeconds), |
| 605 this, &Me2MeNativeMessagingHost::DisconnectElevatedHost); | 608 this, &Me2MeNativeMessagingHost::DisconnectElevatedHost); |
| 606 } | 609 } |
| 607 | 610 |
| 608 void Me2MeNativeMessagingHost::DisconnectElevatedHost() { | 611 void Me2MeNativeMessagingHost::DisconnectElevatedHost() { |
| 609 DCHECK(thread_checker_.CalledOnValidThread()); | 612 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 610 | 613 |
| 611 // This will send an EOF to the elevated host, triggering its shutdown. | 614 // This will send an EOF to the elevated host, triggering its shutdown. |
| 612 elevated_channel_.reset(); | 615 elevated_channel_.reset(); |
| 613 } | 616 } |
| 614 | 617 |
| 615 #else // defined(OS_WIN) | 618 #else // defined(OS_WIN) |
| 616 | 619 |
| 617 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( | 620 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( |
| 618 std::unique_ptr<base::DictionaryValue> message) { | 621 std::unique_ptr<base::DictionaryValue> message) { |
| 619 NOTREACHED(); | 622 NOTREACHED(); |
| 620 return false; | 623 return false; |
| 621 } | 624 } |
| 622 | 625 |
| 623 #endif // !defined(OS_WIN) | 626 #endif // !defined(OS_WIN) |
| 624 | 627 |
| 625 } // namespace remoting | 628 } // namespace remoting |
| OLD | NEW |