diff --git a/Makefile b/Makefile index 1ed0f27..3ca9170 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ VERSION = 1.3rc PACKAGE = yubikey-ksm CODE = .htaccess Makefile NEWS ykksm-config.php ykksm-db.sql \ ykksm-decrypt.php ykksm-export.pl ykksm-gen-keys.pl \ - ykksm-import.pl ykksm-utils.php + ykksm-import.pl ykksm-utils.php ykksm-checksum.pl DOCS = doc/DecryptionProtocol.wiki doc/DesignGoals.wiki \ doc/GenerateKeys.wiki doc/GenerateKSMKey.wiki \ doc/ImportKeysToKSM.wiki doc/Installation.wiki \ @@ -56,6 +56,7 @@ install: install -D ykksm-gen-keys.pl $(binprefix)/ykksm-gen-keys install -D ykksm-import.pl $(binprefix)/ykksm-import install -D ykksm-export.pl $(binprefix)/ykksm-export + install -D ykksm-checksum.pl $(binprefix)/ykksm-checksum install -D --backup --mode 640 --group $(wwwgroup) ykksm-config.php $(etcprefix)/ykksm-config.php install -D ykksm-db.sql $(docprefix)/ykksm-db.sql install -D Makefile $(docprefix)/ykksm.mk diff --git a/ykksm-checksum.pl b/ykksm-checksum.pl new file mode 100644 index 0000000..cf87602 --- /dev/null +++ b/ykksm-checksum.pl @@ -0,0 +1,113 @@ +#!/usr/bin/perl + +# Written by Simon Josefsson . +# Copyright (c) 2010 Yubico AB +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * 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. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +use strict; +use DBI; +use POSIX qw(strftime); +use Digest::SHA1; + +sub usage { + print "Usage: $0 [--verbose] [--help]\n"; + print " [--database DBI] [--db-user USER] [--db-passwd PASSWD]\n"; + print "\n"; + print "Print checksum of important database fields. Useful for quickly\n"; + print "determining whether several KSMs are in sync.\n"; + print "\n"; + print " --database DBI: Database identifier, see http://dbi.perl.org/\n"; + print " defaults to a MySQL database ykksm on localhost,\n"; + print " i.e., dbi:mysql:ykksm. For PostgreSQL on the local\n"; + print " host you can use 'DBI:Pg:dbname=ykksm;host=127.0.0.1'.\n"; + print "\n"; + print " --db-user USER: Database username to use, defaults to empty string.\n"; + print "\n"; + print " --db-passwd PASSWD: Database password to use, defaults to empty string.\n"; + print "\n"; + print "Usage example:\n"; + print "\n"; + print " ./ykksm-checksum.pl --database dbi:mysql:ykksm --db-user user --db-passwd pencil\n"; + print "\n"; + exit 1; +} + +my $verbose = 0; +my $db = "dbi:mysql:ykksm"; +my $dbuser; +my $dbpasswd; +while ($ARGV[0] =~ m/^-(.*)/) { + my $cmd = shift @ARGV; + if (($cmd eq "-v") || ($cmd eq "--verbose")) { + $verbose = 1; + } elsif (($cmd eq "-h") || ($cmd eq "--help")) { + usage(); + } elsif ($cmd eq "--database") { + $db = shift; + } elsif ($cmd eq "--db-user") { + $dbuser = shift; + } elsif ($cmd eq "--db-passwd") { + $dbpasswd = shift; + } +} + +if ($#ARGV>=0) { + usage(); +} + +my $dbh = DBI->connect($db, $dbuser, $dbpasswd, {'RaiseError' => 1}); +my $sth = $dbh->prepare + ('SELECT serialnr, publicname, internalname, aeskey FROM yubikeys') + or die "Couldn't prepare statement: " . $dbh->errstr; +$sth->execute() + or die "Couldn't execute statement: " . $sth->errstr; + +my $sha1 = Digest::SHA1->new; + +my $row; +while ($row = $sth->fetchrow_hashref()) { + if ($verbose) { + print "# serialnr=" . $row->{'serialnr'} . + " publicname=" . $row->{'publicname'} . "\n"; + } + $sha1->add($row->{'serialnr'}); + $sha1->add($row->{'publicname'}); + $sha1->add($row->{'internalname'}); + $sha1->add($row->{'aeskey'}); +} + +if ($sth->rows == 0) { + print "No data?!\n\n"; + exit 1; +} + +print substr ($sha1->hexdigest, 0, 10) . "\n"; + +$sth->finish; +$dbh->disconnect(); + +exit 0;