#! /usr/bin/perl -w use Catacomb; my $GRIPE = 0; my $DEBUG = 0; my $QUIS = $0; $QUIS =~ s:^.*/::; my $MODE = \&encrypt; my $OFILE = "-"; my $TAG = "ciphersaber-%s"; sub usage { my $f = shift; print $f "Usage: $QUIS [-de] [-t TAG] [-o FILE] file...\n"; } sub version { my $f = shift; print $f "$QUIS, catacomb-perl version $Catacomb::VERSION\n"; } sub help { my $f = shift; version($f); print $f "\n"; usage($f); print $f <" } @_) : ""), "\n"; } sub encrypt { my $salt = pack("N", time()) . $Catacomb::random->fill(6); debug("salt", $salt); my $tag = sprintf($TAG, hexify($salt)); my $pass = Catacomb::Passphrase->verify($tag); barf("passwords don't match") unless defined($pass); open OUT, "> $OFILE" or barf("couldn't write file `$OFILE'", $!); syswrite(OUT, $salt) or barf("error writing `$OFILE'", $!); my $c = $Catacomb::Cipher::rc4->init($pass . $salt); foreach my $f (@ARGV ? @ARGV : "-") { open IN, $f or barf("couldn't read file `$f'", $!); for (;;) { my $buf; my $rc = sysread(IN, $buf, 8192); barf("error reading `$f'", $!) unless defined($rc); last unless $rc; syswrite(OUT, $c->encrypt($buf)) or barf("error writing `$OFILE'", $!); } close(IN); } close(OUT) or barf("error writing `$OFILE'", $!); } sub decrypt { open OUT, "> $OFILE" or barf("couldn't write file `$OFILE'", $!); foreach my $f (@ARGV ? @ARGV : "-") { open IN, $f or barf("couldn't read file `$f'", $!); my ($salt, $buf); my $rc = sysread(IN, $salt, 10); barf("error reading `$f'", $!) unless defined($rc); barf("ciphertext file is too short") unless $rc; debug("salt", $salt); my $tag = sprintf($TAG, hexify($salt)); my $pass = Catacomb::Passphrase->read($tag) or barf("couldn't read passphrase", $!); my $c = $Catacomb::Cipher::rc4->init($pass . $salt); for (;;) { my $buf; my $rc = sysread(IN, $buf, 8192); barf("error reading `$f'", $!) unless defined($rc); last unless $rc; syswrite(OUT, $c->decrypt($buf)) or barf("error writing `$OFILE'", $!); } close(IN); } close(OUT) or barf("error writing `$OFILE'", $!); } while (@ARGV) { my $opt = $ARGV[0]; last if $opt eq "-" || $opt =~ /^[^-]/; shift(@ARGV); last if $opt eq "--"; $opt = substr($opt, 1); while (length($opt)) { my $o = substr($opt, 0, 1); $opt = substr($opt, 1); if ($o eq "o") { $OFILE = length($opt) ? $opt : shift(@ARGV); $opt = ""; gripe("option `-o' requires an argument") unless defined($OFILE); } elsif ($o eq "d") { $MODE = \&decrypt; } elsif ($o eq "e") { $MODE = \&encrypt; } elsif ($o eq "t") { $TAG = length($opt) ? $opt : shift(@ARGV); $opt = ""; gripe("option `-t' requires an argument") unless defined($TAG); } elsif ($o eq "h") { help(\*STDOUT); exit(0); } elsif ($o eq "v") { version(\*STDOUT); exit(0); } elsif ($o eq "u") { usage(\*STDOUT); exit(0); } elsif ($o eq "D") { $DEBUG = 1; } else { gripe("unknown option `-$o'"); } } } if ($GRIPE) { usage(\*STDERR); exit(1); } &$MODE(); exit(0);