diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java index c73589e60..63df4acce 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java @@ -1163,7 +1163,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn Boolean.parseBoolean(getTunnel().getClientOptions().getProperty(PROP_DISABLE_HELPER))) { out.write(ERR_HELPER_DISABLED.getBytes("UTF-8")); } else { - LocalHTTPServer.serveLocalFile(out, method, internalPath, internalRawQuery, _proxyNonce); + LocalHTTPServer.serveLocalFile(_context, sockMgr, out, method, internalPath, internalRawQuery, _proxyNonce); } } catch (IOException ioe) { // ignore @@ -1267,26 +1267,13 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn if (code != LookupResult.RESULT_SUCCESS) { if (_log.shouldWarn()) _log.warn("Unable to resolve b33 " + destination + " error code " + code); - // TODO new form to supply missing data if (code != LookupResult.RESULT_FAILURE) { - String header = getErrorPage("b32", ERR_DESTINATION_UNKNOWN); - String msg; - if (code == LookupResult.RESULT_SECRET_REQUIRED) - msg = "b32 address requires lookup password"; - else if (code == LookupResult.RESULT_KEY_REQUIRED) - msg = "b32 address requires encryption key"; - else if (code == LookupResult.RESULT_SECRET_AND_KEY_REQUIRED) - msg = "b32 address requires encryption key and lookup password"; - else if (code == LookupResult.RESULT_DECRYPTION_FAILURE) - msg = "b32 address decryption failure, check encryption key"; - else - msg = "lookup failure code " + code; - try { - writeErrorMessage(header, msg, out, targetRequest, false, destination); - } catch (IOException ioe) {} + // form to supply missing data + writeB32SaveForm(out, destination, code, targetRequest); return; } + // fall through to standard destination unreachable error page } } } else { @@ -1504,6 +1491,63 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn writeFooter(out); } + /** @since 0.9.43 */ + private void writeB32SaveForm(OutputStream outs, String destination, int code, + String targetRequest) throws IOException { + if(outs == null) + return; + Writer out = new BufferedWriter(new OutputStreamWriter(outs, "UTF-8")); + String header = getErrorPage("b32", ERR_DESTINATION_UNKNOWN); + out.write(header); + out.write("
| " + _t("Host") + + " | " + destination + " |
| " + _t("Base 32") + " | " + + "" + destination + " |
" + msg + "
"); + out.write("\n\n"); + writeFooter(out); + } + /** * Read the first line unbuffered. * After that, switch to a BufferedReader, unless the method is "POST". diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java index c8146c97d..a123701a6 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/localServer/LocalHTTPServer.java @@ -12,10 +12,21 @@ import java.util.Properties; import java.util.StringTokenizer; import net.i2p.I2PAppContext; +import net.i2p.client.I2PSession; +import net.i2p.client.I2PSessionException; import net.i2p.client.naming.NamingService; +import net.i2p.client.streaming.I2PSocketManager; +import net.i2p.crypto.Blinding; +import net.i2p.crypto.EncType; +import net.i2p.crypto.KeyPair; +import net.i2p.crypto.SigType; +import net.i2p.data.Base64; +import net.i2p.data.BlindData; import net.i2p.data.DataFormatException; import net.i2p.data.DataHelper; import net.i2p.data.Destination; +import net.i2p.data.PrivateKey; +import net.i2p.data.SigningPublicKey; import net.i2p.i2ptunnel.I2PTunnelHTTPClient; import net.i2p.util.FileUtil; import net.i2p.util.PortMapper; @@ -51,6 +62,14 @@ public abstract class LocalHTTPServer { "\r\n"+ "Add to addressbook failed - bad parameters"; + private final static String ERR_B32 = + "HTTP/1.1 409 Bad\r\n"+ + "Content-Type: text/plain\r\n"+ + "Connection: close\r\n"+ + "Proxy-Connection: close\r\n"+ + "\r\n"+ + "B32 update failed - bad parameters"; + private final static String OK = "HTTP/1.1 200 OK\r\n" + "Content-Type: text/plain\r\n" + @@ -79,10 +98,12 @@ public abstract class LocalHTTPServer { * uncaught vulnerabilities. * Restrict to the /themes/ directory for now. * + * @param sockMgr only for /b32, otherwise ignored * @param targetRequest decoded path only, non-null * @param query raw (encoded), may be null */ - public static void serveLocalFile(OutputStream out, String method, String targetRequest, + public static void serveLocalFile(I2PAppContext context, I2PSocketManager sockMgr, + OutputStream out, String method, String targetRequest, String query, String proxyNonce) throws IOException { //System.err.println("targetRequest: \"" + targetRequest + "\""); // a home page message for the curious... @@ -102,8 +123,8 @@ public abstract class LocalHTTPServer { } // theme hack if (filename.startsWith("console/default/")) - filename = filename.replaceFirst("default", I2PAppContext.getGlobalContext().getProperty("routerconsole.theme", "light")); - File themesDir = new File(I2PAppContext.getGlobalContext().getBaseDir(), "docs/themes"); + filename = filename.replaceFirst("default", context.getProperty("routerconsole.theme", "light")); + File themesDir = new File(context.getBaseDir(), "docs/themes"); File file = new File(themesDir, filename); if (file.exists() && !file.isDirectory()) { String type; @@ -167,7 +188,7 @@ public abstract class LocalHTTPServer { //System.err.println("book : \"" + book + "\""); //System.err.println("nonce : \"" + nonce + "\""); if (proxyNonce.equals(nonce) && url != null && host != null && dest != null) { - NamingService ns = I2PAppContext.getGlobalContext().namingService(); + NamingService ns = context.namingService(); Properties nsOptions = new Properties(); nsOptions.setProperty("list", book); if (referer != null && referer.startsWith("http")) { @@ -182,6 +203,88 @@ public abstract class LocalHTTPServer { return; } out.write(ERR_ADD.getBytes("UTF-8")); + + } else if (targetRequest.equals("/b32")) { + // Send a blinding info message (form submit) + // Parameters are url, host, dest, nonce, and master | router | private. + // Do the add and redirect. + if (query == null) { + out.write(ERR_ADD.getBytes("UTF-8")); + return; + } + Map