git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1399438 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Timothy A. Bish 2012-10-17 21:17:45 +00:00
parent b5e46ef9c5
commit 65af81e09e
1 changed files with 85 additions and 58 deletions

View File

@ -41,9 +41,13 @@ import org.apache.activemq.thread.TaskRunnerFactory;
import org.apache.activemq.util.IOExceptionSupport; import org.apache.activemq.util.IOExceptionSupport;
import org.apache.activemq.util.ServiceStopper; import org.apache.activemq.util.ServiceStopper;
import org.apache.activemq.wireformat.WireFormat; import org.apache.activemq.wireformat.WireFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class NIOSSLTransport extends NIOTransport { public class NIOSSLTransport extends NIOTransport {
private static final Logger LOG = LoggerFactory.getLogger(NIOSSLTransport.class);
protected boolean needClientAuth; protected boolean needClientAuth;
protected boolean wantClientAuth; protected boolean wantClientAuth;
protected String[] enabledCipherSuites; protected String[] enabledCipherSuites;
@ -79,15 +83,36 @@ public class NIOSSLTransport extends NIOTransport {
sslContext = SSLContext.getDefault(); sslContext = SSLContext.getDefault();
} }
String remoteHost = null;
int remotePort = -1;
try {
URI remoteAddress = new URI(this.getRemoteAddress());
remoteHost = remoteAddress.getHost();
remotePort = remoteAddress.getPort();
} catch (Exception e) {
}
// initialize engine, the initial sslSession we get will need to be // initialize engine, the initial sslSession we get will need to be
// updated once the ssl handshake process is completed. // updated once the ssl handshake process is completed.
if (remoteHost != null && remotePort != -1) {
sslEngine = sslContext.createSSLEngine(remoteHost, remotePort);
} else {
sslEngine = sslContext.createSSLEngine(); sslEngine = sslContext.createSSLEngine();
}
sslEngine.setUseClientMode(false); sslEngine.setUseClientMode(false);
if (enabledCipherSuites != null) { if (enabledCipherSuites != null) {
sslEngine.setEnabledCipherSuites(enabledCipherSuites); sslEngine.setEnabledCipherSuites(enabledCipherSuites);
} }
sslEngine.setNeedClientAuth(needClientAuth);
if (wantClientAuth) {
sslEngine.setWantClientAuth(wantClientAuth); sslEngine.setWantClientAuth(wantClientAuth);
}
if (needClientAuth) {
sslEngine.setNeedClientAuth(needClientAuth);
}
sslSession = sslEngine.getSession(); sslSession = sslEngine.getSession();
@ -143,7 +168,7 @@ public class NIOSSLTransport extends NIOTransport {
ByteBuffer plain = ByteBuffer.allocate(sslSession.getApplicationBufferSize()); ByteBuffer plain = ByteBuffer.allocate(sslSession.getApplicationBufferSize());
plain.position(plain.limit()); plain.position(plain.limit());
while(true) { while (true) {
if (!plain.hasRemaining()) { if (!plain.hasRemaining()) {
if (status == SSLEngineResult.Status.OK && handshakeStatus != SSLEngineResult.HandshakeStatus.NEED_UNWRAP) { if (status == SSLEngineResult.Status.OK && handshakeStatus != SSLEngineResult.HandshakeStatus.NEED_UNWRAP) {
@ -153,12 +178,11 @@ public class NIOSSLTransport extends NIOTransport {
} }
int readCount = secureRead(plain); int readCount = secureRead(plain);
if (readCount == 0) if (readCount == 0)
break; break;
// channel is closed, cleanup // channel is closed, cleanup
if (readCount== -1) { if (readCount == -1) {
onException(new EOFException()); onException(new EOFException());
selection.close(); selection.close();
break; break;
@ -181,7 +205,8 @@ public class NIOSSLTransport extends NIOTransport {
if (wireFormat instanceof OpenWireFormat) { if (wireFormat instanceof OpenWireFormat) {
long maxFrameSize = ((OpenWireFormat) wireFormat).getMaxFrameSize(); long maxFrameSize = ((OpenWireFormat) wireFormat).getMaxFrameSize();
if (nextFrameSize > maxFrameSize) { if (nextFrameSize > maxFrameSize) {
throw new IOException("Frame size of " + (nextFrameSize / (1024 * 1024)) + " MB larger than max allowed " + (maxFrameSize / (1024 * 1024)) + " MB"); throw new IOException("Frame size of " + (nextFrameSize / (1024 * 1024)) +
" MB larger than max allowed " + (maxFrameSize / (1024 * 1024)) + " MB");
} }
} }
currentBuffer = ByteBuffer.allocate(nextFrameSize + 4); currentBuffer = ByteBuffer.allocate(nextFrameSize + 4);
@ -213,8 +238,7 @@ public class NIOSSLTransport extends NIOTransport {
if (bytesRead == -1) { if (bytesRead == -1) {
sslEngine.closeInbound(); sslEngine.closeInbound();
if (inputBuffer.position() == 0 || if (inputBuffer.position() == 0 || status == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
status == SSLEngineResult.Status.BUFFER_UNDERFLOW) {
return -1; return -1;
} }
} }
@ -226,9 +250,8 @@ public class NIOSSLTransport extends NIOTransport {
SSLEngineResult res; SSLEngineResult res;
do { do {
res = sslEngine.unwrap(inputBuffer, plain); res = sslEngine.unwrap(inputBuffer, plain);
} while (res.getStatus() == SSLEngineResult.Status.OK && } while (res.getStatus() == SSLEngineResult.Status.OK && res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP
res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.NEED_UNWRAP && && res.bytesProduced() == 0);
res.bytesProduced() == 0);
if (res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED) { if (res.getHandshakeStatus() == SSLEngineResult.HandshakeStatus.FINISHED) {
finishHandshake(); finishHandshake();
@ -237,7 +260,7 @@ public class NIOSSLTransport extends NIOTransport {
status = res.getStatus(); status = res.getStatus();
handshakeStatus = res.getHandshakeStatus(); handshakeStatus = res.getHandshakeStatus();
//TODO deal with BUFFER_OVERFLOW // TODO deal with BUFFER_OVERFLOW
if (status == SSLEngineResult.Status.CLOSED) { if (status == SSLEngineResult.Status.CLOSED) {
sslEngine.closeInbound(); sslEngine.closeInbound();
@ -264,7 +287,7 @@ public class NIOSSLTransport extends NIOTransport {
} }
break; break;
case NEED_WRAP: case NEED_WRAP:
((NIOOutputStream)buffOut).write(ByteBuffer.allocate(0)); ((NIOOutputStream) buffOut).write(ByteBuffer.allocate(0));
break; break;
case FINISHED: case FINISHED:
case NOT_HANDSHAKING: case NOT_HANDSHAKING:
@ -295,14 +318,15 @@ public class NIOSSLTransport extends NIOTransport {
} }
/** /**
* Overriding in order to add the client's certificates to ConnectionInfo Commmands. * Overriding in order to add the client's certificates to ConnectionInfo Commands.
* *
* @param command The Command coming in. * @param command
* The Command coming in.
*/ */
@Override @Override
public void doConsume(Object command) { public void doConsume(Object command) {
if (command instanceof ConnectionInfo) { if (command instanceof ConnectionInfo) {
ConnectionInfo connectionInfo = (ConnectionInfo)command; ConnectionInfo connectionInfo = (ConnectionInfo) command;
connectionInfo.setTransportContext(getPeerCertificates()); connectionInfo.setTransportContext(getPeerCertificates());
} }
super.doConsume(command); super.doConsume(command);
@ -315,10 +339,13 @@ public class NIOSSLTransport extends NIOTransport {
X509Certificate[] clientCertChain = null; X509Certificate[] clientCertChain = null;
try { try {
if (sslSession != null) { if (sslEngine.getSession() != null) {
clientCertChain = (X509Certificate[])sslSession.getPeerCertificates(); clientCertChain = (X509Certificate[]) sslEngine.getSession().getPeerCertificates();
} }
} catch (SSLPeerUnverifiedException e) { } catch (SSLPeerUnverifiedException e) {
if (LOG.isTraceEnabled()) {
LOG.trace("Failed to get peer certificates.", e);
}
} }
return clientCertChain; return clientCertChain;