static nsresult ParseType2Msg(const void *inBuf, uint32_t inLen, Type2Msg *msg) { // make sure inBuf is long enough to contain a meaningful type2 msg. // // 0 NTLMSSP Signature // 8 NTLM Message Type // 12 Target Name // 20 Flags // 24 Challenge // 32 targetInfo // 48 start of optional data blocks // if (inLen < NTLM_TYPE2_HEADER_LEN) return NS_ERROR_UNEXPECTED; const uint8_t *cursor = reinterpret_cast<const uint8_t*>(inBuf); // verify NTLMSSP signature if (memcmp(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) != 0) return NS_ERROR_UNEXPECTED; cursor += sizeof(NTLM_SIGNATURE); // verify Type-2 marker if (memcmp(cursor, NTLM_TYPE2_MARKER, sizeof(NTLM_TYPE2_MARKER)) != 0) return NS_ERROR_UNEXPECTED; cursor += sizeof(NTLM_TYPE2_MARKER); // Read target name security buffer: ... // ... read target length. uint32_t targetLen = ReadUint16(cursor); // ... skip next 16-bit "allocated space" value. ReadUint16(cursor); // ... read offset from inBuf. uint32_t offset = ReadUint32(cursor); mozilla::CheckedInt<uint32_t> targetEnd = offset; targetEnd += targetLen; // Check the offset / length combo is in range of the input buffer, including // integer overflow checking. if (MOZ_LIKELY(targetEnd.isValid() && targetEnd.value() <= inLen)) { msg->targetLen = targetLen; msg->target = reinterpret_cast<const uint8_t*>(inBuf) + offset; } else { // Do not error out, for (conservative) backward compatibility. msg->targetLen = 0; msg->target = nullptr; } // read flags msg->flags = ReadUint32(cursor); // read challenge memcpy(msg->challenge, cursor, sizeof(msg->challenge)); cursor += sizeof(msg->challenge); LOG(("NTLM type 2 message:\n")); LogBuf("target", reinterpret_cast<const uint8_t*> (msg->target), msg->targetLen); LogBuf("flags", reinterpret_cast<const uint8_t*> (&msg->flags), 4); LogFlags(msg->flags); LogBuf("challenge", msg->challenge, sizeof(msg->challenge)); // Read (and skip) the reserved field ReadUint32(cursor); ReadUint32(cursor); // Read target name security buffer: ... // ... read target length. uint32_t targetInfoLen = ReadUint16(cursor); // ... skip next 16-bit "allocated space" value. ReadUint16(cursor); // ... read offset from inBuf. offset = ReadUint32(cursor); mozilla::CheckedInt<uint32_t> targetInfoEnd = offset; targetInfoEnd += targetInfoLen; // Check the offset / length combo is in range of the input buffer, including // integer overflow checking. if (MOZ_LIKELY(targetInfoEnd.isValid() && targetInfoEnd.value() <= inLen)) { msg->targetInfoLen = targetInfoLen; msg->targetInfo = reinterpret_cast<const uint8_t*>(inBuf) + offset; } else { NS_ERROR("failed to get NTLMv2 target info"); return NS_ERROR_UNEXPECTED; } return NS_OK; }
/// Ctor. SingleLogger() : FileLogger(fn, LogFlags() << timestamp << sequence << thread #if defined BUFFERED_GLOBAL_LOGGING << buffer #endif ) {}