Skip to content

Commit

Permalink
feat(devtools-proxy-support): support Node.js `allowPartialTrustChain…
Browse files Browse the repository at this point in the history
…` flag COMPASS-8253 (#476)

This should allow getting back to faster startup times in mongosh.
  • Loading branch information
addaleax authored Sep 26, 2024
1 parent b9f28be commit 1039f1d
Show file tree
Hide file tree
Showing 12 changed files with 248 additions and 60 deletions.
75 changes: 40 additions & 35 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/devtools-connect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
},
"peerDependencies": {
"@mongodb-js/oidc-plugin": "^1.1.0",
"mongodb": "^6.8.0",
"mongodb": "^6.9.0",
"mongodb-log-writer": "^1.4.2"
},
"devDependencies": {
Expand All @@ -75,7 +75,7 @@
"eslint-plugin-promise": "^6.1.1",
"gen-esm-wrapper": "^1.1.0",
"mocha": "^8.4.0",
"mongodb": "^6.8.0",
"mongodb": "^6.9.0",
"mongodb-log-writer": "^1.4.2",
"nyc": "^15.1.0",
"os-dns-native": "^1.2.0",
Expand Down
20 changes: 15 additions & 5 deletions packages/devtools-connect/src/connect.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ describe('devtools connect', function () {
expect(mClientType.getCalls()[0].args[0]).to.equal(uri);
expect(
Object.keys(mClientType.getCalls()[0].args[1]).sort()
).to.deep.equal(['ca', 'lookup']);
).to.deep.equal(['allowPartialTrustChain', 'ca', 'lookup']);
expect(mClient.connect.getCalls()).to.have.lengthOf(1);
expect(result.client).to.equal(mClient);
});
Expand All @@ -73,7 +73,12 @@ describe('devtools connect', function () {
expect(mClientType.getCalls()[0].args[0]).to.equal(uri);
expect(
Object.keys(mClientType.getCalls()[0].args[1]).sort()
).to.deep.equal(['autoEncryption', 'ca', 'lookup']);
).to.deep.equal([
'allowPartialTrustChain',
'autoEncryption',
'ca',
'lookup',
]);
expect(mClientType.getCalls()[0].args[1].autoEncryption).to.deep.equal(
opts.autoEncryption
);
Expand Down Expand Up @@ -114,7 +119,7 @@ describe('devtools connect', function () {
expect(calls[0].args[0]).to.equal(uri);
expect(
Object.keys(mClientType.getCalls()[0].args[1]).sort()
).to.deep.equal(['ca', 'lookup']);
).to.deep.equal(['allowPartialTrustChain', 'ca', 'lookup']);
expect(commandSpy).to.have.been.calledOnceWithExactly({ buildInfo: 1 });
expect(result.client).to.equal(mClientSecond);
});
Expand Down Expand Up @@ -192,7 +197,12 @@ describe('devtools connect', function () {
expect(mClientType.getCalls()[0].args[0]).to.equal(uri);
expect(
Object.keys(mClientType.getCalls()[0].args[1]).sort()
).to.deep.equal(['autoEncryption', 'ca', 'lookup']);
).to.deep.equal([
'allowPartialTrustChain',
'autoEncryption',
'ca',
'lookup',
]);
expect(mClient.connect.getCalls()).to.have.lengthOf(1);
expect(result.client).to.equal(mClient);
});
Expand Down Expand Up @@ -230,7 +240,7 @@ describe('devtools connect', function () {
expect(mClientType.getCalls()[0].args[0]).to.equal(uri);
expect(
Object.keys(mClientType.getCalls()[0].args[1]).sort()
).to.deep.equal(['ca', 'lookup']);
).to.deep.equal(['allowPartialTrustChain', 'ca', 'lookup']);
expect(commandSpy).to.have.been.calledOnceWithExactly({ buildInfo: 1 });
expect(result.client).to.equal(mClientSecond);
});
Expand Down
2 changes: 1 addition & 1 deletion packages/devtools-connect/src/connect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ export async function connectMongoClient(
{},
clientOptions,
shouldAddOidcCallbacks ? state.oidcPlugin.mongoClientOptions : {},
{ ca }
{ ca, allowPartialTrustChain: true }
);

// Adopt dns result order changes with Node v18 that affected the VSCode extension VSCODE-458.
Expand Down
2 changes: 1 addition & 1 deletion packages/devtools-proxy-support/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"https-proxy-agent": "^7.0.5",
"socks-proxy-agent": "^8.0.4",
"ssh2": "^1.15.0",
"system-ca": "^2.0.0"
"system-ca": "^2.0.1"
},
"devDependencies": {
"@mongodb-js/eslint-config-devtools": "0.9.10",
Expand Down
65 changes: 58 additions & 7 deletions packages/devtools-proxy-support/src/agent.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import { expect } from 'chai';
import sinon from 'sinon';
import { HTTPServerProxyTestSetup } from '../test/helpers';
import path from 'path';
import type { Server as TLSServer } from 'tls';
import { createServer as createTLSServer } from 'tls';
import { promises as fs } from 'fs';
import type { AddressInfo } from 'net';
import { tlsSupportsAllowPartialTrustChainFlag } from './system-ca';

describe('createAgent', function () {
let setup: HTTPServerProxyTestSetup;
Expand Down Expand Up @@ -38,9 +43,11 @@ describe('createAgent', function () {
agents = [];
setup = new HTTPServerProxyTestSetup();
await setup.listen();
resetSystemCACache();
});

afterEach(async function () {
resetSystemCACache();
await setup.teardown();
for (const agent of new Set(agents)) {
agent.destroy();
Expand Down Expand Up @@ -183,13 +190,6 @@ describe('createAgent', function () {
});

context('ca support', function () {
beforeEach(function () {
resetSystemCACache();
});
afterEach(function () {
resetSystemCACache();
});

it('can connect using CA as part of the agent options (no explicit CA set)', async function () {
const res = await get(
'https://example.com/hello',
Expand Down Expand Up @@ -362,4 +362,55 @@ q/I2+0j6dAkOGcK/68z7qQXByeGri3n28a1Kn6o=
}
});
});

// This mirrors https://github.com/nodejs/node/blob/1b3420274ea8d8cca339a1f10301d2e80f577c4c/test/parallel/test-tls-client-allow-partial-trust-chain.js
context(
'TLS with partial trust chain in system certificate list',
function () {
const fixtures = path.resolve(
__dirname,
'..',
'test',
'fixtures',
'partial-trust-chain'
);
let server: TLSServer;

beforeEach(async function () {
server = createTLSServer(
{
ca: await fs.readFile(path.join(fixtures, 'ca.pem')),
key: await fs.readFile(path.join(fixtures, 'key.pem')),
cert: await fs.readFile(path.join(fixtures, 'cert.pem')),
},
(socket) => socket.end('HTTP/1.0 200 OK\r\n\r\nOK /hello')
);
server.listen(0);
});

afterEach(function () {
server?.close();
});

it('can connect using partial trust chains in the system CA list', async function () {
if (
process.platform !== 'linux' ||
!tlsSupportsAllowPartialTrustChainFlag()
)
return this.skip(); // only really mock-able on Linux
resetSystemCACache({
env: {
SSL_CERT_FILE: path.join(fixtures, 'ca.pem'),
SSL_CERT_DIR: '/nonexistent',
},
});

const res = await get(
`https://localhost:${(server.address() as AddressInfo).port}/hello`,
createAgent({})
);
expect(res.body).to.equal('OK /hello');
});
}
);
});
Loading

0 comments on commit 1039f1d

Please sign in to comment.