How to run AAFID(tm) entities
-----------------------------

 ======================================================================
 This file is Copyright 1998,1999 by the Purdue Research Foundation and
 may only be used under license.  For terms of the license, see the
 file named COPYRIGHT included with this software release.
 AAFID is a trademark of the Purdue Research Foundation.
 All rights reserved.
 ======================================================================

All AAFID entities, if written according to the proper rules (described in
the User's Guide, found in doc/papers/users_guide_draft.ps), can be
executed both by other programs (such as a Transceiver) or as
stand-alone programs. This last mode is useful for testing, debugging,
or when you do not have a graphical display available.

When an entity (be it one of the base entities found in classes/AAFID,
or an agent, found in classes/Agents) is run stand-alone, it produces
its messages to standard output (which will normally be your
terminal), and receives commands from standard input (which will
normally be the keyboard). Thus, you can interact directly with it and
see its responses.

To run an entity in stand-alone mode, simply run it using the Perl
interpreter, like this:

  perl -w Entity.pm

where you can replace Entity.pm with the corresponding file name.

NOTE: For the entity to run correctly, you must have the path of the
      "classes" subdirectory of the AAFID2 distribution in your
      PERLLIB environment variable. If Perl complains about classes
      that it cannot find, check the value of PERLLIB. See the file
      INSTALL for more details on how to set PERLLIB correctly.

After its initialization is complete, all entities produce a message
of the following form:

  CONNECT CHILD <id> - <time> <class> <description>

where <id> is the identifier of the entity, generated using the host
name, entity class name, version number, and instance number; <time>
is a numeric representation of the current time; <class> is the class
name of the entity; and <description> is the internal description of
the entity (stored in its "Description" parameter).

The generic form of the messages that entities generate and understand
is the following:

  <type> <subtype> <from> <to> <time> <data>

so in the previous case, we have a message of type CONNECT and subtype
CHILD, which is sent by all entities to its parent entity when they
start. In this case, when an entity is running stand-alone, you are
its parent entity.

After the CONNECT message, the entity may generate other messages,
depending on what type of entity it is. For example, an agent will
almost immediately generate its first STATUS_UPDATE message, which
contains its status after performing a check for the first time.

At this point, you can simply type any messages you want to send to
the entity. Although there are several message types that are used
internally by the system, the only one that you will normally use is
the COMMAND message. This message has the following format:

  COMMAND <commandname> <from> <to> <time> <parameters>

where <commandname> is the name of the command that you want the
entity to execute. Some commands take arguments in the form of named
arguments; in these cases, the parameters have to be specified in the
<data> field. The format of the <parameters> section is as follows:

   Param => Value, Param => Value, ...

this is, a comma-separated sequence of Param => Value sequences. The
parameter names are case insensitive, and have to be unquoted words
containing only letters, numbers and underscores. The values can be
any kind of valid Perl expressions. It is your responsibility to
ensure that the syntax of the expressions is correct.

When you are interacting directly with an entity, the <from> and <to>
fields do not have much significance. We recommend using "me" for
<from> and a dash (-) for the <to> field. The dash in the <to> field
acts as a wild card and instructs the entity that receives the message
to act on it. You can also provide a dash for the <time> field, in
which case the message is automatically given the time stamp of the
moment in which it is processed.

A typical command that you may type, therefore, looks like this:

  COMMAND SET_PARAMS me - - CheckPeriod => 10, MyUsers => ['foo', 'bar']

which instructs the entity to execute its SET_PARAMS command, passing
it the arguments CheckPeriod with a value of 10, and MyUsers with a
value of an anonymous list reference to a list containing two strings.

Normally, entity commands do not produce any return values. There are,
however, some commands that do, either by its normal functionality or
as a result of an error. When a command produces a return value, it is
sent back to the entity that requested the command (in this case, you)
as a message of the following form:

  COMMAND RESULT <from> - <time> Command => '<commandname>', <return values>

where <commandname> is the name of the command that produced the
result, and <result values> is a standard sequence of Param => Value
pairs, containing the results produced by the command.

Next, we list the standard commands that some of the standard entities
and agents receive. In this listing, only the command name and
arguments are listed. Remember to type them in the proper format when
you try them with a running entity.

- Standard commands (all entities)

  STOP
	Stops the execution of an entity. Before stopping, the entity
	will send a DISCONNECT message up.

  EVAL Code => "<Perl code>"
       Instructs the entity to execute the Perl code provided, in the
       context of the entity. If the code produces a value other than
       "undef", it is returned.

  SET_PARAMS Param1 => Value1, Param2 => Value2, ...
       Sets the given parameters to the given values.

  GET_PARAMS Params => "Param1, Param2"
       Returns the values of the requested parameters.

  DUMP_YOURSELF
       Returns the internal representation of the entity, which
       contains the current values of all its parameters. Useful for
       debugging and getting an idea of what is going on inside the
       entity.

- ControllerEntity commands (Transceivers and Monitors)

  START Class => "<classspec>"
       Starts running a new entity. Transceivers only have the
       capability of starting local entities, whereas Monitors can
       start both local and remote entities. The <classspec> for a
       local entity has to be the full Perl name of the entity. For
       example, if you want to start a new local PlainTransceiver, you
       would have to type:

         COMMAND START me - - Class => 'AAFID::PlainTransceiver'
   
       The AAFID:: prefix is necessary because it is part of the full
       name of the class.
       
       To start a remote class using a Monitor, you have to prepend the
       host name and a colon to the <classspec>. For example, to start
       a PlainTransceiver in host fiji, you would type:

         COMMAND START me - - Class => 'fiji:AAFID::PlainTransceiver'

  LISTENTITIES
       Returns a list of the entities that the current entity is
       controlling. The entities as returned as their full entity IDs.

  KILL Entities => 'entity1, entity2,...'
       Given the full entity IDs of entities that are being controlled
       by the current one, instructs them to terminate. Notice that in
       this case you will not see the DISCONNECT messages, because
       they are received and processed by the controller entity.

  ADDPATH Path => "path"
       Adds the specified path (it can be a comma-, space- or
       colon-separated list of multiple paths) to the internal @INC
       array, so that those directories will also be searched when you
       request new entities to be started. Useful mostly for debugging
       purposes, because the standard classes/ and classes/Agents
       directories are automatically searched.

- Monitor commands (only the AAFID::Monitor class and its subclasses)

  STARTTRANSCEIVER Host => '<hostname>'
       Starts a new transceiver in the specified host. If a
       transceiver is already running in the specified host, no action
       is taken.

- Agent commands (all agents, descendents of AAFID::Agent):

  REPORT_STATUS
       Instructs the agent to return a message containing its current
       status and message.

- CheckRhosts commands (classes/Agents/CheckRhosts.pm):

  ADDUSERS Users => 'user1, user2,...'
       Adds the specified users to the list of those whose .rhosts
       files are going to be periodically checked.

  LISTUSERS
       Returns a list of all the users that the agent is currently
       monitoring.

  DELUSERS Users => 'user1, user2,...'
       Stops monitoring the specified users.

- CmdSequence commands (classes/Agents/CmdSequence.pm):

  SETFILE File => '<file>'
       Sets the file from which process accounting records can be read
       to detect which processes are executed.

  SETSEQUENCE Sequence => 'cmd1, cmd2,...'
       Sets the sequence of process names to detect.

- CheckFilePermissions commands
  (classes/Agents/CheckFilePermissions.pm):

  ADD_FILES Permission=>[flags,list_of_files]:
       Adds the listed files to the check list with the specified
       permission.
        ex. Permission=>[0644,"/etc/passwd","/etc/.login"]

  REMOVE_FILES Files=>[list_of_files]
       Removes the named files from the list to check
        ex. Files=>["/etc/passwd","/etc/.login"]

  LIST_FILES
       Returns the list of files being checked
        ex of result: (/etc/passwd,429,/etc/.login,429)
        NOTE: It does not convert the value back to octal!

  SIMPLE_SCORING()
       Set the scoring type to be simple. There are now two types of
       scoring - the first is a simple scoring mechanism based on
       simply increasing the state by one.  The second uses a vector
       of values that are added if a given bit in the 12 bit
       permission flag differs.

  VECTOR_SCORING()
       Set the scoring type to be vector based. See above.

  ADD_SCORE_VECTOR Vector=>[[vector values],list_of_files]
       Sets the scoring vector for the listed files to be the given
        ex.  Vector=>[[0,0,0,1,1,1,2,2,2,3,5,1],"/etc/passwd","/etc/login"]


The following is a sample session of running a Monitor. The lines
where the "command" is in lower case were typed by the user, and the
ones in upper case are the responses from the Monitor. Some
explanatory comments are included in the lines starting with an
asterisk (*) (these are not part of the log). The blank lines were
also introduced to improve readability.

% cd /usr/local/AAFID2/classes/AAFID
% perl -w Monitor.pm

CONNECT CHILD narnia:Monitor:1.16:0 - 898918404 AAFID::Monitor Base Monitor Class

command start me - - Class => 'CheckRhosts'

STATUS_UPDATE NOTYPE narnia:CheckRhosts:1.10:0 - 898918420 Status =>
0, Message => 'Read::Write:'

* We started a local agent, and we get its first status report.

command listentities

* Notice how you can omit the rest of the fields if the command does
  not take arguments.

COMMAND RESULT narnia:Monitor:1.16:0 - 898918423 Entities => 'narnia:CheckRhosts:1.10:0',Command => 'LISTENTITIES'

command start me - - Class => 'barnum:CheckInet'

* By requesting to start an agent in barnum, an associated transceiver
  in barnum is automatically started. See the listentities command below.

STATUS_UPDATE NOTYPE barnum:CheckInet:1.06:0 - 898918445 Status => 0, Message => 'No service to monitor has been specified'

* This is the first status report from the agent in barnum. Notice the
  <from> field (third one)

command listentities

COMMAND RESULT narnia:Monitor:1.16:0 - 898918448 Entities => 'narnia:CheckRhosts:1.10:0,barnum:PlainTransceiver:1.06:0',Command => 'LISTENTITIES'

* Notice that the local monitor does not directly control the
  CheckInet agent in barnum, but instead it controls a
  PlainTransceiver object there.

command listentities me barnum:PlainTransceiver:1.06:0

* Here we query the transceiver in barnum directly for its agents.

COMMAND RESULT barnum:PlainTransceiver:1.06:0 - 898918460 Entities => 'barnum:CheckInet:1.06:0',Command => 'LISTENTITIES'

* In the result we see that it is the transceiver in barnum who
  controls the CheckInet agent, even though we requested it to be
  started. 

command setservice me barnum:CheckInet:1.06:0 - Service => 'ftpd'

* Here we send a command directly to the CheckInet agent in barnum,
  telling it to monitor for accesses to the ftp service.

STATUS_UPDATE NOTYPE barnum:CheckInet:1.06:0 - 898918485 Status => 0, Message => 'Requests to ftpd: 0'

command starttransceiver me - - Host => 'lorien'

* We request a new transceiver in lorien.

command listentities

COMMAND RESULT narnia:Monitor:1.16:0 - 898918515 Entities => 'narnia:CheckRhosts:1.10:0,barnum:PlainTransceiver:1.06:0,lorien:PlainTransceiver:1.06:0',Command => 'LISTENTITIES'

STATUS_UPDATE NOTYPE barnum:CheckInet:1.06:0 - 898918525 Status => 1, Message => 'Requests to ftpd: 1'

* This message was produced because someone established an ftp
  connection to barnum. The status of the agent changed, and thus we
  received a status update.

command stop

* This command has also the effect of stopping all the entities that
  the local Monitor is controlling.

DISCONNECT CHILD narnia:Monitor:1.16:0 - 898918529 STOP command or message

* The data field of the DISCONNECT message tells the reason. We could
  have also typed simply "stop", or pressed Ctrl-D (end-of-file) to
  get the same effect.
