예제 #1
0
  private void wrap(ChannelHandlerContext ctx, boolean inUnwrap) throws SSLException {
    ByteBuf out = null;
    ChannelPromise promise = null;
    ByteBufAllocator alloc = ctx.alloc();
    try {
      for (; ; ) {
        Object msg = pendingUnencryptedWrites.current();
        if (msg == null) {
          break;
        }

        ByteBuf buf = (ByteBuf) msg;
        if (out == null) {
          out = allocateOutNetBuf(ctx, buf.readableBytes());
        }

        SSLEngineResult result = wrap(alloc, engine, buf, out);
        if (!buf.isReadable()) {
          promise = pendingUnencryptedWrites.remove();
        } else {
          promise = null;
        }

        if (result.getStatus() == Status.CLOSED) {
          // SSLEngine has been closed already.
          // Any further write attempts should be denied.
          pendingUnencryptedWrites.removeAndFailAll(SSLENGINE_CLOSED);
          return;
        } else {
          switch (result.getHandshakeStatus()) {
            case NEED_TASK:
              runDelegatedTasks();
              break;
            case FINISHED:
              setHandshakeSuccess();
              // deliberate fall-through
            case NOT_HANDSHAKING:
              setHandshakeSuccessIfStillHandshaking();
              // deliberate fall-through
            case NEED_WRAP:
              finishWrap(ctx, out, promise, inUnwrap);
              promise = null;
              out = null;
              break;
            case NEED_UNWRAP:
              return;
            default:
              throw new IllegalStateException(
                  "Unknown handshake status: " + result.getHandshakeStatus());
          }
        }
      }
    } catch (SSLException e) {
      setHandshakeFailure(ctx, e);
      throw e;
    } finally {
      finishWrap(ctx, out, promise, inUnwrap);
    }
  }
예제 #2
0
 @Override
 public void handlerRemoved0(ChannelHandlerContext ctx) throws Exception {
   if (!pendingUnencryptedWrites.isEmpty()) {
     // Check if queue is not empty first because create a new ChannelException is expensive
     pendingUnencryptedWrites.removeAndFailAll(
         new ChannelException("Pending write on removal of SslHandler"));
   }
 }
예제 #3
0
 @Override
 public void write(final ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
     throws Exception {
   if (!(msg instanceof ByteBuf)) {
     promise.setFailure(new UnsupportedMessageTypeException(msg, ByteBuf.class));
     return;
   }
   pendingUnencryptedWrites.add(msg, promise);
 }
예제 #4
0
 @Override
 public void flush(ChannelHandlerContext ctx) throws Exception {
   // Do not encrypt the first write request if this handler is
   // created with startTLS flag turned on.
   if (startTls && !sentFirstMessage) {
     sentFirstMessage = true;
     pendingUnencryptedWrites.removeAndWriteAll();
     ctx.flush();
     return;
   }
   if (pendingUnencryptedWrites.isEmpty()) {
     // It's important to NOT use a voidPromise here as the user
     // may want to add a ChannelFutureListener to the ChannelPromise later.
     //
     // See https://github.com/netty/netty/issues/3364
     pendingUnencryptedWrites.add(Unpooled.EMPTY_BUFFER, ctx.newPromise());
   }
   if (!handshakePromise.isDone()) {
     flushedBeforeHandshake = true;
   }
   wrap(ctx, false);
   ctx.flush();
 }
예제 #5
0
  /** Notify all the handshake futures about the failure during the handshake. */
  private void setHandshakeFailure(ChannelHandlerContext ctx, Throwable cause) {
    // Release all resources such as internal buffers that SSLEngine
    // is managing.
    engine.closeOutbound();

    try {
      engine.closeInbound();
    } catch (SSLException e) {
      // only log in debug mode as it most likely harmless and latest chrome still trigger
      // this all the time.
      //
      // See https://github.com/netty/netty/issues/1340
      String msg = e.getMessage();
      if (msg == null || !msg.contains("possible truncation attack")) {
        logger.debug("{} SSLEngine.closeInbound() raised an exception.", ctx.channel(), e);
      }
    }
    notifyHandshakeFailure(cause);
    pendingUnencryptedWrites.removeAndFailAll(cause);
  }