Software: Apache/2.4.41 (Ubuntu). PHP/8.0.30 uname -a: Linux apirnd 5.4.0-204-generic #224-Ubuntu SMP Thu Dec 5 13:38:28 UTC 2024 x86_64 uid=33(www-data) gid=33(www-data) groups=33(www-data) Safe-mode: OFF (not secure) /var/www/html/wincloud_gateway/node_modules/mongodb/lib/core/auth/ drwxr-xr-x | |
| Viewing file: Select action/file-type: '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;
|
:: Command execute :: | |
--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.037 ]-- |