mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Rate-limit SSL client renegotiation (RIPD-360)
This commit is contained in:
committed by
Vinnie Falco
parent
bbbae072ea
commit
a2764b68ca
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -19,9 +19,13 @@
|
||||
|
||||
#include <ripple/common/RippleSSLContext.h>
|
||||
|
||||
#include <ripple/common/seconds_clock.h>
|
||||
#include <beast/container/aged_unordered_set.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class RippleSSLContextImp : public RippleSSLContext
|
||||
@@ -29,6 +33,8 @@ class RippleSSLContextImp : public RippleSSLContext
|
||||
private:
|
||||
boost::asio::ssl::context m_context;
|
||||
|
||||
// track when SSL connections have last negotiated
|
||||
|
||||
public:
|
||||
RippleSSLContextImp ()
|
||||
: RippleSSLContext (m_context)
|
||||
@@ -45,6 +51,55 @@ public:
|
||||
return DHparams_dup (getDH (key_length));
|
||||
}
|
||||
|
||||
static bool disallowRenegotiation (SSL const* ssl, bool isNew)
|
||||
{
|
||||
// Do not allow a connection to renegotiate
|
||||
// more than once every 4 minutes
|
||||
|
||||
static std::mutex negotiationSetLock;
|
||||
static beast::aged_unordered_set <SSL const*> negotiationSet (ripple::get_seconds_clock ());
|
||||
static std::chrono::seconds const minRenegotiationSeconds = std::chrono::minutes (4);
|
||||
|
||||
std::lock_guard <std::mutex> locker (negotiationSetLock);
|
||||
|
||||
auto const expired = (negotiationSet.clock().now() - minRenegotiationSeconds);
|
||||
|
||||
// Remove expired entries
|
||||
for (auto iter (negotiationSet.chronological.begin ());
|
||||
(iter != negotiationSet.chronological.end ()) && (iter.when () <= expired);
|
||||
iter = negotiationSet.chronological.begin ())
|
||||
{
|
||||
negotiationSet.erase (iter);
|
||||
}
|
||||
|
||||
auto iter = negotiationSet.find (ssl);
|
||||
if (iter != negotiationSet.end ())
|
||||
{
|
||||
if (!isNew)
|
||||
{
|
||||
// This is a renegotiation and the last negotiation was recent
|
||||
return true;
|
||||
}
|
||||
|
||||
negotiationSet.touch (iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
negotiationSet.emplace (ssl);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void info_handler (SSL const* ssl, int event, int)
|
||||
{
|
||||
if ((ssl->s3) && (event & SSL_CB_HANDSHAKE_START))
|
||||
{
|
||||
if (disallowRenegotiation (ssl, SSL_in_before (ssl)))
|
||||
ssl->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
|
||||
}
|
||||
}
|
||||
|
||||
// Pretty prints an error message
|
||||
std::string error_message (std::string const& what,
|
||||
boost::system::error_code const& ec)
|
||||
@@ -105,6 +160,10 @@ public:
|
||||
SSL_CTX_set_tmp_dh_callback (
|
||||
m_context.native_handle (),
|
||||
tmp_dh_handler);
|
||||
|
||||
SSL_CTX_set_info_callback (
|
||||
m_context.native_handle (),
|
||||
info_handler);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user