forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p.zzz.test2' (head 5c1b78bd78845b0c8b90fbb60412c68e7dc4f3e6)
to branch 'i2p.i2p' (head 8bdc25c8e6f40491f20b533d94eacab012adba35)
This commit is contained in:
@ -77,6 +77,7 @@ trans.pt = apps/routerconsole/locale-news/messages_pt.po
|
||||
trans.ru_RU = apps/routerconsole/locale-news/messages_ru.po
|
||||
trans.sv_SE = apps/routerconsole/locale-news/messages_sv.po
|
||||
trans.tr_TR = apps/routerconsole/locale-news/messages_tr.po
|
||||
trans.zh_CN = apps/routerconsole/locale-news/messages_zh.po
|
||||
|
||||
[I2P.i2psnark]
|
||||
source_file = apps/i2psnark/locale/messages_en.po
|
||||
|
@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
|
||||
INST_DIR=directory
|
||||
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
<target name="bundle" unless="no.bundle">
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
|
@ -16,6 +16,10 @@ TMPFILE=build/javafiles.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
|
@ -130,6 +130,7 @@
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
|
@ -15,6 +15,10 @@ TMPFILE=build/javafiles.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
|
@ -193,6 +193,7 @@ public class SnarkManager implements CompleteListener {
|
||||
if (_umgr != null) {
|
||||
_uhandler = new UpdateHandler(_context, _umgr, SnarkManager.this);
|
||||
_umgr.register(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT, 10);
|
||||
_umgr.register(_uhandler, UpdateType.ROUTER_SIGNED_SU3, UpdateMethod.TORRENT, 10);
|
||||
_log.warn("Registering with update manager");
|
||||
} else {
|
||||
_log.warn("No update manager to register with");
|
||||
@ -210,6 +211,7 @@ public class SnarkManager implements CompleteListener {
|
||||
if (_umgr != null && _uhandler != null) {
|
||||
//_uhandler.shutdown();
|
||||
_umgr.unregister(_uhandler, UpdateType.ROUTER_SIGNED, UpdateMethod.TORRENT);
|
||||
_umgr.unregister(_uhandler, UpdateType.ROUTER_SIGNED_SU3, UpdateMethod.TORRENT);
|
||||
}
|
||||
_running = false;
|
||||
_monitor.interrupt();
|
||||
|
@ -42,10 +42,10 @@ class UpdateHandler implements Updater {
|
||||
*/
|
||||
public UpdateTask update(UpdateType type, UpdateMethod method, List<URI> updateSources,
|
||||
String id, String newVersion, long maxTime) {
|
||||
if (type != UpdateType.ROUTER_SIGNED ||
|
||||
if ((type != UpdateType.ROUTER_SIGNED && type != UpdateType.ROUTER_SIGNED_SU3) ||
|
||||
method != UpdateMethod.TORRENT || updateSources.isEmpty())
|
||||
return null;
|
||||
UpdateRunner update = new UpdateRunner(_context, _umgr, _smgr, updateSources, newVersion);
|
||||
UpdateRunner update = new UpdateRunner(_context, _umgr, _smgr, type, updateSources, newVersion);
|
||||
_umgr.notifyProgress(update, "<b>" + _smgr.util().getString("Updating") + "</b>");
|
||||
return update;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
||||
private final Log _log;
|
||||
private final UpdateManager _umgr;
|
||||
private final SnarkManager _smgr;
|
||||
private final UpdateType _type;
|
||||
private final List<URI> _urls;
|
||||
private volatile boolean _isRunning;
|
||||
private volatile boolean _hasMetaInfo;
|
||||
@ -36,11 +37,12 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
||||
private static final long CHECK_INTERVAL = 3*60*1000;
|
||||
|
||||
public UpdateRunner(I2PAppContext ctx, UpdateManager umgr, SnarkManager smgr,
|
||||
List<URI> uris, String newVersion) {
|
||||
UpdateType type, List<URI> uris, String newVersion) {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(getClass());
|
||||
_umgr = umgr;
|
||||
_smgr = smgr;
|
||||
_type = type;
|
||||
_urls = uris;
|
||||
_newVersion = newVersion;
|
||||
}
|
||||
@ -56,7 +58,7 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
||||
}
|
||||
}
|
||||
|
||||
public UpdateType getType() { return UpdateType.ROUTER_SIGNED; }
|
||||
public UpdateType getType() { return _type; }
|
||||
|
||||
public UpdateMethod getMethod() { return UpdateMethod.TORRENT; }
|
||||
|
||||
@ -111,7 +113,7 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
||||
}
|
||||
_snark = _smgr.addMagnet(name, ih, trackerURL, true, true, this);
|
||||
if (_snark != null) {
|
||||
updateStatus("<b>" + _smgr.util().getString("Updating from {0}", updateURL) + "</b>");
|
||||
updateStatus("<b>" + _smgr.util().getString("Updating from {0}", linkify(updateURL)) + "</b>");
|
||||
new Timeout();
|
||||
break;
|
||||
}
|
||||
@ -292,6 +294,12 @@ class UpdateRunner implements UpdateTask, CompleteListener {
|
||||
|
||||
//////// end CompleteListener methods
|
||||
|
||||
private static String linkify(String url) {
|
||||
String durl = url.length() <= 28 ? url :
|
||||
url.substring(0, 25) + "…";
|
||||
return "<a target=\"_blank\" href=\"" + url + "\"/>" + durl + "</a>";
|
||||
}
|
||||
|
||||
private void updateStatus(String s) {
|
||||
_umgr.notifyProgress(this, s);
|
||||
}
|
||||
|
@ -6,20 +6,21 @@
|
||||
# Translators:
|
||||
# "blabla", 2011
|
||||
# blabla <blabla@trash-mail.com>, 2012
|
||||
# D.A. Loader <>, 2012
|
||||
# D.A. Loader, 2012
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# foo <foo@bar>, 2009
|
||||
# SteinQuadrat, 2013
|
||||
# mixxy, 2011
|
||||
# nextloop <ga25day@mytum.de>, 2013
|
||||
# pirr <pirr@tormail.org>, 2012
|
||||
# zeroflag <zeroflag@i2pmail.org>, 2013
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-07-02 17:23+0000\n"
|
||||
"PO-Revision-Date: 2013-06-27 13:09+0000\n"
|
||||
"Last-Translator: SteinQuadrat\n"
|
||||
"POT-Creation-Date: 2013-09-26 21:33+0000\n"
|
||||
"PO-Revision-Date: 2013-09-23 22:30+0000\n"
|
||||
"Last-Translator: nextloop <ga25day@mytum.de>\n"
|
||||
"Language-Team: German (http://www.transifex.com/projects/p/I2P/language/"
|
||||
"de/)\n"
|
||||
"Language: de\n"
|
||||
@ -426,16 +427,16 @@ msgstr "I2P Tunnel öffnen ..."
|
||||
msgid "Opening the I2P tunnel and starting all torrents."
|
||||
msgstr "Öffne den I2P-Tunnel und starte alle Torrents ..."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1903
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1911
|
||||
msgid "Stopping all torrents and closing the I2P tunnel."
|
||||
msgstr "Stoppe alle Torrents und beende den I2P-Tunnel."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1922
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1930
|
||||
msgid "Closing I2P tunnel after notifying trackers."
|
||||
msgstr "Der I2P-Tunnel wird nach Benachrichtigung der Tracker geschlossen."
|
||||
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1929
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1940
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1937
|
||||
#: ../java/src/org/klomp/snark/SnarkManager.java:1948
|
||||
msgid "I2P tunnel closed."
|
||||
msgstr "I2P-Tunnel geschlossen."
|
||||
|
||||
@ -600,9 +601,8 @@ msgid "Stop All"
|
||||
msgstr "Stoppe alle"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:515
|
||||
#, fuzzy
|
||||
msgid "Start all stopped torrents"
|
||||
msgstr "Torrent starten"
|
||||
msgstr "Alle angehaltenen Torrents fortsetzen"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:517
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:531
|
||||
@ -1159,7 +1159,7 @@ msgid "Website URL"
|
||||
msgstr "Webseiten-URL"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2016
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2567
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2566
|
||||
msgid "Open"
|
||||
msgstr "offen"
|
||||
|
||||
@ -1209,15 +1209,15 @@ msgstr "Tracker Liste"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2356
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
msgstr "Kommentar"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2365
|
||||
msgid "Created"
|
||||
msgstr ""
|
||||
msgstr "Erstellt"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2375
|
||||
msgid "Created By"
|
||||
msgstr ""
|
||||
msgstr "Erstellt von"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2385
|
||||
msgid "Magnet link"
|
||||
@ -1283,18 +1283,18 @@ msgstr "vollständig"
|
||||
msgid "remaining"
|
||||
msgstr "verbleibend"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2594
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2592
|
||||
msgid "High"
|
||||
msgstr "hoch"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2599
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2597
|
||||
msgid "Normal"
|
||||
msgstr "normal"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2604
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2602
|
||||
msgid "Skip"
|
||||
msgstr "auslassen"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2613
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2611
|
||||
msgid "Save priorities"
|
||||
msgstr "Prioritäten speichern"
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2psnark\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-08-11 14:23+0000\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:46+0000\n"
|
||||
"PO-Revision-Date: 2010-06-15 14:09+0100\n"
|
||||
"Last-Translator: duck <duck@mail.i2p>\n"
|
||||
"Language-Team: duck <duck@mail.i2p>\n"
|
||||
@ -1100,7 +1100,7 @@ msgid "Website URL"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2016
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2567
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2566
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
@ -1224,18 +1224,18 @@ msgstr ""
|
||||
msgid "remaining"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2594
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2592
|
||||
msgid "High"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2599
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2597
|
||||
msgid "Normal"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2604
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2602
|
||||
msgid "Skip"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2613
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2611
|
||||
msgid "Save priorities"
|
||||
msgstr ""
|
||||
|
@ -15,7 +15,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-08-11 14:29+0000\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:24+0000\n"
|
||||
"PO-Revision-Date: 2013-07-16 15:32+0000\n"
|
||||
"Last-Translator: Boxoa590\n"
|
||||
"Language-Team: French (http://www.transifex.com/projects/p/I2P/language/"
|
||||
@ -1152,7 +1152,7 @@ msgid "Website URL"
|
||||
msgstr "URL du site web"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2016
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2567
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2566
|
||||
msgid "Open"
|
||||
msgstr "Ouvrir le fichier"
|
||||
|
||||
@ -1276,18 +1276,18 @@ msgstr "complet"
|
||||
msgid "remaining"
|
||||
msgstr "restant"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2594
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2592
|
||||
msgid "High"
|
||||
msgstr "Haut"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2599
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2597
|
||||
msgid "Normal"
|
||||
msgstr "Normal"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2604
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2602
|
||||
msgid "Skip"
|
||||
msgstr "Ignorer"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2613
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2611
|
||||
msgid "Save priorities"
|
||||
msgstr "Sauvegarder les priorités"
|
||||
|
@ -15,7 +15,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-08-11 14:27+0000\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:16+0000\n"
|
||||
"PO-Revision-Date: 2013-07-12 16:38+0000\n"
|
||||
"Last-Translator: varnav\n"
|
||||
"Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/I2P/"
|
||||
@ -1155,7 +1155,7 @@ msgid "Website URL"
|
||||
msgstr "URL сайта"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2016
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2567
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2566
|
||||
msgid "Open"
|
||||
msgstr "Открыть"
|
||||
|
||||
@ -1281,18 +1281,18 @@ msgstr "скачано"
|
||||
msgid "remaining"
|
||||
msgstr "осталось"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2594
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2592
|
||||
msgid "High"
|
||||
msgstr "Высокий"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2599
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2597
|
||||
msgid "Normal"
|
||||
msgstr "Нормальный"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2604
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2602
|
||||
msgid "Skip"
|
||||
msgstr "Пропустить"
|
||||
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2613
|
||||
#: ../java/src/org/klomp/snark/web/I2PSnarkServlet.java:2611
|
||||
msgid "Save priorities"
|
||||
msgstr "Сохранить приоритеты"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,7 @@ ogv = video/ogg
|
||||
oga = audio/ogg
|
||||
rar = application/x-rar-compressed
|
||||
su2 = application/zip
|
||||
su3 = application/zip
|
||||
sud = application/zip
|
||||
tbz = application/x-bzip2
|
||||
txt = text/plain
|
||||
|
@ -92,6 +92,7 @@
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
@ -124,6 +125,7 @@
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages-proxy.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
|
@ -15,6 +15,10 @@ TMPFILE=build/javafiles-proxy.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
|
@ -14,6 +14,9 @@ CLASS=net.i2p.i2ptunnel.web.messages
|
||||
TMPFILE=build/javafiles.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC="${JAVA_HOME}/../bin/javac"
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
|
@ -5,21 +5,21 @@
|
||||
#
|
||||
# Translators:
|
||||
# blabla, 2011
|
||||
# blabla <blabla@trash-mail.com>, 2011-2012
|
||||
# D.A. Loader <>, 2012
|
||||
# driz <driz@i2pmail.org>, 2012
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# foo <foo@bar>, 2009
|
||||
# mixxy, 2011
|
||||
# nextloop <ga25day@mytum.de>, 2013
|
||||
# pirr <pirr@tormail.org>, 2012
|
||||
# zeroflag <zeroflag@i2pmail.org>, 2013
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2ptunnel\n"
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-07-13 18:49+0000\n"
|
||||
"PO-Revision-Date: 2013-05-08 13:15+0000\n"
|
||||
"Last-Translator: zeroflag <zeroflag@i2pmail.org>\n"
|
||||
"POT-Creation-Date: 2013-09-26 21:33+0000\n"
|
||||
"PO-Revision-Date: 2013-09-23 22:34+0000\n"
|
||||
"Last-Translator: nextloop <ga25day@mytum.de>\n"
|
||||
"Language-Team: German (http://www.transifex.com/projects/p/I2P/language/"
|
||||
"de/)\n"
|
||||
"Language: de\n"
|
||||
@ -28,337 +28,339 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../java/build/Proxy.java:5
|
||||
msgid "Proxy Authorization Required"
|
||||
msgstr "Outproxy Autorisation"
|
||||
|
||||
#: ../java/build/Proxy.java:6
|
||||
msgid "I2P HTTP Proxy Authorization Required"
|
||||
msgstr "Outproxy Autorisation"
|
||||
|
||||
#: ../java/build/Proxy.java:7
|
||||
msgid "This proxy is configured to require a username and password for access."
|
||||
#: ../java/build/Proxy.java:5 ../java/build/Proxy.java:11
|
||||
msgid "Warning: Outproxy Not Found"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:8
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Please enter your username and password, or check your {0}router "
|
||||
"configuration{1} or {2}I2PTunnel configuration{3}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:9
|
||||
#, java-format
|
||||
msgid ""
|
||||
"To disable authorization, remove the configuration {0}i2ptunnel.proxy."
|
||||
"auth=basic{1}, then stop and restart the HTTP Proxy tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:10 ../java/build/Proxy.java:16
|
||||
msgid "Warning: No Outproxy Configured"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:11 ../java/build/Proxy.java:20
|
||||
#: ../java/build/Proxy.java:32 ../java/build/Proxy.java:44
|
||||
#: ../java/build/Proxy.java:52 ../java/build/Proxy.java:61
|
||||
#: ../java/build/Proxy.java:74 ../java/build/Proxy.java:83
|
||||
#: ../java/build/Proxy.java:93 ../java/build/Proxy.java:103
|
||||
#: ../java/build/Proxy.java:115
|
||||
#: ../java/build/Proxy.java:6 ../java/build/Proxy.java:18
|
||||
#: ../java/build/Proxy.java:27 ../java/build/Proxy.java:40
|
||||
#: ../java/build/Proxy.java:49 ../java/build/Proxy.java:61
|
||||
#: ../java/build/Proxy.java:69 ../java/build/Proxy.java:88
|
||||
#: ../java/build/Proxy.java:99 ../java/build/Proxy.java:111
|
||||
#: ../java/build/Proxy.java:121
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:196
|
||||
msgid "Router Console"
|
||||
msgstr "Routerkonsole"
|
||||
|
||||
#: ../java/build/Proxy.java:12 ../java/build/Proxy.java:21
|
||||
#: ../java/build/Proxy.java:33 ../java/build/Proxy.java:45
|
||||
#: ../java/build/Proxy.java:53 ../java/build/Proxy.java:62
|
||||
#: ../java/build/Proxy.java:75 ../java/build/Proxy.java:84
|
||||
#: ../java/build/Proxy.java:94 ../java/build/Proxy.java:104
|
||||
#: ../java/build/Proxy.java:116
|
||||
#: ../java/build/Proxy.java:7 ../java/build/Proxy.java:19
|
||||
#: ../java/build/Proxy.java:28 ../java/build/Proxy.java:41
|
||||
#: ../java/build/Proxy.java:50 ../java/build/Proxy.java:62
|
||||
#: ../java/build/Proxy.java:70 ../java/build/Proxy.java:89
|
||||
#: ../java/build/Proxy.java:100 ../java/build/Proxy.java:112
|
||||
#: ../java/build/Proxy.java:122
|
||||
msgid "I2P Router Console"
|
||||
msgstr "Routerkonsole"
|
||||
|
||||
#: ../java/build/Proxy.java:13 ../java/build/Proxy.java:22
|
||||
#: ../java/build/Proxy.java:34 ../java/build/Proxy.java:46
|
||||
#: ../java/build/Proxy.java:54 ../java/build/Proxy.java:63
|
||||
#: ../java/build/Proxy.java:76 ../java/build/Proxy.java:85
|
||||
#: ../java/build/Proxy.java:95 ../java/build/Proxy.java:105
|
||||
#: ../java/build/Proxy.java:117
|
||||
#: ../java/build/Proxy.java:8 ../java/build/Proxy.java:20
|
||||
#: ../java/build/Proxy.java:29 ../java/build/Proxy.java:42
|
||||
#: ../java/build/Proxy.java:51 ../java/build/Proxy.java:63
|
||||
#: ../java/build/Proxy.java:71 ../java/build/Proxy.java:90
|
||||
#: ../java/build/Proxy.java:101 ../java/build/Proxy.java:113
|
||||
#: ../java/build/Proxy.java:123
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:197
|
||||
msgid "Configuration"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: ../java/build/Proxy.java:14 ../java/build/Proxy.java:23
|
||||
#: ../java/build/Proxy.java:35 ../java/build/Proxy.java:47
|
||||
#: ../java/build/Proxy.java:55 ../java/build/Proxy.java:64
|
||||
#: ../java/build/Proxy.java:77 ../java/build/Proxy.java:86
|
||||
#: ../java/build/Proxy.java:96 ../java/build/Proxy.java:106
|
||||
#: ../java/build/Proxy.java:118
|
||||
#: ../java/build/Proxy.java:9 ../java/build/Proxy.java:21
|
||||
#: ../java/build/Proxy.java:30 ../java/build/Proxy.java:43
|
||||
#: ../java/build/Proxy.java:52 ../java/build/Proxy.java:64
|
||||
#: ../java/build/Proxy.java:72 ../java/build/Proxy.java:91
|
||||
#: ../java/build/Proxy.java:102 ../java/build/Proxy.java:114
|
||||
#: ../java/build/Proxy.java:124
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:197
|
||||
msgid "Help"
|
||||
msgstr "Hilfe"
|
||||
|
||||
#: ../java/build/Proxy.java:15 ../java/build/Proxy.java:24
|
||||
#: ../java/build/Proxy.java:36 ../java/build/Proxy.java:48
|
||||
#: ../java/build/Proxy.java:56 ../java/build/Proxy.java:65
|
||||
#: ../java/build/Proxy.java:78 ../java/build/Proxy.java:87
|
||||
#: ../java/build/Proxy.java:97 ../java/build/Proxy.java:107
|
||||
#: ../java/build/Proxy.java:119
|
||||
#: ../java/build/Proxy.java:10 ../java/build/Proxy.java:22
|
||||
#: ../java/build/Proxy.java:31 ../java/build/Proxy.java:44
|
||||
#: ../java/build/Proxy.java:53 ../java/build/Proxy.java:65
|
||||
#: ../java/build/Proxy.java:73 ../java/build/Proxy.java:92
|
||||
#: ../java/build/Proxy.java:103 ../java/build/Proxy.java:115
|
||||
#: ../java/build/Proxy.java:125
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:197
|
||||
msgid "Addressbook"
|
||||
msgstr "Adressbuch"
|
||||
|
||||
#: ../java/build/Proxy.java:17
|
||||
msgid ""
|
||||
"Your request was for a site outside of I2P, but you have no HTTP outproxy "
|
||||
"configured."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:18
|
||||
msgid "Please configure an outproxy in I2PTunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:19
|
||||
msgid "Information: New Host Name"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:25
|
||||
msgid "Information: New Host Name with Address Helper"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:26
|
||||
msgid ""
|
||||
"The address helper link you followed is for a new host name that is not in "
|
||||
"your address book."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:27
|
||||
msgid "You may save this host name to your local address book."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:28
|
||||
msgid ""
|
||||
"If you save it to your address book, you will not see this message again."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:29
|
||||
msgid ""
|
||||
"If you do not save it, the host name will be forgotten after the next router "
|
||||
"restart."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:30
|
||||
msgid ""
|
||||
"If you do not wish to visit this host, click the \"back\" button on your "
|
||||
"browser."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:31 ../java/build/Proxy.java:37
|
||||
msgid "Warning: Invalid Destination"
|
||||
msgstr "lokales Ziel"
|
||||
|
||||
#: ../java/build/Proxy.java:38
|
||||
msgid ""
|
||||
"The eepsite destination specified was not valid, or was otherwise "
|
||||
"unreachable."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:39
|
||||
msgid ""
|
||||
"Perhaps you pasted in the wrong Base 64 string or the link you are following "
|
||||
"is bad."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:40
|
||||
msgid "The I2P host could also be offline."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:41 ../java/build/Proxy.java:123
|
||||
#, java-format
|
||||
msgid "You may want to {0}retry{1}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:42 ../java/build/Proxy.java:72
|
||||
#: ../java/build/Proxy.java:113 ../java/build/Proxy.java:124
|
||||
msgid "Could not find the following destination:"
|
||||
msgstr "Tunnel Ziel"
|
||||
|
||||
#: ../java/build/Proxy.java:43 ../java/build/Proxy.java:49
|
||||
msgid "Warning: Request Denied"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:50
|
||||
msgid "You attempted to connect to a non-I2P website or location."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:51 ../java/build/Proxy.java:57
|
||||
msgid "Warning: Invalid Request URI"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:58
|
||||
msgid "The request URI is invalid, and probably contains illegal characters."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:59
|
||||
msgid ""
|
||||
"If you clicked a link, check the end of the URI for any characters the "
|
||||
"browser has mistakenly added on."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:60
|
||||
msgid "Warning: Eepsite Unknown"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:66
|
||||
msgid "Warning: Eepsite Not Found in Addressbook"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:67
|
||||
msgid "The eepsite was not found in your router's addressbook."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:68
|
||||
msgid "Check the link or find a Base 32 or Base 64 address."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:69
|
||||
#, java-format
|
||||
msgid "If you have the Base 64 address, {0}add it to your addressbook{1}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:70
|
||||
msgid ""
|
||||
"Otherwise, find a Base 32 or address helper link, or use a jump service link "
|
||||
"below."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:71
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Seeing this page often? See {0}the FAQ{1} for help in {2}adding some "
|
||||
"subscriptions{3} to your addressbook."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:73
|
||||
msgid "Error: Request Denied"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:79
|
||||
msgid "Error: Local Access"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:80
|
||||
msgid "Your browser is misconfigured."
|
||||
msgstr "Dein Browser unterstützt keine iFrames."
|
||||
|
||||
#: ../java/build/Proxy.java:81
|
||||
msgid ""
|
||||
"Do not use the proxy to access the router console, localhost, or local LAN "
|
||||
"destinations."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:82 ../java/build/Proxy.java:88
|
||||
msgid "Warning: Non-HTTP Protocol"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:89
|
||||
msgid "The request uses a bad protocol."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:90
|
||||
#, java-format
|
||||
msgid "The I2P HTTP Proxy supports {0}http://{1} requests ONLY."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:91
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Other protocols such as {0}https://{1} and {0}ftp://{1} are not allowed."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:92 ../java/build/Proxy.java:98
|
||||
msgid "Warning: Bad Address Helper"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:99
|
||||
#, java-format
|
||||
msgid "The helper key in the URL ({0}i2paddresshelper={1}) is not resolvable."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:100
|
||||
msgid "It seems to be garbage data, or a mistyped Base 32 address."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:101
|
||||
msgid ""
|
||||
"Check your URL to try and fix the helper key to be a valid Base 32 hostname "
|
||||
"or Base 64 key."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:102 ../java/build/Proxy.java:108
|
||||
msgid "Warning: Outproxy Not Found"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:109
|
||||
#: ../java/build/Proxy.java:12
|
||||
msgid "The HTTP Outproxy was not found."
|
||||
msgstr "Der HTTP-Proxy ist nicht bereit"
|
||||
|
||||
#: ../java/build/Proxy.java:110
|
||||
#: ../java/build/Proxy.java:13
|
||||
msgid ""
|
||||
"It is offline, there is network congestion, or your router is not yet well-"
|
||||
"integrated with peers."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:111
|
||||
#: ../java/build/Proxy.java:14
|
||||
#, java-format
|
||||
msgid ""
|
||||
"You may want to {0}retry{1} as this will randomly reselect an outproxy from "
|
||||
"the pool you have defined {2}here{3} (if you have more than one configured)."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:112
|
||||
#: ../java/build/Proxy.java:15
|
||||
#, java-format
|
||||
msgid ""
|
||||
"If you continue to have trouble you may want to edit your outproxy list {0}"
|
||||
"here{1}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:114 ../java/build/Proxy.java:120
|
||||
msgid "Warning: Eepsite Unreachable"
|
||||
#: ../java/build/Proxy.java:16 ../java/build/Proxy.java:38
|
||||
#: ../java/build/Proxy.java:59 ../java/build/Proxy.java:97
|
||||
msgid "Could not find the following destination:"
|
||||
msgstr "Tunnel Ziel"
|
||||
|
||||
#: ../java/build/Proxy.java:17
|
||||
msgid "Error: Request Denied"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:121
|
||||
msgid "The eepsite was not reachable."
|
||||
#: ../java/build/Proxy.java:23
|
||||
msgid "Error: Local Access"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:122
|
||||
#: ../java/build/Proxy.java:24
|
||||
msgid "Your browser is misconfigured."
|
||||
msgstr "Dein Browser unterstützt keine iFrames."
|
||||
|
||||
#: ../java/build/Proxy.java:25
|
||||
msgid ""
|
||||
"The eepsite is offline, there is network congestion, or your router is not "
|
||||
"yet well-integrated with peers."
|
||||
"Do not use the proxy to access the router console, localhost, or local LAN "
|
||||
"destinations."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:125 ../java/build/Proxy.java:126
|
||||
#: ../java/build/Proxy.java:26
|
||||
msgid "Warning: Eepsite Unknown"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:32
|
||||
msgid "Warning: Eepsite Not Found in Addressbook"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:33
|
||||
msgid "The eepsite was not found in your router's addressbook."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:34
|
||||
msgid "Check the link or find a Base 32 or Base 64 address."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:35
|
||||
#, java-format
|
||||
msgid "If you have the Base 64 address, {0}add it to your addressbook{1}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:36
|
||||
msgid ""
|
||||
"Otherwise, find a Base 32 or address helper link, or use a jump service link "
|
||||
"below."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:37
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Seeing this page often? See {0}the FAQ{1} for help in {2}adding some "
|
||||
"subscriptions{3} to your addressbook."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:39 ../java/build/Proxy.java:45
|
||||
msgid "Warning: Invalid Request URI"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:46
|
||||
msgid "The request URI is invalid, and probably contains illegal characters."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:47
|
||||
msgid ""
|
||||
"If you clicked a link, check the end of the URI for any characters the "
|
||||
"browser has mistakenly added on."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:48 ../java/build/Proxy.java:54
|
||||
msgid "Warning: Invalid Destination"
|
||||
msgstr "lokales Ziel"
|
||||
|
||||
#: ../java/build/Proxy.java:55
|
||||
msgid ""
|
||||
"The eepsite destination specified was not valid, or was otherwise "
|
||||
"unreachable."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:56
|
||||
msgid ""
|
||||
"Perhaps you pasted in the wrong Base 64 string or the link you are following "
|
||||
"is bad."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:57
|
||||
msgid "The I2P host could also be offline."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:58 ../java/build/Proxy.java:96
|
||||
#, java-format
|
||||
msgid "You may want to {0}retry{1}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:60 ../java/build/Proxy.java:66
|
||||
msgid "Warning: Request Denied"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:67
|
||||
msgid "You attempted to connect to a non-I2P website or location."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:68 ../java/build/Proxy.java:74
|
||||
msgid "Warning: No Outproxy Configured"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:75
|
||||
msgid ""
|
||||
"Your request was for a site outside of I2P, but you have no HTTP outproxy "
|
||||
"configured."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:76
|
||||
msgid "Please configure an outproxy in I2PTunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:77 ../java/build/Proxy.java:78
|
||||
msgid "Warning: Destination Key Conflict"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:127
|
||||
#: ../java/build/Proxy.java:79
|
||||
msgid ""
|
||||
"The addresshelper link you followed specifies a different destination key "
|
||||
"than a host entry in your host database."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:128
|
||||
#: ../java/build/Proxy.java:80
|
||||
msgid ""
|
||||
"Someone could be trying to impersonate another eepsite, or people have given "
|
||||
"two eepsites identical names."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:129
|
||||
#: ../java/build/Proxy.java:81
|
||||
msgid ""
|
||||
"You can resolve the conflict by considering which key you trust, and either "
|
||||
"discarding the addresshelper link, discarding the host entry from your host "
|
||||
"database, or naming one of them differently."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:82
|
||||
msgid "Proxy Authorization Required"
|
||||
msgstr "Outproxy Autorisation"
|
||||
|
||||
#: ../java/build/Proxy.java:83
|
||||
msgid "I2P HTTP Proxy Authorization Required"
|
||||
msgstr "Outproxy Autorisation"
|
||||
|
||||
#: ../java/build/Proxy.java:84
|
||||
msgid "This proxy is configured to require a username and password for access."
|
||||
msgstr "Dieser Proxy kann nur mit Benutzername und Passwort erreicht werde."
|
||||
|
||||
#: ../java/build/Proxy.java:85
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Please enter your username and password, or check your {0}router "
|
||||
"configuration{1} or {2}I2PTunnel configuration{3}."
|
||||
msgstr ""
|
||||
"Bitte Benutzername und Passwort eingeben, oder überprüfe die {0}Router-"
|
||||
"Einstellungen{1} oder die {2}I2P-Tunnel Einstellungen{3}"
|
||||
|
||||
#: ../java/build/Proxy.java:86
|
||||
#, java-format
|
||||
msgid ""
|
||||
"To disable authorization, remove the configuration {0}i2ptunnel.proxy."
|
||||
"auth=basic{1}, then stop and restart the HTTP Proxy tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:87 ../java/build/Proxy.java:93
|
||||
msgid "Warning: Eepsite Unreachable"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:94
|
||||
msgid "The eepsite was not reachable."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:95
|
||||
msgid ""
|
||||
"The eepsite is offline, there is network congestion, or your router is not "
|
||||
"yet well-integrated with peers."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:98
|
||||
msgid "Information: New Host Name"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:104
|
||||
msgid "Information: New Host Name with Address Helper"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:105
|
||||
msgid ""
|
||||
"The address helper link you followed is for a new host name that is not in "
|
||||
"your address book."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:106
|
||||
msgid "You may save this host name to your local address book."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:107
|
||||
msgid ""
|
||||
"If you save it to your address book, you will not see this message again."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:108
|
||||
msgid ""
|
||||
"If you do not save it, the host name will be forgotten after the next router "
|
||||
"restart."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:109
|
||||
msgid ""
|
||||
"If you do not wish to visit this host, click the \"back\" button on your "
|
||||
"browser."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:110 ../java/build/Proxy.java:116
|
||||
msgid "Warning: Bad Address Helper"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:117
|
||||
#, java-format
|
||||
msgid "The helper key in the URL ({0}i2paddresshelper={1}) is not resolvable."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:118
|
||||
msgid "It seems to be garbage data, or a mistyped Base 32 address."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:119
|
||||
msgid ""
|
||||
"Check your URL to try and fix the helper key to be a valid Base 32 hostname "
|
||||
"or Base 64 key."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:120 ../java/build/Proxy.java:126
|
||||
msgid "Warning: Non-HTTP Protocol"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:127
|
||||
msgid "The request uses a bad protocol."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:128
|
||||
#, java-format
|
||||
msgid "The I2P HTTP Proxy supports {0}http://{1} requests ONLY."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:129
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Other protocols such as {0}https://{1} and {0}ftp://{1} are not allowed."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:572
|
||||
msgid "This seems to be a bad destination:"
|
||||
msgstr "Dies scheint kein gültiges Ziel zu sein:"
|
||||
@ -415,7 +417,7 @@ msgstr "{0} im privaten Adressbuch speichern und auf die Eepseite weiterleiten"
|
||||
msgid "HTTP Outproxy"
|
||||
msgstr "HTTP-Outproxy"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1185
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1216
|
||||
msgid ""
|
||||
"Click a link below to look for an address helper by using a \"jump\" service:"
|
||||
msgstr ""
|
||||
@ -423,7 +425,7 @@ msgstr ""
|
||||
"Adresshelfer von einem \"Sprung\"-Service:"
|
||||
|
||||
#. Translators: parameter is a host name
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1221
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1224
|
||||
#, java-format
|
||||
msgid "{0} jump service"
|
||||
msgstr "Weiterleitungsdienst {0}"
|
||||
|
@ -4,16 +4,16 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# Boxoa590, 2012-2013
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# foo <foo@bar>, 2009
|
||||
# Boxoa590, 2013
|
||||
# Boxoa590, 2012
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2ptunnel\n"
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-08-11 14:30+0000\n"
|
||||
"PO-Revision-Date: 2013-05-29 21:00+0000\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:24+0000\n"
|
||||
"PO-Revision-Date: 2013-08-18 18:06+0000\n"
|
||||
"Last-Translator: Boxoa590\n"
|
||||
"Language-Team: French (http://www.transifex.com/projects/p/I2P/language/"
|
||||
"fr/)\n"
|
||||
@ -25,7 +25,7 @@ msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:5 ../java/build/Proxy.java:11
|
||||
msgid "Warning: Outproxy Not Found"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : outproxy non trouvé"
|
||||
|
||||
#: ../java/build/Proxy.java:6 ../java/build/Proxy.java:18
|
||||
#: ../java/build/Proxy.java:27 ../java/build/Proxy.java:40
|
||||
@ -85,6 +85,8 @@ msgid ""
|
||||
"It is offline, there is network congestion, or your router is not yet well-"
|
||||
"integrated with peers."
|
||||
msgstr ""
|
||||
"Il est hors ligne, ou il ya congestion du réseau, ou votre routeur n'est pas "
|
||||
"encore bien intégré avec les pairs."
|
||||
|
||||
#: ../java/build/Proxy.java:14
|
||||
#, java-format
|
||||
@ -92,6 +94,9 @@ msgid ""
|
||||
"You may want to {0}retry{1} as this will randomly reselect an outproxy from "
|
||||
"the pool you have defined {2}here{3} (if you have more than one configured)."
|
||||
msgstr ""
|
||||
"Vous pouvez vouloir {0}réessayer{1} car cela va re-sélectionner au hasard un "
|
||||
"outproxy du pool que vous avez défini {2}içi{3} (si vous en avez plus d'un "
|
||||
"de configuré)."
|
||||
|
||||
#: ../java/build/Proxy.java:15
|
||||
#, java-format
|
||||
@ -99,6 +104,8 @@ msgid ""
|
||||
"If you continue to have trouble you may want to edit your outproxy list {0}"
|
||||
"here{1}."
|
||||
msgstr ""
|
||||
"Si vous continuez à avoir des dérangements vous pouvez vouloir modifier "
|
||||
"votre liste de outproxy {0}içi{1}."
|
||||
|
||||
#: ../java/build/Proxy.java:16 ../java/build/Proxy.java:38
|
||||
#: ../java/build/Proxy.java:59 ../java/build/Proxy.java:97
|
||||
@ -107,11 +114,11 @@ msgstr "Destination du tunnel"
|
||||
|
||||
#: ../java/build/Proxy.java:17
|
||||
msgid "Error: Request Denied"
|
||||
msgstr ""
|
||||
msgstr "Erreur : demande refusée"
|
||||
|
||||
#: ../java/build/Proxy.java:23
|
||||
msgid "Error: Local Access"
|
||||
msgstr ""
|
||||
msgstr "Erreur : accès local"
|
||||
|
||||
#: ../java/build/Proxy.java:24
|
||||
msgid "Your browser is misconfigured."
|
||||
@ -122,33 +129,39 @@ msgid ""
|
||||
"Do not use the proxy to access the router console, localhost, or local LAN "
|
||||
"destinations."
|
||||
msgstr ""
|
||||
"Ne pas utiliser le proxy pour accéder à la console du routeur, ni au "
|
||||
"localhost, ni vers des destinations de votre LAN local."
|
||||
|
||||
#: ../java/build/Proxy.java:26
|
||||
msgid "Warning: Eepsite Unknown"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : Eepsite inconnu"
|
||||
|
||||
#: ../java/build/Proxy.java:32
|
||||
msgid "Warning: Eepsite Not Found in Addressbook"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : Eepsite pas trouvé dans le carnet d'adresses"
|
||||
|
||||
#: ../java/build/Proxy.java:33
|
||||
msgid "The eepsite was not found in your router's addressbook."
|
||||
msgstr ""
|
||||
"Le eepsite n'a pas été trouvé dans le carnet d'adresses de votre routeur."
|
||||
|
||||
#: ../java/build/Proxy.java:34
|
||||
msgid "Check the link or find a Base 32 or Base 64 address."
|
||||
msgstr ""
|
||||
msgstr "Cliquez le lien ou trouvez une adresse base 32 ou base 64."
|
||||
|
||||
#: ../java/build/Proxy.java:35
|
||||
#, java-format
|
||||
msgid "If you have the Base 64 address, {0}add it to your addressbook{1}."
|
||||
msgstr ""
|
||||
"Si vous avez l''adresse Base 64, {0}ajoutez-là à votre carnet d''adresse{1}."
|
||||
|
||||
#: ../java/build/Proxy.java:36
|
||||
msgid ""
|
||||
"Otherwise, find a Base 32 or address helper link, or use a jump service link "
|
||||
"below."
|
||||
msgstr ""
|
||||
"Sinon, trouver un lien d'assistant d'adresse ou un lien Base 32, ou utiliser "
|
||||
"ci-dessous un lien service de saut."
|
||||
|
||||
#: ../java/build/Proxy.java:37
|
||||
#, java-format
|
||||
@ -156,83 +169,100 @@ msgid ""
|
||||
"Seeing this page often? See {0}the FAQ{1} for help in {2}adding some "
|
||||
"subscriptions{3} to your addressbook."
|
||||
msgstr ""
|
||||
"Voyez-vous cette page souvent ? Voyez {0}la FAQ{1} pour de l'aide afin d'{2}"
|
||||
"ajouter quelques abonnements{3} à votre carnet d'adresses."
|
||||
|
||||
#: ../java/build/Proxy.java:39 ../java/build/Proxy.java:45
|
||||
msgid "Warning: Invalid Request URI"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : demande invalide d'URI"
|
||||
|
||||
#: ../java/build/Proxy.java:46
|
||||
msgid "The request URI is invalid, and probably contains illegal characters."
|
||||
msgstr ""
|
||||
"L'URI de la requête n'est pas valide, et contient probablement des "
|
||||
"caractères illégaux."
|
||||
|
||||
#: ../java/build/Proxy.java:47
|
||||
msgid ""
|
||||
"If you clicked a link, check the end of the URI for any characters the "
|
||||
"browser has mistakenly added on."
|
||||
msgstr ""
|
||||
"Si vous avez cliqué sur un lien, vérifiez la fin de l'URI pour d'éventuels "
|
||||
"caractères que le navigateur aurait ajourté à tort."
|
||||
|
||||
#: ../java/build/Proxy.java:48 ../java/build/Proxy.java:54
|
||||
msgid "Warning: Invalid Destination"
|
||||
msgstr "Destination locale"
|
||||
msgstr "Avertissement : destination invalide"
|
||||
|
||||
#: ../java/build/Proxy.java:55
|
||||
msgid ""
|
||||
"The eepsite destination specified was not valid, or was otherwise "
|
||||
"unreachable."
|
||||
msgstr ""
|
||||
"La destination vers l'eepsite spécifié n'était pas valide, ou autrement "
|
||||
"était inaccessible."
|
||||
|
||||
#: ../java/build/Proxy.java:56
|
||||
msgid ""
|
||||
"Perhaps you pasted in the wrong Base 64 string or the link you are following "
|
||||
"is bad."
|
||||
msgstr ""
|
||||
"Peut-être que vous avez collé dans la mauvaise chaîne base 64, ou le lien "
|
||||
"que vous suivez est mauvais."
|
||||
|
||||
#: ../java/build/Proxy.java:57
|
||||
msgid "The I2P host could also be offline."
|
||||
msgstr ""
|
||||
msgstr "L'hôte I2P pourrait également être déconnecté."
|
||||
|
||||
#: ../java/build/Proxy.java:58 ../java/build/Proxy.java:96
|
||||
#, java-format
|
||||
msgid "You may want to {0}retry{1}."
|
||||
msgstr ""
|
||||
msgstr "Vous pouvez vouloir {0}réessayer{1}."
|
||||
|
||||
#: ../java/build/Proxy.java:60 ../java/build/Proxy.java:66
|
||||
msgid "Warning: Request Denied"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : demande refusée"
|
||||
|
||||
#: ../java/build/Proxy.java:67
|
||||
msgid "You attempted to connect to a non-I2P website or location."
|
||||
msgstr ""
|
||||
msgstr "Vous avez tenté de vous connecter à un site ou emplacement non-I2P."
|
||||
|
||||
#: ../java/build/Proxy.java:68 ../java/build/Proxy.java:74
|
||||
msgid "Warning: No Outproxy Configured"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : pas de outproxy configuré"
|
||||
|
||||
#: ../java/build/Proxy.java:75
|
||||
msgid ""
|
||||
"Your request was for a site outside of I2P, but you have no HTTP outproxy "
|
||||
"configured."
|
||||
msgstr ""
|
||||
"Votre demande était pour un site en dehors de I2P, mais vous n'avez aucun "
|
||||
"outproxy HTTP de configuré."
|
||||
|
||||
#: ../java/build/Proxy.java:76
|
||||
msgid "Please configure an outproxy in I2PTunnel."
|
||||
msgstr ""
|
||||
msgstr "Veuillez configurer un outproxy dans I2PTunnel."
|
||||
|
||||
#: ../java/build/Proxy.java:77 ../java/build/Proxy.java:78
|
||||
msgid "Warning: Destination Key Conflict"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : conflit de clé de destination"
|
||||
|
||||
#: ../java/build/Proxy.java:79
|
||||
msgid ""
|
||||
"The addresshelper link you followed specifies a different destination key "
|
||||
"than a host entry in your host database."
|
||||
msgstr ""
|
||||
"Le lien d'assistant d'adresse que vous avez suivi spécifie une clé de "
|
||||
"destination différente de l'entrée d'hôte contenue dans votre base de "
|
||||
"données hôte."
|
||||
|
||||
#: ../java/build/Proxy.java:80
|
||||
msgid ""
|
||||
"Someone could be trying to impersonate another eepsite, or people have given "
|
||||
"two eepsites identical names."
|
||||
msgstr ""
|
||||
"Quelqu'un pourrait essayer de se faire passer pour un autre eepsite, ou des "
|
||||
"gens ont donné des noms identiques à deux eepsites."
|
||||
|
||||
#: ../java/build/Proxy.java:81
|
||||
msgid ""
|
||||
@ -240,18 +270,24 @@ msgid ""
|
||||
"discarding the addresshelper link, discarding the host entry from your host "
|
||||
"database, or naming one of them differently."
|
||||
msgstr ""
|
||||
"Vous pouvez résoudre le conflit en considérant à quelle clé vous faites "
|
||||
"confiance, et soit rejeter le lien de l'assistant d'adresse en rejetant "
|
||||
"l'entrée d'hôte hors de votre base de données hôte, ou nommer l'une d'elles "
|
||||
"différemment."
|
||||
|
||||
#: ../java/build/Proxy.java:82
|
||||
msgid "Proxy Authorization Required"
|
||||
msgstr "Autorisation de mandataire sortant"
|
||||
msgstr "Autorisation de proxy requise"
|
||||
|
||||
#: ../java/build/Proxy.java:83
|
||||
msgid "I2P HTTP Proxy Authorization Required"
|
||||
msgstr "Autorisation de mandataire sortant"
|
||||
msgstr "Autorisation de proxy HTTP I2P requise"
|
||||
|
||||
#: ../java/build/Proxy.java:84
|
||||
msgid "This proxy is configured to require a username and password for access."
|
||||
msgstr ""
|
||||
"Ce proxy est configuré pour exiger un nom d'utilisateur et un mot de passe "
|
||||
"pour y accéder."
|
||||
|
||||
#: ../java/build/Proxy.java:85
|
||||
#, java-format
|
||||
@ -259,6 +295,8 @@ msgid ""
|
||||
"Please enter your username and password, or check your {0}router "
|
||||
"configuration{1} or {2}I2PTunnel configuration{3}."
|
||||
msgstr ""
|
||||
"Veuillez saisir votre nom d''utilisateur et mot de passe, ou vérifier votre "
|
||||
"{0}configuration de routeur{1} ou {2}configuration de I2PTunnel{3}."
|
||||
|
||||
#: ../java/build/Proxy.java:86
|
||||
#, java-format
|
||||
@ -266,93 +304,115 @@ msgid ""
|
||||
"To disable authorization, remove the configuration {0}i2ptunnel.proxy."
|
||||
"auth=basic{1}, then stop and restart the HTTP Proxy tunnel."
|
||||
msgstr ""
|
||||
"Pour désactiver l''autorisation, supprimer la configuration {0}i2ptunnel."
|
||||
"proxy.auth=basic{1}, puis arrêtez et redémarrez le tunnel du proxy HTTP."
|
||||
|
||||
#: ../java/build/Proxy.java:87 ../java/build/Proxy.java:93
|
||||
msgid "Warning: Eepsite Unreachable"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : Eepsite inaccessible"
|
||||
|
||||
#: ../java/build/Proxy.java:94
|
||||
msgid "The eepsite was not reachable."
|
||||
msgstr ""
|
||||
msgstr "Le eepsite n'était pas joignable."
|
||||
|
||||
#: ../java/build/Proxy.java:95
|
||||
msgid ""
|
||||
"The eepsite is offline, there is network congestion, or your router is not "
|
||||
"yet well-integrated with peers."
|
||||
msgstr ""
|
||||
"Le eepsite est hors ligne, ou il y a congestion du réseau, ou votre routeur "
|
||||
"n'est pas encore bien intégré avec les pairs."
|
||||
|
||||
#: ../java/build/Proxy.java:98
|
||||
msgid "Information: New Host Name"
|
||||
msgstr ""
|
||||
msgstr "Information : nouveau nom d'hôte"
|
||||
|
||||
#: ../java/build/Proxy.java:104
|
||||
msgid "Information: New Host Name with Address Helper"
|
||||
msgstr ""
|
||||
msgstr "Information : nouveau nom d'hôte avec assistant d'adresse"
|
||||
|
||||
#: ../java/build/Proxy.java:105
|
||||
msgid ""
|
||||
"The address helper link you followed is for a new host name that is not in "
|
||||
"your address book."
|
||||
msgstr ""
|
||||
"Le lien d'assistant d'adresse que vous avez suivi est pour un nouveau nom "
|
||||
"d'hôte qui n'est pas dans votre carnet d'adresses."
|
||||
|
||||
#: ../java/build/Proxy.java:106
|
||||
msgid "You may save this host name to your local address book."
|
||||
msgstr ""
|
||||
"Il vous est possible d'enregistrer ce nom d'hôte à votre carnet d'adresses "
|
||||
"local."
|
||||
|
||||
#: ../java/build/Proxy.java:107
|
||||
msgid ""
|
||||
"If you save it to your address book, you will not see this message again."
|
||||
msgstr ""
|
||||
"Si vous l'enregistrez dans votre carnet d'adresses, vous ne verrez plus ce "
|
||||
"message."
|
||||
|
||||
#: ../java/build/Proxy.java:108
|
||||
msgid ""
|
||||
"If you do not save it, the host name will be forgotten after the next router "
|
||||
"restart."
|
||||
msgstr ""
|
||||
"Si vous n'enregistrez pas, le nom d'hôte sera oublié après le prochain "
|
||||
"redémarrage du routeur."
|
||||
|
||||
#: ../java/build/Proxy.java:109
|
||||
msgid ""
|
||||
"If you do not wish to visit this host, click the \"back\" button on your "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Si vous ne souhaitez pas visiter cet hôte, cliquez sur le bouton \"précédent"
|
||||
"\" de votre navigateur."
|
||||
|
||||
#: ../java/build/Proxy.java:110 ../java/build/Proxy.java:116
|
||||
msgid "Warning: Bad Address Helper"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : mauvais assistant d'adresse"
|
||||
|
||||
#: ../java/build/Proxy.java:117
|
||||
#, java-format
|
||||
msgid "The helper key in the URL ({0}i2paddresshelper={1}) is not resolvable."
|
||||
msgstr ""
|
||||
"La clé auxiliaire dans l''URL ({0}i2paddresshelper={1}) n''est pas résoluble."
|
||||
|
||||
#: ../java/build/Proxy.java:118
|
||||
msgid "It seems to be garbage data, or a mistyped Base 32 address."
|
||||
msgstr ""
|
||||
"Il semble y avoir des données incorrectes, ou une faute de frappe dans "
|
||||
"l'adresse Base 32."
|
||||
|
||||
#: ../java/build/Proxy.java:119
|
||||
msgid ""
|
||||
"Check your URL to try and fix the helper key to be a valid Base 32 hostname "
|
||||
"or Base 64 key."
|
||||
msgstr ""
|
||||
"Vérifiez votre URL afin d'essayer de résoudre la clé d'assistance pour "
|
||||
"qu'elle soit un nom d'hôte Base 32 valide ou clé Base 64."
|
||||
|
||||
#: ../java/build/Proxy.java:120 ../java/build/Proxy.java:126
|
||||
msgid "Warning: Non-HTTP Protocol"
|
||||
msgstr ""
|
||||
msgstr "Avertissement : protocole non HTTP"
|
||||
|
||||
#: ../java/build/Proxy.java:127
|
||||
msgid "The request uses a bad protocol."
|
||||
msgstr ""
|
||||
msgstr "La requête utilise un mauvais protocole."
|
||||
|
||||
#: ../java/build/Proxy.java:128
|
||||
#, java-format
|
||||
msgid "The I2P HTTP Proxy supports {0}http://{1} requests ONLY."
|
||||
msgstr ""
|
||||
"Le proxy HTTP I2P prend en charge les demandes {0}http://{1} uniquement."
|
||||
|
||||
#: ../java/build/Proxy.java:129
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Other protocols such as {0}https://{1} and {0}ftp://{1} are not allowed."
|
||||
msgstr ""
|
||||
"D''autres protocoles tels que {0}https://{1} et {0}ftp://{1} ne sont pas "
|
||||
"autorisés."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:572
|
||||
msgid "This seems to be a bad destination:"
|
||||
@ -361,7 +421,8 @@ msgstr "Cela semble être une mauvaise destination"
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:572
|
||||
msgid "i2paddresshelper cannot help you with a destination like that!"
|
||||
msgstr ""
|
||||
"i2paddresshelper ne peut pas vous aider avec une destination comme cela !"
|
||||
"L'assistant d'adresse ne peut pas vous aider avec une destination comme "
|
||||
"cela !"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:639
|
||||
#, java-format
|
||||
@ -371,8 +432,8 @@ msgid ""
|
||||
"\"{1}\">here</a>."
|
||||
msgstr ""
|
||||
"Pour aller à la destination de votre base de données d''hôtes, cliquez <a "
|
||||
"href=\"{0}\">here</a>. Pour aller à la destination de l''aide d''adresse en "
|
||||
"conflit, cliquez <a href=\"{1}\">ici</a>."
|
||||
"href=\"{0}\">içi</a>. Pour aller à la destination de l''assistant d''adresse "
|
||||
"en conflit, cliquez <a href=\"{1}\">içi</a>."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1043
|
||||
msgid "Host"
|
||||
|
@ -4,20 +4,18 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# sfix <anon-9b36b2e@lycos.com>, 2013
|
||||
# Андрей Лукьяненко <operru32@yandex.ru>, 2013
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# foo <foo@bar>, 2009
|
||||
# gmind <grvmind@gmail.com>, 2012-2013
|
||||
# gmind <grvmind@gmail.com>, 2013
|
||||
# gmind <grvmind@gmail.com>, 2012
|
||||
# gmind, 2012-2013
|
||||
# sfix <anon-9b36b2e@lycos.com>, 2013
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2ptunnel\n"
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-08-11 14:28+0000\n"
|
||||
"PO-Revision-Date: 2013-07-05 08:09+0000\n"
|
||||
"Last-Translator: Roman Azarenko <x12ozmouse@ya.ru>\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:17+0000\n"
|
||||
"PO-Revision-Date: 2013-09-14 22:04+0000\n"
|
||||
"Last-Translator: Андрей Лукьяненко <operru32@yandex.ru>\n"
|
||||
"Language-Team: Russian (Russia) (http://www.transifex.com/projects/p/I2P/"
|
||||
"language/ru_RU/)\n"
|
||||
"Language: ru_RU\n"
|
||||
@ -29,7 +27,7 @@ msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:5 ../java/build/Proxy.java:11
|
||||
msgid "Warning: Outproxy Not Found"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Выходной прокси-сервер недоступен"
|
||||
|
||||
#: ../java/build/Proxy.java:6 ../java/build/Proxy.java:18
|
||||
#: ../java/build/Proxy.java:27 ../java/build/Proxy.java:40
|
||||
@ -89,6 +87,8 @@ msgid ""
|
||||
"It is offline, there is network congestion, or your router is not yet well-"
|
||||
"integrated with peers."
|
||||
msgstr ""
|
||||
"Возможно, он отключен, сеть перегружена или ваш маршрутизатор недостаточно "
|
||||
"интегрирован с другими узлами."
|
||||
|
||||
#: ../java/build/Proxy.java:14
|
||||
#, java-format
|
||||
@ -96,6 +96,9 @@ msgid ""
|
||||
"You may want to {0}retry{1} as this will randomly reselect an outproxy from "
|
||||
"the pool you have defined {2}here{3} (if you have more than one configured)."
|
||||
msgstr ""
|
||||
"Вы можете {0}повторить{1} операцию (это случайным образом выберет прокси-"
|
||||
"сервер из определенного {2}здесь{3} списка, если вы настроили более одного "
|
||||
"прокси-сервера)."
|
||||
|
||||
#: ../java/build/Proxy.java:15
|
||||
#, java-format
|
||||
@ -103,6 +106,8 @@ msgid ""
|
||||
"If you continue to have trouble you may want to edit your outproxy list {0}"
|
||||
"here{1}."
|
||||
msgstr ""
|
||||
"Если проблема продолжит появляться, вы можете изменить список прокси-"
|
||||
"серверов {0}здесь{1}."
|
||||
|
||||
#: ../java/build/Proxy.java:16 ../java/build/Proxy.java:38
|
||||
#: ../java/build/Proxy.java:59 ../java/build/Proxy.java:97
|
||||
@ -111,11 +116,11 @@ msgstr "Назначение туннеля"
|
||||
|
||||
#: ../java/build/Proxy.java:17
|
||||
msgid "Error: Request Denied"
|
||||
msgstr ""
|
||||
msgstr "Ошибка: Отказ в выполнении запроса"
|
||||
|
||||
#: ../java/build/Proxy.java:23
|
||||
msgid "Error: Local Access"
|
||||
msgstr ""
|
||||
msgstr "Ошибка: Локальный адрес"
|
||||
|
||||
#: ../java/build/Proxy.java:24
|
||||
msgid "Your browser is misconfigured."
|
||||
@ -126,33 +131,37 @@ msgid ""
|
||||
"Do not use the proxy to access the router console, localhost, or local LAN "
|
||||
"destinations."
|
||||
msgstr ""
|
||||
"Не используйте прокси-сервер для доступа к консоли маршрутизатора, "
|
||||
"локальному компьютеру или локальной сети."
|
||||
|
||||
#: ../java/build/Proxy.java:26
|
||||
msgid "Warning: Eepsite Unknown"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Неизвестный сайт I2P"
|
||||
|
||||
#: ../java/build/Proxy.java:32
|
||||
msgid "Warning: Eepsite Not Found in Addressbook"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Сайт I2P не найден в адресной книге"
|
||||
|
||||
#: ../java/build/Proxy.java:33
|
||||
msgid "The eepsite was not found in your router's addressbook."
|
||||
msgstr ""
|
||||
msgstr "Сайт I2P не найден в адресной книге вашего маршрутизатора."
|
||||
|
||||
#: ../java/build/Proxy.java:34
|
||||
msgid "Check the link or find a Base 32 or Base 64 address."
|
||||
msgstr ""
|
||||
msgstr "Проверьте ссылку или найдите адрес Base32 или Base64."
|
||||
|
||||
#: ../java/build/Proxy.java:35
|
||||
#, java-format
|
||||
msgid "If you have the Base 64 address, {0}add it to your addressbook{1}."
|
||||
msgstr ""
|
||||
msgstr "Если у вас есть адрес Base64, {0}добавьте его в адресную книгу{1}."
|
||||
|
||||
#: ../java/build/Proxy.java:36
|
||||
msgid ""
|
||||
"Otherwise, find a Base 32 or address helper link, or use a jump service link "
|
||||
"below."
|
||||
msgstr ""
|
||||
"В противном случае найдите ссылку Base32 или AddressHelper или используйте "
|
||||
"Jump-службу."
|
||||
|
||||
#: ../java/build/Proxy.java:37
|
||||
#, java-format
|
||||
@ -160,20 +169,24 @@ msgid ""
|
||||
"Seeing this page often? See {0}the FAQ{1} for help in {2}adding some "
|
||||
"subscriptions{3} to your addressbook."
|
||||
msgstr ""
|
||||
"Если вы слишком часто попадаете на эту страницу, то обратитесь к {0}FAQ{1} "
|
||||
"за инструкциями по {2}добавлению подписок{3} адресной книги."
|
||||
|
||||
#: ../java/build/Proxy.java:39 ../java/build/Proxy.java:45
|
||||
msgid "Warning: Invalid Request URI"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Некорректный URI запроса"
|
||||
|
||||
#: ../java/build/Proxy.java:46
|
||||
msgid "The request URI is invalid, and probably contains illegal characters."
|
||||
msgstr ""
|
||||
msgstr "Некорректный URI запроса. Возможно, он содержит недопустимые символы."
|
||||
|
||||
#: ../java/build/Proxy.java:47
|
||||
msgid ""
|
||||
"If you clicked a link, check the end of the URI for any characters the "
|
||||
"browser has mistakenly added on."
|
||||
msgstr ""
|
||||
"Если вы прошли по ссылке, проверьте конец URI на наличие символов, ошибочно "
|
||||
"добавленных браузером."
|
||||
|
||||
#: ../java/build/Proxy.java:48 ../java/build/Proxy.java:54
|
||||
msgid "Warning: Invalid Destination"
|
||||
@ -183,60 +196,68 @@ msgstr "Локальный адрес назначения"
|
||||
msgid ""
|
||||
"The eepsite destination specified was not valid, or was otherwise "
|
||||
"unreachable."
|
||||
msgstr ""
|
||||
msgstr "Указанный адрес недействителен или недоступен."
|
||||
|
||||
#: ../java/build/Proxy.java:56
|
||||
msgid ""
|
||||
"Perhaps you pasted in the wrong Base 64 string or the link you are following "
|
||||
"is bad."
|
||||
msgstr ""
|
||||
"Возможно, вы вставили неправильную строку Base64 или прошли по нерабочей "
|
||||
"ссылке."
|
||||
|
||||
#: ../java/build/Proxy.java:57
|
||||
msgid "The I2P host could also be offline."
|
||||
msgstr ""
|
||||
msgstr "Сайт I2P также может быть отключен."
|
||||
|
||||
#: ../java/build/Proxy.java:58 ../java/build/Proxy.java:96
|
||||
#, java-format
|
||||
msgid "You may want to {0}retry{1}."
|
||||
msgstr ""
|
||||
msgstr "Вы можете {0}повторить{1} операцию."
|
||||
|
||||
#: ../java/build/Proxy.java:60 ../java/build/Proxy.java:66
|
||||
msgid "Warning: Request Denied"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Отказ в выполнении запроса"
|
||||
|
||||
#: ../java/build/Proxy.java:67
|
||||
msgid "You attempted to connect to a non-I2P website or location."
|
||||
msgstr ""
|
||||
msgstr "Вы попытались соединиться с сайтом не в сети I2P."
|
||||
|
||||
#: ../java/build/Proxy.java:68 ../java/build/Proxy.java:74
|
||||
msgid "Warning: No Outproxy Configured"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Выходной прокси-сервер не настроен"
|
||||
|
||||
#: ../java/build/Proxy.java:75
|
||||
msgid ""
|
||||
"Your request was for a site outside of I2P, but you have no HTTP outproxy "
|
||||
"configured."
|
||||
msgstr ""
|
||||
"Вы запросили страницу вне сети I2P, но не имеете настроенного выходного "
|
||||
"прокси-сервера."
|
||||
|
||||
#: ../java/build/Proxy.java:76
|
||||
msgid "Please configure an outproxy in I2PTunnel."
|
||||
msgstr ""
|
||||
msgstr "Пожалуйста, настройте выходной прокси-сервер в I2PTunnel."
|
||||
|
||||
#: ../java/build/Proxy.java:77 ../java/build/Proxy.java:78
|
||||
msgid "Warning: Destination Key Conflict"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Конфликт ключа назначения"
|
||||
|
||||
#: ../java/build/Proxy.java:79
|
||||
msgid ""
|
||||
"The addresshelper link you followed specifies a different destination key "
|
||||
"than a host entry in your host database."
|
||||
msgstr ""
|
||||
"Ссылка AddressHelper, по которой вы прошли, определяет ключ назначения, "
|
||||
"отличный от указанного в адресной книге."
|
||||
|
||||
#: ../java/build/Proxy.java:80
|
||||
msgid ""
|
||||
"Someone could be trying to impersonate another eepsite, or people have given "
|
||||
"two eepsites identical names."
|
||||
msgstr ""
|
||||
"Кто-то может пытаться выдать себя за другой сайт или разные люди дали двум "
|
||||
"сайтам одинаковые имена."
|
||||
|
||||
#: ../java/build/Proxy.java:81
|
||||
msgid ""
|
||||
@ -244,6 +265,9 @@ msgid ""
|
||||
"discarding the addresshelper link, discarding the host entry from your host "
|
||||
"database, or naming one of them differently."
|
||||
msgstr ""
|
||||
"Для разрешения конфликта вы можете определить, какому ключу вы доверяете, и "
|
||||
"либо отказаться от прохода по ссылке, либо удалить старый ключ, либо "
|
||||
"присвоить одному из них другое имя."
|
||||
|
||||
#: ../java/build/Proxy.java:82
|
||||
msgid "Proxy Authorization Required"
|
||||
@ -255,7 +279,7 @@ msgstr "Авторизация outproxy"
|
||||
|
||||
#: ../java/build/Proxy.java:84
|
||||
msgid "This proxy is configured to require a username and password for access."
|
||||
msgstr ""
|
||||
msgstr "Этот прокси-сервер требует имя пользователя и пароль для доступа."
|
||||
|
||||
#: ../java/build/Proxy.java:85
|
||||
#, java-format
|
||||
@ -263,6 +287,8 @@ msgid ""
|
||||
"Please enter your username and password, or check your {0}router "
|
||||
"configuration{1} or {2}I2PTunnel configuration{3}."
|
||||
msgstr ""
|
||||
"Введите имя и пароль или проверьте ваши {0}настройки маршрутизатора{1} и {2}"
|
||||
"настройки I2PTunnel{3}."
|
||||
|
||||
#: ../java/build/Proxy.java:86
|
||||
#, java-format
|
||||
@ -270,93 +296,106 @@ msgid ""
|
||||
"To disable authorization, remove the configuration {0}i2ptunnel.proxy."
|
||||
"auth=basic{1}, then stop and restart the HTTP Proxy tunnel."
|
||||
msgstr ""
|
||||
"Для отключения авторизации удалите строку {0}i2ptunnel.proxy.auth=basic{1} и "
|
||||
"перезапустите туннель HTTP Proxy."
|
||||
|
||||
#: ../java/build/Proxy.java:87 ../java/build/Proxy.java:93
|
||||
msgid "Warning: Eepsite Unreachable"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Сайт I2P недоступен"
|
||||
|
||||
#: ../java/build/Proxy.java:94
|
||||
msgid "The eepsite was not reachable."
|
||||
msgstr ""
|
||||
msgstr "Сайт I2P недоступен."
|
||||
|
||||
#: ../java/build/Proxy.java:95
|
||||
msgid ""
|
||||
"The eepsite is offline, there is network congestion, or your router is not "
|
||||
"yet well-integrated with peers."
|
||||
msgstr ""
|
||||
"Возможно, он отключен, сеть перегружена или ваш маршрутизатор недостаточно "
|
||||
"интегрирован с другими узлами."
|
||||
|
||||
#: ../java/build/Proxy.java:98
|
||||
msgid "Information: New Host Name"
|
||||
msgstr ""
|
||||
msgstr "Информация: Новый доменной адрес"
|
||||
|
||||
#: ../java/build/Proxy.java:104
|
||||
msgid "Information: New Host Name with Address Helper"
|
||||
msgstr ""
|
||||
msgstr "Информация: Новый доменной адрес с AddressHelper"
|
||||
|
||||
#: ../java/build/Proxy.java:105
|
||||
msgid ""
|
||||
"The address helper link you followed is for a new host name that is not in "
|
||||
"your address book."
|
||||
msgstr ""
|
||||
"Ссылка AddressHelper, по которой вы прошли, ведет на домен, не внесенный в "
|
||||
"адресную книгу."
|
||||
|
||||
#: ../java/build/Proxy.java:106
|
||||
msgid "You may save this host name to your local address book."
|
||||
msgstr ""
|
||||
msgstr "Вы можете сохранить этот домен в свою локальную адресную книгу."
|
||||
|
||||
#: ../java/build/Proxy.java:107
|
||||
msgid ""
|
||||
"If you save it to your address book, you will not see this message again."
|
||||
msgstr ""
|
||||
"Если вы сохраните его в вашей адресной книге, вы больше не будете видеть это "
|
||||
"сообщение."
|
||||
|
||||
#: ../java/build/Proxy.java:108
|
||||
msgid ""
|
||||
"If you do not save it, the host name will be forgotten after the next router "
|
||||
"restart."
|
||||
msgstr ""
|
||||
"Если вы не сохраните его, он будет «забыт» после перезапуска маршрутизатора."
|
||||
|
||||
#: ../java/build/Proxy.java:109
|
||||
msgid ""
|
||||
"If you do not wish to visit this host, click the \"back\" button on your "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Если вы не хотите посещать этот сайт, нажмите кнопку «Назад» в браузере."
|
||||
|
||||
#: ../java/build/Proxy.java:110 ../java/build/Proxy.java:116
|
||||
msgid "Warning: Bad Address Helper"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Некорректный AddressHelper"
|
||||
|
||||
#: ../java/build/Proxy.java:117
|
||||
#, java-format
|
||||
msgid "The helper key in the URL ({0}i2paddresshelper={1}) is not resolvable."
|
||||
msgstr ""
|
||||
msgstr "Не удается разобрать ключ AddressHelper ({0}i2paddresshelper={1})."
|
||||
|
||||
#: ../java/build/Proxy.java:118
|
||||
msgid "It seems to be garbage data, or a mistyped Base 32 address."
|
||||
msgstr ""
|
||||
msgstr "Возможно, он содержит ненужные данные или опечатку в адресе Base32."
|
||||
|
||||
#: ../java/build/Proxy.java:119
|
||||
msgid ""
|
||||
"Check your URL to try and fix the helper key to be a valid Base 32 hostname "
|
||||
"or Base 64 key."
|
||||
msgstr ""
|
||||
"Проверьте URL и попробуйте исправить ссылку с использованием корректной "
|
||||
"ссылки Base32 или Base64."
|
||||
|
||||
#: ../java/build/Proxy.java:120 ../java/build/Proxy.java:126
|
||||
msgid "Warning: Non-HTTP Protocol"
|
||||
msgstr ""
|
||||
msgstr "Предупреждение: Протокол не HTTP"
|
||||
|
||||
#: ../java/build/Proxy.java:127
|
||||
msgid "The request uses a bad protocol."
|
||||
msgstr ""
|
||||
msgstr "Запрос отправлен через неподдерживанмый протокол."
|
||||
|
||||
#: ../java/build/Proxy.java:128
|
||||
#, java-format
|
||||
msgid "The I2P HTTP Proxy supports {0}http://{1} requests ONLY."
|
||||
msgstr ""
|
||||
msgstr "HTTP-прокси I2P поддерживает ТОЛЬКО протокол {0}http://{1}."
|
||||
|
||||
#: ../java/build/Proxy.java:129
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Other protocols such as {0}https://{1} and {0}ftp://{1} are not allowed."
|
||||
msgstr ""
|
||||
"Другие протоколы, такие как {0}https://{1} и {0}ftp://{1} не поддерживаются."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:572
|
||||
msgid "This seems to be a bad destination:"
|
||||
|
@ -4,15 +4,14 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# <i2p@robertfoss.se>, 2013.
|
||||
# <i2p@robertfoss.se>, 2012.
|
||||
# Martin Svensson <digitalmannen@gmail.com>, 2011-2012.
|
||||
# hottuna <i2p@robertfoss.se>, 2013
|
||||
# hottuna <i2p@robertfoss.se>, 2012
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P i2ptunnel\n"
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-07-13 18:50+0000\n"
|
||||
"PO-Revision-Date: 2013-01-19 16:53+0000\n"
|
||||
"POT-Creation-Date: 2013-09-26 21:42+0000\n"
|
||||
"PO-Revision-Date: 2013-09-26 06:34+0000\n"
|
||||
"Last-Translator: hottuna <i2p@robertfoss.se>\n"
|
||||
"Language-Team: Swedish (Sweden) (http://www.transifex.com/projects/p/I2P/"
|
||||
"language/sv_SE/)\n"
|
||||
@ -22,336 +21,382 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../java/build/Proxy.java:5
|
||||
msgid "Proxy Authorization Required"
|
||||
msgstr "Tillstånd för utproxy"
|
||||
#: ../java/build/Proxy.java:5 ../java/build/Proxy.java:11
|
||||
msgid "Warning: Outproxy Not Found"
|
||||
msgstr "Varning: Utproxy Ej Hittad"
|
||||
|
||||
#: ../java/build/Proxy.java:6
|
||||
msgid "I2P HTTP Proxy Authorization Required"
|
||||
msgstr "Tillstånd för utproxy"
|
||||
|
||||
#: ../java/build/Proxy.java:7
|
||||
msgid "This proxy is configured to require a username and password for access."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:8
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Please enter your username and password, or check your {0}router "
|
||||
"configuration{1} or {2}I2PTunnel configuration{3}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:9
|
||||
#, java-format
|
||||
msgid ""
|
||||
"To disable authorization, remove the configuration {0}i2ptunnel.proxy."
|
||||
"auth=basic{1}, then stop and restart the HTTP Proxy tunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:10 ../java/build/Proxy.java:16
|
||||
msgid "Warning: No Outproxy Configured"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:11 ../java/build/Proxy.java:20
|
||||
#: ../java/build/Proxy.java:32 ../java/build/Proxy.java:44
|
||||
#: ../java/build/Proxy.java:52 ../java/build/Proxy.java:61
|
||||
#: ../java/build/Proxy.java:74 ../java/build/Proxy.java:83
|
||||
#: ../java/build/Proxy.java:93 ../java/build/Proxy.java:103
|
||||
#: ../java/build/Proxy.java:115
|
||||
#: ../java/build/Proxy.java:6 ../java/build/Proxy.java:18
|
||||
#: ../java/build/Proxy.java:27 ../java/build/Proxy.java:40
|
||||
#: ../java/build/Proxy.java:49 ../java/build/Proxy.java:61
|
||||
#: ../java/build/Proxy.java:69 ../java/build/Proxy.java:88
|
||||
#: ../java/build/Proxy.java:99 ../java/build/Proxy.java:111
|
||||
#: ../java/build/Proxy.java:121
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:196
|
||||
msgid "Router Console"
|
||||
msgstr "Router konsol "
|
||||
msgstr "Routerkonsol"
|
||||
|
||||
#: ../java/build/Proxy.java:12 ../java/build/Proxy.java:21
|
||||
#: ../java/build/Proxy.java:33 ../java/build/Proxy.java:45
|
||||
#: ../java/build/Proxy.java:53 ../java/build/Proxy.java:62
|
||||
#: ../java/build/Proxy.java:75 ../java/build/Proxy.java:84
|
||||
#: ../java/build/Proxy.java:94 ../java/build/Proxy.java:104
|
||||
#: ../java/build/Proxy.java:116
|
||||
#: ../java/build/Proxy.java:7 ../java/build/Proxy.java:19
|
||||
#: ../java/build/Proxy.java:28 ../java/build/Proxy.java:41
|
||||
#: ../java/build/Proxy.java:50 ../java/build/Proxy.java:62
|
||||
#: ../java/build/Proxy.java:70 ../java/build/Proxy.java:89
|
||||
#: ../java/build/Proxy.java:100 ../java/build/Proxy.java:112
|
||||
#: ../java/build/Proxy.java:122
|
||||
msgid "I2P Router Console"
|
||||
msgstr "Router konsol "
|
||||
msgstr "Routerkonsol"
|
||||
|
||||
#: ../java/build/Proxy.java:13 ../java/build/Proxy.java:22
|
||||
#: ../java/build/Proxy.java:34 ../java/build/Proxy.java:46
|
||||
#: ../java/build/Proxy.java:54 ../java/build/Proxy.java:63
|
||||
#: ../java/build/Proxy.java:76 ../java/build/Proxy.java:85
|
||||
#: ../java/build/Proxy.java:95 ../java/build/Proxy.java:105
|
||||
#: ../java/build/Proxy.java:117
|
||||
#: ../java/build/Proxy.java:8 ../java/build/Proxy.java:20
|
||||
#: ../java/build/Proxy.java:29 ../java/build/Proxy.java:42
|
||||
#: ../java/build/Proxy.java:51 ../java/build/Proxy.java:63
|
||||
#: ../java/build/Proxy.java:71 ../java/build/Proxy.java:90
|
||||
#: ../java/build/Proxy.java:101 ../java/build/Proxy.java:113
|
||||
#: ../java/build/Proxy.java:123
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:197
|
||||
msgid "Configuration"
|
||||
msgstr "Konfiguration"
|
||||
|
||||
#: ../java/build/Proxy.java:14 ../java/build/Proxy.java:23
|
||||
#: ../java/build/Proxy.java:35 ../java/build/Proxy.java:47
|
||||
#: ../java/build/Proxy.java:55 ../java/build/Proxy.java:64
|
||||
#: ../java/build/Proxy.java:77 ../java/build/Proxy.java:86
|
||||
#: ../java/build/Proxy.java:96 ../java/build/Proxy.java:106
|
||||
#: ../java/build/Proxy.java:118
|
||||
#: ../java/build/Proxy.java:9 ../java/build/Proxy.java:21
|
||||
#: ../java/build/Proxy.java:30 ../java/build/Proxy.java:43
|
||||
#: ../java/build/Proxy.java:52 ../java/build/Proxy.java:64
|
||||
#: ../java/build/Proxy.java:72 ../java/build/Proxy.java:91
|
||||
#: ../java/build/Proxy.java:102 ../java/build/Proxy.java:114
|
||||
#: ../java/build/Proxy.java:124
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:197
|
||||
msgid "Help"
|
||||
msgstr "Hjälp"
|
||||
|
||||
#: ../java/build/Proxy.java:15 ../java/build/Proxy.java:24
|
||||
#: ../java/build/Proxy.java:36 ../java/build/Proxy.java:48
|
||||
#: ../java/build/Proxy.java:56 ../java/build/Proxy.java:65
|
||||
#: ../java/build/Proxy.java:78 ../java/build/Proxy.java:87
|
||||
#: ../java/build/Proxy.java:97 ../java/build/Proxy.java:107
|
||||
#: ../java/build/Proxy.java:119
|
||||
#: ../java/build/Proxy.java:10 ../java/build/Proxy.java:22
|
||||
#: ../java/build/Proxy.java:31 ../java/build/Proxy.java:44
|
||||
#: ../java/build/Proxy.java:53 ../java/build/Proxy.java:65
|
||||
#: ../java/build/Proxy.java:73 ../java/build/Proxy.java:92
|
||||
#: ../java/build/Proxy.java:103 ../java/build/Proxy.java:115
|
||||
#: ../java/build/Proxy.java:125
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:197
|
||||
msgid "Addressbook"
|
||||
msgstr "Adressbok"
|
||||
|
||||
#: ../java/build/Proxy.java:17
|
||||
msgid ""
|
||||
"Your request was for a site outside of I2P, but you have no HTTP outproxy "
|
||||
"configured."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:18
|
||||
msgid "Please configure an outproxy in I2PTunnel."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:19
|
||||
msgid "Information: New Host Name"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:25
|
||||
msgid "Information: New Host Name with Address Helper"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:26
|
||||
msgid ""
|
||||
"The address helper link you followed is for a new host name that is not in "
|
||||
"your address book."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:27
|
||||
msgid "You may save this host name to your local address book."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:28
|
||||
msgid ""
|
||||
"If you save it to your address book, you will not see this message again."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:29
|
||||
msgid ""
|
||||
"If you do not save it, the host name will be forgotten after the next router "
|
||||
"restart."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:30
|
||||
msgid ""
|
||||
"If you do not wish to visit this host, click the \"back\" button on your "
|
||||
"browser."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:31 ../java/build/Proxy.java:37
|
||||
msgid "Warning: Invalid Destination"
|
||||
msgstr "Lokalt mål"
|
||||
|
||||
#: ../java/build/Proxy.java:38
|
||||
msgid ""
|
||||
"The eepsite destination specified was not valid, or was otherwise "
|
||||
"unreachable."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:39
|
||||
msgid ""
|
||||
"Perhaps you pasted in the wrong Base 64 string or the link you are following "
|
||||
"is bad."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:40
|
||||
msgid "The I2P host could also be offline."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:41 ../java/build/Proxy.java:123
|
||||
#, java-format
|
||||
msgid "You may want to {0}retry{1}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:42 ../java/build/Proxy.java:72
|
||||
#: ../java/build/Proxy.java:113 ../java/build/Proxy.java:124
|
||||
msgid "Could not find the following destination:"
|
||||
msgstr "Mål för tunnel"
|
||||
|
||||
#: ../java/build/Proxy.java:43 ../java/build/Proxy.java:49
|
||||
msgid "Warning: Request Denied"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:50
|
||||
msgid "You attempted to connect to a non-I2P website or location."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:51 ../java/build/Proxy.java:57
|
||||
msgid "Warning: Invalid Request URI"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:58
|
||||
msgid "The request URI is invalid, and probably contains illegal characters."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:59
|
||||
msgid ""
|
||||
"If you clicked a link, check the end of the URI for any characters the "
|
||||
"browser has mistakenly added on."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:60
|
||||
msgid "Warning: Eepsite Unknown"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:66
|
||||
msgid "Warning: Eepsite Not Found in Addressbook"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:67
|
||||
msgid "The eepsite was not found in your router's addressbook."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:68
|
||||
msgid "Check the link or find a Base 32 or Base 64 address."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:69
|
||||
#, java-format
|
||||
msgid "If you have the Base 64 address, {0}add it to your addressbook{1}."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:70
|
||||
msgid ""
|
||||
"Otherwise, find a Base 32 or address helper link, or use a jump service link "
|
||||
"below."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:71
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Seeing this page often? See {0}the FAQ{1} for help in {2}adding some "
|
||||
"subscriptions{3} to your addressbook."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:73
|
||||
msgid "Error: Request Denied"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:79
|
||||
msgid "Error: Local Access"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:80
|
||||
msgid "Your browser is misconfigured."
|
||||
msgstr "Din webbläsare stödjer inte iFrames."
|
||||
|
||||
#: ../java/build/Proxy.java:81
|
||||
msgid ""
|
||||
"Do not use the proxy to access the router console, localhost, or local LAN "
|
||||
"destinations."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:82 ../java/build/Proxy.java:88
|
||||
msgid "Warning: Non-HTTP Protocol"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:89
|
||||
msgid "The request uses a bad protocol."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:90
|
||||
#, java-format
|
||||
msgid "The I2P HTTP Proxy supports {0}http://{1} requests ONLY."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:91
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Other protocols such as {0}https://{1} and {0}ftp://{1} are not allowed."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:92 ../java/build/Proxy.java:98
|
||||
msgid "Warning: Bad Address Helper"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:99
|
||||
#, java-format
|
||||
msgid "The helper key in the URL ({0}i2paddresshelper={1}) is not resolvable."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:100
|
||||
msgid "It seems to be garbage data, or a mistyped Base 32 address."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:101
|
||||
msgid ""
|
||||
"Check your URL to try and fix the helper key to be a valid Base 32 hostname "
|
||||
"or Base 64 key."
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:102 ../java/build/Proxy.java:108
|
||||
msgid "Warning: Outproxy Not Found"
|
||||
msgstr ""
|
||||
|
||||
#: ../java/build/Proxy.java:109
|
||||
#: ../java/build/Proxy.java:12
|
||||
msgid "The HTTP Outproxy was not found."
|
||||
msgstr "HTTP proxyn är inte uppe"
|
||||
msgstr "HTTP Utproxyn hittades ej."
|
||||
|
||||
#: ../java/build/Proxy.java:110
|
||||
#: ../java/build/Proxy.java:13
|
||||
msgid ""
|
||||
"It is offline, there is network congestion, or your router is not yet well-"
|
||||
"integrated with peers."
|
||||
msgstr ""
|
||||
"Den är antingen offline, nätverket är under stor belastning eller så är din "
|
||||
"router ännu inte väl integrerad med peers."
|
||||
|
||||
#: ../java/build/Proxy.java:111
|
||||
#: ../java/build/Proxy.java:14
|
||||
#, java-format
|
||||
msgid ""
|
||||
"You may want to {0}retry{1} as this will randomly reselect an outproxy from "
|
||||
"the pool you have defined {2}here{3} (if you have more than one configured)."
|
||||
msgstr ""
|
||||
"Du kanske vill {0}försöka igen{1} eftersom en ny utproxy kommer väljas "
|
||||
"slumpmässigt utav de som är definierade {2}här{3} (om du har mer än en "
|
||||
"inställd)."
|
||||
|
||||
#: ../java/build/Proxy.java:112
|
||||
#: ../java/build/Proxy.java:15
|
||||
#, java-format
|
||||
msgid ""
|
||||
"If you continue to have trouble you may want to edit your outproxy list {0}"
|
||||
"here{1}."
|
||||
msgstr ""
|
||||
"Om du fortsätter att ha problem, så kanske du vill ändra din utproxy-liste "
|
||||
"{0}här{1}."
|
||||
|
||||
#: ../java/build/Proxy.java:114 ../java/build/Proxy.java:120
|
||||
msgid "Warning: Eepsite Unreachable"
|
||||
msgstr ""
|
||||
#: ../java/build/Proxy.java:16 ../java/build/Proxy.java:38
|
||||
#: ../java/build/Proxy.java:59 ../java/build/Proxy.java:97
|
||||
msgid "Could not find the following destination:"
|
||||
msgstr "Kunde inte hitta följande mål:"
|
||||
|
||||
#: ../java/build/Proxy.java:121
|
||||
msgid "The eepsite was not reachable."
|
||||
msgstr ""
|
||||
#: ../java/build/Proxy.java:17
|
||||
msgid "Error: Request Denied"
|
||||
msgstr "Fel: Förfrågan Nekad"
|
||||
|
||||
#: ../java/build/Proxy.java:122
|
||||
#: ../java/build/Proxy.java:23
|
||||
msgid "Error: Local Access"
|
||||
msgstr "Fel: Lokal Åtkomst"
|
||||
|
||||
#: ../java/build/Proxy.java:24
|
||||
msgid "Your browser is misconfigured."
|
||||
msgstr "Din webbläsare är felkonfigurerad."
|
||||
|
||||
#: ../java/build/Proxy.java:25
|
||||
msgid ""
|
||||
"The eepsite is offline, there is network congestion, or your router is not "
|
||||
"yet well-integrated with peers."
|
||||
"Do not use the proxy to access the router console, localhost, or local LAN "
|
||||
"destinations."
|
||||
msgstr ""
|
||||
"Använd inte proxyn för åtkomst till routerkonsolen, localhost eller lokala "
|
||||
"LAN mål."
|
||||
|
||||
#: ../java/build/Proxy.java:125 ../java/build/Proxy.java:126
|
||||
#: ../java/build/Proxy.java:26
|
||||
msgid "Warning: Eepsite Unknown"
|
||||
msgstr "Varning: Okänd Eepsite"
|
||||
|
||||
#: ../java/build/Proxy.java:32
|
||||
msgid "Warning: Eepsite Not Found in Addressbook"
|
||||
msgstr "Varning: Eepsite Finns Inte i Adressboken"
|
||||
|
||||
#: ../java/build/Proxy.java:33
|
||||
msgid "The eepsite was not found in your router's addressbook."
|
||||
msgstr "Eepsite:n hittades inte i din routers adressbok."
|
||||
|
||||
#: ../java/build/Proxy.java:34
|
||||
msgid "Check the link or find a Base 32 or Base 64 address."
|
||||
msgstr "Kontrollera länken eller hitta en Base32 eller Base64 adress."
|
||||
|
||||
#: ../java/build/Proxy.java:35
|
||||
#, java-format
|
||||
msgid "If you have the Base 64 address, {0}add it to your addressbook{1}."
|
||||
msgstr "Om du har en Base64-adress, {0}lägg till den till din adressbok{1}."
|
||||
|
||||
#: ../java/build/Proxy.java:36
|
||||
msgid ""
|
||||
"Otherwise, find a Base 32 or address helper link, or use a jump service link "
|
||||
"below."
|
||||
msgstr ""
|
||||
"Annars, hitta en Base32 eller adresshjälpar-länk eller använder en hopp-"
|
||||
"tjänst länk nedan."
|
||||
|
||||
#: ../java/build/Proxy.java:37
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Seeing this page often? See {0}the FAQ{1} for help in {2}adding some "
|
||||
"subscriptions{3} to your addressbook."
|
||||
msgstr ""
|
||||
"Ser du denhär sidan ofta? Kika i {0}FAQ:en{1} efter hjälp med att {2}lägga "
|
||||
"till några prenumerationer{3} till din adressbok."
|
||||
|
||||
#: ../java/build/Proxy.java:39 ../java/build/Proxy.java:45
|
||||
msgid "Warning: Invalid Request URI"
|
||||
msgstr "Varning: Ogiltig URI Begärd"
|
||||
|
||||
#: ../java/build/Proxy.java:46
|
||||
msgid "The request URI is invalid, and probably contains illegal characters."
|
||||
msgstr ""
|
||||
"Den begärde URI:n är ogiltig och innehåller troligtvis ogiltiga tecken."
|
||||
|
||||
#: ../java/build/Proxy.java:47
|
||||
msgid ""
|
||||
"If you clicked a link, check the end of the URI for any characters the "
|
||||
"browser has mistakenly added on."
|
||||
msgstr ""
|
||||
"Om du klicka på en länk, kontrollera slutet av URI:n efter andra tecken som "
|
||||
"webbläsaren av misstag lagt till."
|
||||
|
||||
#: ../java/build/Proxy.java:48 ../java/build/Proxy.java:54
|
||||
msgid "Warning: Invalid Destination"
|
||||
msgstr "Varning: Ogiltigt Mål"
|
||||
|
||||
#: ../java/build/Proxy.java:55
|
||||
msgid ""
|
||||
"The eepsite destination specified was not valid, or was otherwise "
|
||||
"unreachable."
|
||||
msgstr ""
|
||||
"Eepsite målet som specificerades är inte giltigt eller kan annars ej nås."
|
||||
|
||||
#: ../java/build/Proxy.java:56
|
||||
msgid ""
|
||||
"Perhaps you pasted in the wrong Base 64 string or the link you are following "
|
||||
"is bad."
|
||||
msgstr ""
|
||||
"Kanske kopierade du in fel Base64 sträng eller så är länken du följer dålig."
|
||||
|
||||
#: ../java/build/Proxy.java:57
|
||||
msgid "The I2P host could also be offline."
|
||||
msgstr "I2P-värden kan också vara offline."
|
||||
|
||||
#: ../java/build/Proxy.java:58 ../java/build/Proxy.java:96
|
||||
#, java-format
|
||||
msgid "You may want to {0}retry{1}."
|
||||
msgstr "Du kanske vill {0}försöka igen{1}."
|
||||
|
||||
#: ../java/build/Proxy.java:60 ../java/build/Proxy.java:66
|
||||
msgid "Warning: Request Denied"
|
||||
msgstr "Varning: Förfrågan Nekad"
|
||||
|
||||
#: ../java/build/Proxy.java:67
|
||||
msgid "You attempted to connect to a non-I2P website or location."
|
||||
msgstr "Du försökte ansluta till en icke-I2P webbsida eller plats."
|
||||
|
||||
#: ../java/build/Proxy.java:68 ../java/build/Proxy.java:74
|
||||
msgid "Warning: No Outproxy Configured"
|
||||
msgstr "Varning: Ingen Utproxy Inställd"
|
||||
|
||||
#: ../java/build/Proxy.java:75
|
||||
msgid ""
|
||||
"Your request was for a site outside of I2P, but you have no HTTP outproxy "
|
||||
"configured."
|
||||
msgstr ""
|
||||
"Din förfrågan var för en sida utanför I2P, men du har ingen HTTP utproxy "
|
||||
"inställd."
|
||||
|
||||
#: ../java/build/Proxy.java:76
|
||||
msgid "Please configure an outproxy in I2PTunnel."
|
||||
msgstr "Var god ställ in en utproxy i I2PTunnel."
|
||||
|
||||
#: ../java/build/Proxy.java:77 ../java/build/Proxy.java:78
|
||||
msgid "Warning: Destination Key Conflict"
|
||||
msgstr ""
|
||||
msgstr "Varning: Konflikt för Mål-nyckeln"
|
||||
|
||||
#: ../java/build/Proxy.java:127
|
||||
#: ../java/build/Proxy.java:79
|
||||
msgid ""
|
||||
"The addresshelper link you followed specifies a different destination key "
|
||||
"than a host entry in your host database."
|
||||
msgstr ""
|
||||
"Adresshjälpar-länken du följde specifierad en annan mål-nyckel än för den "
|
||||
"värd som finns i din värd-databas."
|
||||
|
||||
#: ../java/build/Proxy.java:128
|
||||
#: ../java/build/Proxy.java:80
|
||||
msgid ""
|
||||
"Someone could be trying to impersonate another eepsite, or people have given "
|
||||
"two eepsites identical names."
|
||||
msgstr ""
|
||||
"Någon kanske försöker utge sig för att vara en annan eepsite eller personer "
|
||||
"kan ha givit eepsites identiska namn."
|
||||
|
||||
#: ../java/build/Proxy.java:129
|
||||
#: ../java/build/Proxy.java:81
|
||||
msgid ""
|
||||
"You can resolve the conflict by considering which key you trust, and either "
|
||||
"discarding the addresshelper link, discarding the host entry from your host "
|
||||
"database, or naming one of them differently."
|
||||
msgstr ""
|
||||
"Du kan lösa konflikten genom att överväga vilken nyckel du litar på och "
|
||||
"antingen kasta bort adresshjälpar-länken, kasta bort värdnamnet från din "
|
||||
"värd-databas eller namnge dom olikt."
|
||||
|
||||
#: ../java/build/Proxy.java:82
|
||||
msgid "Proxy Authorization Required"
|
||||
msgstr "Proxy Tillstånd Krävs"
|
||||
|
||||
#: ../java/build/Proxy.java:83
|
||||
msgid "I2P HTTP Proxy Authorization Required"
|
||||
msgstr "I2P HTTP Proxy Tillstånd Krävs"
|
||||
|
||||
#: ../java/build/Proxy.java:84
|
||||
msgid "This proxy is configured to require a username and password for access."
|
||||
msgstr ""
|
||||
"Denhär proxy är inställd till att kräva användarnamn och lösenord för "
|
||||
"åtkomst."
|
||||
|
||||
#: ../java/build/Proxy.java:85
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Please enter your username and password, or check your {0}router "
|
||||
"configuration{1} or {2}I2PTunnel configuration{3}."
|
||||
msgstr ""
|
||||
"Var god ange ditt användarnamn och lösenord eller kontrollera din {0}router-"
|
||||
"konfiguration{1} eller {2}I2PTunnel-konfiguration{3}."
|
||||
|
||||
#: ../java/build/Proxy.java:86
|
||||
#, java-format
|
||||
msgid ""
|
||||
"To disable authorization, remove the configuration {0}i2ptunnel.proxy."
|
||||
"auth=basic{1}, then stop and restart the HTTP Proxy tunnel."
|
||||
msgstr ""
|
||||
"För att slå av autentisering, ta bort inställningen {0}i2ptunnel.proxy."
|
||||
"auth=basic{1}, stanna och starta sedan om HTTP Porxy tunneln."
|
||||
|
||||
#: ../java/build/Proxy.java:87 ../java/build/Proxy.java:93
|
||||
msgid "Warning: Eepsite Unreachable"
|
||||
msgstr "Varning: Eepsite Kan Ej Nås"
|
||||
|
||||
#: ../java/build/Proxy.java:94
|
||||
msgid "The eepsite was not reachable."
|
||||
msgstr "Eepsiten var inte nåbar."
|
||||
|
||||
#: ../java/build/Proxy.java:95
|
||||
msgid ""
|
||||
"The eepsite is offline, there is network congestion, or your router is not "
|
||||
"yet well-integrated with peers."
|
||||
msgstr ""
|
||||
"Eepsiten är offline, nätverket är uner hög belastning eller din router är "
|
||||
"ännu inte väl integrerad med peers."
|
||||
|
||||
#: ../java/build/Proxy.java:98
|
||||
msgid "Information: New Host Name"
|
||||
msgstr "Information: Nytt Värdnamn"
|
||||
|
||||
#: ../java/build/Proxy.java:104
|
||||
msgid "Information: New Host Name with Address Helper"
|
||||
msgstr "Information: Nytt Värdnamn med Adresshjälpare"
|
||||
|
||||
#: ../java/build/Proxy.java:105
|
||||
msgid ""
|
||||
"The address helper link you followed is for a new host name that is not in "
|
||||
"your address book."
|
||||
msgstr ""
|
||||
"Adressjälpar-länken du följde är för ett nytt värdnamn som inte är i din "
|
||||
"adressbok."
|
||||
|
||||
#: ../java/build/Proxy.java:106
|
||||
msgid "You may save this host name to your local address book."
|
||||
msgstr "Du kan spara detta värdnamn i din lokala adressbok."
|
||||
|
||||
#: ../java/build/Proxy.java:107
|
||||
msgid ""
|
||||
"If you save it to your address book, you will not see this message again."
|
||||
msgstr ""
|
||||
"Om du sparar det i din adressbok, så kommer du inte se dethär meddelandet "
|
||||
"igen."
|
||||
|
||||
#: ../java/build/Proxy.java:108
|
||||
msgid ""
|
||||
"If you do not save it, the host name will be forgotten after the next router "
|
||||
"restart."
|
||||
msgstr ""
|
||||
"Om du inte sparar det, så kommer värdnamnet glömmas bort efter nästa router-"
|
||||
"omstart."
|
||||
|
||||
#: ../java/build/Proxy.java:109
|
||||
msgid ""
|
||||
"If you do not wish to visit this host, click the \"back\" button on your "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Om du inte vill besöka värden, klicka på \"tillbaka\"-knappen i din "
|
||||
"webbläsare."
|
||||
|
||||
#: ../java/build/Proxy.java:110 ../java/build/Proxy.java:116
|
||||
msgid "Warning: Bad Address Helper"
|
||||
msgstr "Varning: Dålig Adresshjälpare"
|
||||
|
||||
#: ../java/build/Proxy.java:117
|
||||
#, java-format
|
||||
msgid "The helper key in the URL ({0}i2paddresshelper={1}) is not resolvable."
|
||||
msgstr ""
|
||||
"Hjälpar-nyckeln i URL:en ({0}i2paddresshelper={1}) är inte möjlig att hitta."
|
||||
|
||||
#: ../java/build/Proxy.java:118
|
||||
msgid "It seems to be garbage data, or a mistyped Base 32 address."
|
||||
msgstr "Det verkar vara skräp-data eller en felskriven Base32 adress."
|
||||
|
||||
#: ../java/build/Proxy.java:119
|
||||
msgid ""
|
||||
"Check your URL to try and fix the helper key to be a valid Base 32 hostname "
|
||||
"or Base 64 key."
|
||||
msgstr ""
|
||||
"Kontrollera din URL för att försöka fixa hjälpar-nyckeln så att den är ett "
|
||||
"giltigt Base32 värdnamn eller Base64 nyckel."
|
||||
|
||||
#: ../java/build/Proxy.java:120 ../java/build/Proxy.java:126
|
||||
msgid "Warning: Non-HTTP Protocol"
|
||||
msgstr "Varning: Ej HTTP Protokoll"
|
||||
|
||||
#: ../java/build/Proxy.java:127
|
||||
msgid "The request uses a bad protocol."
|
||||
msgstr "Förfrågan använder ett dåligt protokoll."
|
||||
|
||||
#: ../java/build/Proxy.java:128
|
||||
#, java-format
|
||||
msgid "The I2P HTTP Proxy supports {0}http://{1} requests ONLY."
|
||||
msgstr "I2P HTTP Proxyn stödjer ENBART {0}http://{1} frågor."
|
||||
|
||||
#: ../java/build/Proxy.java:129
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Other protocols such as {0}https://{1} and {0}ftp://{1} are not allowed."
|
||||
msgstr "Andra protokoll som {0}https://{1} och {0}ftp://{1} är inte tillåtna."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:572
|
||||
msgid "This seems to be a bad destination:"
|
||||
@ -409,7 +454,7 @@ msgstr "Spara {0} till privatadressbok och fortsätt till eepsite "
|
||||
msgid "HTTP Outproxy"
|
||||
msgstr "HTTP Utproxy"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1185
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1216
|
||||
msgid ""
|
||||
"Click a link below to look for an address helper by using a \"jump\" service:"
|
||||
msgstr ""
|
||||
@ -417,7 +462,7 @@ msgstr ""
|
||||
"en \"hopp\" tjänst"
|
||||
|
||||
#. Translators: parameter is a host name
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1221
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1224
|
||||
#, java-format
|
||||
msgid "{0} jump service"
|
||||
msgstr "{0} hopptjänst"
|
||||
|
@ -6,20 +6,21 @@
|
||||
# Translators:
|
||||
# blabla, 2011
|
||||
# blabla <blabla@trash-mail.com>, 2011-2012
|
||||
# D.A. Loader <>, 2012
|
||||
# D.A. Loader, 2012
|
||||
# driz <driz@i2pmail.org>, 2012
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# foo <foo@bar>, 2009
|
||||
# mixxy, 2011
|
||||
# nextloop <ga25day@mytum.de>, 2013
|
||||
# pirr <pirr@tormail.org>, 2012
|
||||
# zeroflag <zeroflag@i2pmail.org>, 2013
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-07-02 17:24+0000\n"
|
||||
"PO-Revision-Date: 2013-05-08 13:15+0000\n"
|
||||
"Last-Translator: zeroflag <zeroflag@i2pmail.org>\n"
|
||||
"POT-Creation-Date: 2013-09-26 21:33+0000\n"
|
||||
"PO-Revision-Date: 2013-09-23 22:32+0000\n"
|
||||
"Last-Translator: nextloop <ga25day@mytum.de>\n"
|
||||
"Language-Team: German (http://www.transifex.com/projects/p/I2P/language/"
|
||||
"de/)\n"
|
||||
"Language: de\n"
|
||||
@ -28,126 +29,6 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:572
|
||||
msgid "This seems to be a bad destination:"
|
||||
msgstr "Dies scheint kein gültiges Ziel zu sein:"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:572
|
||||
msgid "i2paddresshelper cannot help you with a destination like that!"
|
||||
msgstr "Der I2P-Adresshelfer kann dir bei solch einem Ziel nicht helfen."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:639
|
||||
#, java-format
|
||||
msgid ""
|
||||
"To visit the destination in your host database, click <a href=\"{0}\">here</"
|
||||
"a>. To visit the conflicting addresshelper destination, click <a href="
|
||||
"\"{1}\">here</a>."
|
||||
msgstr ""
|
||||
"Um das Ziel in Ihrer Host-Datenbank zu besuchen, klicken Sie <a href="
|
||||
"\"{0}\">hier</a>, und um das Ziel aus der kollidierenden Adresshelfer-"
|
||||
"Anfrage zu besuchen, <a href=\"{1}\">hier</a>!"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1043
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:385
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:159
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:389
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:410
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1047
|
||||
msgid "Base 32"
|
||||
msgstr "Base 32"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1051
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:377
|
||||
msgid "Destination"
|
||||
msgstr "Ziel"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1057
|
||||
#, java-format
|
||||
msgid "Continue to {0} without saving"
|
||||
msgstr "Weiter zu {0}, ohne zu speichern"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1062
|
||||
#, java-format
|
||||
msgid "Save {0} to router address book and continue to eepsite"
|
||||
msgstr "{0} im Router-Adressbuch speichern und auf die Eepseite weiterleiten"
|
||||
|
||||
#. only blockfile supports multiple books
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1065
|
||||
#, java-format
|
||||
msgid "Save {0} to master address book and continue to eepsite"
|
||||
msgstr "{0} im Master-Adressbuch speichern und auf die Eepseite weiterleiten"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1066
|
||||
#, java-format
|
||||
msgid "Save {0} to private address book and continue to eepsite"
|
||||
msgstr "{0} im privaten Adressbuch speichern und auf die Eepseite weiterleiten"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1180
|
||||
msgid "HTTP Outproxy"
|
||||
msgstr "HTTP-Outproxy"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1185
|
||||
msgid ""
|
||||
"Click a link below to look for an address helper by using a \"jump\" service:"
|
||||
msgstr ""
|
||||
"Durch Klicken auf einen der untenstehenden Links bekommen Sie einen "
|
||||
"Adresshelfer von einem \"Sprung\"-Service:"
|
||||
|
||||
#. Translators: parameter is a host name
|
||||
#: ../java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java:1221
|
||||
#, java-format
|
||||
msgid "{0} jump service"
|
||||
msgstr "Weiterleitungsdienst {0}"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:163
|
||||
#, java-format
|
||||
msgid "Added via address helper from {0}"
|
||||
msgstr "Hinzugefüg über den Adressenhelfer von {0}"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:165
|
||||
msgid "Added via address helper"
|
||||
msgstr "Durch Adresshelfer hinzugefügt"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:190
|
||||
#, java-format
|
||||
msgid "Redirecting to {0}"
|
||||
msgstr "Weiterleitung zu {0}"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:196
|
||||
msgid "Router Console"
|
||||
msgstr "Routerkonsole"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:197
|
||||
msgid "Addressbook"
|
||||
msgstr "Adressbuch"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:197
|
||||
msgid "Configuration"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:197
|
||||
msgid "Help"
|
||||
msgstr "Hilfe"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:202
|
||||
#, java-format
|
||||
msgid "Saved {0} to the {1} addressbook, redirecting now."
|
||||
msgstr ""
|
||||
"{0} wurde ins {1} Adressbuch geschrieben. Du wirst nun weitergeleitet."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:203
|
||||
#, java-format
|
||||
msgid "Failed to save {0} to the {1} addressbook, redirecting now."
|
||||
msgstr ""
|
||||
"Konnte {0} nicht im {1} Adressbuch speichern. Du wirst nun weitergeleitet."
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java:205
|
||||
msgid "Click here if you are not redirected automatically."
|
||||
msgstr "Klick hier, wenn du nicht automatisch weitergeleitet wirst!"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/EditBean.java:325
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/EditBean.java:335
|
||||
msgid "internal"
|
||||
@ -162,17 +43,15 @@ msgstr[1] ""
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/EditBean.java:408
|
||||
msgid "lower bandwidth and reliability"
|
||||
msgstr ""
|
||||
msgstr "niedrigere Bandbreite und Zuverlässlichkeit"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/EditBean.java:410
|
||||
#, fuzzy
|
||||
msgid "standard bandwidth and reliability"
|
||||
msgstr ""
|
||||
"2 eingehende, 2 ausgehende Tunnel (Standardbandbreitennutzung, zuverlässig)"
|
||||
msgstr "standard Bandbreite und Zuverlässlichkeit"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/EditBean.java:412
|
||||
msgid "higher bandwidth and reliability"
|
||||
msgstr ""
|
||||
msgstr "hohe Bandbreite und Zuverlässlichkeit"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/IndexBean.java:119
|
||||
msgid "Tunnels are not initialized yet, please reload in two minutes."
|
||||
@ -563,6 +442,13 @@ msgstr "für Verbindungen mit Anfragen/Antworten"
|
||||
msgid "Router I2CP Address"
|
||||
msgstr "I2CP-Adresse des Routers"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:385
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:159
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:389
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:410
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editClient_jsp.java:393
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:165
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/editServer_jsp.java:397
|
||||
@ -932,6 +818,10 @@ msgstr "Wartestellung"
|
||||
msgid "Outproxy"
|
||||
msgstr "Ausgehender Proxy"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:377
|
||||
msgid "Destination"
|
||||
msgstr "Ziel"
|
||||
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/index_jsp.java:397
|
||||
msgid "none"
|
||||
msgstr "Keiner"
|
||||
@ -1350,26 +1240,3 @@ msgstr "Abschließen"
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:724
|
||||
msgid "Next"
|
||||
msgstr "Nächstes"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "1 inbound, 1 outbound tunnel (low bandwidth usage, less reliability)"
|
||||
#~ msgstr ""
|
||||
#~ "1 eingehender, 1 ausgehender Tunnel (geringe Bandbreitennutzung, weniger "
|
||||
#~ "zuverlässig)"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "3 inbound, 3 outbound tunnels (higher bandwidth usage, higher reliability)"
|
||||
#~ msgstr ""
|
||||
#~ "3 eingehende, 3 ausgehende Tunnel (hohe Bandbreitennutzung, zuverlässiger)"
|
||||
|
||||
#~ msgid "tunnels"
|
||||
#~ msgstr "Tunnel"
|
||||
|
||||
#~ msgid "4 in, 4 out (high traffic server)"
|
||||
#~ msgstr "4 eingehend, 4 ausgehend (Server mit großem Datenverkehr)"
|
||||
|
||||
#~ msgid "5 in, 5 out (high traffic server)"
|
||||
#~ msgstr "5 eingehend, 5 ausgehend (Server mit großem Datenverkehr)"
|
||||
|
||||
#~ msgid "6 in, 6 out (high traffic server)"
|
||||
#~ msgstr "6 eingehend, 6 ausgehend (Server mit großem Datenverkehr)"
|
||||
|
@ -13,8 +13,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-08-11 14:30+0000\n"
|
||||
"PO-Revision-Date: 2013-07-16 15:35+0000\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:24+0000\n"
|
||||
"PO-Revision-Date: 2013-08-13 14:14+0000\n"
|
||||
"Last-Translator: Boxoa590\n"
|
||||
"Language-Team: French (http://www.transifex.com/projects/p/I2P/language/"
|
||||
"fr/)\n"
|
||||
@ -33,8 +33,8 @@ msgstr "interne"
|
||||
#, java-format
|
||||
msgid "{0} inbound, {0} outbound tunnel"
|
||||
msgid_plural "{0} inbound, {0} outbound tunnels"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr[0] "{0} entrant, {0} sortant tunnels"
|
||||
msgstr[1] "{0} entrants, {0} sortants tunnels"
|
||||
|
||||
#: ../java/src/net/i2p/i2ptunnel/web/EditBean.java:408
|
||||
msgid "lower bandwidth and reliability"
|
||||
@ -1247,79 +1247,3 @@ msgstr "Terminer"
|
||||
#: ../jsp/WEB-INF/classes/net/i2p/i2ptunnel/jsp/wizard_jsp.java:724
|
||||
msgid "Next"
|
||||
msgstr "Suivant"
|
||||
|
||||
#~ msgid "This seems to be a bad destination:"
|
||||
#~ msgstr "Cela semble être une mauvaise destination"
|
||||
|
||||
#~ msgid "i2paddresshelper cannot help you with a destination like that!"
|
||||
#~ msgstr ""
|
||||
#~ "i2paddresshelper ne peut pas vous aider avec une destination comme cela !"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "To visit the destination in your host database, click <a href="
|
||||
#~ "\"{0}\">here</a>. To visit the conflicting addresshelper destination, "
|
||||
#~ "click <a href=\"{1}\">here</a>."
|
||||
#~ msgstr ""
|
||||
#~ "Pour aller à la destination de votre base de données d''hôtes, cliquez <a "
|
||||
#~ "href=\"{0}\">here</a>. Pour aller à la destination de l''aide d''adresse "
|
||||
#~ "en conflit, cliquez <a href=\"{1}\">ici</a>."
|
||||
|
||||
#~ msgid "Base 32"
|
||||
#~ msgstr "Base 32"
|
||||
|
||||
#~ msgid "Continue to {0} without saving"
|
||||
#~ msgstr ""
|
||||
#~ "Aller sur le site i2p {0} sans enregistrer dans un carnet d'adresses. "
|
||||
|
||||
#~ msgid "Save {0} to router address book and continue to eepsite"
|
||||
#~ msgstr ""
|
||||
#~ "Ajouter au carnet d''adresse du routeur {0} et aller sur le site i2p"
|
||||
|
||||
#~ msgid "Save {0} to master address book and continue to eepsite"
|
||||
#~ msgstr "Ajouter au carnet d''adresse principal {0} et aller sur le site i2p"
|
||||
|
||||
#~ msgid "Save {0} to private address book and continue to eepsite"
|
||||
#~ msgstr "Ajouter au carnet d''adresse privé {0} et aller sur le site i2p"
|
||||
|
||||
#~ msgid "HTTP Outproxy"
|
||||
#~ msgstr "proxy sortant HTTP"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Click a link below to look for an address helper by using a \"jump\" "
|
||||
#~ "service:"
|
||||
#~ msgstr ""
|
||||
#~ "Cliquez sur un des liens ci-dessous pour chercher une aide d'adresse en "
|
||||
#~ "utilisant un \"service de saut\":"
|
||||
|
||||
#~ msgid "{0} jump service"
|
||||
#~ msgstr "{0} jump service"
|
||||
|
||||
#~ msgid "Added via address helper from {0}"
|
||||
#~ msgstr "Ajouté via assistant d''adresse depuis {0}"
|
||||
|
||||
#~ msgid "Added via address helper"
|
||||
#~ msgstr "Ajouté via assitant d'adresse"
|
||||
|
||||
#~ msgid "Redirecting to {0}"
|
||||
#~ msgstr "Redirection vers {0}"
|
||||
|
||||
#~ msgid "Router Console"
|
||||
#~ msgstr "Console du routeur"
|
||||
|
||||
#~ msgid "Addressbook"
|
||||
#~ msgstr "Carnet d'adresses"
|
||||
|
||||
#~ msgid "Configuration"
|
||||
#~ msgstr "Configuration"
|
||||
|
||||
#~ msgid "Help"
|
||||
#~ msgstr "Aide"
|
||||
|
||||
#~ msgid "Saved {0} to the {1} addressbook, redirecting now."
|
||||
#~ msgstr "{0} ajouté au carnet d''adresses {1}. Redirection en cours."
|
||||
|
||||
#~ msgid "Failed to save {0} to the {1} addressbook, redirecting now."
|
||||
#~ msgstr "{0} non ajouté au carnet d''adresses {1}. Redirection en cours."
|
||||
|
||||
#~ msgid "Click here if you are not redirected automatically."
|
||||
#~ msgstr "Cliquez ici si vous n'êtes pas redirigé automatiquement."
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -121,6 +121,7 @@
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
@ -167,6 +168,7 @@
|
||||
|
||||
<target name="bundle-news" unless="no.bundle">
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages-news.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
|
@ -15,6 +15,10 @@ TMPFILE=build/javafiles-news.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
|
@ -15,6 +15,10 @@ TMPFILE=build/javafiles.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
|
@ -19,6 +19,7 @@ import java.util.StringTokenizer;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.crypto.SU3File;
|
||||
import net.i2p.crypto.TrustedUpdate;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.router.Router;
|
||||
@ -69,6 +70,7 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
private final Map<UpdateItem, Version> _downloaded;
|
||||
/** downloaded AND installed */
|
||||
private final Map<UpdateItem, Version> _installed;
|
||||
private final boolean _allowTorrent;
|
||||
private static final DecimalFormat _pct = new DecimalFormat("0.0%");
|
||||
|
||||
private volatile String _status;
|
||||
@ -90,6 +92,13 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
_downloaded = new ConcurrentHashMap();
|
||||
_installed = new ConcurrentHashMap();
|
||||
_status = "";
|
||||
// DEBUG slow start for snark updates
|
||||
// For 0.9.4 update, only for dev builds
|
||||
// For 0.9.5 update, only for dev builds and 1% more
|
||||
// For 0.9.6 update, only for dev builds and 3% more
|
||||
// For 0.9.8 update, only for dev builds and 30% more
|
||||
// Remove this for 100%
|
||||
_allowTorrent = RouterVersion.BUILD != 0 || _context.random().nextInt(100) < 30;
|
||||
}
|
||||
|
||||
public static ConsoleUpdateManager getInstance() {
|
||||
@ -99,6 +108,7 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
public void start() {
|
||||
notifyInstalled(NEWS, "", Long.toString(NewsHelper.lastUpdated(_context)));
|
||||
notifyInstalled(ROUTER_SIGNED, "", RouterVersion.VERSION);
|
||||
notifyInstalled(ROUTER_SIGNED_SU3, "", RouterVersion.VERSION);
|
||||
// hack to init from the current news file... do this before we register Updaters
|
||||
// This will not kick off any Updaters as none are yet registered
|
||||
(new NewsFetcher(_context, this, Collections.EMPTY_LIST)).checkForUpdates();
|
||||
@ -122,6 +132,15 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
register(c, ROUTER_SIGNED, HTTP, 0); // news is an update checker for the router
|
||||
Updater u = new UpdateHandler(_context, this);
|
||||
register(u, ROUTER_SIGNED, HTTP, 0);
|
||||
if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
register(c, ROUTER_SIGNED_SU3, HTTP, 0);
|
||||
register(u, ROUTER_SIGNED_SU3, HTTP, 0);
|
||||
// todo
|
||||
//register(c, ROUTER_SIGNED_SU3, HTTPS_CLEARNET, 0);
|
||||
//register(u, ROUTER_SIGNED_SU3, HTTPS_CLEARNET, -10);
|
||||
//register(c, ROUTER_SIGNED_SU3, HTTP_CLEARNET, 0);
|
||||
//register(u, ROUTER_SIGNED_SU3, HTTP_CLEARNET, -20);
|
||||
}
|
||||
// TODO see NewsFetcher
|
||||
//register(u, ROUTER_SIGNED, HTTPS_CLEARNET, -5);
|
||||
//register(u, ROUTER_SIGNED, HTTP_CLEARNET, -10);
|
||||
@ -560,18 +579,18 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
* Call once for each type/method pair.
|
||||
*/
|
||||
public void register(Updater updater, UpdateType type, UpdateMethod method, int priority) {
|
||||
if ((type == ROUTER_SIGNED || type == ROUTER_UNSIGNED) && NewsHelper.dontInstall(_context)) {
|
||||
if ((type == ROUTER_SIGNED || type == ROUTER_UNSIGNED || type == ROUTER_SIGNED_SU3) &&
|
||||
NewsHelper.dontInstall(_context)) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Ignoring registration for " + type + ", router updates disabled");
|
||||
return;
|
||||
}
|
||||
// DEBUG slow start for snark updates
|
||||
// For 0.9.4 update, only for dev builds
|
||||
// For 0.9.5 update, only for dev builds and 1% more
|
||||
// For 0.9.6 update, only for dev builds and 3% more
|
||||
// For 0.9.8 update, only for dev builds and 30% more
|
||||
// Remove this for 100%
|
||||
if (method == TORRENT && RouterVersion.BUILD == 0 && _context.random().nextInt(100) > 29) {
|
||||
if (type == ROUTER_SIGNED_SU3 && !ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Ignoring registration for " + type + ", SU3 updates disabled");
|
||||
return;
|
||||
}
|
||||
if (method == TORRENT && !_allowTorrent) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Ignoring torrent registration");
|
||||
return;
|
||||
@ -725,8 +744,10 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
// fall through
|
||||
|
||||
case ROUTER_SIGNED:
|
||||
case ROUTER_SIGNED_SU3:
|
||||
if (shouldInstall() &&
|
||||
!(isUpdateInProgress(ROUTER_SIGNED) ||
|
||||
isUpdateInProgress(ROUTER_SIGNED_SU3) ||
|
||||
isUpdateInProgress(ROUTER_UNSIGNED))) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Updating " + ui + " after notify");
|
||||
@ -810,6 +831,7 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
switch (task.getType()) {
|
||||
case NEWS:
|
||||
case ROUTER_SIGNED:
|
||||
case ROUTER_SIGNED_SU3:
|
||||
case ROUTER_UNSIGNED:
|
||||
// ConfigUpdateHandler, SummaryHelper, SummaryBarRenderer handle status display
|
||||
break;
|
||||
@ -926,6 +948,12 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
notifyDownloaded(task.getType(), task.getID(), actualVersion);
|
||||
break;
|
||||
|
||||
case ROUTER_SIGNED_SU3:
|
||||
rv = handleSu3File(task.getURI(), actualVersion, file);
|
||||
if (rv)
|
||||
notifyDownloaded(task.getType(), task.getID(), actualVersion);
|
||||
break;
|
||||
|
||||
case ROUTER_UNSIGNED:
|
||||
rv = handleUnsignedFile(task.getURI(), actualVersion, file);
|
||||
if (rv) {
|
||||
@ -981,10 +1009,30 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
_log.info(ui + " " + ver + " downloaded");
|
||||
_downloaded.put(ui, ver);
|
||||
// one trumps the other
|
||||
if (type == ROUTER_SIGNED)
|
||||
if (type == ROUTER_SIGNED) {
|
||||
_downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, ""));
|
||||
else if (type == ROUTER_UNSIGNED)
|
||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, ""));
|
||||
// remove available from other type
|
||||
UpdateItem altui = new UpdateItem(ROUTER_SIGNED_SU3, id);
|
||||
Version old = _available.get(altui);
|
||||
if (old != null && old.compareTo(ver) <= 0)
|
||||
_available.remove(altui);
|
||||
// ... and declare the alt downloaded as well
|
||||
_downloaded.put(altui, ver);
|
||||
} else if (type == ROUTER_SIGNED_SU3) {
|
||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED, ""));
|
||||
_downloaded.remove(new UpdateItem(ROUTER_UNSIGNED, ""));
|
||||
// remove available from other type
|
||||
UpdateItem altui = new UpdateItem(ROUTER_SIGNED, id);
|
||||
Version old = _available.get(altui);
|
||||
if (old != null && old.compareTo(ver) <= 0)
|
||||
_available.remove(altui);
|
||||
// ... and declare the alt downloaded as well
|
||||
_downloaded.put(altui, ver);
|
||||
} else if (type == ROUTER_UNSIGNED) {
|
||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED, ""));
|
||||
_downloaded.remove(new UpdateItem(ROUTER_SIGNED_SU3, ""));
|
||||
}
|
||||
Version old = _available.get(ui);
|
||||
if (old != null && old.compareTo(ver) <= 0)
|
||||
_available.remove(ui);
|
||||
@ -1018,6 +1066,7 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
break;
|
||||
|
||||
case ROUTER_SIGNED:
|
||||
{ // avoid dup variables in next case
|
||||
String URLs = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_URL, ConfigUpdateHandler.DEFAULT_UPDATE_URL);
|
||||
StringTokenizer tok = new StringTokenizer(URLs, " ,\r\n");
|
||||
List<URI> rv = new ArrayList();
|
||||
@ -1028,6 +1077,21 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
}
|
||||
Collections.shuffle(rv, _context.random());
|
||||
return rv;
|
||||
}
|
||||
|
||||
case ROUTER_SIGNED_SU3:
|
||||
{
|
||||
String URLs = ConfigUpdateHandler.SU3_UPDATE_URLS;
|
||||
StringTokenizer tok = new StringTokenizer(URLs, " ,\r\n");
|
||||
List<URI> rv = new ArrayList();
|
||||
while (tok.hasMoreTokens()) {
|
||||
try {
|
||||
rv.add(new URI(tok.nextToken().trim()));
|
||||
} catch (URISyntaxException use) {}
|
||||
}
|
||||
Collections.shuffle(rv, _context.random());
|
||||
return rv;
|
||||
}
|
||||
|
||||
case ROUTER_UNSIGNED:
|
||||
String url = _context.getProperty(ConfigUpdateHandler.PROP_ZIP_URL);
|
||||
@ -1072,14 +1136,59 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
* @return success
|
||||
*/
|
||||
private boolean handleSudFile(URI uri, String actualVersion, File f) {
|
||||
return handleRouterFile(uri, actualVersion, f, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private boolean handleSu3File(URI uri, String actualVersion, File f) {
|
||||
return handleRouterFile(uri, actualVersion, f, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process sud, su2, or su3
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private boolean handleRouterFile(URI uri, String actualVersion, File f, boolean isSU3) {
|
||||
String url = uri.toString();
|
||||
// Process the .sud/.su2 file
|
||||
updateStatus("<b>" + _("Update downloaded") + "</b>");
|
||||
TrustedUpdate up = new TrustedUpdate(_context);
|
||||
File to = new File(_context.getRouterDir(), Router.UPDATE_FILE);
|
||||
String err = up.migrateVerified(RouterVersion.VERSION, f, to);
|
||||
///////////
|
||||
// caller must delete now.. why?
|
||||
String err;
|
||||
// Process the file
|
||||
if (isSU3) {
|
||||
SU3File up = new SU3File(_context, f);
|
||||
File temp = new File(_context.getTempDir(), "su3out-" + _context.random().nextLong() + ".zip");
|
||||
try {
|
||||
if (up.verifyAndMigrate(temp)) {
|
||||
String ver = up.getVersionString();
|
||||
int type = up.getContentType();
|
||||
if (ver == null || VersionComparator.comp(RouterVersion.VERSION, ver) >= 0)
|
||||
err = "Old version " + ver;
|
||||
else if (type != SU3File.CONTENT_ROUTER)
|
||||
err = "Bad su3 content type " + type;
|
||||
else if (!FileUtil.copy(temp, to, true, false))
|
||||
err = "Failed copy to " + to;
|
||||
else
|
||||
err = null; // success
|
||||
} else {
|
||||
err = "Signature failed, signer " + DataHelper.stripHTML(up.getSignerString()) +
|
||||
' ' + up.getSigType();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
_log.error("SU3 extract error", ioe);
|
||||
err = DataHelper.stripHTML(ioe.toString());
|
||||
} finally {
|
||||
temp.delete();
|
||||
}
|
||||
} else {
|
||||
TrustedUpdate up = new TrustedUpdate(_context);
|
||||
err = up.migrateVerified(RouterVersion.VERSION, f, to);
|
||||
}
|
||||
|
||||
// caller must delete.. could be an active torrent
|
||||
//f.delete();
|
||||
if (err == null) {
|
||||
String policy = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_POLICY);
|
||||
@ -1346,6 +1455,8 @@ public class ConsoleUpdateManager implements UpdateManager {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if ("".equals(id))
|
||||
return "UpdateItem " + type;
|
||||
return "UpdateItem " + type + ' ' + id;
|
||||
}
|
||||
}
|
||||
|
@ -48,13 +48,10 @@ class DummyHandler implements Checker, Updater {
|
||||
private final long _delay;
|
||||
|
||||
public DummyRunner(RouterContext ctx, ConsoleUpdateManager mgr, long maxTime) {
|
||||
super(ctx, mgr, Collections.EMPTY_LIST);
|
||||
super(ctx, mgr, UpdateType.TYPE_DUMMY, Collections.EMPTY_LIST);
|
||||
_delay = maxTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateType getType() { return UpdateType.TYPE_DUMMY; }
|
||||
|
||||
@Override
|
||||
public UpdateMethod getMethod() { return UpdateMethod.METHOD_DUMMY; }
|
||||
|
||||
|
@ -32,6 +32,7 @@ import net.i2p.util.EepHead;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.VersionComparator;
|
||||
import net.i2p.util.SSLEepGet;
|
||||
|
||||
/**
|
||||
* Task to fetch updates to the news.xml, and to keep
|
||||
@ -50,7 +51,7 @@ class NewsFetcher extends UpdateRunner {
|
||||
private static final String TEMP_NEWS_FILE = "news.xml.temp";
|
||||
|
||||
public NewsFetcher(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) {
|
||||
super(ctx, mgr, uris);
|
||||
super(ctx, mgr, NEWS, uris);
|
||||
_newsFile = new File(ctx.getRouterDir(), NewsHelper.NEWS_FILE);
|
||||
_tempFile = new File(ctx.getTempDir(), "tmp-" + ctx.random().nextLong() + TEMP_NEWS_FILE);
|
||||
long lastMod = NewsHelper.lastChecked(ctx);
|
||||
@ -73,7 +74,7 @@ class NewsFetcher extends UpdateRunner {
|
||||
}
|
||||
|
||||
public void fetchNews() {
|
||||
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
boolean shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY_NEWS, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY_NEWS);
|
||||
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
|
||||
@ -88,6 +89,9 @@ class NewsFetcher extends UpdateRunner {
|
||||
EepGet get;
|
||||
if (shouldProxy)
|
||||
get = new EepGet(_context, true, proxyHost, proxyPort, 0, _tempFile.getAbsolutePath(), newsURL, true, null, _lastModified);
|
||||
else if ("https".equals(uri.getScheme()))
|
||||
// no constructor w/ last mod check
|
||||
get = new SSLEepGet(_context, _tempFile.getAbsolutePath(), newsURL);
|
||||
else
|
||||
get = new EepGet(_context, false, null, 0, 0, _tempFile.getAbsolutePath(), newsURL, true, null, _lastModified);
|
||||
get.addStatusListener(this);
|
||||
@ -113,9 +117,11 @@ class NewsFetcher extends UpdateRunner {
|
||||
private static final String MIN_JAVA_VERSION_KEY = "minjavaversion";
|
||||
private static final String SUD_KEY = "sudtorrent";
|
||||
private static final String SU2_KEY = "su2torrent";
|
||||
// following are unused
|
||||
private static final String SU3_KEY = "su3torrent";
|
||||
private static final String CLEARNET_SUD_KEY = "sudclearnet";
|
||||
private static final String CLEARNET_SU2_KEY = "su2clearnet";
|
||||
private static final String CLEARNET_HTTP_SU3_KEY = "su3clearnet";
|
||||
private static final String CLEARNET_HTTPS_SU3_KEY = "su3ssl";
|
||||
private static final String I2P_SUD_KEY = "sudi2p";
|
||||
private static final String I2P_SU2_KEY = "su2i2p";
|
||||
|
||||
@ -175,20 +181,24 @@ class NewsFetcher extends UpdateRunner {
|
||||
// and look for a second entry with clearnet URLs
|
||||
// TODO clearnet URLs, notify with HTTP_CLEARNET and/or HTTPS_CLEARNET
|
||||
Map<UpdateMethod, List<URI>> sourceMap = new HashMap(4);
|
||||
// Must do su3 first
|
||||
if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED_SU3, "", HTTP));
|
||||
addMethod(TORRENT, args.get(SU3_KEY), sourceMap);
|
||||
addMethod(HTTP_CLEARNET, args.get(CLEARNET_HTTP_SU3_KEY), sourceMap);
|
||||
addMethod(HTTPS_CLEARNET, args.get(CLEARNET_HTTPS_SU3_KEY), sourceMap);
|
||||
// notify about all sources at once
|
||||
_mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED_SU3,
|
||||
"", sourceMap, ver, "");
|
||||
sourceMap.clear();
|
||||
}
|
||||
// now do sud/su2
|
||||
sourceMap.put(HTTP, _mgr.getUpdateURLs(ROUTER_SIGNED, "", HTTP));
|
||||
String key = FileUtil.isPack200Supported() ? SU2_KEY : SUD_KEY;
|
||||
String murl = args.get(key);
|
||||
if (murl != null) {
|
||||
List<URI> uris = tokenize(murl);
|
||||
if (!uris.isEmpty()) {
|
||||
Collections.shuffle(uris, _context.random());
|
||||
sourceMap.put(TORRENT, uris);
|
||||
}
|
||||
}
|
||||
addMethod(TORRENT, args.get(key), sourceMap);
|
||||
// notify about all sources at once
|
||||
_mgr.notifyVersionAvailable(this, _currentURI,
|
||||
ROUTER_SIGNED, "", sourceMap,
|
||||
ver, "");
|
||||
_mgr.notifyVersionAvailable(this, _currentURI, ROUTER_SIGNED,
|
||||
"", sourceMap, ver, "");
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Our version is current");
|
||||
@ -292,6 +302,21 @@ class NewsFetcher extends UpdateRunner {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse URLs and add to the map
|
||||
* @param urls may be null
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private void addMethod(UpdateMethod method, String urls, Map<UpdateMethod, List<URI>> map) {
|
||||
if (urls != null) {
|
||||
List<URI> uris = tokenize(urls);
|
||||
if (!uris.isEmpty()) {
|
||||
Collections.shuffle(uris, _context.random());
|
||||
map.put(method, uris);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** override to prevent status update */
|
||||
@Override
|
||||
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {}
|
||||
|
@ -35,16 +35,13 @@ class PluginUpdateChecker extends UpdateRunner {
|
||||
|
||||
public PluginUpdateChecker(RouterContext ctx, ConsoleUpdateManager mgr,
|
||||
List<URI> uris, String appName, String oldVersion ) {
|
||||
super(ctx, mgr, uris, oldVersion);
|
||||
super(ctx, mgr, UpdateType.PLUGIN, uris, oldVersion);
|
||||
if (!uris.isEmpty())
|
||||
_currentURI = uris.get(0);
|
||||
_appName = appName;
|
||||
_oldVersion = oldVersion;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UpdateType getType() { return UpdateType.PLUGIN; }
|
||||
|
||||
@Override
|
||||
public String getID() { return _appName; }
|
||||
|
||||
|
@ -60,7 +60,7 @@ class PluginUpdateRunner extends UpdateRunner {
|
||||
|
||||
public PluginUpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris,
|
||||
String appName, String oldVersion ) {
|
||||
super(ctx, mgr, uris);
|
||||
super(ctx, mgr, UpdateType.PLUGIN, uris);
|
||||
if (uris.isEmpty())
|
||||
throw new IllegalArgumentException("uri cannot be empty");
|
||||
else
|
||||
@ -70,12 +70,6 @@ class PluginUpdateRunner extends UpdateRunner {
|
||||
_oldVersion = oldVersion;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public UpdateType getType() {
|
||||
return UpdateType.PLUGIN;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() { return _uri; }
|
||||
|
||||
@ -104,7 +98,7 @@ class PluginUpdateRunner extends UpdateRunner {
|
||||
} else {
|
||||
updateStatus("<b>" + _("Downloading plugin from {0}", _xpi2pURL) + "</b>");
|
||||
// use the same settings as for updater
|
||||
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
boolean shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
|
||||
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
try {
|
||||
|
@ -28,17 +28,10 @@ class UnsignedUpdateChecker extends UpdateRunner {
|
||||
|
||||
public UnsignedUpdateChecker(RouterContext ctx, ConsoleUpdateManager mgr,
|
||||
List<URI> uris, long lastUpdateTime) {
|
||||
super(ctx, mgr, uris);
|
||||
super(ctx, mgr, UpdateType.ROUTER_UNSIGNED, uris);
|
||||
_ms = lastUpdateTime;
|
||||
}
|
||||
|
||||
//////// begin UpdateTask methods
|
||||
|
||||
@Override
|
||||
public UpdateType getType() { return UpdateType.ROUTER_UNSIGNED; }
|
||||
|
||||
//////// end UpdateTask methods
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
_isRunning = true;
|
||||
|
@ -25,16 +25,12 @@ import net.i2p.util.Log;
|
||||
class UnsignedUpdateRunner extends UpdateRunner {
|
||||
|
||||
public UnsignedUpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) {
|
||||
super(ctx, mgr, uris);
|
||||
super(ctx, mgr, ROUTER_UNSIGNED, uris);
|
||||
if (!uris.isEmpty())
|
||||
_currentURI = uris.get(0);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public UpdateType getType() { return ROUTER_UNSIGNED; }
|
||||
|
||||
|
||||
/** Get the file */
|
||||
@Override
|
||||
protected void update() {
|
||||
|
@ -4,7 +4,10 @@ import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.web.ConfigUpdateHandler;
|
||||
import net.i2p.update.*;
|
||||
import static net.i2p.update.UpdateType.*;
|
||||
import static net.i2p.update.UpdateMethod.*;
|
||||
|
||||
/**
|
||||
* <p>Handles the request to update the router by firing one or more
|
||||
@ -38,10 +41,13 @@ class UpdateHandler implements Updater {
|
||||
*/
|
||||
public UpdateTask update(UpdateType type, UpdateMethod method, List<URI> updateSources,
|
||||
String id, String newVersion, long maxTime) {
|
||||
if (type != UpdateType.ROUTER_SIGNED ||
|
||||
method != UpdateMethod.HTTP || updateSources.isEmpty())
|
||||
boolean shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
|
||||
if ((type != ROUTER_SIGNED && type != ROUTER_SIGNED_SU3) ||
|
||||
(shouldProxy && method != HTTP) ||
|
||||
((!shouldProxy) && method != HTTP_CLEARNET && method != HTTPS_CLEARNET) ||
|
||||
updateSources.isEmpty())
|
||||
return null;
|
||||
UpdateRunner update = new UpdateRunner(_context, _mgr, updateSources);
|
||||
UpdateRunner update = new UpdateRunner(_context, _mgr, type, method, updateSources);
|
||||
// set status before thread to ensure UI feedback
|
||||
_mgr.notifyProgress(update, "<b>" + _mgr._("Updating") + "</b>");
|
||||
return update;
|
||||
|
@ -5,6 +5,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.crypto.TrustedUpdate;
|
||||
@ -13,10 +14,12 @@ import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.RouterVersion;
|
||||
import net.i2p.router.web.ConfigUpdateHandler;
|
||||
import net.i2p.update.*;
|
||||
import static net.i2p.update.UpdateMethod.*;
|
||||
import net.i2p.util.EepGet;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.PartialEepGet;
|
||||
import net.i2p.util.SSLEepGet;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
/**
|
||||
@ -30,6 +33,8 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
protected final RouterContext _context;
|
||||
protected final Log _log;
|
||||
protected final ConsoleUpdateManager _mgr;
|
||||
protected final UpdateType _type;
|
||||
protected final UpdateMethod _method;
|
||||
protected final List<URI> _urls;
|
||||
protected final String _updateFile;
|
||||
protected volatile boolean _isRunning;
|
||||
@ -53,20 +58,42 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
/**
|
||||
* Uses router version for partial checks
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris) {
|
||||
this(ctx, mgr, uris, RouterVersion.VERSION);
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type, List<URI> uris) {
|
||||
this(ctx, mgr, type, uris, RouterVersion.VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses router version for partial checks
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type,
|
||||
UpdateMethod method, List<URI> uris) {
|
||||
this(ctx, mgr, type, method, uris, RouterVersion.VERSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param currentVersion used for partial checks
|
||||
* @since 0.9.7
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, List<URI> uris, String currentVersion) {
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type,
|
||||
List<URI> uris, String currentVersion) {
|
||||
this(ctx, mgr, type, HTTP, uris, currentVersion);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param method HTTP, HTTP_CLEARNET, or HTTPS_CLEARNET
|
||||
* @param currentVersion used for partial checks
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public UpdateRunner(RouterContext ctx, ConsoleUpdateManager mgr, UpdateType type,
|
||||
UpdateMethod method, List<URI> uris, String currentVersion) {
|
||||
super("Update Runner");
|
||||
setDaemon(true);
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(getClass());
|
||||
_mgr = mgr;
|
||||
_type = type;
|
||||
_method = method;
|
||||
_urls = uris;
|
||||
_baos = new ByteArrayOutputStream(TrustedUpdate.HEADER_BYTES);
|
||||
_updateFile = (new File(ctx.getTempDir(), "update" + ctx.random().nextInt() + ".tmp")).getAbsolutePath();
|
||||
@ -82,9 +109,9 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
interrupt();
|
||||
}
|
||||
|
||||
public UpdateType getType() { return UpdateType.ROUTER_SIGNED; }
|
||||
public UpdateType getType() { return _type; }
|
||||
|
||||
public UpdateMethod getMethod() { return UpdateMethod.HTTP; }
|
||||
public UpdateMethod getMethod() { return _method; }
|
||||
|
||||
public URI getURI() { return _currentURI; }
|
||||
|
||||
@ -117,9 +144,32 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
// Alternative: In bytesTransferred(), Check the data in the output file after
|
||||
// we've received at least 56 bytes. Need a cancel() method in EepGet ?
|
||||
|
||||
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
int proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
boolean shouldProxy;
|
||||
String proxyHost;
|
||||
int proxyPort;
|
||||
boolean isSSL = false;
|
||||
if (_method == HTTP) {
|
||||
shouldProxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
|
||||
if (shouldProxy) {
|
||||
proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
proxyPort = ConfigUpdateHandler.proxyPort(_context);
|
||||
} else {
|
||||
// TODO, wrong method, fail
|
||||
proxyHost = null;
|
||||
proxyPort = 0;
|
||||
}
|
||||
} else if (_method == HTTP_CLEARNET) {
|
||||
shouldProxy = false;
|
||||
proxyHost = null;
|
||||
proxyPort = 0;
|
||||
} else if (_method == HTTPS_CLEARNET) {
|
||||
shouldProxy = false;
|
||||
proxyHost = null;
|
||||
proxyPort = 0;
|
||||
isSSL = true;
|
||||
} else {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
if (_urls.isEmpty()) {
|
||||
// not likely, don't bother translating
|
||||
@ -132,12 +182,24 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
for (URI uri : _urls) {
|
||||
_currentURI = uri;
|
||||
String updateURL = uri.toString();
|
||||
if ((_method == HTTP && !"http".equals(uri.getScheme())) ||
|
||||
(_method == HTTP_CLEARNET && !"http".equals(uri.getScheme())) ||
|
||||
(_method == HTTPS_CLEARNET && !"https".equals(uri.getScheme())) ||
|
||||
uri.getHost() == null ||
|
||||
(_method != HTTP && uri.getHost().toLowerCase(Locale.US).endsWith(".i2p"))) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Bad update URI " + uri + " for method " + _method);
|
||||
continue;
|
||||
}
|
||||
|
||||
updateStatus("<b>" + _("Updating from {0}", linkify(updateURL)) + "</b>");
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Selected update URL: " + updateURL);
|
||||
|
||||
// Check the first 56 bytes for the version
|
||||
if (shouldProxy) {
|
||||
// FIXME PartialEepGet works with clearnet but not with SSL
|
||||
_newVersion = null;
|
||||
if (!isSSL) {
|
||||
_isPartial = true;
|
||||
_baos.reset();
|
||||
try {
|
||||
@ -157,6 +219,8 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
if (shouldProxy)
|
||||
// 40 retries!!
|
||||
_get = new EepGet(_context, proxyHost, proxyPort, 40, _updateFile, updateURL, false);
|
||||
else if (isSSL)
|
||||
_get = new SSLEepGet(_context, _updateFile, updateURL);
|
||||
else
|
||||
_get = new EepGet(_context, 1, _updateFile, updateURL, false);
|
||||
_get.addStatusListener(UpdateRunner.this);
|
||||
@ -208,6 +272,9 @@ class UpdateRunner extends I2PAppThread implements UpdateTask, EepGet.StatusList
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME if we didn't do a partial, we don't know
|
||||
if (_newVersion == null)
|
||||
_newVersion = "unknown";
|
||||
File tmp = new File(_updateFile);
|
||||
if (_mgr.notifyComplete(this, _newVersion, tmp))
|
||||
this.done = true;
|
||||
|
@ -14,8 +14,6 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
private static final String HOPS = ngettext("1 hop", "{0} hops");
|
||||
private static final String TUNNELS = ngettext("1 tunnel", "{0} tunnels");
|
||||
|
||||
static final String PROP_ADVANCED = "routerconsole.advanced";
|
||||
|
||||
public String getForm() {
|
||||
StringBuilder buf = new StringBuilder(1024);
|
||||
// HTML: <input> cannot be inside a <table>
|
||||
@ -69,7 +67,7 @@ public class ConfigTunnelsHelper extends HelperBase {
|
||||
|
||||
private void renderForm(StringBuilder buf, int index, String prefix, String name, TunnelPoolSettings in, TunnelPoolSettings out) {
|
||||
|
||||
boolean advanced = _context.getBooleanProperty(PROP_ADVANCED);
|
||||
boolean advanced = isAdvanced();
|
||||
|
||||
buf.append("<tr><th colspan=\"3\"><a name=\"").append(prefix).append("\">");
|
||||
buf.append(name).append("</a></th></tr>\n");
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ -22,6 +23,7 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
private String _proxyHost;
|
||||
private String _proxyPort;
|
||||
private boolean _updateThroughProxy;
|
||||
private boolean _newsThroughProxy;
|
||||
private String _trustedKeys;
|
||||
private boolean _updateUnsigned;
|
||||
private String _zipURL;
|
||||
@ -36,7 +38,11 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
public static final String PROP_UPDATE_POLICY = "router.updatePolicy";
|
||||
public static final String DEFAULT_UPDATE_POLICY = "download";
|
||||
public static final String PROP_SHOULD_PROXY = "router.updateThroughProxy";
|
||||
public static final String DEFAULT_SHOULD_PROXY = Boolean.TRUE.toString();
|
||||
public static final boolean DEFAULT_SHOULD_PROXY = true;
|
||||
/** @since 0.9.9 */
|
||||
public static final String PROP_SHOULD_PROXY_NEWS = "router.fetchNewsThroughProxy";
|
||||
/** @since 0.9.9 */
|
||||
public static final boolean DEFAULT_SHOULD_PROXY_NEWS = true;
|
||||
public static final String PROP_PROXY_HOST = "router.updateProxyHost";
|
||||
public static final String DEFAULT_PROXY_HOST = "127.0.0.1";
|
||||
public static final String PROP_PROXY_PORT = "router.updateProxyPort";
|
||||
@ -50,6 +56,7 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
public static final String PROP_ZIP_URL = "router.updateUnsignedURL";
|
||||
|
||||
public static final String PROP_UPDATE_URL = "router.updateURL";
|
||||
|
||||
/**
|
||||
* Changed as of release 0.8 to support both .sud and .su2
|
||||
* Some JVMs (IcedTea) don't have pack200
|
||||
@ -75,6 +82,10 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
"http://update.killyourtv.i2p/i2pupdate.sud\r\n" +
|
||||
"http://update.postman.i2p/i2pupdate.sud" ;
|
||||
|
||||
/**
|
||||
* These are only for .sud and .su2.
|
||||
* Do NOT use this for .su3
|
||||
*/
|
||||
public static final String DEFAULT_UPDATE_URL;
|
||||
static {
|
||||
if (FileUtil.isPack200Supported())
|
||||
@ -83,6 +94,34 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
DEFAULT_UPDATE_URL = NO_PACK200_URLS;
|
||||
}
|
||||
|
||||
private static final String SU3_CERT_DIR = "certificates/router";
|
||||
|
||||
/**
|
||||
* Only enabled if we have pack200 and trusted public key certificates installed
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public static final boolean USE_SU3_UPDATE;
|
||||
static {
|
||||
String[] files = (new File(I2PAppContext.getGlobalContext().getBaseDir(), SU3_CERT_DIR)).list();
|
||||
USE_SU3_UPDATE = FileUtil.isPack200Supported() && files != null && files.length > 0;
|
||||
}
|
||||
|
||||
private static final String DEFAULT_SU3_UPDATE_URLS =
|
||||
"http://echelon.i2p/i2p/i2pupdate.su3\r\n" +
|
||||
"http://inr.i2p/i2p/i2pupdate.su3\r\n" +
|
||||
"http://meeh.i2p/i2pupdate/i2pupdate.su3\r\n" +
|
||||
"http://stats.i2p/i2p/i2pupdate.su3\r\n" +
|
||||
"http://www.i2p2.i2p/_static/i2pupdate.su3\r\n" +
|
||||
"http://update.dg.i2p/files/i2pupdate.su3\r\n" +
|
||||
"http://update.killyourtv.i2p/i2pupdate.su3\r\n" +
|
||||
"http://update.postman.i2p/i2pupdate.su3" ;
|
||||
|
||||
/**
|
||||
* Empty string if disabled. Cannot be overridden by config.
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public static final String SU3_UPDATE_URLS = USE_SU3_UPDATE ? DEFAULT_SU3_UPDATE_URLS : "";
|
||||
|
||||
public static final String PROP_TRUSTED_KEYS = "router.trustedUpdateKeys";
|
||||
|
||||
/**
|
||||
@ -130,6 +169,8 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
Map<String, String> changes = new HashMap();
|
||||
|
||||
if ( (_newsURL != null) && (_newsURL.length() > 0) ) {
|
||||
if (_newsURL.startsWith("https"))
|
||||
_newsThroughProxy = false;
|
||||
String oldURL = ConfigUpdateHelper.getNewsURL(_context);
|
||||
if ( (oldURL == null) || (!_newsURL.equals(oldURL)) ) {
|
||||
changes.put(PROP_NEWS_URL, _newsURL);
|
||||
@ -155,8 +196,9 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
}
|
||||
}
|
||||
|
||||
changes.put(PROP_SHOULD_PROXY, "" + _updateThroughProxy);
|
||||
changes.put(PROP_UPDATE_UNSIGNED, "" + _updateUnsigned);
|
||||
changes.put(PROP_SHOULD_PROXY, Boolean.toString(_updateThroughProxy));
|
||||
changes.put(PROP_SHOULD_PROXY_NEWS, Boolean.toString(_newsThroughProxy));
|
||||
changes.put(PROP_UPDATE_UNSIGNED, Boolean.toString(_updateUnsigned));
|
||||
|
||||
String oldFreqStr = _context.getProperty(PROP_REFRESH_FREQUENCY, DEFAULT_REFRESH_FREQUENCY);
|
||||
long oldFreq = DEFAULT_REFRESH_FREQ;
|
||||
@ -218,4 +260,6 @@ public class ConfigUpdateHandler extends FormHandler {
|
||||
public void setProxyPort(String port) { _proxyPort = port; }
|
||||
public void setUpdateUnsigned(String foo) { _updateUnsigned = true; }
|
||||
public void setZipURL(String url) { _zipURL = url; }
|
||||
/** @since 0.9.9 */
|
||||
public void setNewsThroughProxy(String foo) { _newsThroughProxy = true; }
|
||||
}
|
||||
|
@ -73,13 +73,20 @@ public class ConfigUpdateHelper extends HelperBase {
|
||||
}
|
||||
|
||||
public String getUpdateThroughProxy() {
|
||||
String proxy = _context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY);
|
||||
if (Boolean.parseBoolean(proxy))
|
||||
if (_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY))
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateThroughProxy\" checked=\"checked\" >";
|
||||
else
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateThroughProxy\" >";
|
||||
}
|
||||
|
||||
/** @since 0.9.9 */
|
||||
public String getNewsThroughProxy() {
|
||||
if (_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY_NEWS, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY_NEWS))
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"newsThroughProxy\" checked=\"checked\" >";
|
||||
else
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"newsThroughProxy\" >";
|
||||
}
|
||||
|
||||
public String getUpdateUnsigned() {
|
||||
if (_context.getBooleanProperty(ConfigUpdateHandler.PROP_UPDATE_UNSIGNED))
|
||||
return "<input type=\"checkbox\" class=\"optbox\" value=\"true\" name=\"updateUnsigned\" checked=\"checked\" >";
|
||||
|
@ -11,6 +11,8 @@ public abstract class HelperBase {
|
||||
protected RouterContext _context;
|
||||
protected Writer _out;
|
||||
|
||||
static final String PROP_ADVANCED = "routerconsole.advanced";
|
||||
|
||||
/**
|
||||
* Configure this bean to query a particular router context
|
||||
*
|
||||
@ -25,6 +27,11 @@ public abstract class HelperBase {
|
||||
}
|
||||
}
|
||||
|
||||
/** @since 0.9.9 */
|
||||
public boolean isAdvanced() {
|
||||
return _context.getBooleanProperty(PROP_ADVANCED);
|
||||
}
|
||||
|
||||
/** might be useful in the jsp's */
|
||||
//public RouterContext getContext() { return _context; }
|
||||
|
||||
|
@ -49,6 +49,7 @@ public class NewsHelper extends ContentHelper {
|
||||
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||
if (mgr == null) return false;
|
||||
return mgr.isUpdateInProgress(ROUTER_SIGNED) ||
|
||||
mgr.isUpdateInProgress(ROUTER_SIGNED_SU3) ||
|
||||
mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
|
||||
mgr.isUpdateInProgress(TYPE_DUMMY);
|
||||
}
|
||||
@ -60,7 +61,8 @@ public class NewsHelper extends ContentHelper {
|
||||
public static boolean isUpdateAvailable() {
|
||||
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||
if (mgr == null) return false;
|
||||
return mgr.getUpdateAvailable(ROUTER_SIGNED) != null;
|
||||
return mgr.getUpdateAvailable(ROUTER_SIGNED) != null ||
|
||||
mgr.getUpdateAvailable(ROUTER_SIGNED_SU3) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,6 +73,9 @@ public class NewsHelper extends ContentHelper {
|
||||
public static String updateVersion() {
|
||||
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||
if (mgr == null) return null;
|
||||
String rv = mgr.getUpdateAvailable(ROUTER_SIGNED_SU3);
|
||||
if (rv != null)
|
||||
return rv;
|
||||
return mgr.getUpdateAvailable(ROUTER_SIGNED);
|
||||
}
|
||||
|
||||
@ -93,6 +98,9 @@ public class NewsHelper extends ContentHelper {
|
||||
public static String updateVersionDownloaded() {
|
||||
ConsoleUpdateManager mgr = ConsoleUpdateManager.getInstance();
|
||||
if (mgr == null) return null;
|
||||
String rv = mgr.getUpdateDownloaded(ROUTER_SIGNED_SU3);
|
||||
if (rv != null)
|
||||
return rv;
|
||||
return mgr.getUpdateDownloaded(ROUTER_SIGNED);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,37 @@
|
||||
package net.i2p.router.web;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import net.i2p.data.Signature;
|
||||
|
||||
/**
|
||||
* Sign a statement about this router.
|
||||
* @since 0.9.8
|
||||
*/
|
||||
public class ProofHelper extends HelperBase {
|
||||
|
||||
public String getProof() {
|
||||
StringBuilder buf = new StringBuilder(512);
|
||||
RouterInfo us = _context.router().getRouterInfo();
|
||||
buf.append("Hash: ").append(us.getIdentity().calculateHash().toBase64()).append('\n');
|
||||
//buf.append("Ident: ").append(us.getIdentity().toBase64()).append('\n');
|
||||
for (RouterAddress addr : us.getAddresses()) {
|
||||
buf.append(addr.getTransportStyle()).append(": ").append(addr.getHost()).append('\n');
|
||||
}
|
||||
buf.append("Caps: ").append(us.getCapabilities()).append('\n');
|
||||
buf.append("Date: ").append(new Date()); // no trailing newline
|
||||
String msg = buf.toString();
|
||||
byte[] data = DataHelper.getUTF8(msg);
|
||||
Signature sig = _context.dsa().sign(data, _context.keyManager().getSigningPrivateKey());
|
||||
buf.setLength(0);
|
||||
buf.append("---BEGIN I2P SIGNED MESSAGE---\n");
|
||||
buf.append(msg);
|
||||
buf.append("\n---BEGIN I2P SIGNATURE---\n");
|
||||
buf.append(sig.toBase64());
|
||||
buf.append("\n---END I2P SIGNATURE---");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ 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.crypto.KeyStoreUtil;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.jetty.I2PLogger;
|
||||
@ -38,8 +39,6 @@ import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.I2PAppThread;
|
||||
import net.i2p.util.PortMapper;
|
||||
import net.i2p.util.SecureDirectory;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
import net.i2p.util.ShellCommand;
|
||||
import net.i2p.util.SystemVersion;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
@ -677,12 +676,6 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
System.err.println("Console SSL error, must set " + PROP_KEY_PASSWORD + " in " + (new File(_context.getConfigDir(), "router.config")).getAbsolutePath());
|
||||
return rv;
|
||||
}
|
||||
File dir = ks.getParentFile();
|
||||
if (!dir.exists()) {
|
||||
File sdir = new SecureDirectory(dir.getAbsolutePath());
|
||||
if (!sdir.mkdir())
|
||||
return false;
|
||||
}
|
||||
return createKeyStore(ks);
|
||||
}
|
||||
|
||||
@ -697,31 +690,13 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
*/
|
||||
private boolean createKeyStore(File ks) {
|
||||
// make a random 48 character password (30 * 8 / 5)
|
||||
byte[] rand = new byte[30];
|
||||
_context.random().nextBytes(rand);
|
||||
String keyPassword = Base32.encode(rand);
|
||||
String keyPassword = KeyStoreUtil.randomString();
|
||||
// and one for the cname
|
||||
_context.random().nextBytes(rand);
|
||||
String cname = Base32.encode(rand) + ".console.i2p.net";
|
||||
|
||||
String keytool = (new File(System.getProperty("java.home"), "bin/keytool")).getAbsolutePath();
|
||||
String[] args = new String[] {
|
||||
keytool,
|
||||
"-genkey", // -genkeypair preferred in newer keytools, but this works with more
|
||||
"-storetype", KeyStore.getDefaultType(),
|
||||
"-keystore", ks.getAbsolutePath(),
|
||||
"-storepass", DEFAULT_KEYSTORE_PASSWORD,
|
||||
"-alias", "console",
|
||||
"-dname", "CN=" + cname + ",OU=Console,O=I2P Anonymous Network,L=XX,ST=XX,C=XX",
|
||||
"-validity", "3652", // 10 years
|
||||
"-keyalg", "DSA",
|
||||
"-keysize", "1024",
|
||||
"-keypass", keyPassword};
|
||||
boolean success = (new ShellCommand()).executeSilentAndWaitTimed(args, 30); // 30 secs
|
||||
String cname = KeyStoreUtil.randomString() + ".console.i2p.net";
|
||||
boolean success = KeyStoreUtil.createKeys(ks, "console", cname, "Console", keyPassword);
|
||||
if (success) {
|
||||
success = ks.exists();
|
||||
if (success) {
|
||||
SecureFileOutputStream.setPerms(ks);
|
||||
try {
|
||||
Map<String, String> changes = new HashMap();
|
||||
changes.put(PROP_KEYSTORE_PASSWORD, DEFAULT_KEYSTORE_PASSWORD);
|
||||
@ -735,13 +710,8 @@ public class RouterConsoleRunner implements RouterApp {
|
||||
"The certificate name was generated randomly, and is not associated with your " +
|
||||
"IP address, host name, router identity, or destination keys.");
|
||||
} else {
|
||||
System.err.println("Failed to create console SSL keystore using command line:");
|
||||
StringBuilder buf = new StringBuilder(256);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
buf.append('"').append(args[i]).append("\" ");
|
||||
}
|
||||
System.err.println(buf.toString());
|
||||
System.err.println("This is for the Sun/Oracle keytool, others may be incompatible.\n" +
|
||||
System.err.println("Failed to create console SSL keystore.\n" +
|
||||
"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 +
|
||||
" to " + (new File(_context.getConfigDir(), "router.config")).getAbsolutePath());
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ public class TunnelRenderer {
|
||||
Map<Hash, TunnelPool> clientInboundPools = _context.tunnelManager().getInboundClientPools();
|
||||
Map<Hash, TunnelPool> clientOutboundPools = _context.tunnelManager().getOutboundClientPools();
|
||||
destinations = new ArrayList(clientInboundPools.keySet());
|
||||
boolean debug = _context.getBooleanProperty(ConfigTunnelsHelper.PROP_ADVANCED);
|
||||
boolean debug = _context.getBooleanProperty(HelperBase.PROP_ADVANCED);
|
||||
for (int i = 0; i < destinations.size(); i++) {
|
||||
Hash client = destinations.get(i);
|
||||
boolean isLocal = _context.clientManager().isLocal(client);
|
||||
|
@ -66,6 +66,8 @@ public class UpdateHandler {
|
||||
_nonce.equals(System.getProperty("net.i2p.router.web.UpdateHandler.noncePrev"))) {
|
||||
if (_action.contains("Unsigned")) {
|
||||
update(ROUTER_UNSIGNED);
|
||||
} else if (ConfigUpdateHandler.USE_SU3_UPDATE) {
|
||||
update(ROUTER_SIGNED_SU3);
|
||||
} else {
|
||||
update(ROUTER_SIGNED);
|
||||
}
|
||||
@ -76,7 +78,8 @@ public class UpdateHandler {
|
||||
ConsoleUpdateManager mgr = (ConsoleUpdateManager) _context.updateManager();
|
||||
if (mgr == null)
|
||||
return;
|
||||
if (mgr.isUpdateInProgress(ROUTER_SIGNED) || mgr.isUpdateInProgress(ROUTER_UNSIGNED)) {
|
||||
if (mgr.isUpdateInProgress(ROUTER_SIGNED) || mgr.isUpdateInProgress(ROUTER_UNSIGNED) ||
|
||||
mgr.isUpdateInProgress(ROUTER_SIGNED_SU3)) {
|
||||
_log.error("Update already running");
|
||||
return;
|
||||
}
|
||||
|
@ -48,18 +48,24 @@
|
||||
<tr><td class="mediumtags" align="right"><b><%=formhandler._("Update policy")%>:</b></td>
|
||||
<td><jsp:getProperty name="updatehelper" property="updatePolicySelectBox" /></td></tr>
|
||||
<% } // if canInstall %>
|
||||
<tr><td class="mediumtags" align="right"><b><%=intl._("Fetch news through the eepProxy?")%></b></td>
|
||||
<td><jsp:getProperty name="updatehelper" property="newsThroughProxy" /></td></tr>
|
||||
<tr><td class="mediumtags" align="right"><b><%=intl._("Update through the eepProxy?")%></b></td>
|
||||
<td><jsp:getProperty name="updatehelper" property="updateThroughProxy" /></td>
|
||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("eepProxy host")%>:</b></td>
|
||||
<td><jsp:getProperty name="updatehelper" property="updateThroughProxy" /></td></tr>
|
||||
<% if (updatehelper.isAdvanced()) { %>
|
||||
<tr><td class="mediumtags" align="right"><b><%=intl._("eepProxy host")%>:</b></td>
|
||||
<td><input type="text" size="10" name="proxyHost" value="<jsp:getProperty name="updatehelper" property="proxyHost" />" /></td>
|
||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("eepProxy port")%>:</b></td>
|
||||
<td><input type="text" size="10" name="proxyPort" value="<jsp:getProperty name="updatehelper" property="proxyPort" />" /></td></tr>
|
||||
<% } // if isAdvanced %>
|
||||
<% if (updatehelper.canInstall()) { %>
|
||||
<% if (updatehelper.isAdvanced()) { %>
|
||||
<tr><td class="mediumtags" align="right"><b><%=intl._("Update URLs")%>:</b></td>
|
||||
<td><textarea cols="60" rows="6" name="updateURL" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="updateURL" /></textarea></td>
|
||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("Trusted keys")%>:</b></td>
|
||||
<td><textarea cols="60" rows="6" name="trustedKeys" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="trustedKeys" /></textarea></td>
|
||||
</tr><tr><td id="unsignedbuild" class="mediumtags" align="right"><b><%=intl._("Update with unsigned development builds?")%></b></td>
|
||||
<td><textarea cols="60" rows="6" name="trustedKeys" wrap="off" spellcheck="false"><jsp:getProperty name="updatehelper" property="trustedKeys" /></textarea></td></tr>
|
||||
<% } // if isAdvanced %>
|
||||
<tr><td id="unsignedbuild" class="mediumtags" align="right"><b><%=intl._("Update with unsigned development builds?")%></b></td>
|
||||
<td><jsp:getProperty name="updatehelper" property="updateUnsigned" /></td>
|
||||
</tr><tr><td class="mediumtags" align="right"><b><%=intl._("Unsigned Build URL")%>:</b></td>
|
||||
<td><input type="text" size="60" name="zipURL" value="<jsp:getProperty name="updatehelper" property="zipURL" />"></td></tr>
|
||||
|
16
apps/routerconsole/jsp/proof.jsp
Normal file
16
apps/routerconsole/jsp/proof.jsp
Normal file
@ -0,0 +1,16 @@
|
||||
<%@page contentType="text/html"%>
|
||||
<%@page pageEncoding="UTF-8"%>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
|
||||
<html><head>
|
||||
<%@include file="css.jsi" %>
|
||||
<%=intl.title("Proof")%>
|
||||
<script src="/js/ajax.js" type="text/javascript"></script>
|
||||
<%@include file="summaryajax.jsi" %>
|
||||
</head><body onload="initAjax()">
|
||||
<%@include file="summary.jsi" %><h1>Proof of Ownership</h1>
|
||||
<div class="main" id="main">
|
||||
<jsp:useBean class="net.i2p.router.web.ProofHelper" id="proofHelper" scope="request" />
|
||||
<jsp:setProperty name="proofHelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
|
||||
<textarea cols="70" rows="15" wrap="off" readonly="readonly" spellcheck="false"><jsp:getProperty name="proofHelper" property="proof" /></textarea>
|
||||
</div></body></html>
|
@ -3,13 +3,15 @@
|
||||
# This file is distributed under the same license as the routerconsole package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# Ashoka <martin2p@posteo.de>, 2013
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-07-13 21:46+0000\n"
|
||||
"PO-Revision-Date: 2013-05-08 15:06+0000\n"
|
||||
"Last-Translator: zeroflag <zeroflag@i2pmail.org>\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:25+0000\n"
|
||||
"PO-Revision-Date: 2013-09-16 07:09+0000\n"
|
||||
"Last-Translator: Ashoka <martin2p@posteo.de>\n"
|
||||
"Language-Team: German (http://www.transifex.com/projects/p/I2P/language/"
|
||||
"de/)\n"
|
||||
"Language: de\n"
|
||||
@ -26,39 +28,51 @@ msgstr "Willkommen im I2P!"
|
||||
|
||||
#, java-format
|
||||
msgid "Please {0}have patience{1} as I2P boots up and finds peers."
|
||||
msgstr "Hab noch {0}etwas Geduld{1}, während I2P startet und weitere I2P-Router findet."
|
||||
msgstr ""
|
||||
"Hab noch {0}etwas Geduld{1}, während I2P startet und weitere I2P-Router "
|
||||
"findet."
|
||||
|
||||
#, java-format
|
||||
msgid ""
|
||||
"While you are waiting, please {0}adjust your bandwidth settings{1} on the {2}"
|
||||
"configuration page{3}."
|
||||
msgstr "Passe bitte in der Zwischenzeit {0}deine Einstellungen zur Bandbreite{1} auf der"
|
||||
"{2}Einstellungsseite{3} an!"
|
||||
msgstr ""
|
||||
"Passe bitte in der Zwischenzeit {0}deine Einstellungen zur Bandbreite{1} auf "
|
||||
"der{2}Einstellungsseite{3} an!"
|
||||
|
||||
msgid "Also you can setup your browser to use the I2P proxy to reach eepsites."
|
||||
msgstr "Auch kannst Du gleich deinen Browser für die Nutzung von I2P einrichten."
|
||||
msgstr ""
|
||||
"Auch kannst Du gleich deinen Browser für die Nutzung von I2P einrichten."
|
||||
|
||||
msgid ""
|
||||
"Just enter 127.0.0.1 (or localhost) port 4444 as a http proxy into your "
|
||||
"browser settings."
|
||||
msgstr "Setze in den Einstellungen zum Browser ein HTTP Proxy ein mit 127.0.0.1 (oder localhost) mit Port 4444 als Ziel."
|
||||
msgstr ""
|
||||
"Setze in den Einstellungen zum Browser ein HTTP Proxy ein mit 127.0.0.1 "
|
||||
"(oder localhost) mit Port 4444 als Ziel."
|
||||
|
||||
msgid "Do not use SOCKS for this."
|
||||
msgstr ""
|
||||
msgstr "Benutze keine SOCKS dafür."
|
||||
|
||||
#, java-format
|
||||
msgid ""
|
||||
"More information can be found on the {0}I2P browser proxy setup page{1}."
|
||||
msgstr "Mehr Informationen gibt es auf der {0}I2P browser proxy Setup Seite{1}."
|
||||
msgstr ""
|
||||
"Mehr Informationen gibt es auf der {0}I2P browser proxy Setup Seite{1}."
|
||||
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Once you have a \"shared clients\" destination listed on the left, please {0}"
|
||||
"check out{1} our {2}FAQ{3}."
|
||||
msgstr "Sobald auf der linken Seite eine Verbindung namens \"versch. Klienten\" aufgelistet ist, kannst Du unsere {0}{1} {2}FAQ{3} besuchen."
|
||||
msgstr ""
|
||||
"Sobald auf der linken Seite eine Verbindung namens \"versch. Klienten\" "
|
||||
"aufgelistet ist, kannst Du unsere {0}{1} {2}FAQ{3} besuchen."
|
||||
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Point your IRC client to {0}localhost:6668{1} and say hi to us on {2}#i2p-"
|
||||
"help{3} or {4}#i2p{5}."
|
||||
msgstr "Verbinde deinen IRC-Klienten mit dem Server auf {0}localhost:6668{1} und schau bei uns im Kanal <a href=\"irc://127.0.0.1:6668/i2p-de\">#i2p-de</a>, {2}#i2p-help{3} oder {4}#i2p{5} vorbei!"
|
||||
msgstr ""
|
||||
"Verbinde deinen IRC-Klienten mit dem Server auf {0}localhost:6668{1} und "
|
||||
"schau bei uns im Kanal <a href=\"irc://127.0.0.1:6668/i2p-de\">#i2p-de</a>, "
|
||||
"{2}#i2p-help{3} oder {4}#i2p{5} vorbei!"
|
||||
|
@ -4,15 +4,16 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# Boxoa590, 2013
|
||||
# foo <foo@bar>, 2009
|
||||
# Boxoa590, 2013
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-08-11 15:43+0000\n"
|
||||
"PO-Revision-Date: 2013-07-22 20:37+0000\n"
|
||||
"Last-Translator: Boxoa590\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:24+0000\n"
|
||||
"PO-Revision-Date: 2013-08-11 15:50+0000\n"
|
||||
"Last-Translator: kytv <killyourtv@i2pmail.org>\n"
|
||||
"Language-Team: French (http://www.transifex.com/projects/p/I2P/language/"
|
||||
"fr/)\n"
|
||||
"Language: fr\n"
|
||||
|
@ -3,13 +3,16 @@
|
||||
# This file is distributed under the same license as the routerconsole package.
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# hottuna <i2p@robertfoss.se>, 2013
|
||||
# hottuna <i2p@robertfoss.se>, 2013
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-07-13 21:46+0000\n"
|
||||
"PO-Revision-Date: 2013-01-03 09:01+0000\n"
|
||||
"Last-Translator: mon <mattias.ohlsson@inprose.com>\n"
|
||||
"POT-Creation-Date: 2013-09-26 21:42+0000\n"
|
||||
"PO-Revision-Date: 2013-09-26 06:40+0000\n"
|
||||
"Last-Translator: hottuna <i2p@robertfoss.se>\n"
|
||||
"Language-Team: Swedish (Sweden) (http://www.transifex.com/projects/p/I2P/"
|
||||
"language/sv_SE/)\n"
|
||||
"Language: sv_SE\n"
|
||||
@ -19,7 +22,7 @@ msgstr ""
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
msgid "Congratulations on getting I2P installed!"
|
||||
msgstr ""
|
||||
msgstr "Grattis för din I2P installation!"
|
||||
|
||||
msgid "Welcome to I2P!"
|
||||
msgstr "Välkommen till I2P!"
|
||||
@ -32,32 +35,43 @@ msgstr "{0}Ha tålamod{1} medan I2P startar upp och letar upp peers."
|
||||
msgid ""
|
||||
"While you are waiting, please {0}adjust your bandwidth settings{1} on the {2}"
|
||||
"configuration page{3}."
|
||||
msgstr "Medan du väntar, var god {0}ställ in dina bandbreddd och port inställningar{1} på {2}konfigurations-sidan{3}."
|
||||
msgstr ""
|
||||
"Medan du väntar, var god {0}ställ in dina bandbreddd och port "
|
||||
"inställningar{1} på {2}konfigurations-sidan{3}."
|
||||
|
||||
msgid "Also you can setup your browser to use the I2P proxy to reach eepsites."
|
||||
msgstr ""
|
||||
"Du kan även ställa in din webbläsare till att använda I2P-proxyn för att nå "
|
||||
"eepsidor."
|
||||
|
||||
msgid ""
|
||||
"Just enter 127.0.0.1 (or localhost) port 4444 as a http proxy into your "
|
||||
"browser settings."
|
||||
msgstr ""
|
||||
"Skriv in 127.0.0.1 (eller localhost) port 4444 som en http-proxy i din "
|
||||
"webbläsares inställningar."
|
||||
|
||||
msgid "Do not use SOCKS for this."
|
||||
msgstr ""
|
||||
msgstr "Använd inte SOCKS för detta."
|
||||
|
||||
#, java-format
|
||||
msgid ""
|
||||
"More information can be found on the {0}I2P browser proxy setup page{1}."
|
||||
msgstr ""
|
||||
"Mer information kan hittsa på {0}I2P webbläsar-proxy inställnings sidan{1}."
|
||||
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Once you have a \"shared clients\" destination listed on the left, please {0}"
|
||||
"check out{1} our {2}FAQ{3}."
|
||||
msgstr "När du har en \"delade klienter\" distination listad på vänster sida, {0}kika på{1} vår {2}FAQ{3}."
|
||||
msgstr ""
|
||||
"När du har en \"delade klienter\" distination listad på vänster sida, {0}"
|
||||
"kika på{1} vår {2}FAQ{3}."
|
||||
|
||||
#, java-format
|
||||
msgid ""
|
||||
"Point your IRC client to {0}localhost:6668{1} and say hi to us on {2}#i2p-"
|
||||
"help{3} or {4}#i2p{5}."
|
||||
msgstr "Rikta din IRC-klient till {0}localhost:6668{1} och säg hej till oss på {2}#i2p-help{3} eller {4}#i2p{5}."
|
||||
msgstr ""
|
||||
"Rikta din IRC-klient till {0}localhost:6668{1} och säg hej till oss på {2}"
|
||||
"#i2p-help{3} eller {4}#i2p{5}."
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -204,7 +204,7 @@ public class I2PSocketManagerFull implements I2PSocketManager {
|
||||
|
||||
private void verifySession() throws I2PException {
|
||||
if (_isDestroyed.get())
|
||||
throw new I2PException("destroyed");
|
||||
throw new I2PException("Session was closed");
|
||||
if (!_connectionManager.getSession().isClosed())
|
||||
return;
|
||||
_connectionManager.getSession().connect();
|
||||
|
@ -4,27 +4,29 @@
|
||||
# To contribute translations, see http://www.i2p2.de/newdevelopers
|
||||
#
|
||||
# Translators:
|
||||
# <ducki2p@gmail.com>, 2011.
|
||||
# Martin Svensson <digitalmannen@gmail.com>, 2011, 2012.
|
||||
# ducki2p <ducki2p@gmail.com>, 2011
|
||||
# hottuna <i2p@robertfoss.se>, 2013
|
||||
# hottuna <i2p@robertfoss.se>, 2012
|
||||
# Martin Svensson <digitalmannen@gmail.com>, 2011, 2012
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-04-25 14:51+0000\n"
|
||||
"PO-Revision-Date: 2012-07-23 16:33+0000\n"
|
||||
"Last-Translator: Martin Svensson <digitalmannen@gmail.com>\n"
|
||||
"POT-Creation-Date: 2013-09-26 21:43+0000\n"
|
||||
"PO-Revision-Date: 2013-09-26 07:31+0000\n"
|
||||
"Last-Translator: hottuna <i2p@robertfoss.se>\n"
|
||||
"Language-Team: Swedish (Sweden) (http://www.transifex.com/projects/p/I2P/"
|
||||
"language/sv_SE/)\n"
|
||||
"Language: sv_SE\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"
|
||||
"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 " Värdnamn \"{0}\" innehåller ogiltigttecken {1}"
|
||||
msgstr " Värdnamn \"{0}\" innehåller ogiltiga tecken {1}"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressBean.java:143
|
||||
#: ../src/java/src/i2p/susi/dns/AddressBean.java:145
|
||||
@ -55,7 +57,7 @@ msgstr ""
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressBean.java:218
|
||||
msgid "None"
|
||||
msgstr "Ingen"
|
||||
msgstr "Inga"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressBean.java:226
|
||||
msgid "Hashcash"
|
||||
@ -63,7 +65,7 @@ msgstr "Hashcash"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressBean.java:228
|
||||
msgid "Hidden"
|
||||
msgstr "Dold"
|
||||
msgstr "Gömd"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressBean.java:230
|
||||
msgid "Signed"
|
||||
@ -79,7 +81,7 @@ msgstr "Typ {0}"
|
||||
msgid "One result for search within filtered list."
|
||||
msgid_plural "{0} results for search within filtered list."
|
||||
msgstr[0] "Ett resultat för sökning i filtrerlistan."
|
||||
msgstr[1] "{0} resultat för sökning i filtrerlistan ."
|
||||
msgstr[1] "{0} resultat för sökning i filtrerlistan."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:206
|
||||
#, java-format
|
||||
@ -93,7 +95,7 @@ msgstr[1] "Filtrerlistan innehåller {0} poster."
|
||||
msgid "One result for search."
|
||||
msgid_plural "{0} results for search."
|
||||
msgstr[0] "Ett resultat på sökningen."
|
||||
msgstr[1] "{0} resultat på sökningen."
|
||||
msgstr[1] "{0} resultat till sökningen."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:220
|
||||
#, java-format
|
||||
@ -141,13 +143,13 @@ msgstr ""
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:253
|
||||
#, java-format
|
||||
msgid "Destination added for {0}."
|
||||
msgstr "Mål till lagt för {0}."
|
||||
msgstr "Mål tillagt för {0}."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:285
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:255
|
||||
#, java-format
|
||||
msgid "Destination changed for {0}."
|
||||
msgstr "Målet ändrat för {0}."
|
||||
msgstr "Mål ändrat för {0}."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:287
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:257
|
||||
@ -157,7 +159,7 @@ msgstr "Varning - värdnamn slutar inte med \".i2p\""
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:292
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:265
|
||||
msgid "Invalid Base 64 destination."
|
||||
msgstr "Ogiltigt Base 64 mål"
|
||||
msgstr "Ogiltigt Base64 mål."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:298
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:271
|
||||
@ -168,7 +170,7 @@ msgstr "Ogiltigt värdnamn \"{0}\"."
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:301
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:274
|
||||
msgid "Please enter a host name and destination"
|
||||
msgstr "Ange värdnamn och destination"
|
||||
msgstr "Ange värdnamn och mål"
|
||||
|
||||
#. clear search when deleting
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:305
|
||||
@ -183,14 +185,14 @@ msgstr "Ta bort post"
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:278
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:349
|
||||
msgid "Delete Selected"
|
||||
msgstr "Radera valda"
|
||||
msgstr "Radera Valda"
|
||||
|
||||
#. parameter is a host name
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:319
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:295
|
||||
#, java-format
|
||||
msgid "Destination {0} deleted."
|
||||
msgstr "mål {0} raderat."
|
||||
msgstr "Mål {0} raderat."
|
||||
|
||||
#. parameter will always be >= 2
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:322
|
||||
@ -204,7 +206,7 @@ msgstr[1] "{0} mål raderade."
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:324
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:300
|
||||
msgid "No entries selected to delete."
|
||||
msgstr "Inga uppgifter valda för radering."
|
||||
msgstr "Inga poster valda för radering."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:332
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:307
|
||||
@ -216,46 +218,47 @@ msgid "ERROR: Could not write addressbook file."
|
||||
msgstr "FEL: Kunde inte skriva till adressboks filen."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:340
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:149
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:140
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:311
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:128
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:142
|
||||
msgid ""
|
||||
"Invalid form submission, probably because you used the \"back\" or \"reload"
|
||||
"\" button on your browser. Please resubmit."
|
||||
msgstr ""
|
||||
"Felaktigt formulär, förmodligen för att du använde \"Bakåt \" eller "
|
||||
"\"Uppdaterings\" knappen i din webbläsare. Försök skicka igen."
|
||||
"Felaktigt formulär skickat, förmodligen för att du använde \"Bakåt \" eller "
|
||||
"\"Ladda Om\" knappen i din webbläsare. Försök skicka igen."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/AddressbookBean.java:342
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:151
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:142
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:313
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:130
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:144
|
||||
msgid ""
|
||||
"If the problem persists, verify that you have cookies enabled in your "
|
||||
"browser."
|
||||
msgstr ""
|
||||
"Om problemet kvarstår, bekräfta att du har cookies påslaget i din browser."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:140
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:103
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:131
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:117
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:153
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:145
|
||||
msgid "Save"
|
||||
msgstr "Spara"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:142
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:133
|
||||
msgid "Configuration saved."
|
||||
msgstr "Inställningarna sparas."
|
||||
msgstr "Inställningar sparade."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:143
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:122
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:134
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:136
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:151
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:143
|
||||
msgid "Reload"
|
||||
msgstr "Ladda om"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:145
|
||||
#: ../src/java/src/i2p/susi/dns/ConfigBean.java:136
|
||||
msgid "Configuration reloaded."
|
||||
msgstr "Konfiguration laddas om."
|
||||
msgstr "Inställningar laddade igen."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/NamingServiceBean.java:100
|
||||
#, java-format
|
||||
@ -276,23 +279,24 @@ msgstr "Kunde inte lägga till målet för {0} till namntjänsten {1}"
|
||||
msgid "Failed to delete Destination for {0} from naming service {1}"
|
||||
msgstr "Det gick inte att ta bort målet för {0} från namntjänsten {1}"
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:115
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:129
|
||||
msgid ""
|
||||
"Subscriptions saved, updating addressbook from subscription sources now."
|
||||
msgstr ""
|
||||
"Abonnemang sparade, uppdatering adressbok från abonnemangs källorna nu."
|
||||
"Prenumerationer sparade, uppdaterar adressbok från prenumerations-källorna "
|
||||
"nu."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:120
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:134
|
||||
msgid "Subscriptions saved."
|
||||
msgstr "Abonnemang sprade"
|
||||
msgstr "Prenumerationer sparade."
|
||||
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:124
|
||||
#: ../src/java/src/i2p/susi/dns/SubscriptionsBean.java:138
|
||||
msgid "Subscriptions reloaded."
|
||||
msgstr "Abonnemang laddas om."
|
||||
msgstr "Prenumerationer laddade igen."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:125
|
||||
msgid "address book"
|
||||
msgstr "adressboken"
|
||||
msgstr "adressbok"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:131
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:147
|
||||
@ -352,7 +356,7 @@ msgstr "publicerad"
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:126
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:129
|
||||
msgid "Subscriptions"
|
||||
msgstr "Abonnemang"
|
||||
msgstr "Prenumerationer"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:145
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:139
|
||||
@ -413,11 +417,11 @@ msgstr "Mål"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:286
|
||||
msgid "Mark for deletion"
|
||||
msgstr "Markera för att raderas"
|
||||
msgstr "Markera för borttagning"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:305
|
||||
msgid "Base 32 address"
|
||||
msgstr "Base 32 adress"
|
||||
msgstr "Base32 adress"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:309
|
||||
msgid "More information on this entry"
|
||||
@ -434,7 +438,7 @@ msgstr "Avbryt"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:381
|
||||
msgid "This address book is empty."
|
||||
msgstr "Denna adressbok är tom"
|
||||
msgstr "Denna adressboken är tom."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/addressbook_jsp.java:396
|
||||
msgid "Add new destination"
|
||||
@ -447,7 +451,7 @@ msgstr "Värdnamn"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:119
|
||||
msgid "configuration"
|
||||
msgstr "konfiguration"
|
||||
msgstr "inställningar"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:155
|
||||
msgid "Hints"
|
||||
@ -459,7 +463,7 @@ msgid ""
|
||||
"directory, which is normally ~/.i2p/addressbook/ (Linux) or %APPDATA%\\I2P"
|
||||
"\\addressbook\\ (Windows)."
|
||||
msgstr ""
|
||||
"Fil och katalog sökvägar anges här i förhållande till adressboken "
|
||||
"Fil och katalog sökvägar anges här i förhållande till adressbokens "
|
||||
"arbetskatalog, som normalt är ~/.i2p/addressbook/ (Linux) eller %APPDATA%"
|
||||
"\\I2P\\addressbook\\ (Windows)."
|
||||
|
||||
@ -484,15 +488,14 @@ msgid ""
|
||||
"When you publish your addressbook, ALL destinations from the master and "
|
||||
"router addressbooks appear there."
|
||||
msgstr ""
|
||||
"När du publicerar din adressbok, Kommer samtliga destinationer från master "
|
||||
"När du publicerar din adressbok, kommer samtliga destinationer från master "
|
||||
"och routerns adressböcker visas där."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:163
|
||||
msgid ""
|
||||
"Use the private addressbook for private destinations, these are not "
|
||||
"published."
|
||||
msgstr ""
|
||||
"Använd privata adressboken för privata mål, dessa inte publiceras inte."
|
||||
msgstr "Använd den privata adressboken för privata mål, dessa publiceras inte."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:165
|
||||
msgid "Options"
|
||||
@ -501,8 +504,8 @@ msgstr "Alternativ"
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:167
|
||||
msgid "File containing the list of subscriptions URLs (no need to change)"
|
||||
msgstr ""
|
||||
"Fil som innehåller en förteckning över prenumerations URLer (ingen anledning "
|
||||
"att ändra)"
|
||||
"Fil som innehåller en lista över prenumerations URLer (ingen anledning att "
|
||||
"ändra)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:169
|
||||
msgid "Update interval in hours"
|
||||
@ -513,11 +516,11 @@ msgid ""
|
||||
"Your public hosts.txt file (choose a path within your webserver document "
|
||||
"root)"
|
||||
msgstr ""
|
||||
"Din publika hosts.txt fil (välj en sökväg till din webbservers dokumentrot)"
|
||||
"Din publika hosts.txt fil (välj en sökväg till din webbservers dokumentrot)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:173
|
||||
msgid "Your hosts.txt (don't change)"
|
||||
msgstr "Din hosts.tx (ändra inte)"
|
||||
msgstr "Din hosts.txt (ändra inte)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:175
|
||||
msgid "Your personal addressbook, these hosts will be published"
|
||||
@ -529,11 +532,11 @@ msgstr "Din privata adressbok, den publiceras aldrig"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:179
|
||||
msgid "Port for your eepProxy (no need to change)"
|
||||
msgstr "Port för din eepProxy (du behöver inte ändra)"
|
||||
msgstr "Port för din eepProxy (den behöver inte ändras)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:181
|
||||
msgid "Hostname for your eepProxy (no need to change)"
|
||||
msgstr "Värd namn fär din eepProxy (du behöver inte ändra)"
|
||||
msgstr "Värdnamn för din eepProxy (den behöver inte ändras)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:183
|
||||
msgid "Whether to update the published addressbook"
|
||||
@ -544,20 +547,20 @@ msgid ""
|
||||
"File containing the etags header from the fetched subscription URLs (no need "
|
||||
"to change)"
|
||||
msgstr ""
|
||||
"Fil som innehåller etags header från hämtade prenumeration URLer (du behöver "
|
||||
"inte ändra)"
|
||||
"Fil som innehåller etags header från hämtade prenumeration URL:er (den "
|
||||
"behöver inte ändras)"
|
||||
|
||||
#: ../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 ""
|
||||
"Fil som innehåller en ändring tidsstämpeln för varje hämtade prenumeration "
|
||||
"URL (behävs inte ändras)"
|
||||
"Fil som innehåller en ändring-tidsstämpeln för varje hämtad prenumerations "
|
||||
"URL (den behöver inte ändras)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:189
|
||||
msgid "File to log activity to (change to /dev/null if you like)"
|
||||
msgstr "Fil loggaktivitet sparas till (ändra till / dev / null om du vill)"
|
||||
msgstr "Fil där loggaktivitet sparas till (ändra till / dev / null om du vill)"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/config_jsp.java:191
|
||||
msgid "Name of the theme to use (defaults to 'light')"
|
||||
@ -569,19 +572,19 @@ msgstr "adressbok"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:179
|
||||
msgid "Encoded Name"
|
||||
msgstr "Kodat namn"
|
||||
msgstr "Kodat Namn"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:193
|
||||
msgid "Base 32 Address"
|
||||
msgstr "Base 32 Adress"
|
||||
msgstr "Base32 Adress"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:201
|
||||
msgid "Base 64 Hash"
|
||||
msgstr "Bas 64 Hash"
|
||||
msgstr "Base64 Hash"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:207
|
||||
msgid "Address Helper"
|
||||
msgstr "Adress hjälp"
|
||||
msgstr "Adresshjälpare"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:213
|
||||
msgid "link"
|
||||
@ -589,7 +592,7 @@ msgstr "länk"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:217
|
||||
msgid "Public Key"
|
||||
msgstr "Publik nyckel"
|
||||
msgstr "Publik Nyckel"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:219
|
||||
msgid "ElGamal 2048 bit"
|
||||
@ -609,7 +612,7 @@ msgstr "Certifikat"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:235
|
||||
msgid "Added Date"
|
||||
msgstr "Datum för tillagd"
|
||||
msgstr "Datum för tillägning"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:241
|
||||
msgid "Source"
|
||||
@ -617,7 +620,7 @@ msgstr "Källa"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:247
|
||||
msgid "Last Modified"
|
||||
msgstr "Senast modifierad"
|
||||
msgstr "Senast Ändrad"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/details_jsp.java:253
|
||||
msgid "Notes"
|
||||
@ -625,7 +628,7 @@ msgstr "Anteckningar"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:110
|
||||
msgid "Introduction"
|
||||
msgstr "Inledning"
|
||||
msgstr "Introduktion"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:132
|
||||
msgid "What is the addressbook?"
|
||||
@ -640,8 +643,8 @@ msgid ""
|
||||
"It regularly updates your hosts.txt file from distributed sources or "
|
||||
"\"subscriptions\"."
|
||||
msgstr ""
|
||||
"Den uppdaterar din regelbundet hosts.txt fil från distribuerade källor eller "
|
||||
"\"subscriptions\"."
|
||||
"Den uppdaterar din hosts.txt fil från distribuerade källor eller "
|
||||
"\"prenumerationer\"."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:137
|
||||
msgid ""
|
||||
@ -659,7 +662,6 @@ msgstr ""
|
||||
"href=\"subscriptions\">subscriptions</a> fil. "
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:140
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"For more information on naming in I2P, see <a href=\"http://www.i2p2.i2p/"
|
||||
"naming.html\" target=\"_top\">the overview on www.i2p2.i2p</a>."
|
||||
@ -690,24 +692,24 @@ 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 ""
|
||||
"Om konfigurerad så skrivit router adressboken till \"published\" "
|
||||
"adressboken, som är tillgänglig om du kör en eepsite."
|
||||
"Om konfigurerad så skrivs router adressboken till \"published\" adressboken, "
|
||||
"som är tillgänglig om du kör en eepsite."
|
||||
|
||||
#: ../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 ""
|
||||
"Routern använder också den privat adressbok (syns ej på bilden) som inte är "
|
||||
"samman kopplade eller publicerad."
|
||||
"Routern använder också en privat adressbok (syns ej på bilden) som inte är "
|
||||
"sammansalgen eller publicerad."
|
||||
|
||||
#: ../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 ""
|
||||
"Värdar i den privata adressboken kan nås av dig, men adresserna delas "
|
||||
"aldrig ut till andra."
|
||||
"Värdar i den privata adressboken kan nås av dig, men adresserna delas aldrig "
|
||||
"ut till andra."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/index_jsp.java:150
|
||||
msgid ""
|
||||
@ -719,11 +721,11 @@ msgstr ""
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:111
|
||||
msgid "subscriptions"
|
||||
msgstr "abonnemang"
|
||||
msgstr "prenumerationer"
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:147
|
||||
msgid "The subscription file contains a list of i2p URLs."
|
||||
msgstr "Abonnemangs filen innehåller lista över I2P webbadresser."
|
||||
msgstr "Prenumerations-filen innehåller en lista av I2P URL:er."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:148
|
||||
msgid ""
|
||||
@ -739,7 +741,8 @@ msgid ""
|
||||
"The default subscription is the hosts.txt from www.i2p2.i2p, which is "
|
||||
"updated infrequently."
|
||||
msgstr ""
|
||||
"Den förvalda prenumeration är hosts.txt från www.i2p2.i2p uppdateras sällan."
|
||||
"Den förvalda prenumeration är hosts.txt från www.i2p2.i2p, som uppdateras "
|
||||
"sällan."
|
||||
|
||||
#: ../src/tmp/i2p/susi/dns/jsp/subscriptions_jsp.java:151
|
||||
msgid ""
|
||||
|
@ -126,6 +126,7 @@
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
|
@ -15,6 +15,10 @@ TMPFILE=tmp/javafiles.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
|
@ -80,6 +80,7 @@
|
||||
<!-- Update the messages_*.po files.
|
||||
We need to supply the bat file for windows, and then change the fail property to true -->
|
||||
<exec executable="sh" osfamily="unix" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
<env key="JAVA_HOME" value="${java.home}" />
|
||||
<arg value="./bundle-messages.sh" />
|
||||
</exec>
|
||||
<exec executable="sh" osfamily="mac" failifexecutionfails="true" failonerror="${require.gettext}" >
|
||||
|
@ -15,6 +15,10 @@ TMPFILE=javafiles.txt
|
||||
export TZ=UTC
|
||||
RC=0
|
||||
|
||||
if ! $(which javac > /dev/null 2>&1); then
|
||||
export JAVAC=${JAVA_HOME}/../bin/javac
|
||||
fi
|
||||
|
||||
if [ "$1" = "-p" ]
|
||||
then
|
||||
POUPDATE=1
|
||||
|
@ -14,7 +14,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2012-08-08 01:26+0000\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:25+0000\n"
|
||||
"PO-Revision-Date: 2012-08-05 05:57+0000\n"
|
||||
"Last-Translator: blabla <blabla@trash-mail.com>\n"
|
||||
"Language-Team: German (http://www.transifex.com/projects/p/I2P/language/"
|
||||
@ -25,428 +25,428 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:445
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:447
|
||||
msgid "unknown"
|
||||
msgstr "unbekannt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:464
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:466
|
||||
msgid "Warning: no transfer encoding found, fallback to 7bit."
|
||||
msgstr "Warnung: keine Übertragungskodierung gefunden, Rückgriff auf 7-bit"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:469
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:471
|
||||
#, java-format
|
||||
msgid "No encoder found for encoding \\''{0}\\''."
|
||||
msgstr "kein Kodierer für Kodierung \\''{0}\\'' gefunden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:475
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:477
|
||||
msgid "Warning: no charset found, fallback to US-ASCII."
|
||||
msgstr "Warnung: kein Zeichensatz gefunden; Rückgriff auf US-ASCII"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:489
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:491
|
||||
#, java-format
|
||||
msgid "Charset \\''{0}\\'' not supported."
|
||||
msgstr "Zeichensatz \\''{0}\\'' nicht unterstützt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:493
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:495
|
||||
#, java-format
|
||||
msgid "Part ({0}) not shown, because of {1}"
|
||||
msgstr "Teil ({0}) aufgrund von {1} nicht angezeigt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:516
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:518
|
||||
msgid "Download"
|
||||
msgstr "Herunterladen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:516
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:518
|
||||
msgid "File is packed into a zipfile for security reasons."
|
||||
msgstr "Die Datei wurde aus Sicherheitsgründen in ein Zip-Archiv gepackt."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:516
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:518
|
||||
#, java-format
|
||||
msgid "attachment ({0})."
|
||||
msgstr "Anhang ({0})."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:520
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:522
|
||||
#, java-format
|
||||
msgid "Attachment ({0})."
|
||||
msgstr "Anhang ({0})."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:570
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:572
|
||||
msgid "Need username for authentication."
|
||||
msgstr "Benutzername zur Authentifizierung benötigt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:574
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:576
|
||||
msgid "Need password for authentication."
|
||||
msgstr "Passwort zur Authentifizierung benötigt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:578
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:580
|
||||
msgid "Need hostname for connect."
|
||||
msgstr "Host-Name für die Verbindung benötigt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:583
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:585
|
||||
msgid "Need port number for pop3 connect."
|
||||
msgstr "POP3-Port für die Verbindung benötigt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:590
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:592
|
||||
msgid "POP3 port number is not in range 0..65535."
|
||||
msgstr "Der POP3-Port liegt nicht im Bereich 0-65535."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:596
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:598
|
||||
msgid "POP3 port number is invalid."
|
||||
msgstr "ungültiger POP3-Port"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:602
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:604
|
||||
msgid "Need port number for smtp connect."
|
||||
msgstr "SMTP-Port für die SMTP-Verbindung benötigt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:609
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:611
|
||||
msgid "SMTP port number is not in range 0..65535."
|
||||
msgstr "Der SMTP-Port liegt nicht im Bereich 0-65535."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:615
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:617
|
||||
msgid "SMTP port number is invalid."
|
||||
msgstr "ungültiger SMTP-Port"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:662
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:664
|
||||
msgid "User logged out."
|
||||
msgstr "Benutzer wurde abgemeldet"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:666
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:668
|
||||
msgid "Internal error, lost connection."
|
||||
msgstr "interner Fehler; Verbindung unterbrochen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:762
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:764
|
||||
#, java-format
|
||||
msgid "On {0} {1} wrote:"
|
||||
msgstr "Am {0} schrieb {1}:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:809
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:811
|
||||
msgid "begin forwarded mail"
|
||||
msgstr "Anfang weitergeleiteter Nachricht"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:831
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:833
|
||||
msgid "end forwarded mail"
|
||||
msgstr "Ende weitergeleiteter Nachricht"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:838
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1731
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:840
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1770
|
||||
msgid "Could not fetch mail body."
|
||||
msgstr "Konnte den Körper der Nachricht nicht holen."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:866
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:868
|
||||
msgid "Message id not valid."
|
||||
msgstr "ungültige Nachrichten-ID"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:949
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:951
|
||||
#, java-format
|
||||
msgid "No Encoding found for {0}"
|
||||
msgstr "keine Kodierung für {0} gefunden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:953
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:955
|
||||
#, java-format
|
||||
msgid "Could not encode data: {0}"
|
||||
msgstr "Konte Daten nicht kodieren: {0}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:958
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:960
|
||||
#, java-format
|
||||
msgid "Error reading uploaded file: {0}"
|
||||
msgstr "Fehler beim Lesen der hochzuladenen Datei: {0}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1036
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1038
|
||||
msgid "Error parsing download parameter."
|
||||
msgstr "Fehler beim Parsen des Download-Parameters"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1080
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1082
|
||||
msgid "Invalid pagesize number, resetting to default value."
|
||||
msgstr "ungültige Seitengröße, wird auf Standardwert zurückgesetzt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1104
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1106
|
||||
msgid "No messages marked for deletion."
|
||||
msgstr "Keine Nachrichten zum Löschen markiert"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1124
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1126
|
||||
#, java-format
|
||||
msgid "Error deleting message: {0}"
|
||||
msgstr "Fehler beim Löschen der Nachricht: {0}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1135
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1137
|
||||
#, java-format
|
||||
msgid "1 message deleted."
|
||||
msgid_plural "{0} messages deleted."
|
||||
msgstr[0] "Eine Nachricht gelöscht"
|
||||
msgstr[1] "{0} Nachrichten gelöscht"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1278
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1615
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1313
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1654
|
||||
msgid "Login"
|
||||
msgstr "Anmelden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1280
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1315
|
||||
#, java-format
|
||||
msgid "1 Message"
|
||||
msgid_plural "{0} Messages"
|
||||
msgstr[0] "Eine Nachricht"
|
||||
msgstr[1] "{0} Nachrichten"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1282
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1317
|
||||
msgid "Show Message"
|
||||
msgstr "Nachricht anzeigen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1344
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1383
|
||||
#, java-format
|
||||
msgid "Error decoding content: {0}"
|
||||
msgstr "Fehler beim Dekodieren des Inhalts: {0}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1349
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1388
|
||||
msgid "Error decoding content: No encoder found."
|
||||
msgstr "Fehler bei der Dekodierung: kein Kodierer gefunden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1396
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1435
|
||||
msgid "no subject"
|
||||
msgstr "kein Betreff"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1413
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1452
|
||||
msgid "Found no valid sender address."
|
||||
msgstr "Keine gültige Absenderadresse vorgefunden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1419
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1458
|
||||
#, java-format
|
||||
msgid "Found no valid address in \\''{0}\\''."
|
||||
msgstr "keine gültige Adresse in \\''{0}\\''"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1438
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1477
|
||||
msgid "No recipients found."
|
||||
msgstr "keine Empfänger gefunden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1445
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1484
|
||||
msgid "Quoted printable encoder not available."
|
||||
msgstr "Der angegebene druckbare Kodierer ist nicht verfügbar."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1450
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1489
|
||||
msgid "Header line encoder not available."
|
||||
msgstr "Kodierer für die Kopfzeilen nicht verfügbar"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1501
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1540
|
||||
msgid "Mail sent."
|
||||
msgstr "Mail versandt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1540
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1579
|
||||
msgid "Send"
|
||||
msgstr "Senden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1541
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1580
|
||||
msgid "Cancel"
|
||||
msgstr "Abbruch"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1542
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1581
|
||||
msgid "Delete Attachment"
|
||||
msgstr "Anhang löschen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1543
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1637
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1718
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1582
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1676
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1757
|
||||
msgid "Reload Config"
|
||||
msgstr "Einstellungen neu laden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1544
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1638
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1719
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1583
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1677
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1758
|
||||
msgid "Logout"
|
||||
msgstr "Abmelden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1567
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1723
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1606
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1762
|
||||
msgid "From:"
|
||||
msgstr "Von:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1568
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1607
|
||||
msgid "To:"
|
||||
msgstr "An:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1569
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1608
|
||||
msgid "Cc:"
|
||||
msgstr "Kopie an:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1570
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1609
|
||||
msgid "Bcc:"
|
||||
msgstr "Blindkopie an:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1571
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1725
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1610
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1764
|
||||
msgid "Subject:"
|
||||
msgstr "Betreff:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1572
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1611
|
||||
msgid "Bcc to self"
|
||||
msgstr "Blindkopie zurück?"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1575
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1614
|
||||
msgid "New Attachment:"
|
||||
msgstr "Neuer Anhang:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1575
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1614
|
||||
msgid "Upload File"
|
||||
msgstr "Datei hochladen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1581
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1620
|
||||
msgid "Attachments:"
|
||||
msgstr "Anhänge:"
|
||||
|
||||
#. current postman hq length limits 16/12, new postman version 32/32
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1604
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1643
|
||||
msgid "User"
|
||||
msgstr "Benutzer"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1605
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1644
|
||||
msgid "Password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1610
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1649
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1611
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1650
|
||||
msgid "POP3-Port"
|
||||
msgstr "POP3-Port"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1612
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1651
|
||||
msgid "SMTP-Port"
|
||||
msgstr "SMTP-Port"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1615
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1654
|
||||
msgid "Reset"
|
||||
msgstr "Zurücksetzen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1616
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1655
|
||||
msgid "Learn about I2P mail"
|
||||
msgstr "Erfahre etwas über I2P-Mail"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1617
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1656
|
||||
msgid "Create Account"
|
||||
msgstr "Konto anlegen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1629
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1668
|
||||
msgid "Really delete the marked messages?"
|
||||
msgstr "Sollen die markierten Nachrichten wirklich gelöscht werden?"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1629
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1668
|
||||
msgid "Yes, really delete them!"
|
||||
msgstr "Ja, löschen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1631
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1710
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1670
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1749
|
||||
msgid "New"
|
||||
msgstr "Verfassen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1632
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1711
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1671
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1750
|
||||
msgid "Reply"
|
||||
msgstr "Antworten"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1633
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1712
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1672
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1751
|
||||
msgid "Reply All"
|
||||
msgstr "Allen antworten"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1634
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1713
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1673
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1752
|
||||
msgid "Forward"
|
||||
msgstr "Weiterleiten"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1635
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1714
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1674
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1753
|
||||
msgid "Delete"
|
||||
msgstr "Löschen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1636
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1675
|
||||
msgid "Check Mail"
|
||||
msgstr "Nachrichten abrufen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1640
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1679
|
||||
msgid "Sender"
|
||||
msgstr "Absender"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1641
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1680
|
||||
msgid "Subject"
|
||||
msgstr "Betreff"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1642
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1681
|
||||
msgid "Date"
|
||||
msgstr "Datum"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1643
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1682
|
||||
msgid "Size"
|
||||
msgstr "Größe"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1669
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1708
|
||||
#, java-format
|
||||
msgid "1 Byte"
|
||||
msgid_plural "{0} Bytes"
|
||||
msgstr[0] "1 Byte"
|
||||
msgstr[1] "{0} Bytes"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1674
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1713
|
||||
msgid "Mark All"
|
||||
msgstr "Alles markieren"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1675
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1714
|
||||
msgid "Invert Selection"
|
||||
msgstr "Markierung umkehren"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1676
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1715
|
||||
msgid "Clear"
|
||||
msgstr "Verwerfen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1679
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1680
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1718
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1719
|
||||
msgid "First"
|
||||
msgstr "erste"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1679
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1680
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1715
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1718
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1719
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1754
|
||||
msgid "Previous"
|
||||
msgstr "vorherige"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1681
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1720
|
||||
#, java-format
|
||||
msgid "Page {0} of {1}"
|
||||
msgstr "Seite {0} von {1}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1683
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1684
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1722
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1723
|
||||
msgid "Last"
|
||||
msgstr "letzte"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1683
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1684
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1716
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1722
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1723
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1755
|
||||
msgid "Next"
|
||||
msgstr "nächste"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1687
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1726
|
||||
msgid "Pagesize:"
|
||||
msgstr "Seitengröße"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1688
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1727
|
||||
msgid "Set"
|
||||
msgstr "festlegen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1698
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1737
|
||||
msgid "Really delete this message?"
|
||||
msgstr "Diese Nachricht wirklich löschen?"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1698
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1737
|
||||
msgid "Yes, really delete it!"
|
||||
msgstr "Ja, wirklich löschen"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1717
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1756
|
||||
msgid "Back to Folder"
|
||||
msgstr "Zurück zur Übersicht"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1724
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1763
|
||||
msgid "Date:"
|
||||
msgstr "Datum:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1735
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1774
|
||||
msgid "Could not fetch mail."
|
||||
msgstr "Konnte Nachrichten nicht abrufen."
|
||||
|
@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2013-02-06 02:33+0000\n"
|
||||
"POT-Creation-Date: 2013-09-20 10:12+0000\n"
|
||||
"PO-Revision-Date: 2011-12-13 14:16+0000\n"
|
||||
"Last-Translator: Martin Svensson <digitalmannen@gmail.com>\n"
|
||||
"Language-Team: Swedish (Sweden) (http://www.transifex.net/projects/p/I2P/"
|
||||
@ -20,429 +20,429 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:445
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:447
|
||||
msgid "unknown"
|
||||
msgstr "okänd"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:464
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:466
|
||||
msgid "Warning: no transfer encoding found, fallback to 7bit."
|
||||
msgstr ""
|
||||
"Varning: ingen överförings kodning hittats, återgår till att använda 7bit."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:469
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:471
|
||||
#, java-format
|
||||
msgid "No encoder found for encoding \\''{0}\\''."
|
||||
msgstr "Ingen encoder hittades för kodning \\''{0}\\''."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:475
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:477
|
||||
msgid "Warning: no charset found, fallback to US-ASCII."
|
||||
msgstr "Varning: ingen teckenuppsättning hittats, återgår till US-ASCII."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:489
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:491
|
||||
#, java-format
|
||||
msgid "Charset \\''{0}\\'' not supported."
|
||||
msgstr "Teckenuppsättning \\''{0}\\' stöds inte."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:493
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:495
|
||||
#, java-format
|
||||
msgid "Part ({0}) not shown, because of {1}"
|
||||
msgstr "Del ({0}) visas inte på grund av {1}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:516
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:518
|
||||
msgid "Download"
|
||||
msgstr "Hämta"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:516
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:518
|
||||
msgid "File is packed into a zipfile for security reasons."
|
||||
msgstr "Filen packas till zipfil av säkerhetsskäl."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:516
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:518
|
||||
#, java-format
|
||||
msgid "attachment ({0})."
|
||||
msgstr "bilaga ({0})."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:520
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:522
|
||||
#, java-format
|
||||
msgid "Attachment ({0})."
|
||||
msgstr "Bilaga ({0})."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:570
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:572
|
||||
msgid "Need username for authentication."
|
||||
msgstr "Behöver användarnamn för autentisering."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:574
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:576
|
||||
msgid "Need password for authentication."
|
||||
msgstr "Behöver lösenord för autentisering."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:578
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:580
|
||||
msgid "Need hostname for connect."
|
||||
msgstr "Behöver värd namn för att ansluta."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:583
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:585
|
||||
msgid "Need port number for pop3 connect."
|
||||
msgstr "Behöver portnummer för POP3 anslutning."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:590
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:592
|
||||
msgid "POP3 port number is not in range 0..65535."
|
||||
msgstr "POP3 portnummer är inte inom intervallet 0 .. 65535."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:596
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:598
|
||||
msgid "POP3 port number is invalid."
|
||||
msgstr "POP3 portnummer är ogiltigt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:602
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:604
|
||||
msgid "Need port number for smtp connect."
|
||||
msgstr "Behöver portnummer för SMTP anslutning."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:609
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:611
|
||||
msgid "SMTP port number is not in range 0..65535."
|
||||
msgstr "SMTP portnumret är inte inom intervallet 0 .. 65535."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:615
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:617
|
||||
msgid "SMTP port number is invalid."
|
||||
msgstr "SMTP portnummer ör ogiltigt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:662
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:664
|
||||
msgid "User logged out."
|
||||
msgstr "Användare loggade ut."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:666
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:668
|
||||
msgid "Internal error, lost connection."
|
||||
msgstr "Internt fel, tappade anslutningen."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:762
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:764
|
||||
#, java-format
|
||||
msgid "On {0} {1} wrote:"
|
||||
msgstr "Den {0} {1} skrev:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:809
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:811
|
||||
msgid "begin forwarded mail"
|
||||
msgstr "börjar vidarebefordra e-post"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:831
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:833
|
||||
msgid "end forwarded mail"
|
||||
msgstr "slutar vidarebefordra e-post"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:838
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1731
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:840
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1770
|
||||
msgid "Could not fetch mail body."
|
||||
msgstr "Kunde inte hämta e-postets brödtext."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:866
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:868
|
||||
msgid "Message id not valid."
|
||||
msgstr "Meddelande id är inte giltigt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:949
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:951
|
||||
#, java-format
|
||||
msgid "No Encoding found for {0}"
|
||||
msgstr "Ingen teckenkodning hittades för {0}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:953
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:955
|
||||
#, java-format
|
||||
msgid "Could not encode data: {0}"
|
||||
msgstr "Kunde inte koda data: {0}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:958
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:960
|
||||
#, java-format
|
||||
msgid "Error reading uploaded file: {0}"
|
||||
msgstr "Fel vid läsning av uppladdad fil: {0}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1036
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1038
|
||||
msgid "Error parsing download parameter."
|
||||
msgstr "Fel vid tolkning av nedladdnings parameter."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1080
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1082
|
||||
msgid "Invalid pagesize number, resetting to default value."
|
||||
msgstr "Ogiltigt sidstorleks antal, återställer till standard värde."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1104
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1106
|
||||
msgid "No messages marked for deletion."
|
||||
msgstr "Inga meddelanden var märkta för radering"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1124
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1126
|
||||
#, java-format
|
||||
msgid "Error deleting message: {0}"
|
||||
msgstr "Fel vid raderande av meddelande: {0}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1135
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1137
|
||||
#, java-format
|
||||
msgid "1 message deleted."
|
||||
msgid_plural "{0} messages deleted."
|
||||
msgstr[0] "1 meddelande raderart."
|
||||
msgstr[1] "{0} meddelanden raderade"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1278
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1615
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1313
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1654
|
||||
msgid "Login"
|
||||
msgstr "Logga in"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1280
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1315
|
||||
#, java-format
|
||||
msgid "1 Message"
|
||||
msgid_plural "{0} Messages"
|
||||
msgstr[0] "1 meddelande"
|
||||
msgstr[1] "{0} meddelanden"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1282
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1317
|
||||
msgid "Show Message"
|
||||
msgstr "Visa meddelande"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1344
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1383
|
||||
#, java-format
|
||||
msgid "Error decoding content: {0}"
|
||||
msgstr "Fel vid avkodning av innehåll: {0}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1349
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1388
|
||||
msgid "Error decoding content: No encoder found."
|
||||
msgstr "Fel vid avkodning av innehåll: Ingen encoder hittades."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1396
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1435
|
||||
msgid "no subject"
|
||||
msgstr "inget ämne"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1413
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1452
|
||||
msgid "Found no valid sender address."
|
||||
msgstr "Hittade ingen giltig avsändaradress."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1419
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1458
|
||||
#, java-format
|
||||
msgid "Found no valid address in \\''{0}\\''."
|
||||
msgstr "Hittade ingen giltig adress i \\''{0}\\''."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1438
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1477
|
||||
msgid "No recipients found."
|
||||
msgstr "Inga mottagare funna"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1445
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1484
|
||||
msgid "Quoted printable encoder not available."
|
||||
msgstr "Citerad utskrivbar encoder inte tillgänglig."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1450
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1489
|
||||
msgid "Header line encoder not available."
|
||||
msgstr "Header radens encoder är inte tillgänglig."
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1501
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1540
|
||||
msgid "Mail sent."
|
||||
msgstr "E-post skickat"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1540
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1579
|
||||
msgid "Send"
|
||||
msgstr "Skicka"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1541
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1580
|
||||
msgid "Cancel"
|
||||
msgstr "Avbryt"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1542
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1581
|
||||
msgid "Delete Attachment"
|
||||
msgstr "Radera bilaga"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1543
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1637
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1718
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1582
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1676
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1757
|
||||
msgid "Reload Config"
|
||||
msgstr "Ladda om konfiguration"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1544
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1638
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1719
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1583
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1677
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1758
|
||||
msgid "Logout"
|
||||
msgstr "Logga ut"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1567
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1723
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1606
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1762
|
||||
msgid "From:"
|
||||
msgstr "Från:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1568
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1607
|
||||
msgid "To:"
|
||||
msgstr "Till:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1569
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1608
|
||||
msgid "Cc:"
|
||||
msgstr "Cc:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1570
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1609
|
||||
msgid "Bcc:"
|
||||
msgstr "Bcc:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1571
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1725
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1610
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1764
|
||||
msgid "Subject:"
|
||||
msgstr "Ärende:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1572
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1611
|
||||
msgid "Bcc to self"
|
||||
msgstr "Bcc till själv"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1575
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1614
|
||||
msgid "New Attachment:"
|
||||
msgstr "Ny bilaga:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1575
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1614
|
||||
msgid "Upload File"
|
||||
msgstr "Ladda upp fil"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1581
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1620
|
||||
msgid "Attachments:"
|
||||
msgstr "Bilagor:"
|
||||
|
||||
#. current postman hq length limits 16/12, new postman version 32/32
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1604
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1643
|
||||
msgid "User"
|
||||
msgstr "Användare"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1605
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1644
|
||||
msgid "Password"
|
||||
msgstr "Lösenord"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1610
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1649
|
||||
msgid "Host"
|
||||
msgstr "Värd"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1611
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1650
|
||||
msgid "POP3-Port"
|
||||
msgstr "POP3-port"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1612
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1651
|
||||
msgid "SMTP-Port"
|
||||
msgstr "SMTP-port"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1615
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1654
|
||||
msgid "Reset"
|
||||
msgstr "Återställ"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1616
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1655
|
||||
msgid "Learn about I2P mail"
|
||||
msgstr "Lär mer om I2P e-post"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1617
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1656
|
||||
msgid "Create Account"
|
||||
msgstr "Skapa konto"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1629
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1668
|
||||
msgid "Really delete the marked messages?"
|
||||
msgstr "Vill du verkligen radera valda meddelanden?"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1629
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1668
|
||||
msgid "Yes, really delete them!"
|
||||
msgstr "Ja, radera dem!"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1631
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1710
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1670
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1749
|
||||
msgid "New"
|
||||
msgstr "Ny"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1632
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1711
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1671
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1750
|
||||
msgid "Reply"
|
||||
msgstr "Svara"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1633
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1712
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1672
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1751
|
||||
msgid "Reply All"
|
||||
msgstr "Svara alla"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1634
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1713
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1673
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1752
|
||||
msgid "Forward"
|
||||
msgstr "Vidarebefodera"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1635
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1714
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1674
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1753
|
||||
msgid "Delete"
|
||||
msgstr "Radera"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1636
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1675
|
||||
msgid "Check Mail"
|
||||
msgstr "Kolla e-post"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1640
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1679
|
||||
msgid "Sender"
|
||||
msgstr "Avsändare"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1641
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1680
|
||||
msgid "Subject"
|
||||
msgstr "Ärende"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1642
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1681
|
||||
msgid "Date"
|
||||
msgstr "Datum"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1643
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1682
|
||||
msgid "Size"
|
||||
msgstr "Storlek"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1669
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1708
|
||||
#, java-format
|
||||
msgid "1 Byte"
|
||||
msgid_plural "{0} Bytes"
|
||||
msgstr[0] "1 Byte"
|
||||
msgstr[1] "{0} Bytes"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1674
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1713
|
||||
msgid "Mark All"
|
||||
msgstr "Markera alla"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1675
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1714
|
||||
msgid "Invert Selection"
|
||||
msgstr "Invertera urvalet"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1676
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1715
|
||||
msgid "Clear"
|
||||
msgstr "Rensa "
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1679
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1680
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1718
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1719
|
||||
msgid "First"
|
||||
msgstr "Första"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1679
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1680
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1715
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1718
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1719
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1754
|
||||
msgid "Previous"
|
||||
msgstr "Föregående"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1681
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1720
|
||||
#, java-format
|
||||
msgid "Page {0} of {1}"
|
||||
msgstr "Sida {0} av {1}"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1683
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1684
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1722
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1723
|
||||
msgid "Last"
|
||||
msgstr "Sista"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1683
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1684
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1716
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1722
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1723
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1755
|
||||
msgid "Next"
|
||||
msgstr "Nästa"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1687
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1726
|
||||
msgid "Pagesize:"
|
||||
msgstr "Pagesize:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1688
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1727
|
||||
msgid "Set"
|
||||
msgstr "Ställ"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1698
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1737
|
||||
msgid "Really delete this message?"
|
||||
msgstr "Vill du verkligen radera detta meddelande?"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1698
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1737
|
||||
msgid "Yes, really delete it!"
|
||||
msgstr "Ja, radera det verkligen!"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1717
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1756
|
||||
msgid "Back to Folder"
|
||||
msgstr "Tillbaka till mapp"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1724
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1763
|
||||
msgid "Date:"
|
||||
msgstr "Datum:"
|
||||
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1735
|
||||
#: src/src/i2p/susi/webmail/WebMail.java:1774
|
||||
msgid "Could not fetch mail."
|
||||
msgstr "Kunde inte hämta e-post."
|
||||
|
69
build.xml
69
build.xml
@ -1380,6 +1380,7 @@
|
||||
<exec executable="tests/scripts/checkpo.sh" failonerror="true" />
|
||||
<exec executable="tests/scripts/checkutf8.sh" failonerror="true" />
|
||||
<exec executable="tests/scripts/checkxml.sh" failonerror="true" />
|
||||
<exec executable="tests/scripts/checkscripts.sh" failonerror="true" />
|
||||
</target>
|
||||
|
||||
|
||||
@ -1496,6 +1497,7 @@
|
||||
</condition>
|
||||
</fail>
|
||||
<echo message="Key file is ${release.privkey}" />
|
||||
<!-- now build and verify the unpacked sud from the unpacked zip -->
|
||||
<java classname="net.i2p.crypto.TrustedUpdate" fork="true" failonerror="true">
|
||||
<classpath>
|
||||
<pathelement location="build/i2p.jar" />
|
||||
@ -1528,7 +1530,7 @@
|
||||
<arg value="showversion" />
|
||||
<arg value="i2pupdate.sud" />
|
||||
</java>
|
||||
<!-- now build and verify the packed sud from the packed zip -->
|
||||
<!-- now build and verify the packed su2 from the packed zip -->
|
||||
<java classname="net.i2p.crypto.TrustedUpdate" fork="true" failonerror="true">
|
||||
<classpath>
|
||||
<pathelement location="build/i2p.jar" />
|
||||
@ -1561,6 +1563,59 @@
|
||||
<arg value="showversion" />
|
||||
<arg value="i2pupdate.su2" />
|
||||
</java>
|
||||
<!-- now build and verify the packed su3 from the packed zip -->
|
||||
<input message="Enter su3 private signing key store:" addproperty="release.privkey.su3" />
|
||||
<fail message="You must enter a path." >
|
||||
<condition>
|
||||
<equals arg1="${release.privkey.su3}" arg2=""/>
|
||||
</condition>
|
||||
</fail>
|
||||
<input message="Enter key name (you@mail.i2p):" addproperty="release.signer.su3" />
|
||||
<fail message="You must enter a name." >
|
||||
<condition>
|
||||
<equals arg1="${release.signer.su3}" arg2=""/>
|
||||
</condition>
|
||||
</fail>
|
||||
<input message="Enter key password for ${release.signer.su3}:" addproperty="release.password.su3" />
|
||||
<fail message="You must enter a password." >
|
||||
<condition>
|
||||
<equals arg1="${release.password.su3}" arg2=""/>
|
||||
</condition>
|
||||
</fail>
|
||||
<java classname="net.i2p.crypto.SU3File" inputstring="${release.password.su3}" fork="true" failonerror="true">
|
||||
<classpath>
|
||||
<pathelement location="build/i2p.jar" />
|
||||
</classpath>
|
||||
<arg value="sign" />
|
||||
<arg value="-c" />
|
||||
<arg value="ROUTER" />
|
||||
<arg value="-t" />
|
||||
<arg value="RSA_SHA512_4096" />
|
||||
<arg value="i2pupdate200.zip" />
|
||||
<arg value="i2pupdate.su3" />
|
||||
<arg value="${release.privkey.su3}" />
|
||||
<arg value="${release.number}" />
|
||||
<arg value="${release.signer.su3}" />
|
||||
</java>
|
||||
<echo message="Verify version and VALID signature:" />
|
||||
<java classname="net.i2p.crypto.SU3File" fork="true" failonerror="true">
|
||||
<classpath>
|
||||
<pathelement location="build/i2p.jar" />
|
||||
</classpath>
|
||||
<!-- set base dir so it can find the pubkey cert -->
|
||||
<jvmarg value="-Di2p.dir.base=installer/resources" />
|
||||
<arg value="verifysig" />
|
||||
<arg value="i2pupdate.su3" />
|
||||
</java>
|
||||
<java classname="net.i2p.crypto.SU3File" fork="true" failonerror="true">
|
||||
<classpath>
|
||||
<pathelement location="build/i2p.jar" />
|
||||
</classpath>
|
||||
<!-- set base dir so it can find the pubkey cert -->
|
||||
<jvmarg value="-Di2p.dir.base=installer/resources" />
|
||||
<arg value="showversion" />
|
||||
<arg value="i2pupdate.su3" />
|
||||
</java>
|
||||
<!-- will this use the monotonerc file in the current workspace? -->
|
||||
<echo message="Checking out fresh copy into ../i2p-${release.number} for tarballing:" />
|
||||
<delete dir="../i2p-${release.number}" />
|
||||
@ -1608,6 +1663,7 @@
|
||||
<arg value="i2psource_${release.number}.tar.bz2" />
|
||||
<arg value="i2pupdate_${release.number}.zip" />
|
||||
<arg value="i2pupdate.su2" />
|
||||
<arg value="i2pupdate.su3" />
|
||||
<arg value="i2pupdate.sud" />
|
||||
<arg value="i2pinstall_${release.number}_windows.exe.sig" />
|
||||
<arg value="i2pinstall_${release.number}.jar.sig" />
|
||||
@ -1622,6 +1678,7 @@
|
||||
<arg value="i2psource_${release.number}.tar.bz2" />
|
||||
<arg value="i2pupdate_${release.number}.zip" />
|
||||
<arg value="i2pupdate.su2" />
|
||||
<arg value="i2pupdate.su3" />
|
||||
<arg value="i2pupdate.sud" />
|
||||
<arg value="i2pinstall_${release.number}_windows.exe.sig" />
|
||||
<arg value="i2pinstall_${release.number}.jar.sig" />
|
||||
@ -1635,6 +1692,7 @@
|
||||
<arg value="i2psource_${release.number}.tar.bz2" />
|
||||
<arg value="i2pupdate_${release.number}.zip" />
|
||||
<arg value="i2pupdate.su2" />
|
||||
<arg value="i2pupdate.su3" />
|
||||
<arg value="i2pupdate.sud" />
|
||||
</exec>
|
||||
<!-- make torrent files -->
|
||||
@ -1656,6 +1714,15 @@
|
||||
<arg value="i2pupdate-${release.number}.su2" />
|
||||
<arg value="http://tracker2.postman.i2p/announce.php" />
|
||||
</java>
|
||||
<copy file="i2pupdate.su3" tofile="i2pupdate-${release.number}.su3" />
|
||||
<java classname="org.klomp.snark.Storage" fork="true" failonerror="true">
|
||||
<classpath>
|
||||
<pathelement location="build/i2p.jar" />
|
||||
<pathelement location="build/i2psnark.jar" />
|
||||
</classpath>
|
||||
<arg value="i2pupdate-${release.number}.su3" />
|
||||
<arg value="http://tracker2.postman.i2p/announce.php" />
|
||||
</java>
|
||||
<echo message="Don't forget to mtn tag w: i2p-${release.number}" />
|
||||
<echo message="... and mtn cert t:i2p-${release.number} branch i2p.i2p.release" />
|
||||
</target>
|
||||
|
@ -1,4 +1,4 @@
|
||||
#/bin/sh
|
||||
#!/bin/sh
|
||||
|
||||
(cd jcpuid ; sh build.sh ; cd ..)
|
||||
(cd jbigi ; sh build.sh ; cd ..)
|
||||
|
@ -17,6 +17,8 @@ elif [ $UNIXTYPE = "sunos" ]; then
|
||||
elif [ $UNIXTYPE = "openbsd" ]; then
|
||||
if [ -d /usr/local/jdk-1.7.0 ]; then
|
||||
JAVA_HOME="/usr/local/jdk-1.7.0"
|
||||
elif [ -d /usr/local/jdk-1.6.0 ]; then
|
||||
JAVA_HOME="/usr/local/jdk-1.6.0"
|
||||
fi
|
||||
elif [ $UNIXTYPE = "netbsd" ]; then
|
||||
if [ -d /usr/pkg/java/openjdk7 ]; then
|
||||
|
@ -1,4 +1,4 @@
|
||||
#/bin/sh
|
||||
#!/bin/sh
|
||||
|
||||
case `uname -sr` in
|
||||
MINGW*)
|
||||
|
@ -39,7 +39,7 @@ SunOS*|OpenBSD*|NetBSD*|*FreeBSD*|Linux*)
|
||||
UNIXTYPE="linux"
|
||||
fi
|
||||
COMPILEFLAGS="-fPIC -Wall $CFLAGS"
|
||||
INCLUDES="-I. -I../../jbigi/include -I$JAVA_HOME/include -I$JAVA_HOME/include/${UNIXTYPE}"
|
||||
INCLUDES="-I. -I../../jbigi/include -I$JAVA_HOME/include -I$JAVA_HOME/include/${UNIXTYPE} -I/usr/local/include"
|
||||
LINKFLAGS="-shared -Wl,-soname,libjbigi.so"
|
||||
LIBFILE="libjbigi.so";;
|
||||
*)
|
||||
@ -49,7 +49,7 @@ esac
|
||||
|
||||
if [ "$1" = "dynamic" ] ; then
|
||||
echo "Building a jbigi lib that is dynamically linked to GMP"
|
||||
LIBPATH="-L.libs"
|
||||
LIBPATH="-L.libs -L/usr/local/lib"
|
||||
INCLUDELIBS="-lgmp"
|
||||
else
|
||||
echo "Building a jbigi lib that is statically linked to GMP"
|
||||
@ -59,6 +59,6 @@ fi
|
||||
echo "Compiling C code..."
|
||||
rm -f jbigi.o $LIBFILE
|
||||
$CC -c $COMPILEFLAGS $INCLUDES ../../jbigi/src/jbigi.c || exit 1
|
||||
$CC $LINKFLAGS $INCLUDES -o $LIBFILE jbigi.o $INCLUDELIBS $STATICLIBS || exit 1
|
||||
$CC $LINKFLAGS $INCLUDES -o $LIBFILE jbigi.o $INCLUDELIBS $STATICLIBS $LIBPATH || exit 1
|
||||
|
||||
exit 0
|
||||
|
@ -1,21 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/sh -e
|
||||
# Automatic build of so files, ignores failed builds.
|
||||
# Place latest gmp tarball in the jbigi dir, and exec this script.
|
||||
|
||||
if [ -z "$BASH_VERSION" ]; then
|
||||
echo "This script needs to be run with Bash."
|
||||
echo
|
||||
echo "Please install bash and then run this script with"
|
||||
echo "bash $0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#JBIGI=../../../installer/lib/jbigi/jbigi.jar
|
||||
|
||||
#if [ -f jbigi.jarx ] ; then
|
||||
#JBIGI=../jbigi.jar
|
||||
#fi
|
||||
|
||||
rm -f t/* jcpuid/lib/freenet/support/CPUInformation/* jbigi/lib/net/i2p/util/*
|
||||
|
||||
( cd jcpuid ; ./build.sh )
|
||||
@ -32,7 +18,7 @@ mkdir t
|
||||
cp jbigi/lib/net/i2p/util/* t/
|
||||
(
|
||||
cd t
|
||||
for i in *.so ; { strip $i ; }
|
||||
for i in *.so ; do strip $i ; done
|
||||
)
|
||||
|
||||
cp jcpuid/lib/freenet/support/CPUInformation/* t/
|
||||
@ -47,7 +33,7 @@ mkdir t
|
||||
cp jbigi/lib/net/i2p/util/* t/
|
||||
(
|
||||
cd t
|
||||
for i in *.so ; { strip $i ; }
|
||||
for i in *.so ; do strip $i ; done
|
||||
)
|
||||
|
||||
|
||||
|
@ -16,7 +16,7 @@ package net.i2p;
|
||||
public class CoreVersion {
|
||||
/** deprecated */
|
||||
public final static String ID = "Monotone";
|
||||
public final static String VERSION = "0.9.7.1";
|
||||
public final static String VERSION = "0.9.8.1";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("I2P Core version: " + VERSION);
|
||||
|
@ -7,17 +7,13 @@ import java.io.InputStream;
|
||||
import java.net.Socket;
|
||||
import java.security.KeyStore;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManagerFactory;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.crypto.KeyStoreUtil;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
@ -71,14 +67,14 @@ class I2CPSSLSocketFactory {
|
||||
}
|
||||
|
||||
File dir = new File(context.getConfigDir(), CERT_DIR);
|
||||
int adds = addCerts(dir, ks);
|
||||
int adds = KeyStoreUtil.addCerts(dir, ks);
|
||||
int totalAdds = adds;
|
||||
if (adds > 0)
|
||||
info(context, "Loaded " + adds + " trusted certificates from " + dir.getAbsolutePath());
|
||||
|
||||
File dir2 = new File(System.getProperty("user.dir"), CERT_DIR);
|
||||
if (!dir.getAbsolutePath().equals(dir2.getAbsolutePath())) {
|
||||
adds = addCerts(dir2, ks);
|
||||
adds = KeyStoreUtil.addCerts(dir2, ks);
|
||||
totalAdds += adds;
|
||||
if (adds > 0)
|
||||
info(context, "Loaded " + adds + " trusted certificates from " + dir.getAbsolutePath());
|
||||
@ -105,82 +101,6 @@ class I2CPSSLSocketFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all X509 Certs from a directory and add them to the
|
||||
* trusted set of certificates in the key store
|
||||
*
|
||||
* @return number successfully added
|
||||
*/
|
||||
private static int addCerts(File dir, KeyStore ks) {
|
||||
info("Looking for X509 Certificates in " + dir.getAbsolutePath());
|
||||
int added = 0;
|
||||
if (dir.exists() && dir.isDirectory()) {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File f = files[i];
|
||||
if (!f.isFile())
|
||||
continue;
|
||||
// use file name as alias
|
||||
String alias = f.getName().toLowerCase(Locale.US);
|
||||
boolean success = addCert(f, alias, ks);
|
||||
if (success)
|
||||
added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an X509 Cert from a file and add it to the
|
||||
* trusted set of certificates in the key store
|
||||
*
|
||||
* @return success
|
||||
*/
|
||||
private static boolean addCert(File file, String alias, KeyStore ks) {
|
||||
InputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
X509Certificate cert = (X509Certificate)cf.generateCertificate(fis);
|
||||
info("Read X509 Certificate from " + file.getAbsolutePath() +
|
||||
" Issuer: " + cert.getIssuerX500Principal() +
|
||||
"; Valid From: " + cert.getNotBefore() +
|
||||
" To: " + cert.getNotAfter());
|
||||
try {
|
||||
cert.checkValidity();
|
||||
} catch (CertificateExpiredException cee) {
|
||||
error("Rejecting expired X509 Certificate: " + file.getAbsolutePath(), cee);
|
||||
return false;
|
||||
} catch (CertificateNotYetValidException cnyve) {
|
||||
error("Rejecting X509 Certificate not yet valid: " + file.getAbsolutePath(), cnyve);
|
||||
return false;
|
||||
}
|
||||
ks.setCertificateEntry(alias, cert);
|
||||
info("Now trusting X509 Certificate, Issuer: " + cert.getIssuerX500Principal());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
error("Error reading X509 Certificate: " + file.getAbsolutePath(), gse);
|
||||
return false;
|
||||
} catch (IOException ioe) {
|
||||
error("Error reading X509 Certificate: " + file.getAbsolutePath(), ioe);
|
||||
return false;
|
||||
} finally {
|
||||
try { if (fis != null) fis.close(); } catch (IOException foo) {}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @since 0.9.8 */
|
||||
private static void info(String msg) {
|
||||
log(I2PAppContext.getGlobalContext(), Log.INFO, msg, null);
|
||||
}
|
||||
|
||||
/** @since 0.9.8 */
|
||||
private static void error(String msg, Throwable t) {
|
||||
log(I2PAppContext.getGlobalContext(), Log.ERROR, msg, t);
|
||||
}
|
||||
|
||||
/** @since 0.9.8 */
|
||||
private static void info(I2PAppContext ctx, String msg) {
|
||||
log(ctx, Log.INFO, msg, null);
|
||||
|
103
core/java/src/net/i2p/crypto/CertUtil.java
Normal file
103
core/java/src/net/i2p/crypto/CertUtil.java
Normal file
@ -0,0 +1,103 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.naming.InvalidNameException;
|
||||
import javax.naming.ldap.LdapName;
|
||||
import javax.naming.ldap.Rdn;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
|
||||
/**
|
||||
* Java X.509 certificate utilities, consolidated from various places.
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public class CertUtil {
|
||||
|
||||
private static final int LINE_LENGTH = 64;
|
||||
|
||||
/**
|
||||
* Modified from:
|
||||
* http://www.exampledepot.com/egs/java.security.cert/ExportCert.html
|
||||
*
|
||||
* This method writes a certificate to a file in base64 format.
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.2, moved from SSLEepGet in 0.9.9
|
||||
*/
|
||||
public static boolean saveCert(Certificate cert, File file) {
|
||||
OutputStream os = null;
|
||||
try {
|
||||
// Get the encoded form which is suitable for exporting
|
||||
byte[] buf = cert.getEncoded();
|
||||
os = new SecureFileOutputStream(file);
|
||||
PrintWriter wr = new PrintWriter(os);
|
||||
wr.println("-----BEGIN CERTIFICATE-----");
|
||||
String b64 = Base64.encode(buf, true); // true = use standard alphabet
|
||||
for (int i = 0; i < b64.length(); i += LINE_LENGTH) {
|
||||
wr.println(b64.substring(i, Math.min(i + LINE_LENGTH, b64.length())));
|
||||
}
|
||||
wr.println("-----END CERTIFICATE-----");
|
||||
wr.flush();
|
||||
return true;
|
||||
} catch (CertificateEncodingException cee) {
|
||||
error("Error writing X509 Certificate " + file.getAbsolutePath(), cee);
|
||||
return false;
|
||||
} catch (IOException ioe) {
|
||||
error("Error writing X509 Certificate " + file.getAbsolutePath(), ioe);
|
||||
return false;
|
||||
} finally {
|
||||
try { if (os != null) os.close(); } catch (IOException foo) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a value out of the subject distinguished name
|
||||
* @param type e.g. "CN"
|
||||
* @return value or null if not found
|
||||
*/
|
||||
public static String getSubjectValue(X509Certificate cert, String type) {
|
||||
type = type.toUpperCase(Locale.US);
|
||||
X500Principal p = cert.getSubjectX500Principal();
|
||||
String subj = p.getName();
|
||||
try {
|
||||
LdapName name = new LdapName(subj);
|
||||
for (Rdn rdn : name.getRdns()) {
|
||||
if (type.equals(rdn.getType().toUpperCase(Locale.US)))
|
||||
return (String) rdn.getValue();
|
||||
}
|
||||
} catch (InvalidNameException ine) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void error(String msg, Throwable t) {
|
||||
log(I2PAppContext.getGlobalContext(), Log.ERROR, msg, t);
|
||||
}
|
||||
|
||||
private static void error(I2PAppContext ctx, String msg, Throwable t) {
|
||||
log(ctx, Log.ERROR, msg, t);
|
||||
}
|
||||
|
||||
private static void log(I2PAppContext ctx, int level, String msg, Throwable t) {
|
||||
Log l = ctx.logManager().getLog(CertUtil.class);
|
||||
l.log(level, msg, t);
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ package net.i2p.crypto;
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.spec.DSAParameterSpec;
|
||||
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
|
||||
@ -63,4 +64,9 @@ public class CryptoConstants {
|
||||
+ "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
|
||||
+ "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16);
|
||||
public static final BigInteger elgg = new NativeBigInteger("2");
|
||||
|
||||
/**
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public static final DSAParameterSpec DSA_SHA1_SPEC = new DSAParameterSpec(dsap, dsaq, dsag);
|
||||
}
|
||||
|
@ -34,13 +34,14 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.DSAPrivateKeySpec;
|
||||
import java.security.spec.DSAPublicKeySpec;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.interfaces.DSAKey;
|
||||
import java.security.interfaces.ECKey;
|
||||
import java.security.interfaces.RSAKey;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Hash;
|
||||
@ -62,6 +63,12 @@ import net.i2p.util.NativeBigInteger;
|
||||
*
|
||||
* Params and rv's changed from Hash to SHA1Hash for version 0.8.1
|
||||
* Hash variants of sign() and verifySignature() restored in 0.8.3, required by Syndie.
|
||||
*
|
||||
* As of 0.9.9, certain methods support ECDSA keys and signatures, i.e. all types
|
||||
* specified in SigType. The type is specified by the getType() method in
|
||||
* Signature, SigningPublicKey, and SigningPrivateKey. See Javadocs for individual
|
||||
* methods for the supported types. Methods encountering an unsupported type
|
||||
* will throw an IllegalArgumentException.
|
||||
*/
|
||||
public class DSAEngine {
|
||||
private final Log _log;
|
||||
@ -80,11 +87,26 @@ public class DSAEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify using DSA-SHA1.
|
||||
* Uses TheCrypto code unless configured to use the java.security libraries.
|
||||
* Verify using DSA-SHA1 or ECDSA.
|
||||
* Uses TheCrypto code for DSA-SHA1 unless configured to use the java.security libraries.
|
||||
*/
|
||||
public boolean verifySignature(Signature signature, byte signedData[], SigningPublicKey verifyingKey) {
|
||||
boolean rv;
|
||||
SigType type = signature.getType();
|
||||
if (type != verifyingKey.getType())
|
||||
throw new IllegalArgumentException("type mismatch sig=" + signature.getType() + " key=" + verifyingKey.getType());
|
||||
if (type != SigType.DSA_SHA1) {
|
||||
try {
|
||||
rv = altVerifySig(signature, signedData, verifyingKey);
|
||||
if ((!rv) && _log.shouldLog(Log.WARN))
|
||||
_log.warn(type + " Sig Verify Fail");
|
||||
return rv;
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(type + " Sig Verify Fail", gse);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (_useJavaLibs) {
|
||||
try {
|
||||
rv = altVerifySigSHA1(signature, signedData, verifyingKey);
|
||||
@ -104,25 +126,29 @@ public class DSAEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify using DSA-SHA1
|
||||
* Verify using DSA-SHA1 ONLY
|
||||
*/
|
||||
public boolean verifySignature(Signature signature, byte signedData[], int offset, int size, SigningPublicKey verifyingKey) {
|
||||
return verifySignature(signature, calculateHash(signedData, offset, size), verifyingKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify using DSA-SHA1
|
||||
* Verify using DSA-SHA1 ONLY
|
||||
*/
|
||||
public boolean verifySignature(Signature signature, InputStream in, SigningPublicKey verifyingKey) {
|
||||
return verifySignature(signature, calculateHash(in), verifyingKey);
|
||||
}
|
||||
|
||||
/** @param hash SHA-1 hash, NOT a SHA-256 hash */
|
||||
/**
|
||||
* Verify using DSA-SHA1 ONLY
|
||||
* @param hash SHA-1 hash, NOT a SHA-256 hash
|
||||
*/
|
||||
public boolean verifySignature(Signature signature, SHA1Hash hash, SigningPublicKey verifyingKey) {
|
||||
return verifySig(signature, hash, verifyingKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nonstandard.
|
||||
* Used by Syndie.
|
||||
* @since 0.8.3 (restored, was removed in 0.8.1 and 0.8.2)
|
||||
*/
|
||||
@ -131,10 +157,58 @@ public class DSAEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic signature type.
|
||||
*
|
||||
* @param hash SHA1Hash, Hash, Hash384, or Hash512
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public boolean verifySignature(Signature signature, SimpleDataStructure hash, SigningPublicKey verifyingKey) {
|
||||
SigType type = signature.getType();
|
||||
if (type != verifyingKey.getType())
|
||||
throw new IllegalArgumentException("type mismatch sig=" + type + " key=" + verifyingKey.getType());
|
||||
int hashlen = type.getHashLen();
|
||||
if (hash.length() != hashlen)
|
||||
throw new IllegalArgumentException("type mismatch hash=" + hash.getClass() + " sig=" + type);
|
||||
if (type == SigType.DSA_SHA1)
|
||||
return verifySig(signature, hash, verifyingKey);
|
||||
try {
|
||||
return altVerifySigRaw(signature, hash, verifyingKey);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(type + " Sig Verify Fail", gse);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic signature type.
|
||||
* If you have a Java pubkey, use this, so you don't lose the key parameters,
|
||||
* which may be different than the ones defined in SigType.
|
||||
*
|
||||
* @param hash SHA1Hash, Hash, Hash384, or Hash512
|
||||
* @param pubKey Java key
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public boolean verifySignature(Signature signature, SimpleDataStructure hash, PublicKey pubKey) {
|
||||
try {
|
||||
return altVerifySigRaw(signature, hash, pubKey);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(signature.getType() + " Sig Verify Fail", gse);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify using DSA-SHA1 or Syndie DSA-SHA256 ONLY.
|
||||
* @param hash either a Hash or a SHA1Hash
|
||||
* @since 0.8.3
|
||||
*/
|
||||
private boolean verifySig(Signature signature, SimpleDataStructure hash, SigningPublicKey verifyingKey) {
|
||||
if (signature.getType() != SigType.DSA_SHA1)
|
||||
throw new IllegalArgumentException("Bad sig type " + signature.getType());
|
||||
if (verifyingKey.getType() != SigType.DSA_SHA1)
|
||||
throw new IllegalArgumentException("Bad key type " + verifyingKey.getType());
|
||||
long start = _context.clock().now();
|
||||
|
||||
try {
|
||||
@ -184,10 +258,22 @@ public class DSAEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign using DSA-SHA1.
|
||||
* Sign using DSA-SHA1 or ECDSA.
|
||||
* Uses TheCrypto code unless configured to use the java.security libraries.
|
||||
*
|
||||
* @return null on error
|
||||
*/
|
||||
public Signature sign(byte data[], SigningPrivateKey signingKey) {
|
||||
SigType type = signingKey.getType();
|
||||
if (type != SigType.DSA_SHA1) {
|
||||
try {
|
||||
return altSign(data, signingKey);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(type + " Sign Fail", gse);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (_useJavaLibs) {
|
||||
try {
|
||||
return altSignSHA1(data, signingKey);
|
||||
@ -201,7 +287,9 @@ public class DSAEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign using DSA-SHA1
|
||||
* Sign using DSA-SHA1 ONLY
|
||||
*
|
||||
* @return null on error
|
||||
*/
|
||||
public Signature sign(byte data[], int offset, int length, SigningPrivateKey signingKey) {
|
||||
if ((signingKey == null) || (data == null) || (data.length <= 0)) return null;
|
||||
@ -210,8 +298,10 @@ public class DSAEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign using DSA-SHA1.
|
||||
* Sign using DSA-SHA1 ONLY.
|
||||
* Reads the stream until EOF. Does not close the stream.
|
||||
*
|
||||
* @return null on error
|
||||
*/
|
||||
public Signature sign(InputStream in, SigningPrivateKey signingKey) {
|
||||
if ((signingKey == null) || (in == null) ) return null;
|
||||
@ -219,13 +309,21 @@ public class DSAEngine {
|
||||
return sign(h, signingKey);
|
||||
}
|
||||
|
||||
/** @param hash SHA-1 hash, NOT a SHA-256 hash */
|
||||
/**
|
||||
* Sign using DSA-SHA1 ONLY.
|
||||
*
|
||||
* @param hash SHA-1 hash, NOT a SHA-256 hash
|
||||
* @return null on error
|
||||
*/
|
||||
public Signature sign(SHA1Hash hash, SigningPrivateKey signingKey) {
|
||||
return signIt(hash, signingKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Nonstandard.
|
||||
* Used by Syndie.
|
||||
*
|
||||
* @return null on error
|
||||
* @since 0.8.3 (restored, was removed in 0.8.1 and 0.8.2)
|
||||
*/
|
||||
public Signature sign(Hash hash, SigningPrivateKey signingKey) {
|
||||
@ -233,11 +331,64 @@ public class DSAEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic signature type.
|
||||
*
|
||||
* @param hash SHA1Hash, Hash, Hash384, or Hash512
|
||||
* @return null on error
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public Signature sign(SimpleDataStructure hash, SigningPrivateKey signingKey) {
|
||||
SigType type = signingKey.getType();
|
||||
int hashlen = type.getHashLen();
|
||||
if (hash.length() != hashlen)
|
||||
throw new IllegalArgumentException("type mismatch hash=" + hash.getClass() + " key=" + type);
|
||||
if (type == SigType.DSA_SHA1)
|
||||
return signIt(hash, signingKey);
|
||||
try {
|
||||
return altSignRaw(hash, signingKey);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(type + " Sign Fail", gse);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic signature type.
|
||||
* If you have a Java privkey, use this, so you don't lose the key parameters,
|
||||
* which may be different than the ones defined in SigType.
|
||||
*
|
||||
* @param hash SHA1Hash, Hash, Hash384, or Hash512
|
||||
* @param privKey Java key
|
||||
* @param type returns a Signature of this type
|
||||
* @return null on error
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public Signature sign(SimpleDataStructure hash, PrivateKey privKey, SigType type) {
|
||||
String algo = getRawAlgo(privKey);
|
||||
String talgo = getRawAlgo(type);
|
||||
if (!algo.equals(talgo))
|
||||
throw new IllegalArgumentException("type mismatch type=" + type + " key=" + privKey.getClass().getSimpleName());
|
||||
try {
|
||||
return altSignRaw(algo, hash, privKey, type);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(type + " Sign Fail", gse);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign using DSA-SHA1 or Syndie DSA-SHA256 ONLY.
|
||||
*
|
||||
* @param hash either a Hash or a SHA1Hash
|
||||
* @return null on error
|
||||
* @since 0.8.3
|
||||
*/
|
||||
private Signature signIt(SimpleDataStructure hash, SigningPrivateKey signingKey) {
|
||||
if ((signingKey == null) || (hash == null)) return null;
|
||||
if (signingKey.getType() != SigType.DSA_SHA1)
|
||||
throw new IllegalArgumentException("Bad key type " + signingKey.getType());
|
||||
long start = _context.clock().now();
|
||||
|
||||
Signature sig = new Signature();
|
||||
@ -275,8 +426,11 @@ public class DSAEngine {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
out[i] = rbytes[i + 1];
|
||||
}
|
||||
} else if (rbytes.length > 21) {
|
||||
_log.error("Bad R length " + rbytes.length);
|
||||
return null;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG)) _log.debug("Using short rbytes.length [" + rbytes.length + "]");
|
||||
//if (_log.shouldLog(Log.DEBUG)) _log.debug("Using short rbytes.length [" + rbytes.length + "]");
|
||||
//System.arraycopy(rbytes, 0, out, 20 - rbytes.length, rbytes.length);
|
||||
for (int i = 0; i < rbytes.length; i++)
|
||||
out[i + 20 - rbytes.length] = rbytes[i];
|
||||
@ -291,8 +445,11 @@ public class DSAEngine {
|
||||
for (int i = 0; i < 20; i++) {
|
||||
out[i + 20] = sbytes[i + 1];
|
||||
}
|
||||
} else if (sbytes.length > 21) {
|
||||
_log.error("Bad S length " + sbytes.length);
|
||||
return null;
|
||||
} else {
|
||||
if (_log.shouldLog(Log.DEBUG)) _log.debug("Using short sbytes.length [" + sbytes.length + "]");
|
||||
//if (_log.shouldLog(Log.DEBUG)) _log.debug("Using short sbytes.length [" + sbytes.length + "]");
|
||||
//System.arraycopy(sbytes, 0, out, 40 - sbytes.length, sbytes.length);
|
||||
for (int i = 0; i < sbytes.length; i++)
|
||||
out[i + 20 + 20 - sbytes.length] = sbytes[i];
|
||||
@ -337,6 +494,66 @@ public class DSAEngine {
|
||||
return new SHA1Hash(digested);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic verify DSA_SHA1, ECDSA, or RSA
|
||||
* @throws GeneralSecurityException if algorithm unvailable or on other errors
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private boolean altVerifySig(Signature signature, byte[] data, SigningPublicKey verifyingKey)
|
||||
throws GeneralSecurityException {
|
||||
SigType type = signature.getType();
|
||||
if (type != verifyingKey.getType())
|
||||
throw new IllegalArgumentException("type mismatch sig=" + type + " key=" + verifyingKey.getType());
|
||||
if (type == SigType.DSA_SHA1)
|
||||
return altVerifySigSHA1(signature, data, verifyingKey);
|
||||
|
||||
java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName());
|
||||
PublicKey pubKey = SigUtil.toJavaKey(verifyingKey);
|
||||
jsig.initVerify(pubKey);
|
||||
jsig.update(data);
|
||||
boolean rv = jsig.verify(SigUtil.toJavaSig(signature));
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic raw verify any type
|
||||
* @throws GeneralSecurityException if algorithm unvailable or on other errors
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private boolean altVerifySigRaw(Signature signature, SimpleDataStructure hash, SigningPublicKey verifyingKey)
|
||||
throws GeneralSecurityException {
|
||||
SigType type = signature.getType();
|
||||
if (type != verifyingKey.getType())
|
||||
throw new IllegalArgumentException("type mismatch sig=" + type + " key=" + verifyingKey.getType());
|
||||
|
||||
PublicKey pubKey = SigUtil.toJavaKey(verifyingKey);
|
||||
return verifySignature(signature, hash, pubKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic raw verify any type.
|
||||
* If you have a Java pubkey, use this, so you don't lose the key parameters,
|
||||
* which may be different than the ones defined in SigType.
|
||||
*
|
||||
* @throws GeneralSecurityException if algorithm unvailable or on other errors
|
||||
* @param verifyingKey Java key
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private boolean altVerifySigRaw(Signature signature, SimpleDataStructure hash, PublicKey pubKey)
|
||||
throws GeneralSecurityException {
|
||||
SigType type = signature.getType();
|
||||
int hashlen = hash.length();
|
||||
if (type.getHashLen() != hashlen)
|
||||
throw new IllegalArgumentException("type mismatch hash=" + hash.getClass() + " key=" + type);
|
||||
|
||||
String algo = getRawAlgo(type);
|
||||
java.security.Signature jsig = java.security.Signature.getInstance(algo);
|
||||
jsig.initVerify(pubKey);
|
||||
jsig.update(hash.getData());
|
||||
boolean rv = jsig.verify(SigUtil.toJavaSig(signature));
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternate to verifySignature() using java.security libraries.
|
||||
* @throws GeneralSecurityException if algorithm unvailable or on other errors
|
||||
@ -344,16 +561,10 @@ public class DSAEngine {
|
||||
*/
|
||||
private boolean altVerifySigSHA1(Signature signature, byte[] data, SigningPublicKey verifyingKey) throws GeneralSecurityException {
|
||||
java.security.Signature jsig = java.security.Signature.getInstance("SHA1withDSA");
|
||||
KeyFactory keyFact = KeyFactory.getInstance("DSA");
|
||||
// y p q g
|
||||
KeySpec spec = new DSAPublicKeySpec(new NativeBigInteger(1, verifyingKey.getData()),
|
||||
CryptoConstants.dsap,
|
||||
CryptoConstants.dsaq,
|
||||
CryptoConstants.dsag);
|
||||
PublicKey pubKey = keyFact.generatePublic(spec);
|
||||
PublicKey pubKey = SigUtil.toJavaDSAKey(verifyingKey);
|
||||
jsig.initVerify(pubKey);
|
||||
jsig.update(data);
|
||||
boolean rv = jsig.verify(sigBytesToASN1(signature.getData()));
|
||||
boolean rv = jsig.verify(SigUtil.toJavaSig(signature));
|
||||
//if (!rv) {
|
||||
// System.out.println("BAD SIG\n" + net.i2p.util.HexDump.dump(signature.getData()));
|
||||
// System.out.println("BAD SIG\n" + net.i2p.util.HexDump.dump(sigBytesToASN1(signature.getData())));
|
||||
@ -361,6 +572,56 @@ public class DSAEngine {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic sign DSA_SHA1, ECDSA, or RSA
|
||||
* @throws GeneralSecurityException if algorithm unvailable or on other errors
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private Signature altSign(byte[] data, SigningPrivateKey privateKey) throws GeneralSecurityException {
|
||||
SigType type = privateKey.getType();
|
||||
if (type == SigType.DSA_SHA1)
|
||||
return altSignSHA1(data, privateKey);
|
||||
|
||||
java.security.Signature jsig = java.security.Signature.getInstance(type.getAlgorithmName());
|
||||
PrivateKey privKey = SigUtil.toJavaKey(privateKey);
|
||||
jsig.initSign(privKey, _context.random());
|
||||
jsig.update(data);
|
||||
return SigUtil.fromJavaSig(jsig.sign(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic raw verify any type
|
||||
* @param hash SHA1Hash, Hash, Hash384, or Hash512
|
||||
* @throws GeneralSecurityException if algorithm unvailable or on other errors
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private Signature altSignRaw(SimpleDataStructure hash, SigningPrivateKey privateKey) throws GeneralSecurityException {
|
||||
SigType type = privateKey.getType();
|
||||
String algo = getRawAlgo(type);
|
||||
java.security.Signature jsig = java.security.Signature.getInstance(algo);
|
||||
PrivateKey privKey = SigUtil.toJavaKey(privateKey);
|
||||
return altSignRaw(algo, hash, privKey, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic raw verify any type
|
||||
* @param hash SHA1Hash, Hash, Hash384, or Hash512
|
||||
* @param type returns a Signature of this type
|
||||
* @throws GeneralSecurityException if algorithm unvailable or on other errors
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private Signature altSignRaw(String algo, SimpleDataStructure hash, PrivateKey privKey, SigType type)
|
||||
throws GeneralSecurityException {
|
||||
int hashlen = hash.length();
|
||||
if (type.getHashLen() != hashlen)
|
||||
throw new IllegalArgumentException("type mismatch hash=" + hash.getClass() + " key=" + type);
|
||||
|
||||
java.security.Signature jsig = java.security.Signature.getInstance(algo);
|
||||
jsig.initSign(privKey, _context.random());
|
||||
jsig.update(hash.getData());
|
||||
return SigUtil.fromJavaSig(jsig.sign(), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alternate to sign() using java.security libraries.
|
||||
* @throws GeneralSecurityException if algorithm unvailable or on other errors
|
||||
@ -368,90 +629,35 @@ public class DSAEngine {
|
||||
*/
|
||||
private Signature altSignSHA1(byte[] data, SigningPrivateKey privateKey) throws GeneralSecurityException {
|
||||
java.security.Signature jsig = java.security.Signature.getInstance("SHA1withDSA");
|
||||
KeyFactory keyFact = KeyFactory.getInstance("DSA");
|
||||
// y p q g
|
||||
KeySpec spec = new DSAPrivateKeySpec(new NativeBigInteger(1, privateKey.getData()),
|
||||
CryptoConstants.dsap,
|
||||
CryptoConstants.dsaq,
|
||||
CryptoConstants.dsag);
|
||||
PrivateKey privKey = keyFact.generatePrivate(spec);
|
||||
PrivateKey privKey = SigUtil.toJavaDSAKey(privateKey);
|
||||
jsig.initSign(privKey, _context.random());
|
||||
jsig.update(data);
|
||||
return new Signature(aSN1ToSigBytes(jsig.sign()));
|
||||
return SigUtil.fromJavaSig(jsig.sign(), SigType.DSA_SHA1);
|
||||
}
|
||||
|
||||
/**
|
||||
* http://download.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html
|
||||
* Signature Format ASN.1 sequence of two INTEGER values: r and s, in that order:
|
||||
* SEQUENCE ::= { r INTEGER, s INTEGER }
|
||||
*
|
||||
* http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One
|
||||
* 30 -- tag indicating SEQUENCE
|
||||
* xx - length in octets
|
||||
*
|
||||
* 02 -- tag indicating INTEGER
|
||||
* xx - length in octets
|
||||
* xxxxxx - value
|
||||
*
|
||||
* Convert to BigInteger and back so we have the minimum length representation, as required.
|
||||
* r and s are always non-negative.
|
||||
*
|
||||
* @since 0.8.7
|
||||
*/
|
||||
private static byte[] sigBytesToASN1(byte[] sig) {
|
||||
//System.out.println("pre TO asn1\n" + net.i2p.util.HexDump.dump(sig));
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(48);
|
||||
baos.write(0x30);
|
||||
baos.write(0); // length to be filled in below
|
||||
|
||||
byte[] tmp = new byte[20];
|
||||
baos.write(2);
|
||||
System.arraycopy(sig, 0, tmp, 0, 20);
|
||||
BigInteger r = new BigInteger(1, tmp);
|
||||
byte[] b = r.toByteArray();
|
||||
baos.write(b.length);
|
||||
baos.write(b, 0, b.length);
|
||||
|
||||
baos.write(2);
|
||||
System.arraycopy(sig, 20, tmp, 0, 20);
|
||||
BigInteger s = new BigInteger(1, tmp);
|
||||
b = s.toByteArray();
|
||||
baos.write(b.length);
|
||||
baos.write(b, 0, b.length);
|
||||
byte[] rv = baos.toByteArray();
|
||||
rv[1] = (byte) (rv.length - 2);
|
||||
//System.out.println("post TO asn1\n" + net.i2p.util.HexDump.dump(rv));
|
||||
return rv;
|
||||
/** @since 0.9.9 */
|
||||
private static String getRawAlgo(SigType type) {
|
||||
switch (type.getBaseAlgorithm()) {
|
||||
case DSA:
|
||||
return "NONEwithDSA";
|
||||
case EC:
|
||||
return "NONEwithECDSA";
|
||||
case RSA:
|
||||
return "NONEwithRSA";
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See above.
|
||||
* @since 0.8.7
|
||||
*/
|
||||
private static byte[] aSN1ToSigBytes(byte[] asn) {
|
||||
//System.out.println("pre from asn1\n" + net.i2p.util.HexDump.dump(asn));
|
||||
byte[] rv = new byte[40];
|
||||
int rlen = asn[3];
|
||||
if ((asn[4] & 0x80) != 0)
|
||||
throw new IllegalArgumentException("R is negative");
|
||||
if (rlen > 21)
|
||||
throw new IllegalArgumentException("R too big " + rlen);
|
||||
else if (rlen == 21) {
|
||||
System.arraycopy(asn, 5, rv, 0, 20);
|
||||
} else
|
||||
System.arraycopy(asn, 4, rv, 20 - rlen, rlen);
|
||||
int slenloc = 25 + rlen - 20;
|
||||
int slen = asn[slenloc];
|
||||
if ((asn[slenloc + 1] & 0x80) != 0)
|
||||
throw new IllegalArgumentException("S is negative");
|
||||
if (slen > 21)
|
||||
throw new IllegalArgumentException("S too big " + slen);
|
||||
else if (slen == 21) {
|
||||
System.arraycopy(asn, slenloc + 2, rv, 20, 20);
|
||||
} else
|
||||
System.arraycopy(asn, slenloc + 1, rv, 40 - slen, slen);
|
||||
//System.out.println("post from asn1\n" + net.i2p.util.HexDump.dump(rv));
|
||||
return rv;
|
||||
/** @since 0.9.9 */
|
||||
private static String getRawAlgo(Key key) {
|
||||
if (key instanceof DSAKey)
|
||||
return "NONEwithDSA";
|
||||
if (key instanceof ECKey)
|
||||
return "NONEwithECDSA";
|
||||
if (key instanceof RSAKey)
|
||||
return "NONEwithRSA";
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
//private static final int RUNS = 1000;
|
||||
|
62
core/java/src/net/i2p/crypto/DirKeyRing.java
Normal file
62
core/java/src/net/i2p/crypto/DirKeyRing.java
Normal file
@ -0,0 +1,62 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* No warranty of any kind, either expressed or implied.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
* Dumb storage in a directory for testing.
|
||||
* No sanitization of filenames, unsafe.
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
class DirKeyRing implements KeyRing {
|
||||
|
||||
private final File _base;
|
||||
|
||||
public DirKeyRing(File baseDir) {
|
||||
_base = baseDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cert must be in the file (escaped keyName).crt,
|
||||
* and have a CN == keyName
|
||||
*/
|
||||
public PublicKey getKey(String keyName, String scope, SigType type)
|
||||
throws GeneralSecurityException, IOException {
|
||||
String fileName = keyName.replace("@", "_at_").replace("<", "_").replace(">", "_");
|
||||
File test = new File(fileName);
|
||||
if (test.getParent() != null)
|
||||
throw new IOException("bad key name");
|
||||
File sd = new File(_base, scope);
|
||||
//File td = new File(sd, Integer.toString(type.getCode()));
|
||||
File kd = new File(sd, fileName + ".crt");
|
||||
if (!kd.exists())
|
||||
return null;
|
||||
InputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(kd);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
X509Certificate cert = (X509Certificate)cf.generateCertificate(fis);
|
||||
cert.checkValidity();
|
||||
String cn = CertUtil.getSubjectValue(cert, "CN");
|
||||
if (!keyName.equals(cn))
|
||||
throw new GeneralSecurityException("CN mismatch: " + cn);
|
||||
return cert.getPublicKey();
|
||||
} finally {
|
||||
try { if (fis != null) fis.close(); } catch (IOException foo) {}
|
||||
}
|
||||
}
|
||||
|
||||
public void setKey(String keyName, String scope, PublicKey key) {}
|
||||
}
|
337
core/java/src/net/i2p/crypto/ECConstants.java
Normal file
337
core/java/src/net/i2p/crypto/ECConstants.java
Normal file
@ -0,0 +1,337 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.math.BigInteger;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.AlgorithmParameterGenerator;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.spec.AlgorithmParameterSpec;
|
||||
import java.security.spec.ECField;
|
||||
import java.security.spec.ECFieldFp;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.security.spec.ECPoint;
|
||||
import java.security.spec.EllipticCurve;
|
||||
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
|
||||
/**
|
||||
* Constants for elliptic curves, from NIST FIPS 186-4 (2013) / ANSI X9.62
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
class ECConstants {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static void log(String s) {
|
||||
log(s, null);
|
||||
}
|
||||
|
||||
private static void log(String s, Throwable t) {
|
||||
if (DEBUG) {
|
||||
System.out.println("ECConstants: " + s);
|
||||
if (t != null)
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static final boolean BC_AVAILABLE;
|
||||
|
||||
static {
|
||||
boolean loaded;
|
||||
if (Security.getProvider("BC") == null) {
|
||||
try {
|
||||
Class cls = Class.forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
|
||||
Constructor con = cls.getConstructor(new Class[0]);
|
||||
Provider bc = (Provider)con.newInstance(new Object[0]);
|
||||
Security.addProvider(bc);
|
||||
log("Added BC provider");
|
||||
loaded = true;
|
||||
} catch (Exception e) {
|
||||
log("Unable to add BC provider", e);
|
||||
loaded = false;
|
||||
}
|
||||
} else {
|
||||
log("BC provider already loaded");
|
||||
loaded = true;
|
||||
}
|
||||
BC_AVAILABLE = true;
|
||||
}
|
||||
|
||||
public static boolean isBCAvailable() { return BC_AVAILABLE; }
|
||||
|
||||
private static class ECParms {
|
||||
public final String ps, ns, ss, bs, gxs, gys;
|
||||
private static final BigInteger A = new NativeBigInteger("-3");
|
||||
private static final int H = 1;
|
||||
|
||||
/**
|
||||
* P and N in decimal, no spaces;
|
||||
* Seed, B, Gx, Gy in hex, spaces allowed
|
||||
*/
|
||||
public ECParms(String pss, String nss, String sss, String bss, String gxss, String gyss) {
|
||||
ps = pss; ns = nss; ss = sss; bs = bss; gxs = gxss; gys = gyss;
|
||||
}
|
||||
|
||||
public ECParameterSpec genSpec() {
|
||||
BigInteger pb = new NativeBigInteger(ps);
|
||||
BigInteger nb = new NativeBigInteger(ns);
|
||||
BigInteger sb = new NativeBigInteger(ss.replace(" ", ""), 16);
|
||||
BigInteger bb = new NativeBigInteger(bs.replace(" ", ""), 16);
|
||||
BigInteger gxb = new NativeBigInteger(gxs.replace(" ", ""), 16);
|
||||
BigInteger gyb = new NativeBigInteger(gys.replace(" ", ""), 16);
|
||||
BigInteger ab = new NativeBigInteger(A.mod(pb));
|
||||
ECField field = new ECFieldFp(pb);
|
||||
EllipticCurve curve = new EllipticCurve(field, ab, bb, sb.toByteArray());
|
||||
ECPoint g = new ECPoint(gxb, gyb);
|
||||
return new ECParameterSpec(curve, g, nb, H);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
D.1.2 Curves over Prime Fields
|
||||
|
||||
For each prime p, a pseudo-random curve
|
||||
E : y**2 = x**3 -3x +b (mod p)
|
||||
of prime order n is listed 4. (Thus, for these curves, the cofactor is always h = 1.) The following
|
||||
parameters are given:
|
||||
|
||||
The selection a a = -3 for the coefficient of x was made for reasons of efficiency; see IEEE Std 1363-2000.
|
||||
|
||||
* The prime modulus p
|
||||
* The order n
|
||||
* The 160-bit input seed SEED to the SHA-1 based algorithm (i.e., the domain parameter
|
||||
seed)
|
||||
* The output c of the SHA-1 based algorithm
|
||||
* The coefficient b (satisfying b**2 c = -27 (mod p))
|
||||
* The base point x coordinate G x
|
||||
* The base point y coordinate G y
|
||||
The integers p and n are given in decimal form; bit strings and field elements are given in
|
||||
hexadecimal.
|
||||
*/
|
||||
|
||||
/*
|
||||
D.1.2.1 Curve P-192
|
||||
|
||||
p= 6277101735386680763835789423207666416083908700390324961279
|
||||
n= 6277101735386680763835789423176059013767194773182842284081
|
||||
SEED = 3045ae6f c8422f64 ed579528 d38120ea e12196d5
|
||||
c= 3099d2bb bfcb2538 542dcd5f b078b6ef 5f3d6fe2 c745de65
|
||||
b= 64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1
|
||||
Gx= 188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012
|
||||
Gy= 07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811
|
||||
*/
|
||||
|
||||
private static final ECParms PARM_P192 = new ECParms(
|
||||
// P N Seed B Gx Gy
|
||||
"6277101735386680763835789423207666416083908700390324961279",
|
||||
"6277101735386680763835789423176059013767194773182842284081",
|
||||
"3045ae6f c8422f64 ed579528 d38120ea e12196d5",
|
||||
"64210519 e59c80e7 0fa7e9ab 72243049 feb8deec c146b9b1",
|
||||
"188da80e b03090f6 7cbf20eb 43a18800 f4ff0afd 82ff1012",
|
||||
"07192b95 ffc8da78 631011ed 6b24cdd5 73f977a1 1e794811"
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
D.1.2.3 Curve P-256
|
||||
|
||||
p=
|
||||
1157920892103562487626974469494075735300861434152903141955
|
||||
33631308867097853951
|
||||
n=
|
||||
115792089210356248762697446949407573529996955224135760342
|
||||
422259061068512044369
|
||||
SEED = c49d3608 86e70493 6a6678e1 139d26b7 819f7e90
|
||||
c=
|
||||
7efba166 2985be94 03cb055c 75d4f7e0 ce8d84a9 c5114abc
|
||||
af317768 0104fa0d
|
||||
b=
|
||||
5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6
|
||||
3bce3c3e 27d2604b
|
||||
Gx=
|
||||
6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0
|
||||
f4a13945 d898c296
|
||||
Gy=
|
||||
4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece
|
||||
cbb64068 37bf51f5
|
||||
*/
|
||||
|
||||
private static final ECParms PARM_P256 = new ECParms(
|
||||
// P N Seed B Gx Gy
|
||||
"1157920892103562487626974469494075735300861434152903141955" +
|
||||
"33631308867097853951",
|
||||
"115792089210356248762697446949407573529996955224135760342" +
|
||||
"422259061068512044369",
|
||||
"c49d3608 86e70493 6a6678e1 139d26b7 819f7e90",
|
||||
"5ac635d8 aa3a93e7 b3ebbd55 769886bc 651d06b0 cc53b0f6" +
|
||||
"3bce3c3e 27d2604b",
|
||||
"6b17d1f2 e12c4247 f8bce6e5 63a440f2 77037d81 2deb33a0" +
|
||||
"f4a13945 d898c296",
|
||||
"4fe342e2 fe1a7f9b 8ee7eb4a 7c0f9e16 2bce3357 6b315ece" +
|
||||
"cbb64068 37bf51f5"
|
||||
);
|
||||
|
||||
/*
|
||||
D.1.2.4 Curve P-384
|
||||
|
||||
p=
|
||||
3940200619639447921227904010014361380507973927046544666794
|
||||
8293404245721771496870329047266088258938001861606973112319
|
||||
n=
|
||||
3940200619639447921227904010014361380507973927046544666794
|
||||
6905279627659399113263569398956308152294913554433653942643
|
||||
SEED = a335926a a319a27a 1d00896a 6773a482 7acdac73
|
||||
c=
|
||||
79d1e655 f868f02f ff48dcde e14151dd b80643c1 406d0ca1
|
||||
0dfe6fc5 2009540a 495e8042 ea5f744f 6e184667 cc722483
|
||||
b=
|
||||
b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112
|
||||
0314088f 5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef
|
||||
Gx=
|
||||
aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98
|
||||
59f741e0 82542a38 5502f25d bf55296c 3a545e38 72760ab7
|
||||
G y=
|
||||
3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c
|
||||
e9da3113 b5f0b8c0 0a60b1ce 1d7e819d 7a431d7c 90ea0e5f
|
||||
*/
|
||||
|
||||
private static final ECParms PARM_P384 = new ECParms(
|
||||
// P N Seed B Gx Gy
|
||||
"3940200619639447921227904010014361380507973927046544666794" +
|
||||
"8293404245721771496870329047266088258938001861606973112319",
|
||||
"3940200619639447921227904010014361380507973927046544666794" +
|
||||
"6905279627659399113263569398956308152294913554433653942643",
|
||||
"a335926a a319a27a 1d00896a 6773a482 7acdac73",
|
||||
"b3312fa7 e23ee7e4 988e056b e3f82d19 181d9c6e fe814112" +
|
||||
"0314088f 5013875a c656398d 8a2ed19d 2a85c8ed d3ec2aef",
|
||||
"aa87ca22 be8b0537 8eb1c71e f320ad74 6e1d3b62 8ba79b98" +
|
||||
"59f741e0 82542a38 5502f25d bf55296c 3a545e38 72760ab7",
|
||||
"3617de4a 96262c6f 5d9e98bf 9292dc29 f8f41dbd 289a147c" +
|
||||
"e9da3113 b5f0b8c0 0a60b1ce 1d7e819d 7a431d7c 90ea0e5f"
|
||||
);
|
||||
|
||||
/*
|
||||
D.1.2.5 Curve P-521
|
||||
|
||||
p=
|
||||
686479766013060971498190079908139321726943530014330540939
|
||||
446345918554318339765605212255964066145455497729631139148
|
||||
0858037121987999716643812574028291115057151
|
||||
n=
|
||||
686479766013060971498190079908139321726943530014330540939
|
||||
446345918554318339765539424505774633321719753296399637136
|
||||
3321113864768612440380340372808892707005449
|
||||
SEED = d09e8800 291cb853 96cc6717 393284aa a0da64ba
|
||||
c=
|
||||
0b4 8bfa5f42 0a349495 39d2bdfc 264eeeeb 077688e4
|
||||
4fbf0ad8 f6d0edb3 7bd6b533 28100051 8e19f1b9 ffbe0fe9
|
||||
ed8a3c22 00b8f875 e523868c 70c1e5bf 55bad637
|
||||
b=
|
||||
051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b
|
||||
99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd
|
||||
3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00
|
||||
Gx=
|
||||
c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139
|
||||
053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127
|
||||
a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66
|
||||
Gy=
|
||||
118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449
|
||||
579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901
|
||||
3fad0761 353c7086 a272c240 88be9476 9fd16650
|
||||
*/
|
||||
|
||||
private static final ECParms PARM_P521 = new ECParms(
|
||||
"686479766013060971498190079908139321726943530014330540939" +
|
||||
"446345918554318339765605212255964066145455497729631139148" +
|
||||
"0858037121987999716643812574028291115057151",
|
||||
"686479766013060971498190079908139321726943530014330540939" +
|
||||
"446345918554318339765539424505774633321719753296399637136" +
|
||||
"3321113864768612440380340372808892707005449",
|
||||
"d09e8800 291cb853 96cc6717 393284aa a0da64ba",
|
||||
"051 953eb961 8e1c9a1f 929a21a0 b68540ee a2da725b" +
|
||||
"99b315f3 b8b48991 8ef109e1 56193951 ec7e937b 1652c0bd" +
|
||||
"3bb1bf07 3573df88 3d2c34f1 ef451fd4 6b503f00",
|
||||
"c6 858e06b7 0404e9cd 9e3ecb66 2395b442 9c648139" +
|
||||
"053fb521 f828af60 6b4d3dba a14b5e77 efe75928 fe1dc127" +
|
||||
"a2ffa8de 3348b3c1 856a429b f97e7e31 c2e5bd66",
|
||||
"118 39296a78 9a3bc004 5c8a5fb4 2c7d1bd9 98f54449" +
|
||||
"579b4468 17afbd17 273e662c 97ee7299 5ef42640 c550b901" +
|
||||
"3fad0761 353c7086 a272c240 88be9476 9fd16650"
|
||||
);
|
||||
|
||||
/**
|
||||
* Generate a spec from a curve name
|
||||
* @return null if fail
|
||||
*/
|
||||
private static ECParameterSpec genSpec(String name) {
|
||||
// convert the ECGenParameterSpecs to ECParameterSpecs for several reasons:
|
||||
// 1) to check availability
|
||||
// 2) efficiency
|
||||
// 3) SigUtil must cast the AlgorithmParameterSpec to a ECParameterSpec
|
||||
// to convert a I2P key to a Java key. Sadly, a ECGenParameterSpec
|
||||
// is not a ECParameterSpec.
|
||||
try {
|
||||
AlgorithmParameters ap;
|
||||
try {
|
||||
ap = AlgorithmParameters.getInstance("EC");
|
||||
} catch (Exception e) {
|
||||
if (BC_AVAILABLE) {
|
||||
log("Named curve " + name + " is not available, trying BC", e);
|
||||
ap = AlgorithmParameters.getInstance("EC", "BC");
|
||||
log("Fallback to BC worked for named curve " + name);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
ECGenParameterSpec ecgps = new ECGenParameterSpec(name);
|
||||
ap.init(ecgps);
|
||||
ECParameterSpec rv = ap.getParameterSpec(ECParameterSpec.class);
|
||||
log("Named curve " + name + " loaded");
|
||||
return rv;
|
||||
} catch (Exception e) {
|
||||
log("Named curve " + name + " is not available", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries curve name1, then name2, then creates new from parms.
|
||||
* @param name2 null to skip
|
||||
* @param parms null to skip
|
||||
* @return null if all fail
|
||||
*/
|
||||
private static ECParameterSpec genSpec(String name1, String name2, ECParms parms) {
|
||||
ECParameterSpec rv = genSpec(name1);
|
||||
if (rv == null && name2 != null) {
|
||||
rv = genSpec(name2);
|
||||
if (rv == null && parms != null) {
|
||||
rv = parms.genSpec();
|
||||
if (rv != null)
|
||||
log("Curve " + name2 + " created");
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
// standard curve names
|
||||
// first is OpenJDK 6/7
|
||||
// second is BC
|
||||
public static final ECParameterSpec P192_SPEC = genSpec("secp192r1", "P-192", PARM_P192);
|
||||
public static final ECParameterSpec P256_SPEC = genSpec("secp256r1", "P-256", PARM_P256);
|
||||
public static final ECParameterSpec P384_SPEC = genSpec("secp384r1", "P-384", PARM_P384);
|
||||
public static final ECParameterSpec P521_SPEC = genSpec("secp521r1", "P-521", PARM_P521);
|
||||
|
||||
// Koblitz
|
||||
public static final ECParameterSpec K163_SPEC = genSpec("sect163k1", "K-163", null);
|
||||
public static final ECParameterSpec K233_SPEC = genSpec("sect233k1", "K-233", null);
|
||||
public static final ECParameterSpec K283_SPEC = genSpec("sect283k1", "K-283", null);
|
||||
public static final ECParameterSpec K409_SPEC = genSpec("sect409k1", "K-409", null);
|
||||
public static final ECParameterSpec K571_SPEC = genSpec("sect571k1", "K-571", null);
|
||||
|
||||
|
||||
}
|
@ -81,6 +81,7 @@ public class ElGamalEngine {
|
||||
*/
|
||||
public void shutdown() {
|
||||
_ykgen.shutdown();
|
||||
SigUtil.clearCaches();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,6 +10,14 @@ package net.i2p.crypto;
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.ProviderException;
|
||||
import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.spec.ECPoint;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Hash;
|
||||
@ -19,9 +27,17 @@ import net.i2p.data.SessionKey;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.data.SigningPublicKey;
|
||||
import net.i2p.data.SimpleDataStructure;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
|
||||
// main()
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Signature;
|
||||
import net.i2p.util.Clock;
|
||||
import net.i2p.util.RandomSource;
|
||||
|
||||
/** Define a way of generating asymmetrical key pairs as well as symmetrical keys
|
||||
* @author jrandom
|
||||
*/
|
||||
@ -129,14 +145,16 @@ public class KeyGenerator {
|
||||
SimpleDataStructure[] keys = new SimpleDataStructure[2];
|
||||
keys[0] = new PublicKey();
|
||||
keys[1] = new PrivateKey();
|
||||
byte[] k0 = aalpha.toByteArray();
|
||||
byte[] k1 = a.toByteArray();
|
||||
|
||||
// bigInteger.toByteArray returns SIGNED integers, but since they'return positive,
|
||||
// signed two's complement is the same as unsigned
|
||||
|
||||
keys[0].setData(padBuffer(k0, PublicKey.KEYSIZE_BYTES));
|
||||
keys[1].setData(padBuffer(k1, PrivateKey.KEYSIZE_BYTES));
|
||||
try {
|
||||
keys[0].setData(SigUtil.rectify(aalpha, PublicKey.KEYSIZE_BYTES));
|
||||
keys[1].setData(SigUtil.rectify(a, PrivateKey.KEYSIZE_BYTES));
|
||||
} catch (InvalidKeyException ike) {
|
||||
throw new IllegalArgumentException(ike);
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
@ -149,13 +167,18 @@ public class KeyGenerator {
|
||||
BigInteger a = new NativeBigInteger(1, priv.toByteArray());
|
||||
BigInteger aalpha = CryptoConstants.elgg.modPow(a, CryptoConstants.elgp);
|
||||
PublicKey pub = new PublicKey();
|
||||
byte [] pubBytes = aalpha.toByteArray();
|
||||
pub.setData(padBuffer(pubBytes, PublicKey.KEYSIZE_BYTES));
|
||||
try {
|
||||
pub.setData(SigUtil.rectify(aalpha, PublicKey.KEYSIZE_BYTES));
|
||||
} catch (InvalidKeyException ike) {
|
||||
throw new IllegalArgumentException(ike);
|
||||
}
|
||||
return pub;
|
||||
}
|
||||
|
||||
/** Generate a pair of DSA keys, where index 0 is a SigningPublicKey, and
|
||||
* index 1 is a SigningPrivateKey
|
||||
* index 1 is a SigningPrivateKey.
|
||||
* DSA-SHA1 only.
|
||||
*
|
||||
* @return pair of keys
|
||||
*/
|
||||
public Object[] generateSigningKeypair() {
|
||||
@ -163,6 +186,8 @@ public class KeyGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* DSA-SHA1 only.
|
||||
*
|
||||
* Same as above but different return type
|
||||
* @since 0.8.7
|
||||
*/
|
||||
@ -178,15 +203,69 @@ public class KeyGenerator {
|
||||
BigInteger y = CryptoConstants.dsag.modPow(x, CryptoConstants.dsap);
|
||||
keys[0] = new SigningPublicKey();
|
||||
keys[1] = new SigningPrivateKey();
|
||||
byte k0[] = padBuffer(y.toByteArray(), SigningPublicKey.KEYSIZE_BYTES);
|
||||
byte k1[] = padBuffer(x.toByteArray(), SigningPrivateKey.KEYSIZE_BYTES);
|
||||
|
||||
keys[0].setData(k0);
|
||||
keys[1].setData(k1);
|
||||
try {
|
||||
keys[0].setData(SigUtil.rectify(y, SigningPublicKey.KEYSIZE_BYTES));
|
||||
keys[1].setData(SigUtil.rectify(x, SigningPrivateKey.KEYSIZE_BYTES));
|
||||
} catch (InvalidKeyException ike) {
|
||||
throw new IllegalStateException(ike);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
/** Convert a SigningPrivateKey to a SigningPublicKey
|
||||
/**
|
||||
* Generic signature type, supports DSA and ECDSA
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public SimpleDataStructure[] generateSigningKeys(SigType type) throws GeneralSecurityException {
|
||||
if (type == SigType.DSA_SHA1)
|
||||
return generateSigningKeys();
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(type.getBaseAlgorithm().getName());
|
||||
KeyPair kp;
|
||||
try {
|
||||
kpg.initialize(type.getParams(), _context.random());
|
||||
kp = kpg.generateKeyPair();
|
||||
} catch (ProviderException pe) {
|
||||
// java.security.ProviderException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_DOMAIN_PARAMS_INVALID
|
||||
// This is a RuntimeException, thx Sun
|
||||
// Fails for P-192 only, on Ubuntu
|
||||
Log log = _context.logManager().getLog(KeyGenerator.class);
|
||||
String pname = kpg.getProvider().getName();
|
||||
if ("BC".equals(pname)) {
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("BC KPG failed for " + type, pe);
|
||||
throw new GeneralSecurityException("BC KPG for " + type, pe);
|
||||
}
|
||||
if (!ECConstants.isBCAvailable())
|
||||
throw new GeneralSecurityException(pname + " KPG failed for " + type, pe);
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn(pname + " KPG failed for " + type + ", trying BC" /* , pe */ );
|
||||
try {
|
||||
kpg = KeyPairGenerator.getInstance(type.getBaseAlgorithm().getName(), "BC");
|
||||
kpg.initialize(type.getParams(), _context.random());
|
||||
kp = kpg.generateKeyPair();
|
||||
} catch (ProviderException pe2) {
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("BC KPG failed for " + type + " also", pe2);
|
||||
// throw original exception
|
||||
throw new GeneralSecurityException(pname + " KPG for " + type, pe);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
if (log.shouldLog(Log.WARN))
|
||||
log.warn("BC KPG failed for " + type + " also", gse);
|
||||
// throw original exception
|
||||
throw new GeneralSecurityException(pname + " KPG for " + type, pe);
|
||||
}
|
||||
}
|
||||
java.security.PublicKey pubkey = kp.getPublic();
|
||||
java.security.PrivateKey privkey = kp.getPrivate();
|
||||
SimpleDataStructure[] keys = new SimpleDataStructure[2];
|
||||
keys[0] = SigUtil.fromJavaKey(pubkey, type);
|
||||
keys[1] = SigUtil.fromJavaKey(privkey, type);
|
||||
return keys;
|
||||
}
|
||||
|
||||
/** Convert a SigningPrivateKey to a SigningPublicKey.
|
||||
* DSA-SHA1 only.
|
||||
*
|
||||
* @param priv a SigningPrivateKey object
|
||||
* @return a SigningPublicKey object
|
||||
*/
|
||||
@ -194,27 +273,68 @@ public class KeyGenerator {
|
||||
BigInteger x = new NativeBigInteger(1, priv.toByteArray());
|
||||
BigInteger y = CryptoConstants.dsag.modPow(x, CryptoConstants.dsap);
|
||||
SigningPublicKey pub = new SigningPublicKey();
|
||||
byte [] pubBytes = padBuffer(y.toByteArray(), SigningPublicKey.KEYSIZE_BYTES);
|
||||
pub.setData(pubBytes);
|
||||
try {
|
||||
pub.setData(SigUtil.rectify(y, SigningPublicKey.KEYSIZE_BYTES));
|
||||
} catch (InvalidKeyException ike) {
|
||||
throw new IllegalArgumentException(ike);
|
||||
}
|
||||
return pub;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pad the buffer w/ leading 0s or trim off leading bits so the result is the
|
||||
* given length.
|
||||
*/
|
||||
private final static byte[] padBuffer(byte src[], int length) {
|
||||
byte buf[] = new byte[length];
|
||||
public static void main(String args[]) {
|
||||
try {
|
||||
main2(args);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (src.length > buf.length) // extra bits, chop leading bits
|
||||
System.arraycopy(src, src.length - buf.length, buf, 0, buf.length);
|
||||
else if (src.length < buf.length) // short bits, padd w/ 0s
|
||||
System.arraycopy(src, 0, buf, buf.length - src.length, src.length);
|
||||
else
|
||||
// eq
|
||||
System.arraycopy(src, 0, buf, 0, buf.length);
|
||||
public static void main2(String args[]) {
|
||||
RandomSource.getInstance().nextBoolean();
|
||||
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
|
||||
int runs = 200; // warmup
|
||||
for (int j = 0; j < 2; j++) {
|
||||
for (int i = 0; i <= 100; i++) {
|
||||
SigType type = SigType.getByCode(i);
|
||||
if (type == null)
|
||||
break;
|
||||
try {
|
||||
System.out.println("Testing " + type);
|
||||
testSig(type, runs);
|
||||
} catch (Exception e) {
|
||||
System.out.println("error testing " + type);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
runs = 1000;
|
||||
}
|
||||
}
|
||||
|
||||
return buf;
|
||||
private static void testSig(SigType type, int runs) throws GeneralSecurityException {
|
||||
byte src[] = new byte[512];
|
||||
long stime = 0;
|
||||
long vtime = 0;
|
||||
SimpleDataStructure keys[] = KeyGenerator.getInstance().generateSigningKeys(type);
|
||||
//System.out.println("pubkey " + keys[0]);
|
||||
//System.out.println("privkey " + keys[1]);
|
||||
for (int i = 0; i < runs; i++) {
|
||||
RandomSource.getInstance().nextBytes(src);
|
||||
long start = System.nanoTime();
|
||||
Signature sig = DSAEngine.getInstance().sign(src, (SigningPrivateKey) keys[1]);
|
||||
long mid = System.nanoTime();
|
||||
boolean ok = DSAEngine.getInstance().verifySignature(sig, src, (SigningPublicKey) keys[0]);
|
||||
long end = System.nanoTime();
|
||||
stime += mid - start;
|
||||
vtime += end - mid;
|
||||
if (!ok)
|
||||
throw new GeneralSecurityException(type + " V(S(data)) fail");
|
||||
}
|
||||
stime /= 1000*1000;
|
||||
vtime /= 1000*1000;
|
||||
System.out.println(type + " sign/verify " + runs + " times: " + (vtime+stime) + " ms = " +
|
||||
(((double) stime) / runs) + " each sign, " +
|
||||
(((double) vtime) / runs) + " each verify, " +
|
||||
(((double) (stime + vtime)) / runs) + " s+v");
|
||||
}
|
||||
|
||||
/******
|
||||
|
36
core/java/src/net/i2p/crypto/KeyRing.java
Normal file
36
core/java/src/net/i2p/crypto/KeyRing.java
Normal file
@ -0,0 +1,36 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
/*
|
||||
* free (adj.): unencumbered; not under the control of others
|
||||
* No warranty of any kind, either expressed or implied.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.PublicKey;
|
||||
|
||||
/**
|
||||
* A backend for storing and retrieving SigningPublicKeys
|
||||
* to be used for verifying signatures.
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public interface KeyRing {
|
||||
|
||||
/**
|
||||
* Get a key.
|
||||
* Throws on all errors.
|
||||
* @param scope a domain identifier, indicating router update, reseed, etc.
|
||||
* @return null if none
|
||||
*/
|
||||
public PublicKey getKey(String keyName, String scope, SigType type)
|
||||
throws GeneralSecurityException, IOException;
|
||||
|
||||
/**
|
||||
* Store a key.
|
||||
* Throws on all errors.
|
||||
* @param scope a domain identifier, indicating router update, reseed, etc.
|
||||
*/
|
||||
public void setKey(String keyName, String scope, PublicKey key)
|
||||
throws GeneralSecurityException, IOException;
|
||||
}
|
493
core/java/src/net/i2p/crypto/KeyStoreUtil.java
Normal file
493
core/java/src/net/i2p/crypto/KeyStoreUtil.java
Normal file
@ -0,0 +1,493 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SecureDirectory;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
import net.i2p.util.ShellCommand;
|
||||
import net.i2p.util.SystemVersion;
|
||||
|
||||
/**
|
||||
* Keystore utilities, consolidated from various places.
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public class KeyStoreUtil {
|
||||
|
||||
public static final String DEFAULT_KEYSTORE_PASSWORD = "changeit";
|
||||
private static final String DEFAULT_KEY_ALGORITHM = "RSA";
|
||||
private static final int DEFAULT_KEY_SIZE = 2048;
|
||||
private static final int DEFAULT_KEY_VALID_DAYS = 3652; // 10 years
|
||||
|
||||
/**
|
||||
* Create a new KeyStore object, and load it from ksFile if it is
|
||||
* non-null and it exists.
|
||||
* If ksFile is non-null and it does not exist, create a new empty
|
||||
* keystore file.
|
||||
*
|
||||
* @param ksFile may be null
|
||||
* @param password may be null
|
||||
* @return success
|
||||
*/
|
||||
public static KeyStore createKeyStore(File ksFile, String password)
|
||||
throws GeneralSecurityException, IOException {
|
||||
boolean exists = ksFile != null && ksFile.exists();
|
||||
char[] pwchars = password != null ? password.toCharArray() : null;
|
||||
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
if (exists) {
|
||||
InputStream fis = new FileInputStream(ksFile);
|
||||
ks.load(fis, pwchars);
|
||||
}
|
||||
if (ksFile != null && !exists)
|
||||
ks.store(new SecureFileOutputStream(ksFile), pwchars);
|
||||
return ks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads certs from location of javax.net.ssl.keyStore property,
|
||||
* else from $JAVA_HOME/lib/security/jssacacerts,
|
||||
* else from $JAVA_HOME/lib/security/cacerts.
|
||||
*
|
||||
* @return null on catastrophic failure, returns empty KeyStore if can't load system file
|
||||
* @since 0.8.2, moved from SSLEepGet.initSSLContext() in 0.9.9
|
||||
*/
|
||||
public static KeyStore loadSystemKeyStore() {
|
||||
KeyStore ks;
|
||||
try {
|
||||
ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
error("Key Store init error", gse);
|
||||
return null;
|
||||
}
|
||||
boolean success = false;
|
||||
String override = System.getProperty("javax.net.ssl.keyStore");
|
||||
if (override != null)
|
||||
success = loadCerts(new File(override), ks);
|
||||
if (!success) {
|
||||
if (SystemVersion.isAndroid()) {
|
||||
// thru API 13. As of API 14 (ICS), the file is gone, but
|
||||
// ks.load(null, pw) will bring in the default certs?
|
||||
success = loadCerts(new File(System.getProperty("java.home"), "etc/security/cacerts.bks"), ks);
|
||||
} else {
|
||||
success = loadCerts(new File(System.getProperty("java.home"), "lib/security/jssecacerts"), ks);
|
||||
if (!success)
|
||||
success = loadCerts(new File(System.getProperty("java.home"), "lib/security/cacerts"), ks);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
try {
|
||||
// must be initted
|
||||
ks.load(null, DEFAULT_KEYSTORE_PASSWORD.toCharArray());
|
||||
} catch (Exception e) {}
|
||||
error("All key store loads failed, will only load local certificates", null);
|
||||
}
|
||||
return ks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all X509 Certs from a key store File into a KeyStore
|
||||
* Note that each call reinitializes the KeyStore
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.2, moved from SSLEepGet in 0.9.9
|
||||
*/
|
||||
private static boolean loadCerts(File file, KeyStore ks) {
|
||||
if (!file.exists())
|
||||
return false;
|
||||
InputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
// "changeit" is the default password
|
||||
ks.load(fis, DEFAULT_KEYSTORE_PASSWORD.toCharArray());
|
||||
info("Certs loaded from " + file);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
error("KeyStore load error, no default keys: " + file.getAbsolutePath(), gse);
|
||||
try {
|
||||
// not clear if null is allowed for password
|
||||
ks.load(null, DEFAULT_KEYSTORE_PASSWORD.toCharArray());
|
||||
} catch (Exception foo) {}
|
||||
return false;
|
||||
} catch (IOException ioe) {
|
||||
error("KeyStore load error, no default keys: " + file.getAbsolutePath(), ioe);
|
||||
try {
|
||||
ks.load(null, DEFAULT_KEYSTORE_PASSWORD.toCharArray());
|
||||
} catch (Exception foo) {}
|
||||
return false;
|
||||
} finally {
|
||||
try { if (fis != null) fis.close(); } catch (IOException foo) {}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Count all X509 Certs in a key store
|
||||
*
|
||||
* @return number successfully added
|
||||
* @since 0.8.2, moved from SSLEepGet in 0.9.9
|
||||
*/
|
||||
public static int countCerts(KeyStore ks) {
|
||||
int count = 0;
|
||||
try {
|
||||
for(Enumeration<String> e = ks.aliases(); e.hasMoreElements();) {
|
||||
String alias = e.nextElement();
|
||||
if (ks.isCertificateEntry(alias)) {
|
||||
info("Found cert " + alias);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
} catch (Exception foo) {}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all X509 Certs from a directory and add them to the
|
||||
* trusted set of certificates in the key store
|
||||
*
|
||||
* @return number successfully added
|
||||
* @since 0.8.2, moved from SSLEepGet in 0.9.9
|
||||
*/
|
||||
public static int addCerts(File dir, KeyStore ks) {
|
||||
info("Looking for X509 Certificates in " + dir.getAbsolutePath());
|
||||
int added = 0;
|
||||
if (dir.exists() && dir.isDirectory()) {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File f = files[i];
|
||||
if (!f.isFile())
|
||||
continue;
|
||||
// use file name as alias
|
||||
// https://www.sslshopper.com/ssl-converter.html
|
||||
// No idea if all these formats can actually be read by CertificateFactory
|
||||
String alias = f.getName().toLowerCase(Locale.US);
|
||||
if (alias.endsWith(".crt") || alias.endsWith(".pem") || alias.endsWith(".key") ||
|
||||
alias.endsWith(".der") || alias.endsWith(".key") || alias.endsWith(".p7b") ||
|
||||
alias.endsWith(".p7c") || alias.endsWith(".pfx") || alias.endsWith(".p12"))
|
||||
alias = alias.substring(0, alias.length() - 4);
|
||||
boolean success = addCert(f, alias, ks);
|
||||
if (success)
|
||||
added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an X509 Cert from a file and add it to the
|
||||
* trusted set of certificates in the key store
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.2, moved from SSLEepGet in 0.9.9
|
||||
*/
|
||||
public static boolean addCert(File file, String alias, KeyStore ks) {
|
||||
InputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
X509Certificate cert = (X509Certificate)cf.generateCertificate(fis);
|
||||
info("Read X509 Certificate from " + file.getAbsolutePath() +
|
||||
" Issuer: " + cert.getIssuerX500Principal() +
|
||||
"; Valid From: " + cert.getNotBefore() +
|
||||
" To: " + cert.getNotAfter());
|
||||
try {
|
||||
cert.checkValidity();
|
||||
} catch (CertificateExpiredException cee) {
|
||||
error("Rejecting expired X509 Certificate: " + file.getAbsolutePath(), cee);
|
||||
return false;
|
||||
} catch (CertificateNotYetValidException cnyve) {
|
||||
error("Rejecting X509 Certificate not yet valid: " + file.getAbsolutePath(), cnyve);
|
||||
return false;
|
||||
}
|
||||
ks.setCertificateEntry(alias, cert);
|
||||
info("Now trusting X509 Certificate, Issuer: " + cert.getIssuerX500Principal());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
error("Error reading X509 Certificate: " + file.getAbsolutePath(), gse);
|
||||
return false;
|
||||
} catch (IOException ioe) {
|
||||
error("Error reading X509 Certificate: " + file.getAbsolutePath(), ioe);
|
||||
return false;
|
||||
} finally {
|
||||
try { if (fis != null) fis.close(); } catch (IOException foo) {}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** 48 char b32 string (30 bytes of entropy) */
|
||||
public static String randomString() {
|
||||
I2PAppContext ctx = I2PAppContext.getGlobalContext();
|
||||
// make a random 48 character password (30 * 8 / 5)
|
||||
byte[] rand = new byte[30];
|
||||
ctx.random().nextBytes(rand);
|
||||
return Base32.encode(rand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a keypair and store it in the keystore at ks, creating it if necessary.
|
||||
* Use default keystore password, valid days, algorithm, and key size.
|
||||
*
|
||||
* Warning, may take a long time.
|
||||
*
|
||||
* @param ks path to the keystore
|
||||
* @param alias the name of the key
|
||||
* @param cname e.g. randomstuff.console.i2p.net
|
||||
* @param ou e.g. console
|
||||
* @param keyPW the key password, must be at least 6 characters
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.3, consolidated from RouterConsoleRUnner and SSLClientListenerRunner in 0.9.9
|
||||
*/
|
||||
public static boolean createKeys(File ks, String alias, String cname, String ou,
|
||||
String keyPW) {
|
||||
return createKeys(ks, DEFAULT_KEYSTORE_PASSWORD, alias, cname, ou,
|
||||
DEFAULT_KEY_VALID_DAYS, DEFAULT_KEY_ALGORITHM, DEFAULT_KEY_SIZE, keyPW);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a keypair and store it in the keystore at ks, creating it if necessary.
|
||||
*
|
||||
* Warning, may take a long time.
|
||||
*
|
||||
* @param ks path to the keystore
|
||||
* @param ksPW the keystore password
|
||||
* @param alias the name of the key
|
||||
* @param cname e.g. randomstuff.console.i2p.net
|
||||
* @param ou e.g. console
|
||||
* @param validDays e.g. 3652 (10 years)
|
||||
* @param keyAlg e.g. DSA , RSA, EC
|
||||
* @param keySize e.g. 1024
|
||||
* @param keyPW the key password, must be at least 6 characters
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.3, consolidated from RouterConsoleRUnner and SSLClientListenerRunner in 0.9.9
|
||||
*/
|
||||
public static boolean createKeys(File ks, String ksPW, String alias, String cname, String ou,
|
||||
int validDays, String keyAlg, int keySize, String keyPW) {
|
||||
if (ks.exists()) {
|
||||
try {
|
||||
if (getCert(ks, ksPW, alias) != null) {
|
||||
error("Not overwriting key " + alias + ", already exists in " + ks, null);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
error("Not overwriting key \"" + alias + "\", already exists in " + ks, e);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
File dir = ks.getParentFile();
|
||||
if (dir != null && !dir.exists()) {
|
||||
File sdir = new SecureDirectory(dir.getAbsolutePath());
|
||||
if (!sdir.mkdir()) {
|
||||
error("Can't create directory " + dir, null);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
String keytool = (new File(System.getProperty("java.home"), "bin/keytool")).getAbsolutePath();
|
||||
String[] args = new String[] {
|
||||
keytool,
|
||||
"-genkey", // -genkeypair preferred in newer keytools, but this works with more
|
||||
"-storetype", KeyStore.getDefaultType(),
|
||||
"-keystore", ks.getAbsolutePath(),
|
||||
"-storepass", ksPW,
|
||||
"-alias", alias,
|
||||
"-dname", "CN=" + cname + ",OU=" + ou + ",O=I2P Anonymous Network,L=XX,ST=XX,C=XX",
|
||||
"-validity", Integer.toString(validDays), // 10 years
|
||||
"-keyalg", keyAlg,
|
||||
"-sigalg", getSigAlg(keySize, keyAlg),
|
||||
"-keysize", Integer.toString(keySize),
|
||||
"-keypass", keyPW
|
||||
};
|
||||
// TODO pipe key password to process; requires ShellCommand enhancements
|
||||
boolean success = (new ShellCommand()).executeSilentAndWaitTimed(args, 240);
|
||||
if (success) {
|
||||
success = ks.exists();
|
||||
if (success) {
|
||||
try {
|
||||
success = getPrivateKey(ks, ksPW, alias, keyPW) != null;
|
||||
if (!success)
|
||||
error("Key gen failed to get private key", null);
|
||||
} catch (Exception e) {
|
||||
error("Key gen failed to get private key", e);
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
if (!success)
|
||||
error("Key gen failed for unknown reasons", null);
|
||||
}
|
||||
if (success) {
|
||||
SecureFileOutputStream.setPerms(ks);
|
||||
info("Created self-signed certificate for " + cname + " in keystore: " + ks.getAbsolutePath());
|
||||
} else {
|
||||
StringBuilder buf = new StringBuilder(256);
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
buf.append('"').append(args[i]).append("\" ");
|
||||
}
|
||||
error("Failed to generate keys using command line: " + buf, null);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
private static String getSigAlg(int size, String keyalg) {
|
||||
if (keyalg.equals("EC"))
|
||||
keyalg = "ECDSA";
|
||||
String hash;
|
||||
if (keyalg.equals("ECDSA")) {
|
||||
if (size <= 256)
|
||||
hash = "SHA256";
|
||||
else if (size <= 384)
|
||||
hash = "SHA384";
|
||||
else
|
||||
hash = "SHA512";
|
||||
} else {
|
||||
if (size <= 1024)
|
||||
hash = "SHA1";
|
||||
else if (size <= 2048)
|
||||
hash = "SHA256";
|
||||
else if (size <= 3072)
|
||||
hash = "SHA384";
|
||||
else
|
||||
hash = "SHA512";
|
||||
}
|
||||
return hash + "with" + keyalg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a private key out of a keystore
|
||||
*
|
||||
* @param ks path to the keystore
|
||||
* @param ksPW the keystore password, may be null
|
||||
* @param alias the name of the key
|
||||
* @param keyPW the key password, must be at least 6 characters
|
||||
* @return the key or null if not found
|
||||
*/
|
||||
public static PrivateKey getPrivateKey(File ks, String ksPW, String alias, String keyPW)
|
||||
throws GeneralSecurityException, IOException {
|
||||
InputStream fis = null;
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
fis = new FileInputStream(ks);
|
||||
char[] pwchars = ksPW != null ? ksPW.toCharArray() : null;
|
||||
keyStore.load(fis, pwchars);
|
||||
char[] keypwchars = keyPW.toCharArray();
|
||||
return (PrivateKey) keyStore.getKey(alias, keypwchars);
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a cert out of a keystore
|
||||
*
|
||||
* @param ks path to the keystore
|
||||
* @param ksPW the keystore password, may be null
|
||||
* @param alias the name of the key
|
||||
* @return the certificate or null if not found
|
||||
*/
|
||||
public static Certificate getCert(File ks, String ksPW, String alias)
|
||||
throws GeneralSecurityException, IOException {
|
||||
InputStream fis = null;
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
fis = new FileInputStream(ks);
|
||||
char[] pwchars = ksPW != null ? ksPW.toCharArray() : null;
|
||||
keyStore.load(fis, pwchars);
|
||||
return keyStore.getCertificate(alias);
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the cert back OUT of the keystore and save it in Base64-encoded X.509 format
|
||||
* so the clients can get to it.
|
||||
*
|
||||
* @param ks path to the keystore
|
||||
* @param ksPW the keystore password, may be null
|
||||
* @param alias the name of the key
|
||||
* @param certFile output
|
||||
* @return success
|
||||
* @since 0.8.3 moved from SSLClientListenerRunner in 0.9.9
|
||||
*/
|
||||
public static boolean exportCert(File ks, String ksPW, String alias, File certFile) {
|
||||
InputStream fis = null;
|
||||
try {
|
||||
Certificate cert = getCert(ks, ksPW, alias);
|
||||
if (cert != null)
|
||||
return CertUtil.saveCert(cert, certFile);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
error("Error saving ASCII SSL keys", gse);
|
||||
} catch (IOException ioe) {
|
||||
error("Error saving ASCII SSL keys", ioe);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void info(String msg) {
|
||||
log(I2PAppContext.getGlobalContext(), Log.INFO, msg, null);
|
||||
}
|
||||
|
||||
private static void error(String msg, Throwable t) {
|
||||
log(I2PAppContext.getGlobalContext(), Log.ERROR, msg, t);
|
||||
}
|
||||
|
||||
private static void info(I2PAppContext ctx, String msg) {
|
||||
log(ctx, Log.INFO, msg, null);
|
||||
}
|
||||
|
||||
private static void error(I2PAppContext ctx, String msg, Throwable t) {
|
||||
log(ctx, Log.ERROR, msg, t);
|
||||
}
|
||||
|
||||
private static void log(I2PAppContext ctx, int level, String msg, Throwable t) {
|
||||
if (level >= Log.WARN && !ctx.isRouterContext()) {
|
||||
System.out.println(msg);
|
||||
if (t != null)
|
||||
t.printStackTrace();
|
||||
}
|
||||
Log l = ctx.logManager().getLog(KeyStoreUtil.class);
|
||||
l.log(level, msg, t);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
if (args.length > 0) {
|
||||
File ksf = new File(args[0]);
|
||||
createKeyStore(ksf, DEFAULT_KEYSTORE_PASSWORD);
|
||||
System.out.println("Created empty keystore " + ksf);
|
||||
} else {
|
||||
KeyStore ks = loadSystemKeyStore();
|
||||
if (ks != null) {
|
||||
System.out.println("Loaded system keystore");
|
||||
int count = countCerts(ks);
|
||||
System.out.println("Found " + count + " certs");
|
||||
} else {
|
||||
System.out.println("FAIL");
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
29
core/java/src/net/i2p/crypto/RSAConstants.java
Normal file
29
core/java/src/net/i2p/crypto/RSAConstants.java
Normal file
@ -0,0 +1,29 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.spec.RSAKeyGenParameterSpec;
|
||||
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
|
||||
/**
|
||||
* Constants for RSA
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
class RSAConstants {
|
||||
|
||||
/**
|
||||
* Generate a spec
|
||||
*/
|
||||
private static RSAKeyGenParameterSpec genSpec(int size, BigInteger exp) {
|
||||
return new RSAKeyGenParameterSpec(size, exp);
|
||||
}
|
||||
|
||||
private static final BigInteger F4 = new NativeBigInteger(RSAKeyGenParameterSpec.F4);
|
||||
|
||||
// standard specs
|
||||
public static final RSAKeyGenParameterSpec F4_1024_SPEC = genSpec(1024, F4);
|
||||
public static final RSAKeyGenParameterSpec F4_2048_SPEC = genSpec(2048, F4);
|
||||
public static final RSAKeyGenParameterSpec F4_3072_SPEC = genSpec(3072, F4);
|
||||
public static final RSAKeyGenParameterSpec F4_4096_SPEC = genSpec(4096, F4);
|
||||
}
|
@ -26,6 +26,11 @@ public class SHA1Hash extends SimpleDataStructure {
|
||||
|
||||
public final static int HASH_LENGTH = SHA1.HASH_LENGTH;
|
||||
|
||||
/** @since 0.9.9 */
|
||||
public SHA1Hash() {
|
||||
super();
|
||||
}
|
||||
|
||||
/** @throws IllegalArgumentException if data is not 20 bytes (null is ok) */
|
||||
public SHA1Hash(byte data[]) {
|
||||
super(data);
|
||||
|
@ -11,9 +11,20 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.DigestInputStream;
|
||||
import java.security.DigestOutputStream;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Properties;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataFormatException;
|
||||
@ -21,6 +32,9 @@ import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Signature;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.data.SigningPublicKey;
|
||||
import net.i2p.data.SimpleDataStructure;
|
||||
import net.i2p.util.HexDump;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
|
||||
/**
|
||||
* Succesor to the ".sud" format used in TrustedUpdate.
|
||||
@ -31,60 +45,86 @@ import net.i2p.data.SigningPublicKey;
|
||||
public class SU3File {
|
||||
|
||||
private final I2PAppContext _context;
|
||||
private final Map<SigningPublicKey, String> _trustedKeys;
|
||||
|
||||
private final File _file;
|
||||
private String _version;
|
||||
private int _versionLength;
|
||||
private String _signer;
|
||||
private int _signerLength;
|
||||
private int _contentType;
|
||||
private ContentType _contentType;
|
||||
private long _contentLength;
|
||||
private SigningPublicKey _signerPubkey;
|
||||
private PublicKey _signerPubkey;
|
||||
private boolean _headerVerified;
|
||||
private SigType _sigType;
|
||||
|
||||
private static final byte[] MAGIC = DataHelper.getUTF8("I2Psu3");
|
||||
private static final int FILE_VERSION = 0;
|
||||
private static final int MIN_VERSION_BYTES = 16;
|
||||
private static final int VERSION_OFFSET = Signature.SIGNATURE_BYTES;
|
||||
private static final int VERSION_OFFSET = 40; // Signature.SIGNATURE_BYTES; avoid early ctx init
|
||||
|
||||
private static final int TYPE_ZIP = 0;
|
||||
|
||||
private static final int CONTENT_ROUTER = 0;
|
||||
private static final int CONTENT_ROUTER_P200 = 1;
|
||||
private static final int CONTENT_PLUGIN = 2;
|
||||
private static final int CONTENT_RESEED = 3;
|
||||
public static final int CONTENT_UNKNOWN = 0;
|
||||
public static final int CONTENT_ROUTER = 1;
|
||||
public static final int CONTENT_PLUGIN = 2;
|
||||
public static final int CONTENT_RESEED = 3;
|
||||
|
||||
private static final int SIG_DSA_160 = SigType.DSA_SHA1.getCode();
|
||||
private enum ContentType {
|
||||
UNKNOWN(CONTENT_UNKNOWN, "unknown"),
|
||||
ROUTER(CONTENT_ROUTER, "router"),
|
||||
PLUGIN(CONTENT_PLUGIN, "plugin"),
|
||||
RESEED(CONTENT_RESEED, "reseed")
|
||||
;
|
||||
|
||||
private final int code;
|
||||
private final String name;
|
||||
|
||||
ContentType(int code, String name) {
|
||||
this.code = code;
|
||||
this.name = name;
|
||||
}
|
||||
public int getCode() { return code; }
|
||||
public String getName() { return name; }
|
||||
|
||||
/** @return null if not supported */
|
||||
public static ContentType getByCode(int code) {
|
||||
return BY_CODE.get(Integer.valueOf(code));
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<Integer, ContentType> BY_CODE = new HashMap<Integer, ContentType>();
|
||||
|
||||
static {
|
||||
for (ContentType type : ContentType.values()) {
|
||||
BY_CODE.put(Integer.valueOf(type.getCode()), type);
|
||||
}
|
||||
}
|
||||
|
||||
private static final ContentType DEFAULT_CONTENT_TYPE = ContentType.UNKNOWN;
|
||||
// avoid early ctx init
|
||||
//private static final SigType DEFAULT_SIG_TYPE = SigType.DSA_SHA1;
|
||||
private static final int DEFAULT_SIG_CODE = 0;
|
||||
|
||||
/**
|
||||
* Uses TrustedUpdate's default keys for verification.
|
||||
*
|
||||
*/
|
||||
public SU3File(String file) {
|
||||
this(new File(file));
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses TrustedUpdate's default keys for verification.
|
||||
*
|
||||
*/
|
||||
public SU3File(File file) {
|
||||
this(file, (new TrustedUpdate()).getKeys());
|
||||
this(I2PAppContext.getGlobalContext(), file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param trustedKeys map of pubkey to signer name, null ok if not verifying
|
||||
*
|
||||
*/
|
||||
public SU3File(File file, Map<SigningPublicKey, String> trustedKeys) {
|
||||
this(I2PAppContext.getGlobalContext(), file, trustedKeys);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param trustedKeys map of pubkey to signer name, null ok if not verifying
|
||||
*/
|
||||
public SU3File(I2PAppContext context, File file, Map<SigningPublicKey, String> trustedKeys) {
|
||||
public SU3File(I2PAppContext context, File file) {
|
||||
_context = context;
|
||||
_file = file;
|
||||
_trustedKeys = trustedKeys;
|
||||
}
|
||||
|
||||
public String getVersionString() throws IOException {
|
||||
@ -97,6 +137,24 @@ public class SU3File {
|
||||
return _signer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null if unknown
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public SigType getSigType() throws IOException {
|
||||
verifyHeader();
|
||||
return _sigType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return -1 if unknown
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public int getContentType() throws IOException {
|
||||
verifyHeader();
|
||||
return _contentType != null ? _contentType.getCode() : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws IOE if verify vails.
|
||||
*/
|
||||
@ -128,14 +186,13 @@ public class SU3File {
|
||||
int foo = in.read();
|
||||
if (foo != FILE_VERSION)
|
||||
throw new IOException("bad file version");
|
||||
skip(in, 1);
|
||||
int sigType = in.read();
|
||||
// TODO, for other known algos we must start over with a new MessageDigest
|
||||
// (rewind 10 bytes)
|
||||
if (sigType != SIG_DSA_160)
|
||||
throw new IOException("bad sig type");
|
||||
int sigTypeCode = (int) DataHelper.readLong(in, 2);
|
||||
_sigType = SigType.getByCode(sigTypeCode);
|
||||
// In verifyAndMigrate it reads this far then rewinds, but we don't need to here
|
||||
if (_sigType == null)
|
||||
throw new IOException("unknown sig type: " + sigTypeCode);
|
||||
_signerLength = (int) DataHelper.readLong(in, 2);
|
||||
if (_signerLength != Signature.SIGNATURE_BYTES)
|
||||
if (_signerLength != _sigType.getSigLen())
|
||||
throw new IOException("bad sig length");
|
||||
skip(in, 1);
|
||||
int _versionLength = in.read();
|
||||
@ -153,9 +210,10 @@ public class SU3File {
|
||||
if (foo != TYPE_ZIP)
|
||||
throw new IOException("bad type");
|
||||
skip(in, 1);
|
||||
_contentType = in.read();
|
||||
if (_contentType < CONTENT_ROUTER || _contentType > CONTENT_RESEED)
|
||||
throw new IOException("bad content type");
|
||||
int cType = in.read();
|
||||
_contentType = BY_CODE.get(Integer.valueOf(cType));
|
||||
if (_contentType == null)
|
||||
throw new IOException("unknown content type " + cType);
|
||||
skip(in, 12);
|
||||
|
||||
byte[] data = new byte[_versionLength];
|
||||
@ -174,16 +232,18 @@ public class SU3File {
|
||||
if (bytesRead != signerLen)
|
||||
throw new EOFException();
|
||||
_signer = DataHelper.getUTF8(data);
|
||||
if (_trustedKeys != null) {
|
||||
for (Map.Entry<SigningPublicKey, String> e : _trustedKeys.entrySet()) {
|
||||
if (e.getValue().equals(_signer)) {
|
||||
_signerPubkey = e.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_signerPubkey == null)
|
||||
throw new IOException("unknown signer: " + _signer);
|
||||
|
||||
KeyRing ring = new DirKeyRing(new File(_context.getBaseDir(), "certificates"));
|
||||
try {
|
||||
_signerPubkey = ring.getKey(_signer, _contentType.getName(), _sigType);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
IOException ioe = new IOException("keystore error");
|
||||
ioe.initCause(gse);
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
if (_signerPubkey == null)
|
||||
throw new IOException("unknown signer: " + _signer);
|
||||
_headerVerified = true;
|
||||
}
|
||||
|
||||
@ -200,43 +260,80 @@ public class SU3File {
|
||||
return VERSION_OFFSET + _versionLength + _signerLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* One-pass verify.
|
||||
* Throws IOE on all format errors.
|
||||
*
|
||||
* @return true if signature is good
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public boolean verify() throws IOException {
|
||||
return verifyAndMigrate(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* One-pass verify and extract the content.
|
||||
* Recommend extracting to a temp location as the sig is not checked until
|
||||
* after extraction. This will delete the file if the sig does not verify.
|
||||
* Throws IOE on all format errors.
|
||||
*
|
||||
* @param migrateTo the output file, probably in zip format
|
||||
* @param migrateTo the output file, probably in zip format. Null for verify only.
|
||||
* @return true if signature is good
|
||||
*/
|
||||
public boolean verifyAndMigrate(File migrateTo) throws IOException {
|
||||
DigestInputStream in = null;
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
boolean rv = false;
|
||||
try {
|
||||
MessageDigest md = SHA1.getInstance();
|
||||
in = new DigestInputStream(new BufferedInputStream(new FileInputStream(_file)), md);
|
||||
in = new BufferedInputStream(new FileInputStream(_file));
|
||||
// read 10 bytes to get the sig type
|
||||
in.mark(10);
|
||||
// following is a dup of that in verifyHeader()
|
||||
byte[] magic = new byte[MAGIC.length];
|
||||
DataHelper.read(in, magic);
|
||||
if (!DataHelper.eq(magic, MAGIC))
|
||||
throw new IOException("Not an su3 file");
|
||||
skip(in, 1);
|
||||
int foo = in.read();
|
||||
if (foo != FILE_VERSION)
|
||||
throw new IOException("bad file version");
|
||||
skip(in, 1);
|
||||
int sigTypeCode = in.read();
|
||||
_sigType = SigType.getByCode(sigTypeCode);
|
||||
if (_sigType == null)
|
||||
throw new IOException("unknown sig type: " + sigTypeCode);
|
||||
// end duplicate code
|
||||
// rewind
|
||||
in.reset();
|
||||
MessageDigest md = _sigType.getDigestInstance();
|
||||
DigestInputStream din = new DigestInputStream(in, md);
|
||||
in = din;
|
||||
if (!_headerVerified)
|
||||
verifyHeader(in);
|
||||
else
|
||||
skip(in, getContentOffset());
|
||||
if (_signerPubkey == null)
|
||||
throw new IOException("unknown signer: " + _signer);
|
||||
out = new FileOutputStream(migrateTo);
|
||||
if (migrateTo != null) // else verify only
|
||||
out = new FileOutputStream(migrateTo);
|
||||
byte[] buf = new byte[16*1024];
|
||||
long tot = 0;
|
||||
while (tot < _contentLength) {
|
||||
int read = in.read(buf, 0, (int) Math.min(buf.length, _contentLength - tot));
|
||||
if (read < 0)
|
||||
throw new EOFException();
|
||||
out.write(buf, 0, read);
|
||||
if (migrateTo != null) // else verify only
|
||||
out.write(buf, 0, read);
|
||||
tot += read;
|
||||
}
|
||||
byte[] sha = md.digest();
|
||||
in.on(false);
|
||||
Signature signature = new Signature();
|
||||
din.on(false);
|
||||
Signature signature = new Signature(_sigType);
|
||||
signature.readBytes(in);
|
||||
SHA1Hash hash = new SHA1Hash(sha);
|
||||
SimpleDataStructure hash = _sigType.getHashInstance();
|
||||
hash.setData(sha);
|
||||
//System.out.println("hash\n" + HexDump.dump(sha));
|
||||
//System.out.println("sig\n" + HexDump.dump(signature.getData()));
|
||||
rv = _context.dsa().verifySignature(signature, hash, _signerPubkey);
|
||||
} catch (DataFormatException dfe) {
|
||||
IOException ioe = new IOException("foo");
|
||||
@ -245,7 +342,7 @@ public class SU3File {
|
||||
} finally {
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {}
|
||||
if (out != null) try { out.close(); } catch (IOException ioe) {}
|
||||
if (!rv)
|
||||
if (migrateTo != null && !rv)
|
||||
migrateTo.delete();
|
||||
}
|
||||
return rv;
|
||||
@ -262,20 +359,19 @@ public class SU3File {
|
||||
* @param signer ID of the public key, 1-255 bytes when converted to UTF-8
|
||||
*/
|
||||
public void write(File content, int contentType, String version,
|
||||
String signer, SigningPrivateKey privkey) throws IOException {
|
||||
String signer, PrivateKey privkey, SigType sigType) throws IOException {
|
||||
InputStream in = null;
|
||||
DigestOutputStream out = null;
|
||||
boolean ok = false;
|
||||
try {
|
||||
in = new BufferedInputStream(new FileInputStream(content));
|
||||
MessageDigest md = SHA1.getInstance();
|
||||
MessageDigest md = sigType.getDigestInstance();
|
||||
out = new DigestOutputStream(new BufferedOutputStream(new FileOutputStream(_file)), md);
|
||||
out.write(MAGIC);
|
||||
out.write((byte) 0);
|
||||
out.write((byte) FILE_VERSION);
|
||||
out.write((byte) 0);
|
||||
out.write((byte) SIG_DSA_160);
|
||||
DataHelper.writeLong(out, 2, Signature.SIGNATURE_BYTES);
|
||||
DataHelper.writeLong(out, 2, sigType.getCode());
|
||||
DataHelper.writeLong(out, 2, sigType.getSigLen());
|
||||
out.write((byte) 0);
|
||||
byte[] verBytes = DataHelper.getUTF8(version);
|
||||
if (verBytes.length == 0 || verBytes.length > 255)
|
||||
@ -315,8 +411,13 @@ public class SU3File {
|
||||
|
||||
byte[] sha = md.digest();
|
||||
out.on(false);
|
||||
SHA1Hash hash = new SHA1Hash(sha);
|
||||
Signature signature = _context.dsa().sign(hash, privkey);
|
||||
SimpleDataStructure hash = sigType.getHashInstance();
|
||||
hash.setData(sha);
|
||||
Signature signature = _context.dsa().sign(hash, privkey, sigType);
|
||||
if (signature == null)
|
||||
throw new IOException("sig fail");
|
||||
//System.out.println("hash\n" + HexDump.dump(sha));
|
||||
//System.out.println("sig\n" + HexDump.dump(signature.getData()));
|
||||
signature.writeBytes(out);
|
||||
ok = true;
|
||||
} catch (DataFormatException dfe) {
|
||||
@ -340,17 +441,46 @@ public class SU3File {
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
boolean ok = false;
|
||||
List<String> a = new ArrayList(Arrays.asList(args));
|
||||
try {
|
||||
if ("showversion".equals(args[0])) {
|
||||
ok = showVersionCLI(args[1]);
|
||||
} else if ("sign".equals(args[0])) {
|
||||
ok = signCLI(args[1], args[2], args[3], args[4], args[5]);
|
||||
} else if ("verifysig".equals(args[0])) {
|
||||
ok = verifySigCLI(args[1]);
|
||||
// defaults
|
||||
String stype = null;
|
||||
String ctype = null;
|
||||
Iterator<String> iter = a.iterator();
|
||||
String cmd = iter.next();
|
||||
iter.remove();
|
||||
for ( ; iter.hasNext(); ) {
|
||||
String arg = iter.next();
|
||||
if (arg.equals("-t")) {
|
||||
iter.remove();
|
||||
stype = iter.next();
|
||||
iter.remove();
|
||||
} else if (arg.equals("-c")) {
|
||||
iter.remove();
|
||||
ctype = iter.next();
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
if ("showversion".equals(cmd)) {
|
||||
ok = showVersionCLI(a.get(0));
|
||||
} else if ("sign".equals(cmd)) {
|
||||
// speed things up by specifying a small PRNG buffer size
|
||||
Properties props = new Properties();
|
||||
props.setProperty("prng.bufferSize", "16384");
|
||||
new I2PAppContext(props);
|
||||
ok = signCLI(stype, ctype, a.get(0), a.get(1), a.get(2), a.get(3), a.get(4));
|
||||
} else if ("verifysig".equals(cmd)) {
|
||||
ok = verifySigCLI(a.get(0));
|
||||
} else if ("keygen".equals(cmd)) {
|
||||
ok = genKeysCLI(stype, a.get(0), a.get(1), a.get(2));
|
||||
} else if ("extract".equals(cmd)) {
|
||||
ok = extractCLI(a.get(0), a.get(1));
|
||||
} else {
|
||||
showUsageCLI();
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException aioobe) {
|
||||
} catch (NoSuchElementException nsee) {
|
||||
showUsageCLI();
|
||||
} catch (IndexOutOfBoundsException ioobe) {
|
||||
showUsageCLI();
|
||||
}
|
||||
if (!ok)
|
||||
@ -358,20 +488,85 @@ public class SU3File {
|
||||
}
|
||||
|
||||
private static final void showUsageCLI() {
|
||||
System.err.println("Usage: SU3File showversion signedFile.su3");
|
||||
System.err.println(" SU3File sign inputFile.zip signedFile.su3 privateKeyFile version signerName@mail.i2p");
|
||||
System.err.println(" SU3File verifysig signedFile.su3");
|
||||
System.err.println("Usage: SU3File keygen [-t type|code] publicKeyFile keystore.ks you@mail.i2p");
|
||||
System.err.println(" SU3File sign [-c type|code] [-t type|code] inputFile.zip signedFile.su3 keystore.ks version you@mail.i2p");
|
||||
System.err.println(" SU3File showversion signedFile.su3");
|
||||
System.err.println(" SU3File verifysig signedFile.su3");
|
||||
System.err.println(" SU3File extract signedFile.su3 outFile.zip");
|
||||
System.err.println(dumpTypes());
|
||||
}
|
||||
|
||||
/** @since 0.9.9 */
|
||||
private static String dumpTypes() {
|
||||
StringBuilder buf = new StringBuilder(256);
|
||||
buf.append("Available signature types:\n");
|
||||
for (SigType t : EnumSet.allOf(SigType.class)) {
|
||||
buf.append(" ").append(t).append("\t(code: ").append(t.getCode()).append(')');
|
||||
if (t.getCode() == DEFAULT_SIG_CODE)
|
||||
buf.append(" DEFAULT");
|
||||
buf.append('\n');
|
||||
}
|
||||
buf.append("Available content types:\n");
|
||||
for (ContentType t : EnumSet.allOf(ContentType.class)) {
|
||||
buf.append(" ").append(t).append("\t(code: ").append(t.getCode()).append(')');
|
||||
if (t == DEFAULT_CONTENT_TYPE)
|
||||
buf.append(" DEFAULT");
|
||||
buf.append('\n');
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param stype number or name
|
||||
* @return null if not found
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static SigType parseSigType(String stype) {
|
||||
try {
|
||||
return SigType.valueOf(stype.toUpperCase(Locale.US));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
try {
|
||||
int code = Integer.parseInt(stype);
|
||||
return SigType.getByCode(code);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param stype number or name
|
||||
* @return null if not found
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static ContentType parseContentType(String ctype) {
|
||||
try {
|
||||
return ContentType.valueOf(ctype.toUpperCase(Locale.US));
|
||||
} catch (IllegalArgumentException iae) {
|
||||
try {
|
||||
int code = Integer.parseInt(ctype);
|
||||
return ContentType.getByCode(code);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @return success */
|
||||
private static final boolean showVersionCLI(String signedFile) {
|
||||
try {
|
||||
SU3File file = new SU3File(new File(signedFile), null);
|
||||
SU3File file = new SU3File(signedFile);
|
||||
String versionString = file.getVersionString();
|
||||
if (versionString.equals(""))
|
||||
System.out.println("No version string found in file '" + signedFile + "'");
|
||||
else
|
||||
System.out.println("Version: " + versionString);
|
||||
System.out.println("Version: " + versionString);
|
||||
String signerString = file.getSignerString();
|
||||
if (signerString.equals(""))
|
||||
System.out.println("No signer string found in file '" + signedFile + "'");
|
||||
else
|
||||
System.out.println("Signer: " + signerString);
|
||||
if (file._sigType != null)
|
||||
System.out.println("SigType: " + file._sigType);
|
||||
return !versionString.equals("");
|
||||
} catch (IOException ioe) {
|
||||
ioe.printStackTrace();
|
||||
@ -379,29 +574,57 @@ public class SU3File {
|
||||
}
|
||||
}
|
||||
|
||||
/** @return success */
|
||||
private static final boolean signCLI(String inputFile, String signedFile, String privateKeyFile,
|
||||
String version, String signerName) {
|
||||
InputStream in = null;
|
||||
/**
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean signCLI(String stype, String ctype, String inputFile, String signedFile,
|
||||
String privateKeyFile, String version, String signerName) {
|
||||
SigType type = stype == null ? SigType.getByCode(Integer.valueOf(DEFAULT_SIG_CODE)) : parseSigType(stype);
|
||||
if (type == null) {
|
||||
System.out.println("Signature type " + stype + " is not supported");
|
||||
return false;
|
||||
}
|
||||
ContentType ct = ctype == null ? DEFAULT_CONTENT_TYPE : parseContentType(ctype);
|
||||
if (ct == null) {
|
||||
System.out.println("Content type " + ctype + " is not supported");
|
||||
return false;
|
||||
}
|
||||
return signCLI(type, ct, inputFile, signedFile, privateKeyFile, version, signerName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean signCLI(SigType type, ContentType ctype, String inputFile, String signedFile,
|
||||
String privateKeyFile, String version, String signerName) {
|
||||
try {
|
||||
in = new FileInputStream(privateKeyFile);
|
||||
SigningPrivateKey spk = new SigningPrivateKey();
|
||||
spk.readBytes(in);
|
||||
in.close();
|
||||
String keypw = "";
|
||||
while (keypw.length() < 6) {
|
||||
System.out.print("Enter password for key \"" + signerName + "\": ");
|
||||
keypw = DataHelper.readLine(System.in).trim();
|
||||
if (keypw.length() > 0 && keypw.length() < 6)
|
||||
System.out.println("Key password must be at least 6 characters");
|
||||
}
|
||||
File pkfile = new File(privateKeyFile);
|
||||
PrivateKey pk = KeyStoreUtil.getPrivateKey(pkfile,KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, signerName, keypw);
|
||||
if (pk == null) {
|
||||
System.out.println("Private key for " + signerName + " not found in keystore " + privateKeyFile);
|
||||
return false;
|
||||
}
|
||||
SU3File file = new SU3File(signedFile);
|
||||
file.write(new File(inputFile), CONTENT_ROUTER, version, signerName, spk);
|
||||
file.write(new File(inputFile), ctype.getCode(), version, signerName, pk, type);
|
||||
System.out.println("Input file '" + inputFile + "' signed and written to '" + signedFile + "'");
|
||||
return true;
|
||||
} catch (DataFormatException dfe) {
|
||||
} catch (GeneralSecurityException gse) {
|
||||
System.out.println("Error signing input file '" + inputFile + "'");
|
||||
dfe.printStackTrace();
|
||||
gse.printStackTrace();
|
||||
return false;
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Error signing input file '" + inputFile + "'");
|
||||
ioe.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
@ -410,11 +633,11 @@ public class SU3File {
|
||||
InputStream in = null;
|
||||
try {
|
||||
SU3File file = new SU3File(signedFile);
|
||||
boolean isValidSignature = file.verifyAndMigrate(new File("/dev/null"));
|
||||
boolean isValidSignature = file.verify();
|
||||
if (isValidSignature)
|
||||
System.out.println("Signature VALID (signed by " + file.getSignerString() + ')');
|
||||
System.out.println("Signature VALID (signed by " + file.getSignerString() + ' ' + file._sigType + ')');
|
||||
else
|
||||
System.out.println("Signature INVALID (signed by " + file.getSignerString() + ')');
|
||||
System.out.println("Signature INVALID (signed by " + file.getSignerString() + ' ' + file._sigType +')');
|
||||
return isValidSignature;
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Error verifying input file '" + signedFile + "'");
|
||||
@ -422,4 +645,88 @@ public class SU3File {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean extractCLI(String signedFile, String outFile) {
|
||||
InputStream in = null;
|
||||
try {
|
||||
SU3File file = new SU3File(signedFile);
|
||||
File out = new File(outFile);
|
||||
boolean ok = file.verifyAndMigrate(out);
|
||||
if (ok)
|
||||
System.out.println("File extracted (signed by " + file.getSignerString() + ' ' + file._sigType + ')');
|
||||
else
|
||||
System.out.println("Signature INVALID (signed by " + file.getSignerString() + ' ' + file._sigType +')');
|
||||
return ok;
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Error extracting from file '" + signedFile + "'");
|
||||
ioe.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean genKeysCLI(String stype, String publicKeyFile, String privateKeyFile, String alias) {
|
||||
SigType type = stype == null ? SigType.getByCode(Integer.valueOf(DEFAULT_SIG_CODE)) : parseSigType(stype);
|
||||
if (type == null) {
|
||||
System.out.println("Signature type " + stype + " is not supported");
|
||||
return false;
|
||||
}
|
||||
return genKeysCLI(type, publicKeyFile, privateKeyFile, alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes Java-encoded keys (X.509 for public and PKCS#8 for private)
|
||||
* @return success
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private static final boolean genKeysCLI(SigType type, String publicKeyFile, String privateKeyFile, String alias) {
|
||||
File pubFile = new File(publicKeyFile);
|
||||
if (pubFile.exists()) {
|
||||
System.out.println("Error: Not overwriting file " + publicKeyFile);
|
||||
return false;
|
||||
}
|
||||
File ksFile = new File(privateKeyFile);
|
||||
String keypw = "";
|
||||
try {
|
||||
while (alias.length() == 0) {
|
||||
System.out.print("Enter key name (example@mail.i2p): ");
|
||||
alias = DataHelper.readLine(System.in).trim();
|
||||
}
|
||||
while (keypw.length() < 6) {
|
||||
System.out.print("Enter new key password: ");
|
||||
keypw = DataHelper.readLine(System.in).trim();
|
||||
if (keypw.length() > 0 && keypw.length() < 6)
|
||||
System.out.println("Key password must be at least 6 characters");
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
int keylen = type.getPubkeyLen() * 8;
|
||||
if (type.getBaseAlgorithm() == SigAlgo.EC) {
|
||||
keylen /= 2;
|
||||
if (keylen == 528)
|
||||
keylen = 521;
|
||||
}
|
||||
boolean success = KeyStoreUtil.createKeys(ksFile, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, alias,
|
||||
alias, "I2P", 3652, type.getBaseAlgorithm().getName(),
|
||||
keylen, keypw);
|
||||
if (!success) {
|
||||
System.err.println("Error creating keys for " + alias);
|
||||
return false;
|
||||
}
|
||||
File outfile = new File(publicKeyFile);
|
||||
success = KeyStoreUtil.exportCert(ksFile, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, alias, outfile);
|
||||
if (!success) {
|
||||
System.err.println("Error writing public key for " + alias + " to " + outfile);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
22
core/java/src/net/i2p/crypto/SigAlgo.java
Normal file
22
core/java/src/net/i2p/crypto/SigAlgo.java
Normal file
@ -0,0 +1,22 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
/**
|
||||
* Base signature algorithm type
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public enum SigAlgo {
|
||||
|
||||
DSA("DSA"),
|
||||
EC("EC"),
|
||||
RSA("RSA")
|
||||
;
|
||||
|
||||
private final String name;
|
||||
|
||||
SigAlgo(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() { return name; }
|
||||
}
|
@ -7,6 +7,9 @@ import java.security.spec.InvalidParameterSpecException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.SimpleDataStructure;
|
||||
|
||||
/**
|
||||
* Defines the properties for various signature types
|
||||
* that I2P supports or may someday support.
|
||||
@ -23,22 +26,53 @@ public enum SigType {
|
||||
* Pubkey 128 bytes; privkey 20 bytes; hash 20 bytes; sig 40 bytes
|
||||
* @since 0.9.8
|
||||
*/
|
||||
DSA_SHA1(0, 128, 20, 20, 40, "SHA-1", "SHA1withDSA", null),
|
||||
/** Pubkey 48 bytes; privkey 24 bytes; hash 20 bytes; sig 48 bytes */
|
||||
ECDSA_SHA1_P192(1, 48, 24, 20, 48, "SHA-1", "SHA1withECDSA", null),
|
||||
DSA_SHA1(0, 128, 20, 20, 40, SigAlgo.DSA, "SHA-1", "SHA1withDSA", CryptoConstants.DSA_SHA1_SPEC),
|
||||
/** Pubkey 64 bytes; privkey 32 bytes; hash 32 bytes; sig 64 bytes */
|
||||
ECDSA_SHA256_P256(2, 64, 32, 32, 64, "SHA-256", "SHA256withECDSA", null),
|
||||
ECDSA_SHA256_P256(1, 64, 32, 32, 64, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.P256_SPEC),
|
||||
/** Pubkey 96 bytes; privkey 48 bytes; hash 48 bytes; sig 96 bytes */
|
||||
ECDSA_SHA384_P384(3, 96, 48, 48, 96, "SHA-384", "SHA384withECDSA", null),
|
||||
ECDSA_SHA384_P384(2, 96, 48, 48, 96, SigAlgo.EC, "SHA-384", "SHA384withECDSA", ECConstants.P384_SPEC),
|
||||
/** Pubkey 132 bytes; privkey 66 bytes; hash 64 bytes; sig 132 bytes */
|
||||
ECDSA_SHA512_P521(4, 132, 66, 64, 132, "SHA-512", "SHA512withECDSA", null),
|
||||
ECDSA_SHA512_P521(3, 132, 66, 64, 132, SigAlgo.EC, "SHA-512", "SHA512withECDSA", ECConstants.P521_SPEC),
|
||||
|
||||
/** Pubkey 256 bytes; privkey 512 bytes; hash 32 bytes; sig 256 bytes */
|
||||
RSA_SHA256_2048(4, 256, 512, 32, 256, SigAlgo.RSA, "SHA-256", "SHA256withRSA", RSAConstants.F4_2048_SPEC),
|
||||
/** Pubkey 384 bytes; privkey 768 bytes; hash 48 bytes; sig 384 bytes */
|
||||
RSA_SHA384_3072(5, 384, 768, 48, 384, SigAlgo.RSA, "SHA-384", "SHA384withRSA", RSAConstants.F4_3072_SPEC),
|
||||
/** Pubkey 512 bytes; privkey 1024 bytes; hash 64 bytes; sig 512 bytes */
|
||||
RSA_SHA512_4096(6, 512, 1024, 64, 512, SigAlgo.RSA, "SHA-512", "SHA512withRSA", RSAConstants.F4_4096_SPEC),
|
||||
|
||||
|
||||
|
||||
// TESTING....................
|
||||
|
||||
|
||||
|
||||
// others..........
|
||||
|
||||
// EC mix and match
|
||||
//ECDSA_SHA256_P192(5, 48, 24, 32, 48, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.P192_SPEC),
|
||||
//ECDSA_SHA256_P384(6, 96, 48, 32, 96, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.P384_SPEC),
|
||||
//ECDSA_SHA256_P521(7, 132, 66, 32, 132, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.P521_SPEC),
|
||||
//ECDSA_SHA384_P256(8, 64, 32, 48, 64, SigAlgo.EC, "SHA-384", "SHA384withECDSA", ECConstants.P256_SPEC),
|
||||
//ECDSA_SHA384_P521(9, 132, 66, 48, 132, SigAlgo.EC, "SHA-384", "SHA384withECDSA", ECConstants.P521_SPEC),
|
||||
//ECDSA_SHA512_P256(10, 64, 32, 64, 64, SigAlgo.EC, "SHA-512", "SHA512withECDSA", ECConstants.P256_SPEC),
|
||||
//ECDSA_SHA512_P384(11, 96, 48, 64, 96, SigAlgo.EC, "SHA-512", "SHA512withECDSA", ECConstants.P384_SPEC),
|
||||
|
||||
// Koblitz
|
||||
//ECDSA_SHA256_K163(12, 42, 21, 32, 42, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.K163_SPEC),
|
||||
//ECDSA_SHA256_K233(13, 60, 30, 32, 60, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.K233_SPEC),
|
||||
//ECDSA_SHA256_K283(14, 72, 36, 32, 72, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.K283_SPEC),
|
||||
//ECDSA_SHA256_K409(15, 104, 52, 32, 104, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.K409_SPEC),
|
||||
//ECDSA_SHA256_K571(16, 144, 72, 32, 144, SigAlgo.EC, "SHA-256", "SHA256withECDSA", ECConstants.K571_SPEC),
|
||||
|
||||
// too short..............
|
||||
/** Pubkey 48 bytes; privkey 24 bytes; hash 20 bytes; sig 48 bytes */
|
||||
//ECDSA_SHA1_P192(1, 48, 24, 20, 48, SigAlgo.EC, "SHA-1", "SHA1withECDSA", ECConstants.P192_SPEC),
|
||||
//RSA_SHA1(17, 128, 256, 20, 128, SigAlgo.RSA, "SHA-1", "SHA1withRSA", RSAConstants.F4_1024_SPEC),
|
||||
//MD5
|
||||
//ELGAMAL_SHA256
|
||||
//RSA_SHA1
|
||||
//RSA_SHA256
|
||||
//RSA_SHA384
|
||||
//RSA_SHA512
|
||||
|
||||
//ELGAMAL_SHA256
|
||||
//DSA_2048_224(2, 256, 28, 32, 56, "SHA-256"),
|
||||
// Nonstandard, used by Syndie.
|
||||
// Pubkey 128 bytes; privkey 20 bytes; hash 32 bytes; sig 40 bytes
|
||||
@ -47,19 +81,22 @@ public enum SigType {
|
||||
//DSA_2048_256(2, 256, 32, 32, 64, "SHA-256", "?"),
|
||||
// Pubkey 384 bytes; privkey 32 bytes; hash 32 bytes; sig 64 bytes
|
||||
//DSA_3072_256(3, 384, 32, 32, 64, "SHA-256", "?"),
|
||||
|
||||
;
|
||||
|
||||
private final int code, pubkeyLen, privkeyLen, hashLen, sigLen;
|
||||
private final SigAlgo base;
|
||||
private final String digestName, algoName;
|
||||
private final AlgorithmParameterSpec params;
|
||||
|
||||
SigType(int cod, int pubLen, int privLen, int hLen, int sLen,
|
||||
SigType(int cod, int pubLen, int privLen, int hLen, int sLen, SigAlgo baseAlgo,
|
||||
String mdName, String aName, AlgorithmParameterSpec pSpec) {
|
||||
code = cod;
|
||||
pubkeyLen = pubLen;
|
||||
privkeyLen = privLen;
|
||||
hashLen = hLen;
|
||||
sigLen = sLen;
|
||||
base = baseAlgo;
|
||||
digestName = mdName;
|
||||
algoName = aName;
|
||||
params = pSpec;
|
||||
@ -75,6 +112,8 @@ public enum SigType {
|
||||
public int getHashLen() { return hashLen; }
|
||||
/** the length of the signature, in bytes */
|
||||
public int getSigLen() { return sigLen; }
|
||||
/** the standard base algorithm name used for the Java crypto factories */
|
||||
public SigAlgo getBaseAlgorithm() { return base; }
|
||||
/** the standard name used for the Java crypto factories */
|
||||
public String getAlgorithmName() { return algoName; }
|
||||
/**
|
||||
@ -100,6 +139,25 @@ public enum SigType {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 0.9.9
|
||||
* @throws UnsupportedOperationException if not supported
|
||||
*/
|
||||
public SimpleDataStructure getHashInstance() {
|
||||
switch (getHashLen()) {
|
||||
case 20:
|
||||
return new SHA1Hash();
|
||||
case 32:
|
||||
return new Hash();
|
||||
case 48:
|
||||
return new Hash384();
|
||||
case 64:
|
||||
return new Hash512();
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unsupported hash length: " + getHashLen());
|
||||
}
|
||||
}
|
||||
|
||||
private static final Map<Integer, SigType> BY_CODE = new HashMap<Integer, SigType>();
|
||||
|
||||
static {
|
||||
|
546
core/java/src/net/i2p/crypto/SigUtil.java
Normal file
546
core/java/src/net/i2p/crypto/SigUtil.java
Normal file
@ -0,0 +1,546 @@
|
||||
package net.i2p.crypto;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SignatureException;
|
||||
import java.security.interfaces.DSAPrivateKey;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.security.interfaces.ECPrivateKey;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.DSAPrivateKeySpec;
|
||||
import java.security.spec.DSAPublicKeySpec;
|
||||
import java.security.spec.ECField;
|
||||
import java.security.spec.ECFieldFp;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.security.spec.ECPrivateKeySpec;
|
||||
import java.security.spec.ECPublicKeySpec;
|
||||
import java.security.spec.ECPoint;
|
||||
import java.security.spec.EllipticCurve;
|
||||
import java.security.spec.KeySpec;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.RSAKeyGenParameterSpec;
|
||||
import java.security.spec.RSAPrivateKeySpec;
|
||||
import java.security.spec.RSAPublicKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.data.Signature;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.data.SigningPublicKey;
|
||||
import net.i2p.util.LHMCache;
|
||||
import net.i2p.util.NativeBigInteger;
|
||||
|
||||
|
||||
/**
|
||||
* Utilities for Signing keys and Signatures
|
||||
*
|
||||
* @since 0.9.9
|
||||
*/
|
||||
class SigUtil {
|
||||
|
||||
private static final Map<SigningPublicKey, ECPublicKey> _pubkeyCache = new LHMCache(64);
|
||||
private static final Map<SigningPrivateKey, ECPrivateKey> _privkeyCache = new LHMCache(16);
|
||||
|
||||
private SigUtil() {}
|
||||
|
||||
/**
|
||||
* @return JAVA key!
|
||||
*/
|
||||
public static PublicKey toJavaKey(SigningPublicKey pk)
|
||||
throws GeneralSecurityException {
|
||||
switch (pk.getType().getBaseAlgorithm()) {
|
||||
case DSA:
|
||||
return toJavaDSAKey(pk);
|
||||
case EC:
|
||||
return toJavaECKey(pk);
|
||||
case RSA:
|
||||
return toJavaRSAKey(pk);
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JAVA key!
|
||||
*/
|
||||
public static PrivateKey toJavaKey(SigningPrivateKey pk)
|
||||
throws GeneralSecurityException {
|
||||
switch (pk.getType().getBaseAlgorithm()) {
|
||||
case DSA:
|
||||
return toJavaDSAKey(pk);
|
||||
case EC:
|
||||
return toJavaECKey(pk);
|
||||
case RSA:
|
||||
return toJavaRSAKey(pk);
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pk JAVA key!
|
||||
*/
|
||||
public static SigningPublicKey fromJavaKey(PublicKey pk, SigType type)
|
||||
throws GeneralSecurityException {
|
||||
switch (type.getBaseAlgorithm()) {
|
||||
case DSA:
|
||||
return fromJavaKey((DSAPublicKey) pk);
|
||||
case EC:
|
||||
return fromJavaKey((ECPublicKey) pk, type);
|
||||
case RSA:
|
||||
return fromJavaKey((RSAPublicKey) pk, type);
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pk JAVA key!
|
||||
*/
|
||||
public static SigningPrivateKey fromJavaKey(PrivateKey pk, SigType type)
|
||||
throws GeneralSecurityException {
|
||||
switch (type.getBaseAlgorithm()) {
|
||||
case DSA:
|
||||
return fromJavaKey((DSAPrivateKey) pk);
|
||||
case EC:
|
||||
return fromJavaKey((ECPrivateKey) pk, type);
|
||||
case RSA:
|
||||
return fromJavaKey((RSAPrivateKey) pk, type);
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JAVA key!
|
||||
*/
|
||||
public static ECPublicKey toJavaECKey(SigningPublicKey pk)
|
||||
throws GeneralSecurityException {
|
||||
ECPublicKey rv;
|
||||
synchronized (_pubkeyCache) {
|
||||
rv = _pubkeyCache.get(pk);
|
||||
}
|
||||
if (rv != null)
|
||||
return rv;
|
||||
rv = cvtToJavaECKey(pk);
|
||||
synchronized (_pubkeyCache) {
|
||||
_pubkeyCache.put(pk, rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JAVA key!
|
||||
*/
|
||||
public static ECPrivateKey toJavaECKey(SigningPrivateKey pk)
|
||||
throws GeneralSecurityException {
|
||||
ECPrivateKey rv;
|
||||
synchronized (_privkeyCache) {
|
||||
rv = _privkeyCache.get(pk);
|
||||
}
|
||||
if (rv != null)
|
||||
return rv;
|
||||
rv = cvtToJavaECKey(pk);
|
||||
synchronized (_privkeyCache) {
|
||||
_privkeyCache.put(pk, rv);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private static ECPublicKey cvtToJavaECKey(SigningPublicKey pk)
|
||||
throws GeneralSecurityException {
|
||||
SigType type = pk.getType();
|
||||
BigInteger[] xy = split(pk.getData());
|
||||
ECPoint w = new ECPoint(xy[0], xy[1]);
|
||||
// see ECConstants re: casting
|
||||
ECPublicKeySpec ks = new ECPublicKeySpec(w, (ECParameterSpec) type.getParams());
|
||||
KeyFactory kf = KeyFactory.getInstance("EC");
|
||||
return (ECPublicKey) kf.generatePublic(ks);
|
||||
}
|
||||
|
||||
public static ECPrivateKey cvtToJavaECKey(SigningPrivateKey pk)
|
||||
throws GeneralSecurityException {
|
||||
SigType type = pk.getType();
|
||||
int len = type.getPubkeyLen();
|
||||
int sublen = len / 2;
|
||||
byte[] b = pk.getData();
|
||||
BigInteger s = new NativeBigInteger(1, b);
|
||||
// see ECConstants re: casting
|
||||
ECPrivateKeySpec ks = new ECPrivateKeySpec(s, (ECParameterSpec) type.getParams());
|
||||
KeyFactory kf = KeyFactory.getInstance("EC");
|
||||
return (ECPrivateKey) kf.generatePrivate(ks);
|
||||
}
|
||||
|
||||
public static SigningPublicKey fromJavaKey(ECPublicKey pk, SigType type)
|
||||
throws GeneralSecurityException {
|
||||
ECPoint w = pk.getW();
|
||||
BigInteger x = w.getAffineX();
|
||||
BigInteger y = w.getAffineY();
|
||||
int len = type.getPubkeyLen();
|
||||
byte[] b = combine(x, y, len);
|
||||
return new SigningPublicKey(type, b);
|
||||
}
|
||||
|
||||
public static SigningPrivateKey fromJavaKey(ECPrivateKey pk, SigType type)
|
||||
throws GeneralSecurityException {
|
||||
BigInteger s = pk.getS();
|
||||
int len = type.getPrivkeyLen();
|
||||
byte[] bs = rectify(s, len);
|
||||
return new SigningPrivateKey(type, bs);
|
||||
}
|
||||
|
||||
public static DSAPublicKey toJavaDSAKey(SigningPublicKey pk)
|
||||
throws GeneralSecurityException {
|
||||
KeyFactory kf = KeyFactory.getInstance("DSA");
|
||||
// y p q g
|
||||
KeySpec ks = new DSAPublicKeySpec(new NativeBigInteger(1, pk.getData()),
|
||||
CryptoConstants.dsap,
|
||||
CryptoConstants.dsaq,
|
||||
CryptoConstants.dsag);
|
||||
return (DSAPublicKey) kf.generatePublic(ks);
|
||||
}
|
||||
|
||||
public static DSAPrivateKey toJavaDSAKey(SigningPrivateKey pk)
|
||||
throws GeneralSecurityException {
|
||||
KeyFactory kf = KeyFactory.getInstance("DSA");
|
||||
// x p q g
|
||||
KeySpec ks = new DSAPrivateKeySpec(new NativeBigInteger(1, pk.getData()),
|
||||
CryptoConstants.dsap,
|
||||
CryptoConstants.dsaq,
|
||||
CryptoConstants.dsag);
|
||||
return (DSAPrivateKey) kf.generatePrivate(ks);
|
||||
}
|
||||
|
||||
public static SigningPublicKey fromJavaKey(DSAPublicKey pk)
|
||||
throws GeneralSecurityException {
|
||||
BigInteger y = pk.getY();
|
||||
SigType type = SigType.DSA_SHA1;
|
||||
int len = type.getPubkeyLen();
|
||||
byte[] by = rectify(y, len);
|
||||
return new SigningPublicKey(type, by);
|
||||
}
|
||||
|
||||
public static SigningPrivateKey fromJavaKey(DSAPrivateKey pk)
|
||||
throws GeneralSecurityException {
|
||||
BigInteger x = pk.getX();
|
||||
SigType type = SigType.DSA_SHA1;
|
||||
int len = type.getPrivkeyLen();
|
||||
byte[] bx = rectify(x, len);
|
||||
return new SigningPrivateKey(type, bx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated unused
|
||||
*/
|
||||
public static RSAPublicKey toJavaRSAKey(SigningPublicKey pk)
|
||||
throws GeneralSecurityException {
|
||||
SigType type = pk.getType();
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA");
|
||||
BigInteger n = new NativeBigInteger(1, pk.getData());
|
||||
BigInteger e = ((RSAKeyGenParameterSpec)type.getParams()).getPublicExponent();
|
||||
// modulus exponent
|
||||
KeySpec ks = new RSAPublicKeySpec(n, e);
|
||||
return (RSAPublicKey) kf.generatePublic(ks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated unused
|
||||
*/
|
||||
public static RSAPrivateKey toJavaRSAKey(SigningPrivateKey pk)
|
||||
throws GeneralSecurityException {
|
||||
KeyFactory kf = KeyFactory.getInstance("RSA");
|
||||
// private key is modulus (pubkey) + exponent
|
||||
BigInteger[] nd = split(pk.getData());
|
||||
// modulus exponent
|
||||
KeySpec ks = new RSAPrivateKeySpec(nd[0], nd[1]);
|
||||
return (RSAPrivateKey) kf.generatePrivate(ks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated unused
|
||||
*/
|
||||
public static SigningPublicKey fromJavaKey(RSAPublicKey pk, SigType type)
|
||||
throws GeneralSecurityException {
|
||||
BigInteger n = pk.getModulus();
|
||||
int len = type.getPubkeyLen();
|
||||
byte[] bn = rectify(n, len);
|
||||
return new SigningPublicKey(type, bn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated unused
|
||||
*/
|
||||
public static SigningPrivateKey fromJavaKey(RSAPrivateKey pk, SigType type)
|
||||
throws GeneralSecurityException {
|
||||
// private key is modulus (pubkey) + exponent
|
||||
BigInteger n = pk.getModulus();
|
||||
BigInteger d = pk.getPrivateExponent();
|
||||
byte[] b = combine(n, d, type.getPrivkeyLen());
|
||||
return new SigningPrivateKey(type, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ASN.1 representation
|
||||
*/
|
||||
public static byte[] toJavaSig(Signature sig) {
|
||||
// RSA sigs are not ASN encoded
|
||||
if (sig.getType().getBaseAlgorithm() == SigAlgo.RSA)
|
||||
return sig.getData();
|
||||
return sigBytesToASN1(sig.getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param asn ASN.1 representation
|
||||
* @return a Signature with SigType type
|
||||
*/
|
||||
public static Signature fromJavaSig(byte[] asn, SigType type)
|
||||
throws SignatureException {
|
||||
// RSA sigs are not ASN encoded
|
||||
if (type.getBaseAlgorithm() == SigAlgo.RSA)
|
||||
return new Signature(type, asn);
|
||||
return new Signature(type, aSN1ToSigBytes(asn, type.getSigLen()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JAVA key!
|
||||
*/
|
||||
public static PublicKey importJavaPublicKey(File file, SigType type)
|
||||
throws GeneralSecurityException, IOException {
|
||||
byte[] data = getData(file);
|
||||
KeySpec ks = new X509EncodedKeySpec(data);
|
||||
String algo = type.getBaseAlgorithm().getName();
|
||||
KeyFactory kf = KeyFactory.getInstance(algo);
|
||||
return kf.generatePublic(ks);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return JAVA key!
|
||||
*/
|
||||
public static PrivateKey importJavaPrivateKey(File file, SigType type)
|
||||
throws GeneralSecurityException, IOException {
|
||||
byte[] data = getData(file);
|
||||
KeySpec ks = new PKCS8EncodedKeySpec(data);
|
||||
String algo = type.getBaseAlgorithm().getName();
|
||||
KeyFactory kf = KeyFactory.getInstance(algo);
|
||||
return kf.generatePrivate(ks);
|
||||
}
|
||||
|
||||
/** 16 KB max */
|
||||
private static byte[] getData(File file) throws IOException {
|
||||
byte buf[] = new byte[1024];
|
||||
InputStream in = null;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
int read = 0;
|
||||
int tot = 0;
|
||||
while ( (read = in.read(buf)) != -1) {
|
||||
out.write(buf, 0, read);
|
||||
tot += read;
|
||||
if (tot > 16*1024)
|
||||
throw new IOException("too big");
|
||||
}
|
||||
return out.toByteArray();
|
||||
} finally {
|
||||
if (in != null)
|
||||
try { in.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a byte array into two BigIntegers
|
||||
* @return array of two BigIntegers
|
||||
*/
|
||||
private static BigInteger[] split(byte[] b) {
|
||||
int sublen = b.length / 2;
|
||||
byte[] bx = new byte[sublen];
|
||||
byte[] by = new byte[sublen];
|
||||
System.arraycopy(b, 0, bx, 0, sublen);
|
||||
System.arraycopy(b, sublen, by, 0, sublen);
|
||||
NativeBigInteger x = new NativeBigInteger(1, bx);
|
||||
NativeBigInteger y = new NativeBigInteger(1, by);
|
||||
return new NativeBigInteger[] {x, y};
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine two BigIntegers of nominal length = len / 2
|
||||
* @return array of exactly len bytes
|
||||
*/
|
||||
private static byte[] combine(BigInteger x, BigInteger y, int len)
|
||||
throws InvalidKeyException {
|
||||
int sublen = len / 2;
|
||||
byte[] b = new byte[len];
|
||||
byte[] bx = rectify(x, sublen);
|
||||
byte[] by = rectify(y, sublen);
|
||||
System.arraycopy(bx, 0, b, 0, sublen);
|
||||
System.arraycopy(by, 0, b, sublen, sublen);
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bi non-negative
|
||||
* @return array of exactly len bytes
|
||||
*/
|
||||
public static byte[] rectify(BigInteger bi, int len)
|
||||
throws InvalidKeyException {
|
||||
byte[] b = bi.toByteArray();
|
||||
if (b.length == len) {
|
||||
// just right
|
||||
return b;
|
||||
}
|
||||
if (b.length > len + 1)
|
||||
throw new InvalidKeyException("key too big (" + b.length + ") max is " + (len + 1));
|
||||
byte[] rv = new byte[len];
|
||||
if (b.length == 0)
|
||||
return rv;
|
||||
if ((b[0] & 0x80) != 0)
|
||||
throw new InvalidKeyException("negative");
|
||||
if (b.length > len) {
|
||||
// leading 0 byte
|
||||
if (b[0] != 0)
|
||||
throw new InvalidKeyException("key too big (" + b.length + ") max is " + len);
|
||||
System.arraycopy(b, 1, rv, 0, len);
|
||||
} else {
|
||||
// smaller
|
||||
System.arraycopy(b, 0, rv, len - b.length, b.length);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* http://download.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html
|
||||
* Signature Format ASN.1 sequence of two INTEGER values: r and s, in that order:
|
||||
* SEQUENCE ::= { r INTEGER, s INTEGER }
|
||||
*
|
||||
* http://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One
|
||||
* 30 -- tag indicating SEQUENCE
|
||||
* xx - length in octets
|
||||
*
|
||||
* 02 -- tag indicating INTEGER
|
||||
* xx - length in octets
|
||||
* xxxxxx - value
|
||||
*
|
||||
* Convert to BigInteger and back so we have the minimum length representation, as required.
|
||||
* r and s are always non-negative.
|
||||
*
|
||||
* Only supports sigs up to about 252 bytes. See code to fix BER encoding for this before you
|
||||
* add a SigType with bigger signatures.
|
||||
*
|
||||
* @throws IllegalArgumentException if too big
|
||||
* @since 0.8.7, moved to SigUtil in 0.9.9
|
||||
*/
|
||||
private static byte[] sigBytesToASN1(byte[] sig) {
|
||||
//System.out.println("pre TO asn1\n" + net.i2p.util.HexDump.dump(sig));
|
||||
int len = sig.length;
|
||||
int sublen = len / 2;
|
||||
byte[] tmp = new byte[sublen];
|
||||
|
||||
System.arraycopy(sig, 0, tmp, 0, sublen);
|
||||
BigInteger r = new BigInteger(1, tmp);
|
||||
byte[] rb = r.toByteArray();
|
||||
if (rb.length > 127)
|
||||
throw new IllegalArgumentException("FIXME R length > 127");
|
||||
System.arraycopy(sig, sublen, tmp, 0, sublen);
|
||||
BigInteger s = new BigInteger(1, tmp);
|
||||
byte[] sb = s.toByteArray();
|
||||
if (sb.length > 127)
|
||||
throw new IllegalArgumentException("FIXME S length > 127");
|
||||
int seqlen = rb.length + sb.length + 4;
|
||||
if (seqlen > 255)
|
||||
throw new IllegalArgumentException("FIXME seq length > 255");
|
||||
int totlen = seqlen + 2;
|
||||
if (seqlen > 127)
|
||||
totlen++;
|
||||
byte[] rv = new byte[totlen];
|
||||
int idx = 0;
|
||||
|
||||
rv[idx++] = 0x30;
|
||||
if (seqlen > 127)
|
||||
rv[idx++] =(byte) 0x81;
|
||||
rv[idx++] = (byte) seqlen;
|
||||
|
||||
rv[idx++] = 0x02;
|
||||
rv[idx++] = (byte) rb.length;
|
||||
System.arraycopy(rb, 0, rv, idx, rb.length);
|
||||
idx += rb.length;
|
||||
|
||||
rv[idx++] = 0x02;
|
||||
rv[idx++] = (byte) sb.length;
|
||||
System.arraycopy(sb, 0, rv, idx, sb.length);
|
||||
|
||||
//System.out.println("post TO asn1\n" + net.i2p.util.HexDump.dump(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* See above.
|
||||
* Only supports sigs up to about 252 bytes. See code to fix BER encoding for bigger than that.
|
||||
*
|
||||
* @return len bytes
|
||||
* @since 0.8.7, moved to SigUtil in 0.9.9
|
||||
*/
|
||||
private static byte[] aSN1ToSigBytes(byte[] asn, int len)
|
||||
throws SignatureException {
|
||||
//System.out.println("pre from asn1 len=" + len + "\n" + net.i2p.util.HexDump.dump(asn));
|
||||
if (asn[0] != 0x30)
|
||||
throw new SignatureException("asn[0] = " + (asn[0] & 0xff));
|
||||
// handles total len > 127
|
||||
int idx = 2;
|
||||
if ((asn[1] & 0x80) != 0)
|
||||
idx += asn[1] & 0x7f;
|
||||
if (asn[idx] != 0x02)
|
||||
throw new SignatureException("asn[2] = " + (asn[idx] & 0xff));
|
||||
byte[] rv = new byte[len];
|
||||
int sublen = len / 2;
|
||||
int rlen = asn[++idx];
|
||||
if ((rlen & 0x80) != 0)
|
||||
throw new SignatureException("FIXME R length > 127");
|
||||
if ((asn[++idx] & 0x80) != 0)
|
||||
throw new SignatureException("R is negative");
|
||||
if (rlen > sublen + 1)
|
||||
throw new SignatureException("R too big " + rlen);
|
||||
if (rlen == sublen + 1)
|
||||
System.arraycopy(asn, idx + 1, rv, 0, sublen);
|
||||
else
|
||||
System.arraycopy(asn, idx, rv, sublen - rlen, rlen);
|
||||
idx += rlen;
|
||||
int slenloc = idx + 1;
|
||||
if (asn[idx] != 0x02)
|
||||
throw new SignatureException("asn[s] = " + (asn[idx] & 0xff));
|
||||
int slen = asn[slenloc];
|
||||
if ((slen & 0x80) != 0)
|
||||
throw new SignatureException("FIXME S length > 127");
|
||||
if ((asn[slenloc + 1] & 0x80) != 0)
|
||||
throw new SignatureException("S is negative");
|
||||
if (slen > sublen + 1)
|
||||
throw new SignatureException("S too big " + slen);
|
||||
if (slen == sublen + 1)
|
||||
System.arraycopy(asn, slenloc + 2, rv, sublen, sublen);
|
||||
else
|
||||
System.arraycopy(asn, slenloc + 1, rv, len - slen, slen);
|
||||
//System.out.println("post from asn1\n" + net.i2p.util.HexDump.dump(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
public static void clearCaches() {
|
||||
synchronized(_pubkeyCache) {
|
||||
_pubkeyCache.clear();
|
||||
}
|
||||
synchronized(_privkeyCache) {
|
||||
_privkeyCache.clear();
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ import net.i2p.data.Signature;
|
||||
import net.i2p.data.SigningPrivateKey;
|
||||
import net.i2p.data.SigningPublicKey;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
import net.i2p.util.VersionComparator;
|
||||
import net.i2p.util.ZipFileComment;
|
||||
|
||||
@ -315,20 +316,29 @@ riCe6OlAEiNpcc6mMyIYYWFICbrDFTrDR3wXqwc/Jkcx6L5VVWoagpSzbo3yGhc=
|
||||
|
||||
/** @return success */
|
||||
private static final boolean genKeysCLI(String publicKeyFile, String privateKeyFile) {
|
||||
File pubFile = new File(publicKeyFile);
|
||||
File privFile = new File(privateKeyFile);
|
||||
if (pubFile.exists()) {
|
||||
System.out.println("Error: Not overwriting file " + publicKeyFile);
|
||||
return false;
|
||||
}
|
||||
if (privFile.exists()) {
|
||||
System.out.println("Error: Not overwriting file " + privateKeyFile);
|
||||
return false;
|
||||
}
|
||||
FileOutputStream fileOutputStream = null;
|
||||
|
||||
I2PAppContext context = I2PAppContext.getGlobalContext();
|
||||
try {
|
||||
Object signingKeypair[] = context.keyGenerator().generateSigningKeypair();
|
||||
SigningPublicKey signingPublicKey = (SigningPublicKey) signingKeypair[0];
|
||||
SigningPrivateKey signingPrivateKey = (SigningPrivateKey) signingKeypair[1];
|
||||
|
||||
fileOutputStream = new FileOutputStream(publicKeyFile);
|
||||
fileOutputStream = new SecureFileOutputStream(pubFile);
|
||||
signingPublicKey.writeBytes(fileOutputStream);
|
||||
fileOutputStream.close();
|
||||
fileOutputStream = null;
|
||||
|
||||
fileOutputStream = new FileOutputStream(privateKeyFile);
|
||||
fileOutputStream = new SecureFileOutputStream(privFile);
|
||||
signingPrivateKey.writeBytes(fileOutputStream);
|
||||
|
||||
System.out.println("\r\nPrivate key written to: " + privateKeyFile);
|
||||
|
@ -6,14 +6,22 @@ package net.i2p.update;
|
||||
* @since 0.9.4
|
||||
*/
|
||||
public enum UpdateType {
|
||||
TYPE_DUMMY, // Internal use only
|
||||
/** Dummy: internal use only */
|
||||
TYPE_DUMMY,
|
||||
NEWS,
|
||||
ROUTER_SIGNED,
|
||||
ROUTER_UNSIGNED,
|
||||
PLUGIN,
|
||||
/** unused */
|
||||
GEOIP,
|
||||
/** unused */
|
||||
BLOCKLIST,
|
||||
/** unused */
|
||||
RESEED,
|
||||
/** unused */
|
||||
HOMEPAGE,
|
||||
ADDRESSBOOK
|
||||
/** unused */
|
||||
ADDRESSBOOK,
|
||||
/** @since 0.9.9 */
|
||||
ROUTER_SIGNED_SU3
|
||||
}
|
||||
|
@ -1055,12 +1055,14 @@ public class EepGet {
|
||||
URL url = new URL(_actualURL);
|
||||
if ("http".equals(url.getProtocol())) {
|
||||
String host = url.getHost();
|
||||
if (host.toLowerCase(Locale.US).endsWith(".i2p"))
|
||||
throw new MalformedURLException("I2P addresses must be proxied");
|
||||
int port = url.getPort();
|
||||
if (port == -1)
|
||||
port = 80;
|
||||
_proxy = new Socket(host, port);
|
||||
} else {
|
||||
throw new IOException("URL is not supported:" + _actualURL);
|
||||
throw new MalformedURLException("URL is not supported:" + _actualURL);
|
||||
}
|
||||
// an MUE is an IOE
|
||||
//} catch (MalformedURLException mue) {
|
||||
@ -1089,6 +1091,8 @@ public class EepGet {
|
||||
post = true;
|
||||
URL url = new URL(_actualURL);
|
||||
String host = url.getHost();
|
||||
if (host == null || host.length() <= 0)
|
||||
throw new MalformedURLException("Bad URL, no host");
|
||||
int port = url.getPort();
|
||||
String path = url.getPath();
|
||||
String query = url.getQuery();
|
||||
|
@ -112,7 +112,8 @@ public class NativeBigInteger extends BigInteger {
|
||||
* don't spew log messages. main() below overrides to true.
|
||||
*/
|
||||
private static boolean _doLog = System.getProperty("jbigi.dontLog") == null &&
|
||||
I2PAppContext.getGlobalContext().isRouterContext();
|
||||
I2PAppContext.getCurrentContext() != null &&
|
||||
I2PAppContext.getCurrentContext().isRouterContext();
|
||||
|
||||
/**
|
||||
* The following libraries are be available in jbigi.jar in all I2P versions
|
||||
|
@ -3,6 +3,7 @@ package net.i2p.util;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
@ -11,6 +12,9 @@ import net.i2p.I2PAppContext;
|
||||
* Fetch exactly the first 'size' bytes into a stream
|
||||
* Anything less or more will throw an IOException
|
||||
* No retries, no min and max size options, no timeout option
|
||||
* If the server does not return a Content-Length header of the correct size,
|
||||
* the fetch will fail.
|
||||
*
|
||||
* Useful for checking .sud versions
|
||||
*
|
||||
* @since 0.7.12
|
||||
@ -19,12 +23,20 @@ import net.i2p.I2PAppContext;
|
||||
public class PartialEepGet extends EepGet {
|
||||
long _fetchSize;
|
||||
|
||||
/** @param size fetch exactly this many bytes */
|
||||
/**
|
||||
* Instantiate an EepGet that will fetch exactly size bytes when fetch() is called.
|
||||
*
|
||||
* @param proxyHost use null or "" for no proxy
|
||||
* @param proxyPort use 0 for no proxy
|
||||
* @param size fetch exactly this many bytes
|
||||
*/
|
||||
public PartialEepGet(I2PAppContext ctx, String proxyHost, int proxyPort,
|
||||
OutputStream outputStream, String url, long size) {
|
||||
// we're using this constructor:
|
||||
// public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries, long minSize, long maxSize, String outputFile, OutputStream outputStream, String url, boolean allowCaching, String etag, String postData) {
|
||||
super(ctx, true, proxyHost, proxyPort, 0, size, size, null, outputStream, url, true, null, null);
|
||||
// public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries,
|
||||
// long minSize, long maxSize, String outputFile, OutputStream outputStream, String url, boolean allowCaching, String etag, String postData) {
|
||||
super(ctx, proxyHost != null && proxyPort > 0, proxyHost, proxyPort, 0,
|
||||
size, size, null, outputStream, url, true, null, null);
|
||||
_fetchSize = size;
|
||||
}
|
||||
|
||||
@ -88,7 +100,8 @@ public class PartialEepGet extends EepGet {
|
||||
}
|
||||
|
||||
private static void usage() {
|
||||
System.err.println("PartialEepGet [-p 127.0.0.1:4444] [-l #bytes] url");
|
||||
System.err.println("PartialEepGet [-p 127.0.0.1:4444] [-l #bytes] url\n" +
|
||||
" (use -p :0 for no proxy)");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -96,6 +109,8 @@ public class PartialEepGet extends EepGet {
|
||||
StringBuilder buf = new StringBuilder(2048);
|
||||
URL url = new URL(_actualURL);
|
||||
String host = url.getHost();
|
||||
if (host == null || host.length() <= 0)
|
||||
throw new MalformedURLException("Bad URL, no host");
|
||||
int port = url.getPort();
|
||||
String path = url.getPath();
|
||||
String query = url.getQuery();
|
||||
|
@ -46,18 +46,14 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.security.KeyStore;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
@ -67,7 +63,8 @@ import javax.net.ssl.TrustManagerFactory;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.crypto.CertUtil;
|
||||
import net.i2p.crypto.KeyStoreUtil;
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
/**
|
||||
@ -76,7 +73,7 @@ import net.i2p.data.DataHelper;
|
||||
* Fails on bad certs (must have a valid cert chain)
|
||||
* Self-signed certs or CAs not in the JVM key store must be loaded to be trusted.
|
||||
*
|
||||
* Since 0.8.2, loads additional trusted CA certs from $I2P/certificates/ and ~/.i2p/certificates/
|
||||
* Since 0.8.2, loads additional trusted CA certs from $I2P/certificates/ssl/ and ~/.i2p/certificates/ssl/
|
||||
*
|
||||
* @author zzz
|
||||
* @since 0.7.10
|
||||
@ -91,7 +88,7 @@ public class SSLEepGet extends EepGet {
|
||||
/** may be null if init failed */
|
||||
private SavingTrustManager _stm;
|
||||
|
||||
private static final boolean _isAndroid = SystemVersion.isAndroid();
|
||||
private static final String CERT_DIR = "certificates/ssl";
|
||||
|
||||
/**
|
||||
* A new SSLEepGet with a new SSLState
|
||||
@ -107,9 +104,39 @@ public class SSLEepGet extends EepGet {
|
||||
* @since 0.8.2
|
||||
*/
|
||||
public SSLEepGet(I2PAppContext ctx, OutputStream outputStream, String url, SSLState state) {
|
||||
this(ctx, null, outputStream, url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* A new SSLEepGet with a new SSLState
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public SSLEepGet(I2PAppContext ctx, String outputFile, String url) {
|
||||
this(ctx, outputFile, url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param state an SSLState retrieved from a previous SSLEepGet with getSSLState(), or null.
|
||||
* This makes repeated fetches from the same host MUCH faster,
|
||||
* and prevents repeated key store loads even for different hosts.
|
||||
* @since 0.9.9
|
||||
*/
|
||||
public SSLEepGet(I2PAppContext ctx, String outputFile, String url, SSLState state) {
|
||||
this(ctx, outputFile, null, url, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* outputFile, outputStream: One null, one non-null
|
||||
*
|
||||
* @param state an SSLState retrieved from a previous SSLEepGet with getSSLState(), or null.
|
||||
* This makes repeated fetches from the same host MUCH faster,
|
||||
* and prevents repeated key store loads even for different hosts.
|
||||
* @since 0.9.9
|
||||
*/
|
||||
private SSLEepGet(I2PAppContext ctx, String outputFile, OutputStream outputStream, String url, SSLState state) {
|
||||
// we're using this constructor:
|
||||
// public EepGet(I2PAppContext ctx, boolean shouldProxy, String proxyHost, int proxyPort, int numRetries, long minSize, long maxSize, String outputFile, OutputStream outputStream, String url, boolean allowCaching, String etag, String postData) {
|
||||
super(ctx, false, null, -1, 0, -1, -1, null, outputStream, url, true, null, null);
|
||||
super(ctx, false, null, -1, 0, -1, -1, outputFile, outputStream, url, true, null, null);
|
||||
if (state != null && state.context != null)
|
||||
_sslContext = state.context;
|
||||
else
|
||||
@ -177,70 +204,39 @@ public class SSLEepGet extends EepGet {
|
||||
* else from $JAVA_HOME/lib/security/jssacacerts,
|
||||
* else from $JAVA_HOME/lib/security/cacerts.
|
||||
*
|
||||
* Then adds certs found in the $I2P/certificates/ directory
|
||||
* and in the ~/.i2p/certificates/ directory.
|
||||
* Then adds certs found in the $I2P/certificates/ssl/ directory
|
||||
* and in the ~/.i2p/certificates/ssl/ directory.
|
||||
*
|
||||
* @return null on failure
|
||||
* @since 0.8.2
|
||||
*/
|
||||
private SSLContext initSSLContext() {
|
||||
KeyStore ks;
|
||||
try {
|
||||
ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
_log.error("Key Store init error", gse);
|
||||
KeyStore ks = KeyStoreUtil.loadSystemKeyStore();
|
||||
if (ks == null) {
|
||||
_log.error("Key Store init error");
|
||||
return null;
|
||||
}
|
||||
boolean success = false;
|
||||
String override = System.getProperty("javax.net.ssl.keyStore");
|
||||
if (override != null)
|
||||
success = loadCerts(new File(override), ks);
|
||||
if (!success) {
|
||||
if (_isAndroid) {
|
||||
// thru API 13. As of API 14 (ICS), the file is gone, but
|
||||
// ks.load(null, pw) will bring in the default certs?
|
||||
success = loadCerts(new File(System.getProperty("java.home"), "etc/security/cacerts.bks"), ks);
|
||||
} else {
|
||||
success = loadCerts(new File(System.getProperty("java.home"), "lib/security/jssecacerts"), ks);
|
||||
if (!success)
|
||||
success = loadCerts(new File(System.getProperty("java.home"), "lib/security/cacerts"), ks);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
try {
|
||||
// must be initted
|
||||
ks.load(null, "changeit".toCharArray());
|
||||
} catch (Exception e) {}
|
||||
_log.error("All key store loads failed, will only load local certificates");
|
||||
} else if (_log.shouldLog(Log.INFO)) {
|
||||
int count = 0;
|
||||
try {
|
||||
for(Enumeration<String> e = ks.aliases(); e.hasMoreElements();) {
|
||||
String alias = e.nextElement();
|
||||
if (ks.isCertificateEntry(alias))
|
||||
count++;
|
||||
}
|
||||
} catch (Exception foo) {}
|
||||
if (_log.shouldLog(Log.INFO)) {
|
||||
int count = KeyStoreUtil.countCerts(ks);
|
||||
_log.info("Loaded " + count + " default trusted certificates");
|
||||
}
|
||||
|
||||
File dir = new File(_context.getBaseDir(), "certificates");
|
||||
int adds = addCerts(dir, ks);
|
||||
File dir = new File(_context.getBaseDir(), CERT_DIR);
|
||||
int adds = KeyStoreUtil.addCerts(dir, ks);
|
||||
int totalAdds = adds;
|
||||
if (adds > 0 && _log.shouldLog(Log.INFO))
|
||||
_log.info("Loaded " + adds + " trusted certificates from " + dir.getAbsolutePath());
|
||||
if (!_context.getBaseDir().getAbsolutePath().equals(_context.getConfigDir().getAbsolutePath())) {
|
||||
dir = new File(_context.getConfigDir(), "certificates");
|
||||
adds = addCerts(dir, ks);
|
||||
dir = new File(_context.getConfigDir(), CERT_DIR);
|
||||
adds = KeyStoreUtil.addCerts(dir, ks);
|
||||
totalAdds += adds;
|
||||
if (adds > 0 && _log.shouldLog(Log.INFO))
|
||||
_log.info("Loaded " + adds + " trusted certificates from " + dir.getAbsolutePath());
|
||||
}
|
||||
dir = new File(System.getProperty("user.dir"));
|
||||
if (!_context.getBaseDir().getAbsolutePath().equals(dir.getAbsolutePath())) {
|
||||
dir = new File(_context.getConfigDir(), "certificates");
|
||||
adds = addCerts(dir, ks);
|
||||
dir = new File(_context.getConfigDir(), CERT_DIR);
|
||||
adds = KeyStoreUtil.addCerts(dir, ks);
|
||||
totalAdds += adds;
|
||||
if (adds > 0 && _log.shouldLog(Log.INFO))
|
||||
_log.info("Loaded " + adds + " trusted certificates from " + dir.getAbsolutePath());
|
||||
@ -261,118 +257,6 @@ public class SSLEepGet extends EepGet {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all X509 Certs from a key store File into a KeyStore
|
||||
* Note that each call reinitializes the KeyStore
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.2
|
||||
*/
|
||||
private boolean loadCerts(File file, KeyStore ks) {
|
||||
if (!file.exists())
|
||||
return false;
|
||||
InputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
// "changeit" is the default password
|
||||
ks.load(fis, "changeit".toCharArray());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
_log.error("KeyStore load error, no default keys: " + file.getAbsolutePath(), gse);
|
||||
try {
|
||||
// not clear if null is allowed for password
|
||||
ks.load(null, "changeit".toCharArray());
|
||||
} catch (Exception foo) {}
|
||||
return false;
|
||||
} catch (IOException ioe) {
|
||||
_log.error("KeyStore load error, no default keys: " + file.getAbsolutePath(), ioe);
|
||||
try {
|
||||
ks.load(null, "changeit".toCharArray());
|
||||
} catch (Exception foo) {}
|
||||
return false;
|
||||
} finally {
|
||||
try { if (fis != null) fis.close(); } catch (IOException foo) {}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all X509 Certs from a directory and add them to the
|
||||
* trusted set of certificates in the key store
|
||||
*
|
||||
* @return number successfully added
|
||||
* @since 0.8.2
|
||||
*/
|
||||
private int addCerts(File dir, KeyStore ks) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Looking for X509 Certificates in " + dir.getAbsolutePath());
|
||||
int added = 0;
|
||||
if (dir.exists() && dir.isDirectory()) {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File f = files[i];
|
||||
if (!f.isFile())
|
||||
continue;
|
||||
// use file name as alias
|
||||
// https://www.sslshopper.com/ssl-converter.html
|
||||
// No idea if all these formats can actually be read by CertificateFactory
|
||||
String alias = f.getName().toLowerCase(Locale.US);
|
||||
if (alias.endsWith(".crt") || alias.endsWith(".pem") || alias.endsWith(".key") ||
|
||||
alias.endsWith(".der") || alias.endsWith(".key") || alias.endsWith(".p7b") ||
|
||||
alias.endsWith(".p7c") || alias.endsWith(".pfx") || alias.endsWith(".p12"))
|
||||
alias = alias.substring(0, alias.length() - 4);
|
||||
boolean success = addCert(f, alias, ks);
|
||||
if (success)
|
||||
added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an X509 Cert from a file and add it to the
|
||||
* trusted set of certificates in the key store
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.2
|
||||
*/
|
||||
private boolean addCert(File file, String alias, KeyStore ks) {
|
||||
InputStream fis = null;
|
||||
try {
|
||||
fis = new FileInputStream(file);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
X509Certificate cert = (X509Certificate)cf.generateCertificate(fis);
|
||||
if (_log.shouldLog(Log.INFO)) {
|
||||
_log.info("Read X509 Certificate from " + file.getAbsolutePath() +
|
||||
" Issuer: " + cert.getIssuerX500Principal() +
|
||||
"; Valid From: " + cert.getNotBefore() +
|
||||
" To: " + cert.getNotAfter());
|
||||
}
|
||||
try {
|
||||
cert.checkValidity();
|
||||
} catch (CertificateExpiredException cee) {
|
||||
_log.error("Rejecting expired X509 Certificate: " + file.getAbsolutePath(), cee);
|
||||
return false;
|
||||
} catch (CertificateNotYetValidException cnyve) {
|
||||
_log.error("Rejecting X509 Certificate not yet valid: " + file.getAbsolutePath(), cnyve);
|
||||
return false;
|
||||
}
|
||||
ks.setCertificateEntry(alias, cert);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Now trusting X509 Certificate, Issuer: " + cert.getIssuerX500Principal());
|
||||
} catch (GeneralSecurityException gse) {
|
||||
_log.error("Error reading X509 Certificate: " + file.getAbsolutePath(), gse);
|
||||
return false;
|
||||
} catch (IOException ioe) {
|
||||
_log.error("Error reading X509 Certificate: " + file.getAbsolutePath(), ioe);
|
||||
return false;
|
||||
} finally {
|
||||
try { if (fis != null) fis.close(); } catch (IOException foo) {}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* From http://blogs.sun.com/andreas/resource/InstallCert.java
|
||||
@ -425,44 +309,12 @@ public class SSLEepGet extends EepGet {
|
||||
} catch (Exception e) {
|
||||
System.out.println(" WARNING: Certificate is not currently valid, it cannot be used");
|
||||
}
|
||||
saveCert(cert, new File(name));
|
||||
CertUtil.saveCert(cert, new File(name));
|
||||
}
|
||||
System.out.println("NOTE: To trust them, copy the certificate file(s) to the certificates directory and rerun without the -s option");
|
||||
System.out.println("NOTE: EepGet failed, certificate error follows:");
|
||||
}
|
||||
|
||||
private static final int LINE_LENGTH = 64;
|
||||
|
||||
/**
|
||||
* Modified from:
|
||||
* http://www.exampledepot.com/egs/java.security.cert/ExportCert.html
|
||||
*
|
||||
* This method writes a certificate to a file in base64 format.
|
||||
* @since 0.8.2
|
||||
*/
|
||||
private static void saveCert(Certificate cert, File file) {
|
||||
OutputStream os = null;
|
||||
try {
|
||||
// Get the encoded form which is suitable for exporting
|
||||
byte[] buf = cert.getEncoded();
|
||||
os = new FileOutputStream(file);
|
||||
PrintWriter wr = new PrintWriter(os);
|
||||
wr.println("-----BEGIN CERTIFICATE-----");
|
||||
String b64 = Base64.encode(buf, true); // true = use standard alphabet
|
||||
for (int i = 0; i < b64.length(); i += LINE_LENGTH) {
|
||||
wr.println(b64.substring(i, Math.min(i + LINE_LENGTH, b64.length())));
|
||||
}
|
||||
wr.println("-----END CERTIFICATE-----");
|
||||
wr.flush();
|
||||
} catch (CertificateEncodingException cee) {
|
||||
System.out.println("Error writing X509 Certificate " + file.getAbsolutePath() + ' ' + cee);
|
||||
} catch (IOException ioe) {
|
||||
System.out.println("Error writing X509 Certificate " + file.getAbsolutePath() + ' ' + ioe);
|
||||
} finally {
|
||||
try { if (os != null) os.close(); } catch (IOException foo) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An opaque class for the caller to pass to repeated instantiations of SSLEepGet.
|
||||
* @since 0.8.2
|
||||
@ -641,6 +493,8 @@ public class SSLEepGet extends EepGet {
|
||||
int port = 0;
|
||||
if ("https".equals(url.getProtocol())) {
|
||||
host = url.getHost();
|
||||
if (host.toLowerCase(Locale.US).endsWith(".i2p"))
|
||||
throw new MalformedURLException("I2P addresses unsupported");
|
||||
port = url.getPort();
|
||||
if (port == -1)
|
||||
port = 443;
|
||||
@ -649,7 +503,7 @@ public class SSLEepGet extends EepGet {
|
||||
else
|
||||
_proxy = SSLSocketFactory.getDefault().createSocket(host, port);
|
||||
} else {
|
||||
throw new IOException("Only https supported: " + _actualURL);
|
||||
throw new MalformedURLException("Only https supported: " + _actualURL);
|
||||
}
|
||||
// an MUE is an IOE
|
||||
//} catch (MalformedURLException mue) {
|
||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
||||
i2p (0.9.8-1) UNRELEASED; urgency=low
|
||||
|
||||
* New upstream 0.9.8
|
||||
|
||||
-- Kill Your TV <killyourtv@i2pmail.org> Mon, 30 Sep 2013 00:00:00 +0000
|
||||
|
||||
i2p (0.9.7.1-1) unstable; urgency=low
|
||||
|
||||
* New upstream version 0.9.7.1
|
||||
|
218
debian/patches/0001-path-substitution.patch
vendored
218
debian/patches/0001-path-substitution.patch
vendored
@ -71,10 +71,13 @@ Debian wrapper.config to try to prevent confusion.
|
||||
|
||||
# Priority at which to run the wrapper. See "man nice" for valid priorities.
|
||||
# nice is only used if a priority is specified.
|
||||
@@ -175,48 +166,6 @@
|
||||
# Workaround for Gentoo
|
||||
JAVABINARY=$(awk -F'=' '/^ *wrapper\.java\.command/{print $2}' "$WRAPPER_CONF")
|
||||
@@ -172,64 +163,6 @@
|
||||
exit 1
|
||||
fi
|
||||
|
||||
-# Workaround for Gentoo
|
||||
-JAVABINARY=$(awk -F'=' '/^ *wrapper\.java\.command/{print $2}' "$WRAPPER_CONF")
|
||||
-
|
||||
-if [ -e /etc/gentoo-release ]; then
|
||||
- if [ $JAVABINARY = java ]; then
|
||||
- if [ -x /etc/java-config-2/current-system-vm/bin/java ]; then
|
||||
@ -103,44 +106,54 @@ Debian wrapper.config to try to prevent confusion.
|
||||
- echo "**`gettext 'Failed to load the wrapper'`**"
|
||||
- case `uname -s` in
|
||||
- FreeBSD)
|
||||
- echo
|
||||
- echo "The wrapper requires libiconv to be on your system."
|
||||
- echo "It can be installed with pkg_add -r libiconv"
|
||||
- echo
|
||||
- exit 1
|
||||
- # We should never get here on recent versions of FreeBSD
|
||||
- if ! $(pkg_info -E 'libiconv*' > /dev/null 2>&1); then
|
||||
- echo
|
||||
- echo "The wrapper requires libiconv."
|
||||
- echo
|
||||
- echo "It can be installed with pkg_add -r libiconv"
|
||||
- echo
|
||||
- fi
|
||||
- ;;
|
||||
- *)
|
||||
- echo
|
||||
- unsupported
|
||||
- exit 1
|
||||
- ;;
|
||||
- esac
|
||||
- exit 1
|
||||
-}
|
||||
-
|
||||
-if $(which ldd > /dev/null 2>&1); then
|
||||
- # This should cover every *NIX other than OSX since OSX doesn't have ldd.
|
||||
- # OSX has otool. Is otool on every OSX installation? Is otool's output the same as ldd's?
|
||||
- # The wrapper we ship for OSX are for PPC and Intel, so maybe we don't need to worry about OSX?
|
||||
- if (ldd "$WRAPPER_CMD" |grep -q 'not found') > /dev/null 2>&1 || \
|
||||
- ! (ldd "$WRAPPER_CMD" > /dev/null 2>&1); then
|
||||
- failed
|
||||
- fi
|
||||
-fi
|
||||
-
|
||||
if [ -n "$FIXED_COMMAND" ]
|
||||
then
|
||||
COMMAND="$FIXED_COMMAND"
|
||||
@@ -928,9 +877,6 @@
|
||||
@@ -940,7 +873,7 @@
|
||||
|
||||
# The string passed to eval must handles spaces in paths correctly.
|
||||
COMMAND_LINE="$CMDNICE \"$WRAPPER_CMD\" \"$WRAPPER_CONF\" wrapper.syslog.ident=\"$APP_NAME\" wrapper.java.command=\"$JAVABINARY\" wrapper.pidfile=\"$PIDFILE\" wrapper.name=\"$APP_NAME\" wrapper.displayname=\"$APP_LONG_NAME\" $ANCHORPROP $STATUSPROP $COMMANDPROP $LOCKPROP $LOGPROP wrapper.script.version=3.5.20 $ADDITIONAL_PARA"
|
||||
eval $COMMAND_LINE
|
||||
- if [ "$?" -ne "0" ]; then
|
||||
- failed
|
||||
- fi
|
||||
- eval $COMMAND_LINE || failed
|
||||
+ eval $COMMAND_LINE
|
||||
else
|
||||
eval echo `gettext '$APP_LONG_NAME is already running.'`
|
||||
exit 1
|
||||
@@ -1054,9 +1000,6 @@
|
||||
# The string passed to eval must handles spaces in paths correctly.
|
||||
COMMAND_LINE="$CMDNICE \"$WRAPPER_CMD\" \"$WRAPPER_CONF\" wrapper.syslog.ident=\"$APP_NAME\" wrapper.java.command=\"$JAVABINARY\" wrapper.pidfile=\"$PIDFILE\" wrapper.name=\"$APP_NAME\" wrapper.displayname=\"$APP_LONG_NAME\" wrapper.daemonize=TRUE $ANCHORPROP $IGNOREPROP $STATUSPROP $COMMANDPROP $LOCKPROP $LOGPROP wrapper.script.version=3.5.20 $ADDITIONAL_PARA"
|
||||
eval $COMMAND_LINE
|
||||
- if [ "$?" -ne "0" ]; then
|
||||
- failed
|
||||
- fi
|
||||
else
|
||||
eval echo `gettext '$APP_LONG_NAME is already running.'`
|
||||
exit 1
|
||||
@@ -1793,7 +1736,7 @@
|
||||
@@ -997,7 +930,6 @@
|
||||
if [ "X$pid" = "X" ]
|
||||
then
|
||||
eval echo " `gettext 'WARNING: $APP_LONG_NAME may have failed to start.'`"
|
||||
- failed
|
||||
else
|
||||
eval echo ' running: PID:$pid'
|
||||
fi
|
||||
@@ -1800,7 +1732,7 @@
|
||||
}
|
||||
|
||||
showsetusermesg() {
|
||||
@ -149,7 +162,7 @@ Debian wrapper.config to try to prevent confusion.
|
||||
}
|
||||
|
||||
checkifstartingasroot() {
|
||||
@@ -1801,7 +1744,7 @@
|
||||
@@ -1808,7 +1740,7 @@
|
||||
echo "`gettext 'Running I2P as the root user is *not* recommended.'`"
|
||||
showsetusermesg
|
||||
echo
|
||||
@ -158,7 +171,7 @@ Debian wrapper.config to try to prevent confusion.
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
@@ -1866,24 +1809,10 @@
|
||||
@@ -1873,24 +1805,10 @@
|
||||
status
|
||||
;;
|
||||
|
||||
@ -327,66 +340,44 @@ Debian wrapper.config to try to prevent confusion.
|
||||
-
|
||||
--- a/installer/resources/locale/po/messages_de.po
|
||||
+++ b/installer/resources/locale/po/messages_de.po
|
||||
@@ -192,14 +192,14 @@
|
||||
@@ -192,15 +192,15 @@
|
||||
msgstr "Falls gestartet, fordere einen Java Thread dump an"
|
||||
|
||||
#: ../i2prouter:1788
|
||||
#: ../i2prouter:1803
|
||||
-msgid "Please edit i2prouter and set the variable RUN_AS_USER"
|
||||
-msgstr "Bitte bearbeite i2prouter und setze die Variable RUN_AS_USER"
|
||||
+msgid "Please edit /etc/default/i2p and set the variable RUN_AS_USER"
|
||||
+msgstr "Bitte bearbeite /etc/default/i2p und setze die Variable RUN_AS_USER"
|
||||
|
||||
#: ../i2prouter:1793
|
||||
#: ../i2prouter:1808
|
||||
msgid "Running I2P as the root user is *not* recommended."
|
||||
msgstr "I2P als root Benutzer auszuführen ist *nicht* empfehlenswert."
|
||||
|
||||
#: ../i2prouter:1796
|
||||
#: ../i2prouter:1811
|
||||
-msgid "To run as root anyway, edit i2prouter and set ALLOW_ROOT=true."
|
||||
+msgid "To run as root anyway, edit /etc/default/i2p and set ALLOW_ROOT=true."
|
||||
msgstr ""
|
||||
-"Um I2P trotzdem als root auszuführen bearbeite i2prouter und setze ALLOW_ROOT=true."
|
||||
+"Um I2P trotzdem als root auszuführen bearbeite /etc/default/i2p und setze ALLOW_ROOT=true."
|
||||
-"Um I2P trotzdem als root auszuführen bearbeite i2prouter und setze "
|
||||
+"Um I2P trotzdem als root auszuführen bearbeite /etc/default/i2p und setze "
|
||||
"ALLOW_ROOT=true."
|
||||
--- a/installer/resources/locale/po/messages_en.po
|
||||
+++ b/installer/resources/locale/po/messages_en.po
|
||||
@@ -185,7 +185,7 @@
|
||||
msgstr ""
|
||||
|
||||
#: ../i2prouter:1796
|
||||
#: ../i2prouter:1803
|
||||
-msgid "Please edit i2prouter and set the variable RUN_AS_USER"
|
||||
+msgid "Please edit /etc/defalt/i2p and set the variable RUN_AS_USER"
|
||||
+msgid "Please edit /etc/default/i2p and set the variable RUN_AS_USER"
|
||||
msgstr ""
|
||||
|
||||
#: ../i2prouter:1801
|
||||
#: ../i2prouter:1808
|
||||
@@ -193,5 +193,5 @@
|
||||
msgstr ""
|
||||
|
||||
#: ../i2prouter:1804
|
||||
#: ../i2prouter:1811
|
||||
-msgid "To run as root anyway, edit i2prouter and set ALLOW_ROOT=true."
|
||||
+msgid "To run as root anyway, edit /etc/default/i2p and set ALLOW_ROOT=true."
|
||||
msgstr ""
|
||||
--- a/installer/resources/locale/po/messages_fr.po
|
||||
+++ b/installer/resources/locale/po/messages_fr.po
|
||||
@@ -189,8 +189,8 @@
|
||||
msgstr "Request a Java thread dump if running."
|
||||
|
||||
#: ../i2prouter:1796
|
||||
-msgid "Please edit i2prouter and set the variable RUN_AS_USER"
|
||||
-msgstr "Veuillez éditer $0 et paramétrer la variable RUN_AS_USER"
|
||||
+msgid "Please edit /etc/default/i2p and set the variable RUN_AS_USER"
|
||||
+msgstr "Veuillez éditer /etc/default/i2p et paramétrer la variable RUN_AS_USER"
|
||||
|
||||
#: ../i2prouter:1801
|
||||
msgid "Running I2P as the root user is *not* recommended."
|
||||
@@ -198,7 +198,7 @@
|
||||
"Faire fonctionner I2P en tant qu'utilisateur root n'est *pas* recommandé."
|
||||
|
||||
#: ../i2prouter:1804
|
||||
-msgid "To run as root anyway, edit i2prouter and set ALLOW_ROOT=true."
|
||||
+msgid "To run as root anyway, edit /etc/default/i2p and set ALLOW_ROOT=true."
|
||||
msgstr ""
|
||||
-"Pour exécuter en tant que root de toute façon, éditer $0 et mettre "
|
||||
+"Pour exécuter en tant que root de toute façon, éditer /etc/default/i2p et mettre "
|
||||
"ALLOW_ROOT=true."
|
||||
--- a/installer/resources/locale/po/messages_it.po
|
||||
+++ b/installer/resources/locale/po/messages_it.po
|
||||
@@ -187,7 +187,7 @@
|
||||
@ -405,49 +396,6 @@ Debian wrapper.config to try to prevent confusion.
|
||||
-msgid "To run as root anyway, edit i2prouter and set ALLOW_ROOT=true."
|
||||
+msgid "To run as root anyway, edit /etc/default/i2p and set ALLOW_ROOT=true."
|
||||
msgstr ""
|
||||
--- a/installer/resources/locale/po/messages_ru.po
|
||||
+++ b/installer/resources/locale/po/messages_ru.po
|
||||
@@ -190,16 +190,16 @@
|
||||
msgstr "Запросить дамп нитей Java, если запущено."
|
||||
|
||||
#: ../i2prouter:1796
|
||||
-msgid "Please edit i2prouter and set the variable RUN_AS_USER"
|
||||
+msgid "Please edit /etc/default/i2p and set the variable RUN_AS_USER"
|
||||
msgstr ""
|
||||
-"Пожалуйста отредактируйте i2prouter и установите переменную RUN_AS_USER"
|
||||
+"Пожалуйста отредактируйте /etc/default/i2p и установите переменную RUN_AS_USER"
|
||||
|
||||
#: ../i2prouter:1801
|
||||
msgid "Running I2P as the root user is *not* recommended."
|
||||
msgstr "Запуск I2P от имени root НЕ рекомендовано."
|
||||
|
||||
#: ../i2prouter:1804
|
||||
-msgid "To run as root anyway, edit i2prouter and set ALLOW_ROOT=true."
|
||||
+msgid "To run as root anyway, edit /etc/default/i2p and set ALLOW_ROOT=true."
|
||||
msgstr ""
|
||||
-"Чтобы всё равно запустить из-под root, отредактируйте i2prouter и установите "
|
||||
+"Чтобы всё равно запустить из-под root, отредактируйте /etc/default/i2p и установите "
|
||||
"ALLOW_ROOT=true."
|
||||
--- a/installer/resources/locale/po/messages_sv.po
|
||||
+++ b/installer/resources/locale/po/messages_sv.po
|
||||
@@ -187,13 +187,13 @@
|
||||
msgstr "Fråga efter en Java thread dump vid drift."
|
||||
|
||||
#: ../i2prouter:1780
|
||||
-msgid "Please edit i2prouter and set the variable RUN_AS_USER"
|
||||
-msgstr "Var god ändra i2prouter och sätt variabeln RUN_AS_USER"
|
||||
+msgid "Please edit /etc/default/i2p and set the variable RUN_AS_USER"
|
||||
+msgstr "Var god ändra /etc/default/i2p och sätt variabeln RUN_AS_USER"
|
||||
|
||||
#: ../i2prouter:1785
|
||||
msgid "Running I2P as the root user is *not* recommended."
|
||||
msgstr "Att köra I2P som användare root är *inte* rekommenderat."
|
||||
|
||||
#: ../i2prouter:1788
|
||||
-msgid "To run as root anyway, edit i2prouter and set ALLOW_ROOT=true."
|
||||
-msgstr "För att köra som root iallafall, ändra i2prouter och sätt ALLOW_ROOT=true"
|
||||
+msgid "To run as root anyway, edit /etc/default/i2p and set ALLOW_ROOT=true."
|
||||
+msgstr "För att köra som root iallafall, ändra /etc/default/i2p och sätt ALLOW_ROOT=true"
|
||||
--- a/installer/resources/locale/po/messages_zh.po
|
||||
+++ b/installer/resources/locale/po/messages_zh.po
|
||||
@@ -187,13 +187,13 @@
|
||||
@ -530,3 +478,67 @@ Debian wrapper.config to try to prevent confusion.
|
||||
-"Para executar como root mesmo assim, editar o i2prouter e configurar a "
|
||||
+"Para executar como root mesmo assim, editar o /etc/default/i2p e configurar a "
|
||||
"variável ALLOW_ROOT=true."
|
||||
--- a/installer/resources/locale/po/messages_fr.po
|
||||
+++ b/installer/resources/locale/po/messages_fr.po
|
||||
@@ -187,13 +187,13 @@
|
||||
msgstr "Request a Java thread dump if running."
|
||||
|
||||
#: ../i2prouter:1796
|
||||
-msgid "Please edit i2prouter and set the variable RUN_AS_USER"
|
||||
-msgstr "Veuillez éditer i2prouter et paramétrer la variable RUN_AS_USER"
|
||||
+msgid "Please edit /etc/default/i2p and set the variable RUN_AS_USER"
|
||||
+msgstr "Veuillez éditer /etc/default/i2p et paramétrer la variable RUN_AS_USER"
|
||||
|
||||
#: ../i2prouter:1801
|
||||
msgid "Running I2P as the root user is *not* recommended."
|
||||
msgstr "Faire fonctionner I2P en tant qu'utilisateur root n'est *pas* recommandé."
|
||||
|
||||
#: ../i2prouter:1804
|
||||
-msgid "To run as root anyway, edit i2prouter and set ALLOW_ROOT=true."
|
||||
-msgstr "Pour exécuter en tant que root de toute façon, éditer i2prouter et mettre ALLOW_ROOT=true."
|
||||
+msgid "To run as root anyway, edit /etc/default/i2p and set ALLOW_ROOT=true."
|
||||
+msgstr "Pour exécuter en tant que root de toute façon, éditer /etc/default/i2p et mettre ALLOW_ROOT=true."
|
||||
--- a/installer/resources/locale/po/messages_ru.po
|
||||
+++ b/installer/resources/locale/po/messages_ru.po
|
||||
@@ -190,16 +190,16 @@
|
||||
msgstr "Запросить дамп нитей Java, если запущено."
|
||||
|
||||
#: ../i2prouter:1803
|
||||
-msgid "Please edit i2prouter and set the variable RUN_AS_USER"
|
||||
+msgid "Please edit /etc/default/i2p and set the variable RUN_AS_USER"
|
||||
msgstr ""
|
||||
-"Пожалуйста отредактируйте i2prouter и установите переменную RUN_AS_USER"
|
||||
+"Пожалуйста отредактируйте /etc/default/i2p и установите переменную RUN_AS_USER"
|
||||
|
||||
#: ../i2prouter:1808
|
||||
msgid "Running I2P as the root user is *not* recommended."
|
||||
msgstr "Запуск I2P от имени root НЕ рекомендовано."
|
||||
|
||||
#: ../i2prouter:1811
|
||||
-msgid "To run as root anyway, edit i2prouter and set ALLOW_ROOT=true."
|
||||
+msgid "To run as root anyway, edit /etc/default/i2p and set ALLOW_ROOT=true."
|
||||
msgstr ""
|
||||
-"Чтобы всё равно запустить из-под root, отредактируйте i2prouter и установите "
|
||||
+"Чтобы всё равно запустить из-под root, отредактируйте /etc/default/i2p и установите "
|
||||
"ALLOW_ROOT=true."
|
||||
--- a/installer/resources/locale/po/messages_sv.po
|
||||
+++ b/installer/resources/locale/po/messages_sv.po
|
||||
@@ -187,14 +187,14 @@
|
||||
msgstr "Fråga efter en Java thread dump vid drift."
|
||||
|
||||
#: ../i2prouter:1803
|
||||
-msgid "Please edit i2prouter and set the variable RUN_AS_USER"
|
||||
-msgstr "Var god ändra i2prouter och set variabeln RUN_AS_USER"
|
||||
+msgid "Please edit /etc/default/i2p and set the variable RUN_AS_USER"
|
||||
+msgstr "Var god ändra /etc/default/i2p och set variabeln RUN_AS_USER"
|
||||
|
||||
#: ../i2prouter:1808
|
||||
msgid "Running I2P as the root user is *not* recommended."
|
||||
msgstr "Att köra I2P som användare root är *inte* rekommenderat."
|
||||
|
||||
#: ../i2prouter:1811
|
||||
-msgid "To run as root anyway, edit i2prouter and set ALLOW_ROOT=true."
|
||||
+msgid "To run as root anyway, edit /etc/default/i2p and set ALLOW_ROOT=true."
|
||||
msgstr ""
|
||||
-"För att köra som root oavsett, ändra i2prouter och sätt ALLOW_ROOT=true"
|
||||
+"För att köra som root oavsett, ändra /etc/default/i2p och sätt ALLOW_ROOT=true"
|
||||
|
6
debian/patches/0002-jbigi-soname.patch
vendored
6
debian/patches/0002-jbigi-soname.patch
vendored
@ -15,8 +15,8 @@ a soname to shut lintian up.
|
||||
UNIXTYPE="linux"
|
||||
fi
|
||||
COMPILEFLAGS="-fPIC -Wall $CFLAGS"
|
||||
- INCLUDES="-I. -I../../jbigi/include -I$JAVA_HOME/include -I$JAVA_HOME/include/${UNIXTYPE}"
|
||||
+ INCLUDES="-I. -I./jbigi/include -I$JAVA_HOME/include -I$JAVA_HOME/include/${UNIXTYPE}"
|
||||
- INCLUDES="-I. -I../../jbigi/include -I$JAVA_HOME/include -I$JAVA_HOME/include/${UNIXTYPE} -I/usr/local/include"
|
||||
+ INCLUDES="-I. -I./jbigi/include -I$JAVA_HOME/include -I$JAVA_HOME/include/${UNIXTYPE} -I/usr/local/include"
|
||||
LINKFLAGS="-shared -Wl,-soname,libjbigi.so"
|
||||
LIBFILE="libjbigi.so";;
|
||||
*)
|
||||
@ -26,6 +26,6 @@ a soname to shut lintian up.
|
||||
rm -f jbigi.o $LIBFILE
|
||||
-$CC -c $COMPILEFLAGS $INCLUDES ../../jbigi/src/jbigi.c || exit 1
|
||||
+$CC -c $COMPILEFLAGS $INCLUDES ./jbigi/src/jbigi.c || exit 1
|
||||
$CC $LINKFLAGS $INCLUDES -o $LIBFILE jbigi.o $INCLUDELIBS $STATICLIBS || exit 1
|
||||
$CC $LINKFLAGS $INCLUDES -o $LIBFILE jbigi.o $INCLUDELIBS $STATICLIBS $LIBPATH || exit 1
|
||||
|
||||
exit 0
|
||||
|
37
debian/po/sv.po
vendored
37
debian/po/sv.po
vendored
@ -1,29 +1,30 @@
|
||||
# Swedish debconf translation
|
||||
# Copyright (C) 2011 The I2P Project
|
||||
# This file is distributed under the same license as the i2p package.
|
||||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
#
|
||||
# Translators:
|
||||
# Martin Svensson <digitalmannen@gmail.com>, 2011.
|
||||
# hottuna <i2p@robertfoss.se>, 2013
|
||||
# Martin Svensson <digitalmannen@gmail.com>, 2011
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: I2P\n"
|
||||
"Report-Msgid-Bugs-To: https://trac.i2p2.de/\n"
|
||||
"POT-Creation-Date: 2011-12-27 22:25+0000\n"
|
||||
"PO-Revision-Date: 2011-12-26 09:48+0000\n"
|
||||
"Last-Translator: Martin Svensson <digitalmannen@gmail.com>\n"
|
||||
"Language-Team: Swedish (Sweden) (http://www.transifex.net/projects/p/I2P/"
|
||||
"team/sv_SE/)\n"
|
||||
"PO-Revision-Date: 2013-09-22 05:00+0000\n"
|
||||
"Last-Translator: hottuna <i2p@robertfoss.se>\n"
|
||||
"Language-Team: Swedish (Sweden) (http://www.transifex.com/projects/p/I2P/"
|
||||
"language/sv_SE/)\n"
|
||||
"Language: sv_SE\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"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#. Type: boolean
|
||||
#. Description
|
||||
#: ../i2p.templates:2001
|
||||
msgid "Should the I2P router be started at boot?"
|
||||
msgstr "Skall I2P rutern startas vid uppstart?"
|
||||
msgstr "Ska I2P routern startas vid systemstart?"
|
||||
|
||||
#. Type: boolean
|
||||
#. Description
|
||||
@ -39,7 +40,7 @@ msgstr ""
|
||||
#. Description
|
||||
#: ../i2p.templates:3001
|
||||
msgid "I2P daemon user:"
|
||||
msgstr "Konto för I2P tjänsten:"
|
||||
msgstr "Användare för I2P tjänsten:"
|
||||
|
||||
#. Type: string
|
||||
#. Description
|
||||
@ -50,10 +51,10 @@ msgid ""
|
||||
"account name here. For example, if your previous I2P installation is at /"
|
||||
"home/user/i2p, you may enter 'user' here."
|
||||
msgstr ""
|
||||
"Som standard är I2P inställt för att köras under kontot i2psvc mär den körs "
|
||||
"som tjänst. För att använda ett **existerande** I2P profil, ange ett annat "
|
||||
"konto här. Exempelvis, om din tidigare I2P installation är /home/user/i2p så "
|
||||
"ange 'user' här."
|
||||
"Som standard är I2P inställt för att köras under användaren i2psvc när det "
|
||||
"körs som tjänst. För att använda ett **existerande** I2P profil, ange en "
|
||||
"annan användare här. Exempelvis, om din tidigare I2P installation är /home/"
|
||||
"user/i2p så ange 'user' här."
|
||||
|
||||
#. Type: string
|
||||
#. Description
|
||||
@ -63,19 +64,19 @@ msgid ""
|
||||
"here, the chosen username *MUST* already exist."
|
||||
msgstr ""
|
||||
"OBS! Viktigt: Om en annan användare än standard 'i2psvc' skrivs in här. "
|
||||
"\"MÅSTE\" det användarnamnet redan existera."
|
||||
"*MÅSTE* det användarnamnet redan existera."
|
||||
|
||||
#. Type: string
|
||||
#. Description
|
||||
#: ../i2p.templates:4001
|
||||
msgid "Memory that can be allocated to I2P:"
|
||||
msgstr "Minne som kan tilldelas I2P"
|
||||
msgstr "Minne som kan tilldelas I2P:"
|
||||
|
||||
#. Type: string
|
||||
#. Description
|
||||
#: ../i2p.templates:4001
|
||||
msgid "By default, I2P will only be allowed to use up to 128MB of RAM."
|
||||
msgstr "Som standard kommer I2P bara att använda 128MB RAM "
|
||||
msgstr "Som standard kommer I2P bara att använda up till 128MB RAM."
|
||||
|
||||
#. Type: string
|
||||
#. Description
|
||||
|
112
history.txt
112
history.txt
@ -1,5 +1,115 @@
|
||||
2013-10-06 zzz
|
||||
Prop from branch i2p.i2p.zzz.ecdsa:
|
||||
* Build:
|
||||
- Generate su3 file in release target
|
||||
- Add zzz's new RSA 4096 pubkey cert for updates
|
||||
- Fix checkcerts.sh
|
||||
* Console: Move advanced setting to HelperBase
|
||||
* DSAEngine changes:
|
||||
- Implement raw sign/verify for other SigTypes
|
||||
- Add sign/verify methods using Java keys
|
||||
* ECDSA Support:
|
||||
- Add ECConstants which looks for named curves and falls back to
|
||||
explicitly defining the curves
|
||||
- Add support for ECDSA to SigType, DSAEngine and KeyGenerator
|
||||
- Attempt to add BC as a Provider
|
||||
- genSpec: fallback to BC provider
|
||||
* EepGet:
|
||||
- Fix non-proxied PartialEepGet
|
||||
- Prevent non-proxied eepget for an I2P host
|
||||
* KeyGenerator changes:
|
||||
- Generate key pairs for all supported SigTypes
|
||||
- KeyPairGen: Catch ProviderException, fallback to BC provider
|
||||
- Add KeyGenerator main() tests
|
||||
* KeyRing and DirKeyRing added: simple backend for storing X.509 certs
|
||||
* KeyStoreUtil added:
|
||||
- Consolidate KeyStore code from SSLEepGet, I2CPSSLSocketFactory,
|
||||
SSLClientListenerRunner, and RouterConsoleRunner into new
|
||||
KeyStoreUtil and CertUtil classes in net.i2p.crypto (ticket #744)
|
||||
- Change default to RSA 2048 (ticket #1017)
|
||||
- Set file modes on written keys
|
||||
- Overwrite check in createKeys()
|
||||
- New getCert(), getKey()
|
||||
- Extend keygen max wait
|
||||
- Read back private key to verify after keygen
|
||||
- Validate cert after reading from file
|
||||
- Validate CN in cert
|
||||
- Specify cert signature algorithm when generating keys
|
||||
* NativeBigInteger: Tweak to prevent early context instantiation
|
||||
* RSA support added: constants, parameters, sig types, support in DSAEngine, KeyGenerator, SigUtil
|
||||
* SHA1Hash: Add no-arg constructor
|
||||
* SigType changes:
|
||||
- Add parameters (curve specs) to SigTypes
|
||||
- Add getHashInstance()
|
||||
- Add RSA, fix ECDSA
|
||||
- Renumber, rename, comment out types that are too short.
|
||||
* SigUtil added:
|
||||
- Converters from Java formats (ASN.1, X.509, PKCS#8)
|
||||
to I2P formats for Signatures and SigningKeys
|
||||
- Move ASN.1 converter from DSAEngine to SigUtil, generalize
|
||||
for variable length, add support for longer sequences,
|
||||
add more sanity checks, add more exceptions
|
||||
- Move I2P-to-Java DSA key conversion from DSAEngine to SigUtil
|
||||
- Add Java-to-I2P DSA key conversion
|
||||
- Add Java key import
|
||||
- New split() and combine() methods
|
||||
* SSLEepGet: Move all certificates to certificates/ssl, in preparation
|
||||
for other certificate uses by SU3File
|
||||
* SU3File changes:
|
||||
- Support all SigTypes
|
||||
- Implement keygen
|
||||
- Readahead to get sigtype on verify, as we need the hash type
|
||||
- Enum for content type
|
||||
- Add unknown content type, make default
|
||||
- Fix NPE if private key not found or sign fails
|
||||
- Store generated keys in keystore, and get private key from keystore
|
||||
for signing, in Java format
|
||||
- Use Java keys to sign and verify so we don't
|
||||
lose the key parameters in the conversion to I2P keys
|
||||
- Type checking of Java private key vs. type when signing
|
||||
- Use certs instead of public keys for verification
|
||||
- Fix arg processing
|
||||
- Improve validate-without-extract
|
||||
- New extract command
|
||||
- Change static fields to avoid early context init
|
||||
- Reduce PRNG buffer size for faster signing
|
||||
* Update: Preliminary work for su3 router updates:
|
||||
- New ROUTER_SIGNED_SU3 UpdateType
|
||||
- Add support for torrent and HTTP
|
||||
- Refactor UpdateRunners to return actual UpdateType
|
||||
- Deal with signed/su3 conflicts
|
||||
- Verify and extract su3 files.
|
||||
- Stub out support for clearnet su3 updating
|
||||
- New config for proxying news, separate from proxying update
|
||||
- PartialEepGet and SSLEepGet tweaks to support clearnet update
|
||||
- Remove proxy, key, and url config from /configupdate
|
||||
- More URI checks in UpdateRunner
|
||||
- Add https support for news fetch
|
||||
- Add su3 mime type
|
||||
- Reset found version in update loop so we don't fetch from
|
||||
the next host too.
|
||||
- Prevent NPE on version after SSL fetch
|
||||
|
||||
* 2013-10-02 0.9.8.1 released
|
||||
|
||||
2013-10-01 zzz
|
||||
* Startup: Fix rekeying on Windows (tickets #1056, 1057)
|
||||
|
||||
* 2013-09-30 0.9.8 released
|
||||
|
||||
2013-09-26 kytv
|
||||
* French, German, Russian, and Swedish translation updates from Transifex
|
||||
* Update geoip.txt based on Maxmind GeoLite Country database from 2013-09-03
|
||||
|
||||
2013-09-23 zzz
|
||||
* Console: Add /proof page which can copied to prove you run a router
|
||||
|
||||
2013-09-20 kytv
|
||||
* Chinese, French, German, Russian, and Swedish translation updates from
|
||||
Transifex
|
||||
|
||||
2013-09-17 zzz
|
||||
- Revert expl. default back to 2 hops, wait for next release
|
||||
* Revert expl. default back to 2 hops, wait for next release
|
||||
|
||||
2013-09-07 zzz
|
||||
* Crypto: Don't use "short exponent" on faster platforms.
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<info>
|
||||
<appname>i2p</appname>
|
||||
<appversion>0.9.7.1</appversion>
|
||||
<appversion>0.9.8.1</appversion>
|
||||
<authors>
|
||||
<author name="I2P" email="http://www.i2p2.de/"/>
|
||||
</authors>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user