Search in sources :

Example 1 with SecureDirectory

use of net.i2p.util.SecureDirectory in project i2p.i2p by i2p.

the class SSLUtil method verifyKeyStore.

/**
 *  Create a new selfsigned cert and keystore and pubkey cert if they don't exist.
 *  May take a while.
 *
 *  @param opts in/out, updated if rv is true
 *  @return false if it already exists; if true, caller must save opts
 *  @throws IOException on creation fail
 */
public static boolean verifyKeyStore(Properties opts) throws IOException {
    String name = opts.getProperty(PROP_KEY_ALIAS);
    if (name == null) {
        name = KeyStoreUtil.randomString();
        opts.setProperty(PROP_KEY_ALIAS, name);
    }
    String ksname = opts.getProperty(PROP_KS_NAME);
    if (ksname == null) {
        ksname = PREFIX + name + KS_SUFFIX;
        opts.setProperty(PROP_KS_NAME, ksname);
    }
    File ks = new File(ksname);
    if (!ks.isAbsolute()) {
        ks = new File(I2PAppContext.getGlobalContext().getConfigDir(), KS_DIR);
        ks = new File(ks, ksname);
    }
    if (ks.exists())
        return false;
    File dir = ks.getParentFile();
    if (!dir.exists()) {
        File sdir = new SecureDirectory(dir.getAbsolutePath());
        if (!sdir.mkdirs())
            throw new IOException("Unable to create keystore " + ks);
    }
    boolean rv = createKeyStore(ks, name, opts);
    if (!rv)
        throw new IOException("Unable to create keystore " + ks);
    // Now read it back out of the new keystore and save it in ascii form
    // where the clients can get to it.
    // Failure of this part is not fatal.
    exportCert(ks, name, opts);
    return true;
}
Also used : SecureDirectory(net.i2p.util.SecureDirectory) IOException(java.io.IOException) File(java.io.File)

Example 2 with SecureDirectory

use of net.i2p.util.SecureDirectory in project i2p.i2p by i2p.

the class SnarkManager method migrateConfig.

/**
 *  Migrate the old flat config file to the new config dir
 *  containing the config file minus the per-torrent entries,
 *  the dht file, and 64 subdirs for per-torrent config files
 *  Caller must synch.
 *
 *  @return the new config directory, non-null
 *  @throws RuntimeException on creation fail
 *  @since 0.9.15
 */
private File migrateConfig(File oldFile) {
    File dir = new SecureDirectory(oldFile + CONFIG_DIR_SUFFIX);
    if ((!dir.exists()) && (!dir.mkdirs())) {
        _log.error("Error creating I2PSnark config dir " + dir);
        throw new RuntimeException("Error creating I2PSnark config dir " + dir);
    }
    // move the DHT file as-is
    String oldName = oldFile.toString();
    if (oldName.endsWith(CONFIG_FILE_SUFFIX)) {
        String oldDHT = oldName.replace(CONFIG_FILE_SUFFIX, KRPC.DHT_FILE_SUFFIX);
        File oldDHTFile = new File(oldDHT);
        if (oldDHTFile.exists()) {
            File newDHTFile = new File(dir, "i2psnark" + KRPC.DHT_FILE_SUFFIX);
            FileUtil.rename(oldDHTFile, newDHTFile);
        }
    }
    if (!oldFile.exists())
        return dir;
    Properties oldProps = new Properties();
    try {
        DataHelper.loadProps(oldProps, oldFile);
        // a good time to fix this ancient typo
        String auto = (String) oldProps.remove(PROP_OLD_AUTO_START);
        if (auto != null)
            oldProps.setProperty(PROP_AUTO_START, auto);
    } catch (IOException ioe) {
        _log.error("Error loading I2PSnark config " + oldFile, ioe);
        return dir;
    }
    // Gather the props for each torrent, removing them from config
    // old b64 of hash as key
    Map<String, Properties> configs = new HashMap<String, Properties>(16);
    for (Iterator<Map.Entry<Object, Object>> iter = oldProps.entrySet().iterator(); iter.hasNext(); ) {
        Map.Entry<Object, Object> e = iter.next();
        String k = (String) e.getKey();
        if (k.startsWith(PROP_META_PREFIX)) {
            iter.remove();
            String v = (String) e.getValue();
            try {
                k = k.substring(PROP_META_PREFIX.length());
                // length of b64 of 160 bit infohash
                String h = k.substring(0, 28);
                // skip '.'
                k = k.substring(29);
                Properties tprops = configs.get(h);
                if (tprops == null) {
                    tprops = new OrderedProperties();
                    configs.put(h, tprops);
                }
                if (k.equals(PROP_META_BITFIELD)) {
                    // old config was timestamp,bitfield; split them
                    int comma = v.indexOf(',');
                    if (comma > 0 && v.length() > comma + 1) {
                        tprops.put(PROP_META_STAMP, v.substring(0, comma));
                        tprops.put(PROP_META_BITFIELD, v.substring(comma + 1));
                    } else {
                        // timestamp only??
                        tprops.put(PROP_META_STAMP, v);
                    }
                } else {
                    tprops.put(k, v);
                }
            } catch (IndexOutOfBoundsException ioobe) {
                continue;
            }
        }
    }
    // Now make a config file for each torrent
    for (Map.Entry<String, Properties> e : configs.entrySet()) {
        String b64 = e.getKey();
        Properties props = e.getValue();
        if (props.isEmpty())
            continue;
        b64 = b64.replace('$', '=');
        byte[] ih = Base64.decode(b64);
        if (ih == null || ih.length != 20)
            continue;
        File cfg = configFile(dir, ih);
        if (!cfg.exists()) {
            File subdir = cfg.getParentFile();
            if (!subdir.exists())
                subdir.mkdirs();
            try {
                DataHelper.storeProps(props, cfg);
            } catch (IOException ioe) {
                _log.error("Error storing I2PSnark config " + cfg, ioe);
            }
        }
    }
    // now store in new location, minus the zmeta entries
    File newFile = new File(dir, CONFIG_FILE);
    Properties newProps = new OrderedProperties();
    newProps.putAll(oldProps);
    try {
        DataHelper.storeProps(newProps, newFile);
    } catch (IOException ioe) {
        _log.error("Error storing I2PSnark config " + newFile, ioe);
        return dir;
    }
    oldFile.delete();
    if (_log.shouldLog(Log.WARN))
        _log.warn("Config migrated from " + oldFile + " to " + dir);
    return dir;
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) IOException(java.io.IOException) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) SecureDirectory(net.i2p.util.SecureDirectory) OrderedProperties(net.i2p.util.OrderedProperties) File(java.io.File) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 3 with SecureDirectory

use of net.i2p.util.SecureDirectory in project i2p.i2p by i2p.

the class RouterConsoleRunner method createKeyStore.

/**
 * Create a new keystore with a keypair in it.
 *
 * @return success
 * @since 0.8.3
 */
private boolean createKeyStore(File ks, Set<String> altNames) {
    // make a random 48 character password (30 * 8 / 5)
    String keyPassword = KeyStoreUtil.randomString();
    String cname = "localhost";
    boolean success = KeyStoreUtil.createKeys(ks, "console", cname, altNames, "Console", keyPassword);
    if (success) {
        success = ks.exists();
        if (success) {
            try {
                Map<String, String> changes = new HashMap<String, String>();
                changes.put(PROP_KEYSTORE_PASSWORD, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD);
                changes.put(PROP_KEY_PASSWORD, keyPassword);
                _context.router().saveConfig(changes, null);
            }// class cast exception
             catch (Exception e) {
            }
            // export cert, fails silently
            File dir = new SecureDirectory(_context.getConfigDir(), "certificates");
            dir.mkdir();
            dir = new SecureDirectory(dir, "console");
            dir.mkdir();
            File certFile = new File(dir, "console.local.crt");
            KeyStoreUtil.exportCert(ks, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, "console", certFile);
        }
    }
    if (success) {
        System.err.println("Created self-signed certificate for " + cname + " in keystore: " + ks.getAbsolutePath() + "\n" + "The certificate was generated randomly.\n" + "Unless you have changed the default settings, the certificate is not associated with your " + "IP address, host name, router identity, or destination keys.");
    } else {
        System.err.println("Failed to create console SSL keystore.\n" + "This is for the Sun/Oracle keytool, others may be incompatible.\n" + "If you create the keystore manually, you must add " + PROP_KEYSTORE_PASSWORD + " and " + PROP_KEY_PASSWORD + " to " + (new File(_context.getConfigDir(), "router.config")).getAbsolutePath());
    }
    return success;
}
Also used : HashMap(java.util.HashMap) SecureDirectory(net.i2p.util.SecureDirectory) File(java.io.File) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException)

Example 4 with SecureDirectory

use of net.i2p.util.SecureDirectory in project i2p.i2p by i2p.

the class RouterConsoleRunner method startConsole.

/**
 *  http://irc.codehaus.org/display/JETTY/Porting+to+jetty6
 *
 *<pre>
 *	Server
 *		HandlerCollection
 *			HostCheckHandler (extends GzipHandler)
 *				ContextHandlerCollection
 *					LocaleWebAppHandler (routerconsole)
 *						SessionHandler
 *						SecurityHandler
 *						ServletHandler
 *							servlets...
 *					WebAppContext (i2psnark)
 *					WebAppContext (i2ptunnel)
 *					WebAppContext (imagegen)
 *					WebAppContext (susidns)
 *					WebAppContext (susimail)
 *					WebAppContext (for each plugin with a .war)
 *			DefaultHandler
 *			RequestLogHandler (opt)
 *</pre>
 *
 *  Porting to Jetty 9:
 *
 *  http://dev.eclipse.org/mhonarc/lists/jetty-dev/msg01952.html
 *  You are missing a few facts about Jetty 9.1 ...
 *  First, there are no longer any blocking connectors.
 *  Its all async / nio connectors now. (mainly because that's the direction that the servlet api 3.1 is taking)
 *
 *  Next, there is only 1 connector.   The ServerConnector.
 *  However, it takes 1 or more ConnectionFactory implementations to know how to handle the incoming connection.
 *  We have factories for HTTP (0.9 thru 1.1), SPDY, SSL-http, and SSL-npn so far.
 *  This list of factories will expand as the future of connectivity to web servers is ever growing (think HTTP/2)
 *
 *  Use the embedded examples for help understanding this.
 *  http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/examples/embedded/src/main/java/org/eclipse/jetty/embedded/ManyConnectors.java?id=jetty-9.1.0.RC0
 */
public void startConsole() {
    File workDir = new SecureDirectory(_context.getTempDir(), "jetty-work");
    boolean workDirRemoved = FileUtil.rmdir(workDir, false);
    if (!workDirRemoved)
        System.err.println("ERROR: Unable to remove Jetty temporary work directory");
    boolean workDirCreated = workDir.mkdirs();
    if (!workDirCreated)
        System.err.println("ERROR: Unable to create Jetty temporary work directory");
    // so Jetty can find WebAppConfiguration
    System.setProperty("jetty.class.path", _context.getBaseDir() + "/lib/routerconsole.jar");
    // FIXME
    // http://dev.eclipse.org/mhonarc/lists/jetty-users/msg03487.html
    // _server.setGracefulShutdown(1000);
    // In Jetty 6, QTP was not concurrent, so we switched to
    // ThreadPoolExecutor with a fixed-size queue, a set maxThreads,
    // and a RejectedExecutionPolicy of CallerRuns.
    // Unfortunately, CallerRuns causes lockups in Jetty NIO (ticket #1395)
    // In addition, no flavor of TPE gives us what QTP does:
    // - TPE direct handoff (which we were using) never queues.
    // This doesn't provide any burst management when maxThreads is reached.
    // CallerRuns was an attempt to work around that.
    // - TPE unbounded queue does not adjust the number of threads.
    // This doesn't provide automatic resource management.
    // - TPE bounded queue does not add threads until the queue is full.
    // This doesn't provide good responsiveness to even small bursts.
    // QTP adds threads as soon as the queue is non-empty.
    // QTP as of Jetty 7 uses concurrent.
    // QTP unbounded queue is the default in Jetty.
    // So switch back to QTP with a bounded queue.
    // 
    // ref:
    // http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
    // https://wiki.eclipse.org/Jetty/Howto/High_Load
    // 
    // try {
    // ThreadPool ctp = new CustomThreadPoolExecutor();
    // // Gone in Jetty 7
    // //ctp.prestartAllCoreThreads();
    // _server.setThreadPool(ctp);
    // } catch (Throwable t) {
    // class not found...
    // System.out.println("INFO: Jetty concurrent ThreadPool unavailable, using QueuedThreadPool");
    LinkedBlockingQueue<Runnable> lbq = new LinkedBlockingQueue<Runnable>(4 * MAX_THREADS);
    // min and max threads will be reset below
    QueuedThreadPool qtp = new QueuedThreadPool(MAX_THREADS, MIN_THREADS, MAX_IDLE_TIME, lbq);
    qtp.setName(THREAD_NAME);
    qtp.setDaemon(true);
    _server = new Server(qtp);
    // }
    HandlerCollection hColl = new HandlerCollection();
    ContextHandlerCollection chColl = new ContextHandlerCollection();
    HostCheckHandler chCollWrapper = new HostCheckHandler(_context);
    chCollWrapper.setHandler(chColl);
    // gone in Jetty 7
    // _server.addHandler(hColl);
    _server.setHandler(hColl);
    hColl.addHandler(chCollWrapper);
    hColl.addHandler(new DefaultHandler());
    String log = _context.getProperty("routerconsole.log");
    if (log != null) {
        File logFile = new File(log);
        if (!logFile.isAbsolute())
            logFile = new File(_context.getLogDir(), "logs/" + log);
        try {
            RequestLogHandler rhl = new RequestLogHandler();
            rhl.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath()));
            hColl.addHandler(rhl);
        } catch (Exception ioe) {
            System.err.println("ERROR: Unable to create Jetty log: " + ioe);
        }
    }
    boolean rewrite = false;
    Properties props = webAppProperties();
    if (props.isEmpty()) {
        props.setProperty(PREFIX + ROUTERCONSOLE + ENABLED, "true");
        rewrite = true;
    }
    // Get an absolute path with a trailing slash for the webapps dir
    // We assume relative to the base install dir for backward compatibility
    File app = new File(_webAppsDir);
    if (!app.isAbsolute()) {
        app = new File(_context.getBaseDir(), _webAppsDir);
        try {
            _webAppsDir = app.getCanonicalPath();
        } catch (IOException ioe) {
        }
    }
    if (!_webAppsDir.endsWith("/"))
        _webAppsDir += '/';
    Set<String> listenHosts = new HashSet<String>(8);
    HandlerWrapper rootWebApp = null;
    ServletHandler rootServletHandler = null;
    List<Connector> connectors = new ArrayList<Connector>(4);
    try {
        int boundAddresses = 0;
        SortedSet<String> addresses = Addresses.getAllAddresses();
        boolean hasIPV4 = addresses.contains("0.0.0.0");
        boolean hasIPV6 = addresses.contains("0:0:0:0:0:0:0:0");
        // add standard listeners
        int lport = 0;
        if (_listenPort != null) {
            try {
                lport = Integer.parseInt(_listenPort);
            } catch (NumberFormatException nfe) {
            }
            if (lport <= 0)
                System.err.println("Bad routerconsole port " + _listenPort);
        }
        if (lport > 0) {
            List<String> hosts = new ArrayList<String>(2);
            StringTokenizer tok = new StringTokenizer(_listenHost, " ,");
            while (tok.hasMoreTokens()) {
                String host = tok.nextToken().trim();
                try {
                    // connectors are bad
                    if ((!hasIPV6) && Addresses.isIPv6Address(host))
                        throw new IOException("IPv6 addresses unsupported");
                    if ((!hasIPV4) && Addresses.isIPv4Address(host))
                        throw new IOException("IPv4 addresses unsupported");
                    ServerSocket testSock = null;
                    try {
                        // On Windows, this was passing and Jetty was still failing,
                        // possibly due to %scope_id ???
                        // https://issues.apache.org/jira/browse/ZOOKEEPER-667
                        // so do exactly what Jetty does in SelectChannelConnector.open()
                        testSock = new ServerSocket();
                        InetSocketAddress isa = new InetSocketAddress(host, 0);
                        testSock.bind(isa);
                    } finally {
                        if (testSock != null)
                            try {
                                testSock.close();
                            } catch (IOException ioe) {
                            }
                    }
                    HttpConfiguration httpConfig = new HttpConfiguration();
                    // number of acceptors, (default) number of selectors
                    ServerConnector lsnr = new ServerConnector(_server, 1, 0, new HttpConnectionFactory(httpConfig));
                    // lsnr.setUseDirectBuffers(false);  // default true seems to be leaky
                    lsnr.setHost(host);
                    lsnr.setPort(lport);
                    // default 10 sec
                    lsnr.setIdleTimeout(90 * 1000);
                    // all with same name will use the same thread pool
                    lsnr.setName("ConsoleSocket");
                    // _server.addConnector(lsnr);
                    connectors.add(lsnr);
                    boundAddresses++;
                    hosts.add(host);
                } catch (Exception ioe) {
                    System.err.println("Unable to bind routerconsole to " + host + " port " + _listenPort + ": " + ioe);
                    System.err.println("You may ignore this warning if the console is still available at http://localhost:" + _listenPort);
                }
            }
            if (hosts.isEmpty()) {
                _context.portMapper().register(PortMapper.SVC_CONSOLE, lport);
            } else {
                // put IPv4 first
                Collections.sort(hosts, new HostComparator());
                _context.portMapper().register(PortMapper.SVC_CONSOLE, hosts.get(0), lport);
                // note that we could still fail in connector.start() below
                listenHosts.addAll(hosts);
            }
        }
        // add SSL listeners
        int sslPort = 0;
        if (_sslListenPort != null) {
            try {
                sslPort = Integer.parseInt(_sslListenPort);
            } catch (NumberFormatException nfe) {
            }
            if (sslPort <= 0)
                System.err.println("Bad routerconsole SSL port " + _sslListenPort);
        }
        if (sslPort > 0) {
            File keyStore = new File(_context.getConfigDir(), "keystore/console.ks");
            // Put the list of hosts together early, so we can put it in the selfsigned cert.
            StringTokenizer tok = new StringTokenizer(_sslListenHost, " ,");
            Set<String> altNames = new HashSet<String>(4);
            while (tok.hasMoreTokens()) {
                String s = tok.nextToken().trim();
                if (!s.equals("0.0.0.0") && !s.equals("::") && !s.equals("0:0:0:0:0:0:0:0"))
                    altNames.add(s);
            }
            String allowed = _context.getProperty(PROP_ALLOWED_HOSTS);
            if (allowed != null) {
                tok = new StringTokenizer(allowed, " ,");
                while (tok.hasMoreTokens()) {
                    altNames.add(tok.nextToken().trim());
                }
            }
            if (verifyKeyStore(keyStore, altNames)) {
                // the keystore path and password
                SslContextFactory sslFactory = new SslContextFactory(keyStore.getAbsolutePath());
                sslFactory.setKeyStorePassword(_context.getProperty(PROP_KEYSTORE_PASSWORD, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD));
                // the X.509 cert password (if not present, verifyKeyStore() returned false)
                sslFactory.setKeyManagerPassword(_context.getProperty(PROP_KEY_PASSWORD, "thisWontWork"));
                sslFactory.addExcludeProtocols(I2PSSLSocketFactory.EXCLUDE_PROTOCOLS.toArray(new String[I2PSSLSocketFactory.EXCLUDE_PROTOCOLS.size()]));
                sslFactory.addExcludeCipherSuites(I2PSSLSocketFactory.EXCLUDE_CIPHERS.toArray(new String[I2PSSLSocketFactory.EXCLUDE_CIPHERS.size()]));
                List<String> hosts = new ArrayList<String>(2);
                tok = new StringTokenizer(_sslListenHost, " ,");
                while (tok.hasMoreTokens()) {
                    String host = tok.nextToken().trim();
                    // doing it this way means we don't have to escape an IPv6 host with []
                    try {
                        // connectors are bad
                        if ((!hasIPV6) && Addresses.isIPv6Address(host))
                            throw new IOException("IPv6 addresses unsupported");
                        if ((!hasIPV4) && Addresses.isIPv4Address(host))
                            throw new IOException("IPv4 addresses unsupported");
                        ServerSocket testSock = null;
                        try {
                            // see comments above
                            testSock = new ServerSocket();
                            InetSocketAddress isa = new InetSocketAddress(host, 0);
                            testSock.bind(isa);
                        } finally {
                            if (testSock != null)
                                try {
                                    testSock.close();
                                } catch (IOException ioe) {
                                }
                        }
                        HttpConfiguration httpConfig = new HttpConfiguration();
                        httpConfig.setSecureScheme("https");
                        httpConfig.setSecurePort(sslPort);
                        httpConfig.addCustomizer(new SecureRequestCustomizer());
                        // number of acceptors, (default) number of selectors
                        ServerConnector ssll = new ServerConnector(_server, 1, 0, new SslConnectionFactory(sslFactory, "http/1.1"), new HttpConnectionFactory(httpConfig));
                        // sssll.setUseDirectBuffers(false);  // default true seems to be leaky
                        ssll.setHost(host);
                        ssll.setPort(sslPort);
                        // default 10 sec
                        ssll.setIdleTimeout(90 * 1000);
                        // all with same name will use the same thread pool
                        ssll.setName("ConsoleSocket");
                        // _server.addConnector(ssll);
                        connectors.add(ssll);
                        boundAddresses++;
                        hosts.add(host);
                    } catch (Exception e) {
                        System.err.println("Unable to bind routerconsole to " + host + " port " + sslPort + " for SSL: " + e);
                        if (SystemVersion.isGNU())
                            System.err.println("Probably because GNU classpath does not support Sun keystores");
                        System.err.println("You may ignore this warning if the console is still available at https://localhost:" + sslPort);
                    }
                }
                if (hosts.isEmpty()) {
                    _context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE, sslPort);
                } else {
                    // put IPv4 first
                    Collections.sort(hosts, new HostComparator());
                    _context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE, hosts.get(0), sslPort);
                    // note that we could still fail in connector.start() below
                    listenHosts.addAll(hosts);
                }
            } else {
                System.err.println("Unable to create or access keystore for SSL: " + keyStore.getAbsolutePath());
            }
        }
        if (boundAddresses <= 0) {
            System.err.println("Unable to bind routerconsole to any address on port " + _listenPort + (sslPort > 0 ? (" or SSL port " + sslPort) : ""));
            return;
        }
        // Each address spawns a Connector and an Acceptor thread
        // If the min is less than this, we have no thread for the handlers or the expiration thread.
        qtp.setMinThreads(MIN_THREADS + (2 * boundAddresses));
        qtp.setMaxThreads(MAX_THREADS + (2 * boundAddresses));
        File tmpdir = new SecureDirectory(workDir, ROUTERCONSOLE + "-" + (_listenPort != null ? _listenPort : _sslListenPort));
        tmpdir.mkdir();
        rootServletHandler = new ServletHandler();
        rootWebApp = new LocaleWebAppHandler(_context, "/", _webAppsDir + ROUTERCONSOLE + ".war", tmpdir, rootServletHandler);
        try {
            // Not sure who is supposed to call this, but unless we do,
            // all the jsps die NPE, because JspFactory.getDefaultContext() returns null.
            // We probably have to do this because we don't bundle the Jetty annotations jar and scanner.
            // This is only with Tomcat 8, not with the Jetty (Eclipse) jsp impl.
            // Got a clue from this ancient post for Tomcat 6:
            // https://bz.apache.org/bugzilla/show_bug.cgi?id=39804
            // see also apps/jetty/build.xml
            Class.forName("org.eclipse.jetty.apache.jsp.JettyJasperInitializer");
        } catch (ClassNotFoundException cnfe) {
            System.err.println("Warning: JettyJasperInitializer not found");
        }
        WebAppContext wac = (WebAppContext) (rootWebApp.getHandler());
        initialize(_context, wac);
        WebAppStarter.setWebAppConfiguration(wac);
        chColl.addHandler(rootWebApp);
    } catch (Exception ioe) {
        ioe.printStackTrace();
    }
    // fix up the allowed hosts set (see HostCheckHandler)
    if (listenHosts.contains("0.0.0.0") || listenHosts.contains("::") || listenHosts.contains("0:0:0:0:0:0:0:0")) {
        // empty set says all are valid
        listenHosts.clear();
    } else {
        listenHosts.add("localhost");
        listenHosts.add("127.0.0.1");
        listenHosts.add("::1");
        listenHosts.add("0:0:0:0:0:0:0:1");
        String allowed = _context.getProperty(PROP_ALLOWED_HOSTS);
        if (allowed != null) {
            StringTokenizer tok = new StringTokenizer(allowed, " ,");
            while (tok.hasMoreTokens()) {
                listenHosts.add(tok.nextToken());
            }
        }
    }
    chCollWrapper.setListenHosts(listenHosts);
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=364936
    // WARN:oejw.WebAppContext:Failed startup of context o.e.j.w.WebAppContext{/,jar:file:/.../webapps/routerconsole.war!/},/.../webapps/routerconsole.war
    // java.lang.IllegalStateException: zip file closed
    Resource.setDefaultUseCaches(false);
    try {
        // start does a mapContexts()
        _server.start();
    } catch (Throwable me) {
        // NoClassFoundDefError from a webapp is a throwable, not an exception
        System.err.println("Error starting the Router Console server: " + me);
        me.printStackTrace();
    }
    if (_server.isRunning()) {
        // Add and start the connectors one-by-one
        boolean error = false;
        for (Connector conn : connectors) {
            try {
                _server.addConnector(conn);
                // start after adding so it gets the right thread pool
                conn.start();
            } catch (Throwable me) {
                try {
                    _server.removeConnector(conn);
                } catch (Throwable t) {
                    t.printStackTrace();
                }
                System.err.println("WARNING: Error starting " + conn + ": " + me);
                me.printStackTrace();
                error = true;
            }
        }
        if (error) {
            String port = (_listenPort != null) ? _listenPort : ((_sslListenPort != null) ? _sslListenPort : Integer.toString(DEFAULT_LISTEN_PORT));
            System.err.println("WARNING: Error starting one or more listeners of the Router Console server.\n" + "If your console is still accessible at http://127.0.0.1:" + port + "/,\n" + "this may be a problem only with binding to the IPV6 address ::1.\n" + "If so, you may ignore this error, or remove the\n" + "\"::1,\" in the \"clientApp.0.args\" line of the clients.config file.");
        }
    }
    // Start all the other webapps after the server is up,
    // so things start faster.
    // Jetty 6 starts the connector before the router console is ready
    // This also prevents one webapp from breaking the whole thing
    List<String> notStarted = new ArrayList<String>();
    if (_server.isRunning()) {
        File dir = new File(_webAppsDir);
        File[] files = dir.listFiles(WAR_FILTER);
        if (files != null) {
            for (int i = 0; i < files.length; i++) {
                String appName = files[i].getName();
                appName = appName.substring(0, appName.lastIndexOf(".war"));
                String enabled = props.getProperty(PREFIX + appName + ENABLED);
                if (appName.equals("addressbook")) {
                    // addressbook.war is now empty, thread is started by SusiDNS
                    if (enabled != null) {
                        props.remove(PREFIX + "addressbook" + ENABLED);
                        rewrite = true;
                    }
                } else if (!"false".equals(enabled)) {
                    try {
                        String path = files[i].getCanonicalPath();
                        WebAppStarter.startWebApp(_context, chColl, appName, path);
                        if (enabled == null) {
                            // do this so configclients.jsp knows about all apps from reading the config
                            props.setProperty(PREFIX + appName + ENABLED, "true");
                            rewrite = true;
                        }
                    } catch (Throwable t) {
                        System.err.println("ERROR: Failed to start " + appName + ' ' + t);
                        t.printStackTrace();
                        notStarted.add(appName);
                    }
                } else {
                    notStarted.add(appName);
                }
            }
            changeState(RUNNING);
            if (_mgr != null)
                _mgr.register(this);
        }
    } else {
        System.err.println("ERROR: Router console did not start, not starting webapps");
        changeState(START_FAILED);
    }
    if (rewrite)
        storeWebAppProperties(_context, props);
    if (rootServletHandler != null && notStarted.size() > 0) {
        // map each not-started webapp to the error page
        ServletHolder noWebApp = rootServletHandler.getServlet("net.i2p.router.web.jsp.nowebapp_jsp");
        for (int i = 0; i < notStarted.size(); i++) {
            // we want a new handler for each one since if the webapp is started we remove the handler???
            try {
                if (noWebApp != null) {
                    String path = '/' + notStarted.get(i);
                    // LocaleWebAppsHandler adds a .jsp
                    rootServletHandler.addServletWithMapping(noWebApp, path + ".jsp");
                    rootServletHandler.addServletWithMapping(noWebApp, path + "/*");
                } else {
                    System.err.println("Can't find nowebapp.jsp?");
                }
            } catch (Throwable me) {
                System.err.println(me);
                me.printStackTrace();
            }
        }
    }
    Thread t = new I2PAppThread(new StatSummarizer(), "StatSummarizer", true);
    t.setPriority(Thread.NORM_PRIORITY - 1);
    t.start();
    ConsoleUpdateManager um = new ConsoleUpdateManager(_context, _mgr, null);
    um.start();
    NewsManager nm = new NewsManager(_context, _mgr, null);
    nm.startup();
    if (PluginStarter.pluginsEnabled(_context)) {
        t = new I2PAppThread(new PluginStarter(_context), "PluginStarter", true);
        t.setPriority(Thread.NORM_PRIORITY - 1);
        t.start();
    }
    // RouterAppManager registers its own hook
    if (_mgr == null)
        _context.addShutdownTask(new ServerShutdown());
    ConfigServiceHandler.registerSignalHandler(_context);
}
Also used : Server(org.eclipse.jetty.server.Server) InetSocketAddress(java.net.InetSocketAddress) ArrayList(java.util.ArrayList) ContextHandlerCollection(org.eclipse.jetty.server.handler.ContextHandlerCollection) HttpConfiguration(org.eclipse.jetty.server.HttpConfiguration) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) ServerConnector(org.eclipse.jetty.server.ServerConnector) WebAppContext(org.eclipse.jetty.webapp.WebAppContext) NewsManager(net.i2p.router.news.NewsManager) HashSet(java.util.HashSet) File(java.io.File) AbstractConnector(org.eclipse.jetty.server.AbstractConnector) ServerConnector(org.eclipse.jetty.server.ServerConnector) Connector(org.eclipse.jetty.server.Connector) ServletHandler(org.eclipse.jetty.servlet.ServletHandler) ServletHolder(org.eclipse.jetty.servlet.ServletHolder) Properties(java.util.Properties) SslConnectionFactory(org.eclipse.jetty.server.SslConnectionFactory) HandlerWrapper(org.eclipse.jetty.server.handler.HandlerWrapper) I2PAppThread(net.i2p.util.I2PAppThread) SslContextFactory(org.eclipse.jetty.util.ssl.SslContextFactory) QueuedThreadPool(org.eclipse.jetty.util.thread.QueuedThreadPool) RequestLogHandler(org.eclipse.jetty.server.handler.RequestLogHandler) NCSARequestLog(org.eclipse.jetty.server.NCSARequestLog) ContextHandlerCollection(org.eclipse.jetty.server.handler.ContextHandlerCollection) HandlerCollection(org.eclipse.jetty.server.handler.HandlerCollection) SecureRequestCustomizer(org.eclipse.jetty.server.SecureRequestCustomizer) HttpConnectionFactory(org.eclipse.jetty.server.HttpConnectionFactory) ServerSocket(java.net.ServerSocket) ConsoleUpdateManager(net.i2p.router.update.ConsoleUpdateManager) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) Constraint(org.eclipse.jetty.util.security.Constraint) DefaultHandler(org.eclipse.jetty.server.handler.DefaultHandler) I2PAppThread(net.i2p.util.I2PAppThread) StringTokenizer(java.util.StringTokenizer) SecureDirectory(net.i2p.util.SecureDirectory)

Example 5 with SecureDirectory

use of net.i2p.util.SecureDirectory in project i2p.i2p by i2p.

the class PluginUpdateRunner method transferComplete.

@Override
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) {
    if (!(_xpi2pURL.startsWith("file:") || _method == UpdateMethod.FILE))
        updateStatus("<b>" + _t("Plugin downloaded") + "</b>");
    File f = new File(_updateFile);
    File appDir = new SecureDirectory(_context.getConfigDir(), PLUGIN_DIR);
    if ((!appDir.exists()) && (!appDir.mkdir())) {
        f.delete();
        statusDone("<b>" + _t("Cannot create plugin directory {0}", appDir.getAbsolutePath()) + "</b>");
        return;
    }
    boolean isSU3;
    try {
        isSU3 = isSU3File(f);
    } catch (IOException ioe) {
        f.delete();
        statusDone("<b>" + ioe + "</b>");
        return;
    }
    if (isSU3)
        processSU3(f, appDir, url);
    else
        processSUD(f, appDir, url);
}
Also used : SecureDirectory(net.i2p.util.SecureDirectory) IOException(java.io.IOException) SecureFile(net.i2p.util.SecureFile) SU3File(net.i2p.crypto.SU3File) File(java.io.File)

Aggregations

SecureDirectory (net.i2p.util.SecureDirectory)32 File (java.io.File)31 IOException (java.io.IOException)16 HashMap (java.util.HashMap)5 Properties (java.util.Properties)4 GeneralSecurityException (java.security.GeneralSecurityException)3 ArrayList (java.util.ArrayList)3 OrderedProperties (net.i2p.util.OrderedProperties)3 SecureFile (net.i2p.util.SecureFile)3 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 PrivateKey (java.security.PrivateKey)2 Map (java.util.Map)2 StringTokenizer (java.util.StringTokenizer)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 SU3File (net.i2p.crypto.SU3File)2 WebAppContext (org.eclipse.jetty.webapp.WebAppContext)2 InputStream (java.io.InputStream)1 OutputStreamWriter (java.io.OutputStreamWriter)1 Writer (java.io.Writer)1 InetSocketAddress (java.net.InetSocketAddress)1