From 440b6d97f6496b68a275971b35cd15cc54065e4e Mon Sep 17 00:00:00 2001 From: Patrick Malouin Date: Tue, 15 Feb 2022 22:20:13 -0500 Subject: [PATCH 1/2] fix(pg-connection-string): get closer to libpq semantics for `sslmode` --- packages/pg-connection-string/README.md | 6 ++++-- packages/pg-connection-string/index.js | 21 ++++++++++++++++----- packages/pg-connection-string/test/parse.js | 17 +++++++++++------ 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/packages/pg-connection-string/README.md b/packages/pg-connection-string/README.md index 360505e0d..e5bf88ac0 100644 --- a/packages/pg-connection-string/README.md +++ b/packages/pg-connection-string/README.md @@ -68,8 +68,10 @@ Query parameters follow a `?` character, including the following special query p * `ssl=1`, `ssl=true`, `ssl=0`, `ssl=false` - sets `ssl` to true or false, accordingly * `sslmode=` * `sslmode=disable` - sets `ssl` to false - * `sslmode=no-verify` - sets `ssl` to `{ rejectUnauthorized: false }` - * `sslmode=prefer`, `sslmode=require`, `sslmode=verify-ca`, `sslmode=verify-full` - sets `ssl` to true + * `sslmode=no-verify`, `sslmode=prefer`, - sets `ssl` to `{ rejectUnauthorized: false }` + * `sslmode=require`, - sets `ssl` to `{ rejectUnauthorized: false }` unless `sslrootcert` is specified, in which case it behaves like `verify-ca` + * `sslmode=verify-ca` - sets `ssl` to `{ checkServerIdentity: no-op}` (verify CA, but not server identity) + * `sslmode=verify-full` - sets `ssl` to `{}` (verify CA and server identity) * `sslcert=` - reads data from the given file and includes the result as `ssl.cert` * `sslkey=` - reads data from the given file and includes the result as `ssl.key` * `sslrootcert=` - reads data from the given file and includes the result as `ssl.ca` diff --git a/packages/pg-connection-string/index.js b/packages/pg-connection-string/index.js index 995ff0684..5ac8030e7 100644 --- a/packages/pg-connection-string/index.js +++ b/packages/pg-connection-string/index.js @@ -87,15 +87,26 @@ function parse(str) { break } case 'prefer': - case 'require': - case 'verify-ca': - case 'verify-full': { - break - } case 'no-verify': { config.ssl.rejectUnauthorized = false break } + case 'require': { + if (config.sslrootcert) { + // If a root CA is specified, behavior of `sslmode=require` will be the same as that of `verify-ca` + config.ssl.checkServerIdentity = function () {} + } else { + config.ssl.rejectUnauthorized = false + } + break + } + case 'verify-ca': { + config.ssl.checkServerIdentity = function () {} + break + } + case 'verify-full': { + break + } } return config diff --git a/packages/pg-connection-string/test/parse.js b/packages/pg-connection-string/test/parse.js index a0cd26385..df6f4d7da 100644 --- a/packages/pg-connection-string/test/parse.js +++ b/packages/pg-connection-string/test/parse.js @@ -258,19 +258,24 @@ describe('parse', function () { it('configuration parameter sslmode=prefer', function () { var connectionString = 'pg:///?sslmode=prefer' var subject = parse(connectionString) - subject.ssl.should.eql({}) + subject.ssl.should.eql({ + rejectUnauthorized: false, + }) }) it('configuration parameter sslmode=require', function () { var connectionString = 'pg:///?sslmode=require' var subject = parse(connectionString) - subject.ssl.should.eql({}) + subject.ssl.should.eql({ + rejectUnauthorized: false, + }) }) it('configuration parameter sslmode=verify-ca', function () { var connectionString = 'pg:///?sslmode=verify-ca' var subject = parse(connectionString) - subject.ssl.should.eql({}) + subject.ssl.should.have.property('checkServerIdentity').that.is.a('function') + expect(subject.ssl.checkServerIdentity()).be.undefined }) it('configuration parameter sslmode=verify-full', function () { @@ -282,9 +287,9 @@ describe('parse', function () { it('configuration parameter ssl=true and sslmode=require still work with sslrootcert=/path/to/ca', function () { var connectionString = 'pg:///?ssl=true&sslrootcert=' + __dirname + '/example.ca&sslmode=require' var subject = parse(connectionString) - subject.ssl.should.eql({ - ca: 'example ca\n', - }) + subject.ssl.should.have.property('ca', 'example ca\n') + subject.ssl.should.have.property('checkServerIdentity').that.is.a('function') + expect(subject.ssl.checkServerIdentity()).be.undefined }) it('allow other params like max, ...', function () { From f1a6059db4bebbcb1102910c405230dccf95e2b6 Mon Sep 17 00:00:00 2001 From: Patrick Malouin Date: Wed, 23 Feb 2022 19:59:35 -0500 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Charmander <~@charmander.me> --- packages/pg-connection-string/README.md | 6 +++--- packages/pg-connection-string/test/parse.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/pg-connection-string/README.md b/packages/pg-connection-string/README.md index e5bf88ac0..a65dd139f 100644 --- a/packages/pg-connection-string/README.md +++ b/packages/pg-connection-string/README.md @@ -68,9 +68,9 @@ Query parameters follow a `?` character, including the following special query p * `ssl=1`, `ssl=true`, `ssl=0`, `ssl=false` - sets `ssl` to true or false, accordingly * `sslmode=` * `sslmode=disable` - sets `ssl` to false - * `sslmode=no-verify`, `sslmode=prefer`, - sets `ssl` to `{ rejectUnauthorized: false }` - * `sslmode=require`, - sets `ssl` to `{ rejectUnauthorized: false }` unless `sslrootcert` is specified, in which case it behaves like `verify-ca` - * `sslmode=verify-ca` - sets `ssl` to `{ checkServerIdentity: no-op}` (verify CA, but not server identity) + * `sslmode=no-verify`, `sslmode=prefer` - sets `ssl` to `{ rejectUnauthorized: false }` + * `sslmode=require` - sets `ssl` to `{ rejectUnauthorized: false }` unless `sslrootcert` is specified, in which case it behaves like `verify-ca` + * `sslmode=verify-ca` - sets `ssl` to `{ checkServerIdentity: no-op }` (verify CA, but not server identity) * `sslmode=verify-full` - sets `ssl` to `{}` (verify CA and server identity) * `sslcert=` - reads data from the given file and includes the result as `ssl.cert` * `sslkey=` - reads data from the given file and includes the result as `ssl.key` diff --git a/packages/pg-connection-string/test/parse.js b/packages/pg-connection-string/test/parse.js index df6f4d7da..69dd96015 100644 --- a/packages/pg-connection-string/test/parse.js +++ b/packages/pg-connection-string/test/parse.js @@ -275,7 +275,7 @@ describe('parse', function () { var connectionString = 'pg:///?sslmode=verify-ca' var subject = parse(connectionString) subject.ssl.should.have.property('checkServerIdentity').that.is.a('function') - expect(subject.ssl.checkServerIdentity()).be.undefined + expect(subject.ssl.checkServerIdentity()).to.be.undefined }) it('configuration parameter sslmode=verify-full', function () { @@ -289,7 +289,7 @@ describe('parse', function () { var subject = parse(connectionString) subject.ssl.should.have.property('ca', 'example ca\n') subject.ssl.should.have.property('checkServerIdentity').that.is.a('function') - expect(subject.ssl.checkServerIdentity()).be.undefined + expect(subject.ssl.checkServerIdentity()).to.be.undefined }) it('allow other params like max, ...', function () {