| 
									
										
										
										
											2017-06-14 10:58:56 -06:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.create = function (deps, config) { | 
					
						
							|  |  |  |   if (!config.tunnelServer || !Array.isArray(config.tunnelServer.servernames) || !config.tunnelServer.secret) { | 
					
						
							|  |  |  |     return { | 
					
						
							| 
									
										
										
										
											2017-06-23 17:22:45 -06:00
										 |  |  |       isAdminDomain:  function () { return false; } | 
					
						
							|  |  |  |     , isClientDomain: function () { return false; } | 
					
						
							| 
									
										
										
										
											2017-06-14 10:58:56 -06:00
										 |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var tunnelOpts = Object.assign({}, config.tunnelServer); | 
					
						
							|  |  |  |   // This function should not be called because connections to the admin domains
 | 
					
						
							|  |  |  |   // should already be decrypted, and connections to non-client domains should never
 | 
					
						
							|  |  |  |   // be given to us in the first place.
 | 
					
						
							|  |  |  |   tunnelOpts.httpsTunnel = function (servername, conn) { | 
					
						
							|  |  |  |     console.error('tunnel server received encrypted connection to', servername); | 
					
						
							|  |  |  |     conn.end(); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   tunnelOpts.httpsInvalid = tunnelOpts.httpsTunnel; | 
					
						
							|  |  |  |   // This function should not be called because ACME challenges should be handled
 | 
					
						
							|  |  |  |   // before admin domain connections are given to us, and the only non-encrypted
 | 
					
						
							|  |  |  |   // client connections that should be given to us are ACME challenges.
 | 
					
						
							|  |  |  |   tunnelOpts.handleHttp = function (servername, conn) { | 
					
						
							|  |  |  |     console.error('tunnel server received un-encrypted connection to', servername); | 
					
						
							|  |  |  |     conn.end([ | 
					
						
							|  |  |  |       'HTTP/1.1 404 Not Found' | 
					
						
							|  |  |  |     , 'Date: ' + (new Date()).toUTCString() | 
					
						
							|  |  |  |     , 'Connection: close' | 
					
						
							|  |  |  |     , 'Content-Type: text/html' | 
					
						
							|  |  |  |     , 'Content-Length: 9' | 
					
						
							|  |  |  |     , '' | 
					
						
							|  |  |  |     , 'Not Found' | 
					
						
							|  |  |  |     ].join('\r\n')); | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  |   tunnelOpts.handleInsecureHttp = tunnelOpts.handleHttp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var tunnelServer = require('stunneld').create(tunnelOpts); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var httpServer = require('http').createServer(function (req, res) { | 
					
						
							|  |  |  |     // status code 426 = Upgrade Required
 | 
					
						
							|  |  |  |     res.statusCode = 426; | 
					
						
							|  |  |  |     res.setHeader('Content-Type', 'application/json'); | 
					
						
							|  |  |  |     res.end(JSON.stringify({error: { | 
					
						
							|  |  |  |       message: 'Only websockets accepted for tunnel server' | 
					
						
							|  |  |  |     }})); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  |   var wsServer = new (require('ws').Server)({ server: httpServer }); | 
					
						
							|  |  |  |   wsServer.on('connection', tunnelServer.ws); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     isAdminDomain: function (domain) { | 
					
						
							|  |  |  |       return config.tunnelServer.servernames.indexOf(domain) !== -1; | 
					
						
							| 
									
										
										
										
											2017-06-23 17:22:45 -06:00
										 |  |  |     } | 
					
						
							|  |  |  |   , handleAdminConn: function (conn) { | 
					
						
							| 
									
										
										
										
											2017-06-14 10:58:56 -06:00
										 |  |  |       httpServer.emit('connection', conn); | 
					
						
							| 
									
										
										
										
											2017-06-23 17:22:45 -06:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-06-14 10:58:56 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-23 17:22:45 -06:00
										 |  |  |   , isClientDomain: tunnelServer.isClientDomain | 
					
						
							|  |  |  |   , handleClientConn: tunnelServer.tcp | 
					
						
							| 
									
										
										
										
											2017-06-14 10:58:56 -06:00
										 |  |  |   }; | 
					
						
							|  |  |  | }; |