UNPKG

mysql2

Version:

fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS

130 lines (113 loc) 4.27 kB
// This file was modified by Oracle on July 5, 2021. // Errors generated by asynchronous authentication plugins are now being // handled and subsequently emitted at the command level. // Modifications copyright (c) 2021, Oracle and/or its affiliates. 'use strict'; const Packets = require('../packets/index.js'); const sha256_password = require('../auth_plugins/sha256_password'); const caching_sha2_password = require('../auth_plugins/caching_sha2_password.js'); const mysql_native_password = require('../auth_plugins/mysql_native_password.js'); const mysql_clear_password = require('../auth_plugins/mysql_clear_password.js'); // Use Object.create(null) to avoid prototype pollution // This prevents server-controlled pluginName values like "toString" or "__proto__" // from resolving to prototype properties const standardAuthPlugins = Object.assign(Object.create(null), { sha256_password: sha256_password({}), caching_sha2_password: caching_sha2_password({}), mysql_native_password: mysql_native_password({}), mysql_clear_password: mysql_clear_password({}), }); // Helper function to get auth plugin (custom or standard) function getAuthPlugin(pluginName, connection) { const customPlugins = connection.config.authPlugins; // Check custom plugins with hasOwnProperty for safety if ( customPlugins && Object.prototype.hasOwnProperty.call(customPlugins, pluginName) ) { return customPlugins[pluginName]; } // Safe to access standardAuthPlugins directly since it has no prototype return standardAuthPlugins[pluginName]; } function warnLegacyAuthSwitch() { console.warn( 'WARNING! authSwitchHandler api is deprecated, please use new authPlugins api' ); } function authSwitchPluginError(error, command) { // Authentication errors are fatal error.code = 'AUTH_SWITCH_PLUGIN_ERROR'; error.fatal = true; command.emit('error', error); } function authSwitchRequest(packet, connection, command) { const { pluginName, pluginData } = Packets.AuthSwitchRequest.fromPacket(packet); // legacy plugin api don't allow to override mysql_native_password // if pluginName is mysql_native_password it's using standard auth4.1 auth if ( connection.config.authSwitchHandler && pluginName !== 'mysql_native_password' ) { const legacySwitchHandler = connection.config.authSwitchHandler; warnLegacyAuthSwitch(); legacySwitchHandler({ pluginName, pluginData }, (err, data) => { if (err) { return authSwitchPluginError(err, command); } connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket()); }); return; } const authPlugin = getAuthPlugin(pluginName, connection); if (!authPlugin) { throw new Error( `Server requests authentication using unknown plugin ${pluginName}. See ${'TODO: add plugins doco here'} on how to configure or author authentication plugins.` ); } connection._authPlugin = authPlugin({ connection, command }); Promise.resolve(connection._authPlugin(pluginData)) .then((data) => { if (data) { connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket()); } }) .catch((err) => { authSwitchPluginError(err, command); }); } function authSwitchRequestMoreData(packet, connection, command) { const { data } = Packets.AuthSwitchRequestMoreData.fromPacket(packet); if (connection.config.authSwitchHandler) { const legacySwitchHandler = connection.config.authSwitchHandler; warnLegacyAuthSwitch(); legacySwitchHandler({ pluginData: data }, (err, data) => { if (err) { return authSwitchPluginError(err, command); } connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket()); }); return; } if (!connection._authPlugin) { throw new Error( 'AuthPluginMoreData received but no auth plugin instance found' ); } Promise.resolve(connection._authPlugin(data)) .then((data) => { if (data) { connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket()); } }) .catch((err) => { authSwitchPluginError(err, command); }); } module.exports = { authSwitchRequest, authSwitchRequestMoreData, getAuthPlugin, standardAuthPlugins, };