Esempio n. 1
0
    def handlePLAINTEXTServer(self, header):
        """
        Parse a complete HTTP-like Foolscap negotiation request and begin proxying
        to a destination selected based on the extract TubID.
        """
        # the client sends us a GET message
        lines = header.split("\r\n")
        if not lines[0].startswith("GET "):
            raise BananaError("not right")
        command, url, version = lines[0].split()
        if not url.startswith("/id/"):
            # probably a web browser
            raise BananaError("not right")
        targetTubID = url[4:]

        Message.log(event_type=u"handlePLAINTEXTServer", tub_id=targetTubID)

        if targetTubID == "":
            # they're asking for an old UnauthenticatedTub. Refuse.
            raise NegotiationError("secure Tubs require encryption")
        if isSubstring("Upgrade: TLS/1.0\r\n", header):
            wantEncrypted = True
        else:
            wantEncrypted = False

        Message.log(event_type=u"handlePLAINTEXTServer",
                    want_encrypted=wantEncrypted)

        self._handleTubRequest(header, targetTubID)
Esempio n. 2
0
 def checkToken(self, typebyte, size):
     if self.classname is None:
         if typebyte not in (tokens.STRING, tokens.VOCAB):
             raise BananaError("InstanceUnslicer classname must be string")
     elif self.attrname is None:
         if typebyte not in (tokens.STRING, tokens.VOCAB):
             raise BananaError("InstanceUnslicer keys must be STRINGs")
Esempio n. 3
0
 def checkToken(self, typebyte, size):
     if self.state == 0:
         if typebyte not in (tokens.STRING, tokens.VOCAB):
             raise BananaError("MethodUnslicer methodname must be a string")
     elif self.state == 1:
         if typebyte != tokens.OPEN:
             raise BananaError("MethodUnslicer instance must be OPEN")
     elif self.state == 2:
         if typebyte != tokens.OPEN:
             raise BananaError("MethodUnslicer class must be an OPEN")
Esempio n. 4
0
 def checkToken(self, typebyte, size):
     if self.maxKeys is not None and len(self.d) >= self.maxKeys:
         raise Violation("the table is full")
     if self.key is None:
         if typebyte != INT:
             raise BananaError("VocabUnslicer only accepts INT keys")
     else:
         if typebyte != STRING:
             raise BananaError("VocabUnslicer only accepts STRING values")
         if self.valueConstraint:
             self.valueConstraint.checkToken(typebyte, size)
Esempio n. 5
0
 def checkToken(self, typebyte, size):
     if self.index is None:
         if typebyte != INT:
             raise BananaError("Vocab key must be an INT")
     elif self.value is None:
         if typebyte != STRING:
             raise BananaError("Vocab value must be a STRING")
         if self.valueConstraint:
             self.valueConstraint.checkToken(typebyte, size)
     else:
         raise Violation("add-vocab only accepts two values")
Esempio n. 6
0
 def doOpen(self, opentype):
     # check the opentype
     if self.state == 1:
         if opentype[0] not in ("instance", "none"):
             raise BananaError("MethodUnslicer instance must be " +
                               "instance or None")
     elif self.state == 2:
         if opentype[0] != "class":
             raise BananaError("MethodUnslicer class must be a class")
     unslicer = self.open(opentype)
     # TODO: apply constraint
     return unslicer
Esempio n. 7
0
    def checkToken(self, typebyte, size):
        if self.maxKeys is not None and len(self.d) >= self.maxKeys:
            raise Violation('the table is full')

        if self.key is None:
            if typebyte != INT:
                raise BananaError('VocabUnslicer only accepts INT keys')
        else:
            if typebyte != BYTES:
                raise BananaError('VocabUnslicer only accepts BYTES values')

            if self.valueConstraint:
                self.valueConstraint.checkToken(typebyte, size)
Esempio n. 8
0
 def receiveKey(self, key):
     # I don't think it is legal (in python) to use an incomplete object
     # as a dictionary key, because you must have all the contents to
     # hash it. Someone could fake up a token stream to hit this case,
     # however: OPEN(dict), OPEN(tuple), OPEN(reference), 0, CLOSE, CLOSE,
     # "value", CLOSE
     if isinstance(key, Deferred):
         raise BananaError("incomplete object as dictionary key")
     try:
         if key in self.d:
             raise BananaError("duplicate key '%s'" % key)
     except TypeError:
         raise BananaError("unhashable key '%s'" % key)
     self.key = key
Esempio n. 9
0
 def openerCheckToken(self, typebyte, size, opentype):
     if typebyte == tokens.STRING:
         if len(opentype) == 0:
             if size > self.maxIndexLength:
                 why = "first opentype STRING token is too long, %d>%d" % \
                       (size, self.maxIndexLength)
                 raise Violation(why)
         if opentype == ("copyable", ):
             # TODO: this is silly, of course (should pre-compute maxlen)
             maxlen = reduce(max,
                             [len(cname) \
                              for cname in copyable.CopyableRegistry.keys()]
                             )
             if size > maxlen:
                 why = "copyable-classname token is too long, %d>%d" % \
                       (size, maxlen)
                 raise Violation(why)
     elif typebyte == tokens.VOCAB:
         return
     else:
         # TODO: hack for testing
         raise Violation("index token 0x%02x not STRING or VOCAB" % \
                           ord(typebyte))
         raise BananaError("index token 0x%02x not STRING or VOCAB" % \
                           ord(typebyte))
Esempio n. 10
0
    def _getReference(self, sturdyOrURL):
        if isinstance(sturdyOrURL, SturdyRef):
            sturdy = sturdyOrURL
        else:
            sturdy = SturdyRef(sturdyOrURL)
        # pb->pb: ok, requires crypto
        # pbu->pb: ok, requires crypto
        # pbu->pbu: ok
        # pb->pbu: ok, requires crypto
        if sturdy.encrypted and not crypto_available:
            e = BananaError("crypto for PB is not available, "
                            "we cannot handle encrypted PB-URLs like %s" %
                            sturdy.getURL())
            return defer.fail(e)

        if not self.running:
            # queue their request for service once the Tub actually starts
            log.msg(
                "Tub.getReference(%s) queued until Tub.startService called" %
                sturdy,
                facility="foolscap.tub")
            d = defer.Deferred()
            self._pending_getReferences.append((d, sturdy))
            return d

        name = sturdy.name
        d = self.getBrokerForTubRef(sturdy.getTubRef())
        d.addCallback(lambda b: b.getYourReferenceByName(name))
        return d
Esempio n. 11
0
    def brokerAttached(self, tubref, broker, isClient):
        assert self.running
        assert tubref

        if tubref in self.tubConnectors:
            # we initiated an outbound connection to this tubref
            if not isClient:
                # however, the connection we got was from an inbound
                # connection. The completed (inbound) connection wins, so
                # abandon the outbound TubConnector
                self.tubConnectors[tubref].shutdown()

            # we don't need the TubConnector any more
            del self.tubConnectors[tubref]

        if tubref in self.brokers:
            # this shouldn't happen: acceptDecision is supposed to drop any
            # existing old connection first.
            self.log("ERROR: unexpected duplicate connection from %s" % tubref)
            raise BananaError("unexpected duplicate connection")
        self.brokers[tubref] = broker

        # now inform everyone who's been waiting on it
        if tubref in self.waitingForBrokers:
            for d in self.waitingForBrokers[tubref]:
                eventual.eventually(d.callback, broker)
            del self.waitingForBrokers[tubref]
Esempio n. 12
0
    def receiveChild(self, obj, ready_deferred=None):
        assert not isinstance(obj, Deferred)
        assert ready_deferred is None

        if self.value is not None:
            raise BananaError('already received a string')

        self.value = decimal.Decimal(obj)
Esempio n. 13
0
 def receiveChild(self, obj, ready_deferred=None):
     assert not isinstance(obj, Deferred)
     assert ready_deferred is None
     if self.finished:
         raise BananaError("FunctionUnslicer only accepts one string")
     self.finished = True
     # TODO: taste here!
     self.func = reflect.namedObject(obj)
Esempio n. 14
0
 def receiveChild(self, obj, ready_deferred=None):
     assert not isinstance(obj, Deferred)
     assert ready_deferred is None
     if self.finished:
         raise BananaError("ModuleUnslicer only accepts one string")
     self.finished = True
     # TODO: taste here!
     mod = __import__(obj, {}, {}, "x")
     self.mod = mod
Esempio n. 15
0
 def receiveChild(self, obj, ready_deferred=None):
     assert ready_deferred is None
     if self.classname is None:
         self.classname = obj
         self.attrname = None
     elif self.attrname is None:
         self.attrname = obj
     else:
         if isinstance(obj, Deferred):
             # TODO: this is an artificial restriction, and it might
             # be possible to remove it, but I need to think through
             # it carefully first
             raise BananaError("unreferenceable object in attribute")
         if self.d.has_key(self.attrname):
             raise BananaError("duplicate attribute name '%s'" %
                               self.attrname)
         self.setAttribute(self.attrname, obj)
         self.attrname = None
Esempio n. 16
0
 def receiveChild(self, token, ready_deferred=None):
     assert not isinstance(token, Deferred)
     assert ready_deferred is None
     if self.key is None:
         if self.d.has_key(token):
             raise BananaError("duplicate key '%s'" % token)
         self.key = token
     else:
         self.d[self.key] = token
         self.key = None
Esempio n. 17
0
 def openerCheckToken(self, typebyte, size, opentype):
     if typebyte == tokens.STRING:
         if size > self.maxIndexLength:
             why = "STRING token is too long, %d>%d" % \
                   (size, self.maxIndexLength)
             raise Violation(why)
     elif typebyte == tokens.VOCAB:
         return
     else:
         # TODO: hack for testing
         raise Violation("index token 0x%02x not STRING or VOCAB" % \
                           ord(typebyte))
         raise BananaError("index token 0x%02x not STRING or VOCAB" % \
                           ord(typebyte))
Esempio n. 18
0
 def receiveClose(self):
     if self.state != 3:
         raise BananaError("MethodUnslicer requires three objects")
     if self.im_self is None:
         meth = getattr(self.im_class, self.im_func)
         # getattr gives us an unbound method
         return meth, None
     # TODO: late-available instances
     #if isinstance(self.im_self, NotKnown):
     #    im = _InstanceMethod(self.im_name, self.im_self, self.im_class)
     #    return im
     meth = self.im_class.__dict__[self.im_func]
     # whereas __dict__ gives us a function
     im = instancemethod(meth, self.im_self, self.im_class)
     return im, None
Esempio n. 19
0
    def checkToken(self, typebyte, size):
        """Check the token type. Raise an exception if it is not accepted
        right now, or if the body-length limit is exceeded."""

        limit = self.taster.get(typebyte, "not in list")
        if limit == "not in list":
            if self.strictTaster:
                raise BananaError("invalid token type: %s" %
                                  tokenNames[typebyte])
            else:
                raise Violation("%s token rejected by %s" %
                                (tokenNames[typebyte], self.name))
        if limit and size > limit:
            raise Violation("%s token too large: %d>%d" %
                            (tokenNames[typebyte], size, limit))
Esempio n. 20
0
 def receiveChild(self, obj, ready_deferred=None):
     assert not isinstance(obj, Deferred)
     assert ready_deferred is None
     if self.state == 0:
         self.im_func = obj
         self.state = 1
     elif self.state == 1:
         assert type(obj) in (types.InstanceType, types.NoneType)
         self.im_self = obj
         self.state = 2
     elif self.state == 2:
         assert type(obj) == types.ClassType  # TODO: new-style classes?
         self.im_class = obj
         self.state = 3
     else:
         raise BananaError("MethodUnslicer only accepts three objects")
Esempio n. 21
0
 def checkToken(self, typebyte, size):
     raise BananaError("NoneUnslicer does not accept any tokens")
Esempio n. 22
0
 def receiveClose(self):
     raise BananaError("top-level should never receive CLOSE tokens")
Esempio n. 23
0
 def receiveClose(self):
     if not self.finished:
         raise BananaError("FunctionUnslicer requires a string")
     return self.func, None
Esempio n. 24
0
 def receiveChild(self, obj, ready_deferred=None):
     assert not isinstance(obj, Deferred)
     assert ready_deferred is None
     if self.string != None:
         raise BananaError("already received a string")
     self.string = obj.decode("UTF-8")
Esempio n. 25
0
 def checkToken(self, typebyte, size):
     if typebyte not in (STRING, VOCAB):
         raise BananaError("UnicodeUnslicer only accepts strings")
Esempio n. 26
0
 def receiveChild(self, obj, ready_deferred=None):
     assert not isinstance(obj, Deferred)
     assert ready_deferred is None
     if self.value != None:
         raise BananaError("already received a string")
     self.value = decimal.Decimal(six.ensure_str(obj))
Esempio n. 27
0
 def checkToken(self, typebyte, size):
     if typebyte not in (tokens.STRING, tokens.VOCAB):
         raise BananaError("FunctionUnslicer only accepts strings")
Esempio n. 28
0
 def receiveClose(self):
     if not self.finished:
         raise BananaError("ClassUnslicer requires a string")
     return self.klass, None
Esempio n. 29
0
 def checkToken(self, typebyte, size):
     if typebyte != tokens.OPEN:
         raise BananaError("top-level must be OPEN")
Esempio n. 30
0
 def checkToken(self, typebyte, size):
     if typebyte != tokens.INT:
         raise BananaError("BooleanUnslicer only accepts an INT token")
     if self.value != None:
         raise BananaError("BooleanUnslicer only accepts one token")