use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PTunnelClientBase method buildSocketManager.
/**
* As of 0.9.20 this is fast, and does NOT connect the manager to the router.
* Call verifySocketManager() for that.
*
* @param pkf absolute path or null
* @return non-null
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
* badly that we cant create a socketManager
*/
protected static I2PSocketManager buildSocketManager(I2PTunnel tunnel, String pkf, Logging log) {
// shadows instance _log
Log _log = tunnel.getContext().logManager().getLog(I2PTunnelClientBase.class);
Properties props = new Properties();
props.putAll(tunnel.getClientOptions());
int portNum = 7654;
if (tunnel.port != null) {
try {
portNum = Integer.parseInt(tunnel.port);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("Invalid port specified [" + tunnel.port + "]", nfe);
}
}
I2PSocketManager sockManager = null;
FileInputStream fis = null;
try {
if (pkf != null) {
// Persistent client dest
fis = new FileInputStream(pkf);
sockManager = I2PSocketManagerFactory.createDisconnectedManager(fis, tunnel.host, portNum, props);
} else {
sockManager = I2PSocketManagerFactory.createDisconnectedManager(null, tunnel.host, portNum, props);
}
} catch (I2PSessionException ise) {
throw new IllegalArgumentException("Can't create socket manager", ise);
} catch (IOException ioe) {
if (log != null)
log.log("Error opening key file " + ioe);
_log.error("Error opening key file", ioe);
throw new IllegalArgumentException("Error opening key file", ioe);
} finally {
if (fis != null)
try {
fis.close();
} catch (IOException ioe) {
}
}
sockManager.setName("Client");
if (_log.shouldLog(Log.INFO))
_log.info(tunnel.getClientOptions().getProperty("inbound.nickname") + ": Built a new socket manager [s=" + sockManager.getSession() + "]");
tunnel.addSession(sockManager.getSession());
return sockManager;
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PTunnelClientBase method addSubsession.
/**
* Add a DSA_SHA1 subsession to the shared client if necessary.
*
* @return subsession, or null if none was added
* @since 0.9.20
*/
protected static synchronized I2PSession addSubsession(I2PTunnel tunnel) {
I2PSession sess = socketManager.getSession();
if (sess.getMyDestination().getSigType() == SigType.DSA_SHA1)
return null;
Properties props = new Properties();
props.putAll(tunnel.getClientOptions());
String name = props.getProperty("inbound.nickname");
if (name != null)
props.setProperty("inbound.nickname", name + " (DSA)");
name = props.getProperty("outbound.nickname");
if (name != null)
props.setProperty("outbound.nickname", name + " (DSA)");
props.setProperty(I2PClient.PROP_SIGTYPE, "DSA_SHA1");
try {
return socketManager.addSubsession(null, props);
} catch (I2PSessionException ise) {
Log log = tunnel.getContext().logManager().getLog(I2PTunnelClientBase.class);
if (log.shouldLog(Log.WARN))
log.warn("Failed to add subssession", ise);
return null;
}
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PTunnelServer method addSubsession.
/**
* Add a non-DSA_SHA1 subsession to the DSA_SHA1 server if necessary.
*
* @return subsession, or null if none was added
* @since 0.9.30
*/
private I2PSession addSubsession(I2PSocketManager sMgr, String alt) {
File altFile = TunnelController.filenameToFile(alt);
if (altFile == null)
return null;
I2PSession sess = sMgr.getSession();
if (sess.getMyDestination().getSigType() != SigType.DSA_SHA1)
return null;
Properties props = new Properties();
props.putAll(getTunnel().getClientOptions());
// fixme get actual sig type
String name = props.getProperty("inbound.nickname");
if (name != null)
props.setProperty("inbound.nickname", name + " (EdDSA)");
name = props.getProperty("outbound.nickname");
if (name != null)
props.setProperty("outbound.nickname", name + " (EdDSA)");
props.setProperty(I2PClient.PROP_SIGTYPE, "EdDSA_SHA512_Ed25519");
FileInputStream privData = null;
try {
privData = new FileInputStream(altFile);
return sMgr.addSubsession(privData, props);
} catch (IOException ioe) {
_log.error("Failed to add subssession", ioe);
return null;
} catch (I2PSessionException ise) {
_log.error("Failed to add subssession", ise);
return null;
} finally {
if (privData != null)
try {
privData.close();
} catch (IOException ioe) {
}
}
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class TunnelController method createAltPrivateKey.
/**
* Creates alternate Destination with the same encryption keys as the primary Destination,
* but a different signing key.
*
* Must have already called createPrivateKey() successfully.
* Does nothing unless option OPT_ALT_PKF is set with the privkey file name.
* Does nothing if the file already exists.
*
* @return success
* @since 0.9.30
*/
private boolean createAltPrivateKey() {
if (PREFERRED_SIGTYPE == SigType.DSA_SHA1)
return false;
File keyFile = getPrivateKeyFile();
if (keyFile == null)
return false;
if (!keyFile.exists())
return false;
File altFile = getAlternatePrivateKeyFile();
if (altFile == null)
return false;
if (altFile.equals(keyFile))
return false;
if (altFile.exists())
return true;
PrivateKeyFile pkf = new PrivateKeyFile(keyFile);
FileOutputStream out = null;
try {
Destination dest = pkf.getDestination();
if (dest == null)
return false;
if (dest.getSigType() != SigType.DSA_SHA1)
return false;
PublicKey pub = dest.getPublicKey();
PrivateKey priv = pkf.getPrivKey();
SimpleDataStructure[] signingKeys = KeyGenerator.getInstance().generateSigningKeys(PREFERRED_SIGTYPE);
SigningPublicKey signingPubKey = (SigningPublicKey) signingKeys[0];
SigningPrivateKey signingPrivKey = (SigningPrivateKey) signingKeys[1];
KeyCertificate cert = new KeyCertificate(signingPubKey);
Destination d = new Destination();
d.setPublicKey(pub);
d.setSigningPublicKey(signingPubKey);
d.setCertificate(cert);
int len = signingPubKey.length();
if (len < 128) {
byte[] pad = new byte[128 - len];
RandomSource.getInstance().nextBytes(pad);
d.setPadding(pad);
} else if (len > 128) {
// copy of excess data handled in KeyCertificate constructor
}
out = new SecureFileOutputStream(altFile);
d.writeBytes(out);
priv.writeBytes(out);
signingPrivKey.writeBytes(out);
try {
out.close();
} catch (IOException ioe) {
}
String destStr = d.toBase64();
log("Alternate private key created and saved in " + altFile.getAbsolutePath());
log("You should backup this file in a secure place.");
log("New alternate destination: " + destStr);
String b32 = d.toBase32();
log("Base32: " + b32);
File backupDir = new SecureFile(I2PAppContext.getGlobalContext().getConfigDir(), KEY_BACKUP_DIR);
if (backupDir.isDirectory() || backupDir.mkdir()) {
String name = b32 + '-' + I2PAppContext.getGlobalContext().clock().now() + ".dat";
File backup = new File(backupDir, name);
if (FileUtil.copy(altFile, backup, false, true)) {
SecureFileOutputStream.setPerms(backup);
log("Alternate private key backup saved to " + backup.getAbsolutePath());
}
}
return true;
} catch (GeneralSecurityException e) {
log("Error creating keys " + e);
return false;
} catch (I2PSessionException e) {
log("Error creating keys " + e);
return false;
} catch (I2PException e) {
log("Error creating keys " + e);
return false;
} catch (IOException e) {
log("Error creating keys " + e);
return false;
} catch (RuntimeException e) {
log("Error creating keys " + e);
return false;
} finally {
if (out != null)
try {
out.close();
} catch (IOException ioe) {
}
}
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class SAMv1Handler method execDgOrRawMessage.
/*
* Parse and execute a RAW or DATAGRAM SEND message.
* This is for v1/v2 compatible sending only.
* For v3 sending, see SAMv3DatagramServer.
*
* Note that props are from the command line only.
* Session defaults from CREATE are NOT honored here.
* FIXME if we care, but nobody's probably using v3.2 options for v1/v2 sending.
*
* @since 0.9.25 consolidated from execDatagramMessage() and execRawMessage()
*/
private boolean execDgOrRawMessage(boolean isRaw, String opcode, Properties props) {
if (opcode.equals("SEND")) {
if (props.isEmpty()) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("No parameters specified in SEND message");
return false;
}
String dest = props.getProperty("DESTINATION");
if (dest == null) {
if (_log.shouldWarn())
_log.warn("Destination not specified in SEND message");
return false;
}
int size;
String strsize = props.getProperty("SIZE");
if (strsize == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Size not specified in SEND message");
return false;
}
try {
size = Integer.parseInt(strsize);
} catch (NumberFormatException e) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid SEND size specified: " + strsize);
return false;
}
boolean ok = isRaw ? checkSize(size) : checkDatagramSize(size);
if (!ok) {
if (_log.shouldLog(Log.WARN))
_log.warn("Specified size (" + size + ") is out of protocol limits");
return false;
}
int fromPort = I2PSession.PORT_UNSPECIFIED;
int toPort = I2PSession.PORT_UNSPECIFIED;
int proto;
if (isRaw) {
proto = I2PSession.PROTO_DATAGRAM_RAW;
String s = props.getProperty("PROTOCOL");
if (s != null) {
try {
proto = Integer.parseInt(s);
} catch (NumberFormatException e) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid SEND protocol specified: " + s);
}
}
} else {
proto = I2PSession.PROTO_DATAGRAM;
}
String s = props.getProperty("FROM_PORT");
if (s != null) {
try {
fromPort = Integer.parseInt(s);
} catch (NumberFormatException e) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid SEND port specified: " + s);
}
}
s = props.getProperty("TO_PORT");
if (s != null) {
try {
toPort = Integer.parseInt(s);
} catch (NumberFormatException e) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid SEND port specified: " + s);
}
}
try {
DataInputStream in = new DataInputStream(getClientSocket().socket().getInputStream());
byte[] data = new byte[size];
in.readFully(data);
SAMMessageSess sess = isRaw ? rawSession : datagramSession;
if (!sess.sendBytes(dest, data, proto, fromPort, toPort)) {
if (_log.shouldWarn())
_log.warn((isRaw ? "SEND RAW to " : "SEND DATAGRAM to ") + dest + " size " + size + " failed");
// a message send failure is no reason to drop the SAM session
// for raw and repliable datagrams, just carry on our merry way
}
return true;
} catch (EOFException e) {
if (_log.shouldWarn())
_log.warn("Too few bytes with SEND message (expected: " + size, e);
return false;
} catch (IOException e) {
if (_log.shouldWarn())
_log.warn("Caught IOException while parsing SEND message", e);
return false;
} catch (DataFormatException e) {
if (_log.shouldWarn())
_log.warn("Invalid key specified with SEND message", e);
return false;
} catch (I2PSessionException e) {
_log.error("Session error with SEND message", e);
return false;
}
} else {
if (_log.shouldWarn())
_log.warn("Unrecognized message opcode: \"" + opcode + "\"");
return false;
}
}
Aggregations