/**
   * Validate the MD4 hash against local password
   *
   * @param type3Msg Type3NTLMMessage
   * @param ntlmDetails NTLMLogonDetails
   * @param authenticated boolean
   * @param md4hash String
   * @return true if password hash is valid, false otherwise
   */
  protected boolean validateLocalHashedPassword(
      Type3NTLMMessage type3Msg,
      NTLMLogonDetails ntlmDetails,
      boolean authenticated,
      String md4hash) {
    // Make sure we have hte cached NTLM details, including the type2 message with the server
    // challenge

    if (ntlmDetails == null || ntlmDetails.getType2Message() == null) {
      // DEBUG

      if (getLogger().isDebugEnabled())
        getLogger().debug("No cached Type2, ntlmDetails=" + ntlmDetails);

      // Not authenticated

      return false;
    }

    //  Determine if the client sent us NTLMv1 or NTLMv2
    if (type3Msg.hasFlag(NTLM.FlagNTLM2Key)) {
      //  Determine if the client sent us an NTLMv2 blob or an NTLMv2 session key
      if (type3Msg.getNTLMHashLength() > 24) {
        //  Looks like an NTLMv2 blob
        authenticated = checkNTLMv2(md4hash, ntlmDetails.getChallengeKey(), type3Msg);

        if (getLogger().isDebugEnabled())
          getLogger()
              .debug((authenticated ? "Logged on" : "Logon failed") + " using NTLMSSP/NTLMv2");

        // If the NTlmv2 autentication failed then check if the client has sent an NTLMv1 hash

        if (authenticated == false
            && type3Msg.hasFlag(NTLM.Flag56Bit)
            && type3Msg.getLMHashLength() == 24) {
          // Check the LM hash field

          authenticated = checkNTLMv1(md4hash, ntlmDetails.getChallengeKey(), type3Msg, true);

          // DEBUG

          if (getLogger().isDebugEnabled())
            getLogger()
                .debug(
                    (authenticated ? "Logged on" : "Logon failed")
                        + " using NTLMSSP/NTLMv1 (via fallback)");
        }
      } else {
        //  Looks like an NTLMv2 session key
        authenticated = checkNTLMv2SessionKey(md4hash, ntlmDetails.getChallengeKey(), type3Msg);

        if (getLogger().isDebugEnabled())
          getLogger()
              .debug(
                  (authenticated ? "Logged on" : "Logon failed") + " using NTLMSSP/NTLMv2SessKey");
      }
    } else {
      //  Looks like an NTLMv1 blob
      authenticated = checkNTLMv1(md4hash, ntlmDetails.getChallengeKey(), type3Msg, false);

      if (getLogger().isDebugEnabled())
        getLogger().debug((authenticated ? "Logged on" : "Logon failed") + " using NTLMSSP/NTLMv1");
    }
    return authenticated;
  }