Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 #import "ios/web/web_state/ui/crw_wk_web_view_web_controller.h" | 5 #import "ios/web/web_state/ui/crw_wk_web_view_web_controller.h" |
| 6 | 6 |
| 7 #import <WebKit/WebKit.h> | 7 #import <WebKit/WebKit.h> |
| 8 | 8 |
| 9 #include "base/ios/ios_util.h" | 9 #include "base/ios/ios_util.h" |
| 10 #include "base/ios/weak_nsobject.h" | 10 #include "base/ios/weak_nsobject.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 75 userInfo:userInfo]; | 75 userInfo:userInfo]; |
| 76 } | 76 } |
| 77 WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { | 77 WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) { |
| 78 DCHECK(error); | 78 DCHECK(error); |
| 79 return static_cast<WKWebViewErrorSource>( | 79 return static_cast<WKWebViewErrorSource>( |
| 80 [error.userInfo[kWKWebViewErrorSourceKey] integerValue]); | 80 [error.userInfo[kWKWebViewErrorSourceKey] integerValue]); |
| 81 } | 81 } |
| 82 | 82 |
| 83 } // namespace | 83 } // namespace |
| 84 | 84 |
| 85 #if !defined(__IPHONE_9_0) | |
| 86 // Predeclare iOS9 API so calls are compiled on iOS8 bots. | |
| 87 // TODO(eugenebut): cleanup this (crbug.com/523365). | |
| 88 @interface WKWebView (CRWIOS9API) | |
| 89 @property(nonatomic, readonly, copy) NSArray* certificateChain; | |
| 90 @end | |
| 91 #endif | |
| 92 | |
| 85 @interface CRWWKWebViewWebController () <WKNavigationDelegate, | 93 @interface CRWWKWebViewWebController () <WKNavigationDelegate, |
| 86 WKScriptMessageHandler, | 94 WKScriptMessageHandler, |
| 87 WKUIDelegate> { | 95 WKUIDelegate> { |
| 88 // The WKWebView managed by this instance. | 96 // The WKWebView managed by this instance. |
| 89 base::scoped_nsobject<WKWebView> _wkWebView; | 97 base::scoped_nsobject<WKWebView> _wkWebView; |
| 90 | 98 |
| 91 // The Watch Dog that detects and reports WKWebView crashes. | 99 // The Watch Dog that detects and reports WKWebView crashes. |
| 92 base::scoped_nsobject<CRWWKWebViewCrashDetector> _crashDetector; | 100 base::scoped_nsobject<CRWWKWebViewCrashDetector> _crashDetector; |
| 93 | 101 |
| 94 // The actual URL of the document object (i.e., the last committed URL). | 102 // The actual URL of the document object (i.e., the last committed URL). |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 // Called when a load ends in an SSL error. | 251 // Called when a load ends in an SSL error. |
| 244 - (void)handleSSLError:(NSError*)error; | 252 - (void)handleSSLError:(NSError*)error; |
| 245 #endif | 253 #endif |
| 246 | 254 |
| 247 // Adds an activity indicator tasks for this web controller. | 255 // Adds an activity indicator tasks for this web controller. |
| 248 - (void)addActivityIndicatorTask; | 256 - (void)addActivityIndicatorTask; |
| 249 | 257 |
| 250 // Clears all activity indicator tasks for this web controller. | 258 // Clears all activity indicator tasks for this web controller. |
| 251 - (void)clearActivityIndicatorTasks; | 259 - (void)clearActivityIndicatorTasks; |
| 252 | 260 |
| 261 // Obtains SSL status from given |certChain| and updates navigation items with | |
| 262 // given |certID|. | |
| 263 - (void)updateSSLStatusForNavigationItemsWithCertID:(int)certID | |
| 264 usingCertChain:(NSArray*)certChain; | |
| 265 | |
| 253 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) | 266 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) |
| 254 // Updates SSL status for the current navigation item based on the information | 267 // Updates SSL status for the current navigation item based on the information |
| 255 // provided by web view. | 268 // provided by web view. |
| 256 - (void)updateSSLStatusForCurrentNavigationItem; | 269 - (void)updateSSLStatusForCurrentNavigationItem; |
| 257 #endif | 270 #endif |
| 258 | 271 |
| 259 // Registers load request with empty referrer and link or client redirect | 272 // Registers load request with empty referrer and link or client redirect |
| 260 // transition based on user interaction state. | 273 // transition based on user interaction state. |
| 261 - (void)registerLoadRequest:(const GURL&)url; | 274 - (void)registerLoadRequest:(const GURL&)url; |
| 262 | 275 |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 857 - (void)addActivityIndicatorTask { | 870 - (void)addActivityIndicatorTask { |
| 858 [[CRWNetworkActivityIndicatorManager sharedInstance] | 871 [[CRWNetworkActivityIndicatorManager sharedInstance] |
| 859 startNetworkTaskForGroup:[self activityIndicatorGroupID]]; | 872 startNetworkTaskForGroup:[self activityIndicatorGroupID]]; |
| 860 } | 873 } |
| 861 | 874 |
| 862 - (void)clearActivityIndicatorTasks { | 875 - (void)clearActivityIndicatorTasks { |
| 863 [[CRWNetworkActivityIndicatorManager sharedInstance] | 876 [[CRWNetworkActivityIndicatorManager sharedInstance] |
| 864 clearNetworkTasksForGroup:[self activityIndicatorGroupID]]; | 877 clearNetworkTasksForGroup:[self activityIndicatorGroupID]]; |
| 865 } | 878 } |
| 866 | 879 |
| 880 - (void)updateSSLStatusForNavigationItemsWithCertID:(int)certID | |
| 881 usingCertChain:(NSArray*)certChain { | |
| 882 base::WeakNSObject<CRWWKWebViewWebController> weakSelf(self); | |
| 883 void (^SSLStatusResponse)(web::SecurityStyle, net::CertStatus) = | |
| 884 ^(web::SecurityStyle style, net::CertStatus certStatus) { | |
| 885 base::scoped_nsobject<CRWWKWebViewWebController> strongSelf( | |
| 886 [weakSelf retain]); | |
| 887 if (!strongSelf || [strongSelf isBeingDestroyed]) { | |
| 888 return; | |
| 889 } | |
| 890 | |
| 891 web::NavigationManager* navigationManager = | |
| 892 [strongSelf webStateImpl]->GetNavigationManager(); | |
| 893 int currentItemIndex = navigationManager->GetCurrentEntryIndex(); | |
| 894 | |
| 895 bool updatedCurrentItem = false; | |
| 896 for (int i = 0; i < navigationManager->GetEntryCount(); i++) { | |
| 897 web::NavigationItem* item = navigationManager->GetItemAtIndex(i); | |
| 898 web::SSLStatus& SSLStatus = item->GetSSL(); | |
| 899 if (SSLStatus.cert_id == certID) { | |
|
Ryan Sleevi
2015/09/24 22:25:32
BUG? Not just the same cert - the same cert & host
Eugene But (OOO till 7-30)
2015/09/25 00:28:10
Yes, this was a bug. Fixed.
| |
| 900 web::SSLStatus previousSSLStatus = item->GetSSL(); | |
| 901 SSLStatus.cert_status = certStatus; | |
| 902 SSLStatus.security_style = style; | |
| 903 if (currentItemIndex == i && !previousSSLStatus.Equals(SSLStatus)) { | |
| 904 updatedCurrentItem = true; | |
| 905 } | |
| 906 } | |
| 907 } | |
| 908 | |
| 909 if (updatedCurrentItem) { | |
| 910 [strongSelf didUpdateSSLStatusForCurrentNavigationItem]; | |
| 911 } | |
| 912 }; | |
| 913 | |
| 914 [_certVerificationController querySSLStatusForCertChain:certChain | |
| 915 host:[_wkWebView URL].host | |
| 916 completionHandler:SSLStatusResponse]; | |
| 917 } | |
| 918 | |
| 867 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) | 919 #if !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) |
| 920 | |
| 868 - (void)updateSSLStatusForCurrentNavigationItem { | 921 - (void)updateSSLStatusForCurrentNavigationItem { |
| 869 if ([self isBeingDestroyed]) | 922 if ([self isBeingDestroyed]) |
| 870 return; | 923 return; |
| 871 | 924 |
| 872 DCHECK(self.webStateImpl); | |
| 873 web::NavigationItem* item = | 925 web::NavigationItem* item = |
| 874 self.webStateImpl->GetNavigationManagerImpl().GetLastCommittedItem(); | 926 self.webStateImpl->GetNavigationManagerImpl().GetLastCommittedItem(); |
| 875 if (!item) | 927 if (!item) |
| 876 return; | 928 return; |
| 877 | 929 |
| 878 web::SSLStatus previousSSLStatus = item->GetSSL(); | 930 web::SSLStatus previousSSLStatus = item->GetSSL(); |
| 879 web::SSLStatus& SSLStatus = item->GetSSL(); | 931 web::SSLStatus& SSLStatus = item->GetSSL(); |
| 880 if (item->GetURL().SchemeIsCryptographic()) { | |
| 881 // TODO(eugenebut): Do not set security style to authenticated once | |
| 882 // proceeding with bad ssl cert is implemented. | |
| 883 SSLStatus.security_style = web::SECURITY_STYLE_AUTHENTICATED; | |
| 884 SSLStatus.content_status = [_wkWebView hasOnlySecureContent] | |
| 885 ? web::SSLStatus::NORMAL_CONTENT | |
| 886 : web::SSLStatus::DISPLAYED_INSECURE_CONTENT; | |
| 887 | 932 |
| 888 if (base::ios::IsRunningOnIOS9OrLater()) { | 933 // Starting from iOS9 WKWebView blocks active mixed content, so if |
| 889 scoped_refptr<net::X509Certificate> cert(web::CreateCertFromChain( | 934 // |hasOnlySecureContent| returns NO it means passive content. |
| 890 [_wkWebView performSelector:@selector(certificateChain)])); | 935 // On iOS8 there is no way to determine if web view has active mixed content. |
| 891 if (cert) { | 936 SSLStatus.content_status = [_wkWebView hasOnlySecureContent] |
| 892 SSLStatus.cert_id = web::CertStore::GetInstance()->StoreCert( | 937 ? web::SSLStatus::NORMAL_CONTENT |
| 893 cert.get(), self.certGroupID); | 938 : web::SSLStatus::DISPLAYED_INSECURE_CONTENT; |
| 894 } else { | 939 |
| 895 SSLStatus.security_style = web::SECURITY_STYLE_UNAUTHENTICATED; | 940 // Retrieve top level frame certificate. |
| 896 SSLStatus.cert_id = 0; | 941 scoped_refptr<net::X509Certificate> cert; |
| 942 if (base::ios::IsRunningOnIOS9OrLater() && | |
| 943 item->GetURL().SchemeIsCryptographic()) { | |
| 944 NSArray* chain = [_wkWebView certificateChain]; | |
| 945 cert = web::CreateCertFromChain(chain); | |
| 946 if (cert) { | |
| 947 int oldCertID = SSLStatus.cert_id; | |
|
Ryan Sleevi
2015/09/24 22:25:32
Same remarks re: hostname
Eugene But (OOO till 7-30)
2015/09/25 00:28:10
This can also be a problem in case of redirect. Fi
| |
| 948 SSLStatus.cert_id = web::CertStore::GetInstance()->StoreCert( | |
| 949 cert.get(), self.certGroupID); | |
| 950 if (oldCertID != SSLStatus.cert_id) { | |
| 951 [self updateSSLStatusForNavigationItemsWithCertID:SSLStatus.cert_id | |
| 952 usingCertChain:chain]; | |
| 897 } | 953 } |
| 898 } | 954 } |
| 899 } else { | 955 } |
| 900 SSLStatus.security_style = web::SECURITY_STYLE_UNAUTHENTICATED; | 956 |
| 957 if (!cert) { | |
| 901 SSLStatus.cert_id = 0; | 958 SSLStatus.cert_id = 0; |
| 959 if (!item->GetURL().SchemeIsCryptographic()) { | |
| 960 // HTTP or other non-secure connection. | |
| 961 SSLStatus.security_style = web::SECURITY_STYLE_UNAUTHENTICATED; | |
| 962 } else if (base::ios::IsRunningOnIOS9OrLater()) { | |
| 963 // HTTPS, iOS9 and no certificate (this use-case has not been observed). | |
| 964 // TODO(eugenebut): Add UMA action for this anomaly (crbug.com/528668). | |
| 965 SSLStatus.security_style = web::SECURITY_STYLE_UNKNOWN; | |
| 966 } else { | |
| 967 // HTTPS, iOS8. | |
| 968 // iOS8 cannot load unauthenticated HTTPS content. | |
| 969 SSLStatus.security_style = web::SECURITY_STYLE_AUTHENTICATED; | |
| 970 } | |
| 902 } | 971 } |
| 903 | 972 |
| 904 if (!previousSSLStatus.Equals(SSLStatus)) { | 973 if (!previousSSLStatus.Equals(SSLStatus)) { |
| 905 [self didUpdateSSLStatusForCurrentNavigationItem]; | 974 [self didUpdateSSLStatusForCurrentNavigationItem]; |
| 906 } | 975 } |
| 907 } | 976 } |
| 977 | |
| 908 #endif // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) | 978 #endif // !defined(ENABLE_CHROME_NET_STACK_FOR_WKWEBVIEW) |
| 909 | 979 |
| 910 - (void)registerLoadRequest:(const GURL&)url { | 980 - (void)registerLoadRequest:(const GURL&)url { |
| 911 // If load request is registered via WKWebViewWebController, assume transition | 981 // If load request is registered via WKWebViewWebController, assume transition |
| 912 // is link or client redirect as other transitions will already be registered | 982 // is link or client redirect as other transitions will already be registered |
| 913 // by web controller or delegates. | 983 // by web controller or delegates. |
| 914 // TODO(stuartmorgan): Remove guesswork and replace with information from | 984 // TODO(stuartmorgan): Remove guesswork and replace with information from |
| 915 // decidePolicyForNavigationAction:. | 985 // decidePolicyForNavigationAction:. |
| 916 ui::PageTransition transition = self.userInteractionRegistered | 986 ui::PageTransition transition = self.userInteractionRegistered |
| 917 ? ui::PAGE_TRANSITION_LINK | 987 ? ui::PAGE_TRANSITION_LINK |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1486 placeholderText:defaultText | 1556 placeholderText:defaultText |
| 1487 requestURL: | 1557 requestURL: |
| 1488 net::GURLWithNSURL(frame.request.URL) | 1558 net::GURLWithNSURL(frame.request.URL) |
| 1489 completionHandler:completionHandler]; | 1559 completionHandler:completionHandler]; |
| 1490 } else if (completionHandler) { | 1560 } else if (completionHandler) { |
| 1491 completionHandler(nil); | 1561 completionHandler(nil); |
| 1492 } | 1562 } |
| 1493 } | 1563 } |
| 1494 | 1564 |
| 1495 @end | 1565 @end |
| OLD | NEW |