]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/tls_openssl.c
avformat: fix ID3v2 parser for v2.2 comment frames
[ffmpeg] / libavformat / tls_openssl.c
index 46eb3e68c7e0a4aba1b76318137af8e9c3799bfb..3d9768a805826d5c0285a48ab9b7b13cf2441438 100644 (file)
@@ -43,6 +43,9 @@ typedef struct TLSContext {
     TLSShared tls_shared;
     SSL_CTX *ctx;
     SSL *ssl;
+#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+    BIO_METHOD* url_bio_method;
+#endif
 } TLSContext;
 
 #if HAVE_THREADS
@@ -63,6 +66,87 @@ static unsigned long openssl_thread_id(void)
 #endif
 #endif
 
+static int url_bio_create(BIO *b)
+{
+#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+    BIO_set_init(b, 1);
+    BIO_set_data(b, NULL);
+    BIO_set_flags(b, 0);
+#else
+    b->init = 1;
+    b->ptr = NULL;
+    b->flags = 0;
+#endif
+    return 1;
+}
+
+static int url_bio_destroy(BIO *b)
+{
+    return 1;
+}
+
+#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+#define GET_BIO_DATA(x) BIO_get_data(x);
+#else
+#define GET_BIO_DATA(x) (x)->ptr;
+#endif
+
+static int url_bio_bread(BIO *b, char *buf, int len)
+{
+    URLContext *h;
+    int ret;
+    h = GET_BIO_DATA(b);
+    ret = ffurl_read(h, buf, len);
+    if (ret >= 0)
+        return ret;
+    BIO_clear_retry_flags(b);
+    if (ret == AVERROR_EXIT)
+        return 0;
+    return -1;
+}
+
+static int url_bio_bwrite(BIO *b, const char *buf, int len)
+{
+    URLContext *h;
+    int ret;
+    h = GET_BIO_DATA(b);
+    ret = ffurl_write(h, buf, len);
+    if (ret >= 0)
+        return ret;
+    BIO_clear_retry_flags(b);
+    if (ret == AVERROR_EXIT)
+        return 0;
+    return -1;
+}
+
+static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
+{
+    if (cmd == BIO_CTRL_FLUSH) {
+        BIO_clear_retry_flags(b);
+        return 1;
+    }
+    return 0;
+}
+
+static int url_bio_bputs(BIO *b, const char *str)
+{
+    return url_bio_bwrite(b, str, strlen(str));
+}
+
+#if OPENSSL_VERSION_NUMBER < 0x1010000fL
+static BIO_METHOD url_bio_method = {
+    .type = BIO_TYPE_SOURCE_SINK,
+    .name = "urlprotocol bio",
+    .bwrite = url_bio_bwrite,
+    .bread = url_bio_bread,
+    .bputs = url_bio_bputs,
+    .bgets = NULL,
+    .ctrl = url_bio_ctrl,
+    .create = url_bio_create,
+    .destroy = url_bio_destroy,
+};
+#endif
+
 int ff_openssl_init(void)
 {
     avpriv_lock_avformat();
@@ -128,73 +212,14 @@ static int tls_close(URLContext *h)
         SSL_CTX_free(c->ctx);
     if (c->tls_shared.tcp)
         ffurl_close(c->tls_shared.tcp);
+#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+    if (c->url_bio_method)
+        BIO_meth_free(c->url_bio_method);
+#endif
     ff_openssl_deinit();
     return 0;
 }
 
-static int url_bio_create(BIO *b)
-{
-    b->init = 1;
-    b->ptr = NULL;
-    b->flags = 0;
-    return 1;
-}
-
-static int url_bio_destroy(BIO *b)
-{
-    return 1;
-}
-
-static int url_bio_bread(BIO *b, char *buf, int len)
-{
-    URLContext *h = b->ptr;
-    int ret = ffurl_read(h, buf, len);
-    if (ret >= 0)
-        return ret;
-    BIO_clear_retry_flags(b);
-    if (ret == AVERROR_EXIT)
-        return 0;
-    return -1;
-}
-
-static int url_bio_bwrite(BIO *b, const char *buf, int len)
-{
-    URLContext *h = b->ptr;
-    int ret = ffurl_write(h, buf, len);
-    if (ret >= 0)
-        return ret;
-    BIO_clear_retry_flags(b);
-    if (ret == AVERROR_EXIT)
-        return 0;
-    return -1;
-}
-
-static long url_bio_ctrl(BIO *b, int cmd, long num, void *ptr)
-{
-    if (cmd == BIO_CTRL_FLUSH) {
-        BIO_clear_retry_flags(b);
-        return 1;
-    }
-    return 0;
-}
-
-static int url_bio_bputs(BIO *b, const char *str)
-{
-    return url_bio_bwrite(b, str, strlen(str));
-}
-
-static BIO_METHOD url_bio_method = {
-    .type = BIO_TYPE_SOURCE_SINK,
-    .name = "urlprotocol bio",
-    .bwrite = url_bio_bwrite,
-    .bread = url_bio_bread,
-    .bputs = url_bio_bputs,
-    .bgets = NULL,
-    .ctrl = url_bio_ctrl,
-    .create = url_bio_create,
-    .destroy = url_bio_destroy,
-};
-
 static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **options)
 {
     TLSContext *p = h->priv_data;
@@ -208,12 +233,17 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op
     if ((ret = ff_tls_open_underlying(c, h, uri, options)) < 0)
         goto fail;
 
-    p->ctx = SSL_CTX_new(c->listen ? TLSv1_server_method() : TLSv1_client_method());
+    // We want to support all versions of TLS >= 1.0, but not the deprecated
+    // and insecure SSLv2 and SSLv3.  Despite the name, SSLv23_*_method()
+    // enables support for all versions of SSL and TLS, and we then disable
+    // support for the old protocols immediately after creating the context.
+    p->ctx = SSL_CTX_new(c->listen ? SSLv23_server_method() : SSLv23_client_method());
     if (!p->ctx) {
         av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
         ret = AVERROR(EIO);
         goto fail;
     }
+    SSL_CTX_set_options(p->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
     if (c->ca_file) {
         if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL))
             av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL));
@@ -240,8 +270,20 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op
         ret = AVERROR(EIO);
         goto fail;
     }
+#if OPENSSL_VERSION_NUMBER >= 0x1010000fL
+    p->url_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "urlprotocol bio");
+    BIO_meth_set_write(p->url_bio_method, url_bio_bwrite);
+    BIO_meth_set_read(p->url_bio_method, url_bio_bread);
+    BIO_meth_set_puts(p->url_bio_method, url_bio_bputs);
+    BIO_meth_set_ctrl(p->url_bio_method, url_bio_ctrl);
+    BIO_meth_set_create(p->url_bio_method, url_bio_create);
+    BIO_meth_set_destroy(p->url_bio_method, url_bio_destroy);
+    bio = BIO_new(p->url_bio_method);
+    BIO_set_data(bio, c->tcp);
+#else
     bio = BIO_new(&url_bio_method);
     bio->ptr = c->tcp;
+#endif
     SSL_set_bio(p->ssl, bio, bio);
     if (!c->listen && !c->numerichost)
         SSL_set_tlsext_host_name(p->ssl, c->host);
@@ -283,6 +325,12 @@ static int tls_write(URLContext *h, const uint8_t *buf, int size)
     return print_tls_error(h, ret);
 }
 
+static int tls_get_file_handle(URLContext *h)
+{
+    TLSContext *c = h->priv_data;
+    return ffurl_get_file_handle(c->tls_shared.tcp);
+}
+
 static const AVOption options[] = {
     TLS_COMMON_OPTIONS(TLSContext, tls_shared),
     { NULL }
@@ -301,6 +349,7 @@ const URLProtocol ff_tls_openssl_protocol = {
     .url_read       = tls_read,
     .url_write      = tls_write,
     .url_close      = tls_close,
+    .url_get_file_handle = tls_get_file_handle,
     .priv_data_size = sizeof(TLSContext),
     .flags          = URL_PROTOCOL_FLAG_NETWORK,
     .priv_data_class = &tls_class,