mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 02:55:50 +00:00
Generic HandshakeDetectStream and HandshakeDetectLogic
This commit is contained in:
@@ -72,19 +72,20 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_BufferType.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_CompletionCall.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_ErrorCall.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_FixedInputBuffer.h" />
|
||||
<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\handshake\beast_HandshakeDetectLogic.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicSSL2.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicSSL3.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectStream.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_ProxyHandshake.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_Socket.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SharedSocket.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketBase.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketInterface.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketWrapper.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SslContext.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\streams\beast_prefilled_read_stream.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\streams\beast_PrefilledReadStream.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\system\beast_BoostIncludes.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeer.h" />
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerBasics.h" />
|
||||
@@ -308,13 +309,7 @@
|
||||
<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">
|
||||
<ClCompile Include="..\..\modules\beast_asio\handshake\beast_ProxyHandshake.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>
|
||||
|
||||
@@ -152,15 +152,15 @@
|
||||
<Filter Include="beast_asio\tests">
|
||||
<UniqueIdentifier>{422da6a1-e57e-4a96-9fce-e5958c16026e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\protocol">
|
||||
<UniqueIdentifier>{c4a7b6bb-88ec-4ff1-bc56-7c432a467500}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\basics">
|
||||
<UniqueIdentifier>{ccdc0c8e-f77a-486e-ba2f-29c10ec97f18}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\streams">
|
||||
<UniqueIdentifier>{dfa79046-33ef-4653-a6f9-83954b76a10f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="beast_asio\handshake">
|
||||
<UniqueIdentifier>{4856837a-fa72-4252-8e8f-a112c1dbb3d2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\modules\beast_core\beast_core.h">
|
||||
@@ -767,15 +767,9 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketWrapper.h">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SharedSocket.h">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_Socket.h">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\sockets\beast_SocketInterface.h">
|
||||
<Filter>beast_asio\sockets</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\system\beast_BoostIncludes.h">
|
||||
<Filter>beast_asio\system</Filter>
|
||||
</ClInclude>
|
||||
@@ -815,9 +809,6 @@
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_PeerTest.h">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\protocol\beast_ProxyHandshake.h">
|
||||
<Filter>beast_asio\protocol</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\tests\beast_TestPeerLogicProxyClient.h">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClInclude>
|
||||
@@ -842,15 +833,27 @@
|
||||
<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>
|
||||
<ClInclude Include="..\..\modules\beast_asio\streams\beast_prefilled_read_stream.h">
|
||||
<ClInclude Include="..\..\modules\beast_asio\streams\beast_PrefilledReadStream.h">
|
||||
<Filter>beast_asio\streams</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_ProxyHandshake.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogic.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\basics\beast_FixedInputBuffer.h">
|
||||
<Filter>beast_asio\basics</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicSSL2.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectLogicSSL3.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\modules\beast_asio\handshake\beast_HandshakeDetectStream.h">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\modules\beast_core\beast_core.cpp">
|
||||
@@ -1303,17 +1306,14 @@
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\beast_TestPeerUnitTests.cpp">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\protocol\beast_ProxyHandshake.cpp">
|
||||
<Filter>beast_asio\protocol</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\modules\beast_asio\tests\beast_TestPeerLogicProxyClient.cpp">
|
||||
<Filter>beast_asio\tests</Filter>
|
||||
</ClCompile>
|
||||
<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 Include="..\..\modules\beast_asio\handshake\beast_ProxyHandshake.cpp">
|
||||
<Filter>beast_asio\handshake</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_FIXEDINPUTBUFFER_H_INCLUDED
|
||||
#define BEAST_FIXEDINPUTBUFFER_H_INCLUDED
|
||||
|
||||
/** 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 FixedInputBuffer
|
||||
{
|
||||
template <typename ConstBufferSequence>
|
||||
explicit FixedInputBuffer (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))
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -30,8 +30,7 @@ namespace beast
|
||||
#include "sockets/beast_Socket.cpp"
|
||||
#include "sockets/beast_SslContext.cpp"
|
||||
|
||||
#include "protocol/beast_ProxyHandshake.cpp"
|
||||
#include "protocol/beast_StreamHandshakeDetectorType.cpp"
|
||||
#include "handshake/beast_ProxyHandshake.cpp"
|
||||
|
||||
#include "tests/beast_TestPeerBasics.cpp"
|
||||
#include "tests/beast_TestPeerLogic.cpp"
|
||||
|
||||
@@ -48,24 +48,25 @@ namespace beast
|
||||
|
||||
// Order matters
|
||||
|
||||
#include "basics/beast_PeerRole.h"
|
||||
#include "basics/beast_BufferType.h"
|
||||
#include "basics/beast_CompletionCall.h"
|
||||
#include "basics/beast_ErrorCall.h"
|
||||
#include "basics/beast_FixedInputBuffer.h"
|
||||
#include "basics/beast_PeerRole.h"
|
||||
#include "basics/beast_TransferCall.h"
|
||||
|
||||
#include "sockets/beast_SocketBase.h"
|
||||
#include "sockets/beast_Socket.h"
|
||||
#include "sockets/beast_SocketInterface.h"
|
||||
#include "sockets/beast_SocketWrapper.h"
|
||||
#include "sockets/beast_SharedSocket.h"
|
||||
#include "sockets/beast_SslContext.h"
|
||||
|
||||
#include "protocol/beast_ProxyHandshake.h"
|
||||
#include "protocol/beast_HandshakeDetectorType.h"
|
||||
#include "protocol/beast_StreamHandshakeDetectorType.h"
|
||||
#include "handshake/beast_ProxyHandshake.h"
|
||||
#include "handshake/beast_HandshakeDetectLogic.h"
|
||||
#include "handshake/beast_HandshakeDetectLogicSSL2.h"
|
||||
#include "handshake/beast_HandshakeDetectLogicSSL3.h"
|
||||
#include "handshake/beast_HandshakeDetectStream.h"
|
||||
|
||||
#include "streams/beast_prefilled_read_stream.h"
|
||||
#include "streams/beast_PrefilledReadStream.h"
|
||||
|
||||
#include "tests/beast_TestPeerBasics.h"
|
||||
#include "tests/beast_TestPeer.h"
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKEDETECTLOGIC_H_INCLUDED
|
||||
#define BEAST_HANDSHAKEDETECTLOGIC_H_INCLUDED
|
||||
|
||||
class HandshakeDetectLogic
|
||||
{
|
||||
public:
|
||||
HandshakeDetectLogic ()
|
||||
: m_finished (false)
|
||||
, m_success (false)
|
||||
{
|
||||
}
|
||||
|
||||
/** How many bytes maximum we might need.
|
||||
|
||||
This is the largest number of bytes that the detector
|
||||
might need in order to come to a conclusion about
|
||||
whether or not the handshake is a match. Depending
|
||||
on the data, it could come to that conclusion sooner
|
||||
though.
|
||||
|
||||
Use read_some instead of read so that the detect logic
|
||||
can reject the handshake sooner if possible.
|
||||
*/
|
||||
virtual std::size_t max_needed () = 0;
|
||||
|
||||
/** Return true if we have enough data to form a conclusion.
|
||||
*/
|
||||
bool finished () const noexcept
|
||||
{
|
||||
return m_finished;
|
||||
}
|
||||
|
||||
/** Return true if we came to a conclusion and the data matched.
|
||||
*/
|
||||
bool success () const noexcept
|
||||
{
|
||||
return m_finished && m_success;
|
||||
}
|
||||
|
||||
protected:
|
||||
void conclude (bool success = true)
|
||||
{
|
||||
m_finished = true;
|
||||
m_success = success;
|
||||
}
|
||||
|
||||
void fail ()
|
||||
{
|
||||
conclude (false);
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_finished;
|
||||
bool m_success;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** Wraps the logic and exports it as an abstract interface.
|
||||
*/
|
||||
template <typename Logic>
|
||||
class HandshakeDetectLogicType
|
||||
{
|
||||
public:
|
||||
typedef Logic LogicType;
|
||||
typedef typename Logic::arg_type arg_type;
|
||||
|
||||
explicit HandshakeDetectLogicType (arg_type const& arg = arg_type ())
|
||||
: m_logic (arg)
|
||||
{
|
||||
}
|
||||
|
||||
LogicType& get ()
|
||||
{
|
||||
return m_logic;
|
||||
}
|
||||
|
||||
std::size_t max_needed () noexcept
|
||||
{
|
||||
return m_logic.max_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,103 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKEDETECTLOGICSSL2_H_INCLUDED
|
||||
#define BEAST_HANDSHAKEDETECTLOGICSSL2_H_INCLUDED
|
||||
|
||||
// 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 HandshakeDetectLogicSSL2 : public HandshakeDetectLogic
|
||||
{
|
||||
public:
|
||||
typedef int arg_type;
|
||||
|
||||
explicit HandshakeDetectLogicSSL2 (arg_type const&)
|
||||
{
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
bytesNeeded = 3
|
||||
};
|
||||
|
||||
std::size_t max_needed ()
|
||||
{
|
||||
return bytesNeeded;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
void analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
FixedInputBuffer <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 ();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKEDETECTLOGICSSL3_H_INCLUDED
|
||||
#define BEAST_HANDSHAKEDETECTLOGICSSL3_H_INCLUDED
|
||||
|
||||
// Handshake for SSL 3 (Also TLS 1.0 and 1.1)
|
||||
//
|
||||
// http://www.ietf.org/rfc/rfc2246.txt
|
||||
//
|
||||
// Section 7.4. Handshake protocol
|
||||
//
|
||||
class HandshakeDetectLogicSSL3 : public HandshakeDetectLogic
|
||||
{
|
||||
public:
|
||||
typedef int arg_type; // dummy
|
||||
|
||||
explicit HandshakeDetectLogicSSL3 (arg_type const&)
|
||||
{
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
bytesNeeded = 6
|
||||
};
|
||||
|
||||
std::size_t max_needed ()
|
||||
{
|
||||
return bytesNeeded;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence>
|
||||
void analyze (ConstBufferSequence const& buffer)
|
||||
{
|
||||
uint16 version;
|
||||
FixedInputBuffer <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 ();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,307 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_HANDSHAKEDETECTSTREAM_H_INCLUDED
|
||||
#define BEAST_HANDSHAKEDETECTSTREAM_H_INCLUDED
|
||||
|
||||
/** A stream that can detect a handshake.
|
||||
*/
|
||||
/** @{ */
|
||||
template <class Logic>
|
||||
class HandshakeDetectStream
|
||||
{
|
||||
protected:
|
||||
typedef boost::system::error_code error_code;
|
||||
|
||||
public:
|
||||
typedef Logic LogicType;
|
||||
|
||||
/** Called when the state is known.
|
||||
|
||||
This could be called from any thread, most likely an io_service
|
||||
thread but don't rely on that.
|
||||
|
||||
The Callback must be allocated via operator new.
|
||||
*/
|
||||
struct Callback
|
||||
{
|
||||
virtual ~Callback () { }
|
||||
|
||||
/** Called for synchronous ssl detection.
|
||||
|
||||
Note that the storage for the buffers passed to the
|
||||
callback is owned by the detector class and becomes
|
||||
invalid when the detector class is destroyed, which is
|
||||
a common thing to do from inside your callback.
|
||||
|
||||
@param ec A modifiable error code that becomes the return
|
||||
value of handshake.
|
||||
@param buffers The bytes that were read in.
|
||||
@param is_ssl True if the sequence is an ssl handshake.
|
||||
*/
|
||||
virtual void on_detect (Logic& logic,
|
||||
error_code& ec, ConstBuffers const& buffers) = 0;
|
||||
|
||||
virtual void on_async_detect (Logic& logic,
|
||||
error_code const& ec, ConstBuffers const& buffers,
|
||||
ErrorCall const& origHandler) = 0;
|
||||
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
virtual void on_async_detect (Logic& logic,
|
||||
error_code const& ec, ConstBuffers const& buffers,
|
||||
TransferCall const& origHandler) = 0;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
template <typename Stream, typename Logic>
|
||||
class HandshakeDetectStreamType
|
||||
: public HandshakeDetectStream <Logic>
|
||||
, public boost::asio::ssl::stream_base
|
||||
, public boost::asio::socket_base
|
||||
{
|
||||
private:
|
||||
typedef HandshakeDetectStreamType <Stream, Logic> this_type;
|
||||
typedef boost::asio::streambuf buffer_type;
|
||||
typedef typename boost::remove_reference <Stream>::type stream_type;
|
||||
|
||||
public:
|
||||
typedef typename HandshakeDetectStream <Logic> CallbackType;
|
||||
|
||||
/** This takes ownership of the callback.
|
||||
The callback must be allocated with operator new.
|
||||
*/
|
||||
template <typename Arg>
|
||||
HandshakeDetectStreamType (Callback* callback, Arg& arg)
|
||||
: m_callback (callback)
|
||||
, m_next_layer (arg)
|
||||
, m_stream (m_next_layer)
|
||||
{
|
||||
}
|
||||
|
||||
// basic_io_object
|
||||
|
||||
boost::asio::io_service& get_io_service ()
|
||||
{
|
||||
return m_next_layer.get_io_service ();
|
||||
}
|
||||
|
||||
// basic_socket
|
||||
|
||||
typedef typename stream_type::protocol_type protocol_type;
|
||||
typedef typename stream_type::lowest_layer_type lowest_layer_type;
|
||||
|
||||
lowest_layer_type& lowest_layer ()
|
||||
{
|
||||
return m_next_layer.lowest_layer ();
|
||||
}
|
||||
|
||||
lowest_layer_type const& lowest_layer () const
|
||||
{
|
||||
return m_next_layer.lowest_layer ();
|
||||
}
|
||||
|
||||
// ssl::stream
|
||||
|
||||
error_code handshake (handshake_type type, error_code& ec)
|
||||
{
|
||||
return do_handshake (type, ec, ConstBuffers ());
|
||||
}
|
||||
|
||||
template <typename HandshakeHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(HandshakeHandler, void (error_code))
|
||||
async_handshake (handshake_type type, BOOST_ASIO_MOVE_ARG(HandshakeHandler) handler)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
ErrorCall, void (error_code)> init(
|
||||
BOOST_ASIO_MOVE_CAST(HandshakeHandler)(handler));
|
||||
// init.handler is copied
|
||||
m_origHandler = ErrorCall (HandshakeHandler(init.handler));
|
||||
bassert (m_origBufferedHandler.isNull ());
|
||||
async_do_handshake (type, ConstBuffers ());
|
||||
return init.result.get();
|
||||
#else
|
||||
m_origHandler = ErrorCall (handler);
|
||||
bassert (m_origBufferedHandler.isNull ());
|
||||
async_do_handshake (type, ConstBuffers ());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
template <typename ConstBufferSequence>
|
||||
error_code handshake (handshake_type type,
|
||||
const ConstBufferSequence& buffers, error_code& ec)
|
||||
{
|
||||
return do_handshake (type, ec, ConstBuffers (buffers));;
|
||||
}
|
||||
|
||||
template <typename ConstBufferSequence, typename BufferedHandshakeHandler>
|
||||
BOOST_ASIO_INITFN_RESULT_TYPE(BufferedHandshakeHandler, void (error_code, std::size_t))
|
||||
async_handshake(handshake_type type, const ConstBufferSequence& buffers,
|
||||
BOOST_ASIO_MOVE_ARG(BufferedHandshakeHandler) handler)
|
||||
{
|
||||
#if BEAST_ASIO_HAS_FUTURE_RETURNS
|
||||
boost::asio::detail::async_result_init<
|
||||
BufferedHandshakeHandler, void (error_code, std::size_t)> init(
|
||||
BOOST_ASIO_MOVE_CAST(BufferedHandshakeHandler)(handler));
|
||||
// init.handler is copied
|
||||
m_origBufferedHandler = TransferCall (BufferedHandshakeHandler(init.handler));
|
||||
bassert (m_origHandler.isNull ());
|
||||
async_do_handshake (type, ConstBuffers (buffers));
|
||||
return init.result.get();
|
||||
#else
|
||||
m_origBufferedHandler = TransferCall (handler);
|
||||
bassert (m_origHandler.isNull ());
|
||||
async_do_handshake (type, ConstBuffers (buffers));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
error_code do_handshake (handshake_type, error_code& ec, ConstBuffers const& buffers)
|
||||
{
|
||||
ec = error_code ();
|
||||
|
||||
// Transfer caller data to our buffer.
|
||||
m_buffer.commit (boost::asio::buffer_copy (m_buffer.prepare (
|
||||
boost::asio::buffer_size (buffers)), buffers));
|
||||
|
||||
do
|
||||
{
|
||||
std::size_t const available = m_buffer.size ();
|
||||
std::size_t const needed = m_logic.max_needed ();
|
||||
if (available < needed)
|
||||
{
|
||||
buffer_type::mutable_buffers_type buffers (
|
||||
m_buffer.prepare (needed - available));
|
||||
m_buffer.commit (m_next_layer.read_some (buffers, ec));
|
||||
}
|
||||
|
||||
if (! ec)
|
||||
{
|
||||
m_logic.analyze (m_buffer.data ());
|
||||
|
||||
if (m_logic.finished ())
|
||||
{
|
||||
m_callback->on_detect (m_logic.get (), ec,
|
||||
ConstBuffers (m_buffer.data ()));
|
||||
break;
|
||||
}
|
||||
|
||||
// If this fails it means we will never finish
|
||||
check_postcondition (available < needed);
|
||||
}
|
||||
}
|
||||
while (! ec);
|
||||
|
||||
return ec;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
void async_do_handshake (handshake_type type, ConstBuffers const& buffers)
|
||||
{
|
||||
// Transfer caller data to our buffer.
|
||||
std::size_t const bytes_transferred (boost::asio::buffer_copy (
|
||||
m_buffer.prepare (boost::asio::buffer_size (buffers)), buffers));
|
||||
|
||||
// bootstrap the asynchronous loop
|
||||
on_async_read_some (error_code (), bytes_transferred);
|
||||
}
|
||||
|
||||
// asynchronous version of the synchronous loop found in handshake ()
|
||||
//
|
||||
void on_async_read_some (error_code const& ec, std::size_t bytes_transferred)
|
||||
{
|
||||
if (! ec)
|
||||
{
|
||||
m_buffer.commit (bytes_transferred);
|
||||
|
||||
std::size_t const available = m_buffer.size ();
|
||||
std::size_t const needed = m_logic.max_needed ();
|
||||
|
||||
m_logic.analyze (m_buffer.data ());
|
||||
|
||||
if (m_logic.finished ())
|
||||
{
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
if (! m_origBufferedHandler.isNull ())
|
||||
{
|
||||
bassert (m_origHandler.isNull ());
|
||||
// continuation?
|
||||
m_callback->on_async_detect (m_logic.get (), ec,
|
||||
ConstBuffers (m_buffer.data ()), m_origBufferedHandler);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
bassert (! m_origHandler.isNull ())
|
||||
// continuation?
|
||||
m_callback->on_async_detect (m_logic.get (), ec,
|
||||
ConstBuffers (m_buffer.data ()), m_origHandler);
|
||||
return;
|
||||
}
|
||||
|
||||
// If this fails it means we will never finish
|
||||
check_postcondition (available < needed);
|
||||
|
||||
buffer_type::mutable_buffers_type buffers (m_buffer.prepare (
|
||||
needed - available));
|
||||
|
||||
// need a continuation hook here?
|
||||
m_next_layer.async_read_some (buffers, boost::bind (
|
||||
&this_type::on_async_read_some, this, boost::asio::placeholders::error,
|
||||
boost::asio::placeholders::bytes_transferred));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if BEAST_ASIO_HAS_BUFFEREDHANDSHAKE
|
||||
if (! m_origBufferedHandler.isNull ())
|
||||
{
|
||||
bassert (m_origHandler.isNull ());
|
||||
// continuation?
|
||||
m_callback->on_async_detect (m_logic.get (), ec,
|
||||
ConstBuffers (m_buffer.data ()), m_origBufferedHandler);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
bassert (! m_origHandler.isNull ())
|
||||
// continuation?
|
||||
m_callback->on_async_detect (m_logic.get (), ec,
|
||||
ConstBuffers (m_buffer.data ()), m_origHandler);
|
||||
}
|
||||
|
||||
private:
|
||||
ScopedPointer <typename HandshakeDetectStream <Logic>::Callback> m_callback;
|
||||
Stream m_next_layer;
|
||||
buffer_type m_buffer;
|
||||
boost::asio::buffered_read_stream <stream_type&> m_stream;
|
||||
HandshakeDetectLogicType <Logic> m_logic;
|
||||
ErrorCall m_origHandler;
|
||||
TransferCall m_origBufferedHandler;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
@@ -1,350 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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)
|
||||
{
|
||||
}
|
||||
|
||||
/** How many bytes maximum we might need.
|
||||
|
||||
This is the largest number of bytes that the detector
|
||||
might need in order to come to a conclusion about
|
||||
whether or not the handshake is a match. Depending
|
||||
on the data, it could come to that conclusion sooner
|
||||
though.
|
||||
*/
|
||||
virtual std::size_t max_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 false;
|
||||
*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 max_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 max_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 max_needed () noexcept
|
||||
{
|
||||
return m_logic.max_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
|
||||
@@ -1,19 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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
|
||||
@@ -1,83 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_SHAREDSOCKET_H_INCLUDED
|
||||
#define BEAST_SHAREDSOCKET_H_INCLUDED
|
||||
|
||||
/** A Socket interface with reference counting.
|
||||
|
||||
You can keep a pointer to the base class so that you don't have
|
||||
to see the template or underlying object implementation.
|
||||
|
||||
@see SharedSocketTYpe, SharedObjectPtr
|
||||
*/
|
||||
/** @{ */
|
||||
class SharedSocket
|
||||
: public SharedObject
|
||||
, public virtual Socket
|
||||
{
|
||||
public:
|
||||
/** Store your SharedSocket in one of these! */
|
||||
typedef SharedObjectPtr <SharedSocket> Ptr;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** A RAII container for wrapping an object as a Socket.
|
||||
|
||||
To use this, construct the class with an instance of your object
|
||||
created with operator new. The constructor will take ownership,
|
||||
and delete it when the last reference is removed. For example:
|
||||
|
||||
@code
|
||||
|
||||
boost::asio::io_service ios;
|
||||
boost::asio::ssl:context ctx;
|
||||
|
||||
SharedSocket::Ptr mySocket (
|
||||
new (boost::asio::ssl::stream (ios, ctx)));
|
||||
|
||||
mySocket->handshake ();
|
||||
|
||||
@endcode
|
||||
|
||||
@see SharedSocket
|
||||
*/
|
||||
template <class Object>
|
||||
class SharedSocketType
|
||||
: public SharedSocket
|
||||
, public SocketWrapper <Object>
|
||||
{
|
||||
public:
|
||||
/** Create the shared socket.
|
||||
This takes posession of the object, which will be deleted
|
||||
when the last reference goes away.
|
||||
*/
|
||||
SharedSocketType (Object* object)
|
||||
: SocketWrapper <Object> (object)
|
||||
, m_object (object)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
ScopedPointer <Object> m_object;
|
||||
};
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_SOCKETINTERFACE_H_INCLUDED
|
||||
#define BEAST_SOCKETINTERFACE_H_INCLUDED
|
||||
|
||||
/** These define the interfaces that SocketWrapper can adapt with SFINAE. */
|
||||
struct SocketInterface
|
||||
{
|
||||
// has close()
|
||||
struct Close { };
|
||||
|
||||
/** Tag for some compatibility with boost::asio::basic_socket_acceptor
|
||||
http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/basic_socket_acceptor.html
|
||||
*/
|
||||
struct Acceptor : Close { };
|
||||
|
||||
// Has lowest_layer() and lowest_layer_type
|
||||
struct LowestLayer { };
|
||||
|
||||
/** Tag for parts of boost::asio::basic_socket
|
||||
http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/basic_socket.html
|
||||
*/
|
||||
struct Socket : Close, LowestLayer { };
|
||||
|
||||
/** Tag for parts of boost::asio::basic_stream_socket
|
||||
http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/basic_stream_socket.html
|
||||
*/
|
||||
struct SyncStream { };
|
||||
struct AsyncStream { };
|
||||
struct Stream : SyncStream, AsyncStream { };
|
||||
|
||||
/** Tags for parts of boost::asio::ssl::stream
|
||||
http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/ssl__stream.html
|
||||
*/
|
||||
struct AnyHandshake { };
|
||||
struct SyncHandshake : AnyHandshake { };
|
||||
struct AsyncHandshake : AnyHandshake { };
|
||||
struct BufferedSyncHandshake : AnyHandshake { };
|
||||
struct BufferedAsyncHandshake : AnyHandshake { };
|
||||
struct Handshake : SyncHandshake, AsyncHandshake,
|
||||
BufferedSyncHandshake, BufferedAsyncHandshake,
|
||||
LowestLayer { };
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user