From 46b4d226ca6ed4efa7574ad7bae46af8c73fc7bd Mon Sep 17 00:00:00 2001 From: Mathias Hasselmann Date: Mon, 25 May 2009 17:24:32 +0200 Subject: neonhttp: add property to support SS cerificates Add a property to support self-signed certificates in neonhttpsrc. This property is FALSE by default. Fixes #511097 --- ext/neon/gstneonhttpsrc.c | 71 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 17 deletions(-) (limited to 'ext/neon/gstneonhttpsrc.c') diff --git a/ext/neon/gstneonhttpsrc.c b/ext/neon/gstneonhttpsrc.c index 739b0132..1af733db 100644 --- a/ext/neon/gstneonhttpsrc.c +++ b/ext/neon/gstneonhttpsrc.c @@ -63,6 +63,7 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", #define DEFAULT_IRADIO_GENRE NULL #define DEFAULT_IRADIO_URL NULL #define DEFAULT_AUTOMATIC_REDIRECT TRUE +#define DEFAULT_ACCEPT_SELF_SIGNED FALSE #define DEFAULT_NEON_HTTP_DEBUG FALSE enum @@ -76,6 +77,7 @@ enum PROP_IRADIO_GENRE, PROP_IRADIO_URL, PROP_AUTOMATIC_REDIRECT, + PROP_ACCEPT_SELF_SIGNED, #ifndef GST_DISABLE_GST_DEBUG PROP_NEON_HTTP_DEBUG #endif @@ -200,6 +202,12 @@ gst_neonhttp_src_class_init (GstNeonhttpSrcClass * klass) "Automatically follow HTTP redirects (HTTP Status Code 302/303)", TRUE, G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, PROP_ACCEPT_SELF_SIGNED, + g_param_spec_boolean ("accept-self-signed", "accept-self-signed", + "Accept self-signed SSL/TLS certificates", + DEFAULT_ACCEPT_SELF_SIGNED, G_PARAM_READWRITE)); + #ifndef GST_DISABLE_GST_DEBUG g_object_class_install_property (gobject_class, PROP_NEON_HTTP_DEBUG, @@ -233,6 +241,7 @@ gst_neonhttp_src_init (GstNeonhttpSrc * src, GstNeonhttpSrcClass * g_class) src->iradio_url = DEFAULT_IRADIO_URL; src->user_agent = g_strdup (DEFAULT_USER_AGENT); src->automatic_redirect = DEFAULT_AUTOMATIC_REDIRECT; + src->accept_self_signed = DEFAULT_ACCEPT_SELF_SIGNED; src->session = NULL; src->request = NULL; @@ -332,28 +341,23 @@ gst_neonhttp_src_set_property (GObject * object, guint prop_id, break; } case PROP_USER_AGENT: - { if (src->user_agent) g_free (src->user_agent); src->user_agent = g_strdup (g_value_get_string (value)); break; - } case PROP_IRADIO_MODE: - { src->iradio_mode = g_value_get_boolean (value); break; - } case PROP_AUTOMATIC_REDIRECT: - { src->automatic_redirect = g_value_get_boolean (value); break; - } + case PROP_ACCEPT_SELF_SIGNED: + src->accept_self_signed = g_value_get_boolean (value); + break; #ifndef GST_DISABLE_GST_DEBUG case PROP_NEON_HTTP_DEBUG: - { src->neon_http_debug = g_value_get_boolean (value); break; - } #endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -401,10 +405,8 @@ gst_neonhttp_src_get_property (GObject * object, guint prop_id, break; } case PROP_USER_AGENT: - { g_value_set_string (value, neonhttpsrc->user_agent); break; - } case PROP_IRADIO_MODE: g_value_set_boolean (value, neonhttpsrc->iradio_mode); break; @@ -420,6 +422,9 @@ gst_neonhttp_src_get_property (GObject * object, guint prop_id, case PROP_AUTOMATIC_REDIRECT: g_value_set_boolean (value, neonhttpsrc->automatic_redirect); break; + case PROP_ACCEPT_SELF_SIGNED: + g_value_set_boolean (value, neonhttpsrc->accept_self_signed); + break; #ifndef GST_DISABLE_GST_DEBUG case PROP_NEON_HTTP_DEBUG: g_value_set_boolean (value, neonhttpsrc->neon_http_debug); @@ -431,6 +436,13 @@ gst_neonhttp_src_get_property (GObject * object, guint prop_id, } } +/* NEON CALLBACK */ +static void +oom_callback () +{ + GST_ERROR ("memory exeception in neon"); +} + static GstFlowReturn gst_neonhttp_src_create (GstPushSrc * psrc, GstBuffer ** outbuf) { @@ -772,6 +784,37 @@ error: } } +static int +ssl_verify_callback (void *data, int failures, const ne_ssl_certificate * cert) +{ + GstNeonhttpSrc *src = GST_NEONHTTP_SRC (data); + + if ((failures & NE_SSL_UNTRUSTED) && + src->accept_self_signed && !ne_ssl_cert_signedby (cert)) { + GST_ELEMENT_INFO (src, RESOURCE, READ, + (NULL), ("Accepting self-signed server certificate")); + + failures &= ~NE_SSL_UNTRUSTED; + } + + if (failures & NE_SSL_NOTYETVALID) + GST_ELEMENT_ERROR (src, RESOURCE, READ, + (NULL), ("Server certificate not valid yet")); + if (failures & NE_SSL_EXPIRED) + GST_ELEMENT_ERROR (src, RESOURCE, READ, + (NULL), ("Server certificate has expired")); + if (failures & NE_SSL_IDMISMATCH) + GST_ELEMENT_ERROR (src, RESOURCE, READ, + (NULL), ("Server certificate doesn't match hostname")); + if (failures & NE_SSL_UNTRUSTED) + GST_ELEMENT_ERROR (src, RESOURCE, READ, + (NULL), ("Server certificate signer not trusted")); + + GST_DEBUG_OBJECT (src, "failures: %d\n", failures); + + return failures; +} + /* Try to send the HTTP request to the Icecast server, and if possible deals with * all the probable redirections (HTTP status code == 302/303) */ @@ -799,6 +842,7 @@ gst_neonhttp_src_send_request_and_redirect (GstNeonhttpSrc * src, } ne_set_session_flag (session, NE_SESSFLAG_ICYPROTO, 1); + ne_ssl_set_verify (session, ssl_verify_callback, src); request = ne_request_create (session, "GET", src->query_string); @@ -1014,13 +1058,6 @@ gst_neonhttp_src_uri_handler_init (gpointer g_iface, gpointer iface_data) iface->set_uri = gst_neonhttp_src_uri_set_uri; } -/* NEON CALLBACK */ -static void -oom_callback () -{ - GST_ERROR ("memory exeception in neon"); -} - /* entry point to initialize the plug-in * initialize the plug-in itself * register the element factories and pad templates -- cgit v1.2.1