[tor-commits] [flashproxy/master] Prototype registration over App Engine
dcf at torproject.org
dcf at torproject.org
Sun May 19 16:11:39 UTC 2013
commit f6b09fc8418364f71d624cc1da3fa88a37b04ee1
Author: Arlo Breault <arlolra at gmail.com>
Date: Thu May 9 20:00:07 2013 -0700
Prototype registration over App Engine
See #8860 for details.
---
flashproxy-client | 4 +-
flashproxy-reg-appspot | 144 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 146 insertions(+), 2 deletions(-)
diff --git a/flashproxy-client b/flashproxy-client
index f2f2e26..7fc36fa 100755
--- a/flashproxy-client
+++ b/flashproxy-client
@@ -963,8 +963,8 @@ def build_register_command(method):
af = ["-4"]
elif options.address_family == socket.AF_INET6:
af = ["-6"]
- if method == "email":
- command = [os.path.join(script_dir, "flashproxy-reg-email")] + af
+ if method in ["email", "appspot"]:
+ command = [os.path.join(script_dir, "flashproxy-reg-" + method)] + af
if options.facilitator_pubkey_filename is not None:
command += ["--facilitator-pubkey", options.facilitator_pubkey_filename]
return command
diff --git a/flashproxy-reg-appspot b/flashproxy-reg-appspot
new file mode 100755
index 0000000..9b9b4c3
--- /dev/null
+++ b/flashproxy-reg-appspot
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+
+import base64
+import getopt
+import re
+import socket
+import sys
+import urlparse
+import urllib2
+
+from M2Crypto import RSA, BIO
+
+DEFAULT_REMOTE_PORT = 9000
+DEFAULT_FACILITATOR_URL = "https://fp-facilitator.org/"
+DEFAULT_FACILITATOR_PUBKEY_PEM = """\
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA44Mt8c599/4N2fgu6ppN
+oatPW1GOgZxxObljFtEy0OWM1eHB35OOn+Kn9MxNHTRxVWwCEi0HYxWNVs2qrXxV
+84LmWBz6A65d2qBlgltgLXusiXLrpwxVmJeO+GfmbF8ur0U9JSYxA20cGW/kujNg
+XYDGQxO1Gvxq2lHK2LQmBpkfKEE1DMFASmIvlHDQgDj3XBb5lYeOsHZmg16UrGAq
+1UH238hgJITPGLXBtwLtJkYbrATJvrEcmvI7QSm57SgYGpaB5ZdCbJL5bag5Pgt6
+M5SDDYYY4xxEPzokjFJfCQv+kcyAnzERNMQ9kR41ePTXG62bpngK5iWGeJ5XdkxG
+gwIDAQAB
+-----END PUBLIC KEY-----
+"""
+
+def get_facilitator_pubkey():
+ if options.facilitator_pubkey_filename is not None:
+ return RSA.load_pub_key(options.facilitator_pubkey_filename)
+ else:
+ return RSA.load_pub_key_bio(BIO.MemoryBuffer(DEFAULT_FACILITATOR_PUBKEY_PEM))
+
+def get_external_ip():
+ try:
+ f = urllib2.urlopen("https://agentgatech.appspot.com/")
+ except:
+ return None
+ ip = f.read()
+ f.close()
+ return ip
+
+class options(object):
+ facilitator_url = None
+ facilitator_pubkey_filename = None
+
+def usage(f = sys.stdout):
+ print >> f, """\
+Usage: %(progname)s REMOTE[:PORT]
+Print a URL, which, when retrieved, will cause the client address
+REMOTE[:PORT] to be registered with the flash proxy facilitator. The
+default PORT is %(port)d.
+
+ -f, --facilitator=URL register with the given facilitator
+ (by default "%(fac_url)s").
+ --facilitator-pubkey=FILENAME
+ encrypt registrations to the given PEM-formatted
+ public key (default built-in).
+ -h, --help show this help.\
+""" % {
+ "progname": sys.argv[0],
+ "fac_url": DEFAULT_FACILITATOR_URL,
+ "port": DEFAULT_REMOTE_PORT,
+}
+
+def parse_addr_spec(spec, defhost = None, defport = None):
+ host = None
+ port = None
+ af = 0
+ m = None
+ # IPv6 syntax.
+ if not m:
+ m = re.match(ur'^\[(.+)\]:(\d*)$', spec)
+ if m:
+ host, port = m.groups()
+ af = socket.AF_INET6
+ if not m:
+ m = re.match(ur'^\[(.+)\]$', spec)
+ if m:
+ host, = m.groups()
+ af = socket.AF_INET6
+ # IPv4/hostname/port-only syntax.
+ if not m:
+ try:
+ host, port = spec.split(":", 1)
+ except ValueError:
+ host = spec
+ if re.match(ur'^[\d.]+$', host):
+ af = socket.AF_INET
+ else:
+ af = 0
+ host = host or defhost
+ port = port or defport
+ if port is not None:
+ port = int(port)
+ return host, port
+
+def format_addr(addr):
+ host, port = addr
+ if not host:
+ return u":%d" % port
+ # Numeric IPv6 address?
+ try:
+ addrs = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM, socket.IPPROTO_TCP, socket.AI_NUMERICHOST)
+ af = addrs[0][0]
+ except socket.gaierror, e:
+ af = 0
+ if af == socket.AF_INET6:
+ result = u"[%s]" % host
+ else:
+ result = "%s" % host
+ if port is not None:
+ result += u":%d" % port
+ return result
+
+options.facilitator_url = DEFAULT_FACILITATOR_URL
+
+opt, args = getopt.gnu_getopt(sys.argv[1:], "f:h", ["facilitator=", "facilitator-pubkey=", "help"])
+for o, a in opt:
+ if o == "-f" or o == "--facilitator":
+ options.facilitator_url = a
+ elif o == "--facilitator-pubkey":
+ options.facilitator_pubkey_filename = a
+ elif o == "-h" or o == "--help":
+ usage()
+ sys.exit()
+
+if len(args) != 1:
+ usage(f=sys.stderr)
+ sys.exit(1)
+
+remote_addr = parse_addr_spec(args[0], defport=DEFAULT_REMOTE_PORT)
+if remote_addr[0] is None:
+ remote_addr = parse_addr_spec(get_external_ip(), defport=remote_addr[1])
+if remote_addr[0] is None:
+ print >> sys.stderr, "Could not determine external ip address."
+ sys.exit(1)
+
+reg_plain = (u"client=%s" % format_addr(remote_addr)).encode("utf-8")
+rsa = get_facilitator_pubkey()
+reg_crypt = rsa.public_encrypt(reg_plain, RSA.pkcs1_oaep_padding)
+reg = base64.urlsafe_b64encode(reg_crypt)
+
+url = urlparse.urljoin(options.facilitator_url, "reg/" + reg)
+urllib2.urlopen("https://g-proxy.appspot.com/" + urllib2.quote(url))
More information about the tor-commits
mailing list