summaryrefslogtreecommitdiff
path: root/usr.bin/skey
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2001-06-20 22:19:59 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2001-06-20 22:19:59 +0000
commitb2ed4201f44c6105e504ec1feaf012eb4d2d8540 (patch)
tree0a413a89f87696c75d24fb52738d0abd098decc4 /usr.bin/skey
parent2ab9005aa77c402f1aaec6f2e813675e8e48db2e (diff)
o perl5'ified
o We now lock the skeys database as we ought to avoid problems. o Safe temp file handling o Weed out bogus records instead of ignoring them o Add a hash type to old md4 entries w/o a hash type listed
Diffstat (limited to 'usr.bin/skey')
-rw-r--r--usr.bin/skey/skeyprune.822
-rw-r--r--usr.bin/skey/skeyprune.pl136
2 files changed, 95 insertions, 63 deletions
diff --git a/usr.bin/skey/skeyprune.8 b/usr.bin/skey/skeyprune.8
index e83b63e757a..2580612a818 100644
--- a/usr.bin/skey/skeyprune.8
+++ b/usr.bin/skey/skeyprune.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: skeyprune.8,v 1.5 2000/03/23 21:10:18 aaron Exp $
+.\" $OpenBSD: skeyprune.8,v 1.6 2001/06/20 22:19:58 millert Exp $
.\"
.\"
.Dd September 27, 1996
@@ -12,16 +12,17 @@
.Op Ar days
.Sh DESCRIPTION
.Nm skeyprune
-searches through the file
-.Dq Pa /etc/skeykeys
-and prunes out users who have zeroed their entries via
-.Xr skeyinit 1
+searches through the S/Key database,
+.Dq Pa /etc/skeykeys ,
+and prunes out invalid entries (including users who have zeroed out their)
+entries via
+.Xr skeyinit 1 )
as well as entries that have not been modified in
.Ar days
days.
If
.Ar days
-is not specified only commented out entries are pruned.
+is not specified, only invalid entries are pruned.
.Sh FILES
.Bl -tag -width /etc/skeykeys -compact
.It Pa /etc/skeykeys
@@ -30,12 +31,3 @@ S/Key key information database
.Sh SEE ALSO
.Xr skey 1 ,
.Xr skeyinit 1
-.Sh BUGS
-Since
-.Nm skeyprune
-rewrites
-.Dq Pa /etc/skeykeys ,
-there is a window where S/Key changes could get lost.
-It is therefore suggested that
-.Nm skeyprune
-be run at a time when users are unlikely to be active.
diff --git a/usr.bin/skey/skeyprune.pl b/usr.bin/skey/skeyprune.pl
index bb10bda38ed..004fa65ec03 100644
--- a/usr.bin/skey/skeyprune.pl
+++ b/usr.bin/skey/skeyprune.pl
@@ -1,21 +1,47 @@
-#!/usr/bin/perl
+#!/usr/bin/perl -w
#
-# Prune commented out and crufty entries from skeykeys
+# Copyright (c) 1996, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+# THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Prune commented out, bogus, and crufty entries from /etc/skeykeys
# Usage: skeyprune [days]
#
-# Todd C. Miller <Todd.Miller@courtesan.com>
-# $OpenBSD: skeyprune.pl,v 1.1 1996/09/28 00:00:41 millert Exp $
+# $OpenBSD: skeyprune.pl,v 1.2 2001/06/20 22:19:58 millert Exp $
+#
-# We need to be able convert to time_t
-require 'timelocal.pl';
+use File::Temp qw(:mktemp);
+use Fcntl qw(:DEFAULT :flock);
+use Time::Local;
# Keep out the stupid
die "Only root may run $0.\n" if $>;
-die "Usage: $0 [days]\n" if $#ARGC > 0;
+die "Usage: $0 [days]\n" if $#ARGV > 0;
# Pathnames
$keyfile = '/etc/skeykeys';
-$temp = "$keyfile.tmp$$";
+$template = "$keyfile.XXXXXXXX";
# Quick mapping of month name -> number
%months = ('Jan', 0, 'Feb', 1, 'Mar', 2, 'Apr', 3, 'May', 4, 'Jun', 5,
@@ -24,65 +50,79 @@ $temp = "$keyfile.tmp$$";
# Remove entries that haven't been modified in this many days.
$days_old = $ARGV[0] || -1;
-# Open current key file
+# Safe umask
+umask(077);
+
+# Open and lock the current key file
open(OLD, $keyfile) || die "$0: Can't open $keyfile: $!\n";
+flock(OLD, LOCK_EX) || die "$0: Can't lock $keyfile: $!\n";
# Safely open temp file
-umask(077);
-unlink($temp);
-open(NEW, ">$temp") || die "$0: Can't open tempfile $temp: $!\n";
+($NEW, $temp) = mkstemp($template);
+die "$0: Can't open tempfile $template: $!\n" unless $temp;
-# We need to be extra speedy to close the window where someone can hose us.
+# Run at a high priority so we don't keep things locked for too long
setpriority(0, 0, -4);
while (<OLD>) {
- # Ignore commented out entries
- if ( ! /^#[^\s#]+\s+(MD[0-9]+\s+)?[0-9]+\s+[A-z0-9_-]+\s+[a-f0-9]+\s+(Jan|Feb|Mar|Apr|May|Ju[nl]|Aug|Sep|Oct|Nov|Dec)\s+[0-9]+,\s*[0-9]+\s+[0-9]+:[0-9]+:[0-9]+$/ ) {
- /((Jan|Feb|Mar|Apr|May|Ju[nl]|Aug|Sep|Oct|Nov|Dec)\s+[0-9]+,\s*[0-9]+\s+[0-9]+:[0-9]+:[0-9]+)$/;
-
- # Prune out old entries if asked to
- if ($days_old > 0) {
- # build up time based on date string
- @date = split(/[\s,:]/, $1);
- $sec = $date[5];
- $min = $date[4];
- $hours = $date[3];
- $mday = $date[1] - 1;
- $mon = $months{$date[0]};
- $year = $date[2] - 1900;
-
- $now = time();
- $then = &timelocal($sec,$min,$hours,$mday,$mon,$year);
- if (($now - $then) / (60 * 60 * 24) - 1 <= $days_old) {
- print NEW $_ || do {
- warn "Can't write to $temp: $!\n";
- unlink($temp);
+ chomp();
+
+ # Valid entry: 'username hash seq seed key date"
+ if ( /^[^\s#]+\s+(\S+\s+)?[0-9]+\s+[A-z0-9]+\s+[a-f0-9]+\s+(Jan|Feb|Mar|Apr|May|Ju[nl]|Aug|Sep|Oct|Nov|Dec)\s+[0-9]+,\s*[0-9]+\s+[0-9]+:[0-9]+:[0-9]+$/ ) {
+
+ @entry = split(/[\s,:]+/, $_);
+ # Prune out old entries if asked to
+ if ($days_old > 0) {
+ # build up time based on date string
+ $sec = $date[10];
+ $min = $date[9];
+ $hours = $date[8];
+ $mday = $date[6] - 1;
+ $mon = $months{$date[5]};
+ $year = $date[7] - 1900;
+
+ $now = time();
+ $then = timelocal($sec,$min,$hours,$mday,$mon,$year);
+ if (($now - $then) / (60 * 60 * 24) - 1 > $days_old) {
+ next; # too old
+ }
+ }
+
+ # Missing hash type? Must be md4...
+ if ($entry[1] =~ /^\d/) {
+ splice(@entry, 1, 0, "md4");
+ }
+
+ printf $NEW "%s %s %04d %-16s %s %4s %02d,%-4d %02d:%02d:%02d\n",
+ $entry[0], $entry[1], $entry[2], $entry[3], $entry[4],
+ $entry[5], $entry[6], $entry[7], $entry[8], $entry[9],
+ $entry[10] || do {
+ warn "Can't write to $temp: $!\n";
+ unlink($temp);
+ exit(1);
};
- }
- } else {
- print NEW $_ || do {
- warn "Can't write to $temp: $!\n";
- unlink($temp);
- };
}
- }
}
close(OLD);
-close(NEW);
+close($NEW);
# Set owner/group/mode on tempfile and move to real location.
($mode, $nlink, $uid, $gid) = (stat($keyfile))[2..5];
if (!defined($mode)) {
- unlink($temp);
- die "$0: Unable to stat $keyfile: $!\n";
+ unlink($temp);
+ die "$0: Unable to stat $keyfile: $!\n";
}
if (!chmod($mode, $temp)) {
- unlink($temp);
- die "$0: Unable to set mode of $temp to $mode: $!\n";
+ unlink($temp);
+ die "$0: Unable to set mode of $temp to $mode: $!\n";
}
if (!chown($uid, $gid, $temp)) {
- unlink($temp);
- die "$0: Unable to set owner of $temp to ($uid, $gid): $!\n";
+ unlink($temp);
+ die "$0: Unable to set owner of $temp to ($uid, $gid): $!\n";
+}
+if ($nlink != 1) {
+ $nlink--;
+ warn "$0: Old $keyfile had $nlink hard links, those will be broken\n";
}
# Leave temp file in place if rename fails. Might help in debugging.
rename($temp, $keyfile) || die "$0: Unable to rename $temp to $keyfile: $!\n";