Exemple #1
0
    def getChild(self, path, request):

        # don't expose the file list under root dir
        # for security consideration
        if path == b'':
            return ForbiddenResource()

        uuid = path.decode()
        trade = Trade()
        trade = self.proxy_db.query_file_uuid(uuid)
        if trade:
            file_name = trade.file_name
            file_path = os.path.join(server_root, file_name)
            return File(file_path)

        return ForbiddenResource()
Exemple #2
0
    def register_ip(self, zone, ip):
        """
        Actually register a name for a given IP.

        @returns: A resource or a byte-string depending on the action being
          successful or not.
          Possible HTTP codes are:
            200 (OK)
            400 (Bad request --> no such zone)
            403 (Forbidden --> out of subnet)
            507 (Insufficient storage --> somehow the name space is kinda full)
        """
        if zone not in self.data:
            return ErrorPage(
                400, "Bad Request", "No such zone, consider hosting your own!"
            )
        try:
            return self.get_assign_name(zone, ip) + b"." + zone + b"\n"
        except ValueError:
            return ForbiddenResource("Your IP is not allowed to use this resource.")
        except LookupError:
            return ErrorPage(
                507,
                "Insufficient Storage",
                "It looks like this zone is getting full. Consider hosting your own!",
            )
        except Exception as ex:
            log.error("Error registering {zone} | {ip}", zone=zone, ip=ip)
            log.failure(ex)
            return ErrorPage(500, "Internal Error", "Something odd happened!")
Exemple #3
0
    def requestAvatar(self, avatarId, mind, *interfaces):
        if IResource in interfaces:
            if avatarId.shortNames[0] in self.allowedAvatarIds:
                return (IResource, self.root, lambda: None)
            else:
                return (IResource, ForbiddenResource(), lambda: None)

        raise NotImplementedError()
Exemple #4
0
    def render_GET(self, request):
        path = request.path.decode().strip('/')

        # don't expose the file list under root dir
        # for security consideration
        if path == '':
            return ForbiddenResource().render(request)

        file_path = os.path.join(self.server_root, path)
        return File(file_path).render(request)
Exemple #5
0
 def auth_func(self, request, *args, **kwargs):
     token = "invalid"
     if "token" in request.args:
         token = request.args["token"]
     elif request.requestHeaders.hasHeader("X-Request-Token"):
         token = request.requestHeaders.getRawHeaders(
             "X-Request-Token", [None])[0]
     if token == HoneyProxy.getApiAuthToken():
         return f(self, request, *args, **kwargs)
     else:
         return ForbiddenResource(
             message="Invalid response Token").render(request)
Exemple #6
0
def _render_file(file, request):
    """
    Begin sending the contents of this L{File} (or a subset of the
    contents, based on the 'range' header) to the given request.
    """
    file.restat(False)

    if file.type is None:
        file.type, file.encoding = getTypeAndEncoding(file.basename(),
                                                      file.contentTypes,
                                                      file.contentEncodings,
                                                      file.defaultType)

    if not file.exists():
        return file.childNotFound.render(request)

    if file.isdir():
        return file.redirect(request)

    request.setHeader('accept-ranges', 'bytes')

    try:
        fileForReading = file.openForReading()
    except IOError as e:
        import errno

        if e[0] == errno.EACCES:
            return ForbiddenResource().render(request)
        else:
            raise

    #if request.setLastModified(file.getmtime()) is CACHED:
    #    return ''

    producer = file.makeProducer(request, fileForReading)

    if request.method == 'HEAD':
        return ''

    producer.start()
    # and make sure the connection doesn't get closed
    return NOT_DONE_YET
    def getChild(self, path, request):

        # get username from headers
        # - this should be set on authenticated web sessions
        try:
            user = request.getHeader("x-forwarded-user")
        except:
            user = None

        # check if the request comes from the right user (note: can be forged)
        if user == getpass.getuser():

            # get ood token cookie
            # - cookie name depends on the ood interactive session id ($PWD)
            ood_session_id = os.path.basename(os.getcwd())
            try:
                cookie = request.getCookie(
                    b'_ood_token_' +
                    ood_session_id.encode('utf-8')).decode('utf-8')
            except:
                cookie = None

            # get token from environment
            # - $_ood_token_<session_id> is set in template/before.sh script
            try:
                ood_token = os.environ.get("_ood_token_" +
                                           ood_session_id.replace("-", "_"))
            except:
                ood_token = None

            #return proxy.ReverseProxyResource(self.host, self.port, ('/' + path.decode('utf-8')).encode('utf-8'))

            # check that cookie matches the local token
            if cookie == ood_token and cookie is not None:
                return proxy.ReverseProxyResource(
                    self.host, self.port,
                    ('/' + path.decode('utf-8')).encode('utf-8'))

        request.setResponseCode(403)
        return ForbiddenResource()
Exemple #8
0
    def getChild(self, name, request):

        if name == "home":
            templateParser = TemplateFile('hamjab/resources/home/')
            templateParser.addRenderer(
                'index', MainPageRenderer(self.deviceServerFactory))
            return templateParser

        elif name == "toggleStatus":
            CommandServer.isDisabled = not CommandServer.isDisabled
            return ErrorPage(200, "Status", "Toggled the site status")

        elif CommandServer.isDisabled:
            return ForbiddenResource("The site is disabled")

        elif name == "listDevices":
            return DeviceListResource(self.deviceServerFactory)

        elif name == "macro":
            result = ArgUtils._check_arg("macroName", request.args)
            if result:
                return result

            (macroName, ) = ArgUtils._get_args(request, ("macroName", ))

            if macroName not in self.deviceServerFactory.macros:
                return NoResource()

            return MacroResource(self.deviceServerFactory, macroName)

        elif self.deviceServerFactory.isDeviceRegistered(
                name) and '/' in request.path:

            device = self.deviceServerFactory.getDevice(name)

            return DeviceResource(device)

        return NoResource()
Exemple #9
0
    def renderHTTP(self, ctx):
        """You know what you doing."""
        self.fp.restat()

        if self.type is None:
            self.type, self.encoding = getTypeAndEncoding(
                self.fp.basename(), self.contentTypes, self.contentEncodings,
                self.defaultType)

        if not self.fp.exists():
            return rend.FourOhFour()

        request = inevow.IRequest(ctx)

        if self.fp.isdir():
            return self.redirect(request)

        # fsize is the full file size
        # size is the length of the part actually transmitted
        fsize = size = self.getFileSize()

        request.setHeader('accept-ranges', 'bytes')

        if self.type:
            request.setHeader('content-type', self.type)
        if self.encoding:
            request.setHeader('content-encoding', self.encoding)

        try:
            f = self.openForReading()
        except IOError, e:
            import errno
            if e[0] == errno.EACCES:
                return ForbiddenResource().render(request)
            else:
                raise
Exemple #10
0
 def directoryListing(self):
     return ForbiddenResource(message=b'Nope.')
Exemple #11
0
 def directoryListing(self):
     return ForbiddenResource()
Exemple #12
0
 def render_GET(self, request):
     return ForbiddenResource()
Exemple #13
0
    def getChild(self, path, request):
        """Find the appropriate child resource depending on request type

        Possible URLs:
        - /foo/bar/info/refs -> info refs (file / SmartHTTP hybrid)
        - /foo/bar/git-upload-pack -> SmartHTTP RPC
        - /foo/bar/git-receive-pack -> SmartHTTP RPC
        - /foo/bar/HEAD -> file (dumb http)
        - /foo/bar/objects/* -> file (dumb http)
        """
        path = request.path  # alternatively use path + request.postpath
        pathparts = path.split('/')
        writerequired = False
        script_name = '/'
        new_path = path
        resource = NoResource()

        # Path lookup / translation
        path_info = self.git_configuration.path_lookup(path,
                                                       protocol_hint='http')
        if path_info is None:
            log.msg('User %s tried to access %s '
                    'but the lookup failed' % (self.username, path))
            return resource

        log.msg('Lookup of %s gave %r' % (path, path_info))

        if (path_info['repository_fs_path'] is None
                and path_info['repository_base_fs_path'] is None):
            log.msg('Neither a repository base nor a repository were returned')
            return resource

        # split script_name / new_path according to path info
        if path_info['repository_base_url_path'] is not None:
            script_name = '/'
            script_name += path_info['repository_base_url_path'].strip('/')
            new_path = path[len(script_name.rstrip('/')):]

        # since pretty much everything needs read access, check for it now
        if not self.authnz.can_read(self.username, path_info):
            if self.username is None:
                return UnauthorizedResource(self.credentialFactories)
            else:
                return ForbiddenResource("You don't have read access")

        # Smart HTTP requests
        # /info/refs
        if (len(pathparts) >= 2 and pathparts[-2] == 'info'
                and pathparts[-1] == 'refs'):
            writerequired = ('service' in request.args and
                             request.args['service'][0] == 'git-receive-pack')
            resource = InfoRefs(path_info['repository_fs_path'])

        # /git-upload-pack (client pull)
        elif len(pathparts) >= 1 and pathparts[-1] == 'git-upload-pack':
            cmd = 'git'
            args = [
                os.path.basename(cmd), 'upload-pack', '--stateless-rpc',
                path_info['repository_fs_path']
            ]
            resource = GitCommand(cmd, args)
            request.setHeader('Content-Type',
                              'application/x-git-upload-pack-result')

        # /git-receive-pack (client push)
        elif len(pathparts) >= 1 and pathparts[-1] == 'git-receive-pack':
            writerequired = True
            cmd = 'git'
            args = [
                os.path.basename(cmd), 'receive-pack', '--stateless-rpc',
                path_info['repository_fs_path']
            ]
            resource = GitCommand(cmd, args)
            request.setHeader('Content-Type',
                              'application/x-git-receive-pack-result')

        # static files as specified in file_headers or fallback webfrontend
        else:
            # determine the headers for this file
            filename, headers = None, None
            for matcher, get_headers in file_headers.items():
                m = matcher.match(path)
                if m:
                    filename = m.group(1)
                    headers = get_headers()
                    break

            if filename is not None:
                for key, val in headers.items():
                    request.setHeader(key, val)

                log.msg(
                    "Returning file %s" %
                    os.path.join(path_info['repository_fs_path'], filename))
                resource = File(
                    os.path.join(path_info['repository_fs_path'], filename),
                    headers['Content-Type'])
                resource.isLeaf = True  # static file -> it is a leaf

            else:
                # No match -> fallback to git viewer
                if script_name is not None:
                    # patch pre/post path of request according to
                    # script_name and path
                    request.prepath = script_name.strip('/').split('/')
                    if request.prepath == ['']:
                        request.prepath = []
                    request.postpath = new_path.lstrip('/').split('/')

                    log.msg("pre and post: %r %r" %
                            (request.prepath, request.postpath))

                # If the resource has a withEnviron function, it's
                # probably our own flavour of WSGIResource that
                # supports passing further args for the environ
                if hasattr(self.git_viewer, "withEnviron"):
                    # set wsgirouting args
                    routing_args = {
                        'repository_path': path_info['repository_fs_path'],
                        'repository_base': path_info['repository_base_fs_path']
                    }
                    if 'repository_clone_urls' in path_info:
                        routing_args['repository_clone_urls'] = path_info[
                            'repository_clone_urls']
                    resource = self.git_viewer.withEnviron(
                        {'wsgiorg.routing_args': ([], routing_args)})
                else:
                    resource = self.git_viewer

        # before returning the resource, check if write access is required
        # and enforce privileges accordingly
        # anonymous (username = None) will never be granted write access
        if writerequired and (
                self.username is None
                or not self.authnz.can_write(self.username, path_info)):
            if self.username is None:
                return UnauthorizedResource(self.credentialFactories)
            else:
                return ForbiddenResource("You don't have write access")

        return resource
Exemple #14
0
    def renderHTTP(self, ctx):
        """You know what you doing."""
        self.fp.restat()

        if self.type is None:
            self.type, self.encoding = getTypeAndEncoding(
                self.fp.basename(), self.contentTypes, self.contentEncodings,
                self.defaultType)

        if not self.fp.exists():
            return rend.FourOhFour()

        request = inevow.IRequest(ctx)

        if self.fp.isdir():
            return self.redirect(request)

        # fsize is the full file size
        # size is the length of the part actually transmitted
        fsize = size = self.getFileSize()

        request.setHeader('accept-ranges', 'bytes')

        if self.type:
            request.setHeader('content-type', self.type)
        if self.encoding:
            request.setHeader('content-encoding', self.encoding)

        try:
            f = self.openForReading()
        except IOError as e:
            import errno
            if e[0] == errno.EACCES:
                return ForbiddenResource().render(request)
            else:
                raise

        if request.setLastModified(
                self.fp.getModificationTime()) is http.CACHED:
            return ''

        try:
            range = request.getHeader('range')

            if range is not None:
                # This is a request for partial data...
                bytesrange = string.split(range, '=')
                assert bytesrange[0] == 'bytes',\
                       "Syntactically invalid http range header!"
                start, end = string.split(bytesrange[1], '-')
                if start:
                    f.seek(int(start))
                if end:
                    end = int(end)
                else:
                    end = fsize - 1
                request.setResponseCode(http.PARTIAL_CONTENT)
                request.setHeader(
                    'content-range',
                    "bytes %s-%s/%s" % (str(start), str(end), str(fsize)))
                #content-length should be the actual size of the stuff we're
                #sending, not the full size of the on-server entity.
                size = 1 + end - int(start)

            request.setHeader('content-length', str(size))
        except:
            traceback.print_exc(file=log.logfile)

        if request.method == 'HEAD':
            return ''

        # return data
        FileTransfer(f, size, request)
        # and make sure the connection doesn't get closed
        return request.deferred
Exemple #15
0
 def directoryListing(self):
     #Override to forbid directory listing
     return ForbiddenResource()