Bug 1185173 - Add support for Passive Mixed Content. r=margaret

--HG--
extra : commitid : Eynz8mvQTY1
extra : rebase_source : 939ea84b3ac99e6fe82938775482d484cb78c6d0
This commit is contained in:
Chenxia Liu 2015-08-05 18:10:24 -07:00
Родитель 8f295c87c6
Коммит 42079c5836
12 изменённых файлов: 123 добавлений и 52 удалений

Просмотреть файл

@ -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.">

Двоичные данные
mobile/android/base/resources/drawable-hdpi/lock_inactive.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 937 B

Двоичные данные
mobile/android/base/resources/drawable-hdpi/warning_major.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 528 B

Двоичные данные
mobile/android/base/resources/drawable-xhdpi/lock_inactive.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
mobile/android/base/resources/drawable-xhdpi/warning_major.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 876 B

Двоичные данные
mobile/android/base/resources/drawable-xxhdpi/lock_inactive.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

Двоичные данные
mobile/android/base/resources/drawable-xxhdpi/warning_major.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 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();