GNOME Bugzilla – Bug 749596
rtsp-over-http authentication failure
Last modified: 2015-12-14 15:44:33 UTC
I am attempting to stream rtsp-over-http from an Axis camera with the following pipeline: gst-launch-1.0 --gst-debug=*:3 rtspsrc location="rtsph://192.168.103.77:80/axis-media/media.amp" user-id=testuser user-pw=pword ! fakesink This results in the following errors: ERROR default gstrtspconnection.c:773:setup_tunneling: got failure response 401 Unauthorized ERROR default gstrtspconnection.c:892:gst_rtsp_connection_connect: failed to setup tunneling ERROR rtspsrc gstrtspsrc.c:4198:gst_rtsp_conninfo_connect:<rtspsrc0> Could not connect to server. (Generic error) Further tests: I am able to properly stream rtsp-over-http with the camera under one of the following conditions: - Connect to port 554 instead of 80. (rtsph://192.168.103.77/axis-media/media.amp user-id=testuser user-pw=pword) - Disable authentication on the camera and stream from port 80. (rtsph://192.168.103.77/axis-media/media.amp) Does rtspsrc support authentication when setting up the HTTP tunnel?
I've reproduced this issue and delved into it a bit and it seems that we do not handle authentication during tunneling setup appropriately. When I add the appropriate Authorization header to the request all goes well, but this may require some slight reworking of things to get the response back from setup_tunneling to know what kinds of authentication are supported. Currently, rtspsrc calls gst_connection_connect on rtspconnection which in turn calls setup_tunneling if required. The response to the request in setup tunneling is currently only local in scope, but all of our framework for setting up authentication is in rtspsrc and relies on being able to parse the response. Here are two viable approaches: 1) Create variations of gst_connection_connect and setup_tunneling that are passed a response pointer in addition to the existing arguments so that a caller can leverage the response to setup authentication and retry the connection. For compatibility with other code using gst_connection_connect, we can make gst_connection_connect into a wrapper method which maintains the existing function prototype and simply passes the arguments through with an added response pointer to the new method. 2) From rtspsrc, send a dummy request prior to attempting a connection to see if setup_tunneling will require authentication and add it based upon the response to the dummy request as necessary. From there proceed with connecting as normal. This does have the benefit of keeping all changes local to rtspsrc. I am unsure what approach would be preferred. Please advise as to what strategy you would like to see implemented to resolve this and I would be happy to supply a patch.
IMHO 1) sounds better as it will cause one request less in the good cases.
Created attachment 313869 [details] [review] gst-plugins-base support tunneling auth Agreed, #1 is a better solution. It seems that I can only attach one file at a time(?), so here is the gst-plugins-base patch, which adds allows the caller to retrieve a response that can be inspected to determine if authentication is required and retry with auth as required. The patch that applies to gst-plugins-good will follow in the next comment. Note that whitespace on some lines are changed as a result of running the code through GNU Indent with the flags presented on the FAQ (http://gstreamer.freedesktop.org/data/doc/gstreamer/head/faq/html/chapter-developing.html#idm46475139126480). If you would prefer to have me resubmit these patches without these whitespace changes, please just let me know. As always, let me know if there is anything in the patch that you would like to see changed.
Created attachment 313870 [details] [review] gst-plugins-good retry tunneling with auth Continued from above.
Review of attachment 313869 [details] [review]: ::: gst-libs/gst/rtsp/gstrtspconnection.c @@ +52,2 @@ #ifdef HAVE_CONFIG_H +#include <config.h> Please don't do any whitespace changes :) @@ +235,3 @@ + peer_identity, + g_tls_connection_get_interaction (conn), + G_TLS_DATABASE_VERIFY_NONE, NULL, &error); No code-style fixes, unless in a separate patch. But "gst-indent" should actually revert this part here already. Please run gst-indent on .c files :) @@ +867,3 @@ * forever. If @timeout contains a valid timeout, this function will return + * #GST_RTSP_ETIMEOUT after the timeout expired. If @conn is set to tunneled, + * @response will contain a response to the tunneling request messages. How would the caller know if it indeed does contain that, or if no tunnelling has happened? @@ +871,3 @@ * This function can be cancelled with gst_rtsp_connection_flush(). * * Returns: #GST_RTSP_OK when a connection could be made. Add a "Since: 1.8" marker here @@ +1101,3 @@ + * #GST_RTSP_ETIMEOUT after the timeout expired. + * + * This function can be cancelled with gst_rtsp_connection_flush(). Maybe add a note to the docs that this function is going to cause problems with tunneling and authentication @@ +1110,3 @@ + GstRTSPResult result; + GstRTSPMessage *response; + response = g_new0 (GstRTSPMessage, 1); You can allocate this one on the stack like the old function did @@ +1142,3 @@ g_snprintf (date_string, len, "%s, %02d %s %04d %02d:%02d:%02d GMT", + wkdays[tm.tm_wday], tm.tm_mday, months[tm.tm_mon], + tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec); This and everything following here is also just code-style / whitespace changes. Please remove them from the patch
Review of attachment 313870 [details] [review]: ::: gst/rtsp/gstrtspsrc.c @@ +4519,3 @@ GstRTSPResult res; + GstRTSPMessage *response = NULL; + guint8 retry = 0; Should this be a gboolean and be initialized to FALSE? You only seem to retry at most once @@ +4523,1 @@ + response = g_new0 (GstRTSPMessage, 1); Why not allocate it on the stack?
Instead of all this message dance, could we add a NOT_AUTHORIZED to GstRTSPResult and return that from _connect() instead?
As I see it, if we return NOT_AUTHORIZED instead of passing around the response, how will rtspsrc know how to do auth? We need to know whether basic or digest is supported by the server. If digest is supported we need the nonce and realm provided by the server to continue.
Good point, makes sense :)
Created attachment 317373 [details] [review] gst-plugins-base support tunneling with auth Re-uploading this with whitespace changes removed and response declared on stack.
Created attachment 317374 [details] [review] gst-plugins-good retry tunneling with auth Remove whitespace changes. Declare response on the stack. Add function prototype instead of moving gst_rtsp_conninfo_close.
Comment on attachment 317373 [details] [review] gst-plugins-base support tunneling with auth commit 65c7bd7a2ced2c3c82f6bb4663217c9afdb9faad Author: Evan Callaway <evan.callaway@ipconfigure.com> Date: Mon Dec 14 09:10:16 2015 -0500 rtspconnection: Support authentication during tunneling setup gst_rtsp_connection_connect_with_response accepts a response pointer which it fills with the response from setup_tunneling if the connection is configured to be tunneled. The motivation for this is to allow the caller to inspect the response header to determine if additional authentication is required so that the connection can be retried with the appropriate authentication headers. The function prototype of gst_rtsp_connection_connect has been preserved for compatability with existing code and wraps gst_rtsp_connection_connect_with_response. https://bugzilla.gnome.org/show_bug.cgi?id=749596
Comment on attachment 317374 [details] [review] gst-plugins-good retry tunneling with auth This one does not apply cleanly to GIT master. Can you rebase it? Otherwise looks good to go
Whoops! Yes, will do.
Created attachment 317378 [details] [review] gst-plugins-good retry tunneling with auth Alright, this should apply cleanly to master. Apologies about the mix-up there.
commit 4718870959b1bd31633f64934d0f679a3c99d18b Author: Evan Callaway <evan.callaway@ipconfigure.com> Date: Mon Dec 14 09:05:06 2015 -0500 rtspsrc: Retry connection if tunneling needs authentication Leverage response from gst_rtsp_connection_connect_with_response to determine if the connection should be retried using authentication. If so, add the appropriate authentication headers based upon the response and retry the connection. https://bugzilla.gnome.org/show_bug.cgi?id=749596