Home | History | Annotate | Download | only in net
      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:
     26   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 
     46 void SSLConfigServicePref::GetSSLConfig(net::SSLConfig* config) {
     47   *config = cached_config_;
     48 }
     49 
     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);
     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 
    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
    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
    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 
    169 net::SSLConfigService* SSLConfigServiceManagerPref::Get() {
    170   return ssl_config_service_;
    171 }
    172 
    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 
    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
    204 SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager(
    205     PrefService* user_prefs,
    206     PrefService* local_state) {
    207   return new SSLConfigServiceManagerPref(user_prefs, local_state);
    208 }
    209