protected static void configureClientCertContext(Tomcat tomcat) {
    TesterSupport.initSsl(tomcat);

    // Need a web application with a protected and unprotected URL
    // Must have a real docBase - just use temp
    Context ctx = tomcat.addContext("", System.getProperty("java.io.tmpdir"));

    Tomcat.addServlet(ctx, "simple", new SimpleServlet());
    ctx.addServletMapping("/unprotected", "simple");
    ctx.addServletMapping("/protected", "simple");

    // Security constraints
    SecurityCollection collection = new SecurityCollection();
    collection.addPattern("/protected");
    SecurityConstraint sc = new SecurityConstraint();
    sc.addAuthRole("testrole");
    sc.addCollection(collection);
    ctx.addConstraint(sc);

    // Configure the Realm
    MapRealm realm = new MapRealm();
    realm.addUser("CN=user1, C=US", "not used");
    realm.addUserRole("CN=user1, C=US", "testrole");
    ctx.setRealm(realm);

    // Configure the authenticator
    LoginConfig lc = new LoginConfig();
    lc.setAuthMethod("CLIENT-CERT");
    ctx.setLoginConfig(lc);
    ctx.getPipeline().addValve(new SSLAuthenticator());
  }
  private void setUpLogin() throws Exception {

    // Must have a real docBase for webapps - just use temp
    basicContext = tomcat.addContext(CONTEXT_PATH_LOGIN, System.getProperty("java.io.tmpdir"));
    basicContext.setSessionTimeout(SHORT_SESSION_TIMEOUT_MINS);

    // Add protected servlet to the context
    Tomcat.addServlet(basicContext, "TesterServlet3", new TesterServletEncodeUrl());
    basicContext.addServletMapping(URI_PROTECTED, "TesterServlet3");
    SecurityCollection collection = new SecurityCollection();
    collection.addPattern(URI_PROTECTED);
    SecurityConstraint sc = new SecurityConstraint();
    sc.addAuthRole(ROLE);
    sc.addCollection(collection);
    basicContext.addConstraint(sc);

    // Add unprotected servlet to the context
    Tomcat.addServlet(basicContext, "TesterServlet4", new TesterServletEncodeUrl());
    basicContext.addServletMapping(URI_PUBLIC, "TesterServlet4");
    SecurityCollection collection2 = new SecurityCollection();
    collection2.addPattern(URI_PUBLIC);
    SecurityConstraint sc2 = new SecurityConstraint();
    // do not add a role - which signals access permitted without one
    sc2.addCollection(collection2);
    basicContext.addConstraint(sc2);

    // Configure the authenticator and inherit the Realm from Engine
    LoginConfig lc = new LoginConfig();
    lc.setAuthMethod("BASIC");
    basicContext.setLoginConfig(lc);
    AuthenticatorBase basicAuthenticator = new BasicAuthenticator();
    basicContext.getPipeline().addValve(basicAuthenticator);
  }
예제 #3
0
    private FormAuthClientSelectedMethods(
        boolean clientShouldUseCookies,
        boolean serverShouldUseCookies,
        boolean serverShouldChangeSessid)
        throws Exception {

      Tomcat tomcat = getTomcatInstance();

      // No file system docBase required
      Context ctx = tomcat.addContext("", null);
      Tomcat.addServlet(ctx, "SelectedMethods", new SelectedMethodsServlet());
      ctx.addServletMapping("/test", "SelectedMethods");
      // Login servlet just needs to respond "OK". Client will handle
      // creating a valid response. No need for a form.
      Tomcat.addServlet(ctx, "Login", new TesterServlet());
      ctx.addServletMapping("/login", "Login");

      // Configure the security constraints
      SecurityConstraint constraint = new SecurityConstraint();
      SecurityCollection collection = new SecurityCollection();
      collection.setName("Protect PUT");
      collection.addMethod("PUT");
      collection.addPattern("/test");
      constraint.addCollection(collection);
      constraint.addAuthRole("tomcat");
      ctx.addConstraint(constraint);

      // Configure authentication
      LoginConfig lc = new LoginConfig();
      lc.setAuthMethod("FORM");
      lc.setLoginPage("/login");
      ctx.setLoginConfig(lc);
      ctx.getPipeline().addValve(new FormAuthenticator());

      setUseCookies(clientShouldUseCookies);
      ctx.setCookies(serverShouldUseCookies);

      MapRealm realm = new MapRealm();
      realm.addUser("tomcat", "tomcat");
      realm.addUserRole("tomcat", "tomcat");
      ctx.setRealm(realm);

      tomcat.start();

      // perhaps this does not work until tomcat has started?
      ctx.setSessionTimeout(TIMEOUT_MINS);

      // Valve pipeline is only established after tomcat starts
      Valve[] valves = ctx.getPipeline().getValves();
      for (Valve valve : valves) {
        if (valve instanceof AuthenticatorBase) {
          ((AuthenticatorBase) valve).setChangeSessionIdOnAuthentication(serverShouldChangeSessid);
          break;
        }
      }

      // Port only known after Tomcat starts
      setPort(getPort());
    }
  /**
   * Perform access control based on the specified authorization constraint. Return <code>true
   * </code> if this constraint is satisfied and processing should continue, or <code>false</code>
   * otherwise.
   *
   * @param request Request we are processing
   * @param response Response we are creating
   * @param constraint Security constraint we are enforcing
   * @exception IOException if an input/output error occurs
   */
  protected boolean accessControl(
      HttpRequest request, HttpResponse response, SecurityConstraint constraint)
      throws IOException {

    if (constraint == null) return (true);

    // Specifically allow access to the form login and form error pages
    // and the "j_security_check" action
    LoginConfig config = context.getLoginConfig();
    if ((config != null) && (Constants.FORM_METHOD.equals(config.getAuthMethod()))) {
      String requestURI = request.getDecodedRequestURI();
      String loginPage = context.getPath() + config.getLoginPage();
      if (loginPage.equals(requestURI)) {
        if (debug >= 1) log(" Allow access to login page " + loginPage);
        return (true);
      }
      String errorPage = context.getPath() + config.getErrorPage();
      if (errorPage.equals(requestURI)) {
        if (debug >= 1) log(" Allow access to error page " + errorPage);
        return (true);
      }
      if (requestURI.endsWith(Constants.FORM_ACTION)) {
        if (debug >= 1) log(" Allow access to username/password submission");
        return (true);
      }
    }

    // Which user principal have we already authenticated?
    Principal principal = ((HttpServletRequest) request.getRequest()).getUserPrincipal();
    if (principal == null) {
      if (debug >= 2) log("  No user authenticated, cannot grant access");
      ((HttpServletResponse) response.getResponse())
          .sendError(
              HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
              sm.getString("authenticator.notAuthenticated"));
      return (false);
    }

    // Check each role included in this constraint
    Realm realm = context.getRealm();
    String roles[] = constraint.findAuthRoles();
    if (roles == null) roles = new String[0];

    if (constraint.getAllRoles()) return (true);
    if ((roles.length == 0) && (constraint.getAuthConstraint())) {
      ((HttpServletResponse) response.getResponse())
          .sendError(HttpServletResponse.SC_FORBIDDEN, sm.getString("authenticator.forbidden"));
      return (false); // No listed roles means no access at all
    }
    for (int i = 0; i < roles.length; i++) {
      if (realm.hasRole(principal, roles[i])) return (true);
    }

    // Return a "Forbidden" message denying access to this resource
    ((HttpServletResponse) response.getResponse())
        .sendError(HttpServletResponse.SC_FORBIDDEN, sm.getString("authenticator.forbidden"));
    return (false);
  }
예제 #5
0
  @Test
  public void testBug50015() throws Exception {
    // Test that configuring servlet security constraints programmatically
    // does work.

    // Set up a container
    Tomcat tomcat = getTomcatInstance();

    // No file system docBase required
    Context ctx = tomcat.addContext("", null);

    // Setup realm
    MapRealm realm = new MapRealm();
    realm.addUser("tomcat", "tomcat");
    realm.addUserRole("tomcat", "tomcat");
    ctx.setRealm(realm);

    // Configure app for BASIC auth
    LoginConfig lc = new LoginConfig();
    lc.setAuthMethod("BASIC");
    ctx.setLoginConfig(lc);
    ctx.getPipeline().addValve(new BasicAuthenticator());

    // Add ServletContainerInitializer
    ServletContainerInitializer sci = new Bug50015SCI();
    ctx.addServletContainerInitializer(sci, null);

    // Start the context
    tomcat.start();

    // Request the first servlet
    ByteChunk bc = new ByteChunk();
    int rc = getUrl("http://localhost:" + getPort() + "/bug50015", bc, null);

    // Check for a 401
    assertNotSame("OK", bc.toString());
    assertEquals(401, rc);
  }
예제 #6
0
  @Test
  public void testBug50015() throws Exception {
    // Set up a container
    Tomcat tomcat = getTomcatInstance();

    // Must have a real docBase - just use temp
    File docBase = new File(System.getProperty("java.io.tmpdir"));
    Context ctx = tomcat.addContext("", docBase.getAbsolutePath());

    // Setup realm
    MapRealm realm = new MapRealm();
    realm.addUser("tomcat", "tomcat");
    realm.addUserRole("tomcat", "tomcat");
    ctx.setRealm(realm);

    // Configure app for BASIC auth
    LoginConfig lc = new LoginConfig();
    lc.setAuthMethod("BASIC");
    ctx.setLoginConfig(lc);
    ctx.getPipeline().addValve(new BasicAuthenticator());

    // Add ServletContainerInitializer
    ServletContainerInitializer sci = new Bug50015SCI();
    ctx.addServletContainerInitializer(sci, null);

    // Start the context
    tomcat.start();

    // Request the first servlet
    ByteChunk bc = new ByteChunk();
    int rc = getUrl("http://localhost:" + getPort() + "/bug50015", bc, null);

    // Check for a 401
    assertNotSame("OK", bc.toString());
    assertEquals(401, rc);
  }
예제 #7
0
  public static void main(String[] args) {

    // invoke: http://localhost:8080/Modern or  http://localhost:8080/Primitive

    System.setProperty("catalina.base", System.getProperty("user.dir"));
    Connector connector = new HttpConnector();
    Wrapper wrapper1 = new SimpleWrapper();
    wrapper1.setName("Primitive");
    wrapper1.setServletClass("PrimitiveServlet");
    Wrapper wrapper2 = new SimpleWrapper();
    wrapper2.setName("Modern");
    wrapper2.setServletClass("ModernServlet");

    Context context = new StandardContext();
    // StandardContext's start method adds a default mapper
    context.setPath("/myApp");
    context.setDocBase("myApp");
    LifecycleListener listener = new SimpleContextConfig();
    ((Lifecycle) context).addLifecycleListener(listener);

    context.addChild(wrapper1);
    context.addChild(wrapper2);
    // for simplicity, we don't add a valve, but you can add
    // valves to context or wrapper just as you did in Chapter 6

    Loader loader = new WebappLoader();
    context.setLoader(loader);
    // context.addServletMapping(pattern, name);
    context.addServletMapping("/Primitive", "Primitive");
    context.addServletMapping("/Modern", "Modern");
    // add ContextConfig. This listener is important because it configures
    // StandardContext (sets configured to true), otherwise StandardContext
    // won't start

    // add constraint
    SecurityCollection securityCollection = new SecurityCollection();
    securityCollection.addPattern("/");
    securityCollection.addMethod("GET");

    SecurityConstraint constraint = new SecurityConstraint();
    constraint.addCollection(securityCollection);
    constraint.addAuthRole("manager");
    LoginConfig loginConfig = new LoginConfig();
    loginConfig.setRealmName("Simple Realm");
    // add realm
    Realm realm = new SimpleRealm();

    context.setRealm(realm);
    context.addConstraint(constraint);
    context.setLoginConfig(loginConfig);

    connector.setContainer(context);

    try {
      connector.initialize();
      ((Lifecycle) connector).start();
      ((Lifecycle) context).start();

      // make the application wait until we press a key.
      System.in.read();
      ((Lifecycle) context).stop();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /**
   * Authenticate the user making this request, based on the specified login configuration. Return
   * <code>true</code> if any specified constraint has been satisfied, or <code>false</code> if we
   * have created a response challenge already.
   *
   * @param request Request we are processing
   * @param response Response we are creating
   * @param config Login configuration describing how authentication should be performed
   * @exception IOException if an input/output error occurs
   */
  @Override
  public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config)
      throws IOException {

    // Have we already authenticated someone?
    Principal principal = request.getUserPrincipal();
    String ssoId = (String) request.getNote(Constants.REQ_SSOID_NOTE);
    if (principal != null) {
      if (log.isDebugEnabled()) log.debug("Already authenticated '" + principal.getName() + "'");
      // Associate the session with any existing SSO session
      if (ssoId != null) associate(ssoId, request.getSessionInternal(true));
      return (true);
    }

    // Is there an SSO session against which we can try to reauthenticate?
    if (ssoId != null) {
      if (log.isDebugEnabled())
        log.debug("SSO Id " + ssoId + " set; attempting " + "reauthentication");
      /* Try to reauthenticate using data cached by SSO.  If this fails,
      either the original SSO logon was of DIGEST or SSL (which
      we can't reauthenticate ourselves because there is no
      cached username and password), or the realm denied
      the user's reauthentication for some reason.
      In either case we have to prompt the user for a logon */
      if (reauthenticateFromSSO(ssoId, request)) return true;
    }

    // Validate any credentials already included with this request
    String username = null;
    String password = null;

    MessageBytes authorization =
        request.getCoyoteRequest().getMimeHeaders().getValue("authorization");

    if (authorization != null) {
      authorization.toBytes();
      ByteChunk authorizationBC = authorization.getByteChunk();
      if (authorizationBC.startsWithIgnoreCase("basic ", 0)) {
        authorizationBC.setOffset(authorizationBC.getOffset() + 6);
        // FIXME: Add trimming
        // authorizationBC.trim();

        CharChunk authorizationCC = authorization.getCharChunk();
        Base64.decode(authorizationBC, authorizationCC);

        // Get username and password
        int colon = authorizationCC.indexOf(':');
        if (colon < 0) {
          username = authorizationCC.toString();
        } else {
          char[] buf = authorizationCC.getBuffer();
          username = new String(buf, 0, colon);
          password = new String(buf, colon + 1, authorizationCC.getEnd() - colon - 1);
        }

        authorizationBC.setOffset(authorizationBC.getOffset() - 6);
      }

      principal = context.getRealm().authenticate(username, password);
      if (principal != null) {
        register(request, response, principal, Constants.BASIC_METHOD, username, password);
        return (true);
      }
    }

    StringBuilder value = new StringBuilder(16);
    value.append("Basic realm=\"");
    if (config.getRealmName() == null) {
      value.append(REALM_NAME);
    } else {
      value.append(config.getRealmName());
    }
    value.append('\"');
    response.setHeader(AUTH_HEADER_NAME, value.toString());
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    return (false);
  }
  /**
   * Perform access control based on the specified authorization constraint. Return <code>true
   * </code> if this constraint is satisfied and processing should continue, or <code>false</code>
   * otherwise.
   *
   * @param request Request we are processing
   * @param response Response we are creating
   * @param constraints Security constraint we are enforcing
   * @param context The Context to which client of this class is attached.
   * @exception IOException if an input/output error occurs
   */
  @Override
  public boolean hasResourcePermission(
      Request request, Response response, SecurityConstraint[] constraints, Context context)
      throws IOException {

    if (constraints == null || constraints.length == 0) return (true);

    // Specifically allow access to the form login and form error pages
    // and the "j_security_check" action
    LoginConfig config = context.getLoginConfig();
    if ((config != null) && (Constants.FORM_METHOD.equals(config.getAuthMethod()))) {
      String requestURI = request.getRequestPathMB().toString();
      String loginPage = config.getLoginPage();
      if (loginPage.equals(requestURI)) {
        if (log.isDebugEnabled()) log.debug(" Allow access to login page " + loginPage);
        return (true);
      }
      String errorPage = config.getErrorPage();
      if (errorPage.equals(requestURI)) {
        if (log.isDebugEnabled()) log.debug(" Allow access to error page " + errorPage);
        return (true);
      }
      if (requestURI.endsWith(Constants.FORM_ACTION)) {
        if (log.isDebugEnabled()) log.debug(" Allow access to username/password submission");
        return (true);
      }
    }

    // Which user principal have we already authenticated?
    Principal principal = request.getPrincipal();
    boolean status = false;
    boolean denyfromall = false;
    for (int i = 0; i < constraints.length; i++) {
      SecurityConstraint constraint = constraints[i];

      String roles[];
      if (constraint.getAllRoles()) {
        // * means all roles defined in web.xml
        roles = request.getContext().findSecurityRoles();
      } else {
        roles = constraint.findAuthRoles();
      }

      if (roles == null) roles = new String[0];

      if (log.isDebugEnabled()) log.debug("  Checking roles " + principal);

      if (roles.length == 0 && !constraint.getAllRoles()) {
        if (constraint.getAuthConstraint()) {
          if (log.isDebugEnabled()) log.debug("No roles");
          status = false; // No listed roles means no access at all
          denyfromall = true;
          break;
        }

        if (log.isDebugEnabled()) log.debug("Passing all access");
        status = true;
      } else if (principal == null) {
        if (log.isDebugEnabled()) log.debug("  No user authenticated, cannot grant access");
      } else {
        for (int j = 0; j < roles.length; j++) {
          if (hasRole(null, principal, roles[j])) {
            status = true;
            if (log.isDebugEnabled()) log.debug("Role found:  " + roles[j]);
          } else if (log.isDebugEnabled()) log.debug("No role found:  " + roles[j]);
        }
      }
    }

    if (!denyfromall && allRolesMode != AllRolesMode.STRICT_MODE && !status && principal != null) {
      if (log.isDebugEnabled()) {
        log.debug("Checking for all roles mode: " + allRolesMode);
      }
      // Check for an all roles(role-name="*")
      for (int i = 0; i < constraints.length; i++) {
        SecurityConstraint constraint = constraints[i];
        String roles[];
        // If the all roles mode exists, sets
        if (constraint.getAllRoles()) {
          if (allRolesMode == AllRolesMode.AUTH_ONLY_MODE) {
            if (log.isDebugEnabled()) {
              log.debug("Granting access for role-name=*, auth-only");
            }
            status = true;
            break;
          }

          // For AllRolesMode.STRICT_AUTH_ONLY_MODE there must be zero roles
          roles = request.getContext().findSecurityRoles();
          if (roles.length == 0 && allRolesMode == AllRolesMode.STRICT_AUTH_ONLY_MODE) {
            if (log.isDebugEnabled()) {
              log.debug("Granting access for role-name=*, strict auth-only");
            }
            status = true;
            break;
          }
        }
      }
    }

    // Return a "Forbidden" message denying access to this resource
    if (!status) {
      response.sendError(HttpServletResponse.SC_FORBIDDEN, sm.getString("realmBase.forbidden"));
    }
    return status;
  }
  @Override
  protected void doStart() throws ElasticsearchException {
    try {

      final String currentDir = new File(".").getCanonicalPath();
      final String tomcatDir = currentDir + File.separatorChar + "tomcat";

      logger.debug("cur dir " + currentDir);

      if (tomcat != null) {
        try {
          tomcat.stop();
          tomcat.destroy();
        } catch (final Exception e) {

        }
      }

      tomcat = new ExtendedTomcat();
      tomcat.enableNaming();
      tomcat.getServer().setPort(-1); // shutdown disabled
      tomcat.getServer().setAddress("localhost");

      final String httpProtocolImpl =
          blockingServer
              ? "org.apache.coyote.http11.Http11Protocol"
              : "org.apache.coyote.http11.Http11NioProtocol";

      final Connector httpConnector = new Connector(httpProtocolImpl);
      tomcat.setConnector(httpConnector);
      tomcat.getService().addConnector(httpConnector);

      // TODO report tomcat bug with setProtocol

      if (maxContentLength != null) {
        httpConnector.setMaxPostSize(maxContentLength.bytesAsInt());
      }

      if (maxHeaderSize != null) {
        httpConnector.setAttribute("maxHttpHeaderSize", maxHeaderSize.bytesAsInt());
      }

      if (tcpNoDelay != null) {
        httpConnector.setAttribute("tcpNoDelay", tcpNoDelay.booleanValue());
      }

      if (reuseAddress != null) {
        httpConnector.setAttribute("socket.soReuseAddress", reuseAddress.booleanValue());
      }

      if (tcpKeepAlive != null) {
        httpConnector.setAttribute("socket.soKeepAlive", tcpKeepAlive.booleanValue());
        httpConnector.setAttribute(
            "maxKeepAliveRequests", tcpKeepAlive.booleanValue() ? "100" : "1");
      }

      if (tcpReceiveBufferSize != null) {
        httpConnector.setAttribute("socket.rxBufSize", tcpReceiveBufferSize.bytesAsInt());
      }

      if (tcpSendBufferSize != null) {
        httpConnector.setAttribute("socket.txBufSize", tcpSendBufferSize.bytesAsInt());
      }

      httpConnector.setAttribute(
          "compression", compression ? String.valueOf(compressionLevel) : "off");

      if (maxChunkSize != null) {
        httpConnector.setAttribute("maxExtensionSize", maxChunkSize.bytesAsInt());
      }

      httpConnector.setPort(Integer.parseInt(port));

      tomcat.setBaseDir(tomcatDir);

      final TomcatHttpTransportHandlerServlet servlet = new TomcatHttpTransportHandlerServlet();
      servlet.setTransport(this);

      final Context ctx = tomcat.addContext("", currentDir);

      logger.debug("currentDir " + currentDir);

      Tomcat.addServlet(ctx, "ES Servlet", servlet);

      ctx.addServletMapping("/*", "ES Servlet");

      if (useSSL) {
        logger.info("Using SSL");

        // System.setProperty("javax.net.debug", "ssl");
        httpConnector.setAttribute("SSLEnabled", "true");
        httpConnector.setSecure(true);
        httpConnector.setScheme("https");

        httpConnector.setAttribute("sslProtocol", "TLS");

        httpConnector.setAttribute(
            "keystoreFile", settings.get("security.ssl.keystorefile", "keystore"));
        httpConnector.setAttribute(
            "keystorePass", settings.get("security.ssl.keystorepass", "changeit"));
        httpConnector.setAttribute(
            "keystoreType", settings.get("security.ssl.keystoretype", "JKS"));

        final String keyalias = settings.get("security.ssl.keyalias", null);

        if (keyalias != null) {
          httpConnector.setAttribute("keyAlias", keyalias);
        }

        if (useClientAuth) {

          logger.info(
              "Using SSL Client Auth (PKI), so user/roles will be retrieved from client certificate.");

          httpConnector.setAttribute("clientAuth", "true");

          httpConnector.setAttribute(
              "truststoreFile",
              settings.get("security.ssl.clientauth.truststorefile", "truststore"));
          httpConnector.setAttribute(
              "truststorePass", settings.get("security.ssl.clientauth.truststorepass", "changeit"));
          httpConnector.setAttribute(
              "truststoreType", settings.get("security.ssl.clientauth.truststoretype", "JKS"));

          /*final String loginconf = this.settings
          		.get("security.kerberos.login.conf.path");
          final String krbconf = this.settings
          		.get("security.kerberos.krb5.conf.path");

          SecurityUtil.setSystemPropertyToAbsoluteFile(
          		"java.security.auth.login.config", loginconf);
          SecurityUtil.setSystemPropertyToAbsoluteFile(
          		"java.security.krb5.conf", krbconf);*/

          // httpConnector.setAttribute("allowUnsafeLegacyRenegotiation", "true");

          final SecurityConstraint constraint = new SecurityConstraint();
          constraint.addAuthRole("*");
          constraint.setAuthConstraint(true);
          constraint.setUserConstraint("CONFIDENTIAL");

          final SecurityCollection col = new SecurityCollection();
          col.addPattern("/*");

          constraint.addCollection(col);
          ctx.addConstraint(constraint);

          final LoginConfig lc = new LoginConfig();
          lc.setAuthMethod("CLIENT-CERT");
          lc.setRealmName("clientcretificate");
          ctx.setLoginConfig(lc);

          configureJndiRealm(ctx);

          ctx.getPipeline().addValve(new SSLAuthenticator());
          logger.info("Auth Method is CLIENT-CERT");

          // http://pki-tutorial.readthedocs.org/en/latest/simple/

        }

      } else {
        if (useClientAuth) {
          logger.error("Client Auth only available with SSL");
          throw new RuntimeException("Client Auth only available with SSL");
        }

        // useClientAuth = false;
      }

      if (!useClientAuth) {
        if ("waffle".equalsIgnoreCase(kerberosMode)) {

          final Boolean testMode = settings.getAsBoolean("security.waffle.testmode", false);

          final FilterDef fd = new FilterDef();
          fd.setFilterClass("waffle.servlet.NegotiateSecurityFilter");
          fd.setFilterName("Waffle");

          if (testMode != null && testMode.booleanValue()) {

            fd.addInitParameter("principalFormat", "fqn");
            fd.addInitParameter("roleFormat", "both");
            fd.addInitParameter("allowGuestLogin", "true");
            fd.addInitParameter(
                "securityFilterProviders",
                "org.elasticsearch.plugins.security.waffle.TestProvider");

            logger.info(
                "Kerberos implementaton is WAFFLE in testmode (only work on Windows Operations system)");
          } else {
            final Map<String, String> waffleSettings =
                settings.getByPrefix("security.waffle").getAsMap();

            for (final String waffleKey : waffleSettings.keySet()) {

              fd.addInitParameter(waffleKey.substring(1), waffleSettings.get(waffleKey));

              logger.debug(waffleKey.substring(1) + "=" + waffleSettings.get(waffleKey));
            }

            fd.addInitParameter("principalFormat", "fqn");
            fd.addInitParameter("roleFormat", "both");
            fd.addInitParameter("allowGuestLogin", "false");

            logger.info(
                "Kerberos implementaton is WAFFLE (only work on Windows Operations system)");
          }

          ctx.addFilterDef(fd);
          final FilterMap fm = new FilterMap();
          fm.setFilterName("Waffle");
          fm.addURLPattern("/*");
          ctx.addFilterMap(fm);

        } else if ("spnegoad".equalsIgnoreCase(kerberosMode)) {

          // System.setProperty("sun.security.krb5.debug", "true"); // TODO
          // switch
          // off

          System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");

          final SecurityConstraint constraint = new SecurityConstraint();
          constraint.addAuthRole("*");
          constraint.setAuthConstraint(true);
          constraint.setDisplayName("spnego_sc_all");
          final SecurityCollection col = new SecurityCollection();
          col.addPattern("/*");

          constraint.addCollection(col);
          ctx.addConstraint(constraint);

          final LoginConfig lc = new LoginConfig();
          lc.setAuthMethod("SPNEGO");
          lc.setRealmName("SPNEGO");
          ctx.setLoginConfig(lc);

          logger.info("Kerberos implementaton is SPNEGOAD");

          configureJndiRealm(ctx);

          final ExtendedSpnegoAuthenticator spnegoValve = new ExtendedSpnegoAuthenticator();
          // spnegoValve.setLoginConfigName("es-login");
          spnegoValve.setStoreDelegatedCredential(true);
          ctx.getPipeline().addValve(spnegoValve);

          // final SpnegoAuthenticator spnegoValve = new SpnegoAuthenticator();
          // spnegoValve.setLoginEntryName("es-login");
          // ctx.getPipeline().addValve(spnegoValve);

        } else if ("none".equalsIgnoreCase(kerberosMode)) {

          logger.warn(
              "Kerberos is not configured so user/roles are unavailable. Host based security, in contrast, is woking. ");

        } else {
          logger.error(
              "No Kerberos implementaion '"
                  + kerberosMode
                  + "' found. Kerberos is therefore not configured so user/roles are unavailable. Host based security, in contrast, is woking. ");
        }
      }

      tomcat.start();

      logger.info("Tomcat started");

      InetSocketAddress bindAddress;
      try {
        bindAddress =
            new InetSocketAddress(
                networkService.resolveBindHostAddress(bindHost),
                tomcat.getConnector().getLocalPort());
      } catch (final Exception e) {
        throw new BindTransportException("Failed to resolve bind address", e);
      }

      InetSocketAddress publishAddress;
      try {
        publishAddress =
            new InetSocketAddress(
                networkService.resolvePublishHostAddress(publishHost), bindAddress.getPort());
      } catch (final Exception e) {
        throw new BindTransportException("Failed to resolve publish address", e);
      }

      logger.debug("bindAddress " + bindAddress);
      logger.debug("publishAddress " + publishAddress);

      boundAddress =
          new BoundTransportAddress(
              new InetSocketTransportAddress(bindAddress),
              new InetSocketTransportAddress(publishAddress));

    } catch (final Exception e) {
      throw new ElasticsearchException("Unable to start Tomcat", e);
    }
  }