Annotation of src/usr.bin/skey/skeyprune.pl, Revision 1.2
1.2 ! millert 1: #!/usr/bin/perl -w
1.1 millert 2: #
1.2 ! millert 3: # Copyright (c) 1996, 2001 Todd C. Miller <Todd.Miller@courtesan.com>
! 4: # All rights reserved.
! 5: #
! 6: # Redistribution and use in source and binary forms, with or without
! 7: # modification, are permitted provided that the following conditions
! 8: # are met:
! 9: # 1. Redistributions of source code must retain the above copyright
! 10: # notice, this list of conditions and the following disclaimer.
! 11: # 2. Redistributions in binary form must reproduce the above copyright
! 12: # notice, this list of conditions and the following disclaimer in the
! 13: # documentation and/or other materials provided with the distribution.
! 14: # 3. The name of the author may not be used to endorse or promote products
! 15: # derived from this software without specific prior written permission.
! 16: #
! 17: # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
! 18: # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
! 19: # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
! 20: # THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
! 21: # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! 22: # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! 23: # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! 24: # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! 25: # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 26: # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 27: #
! 28: # Prune commented out, bogus, and crufty entries from /etc/skeykeys
1.1 millert 29: # Usage: skeyprune [days]
30: #
1.2 ! millert 31: # $OpenBSD: skeyprune.pl,v 1.1 1996/09/28 00:00:41 millert Exp $
! 32: #
1.1 millert 33:
1.2 ! millert 34: use File::Temp qw(:mktemp);
! 35: use Fcntl qw(:DEFAULT :flock);
! 36: use Time::Local;
1.1 millert 37:
38: # Keep out the stupid
39: die "Only root may run $0.\n" if $>;
1.2 ! millert 40: die "Usage: $0 [days]\n" if $#ARGV > 0;
1.1 millert 41:
42: # Pathnames
43: $keyfile = '/etc/skeykeys';
1.2 ! millert 44: $template = "$keyfile.XXXXXXXX";
1.1 millert 45:
46: # Quick mapping of month name -> number
47: %months = ('Jan', 0, 'Feb', 1, 'Mar', 2, 'Apr', 3, 'May', 4, 'Jun', 5,
48: 'Jul', 6, 'Aug', 7, 'Sep', 8, 'Oct', 9, 'Nov', 10, 'Dec', 11);
49:
50: # Remove entries that haven't been modified in this many days.
51: $days_old = $ARGV[0] || -1;
52:
1.2 ! millert 53: # Safe umask
! 54: umask(077);
! 55:
! 56: # Open and lock the current key file
1.1 millert 57: open(OLD, $keyfile) || die "$0: Can't open $keyfile: $!\n";
1.2 ! millert 58: flock(OLD, LOCK_EX) || die "$0: Can't lock $keyfile: $!\n";
1.1 millert 59:
60: # Safely open temp file
1.2 ! millert 61: ($NEW, $temp) = mkstemp($template);
! 62: die "$0: Can't open tempfile $template: $!\n" unless $temp;
1.1 millert 63:
1.2 ! millert 64: # Run at a high priority so we don't keep things locked for too long
1.1 millert 65: setpriority(0, 0, -4);
66:
67: while (<OLD>) {
1.2 ! millert 68: chomp();
! 69:
! 70: # Valid entry: 'username hash seq seed key date"
! 71: 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]+$/ ) {
! 72:
! 73: @entry = split(/[\s,:]+/, $_);
! 74: # Prune out old entries if asked to
! 75: if ($days_old > 0) {
! 76: # build up time based on date string
! 77: $sec = $date[10];
! 78: $min = $date[9];
! 79: $hours = $date[8];
! 80: $mday = $date[6] - 1;
! 81: $mon = $months{$date[5]};
! 82: $year = $date[7] - 1900;
! 83:
! 84: $now = time();
! 85: $then = timelocal($sec,$min,$hours,$mday,$mon,$year);
! 86: if (($now - $then) / (60 * 60 * 24) - 1 > $days_old) {
! 87: next; # too old
! 88: }
! 89: }
! 90:
! 91: # Missing hash type? Must be md4...
! 92: if ($entry[1] =~ /^\d/) {
! 93: splice(@entry, 1, 0, "md4");
! 94: }
! 95:
! 96: printf $NEW "%s %s %04d %-16s %s %4s %02d,%-4d %02d:%02d:%02d\n",
! 97: $entry[0], $entry[1], $entry[2], $entry[3], $entry[4],
! 98: $entry[5], $entry[6], $entry[7], $entry[8], $entry[9],
! 99: $entry[10] || do {
! 100: warn "Can't write to $temp: $!\n";
! 101: unlink($temp);
! 102: exit(1);
1.1 millert 103: };
104: }
105: }
106: close(OLD);
1.2 ! millert 107: close($NEW);
1.1 millert 108:
109: # Set owner/group/mode on tempfile and move to real location.
110: ($mode, $nlink, $uid, $gid) = (stat($keyfile))[2..5];
111: if (!defined($mode)) {
1.2 ! millert 112: unlink($temp);
! 113: die "$0: Unable to stat $keyfile: $!\n";
1.1 millert 114: }
115: if (!chmod($mode, $temp)) {
1.2 ! millert 116: unlink($temp);
! 117: die "$0: Unable to set mode of $temp to $mode: $!\n";
1.1 millert 118: }
119: if (!chown($uid, $gid, $temp)) {
1.2 ! millert 120: unlink($temp);
! 121: die "$0: Unable to set owner of $temp to ($uid, $gid): $!\n";
! 122: }
! 123: if ($nlink != 1) {
! 124: $nlink--;
! 125: warn "$0: Old $keyfile had $nlink hard links, those will be broken\n";
1.1 millert 126: }
127: # Leave temp file in place if rename fails. Might help in debugging.
128: rename($temp, $keyfile) || die "$0: Unable to rename $temp to $keyfile: $!\n";
129:
130: exit(0);