\typeout{Original Yodl file: ../../release.yo}








\hfuzz=70pt
\addtolength{\textheight}{2cm}
\addtolength{\textwidth}{4cm}
\addtolength{\hoffset}{-2cm}

   
    
    \documentclass[a4paper]{report}
\usepackage{epsf}
\usepackage{stealth}

\usepackage[T1]{fontenc}
\usepackage{makecell}

\input{/usr/share/yodl/xlatin1.tex}
\setlength{\parskip}{3mm} % height between par
\setlength{\parindent}{0mm} % no par indent

\title{Stealth V.4.04.00}
\author{Frank B. Brokken\ \\ 
University of Groningen}
\date{2005-2025}
\begin{document}\maketitle


\tableofcontents


\cleardoublepage\chapter{Introduction}
    \typeout{Original Yodl file: intro}Welcome to \textbf{stealth}. The program \textbf{stealth} implements a file integrity
scanner. The acronym \textbf{stealth} can be expanded to

\begin{center}
\section*{SSH-based Trust Enforcement Acquired through a Locally Trusted Host.}
\end{center}

This expansion contains the following key terms:

\begin{itemize}
    \item  \texttt{SSH-based}: The file integrity scan is (usually) performed over an
ssh-connection. Usually the computer being scanned (called the \emph{client}) and
the computer initiating the scan (called the \texttt{monitor}) are different
computers. 
    \item  The client should accept incoming ssh-connections from the
monitor. The monitor doesn't have to (and shouldn't, probably).
    \item  \texttt{Trust Enforcement}: following the scan, `trust' is enforced in the
client, due to the integrity of its files.
    \item  \texttt{Locally Trusted Host}: the client apparently trusts the monitor
to use an ssh-connection to perform commands on it. The client therefore
\emph{locally trusts} the monitor. Hence, \emph{locally trusted host}.
    \end{itemize}

\textbf{stealth} is based on an idea by \emph{Hans Gankema} and \emph{Kees Visser},
both at the Center for Information Technology of the University of Groningen.

\textbf{stealth}'s main task is to perform file integrity tests. However, the
testing will leave virtually no sediments on the tested computer. Therefore,
\textbf{stealth} has \emph{stealthy} characteristics. I consider this an important
security improving feature of \textbf{stealth}.

The monitor itself only needs two kinds of outgoing services:
\textbf{ssh}(1) to reach its clients, and some mail transport agent (e.g.,
\textbf{sendmail}(1)) to forward its outgoing mail to some mail-hub.

Here is what happens when \textbf{stealth} is run:
    \begin{itemize}
    \item  First, the \emph{policy} file is read. For each client a policy file is
defined, specifying the actions to be performed, and specifying the values of
several variables used by \textbf{stealth}.

\item  If the command-line option \texttt{+NOTRANS(-\{\}-\{\})daemon $<$uds$>$} is specified, \textbf{stealth}
runs as a daemon process, using the Unix Domain Socket (\texttt{$<$uds$>$}) for
communication with \textbf{stealth} processes running in IPC mode.

If access to the Unix Domain Socket defined by Stealth running in daemon mode
should be restricted, it can be defined in a directory with is only accessible
to the user running Stealth (this will often be the root-user).

When running in daemon mode, \texttt{+NOTRANS(-\{\}-\{\})repeat $<$seconds$>$} may be specified to rerun
the integrity scan every \texttt{$<$seconds$>$} seconds. If an integrity scan is being
performed when, according to the repeat interval the next integrity scan is
due, then the current scan is first completed. Once completed, the next
integrity scan will be performed after \texttt{seconds} seconds.

\item  Next, the monitor opens a command shell on the client using
\textbf{ssh}(1), and a command shell on the monitor computer itself using
\textbf{sh}(1).

\item  Once the command shells are available, commands defined in the policy
file are executed in their order of appearance. Examples are given
below. Normally, return values of the programs are tested. When return values
are to be tested \textbf{stealth} terminates when a non-zero return value is sensed. If
this happens, a message stating the reason why \textbf{stealth} terminated is written to
the report file (and into the mail sent by \textbf{stealth}). In some cases (e.g., when the
report file could not be written), the message is written to the standard
error stream.

\item  Very often integrity tests can be controlled using \textbf{find}(1),
calling programs like \textbf{ls}(1), \textbf{sha1sum}(1) or its own \texttt{-printf} method
to produce file-integrity related statistics. Most of these programs write
file names at the end of generated lines. This characteristic is used by one
of \textbf{stealth}'s internal routines to detect changes in the generated output. Such
changes could indicate some harmful intent, like an installed \emph{root-kit}.

\item  When changes are detected, they are logged in a \emph{report file}, to
which information is always appended. \textbf{Stealth} never reduces the report file's size
or rewrites its contents. When information is added to the report file (beyond
a plain time stamp) the newly added information is e-mailed to a configurable
e-mail address for further (human) processing. Usually the e-mail is sent to
the systems manager of the tested client. \textbf{Stealth} follows the `dark cockpit'
approach in the sense that no mail is sent when no changes were detected.

\item  Report and other log-files may safely be rotated between a pair of
\texttt{+NOTRANS(-\{\}-\{\})suspend} and \texttt{+NOTRANS(-\{\}-\{\})resume} commands (see below at the section
\ref{ROTATE}).
    \end{itemize}

Instead of running in daemon mode, \textbf{stealth} may also run in `foreground' mode.
In foreground mode the option \texttt{+NOTRANS(-\{\}-\{\})daemon} is not specified. When running in
foreground mode \textbf{stealth} either performs one integrity scan (and terminates) or, if
the \texttt{+NOTRANS(-\{\}-\{\})repeat} option has been specified, it repeatedly performs integrity
scans, at intervals determined by the \texttt{+NOTRANS(-\{\}-\{\})repeat} and \texttt{+NOTRANS(-\{\}-\{\})random-interval}
options. When \texttt{+NOTRANS(-\{\}-\{\})repeat} is specified with \textbf{stealth} running in foreground mode a
prompt is shown (i.e., `\texttt{? }') with  \textbf{stealth} terminating after pressing the
\texttt{Enter}-key.

Alternatively, \textbf{stealth} may run in `inter process communication' mode (IPC
mode). IPC mode is characterized by using one of the command-line options
\texttt{+NOTRANS(-\{\}-\{\})reload, +NOTRANS(-\{\}-\{\})rerun, +NOTRANS(-\{\}-\{\})suspend, +NOTRANS(-\{\}-\{\})resume} or \texttt{+NOTRANS(-\{\}-\{\})terminate}. In IPC-mode \textbf{stealth}
communicates with an existing \textbf{stealth} daemon, using the Unix Domain Socket defined
by the \textbf{stealth} daemon. These options require but one argument: the location of the
Unix Domain Socket defined by a running \textbf{stealth} daemon.
    \begin{itemize}
    \item  When started using the \texttt{+NOTRANS(-\{\}-\{\})reload $<$uds$>$} command-line option, the
stealth daemon that created the Unix Domain Socket reloads its policy file
(and skip-file), immediately followed by another integrity scan;
    \item  When started using the \texttt{+NOTRANS(-\{\}-\{\})rerun $<$uds$>$} command-line option, the
stealth daemon that created the Unix Domain Socket performs another integrity
scan;
    \item  When started using the \texttt{+NOTRANS(-\{\}-\{\})terminate $<$usd$>$} command-line option, the
stealth daemon that created the Unix Domain Socket terminates.
    \end{itemize}

The options \texttt{+NOTRANS(-\{\}-\{\})suspend} and \texttt{+NOTRANS(-\{\}-\{\})resume} (see section \ref{ROTATE}) were
implemented to allow safe rotations of \textbf{stealth}'s log-files.

\section{What's new in Stealth V.4.04.00}
    \typeout{Original Yodl file: whatsnew}    With 4.00.00:

\begin{itemize}
    \item  Version 3.00.00 was only short-lived. The inter-process communication
        using signals never ran smoothly. Version 4.00.00 re-implements \textbf{stealth}'s
        inter-process communication using Unix Domain Sockets.
    \item  Previously required absolute file paths are no longer required. When
        relative file paths are used with the \textbf{stealth} daemon or with \textbf{stealth}
        performing an integrity scan as foreground process they are
        interpreted relatively to the current working directory.  Relative
        file locations for options specified in the second section of the
        policy file are interpreted relative to the location of the policy
        file, and relative path specifications used in the first section of
        the policy file are interpreted relative to the policy file's \texttt{USE
        BASE}. 
    \item  The README.flow file is provided with several separately provided
        illustrative images in the distribution-provided directory
        \texttt{documentation/images}.
    \item  Specifications for the logrotate specifications should use
        '\texttt{copytruncate}' and '\texttt{sharedscripts}' (see section \ref{ROTATE}
        for an example)
    \item  Examples in the manual still use \texttt{sha1sum} when checking hash
        values. Stronger hash functions (like \texttt{sha256sum}) might be
        preferred in practice. When updating existing policy files to use
        \texttt{sha256sum} rather than \texttt{sha1sum} realize that \texttt{sha256sum's}
        hash values are longer than \texttt{sha1sum's} hash values, and that
        therefore log files obtained when \texttt{sha1sum} was used are
        incompatible with log files obtained when \texttt{sha256sum} was used. In
        practice this means that new log files need to be generated,
        disregarding any previously geneerated log files.
    \end{itemize}

\cleardoublepage\chapter{Installation}
\typeout{Original Yodl file: install/intro}This chapter describes \textbf{stealth}'s compilation and installation. 

\section{Compiling and installing Stealth}\label{COMPILING}
    \typeout{Original Yodl file: install/compile}After downloading the \textbf{stealth} archive, it should be unpacked. The name of
the archive is of the form \texttt{stealth-4.04.00.tar.gz}, where \texttt{4.04.00}
is a version number. Below, \texttt{4.04.00} should be altered into the version
of the archive that is actually used.

Required, non-standard software, for compiling \textbf{stealth} is summarized in the file
\texttt{required}, which is included in the source file distribution. Currently,
its contents are:

\begin{verbatim}
This file lists non-standard software only. Thus, standard utilities like cp,
mv, sed, etc, etc, are not explicitly mentioned. Neither is the gcc compiler
explicitly mentioned, but a fairly recent one is assumed.

Required software for building Stealth:
---------------------------------------

Latest versions of:

    libbobcat-dev   (cf. https://fbb-git.gitlab.io/bobcat/)
    icmake          (cf. https://fbb-git.gitlab.io/icmake/)
    yodl            (cf. https://fbb-git.gitlab.io/yodl/)

To construct the user guide:

    texlive-latex-base,
    texlive-generic-recommended, 
    texlive-latex-recommended,
    texlive-latex-extra,
    texlive-fonts-recommended,
    cm-super-minimal,
    ghostscript


\end{verbatim}


\begin{itemize}
    \item  \textbf{Stealth} compilation is controlled by \textbf{icmake}(1). The program
maintenance utility \textbf{icmake}(1) can be obtained at
\texttt{https://fbb-git.gitlab.io/icmake/}, and it is also available in several
Linux distributions (e.g., Debian, Ubuntu);

\item  Determine a directory where the files in \textbf{stealth}'s archive ashould be
stored. E.g., if the files in the archive should be stored under \texttt{/tmp}
(and assuming the archive itself is stored in \texttt{/tmp} as well) then do:
        \begin{verbatim}

    cd /tmp
    tar xzf stealth-_CurVers_.tar.gz
        
\end{verbatim}

    This creates a subdirectory \texttt{stealth} containing \textbf{stealth}'s sources;

\item  Change-dir to that directory:
        \begin{verbatim}

    chdir stealth
        
\end{verbatim}


\item  Check the contents of the files \texttt{INSTALL.im} and \texttt{icmconf}, and
verify that all \texttt{\#defines} match your computer's file system and
software. 

When compiling \textbf{stealth}, the
\texttt{bobcat}\footnote{https://fbb-git.gitlab.io/bobcat/} header files must be
available. When \textbf{stealth} is run it is dynamically linked against the bobcat
library. \textbf{Bobcat} can be downloaded from 
\texttt{https://gitlab.com/fbb-git/bobcat/} (and follow its installation
instructions). Alternatively, bobcat may be available in your distribution,
(e.g.,  Debian or Ubuntu). Make sure to install both the run-time
(\textbf{bobcat\_...})  and the development (\textbf{bobcat-dev\_...}) versions.

\item  Execute the command
        \begin{verbatim}

    ./build program strip
        
\end{verbatim}

    This command by default creates the
program \textbf{./tmp/bin/binary}.

\item  To install \textbf{stealth} and its documentation, several commands are available:
        \begin{verbatim}

   ./build install program [path] - installs the program as `path'
                                (by default as `/usr/bin/stealth')
   ./build install man [base]   - install the man pages below `base'
                                (by default below `/usr/share/man/man1')
   ./build install manual [base]- install the manual below `base'
                                (by default below 
                                    `/usr/share/doc/stealth-doc/manual')
   ./build install std [base]   - install standard docs below `base'
                                (by default below `/usr/share/doc/stealth')
   ./build install extra [base] - install extra docs below `base'
                                (by default below 
                                    `/usr/share/doc/stealth-doc')
        
\end{verbatim}

    \end{itemize}

\cleardoublepage\chapter{Granting access}
\typeout{Original Yodl file: access/intro}Access to clients should be granted using the \texttt{ssh} protocol.

Clients must allow the monitor to connect using \texttt{ssh}. \textbf{Stealth} connects to its
clients using ssh certificates, after the monitor's public SSH-key has been
transferred to the clients.

\subsection{The monitor's user: creating an ssh-key}
    \typeout{Original Yodl file: access/monitor}    The monitor's user calling \textbf{stealth} to scan the client must first generate
an \texttt{ssh-keypair}:
        \begin{verbatim}
    ssh-keygen -t rsa
\end{verbatim}
 
    By default this generates a public/private ssh key-pair in the directory
\texttt{.ssh} in the user's home directory. The program asks for a
\emph{passphrase}. A passphrase can be defined (in which case it must be proviced
when \textbf{stealth} is started) or, if the security if the monitor is sufficiently
guaranteed, it can remain empty. To generate an ssh-key without passphrase
simply press \texttt{Enter} in response to the question
        \begin{verbatim}
    Enter passphrase (empty for no passphrase):
\end{verbatim}

    (a confirmation is required: just press \texttt{Enter} again).

\texttt{Ssh-keygen} then  returns a key fingerprint, e.g.,
        \begin{verbatim}
    03:96:49:63:8a:64:33:45:79:ab:ca:de:c8:c8:4f:e9 user@monitor
\end{verbatim}

    which may be saved for future reference.

In the user's \texttt{.ssh} directory the files \texttt{id\_rsa} and \texttt{id\_rsa.pub}
are now created, which completes the preparations at the monitor.

If, instead of running \textbf{stealth} in daemon mode it is preferred to let \textbf{stealth} perform
single, but automated integrity scans, then new \textbf{ssh}(1) connections may be
difficult to establish if the used ssh-key is passphrase-protected. To
implement this scenario (i.e., automated integrity scans using passphrase
protected ssh-keys) the program \textbf{ssh-cron}(1) can profitably be used. 

\subsection{The client's account: accepting ssh from the monitor's user}
    \typeout{Original Yodl file: access/client}    Next, at the client's account where \textbf{stealth}'s \texttt{ssh} command connects to (see
also the \texttt{USE SSH} specification in section \ref{USE}) ssh-access must be
granted to the monitor's user. To do so, the monitor user's file
\texttt{\textasciitilde{}/.ssh/id\_rsa.pub} is added to the client account user's file
\texttt{\textasciitilde{}/.ssh/authorized\_keys}:
        \begin{verbatim}
    # transfer user@monitor's file id_rsa.pub to the client's /tmp
    # directory. Then do:

    cat /tmp/id_rsa.pub >> /home/account/.ssh/authorized_keys
\end{verbatim}


This allows the user at the monitor to login at the account at the
client without specifying the client account's password (of course, if the
ssh-key is passphrase protected that passphrase must still be provided at the
monitor when starting \textbf{stealth}).

\subsection{Logging into the account@client account}
    \typeout{Original Yodl file: access/login}    When user@monitor now issues, for the first time, the command
        \begin{verbatim}
    ssh account@monitor
\end{verbatim}

    \texttt{Ssh} responds like this:
        \begin{verbatim}
    The authenticity of host 'monitor (xxx.yyy.aaa.bbb)' can't be
    established.
    RSA key fingerprint is c4:52:d6:a3:d4:65:0d:5e:2e:66:d8:ab:de:ad:12:be.
    Are you sure you want to continue connecting (yes/no)?
\end{verbatim}

    Answering \texttt{yes} results in the message:
        \begin{verbatim}
    Warning: Permanently added 'monitor,xxx.yyy.aaa.bbb' (RSA) to the
    list of known hosts.
\end{verbatim}


The next time a login is attempted, the authenticity question is not asked
anyore. However, the proper value of the host's RSA key fingerprint (i.e., the
key fingerprint of the \emph{client} computer) should \emph{always} be verified to
prevent \emph{man in the middle} attacks. The proper value may be obtained at the
client by issuing there the command
        \begin{verbatim}
    ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
\end{verbatim}

    This should show the same value of the fingerprint as shown when the
first \texttt{ssh} connection was established. E.g.,
        \begin{verbatim}

    1024 c4:52:d6:a3:d4:65:0d:5e:2e:66:d8:ab:de:ad:12:be ssh_host_rsa_key.pub
\end{verbatim}


\subsection{Using the proper shell}
    \typeout{Original Yodl file: access/using}    On order to minimize the amount of clutter and possibly complications when
only a simple command-shell is required for executing commands, it is
suggested to use a \textbf{bash}(1) shell when logging into \texttt{account@client}'s
account.

When another shell is already used for \texttt{account@client}, then an extra
account (optionally using the same \texttt{UID} as the original account, but using
\textbf{sh}(1) as the shell), could be defined in the client's \texttt{/etc/passwd}
file. In the \textbf{passwd}(5) file this could, e.g., be realized for \emph{root} as
\emph{rootsh} as follows:\ \\ 
        \begin{verbatim}
    rootsh:x:0:0:root:/root:/bin/bash
\end{verbatim}

    If shadow passwording is used, a matching entry in the \texttt{/etc/shadow}
file is required as well.

\cleardoublepage\chapter{The `policy' file}
\typeout{Original Yodl file: policy/intro}    \textbf{Stealth} uses a policy file consisting of two sections, the second
section is optional, and starts at a line merely containing \texttt{\%\%}.

Each policy file is uniquely associated with a host to be tested. Each host
may have multiple policy files, though. In that case, each policy file defines
its own set of checks to be performed.

\begin{itemize}
    \item  The policy file's first section consists of two sets of data: \emph{use
directives} (starting with the keyword \textbf{USE}) and \emph{commands}. 

\item  The (optional) second section starts at a line merely containing
\texttt{\%\%}. Following this separating line several long option specifications can
be entered (cf. section \ref{OPTIONS}). Options
specified on the command-line take priority over options specified 
in the policy file. Although the \texttt{+NOTRANS(-\{\}-\{\})reload} option reloads the policy file,
it will not change option values originally specified as command-line options.

This section may contain specifications of the \texttt{skip-files} and \texttt{log}
options.  Relative file locations specified for these options are interpreted
relative to the location of the policy file. E.g., if the policy file argument
is specified as \texttt{/root/client/policy} then the specification \texttt{log:
client.log} results in \textbf{stealth} writing its logs into the file
\texttt{/root/client/client.log}.
    \end{itemize}

The policy file's first section consists of three sets of data: \emph{define
directives} (starting with the keyword \textbf{DEFINE}), \emph{use directives}
(starting with the keyword \textbf{USE}) and \emph{commands}.

Directives are written in capitals, and should appear exactly as written
below.

Blank lines and information beyond hash-marks (\#) are ignored, while lines
following lines terminating in backslashes (\textbackslash{} ) will be concatenated (\emph{en
passant} removing these backslashes). Leading white space on lines of the
policy file is ignored.

\section{DEFINE directives}
    \typeout{Original Yodl file: policy/defines}    \texttt{DEFINE} directives can be used to define symbols for longer strings.
A \texttt{DEFINE} directive is constructed as follows:
        \begin{verbatim}
    DEFINE name     that what is defined by `name'
\end{verbatim}

    Here,
    \begin{itemize}
    \item  the \texttt{name} following \texttt{DEFINE} is the symbol that may be used in
\texttt{USE} directives (see below) and \texttt{commands} (see below). 
    \item  \texttt{DEFINE} symbols can be used in other \texttt{DEFINE} symbols. However,
it is the responsibility of the policy file's author to make sure that
(indirect) circular definitions are avoided. E.g., after:
        \begin{verbatim}
    DEFINE A    ${B}
    DEFINE B    ${A}
    DEFINE C    ${C}

    USE MAILARGS ${A} ${B} ${C}
\end{verbatim}

    \texttt{MAILARGS} will be expanded to 
        \begin{verbatim}
     ${A} ${A} ${C}
\end{verbatim}

    \item  The text following \texttt{DEFINE name} is then inserted literally into
the \texttt{USE} directive or \texttt{command}.

Example:
        \begin{verbatim}
    DEFINE  SSH         /usr/bin/ssh frank@localhost -q
    DEFINE  EXECSHA1     -xdev -perm /111  -type f -exec /usr/bin/sha1sum {} \;
\end{verbatim}

    The symbols defined by \texttt{DEFINE} directives may consist of letters,
digits and the underscore characters (\texttt{\_}).  In the definition of the symbol
any character can be used. However, initial and/or trailing blanks are removed
from definitions.

To insert a definition into a \texttt{USE} directive or \texttt{command} use the form
        \begin{verbatim}
    ${name}
\end{verbatim}

    E.g., \texttt{\$\{EXECSHA1\}}. Concrete examples are provided below.
    \end{itemize}

\section{USE directives}\label{USE}
    \typeout{Original Yodl file: policy/use}    \texttt{USE} directives provide \textbf{stealth} with arguments which
may be conditional to a certain installation. The following \textbf{USE} directives
are supported:
    \begin{itemize}
    \item  \textbf{USE BASE} \texttt{basedirectory}

\textbf{BASE} defines the directory from where \textbf{stealth} operates. All relative
path specifications in this section of the policy file are interpreted
relative to \textbf{BASE}. \emph{By default} this is the directory where \textbf{stealth} was
started.

If necessary, \textbf{stealth} creates all \textbf{BASE} and other directories below
\texttt{BASE}. 

Example: using the specification
        \begin{verbatim}
    USE BASE /root/client
\end{verbatim}

    results in all information generated by \textbf{stealth} being written in or below the
directory \texttt{/root/client}.

\item  \textbf{USE DD} \texttt{$<$dd$>$}\ \\ 
        The \textbf{DD} specification uses \texttt{/bin/dd} as default, and defines the
location of the \textbf{dd}(1) program, both on the server and on the client. The
\textbf{DD} program is used to copy files between the client and the monitor
without creating separate ssh-connections. The \textbf{DD} program is only
used by \textbf{stealth} for the \texttt{PUT} and \texttt{GET} commands, described below.

Example showing the default:\begin{verbatim}
    USE DD /bin/dd
\end{verbatim}


\item  \textbf{USE DIFF} \texttt{path-to-diff}

The \textbf{DIFF} specification uses \texttt{/usr/bin/diff} as default,
and defines the location of the \textbf{diff}(1) program. The
\textbf{diff}(1) program is used to compare a formerly created logfile of an
integrity check to a newly created logfile.

Example showing the default:
        \begin{verbatim}
    USE DIFF /usr/bin/diff
\end{verbatim}


\item  \textbf{USE DIFFPREFIX} \texttt{$<$prefix$>$}

The \textbf{DIFFPREFIX} specification defines the size of the prefix added
by the \texttt{DIFF} command to lines produced by commands executed through \textbf{stealth}.
The default \texttt{/usr/bin/diff} program prefixes lines by either `\texttt{$>$ }' or
`\texttt{$<$ }'. The default value for \texttt{$<$prefix$>$} therefore equals 2.

Example showing the default:
        \begin{verbatim}
    USE DIFFPREFIX 2
\end{verbatim}


\item  \textbf{USE EMAIL} \texttt{address}

The \textbf{EMAIL} specification defines the email-address to e-mail the
client's integrity scan report to. Mail is only sent when information has
changed.

Example showing the default:
        \begin{verbatim}
    USE EMAIL root
\end{verbatim}


\item  \textbf{USE MAILER} \texttt{mailer}

The \textbf{MAILER} specification defines the program that is used to send
the mail to the \textbf{EMAIL}-address. By default this is \textbf{/usr/bin/mail}(1). 
The \textbf{MAILER} program is called as follows:
        \begin{verbatim}
    MAILER  MAILARGS EMAIL
\end{verbatim}

    (\texttt{MAILARGS}: see below). The information to be mailed is read from
\texttt{MAILER}'s standard input stream.

Example showing the default:
        \begin{verbatim}
    USE MAILER /usr/bin/mail
\end{verbatim}


\item  \textbf{USE MAILARGS} \texttt{arguments}
        The \textbf{MAILARGS} specification defines the arguments to be
to be passed to the \texttt{MAILER} program. By default this is 
        \begin{verbatim}
    USE MAILARGS -s "STEALTH scan report"
\end{verbatim}
 
    Note that blanks may be used in the subject specification: use double or
single quotes to define elements containing blanks. Use \texttt{\textbackslash{}"} to use a double
quote in a string that is itself delimited by double quotes, use \texttt{\textbackslash{}'} to use
a single quote in a string that is itself delimited by single quotes. 

Subtlety: in constructions like 
        \begin{verbatim}
    USE MAILARGS " 't was brillig " and 't went well
\end{verbatim}

    the following arguments are passed to \texttt{MAILER}:
        \begin{itemize}
        \item  \texttt{" 't was brillig "}
        \item  \texttt{and}
        \item  \texttt{'t}
        \item  \texttt{went}
        \item  \texttt{well}
        \end{itemize}
    So, when single- and double-quoted strings overlap, the first string is
taken as a string, and the information beyond the first string is thereupon
interpreted. 

\item  \textbf{USE REPORT} \texttt{$<$file-spec$>$}\ \\ 
        \textbf{REPORT} defines the name of the reportfile. Information is always
appended to this file. At each \textbf{stealth} integrity scan a \emph{time marker line} is
written to the report file. Only when (in addition to the marker line)
additional information is appended to the report file the added contents of
the report file are mailed to the mail address specified in the \textbf{USE EMAIL}
specification. When a relative file specification is used it is interpreted a
location relative to the \texttt{USE BASE} specification.\ \\ 
    Example showing the default:\ \\ 
    \texttt{USE REPORT report}

\item  \textbf{USE SH} \texttt{$<$sh$>$}\ \\ 
        The \textbf{SH} specification uses \texttt{/bin/sh} as default, and defines the
command shell used by the monitor to execute commands on itself. This must be
an absolute path specification.\ \\ 
    Example showing the default:\ \\ 
    \texttt{USE SH /bin/sh}

\item  \textbf{USE SSH} \texttt{$<$user$>$}\ \\ 
        \textbf{The SSH specification has no default}, and \emph{must} be
specified. This must be an absolute path specification.  

Assuming the client \emph{trusts} the monitor (which is after all what this
program is all about, so this should not be a very strong assumption),
preferably the public ssh key of the monitor should be placed in the
client's root \texttt{.ssh/authorized\_keys} file, granting the monitor root access
to the client. Root access is normally needed to gain access to all
directories and files of the client's file system.

In practice, connecting to an account using the \textbf{sh}(1) shell is
preferred. When another shell is already used by that account, one should make
sure that its shell doesn't define its own redirections for standard input
and standard output. One way to accomplish that is for force the execution of
\texttt{/bin/sh} in the \textbf{USE SSH} specification.

An example of an \texttt{SSH} specification to scan a localhost is:
        \begin{verbatim}

    USE SSH root@localhost -T -q                # root's shell is /bin/sh
\end{verbatim}


The same, now explicitly using \texttt{/bin/bash}:
        \begin{verbatim}

    USE SSH root@localhost -T -q exec /bin/bash # root uses another shell
\end{verbatim}


Alternatively, \texttt{+NOTRANS(-\{\}-\{\})noprofile} can be specified to prevent any
profile-initialization: 
        \begin{verbatim}

    USE SSH root@localhost -T -q exec /bin/bash --noprofile
\end{verbatim}
    
    \end{itemize}

In some installations \textbf{stealth} is used to inspect the monitor itself, even
though this is \emph{not} recommended, as it breaks one of the main reasons for
\textbf{stealth}'s existence. But in those situations (so, where \textbf{stealth} is used to monitor the
integrity of the \texttt{localhost}), \texttt{/bin/bash} could be specified at the
\texttt{USE SSH} directive. For example:
        \begin{verbatim}
    # For stealth inspecting localhost:
        USE SSH /bin/bash --noprofile
\end{verbatim}


\section{Commands}\label{COMMANDS}
    \typeout{Original Yodl file: policy/commands}    Following the \textbf{USE} specifications, \emph{commands} can be specified. The
commands are executed in their order of appearance in the policy
file. Processing continues until the last command has been processed or until
a tested command (see below) returns a non-zero return value.

\subsection{LABEL commands}
        \typeout{Original Yodl file: policy/label}    The following \textbf{LABEL} commands are available:
    \begin{itemize}
    \item  \textbf{LABEL} \texttt{text}

This defines a text-label which is written to the \textbf{REPORT} file,
just before the output generated by the next \textbf{CHECK}-command. If the next
\textbf{CHECK}-command generates no output, the label is not written to the
\textbf{REPORT}-file. Once a \textbf{LABEL} has been defined, it is used until it is
redefined by the next \textbf{LABEL} command. Use an empty \textbf{LABEL} command to
suppress printing labels.

The text may contain \texttt{\textbackslash{}n} characters (two characters) which are
transformed to a newline character.
    \item  \textbf{LABEL}

As noted, this clears a previously defined \texttt{LABEL} command.
    \end{itemize}

Examples:
        \begin{verbatim}

    LABEL Inspecting files in /etc\nIncluding subdirectories
    LABEL
\end{verbatim}

    The latter \textbf{LABEL} command clears the text of the former \textbf{LABEL}
command.

\subsection{LOCAL commands}
        \typeout{Original Yodl file: policy/local}    \textbf{LOCAL} commands can be used to specify commands that are 
executed on the monitor itself. The following \textbf{LOCAL} commands are
available: 
    \begin{itemize}
    \item  \textbf{LOCAL} \texttt{command}

Execute \texttt{command} on the monitor, using the \textbf{SH} command
shell. The command must succeed (i.e., must return a zero exit value). 
    Example:
        \begin{verbatim}
    LOCAL mkdir /tmp/client
\end{verbatim}

    This command creates the directory \texttt{/tmp/client} on the monitor.

\item  \textbf{LOCAL NOTEST} \texttt{command}

Execute \texttt{command} on the monitor, using the \textbf{SH} command
shell. The command may or may not succeed.
    Example:
        \begin{verbatim}
    LOCAL NOTEST mkdir /tmp/subdir
\end{verbatim}

    This command creates \texttt{/tmp/subdir} on the monitor. The command
fails if the directory cannot be created, but this does not terminate
\textbf{stealth}.

\item  \textbf{LOCAL CHECK} {[}\textbf{LOG =}{]} \texttt{logfile {[}pathOffset{]} command}

Execute \texttt{command} on the monitor, using the \textbf{SH} command
shell. The command must succeed. The output of this command is compared to the
output of this command generated during the previous integrity check run by
\textbf{stealth}.

The phrase \textbf{LOG =} is optional. When a relative file location is
specified at \texttt{$<$file-spec$>$} it is interpreted relatively to the \texttt{USE BASE}
path specification. 

\texttt{PathOffset} is also optional. If specified it defines the (0-based)
offset where path-names of inspected files start in lines produced by
\texttt{$<$command$>$}. By default \textbf{stealth} assumes that the first occurrence of a forward
slash defines the first character of the path-names of inspected files.

For example, if diff-output looks like this:
        \begin{verbatim}

    01234567890123456789012345678901234567890 (column offsets, not part of 
                                               the diff-output)

    33c33
    < 90d8b506d249634c4ff80b9018644567  filename-specification
    ---
    > b88d0b77db74cc4a742d7bc26cdd2a1e  filename-specification
\end{verbatim}

    then the specification
        \begin{verbatim}
    LOCAL CHECK logfile 36 command-to-be-executed
\end{verbatim}

    informs \textbf{stealth} where to find the filename specifications in the
diff-output. Using the standard \texttt{/usr/bin/diff} command, this offset equals
2 + the offset of the \texttt{filename-specification} found in
\texttt{command-to-be-executed}. 

If the command does not succeed a \emph{warning} message is written to the report
file. The warning message informs the reader that `remaining results might be
forged:
        \begin{verbatim}
    *** BE CAREFUL *** REMAINING RESULTS MAY BE FORGED
\end{verbatim}

    This situation may occur, e.g., if an essential program (like \texttt{sha1sum})
was transferred to the monitor, and it was apparently modified since the
previous check. Processing continues, but remaining checks performed at the
client computer should be interpreted with \emph{extreme} caution.

The output of this command is compared to the output of this command
generated during the previous run of \textbf{stealth}. Any differences are written
to \textbf{REPORT}. 

If differences were found, the existing \texttt{logfile} name is renamed to
\texttt{logfile.YYYYMMDD-HHMMSS}, with \texttt{YYYYMMDD-HHMMSS} the datetime-stamp at
the time \textbf{stealth} was run.

Over time, many \texttt{logfile.YYMMDD-HHMMSS} files could be accumulated.
It is up to the monitor's systems manager to decide what to do
with old datetime-stamped logfiles. For instance, the following script
removes  all \textbf{stealth} reports below the current directory that are
older than 30 days:
        \begin{verbatim}
    #/bin/sh
    FILES=`find ./ -path '*[0-9]' -mtime +30 -type f`

    if [ "$FILES" != "" ] ; then
        rm -f $FILES
    fi
\end{verbatim}


The \texttt{logfile} specifications may use relative and absolute paths. When
relative paths are used, these paths are relative to \textbf{BASE}. When the
directories implied by the \texttt{logfile} specifications do not yet exist, they
are created first.

Example:
        \begin{verbatim}
    LOCAL CHECK LOG = local/sha1sum sha1sum /tmp/sha1sum
\end{verbatim}

    This command will check the SHA1 sum of the \texttt{/tmp/sha1sum} program. The
resulting output is saved at \textbf{BASE}\texttt{/local/sha1sum}. The program must
succeed (i.e., \texttt{sha1sum} must return a zero exit-value).

\item  \textbf{LOCAL NOTEST CHECK}  {[}\textbf{LOG =}{]} \texttt{logfile {[}pathOffset{]} command}

Execute \texttt{command} on the monitor, using the \textbf{SH} command
shell. 

The phrase \textbf{LOG =} is optional. When a relative file location is
specified at \texttt{$<$file-spec$>$} it is interpreted relatively to the \texttt{USE BASE}
path specification. 

The command may or may not succeed. Otherwise, the program performs exactly
like the \textbf{LOCAL CHECK ...}  command, discussed above.

Example:
        \begin{verbatim}
    LOCAL NOTEST CHECK LOG=local/sha1sum sha1sum /tmp/sha1sum
\end{verbatim}

    This command will check the SHA1 sum of the \texttt{/tmp/sha1sum} program. The
resulting output is saved at \textbf{BASE}\texttt{/local/sha1sum}. The program may or may
not succeed (i.e., \texttt{sha1sum} may or may not return a zero exit-value).
    \end{itemize}

\subsection{REMOTE commands}
        \typeout{Original Yodl file: policy/remote}    Plain commands can be executed on the client computer by merely
specifying them. Of course, this means that programs called
\texttt{LABEL}, \texttt{LOCAL} \texttt{USE} or \texttt{DEFINE}, cannot be executed, since
these names are interpreted otherwise by \textbf{stealth}. It's unlikely that this
will cause problems. Remote commands must succeed (i.e., their return 
codes must be 0).

Remote commands are commands executed on the client using the \textbf{SSH}
shell. These commands are executed using the standard \texttt{PATH} set for the
\textbf{SSH} shell. However, it is advised to specify the full pathname to the
programs to be executed, to prevent ``trojan approaches'' where a trojan horse
is installed in an `earlier' directory of the \texttt{PATH}-specification than the
intended program.

Two special remote commands are \texttt{GET} and \texttt{PUT}, which can be used to
copy files between the client and the monitor.  Internally, \texttt{GET} and
\texttt{PUT} use the \texttt{DD} use-specification. If a non-default specification is
used, one should ensure that the alternate program accepts \textbf{dd}(1)'s \texttt{if=,
of=, bs=} and \texttt{count=} options. With \texttt{GET} the options \texttt{bs=, count=} and
\texttt{of=} are used, with \texttt{PUT} the options \texttt{bs=, count=} and \texttt{if=} are
used. Normally there should be no need to alter the default \texttt{DD}
specification.

The \texttt{GET} command may be used as follows:
    \begin{itemize}
    \item  \textbf{GET} \texttt{$<$client-path$>$ $<$local-path$>$}\ \\ 
    Copy the file indicated by \texttt{client-path} at the client to \texttt{local-path}
at the monitor. \texttt{client-path} must be the full path of an existing file
on the client, \texttt{local-path} may either be a local directory, in which case
the client's file name is used, or another file name may be specified, in
which case the client's file is copied to the specified local filename. If the
local file already exists, it is overwritten by the copy-procedure.

Example:
    \begin{verbatim}
    GET /usr/bin/sha1sum /tmp
\end{verbatim}

    The program \texttt{/usr/bin/sha1sum}, available at the client, is copied to
the monitor's \texttt{/tmp} directory. If copying fails for some reason, any
subsequent commands are skipped, and \textbf{stealth} terminates.

\item  \textbf{GET NOTEST} \texttt{$<$client-path$>$ $<$local-path$>$}\ \\ 
    Copy the file indicated by \texttt{client-path} at the client to \texttt{local-path}
at the monitor. \texttt{client-path} must be the full path of an existing file
on the client, \texttt{local-path} may either be a local directory, in which case
the client's file name is used, or another file name may be specified, in
which case the client's file is copied to the specified local filename. If the
local file already exists, it is overwritten by the copy-procedure.

Example:
    \begin{verbatim}
    GET NOTEST /usr/bin/sha1sum /tmp
\end{verbatim}

    The program \texttt{/usr/bin/sha1sum}, available at the client, is copied to the
monitor's \texttt{/tmp} directory. Remaining commands in the policy file are
executed, even if the copying process wasn't successful.
    \end{itemize}

The \texttt{PUT} command may be used as follows:
    \begin{itemize} 
    \item  \textbf{PUT} \texttt{$<$local-path$>$ $<$remote-path$>$}\ \\ 
    Copy the file indicated by \texttt{local-path} at the monitor to
\texttt{remote-path} at the client. The argument \texttt{local-path} must be the
full path of an existing file on the monitor. The argument \texttt{remote-path}
must be the full path to a file on the client. If the remote file already
exists, it is overwritten by \texttt{PUT}.

Example:
    \begin{verbatim}
    PUT /tmp/sha1sum /usr/bin/sha1sum
\end{verbatim}

    The program \texttt{/tmp/sha1sum}, available at the monitor, is copied to the
client as \texttt{usr/bin/sha1sum}. If the copying fails for some reason,
any subsequent commands are skipped, and \textbf{stealth} terminates.

\item  \textbf{PUT NOTEST} \texttt{$<$local-path$>$ $<$remote-path$>$}\ \\ 
    Copy the file indicated by \texttt{local-path} at the monitor to
\texttt{remote-path} at the client. The argument \texttt{local-path} must be the
full path of an existing file on the monitor. The argument \texttt{remote-path}
must be the full path to a file on the client. If the remote file already
exists, it is overwritten by \texttt{PUT}.

Example:
    \begin{verbatim}
    PUT NOTEST /tmp/sha1sum /usr/bin/sha1sum
\end{verbatim}

    Copy the file indicated by \texttt{local-path} at the monitor to
\texttt{remote-path} at the client. The argument \texttt{local-path} must be the full
path of an existing file on the monitor. The argument \texttt{remote-path} must
be the full path to a file on the client. If the remote file already exists,
it is overwritten by \texttt{PUT}. Remaining commands in the policy file are
executed, even if the copying process wasn't successful.
    \end{itemize}

Other commands to be executed on the client can be specified as follows:

\begin{itemize}
    \item  \texttt{command}

Execute `\texttt{command}' on the client, using the \textbf{SSH} command
shell. The command must succeed (i.e., must return a zero exit
value). However, any output generated by the command is ignored. 
    Example:
        \begin{verbatim}
    /usr/bin/find /tmp -type f -exec /bin/rm {} \;
\end{verbatim}

    This command will remove all ordinary files at and below the client's
\texttt{/tmp} directory.

\item  \textbf{NOTEST} \texttt{command}

Execute \texttt{command} on the client, using the \textbf{SSH} command
shell. The command may or may not succeed.

Example:
        \begin{verbatim}
    NOTEST /usr/bin/find /tmp -type f -exec /bin/rm {} \;
\end{verbatim}

    Same as the previous command, but this time the exit value of
\texttt{/usr/bin/find} is not interpreted.

\item  \textbf{CHECK}  {[}\textbf{LOG =}{]} \texttt{logfile {[}pathOffset{]} command}

Execute \texttt{command} on the client, using the \textbf{SSH} command
shell. 

The phrase \textbf{LOG =} is optional. When a relative file location is
specified at \texttt{$<$file-spec$>$} it is interpreted relatively to the \texttt{USE BASE}
path specification. 

\texttt{PathOffset} is also optional, and has the same meaning as for the \texttt{LOCAL
CHECK} command, described above.

The command must succeed. The output of this command is compared to the
output of this command generated during the previous run of \textbf{stealth}. Any
differences are written to \textbf{REPORT}. If differences were found, the existing
\texttt{logfile} name is renamed to \texttt{logfile.YYYYMMDD-HHMMSS}, with
\texttt{YYYYMMDD-HHMMSS} being the datetime-stamp at the time \textbf{stealth} was run.

Note that the command is executed on the client, but the logfile is kept
at the monitor. This command represents the core of the method implemented
by \textbf{stealth}: there will be no residues of the actions performed by \textbf{stealth} on client
computers.

Several examples (note the use of the backslash as line continuation
characters):
    
        \begin{verbatim}
    CHECK LOG = remote/ls.root  /usr/bin/find / \ 
            -xdev -perm /6111 -type f -exec /bin/ls -l {} \;
\end{verbatim}

    All suid/gid/executable files on the same device as the root-directory (/)
on the client computer are listed with their permissions, owner and size
information. The resulting listing is written on the file
\textbf{BASE}\texttt{/remote/ls.root}. 

This long command could be formulated shorter using a \texttt{DEFINE}:
        \begin{verbatim}
    DEFINE LSFIND   -xdev -perm /6111 -type f -exec /bin/ls -l {} \;
    CHECK remote/ls.root  /usr/bin/find / ${LSFIND}
\end{verbatim}


Another example:
        \begin{verbatim}
    DEFINE SHA1SUM -xdev -perm /6111 -type f -exec /usr/bin/sha1sum {} \;
    CHECK remote/sha1.root /usr/bin/find / ${SHA1SUM}
\end{verbatim}

    The SHA1 checksums of all suid/gid/executable files on the same device as
the root-directory (/) on the client computer are determined.  The resulting
listing is written on the file \textbf{BASE}\texttt{/remote/sha1.root}.

\item  \textbf{NOTEST CHECK}  {[}\textbf{LOG =}{]} \texttt{logfile {[}pathOffset{]} command}

Execute \texttt{command} on the client, using the \textbf{SSH} command
shell. 

The phrase \textbf{LOG =} is optional. When a relative file location is
specified at \texttt{$<$file-spec$>$} it is interpreted relatively to the \texttt{USE BASE}
path specification. 

\texttt{PathOffset} is also optional, and has the same meaning as for the \texttt{LOCAL
CHECK} command, described above. The command may or may not
succeed. Otherwise, the program acts identically as the \textbf{CHECK ...} command,
described above.
    Example (using the same \texttt{\$\{SHA1SUM\}})definition:
        \begin{verbatim}
    NOTEST CHECK LOG = remote/sha1.root /usr/bin/find / ${SHA1SUM}
\end{verbatim}

    The SHA1 checksums of all suid/gid/executable files on the same device as
the root-directory (/) on the client computer are determined.  The resulting
listing is written on the file \textbf{BASE}\texttt{/remote/sha1.root}. \textbf{stealth} will
not terminate if the \texttt{/usr/bin/find} program returns a non-zero exit value.
    \end{itemize}

\subsection{Preventing Controller Denial of Service (-{}-{}max-size)}
        \typeout{Original Yodl file: policy/preventing}Either by malicious intent or by accident (as happened to me) the monitor may
be a victim of a (self-inflicted) Denial of Service (DOS) attack. This DOS
attack may occur when the client (apparently) sends a never ending stream of
bytes in response to a \texttt{GET} or \texttt{REMOTE} command. Once one of my monitors
fell victim to this attack when a client's power went down and the monitor
kept on trying to read bytes from that client filling up the monitor's
disk....

This problem was of course caused by a programming error: while reading
information from a client \textbf{stealth} failed to check whether the reading had actually
succeeded. This bug has now been fixed, but an intentional DOS attack could
still be staged along this line when, e.g., the \textbf{find}(1) command is somehow
replaced by a manipulated version continuously writing information to its
standard output stream. Without further precaution \textbf{stealth} would receive a never
ending stream of bytes to be written to its `report' file, thus causing its
disk to fill up.

To prevent this from happening \textbf{stealth} now offers the \texttt{+NOTRANS(-\{\}-\{\})max-size}
command line option allowing the specification of the maximum size of a stream
of bytes received by \textbf{stealth} (e.g., a report or downloaded file). The
maximum is used for each individual download and can be specified in bytes
(using no suffix or the \texttt{B} suffix), kilo-bytes (using \texttt{K}), mega-bytes
(using \texttt{M}) or giga-bytes (using \texttt{G}). The default is set at 10M,
equivalent to the command line specification of \texttt{+NOTRANS(-\{\}-\{\})max-size 10M}. 

If a file or report received from the client exceeds its maximum allowed size
then \textbf{stealth} terminates after writing the following message to the report
file (which is sent to the configured mail address):
        \begin{verbatim}
    
STEALTH - CAN'T CONTINUE: `<name of offending file>' EXCEEDS MAX. 
                                                DOWNLOAD SIZE (<size shown>)
    STEALTH - THIS COULD SIGNAL A SERIOUS PROBLEM WITH THE CLIENT
    STEALTH - ONE OR MORE LOG FILES MAY BE INVALID AS A RESULT
    STEALTH - *** INVESTIGATE ***
\end{verbatim}

    Since a \texttt{+NOTRANS(-\{\}-\{\})max-size} specification may cause \textbf{stealth} to terminate
while receiving the output of a (remotely run) command, an empty or partial
log file will be the result. Of course this partial result is spurious as it
is a direct result of \textbf{stealth} terminating due to a size violation. 

After investigating (and removing) the reasons for the size violation a
new \textbf{stealth} run using the previous log file as the latest baseline should
show only expected changes.

For example, assume the following situation represents a (valid) state of
logfiles:
        \begin{verbatim}
    etc                       stealth                   
    setuid                    stealth.20080316-105756
\end{verbatim}

    Now \textbf{stealth} is run with \texttt{+NOTRANS(-\{\}-\{\})max-size 20}, prematurely 
terminating \textbf{stealth}. This results in the following set of logfiles:
        \begin{verbatim}
    etc                       stealth
    setuid                    stealth.20080316-105756   
                              stealth.20080316-110215
\end{verbatim}

    The file \texttt{stealth} now contains incomplete data with the (latest) file
\texttt{stealth.20080316-110215} containing its previous contents.

The reasons for the size-violation should of course be investigated and
removed. It is suggested to move the file last saved
(\texttt{stealth.20080316-110215}) to the file \texttt{stealth}, as it represents the
state before the size violation was encountered. Following this \textbf{stealth} should
operate normally again.

\cleardoublepage\chapter{Running `stealth'}
\typeout{Original Yodl file: running/intro}Now that \textbf{stealth} has been compiled, the construction of a policy file has
been covered, and a service-account on the client has been defined, what must
be done to run \textbf{stealth} in practice?

Here's what remains to be done:
    \begin{itemize}
    \item  Install \textbf{stealth} at a proper location
    \item  Construct one or more policy files
    \item  Learn to interpret \textbf{stealth}'s output.
    \item  Optionally, automate the removal of old log-files.
    \item  Determine a schedule for running stealth automatically, e.g. using
        \textbf{cron}(1) or \textbf{ssh-cron}(1)
    \end{itemize}
    In this chapter, these topics are discussed.

\section{Installing `stealth'}
    \typeout{Original Yodl file: running/installing}As \textbf{stealth} is mainly a system administrator's tool, it could be
installed in \texttt{/usr/bin}. In that case, do (as \emph{root}) in the
directory where \textbf{stealth} was compiled/unpacked:
        \begin{verbatim}
    ./build install program
\end{verbatim}

    Alternatively, another default location may be specified in the
\texttt{INSTALL.im} file or may be provided to the \texttt{build} script. E.g.,
        \begin{verbatim}
    ./build install program /usr/local/bin/stealth
\end{verbatim}

    installing the binary program as \texttt{/usr/local/bin/stealth}.

The provided \texttt{icmake build} script can be started without arguments for an
overview of possible commands.

\section{Stealth command-line and policy file options}\label{OPTIONS}
    \typeout{Original Yodl file: running/options}    Short options are provided between parentheses, immediately following
their long option equivalents. 

Option descriptions showing (C) can only be used on the command-line, and
are ignored when specified in the second section of the policy file.

In the overview of options `\texttt{$<$uds$>$}' represents the name of the
\emph{Unix Domain Socket} to use, and `\texttt{$<$file-spec$>$}' refers to a (relative or
absolute) specification of a file location. 

With the first and second synopses relative locations (of the Unix Domain
Socket and of other file-specifications) are interpreted relative to the
current working directory.

Command-line options overrule options defined in the policy-file.

\begin{itemize}
    \item  \texttt{+NOTRANS(-\{\}-\{\})daemon (-d) $<$uds$>$}: (C) run as background (daemon)
        process. When the Stealth daemon process is started, the Unix Domain
        Socket (tt$<$uds$>$) may not already exist. 
    \item  \texttt{+NOTRANS(-\{\}-\{\})dry-run}: (C) no integrity scans or reloads are performed, but
        are assumed OK. Remaining tasks are normally performed;
    \item  \texttt{+NOTRANS(-\{\}-\{\})help (-h)}: (C) Display help information and exit;
    \item  \texttt{+NOTRANS(-\{\}-\{\})log (-L) $<$file-spec$>$}: log messages are appended to
        `file-spec'. If file-spec does not exist, it is first created;
    \item  \texttt{+NOTRANS(-\{\}-\{\})logmail}: mail sent by \textbf{stealth} is logged (requires \texttt{+NOTRANS(-\{\}-\{\})log} or
        \texttt{+NOTRANS(-\{\}-\{\})syslog}); 
    \item  \texttt{+NOTRANS(-\{\}-\{\})max-size $<$size$>${[}BKMG{]}}: files retrieved by \texttt{GET} commands may
        at most have \texttt{$<$size$>$} bytes (B), KBytes (K), MBytes (M), GBytes
        (G). The default size is 10M, the default unit is B.
    \item  \texttt{+NOTRANS(-\{\}-\{\})no-mail}: mail is not sent. By default mail is sent as
        configured in the policy-file (\texttt{+NOTRANS(-\{\}-\{\})logmail} can be specified
        independently from \texttt{+NOTRANS(-\{\}-\{\})no-mail});
    \item  \texttt{+NOTRANS(-\{\}-\{\})parse-policy-file (-p)}: (C) parse the policy file, after which
        \textbf{stealth} ends.\ \\ 
        Specify once to see the numbered commands;\ \\ 
        twice to see the policy file parsing steps as well.\ \\ 
        Results are written to the std. output.
    \item  \texttt{+NOTRANS(-\{\}-\{\})ping $<$uds$>$}: (C) performs no actions, but is used to verify that
        a \textbf{stealth} daemon can be reached via its Unix Domain Socket
        (\texttt{$<$uds$>$}). The daemon will respond even if it's currently performing
        an integrity scan. It is used by the \texttt{/usr/bin/stealthcron} script
        to verify that a \textbf{stealth} daemon is alive.
    \item  \texttt{+NOTRANS(-\{\}-\{\})random-interval (-i) $<$interval$>${[}m{]}$>$}: start the scan a random
        interval of $<$interval$>$ seconds (or minutes if an `m' is appended (no
        blanks) to $<$interval$>$) following the delay specified at \texttt{+NOTRANS(-\{\}-\{\})repeat}
        (see below). This option requires specification of the \texttt{+NOTRANS(-\{\}-\{\})repeat}
        and \texttt{+NOTRANS(-\{\}-\{\})daemon} options;
    \item  \texttt{+NOTRANS(-\{\}-\{\})reload $<$uds$>$}: (C) reloads the configuration and skip-files
        and restarts the scan of the \textbf{stealth} daemon process. Options defined in
        the policy file are also reloaded. However, command-line options
        always take priority over options defined in the policy file, so when
        command-line options were used when starting \textbf{stealth} in daemon mode, they
        cannot be modified by reloading the policy file.
    \item  \texttt{+NOTRANS(-\{\}-\{\})repeat $<$seconds$>$}: wake up and perform an integrity scan at
        interrupts or after \texttt{$<$seconds$>$} seconds (or minutes if an `m' is
        appended (no blanks) to $<$seconds$>$) after completing the previous
        integrity scan. The option \texttt{+NOTRANS(-\{\}-\{\})random-interval} can be used to add a
        random delay to \texttt{$<$seconds$>$} until the next integrity scan is
        performed. This option requires specification of the and \texttt{+NOTRANS(-\{\}-\{\})daemon}
        option;
    \item  \texttt{+NOTRANS(-\{\}-\{\})rerun $<$uds$>$}: (C) start executing the integrity scan
        commands that are specified in the \textbf{stealth} daemon process's policy file;
    \item  \texttt{+NOTRANS(-\{\}-\{\})resume $<$uds$>$}: (C) resume a suspended \textbf{stealth} process, implies
        \texttt{+NOTRANS(-\{\}-\{\})rerun};
    \item  \texttt{+NOTRANS(-\{\}-\{\})run-command (-r) $<$nr$>$}: (C) Only execute command number $<$nr$>$
        (natural number).  Command numbers are shown by \textbf{stealth}
        \texttt{+NOTRANS(-\{\}-\{\})-parse-policy-file}. This option can only be specified using the
        second synopsis;
    \item  \texttt{+NOTRANS(-\{\}-\{\})skip-files (-s) $<$file-spec$>$}: all entries in \texttt{$<$file-spec$>$} are
        skipped. Their integrity is not monitored. If an entry is already
        present in a log file then \textbf{stealth} once generates an \texttt{IGNORING} message
        in the mail sent to the address specified at \texttt{EMAIL} in the policy
        file. Each entry mentioned in \texttt{file-spec} must be on a line of
        its own and must be specified using absolute file paths. Entries
        ending in a slash are assumed to be directories whose full contents
        must be skipped. Other entries are interpreted as the names
        of files to skip. Initial and trailing blanks, empty lines and lines
        having a \texttt{\#} as their 1st non blank character are ignored. Here are
        some examples:
            \begin{verbatim}

        # skip all files in user's Mail directory
    /home/user/Mail/
        # skip user's .history file
    /home/user/.history
            
\end{verbatim}

    \item  \texttt{+NOTRANS(-\{\}-\{\})stdout (-o)}: messages are (also) written to the std. output
        stream (only available with the second synopsis);
    \item  \texttt{+NOTRANS(-\{\}-\{\})suspend $<$uds$>$}: (C) suspends a currently active \textbf{stealth}
        process. Following \texttt{+NOTRANS(-\{\}-\{\})suspend} use \texttt{+NOTRANS(-\{\}-\{\})resume} to re-activate an
        \textbf{stealth} daemon or \texttt{+NOTRANS(-\{\}-\{\})terminate} to end an \textbf{stealth} daemon;
    \item  \texttt{+NOTRANS(-\{\}-\{\})syslog}: write syslog messages;
    \item  \texttt{+NOTRANS(-\{\}-\{\})syslog-facility $<$facility$>$}:  syslog facility to use. By
        default facility DAEMON is used;
    \item  \texttt{+NOTRANS(-\{\}-\{\})syslog-priority $<$priority$>$}: syslog priority to use. By
        default priority NOTICE is used;
   \item  \texttt{+NOTRANS(-\{\}-\{\})syslog-tag $<$tag$>$}: \texttt{$<$tag$>$} specifies the identifier that is
        prefixed to syslog messages. By default the tag `STEALTH' is used, see
        also the next section;
    \item  \texttt{+NOTRANS(-\{\}-\{\})terminate $<$uds$>$}: (C) terminate a currently active \textbf{stealth}
        process;
    \item  \texttt{+NOTRANS(-\{\}-\{\})time-stamp (-t) $<$type$>$}: the time-stamps to use. By default
        UTC. To use the local time specify \texttt{+NOTRANS(-\{\}-\{\})time-stamp
        LT}. The \texttt{+NOTRANS(-\{\}-\{\})time-stamp} option does not apply to time-stamps
        generated by syslog (see also the next section);
    \item  \texttt{+NOTRANS(-\{\}-\{\})usage}: (C) Display help information and exit;
    \item  \texttt{+NOTRANS(-\{\}-\{\})verbosity $<$value$>$}: determines the amount of logged
        information. Requires options \texttt{+NOTRANS(-\{\}-\{\})log} or \texttt{+NOTRANS(-\{\}-\{\})syslog}. Possible
        values are:\ \\ 
                         0: nothing is logged\ \\ 
                         1: (default) mode reports and policy commands\ \\ 
                         2: also: ipc commands and actions\ \\ 
                         3: also: integrity scan informative messages
    \item  \texttt{+NOTRANS(-\{\}-\{\})version (-v)}: (C) Display \textbf{stealth}'s version information and
        terminate;
    \end{itemize}

\begin{itemize}
    \item  \texttt{policy}: file specification of the policy file. If a relative
        location is specified then this location is interpreted relative to
        the current working directory. \textbf{Stealth} converts this relative
        specification to an absolute file location, and an option like
        \texttt{+NOTRANS(-\{\}-\{\})reload} will reload the policy file from the thus determined
        absolute file path.
    \end{itemize}

Only one of the options \texttt{+NOTRANS(-\{\}-\{\})daemon, +NOTRANS(-\{\}-\{\})reload, +NOTRANS(-\{\}-\{\})resume,
+NOTRANS(-\{\}-\{\})suspend} or \texttt{+NOTRANS(-\{\}-\{\})terminate} can be specified. The options \texttt{+NOTRANS(-\{\}-\{\})reload,
+NOTRANS(-\{\}-\{\})rerun, +NOTRANS(-\{\}-\{\})resume, +NOTRANS(-\{\}-\{\})suspend,} and \texttt{+NOTRANS(-\{\}-\{\})terminate} ignore any other options.

The following options are still recognized for backward compatibility with \textbf{stealth}
pre-3.00 versions and will be removed in a future \textbf{stealth} version. They generate
error messages suggesting alternatives:

\begin{itemize}
    \item  \texttt{+NOTRANS(-\{\}-\{\})echo-commands (-e)}:
            echo commands to std error when they are processed; use \texttt{+NOTRANS(-\{\}-\{\})log}
            instead.
    \item  \texttt{+NOTRANS(-\{\}-\{\})keep-alive}: run as a daemon; use \texttt{+NOTRANS(-\{\}-\{\})daemon} instead.
    \item  \texttt{+NOTRANS(-\{\}-\{\})only-stdout}: scan report is written to stdout; use
        \texttt{+NOTRANS(-\{\}-\{\})stdout} instead.
    \item  \texttt{+NOTRANS(-\{\}-\{\})quiet (-q)}: suppresses progress messages written to stderr; use
        \texttt{+NOTRANS(-\{\}-\{\})verbosity 0} instead.
    \item  \texttt{+NOTRANS(-\{\}-\{\})suppress $<$uds$>$}: suppresses a currently active \textbf{stealth}
            process; use \texttt{+NOTRANS(-\{\}-\{\})suspend} instead.
    \end{itemize}

The following options were discontinued starting since \textbf{stealth} version 3.00.00:
    \begin{itemize}
    \item  \texttt{+NOTRANS(-\{\}-\{\})debug} (option \texttt{+NOTRANS(-\{\}-\{\})verbosity} or \texttt{+NOTRANS(-\{\}-\{\})dry-run} could be used 
                    instead);
    \item  \texttt{+NOTRANS(-\{\}-\{\})no-child-processes};
    \item  \texttt{+NOTRANS(-\{\}-\{\})parse-config-file}.
    \end{itemize}

When specifying long options in policy files initial hyphens should be
omitted. Here are some examples:
        \begin{verbatim}
    %%
    log /tmp/stealth.log
    verbosity 3
\end{verbatim}


\subsection{Rsyslog filtering}
        \typeout{Original Yodl file: running/rsyslog}    When using \textbf{rsyslogd}(1) property based filters may be used to filter
syslog messages and write them to a file of your choice. E.g., to filter
messages starting with the syslog message tag (e.g., \texttt{STEALTH}) use
        \begin{verbatim}

:syslogtag, isequal, "STEALTH:"   /var/log/stealth.log
:syslogtag, isequal, "STEALTH:"   stop
        
\end{verbatim}

    Note that the colon is part of the tag, but is not specified with the 
\texttt{syslog-tag} option.

This causes all messages having the \texttt{STEALTH:} tag to be written on
\texttt{/var/log/stealth.log} after which they are discarded. More extensive
filtering is also supported, see, e.g.,
\texttt{http://www.rsyslog.com/doc/rsyslog\_conf\_filter.html} and
\texttt{http://www.rsyslog.com/doc/property\_replacer.html}

Time stamps written by \texttt{rsyslogd} are not controlled by \textbf{stealth}'s
\texttt{+NOTRANS(-\{\}-\{\})time-stamp} option, but, e.g., by a \texttt{TZ} specification in
\texttt{/etc/default/rsyslog}. Simply add the line
    \begin{verbatim}
    export TZ=UTC
\end{verbatim}

 to \texttt{/etc/default/rsyslog}, followed by restarting \texttt{rsyslogd} configures
\texttt{rsyslogd} to generate time stamps using UTC.

\section{Construct one or more policy files}
    \typeout{Original Yodl file: running/makepolicy}Here we assume that \textbf{stealth} is run by \emph{root}, and that root wants to
store information about the host \texttt{client} under the subdirectory
\texttt{/root/stealth/client}. 

Furthermore, we assume that reports of \textbf{stealth} integrity-scans should be sent to
the user \texttt{admin@elsewhere}, who is only interested in receiving a short
summary of changes, as the full report can always be read at the monitor
itself. To accomplish this a small support-script was developed, filtering the
report generated by \textbf{stealth} down to its essentials.

As the \texttt{sha1sum} program on the client may be compromised, it is a good idea
to start the integrity scan by transferring the client's \texttt{sha1sum} program
to the monitor first, to verify the integrity of that program locally (i.e.,
at the monitor), before trusting it to compute sha1sums of the client's
files. The same holds true for any libraries and support programs (like
\texttt{find}) that are used intensively during integrity scans.

Sha1sum checks should be performed on all setuid and setgid files on the
\texttt{client}, and in order to be able reach all files on \texttt{client},
\texttt{root@monitor} is allowed to login to the \texttt{root@client} account using
an \texttt{ssh} connection.

Furthermore, sha1sum checks should be performed on all configuration files,
living under \texttt{/etc} and on the file \texttt{/usr/bin/find} (which is used
intensively when performing the integrity checks).

Next, the construction of the required \texttt{policy} file, implementing the
abovementioned requirements, is described in the following subsections.

\subsection{DEFINE directives}
        \typeout{Original Yodl file: running/define}    First we write some \texttt{DEFINE} directives simplifying complex command
specifications: 
        \begin{verbatim}

    DEFINE  SSHCMD  /usr/bin/ssh root@client -T -q exec /bin/bash --noprofile
    DEFINE  EXECSHA1 -xdev -perm +u+s,g+s \( -user root -or -group root \) \ 
                    -type f -exec /usr/bin/sha1sum {} \;
\end{verbatim}

    The first \texttt{DEFINE} defines the \texttt{ssh} command to use: an ssh-connection
will be made to the root account at the client.

The second \texttt{DEFINE} shows the arguments for \textbf{find}(1) when looking for
all root setuid or setgid normal files. For all these files the \textbf{sha1sum}(1)
program should be run.

\subsection{USE directives}        
        \typeout{Original Yodl file: running/use}    Next some \texttt{USE} directives, matching our specific, local,
situation, are defined: 
        \begin{verbatim}

    USE BASE        /root/stealth/client
    USE EMAIL       admin@elswhere
    USE MAILER      /root/bin/stealthmail
    USE MAILARGS    "Client STEALTH report"
    USE SSH         ${SSHCMD}
\end{verbatim}


\begin{itemize}
    \item  All output is  written under the \texttt{/root/stealth/client} directory;
    \item  Mail is sent to the user \texttt{admin@elsewhere};
    \item  As mail program we use a filtering script (\texttt{stealthmail}), which is
        installed in \texttt{/root/bin};
    \item  The script handles its own argument. As it can be used by \textbf{stealth}
        performing integrity scans on other clients as well, it is given an
        argument which can be used as e-mail subject, identifying the
        client-computer that has been integrity-scanned;
    \item  The ssh-command is defined by the \texttt{SSHCMD}. It's definition is used
        at the \texttt{USE SSH} specification;
    \item  Default values of all remaining \texttt{USE} directives are OK, and thus
        were not explicitly specified. They are:
        \begin{verbatim}
    USE DD          /bin/dd
    USE DIFF        /usr/bin/diff
    USE REPORT      report
    USE SH          /bin/sh
\end{verbatim}

    \end{itemize}

\subsection{Commands}
        \typeout{Original Yodl file: running/commands}The following commands are now defined:
    \begin{itemize}
    \item  first, we copy the client's \texttt{sha1sum} program to the monitor. In
practice, this should also include the shared object libraries that are used
by \texttt{sha1sum}, as they might have become corrupted as well;
    \item  Once \texttt{sha1sum} is locally available its integrity is verified;
    \item  Once the integrity of the client's \texttt{sha1sum} has been verified, it
is used to verify the integrity of the client's \texttt{/usr/bin/find} program;
    \item  Following this, all setuid and setgid root files are located and
checked for integrity;
    \item  Finally, the integrity of the client configuration files under
\texttt{/etc} is verified;
    \end{itemize}

In this manual the \textbf{sha1sum}(1) program is frequently used when checking
hash values. Stronger hash functions (like \textbf{sha256sum}(1)) might be
preferred in practice. \texttt{sha256sum's} hash values are remarkably longer than
\texttt{sha1sum's} hash values. When using these longer hash values in the manual
it often clobbers the layout of examples. Therefore in this manual
\textbf{sha1sum}(1) is continued to be used.

Realize, however, that when updating existing policy files to use
\textbf{sha256sum}(1) instead of \textbf{sha1sum}(1), that previously generated log
files (that used \textbf{sha1sum}(1)) are incompatible with log files obtained when
using \textbf{sha256sum}(1). In practice this means that new log files need to be
generated, and any previously geneerated log files must be disregarded.

\subsubsection{Obtaining the client's sha1sum program}
            \typeout{Original Yodl file: running/obtaining}To copy the client's \texttt{sha1sum} program to a local directory we specify:
        \begin{verbatim}

    GET /usr/bin/sha1sum /root/tmp
\end{verbatim}

    This command must succeed. 

\subsubsection{Checking the integrity of the client's sha1sum program}
            \typeout{Original Yodl file: running/checking}Next, we check the integrity of the received \texttt{sha1sum} program. For this, we
use the monitor's \texttt{sha1sum} program:
        \begin{verbatim}

    LABEL \nCheck the client's sha1sum program
    LOCAL CHECK LOG = local/sha1 /usr/bin/sha1sum /root/tmp/sha1sum
        
\end{verbatim}

    The \texttt{LABEL} command writes the label to the report file just before
writing the \texttt{sha1sum} program's output.

The \texttt{LOCAL} command checks the sha1sum of the program copied from the
client. The report is written on the file
\texttt{/root/stealth/client/local/sha1}. If this fails, \textbf{stealth} terminates, alerting
\texttt{admin@elsewhere} that the check failed. This is a serious event, as it
indicates that either the monitor's \texttt{sha1sum} is behaving unexpectedly or
that the client's \texttt{sha1sum} program has unexpectedly changed.

The \texttt{sha1sum} program \emph{may} have changed due to a normal upgrade. If
so, \texttt{admin@elsewhere} will know this, and can (probably) ignore the
warning. The next time \textbf{stealth} is run, the (now updated) SHA1 value is used, and
it again compares the obtained \texttt{SHA1} value to the one obtained for the
downloaded \texttt{sha1sum} program.

\subsubsection{Checking the client's /usr/bin/find program}
            \typeout{Original Yodl file: running/checkingfind}    The client normally uses its \texttt{find} command intensively: \texttt{find} is a
great tool for producing reports about almost any conceivable combination of
characteristics of sets of files. Of course, the client's \texttt{find} command
must itself be OK, as well as the client's \texttt{sha1sum} program. Now that we
know that the client's \texttt{sha1sum} program is OK, we can use it to check the
client's \texttt{/usr/bin/find} program.

Note that the monitor itself no longer needs to invest any significant
processing load: only the client itself is taxed for checking the integrity
of its own files:
        \begin{verbatim}

    LABEL \nchecking the client's /usr/bin/find program
    CHECK LOG = remote/binfind /usr/bin/sha1sum /usr/bin/find
\end{verbatim}


\subsubsection{Checking the client's setuid/setgid files}
            \typeout{Original Yodl file: running/checkingsetuid}    Having checked the client's \texttt{sha1sum} and \texttt{find} programs, sha1 checksum
checks should be performed on all setuid and setgid files on the
client. For this we activate the \texttt{sha1sum} program on the client. In
order to check the setuid/setgid files, the following command is added to the
policy file:
        \begin{verbatim}

    LABEL \nsuid/sgid/executable files uid or gid root on the / partition     
    CHECK LOG = remote/setuidgid /usr/bin/find / ${EXECSHA1}
\end{verbatim}


\subsubsection{Checking the configuration files in the 
                                                client's /etc/ directory}
            \typeout{Original Yodl file: running/checkingconfig}    Finally, the client's configuration files are checked. Some of these files
change so frequently that we don't want them to be checked. E.g.,
\texttt{/etc/adjtime, /etc/mtab}. To check the configuration file, do:
    
        \begin{verbatim}
    LABEL \nconfiguration files under /etc
    CHECK LOG = remote/etcfiles                         \ 
          /usr/bin/find /etc -type f -not -perm /6111   \ 
            -not -regex "/etc/\(adjtime\|mtab\)"        \ 
            -exec /usr/bin/sha1sum {} \;
\end{verbatim}


\subsection{The complete `policy' file}
        \typeout{Original Yodl file: running/policy}Here is the complete policy file we've constructed so far:

\begin{verbatim}
    DEFINE  SSHCMD  /usr/bin/ssh root@client -T -q exec /bin/bash --noprofile
    DEFINE  EXECSHA1 -xdev -perm +u+s,g+s \( -user root -or -group root \) \ 
                    -type f -exec /usr/bin/sha1sum {} \;

    USE BASE        /root/stealth/client
    USE EMAIL       admin@elswhere
    USE MAILER      /root/bin/stealthmail
    USE MAILARGS    "Client STEALTH report"
    USE SSH         ${SSHCMD}

    USE DD          /bin/dd
    USE DIFF        /usr/bin/diff
    USE REPORT      report
    USE SH          /bin/sh

    GET /usr/bin/sha1sum /root/tmp

    LABEL \nCheck the client's sha1sum program
    LOCAL CHECK LOG = local/sha1 /usr/bin/sha1sum /root/tmp/sha1sum

    LABEL \nchecking the client's /usr/bin/find program
    CHECK LOG = remote/binfind /usr/bin/sha1sum /usr/bin/find
 
    LABEL \nsuid/sgid/executable files uid or gid root on the / partition     
    CHECK LOG = remote/setuidgid /usr/bin/find / ${EXECSHA1}

    LABEL \nconfiguration files under /etc
    CHECK LOG = remote/etcfiles                         \ 
          /usr/bin/find /etc -type f -not -perm /6111   \ 
            -not -regex "/etc/\(adjtime\|mtab\)"        \ 
            -exec /usr/bin/sha1sum {} \;




\end{verbatim}


\section{Running `stealth' for the first time}
    \typeout{Original Yodl file: running/firstrun}    When \textbf{stealth} is now run, it creates its initial report files under
\texttt{root/stealth/client}.

The first time \textbf{stealth} is run, it is usually run `by hand'. The initial run by
hand probably benefits from the \texttt{+NOTRANS(-\{\}-\{\})stdout} option, as it shows all executed
commands on the standard output:
        \begin{verbatim}
    stealth --stdout policy
\end{verbatim}

    Furthermore, the reports are initialized. Running \textbf{stealth} this way for the
\texttt{policy} file constructed in the previous sections produces the following
output (lines were wrapped to improve readability):
        \begin{verbatim}
    GET /usr/bin/sha1sum /root/tmp
    LABEL \nCheck the client's sha1sum program
    LOCAL CHECK LOG = local/sha1 /usr/bin/sha1sum /root/tmp/sha1sum
    LABEL \nchecking the client's /usr/bin/find program
    CHECK LOG = remote/binfind /usr/bin/sha1sum /usr/bin/find
    LABEL \nsuid/sgid/executable files uid or gid root on the / partition     
    CHECK LOG = remote/setuidgid /usr/bin/find / -xdev -perm +u+s,g+s 
            \( -user root -or -group root \) -type f 
            -exec /usr/bin/sha1sum {} \;
    LABEL \nconfiguration files under /etc
    CHECK LOG = remote/etcfiles                         /usr/bin/find /etc 
            -type f -not -perm /6111   -not -regex "/etc/\(adjtime\|mtab\)"
            -exec /usr/bin/sha1sum {} \;
    LOCAL /usr/bin/scp -q root@client:/usr/bin/sha1sum /root/tmp
    LABEL \nCheck the client's sha1sum program
    LOCAL CHECK LOG = local/sha1 /usr/bin/sha1sum /root/tmp/sha1sum
    LABEL \nchecking the client's /usr/bin/find program
    CHECK LOG = remote/binfind /usr/bin/sha1sum /usr/bin/find
    LABEL \nsuid/sgid/executable files uid or gid root on the / partition     
    CHECK LOG = remote/setuidgid /usr/bin/find / -xdev -perm +u+s,g+s 
            \( -user root -or -group root \) -type f 
            -exec /usr/bin/sha1sum {} \;
    LABEL \nconfiguration files under /etc
    CHECK LOG = remote/etcfiles                        /usr/bin/find /etc 
            -type f -not -perm /6111   -not -regex "/etc/\(adjtime\|mtab\)"
            -exec /usr/bin/sha1sum {} \;
\end{verbatim}


\subsection{The mailed report}
        \typeout{Original Yodl file: running/mailed}The \texttt{/root/bin/stealthmail} script is called with the following arguments:
        \begin{verbatim}

    "Client STEALTH report" admin@elswhere
\end{verbatim}


The mailed report contains information comparable to this:
        \begin{verbatim}

    STEALTH (4.00.00) started at Sat, 07 Feb 2015 22:10:56 +0100
        
    Check the client's sha1sum program
    Initialized report on local/sha1
    
    checking the client's /usr/bin/find program
    Initialized report on remote/binfind
    
    suid/sgid/executable files uid or gid root on the / partition     
    Initialized report on remote/setuidgid
    
    configuration files under /etc
    Initialized report on remote/etcfiles
\end{verbatim}


\subsection{Files under /root/stealth/client}
        \typeout{Original Yodl file: running/files}    Under \texttt{/root/stealth/client} the following entries are now available:
    \begin{itemize}

\item  \texttt{local}: below this directory the reports of the locally performed
checks are found. Using our demo \texttt{policy} file, only one logfile is found
here: \texttt{sha1}, containing the client's SHA1 checksum of its
\texttt{/usr/bin/sha1sum} program:
        \begin{verbatim}
    45251e259bfaf1951658a7b66c328c52  /root/tmp/sha1sum
\end{verbatim}


\item  \texttt{remote}: at this directory the reports of the remotely performed
checks are found. Using our demo \texttt{policy} file, three files were created:

The file \texttt{binfind}, containing the checksum of the client's
\texttt{/usr/bin/find} program:
        \begin{verbatim}
    fc62fc774999584f1e29e0f94279a652  /usr/bin/find
\end{verbatim}


The file \texttt{etcfiles}, containing the checksums of the client's
configuration files under \texttt{/etc} (shown only partially):
        \begin{verbatim}
    ced739ecb2c43a20053a9f0eb308b2b0  /etc/modutils/aliases
    a2322d7e2f95317b2ddf3543eb4c74c0  /etc/modutils/paths
    f9e3eac60200d41dd5569eeabb4eddff  /etc/modutils/arch/i386
    f07da2ebf00c6ed6649bae5501b84c4f  /etc/modutils/arch/m68k.amiga
    2893201cc7f7556160fa9cd1fb5ba56a  /etc/modutils/arch/m68k.atari
        ...
    bf73b4e76066381cd3caf80369ce1d0e  /etc/deluser.conf
    4cd70d9aee333307a09caa4ef003501d  /etc/adduser.conf.dpkg-save
    8c749353c5027d0065359562d4383b8d  /etc/gimp/1.2/gtkrc_user
    3ec404ec597ef5460600cccf0192f4d6  /etc/gimp/1.2/unitrc
    8c740345b891179228e3d1066291167b  /etc/gimp/1.2/gtkrc
\end{verbatim}


The file \texttt{setuidgid}, containing the checksums of the client's
setuid/setgid root files (shown only partially):
        \begin{verbatim}
    030f3f84ec76a8181cca087c4ba655ea  /bin/login
    b6c0209547d88928f391d2bf88af34aa  /bin/ping
    5d324ad212b2ff8f767637ac1a8071ec  /bin/su
    344dbedc398d5114966914419ef53fcc  /usr/bin/wall
    27b045bd7306001f9ea31bc18712d8b7  /usr/bin/rxvt-xpm
    ...
    3567b18ffc39c2dc6ec0c0d0fc483f4f  /usr/lib/ssh-keysign
    3383a7955ac2406311e9aa51c6ac9c2c  /usr/X11R6/bin/X
    3c99ea0425c6e0278039e16478d2fb57  /usr/X11R6/bin/xterm
    d590f7f5b4d6ae61680692a52235d342  /usr/local/bin/setuidcall
    4c17203d7d91ec4946dea2f0ae365d5b  /sbin/unix_chkpwd
\end{verbatim}


Of course, the checksums and the filenames shown are only for
documentation purposes. At other systems different files and/or
checksums will be reported.

\item  The file \texttt{/root/client/report} \textbf{New lines are always appended to
the \texttt{/root/client/report} file.  It will never shorten, unless shorten by
the systems administrator at `monitor'}.

This file contains the following:
        \begin{verbatim}
    STEALTH (3.00.00) started at Wed, 20 Aug 2014 11:06:50 +0000

    Check the client's sha1sum program
    Initialized report on local/sha1
    
    checking the client's /usr/bin/find program
    Initialized report on remote/binfind
    
    suid/sgid/executable files uid or gid root on the / partition     
    Initialized report on remote/setuidgid
    
    configuration files under /etc
    Initialized report on remote/etcfiles
        
\end{verbatim}

    \end{itemize}

This completes the information generated by \textbf{stealth} during its first run.

\section{Subsequent `stealth' runs}

\subsection{All files unaltered}
        \typeout{Original Yodl file: running/newrunsame}    When \textbf{stealth} is subsequently run, it updates its report files under
\texttt{root/stealth/client}. If nothing has changed, the log-files remain
unaltered. Subsequent runs will, however, add some new info to the file
\texttt{/root/client/report}:
        \begin{verbatim}

    STEALTH (4.00.00) started at Sat, 07 Feb 2015 22:10:56 +0100
    
    Check the client's sha1sum program
    Initialized report on local/sha1
    
    checking the client's /usr/bin/find program
    Initialized report on remote/binfind
    
    suid/sgid/executable files uid or gid root on the / partition     
    Initialized report on remote/setuidgid
    
    configuration files under /etc
    Initialized report on remote/etcfiles
    
    STEALTH (4.00.00) started at Sat, 07 Feb 2015 22:22:15 +0100
\end{verbatim}

    Note that just one extra line was added: a timestamp showing the date/time
of the last run. The systems administrator may rotate the report file every
once in a while to reclaim some disk space.

\subsection{Modifications occurred}
        \typeout{Original Yodl file: running/newrundelta}    Basically, three kinds of modifications are possible: additions,
modifications, and removals. Here we'll show the effects all these changes
have on \textbf{stealth}'s output.

For illustrative purposes, the following changes were made to the
\texttt{client}'s files:
    \begin{itemize}
    \item  \texttt{/etc/motd} was changed
    \item  the file \texttt{timezone\textasciitilde{}} was removed
    \item  the file \texttt{/etc/motd.org} was created
    \end{itemize}

Next, \textbf{stealth} was again run, producing the following output:
    \begin{itemize}

\item  The following new info is now added to file \texttt{/root/client/report}:
        \begin{verbatim}
    STEALTH (3.00.00) started at Wed, 20 Aug 2014 11:13:38 +0000
    
    configuration files under /etc
    ADDED: /etc/motd.org
        < 945d0b8208e9861b8f9f2de155e619f9  /etc/motd.org
    MODIFIED: /etc/motd
        < 7f96195d5f051375fe7b523d29e379c1  /etc/motd
        > 945d0b8208e9861b8f9f2de155e619f9  /etc/motd
    REMOVED: /etc/timezone~
        > 6322bc8cb3ec53f5eea33201b434b74b  /etc/timezone~
\end{verbatim}

    Note that all changes were properly detected and logged in the file
\texttt{/root/client/report}. 

\item  Furthermore, a matching report was sent by \emph{mail}:
        \begin{verbatim}
    STEALTH (3.00.00) started at Wed, 20 Aug 2014 11:13:38 +0000

    configuration files under /etc
    ADDED: /etc/motd.org
        < 945d0b8208e9861b8f9f2de155e619f9  /etc/motd.org
    MODIFIED: /etc/motd
        < 7f96195d5f051375fe7b523d29e379c1  /etc/motd
        > 945d0b8208e9861b8f9f2de155e619f9  /etc/motd
    REMOVED: /etc/timezone~
        > 6322bc8cb3ec53f5eea33201b434b74b  /etc/timezone~
\end{verbatim}

    Note that the report \emph{only} shows the info that was added to the
\emph{/root/client/report} file. 

The report itself could be beautified further. E.g., I use the following
script to mail the report to the addressee:
        \begin{verbatim}

    #!/bin/bash
    
    NAME=`basename $0`
    
    tee /root/stealth/lastreport/$NAME | egrep -v '^([[:space:]]|[[:space:]]*$)' |
        sort | uniq | mail -s $1 $2
        
\end{verbatim}

    For the \texttt{client} computer, this little script writes the mailed report
on a file \texttt{/root/stealth/lastreport/client}, overwriting its previous
contents, removes all lines beginning with blanks (thus trimming away the
\texttt{diff}-generated lines), and e-mails the \texttt{sort}ed and \texttt{uniq}ed lines
using \texttt{mail}. The addressee (\texttt{admin@elsewhere}) then receives the
following information:
        \begin{verbatim}

    ADDED: /etc/motd.org
    MODIFIED: /etc/motd
    REMOVED: /etc/timezone~
    STEALTH (3.00.00) started at Wed, 20 Aug 2014 11:13:38 +0000
    configuration files under /etc
        
\end{verbatim}

    In practice this provides me with all the information I need if something
out of the ordinary has happened.

\item  Finally, the file 
        \begin{verbatim}
    /root/stealth/client/remote/etcfiles
\end{verbatim}
 
    was recreated, saving the old file as 
        \begin{verbatim}
    /root/stealth/client/remote/etcfiles.20021028-112851
\end{verbatim}

    As remarked earlier (see section \ref{COMMANDS}), many
\texttt{logfile.YYMMDD-HHMMSS} files could eventually accumulate. As discussed in
section \ref{COMMANDS}, it might be considered to remove old log files every
now and then.
    \end{itemize}

\subsection{Failing LOCAL commands}
        \typeout{Original Yodl file: running/failing}    If the client's \texttt{sha1sum} program itself is altered, a serious situation
has developed. In that case, further actions by \textbf{stealth} would be suspect, as their
results might easily be currupted. Additional checks \emph{will} be performed,
but a warning is generated on the \texttt{report} file (and in the mail sent to
\texttt{admin@elsewhere}):
        \begin{verbatim}

    STEALTH (4.00.00) started at Sat, 07 Feb 2015 22:27:15 +0100

    Check the client's sha1sum program
    MODIFIED: /root/tmp/sha1sum
        < fc62fc774999584f1e29e0f94279a652  /root/tmp/sha1sum
        > 45251e259bfaf1951658a7b66c328c52  /root/tmp/sha1sum
    
    *** BE CAREFUL *** REMAINING RESULTS MAY BE FORGED
    
    configuration files under /etc
    REMOVED: /etc/motd.org
        > 945d0b8208e9861b8f9f2de155e619f9  /etc/motd.org
    MODIFIED: /etc/motd
        < 945d0b8208e9861b8f9f2de155e619f9  /etc/motd
        > 7f96195d5f051375fe7b523d29e379c1  /etc/motd
\end{verbatim}

    (The report shows the removal of the previously added file \texttt{motd.org},
and the modification of \texttt{motd}. These are real, as the original \texttt{motd}
file, modified earlier, was restored at this point).

\subsection{Skipping (some) integrity checks}
        \typeout{Original Yodl file: running/skipping}Some files or directories may not require integrity checks. Automated
processes may modify files which are not threatening the proper functioning of
running programs or processes. In those cases a file can be prepared holding
the absolute paths of entries to be skipped. Each entry should appear on a
line of its own without any additional information.

\textbf{Stealth} can be informed about this file using the \texttt{+NOTRANS(-\{\}-\{\})skip-files $<$file-spec$>$}
option. When a relative file specification is used with \texttt{+NOTRANS(-\{\}-\{\})skip-files} it is
interpreted a location relative to the current working directory.  The
skip-files file itself must contain the paths of the entries to be skipped
during file integrity scans. If an entry is already present in a log file then
\textbf{stealth} once generates an \texttt{IGNORING} message in the mail sent to the address
specified at \texttt{EMAIL} in the policy file. Each entry in a skip-file must be
on a line of its own and must be specified using absolute file paths. Entries
ending in a slash are assumed to be directories whose full contents must be
skipped. Other entries are interpreted as the names of files to skip. Initial
and trailing blanks, empty lines and lines having a \texttt{\#} as their 1st non
blank character are ignored.

Here is an example:
        \begin{verbatim}

    stealth -e --skip-files /root/stealth/remote/skipping remote.pol
\end{verbatim}


If an entry \texttt{/etc/skipme} appears in the current logs which is thereafter
added to the \texttt{skippath} file then the mail generated by \textbf{stealth} 
once contains a line like the following:
        \begin{verbatim}
    SKIPPING: /etc/skipme
        > a7695bb2d019e60988e757a4b692acfe  /etc/skipme
        
\end{verbatim}

    The reported hash-value is the hash-value at the time of the stealth-run
reporting the \texttt{SKIPPING} message.

Entries ending in a slash are assumed to be directories whose contents must
(recursively) be skipped.

\section{Automating repeated `stealth' runs}
    \typeout{Original Yodl file: running/cron}    To automate \textbf{stealth}'s  integrity scans, a file
\texttt{/etc/cron.d/stealth} could be created, containing a line like
        \begin{verbatim}

    2,17,32,47 * * * *  root    test -x /usr/bin/stealth && \ 
                           /usr/bin/stealth /root/stealth/client.pol
        
\end{verbatim}

    This starts \textbf{stealth} 2 minutes after every hour. In this example the ssh-key
must not require a passphrase, as \textbf{crontab}(1) cannot provide passphrases of
ssh-keys. Ssh-keys requiring passphrases can, however, be used if repeated 
\textbf{stealth} runs are controlled  by a program like \textbf{ssh-cron}(1).

In general, randomized events are harder to notice. For this \textbf{stealth} offers
the \texttt{+NOTRANS(-\{\}-\{\})repeat} and \texttt{+NOTRANS(-\{\}-\{\})random-interval} options. Both options expect an
argument in seconds (or in minutes, if an \texttt{m} is appended to the
specification). After each integrity scan the next integrity scan starts after
the time interval specified by the \texttt{+NOTRANS(-\{\}-\{\})repeat} option plus a random time
value selected from the time interval specified by the \texttt{+NOTRANS(-\{\}-\{\})random-interval}
option. For example, the \textbf{stealth} daemon started by the following command
repeatedly performs integrity scans between two and five minutes after the
last integrity scan completed:
        \begin{verbatim}

    stealth --daemon /root/stealth/client.uds \ 
            --repeat 2m --random-interval 3m /root/stealth/client.pol
\end{verbatim}

    Once this program has started its \textbf{ssh}(1) connection to the client host
persists, and a possibly required ssh-passphrase is no longer
required. Additional (intermediate) integrity scans can always be requested
(also without requiring ssh-passphrase specifications) using the command
        \begin{verbatim}

    stealth --rerun /root/stealth/client.uds
\end{verbatim}


\section{Report File Rotation}\label{ROTATE}
    \typeout{Original Yodl file: running/rotate}When \textbf{stealth} performs integrity scans it appends information to the report
file. This file therefore eventually grows to a large size, and the systems
manager controlling \textbf{stealth} might want to \emph{rotate} the report file every once in
a while (e.g., using a program like \textbf{logrotate}(1), also see the upcoming
section \ref{LOGROTATE}). To ensure that no log-rotation takes place
while \textbf{stealth} is busy performing integrity scans (thus modifying the report file)
the options \textbf{-{}-{}suspend} and \texttt{+NOTRANS(-\{\}-\{\})resume} were implemented. Both options
require the process-ID file of currently active \textbf{stealth} process as their argument.

For example, if a \textbf{stealth} process was once started using the command
    
        \begin{verbatim}

    stealth --daemon /root/stealth/small.uds --repeat 900 \ 
                    /root/stealth/small.pol
\end{verbatim}

    then the \texttt{+NOTRANS(-\{\}-\{\})suspend} and \texttt{+NOTRANS(-\{\}-\{\})resume} commands for this process should
be called as:
        \begin{verbatim}
    stealth --suspend /root/stealth/small.uds
    stealth --resume /root/stealth/small.uds
\end{verbatim}

    The \textbf{stealth} process identified in the files provided as arguments to
the \texttt{+NOTRANS(-\{\}-\{\})suspend} and \texttt{+NOTRANS(-\{\}-\{\})resume} options is called the \emph{daemon stealth
process} below.

The \texttt{+NOTRANS(-\{\}-\{\})suspend} option has the following effect:
    \begin{itemize}
    \item  If the daemon \textbf{stealth} process is currently processing its
policy file, performing an integrity scan, then the currently executing
policy file command is completed, whereafter further commands are ignored,
except for \texttt{+NOTRANS(-\{\}-\{\})resume} (see below) and \texttt{+NOTRANS(-\{\}-\{\})terminate}.
    \item  Any scheduled integrity scans following the \texttt{+NOTRANS(-\{\}-\{\})suspend} command
are ignored by the daemon \textbf{stealth} process;
    \item  The daemon \textbf{stealth} process writes a message that it is being suspended to
the report file and then processes the report file as usual.
    \end{itemize}
    Now that the report file is no longer modified by the daemon
\textbf{stealth} process, log-rotation may take place. E.g., a program like
\textbf{logrotate}(1) allows its users to specify a command or script just before
log-rotation takes place, and `\textbf{stealth} \texttt{+NOTRANS(-\{\}-\{\})suspend udsfile}' could be
specified nicely in such a pre-rotation section.

The \texttt{+NOTRANS(-\{\}-\{\})resume} option has the following effect:
    \begin{itemize}
    \item  The daemon \textbf{stealth} process resumes its activities by performing
another integrity scan. Thus, \texttt{+NOTRANS(-\{\}-\{\})resume} implies \texttt{+NOTRANS(-\{\}-\{\})rerun}.
    \item  Any scheduled integrity scans following the \texttt{+NOTRANS(-\{\}-\{\})resume} command are
again honored by the daemon \textbf{stealth} process.
    \end{itemize}
    Note that, once \texttt{+NOTRANS(-\{\}-\{\})suspend} has been issued, all commands except
\texttt{+NOTRANS(-\{\}-\{\})resume} and \texttt{+NOTRANS(-\{\}-\{\})terminate} are ignored by the daemon \textbf{stealth}
process. While suspended, the \texttt{+NOTRANS(-\{\}-\{\})terminate} command is acknowledged as a
`emergency exit' which may or may not interfere with, e.g., an ongoing
log-rotation process. The daemon \textbf{stealth} process should not normally be
terminated while it is in its suspended mode. The normal way to terminate a
stealth process running in the background is:
    \begin{itemize}
    \item  Wait for the  daemon \textbf{stealth} process to complete an ongoing series of
integrity scan commands;
    \item  Issue the `\textbf{stealth} \texttt{+NOTRANS(-\{\}-\{\})terminate udsfile}' command.
    \end{itemize}

\subsection{Status file cleanup}\label{STATUS}
        \typeout{Original Yodl file: running/status.yo}    Whenever \textbf{stealth} is run and it encounters a modified situation the already
existing status file summarizing that particular situation is saved and a new
status file is created. Eventually, this will result in many status
files. While report files can be rotated, it is pointless to rotate old status
files, since they are never modified. Instead, status files exceeding a
certain age could be removed and more recent files might be zipped to conserve
space. In \textbf{stealth}'s binary distribution the file
\texttt{/usr/share/doc/stealth/usr/bin/stealthcleanup} is provided which can be
used to perform such a cleanup. The script expects one argument: a resource
file defining the following shell variables:
    \begin{itemize}
    \item  \texttt{directories}: the directories below which the status files are
        found;
    \item  \texttt{gzdays}: the number of days a status file must exist before it is
        compressed using \textbf{gzip}(1);
    \item  \texttt{rmdays}: the maximum age (in days) of compressed status
        files. Files exceeding this age are removed using \textbf{rm}(1).
    \end{itemize}
    Here is the \texttt{stealthcleanup} script as contained in the binary
distribution's \texttt{/usr/share/doc/stealth/additional} directory:
        \begin{verbatim}
#!/bin/bash

usage()
{
    echo "
Usage: $0 [-v] rc-file
Where:
    -v: Show the actions that are performed
    rc-file: resource file defining:
            \`directories' - one or more directories containing status files
            \`gzdays'      - number of days status files may exist before they
                             are compressed
            \`rmdays'      - number of days gzipped status files may exist
                             before they are removed. 
"
    exit 1
}


error()
{
    echo "$*" >&2
    exit 1
}

if [ "$1" == "-v" ]
then
    verbose=1
    shift 1
else
    verbose=0
fi

[ $# == 1 ] || usage

# now source the configuration file
. $1           

for x in $directories
do
    cd $x || error "\`$x' must be a directory"
    if [ $verbose -eq 1 ]
    then
        echo "
cd $x"
    fi

    if [ $verbose -eq 1 ]
    then
        echo \
    /usr/bin/find ./ -mtime +$rmdays -type f -regex '.*[0-9]+-[0-9]+\.gz' \
        -exec /bin/rm {} \;
    fi
    /usr/bin/find ./ -mtime +$rmdays -type f -regex '.*[0-9]+-[0-9]+\.gz' \
        -exec /bin/rm {} \;

    if [ $verbose -eq 1 ]
    then
        echo \
    /usr/bin/find ./ -mtime +$gzdays -type f -regex '.*[0-9]+-[0-9]+' \
        -exec /bin/gzip {} \;
    fi 
    /usr/bin/find ./ -mtime +$gzdays -type f -regex '.*[0-9]+-[0-9]+' \
        -exec /bin/gzip {} \;
done

exit 0




\end{verbatim}

    Assuming that the status files are written in
\texttt{/var/stealth/target/local} and \texttt{/var/stealth/target/remote}; that status
file should be compressed when older than 2 days and removed after 30 days,
the resource file is:
        \begin{verbatim}
directories="
    /var/stealth/target/local
    /var/stealth/target/remote
    "

rmdays=30
gzdays=3
\end{verbatim}

    Furthermore assuming that the resourcefile is installed in
\texttt{/etc/stealth/cleanup.rc} and the \texttt{stealthcleanup} script itself in
\texttt{/usr/bin/stealthcleanup}, the \texttt{stealthcleanup} script could be called
as follows:
        \begin{verbatim}

    /usr/bin/stealthcleanup /etc/stealth/cleanup.rc
\end{verbatim}

    Note that \texttt{stealthcleanup} may be called whether or not there are active
\textbf{stealth} processes.

\subsection{Using `logrotate' to control report- and status files}\label{LOGROTATE}
        \typeout{Original Yodl file: running/logrotate.yo}    A program like \textbf{logrotate}(1) allows its users to specify a command or
script immediately following log-rotation, and `\textbf{stealth} \texttt{+NOTRANS(-\{\}-\{\})resume
pidfile}' could be specified nicely in such a post-rotation section.

Here is an example of a specification that can be used with
\textbf{logrotate}(1). Logrotate (on Debian systems) keeps its configuration files
in \texttt{/etc/logrotate.d}, and assuming there is a host \texttt{target}, whose report
file is \texttt{/var/stealth/target/report}, the required \textbf{logrotate}(1)
specification file (e.g., \texttt{/etc/logrotate.d/target}) could be:
        \begin{verbatim}
/root/stealth/report /var/log/stealth/client-small.log {
    weekly
    rotate 12
    compress
    missingok
    copytruncate
    sharedscripts
    prerotate
        /usr/bin/stealth --suspend /root/stealth/small.uds
    endscript
    postrotate 
        /usr/bin/stealth --resume /root/stealth/small.uds
    endscript 
}
\end{verbatim}

    Using this specification file, \textbf{logrotate}(1) will 
    \begin{itemize}
    \item  perform weekly rotations of the report file;
    \item  keep up to 12 rotated files, compressing them using \textbf{gzip}(1);
    \item  suspend the \textbf{stealth} daemon, before rotating its report file;
suspended; 
    \item  following the rotation, \textbf{stealth}'s actions are resumed.
    \end{itemize}
    Note thet \texttt{stealth +NOTRANS(-\{\}-\{\})resume xxx} always initiates another file integrity
scan.

\cleardoublepage\chapter{Kick-starting `stealth'}
\typeout{Original Yodl file: kickstart}Here are the steps to take to kick-start \textbf{stealth}
    \begin{itemize}
    \item  Install the stealth Debian package \texttt{stealth\_4.04.00\_i386.deb} and
thus accept the provided binary program (skipping the next series of steps) or
do not accept the provided binary, and compile \textbf{stealth} yourself, as per the
following steps:
    \item  Unpack \texttt{stealth\_4.04.00.tar.gz}: 
        \texttt{tar xzvf tealth\_4.04.00.tar.gz}
    \item  \texttt{cd stealth};
    \item  Inspect, and where necessary modify the values of the variables in
the files \texttt{INSTALL.cf} and \texttt{icmconf};
    \item  Install a recent Gnu \texttt{g++} compiler;
    \item  Install the bobcat library (both the binary and development version)
(\texttt{https://fbb-git.gitlab.io/bobcat/});
    \item  Install  the \texttt{icmake} program
(\texttt{https://fbb-git.gitlab.io/icmake/});
    \item  Run `\texttt{./build program strip}' to compile \textbf{stealth};
    \item  Run (probably as root) `\texttt{./build install program}' to install;
    \item  Optionally install documentation. See section \ref{COMPILING}.
    \end{itemize}
    Following the installation the \texttt{stealth} directory tree has become
superfluous and can safely be removed.

Next, do:
    \begin{itemize}
    \item  \texttt{cp share/usr/bin/stealthmail  /usr/local/bin}
    \item  \texttt{mkdir           /root/stealth}
    \item  \texttt{cp documentation/example-policies/localhost.pol  /root/stealth}
    \end{itemize}

\texttt{ssh} and \texttt{bash} (or another shell program) should be
available. \texttt{root@localhost} should be able to login at \texttt{localhost} using
\texttt{ssh root@localhost}, using the \texttt{/bin/bash}. Check
(as `root') at least
        \begin{verbatim}
    ssh root@localhost
\end{verbatim}

    as this might ask you for a confirmation that you've got the correct
host. 
    Now, run 
        \begin{verbatim}
    stealth /root/stealth/localhost.pol
\end{verbatim}

    to initialize the stealth-report files for \texttt{localhost}. This initializes
the report for
    \begin{itemize}
    \item  all root setuid/setgid executable files on \texttt{localhost}, 
    \item  and for all files under \texttt{/etc/} on \texttt{localhost}. 
    \end{itemize}

The mail-report is sent to \texttt{root@localhost}.

Now change or add or remove one of these files, and rerun \textbf{stealth}. The
file \texttt{/tmp/stealth-4.04.00.mail} should reflect these changes.

\cleardoublepage\chapter{Usage info}\label{USAGE}
\typeout{Original Yodl file: usage}When \textbf{stealth} is started without arguments, it provides some help about how
to start it. A message like the following is produced:

\begin{verbatim}
stealth V4.04.00
SSH-based Trust Enhancement Acquired through a Locally Trusted Host
Copyright (c) GPL 2005-2025

Usage 1 (activation modes):
   stealth [options] policy
Where:
   [options] - optional arguments (short options between parentheses,
               option descriptions starting with (C) can only be used
               on the command-line and are ignored when specified in the
               policy file).
      --daemon (-d) <uds>: (C) run as a background (daemon) process.
               <uds> is the location of the Unix Domain Socket that is
               used for communication with the stealth daemon process
      --dry-run: (C) no integrity scans or reloads are performed, but
               are assumed OK. Remaining tasks are normally performed
      --log (-L) <file-spec>: log messages are appended to `<file-spec>'.
               If <file-spec> does not exist, it is first created 
      --logmail: mail is logged (requires --log or --syslog)
      --max-size value[BKMG]: files retrieved by GET may at most
               have `value' bytes (B), Kbytes (K), Mbytes (M), Gbytes (G).
               By default: 10M; The default unit is `B'
      --no-mail: mail is not sent. By default mail is sent as configured
               in the policy-file (--logmail can be specified independently
               from --no-mail)
      --parse-policy-file (-p): (C) parse the policy file, no further actions.
               Specify once to see the numbered commands,
               twice to see the policy file parsing steps as well.
               Results to std output.
      --random-interval (-i) value: start integrity scans within
               a random interval of `value' seconds (minutes if an `m'
               is appended to the specified value).
               Requires --repeat.
      --repeat value: start an integrity scan every `value' seconds
               (minutes if an `m' is appended to the specified value).
      --run-command (-r) value: (C) only execute command #`value'
               (not available in combination with --daemon)
      --skip-files (-s) <file-spec>: skip the integrity checks of the
               files having their absolute path names listed in `<file-spec>'
      --stdout (-o): messages are (also) written to stdout
               (not available in combination with --daemon)
      --syslog: write syslog messages
      --syslog-facility fac:  syslog facility to use. By default DAEMON
      --syslog-priority pri:  syslog priority to use. By default NOTICE
      --syslog-tag tag: identifier prefixed to syslog messages. By
               default `STEALTH')
      --time-stamp <type>: the time-stamps to use. By default UTC.
               (does not apply to syslog-timestamps)
      --verbosity (-V) value: determines the amount of logged information.
               Requires --log or --syslog:
                   0: nothing is logged
                   1: mode reports and policy commands
                   2: also: ipc commands and actions
                   3: also: integrity scan informative messages
   policy: location of the policy file

Usage 2 (IPC modes, all options are command-line only):
   stealth {--reload,--rerun,--resume,--suspend,--terminate} <uds>
Where:
      --reload: reload a stealth process's policy and skip-file
                   files
      --rerun: start an integrity scan
      --resume: resume stealth after --suspend
      --suspend: suspend stealth's activities
                   to continue: --resume; to end: --terminate
      --terminate: terminate the stealth daemon
   <uds>: location of the Unix Domain Socket to connect to.

Usage 3 (support mode, all options are command-line only)
   stealth {--help,--version}
Where:
      --help (-h):    provide this help and terminate
      --version (-v): show version information and terminate

\end{verbatim}


Note that with the second type of usage the policy file is not required:
here only the \texttt{pidfile} must be specified.

\cleardoublepage\chapter{Errormessages}
\typeout{Original Yodl file: errors}    \texttt{Can't chdir to `path'}
    \begin{quote}the directory \texttt{path} could not be
created/used. This may be a permission problem. Check the permissions of
\texttt{path} if \texttt{path} does actually exist. The problem may be in a path
component, not necessarily in the last element of the path.
    \end{quote}

\texttt{Can't open `$<$fname$>$' to read (or write)}
     \begin{quote}When a \texttt{GET} or \texttt{PUT} command fails because the target file
could not be read or written, \textbf{stealth} terminates afer logging this message. The
file may not exist or you may not not have sufficient permissions to read or
write it.
    \end{quote}

\texttt{Corrupt line in policy file: ...}
    \begin{quote}The apparently corrupted line is shown. The line is corrupted if
the line could not be split into an initial word and its remainder. Normally
this should not happen. As the line is mentioned, the message itself should
assist you in your repairs.
    \end{quote}

\texttt{could not open $<$logname$>$}
    \begin{quote}This message is generated when the mentioned log-file cannot be
written to. Check the permissions of the file, and check if the path to the
file exists. The problem may be in a path component, not necessarily in the
last element of the path or in the file itself.
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})daemon: missing uds-file or policy file}
    \begin{quote}The \texttt{+NOTRANS(-\{\}-\{\})daemon} option requires the location for its Unix Domain
Socket, and in addition a policy file must be specified. Most likely the
location of the Unix Domain File was omitted, thus confusing the policy file
with the Unix Domain File
    \end{quote}

\texttt{incompatible options: ...}
    \begin{quote}Two or more incompatible options are shown. E.g., \texttt{+NOTRANS(-\{\}-\{\})daemon} is
incompatible with IPC options, which themselves are mutually
incompatible. Omit all but one of the mentioned options and restart \textbf{stealth}
    \end{quote}

\texttt{Inserting command `...' failed.}
    \begin{quote}the mentioned command could not be sent to a child-process (\texttt{sh}
or \texttt{ssh}). Check the availability of the \texttt{ssh} connection to the
client, and whether you have permissions to execute the specified command.
    \end{quote}

\texttt{Invalid +NOTRANS(-\{\}-\{\})random-interval specified}
    \begin{quote}The -{}-{}random-interval option was given an invalid (too large or
        negative) argument.
    \end{quote}

\texttt{invalid +NOTRANS(-\{\}-\{\})$<$option$>$ specified}
    \begin{quote}The specified option value (e.g., \texttt{+NOTRANS(-\{\}-\{\})max-size} was specified, but
its option value is not a valid integral number) is not supported
    \end{quote}

\texttt{LocalClientSocket::connect(): ...}
    \begin{quote}When running in IPC-mode \textbf{stealth} could not connect to the unix domain
socket specified for the IPC-mode. Check whether the matching \textbf{stealth} daemon
exists, and whether the location of the uds-file was correctly specified
    \end{quote}

\texttt{LocalServerSocket::accept(): ...}
    \begin{quote}When running in daemon mode incoming connections could not be
accepted. This may have many causes, and a probably cause is mentioned with
the error message
    \end{quote}

\texttt{LocalServerSocket::listen(): ...}
    \begin{quote}When running in daemon mode the unix domain socket failed to
listen for incoming connections. This may have many causes, and a probably
cause is mentioned with the error message
    \end{quote}

\texttt{LocalServerSocket::open($<$uds$>$): ...}
    \begin{quote}When running in daemon mode the unix domain socket could not be
opened. A possible reason is that an entry in the file system having the same
name already exists. The error message will mention a probably cause of the
failure
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})max-size incompatible with IPC calls}
    \begin{quote}The \texttt{+NOTRANS(-\{\}-\{\})max-size} option can can only be used when \textbf{stealth} is also
receiving a policy file. It cannot be used in combination with the Inter
Process Communication (IPC) options \texttt{+NOTRANS(-\{\}-\{\})reload, +NOTRANS(-\{\}-\{\})rerun, +NOTRANS(-\{\}-\{\})resume, +NOTRANS(-\{\}-\{\})suspend}
or \texttt{+NOTRANS(-\{\}-\{\})terminate}.
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})max-size $<$value$>$: invalid option value}
    \begin{quote}An invalid specification for \texttt{+NOTRANS(-\{\}-\{\})max-size} was received. Refer to
the man-page or manual for information about valid options.\end{quote}

\texttt{No exit value for $<$cmd$>$ ...}
    \begin{quote}No exit value was received for the logged command, after which \textbf{stealth}
terminates. 
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})$<$option$>$ is only valid for a s() foreground process}
    \begin{quote}The indicated option cannot be specified in combination with a
\texttt{+NOTRANS(-\{\}-\{\})daemon} or IPC-option (like \texttt{+NOTRANS(-\{\}-\{\})suspend})
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})random-interval requires +NOTRANS(-\{\}-\{\})repeat}
    \begin{quote}The \texttt{+NOTRANS(-\{\}-\{\})random-interval} option can only be used when the
\texttt{+NOTRANS(-\{\}-\{\})repeat} option has also been specified.
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})repeat not available in IPC modes}
    \begin{quote}The \texttt{+NOTRANS(-\{\}-\{\})repeat} option cannot be specified in combination with an    
IPC-option (like \texttt{+NOTRANS(-\{\}-\{\})suspend})
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})run-command 0: not a valid (natural) command number}
    \begin{quote}The \texttt{+NOTRANS(-\{\}-\{\})run-command} option requires an argument, which is a
positive, integral value.
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})run-command $<$nr$>$: invalid command number}
    \begin{quote}The \texttt{+NOTRANS(-\{\}-\{\})run-command} option requires an argument, which is a
positive, integral value at most equal to the number of commands listed in the
policy file.
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})skip-files incompatible with IPC calls}
    \begin{quote}The \texttt{+NOTRANS(-\{\}-\{\})skip-files} option can only be used when \textbf{stealth} is also given
a policy file. It cannot be used in combination with IPC options (\texttt{+NOTRANS(-\{\}-\{\})reload,
+NOTRANS(-\{\}-\{\})rerun, +NOTRANS(-\{\}-\{\})resume, +NOTRANS(-\{\}-\{\})suspend} or \texttt{+NOTRANS(-\{\}-\{\})terminate}).
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})skip-files: missing skip-file or policy file}
    \begin{quote}The \texttt{+NOTRANS(-\{\}-\{\})skip-files} option requires a file name and the \textbf{stealth} command
also requires a policy file. Most likely the name of the skip-file was not
provided, thus confusing the policy file with the skip-file.
    \end{quote}

\texttt{+NOTRANS(-\{\}-\{\})stdout incompatible with +NOTRANS(-\{\}-\{\})daemon}
    \begin{quote}The \texttt{+NOTRANS(-\{\}-\{\})stdout} option can only be used when \textbf{stealth} is not started as
a daemon process.
    \end{quote}

\texttt{syslog facility $<$facility$>$ not supported}
    \begin{quote}The option \texttt{+NOTRANS(-\{\}-\{\})syslog-facility} requires the name of a standard
\textbf{syslog}(1) facility. Supported facilities are \texttt{DAEMON, LOCAL0} through
\texttt{LOCAL7} and \texttt{USER}. See, e.g., the \textbf{syslog}(3) man-page for an overview
of their definitions.\end{quote}

\texttt{+NOTRANS(-\{\}-\{\})syslog$*$ options incompatible with IPC calls}
    \begin{quote}\texttt{+NOTRANS(-\{\}-\{\})syslog$*$} options can can only be used when \textbf{stealth} is also
receiving a policy file. It cannot be used in combination with the Inter
Process Communication (IPC) options \texttt{+NOTRANS(-\{\}-\{\})reload, +NOTRANS(-\{\}-\{\})rerun, +NOTRANS(-\{\}-\{\})resume, +NOTRANS(-\{\}-\{\})suspend}
or \texttt{+NOTRANS(-\{\}-\{\})terminate}.
    \end{quote}

\texttt{syslog priority $<$priority$>$ not supported}
    \begin{quote}The option \texttt{+NOTRANS(-\{\}-\{\})syslog-priority} requires the name of a standard
\textbf{syslog}(1) priority. All standard priorities are supported. See, e.g., the
\textbf{syslog}(3) man-page for an overview of available priorities. The prefixes
used with the priorities in this man-page (i.e., \texttt{LOG\_} should not be used
when specifying the \texttt{+NOTRANS(-\{\}-\{\})syslog-priority}. E.g., use \texttt{+NOTRANS(-\{\}-\{\})syslog-priority
WARNING} rather than \texttt{+NOTRANS(-\{\}-\{\})syslog-priority LOG-WARNING})
    \end{quote}

\texttt{terminated: non-zero exit value for `...'}
    \begin{quote}A local command (not using the \texttt{CHECK} keyword), returned with a
non-zero exit. This will terminate further processing of the policy
file. Inspect and/or rerun the command `by hand' to find indications about
what went wrong. The report file or the standard error stream may also contain
additional information about the reason of the failure.
    \end{quote}

\texttt{Unable to create the logfile `...'}
    \begin{quote}the mentioned log file could not be created. Check the permissions of
the file, check if the path to the file exists. The problem may be in a path
component, not necessarily in the last element of the path or in the file
itself.
    \end{quote}

\texttt{Unix Domain Socket `$<$uds$>$': already in use, remove it first}
    \begin{quote}The intended Unix Domain Socket name (\texttt{$<$uds$>$}) is already in
use. It could be a file that is or has been used by another process. Either
use another name for the unix domain socket, or remove the existing
file-system entry\end{quote}

\texttt{USE SSH ... entry missing in the policy file}
    \begin{quote}there is no default for the \texttt{USE SSH} specification in the policy
file. The specification could not be found. Provide a specification like:
    \begin{verbatim}
USE SSH     ssh -q root@localhost
\end{verbatim}

    \end{quote}

\end{document}
