Bug 377076: Enhance Security tab in Page Info, patch by Johnathan Nightingale, r=mconnor, ui-r=beltzner

This commit is contained in:
gavin@gavinsharp.com 2007-04-24 14:13:57 -07:00
Родитель a0a5a8bb40
Коммит 1ab6961a8f
6 изменённых файлов: 335 добавлений и 44 удалений

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

@ -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 &amp; 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;
}