Chromium Code Reviews| 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 LOG(ERROR) << "'hostId' not found: " << message.get(); |
| 261 OnError(); | 255 OnError(std::string()); |
|
Sergey Ulanov
2016/08/01 18:45:18
OnError("'hostId' not found")?
joedow
2016/08/01 19:21:34
Done.
| |
| 262 return; | 256 return; |
| 263 } | 257 } |
| 264 std::string pin; | 258 std::string pin; |
| 265 if (!message->GetString("pin", &pin)) { | 259 if (!message->GetString("pin", &pin)) { |
| 266 LOG(ERROR) << "'pin' not found: " << message.get(); | 260 LOG(ERROR) << "'pin' not found: " << message.get(); |
| 267 OnError(); | 261 OnError(std::string()); |
|
Sergey Ulanov
2016/08/01 18:45:19
same here
joedow
2016/08/01 19:21:34
Done.
| |
| 268 return; | 262 return; |
| 269 } | 263 } |
| 270 response->SetString("hash", MakeHostPinHash(host_id, pin)); | 264 response->SetString("hash", MakeHostPinHash(host_id, pin)); |
| 271 channel_->SendMessage(std::move(response)); | 265 SendMessageToClient(std::move(response)); |
| 272 } | 266 } |
| 273 | 267 |
| 274 void Me2MeNativeMessagingHost::ProcessGenerateKeyPair( | 268 void Me2MeNativeMessagingHost::ProcessGenerateKeyPair( |
| 275 std::unique_ptr<base::DictionaryValue> message, | 269 std::unique_ptr<base::DictionaryValue> message, |
| 276 std::unique_ptr<base::DictionaryValue> response) { | 270 std::unique_ptr<base::DictionaryValue> response) { |
| 277 DCHECK(thread_checker_.CalledOnValidThread()); | 271 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 278 | 272 |
| 279 scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::Generate(); | 273 scoped_refptr<RsaKeyPair> key_pair = RsaKeyPair::Generate(); |
| 280 response->SetString("privateKey", key_pair->ToString()); | 274 response->SetString("privateKey", key_pair->ToString()); |
| 281 response->SetString("publicKey", key_pair->GetPublicKey()); | 275 response->SetString("publicKey", key_pair->GetPublicKey()); |
| 282 channel_->SendMessage(std::move(response)); | 276 SendMessageToClient(std::move(response)); |
| 283 } | 277 } |
| 284 | 278 |
| 285 void Me2MeNativeMessagingHost::ProcessUpdateDaemonConfig( | 279 void Me2MeNativeMessagingHost::ProcessUpdateDaemonConfig( |
| 286 std::unique_ptr<base::DictionaryValue> message, | 280 std::unique_ptr<base::DictionaryValue> message, |
| 287 std::unique_ptr<base::DictionaryValue> response) { | 281 std::unique_ptr<base::DictionaryValue> response) { |
| 288 DCHECK(thread_checker_.CalledOnValidThread()); | 282 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 289 | 283 |
| 290 if (needs_elevation_) { | 284 if (needs_elevation_) { |
| 291 if (!DelegateToElevatedHost(std::move(message))) | 285 if (!DelegateToElevatedHost(std::move(message))) |
| 292 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); | 286 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); |
| 293 return; | 287 return; |
| 294 } | 288 } |
| 295 | 289 |
| 296 std::unique_ptr<base::DictionaryValue> config_dict = | 290 std::unique_ptr<base::DictionaryValue> config_dict = |
| 297 ConfigDictionaryFromMessage(std::move(message)); | 291 ConfigDictionaryFromMessage(std::move(message)); |
| 298 if (!config_dict) { | 292 if (!config_dict) { |
| 299 OnError(); | 293 OnError("'config' dictionary not found"); |
| 300 return; | 294 return; |
| 301 } | 295 } |
| 302 | 296 |
| 303 daemon_controller_->UpdateConfig( | 297 daemon_controller_->UpdateConfig( |
| 304 std::move(config_dict), | 298 std::move(config_dict), |
| 305 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, | 299 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, |
| 306 base::Passed(&response))); | 300 base::Passed(&response))); |
| 307 } | 301 } |
| 308 | 302 |
| 309 void Me2MeNativeMessagingHost::ProcessGetDaemonConfig( | 303 void Me2MeNativeMessagingHost::ProcessGetDaemonConfig( |
| 310 std::unique_ptr<base::DictionaryValue> message, | 304 std::unique_ptr<base::DictionaryValue> message, |
| 311 std::unique_ptr<base::DictionaryValue> response) { | 305 std::unique_ptr<base::DictionaryValue> response) { |
| 312 DCHECK(thread_checker_.CalledOnValidThread()); | 306 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 313 | 307 |
| 314 daemon_controller_->GetConfig( | 308 daemon_controller_->GetConfig( |
| 315 base::Bind(&Me2MeNativeMessagingHost::SendConfigResponse, weak_ptr_, | 309 base::Bind(&Me2MeNativeMessagingHost::SendConfigResponse, weak_ptr_, |
| 316 base::Passed(&response))); | 310 base::Passed(&response))); |
| 317 } | 311 } |
| 318 | 312 |
| 319 void Me2MeNativeMessagingHost::ProcessGetPairedClients( | 313 void Me2MeNativeMessagingHost::ProcessGetPairedClients( |
| 320 std::unique_ptr<base::DictionaryValue> message, | 314 std::unique_ptr<base::DictionaryValue> message, |
| 321 std::unique_ptr<base::DictionaryValue> response) { | 315 std::unique_ptr<base::DictionaryValue> response) { |
| 322 DCHECK(thread_checker_.CalledOnValidThread()); | 316 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 323 | 317 |
| 324 if (pairing_registry_.get()) { | 318 if (pairing_registry_.get()) { |
| 325 pairing_registry_->GetAllPairings( | 319 pairing_registry_->GetAllPairings( |
| 326 base::Bind(&Me2MeNativeMessagingHost::SendPairedClientsResponse, | 320 base::Bind(&Me2MeNativeMessagingHost::SendPairedClientsResponse, |
| 327 weak_ptr_, base::Passed(&response))); | 321 weak_ptr_, base::Passed(&response))); |
| 328 } else { | 322 } else { |
| 329 std::unique_ptr<base::ListValue> no_paired_clients(new base::ListValue); | 323 std::unique_ptr<base::ListValue> no_paired_clients(new base::ListValue); |
| 330 SendPairedClientsResponse(std::move(response), | 324 SendPairedClientsResponse(std::move(response), |
| 331 std::move(no_paired_clients)); | 325 std::move(no_paired_clients)); |
| 332 } | 326 } |
| 333 } | 327 } |
| 334 | 328 |
| 335 void Me2MeNativeMessagingHost::ProcessGetUsageStatsConsent( | 329 void Me2MeNativeMessagingHost::ProcessGetUsageStatsConsent( |
| 336 std::unique_ptr<base::DictionaryValue> message, | 330 std::unique_ptr<base::DictionaryValue> message, |
| 337 std::unique_ptr<base::DictionaryValue> response) { | 331 std::unique_ptr<base::DictionaryValue> response) { |
| 338 DCHECK(thread_checker_.CalledOnValidThread()); | 332 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 339 | 333 |
| 340 daemon_controller_->GetUsageStatsConsent( | 334 daemon_controller_->GetUsageStatsConsent( |
| 341 base::Bind(&Me2MeNativeMessagingHost::SendUsageStatsConsentResponse, | 335 base::Bind(&Me2MeNativeMessagingHost::SendUsageStatsConsentResponse, |
| 342 weak_ptr_, base::Passed(&response))); | 336 weak_ptr_, base::Passed(&response))); |
| 343 } | 337 } |
| 344 | 338 |
| 345 void Me2MeNativeMessagingHost::ProcessStartDaemon( | 339 void Me2MeNativeMessagingHost::ProcessStartDaemon( |
| 346 std::unique_ptr<base::DictionaryValue> message, | 340 std::unique_ptr<base::DictionaryValue> message, |
| 347 std::unique_ptr<base::DictionaryValue> response) { | 341 std::unique_ptr<base::DictionaryValue> response) { |
| 348 DCHECK(thread_checker_.CalledOnValidThread()); | 342 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 349 | 343 |
| 350 if (needs_elevation_) { | 344 if (needs_elevation_) { |
| 351 if (!DelegateToElevatedHost(std::move(message))) | 345 if (!DelegateToElevatedHost(std::move(message))) |
| 352 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); | 346 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); |
| 353 return; | 347 return; |
| 354 } | 348 } |
| 355 | 349 |
| 356 bool consent; | 350 bool consent; |
| 357 if (!message->GetBoolean("consent", &consent)) { | 351 if (!message->GetBoolean("consent", &consent)) { |
| 358 LOG(ERROR) << "'consent' not found."; | 352 OnError("'consent' not found."); |
| 359 OnError(); | |
| 360 return; | 353 return; |
| 361 } | 354 } |
| 362 | 355 |
| 363 std::unique_ptr<base::DictionaryValue> config_dict = | 356 std::unique_ptr<base::DictionaryValue> config_dict = |
| 364 ConfigDictionaryFromMessage(std::move(message)); | 357 ConfigDictionaryFromMessage(std::move(message)); |
| 365 if (!config_dict) { | 358 if (!config_dict) { |
| 366 OnError(); | 359 OnError("'config' dictionary not found"); |
| 367 return; | 360 return; |
| 368 } | 361 } |
| 369 | 362 |
| 370 daemon_controller_->SetConfigAndStart( | 363 daemon_controller_->SetConfigAndStart( |
| 371 std::move(config_dict), consent, | 364 std::move(config_dict), consent, |
| 372 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, | 365 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, |
| 373 base::Passed(&response))); | 366 base::Passed(&response))); |
| 374 } | 367 } |
| 375 | 368 |
| 376 void Me2MeNativeMessagingHost::ProcessStopDaemon( | 369 void Me2MeNativeMessagingHost::ProcessStopDaemon( |
| 377 std::unique_ptr<base::DictionaryValue> message, | 370 std::unique_ptr<base::DictionaryValue> message, |
| 378 std::unique_ptr<base::DictionaryValue> response) { | 371 std::unique_ptr<base::DictionaryValue> response) { |
| 379 DCHECK(thread_checker_.CalledOnValidThread()); | 372 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 380 | 373 |
| 381 if (needs_elevation_) { | 374 if (needs_elevation_) { |
| 382 if (!DelegateToElevatedHost(std::move(message))) | 375 if (!DelegateToElevatedHost(std::move(message))) |
| 383 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); | 376 SendAsyncResult(std::move(response), DaemonController::RESULT_FAILED); |
| 384 return; | 377 return; |
| 385 } | 378 } |
| 386 | 379 |
| 387 daemon_controller_->Stop( | 380 daemon_controller_->Stop( |
| 388 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, | 381 base::Bind(&Me2MeNativeMessagingHost::SendAsyncResult, weak_ptr_, |
| 389 base::Passed(&response))); | 382 base::Passed(&response))); |
| 390 } | 383 } |
| 391 | 384 |
| 392 void Me2MeNativeMessagingHost::ProcessGetDaemonState( | 385 void Me2MeNativeMessagingHost::ProcessGetDaemonState( |
| 393 std::unique_ptr<base::DictionaryValue> message, | 386 std::unique_ptr<base::DictionaryValue> message, |
| 394 std::unique_ptr<base::DictionaryValue> response) { | 387 std::unique_ptr<base::DictionaryValue> response) { |
| 395 DCHECK(thread_checker_.CalledOnValidThread()); | 388 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 396 | 389 |
| 397 DaemonController::State state = daemon_controller_->GetState(); | 390 DaemonController::State state = daemon_controller_->GetState(); |
| 398 switch (state) { | 391 switch (state) { |
| 399 case DaemonController::STATE_NOT_IMPLEMENTED: | 392 case DaemonController::STATE_NOT_IMPLEMENTED: |
| 400 response->SetString("state", "NOT_IMPLEMENTED"); | 393 response->SetString("state", "NOT_IMPLEMENTED"); |
| 401 break; | 394 break; |
| 402 case DaemonController::STATE_STOPPED: | 395 case DaemonController::STATE_STOPPED: |
| 403 response->SetString("state", "STOPPED"); | 396 response->SetString("state", "STOPPED"); |
| 404 break; | 397 break; |
| 405 case DaemonController::STATE_STARTING: | 398 case DaemonController::STATE_STARTING: |
| 406 response->SetString("state", "STARTING"); | 399 response->SetString("state", "STARTING"); |
| 407 break; | 400 break; |
| 408 case DaemonController::STATE_STARTED: | 401 case DaemonController::STATE_STARTED: |
| 409 response->SetString("state", "STARTED"); | 402 response->SetString("state", "STARTED"); |
| 410 break; | 403 break; |
| 411 case DaemonController::STATE_STOPPING: | 404 case DaemonController::STATE_STOPPING: |
| 412 response->SetString("state", "STOPPING"); | 405 response->SetString("state", "STOPPING"); |
| 413 break; | 406 break; |
| 414 case DaemonController::STATE_UNKNOWN: | 407 case DaemonController::STATE_UNKNOWN: |
| 415 response->SetString("state", "UNKNOWN"); | 408 response->SetString("state", "UNKNOWN"); |
| 416 break; | 409 break; |
| 417 } | 410 } |
| 418 channel_->SendMessage(std::move(response)); | 411 SendMessageToClient(std::move(response)); |
| 419 } | 412 } |
| 420 | 413 |
| 421 void Me2MeNativeMessagingHost::ProcessGetHostClientId( | 414 void Me2MeNativeMessagingHost::ProcessGetHostClientId( |
| 422 std::unique_ptr<base::DictionaryValue> message, | 415 std::unique_ptr<base::DictionaryValue> message, |
| 423 std::unique_ptr<base::DictionaryValue> response) { | 416 std::unique_ptr<base::DictionaryValue> response) { |
| 424 DCHECK(thread_checker_.CalledOnValidThread()); | 417 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 425 | 418 |
| 426 response->SetString("clientId", google_apis::GetOAuth2ClientID( | 419 response->SetString("clientId", google_apis::GetOAuth2ClientID( |
| 427 google_apis::CLIENT_REMOTING_HOST)); | 420 google_apis::CLIENT_REMOTING_HOST)); |
| 428 channel_->SendMessage(std::move(response)); | 421 SendMessageToClient(std::move(response)); |
| 429 } | 422 } |
| 430 | 423 |
| 431 void Me2MeNativeMessagingHost::ProcessGetCredentialsFromAuthCode( | 424 void Me2MeNativeMessagingHost::ProcessGetCredentialsFromAuthCode( |
| 432 std::unique_ptr<base::DictionaryValue> message, | 425 std::unique_ptr<base::DictionaryValue> message, |
| 433 std::unique_ptr<base::DictionaryValue> response, | 426 std::unique_ptr<base::DictionaryValue> response, |
| 434 bool need_user_email) { | 427 bool need_user_email) { |
| 435 DCHECK(thread_checker_.CalledOnValidThread()); | 428 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 436 | 429 |
| 437 std::string auth_code; | 430 std::string auth_code; |
| 438 if (!message->GetString("authorizationCode", &auth_code)) { | 431 if (!message->GetString("authorizationCode", &auth_code)) { |
| 439 LOG(ERROR) << "'authorizationCode' string not found."; | 432 OnError("'authorizationCode' string not found."); |
| 440 OnError(); | |
| 441 return; | 433 return; |
| 442 } | 434 } |
| 443 | 435 |
| 444 gaia::OAuthClientInfo oauth_client_info = { | 436 gaia::OAuthClientInfo oauth_client_info = { |
| 445 google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING_HOST), | 437 google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING_HOST), |
| 446 google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING_HOST), | 438 google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING_HOST), |
| 447 kServiceAccountRedirectUri | 439 kServiceAccountRedirectUri |
| 448 }; | 440 }; |
| 449 | 441 |
| 450 oauth_client_->GetCredentialsFromAuthCode( | 442 oauth_client_->GetCredentialsFromAuthCode( |
| 451 oauth_client_info, auth_code, need_user_email, base::Bind( | 443 oauth_client_info, auth_code, need_user_email, base::Bind( |
| 452 &Me2MeNativeMessagingHost::SendCredentialsResponse, weak_ptr_, | 444 &Me2MeNativeMessagingHost::SendCredentialsResponse, weak_ptr_, |
| 453 base::Passed(&response))); | 445 base::Passed(&response))); |
| 454 } | 446 } |
| 455 | 447 |
| 456 void Me2MeNativeMessagingHost::SendConfigResponse( | 448 void Me2MeNativeMessagingHost::SendConfigResponse( |
| 457 std::unique_ptr<base::DictionaryValue> response, | 449 std::unique_ptr<base::DictionaryValue> response, |
| 458 std::unique_ptr<base::DictionaryValue> config) { | 450 std::unique_ptr<base::DictionaryValue> config) { |
| 459 DCHECK(thread_checker_.CalledOnValidThread()); | 451 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 460 | 452 |
| 461 if (config) { | 453 if (config) { |
| 462 response->Set("config", config.release()); | 454 response->Set("config", config.release()); |
| 463 } else { | 455 } else { |
| 464 response->Set("config", base::Value::CreateNullValue()); | 456 response->Set("config", base::Value::CreateNullValue()); |
| 465 } | 457 } |
| 466 channel_->SendMessage(std::move(response)); | 458 SendMessageToClient(std::move(response)); |
| 467 } | 459 } |
| 468 | 460 |
| 469 void Me2MeNativeMessagingHost::SendPairedClientsResponse( | 461 void Me2MeNativeMessagingHost::SendPairedClientsResponse( |
| 470 std::unique_ptr<base::DictionaryValue> response, | 462 std::unique_ptr<base::DictionaryValue> response, |
| 471 std::unique_ptr<base::ListValue> pairings) { | 463 std::unique_ptr<base::ListValue> pairings) { |
| 472 DCHECK(thread_checker_.CalledOnValidThread()); | 464 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 473 | 465 |
| 474 response->Set("pairedClients", pairings.release()); | 466 response->Set("pairedClients", pairings.release()); |
| 475 channel_->SendMessage(std::move(response)); | 467 SendMessageToClient(std::move(response)); |
| 476 } | 468 } |
| 477 | 469 |
| 478 void Me2MeNativeMessagingHost::SendUsageStatsConsentResponse( | 470 void Me2MeNativeMessagingHost::SendUsageStatsConsentResponse( |
| 479 std::unique_ptr<base::DictionaryValue> response, | 471 std::unique_ptr<base::DictionaryValue> response, |
| 480 const DaemonController::UsageStatsConsent& consent) { | 472 const DaemonController::UsageStatsConsent& consent) { |
| 481 DCHECK(thread_checker_.CalledOnValidThread()); | 473 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 482 | 474 |
| 483 response->SetBoolean("supported", consent.supported); | 475 response->SetBoolean("supported", consent.supported); |
| 484 response->SetBoolean("allowed", consent.allowed); | 476 response->SetBoolean("allowed", consent.allowed); |
| 485 response->SetBoolean("setByPolicy", consent.set_by_policy); | 477 response->SetBoolean("setByPolicy", consent.set_by_policy); |
| 486 channel_->SendMessage(std::move(response)); | 478 SendMessageToClient(std::move(response)); |
| 487 } | 479 } |
| 488 | 480 |
| 489 void Me2MeNativeMessagingHost::SendAsyncResult( | 481 void Me2MeNativeMessagingHost::SendAsyncResult( |
| 490 std::unique_ptr<base::DictionaryValue> response, | 482 std::unique_ptr<base::DictionaryValue> response, |
| 491 DaemonController::AsyncResult result) { | 483 DaemonController::AsyncResult result) { |
| 492 DCHECK(thread_checker_.CalledOnValidThread()); | 484 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 493 | 485 |
| 494 switch (result) { | 486 switch (result) { |
| 495 case DaemonController::RESULT_OK: | 487 case DaemonController::RESULT_OK: |
| 496 response->SetString("result", "OK"); | 488 response->SetString("result", "OK"); |
| 497 break; | 489 break; |
| 498 case DaemonController::RESULT_FAILED: | 490 case DaemonController::RESULT_FAILED: |
| 499 response->SetString("result", "FAILED"); | 491 response->SetString("result", "FAILED"); |
| 500 break; | 492 break; |
| 501 case DaemonController::RESULT_CANCELLED: | 493 case DaemonController::RESULT_CANCELLED: |
| 502 response->SetString("result", "CANCELLED"); | 494 response->SetString("result", "CANCELLED"); |
| 503 break; | 495 break; |
| 504 } | 496 } |
| 505 channel_->SendMessage(std::move(response)); | 497 SendMessageToClient(std::move(response)); |
| 506 } | 498 } |
| 507 | 499 |
| 508 void Me2MeNativeMessagingHost::SendBooleanResult( | 500 void Me2MeNativeMessagingHost::SendBooleanResult( |
| 509 std::unique_ptr<base::DictionaryValue> response, | 501 std::unique_ptr<base::DictionaryValue> response, |
| 510 bool result) { | 502 bool result) { |
| 511 DCHECK(thread_checker_.CalledOnValidThread()); | 503 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 512 | 504 |
| 513 response->SetBoolean("result", result); | 505 response->SetBoolean("result", result); |
| 514 channel_->SendMessage(std::move(response)); | 506 SendMessageToClient(std::move(response)); |
| 515 } | 507 } |
| 516 | 508 |
| 517 void Me2MeNativeMessagingHost::SendCredentialsResponse( | 509 void Me2MeNativeMessagingHost::SendCredentialsResponse( |
| 518 std::unique_ptr<base::DictionaryValue> response, | 510 std::unique_ptr<base::DictionaryValue> response, |
| 519 const std::string& user_email, | 511 const std::string& user_email, |
| 520 const std::string& refresh_token) { | 512 const std::string& refresh_token) { |
| 521 DCHECK(thread_checker_.CalledOnValidThread()); | 513 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 522 | 514 |
| 523 if (!user_email.empty()) { | 515 if (!user_email.empty()) { |
| 524 response->SetString("userEmail", user_email); | 516 response->SetString("userEmail", user_email); |
| 525 } | 517 } |
| 526 response->SetString("refreshToken", refresh_token); | 518 response->SetString("refreshToken", refresh_token); |
| 527 channel_->SendMessage(std::move(response)); | 519 SendMessageToClient(std::move(response)); |
| 528 } | 520 } |
| 529 | 521 |
| 530 void Me2MeNativeMessagingHost::OnError() { | 522 void Me2MeNativeMessagingHost::SendMessageToClient( |
| 531 // Trigger a host shutdown by sending a nullptr message. | 523 std::unique_ptr<base::Value> message) const { |
| 532 channel_->SendMessage(nullptr); | 524 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 525 std::string message_json; | |
| 526 base::JSONWriter::Write(*message, &message_json); | |
| 527 client_->PostMessageFromNativeHost(message_json); | |
| 533 } | 528 } |
| 534 | 529 |
| 535 void Me2MeNativeMessagingHost::Stop() { | 530 void Me2MeNativeMessagingHost::OnError(const std::string& error_message) { |
| 536 DCHECK(thread_checker_.CalledOnValidThread()); | 531 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 537 | 532 |
| 538 if (!quit_closure_.is_null()) | 533 if (!error_message.empty()) { |
| 539 base::ResetAndReturn(&quit_closure_).Run(); | 534 LOG(ERROR) << error_message; |
| 535 } | |
| 536 | |
| 537 // Trigger a host shutdown by sending an empty message. | |
| 538 client_->CloseChannel(std::string()); | |
| 540 } | 539 } |
| 541 | 540 |
| 542 #if defined(OS_WIN) | 541 #if defined(OS_WIN) |
| 543 Me2MeNativeMessagingHost::ElevatedChannelEventHandler:: | 542 Me2MeNativeMessagingHost::ElevatedChannelEventHandler:: |
| 544 ElevatedChannelEventHandler(Me2MeNativeMessagingHost* host) | 543 ElevatedChannelEventHandler(extensions::NativeMessageHost::Client* client) |
| 545 : parent_(host) { | 544 : client_(client) {} |
| 546 } | |
| 547 | 545 |
| 548 void Me2MeNativeMessagingHost::ElevatedChannelEventHandler::OnMessage( | 546 void Me2MeNativeMessagingHost::ElevatedChannelEventHandler::OnMessage( |
| 549 std::unique_ptr<base::Value> message) { | 547 std::unique_ptr<base::Value> message) { |
| 550 DCHECK(parent_->thread_checker_.CalledOnValidThread()); | 548 DCHECK(thread_checker_.CalledOnValidThread()); |
| 551 | 549 |
| 552 // Simply pass along the response from the elevated host to the client. | 550 // Simply pass along the response from the elevated host to the client. |
| 553 parent_->channel_->SendMessage(std::move(message)); | 551 std::string message_json; |
| 552 base::JSONWriter::Write(*message, &message_json); | |
| 553 client_->PostMessageFromNativeHost(message_json); | |
| 554 } | 554 } |
| 555 | 555 |
| 556 void Me2MeNativeMessagingHost::ElevatedChannelEventHandler::OnDisconnect() { | 556 void Me2MeNativeMessagingHost::ElevatedChannelEventHandler::OnDisconnect() { |
| 557 parent_->OnDisconnect(); | 557 DCHECK(thread_checker_.CalledOnValidThread()); |
| 558 client_->CloseChannel(std::string()); | |
| 558 } | 559 } |
| 559 | 560 |
| 560 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( | 561 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( |
| 561 std::unique_ptr<base::DictionaryValue> message) { | 562 std::unique_ptr<base::DictionaryValue> message) { |
| 562 DCHECK(thread_checker_.CalledOnValidThread()); | 563 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 563 | 564 |
| 564 EnsureElevatedHostCreated(); | 565 EnsureElevatedHostCreated(); |
| 565 | 566 |
| 566 // elevated_channel_ will be null if user rejects the UAC request. | 567 // elevated_channel_ will be null if user rejects the UAC request. |
| 567 if (elevated_channel_) | 568 if (elevated_channel_) |
| 568 elevated_channel_->SendMessage(std::move(message)); | 569 elevated_channel_->SendMessage(std::move(message)); |
| 569 | 570 |
| 570 return elevated_channel_ != nullptr; | 571 return elevated_channel_ != nullptr; |
| 571 } | 572 } |
| 572 | 573 |
| 573 void Me2MeNativeMessagingHost::EnsureElevatedHostCreated() { | 574 void Me2MeNativeMessagingHost::EnsureElevatedHostCreated() { |
| 574 DCHECK(thread_checker_.CalledOnValidThread()); | 575 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 575 DCHECK(needs_elevation_); | 576 DCHECK(needs_elevation_); |
| 576 | 577 |
| 577 if (elevated_channel_) | 578 if (elevated_channel_) |
| 578 return; | 579 return; |
| 579 | 580 |
| 580 base::win::ScopedHandle read_handle; | 581 base::win::ScopedHandle read_handle; |
| 581 base::win::ScopedHandle write_handle; | 582 base::win::ScopedHandle write_handle; |
| 582 // Get the name of the binary to launch. | 583 // Get the name of the binary to launch. |
| 583 base::FilePath binary = base::CommandLine::ForCurrentProcess()->GetProgram(); | 584 base::FilePath binary = base::CommandLine::ForCurrentProcess()->GetProgram(); |
| 584 ProcessLaunchResult result = LaunchNativeMessagingHostProcess( | 585 ProcessLaunchResult result = LaunchNativeMessagingHostProcess( |
| 585 binary, parent_window_handle_, | 586 binary, parent_window_handle_, |
| 586 /*elevate_process=*/true, &read_handle, &write_handle); | 587 /*elevate_process=*/true, &read_handle, &write_handle); |
| 587 if (result != PROCESS_LAUNCH_RESULT_SUCCESS) { | 588 if (result != PROCESS_LAUNCH_RESULT_SUCCESS) { |
| 588 if (result != PROCESS_LAUNCH_RESULT_CANCELLED) { | 589 if (result != PROCESS_LAUNCH_RESULT_CANCELLED) { |
| 589 OnError(); | 590 OnError(std::string()); |
| 590 } | 591 } |
| 591 return; | 592 return; |
| 592 } | 593 } |
| 593 | 594 |
| 594 // Set up the native messaging channel to talk to the elevated host. | 595 // 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. | 596 // Note that input for the elevated channel is output for the elevated host. |
| 596 elevated_channel_.reset(new PipeMessagingChannel( | 597 elevated_channel_.reset(new PipeMessagingChannel( |
| 597 base::File(read_handle.Take()), base::File(write_handle.Take()))); | 598 base::File(read_handle.Take()), base::File(write_handle.Take()))); |
| 598 | 599 |
| 599 elevated_channel_event_handler_.reset( | 600 elevated_channel_event_handler_.reset( |
| 600 new Me2MeNativeMessagingHost::ElevatedChannelEventHandler(this)); | 601 new Me2MeNativeMessagingHost::ElevatedChannelEventHandler(client_)); |
| 601 elevated_channel_->Start(elevated_channel_event_handler_.get()); | 602 elevated_channel_->Start(elevated_channel_event_handler_.get()); |
| 602 | 603 |
| 603 elevated_host_timer_.Start( | 604 elevated_host_timer_.Start( |
| 604 FROM_HERE, base::TimeDelta::FromSeconds(kElevatedHostTimeoutSeconds), | 605 FROM_HERE, base::TimeDelta::FromSeconds(kElevatedHostTimeoutSeconds), |
| 605 this, &Me2MeNativeMessagingHost::DisconnectElevatedHost); | 606 this, &Me2MeNativeMessagingHost::DisconnectElevatedHost); |
| 606 } | 607 } |
| 607 | 608 |
| 608 void Me2MeNativeMessagingHost::DisconnectElevatedHost() { | 609 void Me2MeNativeMessagingHost::DisconnectElevatedHost() { |
| 609 DCHECK(thread_checker_.CalledOnValidThread()); | 610 DCHECK(task_runner()->BelongsToCurrentThread()); |
| 610 | 611 |
| 611 // This will send an EOF to the elevated host, triggering its shutdown. | 612 // This will send an EOF to the elevated host, triggering its shutdown. |
| 612 elevated_channel_.reset(); | 613 elevated_channel_.reset(); |
| 613 } | 614 } |
| 614 | 615 |
| 615 #else // defined(OS_WIN) | 616 #else // defined(OS_WIN) |
| 616 | 617 |
| 617 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( | 618 bool Me2MeNativeMessagingHost::DelegateToElevatedHost( |
| 618 std::unique_ptr<base::DictionaryValue> message) { | 619 std::unique_ptr<base::DictionaryValue> message) { |
| 619 NOTREACHED(); | 620 NOTREACHED(); |
| 620 return false; | 621 return false; |
| 621 } | 622 } |
| 622 | 623 |
| 623 #endif // !defined(OS_WIN) | 624 #endif // !defined(OS_WIN) |
| 624 | 625 |
| 625 } // namespace remoting | 626 } // namespace remoting |
| OLD | NEW |