Check for invalid certificate in Zotero.HTTP.request()

We were checking for this in the sync API client, but that didn't apply
to Amazon S3 for ZFS.
This commit is contained in:
Dan Stillman 2017-09-20 00:19:42 -04:00
parent a858368642
commit 365e58249d
3 changed files with 69 additions and 34 deletions

View file

@ -58,6 +58,16 @@ Zotero.HTTP = new function() {
};
this.TimeoutException.prototype = Object.create(Error.prototype);
this.SecurityException = function (msg, options = {}) {
this.message = msg;
this.stack = new Error().stack;
for (let i in options) {
this[i] = options[i];
}
};
this.SecurityException.prototype = Object.create(Zotero.Error.prototype);
this.promise = function () {
Zotero.debug("Zotero.HTTP.promise() is deprecated -- use Zotero.HTTP.request()", 2);
return this.request.apply(this, arguments);
@ -257,6 +267,15 @@ Zotero.HTTP = new function() {
msg += ":\n\n" + xmlhttp.responseText;
}
Zotero.debug(msg, 1);
try {
_checkSecurity(xmlhttp, channel);
}
catch (e) {
deferred.reject(e);
return;
}
deferred.reject(new Zotero.HTTP.UnexpectedStatusException(xmlhttp, msg));
}
};
@ -934,6 +953,50 @@ Zotero.HTTP = new function() {
break;
}
}
function _checkSecurity(xmlhttp, channel) {
if (xmlhttp.status != 0 || !channel) {
return;
}
let secInfo = channel.securityInfo;
if (secInfo instanceof Ci.nsITransportSecurityInfo) {
secInfo.QueryInterface(Ci.nsITransportSecurityInfo);
if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_INSECURE)
== Ci.nsIWebProgressListener.STATE_IS_INSECURE) {
let url = channel.name;
let ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
try {
var uri = ios.newURI(url, null, null);
var host = uri.host;
}
catch (e) {
Zotero.debug(e);
}
let kbURL = 'https://www.zotero.org/support/kb/ssl_certificate_error';
msg = Zotero.getString('sync.storage.error.webdav.sslCertificateError', host);
dialogButtonText = Zotero.getString('general.moreInformation');
dialogButtonCallback = function () {
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
let win = wm.getMostRecentWindow("navigator:browser");
win.ZoteroPane.loadURI(kbURL, { metaKey: true, shiftKey: true });
};
}
else if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_BROKEN)
== Ci.nsIWebProgressListener.STATE_IS_BROKEN) {
msg = Zotero.getString('sync.error.sslConnectionError');
}
throw new Zotero.HTTP.SecurityException(
msg,
{
dialogButtonText,
dialogButtonCallback
}
);
}
}
/**
* Mimics the window.location/document.location interface, given an nsIURL

View file

@ -643,6 +643,11 @@ Zotero.Sync.Storage.Mode.ZFS.prototype = {
);
}
catch (e) {
// Certificate error
if (e instanceof Zotero.Error) {
throw e;
}
// For timeouts and failures from S3, which happen intermittently,
// wait a little and try again
let timeoutMessage = "Your socket connection to the server was not read from or "

View file

@ -799,40 +799,7 @@ Zotero.Sync.APIClient.prototype = {
let dialogButtonText = null;
let dialogButtonCallback = null;
// Check SSL cert
if (channel) {
let secInfo = channel.securityInfo;
if (secInfo instanceof Ci.nsITransportSecurityInfo) {
secInfo.QueryInterface(Ci.nsITransportSecurityInfo);
if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_INSECURE)
== Ci.nsIWebProgressListener.STATE_IS_INSECURE) {
let url = channel.name;
let ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
try {
var uri = ios.newURI(url, null, null);
var host = uri.host;
}
catch (e) {
Zotero.debug(e);
}
let kbURL = 'https://www.zotero.org/support/kb/ssl_certificate_error';
msg = Zotero.getString('sync.storage.error.webdav.sslCertificateError', host);
dialogButtonText = Zotero.getString('general.moreInformation');
dialogButtonCallback = function () {
let wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
let win = wm.getMostRecentWindow("navigator:browser");
win.ZoteroPane.loadURI(kbURL, { metaKey: true, shiftKey: true });
};
}
else if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_BROKEN)
== Ci.nsIWebProgressListener.STATE_IS_BROKEN) {
msg = Zotero.getString('sync.error.sslConnectionError');
}
}
}
if (!msg && xmlhttp.status === 0) {
if (xmlhttp.status === 0) {
msg = Zotero.getString('sync.error.checkConnection');
}
if (!msg) {