Re: [Twisted-Python] unsafe tracebacks in PB

Hey, sorry for the slow response. It *is* possible to set the 'unsafeTracebacks' flag on both ends of the wire. PBServerFactory() takes a constructor argument to set this flag, while PBClientFactory() does not, but you can always set it after the fact: f = PBClientFactory() f.unsafeTracebacks = True I'm more inclined to resolve the asymmetry by removing the argument from PBServerFactory rather than adding it to PBClientFactory. As a debugging thing, I feel it isn't entirely appropriate to have as a constructor argument. However, I don't really feel that strongly about it either way. For the record, I'll describe a little bit more about what exactly this flag does, because there *is* a sense in which unsafe tracebacks can only be enabled on the "server" side of a given method call. The important thing to remember is that there are two different ways to divide the connection into "client" and "server" ends. Suppose you have program A, which has a pb.Referenceable named Alice that implements remote_foo. Likewise, you have program B, which contains a pb.Referenceable named Bob that implements remote_bar. Let us further suppose that program B used PBServerFactory and reactor.listenTCP to make the object Bob available to the world. Program A then used PBClientFactory and reactor.connectTCP to obtain a RemoteReference to Bob (and somehow passed a reference to Alice over to program B at the same time, so that both programs have a RemoteReference to the other's Referenceable). Now, the setting of this "unsafe tracebacks" flag on side A only affects tracebacks being sent *from* side A: that is, for exceptions that occur on side A, during a remote method invocation that was requested by side B. If you consider any given method call to have a "client side" (which requests the call by doing rref.callRemote("foo", args)), and a "server side" (which implements the method remote_foo(self, args)), then the unsafe-tracebacks flag is only relevant for the "server side". In our example, when B does alice.callRemote("foo"), B is the "client" side and A is the "server" side. If an exception occurs inside Alice's remote_foo method, it is the setting of A's clientfactory.unsafeTracebacks flag that determines whether's A's internal state will be exposed to B. On the other hand, when A does bob.callRemote("bar"), B is the "server" side, so it is B's serverfactory.unsafeTracebacks flag that matters. The important point is that the requesting side for any particular method call does not get to ask for an "unsafe traceback": only the owner of the sensitive information (in this case, the stack frames leading up to the exception, and the globals/locals that are in those stack frames) gets to decide whether or not to share it with the outside world. The second usage of the terms "client" and "server" here has to do with which side initiated the TCP connection and which side accepted it. This is how the PBClientFactory and PBServerFactory classes use these terms. Both of these classes have an 'unsafeTracebacks' flag, and if you set it to something non-zero, then any exception-raising methods invoked on that side will send back a full traceback to the other side. The minor asymmetry here (constructor argument versus set-the-flag-later) is just an oversight in the API. hope that's useful, -Brian
participants (1)
-
Brian Warner