[Openswan dev] Design question: ikev2 state change signifying partial success?

Paul Wouters pwouters at redhat.com
Tue Feb 21 16:01:44 EST 2012


On Tue, 21 Feb 2012, D. Hugh Redelmeier wrote:

>
> First, what are states (enum state_kind values) in Pluto?  They
> reflect where we are in a negotiation, between events.  During the
> processing of events, many things are up in the air and the state will
> be in transition.  During processing, the fine details of where we are
> in negotiation is reflected in where we are in the code.
>
> Conceptually it sounds as if your problem is that one of the messages
> has been partially successful and you have no way of signifying it in
> with enum state_kind.  I think that that indicates the current
> enum state_kind is wrong for V2 (not expressive enough).

I am not (yet) sure. In this case, our parent sa is in state_kind
STATE_PARENT_I3 and STATE_PARENT_R2. But there is a new state which was
cloned from the parent that should become some child sa. We currently
seem to be placing those into the same state as the parent SA's, 
STATE_PARENT_I3 and STATE_PARENT_R2? Those might need be called
STATE_CHILD_I1 and STATE_CHILD_R1?

The difference with IKEv2 I think, is that we go from from one event
to two states, eg:


STATE_PARENT_I1 --->

                       <--- STATE_PARENT_R1,

STATE_PARENT_I2\
                 +--->
STATE_PARENT_I2/

                            / STATE_PARENT_R2,
                       <---+
                            \ STATE_PARENT_R2,


STATE_PARENT_I3             STATE_PARENT_R2
STATE_PARENT_I3             STATE_PARENT_R2

and pluto shows:

Initiator:

000 #2: "test":500 STATE_PARENT_I3 (PARENT SA established); EVENT_SA_REPLACE in 28099s; newest IPSEC; eroute owner; nodpd; idle; import:admin initiate
000 #1: "test":500 STATE_PARENT_I3 (PARENT SA established); EVENT_SA_REPLACE in 3594s; newest ISAKMP; nodpd; idle; import:admin initiate

Responder:

000 #2: "test":500 STATE_PARENT_R2 (received v2I2, PARENT SA established); EVENT_SA_REPLACE in 28443s; newest IPSEC; eroute owner; nodpd; idle; import:respond to stranger
000 #1: "test":500 STATE_PARENT_R2 (received v2I2, PARENT SA established); EVENT_SA_REPLACE in 3513s; newest ISAKMP; nodpd; idle; import:respond to stranger

When there is a mismatch on the child sa, and we cannot establish one of
the "Parent SA" states on each side. To recover from this, I think the
(real!) Parent SA is supposed to try another child SA proposal (which I
am not sure if we even implement right now). But we currently let those
partial SA's linger, and all kind of assumptions go wrong (such as them
being child SA's, they should have an IPSEC_POLICY). So we need to get
rid of these, or handle these partial ones. Since the Child SA's
themselves do not negoatiate IKE (their parents do), I think we should
remove these.

The tricky thing is that the responder's last packet sets up both the
parent and the child sa, so we cannot abort sending that 4th packet in
the exchange, so we have to carry around the bogus child for a while
and delete_state() it after we sent out the last exchange packet. This
last bit requires "signaling" that in the call chain of the
STATE_PARENT_R2 state processor function, and that's where my question
regarding STF_OK versus a new STF_PARENT_OK came from.

In this case, we have the call chain:

ikev2parent_inI2outR2 ->
    ikev2_parent_inI2outR2_continue ->
             ikev2_parent_inI2outR2_tail ->
                  ikev2_child_sa_respond

These all signal now via their return type of stf_status, and if
anything in this chain is not STF_OK, we enter "abort" code that
does not let us complete the parent SA and thus we cannot signal
child sa errors in an encrypted way.

This is why I am thinking of a new stf_result STF_PARENT_OK, that
ikev2_child_sa_respond can return, then the previous callers can
tell the difference between "parent + child SA" and "parent sa only".

So while this creates a new stf_status, this does not create a new
state, as I think once we delete the incomplete child, the parent states
are fine, and we don't want the child state to linger? Or do we want
that, so the child can tell the parent to keep retrying?


> In IKE V1, it was pretty easy to treat the place in the sequence of
> messges of a negotiation as the state of negotiation: a message was
> either accepted or rejected.  Furthermore, in a particular kind of
> exchange, each payload came in a standard-specified message.
>
> If I recall, V2 lets payloads be in any of several messages and you
> can drag out or compress the exchange as much as you want.
>
> This means that the state of negotiation may not be the same as the
> place in the sequence of messages of an exchange.
>
> If the payloads were in a fixed order, even if not in a fixed message,
> you could think of the state as being the position in the sequence of
> payloads.  On the downside, this multiplies the number of states.
>
> If the payloads are not in a fixed order, then states could be
> identified with the set of transmitted payloads and received payloads.
> (I think some orders are forbidden: certain payloads are needed to
> create the IKE SA and must be before that happens and certain payloads
> must be protected and thus be after.)

While these might be problems, I am not sure if these are the same
problems?

> Anyway: you get the idea.  The state needs to reflect what has been
> done and (perhaps implicitly) what still needs to be done.  At least
> for all points between events.

Paul


More information about the Dev mailing list