void rfbVncAuthProcessResponse(rfbClientPtr cl)
{
  char passwdFullControl[MAXPWLEN + 1] = "\0";
  char passwdViewOnly[MAXPWLEN + 1] = "\0";
  int numPasswords;
  Bool ok;
  int n;
  CARD8 response[CHALLENGESIZE];

  n = ReadExact(cl, (char *)response, CHALLENGESIZE);
  if (n <= 0) {
    if (n != 0)
      rfbLogPerror("rfbVncAuthProcessResponse: read");
    rfbCloseClient(cl);
    return;
  }

  ok = FALSE;
  if (rfbOptOtpAuth()) {
    if (rfbAuthOTPValue == NULL) {
      if (nSecTypesEnabled == 1) {
        rfbClientAuthFailed(cl, "The one-time password has not been set on the server");
        return;
      }

    } else {
      memcpy(passwdFullControl, rfbAuthOTPValue, MAXPWLEN);
      passwdFullControl[MAXPWLEN] = '\0';
      numPasswords = rfbAuthOTPValueLen / MAXPWLEN;
      if (numPasswords > 1) {
        memcpy(passwdViewOnly, rfbAuthOTPValue + MAXPWLEN, MAXPWLEN);
        passwdViewOnly[MAXPWLEN] = '\0';
      }

      ok = CheckResponse(cl, numPasswords, passwdFullControl, passwdViewOnly,
                         response);
      if (ok) {
        memset(rfbAuthOTPValue, 0, rfbAuthOTPValueLen);
        free(rfbAuthOTPValue);
        rfbAuthOTPValue = NULL;
      }
    }
  }

  if ((ok == FALSE) && rfbOptRfbAuth()) {
    if (!rfbAuthPasswdFile) {
      rfbClientAuthFailed(cl, "No VNC password file specified on the server (did you forget -rfbauth?)");
      return;
    }

    numPasswords = vncDecryptPasswdFromFile2(rfbAuthPasswdFile,
                                             passwdFullControl,
                                             passwdViewOnly);
    if (numPasswords == 0) {
      rfbLog("rfbVncAuthProcessResponse: could not get password from %s\n",
             rfbAuthPasswdFile);

      if (nSecTypesEnabled == 1) {
        rfbClientAuthFailed(cl, "The server could not read the VNC password file");
        return;
      }
    }

    ok = CheckResponse(cl, numPasswords, passwdFullControl, passwdViewOnly,
                       response);
  }

  if (ok) {
    rfbAuthUnblock();
    rfbClientAuthSucceeded(cl, rfbAuthVNC);
  } else {
    rfbLog("rfbVncAuthProcessResponse: authentication failed from %s\n",
           cl->host);
    if (rfbAuthConsiderBlocking())
      rfbClientAuthFailed(cl, "Authentication failed.  Too many tries");
    else
      rfbClientAuthFailed(cl, "Authentication failed");
  }
}
void rfbVncAuthProcessResponse(rfbClientPtr cl)
{
  char passwdFullControl[MAXPWLEN + 1] = "\0";
  char passwdViewOnly[MAXPWLEN + 1] = "\0";
  int numPasswords;
  Bool ok;
  int n;
  CARD8 response[CHALLENGESIZE];

  n = ReadExact(cl, (char *)response, CHALLENGESIZE);
  if (n <= 0) {
    if (n != 0)
      rfbLogPerror("rfbVncAuthProcessResponse: read");
    rfbCloseClient(cl);
    return;
  }

  ok = FALSE;
  if (rfbOptOtpAuth()) {
    if (rfbAuthOTPValue == NULL) {
      if (nSecTypesEnabled == 1) {
        rfbClientAuthFailed(cl, "The one-time password has not been set on the server");
        return;
      }

    } else {
      memcpy(passwdFullControl, rfbAuthOTPValue, MAXPWLEN);
      passwdFullControl[MAXPWLEN] = '\0';
      numPasswords = rfbAuthOTPValueLen / MAXPWLEN;
      if (numPasswords > 1) {
        memcpy(passwdViewOnly, rfbAuthOTPValue + MAXPWLEN, MAXPWLEN);
        passwdViewOnly[MAXPWLEN] = '\0';
      }

      ok = CheckResponse(cl, numPasswords, passwdFullControl, passwdViewOnly,
                         response);
      if (ok) {
        memset(rfbAuthOTPValue, 0, rfbAuthOTPValueLen);
        free(rfbAuthOTPValue);
        rfbAuthOTPValue = NULL;
      }
    }
  }

  if ((ok == FALSE) && rfbOptRfbAuth()) {
    if (!rfbAuthPasswdFile) {
      rfbClientAuthFailed(cl, "No VNC password file specified on the server (did you forget -rfbauth?)");
      return;
    }

    numPasswords = vncDecryptPasswdFromFile2(rfbAuthPasswdFile,
                                             passwdFullControl,
                                             passwdViewOnly);
    if (numPasswords == 0) {
      rfbLog("rfbVncAuthProcessResponse: could not get password from %s\n",
             rfbAuthPasswdFile);

      if (nSecTypesEnabled == 1) {
        rfbClientAuthFailed(cl, "The server could not read the VNC password file");
        return;
      }
    }

    ok = CheckResponse(cl, numPasswords, passwdFullControl, passwdViewOnly,
                       response);
  }

  if (ok) {
    rfbAuthUnblock();
    rfbClientAuthSucceeded(cl, rfbAuthVNC);
  } else {
    rfbLog("rfbVncAuthProcessResponse: authentication failed from %s\n",
           cl->host);
    if (rfbAuthConsiderBlocking())
      rfbClientAuthFailed(cl, "Authentication failed.  Too many tries");
    else
      rfbClientAuthFailed(cl, "Authentication failed");
  }
}