diff --git a/datastore_server/dist/etc/service.properties b/datastore_server/dist/etc/service.properties index b505620b6abb509dbc45b4c187a5156fc88dc841..492eb3353d0e07a0010f47cd05792e48dccb9ddd 100644 --- a/datastore_server/dist/etc/service.properties +++ b/datastore_server/dist/etc/service.properties @@ -307,41 +307,48 @@ post-registration.post-registration-tasks = pathinfo-feeding post-registration.pathinfo-feeding.class = ch.systemsx.cisd.etlserver.path.PathInfoDatabaseFeedingTask post-registration.pathinfo-feeding.compute-checksum = true - # -# FTP server configuration +# FTP / SFTP server configuration +# +# The built-in FTP / SFTP server provides users with an alternative way to download their data using +# client programs like FileZilla or lftp. # -# when set to 'true' an internal ftp server will be started. it provides users with an alternative -# way to interact with their data (i.e. via an FTP client). -#ftp.server.enable=false +# When set to 'true' an internal ftp / sftp server will be started. Note that to really startup a +# server in addition ftp.server.ftp-port and / or ftp.server.sftp-port need to be set to a value other +# than 0. +ftp.server.enable = true # -# port where the FTP event connections will be opened. Optional parameter, default value is 2121. -#ftp.server.port=2121 +# Port where openBIS listens for incoming FTP connection requests. Remove comment to enable FTP server. +#ftp.server.ftp-port = 2121 # -# Specifies a range of ports to be used when working in passive mode. The default value is "2130-2140", -# meaning only 11 ports will be provide to connecting clients. If there are more than 11 concurrent -# users the configuration will have to be adjusted accordingly. -#ftp.server.passivemode.port.range=2130-2140 +# Specifies a range of ports to be used when working in passive mode (ignored by SFTP server). +# The default value is "2130-2140", thus only 11 ports will be provide to connecting clients. If +# there are more than 11 concurrent users the configuration will have to be adjusted accordingly. +#ftp.server.passivemode.port.range = 2130-2140 # -# when set to true enables the FTP server to run in "active mode". This means data connections -# will always go to a single pre-configured port on the server. Such a configuration can ease the -# server firewall administration (only one additional port should be opened). However it requires -# the client machines to be directly visible from the server. +# Port where openBIS listens for incoming SFTP connection requests. Comment out to disable SFTP server. +ftp.server.sftp-port = 2222 +# +# When set to true enables the FTP server to run in "active mode" (ignored by SFTP server). +# This means data connections will always go to a single pre-configured port on the server. Such a +# configuration can ease the server firewall administration (only one additional port should be +# opened). However it requires the client machines to be directly visible from the server. #ftp.server.activemode.enable=true # -# the active mode port number configuration. Default value is 2122. -#ftp.server.activemode.port=2122 +# The active mode port number configuration. Default value is 2122. +#ftp.server.activemode.port = 2122 # -# Enables explicit FTP over SSL/TLS. Users can switch on connection encryption by issuing the -# FTP "AUTH" command. Similarly to the global 'use-ssl' parameter, when set to 'true' all -# 'keystore.*' properties become mandatory +# Enables explicit FTP over SSL/TLS (ignored by SFTP server). Users can switch on connection +# encryption by issuing the FTP "AUTH" command. Similarly to the global 'use-ssl' parameter, when +# set to 'true' all 'keystore.*' properties become mandatory. #ftp.server.use-ssl=true # -# Allows to enable implicit FTP over SSL/TLS. While this method ensures no passwords are send -# around unencrypted, it is not standardized by an RFC and is therefore poorly supported by clients. +# Allows to enable implicit FTP over SSL/TLS (ignored by SFTP server). While this method ensures +# no passwords are send around unencrypted, it is not standardized by an RFC and is therefore +# poorly supported by clients. #ftp.server.implicit-ssl=false # -# maximum number of threads used by the internal FTP server. Defaults to 25. +# Maximum number of threads used by the internal FTP server (ignored by SFTP server). Defaults to 25. #ftp.server.maxThreads=25 # # The virtual folder structure supplied by the FTP server looks like @@ -365,7 +372,13 @@ post-registration.pathinfo-feeding.compute-checksum = true # /SPACE/PROJECT/EXPERIMENT/2011-10-10-10-10-B-file2.pdf # # Optional parameter, default template value is ${dataSetCode} -#ftp.server.dataset.display.template=${dataSetCode} +ftp.server.dataset.display.template = ${dataSetType}-${dataSetCode} +# +# Shows also parent and child data sets inside a data set directory. The name of these data sets are +# starting with PARENT- or CHILD- followed by the evaluated ftp.server.dataset.display.template. +# Note, this feature only works if the template doesn't contain ${fileName}. +# Comment out (or set to false) to disable this feature. +ftp.server.dataset.show-parents-and-children = true # # Specifies that the contents of a dataset should be listed starting from a preconfigured subpath. # The property is only configurable per data set type. diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServer.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServer.java index 69cc3d8e13bae66f20e60dabc74b82f7c8b801c0..995d46a4bdb6f111127a7428e665c0d39993ac3b 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServer.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServer.java @@ -122,27 +122,30 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File private void start() throws Exception { - String startingMessage = - String.format("Starting %sFTP server on port %d ...", "%s", config.getPort()); if (config.isSftpMode()) { sshServer = createSftpServer(); - operationLog.info(String.format(startingMessage, "S")); + operationLog.info(String.format("Starting SFTP server on port %d ...", + config.getSftpPort())); sshServer.start(); operationLog.info("SFTP server started."); } - server = creatFtpServer(); - operationLog.info(String.format(startingMessage, "")); - server.start(); - operationLog.info("FTP server started."); + if (config.isFtpMode()) + { + server = createFtpServer(); + operationLog.info(String.format("Starting FTP server on port %d ...", + config.getFtpPort())); + server.start(); + operationLog.info("FTP server started."); + } } - private org.apache.ftpserver.FtpServer creatFtpServer() + private org.apache.ftpserver.FtpServer createFtpServer() { FtpServerFactory serverFactory = new FtpServerFactory(); ListenerFactory factory = new ListenerFactory(); - factory.setPort(config.getPort()); + factory.setPort(config.getFtpPort()); if (config.isUseSSL()) { SslConfigurationFactory sslConfigFactory = new SslConfigurationFactory(); @@ -227,7 +230,7 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File @SuppressWarnings("unchecked") private List<NamedFactory<Command>> creatSubsystemFactories() { - return Arrays.<NamedFactory<Command>>asList(new SftpSubsystem.Factory()); + return Arrays.<NamedFactory<Command>> asList(new SftpSubsystem.Factory()); } /** @@ -276,13 +279,13 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File return new org.apache.sshd.server.FileSystemView() { private Cache cache = new Cache(SystemTimeProvider.SYSTEM_TIME_PROVIDER); - + @Override public SshFile getFile(SshFile baseDir, String file) { throw new UnsupportedOperationException(); } - + @Override public SshFile getFile(String file) { @@ -294,13 +297,17 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File throw new IOException(ex.getMessage()); } } - + private static final class FileView implements SshFile { private final DSSFileSystemView fileView; + private final String path; + private final List<InputStream> inputStreams = new ArrayList<InputStream>(); + private FtpFile file; + private final Cache cache; FileView(DSSFileSystemView fileView, String path, Cache cache) @@ -309,7 +316,7 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File this.path = path; this.cache = cache; } - + private FtpFile getFile() { if (file == null) @@ -450,7 +457,7 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File { throw new UnsupportedOperationException(); } - + @Override public InputStream createInputStream(long offset) throws IOException { @@ -475,7 +482,7 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File return "openBIS"; } } - + private static final class KeystoreBasedKeyPairProvider extends AbstractKeyPairProvider { private final KeyPair[] keyPairs; @@ -486,7 +493,8 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File String keyStorePassword = config.getKeyStorePassword(); String keyPassword = config.getKeyPassword(); KeyStore keystore = loadKeystore(keyStoreFile, keyStorePassword); - X509ExtendedKeyManager keyManager = getKeyManager(keystore, keyStorePassword, keyPassword); + X509ExtendedKeyManager keyManager = + getKeyManager(keystore, keyStorePassword, keyPassword); List<KeyPair> list = new ArrayList<KeyPair>(); try { @@ -503,7 +511,8 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File } } keyPairs = list.toArray(new KeyPair[list.size()]); - operationLog.info(keyPairs.length + " key pairs loaded from keystore " + keyStoreFile); + operationLog.info(keyPairs.length + " key pairs loaded from keystore " + + keyStoreFile); } catch (Exception ex) { throw CheckedExceptionTunnel.wrapIfNecessary(ex); @@ -528,11 +537,12 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File } catch (Exception e) { throw CheckedExceptionTunnel.wrapIfNecessary(e); - }finally{ + } finally + { IOUtils.closeQuietly(stream); } } - + private X509ExtendedKeyManager getKeyManager(KeyStore keystore, String keyStorePassword, String keyPassword) { @@ -540,7 +550,8 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File { String defaultAlgorithm = KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory factory = KeyManagerFactory.getInstance(defaultAlgorithm); - char[] password = (keyPassword == null ? keyStorePassword : keyPassword).toCharArray(); + char[] password = + (keyPassword == null ? keyStorePassword : keyPassword).toCharArray(); factory.init(keystore, password); KeyManager[] keyManagers = factory.getKeyManagers(); if (keyManagers.length != 1) @@ -560,7 +571,7 @@ public class FtpServer implements FileSystemFactory, org.apache.sshd.server.File { throw CheckedExceptionTunnel.wrapIfNecessary(ex); } - + } } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfig.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfig.java index ae6792760281e578e699f77cf0567dfe1dac155c..59a6b1a0394f81bfc1d4a03245e1aa19678aebd2 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfig.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/ftp/FtpServerConfig.java @@ -45,7 +45,9 @@ public class FtpServerConfig final static String SFTP_PORT_KEY = PREFIX + "sftp-port"; - final static String PORT_KEY = PREFIX + "port"; + final static String LEGACY_FTP_PORT_KEY = PREFIX + "port"; + + final static String FTP_PORT_KEY = PREFIX + "ftp-port"; final static String USE_SSL_KEY = PREFIX + "use-ssl"; @@ -67,8 +69,6 @@ public class FtpServerConfig final static String SHOW_PARENTS_AND_CHILDREN_KEY = PREFIX + "dataset.show-parents-and-children"; - private static final int DEFAULT_PORT = 2121; - private static final int DEFAULT_ACTIVE_PORT = 2122; private static final boolean DEFAULT_USE_SSL = true; @@ -83,7 +83,9 @@ public class FtpServerConfig private boolean startServer; - private int port; + private int ftpPort; + + private boolean ftpMode; private boolean activeModeEnabled; @@ -129,7 +131,12 @@ public class FtpServerConfig { sftpPort = PropertyUtils.getInt(props, SFTP_PORT_KEY, 0); sftpMode = sftpPort > 0; - port = PropertyUtils.getPosInt(props, PORT_KEY, DEFAULT_PORT); + ftpPort = PropertyUtils.getPosInt(props, FTP_PORT_KEY, 0); + if (ftpPort == 0) + { + ftpPort = PropertyUtils.getPosInt(props, LEGACY_FTP_PORT_KEY, 0); + } + ftpMode = ftpPort > 0; useSSL = PropertyUtils.getBoolean(props, USE_SSL_KEY, DEFAULT_USE_SSL); if (sftpMode || useSSL) { @@ -194,9 +201,14 @@ public class FtpServerConfig return startServer; } - public int getPort() + public boolean isFtpMode() + { + return ftpMode; + } + + public int getFtpPort() { - return port; + return ftpPort; } public boolean isUseSSL() @@ -254,13 +266,16 @@ public class FtpServerConfig */ public void logStartupInfo() { - operationLog.info("FTP Server port: " + port); - operationLog.info("FTP Server using SSL: " + useSSL); - operationLog.info("FTP Server passive ports: " + passivePortsRange); - operationLog.info("FTP Server enable active mode: " + activeModeEnabled); - if (activeModeEnabled) + if (ftpMode) { - operationLog.info("FTP Server active mode port: " + activePort); + operationLog.info("FTP Server port: " + ftpPort); + operationLog.info("FTP Server using SSL: " + useSSL); + operationLog.info("FTP Server passive ports: " + passivePortsRange); + operationLog.info("FTP Server enable active mode: " + activeModeEnabled); + if (activeModeEnabled) + { + operationLog.info("FTP Server active mode port: " + activePort); + } } if (sftpMode) {