2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								#!/usr/bin/env node
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								( function  ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								'use strict' ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  pkg  =  require ( '../package.json' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  program  =  require ( 'commander' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  url  =  require ( 'url' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  stunneld  =  require ( '../wstunneld.js' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								function  collectProxies ( val ,  memo )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  vals  =  val . split ( /,/g ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  vals . map ( function  ( location )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // http:john.example.com:3000
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // http://john.example.com:3000
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var  parts  =  location . split ( ':' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( 1  ===  parts . length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      parts [ 1 ]  =  parts [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      parts [ 0 ]  =  'wss' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( 2  ===  parts . length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( /\./ . test ( parts [ 0 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parts [ 2 ]  =  parts [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parts [ 1 ]  =  parts [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        parts [ 0 ]  =  'wss' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      if  ( ! /\./ . test ( parts [ 1 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        throw  new  Error ( "bad --serve option Example: wss://tunnel.example.com:1337" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    parts [ 0 ]  =  parts [ 0 ] . toLowerCase ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parts [ 1 ]  =  parts [ 1 ] . toLowerCase ( ) . replace ( /(\/\/)?/ ,  '' )  ||  '*' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parts [ 2 ]  =  parseInt ( parts [ 2 ] ,  10 )  ||  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! parts [ 2 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      // TODO grab OS list of standard ports?
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      if  ( - 1  !==  [  'ws' ,  'http'  ] . indexOf ( parts [ 0 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //parts[2] = 80;
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								      else  if  ( - 1  !==  [  'wss' ,  'https'  ] . indexOf ( parts [ 0 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //parts[2] = 443;
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        throw  new  Error ( "port must be specified - ex: tls:*:1337" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      protocol :  parts [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  hostname :  parts [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ,  port :  parts [ 2 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) . forEach ( function  ( val )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    memo . push ( val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  memo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  collectPorts ( val ,  memo )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  memo  =  memo . concat ( val . split ( /,/g ) . filter ( Boolean ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  memo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								program  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . version ( pkg . version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //.command('jsurl <url>')
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . arguments ( '<url>' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . action ( function  ( url )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    program . url  =  url ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  . option ( '--serve <URL>' ,  'comma separated list of <proto>:<//><servername>:<port> to which matching incoming http and https should forward (reverse proxy). Ex: https://john.example.com,tls:*:1337' ,  collectProxies ,  [  ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . option ( '--ports <PORT>' ,  'comma separated list of ports on which to listen. Ex: 80,443,1337' ,  collectPorts ,  [  ] ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  . option ( '--secret <STRING>' ,  'the same secret used by stunneld (used for JWT authentication)' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . parse ( process . argv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								program . stunneld  =  program . stunneld  ||  'wss://pokemap.hellabit.com:3000' ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  jwt  =  require ( 'jsonwebtoken' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  domainsMap  =  { } ;  
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  tokenData  =  {  name :  null ,  domains :  null  } ;  
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								var  location  =  url . parse ( program . stunneld ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  ( ! location . protocol  ||  /\./ . test ( location . protocol ) )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  program . stunneld  =  'wss://'  +  program . stunneld ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  location  =  url . parse ( program . stunneld ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								program . stunneld  =  location . protocol  +  '//'  +  location . hostname  +  ( location . port  ?  ':'  +  location . port  :  '' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 23:52:37 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								program . serve . forEach ( function  ( proxy )  {  
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  domainsMap [ proxy . hostname ]  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								tokenData . domains  =  Object . keys ( domainsMap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								tokenData . name  =  tokenData . domains [ 0 ] ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								if  ( ! program . ports . length )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  program . ports  =  [  80 ,  443  ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								program . services  =  { } ;  
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								program . portsMap  =  { } ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								program . servernamesMap  =  { } ;  
						 
					
						
							
								
									
										
										
										
											2016-09-30 23:52:37 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								program . serve . forEach ( function  ( proxy )  {  
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  //program.services = { 'ssh': 22, 'http': 80, 'https': 443 };
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  program . servernamesMap [ proxy . hostname ]  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  program . services [ proxy . protocol ]  =  proxy . port ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  if  ( proxy . port )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    program . portsMap [ proxy . port ]  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								} ) ;  
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								program . servernames  =  Object . keys ( program . servernamesMap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								program . ports  =  program . ports . concat ( Object . keys ( program . portsMap ) ) ;  
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								program . token  =  program . token  ||  jwt . sign ( tokenData ,  program . secret  ||  'shhhhh' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								if  ( ! program . serve . length )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  throw  new  Error ( "must specify at least on server" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-09-30 23:52:37 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// TODO letsencrypt
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								program . tlsOptions  =  require ( 'localhost.daplie.com-certificates' ) . merge ( { } ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  ( ! program . secret )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // TODO randomly generate and store in file?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  console . warn ( "[SECURITY] using default --secret 'shhhhh'" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  program . secret  =  'shhhhh' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								//require('cluster-store').create().then(function (store) {
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //program.store = store;
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 23:52:37 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-01 02:39:20 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  stunneld . create ( program ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//});
  
						 
					
						
							
								
									
										
										
										
											2016-09-30 18:03:41 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ( ) ) ;