• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "base/message_loop.h"
6 #include "base/threading/thread.h"
7 #include "chrome/browser/browser_process.h"
8 #include "chrome/browser/io_thread.h"
9 #include "chrome/browser/net/ssl_config_service_manager.h"
10 #include "chrome/browser/prefs/pref_member.h"
11 #include "chrome/browser/prefs/pref_service.h"
12 #include "chrome/common/pref_names.h"
13 #include "content/common/notification_details.h"
14 #include "content/common/notification_source.h"
15 #include "content/common/notification_type.h"
16 #include "net/base/ssl_config_service.h"
17 
18 ////////////////////////////////////////////////////////////////////////////////
19 //  SSLConfigServicePref
20 
21 // An SSLConfigService which stores a cached version of the current SSLConfig
22 // prefs, which are updated by SSLConfigServiceManagerPref when the prefs
23 // change.
24 class SSLConfigServicePref : public net::SSLConfigService {
25  public:
SSLConfigServicePref()26   SSLConfigServicePref() {}
~SSLConfigServicePref()27   virtual ~SSLConfigServicePref() {}
28 
29   // Store SSL config settings in |config|. Must only be called from IO thread.
30   virtual void GetSSLConfig(net::SSLConfig* config);
31 
32  private:
33   // Allow the pref watcher to update our internal state.
34   friend class SSLConfigServiceManagerPref;
35 
36   // This method is posted to the IO thread from the browser thread to carry the
37   // new config information.
38   void SetNewSSLConfig(const net::SSLConfig& new_config);
39 
40   // Cached value of prefs, should only be accessed from IO thread.
41   net::SSLConfig cached_config_;
42 
43   DISALLOW_COPY_AND_ASSIGN(SSLConfigServicePref);
44 };
45 
GetSSLConfig(net::SSLConfig * config)46 void SSLConfigServicePref::GetSSLConfig(net::SSLConfig* config) {
47   *config = cached_config_;
48 }
49 
SetNewSSLConfig(const net::SSLConfig & new_config)50 void SSLConfigServicePref::SetNewSSLConfig(
51     const net::SSLConfig& new_config) {
52   net::SSLConfig orig_config = cached_config_;
53   cached_config_ = new_config;
54   ProcessConfigUpdate(orig_config, new_config);
55 }
56 
57 ////////////////////////////////////////////////////////////////////////////////
58 //  SSLConfigServiceManagerPref
59 
60 // The manager for holding and updating an SSLConfigServicePref instance.
61 class SSLConfigServiceManagerPref
62     : public SSLConfigServiceManager,
63       public NotificationObserver {
64  public:
65   SSLConfigServiceManagerPref(PrefService* user_prefs,
66                               PrefService* local_state);
~SSLConfigServiceManagerPref()67   virtual ~SSLConfigServiceManagerPref() {}
68 
69   virtual net::SSLConfigService* Get();
70 
71  private:
72   // Register user_prefs and local_state SSL preferences.
73   static void RegisterPrefs(PrefService* prefs);
74 
75   // Copy pref values to local_state from user_prefs if local_state doesn't have
76   // the pref value and user_prefs has the pref value. Remove them from
77   // user_prefs.
78   static void MigrateUserPrefs(PrefService* local_state,
79                                PrefService* user_prefs);
80 
81   // Callback for preference changes.  This will post the changes to the IO
82   // thread with SetNewSSLConfig.
83   virtual void Observe(NotificationType type,
84                        const NotificationSource& source,
85                        const NotificationDetails& details);
86 
87   // Store SSL config settings in |config|, directly from the preferences. Must
88   // only be called from UI thread.
89   void GetSSLConfigFromPrefs(net::SSLConfig* config);
90 
91   // The prefs (should only be accessed from UI thread)
92   BooleanPrefMember rev_checking_enabled_;
93   BooleanPrefMember ssl3_enabled_;
94   BooleanPrefMember tls1_enabled_;
95 
96   scoped_refptr<SSLConfigServicePref> ssl_config_service_;
97 
98   DISALLOW_COPY_AND_ASSIGN(SSLConfigServiceManagerPref);
99 };
100 
SSLConfigServiceManagerPref(PrefService * user_prefs,PrefService * local_state)101 SSLConfigServiceManagerPref::SSLConfigServiceManagerPref(
102     PrefService* user_prefs, PrefService* local_state)
103     : ssl_config_service_(new SSLConfigServicePref()) {
104   DCHECK(user_prefs);
105   DCHECK(local_state);
106 
107   RegisterPrefs(user_prefs);
108   RegisterPrefs(local_state);
109 
110   // TODO(rtenneti): remove migration code after 6 months.
111   MigrateUserPrefs(local_state, user_prefs);
112 
113   rev_checking_enabled_.Init(prefs::kCertRevocationCheckingEnabled,
114                              local_state, this);
115   ssl3_enabled_.Init(prefs::kSSL3Enabled, local_state, this);
116   tls1_enabled_.Init(prefs::kTLS1Enabled, local_state, this);
117 
118   // Initialize from UI thread.  This is okay as there shouldn't be anything on
119   // the IO thread trying to access it yet.
120   GetSSLConfigFromPrefs(&ssl_config_service_->cached_config_);
121 }
122 
123 // static
RegisterPrefs(PrefService * prefs)124 void SSLConfigServiceManagerPref::RegisterPrefs(PrefService* prefs) {
125   net::SSLConfig default_config;
126   if (!prefs->FindPreference(prefs::kCertRevocationCheckingEnabled)) {
127     prefs->RegisterBooleanPref(prefs::kCertRevocationCheckingEnabled,
128                                default_config.rev_checking_enabled);
129   }
130   if (!prefs->FindPreference(prefs::kSSL3Enabled)) {
131     prefs->RegisterBooleanPref(prefs::kSSL3Enabled,
132                                default_config.ssl3_enabled);
133   }
134   if (!prefs->FindPreference(prefs::kTLS1Enabled)) {
135     prefs->RegisterBooleanPref(prefs::kTLS1Enabled,
136                                default_config.tls1_enabled);
137   }
138 }
139 
140 // static
MigrateUserPrefs(PrefService * local_state,PrefService * user_prefs)141 void SSLConfigServiceManagerPref::MigrateUserPrefs(PrefService* local_state,
142                                                    PrefService* user_prefs) {
143   if (user_prefs->HasPrefPath(prefs::kCertRevocationCheckingEnabled)) {
144     if (!local_state->HasPrefPath(prefs::kCertRevocationCheckingEnabled)) {
145       // Migrate the kCertRevocationCheckingEnabled preference.
146       local_state->SetBoolean(prefs::kCertRevocationCheckingEnabled,
147           user_prefs->GetBoolean(prefs::kCertRevocationCheckingEnabled));
148     }
149     user_prefs->ClearPref(prefs::kCertRevocationCheckingEnabled);
150   }
151   if (user_prefs->HasPrefPath(prefs::kSSL3Enabled)) {
152     if (!local_state->HasPrefPath(prefs::kSSL3Enabled)) {
153       // Migrate the kSSL3Enabled preference.
154       local_state->SetBoolean(prefs::kSSL3Enabled,
155           user_prefs->GetBoolean(prefs::kSSL3Enabled));
156     }
157     user_prefs->ClearPref(prefs::kSSL3Enabled);
158   }
159   if (user_prefs->HasPrefPath(prefs::kTLS1Enabled)) {
160     if (!local_state->HasPrefPath(prefs::kTLS1Enabled)) {
161       // Migrate the kTLS1Enabled preference.
162       local_state->SetBoolean(prefs::kTLS1Enabled,
163           user_prefs->GetBoolean(prefs::kTLS1Enabled));
164     }
165     user_prefs->ClearPref(prefs::kTLS1Enabled);
166   }
167 }
168 
Get()169 net::SSLConfigService* SSLConfigServiceManagerPref::Get() {
170   return ssl_config_service_;
171 }
172 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)173 void SSLConfigServiceManagerPref::Observe(NotificationType type,
174                                           const NotificationSource& source,
175                                           const NotificationDetails& details) {
176   base::Thread* io_thread = g_browser_process->io_thread();
177   if (io_thread) {
178     net::SSLConfig new_config;
179     GetSSLConfigFromPrefs(&new_config);
180 
181     // Post a task to |io_loop| with the new configuration, so it can
182     // update |cached_config_|.
183     io_thread->message_loop()->PostTask(
184         FROM_HERE,
185         NewRunnableMethod(
186             ssl_config_service_.get(),
187             &SSLConfigServicePref::SetNewSSLConfig,
188             new_config));
189   }
190 }
191 
GetSSLConfigFromPrefs(net::SSLConfig * config)192 void SSLConfigServiceManagerPref::GetSSLConfigFromPrefs(
193     net::SSLConfig* config) {
194   config->rev_checking_enabled = rev_checking_enabled_.GetValue();
195   config->ssl3_enabled = ssl3_enabled_.GetValue();
196   config->tls1_enabled = tls1_enabled_.GetValue();
197   SSLConfigServicePref::SetSSLConfigFlags(config);
198 }
199 
200 ////////////////////////////////////////////////////////////////////////////////
201 //  SSLConfigServiceManager
202 
203 // static
CreateDefaultManager(PrefService * user_prefs,PrefService * local_state)204 SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager(
205     PrefService* user_prefs,
206     PrefService* local_state) {
207   return new SSLConfigServiceManagerPref(user_prefs, local_state);
208 }
209