Bug 920801 - Port chat/ changes from Instantbird to comm-central - 6 - Bio 1100 - Use toolkit untrusted cert dialog for "SSL Handshake failed" errors: chat/ part, r=fqueze.

This commit is contained in:
Patrick Cloke 2013-04-10 18:56:57 -04:00
Родитель f0425b294e
Коммит 12fd2c2cab
5 изменённых файлов: 68 добавлений и 13 удалений

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

@ -103,6 +103,11 @@ interface prplIAccount: nsISupports {
/* When a connection error occurred, this value indicates the type of error */
readonly attribute short connectionErrorReason;
/* When a certificate error occurs, the host/port that caused a
* SSL/certificate error when connecting to it. This is only valid when
* connectionErrorReason is one of ERROR_CERT_*. */
readonly attribute AUTF8String connectionTarget;
/* Possible connection error reasons:
ERROR_NETWORK_ERROR and ERROR_ENCRYPTION_ERROR are not fatal and
should enable the automatic reconnection feature. */

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

@ -52,6 +52,40 @@ const GenericAccountPrototype = {
_connectionErrorReason: Ci.prplIAccount.NO_ERROR,
get connectionErrorReason() this._connectionErrorReason,
handleBadCertificate: function(aSocket, aIsSslError) {
this._connectionTarget = aSocket.host + ":" + aSocket.port;
if (aIsSslError)
return Ci.prplIAccount.ERROR_ENCRYPTION_ERROR;
let sslStatus = aSocket.sslStatus;
if (!sslStatus)
return Ci.prplIAccount.ERROR_CERT_NOT_PROVIDED;
if (sslStatus.isUntrusted) {
if (sslStatus.serverCert instanceof Ci.nsIX509Cert3 &&
sslStatus.serverCert.isSelfSigned)
return Ci.prplIAccount.ERROR_CERT_SELF_SIGNED;
return Ci.prplIAccount.ERROR_CERT_UNTRUSTED;
}
if (sslStatus.isNotValidAtThisTime) {
if (sslStatus.serverCert instanceof Ci.nsIX509Cert3 &&
sslStatus.serverCert.validity.notBefore < Date.now() * 1000)
return Ci.prplIAccount.ERROR_CERT_NOT_ACTIVATED;
return Ci.prplIAccount.ERROR_CERT_EXPIRED;
}
if (sslStatus.isDomainMismatch)
return Ci.prplIAccount.ERROR_CERT_HOSTNAME_MISMATCH;
// XXX ERROR_CERT_FINGERPRINT_MISMATCH
return Ci.prplIAccount.ERROR_CERT_OTHER_ERROR;
},
_connectionTarget: "",
get connectionTarget() this._connectionTarget,
reportConnected: function() {
this.imAccount.observe(this, "account-connected", null);
},

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

@ -35,6 +35,7 @@
* connectTimeout (default is no timeout)
* readWriteTimeout (default is no timeout)
* isConnected
* sslStatus
*
* Users should "subclass" this object, i.e. set their .__proto__ to be it. And
* then implement:
@ -42,7 +43,7 @@
* onConnectionHeard()
* onConnectionTimedOut()
* onConnectionReset()
* onBadCertificate(AString aNSSErrorMessage)
* onBadCertificate(boolean aIsSslError, AString aNSSErrorMessage)
* onConnectionClosed()
* onDataReceived(String <data>)
* <length handled> = onBinaryDataReceived(ArrayBuffer <data>)
@ -131,6 +132,9 @@ const Socket = {
connectTimeout: 0,
readWriteTimeout: 0,
// A nsISSLStatus instance giving details about the certificate error.
sslStatus: null,
/*
*****************************************************************************
******************************* Public methods ******************************
@ -402,12 +406,16 @@ const Socket = {
this.onConnectionReset();
else if (aStatus == NS_ERROR_NET_TIMEOUT)
this.onConnectionTimedOut();
else if (aStatus) {
else if (!Components.isSuccessCode(aStatus)) {
let nssErrorsService =
Cc["@mozilla.org/nss_errors_service;1"].getService(Ci.nsINSSErrorsService);
if (aStatus <= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SEC_ERROR_BASE) &&
aStatus >= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SEC_ERROR_LIMIT - 1)) {
this.onBadCertificate(nssErrorsService.getErrorMessage(aStatus));
if ((aStatus <= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SEC_ERROR_BASE) &&
aStatus >= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SEC_ERROR_LIMIT - 1)) ||
(aStatus <= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SSL_ERROR_BASE) &&
aStatus >= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SSL_ERROR_LIMIT - 1))) {
this.onBadCertificate(nssErrorsService.getErrorClass(aStatus) ==
nssErrorsService.ERROR_CLASS_SSL_PROTOCOL,
nssErrorsService.getErrorMessage(aStatus));
return;
}
}
@ -419,12 +427,18 @@ const Socket = {
*/
// Called when there's an error, return true to suppress the modal alert.
// Whatever this function returns, NSS will close the connection.
notifyCertProblem: function(aSocketInfo, aStatus, aTargetSite) true,
notifyCertProblem: function(aSocketInfo, aStatus, aTargetSite) {
this.sslStatus = aStatus;
return true;
},
/*
* nsISSLErrorListener
*/
notifySSLError: function(aSocketInfo, aError, aTargetSite) true,
notifySSLError: function(aSocketInfo, aError, aTargetSite) {
this.sslStatus = null;
return true;
},
/*
* nsITransportEventSink methods

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

@ -674,10 +674,11 @@ ircSocket.prototype = {
this._account.gotDisconnected(Ci.prplIAccount.ERROR_NETWORK_ERROR,
_("connection.error.timeOut"));
},
onBadCertificate: function(aNSSErrorMessage) {
this.ERROR("bad certificate: " + aNSSErrorMessage);
this._account.gotDisconnected(Ci.prplIAccount.ERROR_CERT_OTHER_ERROR,
aNSSErrorMessage);
onBadCertificate: function(aIsSslError, aNSSErrorMessage) {
this.ERROR("Bad certificate or SSL connection for " + this._account.name +
":\n" + aNSSErrorMessage);
let error = this._account.handleBadCertificate(this, aIsSslError);
this._account.gotDisconnected(error, aNSSErrorMessage);
},
get DEBUG() this._account.DEBUG,

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

@ -196,8 +196,9 @@ XMPPSession.prototype = {
onConnectionClosed: function() {
this._networkError(_("connection.error.serverClosedConnection"));
},
onBadCertificate: function(aNSSErrorMessage) {
this.onError(Ci.prplIAccount.ERROR_CERT_OTHER_ERROR, aNSSErrorMessage);
onBadCertificate: function(aIsSslError, aNSSErrorMessage) {
let error = this._account.handleBadCertificate(this, aIsSslError);
this.onError(error, aNSSErrorMessage);
},
onConnectionReset: function() {
this._networkError(_("connection.error.resetByPeer"));