[Zope-Checkins] CVS: Zope/lib/python/ZPublisher - HTTPRequest.py:1.87

Toby Dickenson tdickenson@geminidataloggers.com
Thu, 2 Jan 2003 15:30:02 -0500


Update of /cvs-repository/Zope/lib/python/ZPublisher
In directory cvs.zope.org:/tmp/cvs-serv12855/lib/python/ZPublisher

Modified Files:
	HTTPRequest.py 
Log Message:
Implemented smarter-than-REMOTE_ADDR proposal. IP-based access controls now work through a proxy.

=== Zope/lib/python/ZPublisher/HTTPRequest.py 1.86 => 1.87 ===
--- Zope/lib/python/ZPublisher/HTTPRequest.py:1.86	Fri Dec 20 10:34:48 2002
+++ Zope/lib/python/ZPublisher/HTTPRequest.py	Thu Jan  2 15:29:59 2003
@@ -223,6 +223,11 @@
             del self.other[x]
         self._urls = ()
 
+    def getClientAddr(self):
+        """ The IP address of the client.
+        """
+        return self._client_addr
+
     def __init__(self, stdin, environ, response, clean=0):
         self._orig_env=environ
         # Avoid the overhead of scrubbing the environment in the
@@ -248,6 +253,16 @@
         self._steps=[]
         self._lazies={}
 
+
+        if environ.has_key('REMOTE_ADDR'):
+            self._client_addr = environ['REMOTE_ADDR']
+            if environ.has_key('HTTP_X_FORWARDED_FOR') and self._client_addr in trusted_proxies:
+                # REMOTE_ADDR is one of our trusted local proxies. Not really very remote at all.
+                # The proxy can tell us the IP of the real remote client in the forwarded-for header
+                self._client_addr = environ['HTTP_X_FORWARDED_FOR'].split(',')[-1].strip()
+        else:
+            self._client_addr = ''
+
         ################################################################
         # Get base info first. This isn't likely to cause
         # errors and might be useful to error handlers.
@@ -1489,3 +1504,20 @@
 REC=RECORD|RECORDS
 EMPTY=16
 CONVERTED=32
+
+
+# The ZOPE_TRUSTED_PROXIES environment variable contains a colon separated 
+# list of front-end proxies that are trusted to supply an accurate
+# X_FORWARDED_FOR header. If REMOTE_ADDR is one of the values in this list
+# and it has set an X_FORWARDED_FOR header, ZPublisher copies REMOTE_ADDR
+# into X_FORWARDED_BY, and the last element of the X_FORWARDED_FOR list
+# into REMOTE_ADDR. X_FORWARDED_FOR is left unchanged.
+# This function parses the environment variable into a module variable
+# 
+def trusted_proxies():
+    proxies = os.environ.get('ZOPE_TRUSTED_PROXIES','')
+    proxies = proxies.split(':')
+    proxies = [p.strip() for p in proxies]
+    return tuple(proxies)
+trusted_proxies = trusted_proxies()
+