-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
standalone: update server to support tls
Motivation: As standalone server is used to demonstrate xrootd4j implementations capabilities, the TLS setup should be included into the functionality. Modification: Update DataServerConfiguration to support `--tls`, `--hostcert` and `--hostkey` options. Update DataServerChannelInitializer to optionally enable TLS. Update pom to use "sslcontext-kickstart" library for handle certificates in pem format. Result: standalone server with optional TLS capability. Issue: #179 Acked-by: Lea Morschel Target: master
- Loading branch information
Showing
5 changed files
with
102 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/** | ||
* Copyright (C) 2011-2023 dCache.org <[email protected]> | ||
* Copyright (C) 2011-2024 dCache.org <[email protected]> | ||
* | ||
* This file is part of xrootd4j. | ||
* | ||
|
@@ -23,19 +23,29 @@ | |
import io.netty.channel.ChannelPipeline; | ||
import io.netty.channel.socket.SocketChannel; | ||
import io.netty.handler.logging.LoggingHandler; | ||
import io.netty.handler.ssl.SslContext; | ||
import io.netty.handler.ssl.SslContextBuilder; | ||
import nl.altindag.ssl.pem.util.PemUtils; | ||
import org.dcache.xrootd.core.XrootdAuthenticationHandler; | ||
import org.dcache.xrootd.core.XrootdDecoder; | ||
import org.dcache.xrootd.core.XrootdEncoder; | ||
import org.dcache.xrootd.core.XrootdHandshakeHandler; | ||
import org.dcache.xrootd.core.XrootdSessionHandler; | ||
import org.dcache.xrootd.plugins.ChannelHandlerFactory; | ||
import org.dcache.xrootd.plugins.tls.SSLHandlerFactory; | ||
import org.dcache.xrootd.security.SigningPolicy; | ||
import org.dcache.xrootd.security.TLSSessionInfo; | ||
import org.dcache.xrootd.stream.ChunkedResponseWriteHandler; | ||
import org.dcache.xrootd.util.ServerProtocolFlags; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import javax.net.ssl.SSLException; | ||
import javax.net.ssl.X509ExtendedKeyManager; | ||
import java.nio.file.Paths; | ||
import java.util.Properties; | ||
import java.util.function.Supplier; | ||
|
||
public class DataServerChannelInitializer extends ChannelInitializer<SocketChannel> { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger( | ||
|
@@ -60,9 +70,25 @@ protected void initChannel(SocketChannel ch) throws Exception { | |
/* | ||
* Placeholders, no Sigver and no TLS support yet. | ||
*/ | ||
|
||
SigningPolicy signingPolicy = new SigningPolicy(); | ||
ServerProtocolFlags flags = new ServerProtocolFlags(0); | ||
|
||
SSLHandlerFactory tlsFactory = null; | ||
if (_options.withTls) { | ||
tlsFactory = new LocalPemTlsHandler(_options.hostCert, _options.hostKey); | ||
tlsFactory.initialize(new Properties(), true); | ||
|
||
flags.setMode(ServerProtocolFlags.TlsMode.OPTIONAL); | ||
flags.setRequiresTLSForSession(true); | ||
flags.setRequiresTLSForLogin(true); | ||
flags.setRequiresTLSForData(true); | ||
flags.setSupportsTLS(true); | ||
} | ||
|
||
|
||
TLSSessionInfo tlsSessionInfo = new TLSSessionInfo(flags); | ||
tlsSessionInfo.setServerSslHandlerFactory(tlsFactory); | ||
|
||
XrootdSessionHandler sessionHandler = new XrootdSessionHandler(); | ||
/* | ||
|
@@ -95,4 +121,35 @@ protected void initChannel(SocketChannel ch) throws Exception { | |
signingPolicy); | ||
pipeline.addLast("data-server", dataServerHandler); | ||
} | ||
|
||
private static class LocalPemTlsHandler extends SSLHandlerFactory { | ||
|
||
/** | ||
* Netty SSL context for the TLS handler. | ||
*/ | ||
private final SslContext sslContext; | ||
|
||
/** | ||
* Create a new instance of the TLS handler. | ||
* @param hostcert Path to host certificate file. | ||
* @param hostkey Path to host key file. | ||
* @throws SSLException | ||
*/ | ||
LocalPemTlsHandler(String hostcert, String hostkey) throws SSLException { | ||
X509ExtendedKeyManager keyManager = | ||
PemUtils.loadIdentityMaterial(Paths.get(hostcert), Paths.get(hostkey)); | ||
sslContext = SslContextBuilder.forServer(keyManager).startTls(true).build(); | ||
} | ||
|
||
@Override | ||
protected Supplier<SslContext> buildContextSupplier(Properties properties) { | ||
return () -> sslContext; | ||
} | ||
|
||
@Override | ||
public String getName() { | ||
return SERVER_TLS; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/** | ||
* Copyright (C) 2011-2023 dCache.org <[email protected]> | ||
* Copyright (C) 2011-2024 dCache.org <[email protected]> | ||
* | ||
* This file is part of xrootd4j. | ||
* | ||
|
@@ -58,6 +58,10 @@ public class DataServerConfiguration { | |
public final List<String> channelHandlerPlugins; | ||
public final boolean useZeroCopy; | ||
|
||
public final boolean withTls; | ||
public final String hostCert; | ||
public final String hostKey; | ||
|
||
public final List<ChannelHandlerFactory> channelHandlerFactories; | ||
|
||
public DataServerConfiguration(DataServerOptionParser parser, OptionSet options) | ||
|
@@ -67,6 +71,9 @@ public DataServerConfiguration(DataServerOptionParser parser, OptionSet options) | |
pluginPath = options.valuesOf(parser.pluginPath); | ||
channelHandlerPlugins = options.valuesOf(parser.handlerPlugins); | ||
useZeroCopy = options.has(parser.zeroCopy); | ||
withTls = options.has(parser.withTls); | ||
hostCert = options.valueOf(parser.hostCert); | ||
hostKey = options.valueOf(parser.hostKey); | ||
|
||
_pluginDefaults = loadDefaultProperties(pluginPath); | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
/** | ||
* Copyright (C) 2011-2023 dCache.org <[email protected]> | ||
* Copyright (C) 2011-2024 dCache.org <[email protected]> | ||
* | ||
* This file is part of xrootd4j. | ||
* | ||
|
@@ -30,6 +30,9 @@ public class DataServerOptionParser extends OptionParser { | |
public final OptionSpec<String> handlerPlugins; | ||
public final OptionSpec<File> pluginPath; | ||
public final OptionSpec<Void> zeroCopy; | ||
public final OptionSpec<Void> withTls; | ||
public final OptionSpec<String> hostCert; | ||
public final OptionSpec<String> hostKey; | ||
|
||
{ | ||
port = acceptsAll(asList("p", "port")) | ||
|
@@ -55,5 +58,16 @@ public class DataServerOptionParser extends OptionParser { | |
.describedAs("url") | ||
.ofType(File.class); | ||
zeroCopy = acceptsAll(asList("z", "zerocopy"), "Use zero copy reads"); | ||
withTls = acceptsAll(asList("tls"), "Enable TLS for session and data protection"); | ||
hostCert = acceptsAll(asList("hostcert"), "Path to the host certificate file") | ||
.withRequiredArg() | ||
.describedAs("path") | ||
.ofType(String.class) | ||
.defaultsTo("hostcert.pem"); | ||
hostKey = acceptsAll(asList("hostkey"), "Path to the host key file") | ||
.withRequiredArg() | ||
.describedAs("path") | ||
.ofType(String.class) | ||
.defaultsTo("hostkey.pem"); | ||
} | ||
} |