### Navigation

- index
- modules |
- next |
- previous |
- Gate One Documentation »
- Developer Documentation »

# The SSH Plugin

Todo

Write documentation on ssh.js

ssh.py - A plugin for Gate One that adds additional SSH-specific features.

## Hooks

This Python plugin file implements the following hooks:

    hooks = {
        'Web': [(r"/ssh", KnownHostsHandler)],
        'WebSocket': {
            'ssh_get_connect_string': get_connect_string,
            'ssh_execute_command': ws_exec_command,
            'ssh_get_identities': get_identities,
            'ssh_get_public_key': get_public_key,
            'ssh_get_private_key': get_private_key,
            'ssh_get_host_fingerprint': get_host_fingerprint,
            'ssh_gen_new_keypair': generate_new_keypair,
            'ssh_store_id_file': store_id_file,
            'ssh_delete_identity': delete_identity,
            'ssh_set_default_identities': set_default_identities
        },
        'Escape': opt_esc_handler,
        'Auth': create_user_ssh_dir
    }

## Docstrings

exception `ssh.``SSHMultiplexingException`

  Called when there's a failure trying to open a sub-shell via OpenSSH's Master mode multiplexing capability.

exception `ssh.``SSHExecutionException`

  Called when there's an error trying to execute a command in the slave.

exception `ssh.``SSHKeygenException`

  Called when there's an error trying to generate a public/private keypair.

exception `ssh.``SSHKeypairException`

  Called when there's an error trying to save public/private keypair or certificate.

exception `ssh.``SSHPassphraseException`

  Called when we try to generate/decode something that requires a passphrase but no passphrase was given.

`ssh.``get_ssh_dir`(tws)

  Given a `gateone.TerminalWebSocket` (tws) instance, return the current user's ssh directory

`ssh.``open_sub_channel`(term, tws)

  Opens a sub-channel of communication by executing a new shell on the SSH server using OpenSSH's Master mode capability (it spawns a new slave) and returns the resulting `termio.Multiplex` instance. If a slave has already been opened for this purpose it will re-use the existing channel.

`ssh.``wait_for_prompt`(term, cmd, errorback, callback, m_instance, matched)

  Called by `termio.Multiplex.expect()` inside of `execute_command()`, clears the screen and executes cmd. Also, sets an `expect()` to call `get_cmd_output()` when the end of the command output is detected.

`ssh.``get_cmd_output`(term, errorback, callback, m_instance, matched)

  Captures the output of the command executed inside of `wait_for_prompt()` and calls callback if it isn't `None`.

`ssh.``terminate_sub_channel`(m_instance)

  Calls `m_instance.terminate()` and deletes it from the OPEN_SUBCHANNELS dict.

`ssh.``timeout_sub_channel`(m_instance)

  Called when the sub-channel times out by way of an `termio.Multiplex.expect` pattern that should never match anything.

`ssh.``got_error`(m_instance, match=None, term=None, cmd=None, tws=None)

  Called if `execute_command()` encounters a problem/timeout.

  match is here in case we want to use it for a positive match of an error.

`ssh.``execute_command`(term, cmd, callback=None, tws=None)

  Execute the given command (cmd) on the given term using the existing SSH tunnel (taking advantage of Master mode) and call callback with the output of said command and the current `termio.Multiplex` instance as arguments like so:

      callback(output, m_instance)

  If callback is not provided then the command will be executed and any output will be ignored.

  Note

  This will not result in a new terminal being opened on the client--it simply executes a command and returns the result using the existing SSH tunnel.

`ssh.``send_result`(tws, term, cmd, output, m_instance)

  Called by `ws_exec_command()` when the output of the executed command has been captured successfully. Writes a message to the client with the command's output and some relevant metadata.

`ssh.``ws_exec_command`(settings, tws)

  Takes the necessary variables from settings and calls `execute_command()`.

  settings should be a dict that contains a 'term' and a 'cmd' to execute.

  Tip

  This function can be used to quickly execute a command and return its result from the client over an existing SSH connection without requiring the user to enter their password! See execRemoteCmd() in ssh.js.

class `ssh.``KnownHostsHandler`(application, request, **kwargs)

  This handler allows the client to view, edit, and upload the known_hosts file associated with their user account.

  `get`(*args, **kwargs)

    Determine what the user is asking for and call the appropriate method.

  `post`(*args, **kwargs)

    Determine what the user is updating by checking the given arguments and proceed with the update.

  `_return_known_hosts`()

    Returns the user's known_hosts file in text/plain format.

  `_save_known_hosts`(known_hosts)

    Save the given known_hosts file.

`ssh.``get_connect_string`(term, tws)

  Writes the connection string associated with term to the WebSocket like so:

      {'sshjs_reconnect': {*term*: <connection string>}}

  In ssh.js we attach an action (aka handler) to `GateOne.Net.actions` for 'sshjs_reconnect' messages that attaches the connection string to `GateOne.terminals[*term*]['sshConnectString']`

`ssh.``get_key`(name, public, tws)

  Returns the private SSH key associated with name to the client. If public is `True`, returns the public key to the client.

`ssh.``get_public_key`(name, tws)

  Returns the user's public key file named name.

`ssh.``get_private_key`(name, tws)

  Returns the user's private key file named name.

`ssh.``get_host_fingerprint`(settings, tws)

  Returns a the hash of the given host's public key by making a remote connection to the server (not just by looking at known_hosts).

`ssh.``generate_new_keypair`(settings, tws)

  Calls `openssh_generate_new_keypair()` or `dropbear_generate_new_keypair()` depending on what's available on the system.

`ssh.``overwrite`(m_instance, match)

  Called if we get asked to overwrite an existing keypair.

`ssh.``openssh_generate_new_keypair`(name, path, keytype=None, passphrase='', bits=None, comment='', tws=None)

  Generates a new private and public key pair--stored in the user's directory using the given name and other optional parameters (using OpenSSH).

  If keytype is given, it must be one of "ecdsa", "rsa" or "dsa" (case insensitive). If keytype is "rsa" or "ecdsa", bits may be specified to specify the size of the key.

  Note

  Defaults to generating a 521-byte ecdsa key if OpenSSH is version 5.7+. Otherwise a 2048-bit rsa key will be used.

`ssh.``dropbear_generate_new_keypair`(name, path, keytype=None, passphrase='', bits=None, comment='', tws=None)

  Note

  Not implemented yet

`ssh.``openssh_generate_public_key`(path, passphrase=None, settings=None, tws=None)

  Generates a public key from the given private key at path. If a passphrase is provided, it will be used to generate the public key (if necessary).

`ssh.``store_id_file`(settings, tws=None)

  Stores the given settings['private'] and/or settings['public'] keypair in the user's ssh directory as settings['name'] and/or settings['name'].pub, respectively. Either file can be saved independent of each other (in case this function needs to be called multiple times to save each respective file).

  Also, a settings['certificate'] may be provided to be saved along with the private and public keys. It will be saved as settings['name']-cert.pub.

  Note

  I've found the following website helpful in understanding how to use OpenSSH with SSL certificates: http://blog.habets.pp.se/2011/07/OpenSSH-certificates

  Tip

  Using signed-by-a-CA certificates is very handy because allows you to revoke the user's SSH key(s). e.g. If they left the company.

`ssh.``delete_identity`(name, tws)

  Removes the identity associated with name. For example if name is 'testkey', 'testkey' and 'testkey.pub' would be removed from the user's ssh directory (and 'testkey-cert.pub' if present).

`ssh.``get_identities`(anything, tws)

  Sends a message to the client with a list of the identities stored on the server for the current user.

  anything is just there because the client needs to send something along with the 'action'.

`ssh.``set_default_identities`(identities, tws)

  Given a list of identities, mark them as defaults to use in all outbound SSH connections by writing them to `<user's ssh dir>/.default_ids`. If identities is empty, no identities will be used in outbound connections.

  Note

  Whenever this function is called it will overwrite whatever is in `default_ids`.

`ssh.``opt_esc_handler`(text, tws)

  Handles text passed from the special optional escape sequance handler. We use it to tell ssh.js what the SSH connection string is so it can use that information to duplicate sessions (if the user so desires). For reference, the specific string which will call this function from a terminal app is:

      ]_;ssh|<whatever>

  See also

  `gateone.TerminalWebSocket.esc_opt_handler` and `terminal.Terminal._opt_handler()`

`ssh.``create_user_ssh_dir`(current_user, settings)

  To be called by the 'Auth' hook that gets called after the user is done authenticating, ensures that the `<user's dir>/ssh` directory exists.

### Navigation

- index
- modules |
- next |
- previous |
- Gate One Documentation »
- Developer Documentation »