java.lang.Object
net.i2p.router.web.RouterConsoleRunner
All Implemented Interfaces:
ClientApp, RouterApp

public class RouterConsoleRunnerextends Object implements RouterApp
Start the router console.
  • Field Details

    • _context

      private final RouterContext _context
      The router context.
    • _mgr

      private final ClientAppManager _mgr
      Manager starting and stopping the app.
    • _log

      private final Log _log
      Logger for the console.
    • _navHelper

      private final NavHelper _navHelper
      Helper building the navigation menu.
    • _state

      private volatile ClientAppState _state
      Current state of the console app.
    • _server

      private Server _server
      The Jetty server, null until started.
    • _jettyTimer

      private static ScheduledExecutorScheduler _jettyTimer
      Shared Jetty timer thread.
    • _listenPort

      private String _listenPort
      HTTP port the console listens on.
    • _listenHost

      private String _listenHost
      Host addresses the console listens on.
    • _sslListenPort

      private String _sslListenPort
      HTTPS port the console listens on.
    • _sslListenHost

      private String _sslListenHost
      Host addresses the HTTPS listener uses.
    • _webAppsDir

      private String _webAppsDir
      Directory holding the webapps to deploy.
    • DEFAULT_WEBAPP_CONFIG_FILENAME

      private static final String DEFAULT_WEBAPP_CONFIG_FILENAME
      File listing the webapps to deploy.
      See Also:
    • authenticator

      private static final DigestAuthenticator authenticator
      Jetty authenticator for the console login.
    • NAME

      private static final String NAME
      Name of this client app.
      See Also:
    • JETTY_REALM

      public static final String JETTY_REALM
      Realm name for console authentication.
      See Also:
    • JETTY_ROLE

      private static final String JETTY_ROLE
      Jetty role required by the protected pages.
      See Also:
    • PROP_CONSOLE_PW

      public static final String PROP_CONSOLE_PW
      Property name for the console authentication password.
      See Also:
    • PROP_PW_ENABLE

      public static final String PROP_PW_ENABLE
      Property name for enabling console authentication.
      See Also:
    • MD5_CREDENTIAL_TYPE

      private static final String MD5_CREDENTIAL_TYPE
      From Jetty Credential.java.
      See Also:
    • ROUTERCONSOLE

      public static final String ROUTERCONSOLE
      Name of the root console webapp.
      See Also:
    • PREFIX

      public static final String PREFIX
      Property prefix for webapp enable flags.
      See Also:
    • ENABLED

      public static final String ENABLED
      Property suffix for webapp enable flags.
      See Also:
    • PROP_KEYSTORE_PASSWORD

      public static final String PROP_KEYSTORE_PASSWORD
      Property name for the console keystore password.
      See Also:
    • PROP_KEY_PASSWORD

      public static final String PROP_KEY_PASSWORD
      Property name for the console SSL key password.
      See Also:
    • DEFAULT_LISTEN_PORT

      public static final int DEFAULT_LISTEN_PORT
      Default HTTP listen port for the console.
      See Also:
    • DEFAULT_WEBAPPS_DIR

      private static final String DEFAULT_WEBAPPS_DIR
      Default webapps directory.
      See Also:
    • USAGE

      private static final String USAGE
      Text shown for bad console arguments.
      See Also:
    • MIN_THREADS

      private static final int MIN_THREADS
      Handler thread counts, adjusted for connectors and acceptors in startConsole().
      See Also:
    • MAX_THREADS

      private static final int MAX_THREADS
      Handler thread counts, adjusted for connectors and acceptors in startConsole().
      See Also:
    • MAX_IDLE_TIME

      private static final int MAX_IDLE_TIME
      Idle time before Jetty closes a connection.
      See Also:
    • THREAD_NAME

      private static final String THREAD_NAME
      Name of the console's app thread.
      See Also:
    • PROP_DTG_ENABLED

      public static final String PROP_DTG_ENABLED
      Property name for the desktop GUI enable flag.
      See Also:
    • PROP_ALLOWED_HOSTS

      static final String PROP_ALLOWED_HOSTS
      Property name for hosts allowed to access the console.
      See Also:
    • WAR_FILTER

      static final FileFilter WAR_FILTER
      Accepts every .war file in the webapps directory except routerconsole.war, which is the root context rather than a plugin webapp.
  • Constructor Details

    • RouterConsoleRunner

      public RouterConsoleRunner(RouterContext ctx, ClientAppManager mgr, String[] args)
      Construct and start the console, parsing command-line arguments. Usage:
       non-SSL:
       RouterConsoleRunner
       RouterConsoleRunner 7657
       RouterConsoleRunner 7657 127.0.0.1
       RouterConsoleRunner 7657 127.0.0.1,::1
       RouterConsoleRunner 7657 127.0.0.1,::1 ./webapps/.
      
      SSL:
       RouterConsoleRunner -s 7657
       RouterConsoleRunner -s 7657 127.0.0.1
       RouterConsoleRunner -s 7657 127.0.0.1,::1
       RouterConsoleRunner -s 7657 127.0.0.1,::1 ./webapps/
      
      If using both, non-SSL must be first:
       RouterConsoleRunner 7657 127.0.0.1 -s 7667
       RouterConsoleRunner 7657 127.0.0.1 -s 7667 127.0.0.1
       RouterConsoleRunner 7657 127.0.0.1,::1 -s 7667 127.0.0.1,::1
       RouterConsoleRunner 7657 127.0.0.1,::1 -s 7667 127.0.0.1,::1 ./webapps/
      
      Parameters:
      ctx - the router context
      mgr - the client app manager to register with, or null for a standalone run
      args - second arg may be a comma-separated list of bind addresses, for example ::1,127.0.0.1 On XP, the other order (127.0.0.1,::1) fails the IPV6 bind, because 127.0.0.1 will bind ::1 also. But even though it's bound to both, we can't connect to [::1]:7657 for some reason. So the wise choice is ::1,127.0.0.1
  • Method Details

    • main

      public static void main(String[] args)
      Start the console against the first running router context.
      Parameters:
      args - the console options, in the order documented on the constructor
    • startup

      public void startup()
      Start the console web server.
      Specified by:
      startup in interface ClientApp
    • shutdown

      public void shutdown(String[] args)
      Stop the console web server.
      Specified by:
      shutdown in interface ClientApp
      Parameters:
      args - generally null but could be stopArgs from clients.config
    • getState

      public ClientAppState getState()
      Current console state.
      Specified by:
      getState in interface ClientApp
      Returns:
      non-null
    • getName

      public String getName()
      The console's internal name.
      Specified by:
      getName in interface ClientApp
      Returns:
      non-null
    • getDisplayName

      public String getDisplayName()
      The console's display name.
      Specified by:
      getDisplayName in interface ClientApp
      Returns:
      non-null
    • changeState

      private void changeState(ClientAppState state)
      Records the new app state and notifies the app manager.
      Parameters:
      state - the state to move to
    • getConsoleServer

      Server getConsoleServer()
      The Jetty server backing the console.
      Returns:
      the server, may be null or stopped
    • getConsoleServer

      static Server getConsoleServer(I2PAppContext ctx)
      To get to Jetty. Warning, this will NOT work during shutdown, because changeState(STOPPING) will unregister us first.
      Parameters:
      ctx - the context whose registered console instance to look up
      Returns:
      may be null or stopped perhaps
    • jettyVersion

      public static String jettyVersion()
      The version string of the Jetty server library the console runs on.
      Returns:
      the Jetty version, as reported by Jetty itself
    • isSystrayEnabled

      static boolean isSystrayEnabled(I2PAppContext context)
      Package private for ConfigServiceHandler.
      Parameters:
      context - the context to read the desktopgui.enabled property from
      Returns:
      true if the desktop GUI tray icon is enabled, false if not or on a headless box
    • startTrayApp

      private void startTrayApp()
      Starts the system tray icon if enabled.
    • checkJavaVersion

      private void checkJavaVersion()
      Warn if the JVM is too old.
    • startConsole

      public void startConsole()
      Handler tree:
      Server
          HandlerCollection
              HostCheckHandler
                  ContextHandlerCollection
                      LocaleWebAppHandler (routerconsole)
                          SessionHandler
                          SecurityHandler
                          ServletHandler
                              servlets...
                      WebAppContext (i2psnark, i2ptunnel, imagegen,
                                     susidns, susimail, and each plugin with a .war)
              DefaultHandler
              RequestLogHandler (opt)
      
    • addListeners

      private int addListeners(List<Connector> connectors, Set<String> listenHosts, boolean hasIPV4, boolean hasIPV6)
      Add the HTTP listeners for the configured hosts, testing each bind before the connector is added, and register the console service with the port mapper.
      Parameters:
      connectors - the list to add the created connectors to
      listenHosts - collects the hosts successfully bound
      hasIPV4 - whether IPv4 is available
      hasIPV6 - whether IPv6 is available
      Returns:
      the number of hosts bound
    • addSSLListeners

      private int addSSLListeners(List<Connector> connectors, Set<String> listenHosts, boolean hasIPV4, boolean hasIPV6)
      Add the HTTPS listeners for the configured hosts, creating the self-signed keystore if needed and testing each bind before the connector is added, and register the HTTPS console service with the port mapper.
      Parameters:
      connectors - the list to add the created connectors to
      listenHosts - collects the hosts successfully bound
      hasIPV4 - whether IPv4 is available
      hasIPV6 - whether IPv6 is available
      Returns:
      the number of hosts bound
    • fixUpListenHosts

      private void fixUpListenHosts(Set<String> listenHosts, HostCheckHandler chCollWrapper)
      Expand the listen-host set with the local addresses and the allowed-hosts property, unless a wildcard address was configured, and hand it to the host check handler.
      Parameters:
      listenHosts - the configured hosts, modified in place
      chCollWrapper - the handler that rejects requests with an unexpected Host header
    • startConnectors

      private void startConnectors(List<Connector> connectors)
      Start the server, then add and start each connector one at a time so a failing bind does not take down the console.
      Parameters:
      connectors - the connectors to add, started in list order
    • startWebApps

      private List<String> startWebApps(ContextHandlerCollection chColl, Properties props)
      Start the other webapps in the webapps directory once the server is up, since Jetty starts the connector before the router console is ready; this makes startup faster and keeps one bad webapp from breaking the console. Enable-property rewrites are persisted here.
      Parameters:
      chColl - the context collection to add the webapps to
      props - the webapp properties, updated with the enable rewrites
      Returns:
      the names of the webapps that were not started
    • mapNotStartedWebApps

      private void mapNotStartedWebApps(ServletHandler rootServletHandler, List<String> notStarted)
      Map each not-started webapp to the no-webapp error page.
      Parameters:
      rootServletHandler - the root servlet handler to add the mappings to
      notStarted - the names of the webapps that did not start
    • startBackgroundServices

      private void startBackgroundServices()
      Start the graph generator, update manager, news manager, and plugin starter threads, and register the shutdown and signal handlers.
    • verifyKeyStore

      private boolean verifyKeyStore(File ks, Set<String> altNames)
      Check the console keystore, creating one with a self-signed keypair if needed.
      Parameters:
      ks - the keystore file to check
      altNames - the Subject Alternative Names if a new keystore is created, may be null
      Returns:
      true if the keystore exists with a password or was created successfully
    • createKeyStore

      private boolean createKeyStore(File ks, Set<String> altNames)
      Create a new keystore with a keypair in it.
      Parameters:
      ks - the keystore file to create
      altNames - the Subject Alternative Names for the new certificate, may be null
      Returns:
      true if the keystore was created
    • initialize

      static void initialize(RouterContext ctx, WebAppContext context)
      Set up basic security constraints for the webapp. Add all users and passwords.
      Parameters:
      ctx - the router context, supplying the config directory and password store
      context - the Jetty webapp context the constraints are attached to
    • webAppProperties

      private Properties webAppProperties()
      Loads the webapps config file.
      Returns:
      the properties read, empty if missing
    • webAppProperties

      public static Properties webAppProperties(I2PAppContext ctx)
      Webapp enable properties from the router config directory.
      Parameters:
      ctx - the context whose config directory holds the webapp config file
      Returns:
      the webapp enable properties, empty if the file does not exist yet
    • webAppProperties

      public static Properties webAppProperties(String dir)
      Webapp enable properties from the given directory.
      Parameters:
      dir - the directory holding the webapp config file
      Returns:
      the webapp enable properties, empty if the file does not exist or cannot be read
    • storeWebAppProperties

      public static void storeWebAppProperties(RouterContext ctx, Properties props)
      Persist the webapp enable properties to the config directory. A config directory that cannot be written is logged and otherwise ignored, so the flags are simply re-derived on the next start.
      Parameters:
      ctx - the router context, supplying the config directory to write to
      props - the webapp enable properties to store
    • stopAllWebApps

      private void stopAllWebApps()
      Stops all but the root webapp (routerconsole.war) In Jetty 9, stopping the server doesn't stop the non-root webapps, so we must do it here. There should be a better way to do this, possibly by making the webapps "managed".