CTM tokens in ADC (or why the NMDC protocol is terrible, part 2)
August 3, 2007 2 Comments
ADC’s CTM command contains a token parameter. This solves NMDC’s problem of certain client-client connections being only loosely connected with any hub connection, which in turn solves several secondary issues in NMDC, such as inhibited multiple share support; easy nick-faking in client-client connections; and causing a potentially incorrect nick to be returned by the client receiving the C-C connection if nicks alone don’t unambiguously return. I’ll describe these individually in future blog posts, but this one will just focus on the mechanics of the token and how it authenticates a C-C connection to the hub through which it originated.
The potentially easy case, and the one which in any event the NMDC protocol is competent to handle, even if DC++ isn’t necessarily: one can determine what hub a client-client connections spawned from if a client has received a $ConnectToMe/CTM and thus initiates the C-C connection. In such an event, the bookkeeping is entirely local and therefore not in principle dependent on which protocol one uses – if the client trusts that the hub isn’t spoofing the other user’s messages, then it can transfer that information directly, that local socket N was created in response to a CTM from hub H. Any further communication on socket N can therefore be tied unambiguously to hub H.
The remote end of socket N has a more difficult problem, since it must match just a nick – not a hub nor any other information about a user that NMDC reliably transmit – with a hub. This in even theoretically cannot be done without, at best, heuristics. DC++’s works tolerably, but it’s still guessing. A couple of issues exist – that nicks are public information and therefore trivially spoofable and guessable means that there’s no reliable guarantee the client on the other end is even on of the same hubs one’s own client is, undermining the exclusive nature of hubs; and commonly, that a given nick appears on multiple remote hubs. Whether those nicks represent the same user cannot be unambiguously determined [*], so one cannot just assume that any choice of user associated with that nick is as good as any other. Instead, the remove end, which sent the $ConnectToMe, must guess. This historically seems to have stemmed from the original Neo-Modus client not supporting multiple hubs and therefore the protocol behind it not needing at the time to distinguish these conditions, but it isn’t a reliable way to run a P2P network.
ADC’s token solves this problem, and thus the triggered secondary issues, with minimal computation and bandwidth overhead, by involving only the two clients in question and the hub in transferring thusly private and only per-C-C-connection valid information which all parties involved can use to authenticate the origin of the connection, both the hub and specific user.
In order to do so, though, this token should be generated in a manner such that a third party would find it difficult to forge – otherwise several of the previous flaws would reappear. A good random number generator, though ideally with at least 64 independent output bits and suited for cryptographic applications, should suffice.
If this precondition is established, then only the two clients between which the client-client connection will be created and the hub. This precludes, barring the a hub’s potential untrustworthiness [**], either a rogue user unaffiliated with any hubs spoofing a DC client into interacting further with it or a DC client’s being forced to guess which hub a user is from.
[*] Yes, there are multiple ways of attempting to narrow this down. They’re all ugly and unreliable.
[**] Such hubs create more significant problems. SSL certificates avoid them.