Store server tunnel keys / read tunnel keys from a specified directory when creating a tunnel with tunnelcontrol

Use .i2p-zero in the user's home directory as the i2p config dir.
pull/6/head
knaccc 5 years ago
parent 23f758969d
commit fcfab6ae00

@ -85,9 +85,16 @@ Note that it may take a short while for new tunnels to be set up.
Call the `dist/linux/router/bin/tunnel-control.sh` script as follows to create and destroy tunnels:
#### Listen for i2p connections and forward them to the specified host and port. Returns a newly created destination public key.
#### Listen for i2p connections and forward them to the specified host and port, storing/reading the server key file in/from the specified directory.
`tunnel-control.sh server.create <host> <port>`
If the directory doesn't exist with a file named serverTunnelSecretKey in it,
returns a newly created destination address and writes the secret key for the
new address to a file called serverTunnelSecretKey in the specified directory. Otherwise, read the existing
secret key from that directory. The server tunnel will listen for i2p connections and forward them to the
specified host and port. Returns the I2P b32 destination address for the server tunnel (which deterministically depends
on the contents of the serverTunnelSecretKey file).
`tunnel-control.sh server.create <host> <port> <directory>`
#### Close the tunnel listening for connections on the specified destination public key. Returns "OK".

@ -70,7 +70,6 @@ done
for i in linux mac win linux-gui mac-gui win-gui; do cp -r $basedir/import/i2p.base $basedir/dist/$i/router/; done
for i in linux mac win linux-gui mac-gui win-gui; do mkdir -p $basedir/dist/$i/router/i2p.config; done
# remove unnecessary native libs from jbigi.jar
for i in linux mac win linux-gui mac-gui win-gui; do

@ -89,7 +89,7 @@ public class AddTunnelController {
socksProxyConfigPane.setVisible(false);
if (newToggle.equals(clientTunnelRadioButton)) clientTunnelConfigPane.setVisible(true);
if (newToggle.equals(serverTunnelRadioButton)) {
var keyPair = tunnelControl.genKeyPair();
var keyPair = TunnelControl.KeyPair.gen();
serverKeyField.setText(keyPair.seckey + "," + keyPair.pubkey);
serverAddrField.setText(keyPair.b32Dest);
serverTunnelConfigPane.setVisible(true);

@ -16,7 +16,7 @@ public class Main {
// where to find the I2P installation files
p.put("i2p.dir.base", "/usr/share/i2p");
// where to find the I2P data files
p.put("i2p.dir.config", System.getProperty("user.home") + File.separator + ".i2p");
p.put("i2p.dir.config", System.getProperty("user.home") + File.separator + ".i2p-zero");
// bandwidth limits in K bytes per second
p.put("i2np.inboundKBytesPerSecond","50");
p.put("i2np.outboundKBytesPerSecond","50");

@ -17,6 +17,7 @@ import java.net.InetAddress;
import java.net.ServerSocket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@ -36,6 +37,7 @@ public class TunnelControl implements Runnable {
tunnelControlTempDir.delete();
tunnelControlTempDir.mkdir();
this.tunnelControlTempDir = tunnelControlTempDir;
this.tunnelControlTempDir.deleteOnExit();
}
public interface Tunnel {
@ -132,16 +134,6 @@ public class TunnelControl implements Runnable {
return tunnels;
}
public KeyPair genKeyPair() throws Exception {
ByteArrayOutputStream seckey = new ByteArrayOutputStream();
ByteArrayOutputStream pubkey = new ByteArrayOutputStream();
I2PClient client = I2PClientFactory.createClient();
Destination d = client.createDestination(seckey);
d.writeBytes(pubkey);
String b32Dest = d.toBase32();
return new KeyPair(Base64.encode(seckey.toByteArray()), Base64.encode(pubkey.toByteArray()), b32Dest);
}
public static class KeyPair {
public String seckey;
public String pubkey;
@ -159,23 +151,27 @@ public class TunnelControl implements Runnable {
d.readBytes(new ByteArrayInputStream(Base64.decode(this.seckey)));
this.b32Dest = d.toBase32();
}
public static KeyPair gen() throws Exception {
ByteArrayOutputStream seckey = new ByteArrayOutputStream();
ByteArrayOutputStream pubkey = new ByteArrayOutputStream();
I2PClient client = I2PClientFactory.createClient();
Destination d = client.createDestination(seckey);
d.writeBytes(pubkey);
String b32Dest = d.toBase32();
return new KeyPair(Base64.encode(seckey.toByteArray()), Base64.encode(pubkey.toByteArray()), b32Dest);
}
public static KeyPair read(String path) throws Exception {
return new KeyPair(Files.readString(Paths.get(path)));
}
public void write(String path) throws Exception {
Files.writeString(Paths.get(path), seckey + "," + pubkey);
}
}
@Override
public void run() {
// listen for socket connections to the tunnel controller.
// listen for the commands on port 30000:
// server.create <host> <port> // returns a newly created destination public key, which will listen for i2p connections and forward them to the specified host and port
// server.destroy <i2p destination public key> // closes the tunnel listening for connections on the specified destination public key, and returns OK
// client.create <i2p destination public key> // returns a newly created localhost port number, where connections will be sent over I2P to the destination public key
// client.destroy <port> // closes the tunnel listening for connections on the specified port, and returns OK
// socks.create <port> // creates a socks proxy listening on the specified port
// socks.destroy <port> // closes the socks proxy listening on the specified port, and returns OK
//
// send a command with bash: exec 3<>/dev/tcp/localhost/30000; echo "server.create localhost 80" >&3; cat <&3
//
try {
controlServerSocket = new ServerSocket(clientPortSeq++, 0, InetAddress.getLoopbackAddress());
while (!stopping) {
@ -190,7 +186,18 @@ public class TunnelControl implements Runnable {
case "server.create":
String destHost = args[1];
int destPort = Integer.parseInt(args[2]);
var tunnel = new ServerTunnel(destHost, destPort, genKeyPair(), getTunnelControlTempDir());
File serverTunnelConfigDir = new File(args[3]);
if(!serverTunnelConfigDir.exists()) serverTunnelConfigDir.mkdir();
File serverKeyFile = new File(serverTunnelConfigDir, "serverTunnelSecretKey");
KeyPair keyPair;
if(serverKeyFile.exists()) {
keyPair = KeyPair.read(serverKeyFile.getPath());
}
else {
keyPair = KeyPair.gen();
keyPair.write(serverKeyFile.getPath());
}
var tunnel = new ServerTunnel(destHost, destPort, keyPair, getTunnelControlTempDir());
tunnels.add(tunnel);
out.println(tunnel.dest);
break;

@ -1,3 +1,3 @@
@echo off
set DIR=%~dp0
"%DIR%\java" -cp %DIR%\..\i2p.base\jbigi.jar -m org.getmonero.i2p.zero.gui --i2p.dir.base=%DIR%\..\i2p.base --i2p.dir.config=%DIR%\..\i2p.config %*
"%DIR%\java" -cp %DIR%\..\i2p.base\jbigi.jar -m org.getmonero.i2p.zero.gui --i2p.dir.base=%DIR%\..\i2p.base %*

@ -6,4 +6,4 @@ else
basedir=$(dirname $(dirname $(readlink -fm $0)))
fi
$basedir/bin/java -cp $basedir/i2p.base/jbigi.jar -m org.getmonero.i2p.zero.gui --i2p.dir.base=$basedir/i2p.base --i2p.dir.config=$basedir/i2p.config
$basedir/bin/java -cp $basedir/i2p.base/jbigi.jar -m org.getmonero.i2p.zero.gui --i2p.dir.base=$basedir/i2p.base

@ -6,4 +6,4 @@ else
basedir=$(dirname $(dirname $(readlink -fm $0)))
fi
$basedir/bin/java -cp $basedir/i2p.base/jbigi.jar -m org.getmonero.i2p.zero --i2p.dir.base=$basedir/i2p.base --i2p.dir.config=$basedir/i2p.config
$basedir/bin/java -cp $basedir/i2p.base/jbigi.jar -m org.getmonero.i2p.zero --i2p.dir.base=$basedir/i2p.base

Loading…
Cancel
Save