From 000a2ea00c57157044aeca0fb3f24b37669b163c Mon Sep 17 00:00:00 2001 From: wltsmrz Date: Wed, 14 Jan 2015 17:47:23 -0800 Subject: [PATCH] Abort server connection on unrecoverable TLS error --- src/js/ripple/server.js | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/js/ripple/server.js b/src/js/ripple/server.js index b439f80a..e1dc9c45 100644 --- a/src/js/ripple/server.js +++ b/src/js/ripple/server.js @@ -34,7 +34,7 @@ function Server(remote, opts) { throw new TypeError('Server configuration is not an Object'); } - if (!Server.domainRE.test(opts.host)) { + if (!Server.DOMAIN_RE.test(opts.host)) { throw new Error('Server host is malformed, use "host" and "port" server configuration'); } @@ -128,7 +128,22 @@ function Server(remote, opts) { util.inherits(Server, EventEmitter); -Server.domainRE = /^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?)*\.?$/; +Server.DOMAIN_RE = /^(?=.{1,255}$)[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|[-_]){0,61}[0-9A-Za-z])?)*\.?$/; + +Server.TLS_ERRORS = [ + 'UNABLE_TO_GET_ISSUER_CERT', 'UNABLE_TO_GET_CRL', + 'UNABLE_TO_DECRYPT_CERT_SIGNATURE', 'UNABLE_TO_DECRYPT_CRL_SIGNATURE', + 'UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY', 'CERT_SIGNATURE_FAILURE', + 'CRL_SIGNATURE_FAILURE', 'CERT_NOT_YET_VALID', 'CERT_HAS_EXPIRED', + 'CRL_NOT_YET_VALID', 'CRL_HAS_EXPIRED', 'ERROR_IN_CERT_NOT_BEFORE_FIELD', + 'ERROR_IN_CERT_NOT_AFTER_FIELD', 'ERROR_IN_CRL_LAST_UPDATE_FIELD', + 'ERROR_IN_CRL_NEXT_UPDATE_FIELD', 'OUT_OF_MEM', + 'DEPTH_ZERO_SELF_SIGNED_CERT', 'SELF_SIGNED_CERT_IN_CHAIN', + 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY', 'UNABLE_TO_VERIFY_LEAF_SIGNATURE', + 'CERT_CHAIN_TOO_LONG', 'CERT_REVOKED', 'INVALID_CA', + 'PATH_LENGTH_EXCEEDED', 'INVALID_PURPOSE', 'CERT_UNTRUSTED', + 'CERT_REJECTED' +]; /** * Server states that we will treat as the server being online. @@ -434,6 +449,11 @@ Server.prototype.connect = function() { log.info(self.getServerID(), 'onerror:', e.data || e); } + if (Server.TLS_ERRORS.indexOf(e.message) !== -1) { + // Unrecoverable + throw e; + } + // Most connection errors for WebSockets are conveyed as 'close' events with // code 1006. This is done for security purposes and therefore unlikely to // ever change. @@ -636,14 +656,21 @@ Server.prototype._handlePathFind = function(message) { }; /** - * Handle subscription response messages. Subscription response - * messages indicate that a connection to the server is ready + * Handle initial subscription response message. The server is considered + * `connected` after it has received a response to initial subscription to + * ledger and server streams * * @param {Object} message * @api private */ Server.prototype._handleResponseSubscribe = function(message) { + if (this.isConnected()) { + // This function only concerns initializing the server's internal + // state after a connection + return; + } + if (!this._remote._allow_partial_history && !Server.hasFullLedgerHistory(message)) { // Server has partial history and Remote has been configured to disallow