mirror of
https://github.com/sshuttle/sshuttle.git
synced 2024-11-21 23:43:18 +01:00
123 lines
4.7 KiB
Python
123 lines
4.7 KiB
Python
import re
|
|
import socket
|
|
import sshuttle.helpers as helpers
|
|
import sshuttle.client as client
|
|
import sshuttle.firewall as firewall
|
|
import sshuttle.hostwatch as hostwatch
|
|
import sshuttle.ssyslog as ssyslog
|
|
from sshuttle.options import parser, parse_ipport
|
|
from sshuttle.helpers import family_ip_tuple, log, Fatal
|
|
from sshuttle.sudoers import sudoers
|
|
|
|
|
|
def main():
|
|
opt = parser.parse_args()
|
|
|
|
if opt.sudoers_no_modify:
|
|
# sudoers() calls exit() when it completes
|
|
sudoers(user_name=opt.sudoers_user)
|
|
|
|
if opt.daemon:
|
|
opt.syslog = 1
|
|
if opt.wrap:
|
|
import sshuttle.ssnet as ssnet
|
|
ssnet.MAX_CHANNEL = opt.wrap
|
|
if opt.latency_buffer_size:
|
|
import sshuttle.ssnet as ssnet
|
|
ssnet.LATENCY_BUFFER_SIZE = opt.latency_buffer_size
|
|
helpers.verbose = opt.verbose
|
|
|
|
try:
|
|
if opt.firewall:
|
|
if opt.subnets or opt.subnets_file:
|
|
parser.error('exactly zero arguments expected')
|
|
return firewall.main(opt.method, opt.syslog)
|
|
elif opt.hostwatch:
|
|
hostwatch.hw_main(opt.subnets, opt.auto_hosts)
|
|
return 0
|
|
else:
|
|
# parse_subnetports() is used to create a list of includes
|
|
# and excludes. It is called once for each parameter and
|
|
# returns a list of one or more items for each subnet (it
|
|
# can return more than one item when a hostname in the
|
|
# parameter resolves to multiple IP addresses. Here, we
|
|
# flatten these lists.
|
|
includes = [item for sublist in opt.subnets+opt.subnets_file
|
|
for item in sublist]
|
|
excludes = [item for sublist in opt.exclude for item in sublist]
|
|
|
|
if not includes and not opt.auto_nets:
|
|
parser.error('at least one subnet, subnet file, '
|
|
'or -N expected')
|
|
remotename = opt.remote
|
|
if remotename == '' or remotename == '-':
|
|
remotename = None
|
|
nslist = [family_ip_tuple(ns) for ns in opt.ns_hosts]
|
|
if opt.seed_hosts:
|
|
sh = re.split(r'[\s,]+', (opt.seed_hosts or "").strip())
|
|
elif opt.auto_hosts:
|
|
sh = []
|
|
else:
|
|
sh = None
|
|
if opt.listen:
|
|
ipport_v6 = None
|
|
ipport_v4 = None
|
|
lst = opt.listen.split(",")
|
|
for ip in lst:
|
|
family, ip, port = parse_ipport(ip)
|
|
if family == socket.AF_INET6:
|
|
ipport_v6 = (ip, port)
|
|
else:
|
|
ipport_v4 = (ip, port)
|
|
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
|
|
try:
|
|
int(opt.tmark, 16)
|
|
except ValueError:
|
|
parser.error("--tmark must be a hexadecimal value")
|
|
opt.tmark = opt.tmark.lower() # make 'x' in 0x lowercase
|
|
if not opt.tmark.startswith("0x"): # accept without 0x prefix
|
|
opt.tmark = "0x%s" % opt.tmark
|
|
if opt.syslog:
|
|
ssyslog.start_syslog()
|
|
ssyslog.close_stdin()
|
|
ssyslog.stdout_to_syslog()
|
|
ssyslog.stderr_to_syslog()
|
|
return_code = client.main(ipport_v6, ipport_v4,
|
|
opt.ssh_cmd,
|
|
remotename,
|
|
opt.python,
|
|
opt.latency_control,
|
|
opt.latency_buffer_size,
|
|
opt.dns,
|
|
nslist,
|
|
opt.method,
|
|
sh,
|
|
opt.auto_hosts,
|
|
opt.auto_nets,
|
|
includes,
|
|
excludes,
|
|
opt.daemon,
|
|
opt.to_ns,
|
|
opt.pidfile,
|
|
opt.user,
|
|
opt.sudo_pythonpath,
|
|
opt.tmark)
|
|
|
|
if return_code == 0:
|
|
log('Normal exit code, exiting...')
|
|
else:
|
|
log('Abnormal exit code %d detected, failing...' % return_code)
|
|
return return_code
|
|
|
|
except Fatal as e:
|
|
log('fatal: %s' % e)
|
|
return 99
|
|
except KeyboardInterrupt:
|
|
log('\n')
|
|
log('Keyboard interrupt: exiting.')
|
|
return 1
|