mirror of
https://github.com/sshuttle/sshuttle.git
synced 2024-12-01 04:14:37 +01:00
Fix parsing of hostnames to allow ssh aliases defined in ssh configs) (#418)
* Fix parsing of hostnames to allow ssh aliases defined in ssh configs) * nicer formatting, pep8 applied * Properly parse IPv6 addresses with port specification * Now also handles hostnames with port specified and IPv6 addresses without port properly * Updated parameter description for the remotehost specification * Make the urlparse import backwards compatible to python2 Co-authored-by: Tobi <tobi-git@grimm.gr>
This commit is contained in:
parent
580462156e
commit
966fd0c523
@ -177,9 +177,9 @@ parser.add_argument(
|
|||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-r", "--remote",
|
"-r", "--remote",
|
||||||
metavar="[USERNAME@]ADDR[:PORT]",
|
metavar="[USERNAME[:PASSWORD]@]ADDR[:PORT]",
|
||||||
help="""
|
help="""
|
||||||
ssh hostname (and optional username) of remote %(prog)s server
|
ssh hostname (and optional username and password) of remote %(prog)s server
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
|
@ -6,6 +6,14 @@ import zlib
|
|||||||
import imp
|
import imp
|
||||||
import subprocess as ssubprocess
|
import subprocess as ssubprocess
|
||||||
import shlex
|
import shlex
|
||||||
|
import ipaddress
|
||||||
|
|
||||||
|
# ensure backwards compatiblity with python2.7
|
||||||
|
try:
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
except ImportError:
|
||||||
|
from urlparse import urlparse
|
||||||
|
|
||||||
import sshuttle.helpers as helpers
|
import sshuttle.helpers as helpers
|
||||||
from sshuttle.helpers import debug2
|
from sshuttle.helpers import debug2
|
||||||
|
|
||||||
@ -61,53 +69,64 @@ def empackage(z, name, data=None):
|
|||||||
|
|
||||||
|
|
||||||
def parse_hostport(rhostport):
|
def parse_hostport(rhostport):
|
||||||
# default define variable
|
"""
|
||||||
port = ""
|
parses the given rhostport variable, looking like this:
|
||||||
username = re.split(r'\s*:', rhostport)[0]
|
|
||||||
|
|
||||||
# Fix #410 bad username error detect
|
[username[:password]@]host[:port]
|
||||||
if "@" in username:
|
|
||||||
username = re.split(r'\s*@', rhostport)[0]
|
|
||||||
|
|
||||||
password = None
|
if only host is given, can be a hostname, IPv4/v6 address or a ssh alias
|
||||||
host = None
|
from ~/.ssh/config
|
||||||
|
|
||||||
try:
|
and returns a tuple (username, password, port, host)
|
||||||
password = re.split(r'\s*:', rhostport)[1]
|
"""
|
||||||
if "@" in password:
|
# default port for SSH is TCP port 22
|
||||||
password = password.split("@")[0]
|
|
||||||
except (IndexError, TypeError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
if password is None or "@" in password:
|
|
||||||
# default define password
|
|
||||||
password = None
|
|
||||||
host = password
|
|
||||||
|
|
||||||
if host is None:
|
|
||||||
# split for ipv4 or ipv6
|
|
||||||
host = "{}".format(re.split(r'\s*@', rhostport)[1])
|
|
||||||
|
|
||||||
# try if port define
|
|
||||||
try:
|
|
||||||
# Fix #410 detect host:port
|
|
||||||
port = re.split(r'\s*:', host)[1]
|
|
||||||
host = re.split(r'\s*:', host)[0]
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if port == "":
|
|
||||||
port = 22
|
port = 22
|
||||||
|
username = None
|
||||||
|
password = None
|
||||||
|
host = rhostport
|
||||||
|
|
||||||
|
if "@" in host:
|
||||||
|
# split username (and possible password) from the host[:port]
|
||||||
|
username, host = host.split("@")
|
||||||
|
# Fix #410 bad username error detect
|
||||||
|
# username cannot contain an @ sign in this scenario
|
||||||
|
if ":" in username:
|
||||||
|
# this will even allow for the username to be empty
|
||||||
|
username, password = username.split(":")
|
||||||
|
|
||||||
|
if ":" in host:
|
||||||
|
# IPv6 address and/or got a port specified
|
||||||
|
|
||||||
|
# If it is an IPv6 adress with port specification,
|
||||||
|
# then it will look like: [::1]:22
|
||||||
|
|
||||||
|
try:
|
||||||
|
# try to parse host as an IP adress,
|
||||||
|
# if that works it is an IPv6 address
|
||||||
|
host = ipaddress.ip_address(host)
|
||||||
|
except ValueError:
|
||||||
|
# if that fails parse as URL to get the port
|
||||||
|
parsed = urlparse('//{}'.format(host))
|
||||||
|
try:
|
||||||
|
host = ipaddress.ip_address(parsed.hostname)
|
||||||
|
except ValueError:
|
||||||
|
# else if both fails, we have a hostname with port
|
||||||
|
host = parsed.hostname
|
||||||
|
port = parsed.port
|
||||||
|
|
||||||
|
|
||||||
if password is None or len(password) == 0:
|
if password is None or len(password) == 0:
|
||||||
password = None
|
password = None
|
||||||
|
|
||||||
return username, password, port, host
|
return username, password, port, host
|
||||||
|
|
||||||
|
|
||||||
def connect(ssh_cmd, rhostport, python, stderr, options):
|
def connect(ssh_cmd, rhostport, python, stderr, options):
|
||||||
username, password, port, host = parse_hostport(rhostport)
|
username, password, port, host = parse_hostport(rhostport)
|
||||||
|
if username:
|
||||||
rhost = "{}@{}".format(username, host)
|
rhost = "{}@{}".format(username, host)
|
||||||
|
else:
|
||||||
|
rhost = host
|
||||||
|
|
||||||
z = zlib.compressobj(1)
|
z = zlib.compressobj(1)
|
||||||
content = readfile('sshuttle.assembler')
|
content = readfile('sshuttle.assembler')
|
||||||
|
Loading…
Reference in New Issue
Block a user