ARCv2

 view release on metacpan or  search on metacpan

lib/Arc/Command.pod  view on Meta::CPAN

=head1 NAME

Arc::Command - Abstract base class for ARCv2 commands

=head1 DESCRIPTION

ARC allows non-privileged users to run privileged commands on the server.
The server decides if the user is allowed to run this command through ACL.

This file is a part of the Perl ARCv2 module suite. ARCv2 is a 
rewrite of ARC by R.Toebbicke, CERN, Switzerland in Perl. 

=head1 ABSTRACT

From ARC by R. Toebbicke, modified by me:
User requests are shipped from a client machine to a server using a
SASL-authenticated socket connection. The purpose is to convey
requests such as privileged commands (e.g. AFS, Crontab) to be executed on the
server under appropriate privileges. Given that all privileges are
confined to the server and the server can be programmed as to filter and
check the command to be executed, the client machine can be less trusted
than the server.

Because ARC-v1-Commands are written in perl anyway, implementing the client/server
in perl makes sense. Platform-independence and "easy-to-read" source code are welcome
too. This package provides two perl command line scripts (arcx, arcxd). They can
be used for working with the ARC server from the command line, resp. to start the
server.

=head1 SYNOPSIS

This module is part of the module suite ARCv2.

This is the command module from ARCv2. If we would use C++, we would say
this is an abstract class of an ARC Command. All commands used by ARCv2 should
derive from this class.

=head1 HOW DOES IT WORKS

This abstract class is the base class for all existing ARCv2 commands and 
should be the base class for all new ARCv2 commands.
 
When starting the ARCv2 Server you have to pass a important hash:

 $arc = new Arc::Server ( 
    [..] Arc::Server vars [..],
   connection_vars => { 
      commands => { 
        'pv' => 'Arc::Command::Pv'
      } 
   }
 )  
 
 resp.

 $arc->{connection_vars}->{commands}

This hash describes the assignment of B<Command Name> and B<Command Class>. 
When a client has authenticated and wants to run a command, it will send 
the B<Command Name> and suitable, optional parameters. The server will look into 
the commands hash and creates an object of the B<Command Class> 
associated with B<Command Name>.

 my $perlcmd = $this->{commands}->{$cmd};
 [..]
 eval "require $perlcmd;"
 [..]
 (fork)
 my $ret = eval
 {
  my $object = new $perlcmd(
    _username => $this->{_username},
    _peeraddr => $this->{peeraddr},
    _peerport => $this->{peerport},
    _peername => $this->{peername},
    _cmd => $cmd,
    logfileprefix => "command",
  );
  $object->Execute(@a);
  $cmderr = $object->IsError();

  return -1;
 };
 
When everything went alright, the command will be executed. The command runs
in a separate process. Therefore STDIN, STDOUT and STDERR are duped to two
pipes, one for the in, one for the out direction. In the parent process data
from the encrypted network command connection is read from and written to these pipes.
Same situation on the client side, STDIN and STDOUT are used to put and get the 
data through the network.
 
                   encrypted
          /--->>---| net- |--->>-----\   
        / /---<<---| work |---<<-----\ \
      / /                              \ \
     | |     in                         | |    p2
  |--------|->>--\                  |--------|->>--\ 
  | Client | out   \                | Server | p1    \
  |--------|-<<-\    \              |--------|-<<-\    \ 
                /|\  \|/                          /|\  \|/
               |--------|                       |-----------|
               |  User  |                       |  Command  |
               |--------|                       |-----------|



( run in 0.480 second using v1.01-cache-2.11-cpan-39bf76dae61 )