diff options
author | Eric Williams | 2018-07-04 20:22:07 +0000 |
---|---|---|
committer | Eric Williams | 2018-07-06 15:41:22 +0000 |
commit | a8f4d8012ebe238243cfee7b3a063bd66a2b6f00 (patch) | |
tree | e065cdd74a124b3b4950d661bf95d9a39fd6f5e0 | |
parent | cf84f297e78323f5ca9e70473ea0ecaf4cfacb50 (diff) | |
download | eclipse.platform.swt-a8f4d8012ebe238243cfee7b3a063bd66a2b6f00.tar.gz eclipse.platform.swt-a8f4d8012ebe238243cfee7b3a063bd66a2b6f00.tar.xz eclipse.platform.swt-a8f4d8012ebe238243cfee7b3a063bd66a2b6f00.zip |
Bug 531341: [Webkit2] Can't access self signed web sites using internal
web browser on fedora 27
Added functionality that prompts a user if they'd like to ignore TLS
errors for certain hosts. If a user visits a website that uses a
self-signed certificate, they will be prompted to either ignore TLS
errors for that host, or to go back.
Tested on GTK3.22 with Webkit2.20. No AllBrowser JUnit tests fail, and
Snippet128 works as expected.
Change-Id: I7c7a07ae27017a70e4a06c720f5640d094a6114c
Signed-off-by: Eric Williams <ericwill@redhat.com>
5 files changed, 123 insertions, 3 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c index 1ed41c336c..8cd55c11e7 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c +++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk.c @@ -2296,6 +2296,30 @@ JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1uri_1response_1get_1mime_1 } #endif +#ifndef NO__1webkit_1web_1context_1allow_1tls_1certificate_1for_1host +JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1context_1allow_1tls_1certificate_1for_1host) + (JNIEnv *env, jclass that, jintLong arg0, jintLong arg1, jbyteArray arg2) +{ + jbyte *lparg2=NULL; + jintLong rc = 0; + WebKitGTK_NATIVE_ENTER(env, that, _1webkit_1web_1context_1allow_1tls_1certificate_1for_1host_FUNC); + if (arg2) if ((lparg2 = (*env)->GetByteArrayElements(env, arg2, NULL)) == NULL) goto fail; +/* + rc = (jintLong)webkit_web_context_allow_tls_certificate_for_host(arg0, arg1, lparg2); +*/ + { + WebKitGTK_LOAD_FUNCTION(fp, webkit_web_context_allow_tls_certificate_for_host) + if (fp) { + rc = (jintLong)((jintLong (CALLING_CONVENTION*)(jintLong, jintLong, jbyte *))fp)(arg0, arg1, lparg2); + } + } +fail: + if (arg2 && lparg2) (*env)->ReleaseByteArrayElements(env, arg2, lparg2, 0); + WebKitGTK_NATIVE_EXIT(env, that, _1webkit_1web_1context_1allow_1tls_1certificate_1for_1host_FUNC); + return rc; +} +#endif + #ifndef NO__1webkit_1web_1context_1get_1default JNIEXPORT jintLong JNICALL WebKitGTK_NATIVE(_1webkit_1web_1context_1get_1default) (JNIEnv *env, jclass that) diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c index 68edc8692f..f6afdf4920 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.c @@ -136,6 +136,7 @@ char * WebKitGTK_nativeFunctionNames[] = { "_1webkit_1uri_1request_1new", "_1webkit_1uri_1response_1get_1content_1length", "_1webkit_1uri_1response_1get_1mime_1type", + "_1webkit_1web_1context_1allow_1tls_1certificate_1for_1host", "_1webkit_1web_1context_1get_1default", "_1webkit_1web_1context_1get_1type", "_1webkit_1web_1context_1get_1website_1data_1manager", diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h index aec00a7781..39bf726604 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/library/webkitgtk_stats.h @@ -146,6 +146,7 @@ typedef enum { _1webkit_1uri_1request_1new_FUNC, _1webkit_1uri_1response_1get_1content_1length_FUNC, _1webkit_1uri_1response_1get_1mime_1type_FUNC, + _1webkit_1web_1context_1allow_1tls_1certificate_1for_1host_FUNC, _1webkit_1web_1context_1get_1default_FUNC, _1webkit_1web_1context_1get_1type_FUNC, _1webkit_1web_1context_1get_1website_1data_1manager_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java index dd77c4872f..2fd33b57dc 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java +++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/browser/WebKit.java @@ -140,6 +140,10 @@ class WebKit extends WebBrowser { BrowserFunction eventFunction; //Webkit1 only. boolean ignoreDispose; // Webkit1 & Webkit2. + boolean tlsError; + long /*int*/ tlsErrorCertificate; + String tlsErrorUriString; + URI tlsErrorUri; /** * Timeout used for javascript execution / deadlock detection. @@ -235,6 +239,7 @@ class WebKit extends WebBrowser { static final int FINISHED = 23; // webkit2 only. static final int DOWNLOAD_STARTED = 24; // Webkit2 (webkit1 equivalent is DOWNLOAD_REQUESTED) static final int WIDGET_EVENT = 25; // Webkit2. Used for events like keyboard/mouse input. See Bug 528549 and Bug 533833. + static final int LOAD_FAILED_TLS = 26; // Webkit2 only static final String KEY_CHECK_SUBWINDOW = "org.eclipse.swt.internal.control.checksubwindow"; //$NON-NLS-1$ @@ -261,6 +266,9 @@ class WebKit extends WebBrowser { /** Webkit1 & Webkit2, Process key/mouse events from javascript. */ static Callback JSDOMEventProc; + /** Flag indicating whether TLS errors (like self-signed certificates) are to be ignored. Webkit2 only.*/ + static final boolean ignoreTls; + static { WebViewType = WebKitGTK.webkit_web_view_get_type (); Proc2 = new Callback (WebKit.class, "Proc", 2); //$NON-NLS-1$ @@ -404,6 +412,7 @@ class WebKit extends WebBrowser { SetPendingCookies (NativePendingCookies); NativePendingCookies = null; } + ignoreTls = WEBKIT2 && "true".equals(System.getProperty("org.eclipse.swt.internal.webkitgtk.ignoretlserrors")); } @Override @@ -1014,6 +1023,7 @@ long /*int*/ webViewProc (long /*int*/ handle, long /*int*/ arg0, long /*int*/ a case CONSOLE_MESSAGE: return webkit_console_message (handle, arg0, arg1, arg2); case WINDOW_OBJECT_CLEARED: return webkit_window_object_cleared (handle, arg0, arg1, arg2); case CONTEXT_MENU: return webkit_context_menu(handle, arg0, arg1, arg2); + case LOAD_FAILED_TLS: return webkit_load_failed_tls(handle, arg0, arg1, arg2); default: return 0; } } @@ -1088,7 +1098,7 @@ public void create (Composite parent, int style) { bug522733FirstInstanceCreated = true; OS.g_object_ref(webView); } - if (WEBKIT2 && "true".equals(System.getProperty("org.eclipse.swt.internal.webkitgtk.ignoretlserrors"))) { + if (ignoreTls) { WebKitGTK.webkit_web_context_set_tls_errors_policy(WebKitGTK.webkit_web_view_get_context(webView), WebKitGTK.WEBKIT_TLS_ERRORS_POLICY_IGNORE); System.out.println("***WARNING: WebKitGTK is configured to ignore TLS errors via -Dorg.eclipse.swt.internal.webkitgtk.ignoretlserrors=true ."); @@ -1128,6 +1138,7 @@ public void create (Composite parent, int style) { OS.g_signal_connect (webView, WebKitGTK.mouse_target_changed, Proc4.getAddress (), MOUSE_TARGET_CHANGED); OS.g_signal_connect (webView, WebKitGTK.context_menu, Proc5.getAddress (), CONTEXT_MENU); + OS.g_signal_connect (webView, WebKitGTK.load_failed_with_tls_errors, Proc5.getAddress (), LOAD_FAILED_TLS); } @@ -3272,7 +3283,6 @@ long /*int*/ webkit_load_changed (long /*int*/ web_view, int status, long user_d return handleLoadCommitted (uri, true); } case WebKitGTK.WEBKIT2_LOAD_FINISHED: { - registerBrowserFunctions(); // Bug 508217 addEventHandlers (web_view, true); @@ -3281,16 +3291,84 @@ long /*int*/ webkit_load_changed (long /*int*/ web_view, int status, long user_d long /*int*/ uri = WebKitGTK.webkit_web_view_get_uri (webView); fireNewTitleEvent(getString(uri)); } - fireProgressCompletedEvent(); + /* + * If there is a pending TLS error, handle it by prompting the user for input. + * This is done by popping up a message box and asking if the user would like + * ignore warnings for this host. Clicking yes will do so, clicking no will + * load the previous page. + * + * Not applicable if the ignoreTls flag has been set. See bug 531341. + */ + if (tlsError && !ignoreTls) { + tlsError = false; + String javaHost = tlsErrorUri.getHost(); + MessageBox prompt = new MessageBox (browser.getShell(), SWT.YES | SWT.NO); + prompt.setText("TLS Certificate Error"); + prompt.setMessage("The host (" + javaHost + ") is using a self-signed " + + "certificate. \n\nClick yes to store this exception and proceed to the page," + + " or no to go back."); + int result = prompt.open(); + if (result == SWT.YES) { + long /*int*/ webkitcontext = WebKitGTK.webkit_web_view_get_context(web_view); + if (javaHost != null) { + byte [] host = Converter.javaStringToCString(javaHost); + WebKitGTK.webkit_web_context_allow_tls_certificate_for_host(webkitcontext, tlsErrorCertificate, host); + WebKitGTK.webkit_web_view_reload (web_view); + } else { + System.err.println("***ERROR: Unable to parse host from URI!"); + } + } else { + back(); + } + // De-reference Webkit certificate so it can be freed + if (tlsErrorCertificate != 0) { + OS.g_object_unref (tlsErrorCertificate); + tlsErrorCertificate = 0; + } + } + return 0; } } return 0; } +/** + * This method is only called by Webkit2. + * + * Called in cases where a web page failed to load due to TLS errors + * (self-signed certificates, as an example). + */ +long /*int*/ webkit_load_failed_tls (long /*int*/ web_view, long /*int*/ failing_uri, long /*int*/ certificate, long error) { + assert WEBKIT2 : WebKitGTK.Webkit2AssertMsg; + if (!ignoreTls) { + // Set tlsError flag so that the user can be prompted once this "bad" page has finished loading + tlsError = true; + OS.g_object_ref(certificate); + tlsErrorCertificate = certificate; + convertUri (failing_uri); + } + return 0; +} +/** + * Converts a WebKit URI into a Java URI object. + * + * @param webkitUri a long pointing to the URI in C string form (gchar *) + * @throws URISyntaxException if the string violates RFC 2396, or is otherwise + * malformed + */ +void convertUri (long /*int*/ webkitUri) { + try { + tlsErrorUriString = Converter.cCharPtrToJavaString(webkitUri, false); + tlsErrorUri = new URI (tlsErrorUriString); + } catch (URISyntaxException e) { + System.err.println("***ERROR: Malformed URI from WebKit!"); + return; + } +} /** * Triggered by a change in property. (both gdouble[0,1]) diff --git a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java index 800e1be0e5..2d0054e156 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java +++ b/bundles/org.eclipse.swt/Eclipse SWT WebKit/gtk/org/eclipse/swt/internal/webkit/WebKitGTK.java @@ -104,6 +104,10 @@ public class WebKitGTK extends C { // Authentication. public static final byte[] authenticate = ascii ("authenticate"); // $NON-NLS-1$ // Webkit1 & Webkit2 + // TLS load failure signal + // Webkit2 only + public static final byte[] load_failed_with_tls_errors = ascii ("load-failed-with-tls-errors"); // $NON-NLS-1$ + // Close webview public static final byte[] close_web_view = ascii ("close-web-view"); // $NON-NLS-1$ // Webkit1 public static final byte[] close = ascii ("close"); // $NON-NLS-1$ // Webkit2 @@ -801,6 +805,18 @@ public static final void webkit_credential_free (long /*int*/ credential) { } } +/** @method flags=dynamic */ +public static final native long /*int*/ _webkit_web_context_allow_tls_certificate_for_host(long /*int*/ webKitWebContext, long /*int*/ GTlsCertificate, byte[] constGCharHost); +public static final long /*int*/ webkit_web_context_allow_tls_certificate_for_host(long /*int*/ webKitWebContext, long /*int*/ GTlsCertificate, byte[] constGCharHost) { + assert WEBKIT2 : Webkit2AssertMsg; + // since 2.6 + lock.lock(); + try { + return _webkit_web_context_allow_tls_certificate_for_host(webKitWebContext, GTlsCertificate, constGCharHost); + } finally { + lock.unlock(); + } +} /** @method flags=dynamic */ public static final native long /*int*/ _webkit_web_context_get_type (); |