@@ -45,6 +45,11 @@ def parse(cls, sslmode):
45
45
return getattr (cls , sslmode .replace ('-' , '_' ))
46
46
47
47
48
+ class SSLNegotiation (compat .StrEnum ):
49
+ postgres = "postgres"
50
+ direct = "direct"
51
+
52
+
48
53
_ConnectionParameters = collections .namedtuple (
49
54
'ConnectionParameters' ,
50
55
[
@@ -53,7 +58,7 @@ def parse(cls, sslmode):
53
58
'database' ,
54
59
'ssl' ,
55
60
'sslmode' ,
56
- 'direct_tls ' ,
61
+ 'ssl_negotiation ' ,
57
62
'server_settings' ,
58
63
'target_session_attrs' ,
59
64
'krbsrvname' ,
@@ -269,6 +274,7 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
269
274
auth_hosts = None
270
275
sslcert = sslkey = sslrootcert = sslcrl = sslpassword = None
271
276
ssl_min_protocol_version = ssl_max_protocol_version = None
277
+ sslnegotiation = None
272
278
273
279
if dsn :
274
280
parsed = urllib .parse .urlparse (dsn )
@@ -362,6 +368,9 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
362
368
if 'sslrootcert' in query :
363
369
sslrootcert = query .pop ('sslrootcert' )
364
370
371
+ if 'sslnegotiation' in query :
372
+ sslnegotiation = query .pop ('sslnegotiation' )
373
+
365
374
if 'sslcrl' in query :
366
375
sslcrl = query .pop ('sslcrl' )
367
376
@@ -503,13 +512,36 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
503
512
if ssl is None and have_tcp_addrs :
504
513
ssl = 'prefer'
505
514
515
+ if direct_tls is not None :
516
+ sslneg = (
517
+ SSLNegotiation .direct if direct_tls else SSLNegotiation .postgres
518
+ )
519
+ else :
520
+ if sslnegotiation is None :
521
+ sslnegotiation = os .environ .get ("PGSSLNEGOTIATION" )
522
+
523
+ if sslnegotiation is not None :
524
+ try :
525
+ sslneg = SSLNegotiation (sslnegotiation )
526
+ except ValueError :
527
+ modes = ', ' .join (
528
+ m .name .replace ('_' , '-' )
529
+ for m in SSLNegotiation
530
+ )
531
+ raise exceptions .ClientConfigurationError (
532
+ f'`sslnegotiation` parameter must be one of: { modes } '
533
+ ) from None
534
+ else :
535
+ sslneg = SSLNegotiation .postgres
536
+
506
537
if isinstance (ssl , (str , SSLMode )):
507
538
try :
508
539
sslmode = SSLMode .parse (ssl )
509
540
except AttributeError :
510
541
modes = ', ' .join (m .name .replace ('_' , '-' ) for m in SSLMode )
511
542
raise exceptions .ClientConfigurationError (
512
- '`sslmode` parameter must be one of: {}' .format (modes ))
543
+ '`sslmode` parameter must be one of: {}' .format (modes )
544
+ ) from None
513
545
514
546
# docs at https://www.postgresql.org/docs/10/static/libpq-connect.html
515
547
if sslmode < SSLMode .allow :
@@ -676,7 +708,7 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
676
708
677
709
params = _ConnectionParameters (
678
710
user = user , password = password , database = database , ssl = ssl ,
679
- sslmode = sslmode , direct_tls = direct_tls ,
711
+ sslmode = sslmode , ssl_negotiation = sslneg ,
680
712
server_settings = server_settings ,
681
713
target_session_attrs = target_session_attrs ,
682
714
krbsrvname = krbsrvname , gsslib = gsslib )
@@ -882,9 +914,9 @@ async def __connect_addr(
882
914
# UNIX socket
883
915
connector = loop .create_unix_connection (proto_factory , addr )
884
916
885
- elif params .ssl and params .direct_tls :
886
- # if ssl and direct_tls are given , skip STARTTLS and perform direct
887
- # SSL connection
917
+ elif params .ssl and params .ssl_negotiation is SSLNegotiation . direct :
918
+ # if ssl and ssl_negotiation is `direct` , skip STARTTLS and perform
919
+ # direct SSL connection
888
920
connector = loop .create_connection (
889
921
proto_factory , * addr , ssl = params .ssl
890
922
)
0 commit comments