From 56c1d1e3a12e0be18ccf387ed3d5202aedd4728a Mon Sep 17 00:00:00 2001 From: Thulinma Date: Wed, 12 Oct 2016 00:48:34 +0200 Subject: [PATCH] RTMP push security improvements --- src/output/output_rtmp.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/output/output_rtmp.cpp b/src/output/output_rtmp.cpp index 66737e6e..3cb81b3e 100644 --- a/src/output/output_rtmp.cpp +++ b/src/output/output_rtmp.cpp @@ -927,6 +927,7 @@ namespace Mist { case 9: //video data case 18: {//meta data static std::map pushMeta; + static uint64_t lastTagTime = 0; if (!isInitialized) { MEDIUM_MSG("Received useless media data"); onFinish(); @@ -944,7 +945,23 @@ namespace Mist { unsigned int reTrack = next.cs_id*3 + (F.data[0] == 0x09 ? 1 : (F.data[0] == 0x08 ? 2 : 3)); F.toMeta(myMeta, *amf_storage, reTrack); if (F.getDataLen() && !(F.needsInitData() && F.isInitData())){ - thisPacket.genericFill(F.tagTime(), F.offset(), reTrack, F.getData(), F.getDataLen(), 0, F.isKeyframe); + uint64_t tagTime = next.timestamp; + //Check for decreasing timestamps - this is a connection error. + //We allow wrapping around the 32 bits maximum value if the most significant 8 bits are set. + /// \TODO Provide time continuity for wrap-around. + if (lastTagTime && tagTime < lastTagTime && lastTagTime < 0xFF000000ull){ + FAIL_MSG("Timestamps went from %llu to %llu (decreased): disconnecting!", lastTagTime, tagTime); + onFinish(); + break; + } + //Check if we went more than 10 minutes into the future + if (lastTagTime && tagTime > lastTagTime + 600000){ + FAIL_MSG("Timestamps went from %llu to %llu (> 10m in future): disconnecting!", lastTagTime, tagTime); + onFinish(); + break; + } + thisPacket.genericFill(tagTime, F.offset(), reTrack, F.getData(), F.getDataLen(), 0, F.isKeyframe); + lastTagTime = tagTime; if (!nProxy.userClient.getData()){ char userPageName[NAME_BUFFER_SIZE]; snprintf(userPageName, NAME_BUFFER_SIZE, SHM_USERS, streamName.c_str());