forked from I2P_Developers/i2p.i2p
i2ptunnel:
ECDSA default for all new server tunnels ECDSA default for streamr client tunnels Fix display of server destination on edit page when not running (privkey file path wasn't absolute) Fix display of persistent client key b32 on edit page when not running Fix display of server sig type on edit page when we have a privkey file Add KeysAndCert.getSigType() Javadocs
This commit is contained in:
@ -84,9 +84,20 @@ public class TunnelController implements Logging {
|
||||
public static final String TYPE_SOCKS_IRC = "socksirctunnel";
|
||||
public static final String TYPE_STD_CLIENT = "client";
|
||||
public static final String TYPE_STD_SERVER = "server";
|
||||
/** Client in the UI and I2P side but a server on the localhost side */
|
||||
public static final String TYPE_STREAMR_CLIENT = "streamrclient";
|
||||
/** Server in the UI and I2P side but a client on the localhost side */
|
||||
public static final String TYPE_STREAMR_SERVER = "streamrserver";
|
||||
|
||||
/**
|
||||
* This is guaranteed to be available.
|
||||
* @since 0.9.17
|
||||
*/
|
||||
public static final SigType PREFERRED_SIGTYPE = SigType.ECDSA_SHA256_P256.isAvailable() ?
|
||||
SigType.ECDSA_SHA256_P256 :
|
||||
SigType.DSA_SHA1;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new controller for a tunnel out of the specific config options.
|
||||
* The config may contain a large number of options - only ones that begin in
|
||||
@ -125,15 +136,12 @@ public class TunnelController implements Logging {
|
||||
*/
|
||||
private boolean createPrivateKey() {
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
String filename = getPrivKeyFile();
|
||||
if ( (filename == null) || (filename.trim().length() <= 0) ) {
|
||||
File keyFile = getPrivateKeyFile();
|
||||
if (keyFile == null) {
|
||||
log("No filename specified for the private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
File keyFile = new File(getPrivKeyFile());
|
||||
if (!keyFile.isAbsolute())
|
||||
keyFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), getPrivKeyFile());
|
||||
if (keyFile.exists()) {
|
||||
//log("Not overwriting existing private keys in " + keyFile.getAbsolutePath());
|
||||
return true;
|
||||
@ -145,11 +153,11 @@ public class TunnelController implements Logging {
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
fos = new SecureFileOutputStream(keyFile);
|
||||
SigType stype = I2PClient.DEFAULT_SIGTYPE;
|
||||
SigType stype = PREFERRED_SIGTYPE;
|
||||
String st = _config.getProperty(OPT_SIG_TYPE);
|
||||
if (st != null) {
|
||||
SigType type = SigType.parseSigType(st);
|
||||
if (type != null)
|
||||
if (type != null && type.isAvailable())
|
||||
stype = type;
|
||||
else
|
||||
log("Unsupported sig type " + st + ", reverting to " + stype);
|
||||
@ -586,11 +594,12 @@ public class TunnelController implements Logging {
|
||||
_config.setProperty(OPT_LOW_TAGS, "14");
|
||||
}
|
||||
// same default logic as in EditBean.getSigType()
|
||||
if ((type.equals(TYPE_IRC_CLIENT) || type.equals(TYPE_STD_CLIENT) || type.equals(TYPE_SOCKS_IRC))
|
||||
&& !Boolean.valueOf(getSharedClient())) {
|
||||
if (!_config.containsKey(OPT_SIG_TYPE) &&
|
||||
SigType.ECDSA_SHA256_P256.isAvailable())
|
||||
_config.setProperty(OPT_SIG_TYPE, "ECDSA_SHA256_P256");
|
||||
if (!isClient(type) ||
|
||||
((type.equals(TYPE_IRC_CLIENT) || type.equals(TYPE_STD_CLIENT) ||
|
||||
type.equals(TYPE_SOCKS_IRC) || type.equals(TYPE_STREAMR_CLIENT))
|
||||
&& !Boolean.valueOf(getSharedClient()))) {
|
||||
if (!_config.containsKey(OPT_SIG_TYPE))
|
||||
_config.setProperty(OPT_SIG_TYPE, PREFERRED_SIGTYPE.name());
|
||||
}
|
||||
}
|
||||
|
||||
@ -640,6 +649,34 @@ public class TunnelController implements Logging {
|
||||
public String getI2CPHost() { return _config.getProperty(PROP_I2CP_HOST); }
|
||||
public String getI2CPPort() { return _config.getProperty(PROP_I2CP_PORT); }
|
||||
|
||||
/**
|
||||
* Is it a client or server in the UI and I2P side?
|
||||
* Note that a streamr client is a UI and I2P client but a server on the localhost side.
|
||||
* Note that a streamr server is a UI and I2P server but a client on the localhost side.
|
||||
*
|
||||
* @since 0.9.17
|
||||
*/
|
||||
public boolean isClient() {
|
||||
return isClient(getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it a client or server in the UI and I2P side?
|
||||
* Note that a streamr client is a UI and I2P client but a server on the localhost side.
|
||||
* Note that a streamr server is a UI and I2P server but a client on the localhost side.
|
||||
*
|
||||
* @since 0.9.17 moved from IndexBean
|
||||
*/
|
||||
public static boolean isClient(String type) {
|
||||
return TYPE_STD_CLIENT.equals(type) ||
|
||||
TYPE_HTTP_CLIENT.equals(type) ||
|
||||
TYPE_SOCKS.equals(type) ||
|
||||
TYPE_SOCKS_IRC.equals(type) ||
|
||||
TYPE_CONNECT.equals(type) ||
|
||||
TYPE_STREAMR_CLIENT.equals(type) ||
|
||||
TYPE_IRC_CLIENT.equals(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* These are the ones with a prefix of "option."
|
||||
*
|
||||
@ -664,7 +701,12 @@ public class TunnelController implements Logging {
|
||||
public String getTargetHost() { return _config.getProperty(PROP_TARGET_HOST); }
|
||||
public String getTargetPort() { return _config.getProperty(PROP_TARGET_PORT); }
|
||||
public String getSpoofedHost() { return _config.getProperty(PROP_SPOOFED_HOST); }
|
||||
|
||||
/**
|
||||
* Probably not absolute. May be null. getPrivateKeyFile() recommended.
|
||||
*/
|
||||
public String getPrivKeyFile() { return _config.getProperty(PROP_FILE); }
|
||||
|
||||
public String getListenPort() { return _config.getProperty(PROP_LISTEN_PORT); }
|
||||
public String getTargetDestination() { return _config.getProperty(PROP_DEST); }
|
||||
public String getProxyList() { return _config.getProperty(PROP_PROXIES); }
|
||||
@ -674,30 +716,59 @@ public class TunnelController implements Logging {
|
||||
public boolean getStartOnLoad() { return Boolean.parseBoolean(_config.getProperty(PROP_START, "true")); }
|
||||
public boolean getPersistentClientKey() { return Boolean.parseBoolean(_config.getProperty(OPT_PERSISTENT)); }
|
||||
|
||||
/**
|
||||
* Does not necessarily exist.
|
||||
* @return absolute path or null if unset
|
||||
* @since 0.9.17
|
||||
*/
|
||||
public File getPrivateKeyFile() {
|
||||
String f = getPrivKeyFile();
|
||||
if (f == null)
|
||||
return null;
|
||||
f = f.trim();
|
||||
if (f.length() == 0)
|
||||
return null;
|
||||
File rv = new File(f);
|
||||
if (!rv.isAbsolute())
|
||||
rv = new File(I2PAppContext.getGlobalContext().getConfigDir(), f);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null if not running.
|
||||
* @return Base64 or null
|
||||
*/
|
||||
public String getMyDestination() {
|
||||
if (_tunnel != null) {
|
||||
List<I2PSession> sessions = _tunnel.getSessions();
|
||||
for (int i = 0; i < sessions.size(); i++) {
|
||||
I2PSession session = sessions.get(i);
|
||||
Destination dest = session.getMyDestination();
|
||||
Destination dest = getDestination();
|
||||
if (dest != null)
|
||||
return dest.toBase64();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null if not running.
|
||||
* @return "{52 chars}.b32.i2p" or null
|
||||
*/
|
||||
public String getMyDestHashBase32() {
|
||||
Destination dest = getDestination();
|
||||
if (dest != null)
|
||||
return dest.toBase32();
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns null if not running.
|
||||
* @return Destination or null
|
||||
* @since 0.9.17
|
||||
*/
|
||||
public Destination getDestination() {
|
||||
if (_tunnel != null) {
|
||||
List<I2PSession> sessions = _tunnel.getSessions();
|
||||
for (int i = 0; i < sessions.size(); i++) {
|
||||
I2PSession session = sessions.get(i);
|
||||
Destination dest = session.getMyDestination();
|
||||
if (dest != null)
|
||||
return dest.toBase32();
|
||||
return dest;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -41,6 +41,11 @@ import net.i2p.util.Addresses;
|
||||
public class EditBean extends IndexBean {
|
||||
public EditBean() { super(); }
|
||||
|
||||
/**
|
||||
* Is it a client or server in the UI and I2P side?
|
||||
* Note that a streamr client is a UI and I2P client but a server on the localhost side.
|
||||
* Note that a streamr server is a UI and I2P server but a client on the localhost side.
|
||||
*/
|
||||
public static boolean staticIsClient(int tunnel) {
|
||||
TunnelControllerGroup group = TunnelControllerGroup.getInstance();
|
||||
if (group == null)
|
||||
@ -190,6 +195,12 @@ public class EditBean extends IndexBean {
|
||||
String ttype;
|
||||
boolean isShared;
|
||||
if (tunnel >= 0) {
|
||||
Destination d = getDestination(tunnel);
|
||||
if (d != null) {
|
||||
type = d.getSigType();
|
||||
if (type != null)
|
||||
return type.getCode();
|
||||
}
|
||||
String stype = getProperty(tunnel, I2PClient.PROP_SIGTYPE, null);
|
||||
type = stype != null ? SigType.parseSigType(stype) : null;
|
||||
ttype = getTunnelType(tunnel);
|
||||
@ -201,12 +212,13 @@ public class EditBean extends IndexBean {
|
||||
}
|
||||
if (type == null) {
|
||||
// same default logic as in TunnelController.setConfig()
|
||||
if ((TunnelController.TYPE_IRC_CLIENT.equals(ttype) ||
|
||||
if ((!TunnelController.isClient(ttype) ||
|
||||
((TunnelController.TYPE_IRC_CLIENT.equals(ttype) ||
|
||||
TunnelController.TYPE_SOCKS_IRC.equals(ttype) ||
|
||||
TunnelController.TYPE_STREAMR_CLIENT.equals(ttype) ||
|
||||
TunnelController.TYPE_STD_CLIENT.equals(ttype)) &&
|
||||
!isShared &&
|
||||
SigType.ECDSA_SHA256_P256.isAvailable())
|
||||
type = SigType.ECDSA_SHA256_P256;
|
||||
!isShared)))
|
||||
type = TunnelController.PREFERRED_SIGTYPE;
|
||||
else
|
||||
type = SigType.DSA_SHA1;
|
||||
}
|
||||
|
@ -467,20 +467,24 @@ public class IndexBean {
|
||||
return _group.getControllers().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it a client or server in the UI and I2P side?
|
||||
* Note that a streamr client is a UI and I2P client but a server on the localhost side.
|
||||
* Note that a streamr server is a UI and I2P server but a client on the localhost side.
|
||||
*/
|
||||
public boolean isClient(int tunnelNum) {
|
||||
TunnelController cur = getController(tunnelNum);
|
||||
if (cur == null) return false;
|
||||
return isClient(cur.getType());
|
||||
return cur.isClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is it a client or server in the UI and I2P side?
|
||||
* Note that a streamr client is a UI and I2P client but a server on the localhost side.
|
||||
* Note that a streamr server is a UI and I2P server but a client on the localhost side.
|
||||
*/
|
||||
public static boolean isClient(String type) {
|
||||
return ( (TunnelController.TYPE_STD_CLIENT.equals(type)) ||
|
||||
(TunnelController.TYPE_HTTP_CLIENT.equals(type)) ||
|
||||
(TunnelController.TYPE_SOCKS.equals(type)) ||
|
||||
(TunnelController.TYPE_SOCKS_IRC.equals(type)) ||
|
||||
(TunnelController.TYPE_CONNECT.equals(type)) ||
|
||||
(TunnelController.TYPE_STREAMR_CLIENT.equals(type)) ||
|
||||
(TunnelController.TYPE_IRC_CLIENT.equals(type)));
|
||||
return TunnelController.isClient(type);
|
||||
}
|
||||
|
||||
public String getTunnelName(int tunnel) {
|
||||
@ -657,36 +661,50 @@ public class IndexBean {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getDestinationBase64(int tunnel) {
|
||||
/**
|
||||
* Works even if tunnel is not running.
|
||||
* @return Destination or null
|
||||
* @since 0.9.17
|
||||
*/
|
||||
protected Destination getDestination(int tunnel) {
|
||||
TunnelController tun = getController(tunnel);
|
||||
if (tun != null) {
|
||||
String rv = tun.getMyDestination();
|
||||
Destination rv = tun.getDestination();
|
||||
if (rv != null)
|
||||
return rv;
|
||||
// if not running, do this the hard way
|
||||
String keyFile = tun.getPrivKeyFile();
|
||||
if (keyFile != null && keyFile.trim().length() > 0) {
|
||||
File keyFile = tun.getPrivateKeyFile();
|
||||
if (keyFile != null) {
|
||||
PrivateKeyFile pkf = new PrivateKeyFile(keyFile);
|
||||
try {
|
||||
Destination d = pkf.getDestination();
|
||||
if (d != null)
|
||||
return d.toBase64();
|
||||
rv = pkf.getDestination();
|
||||
if (rv != null)
|
||||
return rv;
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Works even if tunnel is not running.
|
||||
* @return Base64 or ""
|
||||
*/
|
||||
public String getDestinationBase64(int tunnel) {
|
||||
Destination d = getDestination(tunnel);
|
||||
if (d != null)
|
||||
return d.toBase64();
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Works even if tunnel is not running.
|
||||
* @return "{52 chars}.b32.i2p" or ""
|
||||
*/
|
||||
public String getDestHashBase32(int tunnel) {
|
||||
TunnelController tun = getController(tunnel);
|
||||
if (tun != null) {
|
||||
String rv = tun.getMyDestHashBase32();
|
||||
if (rv != null)
|
||||
return rv;
|
||||
}
|
||||
Destination d = getDestination(tunnel);
|
||||
if (d != null)
|
||||
return d.toBase32();
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.i2p.crypto.SHA256Generator;
|
||||
import net.i2p.crypto.SigType;
|
||||
|
||||
/**
|
||||
* KeysAndCert has a public key, a signing key, and a certificate.
|
||||
@ -51,6 +52,22 @@ public class KeysAndCert extends DataStructureImpl {
|
||||
_certificate = cert;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null if not set or unknown
|
||||
* @since 0.9.17
|
||||
*/
|
||||
public SigType getSigType() {
|
||||
if (_certificate == null)
|
||||
return null;
|
||||
if (_certificate.getCertificateType() == Certificate.CERTIFICATE_TYPE_KEY) {
|
||||
try {
|
||||
KeyCertificate kcert = _certificate.toKeyCertificate();
|
||||
return kcert.getSigType();
|
||||
} catch (DataFormatException dfe) {}
|
||||
}
|
||||
return SigType.DSA_SHA1;
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey() {
|
||||
return _publicKey;
|
||||
}
|
||||
|
@ -91,6 +91,7 @@ tunnel.3.i2cpHost=127.0.0.1
|
||||
tunnel.3.i2cpPort=7654
|
||||
tunnel.3.option.inbound.nickname=eepsite
|
||||
tunnel.3.option.outbound.nickname=eepsite
|
||||
tunnel.3.option.i2cp.destination.sigType=ECDSA_SHA256_P256
|
||||
tunnel.3.option.inbound.length=3
|
||||
tunnel.3.option.inbound.lengthVariance=0
|
||||
tunnel.3.option.outbound.length=3
|
||||
|
Reference in New Issue
Block a user