amt-manager-test
Version:
Intel AMT Management Tool - Control power states of AMT-enabled devices
82 lines (81 loc) • 3.61 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseAuthHeader = parseAuthHeader;
exports.constructDigestAuthHeader = constructDigestAuthHeader;
exports.getDigestHeader = getDigestHeader;
const crypto_1 = __importDefault(require("crypto"));
const node_fetch_1 = __importDefault(require("node-fetch"));
// Parse the WWW-Authenticate header to get necessary parts
function parseAuthHeader(authHeader) {
const regex = /(\w+)="([^"]+)"/g;
const authParams = {
realm: '',
nonce: ''
};
let match;
while (match = regex.exec(authHeader)) {
authParams[match[1]] = match[2];
}
if (!authParams.realm || !authParams.nonce) {
throw new Error('Missing required digest authentication parameters');
}
return authParams;
}
// Construct the Digest Authorization header
function constructDigestAuthHeader(authParams, options) {
const { realm, nonce } = authParams;
const { url, username, password, method = 'POST' } = options;
// Generate cnonce and nc (nonce count)
const cnonce = crypto_1.default.randomBytes(16).toString('hex');
const nc = '00000001';
const qop = 'auth';
// Create A1 and A2 hashes (used in Digest calculation)
const A1 = `${username}:${realm}:${password}`;
const A2 = `${method}:${url}`;
const ha1 = crypto_1.default.createHash('md5').update(A1).digest('hex');
const ha2 = crypto_1.default.createHash('md5').update(A2).digest('hex');
// Generate the response hash (Digest Authentication response)
const response = crypto_1.default.createHash('md5').update(`${ha1}:${nonce}:${nc}:${cnonce}:${qop}:${ha2}`).digest('hex');
// Construct the final Digest Authorization header
return `Digest username="${username}", realm="${realm}", nonce="${nonce}", uri="${url}", cnonce="${cnonce}", nc=${nc}, qop=${qop}, response="${response}"`;
}
/**
* Get a Digest Authentication header for a given URL and credentials
* @param options Configuration options for digest authentication
* @returns Promise resolving to the Digest Authorization header
*/
async function getDigestHeader(options) {
const { url, username, password, method = 'GET', headers = {}, retryCount = 0, maxRetries = 3 } = options;
try {
const response = await (0, node_fetch_1.default)(url, {
method,
headers: {
'User-Agent': 'node-fetch',
'Accept': '*/*',
...headers
},
});
const wwwAuthenticate = response.headers.get('www-authenticate');
if (!wwwAuthenticate) {
throw new Error('No WWW-Authenticate header received');
}
// Parse the Digest Authentication challenge
const authParams = parseAuthHeader(wwwAuthenticate);
const digestHeader = constructDigestAuthHeader(authParams, { url, username, password, method });
return digestHeader;
}
catch (error) {
console.error('Error in getting WWW-Authenticate header:', error);
// Retry logic for connection issues
if (retryCount < maxRetries) {
const delay = Math.pow(2, retryCount) * 1000;
console.log(`Retrying in ${delay}ms... (Attempt ${retryCount + 1}/${maxRetries})`);
await new Promise(resolve => setTimeout(resolve, delay));
return getDigestHeader({ ...options, retryCount: retryCount + 1 });
}
return undefined;
}
}