[Zope-dev] ACL patch for zope 2.6
Erik Dahl
edahl@mindspring.com
Tue, 14 Jan 2003 13:53:29 -0500
This is a multi-part message in MIME format.
--------------040304050904070307090404
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
I wanted to add a little more security to a zope site that has no
firewall in front of it but is mostly for internal users. To do this I
put a check in the accept callback of http_server. Not sure how much
security increase this really gives but I wonder if anyone would find it
useful (or if anyone has a better solution)? Here is the patch. I only
added the acl to the http server, it would be easy to do for the others
as well (but I have these turned off).
-EAD
--------------040304050904070307090404
Content-Type: text/plain; x-mac-type="54455854"; x-mac-creator="74657874";
name="zope2.6-aclpatch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="zope2.6-aclpatch"
diff -C3 -r ./z2.py /home/edahl/zope/z2.py
*** ./z2.py 2002-10-08 17:18:20.000000000 -0400
--- /home/edahl/zope/z2.py 2003-01-14 10:48:40.000000000 -0500
***************
*** 222,227 ****
--- 222,234 ----
- The start of response output, and
- The end of the request.
+ -A acl
+ Add an access control list to the HTTP server. List should be comma
+ delimited and can contain any part of the begining of an ip address.
+ For instnace 1.2.,3.4. would allow two class b networks 1.2.0.0/16
+ and 3.4.0.0/16.
+
+
Environment settings are of the form: NAME=VALUE.
Note: you *must* use Python 2.1 or later!
***************
*** 332,337 ****
--- 339,350 ----
# Use a daemon process
USE_DAEMON = 1
+ # Access control list by IP
+ # each ip should be the begining of an ip
+ # ie 1.2. would allow the class b 1.2.0.0
+ # mulitple ips should be comma delimited
+ ACL_LIST=()
+
#
########################################################################
***************
*** 386,392 ****
opts, args = getopt.getopt(sys.argv[1:],
! 'hz:Z:t:i:a:d:u:w:W:f:p:m:Sl:2DP:rF:L:XM:C',
['icp=', 'force-http-connection-close'
])
--- 399,405 ----
opts, args = getopt.getopt(sys.argv[1:],
! 'hz:Z:t:i:a:d:u:w:W:f:p:m:Sl:2DP:rF:L:XM:CA:',
['icp=', 'force-http-connection-close'
])
***************
*** 470,475 ****
--- 483,490 ----
if v=='-': v=''
FCGI_PORT=v
elif o=='-M': DETAILED_LOG_FILE=v
+ elif o=='-A':
+ ACL_LIST = v.split(',')
except SystemExit: sys.exit(0)
except:
***************
*** 646,652 ****
ip=address,
port=port,
resolver=rs,
! logger_object=lg)
except socket.error, why:
if why[0] == 98: # address in use
raise port_err % {'port':port,
--- 661,669 ----
ip=address,
port=port,
resolver=rs,
! logger_object=lg,
! acl_list=ACL_LIST)
!
except socket.error, why:
if why[0] == 98: # address in use
raise port_err % {'port':port,
diff -C3 -r ./ZServer/HTTPServer.py /home/edahl/zope/ZServer/HTTPServer.py
*** ./ZServer/HTTPServer.py 2002-10-03 22:29:49.000000000 -0400
--- /home/edahl/zope/ZServer/HTTPServer.py 2003-01-14 09:28:44.000000000 -0500
***************
*** 357,365 ****
channel_class = zhttp_channel
shutup=0
! def __init__ (self, ip, port, resolver=None, logger_object=None):
self.shutup=1
! http_server.__init__(self, ip, port, resolver, logger_object)
self.shutup=0
self.log_info('HTTP server started at %s\n'
'\tHostname: %s\n\tPort: %d' % (
--- 357,366 ----
channel_class = zhttp_channel
shutup=0
! def __init__ (self, ip, port, resolver=None, logger_object=None,
! acl_list=None):
self.shutup=1
! http_server.__init__(self, ip, port, resolver, logger_object, acl_list)
self.shutup=0
self.log_info('HTTP server started at %s\n'
'\tHostname: %s\n\tPort: %d' % (
diff -C3 -r ./ZServer/medusa/http_server.py /home/edahl/zope/ZServer/medusa/http_server.py
*** ./ZServer/medusa/http_server.py 2002-06-20 10:39:34.000000000 -0400
--- /home/edahl/zope/ZServer/medusa/http_server.py 2003-01-14 10:31:21.000000000 -0500
***************
*** 558,569 ****
channel_class = http_channel
! def __init__ (self, ip, port, resolver=None, logger_object=None):
self.ip = ip
self.port = port
asyncore.dispatcher.__init__ (self)
self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
!
self.handlers = []
if not logger_object:
--- 558,571 ----
channel_class = http_channel
! def __init__ (self, ip, port, resolver=None, logger_object=None,
! acl_list=None):
self.ip = ip
self.port = port
asyncore.dispatcher.__init__ (self)
self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
! self.acl_list = acl_list
!
self.handlers = []
if not logger_object:
***************
*** 652,657 ****
--- 654,673 ----
self.total_clients.decrement()
return
+ # check acl to see if we accept this connection
+ if self.acl_list:
+ ip = addr[0]
+ message = 'connection from client ' + ip
+ self.log_info(message)
+ for acl in self.acl_list:
+ if ip.find(acl) == 0:
+ break
+ else:
+ message += " blocked"
+ self.log_info(message, 'warning')
+ self.total_clients.decrement()
+ return
+
self.channel_class (self, conn, addr)
def install_handler (self, handler, back=0):
--------------040304050904070307090404--