more gpg touch ups
authorjgg <>
Wed, 5 Jan 2000 01:50:22 +0000 (01:50 +0000)
committerjgg <>
Wed, 5 Jan 2000 01:50:22 +0000 (01:50 +0000)
ud-echelon
ud-gpgimport
ud-gpgsigfetch
userdir_ldap.py

index 6434f0e..2be0112 100755 (executable)
@@ -7,6 +7,7 @@ from userdir_ldap import *;
 
 EX_TEMPFAIL = 75;
 EX_PERMFAIL = 65;      # EX_DATAERR
+Debug = "";
 
 # Try to extract a key fingerprint from a PGP siged message
 def TryGPG(Email):
@@ -15,6 +16,7 @@ def TryGPG(Email):
    if string.find(Msg[0],"-----BEGIN PGP SIGNED MESSAGE-----") == -1:
       return None;
       
+   print Msg[0];
    Res = GPGCheckSig(Msg[0]);
 
    # Failed to find a matching sig
@@ -30,71 +32,6 @@ def TryGPG(Email):
    
    return (Attrs[0][1]["uid"][0],"PGP",FormatPGPKey(Res[2][1]));
 
-# Convert the PGP name string to a uid value
-def GetUID(l,Name,UnknownMap = {}):
-   # Crack up the email address into a best guess first/middle/last name
-   (cn,mn,sn) = NameSplit(re.sub('["]','',Name[0]))
-   
-   # Brackets anger the ldap searcher
-   cn = re.sub('[(")]','?',cn);
-   sn = re.sub('[(")]','?',sn);
-
-   # First check the unknown map for the email address
-   if UnknownMap.has_key(Name[1] + '@' + Name[2]):
-      Stat = "unknown map hit for "+str(Name);
-      return (UnknownMap[Name[1] + '@' + Name[2]],[Stat]);
-
-   # Then the cruft component (ie there was no email address to match)
-   if UnknownMap.has_key(Name[2]):
-      Stat = "unknown map hit for"+str(Name);
-      return (UnknownMap[Name[2]],[Stat]);
-
-   # Search for a possible first/last name hit
-   try:
-      Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"(&(cn=%s)(sn=%s))"%(cn,sn),["uid"]);
-   except ldap.FILTER_ERROR:
-      Stat = "Filter failure: (&(cn=%s)(sn=%s))"%(cn,sn);
-      return (None,[Stat]);
-
-   # Try matching on the email address
-   if (len(Attrs) != 1):
-      try:
-         Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"emailforward=%s"%(Name[2]),["uid"]);
-      except ldap.FILTER_ERROR:
-        pass;
-
-   # Hmm, more than one/no return
-   if (len(Attrs) != 1):
-      # Key claims a local address
-      if Name[2] == EmailAppend:
-
-         # Pull out the record for the claimed user
-         Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"(uid=%s)"%(Name[1]),["uid","sn","cn"]);
-
-         # We require the UID surname to be someplace in the key name, this
-         # deals with special purpose keys like 'James Troup (Alternate Debian key)'
-        # Some people put their names backwards on their key too.. check that as well
-         if len(Attrs) == 1 and \
-            (string.find(string.lower(sn),string.lower(Attrs[0][1]["sn"][0])) != -1 or \
-            string.find(string.lower(cn),string.lower(Attrs[0][1]["sn"][0])) != -1):
-            Stat = EmailAppend+" hit for "+str(Name);
-            return (Name[1],[Stat]);
-
-      # Attempt to give some best guess suggestions for use in editing the
-      # override file.
-      Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"(sn~=%s)"%(sn),["uid","sn","cn"]);
-
-      Stat = [];
-      if len(Attrs) != 0:
-         Stat = ["None for %s"%(str(Name))];
-      for x in Attrs:
-         Stat.append("But might be: %s %s <%s@debian.org>"%(x[1]["cn"][0],x[1]["sn"][0],x[1]["uid"][0]));
-      return (None,Stat);       
-   else:
-      return (Attrs[0][1]["uid"][0],None);
-
-   return (None,None);
-
 # Try to guess the name from the email address
 def TryMatcher(Email):
    Sender = Email.getheader("From");
@@ -118,9 +55,13 @@ def TryMatcher(Email):
    return (UID[0],"FROM",Sender);
    
 # Open the log files
-MainLog = open(Ech_MainLog,"a+",0);
-ErrLog = open(Ech_ErrorLog,"a+",0);
-
+if Debug == None:
+   MainLog = open(Ech_MainLog,"a+",0);
+   ErrLog = open(Ech_ErrorLog,"a+",0);
+else:
+   MainLog = open("/dev/stdout","a+",0);
+   ErrLog = open("/dev/stdout","a+",0);
+   
 # Start of main program
 ErrMsg = "Indeterminate Error";
 ErrType = EX_TEMPFAIL;
@@ -138,10 +79,13 @@ try:
    ErrMsg = "An error occured while performing the LDAP lookup";
    global l;
    l = ldap.open(LDAPServer);
-   F = open(PassDir+"/pass-"+pwd.getpwuid(posix.getuid())[0],"r");
-   AccessPass = string.split(string.strip(F.readline())," ");
-   l.simple_bind_s("uid="+AccessPass[0]+","+BaseDn,AccessPass[1]);
-   F.close();
+   if Debug == None:
+      F = open(PassDir+"/pass-"+pwd.getpwuid(posix.getuid())[0],"r");
+      AccessPass = string.split(string.strip(F.readline())," ");
+      l.simple_bind_s("uid="+AccessPass[0]+","+BaseDn,AccessPass[1]);
+      F.close();
+   else:
+      l.simple_bind_s("","");
 
    # Try to decode
    ErrType = EX_TEMPFAIL;
@@ -162,7 +106,10 @@ try:
       MainLog.write("%s %s %s\n"%(User[0],User[1],Msg));
       Dn = "uid=" + User[0] + "," + BaseDn;
       Rec = [(ldap.MOD_REPLACE,"activity-%s"%(User[1]),Msg)];
-      l.modify_s(Dn,Rec);
+      if Debug == None:
+         l.modify_s(Dn,Rec);
+      else:
+         print Rec;
    else:
       User = ("-","UKN",Email.getheader("From"));
       Msg = "[%s] \"%s\" \"%s\" \"%s\""%(Now,User[2],List,MsgID);
index a0f1764..500f965 100755 (executable)
@@ -34,60 +34,6 @@ def LoadOverride(File):
       Split = re.split("[:\n]",Line);
       UnknownMap[Split[0]] = string.strip(Split[1]);
 
-# Convert the PGP name string to a uid value
-def GetUID(l,Name):
-   # Crack up the email address into a best guess first/middle/last name
-   (cn,mn,sn) = NameSplit(re.sub('["]','',Name[0]))
-   
-   # Brackets anger the ldap searcher
-   cn = re.sub('[(")]','?',cn);
-   sn = re.sub('[(")]','?',sn);
-
-   # First check the unknown map for the email address
-   if UnknownMap.has_key(Name[1] + '@' + Name[2]):
-      print "unknown map hit for",Name;
-      return UnknownMap[Name[1] + '@' + Name[2]];
-
-   # Then the cruft component (ie there was no email address to match)
-   if UnknownMap.has_key(Name[2]):
-      print "unknown map hit for",Name;
-      return UnknownMap[Name[2]];
-
-   # Search for a possible first/last name hit
-   try:
-      Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"(&(cn=%s)(sn=%s))"%(cn,sn),["uid"]);
-   except ldap.FILTER_ERROR:
-      print "Filter failure:","(&(cn=%s)(sn=%s))"%(cn,sn);
-      return None;
-
-   # Hmm, more than one/no return
-   if (len(Attrs) != 1):
-      # Key claims a local address
-      if Name[2] == EmailAppend:
-
-         # Pull out the record for the claimed user
-         Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"(uid=%s)"%(Name[1]),["uid","sn","cn"]);
-
-         # We require the UID surname to be someplace in the key name, this
-         # deals with special purpose keys like 'James Troup (Alternate Debian key)'
-        # Some people put their names backwards on their key too.. check that as well
-         if len(Attrs) == 1 and \
-            (string.find(string.lower(sn),string.lower(Attrs[0][1]["sn"][0])) != -1 or \
-            string.find(string.lower(cn),string.lower(Attrs[0][1]["sn"][0])) != -1):
-            print EmailAppend,"hit for",Name;
-            return Name[1];
-
-      # Attempt to give some best guess suggestions for use in editing the
-      # override file.
-      print "None for",Name;
-      Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"(sn~=%s)"%(sn),["uid","sn","cn"]);
-      for x in Attrs:
-         print "  But might be:",x[1]["cn"][0],x[1]["sn"][0],"<" + x[1]["uid"][0] + "@debian.org>";
-   else:
-      return Attrs[0][1]["uid"][0];
-
-   return None;
-
 # Process options
 AdminUser = pwd.getpwuid(posix.getuid())[0];
 (options, arguments) = getopt.getopt(sys.argv[1:], "au:m:n")
@@ -188,17 +134,16 @@ while(1):
       # print "Ignoring keyID",Split2[9],"belonging to",KeyMap[Split2[9]][0];
       KeyMap[Split2[9]][1] = 1;
       continue;
-
-   Match = AddressSplit.match(Split[9]);
-   if Match == None:
-      UID = GetUID(l,("","",Split[9]));
-   else:
-      UID = GetUID(l,Match.groups());
-
-   if UID == None:
+      
+   UID = GetUID(l,SplitEmail(Split[9]),UnknownMap);
+   if UID[0] == None:
+      print "None for",SplitEmail(Split[9]),"'%s'"%(Split[9]);
+      if UID[1] != None: 
+         for x in UID[1]: print x;
       print "MISSING 0x" + Split2[9];
       continue;
 
+   UID = UID[0]
    Rec = [(ldap.MOD_ADD,"keyfingerprint",Split2[9])];
    Dn = "uid=" + UID + "," + BaseDn;
    print "Adding key 0x"+Split2[9],"to",UID;
@@ -227,7 +172,7 @@ print Ignored,"keys already in the directory (ignored)";
 # Look for unmatched keys
 for x in KeyMap.keys():
    if KeyMap[x][1] == 0:
-      print "key 0x",x,"belonging to",KeyMap[x][0],"removed";
+      print "key 0x%s belonging to %s removed"%(x,KeyMap[x][0]);
       if KeyCount.has_key(KeyMap[x][0]) :
          KeyCount[KeyMap[x][0]] = KeyCount[KeyMap[x][0]] - 1
          if KeyCount[KeyMap[x][0]] <= 0:
index ed8d43a..592b319 100755 (executable)
@@ -1,18 +1,5 @@
 #!/usr/bin/env python
 # -*- mode: python -*-
-# This script tries to match key fingerprints from a keyring with user
-# name in a directory. When an unassigned key is found a heuristic match
-# against the keys given cn/sn and the directory is performed to try to get
-# a matching. Generally this works about 90% of the time, matching is fairly
-# strict. In the event a non-match a fuzzy sounds-alike search is performed
-# and the results printed to aide the user.
-#
-# GPG is automatically invoked with the correct magic special options,
-# pass the names of all the valid key rings on the command line.
-#
-# The output report will list what actions were taken. Keys that are present
-# in the directory but not in the key ring will be removed from the 
-# directory. 
 
 import string, re, time, ldap, getopt, sys, pwd, posix;
 from userdir_gpg import *;
@@ -24,10 +11,6 @@ AdminUser = pwd.getpwuid(posix.getuid())[0];
 for (switch, val) in options:
    if (switch == '-o'):
       Output = val
-   elif (switch == '-m'):
-       LoadOverride(val);
-   elif (switch == '-a'):
-       NoAct = 0;
 
 if len(arguments) == 0:
    print "Give some keyrings to probe";
@@ -41,11 +24,10 @@ for x in arguments:
       Args.append("./"+x);
    else:
       Args.append(x);
+Args.append("--fast-list-mode");
 Args.append("--list-sigs");
 Args = Args + GPGSearchOptions + [" 2> /dev/null"]
-print string.join(Args," ")
-#Keys = os.popen(string.join(Args," "),"r");
-Keys = os.popen("cat sigs","r");
+Keys = os.popen(string.join(Args," "),"r");
 
 # Loop over the GPG key file
 HaveKeys = {};
@@ -78,7 +60,7 @@ OldArgs = Args;
 Args = Args + GPGSearchOptions + [" 2> /dev/null"]
 Keys = os.popen(string.join(Args," "),"r");
 
-print "Reading keys from output";
+print "Reading keys from output ring";
 while(1):
    Line = Keys.readline();
    if Line == "":
@@ -105,4 +87,11 @@ while (I > 0):
    OldI = I;
    I = I - 20;
    if I < 0: I = 0;
-   print string.join(Args+KeysToFetch[I:OldI]," ") 
+   print string.join(Args+KeysToFetch[I:OldI]," ")
+   Fetcher = os.popen(string.join(Args+KeysToFetch[I:OldI]," "),"r");
+   while(1):
+      Line = Fetcher.readline();
+      if Line == "":
+         break;
+      print Line;
+   Fetcher.close();
index f3f9ba7..0ea96a9 100644 (file)
@@ -30,6 +30,8 @@ LastNamesPre = {"van": None, "le": None, "de": None, "di": None};
 SSHAuthSplit = re.compile('^(.* )?(\d+) (\d+) (\d+) ?(.+)$');
 #'^([^\d](?:[^ "]+(?:".*")?)*)? ?(\d+) (\d+) (\d+) (.+)$');
 
+AddressSplit = re.compile("(.*).*<([^@]*)@([^>]*)>");
+
 # Safely get an attribute from a tuple representing a dn and an attribute
 # list. It returns the first attribute if there are multi.
 def GetAttr(DnRecord,Attribute,Default = ""):
@@ -101,10 +103,9 @@ def NameSplit(Name):
          break;
         
    # Merge any of the middle initials
-   if len(Words) > 2:
-      while len(Words[2]) == 2 and Words[2][1] == '.':
-         Words[1] = Words[1] +  Words[2];
-         del Words[2];
+   while len(Words) > 2 and len(Words[2]) == 2 and Words[2][1] == '.':
+      Words[1] = Words[1] +  Words[2];
+      del Words[2];
 
    while len(Words) < 2:
       Words.append('');
@@ -251,7 +252,83 @@ def SplitEmail(Addr):
    Res1 = Res1[0];
    if Res1[1] == None:
       return (Res1[0],"","");
+
+   # If there is no @ then the address was not parsed well. Try the alternate
+   # Parsing scheme. This is particularly important when scanning PGP keys.
    Res2 = string.split(Res1[1],"@");
    if len(Res2) != 2:
-      return (Res1[0],"",Res1[1]);
+      Match = AddressSplit.match(Addr);
+      if Match == None:
+         return ("","",Addr);
+      return Match.groups();
+
    return (Res1[0],Res2[0],Res2[1]);
+
+# Convert the PGP name string to a uid value. The return is a tuple of
+# (uid,[message strings]). UnknownMpa is a hash from email to uid that 
+# overrides normal searching.
+def GetUID(l,Name,UnknownMap = {}):
+   # Crack up the email address into a best guess first/middle/last name
+   (cn,mn,sn) = NameSplit(re.sub('["]','',Name[0]))
+   
+   # Brackets anger the ldap searcher
+   cn = re.sub('[(")]','?',cn);
+   sn = re.sub('[(")]','?',sn);
+
+   # First check the unknown map for the email address
+   if UnknownMap.has_key(Name[1] + '@' + Name[2]):
+      Stat = "unknown map hit for "+str(Name);
+      return (UnknownMap[Name[1] + '@' + Name[2]],[Stat]);
+
+   # Then the cruft component (ie there was no email address to match)
+   if UnknownMap.has_key(Name[2]):
+      Stat = "unknown map hit for"+str(Name);
+      return (UnknownMap[Name[2]],[Stat]);
+
+   # Search for a possible first/last name hit
+   try:
+      Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"(&(cn=%s)(sn=%s))"%(cn,sn),["uid"]);
+   except ldap.FILTER_ERROR:
+      Stat = "Filter failure: (&(cn=%s)(sn=%s))"%(cn,sn);
+      return (None,[Stat]);
+
+   # Try matching on the email address
+   if (len(Attrs) != 1):
+      try:
+         Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"emailforward=%s"%(Name[2]),["uid"]);
+      except ldap.FILTER_ERROR:
+        pass;
+
+   # Hmm, more than one/no return
+   if (len(Attrs) != 1):
+      # Key claims a local address
+      if Name[2] == EmailAppend:
+
+         # Pull out the record for the claimed user
+         Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"(uid=%s)"%(Name[1]),["uid","sn","cn"]);
+
+         # We require the UID surname to be someplace in the key name, this
+         # deals with special purpose keys like 'James Troup (Alternate Debian key)'
+        # Some people put their names backwards on their key too.. check that as well
+         if len(Attrs) == 1 and \
+            (string.find(string.lower(sn),string.lower(Attrs[0][1]["sn"][0])) != -1 or \
+            string.find(string.lower(cn),string.lower(Attrs[0][1]["sn"][0])) != -1):
+            Stat = EmailAppend+" hit for "+str(Name);
+            return (Name[1],[Stat]);
+
+      # Attempt to give some best guess suggestions for use in editing the
+      # override file.
+      Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"(sn~=%s)"%(sn),["uid","sn","cn"]);
+
+      Stat = [];
+      if len(Attrs) != 0:
+         Stat = ["None for %s"%(str(Name))];
+      for x in Attrs:
+         Stat.append("But might be: %s %s <%s@debian.org>"%(x[1]["cn"][0],x[1]["sn"][0],x[1]["uid"][0]));
+      return (None,Stat);       
+   else:
+      return (Attrs[0][1]["uid"][0],None);
+
+   return (None,None);
+
+