#!/usr/bin/env python
# -*- mode: python -*-
# This script tries to match a list of email addresses to the ldap database
# uids. It makes use of the PGP key ring to determine matches

import re, time, ldap, getopt, sys;
from userdir_ldap import *;
from userdir_gpg import *;

AddressSplit = re.compile("(.*).*<([^@]*)@([^>]*)>");

# Import an an forward file
def ImportForward(File,EmailMap):
   F = open(File,"r");
   while(1):
      Line = F.readline().strip()
      if Line == "":
         break;
      Split = Line.split(":")
      if len(Split) != 2:
         continue;
   
      Addr = Split[1].strip()
      if EmailMap.has_key(Addr) and  EmailMap[Addr] != Split[0]:
         print "Dup Over Emap",Line,Split
      else:
         EmailMap[Addr] = Split[0];
   F.close();

# Import an override file
def ImportOverride(File,OverMap):
   F = open(File,"r");
   while(1):
      Line = F.readline();
      if Line == "":
         break;
      Line = Line.strip()

      Split = Line.split(":")
      if len(Split) != 2:
         continue;
      OverMap[Split[0]] = Split[1].strip()
   F.close();

(options, arguments) = getopt.getopt(sys.argv[1:], "o:f:")

# Popen GPG with the correct magic special options
Args = [GPGPath] + GPGBasicOptions + GPGKeyRings;
for x in arguments:
   Args.append("--keyring");
   Args.append(x);
Args = Args + GPGSearchOptions + [" 2> /dev/null"]
Keys = os.popen(" ".join(Args),"r")

l = connectLDAP()

# Fetch the key list and map to email address
PasswdAttrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"keyfingerprint=*",\
                ["uid","keyfingerprint"]);
KFMap = {}
for x in PasswdAttrs:
   if x[1].has_key("keyfingerprint") == 0 or x[1].has_key("uid") == 0:
      continue;
   for I in x[1]["keyfingerprint"]:
      KFMap[I] = x[1]["uid"][0];
   
# Loop over the GPG key file mapping addresses to uids
Outstanding = 0;
Ignored = 0;
Emails = [];
EmailMap = {};
UIDMap = {};
UID = None;
FingerPrint = None;
print "Reading keyrings",
sys.stdout.flush();
while(1):
   Line = Keys.readline();
   if Line == "":
      break;
   
   Split = Line.split(":")
   if len(Split) >= 8 and Split[0] == "pub":
      if FingerPrint != None and UID != None:
         for x in Emails:
            Match = AddressSplit.match(x);
            if Match == None:
              continue;
            Groups = Match.groups();
	    Email = Groups[1]+'@'+Groups[2];
	    if UIDMap.has_key(Groups[1]):
	       UIDMap[Groups[1]].append(Email);
            else:
	       UIDMap[Groups[1]] = [Email];
	    if EmailMap.has_key(Email) and EmailMap[Email] != UID:
	       print "Dup Emap",Email
            else:
	       EmailMap[Email] = UID;
      Emails = [Split[9]];
      continue;
   if len(Split) >= 11 and Split[0] == "fpr":
      FingerPrint = Split[9];
      if KFMap.has_key(FingerPrint) == 0:
         print "Failed",FingerPrint;
	 UID = None;
         continue;
      UID = KFMap[FingerPrint];
   if len(Split) >= 9 and Split[0] == "uid":
      Emails.append(Split[9]);
print;

# Process the override files
for (switch, val) in options:
   if (switch == '-f'):
      ImportForward(val,EmailMap);
      BindUser = val;
   elif (switch == '-o'):
      ImportOverride(val,EmailMap);

# Map the input
FinalMap = {};
while(1):
   Line = sys.stdin.readline();
   if Line == "":
      break;
   Line = Line.strip()

   Split = Line.split("@")
   if len(Split) != 2:
      continue;

   # The address is in our domain, go directly
   if Split[1] == EmailAppend:
      if FinalMap.has_key(Line):
        print "Dup",Line
      Split2 = Split[0].split("-")
      FinalMap[Line] = Split2[0];
      continue;

   # Exists in the email map..
   if EmailMap.has_key(Line):
      if FinalMap.has_key(Line):
        print "Dup",Line
      FinalMap[Line] = EmailMap[Line];
      continue;

   # Try again splitting off common address appendage modes
   Split2 = Split[0].split("-")
   Addr = Split2[0]+'@'+Split[1];
   if EmailMap.has_key(Addr):
      if FinalMap.has_key(Addr):
        print "Dup",Addr
      FinalMap[Line] = EmailMap[Addr];
      continue;

    # Failed 
   if UIDMap.has_key(Split[0]):
      print Line,UIDMap[Split[0]];
   print Line;
print "-----";

# Generate a reverse map and check for duplicates
Back = {};
for x in FinalMap.keys():
   if Back.has_key(FinalMap[x]):
      print "Dup",x,FinalMap[x],Back[FinalMap[x]];
   Back[FinalMap[x]] = x;
   
# Print the forward map
for x in Back.keys():
   print "%s: %s" % (x,Back[x]);
