@@ -23,6 +23,12 @@ class TimeoutError(ProcessError):
23
23
class AuthenticationError (ProcessError ):
24
24
pass
25
25
26
+ # The default digest for multiprocessing.connection to use for auth.
27
+ # We configure it here so that it can be tested when choosing a
28
+ # default context without a circular import.
29
+ # Must be the str of a value seen in connection._ALLOWED_DIGESTS.
30
+ _DIGEST_FOR_CONNECTION_HMAC = 'sha256'
31
+
26
32
#
27
33
# Base type for contexts. Bound methods of an instance of this type are included in __all__ of __init__.py
28
34
#
@@ -313,6 +319,21 @@ class ForkServerContext(BaseContext):
313
319
def _check_available (self ):
314
320
if not reduction .HAVE_SEND_HANDLE :
315
321
raise ValueError ('forkserver start method not available' )
322
+ if not _test_if_connection_can_work ():
323
+ raise ValueError (f'forkserver start method not available due to missing hmac-{ _DIGEST_FOR_CONNECTION_HMAC } ' )
324
+
325
+ def _test_if_connection_can_work () -> bool :
326
+ # Authenticated connections required for forkserver using hmac.
327
+ # If the algorithm is unavailable (poor FIPS mode config?) at
328
+ # import time, we cannot default to forkserver. If a user
329
+ # changes the _DIGEST_FOR_CONNECTION_HMAC to one that works in
330
+ # their strange config, the forkserver context will still work.
331
+ import hmac
332
+ try :
333
+ hmac .new (b'test-key' * 8 , b'' , _DIGEST_FOR_CONNECTION_HMAC )
334
+ except ValueError :
335
+ return False
336
+ return True
316
337
317
338
_concrete_contexts = {
318
339
'fork' : ForkContext (),
@@ -322,7 +343,8 @@ def _check_available(self):
322
343
# bpo-33725: running arbitrary code after fork() is no longer reliable
323
344
# on macOS since macOS 10.14 (Mojave). Use spawn by default instead.
324
345
# gh-84559: We changed everyones default to a thread safeish one in 3.14.
325
- if reduction .HAVE_SEND_HANDLE and sys .platform != 'darwin' :
346
+ if (reduction .HAVE_SEND_HANDLE and sys .platform != 'darwin' and
347
+ _test_if_connection_can_work ()):
326
348
_default_context = DefaultContext (_concrete_contexts ['forkserver' ])
327
349
else :
328
350
_default_context = DefaultContext (_concrete_contexts ['spawn' ])
0 commit comments