Author: toad
Date: 2007-12-22 00:12:28 +0000 (Sat, 22 Dec 2007)
New Revision: 16775

Added:
   trunk/freenet/src/freenet/crypt/SSL.java
   trunk/freenet/src/freenet/io/SSLNetworkInterface.java
Modified:
   trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
   trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
   trunk/freenet/src/freenet/node/NodeStarter.java
   trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java
   trunk/freenet/src/freenet/node/fcp/FCPServer.java
Log:
Patch from ET at mj+bSV4hxRMtCj9fcwy4Ww9_3mc on Frost: Add SSL support for FCP, 
HTTP, TMCI.
Request testing!

Modified: trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java     
2007-12-22 00:06:33 UTC (rev 16774)
+++ trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java     
2007-12-22 00:12:28 UTC (rev 16775)
@@ -25,8 +25,10 @@
 import freenet.config.EnumerableOptionCallback;
 import freenet.config.InvalidConfigValueException;
 import freenet.config.SubConfig;
+import freenet.crypt.SSL;
 import freenet.io.AllowedHosts;
 import freenet.io.NetworkInterface;
+import freenet.io.SSLNetworkInterface;
 import freenet.l10n.L10n;
 import freenet.node.NodeClientCore;
 import freenet.support.HTMLNode;
@@ -53,12 +55,13 @@
        String bindTo;
        final AllowedHosts allowedFullAccess;
        final BucketFactory bf;
-       final NetworkInterface networkInterface;
+       NetworkInterface networkInterface;
        private final LinkedList toadlets;
        private String cssName;
        private File cssOverride;
        private Thread myThread;
        private boolean advancedModeEnabled;
+       private boolean ssl = false;
        private boolean fProxyJavascriptEnabled;
        private final PageMaker pageMaker;
        private final NodeClientCore core;
@@ -67,6 +70,21 @@
        static boolean isPanicButtonToBeShown;
        public static final int DEFAULT_FPROXY_PORT = 8888;

+       class FProxySSLCallback implements BooleanCallback {
+               
+               public boolean get() {
+                       return ssl;
+               }
+               public void set(boolean val) throws InvalidConfigValueException 
{
+                       if(val == get()) return;
+                       if(!SSL.available()) {
+                               throw new InvalidConfigValueException("Enable 
SSL support before use ssl with Fproxy");
+                       }
+                       ssl = val;
+                       throw new InvalidConfigValueException("Cannot change 
SSL on the fly, please restart freenet");
+               }
+       }
+
        class FProxyPortCallback implements IntCallback {

                public int get() {
@@ -272,7 +290,8 @@
                                themes.add("clean");
                        }
                }
-               
+               fproxyConfig.register("ssl", false, configItemOrder++, true, 
true, "SimpleToadletServer.ssl", "SimpleToadletServer.sslLong",
+                               new FProxySSLCallback());
                fproxyConfig.register("port", DEFAULT_FPROXY_PORT, 
configItemOrder++, true, true, "SimpleToadletServer.port", 
"SimpleToadletServer.portLong",
                                new FProxyPortCallback());
                fproxyConfig.register("bindTo", 
NetworkInterface.DEFAULT_BIND_TO, configItemOrder++, true, true, 
"SimpleToadletServer.bindTo", "SimpleToadletServer.bindToLong",
@@ -340,9 +359,17 @@

                this.advancedModeEnabled = 
fproxyConfig.getBoolean("advancedModeEnabled");              
                toadlets = new LinkedList();
+
+               if(SSL.available()) {
+                       ssl = fproxyConfig.getBoolean("ssl");
+               }
+
+               if(ssl) {
+                       this.networkInterface = 
SSLNetworkInterface.create(port, this.bindTo, 
fproxyConfig.getString("allowedHosts"), core.getExecutor(), true);
+               } else {
+                       this.networkInterface = NetworkInterface.create(port, 
this.bindTo, fproxyConfig.getString("allowedHosts"), core.getExecutor(), true);
+               }

-               this.networkInterface = NetworkInterface.create(port, 
this.bindTo, fproxyConfig.getString("allowedHosts"), core.getExecutor(), true);
-               
                if(!enabled) {
                        Logger.normal(core, "Not starting FProxy as it's 
disabled");
                        System.out.println("Not starting FProxy as it's 
disabled");

Added: trunk/freenet/src/freenet/crypt/SSL.java
===================================================================
--- trunk/freenet/src/freenet/crypt/SSL.java                            (rev 0)
+++ trunk/freenet/src/freenet/crypt/SSL.java    2007-12-22 00:12:28 UTC (rev 
16775)
@@ -0,0 +1,269 @@
+/*
+ * 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.
+ */
+
+package freenet.crypt;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import javax.net.ServerSocketFactory;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+
+import freenet.config.InvalidConfigValueException;
+import freenet.config.SubConfig;
+import freenet.support.Logger;
+import freenet.support.api.BooleanCallback;
+import freenet.support.api.StringCallback;
+
+import sun.security.x509.X500Name;
+import sun.security.x509.CertAndKeyGen;
+
+public class SSL {
+
+       private static boolean enable;
+       private static KeyStore keystore;
+       private static ServerSocketFactory ssf;
+       private static String keyStore;
+       private static String keyStorePass;
+       private static String keyPass;
+       private static String version;
+
+       private SSL() {
+               
+       }
+
+       /**
+        * Call this function before ask ServerSocket
+        * @return True is ssl is available
+        */
+       public static boolean available() {
+               return (ssf != null);
+       }
+       
+       /**
+        * Configure SSL support
+        * @param sslConfig
+        */
+       public static void init(SubConfig sslConfig) {
+               int configItemOrder = 0;
+               
+               // Tracks config parameters related to a SSL
+               sslConfig.register("sslEnable", false, configItemOrder++, true, 
true, "SSL.enable", "SSL.enableLong",
+                       new BooleanCallback() {
+                               public boolean get() {
+                                       return enable;
+                               }
+                               
+                               public void set(boolean newValue) throws 
InvalidConfigValueException {
+                                       if (newValue != get()) {
+                                               enable = newValue;
+                                               if(enable) {
+                                                       try {
+                                                               loadKeyStore();
+                                                       createSSLContext();
+                                                       } catch (Exception e) {
+                                                               enable = false;
+                                                               
e.printStackTrace(System.out);
+                                                       throw new 
InvalidConfigValueException("Cannot enabled ssl, config error");
+                                                       }
+                                               } else {
+                                                       ssf = null;
+                                                       keyStore = null;
+                                               }
+                                       }
+                               }
+                       }
+               );
+
+               sslConfig.register("sslKeyStore", "datastore/certs", 
configItemOrder++, true, true, "SSL.keyStore", "SSL.keyStoreLong",
+                       new StringCallback() {
+                               public String get() {
+                                       return keyStore;
+                               }
+                               
+                               public void set(String newKeyStore) throws 
InvalidConfigValueException {
+                                       if (!newKeyStore.equals(get())) {
+                                               String oldKeyStore = keyStore;
+                                               keyStore = newKeyStore;
+                                               try {
+                                                       loadKeyStore();
+                                               } catch (Exception e) {
+                                                       keyStore = oldKeyStore;
+                                                       
e.printStackTrace(System.out);
+                                               throw new 
InvalidConfigValueException("Cannot change keystore file");
+                                               }
+                                       }
+                               }
+                       }
+               );
+
+               sslConfig.register("sslKeyStorePass", "freenet", 
configItemOrder++, true, true, "SSL.keyStorePass", "SSL.keyStorePassLong",
+                       new StringCallback() {
+                               public String get() {
+                                       return keyStorePass;
+                               }
+                               
+                               public void set(String newKeyStorePass) throws 
InvalidConfigValueException {
+                                       if (!newKeyStorePass.equals(get())) {
+                                               String oldKeyStorePass = 
keyStorePass;
+                                               keyStorePass = newKeyStorePass;
+                                       try {
+                                               storeKeyStore();
+                                       } catch (Exception e) {
+                                               keyStorePass = oldKeyStorePass;
+                                                       
e.printStackTrace(System.out);
+                                               throw new 
InvalidConfigValueException("Cannot change keystore password");
+                                       }
+                                       }
+                               }
+                       }
+               );
+               
+               sslConfig.register("sslKeyPass", "freenet", configItemOrder++, 
true, true, "SSL.keyPass", "SSL.keyPassLong",
+                       new StringCallback() {
+                               public String get() {
+                                       return keyPass;
+                               }
+                               
+                               public void set(String newKeyPass) throws 
InvalidConfigValueException {
+                                       if (!newKeyPass.equals(get())) {
+                                               String oldKeyPass = keyPass;
+                                               keyPass = newKeyPass;
+                                               try {
+                                                       Certificate[] chain = 
keystore.getCertificateChain("freenet");
+                                                       Key privKey = 
keystore.getKey("freenet", oldKeyPass.toCharArray());
+                                               keystore.setKeyEntry("freenet", 
privKey, keyPass.toCharArray(), chain);
+                                               createSSLContext();
+                                               } catch (Exception e) {
+                                                       keyPass = oldKeyPass;
+                                                       
e.printStackTrace(System.out);
+                                               throw new 
InvalidConfigValueException("Cannot change private key password");
+                                               }
+                                       }
+                               }
+                       }
+               );
+               
+               sslConfig.register("sslVersion", "SSLv3", configItemOrder++, 
true, true, "SSL.version", "SSL.versionLong",
+                       new StringCallback() {
+                               public String get() {
+                                       return version;
+                               }
+                               
+                               public void set(String newVersion) throws 
InvalidConfigValueException {
+                                       if (!newVersion.equals(get())) {
+                                               String oldVersion = version;
+                                               version = newVersion;
+                                               try {
+                                                       createSSLContext();
+                                               } catch (Exception e) {
+                                                       version = oldVersion;
+                                                       
e.printStackTrace(System.out);
+                                               throw new 
InvalidConfigValueException("Cannot change ssl version, wrong value");
+                                               }
+                                       }
+                               }
+                       }
+               );
+
+               enable = sslConfig.getBoolean("sslEnable");
+               keyStore = sslConfig.getString("sslKeyStore");
+               keyStorePass = sslConfig.getString("sslKeyStorePass");
+               keyPass = sslConfig.getString("sslKeyPass");
+               version = sslConfig.getString("sslVersion");
+
+               try {
+                       keystore = KeyStore.getInstance("PKCS12");
+                       loadKeyStore();
+               createSSLContext();
+               } catch (Exception e) {
+                       Logger.error(SSL.class, "Cannot load keystore, ssl is 
disable", e);
+               }
+
+       }
+       
+       /**
+        * Create ServerSocket with ssl support
+        * @return ServerSocket with ssl support
+        * @throws IOException
+        */
+       public static ServerSocket createServerSocket() throws IOException {
+               if(ssf == null) 
+                       throw new IOException("SSL not initialized");
+               return ssf.createServerSocket();
+       }
+       
+       private static void loadKeyStore() throws Exception {
+               if(enable) {
+                       // A keystore is where keys and certificates are kept
+                       // Both the keystore and individual private keys should 
be password protected
+                       try {
+                               FileInputStream fis = new 
FileInputStream(keyStore);
+                               keystore.load(fis, keyStorePass.toCharArray());
+                       } catch (FileNotFoundException fnfe) {
+                               //If keystore not exist, create keystore and 
server certificat
+                               keystore.load(null, keyStorePass.toCharArray());
+                               CertAndKeyGen keypair = new 
CertAndKeyGen("DSA", "SHA1WithDSA");
+                               X500Name x500Name = new X500Name (
+                                               "Freenet",
+                                               "Freenet",
+                                               "Freenet",
+                                               "",
+                                               "",
+                                               ""
+                                       );
+                               keypair.generate(1024);
+                               PrivateKey privKey = keypair.getPrivateKey();
+                               X509Certificate[] chain = new 
X509Certificate[1];
+                               chain[0] = keypair.getSelfCertificate(x500Name, 
(long)365*24*60*60);
+                       keystore.setKeyEntry("freenet", privKey, 
keyPass.toCharArray(), chain);
+                       storeKeyStore();
+                       createSSLContext();
+                       }
+               }
+       }
+       
+       private static void storeKeyStore() throws Exception {
+               if(enable) {
+                       FileOutputStream fos = new FileOutputStream(keyStore);
+                       keystore.store(fos, keyStorePass.toCharArray());
+                       fos.close();
+               }
+       }
+       
+       private static void createSSLContext() throws Exception {
+               if(enable) {
+                       // A KeyManagerFactory is used to create key managers
+                       KeyManagerFactory kmf = 
KeyManagerFactory.getInstance("SunX509");
+                       // Initialize the KeyManagerFactory to work with our 
keystore
+                       kmf.init(keystore, keyPass.toCharArray());
+                       // An SSLContext is an environment for implementing JSSE
+                       // It is used to create a ServerSocketFactory
+                       SSLContext sslc = SSLContext.getInstance(version);
+                       // Initialize the SSLContext to work with our key 
managers
+                       sslc.init(kmf.getKeyManagers(), null, null);
+                       ssf = sslc.getServerSocketFactory();
+               }
+       }
+}

Added: trunk/freenet/src/freenet/io/SSLNetworkInterface.java
===================================================================
--- trunk/freenet/src/freenet/io/SSLNetworkInterface.java                       
        (rev 0)
+++ trunk/freenet/src/freenet/io/SSLNetworkInterface.java       2007-12-22 
00:12:28 UTC (rev 16775)
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+package freenet.io;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+
+import javax.net.ssl.SSLServerSocket;
+
+import freenet.crypt.SSL;
+import freenet.support.Executor;
+import freenet.support.Logger;
+
+/**
+ * An SSL extension to the {@link NetworkInterface} 
+ * @author ET
+ */
+public class SSLNetworkInterface extends NetworkInterface {
+
+       private boolean requireClientAuthentication;
+       
+       public static NetworkInterface create(int port, String bindTo, String 
allowedHosts, Executor executor, boolean ignoreUnbindableIP6) throws 
IOException {
+               NetworkInterface iface = new SSLNetworkInterface(port, 
allowedHosts, executor);
+               try {
+                       iface.setBindTo(bindTo, ignoreUnbindableIP6);
+               } catch (IOException e) {
+                       try {
+                               iface.close();
+                       } catch (IOException e1) {
+                               Logger.error(NetworkInterface.class, "Caught 
"+e1+" closing after catching "+e+" binding while constructing", e1);
+                               // Ignore
+                       }
+                       throw e;
+               }
+               return iface;
+       }
+
+       /**
+        * See {@link NetworkInterface}
+        */
+       protected SSLNetworkInterface(int port, String allowedHosts, Executor 
executor) throws IOException {
+               super(port, allowedHosts, executor);
+       }
+
+       /**
+        * {@inheritDoc}
+        */
+       protected ServerSocket createServerSocket() throws IOException {
+               ServerSocket serverSocket = SSL.createServerSocket();
+               
((SSLServerSocket)serverSocket).setNeedClientAuth(requireClientAuthentication);
+               return serverSocket;
+       }
+       
+       /**
+        * Set true if client authentication is required
+        * @param value true or false
+        */
+       public void setRequireClientAuthentication(boolean value) {
+               requireClientAuthentication = value;
+       }
+}

Modified: trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties   2007-12-22 
00:06:33 UTC (rev 16774)
+++ trunk/freenet/src/freenet/l10n/freenet.l10n.en.properties   2007-12-22 
00:12:28 UTC (rev 16775)
@@ -89,6 +89,7 @@
 ConfigToadlet.reset=Reset
 ConfigToadlet.returnToNodeConfig=Return to node configuration
 ConfigToadlet.shortTitle=Configuration
+ConfigToadlet.ssl=SSL (not affect active servers if change, restart is 
necessary)
 ConfigToadlet.title=Freenet Node Configuration
 ConfigToadlet.toadletsymlinker=toadletsymlinker
 ConfigToadlet.true=true
@@ -350,6 +351,8 @@
 FcpServer.isEnabledLong=Is FCP server enabled ?
 FcpServer.portNumber=FCP port number
 FcpServer.portNumberLong=FCP port number.
+FcpServer.ssl=Enable ssl?
+FcpServer.sslLong=Enable ssl?
 FetchException.longError.10=File not in archive
 FetchException.longError.11=Too many path components - not a manifest? Try 
removing one
 FetchException.longError.12=Internal temp files error, maybe disk full or 
permissions problem?
@@ -914,6 +917,18 @@
 SimpleToadletServer.panicButtonLong=Whether to show or not the panic button on 
the /queue/ page.
 SimpleToadletServer.port=FProxy port number
 SimpleToadletServer.portLong=FProxy port number
+SimpleToadletServer.ssl=Enable ssl?
+SimpleToadletServer.sslLong=Enable ssl?
+SSL.enable=Activate SSL support?
+SSL.enableLong=Activate SSL support?
+SSL.keyStore=Name and path of key store file
+SSL.keyStoreLong=Name and path of key store file
+SSL.keyStorePass=Password for access of key store file
+SSL.keyStorePassLong=Password for access of key store file
+SSL.keyPass=Password of private key access
+SSL.keyPassLong=Password of private key access
+SSL.version=Version of SSL
+SSL.versionLong=Version of SSL, SSLv3 or TLSv1 (default SSLv3)
 StaticToadlet.pathInvalidChars=The given URI contains disallowed characters.
 StaticToadlet.pathNotFound=The path you specified doesn't exist.
 StaticToadlet.pathNotFoundTitle=Path Not Found
@@ -960,6 +975,8 @@
 TextModeClientInterfaceServer.enableInputOutputLong=Enable text mode client 
interface on standard input/output? (.enabled refers to providing a 
telnet-style server, this runs it over a socket)
 TextModeClientInterfaceServer.enabled=Enable TMCI
 TextModeClientInterfaceServer.enabledLong=Whether to enable the TMCI
+TextModeClientInterfaceServer.ssl=Enable ssl?
+TextModeClientInterfaceServer.sslLong=Enable ssl?
 TextModeClientInterfaceServer.telnetPortNumber=Telnet port
 TextModeClientInterfaceServer.telnetPortNumberLong=Telnet port number
 TimeSkewDetectedUserAlert.title=Time skew detected!

Modified: trunk/freenet/src/freenet/node/NodeStarter.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeStarter.java     2007-12-22 00:06:33 UTC 
(rev 16774)
+++ trunk/freenet/src/freenet/node/NodeStarter.java     2007-12-22 00:12:28 UTC 
(rev 16775)
@@ -15,6 +15,7 @@
 import freenet.config.SubConfig;
 import freenet.crypt.DiffieHellman;
 import freenet.crypt.RandomSource;
+import freenet.crypt.SSL;
 import freenet.crypt.Yarrow;
 import freenet.support.Executor;
 import freenet.support.Logger;
@@ -147,6 +148,10 @@
                plug.setDaemon(false);
                plug.start();

+               // Initialize SSL
+       SubConfig sslConfig = new SubConfig("ssl", cfg);
+       SSL.init(sslConfig);
+               
        WrapperManager.signalStarting(500000);
        try {
                node = new Node(cfg, random, logConfigHandler,this, executor);

Modified: trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java   
2007-12-22 00:06:33 UTC (rev 16774)
+++ trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java   
2007-12-22 00:12:28 UTC (rev 16775)
@@ -17,7 +17,9 @@
 import freenet.config.InvalidConfigValueException;
 import freenet.config.SubConfig;
 import freenet.crypt.RandomSource;
+import freenet.crypt.SSL;
 import freenet.io.NetworkInterface;
+import freenet.io.SSLNetworkInterface;
 import freenet.support.Logger;
 import freenet.support.api.BooleanCallback;
 import freenet.support.api.IntCallback;
@@ -35,6 +37,7 @@
     String bindTo;
     String allowedHosts;
     boolean isEnabled;
+    private static boolean ssl = false;
     final NetworkInterface networkInterface;

     TextModeClientInterfaceServer(Node node, NodeClientCore core, int port, 
String bindTo, String allowedHosts) throws IOException {
@@ -47,7 +50,11 @@
         this.bindTo=bindTo;
         this.allowedHosts = allowedHosts;
         this.isEnabled=true;
-        networkInterface = NetworkInterface.create(port, bindTo, allowedHosts, 
n.executor, true);
+        if(ssl) {
+               networkInterface = SSLNetworkInterface.create(port, bindTo, 
allowedHosts, n.executor, true);
+        } else {
+               networkInterface = NetworkInterface.create(port, bindTo, 
allowedHosts, n.executor, true);
+        }
     }

     void start() {
@@ -64,6 +71,7 @@
                SubConfig TMCIConfig = new SubConfig("console", config);

                TMCIConfig.register("enabled", false, 1, true, true /* FIXME 
only because can't be changed on the fly */, 
"TextModeClientInterfaceServer.enabled", 
"TextModeClientInterfaceServer.enabledLong", new TMCIEnabledCallback(core));
+               TMCIConfig.register("ssl", false, 1, true, true , 
"TextModeClientInterfaceServer.ssl", "TextModeClientInterfaceServer.sslLong", 
new TMCISSLCallback());
                TMCIConfig.register("bindTo", NetworkInterface.DEFAULT_BIND_TO, 
2, true, false, "TextModeClientInterfaceServer.bindTo", 
"TextModeClientInterfaceServer.bindToLong", new TMCIBindtoCallback(core));
                TMCIConfig.register("allowedHosts", 
NetworkInterface.DEFAULT_BIND_TO, 2, true, false, 
"TextModeClientInterfaceServer.allowedHosts", 
"TextModeClientInterfaceServer.allowedHostsLong", new 
TMCIAllowedHostsCallback(core));
                TMCIConfig.register("port", 2323, 1, true, false, 
"TextModeClientInterfaceServer.telnetPortNumber", 
"TextModeClientInterfaceServer.telnetPortNumberLong", new 
TCMIPortNumberCallback(core));
@@ -74,6 +82,9 @@
                String bind_ip = TMCIConfig.getString("bindTo");
                String allowedHosts = TMCIConfig.getString("allowedHosts");
                boolean direct = TMCIConfig.getBoolean("directEnabled");
+               if(SSL.available()) {
+                       ssl = TMCIConfig.getBoolean("ssl");
+               }

                if(TMCIEnabled)
                        server = new TextModeClientInterfaceServer(node, core, 
port, bind_ip, allowedHosts);
@@ -113,6 +124,22 @@
        }
     }

+    static class TMCISSLCallback implements BooleanCallback {
+       
+       public boolean get() {
+               return ssl;
+       }
+       
+       public void set(boolean val) throws InvalidConfigValueException {
+               if(val == get()) return;
+                       if(!SSL.available()) {
+                               throw new InvalidConfigValueException("Enable 
SSL support before use ssl with TMCI");
+                       }
+               ssl = val;
+               throw new InvalidConfigValueException("Cannot change SSL on the 
fly, please restart freenet");
+       }
+    }
+
     static class TMCIDirectEnabledCallback implements BooleanCallback {

        final NodeClientCore core;

Modified: trunk/freenet/src/freenet/node/fcp/FCPServer.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPServer.java   2007-12-22 00:06:33 UTC 
(rev 16774)
+++ trunk/freenet/src/freenet/node/fcp/FCPServer.java   2007-12-22 00:12:28 UTC 
(rev 16775)
@@ -30,8 +30,10 @@
 import freenet.config.Config;
 import freenet.config.InvalidConfigValueException;
 import freenet.config.SubConfig;
+import freenet.crypt.SSL;
 import freenet.io.AllowedHosts;
 import freenet.io.NetworkInterface;
+import freenet.io.SSLNetworkInterface;
 import freenet.keys.FreenetURI;
 import freenet.l10n.L10n;
 import freenet.node.Node;
@@ -59,6 +61,7 @@
        final NodeClientCore core;
        final Node node;
        final int port;
+       private static boolean ssl = false;
        public final boolean enabled;
        String bindTo;
        AllowedHosts allowedHostsFullAccess;
@@ -118,7 +121,11 @@

                NetworkInterface tempNetworkInterface = null;
                try {
-                       tempNetworkInterface = NetworkInterface.create(port, 
bindTo, allowedHosts, node.executor, true);
+                       if(ssl) {
+                               tempNetworkInterface = 
SSLNetworkInterface.create(port, bindTo, allowedHosts, node.executor, true);
+                       } else {
+                               tempNetworkInterface = 
NetworkInterface.create(port, bindTo, allowedHosts, node.executor, true);
+                       }
                } catch (IOException be) {
                        Logger.error(this, "Couldn't bind to FCP Port "+bindTo+ 
':' +port+". FCP Server not started.", be);
                        System.out.println("Couldn't bind to FCP Port "+bindTo+ 
':' +port+". FCP Server not started.");
@@ -215,6 +222,22 @@
                }
        }

+       static class FCPSSLCallback implements BooleanCallback{
+
+               public boolean get() {
+                       return ssl;
+               }
+
+               public void set(boolean val) throws InvalidConfigValueException 
{
+               if(val == get()) return;
+                       if(!SSL.available()) {
+                               throw new InvalidConfigValueException("Enable 
SSL support before use ssl with FCP");
+                       }
+                       ssl = val;
+                       throw new InvalidConfigValueException("Cannot change 
SSL on the fly, please restart freenet");
+               }
+       }
+
        // FIXME: Consider moving everything except enabled into constructor
        // Actually we could move enabled in too with an exception???

@@ -368,6 +391,7 @@
                SubConfig fcpConfig = new SubConfig("fcp", config);
                short sortOrder = 0;
                fcpConfig.register("enabled", true, sortOrder++, true, false, 
"FcpServer.isEnabled", "FcpServer.isEnabledLong", new FCPEnabledCallback(core));
+               fcpConfig.register("ssl", false, sortOrder++, true, true, 
"FcpServer.ssl", "FcpServer.sslLong", new FCPSSLCallback());
                fcpConfig.register("port", FCPServer.DEFAULT_FCP_PORT /* 
anagram of 1984, and 1000 up from old number */, 2, true, true, 
"FcpServer.portNumber", "FcpServer.portNumberLong", new 
FCPPortNumberCallback(core));
                fcpConfig.register("bindTo", NetworkInterface.DEFAULT_BIND_TO, 
sortOrder++, false, true, "FcpServer.bindTo", "FcpServer.bindToLong", new 
FCPBindtoCallback(core));
                fcpConfig.register("allowedHosts", 
NetworkInterface.DEFAULT_BIND_TO, sortOrder++, false, true, 
"FcpServer.allowedHosts", "FcpServer.allowedHostsLong", new 
FCPAllowedHostsCallback(core));
@@ -386,6 +410,10 @@
                AssumeDDAUploadIsAllowedCallback cb5;
                fcpConfig.register("assumeDownloadDDAIsAllowed", false, 
sortOrder++, true, false, "FcpServer.assumeDownloadDDAIsAllowed", 
"FcpServer.assumeDownloadDDAIsAllowedLong", cb4 = new 
AssumeDDADownloadIsAllowedCallback());
                fcpConfig.register("assumeUploadDDAIsAllowed", false, 
sortOrder++, true, false, "FcpServer.assumeUploadDDAIsAllowed", 
"FcpServer.assumeUploadDDAIsAllowedLong", cb5 = new 
AssumeDDAUploadIsAllowedCallback());
+
+               if(SSL.available()) {
+                       ssl = fcpConfig.getBoolean("ssl");
+               }

                FCPServer fcp = new FCPServer(fcpConfig.getString("bindTo"), 
fcpConfig.getString("allowedHosts"), 
fcpConfig.getString("allowedHostsFullAccess"), fcpConfig.getInt("port"), node, 
core, persistentDownloadsEnabled, persistentDownloadsDir, 
persistentDownloadsInterval, fcpConfig.getBoolean("enabled"), 
fcpConfig.getBoolean("assumeDownloadDDAIsAllowed"), 
fcpConfig.getBoolean("assumeUploadDDAIsAllowed"));



Reply via email to