#!/usr/bin/env python # -*- mode: python -*- import userdir_gpg, userdir_ldap, sys, traceback, time, ldap, os, getopt; import pwd import email, email.parser from userdir_gpg import *; from userdir_ldap import *; EX_TEMPFAIL = 75; EX_PERMFAIL = 65; # EX_DATAERR Debug = None; # Try to extract a key fingerprint from a PGP siged message def TryGPG(mail): # Try to get a pgp text try: Msg = GetClearSig(mail, lax_multipart=True); except: # Log an exception.. but continue. This is to deal with 'sort of' # PGP-MIME things S = "%s: %s -> %s\n" %(Now,MsgID,ErrMsg); S = S + " %s: %s\n" %(sys.exc_type,sys.exc_value); ErrLog.write(S); return None; if Msg[0].find("-----BEGIN PGP SIGNED MESSAGE-----") == -1: return None; pgp = GPGCheckSig2(Msg[0]); # Failed to find a matching sig if not pgp.ok: S = "%s: %s -> PGP Checking failed '%s': %s %s\n" %(Now,MsgID,mail["From"],str(pgp.why),str(pgp.key_info)); ErrLog.write(S); return None; # Search for the matching key fingerprint Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"keyFingerPrint=" + pgp.key_fpr); if len(Attrs) == 0: return None; if len(Attrs) != 1: raise Error, "Oddly your key fingerprint is assigned to more than one account.." return (Attrs[0][1]["uid"][0],"PGP",FormatPGPKey(pgp.key_fpr)); # Try to guess the name from the email address def TryMatcher(mail): Sender = mail["From"]; if Sender == None: return None; # Split up the address and invoke the matcher routine UID = GetUID(l,SplitEmail(Sender)); if UID[0] == None: if UID[1] == None or len(UID[1]) == 0: return None; # Print out an error message S = "%s: %s -> Address matching failed '%s'\n" %(Now,MsgID,Sender); for x in UID[1]: S = S + " " + x + "\n"; ErrLog.write(S); return None; return (UID[0],"FROM",Sender); # Process options (options, arguments) = getopt.getopt(sys.argv[1:], "dr") for (switch, val) in options: if (switch == '-d'): Debug = ""; # Open the log files 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; Now = time.strftime("%a, %d %b %Y %H:%M:%S",time.gmtime(time.time())); MsgID = None; try: # Get the email ErrType = EX_PERMFAIL; ErrMsg = "Failed to understand the email or find a signature:"; mail = email.parser.Parser().parse(sys.stdin); MsgID = mail["Message-ID"] # Connect to the ldap server ErrType = EX_TEMPFAIL; ErrMsg = "An error occured while performing the LDAP lookup"; global l; l = connectLDAP() if Debug == None: F = open(PassDir+"/pass-"+pwd.getpwuid(os.getuid())[0],"r"); AccessPass = F.readline().strip().split(" ") l.simple_bind_s("uid="+AccessPass[0]+","+BaseDn,AccessPass[1]); F.close(); else: l.simple_bind_s("",""); # Try to decode ErrType = EX_TEMPFAIL; ErrMsg = "An error occured while trying GPG decoding"; User = TryGPG(mail); if User == None: ErrMsg = "An error occured while trying Matcher decoding"; User = TryMatcher(mail); # Get any mailing list information List = mail['X-Mailing-List'] if not List: List = "-"; # Tada, write a log message if User != None: Msg = "[%s] \"%s\" \"%s\" \"%s\""%(Now,User[2],List,MsgID); 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)]; if Debug == None: l.modify_s(Dn,Rec); else: print Rec; else: User = ("-","UKN",mail["From"]); Msg = "[%s] \"%s\" \"%s\" \"%s\""%(Now,User[2],List,MsgID); MainLog.write("%s %s %s\n"%(User[0],User[1],Msg)); except: # Log an exception.. S = "%s: %s -> %s\n" %(Now,MsgID,ErrMsg); S = S + "==> %s: %s\n" %(sys.exc_type,sys.exc_value); List = traceback.extract_tb(sys.exc_traceback); if len(List) > 1: for x in List: S = S + " %s %s:%u: %s\n" %(x[2],x[0],x[1],x[3]); ErrLog.write(S); sys.exit(ErrType); sys.exit(0);