Bug 954534 - Use toolkit untrusted cert dialog for "SSL Handshake failed" errors: chat/ part, r=florian.
This commit is contained in:
Родитель
3ee5cdae24
Коммит
7c994c36f0
|
@ -103,6 +103,11 @@ interface prplIAccount: nsISupports {
|
||||||
/* When a connection error occurred, this value indicates the type of error */
|
/* When a connection error occurred, this value indicates the type of error */
|
||||||
readonly attribute short connectionErrorReason;
|
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:
|
/* Possible connection error reasons:
|
||||||
ERROR_NETWORK_ERROR and ERROR_ENCRYPTION_ERROR are not fatal and
|
ERROR_NETWORK_ERROR and ERROR_ENCRYPTION_ERROR are not fatal and
|
||||||
should enable the automatic reconnection feature. */
|
should enable the automatic reconnection feature. */
|
||||||
|
|
|
@ -52,6 +52,40 @@ const GenericAccountPrototype = {
|
||||||
_connectionErrorReason: Ci.prplIAccount.NO_ERROR,
|
_connectionErrorReason: Ci.prplIAccount.NO_ERROR,
|
||||||
get connectionErrorReason() this._connectionErrorReason,
|
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() {
|
reportConnected: function() {
|
||||||
this.imAccount.observe(this, "account-connected", null);
|
this.imAccount.observe(this, "account-connected", null);
|
||||||
},
|
},
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
* connectTimeout (default is no timeout)
|
* connectTimeout (default is no timeout)
|
||||||
* readWriteTimeout (default is no timeout)
|
* readWriteTimeout (default is no timeout)
|
||||||
* isConnected
|
* isConnected
|
||||||
|
* sslStatus
|
||||||
*
|
*
|
||||||
* Users should "subclass" this object, i.e. set their .__proto__ to be it. And
|
* Users should "subclass" this object, i.e. set their .__proto__ to be it. And
|
||||||
* then implement:
|
* then implement:
|
||||||
|
@ -42,7 +43,7 @@
|
||||||
* onConnectionHeard()
|
* onConnectionHeard()
|
||||||
* onConnectionTimedOut()
|
* onConnectionTimedOut()
|
||||||
* onConnectionReset()
|
* onConnectionReset()
|
||||||
* onBadCertificate(AString aNSSErrorMessage)
|
* onBadCertificate(boolean aIsSslError, AString aNSSErrorMessage)
|
||||||
* onConnectionClosed()
|
* onConnectionClosed()
|
||||||
* onDataReceived(String <data>)
|
* onDataReceived(String <data>)
|
||||||
* <length handled> = onBinaryDataReceived(ArrayBuffer <data>)
|
* <length handled> = onBinaryDataReceived(ArrayBuffer <data>)
|
||||||
|
@ -131,6 +132,9 @@ const Socket = {
|
||||||
connectTimeout: 0,
|
connectTimeout: 0,
|
||||||
readWriteTimeout: 0,
|
readWriteTimeout: 0,
|
||||||
|
|
||||||
|
// A nsISSLStatus instance giving details about the certificate error.
|
||||||
|
sslStatus: null,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
******************************* Public methods ******************************
|
******************************* Public methods ******************************
|
||||||
|
@ -402,12 +406,16 @@ const Socket = {
|
||||||
this.onConnectionReset();
|
this.onConnectionReset();
|
||||||
else if (aStatus == NS_ERROR_NET_TIMEOUT)
|
else if (aStatus == NS_ERROR_NET_TIMEOUT)
|
||||||
this.onConnectionTimedOut();
|
this.onConnectionTimedOut();
|
||||||
else if (aStatus) {
|
else if (!Components.isSuccessCode(aStatus)) {
|
||||||
let nssErrorsService =
|
let nssErrorsService =
|
||||||
Cc["@mozilla.org/nss_errors_service;1"].getService(Ci.nsINSSErrorsService);
|
Cc["@mozilla.org/nss_errors_service;1"].getService(Ci.nsINSSErrorsService);
|
||||||
if (aStatus <= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SEC_ERROR_BASE) &&
|
if ((aStatus <= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SEC_ERROR_BASE) &&
|
||||||
aStatus >= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SEC_ERROR_LIMIT - 1)) {
|
aStatus >= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SEC_ERROR_LIMIT - 1)) ||
|
||||||
this.onBadCertificate(nssErrorsService.getErrorMessage(aStatus));
|
(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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,12 +427,18 @@ const Socket = {
|
||||||
*/
|
*/
|
||||||
// Called when there's an error, return true to suppress the modal alert.
|
// Called when there's an error, return true to suppress the modal alert.
|
||||||
// Whatever this function returns, NSS will close the connection.
|
// 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
|
* nsISSLErrorListener
|
||||||
*/
|
*/
|
||||||
notifySSLError: function(aSocketInfo, aError, aTargetSite) true,
|
notifySSLError: function(aSocketInfo, aError, aTargetSite) {
|
||||||
|
this.sslStatus = null;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nsITransportEventSink methods
|
* nsITransportEventSink methods
|
||||||
|
|
|
@ -674,10 +674,11 @@ ircSocket.prototype = {
|
||||||
this._account.gotDisconnected(Ci.prplIAccount.ERROR_NETWORK_ERROR,
|
this._account.gotDisconnected(Ci.prplIAccount.ERROR_NETWORK_ERROR,
|
||||||
_("connection.error.timeOut"));
|
_("connection.error.timeOut"));
|
||||||
},
|
},
|
||||||
onBadCertificate: function(aNSSErrorMessage) {
|
onBadCertificate: function(aIsSslError, aNSSErrorMessage) {
|
||||||
this.ERROR("bad certificate: " + aNSSErrorMessage);
|
this.ERROR("Bad certificate or SSL connection for " + this._account.name +
|
||||||
this._account.gotDisconnected(Ci.prplIAccount.ERROR_CERT_OTHER_ERROR,
|
":\n" + aNSSErrorMessage);
|
||||||
aNSSErrorMessage);
|
let error = this._account.handleBadCertificate(this, aIsSslError);
|
||||||
|
this._account.gotDisconnected(error, aNSSErrorMessage);
|
||||||
},
|
},
|
||||||
|
|
||||||
get DEBUG() this._account.DEBUG,
|
get DEBUG() this._account.DEBUG,
|
||||||
|
|
|
@ -196,8 +196,9 @@ XMPPSession.prototype = {
|
||||||
onConnectionClosed: function() {
|
onConnectionClosed: function() {
|
||||||
this._networkError(_("connection.error.serverClosedConnection"));
|
this._networkError(_("connection.error.serverClosedConnection"));
|
||||||
},
|
},
|
||||||
onBadCertificate: function(aNSSErrorMessage) {
|
onBadCertificate: function(aIsSslError, aNSSErrorMessage) {
|
||||||
this.onError(Ci.prplIAccount.ERROR_CERT_OTHER_ERROR, aNSSErrorMessage);
|
let error = this._account.handleBadCertificate(this, aIsSslError);
|
||||||
|
this.onError(error, aNSSErrorMessage);
|
||||||
},
|
},
|
||||||
onConnectionReset: function() {
|
onConnectionReset: function() {
|
||||||
this._networkError(_("connection.error.resetByPeer"));
|
this._networkError(_("connection.error.resetByPeer"));
|
||||||
|
|
Загрузка…
Ссылка в новой задаче