/**
   * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
   *
   * @param request servlet request
   * @param response servlet response
   * @throws ServletException if a servlet-specific error occurs
   * @throws IOException if an I/O error occurs
   */
  protected void processRequest(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    try {

      out.println("<html>");
      out.println("<head>");
      out.println("<title>Low Level SecServlet</title>");
      out.println("</head>");
      out.println("<body>");
      out.println("<h1>Low Level Security at " + request.getContextPath() + "</h1>");
      out.println("<br>");
      out.println("AuthType:[" + request.getAuthType() + "]");
      out.println("<br>");

      out.println("RemoteUser:[" + request.getRemoteUser() + "]");
      out.println("<br>");
      if (request.getUserPrincipal() != null) {
        out.println("UserPrincipal.Name:[" + request.getUserPrincipal().getName() + "]");
      } else {
        out.println("no principal");
      }

      out.println("</hr>");

      out.println("</body>");
      out.println("</html>");
    } finally {
      out.close();
    }
  }
Beispiel #2
0
  @Override
  public String getAuthType() {
    HttpServletRequest request = (HttpServletRequest) getRequest();
    String headerValue;

    headerValue = request.getHeader(headerPrefix + "AUTH_TYPE");
    if (headerValue != null) {
      return headerValue;
    } else {
      return request.getAuthType();
    }
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain fc)
      throws IOException, ServletException {
    final HttpServletRequest r = (HttpServletRequest) request;
    final String remoteUser = r.getRemoteUser();
    final String authType = r.getAuthType();
    final Principal userPrincipal = r.getUserPrincipal();

    if (remoteUser != null || authType != null || userPrincipal != null) {
      ((HttpServletResponse) response).sendRedirect(target);
    } else {
      fc.doFilter(request, response);
    }
  }
Beispiel #4
0
 // Update the agent URL in the agent details if not already done
 private void updateAgentDetailsIfNeeded(HttpServletRequest pReq) {
   // Lookup the Agent URL if needed
   AgentDetails details = backendManager.getAgentDetails();
   if (details.isInitRequired()) {
     synchronized (details) {
       if (details.isInitRequired()) {
         if (details.isUrlMissing()) {
           String url =
               getBaseUrl(
                   NetworkUtil.sanitizeLocalUrl(pReq.getRequestURL().toString()),
                   extractServletPath(pReq));
           details.setUrl(url);
         }
         if (details.isSecuredMissing()) {
           details.setSecured(pReq.getAuthType() != null);
         }
         details.seal();
       }
     }
   }
 }
Beispiel #5
0
  /**
   * Returns a String with all basic request information in an HTML table.
   *
   * @return A String with all basic request information in an HTML table.
   */
  public String getRequestInfo() {
    Map info = new TreeMap();
    HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();

    info.put("authType", nullToString(req.getAuthType()));
    info.put("characterEncoding", nullToString(req.getCharacterEncoding()));
    info.put("contentLength", Integer.toString(req.getContentLength()));
    info.put("contentType", nullToString(req.getContentType()));
    info.put("contextPath", nullToString(req.getContextPath()));
    info.put("pathInfo", nullToString(req.getPathInfo()));
    info.put("protocol", nullToString(req.getProtocol()));
    info.put("queryString", nullToString(req.getQueryString()));
    info.put("remoteAddr", nullToString(req.getRemoteAddr()));
    info.put("remoteHost", nullToString(req.getRemoteHost()));
    info.put("remoteUser", nullToString(req.getRemoteUser()));
    info.put("requestURI", nullToString(req.getRequestURI()));
    info.put("scheme", nullToString(req.getScheme()));
    info.put("serverName", nullToString(req.getServerName()));
    info.put("serverPort", Integer.toString(req.getServerPort()));
    info.put("servletPath", nullToString(req.getServletPath()));

    return toHTMLTable("request properties", info);
  }
Beispiel #6
0
  /** {@inheritDoc} */
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
      throws IOException, ServletException {

    HttpServletRequest rqst = (HttpServletRequest) request;
    HttpServletResponse rsp = (HttpServletResponse) response;

    if (LOG.isDebugEnabled()) {
      StringBuilder b =
          new StringBuilder("Request from ")
              .append(rqst.getRemoteHost())
              .append("/")
              .append(rqst.getRemoteAddr())
              .append(":")
              .append(rqst.getRemotePort());

      @SuppressWarnings("unchecked")
      Enumeration<String> e = rqst.getAttributeNames();
      for (; e.hasMoreElements(); ) {
        String attribute = e.nextElement();
        b.append("\n  " + attribute + " => " + rqst.getAttribute(attribute));
      }

      X509Certificate[] userCerts =
          (X509Certificate[]) rqst.getAttribute("javax.servlet.request.X509Certificate");
      if (userCerts != null)
        for (X509Certificate cert : userCerts)
          b.append(
              "\n Client certificate Subject Name is " + cert.getSubjectX500Principal().getName());

      b.append("\n The Scheme is " + rqst.getScheme());
      b.append("\n The Auth Type is " + rqst.getAuthType());
      b.append("\n The Path Info is " + rqst.getPathInfo());
      b.append("\n The Translated Path Info is " + rqst.getPathTranslated());
      b.append("\n The Context Path is " + rqst.getContextPath());
      b.append("\n The Query String is " + rqst.getQueryString());
      b.append("\n The Remote User is " + rqst.getRemoteUser());
      b.append("\n The User Principal is " + rqst.getUserPrincipal());
      b.append("\n The Request URI is " + rqst.getRequestURI());
      b.append("\n The Request URL is " + rqst.getRequestURL());
      b.append("\n The Servlet Path is " + rqst.getServletPath());

      LOG.debug(b.toString());
    }

    if (rqst.getScheme().equalsIgnoreCase("https")) {
      boolean isAuthorized = false;
      X509Certificate[] certs =
          (X509Certificate[]) rqst.getAttribute("javax.servlet.request.X509Certificate");
      if (certs == null || certs.length == 0) {
        rsp.sendError(HttpServletResponse.SC_BAD_REQUEST, "No client SSL certificate received");
        return;
      }
      for (X509Certificate cert : certs) {
        try {
          cert.checkValidity();
        } catch (CertificateExpiredException e) {
          LOG.info("Received cert for " + cert.getSubjectX500Principal().getName() + " expired");
          rsp.sendError(HttpServletResponse.SC_FORBIDDEN, "Certificate expired");
          return;
        } catch (CertificateNotYetValidException e) {
          LOG.info(
              "Received cert for "
                  + cert.getSubjectX500Principal().getName()
                  + " is not yet valid");
          rsp.sendError(HttpServletResponse.SC_FORBIDDEN, "Certificate is not yet valid");
          return;
        }
      }

      String[] tokens = certs[0].getSubjectX500Principal().getName().split("\\s*,\\s*");
      String userID = null;
      for (String s : tokens) {
        if (s.startsWith("CN=")) {
          userID = s;
          break;
        }
      }
      if (userID == null || userID.length() < 4) {
        LOG.info("Can't retrieve user ID from SSL certificate");
        rsp.sendError(
            HttpServletResponse.SC_FORBIDDEN, "Can't retrieve user ID from SSL certificate");
        return;
      }
      userID = userID.substring(3);

      String servletPath = rqst.getServletPath();
      if (HFTP_PATTERN.matcher(servletPath).matches()) {
        // request is an HSFTP request
        if (FILEPATH_PATTERN.matcher(servletPath).matches()) {
          // file path as part of the URL
          isAuthorized =
              checkPath(userID, certs[0], rqst.getPathInfo() != null ? rqst.getPathInfo() : "/");
        } else {
          // file path is stored in "filename" parameter
          isAuthorized = checkPath(userID, certs[0], rqst.getParameter("filename"));
        }
      } else if (RELOAD_PATTERN.matcher(servletPath).matches() && checkUser("Admin", certs[0])) {
        Configuration conf = new Configuration(false);
        conf.addResource("hdfsproxy-default.xml");
        Map<String, Set<Path>> permsMap = getPermMap(conf);
        Map<String, Set<BigInteger>> certsMap = getCertsMap(conf);
        if (permsMap == null || certsMap == null) {
          LOG.warn("Permission files reloading failed");
          rsp.sendError(
              HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Permission files reloading failed");
          return;
        }
        ProxyFilter.permsMap = permsMap;
        ProxyFilter.certsMap = certsMap;
        LOG.info("User permissions and user certs files reloaded");
        rsp.setStatus(HttpServletResponse.SC_OK);
        return;
      } else if (CLEAR_PATTERN.matcher(servletPath).matches() && checkUser("Admin", certs[0])) {
        ProxyUgiManager.clearCache();
        LOG.info("Ugi cache cleared");
        rsp.setStatus(HttpServletResponse.SC_OK);
        return;
      }

      if (!isAuthorized) {
        rsp.sendError(HttpServletResponse.SC_FORBIDDEN, "Unauthorized access");
        return;
      }
      // request is authorized, set ugi for servlets
      UnixUserGroupInformation ugi = ProxyUgiManager.getUgiForUser(userID);
      if (ugi == null) {
        LOG.info("Can't retrieve ugi for user " + userID);
        rsp.sendError(
            HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Can't retrieve ugi for user " + userID);
        return;
      }
      rqst.setAttribute("authorized.ugi", ugi);
    } else { // http request, set ugi for servlets, only for testing purposes
      String ugi = rqst.getParameter("ugi");
      rqst.setAttribute("authorized.ugi", new UnixUserGroupInformation(ugi.split(",")));
    }

    chain.doFilter(request, response);
  }
  /**
   * Copy the HttpServletRequest content inside an AtmosphereRequest. By default the returned
   * AtmosphereRequest is not destroyable.
   *
   * @param request {@link HttpServletRequest}
   * @return an {@link AtmosphereRequest}
   */
  public static final AtmosphereRequest cloneRequest(
      HttpServletRequest request,
      boolean loadInMemory,
      boolean copySession,
      boolean isDestroyable,
      boolean createSession) {
    Builder b;
    HttpServletRequest r;

    Cookie[] cs = request.getCookies();
    Set<Cookie> hs = Collections.synchronizedSet(new HashSet());
    if (cs != null) {
      for (Cookie c : cs) {
        hs.add(c);
      }
    }

    boolean isWrapped = false;
    if (AtmosphereRequestImpl.class.isAssignableFrom(request.getClass())) {
      b = AtmosphereRequestImpl.class.cast(request).b;
      isWrapped = true;
    } else {
      b = new Builder();
      b.request(request);
    }

    HttpSession session = null;
    if (copySession) {
      session = request.getSession(createSession);
      if (session != null) {
        session = new FakeHttpSession(session);
      } else {
        session = new FakeHttpSession("", null, System.currentTimeMillis(), -1);
      }
    }

    b.servletPath(request.getServletPath())
        .pathInfo(request.getPathInfo())
        .contextPath(request.getContextPath())
        .requestURI(request.getRequestURI())
        .requestURL(request.getRequestURL().toString())
        .method(request.getMethod())
        .serverName(request.getServerName())
        .serverPort(request.getServerPort())
        .remoteAddr(request.getRemoteAddr())
        .remoteHost(request.getRemoteHost())
        .remotePort(request.getRemotePort())
        .destroyable(isDestroyable)
        .cookies(hs)
        .session(session)
        .principal(request.getUserPrincipal())
        .authType(request.getAuthType())
        .isSSecure(request.isSecure());

    if (loadInMemory) {
      String s =
          (String)
              attributeWithoutException(request, FrameworkConfig.THROW_EXCEPTION_ON_CLONED_REQUEST);
      boolean throwException = s != null && Boolean.parseBoolean(s);
      r = new NoOpsRequest(throwException);
      if (isWrapped) {
        load(b.request, b);
      } else {
        load(request, b);
      }
      b.request(r);
    }

    return isWrapped ? AtmosphereRequestImpl.class.cast(request) : b.build();
  }
Beispiel #8
0
  private void setEnvironment(ClientSocket stream, WriteStream ws, HttpServletRequest req)
      throws IOException {
    addHeader(stream, ws, "REQUEST_URI", req.getRequestURI());
    addHeader(stream, ws, "REQUEST_METHOD", req.getMethod());

    addHeader(stream, ws, "SERVER_SOFTWARE", "Resin/" + VersionFactory.getVersion());

    addHeader(stream, ws, "SERVER_NAME", req.getServerName());
    // addHeader(stream, ws, "SERVER_ADDR=" + req.getServerAddr());
    addHeader(stream, ws, "SERVER_PORT", String.valueOf(req.getServerPort()));

    addHeader(stream, ws, "REMOTE_ADDR", req.getRemoteAddr());
    addHeader(stream, ws, "REMOTE_HOST", req.getRemoteAddr());
    // addHeader(stream, ws, "REMOTE_PORT=" + req.getRemotePort());

    if (req.getRemoteUser() != null) addHeader(stream, ws, "REMOTE_USER", req.getRemoteUser());
    else addHeader(stream, ws, "REMOTE_USER", "");
    if (req.getAuthType() != null) addHeader(stream, ws, "AUTH_TYPE", req.getAuthType());

    addHeader(stream, ws, "GATEWAY_INTERFACE", "CGI/1.1");
    addHeader(stream, ws, "SERVER_PROTOCOL", req.getProtocol());
    if (req.getQueryString() != null) addHeader(stream, ws, "QUERY_STRING", req.getQueryString());
    else addHeader(stream, ws, "QUERY_STRING", "");

    String scriptPath = req.getServletPath();
    String pathInfo = req.getPathInfo();

    WebApp webApp = (WebApp) req.getServletContext();

    Path appDir = webApp.getAppDir();
    String realPath = webApp.getRealPath(scriptPath);

    if (!appDir.lookup(realPath).isFile() && pathInfo != null) scriptPath = scriptPath + pathInfo;

    /*
     * FastCGI (specifically quercus) uses the PATH_INFO and PATH_TRANSLATED
     * for the script path.
     */
    log.finer("STREAM file: " + webApp.getRealPath(scriptPath));

    addHeader(stream, ws, "PATH_INFO", req.getContextPath() + scriptPath);
    addHeader(stream, ws, "PATH_TRANSLATED", webApp.getRealPath(scriptPath));

    /* These are the values which would be sent to CGI.
    addHeader(stream, ws, "SCRIPT_NAME", req.getContextPath() + scriptPath);
    addHeader(stream, ws, "SCRIPT_FILENAME", app.getRealPath(scriptPath));

    if (pathInfo != null) {
      addHeader(stream, ws, "PATH_INFO", pathInfo);
      addHeader(stream, ws, "PATH_TRANSLATED", req.getRealPath(pathInfo));
    }
    else {
      addHeader(stream, ws, "PATH_INFO", "");
      addHeader(stream, ws, "PATH_TRANSLATED", "");
    }
    */

    int contentLength = req.getContentLength();
    if (contentLength < 0) addHeader(stream, ws, "CONTENT_LENGTH", "0");
    else addHeader(stream, ws, "CONTENT_LENGTH", String.valueOf(contentLength));

    ServletContext rootContext = webApp.getContext("/");

    if (rootContext != null) addHeader(stream, ws, "DOCUMENT_ROOT", rootContext.getRealPath("/"));

    CharBuffer cb = new CharBuffer();

    Enumeration e = req.getHeaderNames();
    while (e.hasMoreElements()) {
      String key = (String) e.nextElement();
      String value = req.getHeader(key);

      if (key.equalsIgnoreCase("content-length")) addHeader(stream, ws, "CONTENT_LENGTH", value);
      else if (key.equalsIgnoreCase("content-type")) addHeader(stream, ws, "CONTENT_TYPE", value);
      else if (key.equalsIgnoreCase("if-modified-since")) {
      } else if (key.equalsIgnoreCase("if-none-match")) {
      } else if (key.equalsIgnoreCase("authorization")) {
      } else if (key.equalsIgnoreCase("proxy-authorization")) {
      } else addHeader(stream, ws, convertHeader(cb, key), value);
    }
  }
 public String getAuthType() {
   return request.getAuthType();
 }
Beispiel #10
0
  private String[] makeEnv(final HttpServletRequest req, final ProjectControl project) {
    final EnvList env = new EnvList(_env);
    final int contentLength = Math.max(0, req.getContentLength());

    // These ones are from "The WWW Common Gateway Interface Version 1.1"
    //
    env.set("AUTH_TYPE", req.getAuthType());
    env.set("CONTENT_LENGTH", Integer.toString(contentLength));
    env.set("CONTENT_TYPE", req.getContentType());
    env.set("GATEWAY_INTERFACE", "CGI/1.1");
    env.set("PATH_INFO", req.getPathInfo());
    env.set("PATH_TRANSLATED", null);
    env.set("QUERY_STRING", req.getQueryString());
    env.set("REMOTE_ADDR", req.getRemoteAddr());
    env.set("REMOTE_HOST", req.getRemoteHost());
    env.set("HTTPS", req.isSecure() ? "ON" : "OFF");

    // The identity information reported about the connection by a
    // RFC 1413 [11] request to the remote agent, if
    // available. Servers MAY choose not to support this feature, or
    // not to request the data for efficiency reasons.
    // "REMOTE_IDENT" => "NYI"
    //
    env.set("REQUEST_METHOD", req.getMethod());
    env.set("SCRIPT_NAME", req.getContextPath() + req.getServletPath());
    env.set("SCRIPT_FILENAME", gitwebCgi.toAbsolutePath().toString());
    env.set("SERVER_NAME", req.getServerName());
    env.set("SERVER_PORT", Integer.toString(req.getServerPort()));
    env.set("SERVER_PROTOCOL", req.getProtocol());
    env.set("SERVER_SOFTWARE", getServletContext().getServerInfo());

    final Enumeration<String> hdrs = enumerateHeaderNames(req);
    while (hdrs.hasMoreElements()) {
      final String name = hdrs.nextElement();
      final String value = req.getHeader(name);
      env.set("HTTP_" + name.toUpperCase().replace('-', '_'), value);
    }

    env.set("GERRIT_CONTEXT_PATH", req.getContextPath() + "/");
    env.set("GERRIT_PROJECT_NAME", project.getProject().getName());

    if (project.forUser(anonymousUserProvider.get()).isVisible()) {
      env.set("GERRIT_ANONYMOUS_READ", "1");
    }

    String remoteUser = null;
    if (project.getCurrentUser().isIdentifiedUser()) {
      final IdentifiedUser u = (IdentifiedUser) project.getCurrentUser();
      final String user = u.getUserName();
      env.set("GERRIT_USER_NAME", user);
      if (user != null && !user.isEmpty()) {
        remoteUser = user;
      } else {
        remoteUser = "******" + u.getAccountId();
      }
    }
    env.set("REMOTE_USER", remoteUser);

    // Override CGI settings using alternative URI provided by gitweb.url.
    // This is required to trick gitweb into thinking that it's served under
    // different URL. Setting just $my_uri on the perl's side isn't enough,
    // because few actions (atom, blobdiff_plain, commitdiff_plain) rely on
    // URL returned by $cgi->self_url().
    //
    if (gitwebUrl != null) {
      int schemePort = -1;

      if (gitwebUrl.getScheme() != null) {
        if (gitwebUrl.getScheme().equals("http")) {
          env.set("HTTPS", "OFF");
          schemePort = 80;
        } else {
          env.set("HTTPS", "ON");
          schemePort = 443;
        }
      }

      if (gitwebUrl.getHost() != null) {
        env.set("SERVER_NAME", gitwebUrl.getHost());
        env.set("HTTP_HOST", gitwebUrl.getHost());
      }

      if (gitwebUrl.getPort() != -1) {
        env.set("SERVER_PORT", Integer.toString(gitwebUrl.getPort()));
      } else if (schemePort != -1) {
        env.set("SERVER_PORT", Integer.toString(schemePort));
      }

      if (gitwebUrl.getPath() != null) {
        env.set("SCRIPT_NAME", gitwebUrl.getPath().isEmpty() ? "/" : gitwebUrl.getPath());
      }
    }

    return env.getEnvArray();
  }
  /**
   * Constructs the CGI environment to be supplied to the invoked CGI script; relies heavliy on
   * Servlet API methods and findCGI
   *
   * @param HttpServletRequest request associated with the CGI invokation
   * @return true if environment was set OK, false if there was a problem and no environment was set
   */
  protected boolean deriveProcessEnvironment(HttpServletRequest req) {
    /*
     * This method is slightly ugly; c'est la vie.
     * "You cannot stop [ugliness], you can only hope to contain [it]"
     * (apologies to Marv Albert regarding MJ)
     */

    Hashtable envp;
    super.deriveProcessEnvironment(req);
    envp = getEnvironment();

    String sPathInfoOrig = null;
    String sPathTranslatedOrig = null;
    String sPathInfoCGI = null;
    String sPathTranslatedCGI = null;
    String sCGIFullPath = null;
    String sCGIScriptName = null;
    String sCGIFullName = null;
    String sCGIName = null;
    String[] sCGINames;
    sPathInfoOrig = this.pathInfo;
    sPathInfoOrig = sPathInfoOrig == null ? "" : sPathInfoOrig;
    sPathTranslatedOrig = req.getPathTranslated();
    sPathTranslatedOrig = sPathTranslatedOrig == null ? "" : sPathTranslatedOrig;
    sCGINames =
        findCGI(
            sPathInfoOrig, getWebAppRootDir(), getContextPath(), getServletPath(), cgiPathPrefix);
    sCGIFullPath = sCGINames[0];
    sCGIScriptName = sCGINames[1];
    sCGIFullName = sCGINames[2];
    sCGIName = sCGINames[3];
    if (sCGIFullPath == null
        || sCGIScriptName == null
        || sCGIFullName == null
        || sCGIName == null) {
      return false;
    }
    envp.put("SERVER_SOFTWARE", "TOMCAT");
    envp.put("SERVER_NAME", nullsToBlanks(req.getServerName()));
    envp.put("GATEWAY_INTERFACE", "CGI/1.1");
    envp.put("SERVER_PROTOCOL", nullsToBlanks(req.getProtocol()));
    int port = req.getServerPort();
    Integer iPort = (port == 0 ? new Integer(-1) : new Integer(port));
    envp.put("SERVER_PORT", iPort.toString());
    envp.put("REQUEST_METHOD", nullsToBlanks(req.getMethod()));

    /*-
     * PATH_INFO should be determined by using sCGIFullName:
     * 1) Let sCGIFullName not end in a "/" (see method findCGI)
     * 2) Let sCGIFullName equal the pathInfo fragment which
     *    corresponds to the actual cgi script.
     * 3) Thus, PATH_INFO = request.getPathInfo().substring(
     *                      sCGIFullName.length())
     *
     * (see method findCGI, where the real work is done)
     *
     */

    if (pathInfo == null || (pathInfo.substring(sCGIFullName.length()).length() <= 0)) {
      sPathInfoCGI = "";
    } else {
      sPathInfoCGI = pathInfo.substring(sCGIFullName.length());
    }
    envp.put("PATH_INFO", sPathInfoCGI);

    /*-
     * PATH_TRANSLATED must be determined after PATH_INFO (and the
     * implied real cgi-script) has been taken into account.
     *
     * The following example demonstrates:
     *
     * servlet info   = /servlet/cgigw/dir1/dir2/cgi1/trans1/trans2
     * cgifullpath    = /servlet/cgigw/dir1/dir2/cgi1
     * path_info      = /trans1/trans2
     * webAppRootDir  = servletContext.getRealPath("/")
     *
     * path_translated = servletContext.getRealPath("/trans1/trans2")
     *
     * That is, PATH_TRANSLATED = webAppRootDir + sPathInfoCGI
     * (unless sPathInfoCGI is null or blank, then the CGI
     * specification dictates that the PATH_TRANSLATED metavariable
     * SHOULD NOT be defined.
     *
     */

    if (sPathInfoCGI != null && !("".equals(sPathInfoCGI))) {
      sPathTranslatedCGI = getContext().getRealPath(sPathInfoCGI);
    } else {
      sPathTranslatedCGI = null;
    }
    if (sPathTranslatedCGI == null || "".equals(sPathTranslatedCGI)) {
      // NOOP
    } else {
      envp.put("PATH_TRANSLATED", nullsToBlanks(sPathTranslatedCGI));
    }
    envp.put("SCRIPT_NAME", nullsToBlanks(sCGIScriptName));
    envp.put("QUERY_STRING", nullsToBlanks(req.getQueryString()));
    envp.put("REMOTE_HOST", nullsToBlanks(req.getRemoteHost()));
    envp.put("REMOTE_ADDR", nullsToBlanks(req.getRemoteAddr()));
    envp.put("AUTH_TYPE", nullsToBlanks(req.getAuthType()));
    envp.put("REMOTE_USER", nullsToBlanks(req.getRemoteUser()));
    envp.put("REMOTE_IDENT", ""); // not necessary for full compliance
    envp.put("CONTENT_TYPE", nullsToBlanks(req.getContentType()));

    /* Note CGI spec says CONTENT_LENGTH must be NULL ("") or undefined
     * if there is no content, so we cannot put 0 or -1 in as per the
     * Servlet API spec.
     */

    int contentLength = req.getContentLength();
    String sContentLength = (contentLength <= 0 ? "" : (new Integer(contentLength)).toString());
    envp.put("CONTENT_LENGTH", sContentLength);
    Enumeration headers = req.getHeaderNames();
    String header = null;
    while (headers.hasMoreElements()) {
      header = null;
      header = ((String) headers.nextElement()).toUpperCase();
      // REMIND: rewrite multiple headers as if received as single
      // REMIND: change character set
      // REMIND: I forgot what the previous REMIND means
      if ("AUTHORIZATION".equalsIgnoreCase(header)
          || "PROXY_AUTHORIZATION".equalsIgnoreCase(header)) {
        // NOOP per CGI specification section 11.2
      } else if ("HOST".equalsIgnoreCase(header)) {
        String host = req.getHeader(header);
        envp.put("HTTP_" + header.replace('-', '_'), host.substring(0, host.indexOf(":")));
      } else {
        envp.put("HTTP_" + header.replace('-', '_'), req.getHeader(header));
      }
    }
    command = sCGIFullPath;
    workingDirectory = new File(command.substring(0, command.lastIndexOf(File.separator)));
    envp.put("X_TOMCAT_COMMAND_PATH", command); // for kicks
    this.setEnvironment(envp);
    return true;
  }
Beispiel #12
0
  /*
   * @param root
   * @param path
   * @param req
   * @param res
   * @exception IOException
   */
  private void exec(File command, String pathInfo, HttpServletRequest req, HttpServletResponse res)
      throws IOException {
    String path = command.toString();
    File dir = command.getParentFile();
    if (log.isDebugEnabled()) log.debug("CGI: execing: " + path);

    EnvList env = new EnvList(_env);

    // these ones are from "The WWW Common Gateway Interface Version 1.1"
    // look at : http://Web.Golux.Com/coar/cgi/draft-coar-cgi-v11-03-clean.html#6.1.1
    env.set("AUTH_TYPE", req.getAuthType());
    env.set("CONTENT_LENGTH", Integer.toString(req.getContentLength()));
    env.set("CONTENT_TYPE", req.getContentType());
    env.set("GATEWAY_INTERFACE", "CGI/1.1");
    env.set("PATH_INFO", pathInfo);
    env.set("PATH_TRANSLATED", req.getPathTranslated());
    env.set("QUERY_STRING", req.getQueryString());
    env.set("REMOTE_ADDR", req.getRemoteAddr());
    env.set("REMOTE_HOST", req.getRemoteHost());
    // The identity information reported about the connection by a
    // RFC 1413 [11] request to the remote agent, if
    // available. Servers MAY choose not to support this feature, or
    // not to request the data for efficiency reasons.
    // "REMOTE_IDENT" => "NYI"
    env.set("REMOTE_USER", req.getRemoteUser());
    env.set("REQUEST_METHOD", req.getMethod());
    String scriptName =
        req.getRequestURI().substring(0, req.getRequestURI().length() - pathInfo.length());
    env.set("SCRIPT_NAME", scriptName);
    env.set("SCRIPT_FILENAME", getServletContext().getRealPath(scriptName));
    env.set("SERVER_NAME", req.getServerName());
    env.set("SERVER_PORT", Integer.toString(req.getServerPort()));
    env.set("SERVER_PROTOCOL", req.getProtocol());
    env.set("SERVER_SOFTWARE", getServletContext().getServerInfo());
    Enumeration enm = req.getHeaderNames();
    while (enm.hasMoreElements()) {
      String name = (String) enm.nextElement();
      String value = req.getHeader(name);
      env.set("HTTP_" + name.toUpperCase().replace('-', '_'), value);
    }

    // these extra ones were from printenv on www.dev.nomura.co.uk
    env.set("HTTPS", (req.isSecure() ? "ON" : "OFF"));
    // "DOCUMENT_ROOT" => root + "/docs",
    // "SERVER_URL" => "NYI - http://us0245",
    // "TZ" => System.getProperty("user.timezone"),

    // are we meant to decode args here ? or does the script get them
    // via PATH_INFO ?  if we are, they should be decoded and passed
    // into exec here...

    String execCmd = path;
    if (execCmd.indexOf(" ") >= 0) execCmd = "\"" + execCmd + "\"";
    if (_cmdPrefix != null) execCmd = _cmdPrefix + " " + execCmd;

    Process p =
        dir == null
            ? Runtime.getRuntime().exec(execCmd, env.getEnvArray())
            : Runtime.getRuntime().exec(execCmd, env.getEnvArray(), dir);

    // hook processes input to browser's output (async)
    final InputStream inFromReq = req.getInputStream();
    final OutputStream outToCgi = p.getOutputStream();
    final int inputLength = req.getContentLength();

    new Thread(
            new Runnable() {
              public void run() {
                try {
                  if (inputLength > 0) IO.copy(inFromReq, outToCgi, inputLength);
                  outToCgi.close();
                } catch (IOException e) {
                  LogSupport.ignore(log, e);
                }
              }
            })
        .start();

    // hook processes output to browser's input (sync)
    // if browser closes stream, we should detect it and kill process...
    try {
      // read any headers off the top of our input stream
      LineInput li = new LineInput(p.getInputStream());
      HttpFields fields = new HttpFields();
      fields.read(li);

      String ContentStatus = "Status";
      String redirect = fields.get(HttpFields.__Location);
      String status = fields.get(ContentStatus);

      if (status != null) {
        log.debug("Found a Status header - setting status on response");
        fields.remove(ContentStatus);

        // NOTE: we ignore any reason phrase, otherwise we
        // would need to use res.sendError() selectively.
        int i = status.indexOf(' ');
        if (i > 0) status = status.substring(0, i);

        res.setStatus(Integer.parseInt(status));
      }

      // copy remaining headers into response...
      for (Iterator i = fields.iterator(); i.hasNext(); ) {
        HttpFields.Entry e = (HttpFields.Entry) i.next();
        res.addHeader(e.getKey(), e.getValue());
      }

      if (status == null && redirect != null) {
        // The CGI has set Location and is counting on us to do the redirect.
        // See http://CGI-Spec.Golux.Com/draft-coar-cgi-v11-03-clean.html#7.2.1.2
        if (!redirect.startsWith("http:/") && !redirect.startsWith("https:/"))
          res.sendRedirect(redirect);
        else res.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
      }

      // copy remains of input onto output...
      IO.copy(li, res.getOutputStream());

      p.waitFor();
      int exitValue = p.exitValue();
      if (log.isDebugEnabled()) log.debug("CGI: p.exitValue(): " + exitValue);
      if (0 != exitValue) {
        log.warn("Non-zero exit status (" + exitValue + ") from CGI program: " + path);
        if (!res.isCommitted()) res.sendError(500, "Failed to exec CGI");
      }
    } catch (IOException e) {
      // browser has probably closed its input stream - we
      // terminate and clean up...
      log.debug("CGI: Client closed connection!");
    } catch (InterruptedException ie) {
      log.debug("CGI: interrupted!");
    } finally {
      p.destroy();
    }

    if (log.isDebugEnabled()) log.debug("CGI: Finished exec: " + p);
  }
  public TaskHttpServletRequest(HttpServletRequest wrapping, Task task) {
    this.session = wrapping.getSession();
    String location = wrapping.getParameter("url");

    cookies = wrapping.getCookies();
    characterEncoding = wrapping.getCharacterEncoding();
    authType = wrapping.getAuthType();
    headerNames = new Vector<String>();
    headers = new MultiMap();
    for (Enumeration e = wrapping.getHeaderNames(); e.hasMoreElements(); ) {
      String headerName = (String) e.nextElement();
      for (Enumeration f = wrapping.getHeaders(headerName); f.hasMoreElements(); ) {
        String headerValue = (String) f.nextElement();
        headers.add(headerName, headerValue);
      }
    }
    contextPath = wrapping.getContextPath();
    pathInfo = wrapping.getPathInfo();
    pathTranslated = wrapping.getPathTranslated();
    remoteUser = wrapping.getRemoteUser(); // TODO check if needed
    requestedSessionId = wrapping.getRequestedSessionId(); // TODO check if needed
    userPrincipal = wrapping.getUserPrincipal(); // TODO check if needed
    requestedSessionIdFromCookie = wrapping.isRequestedSessionIdFromCookie();
    requestedSessionIdFromURL = wrapping.isRequestedSessionIdFromURL();
    requestedSessionIdValid = wrapping.isRequestedSessionIdValid();
    localAddr = wrapping.getLocalAddr();
    localName = wrapping.getLocalName();
    localPort = wrapping.getLocalPort();
    locale = wrapping.getLocale();
    locales = new Vector<Locale>();
    for (Enumeration e = wrapping.getLocales();
        e.hasMoreElements();
        locales.add((Locale) e.nextElement())) ;
    protocol = wrapping.getProtocol();
    remoteAddr = wrapping.getRemoteAddr();
    remoteHost = wrapping.getRemoteHost();
    remotePort = wrapping.getRemotePort();
    scheme = wrapping.getScheme();
    serverName = wrapping.getServerName();
    serverPort = wrapping.getServerPort();
    secure = wrapping.isSecure();

    // Extract the query (everything after ?)
    int idx = location.indexOf('?');
    query = null;
    if (idx != -1) {
      query = location.substring(idx + 1);
    }

    // Extract the URI (everything before ?)
    uri = location;
    if (idx != -1) {
      uri = uri.substring(0, idx);
    }

    // Servlet path (same as URI?)
    servletPath = uri;

    // Extract parameters
    params = new Hashtable<String, String[]>();
    if (query != null) {
      StringTokenizer t = new StringTokenizer(query, "&");
      while (t.hasMoreTokens()) {
        String token = t.nextToken();
        idx = token.indexOf('=');
        String name = token;
        String val = null;
        if (idx != -1) {
          name = token.substring(0, idx);
          val = token.substring(idx + 1);
        } else {
          val = "";
        }
        String[] vals = params.get(name);
        if (vals == null) {
          vals = new String[] {val};
        } else {
          String[] nvals = new String[vals.length + 1];
          System.arraycopy(vals, 0, nvals, 0, vals.length);
          nvals[vals.length] = val;
          vals = nvals;
        }
        params.put(name, vals);
      }
    }

    // Initialise attributes
    attributes = new Hashtable<String, Object>();

    // Create the URL (the URL with protocol / host / post)
    try {
      URL u = new URL(new URL(wrapping.getRequestURL().toString()), uri);
      url = new StringBuffer(u.toExternalForm());
    } catch (MalformedURLException e) {
    }

    setAttribute(ATTR_TASK, task);
  }
Beispiel #14
0
  @Override
  public void onTrigger(final ProcessContext context, final ProcessSession session)
      throws ProcessException {
    try {
      if (!initialized.get()) {
        initializeServer(context);
      }
    } catch (Exception e) {
      context.yield();
      throw new ProcessException("Failed to initialize the server", e);
    }

    final HttpRequestContainer container = containerQueue.poll();
    if (container == null) {
      return;
    }

    final long start = System.nanoTime();
    final HttpServletRequest request = container.getRequest();
    FlowFile flowFile = session.create();
    try {
      flowFile = session.importFrom(request.getInputStream(), flowFile);
    } catch (final IOException e) {
      getLogger()
          .error(
              "Failed to receive content from HTTP Request from {} due to {}",
              new Object[] {request.getRemoteAddr(), e});
      session.remove(flowFile);
      return;
    }

    final String charset =
        request.getCharacterEncoding() == null
            ? context.getProperty(URL_CHARACTER_SET).getValue()
            : request.getCharacterEncoding();

    final String contextIdentifier = UUID.randomUUID().toString();
    final Map<String, String> attributes = new HashMap<>();
    try {
      putAttribute(attributes, HTTPUtils.HTTP_CONTEXT_ID, contextIdentifier);
      putAttribute(attributes, "mime.type", request.getContentType());
      putAttribute(attributes, "http.servlet.path", request.getServletPath());
      putAttribute(attributes, "http.context.path", request.getContextPath());
      putAttribute(attributes, "http.method", request.getMethod());
      putAttribute(attributes, "http.local.addr", request.getLocalAddr());
      putAttribute(attributes, HTTPUtils.HTTP_LOCAL_NAME, request.getLocalName());
      if (request.getQueryString() != null) {
        putAttribute(
            attributes, "http.query.string", URLDecoder.decode(request.getQueryString(), charset));
      }
      putAttribute(attributes, HTTPUtils.HTTP_REMOTE_HOST, request.getRemoteHost());
      putAttribute(attributes, "http.remote.addr", request.getRemoteAddr());
      putAttribute(attributes, "http.remote.user", request.getRemoteUser());
      putAttribute(attributes, HTTPUtils.HTTP_REQUEST_URI, request.getRequestURI());
      putAttribute(attributes, "http.request.url", request.getRequestURL().toString());
      putAttribute(attributes, "http.auth.type", request.getAuthType());

      putAttribute(attributes, "http.requested.session.id", request.getRequestedSessionId());
      if (request.getDispatcherType() != null) {
        putAttribute(attributes, "http.dispatcher.type", request.getDispatcherType().name());
      }
      putAttribute(attributes, "http.character.encoding", request.getCharacterEncoding());
      putAttribute(attributes, "http.locale", request.getLocale());
      putAttribute(attributes, "http.server.name", request.getServerName());
      putAttribute(attributes, HTTPUtils.HTTP_PORT, request.getServerPort());

      final Enumeration<String> paramEnumeration = request.getParameterNames();
      while (paramEnumeration.hasMoreElements()) {
        final String paramName = paramEnumeration.nextElement();
        final String value = request.getParameter(paramName);
        attributes.put("http.param." + paramName, value);
      }

      final Cookie[] cookies = request.getCookies();
      if (cookies != null) {
        for (final Cookie cookie : cookies) {
          final String name = cookie.getName();
          final String cookiePrefix = "http.cookie." + name + ".";
          attributes.put(cookiePrefix + "value", cookie.getValue());
          attributes.put(cookiePrefix + "domain", cookie.getDomain());
          attributes.put(cookiePrefix + "path", cookie.getPath());
          attributes.put(cookiePrefix + "max.age", String.valueOf(cookie.getMaxAge()));
          attributes.put(cookiePrefix + "version", String.valueOf(cookie.getVersion()));
          attributes.put(cookiePrefix + "secure", String.valueOf(cookie.getSecure()));
        }
      }

      final String queryString = request.getQueryString();
      if (queryString != null) {
        final String[] params = URL_QUERY_PARAM_DELIMITER.split(queryString);
        for (final String keyValueString : params) {
          final int indexOf = keyValueString.indexOf("=");
          if (indexOf < 0) {
            // no =, then it's just a key with no value
            attributes.put("http.query.param." + URLDecoder.decode(keyValueString, charset), "");
          } else {
            final String key = keyValueString.substring(0, indexOf);
            final String value;

            if (indexOf == keyValueString.length() - 1) {
              value = "";
            } else {
              value = keyValueString.substring(indexOf + 1);
            }

            attributes.put(
                "http.query.param." + URLDecoder.decode(key, charset),
                URLDecoder.decode(value, charset));
          }
        }
      }
    } catch (final UnsupportedEncodingException uee) {
      throw new ProcessException(
          "Invalid character encoding", uee); // won't happen because charset has been validated
    }

    final Enumeration<String> headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
      final String headerName = headerNames.nextElement();
      final String headerValue = request.getHeader(headerName);
      putAttribute(attributes, "http.headers." + headerName, headerValue);
    }

    final Principal principal = request.getUserPrincipal();
    if (principal != null) {
      putAttribute(attributes, "http.principal.name", principal.getName());
    }

    final X509Certificate certs[] =
        (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate");
    final String subjectDn;
    if (certs != null && certs.length > 0) {
      final X509Certificate cert = certs[0];
      subjectDn = cert.getSubjectDN().getName();
      final String issuerDn = cert.getIssuerDN().getName();

      putAttribute(attributes, HTTPUtils.HTTP_SSL_CERT, subjectDn);
      putAttribute(attributes, "http.issuer.dn", issuerDn);
    } else {
      subjectDn = null;
    }

    flowFile = session.putAllAttributes(flowFile, attributes);

    final HttpContextMap contextMap =
        context.getProperty(HTTP_CONTEXT_MAP).asControllerService(HttpContextMap.class);
    final boolean registered =
        contextMap.register(
            contextIdentifier, request, container.getResponse(), container.getContext());

    if (!registered) {
      getLogger()
          .warn(
              "Received request from {} but could not process it because too many requests are already outstanding; responding with SERVICE_UNAVAILABLE",
              new Object[] {request.getRemoteAddr()});

      try {
        container.getResponse().setStatus(Status.SERVICE_UNAVAILABLE.getStatusCode());
        container.getResponse().flushBuffer();
        container.getContext().complete();
      } catch (final Exception e) {
        getLogger()
            .warn(
                "Failed to respond with SERVICE_UNAVAILABLE message to {} due to {}",
                new Object[] {request.getRemoteAddr(), e});
      }

      session.remove(flowFile);
      return;
    }

    final long receiveMillis = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
    session
        .getProvenanceReporter()
        .receive(
            flowFile,
            HTTPUtils.getURI(attributes),
            "Received from "
                + request.getRemoteAddr()
                + (subjectDn == null ? "" : " with DN=" + subjectDn),
            receiveMillis);
    session.transfer(flowFile, REL_SUCCESS);
    getLogger()
        .info(
            "Transferring {} to 'success'; received from {}",
            new Object[] {flowFile, request.getRemoteAddr()});
  }