Skip to content

Commit 07616e4

Browse files
committed
Use newer TLS functions when available
This removes the deprecation warnings on node.js 0.11.13+ when using SSL. fixes #809
1 parent fd28786 commit 07616e4

File tree

3 files changed

+130
-67
lines changed

3 files changed

+130
-67
lines changed

lib/Connection.js

Lines changed: 68 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
var Crypto = require('crypto');
12
var Net = require('net');
3+
var tls = require('tls');
24
var ConnectionConfig = require('./ConnectionConfig');
35
var Protocol = require('./protocol/Protocol');
46
var SqlString = require('./protocol/SqlString');
@@ -209,40 +211,73 @@ Connection.prototype.format = function(sql, values) {
209211
return SqlString.format(sql, values, this.config.stringifyObjects, this.config.timezone);
210212
};
211213

214+
if (tls.TLSSocket) {
215+
// 0.11+ environment
216+
Connection.prototype._startTLS = function _startTLS(onSecure) {
217+
var secureContext = tls.createSecureContext({
218+
key : this.config.ssl.key,
219+
cert : this.config.ssl.cert,
220+
passphrase : this.config.ssl.passphrase,
221+
ca : this.config.ssl.ca
222+
});
212223

213-
Connection.prototype._startTLS = function(onSecure) {
214-
215-
var crypto = require('crypto');
216-
var tls = require('tls');
217-
218-
// before TLS:
219-
// _socket <-> _protocol
220-
// after:
221-
// _socket <-> securePair.encrypted <-> securePair.cleartext <-> _protocol
222-
223-
var credentials = crypto.createCredentials({
224-
key: this.config.ssl.key,
225-
cert: this.config.ssl.cert,
226-
passphrase: this.config.ssl.passphrase,
227-
ca: this.config.ssl.ca
228-
});
229-
230-
var securePair = tls.createSecurePair(credentials, false);
231-
232-
securePair.encrypted.pipe(this._socket);
233-
securePair.cleartext.pipe(this._protocol);
234-
235-
// TODO: change to unpipe/pipe (does not work for some reason. Streams1/2 conflict?)
236-
this._socket.removeAllListeners('data');
237-
this._protocol.removeAllListeners('data');
238-
this._socket.on('data', function(data) {
239-
securePair.encrypted.write(data);
240-
});
241-
this._protocol.on('data', function(data) {
242-
securePair.cleartext.write(data);
243-
});
244-
securePair.on('secure', onSecure);
245-
};
224+
// "unpipe"
225+
this._socket.removeAllListeners('data');
226+
this._protocol.removeAllListeners('data');
227+
228+
// socket <-> encrypted
229+
var secureSocket = new tls.TLSSocket(this._socket, {
230+
secureContext : secureContext,
231+
isServer : false
232+
});
233+
234+
// cleartext <-> protocol
235+
secureSocket.pipe(this._protocol);
236+
this._protocol.on('data', function(data) {
237+
secureSocket.write(data);
238+
});
239+
240+
secureSocket.on('secure', onSecure);
241+
242+
// start TLS communications
243+
secureSocket._start();
244+
};
245+
} else {
246+
// pre-0.11 environment
247+
Connection.prototype._startTLS = function _startTLS(onSecure) {
248+
// before TLS:
249+
// _socket <-> _protocol
250+
// after:
251+
// _socket <-> securePair.encrypted <-> securePair.cleartext <-> _protocol
252+
253+
var credentials = Crypto.createCredentials({
254+
key : this.config.ssl.key,
255+
cert : this.config.ssl.cert,
256+
passphrase : this.config.ssl.passphrase,
257+
ca : this.config.ssl.ca
258+
});
259+
260+
var securePair = tls.createSecurePair(credentials, false);
261+
262+
// "unpipe"
263+
this._socket.removeAllListeners('data');
264+
this._protocol.removeAllListeners('data');
265+
266+
// socket <-> encrypted
267+
securePair.encrypted.pipe(this._socket);
268+
this._socket.on('data', function(data) {
269+
securePair.encrypted.write(data);
270+
});
271+
272+
// cleartext <-> protocol
273+
securePair.cleartext.pipe(this._protocol);
274+
this._protocol.on('data', function(data) {
275+
securePair.cleartext.write(data);
276+
});
277+
278+
securePair.on('secure', onSecure);
279+
};
280+
}
246281

247282
Connection.prototype._handleConnectTimeout = function() {
248283
if (this._socket) {

test/FakeServer.js

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
var common = require('./common');
55
var _ = require('underscore');
6+
var Crypto = require('crypto');
67
var Net = require('net');
8+
var tls = require('tls');
79
var Packets = require('../lib/protocol/packets');
810
var PacketWriter = require('../lib/protocol/PacketWriter');
911
var Parser = require('../lib/protocol/Parser');
@@ -102,11 +104,10 @@ FakeConnection.prototype._handleData = function(buffer) {
102104
};
103105

104106
FakeConnection.prototype._parsePacket = function(header) {
105-
var Packet = this._determinePacket(header);
106-
var packet = new Packet({protocol41: true});
107-
var parser = this._parser;
107+
var Packet = this._determinePacket(header);
108+
var packet = new Packet({protocol41: true});
108109

109-
packet.parse(parser);
110+
packet.parse(this._parser);
110111

111112
switch (Packet) {
112113
case Packets.ClientAuthenticationPacket:
@@ -120,29 +121,11 @@ FakeConnection.prototype._parsePacket = function(header) {
120121
throw new Error('not implemented');
121122
} else {
122123
this._sendPacket(new Packets.OkPacket());
123-
parser.resetPacketNumber();
124+
this._parser.resetPacketNumber();
124125
}
125126
break;
126127
case Packets.SSLRequestPacket:
127-
// halt parser
128-
parser.pause();
129-
this._socket.removeAllListeners('data');
130-
131-
// inject secure pair
132-
var securePair = common.createSecurePair();
133-
this._socket.pipe(securePair.encrypted);
134-
this._stream = securePair.cleartext;
135-
securePair.cleartext.on('data', this._handleData.bind(this));
136-
securePair.encrypted.pipe(this._socket);
137-
138-
// resume
139-
process.nextTick(function() {
140-
var buffer = parser._buffer.slice(parser._offset);
141-
parser._offset = parser._buffer.length;
142-
parser.resume();
143-
securePair.encrypted.write(buffer);
144-
});
145-
128+
this._startTLS();
146129
break;
147130
case Packets.OldPasswordPacket:
148131
this._oldPasswordPacket = packet;
@@ -156,7 +139,7 @@ FakeConnection.prototype._parsePacket = function(header) {
156139
break;
157140
case Packets.ComPingPacket:
158141
this._sendPacket(new Packets.OkPacket());
159-
parser.resetPacketNumber();
142+
this._parser.resetPacketNumber();
160143
break;
161144
case Packets.ComChangeUserPacket:
162145
this._clientAuthenticationPacket = new Packets.ClientAuthenticationPacket({
@@ -170,7 +153,7 @@ FakeConnection.prototype._parsePacket = function(header) {
170153
user : packet.user
171154
});
172155
this._sendPacket(new Packets.OkPacket());
173-
parser.resetPacketNumber();
156+
this._parser.resetPacketNumber();
174157
break;
175158
case Packets.ComQuitPacket:
176159
this.emit('quit', packet);
@@ -211,3 +194,56 @@ FakeConnection.prototype._determinePacket = function(header) {
211194
FakeConnection.prototype.destroy = function() {
212195
this._socket.destroy();
213196
};
197+
198+
if (tls.TLSSocket) {
199+
// 0.11+ environment
200+
FakeConnection.prototype._startTLS = function _startTLS() {
201+
// halt parser
202+
this._parser.pause();
203+
this._socket.removeAllListeners('data');
204+
205+
// socket <-> encrypted
206+
var secureContext = tls.createSecureContext(common.getSSLConfig());
207+
var secureSocket = new tls.TLSSocket(this._socket, {
208+
secureContext : secureContext,
209+
isServer : true
210+
});
211+
212+
// cleartext <-> protocol
213+
secureSocket.on('data', this._handleData.bind(this));
214+
this._stream = secureSocket;
215+
216+
// resume
217+
var parser = this._parser;
218+
process.nextTick(function() {
219+
var buffer = parser._buffer.slice(parser._offset);
220+
parser._offset = parser._buffer.length;
221+
parser.resume();
222+
secureSocket.ssl.receive(buffer);
223+
});
224+
};
225+
} else {
226+
// pre-0.11 environment
227+
FakeConnection.prototype._startTLS = function _startTLS() {
228+
// halt parser
229+
this._parser.pause();
230+
this._socket.removeAllListeners('data');
231+
232+
// inject secure pair
233+
var credentials = Crypto.createCredentials(common.getSSLConfig());
234+
var securePair = tls.createSecurePair(credentials, true);
235+
this._socket.pipe(securePair.encrypted);
236+
this._stream = securePair.cleartext;
237+
securePair.cleartext.on('data', this._handleData.bind(this));
238+
securePair.encrypted.pipe(this._socket);
239+
240+
// resume
241+
var parser = this._parser;
242+
process.nextTick(function() {
243+
var buffer = parser._buffer.slice(parser._offset);
244+
parser._offset = parser._buffer.length;
245+
parser.resume();
246+
securePair.encrypted.write(buffer);
247+
});
248+
};
249+
}

test/common.js

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
var common = exports;
2-
var crypto = require('crypto');
32
var fs = require('fs');
43
var path = require('path');
5-
var tls = require('tls');
64
var _ = require('underscore');
75
var FakeServer = require('./FakeServer');
86

@@ -48,12 +46,6 @@ common.createFakeServer = function(options) {
4846
return new FakeServer(_.extend({}, options));
4947
};
5048

51-
common.createSecurePair = function() {
52-
var credentials = crypto.createCredentials(common.getSSLConfig());
53-
54-
return tls.createSecurePair(credentials, true);
55-
};
56-
5749
common.useTestDb = function(connection) {
5850
var query = connection.query('CREATE DATABASE ' + common.testDatabase, function(err) {
5951
if (err && err.code !== 'ER_DB_CREATE_EXISTS') throw err;

0 commit comments

Comments
 (0)