summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian May <brian@linuxpenguins.xyz>2016-01-17 10:17:44 +1100
committerBrian May <brian@linuxpenguins.xyz>2016-01-17 10:21:21 +1100
commit7f0b5c698b6336f91c9587f2dc10e2439d0f73bd (patch)
treee718e284733246b8ee9e0b592e1effa002b0e90d
parentf59508f41b5543159a3ada57ffdb4bd11a805b54 (diff)
Fix installation from wheel
Fix the following error. Looks like we have to have a function to call for the entrypoint. $ pip install dist/sshuttle-0.76.dev8_ngf59508f-py2-none-any.whl Processing ./dist/sshuttle-0.76.dev8_ngf59508f-py2-none-any.whl Installing collected packages: sshuttle Exception: Traceback (most recent call last): File "/tmp/ddd/local/lib/python2.7/site-packages/pip/basecommand.py", line 211, in main status = self.run(options, args) File "/tmp/ddd/local/lib/python2.7/site-packages/pip/commands/install.py", line 311, in run root=options.root_path, File "/tmp/ddd/local/lib/python2.7/site-packages/pip/req/req_set.py", line 646, in install **kwargs File "/tmp/ddd/local/lib/python2.7/site-packages/pip/req/req_install.py", line 803, in install self.move_wheel_files(self.source_dir, root=root) File "/tmp/ddd/local/lib/python2.7/site-packages/pip/req/req_install.py", line 998, in move_wheel_files isolated=self.isolated, File "/tmp/ddd/local/lib/python2.7/site-packages/pip/wheel.py", line 479, in move_wheel_files maker.make_multiple(['%s = %s' % kv for kv in console.items()]) File "/tmp/ddd/local/lib/python2.7/site-packages/pip/_vendor/distlib/scripts.py", line 364, in make_multiple filenames.extend(self.make(specification, options)) File "/tmp/ddd/local/lib/python2.7/site-packages/pip/_vendor/distlib/scripts.py", line 353, in make self._make_script(entry, filenames, options=options) File "/tmp/ddd/local/lib/python2.7/site-packages/pip/_vendor/distlib/scripts.py", line 244, in _make_script script = self._get_script_text(entry).encode('utf-8') File "/tmp/ddd/local/lib/python2.7/site-packages/pip/wheel.py", line 396, in _get_script_text "import_name": entry.suffix.split(".")[0], AttributeError: 'NoneType' object has no attribute 'split'
-rwxr-xr-xsetup.py2
-rw-r--r--sshuttle/__main__.py240
-rw-r--r--sshuttle/cmdline.py240
3 files changed, 244 insertions, 238 deletions
diff --git a/setup.py b/setup.py
index f67dee8..58a889d 100755
--- a/setup.py
+++ b/setup.py
@@ -53,7 +53,7 @@ setup(
],
entry_points={
'console_scripts': [
- 'sshuttle = sshuttle.__main__',
+ 'sshuttle = sshuttle.cmdline:main',
],
},
tests_require=['pytest', 'mock'],
diff --git a/sshuttle/__main__.py b/sshuttle/__main__.py
index 19803d0..b4bd42f 100644
--- a/sshuttle/__main__.py
+++ b/sshuttle/__main__.py
@@ -1,238 +1,4 @@
+"""Coverage.py's main entry point."""
import sys
-import re
-import socket
-import sshuttle.helpers as helpers
-import sshuttle.options as options
-import sshuttle.client as client
-import sshuttle.firewall as firewall
-import sshuttle.hostwatch as hostwatch
-import sshuttle.ssyslog as ssyslog
-from sshuttle.helpers import family_ip_tuple, log, Fatal
-
-
-# 1.2.3.4/5 or just 1.2.3.4
-def parse_subnet4(s):
- m = re.match(r'(\d+)(?:\.(\d+)\.(\d+)\.(\d+))?(?:/(\d+))?$', s)
- if not m:
- raise Fatal('%r is not a valid IP subnet format' % s)
- (a, b, c, d, width) = m.groups()
- (a, b, c, d) = (int(a or 0), int(b or 0), int(c or 0), int(d or 0))
- if width is None:
- width = 32
- else:
- width = int(width)
- if a > 255 or b > 255 or c > 255 or d > 255:
- raise Fatal('%d.%d.%d.%d has numbers > 255' % (a, b, c, d))
- if width > 32:
- raise Fatal('*/%d is greater than the maximum of 32' % width)
- return(socket.AF_INET, '%d.%d.%d.%d' % (a, b, c, d), width)
-
-
-# 1:2::3/64 or just 1:2::3
-def parse_subnet6(s):
- m = re.match(r'(?:([a-fA-F\d:]+))?(?:/(\d+))?$', s)
- if not m:
- raise Fatal('%r is not a valid IP subnet format' % s)
- (net, width) = m.groups()
- if width is None:
- width = 128
- else:
- width = int(width)
- if width > 128:
- raise Fatal('*/%d is greater than the maximum of 128' % width)
- return(socket.AF_INET6, net, width)
-
-
-# Subnet file, supporting empty lines and hash-started comment lines
-def parse_subnet_file(s):
- try:
- handle = open(s, 'r')
- except OSError:
- raise Fatal('Unable to open subnet file: %s' % s)
-
- raw_config_lines = handle.readlines()
- config_lines = []
- for line_no, line in enumerate(raw_config_lines):
- line = line.strip()
- if len(line) == 0:
- continue
- if line[0] == '#':
- continue
- config_lines.append(line)
-
- return config_lines
-
-
-# list of:
-# 1.2.3.4/5 or just 1.2.3.4
-# 1:2::3/64 or just 1:2::3
-def parse_subnets(subnets_str):
- subnets = []
- for s in subnets_str:
- if ':' in s:
- subnet = parse_subnet6(s)
- else:
- subnet = parse_subnet4(s)
- subnets.append(subnet)
- return subnets
-
-
-# 1.2.3.4:567 or just 1.2.3.4 or just 567
-def parse_ipport4(s):
- s = str(s)
- m = re.match(r'(?:(\d+)\.(\d+)\.(\d+)\.(\d+))?(?::)?(?:(\d+))?$', s)
- if not m:
- raise Fatal('%r is not a valid IP:port format' % s)
- (a, b, c, d, port) = m.groups()
- (a, b, c, d, port) = (int(a or 0), int(b or 0), int(c or 0), int(d or 0),
- int(port or 0))
- if a > 255 or b > 255 or c > 255 or d > 255:
- raise Fatal('%d.%d.%d.%d has numbers > 255' % (a, b, c, d))
- if port > 65535:
- raise Fatal('*:%d is greater than the maximum of 65535' % port)
- if a is None:
- a = b = c = d = 0
- return ('%d.%d.%d.%d' % (a, b, c, d), port)
-
-
-# [1:2::3]:456 or [1:2::3] or 456
-def parse_ipport6(s):
- s = str(s)
- m = re.match(r'(?:\[([^]]*)])?(?::)?(?:(\d+))?$', s)
- if not m:
- raise Fatal('%s is not a valid IP:port format' % s)
- (ip, port) = m.groups()
- (ip, port) = (ip or '::', int(port or 0))
- return (ip, port)
-
-
-def parse_list(list):
- return re.split(r'[\s,]+', list.strip()) if list else []
-
-
-optspec = """
-sshuttle [-l [ip:]port] [-r [username@]sshserver[:port]] <subnets...>
-sshuttle --firewall <port> <subnets...>
-sshuttle --hostwatch
---
-l,listen= transproxy to this ip address and port number
-H,auto-hosts scan for remote hostnames and update local /etc/hosts
-N,auto-nets automatically determine subnets to route
-dns capture local DNS requests and forward to the remote DNS server
-ns-hosts= capture and forward remote DNS requests to the following servers
-method= auto, nat, tproxy or pf
-python= path to python interpreter on the remote server
-r,remote= ssh hostname (and optional username) of remote sshuttle server
-x,exclude= exclude this subnet (can be used more than once)
-X,exclude-from= exclude the subnets in a file (whitespace separated)
-v,verbose increase debug message verbosity
-V,version print the sshuttle version number and exit
-e,ssh-cmd= the command to use to connect to the remote [ssh]
-seed-hosts= with -H, use these hostnames for initial scan (comma-separated)
-no-latency-control sacrifice latency to improve bandwidth benchmarks
-wrap= restart counting channel numbers after this number (for testing)
-disable-ipv6 disables ipv6 support
-D,daemon run in the background as a daemon
-s,subnets= file where the subnets are stored, instead of on the command line
-syslog send log messages to syslog (default if you use --daemon)
-pidfile= pidfile name (only if using --daemon) [./sshuttle.pid]
-server (internal use only)
-firewall (internal use only)
-hostwatch (internal use only)
-"""
-o = options.Options(optspec)
-(opt, flags, extra) = o.parse(sys.argv[1:])
-
-if opt.version:
- from sshuttle.version import version
- print(version)
- exit(0)
-if opt.daemon:
- opt.syslog = 1
-if opt.wrap:
- import sshuttle.ssnet as ssnet
- ssnet.MAX_CHANNEL = int(opt.wrap)
-helpers.verbose = opt.verbose or 0
-
-try:
- if opt.firewall:
- if len(extra) != 0:
- o.fatal('exactly zero arguments expected')
- result = firewall.main(opt.method, opt.syslog)
- sys.exit(result)
- elif opt.hostwatch:
- sys.exit(hostwatch.hw_main(extra))
- else:
- if len(extra) < 1 and not opt.auto_nets and not opt.subnets:
- o.fatal('at least one subnet, subnet file, or -N expected')
- includes = extra
- excludes = ['127.0.0.0/8']
- for k, v in flags:
- if k in ('-x', '--exclude'):
- excludes.append(v)
- if k in ('-X', '--exclude-from'):
- excludes += open(v).read().split()
- remotename = opt.remote
- if remotename == '' or remotename == '-':
- remotename = None
- nslist = [family_ip_tuple(ns) for ns in parse_list(opt.ns_hosts)]
- if opt.seed_hosts and not opt.auto_hosts:
- o.fatal('--seed-hosts only works if you also use -H')
- if opt.seed_hosts:
- sh = re.split(r'[\s,]+', (opt.seed_hosts or "").strip())
- elif opt.auto_hosts:
- sh = []
- else:
- sh = None
- if opt.subnets:
- includes = parse_subnet_file(opt.subnets)
- if not opt.method:
- method_name = "auto"
- elif opt.method in ["auto", "nat", "tproxy", "pf"]:
- method_name = opt.method
- else:
- o.fatal("method_name %s not supported" % opt.method)
- if opt.listen:
- ipport_v6 = None
- ipport_v4 = None
- list = opt.listen.split(",")
- for ip in list:
- if '[' in ip and ']' in ip:
- ipport_v6 = parse_ipport6(ip)
- else:
- ipport_v4 = parse_ipport4(ip)
- else:
- # parse_ipport4('127.0.0.1:0')
- ipport_v4 = "auto"
- # parse_ipport6('[::1]:0')
- ipport_v6 = "auto" if not opt.disable_ipv6 else None
- if opt.syslog:
- ssyslog.start_syslog()
- ssyslog.stderr_to_syslog()
- return_code = client.main(ipport_v6, ipport_v4,
- opt.ssh_cmd,
- remotename,
- opt.python,
- opt.latency_control,
- opt.dns,
- nslist,
- method_name,
- sh,
- opt.auto_nets,
- parse_subnets(includes),
- parse_subnets(excludes),
- opt.daemon, opt.pidfile)
-
- if return_code == 0:
- log('Normal exit code, exiting...')
- else:
- log('Abnormal exit code detected, failing...' % return_code)
- sys.exit(return_code)
-
-except Fatal as e:
- log('fatal: %s\n' % e)
- sys.exit(99)
-except KeyboardInterrupt:
- log('\n')
- log('Keyboard interrupt: exiting.\n')
- sys.exit(1)
+from sshuttle.cmdline import main
+sys.exit(main())
diff --git a/sshuttle/cmdline.py b/sshuttle/cmdline.py
new file mode 100644
index 0000000..48c0fbe
--- /dev/null
+++ b/sshuttle/cmdline.py
@@ -0,0 +1,240 @@
+import sys
+import re
+import socket
+import sshuttle.helpers as helpers
+import sshuttle.options as options
+import sshuttle.client as client
+import sshuttle.firewall as firewall
+import sshuttle.hostwatch as hostwatch
+import sshuttle.ssyslog as ssyslog
+from sshuttle.helpers import family_ip_tuple, log, Fatal
+
+
+# 1.2.3.4/5 or just 1.2.3.4
+def parse_subnet4(s):
+ m = re.match(r'(\d+)(?:\.(\d+)\.(\d+)\.(\d+))?(?:/(\d+))?$', s)
+ if not m:
+ raise Fatal('%r is not a valid IP subnet format' % s)
+ (a, b, c, d, width) = m.groups()
+ (a, b, c, d) = (int(a or 0), int(b or 0), int(c or 0), int(d or 0))
+ if width is None:
+ width = 32
+ else:
+ width = int(width)
+ if a > 255 or b > 255 or c > 255 or d > 255:
+ raise Fatal('%d.%d.%d.%d has numbers > 255' % (a, b, c, d))
+ if width > 32:
+ raise Fatal('*/%d is greater than the maximum of 32' % width)
+ return(socket.AF_INET, '%d.%d.%d.%d' % (a, b, c, d), width)
+
+
+# 1:2::3/64 or just 1:2::3
+def parse_subnet6(s):
+ m = re.match(r'(?:([a-fA-F\d:]+))?(?:/(\d+))?$', s)
+ if not m:
+ raise Fatal('%r is not a valid IP subnet format' % s)
+ (net, width) = m.groups()
+ if width is None:
+ width = 128
+ else:
+ width = int(width)
+ if width > 128:
+ raise Fatal('*/%d is greater than the maximum of 128' % width)
+ return(socket.AF_INET6, net, width)
+
+
+# Subnet file, supporting empty lines and hash-started comment lines
+def parse_subnet_file(s):
+ try:
+ handle = open(s, 'r')
+ except OSError:
+ raise Fatal('Unable to open subnet file: %s' % s)
+
+ raw_config_lines = handle.readlines()
+ config_lines = []
+ for line_no, line in enumerate(raw_config_lines):
+ line = line.strip()
+ if len(line) == 0:
+ continue
+ if line[0] == '#':
+ continue
+ config_lines.append(line)
+
+ return config_lines
+
+
+# list of:
+# 1.2.3.4/5 or just 1.2.3.4
+# 1:2::3/64 or just 1:2::3
+def parse_subnets(subnets_str):
+ subnets = []
+ for s in subnets_str:
+ if ':' in s:
+ subnet = parse_subnet6(s)
+ else:
+ subnet = parse_subnet4(s)
+ subnets.append(subnet)
+ return subnets
+
+
+# 1.2.3.4:567 or just 1.2.3.4 or just 567
+def parse_ipport4(s):
+ s = str(s)
+ m = re.match(r'(?:(\d+)\.(\d+)\.(\d+)\.(\d+))?(?::)?(?:(\d+))?$', s)
+ if not m:
+ raise Fatal('%r is not a valid IP:port format' % s)
+ (a, b, c, d, port) = m.groups()
+ (a, b, c, d, port) = (int(a or 0), int(b or 0), int(c or 0), int(d or 0),
+ int(port or 0))
+ if a > 255 or b > 255 or c > 255 or d > 255:
+ raise Fatal('%d.%d.%d.%d has numbers > 255' % (a, b, c, d))
+ if port > 65535:
+ raise Fatal('*:%d is greater than the maximum of 65535' % port)
+ if a is None:
+ a = b = c = d = 0
+ return ('%d.%d.%d.%d' % (a, b, c, d), port)
+
+
+# [1:2::3]:456 or [1:2::3] or 456
+def parse_ipport6(s):
+ s = str(s)
+ m = re.match(r'(?:\[([^]]*)])?(?::)?(?:(\d+))?$', s)
+ if not m:
+ raise Fatal('%s is not a valid IP:port format' % s)
+ (ip, port) = m.groups()
+ (ip, port) = (ip or '::', int(port or 0))
+ return (ip, port)
+
+
+def parse_list(list):
+ return re.split(r'[\s,]+', list.strip()) if list else []
+
+
+optspec = """
+sshuttle [-l [ip:]port] [-r [username@]sshserver[:port]] <subnets...>
+sshuttle --firewall <port> <subnets...>
+sshuttle --hostwatch
+--
+l,listen= transproxy to this ip address and port number
+H,auto-hosts scan for remote hostnames and update local /etc/hosts
+N,auto-nets automatically determine subnets to route
+dns capture local DNS requests and forward to the remote DNS server
+ns-hosts= capture and forward remote DNS requests to the following servers
+method= auto, nat, tproxy or pf
+python= path to python interpreter on the remote server
+r,remote= ssh hostname (and optional username) of remote sshuttle server
+x,exclude= exclude this subnet (can be used more than once)
+X,exclude-from= exclude the subnets in a file (whitespace separated)
+v,verbose increase debug message verbosity
+V,version print the sshuttle version number and exit
+e,ssh-cmd= the command to use to connect to the remote [ssh]
+seed-hosts= with -H, use these hostnames for initial scan (comma-separated)
+no-latency-control sacrifice latency to improve bandwidth benchmarks
+wrap= restart counting channel numbers after this number (for testing)
+disable-ipv6 disables ipv6 support
+D,daemon run in the background as a daemon
+s,subnets= file where the subnets are stored, instead of on the command line
+syslog send log messages to syslog (default if you use --daemon)
+pidfile= pidfile name (only if using --daemon) [./sshuttle.pid]
+server (internal use only)
+firewall (internal use only)
+hostwatch (internal use only)
+"""
+
+
+def main():
+ o = options.Options(optspec)
+ (opt, flags, extra) = o.parse(sys.argv[1:])
+
+ if opt.version:
+ from sshuttle.version import version
+ print(version)
+ return 0
+ if opt.daemon:
+ opt.syslog = 1
+ if opt.wrap:
+ import sshuttle.ssnet as ssnet
+ ssnet.MAX_CHANNEL = int(opt.wrap)
+ helpers.verbose = opt.verbose or 0
+
+ try:
+ if opt.firewall:
+ if len(extra) != 0:
+ o.fatal('exactly zero arguments expected')
+ return firewall.main(opt.method, opt.syslog)
+ elif opt.hostwatch:
+ return hostwatch.hw_main(extra)
+ else:
+ if len(extra) < 1 and not opt.auto_nets and not opt.subnets:
+ o.fatal('at least one subnet, subnet file, or -N expected')
+ includes = extra
+ excludes = ['127.0.0.0/8']
+ for k, v in flags:
+ if k in ('-x', '--exclude'):
+ excludes.append(v)
+ if k in ('-X', '--exclude-from'):
+ excludes += open(v).read().split()
+ remotename = opt.remote
+ if remotename == '' or remotename == '-':
+ remotename = None
+ nslist = [family_ip_tuple(ns) for ns in parse_list(opt.ns_hosts)]
+ if opt.seed_hosts and not opt.auto_hosts:
+ o.fatal('--seed-hosts only works if you also use -H')
+ if opt.seed_hosts:
+ sh = re.split(r'[\s,]+', (opt.seed_hosts or "").strip())
+ elif opt.auto_hosts:
+ sh = []
+ else:
+ sh = None
+ if opt.subnets:
+ includes = parse_subnet_file(opt.subnets)
+ if not opt.method:
+ method_name = "auto"
+ elif opt.method in ["auto", "nat", "tproxy", "pf"]:
+ method_name = opt.method
+ else:
+ o.fatal("method_name %s not supported" % opt.method)
+ if opt.listen:
+ ipport_v6 = None
+ ipport_v4 = None
+ list = opt.listen.split(",")
+ for ip in list:
+ if '[' in ip and ']' in ip:
+ ipport_v6 = parse_ipport6(ip)
+ else:
+ ipport_v4 = parse_ipport4(ip)
+ else:
+ # parse_ipport4('127.0.0.1:0')
+ ipport_v4 = "auto"
+ # parse_ipport6('[::1]:0')
+ ipport_v6 = "auto" if not opt.disable_ipv6 else None
+ if opt.syslog:
+ ssyslog.start_syslog()
+ ssyslog.stderr_to_syslog()
+ return_code = client.main(ipport_v6, ipport_v4,
+ opt.ssh_cmd,
+ remotename,
+ opt.python,
+ opt.latency_control,
+ opt.dns,
+ nslist,
+ method_name,
+ sh,
+ opt.auto_nets,
+ parse_subnets(includes),
+ parse_subnets(excludes),
+ opt.daemon, opt.pidfile)
+
+ if return_code == 0:
+ log('Normal exit code, exiting...')
+ else:
+ log('Abnormal exit code detected, failing...' % return_code)
+ return return_code
+
+ except Fatal as e:
+ log('fatal: %s\n' % e)
+ return 99
+ except KeyboardInterrupt:
+ log('\n')
+ log('Keyboard interrupt: exiting.\n')
+ return 1