123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- '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;
|