Directory Digests - Version 0.90 - README
=========================================

CONTENTS

    OVERVIEW
    FEATURES
    EXAMPLES
    INSTALLATION
    DEPENDENCIES
    ISSUES
    HISTORY
    FUTURE
    AUTHOR
    RIGHTS

OVERVIEW

Dirgest is a compact suite of development modules and operational 
scripts that provide a comprehensive ability to work with digests 
of file and directory sets. The modules provide building blocks for
developers, while the scripts are directly useful for local host 
and web site administration. 

Two modules are supplied: Digest::Directory::{BASE,API}.pm
Two scripts are supplied: dirgest.{pl,cgi}

Primary applications are security and integrity.

The author uses this suite to verify correct replication of data 
from local host to non-CLI access remote web site, and then ongoing 
verification that web site content is consistent. The suite is 
also used to ensure integrity of local host (OpenBSD) installation.

The most recent version is always available on CPAN or from the 
author (matthew.gream@pobox.com).


FEATURES

Primary features of the package are:

    - developer BASE and API modules to provide low and high 
      level perl access to dirgests. 

    - operational CLI and CGI scripts to provide command line 
      and common-gateway-interface access to dirgests.

    - uses Digest::MD5.

    - computes a 'dirgest' (ternary of 'digest', 'size', 'name' 
      for given file), and also computes master dirgest across
      all consitituent dirgests.

    - allows file/directory sets to be specified as 'include'
      or 'exclude' entries, either from command line, config
      file, CGI parameters or method calls.

    - allows file/directory sets to have leading name
      components trimmed in compute, fetch and load 
      operations to support cross-host activities.

    - uses LWP::UserAgent to access files and CGI resources,
      allowing media transparency (support HTTP basic
      authentication, and secure mode on cgi resources).

    - object oriented modules, code level trace information
      about activities, comprehensive unit tests and
      documentation.


EXAMPLES

Example 1: save and verify contents of directories (CLI scripts).

    Various examples of usage, from the command line:

    | ------------------------------------------------
    | 
    | napa:tmp $ dirgest.pl --version
    | Directory Digest CLI v0.90 -- Matthew Gream <matthew.gream@pobox.com>
    |     Copyright 2002 Matthew Gream. All Rights Reserved.
    | napa:tmp $ 
    | 
    | ------------------------------------------------
    | 
    | napa:tmp $ dirgest.pl --filename /tmp/dirgests.txt create +/etc
    | Directory Digest CLI v0.90 -- Matthew Gream <matthew.gream@pobox.com>
    |     Copyright 2002 Matthew Gream. All Rights Reserved.
    | including /etc
    | CREATING
    | computing from /etc
    | Can't opendir(/etc/ssl/private): Permission denied
    | Can't opendir(/etc/isakmpd/private): Permission denied
    | writing to /tmp/dirgests.txt
    | napa:tmp $ wc -l /tmp/dirgests.txt
    |      138 /tmp/dirgests.txt
    | napa:tmp $ 
    | 
    | ------------------------------------------------
    | 
    | napa:tmp $ dirgest.pl --quiet show +/etc > /tmp/dirgests2.txt
    | Can't opendir(/etc/ssl/private): Permission denied
    | Can't opendir(/etc/isakmpd/private): Permission denied
    | napa:tmp $ diff /tmp/dirgests2.txt /tmp/dirgests.txt
    | napa:tmp $ 
    | 
    | ------------------------------------------------
    | 
    | napa:tmp $ echo '+/etc' >dirgest.conf
    | napa:tmp $ cat dirgest.conf
    | +/etc
    | napa:tmp $ dirgest.pl --quiet --configure=dirgest.conf show \
    |            >/tmp/dirgests3.txt
    | Can't opendir(/etc/ssl/private): Permission denied
    | Can't opendir(/etc/isakmpd/private): Permission denied
    | napa:tmp $ diff /tmp/dirgests.txt /tmp/dirgests3.txt
    | napa:tmp $ 
    | 
    | ------------------------------------------------
    | 
    | napa:tmp $ ls /usr/local/share/gnupg
    | options.skel
    | napa:tmp $ dirgest.pl --quiet show +/usr/local/share/gnupg
    | = FEy7kEGM+dOntCi0Z/0KRg== 000000004492 /usr/local/share/gnupg/options.skel
    | # jicFVzLgkWo8E9CCmQwX2g==
    | napa:tmp $ dirgest.pl --quiet --trim=3 show +/usr/local/share/gnupg
    | = FEy7kEGM+dOntCi0Z/0KRg== 000000004492 share/gnupg/options.skel
    | # KnnYjjTVmGImyBUxLdWmBg==
    | napa:tmp $ dirgest.pl --quiet --trim=4 show +/usr/local/share/gnupg
    | = FEy7kEGM+dOntCi0Z/0KRg== 000000004492 gnupg/options.skel
    | # ZEJoUs+1ZIxgsosL+xR1rg==
    | napa:tmp $ 
    | 
    | ------------------------------------------------
    | 
    | napa:tmp $ dirgest.pl --quiet show +/usr/local/bin | wc -l
    |      247 
    | napa:tmp $ dirgest.pl --quiet --nodetails show +/usr/local/bin | wc -l
    |        1 
    | napa:tmp $ 
    | 
    | ------------------------------------------------
    | 
    | napa:tmp $ dirgest.pl --filename=dirgests_bin.txt create \
    |            +/usr/local/bin
    | Directory Digest CLI v0.90 -- Matthew Gream <matthew.gream@pobox.com>
    |     Copyright 2002 Matthew Gream. All Rights Reserved.
    | including /usr/local/bin
    | CREATING
    | computing from /usr/local/bin
    | writing to dirgests_bin.txt
    | napa:tmp $ 
    | 
    | ------------------------------------------------
    | 
    | napa:tmp $ mkdir temp
    | napa:tmp $ echo 'foo' > temp/a
    | napa:tmp $ echo 'bar' > temp/b
    | napa:tmp $ echo 'soa' > temp/c
    | napa:tmp $ echo '+temp' > dirgest.conf
    | napa:tmp $ cat dirgest.conf
    | +temp
    | napa:tmp $ 
    | 
    | napa:tmp $ dirgest.pl --configure=dirgest.conf --filename=dirgest.txt \
    |            create
    | Directory Digest CLI v0.90 -- Matthew Gream <matthew.gream@pobox.com>
    |     Copyright 2002 Matthew Gream. All Rights Reserved.
    | configuring from dirgest.conf
    | including temp
    | CREATING
    | computing from temp
    | writing to dirgest.txt
    | napa:tmp $ 
    | 
    | napa:tmp $ cat dirgest.txt
    | = 07BzhNET7exJ6qYjitX/AA== 000000000004 temp/a
    | = wVenkDHhxA+FkxgpvF/FUg== 000000000004 temp/b
    | = VByjna3FKqRpCn/pBcTNBA== 000000000004 temp/c
    | # eDwrWidm1bqhudQSNugM1A==
    | napa:tmp $ 
    | 
    | napa:tmp $ ls -lagt temp
    | total 10
    | drwxrwxrwt  6 root  wheel  512 Oct 21 20:36 ..
    | drwxr-xr-x  2 matt  wheel  512 Oct 21 20:35 .
    | -rw-r--r--  1 matt  wheel    4 Oct 21 20:35 c
    | -rw-r--r--  1 matt  wheel    4 Oct 21 20:35 b
    | -rw-r--r--  1 matt  wheel    4 Oct 21 20:35 a
    | napa:tmp $ 
    | 
    | napa:tmp $ echo 'woa' >temp/c
    | napa:tmp $ dirgest.pl --configure=dirgest.conf --filename=dirgest.txt \
    |            compare
    | Directory Digest CLI v0.90 -- Matthew Gream <matthew.gream@pobox.com>
    |     Copyright 2002 Matthew Gream. All Rights Reserved.
    | configuring from dirgest.conf
    | including temp
    | COMPARING
    | computing from temp
    | reading from dirgest.txt
    | comparing digests
    | ! Pou4+9WzglcSZ/1fIE4SZA== 000000000004 temp/c
    | comparing summaries
    | ? eDwrWidm1bqhudQSNugM1A==
    | comparing differences: 2
    | napa:tmp $ 
    | 
    | napa:tmp $ dirgest.pl --quiet --configure=dirgest.conf \
    |            --filename=dirgest.txt compare
    | ! Pou4+9WzglcSZ/1fIE4SZA== 000000000004 temp/c
    | ? eDwrWidm1bqhudQSNugM1A==
    | napa:tmp $ 
    | 
    | napa:tmp $ dirgest.pl --quiet --show_equal --configure=dirgest.conf \
    |            --filename=dirgest.txt compare
    | = 07BzhNET7exJ6qYjitX/AA== 000000000004 temp/a
    | = wVenkDHhxA+FkxgpvF/FUg== 000000000004 temp/b
    | ! Pou4+9WzglcSZ/1fIE4SZA== 000000000004 temp/c
    | ? eDwrWidm1bqhudQSNugM1A==
    | napa:tmp $ 
    | 
    | napa:tmp $ dirgest.pl --quiet --nodetails --configure=dirgest.conf \
    |            --filename=dirgest.txt update
    | ? eDwrWidm1bqhudQSNugM1A==
    | napa:tmp $ 
    | 
    | napa:tmp $ dirgest.pl --quiet --nodetails --configure=dirgest.conf \
    |            --filename=dirgest.txt update
    | napa:tmp $ 
    | 
    | napa:tmp $ cat dirgest.txt
    | = 07BzhNET7exJ6qYjitX/AA== 000000000004 temp/a
    | = wVenkDHhxA+FkxgpvF/FUg== 000000000004 temp/b
    | = Pou4+9WzglcSZ/1fIE4SZA== 000000000004 temp/c
    | # RG0xlEsyo9W4xLArAbSLlg==
    | napa:tmp $ 
    | 
    | ------------------------------------------------


Example 2: cron-based periodic verification of configuration
    files on local OpenBSD host (CLI scripts).

    a. a trusted host is used to mount the host drive, the
    trusted host has console access only, and contains dirgest
    and configuration in CVS repository.

    b. weekly cron job executes the following:
        - extract DIRGEST from CVS repository
        - run dirgest.pl in update mode with show option to
          update DIRGEST - pipe the output to mail and send
          to administrator + summary to syslog;
        - checkin DIRGEST to the CVS repository

    c. manual script allows operator to update DIRGEST from
    the console.

    (hypothetical example)

Example 3: pre-replication verification of web-site upload, and 
    ongoing cron-based verification, similar to pre/post remote 
    copy verification (CLI and CGI script interaction).

    a. a build script generates the website using Template Toolkit,
    which involves creating content in 'build' from a 'source' 
    directory.

    | ------------------------------------------------
    | napa:www $ ./b
    | BUILDING
    | updating ...
    | building ...
    | ------------------------------------------------

    b. an update script first updates the dirgests and then uses
    a replication script to transfer the updated contents of the
    web site, and then verifies the contents of the web site by
    fetching from the cgi interface.

    | ------------------------------------------------
    | napa:www $ cat u
    | #!/bin/sh
    | 
    | echo UPDATING
    | 
    | EXE_DIRGEST="/usr/local/bin/dirgest.pl"
    | EXE_REPLICATE="/usr/local/bin/replicate.pl"
    | 
    | [...]
    | 
    | echo updating dirgest ...
    | rm -f build/cgi-bin/dirgest/dirgest.txt
    | $EXE_DIRGEST \
    | 	--filename=build/cgi-bin/dirgest/dirgest.txt --trim=1 \
    | 	create \
    | 	-CVS `sed 's,/.*public_html,build,g' < build/cgi-bin/dirgest/dirgest.conf`
    | 
    | [...]
    | 
    | echo uploading ...
    | $EXE_REPLICATE \
    | 	--root=public_html \
    | 	--source=/home/www/build \
    | 	--not=CVS \
    | 	...
    | 
    | [...]
    | 
    | echo verifying ...
    | $EXE_DIRGEST \
    | 	--fetch=http://$HOSTNAME/cgi-bin/dirgest/dirgest.cgi \
    | 	--login=$USERNAME:$PASSWORD \
    | 	--trim=4 \
    | 	--filename=build/cgi-bin/dirgest/dirgest.txt \
    | 	compare
    | 
    | [...]
    | 
    | ------------------------------------------------

    c. the update process results in the following output:

    | ------------------------------------------------
    | napa:www $ ./u
    | UPDATING
    | updating dirgest ...
    | Directory Digest CLI v0.90 -- Matthew Gream <matthew.gream@pobox.com>
    |     Copyright 2002 Matthew Gream. All Rights Reserved.
    | including build
    | excluding CVS
    | excluding build/cgi-bin/dirgest/dirgest.txt
    | excluding build/cgi-bin/perlfect/search/data/sizes
    | excluding build/cgi-bin/perlfect/search/data/content
    | excluding build/cgi-bin/perlfect/search/data/terms
    | excluding build/cgi-bin/perlfect/search/data/titles
    | excluding build/cgi-bin/perlfect/search/data/docs
    | excluding build/cgi-bin/perlfect/search/data/desc
    | excluding build/cgi-bin/perlfect/search/data/urls
    | excluding build/cgi-bin/perlfect/search/data/dates
    | excluding build/cgi-bin/perlfect/search/data/inv_index
    | excluding build/cgi-bin/perlfect/subscribe/mailing_list.txt
    | CREATING
    | computing from build
    | writing to build/cgi-bin/dirgest/dirgest.txt
    | uploading ...
    | [...]
    | scanning remote directory: public_html
    | [...]
    | verifying ...
    | Directory Digest CLI v0.90 -- Matthew Gream <matthew.gream@pobox.com>
    |     Copyright 2002 Matthew Gream. All Rights Reserved.
    | COMPARING
    | reading from build/cgi-bin/dirgest/dirgest.txt
    | fetching from http://matthewgream.net/cgi-bin/dirgest/dirgest.cgi
    | comparing digests
    | comparing summaries
    | comparing differences: 0
    | napa:www $ wc -l build/cgi-bin/dirgest/dirgest.txt
    |      197 build/cgi-bin/dirgest/dirgest.txt
    | napa:www $ head -3 build/cgi-bin/dirgest/dirgest.txt
    | = sxNqlix47RIWoX9sDjC5wA== 000000000002 .cvsignore
    | = tft3saNku+rCpgI0jnht9w== 000000000041 .htaccess
    | = ym+NbPCKfVB2zv1UT/AhCw== 000000000146 cgi-bin/accesslog/.htaccess
    | napa:www $ 
    | ------------------------------------------------
     
    d. a periodic cron job runs to call dirgest.pl against dirgest.cgi
    (on the server) to verify that the website content has not 
    changed. the output is used in a report to the administrator to 
    check for changed site content.

    | ------------------------------------------------
    | napa:www $ cat /usr/local/share/site/site_check
    | #!/bin/ksh
    | #################################################################
    | # $Id: README,v 0.90 2002/10/21 20:24:06 matt Exp matt $
    | #################################################################
    | 
    | [...]
    | 
    | EXE_DIRGEST="/usr/local/bin/dirgest.pl"
    | _DIRGEST_OPTS="--quiet"
    | 
    | [...]
    | 
    | $EXE_DIRGEST $_DIRGEST_OPTS \
    | 	--fetch=http://$HOSTNAME/cgi-bin/dirgest/dirgest.cgi \
    | 	--login=$USERNAME:$PASSWORD \
    | 	--trim=4 \
    | 	--filename=$WWW_BUILD/cgi-bin/dirgest/dirgest.txt \
    | 	compare 
    | 
    | [...]
    | 
    | napa:www $ 
    | ------------------------------------------------


Example 4: verification of tar/zip/archive contents, such as
    with backup, or distribution, or transfer (CLI scripts). a
    wrapper script used to provide the operation. Note that this
    is not cryptographically strong and requires use of some
    form of digital signature for more robust authentication.

    a. archive_create script does the following:
        - stores archive name + files
        - uses dirgest.pl across files to create a DIRGEST
        - uses tar with DIRGEST and files to form archive
    b. archive_extract script does the following:
        - uses tar to extract files and DIRGEST
        - uses dirgest.pl to verify DIGEST against files
        - removes DIRGEST now that operation is complete

    (hypothetical example)


Example 5: use of Digest::Directory::BASE.pm as part of packaging 
    script for software distribution.

    (hypothetical example)


INSTALLATION

To install this module type the following:

   perl Makefile.PL
   make
   make test
   make install

The following modules will be created:

   Digest::Directory::BASE.pm (low level mechanisms)
   Digest::Directory::API.pm (higher level interface)

The following scripts will be created:

   dirgest.pl (Command Line Interface)
   dirgest.cgi (Common Gateway Interface)


DEPENDENCIES

This module requires these other modules and libraries:

   Perl 5.004
   LWP::UserAgent (for Digest::Directory::BASE.pm)
   Digest::MD5 (for Digest::Directory::BASE.pm)
   File::Find (for Digest::Directory::BASE.pm)
   CGI (for dirgest.cgi)
   Getopt::Long (for dirgest.pl)


ISSUES

No known issues are outstanding. 


HISTORY

Version 0.10 - 20 Sep 2002 - Alpha release (internal).
Version 0.90 - 20 Oct 2002 - Beta release (CPAN).


FUTURE

Candidate improvements are:

1. increased configuration file flexibility.
2. use hash for method arguments.
3. include/exclude does better regexp style matching.
4. integrate 'load' and 'fetch' via. LWP to be seamless.
5. remove static's in compute method (is this possible?).
6. allow per-directory dirgest files (e.g. '.dirgest').
7. include contrib/example scripts.
8. support file acl to better support ids style operation.

Suggestions (& patches) warmly welcomed.


AUTHOR

Matthew Gream (MGREAM) <matthew.gream@pobox.com>


RIGHTS

Copyright 2002 Matthew Gream. All Rights Reserved.

This distribution is made available under the same terms and
conditions as the perl distribution. The author offers no
express or implied warranties as to fitness for use. Your
use of this software implies acceptance of these terms and 
conditions.