| #!/usr/bin/perl |
| ## ----------------------------------------------------------------------- |
| ## |
| ## Copyright 2011 Intel Corporation; author: H. Peter Anvin |
| ## |
| ## This program is free software; you can redistribute it and/or |
| ## modify it under the terms of the GNU General Public License as |
| ## published by the Free Software Foundation, Inc.; either version 2 |
| ## of the License, or (at your option) any later version; |
| ## incorporated herein by reference. |
| ## |
| ## ----------------------------------------------------------------------- |
| |
| # |
| # Take a text file and an single gpg ring and separate out |
| # authorized key rings into separate files. |
| # |
| # The format of the input file is: |
| # username key_id other_fields |
| # |
| |
| use strict; |
| use warnings; |
| use File::Temp qw(tempdir); |
| |
| my ($input, $outdir) = @ARGV; |
| |
| if (!defined($outdir)) { |
| die "Usage: $0 input_file output_dir\n"; |
| } |
| |
| my $gpg = 'gpg'; |
| |
| if (! -d $outdir) { |
| mkdir($outdir) |
| or die "$0: cannot create output directory $outdir: $!\n"; |
| } |
| |
| my $tmpdir = tempdir(CLEANUP => 1); |
| if (!defined($tmpdir) || ! -d $tmpdir) { |
| die "$0: failed to create temporary directory\n"; |
| } |
| |
| my $in; |
| open($in, '<', $input) |
| or die "$0: cannot open: $in: $!\n"; |
| |
| my %keys = (); |
| |
| my $line; |
| while (defined($line = <$in>)) { |
| next if ($line !~ /^([A-Za-z0-9_.-]+)\s+([0-9a-fA-F]+)/); |
| |
| my $username = $1; |
| my $keyid = $2; |
| |
| my @keyids = (); |
| open(my $gpgfd, '-|', |
| $gpg, '--fixed-list-mode', '--with-colons', '--list-keys', |
| '--with-fingerprint', '--with-fingerprint', $keyid) |
| or die "$0: failed to run gpg\n"; |
| my $gl; |
| my $fprok = 0; |
| while (defined($gl = <$gpgfd>)) { |
| my @gf = split(/\:/, $gl); |
| |
| if ($fprok && $gf[0] eq 'fpr') { |
| # This is the actual fingerprint we wanted |
| push(@keyids, $gf[9]); |
| $fprok = 0; |
| } else { |
| $fprok = 0; |
| |
| # Key must be a public key |
| next if ($gf[0] ne 'pub'); |
| |
| # Skip keys that are: |
| # i - invalid |
| # d - disabled |
| # r - revoked |
| # e - expired |
| # o - unknown |
| # D (in field 12) - disabled |
| next if ($gf[1] =~ /[idreo]/ || $gf[11] =~ /D/); |
| |
| # XXX: What should be enforced for field 12? |
| |
| $fprok = 1; |
| } |
| } |
| close($gpgfd); |
| |
| if (scalar(@keyids)) { |
| my $n = ++$keys{$username}; |
| system($gpg, '-o', "${tmpdir}/${username}.${n}.key", |
| '--export-options', 'export-local-sigs,export-minimal', |
| '--export', @keyids); |
| } |
| } |
| |
| close($in); |
| |
| foreach my $username (keys(%keys)) { |
| my $n = $keys{$username}; |
| my @i = (); |
| for (my $i = 1; $i <= $n; $i++) { |
| push(@i, "${tmpdir}/${username}.${i}.key"); |
| } |
| system($gpg, '--homedir', $tmpdir, |
| '--no-default-keyring', |
| '--primary-keyring', "${outdir}/${username}.gpg", |
| '--import', @i); |
| unlink("${outdir}/${username}.gpg~"); |
| } |