use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class RequestLeaseSetMessageHandler method signLeaseSet.
/**
* Finish creating and signing the new LeaseSet
* @since 0.9.7
*/
protected synchronized void signLeaseSet(LeaseSet leaseSet, I2PSessionImpl session) {
Destination dest = session.getMyDestination();
// also, if this session is connected to multiple routers, include other leases here
leaseSet.setDestination(dest);
// reuse the old keys for the client
LeaseInfo li = _existingLeaseSets.get(dest);
if (li == null) {
// [enctype:]b64 of private key
String spk = session.getOptions().getProperty("i2cp.leaseSetPrivateKey");
// [sigtype:]b64 of private key
String sspk = session.getOptions().getProperty("i2cp.leaseSetSigningPrivateKey");
PrivateKey privKey = null;
SigningPrivateKey signingPrivKey = null;
if (spk != null && sspk != null) {
boolean useOldKeys = true;
int colon = sspk.indexOf(':');
SigType type = dest.getSigType();
if (colon > 0) {
String stype = sspk.substring(0, colon);
SigType t = SigType.parseSigType(stype);
if (t == type)
sspk = sspk.substring(colon + 1);
else
useOldKeys = false;
}
colon = spk.indexOf(':');
// just ignore for now, no other types supported
if (colon >= 0)
spk = spk.substring(colon + 1);
if (useOldKeys) {
try {
signingPrivKey = new SigningPrivateKey(type);
signingPrivKey.fromBase64(sspk);
} catch (DataFormatException iae) {
useOldKeys = false;
signingPrivKey = null;
}
}
if (useOldKeys) {
try {
privKey = new PrivateKey();
privKey.fromBase64(spk);
} catch (DataFormatException iae) {
privKey = null;
}
}
}
if (privKey == null && !_existingLeaseSets.isEmpty()) {
// look for keypair from another dest using same pubkey
PublicKey pk = dest.getPublicKey();
for (Map.Entry<Destination, LeaseInfo> e : _existingLeaseSets.entrySet()) {
if (pk.equals(e.getKey().getPublicKey())) {
privKey = e.getValue().getPrivateKey();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Creating new leaseInfo keys for " + dest + " with private key from " + e.getKey());
break;
}
}
}
if (privKey != null) {
if (signingPrivKey != null) {
li = new LeaseInfo(privKey, signingPrivKey);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Creating new leaseInfo keys for " + dest + " WITH configured private keys");
} else {
li = new LeaseInfo(privKey, dest);
}
} else {
li = new LeaseInfo(dest);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Creating new leaseInfo keys for " + dest + " without configured private keys");
}
_existingLeaseSets.put(dest, li);
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Caching the old leaseInfo keys for " + dest);
}
leaseSet.setEncryptionKey(li.getPublicKey());
leaseSet.setSigningKey(li.getSigningPublicKey());
// SubSession options aren't updated via the gui, so use the primary options
Properties opts;
if (session instanceof SubSession)
opts = ((SubSession) session).getPrimaryOptions();
else
opts = session.getOptions();
boolean encrypt = Boolean.parseBoolean(opts.getProperty("i2cp.encryptLeaseSet"));
String sk = opts.getProperty("i2cp.leaseSetKey");
Hash h = dest.calculateHash();
if (encrypt && sk != null) {
SessionKey key = new SessionKey();
try {
key.fromBase64(sk);
leaseSet.encrypt(key);
_context.keyRing().put(h, key);
} catch (DataFormatException dfe) {
_log.error("Bad leaseset key: " + sk);
_context.keyRing().remove(h);
}
} else {
_context.keyRing().remove(h);
}
try {
leaseSet.sign(session.getPrivateKey());
// Workaround for unparsable serialized signing private key for revocation
// Send him a dummy DSA_SHA1 private key since it's unused anyway
// See CreateLeaseSetMessage.doReadMessage()
SigningPrivateKey spk = li.getSigningPrivateKey();
if (!_context.isRouterContext() && spk.getType() != SigType.DSA_SHA1) {
byte[] dummy = new byte[SigningPrivateKey.KEYSIZE_BYTES];
_context.random().nextBytes(dummy);
spk = new SigningPrivateKey(dummy);
}
session.getProducer().createLeaseSet(session, leaseSet, spk, li.getPrivateKey());
session.setLeaseSet(leaseSet);
} catch (DataFormatException dfe) {
session.propogateError("Error signing the leaseSet", dfe);
} catch (I2PSessionException ise) {
if (session.isClosed()) {
// race, closed while signing leaseset
// EOFExceptions are logged at WARN level (see I2PSessionImpl.propogateError())
// so the user won't see this
EOFException eof = new EOFException("Session closed while signing leaseset");
eof.initCause(ise);
session.propogateError("Session closed while signing leaseset", eof);
} else {
session.propogateError("Error sending the signed leaseSet", ise);
}
}
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class SessionStatusMessageHandler method handleMessage.
public void handleMessage(I2CPMessage message, I2PSessionImpl session) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Handle message " + message);
SessionStatusMessage msg = (SessionStatusMessage) message;
session.setSessionId(msg.getSessionId());
switch(msg.getStatus()) {
case SessionStatusMessage.STATUS_CREATED:
_log.info("Session created successfully");
break;
case SessionStatusMessage.STATUS_DESTROYED:
_log.warn("Session destroyed");
session.propogateError("Destroyed", new I2PSessionException("Session Status Message received"));
// session.destroySession();
// la la la
session.reconnect();
break;
case SessionStatusMessage.STATUS_INVALID:
_log.warn("Session invalid");
session.propogateError("Invalid", new I2PSessionException("Session Status Message received"));
// ok, honor this destroy message, because we're b0rked
session.destroySession();
break;
case SessionStatusMessage.STATUS_UPDATED:
_log.info("Session status updated");
break;
default:
if (_log.shouldLog(Log.WARN))
_log.warn("Unknown session status sent: " + msg.getStatus());
}
return;
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class SubSession method connect.
/**
* Connect to the router and establish a session. This call blocks until
* a session is granted.
*
* Should be threadsafe, other threads will block until complete.
* Disconnect / destroy from another thread may be called simultaneously and
* will (should?) interrupt the connect.
*
* Connecting a subsession will automatically connect the primary session
* if not previously connected.
*
* @throws I2PSessionException if there is a configuration error or the router is
* not reachable
*/
@Override
public void connect() throws I2PSessionException {
synchronized (_stateLock) {
if (_state != State.OPEN) {
changeState(State.OPENING);
}
}
boolean success = false;
try {
_primary.connect();
// wait until we have created a lease set
int waitcount = 0;
while (_leaseSet == null) {
if (waitcount++ > 5 * 60) {
throw new IOException("No tunnels built after waiting 5 minutes. Your network connection may be down, or there is severe network congestion.");
}
synchronized (_leaseSetWait) {
// InterruptedException caught below
_leaseSetWait.wait(1000);
}
}
synchronized (_stateLock) {
if (_state != State.OPEN) {
Thread notifier = new I2PAppThread(_availabilityNotifier, "ClientNotifier " + getPrefix(), true);
notifier.start();
changeState(State.OPEN);
}
}
success = true;
} catch (InterruptedException ie) {
throw new I2PSessionException("Interrupted", ie);
} catch (IOException ioe) {
throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, ioe);
} finally {
if (!success) {
_availabilityNotifier.stopNotifying();
changeState(State.CLOSED);
}
}
}
use of net.i2p.client.I2PSessionException in project i2p.i2p-bote by i2p.
the class I2PBote method initializeSession.
/**
* Sets up a {@link I2PSession}, using the I2P destination stored on disk or creating a new I2P
* destination if no key file exists.
*/
private void initializeSession() throws I2PSessionException {
Properties sessionProperties = new Properties();
// set tunnel names
sessionProperties.setProperty("inbound.nickname", "I2P-Bote");
sessionProperties.setProperty("outbound.nickname", "I2P-Bote");
sessionProperties.putAll(configuration.getI2CPOptions());
// According to sponge, muxed depends on gzip, so leave gzip enabled
// read the local destination key from the key file if it exists
File destinationKeyFile = configuration.getDestinationKeyFile();
FileReader fileReader = null;
try {
fileReader = new FileReader(destinationKeyFile);
char[] destKeyBuffer = new char[(int) destinationKeyFile.length()];
fileReader.read(destKeyBuffer);
byte[] localDestinationKey = Base64.decode(new String(destKeyBuffer));
ByteArrayInputStream inputStream = new ByteArrayInputStream(localDestinationKey);
socketManager = I2PSocketManagerFactory.createDisconnectedManager(inputStream, null, 0, sessionProperties);
} catch (IOException e) {
log.debug("Destination key file doesn't exist or isn't readable." + e);
} catch (I2PSessionException e) {
// Won't happen, inputStream != null
} finally {
if (fileReader != null)
try {
fileReader.close();
} catch (IOException e) {
log.debug("Error closing file: <" + destinationKeyFile.getAbsolutePath() + ">" + e);
}
}
// if the local destination key can't be read or is invalid, create a new one
if (socketManager == null) {
log.debug("Creating new local destination key");
try {
ByteArrayOutputStream arrayStream = new ByteArrayOutputStream();
i2pClient.createDestination(arrayStream);
byte[] localDestinationKey = arrayStream.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(localDestinationKey);
socketManager = I2PSocketManagerFactory.createDisconnectedManager(inputStream, null, 0, sessionProperties);
saveLocalDestinationKeys(destinationKeyFile, localDestinationKey);
} catch (I2PException e) {
log.error("Error creating local destination key.", e);
} catch (IOException e) {
log.error("Error writing local destination key to file.", e);
}
}
i2pSession = socketManager.getSession();
// Throws I2PSessionException if the connection fails
i2pSession.connect();
Destination localDestination = i2pSession.getMyDestination();
log.info("Local destination key (base64): " + localDestination.toBase64());
log.info("Local destination hash (base64): " + localDestination.calculateHash().toBase64());
log.info("Local destination hash (base32): " + Util.toBase32(localDestination));
}
Aggregations