Skip to content

Commit 9e78abd

Browse files
authored
Add password in prompt cmd (sshuttle#401)
* Add auto password prompt Add auto password with sshpass use user:password@host or user:password:port@host * Update ssh.py * Fix for IPv4 only * Delete print sorry bad commit * ipv4 fix * Fix IPv4 args * Fix for ipv6 * Fix ipv6 no password * Add function parse_hostport * Fix minor bug detect port * Fix minor bug password detect * Clear Code * bad write "=" replace with "==" * Rewrite code for more understand logical and fix minor bug * add default define port * delete old variable unused * replace "==" per "is" try fix code reviews * reback * try define password with len * Fix consistence variable password PR * simplify function split ipv4 or ipv6 * clear code
1 parent e320196 commit 9e78abd

File tree

1 file changed

+50
-27
lines changed

1 file changed

+50
-27
lines changed

sshuttle/ssh.py

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import imp
77
import subprocess as ssubprocess
88
import shlex
9-
109
import sshuttle.helpers as helpers
1110
from sshuttle.helpers import debug2
1211

@@ -61,29 +60,46 @@ def empackage(z, name, data=None):
6160
return b'%s\n%d\n%s' % (name.encode("ASCII"), len(content), content)
6261

6362

63+
def parse_hostport(rhostport):
64+
# default define variable
65+
port = ""
66+
username = re.split(r'\s*:', rhostport)[0]
67+
password = None
68+
host = None
69+
70+
try:
71+
password = re.split(r'\s*:', rhostport)[1]
72+
if "@" in password:
73+
password = password.split("@")[0]
74+
except (IndexError, TypeError):
75+
pass
76+
77+
if password is None or "@" in password:
78+
# default define password
79+
password = None
80+
host = password
81+
82+
if host is None:
83+
# split for ipv4 or ipv6
84+
host = "{}".format(re.split(r'\s*@', rhostport)[1])
85+
# try if port define
86+
try:
87+
port = re.split(r'\s*:', rhostport)[2].split('@')[0]
88+
except IndexError:
89+
pass
90+
91+
if port == "":
92+
port = 22
93+
94+
if password is None or len(password) == 0:
95+
password = None
96+
97+
return username, password, port, host
98+
6499
def connect(ssh_cmd, rhostport, python, stderr, options):
65-
portl = []
66-
67-
if re.sub(r'.*@', '', rhostport or '').count(':') > 1:
68-
if rhostport.count(']') or rhostport.count('['):
69-
result = rhostport.split(']')
70-
rhost = result[0].strip('[')
71-
if len(result) > 1:
72-
result[1] = result[1].strip(':')
73-
if result[1] != '':
74-
portl = ['-p', str(int(result[1]))]
75-
# can't disambiguate IPv6 colons and a port number. pass the hostname
76-
# through.
77-
else:
78-
rhost = rhostport
79-
else: # IPv4
80-
host_port = (rhostport or '').rsplit(':', 1)
81-
rhost = host_port[0]
82-
if len(host_port) > 1:
83-
portl = ['-p', str(int(host_port[1]))]
100+
username, password, port, host = parse_hostport(rhostport)
84101

85-
if rhost == '-':
86-
rhost = None
102+
rhost = "{}@{}".format(username, host)
87103

88104
z = zlib.compressobj(1)
89105
content = readfile('sshuttle.assembler')
@@ -119,10 +135,18 @@ def connect(ssh_cmd, rhostport, python, stderr, options):
119135
else:
120136
pycmd = ("P=python3; $P -V 2>%s || P=python; "
121137
"exec \"$P\" -c %s") % (os.devnull, quote(pyscript))
122-
pycmd = ("exec /bin/sh -c %s" % quote(pycmd))
123-
argv = (sshl +
124-
portl +
125-
[rhost, '--', pycmd])
138+
pycmd = ("/bin/sh -c {}".format(quote(pycmd)))
139+
140+
if password is not None:
141+
os.environ['SSHPASS'] = str(password)
142+
argv = (["sshpass", "-e"] + sshl +
143+
["-p", str(port)] +
144+
[rhost, '--', pycmd])
145+
146+
else:
147+
argv = (sshl +
148+
["-p", str(port)] +
149+
[rhost, '--', pycmd])
126150
(s1, s2) = socket.socketpair()
127151

128152
def setup():
@@ -133,7 +157,6 @@ def setup():
133157
debug2('executing: %r\n' % argv)
134158
p = ssubprocess.Popen(argv, stdin=s1a, stdout=s1b, preexec_fn=setup,
135159
close_fds=True, stderr=stderr)
136-
# No env: Would affect the entire sshuttle.
137160
os.close(s1a)
138161
os.close(s1b)
139162
s2.sendall(content)

0 commit comments

Comments
 (0)