OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ssl/ssl_policy.h" | 5 #include "chrome/browser/ssl/ssl_policy.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "app/resource_bundle.h" | 8 #include "app/resource_bundle.h" |
9 #include "base/base_switches.h" | 9 #include "base/base_switches.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 case net::ERR_CERT_INVALID: | 76 case net::ERR_CERT_INVALID: |
77 OnCertErrorInternal(handler, SSLBlockingPage::ERROR_FATAL); | 77 OnCertErrorInternal(handler, SSLBlockingPage::ERROR_FATAL); |
78 break; | 78 break; |
79 default: | 79 default: |
80 NOTREACHED(); | 80 NOTREACHED(); |
81 handler->CancelRequest(); | 81 handler->CancelRequest(); |
82 break; | 82 break; |
83 } | 83 } |
84 } | 84 } |
85 | 85 |
| 86 void SSLPolicy::DidDisplayInsecureContent(NavigationEntry* entry) { |
| 87 if (!entry) |
| 88 return; |
| 89 |
| 90 // TODO(abarth): We don't actually need to break the whole origin here, |
| 91 // but we can handle that in a later patch. |
| 92 DidRunInsecureContent(entry, entry->url().spec()); |
| 93 } |
| 94 |
86 void SSLPolicy::DidRunInsecureContent(NavigationEntry* entry, | 95 void SSLPolicy::DidRunInsecureContent(NavigationEntry* entry, |
87 const std::string& security_origin) { | 96 const std::string& security_origin) { |
88 if (!entry) | 97 if (!entry) |
89 return; | 98 return; |
90 | 99 |
91 SiteInstance* site_instance = entry->site_instance(); | 100 SiteInstance* site_instance = entry->site_instance(); |
92 if (!site_instance) | 101 if (!site_instance) |
93 return; | 102 return; |
94 | 103 |
95 backend_->HostRanInsecureContent(GURL(security_origin).host(), | 104 backend_->MarkHostAsBroken(GURL(security_origin).host(), |
96 site_instance->GetProcess()->id()); | 105 site_instance->GetProcess()->id()); |
97 } | 106 } |
98 | 107 |
99 void SSLPolicy::OnRequestStarted(SSLRequestInfo* info) { | 108 void SSLPolicy::OnRequestStarted(SSLRequestInfo* info) { |
100 // TODO(abarth): This mechanism is wrong. What we should be doing is sending | 109 if (net::IsCertStatusError(info->ssl_cert_status())) |
101 // this information back through WebKit and out some FrameLoaderClient | 110 UpdateStateForUnsafeContent(info); |
102 // methods. | |
103 // | |
104 // The behavior for HTTPS resources with cert errors should be as follows: | |
105 // 1) If we don't know anything about this host (the one hosting the | |
106 // resource), the resource load just fails. | |
107 // 2) If the user has previously approved the same certificate error for | |
108 // this host in a full-page interstitial, then we'll proceed with the | |
109 // load. | |
110 // 3) If we proceed with the load, we should treat the resources as if they | |
111 // were loaded over HTTP, w.r.t. the display vs. run distinction above. | |
112 // | |
113 // However, right now we don't have the proper context to understand where | |
114 // these resources will be used. Consequently, we're conservative and treat | |
115 // them all like DidRunInsecureContent(). | |
116 | |
117 if (net::IsCertStatusError(info->ssl_cert_status())) { | |
118 backend_->HostRanInsecureContent(info->url().host(), info->child_id()); | |
119 | |
120 // TODO(abarth): We should eventually remove the main_frame_origin and | |
121 // frame_origin properties. First, not every resource load is associated | |
122 // with a frame, so they don't always make sense. Second, the | |
123 // main_frame_origin is computed from the first_party_for_cookies, which has | |
124 // been hacked to death to support third-party cookie blocking. | |
125 | |
126 if (info->resource_type() != ResourceType::MAIN_FRAME && | |
127 info->resource_type() != ResourceType::SUB_FRAME) { | |
128 // The frame's origin now contains mixed content and therefore is broken. | |
129 OriginRanInsecureContent(info->frame_origin(), info->child_id()); | |
130 } | |
131 | |
132 if (info->resource_type() != ResourceType::MAIN_FRAME) { | |
133 // The main frame now contains a frame with mixed content. Therefore, we | |
134 // mark the main frame's origin as broken too. | |
135 OriginRanInsecureContent(info->main_frame_origin(), info->child_id()); | |
136 } | |
137 } | |
138 } | 111 } |
139 | 112 |
140 void SSLPolicy::UpdateEntry(NavigationEntry* entry, TabContents* tab_contents) { | 113 void SSLPolicy::UpdateEntry(NavigationEntry* entry) { |
141 DCHECK(entry); | 114 DCHECK(entry); |
142 | 115 |
143 InitializeEntryIfNeeded(entry); | 116 InitializeEntryIfNeeded(entry); |
144 | 117 |
145 if (!entry->url().SchemeIsSecure()) | 118 if (!entry->url().SchemeIsSecure()) |
146 return; | 119 return; |
147 | 120 |
148 // An HTTPS response may not have a certificate for some reason. When that | 121 // An HTTPS response may not have a certificate for some reason. When that |
149 // happens, use the unauthenticated (HTTP) rather than the authentication | 122 // happens, use the unauthenticated (HTTP) rather than the authentication |
150 // broken security style so that we can detect this error condition. | 123 // broken security style so that we can detect this error condition. |
151 if (!entry->ssl().cert_id()) { | 124 if (!entry->ssl().cert_id()) { |
152 entry->ssl().set_security_style(SECURITY_STYLE_UNAUTHENTICATED); | 125 entry->ssl().set_security_style(SECURITY_STYLE_UNAUTHENTICATED); |
153 return; | 126 return; |
154 } | 127 } |
155 | 128 |
156 // If CERT_STATUS_UNABLE_TO_CHECK_REVOCATION is the only certificate error, | 129 // If CERT_STATUS_UNABLE_TO_CHECK_REVOCATION is the only certificate error, |
157 // don't lower the security style to SECURITY_STYLE_AUTHENTICATION_BROKEN. | 130 // don't lower the security style to SECURITY_STYLE_AUTHENTICATION_BROKEN. |
158 int cert_errors = entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS; | 131 int cert_errors = entry->ssl().cert_status() & net::CERT_STATUS_ALL_ERRORS; |
159 if (cert_errors) { | 132 if (cert_errors) { |
160 if (cert_errors != net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION) | 133 if (cert_errors != net::CERT_STATUS_UNABLE_TO_CHECK_REVOCATION) |
161 entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN); | 134 entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN); |
162 return; | 135 return; |
163 } | 136 } |
164 | 137 |
165 SiteInstance* site_instance = entry->site_instance(); | 138 SiteInstance* site_instance = entry->site_instance(); |
166 // Note that |site_instance| can be NULL here because NavigationEntries don't | 139 // Note that |site_instance| can be NULL here because NavigationEntries don't |
167 // necessarily have site instances. Without a process, the entry can't | 140 // necessarily have site instances. Without a process, the entry can't |
168 // possibly have mixed content. See bug http://crbug.com/12423. | 141 // possibly have mixed content. See bug http://crbug.com/12423. |
169 if (site_instance && | 142 if (site_instance && |
170 backend_->DidHostRunInsecureContent(entry->url().host(), | 143 backend_->DidMarkHostAsBroken(entry->url().host(), |
171 site_instance->GetProcess()->id())) { | 144 site_instance->GetProcess()->id())) |
172 entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN); | 145 entry->ssl().set_has_mixed_content(); |
173 entry->ssl().set_ran_mixed_content(); | |
174 return; | |
175 } | |
176 | |
177 if (tab_contents->displayed_insecure_content()) | |
178 entry->ssl().set_displayed_mixed_content(); | |
179 } | 146 } |
180 | 147 |
181 //////////////////////////////////////////////////////////////////////////////// | 148 //////////////////////////////////////////////////////////////////////////////// |
182 // SSLBlockingPage::Delegate methods | 149 // SSLBlockingPage::Delegate methods |
183 | 150 |
184 SSLErrorInfo SSLPolicy::GetSSLErrorInfo(SSLCertErrorHandler* handler) { | 151 SSLErrorInfo SSLPolicy::GetSSLErrorInfo(SSLCertErrorHandler* handler) { |
185 return SSLErrorInfo::CreateError( | 152 return SSLErrorInfo::CreateError( |
186 SSLErrorInfo::NetErrorToErrorType(handler->cert_error()), | 153 SSLErrorInfo::NetErrorToErrorType(handler->cert_error()), |
187 handler->ssl_info().cert, handler->request_url()); | 154 handler->ssl_info().cert, handler->request_url()); |
188 } | 155 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 } | 200 } |
234 | 201 |
235 void SSLPolicy::InitializeEntryIfNeeded(NavigationEntry* entry) { | 202 void SSLPolicy::InitializeEntryIfNeeded(NavigationEntry* entry) { |
236 if (entry->ssl().security_style() != SECURITY_STYLE_UNKNOWN) | 203 if (entry->ssl().security_style() != SECURITY_STYLE_UNKNOWN) |
237 return; | 204 return; |
238 | 205 |
239 entry->ssl().set_security_style(entry->url().SchemeIsSecure() ? | 206 entry->ssl().set_security_style(entry->url().SchemeIsSecure() ? |
240 SECURITY_STYLE_AUTHENTICATED : SECURITY_STYLE_UNAUTHENTICATED); | 207 SECURITY_STYLE_AUTHENTICATED : SECURITY_STYLE_UNAUTHENTICATED); |
241 } | 208 } |
242 | 209 |
243 void SSLPolicy::OriginRanInsecureContent(const std::string& origin, int pid) { | 210 void SSLPolicy::MarkOriginAsBroken(const std::string& origin, int pid) { |
244 GURL parsed_origin(origin); | 211 GURL parsed_origin(origin); |
245 if (parsed_origin.SchemeIsSecure()) | 212 if (!parsed_origin.SchemeIsSecure()) |
246 backend_->HostRanInsecureContent(parsed_origin.host(), pid); | 213 return; |
| 214 |
| 215 backend_->MarkHostAsBroken(parsed_origin.host(), pid); |
247 } | 216 } |
| 217 |
| 218 void SSLPolicy::UpdateStateForMixedContent(SSLRequestInfo* info) { |
| 219 // TODO(abarth): This function isn't right because we need to remove |
| 220 // info->main_frame_origin(). |
| 221 |
| 222 if (info->resource_type() != ResourceType::MAIN_FRAME && |
| 223 info->resource_type() != ResourceType::SUB_FRAME) { |
| 224 // The frame's origin now contains mixed content and therefore is broken. |
| 225 MarkOriginAsBroken(info->frame_origin(), info->child_id()); |
| 226 } |
| 227 |
| 228 if (info->resource_type() != ResourceType::MAIN_FRAME) { |
| 229 // The main frame now contains a frame with mixed content. Therefore, we |
| 230 // mark the main frame's origin as broken too. |
| 231 MarkOriginAsBroken(info->main_frame_origin(), info->child_id()); |
| 232 } |
| 233 } |
| 234 |
| 235 void SSLPolicy::UpdateStateForUnsafeContent(SSLRequestInfo* info) { |
| 236 // This request as a broken cert, which means its host is broken. |
| 237 backend_->MarkHostAsBroken(info->url().host(), info->child_id()); |
| 238 UpdateStateForMixedContent(info); |
| 239 } |
OLD | NEW |