auth_switch.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // This file was modified by Oracle on July 5, 2021.
  2. // Errors generated by asynchronous authentication plugins are now being
  3. // handled and subsequently emitted at the command level.
  4. // Modifications copyright (c) 2021, Oracle and/or its affiliates.
  5. 'use strict';
  6. const Packets = require('../packets/index.js');
  7. const sha256_password = require('../auth_plugins/sha256_password');
  8. const caching_sha2_password = require('../auth_plugins/caching_sha2_password.js');
  9. const mysql_native_password = require('../auth_plugins/mysql_native_password.js');
  10. const standardAuthPlugins = {
  11. sha256_password: sha256_password({}),
  12. caching_sha2_password: caching_sha2_password({}),
  13. mysql_native_password: mysql_native_password({})
  14. };
  15. function warnLegacyAuthSwitch() {
  16. console.warn(
  17. 'WARNING! authSwitchHandler api is deprecated, please use new authPlugins api'
  18. );
  19. }
  20. function authSwitchPluginError(error, command) {
  21. // Authentication errors are fatal
  22. error.code = 'AUTH_SWITCH_PLUGIN_ERROR';
  23. error.fatal = true;
  24. command.emit('error', error);
  25. }
  26. function authSwitchRequest(packet, connection, command) {
  27. const { pluginName, pluginData } = Packets.AuthSwitchRequest.fromPacket(
  28. packet
  29. );
  30. let authPlugin =
  31. connection.config.authPlugins && connection.config.authPlugins[pluginName];
  32. // legacy plugin api don't allow to override mysql_native_password
  33. // if pluginName is mysql_native_password it's using standard auth4.1 auth
  34. if (
  35. connection.config.authSwitchHandler &&
  36. pluginName !== 'mysql_native_password'
  37. ) {
  38. const legacySwitchHandler = connection.config.authSwitchHandler;
  39. warnLegacyAuthSwitch();
  40. legacySwitchHandler({ pluginName, pluginData }, (err, data) => {
  41. if (err) {
  42. return authSwitchPluginError(err, command);
  43. }
  44. connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
  45. });
  46. return;
  47. }
  48. if (!authPlugin) {
  49. authPlugin = standardAuthPlugins[pluginName];
  50. }
  51. if (!authPlugin) {
  52. throw new Error(
  53. `Server requests authentication using unknown plugin ${pluginName}. See ${'TODO: add plugins doco here'} on how to configure or author authentication plugins.`
  54. );
  55. }
  56. connection._authPlugin = authPlugin({ connection, command });
  57. Promise.resolve(connection._authPlugin(pluginData)).then(data => {
  58. if (data) {
  59. connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
  60. }
  61. }).catch(err => {
  62. authSwitchPluginError(err, command);
  63. });
  64. }
  65. function authSwitchRequestMoreData(packet, connection, command) {
  66. const { data } = Packets.AuthSwitchRequestMoreData.fromPacket(packet);
  67. if (connection.config.authSwitchHandler) {
  68. const legacySwitchHandler = connection.config.authSwitchHandler;
  69. warnLegacyAuthSwitch();
  70. legacySwitchHandler({ pluginData: data }, (err, data) => {
  71. if (err) {
  72. return authSwitchPluginError(err, command);
  73. }
  74. connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
  75. });
  76. return;
  77. }
  78. if (!connection._authPlugin) {
  79. throw new Error(
  80. 'AuthPluginMoreData received but no auth plugin instance found'
  81. );
  82. }
  83. Promise.resolve(connection._authPlugin(data)).then(data => {
  84. if (data) {
  85. connection.writePacket(new Packets.AuthSwitchResponse(data).toPacket());
  86. }
  87. }).catch(err => {
  88. authSwitchPluginError(err, command);
  89. });
  90. }
  91. module.exports = {
  92. authSwitchRequest,
  93. authSwitchRequestMoreData
  94. };