Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
sshuttle
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
pub
sshuttle
Commits
92b99442
Unverified
Commit
92b99442
authored
Nov 03, 2020
by
Brian May
Committed by
GitHub
Nov 03, 2020
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #551 from skuhl/which-fix
Improve consistency of PATH, environments, and which()
parents
b5aaeda2
709e5d15
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
128 additions
and
102 deletions
+128
-102
client.py
sshuttle/client.py
+11
-3
helpers.py
sshuttle/helpers.py
+73
-0
hostwatch.py
sshuttle/hostwatch.py
+4
-16
linux.py
sshuttle/linux.py
+4
-17
__init__.py
sshuttle/methods/__init__.py
+5
-14
ipfw.py
sshuttle/methods/ipfw.py
+6
-14
pf.py
sshuttle/methods/pf.py
+5
-9
server.py
sshuttle/server.py
+4
-26
ssh.py
sshuttle/ssh.py
+13
-1
test_methods_pf.py
tests/client/test_methods_pf.py
+3
-2
No files found.
sshuttle/client.py
View file @
92b99442
...
@@ -15,7 +15,7 @@ import sshuttle.ssyslog as ssyslog
...
@@ -15,7 +15,7 @@ import sshuttle.ssyslog as ssyslog
import
sshuttle.sdnotify
as
sdnotify
import
sshuttle.sdnotify
as
sdnotify
from
sshuttle.ssnet
import
SockWrapper
,
Handler
,
Proxy
,
Mux
,
MuxWrapper
from
sshuttle.ssnet
import
SockWrapper
,
Handler
,
Proxy
,
Mux
,
MuxWrapper
from
sshuttle.helpers
import
log
,
debug1
,
debug2
,
debug3
,
Fatal
,
islocal
,
\
from
sshuttle.helpers
import
log
,
debug1
,
debug2
,
debug3
,
Fatal
,
islocal
,
\
resolvconf_nameservers
resolvconf_nameservers
,
which
from
sshuttle.methods
import
get_method
,
Features
from
sshuttle.methods
import
get_method
,
Features
from
sshuttle
import
__version__
from
sshuttle
import
__version__
try
:
try
:
...
@@ -196,11 +196,19 @@ class FirewallClient:
...
@@ -196,11 +196,19 @@ class FirewallClient:
[
'--firewall'
])
[
'--firewall'
])
if
ssyslog
.
_p
:
if
ssyslog
.
_p
:
argvbase
+=
[
'--syslog'
]
argvbase
+=
[
'--syslog'
]
# Default to sudo unless on OpenBSD in which case use built in `doas`
# Determine how to prefix the command in order to elevate privileges.
if
platform
.
platform
()
.
startswith
(
'OpenBSD'
):
if
platform
.
platform
()
.
startswith
(
'OpenBSD'
):
elev_prefix
=
[
'doas'
]
elev_prefix
=
[
'doas'
]
# OpenBSD uses built in `doas`
else
:
else
:
elev_prefix
=
[
'sudo'
,
'-p'
,
'[local sudo] Password: '
]
elev_prefix
=
[
'sudo'
,
'-p'
,
'[local sudo] Password: '
]
# Look for binary and switch to absolute path if we can find
# it.
path
=
which
(
elev_prefix
[
0
])
if
path
:
elev_prefix
[
0
]
=
path
if
sudo_pythonpath
:
if
sudo_pythonpath
:
elev_prefix
+=
[
'/usr/bin/env'
,
elev_prefix
+=
[
'/usr/bin/env'
,
'PYTHONPATH=
%
s'
%
python_path
]
'PYTHONPATH=
%
s'
%
python_path
]
...
...
sshuttle/helpers.py
View file @
92b99442
import
sys
import
sys
import
socket
import
socket
import
errno
import
errno
import
os
logprefix
=
''
logprefix
=
''
verbose
=
0
verbose
=
0
...
@@ -99,3 +100,75 @@ def family_to_string(family):
...
@@ -99,3 +100,75 @@ def family_to_string(family):
return
"AF_INET"
return
"AF_INET"
else
:
else
:
return
str
(
family
)
return
str
(
family
)
def
get_env
():
"""An environment for sshuttle subprocesses. See get_path()."""
env
=
{
'PATH'
:
get_path
(),
'LC_ALL'
:
"C"
,
}
return
env
def
get_path
():
"""Returns a string of paths separated by os.pathsep.
Users might not have all of the programs sshuttle needs in their
PATH variable (i.e., some programs might be in /sbin). Use PATH
and a hardcoded set of paths to search through. This function is
used by our which() and get_env() functions. If which() and the
subprocess environments differ, programs that which() finds might
not be found at run time (or vice versa).
"""
path
=
[]
if
"PATH"
in
os
.
environ
:
path
+=
os
.
environ
[
"PATH"
]
.
split
(
os
.
pathsep
)
# Python default paths.
path
+=
os
.
defpath
.
split
(
os
.
pathsep
)
# /sbin, etc are not in os.defpath and may not be in PATH either.
# /bin/ and /usr/bin below are probably redundant.
path
+=
[
'/bin'
,
'/usr/bin'
,
'/sbin'
,
'/usr/sbin'
]
# Remove duplicates. Not strictly necessary.
path_dedup
=
[]
for
i
in
path
:
if
i
not
in
path_dedup
:
path_dedup
.
append
(
i
)
return
os
.
pathsep
.
join
(
path_dedup
)
if
sys
.
version_info
>=
(
3
,
3
):
from
shutil
import
which
as
_which
else
:
# Although sshuttle does not officially support older versions of
# Python, some still run the sshuttle server on remote machines
# with old versions of python.
def
_which
(
file
,
mode
=
os
.
F_OK
|
os
.
X_OK
,
path
=
None
):
if
path
is
not
None
:
search_paths
=
path
.
split
(
os
.
pathsep
)
elif
"PATH"
in
os
.
environ
:
search_paths
=
os
.
environ
[
"PATH"
]
.
split
(
os
.
pathsep
)
else
:
search_paths
=
os
.
defpath
.
split
(
os
.
pathsep
)
for
p
in
search_paths
:
filepath
=
os
.
path
.
join
(
p
,
file
)
if
os
.
path
.
exists
(
filepath
)
and
os
.
access
(
filepath
,
mode
):
return
filepath
return
None
def
which
(
file
,
mode
=
os
.
F_OK
|
os
.
X_OK
):
"""A wrapper around shutil.which() that searches a predictable set of
paths and is more verbose about what is happening. See get_path()
for more information.
"""
path
=
get_path
()
rv
=
_which
(
file
,
mode
,
path
)
if
rv
:
debug2
(
"which() found '
%
s' at
%
s
\n
"
%
(
file
,
rv
))
else
:
debug2
(
"which() could not find '
%
s' in
%
s
\n
"
%
(
file
,
path
))
return
rv
sshuttle/hostwatch.py
View file @
92b99442
...
@@ -9,7 +9,7 @@ import platform
...
@@ -9,7 +9,7 @@ import platform
import
subprocess
as
ssubprocess
import
subprocess
as
ssubprocess
import
sshuttle.helpers
as
helpers
import
sshuttle.helpers
as
helpers
from
sshuttle.helpers
import
log
,
debug1
,
debug2
,
debug3
from
sshuttle.helpers
import
log
,
debug1
,
debug2
,
debug3
,
get_env
POLL_TIME
=
60
*
15
POLL_TIME
=
60
*
15
NETSTAT_POLL_TIME
=
30
NETSTAT_POLL_TIME
=
30
...
@@ -125,14 +125,10 @@ def _check_dns(hostname):
...
@@ -125,14 +125,10 @@ def _check_dns(hostname):
def
_check_netstat
():
def
_check_netstat
():
debug2
(
' > netstat
\n
'
)
debug2
(
' > netstat
\n
'
)
env
=
{
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
argv
=
[
'netstat'
,
'-n'
]
argv
=
[
'netstat'
,
'-n'
]
try
:
try
:
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
stderr
=
null
,
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
stderr
=
null
,
env
=
env
)
env
=
get_env
()
)
content
=
p
.
stdout
.
read
()
.
decode
(
"ASCII"
)
content
=
p
.
stdout
.
read
()
.
decode
(
"ASCII"
)
p
.
wait
()
p
.
wait
()
except
OSError
:
except
OSError
:
...
@@ -151,14 +147,10 @@ def _check_smb(hostname):
...
@@ -151,14 +147,10 @@ def _check_smb(hostname):
if
not
_smb_ok
:
if
not
_smb_ok
:
return
return
debug2
(
' > smb:
%
s
\n
'
%
hostname
)
debug2
(
' > smb:
%
s
\n
'
%
hostname
)
env
=
{
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
argv
=
[
'smbclient'
,
'-U'
,
'
%
'
,
'-L'
,
hostname
]
argv
=
[
'smbclient'
,
'-U'
,
'
%
'
,
'-L'
,
hostname
]
try
:
try
:
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
stderr
=
null
,
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
stderr
=
null
,
env
=
env
)
env
=
get_env
()
)
lines
=
p
.
stdout
.
readlines
()
lines
=
p
.
stdout
.
readlines
()
p
.
wait
()
p
.
wait
()
except
OSError
:
except
OSError
:
...
@@ -214,14 +206,10 @@ def _check_nmb(hostname, is_workgroup, is_master):
...
@@ -214,14 +206,10 @@ def _check_nmb(hostname, is_workgroup, is_master):
if
not
_nmb_ok
:
if
not
_nmb_ok
:
return
return
debug2
(
' > n
%
d
%
d:
%
s
\n
'
%
(
is_workgroup
,
is_master
,
hostname
))
debug2
(
' > n
%
d
%
d:
%
s
\n
'
%
(
is_workgroup
,
is_master
,
hostname
))
env
=
{
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
argv
=
[
'nmblookup'
]
+
[
'-M'
]
*
is_master
+
[
'--'
,
hostname
]
argv
=
[
'nmblookup'
]
+
[
'-M'
]
*
is_master
+
[
'--'
,
hostname
]
try
:
try
:
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
stderr
=
null
,
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
stderr
=
null
,
env
=
env
)
env
=
get_
env
)
lines
=
p
.
stdout
.
readlines
()
lines
=
p
.
stdout
.
readlines
()
rv
=
p
.
wait
()
rv
=
p
.
wait
()
except
OSError
:
except
OSError
:
...
...
sshuttle/linux.py
View file @
92b99442
import
os
import
socket
import
socket
import
subprocess
as
ssubprocess
import
subprocess
as
ssubprocess
from
sshuttle.helpers
import
log
,
debug1
,
Fatal
,
family_to_string
from
sshuttle.helpers
import
log
,
debug1
,
Fatal
,
family_to_string
,
get_env
def
nonfatal
(
func
,
*
args
):
def
nonfatal
(
func
,
*
args
):
...
@@ -19,12 +18,8 @@ def ipt_chain_exists(family, table, name):
...
@@ -19,12 +18,8 @@ def ipt_chain_exists(family, table, name):
else
:
else
:
raise
Exception
(
'Unsupported family "
%
s"'
%
family_to_string
(
family
))
raise
Exception
(
'Unsupported family "
%
s"'
%
family_to_string
(
family
))
argv
=
[
cmd
,
'-t'
,
table
,
'-nL'
]
argv
=
[
cmd
,
'-t'
,
table
,
'-nL'
]
env
=
{
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
try
:
try
:
output
=
ssubprocess
.
check_output
(
argv
,
env
=
env
)
output
=
ssubprocess
.
check_output
(
argv
,
env
=
get_env
()
)
for
line
in
output
.
decode
(
'ASCII'
)
.
split
(
'
\n
'
):
for
line
in
output
.
decode
(
'ASCII'
)
.
split
(
'
\n
'
):
if
line
.
startswith
(
'Chain
%
s '
%
name
):
if
line
.
startswith
(
'Chain
%
s '
%
name
):
return
True
return
True
...
@@ -40,11 +35,7 @@ def ipt(family, table, *args):
...
@@ -40,11 +35,7 @@ def ipt(family, table, *args):
else
:
else
:
raise
Exception
(
'Unsupported family "
%
s"'
%
family_to_string
(
family
))
raise
Exception
(
'Unsupported family "
%
s"'
%
family_to_string
(
family
))
debug1
(
'
%
s
\n
'
%
' '
.
join
(
argv
))
debug1
(
'
%
s
\n
'
%
' '
.
join
(
argv
))
env
=
{
rv
=
ssubprocess
.
call
(
argv
,
env
=
get_env
())
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
rv
=
ssubprocess
.
call
(
argv
,
env
=
env
)
if
rv
:
if
rv
:
raise
Fatal
(
'fw:
%
r returned
%
d'
%
(
argv
,
rv
))
raise
Fatal
(
'fw:
%
r returned
%
d'
%
(
argv
,
rv
))
...
@@ -55,11 +46,7 @@ def nft(family, table, action, *args):
...
@@ -55,11 +46,7 @@ def nft(family, table, action, *args):
else
:
else
:
raise
Exception
(
'Unsupported family "
%
s"'
%
family_to_string
(
family
))
raise
Exception
(
'Unsupported family "
%
s"'
%
family_to_string
(
family
))
debug1
(
'
%
s
\n
'
%
' '
.
join
(
argv
))
debug1
(
'
%
s
\n
'
%
' '
.
join
(
argv
))
env
=
{
rv
=
ssubprocess
.
call
(
argv
,
env
=
get_env
())
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
rv
=
ssubprocess
.
call
(
argv
,
env
=
env
)
if
rv
:
if
rv
:
raise
Fatal
(
'fw:
%
r returned
%
d'
%
(
argv
,
rv
))
raise
Fatal
(
'fw:
%
r returned
%
d'
%
(
argv
,
rv
))
...
...
sshuttle/methods/__init__.py
View file @
92b99442
import
os
import
importlib
import
importlib
import
socket
import
socket
import
struct
import
struct
import
errno
import
errno
import
ipaddress
import
ipaddress
from
sshuttle.helpers
import
Fatal
,
debug3
from
sshuttle.helpers
import
Fatal
,
debug3
,
which
def
original_dst
(
sock
):
def
original_dst
(
sock
):
...
@@ -97,27 +96,19 @@ class BaseMethod(object):
...
@@ -97,27 +96,19 @@ class BaseMethod(object):
return
False
return
False
def
_program_exists
(
name
):
paths
=
(
os
.
getenv
(
'PATH'
)
or
os
.
defpath
)
.
split
(
os
.
pathsep
)
for
p
in
paths
:
fn
=
'
%
s/
%
s'
%
(
p
,
name
)
if
os
.
path
.
exists
(
fn
):
return
not
os
.
path
.
isdir
(
fn
)
and
os
.
access
(
fn
,
os
.
X_OK
)
def
get_method
(
method_name
):
def
get_method
(
method_name
):
module
=
importlib
.
import_module
(
"sshuttle.methods.
%
s"
%
method_name
)
module
=
importlib
.
import_module
(
"sshuttle.methods.
%
s"
%
method_name
)
return
module
.
Method
(
method_name
)
return
module
.
Method
(
method_name
)
def
get_auto_method
():
def
get_auto_method
():
if
_program_exists
(
'iptables'
):
if
which
(
'iptables'
):
method_name
=
"nat"
method_name
=
"nat"
elif
_program_exists
(
'nft'
):
elif
which
(
'nft'
):
method_name
=
"nft"
method_name
=
"nft"
elif
_program_exists
(
'pfctl'
):
elif
which
(
'pfctl'
):
method_name
=
"pf"
method_name
=
"pf"
elif
_program_exists
(
'ipfw'
):
elif
which
(
'ipfw'
):
method_name
=
"ipfw"
method_name
=
"ipfw"
else
:
else
:
raise
Fatal
(
raise
Fatal
(
...
...
sshuttle/methods/ipfw.py
View file @
92b99442
...
@@ -2,7 +2,7 @@ import os
...
@@ -2,7 +2,7 @@ import os
import
subprocess
as
ssubprocess
import
subprocess
as
ssubprocess
from
sshuttle.methods
import
BaseMethod
from
sshuttle.methods
import
BaseMethod
from
sshuttle.helpers
import
log
,
debug1
,
debug3
,
\
from
sshuttle.helpers
import
log
,
debug1
,
debug3
,
\
Fatal
,
family_to_string
Fatal
,
family_to_string
,
get_env
recvmsg
=
None
recvmsg
=
None
try
:
try
:
...
@@ -61,11 +61,7 @@ else:
...
@@ -61,11 +61,7 @@ else:
def
ipfw_rule_exists
(
n
):
def
ipfw_rule_exists
(
n
):
argv
=
[
'ipfw'
,
'list'
]
argv
=
[
'ipfw'
,
'list'
]
env
=
{
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
env
=
get_env
())
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
env
=
env
)
found
=
False
found
=
False
for
line
in
p
.
stdout
:
for
line
in
p
.
stdout
:
...
@@ -85,11 +81,7 @@ _oldctls = {}
...
@@ -85,11 +81,7 @@ _oldctls = {}
def
_fill_oldctls
(
prefix
):
def
_fill_oldctls
(
prefix
):
argv
=
[
'sysctl'
,
prefix
]
argv
=
[
'sysctl'
,
prefix
]
env
=
{
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
env
=
get_env
())
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
env
=
env
)
for
line
in
p
.
stdout
:
for
line
in
p
.
stdout
:
line
=
line
.
decode
()
line
=
line
.
decode
()
assert
(
line
[
-
1
]
==
'
\n
'
)
assert
(
line
[
-
1
]
==
'
\n
'
)
...
@@ -105,7 +97,7 @@ def _fill_oldctls(prefix):
...
@@ -105,7 +97,7 @@ def _fill_oldctls(prefix):
def
_sysctl_set
(
name
,
val
):
def
_sysctl_set
(
name
,
val
):
argv
=
[
'sysctl'
,
'-w'
,
'
%
s=
%
s'
%
(
name
,
val
)]
argv
=
[
'sysctl'
,
'-w'
,
'
%
s=
%
s'
%
(
name
,
val
)]
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
return
ssubprocess
.
call
(
argv
,
stdout
=
open
(
os
.
devnull
,
'w'
))
return
ssubprocess
.
call
(
argv
,
stdout
=
open
(
os
.
devnull
,
'w'
)
,
env
=
get_env
()
)
# No env: No output. (Or error that won't be parsed.)
# No env: No output. (Or error that won't be parsed.)
...
@@ -139,7 +131,7 @@ def sysctl_set(name, val, permanent=False):
...
@@ -139,7 +131,7 @@ def sysctl_set(name, val, permanent=False):
def
ipfw
(
*
args
):
def
ipfw
(
*
args
):
argv
=
[
'ipfw'
,
'-q'
]
+
list
(
args
)
argv
=
[
'ipfw'
,
'-q'
]
+
list
(
args
)
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
rv
=
ssubprocess
.
call
(
argv
)
rv
=
ssubprocess
.
call
(
argv
,
env
=
get_env
()
)
# No env: No output. (Or error that won't be parsed.)
# No env: No output. (Or error that won't be parsed.)
if
rv
:
if
rv
:
raise
Fatal
(
'
%
r returned
%
d'
%
(
argv
,
rv
))
raise
Fatal
(
'
%
r returned
%
d'
%
(
argv
,
rv
))
...
@@ -148,7 +140,7 @@ def ipfw(*args):
...
@@ -148,7 +140,7 @@ def ipfw(*args):
def
ipfw_noexit
(
*
args
):
def
ipfw_noexit
(
*
args
):
argv
=
[
'ipfw'
,
'-q'
]
+
list
(
args
)
argv
=
[
'ipfw'
,
'-q'
]
+
list
(
args
)
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
ssubprocess
.
call
(
argv
)
ssubprocess
.
call
(
argv
,
env
=
get_env
()
)
# No env: No output. (Or error that won't be parsed.)
# No env: No output. (Or error that won't be parsed.)
...
...
sshuttle/methods/pf.py
View file @
92b99442
...
@@ -11,7 +11,8 @@ from fcntl import ioctl
...
@@ -11,7 +11,8 @@ from fcntl import ioctl
from
ctypes
import
c_char
,
c_uint8
,
c_uint16
,
c_uint32
,
Union
,
Structure
,
\
from
ctypes
import
c_char
,
c_uint8
,
c_uint16
,
c_uint32
,
Union
,
Structure
,
\
sizeof
,
addressof
,
memmove
sizeof
,
addressof
,
memmove
from
sshuttle.firewall
import
subnet_weight
from
sshuttle.firewall
import
subnet_weight
from
sshuttle.helpers
import
debug1
,
debug2
,
debug3
,
Fatal
,
family_to_string
from
sshuttle.helpers
import
debug1
,
debug2
,
debug3
,
Fatal
,
family_to_string
,
\
get_env
from
sshuttle.methods
import
BaseMethod
from
sshuttle.methods
import
BaseMethod
...
@@ -179,7 +180,7 @@ class FreeBsd(Generic):
...
@@ -179,7 +180,7 @@ class FreeBsd(Generic):
return
freebsd
return
freebsd
def
enable
(
self
):
def
enable
(
self
):
returncode
=
ssubprocess
.
call
([
'kldload'
,
'pf'
])
returncode
=
ssubprocess
.
call
([
'kldload'
,
'pf'
]
,
env
=
get_env
()
)
# No env: No output.
# No env: No output.
super
(
FreeBsd
,
self
)
.
enable
()
super
(
FreeBsd
,
self
)
.
enable
()
if
returncode
==
0
:
if
returncode
==
0
:
...
@@ -189,7 +190,7 @@ class FreeBsd(Generic):
...
@@ -189,7 +190,7 @@ class FreeBsd(Generic):
super
(
FreeBsd
,
self
)
.
disable
(
anchor
)
super
(
FreeBsd
,
self
)
.
disable
(
anchor
)
if
_pf_context
[
'loaded_by_sshuttle'
]
and
\
if
_pf_context
[
'loaded_by_sshuttle'
]
and
\
_pf_context
[
'started_by_sshuttle'
]
==
0
:
_pf_context
[
'started_by_sshuttle'
]
==
0
:
ssubprocess
.
call
([
'kldunload'
,
'pf'
])
ssubprocess
.
call
([
'kldunload'
,
'pf'
]
,
env
=
get_env
()
)
# No env: No output.
# No env: No output.
def
add_anchors
(
self
,
anchor
):
def
add_anchors
(
self
,
anchor
):
...
@@ -386,15 +387,10 @@ else:
...
@@ -386,15 +387,10 @@ else:
def
pfctl
(
args
,
stdin
=
None
):
def
pfctl
(
args
,
stdin
=
None
):
argv
=
[
'pfctl'
]
+
shlex
.
split
(
args
)
argv
=
[
'pfctl'
]
+
shlex
.
split
(
args
)
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
debug1
(
'>>
%
s
\n
'
%
' '
.
join
(
argv
))
env
=
{
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
p
=
ssubprocess
.
Popen
(
argv
,
stdin
=
ssubprocess
.
PIPE
,
p
=
ssubprocess
.
Popen
(
argv
,
stdin
=
ssubprocess
.
PIPE
,
stdout
=
ssubprocess
.
PIPE
,
stdout
=
ssubprocess
.
PIPE
,
stderr
=
ssubprocess
.
PIPE
,
stderr
=
ssubprocess
.
PIPE
,
env
=
env
)
env
=
get_env
()
)
o
=
p
.
communicate
(
stdin
)
o
=
p
.
communicate
(
stdin
)
if
p
.
returncode
:
if
p
.
returncode
:
raise
Fatal
(
'
%
r returned
%
d'
%
(
argv
,
p
.
returncode
))
raise
Fatal
(
'
%
r returned
%
d'
%
(
argv
,
p
.
returncode
))
...
...
sshuttle/server.py
View file @
92b99442
...
@@ -7,24 +7,6 @@ import sys
...
@@ -7,24 +7,6 @@ import sys
import
os
import
os
import
platform
import
platform
if
sys
.
version_info
>=
(
3
,
0
):
from
shutil
import
which
else
:
# python2 compat: shutil.which is not available so we provide our
# own which command
def
which
(
file
,
mode
=
os
.
F_OK
|
os
.
X_OK
,
path
=
None
):
if
path
is
not
None
:
search_paths
=
[
path
]
elif
"PATH"
in
os
.
environ
:
search_paths
=
os
.
environ
[
"PATH"
]
.
split
(
os
.
pathsep
)
else
:
search_paths
=
os
.
defpath
.
split
(
os
.
pathsep
)
for
p
in
search_paths
:
filepath
=
os
.
path
.
join
(
p
,
file
)
if
os
.
path
.
exists
(
filepath
)
and
os
.
access
(
filepath
,
mode
):
return
filepath
return
None
import
sshuttle.ssnet
as
ssnet
import
sshuttle.ssnet
as
ssnet
import
sshuttle.helpers
as
helpers
import
sshuttle.helpers
as
helpers
...
@@ -32,7 +14,7 @@ import sshuttle.hostwatch as hostwatch
...
@@ -32,7 +14,7 @@ import sshuttle.hostwatch as hostwatch
import
subprocess
as
ssubprocess
import
subprocess
as
ssubprocess
from
sshuttle.ssnet
import
Handler
,
Proxy
,
Mux
,
MuxWrapper
from
sshuttle.ssnet
import
Handler
,
Proxy
,
Mux
,
MuxWrapper
from
sshuttle.helpers
import
b
,
log
,
debug1
,
debug2
,
debug3
,
Fatal
,
\
from
sshuttle.helpers
import
b
,
log
,
debug1
,
debug2
,
debug3
,
Fatal
,
\
resolvconf_random_nameserver
resolvconf_random_nameserver
,
which
,
get_env
def
_ipmatch
(
ipstr
):
def
_ipmatch
(
ipstr
):
...
@@ -100,11 +82,7 @@ def _route_iproute(line):
...
@@ -100,11 +82,7 @@ def _route_iproute(line):
def
_list_routes
(
argv
,
extract_route
):
def
_list_routes
(
argv
,
extract_route
):
# FIXME: IPv4 only
# FIXME: IPv4 only
env
=
{
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
env
=
get_env
())
'PATH'
:
os
.
environ
[
'PATH'
],
'LC_ALL'
:
"C"
,
}
p
=
ssubprocess
.
Popen
(
argv
,
stdout
=
ssubprocess
.
PIPE
,
env
=
env
)
routes
=
[]
routes
=
[]
for
line
in
p
.
stdout
:
for
line
in
p
.
stdout
:
if
not
line
.
strip
():
if
not
line
.
strip
():
...
@@ -119,7 +97,6 @@ def _list_routes(argv, extract_route):
...
@@ -119,7 +97,6 @@ def _list_routes(argv, extract_route):
rv
=
p
.
wait
()
rv
=
p
.
wait
()
if
rv
!=
0
:
if
rv
!=
0
:
log
(
'WARNING:
%
r returned
%
d
\n
'
%
(
argv
,
rv
))
log
(
'WARNING:
%
r returned
%
d
\n
'
%
(
argv
,
rv
))
log
(
'WARNING: That prevents --auto-nets from working.
\n
'
)
return
routes
return
routes
...
@@ -130,7 +107,8 @@ def list_routes():
...
@@ -130,7 +107,8 @@ def list_routes():
elif
which
(
'netstat'
):
elif
which
(
'netstat'
):
routes
=
_list_routes
([
'netstat'
,
'-rn'
],
_route_netstat
)
routes
=
_list_routes
([
'netstat'
,
'-rn'
],
_route_netstat
)
else
:
else
:
log
(
'WARNING: Neither ip nor netstat were found on the server.
\n
'
)
log
(
'WARNING: Neither "ip" nor "netstat" were found on the server. '
'--auto-nets feature will not work.
\n
'
)
routes
=
[]
routes
=
[]
for
(
family
,
ip
,
width
)
in
routes
:
for
(
family
,
ip
,
width
)
in
routes
:
...
...
sshuttle/ssh.py
View file @
92b99442
...
@@ -12,7 +12,7 @@ import ipaddress
...
@@ -12,7 +12,7 @@ import ipaddress
from
urllib.parse
import
urlparse
from
urllib.parse
import
urlparse
import
sshuttle.helpers
as
helpers
import
sshuttle.helpers
as
helpers
from
sshuttle.helpers
import
debug2
from
sshuttle.helpers
import
debug2
,
which
,
get_path
,
Fatal
def
get_module_source
(
name
):
def
get_module_source
(
name
):
...
@@ -141,6 +141,17 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
...
@@ -141,6 +141,17 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
argv
=
(
sshl
+
argv
=
(
sshl
+
portl
+
portl
+
[
rhost
,
'--'
,
pycmd
])
[
rhost
,
'--'
,
pycmd
])
# Our which() function searches for programs in get_path()
# directories (which include PATH). This step isn't strictly
# necessary if ssh is already in the user's PATH, but it makes the
# error message friendlier if the user incorrectly passes in a
# custom ssh command that we cannot find.
abs_path
=
which
(
argv
[
0
])
if
abs_path
is
None
:
raise
Fatal
(
"Failed to find '
%
s' in path
%
s"
%
(
argv
[
0
],
get_path
()))
argv
[
0
]
=
abs_path
(
s1
,
s2
)
=
socket
.
socketpair
()
(
s1
,
s2
)
=
socket
.
socketpair
()
def
setup
():
def
setup
():
...
@@ -148,6 +159,7 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
...
@@ -148,6 +159,7 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
s2
.
close
()
s2
.
close
()
s1a
,
s1b
=
os
.
dup
(
s1
.
fileno
()),
os
.
dup
(
s1
.
fileno
())
s1a
,
s1b
=
os
.
dup
(
s1
.
fileno
()),
os
.
dup
(
s1
.
fileno
())
s1
.
close
()
s1
.
close
()
debug2
(
'executing:
%
r
\n
'
%
argv
)
debug2
(
'executing:
%
r
\n
'
%
argv
)
p
=
ssubprocess
.
Popen
(
argv
,
stdin
=
s1a
,
stdout
=
s1b
,
preexec_fn
=
setup
,
p
=
ssubprocess
.
Popen
(
argv
,
stdin
=
s1a
,
stdout
=
s1b
,
preexec_fn
=
setup
,
close_fds
=
True
,
stderr
=
stderr
)
close_fds
=
True
,
stderr
=
stderr
)
...
...
tests/client/test_methods_pf.py
View file @
92b99442
...
@@ -4,7 +4,7 @@ from socket import AF_INET, AF_INET6
...
@@ -4,7 +4,7 @@ from socket import AF_INET, AF_INET6
import
pytest
import
pytest
from
mock
import
Mock
,
patch
,
call
,
ANY
from
mock
import
Mock
,
patch
,
call
,
ANY
from
sshuttle.methods
import
get_method
from
sshuttle.methods
import
get_method
from
sshuttle.helpers
import
Fatal
from
sshuttle.helpers
import
Fatal
,
get_env
from
sshuttle.methods.pf
import
FreeBsd
,
Darwin
,
OpenBsd
from
sshuttle.methods.pf
import
FreeBsd
,
Darwin
,
OpenBsd
...
@@ -316,7 +316,8 @@ def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl,
...
@@ -316,7 +316,8 @@ def test_setup_firewall_freebsd(mock_pf_get_dev, mock_ioctl, mock_pfctl,
b
'to <dns_servers> port 53 keep state
\n
'
),
b
'to <dns_servers> port 53 keep state
\n
'
),
call
(
'-e'
),
call
(
'-e'
),
]
]
assert
call
([
'kldload'
,
'pf'
])
in
mock_subprocess_call
.
mock_calls
assert
call
([
'kldload'
,
'pf'
],
env
=
get_env
())
in
\
mock_subprocess_call
.
mock_calls
mock_pf_get_dev
.
reset_mock
()
mock_pf_get_dev
.
reset_mock
()
mock_ioctl
.
reset_mock
()
mock_ioctl
.
reset_mock
()
mock_pfctl
.
reset_mock
()
mock_pfctl
.
reset_mock
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment