Here is my proposed solution to the encrypted partion/backup
problem posed by Vim.  As part of my "educational task" I've included
it here as a shell archive, an olde-tyme way of distributing stuff.

If you're unfamiliar with shar's   man shar   right now.

Much of this code requires root.  There are defaults for most
of the stuff that relate to my test environment.  It needs quite
a bit of free disk to work right.  Study hard before using!
Lots of fun tricks can be done with a shell archive. 

This shar may not unshar properly if you cut&paste from some sort
of goofy mail client that uses bizarre fonts and formatting.  I will
NOT help with that problem.  Get a real mail client.

Make a fresh directory, cd there and unshar the stuff below as an
unprivileged user.  You should be cd to this directory to use this
stuff.

Nearly all the variable stuff is in file archive.defs.  That
will need to be edited to fit your system.

FILES:

archive.defs    -- definitions  Edit for your system
distfile        -- distfile for rdist  Edit for your system
makedata        -- makes a lot of fake data and directories
*mountarchive    -- sets up and mounts the svnd filesystem  
*unmountarchive  -- umounts the svnd filesystem and "regular" file
xrdist          -- wrapper for rdist

* = needs root or sudo to run mount, vnconfig and umount.

See other post for benchmarks

Criticism welcome and expected.  Questions answered.  Modifications 
considered.  Should be useful to learn about svnd's.

I've run this stuff a lot and it seems to work.

Dave
 ----------------------------------8<----------------------------- cut here
# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#       archive.defs
#       distfile
#       makedata
#       mountarchive
#       unmountarchive
#       xrdist
#
echo x - archive.defs
sed 's/^X//' >archive.defs << 'END-of-archive.defs'
X#! /bin/sh
X#
X# Tailor these to your system
X#
X#  The FOO=${FOO:="default"} allows the default to be over-ridden from the
X#  environment by export or on the command line.
X
XVIMDATA=${VIMDATA:="/home/vim/data"}   
X               # Directory tree where the data files lie.
X               # All files in and under this directory will be archived.
X
XSVNDMOUNT=${SVNDMOUNT:="/home/vim/archive"}
X               # Directory tree where the crypted archive will be mounted.  
X
XVIMARCH=${VIMARCH:="/home/vim/archive/vimdata"}
X               # This will be a mirror of VIMDATA
X
XUSBMOUNT=${USBMOUNT:="/home/vim/usbmnt"}
X               # Where the usb drive partition will be mounted.  
X               # Probably should have a "dot" as its first letter, e.g. 
X               # /home/vim/.usbmnt
X               # This should be an empty directory (typical mount point).
X               # It should be possible to have USBMOUNT be the ~same~ as
X               # SVNDMOUNT, (I have tried this a little), which would hide
X               # the regular file (SVNDFILE) from normal activity. (You
X               # can mount more than one fs on a mount point in BSD.)
X               # This should be explored later.
X
XMOUNTOPT="-o softdep"          
X               # async makes no improvement.  This is used for both the 
X               # raw USB mount and for mounting the svnd filesystem.
X
XUSBDEV=${USBDEV:="/dev/sd0m"}
X               # The device and partition on the USB drive; this may vary 
X               # from time to time, since the USB driver assigns it on the 
X               # fly, I think. I don't have a USB drive, so this is a spare
X               # partition on a normal scsi drive.
X
XSVNDFILE=${SVNDFILE:="svndfile"}
X               # Name of the file to hold the crypto fs.  This is a regular 
X               # file on the USB drive.
X               # This may be a path from the root ("/") of the USB drive.  
X               # The archive file system, encrypted, lives in this file; 
X               # it is made accessible through vnconfig.  It is not a wise
X               # plan to access this file while the vnd is configured to it.
X
XSVNDFILESZ=${SVNDFILESZ:=3000000}
X               # The size of the archive in KB -- try to be at least as 
X               # large as du -s $VIMDATA, +10%
X               # see output of "du -sk $VIMDATA | cut -f1" 
X               # I didn't code this check in.
X               # It may be possible to expand (but not shrink) the size of 
X               # SVNDFILE using growfs as an extraordinary event.  Later on 
X               # that, "version 2". (I have done it, but it is tricky with
X               # an encrypted svnd.
X
XSVND=${SVND:="svnd0"}           
X               # This may vary, if svnd's are used for something else,
X
XSVNDpartition="c"              
X               # Partition to use on the svnd crypto fs.
X
XSVNDOPT=${SVNDOPT:="-k -v"}
X               # "-k" for blowfish, "" for no encryption.
X               # Eventually -K should be used.  -K and -k are different.  
X               # Possible other useful options are -v (verbosity).
END-of-archive.defs
echo x - distfile
sed 's/^X//' >distfile << 'END-of-distfile'
X#File for mirroring /home/vim stuffs
X# This is not a shell script, it is the "distfile" for rdist(1)
X# This file should not need to be run as root if the ownership
X# and modes on the relevant files are OK.  It is defaulted to root
X# because that is how I tested it.
X
Xdata=/home/vim/data
Xarchive=/home/vim/archive/vimdata
Xrdistuser=root
X
Xvim:   ${data} -> [EMAIL PROTECTED]
X       install -oremove ${archive} ;
END-of-distfile
echo x - makedata
sed 's/^X//' >makedata << 'END-of-makedata'
X#! /bin/sh
X#  Creates fake data for testing and benchmarking.
X
Xif [ `uname -n` != "rachel.chuck" ]; then
X        echo This is for the woodchuck to run on his machine.
X        echo Edit \`makedata\' and take out the uname test to run it, if you 
dare.
X        exit 1
Xfi
X
X. ./archive.defs
X
X# creates fake data files in the directory ${VIMDATA} -- be careful!
X# They are filled with weak pseudorandoms.  This was for testing
X# by me, and is not part of any archive scheme.
X
X# first make ten big files, 100MB each
X
Xfor f in 0 1 2 3 4 5 6 7 8 9
Xdo
X       fname=${VIMDATA}/data.big.${f}
X       if [ ! -f ${fname} ] ; then
X               dd if=/dev/prandom of=${fname} bs=1m count=100
X       else 
X               echo ${fname} already exists.
X       fi
Xdone
X
X# now make some subdirectories and populate them
X
X# this creates two files in the current working directory,
X# mk1000.c and mk1000,  They are deleted after they are used,
X# If they already exist, they're overwritten and then deleted.
X# Beware.
X
X# illustrates use of cc in a script
X# illustrates a "here" document (<<)
X# illustrates certain germane system calls.
X
X# by a miracle of sh, sh variables will be substituted in the
X# "here" document.  That's why I chose this rather than coding
X# up a bunch of getenv(3) calls in a separate source file.
X
Xcat >mk1000.c <<__EOF__
X
X#include <err.h>
X#include <errno.h>
X#include <fcntl.h>
X#include <stdio.h>
X#include <sys/param.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#define SIZBUF 1024
Xunsigned char buffer[SIZBUF];
X
Xint
Xmain(int argc, char **argv)
X{
X       int i, j, n;
X       int numfil;
X       int numdir;
X       int sizfil;
X       int infd, outfd;
X       char filename[MAXPATHLEN];
X
X       if(argc!=4) errx(1,"wrong args %d", argc);
X       numdir= atoi(*++argv);
X       numfil= atoi(*++argv);
X       sizfil= atoi(*++argv);  
X       fprintf(stderr,"%d dirs, %d files/dir, %d kB each\n",
X               numdir, numfil, sizfil);
X       if((infd= open("/dev/prandom", O_RDONLY))==-1) err(1, "/dev/prandom");
X
X       while(numdir--) {
X               snprintf(filename, MAXPATHLEN-1, "${VIMDATA}/dir.%.3u", numdir);
X               if(mkdir(filename, 0777)== -1 && errno != EEXIST) 
X                       err(1, filename);
X               if(chdir(filename)== -1)  err(1,filename);
X               fprintf(stderr,"Populating: %s ", filename);
X
X               for(i=0;i<numfil;i++) {
X                       snprintf(filename, MAXPATHLEN-1, "data.%.3u", i);
X                       if((outfd= open(filename, O_WRONLY|O_CREAT|O_EXCL, 
X                               0666))== -1 && errno != EEXIST) err(2,filename);
X                       if(outfd!= -1) {
X                               for(j=0;j<sizfil;j++) {
X                                       if((n = read(infd, buffer, SIZBUF))<=0)
X                                               err(3,filename);
X                                       if(write(outfd, buffer, n)<=0)
X                                               err(4,filename);
X                               }
X                               close(outfd);
X                               if(((i+1)%10) == 0) fputc('.', stderr);
X                       }
X               }
X               if(chdir("${VIMDATA}")==-1) err(12,"chdir to ..");
X               fputc(isatty(fileno(stderr))?'\r':'\n', stderr);
X       }
X       if(isatty(fileno(stderr))) fputc('\n', stderr);
X       return 0;
X}
X__EOF__
X
X# complie the program just copied to mk1000.c
X# No, for security reasons, this should not be taking place in /tmp.
X
Xrm -f mk1000
Xcc -O2 -o mk1000 -pipe mk1000.c
X
X# Run it.
X# usage:  mk1000 subdirectories, files per subdirectoty, KB per file
Xif ./mk1000  100 100 100 ; then
X       echo DONE
Xelse
X       echo FAILED $?
Xfi
X
X# Thank-you, bye-bye
Xrm -f mk1000 mk1000.c
X
Xecho --Done--
END-of-makedata
echo x - mountarchive
sed 's/^X//' >mountarchive << 'END-of-mountarchive'
X#! /bin/sh
X#
X# mounts the usb drive 
X# associates a svnd with the file named SVNDFILE on the usb drive
X# mounts the named partition on SVNDMOUNT
X
X# source in various definitions
X
X. ./archive.defs
X
X# first, mount the USB drive.  In this case it is actually a partition
X# on a scsi fixed drive of mine.
X# Use async if you dare, instead of softdep
X
Xif ! mount ${MOUNTOPT} ${USBDEV} ${USBMOUNT} ; then
X       exit 1
Xfi
X
X# check for the existence of the SVNDFILE, possibly creating it
X
XNEEDSNEWFS=0
Xif [ ! -f ${USBMOUNT}/${SVNDFILE} ] ; then
X       echo File not found: ${USBMOUNT}/${SVNDFILE}
X       echo creating file ${USBMOUNT}/${SVNDFILE}, size is ${SVNDFILESZ}KB
X       dd if=/dev/prandom of=${USBMOUNT}/${SVNDFILE} bs=1k count=${SVNDFILESZ}
X# Now it needs to have a file system built on it, after vnconfig!
X# remember this fact
X       NEEDSNEWFS=1
Xfi
X
X# associate the file with an svnd
X# Should really be using -K, -f and a salt file.
X# Save -K for version 2 ;-)  
X#
X# -k is what turns on encryption.  It prompts for
X# a secret key.
X
Xif ! vnconfig  ${SVNDOPT} ${SVND} ${USBMOUNT}/${SVNDFILE} ; then
X       exit 2
Xfi
X
X#
X# if the file has been disklabelled manually, or the partion
X# *in the file* (not of the usb disk) desired is not "c", then
X# change newfs options to reflect that fact!
X#
X# Note that no diskabelling is done here.  We use the default
X# disklabel, which will mean that only partition "c" is available.
X# This is not "good" for usual disks, but is OK for floppies and
X# various memory disks like this one.  (I THINK).  If this
X# is not true, then disklabel will have to be run.
X#
Xif [ ${NEEDSNEWFS} != 0 ] ; then
X       if ! newfs -o time /dev/r${SVND}${SVNDpartition} ; then
X               exit 3
X       fi
Xfi
X
X# ready to mount the svnd   Try async instead of softdep?
X
Xif ! mount ${MOUNTOPT} /dev/${SVND}${SVNDpartition} ${SVNDMOUNT} ; then
X       echo possible bad encryption key 1>&2
X       exit 4
Xfi
X
Xmount | grep ${USBMOUNT}
Xdf | grep ${USBMOUNT}
Xecho 
Xmount | grep ${SVND}
Xdf | grep ${SVND}
X
Xexit 0
END-of-mountarchive
echo x - unmountarchive
sed 's/^X//' >unmountarchive << 'END-of-unmountarchive'
X#! /bin/sh
X# Unmounts the USB disk, the archive file system, and frees the svnd.
X
X. ./archive.defs
X
X# get brutal
X
Xcd /  # Do that to avoid trouble
X
Xumount /dev/${SVND}${SVNDpartition}
Xvnconfig -u ${SVND}
Xumount ${USBMOUNT}
X
X# failure modes are possible if the filesystems USBMOUNT and/or VIMARCH
X# busy.  They are busy if there are any files open on them, or if
X# some process has its cwd on them.  Use fstat(1) to find these miscreants.
END-of-unmountarchive
echo x - xrdist
sed 's/^X//' >xrdist << 'END-of-xrdist'
X#! /bin/sh
X#
X# Wrapper for rdist execution
X# See the $@ below?  That allows you to execute this script as
X# sh xrdist -x stuff1 -y stuff2  and rdist will be invoked with
X# -x stuff1 and -y stuff2 as additional arguments.
X# to override VIMDATA or VIMARCH, edit archive.defs, or override
X# them in the environment, like:
X# export VIMDATA=/home/vim/some-other/valuable/stuff/ 
X#    -- and/or --
X# VIMDATA=/home/vim/blah/blip sh xrdist 
X#
X
X. ./archive.defs
X
Xif [ ! -f distfile ] ; then
X       echo No distfile, exiting
X       exit 100
Xfi
X
X/usr/bin/rdist -d data=${VIMDATA} -d archive=${VIMARCH} $@
END-of-xrdist
exit

_______________________________________________
Openbsd-newbies mailing list
[email protected]
http://mailman.theapt.org/listinfo/openbsd-newbies

Reply via email to