Commit 65c7bd7a authored by Evan Callaway's avatar Evan Callaway Committed by Sebastian Dröge

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
parent d6be6726
......@@ -1491,6 +1491,7 @@ gst_rtsp_connection_create
gst_rtsp_connection_create_from_socket
gst_rtsp_connection_accept
gst_rtsp_connection_connect
gst_rtsp_connection_connect_with_response
gst_rtsp_connection_close
gst_rtsp_connection_free
......
......@@ -196,6 +196,10 @@ typedef struct
glong body_len;
} GstRTSPBuilder;
/* function prototypes */
static void add_auth_header (GstRTSPConnection * conn,
GstRTSPMessage * message);
static void
build_reset (GstRTSPBuilder * builder)
{
......@@ -681,14 +685,14 @@ gst_rtsp_connection_get_tls_interaction (GstRTSPConnection * conn)
}
static GstRTSPResult
setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout, gchar * uri)
setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout, gchar * uri,
GstRTSPMessage * response)
{
gint i;
GstRTSPResult res;
gchar *value;
guint16 url_port;
GstRTSPMessage *msg;
GstRTSPMessage response;
gboolean old_http;
GstRTSPUrl *url;
GError *error = NULL;
......@@ -696,9 +700,6 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout, gchar * uri)
GSocket *socket;
gchar *luri = NULL;
memset (&response, 0, sizeof (response));
gst_rtsp_message_init (&response);
url = conn->url;
/* create a random sessionid */
......@@ -717,6 +718,7 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout, gchar * uri)
"application/x-rtsp-tunnelled");
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CACHE_CONTROL, "no-cache");
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_PRAGMA, "no-cache");
add_auth_header (conn, msg);
/* we need to temporarily set conn->tunneled to FALSE to prevent the HTTP
* request from being base64 encoded */
......@@ -731,15 +733,15 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout, gchar * uri)
* failure otherwise */
old_http = conn->manual_http;
conn->manual_http = TRUE;
GST_RTSP_CHECK (gst_rtsp_connection_receive (conn, &response, timeout),
GST_RTSP_CHECK (gst_rtsp_connection_receive (conn, response, timeout),
read_failed);
conn->manual_http = old_http;
if (response.type != GST_RTSP_MESSAGE_HTTP_RESPONSE ||
response.type_data.response.code != GST_RTSP_STS_OK)
if (response->type != GST_RTSP_MESSAGE_HTTP_RESPONSE ||
response->type_data.response.code != GST_RTSP_STS_OK)
goto wrong_result;
if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_X_SERVER_IP_ADDRESS,
if (gst_rtsp_message_get_header (response, GST_RTSP_HDR_X_SERVER_IP_ADDRESS,
&value, 0) == GST_RTSP_OK) {
g_free (url->host);
url->host = g_strdup (value);
......@@ -792,6 +794,7 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout, gchar * uri)
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_EXPIRES,
"Sun, 9 Jan 1972 00:00:00 GMT");
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CONTENT_LENGTH, "32767");
add_auth_header (conn, msg);
/* we need to temporarily set conn->tunneled to FALSE to prevent the HTTP
* request from being base64 encoded */
......@@ -801,7 +804,6 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout, gchar * uri)
conn->tunneled = TRUE;
exit:
gst_rtsp_message_unset (&response);
g_free (luri);
return res;
......@@ -827,8 +829,8 @@ read_failed:
}
wrong_result:
{
GST_ERROR ("got failure response %d %s", response.type_data.response.code,
response.type_data.response.reason);
GST_ERROR ("got failure response %d %s",
response->type_data.response.code, response->type_data.response.reason);
res = GST_RTSP_ERROR;
goto exit;
}
......@@ -849,21 +851,26 @@ remote_address_failed:
}
/**
* gst_rtsp_connection_connect:
* gst_rtsp_connection_connect_with_response:
* @conn: a #GstRTSPConnection
* @timeout: a #GTimeVal timeout
* @response: a #GstRTSPMessage
*
* Attempt to connect to the url of @conn made with
* gst_rtsp_connection_create(). If @timeout is #NULL this function can block
* forever. If @timeout contains a valid timeout, this function will return
* #GST_RTSP_ETIMEOUT after the timeout expired.
* #GST_RTSP_ETIMEOUT after the timeout expired. If @conn is set to tunneled,
* @response will contain a response to the tunneling request messages.
*
* This function can be cancelled with gst_rtsp_connection_flush().
*
* Returns: #GST_RTSP_OK when a connection could be made.
*
* Since 1.8
*/
GstRTSPResult
gst_rtsp_connection_connect (GstRTSPConnection * conn, GTimeVal * timeout)
gst_rtsp_connection_connect_with_response (GstRTSPConnection * conn,
GTimeVal * timeout, GstRTSPMessage * response)
{
GstRTSPResult res;
GSocketConnection *connection;
......@@ -921,7 +928,7 @@ gst_rtsp_connection_connect (GstRTSPConnection * conn, GTimeVal * timeout)
conn->control_stream = NULL;
if (conn->tunneled) {
res = setup_tunneling (conn, timeout, uri);
res = setup_tunneling (conn, timeout, uri, response);
if (res != GST_RTSP_OK)
goto tunneling_failed;
}
......@@ -1077,6 +1084,33 @@ add_auth_header (GstRTSPConnection * conn, GstRTSPMessage * message)
}
}
/**
* gst_rtsp_connection_connect:
* @conn: a #GstRTSPConnection
* @timeout: a #GTimeVal timeout
*
* Attempt to connect to the url of @conn made with
* gst_rtsp_connection_create(). If @timeout is #NULL this function can block
* forever. If @timeout contains a valid timeout, this function will return
* #GST_RTSP_ETIMEOUT after the timeout expired.
*
* This function can be cancelled with gst_rtsp_connection_flush().
*
* Returns: #GST_RTSP_OK when a connection could be made.
*/
GstRTSPResult
gst_rtsp_connection_connect (GstRTSPConnection * conn, GTimeVal * timeout)
{
GstRTSPResult result;
GstRTSPMessage response;
gst_rtsp_message_init (&response);
result = gst_rtsp_connection_connect_with_response (conn, timeout, &response);
gst_rtsp_message_unset (&response);
return result;
}
static void
gen_date_string (gchar * date_string, guint len)
{
......
......@@ -67,10 +67,12 @@ GstRTSPResult gst_rtsp_connection_create_from_socket (GSocket * socket,
guint16 port,
const gchar * initial_buffer,
GstRTSPConnection ** conn);
GstRTSPResult gst_rtsp_connection_accept (GSocket *socket, GstRTSPConnection **conn, GCancellable *cancellable);
GstRTSPResult gst_rtsp_connection_connect (GstRTSPConnection *conn, GTimeVal *timeout);
GstRTSPResult gst_rtsp_connection_close (GstRTSPConnection *conn);
GstRTSPResult gst_rtsp_connection_free (GstRTSPConnection *conn);
GstRTSPResult gst_rtsp_connection_accept (GSocket * socket, GstRTSPConnection ** conn, GCancellable * cancellable);
GstRTSPResult gst_rtsp_connection_connect (GstRTSPConnection * conn, GTimeVal * timeout);
GstRTSPResult gst_rtsp_connection_connect_with_response (GstRTSPConnection * conn, GTimeVal * timeout, GstRTSPMessage * response);
GstRTSPResult gst_rtsp_connection_close (GstRTSPConnection *conn);
GstRTSPResult gst_rtsp_connection_free (GstRTSPConnection *conn);
/* TLS connections */
GTlsConnection * gst_rtsp_connection_get_tls (GstRTSPConnection * conn, GError ** error);
......
......@@ -4,6 +4,7 @@ EXPORTS
gst_rtsp_connection_clear_auth_params
gst_rtsp_connection_close
gst_rtsp_connection_connect
gst_rtsp_connection_connect_with_response
gst_rtsp_connection_create
gst_rtsp_connection_create_from_socket
gst_rtsp_connection_do_tunnel
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment