[#915] [#923] Expanded scope of the handshake locks in SSLHandler to avoid possible negotiation after the first SSLEngine wrap
This commit is contained in:
parent
223209864a
commit
ca7702f38c
@ -402,76 +402,75 @@ public class SslHandler extends FrameDecoder
|
|||||||
* succeeds or fails.
|
* succeeds or fails.
|
||||||
*/
|
*/
|
||||||
public ChannelFuture handshake() {
|
public ChannelFuture handshake() {
|
||||||
if (handshaken && !isEnableRenegotiation()) {
|
|
||||||
throw new IllegalStateException("renegotiation disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
final ChannelHandlerContext ctx = this.ctx;
|
|
||||||
final Channel channel = ctx.getChannel();
|
|
||||||
ChannelFuture handshakeFuture;
|
|
||||||
Exception exception = null;
|
|
||||||
|
|
||||||
synchronized (handshakeLock) {
|
synchronized (handshakeLock) {
|
||||||
|
if (handshaken && !isEnableRenegotiation()) {
|
||||||
|
throw new IllegalStateException("renegotiation disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
final ChannelHandlerContext ctx = this.ctx;
|
||||||
|
final Channel channel = ctx.getChannel();
|
||||||
|
ChannelFuture handshakeFuture;
|
||||||
|
Exception exception = null;
|
||||||
|
|
||||||
if (handshaking) {
|
if (handshaking) {
|
||||||
return this.handshakeFuture;
|
return this.handshakeFuture;
|
||||||
} else {
|
|
||||||
handshaking = true;
|
|
||||||
try {
|
|
||||||
engine.beginHandshake();
|
|
||||||
runDelegatedTasks();
|
|
||||||
handshakeFuture = this.handshakeFuture = future(channel);
|
|
||||||
if (handshakeTimeoutInMillis > 0) {
|
|
||||||
handshakeTimeout = timer.newTimeout(new TimerTask() {
|
|
||||||
public void run(Timeout timeout) throws Exception {
|
|
||||||
ChannelFuture future = SslHandler.this.handshakeFuture;
|
|
||||||
if (future != null && future.isDone()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setHandshakeFailure(channel, new SSLException("Handshake did not complete within " +
|
|
||||||
handshakeTimeoutInMillis + "ms"));
|
|
||||||
}
|
|
||||||
}, handshakeTimeoutInMillis, TimeUnit.MILLISECONDS);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
handshakeFuture = this.handshakeFuture = failedFuture(channel, e);
|
|
||||||
exception = e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (exception == null) { // Began handshake successfully.
|
handshaking = true;
|
||||||
try {
|
try {
|
||||||
final ChannelFuture hsFuture = handshakeFuture;
|
engine.beginHandshake();
|
||||||
wrapNonAppData(ctx, channel).addListener(new ChannelFutureListener() {
|
runDelegatedTasks();
|
||||||
public void operationComplete(ChannelFuture future) throws Exception {
|
handshakeFuture = this.handshakeFuture = future(channel);
|
||||||
if (!future.isSuccess()) {
|
if (handshakeTimeoutInMillis > 0) {
|
||||||
Throwable cause = future.getCause();
|
handshakeTimeout = timer.newTimeout(new TimerTask() {
|
||||||
hsFuture.setFailure(cause);
|
public void run(Timeout timeout) throws Exception {
|
||||||
|
ChannelFuture future = SslHandler.this.handshakeFuture;
|
||||||
|
if (future != null && future.isDone()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fireExceptionCaught(ctx, cause);
|
setHandshakeFailure(channel, new SSLException("Handshake did not complete within " +
|
||||||
if (closeOnSSLException) {
|
handshakeTimeoutInMillis + "ms"));
|
||||||
Channels.close(ctx, future(channel));
|
}
|
||||||
|
}, handshakeTimeoutInMillis, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
handshakeFuture = this.handshakeFuture = failedFuture(channel, e);
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exception == null) { // Began handshake successfully.
|
||||||
|
try {
|
||||||
|
final ChannelFuture hsFuture = handshakeFuture;
|
||||||
|
wrapNonAppData(ctx, channel).addListener(new ChannelFutureListener() {
|
||||||
|
public void operationComplete(ChannelFuture future) throws Exception {
|
||||||
|
if (!future.isSuccess()) {
|
||||||
|
Throwable cause = future.getCause();
|
||||||
|
hsFuture.setFailure(cause);
|
||||||
|
|
||||||
|
fireExceptionCaught(ctx, cause);
|
||||||
|
if (closeOnSSLException) {
|
||||||
|
Channels.close(ctx, future(channel));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
});
|
} catch (SSLException e) {
|
||||||
} catch (SSLException e) {
|
handshakeFuture.setFailure(e);
|
||||||
handshakeFuture.setFailure(e);
|
|
||||||
|
|
||||||
fireExceptionCaught(ctx, e);
|
fireExceptionCaught(ctx, e);
|
||||||
|
if (closeOnSSLException) {
|
||||||
|
Channels.close(ctx, future(channel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // Failed to initiate handshake.
|
||||||
|
fireExceptionCaught(ctx, exception);
|
||||||
if (closeOnSSLException) {
|
if (closeOnSSLException) {
|
||||||
Channels.close(ctx, future(channel));
|
Channels.close(ctx, future(channel));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // Failed to initiate handshake.
|
return handshakeFuture;
|
||||||
fireExceptionCaught(ctx, exception);
|
|
||||||
if (closeOnSSLException) {
|
|
||||||
Channels.close(ctx, future(channel));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return handshakeFuture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1282,19 +1281,19 @@ public class SslHandler extends FrameDecoder
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleRenegotiation(HandshakeStatus handshakeStatus) {
|
private void handleRenegotiation(HandshakeStatus handshakeStatus) {
|
||||||
if (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING ||
|
|
||||||
handshakeStatus == HandshakeStatus.FINISHED) {
|
|
||||||
// Not handshaking
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!handshaken) {
|
|
||||||
// Not renegotiation
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final boolean renegotiate;
|
|
||||||
synchronized (handshakeLock) {
|
synchronized (handshakeLock) {
|
||||||
|
if (handshakeStatus == HandshakeStatus.NOT_HANDSHAKING ||
|
||||||
|
handshakeStatus == HandshakeStatus.FINISHED) {
|
||||||
|
// Not handshaking
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handshaken) {
|
||||||
|
// Not renegotiation
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean renegotiate;
|
||||||
if (handshaking) {
|
if (handshaking) {
|
||||||
// Renegotiation in progress or failed already.
|
// Renegotiation in progress or failed already.
|
||||||
// i.e. Renegotiation check has been done already below.
|
// i.e. Renegotiation check has been done already below.
|
||||||
@ -1315,20 +1314,20 @@ public class SslHandler extends FrameDecoder
|
|||||||
// Prevent reentrance of this method.
|
// Prevent reentrance of this method.
|
||||||
handshaking = true;
|
handshaking = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (renegotiate) {
|
if (renegotiate) {
|
||||||
// Renegotiate.
|
// Renegotiate.
|
||||||
handshake();
|
handshake();
|
||||||
} else {
|
} else {
|
||||||
// Raise an exception.
|
// Raise an exception.
|
||||||
fireExceptionCaught(
|
fireExceptionCaught(
|
||||||
ctx, new SSLException(
|
ctx, new SSLException(
|
||||||
"renegotiation attempted by peer; " +
|
"renegotiation attempted by peer; " +
|
||||||
"closing the connection"));
|
"closing the connection"));
|
||||||
|
|
||||||
// Close the connection to stop renegotiation.
|
// Close the connection to stop renegotiation.
|
||||||
Channels.close(ctx, succeededFuture(ctx.getChannel()));
|
Channels.close(ctx, succeededFuture(ctx.getChannel()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user