propagate from branch 'i2p.i2p.zzz.update' (head 267311f29e501fcc8b3d674a93e78b5520ac985e)

to branch 'i2p.i2p' (head edeca2ab47e734c2314ff394609292d8bd3d5293)
This commit is contained in:
zzz
2012-10-28 12:48:35 +00:00
149 changed files with 15417 additions and 4477 deletions

View File

@@ -10,6 +10,7 @@ trans.fr = apps/i2ptunnel/locale/messages_fr.po
trans.hu = apps/i2ptunnel/locale/messages_hu.po trans.hu = apps/i2ptunnel/locale/messages_hu.po
trans.it = apps/i2ptunnel/locale/messages_it.po trans.it = apps/i2ptunnel/locale/messages_it.po
trans.nl = apps/i2ptunnel/locale/messages_nl.po trans.nl = apps/i2ptunnel/locale/messages_nl.po
trans.pt = apps/i2ptunnel/locale/messages_pt.po
trans.ru = apps/i2ptunnel/locale/messages_ru.po trans.ru = apps/i2ptunnel/locale/messages_ru.po
trans.sv_SE = apps/i2ptunnel/locale/messages_sv.po trans.sv_SE = apps/i2ptunnel/locale/messages_sv.po
trans.uk_UA = apps/i2ptunnel/locale/messages_uk.po trans.uk_UA = apps/i2ptunnel/locale/messages_uk.po
@@ -32,6 +33,7 @@ trans.hu = apps/routerconsole/locale/messages_hu.po
trans.it = apps/routerconsole/locale/messages_it.po trans.it = apps/routerconsole/locale/messages_it.po
trans.nl = apps/routerconsole/locale/messages_nl.po trans.nl = apps/routerconsole/locale/messages_nl.po
trans.pl = apps/routerconsole/locale/messages_pl.po trans.pl = apps/routerconsole/locale/messages_pl.po
trans.pt = apps/routerconsole/locale/messages_pt.po
trans.ru = apps/routerconsole/locale/messages_ru.po trans.ru = apps/routerconsole/locale/messages_ru.po
trans.sv_SE = apps/routerconsole/locale/messages_sv.po trans.sv_SE = apps/routerconsole/locale/messages_sv.po
trans.uk_UA = apps/routerconsole/locale/messages_uk.po trans.uk_UA = apps/routerconsole/locale/messages_uk.po
@@ -70,6 +72,7 @@ trans.hu = apps/susidns/locale/messages_hu.po
trans.it = apps/susidns/locale/messages_it.po trans.it = apps/susidns/locale/messages_it.po
trans.nl = apps/susidns/locale/messages_nl.po trans.nl = apps/susidns/locale/messages_nl.po
trans.pl = apps/susidns/locale/messages_pl.po trans.pl = apps/susidns/locale/messages_pl.po
trans.pt = apps/susidns/locale/messages_pt.po
trans.ru = apps/susidns/locale/messages_ru.po trans.ru = apps/susidns/locale/messages_ru.po
trans.sv_SE = apps/susidns/locale/messages_sv.po trans.sv_SE = apps/susidns/locale/messages_sv.po
trans.uk_UA = apps/susidns/locale/messages_uk.po trans.uk_UA = apps/susidns/locale/messages_uk.po

View File

@@ -94,7 +94,7 @@ public class I2Plistener implements Runnable {
} }
} catch (I2PException e) { } catch (I2PException e) {
// bad shit // bad stuff
System.out.println("Exception " + e); System.out.println("Exception " + e);
} }
} finally { } finally {

View File

@@ -58,7 +58,7 @@ public class I2PSnarkUtil {
private volatile I2PSocketManager _manager; private volatile I2PSocketManager _manager;
private boolean _configured; private boolean _configured;
private volatile boolean _connecting; private volatile boolean _connecting;
private final Set<Hash> _shitlist; private final Set<Hash> _banlist;
private int _maxUploaders; private int _maxUploaders;
private int _maxUpBW; private int _maxUpBW;
private int _maxConnections; private int _maxConnections;
@@ -86,7 +86,7 @@ public class I2PSnarkUtil {
_opts = new HashMap(); _opts = new HashMap();
//setProxy("127.0.0.1", 4444); //setProxy("127.0.0.1", 4444);
setI2CPConfig("127.0.0.1", 7654, null); setI2CPConfig("127.0.0.1", 7654, null);
_shitlist = new ConcurrentHashSet(); _banlist = new ConcurrentHashSet();
_maxUploaders = Snark.MAX_TOTAL_UPLOADERS; _maxUploaders = Snark.MAX_TOTAL_UPLOADERS;
_maxUpBW = DEFAULT_MAX_UP_BW; _maxUpBW = DEFAULT_MAX_UP_BW;
_maxConnections = MAX_CONNECTIONS; _maxConnections = MAX_CONNECTIONS;
@@ -283,7 +283,7 @@ public class I2PSnarkUtil {
I2PSocketManager mgr = _manager; I2PSocketManager mgr = _manager;
// FIXME this can cause race NPEs elsewhere // FIXME this can cause race NPEs elsewhere
_manager = null; _manager = null;
_shitlist.clear(); _banlist.clear();
if (mgr != null) { if (mgr != null) {
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Disconnecting from I2P", new Exception("I did it")); _log.debug("Disconnecting from I2P", new Exception("I did it"));
@@ -306,24 +306,24 @@ public class I2PSnarkUtil {
if (addr.equals(getMyDestination())) if (addr.equals(getMyDestination()))
throw new IOException("Attempt to connect to myself"); throw new IOException("Attempt to connect to myself");
Hash dest = addr.calculateHash(); Hash dest = addr.calculateHash();
if (_shitlist.contains(dest)) if (_banlist.contains(dest))
throw new IOException("Not trying to contact " + dest.toBase64() + ", as they are shitlisted"); throw new IOException("Not trying to contact " + dest.toBase64() + ", as they are banlisted");
try { try {
I2PSocket rv = _manager.connect(addr); I2PSocket rv = _manager.connect(addr);
if (rv != null) if (rv != null)
_shitlist.remove(dest); _banlist.remove(dest);
return rv; return rv;
} catch (I2PException ie) { } catch (I2PException ie) {
_shitlist.add(dest); _banlist.add(dest);
_context.simpleScheduler().addEvent(new Unshitlist(dest), 10*60*1000); _context.simpleScheduler().addEvent(new Unbanlist(dest), 10*60*1000);
throw new IOException("Unable to reach the peer " + peer + ": " + ie.getMessage()); throw new IOException("Unable to reach the peer " + peer + ": " + ie.getMessage());
} }
} }
private class Unshitlist implements SimpleTimer.TimedEvent { private class Unbanlist implements SimpleTimer.TimedEvent {
private Hash _dest; private Hash _dest;
public Unshitlist(Hash dest) { _dest = dest; } public Unbanlist(Hash dest) { _dest = dest; }
public void timeReached() { _shitlist.remove(_dest); } public void timeReached() { _banlist.remove(_dest); }
} }
/** /**

View File

@@ -377,7 +377,10 @@ class PeerCoordinator implements PeerListener
public boolean needOutboundPeers() { public boolean needOutboundPeers() {
//return wantedBytes != 0 && needPeers(); //return wantedBytes != 0 && needPeers();
// minus one to make it a little easier for new peers to get in on large swarms // minus one to make it a little easier for new peers to get in on large swarms
return wantedBytes != 0 && !halted && peers.size() < getMaxConnections() - 1; return wantedBytes != 0 &&
!halted &&
peers.size() < getMaxConnections() - 1 &&
(storage == null || !storage.isChecking());
} }
/** /**
@@ -741,6 +744,18 @@ class PeerCoordinator implements PeerListener
break; break;
if (havePieces.get(p.getId()) && !p.isRequested()) if (havePieces.get(p.getId()) && !p.isRequested())
{ {
// never ever choose one that's in partialPieces, or we
// will create a second one and leak
boolean hasPartial = false;
for (PartialPiece pp : partialPieces) {
if (pp.getPiece() == p.getId()) {
if (_log.shouldLog(Log.INFO))
_log.info("wantPiece() skipping partial for " + peer + ": piece = " + pp);
hasPartial = true;
break;
}
}
if (!hasPartial)
piece = p; piece = p;
} }
else if (p.isRequested()) else if (p.isRequested())
@@ -943,11 +958,14 @@ class PeerCoordinator implements PeerListener
*/ */
public boolean gotPiece(Peer peer, PartialPiece pp) public boolean gotPiece(Peer peer, PartialPiece pp)
{ {
if (metainfo == null || storage == null) if (metainfo == null || storage == null || storage.isChecking()) {
pp.release();
return true; return true;
}
int piece = pp.getPiece(); int piece = pp.getPiece();
if (halted) { if (halted) {
_log.info("Got while-halted piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName()); _log.info("Got while-halted piece " + piece + "/" + metainfo.getPieces() +" from " + peer + " for " + metainfo.getName());
pp.release();
return true; // We don't actually care anymore. return true; // We don't actually care anymore.
} }
@@ -962,12 +980,15 @@ class PeerCoordinator implements PeerListener
// Assume we got a good piece, we don't really care anymore. // Assume we got a good piece, we don't really care anymore.
// Well, this could be caused by a change in priorities, so // Well, this could be caused by a change in priorities, so
// only return true if we already have it, otherwise might as well keep it. // only return true if we already have it, otherwise might as well keep it.
if (storage.getBitField().get(piece)) if (storage.getBitField().get(piece)) {
pp.release();
return true; return true;
} }
}
try try
{ {
// this takes forever if complete, as it rechecks
if (storage.putPiece(pp)) if (storage.putPiece(pp))
{ {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
@@ -1173,6 +1194,8 @@ class PeerCoordinator implements PeerListener
public PartialPiece getPartialPiece(Peer peer, BitField havePieces) { public PartialPiece getPartialPiece(Peer peer, BitField havePieces) {
if (metainfo == null) if (metainfo == null)
return null; return null;
if (storage != null && storage.isChecking())
return null;
synchronized(wantedPieces) { synchronized(wantedPieces) {
// sorts by remaining bytes, least first // sorts by remaining bytes, least first
Collections.sort(partialPieces); Collections.sort(partialPieces);
@@ -1277,6 +1300,7 @@ class PeerCoordinator implements PeerListener
PartialPiece pp = iter.next(); PartialPiece pp = iter.next();
if (pp.getPiece() == piece) { if (pp.getPiece() == piece) {
iter.remove(); iter.remove();
pp.release();
// there should be only one but keep going to be sure // there should be only one but keep going to be sure
} }
} }

View File

@@ -592,6 +592,7 @@ class PeerState implements DataLoader
// Send cancel even when we are choked to make sure that it is // Send cancel even when we are choked to make sure that it is
// really never ever send. // really never ever send.
out.sendCancel(req); out.sendCancel(req);
req.getPartialPiece().release();
} }
} }
} }
@@ -741,6 +742,10 @@ class PeerState implements DataLoader
out.sendRequest(r); out.sendRequest(r);
lastRequest = r; lastRequest = r;
return true; return true;
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("Got dup from coord: " + pp);
pp.release();
} }
} }

View File

@@ -985,6 +985,8 @@ public class Storage
/** /**
* Put the piece in the Storage if it is correct. * Put the piece in the Storage if it is correct.
* Warning - takes a LONG time if complete as it does the recheck here.
* TODO thread the recheck?
* *
* @return true if the piece was correct (sha metainfo hash * @return true if the piece was correct (sha metainfo hash
* matches), otherwise false. * matches), otherwise false.

View File

@@ -995,14 +995,16 @@ public class I2PSnarkServlet extends DefaultServlet {
} else if (snark.isAllocating()) { } else if (snark.isAllocating()) {
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Allocating") + "\"></td>" + statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "stalled.png\" title=\"" + _("Allocating") + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Allocating"); "<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Allocating");
} else if (err != null) { } else if (err != null && curPeers == 0) {
if (isRunning && curPeers > 0 && !showPeers) // let's only show this if we have no peers, otherwise PEX and DHT should bail us out, user doesn't care
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" + //if (isRunning && curPeers > 0 && !showPeers)
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") + // statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + "\">" + // "<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") +
curPeers + thinsp(noThinsp) + // ": <a href=\"" + uri + "?p=" + Base64.encode(snark.getInfoHash()) + "\">" +
ngettext("1 peer", "{0} peers", knownPeers) + "</a>"; // curPeers + thinsp(noThinsp) +
else if (isRunning) // ngettext("1 peer", "{0} peers", knownPeers) + "</a>";
//else if (isRunning)
if (isRunning)
statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" + statusString = "<img alt=\"\" border=\"0\" src=\"" + _imgPath + "trackererror.png\" title=\"" + err + "\"></td>" +
"<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") + "<td class=\"snarkTorrentStatus " + rowClass + "\">" + _("Tracker Error") +
": " + curPeers + thinsp(noThinsp) + ": " + curPeers + thinsp(noThinsp) +
@@ -1149,7 +1151,7 @@ public class I2PSnarkServlet extends DefaultServlet {
out.write("</a>"); out.write("</a>");
out.write("<td align=\"right\" class=\"snarkTorrentETA " + rowClass + "\">"); out.write("<td align=\"right\" class=\"snarkTorrentETA " + rowClass + "\">");
if(isRunning && remainingSeconds > 0) if(isRunning && remainingSeconds > 0 && !snark.isChecking())
out.write(DataHelper.formatDuration2(Math.max(remainingSeconds, 10) * 1000)); // (eta 6h) out.write(DataHelper.formatDuration2(Math.max(remainingSeconds, 10) * 1000)); // (eta 6h)
out.write("</td>\n\t"); out.write("</td>\n\t");
out.write("<td align=\"right\" class=\"snarkTorrentDownloaded " + rowClass + "\">"); out.write("<td align=\"right\" class=\"snarkTorrentDownloaded " + rowClass + "\">");

View File

@@ -12,9 +12,9 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: I2P\n" "Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-10-12 00:46+0000\n" "POT-Creation-Date: 2012-10-15 17:57+0000\n"
"PO-Revision-Date: 2012-10-12 00:39+0000\n" "PO-Revision-Date: 2012-10-12 00:54+0000\n"
"Last-Translator: kytv <killyourtv@i2pmail.org>\n" "Last-Translator: BadCluster <badcluster@i2pmail.org>\n"
"Language-Team: Italian (http://www.transifex.com/projects/p/I2P/language/" "Language-Team: Italian (http://www.transifex.com/projects/p/I2P/language/"
"it/)\n" "it/)\n"
"Language: it\n" "Language: it\n"
@@ -342,7 +342,7 @@ msgstr "Torrent in aggiunta in {0}"
#: ../java/src/org/klomp/snark/SnarkManager.java:1374 #: ../java/src/org/klomp/snark/SnarkManager.java:1374
#, java-format #, java-format
msgid "Up bandwidth limit is {0} KBps" msgid "Up bandwidth limit is {0} KBps"
msgstr "" msgstr "La banda di Upload massima è {0} KBps"
#: ../java/src/org/klomp/snark/SnarkManager.java:1396 #: ../java/src/org/klomp/snark/SnarkManager.java:1396
#, java-format #, java-format
@@ -606,7 +606,7 @@ msgstr "File torrent eliminato: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:642 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:642
#, java-format #, java-format
msgid "Download deleted: {0}" msgid "Download deleted: {0}"
msgstr "" msgstr "Downloads cancellati: {0}"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:656 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:656
#, java-format #, java-format
@@ -701,12 +701,12 @@ msgstr "Ripristina tracker di default"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:997 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:997
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:998 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:998
msgid "Checking" msgid "Checking"
msgstr "" msgstr "Controllo (Check)"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1000 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1000
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1001 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1001
msgid "Allocating" msgid "Allocating"
msgstr "" msgstr "Allocando"
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1005 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1005
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1011 #: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:1011

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,7 @@ import java.util.Locale;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.I2PException; import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket; import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketOptions; import net.i2p.client.streaming.I2PSocketOptions;
@@ -20,7 +21,6 @@ import net.i2p.data.Base64;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
import net.i2p.data.Destination; import net.i2p.data.Destination;
import net.i2p.util.EventDispatcher; import net.i2p.util.EventDispatcher;
import net.i2p.util.FileUtil;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.PortMapper; import net.i2p.util.PortMapper;
@@ -58,6 +58,8 @@ import net.i2p.util.PortMapper;
*/ */
public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements Runnable { public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements Runnable {
public static final String AUTH_REALM = "I2P SSL Proxy";
private final static byte[] ERR_DESTINATION_UNKNOWN = private final static byte[] ERR_DESTINATION_UNKNOWN =
("HTTP/1.1 503 Service Unavailable\r\n"+ ("HTTP/1.1 503 Service Unavailable\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+ "Content-Type: text/html; charset=iso-8859-1\r\n"+
@@ -89,17 +91,6 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
"Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>") "Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>")
.getBytes(); .getBytes();
private final static byte[] ERR_AUTH =
("HTTP/1.1 407 Proxy Authentication Required\r\n"+
"Content-Type: text/html; charset=UTF-8\r\n"+
"Cache-control: no-cache\r\n"+
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.5\r\n" + // try to get a UTF-8-encoded response back for the password
"Proxy-Authenticate: Basic realm=\"I2P SSL Proxy\"\r\n" +
"\r\n"+
"<html><body><H1>I2P ERROR: PROXY AUTHENTICATION REQUIRED</H1>"+
"This proxy is configured to require authentication.<BR>")
.getBytes();
private final static byte[] SUCCESS_RESPONSE = private final static byte[] SUCCESS_RESPONSE =
("HTTP/1.1 200 Connection Established\r\n"+ ("HTTP/1.1 200 Connection Established\r\n"+
"Proxy-agent: I2P\r\n"+ "Proxy-agent: I2P\r\n"+
@@ -165,6 +156,11 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
return super.close(forced); return super.close(forced);
} }
/** @since 0.9.4 */
protected String getRealm() {
return AUTH_REALM;
}
protected void clientConnectionRun(Socket s) { protected void clientConnectionRun(Socket s) {
InputStream in = null; InputStream in = null;
OutputStream out = null; OutputStream out = null;
@@ -237,10 +233,10 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
_log.debug(getPrefix(requestId) + "REST :" + restofline + ":"); _log.debug(getPrefix(requestId) + "REST :" + restofline + ":");
_log.debug(getPrefix(requestId) + "DEST :" + destination + ":"); _log.debug(getPrefix(requestId) + "DEST :" + destination + ":");
} }
} else if (line.toLowerCase(Locale.US).startsWith("proxy-authorization: basic ")) { } else if (line.toLowerCase(Locale.US).startsWith("proxy-authorization: ")) {
// strip Proxy-Authenticate from the response in HTTPResponseOutputStream // strip Proxy-Authenticate from the response in HTTPResponseOutputStream
// save for auth check below // save for auth check below
authorization = line.substring(27); // "proxy-authorization: basic ".length() authorization = line.substring(21); // "proxy-authorization: ".length()
line = null; line = null;
} else if (line.length() > 0) { } else if (line.length() > 0) {
// Additional lines - shouldn't be too many. Firefox sends: // Additional lines - shouldn't be too many. Firefox sends:
@@ -281,30 +277,26 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
} }
// Authorization // Authorization
if (!authorize(s, requestId, authorization)) { AuthResult result = authorize(s, requestId, method, authorization);
if (result != AuthResult.AUTH_GOOD) {
if (_log.shouldLog(Log.WARN)) { if (_log.shouldLog(Log.WARN)) {
if (authorization != null) if (authorization != null)
_log.warn(getPrefix(requestId) + "Auth failed, sending 407 again"); _log.warn(getPrefix(requestId) + "Auth failed, sending 407 again");
else else
_log.warn(getPrefix(requestId) + "Auth required, sending 407"); _log.warn(getPrefix(requestId) + "Auth required, sending 407");
} }
writeErrorMessage(ERR_AUTH, out); out.write(getAuthError(result == AuthResult.AUTH_STALE).getBytes());
s.close(); s.close();
return; return;
} }
Destination clientDest = _context.namingService().lookup(destination); Destination clientDest = _context.namingService().lookup(destination);
if (clientDest == null) { if (clientDest == null) {
String str;
byte[] header; byte[] header;
if (usingWWWProxy) if (usingWWWProxy)
str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true); header = getErrorPage("dnfp-header.ht", ERR_DESTINATION_UNKNOWN);
else else
str = FileUtil.readTextFile((new File(_errorDir, "dnfh-header.ht")).getAbsolutePath(), 100, true); header = getErrorPage("dnfh-header.ht", ERR_DESTINATION_UNKNOWN);
if (str != null)
header = str.getBytes();
else
header = ERR_DESTINATION_UNKNOWN;
writeErrorMessage(header, out, targetRequest, usingWWWProxy, destination); writeErrorMessage(header, out, targetRequest, usingWWWProxy, destination);
s.close(); s.close();
return; return;
@@ -341,12 +333,13 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
} }
private static class OnTimeout implements Runnable { private static class OnTimeout implements Runnable {
private Socket _socket; private final Socket _socket;
private OutputStream _out; private final OutputStream _out;
private String _target; private final String _target;
private boolean _usingProxy; private final boolean _usingProxy;
private String _wwwProxy; private final String _wwwProxy;
private long _requestId; private final long _requestId;
public OnTimeout(Socket s, OutputStream out, String target, boolean usingProxy, String wwwProxy, long id) { public OnTimeout(Socket s, OutputStream out, String target, boolean usingProxy, String wwwProxy, long id) {
_socket = s; _socket = s;
_out = out; _out = out;
@@ -355,6 +348,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
_wwwProxy = wwwProxy; _wwwProxy = wwwProxy;
_requestId = id; _requestId = id;
} }
public void run() { public void run() {
//if (_log.shouldLog(Log.DEBUG)) //if (_log.shouldLog(Log.DEBUG))
// _log.debug("Timeout occured requesting " + _target); // _log.debug("Timeout occured requesting " + _target);
@@ -391,17 +385,12 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
boolean usingWWWProxy, String wwwProxy, long requestId) { boolean usingWWWProxy, String wwwProxy, long requestId) {
if (out == null) if (out == null)
return; return;
try {
String str;
byte[] header; byte[] header;
if (usingWWWProxy) if (usingWWWProxy)
str = FileUtil.readTextFile((new File(_errorDir, "dnfp-header.ht")).getAbsolutePath(), 100, true); header = getErrorPage(I2PAppContext.getGlobalContext(), "dnfp-header.ht", ERR_DESTINATION_UNKNOWN);
else else
str = FileUtil.readTextFile((new File(_errorDir, "dnf-header.ht")).getAbsolutePath(), 100, true); header = getErrorPage(I2PAppContext.getGlobalContext(), "dnf-header.ht", ERR_DESTINATION_UNKNOWN);
if (str != null) try {
header = str.getBytes();
else
header = ERR_DESTINATION_UNKNOWN;
writeErrorMessage(header, out, targetRequest, usingWWWProxy, wwwProxy); writeErrorMessage(header, out, targetRequest, usingWWWProxy, wwwProxy);
} catch (IOException ioe) {} } catch (IOException ioe) {}
} }

View File

@@ -3,9 +3,7 @@
*/ */
package net.i2p.i2ptunnel; package net.i2p.i2ptunnel;
import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@@ -73,10 +71,14 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
* via address helper links * via address helper links
*/ */
private final ConcurrentHashMap<String, String> addressHelpers = new ConcurrentHashMap(8); private final ConcurrentHashMap<String, String> addressHelpers = new ConcurrentHashMap(8);
/** /**
* Used to protect actions via http://proxy.i2p/ * Used to protect actions via http://proxy.i2p/
*/ */
private final String _proxyNonce; private final String _proxyNonce;
public static final String AUTH_REALM = "I2P HTTP Proxy";
/** /**
* These are backups if the xxx.ht error page is missing. * These are backups if the xxx.ht error page is missing.
*/ */
@@ -167,15 +169,6 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
"\r\n" + "\r\n" +
"<html><body><H1>I2P ERROR: REQUEST DENIED</H1>" + "<html><body><H1>I2P ERROR: REQUEST DENIED</H1>" +
"Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>").getBytes(); "Your browser is misconfigured. Do not use the proxy to access the router console or other localhost destinations.<BR>").getBytes();
private final static byte[] ERR_AUTH =
("HTTP/1.1 407 Proxy Authentication Required\r\n" +
"Content-Type: text/html; charset=UTF-8\r\n" +
"Cache-control: no-cache\r\n" +
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.5\r\n" + // try to get a UTF-8-encoded response back for the password
"Proxy-Authenticate: Basic realm=\"I2P HTTP Proxy\"\r\n" +
"\r\n" +
"<html><body><H1>I2P ERROR: PROXY AUTHENTICATION REQUIRED</H1>" +
"This proxy is configured to require authentication.<BR>").getBytes();
/** /**
* This constructor always starts the tunnel (ignoring the i2cp.delayOpen option). * This constructor always starts the tunnel (ignoring the i2cp.delayOpen option).
@@ -300,6 +293,12 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
} }
return rv; return rv;
} }
/** @since 0.9.4 */
protected String getRealm() {
return AUTH_REALM;
}
private static final String HELPER_PARAM = "i2paddresshelper"; private static final String HELPER_PARAM = "i2paddresshelper";
public static final String LOCAL_SERVER = "proxy.i2p"; public static final String LOCAL_SERVER = "proxy.i2p";
private static final boolean DEFAULT_GZIP = true; private static final boolean DEFAULT_GZIP = true;
@@ -769,10 +768,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
// hop-by-hop header, and we definitely want to block Windows NTLM after a far-end 407. // hop-by-hop header, and we definitely want to block Windows NTLM after a far-end 407.
// Response to far-end shouldn't happen, as we // Response to far-end shouldn't happen, as we
// strip Proxy-Authenticate from the response in HTTPResponseOutputStream // strip Proxy-Authenticate from the response in HTTPResponseOutputStream
if(lowercaseLine.startsWith("proxy-authorization: basic ")) // save for auth check below authorization = line.substring(21); // "proxy-authorization: ".length()
{
authorization = line.substring(27); // "proxy-authorization: basic ".length()
}
line = null; line = null;
continue; continue;
} else if(lowercaseLine.startsWith("icy")) { } else if(lowercaseLine.startsWith("icy")) {
@@ -850,7 +846,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
} }
// Authorization // Authorization
if(!authorize(s, requestId, authorization)) { AuthResult result = authorize(s, requestId, method, authorization);
if (result != AuthResult.AUTH_GOOD) {
if(_log.shouldLog(Log.WARN)) { if(_log.shouldLog(Log.WARN)) {
if(authorization != null) { if(authorization != null) {
_log.warn(getPrefix(requestId) + "Auth failed, sending 407 again"); _log.warn(getPrefix(requestId) + "Auth failed, sending 407 again");
@@ -858,7 +855,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
_log.warn(getPrefix(requestId) + "Auth required, sending 407"); _log.warn(getPrefix(requestId) + "Auth required, sending 407");
} }
} }
out.write(getErrorPage("auth", ERR_AUTH)); out.write(getAuthError(result == AuthResult.AUTH_STALE).getBytes());
writeFooter(out); writeFooter(out);
s.close(); s.close();
return; return;
@@ -1095,61 +1092,6 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
return Base32.encode(_dest.calculateHash().getData()) + ".b32.i2p"; return Base32.encode(_dest.calculateHash().getData()) + ".b32.i2p";
} }
/**
* foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht,
* or the backup byte array on fail.
*
* .ht files must be UTF-8 encoded and use \r\n terminators so the
* HTTP headers are conformant.
* We can't use FileUtil.readFile() because it strips \r
*
* @return non-null
*/
private byte[] getErrorPage(String base, byte[] backup) {
return getErrorPage(_context, base, backup);
}
private static byte[] getErrorPage(I2PAppContext ctx, String base, byte[] backup) {
File errorDir = new File(ctx.getBaseDir(), "docs");
String lang = ctx.getProperty("routerconsole.lang", Locale.getDefault().getLanguage());
if(lang != null && lang.length() > 0 && !lang.equals("en")) {
File file = new File(errorDir, base + "-header_" + lang + ".ht");
try {
return readFile(file);
} catch(IOException ioe) {
// try the english version now
}
}
File file = new File(errorDir, base + "-header.ht");
try {
return readFile(file);
} catch(IOException ioe) {
return backup;
}
}
private static byte[] readFile(File file) throws IOException {
FileInputStream fis = null;
byte[] buf = new byte[512];
ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
try {
int len = 0;
fis = new FileInputStream(file);
while((len = fis.read(buf)) > 0) {
baos.write(buf, 0, len);
}
return baos.toByteArray();
} finally {
try {
if(fis != null) {
fis.close();
}
} catch(IOException foo) {
}
}
// we won't ever get here
}
/** /**
* Public only for LocalHTTPServer, not for general use * Public only for LocalHTTPServer, not for general use
*/ */
@@ -1163,12 +1105,12 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
private static class OnTimeout implements Runnable { private static class OnTimeout implements Runnable {
private Socket _socket; private final Socket _socket;
private OutputStream _out; private final OutputStream _out;
private String _target; private final String _target;
private boolean _usingProxy; private final boolean _usingProxy;
private String _wwwProxy; private final String _wwwProxy;
private long _requestId; private final long _requestId;
public OnTimeout(Socket s, OutputStream out, String target, boolean usingProxy, String wwwProxy, long id) { public OnTimeout(Socket s, OutputStream out, String target, boolean usingProxy, String wwwProxy, long id) {
_socket = s; _socket = s;

View File

@@ -3,19 +3,26 @@
*/ */
package net.i2p.i2ptunnel; package net.i2p.i2ptunnel;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList; import java.util.ArrayList;
import java.io.File; import java.io.File;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PSocketManager; import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.data.Base64; import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.util.EventDispatcher; import net.i2p.util.EventDispatcher;
import net.i2p.util.InternalSocket; import net.i2p.util.InternalSocket;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.PasswordManager;
/** /**
* Common things for HTTPClient and ConnectClient * Common things for HTTPClient and ConnectClient
@@ -25,6 +32,25 @@ import net.i2p.util.Log;
*/ */
public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implements Runnable { public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implements Runnable {
private static final int PROXYNONCE_BYTES = 8;
private static final int MD5_BYTES = 16;
/** 24 */
private static final int NONCE_BYTES = DataHelper.DATE_LENGTH + MD5_BYTES;
private static final long MAX_NONCE_AGE = 30*24*60*60*1000L;
private static final String ERR_AUTH1 =
"HTTP/1.1 407 Proxy Authentication Required\r\n" +
"Content-Type: text/html; charset=UTF-8\r\n" +
"Cache-control: no-cache\r\n" +
"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.5\r\n" + // try to get a UTF-8-encoded response back for the password
"Proxy-Authenticate: ";
// put the auth type and realm in between
private static final String ERR_AUTH2 =
"\r\n" +
"\r\n" +
"<html><body><H1>I2P ERROR: PROXY AUTHENTICATION REQUIRED</H1>" +
"This proxy is configured to require authentication.";
protected final List<String> _proxyList; protected final List<String> _proxyList;
protected final static byte[] ERR_NO_OUTPROXY = protected final static byte[] ERR_NO_OUTPROXY =
@@ -40,7 +66,7 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
/** used to assign unique IDs to the threads / clients. no logic or functionality */ /** used to assign unique IDs to the threads / clients. no logic or functionality */
protected static volatile long __clientId = 0; protected static volatile long __clientId = 0;
protected static final File _errorDir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs"); private final byte[] _proxyNonce;
protected String getPrefix(long requestId) { return "Client[" + _clientId + "/" + requestId + "]: "; } protected String getPrefix(long requestId) { return "Client[" + _clientId + "/" + requestId + "]: "; }
@@ -63,6 +89,8 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
I2PTunnel tunnel) throws IllegalArgumentException { I2PTunnel tunnel) throws IllegalArgumentException {
super(localPort, ownDest, l, notifyThis, handlerName, tunnel); super(localPort, ownDest, l, notifyThis, handlerName, tunnel);
_proxyList = new ArrayList(4); _proxyList = new ArrayList(4);
_proxyNonce = new byte[PROXYNONCE_BYTES];
_context.random().nextBytes(_proxyNonce);
} }
/** /**
@@ -76,8 +104,12 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
throws IllegalArgumentException { throws IllegalArgumentException {
super(localPort, l, sktMgr, tunnel, notifyThis, clientId); super(localPort, l, sktMgr, tunnel, notifyThis, clientId);
_proxyList = new ArrayList(4); _proxyList = new ArrayList(4);
_proxyNonce = new byte[PROXYNONCE_BYTES];
_context.random().nextBytes(_proxyNonce);
} }
//////// Authorization stuff
/** all auth @since 0.8.2 */ /** all auth @since 0.8.2 */
public static final String PROP_AUTH = "proxyAuth"; public static final String PROP_AUTH = "proxyAuth";
public static final String PROP_USER = "proxyUsername"; public static final String PROP_USER = "proxyUsername";
@@ -90,23 +122,57 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
/** passwords for specific outproxies may be added with outproxyUsername.fooproxy.i2p=user and outproxyPassword.fooproxy.i2p=pw */ /** passwords for specific outproxies may be added with outproxyUsername.fooproxy.i2p=user and outproxyPassword.fooproxy.i2p=pw */
public static final String PROP_OUTPROXY_USER_PREFIX = PROP_OUTPROXY_USER + '.'; public static final String PROP_OUTPROXY_USER_PREFIX = PROP_OUTPROXY_USER + '.';
public static final String PROP_OUTPROXY_PW_PREFIX = PROP_OUTPROXY_PW + '.'; public static final String PROP_OUTPROXY_PW_PREFIX = PROP_OUTPROXY_PW + '.';
/** new style MD5 auth */
public static final String PROP_PROXY_DIGEST_PREFIX = "proxy.auth.";
public static final String PROP_PROXY_DIGEST_SUFFIX = ".md5";
public static final String BASIC_AUTH = "basic";
public static final String DIGEST_AUTH = "digest";
protected abstract String getRealm();
protected enum AuthResult {AUTH_BAD_REQ, AUTH_BAD, AUTH_STALE, AUTH_GOOD}
/** /**
* @param authorization may be null * @since 0.9.4
*/
protected boolean isDigestAuthRequired() {
String authRequired = getTunnel().getClientOptions().getProperty(PROP_AUTH);
if (authRequired == null)
return false;
return authRequired.toLowerCase(Locale.US).equals("digest");
}
/**
* Authorization
* Ref: RFC 2617
* If the socket is an InternalSocket, no auth required.
*
* @param method GET, POST, etc.
* @param authorization may be null, the full auth line e.g. "Basic lskjlksjf"
* @return success * @return success
*/ */
protected boolean authorize(Socket s, long requestId, String authorization) { protected AuthResult authorize(Socket s, long requestId, String method, String authorization) {
// Authorization
// Ref: RFC 2617
// If the socket is an InternalSocket, no auth required.
String authRequired = getTunnel().getClientOptions().getProperty(PROP_AUTH); String authRequired = getTunnel().getClientOptions().getProperty(PROP_AUTH);
if (Boolean.parseBoolean(authRequired) || if (authRequired == null)
(authRequired != null && "basic".equals(authRequired.toLowerCase(Locale.US)))) { return AuthResult.AUTH_GOOD;
authRequired = authRequired.toLowerCase(Locale.US);
if (authRequired.equals("false"))
return AuthResult.AUTH_GOOD;
if (s instanceof InternalSocket) { if (s instanceof InternalSocket) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info(getPrefix(requestId) + "Internal access, no auth required"); _log.info(getPrefix(requestId) + "Internal access, no auth required");
return true; return AuthResult.AUTH_GOOD;
} else if (authorization != null) { }
if (authorization == null)
return AuthResult.AUTH_BAD;
if (_log.shouldLog(Log.INFO))
_log.info(getPrefix(requestId) + "Auth: " + authorization);
String authLC = authorization.toLowerCase(Locale.US);
if (authRequired.equals("true") || authRequired.equals(BASIC_AUTH)) {
if (!authLC.startsWith("basic "))
return AuthResult.AUTH_BAD;
authorization = authorization.substring(6);
// hmm safeDecode(foo, true) to use standard alphabet is private in Base64 // hmm safeDecode(foo, true) to use standard alphabet is private in Base64
byte[] decoded = Base64.decode(authorization.replace("/", "~").replace("+", "=")); byte[] decoded = Base64.decode(authorization.replace("/", "~").replace("+", "="));
if (decoded != null) { if (decoded != null) {
@@ -128,30 +194,277 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
if (pw.equals(configPW)) { if (pw.equals(configPW)) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info(getPrefix(requestId) + "Good auth - user: " + user + " pw: " + pw); _log.info(getPrefix(requestId) + "Good auth - user: " + user + " pw: " + pw);
return true; return AuthResult.AUTH_GOOD;
} else {
if (_log.shouldLog(Log.WARN))
_log.warn(getPrefix(requestId) + "Bad auth, pw mismatch - user: " + user + " pw: " + pw + " expected: " + configPW);
} }
} else {
if (_log.shouldLog(Log.WARN))
_log.warn(getPrefix(requestId) + "Bad auth, no stored pw for user: " + user + " pw: " + pw);
} }
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
} catch (UnsupportedEncodingException uee) { } catch (UnsupportedEncodingException uee) {
_log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee); _log.error(getPrefix(requestId) + "No UTF-8 support? B64: " + authorization, uee);
} catch (ArrayIndexOutOfBoundsException aioobe) { } catch (ArrayIndexOutOfBoundsException aioobe) {
// no ':' in response // no ':' in response
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn(getPrefix(requestId) + "Bad auth B64: " + authorization, aioobe); _log.warn(getPrefix(requestId) + "Bad auth B64: " + authorization, aioobe);
return AuthResult.AUTH_BAD_REQ;
} }
return AuthResult.AUTH_BAD;
} else { } else {
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn(getPrefix(requestId) + "Bad auth B64: " + authorization); _log.warn(getPrefix(requestId) + "Bad auth B64: " + authorization);
return AuthResult.AUTH_BAD_REQ;
} }
} } else if (authRequired.equals(DIGEST_AUTH)) {
return false; if (!authLC.startsWith("digest "))
return AuthResult.AUTH_BAD;
authorization = authorization.substring(7);
Map<String, String> args = parseArgs(authorization);
AuthResult rv = validateDigest(method, args);
return rv;
} else { } else {
return true; _log.error("Unknown proxy authorization type configured: " + authRequired);
return AuthResult.AUTH_BAD_REQ;
} }
} }
/**
* Verify all of it.
* Ref: RFC 2617
* @since 0.9.4
*/
private AuthResult validateDigest(String method, Map<String, String> args) {
String user = args.get("username");
String realm = args.get("realm");
String nonce = args.get("nonce");
String qop = args.get("qop");
String uri = args.get("uri");
String cnonce = args.get("cnonce");
String nc = args.get("nc");
String response = args.get("response");
if (user == null || realm == null || nonce == null || qop == null ||
uri == null || cnonce == null || nc == null || response == null) {
if (_log.shouldLog(Log.INFO))
_log.info("Bad digest request: " + DataHelper.toString(args));
return AuthResult.AUTH_BAD_REQ;
}
// nonce check
AuthResult check = verifyNonce(nonce);
if (check != AuthResult.AUTH_GOOD) {
if (_log.shouldLog(Log.INFO))
_log.info("Bad digest nonce: " + check + ' ' + DataHelper.toString(args));
return check;
}
// get H(A1) == stored password
String ha1 = getTunnel().getClientOptions().getProperty(PROP_PROXY_DIGEST_PREFIX + user +
PROP_PROXY_DIGEST_SUFFIX);
if (ha1 == null) {
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
return AuthResult.AUTH_BAD;
}
// get H(A2)
String a2 = method + ':' + uri;
String ha2 = PasswordManager.md5Hex(a2);
// response check
String kd = ha1 + ':' + nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2;
String hkd = PasswordManager.md5Hex(kd);
if (!response.equals(hkd)) {
_log.logAlways(Log.WARN, "PROXY AUTH FAILURE: user " + user);
if (_log.shouldLog(Log.INFO))
_log.info("Bad digest auth: " + DataHelper.toString(args));
return AuthResult.AUTH_BAD;
}
if (_log.shouldLog(Log.INFO))
_log.info("Good digest auth - user: " + user);
return AuthResult.AUTH_GOOD;
}
/**
* The Base 64 of 24 bytes: (now, md5 of (now, proxy nonce))
* @since 0.9.4
*/
private String getNonce() {
byte[] b = new byte[DataHelper.DATE_LENGTH + PROXYNONCE_BYTES];
byte[] n = new byte[NONCE_BYTES];
long now = _context.clock().now();
DataHelper.toLong(b, 0, DataHelper.DATE_LENGTH, now);
System.arraycopy(_proxyNonce, 0, b, DataHelper.DATE_LENGTH, PROXYNONCE_BYTES);
System.arraycopy(b, 0, n, 0, DataHelper.DATE_LENGTH);
byte[] md5 = PasswordManager.md5Sum(b);
System.arraycopy(md5, 0, n, DataHelper.DATE_LENGTH, MD5_BYTES);
return Base64.encode(n);
}
/**
* Verify the Base 64 of 24 bytes: (now, md5 of (now, proxy nonce))
* @since 0.9.4
*/
private AuthResult verifyNonce(String b64) {
byte[] n = Base64.decode(b64);
if (n == null || n.length != NONCE_BYTES)
return AuthResult.AUTH_BAD;
long now = _context.clock().now();
long stamp = DataHelper.fromLong(n, 0, DataHelper.DATE_LENGTH);
if (now - stamp > MAX_NONCE_AGE)
return AuthResult.AUTH_STALE;
byte[] b = new byte[DataHelper.DATE_LENGTH + PROXYNONCE_BYTES];
System.arraycopy(n, 0, b, 0, DataHelper.DATE_LENGTH);
System.arraycopy(_proxyNonce, 0, b, DataHelper.DATE_LENGTH, PROXYNONCE_BYTES);
byte[] md5 = PasswordManager.md5Sum(b);
if (!DataHelper.eq(md5, 0, n, DataHelper.DATE_LENGTH, MD5_BYTES))
return AuthResult.AUTH_BAD;
return AuthResult.AUTH_GOOD;
}
/**
* What to send if digest auth fails
* @since 0.9.4
*/
protected String getAuthError(boolean isStale) {
boolean isDigest = isDigestAuthRequired();
return
ERR_AUTH1 +
(isDigest ? "Digest" : "Basic") +
" realm=\"" + getRealm() + '"' +
(isDigest ? ", nonce=\"" + getNonce() + "\"," +
" algorithm=MD5," +
" qop=\"auth\"" +
(isStale ? ", stale=true" : "")
: "") +
ERR_AUTH2;
}
/**
* Modified from LoadClientAppsJob.
* All keys are mapped to lower case.
* Ref: RFC 2617
*
* @param args non-null
* @since 0.9.4
*/
private static Map<String, String> parseArgs(String args) {
Map<String, String> rv = new HashMap(8);
char data[] = args.toCharArray();
StringBuilder buf = new StringBuilder(32);
boolean isQuoted = false;
String key = null;
for (int i = 0; i < data.length; i++) {
switch (data[i]) {
case '\"':
if (isQuoted) {
// keys never quoted
if (key != null) {
rv.put(key, buf.toString().trim());
key = null;
}
buf.setLength(0);
}
isQuoted = !isQuoted;
break;
case ' ':
case '\r':
case '\n':
case '\t':
case ',':
// whitespace - if we're in a quoted section, keep this as part of the quote,
// otherwise use it as a delim
if (isQuoted) {
buf.append(data[i]);
} else {
if (key != null) {
rv.put(key, buf.toString().trim());
key = null;
}
buf.setLength(0);
}
break;
case '=':
if (isQuoted) {
buf.append(data[i]);
} else {
key = buf.toString().trim().toLowerCase(Locale.US);
buf.setLength(0);
}
break;
default:
buf.append(data[i]);
break;
}
}
if (key != null)
rv.put(key, buf.toString().trim());
return rv;
}
//////// Error page stuff
/**
* foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht,
* or the backup byte array on fail.
*
* .ht files must be UTF-8 encoded and use \r\n terminators so the
* HTTP headers are conformant.
* We can't use FileUtil.readFile() because it strips \r
*
* @return non-null
* @since 0.9.4 moved from I2PTunnelHTTPClient
*/
protected byte[] getErrorPage(String base, byte[] backup) {
return getErrorPage(_context, base, backup);
}
/**
* foo => errordir/foo-header_xx.ht for lang xx, or errordir/foo-header.ht,
* or the backup byte array on fail.
*
* .ht files must be UTF-8 encoded and use \r\n terminators so the
* HTTP headers are conformant.
* We can't use FileUtil.readFile() because it strips \r
*
* @return non-null
* @since 0.9.4 moved from I2PTunnelHTTPClient
*/
protected static byte[] getErrorPage(I2PAppContext ctx, String base, byte[] backup) {
File errorDir = new File(ctx.getBaseDir(), "docs");
String lang = ctx.getProperty("routerconsole.lang", Locale.getDefault().getLanguage());
if(lang != null && lang.length() > 0 && !lang.equals("en")) {
File file = new File(errorDir, base + "-header_" + lang + ".ht");
try {
return readFile(file);
} catch(IOException ioe) {
// try the english version now
}
}
File file = new File(errorDir, base + "-header.ht");
try {
return readFile(file);
} catch(IOException ioe) {
return backup;
}
}
/**
* @since 0.9.4 moved from I2PTunnelHTTPClient
*/
private static byte[] readFile(File file) throws IOException {
FileInputStream fis = null;
byte[] buf = new byte[2048];
ByteArrayOutputStream baos = new ByteArrayOutputStream(2048);
try {
int len = 0;
fis = new FileInputStream(file);
while((len = fis.read(buf)) > 0) {
baos.write(buf, 0, len);
}
return baos.toByteArray();
} finally {
try {
if(fis != null) {
fis.close();
}
} catch(IOException foo) {
}
}
// we won't ever get here
}
} }

View File

@@ -12,6 +12,8 @@ import java.util.Properties;
import java.util.Set; import java.util.Set;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.app.*;
import static net.i2p.app.ClientAppState.*;
import net.i2p.client.I2PSession; import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException; import net.i2p.client.I2PSessionException;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
@@ -23,15 +25,20 @@ import net.i2p.util.OrderedProperties;
* Coordinate a set of tunnels within the JVM, loading and storing their config * Coordinate a set of tunnels within the JVM, loading and storing their config
* to disk, and building new ones as requested. * to disk, and building new ones as requested.
* *
* Warning - this is a singleton. Todo: fix * This is the entry point from clients.config.
*/ */
public class TunnelControllerGroup { public class TunnelControllerGroup implements ClientApp {
private Log _log; private final Log _log;
private static TunnelControllerGroup _instance; private volatile ClientAppState _state;
private final I2PAppContext _context;
private final ClientAppManager _mgr;
private static volatile TunnelControllerGroup _instance;
static final String DEFAULT_CONFIG_FILE = "i2ptunnel.config"; static final String DEFAULT_CONFIG_FILE = "i2ptunnel.config";
private final List<TunnelController> _controllers; private final List<TunnelController> _controllers;
private String _configFile = DEFAULT_CONFIG_FILE; private final String _configFile;
private static final String REGISTERED_NAME = "i2ptunnel";
/** /**
* Map of I2PSession to a Set of TunnelController objects * Map of I2PSession to a Set of TunnelController objects
@@ -41,48 +48,143 @@ public class TunnelControllerGroup {
*/ */
private final Map<I2PSession, Set<TunnelController>> _sessions; private final Map<I2PSession, Set<TunnelController>> _sessions;
/**
* In I2PAppContext will instantiate if necessary and always return non-null.
* As of 0.9.4, when in RouterContext, will return null
* if the TCG has not yet been started by the router.
*
* @throws IllegalArgumentException if unable to load from i2ptunnel.config
*/
public static TunnelControllerGroup getInstance() { public static TunnelControllerGroup getInstance() {
synchronized (TunnelControllerGroup.class) { synchronized (TunnelControllerGroup.class) {
if (_instance == null) if (_instance == null) {
_instance = new TunnelControllerGroup(DEFAULT_CONFIG_FILE); I2PAppContext ctx = I2PAppContext.getGlobalContext();
if (!ctx.isRouterContext()) {
_instance = new TunnelControllerGroup(ctx, null, null);
_instance.startup();
} // else wait for the router to start it
}
return _instance; return _instance;
} }
} }
private TunnelControllerGroup(String configFile) { /**
_log = I2PAppContext.getGlobalContext().logManager().getLog(TunnelControllerGroup.class); * Instantiation only. Caller must call startup().
_controllers = Collections.synchronizedList(new ArrayList()); * Config file problems will not throw exception until startup().
_configFile = configFile; *
* @param mgr may be null
* @param args one arg, the config file, if not absolute will be relative to the context's config dir,
* if empty or null, the default is i2ptunnel.config
* @since 0.9.4
*/
public TunnelControllerGroup(I2PAppContext context, ClientAppManager mgr, String[] args) {
_state = UNINITIALIZED;
_context = context;
_mgr = mgr;
_log = _context.logManager().getLog(TunnelControllerGroup.class);
_controllers = new ArrayList();
if (args == null || args.length <= 0)
_configFile = DEFAULT_CONFIG_FILE;
else if (args.length == 1)
_configFile = args[0];
else
throw new IllegalArgumentException("Usage: TunnelControllerGroup [filename]");
_sessions = new HashMap(4); _sessions = new HashMap(4);
loadControllers(_configFile); synchronized (TunnelControllerGroup.class) {
I2PAppContext.getGlobalContext().addShutdownTask(new Shutdown()); if (_instance == null)
_instance = this;
}
if (_instance != this) {
_log.logAlways(Log.WARN, "New TunnelControllerGroup, now you have two");
if (_log.shouldLog(Log.WARN))
_log.warn("I did it", new Exception());
}
_state = INITIALIZED;
} }
/**
* @param args one arg, the config file, if not absolute will be relative to the context's config dir,
* if no args, the default is i2ptunnel.config
* @throws IllegalArgumentException if unable to load from config from file
*/
public static void main(String args[]) { public static void main(String args[]) {
synchronized (TunnelControllerGroup.class) { synchronized (TunnelControllerGroup.class) {
if (_instance != null) return; // already loaded through the web if (_instance != null) return; // already loaded through the web
_instance = new TunnelControllerGroup(I2PAppContext.getGlobalContext(), null, args);
_instance.startup();
}
}
if ( (args == null) || (args.length <= 0) ) { /**
_instance = new TunnelControllerGroup(DEFAULT_CONFIG_FILE); * ClientApp interface
} else if (args.length == 1) { * @throws IllegalArgumentException if unable to load config from file
_instance = new TunnelControllerGroup(args[0]); * @since 0.9.4
} else { */
System.err.println("Usage: TunnelControllerGroup [filename]"); public void startup() {
return; loadControllers(_configFile);
if (_mgr != null)
_mgr.register(this);
_context.addShutdownTask(new Shutdown());
} }
/**
* ClientApp interface
* @since 0.9.4
*/
public ClientAppState getState() {
return _state;
} }
/**
* ClientApp interface
* @since 0.9.4
*/
public String getName() {
return REGISTERED_NAME;
}
/**
* ClientApp interface
* @since 0.9.4
*/
public String getDisplayName() {
return REGISTERED_NAME;
}
/**
* @since 0.9.4
*/
private void changeState(ClientAppState state) {
changeState(state, null);
}
/**
* @since 0.9.4
*/
private synchronized void changeState(ClientAppState state, Exception e) {
_state = state;
if (_mgr != null)
_mgr.notify(this, state, null, e);
} }
/** /**
* Warning - destroys the singleton! * Warning - destroys the singleton!
* @since 0.8.8 * @since 0.8.8
*/ */
private static class Shutdown implements Runnable { private class Shutdown implements Runnable {
public void run() { public void run() {
shutdown(); shutdown();
} }
} }
/**
* ClientApp interface
* @since 0.9.4
*/
public void shutdown(String[] args) {
shutdown();
}
/** /**
* Warning - destroys the singleton! * Warning - destroys the singleton!
* Caller must root a new context before calling instance() or main() again. * Caller must root a new context before calling instance() or main() again.
@@ -91,28 +193,31 @@ public class TunnelControllerGroup {
* *
* @since 0.8.8 * @since 0.8.8
*/ */
public static void shutdown() { public void shutdown() {
changeState(STOPPING);
if (_mgr != null)
_mgr.unregister(this);
unloadControllers();
synchronized (TunnelControllerGroup.class) { synchronized (TunnelControllerGroup.class) {
if (_instance == null) return; if (_instance == this)
_instance.unloadControllers();
_instance._log = null;
_instance = null; _instance = null;
} }
/// fixme static
I2PTunnelClientBase.killClientExecutor(); I2PTunnelClientBase.killClientExecutor();
changeState(STOPPED);
} }
/** /**
* Load up all of the tunnels configured in the given file (but do not start * Load up all of the tunnels configured in the given file (but do not start
* them) * them)
* *
* DEPRECATED for use outside this class. Use startup() or getInstance().
*
* @throws IllegalArgumentException if unable to load from file
*/ */
public void loadControllers(String configFile) { public synchronized void loadControllers(String configFile) {
changeState(STARTING);
Properties cfg = loadConfig(configFile); Properties cfg = loadConfig(configFile);
if (cfg == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to load the config from " + configFile);
return;
}
int i = 0; int i = 0;
while (true) { while (true) {
String type = cfg.getProperty("tunnel." + i + ".type"); String type = cfg.getProperty("tunnel." + i + ".type");
@@ -127,10 +232,12 @@ public class TunnelControllerGroup {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info(i + " controllers loaded from " + configFile); _log.info(i + " controllers loaded from " + configFile);
changeState(RUNNING);
} }
private class StartControllers implements Runnable { private class StartControllers implements Runnable {
public void run() { public void run() {
synchronized(TunnelControllerGroup.this) {
for (int i = 0; i < _controllers.size(); i++) { for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = _controllers.get(i); TunnelController controller = _controllers.get(i);
if (controller.getStartOnLoad()) if (controller.getStartOnLoad())
@@ -138,9 +245,15 @@ public class TunnelControllerGroup {
} }
} }
} }
}
/**
public void reloadControllers() { * Stop all tunnels, reload config, and restart those configured to do so.
* WARNING - Does NOT simply reload the configuration!!! This is probably not what you want.
*
* @throws IllegalArgumentException if unable to reload config file
*/
public synchronized void reloadControllers() {
unloadControllers(); unloadControllers();
loadControllers(_configFile); loadControllers(_configFile);
} }
@@ -150,7 +263,7 @@ public class TunnelControllerGroup {
* file or do other silly things) * file or do other silly things)
* *
*/ */
public void unloadControllers() { public synchronized void unloadControllers() {
stopAllControllers(); stopAllControllers();
_controllers.clear(); _controllers.clear();
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
@@ -162,14 +275,14 @@ public class TunnelControllerGroup {
* a config file or start it or anything) * a config file or start it or anything)
* *
*/ */
public void addController(TunnelController controller) { _controllers.add(controller); } public synchronized void addController(TunnelController controller) { _controllers.add(controller); }
/** /**
* Stop and remove the given tunnel * Stop and remove the given tunnel
* *
* @return list of messages from the controller as it is stopped * @return list of messages from the controller as it is stopped
*/ */
public List<String> removeController(TunnelController controller) { public synchronized List<String> removeController(TunnelController controller) {
if (controller == null) return new ArrayList(); if (controller == null) return new ArrayList();
controller.stopTunnel(); controller.stopTunnel();
List<String> msgs = controller.clearMessages(); List<String> msgs = controller.clearMessages();
@@ -183,7 +296,7 @@ public class TunnelControllerGroup {
* *
* @return list of messages the tunnels generate when stopped * @return list of messages the tunnels generate when stopped
*/ */
public List<String> stopAllControllers() { public synchronized List<String> stopAllControllers() {
List<String> msgs = new ArrayList(); List<String> msgs = new ArrayList();
for (int i = 0; i < _controllers.size(); i++) { for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = _controllers.get(i); TunnelController controller = _controllers.get(i);
@@ -200,7 +313,7 @@ public class TunnelControllerGroup {
* *
* @return list of messages the tunnels generate when started * @return list of messages the tunnels generate when started
*/ */
public List<String> startAllControllers() { public synchronized List<String> startAllControllers() {
List<String> msgs = new ArrayList(); List<String> msgs = new ArrayList();
for (int i = 0; i < _controllers.size(); i++) { for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = _controllers.get(i); TunnelController controller = _controllers.get(i);
@@ -218,7 +331,7 @@ public class TunnelControllerGroup {
* *
* @return list of messages the tunnels generate when restarted * @return list of messages the tunnels generate when restarted
*/ */
public List<String> restartAllControllers() { public synchronized List<String> restartAllControllers() {
List<String> msgs = new ArrayList(); List<String> msgs = new ArrayList();
for (int i = 0; i < _controllers.size(); i++) { for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = _controllers.get(i); TunnelController controller = _controllers.get(i);
@@ -235,7 +348,7 @@ public class TunnelControllerGroup {
* *
* @return list of messages the tunnels have generated * @return list of messages the tunnels have generated
*/ */
public List<String> clearAllMessages() { public synchronized List<String> clearAllMessages() {
List<String> msgs = new ArrayList(); List<String> msgs = new ArrayList();
for (int i = 0; i < _controllers.size(); i++) { for (int i = 0; i < _controllers.size(); i++) {
TunnelController controller = _controllers.get(i); TunnelController controller = _controllers.get(i);
@@ -257,8 +370,7 @@ public class TunnelControllerGroup {
* Save the configuration of all known tunnels to the given file * Save the configuration of all known tunnels to the given file
* *
*/ */
public void saveConfig(String configFile) throws IOException { public synchronized void saveConfig(String configFile) throws IOException {
_configFile = configFile;
File cfgFile = new File(configFile); File cfgFile = new File(configFile);
if (!cfgFile.isAbsolute()) if (!cfgFile.isAbsolute())
cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile); cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile);
@@ -279,16 +391,17 @@ public class TunnelControllerGroup {
/** /**
* Load up the config data from the file * Load up the config data from the file
* *
* @return properties loaded or null if there was an error * @return properties loaded
* @throws IllegalArgumentException if unable to load from file
*/ */
private Properties loadConfig(String configFile) { private synchronized Properties loadConfig(String configFile) {
File cfgFile = new File(configFile); File cfgFile = new File(configFile);
if (!cfgFile.isAbsolute()) if (!cfgFile.isAbsolute())
cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile); cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile);
if (!cfgFile.exists()) { if (!cfgFile.exists()) {
if (_log.shouldLog(Log.ERROR)) if (_log.shouldLog(Log.ERROR))
_log.error("Unable to load the controllers from " + cfgFile.getAbsolutePath()); _log.error("Unable to load the controllers from " + cfgFile.getAbsolutePath());
return null; throw new IllegalArgumentException("Unable to load the controllers from " + cfgFile.getAbsolutePath());
} }
Properties props = new Properties(); Properties props = new Properties();
@@ -298,7 +411,7 @@ public class TunnelControllerGroup {
} catch (IOException ioe) { } catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR)) if (_log.shouldLog(Log.ERROR))
_log.error("Error reading the controllers from " + cfgFile.getAbsolutePath(), ioe); _log.error("Error reading the controllers from " + cfgFile.getAbsolutePath(), ioe);
return null; throw new IllegalArgumentException("Error reading the controllers from " + cfgFile.getAbsolutePath(), ioe);
} }
} }
@@ -307,7 +420,9 @@ public class TunnelControllerGroup {
* *
* @return list of TunnelController objects * @return list of TunnelController objects
*/ */
public List<TunnelController> getControllers() { return _controllers; } public synchronized List<TunnelController> getControllers() {
return new ArrayList(_controllers);
}
/** /**

View File

@@ -29,8 +29,8 @@ import net.i2p.util.Addresses;
/** /**
* Ugly little accessor for the edit page * Ugly little accessor for the edit page
* *
* Warning - This class is not part of the i2ptunnel API, and at some point * Warning - This class is not part of the i2ptunnel API,
* it will be moved from the jar to the war. * it has been moved from the jar to the war.
* Usage by classes outside of i2ptunnel.war is deprecated. * Usage by classes outside of i2ptunnel.war is deprecated.
*/ */
public class EditBean extends IndexBean { public class EditBean extends IndexBean {
@@ -38,6 +38,8 @@ public class EditBean extends IndexBean {
public static boolean staticIsClient(int tunnel) { public static boolean staticIsClient(int tunnel) {
TunnelControllerGroup group = TunnelControllerGroup.getInstance(); TunnelControllerGroup group = TunnelControllerGroup.getInstance();
if (group == null)
return false;
List controllers = group.getControllers(); List controllers = group.getControllers();
if (controllers.size() > tunnel) { if (controllers.size() > tunnel) {
TunnelController cur = (TunnelController)controllers.get(tunnel); TunnelController cur = (TunnelController)controllers.get(tunnel);
@@ -55,6 +57,7 @@ public class EditBean extends IndexBean {
else else
return "127.0.0.1"; return "127.0.0.1";
} }
public String getTargetPort(int tunnel) { public String getTargetPort(int tunnel) {
TunnelController tun = getController(tunnel); TunnelController tun = getController(tunnel);
if (tun != null && tun.getTargetPort() != null) if (tun != null && tun.getTargetPort() != null)
@@ -62,6 +65,7 @@ public class EditBean extends IndexBean {
else else
return ""; return "";
} }
public String getSpoofedHost(int tunnel) { public String getSpoofedHost(int tunnel) {
TunnelController tun = getController(tunnel); TunnelController tun = getController(tunnel);
if (tun != null && tun.getSpoofedHost() != null) if (tun != null && tun.getSpoofedHost() != null)
@@ -69,12 +73,13 @@ public class EditBean extends IndexBean {
else else
return ""; return "";
} }
public String getPrivateKeyFile(int tunnel) { public String getPrivateKeyFile(int tunnel) {
TunnelController tun = getController(tunnel); TunnelController tun = getController(tunnel);
if (tun != null && tun.getPrivKeyFile() != null) if (tun != null && tun.getPrivKeyFile() != null)
return tun.getPrivKeyFile(); return tun.getPrivKeyFile();
if (tunnel < 0) if (tunnel < 0)
tunnel = _group.getControllers().size(); tunnel = _group == null ? 1 : _group.getControllers().size() + 1;
return "i2ptunnel" + tunnel + "-privKeys.dat"; return "i2ptunnel" + tunnel + "-privKeys.dat";
} }
@@ -221,19 +226,7 @@ public class EditBean extends IndexBean {
/** all proxy auth @since 0.8.2 */ /** all proxy auth @since 0.8.2 */
public boolean getProxyAuth(int tunnel) { public boolean getProxyAuth(int tunnel) {
return getBooleanProperty(tunnel, I2PTunnelHTTPClientBase.PROP_AUTH) && return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_AUTH, "false") != "false";
getProxyUsername(tunnel).length() > 0 &&
getProxyPassword(tunnel).length() > 0;
}
public String getProxyUsername(int tunnel) {
return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_USER, "");
}
public String getProxyPassword(int tunnel) {
if (getProxyUsername(tunnel).length() <= 0)
return "";
return getProperty(tunnel, I2PTunnelHTTPClientBase.PROP_PW, "");
} }
public boolean getOutproxyAuth(int tunnel) { public boolean getOutproxyAuth(int tunnel) {
@@ -354,10 +347,17 @@ public class EditBean extends IndexBean {
if (opts == null) return ""; if (opts == null) return "";
StringBuilder buf = new StringBuilder(64); StringBuilder buf = new StringBuilder(64);
int i = 0; int i = 0;
boolean isMD5Proxy = "httpclient".equals(tun.getType()) ||
"connectclient".equals(tun.getType());
for (Iterator iter = opts.keySet().iterator(); iter.hasNext(); ) { for (Iterator iter = opts.keySet().iterator(); iter.hasNext(); ) {
String key = (String)iter.next(); String key = (String)iter.next();
if (_noShowSet.contains(key)) if (_noShowSet.contains(key))
continue; continue;
// leave in for HTTP and Connect so it can get migrated to MD5
// hide for SOCKS until migrated to MD5
if ((!isMD5Proxy) &&
_nonProxyNoShowSet.contains(key))
continue;
String val = opts.getProperty(key); String val = opts.getProperty(key);
if (i != 0) buf.append(' '); if (i != 0) buf.append(' ');
buf.append(key).append('=').append(val); buf.append(key).append('=').append(val);

View File

@@ -27,6 +27,7 @@ import net.i2p.data.Certificate;
import net.i2p.data.Destination; import net.i2p.data.Destination;
import net.i2p.data.PrivateKeyFile; import net.i2p.data.PrivateKeyFile;
import net.i2p.data.SessionKey; import net.i2p.data.SessionKey;
import net.i2p.i2ptunnel.I2PTunnelConnectClient;
import net.i2p.i2ptunnel.I2PTunnelHTTPClient; import net.i2p.i2ptunnel.I2PTunnelHTTPClient;
import net.i2p.i2ptunnel.I2PTunnelHTTPClientBase; import net.i2p.i2ptunnel.I2PTunnelHTTPClientBase;
import net.i2p.i2ptunnel.I2PTunnelIRCClient; import net.i2p.i2ptunnel.I2PTunnelIRCClient;
@@ -36,18 +37,20 @@ import net.i2p.util.Addresses;
import net.i2p.util.ConcurrentHashSet; import net.i2p.util.ConcurrentHashSet;
import net.i2p.util.FileUtil; import net.i2p.util.FileUtil;
import net.i2p.util.Log; import net.i2p.util.Log;
import net.i2p.util.PasswordManager;
/** /**
* Simple accessor for exposing tunnel info, but also an ugly form handler * Simple accessor for exposing tunnel info, but also an ugly form handler
* *
* Warning - This class is not part of the i2ptunnel API, and at some point * Warning - This class is not part of the i2ptunnel API,
* it will be moved from the jar to the war. * it has been moved from the jar to the war.
* Usage by classes outside of i2ptunnel.war is deprecated. * Usage by classes outside of i2ptunnel.war is deprecated.
*/ */
public class IndexBean { public class IndexBean {
protected final I2PAppContext _context; protected final I2PAppContext _context;
protected final Log _log; protected final Log _log;
protected final TunnelControllerGroup _group; protected final TunnelControllerGroup _group;
private final String _fatalError;
private String _action; private String _action;
private int _tunnel; private int _tunnel;
//private long _prevNonce; //private long _prevNonce;
@@ -83,15 +86,14 @@ public class IndexBean {
private int _hashCashValue; private int _hashCashValue;
private int _certType; private int _certType;
private String _certSigner; private String _certSigner;
private String _newProxyUser;
private String _newProxyPW;
public static final int RUNNING = 1; public static final int RUNNING = 1;
public static final int STARTING = 2; public static final int STARTING = 2;
public static final int NOT_RUNNING = 3; public static final int NOT_RUNNING = 3;
public static final int STANDBY = 4; public static final int STANDBY = 4;
/** deprecated unimplemented, now using routerconsole realm */
//public static final String PROP_TUNNEL_PASSPHRASE = "i2ptunnel.passphrase";
public static final String PROP_TUNNEL_PASSPHRASE = "consolePassword";
//static final String PROP_NONCE = IndexBean.class.getName() + ".nonce"; //static final String PROP_NONCE = IndexBean.class.getName() + ".nonce";
//static final String PROP_NONCE_OLD = PROP_NONCE + '2'; //static final String PROP_NONCE_OLD = PROP_NONCE + '2';
/** 3 wasn't enough for some browsers. They are reloading the page for some reason - maybe HEAD? @since 0.8.1 */ /** 3 wasn't enough for some browsers. They are reloading the page for some reason - maybe HEAD? @since 0.8.1 */
@@ -104,11 +106,23 @@ public class IndexBean {
public static final String DEFAULT_THEME = "light"; public static final String DEFAULT_THEME = "light";
public static final String PROP_CSS_DISABLED = "routerconsole.css.disabled"; public static final String PROP_CSS_DISABLED = "routerconsole.css.disabled";
public static final String PROP_JS_DISABLED = "routerconsole.javascript.disabled"; public static final String PROP_JS_DISABLED = "routerconsole.javascript.disabled";
private static final String PROP_PW_ENABLE = "routerconsole.auth.enable";
public IndexBean() { public IndexBean() {
_context = I2PAppContext.getGlobalContext(); _context = I2PAppContext.getGlobalContext();
_log = _context.logManager().getLog(IndexBean.class); _log = _context.logManager().getLog(IndexBean.class);
_group = TunnelControllerGroup.getInstance(); TunnelControllerGroup tcg;
String error;
try {
tcg = TunnelControllerGroup.getInstance();
error = tcg == null ? _("Tunnels are not initialized yet, please reload in two minutes.")
: null;
} catch (IllegalArgumentException iae) {
tcg = null;
error = iae.toString();
}
_group = tcg;
_fatalError = error;
_tunnel = -1; _tunnel = -1;
_curNonce = "-1"; _curNonce = "-1";
addNonce(); addNonce();
@@ -116,6 +130,13 @@ public class IndexBean {
_otherOptions = new ConcurrentHashMap(4); _otherOptions = new ConcurrentHashMap(4);
} }
/**
* @since 0.9.4
*/
public boolean isInitialized() {
return _group != null;
}
public static String getNextNonce() { public static String getNextNonce() {
synchronized (_nonces) { synchronized (_nonces) {
return _nonces.get(0); return _nonces.get(0);
@@ -145,14 +166,11 @@ public class IndexBean {
} }
} }
/** deprecated unimplemented, now using routerconsole realm */
public void setPassphrase(String phrase) {
}
public void setAction(String action) { public void setAction(String action) {
if ( (action == null) || (action.trim().length() <= 0) ) return; if ( (action == null) || (action.trim().length() <= 0) ) return;
_action = action; _action = action;
} }
public void setTunnel(String tunnel) { public void setTunnel(String tunnel) {
if ( (tunnel == null) || (tunnel.trim().length() <= 0) ) return; if ( (tunnel == null) || (tunnel.trim().length() <= 0) ) return;
try { try {
@@ -162,17 +180,17 @@ public class IndexBean {
} }
} }
/** just check if console password option is set, jetty will do auth */
private boolean validPassphrase() {
String pass = _context.getProperty(PROP_TUNNEL_PASSPHRASE);
return pass != null && pass.trim().length() > 0;
}
private String processAction() { private String processAction() {
if ( (_action == null) || (_action.trim().length() <= 0) || ("Cancel".equals(_action))) if ( (_action == null) || (_action.trim().length() <= 0) || ("Cancel".equals(_action)))
return ""; return "";
if ( (!haveNonce(_curNonce)) && (!validPassphrase()) ) if (_group == null)
return _("Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit."); return "Error - tunnels are not initialized yet";
// If passwords are turned on, all is assumed good
if (!_context.getBooleanProperty(PROP_PW_ENABLE) &&
!haveNonce(_curNonce))
return _("Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.")
+ ' ' +
_("If the problem persists, verify that you have cookies enabled in your browser.");
if ("Stop all".equals(_action)) if ("Stop all".equals(_action))
return stopAll(); return stopAll();
else if ("Start all".equals(_action)) else if ("Start all".equals(_action))
@@ -200,33 +218,33 @@ public class IndexBean {
else else
return "Action " + _action + " unknown"; return "Action " + _action + " unknown";
} }
private String stopAll() { private String stopAll() {
if (_group == null) return "";
List<String> msgs = _group.stopAllControllers(); List<String> msgs = _group.stopAllControllers();
return getMessages(msgs); return getMessages(msgs);
} }
private String startAll() { private String startAll() {
if (_group == null) return "";
List<String> msgs = _group.startAllControllers(); List<String> msgs = _group.startAllControllers();
return getMessages(msgs); return getMessages(msgs);
} }
private String restartAll() { private String restartAll() {
if (_group == null) return "";
List<String> msgs = _group.restartAllControllers(); List<String> msgs = _group.restartAllControllers();
return getMessages(msgs); return getMessages(msgs);
} }
private String reloadConfig() {
if (_group == null) return "";
private String reloadConfig() {
_group.reloadControllers(); _group.reloadControllers();
return _("Configuration reloaded for all tunnels"); return _("Configuration reloaded for all tunnels");
} }
private String start() { private String start() {
if (_tunnel < 0) return "Invalid tunnel"; if (_tunnel < 0) return "Invalid tunnel";
List controllers = _group.getControllers(); List<TunnelController> controllers = _group.getControllers();
if (_tunnel >= controllers.size()) return "Invalid tunnel"; if (_tunnel >= controllers.size()) return "Invalid tunnel";
TunnelController controller = (TunnelController)controllers.get(_tunnel); TunnelController controller = controllers.get(_tunnel);
controller.startTunnelBackground(); controller.startTunnelBackground();
// give the messages a chance to make it to the window // give the messages a chance to make it to the window
try { Thread.sleep(1000); } catch (InterruptedException ie) {} try { Thread.sleep(1000); } catch (InterruptedException ie) {}
@@ -237,9 +255,9 @@ public class IndexBean {
private String stop() { private String stop() {
if (_tunnel < 0) return "Invalid tunnel"; if (_tunnel < 0) return "Invalid tunnel";
List controllers = _group.getControllers(); List<TunnelController> controllers = _group.getControllers();
if (_tunnel >= controllers.size()) return "Invalid tunnel"; if (_tunnel >= controllers.size()) return "Invalid tunnel";
TunnelController controller = (TunnelController)controllers.get(_tunnel); TunnelController controller = controllers.get(_tunnel);
controller.stopTunnel(); controller.stopTunnel();
// give the messages a chance to make it to the window // give the messages a chance to make it to the window
try { Thread.sleep(1000); } catch (InterruptedException ie) {} try { Thread.sleep(1000); } catch (InterruptedException ie) {}
@@ -268,10 +286,10 @@ public class IndexBean {
// if the current tunnel is shared, and of supported type // if the current tunnel is shared, and of supported type
if (Boolean.parseBoolean(cur.getSharedClient()) && isClient(cur.getType())) { if (Boolean.parseBoolean(cur.getSharedClient()) && isClient(cur.getType())) {
// all clients use the same I2CP session, and as such, use the same I2CP options // all clients use the same I2CP session, and as such, use the same I2CP options
List controllers = _group.getControllers(); List<TunnelController> controllers = _group.getControllers();
for (int i = 0; i < controllers.size(); i++) { for (int i = 0; i < controllers.size(); i++) {
TunnelController c = (TunnelController)controllers.get(i); TunnelController c = controllers.get(i);
// Current tunnel modified by user, skip // Current tunnel modified by user, skip
if (c == cur) continue; if (c == cur) continue;
@@ -375,7 +393,7 @@ public class IndexBean {
*/ */
public String getMessages() { public String getMessages() {
if (_group == null) if (_group == null)
return ""; return _fatalError;
StringBuilder buf = new StringBuilder(512); StringBuilder buf = new StringBuilder(512);
if (_action != null) { if (_action != null) {
@@ -804,21 +822,22 @@ public class IndexBean {
/** all proxy auth @since 0.8.2 */ /** all proxy auth @since 0.8.2 */
public void setProxyAuth(String s) { public void setProxyAuth(String s) {
_booleanOptions.add(I2PTunnelHTTPClientBase.PROP_AUTH); if (s != null)
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_AUTH, I2PTunnelHTTPClientBase.DIGEST_AUTH);
} }
public void setProxyUsername(String s) { public void setProxyUsername(String s) {
if (s != null) if (s != null)
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_USER, s.trim()); _newProxyUser = s.trim();
} }
public void setProxyPassword(String s) { public void setProxyPassword(String s) {
if (s != null) if (s != null)
_otherOptions.put(I2PTunnelHTTPClientBase.PROP_PW, s.trim()); _newProxyPW = s.trim();
} }
public void setOutproxyAuth(String s) { public void setOutproxyAuth(String s) {
_booleanOptions.add(I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH); _otherOptions.put(I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH, I2PTunnelHTTPClientBase.DIGEST_AUTH);
} }
public void setOutproxyUsername(String s) { public void setOutproxyUsername(String s) {
@@ -1040,6 +1059,45 @@ public class IndexBean {
config.setProperty("proxyList", _proxyList); config.setProperty("proxyList", _proxyList);
} }
// Proxy auth including migration to MD5
if ("httpclient".equals(_type) || "connectclient".equals(_type)) {
// Migrate even if auth is disabled
// go get the old from custom options that updateConfigGeneric() put in there
String puser = "option." + I2PTunnelHTTPClientBase.PROP_USER;
String user = config.getProperty(puser);
String ppw = "option." + I2PTunnelHTTPClientBase.PROP_PW;
String pw = config.getProperty(ppw);
if (user != null && pw != null && user.length() > 0 && pw.length() > 0) {
String pmd5 = "option." + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_PREFIX +
user + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_SUFFIX;
if (config.getProperty(pmd5) == null) {
// not in there, migrate
String realm = _type.equals("httpclient") ? I2PTunnelHTTPClient.AUTH_REALM
: I2PTunnelConnectClient.AUTH_REALM;
String hex = PasswordManager.md5Hex(realm, user, pw);
if (hex != null) {
config.setProperty(pmd5, hex);
config.remove(puser);
config.remove(ppw);
}
}
}
// New user/password
String auth = _otherOptions.get(I2PTunnelHTTPClientBase.PROP_AUTH);
if (auth != null && !auth.equals("false")) {
if (_newProxyUser != null && _newProxyPW != null &&
_newProxyUser.length() > 0 && _newProxyPW.length() > 0) {
String pmd5 = "option." + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_PREFIX +
_newProxyUser + I2PTunnelHTTPClientBase.PROP_PROXY_DIGEST_SUFFIX;
String realm = _type.equals("httpclient") ? I2PTunnelHTTPClient.AUTH_REALM
: I2PTunnelConnectClient.AUTH_REALM;
String hex = PasswordManager.md5Hex(realm, _newProxyUser, _newProxyPW);
if (hex != null)
config.setProperty(pmd5, hex);
}
}
}
if ("ircclient".equals(_type) || "client".equals(_type) || "streamrclient".equals(_type)) { if ("ircclient".equals(_type) || "client".equals(_type) || "streamrclient".equals(_type)) {
if (_targetDestination != null) if (_targetDestination != null)
config.setProperty("targetDestination", _targetDestination); config.setProperty("targetDestination", _targetDestination);
@@ -1084,15 +1142,16 @@ public class IndexBean {
"i2cp.reduceOnIdle", "i2cp.closeOnIdle", "i2cp.newDestOnResume", "persistentClientKey", "i2cp.delayOpen" "i2cp.reduceOnIdle", "i2cp.closeOnIdle", "i2cp.newDestOnResume", "persistentClientKey", "i2cp.delayOpen"
}; };
private static final String _booleanProxyOpts[] = { private static final String _booleanProxyOpts[] = {
I2PTunnelHTTPClientBase.PROP_AUTH, I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH I2PTunnelHTTPClientBase.PROP_OUTPROXY_AUTH
}; };
private static final String _booleanServerOpts[] = { private static final String _booleanServerOpts[] = {
"i2cp.reduceOnIdle", "i2cp.encryptLeaseSet", PROP_ENABLE_ACCESS_LIST, PROP_ENABLE_BLACKLIST "i2cp.reduceOnIdle", "i2cp.encryptLeaseSet", PROP_ENABLE_ACCESS_LIST, PROP_ENABLE_BLACKLIST
}; };
private static final String _otherClientOpts[] = { private static final String _otherClientOpts[] = {
"i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.closeIdleTime", "i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.closeIdleTime",
"proxyUsername", "proxyPassword", "outproxyUsername", "outproxyPassword", "outproxyUsername", "outproxyPassword",
I2PTunnelHTTPClient.PROP_JUMP_SERVERS I2PTunnelHTTPClient.PROP_JUMP_SERVERS,
I2PTunnelHTTPClientBase.PROP_AUTH
}; };
private static final String _otherServerOpts[] = { private static final String _otherServerOpts[] = {
"i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.leaseSetKey", "i2cp.accessList", "i2cp.reduceIdleTime", "i2cp.reduceQuantity", "i2cp.leaseSetKey", "i2cp.accessList",
@@ -1101,7 +1160,17 @@ public class IndexBean {
PROP_MAX_STREAMS PROP_MAX_STREAMS
}; };
/**
* do NOT add these to noShoOpts, we must leave them in for HTTPClient and ConnectCLient
* so they will get migrated to MD5
* TODO migrate socks to MD5
*/
private static final String _otherProxyOpts[] = {
"proxyUsername", "proxyPassword"
};
protected static final Set _noShowSet = new HashSet(64); protected static final Set _noShowSet = new HashSet(64);
protected static final Set _nonProxyNoShowSet = new HashSet(4);
static { static {
_noShowSet.addAll(Arrays.asList(_noShowOpts)); _noShowSet.addAll(Arrays.asList(_noShowOpts));
_noShowSet.addAll(Arrays.asList(_booleanClientOpts)); _noShowSet.addAll(Arrays.asList(_booleanClientOpts));
@@ -1109,6 +1178,7 @@ public class IndexBean {
_noShowSet.addAll(Arrays.asList(_booleanServerOpts)); _noShowSet.addAll(Arrays.asList(_booleanServerOpts));
_noShowSet.addAll(Arrays.asList(_otherClientOpts)); _noShowSet.addAll(Arrays.asList(_otherClientOpts));
_noShowSet.addAll(Arrays.asList(_otherServerOpts)); _noShowSet.addAll(Arrays.asList(_otherServerOpts));
_nonProxyNoShowSet.addAll(Arrays.asList(_otherProxyOpts));
} }
private void updateConfigGeneric(Properties config) { private void updateConfigGeneric(Properties config) {
@@ -1139,6 +1209,12 @@ public class IndexBean {
String key = pair.substring(0, eq); String key = pair.substring(0, eq);
if (_noShowSet.contains(key)) if (_noShowSet.contains(key))
continue; continue;
// leave in for HTTP and Connect so it can get migrated to MD5
// hide for SOCKS until migrated to MD5
if ((!"httpclient".equals(_type)) &&
(! "connectclient".equals(_type)) &&
_nonProxyNoShowSet.contains(key))
continue;
String val = pair.substring(eq+1); String val = pair.substring(eq+1);
config.setProperty("option." + key, val); config.setProperty("option." + key, val);
} }
@@ -1190,9 +1266,9 @@ public class IndexBean {
protected TunnelController getController(int tunnel) { protected TunnelController getController(int tunnel) {
if (tunnel < 0) return null; if (tunnel < 0) return null;
if (_group == null) return null; if (_group == null) return null;
List controllers = _group.getControllers(); List<TunnelController> controllers = _group.getControllers();
if (controllers.size() > tunnel) if (controllers.size() > tunnel)
return (TunnelController)controllers.get(tunnel); return controllers.get(tunnel);
else else
return null; return null;
} }

View File

@@ -31,7 +31,11 @@
<body id="tunnelEditPage"> <body id="tunnelEditPage">
<div id="pageHeader"> <div id="pageHeader">
</div> </div>
<%
if (editBean.isInitialized()) {
%>
<form method="post" action="list"> <form method="post" action="list">
<div id="tunnelEditPanel" class="panel"> <div id="tunnelEditPanel" class="panel">
@@ -435,13 +439,13 @@
<label> <label>
<%=intl._("Username")%>: <%=intl._("Username")%>:
</label> </label>
<input type="text" id="clientPort" name="proxyUsername" title="Set username for this service" value="<%=editBean.getProxyUsername(curTunnel)%>" class="freetext" /> <input type="text" id="clientPort" name="proxyUsername" title="Set username for this service" value="" class="freetext" />
</div> </div>
<div id="portField" class="rowItem"> <div id="portField" class="rowItem">
<label> <label>
<%=intl._("Password")%>: <%=intl._("Password")%>:
</label> </label>
<input type="password" id="clientPort" name="proxyPassword" title="Set password for this service" value="<%=editBean.getProxyPassword(curTunnel)%>" class="freetext" /> <input type="password" id="clientPort" name="proxyPassword" title="Set password for this service" value="" class="freetext" />
</div> </div>
<div class="subdivider"> <div class="subdivider">
<hr /> <hr />
@@ -508,5 +512,12 @@
</form> </form>
<div id="pageFooter"> <div id="pageFooter">
</div> </div>
<%
} else {
%>Tunnels are not initialized yet, please reload in two minutes.<%
} // isInitialized()
%>
</body> </body>
</html> </html>

View File

@@ -31,7 +31,11 @@
<body id="tunnelEditPage"> <body id="tunnelEditPage">
<div id="pageHeader"> <div id="pageHeader">
</div> </div>
<%
if (editBean.isInitialized()) {
%>
<form method="post" action="list"> <form method="post" action="list">
<div id="tunnelEditPanel" class="panel"> <div id="tunnelEditPanel" class="panel">
@@ -518,5 +522,12 @@
</form> </form>
<div id="pageFooter"> <div id="pageFooter">
</div> </div>
<%
} else {
%>Tunnels are not initialized yet, please reload in two minutes.<%
} // isInitialized()
%>
</body> </body>
</html> </html>

View File

@@ -55,12 +55,23 @@
</div> </div>
</div> </div>
</div> </div>
<%
if (indexBean.isInitialized()) {
%>
<div id="globalOperationsPanel" class="panel"> <div id="globalOperationsPanel" class="panel">
<div class="header"></div> <div class="header"></div>
<div class="footer"> <div class="footer">
<div class="toolbox"> <div class="toolbox">
<a class="control" href="wizard"><%=intl._("Tunnel Wizard")%></a> <a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&amp;action=Stop%20all"><%=intl._("Stop All")%></a> <a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&amp;action=Start%20all"><%=intl._("Start All")%></a> <a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&amp;action=Restart%20all"><%=intl._("Restart All")%></a> <a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&amp;action=Reload%20configuration"><%=intl._("Reload Config")%></a> <a class="control" href="wizard"><%=intl._("Tunnel Wizard")%></a>
<a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&amp;action=Stop%20all"><%=intl._("Stop All")%></a>
<a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&amp;action=Start%20all"><%=intl._("Start All")%></a>
<a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&amp;action=Restart%20all"><%=intl._("Restart All")%></a>
<%--
//this is really bad because it stops and restarts all tunnels, which is probably not what you want
<a class="control" href="list?nonce=<%=indexBean.getNextNonce()%>&amp;action=Reload%20configuration"><%=intl._("Reload Config")%></a>
--%>
</div> </div>
</div> </div>
</div> </div>
@@ -285,7 +296,9 @@
</label> </label>
<div class="text"> <div class="text">
<% String cdest = indexBean.getClientDestination(curClient); <% String cdest = indexBean.getClientDestination(curClient);
if (cdest.length() > 0) { if (cdest.length() > 70) { // Probably a B64 (a B32 is 60 chars) so truncate
%><%=cdest.substring(0, 45)%>&hellip;<%=cdest.substring(cdest.length() - 15, cdest.length())%><%
} else if (cdest.length() > 0) {
%><%=cdest%><% %><%=cdest%><%
} else { } else {
%><i><%=intl._("none")%></i><% %><i><%=intl._("none")%></i><%
@@ -327,6 +340,11 @@
</form> </form>
</div> </div>
</div> </div>
<%
} // isInitialized()
%>
<div id="pageFooter"> <div id="pageFooter">
</div> </div>
</body> </body>

View File

@@ -6,6 +6,7 @@
# Translators: # Translators:
# "blabla", 2011. # "blabla", 2011.
# <blabla@trash-mail.com>, 2011, 2012. # <blabla@trash-mail.com>, 2011, 2012.
# Daniel Mustieles <daniel.mustieles@gmail.com>, 2012.
# ducki2p <ducki2p@gmail.com>, 2011. # ducki2p <ducki2p@gmail.com>, 2011.
# foo <foo@bar>, 2009. # foo <foo@bar>, 2009.
# <punkibastardo@gmail.com>, 2011, 2012. # <punkibastardo@gmail.com>, 2011, 2012.
@@ -13,17 +14,16 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: I2P\n" "Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
"POT-Creation-Date: 2012-07-26 19:45+0000\n" "POT-Creation-Date: 2012-10-12 00:38+0000\n"
"PO-Revision-Date: 2012-07-21 19:52+0000\n" "PO-Revision-Date: 2012-10-18 08:55+0000\n"
"Last-Translator: blabla <blabla@trash-mail.com>\n" "Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: Spanish (http://www.transifex.com/projects/p/I2P/language/" "Language-Team: Spanish (http://www.transifex.com/projects/p/I2P/language/es/)\n"
"es/)\n"
"Language: es\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n" "Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:554 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:554
msgid "This seems to be a bad destination:" msgid "This seems to be a bad destination:"
@@ -36,13 +36,10 @@ msgstr "El ayudante de direcciones no te puede ayudar con un destino así."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:621 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:621
#, java-format #, java-format
msgid "" msgid ""
"To visit the destination in your host database, click <a href=\"{0}\">here</" "To visit the destination in your host database, click <a "
"a>. To visit the conflicting addresshelper destination, click <a href=" "href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, "
"\"{1}\">here</a>." "click <a href=\"{1}\">here</a>."
msgstr "" msgstr "Para visitar el destino en la base de datos de hosts, ¡pincha <a href=\"{0}\">aquí</a>! Para visitar el destino del ayudante de direcciones en conflicto, ¡pincha <a href=\"{1}\">aquí</a>!"
"Para visitar el destino en la base de datos de hosts, ¡pincha <a href="
"\"{0}\">aquí</a>! Para visitar el destino del ayudante de direcciones en "
"conflicto, ¡pincha <a href=\"{1}\">aquí</a>!"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1023 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1023
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:403 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:403
@@ -57,7 +54,7 @@ msgid "Base 32"
msgstr "Base 32" msgstr "Base 32"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1031 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1031
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:380 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:374
msgid "Destination" msgid "Destination"
msgstr "Destino" msgstr "Destino"
@@ -69,21 +66,18 @@ msgstr "Acceder a {0} sin guardar"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1042 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1042
#, java-format #, java-format
msgid "Save {0} to router address book and continue to eepsite" msgid "Save {0} to router address book and continue to eepsite"
msgstr "" msgstr "Guardar {0} a la libreta de direcciones del router y acceder al sitio i2p."
"Guardar {0} a la libreta de direcciones del router y acceder al sitio i2p."
#. only blockfile supports multiple books #. only blockfile supports multiple books
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1045 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1045
#, java-format #, java-format
msgid "Save {0} to master address book and continue to eepsite" msgid "Save {0} to master address book and continue to eepsite"
msgstr "" msgstr "Guardar {0} a la libreta de direcciones principal y acceder al sitio i2p."
"Guardar {0} a la libreta de direcciones principal y acceder al sitio i2p."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1046 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1046
#, java-format #, java-format
msgid "Save {0} to private address book and continue to eepsite" msgid "Save {0} to private address book and continue to eepsite"
msgstr "" msgstr "Guardar {0} a la libreta de direcciones privada y acceder al sitio i2p."
"Guardar {0} a la libreta de direcciones privada y acceder al sitio i2p."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1211 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1211
msgid "HTTP Outproxy" msgid "HTTP Outproxy"
@@ -91,10 +85,9 @@ msgstr "Puerta de salida HTTP"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1216 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1216
msgid "" msgid ""
"Click a link below to look for an address helper by using a \"jump\" service:" "Click a link below to look for an address helper by using a \"jump\" "
msgstr "" "service:"
"Pincha en un enlace de debajo para buscar un ayudante de direcciones " msgstr "Pincha en un enlace de debajo para buscar un ayudante de direcciones mediante el uso de un servicio de \"salto\":"
"mediante el uso de un servicio de \"salto\":"
#. Translators: parameter is a host name #. Translators: parameter is a host name
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1252 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1252
@@ -146,97 +139,109 @@ msgstr "¡Haz click aquí si no estás siendo enviado automáticamente!"
msgid "internal" msgid "internal"
msgstr "interno" msgstr "interno"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:174 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:175
msgid "" msgid ""
"Invalid form submission, probably because you used the 'back' or 'reload' " "Invalid form submission, probably because you used the 'back' or 'reload' "
"button on your browser. Please resubmit." "button on your browser. Please resubmit."
msgstr "" msgstr "El formulario presentado es inválido, probablemente porque has utilizado el botón 'atrás' o 'recargar' de tu navegador. Por favor, ¡vuelve a enviarlo!"
"El formulario presentado es inválido, probablemente porque has utilizado el "
"botón 'atrás' o 'recargar' de tu navegador. Por favor, ¡vuelve a enviarlo!"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:221 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:222
msgid "Configuration reloaded for all tunnels" msgid "Configuration reloaded for all tunnels"
msgstr "Configuración recargada para todos los túneles" msgstr "Configuración recargada para todos los túneles"
#. and give them something to look at in any case #. and give them something to look at in any case
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:233 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:234
msgid "Starting tunnel" msgid "Starting tunnel"
msgstr "Inicializando el túnel" msgstr "Inicializando el túnel"
#. and give them something to look at in any case #. and give them something to look at in any case
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:246 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:247
msgid "Stopping tunnel" msgid "Stopping tunnel"
msgstr "Deteniendo el túnel" msgstr "Deteniendo el túnel"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:314 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:315
msgid "Configuration changes saved" msgid "Configuration changes saved"
msgstr "Cambios en la configuración guardados" msgstr "Cambios en la configuración guardados"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:317 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:318
msgid "Failed to save configuration" msgid "Failed to save configuration"
msgstr "No se pudo guardar la configuración" msgstr "No se pudo guardar la configuración"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:436 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:437
msgid "New Tunnel" msgid "New Tunnel"
msgstr "Nuevo túnel" msgstr "Nuevo túnel"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:456 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:460
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:470
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:587
msgid "Port not set"
msgstr "Puerto no establecido"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:463
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:589
msgid "Invalid port"
msgstr "Puerto no válido"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:466
msgid "Warning - ports less than 1024 are not recommended"
msgstr "Advertencia: no se recomienda usar puertos inferiores al 1024"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:482
msgid "Standard client" msgid "Standard client"
msgstr "Cliente estándar" msgstr "Cliente estándar"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:457 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:483
msgid "HTTP client" msgid "HTTP client"
msgstr "Cliente HTTP" msgstr "Cliente HTTP"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:458 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:484
msgid "IRC client" msgid "IRC client"
msgstr "Cliente IRC" msgstr "Cliente IRC"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:459 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:485
msgid "Standard server" msgid "Standard server"
msgstr "Servidor estándar" msgstr "Servidor estándar"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:460 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:486
msgid "HTTP server" msgid "HTTP server"
msgstr "Servidor HTTP" msgstr "Servidor HTTP"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:461 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:487
msgid "SOCKS 4/4a/5 proxy" msgid "SOCKS 4/4a/5 proxy"
msgstr "Proxy SOCKS 4/4a/5" msgstr "Proxy SOCKS 4/4a/5"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:462 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:488
msgid "SOCKS IRC proxy" msgid "SOCKS IRC proxy"
msgstr "Proxy IRC SOCKS" msgstr "Proxy IRC SOCKS"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:463 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:489
msgid "CONNECT/SSL/HTTPS proxy" msgid "CONNECT/SSL/HTTPS proxy"
msgstr "Proxy CONNECT/SSL/HTTPS" msgstr "Proxy CONNECT/SSL/HTTPS"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:464 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:490
msgid "IRC server" msgid "IRC server"
msgstr "Servidor de IRC" msgstr "Servidor de IRC"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:465 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:491
msgid "Streamr client" msgid "Streamr client"
msgstr "Cliente Streamr" msgstr "Cliente Streamr"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:466 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:492
msgid "Streamr server" msgid "Streamr server"
msgstr "Servidor Streamr" msgstr "Servidor Streamr"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:467 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:493
msgid "HTTP bidir" msgid "HTTP bidir"
msgstr "HTTP bidir" msgstr "HTTP bidir"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:555 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:581
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:305 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:299
msgid "Host not set" msgid "Host not set"
msgstr "Host no establecido" msgstr "Host no establecido"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:559 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:583
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:287 msgid "Invalid address"
msgid "Port not set" msgstr "Dirección no válida"
msgstr "Puerto no establecido"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:82 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:82
msgid "I2P Tunnel Manager - Edit Client Tunnel" msgid "I2P Tunnel Manager - Edit Client Tunnel"
@@ -263,14 +268,14 @@ msgstr "Nombre"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:127 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:127
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:127 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:127
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:261 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:261
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:294 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:288
msgid "Type" msgid "Type"
msgstr "Tipo" msgstr "Tipo"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:131 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:131
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:131 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:131
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:393
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:330 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:330
msgid "Description" msgid "Description"
msgstr "Descripción" msgstr "Descripción"
@@ -329,9 +334,7 @@ msgstr "Túnel Compartido"
msgid "" msgid ""
"(Share tunnels with other clients and irc/httpclients? Change requires " "(Share tunnels with other clients and irc/httpclients? Change requires "
"restart of client proxy)" "restart of client proxy)"
msgstr "" msgstr "(¿Compartir túneles con otros clientes y clientes de IRC/http? Cambiar esto requiere reiniciar el proxy de cliente)"
"(¿Compartir túneles con otros clientes y clientes de IRC/http? Cambiar esto "
"requiere reiniciar el proxy de cliente)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:225 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:225
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:135 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:135
@@ -359,9 +362,7 @@ msgstr "Opciones de red avanzadas"
msgid "" msgid ""
"(NOTE: when this client proxy is configured to share tunnels, then these " "(NOTE: when this client proxy is configured to share tunnels, then these "
"options are for all the shared proxy clients!)" "options are for all the shared proxy clients!)"
msgstr "" msgstr "(NOTA: Si este proxy de cliente está configurado para compartir túneles, estas opciones se aplicarán a todos los proxys de cliente compartidos.)"
"(NOTA: Si este proxy de cliente está configurado para compartir túneles, "
"estas opciones se aplicarán a todos los proxys de cliente compartidos.)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:245 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:245
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:255 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:255
@@ -412,23 +413,18 @@ msgstr "Variación de 0 saltos (sin aleatoriedad, rendimiento constante)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:300 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:300
msgid "" msgid ""
"+ 0-1 hop variance (medium additive randomisation, subtractive performance)" "+ 0-1 hop variance (medium additive randomisation, subtractive performance)"
msgstr "" msgstr "Variación de + 0-1 salto (aleatoriedad media aditiva, rendimiento substractivo)"
"Variación de + 0-1 salto (aleatoriedad media aditiva, rendimiento "
"substractivo)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:294 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:294
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:304 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:304
msgid "" msgid ""
"+ 0-2 hop variance (high additive randomisation, subtractive performance)" "+ 0-2 hop variance (high additive randomisation, subtractive performance)"
msgstr "" msgstr "Variación de + 0-2 saltos (aleatoriedad alta aditiva, rendimiento substractivo)"
"Variación de + 0-2 saltos (aleatoriedad alta aditiva, rendimiento "
"substractivo)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:298 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:298
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:308 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:308
msgid "+/- 0-1 hop variance (standard randomisation, standard performance)" msgid "+/- 0-1 hop variance (standard randomisation, standard performance)"
msgstr "" msgstr "Variación de +/- 0-1 salto (aleatoriedad estándar, rendimiento estándar)"
"Variación de +/- 0-1 salto (aleatoriedad estándar, rendimiento estándar)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:302 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:302
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:312 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:312
@@ -448,25 +444,20 @@ msgstr "Cantidad"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:325 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:325
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)" msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
msgstr "" msgstr "1 túnel entrante, 1 de salida (bajo uso de ancho de banda, menos fiabilidad)"
"1 túnel entrante, 1 de salida (bajo uso de ancho de banda, menos fiabilidad)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:329 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:329
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:339 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:339
msgid "" msgid ""
"2 inbound, 2 outbound tunnels (standard bandwidth usage, standard " "2 inbound, 2 outbound tunnels (standard bandwidth usage, standard "
"reliability)" "reliability)"
msgstr "" msgstr "2 túneles entrantes, 2 de salida (uso de ancho de banda estándar, fiabilidad estándar)"
"2 túneles entrantes, 2 de salida (uso de ancho de banda estándar, fiabilidad "
"estándar)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:333 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:333
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:343 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:343
msgid "" msgid ""
"3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)" "3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
msgstr "" msgstr "3 túneles entrantes, 3 de salida (mayor uso de ancho de banda, mayor fiabilidad)"
"3 túneles entrantes, 3 de salida (mayor uso de ancho de banda, mayor "
"fiabilidad)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:341 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:341
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:351 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:351
@@ -486,24 +477,18 @@ msgstr "0 túneles de respaldo (redundancia 0, no aumenta el uso de recursos)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:357 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:357
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:367 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:367
msgid "1 backup tunnel each direction (low redundancy, low resource usage)" msgid "1 backup tunnel each direction (low redundancy, low resource usage)"
msgstr "" msgstr "1 túnel de respaldo en cada dirección (redundancia baja, uso bajo de recursos)"
"1 túnel de respaldo en cada dirección (redundancia baja, uso bajo de "
"recursos)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:361 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:361
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:371 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:371
msgid "" msgid ""
"2 backup tunnels each direction (medium redundancy, medium resource usage)" "2 backup tunnels each direction (medium redundancy, medium resource usage)"
msgstr "" msgstr "2 túneles de respaldo en cada dirección (redundancia media, uso de recursos medio)"
"2 túneles de respaldo en cada dirección (redundancia media, uso de recursos "
"medio)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:365 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:365
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:375 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:375
msgid "3 backup tunnels each direction (high redundancy, high resource usage)" msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
msgstr "" msgstr "3 túneles de respaldo en cada dirección (alta redundancia, uso de recursos alto)"
"3 túneles de respaldo en cada dirección (alta redundancia, uso de recursos "
"alto)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:373 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:373
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:383 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:383
@@ -835,7 +820,7 @@ msgstr "Vista previa"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:129 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:129
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:192 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:192
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:265 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:265
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:312 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:306
msgid "Status" msgid "Status"
msgstr "Estado" msgstr "Estado"
@@ -848,30 +833,30 @@ msgid "No Preview"
msgstr "Sin vista previa" msgstr "Sin vista previa"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:199 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:199
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:319 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:313
msgid "Starting..." msgid "Starting..."
msgstr "Iniciando..." msgstr "Iniciando..."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:206 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:206
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:220 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:220
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:326 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:320
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:340 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:334
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:354 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:348
msgid "Stop" msgid "Stop"
msgstr "Detener" msgstr "Detener"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:213 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:213
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:347 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:341
msgid "Running" msgid "Running"
msgstr "Ejecutándose" msgstr "Ejecutándose"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:227 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:227
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:361 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:355
msgid "Stopped" msgid "Stopped"
msgstr "Detenido" msgstr "Detenido"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:234 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:234
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:368 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:362
msgid "Start" msgid "Start"
msgstr "Iniciar" msgstr "Iniciar"
@@ -880,7 +865,7 @@ msgid "New server tunnel"
msgstr "Nuevo servidor de túnel" msgstr "Nuevo servidor de túnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:409 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:403
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:223 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:223
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:265 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:265
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:295 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:295
@@ -890,7 +875,7 @@ msgid "Standard"
msgstr "Estándar" msgstr "Estándar"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:411 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:405
msgid "Create" msgid "Create"
msgstr "Crear" msgstr "Crear"
@@ -899,23 +884,23 @@ msgid "I2P Client Tunnels"
msgstr "Túneles de cliente I2P" msgstr "Túneles de cliente I2P"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:263 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:263
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:298 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:292
msgid "Interface" msgid "Interface"
msgstr "Interfaz" msgstr "Interfaz"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:333 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:327
msgid "Standby" msgid "Standby"
msgstr "En espera" msgstr "En espera"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:377 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:371
msgid "Outproxy" msgid "Outproxy"
msgstr "Puerta de salida" msgstr "Puerta de salida"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:394 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:388
msgid "none" msgid "none"
msgstr "ninguno" msgstr "ninguno"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:407 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
msgid "New client tunnel" msgid "New client tunnel"
msgstr "Nuevo túnel cliente" msgstr "Nuevo túnel cliente"
@@ -959,35 +944,27 @@ msgstr "Asistente completado"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:189 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:189
msgid "" msgid ""
"This wizard will take you through the various options available for creating " "This wizard will take you through the various options available for creating"
"tunnels in I2P." " tunnels in I2P."
msgstr "" msgstr "Este asistente le guiará a través de las distintas opciones disponibles para la creación de túneles en I2P."
"Este asistente le guiará a través de las distintas opciones disponibles para "
"la creación de túneles en I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:191 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:191
msgid "" msgid ""
"The first thing to decide is whether you want to create a server or a client " "The first thing to decide is whether you want to create a server or a client"
"tunnel." " tunnel."
msgstr "" msgstr "Lo primero que debe decidir es si se desea crear un túnel de servidor o de cliente."
"Lo primero que debe decidir es si se desea crear un túnel de servidor o de "
"cliente."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:193 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:193
msgid "" msgid ""
"If you need to connect to a remote service, such as an IRC server inside I2P " "If you need to connect to a remote service, such as an IRC server inside I2P"
"or a code repository, then you will require a CLIENT tunnel." " or a code repository, then you will require a CLIENT tunnel."
msgstr "" msgstr "Si necesita conectarse a un servicio remoto, como un servidor de IRC dentro de I2P o un repositorio de código, va a requerir un túnel CLIENTE."
"Si necesita conectarse a un servicio remoto, como un servidor de IRC dentro "
"de I2P o un repositorio de código, va a requerir un túnel CLIENTE."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:195 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:195
msgid "" msgid ""
"On the other hand, if you wish to host a service for others to connect to " "On the other hand, if you wish to host a service for others to connect to "
"you'll need to create a SERVER tunnel." "you'll need to create a SERVER tunnel."
msgstr "" msgstr "Por otro lado, si desea hospedar un servicio para que otros puedan conectarse a usted, necesitará crear un túnel SERVIDOR."
"Por otro lado, si desea hospedar un servicio para que otros puedan "
"conectarse a usted, necesitará crear un túnel SERVIDOR."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:197 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:197
msgid "Server Tunnel" msgid "Server Tunnel"
@@ -1010,9 +987,7 @@ msgstr "Túnel básico para la conexión a un servicio dentro de I2P."
msgid "" msgid ""
"Try this if none of the tunnel types below fit your requirements, or you " "Try this if none of the tunnel types below fit your requirements, or you "
"don't know what type of tunnel you need." "don't know what type of tunnel you need."
msgstr "" msgstr "Pruebe esto si ninguno de los tipos de túneles a continuación se ajustan a sus requerimientos, o si no sabe qué tipo de túnel necesita."
"Pruebe esto si ninguno de los tipos de túneles a continuación se ajustan a "
"sus requerimientos, o si no sabe qué tipo de túnel necesita."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:229 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:229
msgid "Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P." msgid "Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P."
@@ -1021,20 +996,15 @@ msgstr "Túnel que actúa como un proxy HTTP para llegar a eepsites dentro I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:231 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:231
msgid "" msgid ""
"Set your browser to use this tunnel as an http proxy, or set your " "Set your browser to use this tunnel as an http proxy, or set your "
"\"http_proxy\" environment variable for command-line applications in GNU/" "\"http_proxy\" environment variable for command-line applications in "
"Linux." "GNU/Linux."
msgstr "" msgstr "Configure su navegador para usar este túnel como un proxy HTTP, o configure su variable de entorno \"http_proxy\" para aplicaciones de línea de comandos en GNU / Linux."
"Configure su navegador para usar este túnel como un proxy HTTP, o configure "
"su variable de entorno \"http_proxy\" para aplicaciones de línea de comandos "
"en GNU / Linux."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:233 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:233
msgid "" msgid ""
"Websites outside I2P can also be reached if an HTTP proxy within I2P is " "Websites outside I2P can also be reached if an HTTP proxy within I2P is "
"known." "known."
msgstr "" msgstr "También es posible llegar a sitios web de fuera de I2P si se conoce algún proxy HTTP dentro de I2P."
"También es posible llegar a sitios web de fuera de I2P si se conoce algún "
"proxy HTTP dentro de I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:235 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:235
msgid "Customised client tunnel specific for IRC connections." msgid "Customised client tunnel specific for IRC connections."
@@ -1044,17 +1014,13 @@ msgstr "Túnel de cliente personalizado específicamente para conexiones de IRC.
msgid "" msgid ""
"With this tunnel type, your IRC client will be able to connect to an IRC " "With this tunnel type, your IRC client will be able to connect to an IRC "
"network inside I2P." "network inside I2P."
msgstr "" msgstr "Con este tipo de túnel, su cliente de IRC será capaz de conectarse a una red de IRC dentro de I2P."
"Con este tipo de túnel, su cliente de IRC será capaz de conectarse a una red "
"de IRC dentro de I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:239 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:239
msgid "" msgid ""
"Each IRC network in I2P that you wish to connect to will require its own " "Each IRC network in I2P that you wish to connect to will require its own "
"tunnel. (See Also, SOCKS IRC)" "tunnel. (See Also, SOCKS IRC)"
msgstr "" msgstr "Cada red IRC en I2P a la que desee conectarse requerirá su propio túnel. (Véase también, SOCKS IRC)"
"Cada red IRC en I2P a la que desee conectarse requerirá su propio túnel. "
"(Véase también, SOCKS IRC)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:241 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:241
msgid "A tunnel that implements the SOCKS protocol." msgid "A tunnel that implements the SOCKS protocol."
@@ -1064,45 +1030,33 @@ msgstr "Un túnel que implementa el protocolo SOCKS."
msgid "" msgid ""
"This enables both TCP and UDP connections to be made through a SOCKS " "This enables both TCP and UDP connections to be made through a SOCKS "
"outproxy within I2P." "outproxy within I2P."
msgstr "" msgstr "Esto permite que las conexiones TCP y UDP se hagan a través de un outproxy SOCKS que esté dentro de I2P."
"Esto permite que las conexiones TCP y UDP se hagan a través de un outproxy "
"SOCKS que esté dentro de I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:245 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:245
msgid "" msgid ""
"A client tunnel implementing the SOCKS protocol, which is customised for " "A client tunnel implementing the SOCKS protocol, which is customised for "
"connecting to IRC networks." "connecting to IRC networks."
msgstr "" msgstr "Un túnel de cliente que implementa el protocolo SOCKS, personalizado para la conexión con redes IRC."
"Un túnel de cliente que implementa el protocolo SOCKS, personalizado para la "
"conexión con redes IRC."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:247 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:247
msgid "" msgid ""
"With this tunnel type, IRC networks in I2P can be reached by typing the I2P " "With this tunnel type, IRC networks in I2P can be reached by typing the I2P "
"address into your IRC client, and configuring the IRC client to use this " "address into your IRC client, and configuring the IRC client to use this "
"SOCKS tunnel." "SOCKS tunnel."
msgstr "" msgstr "Con este tipo de túnel, las redes IRC de I2P pueden ser alcanzadas escribiendo directamente la dirección I2P en el cliente de IRC, y configurando el cliente de IRC para utilizar este túnel SOCKS."
"Con este tipo de túnel, las redes IRC de I2P pueden ser alcanzadas "
"escribiendo directamente la dirección I2P en el cliente de IRC, y "
"configurando el cliente de IRC para utilizar este túnel SOCKS."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:249 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:249
msgid "" msgid ""
"This means that only one I2P tunnel is required rather than a separate " "This means that only one I2P tunnel is required rather than a separate "
"tunnel per IRC network." "tunnel per IRC network."
msgstr "" msgstr "Esto significa que sólo es necesario un único túnel I2P en lugar de un túnel distinto por cada red IRC."
"Esto significa que sólo es necesario un único túnel I2P en lugar de un túnel "
"distinto por cada red IRC."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:251 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:251
msgid "" msgid ""
"IRC networks outside I2P can also be reached if a SOCKS outproxy within I2P " "IRC networks outside I2P can also be reached if a SOCKS outproxy within I2P "
"is known, though it depends on whether or not the outproxy has been blocked " "is known, though it depends on whether or not the outproxy has been blocked "
"by the IRC network." "by the IRC network."
msgstr "" msgstr "También se puede llegar a redes IRC de fuera de I2P si se conoce un outproxy SOCKS en I2P, aunque depende de si el outproxy ha sido bloqueado por la red IRC."
"También se puede llegar a redes IRC de fuera de I2P si se conoce un outproxy "
"SOCKS en I2P, aunque depende de si el outproxy ha sido bloqueado por la red "
"IRC."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:253 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:253
msgid "A client tunnel that implements the HTTP CONNECT command." msgid "A client tunnel that implements the HTTP CONNECT command."
@@ -1112,9 +1066,7 @@ msgstr "Un túnel de cliente que implementa el comando HTTP CONNECT."
msgid "" msgid ""
"This enables TCP connections to be made through an HTTP outproxy, assuming " "This enables TCP connections to be made through an HTTP outproxy, assuming "
"the proxy supports the CONNECT command." "the proxy supports the CONNECT command."
msgstr "" msgstr "Esto permite hacer conexiones TCP a través de un outproxy HTTP, suponiendo que el servidor proxy admita el comando CONNECT."
"Esto permite hacer conexiones TCP a través de un outproxy HTTP, suponiendo "
"que el servidor proxy admita el comando CONNECT."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:257 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:257
msgid "A customised client tunnel for Streamr." msgid "A customised client tunnel for Streamr."
@@ -1122,8 +1074,7 @@ msgstr "Un túnel de cliente personalizado para Streamr."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:267 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:267
msgid "A basic server tunnel for hosting a generic service inside I2P." msgid "A basic server tunnel for hosting a generic service inside I2P."
msgstr "" msgstr "Un túnel básico de servidor para alojar un servicio genérico dentro de I2P."
"Un túnel básico de servidor para alojar un servicio genérico dentro de I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:271 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:271
msgid "A server tunnel that is customised for HTTP connections." msgid "A server tunnel that is customised for HTTP connections."
@@ -1137,28 +1088,21 @@ msgstr "Utilice este tipo de túnel si desea alojar una eepsite."
msgid "" msgid ""
"A customised server tunnel that can both serve HTTP data and connect to " "A customised server tunnel that can both serve HTTP data and connect to "
"other server tunnels." "other server tunnels."
msgstr "" msgstr "Un túnel de servidor personalizado que puede servir tanto datos HTTP como conectar a otros túneles de servidor."
"Un túnel de servidor personalizado que puede servir tanto datos HTTP como "
"conectar a otros túneles de servidor."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:277 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:277
msgid "This tunnel type is predominantly used when running a Seedless server." msgid "This tunnel type is predominantly used when running a Seedless server."
msgstr "" msgstr "Este tipo de túnel se utiliza principalmente cuando se ejecuta un servidor sin semillas (Seedless)."
"Este tipo de túnel se utiliza principalmente cuando se ejecuta un servidor "
"sin semillas (Seedless)."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:279 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:279
msgid "A customised server tunnel for hosting IRC networks inside I2P." msgid "A customised server tunnel for hosting IRC networks inside I2P."
msgstr "" msgstr "Un túnel de servidor personalizado para alojar redes IRC dentro de I2P."
"Un túnel de servidor personalizado para alojar redes IRC dentro de I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:281 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:281
msgid "" msgid ""
"Usually, a separate tunnel needs to be created for each IRC server that is " "Usually, a separate tunnel needs to be created for each IRC server that is "
"to be accessible inside I2P." "to be accessible inside I2P."
msgstr "" msgstr "Normalmente, se debe crear un túnel por separado para cada servidor IRC, que será accesible dentro de I2P."
"Normalmente, se debe crear un túnel por separado para cada servidor IRC, que "
"será accesible dentro de I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:283 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:283
msgid "A customised server tunnel for Streamr." msgid "A customised server tunnel for Streamr."
@@ -1172,17 +1116,13 @@ msgstr "Elegir un nombre y una descripción para su túnel."
msgid "" msgid ""
"These can be anything you want - they are just for ease of identifying the " "These can be anything you want - they are just for ease of identifying the "
"tunnel in the routerconsole." "tunnel in the routerconsole."
msgstr "" msgstr "Estos pueden ser lo que se quiera - son sólo para facilitar la identificación del túnel en la consola del router."
"Estos pueden ser lo que se quiera - son sólo para facilitar la "
"identificación del túnel en la consola del router."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:354 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:354
msgid "" msgid ""
"If you know of any outproxies for this type of tunnel (either HTTP or " "If you know of any outproxies for this type of tunnel (either HTTP or "
"SOCKS), fill them in below." "SOCKS), fill them in below."
msgstr "" msgstr "Si conoce algún outproxie para este tipo de túnel (HTTP o SOCKS), rellénelo a continuación."
"Si conoce algún outproxie para este tipo de túnel (HTTP o SOCKS), rellénelo "
"a continuación."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:356 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:356
msgid "Separate multiple proxies with commas." msgid "Separate multiple proxies with commas."
@@ -1192,35 +1132,27 @@ msgstr "Separe múltiples servidores proxy con comas."
msgid "" msgid ""
"Type in the I2P destination of the service that this client tunnel should " "Type in the I2P destination of the service that this client tunnel should "
"connect to." "connect to."
msgstr "" msgstr "Introduzca el destino de I2P del servicio al que este túnel de cliente debe conectarse."
"Introduzca el destino de I2P del servicio al que este túnel de cliente debe "
"conectarse."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:376 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:376
msgid "" msgid ""
"This could be the full base 64 destination key, or an I2P URL from your " "This could be the full base 64 destination key, or an I2P URL from your "
"address book." "address book."
msgstr "" msgstr "Este puede ser la clave de destino en base 64 o una dirección URL I2P de su libreta de direcciones."
"Este puede ser la clave de destino en base 64 o una dirección URL I2P de su "
"libreta de direcciones."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:406 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:406
msgid "" msgid ""
"This is the IP that your service is running on, this is usually on the same " "This is the IP that your service is running on, this is usually on the same "
"machine so 127.0.0.1 is autofilled." "machine so 127.0.0.1 is autofilled."
msgstr "" msgstr "Esta es la IP en la que el servicio se está ejecutando, esto suele ser en la misma máquina, por lo que se ha auto-rellenado con 127.0.0.1 "
"Esta es la IP en la que el servicio se está ejecutando, esto suele ser en la "
"misma máquina, por lo que se ha auto-rellenado con 127.0.0.1 "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:429 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:429
msgid "This is the port that the service is accepting connections on." msgid "This is the port that the service is accepting connections on."
msgstr "" msgstr "Este es el puerto por el que el servicio está aceptando conexiones entrantes."
"Este es el puerto por el que el servicio está aceptando conexiones entrantes."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:450 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:450
msgid "This is the port that the client tunnel will be accessed from locally." msgid "This is the port that the client tunnel will be accessed from locally."
msgstr "" msgstr "Este es el puerto por el que se accederá al túnel de cliente localmente."
"Este es el puerto por el que se accederá al túnel de cliente localmente."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:452 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:452
msgid "This is also the client port for the HTTPBidir server tunnel." msgid "This is also the client port for the HTTPBidir server tunnel."
@@ -1230,9 +1162,7 @@ msgstr "También es el puerto de cliente para el túnel de servidor HTTPBidir."
msgid "" msgid ""
"How do you want this tunnel to be accessed? By just this machine, your " "How do you want this tunnel to be accessed? By just this machine, your "
"entire subnet, or external internet?" "entire subnet, or external internet?"
msgstr "" msgstr "¿Cómo quiere que se acceda a este túnel? ¿Sólo esta máquina, su subred entera, o todo el internet externo?"
"¿Cómo quiere que se acceda a este túnel? ¿Sólo esta máquina, su subred "
"entera, o todo el internet externo?"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:473 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:473
msgid "You will most likely want to just allow 127.0.0.1" msgid "You will most likely want to just allow 127.0.0.1"
@@ -1242,41 +1172,30 @@ msgstr "Lo más probable es que desee permitir sólo 127.0.0.1"
msgid "" msgid ""
"The I2P router can automatically start this tunnel for you when the router " "The I2P router can automatically start this tunnel for you when the router "
"is started." "is started."
msgstr "" msgstr "El router I2P puede activar automáticamente este túnel cuando el router se inicie"
"El router I2P puede activar automáticamente este túnel cuando el router se "
"inicie"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:517 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:517
msgid "" msgid ""
"This can be useful for frequently-used tunnels (especially server tunnels), " "This can be useful for frequently-used tunnels (especially server tunnels), "
"but for tunnels that are only used occassionally it would mean that the I2P " "but for tunnels that are only used occassionally it would mean that the I2P "
"router is creating and maintaining unnecessary tunnels." "router is creating and maintaining unnecessary tunnels."
msgstr "" msgstr "Esto puede ser útil para los túneles de uso frecuente (especialmente en los túneles de servidor), pero para los túneles que sólo se utilizan ocasionalmente, significaría que el router I2P está creando y manteniendo túneles innecesarios."
"Esto puede ser útil para los túneles de uso frecuente (especialmente en los "
"túneles de servidor), pero para los túneles que sólo se utilizan "
"ocasionalmente, significaría que el router I2P está creando y manteniendo "
"túneles innecesarios."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:543 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:543
msgid "The wizard has now collected enough information to create your tunnel." msgid "The wizard has now collected enough information to create your tunnel."
msgstr "" msgstr "El asistente ya ha recogido suficiente información para crear el túnel."
"El asistente ya ha recogido suficiente información para crear el túnel."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:545 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:545
msgid "" msgid ""
"Upon clicking the Save button below, the wizard will set up the tunnel, and " "Upon clicking the Save button below, the wizard will set up the tunnel, and "
"take you back to the main I2PTunnel page." "take you back to the main I2PTunnel page."
msgstr "" msgstr "Al hacer clic en el botón Guardar a continuación, el asistente creará el túnel, y le llevará de vuelta a la página principal de túneles I2P."
"Al hacer clic en el botón Guardar a continuación, el asistente creará el "
"túnel, y le llevará de vuelta a la página principal de túneles I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:550 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:550
msgid "" msgid ""
"Because you chose to automatically start the tunnel when the router starts, " "Because you chose to automatically start the tunnel when the router starts, "
"you don't have to do anything further." "you don't have to do anything further."
msgstr "" msgstr "Como ha decidido iniciar automáticamente el túnel cuando el router se inicie, no tiene que hacer nada más."
"Como ha decidido iniciar automáticamente el túnel cuando el router se "
"inicie, no tiene que hacer nada más."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:552 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:552
msgid "The router will start the tunnel once it has been set up." msgid "The router will start the tunnel once it has been set up."
@@ -1286,17 +1205,13 @@ msgstr "El router iniciará el túnel una vez haya sido establecido."
msgid "" msgid ""
"Because you chose not to automatically start the tunnel, you will have to " "Because you chose not to automatically start the tunnel, you will have to "
"manually start it." "manually start it."
msgstr "" msgstr "Como usted ha decidido no iniciar automáticamente el túnel, tendrá que iniciarlo de forma manual."
"Como usted ha decidido no iniciar automáticamente el túnel, tendrá que "
"iniciarlo de forma manual."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:558 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:558
msgid "" msgid ""
"You can do this by clicking the Start button on the main page which " "You can do this by clicking the Start button on the main page which "
"corresponds to the new tunnel." "corresponds to the new tunnel."
msgstr "" msgstr "Esto se puede hacer haciendo clic en el botón Iniciar en la página principal que corresponde al nuevo túnel."
"Esto se puede hacer haciendo clic en el botón Iniciar en la página principal "
"que corresponde al nuevo túnel."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:562 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:562
msgid "Below is a summary of the options you chose:" msgid "Below is a summary of the options you chose:"
@@ -1306,19 +1221,14 @@ msgstr "A continuación se muestra un resumen de las opciones que ha elegido:"
msgid "" msgid ""
"Alongside these basic settings, there are a number of advanced options for " "Alongside these basic settings, there are a number of advanced options for "
"tunnel configuration." "tunnel configuration."
msgstr "" msgstr "Junto a estos valores básicos, hay una serie de opciones avanzadas para la configuración de túneles."
"Junto a estos valores básicos, hay una serie de opciones avanzadas para la "
"configuración de túneles."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:662 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:662
msgid "" msgid ""
"The wizard will set reasonably sensible default values for these, but you " "The wizard will set reasonably sensible default values for these, but you "
"can view and/or edit these by clicking on the tunnel's name in the main " "can view and/or edit these by clicking on the tunnel's name in the main "
"I2PTunnel page." "I2PTunnel page."
msgstr "" msgstr "El asistente establecerá valores razonablemente sensibles para ellos por defecto, pero se pueden ver y/o editar haciendo clic en el nombre del túnel en la página de túneles I2P principal."
"El asistente establecerá valores razonablemente sensibles para ellos por "
"defecto, pero se pueden ver y/o editar haciendo clic en el nombre del túnel "
"en la página de túneles I2P principal."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:704 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:704
msgid "Previous" msgid "Previous"

View File

@@ -12,9 +12,9 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: I2P\n" "Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-10-12 00:46+0000\n" "POT-Creation-Date: 2012-10-15 17:57+0000\n"
"PO-Revision-Date: 2012-10-12 00:40+0000\n" "PO-Revision-Date: 2012-10-12 00:51+0000\n"
"Last-Translator: kytv <killyourtv@i2pmail.org>\n" "Last-Translator: BadCluster <badcluster@i2pmail.org>\n"
"Language-Team: Italian (http://www.transifex.com/projects/p/I2P/language/" "Language-Team: Italian (http://www.transifex.com/projects/p/I2P/language/"
"it/)\n" "it/)\n"
"Language: it\n" "Language: it\n"
@@ -185,11 +185,11 @@ msgstr "Porta non impostata"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:463 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:463
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:589 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:589
msgid "Invalid port" msgid "Invalid port"
msgstr "" msgstr "Porta non valida"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:466 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:466
msgid "Warning - ports less than 1024 are not recommended" msgid "Warning - ports less than 1024 are not recommended"
msgstr "" msgstr "Attenzione - E' meglio non utilizzare porte inderiori alla 1024"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:482 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:482
msgid "Standard client" msgid "Standard client"
@@ -246,7 +246,7 @@ msgstr "Host non impostato"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:583 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:583
msgid "Invalid address" msgid "Invalid address"
msgstr "" msgstr "Indirizzo non valido"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:82 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:82
msgid "I2P Tunnel Manager - Edit Client Tunnel" msgid "I2P Tunnel Manager - Edit Client Tunnel"

File diff suppressed because it is too large Load Diff

View File

@@ -8,17 +8,16 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: I2P\n" "Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
"POT-Creation-Date: 2012-07-26 19:10+0000\n" "POT-Creation-Date: 2012-10-12 00:38+0000\n"
"PO-Revision-Date: 2012-07-23 16:31+0000\n" "PO-Revision-Date: 2012-10-12 00:40+0000\n"
"Last-Translator: Martin Svensson <digitalmannen@gmail.com>\n" "Last-Translator: kytv <killyourtv@i2pmail.org>\n"
"Language-Team: Swedish (Sweden) (http://www.transifex.com/projects/p/I2P/" "Language-Team: Swedish (Sweden) (http://www.transifex.com/projects/p/I2P/language/sv_SE/)\n"
"language/sv_SE/)\n"
"Language: sv_SE\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n" "Language: sv_SE\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:554 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:554
msgid "This seems to be a bad destination:" msgid "This seems to be a bad destination:"
@@ -31,13 +30,10 @@ msgstr "i2padresshjälp kan inte hjälpa dig med ett sådant mål!"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:621 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:621
#, java-format #, java-format
msgid "" msgid ""
"To visit the destination in your host database, click <a href=\"{0}\">here</" "To visit the destination in your host database, click <a "
"a>. To visit the conflicting addresshelper destination, click <a href=" "href=\"{0}\">here</a>. To visit the conflicting addresshelper destination, "
"\"{1}\">here</a>." "click <a href=\"{1}\">here</a>."
msgstr "" msgstr "För att besöka målet i din värd databas href=\"{0}\"> klicka <a här </ a>. För att besöka de motstridiga hjälpaddresserna,<a href=\"{1}\"> klicka <a här </ a>."
"För att besöka målet i din värd databas href=\"{0}\"> klicka <a här </ a>. "
"För att besöka de motstridiga hjälpaddresserna,<a href=\"{1}\"> klicka <a "
"här </ a>."
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1023 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1023
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:403 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:403
@@ -52,7 +48,7 @@ msgid "Base 32"
msgstr "Bas 32" msgstr "Bas 32"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1031 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1031
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:380 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:374
msgid "Destination" msgid "Destination"
msgstr "Mål" msgstr "Mål"
@@ -83,10 +79,9 @@ msgstr "HTTP Utproxy"
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1216 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1216
msgid "" msgid ""
"Click a link below to look for an address helper by using a \"jump\" service:" "Click a link below to look for an address helper by using a \"jump\" "
msgstr "" "service:"
"Klicka på en länk nedan för att söka efter en hjälpaddress genom att använda " msgstr "Klicka på en länk nedan för att söka efter en hjälpaddress genom att använda en \"hopp\" tjänst"
"en \"hopp\" tjänst"
#. Translators: parameter is a host name #. Translators: parameter is a host name
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1252 #: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1252
@@ -138,97 +133,109 @@ msgstr "Klicka här om du inte omdirigeras automatiskt "
msgid "internal" msgid "internal"
msgstr "Intern " msgstr "Intern "
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:174 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:175
msgid "" msgid ""
"Invalid form submission, probably because you used the 'back' or 'reload' " "Invalid form submission, probably because you used the 'back' or 'reload' "
"button on your browser. Please resubmit." "button on your browser. Please resubmit."
msgstr "" msgstr "Ogiltigt formulärbegäran, beror troligtvis på attt du använde 'tillbaka' eller 'uppdatera' knappen. Försök att skicka igen"
"Ogiltigt formulärbegäran, beror troligtvis på attt du använde 'tillbaka' "
"eller 'uppdatera' knappen. Försök att skicka igen"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:221 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:222
msgid "Configuration reloaded for all tunnels" msgid "Configuration reloaded for all tunnels"
msgstr "Konfigurationen uppdateras för alla tunnlar" msgstr "Konfigurationen uppdateras för alla tunnlar"
#. and give them something to look at in any case #. and give them something to look at in any case
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:233 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:234
msgid "Starting tunnel" msgid "Starting tunnel"
msgstr "Startar tunnel" msgstr "Startar tunnel"
#. and give them something to look at in any case #. and give them something to look at in any case
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:246 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:247
msgid "Stopping tunnel" msgid "Stopping tunnel"
msgstr "Stannar tunnel" msgstr "Stannar tunnel"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:314 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:315
msgid "Configuration changes saved" msgid "Configuration changes saved"
msgstr "Konfigurationsändringar sparas" msgstr "Konfigurationsändringar sparas"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:317 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:318
msgid "Failed to save configuration" msgid "Failed to save configuration"
msgstr "Det gick inte att spara konfigurationen" msgstr "Det gick inte att spara konfigurationen"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:436 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:437
msgid "New Tunnel" msgid "New Tunnel"
msgstr "Ny tunnel" msgstr "Ny tunnel"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:456 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:460
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:470
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:587
msgid "Port not set"
msgstr "Ingen port angiven"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:463
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:589
msgid "Invalid port"
msgstr ""
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:466
msgid "Warning - ports less than 1024 are not recommended"
msgstr ""
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:482
msgid "Standard client" msgid "Standard client"
msgstr "Standard klient" msgstr "Standard klient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:457 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:483
msgid "HTTP client" msgid "HTTP client"
msgstr "HTTP-klient" msgstr "HTTP-klient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:458 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:484
msgid "IRC client" msgid "IRC client"
msgstr "IRC-klient" msgstr "IRC-klient"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:459 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:485
msgid "Standard server" msgid "Standard server"
msgstr "Standard server" msgstr "Standard server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:460 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:486
msgid "HTTP server" msgid "HTTP server"
msgstr "HTTP server" msgstr "HTTP server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:461 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:487
msgid "SOCKS 4/4a/5 proxy" msgid "SOCKS 4/4a/5 proxy"
msgstr "SOCKS 4/4a/5 proxy" msgstr "SOCKS 4/4a/5 proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:462 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:488
msgid "SOCKS IRC proxy" msgid "SOCKS IRC proxy"
msgstr "SOCKS IRC proxy" msgstr "SOCKS IRC proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:463 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:489
msgid "CONNECT/SSL/HTTPS proxy" msgid "CONNECT/SSL/HTTPS proxy"
msgstr "CONNECT/SSL/HTTPS proxy" msgstr "CONNECT/SSL/HTTPS proxy"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:464 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:490
msgid "IRC server" msgid "IRC server"
msgstr "IRC-server" msgstr "IRC-server"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:465 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:491
msgid "Streamr client" msgid "Streamr client"
msgstr "Klient för Streamr " msgstr "Klient för Streamr "
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:466 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:492
msgid "Streamr server" msgid "Streamr server"
msgstr "Server för Streamr" msgstr "Server för Streamr"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:467 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:493
msgid "HTTP bidir" msgid "HTTP bidir"
msgstr "HTTP bidir" msgstr "HTTP bidir"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:555 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:581
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:305 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:299
msgid "Host not set" msgid "Host not set"
msgstr "Ingen värd angiven" msgstr "Ingen värd angiven"
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:559 #: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:583
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:287 msgid "Invalid address"
msgid "Port not set" msgstr ""
msgstr "Ingen port angiven"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:82 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:82
msgid "I2P Tunnel Manager - Edit Client Tunnel" msgid "I2P Tunnel Manager - Edit Client Tunnel"
@@ -255,14 +262,14 @@ msgstr "Namn"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:127 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:127
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:127 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:127
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:261 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:261
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:294 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:288
msgid "Type" msgid "Type"
msgstr "Typ" msgstr "Typ"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:131 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:131
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:131 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:131
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:241
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:399 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:393
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:330 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:330
msgid "Description" msgid "Description"
msgstr "Beskrivning" msgstr "Beskrivning"
@@ -321,9 +328,7 @@ msgstr "Delad klient"
msgid "" msgid ""
"(Share tunnels with other clients and irc/httpclients? Change requires " "(Share tunnels with other clients and irc/httpclients? Change requires "
"restart of client proxy)" "restart of client proxy)"
msgstr "" msgstr "(Dela tunnlarna med andra klienter och irc/HTTP-klienter? Ändring kräver omstart av klientproxyn)"
"(Dela tunnlarna med andra klienter och irc/HTTP-klienter? Ändring kräver "
"omstart av klientproxyn)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:225 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:225
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:135 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:135
@@ -351,9 +356,7 @@ msgstr "Avancerade nätverks instälningar"
msgid "" msgid ""
"(NOTE: when this client proxy is configured to share tunnels, then these " "(NOTE: when this client proxy is configured to share tunnels, then these "
"options are for all the shared proxy clients!)" "options are for all the shared proxy clients!)"
msgstr "" msgstr "(OBS: när denna klientproxyn är konfigurerad för att dela tunnlar, då gäller dessa alternativ för alla delade proxyklienter!)"
"(OBS: när denna klientproxyn är konfigurerad för att dela tunnlar, då gäller "
"dessa alternativ för alla delade proxyklienter!)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:245 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:245
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:255 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:255
@@ -435,26 +438,20 @@ msgstr "Antal"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:325 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:325
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:335
msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)" msgid "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
msgstr "" msgstr "1 inkommande, 1 utgående tunnlar (låg bandbreddsanvändning, låg tillförlitlighet)"
"1 inkommande, 1 utgående tunnlar (låg bandbreddsanvändning, låg "
"tillförlitlighet)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:329 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:329
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:339 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:339
msgid "" msgid ""
"2 inbound, 2 outbound tunnels (standard bandwidth usage, standard " "2 inbound, 2 outbound tunnels (standard bandwidth usage, standard "
"reliability)" "reliability)"
msgstr "" msgstr "2 inkommande, 2 utgående tunnlar (normal bandbreddsanvändning, normal tillförlitlighet)"
"2 inkommande, 2 utgående tunnlar (normal bandbreddsanvändning, normal "
"tillförlitlighet)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:333 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:333
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:343 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:343
msgid "" msgid ""
"3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)" "3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
msgstr "" msgstr "3 inkommande, 3 utgående tunnlar (Högre bandbreddsanvändning, högre tillförlitlighet)"
"3 inkommande, 3 utgående tunnlar (Högre bandbreddsanvändning, högre "
"tillförlitlighet)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:341 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:341
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:351 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:351
@@ -469,8 +466,7 @@ msgstr "Antal reserver"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:353 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:353
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:363 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:363
msgid "0 backup tunnels (0 redundancy, no added resource usage)" msgid "0 backup tunnels (0 redundancy, no added resource usage)"
msgstr "" msgstr "0 reserv tunnlar i varje riktning (ingen redundans, ingen resursanvändning)"
"0 reserv tunnlar i varje riktning (ingen redundans, ingen resursanvändning)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:357 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:357
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:367 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:367
@@ -481,15 +477,12 @@ msgstr "1 reserv tunnel i varje riktning (låg redundans, låg resursanvändning
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:371 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:371
msgid "" msgid ""
"2 backup tunnels each direction (medium redundancy, medium resource usage)" "2 backup tunnels each direction (medium redundancy, medium resource usage)"
msgstr "" msgstr "2 reserv tunnlar i varje riktning (medel hög redundans, medel hög resursanvändning)"
"2 reserv tunnlar i varje riktning (medel hög redundans, medel hög "
"resursanvändning)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:365 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:365
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:375 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:375
msgid "3 backup tunnels each direction (high redundancy, high resource usage)" msgid "3 backup tunnels each direction (high redundancy, high resource usage)"
msgstr "" msgstr "3 reserv tunnlar i varje riktning (hög redundans, hög resursanvändning)"
"3 reserv tunnlar i varje riktning (hög redundans, hög resursanvändning)"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:373 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:373
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:383 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:383
@@ -821,7 +814,7 @@ msgstr "förhandsvisning"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:129 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:129
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:192 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:192
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:265 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:265
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:312 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:306
msgid "Status" msgid "Status"
msgstr "Status" msgstr "Status"
@@ -834,30 +827,30 @@ msgid "No Preview"
msgstr "Ingen förhandsvisning" msgstr "Ingen förhandsvisning"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:199 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:199
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:319 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:313
msgid "Starting..." msgid "Starting..."
msgstr "Startar..." msgstr "Startar..."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:206 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:206
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:220 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:220
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:326 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:320
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:340 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:334
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:354 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:348
msgid "Stop" msgid "Stop"
msgstr "Stopp" msgstr "Stopp"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:213 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:213
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:347 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:341
msgid "Running" msgid "Running"
msgstr "Kör" msgstr "Kör"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:227 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:227
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:361 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:355
msgid "Stopped" msgid "Stopped"
msgstr "Stoppad" msgstr "Stoppad"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:234 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:234
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:368 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:362
msgid "Start" msgid "Start"
msgstr "Start" msgstr "Start"
@@ -866,7 +859,7 @@ msgid "New server tunnel"
msgstr "Ny severtunnel " msgstr "Ny severtunnel "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:251
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:409 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:403
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:223 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:223
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:265 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:265
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:295 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:295
@@ -876,7 +869,7 @@ msgid "Standard"
msgstr "Standard" msgstr "Standard"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:253
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:411 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:405
msgid "Create" msgid "Create"
msgstr "Skapa" msgstr "Skapa"
@@ -885,23 +878,23 @@ msgid "I2P Client Tunnels"
msgstr "I2P Klienttunnel" msgstr "I2P Klienttunnel"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:263 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:263
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:298 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:292
msgid "Interface" msgid "Interface"
msgstr "Gränssnitt " msgstr "Gränssnitt "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:333 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:327
msgid "Standby" msgid "Standby"
msgstr "Standby" msgstr "Standby"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:377 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:371
msgid "Outproxy" msgid "Outproxy"
msgstr "Utproxy" msgstr "Utproxy"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:394 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:388
msgid "none" msgid "none"
msgstr "Ingen" msgstr "Ingen"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:407 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:401
msgid "New client tunnel" msgid "New client tunnel"
msgstr "Ny klienttunnel" msgstr "Ny klienttunnel"
@@ -945,33 +938,27 @@ msgstr "Guiden färdig "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:189 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:189
msgid "" msgid ""
"This wizard will take you through the various options available for creating " "This wizard will take you through the various options available for creating"
"tunnels in I2P." " tunnels in I2P."
msgstr "" msgstr "Guiden tar dig igenom de olika inställningsmöjligheterna för att skapa tunnlar."
"Guiden tar dig igenom de olika inställningsmöjligheterna för att skapa "
"tunnlar."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:191 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:191
msgid "" msgid ""
"The first thing to decide is whether you want to create a server or a client " "The first thing to decide is whether you want to create a server or a client"
"tunnel." " tunnel."
msgstr "" msgstr "Det första är att bestämma om det skall vara en server- eller klient-tunnel. "
"Det första är att bestämma om det skall vara en server- eller klient-tunnel. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:193 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:193
msgid "" msgid ""
"If you need to connect to a remote service, such as an IRC server inside I2P " "If you need to connect to a remote service, such as an IRC server inside I2P"
"or a code repository, then you will require a CLIENT tunnel." " or a code repository, then you will require a CLIENT tunnel."
msgstr "" msgstr "Om du ansluter till en fjärrtjänst så som tex en IRC-server inom I2P, behövs en KLIENT-tunnel. "
"Om du ansluter till en fjärrtjänst så som tex en IRC-server inom I2P, behövs "
"en KLIENT-tunnel. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:195 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:195
msgid "" msgid ""
"On the other hand, if you wish to host a service for others to connect to " "On the other hand, if you wish to host a service for others to connect to "
"you'll need to create a SERVER tunnel." "you'll need to create a SERVER tunnel."
msgstr "" msgstr "Men om du vill göra en tjänst tillgänglig för andra behövs en SERVER-tunnel."
"Men om du vill göra en tjänst tillgänglig för andra behövs en SERVER-tunnel."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:197 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:197
msgid "Server Tunnel" msgid "Server Tunnel"
@@ -987,32 +974,25 @@ msgstr "Det finns flera typer av tunnlar att välja på:"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:225 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:225
msgid "Basic tunnel for connecting to a single service inside I2P." msgid "Basic tunnel for connecting to a single service inside I2P."
msgstr "" msgstr "Grundläggande tunnel för anslutning till en snigel tjänst innanför I2P. "
"Grundläggande tunnel för anslutning till en snigel tjänst innanför I2P. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:227 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:227
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:269 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:269
msgid "" msgid ""
"Try this if none of the tunnel types below fit your requirements, or you " "Try this if none of the tunnel types below fit your requirements, or you "
"don't know what type of tunnel you need." "don't know what type of tunnel you need."
msgstr "" msgstr "Prova detta om ingen av valen passar eller du inte vet vilken typ av tunnel som behövs."
"Prova detta om ingen av valen passar eller du inte vet vilken typ av tunnel "
"som behövs."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:229 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:229
msgid "Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P." msgid "Tunnel that acts as an HTTP proxy for reaching eepsites inside I2P."
msgstr "" msgstr "Tunneln agerar som en HTTP-proxy för att komma åt eepsites innanför I2P. "
"Tunneln agerar som en HTTP-proxy för att komma åt eepsites innanför I2P. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:231 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:231
msgid "" msgid ""
"Set your browser to use this tunnel as an http proxy, or set your " "Set your browser to use this tunnel as an http proxy, or set your "
"\"http_proxy\" environment variable for command-line applications in GNU/" "\"http_proxy\" environment variable for command-line applications in "
"Linux." "GNU/Linux."
msgstr "" msgstr "Peka din webbläsare på denna tunnel som en http-proxy eller ställ in miljövariabeln \"http_proxy\" för terminal baserade applikationer i GNU/Linux."
"Peka din webbläsare på denna tunnel som en http-proxy eller ställ in "
"miljövariabeln \"http_proxy\" för terminal baserade applikationer i GNU/"
"Linux."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:233 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:233
msgid "" msgid ""
@@ -1034,9 +1014,7 @@ msgstr "Med denna tunneltyp kan IRC-klienter ansluta till IRC-nät inom I2P "
msgid "" msgid ""
"Each IRC network in I2P that you wish to connect to will require its own " "Each IRC network in I2P that you wish to connect to will require its own "
"tunnel. (See Also, SOCKS IRC)" "tunnel. (See Also, SOCKS IRC)"
msgstr "" msgstr "Varje IRC-nät inom I2P som du vill ansluta till kräver en egen tunnel (Se även: SOCKS IRC) "
"Varje IRC-nät inom I2P som du vill ansluta till kräver en egen tunnel (Se "
"även: SOCKS IRC) "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:241 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:241
msgid "A tunnel that implements the SOCKS protocol." msgid "A tunnel that implements the SOCKS protocol."
@@ -1046,9 +1024,7 @@ msgstr "En tunnel som implementerar SOCKS protokollet."
msgid "" msgid ""
"This enables both TCP and UDP connections to be made through a SOCKS " "This enables both TCP and UDP connections to be made through a SOCKS "
"outproxy within I2P." "outproxy within I2P."
msgstr "" msgstr "Detta möjliggör både TCP och UDP anslutningar genom SOCKS utgående-proxy innanför I2P "
"Detta möjliggör både TCP och UDP anslutningar genom SOCKS utgående-proxy "
"innanför I2P "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:245 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:245
msgid "" msgid ""
@@ -1061,27 +1037,20 @@ msgid ""
"With this tunnel type, IRC networks in I2P can be reached by typing the I2P " "With this tunnel type, IRC networks in I2P can be reached by typing the I2P "
"address into your IRC client, and configuring the IRC client to use this " "address into your IRC client, and configuring the IRC client to use this "
"SOCKS tunnel." "SOCKS tunnel."
msgstr "" msgstr "Med denna tunnel typen kan IRC-nät inom I2P nås genom att skriva in I2P adressen i IRC-klienten och konfigurera IRC-klienten att använda denna SOCKS-tunneln."
"Med denna tunnel typen kan IRC-nät inom I2P nås genom att skriva in I2P "
"adressen i IRC-klienten och konfigurera IRC-klienten att använda denna SOCKS-"
"tunneln."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:249 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:249
msgid "" msgid ""
"This means that only one I2P tunnel is required rather than a separate " "This means that only one I2P tunnel is required rather than a separate "
"tunnel per IRC network." "tunnel per IRC network."
msgstr "" msgstr "Detta innebär att enbart en I2P-tunnel behövs istället för en tunnel per IRC-nät."
"Detta innebär att enbart en I2P-tunnel behövs istället för en tunnel per IRC-"
"nät."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:251 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:251
msgid "" msgid ""
"IRC networks outside I2P can also be reached if a SOCKS outproxy within I2P " "IRC networks outside I2P can also be reached if a SOCKS outproxy within I2P "
"is known, though it depends on whether or not the outproxy has been blocked " "is known, though it depends on whether or not the outproxy has been blocked "
"by the IRC network." "by the IRC network."
msgstr "" msgstr "IRC-nät utanför I2P kan nås om en SOCKS-proxy innanför I2P är känd, men det bror på om utgående-proxy har blockerats av IRC-nätet."
"IRC-nät utanför I2P kan nås om en SOCKS-proxy innanför I2P är känd, men det "
"bror på om utgående-proxy har blockerats av IRC-nätet."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:253 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:253
msgid "A client tunnel that implements the HTTP CONNECT command." msgid "A client tunnel that implements the HTTP CONNECT command."
@@ -1091,9 +1060,7 @@ msgstr "En klient-tunnel som implementerar HTTP CONNECT kommandot. "
msgid "" msgid ""
"This enables TCP connections to be made through an HTTP outproxy, assuming " "This enables TCP connections to be made through an HTTP outproxy, assuming "
"the proxy supports the CONNECT command." "the proxy supports the CONNECT command."
msgstr "" msgstr "Detta möjliggör TCP anslutningar genom en HTTP utgående-proxy om proxyn stödjer CONNECT kommandot"
"Detta möjliggör TCP anslutningar genom en HTTP utgående-proxy om proxyn "
"stödjer CONNECT kommandot"
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:257 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:257
msgid "A customised client tunnel for Streamr." msgid "A customised client tunnel for Streamr."
@@ -1115,9 +1082,7 @@ msgstr "Använd denna denna typ av tunnel om du vill köra en eepsite."
msgid "" msgid ""
"A customised server tunnel that can both serve HTTP data and connect to " "A customised server tunnel that can both serve HTTP data and connect to "
"other server tunnels." "other server tunnels."
msgstr "" msgstr "En anpassad server tunnel som hanterar både HTTP data och anslutningar till andra server-tunnlar."
"En anpassad server tunnel som hanterar både HTTP data och anslutningar till "
"andra server-tunnlar."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:277 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:277
msgid "This tunnel type is predominantly used when running a Seedless server." msgid "This tunnel type is predominantly used when running a Seedless server."
@@ -1131,9 +1096,7 @@ msgstr "En server-tunnel för IRC-Nät innanför I2P."
msgid "" msgid ""
"Usually, a separate tunnel needs to be created for each IRC server that is " "Usually, a separate tunnel needs to be created for each IRC server that is "
"to be accessible inside I2P." "to be accessible inside I2P."
msgstr "" msgstr "Vanligtvis behövs en separat tunnel för varje IRC-server som skall anslutas till innanför I2P."
"Vanligtvis behövs en separat tunnel för varje IRC-server som skall anslutas "
"till innanför I2P."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:283 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:283
msgid "A customised server tunnel for Streamr." msgid "A customised server tunnel for Streamr."
@@ -1147,17 +1110,13 @@ msgstr "Välj namn och beskrivning av tunneln."
msgid "" msgid ""
"These can be anything you want - they are just for ease of identifying the " "These can be anything you want - they are just for ease of identifying the "
"tunnel in the routerconsole." "tunnel in the routerconsole."
msgstr "" msgstr "Kan vad som helst, används enbart för att enkelt identifiera tunneln i routerkonsolen "
"Kan vad som helst, används enbart för att enkelt identifiera tunneln i "
"routerkonsolen "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:354 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:354
msgid "" msgid ""
"If you know of any outproxies for this type of tunnel (either HTTP or " "If you know of any outproxies for this type of tunnel (either HTTP or "
"SOCKS), fill them in below." "SOCKS), fill them in below."
msgstr "" msgstr "Om du känner till några utgående proxies för denna typen av tunnlar (HTTP eller SOCKS), fyll i dem nedan. "
"Om du känner till några utgående proxies för denna typen av tunnlar (HTTP "
"eller SOCKS), fyll i dem nedan. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:356 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:356
msgid "Separate multiple proxies with commas." msgid "Separate multiple proxies with commas."
@@ -1179,9 +1138,7 @@ msgstr "Kan vara hela base 64 målsnyckeln eller en I2P URL från adressboken."
msgid "" msgid ""
"This is the IP that your service is running on, this is usually on the same " "This is the IP that your service is running on, this is usually on the same "
"machine so 127.0.0.1 is autofilled." "machine so 127.0.0.1 is autofilled."
msgstr "" msgstr "Detta är IP-adressen som tjänsten körs på, detta är vanligtvis på samma maskin så 127.0.0.1 fylls i automatiskt. "
"Detta är IP-adressen som tjänsten körs på, detta är vanligtvis på samma "
"maskin så 127.0.0.1 fylls i automatiskt. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:429 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:429
msgid "This is the port that the service is accepting connections on." msgid "This is the port that the service is accepting connections on."
@@ -1199,9 +1156,7 @@ msgstr "Detta är också en klient-port för HTTPBidir server-tunneln."
msgid "" msgid ""
"How do you want this tunnel to be accessed? By just this machine, your " "How do you want this tunnel to be accessed? By just this machine, your "
"entire subnet, or external internet?" "entire subnet, or external internet?"
msgstr "" msgstr "Hur du vill att tunneln ska nås? Enbart denna maskinen, ditt lokala nät eller hela internet? "
"Hur du vill att tunneln ska nås? Enbart denna maskinen, ditt lokala nät "
"eller hela internet? "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:473 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:473
msgid "You will most likely want to just allow 127.0.0.1" msgid "You will most likely want to just allow 127.0.0.1"
@@ -1218,10 +1173,7 @@ msgid ""
"This can be useful for frequently-used tunnels (especially server tunnels), " "This can be useful for frequently-used tunnels (especially server tunnels), "
"but for tunnels that are only used occassionally it would mean that the I2P " "but for tunnels that are only used occassionally it would mean that the I2P "
"router is creating and maintaining unnecessary tunnels." "router is creating and maintaining unnecessary tunnels."
msgstr "" msgstr "Detta kan vara användbart för tunnlar som används ofta (tex server-tunnlar) men för tunnlar som används sällan innebär det att onödiga tunnlar upprättas. "
"Detta kan vara användbart för tunnlar som används ofta (tex server-tunnlar) "
"men för tunnlar som används sällan innebär det att onödiga tunnlar "
"upprättas. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:543 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:543
msgid "The wizard has now collected enough information to create your tunnel." msgid "The wizard has now collected enough information to create your tunnel."
@@ -1231,17 +1183,13 @@ msgstr "Guiden hat samlat tillräckligt med information för att skapa tunneln.
msgid "" msgid ""
"Upon clicking the Save button below, the wizard will set up the tunnel, and " "Upon clicking the Save button below, the wizard will set up the tunnel, and "
"take you back to the main I2PTunnel page." "take you back to the main I2PTunnel page."
msgstr "" msgstr "När du klickar på \"spara\" kommer guiden att skapa tunneln och sedan ta dig till sidan för tunnlar."
"När du klickar på \"spara\" kommer guiden att skapa tunneln och sedan ta dig "
"till sidan för tunnlar."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:550 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:550
msgid "" msgid ""
"Because you chose to automatically start the tunnel when the router starts, " "Because you chose to automatically start the tunnel when the router starts, "
"you don't have to do anything further." "you don't have to do anything further."
msgstr "" msgstr "Efter som du valt att starta tunneln samtidigt som routern startas behövs inget mer göras. "
"Efter som du valt att starta tunneln samtidigt som routern startas behövs "
"inget mer göras. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:552 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:552
msgid "The router will start the tunnel once it has been set up." msgid "The router will start the tunnel once it has been set up."
@@ -1251,9 +1199,7 @@ msgstr "Routern starta tunneln när den skapats. "
msgid "" msgid ""
"Because you chose not to automatically start the tunnel, you will have to " "Because you chose not to automatically start the tunnel, you will have to "
"manually start it." "manually start it."
msgstr "" msgstr "Efter som du valt att inte starta tunneln samtidigt som routern startas, behövs den startas manuellt."
"Efter som du valt att inte starta tunneln samtidigt som routern startas, "
"behövs den startas manuellt."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:558 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:558
msgid "" msgid ""
@@ -1269,18 +1215,14 @@ msgstr "Nedan är en sammanfattning över valen du kan göra:"
msgid "" msgid ""
"Alongside these basic settings, there are a number of advanced options for " "Alongside these basic settings, there are a number of advanced options for "
"tunnel configuration." "tunnel configuration."
msgstr "" msgstr "Vid sidan om dessa grundägande inställningar finns att par avancerade val för tunneln. "
"Vid sidan om dessa grundägande inställningar finns att par avancerade val "
"för tunneln. "
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:662 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:662
msgid "" msgid ""
"The wizard will set reasonably sensible default values for these, but you " "The wizard will set reasonably sensible default values for these, but you "
"can view and/or edit these by clicking on the tunnel's name in the main " "can view and/or edit these by clicking on the tunnel's name in the main "
"I2PTunnel page." "I2PTunnel page."
msgstr "" msgstr "Guiden väljer lämpliga värden för dessa. Men du kan ändra/se värdena på huvudsidan för I2P-tunnlar."
"Guiden väljer lämpliga värden för dessa. Men du kan ändra/se värdena på "
"huvudsidan för I2P-tunnlar."
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:704 #: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:704
msgid "Previous" msgid "Previous"

View File

@@ -0,0 +1,170 @@
package net.i2p.jetty;
// Contains code from org.mortbay.xml.XmlConfiguation:
// ========================================================================
// Copyright 2004-2005 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.app.*;
import static net.i2p.app.ClientAppState.*;
import org.mortbay.component.LifeCycle;
import org.mortbay.resource.Resource;
import org.mortbay.xml.XmlConfiguration;
/**
* Start Jetty where the args are one or more XML files.
* Save a reference to the Server so it can be cleanly stopped later.
*
* This is like XmlConfiguration.main(), which is essentially what
* org.mortbay.start.Main does.
*
* @since 0.9.4
*/
public class JettyStart implements ClientApp {
private final I2PAppContext _context;
private final ClientAppManager _mgr;
private final String[] _args;
private final List<LifeCycle> _jettys;
private volatile ClientAppState _state;
/**
* All args must be XML file names.
* Does not support any of the other argument types from org.mortbay.start.Main.
*/
public JettyStart(I2PAppContext context, ClientAppManager mgr, String[] args) throws Exception {
_state = UNINITIALIZED;
_context = context;
_mgr = mgr;
_args = args;
_jettys = new ArrayList(args.length);
parseArgs(args);
_state = INITIALIZED;
}
/**
* Modified from XmlConfiguration.main()
*/
public void parseArgs(String[] args) throws Exception {
Properties properties=new Properties();
XmlConfiguration last=null;
for (int i = 0; i < args.length; i++) {
if (args[i].toLowerCase().endsWith(".properties")) {
properties.load(Resource.newResource(args[i]).getInputStream());
} else {
XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(args[i]).getURL());
if (last!=null)
configuration.getIdMap().putAll(last.getIdMap());
if (properties.size()>0)
configuration.setProperties(properties);
Object o = configuration.configure();
if (o instanceof LifeCycle)
_jettys.add((LifeCycle)o);
last=configuration;
}
}
}
public void startup() {
if (_state != INITIALIZED)
return;
if (_jettys.isEmpty()) {
changeState(START_FAILED);
} else {
(new Starter()).start();
}
}
private class Starter extends Thread {
public Starter() {
super("JettyStarter");
}
/**
* Modified from XmlConfiguration.main()
*/
public void run() {
changeState(STARTING);
for (LifeCycle lc : _jettys) {
if (!lc.isRunning()) {
try {
lc.start();
} catch (Exception e) {
changeState(START_FAILED, e);
return;
}
}
}
changeState(RUNNING);
}
}
public void shutdown(String[] args) {
if (_state != RUNNING)
return;
if (_jettys.isEmpty()) {
changeState(STOPPED);
} else {
(new Stopper()).start();
}
}
private class Stopper extends Thread {
public Stopper() {
super("JettyStopper");
}
public void run() {
changeState(STOPPING);
for (LifeCycle lc : _jettys) {
if (lc.isRunning()) {
try {
lc.stop();
} catch (Exception e) {
changeState(STOPPING, e);
}
}
}
changeState(STOPPED);
}
}
public ClientAppState getState() {
return _state;
}
public String getName() {
return "Jetty";
}
public String getDisplayName() {
return "Jetty " + Arrays.toString(_args);
}
private void changeState(ClientAppState state) {
changeState(state, null);
}
private synchronized void changeState(ClientAppState state, Exception e) {
_state = state;
_mgr.notify(this, state, null, e);
}
}

View File

@@ -18,15 +18,15 @@ import java.util.TreeMap;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
import net.i2p.data.Hash; import net.i2p.data.Hash;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.router.Shitlist; import net.i2p.router.Banlist;
/** /**
* Moved from Shitlist.java * Moved from Banlist.java
*/ */
public class ShitlistRenderer { public class BanlistRenderer {
private final RouterContext _context; private final RouterContext _context;
public ShitlistRenderer(RouterContext context) { public BanlistRenderer(RouterContext context) {
_context = context; _context = context;
} }
@@ -40,9 +40,9 @@ public class ShitlistRenderer {
StringBuilder buf = new StringBuilder(1024); StringBuilder buf = new StringBuilder(1024);
// move to the jsp // move to the jsp
//buf.append("<h2>Banned Peers</h2>"); //buf.append("<h2>Banned Peers</h2>");
Map<Hash, Shitlist.Entry> entries = new TreeMap(new HashComparator()); Map<Hash, Banlist.Entry> entries = new TreeMap(new HashComparator());
entries.putAll(_context.shitlist().getEntries()); entries.putAll(_context.banlist().getEntries());
if (entries.isEmpty()) { if (entries.isEmpty()) {
buf.append("<i>").append(_("none")).append("</i>"); buf.append("<i>").append(_("none")).append("</i>");
out.write(buf.toString()); out.write(buf.toString());
@@ -51,9 +51,9 @@ public class ShitlistRenderer {
buf.append("<ul>"); buf.append("<ul>");
for (Map.Entry<Hash, Shitlist.Entry> e : entries.entrySet()) { for (Map.Entry<Hash, Banlist.Entry> e : entries.entrySet()) {
Hash key = e.getKey(); Hash key = e.getKey();
Shitlist.Entry entry = e.getValue(); Banlist.Entry entry = e.getValue();
long expires = entry.expireOn-_context.clock().now(); long expires = entry.expireOn-_context.clock().now();
if (expires <= 0) if (expires <= 0)
continue; continue;

View File

@@ -23,7 +23,6 @@ import org.mortbay.jetty.handler.ContextHandlerCollection;
* Saves changes to clients.config or webapps.config * Saves changes to clients.config or webapps.config
*/ */
public class ConfigClientsHandler extends FormHandler { public class ConfigClientsHandler extends FormHandler {
private Map _settings;
@Override @Override
protected void processForm() { protected void processForm() {
@@ -171,8 +170,6 @@ public class ConfigClientsHandler extends FormHandler {
} }
public void setSettings(Map settings) { _settings = new HashMap(settings); }
private void saveClientChanges() { private void saveClientChanges() {
List<ClientAppConfig> clients = ClientAppConfig.getClientApps(_context); List<ClientAppConfig> clients = ClientAppConfig.getClientApps(_context);
for (int cur = 0; cur < clients.size(); cur++) { for (int cur = 0; cur < clients.size(); cur++) {
@@ -216,15 +213,8 @@ public class ConfigClientsHandler extends FormHandler {
} }
ClientAppConfig.writeClientAppConfig(_context, clients); ClientAppConfig.writeClientAppConfig(_context, clients);
addFormNotice(_("Client configuration saved successfully - restart required to take effect.")); addFormNotice(_("Client configuration saved successfully"));
} addFormNotice(_("Restart required to take effect"));
/** curses Jetty for returning arrays */
private String getJettyString(String key) {
String[] arr = (String[]) _settings.get(key);
if (arr == null)
return null;
return arr[0].trim();
} }
// STUB for stopClient, not completed yet. // STUB for stopClient, not completed yet.
@@ -248,7 +238,7 @@ public class ConfigClientsHandler extends FormHandler {
return; return;
} }
ClientAppConfig ca = clients.get(i); ClientAppConfig ca = clients.get(i);
LoadClientAppsJob.runClient(ca.className, ca.clientName, LoadClientAppsJob.parseArgs(ca.args), _log); LoadClientAppsJob.runClient(ca.className, ca.clientName, LoadClientAppsJob.parseArgs(ca.args), _context, _log);
addFormNotice(_("Client") + ' ' + _(ca.clientName) + ' ' + _("started") + '.'); addFormNotice(_("Client") + ' ' + _(ca.clientName) + ' ' + _("started") + '.');
} }
@@ -264,7 +254,7 @@ public class ConfigClientsHandler extends FormHandler {
} }
private void saveWebAppChanges() { private void saveWebAppChanges() {
Properties props = RouterConsoleRunner.webAppProperties(); Properties props = RouterConsoleRunner.webAppProperties(_context);
Set keys = props.keySet(); Set keys = props.keySet();
for (Iterator iter = keys.iterator(); iter.hasNext(); ) { for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
String name = (String)iter.next(); String name = (String)iter.next();
@@ -275,7 +265,7 @@ public class ConfigClientsHandler extends FormHandler {
if (! RouterConsoleRunner.ROUTERCONSOLE.equals(app)) if (! RouterConsoleRunner.ROUTERCONSOLE.equals(app))
props.setProperty(name, "" + (val != null)); props.setProperty(name, "" + (val != null));
} }
RouterConsoleRunner.storeWebAppProperties(props); RouterConsoleRunner.storeWebAppProperties(_context, props);
addFormNotice(_("WebApp configuration saved.")); addFormNotice(_("WebApp configuration saved."));
} }
@@ -416,11 +406,12 @@ public class ConfigClientsHandler extends FormHandler {
if (intfc != null) if (intfc != null)
changes.put(ClientManagerFacadeImpl.PROP_CLIENT_HOST, intfc); changes.put(ClientManagerFacadeImpl.PROP_CLIENT_HOST, intfc);
String user = getJettyString("user"); String user = getJettyString("user");
if (user != null)
changes.put(ConfigClientsHelper.PROP_USER, user);
String pw = getJettyString("pw"); String pw = getJettyString("pw");
if (pw != null) if (user != null && pw != null && user.length() > 0 && pw.length() > 0) {
changes.put(ConfigClientsHelper.PROP_PW, pw); ConsolePasswordManager mgr = new ConsolePasswordManager(_context);
mgr.saveHash(ConfigClientsHelper.PROP_AUTH, user, pw);
addFormNotice(_("Added user {0}", user));
}
String mode = getJettyString("mode"); String mode = getJettyString("mode");
boolean disabled = "0".equals(mode); boolean disabled = "0".equals(mode);
boolean ssl = "2".equals(mode); boolean ssl = "2".equals(mode);
@@ -433,9 +424,10 @@ public class ConfigClientsHandler extends FormHandler {
boolean all = "0.0.0.0".equals(intfc) || "0:0:0:0:0:0:0:0".equals(intfc) || boolean all = "0.0.0.0".equals(intfc) || "0:0:0:0:0:0:0:0".equals(intfc) ||
"::".equals(intfc); "::".equals(intfc);
changes.put(ConfigClientsHelper.BIND_ALL_INTERFACES, Boolean.toString(all)); changes.put(ConfigClientsHelper.BIND_ALL_INTERFACES, Boolean.toString(all));
if (_context.router().saveConfig(changes, null)) if (_context.router().saveConfig(changes, null)) {
addFormNotice(_("Interface configuration saved successfully - restart required to take effect.")); addFormNotice(_("Interface configuration saved"));
else addFormNotice(_("Restart required to take effect"));
} else
addFormError(_("Error saving the configuration (applied but not saved) - please see the error logs")); addFormError(_("Error saving the configuration (applied but not saved) - please see the error logs"));
} }
} }

View File

@@ -24,8 +24,6 @@ public class ConfigClientsHelper extends HelperBase {
public static final String PROP_ENABLE_SSL = "i2cp.SSL"; public static final String PROP_ENABLE_SSL = "i2cp.SSL";
/** from ClientMessageEventListener */ /** from ClientMessageEventListener */
public static final String PROP_AUTH = "i2cp.auth"; public static final String PROP_AUTH = "i2cp.auth";
public static final String PROP_USER = "i2cp.username";
public static final String PROP_PW = "i2cp.password";
public ConfigClientsHelper() {} public ConfigClientsHelper() {}
@@ -35,16 +33,6 @@ public class ConfigClientsHelper extends HelperBase {
Integer.toString(ClientManagerFacadeImpl.DEFAULT_PORT)); Integer.toString(ClientManagerFacadeImpl.DEFAULT_PORT));
} }
/** @since 0.8.3 */
public String getUser() {
return _context.getProperty(PROP_USER, "");
}
/** @since 0.8.3 */
public String getPw() {
return _context.getProperty(PROP_PW, "");
}
/** @since 0.8.3 */ /** @since 0.8.3 */
public String i2cpModeChecked(int mode) { public String i2cpModeChecked(int mode) {
boolean disabled = _context.getBooleanProperty(PROP_DISABLE_EXTERNAL); boolean disabled = _context.getBooleanProperty(PROP_DISABLE_EXTERNAL);
@@ -128,7 +116,7 @@ public class ConfigClientsHelper extends HelperBase {
StringBuilder buf = new StringBuilder(1024); StringBuilder buf = new StringBuilder(1024);
buf.append("<table>\n"); buf.append("<table>\n");
buf.append("<tr><th align=\"right\">" + _("WebApp") + "</th><th>" + _("Run at Startup?") + "</th><th>" + _("Control") + "</th><th align=\"left\">" + _("Description") + "</th></tr>\n"); buf.append("<tr><th align=\"right\">" + _("WebApp") + "</th><th>" + _("Run at Startup?") + "</th><th>" + _("Control") + "</th><th align=\"left\">" + _("Description") + "</th></tr>\n");
Properties props = RouterConsoleRunner.webAppProperties(); Properties props = RouterConsoleRunner.webAppProperties(_context);
Set<String> keys = new TreeSet(props.keySet()); Set<String> keys = new TreeSet(props.keySet());
for (Iterator<String> iter = keys.iterator(); iter.hasNext(); ) { for (Iterator<String> iter = keys.iterator(); iter.hasNext(); ) {
String name = iter.next(); String name = iter.next();

View File

@@ -1,11 +1,9 @@
package net.i2p.router.web; package net.i2p.router.web;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Set; import java.util.Set;
import java.util.Map;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
@@ -16,8 +14,6 @@ import net.i2p.data.DataHelper;
*/ */
public class ConfigHomeHandler extends FormHandler { public class ConfigHomeHandler extends FormHandler {
private Map _settings;
@Override @Override
protected void processForm() { protected void processForm() {
if (_action == null) return; if (_action == null) return;
@@ -106,14 +102,4 @@ public class ConfigHomeHandler extends FormHandler {
addFormError(_("Unsupported")); addFormError(_("Unsupported"));
} }
} }
public void setSettings(Map settings) { _settings = new HashMap(settings); }
/** curses Jetty for returning arrays */
private String getJettyString(String key) {
String[] arr = (String[]) _settings.get(key);
if (arr == null)
return null;
return arr[0].trim();
}
} }

View File

@@ -280,9 +280,10 @@ public class ConfigNetHandler extends FormHandler {
_upnp) { _upnp) {
// This is minor, don't set restartRequired // This is minor, don't set restartRequired
if (_upnp) if (_upnp)
addFormNotice(_("Enabling UPnP, restart required to take effect")); addFormNotice(_("Enabling UPnP"));
else else
addFormNotice(_("Disabling UPnP, restart required to take effect")); addFormNotice(_("Disabling UPnP"));
addFormNotice(_("Restart required to take effect"));
} }
changes.put(TransportManager.PROP_ENABLE_UPNP, "" + _upnp); changes.put(TransportManager.PROP_ENABLE_UPNP, "" + _upnp);

View File

@@ -20,7 +20,7 @@ public class ConfigPeerHandler extends FormHandler {
} else if (_action.equals(_("Ban peer until restart"))) { } else if (_action.equals(_("Ban peer until restart"))) {
Hash h = getHash(); Hash h = getHash();
if (h != null) { if (h != null) {
_context.shitlist().shitlistRouterForever(h, _("Manually banned via {0}"), "<a href=\"configpeer\">configpeer</a>"); _context.banlist().banlistRouterForever(h, _("Manually banned via {0}"), "<a href=\"configpeer\">configpeer</a>");
addFormNotice(_("Peer") + " " + _peer + " " + _("banned until restart") ); addFormNotice(_("Peer") + " " + _peer + " " + _("banned until restart") );
return; return;
} }
@@ -28,8 +28,8 @@ public class ConfigPeerHandler extends FormHandler {
} else if (_action.equals(_("Unban peer"))) { } else if (_action.equals(_("Unban peer"))) {
Hash h = getHash(); Hash h = getHash();
if (h != null) { if (h != null) {
if (_context.shitlist().isShitlisted(h)) { if (_context.banlist().isBanlisted(h)) {
_context.shitlist().unshitlistRouter(h); _context.banlist().unbanlistRouter(h);
addFormNotice(_("Peer") + " " + _peer + " " + _("unbanned") ); addFormNotice(_("Peer") + " " + _peer + " " + _("unbanned") );
} else } else
addFormNotice(_("Peer") + " " + _peer + " " + _("is not currently banned") ); addFormNotice(_("Peer") + " " + _peer + " " + _("is not currently banned") );

View File

@@ -11,7 +11,6 @@ import net.i2p.router.networkdb.reseed.Reseeder;
* @since 0.8.3 * @since 0.8.3
*/ */
public class ConfigReseedHandler extends FormHandler { public class ConfigReseedHandler extends FormHandler {
private Map _settings;
private final Map<String, String> changes = new HashMap(); private final Map<String, String> changes = new HashMap();
private final List<String> removes = new ArrayList(); private final List<String> removes = new ArrayList();
@@ -35,16 +34,6 @@ public class ConfigReseedHandler extends FormHandler {
addFormError(_("Unsupported") + ' ' + _action + '.'); addFormError(_("Unsupported") + ' ' + _action + '.');
} }
public void setSettings(Map settings) { _settings = new HashMap(settings); }
/** curses Jetty for returning arrays */
private String getJettyString(String key) {
String[] arr = (String[]) _settings.get(key);
if (arr == null)
return null;
return arr[0].trim();
}
/** @since 0.8.9 */ /** @since 0.8.9 */
private void saveString(String config, String param) { private void saveString(String config, String param) {
String val = getJettyString(param); String val = getJettyString(param);

View File

@@ -8,6 +8,7 @@ import net.i2p.apps.systray.UrlLauncher;
import net.i2p.router.Router; import net.i2p.router.Router;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.router.startup.ClientAppConfig; import net.i2p.router.startup.ClientAppConfig;
import net.i2p.util.PortMapper;
import net.i2p.util.SystemVersion; import net.i2p.util.SystemVersion;
import net.i2p.util.VersionComparator; import net.i2p.util.VersionComparator;
@@ -257,7 +258,9 @@ public class ConfigServiceHandler extends FormHandler {
} }
// releases <= 0.6.5 deleted the entry completely // releases <= 0.6.5 deleted the entry completely
if (shouldLaunchBrowser && !found) { if (shouldLaunchBrowser && !found) {
ClientAppConfig ca = new ClientAppConfig(UrlLauncher.class.getName(), "consoleBrowser", "http://127.0.0.1:7657", 5, false); int port = _context.portMapper().getPort(PortMapper.SVC_CONSOLE, RouterConsoleRunner.DEFAULT_LISTEN_PORT);
ClientAppConfig ca = new ClientAppConfig(UrlLauncher.class.getName(), "consoleBrowser",
"http://127.0.0.1:" + port + '/', 5, false);
clients.add(ca); clients.add(ca);
} }
ClientAppConfig.writeClientAppConfig(_context, clients); ClientAppConfig.writeClientAppConfig(_context, clients);

View File

@@ -116,9 +116,10 @@ public class ConfigStatsHandler extends FormHandler {
addFormNotice(_("Stat filter and location updated successfully to") + ": " + stats.toString()); addFormNotice(_("Stat filter and location updated successfully to") + ": " + stats.toString());
if (fullChanged) { if (fullChanged) {
if (_isFull) if (_isFull)
addFormNotice(_("Full statistics enabled - restart required to take effect")); addFormNotice(_("Full statistics enabled"));
else else
addFormNotice(_("Full statistics disabled - restart required to take effect")); addFormNotice(_("Full statistics disabled"));
addFormNotice(_("Restart required to take effect"));
} }
if (graphsChanged) if (graphsChanged)
addFormNotice(_("Graph list updated, may take up to 60s to be reflected here and on the <a href=\"graphs.jsp\">Graphs Page</a>")); addFormNotice(_("Graph list updated, may take up to 60s to be reflected here and on the <a href=\"graphs.jsp\">Graphs Page</a>"));

View File

@@ -1,7 +1,6 @@
package net.i2p.router.web; package net.i2p.router.web;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
@@ -17,8 +16,6 @@ import net.i2p.data.DataHelper;
*/ */
public class ConfigSummaryHandler extends FormHandler { public class ConfigSummaryHandler extends FormHandler {
private Map _settings;
@Override @Override
protected void processForm() { protected void processForm() {
if (_action == null) return; if (_action == null) return;
@@ -144,16 +141,6 @@ public class ConfigSummaryHandler extends FormHandler {
} }
} }
public void setSettings(Map settings) { _settings = new HashMap(settings); }
/** curses Jetty for returning arrays */
private String getJettyString(String key) {
String[] arr = (String[]) _settings.get(key);
if (arr == null)
return null;
return arr[0].trim();
}
public void setMovingAction() { public void setMovingAction() {
for (Object o : _settings.keySet()) { for (Object o : _settings.keySet()) {
if (!(o instanceof String)) if (!(o instanceof String))

View File

@@ -13,8 +13,13 @@ public class ConfigUIHandler extends FormHandler {
@Override @Override
protected void processForm() { protected void processForm() {
if (_shouldSave) if (_shouldSave) {
saveChanges(); saveChanges();
} else if (_action.equals(_("Delete selected"))) {
delUser();
} else if (_action.equals(_("Add user"))) {
addUser();
}
} }
public void setShouldsave(String moo) { _shouldSave = true; } public void setShouldsave(String moo) { _shouldSave = true; }
@@ -51,4 +56,48 @@ public class ConfigUIHandler extends FormHandler {
addFormError(_("Error saving the configuration (applied but not saved) - please see the error logs.")); addFormError(_("Error saving the configuration (applied but not saved) - please see the error logs."));
} }
} }
private void addUser() {
String name = getJettyString("name");
if (name == null || name.length() <= 0) {
addFormError(_("No user name entered"));
return;
}
String pw = getJettyString("pw");
if (pw == null || pw.length() <= 0) {
addFormError(_("No password entered"));
return;
}
ConsolePasswordManager mgr = new ConsolePasswordManager(_context);
// rfc 2617
if (mgr.saveMD5(RouterConsoleRunner.PROP_CONSOLE_PW, RouterConsoleRunner.JETTY_REALM, name, pw)) {
if (!_context.getBooleanProperty(RouterConsoleRunner.PROP_PW_ENABLE))
_context.router().saveConfig(RouterConsoleRunner.PROP_PW_ENABLE, "true");
addFormNotice(_("Added user {0}", name));
addFormNotice(_("Restart required to take effect"));
} else {
addFormError(_("Error saving the configuration (applied but not saved) - please see the error logs."));
}
}
private void delUser() {
ConsolePasswordManager mgr = new ConsolePasswordManager(_context);
boolean success = false;
for (Object o : _settings.keySet()) {
if (!(o instanceof String))
continue;
String k = (String) o;
if (!k.startsWith("delete_"))
continue;
k = k.substring(7);
if (mgr.remove(RouterConsoleRunner.PROP_CONSOLE_PW, k)) {
addFormNotice(_("Removed user {0}", k));
success = true;
} else {
addFormError(_("Error saving the configuration (applied but not saved) - please see the error logs."));
}
}
if (success)
addFormNotice(_("Restart required to take effect"));
}
} }

View File

@@ -2,8 +2,9 @@ package net.i2p.router.web;
import java.io.File; import java.io.File;
import java.util.Iterator; import java.util.Iterator;
import java.util.TreeSet; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeSet;
public class ConfigUIHelper extends HelperBase { public class ConfigUIHelper extends HelperBase {
@@ -87,4 +88,38 @@ public class ConfigUIHelper extends HelperBase {
} }
return buf.toString(); return buf.toString();
} }
/** @since 0.9.4 */
public String getPasswordForm() {
StringBuilder buf = new StringBuilder(512);
ConsolePasswordManager mgr = new ConsolePasswordManager(_context);
Map<String, String> userpw = mgr.getMD5(RouterConsoleRunner.PROP_CONSOLE_PW);
buf.append("<table>");
if (userpw.isEmpty()) {
buf.append("<tr><td colspan=\"3\">");
buf.append(_("Add a user and password to enable."));
buf.append("</td></tr>");
} else {
buf.append("<tr><th>")
.append(_("Remove"))
.append("</th><th>")
.append(_("User Name"))
.append("</th><th>&nbsp;</th></tr>\n");
for (String name : userpw.keySet()) {
buf.append("<tr><td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"delete_")
.append(name)
.append("\"></td><td colspan=\"2\">")
.append(name)
.append("</td></tr>\n");
}
}
buf.append("<tr><td align=\"center\"><b>")
.append(_("Add")).append(":</b>" +
"</td><td align=\"left\"><input type=\"text\" name=\"name\">" +
"</td><td align=\"left\"><b>");
buf.append(_("Password")).append(":</b> " +
"<input type=\"password\" size=\"40\" name=\"pw\"></td></tr>" +
"</table>\n");
return buf.toString();
}
} }

View File

@@ -0,0 +1,213 @@
package net.i2p.router.web;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.router.util.RouterPasswordManager;
//import org.mortbay.jetty.security.UnixCrypt;
/**
* Manage both plaintext and salted/hashed password storage in
* router.config.
*
* @since 0.9.4
*/
public class ConsolePasswordManager extends RouterPasswordManager {
private static final String PROP_MIGRATED = "routerconsole.passwordManager.migrated";
// migrate these to hash
private static final String PROP_CONSOLE_OLD = "consolePassword";
private static final String CONSOLE_USER = "admin";
public ConsolePasswordManager(RouterContext ctx) {
super(ctx);
migrateConsole();
}
/**
* The username is the salt
*
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @param pw plain text, already trimmed
* @return if pw verified
*/
/****
public boolean checkCrypt(String realm, String user, String pw) {
String pfx = realm;
if (user != null && user.length() > 0)
pfx += '.' + user;
String cr = _context.getProperty(pfx + PROP_CRYPT);
if (cr == null)
return false;
return cr.equals(UnixCrypt.crypt(pw, cr));
}
****/
/**
* Straight MD5. Compatible with Jetty.
*
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @param pw plain text, already trimmed
* @return if pw verified
*/
public boolean checkMD5(String realm, String subrealm, String user, String pw) {
String pfx = realm;
if (user != null && user.length() > 0)
pfx += '.' + user;
String hex = _context.getProperty(pfx + PROP_MD5);
if (hex == null)
return false;
return hex.equals(md5Hex(subrealm, user, pw));
}
/**
* Get all MD5 usernames and passwords. Compatible with Jetty.
* Any "null" user is NOT included..
*
* @param realm e.g. i2cp, routerconsole, etc.
* @return Map of usernames to passwords (hex with leading zeros, 32 characters)
*/
public Map<String, String> getMD5(String realm) {
String pfx = realm + '.';
Map<String, String> rv = new HashMap(4);
for (Map.Entry<String, String> e : _context.router().getConfigMap().entrySet()) {
String prop = e.getKey();
if (prop.startsWith(pfx) && prop.endsWith(PROP_MD5)) {
String user = prop.substring(0, prop.length() - PROP_MD5.length()).substring(pfx.length());
String hex = e.getValue();
if (user.length() > 0 && hex.length() == 32)
rv.put(user, hex);
}
}
return rv;
}
/**
* Migrate from plaintext to MD5 hash
* Ref: RFC 2617
*
* @return success or nothing to migrate
*/
private boolean migrateConsole() {
synchronized(ConsolePasswordManager.class) {
if (_context.getBooleanProperty(PROP_MIGRATED))
return true;
// consolePassword
String pw = _context.getProperty(PROP_CONSOLE_OLD);
if (pw != null) {
Map toAdd = new HashMap(2);
if (pw.length() > 0) {
saveMD5(RouterConsoleRunner.PROP_CONSOLE_PW, RouterConsoleRunner.JETTY_REALM,
CONSOLE_USER, pw);
toAdd.put(RouterConsoleRunner.PROP_PW_ENABLE, "true");
}
toAdd.put(PROP_MIGRATED, "true");
List toDel = Collections.singletonList(PROP_CONSOLE_OLD);
return _context.router().saveConfig(toAdd, toDel);
}
return true;
}
}
/**
* This will fail if
* user contains '#' or '=' or starts with '!'
* The user is the salt.
*
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @param pw plain text, already trimmed
* @return success
*/
/****
public boolean saveCrypt(String realm, String user, String pw) {
String pfx = realm;
if (user != null && user.length() > 0)
pfx += '.' + user;
String salt = user != null ? user : "";
String crypt = UnixCrypt.crypt(pw, salt);
Map<String, String> toAdd = Collections.singletonMap(pfx + PROP_CRYPT, crypt);
List<String> toDel = new ArrayList(4);
toDel.add(pfx + PROP_PW);
toDel.add(pfx + PROP_B64);
toDel.add(pfx + PROP_MD5);
toDel.add(pfx + PROP_SHASH);
return _context.router().saveConfig(toAdd, toDel);
}
****/
/**
* Straight MD5, no salt
* Compatible with Jetty and RFC 2617.
*
* @param realm The full realm, e.g. routerconsole.auth.i2prouter, etc.
* @param subrealm to be used in creating the checksum
* @param user non-null, non-empty, already trimmed
* @param pw plain text
* @return if pw verified
*/
public boolean saveMD5(String realm, String subrealm, String user, String pw) {
String pfx = realm;
if (user != null && user.length() > 0)
pfx += '.' + user;
String hex = md5Hex(subrealm, user, pw);
if (hex == null)
return false;
Map<String, String> toAdd = Collections.singletonMap(pfx + PROP_MD5, hex);
List<String> toDel = new ArrayList(4);
toDel.add(pfx + PROP_PW);
toDel.add(pfx + PROP_B64);
toDel.add(pfx + PROP_CRYPT);
toDel.add(pfx + PROP_SHASH);
return _context.router().saveConfig(toAdd, toDel);
}
public static void main(String args[]) {
RouterContext ctx = (new Router()).getContext();
ConsolePasswordManager pm = new ConsolePasswordManager(ctx);
if (!pm.migrate())
System.out.println("Fail 1");
if (!pm.migrateConsole())
System.out.println("Fail 1a");
System.out.println("Test plain");
if (!pm.savePlain("type1", "user1", "pw1"))
System.out.println("Fail 2");
if (!pm.checkPlain("type1", "user1", "pw1"))
System.out.println("Fail 3");
System.out.println("Test B64");
if (!pm.saveB64("type2", "user2", "pw2"))
System.out.println("Fail 4");
if (!pm.checkB64("type2", "user2", "pw2"))
System.out.println("Fail 5");
System.out.println("Test MD5");
if (!pm.saveMD5("type3", "realm", "user3", "pw3"))
System.out.println("Fail 6");
if (!pm.checkMD5("type3", "realm", "user3", "pw3"))
System.out.println("Fail 7");
//System.out.println("Test crypt");
//if (!pm.saveCrypt("type4", "user4", "pw4"))
// System.out.println("Fail 8");
//if (!pm.checkCrypt("type4", "user4", "pw4"))
// System.out.println("Fail 9");
System.out.println("Test hash");
if (!pm.saveHash("type5", "user5", "pw5"))
System.out.println("Fail 10");
if (!pm.checkHash("type5", "user5", "pw5"))
System.out.println("Fail 11");
}
}

View File

@@ -1,7 +1,9 @@
package net.i2p.router.web; package net.i2p.router.web;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.util.Log; import net.i2p.util.Log;
@@ -18,16 +20,14 @@ import net.i2p.util.Log;
public class FormHandler { public class FormHandler {
protected RouterContext _context; protected RouterContext _context;
protected Log _log; protected Log _log;
private String _nonce; protected Map _settings;
private String _nonce, _nonce1, _nonce2;
protected String _action; protected String _action;
protected String _method; protected String _method;
protected String _passphrase;
private final List<String> _errors; private final List<String> _errors;
private final List<String> _notices; private final List<String> _notices;
private boolean _processed; private boolean _processed;
private boolean _valid; private boolean _valid;
private static final String NONCE_SUFFIX = ".nonce";
private static final String PREV_SUFFIX = "Prev";
public FormHandler() { public FormHandler() {
_errors = new ArrayList(); _errors = new ArrayList();
@@ -52,7 +52,28 @@ public class FormHandler {
public void setNonce(String val) { _nonce = val; } public void setNonce(String val) { _nonce = val; }
public void setAction(String val) { _action = val; } public void setAction(String val) { _action = val; }
public void setPassphrase(String val) { _passphrase = val; }
/**
* For many forms, it's easiest just to put all the parameters here.
*
* @since 0.9.4 consolidated from numerous FormHandlers
*/
public void setSettings(Map settings) { _settings = new HashMap(settings); }
/**
* setSettings() must have been called previously
* Curses Jetty for returning arrays.
*
* @since 0.9.4 consolidated from numerous FormHandlers
*/
protected String getJettyString(String key) {
if (_settings == null)
return null;
String[] arr = (String[]) _settings.get(key);
if (arr == null)
return null;
return arr[0].trim();
}
/** /**
* Call this to prevent changes using GET * Call this to prevent changes using GET
@@ -62,6 +83,15 @@ public class FormHandler {
*/ */
public void storeMethod(String val) { _method = val; } public void storeMethod(String val) { _method = val; }
/**
* The old nonces from the session
* @since 0.9.4
*/
public void storeNonces(String n1, String n2) {
_nonce1 = n1;
_nonce2 = n2;
}
/** /**
* Override this to perform the final processing (in turn, adding formNotice * Override this to perform the final processing (in turn, adding formNotice
* and formError messages, etc) * and formError messages, etc)
@@ -147,37 +177,35 @@ public class FormHandler {
_valid = false; _valid = false;
return; return;
} }
if (_nonce == null) {
//addFormError("You trying to mess with me? Huh? Are you?");
_valid = false;
return;
}
// To prevent actions with GET, jsps must call storeMethod() // To prevent actions with GET, jsps must call storeMethod()
if (_method != null && !"POST".equals(_method)) { if (_method != null && !"POST".equals(_method)) {
addFormError("Invalid form submission, requires POST not " + _method); addFormError("Invalid form submission, requires POST not " + _method);
_valid = false; _valid = false;
return; return;
} }
// If passwords are turned on, all is assumed good
if (_context.getBooleanProperty(RouterConsoleRunner.PROP_PW_ENABLE)) {
_valid = true;
return;
}
if (_nonce == null) {
//addFormError("You trying to mess with me? Huh? Are you?");
_valid = false;
return;
}
String sharedNonce = System.getProperty("router.consoleNonce"); String sharedNonce = System.getProperty("router.consoleNonce");
if ( (sharedNonce != null) && (sharedNonce.equals(_nonce) ) ) { if ( (sharedNonce != null) && (sharedNonce.equals(_nonce) ) ) {
return; return;
} }
String nonce = System.getProperty(getClass().getName() + NONCE_SUFFIX); if (!_nonce.equals(_nonce1) && !_nonce.equals(_nonce2)) {
String noncePrev = nonce + PREV_SUFFIX; addFormError(_("Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.")
if ( ( (nonce == null) || (!_nonce.equals(nonce)) ) && + ' ' +
( (noncePrev == null) || (!_nonce.equals(noncePrev)) ) ) { _("If the problem persists, verify that you have cookies enabled in your browser."));
String expected = _context.getProperty("consolePassword");
if ( (expected != null) && (expected.trim().length() > 0) && (expected.equals(_passphrase)) ) {
// ok
} else {
addFormError(_("Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit."));
_valid = false; _valid = false;
} }
} }
}
private void process() { private void process() {
if (!_processed) { if (!_processed) {
@@ -204,18 +232,13 @@ public class FormHandler {
} }
/** /**
* Generate a new nonce, store old and new in the system properties. * Generate a new nonce.
* Only call once per page! * Only call once per page!
* @return a new random long as a String * @return a new random long as a String
* @since 0.8.5 * @since 0.8.5
*/ */
public String getNewNonce() { public String getNewNonce() {
String prop = getClass().getName() + NONCE_SUFFIX;
String prev = System.getProperty(prop);
if (prev != null)
System.setProperty(prop + PREV_SUFFIX, prev);
String rv = Long.toString(_context.random().nextLong()); String rv = Long.toString(_context.random().nextLong());
System.setProperty(prop, rv);
return rv; return rv;
} }

View File

@@ -662,7 +662,7 @@ public class PluginStarter implements Runnable {
// quick check, will throw ClassNotFoundException on error // quick check, will throw ClassNotFoundException on error
LoadClientAppsJob.testClient(app.className, cl); LoadClientAppsJob.testClient(app.className, cl);
// run this guy now // run this guy now
LoadClientAppsJob.runClient(app.className, app.clientName, argVal, log, pluginThreadGroup, cl); LoadClientAppsJob.runClient(app.className, app.clientName, argVal, ctx, log, pluginThreadGroup, cl);
} else { } else {
// If there is some delay, there may be a really good reason for it. // If there is some delay, there may be a really good reason for it.
// Loading a class would be one of them! // Loading a class would be one of them!

View File

@@ -168,7 +168,7 @@ class ProfileOrganizerRenderer {
} }
buf.append("</td><td align=\"right\">").append(num(prof.getIntegrationValue())); buf.append("</td><td align=\"right\">").append(num(prof.getIntegrationValue()));
buf.append("</td><td align=\"center\">"); buf.append("</td><td align=\"center\">");
if (_context.shitlist().isShitlisted(peer)) buf.append(_("Banned")); if (_context.banlist().isBanlisted(peer)) buf.append(_("Banned"));
if (prof.getIsFailing()) buf.append(' ').append(_("Failing")); if (prof.getIsFailing()) buf.append(' ').append(_("Failing"));
if (_context.commSystem().wasUnreachable(peer)) buf.append(' ').append(_("Unreachable")); if (_context.commSystem().wasUnreachable(peer)) buf.append(' ').append(_("Unreachable"));
Rate failed = prof.getTunnelHistory().getFailedRate().getRate(30*60*1000); Rate failed = prof.getTunnelHistory().getFailedRate().getRate(30*60*1000);

View File

@@ -46,7 +46,7 @@ public class ProfilesHelper extends HelperBase {
renderNavBar(); renderNavBar();
} catch (IOException ioe) {} } catch (IOException ioe) {}
if (_full == 3) if (_full == 3)
getShitlistSummary(); getBanlistSummary();
else else
getProfileSummary(); getProfileSummary();
return ""; return "";
@@ -64,9 +64,9 @@ public class ProfilesHelper extends HelperBase {
} }
/** @return empty string, writes directly to _out */ /** @return empty string, writes directly to _out */
public String getShitlistSummary() { public String getBanlistSummary() {
try { try {
ShitlistRenderer rend = new ShitlistRenderer(_context); BanlistRenderer rend = new BanlistRenderer(_context);
rend.renderStatusHTML(_out); rend.renderStatusHTML(_out);
} catch (IOException ioe) { } catch (IOException ioe) {
ioe.printStackTrace(); ioe.printStackTrace();

View File

@@ -23,11 +23,15 @@ import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
import net.i2p.app.ClientAppManager;
import net.i2p.app.ClientAppState;
import static net.i2p.app.ClientAppState.*;
import net.i2p.apps.systray.SysTray; import net.i2p.apps.systray.SysTray;
import net.i2p.data.Base32; import net.i2p.data.Base32;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
import net.i2p.router.update.ConsoleUpdateManager; import net.i2p.router.update.ConsoleUpdateManager;
import net.i2p.router.app.RouterApp;
import net.i2p.util.Addresses; import net.i2p.util.Addresses;
import net.i2p.util.FileUtil; import net.i2p.util.FileUtil;
import net.i2p.util.I2PAppThread; import net.i2p.util.I2PAppThread;
@@ -48,6 +52,7 @@ import org.mortbay.jetty.handler.DefaultHandler;
import org.mortbay.jetty.handler.HandlerCollection; import org.mortbay.jetty.handler.HandlerCollection;
import org.mortbay.jetty.handler.RequestLogHandler; import org.mortbay.jetty.handler.RequestLogHandler;
import org.mortbay.jetty.nio.SelectChannelConnector; import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.Credential.MD5;
import org.mortbay.jetty.security.DigestAuthenticator; import org.mortbay.jetty.security.DigestAuthenticator;
import org.mortbay.jetty.security.HashUserRealm; import org.mortbay.jetty.security.HashUserRealm;
import org.mortbay.jetty.security.Constraint; import org.mortbay.jetty.security.Constraint;
@@ -65,7 +70,10 @@ import org.mortbay.thread.concurrent.ThreadPool;
/** /**
* Start the router console. * Start the router console.
*/ */
public class RouterConsoleRunner { public class RouterConsoleRunner implements RouterApp {
private final RouterContext _context;
private final ClientAppManager _mgr;
private volatile ClientAppState _state = UNINITIALIZED;
private static Server _server; private static Server _server;
private String _listenPort; private String _listenPort;
private String _listenHost; private String _listenHost;
@@ -74,14 +82,21 @@ public class RouterConsoleRunner {
private String _webAppsDir; private String _webAppsDir;
private static final String DEFAULT_WEBAPP_CONFIG_FILENAME = "webapps.config"; private static final String DEFAULT_WEBAPP_CONFIG_FILENAME = "webapps.config";
// Jetty Auth
private static final DigestAuthenticator authenticator = new DigestAuthenticator(); private static final DigestAuthenticator authenticator = new DigestAuthenticator();
public static final String JETTY_REALM = "i2prouter";
private static final String JETTY_ROLE = "routerAdmin";
public static final String PROP_CONSOLE_PW = "routerconsole.auth." + JETTY_REALM;
public static final String PROP_PW_ENABLE = "routerconsole.auth.enable";
public static final String ROUTERCONSOLE = "routerconsole"; public static final String ROUTERCONSOLE = "routerconsole";
public static final String PREFIX = "webapps."; public static final String PREFIX = "webapps.";
public static final String ENABLED = ".startOnLoad"; public static final String ENABLED = ".startOnLoad";
private static final String PROP_KEYSTORE_PASSWORD = "routerconsole.keystorePassword"; private static final String PROP_KEYSTORE_PASSWORD = "routerconsole.keystorePassword";
private static final String DEFAULT_KEYSTORE_PASSWORD = "changeit"; private static final String DEFAULT_KEYSTORE_PASSWORD = "changeit";
private static final String PROP_KEY_PASSWORD = "routerconsole.keyPassword"; private static final String PROP_KEY_PASSWORD = "routerconsole.keyPassword";
private static final String DEFAULT_LISTEN_PORT = "7657"; public static final int DEFAULT_LISTEN_PORT = 7657;
private static final String DEFAULT_LISTEN_HOST = "127.0.0.1"; private static final String DEFAULT_LISTEN_HOST = "127.0.0.1";
private static final String DEFAULT_WEBAPPS_DIR = "./webapps/"; private static final String DEFAULT_WEBAPPS_DIR = "./webapps/";
private static final String USAGE = "Bad RouterConsoleRunner arguments, check clientApp.0.args in your clients.config file! " + private static final String USAGE = "Bad RouterConsoleRunner arguments, check clientApp.0.args in your clients.config file! " +
@@ -125,10 +140,12 @@ public class RouterConsoleRunner {
* to both, we can't connect to [::1]:7657 for some reason. * to both, we can't connect to [::1]:7657 for some reason.
* So the wise choice is ::1,127.0.0.1 * So the wise choice is ::1,127.0.0.1
*/ */
public RouterConsoleRunner(String args[]) { public RouterConsoleRunner(RouterContext ctx, ClientAppManager mgr, String args[]) {
_context = ctx;
_mgr = mgr;
if (args.length == 0) { if (args.length == 0) {
// _listenHost and _webAppsDir are defaulted below // _listenHost and _webAppsDir are defaulted below
_listenPort = DEFAULT_LISTEN_PORT; _listenPort = Integer.toString(DEFAULT_LISTEN_PORT);
} else { } else {
boolean ssl = false; boolean ssl = false;
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
@@ -161,12 +178,59 @@ public class RouterConsoleRunner {
System.err.println(USAGE); System.err.println(USAGE);
throw new IllegalArgumentException(USAGE); throw new IllegalArgumentException(USAGE);
} }
_state = INITIALIZED;
} }
public static void main(String args[]) { public static void main(String args[]) {
startTrayApp(); List<RouterContext> contexts = RouterContext.listContexts();
RouterConsoleRunner runner = new RouterConsoleRunner(args); if (contexts == null || contexts.isEmpty())
runner.startConsole(); throw new IllegalStateException("no router context");
RouterConsoleRunner runner = new RouterConsoleRunner(contexts.get(0), null, args);
runner.startup();
}
/////// ClientApp methods
/** @since 0.9.4 */
public void startup() {
changeState(STARTING);
startTrayApp(_context);
startConsole();
}
/** @since 0.9.4 */
public void shutdown(String[] args) {
changeState(STOPPING);
try {
_server.stop();
} catch (Exception ie) {}
PortMapper portMapper = _context.portMapper();
portMapper.unregister(PortMapper.SVC_CONSOLE);
portMapper.unregister(PortMapper.SVC_HTTPS_CONSOLE);
changeState(STOPPED);
}
/** @since 0.9.4 */
public ClientAppState getState() {
return _state;
}
/** @since 0.9.4 */
public String getName() {
return "console";
}
/** @since 0.9.4 */
public String getDisplayName() {
return "Router Console";
}
/////// end ClientApp methods
private synchronized void changeState(ClientAppState state) {
_state = state;
if (_mgr != null)
_mgr.notify(this, state, null, null);
} }
/** /**
@@ -178,13 +242,13 @@ public class RouterConsoleRunner {
return _server; return _server;
} }
private static void startTrayApp() { private static void startTrayApp(I2PAppContext ctx) {
try { try {
//TODO: move away from routerconsole into a separate application. //TODO: move away from routerconsole into a separate application.
//ApplicationManager? //ApplicationManager?
boolean recentJava = SystemVersion.isJava6(); boolean recentJava = SystemVersion.isJava6();
// default false for now // default false for now
boolean desktopguiEnabled = I2PAppContext.getGlobalContext().getBooleanProperty("desktopgui.enabled"); boolean desktopguiEnabled = ctx.getBooleanProperty("desktopgui.enabled");
if (recentJava && desktopguiEnabled) { if (recentJava && desktopguiEnabled) {
//Check if we are in a headless environment, set properties accordingly //Check if we are in a headless environment, set properties accordingly
System.setProperty("java.awt.headless", Boolean.toString(GraphicsEnvironment.isHeadless())); System.setProperty("java.awt.headless", Boolean.toString(GraphicsEnvironment.isHeadless()));
@@ -219,7 +283,7 @@ public class RouterConsoleRunner {
*</pre> *</pre>
*/ */
public void startConsole() { public void startConsole() {
File workDir = new SecureDirectory(I2PAppContext.getGlobalContext().getTempDir(), "jetty-work"); File workDir = new SecureDirectory(_context.getTempDir(), "jetty-work");
boolean workDirRemoved = FileUtil.rmdir(workDir, false); boolean workDirRemoved = FileUtil.rmdir(workDir, false);
if (!workDirRemoved) if (!workDirRemoved)
System.err.println("ERROR: Unable to remove Jetty temporary work directory"); System.err.println("ERROR: Unable to remove Jetty temporary work directory");
@@ -228,7 +292,7 @@ public class RouterConsoleRunner {
System.err.println("ERROR: Unable to create Jetty temporary work directory"); System.err.println("ERROR: Unable to create Jetty temporary work directory");
//try { //try {
// Log.setLog(new I2PLogger(I2PAppContext.getGlobalContext())); // Log.setLog(new I2PLogger(_context));
//} catch (Throwable t) { //} catch (Throwable t) {
// System.err.println("INFO: I2P Jetty logging class not found, logging to wrapper log"); // System.err.println("INFO: I2P Jetty logging class not found, logging to wrapper log");
//} //}
@@ -236,7 +300,7 @@ public class RouterConsoleRunner {
System.setProperty("org.mortbay.log.class", "net.i2p.jetty.I2PLogger"); System.setProperty("org.mortbay.log.class", "net.i2p.jetty.I2PLogger");
// so Jetty can find WebAppConfiguration // so Jetty can find WebAppConfiguration
System.setProperty("jetty.class.path", I2PAppContext.getGlobalContext().getBaseDir() + "/lib/routerconsole.jar"); System.setProperty("jetty.class.path", _context.getBaseDir() + "/lib/routerconsole.jar");
_server = new Server(); _server = new Server();
_server.setGracefulShutdown(1000); _server.setGracefulShutdown(1000);
@@ -259,11 +323,11 @@ public class RouterConsoleRunner {
hColl.addHandler(chColl); hColl.addHandler(chColl);
hColl.addHandler(new DefaultHandler()); hColl.addHandler(new DefaultHandler());
String log = I2PAppContext.getGlobalContext().getProperty("routerconsole.log"); String log = _context.getProperty("routerconsole.log");
if (log != null) { if (log != null) {
File logFile = new File(log); File logFile = new File(log);
if (!logFile.isAbsolute()) if (!logFile.isAbsolute())
logFile = new File(I2PAppContext.getGlobalContext().getLogDir(), "logs/" + log); logFile = new File(_context.getLogDir(), "logs/" + log);
try { try {
RequestLogHandler rhl = new RequestLogHandler(); RequestLogHandler rhl = new RequestLogHandler();
rhl.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath())); rhl.setRequestLog(new NCSARequestLog(logFile.getAbsolutePath()));
@@ -283,7 +347,7 @@ public class RouterConsoleRunner {
// We assume relative to the base install dir for backward compatibility // We assume relative to the base install dir for backward compatibility
File app = new File(_webAppsDir); File app = new File(_webAppsDir);
if (!app.isAbsolute()) { if (!app.isAbsolute()) {
app = new File(I2PAppContext.getGlobalContext().getBaseDir(), _webAppsDir); app = new File(_context.getBaseDir(), _webAppsDir);
try { try {
_webAppsDir = app.getCanonicalPath(); _webAppsDir = app.getCanonicalPath();
} catch (IOException ioe) {} } catch (IOException ioe) {}
@@ -363,7 +427,7 @@ public class RouterConsoleRunner {
} }
} }
// XXX: what if listenhosts do not include 127.0.0.1? (Should that ever even happen?) // XXX: what if listenhosts do not include 127.0.0.1? (Should that ever even happen?)
I2PAppContext.getGlobalContext().portMapper().register(PortMapper.SVC_CONSOLE,lport); _context.portMapper().register(PortMapper.SVC_CONSOLE,lport);
} }
// add SSL listeners // add SSL listeners
@@ -376,8 +440,7 @@ public class RouterConsoleRunner {
System.err.println("Bad routerconsole SSL port " + _sslListenPort); System.err.println("Bad routerconsole SSL port " + _sslListenPort);
} }
if (sslPort > 0) { if (sslPort > 0) {
I2PAppContext ctx = I2PAppContext.getGlobalContext(); File keyStore = new File(_context.getConfigDir(), "keystore/console.ks");
File keyStore = new File(ctx.getConfigDir(), "keystore/console.ks");
if (verifyKeyStore(keyStore)) { if (verifyKeyStore(keyStore)) {
StringTokenizer tok = new StringTokenizer(_sslListenHost, " ,"); StringTokenizer tok = new StringTokenizer(_sslListenHost, " ,");
while (tok.hasMoreTokens()) { while (tok.hasMoreTokens()) {
@@ -408,9 +471,9 @@ public class RouterConsoleRunner {
SslSelectChannelConnector sssll = new SslSelectChannelConnector(); SslSelectChannelConnector sssll = new SslSelectChannelConnector();
// the keystore path and password // the keystore path and password
sssll.setKeystore(keyStore.getAbsolutePath()); sssll.setKeystore(keyStore.getAbsolutePath());
sssll.setPassword(ctx.getProperty(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD)); sssll.setPassword(_context.getProperty(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD));
// the X.509 cert password (if not present, verifyKeyStore() returned false) // the X.509 cert password (if not present, verifyKeyStore() returned false)
sssll.setKeyPassword(ctx.getProperty(PROP_KEY_PASSWORD, "thisWontWork")); sssll.setKeyPassword(_context.getProperty(PROP_KEY_PASSWORD, "thisWontWork"));
sssll.setUseDirectBuffers(false); // default true seems to be leaky sssll.setUseDirectBuffers(false); // default true seems to be leaky
ssll = sssll; ssll = sssll;
} else { } else {
@@ -418,9 +481,9 @@ public class RouterConsoleRunner {
SslSocketConnector sssll = new SslSocketConnector(); SslSocketConnector sssll = new SslSocketConnector();
// the keystore path and password // the keystore path and password
sssll.setKeystore(keyStore.getAbsolutePath()); sssll.setKeystore(keyStore.getAbsolutePath());
sssll.setPassword(ctx.getProperty(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD)); sssll.setPassword(_context.getProperty(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD));
// the X.509 cert password (if not present, verifyKeyStore() returned false) // the X.509 cert password (if not present, verifyKeyStore() returned false)
sssll.setKeyPassword(ctx.getProperty(PROP_KEY_PASSWORD, "thisWontWork")); sssll.setKeyPassword(_context.getProperty(PROP_KEY_PASSWORD, "thisWontWork"));
ssll = sssll; ssll = sssll;
} }
ssll.setHost(host); ssll.setHost(host);
@@ -437,7 +500,7 @@ public class RouterConsoleRunner {
System.err.println("You may ignore this warning if the console is still available at https://localhost:" + sslPort); System.err.println("You may ignore this warning if the console is still available at https://localhost:" + sslPort);
} }
} }
I2PAppContext.getGlobalContext().portMapper().register(PortMapper.SVC_HTTPS_CONSOLE,sslPort); _context.portMapper().register(PortMapper.SVC_HTTPS_CONSOLE,sslPort);
} else { } else {
System.err.println("Unable to create or access keystore for SSL: " + keyStore.getAbsolutePath()); System.err.println("Unable to create or access keystore for SSL: " + keyStore.getAbsolutePath());
} }
@@ -448,7 +511,7 @@ public class RouterConsoleRunner {
return; return;
} }
rootWebApp = new LocaleWebAppHandler(I2PAppContext.getGlobalContext(), rootWebApp = new LocaleWebAppHandler(_context,
"/", _webAppsDir + ROUTERCONSOLE + ".war"); "/", _webAppsDir + ROUTERCONSOLE + ".war");
File tmpdir = new SecureDirectory(workDir, ROUTERCONSOLE + "-" + File tmpdir = new SecureDirectory(workDir, ROUTERCONSOLE + "-" +
(_listenPort != null ? _listenPort : _sslListenPort)); (_listenPort != null ? _listenPort : _sslListenPort));
@@ -458,7 +521,7 @@ public class RouterConsoleRunner {
rootWebApp.setSessionHandler(new SessionHandler()); rootWebApp.setSessionHandler(new SessionHandler());
rootServletHandler = new ServletHandler(); rootServletHandler = new ServletHandler();
rootWebApp.setServletHandler(rootServletHandler); rootWebApp.setServletHandler(rootServletHandler);
initialize(rootWebApp); initialize(_context, rootWebApp);
chColl.addHandler(rootWebApp); chColl.addHandler(rootWebApp);
} catch (Exception ioe) { } catch (Exception ioe) {
@@ -495,7 +558,7 @@ public class RouterConsoleRunner {
} }
if (error) { if (error) {
System.err.println("WARNING: Error starting one or more listeners of the Router Console server.\n" + System.err.println("WARNING: Error starting one or more listeners of the Router Console server.\n" +
"If your console is still accessible at http://127.0.0.1:7657/,\n" + "If your console is still accessible at http://127.0.0.1:" + _listenPort + "/,\n" +
"this may be a problem only with binding to the IPV6 address ::1.\n" + "this may be a problem only with binding to the IPV6 address ::1.\n" +
"If so, you may ignore this error, or remove the\n" + "If so, you may ignore this error, or remove the\n" +
"\"::1,\" in the \"clientApp.0.args\" line of the clients.config file."); "\"::1,\" in the \"clientApp.0.args\" line of the clients.config file.");
@@ -517,7 +580,7 @@ public class RouterConsoleRunner {
if (! "false".equals(enabled)) { if (! "false".equals(enabled)) {
try { try {
String path = new File(dir, fileNames[i]).getCanonicalPath(); String path = new File(dir, fileNames[i]).getCanonicalPath();
WebAppStarter.startWebApp(I2PAppContext.getGlobalContext(), chColl, appName, path); WebAppStarter.startWebApp(_context, chColl, appName, path);
if (enabled == null) { if (enabled == null) {
// do this so configclients.jsp knows about all apps from reading the config // do this so configclients.jsp knows about all apps from reading the config
props.setProperty(PREFIX + appName + ENABLED, "true"); props.setProperty(PREFIX + appName + ENABLED, "true");
@@ -532,13 +595,15 @@ public class RouterConsoleRunner {
notStarted.add(appName); notStarted.add(appName);
} }
} }
changeState(RUNNING);
} }
} else { } else {
System.err.println("ERROR: Router console did not start, not starting webapps"); System.err.println("ERROR: Router console did not start, not starting webapps");
changeState(START_FAILED);
} }
if (rewrite) if (rewrite)
storeWebAppProperties(props); storeWebAppProperties(_context, props);
if (rootServletHandler != null && notStarted.size() > 0) { if (rootServletHandler != null && notStarted.size() > 0) {
// map each not-started webapp to the error page // map each not-started webapp to the error page
@@ -565,35 +630,29 @@ public class RouterConsoleRunner {
t.setPriority(Thread.NORM_PRIORITY - 1); t.setPriority(Thread.NORM_PRIORITY - 1);
t.start(); t.start();
List<RouterContext> contexts = RouterContext.listContexts(); ConsoleUpdateManager um = new ConsoleUpdateManager(_context);
if (contexts != null) {
RouterContext ctx = contexts.get(0);
ConsoleUpdateManager um = new ConsoleUpdateManager(ctx);
um.start(); um.start();
if (PluginStarter.pluginsEnabled(ctx)) { if (PluginStarter.pluginsEnabled(_context)) {
t = new I2PAppThread(new PluginStarter(ctx), "PluginStarter", true); t = new I2PAppThread(new PluginStarter(_context), "PluginStarter", true);
t.setPriority(Thread.NORM_PRIORITY - 1); t.setPriority(Thread.NORM_PRIORITY - 1);
t.start(); t.start();
ctx.addShutdownTask(new PluginStopper(ctx)); _context.addShutdownTask(new PluginStopper(_context));
} }
// stat summarizer registers its own hook // stat summarizer registers its own hook
ctx.addShutdownTask(new ServerShutdown()); _context.addShutdownTask(new ServerShutdown());
ConfigServiceHandler.registerSignalHandler(ctx); ConfigServiceHandler.registerSignalHandler(_context);
} // else log CRIT ?
} }
/** /**
* @return success if it exists and we have a password, or it was created successfully. * @return success if it exists and we have a password, or it was created successfully.
* @since 0.8.3 * @since 0.8.3
*/ */
private static boolean verifyKeyStore(File ks) { private boolean verifyKeyStore(File ks) {
if (ks.exists()) { if (ks.exists()) {
I2PAppContext ctx = I2PAppContext.getGlobalContext(); boolean rv = _context.getProperty(PROP_KEY_PASSWORD) != null;
boolean rv = ctx.getProperty(PROP_KEY_PASSWORD) != null;
if (!rv) if (!rv)
System.err.println("Console SSL error, must set " + PROP_KEY_PASSWORD + " in " + (new File(ctx.getConfigDir(), "router.config")).getAbsolutePath()); System.err.println("Console SSL error, must set " + PROP_KEY_PASSWORD + " in " + (new File(_context.getConfigDir(), "router.config")).getAbsolutePath());
return rv; return rv;
} }
File dir = ks.getParentFile(); File dir = ks.getParentFile();
@@ -614,14 +673,13 @@ public class RouterConsoleRunner {
* @return success * @return success
* @since 0.8.3 * @since 0.8.3
*/ */
private static boolean createKeyStore(File ks) { private boolean createKeyStore(File ks) {
I2PAppContext ctx = I2PAppContext.getGlobalContext();
// make a random 48 character password (30 * 8 / 5) // make a random 48 character password (30 * 8 / 5)
byte[] rand = new byte[30]; byte[] rand = new byte[30];
ctx.random().nextBytes(rand); _context.random().nextBytes(rand);
String keyPassword = Base32.encode(rand); String keyPassword = Base32.encode(rand);
// and one for the cname // and one for the cname
ctx.random().nextBytes(rand); _context.random().nextBytes(rand);
String cname = Base32.encode(rand) + ".console.i2p.net"; String cname = Base32.encode(rand) + ".console.i2p.net";
String keytool = (new File(System.getProperty("java.home"), "bin/keytool")).getAbsolutePath(); String keytool = (new File(System.getProperty("java.home"), "bin/keytool")).getAbsolutePath();
@@ -643,11 +701,10 @@ public class RouterConsoleRunner {
if (success) { if (success) {
SecureFileOutputStream.setPerms(ks); SecureFileOutputStream.setPerms(ks);
try { try {
RouterContext rctx = (RouterContext) ctx;
Map<String, String> changes = new HashMap(); Map<String, String> changes = new HashMap();
changes.put(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD); changes.put(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD);
changes.put(PROP_KEY_PASSWORD, keyPassword); changes.put(PROP_KEY_PASSWORD, keyPassword);
rctx.router().saveConfig(changes, null); _context.router().saveConfig(changes, null);
} catch (Exception e) {} // class cast exception } catch (Exception e) {} // class cast exception
} }
} }
@@ -664,28 +721,43 @@ public class RouterConsoleRunner {
System.err.println(buf.toString()); System.err.println(buf.toString());
System.err.println("This is for the Sun/Oracle keytool, others may be incompatible.\n" + System.err.println("This is for the Sun/Oracle keytool, others may be incompatible.\n" +
"If you create the keystore manually, you must add " + PROP_KEYSTORE_PASSWORD + " and " + PROP_KEY_PASSWORD + "If you create the keystore manually, you must add " + PROP_KEYSTORE_PASSWORD + " and " + PROP_KEY_PASSWORD +
" to " + (new File(ctx.getConfigDir(), "router.config")).getAbsolutePath()); " to " + (new File(_context.getConfigDir(), "router.config")).getAbsolutePath());
} }
return success; return success;
} }
static void initialize(WebAppContext context) { /**
* Set up basic security constraints for the webapp.
* Add all users and passwords.
*/
static void initialize(RouterContext ctx, WebAppContext context) {
SecurityHandler sec = new SecurityHandler(); SecurityHandler sec = new SecurityHandler();
List<ConstraintMapping> constraints = new ArrayList(4); List<ConstraintMapping> constraints = new ArrayList(4);
String password = getPassword(); ConsolePasswordManager mgr = new ConsolePasswordManager(ctx);
if (password != null) { boolean enable = ctx.getBooleanProperty(PROP_PW_ENABLE);
HashUserRealm realm = new HashUserRealm("i2prouter"); if (enable) {
realm.put("admin", password); Map<String, String> userpw = mgr.getMD5(PROP_CONSOLE_PW);
realm.addUserToRole("admin", "routerAdmin"); if (userpw.isEmpty()) {
enable = false;
ctx.router().saveConfig(PROP_CONSOLE_PW, "false");
} else {
HashUserRealm realm = new HashUserRealm(JETTY_REALM);
sec.setUserRealm(realm); sec.setUserRealm(realm);
sec.setAuthenticator(authenticator); sec.setAuthenticator(authenticator);
Constraint constraint = new Constraint("admin", "routerAdmin"); for (Map.Entry<String, String> e : userpw.entrySet()) {
String user = e.getKey();
String pw = e.getValue();
realm.put(user, MD5.__TYPE + pw);
realm.addUserToRole(user, JETTY_ROLE);
Constraint constraint = new Constraint(user, JETTY_ROLE);
constraint.setAuthenticate(true); constraint.setAuthenticate(true);
ConstraintMapping cm = new ConstraintMapping(); ConstraintMapping cm = new ConstraintMapping();
cm.setConstraint(constraint); cm.setConstraint(constraint);
cm.setPathSpec("/"); cm.setPathSpec("/");
constraints.add(cm); constraints.add(cm);
} }
}
}
// This forces a '403 Forbidden' response for TRACE and OPTIONS unless the // This forces a '403 Forbidden' response for TRACE and OPTIONS unless the
// WAC handler handles it. // WAC handler handles it.
@@ -719,24 +791,10 @@ public class RouterConsoleRunner {
context.setSecurityHandler(sec); context.setSecurityHandler(sec);
} }
static String getPassword() { /** @since 0.8.8 */
List<RouterContext> contexts = RouterContext.listContexts(); private class ServerShutdown implements Runnable {
if (contexts != null) { public void run() {
for (int i = 0; i < contexts.size(); i++) { shutdown(null);
RouterContext ctx = contexts.get(i);
String password = ctx.getProperty("consolePassword");
if (password != null) {
password = password.trim();
if (password.length() > 0) {
return password;
}
}
}
// no password in any context
return null;
} else {
// no contexts?!
return null;
} }
} }
@@ -749,13 +807,18 @@ public class RouterConsoleRunner {
} }
} }
public static Properties webAppProperties() { private Properties webAppProperties() {
return webAppProperties(I2PAppContext.getGlobalContext().getConfigDir().getAbsolutePath()); return webAppProperties(_context.getConfigDir().getAbsolutePath());
}
/** @since 0.9.4 */
public static Properties webAppProperties(I2PAppContext ctx) {
return webAppProperties(ctx.getConfigDir().getAbsolutePath());
} }
public static Properties webAppProperties(String dir) { public static Properties webAppProperties(String dir) {
Properties rv = new Properties(); Properties rv = new Properties();
// String webappConfigFile = ctx.getProperty(PROP_WEBAPP_CONFIG_FILENAME, DEFAULT_WEBAPP_CONFIG_FILENAME); // String webappConfigFile = _context.getProperty(PROP_WEBAPP_CONFIG_FILENAME, DEFAULT_WEBAPP_CONFIG_FILENAME);
String webappConfigFile = DEFAULT_WEBAPP_CONFIG_FILENAME; String webappConfigFile = DEFAULT_WEBAPP_CONFIG_FILENAME;
File cfgFile = new File(dir, webappConfigFile); File cfgFile = new File(dir, webappConfigFile);
@@ -768,10 +831,10 @@ public class RouterConsoleRunner {
return rv; return rv;
} }
public static void storeWebAppProperties(Properties props) { public static void storeWebAppProperties(RouterContext ctx, Properties props) {
// String webappConfigFile = ctx.getProperty(PROP_WEBAPP_CONFIG_FILENAME, DEFAULT_WEBAPP_CONFIG_FILENAME); // String webappConfigFile = _context.getProperty(PROP_WEBAPP_CONFIG_FILENAME, DEFAULT_WEBAPP_CONFIG_FILENAME);
String webappConfigFile = DEFAULT_WEBAPP_CONFIG_FILENAME; String webappConfigFile = DEFAULT_WEBAPP_CONFIG_FILENAME;
File cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), webappConfigFile); File cfgFile = new File(ctx.getConfigDir(), webappConfigFile);
try { try {
DataHelper.storeProps(props, cfgFile); DataHelper.storeProps(props, cfgFile);

View File

@@ -172,6 +172,8 @@ public class SummaryHelper extends HelperBase {
//if (_context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0) //if (_context.router().getRouterInfo().getCapabilities().indexOf('O') >= 0)
// return _("WARN-Firewalled and Fast"); // return _("WARN-Firewalled and Fast");
return _("Firewalled"); return _("Firewalled");
case CommSystemFacade.STATUS_DISCONNECTED:
return _("Disconnected - check network cable");
case CommSystemFacade.STATUS_HOSED: case CommSystemFacade.STATUS_HOSED:
return _("ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart"); return _("ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart");
case CommSystemFacade.STATUS_UNKNOWN: // fallthrough case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
@@ -283,11 +285,11 @@ public class SummaryHelper extends HelperBase {
* *
*/ */
/******** /********
public int getShitlistedPeers() { public int getBanlistedPeers() {
if (_context == null) if (_context == null)
return 0; return 0;
else else
return _context.shitlist().getRouterCount(); return _context.banlist().getRouterCount();
} }
********/ ********/

View File

@@ -74,7 +74,7 @@ public class WebAppConfiguration implements Configuration {
cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH); cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH);
dir = pluginDir; dir = pluginDir;
} else { } else {
Properties props = RouterConsoleRunner.webAppProperties(); Properties props = RouterConsoleRunner.webAppProperties(i2pContext);
cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH); cp = props.getProperty(RouterConsoleRunner.PREFIX + appName + CLASSPATH);
} }
if (cp == null) if (cp == null)

View File

@@ -6,7 +6,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import net.i2p.I2PAppContext; import net.i2p.router.RouterContext;
import net.i2p.util.FileUtil; import net.i2p.util.FileUtil;
import net.i2p.util.SecureDirectory; import net.i2p.util.SecureDirectory;
@@ -51,7 +51,7 @@ public class WebAppStarter {
* adds and starts * adds and starts
* @throws just about anything, caller would be wise to catch Throwable * @throws just about anything, caller would be wise to catch Throwable
*/ */
static void startWebApp(I2PAppContext ctx, ContextHandlerCollection server, static void startWebApp(RouterContext ctx, ContextHandlerCollection server,
String appName, String warPath) throws Exception { String appName, String warPath) throws Exception {
File tmpdir = new SecureDirectory(ctx.getTempDir(), "jetty-work-" + appName + ctx.random().nextInt()); File tmpdir = new SecureDirectory(ctx.getTempDir(), "jetty-work-" + appName + ctx.random().nextInt());
WebAppContext wac = addWebApp(ctx, server, appName, warPath, tmpdir); WebAppContext wac = addWebApp(ctx, server, appName, warPath, tmpdir);
@@ -65,7 +65,7 @@ public class WebAppStarter {
* This is used only by RouterConsoleRunner, which adds all the webapps first * This is used only by RouterConsoleRunner, which adds all the webapps first
* and then starts all at once. * and then starts all at once.
*/ */
static WebAppContext addWebApp(I2PAppContext ctx, ContextHandlerCollection server, static WebAppContext addWebApp(RouterContext ctx, ContextHandlerCollection server,
String appName, String warPath, File tmpdir) throws IOException { String appName, String warPath, File tmpdir) throws IOException {
// Jetty will happily load one context on top of another without stopping // Jetty will happily load one context on top of another without stopping
@@ -103,7 +103,7 @@ public class WebAppStarter {
wac.setExtractWAR(false); wac.setExtractWAR(false);
// this does the passwords... // this does the passwords...
RouterConsoleRunner.initialize(wac); RouterConsoleRunner.initialize(ctx, wac);
// see WebAppConfiguration for info // see WebAppConfiguration for info
String[] classNames = wac.getConfigurationClasses(); String[] classNames = wac.getConfigurationClasses();

View File

@@ -19,13 +19,10 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigNetHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigNetHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<div class="configure"> <div class="configure">
<form action="" method="POST"> <form action="" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>">
<input type="hidden" name="action" value="blah" > <input type="hidden" name="action" value="blah" >
<input type="hidden" name="ratesOnly" value="1" > <input type="hidden" name="ratesOnly" value="1" >
<h3><%=intl._("Bandwidth limiter")%></h3><p> <h3><%=intl._("Bandwidth limiter")%></h3><p>

View File

@@ -21,14 +21,11 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigAdvancedHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigAdvancedHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<div class="configure"> <div class="configure">
<div class="wideload"> <div class="wideload">
<form action="" method="POST"> <form action="" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<input type="hidden" name="action" value="blah" > <input type="hidden" name="action" value="blah" >
<h3><%=intl._("Advanced I2P Configuration")%></h3> <h3><%=intl._("Advanced I2P Configuration")%></h3>
<textarea rows="32" cols="60" name="config" wrap="off" spellcheck="false"><jsp:getProperty name="advancedhelper" property="settings" /></textarea><br><hr> <textarea rows="32" cols="60" name="config" wrap="off" spellcheck="false"><jsp:getProperty name="advancedhelper" property="settings" /></textarea><br><hr>

View File

@@ -25,16 +25,8 @@ input.default { width: 1px; height: 1px; visibility: hidden; }
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigClientsHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigClientsHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter(\"action\")%>" />
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter(\"nonce\")%>" />
<jsp:setProperty name="formhandler" property="settings" value="<%=request.getParameterMap()%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<div class="configure"> <div class="configure">
<%
String pageNonce = formhandler.getNewNonce();
%>
<h3><%=intl._("Client Configuration")%></h3><p> <h3><%=intl._("Client Configuration")%></h3><p>
<%=intl._("The Java clients listed below are started by the router and run in the same JVM.")%> <%=intl._("The Java clients listed below are started by the router and run in the same JVM.")%>
</p><div class="wideload"> </p><div class="wideload">
@@ -85,9 +77,9 @@ input.default { width: 1px; height: 1px; visibility: hidden; }
<input type="checkbox" class="optbox" name="auth" value="true" <jsp:getProperty name="clientshelper" property="auth" /> > <input type="checkbox" class="optbox" name="auth" value="true" <jsp:getProperty name="clientshelper" property="auth" /> >
<%=intl._("Require username and password")%><br> <%=intl._("Require username and password")%><br>
<%=intl._("Username")%>: <%=intl._("Username")%>:
<input name="user" type="text" value="<jsp:getProperty name="clientshelper" property="user" />" ><br> <input name="user" type="text" value="" /><br>
<%=intl._("Password")%>: <%=intl._("Password")%>:
<input name="pw" type="password" value="<jsp:getProperty name="clientshelper" property="pw" />" ><br> <input name="pw" type="password" value="" /><br>
</p><p><b><%=intl._("The default settings will work for most people.")%></b> </p><p><b><%=intl._("The default settings will work for most people.")%></b>
<%=intl._("Any changes made here must also be configured in the external client.")%> <%=intl._("Any changes made here must also be configured in the external client.")%>
<%=intl._("Many clients do not support SSL or authorization.")%> <%=intl._("Many clients do not support SSL or authorization.")%>

View File

@@ -22,14 +22,7 @@ input.default {
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigHomeHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigHomeHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:setProperty name="formhandler" property="settings" value="<%=request.getParameterMap()%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<%
String pageNonce = formhandler.getNewNonce();
%>
<jsp:useBean class="net.i2p.router.web.HomeHelper" id="homehelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.HomeHelper" id="homehelper" scope="request" />
<jsp:setProperty name="homehelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" /> <jsp:setProperty name="homehelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />

View File

@@ -15,10 +15,7 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigKeyringHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigKeyringHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<jsp:useBean class="net.i2p.router.web.ConfigKeyringHelper" id="keyringhelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigKeyringHelper" id="keyringhelper" scope="request" />
<jsp:setProperty name="keyringhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" /> <jsp:setProperty name="keyringhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<div class="configure"><h2><%=intl._("Keyring")%></h2><p> <div class="configure"><h2><%=intl._("Keyring")%></h2><p>
@@ -29,7 +26,7 @@
</div> </div>
<form action="" method="POST"> <form action="" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<h3><%=intl._("Manual Keyring Addition")%></h3><p> <h3><%=intl._("Manual Keyring Addition")%></h3><p>
<%=intl._("Enter keys for encrypted remote destinations here.")%> <%=intl._("Enter keys for encrypted remote destinations here.")%>
<%=intl._("Keys for local destinations must be entered on the")%> <a href="i2ptunnel/"><%=intl._("I2PTunnel page")%></a>. <%=intl._("Keys for local destinations must be entered on the")%> <a href="i2ptunnel/"><%=intl._("I2PTunnel page")%></a>.

View File

@@ -18,13 +18,10 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigLoggingHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigLoggingHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<div class="configure"> <div class="configure">
<form action="" method="POST"> <form action="" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<input type="hidden" name="action" value="blah" > <input type="hidden" name="action" value="blah" >
<h3><%=intl._("Configure I2P Logging Options")%></h3> <h3><%=intl._("Configure I2P Logging Options")%></h3>
<div class="wideload"> <div class="wideload">

View File

@@ -18,13 +18,10 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigNetHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigNetHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<div class="configure"> <div class="configure">
<form action="" method="POST"> <form action="" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<input type="hidden" name="action" value="blah" > <input type="hidden" name="action" value="blah" >
<h3><%=intl._("IP and Transport Configuration")%></h3><p> <h3><%=intl._("IP and Transport Configuration")%></h3><p>
<img src="/themes/console/images/itoopie_xsm.png" alt=""> <img src="/themes/console/images/itoopie_xsm.png" alt="">
@@ -207,7 +204,7 @@
<p> <p>
This setting causes your router identity to be regenerated every time your IP address This setting causes your router identity to be regenerated every time your IP address
changes. If you have a dynamic IP this option can speed up your reintegration into changes. If you have a dynamic IP this option can speed up your reintegration into
the network (since people will have shitlisted your old router identity), and, for the network (since people will have banned your old router identity), and, for
very weak adversaries, help frustrate trivial very weak adversaries, help frustrate trivial
<a href="http://www.i2p.net/how_threatmodel#intersection">intersection <a href="http://www.i2p.net/how_threatmodel#intersection">intersection
attacks</a> against the NetDB. Your different router identities would only be attacks</a> against the NetDB. Your different router identities would only be

View File

@@ -15,13 +15,7 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigPeerHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigPeerHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<jsp:useBean class="net.i2p.router.web.ConfigPeerHelper" id="peerhelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigPeerHelper" id="peerhelper" scope="request" />
<jsp:setProperty name="peerhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" /> <jsp:setProperty name="peerhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
@@ -31,7 +25,7 @@
%> %>
<div class="configure"> <div class="configure">
<form action="configpeer" method="POST"> <form action="configpeer" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<a name="sh"> </a> <a name="sh"> </a>
<a name="unsh"> </a> <a name="unsh"> </a>
<a name="bonus"> </a> <a name="bonus"> </a>
@@ -61,11 +55,11 @@
<input type="text" size="8" name="capacity" value="<%=capacity%>" /> <input type="text" size="8" name="capacity" value="<%=capacity%>" />
<input type="submit" name="action" class="add" value="<%=intl._("Adjust peer bonuses")%>" /></p></div> <input type="submit" name="action" class="add" value="<%=intl._("Adjust peer bonuses")%>" /></p></div>
</form> </form>
<a name="shitlist"> </a><h2><%=intl._("Banned Peers")%></h2> <a name="banlist"> </a><h2><%=intl._("Banned Peers")%></h2>
<jsp:useBean class="net.i2p.router.web.ProfilesHelper" id="profilesHelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.ProfilesHelper" id="profilesHelper" scope="request" />
<jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" /> <jsp:setProperty name="profilesHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<% profilesHelper.storeWriter(out); %> <% profilesHelper.storeWriter(out); %>
<jsp:getProperty name="profilesHelper" property="shitlistSummary" /> <jsp:getProperty name="profilesHelper" property="banlistSummary" />
<div class="wideload"><h2><%=intl._("Banned IPs")%></h2> <div class="wideload"><h2><%=intl._("Banned IPs")%></h2>
<jsp:getProperty name="peerhelper" property="blocklistSummary" /> <jsp:getProperty name="peerhelper" property="blocklistSummary" />

View File

@@ -18,14 +18,9 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigReseedHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigReseedHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter(\"action\")%>" />
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter(\"nonce\")%>" />
<jsp:setProperty name="formhandler" property="settings" value="<%=request.getParameterMap()%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<div class="configure"><form action="" method="POST"> <div class="configure"><form action="" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<h3><%=intl._("Reseeding Configuration")%></h3> <h3><%=intl._("Reseeding Configuration")%></h3>
<p><%=intl._("Reseeding is the bootstrapping process used to find other routers when you first install I2P, or when your router has too few router references remaining.")%> <p><%=intl._("Reseeding is the bootstrapping process used to find other routers when you first install I2P, or when your router has too few router references remaining.")%>
<%=intl._("If reseeding has failed, you should first check your network connection.")%> <%=intl._("If reseeding has failed, you should first check your network connection.")%>

View File

@@ -15,13 +15,10 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigServiceHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigServiceHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<div class="configure"> <div class="configure">
<form action="" method="POST"> <form action="" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<h3><%=intl._("Shutdown the router")%></h3> <h3><%=intl._("Shutdown the router")%></h3>
<p><%=intl._("Graceful shutdown lets the router satisfy the agreements it has already made before shutting down, but may take a few minutes.")%> <p><%=intl._("Graceful shutdown lets the router satisfy the agreements it has already made before shutting down, but may take a few minutes.")%>
<%=intl._("If you need to kill the router immediately, that option is available as well.")%></p> <%=intl._("If you need to kill the router immediately, that option is available as well.")%></p>

View File

@@ -22,17 +22,10 @@ input.default {
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigSummaryHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigSummaryHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:setProperty name="formhandler" property="settings" value="<%=request.getParameterMap()%>" />
<% <%
formhandler.setMovingAction(); formhandler.setMovingAction();
%> %>
<jsp:getProperty name="formhandler" property="allMessages" />
<%
String pageNonce = formhandler.getNewNonce();
%>
<jsp:useBean class="net.i2p.router.web.SummaryHelper" id="summaryhelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.SummaryHelper" id="summaryhelper" scope="request" />
<jsp:setProperty name="summaryhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" /> <jsp:setProperty name="summaryhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />

View File

@@ -66,17 +66,13 @@ function toggleAll(category)
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigStatsHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigStatsHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<jsp:useBean class="net.i2p.router.web.ConfigStatsHelper" id="statshelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigStatsHelper" id="statshelper" scope="request" />
<jsp:setProperty name="statshelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" /> <jsp:setProperty name="statshelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<div class="configure"> <div class="configure">
<form id="statsForm" name="statsForm" action="" method="POST"> <form id="statsForm" name="statsForm" action="" method="POST">
<input type="hidden" name="action" value="foo" > <input type="hidden" name="action" value="foo" >
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<h3><%=intl._("Configure I2P Stat Collection")%></h3> <h3><%=intl._("Configure I2P Stat Collection")%></h3>
<p><%=intl._("Enable full stats?")%> <p><%=intl._("Enable full stats?")%>
<input type="checkbox" class="optbox" name="isFull" value="true" <% <input type="checkbox" class="optbox" name="isFull" value="true" <%

View File

@@ -17,13 +17,7 @@
<div class="main" id="main"> <div class="main" id="main">
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigTunnelsHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigTunnelsHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:setProperty name="formhandler" property="shouldsave" value="<%=request.getParameter(\"shouldsave\")%>" />
<jsp:setProperty name="formhandler" property="action" value="<%=request.getParameter(\"action\")%>" />
<jsp:setProperty name="formhandler" property="nonce" value="<%=request.getParameter(\"nonce\")%>" />
<jsp:setProperty name="formhandler" property="settings" value="<%=request.getParameterMap()%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<div class="configure"><p> <div class="configure"><p>
<%=intl._("NOTE")%>: <%=intl._("NOTE")%>:
<%=intl._("The default settings work for most people.")%> <%=intl._("The default settings work for most people.")%>
@@ -33,7 +27,7 @@
<%=intl._("Change these settings with care, and adjust them if you have problems.")%> <%=intl._("Change these settings with care, and adjust them if you have problems.")%>
<div class="wideload"> <div class="wideload">
<form action="" method="POST"> <form action="" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<input type="hidden" name="action" value="blah" > <input type="hidden" name="action" value="blah" >
<jsp:getProperty name="tunnelshelper" property="form" /> <jsp:getProperty name="tunnelshelper" property="form" />
<%=intl._("Note")%>: <%=intl._("Exploratory tunnel setting changes are stored in the router.config file.")%> <%=intl._("Note")%>: <%=intl._("Exploratory tunnel setting changes are stored in the router.config file.")%>

View File

@@ -6,6 +6,13 @@
<html><head> <html><head>
<%@include file="css.jsi" %> <%@include file="css.jsi" %>
<%=intl.title("config UI")%> <%=intl.title("config UI")%>
<style type='text/css'>
input.default {
width: 1px;
height: 1px;
visibility: hidden;
}
</style>
<script src="/js/ajax.js" type="text/javascript"></script> <script src="/js/ajax.js" type="text/javascript"></script>
<%@include file="summaryajax.jsi" %> <%@include file="summaryajax.jsi" %>
</head><body onload="initAjax()"> </head><body onload="initAjax()">
@@ -21,10 +28,7 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigUIHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigUIHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<div class="configure"><div class="topshimten"><h3><%=uihelper._("Router Console Theme")%></h3></div> <div class="configure"><div class="topshimten"><h3><%=uihelper._("Router Console Theme")%></h3></div>
<form action="" method="POST"> <form action="" method="POST">
<% <%
@@ -36,7 +40,7 @@
} }
%> %>
<input type="hidden" name="consoleNonce" value="<%=consoleNonce%>" > <input type="hidden" name="consoleNonce" value="<%=consoleNonce%>" >
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<input type="hidden" name="action" value="blah" > <input type="hidden" name="action" value="blah" >
<% <%
String userAgent = request.getHeader("User-Agent"); String userAgent = request.getHeader("User-Agent");
@@ -54,5 +58,17 @@
</p><hr><div class="formaction"> </p><hr><div class="formaction">
<input type="reset" class="cancel" value="<%=intl._("Cancel")%>" > <input type="reset" class="cancel" value="<%=intl._("Cancel")%>" >
<input type="submit" name="shouldsave" class="accept" value="<%=intl._("Apply")%>" > <input type="submit" name="shouldsave" class="accept" value="<%=intl._("Apply")%>" >
</div></form></div> </div></form>
<h3><%=uihelper._("Router Console Password")%></h3>
<form action="" method="POST">
<input type="hidden" name="nonce" value="<%=pageNonce%>" >
<jsp:getProperty name="uihelper" property="passwordForm" />
<div class="formaction">
<input type="submit" name="action" class="default" value="<%=intl._("Add user")%>" >
<input type="submit" name="action" class="delete" value="<%=intl._("Delete selected")%>" >
<input type="reset" class="cancel" value="<%=intl._("Cancel")%>" >
<input type="submit" name="action" class="add" value="<%=intl._("Add user")%>" >
</div>
</form></div>
</div></body></html> </div></body></html>

View File

@@ -16,17 +16,14 @@
<%@include file="confignav.jsi" %> <%@include file="confignav.jsi" %>
<jsp:useBean class="net.i2p.router.web.ConfigUpdateHandler" id="formhandler" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigUpdateHandler" id="formhandler" scope="request" />
<% formhandler.storeMethod(request.getMethod()); %> <%@include file="formhandler.jsi" %>
<jsp:setProperty name="formhandler" property="*" />
<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<jsp:getProperty name="formhandler" property="allMessages" />
<jsp:useBean class="net.i2p.router.web.ConfigUpdateHelper" id="updatehelper" scope="request" /> <jsp:useBean class="net.i2p.router.web.ConfigUpdateHelper" id="updatehelper" scope="request" />
<jsp:setProperty name="updatehelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" /> <jsp:setProperty name="updatehelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
<div class="messages"> <div class="messages">
<jsp:getProperty name="updatehelper" property="newsStatus" /></div> <jsp:getProperty name="updatehelper" property="newsStatus" /></div>
<div class="configure"> <div class="configure">
<form action="" method="POST"> <form action="" method="POST">
<input type="hidden" name="nonce" value="<jsp:getProperty name="formhandler" property="newNonce" />" > <input type="hidden" name="nonce" value="<%=pageNonce%>" >
<% /* set hidden default */ %> <% /* set hidden default */ %>
<input type="submit" name="action" value="" style="display:none" > <input type="submit" name="action" value="" style="display:none" >
<% if (updatehelper.canInstall()) { %> <% if (updatehelper.canInstall()) { %>

View File

@@ -0,0 +1,43 @@
<%
/*
* Does the standard setup for all form handlers, then
* displays the message box (which drives the form processing).
*
* Included ~15 times, keep whitespace to a minimum
*
* Include this directly after the line:
* <jsp:useBean class="net.i2p.router.web.xxxHandler" id="formhandler" scope="request" />
*/
// This initializes the RouterContext - must be the first thing
formhandler.setContextId((String)session.getAttribute("i2p.contextId"));
// Prevents any saves via GET
formhandler.storeMethod(request.getMethod());
// Store the nonces for verification
String klass = formhandler.getClass().getName();
String nonceAttr1 = klass + ".nonce";
String nonceAttr2 = nonceAttr1 + "Prev";
String nonce1 = (String) session.getAttribute(nonceAttr1);
String nonce2 = (String) session.getAttribute(nonceAttr2);
formhandler.storeNonces(nonce1, nonce2);
// Put all the params in the map, some handlers use this instead of individual setters
// We also call all of the setters below.
formhandler.setSettings(request.getParameterMap());
%>
<jsp:setProperty name="formhandler" property="*" />
<jsp:getProperty name="formhandler" property="allMessages" />
<%
// Only call this once per page, do not getProperty("newNonce") elsewhere,
// use the variable instead.
// This shuffles down the nonces, so it must be after getAllMessages() above,
// since it does the form validation.
String pageNonce = formhandler.getNewNonce();
session.setAttribute(nonceAttr2, nonce1);
session.setAttribute(nonceAttr1, pageNonce);
%>

File diff suppressed because it is too large Load Diff

View File

@@ -15,8 +15,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: I2P\n" "Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-10-12 00:46+0000\n" "POT-Creation-Date: 2012-10-15 17:57+0000\n"
"PO-Revision-Date: 2012-10-12 00:44+0000\n" "PO-Revision-Date: 2012-10-12 00:50+0000\n"
"Last-Translator: BadCluster <badcluster@i2pmail.org>\n" "Last-Translator: BadCluster <badcluster@i2pmail.org>\n"
"Language-Team: Italian (http://www.transifex.com/projects/p/I2P/language/" "Language-Team: Italian (http://www.transifex.com/projects/p/I2P/language/"
"it/)\n" "it/)\n"
@@ -361,7 +361,7 @@ msgstr "Quanto è passato dall'inizio di questa connessione"
#: ../../../router/java/src/net/i2p/router/transport/TransportManager.java:540 #: ../../../router/java/src/net/i2p/router/transport/TransportManager.java:540
#: ../../../router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java:756 #: ../../../router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java:756
#: ../../../router/java/src/net/i2p/router/transport/udp/UDPTransport.java:2188 #: ../../../router/java/src/net/i2p/router/transport/udp/UDPTransport.java:2188
#: ../java/src/net/i2p/router/web/SummaryHelper.java:835 #: ../java/src/net/i2p/router/web/SummaryHelper.java:836
msgid "Up" msgid "Up"
msgstr "Su" msgstr "Su"
@@ -722,7 +722,7 @@ msgstr "Bannato"
#: ../../../router/java/src/net/i2p/router/transport/udp/UDPTransport.java:2310 #: ../../../router/java/src/net/i2p/router/transport/udp/UDPTransport.java:2310
msgid "backlogged" msgid "backlogged"
msgstr "" msgstr "ritardi"
#. buf.append("<tr><td colspan=\"16\"><hr></td></tr>\n"); #. buf.append("<tr><td colspan=\"16\"><hr></td></tr>\n");
#: ../../../router/java/src/net/i2p/router/transport/udp/UDPTransport.java:2390 #: ../../../router/java/src/net/i2p/router/transport/udp/UDPTransport.java:2390
@@ -2134,7 +2134,7 @@ msgstr "Cancella"
#: ../java/src/net/i2p/router/web/ConfigHomeHandler.java:25 #: ../java/src/net/i2p/router/web/ConfigHomeHandler.java:25
#: ../java/src/net/i2p/router/web/ConfigSummaryHandler.java:26 #: ../java/src/net/i2p/router/web/ConfigSummaryHandler.java:26
#: ../java/src/net/i2p/router/web/SummaryHelper.java:855 #: ../java/src/net/i2p/router/web/SummaryHelper.java:856
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:419 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:419
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:439 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:439
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:455 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:455
@@ -2143,7 +2143,7 @@ msgstr "Elimina selezionati"
#: ../java/src/net/i2p/router/web/ConfigHomeHandler.java:26 #: ../java/src/net/i2p/router/web/ConfigHomeHandler.java:26
#: ../java/src/net/i2p/router/web/ConfigSummaryHandler.java:27 #: ../java/src/net/i2p/router/web/ConfigSummaryHandler.java:27
#: ../java/src/net/i2p/router/web/SummaryHelper.java:874 #: ../java/src/net/i2p/router/web/SummaryHelper.java:875
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:417 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:417
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:425 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:425
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:437 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/confighome_jsp.java:437
@@ -2294,7 +2294,7 @@ msgstr "WARN"
#: ../java/src/net/i2p/router/web/ConfigLoggingHelper.java:88 #: ../java/src/net/i2p/router/web/ConfigLoggingHelper.java:88
#: ../java/src/net/i2p/router/web/HomeHelper.java:192 #: ../java/src/net/i2p/router/web/HomeHelper.java:192
#: ../java/src/net/i2p/router/web/SummaryHelper.java:809 #: ../java/src/net/i2p/router/web/SummaryHelper.java:810
msgid "Remove" msgid "Remove"
msgstr "Rimuovi" msgstr "Rimuovi"
@@ -2448,12 +2448,12 @@ msgstr "Aggiornamento porta TCP a {0}"
#: ../java/src/net/i2p/router/web/ConfigNetHandler.java:224 #: ../java/src/net/i2p/router/web/ConfigNetHandler.java:224
#: ../java/src/net/i2p/router/web/ConfigNetHandler.java:249 #: ../java/src/net/i2p/router/web/ConfigNetHandler.java:249
msgid "Warning - ports less than 1024 are not recommended" msgid "Warning - ports less than 1024 are not recommended"
msgstr "" msgstr "Attenzione - è meglio non utilizzare le porte da 0 a 1024!"
#: ../java/src/net/i2p/router/web/ConfigNetHandler.java:228 #: ../java/src/net/i2p/router/web/ConfigNetHandler.java:228
#: ../java/src/net/i2p/router/web/ConfigNetHandler.java:255 #: ../java/src/net/i2p/router/web/ConfigNetHandler.java:255
msgid "Invalid port" msgid "Invalid port"
msgstr "" msgstr "Porta non valida"
#: ../java/src/net/i2p/router/web/ConfigNetHandler.java:233 #: ../java/src/net/i2p/router/web/ConfigNetHandler.java:233
msgid "Updating inbound TCP port to auto" msgid "Updating inbound TCP port to auto"
@@ -2462,7 +2462,7 @@ msgstr "Aggiornando le porte TCP entranti a automatiche"
#: ../java/src/net/i2p/router/web/ConfigNetHandler.java:247 #: ../java/src/net/i2p/router/web/ConfigNetHandler.java:247
#, java-format #, java-format
msgid "Updating UDP port to {0}" msgid "Updating UDP port to {0}"
msgstr "" msgstr "Aggiornamento porta UDP a {0}"
#: ../java/src/net/i2p/router/web/ConfigNetHandler.java:272 #: ../java/src/net/i2p/router/web/ConfigNetHandler.java:272
msgid "Gracefully restarting into Hidden Router Mode" msgid "Gracefully restarting into Hidden Router Mode"
@@ -2502,7 +2502,7 @@ msgstr "Introduttori SSU richiesti"
#: ../java/src/net/i2p/router/web/ConfigNetHandler.java:369 #: ../java/src/net/i2p/router/web/ConfigNetHandler.java:369
msgid "Invalid address" msgid "Invalid address"
msgstr "" msgstr "Indirizzo non valido"
#: ../java/src/net/i2p/router/web/ConfigNetHandler.java:374 #: ../java/src/net/i2p/router/web/ConfigNetHandler.java:374
#, java-format #, java-format
@@ -2745,11 +2745,11 @@ msgstr "La console non verrà mostrata all'avvio"
#: ../java/src/net/i2p/router/web/ConfigServiceHandler.java:221 #: ../java/src/net/i2p/router/web/ConfigServiceHandler.java:221
#: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:457 #: ../jsp/WEB-INF/classes/net/i2p/router/web/jsp/configservice_jsp.java:457
msgid "Force GC" msgid "Force GC"
msgstr "" msgstr "Forza GC"
#: ../java/src/net/i2p/router/web/ConfigServiceHandler.java:223 #: ../java/src/net/i2p/router/web/ConfigServiceHandler.java:223
msgid "Full garbage collection requested" msgid "Full garbage collection requested"
msgstr "" msgstr "Richieste totali"
#: ../java/src/net/i2p/router/web/ConfigServiceHandler.java:232 #: ../java/src/net/i2p/router/web/ConfigServiceHandler.java:232
msgid "Service installed" msgid "Service installed"
@@ -3468,7 +3468,7 @@ msgstr ""
"Il tuo browser non è configurato correttamente per usare il proxy HTTP al {0}" "Il tuo browser non è configurato correttamente per usare il proxy HTTP al {0}"
#: ../java/src/net/i2p/router/web/HomeHelper.java:194 #: ../java/src/net/i2p/router/web/HomeHelper.java:194
#: ../java/src/net/i2p/router/web/SummaryHelper.java:811 #: ../java/src/net/i2p/router/web/SummaryHelper.java:812
msgid "Name" msgid "Name"
msgstr "Nome" msgstr "Nome"
@@ -3477,7 +3477,7 @@ msgid "URL"
msgstr "URL" msgstr "URL"
#: ../java/src/net/i2p/router/web/HomeHelper.java:214 #: ../java/src/net/i2p/router/web/HomeHelper.java:214
#: ../java/src/net/i2p/router/web/SummaryHelper.java:857 #: ../java/src/net/i2p/router/web/SummaryHelper.java:858
msgid "Add" msgid "Add"
msgstr "Aggiungi" msgstr "Aggiungi"
@@ -4135,37 +4135,37 @@ msgstr "Bannato fino al riavvio o in {0}"
msgid "unban now" msgid "unban now"
msgstr "riammissione istantanea" msgstr "riammissione istantanea"
#: ../java/src/net/i2p/router/web/StatSummarizer.java:314 #: ../java/src/net/i2p/router/web/StatSummarizer.java:312
msgid "Bandwidth usage" msgid "Bandwidth usage"
msgstr "Utilizzo di larghezza di banda" msgstr "Utilizzo di larghezza di banda"
#: ../java/src/net/i2p/router/web/StatSummarizer.java:324 #: ../java/src/net/i2p/router/web/StatSummarizer.java:322
msgid "Outbound Bytes/sec" msgid "Outbound Bytes/sec"
msgstr "Bytes/s In Uscita" msgstr "Bytes/s In Uscita"
#. def.line(sendName, Color.BLUE, "Outbound bytes/sec", 3); #. def.line(sendName, Color.BLUE, "Outbound bytes/sec", 3);
#: ../java/src/net/i2p/router/web/StatSummarizer.java:326 #: ../java/src/net/i2p/router/web/StatSummarizer.java:324
msgid "Inbound Bytes/sec" msgid "Inbound Bytes/sec"
msgstr "Bytes/s In Entrata" msgstr "Bytes/s In Entrata"
#: ../java/src/net/i2p/router/web/StatSummarizer.java:327
#: ../java/src/net/i2p/router/web/StatSummarizer.java:328
#: ../java/src/net/i2p/router/web/StatSummarizer.java:329 #: ../java/src/net/i2p/router/web/StatSummarizer.java:329
#: ../java/src/net/i2p/router/web/StatSummarizer.java:330 #: ../java/src/net/i2p/router/web/StatSummarizer.java:330
#: ../java/src/net/i2p/router/web/StatSummarizer.java:331
#: ../java/src/net/i2p/router/web/StatSummarizer.java:332
msgid "Bps" msgid "Bps"
msgstr "Bps" msgstr "Bps"
#: ../java/src/net/i2p/router/web/StatSummarizer.java:329 #: ../java/src/net/i2p/router/web/StatSummarizer.java:327
msgid "Out average" msgid "Out average"
msgstr "Media In Uscita" msgstr "Media In Uscita"
#: ../java/src/net/i2p/router/web/StatSummarizer.java:328
#: ../java/src/net/i2p/router/web/StatSummarizer.java:330 #: ../java/src/net/i2p/router/web/StatSummarizer.java:330
#: ../java/src/net/i2p/router/web/StatSummarizer.java:332
#: ../java/src/net/i2p/router/web/SummaryRenderer.java:155 #: ../java/src/net/i2p/router/web/SummaryRenderer.java:155
msgid "max" msgid "max"
msgstr "massimo" msgstr "massimo"
#: ../java/src/net/i2p/router/web/StatSummarizer.java:331 #: ../java/src/net/i2p/router/web/StatSummarizer.java:329
msgid "In average" msgid "In average"
msgstr "Media In Entrata" msgstr "Media In Entrata"
@@ -4678,13 +4678,13 @@ msgstr "Costruendo i tunnel"
#. nicely under 'local destinations' in the summary bar #. nicely under 'local destinations' in the summary bar
#. note that if the wording changes in i2ptunnel.config, we have to #. note that if the wording changes in i2ptunnel.config, we have to
#. keep the old string here as well for existing installs #. keep the old string here as well for existing installs
#: ../java/src/net/i2p/router/web/SummaryHelper.java:462 #: ../java/src/net/i2p/router/web/SummaryHelper.java:459
#: ../java/strings/Strings.java:36 #: ../java/strings/Strings.java:36
msgid "shared clients" msgid "shared clients"
msgstr "client condivisi" msgstr "client condivisi"
#. Note to translators: parameter is a version, e.g. "0.8.4" #. Note to translators: parameter is a version, e.g. "0.8.4"
#: ../java/src/net/i2p/router/web/SummaryHelper.java:676 #: ../java/src/net/i2p/router/web/SummaryHelper.java:677
#, java-format #, java-format
msgid "Download {0} Update" msgid "Download {0} Update"
msgstr "Scaricamento {0} Aggiornamento" msgstr "Scaricamento {0} Aggiornamento"
@@ -4692,40 +4692,40 @@ msgstr "Scaricamento {0} Aggiornamento"
#. Note to translators: parameter is a date and time, e.g. "02-Mar 20:34 UTC" #. Note to translators: parameter is a date and time, e.g. "02-Mar 20:34 UTC"
#. <br> is optional, to help the browser make the lines even in the button #. <br> is optional, to help the browser make the lines even in the button
#. If the translation is shorter than the English, you should probably not include <br> #. If the translation is shorter than the English, you should probably not include <br>
#: ../java/src/net/i2p/router/web/SummaryHelper.java:684 #: ../java/src/net/i2p/router/web/SummaryHelper.java:685
#, java-format #, java-format
msgid "Download Unsigned<br>Update {0}" msgid "Download Unsigned<br>Update {0}"
msgstr "Scaricamento Aggiornamento {0} Non Firmato<br>" msgstr "Scaricamento Aggiornamento {0} Non Firmato<br>"
#: ../java/src/net/i2p/router/web/SummaryHelper.java:709 #: ../java/src/net/i2p/router/web/SummaryHelper.java:710
msgid "Help with firewall configuration" msgid "Help with firewall configuration"
msgstr "Aiuto con la configurazione del firewall" msgstr "Aiuto con la configurazione del firewall"
#: ../java/src/net/i2p/router/web/SummaryHelper.java:711 #: ../java/src/net/i2p/router/web/SummaryHelper.java:712
msgid "Check network connection and NAT/firewall" msgid "Check network connection and NAT/firewall"
msgstr "Controlla la connessione di rete e il NAT/firewall" msgstr "Controlla la connessione di rete e il NAT/firewall"
#: ../java/src/net/i2p/router/web/SummaryHelper.java:730 #: ../java/src/net/i2p/router/web/SummaryHelper.java:731
msgid "Reseed" msgid "Reseed"
msgstr "Reseed" msgstr "Reseed"
#: ../java/src/net/i2p/router/web/SummaryHelper.java:813 #: ../java/src/net/i2p/router/web/SummaryHelper.java:814
msgid "Order" msgid "Order"
msgstr "Ordine" msgstr "Ordine"
#: ../java/src/net/i2p/router/web/SummaryHelper.java:830 #: ../java/src/net/i2p/router/web/SummaryHelper.java:831
msgid "Top" msgid "Top"
msgstr "Sopra" msgstr "Sopra"
#: ../java/src/net/i2p/router/web/SummaryHelper.java:843 #: ../java/src/net/i2p/router/web/SummaryHelper.java:844
msgid "Down" msgid "Down"
msgstr "Sotto" msgstr "Sotto"
#: ../java/src/net/i2p/router/web/SummaryHelper.java:848 #: ../java/src/net/i2p/router/web/SummaryHelper.java:849
msgid "Bottom" msgid "Bottom"
msgstr "Basso" msgstr "Basso"
#: ../java/src/net/i2p/router/web/SummaryHelper.java:860 #: ../java/src/net/i2p/router/web/SummaryHelper.java:861
msgid "Select a section to add" msgid "Select a section to add"
msgstr "Seleziona una sezione da aggiungere" msgstr "Seleziona una sezione da aggiungere"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -77,6 +77,8 @@ class Connection {
private final SimpleTimer2 _timer; private final SimpleTimer2 _timer;
private long _lifetimeBytesSent; private long _lifetimeBytesSent;
/** TBD for tcpdump-compatible ack output */
private long _lowestBytesAckedThrough;
private long _lifetimeBytesReceived; private long _lifetimeBytesReceived;
private long _lifetimeDupMessageSent; private long _lifetimeDupMessageSent;
private long _lifetimeDupMessageReceived; private long _lifetimeDupMessageReceived;
@@ -974,7 +976,7 @@ class Connection {
switch (_options.getInactivityAction()) { switch (_options.getInactivityAction()) {
case ConnectionOptions.INACTIVITY_ACTION_NOOP: case ConnectionOptions.INACTIVITY_ACTION_NOOP:
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Inactivity timer expired, but we aint doin' shit"); _log.warn("Inactivity timer expired, not doing anything");
break; break;
case ConnectionOptions.INACTIVITY_ACTION_SEND: case ConnectionOptions.INACTIVITY_ACTION_SEND:
if (_closeSentOn <= 0 && _closeReceivedOn <= 0) { if (_closeSentOn <= 0 && _closeReceivedOn <= 0) {

View File

@@ -194,6 +194,11 @@ class ConnectionHandler {
// between here and PacketHandler, causing the packet to loop forever.... // between here and PacketHandler, causing the packet to loop forever....
_manager.getPacketHandler().receivePacketDirect(packet, false); _manager.getPacketHandler().receivePacketDirect(packet, false);
} else { } else {
// log it here, just before we kill it - dest will be unknown
if (I2PSocketManagerFull.pcapWriter != null &&
_context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
packet.logTCPDump(null);
// goodbye // goodbye
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.WARN))
_log.warn("Did not find con for queued non-syn packet, dropping: " + packet); _log.warn("Did not find con for queued non-syn packet, dropping: " + packet);

View File

@@ -266,6 +266,10 @@ class ConnectionManager {
} }
con.setReceiveStreamId(receiveId); con.setReceiveStreamId(receiveId);
// finally, we know enough that we can log the packet with the conn filled in
if (I2PSocketManagerFull.pcapWriter != null &&
_context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
synPacket.logTCPDump(con);
try { try {
// This validates the packet, and sets the con's SendStreamID and RemotePeer // This validates the packet, and sets the con's SendStreamID and RemotePeer
con.getPacketHandler().receivePacket(synPacket, con); con.getPacketHandler().receivePacket(synPacket, con);

View File

@@ -85,6 +85,7 @@ public class I2PSocketManagerFull implements I2PSocketManager {
_log.info("Socket manager created. \ndefault options: " + _defaultOptions _log.info("Socket manager created. \ndefault options: " + _defaultOptions
+ "\noriginal properties: " + opts); + "\noriginal properties: " + opts);
} }
debugInit(context);
} }
/** /**
@@ -314,6 +315,8 @@ public class I2PSocketManagerFull implements I2PSocketManager {
} catch (I2PSessionException ise) { } catch (I2PSessionException ise) {
_log.warn("Unable to destroy the session", ise); _log.warn("Unable to destroy the session", ise);
} }
if (pcapWriter != null)
pcapWriter.flush();
} }
} }
@@ -342,4 +345,25 @@ public class I2PSocketManagerFull implements I2PSocketManager {
public void removeDisconnectListener(I2PSocketManager.DisconnectListener lsnr) { public void removeDisconnectListener(I2PSocketManager.DisconnectListener lsnr) {
_connectionManager.getMessageHandler().removeDisconnectListener(lsnr); _connectionManager.getMessageHandler().removeDisconnectListener(lsnr);
} }
private static final Object _pcapInitLock = new Object();
private static boolean _pcapInitialized;
static PcapWriter pcapWriter;
static final String PROP_PCAP = "i2p.streaming.pcap";
private static final String PCAP_FILE = "streaming.pcap";
private static void debugInit(I2PAppContext ctx) {
if (!ctx.getBooleanProperty(PROP_PCAP))
return;
synchronized(_pcapInitLock) {
if (!_pcapInitialized) {
try {
pcapWriter = new PcapWriter(ctx, PCAP_FILE);
} catch (java.io.IOException ioe) {
System.err.println("pcap init ioe: " + ioe);
}
_pcapInitialized = true;
}
}
}
} }

View File

@@ -1,5 +1,6 @@
package net.i2p.client.streaming; package net.i2p.client.streaming;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
@@ -16,7 +17,8 @@ import net.i2p.util.Log;
* This contains solely the data that goes out on the wire, * This contains solely the data that goes out on the wire,
* including the local and remote port which is embedded in * including the local and remote port which is embedded in
* the I2CP overhead, not in the packet itself. * the I2CP overhead, not in the packet itself.
* For local state saved for outbound packets, see PacketLocal. * This is the class used for inbound packets.
* For local state saved for outbound packets, see the PacketLocal extension.
* *
* <p> * <p>
* *
@@ -709,4 +711,14 @@ class Packet {
if (isFlagSet(FLAG_SYNCHRONIZE)) buf.append(" SYN"); if (isFlagSet(FLAG_SYNCHRONIZE)) buf.append(" SYN");
return buf.toString(); return buf.toString();
} }
/** Generate a pcap/tcpdump-compatible format,
* so we can use standard debugging tools.
*/
public void logTCPDump(Connection con) {
try {
I2PSocketManagerFull.pcapWriter.write(this, con);
} catch (IOException ioe) {
}
}
} }

View File

@@ -108,6 +108,8 @@ class PacketHandler {
receiveUnknownCon(packet, sendId, queueIfNoConn); receiveUnknownCon(packet, sendId, queueIfNoConn);
displayPacket(packet, "UNKN", null); displayPacket(packet, "UNKN", null);
} }
// Don't log here, wait until we have the conn to make the dumps easier to follow
//((PacketLocal)packet).logTCPDump(true);
} }
private static final SimpleDateFormat _fmt = new SimpleDateFormat("HH:mm:ss.SSS"); private static final SimpleDateFormat _fmt = new SimpleDateFormat("HH:mm:ss.SSS");
@@ -128,6 +130,10 @@ class PacketHandler {
} }
private void receiveKnownCon(Connection con, Packet packet) { private void receiveKnownCon(Connection con, Packet packet) {
// is this ok here or does it need to be below each packetHandler().receivePacket() ?
if (I2PSocketManagerFull.pcapWriter != null &&
_context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
packet.logTCPDump(con);
if (packet.isFlagSet(Packet.FLAG_ECHO)) { if (packet.isFlagSet(Packet.FLAG_ECHO)) {
if (packet.getSendStreamId() > 0) { if (packet.getSendStreamId() > 0) {
if (con.getOptions().getAnswerPings()) if (con.getOptions().getAnswerPings())
@@ -282,8 +288,13 @@ class PacketHandler {
} }
if (packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) { if (packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) {
// logTCPDump() will be called in ConnectionManager.receiveConnection(),
// which is called by ConnectionHandler.receiveNewSyn(),
// after we have a new conn, which makes the logging better.
_manager.getConnectionHandler().receiveNewSyn(packet); _manager.getConnectionHandler().receiveNewSyn(packet);
} else if (queueIfNoConn) { } else if (queueIfNoConn) {
// don't call logTCPDump() here, wait for it to find a conn
// We can get here on the 2nd+ packet if the 1st (SYN) packet // We can get here on the 2nd+ packet if the 1st (SYN) packet
// is still on the _synQueue in the ConnectionHandler, and // is still on the _synQueue in the ConnectionHandler, and
// ConnectionManager.receiveConnection() hasn't run yet to put // ConnectionManager.receiveConnection() hasn't run yet to put
@@ -307,6 +318,10 @@ class PacketHandler {
//packet.releasePayload(); //packet.releasePayload();
_manager.getConnectionHandler().receiveNewSyn(packet); _manager.getConnectionHandler().receiveNewSyn(packet);
} else { } else {
// log it here, just before we kill it - dest will be unknown
if (I2PSocketManagerFull.pcapWriter != null &&
_context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
packet.logTCPDump(null);
// don't queue again (infinite loop!) // don't queue again (infinite loop!)
sendReset(packet); sendReset(packet);
packet.releasePayload(); packet.releasePayload();

View File

@@ -1,5 +1,6 @@
package net.i2p.client.streaming; package net.i2p.client.streaming;
import java.io.IOException;
import java.util.Set; import java.util.Set;
import net.i2p.I2PAppContext; import net.i2p.I2PAppContext;
@@ -9,6 +10,8 @@ import net.i2p.util.Log;
import net.i2p.util.SimpleTimer2; import net.i2p.util.SimpleTimer2;
/** /**
* This is the class used for outbound packets.
*
* coordinate local attributes about a packet - send time, ack time, number of * coordinate local attributes about a packet - send time, ack time, number of
* retries, etc. * retries, etc.
*/ */
@@ -256,4 +259,15 @@ class PacketLocal extends Packet implements MessageOutputStream.WriteStatus {
public boolean writeAccepted() { return _acceptedOn > 0 && _cancelledOn <= 0; } public boolean writeAccepted() { return _acceptedOn > 0 && _cancelledOn <= 0; }
public boolean writeFailed() { return _cancelledOn > 0; } public boolean writeFailed() { return _cancelledOn > 0; }
public boolean writeSuccessful() { return _ackOn > 0 && _cancelledOn <= 0; } public boolean writeSuccessful() { return _ackOn > 0 && _cancelledOn <= 0; }
/** Generate a pcap/tcpdump-compatible format,
* so we can use standard debugging tools.
*/
public void logTCPDump() {
try {
I2PSocketManagerFull.pcapWriter.write(this);
} catch (IOException ioe) {
_log.warn("pcap write ioe: " + ioe);
}
}
} }

View File

@@ -169,6 +169,9 @@ class PacketQueue {
Connection c = packet.getConnection(); Connection c = packet.getConnection();
String suffix = (c != null ? "wsize " + c.getOptions().getWindowSize() + " rto " + c.getOptions().getRTO() : null); String suffix = (c != null ? "wsize " + c.getOptions().getWindowSize() + " rto " + c.getOptions().getRTO() : null);
_connectionManager.getPacketHandler().displayPacket(packet, "SEND", suffix); _connectionManager.getPacketHandler().displayPacket(packet, "SEND", suffix);
if (I2PSocketManagerFull.pcapWriter != null &&
_context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
((PacketLocal)packet).logTCPDump();
} }
if ( (packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) ) { if ( (packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) ) {

View File

@@ -0,0 +1,382 @@
package net.i2p.client.streaming;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
/**
* Write a standard pcap file with a "TCP" packet that can be analyzed with
* standard tools such as wireshark.
*
* The source and dest "IP" and "port" are fake but are generated from the
* hashes of the Destinations and stream ID's, so they will be consistent.
* The local "IP" will always be of the form 127.0.x.y
* Initial IP for a conn will be 127.0.0.0 for the local and 0.0.0.0 for the remote.
*
* Reference: http://wiki.wireshark.org/Development/LibpcapFileFormat
*
* The Jpcap library http://netresearch.ics.uci.edu/kfujii/jpcap/doc/
* was close to what I want, but it requires you to instantiate a "captor"
* before you can write a file, and it requires a native lib to do so,
* and even then, it only wants to read the file, not write it.
*
* We even calculate a correct TCP header checksum to keep the tools happy.
* We don't, however, convert I2P-style sequence numbers, which count packets,
* to TCP-style byte counts. We don't track a lowest-acked-thru byte count atm, really.
*
* We do represent the window size in bytes though, so that's real confusing.
*
* This is designed to debug the streaming lib, but there are not log calls for every
* single packet - pings and pongs, and various odd cases where received packets
* are dropped, are not logged.
*
* Yes we could dump it natively and write a wireshark dissector. That sounds hard.
* And we wouldn't get the TCP stream analysis built into the tools.
*
* @author zzz
*/
public class PcapWriter {
/** big-endian, see file format ref - 24 bytes */
private static final byte[] FILE_HEADER = { (byte) 0xa1, (byte) 0xb2, (byte) 0xc3, (byte) 0xd4,
0, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, (byte) 0xff, (byte) 0xff, 0, 0, 0, 1 };
/** dummy macs and ethertype */
private static final byte[] MAC_HEADER = { 1, 2, 3, 4, 5, 6,
1, 2, 3, 4, 5, 6,
(byte) 0x80, 0 };
private static final byte[] IP_HEADER_1 = { 0x45, 0 }; // the length goes after this
private static final byte[] IP_HEADER_2 = { 0x12, 0x34, 0x40, 0, 64, 6 }; // ID, flags, TTL and TCP
private static final byte[] UNK_IP = { (byte) 0xff, 0, 0, 0};
private static final byte[] MY_UNK_IP = {127, 0, 0, 0};
/** max # of streaming lib payload bytes to dump */
private static final int MAX_PAYLOAD_BYTES = 10;
/** options - give our custom ones some mnemonics */
private static final int MAX_OPTION_LEN = 40;
private static final byte OPTION_END = 0;
private static final byte OPTION_MSS = 2;
private static final byte OPTION_PING = 6;
private static final byte OPTION_PONG = 7;
private static final byte OPTION_SIGREQ = 0x55;
private static final byte OPTION_SIG = 0x56;
private static final byte OPTION_RDELAY = (byte) 0xde;
private static final byte OPTION_ODELAY = (byte) 0xd0;
private static final byte OPTION_FROM = (byte) 0xf0;
private static final byte OPTION_NACK = (byte) 0xac;
private final OutputStream _fos;
private final I2PAppContext _context;
public PcapWriter(I2PAppContext ctx, String file) throws IOException {
_context = ctx;
File f = new File(ctx.getLogDir(), file);
//if (f.exists()) {
// _fos = new FileOutputStream(f, true);
//} else {
_fos = new BufferedOutputStream(new FileOutputStream(f), 64*1024);
_fos.write(FILE_HEADER);
//}
}
public void close() {
try {
_fos.close();
} catch (IOException ioe) {}
}
public void flush() {
try {
_fos.flush();
} catch (IOException ioe) {}
}
/**
* For outbound packets
*/
public void write(PacketLocal pkt) throws IOException {
try {
wrt(pkt, pkt.getConnection(), false);
} catch (DataFormatException dfe) {
dfe.printStackTrace();
throw new IOException(dfe.toString());
}
}
/**
* For inbound packets
* @param con may be null
*/
public void write(Packet pkt, Connection con) throws IOException {
try {
wrt(pkt, con, true);
} catch (DataFormatException dfe) {
dfe.printStackTrace();
throw new IOException(dfe.toString());
}
}
/**
* @param con may be null
*/
private synchronized void wrt(Packet pkt, Connection con, boolean isInbound) throws IOException, DataFormatException {
int includeLen = Math.min(MAX_PAYLOAD_BYTES, pkt.getPayloadSize());
// option block
Options opts = new Options();
if (pkt.isFlagSet(Packet.FLAG_MAX_PACKET_SIZE_INCLUDED))
opts.add(OPTION_MSS, 2, pkt.getOptionalMaxSize());
if (pkt.isFlagSet(Packet.FLAG_DELAY_REQUESTED))
opts.add(OPTION_ODELAY, 2, pkt.getOptionalDelay());
if (pkt.getResendDelay() > 0)
opts.add(OPTION_RDELAY, 1, pkt.getResendDelay());
if (pkt.isFlagSet(Packet.FLAG_SIGNATURE_REQUESTED))
opts.add(OPTION_SIGREQ);
if (pkt.isFlagSet(Packet.FLAG_SIGNATURE_INCLUDED))
opts.add(OPTION_SIG);
if (pkt.isFlagSet(Packet.FLAG_FROM_INCLUDED))
opts.add(OPTION_FROM);
if (pkt.isFlagSet(Packet.FLAG_ECHO)) {
if (pkt.getSendStreamId() > 0)
opts.add(OPTION_PING);
else
opts.add(OPTION_PONG);
}
if (pkt.getNacks() != null)
opts.add(OPTION_NACK, 1, pkt.getNacks().length);
int optLen = opts.size();
byte options[] = opts.getData();
// PCAP Header
long now;
if (isInbound)
now = _context.clock().now();
else
now = ((PacketLocal)pkt).getLastSend();
DataHelper.writeLong(_fos, 4, now / 1000);
DataHelper.writeLong(_fos, 4, 1000 * (now % 1000));
DataHelper.writeLong(_fos, 4, 54 + optLen + includeLen); // 14 MAC + 20 IP + 20 TCP
DataHelper.writeLong(_fos, 4, 58 + optLen + pkt.getPayloadSize()); // 54 + MAC checksum
// MAC Header 14 bytes
_fos.write(MAC_HEADER);
// IP 20 bytes total
// IP Header 12 bytes
int length = 20 + 20 + optLen + pkt.getPayloadSize();
_fos.write(IP_HEADER_1);
DataHelper.writeLong(_fos, 2, length); // total IP length
_fos.write(IP_HEADER_2);
// src and dst IP 8 bytes
// make our side always start with 127.0.x.x
byte[] srcAddr, dstAddr;
if (isInbound) {
if (con != null) {
dstAddr = new byte[4];
dstAddr[0] = 127;
dstAddr[1] = 0;
System.arraycopy(con.getSession().getMyDestination().calculateHash().getData(), 0, dstAddr, 2, 2);
} else
dstAddr = MY_UNK_IP;
if (con != null && con.getRemotePeer() != null)
srcAddr = con.getRemotePeer().calculateHash().getData();
else if (pkt.getOptionalFrom() != null)
srcAddr = pkt.getOptionalFrom().calculateHash().getData();
else
srcAddr = UNK_IP;
} else {
if (con != null) {
srcAddr = new byte[4];
srcAddr[0] = 127;
srcAddr[1] = 0;
System.arraycopy(con.getSession().getMyDestination().calculateHash().getData(), 0, srcAddr, 2, 2);
} else
srcAddr = MY_UNK_IP;
if (con != null && con.getRemotePeer() != null)
dstAddr = con.getRemotePeer().calculateHash().getData();
else
dstAddr = UNK_IP;
}
// calculate and output the correct IP header checksum to keep the analyzers happy
int checksum = length;
checksum = update(checksum, IP_HEADER_1);
checksum = update(checksum, IP_HEADER_2);
checksum = update(checksum, srcAddr, 4);
checksum = update(checksum, dstAddr, 4);
DataHelper.writeLong(_fos, 2, checksum ^ 0xffff);
// IPs
_fos.write(srcAddr, 0, 4);
_fos.write(dstAddr, 0, 4);
// TCP header 20 bytes total
// src and dst port 4 bytes
// the rcv ID is the source, and the send ID is the dest.
DataHelper.writeLong(_fos, 2, pkt.getReceiveStreamId() & 0xffff);
DataHelper.writeLong(_fos, 2, pkt.getSendStreamId() & 0xffff);
// seq and acks 8 bytes
long seq;
// wireshark wants the seq # in a SYN packet to be one less than the first data packet,
// so let's set it to 0. ???????????
if (pkt.isFlagSet(Packet.FLAG_SYNCHRONIZE))
seq = 0xffffffff;
else
seq = pkt.getSequenceNum();
long acked = 0;
if (con != null) {
if (isInbound)
acked = getLowestAckedThrough(pkt, con);
else
acked = getLowestAckedThrough(pkt, con);
}
DataHelper.writeLong(_fos, 4, pkt.getSequenceNum());
DataHelper.writeLong(_fos, 4, acked);
// offset and flags 2 bytes
int flags = 0;
if (pkt.isFlagSet(Packet.FLAG_CLOSE))
flags |= 0x01;
if (pkt.isFlagSet(Packet.FLAG_SYNCHRONIZE))
flags |= 0x02;
if (pkt.isFlagSet(Packet.FLAG_RESET))
flags |= 0x04;
if (!pkt.isFlagSet(Packet.FLAG_NO_ACK))
flags |= 0x10;
// offset byte
int osb = (5 + (optLen / 4)) << 4;
DataHelper.writeLong(_fos, 1, osb); // 5 + optLen/4 32-byte words
DataHelper.writeLong(_fos, 1, flags);
// window size 2 bytes
long window = ConnectionOptions.INITIAL_WINDOW_SIZE;
long msgSize = ConnectionOptions.DEFAULT_MAX_MESSAGE_SIZE;
if (con != null) {
if (isInbound) {
// try to represent what he thinks the window is, we don't really know
// this isn't really right, the lastsendid can get way ahead
window = acked + con.getOptions().getWindowSize() - con.getLastSendId();
} else {
// following is from ConnectionPacketHandler
long ready = con.getInputStream().getHighestReadyBockId();
int available = con.getOptions().getInboundBufferSize() - con.getInputStream().getTotalReadySize();
int allowedBlocks = available/con.getOptions().getMaxMessageSize();
window = (ready + allowedBlocks) - pkt.getSequenceNum();
}
if (window < 0)
window = 0;
msgSize = con.getOptions().getMaxMessageSize();
}
// messages -> bytes
window *= msgSize;
// for now we don't spoof window scaling
if (window > 65535)
window = 65535;
DataHelper.writeLong(_fos, 2, window);
// checksum and urgent pointer 4 bytes
DataHelper.writeLong(_fos, 4, 0);
// TCP option block
if (optLen > 0)
_fos.write(options, 0, optLen);
// some data
if (includeLen > 0)
_fos.write(pkt.getPayload().getData(), 0, includeLen);
if (pkt.isFlagSet(Packet.FLAG_CLOSE))
_fos.flush();
}
/**
* copied from Connection.ackPackets()
*
* This is really nasty, but if the packet has an ACK, then we
* find the lowest NACK, and we are acked thru the lowest - 1.
*
* If there is no ACK, then we could use the conn's highest acked through,
* for an inbound packet (containing acks for outbound packets)
* But it appears that all packets have ACKs, as FLAG_NO_ACK is never set.
*
* To do: Add the SACK option to the TCP header.
*/
private static long getLowestAckedThrough(Packet pkt, Connection con) {
long nacks[] = pkt.getNacks();
long lowest = pkt.getAckThrough(); // can return -1 but we increment below
if (nacks != null) {
for (int i = 0; i < nacks.length; i++) {
if (nacks[i] - 1 < lowest)
lowest = nacks[i] - 1;
}
}
// I2P ack is of current seq number; TCP is next expected seq number
// should be >= 0 now
lowest++;
// just in case
return Math.max(0, lowest);
}
private static class Options {
private final byte[] _b;
private int _len;
public Options() {
_b = new byte[MAX_OPTION_LEN];
}
/** 40 bytes long, caller must use size() to get actual size */
public byte[] getData() { return _b; }
/** rounded to next 4 bytes */
public int size() { return ((_len + 3) / 4) * 4; }
public void add(byte type) {
add(type, 0, 0);
}
public void add(byte type, int datalen, int data) {
// no room? drop silently
if (_len + datalen + 2 > MAX_OPTION_LEN)
return;
_b[_len++] = type;
_b[_len++] = (byte) (datalen + 2);
if (datalen > 0) {
for (int i = datalen - 1; i >= 0; i--)
_b[_len++] = (byte) ((data >> (i * 8)) & 0xff);
}
// end-of-options mark
if (_len < MAX_OPTION_LEN)
_b[_len] = OPTION_END;
}
}
/** one's complement 2-byte checksum update */
private static int update(int checksum, byte[] b) {
return update(checksum, b, b.length);
}
private static int update(int checksum, byte[] b, int len) {
int rv = checksum;
for (int i = 0; i < len; i += 2) {
rv += ((b[i] << 8) & 0xff00) | (b[i+1] & 0xff);
if (rv > 0xffff) {
rv &= 0xffff;
rv++;
}
}
return rv;
}
}

View File

@@ -0,0 +1,704 @@
# I2P
# Copyright (C) 2009 The I2P Project
# This file is distributed under the same license as the susidns package.
# To contribute translations, see http://www.i2p2.de/newdevelopers
#
# Translators:
# <rutweiller@hotmail.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: I2P\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-10-19 07:45+0000\n"
"PO-Revision-Date: 2012-10-17 23:34+0000\n"
"Last-Translator: Ruthein <rutweiller@hotmail.com>\n"
"Language-Team: Portuguese (http://www.transifex.com/projects/p/I2P/language/"
"pt/)\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ../src/java/src/i2p/susi/dns/AddressBean.java:130
#, java-format
msgid "Host name \"{0}\" contains illegal character {1}"
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressBean.java:143
#: ../src/java/src/i2p/susi/dns/AddressBean.java:145
#: ../src/java/src/i2p/susi/dns/AddressBean.java:152
#, java-format
msgid "Host name cannot start with \"{0}\""
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressBean.java:147
#: ../src/java/src/i2p/susi/dns/AddressBean.java:149
#, java-format
msgid "Host name cannot end with \"{0}\""
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressBean.java:154
#, java-format
msgid "Host name cannot contain \"{0}\""
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressBean.java:157
#, java-format
msgid ""
"Host name \"{0}\" requires conversion to ASCII but the conversion library is "
"unavailable in this JVM"
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressBean.java:218
msgid "None"
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressBean.java:226
msgid "Hashcash"
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressBean.java:228
msgid "Hidden"
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressBean.java:230
msgid "Signed"
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressBean.java:232
#, java-format
msgid "Type {0}"
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:202
#, java-format
msgid "One result for search within filtered list."
msgid_plural "{0} results for search within filtered list."
msgstr[0] ""
msgstr[1] ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:206
#, java-format
msgid "Filtered list contains 1 entry."
msgid_plural "Fltered list contains {0} entries."
msgstr[0] ""
msgstr[1] ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:211
#, java-format
msgid "One result for search."
msgid_plural "{0} results for search."
msgstr[0] ""
msgstr[1] ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:220
#, java-format
msgid "Address book contains 1 entry."
msgid_plural "Address book contains {0} entries."
msgstr[0] ""
msgstr[1] ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:236
#, java-format
msgid "Showing {0} of {1}"
msgstr "Showing {0} of {1}"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:257
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:227
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:412
msgid "Add"
msgstr "Add"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:257
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:268
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:227
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:239
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:410
msgid "Replace"
msgstr "Replace"
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:267
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:238
#, java-format
msgid "Host name {0} is already in address book, unchanged."
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:269
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:240
#, java-format
msgid ""
"Host name {0} is already in address book with a different destination. Click "
"\"Replace\" to overwrite."
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:282
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:253
#, java-format
msgid "Destination added for {0}."
msgstr "Destination added for {0}."
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:284
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:255
#, java-format
msgid "Destination changed for {0}."
msgstr "Destination changed for {0}."
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:286
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:257
msgid "Warning - host name does not end with \".i2p\""
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:291
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:265
msgid "Invalid Base 64 destination."
msgstr "Invalid destination Base 64 ."
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:297
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:271
#, java-format
msgid "Invalid host name \"{0}\"."
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:300
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:274
msgid "Please enter a host name and destination"
msgstr "Please enter a host name and destination"
#. clear search when deleting
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:304
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:325
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:278
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:303
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:274
msgid "Delete Entry"
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:304
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:278
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:351
msgid "Delete Selected"
msgstr "Delete Selected"
#. parameter is a host name
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:318
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:295
#, java-format
msgid "Destination {0} deleted."
msgstr "Destination {0} deleted."
#. parameter will always be >= 2
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:321
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:298
#, java-format
msgid "1 destination deleted."
msgid_plural "{0} destinations deleted."
msgstr[0] ""
msgstr[1] ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:323
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:300
msgid "No entries selected to delete."
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:331
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:307
msgid "Address book saved."
msgstr ""
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:334
msgid "ERROR: Could not write addressbook file."
msgstr "ERROR: Could not write addressbook file."
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:339
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:148
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:311
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:128
msgid ""
"Invalid form submission, probably because you used the \"back\" or \"reload"
"\" button on your browser. Please resubmit."
msgstr ""
"Invalid form submission, probably because you used the \"back\" or \"reload"
"\" button on your browser. Please resubmit."
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:139
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:103
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:153
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:145
msgid "Save"
msgstr "Save"
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:141
msgid "Configuration saved."
msgstr "Configuration saved."
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:142
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:122
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:151
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:143
msgid "Reload"
msgstr "Reload"
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:144
msgid "Configuration reloaded."
msgstr "Configuration reloaded."
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:101
#, java-format
msgid "{0} address book in {1} database"
msgstr ""
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:248
msgid "Manually added via SusiDNS"
msgstr ""
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:262
#, java-format
msgid "Failed to add Destination for {0} to naming service {1}"
msgstr ""
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:286
#, java-format
msgid "Failed to delete Destination for {0} from naming service {1}"
msgstr ""
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:115
msgid ""
"Subscriptions saved, updating addressbook from subscription sources now."
msgstr ""
"Subscriptions saved, updating addressbook from subscription sources now."
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:120
msgid "Subscriptions saved."
msgstr "Subscriptions saved."
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:124
msgid "Subscriptions reloaded."
msgstr "Subscriptions reloaded."
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:125
msgid "address book"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:131
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:147
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:125
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:141
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:116
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:132
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:130
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:117
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:133
msgid "Overview"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:133
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:127
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:118
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:116
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:119
msgid "Address books"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:135
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:129
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:120
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:118
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:121
msgid "private"
msgstr "private"
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:137
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:131
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:122
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:120
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:123
msgid "master"
msgstr "master"
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:139
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:133
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:124
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:122
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:125
msgid "router"
msgstr "router"
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:141
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:135
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:126
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:124
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:127
msgid "published"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:143
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:137
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:128
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:126
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:129
msgid "Subscriptions"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:145
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:139
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:130
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:128
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:131
msgid "Configuration"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:149
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:134
msgid "Address book"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:154
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:139
msgid "Storage"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:172
msgid "Filter"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:175
msgid "other"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:177
msgid "all"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:191
msgid "Current filter"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:196
msgid "clear filter"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:209
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:213
msgid "Search"
msgstr "Search"
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:246
msgid "Name"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:248
msgid "Links"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:250
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:404
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:266
msgid "Destination"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:286
msgid "Mark for deletion"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:307
msgid "Base 32 address"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:311
msgid "More information on this entry"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:314
msgid "details"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:349
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:408
msgid "Cancel"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:383
msgid "This address book is empty."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:398
msgid "Add new destination"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:400
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:165
msgid "Host Name"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:119
msgid "configuration"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:155
msgid "Hints"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:157
msgid ""
"File and directory paths here are relative to the addressbook's working "
"directory, which is normally ~/.i2p/addressbook/ (Linux) or %APPDATA%\\I2P"
"\\addressbook\\ (Windows)."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:159
msgid ""
"If you want to manually add lines to an addressbook, add them to the private "
"or master addressbooks."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:160
msgid ""
"The router addressbook and the published addressbook are updated by the "
"addressbook application."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:162
msgid ""
"When you publish your addressbook, ALL destinations from the master and "
"router addressbooks appear there."
msgstr ""
"When you publish your addressbook, ALL destinations from the master and "
"router addressbooks appear there."
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:163
msgid ""
"Use the private addressbook for private destinations, these are not "
"published."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:165
msgid "Options"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:167
msgid "File containing the list of subscriptions URLs (no need to change)"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:169
msgid "Update interval in hours"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:171
msgid ""
"Your public hosts.txt file (choose a path within your webserver document "
"root)"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:173
msgid "Your hosts.txt (don't change)"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:175
msgid "Your personal addressbook, these hosts will be published"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:177
msgid "Your private addressbook, it is never published"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:179
msgid "Port for your eepProxy (no need to change)"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:181
msgid "Hostname for your eepProxy (no need to change)"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:183
msgid "Whether to update the published addressbook"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:185
msgid ""
"File containing the etags header from the fetched subscription URLs (no need "
"to change)"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:187
msgid ""
"File containing the modification timestamp for each fetched subscription URL "
"(no need to change)"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:189
msgid "File to log activity to (change to /dev/null if you like)"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:191
msgid "Name of the theme to use (defaults to 'light')"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:110
msgid "addressbook"
msgstr "addressbook"
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:181
msgid "Encoded Name"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:197
msgid "Base 32 Address"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:207
msgid "Base 64 Hash"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:213
msgid "Address Helper"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:220
msgid "link"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:224
msgid "Public Key"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:226
msgid "ElGamal 2048 bit"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:230
msgid "Signing Key"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:232
msgid "DSA 1024 bit"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:236
msgid "Certificate"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:242
msgid "Added Date"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:248
msgid "Source"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:254
msgid "Last Modified"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:260
msgid "Notes"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:110
msgid "Introduction"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:132
msgid "What is the addressbook?"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:134
msgid "The addressbook application is part of your I2P installation."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:135
msgid ""
"It regularly updates your hosts.txt file from distributed sources or "
"\"subscriptions\"."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:137
msgid ""
"In the default configuration, the address book is only subscribed to www."
"i2p2.i2p."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:138
msgid ""
"Subscribing to additional sites is easy, just add them to your <a href="
"\"subscriptions\">subscriptions</a> file."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:140
msgid ""
"For more information on naming in I2P, see <a href=\"http://www.i2p2.i2p/"
"naming.html\">the overview on www.i2p2.i2p</a>."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:142
msgid "How does the addressbook application work?"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:144
msgid ""
"The addressbook application regularly polls your subscriptions and merges "
"their content into your \"router\" address book."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:145
msgid ""
"Then it merges your \"master\" address book into the router address book as "
"well."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:146
msgid ""
"If configured, the router address book is now written to the \"published\" "
"address book, which will be publicly available if you are running an eepsite."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:148
msgid ""
"The router also uses a private address book (not shown in the picture), "
"which is not merged or published."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:149
msgid ""
"Hosts in the private address book can be accessed by you but their addresses "
"are never distributed to others."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:150
msgid ""
"The private address book can also be used for aliases of hosts in your other "
"address books."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:111
msgid "subscriptions"
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:147
msgid "The subscription file contains a list of i2p URLs."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:148
msgid ""
"The addressbook application regularly checks this list for new eepsites."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:149
msgid "Those URLs refer to published hosts.txt files."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:150
msgid ""
"The default subscription is the hosts.txt from www.i2p2.i2p, which is "
"updated infrequently."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:151
msgid ""
"So it is a good idea to add additional subscriptions to sites that have the "
"latest addresses."
msgstr ""
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:153
msgid "See the FAQ for a list of subscription URLs."
msgstr ""

View File

@@ -119,10 +119,10 @@ public class AddressbookBean extends BaseBean
} }
public String getBook() public String getBook()
{ {
if( book == null || ( book.compareToIgnoreCase( "master" ) != 0 && if( book == null || ( !book.equalsIgnoreCase( "master" ) &&
book.compareToIgnoreCase( "router" ) != 0 && !book.equalsIgnoreCase( "router" ) &&
book.compareToIgnoreCase( "private" ) != 0 && !book.equalsIgnoreCase( "private" ) &&
book.compareToIgnoreCase( "published" ) != 0 )) !book.equalsIgnoreCase( "published" )))
book = "router"; book = "router";
return book; return book;
@@ -252,7 +252,8 @@ public class AddressbookBean extends BaseBean
String message = ""; String message = "";
if( action != null ) { if( action != null ) {
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) { if (_context.getBooleanProperty(PROP_PW_ENABLE) ||
(serial != null && serial.equals(lastSerial))) {
boolean changed = false; boolean changed = false;
if (action.equals(_("Add")) || action.equals(_("Replace"))) { if (action.equals(_("Add")) || action.equals(_("Replace"))) {
if( addressbook != null && hostname != null && destination != null ) { if( addressbook != null && hostname != null && destination != null ) {
@@ -336,7 +337,9 @@ public class AddressbookBean extends BaseBean
} }
} }
else { else {
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit."); message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.")
+ ' ' +
_("If the problem persists, verify that you have cookies enabled in your browser.");
} }
} }
@@ -364,22 +367,22 @@ public class AddressbookBean extends BaseBean
public boolean isMaster() public boolean isMaster()
{ {
return getBook().compareToIgnoreCase( "master" ) == 0; return getBook().equalsIgnoreCase("master");
} }
public boolean isRouter() public boolean isRouter()
{ {
return getBook().compareToIgnoreCase( "router" ) == 0; return getBook().equalsIgnoreCase("router");
} }
public boolean isPublished() public boolean isPublished()
{ {
return getBook().compareToIgnoreCase( "published" ) == 0; return getBook().equalsIgnoreCase("published");
} }
public boolean isPrivate() public boolean isPrivate()
{ {
return getBook().compareToIgnoreCase( "private" ) == 0; return getBook().equalsIgnoreCase("private");
} }
public void setFilter(String filter) { public void setFilter(String filter) {
if( filter != null && ( filter.length() == 0 || filter.compareToIgnoreCase( "none" ) == 0 ) ) { if( filter != null && ( filter.length() == 0 || filter.equalsIgnoreCase("none"))) {
filter = null; filter = null;
search = null; search = null;
} }

View File

@@ -14,7 +14,7 @@ import net.i2p.I2PAppContext;
*/ */
public class BaseBean public class BaseBean
{ {
private final I2PAppContext _context; protected final I2PAppContext _context;
protected final Properties properties; protected final Properties properties;
private long configLastLoaded = 0; private long configLastLoaded = 0;
@@ -26,6 +26,7 @@ public class BaseBean
public static final String PROP_THEME_NAME = "theme"; public static final String PROP_THEME_NAME = "theme";
public static final String DEFAULT_THEME = "light"; public static final String DEFAULT_THEME = "light";
public static final String BASE_THEME_PATH = "/themes/susidns/"; public static final String BASE_THEME_PATH = "/themes/susidns/";
public static final String PROP_PW_ENABLE = "routerconsole.auth.enable";
public BaseBean() public BaseBean()
{ {

View File

@@ -135,7 +135,8 @@ public class ConfigBean implements Serializable {
public String getMessages() { public String getMessages() {
String message = ""; String message = "";
if( action != null ) { if( action != null ) {
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) { if (I2PAppContext.getGlobalContext().getBooleanProperty(BaseBean.PROP_PW_ENABLE) ||
(serial != null && serial.equals(lastSerial))) {
if(action.equals(_("Save"))) { if(action.equals(_("Save"))) {
save(); save();
message = _("Configuration saved."); message = _("Configuration saved.");
@@ -145,7 +146,9 @@ public class ConfigBean implements Serializable {
} }
} }
else { else {
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit."); message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.")
+ ' ' +
_("If the problem persists, verify that you have cookies enabled in your browser.");
} }
} }
if( message.length() > 0 ) if( message.length() > 0 )

View File

@@ -28,7 +28,6 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.client.naming.NamingService; import net.i2p.client.naming.NamingService;
import net.i2p.data.DataFormatException; import net.i2p.data.DataFormatException;
import net.i2p.data.Destination; import net.i2p.data.Destination;
@@ -128,7 +127,7 @@ public class NamingServiceBean extends AddressbookBean
/** @return the NamingService for the current file name, or the root NamingService */ /** @return the NamingService for the current file name, or the root NamingService */
private NamingService getNamingService() private NamingService getNamingService()
{ {
NamingService root = I2PAppContext.getGlobalContext().namingService(); NamingService root = _context.namingService();
NamingService rv = searchNamingService(root, getFileName()); NamingService rv = searchNamingService(root, getFileName());
return rv != null ? rv : root; return rv != null ? rv : root;
} }
@@ -173,7 +172,7 @@ public class NamingServiceBean extends AddressbookBean
for (Map.Entry<String, Destination> entry : results.entrySet()) { for (Map.Entry<String, Destination> entry : results.entrySet()) {
String name = entry.getKey(); String name = entry.getKey();
if( filter != null && filter.length() > 0 ) { if( filter != null && filter.length() > 0 ) {
if( filter.compareTo( "0-9" ) == 0 ) { if (filter.equals("0-9")) {
char first = name.charAt(0); char first = name.charAt(0);
if( first < '0' || first > '9' ) if( first < '0' || first > '9' )
continue; continue;
@@ -222,7 +221,8 @@ public class NamingServiceBean extends AddressbookBean
Properties nsOptions = new Properties(); Properties nsOptions = new Properties();
// only blockfile needs this // only blockfile needs this
nsOptions.setProperty("list", getFileName()); nsOptions.setProperty("list", getFileName());
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) { if (_context.getBooleanProperty(PROP_PW_ENABLE) ||
(serial != null && serial.equals(lastSerial))) {
boolean changed = false; boolean changed = false;
if (action.equals(_("Add")) || action.equals(_("Replace"))) { if (action.equals(_("Add")) || action.equals(_("Replace"))) {
if(hostname != null && destination != null) { if(hostname != null && destination != null) {
@@ -243,7 +243,7 @@ public class NamingServiceBean extends AddressbookBean
Destination dest = new Destination(destination); Destination dest = new Destination(destination);
if (oldDest != null) { if (oldDest != null) {
nsOptions.putAll(outProperties); nsOptions.putAll(outProperties);
nsOptions.setProperty("m", Long.toString(I2PAppContext.getGlobalContext().clock().now())); nsOptions.setProperty("m", Long.toString(_context.clock().now()));
} }
nsOptions.setProperty("s", _("Manually added via SusiDNS")); nsOptions.setProperty("s", _("Manually added via SusiDNS"));
boolean success = getNamingService().put(host, dest, nsOptions); boolean success = getNamingService().put(host, dest, nsOptions);
@@ -308,7 +308,9 @@ public class NamingServiceBean extends AddressbookBean
} }
} }
else { else {
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit."); message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.")
+ ' ' +
_("If the problem persists, verify that you have cookies enabled in your browser.");
} }
} }

View File

@@ -33,7 +33,6 @@ import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.Properties; import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.util.SecureFileOutputStream; import net.i2p.util.SecureFileOutputStream;
public class SubscriptionsBean extends BaseBean public class SubscriptionsBean extends BaseBean
@@ -99,7 +98,8 @@ public class SubscriptionsBean extends BaseBean
public String getMessages() { public String getMessages() {
String message = ""; String message = "";
if( action != null ) { if( action != null ) {
if( lastSerial != null && serial != null && serial.compareTo( lastSerial ) == 0 ) { if (_context.getBooleanProperty(PROP_PW_ENABLE) ||
(serial != null && serial.equals(lastSerial))) {
if (action.equals(_("Save"))) { if (action.equals(_("Save"))) {
save(); save();
/******* /*******
@@ -115,7 +115,7 @@ public class SubscriptionsBean extends BaseBean
message = _("Subscriptions saved, updating addressbook from subscription sources now."); message = _("Subscriptions saved, updating addressbook from subscription sources now.");
// + "<img height=\"1\" width=\"1\" alt=\"\" " + // + "<img height=\"1\" width=\"1\" alt=\"\" " +
// "src=\"/addressbook/?wakeup=1&nonce=" + nonce + "\">"; // "src=\"/addressbook/?wakeup=1&nonce=" + nonce + "\">";
I2PAppContext.getGlobalContext().namingService().requestUpdate(null); _context.namingService().requestUpdate(null);
} else { } else {
message = _("Subscriptions saved."); message = _("Subscriptions saved.");
} }
@@ -125,7 +125,9 @@ public class SubscriptionsBean extends BaseBean
} }
} }
else { else {
message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit."); message = _("Invalid form submission, probably because you used the \"back\" or \"reload\" button on your browser. Please resubmit.")
+ ' ' +
_("If the problem persists, verify that you have cookies enabled in your browser.");
} }
} }
if( message.length() > 0 ) if( message.length() > 0 )

View File

@@ -42,7 +42,7 @@ public class POP3MailBox {
private String host = null, user = null, pass = null; private String host = null, user = null, pass = null;
private String lastLine = "-ERR", lastError = null; private String lastLine = "-ERR No response from server", lastError = null;
private int port = 0, mails = 0, read = 0; private int port = 0, mails = 0, read = 0;

View File

@@ -1060,7 +1060,7 @@
--> -->
</target> </target>
<target name="prepupdateSmall" depends="buildSmall, prepupdateRouter, prepthemeupdates"> <target name="prepupdateSmall" depends="buildSmall, prepupdateRouter, prepjupdatefixes, prepthemeupdates">
<copy file="build/i2ptunnel.jar" todir="pkg-temp/lib/" /> <copy file="build/i2ptunnel.jar" todir="pkg-temp/lib/" />
<copy file="build/mstreaming.jar" todir="pkg-temp/lib/" /> <copy file="build/mstreaming.jar" todir="pkg-temp/lib/" />
<copy file="build/streaming.jar" todir="pkg-temp/lib/" /> <copy file="build/streaming.jar" todir="pkg-temp/lib/" />
@@ -1116,7 +1116,7 @@
</target> </target>
<!-- Jetty 6 I2P logging addons, not really fixes --> <!-- Jetty 6 I2P logging addons, not really fixes -->
<target name="prepjupdatefixes" depends="prepupdate, buildWEB"> <target name="prepjupdatefixes" depends="buildWEB">
<copy file="build/jetty-i2p.jar" todir="pkg-temp/lib/" /> <copy file="build/jetty-i2p.jar" todir="pkg-temp/lib/" />
</target> </target>

View File

@@ -16,7 +16,7 @@ package net.i2p;
public class CoreVersion { public class CoreVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = "0.9.2"; public final static String VERSION = "0.9.3";
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("I2P Core version: " + VERSION); System.out.println("I2P Core version: " + VERSION);

View File

@@ -0,0 +1,58 @@
package net.i2p.app;
import net.i2p.I2PAppContext;
/**
* If a class started via clients.config implements this interface,
* it will be used to manage the client, instead of starting with main()
*
* Clients implementing this interface MUST provide the following constructor:
*
* public MyClientApp(I2PAppContext context, ClientAppManager listener, String[] args) {...}
*
* All parameters are non-null.
* This constructor is for instantiation only.
* Do not take a long time. Do not block. Never start threads or processes in it.
* The ClientAppState of the returned object must be INITIALIZED,
* or else throw something.
* The startup() method will be called next.
*
* Never ever hold a static reference to the context or anything derived from it.
*
* @since 0.9.4
*/
public interface ClientApp {
/**
* Do not take a long time. Do not block. Start threads here if necessary.
* Client must call ClientAppManager.notify() at least once within this
* method to change the state from INITIALIZED to something else.
* Will not be called multiple times on the same object.
*/
public void startup() throws Throwable;
/**
* Do not take a long time. Do not block. Use a thread if necessary.
* If previously running, client must call ClientAppManager.notify() at least once within this
* method to change the state to STOPPING or STOPPED.
* May be called multiple times on the same object, in any state.
*/
public void shutdown(String[] args) throws Throwable;
/**
* The current state of the ClientApp.
*/
public ClientAppState getState();
/**
* The generic name of the ClientApp, used for registration,
* e.g. "console". Do not translate.
*/
public String getName();
/**
* The dislplay name of the ClientApp, used in user interfaces.
* The app must translate.
*/
public String getDisplayName();
}

View File

@@ -0,0 +1,51 @@
package net.i2p.app;
/**
* Notify the router of events, and provide methods for
* client apps to find each other.
*
* @since 0.9.4
*/
public interface ClientAppManager {
/**
* Must be called on all state transitions except
* from UNINITIALIZED to INITIALIZED.
*
* @param app non-null
* @param state non-null
* @param message may be null
* @param e may be null
*/
public void notify(ClientApp app, ClientAppState state, String message, Exception e);
/**
* Register with the manager under the given name,
* so that other clients may find it.
* Only required for apps used by other apps.
*
* @param app non-null
* @param name non-null
* @return true if successful, false if duplicate name
*/
public boolean register(ClientApp app);
/**
* Unregister with the manager. Name must be the same as that from register().
* Only required for apps used by other apps.
*
* @param app non-null
* @param name non-null
*/
public void unregister(ClientApp app);
/**
* Get a registered app.
* Only used for apps finding other apps.
*
* @param app non-null
* @param name non-null
* @return client app or null
*/
public ClientApp getRegisteredApp(String name);
}

View File

@@ -0,0 +1,25 @@
package net.i2p.app;
/**
* Status of a client application.
* ClientAppManager.notify() must be called on all state transitions except
* from UNINITIALIZED to INITIALIZED.
*
* @since 0.9.4
*/
public enum ClientAppState {
/** initial value */
UNINITIALIZED,
/** after constructor is complete */
INITIALIZED,
STARTING,
START_FAILED,
RUNNING,
STOPPING,
/** stopped normally */
STOPPED,
/** stopped abnormally */
CRASHED,
/** forked as a new process, status unknown from now on */
FORKED
}

View File

@@ -0,0 +1,18 @@
<html>
<body>
<p>
Interfaces for classes to be started and stopped via clients.config.
Classes implementing the ClientApp interface will be controlled with
the that interface instead of being started with main().
</p>
<p>
The benefits for clients using this interface:
<ul>
<li>Get the current context via the constructor
<li>Complete life cycle management by the router
<li>Avoid the need for static references
<li>Ability to find other clients without using static references
</ul>
</p>
</body>
</html>

View File

@@ -367,6 +367,15 @@ public class DataHelper {
* (unless the options param is an OrderedProperties) * (unless the options param is an OrderedProperties)
*/ */
public static String toString(Properties options) { public static String toString(Properties options) {
return toString((Map) options);
}
/**
* Pretty print the mapping, unsorted
* (unless the options param is an OrderedProperties)
* @since 0.9.4
*/
public static String toString(Map<?, ?> options) {
StringBuilder buf = new StringBuilder(); StringBuilder buf = new StringBuilder();
if (options != null) { if (options != null) {
for (Map.Entry entry : options.entrySet()) { for (Map.Entry entry : options.entrySet()) {
@@ -502,7 +511,7 @@ public class DataHelper {
} }
/** /**
* Hex with leading zeros. * Lower-case hex with leading zeros.
* Use toHexString(byte[]) to not get leading zeros * Use toHexString(byte[]) to not get leading zeros
* @param buf may be null (returns "") * @param buf may be null (returns "")
* @return String of length 2*buf.length * @return String of length 2*buf.length
@@ -516,7 +525,7 @@ public class DataHelper {
private static final byte[] EMPTY_BUFFER = "".getBytes(); private static final byte[] EMPTY_BUFFER = "".getBytes();
/** /**
* Hex with leading zeros. * Lower-case hex with leading zeros.
* Use toHexString(byte[]) to not get leading zeros * Use toHexString(byte[]) to not get leading zeros
* @param buf may be null * @param buf may be null
* @param len number of bytes. If greater than buf.length, additional zeros will be prepended * @param len number of bytes. If greater than buf.length, additional zeros will be prepended
@@ -546,7 +555,7 @@ public class DataHelper {
} }
/** /**
* Hex without leading zeros. * Lower-case hex without leading zeros.
* Use toString(byte[] to get leading zeros * Use toString(byte[] to get leading zeros
* @param data may be null (returns "00") * @param data may be null (returns "00")
*/ */

View File

@@ -25,6 +25,15 @@ import net.i2p.I2PAppContext;
*/ */
public abstract class Addresses { public abstract class Addresses {
/**
* Do we have any non-loop, non-wildcard IPv4 address at all?
* @since 0.9.4
*/
public static boolean isConnected() {
// not as good as using a Java DBus implementation to talk to NetworkManager...
return !getAddresses(true, false, false).isEmpty();
}
/** @return the first non-local address it finds, or null */ /** @return the first non-local address it finds, or null */
public static String getAnyAddress() { public static String getAnyAddress() {
SortedSet<String> a = getAddresses(); SortedSet<String> a = getAddresses();
@@ -51,13 +60,28 @@ public abstract class Addresses {
} }
/** /**
* @return a sorted array of all addresses * @return a sorted set of all addresses including wildcard
* @param includeLocal whether to include local * @param includeLocal whether to include local
* @param includeIPv6 whether to include IPV6 * @param includeIPv6 whether to include IPV6
* @return an array of all addresses * @return an array of all addresses
* @since 0.8.3 * @since 0.8.3
*/ */
public static SortedSet<String> getAddresses(boolean includeLocal, boolean includeIPv6) { public static SortedSet<String> getAddresses(boolean includeLocal, boolean includeIPv6) {
return getAddresses(includeLocal, includeLocal, includeIPv6);
}
/**
* @return a sorted set of all addresses
* @param includeSiteLocal whether to include private like 192.168.x.x
* @param includeLoopAndWildcard whether to include 127.x.x.x and 0.0.0.0
* @param includeIPv6 whether to include IPV6
* @param includeWildCard whether to include 0.0.0.0 and/or 0:0:0:0:0:0 (includeLocal must be true)
* @return an array of all addresses
* @since 0.9.4
*/
public static SortedSet<String> getAddresses(boolean includeSiteLocal,
boolean includeLoopbackAndWildcard,
boolean includeIPv6) {
boolean haveIPv4 = false; boolean haveIPv4 = false;
boolean haveIPv6 = false; boolean haveIPv6 = false;
SortedSet<String> rv = new TreeSet(); SortedSet<String> rv = new TreeSet();
@@ -70,7 +94,8 @@ public abstract class Addresses {
haveIPv4 = true; haveIPv4 = true;
else else
haveIPv6 = true; haveIPv6 = true;
if (shouldInclude(allMyIps[i], includeLocal, includeIPv6)) if (shouldInclude(allMyIps[i], includeSiteLocal,
includeLoopbackAndWildcard, includeIPv6))
rv.add(allMyIps[i].getHostAddress()); rv.add(allMyIps[i].getHostAddress());
} }
} }
@@ -87,34 +112,39 @@ public abstract class Addresses {
haveIPv4 = true; haveIPv4 = true;
else else
haveIPv6 = true; haveIPv6 = true;
if (shouldInclude(addr, includeLocal, includeIPv6)) if (shouldInclude(addr, includeSiteLocal,
includeLoopbackAndWildcard, includeIPv6))
rv.add(addr.getHostAddress()); rv.add(addr.getHostAddress());
} }
} }
} }
} catch (SocketException e) {} } catch (SocketException e) {}
if (includeLocal && haveIPv4) if (includeLoopbackAndWildcard) {
if (haveIPv4)
rv.add("0.0.0.0"); rv.add("0.0.0.0");
if (includeLocal && includeIPv6 && haveIPv6) if (includeIPv6 && haveIPv6)
rv.add("0:0:0:0:0:0:0:0"); // we could do "::" but all the other ones are probably in long form rv.add("0:0:0:0:0:0:0:0"); // we could do "::" but all the other ones are probably in long form
}
return rv; return rv;
} }
private static boolean shouldInclude(InetAddress ia, boolean includeLocal, boolean includeIPv6) { private static boolean shouldInclude(InetAddress ia, boolean includeSiteLocal,
boolean includeLoopbackAndWildcard, boolean includeIPv6) {
return return
(!ia.isLinkLocalAddress()) && (!ia.isLinkLocalAddress()) && // 169.254.x.x
(!ia.isMulticastAddress()) && (!ia.isMulticastAddress()) &&
(includeLocal || (includeLoopbackAndWildcard ||
((!ia.isAnyLocalAddress()) && ((!ia.isAnyLocalAddress()) &&
(!ia.isLoopbackAddress()) && (!ia.isLoopbackAddress()))) &&
(!ia.isSiteLocalAddress()))) && (includeSiteLocal ||
!ia.isSiteLocalAddress()) &&
// Hamachi 5/8 allocated to RIPE (30 November 2010) // Hamachi 5/8 allocated to RIPE (30 November 2010)
// Removed from TransportImpl.isPubliclyRoutable() // Removed from TransportImpl.isPubliclyRoutable()
// Check moved to here, for now, but will eventually need to // Check moved to here, for now, but will eventually need to
// remove it from here also. // remove it from here also.
(includeLocal || //(includeLocal ||
(!ia.getHostAddress().startsWith("5."))) && //(!ia.getHostAddress().startsWith("5."))) &&
(includeIPv6 || (includeIPv6 ||
(ia instanceof Inet4Address)); (ia instanceof Inet4Address));
} }
@@ -247,13 +277,18 @@ public abstract class Addresses {
* Print out the local addresses * Print out the local addresses
*/ */
public static void main(String[] args) { public static void main(String[] args) {
System.err.println("External Addresses:"); System.err.println("External IPv4 Addresses:");
Set<String> a = getAddresses(false, false); Set<String> a = getAddresses(false, false, false);
for (String s : a) for (String s : a)
System.err.println(s); System.err.println(s);
System.err.println("All addresses:"); System.err.println("\nExternal and Local IPv4 Addresses:");
a = getAddresses(true, true); a = getAddresses(true, false, false);
for (String s : a) for (String s : a)
System.err.println(s); System.err.println(s);
System.err.println("\nAll addresses:");
a = getAddresses(true, true, true);
for (String s : a)
System.err.println(s);
System.err.println("\nIs connected? " + isConnected());
} }
} }

View File

@@ -353,7 +353,7 @@ public class NativeBigInteger extends BigInteger {
/** /**
* <p>Compare the BigInteger.modPow vs the NativeBigInteger.modPow of some * <p>Compare the BigInteger.modPow vs the NativeBigInteger.modPow of some
* really big (2Kbit) numbers 100 different times and benchmark the * really big (2Kbit) numbers 100 different times and benchmark the
* performance (or shit a brick if they don't match). </p> * performance.</p>
* *
*/ */
public static void main(String args[]) { public static void main(String args[]) {

View File

@@ -0,0 +1,200 @@
package net.i2p.util;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.data.SessionKey;
/**
* Manage both plaintext and salted/hashed password storage in
* router.config.
*
* There's no state here, so instantiate at will.
*
* @since 0.9.4
*/
public class PasswordManager {
private final I2PAppContext _context;
protected static final int SALT_LENGTH = 16;
/** 48 */
protected static final int SHASH_LENGTH = SALT_LENGTH + SessionKey.KEYSIZE_BYTES;
/** stored as plain text */
protected static final String PROP_PW = ".password";
/** stored obfuscated as b64 of the UTF-8 bytes */
protected static final String PROP_B64 = ".b64";
/** stored as the hex of the MD5 hash of the ISO-8859-1 bytes. Compatible with Jetty. */
protected static final String PROP_MD5 = ".md5";
/** stored as a Unix crypt string */
protected static final String PROP_CRYPT = ".crypt";
/** stored as the b64 of the 16 byte salt + the 32 byte hash of the UTF-8 bytes */
protected static final String PROP_SHASH = ".shash";
public PasswordManager(I2PAppContext ctx) {
_context = ctx;
}
/**
* Checks both plaintext and hash
*
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @param pw plain text, already trimmed
* @return if pw verified
*/
public boolean check(String realm, String user, String pw) {
return checkPlain(realm, user, pw) ||
checkB64(realm, user, pw) ||
checkHash(realm, user, pw);
}
/**
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @param pw plain text, already trimmed
* @return if pw verified
*/
public boolean checkPlain(String realm, String user, String pw) {
String pfx = realm;
if (user != null && user.length() > 0)
pfx += '.' + user;
return pw.equals(_context.getProperty(pfx + PROP_PW));
}
/**
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @param pw plain text, already trimmed
* @return if pw verified
*/
public boolean checkB64(String realm, String user, String pw) {
String pfx = realm;
if (user != null && user.length() > 0)
pfx += '.' + user;
String b64 = _context.getProperty(pfx + PROP_B64);
if (b64 == null)
return false;
return b64.equals(Base64.encode(DataHelper.getUTF8(pw)));
}
/**
* With random salt
*
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @param pw plain text, already trimmed
* @return if pw verified
*/
public boolean checkHash(String realm, String user, String pw) {
String pfx = realm;
if (user != null && user.length() > 0)
pfx += '.' + user;
String shash = _context.getProperty(pfx + PROP_SHASH);
if (shash == null)
return false;
byte[] shashBytes = Base64.decode(shash);
if (shashBytes == null || shashBytes.length != SHASH_LENGTH)
return false;
byte[] salt = new byte[SALT_LENGTH];
byte[] hash = new byte[SessionKey.KEYSIZE_BYTES];
System.arraycopy(shashBytes, 0, salt, 0, SALT_LENGTH);
System.arraycopy(shashBytes, SALT_LENGTH, hash, 0, SessionKey.KEYSIZE_BYTES);
byte[] pwHash = _context.keyGenerator().generateSessionKey(salt, DataHelper.getUTF8(pw)).getData();
return DataHelper.eq(hash, pwHash);
}
/**
* Either plain or b64
*
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @return the pw or null
*/
public String get(String realm, String user) {
String rv = getPlain(realm, user);
if (rv != null)
return rv;
return getB64(realm, user);
}
/**
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @return the pw or null
*/
public String getPlain(String realm, String user) {
String pfx = realm;
if (user != null && user.length() > 0)
pfx += '.' + user;
return _context.getProperty(pfx + PROP_PW);
}
/**
* @param realm e.g. i2cp, routerconsole, etc.
* @param user null or "" for no user, already trimmed
* @return the decoded pw or null
*/
public String getB64(String realm, String user) {
String pfx = realm;
if (user != null && user.length() > 0)
pfx += '.' + user;
String b64 = _context.getProperty(pfx + PROP_B64);
if (b64 == null)
return null;
return Base64.decodeToString(b64);
}
/**
* Straight MD5, no salt
* Will return the MD5 sum of "user:subrealm:pw", compatible with Jetty
* and RFC 2617.
*
* @param subrealm to be used in creating the checksum
* @param user non-null, non-empty, already trimmed
* @param pw non-null, plain text, already trimmed
* @return lower-case hex with leading zeros, 32 chars, or null on error
*/
public static String md5Hex(String subrealm, String user, String pw) {
String fullpw = user + ':' + subrealm + ':' + pw;
return md5Hex(fullpw);
}
/**
* Straight MD5, no salt
* Will return the MD5 sum of the data, compatible with Jetty
* and RFC 2617.
*
* @param fullpw non-null, plain text, already trimmed
* @return lower-case hex with leading zeros, 32 chars, or null on error
*/
public static String md5Hex(String fullpw) {
try {
byte[] data = fullpw.getBytes("ISO-8859-1");
byte[] sum = md5Sum(data);
if (sum != null)
// adds leading zeros if necessary
return DataHelper.toString(sum);
} catch (UnsupportedEncodingException uee) {}
return null;
}
/**
* Standard MD5 checksum
*
* @param data non-null
* @return 16 bytes, or null on error
*/
public static byte[] md5Sum(byte[] data) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(data);
return md.digest();
} catch (NoSuchAlgorithmException nsae) {}
return null;
}
}

66
debian/changelog vendored
View File

@@ -1,4 +1,50 @@
i2p (0.9.1-1) unstable; urgency=low i2p (0.9.3-1) stable; urgency=low
* New Upstream release
* Upstream changelog (full details in history.txt):
- Active Queue Management
- I2PSnark DHT: Several bug fixes, enable by default.
- Priority queues
- Several SSU fixes including memory leak, and better handling of routers
behind firewalls that change UDP ports; additional defenses for malicious
packets.
- Fix piece selection (rarest-first) bugs in i2psnark
- Fix bug causing multiple browsers to open at startup
- Improvements in caching
- Several synchronization fixes and lock contention reduction
- Major reduction in SSU buffers memory use
- Fix streaming connection timeout back to 1 minute, was inadvertently
changed to 5 minutes; set i2ptunnel server read timeout to 5 minutes, was
unlimited
- Improved defenses in i2ptunnel for "darkloris"
- More validation at torrent creation in i2psnark
- Several parameter changes in SSU to improve throughput
- New event log for major events including restarts; show multiple restart
lines on graphs
- Remove duplicate messages from logs
- Don't respond to blocked streaming connections with a reset, just drop
- Remove all uses of inefficient SimpleTimer
- More checks for valid IPs and ports entered in console
- Fix bug that wasted a lot of entropy
- Translation updates: Italian, Portuguese, Spanish, Swedish
- Add non-NIO configuration in jetty.xml, recommended for Java 5
- Update GeoIP data
-- Kill Your TV <killyourtv@i2pmail.org> Sat, 27 Oct 2012 16:47:37 +0000
i2p (0.9.2-2) stable; urgency=high
* Fix stupid bug in i2prouter
-- Kill Your TV <killyourtv@i2pmail.org> Sat, 22 Sep 2012 13:57:39 +0000
i2p (0.9.2-1) stable; urgency=low
* New upstream release (see history.txt for details)
-- Kill Your TV <killyourtv@i2pmail.org> Fri, 21 Sep 2012 18:13:32 +0000
i2p (0.9.1-1) stable; urgency=low
* New upstream version 0.9.1 * New upstream version 0.9.1
* Don't depend on Debian's/Ubuntu's version of Jetty. Jetty6 is going away * Don't depend on Debian's/Ubuntu's version of Jetty. Jetty6 is going away
@@ -13,13 +59,13 @@ i2p (0.9.1-1) unstable; urgency=low
-- Kill Your TV <killyourtv@i2pmail.org> Mon, 30 Jul 2012 17:41:04 +0000 -- Kill Your TV <killyourtv@i2pmail.org> Mon, 30 Jul 2012 17:41:04 +0000
i2p (0.9-1) unstable; urgency=low i2p (0.9-1) stable; urgency=low
* New Upstream Version * New Upstream Version
-- Kill Your TV <killyourtv@i2pmail.org> Wed, 02 May 2012 16:33:11 +0000 -- Kill Your TV <killyourtv@i2pmail.org> Wed, 02 May 2012 16:33:11 +0000
i2p (0.8.13-2) unstable; urgency=low i2p (0.8.13-2) stable; urgency=low
* Fix bug in postinst cause by changes to adduser's behaviour. * Fix bug in postinst cause by changes to adduser's behaviour.
@@ -66,38 +112,38 @@ i2p (0.8.12-1) stable; urgency=low
-- Kill Your TV <killyourtv@i2pmail.org> Fri, 06 Jan 2012 02:49:03 +0000 -- Kill Your TV <killyourtv@i2pmail.org> Fri, 06 Jan 2012 02:49:03 +0000
i2p (0.8.11+repack-2) stable; urgency=medium i2p (0.8.11-2) stable; urgency=medium
* Fix STUPID bug running I2P with i2prouter. Thanks soundwave. * Fix STUPID bug running I2P with i2prouter. Thanks soundwave.
-- Kill Your TV <killyourtv@i2pmail.org> Tue, 08 Nov 2011 20:02:05 +0000 -- Kill Your TV <killyourtv@i2pmail.org> Tue, 08 Nov 2011 20:02:05 +0000
i2p (0.8.11+repack-1) stable; urgency=low i2p (0.8.11-1) stable; urgency=low
* New Upstream Version * New Upstream Version
* sv and uk debconf translation updates * sv and uk debconf translation updates
-- Kill Your TV <killyourtv@i2pmail.org> Mon, 07 Nov 2011 19:20:15 +0000 -- Kill Your TV <killyourtv@i2pmail.org> Mon, 07 Nov 2011 19:20:15 +0000
i2p (0.8.10+repack-1) stable; urgency=medium i2p (0.8.10-1) stable; urgency=medium
* New upstream version * New upstream version
-- Kill Your TV <killyourtv@i2pmail.org> Thu, 20 Oct 2011 05:25:04 +0000 -- Kill Your TV <killyourtv@i2pmail.org> Thu, 20 Oct 2011 05:25:04 +0000
i2p (0.8.9+repack-1) stable; urgency=medium i2p (0.8.9-1) stable; urgency=medium
* New upstream version * New upstream version
-- Kill Your TV <killyourtv@i2pmail.org> Tue, 11 Oct 2011 19:55:08 +0000 -- Kill Your TV <killyourtv@i2pmail.org> Tue, 11 Oct 2011 19:55:08 +0000
i2p (0.8.8+repack-3) UNRELEASED; urgency=low i2p (0.8.8-3) UNRELEASED; urgency=low
* Add dump option to initscript * Add dump option to initscript
-- Kill Your TV <killyourtv@i2pmail.org> Tue, 06 Sep 2011 12:42:22 +0000 -- Kill Your TV <killyourtv@i2pmail.org> Tue, 06 Sep 2011 12:42:22 +0000
i2p (0.8.8+repack-2) stable; urgency=medium i2p (0.8.8-2) stable; urgency=medium
* Backport patch from mtn 04ec606 to fix trac #515 * Backport patch from mtn 04ec606 to fix trac #515
* Fix trac ticket #514 ("debconf values are overwritten upon * Fix trac ticket #514 ("debconf values are overwritten upon
@@ -107,7 +153,7 @@ i2p (0.8.8+repack-2) stable; urgency=medium
-- Kill Your TV <killyourtv@i2pmail.org> Fri, 02 Sep 2011 23:32:32 +0000 -- Kill Your TV <killyourtv@i2pmail.org> Fri, 02 Sep 2011 23:32:32 +0000
i2p (0.8.8+repack-1) stable; urgency=low i2p (0.8.8-1) stable; urgency=low
* New Upstream Version * New Upstream Version

View File

@@ -127,7 +127,7 @@ Debian wrapper.config to try to prevent confusion.
else else
eval echo `gettext '$APP_LONG_NAME is already running.'` eval echo `gettext '$APP_LONG_NAME is already running.'`
exit 1 exit 1
@@ -1871,18 +1816,9 @@ @@ -1874,18 +1819,9 @@
status status
;; ;;

View File

@@ -1,3 +1,33 @@
* 2012-10-27 0.9.3 released
2012-10-25 zzz
* BuildHandler: Fix "too slow" rejections due to internal clock skew
2012-10-24 zzz
* I2PSnark:
- Fix several partial piece (temp file) leaks
- Don't lose all DHT peers if we stop quickly
- Explore a kbucket if it's less than 3/4 full
2012-10-24 str4d
* i2ptunnel: Truncate long client destinations (ticket #581)
2012-10-21 zzz
* Watchdog: Don't dump threads too often (ticket #519)
2012-10-20 zzz
* Transport: Back out CoDel for SSU PeerState and NTCP
2012-10-19 zzz
* UDP: Fix peer test NPE (ticket # 748)
2012-10-18 kytv
* Portuguese and Spanish updates from Transifex
* Update geoip.txt based on Maxmind GeoLite Country database from 2012-10-02
2012-10-15 kytv
* Italian and Swedish updates from Transifex
2012-10-14 zzz 2012-10-14 zzz
* Console: Use non-nio connector for Java 5 and JamVM/gij * Console: Use non-nio connector for Java 5 and JamVM/gij
(tickets #715 and #743) (tickets #715 and #743)

View File

@@ -4,9 +4,9 @@
<info> <info>
<appname>i2p</appname> <appname>i2p</appname>
<appversion>0.9.2</appversion> <appversion>0.9.3</appversion>
<authors> <authors>
<author name="I2P" email="http://forum.i2p2.de/"/> <author name="I2P" email="http://www.i2p2.de/"/>
</authors> </authors>
<url>http://www.i2p2.de/</url> <url>http://www.i2p2.de/</url>
<javaversion>1.5</javaversion> <javaversion>1.5</javaversion>

View File

@@ -1,16 +0,0 @@
-----BEGIN CERTIFICATE-----
MIICiTCCAfICCQDI/vgxtkEs3TANBgkqhkiG9w0BAQUFADCBiDELMAkGA1UEBhMC
VU4xEzARBgNVBAgTCldvcmxkLVdpZGUxETAPBgNVBAcTCEludGVybmV0MQwwCgYD
VQQKEwNJMlAxDTALBgNVBAsTBEgySUsxFjAUBgNVBAMTDTc1LjE0NS4xMjUuNTkx
HDAaBgkqhkiG9w0BCQEWDWgyaWtAbWFpbC5pMnAwHhcNMTExMDA3MDAwNDM3WhcN
MjExMDA0MDAwNDM3WjCBiDELMAkGA1UEBhMCVU4xEzARBgNVBAgTCldvcmxkLVdp
ZGUxETAPBgNVBAcTCEludGVybmV0MQwwCgYDVQQKEwNJMlAxDTALBgNVBAsTBEgy
SUsxFjAUBgNVBAMTDTc1LjE0NS4xMjUuNTkxHDAaBgkqhkiG9w0BCQEWDWgyaWtA
bWFpbC5pMnAwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOGkLwuCY6J7Oude
5SdiU/RT7Bhm26M8ufntI1IKsog+BggoqhIoNgzk79q59rsoXA7o+lcXtHGXQoME
mz8HtzGrO90A3ZYCM3Xb6S42DHh6QepZjHBt3hDsPZJl0XXNrB+Wfpljo2y4IfiH
aQo4cBWt0pi29SspA87KFzh1S8gtAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAi7Z5
gmkwHPojE3xEc9tATa2H2MnLXBGcuAaLAv+qAGza5V2Pa6wVTgpUKGfvWR6+Ae2B
ACe9LsIsE2IPtTIwjiwbfmmJ6dkvLHX/bxdp/+X5DjAFa36j+elKVZSerkgy9cLV
rrSQF8UW3HFlwElB0aLgbApOFnArDrbuEnjrjEg=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIIC0DCCAjmgAwIBAgIJANdBFbakbhhOMA0GCSqGSIb3DQEBBQUAMIGAMQswCQYD
VQQGEwJOTzENMAsGA1UECAwET3NsbzENMAsGA1UEBwwET3NsbzEMMAoGA1UECgwD
STJQMQwwCgYDVQQLDANJMlAxFjAUBgNVBAMMDW5ldGRiLmkycDIubm8xHzAdBgkq
hkiG9w0BCQEWEG1lZWhAaTJwbWFpbC5vcmcwHhcNMTIxMDIzMDExMjIyWhcNMTkx
MDIyMDExMjIyWjCBgDELMAkGA1UEBhMCTk8xDTALBgNVBAgMBE9zbG8xDTALBgNV
BAcMBE9zbG8xDDAKBgNVBAoMA0kyUDEMMAoGA1UECwwDSTJQMRYwFAYDVQQDDA1u
ZXRkYi5pMnAyLm5vMR8wHQYJKoZIhvcNAQkBFhBtZWVoQGkycG1haWwub3JnMIGf
MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCDvmjTpff6/XpiNuqoa9ZEKMlyq1o
kas9fHwnZax/0QTM3xusSQQ9DzeVMSx1ueYxhTZ6VLmE1mTr0aIndzugxGK/g85H
Y+cUl3nw7+5gLPMCUrKAXqQokE3mYxSNY3AUeend7nmHvm9iciw4+Sa2+6ROvQQy
kD31CEN6/I04rwIDAQABo1AwTjAdBgNVHQ4EFgQUV83dJhEcLbfJ+uh+MDYNPdah
RoQwHwYDVR0jBBgwFoAUV83dJhEcLbfJ+uh+MDYNPdahRoQwDAYDVR0TBAUwAwEB
/zANBgkqhkiG9w0BAQUFAAOBgQBQQlJym7mUMUM2ryKu20z2PSUzFyq5U4rWHeo3
elbNaTsFBwi+Ot/Lg/A5I4V8gywH1fBTG5bYKDUYvWohz1qIg66G57B1zT1zK9yh
Byz9go44M3y1/kXXSsJlY9llG9DDicr1y6LfldwZJ5zFAd3iiB8D8UadP5YLqb7v
wb1F1g==
-----END CERTIFICATE-----

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,17 @@
<!-- <!--
<i2p.news date="$Date: 2012-09-21 00:00:00 $"> <i2p.news date="$Date: 2012-10-27 00:00:00 $">
<i2p.release version="0.9.2" date="2012/09/21" minVersion="0.6" /> <i2p.release version="0.9.3" date="2012/10/27" minVersion="0.6" />
--> -->
<div lang="en"> <div lang="en">
<h3>2012-09-21: <b>0.9.2 <a href="http://www.i2p2.i2p/release-0.9.2.html">Released</a></b></h3> <h3>2012-10-27: <b>0.9.3 <a href="http://www.i2p2.i2p/release-0.9.3.html">Released</a></b></h3>
<p> <p>
0.9.2 includes extensive low-level changes to improve the performance and efficiency of the router. 0.9.3 includes extensive low-level changes to the queueing of messages in the router.
We have updated our UPnP library, to hopefully make UPnP work for more people. We implement the CoDel Active Queue Management (AQM) algoorithm.
I2PSnark now has DHT support, but it is not yet enabled by default, as we plan to do more We also unify the queueing and priority mechanisms in the transports to aid diagnosis and reduce network latency.
testing during the upcoming 0.9.3 development cycle. Work continues on fixing UDP transport bugs and making UDP more resistant to attacks.
There are more changes to improve the performance of the router and reduce its memory usage.
Also, we enable i2psnark's DHT support, introduced last release, by default.
As usual, there's also lots of bug fixes in this release, so updating is recommended. As usual, there's also lots of bug fixes in this release, so updating is recommended.
</p><p> </p><p>
Say hello to the volunteers on the <a href="irc://127.0.0.1:6668/i2p-help">#i2p-help IRC channel</a>. Say hello to the volunteers on the <a href="irc://127.0.0.1:6668/i2p-help">#i2p-help IRC channel</a>.

View File

@@ -24,12 +24,12 @@ import net.i2p.util.ConcurrentHashSet;
import net.i2p.util.Log; import net.i2p.util.Log;
/** /**
* Routers are shitlisted only if none of our transports can talk to them * Routers are banlisted only if none of our transports can talk to them
* or their signed router info is completely screwy. Individual transports * or their signed router info is completely screwy. Individual transports
* manage their own unreachable lists and do not generally add to the overall * manage their own unreachable lists and do not generally add to the overall
* shitlist. * banlist.
*/ */
public class Shitlist { public class Banlist {
private final Log _log; private final Log _log;
private final RouterContext _context; private final RouterContext _context;
private final Map<Hash, Entry> _entries; private final Map<Hash, Entry> _entries;
@@ -37,11 +37,11 @@ public class Shitlist {
public static class Entry { public static class Entry {
/** when it should expire, per the i2p clock */ /** when it should expire, per the i2p clock */
public long expireOn; public long expireOn;
/** why they were shitlisted */ /** why they were banlisted */
public String cause; public String cause;
/** separate code so cause can contain {0} for translation */ /** separate code so cause can contain {0} for translation */
public String causeCode; public String causeCode;
/** what transports they were shitlisted for (String), or null for all transports */ /** what transports they were banlisted for (String), or null for all transports */
public Set<String> transports; public Set<String> transports;
} }
@@ -49,46 +49,46 @@ public class Shitlist {
* Don't make this too long as the failure may be transient * Don't make this too long as the failure may be transient
* due to connection limits. * due to connection limits.
*/ */
public final static long SHITLIST_DURATION_MS = 7*60*1000; public final static long BANLIST_DURATION_MS = 7*60*1000;
public final static long SHITLIST_DURATION_MAX = 30*60*1000; public final static long BANLIST_DURATION_MAX = 30*60*1000;
public final static long SHITLIST_DURATION_PARTIAL = 10*60*1000; public final static long BANLIST_DURATION_PARTIAL = 10*60*1000;
public final static long SHITLIST_DURATION_FOREVER = 181l*24*60*60*1000; // will get rounded down to 180d on console public final static long BANLIST_DURATION_FOREVER = 181l*24*60*60*1000; // will get rounded down to 180d on console
public final static long SHITLIST_CLEANER_START_DELAY = SHITLIST_DURATION_PARTIAL; public final static long BANLIST_CLEANER_START_DELAY = BANLIST_DURATION_PARTIAL;
public Shitlist(RouterContext context) { public Banlist(RouterContext context) {
_context = context; _context = context;
_log = context.logManager().getLog(Shitlist.class); _log = context.logManager().getLog(Banlist.class);
_entries = new ConcurrentHashMap(16); _entries = new ConcurrentHashMap(16);
_context.jobQueue().addJob(new Cleanup(_context)); _context.jobQueue().addJob(new Cleanup(_context));
} }
private class Cleanup extends JobImpl { private class Cleanup extends JobImpl {
private List<Hash> _toUnshitlist; private List<Hash> _toUnbanlist;
public Cleanup(RouterContext ctx) { public Cleanup(RouterContext ctx) {
super(ctx); super(ctx);
_toUnshitlist = new ArrayList(4); _toUnbanlist = new ArrayList(4);
getTiming().setStartAfter(ctx.clock().now() + SHITLIST_CLEANER_START_DELAY); getTiming().setStartAfter(ctx.clock().now() + BANLIST_CLEANER_START_DELAY);
} }
public String getName() { return "Expire banned peers"; } public String getName() { return "Expire banned peers"; }
public void runJob() { public void runJob() {
_toUnshitlist.clear(); _toUnbanlist.clear();
long now = getContext().clock().now(); long now = getContext().clock().now();
try { try {
for (Iterator iter = _entries.entrySet().iterator(); iter.hasNext(); ) { for (Iterator iter = _entries.entrySet().iterator(); iter.hasNext(); ) {
Map.Entry<Hash, Entry> e = (Map.Entry) iter.next(); Map.Entry<Hash, Entry> e = (Map.Entry) iter.next();
if (e.getValue().expireOn <= now) { if (e.getValue().expireOn <= now) {
iter.remove(); iter.remove();
_toUnshitlist.add(e.getKey()); _toUnbanlist.add(e.getKey());
} }
} }
} catch (IllegalStateException ise) {} // next time... } catch (IllegalStateException ise) {} // next time...
for (Hash peer : _toUnshitlist) { for (Hash peer : _toUnbanlist) {
PeerProfile prof = _context.profileOrganizer().getProfile(peer); PeerProfile prof = _context.profileOrganizer().getProfile(peer);
if (prof != null) if (prof != null)
prof.unshitlist(); prof.unbanlist();
_context.messageHistory().unshitlist(peer); _context.messageHistory().unbanlist(peer);
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Unshitlisting router (expired) " + peer.toBase64()); _log.info("Unbanlisting router (expired) " + peer.toBase64());
} }
requeue(30*1000); requeue(30*1000);
@@ -100,69 +100,69 @@ public class Shitlist {
} }
/** /**
* For ShitlistRenderer in router console. * For BanlistRenderer in router console.
* Note - may contain expired entries. * Note - may contain expired entries.
*/ */
public Map<Hash, Entry> getEntries() { public Map<Hash, Entry> getEntries() {
return Collections.unmodifiableMap(_entries); return Collections.unmodifiableMap(_entries);
} }
public boolean shitlistRouter(Hash peer) { public boolean banlistRouter(Hash peer) {
return shitlistRouter(peer, null); return banlistRouter(peer, null);
} }
public boolean shitlistRouter(Hash peer, String reason) { return shitlistRouter(peer, reason, null); } public boolean banlistRouter(Hash peer, String reason) { return banlistRouter(peer, reason, null); }
/** ick have to put the reasonCode in the front to avoid ambiguity */ /** ick have to put the reasonCode in the front to avoid ambiguity */
public boolean shitlistRouter(String reasonCode, Hash peer, String reason) { public boolean banlistRouter(String reasonCode, Hash peer, String reason) {
return shitlistRouter(peer, reason, reasonCode, null, false); return banlistRouter(peer, reason, reasonCode, null, false);
} }
public boolean shitlistRouter(Hash peer, String reason, String transport) { public boolean banlistRouter(Hash peer, String reason, String transport) {
return shitlistRouter(peer, reason, transport, false); return banlistRouter(peer, reason, transport, false);
} }
public boolean shitlistRouterForever(Hash peer, String reason) { public boolean banlistRouterForever(Hash peer, String reason) {
return shitlistRouter(peer, reason, null, true); return banlistRouter(peer, reason, null, true);
} }
public boolean shitlistRouterForever(Hash peer, String reason, String reasonCode) { public boolean banlistRouterForever(Hash peer, String reason, String reasonCode) {
return shitlistRouter(peer, reason, reasonCode, null, true); return banlistRouter(peer, reason, reasonCode, null, true);
} }
public boolean shitlistRouter(Hash peer, String reason, String transport, boolean forever) { public boolean banlistRouter(Hash peer, String reason, String transport, boolean forever) {
return shitlistRouter(peer, reason, null, transport, forever); return banlistRouter(peer, reason, null, transport, forever);
} }
private boolean shitlistRouter(Hash peer, String reason, String reasonCode, String transport, boolean forever) { private boolean banlistRouter(Hash peer, String reason, String reasonCode, String transport, boolean forever) {
if (peer == null) { if (peer == null) {
_log.error("wtf, why did we try to shitlist null?", new Exception("shitfaced")); _log.error("wtf, why did we try to banlist null?", new Exception("banfaced"));
return false; return false;
} }
if (_context.routerHash().equals(peer)) { if (_context.routerHash().equals(peer)) {
_log.error("wtf, why did we try to shitlist ourselves?", new Exception("shitfaced")); _log.error("wtf, why did we try to banlist ourselves?", new Exception("banfaced"));
return false; return false;
} }
boolean wasAlready = false; boolean wasAlready = false;
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Shitlisting router " + peer.toBase64() + _log.info("Banlisting router " + peer.toBase64() +
((transport != null) ? " on transport " + transport : ""), new Exception("Shitlist cause: " + reason)); ((transport != null) ? " on transport " + transport : ""), new Exception("Banlist cause: " + reason));
Entry e = new Entry(); Entry e = new Entry();
if (forever) { if (forever) {
e.expireOn = _context.clock().now() + SHITLIST_DURATION_FOREVER; e.expireOn = _context.clock().now() + BANLIST_DURATION_FOREVER;
} else if (transport != null) { } else if (transport != null) {
e.expireOn = _context.clock().now() + SHITLIST_DURATION_PARTIAL; e.expireOn = _context.clock().now() + BANLIST_DURATION_PARTIAL;
} else { } else {
long period = SHITLIST_DURATION_MS + _context.random().nextLong(SHITLIST_DURATION_MS / 4); long period = BANLIST_DURATION_MS + _context.random().nextLong(BANLIST_DURATION_MS / 4);
PeerProfile prof = _context.profileOrganizer().getProfile(peer); PeerProfile prof = _context.profileOrganizer().getProfile(peer);
if (prof != null) { if (prof != null) {
period = SHITLIST_DURATION_MS << prof.incrementShitlists(); period = BANLIST_DURATION_MS << prof.incrementBanlists();
period += _context.random().nextLong(period); period += _context.random().nextLong(period);
} }
if (period > SHITLIST_DURATION_MAX) if (period > BANLIST_DURATION_MAX)
period = SHITLIST_DURATION_MAX; period = BANLIST_DURATION_MAX;
e.expireOn = _context.clock().now() + period; e.expireOn = _context.clock().now() + period;
} }
e.cause = reason; e.cause = reason;
@@ -202,28 +202,28 @@ public class Shitlist {
//_context.tunnelManager().peerFailed(peer); //_context.tunnelManager().peerFailed(peer);
//_context.messageRegistry().peerFailed(peer); //_context.messageRegistry().peerFailed(peer);
if (!wasAlready) if (!wasAlready)
_context.messageHistory().shitlist(peer, reason); _context.messageHistory().banlist(peer, reason);
return wasAlready; return wasAlready;
} }
public void unshitlistRouter(Hash peer) { public void unbanlistRouter(Hash peer) {
unshitlistRouter(peer, true); unbanlistRouter(peer, true);
} }
private void unshitlistRouter(Hash peer, boolean realUnshitlist) { unshitlistRouter(peer, realUnshitlist, null); } private void unbanlistRouter(Hash peer, boolean realUnbanlist) { unbanlistRouter(peer, realUnbanlist, null); }
public void unshitlistRouter(Hash peer, String transport) { unshitlistRouter(peer, true, transport); } public void unbanlistRouter(Hash peer, String transport) { unbanlistRouter(peer, true, transport); }
private void unshitlistRouter(Hash peer, boolean realUnshitlist, String transport) { private void unbanlistRouter(Hash peer, boolean realUnbanlist, String transport) {
if (peer == null) return; if (peer == null) return;
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Calling unshitlistRouter " + peer.toBase64() _log.debug("Calling unbanlistRouter " + peer.toBase64()
+ (transport != null ? "/" + transport : "")); + (transport != null ? "/" + transport : ""));
boolean fully = false; boolean fully = false;
Entry e = _entries.remove(peer); Entry e = _entries.remove(peer);
if ( (e == null) || (e.transports == null) || (transport == null) || (e.transports.size() <= 1) ) { if ( (e == null) || (e.transports == null) || (transport == null) || (e.transports.size() <= 1) ) {
// fully unshitlisted // fully unbanlisted
fully = true; fully = true;
} else { } else {
e.transports.remove(transport); e.transports.remove(transport);
@@ -234,30 +234,30 @@ public class Shitlist {
} }
if (fully) { if (fully) {
if (realUnshitlist) { if (realUnbanlist) {
PeerProfile prof = _context.profileOrganizer().getProfile(peer); PeerProfile prof = _context.profileOrganizer().getProfile(peer);
if (prof != null) if (prof != null)
prof.unshitlist(); prof.unbanlist();
} }
_context.messageHistory().unshitlist(peer); _context.messageHistory().unbanlist(peer);
if (_log.shouldLog(Log.INFO) && e != null) if (_log.shouldLog(Log.INFO) && e != null)
_log.info("Unshitlisting router " + peer.toBase64() _log.info("Unbanlisting router " + peer.toBase64()
+ (transport != null ? "/" + transport : "")); + (transport != null ? "/" + transport : ""));
} }
} }
public boolean isShitlisted(Hash peer) { return isShitlisted(peer, null); } public boolean isBanlisted(Hash peer) { return isBanlisted(peer, null); }
public boolean isShitlisted(Hash peer, String transport) { public boolean isBanlisted(Hash peer, String transport) {
boolean rv = false; boolean rv = false;
boolean unshitlist = false; boolean unbanlist = false;
Entry entry = _entries.get(peer); Entry entry = _entries.get(peer);
if (entry == null) { if (entry == null) {
rv = false; rv = false;
} else if (entry.expireOn <= _context.clock().now()) { } else if (entry.expireOn <= _context.clock().now()) {
_entries.remove(peer); _entries.remove(peer);
unshitlist = true; unbanlist = true;
rv = false; rv = false;
} else if (entry.transports == null) { } else if (entry.transports == null) {
rv = true; rv = true;
@@ -265,21 +265,21 @@ public class Shitlist {
rv = entry.transports.contains(transport); rv = entry.transports.contains(transport);
} }
if (unshitlist) { if (unbanlist) {
PeerProfile prof = _context.profileOrganizer().getProfile(peer); PeerProfile prof = _context.profileOrganizer().getProfile(peer);
if (prof != null) if (prof != null)
prof.unshitlist(); prof.unbanlist();
_context.messageHistory().unshitlist(peer); _context.messageHistory().unbanlist(peer);
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Unshitlisting router (expired) " + peer.toBase64()); _log.info("Unbanlisting router (expired) " + peer.toBase64());
} }
return rv; return rv;
} }
public boolean isShitlistedForever(Hash peer) { public boolean isBanlistedForever(Hash peer) {
Entry entry = _entries.get(peer); Entry entry = _entries.get(peer);
return entry != null && entry.expireOn > _context.clock().now() + SHITLIST_DURATION_MAX; return entry != null && entry.expireOn > _context.clock().now() + BANLIST_DURATION_MAX;
} }
/** @deprecated moved to router console */ /** @deprecated moved to router console */

Some files were not shown because too many files have changed in this diff Show More