Starting to rename the project to Passageway

This commit is contained in:
R. Tyler Croy 2013-03-10 16:50:56 -07:00
parent e15cb9e96a
commit d29120136e
15 changed files with 104 additions and 198 deletions

20
.gitignore vendored
View File

@ -1,3 +1,17 @@
.idea
.idea/*
.idea/**/*
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp

4
Gemfile Normal file
View File

@ -0,0 +1,4 @@
source 'https://rubygems.org'
# Specify your gem's dependencies in passageway.gemspec
gemspec

22
LICENSE.txt Normal file
View File

@ -0,0 +1,22 @@
Copyright (c) 2013 R. Tyler Croy
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -1,6 +0,0 @@
Rakefile
lib/localtunnel.rb
lib/localtunnel/tunnel.rb
lib/localtunnel/net_ssh_gateway_patch.rb
bin/localtunnel
Manifest

29
README.md Normal file
View File

@ -0,0 +1,29 @@
# Passageway
TODO: Write a gem description
## Installation
Add this line to your application's Gemfile:
gem 'passageway'
And then execute:
$ bundle
Or install it yourself as:
$ gem install passageway
## Usage
TODO: Write usage instructions here
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

View File

@ -1,65 +0,0 @@
= localtunnel -- instant public tunnel to your local web server
== Install
To get the dependencies if you don't have them, type:
sudo apt-get install ruby ruby1.8-dev rubygems1.8 libopenssl-ruby
Now you can install localtunnel with RubyGems:
sudo gem install localtunnel
or to get the source:
git clone http://github.com/progrium/localtunnel.git
== Usage
localtunnel [options] <localport>
-k, --key FILE upload a public key for authentication
Localtunnel is a client to a free and open source reverse tunneling
service made specifically for web traffic. It's intended to be used to
temporarily expose local web servers to the greater Internet for
debugging, unit tests, demos, etc.
This is how you make your local port 8080 public:
$ localtunnel 8080
Port 8080 is now publicly accessible from http://8bv2.localtunnel.com ...
Using localtunnel is comparable to using SSH reverse/remote port
forwarding on a remote host that has GatewayPorts enabled, but without
all the configuration or the need of a host. The localtunnel command
works with a server component that is running on localtunnel.com,
which is provided as a free service.
If you have never run localtunnel before, you'll need to upload a public
key to authenticate. You do this once:
$ localtunnel -k ~/.ssh/id_rsa.pub 8080
After that, you shouldn't have to use -k again.
Localtunnel can be started before or after the local web server. It
tunnels through to the url given in that status message "publicly
accessible from..." for as long as the command is running. The tunnel
is closed if the command exits.
Localtunnel will search for the file .localtunnel_callback in the CWD.
If it exists, it will execute the file with one argument, the public
endpoint, when the tunnel is opened. This is useful for starting other
tools or processes that need the name of the endpoint.
== Contributors
andyl (andy@r210.com)
Charles Merriam (charles.merriam@gmail.com)
Hunter Gillane (hunter.gillane@gmail.com)
Michael Sofaer (msofaer@pivotallabs.com)
Jeff Lindsay (progrium@gmail.com)
== License
MIT

View File

@ -1,16 +1 @@
require 'rubygems'
require 'rake'
require 'echoe'
Echoe.new('localtunnel', '0.3.1') do |p|
p.description = "instant public tunnel to your local web server"
p.url = "http://github.com/progrium/localtunnel"
p.author = "Jeff Lindsay"
p.email = "jeff.lindsay@twilio.com"
p.rdoc_pattern = //
p.rdoc_options = []
p.ignore_pattern = ["tmp/*", "script/*"]
p.executable_pattern = ["bin/*"]
p.runtime_dependencies = ["json >=1.2.4", "net-ssh >=2.0.22", "net-ssh-gateway >=1.0.1"]
p.development_dependencies = []
end
require "bundler/gem_tasks"

View File

@ -1,2 +0,0 @@
$: << File.expand_path(File.dirname(__FILE__))
require 'localtunnel/tunnel'

5
lib/passageway.rb Normal file
View File

@ -0,0 +1,5 @@
require "passageway/version"
module Passageway
# Your code goes here...
end

View File

@ -0,0 +1,3 @@
module Passageway
VERSION = "0.0.1"
end

23
passageway.gemspec Normal file
View File

@ -0,0 +1,23 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'passageway/version'
Gem::Specification.new do |spec|
spec.name = "passageway"
spec.version = Passageway::VERSION
spec.authors = ["R. Tyler Croy"]
spec.email = ["tyler@monkeypox.org"]
spec.description = %q{TODO: Write a gem description}
spec.summary = %q{TODO: Write a gem summary}
spec.homepage = ""
spec.license = "MIT"
spec.files = `git ls-files`.split($/)
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ["lib"]
spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "rake"
end

106
server.py
View File

@ -1,106 +0,0 @@
try:
from twisted.internet import pollreactor
pollreactor.install()
except: pass
from twisted.internet import protocol, reactor, defer, task
from twisted.web import http, proxy, resource, server
from twisted.python import log
import sys, time
import urlparse
import socket
import simplejson
import re
SSH_USER = 'localtunnel'
AUTHORIZED_KEYS = '/home/localtunnel/.ssh/authorized_keys'
PORT_RANGE = [32000, 64000]
BANNER = "This localtunnel service is brought to you by Twilio."
SSH_OPTIONS = 'command="/bin/echo Shell access denied",no-agent-forwarding,no-pty,no-user-rc,no-X11-forwarding '
KEY_REGEX = re.compile(r'^ssh-(\w{3}) [^\n]+$')
def port_available(port):
try:
socket.create_connection(['127.0.0.1', port]).close()
return False
except socket.error:
return True
def baseN(num,b=32,numerals="23456789abcdefghijkmnpqrstuvwxyz"):
return ((num == 0) and "0" ) or (baseN(num // b, b).lstrip("0") + numerals[num % b])
class LocalTunnelReverseProxy(proxy.ReverseProxyResource):
isLeaf = True
def __init__(self, user, host='127.0.0.1'):
self.user = user
self.tunnels = {}
proxy.ReverseProxyResource.__init__(self, host, None, None)
def find_tunnel_name(self):
name = baseN(abs(hash(time.time())))[0:4]
if (name in self.tunnels and not port_available(self.tunnels[name])) or name == 'open':
time.sleep(0.1)
return self.find_tunnel_name()
return name
def find_tunnel_port(self):
port = PORT_RANGE[0]
start_time = time.time()
while not port_available(port):
if time.time()-start_time > 3:
raise Exception("No port available")
port += 1
if port >= PORT_RANGE[1]: port = PORT_RANGE[0]
return port
def garbage_collect(self):
for name in self.tunnels:
if port_available(self.tunnels[name]):
del self.tunnels[name]
def install_key(self, key):
if not KEY_REGEX.match(key.strip()):
return False
key = ''.join([SSH_OPTIONS, key.strip(), "\n"])
fr = open(AUTHORIZED_KEYS, 'r')
if not key in fr.readlines():
fa = open(AUTHORIZED_KEYS, 'a')
fa.write(key)
fa.close()
fr.close()
return True
def register_tunnel(self, superhost, key=None):
if key and not self.install_key(key): return simplejson.dumps(dict(error="Invalid key."))
name = self.find_tunnel_name()
port = self.find_tunnel_port()
self.tunnels[name] = port
return simplejson.dumps(
dict(through_port=port, user=self.user, host='%s.%s' % (name, superhost), banner=BANNER))
def render(self, request):
host = request.getHeader('host')
name, superhost = host.split('.', 1)
if host.startswith('open.'):
request.setHeader('Content-Type', 'application/json')
return self.register_tunnel(superhost, request.args.get('key', [None])[0])
else:
if not name in self.tunnels: return "Not found"
request.content.seek(0, 0)
clientFactory = self.proxyClientFactoryClass(
request.method, request.uri, request.clientproto,
request.getAllHeaders(), request.content.read(), request)
self.reactor.connectTCP(self.host, self.tunnels[name], clientFactory)
return server.NOT_DONE_YET
#if 'location' in request.responseHeaders and host in request.responseHeaders['location']:
# # Strip out the port they think they need
# p = re.compile(r'%s\:\d+' % host)
# location = p.sub(host, request.responseHeaders['location'])
# request.responseHeaders['location'] = location
log.startLogging(sys.stdout)
reactor.listenTCP(80, server.Site(LocalTunnelReverseProxy(SSH_USER)))
reactor.run()