commit daa148cebd3da69fa24739e2910d67b7480b4fdd Author: Igor Oliveira igt0@torproject.org Date: Mon Oct 29 12:30:14 2018 -0200
Bug 26690: Port padlock states for .onion services to mobile
Prior to this patch, TBA was showing onion services as insecure connection and SSL/TLS ones as encrypted connections(lock icon).
This patch fixes the issue adding several new onion icons to indicate all the various permutations of onions services hosted HTTP or HTTPS pages. --- .../app/src/main/res/drawable-hdpi/ic_onion.png | Bin 0 -> 807 bytes .../main/res/drawable-hdpi/ic_onion_disabled.png | Bin 0 -> 975 bytes .../src/main/res/drawable-hdpi/ic_onion_lock.png | Bin 0 -> 932 bytes .../app/src/main/res/drawable-xhdpi/ic_onion.png | Bin 0 -> 1015 bytes .../main/res/drawable-xhdpi/ic_onion_disabled.png | Bin 0 -> 1260 bytes .../src/main/res/drawable-xhdpi/ic_onion_lock.png | Bin 0 -> 1275 bytes .../app/src/main/res/drawable-xxhdpi/ic_onion.png | Bin 0 -> 1592 bytes .../main/res/drawable-xxhdpi/ic_onion_disabled.png | Bin 0 -> 1892 bytes .../src/main/res/drawable-xxhdpi/ic_onion_lock.png | Bin 0 -> 1899 bytes .../app/src/main/res/drawable-xxxhdpi/ic_onion.png | Bin 0 -> 2099 bytes .../res/drawable-xxxhdpi/ic_onion_disabled.png | Bin 0 -> 2526 bytes .../main/res/drawable-xxxhdpi/ic_onion_lock.png | Bin 0 -> 2568 bytes .../main/res/drawable/security_mode_icon_nm.xml | 9 +++++++++ .../main/res/drawable/security_mode_icon_pm.xml | 9 +++++++++ .../src/main/res/drawable/site_security_icon.xml | 10 +++++++++- .../base/java/org/mozilla/gecko/SiteIdentity.java | 14 ++++++++++++++ .../mozilla/gecko/toolbar/SecurityModeUtil.java | 21 ++++++++++++++++----- .../mozilla/gecko/toolbar/SiteIdentityPopup.java | 17 +++++++++++------ mobile/android/chrome/content/browser.js | 15 ++++++++++++++- 19 files changed, 82 insertions(+), 13 deletions(-)
diff --git a/mobile/android/app/src/main/res/drawable-hdpi/ic_onion.png b/mobile/android/app/src/main/res/drawable-hdpi/ic_onion.png new file mode 100644 index 000000000000..1a61d982752b Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-hdpi/ic_onion.png differ diff --git a/mobile/android/app/src/main/res/drawable-hdpi/ic_onion_disabled.png b/mobile/android/app/src/main/res/drawable-hdpi/ic_onion_disabled.png new file mode 100644 index 000000000000..9669d12101fb Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-hdpi/ic_onion_disabled.png differ diff --git a/mobile/android/app/src/main/res/drawable-hdpi/ic_onion_lock.png b/mobile/android/app/src/main/res/drawable-hdpi/ic_onion_lock.png new file mode 100644 index 000000000000..b0f60fea5b28 Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-hdpi/ic_onion_lock.png differ diff --git a/mobile/android/app/src/main/res/drawable-xhdpi/ic_onion.png b/mobile/android/app/src/main/res/drawable-xhdpi/ic_onion.png new file mode 100755 index 000000000000..074330c3a25a Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-xhdpi/ic_onion.png differ diff --git a/mobile/android/app/src/main/res/drawable-xhdpi/ic_onion_disabled.png b/mobile/android/app/src/main/res/drawable-xhdpi/ic_onion_disabled.png new file mode 100755 index 000000000000..09db37998d33 Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-xhdpi/ic_onion_disabled.png differ diff --git a/mobile/android/app/src/main/res/drawable-xhdpi/ic_onion_lock.png b/mobile/android/app/src/main/res/drawable-xhdpi/ic_onion_lock.png new file mode 100755 index 000000000000..13799b7fa8f7 Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-xhdpi/ic_onion_lock.png differ diff --git a/mobile/android/app/src/main/res/drawable-xxhdpi/ic_onion.png b/mobile/android/app/src/main/res/drawable-xxhdpi/ic_onion.png new file mode 100755 index 000000000000..711bb3c8d8fa Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-xxhdpi/ic_onion.png differ diff --git a/mobile/android/app/src/main/res/drawable-xxhdpi/ic_onion_disabled.png b/mobile/android/app/src/main/res/drawable-xxhdpi/ic_onion_disabled.png new file mode 100755 index 000000000000..0d931669abf3 Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-xxhdpi/ic_onion_disabled.png differ diff --git a/mobile/android/app/src/main/res/drawable-xxhdpi/ic_onion_lock.png b/mobile/android/app/src/main/res/drawable-xxhdpi/ic_onion_lock.png new file mode 100755 index 000000000000..f7a5c29b4c17 Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-xxhdpi/ic_onion_lock.png differ diff --git a/mobile/android/app/src/main/res/drawable-xxxhdpi/ic_onion.png b/mobile/android/app/src/main/res/drawable-xxxhdpi/ic_onion.png new file mode 100755 index 000000000000..97a0beabbe0c Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-xxxhdpi/ic_onion.png differ diff --git a/mobile/android/app/src/main/res/drawable-xxxhdpi/ic_onion_disabled.png b/mobile/android/app/src/main/res/drawable-xxxhdpi/ic_onion_disabled.png new file mode 100755 index 000000000000..aec29bf6238b Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-xxxhdpi/ic_onion_disabled.png differ diff --git a/mobile/android/app/src/main/res/drawable-xxxhdpi/ic_onion_lock.png b/mobile/android/app/src/main/res/drawable-xxxhdpi/ic_onion_lock.png new file mode 100755 index 000000000000..71df527b2a6a Binary files /dev/null and b/mobile/android/app/src/main/res/drawable-xxxhdpi/ic_onion_lock.png differ diff --git a/mobile/android/app/src/main/res/drawable/security_mode_icon_nm.xml b/mobile/android/app/src/main/res/drawable/security_mode_icon_nm.xml index 0b6b496b0b34..bb0da0b843d2 100644 --- a/mobile/android/app/src/main/res/drawable/security_mode_icon_nm.xml +++ b/mobile/android/app/src/main/res/drawable/security_mode_icon_nm.xml @@ -28,5 +28,14 @@ <item android:drawable="@drawable/ic_search_icon" android:maxLevel="6" /> + <item + android:drawable="@drawable/ic_onion" + android:maxLevel="7"/> + <item + android:drawable="@drawable/ic_onion_lock" + android:maxLevel="8"/> + <item + android:drawable="@drawable/ic_onion_disabled" + android:maxLevel="9"/>
</level-list> diff --git a/mobile/android/app/src/main/res/drawable/security_mode_icon_pm.xml b/mobile/android/app/src/main/res/drawable/security_mode_icon_pm.xml index edbd269040d1..be47d7fe081f 100644 --- a/mobile/android/app/src/main/res/drawable/security_mode_icon_pm.xml +++ b/mobile/android/app/src/main/res/drawable/security_mode_icon_pm.xml @@ -28,5 +28,14 @@ <item android:drawable="@drawable/ic_search_icon" android:maxLevel="6" /> + <item + android:drawable="@drawable/ic_onion" + android:maxLevel="7"/> + <item + android:drawable="@drawable/ic_onion_lock" + android:maxLevel="8"/> + <item + android:drawable="@drawable/ic_onion_disabled" + android:maxLevel="9"/>
</level-list> diff --git a/mobile/android/app/src/main/res/drawable/site_security_icon.xml b/mobile/android/app/src/main/res/drawable/site_security_icon.xml index ac8624f861ad..f5f4c7775110 100644 --- a/mobile/android/app/src/main/res/drawable/site_security_icon.xml +++ b/mobile/android/app/src/main/res/drawable/site_security_icon.xml @@ -28,5 +28,13 @@ <item android:drawable="@drawable/ic_search_icon" android:maxLevel="6" /> - + <item + android:drawable="@drawable/ic_onion" + android:maxLevel="7"/> + <item + android:drawable="@drawable/ic_onion_lock" + android:maxLevel="8"/> + <item + android:drawable="@drawable/ic_onion_disabled" + android:maxLevel="9"/> </level-list> diff --git a/mobile/android/base/java/org/mozilla/gecko/SiteIdentity.java b/mobile/android/base/java/org/mozilla/gecko/SiteIdentity.java index 79262586b8fe..0a1b92b75f96 100644 --- a/mobile/android/base/java/org/mozilla/gecko/SiteIdentity.java +++ b/mobile/android/base/java/org/mozilla/gecko/SiteIdentity.java @@ -25,6 +25,8 @@ public class SiteIdentity { private String mCountry; private String mVerifier; private String mOrigin; + private boolean mIsOnionHost; + private boolean mHasCert;
public enum SecurityMode { UNKNOWN, @@ -59,6 +61,8 @@ public class SiteIdentity { mCountry = null; mVerifier = null; mSecure = false; + mIsOnionHost = false; + mHasCert = false; }
public void reset() { @@ -108,6 +112,8 @@ public class SiteIdentity { mVerifier = identityData.getString("verifier"); mSecure = identityData.getBoolean("secure"); mSecurityException = identityData.getBoolean("securityException"); + mIsOnionHost = identityData.getBoolean("isOnionHost"); + mHasCert = identityData.getBoolean("hasCert"); }
/* package */ void updateTrackingMode(final String trackingEvent) { @@ -154,6 +160,14 @@ public class SiteIdentity { return mSecure; }
+ public boolean isOnionHost() { + return mIsOnionHost; + } + + public boolean hasCert() { + return mHasCert; + } + public MixedMode getMixedModeActive() { return mMixedModeActive; } diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/SecurityModeUtil.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/SecurityModeUtil.java index ceb33b8e3acb..10bc83c279a1 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/SecurityModeUtil.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/SecurityModeUtil.java @@ -35,6 +35,9 @@ public class SecurityModeUtil { LOCK_SECURE(1), LOCK_WARNING(-1), // not used for now. reserve for MixedDisplayContent icon, if any. LOCK_INSECURE(3), + ONION(7), + ONION_ACTIVATE(8), + ONION_DISABLED(9), WARNING(2), TRACKING_CONTENT_BLOCKED(4), TRACKING_CONTENT_LOADED(5); @@ -100,6 +103,8 @@ public class SecurityModeUtil { final MixedMode displayMixedMode = identity.getMixedModeDisplay(); final TrackingMode trackingMode = identity.getTrackingMode(); final boolean securityException = identity.isSecurityException(); + final boolean isOnionHost = identity.isOnionHost(); + final boolean hasCert = identity.hasCert();
if (securityException) { return IconType.WARNING; @@ -108,9 +113,9 @@ public class SecurityModeUtil { } else if (trackingMode == TrackingMode.TRACKING_CONTENT_BLOCKED) { return IconType.TRACKING_CONTENT_BLOCKED; } else if (activeMixedMode == MixedMode.LOADED) { - return IconType.LOCK_INSECURE; + return isOnionHost ? IconType.ONION_DISABLED : IconType.LOCK_INSECURE; } else if (displayMixedMode == MixedMode.LOADED) { - return IconType.WARNING; + return isOnionHost ? IconType.ONION_DISABLED : IconType.WARNING; }
// Chrome-UI checking is after tracking/mixed-content, even for about: pages, as they @@ -119,9 +124,15 @@ public class SecurityModeUtil { return IconType.DEFAULT; }
- return securityModeMap.containsKey(securityMode) - ? securityModeMap.get(securityMode) - : IconType.UNKNOWN; + if (securityMode == SecurityMode.UNKNOWN) { + return isOnionHost ? IconType.ONION : IconType.UNKNOWN; + } else if (securityMode == SecurityMode.IDENTIFIED) { + return isOnionHost ? (hasCert ? IconType.ONION_ACTIVATE : IconType.ONION) : IconType.LOCK_SECURE; + } else if (securityMode == SecurityMode.VERIFIED) { + return isOnionHost ? IconType.ONION_ACTIVATE : IconType.LOCK_SECURE; + } else { + return IconType.UNKNOWN; + } }
/** diff --git a/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java b/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java index 831f69f2bf09..df67f0a9b9ed 100644 --- a/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java +++ b/mobile/android/base/java/org/mozilla/gecko/toolbar/SiteIdentityPopup.java @@ -144,8 +144,9 @@ public class SiteIdentityPopup extends AnchoredPopup implements BundleEventListe init(); }
- final boolean isIdentityKnown = (siteIdentity.getSecurityMode() == SecurityMode.IDENTIFIED || - siteIdentity.getSecurityMode() == SecurityMode.VERIFIED); + final boolean isIdentityKnown = ((siteIdentity.getSecurityMode() == SecurityMode.IDENTIFIED || + siteIdentity.getSecurityMode() == SecurityMode.VERIFIED) && + siteIdentity.hasCert()); updateConnectionState(siteIdentity); toggleIdentityKnownContainerVisibility(isIdentityKnown);
@@ -322,7 +323,8 @@ public class SiteIdentityPopup extends AnchoredPopup implements BundleEventListe } else if (!siteIdentity.isSecure()) { if (siteIdentity.getMixedModeActive() == MixedMode.LOADED) { // Active Mixed Content loaded because user has disabled blocking. - mIcon.setImageResource(R.drawable.ic_lock_disabled); + int resId = siteIdentity.isOnionHost() ? R.drawable.ic_onion_disabled : R.drawable.ic_lock_disabled; + mIcon.setImageResource(resId); clearSecurityStateIcon(); mMixedContentActivity.setVisibility(View.VISIBLE); mMixedContentActivity.setText(R.string.mixed_content_protection_disabled); @@ -330,7 +332,8 @@ public class SiteIdentityPopup extends AnchoredPopup implements BundleEventListe mLink.setVisibility(View.VISIBLE); } else if (siteIdentity.getMixedModeDisplay() == MixedMode.LOADED) { // Passive Mixed Content loaded. - mIcon.setImageResource(R.drawable.ic_lock_inactive); + int resId = siteIdentity.isOnionHost() ? R.drawable.ic_onion_disabled : R.drawable.ic_lock_inactive; + mIcon.setImageResource(resId); setSecurityStateIcon(R.drawable.ic_warning_major, 1); mMixedContentActivity.setVisibility(View.VISIBLE); if (siteIdentity.getMixedModeActive() == MixedMode.BLOCKED) { @@ -342,7 +345,8 @@ public class SiteIdentityPopup extends AnchoredPopup implements BundleEventListe
} else { // Unencrypted connection with no mixed content. - mIcon.setImageResource(R.drawable.globe_light); + int resId = siteIdentity.isOnionHost() ? R.drawable.ic_onion : R.drawable.globe_light; + mIcon.setImageResource(resId); clearSecurityStateIcon();
mMixedContentActivity.setVisibility(View.GONE); @@ -361,7 +365,8 @@ public class SiteIdentityPopup extends AnchoredPopup implements BundleEventListe
} else { // Connection is secure. - mIcon.setImageResource(R.drawable.ic_lock); + int resId = siteIdentity.isOnionHost() ? (siteIdentity.hasCert() ? R.drawable.ic_onion_lock : R.drawable.ic_onion) : R.drawable.ic_lock; + mIcon.setImageResource(resId);
setSecurityStateIcon(R.drawable.img_check, 2); mSecurityState.setTextColor(ContextCompat.getColor(mContext, R.color.affirmative_green)); diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index c9cf0f128176..e139e59a7f40 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -6788,6 +6788,17 @@ var IdentityHandler = { return result; },
+ isOnionHost: function isOnionHost() { + try { + return this._uri.host.toLowerCase().endsWith(".onion"); + } catch (e) { + // If something goes wrong (e.g. host is an exception + // because this is an about: page) just fall back + // on false. + return false; + } + }, + /** * Determines the identity mode corresponding to the icon we show in the urlbar. */ @@ -6913,6 +6924,8 @@ var IdentityHandler = { };
result.host = this.getEffectiveHost(); + result.isOnionHost = this.isOnionHost(); + result.hasCert = !!this._lastStatus;
// Don't show identity data for pages with an unknown identity or if any // mixed content is loaded (mixed display content is loaded by default). @@ -6982,7 +6995,7 @@ var IdentityHandler = { // Updating the tooltip value in those cases isn't critical. // FIXME: Fixing bug 646690 would probably makes this check unnecessary if ( - this._lastLocation.hostname && + this._lastLocation.hostname && iData.cert && this._overrideService.hasMatchingOverride( this._lastLocation.hostname, this._lastLocation.port || 443,