 07fc8f17cc
			
		
	
	07fc8f17cc
	
	
	
		
			
			Summary: Fixes T10806. Although browsers don't seem to care about this, it's more correct to support it, and the new test console uses normal `cURL` and does care. Test Plan: - Hit the error case for providing a chain but no key/cert. - Used `openssl s_client -connect localhost:22280` to connect to local Aphlict servers. - With SSL but no chain, saw `openssl` fail to verify the remote. - With SSL and a chain, saw `openssl` verify the identify of the remote. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10806 Differential Revision: https://secure.phabricator.com/D15709
		
			
				
	
	
		
			180 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			3.9 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');
 | |
| 
 | |
| 
 | |
| 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.chain'] = 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'],
 | |
|     };
 | |
| 
 | |
|     if (server['ssl.chain']) {
 | |
|       https_config.ca = server['ssl.chain'];
 | |
|     }
 | |
| 
 | |
|     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);
 | |
|   }
 | |
| }
 | |
| 
 | |
| for (ii = 0; ii < aphlict_admins.length; ii++) {
 | |
|   var admin_server = aphlict_admins[ii];
 | |
|   admin_server.setClientServers(aphlict_clients);
 | |
| }
 |