[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [flashproxy/master] migrate flashproxy-client to argparse
commit c323a11f3c4fbf9ed0fd9721d62410584524197b
Author: Ximin Luo <infinity0@xxxxxxx>
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 mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits