class SecurityContextTestCase(unittest.TestCase): logger = getLogger("SecurityContextTestCase") file = "security.xml.sample" def setUp(self): self.context = Context() self.logger.debug(str(len(self.context.roles))) def tearDown(self): del self.context def testPermissions(self): self.assertTrue(len(self.context.permissions) == 5) self.assertEqual(self.context.permissions[0].id, "allow-all") self.assertEqual(self.context.permissions[2].id, "deny-localhost") self.assertEqual(len(self.context.permissions[2].constraints), 2) def testRoles(self): self.assertTrue(len(self.context.roles) == 2) self.assertEqual(self.context.roles[1].id, "administrator") def testUsers(self): self.assertTrue(len(self.context.users) == 2) u = self.context.get_user("user1", "123") self.assertTrue(u is not None) command = "nmap -v localhost" self.assertFalse(u.is_permitted(command))
class HttpResponse(object): """A class to represent a HTTP Response to be sent back to the web browser (client). It is possible to set response headers working like a dict, with the ``__setitem__`` method. Example: >>> response['Content-type'] = 'text/html' >>> response['Content-disposition'] = 'attachment; filename=xyz.html' """ logger = getLogger("HttpResponse") def __init__(self, data="", mimeType="text/html"): self.headers = {} self.data = data self.code = 200 self.headers['Content-type'] = mimeType def write(self, data): """Appends text to the response stream """ self.data += data def loadTemplate(self, template): """Load a template given its filename (relative to ``Path.templates_dir``).""" template_dir = Path.templates_dir template = template.split("/") tpl_path = os.path.join(template_dir, *template) #self.logger.debug("TEMPLATE FILE: " + tpl_path) self.data += open(tpl_path).read() def __add__(self, obj): if type(obj) in StringTypes: response = deepcopy(self) response.write(obj) return response if not issubclass(obj.__class__, self.__class__): raise ValueError, "Cannot add object %s of type %s" % ( repr(obj), repr(obj.__class__)) else: return HttpResponse(self.data + obj.data, self.headers['Content-type']) def __mod__(self, l): response = deepcopy(self) response.data %= l return response def __setitem__(self, key, value): self.headers[key] = value def __getitem__(self, key): return self.headers[key] def __str__(self): return self.data
class UmitWebServer(HTTPServer): _resourcePool = {} currentInstance = None logger = getLogger("UmitWebServer") def __init__(self): HTTPServer.__init__( self, (Path.web_server_address, int(Path.web_server_port)), UmitRequestHandler) UmitWebServer.currentInstance = self def finish_request(self, *args, **kwargs): HTTPServer.finish_request(self, *args, **kwargs) def close_request(self, request): HTTPServer.close_request(self, request) request.close() del request def addResource(self, resource, public=False): junk = "çoa^wer098~73°0£24q¢ßðæ3w4w98948512397&*@#$!@#*(1234567890*/)" key = md5.new(str(random.randint(0, sys.maxint-1)) \ + str(random.randint(1, sys.maxint-1)//2) \ + junk).hexdigest() self._resourcePool[key] = resource return key def removeResource(self, resourceID): if resourceID in self._resourcePool.keys(): del self._resourcePool[resourceID] return True return False def getResource(self, resourceID): if resourceID in self._resourcePool.keys(): return self._resourcePool[resourceID] def updateResource(self, resourceID, resource): if resourceID in self._resourcePool.keys(): self._resourcePool[resourceID] = resource return True return False def fireResourceEvent(self, resourceID, eventName): if resourceID in self._resourcePool.keys(): if hasattr(self._resourcePool[resourceID], eventName): target = getattr(self._resourcePool[resourceID], eventName) th = ServerThread(target) th.start() return th return False def run(self): SessionWrapper.clear() #os.chroot(os.path.join(os.path.dirname(__file__), "chroot")) #f = open("umitweb.log", "a+", 1) #sys.stderr = sys.stdout = f self.serve_forever()
class BaseTest(object): _path = "" logger = getLogger("TEST: %s" % _path) def __init__(self, req): self._req = req def runTest(self): HttpResponse("=P")
def get_security_parser(config_file=None): logger = getLogger("Context") cfg_file = config_file or SECURITY_FILE parser = make_parser() ctx = SecurityContext() parser.setContentHandler(SecurityConfHandler(ctx)) f = open(cfg_file, 'r') parser.parse(f) f.close() return ctx
class URLResolver(object): """A class to resolve URLs. It works anylsing the path passed to the server. UmitWeb has a urls module that contains URL patterns (like in django framework - http://www.djangoproject.com). Each pattern is assinged with one function. This function is executed and the result (an instance of HttpResponse) is sent back to the client (the http browser). """ logger = getLogger("URLResolver") def __init__(self): pass def resolve(self, request): """Resolve the path and executes the assigned function. if the path wasn't found in the urls module, this method raises a Http404 error. Parameters: * ``request`` -- and instance of HttpRequest. """ path = request.get_path()[1:] found = False for regex, action in patterns: pat = re.compile(regex) match = pat.match(path) if match: try: found = True module, function = action.rsplit(".", 1) module = __import__(module, level=0, fromlist=["umitWeb.views"]) self.logger.debug("Importing module (" + path + "): " + module.__name__) executer = getattr(module, function) ret = executer(request, **match.groupdict()) del executer del module return ret except ImportError, e: raise HttpError(500, str(e)) break if not found: raise Http404
class HttpTestCase(unittest.TestCase): logger = getLogger("HttpTestCase") def setUp(self): self.server_url = "http://localhost:8059" self.info_url = "%s/test/server/info/" % self.server_url self.req_info = urllib2.Request(self.info_url) def get_cookie(self, headers, name): try: pattern = r".*%s=([^;]+)[;]{0,1}.*" % name return re.findall(pattern, headers['set-cookie'])[0] except Exception, ex: raise ValueError("Cookie %s does not exist. Exception: %s" % (name, str(ex)))
class ServerThread(Thread): logger = getLogger("Thread") def __init__(self, child_process=None): Thread.__init__(self) self.child_process = child_process self.exceptions = [] def run(self): if callable(self.child_process): try: self.child_process() except Exception, e: self.logger.critical( ">>> Exception during child_process execution: %s" % str(e)) self.exceptions.append(e)
def run_tests(): logger = getLogger() unittest.main()
# This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from umitWeb.Http import HttpResponseRedirect, Http403 from umitWeb.WebLogger import getLogger REDIRECT = 0 ERROR = 1 logger = getLogger(__name__) #decorator def authenticate(destination=None, redirect_page=None): """``authenticate`` is a decorator for each view that needs authentication. Parameters: * ``destination`` -- the argument that determines if the page will be redirected to another location (0), or a forbidden page (error 403) will be displayed (1). * ``redirect_page`` -- the page that will be followed by if the user is not authenticated. """ destination = destination or REDIRECT redirect_page = redirect_page or "/login/"
class JsOutputHighlight(NmapOutputHighlight): logger = getLogger("JsOutputHighlight") def __init__(self, *args): NmapOutputHighlight.__init__(self, *args) self.parser.read(Path.webconfig_file)
from math import floor, sqrt import sys import os from types import DictType from umitWeb.Http import HttpResponse, Http404, HttpError from umitWeb.Auth import authenticate, ERROR from umitWeb.WebLogger import getLogger from umitCore.NmapParser import NmapParser from umitCore.Diff import Diff, ParserDiff from umitCore.UmitConf import DiffColors from umitCore.DiffHtml import DiffHtml from tempfile import mktemp logger = getLogger("compare_results") @authenticate() def index(req): response = HttpResponse() response.loadTemplate("compare_results.html") return response @authenticate(ERROR) def upload(req): logger.debug("FILES: %s" % str(req.FILES)) if req.FILES.has_key('u1-result'): up_file = req.FILES['u1-result'] else: up_file = req.FILES['u2-result']
from math import floor, sqrt import sys import os from types import DictType from umitWeb.Http import HttpResponse, Http404, HttpError from umitWeb.Auth import authenticate, ERROR from umitWeb.WebLogger import getLogger from umitCore.NmapParser import NmapParser from umitCore.Diff import Diff, ParserDiff from umitCore.UmitConf import DiffColors from umitCore.DiffHtml import DiffHtml from tempfile import mktemp logger = getLogger("compare_results") @authenticate() def index(req): response = HttpResponse() response.loadTemplate("compare_results.html") return response @authenticate(ERROR) def upload(req): logger.debug("FILES: %s" % str(req.FILES)) if req.FILES.has_key('u1-result'): up_file = req.FILES['u1-result']; else: up_file = req.FILES['u2-result'];
class UmitRequestHandler(BaseHTTPRequestHandler): """Custom HTTP Request Handler for UmitWeb""" COOKIE_SESSION_NAME = "umitsessid" logger = getLogger("UmitRequestHandler") def __init__(self, request, client_address, server): self.server = server BaseHTTPRequestHandler.__init__(self, request, client_address, server) def do_GET(self): """Processor for HTTP GET command. A shortcut for process_request().""" self._process_request() def do_POST(self): """Processor for HTTP POST command. A shortcut for process_request()""" self._process_request() def send_redirect(self, path): self.send_response(303) response = "Location: %s\n" % path self.wfile.write(response) def _process_request(self): """Process the request and writes the response back to the client. If a HttpError occurs, the response is sent as a ``HTTPError``. """ try: request = HttpRequest(self) if "." not in request.path.rsplit("/", 1)[-1] and \ not request.path.endswith("/"): redirect_page = "%s/" % request.get_path() if request.querystring: redirect_page += "?%s" % request.querystring self.send_redirect(redirect_page) else: resolver = URLResolver() self.session_start(request) response = resolver.resolve(request) if response.__class__ is not HttpResponse and not \ issubclass(response.__class__, HttpResponse): raise HttpError(500, "Expected HttpResponse, got %s" % \ response.__class__.__name__) for f in request.FILES.items(): try: os.unlink(f[1]['temp_name']) except: pass if request.session.modified: request.session.save() self.send_response(response.code) self.logger.debug("Response code: %s" % str(response.code)) for header in response.headers.keys(): self.send_header(header, response.headers[header]) if not request.session.destroyed: request.COOKIES[self.COOKIE_SESSION_NAME] = \ request.session.get_sessid() request.COOKIES[self.COOKIE_SESSION_NAME]['path'] = "/" self.wfile.write(str(request.COOKIES) + '\n') self.end_headers() self.wfile.write(response.data) except HttpError, e: self.logger.error("Status code: %s - Message: %s", str(e.error_code), e.message) self.send_error(e.error_code, e.message) except Exception, e: print_exc() error = StringIO(0) self.send_error(500, str(e)) self.wfile.write("<h2>Exception Details:</h2><pre>") print_exc(file=error) error.flush() error.seek(0) errMSG = error.read() self.logger.error(errMSG) self.wfile.write(errMSG) self.wfile.write("</pre>")
# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from umitWeb.Http import HttpResponse, HttpResponseRedirect from umitWeb.Auth import html_auth, ERROR from umitWeb.Security import Context from umitWeb.WebLogger import getLogger logger = getLogger("html.main") def index(req): response = HttpResponse() response.loadTemplate("html/index.html") return response @html_auth() def main(req): response = HttpResponse() response.loadTemplate("html/main.html") return response
class HttpRequest(object): """A class to encapsulate the elements of a HTTP Request. """ logger = getLogger("HttpRequest") user = property(lambda self: self.session.user) def __init__(self, requestHandler): self.requestHandler = requestHandler self.headers = self.requestHandler.headers self.querystring = "" self.method = self.requestHandler.command if "?" in self.requestHandler.path: self.path, self.querystring = self.requestHandler.path.split("?") else: self.path = self.requestHandler.path self.GET = {} self.POST = {} self.REQUEST = {} self.FILES = {} self.COOKIES = {} if self.querystring: for arg in self.querystring.split("&"): if "=" in arg: key, value = arg.split("=", 1) self.GET[unquote(key)] = unquote(value) else: self.GET[unquote(arg)] = "" if self.requestHandler.command == "POST": length = int(self.headers.get('content-length', 0)) pdata = self.requestHandler.rfile.read(length) if pdata: if "multipart/form-data" not in self.headers.get( 'content-type', 'x-www-urlencoded'): self.logger.debug("Simple Form! Encoding: %s" % str(self.headers)) if "+" in pdata: unquote_func = unquote_plus else: unquote_func = unquote for arg in pdata.split("&"): key, value = arg.split("=", 1) self.POST[unquote_func(key)] = unquote_func(value) else: #multipart/form-data form self.logger.debug("Multipart form!") boundary = re.findall( r".*;[\s][Bb][Oo][Uu][Nn][Dd][Aa][Rr][Yy]=([^;]*).*", self.headers['content-type']) if boundary: boundary = boundary[0] form_elements = pdata.split("--%s" % boundary)[1:-1] for element in form_elements: header, data = element.split("\r\n", 2)[1:] #self.logger.debug("Form-header: %s" % header) #self.logger.debug("Form-data: %s" % data) match_file = re.search( r"[\s]?filename=[\"]?(?P<filename>[^;^$^\"]+)[\"]?", header) match_text = re.search( r"[\s;]?name=[\"]?(?P<name>[^;^$^\"]+)[\"]?", header) #self.logger.debug("groupdict (file): %s" % str(match_file.groupdict())) #self.logger.debug("groupdict (text): %s" % str(match_text.groupdict())) if match_file: #Type: File content_type, data = data.split("\r\n", 1) data = data[2: -2] # Delete initial and final '\r\n' #self.logger.debug("Data: " + str(data)) content_type = content_type[len("content-type:") - 1:].strip() temp_name = mktemp() temp_file = open(temp_name, "wb", 1) temp_file.write(data) temp_file.flush() temp_file.close() self.FILES[match_text.groupdict()['name']] = { "content_type": content_type, "name": match_file.groupdict()['filename'], "temp_name": temp_name, "size": len(data), "temp_file": open(temp_name, "rb", 0) } self.POST[match_text.groupdict( )['name']] = match_file.groupdict()['filename'] else: #Type: Plain text self.POST[match_text.groupdict() ['name']] = data[2:-2] self.logger.debug("FILES: %s" % str(self.FILES)) else: print "No pdata!" self.COOKIES = SimpleCookie(self.headers.get("cookie", "")) self.REQUEST.update(self.GET) self.REQUEST.update(self.POST) if self.requestHandler.command == "POST": self.logger.debug("POST data: %s" % str(self.POST)) #self.logger.debug("POST path: %s" % str(self.get_path())) #if self.FILES: # for file in self.FILES.items(): # self.logger.debug("temp name: %s" % file[1]['temp_name']) #self.logger.debug("data: %s" % file[1]['temp_file'].read()) #file[1]['temp_file'].seek(0) def get_rfile(self, rfile, length=16 * 1024, size=0): if not size: return r = "" while size > 0: buf = rfile.read(min(length, size)) if not buf: break r += buf size -= len(buf) return r def get_path(self): """Return the path part of a request """ return self.path def session_destroy(self): """Destroy the current session. """ del self.COOKIES['umitsessid'] self.session._session.delete()
# # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from umitWeb.Http import HttpResponse, HttpResponseRedirect from umitWeb.Auth import html_auth, ERROR from umitWeb.Security import Context from umitWeb.WebLogger import getLogger logger = getLogger("html.main") def index(req): response = HttpResponse() response.loadTemplate("html/index.html") return response @html_auth() def main(req): response = HttpResponse() response.loadTemplate("html/main.html") return response def login(req): logger.debug("aeeeeeeeee") response = HttpResponse()
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from os.path import join, abspath, dirname, exists, pardir import sys from types import DictionaryType, StringType, ListType from math import floor, sqrt from umitWeb.WebConf import JsOutputHighlight from umitWeb.Http import HttpResponse, Http404, HttpResponseRedirect from umitWeb.WebLogger import getLogger from umitWeb.Auth import authenticate, ERROR from umitWeb.WebPaths import WPath as Path from umitWeb.Security import Context import mimetypes logger = getLogger("main") @authenticate() def index(req): response = HttpResponse() response.loadTemplate("index.html") return response @authenticate(ERROR) def output_highlight(req): response = HttpResponse() response['Content-type'] = "text/javascript; charset=utf-8" highlight = JsOutputHighlight() attrDic = {}
# This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA from umitWeb.Http import HttpResponseRedirect, Http403 from umitWeb.WebLogger import getLogger REDIRECT = 0 ERROR = 1 logger = getLogger(__name__) # decorator def authenticate(destination=None, redirect_page=None): """``authenticate`` is a decorator for each view that needs authentication. Parameters: * ``destination`` -- the argument that determines if the page will be redirected to another location (0), or a forbidden page (error 403) will be displayed (1). * ``redirect_page`` -- the page that will be followed by if the user is not authenticated. """ destination = destination or REDIRECT redirect_page = redirect_page or "/login/"
class SecurityConfHandler(ContentHandler): logger = getLogger("ContentHandler") _in_users = False _in_roles = False _in_permissions = False _in_constraint = False _in_permission = False _in_role = False _in_user = False _in_description = False _in_name = False _in_password = False def __init__(self, context): self.context = context def _add_permission(self, attrs): self.context.add_permission(attrs.get("id"), attrs.get("type", "allow")) def _add_constraint_to_permission(self, attrs): p = self.context.permissions[-1].add_constraint(attrs.get("type", "command")) def _add_role(self, id): self.context.roles.append(Role(id)) def _add_permission_to_role(self, id): perm = self.context.get_permission(id) if perm: self.context.roles[-1].permissions.append(perm) else: raise ElementNotFound() def _add_user(self, login, superuser): self.context.users.append(User(login, superuser=superuser)) def _add_role_to_user(self, id): role = self.context.get_role(id) if role: self.context.users[-1].roles.append(role) else: raise ElementNotFound() def startElement(self, name, attrs): if name == "permissions" and not self._in_roles: self._in_permissions = True elif name == "permission" and self._in_permissions: self._in_permission = True self._add_permission(attrs) elif name == "permission" and self._in_role: self._add_permission_to_role(attrs.get("ref")) elif name == "constraint": self._in_constraint = True self._add_constraint_to_permission(attrs) elif name == "roles" and not self._in_users: self._in_roles = True elif name == "role" and self._in_roles: self._add_role(attrs.get("id")) self._in_role = True elif name == "role" and self._in_user: self._add_role_to_user(attrs.get("ref")) elif name == "description": self._in_description = True elif name == "users": self._in_users = True elif name == "user" and self._in_users: self._in_user = True self._add_user(attrs.get("login"), attrs.get("superuser", "no")) elif name == "name" and self._in_user: self._in_name = True elif name == "password" and self._in_user: self._in_password = True def characters(self, ch): if self._in_constraint: self.context.permissions[-1].constraints[-1].content += ch elif self._in_description and self._in_role: self.context.roles[-1].description += ch elif self._in_description and self._in_permission: self.context.permissions[-1].description += ch elif self._in_name and self._in_user: self.context.users[-1].name += ch elif self._in_password and self._in_user: self.context.users[-1].password += ch def endElement(self, name): if name == "constraint": self._in_constraint = False elif name == "permission" and self._in_permissions: self._in_permission = False elif name == "permissions" and not self._in_roles: self._in_permissions = False elif name == "roles" and not self._in_users: self._in_roles = False elif name == "role" and self._in_roles: self._in_role = False elif name == "description": self._in_description = False elif name == "users": self._in_users = False elif name == "user" and self._in_users: self._in_user = False elif name == "name" and self._in_user: self._in_name = False elif name == "password" and self._in_user: self._in_password = False