From: jgg <> Date: Mon, 3 Jan 2000 08:34:26 +0000 (+0000) Subject: Echelon X-Git-Tag: debian_userdir-ldap_0-3-7~178 X-Git-Url: https://git.adam-barratt.org.uk/?p=mirror%2Fuserdir-ldap.git;a=commitdiff_plain;h=d34f4cb87a80d211f07fc1bfb2b9a630d1346e7c Echelon --- diff --git a/debian/rules b/debian/rules index d64dad8..ec49962 100755 --- a/debian/rules +++ b/debian/rules @@ -38,7 +38,7 @@ binary-indep: build echo "userdir_gpg" >> $(i)/$(pysite)/userdir_ldap.pth install -m 644 userdir_ldap.py userdir_gpg.py \ $(i)/$(pysite)/userdir_ldap/ - install -m 755 {ud-forwardlist,ud-gpgimport,ud-info,ud-ldapshow,ud-userimport,ud-mailgate,ud-generate,ud-passchk,ud-useradd,ud-replicate,ud-xearth,ud-fingerserv} $(i)/usr/bin/ + install -m 755 {ud-forwardlist,ud-gpgimport,ud-info,ud-ldapshow,ud-userimport,ud-mailgate,ud-generate,ud-passchk,ud-useradd,ud-replicate,ud-xearth,ud-fingerserv,ud-echelon} $(i)/usr/bin/ install -m 755 web/*.* $(i)/var/www/userdir-ldap/ chown www-data.www-data $(i)/var/cache/userdir-ldap/web-cookies/ chmod u=rwx,g=,o= $(i)/var/cache/userdir-ldap/web-cookies/ diff --git a/ud-echelon b/ud-echelon new file mode 100755 index 0000000..6434f0e --- /dev/null +++ b/ud-echelon @@ -0,0 +1,182 @@ +#!/usr/bin/env python +# -*- mode: python -*- +import userdir_gpg, userdir_ldap, sys, traceback, time, ldap, posix; +import string, pwd +from userdir_gpg import *; +from userdir_ldap import *; + +EX_TEMPFAIL = 75; +EX_PERMFAIL = 65; # EX_DATAERR + +# Try to extract a key fingerprint from a PGP siged message +def TryGPG(Email): + # Try to get a pgp text + Msg = GetClearSig(Email); + if string.find(Msg[0],"-----BEGIN PGP SIGNED MESSAGE-----") == -1: + return None; + + Res = GPGCheckSig(Msg[0]); + + # Failed to find a matching sig + if Res[0] != None: + return None; + + # Search for the matching key fingerprint + Attrs = l.search_s(BaseDn,ldap.SCOPE_ONELEVEL,"keyfingerprint=" + Res[2][1]); + 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(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"); + 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); + +# Open the log files +MainLog = open(Ech_MainLog,"a+",0); +ErrLog = open(Ech_ErrorLog,"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:"; + Email = mimetools.Message(sys.stdin,0); + MsgID = Email.getheader("Message-ID"); + + # Connect to the ldap server + ErrType = EX_TEMPFAIL; + 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(); + + # Try to decode + ErrType = EX_TEMPFAIL; + ErrMsg = "An error occured while trying GPG decoding"; + User = TryGPG(Email); + if User == None: + ErrMsg = "An error occured while trying Matcher decoding"; + User = TryMatcher(Email); + + # Get any mailing list information + List = Email.getheader("X-Mailing-List"); + if List == None: + 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)]; + l.modify_s(Dn,Rec); + else: + User = ("-","UKN",Email.getheader("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); diff --git a/ud-gpgimport b/ud-gpgimport index bd9ba9e..a0f1764 100755 --- a/ud-gpgimport +++ b/ud-gpgimport @@ -23,8 +23,6 @@ from userdir_gpg import *; UnknownMap = {}; NoAct = 1; -AddressSplit = re.compile("(.*).*<([^@]*)@([^>]*)>"); - # Read the override file into the unknown map. The override file is a list # of colon delimited entires mapping PGP email addresess to local users def LoadOverride(File): diff --git a/userdir-ldap.conf b/userdir-ldap.conf index b61d1f4..bc3e4c0 100644 --- a/userdir-ldap.conf +++ b/userdir-ldap.conf @@ -19,13 +19,16 @@ templatesdir = "/etc/userdir-ldap/templates/"; replaycachefile = "/var/cache/userdir-ldap/replay"; #replaycachefile = "/tmp/replay"; +# Echelon +ech_errorlog = "/org/db.debian.org/mail/Log/ech-errors.log" +ech_mainlog = "/org/db.debian.org/mail/Log/ech.log" + # User properties defaultgid = 800; # For the output generator generateconf = "/etc/userdir-ldap/generate.conf" generatedir = "/var/cache/userdir-ldap/hosts/"; -#generatedir = "/tmp/hosts"; passdir = "/etc/userdir-ldap/"; # GPG Things @@ -43,7 +46,7 @@ webloginurl = "login.cgi"; websearchurl = "search.cgi"; webupdateurl = "update.cgi"; -weblogfile = '/var/log/userldap-web.log'; +weblogfile = "/var/log/userldap-web.log"; # When should authentication tokens expire? authexpires = 600; diff --git a/userdir_ldap.py b/userdir_ldap.py index adcc859..f3f9ba7 100644 --- a/userdir_ldap.py +++ b/userdir_ldap.py @@ -1,5 +1,5 @@ # Some routines and configuration that are used by the ldap progams -import termios, TERMIOS, re, string, imp, ldap, sys, whrandom, crypt; +import termios, TERMIOS, re, string, imp, ldap, sys, whrandom, crypt, rfc822; try: File = open("/etc/userdir-ldap/userdir-ldap.conf"); @@ -8,6 +8,7 @@ except: ConfModule = imp.load_source("userdir_config","/etc/userdir-ldap.conf",File); File.close(); +# Cheap hack BaseDn = ConfModule.basedn; BaseDn = ConfModule.basedn; LDAPServer = ConfModule.ldaphost; @@ -18,6 +19,8 @@ GenerateConf = ConfModule.generateconf; DefaultGID = ConfModule.defaultgid; TemplatesDir = ConfModule.templatesdir; PassDir = ConfModule.passdir; +Ech_ErrorLog = ConfModule.ech_errorlog; +Ech_MainLog = ConfModule.ech_mainlog; # This is a list of common last-name prefixes LastNamesPre = {"van": None, "le": None, "de": None, "di": None}; @@ -238,5 +241,17 @@ def FormatPGPKey(Str): I = I + 4; else: Res = Str; - return Res; - + return string.strip(Res); + +# Take an email address and split it into 3 parts, (Name,UID,Domain) +def SplitEmail(Addr): + Res1 = rfc822.AddrlistClass(Addr).getaddress(); + if len(Res1) != 1: + return ("","",Addr); + Res1 = Res1[0]; + if Res1[1] == None: + return (Res1[0],"",""); + Res2 = string.split(Res1[1],"@"); + if len(Res2) != 2: + return (Res1[0],"",Res1[1]); + return (Res1[0],Res2[0],Res2[1]);