genode/repos/gems/src/server/ssh_terminal
Sid Hussmann eaefcc2c6f ssh: add exec channel and exit on interactive
This commit implements the ssh exec channel request. It also handles
some shortcommings on the interactive channel like exit and concurrent
session establishments.

Pipes into the channel do not work yet. E.g.:
echo foobar | ssh noux@localhost -p 5555 "cat > /rw/test.txt"

The issue described with FIXME in Ssh::Server::incoming_connection()
could not be reproduced and might have been fixed with the improved
file descriptor handling.

Fixes #3401
2019-08-13 12:02:03 +02:00
..
login.h ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
main.cc ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
README ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
root_component.h ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
server.cc ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
server.h ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
session_component.h ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
ssh_callbacks.cc ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
target.mk ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
terminal.h ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
util.cc ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00
util.h ssh: add exec channel and exit on interactive 2019-08-13 12:02:03 +02:00

This directory contains an minimal SSH Terminal server. It provides
concurrent access to multiple Terminal sessions via interactive SSH sessions.
Before using the component, please consult the _Notes_ section to learn
about the current subtleties.

For an example on how to use the server please look at the run script
provided by _repos/gems/run/ssh_terminal_ or _repos/gems/run/ssh_exec_channel_.


Configuration
~~~~~~~~~~~~~

Examplary configuration:

! <config port="2022" ed25519_key="/etc/ed25519_host_key
!         allow_password="yes" allow_publickey="yes"/>
!   <vfs>
!   <policy label="noux-system" user="root" password="toor"/>
!   <policy label="noux-user"   user="user" pub_key="/etc/user.pub"/>
!
!     <dir name="dev">
!       <log/> <rtc/>
!       <inline name="random">012345678</inline>
!     </dir>
!     <dir name="socket"> <lxip dhcp="yes"/> </dir>
!     <dir name="etc"> <fs/> </dir>
!   </vfs>
!   <libc stdout="/dev/log" stderr="/dev/log" rtc="/dev/rtc" socket="/socket"/>
! </config>

The above config snippet shows a configuration where two Noux clients may
connect to the Terminal server and SSH connections with either a password or a
public are processed on port 2022. All SSH logins for the user 'root' are
linked to the 'noux-system' session, while all 'user' logins are forwarded
to the 'noux-user' session.

The '<config>' node has several mandatory attributes:

* 'port' specfies the TCP port the SSH server attempts to listen on.

* 'ecdsa_key', 'ed25519_key' and 'rsa_key' set the respective
  path to the host key. At least one of them must be specified.

* 'allow_password' enables password logins while 'allow_publickey'
  enables public-key logins. At least one of them must be specified.
  Those Authentication methods are set for all logins even if they
  are not useable by one or the other.

Aside from the mandatory attributes there are optional ones:

* 'log_logins' enables logging of login attempts. These attempts will
   be printed to the LOG session. The default is 'yes'.

The relation between a Terminal session and a SSH session is established
by a '<policy>' node. It first specifies which Terminal client may access
the server. Second and more importantly it specifies which SSH session has
access to which Terminal session. The non policy-label specific attributes
of the node form a login that is used to authenticate access via the SSH
session:

* 'user' sets the name of a login and is used throughout the component
  to establish the relation between Terminal and SSH session and is therefore
  mandatory.

* 'password' sets the password of the login, which is used to authenticate
  a login attempt.

* 'pub_key' sets the path to the public-key file, which is used to authenticate
  a login attempt.

* 'multi_login' allows one Terminal session to be used by mutliple SSH
  sessions concurrently, the default is false.

Either one of the 'password' or 'pub_key' attributes must be set in order for
the login to be valid.

Normally, all Terminal sessions are expected to be established before an SSH
connection is made. To accommodate the use-case where the Terminal client is
made available in a dynamic fashion, the 'request_terminal' attribute can by
set to 'yes'. In this case the SSH Terminal server will generate a report,
which then can be inspected and reacted upon by a management component,
whenever a SSH connection for a detached Terminal session is made. Data coming
from the SSH session will be ignored as long as the Terminal client is not
attached to the server. This mechanism is useful in cases where the attached
Terminal might terminate itself, e.g. a shell when receiving EOF, but a
subsequent login attempt expects the Terminal client to be still attached.

The following snippet shows such a report:

! <request_terminal user="baron"/>

The component will generate the report only once when the first login
via SSH is made and the corresponding Terminal session is not available.
All subsequent logins have to wait until the session is provided. Once the
Terminal session has been detached an 'exit' report is generated. Detaching a
terminal client will lead to a disconnect for the corresponding SSH session If
there are active SSH session after the Terminal in question has been detached, a
new report will be generated.


Notes
~~~~~

* A helper component is needed, in case an exec channel is required or when
  Terminal sessions need to be started *after* the SSH connection is
  established. An example can be found here: _repos/gems/src/test/exec_terminal/

* The SSH connection MUST be forcefully cut at the client in case the Terminal
  session is established *before* the ssh channel is open. This can be done
  when using OpenSSH by entering '~.'.

* Host keys can be generated by using ssh-keygen(1) on your host system
  (e.g., 'ssh-keygen -t ed25519_key -f ed25519_key' without a passphrase and
  then use the 'ed25519_key' file).

* Reports from concurrent logins will override each other and potentially lead
  to lost reports.

* Although concurrent access to one Terminal session via multiple SSH sessions
  at the same time is possible, it should better be avoided as there are no
  safety measures in place.