#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
PROP_IRADIO_GENRE,
PROP_IRADIO_URL,
PROP_AUTOMATIC_REDIRECT,
+ PROP_ACCEPT_SELF_SIGNED,
#ifndef GST_DISABLE_GST_DEBUG
PROP_NEON_HTTP_DEBUG
#endif
"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,
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;
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);
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;
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);
}
}
+/* NEON CALLBACK */
+static void
+oom_callback ()
+{
+ GST_ERROR ("memory exeception in neon");
+}
+
static GstFlowReturn
gst_neonhttp_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
{
}
}
+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)
*/
}
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);
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