tls: emit errors on close whilst async action
When loading session, OCSP response, SNI, always check that the `self._handle` is present. If it is not - the socket was closed - and we should emit the error instead of throwing an uncaught exception. Fix: https://github.com/joyent/node/issues/8780 Fix: https://github.com/iojs/io.js/issues/1696 PR-URL: https://github.com/nodejs/io.js/pull/1702 Reviewed-By: Trevor Norris <trev.norris@gmail.com>
This commit is contained in:
parent
6d95f4ff92
commit
5795e835a1
@ -61,6 +61,9 @@ function loadSession(self, hello, cb) {
|
|||||||
if (err)
|
if (err)
|
||||||
return cb(err);
|
return cb(err);
|
||||||
|
|
||||||
|
if (!self._handle)
|
||||||
|
return cb(new Error('Socket is closed'));
|
||||||
|
|
||||||
// NOTE: That we have disabled OpenSSL's internal session storage in
|
// NOTE: That we have disabled OpenSSL's internal session storage in
|
||||||
// `node_crypto.cc` and hence its safe to rely on getting servername only
|
// `node_crypto.cc` and hence its safe to rely on getting servername only
|
||||||
// from clienthello or this place.
|
// from clienthello or this place.
|
||||||
@ -91,6 +94,9 @@ function loadSNI(self, servername, cb) {
|
|||||||
if (err)
|
if (err)
|
||||||
return cb(err);
|
return cb(err);
|
||||||
|
|
||||||
|
if (!self._handle)
|
||||||
|
return cb(new Error('Socket is closed'));
|
||||||
|
|
||||||
// TODO(indutny): eventually disallow raw `SecureContext`
|
// TODO(indutny): eventually disallow raw `SecureContext`
|
||||||
if (context)
|
if (context)
|
||||||
self._handle.sni_context = context.context || context;
|
self._handle.sni_context = context.context || context;
|
||||||
@ -127,6 +133,9 @@ function requestOCSP(self, hello, ctx, cb) {
|
|||||||
if (err)
|
if (err)
|
||||||
return cb(err);
|
return cb(err);
|
||||||
|
|
||||||
|
if (!self._handle)
|
||||||
|
return cb(new Error('Socket is closed'));
|
||||||
|
|
||||||
if (response)
|
if (response)
|
||||||
self._handle.setOCSPResponse(response);
|
self._handle.setOCSPResponse(response);
|
||||||
cb(null);
|
cb(null);
|
||||||
@ -157,6 +166,9 @@ function oncertcb(info) {
|
|||||||
if (err)
|
if (err)
|
||||||
return self.destroy(err);
|
return self.destroy(err);
|
||||||
|
|
||||||
|
if (!self._handle)
|
||||||
|
return cb(new Error('Socket is closed'));
|
||||||
|
|
||||||
self._handle.certCbDone();
|
self._handle.certCbDone();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -179,6 +191,9 @@ function onnewsession(key, session) {
|
|||||||
return;
|
return;
|
||||||
once = true;
|
once = true;
|
||||||
|
|
||||||
|
if (!self._handle)
|
||||||
|
return cb(new Error('Socket is closed'));
|
||||||
|
|
||||||
self._handle.newSessionDone();
|
self._handle.newSessionDone();
|
||||||
|
|
||||||
self._newSessionPending = false;
|
self._newSessionPending = false;
|
||||||
|
73
test/parallel/test-tls-async-cb-after-socket-end.js
Normal file
73
test/parallel/test-tls-async-cb-after-socket-end.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
var common = require('../common');
|
||||||
|
|
||||||
|
var assert = require('assert');
|
||||||
|
var path = require('path');
|
||||||
|
var fs = require('fs');
|
||||||
|
var constants = require('constants');
|
||||||
|
|
||||||
|
if (!common.hasCrypto) {
|
||||||
|
console.log('1..0 # Skipped: missing crypto');
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
var tls = require('tls');
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
secureOptions: constants.SSL_OP_NO_TICKET,
|
||||||
|
key: fs.readFileSync(path.join(common.fixturesDir, 'test_key.pem')),
|
||||||
|
cert: fs.readFileSync(path.join(common.fixturesDir, 'test_cert.pem'))
|
||||||
|
};
|
||||||
|
|
||||||
|
var server = tls.createServer(options, function(c) {
|
||||||
|
});
|
||||||
|
|
||||||
|
var sessionCb = null;
|
||||||
|
var client = null;
|
||||||
|
|
||||||
|
server.on('newSession', function(key, session, done) {
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
server.on('resumeSession', function(id, cb) {
|
||||||
|
sessionCb = cb;
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(1443, function() {
|
||||||
|
var clientOpts = {
|
||||||
|
port: 1443,
|
||||||
|
rejectUnauthorized: false,
|
||||||
|
session: false
|
||||||
|
};
|
||||||
|
|
||||||
|
var s1 = tls.connect(clientOpts, function() {
|
||||||
|
clientOpts.session = s1.getSession();
|
||||||
|
console.log('1st secure');
|
||||||
|
|
||||||
|
s1.destroy();
|
||||||
|
var s2 = tls.connect(clientOpts, function(s) {
|
||||||
|
console.log('2nd secure');
|
||||||
|
|
||||||
|
s2.destroy();
|
||||||
|
}).on('connect', function() {
|
||||||
|
console.log('2nd connected');
|
||||||
|
client = s2;
|
||||||
|
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function next() {
|
||||||
|
if (!client || !sessionCb)
|
||||||
|
return;
|
||||||
|
|
||||||
|
client.destroy();
|
||||||
|
setTimeout(function() {
|
||||||
|
sessionCb();
|
||||||
|
server.close();
|
||||||
|
}, 100);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user