Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Add invalid certificate bypass to ssl error pages #2530

Merged
merged 3 commits into from
Jan 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ object EngineProvider {
runtime = GeckoRuntime.create(context, builder.build())
for (extension in WEB_EXTENSIONS) {
val path = "resource://android/assets/web_extensions/$extension/"
runtime!!.registerWebExtension(WebExtension(path))
runtime!!.registerWebExtension(WebExtension(path, runtime!!.webExtensionController))
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,7 @@ public GeckoResult<GeckoSession> onNewSession(@NonNull GeckoSession aSession, @N
public GeckoResult<String> onLoadError(@NonNull GeckoSession session, String uri, @NonNull WebRequestError error) {
Log.d(LOGTAG, "Session onLoadError: " + uri);

return GeckoResult.fromValue(InternalPages.createErrorPageDataURI(mContext, uri, error.category, error.code));
return GeckoResult.fromValue(InternalPages.createErrorPageDataURI(mContext, uri, error.code));
}

// Progress Listener
Expand Down
196 changes: 91 additions & 105 deletions app/src/common/shared/org/mozilla/vrbrowser/utils/InternalPages.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,110 +16,84 @@

public class InternalPages {

private static ErrorType fromGeckoErrorToErrorType(int category, int error) {
switch(category) {
case WebRequestError.ERROR_CATEGORY_UNKNOWN: {
return ErrorType.UNKNOWN;
private static ErrorType fromGeckoErrorToErrorType(int error) {
switch(error) {
case WebRequestError.ERROR_SECURITY_SSL: {
return ErrorType.ERROR_SECURITY_SSL;
}
case WebRequestError.ERROR_SECURITY_BAD_CERT: {
return ErrorType.ERROR_SECURITY_BAD_CERT;
}
case WebRequestError.ERROR_NET_INTERRUPT: {
return ErrorType.ERROR_NET_INTERRUPT;
}
case WebRequestError.ERROR_NET_TIMEOUT: {
return ErrorType.ERROR_NET_TIMEOUT;
}
case WebRequestError.ERROR_CONNECTION_REFUSED: {
return ErrorType.ERROR_CONNECTION_REFUSED;
}
case WebRequestError.ERROR_UNKNOWN_SOCKET_TYPE: {
return ErrorType.ERROR_UNKNOWN_SOCKET_TYPE;
}
case WebRequestError.ERROR_REDIRECT_LOOP: {
return ErrorType.ERROR_REDIRECT_LOOP;
}
case WebRequestError.ERROR_OFFLINE: {
return ErrorType.ERROR_OFFLINE;
}
case WebRequestError.ERROR_PORT_BLOCKED: {
return ErrorType.ERROR_PORT_BLOCKED;
}
case WebRequestError.ERROR_NET_RESET: {
return ErrorType.ERROR_NET_RESET;
}
case WebRequestError.ERROR_UNSAFE_CONTENT_TYPE: {
return ErrorType.ERROR_UNSAFE_CONTENT_TYPE;
}
case WebRequestError.ERROR_CORRUPTED_CONTENT: {
return ErrorType.ERROR_CORRUPTED_CONTENT;
}
case WebRequestError.ERROR_CONTENT_CRASHED: {
return ErrorType.ERROR_CONTENT_CRASHED;
}
case WebRequestError.ERROR_INVALID_CONTENT_ENCODING: {
return ErrorType.ERROR_INVALID_CONTENT_ENCODING;
}
case WebRequestError.ERROR_CATEGORY_SECURITY: {
switch (error) {
case WebRequestError.ERROR_SECURITY_SSL: {
return ErrorType.ERROR_SECURITY_SSL;
}
case WebRequestError.ERROR_SECURITY_BAD_CERT: {
return ErrorType.ERROR_SECURITY_BAD_CERT;
}
}
}
case WebRequestError.ERROR_CATEGORY_NETWORK: {
switch (error) {
case WebRequestError.ERROR_NET_INTERRUPT: {
return ErrorType.ERROR_NET_INTERRUPT;
}
case WebRequestError.ERROR_NET_TIMEOUT: {
return ErrorType.ERROR_NET_TIMEOUT;
}
case WebRequestError.ERROR_CONNECTION_REFUSED: {
return ErrorType.ERROR_CONNECTION_REFUSED;
}
case WebRequestError.ERROR_UNKNOWN_SOCKET_TYPE: {
return ErrorType.ERROR_UNKNOWN_SOCKET_TYPE;
}
case WebRequestError.ERROR_REDIRECT_LOOP: {
return ErrorType.ERROR_REDIRECT_LOOP;
}
case WebRequestError.ERROR_OFFLINE: {
return ErrorType.ERROR_OFFLINE;
}
case WebRequestError.ERROR_PORT_BLOCKED: {
return ErrorType.ERROR_PORT_BLOCKED;
}
case WebRequestError.ERROR_NET_RESET: {
return ErrorType.ERROR_NET_RESET;
}
}
}
case WebRequestError.ERROR_CATEGORY_CONTENT: {
switch (error) {
case WebRequestError.ERROR_UNSAFE_CONTENT_TYPE: {
return ErrorType.ERROR_UNSAFE_CONTENT_TYPE;
}
case WebRequestError.ERROR_CORRUPTED_CONTENT: {
return ErrorType.ERROR_CORRUPTED_CONTENT;
}
case WebRequestError.ERROR_CONTENT_CRASHED: {
return ErrorType.ERROR_CONTENT_CRASHED;
}
case WebRequestError.ERROR_INVALID_CONTENT_ENCODING: {
return ErrorType.ERROR_INVALID_CONTENT_ENCODING;
}
}
}
case WebRequestError.ERROR_CATEGORY_URI: {
switch (error) {
case WebRequestError.ERROR_UNKNOWN_HOST: {
return ErrorType.ERROR_UNKNOWN_HOST;
}
case WebRequestError.ERROR_MALFORMED_URI: {
return ErrorType.ERROR_MALFORMED_URI;
}
case WebRequestError.ERROR_UNKNOWN_PROTOCOL: {
return ErrorType.ERROR_UNKNOWN_PROTOCOL;
}
case WebRequestError.ERROR_FILE_NOT_FOUND: {
return ErrorType.ERROR_FILE_NOT_FOUND;
}
case WebRequestError.ERROR_FILE_ACCESS_DENIED: {
return ErrorType.ERROR_FILE_ACCESS_DENIED;
}
}
}
case WebRequestError.ERROR_CATEGORY_PROXY: {
switch (error) {
case WebRequestError.ERROR_PROXY_CONNECTION_REFUSED: {
return ErrorType.ERROR_CONNECTION_REFUSED;
}
case WebRequestError.ERROR_UNKNOWN_PROXY_HOST: {
return ErrorType.ERROR_UNKNOWN_PROXY_HOST;
}
}
}
case WebRequestError.ERROR_CATEGORY_SAFEBROWSING: {
switch (error) {
case WebRequestError.ERROR_SAFEBROWSING_MALWARE_URI: {
return ErrorType.ERROR_SAFEBROWSING_MALWARE_URI;
}
case WebRequestError.ERROR_SAFEBROWSING_UNWANTED_URI: {
return ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI;
}
case WebRequestError.ERROR_SAFEBROWSING_HARMFUL_URI: {
return ErrorType.ERROR_SAFEBROWSING_HARMFUL_URI;
}
case WebRequestError.ERROR_SAFEBROWSING_PHISHING_URI: {
return ErrorType.ERROR_SAFEBROWSING_PHISHING_URI;
}
}
case WebRequestError.ERROR_UNKNOWN_HOST: {
return ErrorType.ERROR_UNKNOWN_HOST;
}
case WebRequestError.ERROR_MALFORMED_URI: {
return ErrorType.ERROR_MALFORMED_URI;
}
case WebRequestError.ERROR_UNKNOWN_PROTOCOL: {
return ErrorType.ERROR_UNKNOWN_PROTOCOL;
}
case WebRequestError.ERROR_FILE_NOT_FOUND: {
return ErrorType.ERROR_FILE_NOT_FOUND;
}
case WebRequestError.ERROR_FILE_ACCESS_DENIED: {
return ErrorType.ERROR_FILE_ACCESS_DENIED;
}
case WebRequestError.ERROR_PROXY_CONNECTION_REFUSED: {
return ErrorType.ERROR_PROXY_CONNECTION_REFUSED;
}
case WebRequestError.ERROR_UNKNOWN_PROXY_HOST: {
return ErrorType.ERROR_UNKNOWN_PROXY_HOST;
}
case WebRequestError.ERROR_SAFEBROWSING_MALWARE_URI: {
return ErrorType.ERROR_SAFEBROWSING_MALWARE_URI;
}
case WebRequestError.ERROR_SAFEBROWSING_UNWANTED_URI: {
return ErrorType.ERROR_SAFEBROWSING_UNWANTED_URI;
}
case WebRequestError.ERROR_SAFEBROWSING_HARMFUL_URI: {
return ErrorType.ERROR_SAFEBROWSING_HARMFUL_URI;
}
case WebRequestError.ERROR_SAFEBROWSING_PHISHING_URI: {
return ErrorType.ERROR_SAFEBROWSING_PHISHING_URI;
}
case WebRequestError.ERROR_CATEGORY_UNKNOWN:
default: {
return ErrorType.UNKNOWN;
}
Expand All @@ -142,16 +116,28 @@ public static PageResources create(int html, int css) {

public static String createErrorPageDataURI(Context context,
String uri,
int errorCategory,
int errorType) {
// TODO: browser-error pages component needs to accept a uri parameter
String html = ErrorPages.INSTANCE.createErrorPage(
context,
fromGeckoErrorToErrorType(errorCategory, errorType),
fromGeckoErrorToErrorType(errorType),
uri,
R.raw.error_pages,
R.raw.error_style);

boolean showSSLAdvanced;
switch (errorType) {
case WebRequestError.ERROR_SECURITY_SSL:
case WebRequestError.ERROR_SECURITY_BAD_CERT:
showSSLAdvanced = true;
break;
default:
showSSLAdvanced = false;
}

html = html
.replace("%url%", uri)
.replace("%advancedSSLStyle%", showSSLAdvanced ? "block" : "none");

return "data:text/html;base64," + Base64.encodeToString(html.getBytes(), Base64.NO_WRAP);
}

Expand Down
67 changes: 59 additions & 8 deletions app/src/main/res/raw/error_pages.html
Original file line number Diff line number Diff line change
@@ -1,28 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<html class="error">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width; user-scalable=false;" />
<title>%pageTitle%</title>
<style>%css%</style>
<script type="text/javascript">
var advancedVisible = false;
function toggleAdvanced() {
if (advancedVisible) {
document.getElementById('badCertAdvancedPanel').style.display='none';

} else {
document.getElementById('badCertAdvancedPanel').style.display='block';
}

advancedVisible = !advancedVisible;
}
function acceptAndContinue(temporary) {
document.addCertException(temporary).then(() => {
location.reload();
},
err => {
console.error("Unexpected error: " + err)
}
);
}
</script>
</head>
<body>

<body id="errorPage" dir="auto">
<!-- PAGE CONTAINER (for styling purposes only) -->
<div id="errorPageContainer">

<!-- Error Title -->
<div id="errorTitle">
<h1 class="errorTitleText">%messageShort%</h1>
<h1 id="et_dnsNotFound" class="errorTitleText">%messageShort%</h1>
</div>

<!-- LONG CONTENT (the section most likely to require scrolling) -->
<div id="errorLongContent">
<!-- Long Description -->
<div id="errorLongDesc">%messageLong%</div>

<!-- Short Description -->
<div id="errorShortDesc">
%messageLong%
</div>

</div>

<!-- Retry Button -->
<br/>
<button id="errorTryAgain" onclick="window.location.reload();">%button%</button>
<button id="errorTryAgain" onclick="window.location.reload()">%button%</button>

<!-- Advanced Button -->
<button id="advancedButton" class="buttonSecondary" onclick="toggleAdvanced()" style="display: %advancedSSLStyle%;">Advanced...</button>

<div id="advancedPanelContainer">
<div id="badCertAdvancedPanel" class="advanced-panel" style="display: none;">
<p id="badCertTechnicalInfo">
<label>Someone could be trying to impersonate the site and you should not continue.</label>

<label>Websites prove their identity via certificates. Firefox does not trust <b>%url%</b> because its certificate issuer is unknown, the certificate is self-signed, or the server is not sending the correct intermediate certificates.</label>
</p>
<div id="advancedPanelButtonContainer" class="button-container">
<button id="advancedPanelReturnButton" onClick="window.history.back()" class="button">Go Back (Recommended)</button>
</div>
<div id="advancedPanelButtonContainer" class="button-container">
<button id="button" class="buttonSecondary" onClick="acceptAndContinue(true)">Accept the Risk and Continue</button>
</div>
</div>
</div>
</div>
</body>
</html>
Loading