| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 | var Buffer = require('safe-buffer').Buffer;var Crypto = require('crypto');var Auth   = exports;function auth(name, data, options) {  options = options || {};  switch (name) {    case 'mysql_native_password':      return Auth.token(options.password, data.slice(0, 20));    default:      return undefined;  }}Auth.auth = auth;function sha1(msg) {  var hash = Crypto.createHash('sha1');  hash.update(msg, 'binary');  return hash.digest('binary');}Auth.sha1 = sha1;function xor(a, b) {  a = Buffer.from(a, 'binary');  b = Buffer.from(b, 'binary');  var result = Buffer.allocUnsafe(a.length);  for (var i = 0; i < a.length; i++) {    result[i] = (a[i] ^ b[i]);  }  return result;}Auth.xor = xor;Auth.token = function(password, scramble) {  if (!password) {    return Buffer.alloc(0);  }  // password must be in binary format, not utf8  var stage1 = sha1((Buffer.from(password, 'utf8')).toString('binary'));  var stage2 = sha1(stage1);  var stage3 = sha1(scramble.toString('binary') + stage2);  return xor(stage3, stage1);};// This is a port of sql/password.c:hash_password which needs to be used for// pre-4.1 passwords.Auth.hashPassword = function(password) {  var nr     = [0x5030, 0x5735];  var add    = 7;  var nr2    = [0x1234, 0x5671];  var result = Buffer.alloc(8);  if (typeof password === 'string'){    password = Buffer.from(password);  }  for (var i = 0; i < password.length; i++) {    var c = password[i];    if (c === 32 || c === 9) {      // skip space in password      continue;    }    // nr^= (((nr & 63)+add)*c)+ (nr << 8);    // nr = xor(nr, add(mul(add(and(nr, 63), add), c), shl(nr, 8)))    nr = this.xor32(nr, this.add32(this.mul32(this.add32(this.and32(nr, [0, 63]), [0, add]), [0, c]), this.shl32(nr, 8)));    // nr2+=(nr2 << 8) ^ nr;    // nr2 = add(nr2, xor(shl(nr2, 8), nr))    nr2 = this.add32(nr2, this.xor32(this.shl32(nr2, 8), nr));    // add+=tmp;    add += c;  }  this.int31Write(result, nr, 0);  this.int31Write(result, nr2, 4);  return result;};Auth.randomInit = function(seed1, seed2) {  return {    max_value     : 0x3FFFFFFF,    max_value_dbl : 0x3FFFFFFF,    seed1         : seed1 % 0x3FFFFFFF,    seed2         : seed2 % 0x3FFFFFFF  };};Auth.myRnd = function(r){  r.seed1 = (r.seed1 * 3 + r.seed2) % r.max_value;  r.seed2 = (r.seed1 + r.seed2 + 33) % r.max_value;  return r.seed1 / r.max_value_dbl;};Auth.scramble323 = function(message, password) {  if (!password) {    return Buffer.alloc(0);  }  var to          = Buffer.allocUnsafe(8);  var hashPass    = this.hashPassword(password);  var hashMessage = this.hashPassword(message.slice(0, 8));  var seed1       = this.int32Read(hashPass, 0) ^ this.int32Read(hashMessage, 0);  var seed2       = this.int32Read(hashPass, 4) ^ this.int32Read(hashMessage, 4);  var r           = this.randomInit(seed1, seed2);  for (var i = 0; i < 8; i++){    to[i] = Math.floor(this.myRnd(r) * 31) + 64;  }  var extra = (Math.floor(this.myRnd(r) * 31));  for (var i = 0; i < 8; i++){    to[i] ^= extra;  }  return to;};Auth.xor32 = function(a, b){  return [a[0] ^ b[0], a[1] ^ b[1]];};Auth.add32 = function(a, b){  var w1 = a[1] + b[1];  var w2 = a[0] + b[0] + ((w1 & 0xFFFF0000) >> 16);  return [w2 & 0xFFFF, w1 & 0xFFFF];};Auth.mul32 = function(a, b){  // based on this example of multiplying 32b ints using 16b  // http://www.dsprelated.com/showmessage/89790/1.php  var w1 = a[1] * b[1];  var w2 = (((a[1] * b[1]) >> 16) & 0xFFFF) + ((a[0] * b[1]) & 0xFFFF) + (a[1] * b[0] & 0xFFFF);  return [w2 & 0xFFFF, w1 & 0xFFFF];};Auth.and32 = function(a, b){  return [a[0] & b[0], a[1] & b[1]];};Auth.shl32 = function(a, b){  // assume b is 16 or less  var w1 = a[1] << b;  var w2 = (a[0] << b) | ((w1 & 0xFFFF0000) >> 16);  return [w2 & 0xFFFF, w1 & 0xFFFF];};Auth.int31Write = function(buffer, number, offset) {  buffer[offset] = (number[0] >> 8) & 0x7F;  buffer[offset + 1] = (number[0]) & 0xFF;  buffer[offset + 2] = (number[1] >> 8) & 0xFF;  buffer[offset + 3] = (number[1]) & 0xFF;};Auth.int32Read = function(buffer, offset){  return (buffer[offset] << 24)       + (buffer[offset + 1] << 16)       + (buffer[offset + 2] << 8)       + (buffer[offset + 3]);};
 |