[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [xmpp] the stream negotiation process



On Fri Oct 16 22:49:44 2009, Joe Hildebrand wrote:
(as individual)

On 10/16/09 9:24 AM, "Peter Saint-Andre" <stpeter at stpeter.im> wrote:

> You are recommending instead something like this:
>
> R: <stream:features>
>      <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
>        <stream:required restart='true'/>
>      </starttls>
>    </stream:features>
>
> Now, what we've said is that the use of <required/> and <optional/> is a > convention that we will follow in defining all stream features, but I > think you're right that it's better to define one qualified name for > this, and probably place it in the streams namespace (we could define a > new namespace just for optionality of stream features, but I don't see a
> compelling reason to do that).

+1.  I really like that approach.


I think this is better than the original proposition, but my worry is that it only makes sense when there is, for sake of example, only one way to skin a cat.

When there are multiple features that fulfill the requirements, it seems that the logic becomes fairly complex. I don't see this happening for cases like TLS, in fact, for reasons I'll go into in a second, but for post-auth cases, I think we're trying to solve a problem for which we have no use cases.

For preauth, what the server is actually trying to express is generally security requirements. Perhaps the logical thing to do, if we really want to radically change the old <required/>, is to have the server provide security requirements in some form - that form seems like something for some other working group to solve, though.

But really, what we're trying to do is usually pretty simple - require encryption or not.

The simple approach here is to provide features like:

<s:features>
	<starttls/>
	<mechanisms><mechanism>GSSAPI</mechanism></mechanisms>
</s:features>

Then the client gets to pick one of those two. Picking <starttls/> gives it TLS, and the servers offers more mechanisms - mechanisms without a security layer as well, probably.

Notice I've not used <required/>. I'm not convinced that <required/> is even needed here. The interesting case is actually <optional/>, which *is* required for the old session stuff - if it weren't for the fact you can pipeline it. (And here I assume there may be good reasons to list the feature for old clients, but I'm not convinced).


>> Whether a feature requires a stream
>> restart or not is part of the definition of the feature (e.g., it's part >> of the definitions of the SASL and STARTTLS features). If an entity
>> understands a feature, then it already knows whether a restart is
>> required or not. What value does the 'restart' attribute add? Are there
>> any use-cases where the 'restart' attribute saves the day?
>
> IMHO it's better to be explicit than implicit in what's required
> throughout the stream negotiation process.

It also makes writing clients much easier, because they can process stream
restarts generically.


I think you must write clients in a wholly different way to me. My XMPP client (the one I wrote for myself) has precisely two lines devoted to the thorny issue of stream restarts. I just don't see the problem. Surely the definition of the feature is very explicit in whether or not the feature requires a stream restart?

(Incidentally, I just looked at the relevant places in our server code, and there's *four* lines, there. It's sheer madness, escalating out of control, and it must stop now! Or maybe not.)

I mean, if I suddenly decide that the resource binding requires a stream restart, what on earth should a client do? Restart the stream once it receives an <iq type='result'/>? With what from attribute? What does a server do if the client doesn't restart? Reject it? With what error?

> Well, <required/> and <optional/> are really not ideal because they're > defining a boolean. It would be better to have something like this:
>
> R: <stream:features>
>      <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>
>        <stream:usage required='true' restart='true'/>
>      </starttls>
>    </stream:features>
>
> Here both attributes would default to FALSE.

As well, servers SHOULD allow SASL restarts even if restart='false', for
backward-compatibility.


Yay. But you can only not require a restart for TLS and SASL if you also allow for mid-stream feature updates.

We need this because the security properties of the stream may change, and it's *far* easier to mandate a restart in all cases of TLS and SASL, instead of merely "when the security properties change". (It'd be marginally easier with SASL, actually, since when the security properties change the client generally knows about it, but still.)

I really don't think that leaving this to server choice is very wise at all.


>> How about a stream feature advertising an entity's
>> ability to receive feature updates?
>
> Nothing in RFC 3920 forbids this behavior, and in any case what you want > is a feature that could be advertised by the initiating entity (so that
> it can tell the receiving entity "yes I support feature updates").
>
> But that gets into the question of feature declarations from the
> initiating entity to the receiving entity, which is also interesting but
> not yet defined.

The question is whether late stream features will break existing client software. I think there is a possibility. I've had several bad ideas about how to have clients and servers know that they both support this, but all of
them are heavy-weight compared to a) the utility and b) the risk.

Right. And without this there is no longer any value to avoiding restarts for TLS, certainly, and SASL, probably.


Maybe we should just do some client/library testing to see what happens. :)

Yes, because luckily, we're confident we can exhaustively test all extant XMPP clients with all possible feature changes.

The XMPP community is pretty close-knit, but not that close-knit.

Besides which, features are for stream properties - by the time the stream is established, it's too late to change these. If the change is, say, mandating TLS, then you *want* to kick off all your connections.

Instead, if people really want to shave a restart off SASL, have an extra parameter to <auth/> which causes the server to drop support for security layers, and pipeline a <stream:features/> after the <success/>. Perhaps - because it's a zero-octet switchover, it makes some sense there.

Doing the same for TLS is much harder - in principle it's possible, but won't save any round-trips if client session resumption is being used, if memory serves. (More round-trips are saved by batshit crazy stuff like Stunt Buffering, as Tony Finch once called it).

So, here's a summary:

1) You probably don't want to require features. Instead, you only want to drop the ones the clients not allowed to use right now.

2) Optional might not be needed either. If it is, it's only for the session feature, and that only if it's actually required to be listed, and that could be solved by a new feature, pipelining, or a specific child for session's feature.

3) Altering restart behaviour on the fly is only possible if features can be sent on the fly.

4) And they can't - it's simply too big a change for the protocol.

So really, I think we're chasing ghosts, here. If there's optimizations to be made, let's please figure them out and make them. But making things too generic is simply over-engineering something that actually works just fine right now.

Dave.
--
Dave Cridland - mailto:dave at cridland.net - xmpp:dwd at dave.cridland.net
 - acap://acap.dave.cridland.net/byowner/user/dwd/bookmarks/
 - http://dave.cridland.net/
Infotrope Polymer - ACAP, IMAP, ESMTP, and Lemonade

Note Well: Messages sent to this mailing list are the opinions of the senders and do not imply endorsement by the IETF.