Make IP filtering simpler. Use it everywhere.

This commit is contained in:
Nick Daly 2012-06-10 21:00:26 -05:00
parent c9cf5d28c6
commit 445c89838a

View File

@ -1,5 +1,11 @@
"""The HTTPS Santiago listener and sender. """The HTTPS Santiago listener and sender.
FIXME: add real authentication.
FIXME: sanitize or properly escape user input (XSS, attacks on the client).
FIXME: make sure we never try to execute user input (injection, attacks on the
server).
FIXME: all the Blammos. They're terrible, unacceptable failures.
""" """
@ -11,7 +17,16 @@ import httplib, urllib, urlparse
import sys import sys
import logging import logging
def allow_ips(ips = None):
if ips == None:
ips = [ "127.0.0.1" ]
if cherrypy.request.remote.ip not in ips:
santiago.debug_log("Request from non-local IP. Forbidden.")
raise cherrypy.HTTPError(403)
cherrypy.tools.ip_filter = cherrypy.Tool('before_handler', allow_ips)
def start(*args, **kwargs): def start(*args, **kwargs):
"""Module-level start function, called after listener and sender started. """Module-level start function, called after listener and sender started.
@ -50,6 +65,7 @@ class Listener(santiago.SantiagoListener):
santiago.debug_log("Listener Created.") santiago.debug_log("Listener Created.")
@cherrypy.tools.ip_filter()
def index(self, **kwargs): def index(self, **kwargs):
"""Receive an incoming Santiago request from another Santiago client.""" """Receive an incoming Santiago request from another Santiago client."""
@ -63,12 +79,9 @@ class Listener(santiago.SantiagoListener):
except Exception as e: except Exception as e:
logging.exception(e) logging.exception(e)
if not cherrypy.request.remote.ip.startswith("127.0.0."):
santiago.debug_log("Request from non-local IP")
return
raise cherrypy.HTTPRedirect("/freedombuddy") raise cherrypy.HTTPRedirect("/freedombuddy")
@cherrypy.tools.ip_filter()
def learn(self, host, service, **kwargs): def learn(self, host, service, **kwargs):
"""Request a resource from another Santiago client. """Request a resource from another Santiago client.
@ -79,31 +92,21 @@ class Listener(santiago.SantiagoListener):
# if not cherrypy.request.method == "POST": # if not cherrypy.request.method == "POST":
# return # return
if not cherrypy.request.remote.ip.startswith("127.0.0."):
santiago.debug_log("Request from non-local IP")
return
return super(Listener, self).learn(host, service) return super(Listener, self).learn(host, service)
@cherrypy.tools.ip_filter()
def where(self, host, service, **kwargs): def where(self, host, service, **kwargs):
"""Show where a host is providing me services. """Show where a host is providing me services.
TODO: make the output format a parameter. TODO: make the output format a parameter.
""" """
if not cherrypy.request.remote.ip.startswith("127.0.0."):
santiago.debug_log("Request from non-local IP")
return
return list(super(Listener, self).where(host, service)) return list(super(Listener, self).where(host, service))
@cherrypy.tools.ip_filter()
def provide(self, client, service, location, **kwargs): def provide(self, client, service, location, **kwargs):
"""Provide a service for the client at the location.""" """Provide a service for the client at the location."""
if not cherrypy.request.remote.ip.startswith("127.0.0."):
santiago.debug_log("Request from non-local IP")
return
return super(Listener, self).provide(client, service, location) return super(Listener, self).provide(client, service, location)
class Sender(santiago.SantiagoSender): class Sender(santiago.SantiagoSender):
@ -114,6 +117,7 @@ class Sender(santiago.SantiagoSender):
self.proxy_host = proxy_host self.proxy_host = proxy_host
self.proxy_port = proxy_port self.proxy_port = proxy_port
@cherrypy.tools.ip_filter()
def outgoing_request(self, request, destination): def outgoing_request(self, request, destination):
"""Send an HTTPS request to each Santiago client. """Send an HTTPS request to each Santiago client.
@ -209,6 +213,7 @@ class RestMonitor(santiago.RestController):
searchList = [dict(values)]))] searchList = [dict(values)]))]
class HostedService(RestMonitor): class HostedService(RestMonitor):
@cherrypy.tools.ip_filter()
def GET(self, client, service): def GET(self, client, service):
return self.respond("hostedService-get.tmpl", { return self.respond("hostedService-get.tmpl", {
"service": service, "service": service,
@ -216,17 +221,20 @@ class HostedService(RestMonitor):
"locations": self.santiago.hosting[client][service] }) "locations": self.santiago.hosting[client][service] })
class HostedClient(RestMonitor): class HostedClient(RestMonitor):
@cherrypy.tools.ip_filter()
def GET(self, client): def GET(self, client):
return self.respond("hostedClient-get.tmpl", return self.respond("hostedClient-get.tmpl",
{ "client": client, { "client": client,
"services": self.santiago.hosting[client] }) "services": self.santiago.hosting[client] })
class Hosting(RestMonitor): class Hosting(RestMonitor):
@cherrypy.tools.ip_filter()
def GET(self): def GET(self):
return self.respond("hosting-get.tmpl", return self.respond("hosting-get.tmpl",
{"clients": [x for x in self.santiago.consuming]}) {"clients": [x for x in self.santiago.consuming]})
class ConsumedService(RestMonitor): class ConsumedService(RestMonitor):
@cherrypy.tools.ip_filter()
def GET(self, host, service): def GET(self, host, service):
return self.respond("consumedService-get.tmpl", return self.respond("consumedService-get.tmpl",
{ "service": service, { "service": service,
@ -235,16 +243,19 @@ class ConsumedService(RestMonitor):
self.santiago.consuming[host][service] }) self.santiago.consuming[host][service] })
class ConsumedHost(RestMonitor): class ConsumedHost(RestMonitor):
@cherrypy.tools.ip_filter()
def GET(self, host): def GET(self, host):
return self.respond("consumedHost-get.tmpl", return self.respond("consumedHost-get.tmpl",
{ "services": self.santiago.consuming[host], { "services": self.santiago.consuming[host],
"host": host }) "host": host })
class Consuming(RestMonitor): class Consuming(RestMonitor):
@cherrypy.tools.ip_filter()
def GET(self): def GET(self):
return self.respond("consuming-get.tmpl", return self.respond("consuming-get.tmpl",
{ "hosts": [x for x in self.santiago.consuming]}) { "hosts": [x for x in self.santiago.consuming]})
@cherrypy.tools.ip_filter()
def POST(self, host="", put="", delete=""): def POST(self, host="", put="", delete=""):
if put: if put:
self.PUT(put) self.PUT(put)
@ -255,21 +266,27 @@ class Consuming(RestMonitor):
raise cherrypy.HTTPRedirect("/consuming") raise cherrypy.HTTPRedirect("/consuming")
@cherrypy.tools.ip_filter()
def PUT(self, put): def PUT(self, put):
self.santiago.consuming[host] = None self.santiago.consuming[host] = None
@cherrypy.tools.ip_filter()
def DELETE(self, delete): def DELETE(self, delete):
if delete in self.santiago.consuming: if delete in self.santiago.consuming:
del self.santiago.consuming[delete] del self.santiago.consuming[delete]
class Root(RestMonitor): class Root(RestMonitor):
@cherrypy.tools.ip_filter()
def GET(self): def GET(self):
return self.respond("root-get.tmpl", {}) return self.respond("root-get.tmpl", {})
class Stop(RestMonitor): class Stop(RestMonitor):
@cherrypy.tools.ip_filter()
def POST(self): def POST(self):
self.santiago.live = 0 self.santiago.live = 0
raise cherrypy.HTTPRedirect("/")
@cherrypy.tools.ip_filter()
def GET(self): def GET(self):
self.POST() # cause it's late and I'm tired. self.POST() # FIXME cause it's late and I'm tired.