\input texinfo.tex
@c %**start of header
@setfilename fsh.info
@include version.texi
@settitle fsh @value{VERSION}
@c %**end of header
@setchapternewpage odd
     
@ifinfo
This file documents fsh, which provides fast and secure remote command
execution.

Copyright (C) 1999-2001 Per Cederqvist.

Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.
     
@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries a copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).
     
@end ignore
Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
sections entitled ``Copying'' and ``GNU General Public License'' are
included exactly as in the original, and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
     
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation
approved by the Free Software Foundation.

@end ifinfo

@dircategory Shells and utilities
@direntry
* fsh: (fsh).                           Fast remote command execution.
@end direntry

@titlepage
@title Fsh
@subtitle Fast Remote Command Execution
@subtitle Version @value{VERSION}

@author Per Cederqvist

@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1999-2001 Per Cederqvist

Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided also that the
sections entitled ``Copying'' and ``GNU General Public License'' are
included exactly as in the original, and provided that the entire
resulting derived work is distributed under the terms of a permission
notice identical to this one.
     
Permission is granted to copy and distribute translations of this manual
into another language, under the above conditions for modified versions,
except that this permission notice may be stated in a translation
approved by the Free Software Foundation.

@end titlepage


@node Top
@top Fsh

@ifinfo

This manual documents fsh version @value{VERSION}.

@menu
* Introduction::                What is fsh good for?
* Invoking fshd::               Creating a tunnel.
* Invoking fsh::                Using the tunnel.
* Invoking fcp::                Copying files via the tunnel
* Using with CVS::              Some tips for CVS interoperability.
* Bugs::                        Reporting bugs, finding new releases.
* Remote protocol::             The remote protocol.
* Local protocol::              The local protocol.
@end menu
@end ifinfo     

@node Introduction
@chapter Introduction to fsh

Remote command execution via a cryptographically strong method such as
@code{lsh} or @code{ssh} is often painfully slow, especially if either
of the involved computers is slow.  The biggest problem is that the
client and the server perform a lot of complex calculations during
connection establishment.

@code{fsh} uses @code{lsh} or @code{ssh} to establish a secure tunnel to
the remote system.  This takes as long as a normal connection
establishment, but once the tunnel is established, @code{fsh} can reuse
it to start new sessions on the remote system almost instantaneously.
You get the security of @code{ssh} and the speed of @code{rsh}.

There are three programs at work.  @code{fshd} establish a tunnel to the
remote system.  It can use @code{lsh}, @code{ssh} or even @code{rsh} to
establish it.  It will start @code{in.fshd} on the remote system.  You
can start @code{fshd} manually, or allow @code{fsh} to do it
automatically on an as-needed basis.

@code{in.fshd} receives commands such as "create a new session running
the command @code{gcc foo.c}, and call it session 3" or "send the
following data to standard input of session 5" via the tunnel.  You
would normally not interact directly with @code{in.fshd}.

@code{fsh} is a drop-in replacement for @code{rsh}.  It connects to the
local @code{fshd} using a unix domain socket that is protected so that
only the user that started @code{fshd} can connect to it.  It uses
@code{fshd} to forward a request to @code{in.fshd}, which will in turn
start the requested program.

@node Invoking fshd
@chapter Invoking fshd

There is normally no need to invoke @code{fshd} manually, but it may be
useful for debugging purposes.  A typical invocation may look like one
of these:

@example
fshd sally.lysator.liu.se
fshd -r lsh biffen.cendio.se
fshd -l root biffen.cendio.se
@end example

The @code{in.fshd} binary must be present in your path on the remote
system once you log in.

If the connection is successful the message @samp{Connection
established} will be displayed (unless the option @samp{-b} was given).
This typically takes a few seconds.  The tunnel is closed if you kill
@code{fshd}, or if no session has used the tunnel for so long that a
timeout is reached.

The basic invocation syntax is:

@example
fshd [ options ] server
@end example

@code{fshd} understands the following options:

@table @samp
@item -r @var{method}

The @var{method} argument should be an @code{rsh}-compatible program.
The default value is @code{ssh}.

The @var{method} argument will be unquoted using the quoted-printable
encoding, so if it contains an equal sign (@code{=}) you have to write
it as @code{=3D}.

@item -l @var{login}

Specify the user name that should be used on the remote system.

@item -b
@itemx --background

Tell fshd to detach from the controlling terminal and run in the
background as soon as a connection to the remote system has been
established.  This option is used by @code{fsh} when it auto-starts an
@code{fshd}.  If this option is not given @code{fshd} will print some
messages as connections are established.

@item -T @var{timeout}
@itemx --timeout=@var{timeout}

If this instance of @code{fshd} has been unused for more than
@var{timeout} seconds, @code{fshd} will terminate.  The default timeout
can be set at configure time, but is normally ten hours.

Use @code{--timeout=0} to disable the timeout.
@end table

@node Invoking fsh
@chapter Invoking fsh

You can use @code{fsh} to connect to a remote system via a tunnel.  If
no @code{fshd} with the approriate options is running one will be
started by @code{fsh}.  The exit value of @code{fsh} will be the exit
value of the command that is executed remotely.

The remote command will be executed via whatever @code{$SHELL} is set to
when the user logs in to the remote system.  It might be instructive to
run @samp{fsh sally env} to see what the remote environment really looks
like.  If you do not like it, you should consult the documentation for
the underlying transport (such as @code{ssh})--@code{fsh} does not alter
the environment.

Here are a few examples of how @code{fsh} can be used:

@example
fsh sally.lysator.liu.se echo hej
fsh -r lsh biffen.cendio.se head -43 /etc/termcap
fsh -l root -r lsh biffen.cendio.se head -43 /etc/termcap
@end example

The basic invocation syntax is:

@example
fsh [ options ] server command args...
@end example

@table @samp
@item -r @var{method} 

The @code{method} argument should be an @code{rsh}-compatible program.
The default value is @code{ssh}.

@item -l @var{login}
The @code{login} argument specifies the user name that should be used on
the remote system.

@item -T @var{timeout}
@itemx --timeout=@var{timeout}

If there is no tunnel @code{fsh} will automatically start @code{fshd},
and pass this option to @code{fshd}.  Once that @code{fshd} has been
unused for more than @var{timeout} seconds, it will terminate.  The
default timeout can be set at configure time, but is normally ten hours.

Use @code{--timeout=0} to disable the timeout.

This option is ignored if @code{fshd} is already running.
@end table

@node Invoking fcp
@chapter Invoking fcp

You can use @code{fcp} to copy files to a remote system via a tunnel.

@example
fcp [scp-options] f1 f2
fcp [scp-options] f1 f2... dir
@end example

@code{fcp} is a very simple wrapper that starts @code{scp} with the
@samp{-S path-to-ssh} argument, telling it to use @code{fshwrap}, which
is another simple wrapper that gets rid of all flags that @code{ssh}
accepts but @code{fsh} doesn't implement, and then calls @code{fsh}.

The net result is that you can use @code{fcp} as you use @code{scp}, for
most uses, but sometimes all these wrappers might get in the way.  See
the @code{scp} documentation for information about the flags that
@code{scp} accepts.

@node Using with CVS
@chapter Sample application: CVS

The reason why @code{fsh} was written was to make it possible to use
remote CVS fast and securely.  This chapter outlines all necessary steps
towards that end.  It is assumed that you already have a working CVS
repository on a server, and that CVS is installed on the client as well.

@itemize @bullet
@item
Install @code{fsh} on the server and client.  Make sure it exists in
your default path.

@item
Test that you really can log in to the server from the client.

@example
bash$ ssh server.domain echo it is working
it is working
bash$
@end example

You may have to enter a password or passphrase.  That is OK.

@item
Make sure that @code{in.fshd} is found when you log in to the server.

@example
bash$ ssh server.domain in.fshd
fsh 1
@end example

You may have to enter a password or passphrase.  That is OK.

Once you receive the line @code{fsh 1} you can press end-of-file to end
the session.

@item
Start a tunnel to the remote system.

@example
bash$ fshd server.domain
Connection established
@end example

This step is not really necessary, but since your are reading this you
probably have a problem with your connection.  Running @code{fshd}
manually may help troubleshooting any problem you have.

You may have to enter a password or passphrase.  That is OK.

@item
Switch to another screen (or virtual console, or xterm, or whatever) on
the client.  Set the environment variable @code{CVS_RSH} to the value
@var{fsh}:

@example
bash$ export CVS_RSH=fsh
@end example

@item
Run cvs to export a module.

@example
bash$ cvs -d server.domain:/path/to/cvs/repository co module-name
@end example

@item
Access the module and experience the speed.

@example
bash$ cd module-name
bash$ cvs log foo.c
bash$ cvs status bar.c
@end example

If you switch back to the screen running @code{fshd}, you will notice
that a few lines of texts was written each time a remote command was
executed.

@end itemize

If you are using a modem or a slow internet connection to connect to the
remote server, you probably want to use @code{Compression} in
@file{.ssh/config}.  See ssh(1).


@node Bugs
@chapter Reporting bugs

Bugs should preferably be reported using the Bugzilla installation at
@url{http://bugzilla.lysator.liu.se/}.  You can also query Bugzilla
for known bugs.

Bugs can also be reported to @email{fsh-bugs@@lists.lysator.liu.se},
if for some reason you cannot use Bugzilla.  If you don't want the bug
report to be public you can try @email{ceder@@lysator.liu.se} instead.
Expect a response time of at least one to two weeks.  I have been
known to reply to mail after a couple of years in the past.
      
Before you report a bug, please check if there is a new release
available first.  The home page of @code{fsh} is
@url{http://www.lysator.liu.se/fsh/}.  You can find info about the fsh
mailing lists there as well.


@node Remote protocol
@chapter The remote protocol

This chapter documents the protocol between @code{fshd} and
@code{in.fshd}.  This protocol is normally only of interest to the
developer of @code{fsh}, and may be a little out of date.

In the description below, @code{fshd} is the client and @code{in.fshd}
is the server.  You can try out the protocol manually if you like by
starting @code{in.fshd} interactively.  In the example, the text that is
output by @code{in.fshd} appears after the print symbol @samp{@print{}}.

@example
bash$ in.fshd
 @print{} fsh 1
new 2 8Hcat -vet
stdin 2 4Hfoo

 @print{} stdout 2 5Hfoo$
 @print{} 
eof-stdin 2
 @print{} eof-stdout 2
 @print{} eof-stderr 2
 @print{} exit 2 1H0
 @print{} eos 2
@end example

@section Basic syntax

The protocol assumes an 8-bit-clean connection.  All commands (except
the initial greeting) have the same overall structure.  This protocol
uses ASCII, but it is capable of transmitting any byte-stream.  This is
the overall structure:

@itemize @bullet{}
@item
The command name (a string).
@item
A space.
@item
The session number, coded as a decimal string.
@item
A space, if there is a data chunk.
@item
An optional data chunk, coded as the length (expressed as a decimal
string), the ASCII letter @samp{H}, and the data.  The data may contain
any character, including NULs and newlines.
@item
A newline.
@end itemize

Some commands require the data chunk, while others don't allow it.
There is no command that only uses a data chunk sometimes.

@section Connection establishment

The server starts by sending a greeting to the client.  This is the only
thing that doesn't adhere to the basic syntax.  It contains the word
@samp{fsh} followed by the version number of the protocol, which is 1.
The client does not respond.

@example
fsh 1
@end example

@section Session management

Each remote command that should be executed is contained in a session.
There can be several simultaneous sessions.  The client associates each
session with a unique session id, which is an integer.

A new session is created by sending a @code{new} command to the server.

@example
new @var{session-id} @var{command}
@end example

The @var{command} is a string, suitable to pass to whatever
@samp{$SHELL} is set to on the remote system.

Once a session is established data can be sent by either the client or
the server.  The client uses @code{stdin} to send data.  The server uses
@code{stdout} or @code{stderr}.  The format of these three commands is
the same:

@example
stdin @var{session-id} @var{strlen}H@var{data}
stdout @var{session-id} @var{strlen}H@var{data}
stderr @var{session-id} @var{strlen}H@var{data}
@end example

@var{strlen} is a decimal string, that specifies how long @var{data} is.
The @var{data} can contain any byte, including NUL, newline and carriage
return.

The client can send signals to the session:

@example
signal @var{session-id} @var{signal-name}
@end example

The following values are defined for @var{signal-name}:

@itemize @bullet
@item HUP
@item INT
@item QUIT
@item ILL
@item TRAP
@item IOT
@item BUS
@item FPE
@item KILL
@item USR1
@item SEGV
@item USR2
@item PIPE
@item ALRM
@item TERM
@item CHLD
@item CONT
@item STOP
@item TSTP
@item TTIN
@item TTOU
@item URG
@item XCPU
@item XFSZ
@item VTALRM
@item PROF
@item WINCH
@item IO
@item PWR
@end itemize

End-of-file can be specified for each of the three data channels
separately:

@example
eof-stdin @var{session-id}
eof-stdout @var{session-id}
eof-stderr @var{session-id}
@end example

When the child dies the server will send the exit status to the client.

@example
exit @var{session-id} @var{exit-status}
signal-exit @var{session-id} @var{signal-name}
@end example

@ignore
@c FIXME: we should send the core-dumped flag.  Patches welcome.
The @var{core-dumped} flag is 1 if a core file was generated, 0 if no
core was generated (or if the remote implementation is unable to
determine if a core was generated or not).  Please note, however, that
the flag is not currently sent over the protocol.
@end ignore

@section Session termination

The server always sends an end-of-session to the client when it discards
a session.

@example
eos @var{session-id}
@end example

The @code{eos} will be generated spontaneously by the server when it has
sent @code{eof-stdout}, @code{eof-stderr} and one of @code{exit} or
@code{signal-exit}.  The client should never reuse a session id until it
has seen an @code{eos} from the server.

The client can also request that the session is terminated by sending an
@code{eos} to the server.  This should only be used in abnormal
situations, such as if the fsh program responsible for this session
unexpectedly died (indicating that there is nobody awaiting the result
of the program).  When the server receives an @code{eos} it will kill
the program (with something similar to @code{kill -KILL @var{pid}}) if
it is alive, close all ptys to the program (without trying to drain
them), and send back an @code{eos} response to the client as
confirmation.

@section Flow control

To avoid pileup of unprocessed data in the endpoints (stdin data in
@code{in.fshd} and stdout/stderr data in @code{fsh}) a strict flow
control protocol must be adhered to.

When a session is created it is initially allowed to send 128 KB (that
is, 131072 bytes) to the stdin of the remote system.  When it receives
an @code{stdin-flow} statement the limit is increased to the value sent
in it.  The @code{fsh} process is responsible for counting the bytes and
pause if it doesn't receive an @code{stdin-flow} statement in time.  The
@code{in.fshd} process is responsible for sending @code{stdin-flow}
statements.  They should ideally be sent in advance, so that
@code{in.fshd} always maintains a buffer of pending input to the
process.

Similarly, @code{in.fshd} may only send 128 KB of stdout data and 128 KB
of stderr data, until it receives @code{stdout-flow} and
@code{stderr-flow} commands from @code{fsh}.

@example
stdin-flow session-no new-limit
stdout-flow session-no new-limit
stderr-flow session-no new-limit
@end example

Please note that @code{fshd} is not directly involved in the flow
control protocol.  It only relays messages between all the @code{fsh}
processes an the @code{in.fshd} process.

These limits exists so that both @code{in.fshd} and all @code{fsh}
processes always should be able to read anything that @code{fshd} wants
to send to them.  The initially allowed window of 128 KB is included so
that a new session can start sending data at once, without a need for
any round-trip delay.

@node Local protocol
@chapter The local protocol

The protocol used between @code{fsh} and @code{fshd} is identicaly to
the remote protocol, with one exception: there is no session number.

@code{fshd} creates an AF_UNIX socket in
@file{/tmp/fshd-@var{UID}/@var{server}.@var{method}.@var{login}} (with
funny characters encoded with a QP-like encoding).  The protection of
@file{/tmp/fshd-@var{UID}} is set so that it is only accessible by the
user with the proper uid.
     
@contents
@bye
