diff --git a/CHANGELOG.md b/CHANGELOG.md index 97603ecfcc6..5ebfe5f62a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Note that this project **does not** adhere to [Semantic Versioning](http://semve - We added two new fields to track the creation and most recent modification date and time for each entry. [koppor#130](https://github.com/koppor/jabref/issues/130) - We added a feature that allows the user to copy highlighted text in the preview window. [#6962](https://github.com/JabRef/jabref/issues/6962) - We added a feature that allows you to create new BibEntry via paste arxivId [#2292](https://github.com/JabRef/jabref/issues/2292) +- We added a feature that allows the user to choose whether to trust the target site when unable to find a valid certification path from the file download site. [#7616](https://github.com/JabRef/jabref/issues/7616) ### Changed diff --git a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java index cdc9562e978..87e71366a6d 100644 --- a/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java +++ b/src/main/java/org/jabref/gui/fieldeditors/LinkedFileViewModel.java @@ -10,6 +10,9 @@ import java.util.Optional; import java.util.function.BiPredicate; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSocketFactory; import javax.xml.transform.TransformerException; import javafx.beans.Observable; @@ -425,6 +428,10 @@ public void download() { } URLDownload urlDownload = new URLDownload(linkedFile.getLink()); + if (!checkSSLHandshake(urlDownload)) { + return; + } + BackgroundTask downloadTask = prepareDownloadTask(targetDirectory.get(), urlDownload); downloadTask.onSuccess(destination -> { LinkedFile newLinkedFile = LinkedFilesEditorViewModel.fromFile(destination, databaseContext.getFileDirectories(filePreferences), externalFileTypes); @@ -463,7 +470,28 @@ public void download() { } } + public boolean checkSSLHandshake(URLDownload urlDownload) { + try { + urlDownload.canBeReached(); + } catch (kong.unirest.UnirestException ex) { + if (ex.getCause() instanceof javax.net.ssl.SSLHandshakeException) { + if (dialogService.showConfirmationDialogAndWait(Localization.lang("Download file"), + Localization.lang("Unable to find valid certification path to requested target(%0), download anyway?", + urlDownload.getSource().toString()))) { + URLDownload.bypassSSLVerification(); + return true; + } else { + dialogService.notify(Localization.lang("Download operation canceled.")); + } + } + return false; + } + return true; + } + public BackgroundTask prepareDownloadTask(Path targetDirectory, URLDownload urlDownload) { + SSLSocketFactory defaultSSLSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory(); + HostnameVerifier defaultHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier(); BackgroundTask downloadTask = BackgroundTask .wrap(() -> { Optional suggestedType = inferFileType(urlDownload); @@ -476,6 +504,7 @@ public BackgroundTask prepareDownloadTask(Path targetDirectory, URLDownloa return targetDirectory.resolve(fulltextDir).resolve(suggestedName); }) .then(destination -> new FileDownloadTask(urlDownload.getSource(), destination)) + .onFinished(() -> URLDownload.setSSLVerification(defaultSSLSocketFactory, defaultHostnameVerifier)) .onFailure(exception -> dialogService.showErrorDialogAndWait("Download failed", exception)); return downloadTask; } diff --git a/src/main/java/org/jabref/logic/net/URLDownload.java b/src/main/java/org/jabref/logic/net/URLDownload.java index 99887c7ac93..de94af68dc5 100644 --- a/src/main/java/org/jabref/logic/net/URLDownload.java +++ b/src/main/java/org/jabref/logic/net/URLDownload.java @@ -36,6 +36,7 @@ import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; @@ -132,6 +133,20 @@ public X509Certificate[] getAcceptedIssuers() { } } + /** + * + * @param socketFactory trust manager + * @param verifier host verifier + */ + public static void setSSLVerification(SSLSocketFactory socketFactory, HostnameVerifier verifier) { + try { + HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory); + HttpsURLConnection.setDefaultHostnameVerifier(verifier); + } catch (Exception e) { + LOGGER.error("A problem occurred when reset SSL verification", e); + } + } + public URL getSource() { return source; } diff --git a/src/main/resources/l10n/JabRef_en.properties b/src/main/resources/l10n/JabRef_en.properties index c75a24158dd..56f6d51106f 100644 --- a/src/main/resources/l10n/JabRef_en.properties +++ b/src/main/resources/l10n/JabRef_en.properties @@ -2292,3 +2292,6 @@ Import\ settings=Import settings Custom\ DOI\ URI=Custom DOI URI Customization=Customization Use\ custom\ DOI\ base\ URI\ for\ article\ access=Use custom DOI base URI for article access + +Unable\ to\ find\ valid\ certification\ path\ to\ requested\ target(%0),\ download\ anyway?=Unable to find valid certification path to requested target(%0), download anyway? +Download\ operation\ canceled.=Download operation canceled.