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
3// found in the LICENSE file.
4
5#include "chrome/browser/prefs/command_line_pref_store.h"
6
7#include <string>
8#include <vector>
9
10#include "base/files/file_path.h"
11#include "base/logging.h"
12#include "base/strings/string_number_conversions.h"
13#include "base/strings/string_split.h"
14#include "base/values.h"
15#include "chrome/browser/prefs/proxy_config_dictionary.h"
16#include "chrome/common/chrome_switches.h"
17#include "chrome/common/pref_names.h"
18#include "ui/base/ui_base_switches.h"
19
20#if defined(OS_CHROMEOS)
21#include "chromeos/chromeos_switches.h"
22#endif
23
24const CommandLinePrefStore::StringSwitchToPreferenceMapEntry
25    CommandLinePrefStore::string_switch_map_[] = {
26      { switches::kLang, prefs::kApplicationLocale },
27      { switches::kAuthSchemes, prefs::kAuthSchemes },
28      { switches::kAuthServerWhitelist, prefs::kAuthServerWhitelist },
29      { switches::kAuthNegotiateDelegateWhitelist,
30          prefs::kAuthNegotiateDelegateWhitelist },
31      { switches::kGSSAPILibraryName, prefs::kGSSAPILibraryName },
32      { data_reduction_proxy::switches::kDataReductionProxy,
33          data_reduction_proxy::prefs::kDataReductionProxy },
34      { switches::kSSLVersionMin, prefs::kSSLVersionMin },
35      { switches::kSSLVersionMax, prefs::kSSLVersionMax },
36      { switches::kSSLVersionFallbackMin, prefs::kSSLVersionFallbackMin },
37};
38
39const CommandLinePrefStore::PathSwitchToPreferenceMapEntry
40    CommandLinePrefStore::path_switch_map_[] = {
41      { switches::kDiskCacheDir, prefs::kDiskCacheDir },
42};
43
44const CommandLinePrefStore::BooleanSwitchToPreferenceMapEntry
45    CommandLinePrefStore::boolean_switch_map_[] = {
46      { switches::kDisableAuthNegotiateCnameLookup,
47          prefs::kDisableAuthNegotiateCnameLookup, true },
48      { switches::kEnableAuthNegotiatePort, prefs::kEnableAuthNegotiatePort,
49          true },
50      { switches::kDisable3DAPIs, prefs::kDisable3DAPIs, true },
51      { switches::kEnableCloudPrintProxy, prefs::kCloudPrintProxyEnabled,
52          true },
53      { switches::kAllowOutdatedPlugins, prefs::kPluginsAllowOutdated, true },
54      { switches::kAlwaysAuthorizePlugins, prefs::kPluginsAlwaysAuthorize,
55          true },
56      { switches::kNoPings, prefs::kEnableHyperlinkAuditing, false },
57      { switches::kNoReferrers, prefs::kEnableReferrers, false },
58      { switches::kAllowRunningInsecureContent,
59        prefs::kWebKitAllowRunningInsecureContent, true },
60      { switches::kNoDisplayingInsecureContent,
61        prefs::kWebKitAllowDisplayingInsecureContent, false },
62      { switches::kAllowCrossOriginAuthPrompt,
63        prefs::kAllowCrossOriginAuthPrompt, true },
64      { switches::kDisablePrintPreview, prefs::kPrintPreviewDisabled, true },
65#if defined(OS_CHROMEOS)
66      { chromeos::switches::kEnableTouchpadThreeFingerClick,
67          prefs::kEnableTouchpadThreeFingerClick, true },
68#endif
69      { switches::kDisableAsyncDns, prefs::kBuiltInDnsClientEnabled, false },
70      { switches::kEnableAsyncDns, prefs::kBuiltInDnsClientEnabled, true },
71};
72
73const CommandLinePrefStore::IntegerSwitchToPreferenceMapEntry
74    CommandLinePrefStore::integer_switch_map_[] = {
75      { switches::kDiskCacheSize, prefs::kDiskCacheSize },
76      { switches::kMediaCacheSize, prefs::kMediaCacheSize },
77    };
78
79CommandLinePrefStore::CommandLinePrefStore(const CommandLine* command_line)
80    : command_line_(command_line) {
81  ApplySimpleSwitches();
82  ApplyProxyMode();
83  ValidateProxySwitches();
84  ApplySSLSwitches();
85  ApplyBackgroundModeSwitches();
86}
87
88CommandLinePrefStore::~CommandLinePrefStore() {}
89
90bool CommandLinePrefStore::ValidateProxySwitches() {
91  if (command_line_->HasSwitch(switches::kNoProxyServer) &&
92      (command_line_->HasSwitch(switches::kProxyAutoDetect) ||
93       command_line_->HasSwitch(switches::kProxyServer) ||
94       command_line_->HasSwitch(switches::kProxyPacUrl) ||
95       command_line_->HasSwitch(switches::kProxyBypassList))) {
96    LOG(WARNING) << "Additional command-line proxy switches specified when --"
97                 << switches::kNoProxyServer << " was also specified.";
98    return false;
99  }
100  return true;
101}
102
103void CommandLinePrefStore::ApplySimpleSwitches() {
104  // Look for each switch we know about and set its preference accordingly.
105  for (size_t i = 0; i < arraysize(string_switch_map_); ++i) {
106    if (command_line_->HasSwitch(string_switch_map_[i].switch_name)) {
107      SetValue(string_switch_map_[i].preference_path,
108               new base::StringValue(command_line_->GetSwitchValueASCII(
109                   string_switch_map_[i].switch_name)));
110    }
111  }
112
113  for (size_t i = 0; i < arraysize(path_switch_map_); ++i) {
114    if (command_line_->HasSwitch(path_switch_map_[i].switch_name)) {
115      SetValue(path_switch_map_[i].preference_path,
116               new base::StringValue(command_line_->GetSwitchValuePath(
117                   path_switch_map_[i].switch_name).value()));
118    }
119  }
120
121  for (size_t i = 0; i < arraysize(integer_switch_map_); ++i) {
122    if (command_line_->HasSwitch(integer_switch_map_[i].switch_name)) {
123      std::string str_value = command_line_->GetSwitchValueASCII(
124          integer_switch_map_[i].switch_name);
125      int int_value = 0;
126      if (!base::StringToInt(str_value, &int_value)) {
127        LOG(ERROR) << "The value " << str_value << " of "
128                   << integer_switch_map_[i].switch_name
129                   << " can not be converted to integer, ignoring!";
130        continue;
131      }
132      SetValue(integer_switch_map_[i].preference_path,
133               new base::FundamentalValue(int_value));
134    }
135  }
136
137  for (size_t i = 0; i < arraysize(boolean_switch_map_); ++i) {
138    if (command_line_->HasSwitch(boolean_switch_map_[i].switch_name)) {
139      SetValue(boolean_switch_map_[i].preference_path,
140               new base::FundamentalValue(boolean_switch_map_[i].set_value));
141    }
142  }
143}
144
145void CommandLinePrefStore::ApplyProxyMode() {
146  if (command_line_->HasSwitch(switches::kNoProxyServer)) {
147    SetValue(prefs::kProxy,
148             ProxyConfigDictionary::CreateDirect());
149  } else if (command_line_->HasSwitch(switches::kProxyPacUrl)) {
150    std::string pac_script_url =
151        command_line_->GetSwitchValueASCII(switches::kProxyPacUrl);
152    SetValue(prefs::kProxy,
153             ProxyConfigDictionary::CreatePacScript(pac_script_url, false));
154  } else if (command_line_->HasSwitch(switches::kProxyAutoDetect)) {
155    SetValue(prefs::kProxy,
156             ProxyConfigDictionary::CreateAutoDetect());
157  } else if (command_line_->HasSwitch(switches::kProxyServer)) {
158    std::string proxy_server =
159        command_line_->GetSwitchValueASCII(switches::kProxyServer);
160    std::string bypass_list =
161        command_line_->GetSwitchValueASCII(switches::kProxyBypassList);
162    SetValue(prefs::kProxy,
163             ProxyConfigDictionary::CreateFixedServers(proxy_server,
164                                                       bypass_list));
165  }
166}
167
168void CommandLinePrefStore::ApplySSLSwitches() {
169  if (command_line_->HasSwitch(switches::kCipherSuiteBlacklist)) {
170    std::string cipher_suites =
171        command_line_->GetSwitchValueASCII(switches::kCipherSuiteBlacklist);
172    std::vector<std::string> cipher_strings;
173    base::SplitString(cipher_suites, ',', &cipher_strings);
174    base::ListValue* list_value = new base::ListValue();
175    for (std::vector<std::string>::const_iterator it = cipher_strings.begin();
176         it != cipher_strings.end(); ++it) {
177      list_value->Append(new base::StringValue(*it));
178    }
179    SetValue(prefs::kCipherSuiteBlacklist, list_value);
180  }
181}
182
183void CommandLinePrefStore::ApplyBackgroundModeSwitches() {
184  if (command_line_->HasSwitch(switches::kDisableExtensions))
185    SetValue(prefs::kBackgroundModeEnabled, new base::FundamentalValue(false));
186}
187