diff options
author | Huahui Wu <hwu@google.com> | 2010-12-15 09:41:59 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-12-15 09:42:00 -0800 |
commit | 4ab61e100d25f6998a1b91e1949a0c81ddf00beb (patch) | |
tree | 06c69ff92995b61067e1a851aafc82318b7513ba | |
parent | a27aeefa969a6478d8defe52be7526d611970b49 (diff) | |
parent | 1f9212cd9a5e957562b12e8c3294b7f357fa1f85 (diff) | |
download | external_webkit-4ab61e100d25f6998a1b91e1949a0c81ddf00beb.zip external_webkit-4ab61e100d25f6998a1b91e1949a0c81ddf00beb.tar.gz external_webkit-4ab61e100d25f6998a1b91e1949a0c81ddf00beb.tar.bz2 |
Merge "b/2864818 Prompt SSL cert error dialog to user and proceed or cancel the request. Java side CL: https://android-git.corp.google.com/g/#change,84530"
-rw-r--r-- | WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp | 3 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebRequest.cpp | 16 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebRequest.h | 2 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp | 27 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebUrlLoaderClient.h | 3 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebViewClientError.cpp | 19 | ||||
-rw-r--r-- | WebKit/android/WebCoreSupport/WebViewClientError.h | 2 | ||||
-rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.cpp | 49 | ||||
-rw-r--r-- | WebKit/android/jni/WebCoreFrameBridge.h | 2 |
9 files changed, 112 insertions, 11 deletions
diff --git a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp index a563c6a..4053e56 100644 --- a/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp +++ b/WebKit/android/WebCoreSupport/FrameLoaderClientAndroid.cpp @@ -74,6 +74,7 @@ #include "WebHistory.h" #include "WebIconDatabase.h" #include "WebFrameView.h" +#include "WebViewClientError.h" #include "WebViewCore.h" #include "autofill/WebAutoFill.h" #include "android_graphics.h" @@ -592,7 +593,7 @@ void FrameLoaderClientAndroid::setMainDocumentError(DocumentLoader* docLoader, c m_manualLoader = NULL; m_hasSentResponseToPlugin = false; } else { - if (!error.isNull() && error.errorCode() >= InternalErrorLast) + if (!error.isNull() && error.errorCode() >= InternalErrorLast && error.errorCode() != ERROR_OK) m_webFrame->reportError(error.errorCode(), error.localizedDescription(), error.failingURL()); } diff --git a/WebKit/android/WebCoreSupport/WebRequest.cpp b/WebKit/android/WebCoreSupport/WebRequest.cpp index 468a3cd..cd496df 100644 --- a/WebKit/android/WebCoreSupport/WebRequest.cpp +++ b/WebKit/android/WebCoreSupport/WebRequest.cpp @@ -318,12 +318,12 @@ void WebRequest::OnAuthRequired(URLRequest* request, net::AuthChallengeInfo* aut m_urlLoader.get(), &WebUrlLoaderClient::authRequired, authInfoPtr, firstTime)); } -// Called when we received an SSL certificate error. Right now, we only -// set the appropriate error code. FIXME: the delegate should provide +// Called when we received an SSL certificate error. The delegate will provide // the user the options to proceed, cancel, or view certificates. void WebRequest::OnSSLCertificateError(URLRequest* request, int cert_error, net::X509Certificate* cert) { - request->SimulateError(cert_error); + m_urlLoader->maybeCallOnMainThread(NewRunnableMethod( + m_urlLoader.get(), &WebUrlLoaderClient::reportSslCertError, cert_error, cert)); } // After calling Start(), the delegate will receive an OnResponseStarted @@ -370,6 +370,16 @@ void WebRequest::followDeferredRedirect() m_request->FollowDeferredRedirect(); } +void WebRequest::proceedSslCertError() +{ + m_request->ContinueDespiteLastError(); +} + +void WebRequest::cancelSslCertError(int cert_error) +{ + m_request->SimulateError(cert_error); +} + void WebRequest::startReading() { ASSERT(m_loadState == Response || m_loadState == GotData, "StartReading in state other than RESPONSE and GOTDATA"); diff --git a/WebKit/android/WebCoreSupport/WebRequest.h b/WebKit/android/WebCoreSupport/WebRequest.h index c78546c..c3c5ec0 100644 --- a/WebKit/android/WebCoreSupport/WebRequest.h +++ b/WebKit/android/WebCoreSupport/WebRequest.h @@ -80,6 +80,8 @@ public: void setAuth(const string16& username, const string16& password); void cancelAuth(); void followDeferredRedirect(); + void proceedSslCertError(); + void cancelSslCertError(int cert_error); const std::string& getUrl() const; const std::string& getUserAgent() const; diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp index 50defc2..0d7981a 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp +++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp @@ -224,6 +224,25 @@ void WebUrlLoaderClient::cancelAuth() thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::cancelAuth)); } +void WebUrlLoaderClient::proceedSslCertError() +{ + base::Thread* thread = ioThread(); + if (!thread) { + return; + } + thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::proceedSslCertError)); +} + +void WebUrlLoaderClient::cancelSslCertError(int cert_error) +{ + base::Thread* thread = ioThread(); + if (!thread) { + return; + } + thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(m_request.get(), &WebRequest::cancelSslCertError, cert_error)); +} + + void WebUrlLoaderClient::finish() { m_finished = true; @@ -349,4 +368,12 @@ void WebUrlLoaderClient::authRequired(scoped_refptr<net::AuthChallengeInfo> auth m_webFrame->didReceiveAuthenticationChallenge(this, host, realm, firstTime); } +void WebUrlLoaderClient::reportSslCertError(int cert_error, net::X509Certificate* cert) +{ + if (!isActive()) return; + std::vector<std::string> chain_bytes; + cert->GetChainDEREncodedBytes(&chain_bytes); + m_webFrame->reportSslCertError(this, cert_error, chain_bytes[0]); +} + } // namespace android diff --git a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h index d69bea6..e5a4d8f 100644 --- a/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h +++ b/WebKit/android/WebCoreSupport/WebUrlLoaderClient.h @@ -72,6 +72,8 @@ public: void pauseLoad(bool pause) {} // Android method, does nothing for now void setAuth(const std::string& username, const std::string& password); void cancelAuth(); + void proceedSslCertError(); + void cancelSslCertError(int cert_error); typedef void CallbackFunction(void*); @@ -88,6 +90,7 @@ public: void didFail(PassOwnPtr<WebResponse>); void willSendRequest(PassOwnPtr<WebResponse>); void authRequired(scoped_refptr<net::AuthChallengeInfo>, bool firstTime); + void reportSslCertError(int cert_error, net::X509Certificate* cert); // Handle to the chrome IO thread static base::Thread* ioThread(); diff --git a/WebKit/android/WebCoreSupport/WebViewClientError.cpp b/WebKit/android/WebCoreSupport/WebViewClientError.cpp index 9744efb..59542da 100644 --- a/WebKit/android/WebCoreSupport/WebViewClientError.cpp +++ b/WebKit/android/WebCoreSupport/WebViewClientError.cpp @@ -101,6 +101,17 @@ WebViewClientError ToWebViewClientError(net::Error error) { case ERR_SSL_SNAP_START_NPN_MISPREDICTION: case ERR_SSL_CLIENT_AUTH_PRIVATE_KEY_ACCESS_DENIED: case ERR_SSL_CLIENT_AUTH_CERT_NO_PRIVATE_KEY: + return ERROR_FAILED_SSL_HANDSHAKE; + + case ERR_PROXY_AUTH_UNSUPPORTED: + case ERR_PROXY_AUTH_REQUESTED: + case ERR_PROXY_CONNECTION_FAILED: + case ERR_UNEXPECTED_PROXY_AUTH: + return ERROR_PROXY_AUTHENTICATION; + + /* The certificate errors are handled by their own dialog + * and don't need to be reported to the framework again. + */ case ERR_CERT_COMMON_NAME_INVALID: case ERR_CERT_DATE_INVALID: case ERR_CERT_AUTHORITY_INVALID: @@ -111,13 +122,7 @@ WebViewClientError ToWebViewClientError(net::Error error) { case ERR_CERT_INVALID: case ERR_CERT_WEAK_SIGNATURE_ALGORITHM: case ERR_CERT_NOT_IN_DNS: - return ERROR_FAILED_SSL_HANDSHAKE; - - case ERR_PROXY_AUTH_UNSUPPORTED: - case ERR_PROXY_AUTH_REQUESTED: - case ERR_PROXY_CONNECTION_FAILED: - case ERR_UNEXPECTED_PROXY_AUTH: - return ERROR_PROXY_AUTHENTICATION; + return ERROR_OK; default: return ERROR_UNKNOWN; diff --git a/WebKit/android/WebCoreSupport/WebViewClientError.h b/WebKit/android/WebCoreSupport/WebViewClientError.h index 847fb01..d274dc7 100644 --- a/WebKit/android/WebCoreSupport/WebViewClientError.h +++ b/WebKit/android/WebCoreSupport/WebViewClientError.h @@ -32,6 +32,8 @@ namespace android { // This enum must be kept in sync with WebViewClient.java enum WebViewClientError { + /** Success */ + ERROR_OK = 0, /** Generic error */ ERROR_UNKNOWN = -1, /** Server or proxy hostname lookup failed */ diff --git a/WebKit/android/jni/WebCoreFrameBridge.cpp b/WebKit/android/jni/WebCoreFrameBridge.cpp index 5fa5dfb..4fac42d 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.cpp +++ b/WebKit/android/jni/WebCoreFrameBridge.cpp @@ -215,6 +215,7 @@ struct WebFrame::JavaBrowserFrame jmethodID mGetFileSize; jmethodID mGetFile; jmethodID mDidReceiveAuthenticationChallenge; + jmethodID mReportSslCertError; jmethodID mDownloadStart; AutoJObject frame(JNIEnv* env) { return getRealObject(env, mObj); @@ -281,6 +282,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* mJavaFrame->mGetFile = env->GetMethodID(clazz, "getFile", "(Ljava/lang/String;[BII)I"); mJavaFrame->mDidReceiveAuthenticationChallenge = env->GetMethodID(clazz, "didReceiveAuthenticationChallenge", "(ILjava/lang/String;Ljava/lang/String;Z)V"); + mJavaFrame->mReportSslCertError = env->GetMethodID(clazz, "reportSslCertError", "(II[B)V"); mJavaFrame->mDownloadStart = env->GetMethodID(clazz, "downloadStart", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;J)V"); env->DeleteLocalRef(clazz); @@ -308,6 +310,7 @@ WebFrame::WebFrame(JNIEnv* env, jobject obj, jobject historyList, WebCore::Page* LOG_ASSERT(mJavaFrame->mGetFileSize, "Could not find method getFileSize"); LOG_ASSERT(mJavaFrame->mGetFile, "Could not find method getFile"); LOG_ASSERT(mJavaFrame->mDidReceiveAuthenticationChallenge, "Could not find method didReceiveAuthenticationChallenge"); + LOG_ASSERT(mJavaFrame->mReportSslCertError, "Could not find method reportSslCertError"); LOG_ASSERT(mJavaFrame->mDownloadStart, "Could not find method downloadStart"); mUserAgent = WTF::String(); @@ -863,6 +866,26 @@ WebFrame::didReceiveAuthenticationChallenge(WebUrlLoaderClient* client, const st } void +WebFrame::reportSslCertError(WebUrlLoaderClient* client, int cert_error, const std::string& cert) +{ +#ifdef ANDROID_INSTRUMENT + TimeCounterAuto counter(TimeCounter::JavaCallbackTimeCounter); +#endif + JNIEnv* env = getJNIEnv(); + int jHandle = reinterpret_cast<int>(client); + + int len = cert.length(); + jbyteArray jCert = env->NewByteArray(len); + jbyte* bytes = env->GetByteArrayElements(jCert, NULL); + cert.copy(reinterpret_cast<char*>(bytes), len); + + env->CallVoidMethod(mJavaFrame->frame(env).get(), + mJavaFrame->mReportSslCertError, jHandle, cert_error, jCert); + env->DeleteLocalRef(jCert); + checkException(env); +} + +void WebFrame::downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength) { #ifdef ANDROID_INSTRUMENT @@ -1876,6 +1899,18 @@ static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle) client->cancelAuth(); } +static void SslCertErrorProceed(JNIEnv *env, jobject obj, int handle) +{ + WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle); + client->proceedSslCertError(); +} + +static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_error) +{ + WebUrlLoaderClient* client = reinterpret_cast<WebUrlLoaderClient*>(handle); + client->cancelSslCertError(cert_error); +} + #else static void AuthenticationProceed(JNIEnv *env, jobject obj, int handle, jstring jUsername, jstring jPassword) @@ -1888,6 +1923,16 @@ static void AuthenticationCancel(JNIEnv *env, jobject obj, int handle) LOGW("Chromium authentication API called, but libchromium is not available"); } +static void SslCertErrorProceed(JNIEnv *env, jobject obj, int handle) +{ + LOGW("Chromium SSL API called, but libchromium is not available"); +} + +static void SslCertErrorCancel(JNIEnv *env, jobject obj, int handle, int cert_error) +{ + LOGW("Chromium SSL API called, but libchromium is not available"); +} + #endif // USE(CHROME_NETWORK_STACK) // ---------------------------------------------------------------------------- @@ -1950,6 +1995,10 @@ static JNINativeMethod gBrowserFrameNativeMethods[] = { (void*) AuthenticationProceed }, { "nativeAuthenticationCancel", "(I)V", (void*) AuthenticationCancel }, + { "nativeSslCertErrorProceed", "(I)V", + (void*) SslCertErrorProceed }, + { "nativeSslCertErrorCancel", "(II)V", + (void*) SslCertErrorCancel }, }; int registerWebFrame(JNIEnv* env) diff --git a/WebKit/android/jni/WebCoreFrameBridge.h b/WebKit/android/jni/WebCoreFrameBridge.h index 4575460..41037d9 100644 --- a/WebKit/android/jni/WebCoreFrameBridge.h +++ b/WebKit/android/jni/WebCoreFrameBridge.h @@ -115,6 +115,8 @@ class WebFrame : public WebCoreRefObject { void didReceiveAuthenticationChallenge(WebUrlLoaderClient*, const std::string& host, const std::string& realm, bool useCachedCredentials); + void reportSslCertError(WebUrlLoaderClient* client, int cert_error, const std::string& cert); + void downloadStart(const std::string& url, const std::string& userAgent, const std::string& contentDisposition, const std::string& mimetype, long long contentLength); void maybeSavePassword(WebCore::Frame* frame, const WebCore::ResourceRequest& request); |