--- IntranetUserFolder/IntranetUserFolder.py 2006/07/05 12:38:21 1.2 +++ IntranetUserFolder/IntranetUserFolder.py 2007/03/01 19:17:10 1.3 @@ -1,118 +1,100 @@ -"""User Folder Extension, tests now also ip number of the host where the original call comes from in case of redirects""" +"""User Folder Extension, tests now also ip number of the host where the original connection + comes from in case of proxies/rewrites""" import Globals from AccessControl.User import UserFolder +from AccessControl import AuthEncoding from Globals import MessageDialog -import zLOG +import logging import re +import socket class IntranetUserFolder(UserFolder): - """User folder for Intranet""" - _domain_auth_mode=1 # Identification via domain - meta_type="IntranetUserFolder" - - def authenticate(self, name, password, request): - """modified authenticate to use domainspecmath below""" - #zLOG.LOG('IntranetUserFolder',zLOG.INFO,"authenticate %s, %s from %s"%(name,password,request['REMOTE_ADDR'])) - - emergency = self._emergency_user - if name is None: - return None - if emergency and name==emergency.getUserName(): - user = emergency - else: - user = self.getUser(name) - if user is not None and user.authenticate(password, request): - domains = user.getDomains() - if self.domainSpecMatch(domains, request): - #zLOG.LOG('IntranetUserFolder',zLOG.INFO," as %s"%user) - return user - - #zLOG.LOG('IntranetUserFolder',zLOG.INFO," failed!") - return None - - def domainSpecMatch(self, spec, request): - """modified domainspecmatch to look at FORWARDED_FOR""" - #zLOG.LOG('IntranetUserFolder',zLOG.INFO,"domainspecmatch %s, %s"%(self,spec)) - host='' - addr='' - - - # Fast exit for the match-all case - if len(spec) == 1 and spec[0] == '*': - return 1 - - if request.has_key('REMOTE_HOST'): - host=request['REMOTE_HOST'] - - addr=request.getClientAddr() - #if request.has_key('REMOTE_ADDR'): - # addr=request['REMOTE_ADDR'] - - if request.has_key('HTTP_X_FORWARDED_FOR'): - addr=request['HTTP_X_FORWARDED_FOR'] - #zLOG.LOG('IntranetUserFolder',zLOG.INFO,"forwarded addr: %s"%(addr)) - # check for strange headers (may be fake) - if len(addr.split('.')) != 4: - zLOG.LOG('IntranetUserFolder',zLOG.WARNING,"invalid forward addr: %s"%(addr)) - return 0 - - if not host and not addr: - return 0 - - if not host: - try: host=socket.gethostbyaddr(addr)[0] - except: pass - if not addr: - try: addr=socket.gethostbyname(host) - except: pass - - _host=host.split('.') - _addr=addr.split('.') - _hlen=len(_host) - _alen=len(_addr) - - #zLOG.LOG('IntranetUserFolder',zLOG.INFO,"host: %s, addr: %s"%(_host,_addr)) - - for ob in spec: - sz=len(ob) - _ob=ob.split('.') - _sz=len(_ob) - - mo = addr_match(ob) - if mo is not None: - if mo.end(0)==sz: - fail=0 - for i in range(_sz): - a=_addr[i] - o=_ob[i] - if (o != a) and (o != '*'): - fail=1 - break - if fail: - continue - return 1 - - mo = host_match(ob) - if mo is not None: - if mo.end(0)==sz: - if _hlen < _sz: - continue - elif _hlen > _sz: - _item=_host[-_sz:] - else: - _item=_host - fail=0 - for i in range(_sz): - h=_item[i] - o=_ob[i] - if (o != h) and (o != '*'): - fail=1 - break - if fail: - continue - return 1 - return 0 + """User folder for Intranet""" + _domain_auth_mode=1 # Identification via domain + meta_type="IntranetUserFolder" + + def authenticate(self, name, password, request): + """modified authenticate to use domainspecmatch below""" + #logging.debug("IntranetUserFolder: authenticate %s from %s"%(name,request['REMOTE_ADDR'])) + + emergency = self._emergency_user + if name is None: + return None + if emergency and name==emergency.getUserName(): + user = emergency + else: + user = self.getUser(name) + + #logging.debug("IntranetUserFolder: user: %s"%repr(user)) + + if user is not None: + pwd=user._getPassword() + # check PW first (which may be empty) + if AuthEncoding.pw_validate(pwd, password): + domains = user.getDomains() + #logging.debug("IntranetUserFolder: pw OK, domains: %s"%(repr(domains))) + if self.domainSpecMatch(domains, request): + logging.debug("IntranetUserFolder: domain user %s"%user) + return user + #else: + #logging.debug("IntranetUserFolder: pw not ok: '%s'"%password) + #logging.debug("IntranetUserFolder: user has password: '%s'"%user._getPassword()) + + logging.debug("IntranetUserFolder: authenticate failed here!") + return None + + def domainSpecMatch(self, spec, request): + """modified domainspecmatch to look at FORWARDED_FOR""" + #logging.debug("IntranetUserFolder: domainspecmatch %s, %s"%(self,spec)) + addr='' + + # Fast exit for the match-all case + if len(spec) == 0 or (len(spec) == 1 and spec[0] == '*'): + return 1 + + # start with getClientAddr + addr=request.getClientAddr() + #logging.debug("IntranetUserFolder: getclientaddr: %s"%(addr)) + #if request.has_key('REMOTE_ADDR'): + # addr=request['REMOTE_ADDR'] + + # override with forwarded address if present + if request.get('HTTP_X_FORWARDED_FOR', None): + addr=request['HTTP_X_FORWARDED_FOR'] + #logging.debug("IntranetUserFolder: forwarded addr: %s"%(addr)) + + # check for strange headers (may be fake) + if len(addr.split('.')) != 4: + logging.warning("IntranetUserFolder: invalid forward addr: %s"%(addr)) + return 0 + + if not addr: + return 0 + + _addr=addr.split('.') + #logging.debug("IntranetUserFolder: addr: %s , %s"%(repr(_addr), repr(_m), repr(_addr & _m))) + + for ob in spec: + sz=len(ob) + _ob=ob.split('.') + _sz=len(_ob) + + mo = addr_match(ob) + if mo is not None: + if mo.end(0)==sz: + fail=0 + for i in range(_sz): + a=_addr[i] + o=_ob[i] + if (o != a) and (o != '*'): + fail=1 + break + if fail: + continue + return 1 + + return 0 Globals.default__class_init__(IntranetUserFolder) @@ -131,8 +113,7 @@ def manage_addIntranetUserFolder(self,dt REQUEST['RESPONSE'].redirect(self.absolute_url()+'/manage_main') def manage_addIntranetUserFolderForm(self): - """add a user folder form""" - return manage_addIntranetUserFolder(self,REQUEST=self.REQUEST) + """add a user folder form""" + return manage_addIntranetUserFolder(self,REQUEST=self.REQUEST) addr_match=re.compile(r'((\d{1,3}\.){1,3}\*)|((\d{1,3}\.){3}\d{1,3})').match -host_match=re.compile(r'(([\_0-9a-zA-Z\-]*\.)*[0-9a-zA-Z\-]*)').match