From 93629735d76c09405248c1f6b2b2c5517fff88fd Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Thu, 3 Mar 2016 17:14:26 +0000 Subject: [PATCH] avformat: Add a protocol blacklisting API Signed-off-by: Derek Buitenhuis --- Changelog | 1 + doc/APIchanges | 3 +++ libavformat/async.c | 2 +- libavformat/avformat.h | 11 +++++++++-- libavformat/avidec.c | 2 +- libavformat/avio.c | 22 ++++++++++++++++++++-- libavformat/avio.h | 5 +++++ libavformat/avio_internal.h | 2 +- libavformat/aviobuf.c | 13 +++++++++---- libavformat/cache.c | 2 +- libavformat/concat.c | 2 +- libavformat/concatdec.c | 2 +- libavformat/crypto.c | 2 +- libavformat/ftp.c | 4 ++-- libavformat/gopher.c | 2 +- libavformat/hls.c | 2 +- libavformat/hlsproto.c | 4 ++-- libavformat/http.c | 6 +++--- libavformat/icecast.c | 2 +- libavformat/internal.h | 2 +- libavformat/md5proto.c | 2 +- libavformat/mmst.c | 2 +- libavformat/mpeg.c | 2 +- libavformat/options.c | 2 +- libavformat/options_table.h | 1 + libavformat/rdt.c | 2 +- libavformat/rtmpcrypt.c | 2 +- libavformat/rtmpproto.c | 4 ++-- libavformat/rtpdec_asf.c | 2 +- libavformat/rtpproto.c | 6 +++--- libavformat/rtsp.c | 10 +++++----- libavformat/rtspdec.c | 4 ++-- libavformat/sapdec.c | 4 ++-- libavformat/sapenc.c | 4 ++-- libavformat/smoothstreamingenc.c | 8 ++++---- libavformat/srtpproto.c | 2 +- libavformat/subfile.c | 2 +- libavformat/tls.c | 2 +- libavformat/tls_securetransport.c | 2 +- libavformat/url.h | 3 ++- libavformat/utils.c | 19 +++++++++++++++---- libavformat/version.h | 4 ++-- 42 files changed, 116 insertions(+), 64 deletions(-) diff --git a/Changelog b/Changelog index d6459a85cf..0e70724f1a 100644 --- a/Changelog +++ b/Changelog @@ -10,6 +10,7 @@ version : - datascope filter - bench and abench filters - ciescope filter +- protocol blacklisting API version 3.0: diff --git a/doc/APIchanges b/doc/APIchanges index a75f3468f1..2fc6a71942 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-XX-XX - xxxxxxx - lavf 57.28.100 + Add protocol blacklisting API + 2016-02-28 - xxxxxxx - lavc 57.27.101 Validate AVFrame returned by get_buffer2 to have required planes not NULL and unused planes set to NULL as crashes diff --git a/libavformat/async.c b/libavformat/async.c index a835292e05..0cc6fb0e27 100644 --- a/libavformat/async.c +++ b/libavformat/async.c @@ -251,7 +251,7 @@ static int async_open(URLContext *h, const char *arg, int flags, AVDictionary ** /* wrap interrupt callback */ c->interrupt_callback = h->interrupt_callback; - ret = ffurl_open_whitelist(&c->inner, arg, flags, &interrupt_callback, options, h->protocol_whitelist); + ret = ffurl_open_whitelist(&c->inner, arg, flags, &interrupt_callback, options, h->protocol_whitelist, h->protocol_blacklist); if (ret != 0) { av_log(h, AV_LOG_ERROR, "ffurl_open failed : %s, %s\n", av_err2str(ret), arg); goto url_fail; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index b843a4b344..ef34c86129 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1832,11 +1832,11 @@ typedef struct AVFormatContext { #endif /** - * ',' separated list of allowed protocols. + * ',' separated list of disallowed protocols. * - encoding: unused * - decoding: set by user through AVOptions (NO direct access) */ - char *protocol_whitelist; + char *protocol_blacklist; /* * A callback for opening new IO streams. @@ -1865,6 +1865,13 @@ typedef struct AVFormatContext { * A callback for closing the streams opened with AVFormatContext.io_open(). */ void (*io_close)(struct AVFormatContext *s, AVIOContext *pb); + + /** + * ',' separated list of disallowed protocols. + * - encoding: unused + * - decoding: set by user through AVOptions (NO direct access) + */ + char *protocol_blacklist; } AVFormatContext; int av_format_get_probe_score(const AVFormatContext *s); diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 38598107fc..eaf842141c 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -1089,7 +1089,7 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) ast->sub_ctx->pb = pb; - if (ff_copy_whitelists(ast->sub_ctx, s) < 0) + if (ff_copy_whiteblacklists(ast->sub_ctx, s) < 0) goto error; if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) { diff --git a/libavformat/avio.c b/libavformat/avio.c index 69b6eaac83..0be820b9ec 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -55,6 +55,7 @@ static void *urlcontext_child_next(void *obj, void *prev) #define D AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { {"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, + {"protocol_blacklist", "List of protocols that are not allowed to be used", OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, { NULL } }; @@ -173,12 +174,19 @@ int ffurl_connect(URLContext *uc, AVDictionary **options) // Check that URLContext was initialized correctly and lists are matching if set av_assert0(!(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) || (uc->protocol_whitelist && !strcmp(uc->protocol_whitelist, e->value))); + av_assert0(!(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) || + (uc->protocol_blacklist && !strcmp(uc->protocol_blacklist, e->value))); if (uc->protocol_whitelist && av_match_list(uc->prot->name, uc->protocol_whitelist, ',') <= 0) { av_log(uc, AV_LOG_ERROR, "Protocol not on whitelist \'%s\'!\n", uc->protocol_whitelist); return AVERROR(EINVAL); } + if (uc->protocol_blacklist && av_match_list(uc->prot->name, uc->protocol_blacklist, ',') > 0) { + av_log(uc, AV_LOG_ERROR, "Protocol blacklisted \'%s\'!\n", uc->protocol_blacklist); + return AVERROR(EINVAL); + } + if (!uc->protocol_whitelist && uc->prot->default_whitelist) { av_log(uc, AV_LOG_DEBUG, "Setting default whitelist '%s'\n", uc->prot->default_whitelist); uc->protocol_whitelist = av_strdup(uc->prot->default_whitelist); @@ -190,6 +198,8 @@ int ffurl_connect(URLContext *uc, AVDictionary **options) if ((err = av_dict_set(options, "protocol_whitelist", uc->protocol_whitelist, 0)) < 0) return err; + if ((err = av_dict_set(options, "protocol_blacklist", uc->protocol_blacklist, 0)) < 0) + return err; err = uc->prot->url_open2 ? uc->prot->url_open2(uc, @@ -199,6 +209,7 @@ int ffurl_connect(URLContext *uc, AVDictionary **options) uc->prot->url_open(uc, uc->filename, uc->flags); av_dict_set(options, "protocol_whitelist", NULL, 0); + av_dict_set(options, "protocol_blacklist", NULL, 0); if (err) return err; @@ -290,7 +301,8 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags, } int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist) + const AVIOInterruptCB *int_cb, AVDictionary **options, + const char *whitelist, const char* blacklist) { AVDictionary *tmp_opts = NULL; AVDictionaryEntry *e; @@ -307,10 +319,16 @@ int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, av_assert0(!whitelist || !(e=av_dict_get(*options, "protocol_whitelist", NULL, 0)) || !strcmp(whitelist, e->value)); + av_assert0(!blacklist || + !(e=av_dict_get(*options, "protocol_blacklist", NULL, 0)) || + !strcmp(blacklist, e->value)); if ((ret = av_dict_set(options, "protocol_whitelist", whitelist, 0)) < 0) goto fail; + if ((ret = av_dict_set(options, "protocol_blacklist", blacklist, 0)) < 0) + goto fail; + if ((ret = av_opt_set_dict(*puc, options)) < 0) goto fail; @@ -328,7 +346,7 @@ int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options) { return ffurl_open_whitelist(puc, filename, flags, - int_cb, options, NULL); + int_cb, options, NULL, NULL); } static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf, diff --git a/libavformat/avio.h b/libavformat/avio.h index 7fbce32b6c..23214031f1 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -254,6 +254,11 @@ typedef struct AVIOContext { * ',' separated list of allowed protocols. */ const char *protocol_whitelist; + + /** + * ',' separated list of disallowed protocols. + */ + const char *protocol_blacklist; } AVIOContext; /* unbuffered I/O */ diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h index 1e2a18e161..ba9bd4e2a4 100644 --- a/libavformat/avio_internal.h +++ b/libavformat/avio_internal.h @@ -155,7 +155,7 @@ int ffio_open_null_buf(AVIOContext **s); int ffio_open_whitelist(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, - const char *whitelist); + const char *whitelist, const char *blacklist); /** * Close a null buffer. diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index e45afd1cef..00f7c5a180 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -848,6 +848,11 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) avio_closep(s); goto fail; } + (*s)->protocol_blacklist = av_strdup(h->protocol_blacklist); + if (!(*s)->protocol_blacklist && h->protocol_blacklist) { + avio_closep(s); + goto fail; + } (*s)->direct = h->flags & AVIO_FLAG_DIRECT; (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL; @@ -974,13 +979,13 @@ int avio_open(AVIOContext **s, const char *filename, int flags) int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, - const char *whitelist + const char *whitelist, const char *blacklist ) { URLContext *h; int err; - err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist); + err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist); if (err < 0) return err; err = ffio_fdopen(s, h); @@ -994,13 +999,13 @@ int ffio_open_whitelist(AVIOContext **s, const char *filename, int flags, int avio_open2(AVIOContext **s, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options) { - return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL); + return ffio_open_whitelist(s, filename, flags, int_cb, options, NULL, NULL); } int ffio_open2_wrapper(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options) { - return ffio_open_whitelist(pb, url, flags, int_cb, options, s->protocol_whitelist); + return ffio_open_whitelist(pb, url, flags, int_cb, options, s->protocol_whitelist, s->protocol_blacklist); } int avio_close(AVIOContext *s) diff --git a/libavformat/cache.c b/libavformat/cache.c index 59d7fe6bdf..1d26cb8e1e 100644 --- a/libavformat/cache.c +++ b/libavformat/cache.c @@ -87,7 +87,7 @@ static int cache_open(URLContext *h, const char *arg, int flags, AVDictionary ** av_freep(&buffername); return ffurl_open_whitelist(&c->inner, arg, flags, &h->interrupt_callback, - options, h->protocol_whitelist); + options, h->protocol_whitelist, h->protocol_blacklist); } static int add_entry(URLContext *h, const unsigned char *buf, int size) diff --git a/libavformat/concat.c b/libavformat/concat.c index 190f36d43a..288bf14452 100644 --- a/libavformat/concat.c +++ b/libavformat/concat.c @@ -98,7 +98,7 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) /* creating URLContext */ err = ffurl_open_whitelist(&uc, node_uri, flags, - &h->interrupt_callback, NULL, h->protocol_whitelist); + &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist); if (err < 0) break; diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index d226e1504e..e69096f919 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -301,7 +301,7 @@ static int open_file(AVFormatContext *avf, unsigned fileno) cat->avf->interrupt_callback = avf->interrupt_callback; - if ((ret = ff_copy_whitelists(cat->avf, avf)) < 0) + if ((ret = ff_copy_whiteblacklists(cat->avf, avf)) < 0) return ret; if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 || diff --git a/libavformat/crypto.c b/libavformat/crypto.c index 221cb9aa9a..4222e1e33f 100644 --- a/libavformat/crypto.c +++ b/libavformat/crypto.c @@ -138,7 +138,7 @@ static int crypto_open2(URLContext *h, const char *uri, int flags, AVDictionary if ((ret = ffurl_open_whitelist(&c->hd, nested_url, flags, &h->interrupt_callback, options, - h->protocol_whitelist)) < 0) { + h->protocol_whitelist, h->protocol_blacklist)) < 0) { av_log(h, AV_LOG_ERROR, "Unable to open resource: %s\n", nested_url); goto err; } diff --git a/libavformat/ftp.c b/libavformat/ftp.c index 50b28e2c2b..890930c4f0 100644 --- a/libavformat/ftp.c +++ b/libavformat/ftp.c @@ -539,7 +539,7 @@ static int ftp_connect_control_connection(URLContext *h) } /* if option is not given, don't pass it and let tcp use its own default */ err = ffurl_open_whitelist(&s->conn_control, buf, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, &opts, - h->protocol_whitelist); + h->protocol_whitelist, h->protocol_blacklist); av_dict_free(&opts); if (err < 0) { av_log(h, AV_LOG_ERROR, "Cannot open control connection\n"); @@ -593,7 +593,7 @@ static int ftp_connect_data_connection(URLContext *h) } /* if option is not given, don't pass it and let tcp use its own default */ err = ffurl_open_whitelist(&s->conn_data, buf, h->flags, &h->interrupt_callback, &opts, - h->protocol_whitelist); + h->protocol_whitelist, h->protocol_blacklist); av_dict_free(&opts); if (err < 0) return err; diff --git a/libavformat/gopher.c b/libavformat/gopher.c index 271c825b3b..d1113e74e9 100644 --- a/libavformat/gopher.c +++ b/libavformat/gopher.c @@ -94,7 +94,7 @@ static int gopher_open(URLContext *h, const char *uri, int flags) s->hd = NULL; err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, NULL, h->protocol_whitelist); + &h->interrupt_callback, NULL, h->protocol_whitelist, h->protocol_blacklist); if (err < 0) goto fail; diff --git a/libavformat/hls.c b/libavformat/hls.c index 171544501b..61ab5c8435 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -1619,7 +1619,7 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->io_open = nested_io_open; pls->stream_offset = stream_offset; - if ((ret = ff_copy_whitelists(pls->ctx, s)) < 0) + if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0) goto fail; ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL); diff --git a/libavformat/hlsproto.c b/libavformat/hlsproto.c index 1f2e63dff2..097e5203c3 100644 --- a/libavformat/hlsproto.c +++ b/libavformat/hlsproto.c @@ -119,7 +119,7 @@ static int parse_playlist(URLContext *h, const char *url) if ((ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, &h->interrupt_callback, NULL, - h->protocol_whitelist)) < 0) + h->protocol_whitelist, h->protocol_blacklist)) < 0) return ret; read_chomp_line(in, line, sizeof(line)); @@ -307,7 +307,7 @@ retry: av_log(h, AV_LOG_DEBUG, "opening %s\n", url); ret = ffurl_open_whitelist(&s->seg_hd, url, AVIO_FLAG_READ, &h->interrupt_callback, NULL, - h->protocol_whitelist); + h->protocol_whitelist, h->protocol_blacklist); if (ret < 0) { if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; diff --git a/libavformat/http.c b/libavformat/http.c index a4ce479e34..ae77b646f7 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -221,7 +221,7 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) if (!s->hd) { err = ffurl_open_whitelist(&s->hd, buf, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, options, - h->protocol_whitelist); + h->protocol_whitelist, h->protocol_blacklist); if (err < 0) return err; } @@ -456,7 +456,7 @@ static int http_listen(URLContext *h, const char *uri, int flags, goto fail; if ((ret = ffurl_open_whitelist(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, options, - h->protocol_whitelist + h->protocol_whitelist, h->protocol_blacklist )) < 0) goto fail; s->handshake_step = LOWER_PROTO; @@ -1582,7 +1582,7 @@ static int http_proxy_open(URLContext *h, const char *uri, int flags) redo: ret = ffurl_open_whitelist(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, NULL, - h->protocol_whitelist); + h->protocol_whitelist, h->protocol_blacklist); if (ret < 0) return ret; diff --git a/libavformat/icecast.c b/libavformat/icecast.c index e5f1a95379..f7ca5cb30c 100644 --- a/libavformat/icecast.c +++ b/libavformat/icecast.c @@ -165,7 +165,7 @@ static int icecast_open(URLContext *h, const char *uri, int flags) ff_url_join(h_url, sizeof(h_url), "http", auth, host, port, "%s", path); // Finally open http proto handler ret = ffurl_open_whitelist(&s->hd, h_url, AVIO_FLAG_READ_WRITE, NULL, - &opt_dict, h->protocol_whitelist); + &opt_dict, h->protocol_whitelist, h->protocol_blacklist); cleanup: av_freep(&user); diff --git a/libavformat/internal.h b/libavformat/internal.h index 37a8591ea2..7defce88a7 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -532,7 +532,7 @@ enum AVWriteUncodedFrameFlags { /** * Copies the whilelists from one context to the other */ -int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src); +int ff_copy_whiteblacklists(AVFormatContext *dst, AVFormatContext *src); int ffio_open2_wrapper(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options); diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c index 3d8c2a084e..2df34c6350 100644 --- a/libavformat/md5proto.c +++ b/libavformat/md5proto.c @@ -71,7 +71,7 @@ static int md5_close(URLContext *h) if (*filename) { err = ffurl_open_whitelist(&out, filename, AVIO_FLAG_WRITE, &h->interrupt_callback, NULL, - h->protocol_whitelist); + h->protocol_whitelist, h->protocol_blacklist); if (err) return err; err = ffurl_write(out, buf, i*2+1); diff --git a/libavformat/mmst.c b/libavformat/mmst.c index b168903378..0f48b4615e 100644 --- a/libavformat/mmst.c +++ b/libavformat/mmst.c @@ -530,7 +530,7 @@ static int mms_open(URLContext *h, const char *uri, int flags) ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL); err = ffurl_open_whitelist(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, NULL, - h->protocol_whitelist); + h->protocol_whitelist, h->protocol_blacklist); if (err) goto fail; diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 69685cf890..a7ceeaf01d 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -732,7 +732,7 @@ static int vobsub_read_header(AVFormatContext *s) goto end; } - if ((ret = ff_copy_whitelists(vobsub->sub_ctx, s)) < 0) + if ((ret = ff_copy_whiteblacklists(vobsub->sub_ctx, s)) < 0) goto end; ret = avformat_open_input(&vobsub->sub_ctx, vobsub->sub_name, iformat, NULL); diff --git a/libavformat/options.c b/libavformat/options.c index 8fe0017196..04d9c454d3 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -109,7 +109,7 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif - return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist); + return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist); } static void io_close_default(AVFormatContext *s, AVIOContext *pb) diff --git a/libavformat/options_table.h b/libavformat/options_table.h index 74923d88b9..0be5221fb3 100644 --- a/libavformat/options_table.h +++ b/libavformat/options_table.h @@ -101,6 +101,7 @@ static const AVOption avformat_options[] = { {"codec_whitelist", "List of decoders that are allowed to be used", OFFSET(codec_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, {"format_whitelist", "List of demuxers that are allowed to be used", OFFSET(format_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, {"protocol_whitelist", "List of protocols that are allowed to be used", OFFSET(protocol_whitelist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, +{"protocol_blacklist", "List of protocols that are not allowed to be used", OFFSET(protocol_blacklist), AV_OPT_TYPE_STRING, { .str = NULL }, CHAR_MIN, CHAR_MAX, D }, {NULL}, }; diff --git a/libavformat/rdt.c b/libavformat/rdt.c index c3ac19852f..0300b76928 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -531,7 +531,7 @@ static av_cold int rdt_init(AVFormatContext *s, int st_index, PayloadContext *rd if (!rdt->rmctx) return AVERROR(ENOMEM); - if ((ret = ff_copy_whitelists(rdt->rmctx, s)) < 0) + if ((ret = ff_copy_whiteblacklists(rdt->rmctx, s)) < 0) return ret; return avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL); diff --git a/libavformat/rtmpcrypt.c b/libavformat/rtmpcrypt.c index 77ca2d154f..3d5eb22392 100644 --- a/libavformat/rtmpcrypt.c +++ b/libavformat/rtmpcrypt.c @@ -266,7 +266,7 @@ static int rtmpe_open(URLContext *h, const char *uri, int flags) /* open the tcp or ffrtmphttp connection */ if ((ret = ffurl_open_whitelist(&rt->stream, url, AVIO_FLAG_READ_WRITE, &h->interrupt_callback, NULL, - h->protocol_whitelist)) < 0) { + h->protocol_whitelist, h->protocol_blacklist)) < 0) { rtmpe_close(h); return ret; } diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index ee8c8a6faa..c01bc40204 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1120,7 +1120,7 @@ static int rtmp_calc_swfhash(URLContext *s) /* Get the SWF player file. */ if ((ret = ffurl_open_whitelist(&stream, rt->swfverify, AVIO_FLAG_READ, &s->interrupt_callback, NULL, - s->protocol_whitelist)) < 0) { + s->protocol_whitelist, s->protocol_blacklist)) < 0) { av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify); goto fail; } @@ -2650,7 +2650,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) reconnect: if ((ret = ffurl_open_whitelist(&rt->stream, buf, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, &opts, - s->protocol_whitelist)) < 0) { + s->protocol_whitelist, s->protocol_blacklist)) < 0) { av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf); goto fail; } diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c index 2b1ddf140d..041085fb8d 100644 --- a/libavformat/rtpdec_asf.c +++ b/libavformat/rtpdec_asf.c @@ -131,7 +131,7 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p) rt->asf_ctx->pb = &pb; av_dict_set(&opts, "no_resync_search", "1", 0); - if ((ret = ff_copy_whitelists(rt->asf_ctx, s)) < 0) { + if ((ret = ff_copy_whiteblacklists(rt->asf_ctx, s)) < 0) { av_dict_free(&opts); return ret; } diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index a35ff5f216..451d8114e5 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -381,7 +381,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) hostname, rtp_port, s->local_rtpport, sources, block); if (ffurl_open_whitelist(&s->rtp_hd, buf, flags, &h->interrupt_callback, - NULL, h->protocol_whitelist) < 0) + NULL, h->protocol_whitelist, h->protocol_blacklist) < 0) goto fail; s->local_rtpport = ff_udp_get_local_port(s->rtp_hd); if(s->local_rtpport == 65535) { @@ -395,7 +395,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) sources, block); if (ffurl_open_whitelist(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL, - h->protocol_whitelist) < 0) { + h->protocol_whitelist, h->protocol_blacklist) < 0) { s->local_rtpport = s->local_rtcpport = -1; continue; } @@ -405,7 +405,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) hostname, s->rtcp_port, s->local_rtcpport, sources, block); if (ffurl_open_whitelist(&s->rtcp_hd, buf, flags, &h->interrupt_callback, - NULL, h->protocol_whitelist) < 0) + NULL, h->protocol_whitelist, h->protocol_blacklist) < 0) goto fail; break; } diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index d710469641..64f8c91950 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1469,7 +1469,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, /* we will use two ports per rtp stream (rtp and rtcp) */ j += 2; err = ffurl_open_whitelist(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, &opts, s->protocol_whitelist); + &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist); av_dict_free(&opts); @@ -1612,7 +1612,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, ff_url_join(url, sizeof(url), "rtp", NULL, namebuf, port, "%s", optbuf); if (ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist) < 0) { + &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist) < 0) { err = AVERROR_INVALIDDATA; goto fail; } @@ -1801,7 +1801,7 @@ redirect: host, port, "?timeout=%d", rt->stimeout); if ((ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { + &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist)) < 0) { err = ret; goto fail; } @@ -2317,7 +2317,7 @@ static int sdp_read_header(AVFormatContext *s) rtsp_st->nb_exclude_source_addrs, rtsp_st->exclude_source_addrs); err = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback, &opts, s->protocol_whitelist); + &s->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist); av_dict_free(&opts); @@ -2387,7 +2387,7 @@ static int rtp_read_header(AVFormatContext *s) return AVERROR(EIO); ret = ffurl_open_whitelist(&in, s->filename, AVIO_FLAG_READ, - &s->interrupt_callback, NULL, s->protocol_whitelist); + &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist); if (ret) goto fail; diff --git a/libavformat/rtspdec.c b/libavformat/rtspdec.c index 17f04c0254..ca7acc806b 100644 --- a/libavformat/rtspdec.c +++ b/libavformat/rtspdec.c @@ -296,7 +296,7 @@ static int rtsp_read_setup(AVFormatContext *s, char* host, char *controlurl) av_log(s, AV_LOG_TRACE, "Opening: %s", url); ret = ffurl_open_whitelist(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, &opts, - s->protocol_whitelist); + s->protocol_whitelist, s->protocol_blacklist); av_dict_free(&opts); if (ret) localport += 2; @@ -665,7 +665,7 @@ static int rtsp_listen(AVFormatContext *s) if (ret = ffurl_open_whitelist(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE, &s->interrupt_callback, NULL, - s->protocol_whitelist)) { + s->protocol_whitelist, s->protocol_blacklist)) { av_log(s, AV_LOG_ERROR, "Unable to open RTSP for listening\n"); return ret; } diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c index 926795b6a9..0473b018f9 100644 --- a/libavformat/sapdec.c +++ b/libavformat/sapdec.c @@ -87,7 +87,7 @@ static int sap_read_header(AVFormatContext *s) port); ret = ffurl_open_whitelist(&sap->ann_fd, url, AVIO_FLAG_READ, &s->interrupt_callback, NULL, - s->protocol_whitelist); + s->protocol_whitelist, s->protocol_blacklist); if (ret) goto fail; @@ -161,7 +161,7 @@ static int sap_read_header(AVFormatContext *s) sap->sdp_ctx->pb = &sap->sdp_pb; sap->sdp_ctx->interrupt_callback = s->interrupt_callback; - if ((ret = ff_copy_whitelists(sap->sdp_ctx, s)) < 0) + if ((ret = ff_copy_whiteblacklists(sap->sdp_ctx, s)) < 0) goto fail; ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL); diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c index b2f64b8060..0699e3e5b8 100644 --- a/libavformat/sapenc.c +++ b/libavformat/sapenc.c @@ -151,7 +151,7 @@ static int sap_write_header(AVFormatContext *s) base_port += 2; ret = ffurl_open_whitelist(&fd, url, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, - s->protocol_whitelist); + s->protocol_whitelist, s->protocol_blacklist); if (ret) { ret = AVERROR(EIO); goto fail; @@ -171,7 +171,7 @@ static int sap_write_header(AVFormatContext *s) "?ttl=%d&connect=1", ttl); ret = ffurl_open_whitelist(&sap->ann_fd, url, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, - s->protocol_whitelist); + s->protocol_whitelist, s->protocol_blacklist); if (ret) { ret = AVERROR(EIO); goto fail; diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index da0e222b3d..5333ba86c7 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -123,7 +123,7 @@ static int64_t ism_seek(void *opaque, int64_t offset, int whence) os->tail_out = os->out; av_dict_set(&opts, "truncate", "0", 0); ret = ffurl_open_whitelist(&os->out, frag->file, AVIO_FLAG_WRITE, - &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist); + &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist, os->ctx->protocol_blacklist); av_dict_free(&opts); if (ret < 0) { os->out = os->tail_out; @@ -132,7 +132,7 @@ static int64_t ism_seek(void *opaque, int64_t offset, int whence) } av_dict_set(&opts, "truncate", "0", 0); ffurl_open_whitelist(&os->out2, frag->infofile, AVIO_FLAG_WRITE, - &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist); + &os->ctx->interrupt_callback, &opts, os->ctx->protocol_whitelist, os->ctx->protocol_blacklist); av_dict_free(&opts); ffurl_seek(os->out, offset - frag->start_pos, SEEK_SET); if (os->out2) @@ -332,7 +332,7 @@ static int ism_write_header(AVFormatContext *s) } ctx = avformat_alloc_context(); - if (!ctx || ff_copy_whitelists(ctx, s) < 0) { + if (!ctx || ff_copy_whiteblacklists(ctx, s) < 0) { ret = AVERROR(ENOMEM); goto fail; } @@ -526,7 +526,7 @@ static int ism_flush(AVFormatContext *s, int final) continue; snprintf(filename, sizeof(filename), "%s/temp", os->dirname); - ret = ffurl_open_whitelist(&os->out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = ffurl_open_whitelist(&os->out, filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist, s->protocol_blacklist); if (ret < 0) break; os->cur_start_pos = os->tail_pos; diff --git a/libavformat/srtpproto.c b/libavformat/srtpproto.c index 470f87bc37..ef87c08e0d 100644 --- a/libavformat/srtpproto.c +++ b/libavformat/srtpproto.c @@ -81,7 +81,7 @@ static int srtp_open(URLContext *h, const char *uri, int flags) path, sizeof(path), uri); ff_url_join(buf, sizeof(buf), "rtp", NULL, hostname, rtp_port, "%s", path); if ((ret = ffurl_open_whitelist(&s->rtp_hd, buf, flags, &h->interrupt_callback, - NULL, h->protocol_whitelist)) < 0) + NULL, h->protocol_whitelist, h->protocol_blacklist)) < 0) goto fail; h->max_packet_size = FFMIN(s->rtp_hd->max_packet_size, diff --git a/libavformat/subfile.c b/libavformat/subfile.c index 8a3c167d74..fdd328a084 100644 --- a/libavformat/subfile.c +++ b/libavformat/subfile.c @@ -78,7 +78,7 @@ static int subfile_open(URLContext *h, const char *filename, int flags, } av_strstart(filename, "subfile:", &filename); ret = ffurl_open_whitelist(&c->h, filename, flags, &h->interrupt_callback, - options, h->protocol_whitelist); + options, h->protocol_whitelist, h->protocol_blacklist); if (ret < 0) return ret; c->pos = c->start; diff --git a/libavformat/tls.c b/libavformat/tls.c index c625983660..2a59aa77c6 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -106,5 +106,5 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV return ffurl_open_whitelist(&c->tcp, buf, AVIO_FLAG_READ_WRITE, &parent->interrupt_callback, options, - parent->protocol_whitelist); + parent->protocol_whitelist, parent->protocol_blacklist); } diff --git a/libavformat/tls_securetransport.c b/libavformat/tls_securetransport.c index a26b9694cd..253c89c5ab 100644 --- a/libavformat/tls_securetransport.c +++ b/libavformat/tls_securetransport.c @@ -83,7 +83,7 @@ static int import_pem(URLContext *h, char *path, CFArrayRef *array) if ((ret = ffio_open_whitelist(&s, path, AVIO_FLAG_READ, &h->interrupt_callback, NULL, - h->protocol_whitelist)) < 0) + h->protocol_whitelist, h->protocol_blacklist)) < 0) goto end; if ((ret = avio_size(s)) < 0) diff --git a/libavformat/url.h b/libavformat/url.h index 95acd27b46..4ce60cc8df 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -47,6 +47,7 @@ typedef struct URLContext { AVIOInterruptCB interrupt_callback; int64_t rw_timeout; /**< maximum time to wait for (network) read/write operation completion, in mcs */ const char *protocol_whitelist; + const char *protocol_blacklist; } URLContext; typedef struct URLProtocol { @@ -140,7 +141,7 @@ int ffurl_connect(URLContext *uc, AVDictionary **options); */ int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, - const char *whitelist); + const char *whitelist, const char* blacklist); int ffurl_open(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options); diff --git a/libavformat/utils.c b/libavformat/utils.c index 7c14725d8b..5f48de1247 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -142,18 +142,21 @@ void av_format_inject_global_side_data(AVFormatContext *s) } } -int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src) +int ff_copy_whiteblacklists(AVFormatContext *dst, AVFormatContext *src) { av_assert0(!dst->codec_whitelist && !dst->format_whitelist && - !dst->protocol_whitelist); + !dst->protocol_whitelist && + !dst->protocol_blacklist); dst-> codec_whitelist = av_strdup(src->codec_whitelist); dst->format_whitelist = av_strdup(src->format_whitelist); dst->protocol_whitelist = av_strdup(src->protocol_whitelist); + dst->protocol_blacklist = av_strdup(src->protocol_blacklist); if ( (src-> codec_whitelist && !dst-> codec_whitelist) || (src-> format_whitelist && !dst-> format_whitelist) - || (src->protocol_whitelist && !dst->protocol_whitelist)) { - av_log(dst, AV_LOG_ERROR, "Failed to duplicate whitelist\n"); + || (src->protocol_whitelist && !dst->protocol_whitelist) + || (src->protocol_blacklist && !dst->protocol_blacklist)) { + av_log(dst, AV_LOG_ERROR, "Failed to duplicate black/whitelist\n"); return AVERROR(ENOMEM); } return 0; @@ -460,6 +463,14 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, } } + if (!s->protocol_blacklist && s->pb && s->pb->protocol_blacklist) { + s->protocol_blacklist = av_strdup(s->pb->protocol_blacklist); + if (!s->protocol_blacklist) { + ret = AVERROR(ENOMEM); + goto fail; + } + } + if (s->format_whitelist && av_match_list(s->iformat->name, s->format_whitelist, ',') <= 0) { av_log(s, AV_LOG_ERROR, "Format not on whitelist \'%s\'\n", s->format_whitelist); ret = AVERROR(EINVAL); diff --git a/libavformat/version.h b/libavformat/version.h index 22f2797cb2..7dcce2cabf 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,8 +30,8 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 27 -#define LIBAVFORMAT_VERSION_MICRO 102 +#define LIBAVFORMAT_VERSION_MINOR 28 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \