commit c323a11f3c4fbf9ed0fd9721d62410584524197b Author: Ximin Luo infinity0@gmx.com Date: Tue Nov 19 17:17:59 2013 +0000
migrate flashproxy-client to argparse --- flashproxy-client | 255 ++++++++++++++++++++++++----------------------------- 1 file changed, 115 insertions(+), 140 deletions(-)
diff --git a/flashproxy-client b/flashproxy-client index 09630b3..60068be 100755 --- a/flashproxy-client +++ b/flashproxy-client @@ -3,11 +3,11 @@ The flashproxy client transport plugin. """
+import argparse import BaseHTTPServer import array import base64 import cStringIO -import getopt import os import os.path import select @@ -69,70 +69,6 @@ class options(object): transport = DEFAULT_TRANSPORT safe_logging = True
-def usage(f = sys.stdout): - print >> f, """\ -Usage: %(progname)s --register [LOCAL][:PORT] [REMOTE][:PORT] -Wait for connections on a local and a remote port. When any pair of connections -exists, data is ferried between them until one side is closed. By default -LOCAL is localhost addresses on port %(local_port)d and REMOTE is all addresses -on port %(remote_port)d. - -The local connection acts as a SOCKS4a proxy, but the host and port in the SOCKS -request are ignored and the local connection is always linked to a remote -connection. - -By default, runs as a managed proxy: informs a parent Tor process of support for -the "flashproxy" or "websocket" pluggable transport. In managed mode, -the LOCAL port is chosen arbitrarily instead of defaulting to -%(local_port)d; however this can be overridden by including a LOCAL port -in the command. This is the way the program should be invoked in a torrc -ClientTransportPlugin "exec" line. Use the --external option to run as -an external proxy that does not interact with Tor. - -If any of the --register, --register-addr, or --register-methods options are -used, then your IP address will be sent to the facilitator so that proxies can -connect to you. You need to register in some way in order to get any service. -The --facilitator option allows controlling which facilitator is used; if -omitted, it uses a public default. - - -4 registration helpers use IPv4. - -6 registration helpers use IPv6. - --daemon daemonize (Unix only). - --external be an external proxy (don't interact with Tor using - environment variables and stdout). - -f, --facilitator=URL advertise willingness to receive connections to URL. - --facilitator-pubkey=FILENAME - encrypt registrations to the given PEM-formatted - public key (default built-in). - -h, --help show this help. - -l, --log FILENAME write log to FILENAME (default stdout). - --pidfile FILENAME write PID to FILENAME after daemonizing. - --port-forwarding attempt to forward REMOTE port. - --port-forwarding-helper=PROGRAM use the given PROGRAM to forward ports - (default "%(port_forwarding_helper)s"). Implies --port-forwarding. - --port-forwarding-external=PORT forward the external PORT to REMOTE on - the local host (default same as REMOTE). Implies - --port-forwarding. - -r, --register register with the facilitator. - --register-addr=ADDR register the given address (in case it differs from - REMOTE). Implies --register. - --register-methods=METHOD[,METHOD...] - register using the given comma-separated list of - methods. Implies --register. Possible methods are - appspot email http - Default is "%(reg_methods)s". - --transport=TRANSPORT register using the given transport - (default "%(transport)s"). - --unsafe-logging don't scrub IP addresses from logs.\ -""" % { - "progname": sys.argv[0], - "local_port": DEFAULT_LOCAL_PORT_EXTERNAL, - "remote_port": DEFAULT_REMOTE_PORT, - "reg_methods": ",".join(DEFAULT_REGISTER_METHODS), - "port_forwarding_helper": DEFAULT_PORT_FORWARDING_HELPER, - "transport": DEFAULT_TRANSPORT, -} - def safe_str(s): """Return "[scrubbed]" if options.safe_logging is true, and s otherwise.""" if options.safe_logging: @@ -1070,69 +1006,109 @@ def main(): global websocket_pending, socks_pending global unlinked_locals, unlinked_remotes
- register_addr_spec = None - register_methods = [] - - opts, args = getopt.gnu_getopt(sys.argv[1:], "46f:hl:r", [ - "daemon", - "external", - "facilitator=", - "facilitator-pubkey=", - "help", - "log=", - "pidfile=", - "register", - "register-addr=", - "register-methods=", - "port-forwarding", - "port-forwarding-helper=", - "port-forwarding-external=", - "transport=", - "unsafe-logging", - ]) - for o, a in opts: - if o == "-4": - options.address_family = socket.AF_INET - elif o == "-6": - options.address_family = socket.AF_INET6 - elif o == "--daemon": - options.daemonize = True - elif o == "--external": - options.managed = False - elif 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() - elif o == "-l" or o == "--log": - options.log_filename = a - elif o == "--pidfile": - options.pid_filename = a - elif o == "-r" or o == "--register": - options.register = True - elif o == "--register-addr": - if register_addr_spec is not None: - print >> sys.stderr, "%s: only one --register-addr is allowed." % sys.argv[0] - sys.exit(1) - options.register = True - register_addr_spec = a - elif o == "--register-methods": - options.register = True - register_methods.extend(a.split(",")) - elif o == "--port-forwarding": - options.port_forwarding = True - elif o == "--port-forwarding-helper": - options.port_forwarding = True - options.port_forwarding_helper = a - elif o == "--port-forwarding-external": - options.port_forwarding = True - options.port_forwarding_external = int(a) - elif o == "--transport": - options.transport = a - elif o == "--unsafe-logging": - options.safe_logging = False + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description="""\ +Wait for connections on a local and a remote port. When any pair of connections +exists, data is ferried between them until one side is closed. + +The local connection acts as a SOCKS4a proxy, but the host and port in the SOCKS +request are ignored and the local connection is always linked to a remote +connection. + +By default, runs as a managed proxy: informs a parent Tor process of support for +the "flashproxy" or "websocket" pluggable transport. In managed mode, the LOCAL +port is chosen arbitrarily instead of the default; this can be overridden by +including a LOCAL port in the command. This is the way the program should be +invoked in a torrc ClientTransportPlugin "exec" line. Use the --external option +to run as an external proxy that does not interact with Tor. + +If any of the --register, --register-addr, or --register-methods options are +used, then your IP address will be sent to the facilitator so that proxies can +connect to you. You need to register in some way in order to get any service. +The --facilitator option allows controlling which facilitator is used; if +omitted, it uses a public default.""", + epilog="""\ +The -4, -6, --unsafe-logging, --transport and --facilitator-pubkey options are +propagated to the child registration helpers. For backwards compatilibility, +the --facilitator option is also propagated to the http registration helper. +If you need to pass more options, use TODO #9976.""") + # common opts + parser.add_argument("-4", help="name lookups use only IPv4.", + action="store_const", const=socket.AF_INET, dest="address_family") + parser.add_argument("-6", help="name lookups use only IPv6.", + action="store_const", const=socket.AF_INET6, dest="address_family") + parser.add_argument("--unsafe-logging", help="don't scrub IP addresses and " + "other sensitive information from logs.", action="store_true") + parser.add_argument("--facilitator-pubkey", help="encrypt registrations to " + "the given PEM-formatted public key file (default built-in).", + metavar='FILENAME') + parser.add_argument("--transport", + help="register using the given transport, default %(default)s.", + default=DEFAULT_TRANSPORT) + parser.add_argument("-f", "--facilitator", metavar="URL", + help="register with the facilitator at this URL, default %(default)s. " + "This is passed to the http registration ONLY.") + # specific opts and args + parser.add_argument("--daemon", + help="daemonize (Unix only).", action="store_true") + parser.add_argument("--external", + help="be an external (non-managed) proxy - don't interact with Tor " + "using environment variables and stdout.", action="store_true") + parser.add_argument("-l", "--log", metavar="FILENAME", + help="write log to FILENAME (default stderr).") + parser.add_argument("--pidfile", metavar="FILENAME", + help="write PID to FILENAME after daemonizing.") + parser.add_argument("--port-forwarding", + help="attempt to forward REMOTE port.", action="store_true") + parser.add_argument("--port-forwarding-helper", metavar="PROGRAM", + help="use the given PROGRAM to forward ports, default %s. Implies " + "--port-forwarding." % DEFAULT_PORT_FORWARDING_HELPER) + parser.add_argument("--port-forwarding-external", metavar="PORT", + help="forward the external PORT to REMOTE on the local host, default " + "same as the REMOTE. Implies --port-forwarding.", type=int) + parser.add_argument("-r", "--register", + help="register with the facilitator.", action="store_true") + parser.add_argument("--register-addr", metavar="ADDR", + help="register the given address (in case it differs from REMOTE). " + "Implies --register.") + parser.add_argument("--register-methods", metavar="METHOD[,METHOD...]", + help="register using the given comma-separated list of methods. " + "Implies --register. Possible methods are appspot,email,http. Default " + "is %s." % ",".join(DEFAULT_REGISTER_METHODS), + type=lambda x: None if x is None else x.split(",") if x else []) + parser.add_argument("local_addr", metavar="LOCAL:PORT", + help="local addr+port to listen on, default all localhost addresses on " + "port %s. In managed mode, the port is chosen arbitrarily if not given." + % DEFAULT_LOCAL_PORT_EXTERNAL, default="", nargs="?") + parser.add_argument("remote_addr", metavar="REMOTE:PORT", + help="remote addr+port to listen on, default all addresses on port %s" + % DEFAULT_REMOTE_PORT, default="", nargs="?") + + ns = parser.parse_args(sys.argv[1:]) + options.address_family = ns.address_family or socket.AF_UNSPEC + if options.address_family != socket.AF_UNSPEC: + getaddrinfo = socket.getaddrinfo + def getaddrinfo_replacement(host, port, family, *args, **kwargs): + return getaddrinfo(host, port, options.address_family, *args, **kwargs) + socket.getaddrinfo = getaddrinfo_replacement + options.safe_logging = not ns.unsafe_logging + + options.managed = not ns.external + + # do registration if any of the register options were set + do_register = (ns.register or + ns.register_addr is not None or + ns.register_methods is not None) + + # do port forwarding if any of the port-forwarding options were set + do_port_forwarding = (ns.port_forwarding or + ns.port_forwarding_helper is not None or + ns.port_forwarding_external is not None) + + options.log_filename = ns.log + options.daemonize = ns.daemon + options.pid_filename = ns.pidfile
if options.log_filename: options.log_file = open(options.log_filename, "a") @@ -1152,18 +1128,8 @@ def main(): default_local_port = DEFAULT_LOCAL_PORT_EXTERNAL default_remote_port = DEFAULT_REMOTE_PORT
- if len(args) == 0: - local_addr = ("", default_local_port) - remote_addr = ("", default_remote_port) - elif len(args) == 1: - local_addr = parse_addr_spec(args[0], defhost="", defport=default_local_port) - remote_addr = ("", default_remote_port) - elif len(args) == 2: - local_addr = parse_addr_spec(args[0], defhost="", defport=default_local_port) - remote_addr = parse_addr_spec(args[1], defhost="", defport=default_remote_port) - else: - usage(sys.stderr) - sys.exit(1) + local_addr = parse_addr_spec(ns.local_addr, defhost="", defport=default_local_port) + remote_addr = parse_addr_spec(ns.remote_addr, defhost="", defport=default_remote_port)
if local_addr[0]: options.local_addrs.append(local_addr) @@ -1180,11 +1146,20 @@ def main(): if socket.has_ipv6: options.remote_addrs.append(("::", remote_addr[1]))
+ # Determine registration info if requested. + options.register = do_register + register_addr_spec = ns.register_addr + register_methods = ns.register_methods + if not register_methods: register_methods = DEFAULT_REGISTER_METHODS for method in register_methods: options.register_commands.append(build_register_command(method))
+ options.port_forwarding = do_port_forwarding + options.port_forwarding_helper = ns.port_forwarding_helper or DEFAULT_PORT_FORWARDING_HELPER + options.port_forwarding_external = ns.port_forwarding_external + # Remote sockets, accepting remote WebSocket connections from proxies. remote_listen = [] for addr in options.remote_addrs:
tor-commits@lists.torproject.org