From 06b600901c82a8e6c4e8722597685f2a254084b0 Mon Sep 17 00:00:00 2001 From: Kristofer Bjorkstrom Date: Tue, 2 Apr 2019 10:01:47 +0200 Subject: [PATCH] rtspconnection: CSeq validation Make rtspconnection a little more strict to RFC2326. Make sure that CSeq is in every RTSP message and that CSeq is valid. Also break the build_next loop if any parsing fails, By acting on the builder->status code. --- gst-libs/gst/rtsp/gstrtspconnection.c | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/gst-libs/gst/rtsp/gstrtspconnection.c b/gst-libs/gst/rtsp/gstrtspconnection.c index c65b9b6..e4a6f93 100644 --- a/gst-libs/gst/rtsp/gstrtspconnection.c +++ b/gst-libs/gst/rtsp/gstrtspconnection.c @@ -2292,6 +2292,43 @@ normalize_line (guint8 * buffer) } } +static gboolean +cseq_validation (GstRTSPConnection * conn, GstRTSPMessage * message) +{ + gchar *cseq_header; + gint64 cseq = 0; + GstRTSPResult res; + + if (message->type == GST_RTSP_MESSAGE_RESPONSE || + message->type == GST_RTSP_MESSAGE_REQUEST) { + if ((res = gst_rtsp_message_get_header (message, GST_RTSP_HDR_CSEQ, + &cseq_header, 0)) != GST_RTSP_OK) { + /* rfc2326 This field MUST be present in all RTSP req and resp */ + goto invalid_format; + } + + errno = 0; + cseq = g_ascii_strtoll (cseq_header, NULL, 10); + if (errno != 0 || cseq < 0) { + /* CSeq has no valid value */ + goto invalid_format; + } + + if (message->type == GST_RTSP_MESSAGE_RESPONSE && + (conn->cseq == 0 || conn->cseq < cseq)) { + /* Response CSeq can't be higher than the number of outgoing requests + * neither is a response valid if no request has been made */ + goto invalid_format; + } + } + return GST_RTSP_OK; + +invalid_format: + { + return GST_RTSP_EPARSE; + } +} + /* returns: * GST_RTSP_OK when a complete message was read. * GST_RTSP_EEOF: when the read socket is closed @@ -2424,6 +2461,11 @@ build_next (GstRTSPBuilder * builder, GstRTSPMessage * message, if (res != GST_RTSP_OK) builder->status = res; } + if (builder->status != GST_RTSP_OK) { + res = builder->status; + goto invalid_format; + } + builder->line++; builder->offset = 0; break; @@ -2435,6 +2477,11 @@ build_next (GstRTSPBuilder * builder, GstRTSPMessage * message, conn->may_cancel = TRUE; + if ((res = cseq_validation (conn, message)) != GST_RTSP_OK) { + /* message don't comply with rfc2326 regarding CSeq */ + goto invalid_format; + } + if (message->type == GST_RTSP_MESSAGE_DATA) { /* data messages don't have headers */ res = GST_RTSP_OK; @@ -2504,6 +2551,12 @@ invalid_body_len: GST_DEBUG ("could not allocate body"); return GST_RTSP_ERROR; } +invalid_format: + { + conn->may_cancel = TRUE; + GST_DEBUG ("could not parse"); + return res; + } } /** -- 2.7.4