Skip to content

Commit fb2ac8c

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: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
1 parent a1c94c1 commit fb2ac8c

File tree

2 files changed

+45
-12
lines changed

2 files changed

+45
-12
lines changed

cabal-install/src/Distribution/Client/HttpUtils.hs

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ downloadURI transport verbosity uri path = do
192192
-- Only use the external http transports if we actually have to
193193
-- (or have been told to do so)
194194
let transport'
195-
| uriScheme uri == "http:"
195+
| isHttpURI uri
196196
, not (transportManuallySelected transport) =
197197
plainHttpTransport
198198
| otherwise =
@@ -251,20 +251,35 @@ downloadURI transport verbosity uri path = do
251251
-- Utilities for repo url management
252252
--
253253

254+
-- | If the remote repo is accessed over HTTPS, ensure that the transport
255+
-- supports HTTPS.
254256
remoteRepoCheckHttps :: Verbosity -> HttpTransport -> RemoteRepo -> IO ()
255-
remoteRepoCheckHttps verbosity transport repo
256-
| uriScheme (remoteRepoURI repo) == "https:"
257-
, not (transportSupportsHttps transport) =
258-
dieWithException verbosity $ RemoteRepoCheckHttps (unRepoName (remoteRepoName repo)) requiresHttpsErrorMessage
259-
| otherwise = return ()
257+
remoteRepoCheckHttps verbosity transport repo =
258+
transportCheckHttpsWithError verbosity transport (remoteRepoURI repo) $
259+
RemoteRepoCheckHttps (unRepoName (remoteRepoName repo)) requiresHttpsErrorMessage
260260

261+
-- | If the URI scheme is HTTPS, ensure the transport supports HTTPS.
261262
transportCheckHttps :: Verbosity -> HttpTransport -> URI -> IO ()
262-
transportCheckHttps verbosity transport uri
263-
| uriScheme uri == "https:"
263+
transportCheckHttps verbosity transport uri =
264+
transportCheckHttpsWithError verbosity transport uri $
265+
TransportCheckHttps uri requiresHttpsErrorMessage
266+
267+
-- | If the URI scheme is HTTPS, ensure the transport supports HTTPS.
268+
-- If not, fail with the given error.
269+
transportCheckHttpsWithError
270+
:: Verbosity -> HttpTransport -> URI -> CabalInstallException -> IO ()
271+
transportCheckHttpsWithError verbosity transport uri err
272+
| isHttpsURI uri
264273
, not (transportSupportsHttps transport) =
265-
dieWithException verbosity $ TransportCheckHttps uri requiresHttpsErrorMessage
274+
dieWithException verbosity err
266275
| otherwise = return ()
267276

277+
isHttpsURI :: URI -> Bool
278+
isHttpsURI uri = uriScheme uri == "https:"
279+
280+
isHttpURI :: URI -> Bool
281+
isHttpURI uri = uriScheme uri == "http:"
282+
268283
requiresHttpsErrorMessage :: String
269284
requiresHttpsErrorMessage =
270285
"requires HTTPS however the built-in HTTP implementation "
@@ -280,12 +295,12 @@ requiresHttpsErrorMessage =
280295
remoteRepoTryUpgradeToHttps :: Verbosity -> HttpTransport -> RemoteRepo -> IO RemoteRepo
281296
remoteRepoTryUpgradeToHttps verbosity transport repo
282297
| remoteRepoShouldTryHttps repo
283-
, uriScheme (remoteRepoURI repo) == "http:"
298+
, isHttpURI (remoteRepoURI repo)
284299
, not (transportSupportsHttps transport)
285300
, not (transportManuallySelected transport) =
286301
dieWithException verbosity $ TryUpgradeToHttps [name | (name, _, True, _) <- supportedTransports]
287302
| remoteRepoShouldTryHttps repo
288-
, uriScheme (remoteRepoURI repo) == "http:"
303+
, isHttpURI (remoteRepoURI repo)
289304
, transportSupportsHttps transport =
290305
return
291306
repo
@@ -505,12 +520,18 @@ curlTransport prog =
505520
(Just (Left (uname, passwd)), _) -> Just $ Left (uname ++ ":" ++ passwd)
506521
(Nothing, Just a) -> Just $ Left a
507522
(Nothing, Nothing) -> Nothing
523+
let authnSchemeArg
524+
-- When using TLS, we can accept Basic authentication. Let curl
525+
-- decide based on the scheme(s) offered by the server.
526+
| isHttpsURI uri = "--anyauth"
527+
-- When not using TLS, force Digest scheme
528+
| otherwise = "--digest"
508529
case mbAuthStringToken of
509530
Just (Left up) ->
510531
progInvocation
511532
{ progInvokeInput =
512533
Just . IODataText . unlines $
513-
[ "--digest"
534+
[ authnSchemeArg
514535
, "--user " ++ up
515536
]
516537
, progInvokeArgs = ["--config", "-"] ++ progInvokeArgs progInvocation

changelog.d/pr-10089

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
synopsis: `curl` transport now supports Basic authentication
2+
packages: cabal-install
3+
prs: #10089
4+
5+
description: {
6+
7+
- The `curl` HTTP transport previously only supported the HTTP Digest
8+
authentication scheme. Basic authentication is now supported
9+
when using HTTPS; Curl will use the scheme offered by the server.
10+
The `wget` transport already supports HTTPS.
11+
12+
}

0 commit comments

Comments
 (0)