Search in sources :

Example 1 with GridClientHandshakeRequest

use of org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest in project ignite by apache.

the class TcpRestUnmarshalVulnerabilityTest method attack.

/**
 * @param data Data.
 */
private void attack(byte[] data) throws IOException {
    InetAddress addr = InetAddress.getByName(host);
    try (Socket sock = new Socket(addr, port);
        OutputStream os = new BufferedOutputStream(sock.getOutputStream())) {
        // Handshake request.
        os.write(IGNITE_HANDSHAKE_FLAG);
        GridClientHandshakeRequest req = new GridClientHandshakeRequest();
        req.marshallerId(GridClientJdkMarshaller.ID);
        os.write(req.rawBytes());
        os.flush();
        // Handshake response
        InputStream is = new BufferedInputStream(sock.getInputStream());
        // Read handshake response.
        is.read(new byte[146]);
        int len = data.length + 40;
        // Package type.
        os.write(IGNITE_REQ_FLAG);
        // Package length.
        os.write((byte) (len >> 24));
        os.write((byte) (len >> 16));
        os.write((byte) (len >> 8));
        os.write((byte) (len));
        // Stream header.
        os.write(new byte[40]);
        // Exploit.
        os.write(data);
        os.flush();
    }
}
Also used : GridClientHandshakeRequest(org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest) BufferedInputStream(java.io.BufferedInputStream) BufferedInputStream(java.io.BufferedInputStream) ObjectInputStream(java.io.ObjectInputStream) InputStream(java.io.InputStream) BufferedOutputStream(java.io.BufferedOutputStream) OutputStream(java.io.OutputStream) InetAddress(java.net.InetAddress) BufferedOutputStream(java.io.BufferedOutputStream) Socket(java.net.Socket)

Example 2 with GridClientHandshakeRequest

use of org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest in project ignite by apache.

the class GridTcpRouterNioListenerAdapter method onMessage.

/**
 * {@inheritDoc}
 */
@SuppressWarnings("TypeMayBeWeakened")
@Override
public void onMessage(final GridNioSession ses, final GridClientMessage msg) {
    if (msg instanceof GridRouterRequest) {
        GridRouterRequest routerMsg = (GridRouterRequest) msg;
        final UUID clientId = routerMsg.clientId();
        final long reqId = routerMsg.requestId();
        try {
            client.forwardMessage(routerMsg, routerMsg.destinationId(), ses.<Byte>meta(MARSHALLER_ID.ordinal())).listen(new GridClientFutureListener() {

                @Override
                public void onDone(GridClientFuture fut) {
                    try {
                        GridRouterResponse res = (GridRouterResponse) fut.get();
                        // Restoring original request id, because it was overwritten by the client.
                        res.requestId(reqId);
                        ses.send(res);
                    } catch (GridClientException e) {
                        ses.send(makeFailureResponse(e, clientId, reqId));
                    }
                }
            });
        } catch (GridClientException e) {
            ses.send(makeFailureResponse(e, clientId, reqId));
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            U.warn(log, "Message forwarding was interrupted (will ignore last message): " + e.getMessage());
        }
    } else if (msg instanceof GridClientHandshakeRequest) {
        GridClientHandshakeRequest hs = (GridClientHandshakeRequest) msg;
        short ver = hs.version();
        if (!SUPP_VERS.contains(ver)) {
            U.error(log, "Client protocol version is not supported [ses=" + ses + ", ver=" + ver + ", supported=" + SUPP_VERS + ']');
            ses.close();
        } else {
            byte marshId = hs.marshallerId();
            GridClientMarshaller marsh = marshMap.get(marshId);
            if (marsh == null) {
                U.error(log, "Client marshaller ID is invalid. Note that .NET and C++ clients " + "are supported only in enterprise edition [ses=" + ses + ", marshId=" + marshId + ']');
                ses.close();
            } else {
                ses.addMeta(MARSHALLER_ID.ordinal(), marshId);
                ses.addMeta(MARSHALLER.ordinal(), marsh);
                ses.send(GridClientHandshakeResponse.OK);
            }
        }
    } else if (msg instanceof GridClientPingPacket)
        ses.send(GridClientPingPacket.PING_MESSAGE);
    else
        throw new IllegalArgumentException("Unsupported input message: " + msg);
}
Also used : GridClientException(org.apache.ignite.internal.client.GridClientException) GridClientFuture(org.apache.ignite.internal.client.GridClientFuture) GridRouterResponse(org.apache.ignite.internal.processors.rest.client.message.GridRouterResponse) GridClientMarshaller(org.apache.ignite.internal.client.marshaller.GridClientMarshaller) GridRouterRequest(org.apache.ignite.internal.processors.rest.client.message.GridRouterRequest) GridClientPingPacket(org.apache.ignite.internal.processors.rest.client.message.GridClientPingPacket) GridClientFutureListener(org.apache.ignite.internal.client.GridClientFutureListener) GridClientHandshakeRequest(org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest) UUID(java.util.UUID)

Example 3 with GridClientHandshakeRequest

use of org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest in project ignite by apache.

the class TcpRestParserSelfTest method testParseClientHandshake.

/**
 * Tests correct parsing of client handshake packets.
 *
 * @throws Exception If failed.
 */
@Test
public void testParseClientHandshake() throws Exception {
    for (int splitPos = 1; splitPos < 5; splitPos++) {
        log.info("Checking split position: " + splitPos);
        ByteBuffer tmp = clientHandshakePacket();
        ByteBuffer[] split = split(tmp, splitPos);
        GridNioSession ses = new MockNioSession();
        ses.addMeta(MARSHALLER.ordinal(), new GridClientOptimizedMarshaller());
        GridTcpRestParser parser = new GridTcpRestParser(false);
        Collection<GridClientMessage> lst = new ArrayList<>(1);
        for (ByteBuffer buf : split) {
            GridClientMessage r;
            while (buf.hasRemaining() && (r = parser.decode(ses, buf)) != null) lst.add(r);
            assertTrue("Parser has left unparsed bytes.", buf.remaining() == 0);
        }
        assertEquals(1, lst.size());
        GridClientHandshakeRequest req = (GridClientHandshakeRequest) F.first(lst);
        assertNotNull(req);
        assertEquals(U.bytesToShort(new byte[] { 5, 0 }, 0), req.version());
    }
}
Also used : MockNioSession(org.apache.ignite.internal.util.nio.impl.MockNioSession) GridClientHandshakeRequest(org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest) GridNioSession(org.apache.ignite.internal.util.nio.GridNioSession) GridClientOptimizedMarshaller(org.apache.ignite.internal.client.marshaller.optimized.GridClientOptimizedMarshaller) ArrayList(java.util.ArrayList) ByteBuffer(java.nio.ByteBuffer) GridClientMessage(org.apache.ignite.internal.processors.rest.client.message.GridClientMessage) GridCommonAbstractTest(org.apache.ignite.testframework.junits.common.GridCommonAbstractTest) Test(org.junit.Test)

Example 4 with GridClientHandshakeRequest

use of org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest in project ignite by apache.

the class GridTcpRestNioListener method onMessage.

/**
 * {@inheritDoc}
 */
@Override
public void onMessage(final GridNioSession ses, final GridClientMessage msg) {
    if (msg instanceof GridMemcachedMessage)
        memcachedLsnr.onMessage(ses, (GridMemcachedMessage) msg);
    else if (msg instanceof GridRedisMessage)
        redisLsnr.onMessage(ses, (GridRedisMessage) msg);
    else if (msg instanceof GridClientPingPacket)
        ses.send(msg);
    else if (msg instanceof GridClientHandshakeRequest) {
        GridClientHandshakeRequest hs = (GridClientHandshakeRequest) msg;
        short ver = hs.version();
        if (!SUPP_VERS.contains(ver)) {
            U.error(log, "Client protocol version is not supported [ses=" + ses + ", ver=" + ver + ", supported=" + SUPP_VERS + ']');
            onSessionClosed(ses);
        } else {
            byte marshId = hs.marshallerId();
            if (marshMapLatch.getCount() > 0) {
                try {
                    U.await(marshMapLatch);
                } catch (IgniteInterruptedCheckedException e) {
                    U.error(log, "Marshaller is not initialized.", e);
                    onSessionClosed(ses);
                    return;
                }
            }
            GridClientMarshaller marsh = marshMap.get(marshId);
            if (marsh == null) {
                U.error(log, "Client marshaller ID is invalid. Note that .NET and C++ clients " + "are supported only in enterprise edition [ses=" + ses + ", marshId=" + marshId + ']');
                onSessionClosed(ses);
            } else {
                ses.addMeta(MARSHALLER.ordinal(), marsh);
                ses.send(GridClientHandshakeResponse.OK);
            }
        }
    } else {
        final GridRestRequest req = createRestRequest(ses, msg);
        if (req != null) {
            IgniteInternalFuture<GridRestResponse> taskFut = hnd.handleAsync(req);
            if (isInterruptible(msg))
                addFutureToSession(ses, taskFut);
            taskFut.listen(new CI1<IgniteInternalFuture<GridRestResponse>>() {

                @Override
                public void apply(IgniteInternalFuture<GridRestResponse> fut) {
                    removeFutureFromSession(ses, taskFut);
                    GridClientResponse res = new GridClientResponse();
                    res.requestId(msg.requestId());
                    res.clientId(msg.clientId());
                    try {
                        GridRestResponse restRes = fut.get();
                        res.sessionToken(restRes.sessionTokenBytes());
                        res.successStatus(restRes.getSuccessStatus());
                        res.errorMessage(restRes.getError());
                        Object o = restRes.getResponse();
                        // In case of metrics a little adjustment is needed.
                        if (o instanceof GridCacheRestMetrics)
                            o = ((GridCacheRestMetrics) o).map();
                        res.result(o);
                    } catch (IgniteCheckedException e) {
                        U.error(log, "Failed to process client request: " + msg, e);
                        res.successStatus(GridClientResponse.STATUS_FAILED);
                        res.errorMessage("Failed to process client request: " + e.getMessage());
                    }
                    GridNioFuture<?> sf = ses.send(res);
                    // Check if send failed.
                    sf.listen(new CI1<IgniteInternalFuture<?>>() {

                        @Override
                        public void apply(IgniteInternalFuture<?> fut) {
                            try {
                                fut.get();
                            } catch (IgniteCheckedException e) {
                                U.error(log, "Failed to process client request [ses=" + ses + ", msg=" + msg + ']', e);
                            }
                        }
                    });
                }
            });
        } else
            U.error(log, "Failed to process client request (unknown packet type) [ses=" + ses + ", msg=" + msg + ']');
    }
}
Also used : GridClientResponse(org.apache.ignite.internal.processors.rest.client.message.GridClientResponse) GridClientMarshaller(org.apache.ignite.internal.client.marshaller.GridClientMarshaller) CI1(org.apache.ignite.internal.util.typedef.CI1) GridClientPingPacket(org.apache.ignite.internal.processors.rest.client.message.GridClientPingPacket) GridRedisMessage(org.apache.ignite.internal.processors.rest.protocols.tcp.redis.GridRedisMessage) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) GridClientHandshakeRequest(org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridRestResponse(org.apache.ignite.internal.processors.rest.GridRestResponse) GridCacheRestMetrics(org.apache.ignite.internal.processors.rest.handlers.cache.GridCacheRestMetrics) GridRestRequest(org.apache.ignite.internal.processors.rest.request.GridRestRequest)

Example 5 with GridClientHandshakeRequest

use of org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest in project ignite by apache.

the class GridTcpRestParser method parseHandshake.

/**
 * Parses a client handshake, checking a client version and
 * reading the marshaller protocol ID.
 *
 * @param buf Message bytes.
 * @param state Parser state.
 * @return True if a hint was parsed, false if still need more bytes to parse.
 */
@Nullable
private GridClientMessage parseHandshake(ByteBuffer buf, ParserState state) {
    assert state.packetType() == GridClientPacketType.IGNITE_HANDSHAKE;
    int idx = state.index();
    GridClientHandshakeRequest packet = (GridClientHandshakeRequest) state.packet();
    if (packet == null) {
        packet = new GridClientHandshakeRequest();
        state.packet(packet);
    }
    int rem = buf.remaining();
    if (rem > 0) {
        // Buffer to read data to.
        byte[] bbuf = new byte[5];
        // Number of bytes to read.
        int nRead = Math.min(rem, bbuf.length);
        // Batch read from buffer.
        buf.get(bbuf, 0, nRead);
        // Number of available bytes.
        int nAvailable = nRead;
        if (idx < 4) {
            // Need to read version bytes.
            // Number of version bytes available in buffer.
            int len = Math.min(nRead, 4 - idx);
            packet.putBytes(bbuf, idx, len);
            idx += len;
            state.index(idx);
            nAvailable -= len;
        }
        assert idx <= 4 : "Wrong idx: " + idx;
        assert nAvailable == 0 || nAvailable == 1 : "Wrong nav: " + nAvailable;
        if (idx == 4 && nAvailable > 0)
            return packet;
    }
    // Wait for more data.
    return null;
}
Also used : GridClientHandshakeRequest(org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest) Nullable(org.jetbrains.annotations.Nullable)

Aggregations

GridClientHandshakeRequest (org.apache.ignite.internal.processors.rest.client.message.GridClientHandshakeRequest)5 GridClientMarshaller (org.apache.ignite.internal.client.marshaller.GridClientMarshaller)2 GridClientPingPacket (org.apache.ignite.internal.processors.rest.client.message.GridClientPingPacket)2 BufferedInputStream (java.io.BufferedInputStream)1 BufferedOutputStream (java.io.BufferedOutputStream)1 InputStream (java.io.InputStream)1 ObjectInputStream (java.io.ObjectInputStream)1 OutputStream (java.io.OutputStream)1 InetAddress (java.net.InetAddress)1 Socket (java.net.Socket)1 ByteBuffer (java.nio.ByteBuffer)1 ArrayList (java.util.ArrayList)1 UUID (java.util.UUID)1 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)1 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)1 IgniteInterruptedCheckedException (org.apache.ignite.internal.IgniteInterruptedCheckedException)1 GridClientException (org.apache.ignite.internal.client.GridClientException)1 GridClientFuture (org.apache.ignite.internal.client.GridClientFuture)1 GridClientFutureListener (org.apache.ignite.internal.client.GridClientFutureListener)1 GridClientOptimizedMarshaller (org.apache.ignite.internal.client.marshaller.optimized.GridClientOptimizedMarshaller)1