auth_switch.js 3.6 KB

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