From 5668e73beb30b95abc6520b7432c54972ca3ab2c Mon Sep 17 00:00:00 2001 From: Stephan Bergmann Date: Wed, 20 Nov 2013 14:43:45 +0100 Subject: avmedia: Implement "block untrusted referer links" feature See f0a9ca24fd4bf79cac908bf0d6fdb8905dc504db "rhbz#887420 Implement 'block untrusted referer links' feature" for details. This adds some further /*TODO?*/ comments, and one known problem (marked /*TODO!*/) is that movies/sounds are not blocked during a slideshow presentation. Change-Id: Ib2d0c7e4f7b02c4bdec0d8a90cee5e7e1bee8325 --- avmedia/source/framework/mediacontrol.cxx | 4 ++-- avmedia/source/framework/mediaitem.cxx | 13 +++++++++++-- avmedia/source/framework/mediaplayer.cxx | 4 ++-- avmedia/source/framework/soundhandler.cxx | 9 +++++---- avmedia/source/viewer/mediawindow.cxx | 16 +++++++++------- avmedia/source/viewer/mediawindow_impl.cxx | 15 ++++++++++----- avmedia/source/viewer/mediawindow_impl.hxx | 4 ++-- 7 files changed, 41 insertions(+), 24 deletions(-) (limited to 'avmedia/source') diff --git a/avmedia/source/framework/mediacontrol.cxx b/avmedia/source/framework/mediacontrol.cxx index fc67309f62b5..7facb1f26f1a 100644 --- a/avmedia/source/framework/mediacontrol.cxx +++ b/avmedia/source/framework/mediacontrol.cxx @@ -494,11 +494,11 @@ IMPL_LINK( MediaControl, implSelectHdl, ToolBox*, p ) if (::avmedia::MediaWindow::executeMediaURLDialog( GetParent(), aURL, 0)) { - if( !::avmedia::MediaWindow::isMediaURL( aURL, true ) ) + if( !::avmedia::MediaWindow::isMediaURL( aURL, ""/*TODO?*/, true ) ) ::avmedia::MediaWindow::executeFormatErrorBox( this ); else { - aExecItem.setURL( aURL, "" ); + aExecItem.setURL( aURL, "", ""/*TODO?*/ ); aExecItem.setState( MEDIASTATE_PLAY ); } } diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx index 98359b1b0411..b57abfecb9ce 100644 --- a/avmedia/source/framework/mediaitem.cxx +++ b/avmedia/source/framework/mediaitem.cxx @@ -53,6 +53,7 @@ struct MediaItem::Impl { OUString m_URL; OUString m_TempFileURL; + OUString m_Referer; sal_uInt32 m_nMaskSet; MediaState m_eState; double m_fTime; @@ -76,6 +77,7 @@ struct MediaItem::Impl Impl(Impl const& rOther) : m_URL( rOther.m_URL ) , m_TempFileURL( rOther.m_TempFileURL ) + , m_Referer( rOther.m_Referer ) , m_nMaskSet( rOther.m_nMaskSet ) , m_eState( rOther.m_eState ) , m_fTime( rOther.m_fTime ) @@ -118,6 +120,7 @@ int MediaItem::operator==( const SfxPoolItem& rItem ) const MediaItem const& rOther(static_cast< const MediaItem& >(rItem)); return m_pImpl->m_nMaskSet == rOther.m_pImpl->m_nMaskSet && m_pImpl->m_URL == rOther.m_pImpl->m_URL + && m_pImpl->m_Referer == rOther.m_pImpl->m_Referer && m_pImpl->m_eState == rOther.m_pImpl->m_eState && m_pImpl->m_fDuration == rOther.m_pImpl->m_fDuration && m_pImpl->m_fTime == rOther.m_pImpl->m_fTime @@ -202,7 +205,7 @@ void MediaItem::merge( const MediaItem& rMediaItem ) const sal_uInt32 nMaskSet = rMediaItem.getMaskSet(); if( AVMEDIA_SETMASK_URL & nMaskSet ) - setURL( rMediaItem.getURL(), rMediaItem.getTempURL() ); + setURL( rMediaItem.getURL(), rMediaItem.getTempURL(), rMediaItem.getReferer() ); if( AVMEDIA_SETMASK_STATE & nMaskSet ) setState( rMediaItem.getState() ); @@ -235,11 +238,12 @@ sal_uInt32 MediaItem::getMaskSet() const //------------------------------------------------------------------------ -void MediaItem::setURL( const OUString& rURL, const OUString& rTempURL ) +void MediaItem::setURL( const OUString& rURL, const OUString& rTempURL, const OUString& rReferer ) { m_pImpl->m_nMaskSet |= AVMEDIA_SETMASK_URL; m_pImpl->m_URL = rURL; m_pImpl->m_TempFileURL = rTempURL; + m_pImpl->m_Referer = rReferer; } //------------------------------------------------------------------------ @@ -254,6 +258,11 @@ const OUString& MediaItem::getTempURL() const return m_pImpl->m_TempFileURL; } +const OUString& MediaItem::getReferer() const +{ + return m_pImpl->m_Referer; +} + //------------------------------------------------------------------------ void MediaItem::setState( MediaState eState ) diff --git a/avmedia/source/framework/mediaplayer.cxx b/avmedia/source/framework/mediaplayer.cxx index e5b35d308b51..bef6fc6cdef7 100644 --- a/avmedia/source/framework/mediaplayer.cxx +++ b/avmedia/source/framework/mediaplayer.cxx @@ -116,11 +116,11 @@ void MediaFloater::ToggleFloatingMode() // ----------------------------------------------------------------------------- -void MediaFloater::setURL( const OUString& rURL, bool bPlayImmediately ) +void MediaFloater::setURL( const OUString& rURL, const OUString& rReferer, bool bPlayImmediately ) { if( mpMediaWindow ) { - mpMediaWindow->setURL( rURL ); + mpMediaWindow->setURL( rURL, rReferer ); if( mpMediaWindow->isValid() && bPlayImmediately ) mpMediaWindow->start(); diff --git a/avmedia/source/framework/soundhandler.cxx b/avmedia/source/framework/soundhandler.cxx index 06658e9ad948..e56f86b7822d 100644 --- a/avmedia/source/framework/soundhandler.cxx +++ b/avmedia/source/framework/soundhandler.cxx @@ -264,11 +264,11 @@ void SAL_CALL SoundHandler::dispatchWithNotification(const css::util::URL& // SAFE { const ::osl::MutexGuard aLock( m_aLock ); + utl::MediaDescriptor aDescriptor(lDescriptor); + { //close streams otherwise on windows we can't reopen the file in the //media player when we pass the url to directx as it'll already be open - utl::MediaDescriptor aDescriptor(lDescriptor); - css::uno::Reference< css::io::XInputStream > xInputStream = aDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_INPUTSTREAM(), css::uno::Reference< css::io::XInputStream >()); @@ -290,7 +290,7 @@ void SAL_CALL SoundHandler::dispatchWithNotification(const css::util::URL& try { m_bError = false; - m_xPlayer.set( avmedia::MediaWindow::createPlayer( aURL.Complete ), css::uno::UNO_QUERY_THROW ); + m_xPlayer.set( avmedia::MediaWindow::createPlayer( aURL.Complete, aDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_REFERRER(), OUString()) ), css::uno::UNO_QUERY_THROW ); // OK- we can start async playing ... // Count this request and initialize self-holder against dieing by uno ref count ... m_xSelfHold = css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY); @@ -346,10 +346,11 @@ OUString SAL_CALL SoundHandler::detect( css::uno::Sequence< css::beans::Property // Analyze given descriptor to find filename or input stream or ... utl::MediaDescriptor aDescriptor(lDescriptor); OUString sURL = aDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_URL(), OUString()); + OUString sReferer = aDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_REFERRER(), OUString()); if ( (sURL.getLength() ) && - (avmedia::MediaWindow::isMediaURL(sURL)) + (avmedia::MediaWindow::isMediaURL(sURL, sReferer)) ) { // If the file type is supported depends on the OS, so... diff --git a/avmedia/source/viewer/mediawindow.cxx b/avmedia/source/viewer/mediawindow.cxx index 45c9901035c7..2ef1f9a06ebf 100644 --- a/avmedia/source/viewer/mediawindow.cxx +++ b/avmedia/source/viewer/mediawindow.cxx @@ -56,9 +56,9 @@ MediaWindow::~MediaWindow() {} // ------------------------------------------------------------------------- -void MediaWindow::setURL( const OUString& rURL ) +void MediaWindow::setURL( const OUString& rURL, const OUString& rReferer ) { - mpImpl->setURL( rURL, OUString() ); + mpImpl->setURL( rURL, OUString(), rReferer ); } // ------------------------------------------------------------------------- @@ -328,7 +328,7 @@ void MediaWindow::executeFormatErrorBox( Window* pParent ) // ------------------------------------------------------------------------- -bool MediaWindow::isMediaURL( const OUString& rURL, bool bDeep, Size* pPreferredSizePixel ) +bool MediaWindow::isMediaURL( const OUString& rURL, const OUString& rReferer, bool bDeep, Size* pPreferredSizePixel ) { const INetURLObject aURL( rURL ); bool bRet = false; @@ -340,7 +340,8 @@ bool MediaWindow::isMediaURL( const OUString& rURL, bool bDeep, Size* pPreferred try { uno::Reference< media::XPlayer > xPlayer( priv::MediaWindowImpl::createPlayer( - aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ) ); + aURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ), + rReferer ) ); if( xPlayer.is() ) { @@ -383,18 +384,19 @@ bool MediaWindow::isMediaURL( const OUString& rURL, bool bDeep, Size* pPreferred // ------------------------------------------------------------------------- -uno::Reference< media::XPlayer > MediaWindow::createPlayer( const OUString& rURL ) +uno::Reference< media::XPlayer > MediaWindow::createPlayer( const OUString& rURL, const OUString& rReferer ) { - return priv::MediaWindowImpl::createPlayer( rURL ); + return priv::MediaWindowImpl::createPlayer( rURL, rReferer ); } // ------------------------------------------------------------------------- uno::Reference< graphic::XGraphic > MediaWindow::grabFrame( const OUString& rURL, + const OUString& rReferer, bool bAllowToCreateReplacementGraphic, double fMediaTime ) { - uno::Reference< media::XPlayer > xPlayer( createPlayer( rURL ) ); + uno::Reference< media::XPlayer > xPlayer( createPlayer( rURL, rReferer ) ); uno::Reference< graphic::XGraphic > xRet; ::std::auto_ptr< Graphic > apGraphic; diff --git a/avmedia/source/viewer/mediawindow_impl.cxx b/avmedia/source/viewer/mediawindow_impl.cxx index 4157f7a07610..2c2239691f7d 100644 --- a/avmedia/source/viewer/mediawindow_impl.cxx +++ b/avmedia/source/viewer/mediawindow_impl.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -204,9 +205,13 @@ MediaWindowImpl::~MediaWindowImpl() delete mpMediaWindowControl; } -uno::Reference< media::XPlayer > MediaWindowImpl::createPlayer( const OUString& rURL ) +uno::Reference< media::XPlayer > MediaWindowImpl::createPlayer( const OUString& rURL, const OUString& rReferer ) { uno::Reference< media::XPlayer > xPlayer; + if (SvtSecurityOptions().isUntrustedReferer(rReferer)) { + return xPlayer; + } + uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() ); static const char * aServiceManagers[] = { @@ -246,7 +251,7 @@ uno::Reference< media::XPlayer > MediaWindowImpl::createPlayer( const OUString& } void MediaWindowImpl::setURL( const OUString& rURL, - OUString const& rTempURL) + OUString const& rTempURL, OUString const& rReferer) { if( rURL != getURL() ) { @@ -278,7 +283,7 @@ void MediaWindowImpl::setURL( const OUString& rURL, } mxPlayer = createPlayer( - (!mTempFileURL.isEmpty()) ? mTempFileURL : maFileURL ); + (!mTempFileURL.isEmpty()) ? mTempFileURL : maFileURL, rReferer ); onURLChanged(); } } @@ -326,7 +331,7 @@ void MediaWindowImpl::updateMediaItem( MediaItem& rItem ) const rItem.setMute( isMute() ); rItem.setVolumeDB( getVolumeDB() ); rItem.setZoom( getZoom() ); - rItem.setURL( getURL(), mTempFileURL ); + rItem.setURL( getURL(), mTempFileURL, ""/*TODO?*/ ); } void MediaWindowImpl::executeMediaItem( const MediaItem& rItem ) @@ -335,7 +340,7 @@ void MediaWindowImpl::executeMediaItem( const MediaItem& rItem ) // set URL first if( nMaskSet & AVMEDIA_SETMASK_URL ) - setURL( rItem.getURL(), rItem.getTempURL() ); + setURL( rItem.getURL(), rItem.getTempURL(), rItem.getReferer() ); // set different states next if( nMaskSet & AVMEDIA_SETMASK_TIME ) diff --git a/avmedia/source/viewer/mediawindow_impl.hxx b/avmedia/source/viewer/mediawindow_impl.hxx index 340ab128e944..42d95108b86b 100644 --- a/avmedia/source/viewer/mediawindow_impl.hxx +++ b/avmedia/source/viewer/mediawindow_impl.hxx @@ -91,9 +91,9 @@ namespace avmedia MediaWindowImpl( Window* parent, MediaWindow* pMediaWindow, bool bInternalMediaControl ); virtual ~MediaWindowImpl(); - static ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > createPlayer( const OUString& rURL ); + static ::com::sun::star::uno::Reference< ::com::sun::star::media::XPlayer > createPlayer( const OUString& rURL, const OUString& rReferer ); - void setURL( const OUString& rURL, OUString const& rTempURL ); + void setURL( const OUString& rURL, OUString const& rTempURL, OUString const& rReferer ); const OUString& getURL() const; -- cgit