GPG fixes
[mirror/userdir-ldap.git] / ud-echelon
1 #!/usr/bin/env python
2 # -*- mode: python -*-
3 import userdir_gpg, userdir_ldap, sys, traceback, time, ldap, posix, getopt;
4 import string, pwd
5 from userdir_gpg import *;
6 from userdir_ldap import *;
7
8 EX_TEMPFAIL = 75;
9 EX_PERMFAIL = 65;      # EX_DATAERR
10 Debug = None;
11
12 # Try to extract a key fingerprint from a PGP siged message
13 def TryGPG(Email):
14    # Try to get a pgp text
15    Msg = GetClearSig(Email);
16    if string.find(Msg[0],"-----BEGIN PGP SIGNED MESSAGE-----") == -1:
17       return None;
18       
19    Res = GPGCheckSig(Msg[0]);
20
21    # Failed to find a matching sig
22    if Res[0] != None:
23       S = "%s: %s -> PGP Checking failed '%s': %s %s\n" %(Now,MsgID,Email.getheader("From"),str(Res[0]),str(Res[2]));
24       ErrLog.write(S);
25       return None;
26       
27    # Search for the matching key fingerprint
28    Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"keyfingerprint=" + Res[2][1]);
29    if len(Attrs) == 0:
30       return None;
31    if len(Attrs) != 1:
32       raise Error, "Oddly your key fingerprint is assigned to more than one account.."
33    
34    return (Attrs[0][1]["uid"][0],"PGP",FormatPGPKey(Res[2][1]));
35
36 # Try to guess the name from the email address
37 def TryMatcher(Email):
38    Sender = Email.getheader("From");
39    if Sender == None:
40       return None;
41       
42    # Split up the address and invoke the matcher routine
43    UID = GetUID(l,SplitEmail(Sender));
44    
45    if UID[0] == None:
46       if UID[1] == None or len(UID[1]) == 0:
47          return None;
48
49       # Print out an error message
50       S = "%s: %s -> Address matching failed '%s'\n" %(Now,MsgID,Sender);
51       for x in UID[1]:
52          S = S + " " + x + "\n";
53       ErrLog.write(S);
54       return None;
55     
56    return (UID[0],"FROM",Sender);
57
58 # Process options
59 (options, arguments) = getopt.getopt(sys.argv[1:], "dr")
60 for (switch, val) in options:
61    if (switch == '-d'):
62       Debug = "";
63    
64 # Open the log files
65 if Debug == None:
66    MainLog = open(Ech_MainLog,"a+",0);
67    ErrLog = open(Ech_ErrorLog,"a+",0);
68 else:
69    MainLog = open("/dev/stdout","a+",0);
70    ErrLog = open("/dev/stdout","a+",0);
71    
72 # Start of main program
73 ErrMsg = "Indeterminate Error";
74 ErrType = EX_TEMPFAIL;
75 Now = time.strftime("%a, %d %b %Y %H:%M:%S",time.gmtime(time.time()));
76 MsgID = None;
77 try:
78    # Get the email 
79    ErrType = EX_PERMFAIL;
80    ErrMsg = "Failed to understand the email or find a signature:";
81    Email = mimetools.Message(sys.stdin,0);
82    MsgID = Email.getheader("Message-ID");
83    
84    # Connect to the ldap server
85    ErrType = EX_TEMPFAIL;
86    ErrMsg = "An error occured while performing the LDAP lookup";
87    global l;
88    l = ldap.open(LDAPServer);
89    if Debug == None:
90       F = open(PassDir+"/pass-"+pwd.getpwuid(posix.getuid())[0],"r");
91       AccessPass = string.split(string.strip(F.readline())," ");
92       l.simple_bind_s("uid="+AccessPass[0]+","+BaseDn,AccessPass[1]);
93       F.close();
94    else:
95       l.simple_bind_s("","");
96
97    # Try to decode
98    ErrType = EX_TEMPFAIL;
99    ErrMsg = "An error occured while trying GPG decoding";
100    User = TryGPG(Email);
101    if User == None:
102       ErrMsg = "An error occured while trying Matcher decoding";
103       User = TryMatcher(Email);
104
105    # Get any mailing list information   
106    List = Email.getheader("X-Mailing-List");
107    if List == None:
108       List = "-";
109
110    # Tada, write a log message
111    if User != None:
112       Msg = "[%s] \"%s\" \"%s\" \"%s\""%(Now,User[2],List,MsgID);
113       MainLog.write("%s %s %s\n"%(User[0],User[1],Msg));
114       Dn = "uid=" + User[0] + "," + BaseDn;
115       Rec = [(ldap.MOD_REPLACE,"activity-%s"%(User[1]),Msg)];
116       if Debug == None:
117          l.modify_s(Dn,Rec);
118       else:
119          print Rec;
120    else:
121       User = ("-","UKN",Email.getheader("From"));
122       Msg = "[%s] \"%s\" \"%s\" \"%s\""%(Now,User[2],List,MsgID);
123       MainLog.write("%s %s %s\n"%(User[0],User[1],Msg));
124
125 except:
126    # Log an exception..
127    S = "%s: %s -> %s\n" %(Now,MsgID,ErrMsg);
128    S = S + "==> %s: %s\n" %(sys.exc_type,sys.exc_value);
129    List = traceback.extract_tb(sys.exc_traceback);
130    if len(List) > 1:
131       for x in List:
132          S = S + "   %s %s:%u: %s\n" %(x[2],x[0],x[1],x[3]);
133    ErrLog.write(S);
134    sys.exit(ErrType);
135    
136 sys.exit(0);