Here's what I have so far. With the event replacement changes in the patch,
ipsecdoi_replace initiates and sends a new Parent SA when the old one expires.
The rekeymargin options also don't seem to work with IKEv2 (since it's not
negotiated?) so I needed a hack to delay the delete event otherwise it goes
right out after the first IKE message on the rekey.

So we get to ikev2parent_outI1 to rekey. I don't understand the policy part of
this in regards to the addition of a pending state, as it seems that we need our
new SA's to pend until they are established and the code later on expects that
it can find a pending state. 

It does:

        if (HAS_IPSEC_POLICY(policy)) {                            
#ifdef HAVE_LABELED_IPSEC                                                       
          
                st->sec_ctx = NULL;                                             
          
                if ( uctx != NULL)                                              
          
                        libreswan_log(                                          
          
                                "Labeled ipsec is not supported with ikev2 
yet");         
#endif                                                                          
          
                add_pending(dup_any(whack_sock), st, c, policy, 1,              
          
                            predecessor == NULL ? SOS_NOBODY : 
predecessor->st_serialno   
#ifdef HAVE_LABELED_IPSEC                                                       
          
                            , st->sec_ctx                                       
          
#endif                                                                          
          
                            );                                                  
          

Before we rekey the IPSEC part of the policy is removed. So this is confusing
and I work around it in the patch.

Now we rekey:

May 28 15:45:15 west pluto[16030]: | event after this is EVENT_PENDING_DDNS in 
3 seconds                         
May 28 15:45:15 west pluto[16030]: | processing connection rekey                
                                 
May 28 15:45:15 west pluto[16030]: "rekey" #1: replacing stale ISAKMP SA        
                                 
May 28 15:45:15 west pluto[16030]: | creating state object #3 at 0x7f64366d6630 
                                 
May 28 15:45:15 west pluto[16030]: | processing connection rekey                
                                 
May 28 15:45:15 west pluto[16030]: | ICOOKIE:  f0 48 39 19  c8 3c 58 e8         
                                 
May 28 15:45:15 west pluto[16030]: | RCOOKIE:  00 00 00 00  00 00 00 00         
                                 
May 28 15:45:15 west pluto[16030]: | state hash entry 20                        
                                 
May 28 15:45:15 west pluto[16030]: | inserting state object #3                  
                                 
May 28 15:45:15 west pluto[16030]: | inserting event EVENT_SO_DISCARD, timeout 
in 0 seconds for #3               
May 28 15:45:15 west pluto[16030]: | event added at head of queue               
                                 
May 28 15:45:15 west pluto[16030]: | processing connection rekey                
                                 
May 28 15:45:15 west pluto[16030]: | Queuing pending Quick Mode with 
192.168.1.113 "rekey"                       
May 28 15:45:15 west pluto[16030]: "rekey" #3: initiating v2 parent SA to 
replace #1                             

v2R1 comes back and:

May 28 15:45:16 west pluto[16030]: | PSK auth octets  cf 29 10 e6  1d 7b bc c1  
61 8c 38 6b  6d e4 47 0d     
May 28 15:45:16 west pluto[16030]: | emitting 16 raw bytes of PSK auth into 
IKEv2 Authentication Payload     
May 28 15:45:16 west pluto[16030]: | PSK auth  cf 29 10 e6  1d 7b bc c1  61 8c 
38 6b  6d e4 47 0d            
May 28 15:45:16 west pluto[16030]: | emitting length of IKEv2 Authentication 
Payload: 24                     
May 28 15:45:16 west pluto[16030]: | kernel_alg_db_new() initial trans_cnt=0    
                             
May 28 15:45:16 west pluto[16030]: | kernel_alg_db_new() will return 
p_new->protoid=0, p_new->trans_cnt=0    
May 28 15:45:16 west pluto[16030]: | returning new proposal from esp_info       
                             
May 28 15:45:16 west pluto[16030]: | *****emit IKEv2 Security Association 
Payload:                           
May 28 15:45:16 west pluto[16030]: |    next payload type: ISAKMP_NEXT_v2TSi    
                             
May 28 15:45:16 west pluto[16030]: |    critical bit: none                      
                             
May 28 15:45:16 west pluto[16030]: | netlink_get_spi: allocated 0xf99f3a87 for 
esp.0@192.168.1.112           
<crash> :(

Program received signal SIGSEGV, Segmentation fault.
ikev2_out_sa (outs=outs@entry=0x7fffb9898920, protoid=protoid@entry=3, 
sadb=0x7f1e871eb330, st=0x7f1e871f1c50, parentSA=parentSA@entry=0, 
np=np@entry=44 ',') at 
/root/libreswan-test/programs/pluto/ikev2_spdb_struct.c:149
(gdb) bt
#0  ikev2_out_sa (outs=outs@entry=0x7fffb9898920, protoid=protoid@entry=3, 
sadb=0x7f1e871eb330, st=0x7f1e871f1c50, parentSA=parentSA@entry=0, 
np=np@entry=44 ',') at 
/root/libreswan-test/programs/pluto/ikev2_spdb_struct.c:149
#1  0x00007f1e86529485 in ikev2_emit_ipsec_sa (md=md@entry=0x7f1e871c6aa0, 
outpbs=outpbs@entry=0x7fffb9898920, np=np@entry=44, c=c@entry=0x7f1e871c00c0, 
policy=<optimized out>) at 
/root/libreswan-test/programs/pluto/ikev2_spdb_struct.c:175
8
#2  0x00007f1e86521cd4 in ikev2_parent_inR1outI2_tail 
(pcrc=pcrc@entry=0x7f1e871ecad0, r=r@entry=0x7fffb9898b70) at 
/root/libreswan-test/programs/pluto/ikev2_parent.c:1625
#3  0x00007f1e86522005 in ikev2_parent_inR1outI2_continue (pcrc=0x7f1e871ecad0, 
r=0x7fffb9898b70, ugh=<optimized out>) at 
/root/libreswan-test/programs/pluto/ikev2_parent.c:1168

This happens at:

144|         for (pc_cnt = 0; pc_cnt < sadb->prop_disj_cnt; pc_cnt++) {
145|                 struct db_v2_prop *vp = &sadb->prop_disj[pc_cnt];
146|                 unsigned int pr_cnt;
147|
148|                 /* now send out all the transforms */
149+>                for (pr_cnt = 0; pr_cnt < vp->prop_cnt; pr_cnt++) {
150|                         unsigned int ts_cnt;
151|                         struct db_v2_prop_conj *vpc = &vp->props[pr_cnt];

(gdb) p vp
$1 = (struct db_v2_prop *) 0x0

(gdb) p *sadb
$4 = {
  dynamic = 1,
  parentSA = 0,
  prop_conjs = 0x7f1e871f56c0,
  prop_conj_cnt = 1,
  prop_disj = 0x0,
  prop_disj_cnt = 1
}

I can't tell why the prop_disj data is missing here. Any ideas?

While IKEv2 rekeying without a CREATE_CHILD_SA seems hacky enough so I don't 
want to butcher this too much :)

Matt
diff --git a/include/pluto_constants.h b/include/pluto_constants.h
index 88fa7ab..b0e174b 100644
--- a/include/pluto_constants.h
+++ b/include/pluto_constants.h
@@ -437,6 +437,10 @@ enum phase1_role {
 
 #define IS_PARENT_SA(st) (!IS_CHILD_SA(st))
 
+#define V1_V2_IKESA(st)  (IS_PHASE1(st->st_state) || \
+                         IS_PHASE15(st->st_state) || \
+                         IS_PARENT_SA(st))
+
 /* kind of struct connection
  * Ordered (mostly) by concreteness.  Order is exploited.
  */
diff --git a/programs/pluto/ikev2_parent.c b/programs/pluto/ikev2_parent.c
index 324610c..ed5868f 100644
--- a/programs/pluto/ikev2_parent.c
+++ b/programs/pluto/ikev2_parent.c
@@ -124,7 +124,7 @@ stf_status ikev2parent_outI1(int whack_sock,
        st->st_msgid_nextuse = 0;
        st->st_try   = try;
 
-       if (HAS_IPSEC_POLICY(policy)) {
+       if (HAS_IPSEC_POLICY(policy) || predecessor != NULL) {
 #ifdef HAVE_LABELED_IPSEC
                st->sec_ctx = NULL;
                if ( uctx != NULL)
diff --git a/programs/pluto/timer.c b/programs/pluto/timer.c
index 1e919b0..7d94944 100644
--- a/programs/pluto/timer.c
+++ b/programs/pluto/timer.c
@@ -627,11 +627,11 @@ void handle_next_timer_event(void)
        {
                struct connection *c;
                so_serial_t newest;
+               time_t margin;
 
                passert(st != NULL);
                c = st->st_connection;
-               newest = (IS_PHASE1(st->st_state) ||
-                       IS_PHASE15(st->st_state )) ?
+               newest = V1_V2_IKESA(st) ?
                        c->newest_isakmp_sa : c->newest_ipsec_sa;
 
                if (newest > st->st_serialno &&
@@ -640,9 +640,8 @@ void handle_next_timer_event(void)
                        DBG(DBG_LIFECYCLE,
                                libreswan_log(
                                        "not replacing stale %s SA: #%lu will 
do",
-                                       (IS_PHASE1(st->st_state) ||
-                                               IS_PHASE15(st->st_state )) ?
-                                       "ISAKMP" : "IPsec", newest));
+                                        V1_V2_IKESA(st) ?
+                                        "ISAKMP" : "IPsec", newest));
                } else if (type == EVENT_SA_REPLACE_IF_USED   &&
                        st->st_outbound_time <= tm - c->sa_rekey_margin) {
                        /*
@@ -666,22 +665,26 @@ void handle_next_timer_event(void)
                        DBG(DBG_LIFECYCLE,
                                libreswan_log(
                                        "not replacing stale %s SA: inactive 
for %lus",
-                                       (IS_PHASE1(st->st_state) ||
-                                               IS_PHASE15(st->st_state )) ?
-                                               "ISAKMP" : "IPsec",
+                                        V1_V2_IKESA(st) ? "ISAKMP" : "IPsec",
                                        (unsigned long)(tm -
                                                st->st_outbound_time)));
                } else {
                        DBG(DBG_LIFECYCLE,
                                libreswan_log("replacing stale %s SA",
-                                       (IS_PHASE1(st->st_state) ||
-                                               IS_PHASE15(st->st_state)) ?
-                                       "ISAKMP" : "IPsec"));
+                                             V1_V2_IKESA(st) ?
+                                             "ISAKMP" : "IPsec"));
                        ipsecdoi_replace(st, LEMPTY, LEMPTY, 1);
                }
                delete_liveness_event(st);
                delete_dpd_event(st);
-               event_schedule(EVENT_SA_EXPIRE, st->st_margin, st);
+
+               /* XXX hack - get around st->st_margin being 0 here on ikev2 
rekey for the moment */
+               if (st->st_ikev2 && st->st_margin < 1)
+                       margin = 10;
+               else
+                       margin = st->st_margin;
+
+               event_schedule(EVENT_SA_EXPIRE, margin, st);
        }
        break;
 
@@ -694,7 +697,7 @@ void handle_next_timer_event(void)
                passert(st != NULL);
                c = st->st_connection;
 
-               if (IS_PHASE1(st->st_state) || IS_PHASE15(st->st_state)) {
+               if (V1_V2_IKESA(st)) {
                        satype = "ISAKMP";
                        latest = c->newest_isakmp_sa;
                } else {
_______________________________________________
Swan-dev mailing list
Swan-dev@lists.libreswan.org
https://lists.libreswan.org/mailman/listinfo/swan-dev

Reply via email to