mirror of
https://github.com/sshuttle/sshuttle.git
synced 2025-04-30 22:24:55 +02:00
Issue #631 suggests that we should warn about users who add sshuttle to sudoers because it isn't obvious that when a user can run sshuttle as root, they can run any command as root using sshuttle's -e or --ssh-cmd parameters. This patch adds a comment that warns about this problem to the sudoers file. It also prints the warning to the console if the user uses an option that writes the data directly to the file. This patch also causes the output of the sudoers-add command to be printed to the console so that the user can see the name of the file that was created. There is room for improvement: Warnings could be added to the documentation and/or these parameters could be removed entirely.
72 lines
1.8 KiB
Python
72 lines
1.8 KiB
Python
import os
|
|
import sys
|
|
import getpass
|
|
from uuid import uuid4
|
|
from subprocess import Popen, PIPE
|
|
from sshuttle.helpers import log, debug1
|
|
from distutils import spawn
|
|
|
|
path_to_sshuttle = sys.argv[0]
|
|
path_to_dist_packages = os.path.dirname(os.path.abspath(__file__))[:-9]
|
|
|
|
# randomize command alias to avoid collisions
|
|
command_alias = 'SSHUTTLE%(num)s' % {'num': uuid4().hex[-3:].upper()}
|
|
|
|
# Template for the sudoers file
|
|
template = '''
|
|
Cmnd_Alias %(ca)s = /usr/bin/env PYTHONPATH=%(dist_packages)s %(py)s %(path)s *
|
|
|
|
%(user_name)s ALL=NOPASSWD: %(ca)s
|
|
'''
|
|
|
|
warning_msg = "# WARNING: When you allow a user to run sshuttle as root,\n" \
|
|
"# they can then use sshuttle's --ssh-cmd option to run any\n" \
|
|
"# command as root.\n"
|
|
|
|
|
|
def build_config(user_name):
|
|
content = warning_msg
|
|
content += template % {
|
|
'ca': command_alias,
|
|
'dist_packages': path_to_dist_packages,
|
|
'py': sys.executable,
|
|
'path': path_to_sshuttle,
|
|
'user_name': user_name,
|
|
}
|
|
|
|
return content
|
|
|
|
|
|
def save_config(content, file_name):
|
|
process = Popen([
|
|
'/usr/bin/sudo',
|
|
spawn.find_executable('sudoers-add'),
|
|
file_name,
|
|
], stdout=PIPE, stdin=PIPE)
|
|
|
|
process.stdin.write(content.encode())
|
|
|
|
streamdata = process.communicate()[0]
|
|
sys.stdout.write(streamdata.decode("ASCII"))
|
|
returncode = process.returncode
|
|
|
|
if returncode:
|
|
log('Failed updating sudoers file.')
|
|
debug1(streamdata)
|
|
exit(returncode)
|
|
else:
|
|
log('Success, sudoers file update.')
|
|
exit(0)
|
|
|
|
|
|
def sudoers(user_name=None, no_modify=None, file_name=None):
|
|
user_name = user_name or getpass.getuser()
|
|
content = build_config(user_name)
|
|
|
|
if no_modify:
|
|
sys.stdout.write(content)
|
|
exit(0)
|
|
else:
|
|
sys.stdout.write(warning_msg)
|
|
save_config(content, file_name)
|