OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/elevated_controller_win.h" | 5 #include "remoting/host/elevated_controller_win.h" |
6 | 6 |
7 #include <sddl.h> | 7 #include <sddl.h> |
8 | 8 |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 // reasonable configuration we will ever need. 1MB is low enough to make | 37 // reasonable configuration we will ever need. 1MB is low enough to make |
38 // the probability of out of memory situation fairly low. OOM is still possible | 38 // the probability of out of memory situation fairly low. OOM is still possible |
39 // and we will crash if it occurs. | 39 // and we will crash if it occurs. |
40 const size_t kMaxConfigFileSize = 1024 * 1024; | 40 const size_t kMaxConfigFileSize = 1024 * 1024; |
41 | 41 |
42 // ReadConfig() filters the configuration file stripping all variables except of | 42 // ReadConfig() filters the configuration file stripping all variables except of |
43 // the following two. | 43 // the following two. |
44 const char kHostId[] = "host_id"; | 44 const char kHostId[] = "host_id"; |
45 const char kXmppLogin[] = "xmpp_login"; | 45 const char kXmppLogin[] = "xmpp_login"; |
46 | 46 |
| 47 // The configuration keys that cannot be specified in UpdateConfig(). |
| 48 const char* const kReadonlyKeys[] = { kHostId, kXmppLogin }; |
| 49 |
47 // Reads and parses the configuration file up to |kMaxConfigFileSize| in | 50 // Reads and parses the configuration file up to |kMaxConfigFileSize| in |
48 // size. | 51 // size. |
49 HRESULT ReadConfig(const FilePath& filename, | 52 HRESULT ReadConfig(const FilePath& filename, |
50 scoped_ptr<base::DictionaryValue>* config_out) { | 53 scoped_ptr<base::DictionaryValue>* config_out) { |
51 | 54 |
52 // Read raw data from the configuration file. | 55 // Read raw data from the configuration file. |
53 base::win::ScopedHandle file( | 56 base::win::ScopedHandle file( |
54 CreateFileW(filename.value().c_str(), | 57 CreateFileW(filename.value().c_str(), |
55 GENERIC_READ, | 58 GENERIC_READ, |
56 FILE_SHARE_READ | FILE_SHARE_WRITE, | 59 FILE_SHARE_READ | FILE_SHARE_WRITE, |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 LOG_GETLASTERROR(ERROR) | 323 LOG_GETLASTERROR(ERROR) |
321 << "Failed to stop the '" << kWindowsServiceName << "'service"; | 324 << "Failed to stop the '" << kWindowsServiceName << "'service"; |
322 return HRESULT_FROM_WIN32(error); | 325 return HRESULT_FROM_WIN32(error); |
323 } | 326 } |
324 } | 327 } |
325 | 328 |
326 return S_OK; | 329 return S_OK; |
327 } | 330 } |
328 | 331 |
329 STDMETHODIMP ElevatedControllerWin::UpdateConfig(BSTR config) { | 332 STDMETHODIMP ElevatedControllerWin::UpdateConfig(BSTR config) { |
330 return E_NOTIMPL; | 333 // Parse the config. |
| 334 std::string config_str = UTF16ToUTF8( |
| 335 string16(static_cast<char16*>(config), ::SysStringLen(config))); |
| 336 scoped_ptr<base::Value> config_value(base::JSONReader::Read(config_str)); |
| 337 if (!config_value.get()) { |
| 338 return E_FAIL; |
| 339 } |
| 340 base::DictionaryValue* config_dict = NULL; |
| 341 if (!config_value->GetAsDictionary(&config_dict)) { |
| 342 return E_FAIL; |
| 343 } |
| 344 // Check for bad keys. |
| 345 for (int i = 0; i < arraysize(kReadonlyKeys); ++i) { |
| 346 if (config_dict->HasKey(kReadonlyKeys[i])) { |
| 347 return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED); |
| 348 } |
| 349 } |
| 350 // Get the old config. |
| 351 FilePath config_dir = remoting::GetConfigDir(); |
| 352 scoped_ptr<base::DictionaryValue> config_old; |
| 353 HRESULT hr = ReadConfig(config_dir.Append(kConfigFileName), &config_old); |
| 354 if (FAILED(hr)) { |
| 355 return hr; |
| 356 } |
| 357 // Merge items from the given config into the old config. |
| 358 config_old->MergeDictionary(config_dict); |
| 359 // Write the updated config. |
| 360 std::string config_updated_str; |
| 361 base::JSONWriter::Write(config_old.get(), &config_updated_str); |
| 362 return WriteConfig(config_dir.Append(kConfigFileName), |
| 363 config_updated_str.c_str(), |
| 364 config_updated_str.size()); |
331 } | 365 } |
332 | 366 |
333 HRESULT ElevatedControllerWin::OpenService(ScopedScHandle* service_out) { | 367 HRESULT ElevatedControllerWin::OpenService(ScopedScHandle* service_out) { |
334 DWORD error; | 368 DWORD error; |
335 | 369 |
336 ScopedScHandle scmanager( | 370 ScopedScHandle scmanager( |
337 ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, | 371 ::OpenSCManagerW(NULL, SERVICES_ACTIVE_DATABASE, |
338 SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE)); | 372 SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE)); |
339 if (!scmanager.IsValid()) { | 373 if (!scmanager.IsValid()) { |
340 error = GetLastError(); | 374 error = GetLastError(); |
(...skipping 13 matching lines...) Expand all Loading... |
354 << "Failed to open to the '" << kWindowsServiceName << "' service"; | 388 << "Failed to open to the '" << kWindowsServiceName << "' service"; |
355 | 389 |
356 return HRESULT_FROM_WIN32(error); | 390 return HRESULT_FROM_WIN32(error); |
357 } | 391 } |
358 | 392 |
359 service_out->Set(service.Take()); | 393 service_out->Set(service.Take()); |
360 return S_OK; | 394 return S_OK; |
361 } | 395 } |
362 | 396 |
363 } // namespace remoting | 397 } // namespace remoting |
OLD | NEW |