aboutsummaryrefslogtreecommitdiff
path: root/node_modules/mysql2/lib/packets/handshake.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/mysql2/lib/packets/handshake.js')
-rw-r--r--node_modules/mysql2/lib/packets/handshake.js112
1 files changed, 112 insertions, 0 deletions
diff --git a/node_modules/mysql2/lib/packets/handshake.js b/node_modules/mysql2/lib/packets/handshake.js
new file mode 100644
index 0000000..239387c
--- /dev/null
+++ b/node_modules/mysql2/lib/packets/handshake.js
@@ -0,0 +1,112 @@
+'use strict';
+
+const Packet = require('../packets/packet');
+const ClientConstants = require('../constants/client.js');
+
+// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
+
+class Handshake {
+ constructor(args) {
+ this.protocolVersion = args.protocolVersion;
+ this.serverVersion = args.serverVersion;
+ this.capabilityFlags = args.capabilityFlags;
+ this.connectionId = args.connectionId;
+ this.authPluginData1 = args.authPluginData1;
+ this.authPluginData2 = args.authPluginData2;
+ this.characterSet = args.characterSet;
+ this.statusFlags = args.statusFlags;
+ this.autPluginName = args.autPluginName;
+ }
+
+ setScrambleData(cb) {
+ require('crypto').randomBytes(20, (err, data) => {
+ if (err) {
+ cb(err);
+ return;
+ }
+ this.authPluginData1 = data.slice(0, 8);
+ this.authPluginData2 = data.slice(8, 20);
+ cb();
+ });
+ }
+
+ toPacket(sequenceId) {
+ const length = 68 + Buffer.byteLength(this.serverVersion, 'utf8');
+ const buffer = Buffer.alloc(length + 4, 0); // zero fill, 10 bytes filler later needs to contain zeros
+ const packet = new Packet(sequenceId, buffer, 0, length + 4);
+ packet.offset = 4;
+ packet.writeInt8(this.protocolVersion);
+ packet.writeString(this.serverVersion, 'cesu8');
+ packet.writeInt8(0);
+ packet.writeInt32(this.connectionId);
+ packet.writeBuffer(this.authPluginData1);
+ packet.writeInt8(0);
+ const capabilityFlagsBuffer = Buffer.allocUnsafe(4);
+ capabilityFlagsBuffer.writeUInt32LE(this.capabilityFlags, 0);
+ packet.writeBuffer(capabilityFlagsBuffer.slice(0, 2));
+ packet.writeInt8(this.characterSet);
+ packet.writeInt16(this.statusFlags);
+ packet.writeBuffer(capabilityFlagsBuffer.slice(2, 4));
+ packet.writeInt8(21); // authPluginDataLength
+ packet.skip(10);
+ packet.writeBuffer(this.authPluginData2);
+ packet.writeInt8(0);
+ packet.writeString('mysql_native_password', 'latin1');
+ packet.writeInt8(0);
+ return packet;
+ }
+
+ static fromPacket(packet) {
+ const args = {};
+ args.protocolVersion = packet.readInt8();
+ args.serverVersion = packet.readNullTerminatedString('cesu8');
+ args.connectionId = packet.readInt32();
+ args.authPluginData1 = packet.readBuffer(8);
+ packet.skip(1);
+ const capabilityFlagsBuffer = Buffer.allocUnsafe(4);
+ capabilityFlagsBuffer[0] = packet.readInt8();
+ capabilityFlagsBuffer[1] = packet.readInt8();
+ if (packet.haveMoreData()) {
+ args.characterSet = packet.readInt8();
+ args.statusFlags = packet.readInt16();
+ // upper 2 bytes
+ capabilityFlagsBuffer[2] = packet.readInt8();
+ capabilityFlagsBuffer[3] = packet.readInt8();
+ args.capabilityFlags = capabilityFlagsBuffer.readUInt32LE(0);
+ if (args.capabilityFlags & ClientConstants.PLUGIN_AUTH) {
+ args.authPluginDataLength = packet.readInt8();
+ } else {
+ args.authPluginDataLength = 0;
+ packet.skip(1);
+ }
+ packet.skip(10);
+ } else {
+ args.capabilityFlags = capabilityFlagsBuffer.readUInt16LE(0);
+ }
+
+ const isSecureConnection =
+ args.capabilityFlags & ClientConstants.SECURE_CONNECTION;
+ if (isSecureConnection) {
+ const authPluginDataLength = args.authPluginDataLength;
+ if (authPluginDataLength === 0) {
+ // for Secure Password Authentication
+ args.authPluginDataLength = 20;
+ args.authPluginData2 = packet.readBuffer(12);
+ packet.skip(1);
+ } else {
+ // length > 0
+ // for Custom Auth Plugin (PLUGIN_AUTH)
+ const len = Math.max(13, authPluginDataLength - 8);
+ args.authPluginData2 = packet.readBuffer(len);
+ }
+ }
+
+ if (args.capabilityFlags & ClientConstants.PLUGIN_AUTH) {
+ args.autPluginName = packet.readNullTerminatedString('ascii');
+ }
+
+ return new Handshake(args);
+ }
+}
+
+module.exports = Handshake;