diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
index 51c9373b0..905c27cee 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
@@ -198,6 +198,7 @@ public class SnarkManager implements Snark.CompleteListener {
String ot = _config.getProperty(I2PSnarkUtil.PROP_OPENTRACKERS);
if (ot != null)
_util.setOpenTrackerString(ot);
+ // FIXME set util use open trackers property somehow
getDataDir().mkdirs();
}
@@ -428,6 +429,14 @@ public class SnarkManager implements Snark.CompleteListener {
fis.close();
fis = null;
+ if (!TrackerClient.isValidAnnounce(info.getAnnounce())) {
+ if (_util.shouldUseOpenTrackers() && _util.getOpenTrackers() != null) {
+ addMessage(_("Warning - Ignoring non-i2p tracker in \"{0}\", will announce to i2p open trackers only", info.getName()));
+ } else {
+ addMessage(_("Warning - Ignoring non-i2p tracker in \"{0}\", and open trackers are disabled, you must enable open trackers before starting the torrent!", info.getName()));
+ dontAutoStart = true;
+ }
+ }
String rejectMessage = locked_validateTorrent(info);
if (rejectMessage != null) {
sfile.delete();
@@ -551,12 +560,10 @@ public class SnarkManager implements Snark.CompleteListener {
saveConfig();
}
+ /**
+ * Warning - does not validate announce URL - use TrackerClient.isValidAnnounce()
+ */
private String locked_validateTorrent(MetaInfo info) throws IOException {
- String announce = info.getAnnounce();
- // basic validation of url
- if ((!announce.startsWith("http://")) ||
- (announce.indexOf(".i2p/") < 0)) // need to do better than this
- return _("Non-i2p tracker in \"{0}\", deleting it from our list of trackers!", info.getName());
List files = info.getFiles();
if ( (files != null) && (files.size() > MAX_FILES_PER_TORRENT) ) {
return _("Too many files in \"{0}\" ({1}), deleting it!", info.getName(), files.size());
diff --git a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java
index 309fd62b5..c6f22a63d 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/TrackerClient.java
@@ -24,6 +24,8 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
@@ -123,13 +125,19 @@ public class TrackerClient extends I2PAppThread
// followed by the secondary open trackers
// It's painful, but try to make sure if an open tracker is also
// the primary tracker, that we don't add it twice.
+ // todo: check for b32 matches as well
trackers = new ArrayList(2);
- trackers.add(new Tracker(meta.getAnnounce(), true));
+ String primary = meta.getAnnounce();
+ if (isValidAnnounce(primary)) {
+ trackers.add(new Tracker(meta.getAnnounce(), true));
+ } else {
+ _log.warn("Skipping invalid or non-i2p announce: " + primary);
+ }
List tlist = _util.getOpenTrackers();
if (tlist != null) {
for (int i = 0; i < tlist.size(); i++) {
String url = (String)tlist.get(i);
- if (!url.startsWith("http://")) {
+ if (!isValidAnnounce(url)) {
_log.error("Bad announce URL: [" + url + "]");
continue;
}
@@ -138,22 +146,29 @@ public class TrackerClient extends I2PAppThread
_log.error("Bad announce URL: [" + url + "]");
continue;
}
- if (meta.getAnnounce().startsWith(url.substring(0, slash)))
+ if (primary.startsWith(url.substring(0, slash)))
continue;
String dest = _util.lookup(url.substring(7, slash));
if (dest == null) {
_log.error("Announce host unknown: [" + url + "]");
continue;
}
- if (meta.getAnnounce().startsWith("http://" + dest))
+ if (primary.startsWith("http://" + dest))
continue;
- if (meta.getAnnounce().startsWith("http://i2p/" + dest))
+ if (primary.startsWith("http://i2p/" + dest))
continue;
trackers.add(new Tracker(url, false));
_log.debug("Additional announce: [" + url + "] for infoHash: " + infoHash);
}
}
+ if (tlist.size() <= 0) {
+ // FIXME really need to get this message to the gui
+ stop = true;
+ _log.error("No valid trackers for infoHash: " + infoHash);
+ return;
+ }
+
long uploaded = coordinator.getUploaded();
long downloaded = coordinator.getDownloaded();
long left = coordinator.getLeft();
@@ -399,6 +414,22 @@ public class TrackerClient extends I2PAppThread
return sb.toString();
}
+ /**
+ * @return true for i2p hosts only
+ * @since 0.7.12
+ */
+ static boolean isValidAnnounce(String ann) {
+ URL url;
+ try {
+ url = new URL(ann);
+ } catch (MalformedURLException mue) {
+ return false;
+ }
+ return url.getProtocol().equals("http") &&
+ (url.getHost().endsWith(".i2p") || url.getHost().equals("i2p")) &&
+ url.getPort() < 0;
+ }
+
private class Tracker
{
String announce;
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index f5e46d5d9..013d70a94 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -455,8 +455,11 @@ public class I2PSnarkServlet extends HttpServlet {
int i = filename.lastIndexOf(".torrent");
if (i > 0)
filename = filename.substring(0, i);
- if (filename.length() > MAX_DISPLAYED_FILENAME_LENGTH)
+ String fullFilename = filename;
+ if (filename.length() > MAX_DISPLAYED_FILENAME_LENGTH) {
+ fullFilename = new String(filename);
filename = filename.substring(0, MAX_DISPLAYED_FILENAME_LENGTH) + "…";
+ }
long total = snark.meta.getTotalLength();
// Early typecast, avoid possibly overflowing a temp integer
long remaining = (long) snark.storage.needed() * (long) snark.meta.getPieceLength(0);
@@ -627,13 +630,23 @@ public class I2PSnarkServlet extends HttpServlet {
out.write("");
+ out.write("\" onclick=\"if (!confirm('");
+ // Can't figure out how to escape double quotes inside the onclick string.
+ // Single quotes in translate strings with parameters must be doubled.
+ // Then the remaining single quite must be escaped
+ out.write(_("Are you sure you want to delete the file \\''{0}.torrent\\'' (downloaded data will not be deleted) ?", fullFilename));
+ out.write("')) { return false; }\">");
out.write(_("Remove"));
out.write("
");
out.write("");
+ out.write("\" onclick=\"if (!confirm('");
+ // Can't figure out how to escape double quotes inside the onclick string.
+ // Single quotes in translate strings with parameters must be doubled.
+ // Then the remaining single quite must be escaped
+ out.write(_("Are you sure you want to delete the torrent \\''{0}\\'' and all downloaded data?", fullFilename));
+ out.write("')) { return false; }\">");
out.write(_("Delete"));
out.write("");
}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java
index d66e37e23..bb19f3c47 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigClientsHelper.java
@@ -42,11 +42,12 @@ public class ConfigClientsHelper extends HelperBase {
ClientAppConfig ca = clients.get(cur);
renderForm(buf, ""+cur, ca.clientName, false, !ca.disabled,
"webConsole".equals(ca.clientName) || "Web console".equals(ca.clientName),
- ca.className + ((ca.args != null) ? " " + ca.args : ""), (""+cur).equals(_edit), true, false, false);
+ ca.className + ((ca.args != null) ? " " + ca.args : ""), (""+cur).equals(_edit),
+ true, false, false, true);
}
if ("new".equals(_edit))
- renderForm(buf, "" + clients.size(), "", false, false, false, "", true, false, false, false);
+ renderForm(buf, "" + clients.size(), "", false, false, false, "", true, false, false, false, false);
buf.append("\n");
return buf.toString();
}
@@ -63,7 +64,8 @@ public class ConfigClientsHelper extends HelperBase {
String app = name.substring(RouterConsoleRunner.PREFIX.length(), name.lastIndexOf(RouterConsoleRunner.ENABLED));
String val = props.getProperty(name);
renderForm(buf, app, app, !"addressbook".equals(app),
- "true".equals(val), RouterConsoleRunner.ROUTERCONSOLE.equals(app), app + ".war", false, false, false, false);
+ "true".equals(val), RouterConsoleRunner.ROUTERCONSOLE.equals(app), app + ".war",
+ false, false, false, false, false);
}
}
buf.append("\n");
@@ -146,7 +148,7 @@ public class ConfigClientsHelper extends HelperBase {
desc.append("");
renderForm(buf, app, app, false,
"true".equals(val), false, desc.toString(), false, false,
- updateURL != null, true);
+ updateURL != null, true, true);
}
}
buf.append("\n");
@@ -156,7 +158,8 @@ public class ConfigClientsHelper extends HelperBase {
/** ro trumps edit and showEditButton */
private void renderForm(StringBuilder buf, String index, String name, boolean urlify,
boolean enabled, boolean ro, String desc, boolean edit,
- boolean showEditButton, boolean showUpdateButton, boolean showStopButton) {
+ boolean showEditButton, boolean showUpdateButton, boolean showStopButton,
+ boolean showDeleteButton) {
buf.append("