2017-11-29 19:49:05 +00:00
|
|
|
{- youtube-dl integration for git-annex
|
|
|
|
-
|
2018-06-17 18:46:22 +00:00
|
|
|
- Copyright 2017-2018 Joey Hess <id@joeyh.name>
|
2017-11-29 19:49:05 +00:00
|
|
|
-
|
|
|
|
- Licensed under the GNU GPL version 3 or higher.
|
|
|
|
-}
|
|
|
|
|
2017-12-11 16:46:34 +00:00
|
|
|
module Annex.YoutubeDl (
|
|
|
|
youtubeDl,
|
|
|
|
youtubeDlTo,
|
|
|
|
youtubeDlSupported,
|
|
|
|
youtubeDlCheck,
|
|
|
|
youtubeDlFileName,
|
limit url downloads to whitelisted schemes
Security fix! Allowing any schemes, particularly file: and
possibly others like scp: allowed file exfiltration by anyone who had
write access to the git repository, since they could add an annexed file
using such an url, or using an url that redirected to such an url,
and wait for the victim to get it into their repository and send them a copy.
* Added annex.security.allowed-url-schemes setting, which defaults
to only allowing http and https URLs. Note especially that file:/
is no longer enabled by default.
* Removed annex.web-download-command, since its interface does not allow
supporting annex.security.allowed-url-schemes across redirects.
If you used this setting, you may want to instead use annex.web-options
to pass options to curl.
With annex.web-download-command removed, nearly all url accesses in
git-annex are made via Utility.Url via http-client or curl. http-client
only supports http and https, so no problem there.
(Disabling one and not the other is not implemented.)
Used curl --proto to limit the allowed url schemes.
Note that this will cause git annex fsck --from web to mark files using
a disallowed url scheme as not being present in the web. That seems
acceptable; fsck --from web also does that when a web server is not available.
youtube-dl already disabled file: itself (probably for similar
reasons). The scheme check was also added to youtube-dl urls for
completeness, although that check won't catch any redirects it might
follow. But youtube-dl goes off and does its own thing with other
protocols anyway, so that's fine.
Special remotes that support other domain-specific url schemes are not
affected by this change. In the bittorrent remote, aria2c can still
download magnet: links. The download of the .torrent file is
otherwise now limited by annex.security.allowed-url-schemes.
This does not address any external special remotes that might download
an url themselves. Current thinking is all external special remotes will
need to be audited for this problem, although many of them will use
http libraries that only support http and not curl's menagarie.
The related problem of accessing private localhost and LAN urls is not
addressed by this commit.
This commit was sponsored by Brett Eisenberg on Patreon.
2018-06-15 20:52:24 +00:00
|
|
|
youtubeDlFileNameHtmlOnly,
|
2017-12-11 16:46:34 +00:00
|
|
|
) where
|
2017-11-29 19:49:05 +00:00
|
|
|
|
|
|
|
import Annex.Common
|
|
|
|
import qualified Annex
|
|
|
|
import Annex.Content
|
2017-12-06 17:16:06 +00:00
|
|
|
import Annex.Url
|
2017-11-29 19:49:05 +00:00
|
|
|
import Utility.Url (URLString)
|
2017-11-30 20:08:30 +00:00
|
|
|
import Utility.DiskFree
|
2017-12-06 17:16:06 +00:00
|
|
|
import Utility.HtmlDetect
|
2017-12-31 20:08:31 +00:00
|
|
|
import Utility.Process.Transcript
|
2017-11-30 20:08:30 +00:00
|
|
|
import Logs.Transfer
|
2017-11-29 19:49:05 +00:00
|
|
|
|
2017-12-11 16:46:34 +00:00
|
|
|
import Network.URI
|
2017-12-31 19:19:01 +00:00
|
|
|
import Control.Concurrent.Async
|
2017-12-11 16:46:34 +00:00
|
|
|
|
2018-06-17 18:46:22 +00:00
|
|
|
-- youtube-dl is can follow redirects to anywhere, including potentially
|
2018-06-28 17:01:18 +00:00
|
|
|
-- localhost or a private address. So, it's only allowed to download
|
|
|
|
-- content if the user has allowed access to all addresses.
|
2018-06-17 18:46:22 +00:00
|
|
|
youtubeDlAllowed :: Annex Bool
|
|
|
|
youtubeDlAllowed = httpAddressesUnlimited
|
|
|
|
|
2018-06-28 17:01:18 +00:00
|
|
|
youtubeDlNotAllowedMessage :: String
|
|
|
|
youtubeDlNotAllowedMessage = unwords
|
2018-09-02 20:08:00 +00:00
|
|
|
[ "This url is supported by youtube-dl, but"
|
|
|
|
, "youtube-dl could potentially access any address, and the"
|
2018-06-28 17:01:18 +00:00
|
|
|
, "configuration of annex.security.allowed-http-addresses"
|
2018-09-02 20:08:00 +00:00
|
|
|
, "does not allow that. Not using youtube-dl."
|
2018-06-28 17:01:18 +00:00
|
|
|
]
|
|
|
|
|
2017-11-29 19:49:05 +00:00
|
|
|
-- Runs youtube-dl in a work directory, to download a single media file
|
|
|
|
-- from the url. Reutrns the path to the media file in the work directory.
|
|
|
|
--
|
|
|
|
-- If youtube-dl fails without writing any files to the work directory,
|
|
|
|
-- or is not installed, returns Right Nothing.
|
|
|
|
--
|
|
|
|
-- The work directory can contain files from a previous run of youtube-dl
|
|
|
|
-- and it will resume. It should not contain any other files though,
|
|
|
|
-- and youtube-dl needs to finish up with only one file in the directory
|
|
|
|
-- so we know which one it downloaded.
|
|
|
|
--
|
|
|
|
-- (Note that we can't use --output to specifiy the file to download to,
|
|
|
|
-- due to <https://github.com/rg3/youtube-dl/issues/14864>)
|
|
|
|
youtubeDl :: URLString -> FilePath -> Annex (Either String (Maybe FilePath))
|
2018-06-17 18:46:22 +00:00
|
|
|
youtubeDl url workdir = ifM httpAddressesUnlimited
|
|
|
|
( withUrlOptions $ youtubeDl' url workdir
|
2018-06-28 17:01:18 +00:00
|
|
|
, return $ Left youtubeDlNotAllowedMessage
|
2018-06-17 18:46:22 +00:00
|
|
|
)
|
limit url downloads to whitelisted schemes
Security fix! Allowing any schemes, particularly file: and
possibly others like scp: allowed file exfiltration by anyone who had
write access to the git repository, since they could add an annexed file
using such an url, or using an url that redirected to such an url,
and wait for the victim to get it into their repository and send them a copy.
* Added annex.security.allowed-url-schemes setting, which defaults
to only allowing http and https URLs. Note especially that file:/
is no longer enabled by default.
* Removed annex.web-download-command, since its interface does not allow
supporting annex.security.allowed-url-schemes across redirects.
If you used this setting, you may want to instead use annex.web-options
to pass options to curl.
With annex.web-download-command removed, nearly all url accesses in
git-annex are made via Utility.Url via http-client or curl. http-client
only supports http and https, so no problem there.
(Disabling one and not the other is not implemented.)
Used curl --proto to limit the allowed url schemes.
Note that this will cause git annex fsck --from web to mark files using
a disallowed url scheme as not being present in the web. That seems
acceptable; fsck --from web also does that when a web server is not available.
youtube-dl already disabled file: itself (probably for similar
reasons). The scheme check was also added to youtube-dl urls for
completeness, although that check won't catch any redirects it might
follow. But youtube-dl goes off and does its own thing with other
protocols anyway, so that's fine.
Special remotes that support other domain-specific url schemes are not
affected by this change. In the bittorrent remote, aria2c can still
download magnet: links. The download of the .torrent file is
otherwise now limited by annex.security.allowed-url-schemes.
This does not address any external special remotes that might download
an url themselves. Current thinking is all external special remotes will
need to be audited for this problem, although many of them will use
http libraries that only support http and not curl's menagarie.
The related problem of accessing private localhost and LAN urls is not
addressed by this commit.
This commit was sponsored by Brett Eisenberg on Patreon.
2018-06-15 20:52:24 +00:00
|
|
|
|
|
|
|
youtubeDl' :: URLString -> FilePath -> UrlOptions -> Annex (Either String (Maybe FilePath))
|
|
|
|
youtubeDl' url workdir uo
|
|
|
|
| supportedScheme uo url = ifM (liftIO $ inPath "youtube-dl")
|
2017-12-11 16:46:34 +00:00
|
|
|
( runcmd >>= \case
|
|
|
|
Right True -> workdirfiles >>= \case
|
|
|
|
(f:[]) -> return (Right (Just f))
|
|
|
|
[] -> return nofiles
|
|
|
|
fs -> return (toomanyfiles fs)
|
|
|
|
Right False -> workdirfiles >>= \case
|
|
|
|
[] -> return (Right Nothing)
|
|
|
|
_ -> return (Left "youtube-dl download is incomplete. Run the command again to resume.")
|
|
|
|
Left msg -> return (Left msg)
|
|
|
|
, return (Right Nothing)
|
|
|
|
)
|
|
|
|
| otherwise = return (Right Nothing)
|
2017-11-29 19:49:05 +00:00
|
|
|
where
|
|
|
|
nofiles = Left "youtube-dl did not put any media in its work directory, perhaps it's been configured to store files somewhere else?"
|
|
|
|
toomanyfiles fs = Left $ "youtube-dl downloaded multiple media files; git-annex is only able to deal with one per url: " ++ show fs
|
2017-12-05 19:00:50 +00:00
|
|
|
workdirfiles = liftIO $ filterM (doesFileExist) =<< dirContents workdir
|
2017-11-30 20:08:30 +00:00
|
|
|
runcmd = youtubeDlMaxSize workdir >>= \case
|
|
|
|
Left msg -> return (Left msg)
|
|
|
|
Right maxsize -> do
|
|
|
|
quiet <- commandProgressDisabled
|
|
|
|
opts <- youtubeDlOpts $ dlopts ++ maxsize ++
|
|
|
|
if quiet then [ Param "--quiet" ] else []
|
|
|
|
ok <- liftIO $ boolSystem' "youtube-dl" opts $
|
|
|
|
\p -> p { cwd = Just workdir }
|
|
|
|
return (Right ok)
|
|
|
|
dlopts =
|
|
|
|
[ Param url
|
|
|
|
-- To make youtube-dl only download one file when given a
|
|
|
|
-- page with a video and a playlist, download only the video.
|
|
|
|
, Param "--no-playlist"
|
|
|
|
-- And when given a page with only a playlist, download only
|
|
|
|
-- the first video on the playlist. (Assumes the video is
|
|
|
|
-- somewhat stable, but this is the only way to prevent
|
|
|
|
-- youtube-dl from downloading the whole playlist.)
|
|
|
|
, Param "--playlist-items", Param "0"
|
|
|
|
]
|
|
|
|
|
|
|
|
-- To honor annex.diskreserve, ask youtube-dl to not download too
|
|
|
|
-- large a media file. Factors in other downloads that are in progress,
|
|
|
|
-- and any files in the workdir that it may have partially downloaded
|
|
|
|
-- before.
|
|
|
|
youtubeDlMaxSize :: FilePath -> Annex (Either String [CommandParam])
|
|
|
|
youtubeDlMaxSize workdir = ifM (Annex.getState Annex.force)
|
|
|
|
( return $ Right []
|
|
|
|
, liftIO (getDiskFree workdir) >>= \case
|
|
|
|
Just have -> do
|
|
|
|
inprogress <- sizeOfDownloadsInProgress (const True)
|
|
|
|
partial <- liftIO $ sum
|
|
|
|
<$> (mapM getFileSize =<< dirContents workdir)
|
|
|
|
reserve <- annexDiskReserve <$> Annex.getGitConfig
|
|
|
|
let maxsize = have - reserve - inprogress + partial
|
|
|
|
if maxsize > 0
|
|
|
|
then return $ Right
|
|
|
|
[ Param "--max-filesize"
|
|
|
|
, Param (show maxsize)
|
|
|
|
]
|
|
|
|
else return $ Left $
|
|
|
|
needMoreDiskSpace $
|
|
|
|
negate maxsize + 1024
|
|
|
|
Nothing -> return $ Right []
|
|
|
|
)
|
2017-11-29 19:49:05 +00:00
|
|
|
|
|
|
|
-- Download a media file to a destination,
|
|
|
|
youtubeDlTo :: Key -> URLString -> FilePath -> Annex Bool
|
2018-06-28 17:01:18 +00:00
|
|
|
youtubeDlTo key url dest = do
|
2017-12-05 19:00:50 +00:00
|
|
|
res <- withTmpWorkDir key $ \workdir ->
|
|
|
|
youtubeDl url workdir >>= \case
|
2017-11-29 19:49:05 +00:00
|
|
|
Right (Just mediafile) -> do
|
|
|
|
liftIO $ renameFile mediafile dest
|
2017-11-30 17:45:43 +00:00
|
|
|
return (Just True)
|
|
|
|
Right Nothing -> return (Just False)
|
|
|
|
Left msg -> do
|
|
|
|
warning msg
|
|
|
|
return Nothing
|
|
|
|
return (fromMaybe False res)
|
2017-11-29 19:49:05 +00:00
|
|
|
|
2017-12-06 17:16:06 +00:00
|
|
|
-- youtube-dl supports downloading urls that are not html pages,
|
|
|
|
-- but we don't want to use it for such urls, since they can be downloaded
|
|
|
|
-- without it. So, this first downloads part of the content and checks
|
|
|
|
-- if it's a html page; only then is youtube-dl used.
|
2017-12-08 18:49:55 +00:00
|
|
|
htmlOnly :: URLString -> a -> Annex a -> Annex a
|
2018-04-04 19:00:51 +00:00
|
|
|
htmlOnly url fallback a = withUrlOptions $ \uo ->
|
2017-12-06 17:16:06 +00:00
|
|
|
liftIO (downloadPartial url uo htmlPrefixLength) >>= \case
|
2017-12-08 18:49:55 +00:00
|
|
|
Just bs | isHtmlBs bs -> a
|
|
|
|
_ -> return fallback
|
|
|
|
|
2018-06-28 17:01:18 +00:00
|
|
|
-- Check if youtube-dl supports downloading content from an url.
|
2017-12-08 18:49:55 +00:00
|
|
|
youtubeDlSupported :: URLString -> Annex Bool
|
2018-06-28 17:01:18 +00:00
|
|
|
youtubeDlSupported url = either (const False) id
|
|
|
|
<$> withUrlOptions (youtubeDlCheck' url)
|
2017-12-08 18:49:55 +00:00
|
|
|
|
|
|
|
-- Check if youtube-dl can find media in an url.
|
2018-06-28 17:01:18 +00:00
|
|
|
--
|
|
|
|
-- While this does not download anything, it checks youtubeDlAllowed
|
|
|
|
-- for symmetry with youtubeDl; the check should not succeed if the
|
|
|
|
-- download won't succeed.
|
2017-12-08 18:49:55 +00:00
|
|
|
youtubeDlCheck :: URLString -> Annex (Either String Bool)
|
2018-06-17 18:46:22 +00:00
|
|
|
youtubeDlCheck url = ifM youtubeDlAllowed
|
|
|
|
( withUrlOptions $ youtubeDlCheck' url
|
2018-06-28 17:01:18 +00:00
|
|
|
, return $ Left youtubeDlNotAllowedMessage
|
2018-06-17 18:46:22 +00:00
|
|
|
)
|
limit url downloads to whitelisted schemes
Security fix! Allowing any schemes, particularly file: and
possibly others like scp: allowed file exfiltration by anyone who had
write access to the git repository, since they could add an annexed file
using such an url, or using an url that redirected to such an url,
and wait for the victim to get it into their repository and send them a copy.
* Added annex.security.allowed-url-schemes setting, which defaults
to only allowing http and https URLs. Note especially that file:/
is no longer enabled by default.
* Removed annex.web-download-command, since its interface does not allow
supporting annex.security.allowed-url-schemes across redirects.
If you used this setting, you may want to instead use annex.web-options
to pass options to curl.
With annex.web-download-command removed, nearly all url accesses in
git-annex are made via Utility.Url via http-client or curl. http-client
only supports http and https, so no problem there.
(Disabling one and not the other is not implemented.)
Used curl --proto to limit the allowed url schemes.
Note that this will cause git annex fsck --from web to mark files using
a disallowed url scheme as not being present in the web. That seems
acceptable; fsck --from web also does that when a web server is not available.
youtube-dl already disabled file: itself (probably for similar
reasons). The scheme check was also added to youtube-dl urls for
completeness, although that check won't catch any redirects it might
follow. But youtube-dl goes off and does its own thing with other
protocols anyway, so that's fine.
Special remotes that support other domain-specific url schemes are not
affected by this change. In the bittorrent remote, aria2c can still
download magnet: links. The download of the .torrent file is
otherwise now limited by annex.security.allowed-url-schemes.
This does not address any external special remotes that might download
an url themselves. Current thinking is all external special remotes will
need to be audited for this problem, although many of them will use
http libraries that only support http and not curl's menagarie.
The related problem of accessing private localhost and LAN urls is not
addressed by this commit.
This commit was sponsored by Brett Eisenberg on Patreon.
2018-06-15 20:52:24 +00:00
|
|
|
|
|
|
|
youtubeDlCheck' :: URLString -> UrlOptions -> Annex (Either String Bool)
|
|
|
|
youtubeDlCheck' url uo
|
|
|
|
| supportedScheme uo url = catchMsgIO $ htmlOnly url False $ do
|
2017-12-11 16:46:34 +00:00
|
|
|
opts <- youtubeDlOpts [ Param url, Param "--simulate" ]
|
|
|
|
liftIO $ snd <$> processTranscript "youtube-dl" (toCommand opts) Nothing
|
|
|
|
| otherwise = return (Right False)
|
2017-11-30 18:35:25 +00:00
|
|
|
|
|
|
|
-- Ask youtube-dl for the filename of media in an url.
|
|
|
|
--
|
|
|
|
-- (This is not always identical to the filename it uses when downloading.)
|
|
|
|
youtubeDlFileName :: URLString -> Annex (Either String FilePath)
|
2018-06-28 17:01:18 +00:00
|
|
|
youtubeDlFileName url = withUrlOptions go
|
2017-12-31 18:55:51 +00:00
|
|
|
where
|
limit url downloads to whitelisted schemes
Security fix! Allowing any schemes, particularly file: and
possibly others like scp: allowed file exfiltration by anyone who had
write access to the git repository, since they could add an annexed file
using such an url, or using an url that redirected to such an url,
and wait for the victim to get it into their repository and send them a copy.
* Added annex.security.allowed-url-schemes setting, which defaults
to only allowing http and https URLs. Note especially that file:/
is no longer enabled by default.
* Removed annex.web-download-command, since its interface does not allow
supporting annex.security.allowed-url-schemes across redirects.
If you used this setting, you may want to instead use annex.web-options
to pass options to curl.
With annex.web-download-command removed, nearly all url accesses in
git-annex are made via Utility.Url via http-client or curl. http-client
only supports http and https, so no problem there.
(Disabling one and not the other is not implemented.)
Used curl --proto to limit the allowed url schemes.
Note that this will cause git annex fsck --from web to mark files using
a disallowed url scheme as not being present in the web. That seems
acceptable; fsck --from web also does that when a web server is not available.
youtube-dl already disabled file: itself (probably for similar
reasons). The scheme check was also added to youtube-dl urls for
completeness, although that check won't catch any redirects it might
follow. But youtube-dl goes off and does its own thing with other
protocols anyway, so that's fine.
Special remotes that support other domain-specific url schemes are not
affected by this change. In the bittorrent remote, aria2c can still
download magnet: links. The download of the .torrent file is
otherwise now limited by annex.security.allowed-url-schemes.
This does not address any external special remotes that might download
an url themselves. Current thinking is all external special remotes will
need to be audited for this problem, although many of them will use
http libraries that only support http and not curl's menagarie.
The related problem of accessing private localhost and LAN urls is not
addressed by this commit.
This commit was sponsored by Brett Eisenberg on Patreon.
2018-06-15 20:52:24 +00:00
|
|
|
go uo
|
|
|
|
| supportedScheme uo url = flip catchIO (pure . Left . show) $
|
|
|
|
htmlOnly url nomedia (youtubeDlFileNameHtmlOnly' url uo)
|
|
|
|
| otherwise = return nomedia
|
2017-12-31 18:55:51 +00:00
|
|
|
nomedia = Left "no media in url"
|
|
|
|
|
|
|
|
-- Does not check if the url contains htmlOnly; use when that's already
|
|
|
|
-- been verified.
|
limit url downloads to whitelisted schemes
Security fix! Allowing any schemes, particularly file: and
possibly others like scp: allowed file exfiltration by anyone who had
write access to the git repository, since they could add an annexed file
using such an url, or using an url that redirected to such an url,
and wait for the victim to get it into their repository and send them a copy.
* Added annex.security.allowed-url-schemes setting, which defaults
to only allowing http and https URLs. Note especially that file:/
is no longer enabled by default.
* Removed annex.web-download-command, since its interface does not allow
supporting annex.security.allowed-url-schemes across redirects.
If you used this setting, you may want to instead use annex.web-options
to pass options to curl.
With annex.web-download-command removed, nearly all url accesses in
git-annex are made via Utility.Url via http-client or curl. http-client
only supports http and https, so no problem there.
(Disabling one and not the other is not implemented.)
Used curl --proto to limit the allowed url schemes.
Note that this will cause git annex fsck --from web to mark files using
a disallowed url scheme as not being present in the web. That seems
acceptable; fsck --from web also does that when a web server is not available.
youtube-dl already disabled file: itself (probably for similar
reasons). The scheme check was also added to youtube-dl urls for
completeness, although that check won't catch any redirects it might
follow. But youtube-dl goes off and does its own thing with other
protocols anyway, so that's fine.
Special remotes that support other domain-specific url schemes are not
affected by this change. In the bittorrent remote, aria2c can still
download magnet: links. The download of the .torrent file is
otherwise now limited by annex.security.allowed-url-schemes.
This does not address any external special remotes that might download
an url themselves. Current thinking is all external special remotes will
need to be audited for this problem, although many of them will use
http libraries that only support http and not curl's menagarie.
The related problem of accessing private localhost and LAN urls is not
addressed by this commit.
This commit was sponsored by Brett Eisenberg on Patreon.
2018-06-15 20:52:24 +00:00
|
|
|
youtubeDlFileNameHtmlOnly :: URLString -> Annex (Either String FilePath)
|
2018-06-28 17:01:18 +00:00
|
|
|
youtubeDlFileNameHtmlOnly = withUrlOptions . youtubeDlFileNameHtmlOnly'
|
limit url downloads to whitelisted schemes
Security fix! Allowing any schemes, particularly file: and
possibly others like scp: allowed file exfiltration by anyone who had
write access to the git repository, since they could add an annexed file
using such an url, or using an url that redirected to such an url,
and wait for the victim to get it into their repository and send them a copy.
* Added annex.security.allowed-url-schemes setting, which defaults
to only allowing http and https URLs. Note especially that file:/
is no longer enabled by default.
* Removed annex.web-download-command, since its interface does not allow
supporting annex.security.allowed-url-schemes across redirects.
If you used this setting, you may want to instead use annex.web-options
to pass options to curl.
With annex.web-download-command removed, nearly all url accesses in
git-annex are made via Utility.Url via http-client or curl. http-client
only supports http and https, so no problem there.
(Disabling one and not the other is not implemented.)
Used curl --proto to limit the allowed url schemes.
Note that this will cause git annex fsck --from web to mark files using
a disallowed url scheme as not being present in the web. That seems
acceptable; fsck --from web also does that when a web server is not available.
youtube-dl already disabled file: itself (probably for similar
reasons). The scheme check was also added to youtube-dl urls for
completeness, although that check won't catch any redirects it might
follow. But youtube-dl goes off and does its own thing with other
protocols anyway, so that's fine.
Special remotes that support other domain-specific url schemes are not
affected by this change. In the bittorrent remote, aria2c can still
download magnet: links. The download of the .torrent file is
otherwise now limited by annex.security.allowed-url-schemes.
This does not address any external special remotes that might download
an url themselves. Current thinking is all external special remotes will
need to be audited for this problem, although many of them will use
http libraries that only support http and not curl's menagarie.
The related problem of accessing private localhost and LAN urls is not
addressed by this commit.
This commit was sponsored by Brett Eisenberg on Patreon.
2018-06-15 20:52:24 +00:00
|
|
|
|
|
|
|
youtubeDlFileNameHtmlOnly' :: URLString -> UrlOptions -> Annex (Either String FilePath)
|
|
|
|
youtubeDlFileNameHtmlOnly' url uo
|
|
|
|
| supportedScheme uo url = flip catchIO (pure . Left . show) go
|
2017-12-11 16:46:34 +00:00
|
|
|
| otherwise = return nomedia
|
|
|
|
where
|
|
|
|
go = do
|
2017-12-08 18:49:55 +00:00
|
|
|
-- Sometimes youtube-dl will fail with an ugly backtrace
|
|
|
|
-- (eg, http://bugs.debian.org/874321)
|
|
|
|
-- so catch stderr as well as stdout to avoid the user
|
|
|
|
-- seeing it. --no-warnings avoids warning messages that
|
|
|
|
-- are output to stdout.
|
|
|
|
opts <- youtubeDlOpts
|
|
|
|
[ Param url
|
|
|
|
, Param "--get-filename"
|
|
|
|
, Param "--no-warnings"
|
2018-11-28 21:14:47 +00:00
|
|
|
, Param "--no-playlist"
|
2017-12-08 18:49:55 +00:00
|
|
|
]
|
2017-12-31 19:19:01 +00:00
|
|
|
(Nothing, Just o, Just e, pid) <- liftIO $ createProcess
|
|
|
|
(proc "youtube-dl" (toCommand opts))
|
|
|
|
{ std_out = CreatePipe
|
|
|
|
, std_err = CreatePipe
|
|
|
|
}
|
|
|
|
output <- liftIO $ fmap fst $
|
|
|
|
hGetContentsStrict o
|
|
|
|
`concurrently`
|
|
|
|
hGetContentsStrict e
|
|
|
|
ok <- liftIO $ checkSuccessProcess pid
|
2017-12-08 18:49:55 +00:00
|
|
|
return $ case (ok, lines output) of
|
|
|
|
(True, (f:_)) | not (null f) -> Right f
|
|
|
|
_ -> nomedia
|
|
|
|
nomedia = Left "no media in url"
|
2017-11-30 18:35:25 +00:00
|
|
|
|
|
|
|
youtubeDlOpts :: [CommandParam] -> Annex [CommandParam]
|
|
|
|
youtubeDlOpts addopts = do
|
2017-11-30 00:07:03 +00:00
|
|
|
opts <- map Param . annexYoutubeDlOptions <$> Annex.getGitConfig
|
2017-11-30 18:35:25 +00:00
|
|
|
return (opts ++ addopts)
|
2017-12-11 16:46:34 +00:00
|
|
|
|
limit url downloads to whitelisted schemes
Security fix! Allowing any schemes, particularly file: and
possibly others like scp: allowed file exfiltration by anyone who had
write access to the git repository, since they could add an annexed file
using such an url, or using an url that redirected to such an url,
and wait for the victim to get it into their repository and send them a copy.
* Added annex.security.allowed-url-schemes setting, which defaults
to only allowing http and https URLs. Note especially that file:/
is no longer enabled by default.
* Removed annex.web-download-command, since its interface does not allow
supporting annex.security.allowed-url-schemes across redirects.
If you used this setting, you may want to instead use annex.web-options
to pass options to curl.
With annex.web-download-command removed, nearly all url accesses in
git-annex are made via Utility.Url via http-client or curl. http-client
only supports http and https, so no problem there.
(Disabling one and not the other is not implemented.)
Used curl --proto to limit the allowed url schemes.
Note that this will cause git annex fsck --from web to mark files using
a disallowed url scheme as not being present in the web. That seems
acceptable; fsck --from web also does that when a web server is not available.
youtube-dl already disabled file: itself (probably for similar
reasons). The scheme check was also added to youtube-dl urls for
completeness, although that check won't catch any redirects it might
follow. But youtube-dl goes off and does its own thing with other
protocols anyway, so that's fine.
Special remotes that support other domain-specific url schemes are not
affected by this change. In the bittorrent remote, aria2c can still
download magnet: links. The download of the .torrent file is
otherwise now limited by annex.security.allowed-url-schemes.
This does not address any external special remotes that might download
an url themselves. Current thinking is all external special remotes will
need to be audited for this problem, although many of them will use
http libraries that only support http and not curl's menagarie.
The related problem of accessing private localhost and LAN urls is not
addressed by this commit.
This commit was sponsored by Brett Eisenberg on Patreon.
2018-06-15 20:52:24 +00:00
|
|
|
supportedScheme :: UrlOptions -> URLString -> Bool
|
|
|
|
supportedScheme uo url = case parseURIRelaxed url of
|
2017-12-11 16:46:34 +00:00
|
|
|
Nothing -> False
|
limit url downloads to whitelisted schemes
Security fix! Allowing any schemes, particularly file: and
possibly others like scp: allowed file exfiltration by anyone who had
write access to the git repository, since they could add an annexed file
using such an url, or using an url that redirected to such an url,
and wait for the victim to get it into their repository and send them a copy.
* Added annex.security.allowed-url-schemes setting, which defaults
to only allowing http and https URLs. Note especially that file:/
is no longer enabled by default.
* Removed annex.web-download-command, since its interface does not allow
supporting annex.security.allowed-url-schemes across redirects.
If you used this setting, you may want to instead use annex.web-options
to pass options to curl.
With annex.web-download-command removed, nearly all url accesses in
git-annex are made via Utility.Url via http-client or curl. http-client
only supports http and https, so no problem there.
(Disabling one and not the other is not implemented.)
Used curl --proto to limit the allowed url schemes.
Note that this will cause git annex fsck --from web to mark files using
a disallowed url scheme as not being present in the web. That seems
acceptable; fsck --from web also does that when a web server is not available.
youtube-dl already disabled file: itself (probably for similar
reasons). The scheme check was also added to youtube-dl urls for
completeness, although that check won't catch any redirects it might
follow. But youtube-dl goes off and does its own thing with other
protocols anyway, so that's fine.
Special remotes that support other domain-specific url schemes are not
affected by this change. In the bittorrent remote, aria2c can still
download magnet: links. The download of the .torrent file is
otherwise now limited by annex.security.allowed-url-schemes.
This does not address any external special remotes that might download
an url themselves. Current thinking is all external special remotes will
need to be audited for this problem, although many of them will use
http libraries that only support http and not curl's menagarie.
The related problem of accessing private localhost and LAN urls is not
addressed by this commit.
This commit was sponsored by Brett Eisenberg on Patreon.
2018-06-15 20:52:24 +00:00
|
|
|
Just u -> case uriScheme u of
|
|
|
|
-- avoid ugly message from youtube-dl about not supporting file:
|
|
|
|
"file:" -> False
|
|
|
|
-- ftp indexes may look like html pages, and there's no point
|
|
|
|
-- involving youtube-dl in a ftp download
|
|
|
|
"ftp:" -> False
|
|
|
|
_ -> allowedScheme uo u
|