Skip to content

Commit 70eb04c

Browse files
jdobeselprans
authored andcommitted
Add support for sslcert, sslkey and sslrootcert parameters in DSNs
1 parent 67ebbc9 commit 70eb04c

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

asyncpg/connect_utils.py

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ def _parse_hostlist(hostlist, port, *, unquote=False):
222222

223223
def _parse_connect_dsn_and_args(*, dsn, host, port, user,
224224
password, passfile, database, ssl,
225+
sslcert, sslkey, sslrootcert, sslcrl,
225226
connect_timeout, server_settings):
226227
# `auth_hosts` is the version of host information for the purposes
227228
# of reading the pgpass file.
@@ -310,6 +311,26 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
310311
if ssl is None:
311312
ssl = val
312313

314+
if 'sslcert' in query:
315+
val = query.pop('sslcert')
316+
if sslcert is None:
317+
sslcert = val
318+
319+
if 'sslkey' in query:
320+
val = query.pop('sslkey')
321+
if sslkey is None:
322+
sslkey = val
323+
324+
if 'sslrootcert' in query:
325+
val = query.pop('sslrootcert')
326+
if sslrootcert is None:
327+
sslrootcert = val
328+
329+
if 'sslcrl' in query:
330+
val = query.pop('sslcrl')
331+
if sslcrl is None:
332+
sslcrl = val
333+
313334
if query:
314335
if server_settings is None:
315336
server_settings = query
@@ -427,7 +448,6 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
427448
'`sslmode` parameter must be one of: {}'.format(modes))
428449

429450
# docs at https://www.postgresql.org/docs/10/static/libpq-connect.html
430-
# Not implemented: sslcert & sslkey & sslrootcert & sslcrl params.
431451
if sslmode < SSLMode.allow:
432452
ssl = False
433453
else:
@@ -436,6 +456,28 @@ def _parse_connect_dsn_and_args(*, dsn, host, port, user,
436456
ssl.verify_mode = ssl_module.CERT_REQUIRED
437457
if sslmode <= SSLMode.require:
438458
ssl.verify_mode = ssl_module.CERT_NONE
459+
460+
if sslcert is None:
461+
sslcert = os.getenv('PGSSLCERT')
462+
463+
if sslkey is None:
464+
sslkey = os.getenv('PGSSLKEY')
465+
466+
if sslrootcert is None:
467+
sslrootcert = os.getenv('PGSSLROOTCERT')
468+
469+
if sslcrl is None:
470+
sslcrl = os.getenv('PGSSLCRL')
471+
472+
if sslcert:
473+
ssl.load_cert_chain(sslcert, keyfile=sslkey)
474+
475+
if sslrootcert:
476+
ssl.load_verify_locations(cafile=sslrootcert)
477+
478+
if sslcrl:
479+
ssl.load_verify_locations(cafile=sslcrl)
480+
439481
elif ssl is True:
440482
ssl = ssl_module.create_default_context()
441483
sslmode = SSLMode.verify_full
@@ -463,7 +505,8 @@ def _parse_connect_arguments(*, dsn, host, port, user, password, passfile,
463505
statement_cache_size,
464506
max_cached_statement_lifetime,
465507
max_cacheable_statement_size,
466-
ssl, server_settings):
508+
ssl, sslcert, sslkey, sslrootcert, sslcrl,
509+
server_settings):
467510

468511
local_vars = locals()
469512
for var_name in {'max_cacheable_statement_size',
@@ -491,7 +534,8 @@ def _parse_connect_arguments(*, dsn, host, port, user, password, passfile,
491534
addrs, params = _parse_connect_dsn_and_args(
492535
dsn=dsn, host=host, port=port, user=user,
493536
password=password, passfile=passfile, ssl=ssl,
494-
database=database, connect_timeout=timeout,
537+
sslcert=sslcert, sslkey=sslkey, sslrootcert=sslrootcert,
538+
sslcrl=sslcrl, database=database, connect_timeout=timeout,
495539
server_settings=server_settings)
496540

497541
config = _ClientConfiguration(

asyncpg/connection.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,6 +1758,10 @@ async def connect(dsn=None, *,
17581758
max_cacheable_statement_size=1024 * 15,
17591759
command_timeout=None,
17601760
ssl=None,
1761+
sslcert=None,
1762+
sslkey=None,
1763+
sslrootcert=None,
1764+
sslcrl=None,
17611765
connection_class=Connection,
17621766
record_class=protocol.Record,
17631767
server_settings=None):
@@ -1900,6 +1904,21 @@ async def connect(dsn=None, *,
19001904
.. note::
19011905
19021906
*ssl* is ignored for Unix domain socket communication.
1907+
1908+
:param sslcert:
1909+
This parameter specifies the file name of the client SSL certificate.
1910+
1911+
:param sslkey:
1912+
This parameter specifies the location for the secret key used for
1913+
the client certificate.
1914+
1915+
:param sslrootcert:
1916+
This parameter specifies the name of a file containing SSL certificate
1917+
authority (CA) certificate(s).
1918+
1919+
:param sslcrl
1920+
This parameter specifies the file name of the SSL certificate
1921+
revocation list (CRL).
19031922
19041923
:param dict server_settings:
19051924
An optional dict of server runtime parameters. Refer to
@@ -1993,6 +2012,10 @@ async def connect(dsn=None, *,
19932012
password=password,
19942013
passfile=passfile,
19952014
ssl=ssl,
2015+
sslcert=sslcert,
2016+
sslkey=sslkey,
2017+
sslrootcert=sslrootcert,
2018+
sslcrl=sslcrl,
19962019
database=database,
19972020
server_settings=server_settings,
19982021
command_timeout=command_timeout,

0 commit comments

Comments
 (0)