]> granicus.if.org Git - icinga2/commitdiff
Limit JSON-RPC message size
authorNoah Hilverling <noah.hilverling@icinga.com>
Thu, 1 Mar 2018 08:47:29 +0000 (09:47 +0100)
committerGunnar Beutner <gunnar.beutner@icinga.com>
Tue, 6 Mar 2018 07:53:14 +0000 (08:53 +0100)
lib/base/netstring.cpp
lib/base/netstring.hpp
lib/remote/jsonrpc.cpp
lib/remote/jsonrpc.hpp
lib/remote/jsonrpcconnection.cpp

index 934097e2b3d3a9684f21c2cded67a346e1d7cf89..e77a41285cb752be58d1116a22a198a9abb3cc44 100644 (file)
@@ -32,7 +32,8 @@ using namespace icinga;
  * @exception invalid_argument The input stream is invalid.
  * @see https://github.com/PeterScott/netstring-c/blob/master/netstring.c
  */
-StreamReadStatus NetString::ReadStringFromStream(const Stream::Ptr& stream, String *str, StreamReadContext& context, bool may_wait)
+StreamReadStatus NetString::ReadStringFromStream(const Stream::Ptr& stream, String *str, StreamReadContext& context,
+       bool may_wait, ssize_t maxMessageLength)
 {
        if (context.Eof)
                return StatusEof;
@@ -84,6 +85,13 @@ StreamReadStatus NetString::ReadStringFromStream(const Stream::Ptr& stream, Stri
        /* read the whole message */
        size_t data_length = len + 1;
 
+       if (maxMessageLength >= 0 && data_length > maxMessageLength) {
+               std::stringstream errorMessage;
+               errorMessage << "Max data length exceeded: " << (maxMessageLength / 1024 / 1024) << " MB";
+
+               BOOST_THROW_EXCEPTION(std::invalid_argument(errorMessage.str()));
+       }
+
        char *data = context.Buffer + header_length + 1;
 
        if (context.Size < header_length + 1 + data_length) {
index c24cba028e8c56afb4be8d99127c6eeb87e9790d..045ef5b0bc0344207e92b896af121b2c2cc97b76 100644 (file)
@@ -38,8 +38,9 @@ class String;
 class I2_BASE_API NetString
 {
 public:
-       static StreamReadStatus ReadStringFromStream(const Stream::Ptr& stream, String *message, StreamReadContext& context, bool may_wait = false);
-       static void WriteStringToStream(const Stream::Ptr& stream, const String& message);
+       static StreamReadStatus ReadStringFromStream(const Stream::Ptr& stream, String *message, StreamReadContext& context,
+               bool may_wait = false, ssize_t maxMessageLength = -1);
+       static size_t WriteStringToStream(const Stream::Ptr& stream, const String& message);
        static void WriteStringToStream(std::ostream& stream, const String& message);
 
 private:
index 1d3efd5ca18163e9cf9be02243978b63ac633115..f0cca71f68f9f38b7a20180c8f4ab5333d2de976 100644 (file)
@@ -70,10 +70,10 @@ void JsonRpc::SendMessage(const Stream::Ptr& stream, const Dictionary::Ptr& mess
        NetString::WriteStringToStream(stream, json);
 }
 
-StreamReadStatus JsonRpc::ReadMessage(const Stream::Ptr& stream, String *message, StreamReadContext& src, bool may_wait)
+StreamReadStatus JsonRpc::ReadMessage(const Stream::Ptr& stream, String *message, StreamReadContext& src, bool may_wait, ssize_t maxMessageLength)
 {
        String jsonString;
-       StreamReadStatus srs = NetString::ReadStringFromStream(stream, &jsonString, src, may_wait);
+       StreamReadStatus srs = NetString::ReadStringFromStream(stream, &jsonString, src, may_wait, maxMessageLength);
 
        if (srs != StatusNewItem)
                return srs;
index 3589b365a05595b58305a5063aea0429ba56889f..6ab83e35f3a719ecba6fb67a8190f8118463ff5b 100644 (file)
@@ -35,8 +35,8 @@ namespace icinga
 class I2_REMOTE_API JsonRpc
 {
 public:
-       static void SendMessage(const Stream::Ptr& stream, const Dictionary::Ptr& message);
-       static StreamReadStatus ReadMessage(const Stream::Ptr& stream, String *message, StreamReadContext& src, bool may_wait = false);
+       static size_t SendMessage(const Stream::Ptr& stream, const Dictionary::Ptr& message);
+       static StreamReadStatus ReadMessage(const Stream::Ptr& stream, String *message, StreamReadContext& src, bool may_wait = false, ssize_t maxMessageLength = -1);
        static Dictionary::Ptr DecodeMessage(const String& message);
 
 private:
index 161a9d01521bb400410e1e0ecd6a5e7f67280574..ac23a10600f8ac878cde7cc75cdc1de0dd5f00fa 100644 (file)
@@ -237,9 +237,14 @@ void JsonRpcConnection::MessageHandler(const String& jsonString)
 
 bool JsonRpcConnection::ProcessMessage(void)
 {
+       ssize_t maxMessageLength = 64 * 1024;
+
+       if (m_Endpoint)
+               maxMessageLength = -1; /* no limit */
+
        String message;
 
-       StreamReadStatus srs = JsonRpc::ReadMessage(m_Stream, &message, m_Context, false);
+       StreamReadStatus srs = JsonRpc::ReadMessage(m_Stream, &message, m_Context, false, maxMessageLength);
 
        if (srs != StatusNewItem)
                return false;