use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class SAMv3Handler method execSessionMessage.
/* Parse and execute a SESSION message */
@Override
protected boolean execSessionMessage(String opcode, Properties props) {
String dest = "BUG!";
boolean ok = false;
String nick = (String) props.remove("ID");
if (nick == null)
return writeString(SESSION_ERROR, "ID not specified");
String style = (String) props.remove("STYLE");
if (style == null && !opcode.equals("REMOVE"))
return writeString(SESSION_ERROR, "No SESSION STYLE specified");
try {
if (opcode.equals("CREATE")) {
if ((this.getRawSession() != null) || (this.getDatagramSession() != null) || (this.getStreamSession() != null)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Trying to create a session, but one still exists");
return writeString(SESSION_ERROR, "Session already exists");
}
if (props.isEmpty()) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("No parameters specified in SESSION CREATE message");
return writeString(SESSION_ERROR, "No parameters for SESSION CREATE");
}
dest = (String) props.remove("DESTINATION");
if (dest == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SESSION DESTINATION parameter not specified");
return writeString(SESSION_ERROR, "DESTINATION not specified");
}
if (dest.equals("TRANSIENT")) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("TRANSIENT destination requested");
String sigTypeStr = (String) props.remove("SIGNATURE_TYPE");
SigType sigType;
if (sigTypeStr != null) {
sigType = SigType.parseSigType(sigTypeStr);
if (sigType == null) {
return writeString(SESSION_ERROR, "SIGNATURE_TYPE " + sigTypeStr + " unsupported");
}
} else {
sigType = SigType.DSA_SHA1;
}
ByteArrayOutputStream priv = new ByteArrayOutputStream(663);
SAMUtils.genRandomKey(priv, null, sigType);
dest = Base64.encode(priv.toByteArray());
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Custom destination specified [" + dest + "]");
if (!SAMUtils.checkPrivateDestination(dest))
return writeString("SESSION STATUS RESULT=INVALID_KEY\n");
}
// Unconditionally override what the client may have set
// (iMule sets BestEffort) as None is more efficient
// and the client has no way to access delivery notifications
i2cpProps.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
i2cpProps.setProperty("i2cp.fastReceive", "true");
// Record the session in the database sSessionsHash
Properties allProps = new Properties();
allProps.putAll(i2cpProps);
allProps.putAll(props);
if (style.equals("MASTER")) {
// We must put these here, as SessionRecord.getProps() makes a copy,
// and the socket manager is instantiated in the
// SAMStreamSession constructor.
allProps.setProperty("i2p.streaming.enforceProtocol", "true");
allProps.setProperty("i2cp.dontPublishLeaseSet", "false");
}
try {
sSessionsHash.put(nick, new SessionRecord(dest, allProps, this));
} catch (SessionsDB.ExistingIdException e) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SESSION ID parameter already in use");
return writeString("SESSION STATUS RESULT=DUPLICATED_ID\n");
} catch (SessionsDB.ExistingDestException e) {
return writeString("SESSION STATUS RESULT=DUPLICATED_DEST\n");
}
if (style.equals("RAW")) {
SAMv3DatagramServer dgs = bridge.getV3DatagramServer(props);
SAMv3RawSession v3 = new SAMv3RawSession(nick, dgs);
rawSession = v3;
this.session = v3;
v3.start();
} else if (style.equals("DATAGRAM")) {
SAMv3DatagramServer dgs = bridge.getV3DatagramServer(props);
SAMv3DatagramSession v3 = new SAMv3DatagramSession(nick, dgs);
datagramSession = v3;
this.session = v3;
v3.start();
} else if (style.equals("STREAM")) {
SAMv3StreamSession v3 = newSAMStreamSession(nick);
streamSession = v3;
this.session = v3;
v3.start();
} else if (style.equals("MASTER")) {
SAMv3DatagramServer dgs = bridge.getV3DatagramServer(props);
MasterSession v3 = new MasterSession(nick, dgs, this, allProps);
streamSession = v3;
datagramSession = v3;
rawSession = v3;
this.session = v3;
v3.start();
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unrecognized SESSION STYLE: \"" + style + "\"");
return writeString(SESSION_ERROR, "Unrecognized SESSION STYLE");
}
ok = true;
return writeString("SESSION STATUS RESULT=OK DESTINATION=" + dest + "\n");
} else if (opcode.equals("ADD") || opcode.equals("REMOVE")) {
// prevent trouble in finally block
ok = true;
if (streamSession == null || datagramSession == null || rawSession == null)
return writeString(SESSION_ERROR, "Not a MASTER session");
MasterSession msess = (MasterSession) session;
String msg;
if (opcode.equals("ADD")) {
msg = msess.add(nick, style, props);
} else {
msg = msess.remove(nick, props);
}
if (msg == null)
return writeString("SESSION STATUS RESULT=OK ID=\"" + nick + '"', opcode + ' ' + nick);
else
return writeString(SESSION_ERROR + " ID=\"" + nick + '"', msg);
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unrecognized SESSION message opcode: \"" + opcode + "\"");
return writeString(SESSION_ERROR, "Unrecognized opcode");
}
} catch (DataFormatException e) {
_log.error("Invalid SAM destination specified", e);
return writeString("SESSION STATUS RESULT=INVALID_KEY", e.getMessage());
} catch (I2PSessionException e) {
_log.error("Failed to start SAM session", e);
return writeString(SESSION_ERROR, e.getMessage());
} catch (SAMException e) {
_log.error("Failed to start SAM session", e);
return writeString(SESSION_ERROR, e.getMessage());
} catch (IOException e) {
_log.error("Failed to start SAM session", e);
return writeString(SESSION_ERROR, e.getMessage());
} finally {
// unregister the session if it has not been created
if (!ok && nick != null) {
sSessionsHash.del(nick);
session = null;
}
}
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class ConfigTunnelsHandler method saveChanges.
/**
* The user made changes to the network config and wants to save them, so
* lets go ahead and do so.
*/
private void saveChanges() {
boolean saveRequired = false;
Map<String, String> changes = new HashMap<String, String>();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Saving changes, with props = " + _settings + ".");
int updated = 0;
int index = 0;
while (true) {
Object val = _settings.get("pool." + index);
if (val == null)
break;
Hash client = new Hash();
String poolName = (val instanceof String ? (String) val : ((String[]) val)[0]);
TunnelPoolSettings in = null;
TunnelPoolSettings out = null;
if ("exploratory".equals(poolName)) {
in = _context.tunnelManager().getInboundSettings();
out = _context.tunnelManager().getOutboundSettings();
} else {
try {
client.fromBase64(poolName);
} catch (DataFormatException dfe) {
addFormError("Internal error (pool name could not resolve - " + poolName + ").");
index++;
continue;
}
in = _context.tunnelManager().getInboundSettings(client);
out = _context.tunnelManager().getOutboundSettings(client);
}
if ((in == null) || (out == null)) {
addFormError("Internal error (pool settings cound not be found for " + poolName + ").");
index++;
continue;
}
in.setLength(getInt(_settings.get(index + ".depthInbound")));
out.setLength(getInt(_settings.get(index + ".depthOutbound")));
in.setLengthVariance(getInt(_settings.get(index + ".varianceInbound")));
out.setLengthVariance(getInt(_settings.get(index + ".varianceOutbound")));
in.setQuantity(getInt(_settings.get(index + ".quantityInbound")));
out.setQuantity(getInt(_settings.get(index + ".quantityOutbound")));
in.setBackupQuantity(getInt(_settings.get(index + ".backupInbound")));
out.setBackupQuantity(getInt(_settings.get(index + ".backupOutbound")));
if ("exploratory".equals(poolName)) {
changes.put(TunnelPoolSettings.PREFIX_INBOUND_EXPLORATORY + TunnelPoolSettings.PROP_LENGTH, in.getLength() + "");
changes.put(TunnelPoolSettings.PREFIX_OUTBOUND_EXPLORATORY + TunnelPoolSettings.PROP_LENGTH, out.getLength() + "");
changes.put(TunnelPoolSettings.PREFIX_INBOUND_EXPLORATORY + TunnelPoolSettings.PROP_LENGTH_VARIANCE, in.getLengthVariance() + "");
changes.put(TunnelPoolSettings.PREFIX_OUTBOUND_EXPLORATORY + TunnelPoolSettings.PROP_LENGTH_VARIANCE, out.getLengthVariance() + "");
changes.put(TunnelPoolSettings.PREFIX_INBOUND_EXPLORATORY + TunnelPoolSettings.PROP_QUANTITY, in.getQuantity() + "");
changes.put(TunnelPoolSettings.PREFIX_OUTBOUND_EXPLORATORY + TunnelPoolSettings.PROP_QUANTITY, out.getQuantity() + "");
changes.put(TunnelPoolSettings.PREFIX_INBOUND_EXPLORATORY + TunnelPoolSettings.PROP_BACKUP_QUANTITY, in.getBackupQuantity() + "");
changes.put(TunnelPoolSettings.PREFIX_OUTBOUND_EXPLORATORY + TunnelPoolSettings.PROP_BACKUP_QUANTITY, out.getBackupQuantity() + "");
}
if ("exploratory".equals(poolName)) {
if (_log.shouldLog(Log.DEBUG)) {
_log.debug("Inbound exploratory settings: " + in);
_log.debug("Outbound exploratory settings: " + out);
}
_context.tunnelManager().setInboundSettings(in);
_context.tunnelManager().setOutboundSettings(out);
} else {
if (_log.shouldLog(Log.DEBUG)) {
_log.debug("Inbound settings for " + client.toBase64() + ": " + in);
_log.debug("Outbound settings for " + client.toBase64() + ": " + out);
}
_context.tunnelManager().setInboundSettings(client, in);
_context.tunnelManager().setOutboundSettings(client, out);
}
updated++;
saveRequired = true;
index++;
}
if (updated > 0)
// the count isn't really correct anyway, since we don't check for actual changes
// addFormNotice("Updated settings for " + updated + " pools.");
addFormNotice(_t("Updated settings for all pools."));
if (saveRequired) {
boolean saved = _context.router().saveConfig(changes, null);
if (saved)
addFormNotice(_t("Exploratory tunnel configuration saved successfully."));
else
addFormError(_t("Error saving the configuration (applied but not saved) - please see the error logs."));
}
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class MasterSession method add.
/**
* Add a session
* @return null for success, or error message
*/
public synchronized String add(String nick, String style, Properties props) {
if (props.containsKey("DESTINATION"))
return "SESSION ADD may not contain DESTINATION";
SessionRecord rec = SAMv3Handler.sSessionsHash.get(nick);
if (rec != null || sessions.containsKey(nick))
return "Duplicate ID " + nick;
int listenPort = I2PSession.PORT_ANY;
String slp = (String) props.remove("LISTEN_PORT");
if (slp == null)
slp = props.getProperty("FROM_PORT");
if (slp != null) {
try {
listenPort = Integer.parseInt(slp);
if (listenPort < 0 || listenPort > 65535)
return "Bad LISTEN_PORT " + slp;
// TODO enforce streaming listen port must be 0 or from port
} catch (NumberFormatException nfe) {
return "Bad LISTEN_PORT " + slp;
}
}
int listenProtocol;
SAMMessageSess sess;
SAMv3Handler subhandler;
try {
I2PSession isess = socketMgr.getSession();
subhandler = new SAMv3Handler(handler.getClientSocket(), handler.verMajor, handler.verMinor, handler.getBridge());
if (style.equals("RAW")) {
if (!props.containsKey("PORT"))
return "RAW subsession must specify PORT";
listenProtocol = I2PSession.PROTO_DATAGRAM_RAW;
String spr = (String) props.remove("LISTEN_PROTOCOL");
if (spr == null)
spr = props.getProperty("PROTOCOL");
if (spr != null) {
try {
listenProtocol = Integer.parseInt(spr);
// RAW can't listen on streaming protocol
if (listenProtocol < 0 || listenProtocol > 255 || listenProtocol == I2PSession.PROTO_STREAMING)
return "Bad RAW LISTEN_PPROTOCOL " + spr;
} catch (NumberFormatException nfe) {
return "Bad LISTEN_PROTOCOL " + spr;
}
}
SAMv3RawSession ssess = new SAMv3RawSession(nick, props, handler, isess, listenProtocol, listenPort, dgs);
subhandler.setSession(ssess);
sess = ssess;
} else if (style.equals("DATAGRAM")) {
if (!props.containsKey("PORT"))
return "DATAGRAM subsession must specify PORT";
listenProtocol = I2PSession.PROTO_DATAGRAM;
SAMv3DatagramSession ssess = new SAMv3DatagramSession(nick, props, handler, isess, listenPort, dgs);
subhandler.setSession(ssess);
sess = ssess;
} else if (style.equals("STREAM")) {
listenProtocol = I2PSession.PROTO_STREAMING;
// FIXME need something that hangs off an existing dest
SAMv3StreamSession ssess = new SAMv3StreamSession(nick, props, handler, socketMgr, listenPort);
subhandler.setSession(ssess);
sess = ssess;
} else {
return "Unrecognized SESSION STYLE " + style;
}
} catch (IOException e) {
return e.toString();
} catch (DataFormatException e) {
return e.toString();
} catch (SAMException e) {
return e.toString();
} catch (I2PSessionException e) {
return e.toString();
}
for (SAMMessageSess s : sessions.values()) {
if (listenProtocol == s.getListenProtocol() && listenPort == s.getListenPort())
return "Duplicate protocol " + listenProtocol + " and port " + listenPort;
}
rec = new SessionRecord(getDestination().toBase64(), props, subhandler);
try {
SAMv3Handler.sSessionsHash.putDupDestOK(nick, rec);
sessions.put(nick, sess);
} catch (SessionsDB.ExistingIdException e) {
return "Duplicate ID " + nick;
}
if (_log.shouldWarn())
_log.warn("added " + style + " proto " + listenProtocol + " port " + listenPort);
sess.start();
// all ok
return null;
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class SAMUtils method checkPrivateDestination.
/**
* Check whether a base64-encoded dest is valid
*
* @param dest The base64-encoded destination to be checked
*
* @return True if the destination is valid, false otherwise
*/
/**
**
* public static boolean checkDestination(String dest) {
* try {
* Destination d = new Destination();
* d.fromBase64(dest);
*
* return true;
* } catch (DataFormatException e) {
* return false;
* }
* }
***
*/
/**
* Check whether a base64-encoded {dest,privkey,signingprivkey} is valid
*
* @param dest The base64-encoded destination and keys to be checked (same format as PrivateKeyFile)
* @return true if valid
*/
public static boolean checkPrivateDestination(String dest) {
byte[] b = Base64.decode(dest);
if (b == null || b.length < 663)
return false;
ByteArrayInputStream destKeyStream = new ByteArrayInputStream(b);
try {
Destination d = Destination.create(destKeyStream);
new PrivateKey().readBytes(destKeyStream);
SigningPrivateKey spk = new SigningPrivateKey(d.getSigningPublicKey().getType());
spk.readBytes(destKeyStream);
} catch (DataFormatException e) {
return false;
} catch (IOException e) {
return false;
}
return destKeyStream.available() == 0;
}
use of net.i2p.data.DataFormatException in project i2p.i2p by i2p.
the class ElGamalTest method testAES.
public void testAES() {
SessionKey sessionKey = KeyGenerator.getInstance().generateSessionKey();
Hash h = SHA256Generator.getInstance().calculateHash(sessionKey.getData());
byte[] iv = new byte[16];
System.arraycopy(h.getData(), 0, iv, 0, 16);
String msg = "Hello world";
byte[] encrypted = _context.elGamalAESEngine().encryptAESBlock(DataHelper.getASCII(msg), sessionKey, iv, null, null, 64);
Set<SessionTag> foundTags = new HashSet<SessionTag>();
SessionKey foundKey = new SessionKey();
byte[] decrypted = null;
try {
decrypted = _context.elGamalAESEngine().decryptAESBlock(encrypted, 0, encrypted.length, sessionKey, iv, null, foundTags, foundKey);
} catch (DataFormatException dfe) {
dfe.printStackTrace();
fail();
}
assertNotNull(decrypted);
String read = new String(decrypted);
assertEquals(msg, read);
}
Aggregations