mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-21 13:36:39 +00:00
rtspconnection: allow specifying a certificate database
Two new functions have been added, gst_rtsp_connection_set_tls_database() and gst_rtsp_connection_get_tls_database(). The certificate database will be used when a certificate can't be verified with the default database. https://bugzilla.gnome.org/show_bug.cgi?id=724393
This commit is contained in:
parent
9121b16aa0
commit
0a115bd31f
2 changed files with 126 additions and 1 deletions
|
@ -151,6 +151,9 @@ struct _GstRTSPConnection
|
||||||
gchar *passwd;
|
gchar *passwd;
|
||||||
GHashTable *auth_params;
|
GHashTable *auth_params;
|
||||||
|
|
||||||
|
/* TLS */
|
||||||
|
GTlsDatabase *tls_database;
|
||||||
|
|
||||||
DecodeCtx ctx;
|
DecodeCtx ctx;
|
||||||
DecodeCtx *ctxp;
|
DecodeCtx *ctxp;
|
||||||
|
|
||||||
|
@ -195,6 +198,66 @@ build_reset (GstRTSPBuilder * builder)
|
||||||
memset (builder, 0, sizeof (GstRTSPBuilder));
|
memset (builder, 0, sizeof (GstRTSPBuilder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
tls_accept_certificate (GTlsConnection * conn, GTlsCertificate * peer_cert,
|
||||||
|
GTlsCertificateFlags errors, GstRTSPConnection * rtspconn)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
gboolean accept = FALSE;
|
||||||
|
|
||||||
|
if (rtspconn->tls_database) {
|
||||||
|
GSocketConnectable *peer_identity;
|
||||||
|
GTlsCertificateFlags validation_flags;
|
||||||
|
|
||||||
|
GST_DEBUG ("TLS peer certificate not accepted, checking user database...");
|
||||||
|
|
||||||
|
peer_identity =
|
||||||
|
g_tls_client_connection_get_server_identity (G_TLS_CLIENT_CONNECTION
|
||||||
|
(conn));
|
||||||
|
|
||||||
|
errors =
|
||||||
|
g_tls_database_verify_chain (rtspconn->tls_database, peer_cert,
|
||||||
|
G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER, peer_identity,
|
||||||
|
g_tls_connection_get_interaction (conn), G_TLS_DATABASE_VERIFY_NONE,
|
||||||
|
NULL, &error);
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
goto verify_error;
|
||||||
|
|
||||||
|
validation_flags = gst_rtsp_connection_get_tls_validation_flags (rtspconn);
|
||||||
|
|
||||||
|
accept = ((errors & validation_flags) == 0);
|
||||||
|
if (accept)
|
||||||
|
GST_DEBUG ("Peer certificate accepted");
|
||||||
|
else
|
||||||
|
GST_DEBUG ("Peer certificate not accepted (errors: 0x%08X)", errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
return accept;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
|
verify_error:
|
||||||
|
{
|
||||||
|
GST_ERROR ("An error occurred while verifying the peer certificate: %s",
|
||||||
|
error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
socket_client_event (GSocketClient * client, GSocketClientEvent event,
|
||||||
|
GSocketConnectable * connectable, GIOStream * connection,
|
||||||
|
GstRTSPConnection * rtspconn)
|
||||||
|
{
|
||||||
|
if (event == G_SOCKET_CLIENT_TLS_HANDSHAKING) {
|
||||||
|
GST_DEBUG ("TLS handshaking about to start...");
|
||||||
|
|
||||||
|
g_signal_connect (connection, "accept-certificate",
|
||||||
|
(GCallback) tls_accept_certificate, rtspconn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_rtsp_connection_create:
|
* gst_rtsp_connection_create:
|
||||||
* @url: a #GstRTSPUrl
|
* @url: a #GstRTSPUrl
|
||||||
|
@ -225,6 +288,9 @@ gst_rtsp_connection_create (const GstRTSPUrl * url, GstRTSPConnection ** conn)
|
||||||
if (url->transports & GST_RTSP_LOWER_TRANS_TLS)
|
if (url->transports & GST_RTSP_LOWER_TRANS_TLS)
|
||||||
g_socket_client_set_tls (newconn->client, TRUE);
|
g_socket_client_set_tls (newconn->client, TRUE);
|
||||||
|
|
||||||
|
g_signal_connect (newconn->client, "event", (GCallback) socket_client_event,
|
||||||
|
newconn);
|
||||||
|
|
||||||
newconn->url = gst_rtsp_url_copy (url);
|
newconn->url = gst_rtsp_url_copy (url);
|
||||||
newconn->timer = g_timer_new ();
|
newconn->timer = g_timer_new ();
|
||||||
newconn->timeout = 60;
|
newconn->timeout = 60;
|
||||||
|
@ -493,6 +559,62 @@ gst_rtsp_connection_get_tls_validation_flags (GstRTSPConnection * conn)
|
||||||
return g_socket_client_get_tls_validation_flags (conn->client);
|
return g_socket_client_get_tls_validation_flags (conn->client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_connection_set_tls_database:
|
||||||
|
* @conn: a #GstRTSPConnection
|
||||||
|
* @database: a #GTlsDatabase
|
||||||
|
*
|
||||||
|
* Sets the anchor certificate authorities database. This certificate
|
||||||
|
* database will be used to verify the server's certificate in case it
|
||||||
|
* can't be verified with the default certificate database first.
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gst_rtsp_connection_set_tls_database (GstRTSPConnection * conn,
|
||||||
|
GTlsDatabase * database)
|
||||||
|
{
|
||||||
|
GTlsDatabase *old_db;
|
||||||
|
|
||||||
|
g_return_if_fail (conn != NULL);
|
||||||
|
|
||||||
|
if (database)
|
||||||
|
g_object_ref (database);
|
||||||
|
|
||||||
|
old_db = conn->tls_database;
|
||||||
|
conn->tls_database = database;
|
||||||
|
|
||||||
|
if (old_db)
|
||||||
|
g_object_unref (old_db);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_rtsp_connection_get_tls_database:
|
||||||
|
* @conn: a #GstRTSPConnection
|
||||||
|
*
|
||||||
|
* Gets the anchor certificate authorities database that will be used
|
||||||
|
* after a server certificate can't be verified with the default
|
||||||
|
* certificate database.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): the anchor certificate authorities database, or NULL if no
|
||||||
|
* database has been previously set. Use g_object_unref() to release the
|
||||||
|
* certificate database.
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
*/
|
||||||
|
GTlsDatabase *
|
||||||
|
gst_rtsp_connection_get_tls_database (GstRTSPConnection * conn)
|
||||||
|
{
|
||||||
|
GTlsDatabase *result;
|
||||||
|
|
||||||
|
g_return_val_if_fail (conn != NULL, NULL);
|
||||||
|
|
||||||
|
if ((result = conn->tls_database))
|
||||||
|
g_object_ref (result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static GstRTSPResult
|
static GstRTSPResult
|
||||||
setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout, gchar * uri)
|
setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout, gchar * uri)
|
||||||
{
|
{
|
||||||
|
@ -2147,6 +2269,8 @@ gst_rtsp_connection_free (GstRTSPConnection * conn)
|
||||||
g_object_unref (conn->cancellable);
|
g_object_unref (conn->cancellable);
|
||||||
if (conn->client)
|
if (conn->client)
|
||||||
g_object_unref (conn->client);
|
g_object_unref (conn->client);
|
||||||
|
if (conn->tls_database)
|
||||||
|
g_object_unref (conn->tls_database);
|
||||||
|
|
||||||
g_timer_destroy (conn->timer);
|
g_timer_destroy (conn->timer);
|
||||||
gst_rtsp_url_free (conn->url);
|
gst_rtsp_url_free (conn->url);
|
||||||
|
|
|
@ -76,7 +76,8 @@ GstRTSPResult gst_rtsp_connection_free (GstRTSPConnection *conn);
|
||||||
GTlsConnection * gst_rtsp_connection_get_tls (GstRTSPConnection * conn, GError ** error);
|
GTlsConnection * gst_rtsp_connection_get_tls (GstRTSPConnection * conn, GError ** error);
|
||||||
gboolean gst_rtsp_connection_set_tls_validation_flags (GstRTSPConnection * conn, GTlsCertificateFlags flags);
|
gboolean gst_rtsp_connection_set_tls_validation_flags (GstRTSPConnection * conn, GTlsCertificateFlags flags);
|
||||||
GTlsCertificateFlags gst_rtsp_connection_get_tls_validation_flags (GstRTSPConnection * conn);
|
GTlsCertificateFlags gst_rtsp_connection_get_tls_validation_flags (GstRTSPConnection * conn);
|
||||||
|
void gst_rtsp_connection_set_tls_database (GstRTSPConnection * conn, GTlsDatabase * database);
|
||||||
|
GTlsDatabase * gst_rtsp_connection_get_tls_database (GstRTSPConnection * conn);
|
||||||
|
|
||||||
/* sending/receiving raw bytes */
|
/* sending/receiving raw bytes */
|
||||||
GstRTSPResult gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data,
|
GstRTSPResult gst_rtsp_connection_read (GstRTSPConnection * conn, guint8 * data,
|
||||||
|
|
Loading…
Reference in a new issue