aboutsummaryrefslogtreecommitdiffstats
path: root/genrings
blob: 34a91dbbf3f5ae9ef87a28337e98d869970a2025 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/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~");
}