Esempio n. 1
0
def getHttpAuth(req):
    # special header to pass a session id through
    # instead of a real http authorization token
    if 'X-Session-Id' in req.headers:
        return req.headers['X-Session-Id']

    # pysid cookies are just as good as the session id - flex uses the browser
    # for authentication info and cookies are sent for free. (RBL-4276)
    if 'pysid' in req.cookies:
        return req.cookies['pysid']

    return webauth.getAuth(req)
Esempio n. 2
0
    def _getResponse(self):
        self.authToken = auth = getAuth(self.request)
        if auth is None:
            return self._requestAuth("Invalid authentication token")

        # Repository setup
        self.serverNameList = self.repServer.serverNameList
        cfg = conarycfg.ConaryConfiguration(readConfigFiles=False)
        cfg.repositoryMap = self.repServer.map
        for serverName in self.serverNameList:
            cfg.user.addServerGlob(serverName, auth[0], auth[1])
        self.repos = shimclient.ShimNetClient(
                server=self.repServer,
                protocol=self.request.scheme,
                port=self.request.server_port,
                authToken=auth,
                repMap=cfg.repositoryMap,
                userMap=cfg.user,
                )

        # Check if the request is sane
        methodName = self.request.path_info_peek() or 'main'
        method = None
        if methodName and methodName[0] != '_':
            method = getattr(self, methodName, None)
        if not method:
            raise exc.HTTPNotFound()
        self.methodName = methodName

        # Do authn/authz checks
        if auth[0] != 'anonymous':
            self.loggedIn = self.repServer.auth.checkPassword(auth)
            if not self.loggedIn:
                return self._requestAuth()
        else:
            self.loggedIn = False

        # Run the method
        self.hasWrite = self.repServer.auth.check(auth, write=True)
        self.isAdmin = self.repServer.auth.authCheck(auth, admin=True)
        params = self.request.params.mixed()
        try:
            result = method(auth=auth, **params)
        except (exc.HTTPForbidden, errors.InsufficientPermission):
            if self.loggedIn:
                raise exc.HTTPForbidden()
            else:
                return self._requestAuth()
        except WebError, err:
            result = self._write("error", error=str(err))
Esempio n. 3
0
    def _getResponse(self):
        self.authToken = auth = getAuth(self.request)
        if auth is None:
            return self._requestAuth("Invalid authentication token")

        # Repository setup
        self.serverNameList = self.repServer.serverNameList
        cfg = conarycfg.ConaryConfiguration(readConfigFiles=False)
        cfg.repositoryMap = self.repServer.map
        for serverName in self.serverNameList:
            cfg.user.addServerGlob(serverName, auth[0], auth[1])
        self.repos = shimclient.ShimNetClient(
            server=self.repServer,
            protocol=self.request.scheme,
            port=self.request.server_port,
            authToken=auth,
            repMap=cfg.repositoryMap,
            userMap=cfg.user,
        )

        # Check if the request is sane
        methodName = self.request.path_info_peek() or 'main'
        method = None
        if methodName and methodName[0] != '_':
            method = getattr(self, methodName, None)
        if not method:
            raise exc.HTTPNotFound()
        self.methodName = methodName

        # Do authn/authz checks
        if auth[0] != 'anonymous':
            self.loggedIn = self.repServer.auth.checkPassword(auth)
            if not self.loggedIn:
                return self._requestAuth()
        else:
            self.loggedIn = False

        # Run the method
        self.hasWrite = self.repServer.auth.check(auth, write=True)
        self.isAdmin = self.repServer.auth.authCheck(auth, admin=True)
        params = self.request.params.mixed()
        try:
            result = method(auth=auth, **params)
        except (exc.HTTPForbidden, errors.InsufficientPermission):
            if self.loggedIn:
                raise exc.HTTPForbidden()
            else:
                return self._requestAuth()
        except WebError, err:
            result = self._write("error", error=str(err))
Esempio n. 4
0
def post(port, isSecure, repos, req, authToken=None, repServer=None):
    if authToken is None:
        authToken = getAuth(req)
    if authToken is None:
        return apache.HTTP_BAD_REQUEST

    if authToken[0] != "anonymous" and not isSecure and repos.cfg.forceSSL:
        return apache.HTTP_FORBIDDEN

    if isSecure:
        protocol = "https"
    else:
        protocol = "http"

    extraInfo = None
    repos.log.reset()
    if req.headers_in['Content-Type'] == "text/xml":
        # handle XML-RPC requests
        encoding = req.headers_in.get('Content-Encoding', None)
        sio = util.BoundedStringIO()
        try:
            util.copyStream(req, sio)
        except IOError, e:
            # if we got a read timeout, marshal an exception back
            # to the client
            print >> sys.stderr, 'error reading from client: %s' % e
            method = 'unknown - client timeout'
            response = xmlshims.ResponseArgs.newException(
                'ClientTimeout', 'The server was not able to read the '
                'XML-RPC request sent by this client. '
                'This is sometimes caused by MTU problems '
                'on your network connection.  Using a '
                'smaller MTU may work around this '
                'problem.')
            headers = {}
            startTime = time.time()
        else:
            # otherwise, we've read the data, let's process it
            if encoding == 'deflate':
                sio.seek(0)
                try:
                    sio = util.decompressStream(sio)
                except zlib.error, error:
                    req.log_error("zlib inflate error in POST: %s" % error)
                    return apache.HTTP_BAD_REQUEST

            startTime = time.time()
            sio.seek(0)
            try:
                (params, method) = util.xmlrpcLoad(sio)
            except:
                req.log_error('error parsing XMLRPC request')
                return apache.HTTP_BAD_REQUEST
            repos.log(3, "decoding=%s" % method, authToken[0],
                      "%.3f" % (time.time() - startTime))
            # req.connection.local_addr[0] is the IP address the server
            # listens on, not the IP address of the accepted socket. Most of
            # the times it will be 0.0.0.0 which is not very useful. We're
            # using local_ip instead, and we grab just the port from
            # local_addr.
            localAddr = "%s:%s" % (req.connection.local_ip,
                                   req.connection.local_addr[1])

            remoteIp = req.connection.remote_ip
            # Get the IP address of the original request in the case
            # of a proxy, otherwise use the connection's remote_ip
            if 'X-Forwarded-For' in req.headers_in:
                # pick the right-most client, since that is
                # the one closest to us.  For example, if
                # we have "X-Forwarded-For: 1.2.3.4, 4.5.6.7"
                # we want to use 4.5.6.7
                clients = req.headers_in['X-Forwarded-For']
                remoteIp = clients.split(',')[-1].strip()
            try:
                request = xmlshims.RequestArgs.fromWire(params)
            except (TypeError, ValueError, IndexError):
                req.log_error('error parsing XMLRPC arguments')
                return apache.HTTP_BAD_REQUEST
            try:
                response, extraInfo = repos.callWrapper(
                    protocol=protocol,
                    port=port,
                    methodname=method,
                    authToken=authToken,
                    request=request,
                    remoteIp=remoteIp,
                    rawUrl=req.unparsed_uri,
                    localAddr=localAddr,
                    protocolString=req.protocol,
                    headers=req.headers_in,
                    isSecure=isSecure,
                )
            except errors.InsufficientPermission:
                return apache.HTTP_FORBIDDEN
Esempio n. 5
0
def get(port,
        isSecure,
        repos,
        req,
        restHandler=None,
        authToken=None,
        repServer=None):
    uri = req.uri
    if uri.endswith('/'):
        uri = uri[:-1]
    cmd = os.path.basename(uri)

    if authToken is None:
        authToken = getAuth(req)

    if authToken is None:
        return apache.HTTP_BAD_REQUEST

    if authToken[0] != "anonymous" and not isSecure and repos.cfg.forceSSL:
        return apache.HTTP_FORBIDDEN

    if restHandler and uri.startswith(restHandler.prefix):
        return restHandler.handle(req, req.unparsed_uri)
    elif cmd == "changeset":
        if not req.args:
            # the client asked for a changeset, but there is no
            # ?tmpXXXXXX.cf after /conary/changeset (CNY-1142)
            return apache.HTTP_BAD_REQUEST
        if '/' in req.args:
            return apache.HTTP_FORBIDDEN

        localName = repos.tmpPath + "/" + req.args + "-out"

        if localName.endswith(".cf-out"):
            try:
                f = open(localName, "r")
            except IOError:
                return apache.HTTP_NOT_FOUND

            os.unlink(localName)

            items = []
            totalSize = 0
            for l in f.readlines():
                (path, size, isChangeset, preserveFile) = l.split()
                size = int(size)
                isChangeset = int(isChangeset)
                preserveFile = int(preserveFile)
                totalSize += size
                items.append((path, size, isChangeset, preserveFile))
            f.close()
            del f
        else:
            try:
                size = os.stat(localName).st_size
            except OSError:
                return apache.HTTP_NOT_FOUND
            items = [(localName, size, 0, 0)]
            totalSize = size

        # TODO: refactor to use proxy.ChangesetFileReader
        readNestedFile = proxy.ChangesetFileReader.readNestedFile
        req.content_type = "application/x-conary-change-set"
        req.set_content_length(totalSize)
        for (path, size, isChangeset, preserveFile) in items:
            if isChangeset:
                cs = FileContainer(util.ExtendedFile(path, buffering=False))
                try:
                    for data in cs.dumpIter(readNestedFile,
                                            args=(repos.getContentsStore(), )):
                        req.write(data)
                except IOError, err:
                    log.error("IOError dumping changeset: %s" % err)
                    return apache.HTTP_BAD_REQUEST
                del cs
            else:
                sendfile(req, size, path)

            if not preserveFile:
                os.unlink(path)

        return apache.OK
Esempio n. 6
0
def post(port, isSecure, repos, req, authToken=None, repServer=None):
    if authToken is None:
        authToken = getAuth(req)
    if authToken is None:
        return apache.HTTP_BAD_REQUEST

    if authToken[0] != "anonymous" and not isSecure and repos.cfg.forceSSL:
        return apache.HTTP_FORBIDDEN

    if isSecure:
        protocol = "https"
    else:
        protocol = "http"

    extraInfo = None
    repos.log.reset()
    if req.headers_in['Content-Type'] == "text/xml":
        # handle XML-RPC requests
        encoding = req.headers_in.get('Content-Encoding', None)
        sio = util.BoundedStringIO()
        try:
            util.copyStream(req, sio)
        except IOError, e:
            # if we got a read timeout, marshal an exception back
            # to the client
            print >> sys.stderr, 'error reading from client: %s' %e
            method = 'unknown - client timeout'
            response = xmlshims.ResponseArgs.newException('ClientTimeout',
                                    'The server was not able to read the '
                                    'XML-RPC request sent by this client. '
                                    'This is sometimes caused by MTU problems '
                                    'on your network connection.  Using a '
                                    'smaller MTU may work around this '
                                    'problem.')
            headers = {}
            startTime = time.time()
        else:
            # otherwise, we've read the data, let's process it
            if encoding == 'deflate':
                sio.seek(0)
                try:
                    sio = util.decompressStream(sio)
                except zlib.error, error:
                    req.log_error("zlib inflate error in POST: %s" % error)
                    return apache.HTTP_BAD_REQUEST

            startTime = time.time()
            sio.seek(0)
            try:
                (params, method) = util.xmlrpcLoad(sio)
            except:
                req.log_error('error parsing XMLRPC request')
                return apache.HTTP_BAD_REQUEST
            repos.log(3, "decoding=%s" % method, authToken[0],
                      "%.3f" % (time.time()-startTime))
            # req.connection.local_addr[0] is the IP address the server
            # listens on, not the IP address of the accepted socket. Most of
            # the times it will be 0.0.0.0 which is not very useful. We're
            # using local_ip instead, and we grab just the port from
            # local_addr.
            localAddr = "%s:%s" % (req.connection.local_ip,
                                   req.connection.local_addr[1])

            remoteIp = req.connection.remote_ip
            # Get the IP address of the original request in the case
            # of a proxy, otherwise use the connection's remote_ip
            if 'X-Forwarded-For' in req.headers_in:
                # pick the right-most client, since that is
                # the one closest to us.  For example, if
                # we have "X-Forwarded-For: 1.2.3.4, 4.5.6.7"
                # we want to use 4.5.6.7
                clients = req.headers_in['X-Forwarded-For']
                remoteIp = clients.split(',')[-1].strip()
            try:
                request = xmlshims.RequestArgs.fromWire(params)
            except (TypeError, ValueError, IndexError):
                req.log_error('error parsing XMLRPC arguments')
                return apache.HTTP_BAD_REQUEST
            try:
                response, extraInfo = repos.callWrapper(
                        protocol=protocol,
                        port=port,
                        methodname=method,
                        authToken=authToken,
                        request=request,
                        remoteIp=remoteIp,
                        rawUrl=req.unparsed_uri,
                        localAddr=localAddr,
                        protocolString=req.protocol,
                        headers=req.headers_in,
                        isSecure=isSecure,
                        )
            except errors.InsufficientPermission:
                return apache.HTTP_FORBIDDEN
Esempio n. 7
0
def get(port, isSecure, repos, req, restHandler=None, authToken=None, repServer=None):
    uri = req.uri
    if uri.endswith('/'):
        uri = uri[:-1]
    cmd = os.path.basename(uri)

    if authToken is None:
        authToken = getAuth(req)

    if authToken is None:
        return apache.HTTP_BAD_REQUEST

    if authToken[0] != "anonymous" and not isSecure and repos.cfg.forceSSL:
        return apache.HTTP_FORBIDDEN

    if restHandler and uri.startswith(restHandler.prefix):
        return restHandler.handle(req, req.unparsed_uri)
    elif cmd == "changeset":
        if not req.args:
            # the client asked for a changeset, but there is no
            # ?tmpXXXXXX.cf after /conary/changeset (CNY-1142)
            return apache.HTTP_BAD_REQUEST
        if '/' in req.args:
            return apache.HTTP_FORBIDDEN

        localName = repos.tmpPath + "/" + req.args + "-out"

        if localName.endswith(".cf-out"):
            try:
                f = open(localName, "r")
            except IOError:
                return apache.HTTP_NOT_FOUND

            os.unlink(localName)

            items = []
            totalSize = 0
            for l in f.readlines():
                (path, size, isChangeset, preserveFile) = l.split()
                size = int(size)
                isChangeset = int(isChangeset)
                preserveFile = int(preserveFile)
                totalSize += size
                items.append((path, size, isChangeset, preserveFile))
            f.close()
            del f
        else:
            try:
                size = os.stat(localName).st_size;
            except OSError:
                return apache.HTTP_NOT_FOUND
            items = [ (localName, size, 0, 0) ]
            totalSize = size

        # TODO: refactor to use proxy.ChangesetFileReader
        readNestedFile = proxy.ChangesetFileReader.readNestedFile
        req.content_type = "application/x-conary-change-set"
        req.set_content_length(totalSize)
        for (path, size, isChangeset, preserveFile) in items:
            if isChangeset:
                cs = FileContainer(util.ExtendedFile(path, buffering=False))
                try:
                    for data in cs.dumpIter(readNestedFile,
                            args=(repos.getContentsStore(),)):
                        req.write(data)
                except IOError, err:
                    log.error("IOError dumping changeset: %s" % err)
                    return apache.HTTP_BAD_REQUEST
                del cs
            else:
                sendfile(req, size, path)

            if not preserveFile:
                os.unlink(path)

        return apache.OK