1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-26 15:30:58 +01:00
phorge-phorge/support/aphlict/server/aphlict_server.js
Alex Vandiver 11f1c13915 Append the intermediate chain to the "cert" parameter in Aphlict
Summary:
Per the documentation[1], any intermediate chain is to be
appended to the "cert" parameter.  The "ca" parameter controls the
root CA used to authenticate the client certificate, if one is
provided, and is not used for intermediate certificate chains -- nor
has it ever been.  It is not clear how this could have worked in the
past[2].

[1] https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options
[2] D15709

Test Plan:
Before this diff, with node 4.2.6 from Ubuntu packages:
```
$ openssl s_client -connect phabricator.dropboxer.net:22280 -verify 5 -CApath /etc/ssl/certs/
verify depth is 5
CONNECTED(00000003)
depth=0 C = US, ST = California, L = San Francisco, O = "Dropbox, Inc", OU = Dropbox Ops, CN = phabricator.dropboxer.net
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Dropbox, Inc", OU = Dropbox Ops, CN = phabricator.dropboxer.net
verify error:num=27:certificate not trusted
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Dropbox, Inc", OU = Dropbox Ops, CN = phabricator.dropboxer.net
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=San Francisco/O=Dropbox, Inc/OU=Dropbox Ops/CN=phabricator.dropboxer.net
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
```

After:
```
$ openssl s_client -connect phabricator.dropboxer.net:22280 -verify 5 -CApath /etc/ssl/certs/
verify depth is 5
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
verify return:1
depth=0 C = US, ST = California, L = San Francisco, O = "Dropbox, Inc", OU = Dropbox Ops, CN = phabricator.dropboxer.net
verify return:1
---
Certificate chain
 0 s:/C=US/ST=California/L=San Francisco/O=Dropbox, Inc/OU=Dropbox Ops/CN=phabricator.dropboxer.net
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
 1 s:/C=US/ST=California/L=San Francisco/O=Dropbox, Inc/OU=Dropbox Ops/CN=phabricator.dropboxer.net
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
 2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
```

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, epriestley

Differential Revision: https://secure.phabricator.com/D18181
2018-06-26 19:34:28 +00:00

199 lines
4.4 KiB
JavaScript

'use strict';
var JX = require('./lib/javelin').JX;
var http = require('http');
var https = require('https');
var util = require('util');
var fs = require('fs');
function parse_command_line_arguments(argv) {
var args = {
test: false,
config: null
};
for (var ii = 2; ii < argv.length; ii++) {
var arg = argv[ii];
var matches = arg.match(/^--([^=]+)=(.*)$/);
if (!matches) {
throw new Error('Unknown argument "' + arg + '"!');
}
if (!(matches[1] in args)) {
throw new Error('Unknown argument "' + matches[1] + '"!');
}
args[matches[1]] = matches[2];
}
return args;
}
function parse_config(args) {
var data = fs.readFileSync(args.config);
return JSON.parse(data);
}
require('./lib/AphlictLog');
var debug = new JX.AphlictLog()
.addConsole(console);
var args = parse_command_line_arguments(process.argv);
var config = parse_config(args);
function set_exit_code(code) {
process.on('exit', function() {
process.exit(code);
});
}
process.on('uncaughtException', function(err) {
var context = null;
if (err.code == 'EACCES') {
context = util.format(
'Unable to open file ("%s"). Check that permissions are set ' +
'correctly.',
err.path);
}
var message = [
'\n<<< UNCAUGHT EXCEPTION! >>>',
];
if (context) {
message.push(context);
}
message.push(err.stack);
debug.log(message.join('\n\n'));
set_exit_code(1);
});
try {
require('ws');
} catch (ex) {
throw new Error(
'You need to install the Node.js "ws" module for websocket support. ' +
'See "Notifications User Guide: Setup and Configuration" in the ' +
'documentation for instructions. ' + ex.toString());
}
// NOTE: Require these only after checking for the "ws" module, since they
// depend on it.
require('./lib/AphlictAdminServer');
require('./lib/AphlictClientServer');
require('./lib/AphlictPeerList');
require('./lib/AphlictPeer');
var ii;
var logs = config.logs || [];
for (ii = 0; ii < logs.length; ii++) {
debug.addLog(logs[ii].path);
}
var servers = [];
for (ii = 0; ii < config.servers.length; ii++) {
var spec = config.servers[ii];
spec.listen = spec.listen || '0.0.0.0';
if (spec['ssl.key']) {
spec['ssl.key'] = fs.readFileSync(spec['ssl.key']);
}
if (spec['ssl.cert']){
spec['ssl.cert'] = fs.readFileSync(spec['ssl.cert']);
if (spec['ssl.chain']){
spec['ssl.cert'] += "\n" + fs.readFileSync(spec['ssl.chain']);
}
}
servers.push(spec);
}
// If we're just doing a configuration test, exit here before starting any
// servers.
if (args.test) {
debug.log('Configuration test OK.');
set_exit_code(0);
return;
}
debug.log('Starting servers (service PID %d).', process.pid);
for (ii = 0; ii < logs.length; ii++) {
debug.log('Logging to "%s".', logs[ii].path);
}
var aphlict_servers = [];
var aphlict_clients = [];
var aphlict_admins = [];
for (ii = 0; ii < servers.length; ii++) {
var server = servers[ii];
var is_client = (server.type == 'client');
var http_server;
if (server['ssl.key']) {
var https_config = {
key: server['ssl.key'],
cert: server['ssl.cert'],
};
http_server = https.createServer(https_config);
} else {
http_server = http.createServer();
}
var aphlict_server;
if (is_client) {
aphlict_server = new JX.AphlictClientServer(http_server);
} else {
aphlict_server = new JX.AphlictAdminServer(http_server);
}
aphlict_server.setLogger(debug);
aphlict_server.listen(server.port, server.listen);
debug.log(
'Started %s server (Port %d, %s).',
server.type,
server.port,
server['ssl.key'] ? 'With SSL' : 'No SSL');
aphlict_servers.push(aphlict_server);
if (is_client) {
aphlict_clients.push(aphlict_server);
} else {
aphlict_admins.push(aphlict_server);
}
}
var peer_list = new JX.AphlictPeerList();
debug.log(
'This server has fingerprint "%s".',
peer_list.getFingerprint());
var cluster = config.cluster || [];
for (ii = 0; ii < cluster.length; ii++) {
var peer = cluster[ii];
var peer_client = new JX.AphlictPeer()
.setHost(peer.host)
.setPort(peer.port)
.setProtocol(peer.protocol);
peer_list.addPeer(peer_client);
}
for (ii = 0; ii < aphlict_admins.length; ii++) {
var admin_server = aphlict_admins[ii];
admin_server.setClientServers(aphlict_clients);
admin_server.setPeerList(peer_list);
}
for (ii = 0; ii < aphlict_clients.length; ii++) {
var client_server = aphlict_clients[ii];
client_server.setAdminServers(aphlict_admins);
}