Example #1
0
  /**
   * Notifies this <tt>StunCandidateHarvest</tt> that a specific STUN <tt>Request</tt> has been
   * challenged for a long-term credential (as the short-term credential mechanism does not utilize
   * challenging) in a specific <tt>realm</tt> and with a specific <tt>nonce</tt>.
   *
   * @param realm the realm in which the specified STUN <tt>Request</tt> has been challenged for a
   *     long-term credential
   * @param nonce the nonce with which the specified STUN <tt>Request</tt> has been challenged for a
   *     long-term credential
   * @param request the STUN <tt>Request</tt> which has been challenged for a long-term credential
   * @param requestTransactionID the <tt>TransactionID</tt> of <tt>request</tt> because
   *     <tt>request</tt> only has it as a <tt>byte</tt> array and <tt>TransactionID</tt> is
   *     required for the <tt>applicationData</tt> property value
   * @return <tt>true</tt> if the challenge has been processed and this
   *     <tt>StunCandidateHarvest</tt> is to continue processing STUN <tt>Response</tt>s; otherwise,
   *     <tt>false</tt>
   * @throws StunException if anything goes wrong while processing the challenge
   */
  private boolean processChallenge(
      byte[] realm, byte[] nonce, Request request, TransactionID requestTransactionID)
      throws StunException {
    UsernameAttribute usernameAttribute =
        (UsernameAttribute) request.getAttribute(Attribute.USERNAME);

    if (usernameAttribute == null) {
      if (longTermCredentialSession == null) {
        LongTermCredential longTermCredential = harvester.createLongTermCredential(this, realm);

        if (longTermCredential == null) {
          // The long-term credential mechanism is not being utilized.
          return false;
        } else {
          longTermCredentialSession = new LongTermCredentialSession(longTermCredential, realm);
          harvester
              .getStunStack()
              .getCredentialsManager()
              .registerAuthority(longTermCredentialSession);
        }
      } else {
        /*
         * If we're going to use the long-term credential to retry the
         * request, the long-term credential should be for the request
         * in terms of realm.
         */
        if (!longTermCredentialSession.realmEquals(realm)) return false;
      }
    } else {
      /*
       * If we sent a USERNAME in our request, then we had the long-term
       * credential at the time we sent the request in question.
       */
      if (longTermCredentialSession == null) return false;
      else {
        /*
         * If we're going to use the long-term credential to retry the
         * request, the long-term credential should be for the request
         * in terms of username.
         */
        if (!longTermCredentialSession.usernameEquals(usernameAttribute.getUsername()))
          return false;
        else {
          // And it terms of realm, of course.
          if (!longTermCredentialSession.realmEquals(realm)) return false;
        }
      }
    }

    /*
     * The nonce is either becoming known for the first time or being
     * updated after the old one has gone stale.
     */
    longTermCredentialSession.setNonce(nonce);

    Request retryRequest = createRequestToRetry(request);
    TransactionID retryRequestTransactionID = null;

    if (retryRequest != null) {
      if (requestTransactionID != null) {
        Object applicationData = requestTransactionID.getApplicationData();

        if (applicationData != null) {
          byte[] retryRequestTransactionIDAsBytes = retryRequest.getTransactionID();

          retryRequestTransactionID =
              (retryRequestTransactionIDAsBytes == null)
                  ? TransactionID.createNewTransactionID()
                  : TransactionID.createTransactionID(
                      harvester.getStunStack(), retryRequestTransactionIDAsBytes);
          retryRequestTransactionID.setApplicationData(applicationData);
        }
      }
      retryRequestTransactionID = sendRequest(retryRequest, false, retryRequestTransactionID);
    }
    return (retryRequestTransactionID != null);
  }