Port Forwarding Support is: |
- #[portForwardingEnabled]# |
+ #[portForwarding.Enabled]# |
+
+ Port Forwarding Method: |
+ #[portForwarding.Type]#
+ |
|
+Secure channel specific settings: |
Port Forwarding Port: |
- #[portForwardingPort]# |
+ #[portForwarding.sch.Port]# |
Port Forwarding Host: |
- #[portForwardingHostUser]#@#[portForwardingHost]#:#[portForwardingHostPort]# |
+ #[portForwarding.sch.HostUser]#@#[portForwarding.sch.Host]#:#[portForwarding.sch.HostPort]# |
Port Forwarding uses proxy: |
- #[portForwardingUseProxy]# |
+ #[portForwarding.sch.UseProxy]# |
::
diff --git a/htroot/SettingsAck_p.java b/htroot/SettingsAck_p.java
index f6c085336..4365912a7 100644
--- a/htroot/SettingsAck_p.java
+++ b/htroot/SettingsAck_p.java
@@ -244,14 +244,15 @@ public class SettingsAck_p {
// port forwarding configuration
if (post.containsKey("portForwarding")) {
- env.setConfig("portForwardingEnabled", post.containsKey("portForwardingEnabled")?"true":"false");
- env.setConfig("portForwardingUseProxy",post.containsKey("portForwardingUseProxy")?"true":"false");
- env.setConfig("portForwardingPort", (String)post.get("portForwardingPort"));
-
- env.setConfig("portForwardingHost", (String)post.get("portForwardingHost"));
- env.setConfig("portForwardingHostPort",(String)post.get("portForwardingHostPort"));
- env.setConfig("portForwardingHostUser",(String)post.get("portForwardingHostUser"));
- env.setConfig("portForwardingHostPwd", (String)post.get("portForwardingHostPwd"));
+ env.setConfig("portForwarding.Enabled", post.containsKey("portForwarding.Enabled")?"true":"false");
+ env.setConfig("portForwarding.Type", (String)post.get("portForwarding.Type"));
+
+ env.setConfig("portForwarding.sch.UseProxy",post.containsKey("portForwarding.sch.UseProxy")?"true":"false");
+ env.setConfig("portForwarding.sch.Port", (String)post.get("portForwarding.sch.Port"));
+ env.setConfig("portForwarding.sch.Host", (String)post.get("portForwarding.sch.Host"));
+ env.setConfig("portForwarding.sch.HostPort",(String)post.get("portForwarding.sch.HostPort"));
+ env.setConfig("portForwarding.sch.HostUser",(String)post.get("portForwarding.sch.HostUser"));
+ env.setConfig("portForwarding.sch.HostPwd", (String)post.get("portForwarding.sch.HostPwd"));
// trying to reconnect the port forwarding channel
try {
@@ -273,13 +274,15 @@ public class SettingsAck_p {
}
prop.put("info", 22);
- prop.put("info_portForwardingEnabled", post.containsKey("portForwardingEnabled")?"on":"off");
- prop.put("info_portForwardingUseProxy",post.containsKey("portForwardingUseProxy")?"on":"off");
- prop.put("info_portForwardingPort", (String)post.get("portForwardingPort"));
- prop.put("info_portForwardingHost", (String)post.get("portForwardingHost"));
- prop.put("info_portForwardingHostPort",(String)post.get("portForwardingHostPort"));
- prop.put("info_portForwardingHostUser",(String)post.get("portForwardingHostUser"));
- prop.put("info_portForwardingHostPwd", (String)post.get("portForwardingHostPwd"));
+ prop.put("info_portForwarding.Enabled", post.containsKey("portForwarding.Enabled")?"on":"off");
+ prop.put("info_portForwarding.Type", (String)post.get("portForwarding.Type"));
+
+ prop.put("info_portForwarding.sch.UseProxy",post.containsKey("portForwarding.sch.UseProxy")?"on":"off");
+ prop.put("info_portForwarding.sch.Port", (String)post.get("portForwarding.sch.Port"));
+ prop.put("info_portForwarding.sch.Host", (String)post.get("portForwarding.sch.Host"));
+ prop.put("info_portForwarding.sch.HostPort",(String)post.get("portForwarding.sch.HostPort"));
+ prop.put("info_portForwarding.sch.HostUser",(String)post.get("portForwarding.sch.HostUser"));
+ prop.put("info_portForwarding.sch.HostPwd", (String)post.get("portForwarding.sch.HostPwd"));
return prop;
}
diff --git a/htroot/Settings_PortForwarding.inc b/htroot/Settings_PortForwarding.inc
index e41906db1..2dc3aa009 100644
--- a/htroot/Settings_PortForwarding.inc
+++ b/htroot/Settings_PortForwarding.inc
@@ -3,46 +3,60 @@
You can use a remote server running a ssh demon to forward your server/proxy port.
This is useful if you want to tunnel throug a NAT/router.
Alternatively, you can simply set a virtual server port on your NAT/Server to enable connections from outside.
-#(portForwardingAvailable)#
diff --git a/htroot/Settings_p.java b/htroot/Settings_p.java
index 3be190403..7209e12c2 100644
--- a/htroot/Settings_p.java
+++ b/htroot/Settings_p.java
@@ -53,8 +53,10 @@ import de.anomic.plasma.plasmaParser;
import de.anomic.plasma.plasmaParserConfig;
import de.anomic.plasma.plasmaSwitchboard;
import de.anomic.plasma.parser.ParserInfo;
+import de.anomic.server.serverCore;
import de.anomic.server.serverObjects;
import de.anomic.server.serverSwitch;
+import de.anomic.server.portForwarding.serverPortForwarding;
import de.anomic.yacy.yacyCore;
import de.anomic.yacy.yacySeedUploader;
@@ -120,22 +122,34 @@ public final class Settings_p {
prop.put("proxy.sendXForwardedForHeader", env.getConfig("proxy.sendXForwardedForHeader", "true").equals("true") ? 1 : 0);
// remote port forwarding settings
+ String[] forwardingMethods = new String[]{"sch","upnp"};
+ String currentForwarder = env.getConfig("portForwarding.Type", "none");
boolean portForwardingAvailable = false;
- try {
- Class.forName("de.anomic.server.serverPortForwardingSch");
- portForwardingAvailable = true;
- } catch (Exception e) {
- } catch (Error e) {}
-
- prop.put("portForwardingAvailable",portForwardingAvailable? 1:0);
- prop.put("portForwardingEnabled",env.getConfig("portForwardingEnabled","false").equals("true")? 1 : 0);
- prop.put("portForwardingUseProxy",env.getConfig("portForwardingUseProxy", "false").equals("true")? 1 : 0);
- prop.put("portForwardingPort",env.getConfig("portForwardingPort", ""));
-
- prop.put("portForwardingHost",env.getConfig("portForwardingHost", ""));
- prop.put("portForwardingHostPort",env.getConfig("portForwardingHostPort", ""));
- prop.put("portForwardingHostUser",env.getConfig("portForwardingHostUser", ""));
- prop.put("portForwardingHostPwd",env.getConfig("portForwardingHostPwd", ""));
+ int methodCount = 0;
+
+ for (int i=0; i < forwardingMethods.length; i++) {
+ try {
+ Class forwarder = Class.forName(env.getConfig("portForwarding." + forwardingMethods[i],""));
+ prop.put("forwardingMethods_" + methodCount + "_name",forwardingMethods[i]);
+ prop.put("forwardingMethods_" + methodCount + "_selected", forwardingMethods[i].equals(currentForwarder)?1:0);
+ methodCount++;
+ } catch (Exception e) {
+ } catch (Error e) {}
+ }
+ prop.put("forwardingMethods",methodCount);
+
+ if (methodCount > 0) portForwardingAvailable = true;
+
+ prop.put("portForwarding.Type",currentForwarder);
+ prop.put("portForwarding.Available",portForwardingAvailable? 1:0);
+ prop.put("portForwarding.Enabled",env.getConfig("portForwarding.Enabled","false").equals("true")? 1 : 0);
+
+ prop.put("portForwarding.sch.UseProxy",env.getConfig("portForwarding.sch.UseProxy", "false").equals("true")? 1 : 0);
+ prop.put("portForwarding.sch.Port",env.getConfig("portForwarding.sch.Port", ""));
+ prop.put("portForwarding.sch.Host",env.getConfig("portForwarding.sch.Host", ""));
+ prop.put("portForwarding.sch.HostPort",env.getConfig("portForwarding.sch.HostPort", ""));
+ prop.put("portForwarding.sch.HostUser",env.getConfig("portForwarding.sch.HostUser", ""));
+ prop.put("portForwarding.sch.HostPwd",env.getConfig("portForwarding.sch.HostPwd", ""));
// set values
String s;
diff --git a/libx/commons-jxpath-1.1.jar b/libx/commons-jxpath-1.1.jar
new file mode 100644
index 000000000..9516e2ad6
Binary files /dev/null and b/libx/commons-jxpath-1.1.jar differ
diff --git a/libx/sbbi-upnplib-1.0.3.jar b/libx/sbbi-upnplib-1.0.3.jar
new file mode 100644
index 000000000..32f07d59e
Binary files /dev/null and b/libx/sbbi-upnplib-1.0.3.jar differ
diff --git a/source/de/anomic/http/httpHeader.java b/source/de/anomic/http/httpHeader.java
index dda7344c2..25082cfad 100644
--- a/source/de/anomic/http/httpHeader.java
+++ b/source/de/anomic/http/httpHeader.java
@@ -769,6 +769,7 @@ public final class httpHeader extends TreeMap implements Map {
// and therefor was set to virtualHost by function parseQuery()
if (!prop.getProperty(CONNECTION_PROP_HOST).equals(virtualHost)) return;
+ // TODO: we could have problems with connections from extern here ...
String dstHostSocket = (String) header.get(httpHeader.HOST);
prop.setProperty(CONNECTION_PROP_HOST,(httpd.isThisHostName(dstHostSocket)?virtualHost:dstHostSocket));
}
diff --git a/source/de/anomic/server/portForwarding/sch/serverPortForwardingSch.java b/source/de/anomic/server/portForwarding/sch/serverPortForwardingSch.java
new file mode 100644
index 000000000..ee9d817ae
--- /dev/null
+++ b/source/de/anomic/server/portForwarding/sch/serverPortForwardingSch.java
@@ -0,0 +1,321 @@
+// serverPortForwardingSch.java
+// -------------------------------------
+// part of YACY
+// (C) by Michael Peter Christen; mc@anomic.de
+// first published on http://www.anomic.de
+// Frankfurt, Germany, 2004
+//
+// This file ist contributed by Martin Thelian
+//
+// $LastChangedDate: 2006-02-20 23:57:42 +0100 (Mo, 20 Feb 2006) $
+// $LastChangedRevision: 1715 $
+// $LastChangedBy: borg-0300 $
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// Using this software in any meaning (reading, learning, copying, compiling,
+// running) means that you agree that the Author(s) is (are) not responsible
+// for cost, loss of data or any harm that may be caused directly or indirectly
+// by usage of this softare or this documentation. The usage of this software
+// is on your own risk. The installation and usage (starting/running) of this
+// software may allow other people or application to access your computer and
+// any attached devices and is highly dependent on the configuration of the
+// software which must be done by the user of the software; the author(s) is
+// (are) also not responsible for proper configuration and usage of the
+// software, even if provoked by documentation provided together with
+// the software.
+//
+// Any changes to this file according to the GPL as documented in the file
+// gpl.txt aside this file in the shipment you received can be done to the
+// lines that follows this copyright notice here, but changes must not be
+// done inside the copyright notive above. A re-distribution must contain
+// the intact and unchanged copyright notice.
+// Contributions and changes to the program code must be marked as such.
+
+package de.anomic.server.portForwarding.sch;
+
+import java.io.IOException;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.ProxyHTTP;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.UIKeyboardInteractive;
+import com.jcraft.jsch.UserInfo;
+
+import de.anomic.server.serverInstantThread;
+import de.anomic.server.serverSwitch;
+import de.anomic.server.logging.serverLog;
+import de.anomic.server.portForwarding.serverPortForwarding;
+import de.anomic.yacy.yacyClient;
+import de.anomic.yacy.yacyCore;
+
+public class serverPortForwardingSch implements serverPortForwarding{
+
+ /* ========================================================================
+ * Constants needed to read properties from the configuration file
+ * ======================================================================== */
+ public static final String FORWARDING_HOST = "portForwarding.sch.Host";
+ public static final String FORWARDING_HOST_PORT = "portForwarding.sch.HostPort";
+ public static final String FORWARDING_HOST_USER = "portForwarding.sch.HostUser";
+ public static final String FORWARDING_HOST_PWD = "portForwarding.sch.HostPwd";
+
+ public static final String FORWARDING_PORT = "portForwarding.sch.Port";
+ public static final String FORWARDING_USE_PROXY = "portForwarding.sch.UseProxy";
+
+
+ /* ========================================================================
+ * Other object fields
+ * ======================================================================== */
+ private serverSwitch switchboard;
+
+ private String forwardingHost;
+ private int forwardingHostPort;
+ private String forwardingHostUser;
+ private String forwardingHostPwd;
+
+ private int forwardingPort;
+ private boolean useProxy;
+
+ private String remoteProxyHost;
+ private int remoteProxyPort;
+
+ private String localHost;
+ private int localHostPort;
+
+ private static Session session;
+ private static serverInstantThread sessionWatcher;
+
+ private serverLog log;
+
+ public serverPortForwardingSch() {
+ super();
+ this.log = new serverLog("PORT_FORWARDING_SCH");
+ }
+
+ public void init(
+ serverSwitch switchboard,
+ String localHost,
+ int localPort
+ ) throws Exception {
+ try {
+ this.log.logFine("Initializing port forwarding via sch ...");
+
+ this.switchboard = switchboard;
+
+ this.forwardingHost = switchboard.getConfig(FORWARDING_HOST,"localhost");
+ this.forwardingHostPort = Integer.valueOf(switchboard.getConfig(FORWARDING_HOST_PORT,"8080")).intValue();
+ this.forwardingHostUser = switchboard.getConfig(FORWARDING_HOST_USER,"xxx");
+ this.forwardingHostPwd = switchboard.getConfig(FORWARDING_HOST_PWD,"xxx");
+
+ this.forwardingPort = Integer.valueOf(switchboard.getConfig(FORWARDING_PORT,"8080")).intValue();
+ this.useProxy = Boolean.valueOf(switchboard.getConfig(FORWARDING_USE_PROXY,"false")).booleanValue();
+
+ this.localHost = localHost;
+ this.localHostPort = localPort;
+
+ // load remote proxy data
+ this.remoteProxyHost = switchboard.getConfig("remoteProxyHost","");
+ try {
+ this.remoteProxyPort = Integer.parseInt(switchboard.getConfig("remoteProxyPort","3128"));
+ } catch (NumberFormatException e) {
+ remoteProxyPort = 3128;
+ }
+
+ // checking if all needed libs are availalbe
+ String javaClassPath = System.getProperty("java.class.path");
+ if (javaClassPath.indexOf("jsch") == -1) {
+ throw new IllegalStateException("Missing library.");
+ }
+ } catch (Exception e) {
+ this.log.logSevere("Unable to initialize port forwarding.",e);
+ throw e;
+ }
+ }
+
+ public String getHost() {
+ return this.forwardingHost;
+ }
+
+ public int getPort() {
+ return this.forwardingPort;
+ }
+
+ public synchronized void connect() throws IOException {
+ try{
+ if ((session != null) && (session.isConnected()))
+ throw new IOException("Session already connected");
+
+ this.log.logInfo("Trying to connect to remote port forwarding host " + this.forwardingHostUser + "@" + this.forwardingHost + ":" + this.forwardingHostPort);
+
+ JSch jsch=new JSch();
+ session=jsch.getSession(this.forwardingHostUser, this.forwardingHost, this.forwardingHostPort);
+ session.setPassword(this.forwardingHostPwd);
+
+ /*
+ * Setting the StrictHostKeyChecking to ignore unknown
+ * hosts because of a missing known_hosts file ...
+ */
+ java.util.Properties config = new java.util.Properties();
+ config.put("StrictHostKeyChecking","no");
+ session.setConfig(config);
+
+ // setting the proxy that should be used
+ if (this.useProxy) {
+ session.setProxy(new ProxyHTTP(this.remoteProxyHost, this.remoteProxyPort));
+ }
+
+ // username and password will be given via UserInfo interface.
+ UserInfo ui= new MyUserInfo(this.forwardingHostPwd);
+ session.setUserInfo(ui);
+
+ // trying to connect ...
+ session.connect();
+
+ // activating remote port forwarding
+ session.setPortForwardingR(this.forwardingPort, this.localHost, this.localHostPort);
+
+ // using a timer task to control if the session remains open
+ if (sessionWatcher == null) {
+ this.log.logFine("Deploying port forwarding session watcher thread.");
+ this.switchboard.deployThread("portForwardingWatcher", "Remote Port Forwarding Watcher", "this thread is used to detect broken connections and to re-establish it if necessary.", null,
+ sessionWatcher = new serverInstantThread(this, "reconnect", null), 30000,30000,30000,1000);
+ sessionWatcher.setSyncObject(new Object());
+ }
+
+ this.log.logInfo("Remote port forwarding connection established: " +
+ this.forwardingHost+ ":" + this.forwardingPort + " -> " +
+ this.localHost + ":" + this.localHostPort);
+ }
+ catch(Exception e){
+ this.log.logSevere("Unable to connect to remote port forwarding host.",e);
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public synchronized boolean reconnect() throws IOException {
+ if ((!this.isConnected()) && (!Thread.currentThread().isInterrupted())) {
+ this.log.logFine("Trying to reconnect to port forwarding host.");
+ this.disconnect();
+ this.connect();
+ return this.isConnected();
+ }
+ return false;
+ }
+
+ public synchronized void disconnect() throws IOException {
+ if (session == null) throw new IOException("No connection established.");
+
+ // terminating port watcher thread
+ this.log.logFine("Terminating port forwarding session watcher thread.");
+ this.switchboard.terminateThread("portForwardingWatcher",true);
+ sessionWatcher = null;
+
+ // disconnection the session
+ try {
+ session.disconnect();
+ this.log.logFine("Successfully disconnected from port forwarding host.");
+ } catch (Exception e) {
+ this.log.logSevere("Error while trying to disconnect from port forwarding host.",e);
+ throw new IOException(e.getMessage());
+ }
+ }
+
+ public synchronized boolean isConnected() {
+ if (session == null) return false;
+ if (!session.isConnected()) return false;
+ int urls = yacyClient.queryUrlCount(yacyCore.seedDB.mySeed);
+ return !(urls < 0);
+ }
+
+ class MyUserInfo
+ implements UserInfo, UIKeyboardInteractive {
+ String passwd;
+
+ public MyUserInfo(String password) {
+ this.passwd = password;
+ }
+
+ public String getPassword() {
+ return this.passwd;
+ }
+
+ public boolean promptYesNo(String str){
+ System.err.println("User was prompted from: " + str);
+ return true;
+ }
+
+ public String getPassphrase() {
+ return null;
+ }
+
+ public boolean promptPassphrase(String message) {
+ System.out.println("promptPassphrase : " + message);
+ return false;
+ }
+
+ public boolean promptPassword(String message) {
+ System.out.println("promptPassword : " + message);
+ return true;
+ }
+
+ /**
+ * @see com.jcraft.jsch.UserInfo#showMessage(java.lang.String)
+ */
+ public void showMessage(String message) {
+ System.out.println("Sch has tried to show the following message to the user: " + message);
+ }
+
+ public String[] promptKeyboardInteractive(String destination,
+ String name,
+ String instruction,
+ String[] prompt,
+ boolean[] echo) {
+ System.out.println("User was prompted using interactive-keyboard: " +
+ "\n\tDestination: " + destination +
+ "\n\tName: " + name +
+ "\n\tInstruction: " + instruction +
+ "\n\tPrompt: " + arrayToString2(prompt,"|") +
+ "\n\techo: " + arrayToString2(echo,"|"));
+
+ if ((prompt.length >= 1) && (prompt[0].startsWith("Password")))
+ return new String[]{this.passwd};
+ return new String[]{};
+ }
+
+ String arrayToString2(String[] a, String separator) {
+ StringBuffer result = new StringBuffer(); // start with first element
+ if (a.length > 0) {
+ result.append(a[0]);
+ for (int i=1; i