Mass rename
[devwiki.git] / wiki / design / tlv.mdwn
diff --git a/wiki/design/tlv.mdwn b/wiki/design/tlv.mdwn
deleted file mode 100644 (file)
index ec1be93..0000000
+++ /dev/null
@@ -1,178 +0,0 @@
-## Rationale for the TLV abstraction  
-
-hartmans: Luke, do you have opinions on what we want to do to the tokens for the target name stuff and SNI?  
-lukeh: will we be sending a bunch of arbitrary attributes like the acceptor does? like GSS-Asserted-Acceptor-Service-Name  
-lukeh: what's SNI?  
-hartmans: I think it means that the first token from initiator to acceptor (which I guess is useless today) probably wants to be a TLV token.  
-lukeh: yeah, I followed that on the mailing list but didn't implement as I was busy with other stuff  
-lukeh: that sounds reasonable, I guess it would require some reorganisation  
-lukeh: why do we want to send the target name?  
-hartmans: If you're getting a target name back then you probably want a TLV token for the first acceptor to initiator. But today that also includes an eap identity request, right?  
-lukeh: yes  
-hartmans: The question is do we want to TLV all the EAP tokens at that point?  
-lukeh: hmm.  
-lukeh: well either way I guess has merit  
-hartmans: The down side of TLVing everything is that then you can have news ways of having mallformed tokens.  
-lukeh: but I probably need to understand things better  
-lukeh: why does the acceptor send the target name back?  
-lukeh: I'm starting from a point of not understanding what is wrong with the existing protocol :)  
-hartmans: OK, so there are two different usages.  
-lukeh: as my understanding is we get the acceptor name back anyway in the EAP CB attributes  
-hartmans: 1) server name indication: the initiator knows the target name, but the acceptor may server multiple names.  
-hartmans: Here, the acceptor wants to know what name the initiator is calling.  
-***hartmans needs to think through the gss implications of what names the server accepts with Nico  
-hartmans: The other usage is null target name: the initiator doesn't know the target name but will look at the target name in the established context and see if it likes it.  
-hartmans: However in our mechanism, the initiator needs to learn the target name early so it can channel bind to it in EAP so it actually can believe the result.  
-hartmans: No, we don't get the acceptor name back in the eap CB.  
-hartmans: We *send* it in the eap cb and get back an indication about whether the server considered it in the CB result.  
-lukeh: ah.  
-hartmans: We don't get the value back.  
-hartmans: The other thing I'm wondering.  
-hartmans: Is there any actual information in the eap identity request?  
-hartmans: Could we just fake that packet and save a round trip?  
-lukeh: hmm, good point  
-Josh: we need the realm for routing  
-lukeh: that's in the response, not the request.  
-hartmans: That's in the identity response, right?  
-Josh: oh I mis-read  
-lukeh: yeah, Sam, that's an interesting point  
-lukeh: it didn't occur to me to do that  
-Josh: that would be a violation of the EAP SM, no?  
-lukeh: possibly  
-lukeh: I mean, the initiator would generate it itself rather than getting it from the acceptor  
-lukeh: certainly it's easier to understand in the current protocol  
-lukeh: but whether it's not worth optimising away is another question.  
-hartmans: Josh, it all depends on where you draw the layers.  
-Josh: take your point  
-hartmans: Note that on the radius server, the EAP SM never generates that packet... The NAS generates that one, right?  
-Josh: right  
-hartmans: I'm arguing we're basically doing the same thing. Rather than having the NAs generate that, we're asking the client to generate that and feed it to its own state machine.  
-hartmans: That only works if the packet is content free.  
-Josh: what's the advantage to that?  
-lukeh: save a roundtrip  
-lukeh: because currently the initiator sends an empty token  
-lukeh: just to poke things into action  
-Josh: IIRC, the data field can be used in the EAP-Identity/Request, but rarely is.  
-lukeh: hmm, if we are optimising something away that might be useful  
-hartmans: If it is used, what's it used for.  
-lukeh: then that may be bad.  
-hartmans: Sadly, Jari is not online. (He's the obvious eap expert in my buddy list)  
-Josh: I think we have previously floated the idea of using that data field for federation selection  
-lukeh: heh, can we shove the acceptor name in there  
-hartmans: Josh, I think that the changes we're talking about for target name null and for sni will give us the rope we need for federation selection.  
-***hartmans will investigate what that's useful for.  
-lukeh: please define SNI  
-lukeh: server name indication  
-lukeh: ?  
-Josh: True, and cleaner I believe.  
-hartmans: Luke if you're going to have an opinion on what tokens should be TLVed, please do so preferably before IETF.  
-hartmans: yes  
-  
-## Actual Design of resulting TLV implementation  
-  
-lukeh: OK, so the TLV code runs on a table of ( input token, output token, valid states, flags, callback )  
-lukeh: there are still a few too many special cases to be completely in love with it  
-lukeh: but hopefully after a few more days of hacking it will get there  
-lukeh: I've added some debug tokens in the initial leg to test that that works  
-lukeh: the previous extension tokens (GSS CB, reauth) are now just, obviously, TLVs in the last leg  
-lukeh: there is now only one *GSS* token for context establishment, TOK_TYPE_ESTABLISH_CONTEXT  
-lukeh: and a bunch of "inner" token types  
-lukeh: #define ITOK_TYPE_CONTEXT_ERR           0x00000001  
-    #define ITOK_TYPE_ACCEPTOR_NAME_REQ     0x00000002  
-    #define ITOK_TYPE_ACCEPTOR_NAME_RESP    0x00000003  
-    #define ITOK_TYPE_EAP_RESP              0x00000004  
-    #define ITOK_TYPE_EAP_REQ               0x00000005  
-    #define ITOK_TYPE_GSS_CHANNEL_BINDINGS  0x00000006  
-    #define ITOK_TYPE_REAUTH_CREDS          0x00000007  
-    #define ITOK_TYPE_REAUTH_REQ            0x00000008  
-    #define ITOK_TYPE_REAUTH_RESP           0x00000009  
-    #define ITOK_TYPE_VERSION_INFO          0x0000000A  
-    #define ITOK_TYPE_VENDOR_INFO           0x0000000B  
-    #define ITOK_FLAG_CRITICAL              0x80000000  /* critical, wire flag */  
-  
-lukeh: s/last leg/last round trip/  
-hartmans: What do you mean by token types in the table?  
-hartmans: Do you mean that a given callback can only produce one output token type, or something more than that?  
-lukeh: a given callback can only produce one output token type  
-lukeh: true, a callback could have returned a set of tokens  
-lukeh: perhaps that would be desirable  
-lukeh: but as long as the state can be passed through the context or credential object  
-lukeh: the same effect can be achieved  
-hartmans: I think that simplicity is good for now.  
-hartmans: OK, that implementation makes sense.  
-lukeh: the trunk is simplicity :-)  
-lukeh: although one nice thing is that the state machine walker is now shared between initiator and acceptor.  
-lukeh: so I may have reduced the line count actually.  
-lukeh: meh, about the same.  
-hartmans: So, can a callback return success and no token?  
-lukeh: yeah.  
-hartmans: good.  
-lukeh: (well, CONTINUE, or COMPLETE)  
-lukeh: I needed that for a couple of cases.  
-lukeh: first, if you transit states and don't emit a token  
-hartmans: and anyone returning continue means overall result is continue?  
-hartmans: anyone returning error means overall result is error?  
-lukeh: (hang on)  
-lukeh: e.g. going from completing the EAP stage (if no token emitted) to the extension stage  
-hartmans: Does that produce a round-trip or does it simply re-run the packet in the new state combining the output?  
-lukeh: (I'm going to answer your questions in order asked)  
-hartmans: That (state transition) was the case that was making me think you'd need the no token logic  
-lukeh: also, if you have a set of optional tokens (e.g. extensions) you need something to mark the end and transit the state.  
-hartmans: Yes, answering in order asked is fine.  
-lukeh: The very final callback that marks the context established returns COMPLETE  
-lukeh: Others return CONTINUE on success or an error.  
-lukeh: Returning an error means the overall result is an error and, on the acceptor side, an error token may be generated (this is done at the state machine layer)  
-lukeh: In case of a state transition when there is no output token, then the next set of callbacks are called with no input token  
-lukeh: to avoid regurgitating the input token from the previous state  
-hartmans: OK that last is non-obvious to me (calling nwith no input token)  
-lukeh: so, basically, tokens are emitted to the peer  
-hartmans: Can I see the table? It might be more clear there.  
-lukeh: when we've run out of callbacks or we transit states and have a token to send  
-lukeh: (more or less, there are a couple of exceptions to handle things like sending no tokens on the initial context token in order to poke the acceptor into sending us an EAP request)  
-lukeh: (rather than sending an empty EAP response from the initiator, as semantically that did not seem correct)  
-lukeh: (although perhaps it is, who knows.)  
-lukeh: if you checkout tlv  
-lukeh: look for eapGssInitiatorSm in init_sec_context.c  
-lukeh: and the corresponding one for the acceptor.  
-lukeh: note: the states are bitmasks.  
-lukeh: there's some verbose commenting in init_sm.c too.  
-hartmans: Ah, that makes so much more sense from the table  
-hartmans: This is quite clever.  
-lukeh: Hmm, it still doesn't feel *quite* right. Too many exceptions. I suspect if that if I was doing it from scratch rather than refactoring it might look different. But, it seems to work for now. Will revise over coming days.  
-lukeh: I think it is ugly because it collapses the state and token dimensions into a single one.  
-lukeh: However it does make it easier to have tokens that support multiple states.  
-lukeh: Although there are some limitations with that (the dispatch table is not retraversed after a state change so it effectively only works for exception tokens; of course, that's easily fixed)  
-hartmans: So, we depend on the EAP machine keeping us in sync between the initiator and acceptor?  
-hartmans: Not a problem, just confirming I understand.  
-hartmans: What do you mean state and token are combined? They are separate columns in the table as far as I can tell  
-lukeh: it's not a 2 dimensional array.  
-lukeh: they are separate columns yes  
-lukeh: re: depending on the EAP machine  
-hartmans: Ah.  
-lukeh: yes, I guess we do, what else could one do?  
-lukeh: it's a black box  
-lukeh: I don't know what happens yet if the EAP machine emits a token on success, I don't think that's possible though  
-lukeh: I need to check  
-***hartmans has too much of a relational database mindset to think of that as more than an efficiency issue  
-lukeh: yeah, I never used relational databases, so I never had that mindset  
-hartmans: I think depending on EAP to be consistent is fine.  
-hartmans: We could actually echo the eap state in some sort of market token. That would be far far worse.  
-lukeh: So, adding a new token that doesn't change the state is fairly easy.  
-lukeh: You just need to be careful where you put it in the table  :)  
-lukeh: It needs to be before the state changing entry.  
-lukeh: You can set the critical/required flags as desired.  
-lukeh: Some care is likely necessary to avoid colliding with the reauthentication path. But I think that's fairly easy.  
-lukeh: In my initial implementation I had overloaded the GSS status codes to mean various things, but in the end that got quite ugly.  
-lukeh: So I went with the callbacks performing the state changes themselves plus a flag to indicate a few exceptional things (e.g. get-out now)  
-hartmans: Presumably error always means get out now?  
-lukeh: yes  
-lukeh: if you want to get out now on CONTINUE, you need to either  
-lukeh: a) change state and emit a token  
-lukeh: b) change state and set FORCE_SEND_TOKEN (this is used to handle the initial case where we poke the acceptor without sending an inner token)  
-lukeh: c) set STOP_EVAL - this is not used yet  
-lukeh: the above applies to COMPLETE as well as CONTINUE  
-lukeh: there are some sanity checks to make sure COMPLETE only happens when state becomes ESTABLISHED  
-lukeh: see SM_ASSERT_VALID  
-hartmans: OK, and we can remove an exception if we decide it's OK for us to fake the eap request identity  
-lukeh: ah yes  
-hartmans: This is really cool.