1 // Copyright 2014 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 #ifndef CHROME_BROWSER_SSL_CHROME_SSL_HOST_STATE_DELEGATE_H_ 6 #define CHROME_BROWSER_SSL_CHROME_SSL_HOST_STATE_DELEGATE_H_ 7 8 #include "base/gtest_prod_util.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/time/time.h" 11 #include "content/public/browser/ssl_host_state_delegate.h" 12 13 class Profile; 14 15 namespace base { 16 class Clock; 17 class DictionaryValue; 18 } // namespace base 19 20 // Tracks whether the user has allowed a certificate error exception for a 21 // specific site, SSL fingerprint, and error. Based on command-line flags and 22 // experimental group, remembers this decision either until end-of-session or 23 // for a particular length of time. 24 class ChromeSSLHostStateDelegate : public content::SSLHostStateDelegate { 25 public: 26 explicit ChromeSSLHostStateDelegate(Profile* profile); 27 virtual ~ChromeSSLHostStateDelegate(); 28 29 // SSLHostStateDelegate: 30 virtual void AllowCert(const std::string& host, 31 const net::X509Certificate& cert, 32 net::CertStatus error) OVERRIDE; 33 virtual void Clear() OVERRIDE; 34 virtual CertJudgment QueryPolicy(const std::string& host, 35 const net::X509Certificate& cert, 36 net::CertStatus error, 37 bool* expired_previous_decision) OVERRIDE; 38 virtual void HostRanInsecureContent(const std::string& host, 39 int pid) OVERRIDE; 40 virtual bool DidHostRunInsecureContent(const std::string& host, 41 int pid) const OVERRIDE; 42 43 // Revokes all SSL certificate error allow exceptions made by the user for 44 // |host| in the given Profile. 45 virtual void RevokeUserAllowExceptions(const std::string& host); 46 47 // RevokeUserAllowExceptionsHard is the same as RevokeUserAllowExceptions but 48 // additionally may close idle connections in the process. This should be used 49 // *only* for rare events, such as a user controlled button, as it may be very 50 // disruptive to the networking stack. 51 virtual void RevokeUserAllowExceptionsHard(const std::string& host); 52 53 // Returns whether the user has allowed a certificate error exception for 54 // |host|. This does not mean that *all* certificate errors are allowed, just 55 // that there exists an exception. To see if a particular certificate and 56 // error combination exception is allowed, use QueryPolicy(). 57 virtual bool HasAllowException(const std::string& host) const; 58 59 protected: 60 // SetClock takes ownership of the passed in clock. 61 void SetClock(scoped_ptr<base::Clock> clock); 62 63 private: 64 FRIEND_TEST_ALL_PREFIXES(ForgetInstantlySSLHostStateDelegateTest, 65 MakeAndForgetException); 66 FRIEND_TEST_ALL_PREFIXES(RememberSSLHostStateDelegateTest, AfterRestart); 67 FRIEND_TEST_ALL_PREFIXES(RememberSSLHostStateDelegateTest, 68 QueryPolicyExpired); 69 70 // Used to specify whether new content setting entries should be created if 71 // they don't already exist when querying the user's settings. 72 enum CreateDictionaryEntriesDisposition { 73 CREATE_DICTIONARY_ENTRIES, 74 DO_NOT_CREATE_DICTIONARY_ENTRIES 75 }; 76 77 // Specifies whether user SSL error decisions should be forgetten at the end 78 // of this current session (the old style of remembering decisions), or 79 // whether they should be remembered across session restarts for a specified 80 // length of time, deteremined by 81 // |default_ssl_cert_decision_expiration_delta_|. 82 enum RememberSSLExceptionDecisionsDisposition { 83 FORGET_SSL_EXCEPTION_DECISIONS_AT_SESSION_END, 84 REMEMBER_SSL_EXCEPTION_DECISIONS_FOR_DELTA 85 }; 86 87 // Returns a dictionary of certificate fingerprints and errors that have been 88 // allowed as exceptions by the user. 89 // 90 // |dict| specifies the user's full exceptions dictionary for a specific site 91 // in their content settings. Must be retrieved directly from a website 92 // setting in the the profile's HostContentSettingsMap. 93 // 94 // If |create_entries| specifies CreateDictionaryEntries, then 95 // GetValidCertDecisionsDict will create a new set of entries within the 96 // dictionary if they do not already exist. Otherwise will fail and return if 97 // NULL if they do not exist. 98 // 99 // |expired_previous_decision| is set to true if there had been a previous 100 // decision made by the user but it has expired. Otherwise it is set to false. 101 base::DictionaryValue* GetValidCertDecisionsDict( 102 base::DictionaryValue* dict, 103 CreateDictionaryEntriesDisposition create_entries, 104 bool* expired_previous_decision); 105 106 scoped_ptr<base::Clock> clock_; 107 RememberSSLExceptionDecisionsDisposition should_remember_ssl_decisions_; 108 base::TimeDelta default_ssl_cert_decision_expiration_delta_; 109 Profile* profile_; 110 111 // A BrokenHostEntry is a pair of (host, process_id) that indicates the host 112 // contains insecure content in that renderer process. 113 typedef std::pair<std::string, int> BrokenHostEntry; 114 115 // Hosts which have been contaminated with insecure content in the 116 // specified process. Note that insecure content can travel between 117 // same-origin frames in one processs but cannot jump between processes. 118 std::set<BrokenHostEntry> ran_insecure_content_hosts_; 119 120 // This is a GUID to mark this unique session. Whenever a certificate decision 121 // expiration is set, the GUID is saved as well so Chrome can tell if it was 122 // last set during the current session. This is used by the 123 // FORGET_SSL_EXCEPTION_DECISIONS_AT_SESSION_END experimental group to 124 // determine if the expired_previous_decision bit should be set on queries. 125 // 126 // Why not just iterate over the set of current extensions and mark them all 127 // as expired when the session starts, rather than storing a GUID for the 128 // current session? Glad you asked! Unfortunately, content settings does not 129 // currently support iterating over all current *compound* content setting 130 // values (iteration only works for simple content settings). While this could 131 // be added, it would be a fair amount of work for what amounts to a temporary 132 // measurement problem, so it's not worth the complexity. 133 // 134 // TODO(jww): This is only used by the default and disable groups of the 135 // certificate memory decisions experiment to tell if a decision has expired 136 // since the last session. Since this is only used for UMA purposes, this 137 // should be removed after the experiment has finished, and a call to Clear() 138 // should be added to the constructor and destructor for members of the 139 // FORGET_SSL_EXCEPTION_DECISIONS_AT_SESSION_END groups. See 140 // https://crbug.com/418631 for more details. 141 const std::string current_expiration_guid_; 142 143 DISALLOW_COPY_AND_ASSIGN(ChromeSSLHostStateDelegate); 144 }; 145 146 #endif // CHROME_BROWSER_SSL_CHROME_SSL_HOST_STATE_DELEGATE_H_ 147