From d4f10b232a031004905fa1705829a2060764c407 Mon Sep 17 00:00:00 2001 From: Brian May Date: Sun, 15 Nov 2015 16:45:26 +1100 Subject: [PATCH] Restructure code * Make compatible with setuptools. * Load modules via ssh into separate modules, not the one name space. --- MANIFEST.in | 5 + README.md => README.rst | 125 ++++++------- VERSION.txt | 1 + run | 6 + setup.py | 51 +++++ src/Makefile | 10 - src/do | 175 ------------------ src/sshuttle | 12 -- {src/compat => sshuttle}/__init__.py | 0 src/main.py => sshuttle/__main__.py | 12 +- {src => sshuttle}/all.do | 0 {src => sshuttle}/assembler.py | 22 ++- {src => sshuttle}/clean.do | 0 {src => sshuttle}/client.py | 14 +- sshuttle/compat/__init__.py | 0 {src => sshuttle}/compat/ssubprocess.py | 0 {src => sshuttle}/default.8.do | 0 {src => sshuttle}/firewall.py | 2 +- {src => sshuttle}/helpers.py | 0 {src => sshuttle}/hostwatch.py | 8 +- {src => sshuttle}/options.py | 0 {src => sshuttle}/server.py | 16 +- {src => sshuttle}/ssh.py | 68 ++++--- {src => sshuttle}/sshuttle.md | 0 {src => sshuttle}/ssnet.py | 3 +- {src => sshuttle}/ssyslog.py | 0 {src => sshuttle}/stresstest.py | 0 {src => sshuttle}/ui-macos/.gitignore | 0 .../ui-macos/ChickenErrorTemplate.pdf | Bin .../ui-macos/ChickenIdleTemplate.pdf | Bin .../ui-macos/ChickenRunningTemplate.pdf | Bin {src => sshuttle}/ui-macos/Info.plist | 0 {src => sshuttle}/ui-macos/MainMenu.xib | 0 {src => sshuttle}/ui-macos/UserDefaults.plist | 0 {src => sshuttle}/ui-macos/all.do | 0 {src => sshuttle}/ui-macos/app.icns | Bin {src => sshuttle}/ui-macos/askpass.py | 0 {src => sshuttle}/ui-macos/bits/.gitignore | 0 {src => sshuttle}/ui-macos/bits/PkgInfo | 0 {src => sshuttle}/ui-macos/bits/runpython.c | 0 {src => sshuttle}/ui-macos/bits/runpython.do | 0 {src => sshuttle}/ui-macos/clean.do | 0 {src => sshuttle}/ui-macos/debug.app.do | 0 {src => sshuttle}/ui-macos/default.app.do | 0 .../ui-macos/default.app.tar.gz.do | 0 {src => sshuttle}/ui-macos/default.app.zip.do | 0 {src => sshuttle}/ui-macos/default.nib.do | 0 {src => sshuttle}/ui-macos/dist.do | 0 {src => sshuttle}/ui-macos/git-export.do | 0 {src => sshuttle}/ui-macos/main.py | 0 {src => sshuttle}/ui-macos/models.py | 0 {src => sshuttle}/ui-macos/my.py | 0 {src => sshuttle}/ui-macos/run.do | 0 {src => sshuttle}/ui-macos/sources.list.do | 0 {src => sshuttle}/ui-macos/sshuttle | 0 55 files changed, 214 insertions(+), 316 deletions(-) create mode 100644 MANIFEST.in rename README.md => README.rst (83%) create mode 100644 VERSION.txt create mode 100755 run create mode 100755 setup.py delete mode 100644 src/Makefile delete mode 100755 src/do delete mode 100755 src/sshuttle rename {src/compat => sshuttle}/__init__.py (100%) rename src/main.py => sshuttle/__main__.py (97%) rename {src => sshuttle}/all.do (100%) rename {src => sshuttle}/assembler.py (50%) rename {src => sshuttle}/clean.do (100%) rename {src => sshuttle}/client.py (98%) create mode 100644 sshuttle/compat/__init__.py rename {src => sshuttle}/compat/ssubprocess.py (100%) rename {src => sshuttle}/default.8.do (100%) rename {src => sshuttle}/firewall.py (99%) rename {src => sshuttle}/helpers.py (100%) rename {src => sshuttle}/hostwatch.py (97%) rename {src => sshuttle}/options.py (100%) rename {src => sshuttle}/server.py (96%) rename {src => sshuttle}/ssh.py (61%) rename {src => sshuttle}/sshuttle.md (100%) rename {src => sshuttle}/ssnet.py (99%) rename {src => sshuttle}/ssyslog.py (100%) rename {src => sshuttle}/stresstest.py (100%) rename {src => sshuttle}/ui-macos/.gitignore (100%) rename {src => sshuttle}/ui-macos/ChickenErrorTemplate.pdf (100%) rename {src => sshuttle}/ui-macos/ChickenIdleTemplate.pdf (100%) rename {src => sshuttle}/ui-macos/ChickenRunningTemplate.pdf (100%) rename {src => sshuttle}/ui-macos/Info.plist (100%) rename {src => sshuttle}/ui-macos/MainMenu.xib (100%) rename {src => sshuttle}/ui-macos/UserDefaults.plist (100%) rename {src => sshuttle}/ui-macos/all.do (100%) rename {src => sshuttle}/ui-macos/app.icns (100%) rename {src => sshuttle}/ui-macos/askpass.py (100%) rename {src => sshuttle}/ui-macos/bits/.gitignore (100%) rename {src => sshuttle}/ui-macos/bits/PkgInfo (100%) rename {src => sshuttle}/ui-macos/bits/runpython.c (100%) rename {src => sshuttle}/ui-macos/bits/runpython.do (100%) rename {src => sshuttle}/ui-macos/clean.do (100%) rename {src => sshuttle}/ui-macos/debug.app.do (100%) rename {src => sshuttle}/ui-macos/default.app.do (100%) rename {src => sshuttle}/ui-macos/default.app.tar.gz.do (100%) rename {src => sshuttle}/ui-macos/default.app.zip.do (100%) rename {src => sshuttle}/ui-macos/default.nib.do (100%) rename {src => sshuttle}/ui-macos/dist.do (100%) rename {src => sshuttle}/ui-macos/git-export.do (100%) rename {src => sshuttle}/ui-macos/main.py (100%) rename {src => sshuttle}/ui-macos/models.py (100%) rename {src => sshuttle}/ui-macos/my.py (100%) rename {src => sshuttle}/ui-macos/run.do (100%) rename {src => sshuttle}/ui-macos/sources.list.do (100%) rename {src => sshuttle}/ui-macos/sshuttle (100%) diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..cb65042 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,5 @@ +include *.txt +include *.rst +include *.py +include MANIFEST.in +recursive-include sshuttle *.py diff --git a/README.md b/README.rst similarity index 83% rename from README.md rename to README.rst index e621477..bd9d48f 100644 --- a/README.md +++ b/README.rst @@ -1,28 +1,3 @@ - -WARNING: -On MacOS 10.6 (at least up to 10.6.6), your network will -stop responding about 10 minutes after the first time you -start sshuttle, because of a MacOS kernel bug relating to -arp and the net.inet.ip.scopedroute sysctl. To fix it, -just switch your wireless off and on. Sshuttle makes the -kernel setting it changes permanent, so this won't happen -again, even after a reboot. - -Required Software -================= - - - You need PyXAPI, available here: - http://www.pps.univ-paris-diderot.fr/~ylg/PyXAPI/ - - Python 2.x, both locally and the remote system - - -Additional Suggested Software ------------------------------ - - - You may want to need autossh, available in various package management - systems - - sshuttle: where transparent proxy meets VPN meets ssh ===================================================== @@ -45,63 +20,82 @@ common case: - You hate openssh's port forwarding because it's randomly slow and/or stupid. - + - You can't use openssh's PermitTunnel feature because it's disabled by default on openssh servers; plus it does TCP-over-TCP, which has terrible performance (see below). - + Prerequisites ------------- - sudo, su, or logged in as root on your client machine. (The server doesn't need admin access.) - + - If you use Linux on your client machine: iptables installed on the client, including at least the iptables DNAT, REDIRECT, and ttl modules. These are installed by default on most Linux distributions. (The server doesn't need iptables and doesn't need to be Linux.) - + - If you use MacOS or BSD on your client machine: Your kernel needs to be compiled with `IPFIREWALL_FORWARD` (MacOS has this by default) and you need to have ipfw available. (The server doesn't need to be MacOS or BSD.) + - Python 2.x, both locally and the remote system. Python 3.x is not yet supported. + +*WARNING*: +On MacOS 10.6 (at least up to 10.6.6), your network will +stop responding about 10 minutes after the first time you +start sshuttle, because of a MacOS kernel bug relating to +arp and the net.inet.ip.scopedroute sysctl. To fix it, +just switch your wireless off and on. Sshuttle makes the +kernel setting it changes permanent, so this won't happen +again, even after a reboot. + + +Additional Suggested Software +----------------------------- + + - You may want to need autossh, available in various package management + systems + + - For Linux only tproxy support, you need PyXAPI, available here: + http://www.pps.univ-paris-diderot.fr/~ylg/PyXAPI/ + + Obtaining sshuttle ------------------ - - First, go get PyXAPI from the link above + - Clone:: - - Clone: `git clone https://github.com/sshuttle/sshuttle.git` + git clone https://github.com/sshuttle/sshuttle.git + ./setup.py install + + - From PyPI:: + + pip install sshuttle -Usage on (Ubuntu) Linux ------------------------ +Usage +----- - - `cd packaging; ./make_deb` + - Forward all traffic:: - - `sudo dpkg -i ./sshuttle-VERSION.deb` - - - Check out the files in `/etc/sshuttle`; configure them so your tunnel works - - - `sudo service sshuttle start` - - -Usage on other Linuxes and OSes -------------------------------- - - src/sshuttle -r username@sshserver 0.0.0.0/0 -vv + sshuttle -r username@sshserver 0.0.0.0/0 -vv - There is a shortcut for 0.0.0.0/0 for those that value - their wrists - src/sshuttle -r username@sshserver 0/0 -vv + their wrists:: + + sshuttle -r username@sshserver 0/0 -vv - If you would also like your DNS queries to be proxied - through the DNS server of the server you are connect to: - src/sshuttle --dns -vvr username@sshserver 0/0 + through the DNS server of the server you are connect to:: + + sshuttle --dns -vvr username@sshserver 0/0 The above is probably what you want to use to prevent local network attacks such as Firesheep and friends. @@ -112,6 +106,7 @@ then the remote ssh password. Or you might have sudo and ssh set up to not require passwords, in which case you won't be prompted at all.) + Usage Notes ----------- @@ -127,7 +122,7 @@ to the remote python interpreter. This creates a transparent proxy server on your local machine for all IP addresses that match 0.0.0.0/0. (You can use more specific IP addresses if you want; use any number of IP addresses or subnets to change which -addresses get proxied. Using 0.0.0.0/0 proxies everything, which is +addresses get proxied. Using 0.0.0.0/0 proxies *everything*, which is interesting if you don't trust the people on your local network.) Any TCP session you initiate to one of the proxied IP addresses will be @@ -139,6 +134,19 @@ Fun, right? A poor man's instant VPN, and you don't even have to have admin access on the server. +Support +------- + +Mailing list: + +* Subscribe by sending a message to +* List archives are at: http://groups.google.com/group/sshuttle + +Issue tracker and pull requests at github: + +* https://github.com/sshuttle/sshuttle + + Theory of Operation ------------------- @@ -155,8 +163,7 @@ doesn't care about individual connections; ie. it's "stateless" with respect to the traffic. sshuttle is the opposite of stateless; it tracks every single connection. -You could compare sshuttle to something like the old Slirp program, which was a +You could compare sshuttle to something like the old `Slirp `_ program, which was a userspace TCP/IP implementation that did something similar. But it operated on a packet-by-packet basis on the client side, reassembling the packets on the server side. That worked okay back in the "real live serial @@ -164,9 +171,9 @@ port" days, because serial ports had predictable latency and buffering. But you can't safely just forward TCP packets over a TCP session (like ssh), because TCP's performance depends fundamentally on packet loss; it -must experience packet loss in order to know when to slow down! At +*must* experience packet loss in order to know when to slow down! At the same time, the outer TCP session (ssh, in this case) is a reliable -transport, which means that what you forward through the tunnel never +transport, which means that what you forward through the tunnel *never* experiences packet loss. The ssh session itself experiences packet loss, of course, but TCP fixes it up and ssh (and thus you) never know the difference. But neither does your inner TCP session, and extremely screwy @@ -181,8 +188,7 @@ safe. Useless Trivia -------------- -Back in 1998 (12 years ago! Yikes!), I released the first version of Tunnel Vision, a +Back in 1998 (12 years ago! Yikes!), I released the first version of `Tunnel Vision `_, a semi-intelligent VPN client for Linux. Unfortunately, I made two big mistakes: I implemented the key exchange myself (oops), and I ended up doing TCP-over-TCP (double oops). The resulting program worked okay - and people @@ -197,8 +203,7 @@ tool we called "Double Vision"). I was still in university at the time. A couple years after that, one of my professors was working with some graduate students on the technology that -would eventually become Slipstream -Internet Acceleration. He asked me to do a contract for him to build an +would eventually become `Slipstream Internet Acceleration `_. He asked me to do a contract for him to build an initial prototype of a transparent proxy server for mobile networks. The idea was similar to sshuttle: if you reassemble and then disassemble the TCP packets, you can reduce latency and improve performance vs. just forwarding @@ -215,7 +220,3 @@ later. You're welcome. -- Avery Pennarun - -Mailing list: - Subscribe by sending a message to - List archives are at: http://groups.google.com/group/sshuttle diff --git a/VERSION.txt b/VERSION.txt new file mode 100644 index 0000000..b214dd9 --- /dev/null +++ b/VERSION.txt @@ -0,0 +1 @@ +0.72 diff --git a/run b/run new file mode 100755 index 0000000..7fd71d4 --- /dev/null +++ b/run @@ -0,0 +1,6 @@ +#!/bin/sh +if python2 -V 2>/dev/null; then + exec python2 -m "sshuttle" "$@" +else + exec python -m "sshuttle" "$@" +fi diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..f16dc3c --- /dev/null +++ b/setup.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python + +# Copyright 2012-2014 Brian May +# +# This file is part of python-tldap. +# +# python-tldap is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# python-tldap is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with python-tldap If not, see . + +from setuptools import setup, find_packages + +with open('VERSION.txt', 'r') as f: + version = f.readline().strip() + +setup( + name="sshuttle", + version=version, + url='https://github.com/sshuttle/sshuttle', + author='Brian May', + author_email='brian@linuxpenguins.xyz', + description='Transparent proxy server that works as a poor man\'s VPN.', + packages=find_packages(), + license="GPL2+", + long_description=open('README.rst').read(), + classifiers=[ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Intended Audience :: End Users/Desktop", + "License :: OSI Approved :: " + "GNU General Public License v2 or later (GPLv2+)", + "Operating System :: OS Independent", + "Programming Language :: Python :: 2.7", + "Topic :: System :: Networking", + ], + entry_points={ + 'console_scripts': [ + 'sshuttle = sshuttle.__main__', + ], + }, + keywords="ssh vpn", +) diff --git a/src/Makefile b/src/Makefile deleted file mode 100644 index c167744..0000000 --- a/src/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -all: - -Makefile: - @ - -%: FORCE - +./do $@ - -.PHONY: FORCE - diff --git a/src/do b/src/do deleted file mode 100755 index d84c442..0000000 --- a/src/do +++ /dev/null @@ -1,175 +0,0 @@ -#!/bin/sh -# -# A minimal alternative to djb redo that doesn't support incremental builds. -# For the full version, visit http://github.com/apenwarr/redo -# -# The author disclaims copyright to this source file and hereby places it in -# the public domain. (2010 12 14) -# - -# By default, no output coloring. -green="" -bold="" -plain="" - -if [ -n "$TERM" -a "$TERM" != "dumb" ] && tty <&2 >/dev/null 2>&1; then - green="$(printf '\033[32m')" - bold="$(printf '\033[1m')" - plain="$(printf '\033[m')" -fi - -_dirsplit() -{ - base=${1##*/} - dir=${1%$base} -} - -dirname() -( - _dirsplit "$1" - dir=${dir%/} - echo "${dir:-.}" -) - -_dirsplit "$0" -export REDO=$(cd "${dir:-.}" && echo "$PWD/$base") - -DO_TOP= -if [ -z "$DO_BUILT" ]; then - DO_TOP=1 - [ -n "$*" ] || set all # only toplevel redo has a default target - export DO_BUILT=$PWD/.do_built - : >>"$DO_BUILT" - echo "Removing previously built files..." >&2 - sort -u "$DO_BUILT" | tee "$DO_BUILT.new" | - while read f; do printf "%s\0%s.did\0" "$f" "$f"; done | - xargs -0 rm -f 2>/dev/null - mv "$DO_BUILT.new" "$DO_BUILT" - DO_PATH=$DO_BUILT.dir - export PATH=$DO_PATH:$PATH - rm -rf "$DO_PATH" - mkdir "$DO_PATH" - for d in redo redo-ifchange; do - ln -s "$REDO" "$DO_PATH/$d"; - done - [ -e /bin/true ] && TRUE=/bin/true || TRUE=/usr/bin/true - for d in redo-ifcreate redo-stamp redo-always; do - ln -s $TRUE "$DO_PATH/$d"; - done -fi - - -_find_dofile_pwd() -{ - dofile=default.$1.do - while :; do - dofile=default.${dofile#default.*.} - [ -e "$dofile" -o "$dofile" = default.do ] && break - done - ext=${dofile#default} - ext=${ext%.do} - base=${1%$ext} -} - - -_find_dofile() -{ - local prefix= - while :; do - _find_dofile_pwd "$1" - [ -e "$dofile" ] && break - [ "$PWD" = "/" ] && break - target=${PWD##*/}/$target - tmp=${PWD##*/}/$tmp - prefix=${PWD##*/}/$prefix - cd .. - done - base=$prefix$base -} - - -_run_dofile() -{ - export DO_DEPTH="$DO_DEPTH " - export REDO_TARGET=$PWD/$target - local line1 - set -e - read line1 <"$PWD/$dofile" - cmd=${line1#"#!/"} - if [ "$cmd" != "$line1" ]; then - /$cmd "$PWD/$dofile" "$@" >"$tmp.tmp2" - else - :; . "$PWD/$dofile" >"$tmp.tmp2" - fi -} - - -_do() -{ - local dir=$1 target=$2 tmp=$3 - if [ ! -e "$target" ] || [ -d "$target" -a ! -e "$target.did" ]; then - printf '%sdo %s%s%s%s\n' \ - "$green" "$DO_DEPTH" "$bold" "$dir$target" "$plain" >&2 - echo "$PWD/$target" >>"$DO_BUILT" - dofile=$target.do - base=$target - ext= - [ -e "$target.do" ] || _find_dofile "$target" - if [ ! -e "$dofile" ]; then - echo "do: $target: no .do file" >&2 - return 1 - fi - [ ! -e "$DO_BUILT" ] || [ ! -d "$(dirname "$target")" ] || - : >>"$target.did" - ( _run_dofile "$target" "$base" "$tmp.tmp" ) - rv=$? - if [ $rv != 0 ]; then - printf "do: %s%s\n" "$DO_DEPTH" \ - "$dir$target: got exit code $rv" >&2 - rm -f "$tmp.tmp" "$tmp.tmp2" - return $rv - fi - mv "$tmp.tmp" "$target" 2>/dev/null || - ! test -s "$tmp.tmp2" || - mv "$tmp.tmp2" "$target" 2>/dev/null - rm -f "$tmp.tmp2" - else - echo "do $DO_DEPTH$target exists." >&2 - fi -} - - -# Make corrections for directories that don't actually exist yet. -_dir_shovel() -{ - local dir base - xdir=$1 xbase=$2 xbasetmp=$2 - while [ ! -d "$xdir" -a -n "$xdir" ]; do - _dirsplit "${xdir%/}" - xbasetmp=${base}__$xbase - xdir=$dir xbase=$base/$xbase - echo "xbasetmp='$xbasetmp'" >&2 - done -} - - -redo() -{ - for i in "$@"; do - _dirsplit "$i" - _dir_shovel "$dir" "$base" - dir=$xdir base=$xbase basetmp=$xbasetmp - ( cd "$dir" && _do "$dir" "$base" "$basetmp" ) || return 1 - done -} - - -set -e -redo "$@" - -if [ -n "$DO_TOP" ]; then - echo "Removing stamp files..." >&2 - [ ! -e "$DO_BUILT" ] || - while read f; do printf "%s.did\0" "$f"; done <"$DO_BUILT" | - xargs -0 rm -f 2>/dev/null -fi diff --git a/src/sshuttle b/src/sshuttle deleted file mode 100755 index 2d234d5..0000000 --- a/src/sshuttle +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh -EXE=$0 -for i in 1 2 3 4 5 6 7 8 9 10; do - [ -L "$EXE" ] || break - EXE=$(readlink "$EXE") -done -DIR=$(dirname "$EXE") -if python2 -V 2>/dev/null; then - exec python2 "$DIR/main.py" python2 "$@" -else - exec python "$DIR/main.py" python "$@" -fi diff --git a/src/compat/__init__.py b/sshuttle/__init__.py similarity index 100% rename from src/compat/__init__.py rename to sshuttle/__init__.py diff --git a/src/main.py b/sshuttle/__main__.py similarity index 97% rename from src/main.py rename to sshuttle/__main__.py index b7d7f70..409e0d6 100644 --- a/src/main.py +++ b/sshuttle/__main__.py @@ -3,11 +3,11 @@ import re import socket import helpers import options -import client -import server -import firewall -import hostwatch -from helpers import family_ip_tuple, log, Fatal +import sshuttle.client as client +import sshuttle.server as server +import sshuttle.firewall as firewall +import sshuttle.hostwatch as hostwatch +from sshuttle.helpers import family_ip_tuple, log, Fatal # 1.2.3.4/5 or just 1.2.3.4 @@ -139,7 +139,7 @@ firewall (internal use only) hostwatch (internal use only) """ o = options.Options(optspec) -(opt, flags, extra) = o.parse(sys.argv[2:]) +(opt, flags, extra) = o.parse(sys.argv[1:]) if opt.daemon: opt.syslog = 1 diff --git a/src/all.do b/sshuttle/all.do similarity index 100% rename from src/all.do rename to sshuttle/all.do diff --git a/src/assembler.py b/sshuttle/assembler.py similarity index 50% rename from src/assembler.py rename to sshuttle/assembler.py index ec020b5..be5b957 100644 --- a/src/assembler.py +++ b/sshuttle/assembler.py @@ -1,8 +1,8 @@ import sys import zlib +import imp z = zlib.decompressobj() -mainmod = sys.modules[__name__] while 1: name = sys.stdin.readline().strip() if name: @@ -11,17 +11,23 @@ while 1: sys.stderr.write('server: assembling %r (%d bytes)\n' % (name, nbytes)) content = z.decompress(sys.stdin.read(nbytes)) - exec compile(content, name, "exec") - # FIXME: this crushes everything into a single module namespace, - # then makes each of the module names point at this one. Gross. - assert(name.endswith('.py')) - modname = name[:-3] - mainmod.__dict__[modname] = mainmod + module = imp.new_module(name) + parent, _, parent_name = name.rpartition(".") + if parent != "": + setattr(sys.modules[parent], parent_name, module) + + code = compile(content, name, "exec") + exec code in module.__dict__ + sys.modules[name] = module else: break -verbose = verbosity sys.stderr.flush() sys.stdout.flush() + +import sshuttle.helpers +sshuttle.helpers.verbose = verbosity + +from sshuttle.server import main main() diff --git a/src/clean.do b/sshuttle/clean.do similarity index 100% rename from src/clean.do rename to sshuttle/clean.do diff --git a/src/client.py b/sshuttle/client.py similarity index 98% rename from src/client.py rename to sshuttle/client.py index 575d437..a0f6573 100644 --- a/src/client.py +++ b/sshuttle/client.py @@ -3,15 +3,15 @@ import errno import re import signal import time -import compat.ssubprocess as ssubprocess +import sshuttle.compat.ssubprocess as ssubprocess import helpers import os -import ssnet -import ssh +import sshuttle.ssnet as ssnet +import sshuttle.ssh as ssh import ssyslog import sys -from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper -from helpers import log, debug1, debug2, debug3, Fatal, islocal, \ +from sshuttle.ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper +from sshuttle.helpers import log, debug1, debug2, debug3, Fatal, islocal, \ resolvconf_nameservers recvmsg = None @@ -282,7 +282,9 @@ class FirewallClient: self.auto_nets = [] self.subnets_include = subnets_include self.subnets_exclude = subnets_exclude - argvbase = ([sys.argv[1], sys.argv[0], sys.argv[1]] + + python_path = os.path.dirname(os.path.dirname(__file__)) + argvbase = (["PYTHONPATH=%s" % python_path] + + [sys.executable, sys.argv[0]] + ['-v'] * (helpers.verbose or 0) + ['--firewall', str(port_v6), str(port_v4), str(dnsport_v6), str(dnsport_v4), diff --git a/sshuttle/compat/__init__.py b/sshuttle/compat/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/compat/ssubprocess.py b/sshuttle/compat/ssubprocess.py similarity index 100% rename from src/compat/ssubprocess.py rename to sshuttle/compat/ssubprocess.py diff --git a/src/default.8.do b/sshuttle/default.8.do similarity index 100% rename from src/default.8.do rename to sshuttle/default.8.do diff --git a/src/firewall.py b/sshuttle/firewall.py similarity index 99% rename from src/firewall.py rename to sshuttle/firewall.py index 07ce437..1856a15 100644 --- a/src/firewall.py +++ b/sshuttle/firewall.py @@ -8,7 +8,7 @@ import ssyslog import sys import os import re -from helpers import log, debug1, debug3, islocal, Fatal, family_to_string, \ +from sshuttle.helpers import log, debug1, debug3, islocal, Fatal, family_to_string, \ resolvconf_nameservers from fcntl import ioctl from ctypes import c_char, c_uint8, c_uint16, c_uint32, Union, Structure, \ diff --git a/src/helpers.py b/sshuttle/helpers.py similarity index 100% rename from src/helpers.py rename to sshuttle/helpers.py diff --git a/src/hostwatch.py b/sshuttle/hostwatch.py similarity index 97% rename from src/hostwatch.py rename to sshuttle/hostwatch.py index b7b0bcd..1c49bf7 100644 --- a/src/hostwatch.py +++ b/sshuttle/hostwatch.py @@ -5,10 +5,10 @@ import select import errno import os import sys -if not globals().get('skip_imports'): - import compat.ssubprocess as ssubprocess - import helpers - from helpers import log, debug1, debug2, debug3 + +import sshuttle.compat.ssubprocess as ssubprocess +import sshuttle.helpers as helpers +from sshuttle.helpers import log, debug1, debug2, debug3 POLL_TIME = 60 * 15 NETSTAT_POLL_TIME = 30 diff --git a/src/options.py b/sshuttle/options.py similarity index 100% rename from src/options.py rename to sshuttle/options.py diff --git a/src/server.py b/sshuttle/server.py similarity index 96% rename from src/server.py rename to sshuttle/server.py index 6229fbf..7f7ad88 100644 --- a/src/server.py +++ b/sshuttle/server.py @@ -5,14 +5,14 @@ import traceback import time import sys import os -if not globals().get('skip_imports'): - import ssnet - import helpers - import hostwatch - import compat.ssubprocess as ssubprocess - from ssnet import Handler, Proxy, Mux, MuxWrapper - from helpers import log, debug1, debug2, debug3, Fatal, \ - resolvconf_random_nameserver + +import sshuttle.ssnet as ssnet +import sshuttle.helpers as helpers +import sshuttle.hostwatch as hostwatch +import sshuttle.compat.ssubprocess as ssubprocess +from sshuttle.ssnet import Handler, Proxy, Mux, MuxWrapper +from sshuttle.helpers import log, debug1, debug2, debug3, Fatal, \ + resolvconf_random_nameserver if not globals().get('latency_control'): diff --git a/src/ssh.py b/sshuttle/ssh.py similarity index 61% rename from src/ssh.py rename to sshuttle/ssh.py index 5ab3f2c..a0c1ad1 100644 --- a/src/ssh.py +++ b/sshuttle/ssh.py @@ -3,28 +3,51 @@ import os import re import socket import zlib -import compat.ssubprocess as ssubprocess -import helpers -from helpers import debug2 +import imp +import sshuttle.compat.ssubprocess as ssubprocess +import sshuttle.helpers as helpers +from sshuttle.helpers import debug2 def readfile(name): - basedir = os.path.dirname(os.path.abspath(sys.argv[0])) - path = [basedir] + sys.path - for d in path: - fullname = os.path.join(d, name) - if os.path.exists(fullname): - return open(fullname, 'rb').read() - raise Exception("can't find file %r in any of %r" % (name, path)) + tokens = name.split(".") + f = None + token = tokens[0] + token_name = [token] + token_str = ".".join(token_name) -def empackage(z, filename, data=None): - (path, basename) = os.path.split(filename) + try: + f, pathname, description = imp.find_module(token_str) + + for token in tokens[1:]: + module = imp.load_module(token_str, f, pathname, description) + if f is not None: + f.close() + + token_name.append(token) + token_str = ".".join(token_name) + + f, pathname, description = imp.find_module( + token, module.__path__) + + if f is not None: + contents = f.read() + else: + contents = "" + + finally: + if f is not None: + f.close() + + return contents + +def empackage(z, name, data=None): if not data: - data = readfile(filename) + data = readfile(name) content = z.compress(data) content += z.flush(zlib.Z_SYNC_FLUSH) - return '%s\n%d\n%s' % (basename, len(content), content) + return '%s\n%d\n%s' % (name, len(content), content) def connect(ssh_cmd, rhostport, python, stderr, options): @@ -52,19 +75,20 @@ def connect(ssh_cmd, rhostport, python, stderr, options): rhost = None z = zlib.compressobj(1) - content = readfile('assembler.py') + content = readfile('sshuttle.assembler') optdata = ''.join("%s=%r\n" % (k, v) for (k, v) in options.items()) - content2 = (empackage(z, 'cmdline_options.py', optdata) + - empackage(z, 'helpers.py') + - empackage(z, 'compat/ssubprocess.py') + - empackage(z, 'ssnet.py') + - empackage(z, 'hostwatch.py') + - empackage(z, 'server.py') + + content2 = (empackage(z, 'sshuttle') + + empackage(z, 'sshuttle.cmdline_options', optdata) + + empackage(z, 'sshuttle.helpers') + + empackage(z, 'sshuttle.compat') + + empackage(z, 'sshuttle.compat.ssubprocess') + + empackage(z, 'sshuttle.ssnet') + + empackage(z, 'sshuttle.hostwatch') + + empackage(z, 'sshuttle.server') + "\n") pyscript = r""" import sys; - skip_imports=1; verbosity=%d; exec compile(sys.stdin.read(%d), "assembler.py", "exec") """ % (helpers.verbose or 0, len(content)) diff --git a/src/sshuttle.md b/sshuttle/sshuttle.md similarity index 100% rename from src/sshuttle.md rename to sshuttle/sshuttle.md diff --git a/src/ssnet.py b/sshuttle/ssnet.py similarity index 99% rename from src/ssnet.py rename to sshuttle/ssnet.py index 89712fa..2781a24 100644 --- a/src/ssnet.py +++ b/sshuttle/ssnet.py @@ -3,8 +3,7 @@ import socket import errno import select import os -if not globals().get('skip_imports'): - from helpers import log, debug1, debug2, debug3, Fatal +from sshuttle.helpers import log, debug1, debug2, debug3, Fatal MAX_CHANNEL = 65535 diff --git a/src/ssyslog.py b/sshuttle/ssyslog.py similarity index 100% rename from src/ssyslog.py rename to sshuttle/ssyslog.py diff --git a/src/stresstest.py b/sshuttle/stresstest.py similarity index 100% rename from src/stresstest.py rename to sshuttle/stresstest.py diff --git a/src/ui-macos/.gitignore b/sshuttle/ui-macos/.gitignore similarity index 100% rename from src/ui-macos/.gitignore rename to sshuttle/ui-macos/.gitignore diff --git a/src/ui-macos/ChickenErrorTemplate.pdf b/sshuttle/ui-macos/ChickenErrorTemplate.pdf similarity index 100% rename from src/ui-macos/ChickenErrorTemplate.pdf rename to sshuttle/ui-macos/ChickenErrorTemplate.pdf diff --git a/src/ui-macos/ChickenIdleTemplate.pdf b/sshuttle/ui-macos/ChickenIdleTemplate.pdf similarity index 100% rename from src/ui-macos/ChickenIdleTemplate.pdf rename to sshuttle/ui-macos/ChickenIdleTemplate.pdf diff --git a/src/ui-macos/ChickenRunningTemplate.pdf b/sshuttle/ui-macos/ChickenRunningTemplate.pdf similarity index 100% rename from src/ui-macos/ChickenRunningTemplate.pdf rename to sshuttle/ui-macos/ChickenRunningTemplate.pdf diff --git a/src/ui-macos/Info.plist b/sshuttle/ui-macos/Info.plist similarity index 100% rename from src/ui-macos/Info.plist rename to sshuttle/ui-macos/Info.plist diff --git a/src/ui-macos/MainMenu.xib b/sshuttle/ui-macos/MainMenu.xib similarity index 100% rename from src/ui-macos/MainMenu.xib rename to sshuttle/ui-macos/MainMenu.xib diff --git a/src/ui-macos/UserDefaults.plist b/sshuttle/ui-macos/UserDefaults.plist similarity index 100% rename from src/ui-macos/UserDefaults.plist rename to sshuttle/ui-macos/UserDefaults.plist diff --git a/src/ui-macos/all.do b/sshuttle/ui-macos/all.do similarity index 100% rename from src/ui-macos/all.do rename to sshuttle/ui-macos/all.do diff --git a/src/ui-macos/app.icns b/sshuttle/ui-macos/app.icns similarity index 100% rename from src/ui-macos/app.icns rename to sshuttle/ui-macos/app.icns diff --git a/src/ui-macos/askpass.py b/sshuttle/ui-macos/askpass.py similarity index 100% rename from src/ui-macos/askpass.py rename to sshuttle/ui-macos/askpass.py diff --git a/src/ui-macos/bits/.gitignore b/sshuttle/ui-macos/bits/.gitignore similarity index 100% rename from src/ui-macos/bits/.gitignore rename to sshuttle/ui-macos/bits/.gitignore diff --git a/src/ui-macos/bits/PkgInfo b/sshuttle/ui-macos/bits/PkgInfo similarity index 100% rename from src/ui-macos/bits/PkgInfo rename to sshuttle/ui-macos/bits/PkgInfo diff --git a/src/ui-macos/bits/runpython.c b/sshuttle/ui-macos/bits/runpython.c similarity index 100% rename from src/ui-macos/bits/runpython.c rename to sshuttle/ui-macos/bits/runpython.c diff --git a/src/ui-macos/bits/runpython.do b/sshuttle/ui-macos/bits/runpython.do similarity index 100% rename from src/ui-macos/bits/runpython.do rename to sshuttle/ui-macos/bits/runpython.do diff --git a/src/ui-macos/clean.do b/sshuttle/ui-macos/clean.do similarity index 100% rename from src/ui-macos/clean.do rename to sshuttle/ui-macos/clean.do diff --git a/src/ui-macos/debug.app.do b/sshuttle/ui-macos/debug.app.do similarity index 100% rename from src/ui-macos/debug.app.do rename to sshuttle/ui-macos/debug.app.do diff --git a/src/ui-macos/default.app.do b/sshuttle/ui-macos/default.app.do similarity index 100% rename from src/ui-macos/default.app.do rename to sshuttle/ui-macos/default.app.do diff --git a/src/ui-macos/default.app.tar.gz.do b/sshuttle/ui-macos/default.app.tar.gz.do similarity index 100% rename from src/ui-macos/default.app.tar.gz.do rename to sshuttle/ui-macos/default.app.tar.gz.do diff --git a/src/ui-macos/default.app.zip.do b/sshuttle/ui-macos/default.app.zip.do similarity index 100% rename from src/ui-macos/default.app.zip.do rename to sshuttle/ui-macos/default.app.zip.do diff --git a/src/ui-macos/default.nib.do b/sshuttle/ui-macos/default.nib.do similarity index 100% rename from src/ui-macos/default.nib.do rename to sshuttle/ui-macos/default.nib.do diff --git a/src/ui-macos/dist.do b/sshuttle/ui-macos/dist.do similarity index 100% rename from src/ui-macos/dist.do rename to sshuttle/ui-macos/dist.do diff --git a/src/ui-macos/git-export.do b/sshuttle/ui-macos/git-export.do similarity index 100% rename from src/ui-macos/git-export.do rename to sshuttle/ui-macos/git-export.do diff --git a/src/ui-macos/main.py b/sshuttle/ui-macos/main.py similarity index 100% rename from src/ui-macos/main.py rename to sshuttle/ui-macos/main.py diff --git a/src/ui-macos/models.py b/sshuttle/ui-macos/models.py similarity index 100% rename from src/ui-macos/models.py rename to sshuttle/ui-macos/models.py diff --git a/src/ui-macos/my.py b/sshuttle/ui-macos/my.py similarity index 100% rename from src/ui-macos/my.py rename to sshuttle/ui-macos/my.py diff --git a/src/ui-macos/run.do b/sshuttle/ui-macos/run.do similarity index 100% rename from src/ui-macos/run.do rename to sshuttle/ui-macos/run.do diff --git a/src/ui-macos/sources.list.do b/sshuttle/ui-macos/sources.list.do similarity index 100% rename from src/ui-macos/sources.list.do rename to sshuttle/ui-macos/sources.list.do diff --git a/src/ui-macos/sshuttle b/sshuttle/ui-macos/sshuttle similarity index 100% rename from src/ui-macos/sshuttle rename to sshuttle/ui-macos/sshuttle