private void validateResponse(ClientUpgradeResponse response) {
    // Check the Accept hash
    String reqKey = request.getKey();
    String expectedHash = AcceptHash.hashKey(reqKey);
    response.validateWebSocketHash(expectedHash);

    // Parse extensions
    List<ExtensionConfig> extensions = new ArrayList<>();
    List<String> extValues = response.getHeaders("Sec-WebSocket-Extensions");
    if (extValues != null) {
      for (String extVal : extValues) {
        QuotedStringTokenizer tok = new QuotedStringTokenizer(extVal, ",");
        while (tok.hasMoreTokens()) {
          extensions.add(ExtensionConfig.parse(tok.nextToken()));
        }
      }
    }
    response.setExtensions(extensions);
  }
  /**
   * @param context
   * @param descriptor
   * @param node
   */
  public void visitContextParam(WebAppContext context, Descriptor descriptor, XmlParser.Node node)
      throws Exception {
    String name = node.getString("param-name", false, true);
    String value = node.getString("param-value", false, true);
    List<String> values = new ArrayList<>();

    // extract values
    switch (name) {
      case ServletContext.ORDERED_LIBS:
      case AnnotationConfiguration.CONTAINER_INITIALIZERS:
      case MetaInfConfiguration.METAINF_TLDS:
      case MetaInfConfiguration.METAINF_RESOURCES:
        context.removeAttribute(name);

        QuotedStringTokenizer tok = new QuotedStringTokenizer(value, ",");
        while (tok.hasMoreElements()) values.add(tok.nextToken().trim());

        break;

      default:
        values.add(value);
    }

    // handle values
    switch (name) {
      case ServletContext.ORDERED_LIBS:
        {
          List<Object> libs = new ArrayList<>();
          Object o = context.getAttribute(ServletContext.ORDERED_LIBS);
          if (o instanceof Collection<?>) libs.addAll((Collection<?>) o);
          libs.addAll(values);
          if (libs.size() > 0) context.setAttribute(ServletContext.ORDERED_LIBS, libs);

          break;
        }

      case AnnotationConfiguration.CONTAINER_INITIALIZERS:
        {
          for (String i : values)
            visitContainerInitializer(
                context,
                new ContainerInitializer(Thread.currentThread().getContextClassLoader(), i));
          break;
        }

      case MetaInfConfiguration.METAINF_TLDS:
        {
          List<Object> tlds = new ArrayList<>();
          String war = context.getBaseResource().getURI().toString();
          Object o = context.getAttribute(MetaInfConfiguration.METAINF_TLDS);
          if (o instanceof Collection<?>) tlds.addAll((Collection<?>) o);
          for (String i : values) {
            Resource r = Resource.newResource(i.replace("${WAR}/", war));
            if (r.exists()) tlds.add(r.getURL());
            else throw new IllegalArgumentException("TLD not found: " + r);
          }

          if (tlds.size() > 0) context.setAttribute(MetaInfConfiguration.METAINF_TLDS, tlds);
          break;
        }

      case MetaInfConfiguration.METAINF_RESOURCES:
        {
          String war = context.getBaseResource().getURI().toString();
          for (String i : values) {
            Resource r = Resource.newResource(i.replace("${WAR}/", war));
            if (r.exists()) visitMetaInfResource(context, r);
            else throw new IllegalArgumentException("Resource not found: " + r);
          }
          break;
        }

      default:
    }
  }
  /**
   * Format a set cookie value
   *
   * @param name the name
   * @param value the value
   * @param domain the domain
   * @param path the path
   * @param maxAge the maximum age
   * @param comment the comment (only present on versions > 0)
   * @param isSecure true if secure cookie
   * @param isHttpOnly true if for http only
   * @param version version of cookie logic to use (0 == default behavior)
   */
  public void addSetCookie(
      final String name,
      final String value,
      final String domain,
      final String path,
      final long maxAge,
      final String comment,
      final boolean isSecure,
      final boolean isHttpOnly,
      int version) {
    String delim = __COOKIE_DELIM;

    // Check arguments
    if (name == null || name.length() == 0) throw new IllegalArgumentException("Bad cookie name");

    // Format value and params
    StringBuilder buf = new StringBuilder(128);
    String name_value_params;
    QuotedStringTokenizer.quoteIfNeeded(buf, name, delim);
    buf.append('=');
    String start = buf.toString();
    boolean hasDomain = false;
    boolean hasPath = false;

    if (value != null && value.length() > 0) QuotedStringTokenizer.quoteIfNeeded(buf, value, delim);

    if (comment != null && comment.length() > 0) {
      buf.append(";Comment=");
      QuotedStringTokenizer.quoteIfNeeded(buf, comment, delim);
    }

    if (path != null && path.length() > 0) {
      hasPath = true;
      buf.append(";Path=");
      if (path.trim().startsWith("\"")) buf.append(path);
      else QuotedStringTokenizer.quoteIfNeeded(buf, path, delim);
    }
    if (domain != null && domain.length() > 0) {
      hasDomain = true;
      buf.append(";Domain=");
      QuotedStringTokenizer.quoteIfNeeded(buf, domain.toLowerCase(Locale.ENGLISH), delim);
    }

    if (maxAge >= 0) {
      // Always add the expires param as some browsers still don't handle max-age
      buf.append(";Expires=");
      if (maxAge == 0) buf.append(__01Jan1970_COOKIE);
      else formatCookieDate(buf, System.currentTimeMillis() + 1000L * maxAge);

      if (version > 0) {
        buf.append(";Max-Age=");
        buf.append(maxAge);
      }
    }

    if (isSecure) buf.append(";Secure");
    if (isHttpOnly) buf.append(";HttpOnly");

    name_value_params = buf.toString();

    // remove existing set-cookie of same name
    Field field = getField(HttpHeaders.SET_COOKIE);
    Field last = null;
    while (field != null) {
      String val = (field._value == null ? null : field._value.toString());
      if (val != null && val.startsWith(start)) {
        // existing cookie has same name, does it also match domain and path?
        if (((!hasDomain && !val.contains("Domain"))
                || (hasDomain && val.contains("Domain=" + domain)))
            && ((!hasPath && !val.contains("Path")) || (hasPath && val.contains("Path=" + path)))) {
          _fields.remove(field);
          if (last == null) _names.put(HttpHeaders.SET_COOKIE_BUFFER, field._next);
          else last._next = field._next;
          break;
        }
      }
      last = field;
      field = field._next;
    }

    add(HttpHeaders.SET_COOKIE_BUFFER, new ByteArrayBuffer(name_value_params));

    // Expire responses with set-cookie headers so they do not get cached.
    put(HttpHeaders.EXPIRES_BUFFER, __01Jan1970_BUFFER);
  }
Exemple #4
0
  @Override
  public AuthStatus validateRequest(
      MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException {
    HttpServletRequest request = (HttpServletRequest) messageInfo.getRequestMessage();
    HttpServletResponse response = (HttpServletResponse) messageInfo.getResponseMessage();
    String credentials = request.getHeader(HttpHeader.AUTHORIZATION.asString());

    try {
      boolean stale = false;
      // TODO extract from request
      long timestamp = System.currentTimeMillis();
      if (credentials != null) {
        if (LOG.isDebugEnabled()) LOG.debug("Credentials: " + credentials);
        QuotedStringTokenizer tokenizer =
            new QuotedStringTokenizer(credentials, "=, ", true, false);
        final Digest digest = new Digest(request.getMethod());
        String last = null;
        String name = null;

        while (tokenizer.hasMoreTokens()) {
          String tok = tokenizer.nextToken();
          char c = (tok.length() == 1) ? tok.charAt(0) : '\0';

          switch (c) {
            case '=':
              name = last;
              last = tok;
              break;
            case ',':
              name = null;
            case ' ':
              break;

            default:
              last = tok;
              if (name != null) {
                if ("username".equalsIgnoreCase(name)) digest.username = tok;
                else if ("realm".equalsIgnoreCase(name)) digest.realm = tok;
                else if ("nonce".equalsIgnoreCase(name)) digest.nonce = tok;
                else if ("nc".equalsIgnoreCase(name)) digest.nc = tok;
                else if ("cnonce".equalsIgnoreCase(name)) digest.cnonce = tok;
                else if ("qop".equalsIgnoreCase(name)) digest.qop = tok;
                else if ("uri".equalsIgnoreCase(name)) digest.uri = tok;
                else if ("response".equalsIgnoreCase(name)) digest.response = tok;
                break;
              }
          }
        }

        int n = checkNonce(digest.nonce, timestamp);

        if (n > 0) {
          if (login(
              clientSubject, digest.username, digest, Constraint.__DIGEST_AUTH, messageInfo)) {
            return AuthStatus.SUCCESS;
          }
        } else if (n == 0) stale = true;
      }

      if (!isMandatory(messageInfo)) {
        return AuthStatus.SUCCESS;
      }
      String domain = request.getContextPath();
      if (domain == null) domain = "/";
      response.setHeader(
          HttpHeader.WWW_AUTHENTICATE.asString(),
          "Digest realm=\""
              + realmName
              + "\", domain=\""
              + domain
              + "\", nonce=\""
              + newNonce(timestamp)
              + "\", algorithm=MD5, qop=\"auth\""
              + (useStale ? (" stale=" + stale) : ""));
      response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
      return AuthStatus.SEND_CONTINUE;
    } catch (IOException e) {
      throw new AuthException(e.getMessage());
    } catch (UnsupportedCallbackException e) {
      throw new AuthException(e.getMessage());
    }
  }
    /* ------------------------------------------------------------ */
    public void sendContent(Object content) throws IOException {
      Resource resource = null;

      if (isClosed()) throw new IOException("Closed");

      if (super._generator.isWritten()) throw new IllegalStateException("!empty");

      // Convert HTTP content to contentl
      if (content instanceof HttpContent) {
        HttpContent httpContent = (HttpContent) content;
        Buffer contentType = httpContent.getContentType();
        if (contentType != null && !_responseFields.containsKey(HttpHeaders.CONTENT_TYPE_BUFFER)) {
          String enc = _response.getSetCharacterEncoding();
          if (enc == null) _responseFields.add(HttpHeaders.CONTENT_TYPE_BUFFER, contentType);
          else {
            if (contentType instanceof CachedBuffer) {
              CachedBuffer content_type = ((CachedBuffer) contentType).getAssociate(enc);
              if (content_type != null)
                _responseFields.put(HttpHeaders.CONTENT_TYPE_BUFFER, content_type);
              else {
                _responseFields.put(
                    HttpHeaders.CONTENT_TYPE_BUFFER,
                    contentType + ";charset=" + QuotedStringTokenizer.quoteIfNeeded(enc, ";= "));
              }
            } else {
              _responseFields.put(
                  HttpHeaders.CONTENT_TYPE_BUFFER,
                  contentType + ";charset=" + QuotedStringTokenizer.quoteIfNeeded(enc, ";= "));
            }
          }
        }
        if (httpContent.getContentLength() > 0)
          _responseFields.putLongField(
              HttpHeaders.CONTENT_LENGTH_BUFFER, httpContent.getContentLength());
        Buffer lm = httpContent.getLastModified();
        long lml = httpContent.getResource().lastModified();
        if (lm != null) _responseFields.put(HttpHeaders.LAST_MODIFIED_BUFFER, lm);
        else if (httpContent.getResource() != null) {
          if (lml != -1) _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, lml);
        }

        boolean direct =
            _connector instanceof NIOConnector
                && ((NIOConnector) _connector).getUseDirectBuffers()
                && !(_connector instanceof SslConnector);
        content = direct ? httpContent.getDirectBuffer() : httpContent.getIndirectBuffer();
        if (content == null) content = httpContent.getInputStream();
      } else if (content instanceof Resource) {
        resource = (Resource) content;
        _responseFields.putDateField(HttpHeaders.LAST_MODIFIED_BUFFER, resource.lastModified());
        content = resource.getInputStream();
      }

      // Process content.
      if (content instanceof Buffer) {
        super._generator.addContent((Buffer) content, Generator.LAST);
        commitResponse(Generator.LAST);
      } else if (content instanceof InputStream) {
        InputStream in = (InputStream) content;

        try {
          int max = super._generator.prepareUncheckedAddContent();
          Buffer buffer = super._generator.getUncheckedBuffer();

          int len = buffer.readFrom(in, max);

          while (len >= 0) {
            super._generator.completeUncheckedAddContent();
            _out.flush();

            max = super._generator.prepareUncheckedAddContent();
            buffer = super._generator.getUncheckedBuffer();
            len = buffer.readFrom(in, max);
          }
          super._generator.completeUncheckedAddContent();
          _out.flush();
        } finally {
          if (resource != null) resource.release();
          else in.close();
        }
      } else throw new IllegalArgumentException("unknown content type?");
    }
  public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory)
      throws ServerAuthException {
    if (!mandatory) {
      return _deferred;
    }

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    String credentials = request.getHeader(HttpHeaders.AUTHORIZATION);

    try {
      boolean stale = false;
      if (credentials != null) {
        if (Log.isDebugEnabled()) {
          Log.debug("Credentials: " + credentials);
        }
        QuotedStringTokenizer tokenizer =
            new QuotedStringTokenizer(credentials, "=, ", true, false);
        final Digest digest = new Digest(request.getMethod());
        String last = null;
        String name = null;

        while (tokenizer.hasMoreTokens()) {
          String tok = tokenizer.nextToken();
          char c = (tok.length() == 1) ? tok.charAt(0) : '\0';

          switch (c) {
            case '=':
              name = last;
              last = tok;
              break;
            case ',':
              name = null;
            case ' ':
              break;

            default:
              last = tok;
              if (name != null) {
                if ("username".equalsIgnoreCase(name)) {
                  digest.username = tok;
                } else if ("realm".equalsIgnoreCase(name)) {
                  digest.realm = tok;
                } else if ("nonce".equalsIgnoreCase(name)) {
                  digest.nonce = tok;
                } else if ("nc".equalsIgnoreCase(name)) {
                  digest.nc = tok;
                } else if ("cnonce".equalsIgnoreCase(name)) {
                  digest.cnonce = tok;
                } else if ("qop".equalsIgnoreCase(name)) {
                  digest.qop = tok;
                } else if ("uri".equalsIgnoreCase(name)) {
                  digest.uri = tok;
                } else if ("response".equalsIgnoreCase(name)) {
                  digest.response = tok;
                }
                break;
              }
          }
        }

        int n = checkNonce(digest.nonce, (Request) request);

        if (n > 0) {
          UserIdentity user = _loginService.login(digest.username, digest);
          if (user != null) {
            return new UserAuthentication(getAuthMethod(), user);
          }
        } else if (n == 0) {
          stale = true;
        }
      }

      if (!_deferred.isDeferred(response)) {
        String domain = request.getContextPath();
        if (domain == null) {
          domain = "/";
        }
        response.setHeader(
            HttpHeaders.WWW_AUTHENTICATE,
            "Digest realm=\""
                + _loginService.getName()
                + "\", domain=\""
                + domain
                + "\", nonce=\""
                + newNonce((Request) request)
                + "\", algorithm=MD5, qop=\"auth\""
                + (_useStale ? (" stale=" + stale) : ""));
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

        return Authentication.SEND_CONTINUE;
      }

      return Authentication.UNAUTHENTICATED;
    } catch (Exception e) {
      throw new ServerAuthException(e);
    }
  }