/**
   * Event is enqueued only if necessary : - socks proxies do not need the reconnection feature so
   * events are always forwarded for these. - http proxies events will be enqueued while handshake
   * has not been completed or until connection was closed. If connection was prematurely closed
   * previous events are discarded and only the session closed is delivered.
   *
   * @param evt the event to enqueue
   */
  public void enqueueEventIfNecessary(final IoSessionEvent evt) {
    logger.debug("??? >> Enqueue {}", evt);

    if (proxyIoSession.getRequest() instanceof SocksProxyRequest) {
      // No reconnection used
      evt.deliverEvent();
      return;
    }

    if (proxyIoSession.getHandler().isHandshakeComplete()) {
      evt.deliverEvent();
    } else {
      if (evt.getType() == IoSessionEventType.CLOSED) {
        if (proxyIoSession.isAuthenticationFailed()) {
          proxyIoSession.getConnector().cancelConnectFuture();
          discardSessionQueueEvents();
          evt.deliverEvent();
        } else {
          discardSessionQueueEvents();
        }
      } else if (evt.getType() == IoSessionEventType.OPENED) {
        // Enqueue event cause it will not reach IoHandler but deliver it to enable
        // session creation.
        enqueueSessionEvent(evt);
        evt.deliverEvent();
      } else {
        enqueueSessionEvent(evt);
      }
    }
  }
Example #2
0
  /**
   * Computes the response to the DIGEST challenge.
   *
   * @param session the current session
   * @param map the map holding the directives sent by the proxy
   * @param method the HTTP verb
   * @param pwd the password
   * @param charsetName the name of the charset used for the challenge
   * @param body the html body to be hashed for integrity calculations
   */
  public static String computeResponseValue(
      IoSession session,
      HashMap<String, String> map,
      String method,
      String pwd,
      String charsetName,
      String body)
      throws AuthenticationException, UnsupportedEncodingException {

    byte[] hA1;
    StringBuilder sb;
    boolean isMD5Sess =
        "md5-sess".equalsIgnoreCase(StringUtilities.getDirectiveValue(map, "algorithm", false));

    if (!isMD5Sess || (session.getAttribute(SESSION_HA1) == null)) {
      // Build A1
      sb = new StringBuilder();
      sb.append(
              StringUtilities.stringTo8859_1(
                  StringUtilities.getDirectiveValue(map, "username", true)))
          .append(':');

      String realm =
          StringUtilities.stringTo8859_1(StringUtilities.getDirectiveValue(map, "realm", false));
      if (realm != null) {
        sb.append(realm);
      }

      sb.append(':').append(pwd);

      if (isMD5Sess) {
        byte[] prehA1;
        synchronized (md5) {
          md5.reset();
          prehA1 = md5.digest(sb.toString().getBytes(charsetName));
        }

        sb = new StringBuilder();
        sb.append(ByteUtilities.asHex(prehA1));
        sb.append(':')
            .append(
                StringUtilities.stringTo8859_1(
                    StringUtilities.getDirectiveValue(map, "nonce", true)));
        sb.append(':')
            .append(
                StringUtilities.stringTo8859_1(
                    StringUtilities.getDirectiveValue(map, "cnonce", true)));

        synchronized (md5) {
          md5.reset();
          hA1 = md5.digest(sb.toString().getBytes(charsetName));
        }

        session.setAttribute(SESSION_HA1, hA1);
      } else {
        synchronized (md5) {
          md5.reset();
          hA1 = md5.digest(sb.toString().getBytes(charsetName));
        }
      }
    } else {
      hA1 = (byte[]) session.getAttribute(SESSION_HA1);
    }

    sb = new StringBuilder(method);
    sb.append(':');
    sb.append(StringUtilities.getDirectiveValue(map, "uri", false));

    String qop = StringUtilities.getDirectiveValue(map, "qop", false);
    if ("auth-int".equalsIgnoreCase(qop)) {
      ProxyIoSession proxyIoSession =
          (ProxyIoSession) session.getAttribute(ProxyIoSession.PROXY_SESSION);
      byte[] hEntity;

      synchronized (md5) {
        md5.reset();
        hEntity = md5.digest(body.getBytes(proxyIoSession.getCharsetName()));
      }
      sb.append(':').append(hEntity);
    }

    byte[] hA2;
    synchronized (md5) {
      md5.reset();
      hA2 = md5.digest(sb.toString().getBytes(charsetName));
    }

    sb = new StringBuilder();
    sb.append(ByteUtilities.asHex(hA1));
    sb.append(':').append(StringUtilities.getDirectiveValue(map, "nonce", true));
    sb.append(":00000001:");

    sb.append(StringUtilities.getDirectiveValue(map, "cnonce", true));
    sb.append(':').append(qop).append(':');
    sb.append(ByteUtilities.asHex(hA2));

    byte[] hFinal;
    synchronized (md5) {
      md5.reset();
      hFinal = md5.digest(sb.toString().getBytes(charsetName));
    }

    return ByteUtilities.asHex(hFinal);
  }