芝麻web文件管理V1.00
编辑当前文件:/home/freeclou/app.optimyar.com/backend/node_modules/mongodb/lib/core/auth/mongodb_aws.js
'use strict'; const AuthProvider = require('./auth_provider').AuthProvider; const MongoCredentials = require('./mongo_credentials').MongoCredentials; const MongoError = require('../error').MongoError; const crypto = require('crypto'); const http = require('http'); const maxWireVersion = require('../utils').maxWireVersion; const url = require('url'); let aws4; try { aws4 = require('aws4'); } catch (e) { // don't do anything; } const ASCII_N = 110; const AWS_RELATIVE_URI = 'http://169.254.170.2'; const AWS_EC2_URI = 'http://169.254.169.254'; const AWS_EC2_PATH = '/latest/meta-data/iam/security-credentials'; class MongoDBAWS extends AuthProvider { auth(authContext, callback) { const connection = authContext.connection; const credentials = authContext.credentials; if (maxWireVersion(connection) < 9) { callback(new MongoError('MONGODB-AWS authentication requires MongoDB version 4.4 or later')); return; } if (aws4 == null) { callback( new MongoError( 'MONGODB-AWS authentication requires the `aws4` module, please install it as a dependency of your project' ) ); return; } if (credentials.username == null) { makeTempCredentials(credentials, (err, tempCredentials) => { if (err) return callback(err); authContext.credentials = tempCredentials; this.auth(authContext, callback); }); return; } const username = credentials.username; const password = credentials.password; const db = credentials.source; const token = credentials.mechanismProperties.AWS_SESSION_TOKEN; const bson = this.bson; crypto.randomBytes(32, (err, nonce) => { if (err) { callback(err); return; } const saslStart = { saslStart: 1, mechanism: 'MONGODB-AWS', payload: bson.serialize({ r: nonce, p: ASCII_N }) }; connection.command(`${db}.$cmd`, saslStart, (err, result) => { if (err) return callback(err); const res = result.result; const serverResponse = bson.deserialize(res.payload.buffer); const host = serverResponse.h; const serverNonce = serverResponse.s.buffer; if (serverNonce.length !== 64) { callback( new MongoError(`Invalid server nonce length ${serverNonce.length}, expected 64`) ); return; } if (serverNonce.compare(nonce, 0, nonce.length, 0, nonce.length) !== 0) { callback(new MongoError('Server nonce does not begin with client nonce')); return; } if (host.length < 1 || host.length > 255 || host.indexOf('..') !== -1) { callback(new MongoError(`Server returned an invalid host: "${host}"`)); return; } const body = 'Action=GetCallerIdentity&Version=2011-06-15'; const options = aws4.sign( { method: 'POST', host, region: deriveRegion(serverResponse.h), service: 'sts', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': body.length, 'X-MongoDB-Server-Nonce': serverNonce.toString('base64'), 'X-MongoDB-GS2-CB-Flag': 'n' }, path: '/', body }, { accessKeyId: username, secretAccessKey: password, token } ); const authorization = options.headers.Authorization; const date = options.headers['X-Amz-Date']; const payload = { a: authorization, d: date }; if (token) { payload.t = token; } const saslContinue = { saslContinue: 1, conversationId: 1, payload: bson.serialize(payload) }; connection.command(`${db}.$cmd`, saslContinue, err => { if (err) return callback(err); callback(); }); }); }); } } function makeTempCredentials(credentials, callback) { function done(creds) { if (creds.AccessKeyId == null || creds.SecretAccessKey == null || creds.Token == null) { callback(new MongoError('Could not obtain temporary MONGODB-AWS credentials')); return; } callback( undefined, new MongoCredentials({ username: creds.AccessKeyId, password: creds.SecretAccessKey, source: credentials.source, mechanism: 'MONGODB-AWS', mechanismProperties: { AWS_SESSION_TOKEN: creds.Token } }) ); } // If the environment variable AWS_CONTAINER_CREDENTIALS_RELATIVE_URI // is set then drivers MUST assume that it was set by an AWS ECS agent if (process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) { request( `${AWS_RELATIVE_URI}${process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}`, (err, res) => { if (err) return callback(err); done(res); } ); return; } // Otherwise assume we are on an EC2 instance // get a token request( `${AWS_EC2_URI}/latest/api/token`, { method: 'PUT', json: false, headers: { 'X-aws-ec2-metadata-token-ttl-seconds': 30 } }, (err, token) => { if (err) return callback(err); // get role name request( `${AWS_EC2_URI}/${AWS_EC2_PATH}`, { json: false, headers: { 'X-aws-ec2-metadata-token': token } }, (err, roleName) => { if (err) return callback(err); // get temp credentials request( `${AWS_EC2_URI}/${AWS_EC2_PATH}/${roleName}`, { headers: { 'X-aws-ec2-metadata-token': token } }, (err, creds) => { if (err) return callback(err); done(creds); } ); } ); } ); } function deriveRegion(host) { const parts = host.split('.'); if (parts.length === 1 || parts[1] === 'amazonaws') { return 'us-east-1'; } return parts[1]; } function request(uri, options, callback) { if (typeof options === 'function') { callback = options; options = {}; } options = Object.assign( { method: 'GET', timeout: 10000, json: true }, url.parse(uri), options ); const req = http.request(options, res => { res.setEncoding('utf8'); let data = ''; res.on('data', d => (data += d)); res.on('end', () => { if (options.json === false) { callback(undefined, data); return; } try { const parsed = JSON.parse(data); callback(undefined, parsed); } catch (err) { callback(new MongoError(`Invalid JSON response: "${data}"`)); } }); }); req.on('error', err => callback(err)); req.end(); } module.exports = MongoDBAWS;