fix PKI cert extraction

Original commit: elastic/x-pack-elasticsearch@9c68611557
This commit is contained in:
jaymode 2016-08-02 14:07:16 -04:00
parent b525891212
commit af16eec512
2 changed files with 33 additions and 19 deletions

View File

@ -5,6 +5,7 @@
*/ */
package org.elasticsearch.xpack.security.transport; package org.elasticsearch.xpack.security.transport;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLPeerUnverifiedException;
import java.io.IOException; import java.io.IOException;
import java.security.cert.Certificate; import java.security.cert.Certificate;
@ -81,30 +82,39 @@ public interface ServerTransportFilter {
unwrappedChannel = ((DelegatingTransportChannel) unwrappedChannel).getChannel(); unwrappedChannel = ((DelegatingTransportChannel) unwrappedChannel).getChannel();
} }
if (extractClientCert && (unwrappedChannel instanceof TcpTransportChannel) if (extractClientCert && (unwrappedChannel instanceof TcpTransportChannel)) {
&& ((TcpTransportChannel) unwrappedChannel).getChannel() instanceof Channel) { if (((TcpTransportChannel) unwrappedChannel).getChannel() instanceof Channel) {
Channel channel = (Channel) ((TcpTransportChannel) unwrappedChannel).getChannel(); Channel channel = (Channel) ((TcpTransportChannel) unwrappedChannel).getChannel();
SslHandler sslHandler = channel.getPipeline().get(SslHandler.class); SslHandler sslHandler = channel.getPipeline().get(SslHandler.class);
assert sslHandler != null; assert sslHandler != null;
extactClientCertificates(sslHandler.getEngine(), channel);
try { } else if (((TcpTransportChannel) unwrappedChannel).getChannel() instanceof io.netty.channel.Channel) {
Certificate[] certs = sslHandler.getEngine().getSession().getPeerCertificates(); io.netty.channel.Channel channel = (io.netty.channel.Channel) ((TcpTransportChannel) unwrappedChannel).getChannel();
if (certs instanceof X509Certificate[]) { io.netty.handler.ssl.SslHandler sslHandler = channel.pipeline().get(io.netty.handler.ssl.SslHandler.class);
threadContext.putTransient(PkiRealm.PKI_CERT_HEADER_NAME, certs); assert sslHandler != null;
} extactClientCertificates(sslHandler.engine(), channel);
} catch (SSLPeerUnverifiedException e) {
// this happens when we only request client authentication and the client does not provide it
if (logger.isTraceEnabled()) {
logger.trace("SSL Peer did not present a certificate on channel [{}]", e, channel);
} else if (logger.isDebugEnabled()) {
logger.debug("SSL Peer did not present a certificate on channel [{}]", channel);
}
} }
} }
Authentication authentication = authcService.authenticate(securityAction, request, null); Authentication authentication = authcService.authenticate(securityAction, request, null);
authzService.authorize(authentication, securityAction, request); authzService.authorize(authentication, securityAction, request);
} }
private void extactClientCertificates(SSLEngine sslEngine, Object channel) {
try {
Certificate[] certs = sslEngine.getSession().getPeerCertificates();
if (certs instanceof X509Certificate[]) {
threadContext.putTransient(PkiRealm.PKI_CERT_HEADER_NAME, certs);
}
} catch (SSLPeerUnverifiedException e) {
// this happens when we only request client authentication and the client does not provide it
if (logger.isTraceEnabled()) {
logger.trace("SSL Peer did not present a certificate on channel [{}]", e, channel);
} else if (logger.isDebugEnabled()) {
logger.debug("SSL Peer did not present a certificate on channel [{}]", channel);
}
}
}
} }
/** /**

View File

@ -45,7 +45,7 @@ import static org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Tr
import static org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Transport.SSL_SETTING; import static org.elasticsearch.xpack.security.transport.netty3.SecurityNetty3Transport.SSL_SETTING;
/** /**
* * Implementation of a transport that extends the {@link Netty4Transport} to add SSL and IP Filtering
*/ */
public class SecurityNetty4Transport extends Netty4Transport { public class SecurityNetty4Transport extends Netty4Transport {
@ -86,6 +86,10 @@ public class SecurityNetty4Transport extends Netty4Transport {
return new SecurityClientChannelInitializer(); return new SecurityClientChannelInitializer();
} }
/**
* This method ensures that all channels have their SSL handshakes completed. This is necessary to prevent the application from
* writing data while the handshake is in progress which could cause the handshake to fail.
*/
@Override @Override
protected void onAfterChannelsConnected(NodeChannels nodeChannels) { protected void onAfterChannelsConnected(NodeChannels nodeChannels) {
for (Channel channel : nodeChannels.allChannels) { for (Channel channel : nodeChannels.allChannels) {