Skip to content
Snippets Groups Projects
Unverified Commit fb2ac8c0 authored by Fraser Tweedale's avatar Fraser Tweedale Committed by GitHub
Browse files

cabal-install: update curl transport to support Basic authentication (#10089)


* cabal-install: extract url scheme checks

Extract a bunch of string equality checks for the URI scheme to
top-level functions.

* cabal-install: refactor and document transport checks

"They're the same picture".  Thus, refactor the *transport supports
https* checks.

* cabal-install: allow Basic authentication in curl transport

Allow the curl transport to use Basic authentication, if and only if
the url scheme is HTTPS (i.e. TLS will be used).  Retain the
existing behaviour (force Digest scheme) for insecure requests.

This change is required to support upcoming hackage-server changes.
The wget transport already supports Basic authentication.

---------

Co-authored-by: default avatarmergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent a1c94c10
No related branches found
No related tags found
No related merge requests found
Pipeline #99569 passed
......@@ -192,7 +192,7 @@ downloadURI transport verbosity uri path = do
-- Only use the external http transports if we actually have to
-- (or have been told to do so)
let transport'
| uriScheme uri == "http:"
| isHttpURI uri
, not (transportManuallySelected transport) =
plainHttpTransport
| otherwise =
......@@ -251,20 +251,35 @@ downloadURI transport verbosity uri path = do
-- Utilities for repo url management
--
-- | If the remote repo is accessed over HTTPS, ensure that the transport
-- supports HTTPS.
remoteRepoCheckHttps :: Verbosity -> HttpTransport -> RemoteRepo -> IO ()
remoteRepoCheckHttps verbosity transport repo
| uriScheme (remoteRepoURI repo) == "https:"
, not (transportSupportsHttps transport) =
dieWithException verbosity $ RemoteRepoCheckHttps (unRepoName (remoteRepoName repo)) requiresHttpsErrorMessage
| otherwise = return ()
remoteRepoCheckHttps verbosity transport repo =
transportCheckHttpsWithError verbosity transport (remoteRepoURI repo) $
RemoteRepoCheckHttps (unRepoName (remoteRepoName repo)) requiresHttpsErrorMessage
-- | If the URI scheme is HTTPS, ensure the transport supports HTTPS.
transportCheckHttps :: Verbosity -> HttpTransport -> URI -> IO ()
transportCheckHttps verbosity transport uri
| uriScheme uri == "https:"
transportCheckHttps verbosity transport uri =
transportCheckHttpsWithError verbosity transport uri $
TransportCheckHttps uri requiresHttpsErrorMessage
-- | If the URI scheme is HTTPS, ensure the transport supports HTTPS.
-- If not, fail with the given error.
transportCheckHttpsWithError
:: Verbosity -> HttpTransport -> URI -> CabalInstallException -> IO ()
transportCheckHttpsWithError verbosity transport uri err
| isHttpsURI uri
, not (transportSupportsHttps transport) =
dieWithException verbosity $ TransportCheckHttps uri requiresHttpsErrorMessage
dieWithException verbosity err
| otherwise = return ()
isHttpsURI :: URI -> Bool
isHttpsURI uri = uriScheme uri == "https:"
isHttpURI :: URI -> Bool
isHttpURI uri = uriScheme uri == "http:"
requiresHttpsErrorMessage :: String
requiresHttpsErrorMessage =
"requires HTTPS however the built-in HTTP implementation "
......@@ -280,12 +295,12 @@ requiresHttpsErrorMessage =
remoteRepoTryUpgradeToHttps :: Verbosity -> HttpTransport -> RemoteRepo -> IO RemoteRepo
remoteRepoTryUpgradeToHttps verbosity transport repo
| remoteRepoShouldTryHttps repo
, uriScheme (remoteRepoURI repo) == "http:"
, isHttpURI (remoteRepoURI repo)
, not (transportSupportsHttps transport)
, not (transportManuallySelected transport) =
dieWithException verbosity $ TryUpgradeToHttps [name | (name, _, True, _) <- supportedTransports]
| remoteRepoShouldTryHttps repo
, uriScheme (remoteRepoURI repo) == "http:"
, isHttpURI (remoteRepoURI repo)
, transportSupportsHttps transport =
return
repo
......@@ -505,12 +520,18 @@ curlTransport prog =
(Just (Left (uname, passwd)), _) -> Just $ Left (uname ++ ":" ++ passwd)
(Nothing, Just a) -> Just $ Left a
(Nothing, Nothing) -> Nothing
let authnSchemeArg
-- When using TLS, we can accept Basic authentication. Let curl
-- decide based on the scheme(s) offered by the server.
| isHttpsURI uri = "--anyauth"
-- When not using TLS, force Digest scheme
| otherwise = "--digest"
case mbAuthStringToken of
Just (Left up) ->
progInvocation
{ progInvokeInput =
Just . IODataText . unlines $
[ "--digest"
[ authnSchemeArg
, "--user " ++ up
]
, progInvokeArgs = ["--config", "-"] ++ progInvokeArgs progInvocation
......
synopsis: `curl` transport now supports Basic authentication
packages: cabal-install
prs: #10089
description: {
- The `curl` HTTP transport previously only supported the HTTP Digest
authentication scheme. Basic authentication is now supported
when using HTTPS; Curl will use the scheme offered by the server.
The `wget` transport already supports HTTPS.
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment