Skip to content
Browse files

Added the ability for plugins to add their own define() options to ga…

…teone.py. Also, 90% done with adding SSHFP support but my "awake" powers have been drained for the day. I will finish adding SSHFP support tomorrow.
  • Loading branch information...
1 parent 8969f5d commit a17f3cb78ca6cd39fd20067578b697769cd43ed3 @liftoff liftoff committed
Showing with 49 additions and 40 deletions.
  1. +24 −40 gateone/gateone.py
  2. +16 −0 gateone/plugins/ssh/scripts/ssh_connect.py
  3. +9 −0 gateone/plugins/ssh/ssh.py
View
64 gateone/gateone.py
@@ -927,13 +927,6 @@ def __init__(self, settings):
"default_filename": "index.html"
})
]
- # Load plugins and grab their hooks
- imported = load_plugins(PLUGINS['py'])
- for plugin in imported:
- try:
- PLUGIN_HOOKS.update({plugin.__name__: plugin.hooks})
- except AttributeError:
- pass # No hooks--probably just a supporting .py file.
# Connect the hooks
for plugin_name, hooks in PLUGIN_HOOKS.items():
if 'Web' in hooks:
@@ -978,7 +971,9 @@ def main():
type=str
)
define("command",
- default=GATEONE_DIR + "plugins/ssh/scripts/ssh_connect.py",
+ default=GATEONE_DIR + "/plugins/ssh/scripts/ssh_connect.py -S "
+ r"'/tmp/gateone/%SESSION%/%r@%h:%p' -a "
+ "'-oUserKnownHostsFile=%USERDIR%/%USER%/known_hosts'",
help="Run the given command when a user connects (e.g. 'nethack').",
type=str
)
@@ -1103,7 +1098,14 @@ def main():
help="Kill any running Gate One terminal processes including dtach'd "
"processes."
)
- # TODO: Give plugins the ability to add their own define()s
+ # Before we do anythong else, load plugins and assign their hooks. This
+ # allows plugins to add their own define() statements/options.
+ imported = load_plugins(PLUGINS['py'])
+ for plugin in imported:
+ try:
+ PLUGIN_HOOKS.update({plugin.__name__: plugin.hooks})
+ except AttributeError:
+ pass # No hooks--probably just a supporting .py file.
# TODO: Use the arguments passed to gateone.py to generate server.conf if it
# isn't already present.
if os.path.exists(GATEONE_DIR + "/server.conf"):
@@ -1117,37 +1119,19 @@ def main():
if not os.path.exists(options.session_dir): # Make our session_dir
mkdir_p(options.session_dir)
os.chmod(options.session_dir, 0700)
- config_defaults = {
- 'debug': False,
- 'cookie_secret': generate_session_id(), # Works for so many things!
- 'port': 443,
- 'address': '0.0.0.0', # All addresses
- 'embedded': False,
- 'auth': None,
- 'dtach': True,
- # NOTE: The next four options are specific to the Tornado framework
- 'log_file_max_size': 100 * 1024 * 1024, # 100MB
- 'log_file_num_backups': 10, # 1GB total max
- 'log_file_prefix': '/var/log/gateone/webserver.log',
- 'logging': 'info', # One of: info, warning, error, none
- 'user_dir': options.user_dir,
- 'session_dir': options.session_dir,
- 'session_logging': options.session_logging,
- 'syslog_session_logging': options.syslog_session_logging,
- 'syslog_facility': options.syslog_facility,
- 'session_timeout': options.session_timeout,
- 'keyfile': GATEONE_DIR + "/keyfile.pem",
- 'certificate': GATEONE_DIR + "/certificate.pem",
- 'command': (
- GATEONE_DIR + "/plugins/ssh/scripts/ssh_connect.py -S "
- r"'/tmp/gateone/%SESSION%/%r@%h:%p' -a "
- "'-oUserKnownHostsFile=%USERDIR%/%USER%/known_hosts'"
- ),
- 'sso_realm': 'EXAMPLE.COM',
- 'sso_service': 'HTTP',
- 'pam_realm': uname()[1],
- 'pam_service': 'login'
- }
+ config_defaults = {}
+ for key, value in options.items():
+ config_defaults.update({key: value.default})
+ # A few config defaults need special handling
+ del config_defaults['kill'] # This shouldn't be in server.conf
+ del config_defaults['help'] # Neither should this
+ config_defaults.update({'cookie_secret': generate_session_id()})
+ # NOTE: The next four options are specific to the Tornado framework
+ config_defaults.update({'log_file_max_size': 100 * 1024 * 1024}) # 100MB
+ config_defaults.update({'log_file_num_backups': 10})
+ config_defaults.update({'log_to_stderr': False})
+ config_defaults.update(
+ {'log_file_prefix': '/var/log/gateone/webserver.log'})
config = open(GATEONE_DIR + "/server.conf", "w")
for key, value in config_defaults.items():
if isinstance(value, basestring):
View
16 gateone/plugins/ssh/scripts/ssh_connect.py
@@ -20,6 +20,9 @@
from subprocess import Popen, PIPE
from optparse import OptionParser
+# Import 3rd party stuff
+from tornado.options import options
+
# Globals
re_host = re.compile(r'ssh://')
@@ -40,6 +43,7 @@ def connect_ssh(
password=None,
env=None,
socket=None,
+ sshfp=False,
additional_args=None):
"""
Starts an interactive SSH session to the given host as the given user on the
@@ -71,6 +75,8 @@ def connect_ssh(
"-p", port,
"-l", user,
]
+ if sshfp:
+ args.append("-oVerifyHostKeyDNS=yes")
if socket:
# Only set Master mode if we don't have a socket for this session.
# This allows us to duplicate a session without having to code
@@ -188,22 +194,31 @@ def parse_ssh_url(url):
"mode and 'man ssh')."),
metavar="'<filepath>'"
)
+ parser.add_option("--sshfp",
+ dest="sshfp",
+ default=False,
+ help=("Enable the use of SSHFP in verifying host keys. See: "
+ "http://en.wikipedia.org/wiki/SSHFP#SSHFP")
+ )
(options, args) = parser.parse_args()
try:
if len(args) == 1:
(user, host, port, password) = parse_ssh_url(args[0])
connect_ssh(user, host, port,
password=password,
+ sshfp=options.sshfp,
additional_args=options.additional_args,
socket=options.socket
)
elif len(args) == 2: # No port given, assume 22
connect_ssh(args[0], args[1], '22',
+ sshfp=options.sshfp,
additional_args=options.additional_args,
socket=options.socket
)
elif len(args) == 3:
connect_ssh(args[0], args[1], args[2],
+ sshfp=options.sshfp,
additional_args=options.additional_args,
socket=options.socket
)
@@ -231,6 +246,7 @@ def parse_ssh_url(url):
print("\x1b]_;ssh|%s@%s:%s\007" % (user, host, port))
connect_ssh(user, host, port,
password=password,
+ sshfp=options.sshfp,
additional_args=options.additional_args,
socket=options.socket
)
View
9 gateone/plugins/ssh/ssh.py
@@ -23,6 +23,7 @@
# Tornado stuff
import tornado.web
from tornado.escape import json_encode, json_decode
+from tornado.options import define
# Helper functions
# TODO: make execute_command() a user-configurable option... So it will automatically run whatever command(s) the user likes via a back-end channel whenever they connect to a given server. Maybe even differentiate between when they connect and when they start up a master or slave channel.
@@ -115,6 +116,14 @@ def opt_esc_handler(text, tws):
message = {'sshjs_connect': text}
tws.write_message(json_encode(message))
+# Define a new option for gateone.py to use
+define(
+ "sshfp",
+ default=False,
+ help="Enable the use of SSHFP in verifying host keys. See: "
+ "http://en.wikipedia.org/wiki/SSHFP#SSHFP"
+)
+
hooks = {
'Web': [(r"/ssh", KnownHostsHandler)],
'WebSocket': {

0 comments on commit a17f3cb

Please sign in to comment.
Something went wrong with that request. Please try again.