function createType3Message()

in api/opensource/node-http-ntlm/ntlm.js [136:230]


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');
}