diff --git a/apps/i2ptunnel/java/build.xml b/apps/i2ptunnel/java/build.xml index ea2197afd..831314688 100644 --- a/apps/i2ptunnel/java/build.xml +++ b/apps/i2ptunnel/java/build.xml @@ -56,7 +56,7 @@ debug="true" deprecation="on" source="${javac.version}" target="${javac.version}" destdir="./build/obj" includeAntRuntime="false" - classpath="../../../core/java/build/i2p.jar:build/i2ptunnel.jar:../../jetty/jettylib/jetty-i2p.jar:../../jetty/jettylib/jetty-xml.jar" > + classpath="../../../core/java/build/i2p.jar:build/i2ptunnel.jar:../../jetty/jettylib/jetty-i2p.jar:../../jetty/jettylib/jetty-util.jar:../../jetty/jettylib/jetty-xml.jar" > @@ -318,7 +318,6 @@ - @@ -353,8 +352,8 @@ - + diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java index b5c129df3..27aac4db3 100644 --- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java +++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/IndexBean.java @@ -134,8 +134,11 @@ public class IndexBean { } } - /** do we know this nonce? @since 0.8.1 */ - private static boolean haveNonce(String nonce) { + /** + * do we know this nonce? + * @since 0.8.1 public since 0.9.35 + */ + public static boolean haveNonce(String nonce) { synchronized (_nonces) { return _nonces.contains(nonce); } diff --git a/apps/i2ptunnel/jsp/ssl.jsp b/apps/i2ptunnel/jsp/ssl.jsp index 40abbfab5..260781f5f 100644 --- a/apps/i2ptunnel/jsp/ssl.jsp +++ b/apps/i2ptunnel/jsp/ssl.jsp @@ -100,6 +100,111 @@ input.default { width: 1px; height: 1px; visibility: hidden; } if (name == null || name.equals("")) name = editBean.getTunnelName(curTunnel); if (!"new".equals(tunnelType)) { + // POST handling + String action = request.getParameter("action"); + if (action != null) { + String nonce = request.getParameter("nonce"); + String newpw = request.getParameter("nofilter_keyPassword"); + String appNum = request.getParameter("clientAppNumber"); + String ksPath = request.getParameter("nofilter_ksPath"); + String jettySSLConfigPath = request.getParameter("nofilter_jettySSLFile"); + if (newpw != null) { + newpw = newpw.trim(); + if (newpw.length() <= 0) + newpw = null; + } + if (!editBean.haveNonce(nonce)) { + out.println(intl._t("Invalid form submission, probably because you used the 'back' or 'reload' button on your browser. Please resubmit.") + + ' ' + + intl._t("If the problem persists, verify that you have cookies enabled in your browser.")); + } else if (!action.equals("Generate")) { + out.println("Unknown form action"); + } else if (newpw == null) { + out.println("Password required"); + } else if (appNum == null || ksPath == null || jettySSLConfigPath == null) { + out.println("Missing parameters"); + } else if (b32.length() <= 0) { + out.println("No destination set - start tunnel first"); + } else if (name == null || !name.endsWith(".i2p")) { + out.println("No hostname set - go back and configure"); + } else { + boolean ok = true; + + // generate selfsigned cert + java.util.Set altNames = new java.util.HashSet(4); + altNames.add(b32); + altNames.add(name); + if (!name.startsWith("www.")) + altNames.add("www." + name); + if (altb32 != null && altb32.length() > 0) + altNames.add(altb32); + File ks = new File(ksPath); + ok = net.i2p.crypto.KeyStoreUtil.createKeys(ks, "eepsite", name, altNames, b32, newpw); + if (ok) { + out.println("Created selfsigned cert"); + } + + // rewrite jetty-ssl.xml + if (ok) { + String obf = org.eclipse.jetty.util.security.Password.obfuscate(newpw); + File f = new File(jettySSLConfigPath); + try { + org.eclipse.jetty.xml.XmlParser.Node root; + root = net.i2p.jetty.JettyXmlConfigurationParser.parse(f); + //JettyXmlConfigurationParser.setValue(root, "KeyStorePassword", ...); + JettyXmlConfigurationParser.setValue(root, "KeyManagerPassword", obf); + JettyXmlConfigurationParser.setValue(root, "TrustStorePassword", obf); + File fb = new File(jettySSLConfigPath + ".bkup"); + if (fb.exists()) + fb = new File(jettySSLConfigPath + '-' + System.currentTimeMillis() + ".bkup"); + ok = net.i2p.util.FileUtil.copy(f, fb, false, true); + if (ok) { + java.io.Writer w = null; + try { + w = new java.io.OutputStreamWriter(new net.i2p.util.SecureFileOutputStream(f), "UTF-8"); + w.write(root.toString()); + } catch (java.io.IOException ioe) { + ioe.printStackTrace(); + ok = false; + } finally { + if (w != null) try { w.close(); } catch (java.io.IOException ioe2) {} + } + } + } catch (org.xml.sax.SAXException saxe) { + saxe.printStackTrace(); + out.println(DataHelper.escapeHTML(saxe.getMessage())); + ok = false; + } + } + + // rewrite clients.config + boolean isSSLEnabled = Boolean.parseBoolean(request.getParameter("isSSLEnabled")); + if (ok && !isSSLEnabled) { + } + + // stop and restart jetty + + // stop tunnel + if (ok) { + + } + + // rewrite i2ptunnel.config + if (ok) { + + } + + // restart tunnel + if (ok) { + + } + + if (ok) { + out.println(intl. _t("Configuration changes saved")); + } + } + } + %>
@@ -374,6 +479,10 @@ input.default { width: 1px; height: 1px; visibility: hidden; } } // isPWDefault %> <%=intl._t("Password")%>: + + + + " value="" class="freetext password" /> diff --git a/apps/jetty/java/src/net/i2p/jetty/JettyXmlConfigurationParser.java b/apps/jetty/java/src/net/i2p/jetty/JettyXmlConfigurationParser.java index 3dd5a0104..ee44462d7 100644 --- a/apps/jetty/java/src/net/i2p/jetty/JettyXmlConfigurationParser.java +++ b/apps/jetty/java/src/net/i2p/jetty/JettyXmlConfigurationParser.java @@ -120,6 +120,12 @@ public class JettyXmlConfigurationParser if (aname != null && aname.toLowerCase(Locale.US).equals(nameLC)) { // Node doesn't support set() or remove() but it does have clear() n.clear(); + // work around bug in XmlParser.Node.add(int, Object) + // where it will AIOOBE when calling add(String) after clear() after add(String) + // because the _lastString field isn't reset to false + // so we need to add a non-String object and then clear again. + n.add(Integer.valueOf(0)); + n.clear(); n.add(value); return true; }