Merge pull request #10 from zeit/no-cert-locations

Treat certs as file contents
This commit is contained in:
Naoyuki Kanezawa 2019-10-09 21:09:23 +09:00 committed by GitHub
commit 5652168b41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 63 deletions

View File

@ -19,7 +19,6 @@
import moment from 'moment'; import moment from 'moment';
import * as os from 'os'; import * as os from 'os';
import * as dns from 'dns'; import * as dns from 'dns';
import * as fs from 'fs';
import * as tls from 'tls'; // eslint-disable-line no-unused-vars import * as tls from 'tls'; // eslint-disable-line no-unused-vars
let dnsPromises = dns.promises; let dnsPromises = dns.promises;
@ -99,9 +98,9 @@ type SyslogOptions = {
rfc5424?: RFC5424 | RFC5424Options; rfc5424?: RFC5424 | RFC5424Options;
target?: string; target?: string;
tcpTimeout?: number; tcpTimeout?: number;
tlsServerCerts?: string | string[]; tlsServerCerts?: (Buffer | string)[];
tlsClientCert?: string; tlsClientCert?: Buffer | string;
tlsClientKey?: string; tlsClientKey?: Buffer | string;
}; };
/** /**
@ -126,9 +125,9 @@ export class Syslog {
rfc5424: any; rfc5424: any;
target: string; target: string;
tcpTimeout: number; tcpTimeout: number;
tlsServerCerts: string | string[]; tlsServerCerts: (Buffer | string)[];
tlsClientCert: string; tlsClientCert: Buffer | string;
tlsClientKey: string; tlsClientKey: Buffer | string;
/** /**
* Construct a new Syslog transport object with user options * Construct a new Syslog transport object with user options
* @public * @public
@ -148,15 +147,15 @@ export class Syslog {
* @param {number} [options.tcpTimeout=10000] - Ignored for all other * @param {number} [options.tcpTimeout=10000] - Ignored for all other
* transports, this option if set will take presidents over any timeout * transports, this option if set will take presidents over any timeout
* set in a formatting object * set in a formatting object
* @param {string[]} [options.tlsServerCerts] - Array of authorized TLS server * @param {Buffer[]|string[]} [options.tlsServerCerts] - Array of authorized
* certificates file locations, this option if set will take presidents * TLS server certificates, this option if set will take presidents
* over any certificates set in a formatting object * over any certificates set in a formatting object
* @param {string} [options.tlsClientCert] - Client TLS certificate file * @param {string} [options.tlsClientCert] - Client TLS certificate that this
* location that this client should use, this option if set will take * client should use, this option if set will take presidents over any
* presidents over any certificates set in a formatting object * certificates set in a formatting object
* @param {string} [options.tlsClientKey] - Client TLS key file * @param {string} [options.tlsClientKey] - Client TLS key that this client
* location that this client should use, this option if set will take * should use, this option if set will take presidents over any
* presidents over any certificates set in a formatting object * certificates set in a formatting object
* @param {string} [options.rejectUnauthorized] - If not false, the server * @param {string} [options.rejectUnauthorized] - If not false, the server
* certificate is verified against the list of supplied CAs. * certificate is verified against the list of supplied CAs.
* >>>Syslog Format Settings * >>>Syslog Format Settings
@ -185,12 +184,11 @@ export class Syslog {
this.port = options.port || 514; this.port = options.port || 514;
/** @type {number} */ /** @type {number} */
this.tcpTimeout = options.tcpTimeout || 10000; this.tcpTimeout = options.tcpTimeout || 10000;
if ((typeof options.tlsServerCerts === 'object' if (Array.isArray(options.tlsServerCerts)
&& Array.isArray(options.tlsServerCerts)) || Buffer.isBuffer(options.tlsServerCerts)
|| typeof options.tlsServerCerts === 'string') { || typeof options.tlsServerCerts === 'string') {
this.addTlsServerCerts(options.tlsServerCerts); this.addTlsServerCerts(options.tlsServerCerts);
} else { } else {
/** @type {string[]} */
this.tlsServerCerts = []; this.tlsServerCerts = [];
} }
if (options.tlsClientCert) { if (options.tlsClientCert) {
@ -258,24 +256,24 @@ export class Syslog {
/** /**
* Add a TLS server certificate which can be used to authenticate the server * Add a TLS server certificate which can be used to authenticate the server
* this syslog client is connecting too. This function will validate the * this syslog client is connecting too. This function will validate the
* input as a file location string and add it to an array of certificates * input type and add it to an array of certificates
* @private * @private
* @version 0.0.0 * @version 0.0.0
* @since 0.0.0 * @since 0.0.0
* @param {string|string[]} certs - File location of the certificate(s) * @param {Buffer|Buffer[]|string|string[]} certs - the certificate(s)
* @returns {boolean} - True * @returns {boolean} - True
* @throws {Error} - A Type Error * @throws {Error} - A Type Error
*/ */
addTlsServerCerts(certs) { addTlsServerCerts(certs) {
if (typeof certs === 'object' && Array.isArray(certs)) { if (Array.isArray(certs)) {
/** @private @type {string[]} */ /** @private @type {string[]} */
this.tlsServerCerts = certs; this.tlsServerCerts = certs;
} else if (typeof certs === 'string') { } else if (Buffer.isBuffer(certs) || typeof certs === 'string') {
this.tlsServerCerts = [certs]; this.tlsServerCerts = [certs];
} else { } else {
let errMsg = let errMsg =
'TYPE ERROR: Server Cert file locations should be a string'; 'TYPE ERROR: Server Cert should be a Buffer/string';
errMsg += ' or array of strings'; errMsg += ' or array of Buffers/strings';
throw new Error(errMsg); throw new Error(errMsg);
} }
return true; return true;
@ -361,32 +359,32 @@ export class Syslog {
port: this.port, port: this.port,
}; };
// Load client cert and key if requested // Load client cert and key if requested
if (typeof this.tlsClientKey === 'string' if (Buffer.isBuffer(this.tlsClientKey)
&& typeof this.tlsClientCert === 'string') { || typeof this.tlsClientKey === 'string') {
tlsOptions.key = fs.readFileSync(this.tlsClientKey); tlsOptions.key = this.tlsClientKey;
tlsOptions.cert = fs.readFileSync(this.tlsClientCert); } else if (typeof this.tlsClientKey !== 'undefined') {
} else if (typeof this.tlsClientKey !== 'string' const errMsg = 'TYPE ERROR: TLS Client Key is not a valid type';
&& typeof this.tlsClientKey !== 'undefined') {
let errMsg = 'TYPE ERROR: TLS Client Key is not a file';
errMsg += 'location string';
throw new Error(errMsg); throw new Error(errMsg);
} else if (typeof this.tlsClientCert !== 'string' }
&& typeof this.tlsClientCert !== 'undefined') { if (Buffer.isBuffer(this.tlsClientCert)
let errMsg = 'TYPE ERROR: TLS Client Cert is not a file'; || typeof this.tlsClientCert === 'string') {
errMsg += 'location string'; tlsOptions.cert = this.tlsClientCert;
} else if (typeof this.tlsClientCert !== 'undefined') {
const errMsg = 'TYPE ERROR: TLS Client Cert is not a valid type';
throw new Error(errMsg); throw new Error(errMsg);
} }
// Load any server certs if provided // Load any server certs if provided
let tlsCerts = this.tlsServerCerts.length; let tlsCerts = this.tlsServerCerts.length;
if (tlsCerts > 0) { if (tlsCerts > 0) {
let tlsOptionsCerts = []; const tlsOptionsCerts = [];
for (let certIndex = 0; certIndex < tlsCerts; certIndex++) { for (let certIndex = 0; certIndex < tlsCerts; certIndex++) {
if (typeof this.tlsServerCerts[certIndex] !== 'string') { const tlsServerCert = this.tlsServerCerts[certIndex];
let errMsg = 'TYPE ERROR: TLS Server Cert is not a file'; if (!Buffer.isBuffer(tlsServerCert)
errMsg += 'location string'; && typeof tlsServerCert !== 'string') {
let errMsg = 'TYPE ERROR: TLS Server Cert is not a valid type';
throw new Error(errMsg); throw new Error(errMsg);
} }
let cert = fs.readFileSync(this.tlsServerCerts[certIndex]); let cert = this.tlsServerCerts[certIndex];
tlsOptionsCerts.push(cert); tlsOptionsCerts.push(cert);
} }
tlsOptions.ca = tlsOptionsCerts; tlsOptions.ca = tlsOptionsCerts;

View File

@ -190,7 +190,7 @@ describe('LEEF Class Tests', () => {
let syslog = new SyslogPro.Syslog({ let syslog = new SyslogPro.Syslog({
port: global.tlsBasicServerPort+100, port: global.tlsBasicServerPort+100,
protocol: 'tls', protocol: 'tls',
tlsServerCerts: ['./tests/jest_test_server_cert.pem'] tlsServerCerts: [fs.readFileSync('./tests/jest_test_server_cert.pem')]
}); });
let leef = new SyslogPro.LEEF({ let leef = new SyslogPro.LEEF({
vendor: 'test', vendor: 'test',
@ -219,9 +219,9 @@ describe('LEEF Class Tests', () => {
let syslogOptions = { let syslogOptions = {
port: global.tlsAuthServerPort, port: global.tlsAuthServerPort,
protocol: 'tls', protocol: 'tls',
tlsServerCerts: ['./tests/jest_test_server_cert.pem'], tlsServerCerts: [fs.readFileSync('./tests/jest_test_server_cert.pem')],
tlsClientCert: './tests/jest_test_client_cert.pem', tlsClientCert: fs.readFileSync('./tests/jest_test_client_cert.pem'),
tlsClientKey: './tests/jest_test_client_key.pem', tlsClientKey: fs.readFileSync('./tests/jest_test_client_key.pem'),
}; };
let leef = new SyslogPro.LEEF({ let leef = new SyslogPro.LEEF({
server: syslogOptions server: syslogOptions
@ -778,7 +778,7 @@ describe('Base Syslog Class tests', () => {
let syslog = new SyslogPro.Syslog({ let syslog = new SyslogPro.Syslog({
protocol: 'tls', protocol: 'tls',
port: global.tlsBasicServerPort, port: global.tlsBasicServerPort,
tlsServerCerts: ['./tests/jest_test_server_cert.pem'], tlsServerCerts: [fs.readFileSync('./tests/jest_test_server_cert.pem')],
tcpTimeout: 1 tcpTimeout: 1
}); });
expect.assertions(1); expect.assertions(1);
@ -789,7 +789,7 @@ describe('Base Syslog Class tests', () => {
expect(reason.message).toBe(errorMsg); expect(reason.message).toBe(errorMsg);
} }
}); });
test('Syslog Send TLS with server cert location type Error', async () => { test('Syslog Send TLS with server cert type Error', async () => {
let syslog = new SyslogPro.Syslog({ let syslog = new SyslogPro.Syslog({
protocol: 'tls', protocol: 'tls',
port: global.tlsBasicServerPort, port: global.tlsBasicServerPort,
@ -800,35 +800,33 @@ describe('Base Syslog Class tests', () => {
try { try {
await syslog.send('test'); await syslog.send('test');
} catch(reason) { } catch(reason) {
let errorMsg = 'TYPE ERROR: TLS Server Cert is not a file'; let errorMsg = 'TYPE ERROR: TLS Server Cert is not a valid type';
errorMsg += 'location string';
expect(reason.message).toBe(errorMsg); expect(reason.message).toBe(errorMsg);
} }
}); });
test('Syslog Send TLS with client cert location type Error', async () => { test('Syslog Send TLS with client cert type Error', async () => {
let syslog = new SyslogPro.Syslog({ let syslog = new SyslogPro.Syslog({
protocol: 'tls', protocol: 'tls',
port: global.tlsBasicServerPort, port: global.tlsBasicServerPort,
tlsServerCerts: './tests/jest_test_server_cert.pem', tlsServerCerts: fs.readFileSync('./tests/jest_test_server_cert.pem'),
tlsClientCert: {}, tlsClientCert: {},
tlsClientKey: './tests/jest_test_client_key.pem', tlsClientKey: fs.readFileSync('./tests/jest_test_client_key.pem'),
tcpTimeout: 1 tcpTimeout: 1
}); });
expect.assertions(1); expect.assertions(1);
try { try {
await syslog.send('test'); await syslog.send('test');
} catch(reason) { } catch(reason) {
let errorMsg = 'TYPE ERROR: TLS Client Cert is not a file'; let errorMsg = 'TYPE ERROR: TLS Client Cert is not a valid type';
errorMsg += 'location string';
expect(reason.message).toBe(errorMsg); expect(reason.message).toBe(errorMsg);
} }
}); });
test('Syslog Send TLS with client key location type Error', async () => { test('Syslog Send TLS with client key type Error', async () => {
let syslog = new SyslogPro.Syslog({ let syslog = new SyslogPro.Syslog({
protocol: 'tls', protocol: 'tls',
port: global.tlsBasicServerPort, port: global.tlsBasicServerPort,
tlsServerCerts: ['./tests/jest_test_server_cert.pem'], tlsServerCerts: [fs.readFileSync('./tests/jest_test_server_cert.pem')],
tlsClientCert: './tests/jest_test_client_cert.pem', tlsClientCert: fs.readFileSync('./tests/jest_test_client_cert.pem'),
tlsClientKey: {}, tlsClientKey: {},
tcpTimeout: 1 tcpTimeout: 1
}); });
@ -836,8 +834,7 @@ describe('Base Syslog Class tests', () => {
try { try {
await syslog.send('test'); await syslog.send('test');
} catch(reason) { } catch(reason) {
let errorMsg = 'TYPE ERROR: TLS Client Key is not a file'; let errorMsg = 'TYPE ERROR: TLS Client Key is not a valid type';
errorMsg += 'location string';
expect(reason.message).toBe(errorMsg); expect(reason.message).toBe(errorMsg);
} }
}); });
@ -886,7 +883,7 @@ describe('Base Syslog Class tests', () => {
expect(reason.message).toBe(errorMsg); expect(reason.message).toBe(errorMsg);
} }
}); });
test('Syslog addTlsServerCerts server cert location type Error', () => { test('Syslog addTlsServerCerts server cert type Error', () => {
let syslog = new SyslogPro.Syslog({ let syslog = new SyslogPro.Syslog({
protocol: 'tls', protocol: 'tls',
port: global.tlsBasicServerPort, port: global.tlsBasicServerPort,
@ -896,8 +893,8 @@ describe('Base Syslog Class tests', () => {
try { try {
syslog.addTlsServerCerts(6); syslog.addTlsServerCerts(6);
} catch (reason) { } catch (reason) {
let errorMsg = 'TYPE ERROR: Server Cert file locations should be a'; let errorMsg = 'TYPE ERROR: Server Cert should be a';
errorMsg += ' string or array of strings'; errorMsg += ' Buffer/string or array of Buffers/strings';
expect(reason.message).toBe(errorMsg); expect(reason.message).toBe(errorMsg);
} }
}); });