aboutsummaryrefslogtreecommitdiff
path: root/node_modules/mysql2/lib/packets/handshake_response.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/mysql2/lib/packets/handshake_response.js')
-rw-r--r--node_modules/mysql2/lib/packets/handshake_response.js145
1 files changed, 145 insertions, 0 deletions
diff --git a/node_modules/mysql2/lib/packets/handshake_response.js b/node_modules/mysql2/lib/packets/handshake_response.js
new file mode 100644
index 0000000..b2dee38
--- /dev/null
+++ b/node_modules/mysql2/lib/packets/handshake_response.js
@@ -0,0 +1,145 @@
+'use strict';
+
+const ClientConstants = require('../constants/client.js');
+const CharsetToEncoding = require('../constants/charset_encodings.js');
+const Packet = require('../packets/packet.js');
+
+const auth41 = require('../auth_41.js');
+
+class HandshakeResponse {
+ constructor(handshake) {
+ this.user = handshake.user || '';
+ this.database = handshake.database || '';
+ this.password = handshake.password || '';
+ this.passwordSha1 = handshake.passwordSha1;
+ this.authPluginData1 = handshake.authPluginData1;
+ this.authPluginData2 = handshake.authPluginData2;
+ this.compress = handshake.compress;
+ this.clientFlags = handshake.flags;
+ // TODO: pre-4.1 auth support
+ let authToken;
+ if (this.passwordSha1) {
+ authToken = auth41.calculateTokenFromPasswordSha(
+ this.passwordSha1,
+ this.authPluginData1,
+ this.authPluginData2
+ );
+ } else {
+ authToken = auth41.calculateToken(
+ this.password,
+ this.authPluginData1,
+ this.authPluginData2
+ );
+ }
+ this.authToken = authToken;
+ this.charsetNumber = handshake.charsetNumber;
+ this.encoding = CharsetToEncoding[handshake.charsetNumber];
+ this.connectAttributes = handshake.connectAttributes;
+ }
+
+ serializeResponse(buffer) {
+ const isSet = flag => this.clientFlags & ClientConstants[flag];
+ const packet = new Packet(0, buffer, 0, buffer.length);
+ packet.offset = 4;
+ packet.writeInt32(this.clientFlags);
+ packet.writeInt32(0); // max packet size. todo: move to config
+ packet.writeInt8(this.charsetNumber);
+ packet.skip(23);
+ const encoding = this.encoding;
+ packet.writeNullTerminatedString(this.user, encoding);
+ let k;
+ if (isSet('PLUGIN_AUTH_LENENC_CLIENT_DATA')) {
+ packet.writeLengthCodedNumber(this.authToken.length);
+ packet.writeBuffer(this.authToken);
+ } else if (isSet('SECURE_CONNECTION')) {
+ packet.writeInt8(this.authToken.length);
+ packet.writeBuffer(this.authToken);
+ } else {
+ packet.writeBuffer(this.authToken);
+ packet.writeInt8(0);
+ }
+ if (isSet('CONNECT_WITH_DB')) {
+ packet.writeNullTerminatedString(this.database, encoding);
+ }
+ if (isSet('PLUGIN_AUTH')) {
+ // TODO: pass from config
+ packet.writeNullTerminatedString('mysql_native_password', 'latin1');
+ }
+ if (isSet('CONNECT_ATTRS')) {
+ const connectAttributes = this.connectAttributes || {};
+ const attrNames = Object.keys(connectAttributes);
+ let keysLength = 0;
+ for (k = 0; k < attrNames.length; ++k) {
+ keysLength += Packet.lengthCodedStringLength(attrNames[k], encoding);
+ keysLength += Packet.lengthCodedStringLength(
+ connectAttributes[attrNames[k]],
+ encoding
+ );
+ }
+ packet.writeLengthCodedNumber(keysLength);
+ for (k = 0; k < attrNames.length; ++k) {
+ packet.writeLengthCodedString(attrNames[k], encoding);
+ packet.writeLengthCodedString(
+ connectAttributes[attrNames[k]],
+ encoding
+ );
+ }
+ }
+ return packet;
+ }
+
+ toPacket() {
+ if (typeof this.user !== 'string') {
+ throw new Error('"user" connection config property must be a string');
+ }
+ if (typeof this.database !== 'string') {
+ throw new Error('"database" connection config property must be a string');
+ }
+ // dry run: calculate resulting packet length
+ const p = this.serializeResponse(Packet.MockBuffer());
+ return this.serializeResponse(Buffer.alloc(p.offset));
+ }
+ static fromPacket(packet) {
+ const args = {};
+ args.clientFlags = packet.readInt32();
+ function isSet(flag) {
+ return args.clientFlags & ClientConstants[flag];
+ }
+ args.maxPacketSize = packet.readInt32();
+ args.charsetNumber = packet.readInt8();
+ const encoding = CharsetToEncoding[args.charsetNumber];
+ args.encoding = encoding;
+ packet.skip(23);
+ args.user = packet.readNullTerminatedString(encoding);
+ let authTokenLength;
+ if (isSet('PLUGIN_AUTH_LENENC_CLIENT_DATA')) {
+ authTokenLength = packet.readLengthCodedNumber(encoding);
+ args.authToken = packet.readBuffer(authTokenLength);
+ } else if (isSet('SECURE_CONNECTION')) {
+ authTokenLength = packet.readInt8();
+ args.authToken = packet.readBuffer(authTokenLength);
+ } else {
+ args.authToken = packet.readNullTerminatedString(encoding);
+ }
+ if (isSet('CONNECT_WITH_DB')) {
+ args.database = packet.readNullTerminatedString(encoding);
+ }
+ if (isSet('PLUGIN_AUTH')) {
+ args.authPluginName = packet.readNullTerminatedString(encoding);
+ }
+ if (isSet('CONNECT_ATTRS')) {
+ const keysLength = packet.readLengthCodedNumber(encoding);
+ const keysEnd = packet.offset + keysLength;
+ const attrs = {};
+ while (packet.offset < keysEnd) {
+ attrs[
+ packet.readLengthCodedString(encoding)
+ ] = packet.readLengthCodedString(encoding);
+ }
+ args.connectAttributes = attrs;
+ }
+ return args;
+ }
+}
+
+module.exports = HandshakeResponse;