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. 24class 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 46void SSLConfigServicePref::GetSSLConfig(net::SSLConfig* config) { 47 *config = cached_config_; 48} 49 50void 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. 61class 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 101SSLConfigServiceManagerPref::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 124void 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 141void 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 169net::SSLConfigService* SSLConfigServiceManagerPref::Get() { 170 return ssl_config_service_; 171} 172 173void 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 192void 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 204SSLConfigServiceManager* SSLConfigServiceManager::CreateDefaultManager( 205 PrefService* user_prefs, 206 PrefService* local_state) { 207 return new SSLConfigServiceManagerPref(user_prefs, local_state); 208} 209