2016-09-30 13:47:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								#!/usr/bin/env node
  
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								( function  ( )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								'use strict' ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  pkg  =  require ( '../package.json' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  program  =  require ( 'commander' ) ;  
						 
					
						
							
								
									
										
										
										
											2016-09-30 15:04:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  url  =  require ( 'url' ) ;  
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								var  stunnel  =  require ( '../wsclient.js' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 15:01:58 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  parseProxy ( location )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // http:john.example.com:3000
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  // http://john.example.com:3000
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  parts  =  location . split ( ':' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //var dual = false;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  ( /\./ . test ( parts [ 0 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //dual = true;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parts [ 2 ]  =  parts [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parts [ 1 ]  =  parts [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    parts [ 0 ]  =  'https' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  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?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( 'http'  ===  parts [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      parts [ 2 ]  =  80 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-05 23:27:57 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 15:01:58 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  if  ( 'https'  ===  parts [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      parts [ 2 ]  =  443 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 15:01:58 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      throw  new  Error ( "port must be specified - ex: tls:*:1337" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    protocol :  parts [ 0 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  hostname :  parts [ 1 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ,  port :  parts [ 2 ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 15:01:58 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								function  collectProxies ( val ,  memo )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  var  vals  =  val . split ( /,/g ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  vals . map ( parseProxy ) . forEach ( function  ( val )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 15:04:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    memo . push ( val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  memo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								program  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . version ( pkg . version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  //.command('jsurl <url>')
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . arguments ( '<url>' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . action ( function  ( url )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    program . url  =  url ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 15:04:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  . option ( '-k --insecure' ,  'Allow TLS connections to stunneld without valid certs (rejectUnauthorized: false)' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  . option ( '--locals <LINE>' ,  '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 ,  [  ] )  // --reverse-proxies
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . option ( '--stunneld <URL>' ,  'the domain (or ip address) at which you are running stunneld.js (the proxy)' )  // --proxy
 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 15:04:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  . option ( '--secret <STRING>' ,  'the same secret used by stunneld (used for JWT authentication)' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  . option ( '--token <STRING>' ,  'a pre-generated token for use with stunneld (instead of generating one with --secret)' ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								  . parse ( process . argv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 15:04:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								program . stunneld  =  program . stunneld  ||  'wss://pokemap.hellabit.com:3000' ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								var  jwt  =  require ( 'jsonwebtoken' ) ;  
						 
					
						
							
								
									
										
										
										
											2016-09-30 15:04:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								var  domainsMap  =  { } ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  tokenData  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  name :  null 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								,  domains :  null  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								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  :  '' ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								program . locals . forEach ( function  ( proxy )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  domainsMap [ proxy . hostname ]  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								tokenData . domains  =  Object . keys ( domainsMap ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								tokenData . name  =  tokenData . domains [ 0 ] ;  
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 15:04:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								program . token  =  program . token  ||  jwt . sign ( tokenData ,  program . secret  ||  'shhhhh' ) ;  
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-05 23:02:28 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								program . net  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  createConnection :  function  ( info ,  cb )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-05 23:10:16 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // data is the hello packet / first chunk
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-06 15:01:58 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // info = { data, servername, port, host, remoteFamily, remoteAddress, remotePort }
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-05 23:02:28 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    var  net  =  require ( 'net' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // socket = { write, push, end, events: [ 'readable', 'data', 'error', 'end' ] };
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    var  socket  =  net . createConnection ( {  port :  info . port ,  host :  info . host  } ,  cb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  socket ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2016-10-05 23:27:57 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								program . locals . forEach ( function  ( proxy )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  console . log ( '[local proxy]' ,  proxy . protocol  +  '://'  +  proxy . hostname  +  ':'  +  proxy . port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-30 12:33:38 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								stunnel . connect ( program ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ( ) ) ;