Signature fetcher thingy
[mirror/userdir-ldap.git] / ud-gpgsigfetch
1 #!/usr/bin/env python
2 # -*- mode: python -*-
3 # This script tries to match key fingerprints from a keyring with user
4 # name in a directory. When an unassigned key is found a heuristic match
5 # against the keys given cn/sn and the directory is performed to try to get
6 # a matching. Generally this works about 90% of the time, matching is fairly
7 # strict. In the event a non-match a fuzzy sounds-alike search is performed
8 # and the results printed to aide the user.
9 #
10 # GPG is automatically invoked with the correct magic special options,
11 # pass the names of all the valid key rings on the command line.
12 #
13 # The output report will list what actions were taken. Keys that are present
14 # in the directory but not in the key ring will be removed from the 
15 # directory. 
16
17 import string, re, time, ldap, getopt, sys, pwd, posix;
18 from userdir_gpg import *;
19 Output = "extrakeys.gpg";
20
21 # Process options
22 AdminUser = pwd.getpwuid(posix.getuid())[0];
23 (options, arguments) = getopt.getopt(sys.argv[1:], "o:")
24 for (switch, val) in options:
25    if (switch == '-o'):
26       Output = val
27    elif (switch == '-m'):
28        LoadOverride(val);
29    elif (switch == '-a'):
30        NoAct = 0;
31
32 if len(arguments) == 0:
33    print "Give some keyrings to probe";
34    os.exit(0);
35
36 # Popen GPG with the correct magic special options
37 Args = [GPGPath] + GPGBasicOptions;
38 for x in arguments:
39    Args.append("--keyring");
40    if string.find(x,"/") == -1:
41       Args.append("./"+x);
42    else:
43       Args.append(x);
44 Args.append("--list-sigs");
45 Args = Args + GPGSearchOptions + [" 2> /dev/null"]
46 print string.join(Args," ")
47 #Keys = os.popen(string.join(Args," "),"r");
48 Keys = os.popen("cat sigs","r");
49
50 # Loop over the GPG key file
51 HaveKeys = {};
52 NeedKeys = {};
53 print "Reading keys+sigs from keyring";
54 while(1):
55    Line = Keys.readline();
56    if Line == "":
57       break;
58    
59    Split = string.split(Line,":");
60    if len(Split) >= 8 and Split[0] == "pub":
61       HaveKeys[Split[4]] = "";
62       continue;
63
64    if len(Split) >= 5 and Split[0] == "sig":
65       NeedKeys[Split[4]] = "";
66       continue;
67 Keys.close();
68
69 # Popen GPG with the correct magic special options
70 Args = [GPGPath] + GPGBasicOptions;
71 for x in [Output]:
72    Args.append("--keyring");
73    if string.find(x,"/") == -1:
74       Args.append("./"+x);
75    else:
76       Args.append(x);
77 OldArgs = Args;      
78 Args = Args + GPGSearchOptions + [" 2> /dev/null"]
79 Keys = os.popen(string.join(Args," "),"r");
80
81 print "Reading keys from output";
82 while(1):
83    Line = Keys.readline();
84    if Line == "":
85       break;
86    
87    Split = string.split(Line,":");
88    if len(Split) >= 8 and Split[0] == "pub":
89       HaveKeys[Split[4]] = "";
90       continue;
91 Keys.close();
92
93 KeysToFetch = [];
94 for x in NeedKeys.keys():
95    if not HaveKeys.has_key(x):
96       KeysToFetch.append("0x"+x);
97
98 print "Have %u keys and %u sigs, need %u keys"%(len(HaveKeys),len(NeedKeys),len(KeysToFetch));
99
100 Args = OldArgs;
101 Args.append("--keyserver 18.43.0.48");
102 Args.append("--recv-keys");
103 I = len(KeysToFetch);
104 while (I > 0):
105    OldI = I;
106    I = I - 20;
107    if I < 0: I = 0;
108    print string.join(Args+KeysToFetch[I:OldI]," ")