mirror of
https://github.com/kennethreitz/bake.git
synced 2026-06-05 23:00:17 +00:00
cleanup
This commit is contained in:
Generated
Vendored
+390
@@ -0,0 +1,390 @@
|
||||
var crypto = require('crypto');
|
||||
|
||||
var flags = {
|
||||
NTLM_NegotiateUnicode : 0x00000001,
|
||||
NTLM_NegotiateOEM : 0x00000002,
|
||||
NTLM_RequestTarget : 0x00000004,
|
||||
NTLM_Unknown9 : 0x00000008,
|
||||
NTLM_NegotiateSign : 0x00000010,
|
||||
NTLM_NegotiateSeal : 0x00000020,
|
||||
NTLM_NegotiateDatagram : 0x00000040,
|
||||
NTLM_NegotiateLanManagerKey : 0x00000080,
|
||||
NTLM_Unknown8 : 0x00000100,
|
||||
NTLM_NegotiateNTLM : 0x00000200,
|
||||
NTLM_NegotiateNTOnly : 0x00000400,
|
||||
NTLM_Anonymous : 0x00000800,
|
||||
NTLM_NegotiateOemDomainSupplied : 0x00001000,
|
||||
NTLM_NegotiateOemWorkstationSupplied : 0x00002000,
|
||||
NTLM_Unknown6 : 0x00004000,
|
||||
NTLM_NegotiateAlwaysSign : 0x00008000,
|
||||
NTLM_TargetTypeDomain : 0x00010000,
|
||||
NTLM_TargetTypeServer : 0x00020000,
|
||||
NTLM_TargetTypeShare : 0x00040000,
|
||||
NTLM_NegotiateExtendedSecurity : 0x00080000,
|
||||
NTLM_NegotiateIdentify : 0x00100000,
|
||||
NTLM_Unknown5 : 0x00200000,
|
||||
NTLM_RequestNonNTSessionKey : 0x00400000,
|
||||
NTLM_NegotiateTargetInfo : 0x00800000,
|
||||
NTLM_Unknown4 : 0x01000000,
|
||||
NTLM_NegotiateVersion : 0x02000000,
|
||||
NTLM_Unknown3 : 0x04000000,
|
||||
NTLM_Unknown2 : 0x08000000,
|
||||
NTLM_Unknown1 : 0x10000000,
|
||||
NTLM_Negotiate128 : 0x20000000,
|
||||
NTLM_NegotiateKeyExchange : 0x40000000,
|
||||
NTLM_Negotiate56 : 0x80000000
|
||||
};
|
||||
var typeflags = {
|
||||
NTLM_TYPE1_FLAGS : flags.NTLM_NegotiateUnicode
|
||||
+ flags.NTLM_NegotiateOEM
|
||||
+ flags.NTLM_RequestTarget
|
||||
+ flags.NTLM_NegotiateNTLM
|
||||
+ flags.NTLM_NegotiateOemDomainSupplied
|
||||
+ flags.NTLM_NegotiateOemWorkstationSupplied
|
||||
+ flags.NTLM_NegotiateAlwaysSign
|
||||
+ flags.NTLM_NegotiateExtendedSecurity
|
||||
+ flags.NTLM_NegotiateVersion
|
||||
+ flags.NTLM_Negotiate128
|
||||
+ flags.NTLM_Negotiate56,
|
||||
|
||||
NTLM_TYPE2_FLAGS : flags.NTLM_NegotiateUnicode
|
||||
+ flags.NTLM_RequestTarget
|
||||
+ flags.NTLM_NegotiateNTLM
|
||||
+ flags.NTLM_NegotiateAlwaysSign
|
||||
+ flags.NTLM_NegotiateExtendedSecurity
|
||||
+ flags.NTLM_NegotiateTargetInfo
|
||||
+ flags.NTLM_NegotiateVersion
|
||||
+ flags.NTLM_Negotiate128
|
||||
+ flags.NTLM_Negotiate56
|
||||
};
|
||||
|
||||
function createType1Message(options){
|
||||
var domain = escape(options.domain.toUpperCase());
|
||||
var workstation = escape(options.workstation.toUpperCase());
|
||||
var protocol = 'NTLMSSP\0';
|
||||
|
||||
var BODY_LENGTH = 40;
|
||||
|
||||
var type1flags = typeflags.NTLM_TYPE1_FLAGS;
|
||||
if(!domain || domain === '')
|
||||
type1flags = type1flags - flags.NTLM_NegotiateOemDomainSupplied;
|
||||
|
||||
var pos = 0;
|
||||
var buf = new Buffer(BODY_LENGTH + domain.length + workstation.length);
|
||||
|
||||
|
||||
buf.write(protocol, pos, protocol.length); pos += protocol.length; // protocol
|
||||
buf.writeUInt32LE(1, pos); pos += 4; // type 1
|
||||
buf.writeUInt32LE(type1flags, pos); pos += 4; // TYPE1 flag
|
||||
|
||||
buf.writeUInt16LE(domain.length, pos); pos += 2; // domain length
|
||||
buf.writeUInt16LE(domain.length, pos); pos += 2; // domain max length
|
||||
buf.writeUInt32LE(BODY_LENGTH + workstation.length, pos); pos += 4; // domain buffer offset
|
||||
|
||||
buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation length
|
||||
buf.writeUInt16LE(workstation.length, pos); pos += 2; // workstation max length
|
||||
buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; // workstation buffer offset
|
||||
|
||||
buf.writeUInt8(5, pos); pos += 1; //ProductMajorVersion
|
||||
buf.writeUInt8(1, pos); pos += 1; //ProductMinorVersion
|
||||
buf.writeUInt16LE(2600, pos); pos += 2; //ProductBuild
|
||||
|
||||
buf.writeUInt8(0 , pos); pos += 1; //VersionReserved1
|
||||
buf.writeUInt8(0 , pos); pos += 1; //VersionReserved2
|
||||
buf.writeUInt8(0 , pos); pos += 1; //VersionReserved3
|
||||
buf.writeUInt8(15, pos); pos += 1; //NTLMRevisionCurrent
|
||||
|
||||
buf.write(workstation, pos, workstation.length, 'ascii'); pos += workstation.length; // workstation string
|
||||
buf.write(domain , pos, domain.length , 'ascii'); pos += domain.length;
|
||||
|
||||
return 'NTLM ' + buf.toString('base64');
|
||||
}
|
||||
|
||||
function parseType2Message(rawmsg, callback){
|
||||
var match = rawmsg.match(/NTLM (.+)?/);
|
||||
if(!match || !match[1])
|
||||
return callback(new Error("Couldn't find NTLM in the message type2 comming from the server"));
|
||||
|
||||
var buf = new Buffer(match[1], 'base64');
|
||||
|
||||
var msg = {};
|
||||
|
||||
msg.signature = buf.slice(0, 8);
|
||||
msg.type = buf.readInt16LE(8);
|
||||
|
||||
if(msg.type != 2)
|
||||
return callback(new Error("Server didn't return a type 2 message"));
|
||||
|
||||
msg.targetNameLen = buf.readInt16LE(12);
|
||||
msg.targetNameMaxLen = buf.readInt16LE(14);
|
||||
msg.targetNameOffset = buf.readInt32LE(16);
|
||||
msg.targetName = buf.slice(msg.targetNameOffset, msg.targetNameOffset + msg.targetNameMaxLen);
|
||||
|
||||
msg.negotiateFlags = buf.readInt32LE(20);
|
||||
msg.serverChallenge = buf.slice(24, 32);
|
||||
msg.reserved = buf.slice(32, 40);
|
||||
|
||||
if(msg.negotiateFlags & flags.NTLM_NegotiateTargetInfo){
|
||||
msg.targetInfoLen = buf.readInt16LE(40);
|
||||
msg.targetInfoMaxLen = buf.readInt16LE(42);
|
||||
msg.targetInfoOffset = buf.readInt32LE(44);
|
||||
msg.targetInfo = buf.slice(msg.targetInfoOffset, msg.targetInfoOffset + msg.targetInfoLen);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
function createType3Message(msg2, options){
|
||||
var nonce = msg2.serverChallenge;
|
||||
var username = options.username;
|
||||
var password = options.password;
|
||||
var negotiateFlags = msg2.negotiateFlags;
|
||||
|
||||
var isUnicode = negotiateFlags & flags.NTLM_NegotiateUnicode;
|
||||
var isNegotiateExtendedSecurity = negotiateFlags & flags.NTLM_NegotiateExtendedSecurity;
|
||||
|
||||
var BODY_LENGTH = 72;
|
||||
|
||||
var domainName = escape(options.domain.toUpperCase());
|
||||
var workstation = escape(options.workstation.toUpperCase());
|
||||
|
||||
var workstationBytes, domainNameBytes, usernameBytes, encryptedRandomSessionKeyBytes;
|
||||
|
||||
var encryptedRandomSessionKey = "";
|
||||
if(isUnicode){
|
||||
workstationBytes = new Buffer(workstation, 'utf16le');
|
||||
domainNameBytes = new Buffer(domainName, 'utf16le');
|
||||
usernameBytes = new Buffer(username, 'utf16le');
|
||||
encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'utf16le');
|
||||
}else{
|
||||
workstationBytes = new Buffer(workstation, 'ascii');
|
||||
domainNameBytes = new Buffer(domainName, 'ascii');
|
||||
usernameBytes = new Buffer(username, 'ascii');
|
||||
encryptedRandomSessionKeyBytes = new Buffer(encryptedRandomSessionKey, 'ascii');
|
||||
}
|
||||
|
||||
var lmChallengeResponse = calc_resp(create_LM_hashed_password_v1(password), nonce);
|
||||
var ntChallengeResponse = calc_resp(create_NT_hashed_password_v1(password), nonce);
|
||||
|
||||
if(isNegotiateExtendedSecurity){
|
||||
var pwhash = create_NT_hashed_password_v1(password);
|
||||
var clientChallenge = "";
|
||||
for(var i=0; i < 8; i++){
|
||||
clientChallenge += String.fromCharCode( Math.floor(Math.random()*256) );
|
||||
}
|
||||
var clientChallengeBytes = new Buffer(clientChallenge, 'ascii');
|
||||
var challenges = ntlm2sr_calc_resp(pwhash, nonce, clientChallengeBytes);
|
||||
lmChallengeResponse = challenges.lmChallengeResponse;
|
||||
ntChallengeResponse = challenges.ntChallengeResponse;
|
||||
}
|
||||
|
||||
var signature = 'NTLMSSP\0';
|
||||
|
||||
var pos = 0;
|
||||
var buf = new Buffer(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length + encryptedRandomSessionKeyBytes.length);
|
||||
|
||||
buf.write(signature, pos, signature.length); pos += signature.length;
|
||||
buf.writeUInt32LE(3, pos); pos += 4; // type 1
|
||||
|
||||
buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseLen
|
||||
buf.writeUInt16LE(lmChallengeResponse.length, pos); pos += 2; // LmChallengeResponseMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length, pos); pos += 4; // LmChallengeResponseOffset
|
||||
|
||||
buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseLen
|
||||
buf.writeUInt16LE(ntChallengeResponse.length, pos); pos += 2; // NtChallengeResponseMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length, pos); pos += 4; // NtChallengeResponseOffset
|
||||
|
||||
buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameLen
|
||||
buf.writeUInt16LE(domainNameBytes.length, pos); pos += 2; // DomainNameMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH, pos); pos += 4; // DomainNameOffset
|
||||
|
||||
buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameLen
|
||||
buf.writeUInt16LE(usernameBytes.length, pos); pos += 2; // UserNameMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length, pos); pos += 4; // UserNameOffset
|
||||
|
||||
buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationLen
|
||||
buf.writeUInt16LE(workstationBytes.length, pos); pos += 2; // WorkstationMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length, pos); pos += 4; // WorkstationOffset
|
||||
|
||||
buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyLen
|
||||
buf.writeUInt16LE(encryptedRandomSessionKeyBytes.length, pos); pos += 2; // EncryptedRandomSessionKeyMaxLen
|
||||
buf.writeUInt32LE(BODY_LENGTH + domainNameBytes.length + usernameBytes.length + workstationBytes.length + lmChallengeResponse.length + ntChallengeResponse.length, pos); pos += 4; // EncryptedRandomSessionKeyOffset
|
||||
|
||||
buf.writeUInt32LE(typeflags.NTLM_TYPE2_FLAGS, pos); pos += 4; // NegotiateFlags
|
||||
|
||||
buf.writeUInt8(5, pos); pos++; // ProductMajorVersion
|
||||
buf.writeUInt8(1, pos); pos++; // ProductMinorVersion
|
||||
buf.writeUInt16LE(2600, pos); pos += 2; // ProductBuild
|
||||
buf.writeUInt8(0, pos); pos++; // VersionReserved1
|
||||
buf.writeUInt8(0, pos); pos++; // VersionReserved2
|
||||
buf.writeUInt8(0, pos); pos++; // VersionReserved3
|
||||
buf.writeUInt8(15, pos); pos++; // NTLMRevisionCurrent
|
||||
|
||||
domainNameBytes.copy(buf, pos); pos += domainNameBytes.length;
|
||||
usernameBytes.copy(buf, pos); pos += usernameBytes.length;
|
||||
workstationBytes.copy(buf, pos); pos += workstationBytes.length;
|
||||
lmChallengeResponse.copy(buf, pos); pos += lmChallengeResponse.length;
|
||||
ntChallengeResponse.copy(buf, pos); pos += ntChallengeResponse.length;
|
||||
encryptedRandomSessionKeyBytes.copy(buf, pos); pos += encryptedRandomSessionKeyBytes.length;
|
||||
|
||||
return 'NTLM ' + buf.toString('base64');
|
||||
}
|
||||
|
||||
function create_LM_hashed_password_v1(password){
|
||||
// fix the password length to 14 bytes
|
||||
password = password.toUpperCase();
|
||||
var passwordBytes = new Buffer(password, 'ascii');
|
||||
|
||||
var passwordBytesPadded = new Buffer(14);
|
||||
passwordBytesPadded.fill("\0");
|
||||
var sourceEnd = 14;
|
||||
if(passwordBytes.length < 14) sourceEnd = passwordBytes.length;
|
||||
passwordBytes.copy(passwordBytesPadded, 0, 0, sourceEnd);
|
||||
|
||||
// split into 2 parts of 7 bytes:
|
||||
var firstPart = passwordBytesPadded.slice(0,7);
|
||||
var secondPart = passwordBytesPadded.slice(7);
|
||||
|
||||
function encrypt(buf){
|
||||
var key = insertZerosEvery7Bits(buf);
|
||||
var des = crypto.createCipheriv('DES-ECB', key, '');
|
||||
return des.update("KGS!@#$%"); // page 57 in [MS-NLMP]);
|
||||
}
|
||||
|
||||
var firstPartEncrypted = encrypt(firstPart);
|
||||
var secondPartEncrypted = encrypt(secondPart);
|
||||
|
||||
return Buffer.concat([firstPartEncrypted, secondPartEncrypted]);
|
||||
}
|
||||
|
||||
function insertZerosEvery7Bits(buf){
|
||||
var binaryArray = bytes2binaryArray(buf);
|
||||
var newBinaryArray = [];
|
||||
for(var i=0; i<binaryArray.length; i++){
|
||||
newBinaryArray.push(binaryArray[i]);
|
||||
|
||||
if((i+1)%7 === 0){
|
||||
newBinaryArray.push(0);
|
||||
}
|
||||
}
|
||||
return binaryArray2bytes(newBinaryArray);
|
||||
}
|
||||
|
||||
function bytes2binaryArray(buf){
|
||||
var hex2binary = {
|
||||
0: [0,0,0,0],
|
||||
1: [0,0,0,1],
|
||||
2: [0,0,1,0],
|
||||
3: [0,0,1,1],
|
||||
4: [0,1,0,0],
|
||||
5: [0,1,0,1],
|
||||
6: [0,1,1,0],
|
||||
7: [0,1,1,1],
|
||||
8: [1,0,0,0],
|
||||
9: [1,0,0,1],
|
||||
A: [1,0,1,0],
|
||||
B: [1,0,1,1],
|
||||
C: [1,1,0,0],
|
||||
D: [1,1,0,1],
|
||||
E: [1,1,1,0],
|
||||
F: [1,1,1,1]
|
||||
};
|
||||
|
||||
var hexString = buf.toString('hex').toUpperCase();
|
||||
var array = [];
|
||||
for(var i=0; i<hexString.length; i++){
|
||||
var hexchar = hexString.charAt(i);
|
||||
array = array.concat(hex2binary[hexchar]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
function binaryArray2bytes(array){
|
||||
var binary2hex = {
|
||||
'0000': 0,
|
||||
'0001': 1,
|
||||
'0010': 2,
|
||||
'0011': 3,
|
||||
'0100': 4,
|
||||
'0101': 5,
|
||||
'0110': 6,
|
||||
'0111': 7,
|
||||
'1000': 8,
|
||||
'1001': 9,
|
||||
'1010': 'A',
|
||||
'1011': 'B',
|
||||
'1100': 'C',
|
||||
'1101': 'D',
|
||||
'1110': 'E',
|
||||
'1111': 'F'
|
||||
};
|
||||
|
||||
var bufArray = [];
|
||||
|
||||
for(var i=0; i<array.length; i +=8 ){
|
||||
if((i+7) > array.length)
|
||||
break;
|
||||
|
||||
var binString1 = '' + array[i] + '' + array[i+1] + '' + array[i+2] + '' + array[i+3];
|
||||
var binString2 = '' + array[i+4] + '' + array[i+5] + '' + array[i+6] + '' + array[i+7];
|
||||
var hexchar1 = binary2hex[binString1];
|
||||
var hexchar2 = binary2hex[binString2];
|
||||
|
||||
var buf = new Buffer(hexchar1 + '' + hexchar2, 'hex');
|
||||
bufArray.push(buf);
|
||||
}
|
||||
|
||||
return Buffer.concat(bufArray);
|
||||
}
|
||||
|
||||
function create_NT_hashed_password_v1(password){
|
||||
var buf = new Buffer(password, 'utf16le');
|
||||
var md4 = crypto.createHash('md4');
|
||||
md4.update(buf);
|
||||
return new Buffer(md4.digest());
|
||||
}
|
||||
|
||||
function calc_resp(password_hash, server_challenge){
|
||||
// padding with zeros to make the hash 21 bytes long
|
||||
var passHashPadded = new Buffer(21);
|
||||
passHashPadded.fill("\0");
|
||||
password_hash.copy(passHashPadded, 0, 0, password_hash.length);
|
||||
|
||||
var resArray = [];
|
||||
|
||||
var des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(0,7)), '');
|
||||
resArray.push( des.update(server_challenge.slice(0,8)) );
|
||||
|
||||
des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(7,14)), '');
|
||||
resArray.push( des.update(server_challenge.slice(0,8)) );
|
||||
|
||||
des = crypto.createCipheriv('DES-ECB', insertZerosEvery7Bits(passHashPadded.slice(14,21)), '');
|
||||
resArray.push( des.update(server_challenge.slice(0,8)) );
|
||||
|
||||
return Buffer.concat(resArray);
|
||||
}
|
||||
|
||||
function ntlm2sr_calc_resp(responseKeyNT, serverChallenge, clientChallenge){
|
||||
// padding with zeros to make the hash 16 bytes longer
|
||||
var lmChallengeResponse = new Buffer(clientChallenge.length + 16);
|
||||
lmChallengeResponse.fill("\0");
|
||||
clientChallenge.copy(lmChallengeResponse, 0, 0, clientChallenge.length);
|
||||
|
||||
var buf = Buffer.concat([serverChallenge, clientChallenge]);
|
||||
var md5 = crypto.createHash('md5');
|
||||
md5.update(buf);
|
||||
var sess = md5.digest();
|
||||
var ntChallengeResponse = calc_resp(responseKeyNT, sess.slice(0,8));
|
||||
|
||||
return {
|
||||
lmChallengeResponse: lmChallengeResponse,
|
||||
ntChallengeResponse: ntChallengeResponse
|
||||
};
|
||||
}
|
||||
|
||||
exports.createType1Message = createType1Message;
|
||||
exports.parseType2Message = parseType2Message;
|
||||
exports.createType3Message = createType3Message;
|
||||
|
||||
|
||||
|
||||
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
// This software (ntlm.js) was copied from a file of the same name at https://github.com/SamDecrock/node-http-ntlm/blob/master/ntlm.js.
|
||||
//
|
||||
// As of this writing, it is a part of the node-http-ntlm module produced by SamDecrock.
|
||||
//
|
||||
// It is used as a part of the NTLM support provided by the azure-devops-node-api library.
|
||||
//
|
||||
Reference in New Issue
Block a user