File novell-ipsec-tools_plugins-support-nortel.patch of Package novell-ipsec-tools

Index: ipsec-tools-0.7.3/src/racoon/oakley.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/oakley.c
+++ ipsec-tools-0.7.3/src/racoon/oakley.c
@@ -96,6 +96,13 @@
 #include "gssapi.h"
 #endif
 
+#ifdef PLUGINS_SUPPORT
+#include "plugin_frame/common.h"
+#include "plugin_frame/framework.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif // PLUGINS_SUPPORT
+
 #define OUTBOUND_SA	0
 #define INBOUND_SA	1
 
@@ -131,6 +138,10 @@ static cert_t *save_certbuf __P((struct
 static cert_t *save_certx509 __P((X509 *));
 static int oakley_padlen __P((int, int));
 
+#ifdef PLUGINS_SUPPORT
+static int plugin_generate_psk __P((u_int8_t, u_int8_t, int, vchar_t **));
+#endif // PLUGINS_SUPPORT
+
 int
 oakley_get_defaultlifetime()
 {
@@ -2465,6 +2476,9 @@ oakley_skeyid(iph1)
 	char *p;
 	int len;
 	int error = -1;
+#ifdef PLUGINS_SUPPORT
+	int status = PLUGIN_FRAME_STATUS_SUCCESS;
+#endif // PLUGINS_SUPPORT
 	
 	/* SKEYID */
 	switch (AUTHMETHOD(iph1)) {
@@ -2474,7 +2488,22 @@ oakley_skeyid(iph1)
 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
 #endif
 		if (iph1->etype != ISAKMP_ETYPE_IDENT) {
-			iph1->authstr = getpskbyname(iph1->id_p);
+
+#ifdef PLUGINS_SUPPORT
+			status = plugin_generate_psk(iph1->etype,
+					(iph1->side == INITIATOR)? TPIKE_MIDX_INITIATOR: TPIKE_MIDX_RESPONDER,
+				   	iph1->approval->authmethod,
+				   	&(iph1->authstr));
+			if (status == TPIKE_ERR_HASH_MATCH_NOT_FOUND
+					|| status == TPIKE_ERR_HASH_TABLE_OVERFLOW)
+			{
+#endif // PLUGINS_SUPPORT
+				iph1->authstr = getpskbyname(iph1->id_p);
+
+#ifdef PLUGINS_SUPPORT
+			}
+#endif // PLUGINS_SUPPORT
+
 			if (iph1->authstr == NULL) {
 				if (iph1->rmconf->verify_identifier) {
 					plog(LLV_ERROR, LOCATION, iph1->remote,
@@ -3313,3 +3342,54 @@ oakley_padlen(len, base)
 	return padlen;
 }
 
+#ifdef PLUGINS_SUPPORT
+int
+plugin_generate_psk(etype, side, authmethod, psk)
+	u_int8_t etype;
+	u_int8_t side;
+	int authmethod;
+	vchar_t **psk;
+{
+	struct hookpoint hpoint, *hp;
+	struct handlerinfo *hinfo;
+	void *inarr = NULL, *outarr = NULL, *outp = NULL;
+	u_int32_t myposition = 0, status = TPIKE_STATUS_SUCCESS;
+	u_int8_t sendorrecv = 0, msgindx = 0;
+	char *keyval = NULL;
+
+	switch(etype)
+	{
+		case ISAKMP_ETYPE_IDENT:
+			sendorrecv = TPIKE_MIDX_SEND;
+
+			msgindx = (side == TPIKE_MIDX_INITIATOR) ? 3 : 2;
+			break;
+		case ISAKMP_ETYPE_AGG:
+			sendorrecv = (side == TPIKE_MIDX_INITIATOR) ? TPIKE_MIDX_RECEIVE :TPIKE_MIDX_SEND ;
+			msgindx = (side == TPIKE_MIDX_INITIATOR) ? 1 : 2;
+			break;
+		case ISAKMP_ETYPE_BASE:
+			myposition = (side == INITIATOR) ? ((authmethod == OAKLEY_ATTR_AUTH_METHOD_RSASIG || authmethod == OAKLEY_ATTR_AUTH_METHOD_DSSSIG) ? INITIATOR_RCVD_THREE : INITIATOR_SEND_TWO) : RESPONDER_RCVD_TWO;
+			break;
+		default:
+			//invalid state - log it
+			return -2;      //framework needs to define an error code for invalid state
+	}
+
+	hp = &hpoint;
+	mk_hookpoint(PAYLOAD_TYPE, ISAKMP_NPTYPE_NONE, ISAKMP_NPTYPE_NONE, MAKE_POS(etype, side, sendorrecv, msgindx, 0xff, 0xff), 0, 0, keyval, hp);
+
+	tpike_pack_in(&inarr, 0);
+
+	if((status = tpike_dispatch_generic(&hpoint, inarr, &outarr)) == TPIKE_STATUS_SUCCESS) {
+
+		if((status = tpike_pack_out(outarr, 1, TPIKE_DTYPE_STRUCTVCHAR, &outp)) == TPIKE_STATUS_SUCCESS) {
+
+			*psk = vmalloc(((vchar_t *)outp)->l);
+			memcpy((*psk)->v, ((vchar_t *)outp)->v, ((vchar_t *)outp)->l);
+		}
+	}
+
+	return status;
+}
+#endif // PLUGINS_SUPPORT
Index: ipsec-tools-0.7.3/src/racoon/ipsec_doi.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/ipsec_doi.c
+++ ipsec-tools-0.7.3/src/racoon/ipsec_doi.c
@@ -97,6 +97,13 @@ static int switch_authmethod(int);
 #endif
 #endif
 
+#ifdef PLUGINS_SUPPORT
+#include "plugin_frame/common.h"
+#include "plugin_frame/framework.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif
+
 int verbose_proposal_check = 1;
 
 static vchar_t *get_ph1approval __P((struct ph1handle *, struct prop_pair **));
@@ -160,6 +167,13 @@ static vchar_t *setph2proposal0 __P((con
 
 static vchar_t *getidval __P((int, vchar_t *));
 
+#ifdef PLUGINS_SUPPORT
+static int plugin_generate_idval __P((u_int8_t, u_int8_t, vchar_t **));
+static int plugin_check_attr_ipsec __P((struct isakmp_data *, int));
+static int plugin_check_attr_isakmp __P((struct isakmp_data *data, int type));
+#endif
+
+
 #ifdef HAVE_GSSAPI
 static struct isakmpsa *fixup_initiator_sa __P((struct isakmpsa *,
 	struct isakmpsa *));
@@ -1214,6 +1228,12 @@ found:
 		if (!x)
 			goto err;	/* XXX */
 
+#ifdef PLUGINS_SUPPORT
+		if (iph2->ph1->natt_flags & NAT_DETECTED) {
+			sp->udp_encap = 1;
+		}
+#endif
+
 		n = racoon_calloc(1, sizeof(struct prop_pair));
 		if (n == NULL) {
 			plog(LLV_ERROR, LOCATION, NULL,
@@ -2059,6 +2079,10 @@ check_attr_isakmp(trns)
 	int tlen;
 	int flag, type;
 	u_int16_t lorv;
+#ifdef PLUGINS_SUPPORT
+	int status = TPIKE_STATUS_SUCCESS;
+#endif
+
 
 	tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
 	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
@@ -2229,9 +2253,16 @@ check_attr_isakmp(trns)
 			break;
 
 		default:
-			plog(LLV_ERROR, LOCATION, NULL,
-				"invalid attribute type %d.\n", type);
-			return -1;
+#ifdef PLUGINS_SUPPORT
+			status = plugin_check_attr_isakmp(d, type);
+			if(status == TPIKE_ERR_HASH_MATCH_NOT_FOUND || status == TPIKE_ERR_HASH_TABLE_OVERFLOW) {
+#endif
+				plog(LLV_ERROR, LOCATION, NULL,
+						"invalid attribute type %d.\n", type);
+				return -1;
+#ifdef PLUGINS_SUPPORT
+			}
+#endif
 		}
 
 		if (flag) {
@@ -2275,6 +2306,9 @@ check_attr_ipsec(proto_id, trns)
 	int flag, type = 0;
 	u_int16_t lorv;
 	int attrseen[16];	/* XXX magic number */
+#ifdef PLUGINS_SUPPORT
+	int status = TPIKE_STATUS_SUCCESS;
+#endif
 
 	tlen = ntohs(trns->h.len) - sizeof(struct isakmp_pl_t);
 	d = (struct isakmp_data *)((caddr_t)trns + sizeof(struct isakmp_pl_t));
@@ -2453,9 +2487,16 @@ ahmismatch:
 			return -1;
 
 		default:
-			plog(LLV_ERROR, LOCATION, NULL,
-				"invalid attribute type %d.\n", type);
-			return -1;
+#ifdef PLUGINS_SUPPORT
+			status = plugin_check_attr_ipsec(d, type);
+			if(status == TPIKE_ERR_HASH_MATCH_NOT_FOUND || status == TPIKE_ERR_HASH_TABLE_OVERFLOW) {
+#endif
+				plog(LLV_ERROR, LOCATION, NULL,
+						"invalid attribute type %d.\n", type);
+				return -1;
+#ifdef PLUGINS_SUPPORT
+			}
+#endif
 		}
 
 		if (flag) {
@@ -2737,7 +2778,11 @@ setph1trns(sa, buf)
 	}
 
 	attrlen = setph1attr(sa, p);
+#ifdef PLUGINS_SUPPORT
+	trnslen += attrlen + ((sa->pluginikeattribs) ? sa->pluginikeattribs->l : 0);
+#else
 	trnslen += attrlen;
+#endif
 	if (buf)
 		p += attrlen;
 
@@ -2754,6 +2799,10 @@ setph1attr(sa, buf)
 {
 	caddr_t p = buf;
 	int attrlen = 0;
+#ifdef PLUGINS_SUPPORT
+	struct isakmp_data *attrib = NULL;
+	int lenread = 0, dlen = 0;
+#endif
 
 	if (sa->lifetime) {
 		u_int32_t lifetime = htonl((u_int32_t)sa->lifetime);
@@ -2854,6 +2903,26 @@ setph1attr(sa, buf)
 		break;
 	}
 
+#ifdef PLUGINS_SUPPORT
+	//check if the plugin has any attribs to send
+	if(buf && sa->pluginikeattribs)
+	{
+		lenread = 0;
+		for( ; lenread < sa->pluginikeattribs->l; lenread += (sizeof(struct isakmp_data) + dlen))
+		{
+			attrib = (struct isakmp_data *)(sa->pluginikeattribs->v + lenread);
+			if(attrib->type & ISAKMP_GEN_TV) {
+				p = isakmp_set_attr_l(p, (attrib->type & ~ISAKMP_GEN_MASK), attrib->lorv);
+				dlen = 0;
+			}
+			else {
+				p = isakmp_set_attr_v(p, attrib->type, (caddr_t)(attrib + 1), attrib->lorv );
+				dlen = attrib->lorv;
+			}
+		}
+	}
+#endif
+
 #ifdef HAVE_GSSAPI
 	if (sa->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
 	    sa->gssid != NULL) {
@@ -3439,39 +3508,39 @@ ipsecdoi_chkcmpids( idt, ids, exact )
 	{
 		/*
 		 * special exception for comparing
-                 * address to subnet id types when
-                 * the netmask is address length
-                 */
+		 * address to subnet id types when
+		 * the netmask is address length
+		 */
 
 		if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR)&&
-		    (id_bt->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)) {
+				(id_bt->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)) {
 			result = ipsecdoi_subnetisaddr_v4(&ident_t,&ident_s);
 			goto cmpid_result;
 		}
 
 		if ((id_bs->type == IPSECDOI_ID_IPV4_ADDR_SUBNET)&&
-		    (id_bt->type == IPSECDOI_ID_IPV4_ADDR)) {
+				(id_bt->type == IPSECDOI_ID_IPV4_ADDR)) {
 			result = ipsecdoi_subnetisaddr_v4(&ident_s,&ident_t);
 			goto cmpid_result;
 		}
 
 #ifdef INET6
 		if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR)&&
-		    (id_bt->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
+				(id_bt->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
 			result = ipsecdoi_subnetisaddr_v6(&ident_t,&ident_s);
 			goto cmpid_result;
 		}
 
 		if ((id_bs->type == IPSECDOI_ID_IPV6_ADDR_SUBNET)&&
-		    (id_bt->type == IPSECDOI_ID_IPV6_ADDR)) {
+				(id_bt->type == IPSECDOI_ID_IPV6_ADDR)) {
 			result = ipsecdoi_subnetisaddr_v6(&ident_s,&ident_t);
 			goto cmpid_result;
 		}
 #endif
 		plog(LLV_DEBUG, LOCATION, NULL,
-			"check and compare ids : id type mismatch %s != %s\n",
-			s_ipsecdoi_ident(id_bs->type),
-			s_ipsecdoi_ident(id_bt->type));
+				"check and compare ids : id type mismatch %s != %s\n",
+				s_ipsecdoi_ident(id_bs->type),
+				s_ipsecdoi_ident(id_bt->type));
 
 		return 1;
 	}
@@ -3487,8 +3556,8 @@ ipsecdoi_chkcmpids( idt, ids, exact )
 	/* compare the ID data. */
 
 	switch (id_bt->type) {
-	        case IPSECDOI_ID_DER_ASN1_DN:
-        	case IPSECDOI_ID_DER_ASN1_GN:
+		case IPSECDOI_ID_DER_ASN1_DN:
+		case IPSECDOI_ID_DER_ASN1_GN:
 			/* compare asn1 ids */
 			result = eay_cmp_asn1dn(&ident_t, &ident_s);
 			goto cmpid_result;
@@ -3496,7 +3565,7 @@ ipsecdoi_chkcmpids( idt, ids, exact )
 		case IPSECDOI_ID_IPV4_ADDR:
 			/* validate lengths */
 			if ((ident_t.l != sizeof(struct in_addr))||
-			    (ident_s.l != sizeof(struct in_addr)))
+					(ident_s.l != sizeof(struct in_addr)))
 				goto cmpid_invalid;
 			break;
 
@@ -3504,7 +3573,7 @@ ipsecdoi_chkcmpids( idt, ids, exact )
 		case IPSECDOI_ID_IPV4_ADDR_RANGE:
 			/* validate lengths */
 			if ((ident_t.l != (sizeof(struct in_addr)*2))||
-			    (ident_s.l != (sizeof(struct in_addr)*2)))
+					(ident_s.l != (sizeof(struct in_addr)*2)))
 				goto cmpid_invalid;
 			break;
 
@@ -3512,7 +3581,7 @@ ipsecdoi_chkcmpids( idt, ids, exact )
 		case IPSECDOI_ID_IPV6_ADDR:
 			/* validate lengths */
 			if ((ident_t.l != sizeof(struct in6_addr))||
-			    (ident_s.l != sizeof(struct in6_addr)))
+					(ident_s.l != sizeof(struct in6_addr)))
 				goto cmpid_invalid;
 			break;
 
@@ -3520,7 +3589,7 @@ ipsecdoi_chkcmpids( idt, ids, exact )
 		case IPSECDOI_ID_IPV6_ADDR_RANGE:
 			/* validate lengths */
 			if ((ident_t.l != (sizeof(struct in6_addr)*2))||
-			    (ident_s.l != (sizeof(struct in6_addr)*2)))
+					(ident_s.l != (sizeof(struct in6_addr)*2)))
 				goto cmpid_invalid;
 			break;
 #endif
@@ -3531,8 +3600,8 @@ ipsecdoi_chkcmpids( idt, ids, exact )
 
 		default:
 			plog(LLV_ERROR, LOCATION, NULL,
-				"Unhandled id type %i specified for comparison\n",
-				id_bt->type);
+					"Unhandled id type %i specified for comparison\n",
+					id_bt->type);
 			return -1;
 	}
 
@@ -3752,6 +3821,9 @@ ipsecdoi_setid1(iph1)
 	struct ipsecdoi_id_b id_b;
 	vchar_t *ident = NULL;
 	struct sockaddr *ipid = NULL;
+#ifdef PLUGINS_SUPPORT
+	int status = TPIKE_STATUS_SUCCESS;
+#endif
 
 	/* init */
 	id_b.proto_id = 0;
@@ -3769,7 +3841,15 @@ ipsecdoi_setid1(iph1)
 		break;
 	case IDTYPE_KEYID:
 		id_b.type = IPSECDOI_ID_KEY_ID;
+#ifdef PLUGINS_SUPPORT
+		status = plugin_generate_idval(iph1->etype, iph1->side, &ident);
+		if(status == TPIKE_ERR_HASH_MATCH_NOT_FOUND || status == TPIKE_ERR_HASH_TABLE_OVERFLOW)
+		{
+#endif
 		ident = getidval(iph1->rmconf->idvtype, iph1->rmconf->idv);
+#ifdef PLUGINS_SUPPORT
+		}
+#endif
 		break;
 	case IDTYPE_ASN1DN:
 		id_b.type = IPSECDOI_ID_DER_ASN1_DN;
@@ -4238,6 +4318,48 @@ ipsecdoi_sockrange2id(laddr, haddr, ul_p
 	return new;
 }
 
+extern vchar_t *
+get_ipsecdoi_id(addr, proto)
+	admin_com_addrinfo *addr;
+	u_int proto;
+{
+	vchar_t *id;
+
+	switch (addr->addrtype) {
+		case IPSECDOI_ID_IPV4_ADDR:
+		case IPSECDOI_ID_IPV6_ADDR:
+			return (ipsecdoi_sockaddr2id((struct sockaddr *)&(addr->addrt.addr),
+						sizeof(struct in_addr) << 3,
+						proto));
+			break;
+		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
+		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
+			return (ipsecdoi_sockaddr2id((struct sockaddr *)&(addr->addrt.addr),
+						sizeof(struct in_addr),
+						proto));
+			break;
+		case IPSECDOI_ID_IPV4_ADDR_RANGE:
+		case IPSECDOI_ID_IPV6_ADDR_RANGE:
+			return (ipsecdoi_sockrange2id((struct sockaddr *)&(addr->addrt.range.laddr),
+						(struct sockaddr *)&(addr->addrt.range.haddr),
+						proto));
+
+			break;
+		default:
+			break;
+	}
+	return NULL;
+}
+
+void
+ipsecdoi_idtype2doi(id)
+	vchar_t *id;
+{
+	int newtype = ((struct ipsecdoi_id_b *)id->v)->type;
+	if ((newtype = idtype2doi(newtype)) != 255)
+		((struct ipsecdoi_id_b *)id->v)->type = newtype;
+	return;
+}
 
 /*
  * create sockaddr structure from ID payload (buf).
@@ -4931,3 +5053,101 @@ switch_authmethod(authmethod)
 	return authmethod;
 }
 #endif
+#ifdef PLUGINS_SUPPORT
+int
+plugin_generate_idval(etype, side, idv)
+	u_int8_t etype;
+	u_int8_t side;
+	vchar_t **idv;
+{
+	struct hookpoint hpoint, *hp;
+	struct handlerinfo *hinfo;
+	vchar_t *outp = NULL;
+	void *inarr = NULL, *outarr = NULL;
+	u_int32_t myposition = 0, status = TPIKE_STATUS_SUCCESS;
+	char *keyval = NULL;
+
+	if(etype == ISAKMP_ETYPE_IDENT)
+		myposition = (side == INITIATOR) ? INITIATOR_SEND_THREE : RESPONDER_SEND_THREE;
+	else if(etype == ISAKMP_ETYPE_AGG || etype == ISAKMP_ETYPE_BASE)
+		myposition = (side == INITIATOR) ? INITIATOR_SEND_ONE : RESPONDER_SEND_ONE;
+	else
+	{
+		//invalid state - log it
+		return -2;  //frameowrk needs to define an error code for invalid state
+	}
+
+	hp = &hpoint;
+
+	mk_hookpoint(PAYLOAD_TYPE, ISAKMP_NPTYPE_ID, IPSECDOI_ID_KEY_ID, MAKE_POS2(etype, myposition, 0xff, 0xff), 0, 0, keyval, hp);
+
+	tpike_pack_in(&inarr, 0);
+
+	if((status = tpike_dispatch_generic(&hpoint, inarr, &outarr)) == TPIKE_STATUS_SUCCESS) {
+
+		if((status = tpike_pack_out(outarr, 1, TPIKE_DTYPE_STRUCTVCHAR, &outp)) == TPIKE_STATUS_SUCCESS) {
+			*idv = vmalloc(((vchar_t *)outp)->l);
+			memcpy((*idv)->v, ((vchar_t *)outp)->v, ((vchar_t *)outp)->l);
+		}
+	}
+	return status;
+}
+
+int plugin_check_attr_ipsec(struct isakmp_data *data, int type)
+{
+	struct hookpoint hpoint, *hp;
+	struct handlerinfo *hinfo;
+	vchar_t *outp = NULL;
+	void *inarr = NULL, *outarr = NULL;
+	u_int32_t myposition = 0, status = TPIKE_STATUS_SUCCESS;
+	void *keyval = NULL;
+
+	hp = &hpoint;
+	keyval = &type;
+
+	mk_hookpoint (ATTRIBUTE_TYPE,
+		   	IPSEC_ATTRIB_TYPE,
+		   	0,
+		   	MAKE_POS(ISAKMP_ETYPE_QUICK, TPIKE_MIDX_RESPONDER, TPIKE_MIDX_RECEIVE, 0, 0xff, 0xff),
+		   	1, sizeof(type), keyval, hp);
+
+	if ((status = tpike_pack_in(&inarr, 1, TPIKE_DTYPE_STRUCTISAKMPDATA, data) == TPIKE_STATUS_SUCCESS)) {
+
+		if((status = tpike_dispatch_generic(&hpoint, inarr, &outarr)) == TPIKE_STATUS_SUCCESS) {
+
+			tpike_pack_out(outarr, 0);
+		}
+	}
+
+	return status;
+}
+
+int plugin_check_attr_isakmp(struct isakmp_data *data, int type)
+{
+	struct hookpoint hpoint, *hp;
+	struct handlerinfo *hinfo;
+	vchar_t *outp = NULL;
+	void *inarr = NULL, *outarr = NULL;
+	u_int32_t myposition = 0, status = TPIKE_STATUS_SUCCESS;
+	void *keyval = NULL;
+
+	hp = &hpoint;
+	keyval = &type;
+
+	mk_hookpoint (ATTRIBUTE_TYPE,
+		   	ISAKMP_ATTRIB_TYPE,
+		   	0,
+		   	MAKE_POS(0, 0, TPIKE_MIDX_RECEIVE, 0, 0xff, 0xff),
+		   	1, sizeof(type), keyval, hp);
+
+	if ((status = tpike_pack_in(&inarr, 1, TPIKE_DTYPE_STRUCTISAKMPDATA, data) == TPIKE_STATUS_SUCCESS)) {
+
+		if((status = tpike_dispatch_generic(&hpoint, inarr, &outarr)) == TPIKE_STATUS_SUCCESS) {
+
+			tpike_pack_out(outarr, 0);
+		}
+	}
+
+	return status;
+}
+#endif
Index: ipsec-tools-0.7.3/src/racoon/ipsec_doi.h
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/ipsec_doi.h
+++ ipsec-tools-0.7.3/src/racoon/ipsec_doi.h
@@ -34,6 +34,8 @@
 #ifndef _IPSEC_DOI_H
 #define _IPSEC_DOI_H
 
+#include "admin.h"
+
 /* refered to RFC2407 */
 
 #define IPSEC_DOI 1
@@ -224,6 +226,8 @@ extern int ipsecdoi_id2sockaddr __P((vch
 extern char *ipsecdoi_id2str __P((const vchar_t *));
 extern vchar_t *ipsecdoi_sockrange2id __P((	struct sockaddr *,
 	struct sockaddr *, u_int));
+extern vchar_t *get_ipsecdoi_id __P((admin_com_addrinfo *, u_int));
+extern void ipsecdoi_idtype2doi __P((vchar_t *id));
 
 extern vchar_t *ipsecdoi_setph1proposal __P((struct isakmpsa *));
 extern int ipsecdoi_setph2proposal __P((struct ph2handle *));
Index: ipsec-tools-0.7.3/src/racoon/isakmp_agg.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_agg.c
+++ ipsec-tools-0.7.3/src/racoon/isakmp_agg.c
@@ -95,6 +95,13 @@
 #include "gssapi.h"
 #endif
 
+#ifdef PLUGINS_SUPPORT
+#include "plugin_frame/common.h"
+#include "plugin_frame/framework.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif
+
 /*
  * begin Aggressive Mode as initiator.
  */
@@ -134,7 +141,14 @@ agg_i1send(iph1, msg)
 #ifdef ENABLE_DPD
 	vchar_t *vid_dpd = NULL;
 #endif
-
+#ifdef PLUGINS_SUPPORT
+	void *inarr = NULL, *outarr = NULL;
+	struct isakmp_data *ikeattr = NULL;
+	int ikeattrlen = 0, *val = NULL ;
+	struct isakmpsa *prop = NULL;
+	struct hookpoint hpoint, *hp = NULL;
+	char *keyval = NULL;
+#endif
 
 	/* validity check */
 	if (msg != NULL) {
@@ -156,6 +170,30 @@ agg_i1send(iph1, msg)
 	if (ipsecdoi_setid1(iph1) < 0)
 		goto end;
 
+#ifdef PLUGINS_SUPPORT
+	//get the ike attribs from the registered plugins
+	hp = &hpoint;
+	mk_hookpoint(ATTRIBUTE_TYPE, IKE_ATTRIB_TYPE, /*ANY*/0, MAKE_POS(ISAKMP_ETYPE_AGG, TPIKE_MIDX_INITIATOR, TPIKE_MIDX_SEND, 0 /* Any. Change it to 1 */ , 0xff, 0xff), 0, 0, keyval, hp);
+
+	tpike_pack_in(&inarr, 0);
+
+	if(tpike_dispatch_generic(&hpoint, inarr, &outarr) == TPIKE_STATUS_SUCCESS) {
+
+		if (tpike_pack_out(outarr, 2, TPIKE_DTYPE_STRUCTISAKMPDATA, &ikeattr, TPIKE_DTYPE_INT32PT, &val) == TPIKE_STATUS_SUCCESS) {
+			ikeattrlen = *val;
+			//set ike attribs in all sa structures
+			prop = iph1->rmconf->proposal;
+			while(prop) {
+
+				prop->pluginikeattribs = vmalloc(ikeattrlen);
+				memcpy(prop->pluginikeattribs->v, ikeattr, ikeattrlen);
+
+				prop = prop->next;
+			}
+		}
+	}
+#endif
+
 	/* create SA payload for my proposal */
 	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
 	if (iph1->sa == NULL)
@@ -265,6 +303,9 @@ agg_i1send(iph1, msg)
 	 */
 	if (iph1->rmconf->nat_traversal) 
 		plist = isakmp_plist_append_natt_vids(plist, vid_natt);
+    else
+		vid_natt[0] = NULL;
+
 #endif
 #ifdef ENABLE_HYBRID
 	if (vid_xauth)
@@ -282,6 +323,10 @@ agg_i1send(iph1, msg)
 	}
 #endif
 
+#ifdef PLUGINS_SUPPORT
+	plist = isakmp_plist_insert_vendorid_payload(plist, iph1, INITIATOR_SEND_ONE);
+#endif
+
 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
 
 #ifdef HAVE_PRINT_ISAKMP_C
@@ -364,6 +409,11 @@ agg_i2recv(iph1, msg)
 	TAILQ_INIT(&natd_tree);
 #endif
 
+#ifdef PLUGINS_SUPPORT
+	int status = TPIKE_STATUS_SUCCESS;
+	void *resp = NULL;
+#endif
+
 	/* validity check */
 	if (iph1->status != PHASE1ST_MSG1SENT) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -425,6 +475,19 @@ agg_i2recv(iph1, msg)
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
+#ifdef PLUGINS_SUPPORT
+			//status = verify_payload(ISAKMP_NPTYPE_VID, ISAKMP_ETYPE_AGG, TPIKE_MIDX_INITIATOR, TPIKE_MIDX_RECEIVE, 1, (void *)pa->ptr,(void **) &resp);
+			status = verify_payload(ISAKMP_NPTYPE_VID, ISAKMP_ETYPE_AGG, TPIKE_MIDX_INITIATOR, TPIKE_MIDX_RECEIVE, 1, (void *)pa->ptr,&resp);
+			if(status == TPIKE_STATUS_SUCCESS) {
+				if(((struct isakmp_data *)resp)->type == PRIVATE_NATTVID_PAYLOAD_TYPE) {
+					//need to fill natt options
+					natt_handle_private_vendorid(iph1, (struct isakmp_data *)resp);
+				}
+				break;
+			}
+			else if(status != TPIKE_ERR_HASH_MATCH_NOT_FOUND && status != TPIKE_ERR_HASH_TABLE_OVERFLOW)
+				goto end;
+#endif
 			vid_numeric = check_vendorid(pa->ptr);
 #ifdef ENABLE_NATT
 			if (iph1->rmconf->nat_traversal && 
@@ -561,7 +624,12 @@ agg_i2recv(iph1, msg)
 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
 
 		if (iph1->natt_flags & NAT_DETECTED)
+#if 1
+			// Nortel changes hard coded here. to be in plugin later. Change header also
+			nortel_natt_float_ports(iph1);
+#else
 			natt_float_ports (iph1);
+#endif
 	}
 #endif
 
@@ -734,6 +802,7 @@ agg_i2send(iph1, msg)
 
 #ifdef ENABLE_NATT
 	/* generate NAT-D payloads */
+#if 0
 	if (NATT_AVAILABLE(iph1)) {
 		vchar_t *natd[2] = { NULL, NULL };
 
@@ -760,6 +829,7 @@ agg_i2send(iph1, msg)
 		    natd[1], iph1->natt_options->payload_nat_d);
 	}
 #endif
+#endif
 
 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
 
@@ -812,6 +882,10 @@ agg_r1recv(iph1, msg)
 #ifdef HAVE_GSSAPI
 	vchar_t *gsstoken = NULL;
 #endif
+#ifdef PLUGINS_SUPPORT
+	int status = TPIKE_STATUS_SUCCESS;
+	void *resp = NULL;
+#endif
 
 	/* validity check */
 	if (iph1->status != PHASE1ST_START) {
@@ -860,6 +934,18 @@ agg_r1recv(iph1, msg)
 				goto end;
 			break;
 		case ISAKMP_NPTYPE_VID:
+#ifdef PLUGINS_SUPPORT
+			status = verify_payload(ISAKMP_NPTYPE_VID, ISAKMP_ETYPE_AGG, TPIKE_MIDX_RESPONDER, TPIKE_MIDX_RECEIVE, ONE, (void *)pa->ptr, &resp);
+			if(status == TPIKE_STATUS_SUCCESS) {
+				if(((struct isakmp_data *)resp)->type == PRIVATE_NATTVID_PAYLOAD_TYPE) {
+					//need to fill natt options
+					natt_handle_private_vendorid(iph1, (struct isakmp_data *)resp);
+				}
+				break;
+			}
+			else if(status != TPIKE_ERR_HASH_MATCH_NOT_FOUND && status != TPIKE_ERR_HASH_TABLE_OVERFLOW)
+				goto end;
+#endif
 			vid_numeric = check_vendorid(pa->ptr);
 
 #ifdef ENABLE_NATT
@@ -1311,6 +1397,9 @@ agg_r1send(iph1, msg)
 		plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
 #endif
 
+#ifdef PLUGINS_SUPPORT
+	plist = isakmp_plist_insert_vendorid_payload(plist, iph1, RESPONDER_SEND_ONE);
+#endif
 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
 
 #ifdef HAVE_PRINT_ISAKMP_C
Index: ipsec-tools-0.7.3/src/racoon/nattraversal.h
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/nattraversal.h
+++ ipsec-tools-0.7.3/src/racoon/nattraversal.h
@@ -79,9 +79,19 @@ vchar_t *natt_hash_addr (struct ph1handl
 int natt_compare_addr_hash (struct ph1handle *iph1, vchar_t *natd_received, int natd_seq);
 int natt_udp_encap (int encmode);
 int natt_fill_options (struct ph1natt_options *opts, int version);
+
+#if 1
+// Nortel changes hard coded here. to be in plugin later.
+void nortel_natt_float_ports (struct ph1handle *iph1);
+#endif
+
 void natt_float_ports (struct ph1handle *iph1);
 void natt_handle_vendorid (struct ph1handle *iph1, int vid_numeric);
 
+#ifdef PLUGINS_SUPPORT
+void natt_handle_private_vendorid(struct ph1handle *ph1, void *resp);
+int plugin_update_natt_options(struct ph2handle *ph2, int sendorrecv);
+#endif
 
 struct payload_list *
 isakmp_plist_append_natt_vids (struct payload_list *plist, vchar_t *vid_natt[MAX_NATT_VID_COUNT]);
Index: ipsec-tools-0.7.3/src/racoon/nattraversal.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/nattraversal.c
+++ ipsec-tools-0.7.3/src/racoon/nattraversal.c
@@ -68,6 +68,13 @@
 #include "nattraversal.h"
 #include "grabmyaddr.h"
 
+#ifdef PLUGINS_SUPPORT
+#include "plugin_frame/common.h"
+#include "plugin_frame/framework.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif
+
 struct natt_ka_addrs {
   struct sockaddr	*src;
   struct sockaddr	*dst;
@@ -284,6 +291,48 @@ natt_fill_options (struct ph1natt_option
   return 0;
 }
 
+struct ph2natt globalNatt;
+
+#ifdef PLUGINS_SUPPORT
+int plugin_update_natt_options(struct ph2handle *ph2, int sendorrecv)
+{
+	struct hookpoint hpoint, *hp;
+	struct handlerinfo *hinfo;
+	struct ph2natt *natt;
+	void *outarr = NULL, *inarr = NULL;
+	int index = 0, incount = 0;
+	u_int8_t side;
+	u_int32_t position = 0, status = TPIKE_STATUS_SUCCESS;
+	char *keyval = NULL;
+
+	hp = &hpoint;
+
+	side = (ph2->side == INITIATOR) ? TPIKE_MIDX_INITIATOR : TPIKE_MIDX_RESPONDER ;
+	mk_hookpoint(NATT_OPTIONS_TYPE, 0, /*ANY*/0, MAKE_POS(ISAKMP_ETYPE_QUICK, side, sendorrecv, 0, 0xff, 0xff), 0, 0, keyval, hp);
+
+	if((status = tpike_pack_in(&inarr, 0)) == TPIKE_STATUS_SUCCESS) {
+
+		if((status = tpike_dispatch_generic(&hpoint, inarr, &outarr)) == TPIKE_STATUS_SUCCESS) {
+
+			if((status = tpike_pack_out(outarr, 1, TPIKE_DTYPE_STRUCTNATTOPTIONS, &natt)
+			   ) == TPIKE_STATUS_SUCCESS) {
+				if (ph2->ph1 && ph2->ph1->natt_options)
+				{
+					ph2->ph1->natt_options->encaps_type = natt->type;
+					//set_port(ph2->ph1->local, natt->sport);
+					//set_port(ph2->ph1->remote, natt->dport);
+					globalNatt.sport=natt->sport;
+					globalNatt.dport=natt->dport;
+
+				}
+			}
+		}
+
+	}
+	return status;
+}
+#endif
+
 void
 natt_float_ports (struct ph1handle *iph1)
 {
@@ -303,6 +352,19 @@ natt_float_ports (struct ph1handle *iph1
 }
 
 void
+nortel_natt_float_ports (struct ph1handle *iph1)
+{
+	if (! (iph1->natt_flags && NAT_DETECTED) )
+		return;
+	if (! iph1->natt_options->float_port){
+		/* Drafts 00 / 01, just schedule keepalive */
+		natt_keepalive_add_ph1 (iph1);
+		return;
+	}
+	natt_keepalive_add (iph1->local, iph1->remote);
+}
+
+void
 natt_handle_vendorid (struct ph1handle *iph1, int vid_numeric)
 {
   if (! iph1->natt_options)
@@ -328,6 +390,31 @@ natt_keepalive_delete (struct natt_ka_ad
   racoon_free (ka);
 }
 
+#ifdef PLUGINS_SUPPORT
+void
+natt_handle_private_vendorid (struct ph1handle *iph1, void *d)
+{
+	struct isakmp_data *data = (struct isakmp_data *)d;
+
+	if (! iph1->natt_options)
+		iph1->natt_options = racoon_calloc (1, sizeof (*iph1->natt_options));
+
+	if (! iph1->natt_options) {
+		plog (LLV_ERROR, LOCATION, NULL,
+				"Allocating memory for natt_options failed!\n");
+		return;
+	}
+
+	if(!data)
+		return;
+	if(data->lorv) {
+		memcpy(iph1->natt_options, data + 1, data->lorv);
+		iph1->natt_flags |= NAT_ANNOUNCED;
+		iph1->natt_flags |= NAT_DETECTED;
+	}
+}
+#endif
+
 /* NAT keepalive functions */
 static void
 natt_keepalive_send (void *param)
Index: ipsec-tools-0.7.3/src/racoon/pfkey.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/pfkey.c
+++ ipsec-tools-0.7.3/src/racoon/pfkey.c
@@ -100,6 +100,15 @@
 #include "crypto_openssl.h"
 #include "grabmyaddr.h"
 
+#ifdef PLUGINS_SUPPORT
+//EVT - remove this after private events
+#include "evt.h"
+#include "plugin_frame/common.h"
+#include "plugin_frame/framework.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif
+
 #if defined(SADB_X_EALG_RIJNDAELCBC) && !defined(SADB_X_EALG_AESCBC)
 #define SADB_X_EALG_AESCBC  SADB_X_EALG_RIJNDAELCBC
 #endif
@@ -185,6 +194,9 @@ static int addnewsp __P((caddr_t *));
 #endif
 #endif
 
+int assignedinPolicySPID;
+int assignedoutPolicySPID;
+
 /*
  * PF_KEY packet handler
  *	0: success
@@ -197,6 +209,11 @@ pfkey_handler()
 	int len;
 	caddr_t mhp[SADB_EXT_MAX + 1];
 	int error = -1;
+#ifdef PLUGINS_SUPPORT
+	void *inarr = NULL, *outarr = NULL;
+	struct hookpoint hpoint, *hp = NULL;
+	char *keyval = NULL;
+#endif
 
 	/* receive pfkey message. */
 	len = 0;
@@ -270,6 +287,25 @@ pfkey_handler()
 		goto end;
 
 	error = 0;
+#ifdef PLUGINS_SUPPORT
+	//get the ike attribs from the registered plugins
+	hp = &hpoint;
+	mk_hookpoint(PFKEY_MSG_TYPE, msg->sadb_msg_type, /*ANY*/0, MAKE_POS(ISAKMP_ETYPE_ALL, TPIKE_MIDX_ANY, TPIKE_MIDX_ANY, 0 /* Any. Change it to 1 */ , 0xff, 0xff), 0, 0, keyval, hp);
+
+	tpike_pack_in(&inarr, 0);
+
+	if(tpike_dispatch_generic(&hpoint, inarr, &outarr) == TPIKE_STATUS_SUCCESS) {
+
+		if (tpike_pack_out(outarr, 0) == TPIKE_STATUS_SUCCESS) {
+			plog(LLV_INFO, LOCATION, NULL, "PF_KEY message type %d notified to plugin\n", msg->sadb_msg_type);
+
+			;
+		}
+	}
+	else
+		plog(LLV_DEBUG2, LOCATION, NULL, "PF_KEY message type %d not registered by plugin\n", msg->sadb_msg_type);
+#endif
+
 end:
 	if (msg)
 		racoon_free(msg);
@@ -352,6 +388,75 @@ done:
 	return buf;
 }
 
+#ifdef ENABLE_AP_CLIENTMODE
+
+/*
+ * Adding policies to the SPD
+ * OUT:
+ *     0               : success
+ *     NEGATIVE        : error occured and errno returned.
+ */
+int
+pfkey_add_policy_to_SPD(srcaddr, prefs, dstaddr, prefd, proto, policyin, policyout, seq)
+	struct sockaddr *srcaddr, *dstaddr;
+	u_int prefs, prefd, proto;
+	caddr_t policyin, policyout;
+	u_int32_t seq;
+{
+	int pfkey_so;
+	struct sadb_msg *msg;
+	caddr_t mhp[SADB_EXT_MAX + 1]; //some null ptr check to be done in failure case
+
+
+	if((pfkey_so = pfkey_open()) < 0){
+		plog(LLV_ERROR, LOCATION, NULL,"pfkey_open failed\n");
+		return -1;
+	}
+
+	if(pfkey_send_spdadd(pfkey_so, srcaddr, prefs,dstaddr, prefd, proto, policyout, ipsec_get_policylen(policyout), 0) < 0){                                                        plog(LLV_ERROR, LOCATION, NULL,"pfkey_send_spadd failed\n");
+		pfkey_close(pfkey_so);
+		return -2;
+	}
+	else{
+		//pfkey_send_spadd succeeded - retrieve SP ID value
+		if((msg = pfkey_recv(pfkey_so)) == NULL){
+			plog(LLV_ERROR, LOCATION, NULL,"pfkey_recv failed\n");
+		}
+		if(pfkey_align(msg,mhp) < 0){
+			plog(LLV_ERROR, LOCATION, NULL,"pfkey_align failed\n");
+		}
+		//temporary
+		else{
+			//assignedoutPolicySPID = ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
+		}
+	}
+
+	if(pfkey_send_spdadd(pfkey_so, dstaddr, prefd, srcaddr, prefs, proto, policyin, ipsec_get_policylen(policyin), 0) < 0){
+		//delete the added rule
+		pfkey_send_spddelete(pfkey_so, srcaddr, prefs,dstaddr, prefd, proto, policyout, ipsec_get_policylen(policyout), 0);
+		plog(LLV_ERROR, LOCATION, NULL,"pfkey_send_spadd failed\n");
+		pfkey_close(pfkey_so);
+		return -3;
+	}
+	else{
+		if((msg = pfkey_recv(pfkey_so)) == NULL){
+			plog(LLV_ERROR, LOCATION, NULL,"pfkey_recv failed\n");
+		}
+		if(pfkey_align(msg,mhp) < 0){
+			plog(LLV_ERROR, LOCATION, NULL,"pfkey_align failed\n");
+		}
+		//temporary
+		else{
+			//assignedinPolicySPID = ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
+		}
+	}
+
+	pfkey_close(pfkey_so);
+
+	return 0;
+}
+#endif
+
 #ifdef ENABLE_ADMINPORT
 /*
  * flush SADB
@@ -1020,6 +1125,7 @@ pk_recvgetspi(mhp)
 /*
  * set inbound SA
  */
+extern struct ph2natt globalNatt;
 int
 pk_sendupdate(iph2)
 	struct ph2handle *iph2;
@@ -1107,8 +1213,15 @@ pk_sendupdate(iph2)
 #ifdef ENABLE_NATT
 		if (pr->udp_encap) {
 			sa_args.l_natt_type = iph2->ph1->natt_options->encaps_type;
-			sa_args.l_natt_sport = extract_port (iph2->ph1->remote);
-			sa_args.l_natt_dport = extract_port (iph2->ph1->local);
+
+			if (globalNatt.sport != 0 && globalNatt.dport != 0) {
+				sa_args.l_natt_sport = globalNatt.sport;
+				sa_args.l_natt_dport = globalNatt.dport;
+			} else {
+				sa_args.l_natt_sport = extract_port (iph2->ph1->remote);
+				sa_args.l_natt_dport = extract_port (iph2->ph1->local);
+			}
+
 			sa_args.l_natt_oa = NULL;  // FIXME: Here comes OA!!!
 #ifdef SADB_X_EXT_NAT_T_FRAG
 			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
@@ -1252,6 +1365,10 @@ pk_recvupdate(mhp)
 				sadbsecas2str(iph2->dst, iph2->src,
 					msg->sadb_msg_satype, sa->sadb_sa_spi,
 					sa_mode));
+#ifdef PLUGINS_SUPPORT
+//EVT - remove this after private events
+			EVT_PUSH(iph2->dst, iph2->src, EVTT_PHASE2_UP, NULL);
+#endif
 		}
 
 		if (pr->ok == 0)
@@ -1396,8 +1513,16 @@ pk_sendadd(iph2)
 
 		if (pr->udp_encap) {
 			sa_args.l_natt_type = UDP_ENCAP_ESPINUDP;
-			sa_args.l_natt_sport = extract_port(iph2->ph1->local);
-			sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
+
+			if (globalNatt.sport != 0 && globalNatt.dport != 0) {
+				sa_args.l_natt_sport = globalNatt.sport;
+				sa_args.l_natt_dport = globalNatt.dport;
+			}
+			else{
+				sa_args.l_natt_sport = extract_port(iph2->ph1->local);
+				sa_args.l_natt_dport = extract_port(iph2->ph1->remote);
+			}
+
 			sa_args.l_natt_oa = NULL; // FIXME: Here comes OA!!!
 #ifdef SADB_X_EXT_NAT_T_FRAG
 			sa_args.l_natt_frag = iph2->ph1->rmconf->esp_frag;
@@ -1511,6 +1636,11 @@ pk_recvadd(mhp)
 		sadbsecas2str(iph2->src, iph2->dst,
 			msg->sadb_msg_satype, sa->sadb_sa_spi, sa_mode));
 
+#ifdef PLUGINS_SUPPORT
+//EVT - remove this after private events
+	EVT_PUSH(iph2->src, iph2->dst, EVTT_PHASE2_UP, NULL);
+#endif
+
 	plog(LLV_DEBUG, LOCATION, NULL, "===\n");
 	return 0;
 }
@@ -2218,6 +2348,8 @@ pk_recvspdupdate(mhp)
 	struct secpolicy *sp;
  	u_int64_t created;
 
+	plog(LLV_DEBUG, LOCATION, NULL, "call pk_recvspdupdate\n");
+
 	/* sanity check */
 	if (mhp[0] == NULL
 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
@@ -2340,6 +2472,8 @@ pk_recvspdadd(mhp)
 	struct secpolicy *sp;
 	u_int64_t created;
 
+	plog(LLV_DEBUG, LOCATION, NULL, "call pk_recvspdadd\n");
+
 	/* sanity check */
 	if (mhp[0] == NULL
 	 || mhp[SADB_EXT_ADDRESS_SRC] == NULL
@@ -2624,6 +2758,8 @@ pk_recvspddump(mhp)
 	struct secpolicy *sp;
 	u_int64_t created;
 
+	plog(LLV_DEBUG, LOCATION, NULL, "call pk_recvspddump\n");
+
 	/* sanity check */
 	if (mhp[0] == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -2872,6 +3008,8 @@ addnewsp(mhp)
 	struct sadb_lifetime *lt;
 	u_int64_t created;
 
+	plog(LLV_DEBUG, LOCATION, NULL, "call addnewsp\n");
+
 	/* sanity check */
 	if (mhp[SADB_EXT_ADDRESS_SRC] == NULL
 	 || mhp[SADB_EXT_ADDRESS_DST] == NULL
Index: ipsec-tools-0.7.3/src/racoon/pfkey.h
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/pfkey.h
+++ ipsec-tools-0.7.3/src/racoon/pfkey.h
@@ -44,6 +44,8 @@ extern const int pfkey_nsatypes;
 
 extern int pfkey_handler __P((void));
 extern vchar_t *pfkey_dump_sadb __P((int));
+
+extern int pfkey_add_policy_to_SPD __P((struct sockaddr *, u_int, struct sockaddr *, u_int, u_int, caddr_t, caddr_t, u_int32_t));
 extern void pfkey_flush_sadb __P((u_int));
 extern int pfkey_init __P((void));
 
Index: ipsec-tools-0.7.3/src/racoon/remoteconf.h
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/remoteconf.h
+++ ipsec-tools-0.7.3/src/racoon/remoteconf.h
@@ -146,9 +146,14 @@ struct isakmpsa {
 #ifdef HAVE_GSSAPI
 	vchar_t *gssid;
 #endif
+
 	int dh_group;			/* don't use it if aggressive mode */
 	struct dhgroup *dhgrp;		/* don't use it if aggressive mode */
 
+#ifdef PLUGINS_SUPPORT
+	vchar_t *pluginikeattribs;
+#endif
+
 	struct isakmpsa *next;		/* next transform */
 	struct remoteconf *rmconf;	/* backpointer to remoteconf */
 };
Index: ipsec-tools-0.7.3/src/racoon/sainfo.h
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/sainfo.h
+++ ipsec-tools-0.7.3/src/racoon/sainfo.h
@@ -71,6 +71,7 @@ struct sainfoalg {
 extern struct sainfo *getsainfo __P((const vchar_t *,
 	const vchar_t *, const vchar_t *, int));
 extern struct sainfo *newsainfo __P((void));
+extern struct sainfo *dupsainfo __P((struct sainfo *));
 extern void delsainfo __P((struct sainfo *));
 extern void inssainfo __P((struct sainfo *));
 extern void remsainfo __P((struct sainfo *));
@@ -79,6 +80,7 @@ extern void initsainfo __P((void));
 extern struct sainfoalg *newsainfoalg __P((void));
 extern void delsainfoalg __P((struct sainfoalg *));
 extern void inssainfoalg __P((struct sainfoalg **, struct sainfoalg *));
+extern struct sainfoalg *dupsainfoalg __P((struct sainfoalg *si));
 extern const char * sainfo2str __P((const struct sainfo *));
 
 extern void save_sainfotree __P((void));
Index: ipsec-tools-0.7.3/src/racoon/sainfo.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/sainfo.c
+++ ipsec-tools-0.7.3/src/racoon/sainfo.c
@@ -90,39 +90,39 @@ getsainfo(loc, rmt, peer, remoteid)
 	/* debug level output */
 	if(loglevel >= LLV_DEBUG) {
 		char *dloc, *drmt, *dpeer, *dclient;
- 
+
 		if (loc == NULL)
 			dloc = strdup("ANONYMOUS");
 		else
 			dloc = ipsecdoi_id2str(loc);
- 
+
 		if (rmt == NULL)
 			drmt = strdup("ANONYMOUS");
 		else
 			drmt = ipsecdoi_id2str(rmt);
- 
+
 		if (peer == NULL)
 			dpeer = strdup("NULL");
 		else
 			dpeer = ipsecdoi_id2str(peer);
- 
+
 		plog(LLV_DEBUG, LOCATION, NULL,
-			"getsainfo params: loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%i\n",
-			dloc, drmt, dpeer, remoteid );
- 
-                racoon_free(dloc);
-                racoon_free(drmt);
-                racoon_free(dpeer);
+				"getsainfo params: loc=\'%s\', rmt=\'%s\', peer=\'%s\', id=%i\n",
+				dloc, drmt, dpeer, remoteid );
+
+		racoon_free(dloc);
+		racoon_free(drmt);
+		racoon_free(dpeer);
 	}
 
-    again:
+again:
 	plog(LLV_DEBUG, LOCATION, NULL,
-		"getsainfo pass #%i\n", pass);
- 
+			"getsainfo pass #%i\n", pass);
+
 	LIST_FOREACH(s, &sitree, chain) {
 		const char *sainfostr = sainfo2str(s);
 		plog(LLV_DEBUG, LOCATION, NULL,
-			"evaluating sainfo: %s\n", sainfostr);
+				"evaluating sainfo: %s\n", sainfostr);
 
 		if(s->remoteid != remoteid)
 			continue;
@@ -148,7 +148,7 @@ getsainfo(loc, rmt, peer, remoteid)
 
 		/* compare the ids */
 		if (!ipsecdoi_chkcmpids(loc, s->idsrc, 0) &&
-		    !ipsecdoi_chkcmpids(rmt, s->iddst, 0))
+				!ipsecdoi_chkcmpids(rmt, s->iddst, 0))
 			return s;
 	}
 
@@ -171,7 +171,72 @@ newsainfo()
 
 	new->lifetime = IPSECDOI_ATTR_SA_LD_SEC_DEFAULT;
 	new->lifebyte = IPSECDOI_ATTR_SA_LD_KB_MAX;
+	new->id_i = NULL;
+
+	return new;
+}
+
+struct sainfo *
+dupsainfo(si)
+	struct sainfo *si;
+{
+	struct sainfo *new;
+	int alg_class = 0, ac = 0;
+
+	if (si == NULL){
+		plog(LLV_DEBUG, LOCATION, NULL,
+				"Request for copying Null sainfo received.");
+		return NULL;
+	}
+	new = racoon_calloc(1, sizeof(*new));
+	if (new == NULL){
+		plog(LLV_DEBUG, LOCATION, NULL,
+				"Failed to allocate memory for sainfo\n");
+		return NULL;
+	}
+
+	/* Copy idsrc and iddst */
+	if (si->idsrc != NULL){
+		new->idsrc = vmalloc(si->idsrc->l);
+		new->idsrc->l = si->idsrc->l;
+		memcpy(new->idsrc->v, si->idsrc->v, si->idsrc->l);
+	}
+
+	if (si->iddst != NULL){
+		new->iddst = vmalloc(si->iddst->l);
+		new->iddst->l = si->iddst->l;
+		memcpy(new->iddst->v, si->iddst->v, si->iddst->l);
+	}
 
+	/* Copy lifetime, lifebyte, pfs_group */
+	new->lifetime = si->lifetime;
+	new->lifebyte = si->lifebyte;
+	new->pfs_group = si->pfs_group;
+
+	/* Deep Copy sainfoalg structure */
+	for (alg_class = algclass_ipsec_enc;
+			alg_class <= algclass_isakmp_ameth;
+			alg_class++){
+		if (si->algs[alg_class] != NULL){
+			if (!(new->algs[alg_class]=dupsainfoalg(si->algs[alg_class]))){
+				delsainfoalg(new->algs[alg_class]);
+				if (new->idsrc != NULL)
+					racoon_free(new->idsrc);
+				if (new->iddst != NULL)
+					racoon_free(new->iddst);
+
+				/* Remove all the previously allocated sainfoalg classes */
+				for(ac=alg_class; ac<=0 ; ac--){
+					delsainfoalg(new->algs[ac]);
+				}
+
+				racoon_free(new);
+				plog(LLV_DEBUG, LOCATION, NULL,
+						"Failed to copy sainfoalg...\n");
+				return NULL;
+			}
+		}
+	}
 	return new;
 }
 
@@ -268,6 +333,20 @@ inssainfoalg(head, new)
 		*head = new;
 }
 
+struct sainfoalg *
+dupsainfoalg(alg)
+	struct sainfoalg *alg;
+{
+	struct sainfoalg *old, *new = NULL, *newhead = NULL;
+	for (old = alg; old; old = old->next) {
+		new = newsainfoalg();
+		memcpy(new, old, sizeof(struct sainfoalg));
+		new->next = NULL;
+		inssainfoalg(&newhead, new);
+	}
+	return newhead;
+}
+
 const char *
 sainfo2str(si)
 	const struct sainfo *si;
Index: ipsec-tools-0.7.3/src/racoon/isakmp_quick.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_quick.c
+++ ipsec-tools-0.7.3/src/racoon/isakmp_quick.c
@@ -87,11 +87,26 @@
 #include "admin.h"
 #include "strnames.h"
 
+#ifdef PLUGINS_SUPPORT
+#include "plugin_frame/common.h"
+#include "plugin_frame/framework.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif
+#ifdef ENABLE_NATT
+#include "nattraversal.h"
+#endif
+
 /* quick mode */
 static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *));
 static int get_sainfo_r __P((struct ph2handle *));
 static int get_proposal_r __P((struct ph2handle *));
 
+#if 1
+//shud be in plugin
+extern struct ph2natt globalNatt;
+#endif
+
 /* %%%
  * Quick Mode
  */
@@ -653,6 +668,13 @@ quick_i2send(iph2, msg0)
 		goto end;
 	}
 
+#ifdef PLUGINS_SUPPORT
+	//Does the vendor plugin have any NATT options
+	globalNatt.sport=0;
+	globalNatt.dport=0;
+	plugin_update_natt_options(iph2, TPIKE_MIDX_SEND);
+#endif
+
 	/* Do UPDATE for initiator */
 	plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
 	if (pk_sendupdate(iph2) < 0) {
@@ -796,6 +818,13 @@ quick_i3recv(iph2, msg0)
 		goto end;
 	}
 
+#ifdef PLUGINS_SUPPORT
+	//Does the vendor plugin have any NATT options
+	globalNatt.sport=0;
+	globalNatt.dport=0;
+	plugin_update_natt_options(iph2, TPIKE_MIDX_RECEIVE);
+#endif
+
 	/* Do UPDATE for initiator */
 	plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
 	if (pk_sendupdate(iph2) < 0) {
@@ -843,6 +872,13 @@ quick_r1recv(iph2, msg0)
 	int tlen;
 	int f_id_order;	/* for ID payload detection */
 	int error = ISAKMP_INTERNAL_ERROR;
+#ifdef PLUGINS_SUPPORT
+	void *inarr = NULL, *outarr = NULL;
+	int *val = NULL ;
+	struct hookpoint hpoint, *hp = NULL;
+	int isplecheckrqd = 0;
+	char *keyval = NULL;
+#endif
 
 	/* validity check */
 	if (iph2->status != PHASE2ST_START) {
@@ -1014,6 +1050,23 @@ quick_r1recv(iph2, msg0)
 		tlen += pa->len;
 	}
 
+#ifdef PLUGINS_SUPPORT
+	//Get to know if the registered plugins want the payload existency checks.
+	hp = &hpoint;
+	mk_hookpoint(IS_PLECHECK_TYPE, 0, /*ANY*/0, MAKE_POS(ISAKMP_ETYPE_QUICK, TPIKE_MIDX_RESPONDER, TPIKE_MIDX_RECEIVE, 0 /* Any. Change it to 1 */ , 0xff, 0xff), 0, 0, keyval, hp);
+
+	tpike_pack_in(&inarr, 0);
+
+	if(tpike_dispatch_generic(&hpoint, inarr, &outarr) == TPIKE_STATUS_SUCCESS) {
+
+		if (tpike_pack_out(outarr, 1, TPIKE_DTYPE_INT32PT, &val) == TPIKE_STATUS_SUCCESS)
+			isplecheckrqd = *val;
+	}
+
+	if(isplecheckrqd ){
+		plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, "PL E CHECK RQD.\n");
+#endif
+
 	/* payload existency check */
 	if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) {
 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
@@ -1021,6 +1074,12 @@ quick_r1recv(iph2, msg0)
 		error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
 		goto end;
 	}
+#ifdef PLUGINS_SUPPORT
+	}
+	else{
+		plog(LLV_DEBUG, LOCATION, iph2->ph1->remote, "PL E CHECK NOT RQD.\n");
+	}
+#endif
 
 	if (iph2->id_p) {
 		plog(LLV_DEBUG, LOCATION, NULL, "received IDci2:");
@@ -1117,6 +1176,25 @@ quick_r1recv(iph2, msg0)
 	/* change status of isakmp status entry */
 	iph2->status = PHASE2ST_STATUS2;
 
+#ifdef PLUGINS_SUPPORT
+	//get the ike attribs from the registered plugins
+	hp = &hpoint;
+	mk_hookpoint(IKE_NEGO_STATE_TYPE, 0, /*ANY*/0, MAKE_POS(ISAKMP_ETYPE_QUICK, TPIKE_MIDX_RESPONDER, TPIKE_MIDX_RECEIVE, 1 /* Any. Change it to 1 */ , 0xff, 0xff), 0, 0, keyval, hp);
+
+	tpike_pack_in(&inarr, 0);
+
+	if(tpike_dispatch_generic(&hpoint, inarr, &outarr) == TPIKE_STATUS_SUCCESS) {
+
+		if (tpike_pack_out(outarr, 0) == TPIKE_STATUS_SUCCESS) {
+			plog(LLV_INFO, LOCATION, NULL, "Quick Mode start message notified to plugin\n");
+			;
+		}
+	}
+	else
+		plog(LLV_DEBUG2, LOCATION, NULL, " Quick mode start message not registered by plugin\n");
+
+#endif
+
 	error = 0;
 
 end:
@@ -1641,6 +1719,13 @@ quick_r3prep(iph2, msg0)
 		goto end;
 	}
 
+#ifdef PLUGINS_SUPPORT
+	//Does the vendor plugin have any NATT options
+	globalNatt.sport=0;
+	globalNatt.dport=0;
+	plugin_update_natt_options(iph2, TPIKE_MIDX_ANY);
+#endif
+
 	/* Do UPDATE as responder */
 	plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
 	if (pk_sendupdate(iph2) < 0) {
Index: ipsec-tools-0.7.3/src/racoon/isakmp_var.h
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_var.h
+++ ipsec-tools-0.7.3/src/racoon/isakmp_var.h
@@ -111,6 +111,12 @@ extern struct payload_list *isakmp_plist
 extern vchar_t *isakmp_plist_set_all __P((struct payload_list **plist,
 	struct ph1handle *iph1));
 
+#ifdef PLUGINS_SUPPORT
+extern struct payload_list *isakmp_plist_insert_vendorid_payload __P((struct payload_list *plist, struct ph1handle *iph1, u_int8_t position));
+extern int verify_payload __P((u_int8_t payloadtype, u_int8_t etype, u_int8_t , u_int8_t, u_int8_t, void *pl, void **data));
+#endif
+
+
 #ifdef HAVE_PRINT_ISAKMP_C
 extern void isakmp_printpacket __P((vchar_t *, struct sockaddr *,
 	struct sockaddr *, int));
Index: ipsec-tools-0.7.3/src/racoon/isakmp_inf.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_inf.c
+++ ipsec-tools-0.7.3/src/racoon/isakmp_inf.c
@@ -98,6 +98,13 @@
 #include "nattraversal.h"
 #endif
 
+#ifdef PLUGINS_SUPPORT
+#include "plugin_frame/common.h"
+#include "plugin_frame/framework.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif
+
 /* information exchange */
 static int isakmp_info_recv_n (struct ph1handle *, struct isakmp_pl_n *, u_int32_t, int);
 static int isakmp_info_recv_d (struct ph1handle *, struct isakmp_pl_d *, u_int32_t, int);
@@ -418,6 +425,12 @@ isakmp_info_recv_n(iph1, notify, msgid,
 		racoon_free(spi);
 	}
 
+#ifdef PLUGINS_SUPPORT
+	if (type ==ISAKMP_NTYPE_AUTHENTICATION_FAILED){
+		evt_push(NULL,NULL,EVTT_XAUTH_FAILED,NULL);
+	}
+#endif
+
 	/* Send the message data to the logs */
 	if(type >= ISAKMP_NTYPE_MINERROR &&
 	   type <= ISAKMP_NTYPE_MAXERROR) {
@@ -794,6 +807,37 @@ isakmp_info_send_n1(iph1, type, data)
 	 * by cookie and SPI has no meaning, 0 <= SPI size <= 16.
 	 * RFC2407 4.6.3.3, INITIAL-CONTACT is required to set to 16.
 	 */
+#ifdef PLUGINS_SUPPORT
+	void *inarr = NULL, *outarr = NULL;
+	struct isakmp_data *ikeattr = NULL;
+	int ikeattrlen = 0, *val = NULL ;
+	struct isakmpsa *prop = NULL;
+	struct hookpoint hpoint, *hp = NULL;
+	char *keyval = NULL;
+
+	/* Initialize spisiz and n for stopping gcc to crib */
+	plog(LLV_INFO, LOCATION, NULL, "iN ISAKMP_INFO_SEND_N1");
+
+	spisiz = 0;
+	n = NULL;
+	//get the ike attribs from the registered plugins
+	hp = &hpoint;
+	mk_hookpoint(PAYLOAD_TYPE, ISAKMP_NPTYPE_NONE, /*ANY*/0, MAKE_POS(ISAKMP_ETYPE_INFO, TPIKE_MIDX_ANY, TPIKE_MIDX_ANY, 0 /* Any. Change it to 1 */ , 0xff, 0xff), 0, 0, keyval, hp) ;
+	tpike_pack_in(&inarr, 2, TPIKE_DTYPE_STRUCTIPH1, iph1, TPIKE_DTYPE_INT32PT, &type );
+
+	if(tpike_dispatch_generic(&hpoint, inarr, &outarr) == TPIKE_STATUS_SUCCESS) {
+
+		if (tpike_pack_out(outarr, 1, TPIKE_DTYPE_STRUCTVCHAR , &payload) == TPIKE_STATUS_SUCCESS) {
+			plog(LLV_DEBUG2, LOCATION, NULL,"Sending info payload got from plugin\n" );
+		}
+		else
+			goto normalpath;
+
+	}
+	else
+normalpath:
+	{
+#endif
 	if (type == ISAKMP_NTYPE_INITIAL_CONTACT)
 		spisiz = sizeof(isakmp_index);
 	else
@@ -822,7 +866,19 @@ isakmp_info_send_n1(iph1, type, data)
 		memcpy((caddr_t)(n + 1) + spisiz, data->v, data->l);
 
 	error = isakmp_info_send_common(iph1, payload, ISAKMP_NPTYPE_N, iph1->flags);
-	vfree(payload);
+
+#ifdef PLUGINS_SUPPORT
+	}
+	if (payload)
+	{
+		n = (struct isakmp_pl_n *)payload->v;
+
+		plog(LLV_DEBUG2,LOCATION,NULL,"h.np = %d, h.reserved = %d, h.len = %d, doi = %d, proto = %d, spi size = %d, type=%d, spi = %d\n ",  n->h.np, n->h.reserved, n->h.len, n->doi, n->proto_id, n->spi_size, n->type, *(u_int32_t *)(n+1));
+#endif
+		vfree(payload);
+#ifdef PLUGINS_SUPPORT
+	}
+#endif
 
 	return error;
 }
Index: ipsec-tools-0.7.3/src/racoon/isakmp_ident.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_ident.c
+++ ipsec-tools-0.7.3/src/racoon/isakmp_ident.c
@@ -90,6 +90,13 @@
 #include "isakmp_frag.h"
 #endif
 
+#ifdef PLUGINS_SUPPORT
+#include "plugin_frame/common.h"
+#include "plugin_frame/framework.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif
+
 static vchar_t *ident_ir2mx __P((struct ph1handle *));
 static vchar_t *ident_ir3mx __P((struct ph1handle *));
 
@@ -124,6 +131,16 @@ ident_i1send(iph1, msg)
 #ifdef ENABLE_DPD
 	vchar_t *vid_dpd = NULL;
 #endif
+
+#ifdef PLUGINS_SUPPORT
+	void *inarr = NULL, *outarr = NULL;
+	struct isakmp_data *ikeattr = NULL;
+	int ikeattrlen = 0, *val = NULL ;
+	struct isakmpsa *prop = NULL;
+	struct hookpoint hpoint, *hp = NULL;
+	char *keyval = NULL;
+#endif
+
 	/* validity check */
 	if (msg != NULL) {
 		plog(LLV_ERROR, LOCATION, NULL,
@@ -140,6 +157,30 @@ ident_i1send(iph1, msg)
 	memset(&iph1->index, 0, sizeof(iph1->index));
 	isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
 
+#ifdef PLUGINS_SUPPORT
+	//get the ike attribs from the registered plugins
+	hp = &hpoint;
+	mk_hookpoint(ATTRIBUTE_TYPE, IKE_ATTRIB_TYPE, /*ANY*/0, MAKE_POS(ISAKMP_ETYPE_IDENT, TPIKE_MIDX_INITIATOR, TPIKE_MIDX_SEND, 0 /* Any. Change it         to 1 */ , 0xff, 0xff), 0, 0, keyval, hp);
+
+	tpike_pack_in(&inarr, 0);
+
+	if(tpike_dispatch_generic(&hpoint, inarr, &outarr) == TPIKE_STATUS_SUCCESS)
+	{
+		if (tpike_pack_out(outarr, 2, TPIKE_DTYPE_STRUCTISAKMPDATA, &ikeattr, TPIKE_DTYPE_INT32PT, &val) == TPIKE_STATUS_SUCCESS)
+		{
+			ikeattrlen = *val;
+			//set ike attribs in all sa structures
+			prop = iph1->rmconf->proposal;
+			while(prop)
+			{
+				prop->pluginikeattribs = vmalloc(ikeattrlen);
+				memcpy(prop->pluginikeattribs->v, ikeattr, ikeattrlen);
+				prop = prop->next;
+			}
+		}
+	}
+#endif
+
 	/* create SA payload for my proposal */
 	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
 	if (iph1->sa == NULL)
@@ -152,6 +193,8 @@ ident_i1send(iph1, msg)
 	/* set VID payload for NAT-T if NAT-T support allowed in the config file */
 	if (iph1->rmconf->nat_traversal) 
 		plist = isakmp_plist_append_natt_vids(plist, vid_natt);
+	else
+		vid_natt[0]=NULL;
 #endif
 #ifdef ENABLE_HYBRID
 	/* Do we need Xauth VID? */
@@ -203,6 +246,9 @@ ident_i1send(iph1, msg)
 	}
 #endif
 
+#ifdef PLUGINS_SUPPORT
+	plist = (struct payload_list *)isakmp_plist_insert_vendorid_payload(plist, iph1, INITIATOR_SEND_ONE);
+#endif
 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
 
 #ifdef HAVE_PRINT_ISAKMP_C
@@ -258,6 +304,11 @@ ident_i2recv(iph1, msg)
 	vchar_t *satmp = NULL;
 	int error = -1;
 	int vid_numeric;
+#ifdef PLUGINS_SUPPORT
+	int status = TPIKE_STATUS_SUCCESS;
+	void *resp = NULL;
+#endif
+
 
 	/* validity check */
 	if (iph1->status != PHASE1ST_MSG1SENT) {
@@ -300,6 +351,20 @@ ident_i2recv(iph1, msg)
 		switch (pa->type) {
 		case ISAKMP_NPTYPE_VID:
 			vid_numeric = check_vendorid(pa->ptr);
+#ifdef PLUGINS_SUPPORT
+			//status = verify_payload(ISAKMP_NPTYPE_VID, ISAKMP_ETYPE_AGG, TPIKE_MIDX_INITIATOR, TPIKE_MIDX_RECEIVE, 1, (void *)pa->ptr,(void **) &resp);
+			status = verify_payload(ISAKMP_NPTYPE_VID, ISAKMP_ETYPE_IDENT, TPIKE_MIDX_INITIATOR, TPIKE_MIDX_RECEIVE, 1, (void *)pa->ptr,&resp);
+			if(status == TPIKE_STATUS_SUCCESS) {
+				if(((struct isakmp_data *)resp)->type == PRIVATE_NATTVID_PAYLOAD_TYPE) {
+					//need to fill natt options
+					natt_handle_private_vendorid(iph1, (struct isakmp_data *)resp);
+				}
+				break;
+			}
+			else if(status != TPIKE_ERR_HASH_MATCH_NOT_FOUND && status != TPIKE_ERR_HASH_TABLE_OVERFLOW)
+				goto end;
+#endif // PLUGINS_SUPPORT
+
 #ifdef ENABLE_NATT
 			if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
 			  natt_handle_vendorid(iph1, vid_numeric);
@@ -969,10 +1034,16 @@ ident_r1recv(iph1, msg)
 	}
 
 #ifdef ENABLE_NATT
-	if (NATT_AVAILABLE(iph1))
+	if (NATT_AVAILABLE(iph1)) {
 		plog(LLV_INFO, LOCATION, iph1->remote,
-		     "Selected NAT-T version: %s\n",
-		     vid_string_by_id(iph1->natt_options->version));
+				"Selected NAT-T version: %s\n",
+				vid_string_by_id(iph1->natt_options->version));
+
+		if(((struct sockaddr_in *)iph1->remote)->sin_port == htons(4500) && ((struct sockaddr_in *)iph1->local)->sin_port == htons(4500) ){
+			iph1->natt_flags |= NAT_PORTS_CHANGED;
+			plog (LLV_DEBUG2, LOCATION, NULL, "NON-ESP MARKER NON-ENFORCEMENT\n");
+		}
+	}
 #endif
 
 	/* check SA payload and set approval SA for use */
Index: ipsec-tools-0.7.3/src/racoon/isakmp_cfg.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/isakmp_cfg.c
+++ ipsec-tools-0.7.3/src/racoon/isakmp_cfg.c
@@ -105,6 +105,13 @@
 #include "admin.h"
 #include "privsep.h"
 
+#ifdef PLUGINS_SUPPORT
+#include "plugin_frame/framework.h"
+#include "plugin_frame/common.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif
+
 struct isakmp_cfg_config isakmp_cfg_config;
 
 static vchar_t *buffer_cat(vchar_t *s, vchar_t *append);
@@ -129,6 +136,12 @@ static int isakmp_cfg_accounting(struct
 static int isakmp_cfg_accounting_radius(struct ph1handle *, int);
 #endif
 
+#ifdef PLUGINS_SUPPORT
+static int isakmp_plugin_cfg_priv (struct ph1handle *iph1, struct isakmp_pl_attr *attrpl);
+static int isakmp_plugin_cfg_req (struct ph1handle *iph1, struct isakmp_data *attr, vchar_t **reply_attr);
+static int isakmp_plugin_cfg_set (struct ph1handle *iph1, struct isakmp_data *attr, vchar_t **reply_attr);
+
+#endif
 /* 
  * Handle an ISAKMP config mode packet
  * We expect HDR, HASH, ATTR
@@ -275,6 +288,9 @@ isakmp_cfg_attr_r(iph1, msgid, attrpl)
 	struct isakmp_pl_attr *attrpl;
 {
 	int type = attrpl->type;
+#ifdef PLUGINS_SUPPORT
+	int status = TPIKE_STATUS_SUCCESS;
+#endif
 
 	plog(LLV_DEBUG, LOCATION, NULL,
 	     "Configuration exchange type %s\n", s_isakmp_cfg_ptype(type));
@@ -301,9 +317,23 @@ isakmp_cfg_attr_r(iph1, msgid, attrpl)
 		break;
 
 	default:
+#ifdef PLUGINS_SUPPORT
+		iph1->msgid = msgid;
+		if((status = isakmp_plugin_cfg_priv(iph1, attrpl)) == TPIKE_STATUS_SUCCESS) {
+			//Temporary -  to make NORTEL work
+			oakley_delivm(iph1->mode_cfg->ivm);
+			iph1->mode_cfg->ivm = NULL;
+			//end Temporary
+			return status;
+		}
+		else {
+#endif
 		plog(LLV_WARNING, LOCATION, NULL,
 		     "Unepected configuration exchange type %d\n", type);
 		return -1;
+#ifdef PLUGINS_SUPPORT
+		}
+#endif
 		break;
 	}
 
@@ -497,6 +527,9 @@ isakmp_cfg_request(iph1, attrpl)
 	vchar_t *reply_attr;
 	int type;
 	int error = -1;
+#ifdef PLUGINS_SUPPORT
+	int status = TPIKE_STATUS_SUCCESS;
+#endif
 
 	if ((payload = vmalloc(sizeof(*reply))) == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
@@ -522,12 +555,26 @@ isakmp_cfg_request(iph1, attrpl)
 
 			switch (type) {
 			case XAUTH_TYPE:
+#ifdef PLUGINS_SUPPORT
+				status = isakmp_plugin_cfg_req(iph1, attr, &reply_attr);
+				if(status == TPIKE_ERR_HASH_MATCH_NOT_FOUND || status == TPIKE_ERR_HASH_TABLE_OVERFLOW) {
+#endif
 				reply_attr = isakmp_xauth_req(iph1, attr);
+#ifdef PLUGINS_SUPPORT
+				}
+#endif
 				break;
 			default:
+#ifdef PLUGINS_SUPPORT
+				status = isakmp_plugin_cfg_req(iph1, attr, &reply_attr);
+				if(status == TPIKE_ERR_HASH_MATCH_NOT_FOUND || status == TPIKE_ERR_HASH_TABLE_OVERFLOW) {
+#endif
 				plog(LLV_WARNING, LOCATION, NULL,
 				     "Ignored short attribute %s\n",
 				     s_isakmp_cfg_type(type));
+#ifdef PLUGINS_SUPPORT
+				}
+#endif
 				break;
 			}
 
@@ -576,7 +623,14 @@ isakmp_cfg_request(iph1, attrpl)
 		case XAUTH_STATUS:
 		case XAUTH_NEXT_PIN:
 		case XAUTH_ANSWER:
+#ifdef PLUGINS_SUPPORT
+			status = isakmp_plugin_cfg_req(iph1, attr, &reply_attr);
+			if(status == TPIKE_ERR_HASH_MATCH_NOT_FOUND || status == TPIKE_ERR_HASH_TABLE_OVERFLOW) {
+#endif
 			reply_attr = isakmp_xauth_req(iph1, attr);
+#ifdef PLUGINS_SUPPORT
+			}
+#endif
 			break;
 
 		case APPLICATION_VERSION:
@@ -600,9 +654,16 @@ isakmp_cfg_request(iph1, attrpl)
 
 		case INTERNAL_ADDRESS_EXPIRY:
 		default:
+#ifdef PLUGINS_SUPPORT
+			status = isakmp_plugin_cfg_req(iph1, attr, &reply_attr);
+			if(status == TPIKE_ERR_HASH_MATCH_NOT_FOUND || status == TPIKE_ERR_HASH_TABLE_OVERFLOW) {
+#endif
 			plog(LLV_WARNING, LOCATION, NULL,
 			     "Ignored attribute %s\n",
 			     s_isakmp_cfg_type(type));
+#ifdef PLUGINS_SUPPORT
+			}
+#endif
 			break;
 		}
 
@@ -665,6 +726,9 @@ isakmp_cfg_set(iph1, attrpl)
 	vchar_t *reply_attr;
 	int type;
 	int error = -1;
+#ifdef PLUGINS_SUPPORT
+        int status  = 0;
+#endif
 
 	if ((payload = vmalloc(sizeof(*reply))) == NULL) {
 		plog(LLV_ERROR, LOCATION, NULL, "Cannot allocate memory\n");
@@ -689,16 +753,34 @@ isakmp_cfg_set(iph1, attrpl)
 		
 		switch (type & ~ISAKMP_GEN_MASK) {
 		case XAUTH_STATUS:
+#ifdef PLUGINS_SUPPORT
+			status = isakmp_plugin_cfg_set(iph1, attr, &reply_attr);
+			if(status == TPIKE_ERR_HASH_MATCH_NOT_FOUND || status == TPIKE_ERR_HASH_TABLE_OVERFLOW) {
+#endif
 			reply_attr = isakmp_xauth_set(iph1, attr);
+#ifdef PLUGINS_SUPPORT
+			}
+#endif
 			break;
 		default:
+#ifdef PLUGINS_SUPPORT
+			status = isakmp_plugin_cfg_set(iph1, attr, &reply_attr);
+			if(status == TPIKE_ERR_HASH_MATCH_NOT_FOUND || status == TPIKE_ERR_HASH_TABLE_OVERFLOW) {
+#endif
 			plog(LLV_DEBUG, LOCATION, NULL,
 			     "Unexpected SET attribute %s\n", 
 		     	     s_isakmp_cfg_type(type & ~ISAKMP_GEN_MASK));
+#ifdef PLUGINS_SUPPORT
+			}
+#endif
 			break;
 		}
 
+#if 1
 		if (reply_attr != NULL) {
+#else
+		if ((reply_attr = vmalloc(sizeof(*reply_attr))) != NULL) {
+#endif
 			payload = buffer_cat(payload, reply_attr);
 			vfree(reply_attr);
 		}
@@ -724,6 +806,39 @@ isakmp_cfg_set(iph1, attrpl)
 	reply->type = ISAKMP_CFG_ACK;
 	reply->id = attrpl->id;
 
+#ifdef PLUGINS_SUPPORT
+	{
+		/* FIXME : is this correct to add a new subtype for ATTRIB_ACK hook */
+		/* before sending cfg ack */
+		void *outarr = NULL, *inarr = NULL, *keyval = NULL;
+		int status = TPIKE_STATUS_SUCCESS;
+		struct hookpoint * hp, hpoint;
+
+		hp = &hpoint;
+
+		mk_hookpoint(ATTRIBUTE_TYPE,
+			   	CONFIG_ATTRIB_ACK_TYPE,
+			   	ISAKMP_CFG_SET,
+			   	MAKE_POS(ISAKMP_ETYPE_CFG,
+				   	(iph1->side == INITIATOR) ? TPIKE_MIDX_INITIATOR : TPIKE_MIDX_RESPONDER,
+				   	TPIKE_MIDX_RECEIVE,
+				   	/*ANY*/0, 0xff, 0xff),
+			   	0, 0, keyval, hp);
+
+		if (! TPIKE_OK(status = tpike_pack_in(&inarr, 0)))
+			plog(LLV_WARNING, LOCATION, NULL, "packin failed\n");
+
+		if (TPIKE_OK (status)) {
+			if(! TPIKE_OK (status = tpike_dispatch_generic(&hpoint, inarr, &outarr)))
+				plog(LLV_WARNING, LOCATION, NULL, "dispatch failed \n");
+			if (TPIKE_OK (status)) {
+				if(! TPIKE_OK (status = tpike_pack_out(outarr, 0)))
+					plog(LLV_ERROR, LOCATION, NULL, "pack out failed\n");
+			}
+		}
+	}
+#endif
+
 	plog(LLV_DEBUG, LOCATION, NULL,
 		     "Sending MODE_CFG ACK\n");
 
@@ -2157,3 +2272,166 @@ isakmp_cfg_init(cold)
 	return 0;
 }
 
+#ifdef PLUGINS_SUPPORT
+int
+isakmp_plugin_cfg_req(iph1, attr, reply_attr)
+	struct ph1handle *iph1;
+	struct isakmp_data *attr;
+	vchar_t	**reply_attr;
+{
+	struct hookpoint hpoint, *hp = NULL;
+	struct isakmp_data *attrval = NULL, *temp = NULL;
+	vchar_t *value = NULL;
+	void *outarr = NULL, *inarr = NULL;
+	u_int16_t attrtype = 0;
+	int status = TPIKE_STATUS_SUCCESS;
+	int datalen = 0;
+	void *keyval = NULL;
+
+	attrtype = ntohs(attr->type);
+
+	if(attrtype & ISAKMP_GEN_TV)
+		attrtype = attrtype & ~ISAKMP_GEN_TV;
+
+	hp = &hpoint;
+	keyval = &attrtype;
+
+	mk_hookpoint (ATTRIBUTE_TYPE,
+		   	CONFIG_ATTRIB_TYPE,
+		   	ISAKMP_CFG_REQUEST,
+		   	MAKE_POS(ISAKMP_ETYPE_CFG,
+			   	(iph1->side == INITIATOR) ? TPIKE_MIDX_INITIATOR : TPIKE_MIDX_RESPONDER,
+			   	TPIKE_MIDX_RECEIVE,
+			   	/*ANY*/0, 0xff, 0xff),
+		   	1, sizeof(attrtype), keyval, hp);
+
+	tpike_pack_in(&inarr, 0);
+
+	if((status = tpike_dispatch_generic(&hpoint, inarr, &outarr)) == TPIKE_STATUS_SUCCESS) {
+
+		if((status = tpike_pack_out(outarr, 1, TPIKE_DTYPE_STRUCTISAKMPDATA, &attrval)) == TPIKE_STATUS_SUCCESS) {
+
+			if((attrval->type) & ISAKMP_GEN_TV)
+				datalen = 0;
+			else
+				datalen = attrval->lorv;
+			if((*reply_attr = vmalloc(sizeof(struct isakmp_data) + datalen)) == NULL)
+			{
+				//log & set error, and come out!
+				status = TPIKE_ERR_MEM_ALLOC_FAILED;
+				goto tpike_req_end;
+			}
+
+			value = *reply_attr;
+			temp = (struct isakmp_data *)value->v;
+			if(datalen == 0)	//its a TV value
+			{
+				temp->type = htons(attrval->type);
+				temp->lorv = attrval->lorv;
+			}
+			else
+			{
+				temp->type = htons(attrval->type);
+				temp->lorv = htons(datalen);
+				memcpy(temp + 1, attrval + 1, datalen);
+
+			}
+		}
+	}
+
+tpike_req_end:
+	return status; //should return status returned by plugin
+
+}
+
+int
+isakmp_plugin_cfg_set(iph1, attr, resp)
+	struct ph1handle *iph1;
+	struct isakmp_data *attr;
+	vchar_t	**resp;
+{
+	struct hookpoint hpoint, *hp;
+	struct isakmp_data *setresp = NULL, *temp = NULL;
+	vchar_t *value = NULL;
+	void *outarr = NULL, *inarr = NULL;
+	u_int16_t attrtype = 0;
+	int status = TPIKE_STATUS_SUCCESS;
+	int datalen = 0;
+
+	attrtype = ntohs(attr->type);
+
+	if(attrtype & ISAKMP_GEN_TV)
+		attrtype = attrtype & ~ISAKMP_GEN_TV;
+
+	hp = &hpoint;
+
+	mk_hookpoint(ATTRIBUTE_TYPE, CONFIG_ATTRIB_TYPE, ISAKMP_CFG_SET, MAKE_POS(ISAKMP_ETYPE_CFG, (iph1->side == INITIATOR) ? TPIKE_MIDX_INITIATOR : TPIKE_MIDX_RESPONDER, TPIKE_MIDX_RECEIVE, /*ANY*/0, 0xff, 0xff), 1, sizeof(attr->type), &(attr->type), hp);
+
+	if((status = tpike_pack_in(&inarr, 1, TPIKE_DTYPE_STRUCTISAKMPDATA, attr)) == TPIKE_STATUS_SUCCESS) {
+
+		if((status = tpike_dispatch_generic(&hpoint, inarr, &outarr)) == TPIKE_STATUS_SUCCESS) {
+
+			if((status = tpike_pack_out(outarr, 1, TPIKE_DTYPE_STRUCTISAKMPDATA, &setresp)) == TPIKE_STATUS_SUCCESS) {
+
+				if(setresp->type & ISAKMP_GEN_TV)
+					datalen = 0;
+				else
+					datalen = setresp->lorv;
+				if((*resp = vmalloc(sizeof(struct isakmp_data) + datalen)) == NULL)
+				{
+					//log & set error, and come out!
+					status = TPIKE_ERR_MEM_ALLOC_FAILED;
+					goto tpike_set_end;
+				}
+
+				value = *resp;
+				temp = (struct isakmp_data *)value->v;
+				if(datalen == 0)	//its a TV value
+				{
+					temp->type = setresp->type;
+					temp->lorv = setresp->lorv;
+				}
+				else
+				{
+					temp->type = setresp->type;
+					temp->lorv = datalen;
+					memcpy(temp + 1, setresp + 1, datalen);
+
+				}
+			}
+		}
+	}
+
+tpike_set_end:
+	return status; //should return status returned by plugin
+}
+
+int
+isakmp_plugin_cfg_priv(iph1, attrpl)
+	struct ph1handle *iph1;
+	struct isakmp_pl_attr *attrpl;
+{
+	struct hookpoint hpoint, *hp;
+	struct isakmp_data *setresp = NULL, *temp = NULL;
+	vchar_t *value = NULL;
+	void *outarr = NULL, *inarr = NULL;
+	u_int16_t attrtype = 0;
+	int status = TPIKE_STATUS_SUCCESS;
+	char *keyval = NULL;
+
+	attrtype = (attrpl->type);
+	hp = &hpoint;
+
+	mk_hookpoint(ATTRIBUTE_TYPE, CONFIG_ATTRIB_TYPE, attrtype, MAKE_POS(ISAKMP_ETYPE_CFG, (iph1->side == INITIATOR) ? TPIKE_MIDX_INITIATOR : TPIKE_MIDX_RESPONDER, TPIKE_MIDX_RECEIVE, /*ANY*/0, 0xff, 0xff), 1, 0, keyval, hp);
+
+	if((status = tpike_pack_in(&inarr, 1, TPIKE_DTYPE_STRUCTISAKMPDATA, NULL)) == TPIKE_STATUS_SUCCESS) {
+
+		if((status = tpike_dispatch_generic(&hpoint, inarr, &outarr)) == TPIKE_STATUS_SUCCESS) {
+
+			tpike_pack_out(outarr, 0); //plugin should respond with success/error value
+		}
+	}
+
+	return status; //should return status returned by plugin
+}
+#endif
Index: ipsec-tools-0.7.3/src/racoon/localconf.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/localconf.c
+++ ipsec-tools-0.7.3/src/racoon/localconf.c
@@ -126,6 +126,19 @@ setdefault()
 	lcconf->natt_ka_interval = LC_DEFAULT_NATT_KA_INTERVAL;
 }
 
+/* Replace the racoon_conf_file */
+int
+setracoonconf(conffile)
+	char *conffile;
+{
+	if (lcconf->racoon_conf && (strcmp (lcconf->racoon_conf, LC_DEFAULT_CF) != 0))
+	{
+		free(lcconf->racoon_conf);
+	}
+	lcconf->racoon_conf = strdup(conffile);
+	return 0;
+}
+
 /*
  * get PSK by string.
  */
Index: ipsec-tools-0.7.3/src/racoon/localconf.h
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/localconf.h
+++ ipsec-tools-0.7.3/src/racoon/localconf.h
@@ -34,6 +34,8 @@
 #ifndef _LOCALCONF_H
 #define _LOCALCONF_H
 
+#include "config.h"
+
 /* local configuration */
 
 #define LC_DEFAULT_CF	SYSCONFDIR "/racoon.conf"
@@ -118,12 +120,19 @@ struct localconf {
 		 */
 
 	int gss_id_enc;			/* GSS ID encoding to use */
+
+#ifdef PLUGINS_SUPPORT
+	int plugins_support;    /* whether enable the plugins support or not */
+	char *plugins_name;
+	char *plugins_path;     /* plugins' filename or path */
+#endif /* PLUGINS_SUPPORT */
 };
 
 extern struct localconf *lcconf;
 
 extern void initlcconf __P((void));
 extern void flushlcconf __P((void));
+extern int setracoonconf __P((char *));
 extern vchar_t *getpskbyname __P((vchar_t *));
 extern vchar_t *getpskbyaddr __P((struct sockaddr *));
 extern void getpathname __P((char *, int, int, const char *));
Index: ipsec-tools-0.7.3/src/racoon/main.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/main.c
+++ ipsec-tools-0.7.3/src/racoon/main.c
@@ -340,7 +340,7 @@ parse(ac, av)
 			exit(1);
 #endif
 		case 'f':
-			lcconf->racoon_conf = optarg;
+			lcconf->racoon_conf = strdup(optarg);
 			break;
 		case 'l':
 			plogset(optarg);
Index: ipsec-tools-0.7.3/src/racoon/Makefile.am
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/Makefile.am
+++ ipsec-tools-0.7.3/src/racoon/Makefile.am
@@ -4,7 +4,8 @@ sbin_PROGRAMS = racoon racoonctl plainrs
 noinst_PROGRAMS = eaytest
 include_racoon_HEADERS = racoonctl.h var.h vmbuf.h misc.h gcmalloc.h admin.h \
 	schedule.h sockmisc.h vmbuf.h isakmp_var.h isakmp.h isakmp_xauth.h \
-	isakmp_cfg.h isakmp_unity.h ipsec_doi.h evt.h
+	isakmp_cfg.h isakmp_unity.h ipsec_doi.h evt.h oakley.h nattraversal.h vendorid.h \
+	handler.h remoteconf.h genlist.h isakmp_inf.h gnuc.h
 lib_LTLIBRARIES = libracoon.la
 
 adminsockdir=${localstatedir}/racoon
@@ -12,8 +13,8 @@ adminsockdir=${localstatedir}/racoon
 BUILT_SOURCES = cfparse.h prsa_par.h
 INCLUDES = -I${srcdir}/../libipsec 
 AM_CFLAGS = -D_GNU_SOURCE @GLIBC_BUGS@ -DSYSCONFDIR=\"${sysconfdir}\" \
-	-DADMINPORTDIR=\"${adminsockdir}\"
-AM_LDFLAGS = @EXTRA_CRYPTO@ -lcrypto
+	-DADMINPORTDIR=\"${adminsockdir}\" @PLUGINS_SUPPORT_CFLAGS@
+AM_LDFLAGS = @EXTRA_CRYPTO@ -lcrypto @PLUGINS_SUPPORT_LDFLAGS@
 AM_YFLAGS = -d ${$*_YFLAGS}
 AM_LFLAGS = ${$*_LFLAGS}
 
@@ -39,7 +40,8 @@ racoon_SOURCES = \
 EXTRA_racoon_SOURCES = isakmp_xauth.c isakmp_cfg.c isakmp_unity.c throttle.c \
 	isakmp_frag.c nattraversal.c security.c $(MISSING_ALGOS)
 racoon_LDADD = $(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(LEXLIB) \
-	 $(SECCTX_OBJS) vmbuf.o sockmisc.o misc.o ../libipsec/libipsec.la
+	 $(SECCTX_OBJS) vmbuf.o sockmisc.o misc.o ../libipsec/libipsec.la \
+	 ../plugin_frame/libplugin_frame.la
 racoon_DEPENDENCIES = \
 	$(CRYPTOBJS) $(HYBRID_OBJS) $(NATT_OBJS) $(FRAG_OBJS) $(SECCTX_OBJS) \
 	vmbuf.o sockmisc.o misc.o
Index: ipsec-tools-0.7.3/configure.ac
===================================================================
--- ipsec-tools-0.7.3.orig/configure.ac
+++ ipsec-tools-0.7.3/configure.ac
@@ -2,7 +2,7 @@ dnl -*- mode: m4 -*-
 dnl Id: configure.ac,v 1.77 2006/07/20 19:19:27 manubsd Exp
 
 AC_PREREQ(2.52)
-AC_INIT(ipsec-tools, 0.7.3)
+AC_INIT(novell-ipsec-tools, 0.7.3)
 AC_CONFIG_SRCDIR([configure.ac])
 AM_CONFIG_HEADER(config.h)
 
@@ -260,6 +260,21 @@ if test $enable_adminport = "yes"; then
 fi
 AC_MSG_RESULT($enable_adminport)
 
+# Option --enable-apclient
+AC_MSG_CHECKING(if --enable-apclient option specified)
+AC_ARG_ENABLE(apclient,
+	[ --enable-apclient   enable admin port client extensions],
+	[],[enable_apclient=no])
+if test $enable_apclient = "yes"; then
+    if test $enable_adminport = "yes"; then
+        AC_MSG_RESULT(ok) ;
+        AC_DEFINE([ENABLE_AP_CLIENTMODE],[],[Enable Admin Port Client Extensions])
+    else
+        AC_MSG_ERROR([Enabling Admin port Client without enabling admin port  Aborting]);
+    fi
+fi
+AC_MSG_RESULT($enable_apclient)
+
 # Option RC5
 AC_MSG_CHECKING(if --enable-rc5 option is specified)
 AC_ARG_ENABLE(rc5,
@@ -801,7 +816,17 @@ AC_ARG_ENABLE(plugins-support,
         [], [enable_plugins_support=no])
 if test "x$enable_plugins_support" = "xyes"; then
         AC_DEFINE([PLUGINS_SUPPORT], [], [Enable plugins support])
+	PLUGINS_SUPPORT_CFLAGS='-I${top_srcdir}/src -export-dynamic'
+	PLUGINS_SUPPORT_CPPFLAGS='-I${top_srcdir}/src -export-dynamic'
+	PLUGINS_SUPPORT_LDFLAGS='-Wl,--export-dynamic'
+	PLUGINS_SUPPROT_LDADD='${top_builddir}/src/plugin_frame/libplugin_frame.la'
+
+	AC_SUBST(PLUGINS_SUPPORT_CPPFLAGS)
+	AC_SUBST(PLUGINS_SUPPORT_CFLAGS)
+	AC_SUBST(PLUGINS_SUPPORT_LDFLAGS)
+	AC_SUBST(PLUGINS_SUPPORT_LDADD)
 fi
+
 AC_MSG_RESULT($enable_plugins_support)
 
 
@@ -827,6 +852,7 @@ AC_CONFIG_FILES([
   src/include-glibc/Makefile
   src/libipsec/Makefile
   src/setkey/Makefile
+  src/plugin_frame/Makefile
   src/racoon/Makefile
   src/racoon/samples/psk.txt
   src/racoon/samples/racoon.conf
Index: ipsec-tools-0.7.3/src/racoon/isakmp.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/isakmp.c
+++ ipsec-tools-0.7.3/src/racoon/isakmp.c
@@ -107,6 +107,13 @@
 
 #include <fcntl.h>
 
+#ifdef PLUGINS_SUPPORT
+#include "plugin_frame/common.h"
+#include "plugin_frame/framework.h"
+#include "plugin_frame/position.h"
+#include "plugin_frame/error.h"
+#endif
+
 #ifdef ENABLE_NATT
 # include "nattraversal.h"
 #endif
@@ -779,6 +786,13 @@ ph1_main(iph1, msg)
 	struct timeval start, end;
 #endif
 
+#ifdef PLUGINS_SUPPORT
+	void *inarr = NULL, *outarr = NULL;
+	int *val = NULL ;
+	struct hookpoint hpoint, *hp = NULL;
+        int isrekeyreq = 0;
+	char *keyval = NULL;
+#endif
 	/* ignore a packet */
 	if (iph1->status == PHASE1ST_ESTABLISHED)
 		return 0;
@@ -853,32 +867,54 @@ ph1_main(iph1, msg)
 #ifdef ENABLE_STATS
 		gettimeofday(&iph1->end, NULL);
 		syslog(LOG_NOTICE, "%s(%s): %8.6f",
-			"phase1", s_isakmp_etype(iph1->etype),
-			timedelta(&iph1->start, &iph1->end));
+				"phase1", s_isakmp_etype(iph1->etype),
+				timedelta(&iph1->start, &iph1->end));
 #endif
 
 		/* save created date. */
 		(void)time(&iph1->created);
 
-		/* add to the schedule to expire, and seve back pointer. */
-		iph1->sce = sched_new(iph1->approval->lifetime,
-		    isakmp_ph1expire_stub, iph1);
+#ifdef PLUGINS_SUPPORT
+		//get the ike attribs from the registered plugins
+		hp = &hpoint;
+		mk_hookpoint(IS_REKEYREQ_TYPE, 0, /*ANY*/0, MAKE_POS(ISAKMP_ETYPE_AGG, TPIKE_MIDX_INITIATOR, TPIKE_MIDX_SEND, 0 /* Any. Change it to 1 */ , 0xff, 0xff), 0, 0, keyval, hp);
+
+		tpike_pack_in(&inarr, 0);
+
+		if(tpike_dispatch_generic(&hpoint, inarr, &outarr) == TPIKE_STATUS_SUCCESS) {
+
+			if (tpike_pack_out(outarr, 1, TPIKE_DTYPE_INT32PT, &val) == TPIKE_STATUS_SUCCESS)
+				isrekeyreq = *val;
+		}
+
+		if(isrekeyreq){
+			plog(LLV_DEBUG, LOCATION, iph1->remote, "ADDED PHASE1 REKEY TIMER.\n");
+#endif
+			/* add to the schedule to expire, and seve back pointer. */
+			iph1->sce = sched_new(iph1->approval->lifetime,
+					isakmp_ph1expire_stub, iph1);
+#ifdef PLUGINS_SUPPORT
+		}
+		else{
+			plog(LLV_DEBUG, LOCATION, iph1->remote, "PHASE1 REKEY TIMER NOT CHOSEN.\n");
+		}
+#endif
 #ifdef ENABLE_HYBRID
 		if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
 			switch(AUTHMETHOD(iph1)) {
-			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
-			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
-				xauth_sendreq(iph1);
-				/* XXX Don't process INITIAL_CONTACT */
-				iph1->rmconf->ini_contact = 0;
-				break;
-			default:
-				break;
+				case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+				case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+					xauth_sendreq(iph1);
+					/* XXX Don't process INITIAL_CONTACT */
+					iph1->rmconf->ini_contact = 0;
+					break;
+				default:
+					break;
 			}
 		}
 #endif
@@ -891,14 +927,14 @@ ph1_main(iph1, msg)
 		/* INITIAL-CONTACT processing */
 		/* don't anything if local test mode. */
 		if (!f_local
-		 && iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) {
+				&& iph1->rmconf->ini_contact && !getcontacted(iph1->remote)) {
 			/* send INITIAL-CONTACT */
 			isakmp_info_send_n1(iph1,
 					ISAKMP_NTYPE_INITIAL_CONTACT, NULL);
 			/* insert a node into contacted list. */
 			if (inscontacted(iph1->remote) == -1) {
 				plog(LLV_ERROR, LOCATION, iph1->remote,
-					"failed to add contacted list.\n");
+						"failed to add contacted list.\n");
 				/* ignore */
 			}
 		}
@@ -912,22 +948,22 @@ ph1_main(iph1, msg)
 		 * case it is done when we receive the configuration.
 		 */
 		if ((iph1->status == PHASE1ST_ESTABLISHED) &&
-		    !iph1->rmconf->mode_cfg) { 
+				!iph1->rmconf->mode_cfg) {
 			switch (AUTHMETHOD(iph1)) {
 #ifdef ENABLE_HYBRID
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
-			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
-			/* Unimplemeted... */
-			case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
-			case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
-				break;
-#endif
-			default:
-				script_hook(iph1, SCRIPT_PHASE1_UP);
-				break;
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
+				case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
+					/* Unimplemeted... */
+				case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
+				case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
+					break;
+#endif
+				default:
+					script_hook(iph1, SCRIPT_PHASE1_UP);
+					break;
 			}
 		}
 	}
@@ -3626,3 +3662,111 @@ setscopeid(sp_addr0, sa_addr0)
 	return 0;
 }
 #endif
+#ifdef PLUGINS_SUPPORT
+struct payload_list *isakmp_plist_insert_vendorid_payload(
+		struct payload_list *plist,
+	   	struct ph1handle *iph1,
+	   	u_int8_t myposition)
+{
+	int index = 0, incount = 0;
+	u_int32_t position = 0;
+	struct payload_list *newpayload = NULL, *current = NULL, *anchorpl = NULL, *pl = plist, *first;
+	struct hookpoint hpoint, *hp;
+	struct handlerinfo *hinfo;
+	void *inarr = NULL, *outarr = NULL;
+	char *keyval = NULL;
+
+	/* Seek to the first item.  */
+	while (pl->prev) pl = pl->prev;
+	first = pl;
+
+	hinfo = racoon_malloc(sizeof (struct handlerinfo));
+	if(hinfo == NULL)
+	{
+		return first;
+	}
+
+	hp = &hpoint;
+
+	for( ;pl != NULL; pl = pl->next)
+	{
+		//TODO: Take care of inserting as first payload
+		mk_hookpoint(PAYLOAD_TYPE, ISAKMP_NPTYPE_VID, /*ANY*/0, MAKE_POS2(iph1->etype, myposition, pl->payload_type, (pl->next != NULL)? pl->next->payload_type : ISAKMP_NPTYPE_NONE), 0, 0, keyval, hp);
+
+		tpike_pack_in(&inarr, 1, TPIKE_DTYPE_STRUCTIPH1, iph1);
+
+		if(tpike_dispatch_generic(&hpoint, inarr, &outarr) != TPIKE_STATUS_SUCCESS)
+			continue;
+
+		if(tpike_pack_out(outarr, 1, TPIKE_DTYPE_STRUCTPAYLOADLIST, &newpayload) != TPIKE_STATUS_SUCCESS)
+			continue;
+
+		anchorpl = pl;
+		for(; newpayload && pl; pl = pl->next)
+		{
+			//if((pl->next->prev = racoon_malloc (sizeof (struct payload_list))) == NULL)
+			if((current = racoon_malloc (sizeof (struct payload_list))) == NULL)
+				continue; //malloc has failed, do we want to continue?
+			current->payload = vmalloc(newpayload->payload->l);
+			memcpy(current->payload->v, newpayload->payload->v, newpayload->payload->l);
+			current->payload_type = newpayload->payload_type;
+			current->next = current->prev = NULL;
+
+			if(!pl->next) {
+				current = pl->next;
+				current->prev = pl;
+			}
+			else {
+				pl->next->prev = current;
+				current->next = pl->next;
+				current->prev = pl;
+				pl->next = current;
+			}
+
+			//if(!newpayload->next)
+			//	break;
+			newpayload = newpayload->next;
+
+		}
+		pl = anchorpl;
+		break;	//remove once framework takes care of payload match according to k1 & k2
+
+	}
+
+	return first;
+}
+
+
+int verify_payload(
+		u_int8_t payloadtype,
+	   	u_int8_t etype,
+	   	u_int8_t side,
+	   	u_int8_t sendorrecv,
+	   	u_int8_t msgindx,
+	   	void *pl,
+	   	void **buf)
+{
+	struct hookpoint hpoint, *hp;
+	struct handlerinfo *hinfo;
+	struct isakmp_data **resp = (struct isakmp_data **)buf;
+	void *outarr = NULL, *inarr = NULL;
+	int index = 0, incount = 0;
+	u_int32_t position = 0, status = TPIKE_STATUS_SUCCESS;
+	char *keyval = NULL;
+
+	hp = &hpoint;
+
+	mk_hookpoint(PAYLOAD_TYPE, payloadtype, /*ANY*/0, MAKE_POS(etype, side, sendorrecv, msgindx, 0xff, 0xff), 0, 0, keyval, hp);
+
+	if((status = tpike_pack_in(&inarr, 1, TPIKE_DTYPE_STRUCTISAKMPGEN, pl)) == TPIKE_STATUS_SUCCESS) {
+
+		if((status = tpike_dispatch_generic(&hpoint, inarr, &outarr)) == TPIKE_STATUS_SUCCESS) {
+
+			status = tpike_pack_out(outarr, 1, TPIKE_DTYPE_STRUCTISAKMPDATA, resp); //plugin should respond with success/error value
+		}
+
+	}
+	return status; //should return status returned by plugin
+}
+
+#endif
Index: ipsec-tools-0.7.3/src/racoon/remoteconf.c
===================================================================
--- ipsec-tools-0.7.3.orig/src/racoon/remoteconf.c
+++ ipsec-tools-0.7.3/src/racoon/remoteconf.c
@@ -302,10 +302,15 @@ delrmconf(rmconf)
 	if (rmconf->xauth)
 		xauth_rmconf_delete(&rmconf->xauth);
 #endif
+	if (rmconf->remote)
+		racoon_free(rmconf->remote);
+
 	if (rmconf->etypes){
 		deletypes(rmconf->etypes);
 		rmconf->etypes=NULL;
 	}
+	if (rmconf->idv)
+		racoon_free(rmconf->idv);
 	if (rmconf->idvl_p)
 		genlist_free(rmconf->idvl_p, idspec_free);
 	if (rmconf->dhgrp)
@@ -453,6 +458,10 @@ newisakmpsa()
 	new->gssid = NULL;
 #endif
 
+#ifdef PLUGINS_SUPPORT
+	new->pluginikeattribs = NULL;
+#endif
+
 	return new;
 }
 
openSUSE Build Service is sponsored by