mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 02:55:50 +00:00
Handshake detection wrappers
This commit is contained in:
@@ -75,6 +75,8 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_PeerRole.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_TransferCall.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\beast_asio.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\beast_HandshakeDetectorType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\beast_StreamHandshakeDetectorType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\beast_ProxyHandshake.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_Socket.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SharedSocket.h" />
|
||||
@@ -306,6 +308,12 @@
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\beast_asio.cpp" />
|
||||
<ClCompile Include="..\..\modules\beast_asio\protocol\beast_StreamHandshakeDetectorType.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\protocol\beast_ProxyHandshake.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
|
||||
@@ -842,6 +842,12 @@
|
||||
<ClInclude Include="..\..\modules\beast_core\memory\beast_ByteSwap.h">
|
||||
<Filter>beast_core\memory</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\beast_HandshakeDetectorType.h">
|
||||
<Filter>beast_asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\beast_StreamHandshakeDetectorType.h">
|
||||
<Filter>beast_asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">
|
||||
@@ -1303,6 +1309,9 @@
|
||||
<ClCompile Include="..\..\modules\beast_asio\basics\beast_PeerRole.cpp">
|
||||
<Filter>beast_asio\basics</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\protocol\beast_StreamHandshakeDetectorType.cpp">
|
||||
<Filter>beast_asio\protocol</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="..\..\TODO.txt" />
|
||||
|
||||
@@ -91,10 +91,13 @@ private:
|
||||
std::vector <Buffer> m_buffers;
|
||||
};
|
||||
|
||||
typedef boost::asio::const_buffer ConstBuffer;
|
||||
typedef boost::asio::mutable_buffer MutableBuffer;
|
||||
|
||||
/** Meets the requirements of ConstBufferSequence */
|
||||
typedef BufferType <boost::asio::const_buffer> ConstBuffers;
|
||||
typedef BufferType <ConstBuffer> ConstBuffers;
|
||||
|
||||
/** Meets the requirements of MutableBufferSequence */
|
||||
typedef BufferType <boost::asio::mutable_buffer> MutableBuffers;
|
||||
typedef BufferType <MutableBuffer> MutableBuffers;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace beast
|
||||
#include "sockets/beast_SslContext.cpp"
|
||||
|
||||
#include "protocol/beast_ProxyHandshake.cpp"
|
||||
#include "protocol/beast_StreamHandshakeDetectorType.cpp"
|
||||
|
||||
#include "tests/beast_TestPeerBasics.cpp"
|
||||
#include "tests/beast_TestPeerLogic.cpp"
|
||||
|
||||
@@ -63,6 +63,8 @@ namespace beast
|
||||
#include "sockets/beast_SslContext.h"
|
||||
|
||||
#include "protocol/beast_ProxyHandshake.h"
|
||||
#include "protocol/beast_HandshakeDetectorType.h"
|
||||
#include "protocol/beast_StreamHandshakeDetectorType.h"
|
||||
|
||||
#include "tests/beast_TestPeerBasics.h"
|
||||
#include "tests/beast_TestPeer.h"
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_HANDSHAKEDETECTORTYPE_H_INCLUDED
|
||||
#define BEAST_HANDSHAKEDETECTORTYPE_H_INCLUDED
|
||||
|
||||
class DetectPolicy
|
||||
{
|
||||
public:
|
||||
DetectPolicy ()
|
||||
: m_finished (false)
|
||||
, m_success (false)
|
||||
{
|
||||
}
|
||||
|
||||
/** Returns the minimum number of bytes we need to succeed.
|
||||
*/
|
||||
virtual std::size_t needed () = 0;
|
||||
|
||||
/** Returns true if the return value of success() is valid.
|
||||
*/
|
||||
bool finished () const noexcept
|
||||
{
|
||||
return m_finished;
|
||||
}
|
||||
|
||||
/** Returns true if the buffers matched the Handshake
|
||||
*/
|
||||
bool success () const noexcept
|
||||
{
|
||||
bassert (m_finished);
|
||||
return m_success;
|
||||
}
|
||||
|
||||
protected:
|
||||
void conclude (bool success = true)
|
||||
{
|
||||
m_finished = true;
|
||||
m_success = success;
|
||||
}
|
||||
|
||||
void fail ()
|
||||
{
|
||||
conclude (false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/** Represents a small, fixed size buffer.
|
||||
This provides a convenient interface for doing a bytewise
|
||||
verification/reject test on a handshake protocol.
|
||||
*/
|
||||
template <int Bytes>
|
||||
struct Input
|
||||
{
|
||||
template <typename ConstBufferSequence>
|
||||
explicit Input (ConstBufferSequence const& buffer)
|
||||
: m_buffer (boost::asio::buffer (m_storage))
|
||||
, m_size (boost::asio::buffer_copy (m_buffer, buffer))
|
||||
, m_data (boost::asio::buffer_cast <uint8 const*> (m_buffer))
|
||||
{
|
||||
}
|
||||
#if 0
|
||||
uint8 const* data () const noexcept
|
||||
{
|
||||
return m_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8 operator[] (std::size_t index) const noexcept
|
||||
{
|
||||
bassert (index >= 0 && index < m_size);
|
||||
return m_data [index];
|
||||
}
|
||||
|
||||
bool peek (std::size_t bytes) const noexcept
|
||||
{
|
||||
if (m_size >= bytes)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool peek (T* t) noexcept
|
||||
{
|
||||
std::size_t const bytes = sizeof (T);
|
||||
if (m_size >= bytes)
|
||||
{
|
||||
std::copy (m_data, m_data + bytes, t);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool consume (std::size_t bytes) noexcept
|
||||
{
|
||||
if (m_size >= bytes)
|
||||
{
|
||||
m_data += bytes;
|
||||
m_size -= bytes;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool read (T* t) noexcept
|
||||
{
|
||||
std::size_t const bytes = sizeof (T);
|
||||
if (m_size >= bytes)
|
||||
{
|
||||
//this causes a stack corruption.
|
||||
//std::copy (m_data, m_data + bytes, t);
|
||||
|
||||
memcpy (t, m_data, bytes);
|
||||
m_data += bytes;
|
||||
m_size -= bytes;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reads an integraltype in network byte order
|
||||
template <typename IntegerType>
|
||||
bool readNetworkInteger (IntegerType* value)
|
||||
{
|
||||
// Must be an integral type!
|
||||
// not available in all versions of std:: unfortunately
|
||||
//static_bassert (std::is_integral <IntegerType>::value);
|
||||
IntegerType networkValue;
|
||||
if (! read (&networkValue))
|
||||
return;
|
||||
*value = fromNetworkByteOrder (networkValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::array <uint8, Bytes> m_storage;
|
||||
MutableBuffer m_buffer;
|
||||
std::size_t m_size;
|
||||
uint8 const* m_data;
|
||||
};
|
||||
|
||||
private:
|
||||
bool m_finished;
|
||||
bool m_success;
|
||||
};
|
||||
|
||||
// Handshake for SSL 2
|
||||
//
|
||||
// http://tools.ietf.org/html/rfc5246#appendix-E.2
|
||||
//
|
||||
// uint8 V2CipherSpec[3];
|
||||
// struct {
|
||||
// uint16 msg_length;
|
||||
// uint8 msg_type;
|
||||
// Version version; Should be 'ProtocolVersion'?
|
||||
// uint16 cipher_spec_length;
|
||||
// uint16 session_id_length;
|
||||
// uint16 challenge_length;
|
||||
// ...
|
||||
//
|
||||
class SSL2 : public DetectPolicy
|
||||
{
|
||||
public:
|
||||
typedef int arg_type;
|
||||
|
||||
explicit SSL2 (arg_type const&)
|
||||
{
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
bytesNeeded = 3
|
||||
};
|
||||
|
||||
std::size_t needed ()
|
||||
{
|
||||
return bytesNeeded;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
void analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
Input <bytesNeeded> in (buffer);
|
||||
|
||||
{
|
||||
uint8 byte;
|
||||
if (! in.peek (&byte))
|
||||
return;
|
||||
|
||||
// First byte must have the high bit set
|
||||
//
|
||||
if((byte & 0x80) != 0x80)
|
||||
return fail ();
|
||||
}
|
||||
|
||||
// The remaining bits contain the
|
||||
// length of the following data in bytes.
|
||||
//
|
||||
uint16 msg_length;
|
||||
if (! in.readNetworkInteger(&msg_length))
|
||||
return;
|
||||
|
||||
// sizeof (msg_type +
|
||||
// Version (ProtcolVersion?) +
|
||||
// cipher_spec_length +
|
||||
// session_id_length +
|
||||
// challenge_length)
|
||||
//
|
||||
// Should be 9 or greater.
|
||||
//
|
||||
if (msg_length < 9)
|
||||
return fail ();
|
||||
|
||||
uint8 msg_type;
|
||||
if (! in.read (&msg_type))
|
||||
return;
|
||||
|
||||
// The msg_type must be 0x01 for a version 2 ClientHello
|
||||
//
|
||||
if (msg_type != 0x01)
|
||||
return fail ();
|
||||
|
||||
conclude ();
|
||||
}
|
||||
};
|
||||
|
||||
// Handshake for SSL 3 (Also TLS 1.0 and 1.1)
|
||||
//
|
||||
// http://www.ietf.org/rfc/rfc2246.txt
|
||||
//
|
||||
// Section 7.4. Handshake protocol
|
||||
//
|
||||
class SSL3 : public DetectPolicy
|
||||
{
|
||||
public:
|
||||
typedef int arg_type; // dummy
|
||||
|
||||
explicit SSL3 (arg_type const&)
|
||||
{
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
bytesNeeded = 6
|
||||
};
|
||||
|
||||
std::size_t needed ()
|
||||
{
|
||||
return bytesNeeded;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
void analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
uint16 version;
|
||||
Input <bytesNeeded> in (buffer);
|
||||
|
||||
uint8 msg_type;
|
||||
if (! in.read (&msg_type))
|
||||
return;
|
||||
|
||||
// msg_type must be 0x16 = "SSL Handshake"
|
||||
//
|
||||
if (msg_type != 0x16)
|
||||
return fail ();
|
||||
|
||||
if (! in.read (&version))
|
||||
return;
|
||||
version = fromNetworkByteOrder (version);
|
||||
|
||||
uint16 length;
|
||||
if (! in.read (&length))
|
||||
return;
|
||||
|
||||
length = fromNetworkByteOrder (length);
|
||||
|
||||
conclude ();
|
||||
}
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
template <typename Logic>
|
||||
class HandshakeDetectorType
|
||||
{
|
||||
public:
|
||||
typedef typename Logic::arg_type arg_type;
|
||||
|
||||
explicit HandshakeDetectorType (arg_type const& arg = arg_type ())
|
||||
: m_logic (arg)
|
||||
{
|
||||
}
|
||||
|
||||
std::size_t needed () noexcept
|
||||
{
|
||||
return m_logic.needed ();
|
||||
}
|
||||
|
||||
bool finished () noexcept
|
||||
{
|
||||
return m_logic.finished ();
|
||||
}
|
||||
|
||||
/** If finished is true, this tells us if the handshake was detected.
|
||||
*/
|
||||
bool success () noexcept
|
||||
{
|
||||
return m_logic.success ();
|
||||
}
|
||||
|
||||
/** Analyze the buffer to match the Handshake.
|
||||
Returns `true` if the analysis is complete.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
bool analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
bassert (! m_logic.finished ());
|
||||
m_logic.analyze (buffer);
|
||||
return m_logic.finished ();
|
||||
}
|
||||
|
||||
private:
|
||||
Logic m_logic;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_STREAMHANDSHAKEDETECTORTYPE_H_INCLUDED
|
||||
#define BEAST_STREAMHANDSHAKEDETECTORTYPE_H_INCLUDED
|
||||
|
||||
/** Wraps a HandshakeDetector and does the work on the Socket for you.
|
||||
*/
|
||||
template <class Detector>
|
||||
class StreamHandshakeDetectorType
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
typedef StreamHandshakeDetectorType <Detector> This;
|
||||
|
||||
public:
|
||||
typedef typename Detector::arg_type arg_type;
|
||||
|
||||
explicit StreamHandshakeDetectorType (arg_type const& arg = arg_type ())
|
||||
{
|
||||
}
|
||||
|
||||
template <typename HandshakeHandler>
|
||||
void async_handshake (Socket& socket, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
||||
{
|
||||
#if 0
|
||||
std::size_t const bytes = m_detector.needed ();
|
||||
#if 1
|
||||
boost::asio::async_read (socket, m_buffer.prepare (bytes), boost::bind (
|
||||
&This::on_read <typename HandshakeHandler>, this, &socket,
|
||||
handler,
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
#else
|
||||
boost::asio::async_read (socket, m_buffer.prepare (bytes), boost::bind (
|
||||
&This::on_read2, this,
|
||||
boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename HandshakeHandler>
|
||||
void on_read (Socket* socket, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler,
|
||||
error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
m_buffer.commit (bytes_transferred);
|
||||
|
||||
if (m_detector.analyze (m_buffer.data ()))
|
||||
{
|
||||
if (m_detector.success ())
|
||||
{
|
||||
//socket->async_handshake (Socket::server, m_buffer.data (), handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Detector m_detector;
|
||||
boost::asio::streambuf m_buffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -51,10 +51,14 @@
|
||||
#include <boost/version.hpp>
|
||||
#if (BOOST_VERSION / 100) >= 1054
|
||||
# define BEAST_ASIO_HAS_BUFFEREDHANDSHAKE 1
|
||||
# define BEAST_ASIO_HAS_FUTURE_RETURNS 1
|
||||
# ifndef BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
# define BEAST_ASIO_HAS_FUTURE_RETURNS 1
|
||||
# endif
|
||||
#else
|
||||
# define BEAST_ASIO_HAS_BUFFEREDHANDSHAKE 0
|
||||
# define BEAST_ASIO_HAS_FUTURE_RETURNS 0
|
||||
# ifndef BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
# define BEAST_ASIO_HAS_FUTURE_RETURNS 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ! BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
|
||||
@@ -34,4 +34,3 @@ void TestPeerLogicProxyClient::on_pre_handshake ()
|
||||
std::size_t const amount = boost::asio::write (
|
||||
socket (), boost::asio::buffer (line), error ());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user