зеркало из https://github.com/mozilla/gecko-dev.git
Bug 377076: Enhance Security tab in Page Info, patch by Johnathan Nightingale, r=mconnor, ui-r=beltzner
This commit is contained in:
Родитель
a798e754b0
Коммит
d95a02620d
|
@ -191,7 +191,7 @@
|
|||
</tree>
|
||||
</groupbox>
|
||||
<groupbox id="securityBox">
|
||||
<caption label="&securityHeader;" onclick="toggleGroupbox('securityBox');"/>
|
||||
<caption label="&securityHeader;"/>
|
||||
<description id="general-security-identity" class="header"/>
|
||||
<description id="general-security-privacy" class="header"/>
|
||||
<hbox align="right">
|
||||
|
@ -368,21 +368,105 @@
|
|||
</vbox>
|
||||
</vbox>
|
||||
|
||||
<!-- Security & Privacy -->
|
||||
<vbox id="securityPanel">
|
||||
<textbox id="security-identity" readonly="true" class="header"/>
|
||||
<description id="security-identity-text" control="security-identity" flex="1"/>
|
||||
<hbox align="center">
|
||||
<button id="security-view-cert" label="&securityView.label;"
|
||||
accesskey="&securityView.accesskey;"
|
||||
oncommand="security.viewCert();"/>
|
||||
<description id="security-view-text" control="security-view-cert" flex="1"/>
|
||||
</hbox>
|
||||
<!-- Identity Section -->
|
||||
<label id="security-identity" class="header" value="&securityView.identity.header;"/>
|
||||
<grid>
|
||||
<columns>
|
||||
<column/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row><!-- Domain -->
|
||||
<label id="security-identity-domain-label"
|
||||
class="fieldLabel"
|
||||
value="&securityView.identity.domain;"
|
||||
control="security-identity-domain-value"/>
|
||||
<textbox id="security-identity-domain-value"
|
||||
class="fieldValue" readonly="true"/>
|
||||
</row>
|
||||
<row><!-- Owner -->
|
||||
<label id="security-identity-owner-label"
|
||||
class="fieldLabel"
|
||||
value="&securityView.identity.owner;"
|
||||
control="security-identity-owner-value"/>
|
||||
<textbox id="security-identity-owner-value"
|
||||
class="fieldValue" readonly="true"/>
|
||||
</row>
|
||||
<row><!-- Verifier -->
|
||||
<label id="security-identity-verifier-label"
|
||||
class="fieldLabel"
|
||||
value="&securityView.identity.verifier;"
|
||||
control="security-identity-verifier-value"/>
|
||||
<textbox id="security-identity-verifier-value"
|
||||
class="fieldValue" readonly="true" />
|
||||
</row>
|
||||
<row><!-- Cert button -->
|
||||
<button id="security-view-cert" label="&securityView.label;"
|
||||
accesskey="&securityView.accesskey;"
|
||||
oncommand="security.viewCert();"/>
|
||||
<label id="security-view-text" class="fieldLabel"
|
||||
control="security-view-cert" flex="1"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
|
||||
<separator class="groove"/>
|
||||
<description id="security-privacy" class="header"/>
|
||||
<textbox id="security-privacy" readonly="true" multiline="true" class="header"/>
|
||||
|
||||
<!-- Privacy & History section -->
|
||||
<label id="security-privacy" class="header" value="&securityView.privacy.header;" />
|
||||
<grid>
|
||||
<columns>
|
||||
<column flex="1"/>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
|
||||
<rows>
|
||||
<row><!-- History -->
|
||||
<description id="security-privacy-history-label"
|
||||
control="security-privacy-history-value"
|
||||
class="fieldLabel">&securityView.privacy.history;</description>
|
||||
<textbox id="security-privacy-history-value"
|
||||
class="fieldValue"
|
||||
value="&securityView.unknown;" />
|
||||
</row>
|
||||
<row><!-- Cookies -->
|
||||
<description id="security-privacy-cookies-label"
|
||||
control="security-privacy-cookies-value"
|
||||
class="fieldLabel">&securityView.privacy.cookies;</description>
|
||||
<textbox id="security-privacy-cookies-value"
|
||||
class="fieldValue"
|
||||
value="&securityView.unknown;" />
|
||||
<button id="security-view-cookies"
|
||||
label="&securityView.privacy.viewCookies;"
|
||||
accesskey="&securityView.privacy.viewCookies.accessKey;"
|
||||
oncommand="security.viewCookies();"/>
|
||||
</row>
|
||||
<row><!-- Passwords -->
|
||||
<description id="security-privacy-passwords-label"
|
||||
control="security-privacy-passwords-value"
|
||||
class="fieldLabel">&securityView.privacy.passwords;</description>
|
||||
<textbox id="security-privacy-passwords-value"
|
||||
class="fieldValue"
|
||||
value="&securityView.unknown;" />
|
||||
<button id="security-view-password"
|
||||
label="&securityView.privacy.viewPasswords;"
|
||||
accesskey="&securityView.privacy.viewPasswords.accessKey;"
|
||||
oncommand="security.viewPasswords();"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
|
||||
<separator class="groove"/>
|
||||
|
||||
<!-- Technical Details section -->
|
||||
<label id="security-technical" class="header" value="&securityView.technical.header;" />
|
||||
<vbox flex="1">
|
||||
<description id="security-privacy-msg1" control="security-privacy"/>
|
||||
<description id="security-privacy-msg2" control="security-privacy"/>
|
||||
<label id="security-technical-shortform" class="fieldValue"/>
|
||||
<description id="security-technical-longform1" class="fieldLabel"/>
|
||||
<description id="security-technical-longform2" class="fieldLabel"/>
|
||||
</vbox>
|
||||
</vbox>
|
||||
<!-- Others added by overlay -->
|
||||
|
|
|
@ -88,7 +88,8 @@ var security = {
|
|||
encryptionAlgorithm : status.cipherName,
|
||||
encryptionStrength : status.secretKeyLength,
|
||||
isBroken : isBroken,
|
||||
cert : cert
|
||||
cert : cert,
|
||||
fullLocation : gWindow.location
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
|
@ -97,7 +98,8 @@ var security = {
|
|||
encryptionAlgorithm : "",
|
||||
encryptionStrength : 0,
|
||||
isBroken : isBroken,
|
||||
cert : null
|
||||
cert : null,
|
||||
fullLocation : gWindow.location
|
||||
};
|
||||
}
|
||||
},
|
||||
|
@ -120,12 +122,43 @@ var security = {
|
|||
// No mapping required
|
||||
return name;
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the cookie manager window
|
||||
*/
|
||||
viewCookies : function()
|
||||
{
|
||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var win = wm.getMostRecentWindow("Browser:Cookies");
|
||||
if (win)
|
||||
win.focus();
|
||||
else
|
||||
window.openDialog("chrome://browser/content/preferences/cookies.xul",
|
||||
"Browser:Cookies", "");
|
||||
},
|
||||
|
||||
/**
|
||||
* Open the password manager window
|
||||
*/
|
||||
viewPasswords : function()
|
||||
{
|
||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var win = wm.getMostRecentWindow("Toolkit:PasswordManager");
|
||||
if (win)
|
||||
win.focus();
|
||||
else
|
||||
window.openDialog("chrome://passwordmgr/content/passwordManager.xul",
|
||||
"Toolkit:PasswordManager", "");
|
||||
},
|
||||
|
||||
_cert : null
|
||||
};
|
||||
|
||||
function securityOnLoad() {
|
||||
var bundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
|
||||
var pageInfoBundle = document.getElementById("pageinfobundle");
|
||||
|
||||
var info = security._getSecurityInfo();
|
||||
if (!info) {
|
||||
|
@ -134,36 +167,74 @@ function securityOnLoad() {
|
|||
return;
|
||||
}
|
||||
|
||||
var idHdr;
|
||||
var message1;
|
||||
var message2;
|
||||
/* Set Identity section text */
|
||||
setText("security-identity-domain-value", info.hostName);
|
||||
|
||||
// FIXME - Should only be showing the next two if the cert is EV. Waiting on
|
||||
// bug 374336
|
||||
var owner, verifier, generalPageIdentityString;
|
||||
if (info.cert && !info.isBroken) {
|
||||
// Try to pull out meaningful values. Technically these fields are optional
|
||||
// so we'll employ fallbacks where appropriate. The EV spec states that Org
|
||||
// fields must be specified for subject and issuer so when 374336 lands, this
|
||||
// code can be simplified.
|
||||
owner = info.cert.organization || info.cert.commonName ||
|
||||
info.cert.subjectName;
|
||||
verifier = security.mapIssuerOrganization(info.cAName ||
|
||||
info.cert.issuerCommonName ||
|
||||
info.cert.issuerName);
|
||||
generalPageIdentityString = pageInfoBundle.getFormattedString("generalSiteIdentity",
|
||||
[owner, verifier]);
|
||||
}
|
||||
else {
|
||||
// We don't have valid identity credentials.
|
||||
owner = pageInfoBundle.getString("securityNoIdentity");
|
||||
verifier = pageInfoBundle.getString("notset");
|
||||
generalPageIdentityString = owner;
|
||||
}
|
||||
|
||||
/* Set the identification messages */
|
||||
setText("security-identity-owner-value", owner);
|
||||
setText("security-identity-verifier-value", verifier);
|
||||
setText("general-security-identity", generalPageIdentityString);
|
||||
|
||||
/* Manage the View Cert button*/
|
||||
if (info.cert) {
|
||||
idHdr = bundle.GetStringFromName("pageInfo_WebSiteVerified");
|
||||
|
||||
message1 = bundle.formatStringFromName("pageInfo_Identity_Verified",
|
||||
[ info.hostName, info.cAName ],
|
||||
2);
|
||||
setText("security-identity-text", message1);
|
||||
|
||||
var viewText = bundle.GetStringFromName("pageInfo_ViewCertificate");
|
||||
setText("security-view-text", viewText);
|
||||
security._cert = info.cert;
|
||||
}
|
||||
else {
|
||||
idHdr = bundle.GetStringFromName("pageInfo_SiteNotVerified");
|
||||
var viewCert = document.getElementById("security-view-cert");
|
||||
viewCert.collapsed = true;
|
||||
}
|
||||
setText("general-security-identity", idHdr);
|
||||
setText("security-identity", idHdr);
|
||||
|
||||
/* Set Privacy & History section text */
|
||||
var yesStr = pageInfoBundle.getString("yes");
|
||||
var noStr = pageInfoBundle.getString("no");
|
||||
|
||||
setText("security-privacy-cookies-value",
|
||||
hostHasCookies(info.hostName) ? yesStr : noStr);
|
||||
setText("security-privacy-passwords-value",
|
||||
realmHasPasswords(info.fullLocation) ? yesStr : noStr);
|
||||
|
||||
var visitCount = previousVisitCount(info.hostName);
|
||||
if(visitCount > 1) {
|
||||
setText("security-privacy-history-value",
|
||||
pageInfoBundle.getFormattedString("securityNVisits", [visitCount]));
|
||||
}
|
||||
else if (visitCount == 1) {
|
||||
setText("security-privacy-history-value",
|
||||
pageInfoBundle.getString("securityOneVisit"));
|
||||
}
|
||||
else {
|
||||
setText("security-privacy-history-value", noStr);
|
||||
}
|
||||
|
||||
/* Set the Technical Detail section messages */
|
||||
var hdr;
|
||||
var msg1;
|
||||
var msg2;
|
||||
|
||||
/* Set the encryption messages */
|
||||
if (info.isBroken) {
|
||||
hdr = bundle.GetStringFromName("pageInfo_MixedContent");
|
||||
msg1 = bundle.GetStringFromName("pageInfo_Privacy_Mixed1");
|
||||
|
@ -190,10 +261,10 @@ function securityOnLoad() {
|
|||
msg1 = bundle.GetStringFromName("pageInfo_Privacy_None3");
|
||||
msg2 = bundle.GetStringFromName("pageInfo_Privacy_None2");
|
||||
}
|
||||
setText("security-technical-shortform", hdr);
|
||||
setText("security-technical-longform1", msg1);
|
||||
setText("security-technical-longform2", msg2);
|
||||
setText("general-security-privacy", hdr);
|
||||
setText("security-privacy", hdr);
|
||||
setText("security-privacy-msg1", msg1);
|
||||
setText("security-privacy-msg2", msg2);
|
||||
}
|
||||
|
||||
function setText(id, value)
|
||||
|
@ -201,7 +272,7 @@ function setText(id, value)
|
|||
var element = document.getElementById(id);
|
||||
if (!element)
|
||||
return;
|
||||
if (element.localName == "textbox")
|
||||
if (element.localName == "textbox" || element.localName == "label")
|
||||
element.value = value;
|
||||
else {
|
||||
if (element.hasChildNodes())
|
||||
|
@ -219,3 +290,86 @@ function viewCertHelper(parent, cert)
|
|||
var cd = Components.classes[CERTIFICATEDIALOGS_CONTRACTID].getService(nsICertificateDialogs);
|
||||
cd.viewCert(parent, cert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true iff we have cookies for hostName
|
||||
*/
|
||||
function hostHasCookies(hostName) {
|
||||
if (!hostName)
|
||||
return false;
|
||||
|
||||
var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"]
|
||||
.getService(Components.interfaces.nsICookieManager);
|
||||
|
||||
var iter = cookieManager.enumerator;
|
||||
while (iter.hasMoreElements()){
|
||||
var cookie = iter.getNext().QueryInterface(Components.interfaces.nsICookie);
|
||||
if (!cookie)
|
||||
continue;
|
||||
|
||||
// A direct match works whether it's a domain cookie or not
|
||||
if (cookie.host == hostName)
|
||||
return true;
|
||||
|
||||
// Domain cookies just need to end with our target hostname
|
||||
if (cookie.isDomain && endsWith(hostName, cookie.host))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true iff realm (proto://host:port) (extracted from location) has
|
||||
* saved passwords
|
||||
*/
|
||||
function realmHasPasswords(location) {
|
||||
if (!location)
|
||||
return false;
|
||||
|
||||
var realm = makeURI(location).prePath;
|
||||
var passwordManager = Components.classes["@mozilla.org/passwordmanager;1"]
|
||||
.getService(Components.interfaces.nsIPasswordManager);
|
||||
var e = passwordManager.enumerator;
|
||||
while (e.hasMoreElements()) {
|
||||
var next = e.getNext().QueryInterface(Components.interfaces.nsIPassword);
|
||||
if (!next)
|
||||
continue;
|
||||
|
||||
if (realm == next.host)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of previous visits recorded for host before today.
|
||||
*
|
||||
* @param host - the domain name to look for in history
|
||||
*/
|
||||
function previousVisitCount(host, endTimeReference) {
|
||||
if (!host)
|
||||
return false;
|
||||
|
||||
var historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"]
|
||||
.getService(Components.interfaces.nsINavHistoryService);
|
||||
|
||||
var options = historyService.getNewQueryOptions();
|
||||
options.resultType = options.RESULTS_AS_VISIT;
|
||||
|
||||
// Search for visits to this host before today
|
||||
var query = historyService.getNewQuery();
|
||||
query.endTimeReference = query.TIME_RELATIVE_TODAY;
|
||||
query.endTime = 0;
|
||||
query.domain = host;
|
||||
|
||||
var result = historyService.executeQuery(query, options);
|
||||
result.root.containerOpen = true;
|
||||
return result.root.childCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true iff the string suffix appears at the end of the string target
|
||||
*/
|
||||
function endsWith(target, suffix) {
|
||||
return target && suffix && target.substr(-1 * suffix.length) === suffix;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
# ***** END LICENSE BLOCK *****
|
||||
-->
|
||||
|
||||
<!ENTITY pageInfoWindow.width "425">
|
||||
<!ENTITY pageInfoWindow.height "470">
|
||||
<!ENTITY pageInfoWindow.width "600">
|
||||
<!ENTITY pageInfoWindow.height "500">
|
||||
|
||||
<!ENTITY copy.key "C">
|
||||
<!ENTITY copy.label "Copy">
|
||||
|
@ -99,3 +99,21 @@
|
|||
<!ENTITY securityHeader "Security information for this page">
|
||||
<!ENTITY securityView.label "View">
|
||||
<!ENTITY securityView.accesskey "V">
|
||||
<!ENTITY securityView.unknown "Unknown">
|
||||
|
||||
|
||||
<!ENTITY securityView.identity.header "Web Site Identity">
|
||||
<!ENTITY securityView.identity.owner "Owner: ">
|
||||
<!ENTITY securityView.identity.domain "Web site: ">
|
||||
<!ENTITY securityView.identity.verifier "Verified by: ">
|
||||
|
||||
<!ENTITY securityView.privacy.header "Privacy & History">
|
||||
<!ENTITY securityView.privacy.history "Have I visited this website before today?">
|
||||
<!ENTITY securityView.privacy.cookies "Is this web site storing information (cookies) on my computer?">
|
||||
<!ENTITY securityView.privacy.viewCookies "View Cookies">
|
||||
<!ENTITY securityView.privacy.viewCookies.accessKey "k">
|
||||
<!ENTITY securityView.privacy.passwords "Have I saved any passwords for this web site?">
|
||||
<!ENTITY securityView.privacy.viewPasswords "View Saved Passwords">
|
||||
<!ENTITY securityView.privacy.viewPasswords.accessKey "w">
|
||||
|
||||
<!ENTITY securityView.technical.header "Technical Details">
|
||||
|
|
|
@ -43,6 +43,8 @@ noPageTitle=Untitled Page:
|
|||
pageTitle=%S:
|
||||
unknown=Unknown
|
||||
notset=Not specified
|
||||
yes=Yes
|
||||
no=No
|
||||
|
||||
mediaImg=Image
|
||||
mediaBGImg=Background
|
||||
|
@ -62,6 +64,11 @@ generalMemoryCache=Memory cache
|
|||
generalSize=%S KB (%S bytes)
|
||||
generalMetaTag=Meta (1 tag)
|
||||
generalMetaTags=Meta (%S tags)
|
||||
generalSiteIdentity=This web site is owned by %S\nThis has been verified by %S
|
||||
|
||||
feedRss=RSS
|
||||
feedAtom=Atom
|
||||
|
||||
securityNoIdentity=This web site does not supply identity information.
|
||||
securityOneVisit=Yes, once
|
||||
securityNVisits=Yes, %S times
|
||||
|
|
|
@ -163,6 +163,15 @@ groupbox tree {
|
|||
-moz-margin-start: 10px;
|
||||
}
|
||||
|
||||
#securityBox .caption-icon {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
#general-security-identity {
|
||||
white-space: -moz-pre-wrap;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
/* Media Tab */
|
||||
#imagetree {
|
||||
min-height: 10em;
|
||||
|
@ -238,10 +247,15 @@ treechildren::-moz-tree-cell-text(broken) {
|
|||
}
|
||||
|
||||
/* Security Tab */
|
||||
#securityTab textbox {
|
||||
-moz-margin-start: 4px;
|
||||
#securityPanel .header {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
#securityPanel .fieldLabel {
|
||||
margin: 5px 10px 10px 10px;
|
||||
}
|
||||
|
||||
#securityTab textarea {
|
||||
overflow: hidden;
|
||||
#securityPanel .fieldValue {
|
||||
font-weight: bold;
|
||||
margin: 5px 10px 0px 10px;
|
||||
}
|
||||
|
|
|
@ -170,6 +170,15 @@ groupbox tree {
|
|||
-moz-margin-start: 10px;
|
||||
}
|
||||
|
||||
#securityBox .caption-icon {
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
#general-security-identity {
|
||||
white-space: -moz-pre-wrap;
|
||||
line-height: 2em;
|
||||
}
|
||||
|
||||
/* Media Tab */
|
||||
#imagetree {
|
||||
min-height: 10em;
|
||||
|
@ -245,10 +254,15 @@ treechildren::-moz-tree-cell-text(broken) {
|
|||
}
|
||||
|
||||
/* Security Tab */
|
||||
#securityTab textbox {
|
||||
-moz-margin-start: 4px;
|
||||
#securityPanel .header {
|
||||
font-size: 120%;
|
||||
}
|
||||
|
||||
#securityPanel .fieldLabel {
|
||||
margin: 5px 10px 10px 10px;
|
||||
}
|
||||
|
||||
#securityTab textarea {
|
||||
overflow: hidden;
|
||||
#securityPanel .fieldValue {
|
||||
font-weight: bold;
|
||||
margin: 5px 10px 0px 10px;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче