зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1185173 - Add support for Passive Mixed Content. r=margaret
--HG-- extra : commitid : Eynz8mvQTY1 extra : rebase_source : 939ea84b3ac99e6fe82938775482d484cb78c6d0
This commit is contained in:
Родитель
8f295c87c6
Коммит
42079c5836
|
@ -13,13 +13,14 @@ import android.text.TextUtils;
|
|||
public class SiteIdentity {
|
||||
private final String LOGTAG = "GeckoSiteIdentity";
|
||||
private SecurityMode mSecurityMode;
|
||||
private MixedMode mMixedMode;
|
||||
private boolean mSecure;
|
||||
private MixedMode mMixedModeActive;
|
||||
private MixedMode mMixedModeDisplay;
|
||||
private TrackingMode mTrackingMode;
|
||||
private String mHost;
|
||||
private String mOwner;
|
||||
private String mSupplemental;
|
||||
private String mVerifier;
|
||||
private boolean mEncrypted;
|
||||
private String mOrigin;
|
||||
|
||||
// The order of the items here relate to image levels in
|
||||
|
@ -59,8 +60,8 @@ public class SiteIdentity {
|
|||
// site_security_level.xml
|
||||
public enum MixedMode {
|
||||
UNKNOWN("unknown"),
|
||||
MIXED_CONTENT_BLOCKED("mixed_content_blocked"),
|
||||
MIXED_CONTENT_LOADED("mixed_content_loaded");
|
||||
MIXED_CONTENT_BLOCKED("blocked"),
|
||||
MIXED_CONTENT_LOADED("loaded");
|
||||
|
||||
private final String mId;
|
||||
|
||||
|
@ -132,12 +133,13 @@ public class SiteIdentity {
|
|||
mOwner = null;
|
||||
mSupplemental = null;
|
||||
mVerifier = null;
|
||||
mEncrypted = false;
|
||||
mSecure = false;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
resetIdentity();
|
||||
mMixedMode = MixedMode.UNKNOWN;
|
||||
mMixedModeActive = MixedMode.UNKNOWN;
|
||||
mMixedModeDisplay = MixedMode.UNKNOWN;
|
||||
mTrackingMode = TrackingMode.UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -151,9 +153,15 @@ public class SiteIdentity {
|
|||
JSONObject mode = identityData.getJSONObject("mode");
|
||||
|
||||
try {
|
||||
mMixedMode = MixedMode.fromString(mode.getString("mixed"));
|
||||
mMixedModeDisplay = MixedMode.fromString(mode.getString("mixed_display"));
|
||||
} catch (Exception e) {
|
||||
mMixedMode = MixedMode.UNKNOWN;
|
||||
mMixedModeDisplay = MixedMode.UNKNOWN;
|
||||
}
|
||||
|
||||
try {
|
||||
mMixedModeActive = MixedMode.fromString(mode.getString("mixed_active"));
|
||||
} catch (Exception e) {
|
||||
mMixedModeActive = MixedMode.UNKNOWN;
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -175,7 +183,7 @@ public class SiteIdentity {
|
|||
mOwner = identityData.optString("owner", null);
|
||||
mSupplemental = identityData.optString("supplemental", null);
|
||||
mVerifier = identityData.getString("verifier");
|
||||
mEncrypted = identityData.optBoolean("encrypted", false);
|
||||
mSecure = identityData.optBoolean("secure", false);
|
||||
} catch (Exception e) {
|
||||
resetIdentity();
|
||||
}
|
||||
|
@ -208,12 +216,16 @@ public class SiteIdentity {
|
|||
return mVerifier;
|
||||
}
|
||||
|
||||
public boolean getEncrypted() {
|
||||
return mEncrypted;
|
||||
public boolean isSecure() {
|
||||
return mSecure;
|
||||
}
|
||||
|
||||
public MixedMode getMixedMode() {
|
||||
return mMixedMode;
|
||||
public MixedMode getMixedModeActive() {
|
||||
return mMixedModeActive;
|
||||
}
|
||||
|
||||
public MixedMode getMixedModeDisplay() {
|
||||
return mMixedModeDisplay;
|
||||
}
|
||||
|
||||
public TrackingMode getTrackingMode() {
|
||||
|
|
|
@ -564,6 +564,8 @@ just addresses the organization to follow, e.g. "This site is run by " -->
|
|||
|
||||
<!-- Mixed content notifications in site identity popup -->
|
||||
<!ENTITY mixed_content_blocked_all "&brandShortName; has blocked insecure elements on this page.">
|
||||
<!ENTITY mixed_content_blocked_some "&brandShortName; has blocked some insecure elements on this page.">
|
||||
<!ENTITY mixed_content_display_loaded "This page has some insecure elements.">
|
||||
<!ENTITY mixed_content_protection_disabled "You have disabled protection from insecure elements.">
|
||||
|
||||
<!ENTITY loaded_mixed_content_message "This page is displaying content that isn\'t secure.">
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 937 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 528 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.1 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 876 B |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.9 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 900 B |
|
@ -469,6 +469,8 @@
|
|||
<string name="identity_connection_insecure">&identity_connection_insecure;</string>
|
||||
|
||||
<string name="mixed_content_blocked_all">&mixed_content_blocked_all;</string>
|
||||
<string name="mixed_content_blocked_some">&mixed_content_blocked_some;</string>
|
||||
<string name="mixed_content_display_loaded">&mixed_content_display_loaded;</string>
|
||||
<string name="mixed_content_protection_disabled">&mixed_content_protection_disabled;</string>
|
||||
|
||||
<string name="doorhanger_tracking_title">&doorhanger_tracking_title;</string>
|
||||
|
|
|
@ -296,18 +296,60 @@ public class SiteIdentityPopup extends AnchoredPopup implements GeckoEventListen
|
|||
mIdentityKnownContainer.setVisibility(identityInfoVisibility);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Site Identity content to reflect connection state.
|
||||
*
|
||||
* The connection state should reflect the combination of:
|
||||
* a) Connection encryption
|
||||
* b) Mixed Content state (Active/Display Mixed content, loaded, blocked, none, etc)
|
||||
* and update the icons and strings to inform the user of that state.
|
||||
*
|
||||
* @param siteIdentity SiteIdentity information about the connection.
|
||||
*/
|
||||
private void updateConnectionState(final SiteIdentity siteIdentity) {
|
||||
if (siteIdentity.getEncrypted()) {
|
||||
if (!siteIdentity.isSecure()) {
|
||||
if (siteIdentity.getMixedModeActive() == MixedMode.MIXED_CONTENT_LOADED) {
|
||||
// Active Mixed Content loaded because user has disabled blocking.
|
||||
mIcon.setImageResource(R.drawable.lock_disabled);
|
||||
clearSecurityStateIcon();
|
||||
mMixedContentActivity.setVisibility(View.VISIBLE);
|
||||
mMixedContentActivity.setText(R.string.mixed_content_protection_disabled);
|
||||
|
||||
mLink.setVisibility(View.VISIBLE);
|
||||
} else if (siteIdentity.getMixedModeDisplay() == MixedMode.MIXED_CONTENT_LOADED) {
|
||||
// Passive Mixed Content loaded.
|
||||
mIcon.setImageResource(R.drawable.lock_inactive);
|
||||
setSecurityStateIcon(R.drawable.warning_major, 1);
|
||||
mMixedContentActivity.setVisibility(View.VISIBLE);
|
||||
if (siteIdentity.getMixedModeActive() == MixedMode.MIXED_CONTENT_BLOCKED) {
|
||||
mMixedContentActivity.setText(R.string.mixed_content_blocked_some);
|
||||
} else {
|
||||
mMixedContentActivity.setText(R.string.mixed_content_display_loaded);
|
||||
}
|
||||
mLink.setVisibility(View.VISIBLE);
|
||||
|
||||
} else {
|
||||
// Unencrypted connection with no mixed content.
|
||||
mIcon.setImageResource(R.drawable.globe_light);
|
||||
clearSecurityStateIcon();
|
||||
|
||||
mMixedContentActivity.setVisibility(View.GONE);
|
||||
mLink.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
mSecurityState.setText(R.string.identity_connection_insecure);
|
||||
mSecurityState.setTextColor(mResources.getColor(R.color.placeholder_active_grey));
|
||||
} else {
|
||||
// Connection is secure.
|
||||
mIcon.setImageResource(R.drawable.lock_secure);
|
||||
|
||||
setSecurityStateIcon(R.drawable.img_check, 2);
|
||||
mSecurityState.setTextColor(mResources.getColor(R.color.affirmative_green));
|
||||
final Drawable stateIcon = ContextCompat.getDrawable(mContext, R.drawable.img_check);
|
||||
stateIcon.setBounds(0, 0, stateIcon.getIntrinsicWidth()/2, stateIcon.getIntrinsicHeight()/2);
|
||||
mSecurityState.setCompoundDrawables(stateIcon, null, null, null);
|
||||
mSecurityState.setCompoundDrawablePadding((int) mResources.getDimension(R.dimen.doorhanger_drawable_padding));
|
||||
mSecurityState.setText(R.string.identity_connection_secure);
|
||||
|
||||
if (siteIdentity.getMixedMode() == MixedMode.MIXED_CONTENT_BLOCKED) {
|
||||
// Mixed content has been blocked, if present.
|
||||
if (siteIdentity.getMixedModeActive() == MixedMode.MIXED_CONTENT_BLOCKED ||
|
||||
siteIdentity.getMixedModeDisplay() == MixedMode.MIXED_CONTENT_BLOCKED) {
|
||||
mMixedContentActivity.setVisibility(View.VISIBLE);
|
||||
mMixedContentActivity.setText(R.string.mixed_content_blocked_all);
|
||||
mLink.setVisibility(View.VISIBLE);
|
||||
|
@ -315,25 +357,20 @@ public class SiteIdentityPopup extends AnchoredPopup implements GeckoEventListen
|
|||
mMixedContentActivity.setVisibility(View.GONE);
|
||||
mLink.setVisibility(View.GONE);
|
||||
}
|
||||
} else {
|
||||
if (siteIdentity.getMixedMode() == MixedMode.MIXED_CONTENT_LOADED) {
|
||||
mIcon.setImageResource(R.drawable.lock_disabled);
|
||||
mMixedContentActivity.setVisibility(View.VISIBLE);
|
||||
mMixedContentActivity.setText(R.string.mixed_content_protection_disabled);
|
||||
mLink.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mIcon.setImageResource(R.drawable.globe_light);
|
||||
mMixedContentActivity.setVisibility(View.GONE);
|
||||
mLink.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
mSecurityState.setText(R.string.identity_connection_insecure);
|
||||
mSecurityState.setTextColor(mResources.getColor(R.color.placeholder_active_grey));
|
||||
mSecurityState.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
||||
mSecurityState.setCompoundDrawablePadding(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void clearSecurityStateIcon() {
|
||||
mSecurityState.setCompoundDrawablePadding(0);
|
||||
mSecurityState.setCompoundDrawables(null, null, null, null);
|
||||
}
|
||||
|
||||
private void setSecurityStateIcon(int resource, int factor) {
|
||||
final Drawable stateIcon = ContextCompat.getDrawable(mContext, resource);
|
||||
stateIcon.setBounds(0, 0, stateIcon.getIntrinsicWidth()/factor, stateIcon.getIntrinsicHeight()/factor);
|
||||
mSecurityState.setCompoundDrawables(stateIcon, null, null, null);
|
||||
mSecurityState.setCompoundDrawablePadding((int) mResources.getDimension(R.dimen.doorhanger_drawable_padding));
|
||||
}
|
||||
private void updateIdentityInformation(final SiteIdentity siteIdentity) {
|
||||
String owner = siteIdentity.getOwner();
|
||||
if (owner == null) {
|
||||
|
|
|
@ -427,7 +427,8 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout
|
|||
trackingMode = TrackingMode.UNKNOWN;
|
||||
} else {
|
||||
securityMode = siteIdentity.getSecurityMode();
|
||||
mixedMode = siteIdentity.getMixedMode();
|
||||
// TODO: get both types of mixed modes.
|
||||
mixedMode = siteIdentity.getMixedModeActive();
|
||||
trackingMode = siteIdentity.getTrackingMode();
|
||||
}
|
||||
|
||||
|
@ -435,6 +436,7 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout
|
|||
// Default to the identity level
|
||||
int imageLevel = securityMode.ordinal();
|
||||
|
||||
// TODO: Update toolbar icons.
|
||||
// Check to see if any protection was overridden first
|
||||
if (trackingMode == TrackingMode.TRACKING_CONTENT_LOADED) {
|
||||
imageLevel = LEVEL_SHIELD_DISABLED;
|
||||
|
|
|
@ -7087,23 +7087,23 @@ var IdentityHandler = {
|
|||
// No trusted identity information. No site identity icon is shown.
|
||||
IDENTITY_MODE_UNKNOWN: "unknown",
|
||||
|
||||
// Minimal SSL CA-signed domain verification. Blue lock icon is shown.
|
||||
IDENTITY_MODE_DOMAIN_VERIFIED: "verified",
|
||||
|
||||
// High-quality identity information. Green lock icon is shown.
|
||||
// Domain-Validation SSL CA-signed domain verification (DV).
|
||||
IDENTITY_MODE_IDENTIFIED: "identified",
|
||||
|
||||
// Extended-Validation SSL CA-signed identity information (EV). A more rigorous validation process.
|
||||
IDENTITY_MODE_VERIFIED: "verified",
|
||||
|
||||
// The following mixed content modes are only used if "security.mixed_content.block_active_content"
|
||||
// is enabled. Our Java frontend coalesces them into one indicator.
|
||||
|
||||
// No mixed content information. No mixed content icon is shown.
|
||||
MIXED_MODE_UNKNOWN: "unknown",
|
||||
|
||||
// Blocked active mixed content. Shield icon is shown, with a popup option to load content.
|
||||
MIXED_MODE_CONTENT_BLOCKED: "mixed_content_blocked",
|
||||
// Blocked active mixed content.
|
||||
MIXED_MODE_CONTENT_BLOCKED: "blocked",
|
||||
|
||||
// Loaded active mixed content. Yellow triangle icon is shown.
|
||||
MIXED_MODE_CONTENT_LOADED: "mixed_content_loaded",
|
||||
// Loaded active mixed content.
|
||||
MIXED_MODE_CONTENT_LOADED: "loaded",
|
||||
|
||||
// The following tracking content modes are only used if tracking protection
|
||||
// is enabled. Our Java frontend coalesces them into one indicator.
|
||||
|
@ -7159,27 +7159,39 @@ var IdentityHandler = {
|
|||
*/
|
||||
getIdentityMode: function getIdentityMode(aState) {
|
||||
if (aState & Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL) {
|
||||
return this.IDENTITY_MODE_IDENTIFIED;
|
||||
return this.IDENTITY_MODE_VERIFIED;
|
||||
}
|
||||
|
||||
if (aState & Ci.nsIWebProgressListener.STATE_IS_SECURE) {
|
||||
return this.IDENTITY_MODE_DOMAIN_VERIFIED;
|
||||
return this.IDENTITY_MODE_IDENTIFIED;
|
||||
}
|
||||
|
||||
return this.IDENTITY_MODE_UNKNOWN;
|
||||
},
|
||||
|
||||
getMixedMode: function getMixedMode(aState) {
|
||||
if (aState & Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT) {
|
||||
return this.MIXED_MODE_CONTENT_BLOCKED;
|
||||
getMixedDisplayMode: function getMixedDisplayMode(aState) {
|
||||
if (aState & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT) {
|
||||
return this.MIXED_MODE_CONTENT_LOADED;
|
||||
}
|
||||
|
||||
if (aState & Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_DISPLAY_CONTENT) {
|
||||
return this.MIXED_MODE_CONTENT_BLOCKED;
|
||||
}
|
||||
|
||||
return this.MIXED_MODE_UNKNOWN;
|
||||
},
|
||||
|
||||
getMixedActiveMode: function getActiveDisplayMode(aState) {
|
||||
// Only show an indicator for loaded mixed content if the pref to block it is enabled
|
||||
if ((aState & Ci.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT) &&
|
||||
!Services.prefs.getBoolPref("security.mixed_content.block_active_content")) {
|
||||
return this.MIXED_MODE_CONTENT_LOADED;
|
||||
}
|
||||
|
||||
if (aState & Ci.nsIWebProgressListener.STATE_BLOCKED_MIXED_ACTIVE_CONTENT) {
|
||||
return this.MIXED_MODE_CONTENT_BLOCKED;
|
||||
}
|
||||
|
||||
return this.MIXED_MODE_UNKNOWN;
|
||||
},
|
||||
|
||||
|
@ -7230,13 +7242,15 @@ var IdentityHandler = {
|
|||
this._lastLocation = locationObj;
|
||||
|
||||
let identityMode = this.getIdentityMode(aState);
|
||||
let mixedMode = this.getMixedMode(aState);
|
||||
let mixedDisplay = this.getMixedDisplayMode(aState);
|
||||
let mixedActive = this.getMixedActiveMode(aState);
|
||||
let trackingMode = this.getTrackingMode(aState, aBrowser);
|
||||
let result = {
|
||||
origin: locationObj.origin,
|
||||
mode: {
|
||||
identity: identityMode,
|
||||
mixed: mixedMode,
|
||||
mixed_display: mixedDisplay,
|
||||
mixed_active: mixedActive,
|
||||
tracking: trackingMode
|
||||
}
|
||||
};
|
||||
|
@ -7244,10 +7258,12 @@ var IdentityHandler = {
|
|||
// 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).
|
||||
if (identityMode == this.IDENTITY_MODE_UNKNOWN || aState & Ci.nsIWebProgressListener.STATE_IS_BROKEN) {
|
||||
result.secure = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
result.encrypted = true;
|
||||
result.secure = true;
|
||||
|
||||
result.host = this.getEffectiveHost();
|
||||
|
||||
let iData = this.getIdentityData();
|
||||
|
|
Загрузка…
Ссылка в новой задаче