sspi.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. 'use strict';
  2. const AuthProvider = require('./auth_provider').AuthProvider;
  3. const retrieveKerberos = require('../utils').retrieveKerberos;
  4. let kerberos;
  5. /**
  6. * Creates a new SSPI authentication mechanism
  7. * @class
  8. * @extends AuthProvider
  9. */
  10. class SSPI extends AuthProvider {
  11. /**
  12. * Implementation of authentication for a single connection
  13. * @override
  14. */
  15. _authenticateSingleConnection(sendAuthCommand, connection, credentials, callback) {
  16. // TODO: Destructure this
  17. const username = credentials.username;
  18. const password = credentials.password;
  19. const mechanismProperties = credentials.mechanismProperties;
  20. const gssapiServiceName =
  21. mechanismProperties['gssapiservicename'] ||
  22. mechanismProperties['gssapiServiceName'] ||
  23. 'mongodb';
  24. SSIPAuthenticate(
  25. this,
  26. kerberos.processes.MongoAuthProcess,
  27. username,
  28. password,
  29. gssapiServiceName,
  30. sendAuthCommand,
  31. connection,
  32. mechanismProperties,
  33. callback
  34. );
  35. }
  36. /**
  37. * Authenticate
  38. * @override
  39. * @method
  40. */
  41. auth(sendAuthCommand, connections, credentials, callback) {
  42. if (kerberos == null) {
  43. try {
  44. kerberos = retrieveKerberos();
  45. } catch (e) {
  46. return callback(e, null);
  47. }
  48. }
  49. super.auth(sendAuthCommand, connections, credentials, callback);
  50. }
  51. }
  52. function SSIPAuthenticate(
  53. self,
  54. MongoAuthProcess,
  55. username,
  56. password,
  57. gssapiServiceName,
  58. sendAuthCommand,
  59. connection,
  60. options,
  61. callback
  62. ) {
  63. const authProcess = new MongoAuthProcess(
  64. connection.host,
  65. connection.port,
  66. gssapiServiceName,
  67. options
  68. );
  69. function authCommand(command, authCb) {
  70. sendAuthCommand(connection, '$external.$cmd', command, authCb);
  71. }
  72. authProcess.init(username, password, err => {
  73. if (err) return callback(err, false);
  74. authProcess.transition('', (err, payload) => {
  75. if (err) return callback(err, false);
  76. const command = {
  77. saslStart: 1,
  78. mechanism: 'GSSAPI',
  79. payload,
  80. autoAuthorize: 1
  81. };
  82. authCommand(command, (err, doc) => {
  83. if (err) return callback(err, false);
  84. authProcess.transition(doc.payload, (err, payload) => {
  85. if (err) return callback(err, false);
  86. const command = {
  87. saslContinue: 1,
  88. conversationId: doc.conversationId,
  89. payload
  90. };
  91. authCommand(command, (err, doc) => {
  92. if (err) return callback(err, false);
  93. authProcess.transition(doc.payload, (err, payload) => {
  94. if (err) return callback(err, false);
  95. const command = {
  96. saslContinue: 1,
  97. conversationId: doc.conversationId,
  98. payload
  99. };
  100. authCommand(command, (err, response) => {
  101. if (err) return callback(err, false);
  102. authProcess.transition(null, err => {
  103. if (err) return callback(err, null);
  104. callback(null, response);
  105. });
  106. });
  107. });
  108. });
  109. });
  110. });
  111. });
  112. });
  113. }
  114. module.exports = SSPI;