I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 2a9d61b1 authored by str4d's avatar str4d
Browse files

merge of '6eb0d9bd5731afaa33fa1a0c82dd08a1d16d104b'

     and 'f4fa275a1d6e014c64c5ff063fb890dd05e4ed60'
parents a9f6839a 7e5bd177
No related branches found
No related tags found
No related merge requests found
package net.i2p.i2ptunnel.ui;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.i2ptunnel.I2PTunnelClientBase;
import net.i2p.i2ptunnel.SSLClientUtil;
import net.i2p.i2ptunnel.TunnelController;
import net.i2p.i2ptunnel.TunnelControllerGroup;
import net.i2p.i2ptunnel.web.Messages;
import net.i2p.util.FileUtil;
import net.i2p.util.Log;
import net.i2p.util.SecureFile;
/**
* General helper functions used by all UIs.
*
* @since 0.9.19
*/
public class GeneralHelper {
private static final String OPT = TunnelController.PFX_OPTION;
public static TunnelController getController(TunnelControllerGroup tcg, int tunnel) {
if (tunnel < 0) return null;
if (tcg == null) return null;
List<TunnelController> controllers = tcg.getControllers();
if (controllers.size() > tunnel)
return controllers.get(tunnel);
else
return null;
}
public static List<String> saveTunnel(
I2PAppContext context, TunnelControllerGroup tcg, int tunnel, TunnelConfig config) {
List<String> msgs = updateTunnelConfig(tcg, tunnel, config);
msgs.addAll(saveConfig(context, tcg));
return msgs;
}
protected static List<String> updateTunnelConfig(TunnelControllerGroup tcg, int tunnel, TunnelConfig config) {
// Get current tunnel controller
TunnelController cur = getController(tcg, tunnel);
Properties props = config.getConfig();
List<String> msgs = new ArrayList<String>();
String type = props.getProperty(TunnelController.PROP_TYPE);
if (TunnelController.TYPE_STD_CLIENT.equals(type) || TunnelController.TYPE_IRC_CLIENT.equals(type)) {
//
// If we switch to SSL, create the keystore here, so we can store the new properties.
// Down in I2PTunnelClientBase it's very hard to save the config.
//
if (Boolean.parseBoolean(props.getProperty(OPT + I2PTunnelClientBase.PROP_USE_SSL))) {
try {
boolean created = SSLClientUtil.verifyKeyStore(props, OPT);
if (created) {
// config now contains new keystore props
msgs.add("Created new self-signed certificate for tunnel " + getTunnelName(tcg, tunnel));
}
} catch (IOException ioe) {
msgs.add("Failed to create new self-signed certificate for tunnel " +
getTunnelName(tcg, tunnel) + ", check logs: " + ioe);
}
}
}
if (cur == null) {
// creating new
cur = new TunnelController(props, "", true);
tcg.addController(cur);
if (cur.getStartOnLoad())
cur.startTunnelBackground();
} else {
cur.setConfig(props, "");
}
// Only modify other shared tunnels
// if the current tunnel is shared, and of supported type
if (Boolean.parseBoolean(cur.getSharedClient()) && TunnelController.isClient(cur.getType())) {
// all clients use the same I2CP session, and as such, use the same I2CP options
List<TunnelController> controllers = tcg.getControllers();
for (int i = 0; i < controllers.size(); i++) {
TunnelController c = controllers.get(i);
// Current tunnel modified by user, skip
if (c == cur) continue;
// Only modify this non-current tunnel
// if it belongs to a shared destination, and is of supported type
if (Boolean.parseBoolean(c.getSharedClient()) && TunnelController.isClient(c.getType())) {
Properties cOpt = c.getConfig("");
config.updateTunnelQuantities(cOpt);
cOpt.setProperty("option.inbound.nickname", TunnelConfig.SHARED_CLIENT_NICKNAME);
cOpt.setProperty("option.outbound.nickname", TunnelConfig.SHARED_CLIENT_NICKNAME);
c.setConfig(cOpt, "");
}
}
}
return msgs;
}
protected static List<String> saveConfig(I2PAppContext context, TunnelControllerGroup tcg) {
List<String> rv = tcg.clearAllMessages();
try {
tcg.saveConfig();
rv.add(0, _("Configuration changes saved", context));
} catch (IOException ioe) {
Log log = context.logManager().getLog(GeneralHelper.class);
log.error("Failed to save config file", ioe);
rv.add(0, _("Failed to save configuration", context) + ": " + ioe.toString());
}
return rv;
}
/**
* Stop the tunnel, delete from config,
* rename the private key file if in the default directory
*/
public static List<String> deleteTunnel(
I2PAppContext context, TunnelControllerGroup tcg,int tunnel, TunnelConfig config) {
List<String> msgs;
TunnelController cur = getController(tcg, tunnel);
if (cur == null) {
msgs = new ArrayList<>();
msgs.add("Invalid tunnel number");
return msgs;
}
msgs = tcg.removeController(cur);
msgs.addAll(saveConfig(context, tcg));
// Rename private key file if it was a default name in
// the default directory, so it doesn't get reused when a new
// tunnel is created.
// Use configured file name if available, not the one from the form.
String pk = cur.getPrivKeyFile();
if (pk == null)
pk = config.getPrivKeyFile();
if (pk != null && pk.startsWith("i2ptunnel") && pk.endsWith("-privKeys.dat") &&
((!TunnelController.isClient(cur.getType())) || cur.getPersistentClientKey())) {
File pkf = new File(context.getConfigDir(), pk);
if (pkf.exists()) {
String name = cur.getName();
if (name == null) {
name = cur.getDescription();
if (name == null) {
name = cur.getType();
if (name == null)
name = Long.toString(context.clock().now());
}
}
name = name.replace(' ', '_').replace(':', '_').replace("..", "_").replace('/', '_').replace('\\', '_');
name = "i2ptunnel-deleted-" + name + '-' + context.clock().now() + "-privkeys.dat";
File backupDir = new SecureFile(context.getConfigDir(), TunnelController.KEY_BACKUP_DIR);
File to;
if (backupDir.isDirectory() || backupDir.mkdir())
to = new File(backupDir, name);
else
to = new File(context.getConfigDir(), name);
boolean success = FileUtil.rename(pkf, to);
if (success)
msgs.add("Private key file " + pkf.getAbsolutePath() +
" renamed to " + to.getAbsolutePath());
}
}
return msgs;
}
public static String getTunnelName(TunnelControllerGroup tcg, int tunnel) {
TunnelController tun = getController(tcg, tunnel);
if (tun != null)
return tun.getName();
else
return null;
}
protected static String _(String key, I2PAppContext context) {
return Messages._(key, context);
}
}
...@@ -9,7 +9,6 @@ package net.i2p.i2ptunnel.web; ...@@ -9,7 +9,6 @@ package net.i2p.i2ptunnel.web;
*/ */
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
...@@ -23,19 +22,16 @@ import net.i2p.data.DataHelper; ...@@ -23,19 +22,16 @@ import net.i2p.data.DataHelper;
import net.i2p.data.Destination; import net.i2p.data.Destination;
import net.i2p.data.PrivateKeyFile; import net.i2p.data.PrivateKeyFile;
import net.i2p.data.SessionKey; import net.i2p.data.SessionKey;
import net.i2p.i2ptunnel.I2PTunnelClientBase;
import net.i2p.i2ptunnel.I2PTunnelHTTPClient; import net.i2p.i2ptunnel.I2PTunnelHTTPClient;
import net.i2p.i2ptunnel.I2PTunnelHTTPClientBase; import net.i2p.i2ptunnel.I2PTunnelHTTPClientBase;
import net.i2p.i2ptunnel.I2PTunnelHTTPServer; import net.i2p.i2ptunnel.I2PTunnelHTTPServer;
import net.i2p.i2ptunnel.I2PTunnelServer; import net.i2p.i2ptunnel.I2PTunnelServer;
import net.i2p.i2ptunnel.SSLClientUtil;
import net.i2p.i2ptunnel.TunnelController; import net.i2p.i2ptunnel.TunnelController;
import net.i2p.i2ptunnel.TunnelControllerGroup; import net.i2p.i2ptunnel.TunnelControllerGroup;
import net.i2p.i2ptunnel.ui.GeneralHelper;
import net.i2p.i2ptunnel.ui.TunnelConfig; import net.i2p.i2ptunnel.ui.TunnelConfig;
import net.i2p.util.Addresses; import net.i2p.util.Addresses;
import net.i2p.util.FileUtil;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.SecureFile;
/** /**
* Simple accessor for exposing tunnel info, but also an ugly form handler * Simple accessor for exposing tunnel info, but also an ugly form handler
...@@ -79,7 +75,6 @@ public class IndexBean { ...@@ -79,7 +75,6 @@ public class IndexBean {
public static final String PROP_CSS_DISABLED = "routerconsole.css.disabled"; public static final String PROP_CSS_DISABLED = "routerconsole.css.disabled";
public static final String PROP_JS_DISABLED = "routerconsole.javascript.disabled"; public static final String PROP_JS_DISABLED = "routerconsole.javascript.disabled";
private static final String PROP_PW_ENABLE = "routerconsole.auth.enable"; private static final String PROP_PW_ENABLE = "routerconsole.auth.enable";
private static final String OPT = TunnelController.PFX_OPTION;
public IndexBean() { public IndexBean() {
_context = I2PAppContext.getGlobalContext(); _context = I2PAppContext.getGlobalContext();
...@@ -240,84 +235,10 @@ public class IndexBean { ...@@ -240,84 +235,10 @@ public class IndexBean {
} }
private String saveChanges() { private String saveChanges() {
// Get current tunnel controller
TunnelController cur = getController(_tunnel);
Properties config = getConfig();
String ksMsg = null;
String type = config.getProperty(TunnelController.PROP_TYPE);
if (TunnelController.TYPE_STD_CLIENT.equals(type) || TunnelController.TYPE_IRC_CLIENT.equals(type)) {
//
// If we switch to SSL, create the keystore here, so we can store the new properties.
// Down in I2PTunnelClientBase it's very hard to save the config.
//
if (Boolean.parseBoolean(config.getProperty(OPT + I2PTunnelClientBase.PROP_USE_SSL))) {
try {
boolean created = SSLClientUtil.verifyKeyStore(config, OPT);
if (created) {
// config now contains new keystore props
ksMsg = "Created new self-signed certificate for tunnel " + getTunnelName(_tunnel);
}
} catch (IOException ioe) {
ksMsg = "Failed to create new self-signed certificate for tunnel " +
getTunnelName(_tunnel) + ", check logs: " + ioe;
}
}
}
if (cur == null) {
// creating new
cur = new TunnelController(config, "", true);
_group.addController(cur);
if (cur.getStartOnLoad())
cur.startTunnelBackground();
} else {
cur.setConfig(config, "");
}
// Only modify other shared tunnels
// if the current tunnel is shared, and of supported type
if (Boolean.parseBoolean(cur.getSharedClient()) && isClient(cur.getType())) {
// all clients use the same I2CP session, and as such, use the same I2CP options
List<TunnelController> controllers = _group.getControllers();
for (int i = 0; i < controllers.size(); i++) {
TunnelController c = controllers.get(i);
// Current tunnel modified by user, skip
if (c == cur) continue;
// Only modify this non-current tunnel
// if it belongs to a shared destination, and is of supported type
if (Boolean.parseBoolean(c.getSharedClient()) && isClient(c.getType())) {
Properties cOpt = c.getConfig("");
_config.updateTunnelQuantities(config);
cOpt.setProperty("option.inbound.nickname", TunnelConfig.SHARED_CLIENT_NICKNAME);
cOpt.setProperty("option.outbound.nickname", TunnelConfig.SHARED_CLIENT_NICKNAME);
c.setConfig(cOpt, "");
}
}
}
List<String> msgs = doSave();
if (ksMsg != null)
msgs.add(ksMsg);
// FIXME name will be HTML escaped twice // FIXME name will be HTML escaped twice
return getMessages(msgs); return getMessages(GeneralHelper.saveTunnel(_context, _group, _tunnel, _config));
} }
private List<String> doSave() {
List<String> rv = _group.clearAllMessages();
try {
_group.saveConfig();
rv.add(0, _("Configuration changes saved"));
} catch (IOException ioe) {
_log.error("Failed to save config file", ioe);
rv.add(0, _("Failed to save configuration") + ": " + ioe.toString());
}
return rv;
}
/** /**
* Stop the tunnel, delete from config, * Stop the tunnel, delete from config,
* rename the private key file if in the default directory * rename the private key file if in the default directory
...@@ -325,49 +246,8 @@ public class IndexBean { ...@@ -325,49 +246,8 @@ public class IndexBean {
private String deleteTunnel() { private String deleteTunnel() {
if (!_removeConfirmed) if (!_removeConfirmed)
return "Please confirm removal"; return "Please confirm removal";
TunnelController cur = getController(_tunnel); return getMessages(GeneralHelper.deleteTunnel(_context, _group, _tunnel, _config));
if (cur == null)
return "Invalid tunnel number";
List<String> msgs = _group.removeController(cur);
msgs.addAll(doSave());
// Rename private key file if it was a default name in
// the default directory, so it doesn't get reused when a new
// tunnel is created.
// Use configured file name if available, not the one from the form.
String pk = cur.getPrivKeyFile();
if (pk == null)
pk = _config.getPrivKeyFile();
if (pk != null && pk.startsWith("i2ptunnel") && pk.endsWith("-privKeys.dat") &&
((!isClient(cur.getType())) || cur.getPersistentClientKey())) {
File pkf = new File(_context.getConfigDir(), pk);
if (pkf.exists()) {
String name = cur.getName();
if (name == null) {
name = cur.getDescription();
if (name == null) {
name = cur.getType();
if (name == null)
name = Long.toString(_context.clock().now());
}
}
name = name.replace(' ', '_').replace(':', '_').replace("..", "_").replace('/', '_').replace('\\', '_');
name = "i2ptunnel-deleted-" + name + '-' + _context.clock().now() + "-privkeys.dat";
File backupDir = new SecureFile(_context.getConfigDir(), TunnelController.KEY_BACKUP_DIR);
File to;
if (backupDir.isDirectory() || backupDir.mkdir())
to = new File(backupDir, name);
else
to = new File(_context.getConfigDir(), name);
boolean success = FileUtil.rename(pkf, to);
if (success)
msgs.add("Private key file " + pkf.getAbsolutePath() +
" renamed to " + to.getAbsolutePath());
}
}
return getMessages(msgs);
} }
/** /**
...@@ -436,9 +316,9 @@ public class IndexBean { ...@@ -436,9 +316,9 @@ public class IndexBean {
} }
public String getTunnelName(int tunnel) { public String getTunnelName(int tunnel) {
TunnelController tun = getController(tunnel); String name = GeneralHelper.getTunnelName(_group, tunnel);
if (tun != null && tun.getName() != null) if (name != null)
return DataHelper.escapeHTML(tun.getName()); return DataHelper.escapeHTML(name);
else else
return _("New Tunnel"); return _("New Tunnel");
} }
...@@ -1240,13 +1120,7 @@ public class IndexBean { ...@@ -1240,13 +1120,7 @@ public class IndexBean {
/// ///
protected TunnelController getController(int tunnel) { protected TunnelController getController(int tunnel) {
if (tunnel < 0) return null; return GeneralHelper.getController(_group, tunnel);
if (_group == null) return null;
List<TunnelController> controllers = _group.getControllers();
if (controllers.size() > tunnel)
return controllers.get(tunnel);
else
return null;
} }
private static String getMessages(List<String> msgs) { private static String getMessages(List<String> msgs) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment