Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > e8916e5cb6487118130934db089d8fa5 > files > 11

openswan-2.6.32-9.el5.src.rpm

diff -urNp openswan-2.6.32-cvs-patched/programs/pluto/ikev2_child.c openswan-2.6.32-current/programs/pluto/ikev2_child.c
--- openswan-2.6.32-cvs-patched/programs/pluto/ikev2_child.c	2011-03-02 10:22:54.215538106 -0500
+++ openswan-2.6.32-current/programs/pluto/ikev2_child.c	2011-03-17 10:56:41.470114998 -0400
@@ -97,6 +97,23 @@ struct traffic_selector ikev2_subnettots
 	break;
     }
 
+    /* IKEv2 code always sent 0-65535 as port regardless of 
+     * what local policy is. if local policy states a specific 
+     * protocol and port, then send that protocol 
+     * value and port to other end */
+
+    ts.ipprotoid = e->protocol;
+
+    /*if port is %any or 0*/
+    if(e->port == 0 || e->has_port_wildcard) {
+    ts.startport = 0;
+    ts.endport = 65535;
+    }
+    else {
+    ts.startport = e->port;
+    ts.endport = e->port;
+    }
+	
     return ts;
 }
 
@@ -128,9 +145,16 @@ stf_status ikev2_emit_ts(struct msg_dige
 	its1.isat1_sellen = 40;
 	break;
     }
-    its1.isat1_ipprotoid = 0;      /* all protocols */
-    its1.isat1_startport = 0;      /* all ports */
-    its1.isat1_endport = 65535;  
+
+
+    /* IKEv2 code always sent 0-65535 as port regardless of 
+     * what local policy is. if local policy states a specific 
+     * protocol and port, then send that protocol 
+     * value and port to other end */
+
+    its1.isat1_ipprotoid = ts->ipprotoid;      /* protocol as per local policy*/
+    its1.isat1_startport = htons(ts->startport);      /* ports as per local policy*/
+    its1.isat1_endport = htons(ts->endport);  
     if(!out_struct(&its1, &ikev2_ts1_desc, &ts_pbs, &ts_pbs2))
 	return STF_INTERNAL_ERROR;
     
@@ -268,8 +292,9 @@ ikev2_parse_ts(struct payload_digest *co
 	    }
 
 	    array[i].ipprotoid = ts1.isat1_ipprotoid;
-	    array[i].startport = ts1.isat1_startport;
-	    array[i].endport   = ts1.isat1_startport;
+	    /*should be converted to host byte order for local processing*/
+	    array[i].startport = ntohs(ts1.isat1_startport);
+	    array[i].endport   = ntohs(ts1.isat1_endport);
 	}
     }
     
@@ -354,6 +379,19 @@ static int ikev2_evaluate_connection_fit
 		int fitbits2  = maskbits2 + ts_range2;
 		int fitbits = (fitbits1 << 8) + fitbits2;
 
+		/*
+		 * comparing for ports
+		 * for finding better local polcy
+		 */
+
+		if( ei->port && (tsi[tsi_ni].startport == ei->port && tsi[tsi_ni].endport == ei->port)) {
+		fitbits = fitbits << 1;
+		}
+
+		if( er->port && (tsr[tsr_ni].startport == er->port && tsr[tsr_ni].endport == er->port)) {
+		fitbits = fitbits << 1;
+		}
+
 		DBG(DBG_CONTROLMORE,
 		{
 		    DBG_log("      has ts_range1=%u maskbits1=%u ts_range2=%u maskbits2=%u fitbits=%d <> %d"
@@ -390,27 +428,6 @@ stf_status ikev2_child_sa_respond(struct
     unsigned int tsi_n, tsr_n;
 
     st1 = duplicate_state(st);
-    insert_state(st1);
-    md->st = st1;
-    md->pst= st;
-
-    /* start of SA out */
-    {
-	struct isakmp_sa r_sa = sa_pd->payload.sa;
-	notification_t rn;
-	pb_stream r_sa_pbs;
-
-	r_sa.isasa_np = ISAKMP_NEXT_v2TSi;  
-	if (!out_struct(&r_sa, &ikev2_sa_desc, outpbs, &r_sa_pbs))
-	    return STF_INTERNAL_ERROR;
-
-	/* SA body in and out */
-	rn = ikev2_parse_child_sa_body(&sa_pd->pbs, &sa_pd->payload.v2sa,
-				       &r_sa_pbs, st1, FALSE);
-	
-	if (rn != NOTHING_WRONG)
-	    return STF_FAIL + rn;
-    }
 
     /*
      * now look at provided TSx, and see if these fit the connection
@@ -449,7 +466,7 @@ stf_status ikev2_child_sa_respond(struct
 	{
 	    hp = find_host_pair(&sra->this.host_addr
 				, sra->this.host_port
-				, NULL
+				, &sra->that.host_addr
 				, sra->that.host_port);
 
 #ifdef DEBUG
@@ -499,12 +516,40 @@ stf_status ikev2_child_sa_respond(struct
 	 * the state structure as the tsi/tsr
 	 *
 	 */
+
+	/*better connection*/
+	c=b;
+
 	/* Paul: should we STF_FAIL here instead of checking for NULL */
 	if (bsr != NULL) {
 		st1->st_ts_this = ikev2_subnettots(&bsr->this);
 		st1->st_ts_that = ikev2_subnettots(&bsr->that);
 	}
     }
+
+    st1->st_connection = c;
+    insert_state(st1);
+    md->st = st1;
+    md->pst= st;
+
+    /* start of SA out */
+    {
+	struct isakmp_sa r_sa = sa_pd->payload.sa;
+	notification_t rn;
+	pb_stream r_sa_pbs;
+
+	r_sa.isasa_np = ISAKMP_NEXT_v2TSi;  
+	if (!out_struct(&r_sa, &ikev2_sa_desc, outpbs, &r_sa_pbs))
+	    return STF_INTERNAL_ERROR;
+
+	/* SA body in and out */
+	rn = ikev2_parse_child_sa_body(&sa_pd->pbs, &sa_pd->payload.v2sa,
+				       &r_sa_pbs, st1, FALSE);
+	
+	if (rn != NOTHING_WRONG)
+	    return STF_FAIL + rn;
+    }
+
     ret = ikev2_calc_emit_ts(md, outpbs, role
 			     , c, c->policy);
     if(ret != STF_OK) return ret;
diff -urNp openswan-2.6.32-cvs-patched/programs/pluto/kernel_netlink.c openswan-2.6.32-current/programs/pluto/kernel_netlink.c
--- openswan-2.6.32-cvs-patched/programs/pluto/kernel_netlink.c	2011-03-02 10:47:39.480778457 -0500
+++ openswan-2.6.32-current/programs/pluto/kernel_netlink.c	2011-03-17 10:56:49.851084412 -0400
@@ -591,6 +591,32 @@ netlink_raw_eroute(const ip_address *thi
 
     req.u.p.sel.sport = portof(&this_client->addr);
     req.u.p.sel.dport = portof(&that_client->addr);
+
+    /* As per RFC 4301/5996, icmp type is put in the most significant 8 bits
+     * and icmp code is in the least significant 8 bits of port field. 
+     * Although Openswan does not have any configuration options for 
+     * icmp type/code values, it is possible to specify icmp type and code 
+     * using protoport option. For example, icmp echo request (type 8/code 0) 
+     * needs to be encoded as 0x0800 in the port field and can be specified 
+     * as left/rightprotoport=icmp/2048. Now with NETKEY, icmp type and code
+     * need to be passed as source and destination ports, respectively.
+     * therefore, this code extracts upper 8 bits and lower 8 bits and puts
+     * into source and destination ports before passing to NETKEY. */
+
+
+    if( 1 == transport_proto /*icmp*/ || 58 == transport_proto /*ipv6-icmp*/) {
+
+	u_int16_t icmp_type;
+	u_int16_t icmp_code;
+
+	icmp_type = ntohs(req.u.p.sel.sport) >> 8;
+	icmp_code = ntohs(req.u.p.sel.sport) & 0xFF;
+
+	req.u.p.sel.sport = htons(icmp_type);
+	req.u.p.sel.dport = htons(icmp_code);
+	
+    }
+
     req.u.p.sel.sport_mask = (req.u.p.sel.sport) ? ~0:0;
     req.u.p.sel.dport_mask = (req.u.p.sel.dport) ? ~0:0;
     ip2xfrm(&this_client->addr, &req.u.p.sel.saddr);