protected BufferChain wrapWithSasl(BufferChain bc) throws IOException { if (!this.connection.useSasl) return bc; // Looks like no way around this; saslserver wants a byte array. I have to make it one. // THIS IS A BIG UGLY COPY. byte [] responseBytes = bc.getBytes(); byte [] token; // synchronization may be needed since there can be multiple Handler // threads using saslServer or Crypto AES to wrap responses. if (connection.useCryptoAesWrap) { // wrap with Crypto AES synchronized (connection.cryptoAES) { token = connection.cryptoAES.wrap(responseBytes, 0, responseBytes.length); } } else { synchronized (connection.saslServer) { token = connection.saslServer.wrap(responseBytes, 0, responseBytes.length); } } if (RpcServer.LOG.isTraceEnabled()) { RpcServer.LOG.trace("Adding saslServer wrapped token of size " + token.length + " as call response."); } ByteBuffer[] responseBufs = new ByteBuffer[2]; responseBufs[0] = ByteBuffer.wrap(Bytes.toBytes(token.length)); responseBufs[1] = ByteBuffer.wrap(token); return new BufferChain(responseBufs); }
/** * No protobuf encoding of raw sasl messages */ protected final void doRawSaslReply(SaslStatus status, Writable rv, String errorClass, String error) throws IOException { BufferChain bc; // In my testing, have noticed that sasl messages are usually // in the ballpark of 100-200. That's why the initial capacity is 256. try (ByteBufferOutputStream saslResponse = new ByteBufferOutputStream(256); DataOutputStream out = new DataOutputStream(saslResponse)) { out.writeInt(status.state); // write status if (status == SaslStatus.SUCCESS) { rv.write(out); } else { WritableUtils.writeString(out, errorClass); WritableUtils.writeString(out, error); } bc = new BufferChain(saslResponse.getByteBuffer()); } doRespond(() -> bc); }
protected final RpcResponse getErrorResponse(String msg, Exception e) throws IOException { ResponseHeader.Builder headerBuilder = ResponseHeader.newBuilder().setCallId(-1); ServerCall.setExceptionResponse(e, msg, headerBuilder); ByteBuffer headerBuf = ServerCall.createHeaderAndMessageBytes(null, headerBuilder.build(), 0, null); BufferChain buf = new BufferChain(headerBuf); return () -> buf; }
/** * Send the response for connection header */ private void responseConnectionHeader(RPCProtos.ConnectionHeaderResponse.Builder chrBuilder) throws FatalConnectionException { // Response the connection header if Crypto AES is enabled if (!chrBuilder.hasCryptoCipherMeta()) return; try { byte[] connectionHeaderResBytes = chrBuilder.build().toByteArray(); // encrypt the Crypto AES cipher meta data with sasl server, and send to client byte[] unwrapped = new byte[connectionHeaderResBytes.length + 4]; Bytes.putBytes(unwrapped, 0, Bytes.toBytes(connectionHeaderResBytes.length), 0, 4); Bytes.putBytes(unwrapped, 4, connectionHeaderResBytes, 0, connectionHeaderResBytes.length); byte[] wrapped = saslServer.wrap(unwrapped, 0, unwrapped.length); BufferChain bc; try (ByteBufferOutputStream response = new ByteBufferOutputStream(wrapped.length + 4); DataOutputStream out = new DataOutputStream(response)) { out.writeInt(wrapped.length); out.write(wrapped); bc = new BufferChain(response.getByteBuffer()); } doRespond(() -> bc); } catch (IOException ex) { throw new UnsupportedCryptoException(ex.getMessage(), ex); } }
@Test public void testGetBackBytesWePutIn() { ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS); BufferChain chain = new BufferChain(bufs); assertTrue(Bytes.equals(Bytes.toBytes("hello world"), chain.getBytes())); }
bc = new BufferChain(responseBufs); if (connection.useWrap) { bc = wrapWithSasl(bc);
@Test public void testChainChunkBiggerThanWholeArray() throws IOException { ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS); BufferChain chain = new BufferChain(bufs); writeAndVerify(chain, "hello world", 8192); assertNoRemaining(bufs); }
@Test public void testChainChunkBiggerThanSomeArrays() throws IOException { ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS); BufferChain chain = new BufferChain(bufs); writeAndVerify(chain, "hello world", 3); assertNoRemaining(bufs); }
@Test public void testLimitOffset() throws IOException { ByteBuffer[] bufs = new ByteBuffer[] { stringBuf("XXXhelloYYY", 3, 5), stringBuf(" ", 0, 1), stringBuf("XXXXworldY", 4, 5) }; BufferChain chain = new BufferChain(bufs); writeAndVerify(chain , "hello world", 3); assertNoRemaining(bufs); }
@Test public void testWithSpy() throws IOException { ByteBuffer[] bufs = new ByteBuffer[] { stringBuf("XXXhelloYYY", 3, 5), stringBuf(" ", 0, 1), stringBuf("XXXXworldY", 4, 5) }; BufferChain chain = new BufferChain(bufs); FileOutputStream fos = new FileOutputStream(tmpFile); FileChannel ch = Mockito.spy(fos.getChannel()); try { chain.write(ch, 2); assertEquals("he", Files.toString(tmpFile, Charsets.UTF_8)); chain.write(ch, 2); assertEquals("hell", Files.toString(tmpFile, Charsets.UTF_8)); chain.write(ch, 3); assertEquals("hello w", Files.toString(tmpFile, Charsets.UTF_8)); chain.write(ch, 8); assertEquals("hello world", Files.toString(tmpFile, Charsets.UTF_8)); } finally { ch.close(); fos.close(); } }
protected synchronized void setSaslTokenResponse(ByteBuffer response) { this.response = new BufferChain(response); }
private BufferChain wrapWithSasl(BufferChain bc) throws IOException { if (!this.connection.useSasl) return bc; // Looks like no way around this; saslserver wants a byte array. I have to make it one. // THIS IS A BIG UGLY COPY. byte [] responseBytes = bc.getBytes(); byte [] token; // synchronization may be needed since there can be multiple Handler // threads using saslServer to wrap responses. synchronized (connection.saslServer) { token = connection.saslServer.wrap(responseBytes, 0, responseBytes.length); } if (LOG.isTraceEnabled()) { LOG.trace("Adding saslServer wrapped token of size " + token.length + " as call response."); } ByteBuffer bbTokenLength = ByteBuffer.wrap(Bytes.toBytes(token.length)); ByteBuffer bbTokenBytes = ByteBuffer.wrap(token); return new BufferChain(bbTokenLength, bbTokenBytes); }
@Test public void testGetBackBytesWePutIn() { ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS); BufferChain chain = new BufferChain(bufs); assertTrue(Bytes.equals(Bytes.toBytes("hello world"), chain.getBytes())); }
@Test public void testChainChunkBiggerThanWholeArray() throws IOException { ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS); BufferChain chain = new BufferChain(bufs); writeAndVerify(chain, "hello world", 8192); assertNoRemaining(bufs); }
@Test public void testChainChunkBiggerThanSomeArrays() throws IOException { ByteBuffer[] bufs = wrapArrays(HELLO_WORLD_CHUNKS); BufferChain chain = new BufferChain(bufs); writeAndVerify(chain, "hello world", 3); assertNoRemaining(bufs); }
(this.cellBlock == null? 0: this.cellBlock.limit()); ByteBuffer bbTotalSize = ByteBuffer.wrap(Bytes.toBytes(totalSize)); bc = new BufferChain(bbTotalSize, bbHeader, bbResult, this.cellBlock); if (connection.useWrap) { bc = wrapWithSasl(bc);
@Test public void testLimitOffset() throws IOException { ByteBuffer[] bufs = new ByteBuffer[] { stringBuf("XXXhelloYYY", 3, 5), stringBuf(" ", 0, 1), stringBuf("XXXXworldY", 4, 5) }; BufferChain chain = new BufferChain(bufs); writeAndVerify(chain , "hello world", 3); assertNoRemaining(bufs); }
@Test public void testWithSpy() throws IOException { ByteBuffer[] bufs = new ByteBuffer[] { stringBuf("XXXhelloYYY", 3, 5), stringBuf(" ", 0, 1), stringBuf("XXXXworldY", 4, 5) }; BufferChain chain = new BufferChain(bufs); FileOutputStream fos = new FileOutputStream(tmpFile); FileChannel ch = Mockito.spy(fos.getChannel()); try { chain.write(ch, 2); assertEquals("he", Files.toString(tmpFile, Charsets.UTF_8)); chain.write(ch, 2); assertEquals("hell", Files.toString(tmpFile, Charsets.UTF_8)); chain.write(ch, 3); assertEquals("hello w", Files.toString(tmpFile, Charsets.UTF_8)); chain.write(ch, 8); assertEquals("hello world", Files.toString(tmpFile, Charsets.UTF_8)); } finally { ch.close(); fos.close(); } }