Skip to content

Commit 7b3b8ac

Browse files
committed
tls: accept empty net.Sockets
Accept `new net.Socket()` as a `socket` option to `tls.connect()` without triggering an assertion error in C++. This is done by wrapping it into a JSStream to ensure that there will be a handle at the time of wrapping the socket into TLSSocket. Fix: #987 PR-URL: #1046 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Rod Vagg <[email protected]>
1 parent e1bf670 commit 7b3b8ac

File tree

2 files changed

+60
-11
lines changed

2 files changed

+60
-11
lines changed

lib/_tls_wrap.js

+19-11
Original file line numberDiff line numberDiff line change
@@ -227,15 +227,20 @@ function TLSSocket(socket, options) {
227227
this.authorizationError = null;
228228

229229
// Wrap plain JS Stream into StreamWrap
230+
var wrap;
230231
if (!(socket instanceof net.Socket) && socket instanceof Duplex)
231-
socket = new StreamWrap(socket);
232+
wrap = new StreamWrap(socket);
233+
else if ((socket instanceof net.Socket) && !socket._handle)
234+
wrap = new StreamWrap(socket);
235+
else
236+
wrap = socket;
232237

233238
// Just a documented property to make secure sockets
234239
// distinguishable from regular ones.
235240
this.encrypted = true;
236241

237242
net.Socket.call(this, {
238-
handle: this._wrapHandle(socket && socket._handle),
243+
handle: this._wrapHandle(wrap && wrap._handle),
239244
allowHalfOpen: socket && socket.allowHalfOpen,
240245
readable: false,
241246
writable: false
@@ -246,7 +251,7 @@ function TLSSocket(socket, options) {
246251

247252
this.on('error', this._tlsError);
248253

249-
this._init(socket);
254+
this._init(socket, wrap);
250255

251256
// Make sure to setup all required properties like: `_connecting` before
252257
// starting the flow of the data
@@ -302,7 +307,7 @@ TLSSocket.prototype._wrapHandle = function(handle) {
302307
return res;
303308
};
304309

305-
TLSSocket.prototype._init = function(socket) {
310+
TLSSocket.prototype._init = function(socket, wrap) {
306311
var self = this;
307312
var options = this._tlsOptions;
308313
var ssl = this._handle;
@@ -394,24 +399,26 @@ TLSSocket.prototype._init = function(socket) {
394399
ssl.receive(buf);
395400
}
396401

397-
if (socket) {
402+
if (socket instanceof net.Socket) {
398403
this._parent = socket;
399404

400405
// To prevent assertion in afterConnect() and properly kick off readStart
401-
this._connecting = socket._connecting;
406+
this._connecting = socket._connecting || !socket._handle;
402407
socket.once('connect', function() {
403408
self._connecting = false;
404409
self.emit('connect');
405410
});
406-
407-
socket.on('error', function(err) {
408-
self._tlsError(err);
409-
});
410411
}
411412

412413
// Assume `tls.connect()`
413-
if (!socket)
414+
if (wrap) {
415+
wrap.on('error', function(err) {
416+
self._tlsError(err);
417+
});
418+
} else {
419+
assert(!socket);
414420
this._connecting = true;
421+
}
415422
};
416423

417424
TLSSocket.prototype.renegotiate = function(options, callback) {
@@ -506,6 +513,7 @@ TLSSocket.prototype._start = function() {
506513
return;
507514
}
508515

516+
debug('start');
509517
if (this._tlsOptions.requestOCSP)
510518
this._handle.requestOCSP();
511519
this._handle.start();
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
if (!process.versions.openssl) {
2+
console.error('Skipping because node compiled without OpenSSL.');
3+
process.exit(0);
4+
}
5+
6+
var assert = require('assert');
7+
var fs = require('fs');
8+
var net = require('net');
9+
var tls = require('tls');
10+
11+
var common = require('../common');
12+
13+
var out = '';
14+
15+
var server = tls.createServer({
16+
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
17+
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem')
18+
}, function(c) {
19+
c.end('hello');
20+
}).listen(common.PORT, function() {
21+
var socket = new net.Socket();
22+
23+
var s = tls.connect({
24+
socket: socket,
25+
rejectUnauthorized: false
26+
}, function() {
27+
s.on('data', function(chunk) {
28+
out += chunk;
29+
});
30+
s.on('end', function() {
31+
s.destroy();
32+
server.close();
33+
});
34+
});
35+
36+
socket.connect(common.PORT);
37+
});
38+
39+
process.on('exit', function() {
40+
assert.equal(out, 'hello');
41+
});

0 commit comments

Comments
 (0)