Kuma/server/modules/axios-ntlm/lib/ntlm.js
Toby Liddicoat 9081025c4a Refactor modules for improved readability and consistency
Reformatted code across multiple modules, standardizing string quotes, indentation, and spacing. Improved readability by restructuring blocks and aligning object properties consistently. These changes ensure better code maintainability and follow standard conventions.

Signed-off-by: Toby Liddicoat <toby@codesure.co.uk>
2025-02-27 19:58:07 +00:00

226 lines
8.5 KiB
JavaScript

"use strict";
// Original file https://raw.githubusercontent.com/elasticio/node-ntlm-client/master/lib/ntlm.js
var os = require("os"), flags = require("./flags"), hash = require("./hash");
var NTLMSIGNATURE = "NTLMSSP\0";
function createType1Message(workstation, target) {
var dataPos = 32, pos = 0, buf = new Buffer.alloc(1024);
workstation = workstation === undefined ? os.hostname() : workstation;
target = target === undefined ? "" : target;
//signature
buf.write(NTLMSIGNATURE, pos, NTLMSIGNATURE.length, "ascii");
pos += NTLMSIGNATURE.length;
//message type
buf.writeUInt32LE(1, pos);
pos += 4;
//flags
buf.writeUInt32LE(flags.NTLMFLAG_NEGOTIATE_OEM |
flags.NTLMFLAG_REQUEST_TARGET |
flags.NTLMFLAG_NEGOTIATE_NTLM_KEY |
flags.NTLMFLAG_NEGOTIATE_NTLM2_KEY |
flags.NTLMFLAG_NEGOTIATE_ALWAYS_SIGN, pos);
pos += 4;
//domain security buffer
buf.writeUInt16LE(target.length, pos);
pos += 2;
buf.writeUInt16LE(target.length, pos);
pos += 2;
buf.writeUInt32LE(target.length === 0 ? 0 : dataPos, pos);
pos += 4;
if (target.length > 0) {
dataPos += buf.write(target, dataPos, "ascii");
}
//workstation security buffer
buf.writeUInt16LE(workstation.length, pos);
pos += 2;
buf.writeUInt16LE(workstation.length, pos);
pos += 2;
buf.writeUInt32LE(workstation.length === 0 ? 0 : dataPos, pos);
pos += 4;
if (workstation.length > 0) {
dataPos += buf.write(workstation, dataPos, "ascii");
}
return "NTLM " + buf.toString("base64", 0, dataPos);
}
function decodeType2Message(str) {
if (str === undefined) {
throw new Error("Invalid argument");
}
//convenience
if (Object.prototype.toString.call(str) !== "[object String]") {
if (str.hasOwnProperty("headers") && str.headers.hasOwnProperty("www-authenticate")) {
str = str.headers["www-authenticate"];
} else {
throw new Error("Invalid argument");
}
}
var ntlmMatch = /^NTLM ([^,\s]+)/.exec(str);
if (ntlmMatch) {
str = ntlmMatch[1];
}
var buf = new Buffer.from(str, "base64"), obj = {};
//check signature
if (buf.toString("ascii", 0, NTLMSIGNATURE.length) !== NTLMSIGNATURE) {
throw new Error("Invalid message signature: " + str);
}
//check message type
if (buf.readUInt32LE(NTLMSIGNATURE.length) !== 2) {
throw new Error("Invalid message type (no type 2)");
}
//read flags
obj.flags = buf.readUInt32LE(20);
obj.encoding = (obj.flags & flags.NTLMFLAG_NEGOTIATE_OEM) ? "ascii" : "ucs2";
obj.version = (obj.flags & flags.NTLMFLAG_NEGOTIATE_NTLM2_KEY) ? 2 : 1;
obj.challenge = buf.slice(24, 32);
//read target name
obj.targetName = (function () {
var length = buf.readUInt16LE(12);
//skipping allocated space
var offset = buf.readUInt32LE(16);
if (length === 0) {
return "";
}
if ((offset + length) > buf.length || offset < 32) {
throw new Error("Bad type 2 message");
}
return buf.toString(obj.encoding, offset, offset + length);
})();
//read target info
if (obj.flags & flags.NTLMFLAG_NEGOTIATE_TARGET_INFO) {
obj.targetInfo = (function () {
var info = {};
var length = buf.readUInt16LE(40);
//skipping allocated space
var offset = buf.readUInt32LE(44);
var targetInfoBuffer = new Buffer.alloc(length);
buf.copy(targetInfoBuffer, 0, offset, offset + length);
if (length === 0) {
return info;
}
if ((offset + length) > buf.length || offset < 32) {
throw new Error("Bad type 2 message");
}
var pos = offset;
while (pos < (offset + length)) {
var blockType = buf.readUInt16LE(pos);
pos += 2;
var blockLength = buf.readUInt16LE(pos);
pos += 2;
if (blockType === 0) {
//reached the terminator subblock
break;
}
var blockTypeStr = void 0;
switch (blockType) {
case 1:
blockTypeStr = "SERVER";
break;
case 2:
blockTypeStr = "DOMAIN";
break;
case 3:
blockTypeStr = "FQDN";
break;
case 4:
blockTypeStr = "DNS";
break;
case 5:
blockTypeStr = "PARENT_DNS";
break;
default:
blockTypeStr = "";
break;
}
if (blockTypeStr) {
info[blockTypeStr] = buf.toString("ucs2", pos, pos + blockLength);
}
pos += blockLength;
}
return {
parsed: info,
buffer: targetInfoBuffer,
};
})();
}
return obj;
}
function createType3Message(type2Message, username, password, workstation, target) {
var dataPos = 52, buf = new Buffer.alloc(1024);
if (workstation === undefined) {
workstation = os.hostname();
}
if (target === undefined) {
target = type2Message.targetName;
}
//signature
buf.write(NTLMSIGNATURE, 0, NTLMSIGNATURE.length, "ascii");
//message type
buf.writeUInt32LE(3, 8);
if (type2Message.version === 2) {
dataPos = 64;
var ntlmHash = hash.createNTLMHash(password), nonce = hash.createPseudoRandomValue(16),
lmv2 = hash.createLMv2Response(type2Message, username, ntlmHash, nonce, target),
ntlmv2 = hash.createNTLMv2Response(type2Message, username, ntlmHash, nonce, target);
//lmv2 security buffer
buf.writeUInt16LE(lmv2.length, 12);
buf.writeUInt16LE(lmv2.length, 14);
buf.writeUInt32LE(dataPos, 16);
lmv2.copy(buf, dataPos);
dataPos += lmv2.length;
//ntlmv2 security buffer
buf.writeUInt16LE(ntlmv2.length, 20);
buf.writeUInt16LE(ntlmv2.length, 22);
buf.writeUInt32LE(dataPos, 24);
ntlmv2.copy(buf, dataPos);
dataPos += ntlmv2.length;
} else {
var lmHash = hash.createLMHash(password), ntlmHash = hash.createNTLMHash(password),
lm = hash.createLMResponse(type2Message.challenge, lmHash),
ntlm = hash.createNTLMResponse(type2Message.challenge, ntlmHash);
//lm security buffer
buf.writeUInt16LE(lm.length, 12);
buf.writeUInt16LE(lm.length, 14);
buf.writeUInt32LE(dataPos, 16);
lm.copy(buf, dataPos);
dataPos += lm.length;
//ntlm security buffer
buf.writeUInt16LE(ntlm.length, 20);
buf.writeUInt16LE(ntlm.length, 22);
buf.writeUInt32LE(dataPos, 24);
ntlm.copy(buf, dataPos);
dataPos += ntlm.length;
}
//target name security buffer
buf.writeUInt16LE(type2Message.encoding === "ascii" ? target.length : target.length * 2, 28);
buf.writeUInt16LE(type2Message.encoding === "ascii" ? target.length : target.length * 2, 30);
buf.writeUInt32LE(dataPos, 32);
dataPos += buf.write(target, dataPos, type2Message.encoding);
//user name security buffer
buf.writeUInt16LE(type2Message.encoding === "ascii" ? username.length : username.length * 2, 36);
buf.writeUInt16LE(type2Message.encoding === "ascii" ? username.length : username.length * 2, 38);
buf.writeUInt32LE(dataPos, 40);
dataPos += buf.write(username, dataPos, type2Message.encoding);
//workstation name security buffer
buf.writeUInt16LE(type2Message.encoding === "ascii" ? workstation.length : workstation.length * 2, 44);
buf.writeUInt16LE(type2Message.encoding === "ascii" ? workstation.length : workstation.length * 2, 46);
buf.writeUInt32LE(dataPos, 48);
dataPos += buf.write(workstation, dataPos, type2Message.encoding);
if (type2Message.version === 2) {
//session key security buffer
buf.writeUInt16LE(0, 52);
buf.writeUInt16LE(0, 54);
buf.writeUInt32LE(0, 56);
//flags
buf.writeUInt32LE(type2Message.flags, 60);
}
return "NTLM " + buf.toString("base64", 0, dataPos);
}
module.exports = {
createType1Message: createType1Message,
decodeType2Message: decodeType2Message,
createType3Message: createType3Message,
};
//# sourceMappingURL=ntlm.js.map