use of net.i2p.data.Destination in project i2p.i2p by i2p.
the class I2PTunnel method destFromName.
/**
* @param i2cpHost may be null
* @param i2cpPort may be null
* @param user may be null
* @param pw may be null
* @since 0.9.11
*/
private static Destination destFromName(String name, String i2cpHost, String i2cpPort, boolean isSSL, String user, String pw) throws DataFormatException {
if ((name == null) || (name.trim().length() <= 0))
throw new DataFormatException("Empty destination provided");
I2PAppContext ctx = I2PAppContext.getGlobalContext();
Log log = ctx.logManager().getLog(I2PTunnel.class);
if (name.startsWith("file:")) {
Destination result = new Destination();
byte[] content = null;
FileInputStream in = null;
try {
in = new FileInputStream(name.substring("file:".length()));
byte[] buf = new byte[1024];
int read = DataHelper.read(in, buf);
content = new byte[read];
System.arraycopy(buf, 0, content, 0, read);
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
return null;
} finally {
if (in != null)
try {
in.close();
} catch (IOException io) {
}
}
try {
result.fromByteArray(content);
return result;
} catch (RuntimeException ex) {
if (log.shouldLog(Log.INFO))
log.info("File is not a binary destination - trying base64");
try {
byte[] decoded = Base64.decode(new String(content));
result.fromByteArray(decoded);
return result;
} catch (DataFormatException dfe) {
if (log.shouldLog(Log.WARN))
log.warn("File is not a base64 destination either - failing!");
return null;
}
}
} else {
// ask naming service
name = name.trim();
NamingService inst = ctx.namingService();
boolean b32 = name.length() == 60 && name.toLowerCase(Locale.US).endsWith(".b32.i2p");
Destination d = null;
if (ctx.isRouterContext() || !b32) {
// Local lookup.
// Even though we could do b32 outside router ctx here,
// we do it below instead so we can set the host and port,
// which we can't do with lookup()
d = inst.lookup(name);
if (d != null || ctx.isRouterContext() || name.length() >= 516)
return d;
}
// Outside router context only,
// try simple session to ask the router.
I2PClient client = new I2PSimpleClient();
Properties opts = new Properties();
if (i2cpHost != null)
opts.put(I2PClient.PROP_TCP_HOST, i2cpHost);
if (i2cpPort != null)
opts.put(I2PClient.PROP_TCP_PORT, i2cpPort);
opts.put("i2cp.SSL", Boolean.toString(isSSL));
if (user != null)
opts.put("i2cp.username", user);
if (pw != null)
opts.put("i2cp.password", pw);
I2PSession session = null;
try {
session = client.createSession(null, opts);
session.connect();
d = session.lookupDest(name);
} catch (I2PSessionException ise) {
if (log.shouldLog(Log.WARN))
log.warn("Lookup via router failed", ise);
} finally {
if (session != null) {
try {
session.destroySession();
} catch (I2PSessionException ise) {
}
}
}
return d;
}
}
use of net.i2p.data.Destination in project i2p.i2p by i2p.
the class I2PTunnel method runLookup.
/**
* Perform a lookup of the name specified
* Deprecated - only used by CLI
*
* Sets the event "lookupResult" = base64 of the destination, or an error message
*
* @param args {name}
* @param l logger to receive events and output
*/
private void runLookup(String[] args, Logging l) {
if (args.length != 1) {
l.log("lookup <name>\n" + " try to resolve the name into a destination key");
notifyEvent("lookupResult", "invalidUsage");
} else {
try {
boolean ssl = Boolean.parseBoolean(_clientOptions.getProperty("i2cp.SSL"));
String user = _clientOptions.getProperty("i2cp.username");
String pw = _clientOptions.getProperty("i2cp.password");
Destination dest = destFromName(args[0], host, port, ssl, user, pw);
if (dest == null) {
l.log("Unknown host: " + args[0]);
notifyEvent("lookupResult", "unkown host");
} else {
l.log(dest.toBase64());
notifyEvent("lookupResult", dest.toBase64());
}
} catch (DataFormatException dfe) {
l.log("Unknown or invalid host: " + args[0]);
notifyEvent("lookupResult", "invalid host");
}
}
}
use of net.i2p.data.Destination in project i2p.i2p by i2p.
the class I2PTunnelHTTPClientBase method writeErrorMessage.
/**
* @param jumpServers comma- or space-separated list, or null
* @param extraMessage extra message or null, will be HTML-escaped
* @since 0.9.14
*/
protected void writeErrorMessage(String errMessage, String extraMessage, OutputStream outs, String targetRequest, boolean usingWWWProxy, String wwwProxy, String jumpServers) throws IOException {
if (outs == null)
return;
Writer out = new BufferedWriter(new OutputStreamWriter(outs, "UTF-8"));
out.write(errMessage);
if (targetRequest != null) {
String uri = DataHelper.escapeHTML(targetRequest);
out.write("<a href=\"");
out.write(uri);
out.write("\">");
// Long URLs are handled in CSS
out.write(uri);
out.write("</a>");
if (usingWWWProxy) {
out.write("<br><br><b>");
out.write(_t("HTTP Outproxy"));
out.write(":</b> " + wwwProxy);
}
if (extraMessage != null) {
out.write("<br><br><b>" + DataHelper.escapeHTML(extraMessage) + "</b>");
}
if (jumpServers != null && jumpServers.length() > 0) {
boolean first = true;
if (uri.startsWith("http://")) {
uri = uri.substring(7);
}
StringTokenizer tok = new StringTokenizer(jumpServers, ", ");
while (tok.hasMoreTokens()) {
String jurl = tok.nextToken();
String jumphost;
try {
URI jURI = new URI(jurl);
String proto = jURI.getScheme();
jumphost = jURI.getHost();
if (proto == null || jumphost == null || !proto.toLowerCase(Locale.US).equals("http"))
continue;
jumphost = jumphost.toLowerCase(Locale.US);
if (!jumphost.endsWith(".i2p"))
continue;
} catch (URISyntaxException use) {
continue;
}
// Skip jump servers we don't know
if (!jumphost.endsWith(".b32.i2p")) {
Destination dest = _context.namingService().lookup(jumphost);
if (dest == null) {
continue;
}
}
if (first) {
first = false;
out.write("<br><br>\n<div id=\"jumplinks\">\n<h4>");
out.write(_t("Click a link below for an address helper from a jump service"));
out.write("</h4>\n");
} else {
out.write("<br>");
}
out.write("<a href=\"");
out.write(jurl);
out.write(uri);
out.write("\">");
// Translators: parameter is a host name
out.write(_t("{0} jump service", jumphost));
out.write("</a>\n");
}
if (!first) {
// We wrote out the opening <div>
out.write("</div>\n");
}
}
}
out.write("</div>\n");
writeFooter(out);
}
use of net.i2p.data.Destination 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.data.Destination in project i2p.i2p by i2p.
the class PeerCoordinator method gotPeers.
/**
* Get peers from PEX -
* PeerListener callback
* @since 0.8.4
*/
public void gotPeers(Peer peer, List<PeerID> peers) {
if (!needOutboundPeers())
return;
Destination myDest = _util.getMyDestination();
if (myDest == null)
return;
byte[] myHash = myDest.calculateHash().getData();
List<Peer> pList = peerList();
for (PeerID id : peers) {
if (peerIDInList(id, pList) != null)
continue;
if (DataHelper.eq(myHash, id.getDestHash()))
continue;
pexPeers.add(id);
}
// TrackerClient will poll for pexPeers and do the add in its thread,
// rather than running another thread here.
}
Aggregations