diff -ru openswan-1.0.0/pluto/connections.c openswan-1.0.0-psk-rsa-2/pluto/connections.c
--- openswan-1.0.0/pluto/connections.c	Fri Nov 28 18:44:22 2003
+++ openswan-1.0.0-psk-rsa-2/pluto/connections.c	Fri Mar 12 17:16:32 2004
@@ -792,6 +792,7 @@
 	    {
 		if (c->policy & POLICY_AGGRESSIVE)
 		    continue;
+#if 0
 		if ((c->policy ^ wm->policy) & (POLICY_PSK | POLICY_RSASIG))
 		{
 		    loglog(RC_CLASH
@@ -799,6 +800,7 @@
 			, c->name);
 		    return FALSE;
 		}
+#endif
 	    }
 	}
     }
@@ -1960,9 +1962,20 @@
  */
 struct connection *
 find_host_connection(const ip_address *me, u_int16_t my_port
-, const ip_address *him, u_int16_t his_port)
+, const ip_address *him, u_int16_t his_port, lset_t policy)
 {
-    return find_host_pair_connections(me, my_port, him, his_port);
+    struct connection *c;
+    c = find_host_pair_connections(me, my_port, him, his_port);
+    if (policy != LEMPTY) {
+	/* if we have requirements for the policy, choose the first matching
+	 * connection.
+	 */
+	for (; c != NULL; c = c->hp_next) {
+	    if ((c->policy & policy) == policy)
+		break;
+	}
+    }
+    return c;
 }
 
 /* given an up-until-now satisfactory connection, find the best connection
diff -ru openswan-1.0.0/pluto/connections.h openswan-1.0.0-psk-rsa-2/pluto/connections.h
--- openswan-1.0.0/pluto/connections.h	Fri Nov 28 18:44:22 2003
+++ openswan-1.0.0-psk-rsa-2/pluto/connections.h	Fri Mar 12 17:16:32 2004
@@ -213,7 +213,7 @@
 extern struct connection
     *con_by_name(const char *nm, bool strict),
     *find_host_connection(const ip_address *me, u_int16_t my_port
-	, const ip_address *him, u_int16_t his_port),
+	, const ip_address *him, u_int16_t his_port, lset_t policy),
     *refine_host_connection(const struct state *st, const struct id *id
 	, bool initiator, bool aggrmode),
     *find_client_connection(struct connection *c
diff -ru openswan-1.0.0/pluto/ipsec_doi.c openswan-1.0.0-psk-rsa-2/pluto/ipsec_doi.c
--- openswan-1.0.0/pluto/ipsec_doi.c	Fri Nov 28 18:44:22 2003
+++ openswan-1.0.0-psk-rsa-2/pluto/ipsec_doi.c	Fri Mar 12 17:16:32 2004
@@ -298,7 +298,7 @@
 collect_rw_ca_candidates(struct msg_digest *md, generalName_t **top)
 {
     struct connection *d = find_host_connection(&md->iface->addr
-	, pluto_port, (ip_address*)NULL, md->sender_port);
+	, pluto_port, (ip_address*)NULL, md->sender_port, LEMPTY);
 
     for (; d != NULL; d = d->hp_next)
     {
@@ -3018,15 +3018,18 @@
     struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
     struct state *st;
     struct connection *c = find_host_connection(&md->iface->addr, pluto_port
-	, &md->sender, md->sender_port);
+	, &md->sender, md->sender_port, LEMPTY);
 
     pb_stream r_sa_pbs;
 
     if (c == NULL)
     {
+	pb_stream pre_sa_pbs = sa_pd->pbs;
+	lset_t policy = preparse_isakmp_sa_body(&pre_sa_pbs);
+
 	/* see if a wildcarded connection can be found */
 	c = find_host_connection(&md->iface->addr, pluto_port
-	    , (ip_address*)NULL, md->sender_port);
+	    , (ip_address*)NULL, md->sender_port, policy);
 	if (c != NULL)
 	{
 	    /* Create a temporary connection that is a copy of this one.
@@ -3044,8 +3047,10 @@
 	else
 	{
 	    loglog(RC_LOG_SERIOUS, "initial Main Mode message received on %s:%u"
-		" but no connection has been authorized"
-		, ip_str(&md->iface->addr), ntohs(portof(&md->iface->addr)));
+		" but no connection has been authorized%s%s"
+		, ip_str(&md->iface->addr), ntohs(portof(&md->iface->addr))
+		, (policy != LEMPTY) ? " with policy=" : ""
+		, (policy != LEMPTY) ? bitnamesof(sa_policy_bit_names, policy) : "");
 	    /* XXX notification is in order! */
 	    return STF_IGNORE;
 	}
@@ -3919,16 +3924,19 @@
     struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_SA];
     pb_stream *keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
     struct connection *c = find_host_connection(&md->iface->addr, pluto_port
-	, &md->sender, md->sender_port);
+	, &md->sender, md->sender_port, LEMPTY);
     pb_stream r_id_pbs;	/* ID Payload; also used for hash calculation */
     pb_stream r_sa_pbs;
     int auth_payload,next_payload;
 
     if (c == NULL)
     {
+	pb_stream pre_sa_pbs = sa_pd->pbs;
+	lset_t policy = preparse_isakmp_sa_body(&pre_sa_pbs);
+
 	/* see if a wildcarded connection can be found */
 	c = find_host_connection(&md->iface->addr, pluto_port
-	    , (ip_address*)NULL, md->sender_port);
+	    , (ip_address*)NULL, md->sender_port, policy);
 	if (c != NULL && c->policy & POLICY_AGGRESSIVE)
 	{
 	    /* Create a temporary connection that is a copy of this one.
@@ -3946,8 +3954,10 @@
 	else
 	{
 	    loglog(RC_LOG_SERIOUS, "initial Aggressive Mode message from %s"
-		" but no (wildcard) connection has been configured"
-		, ip_str(&md->sender));
+		" but no (wildcard) connection has been configured%s%s"
+		, ip_str(&md->sender)
+	    , (policy != LEMPTY) ? " with policy=" : ""
+		, (policy != LEMPTY) ? bitnamesof(sa_policy_bit_names, policy) : "");
 	    /* XXX notification is in order! */
 	    return STF_IGNORE;
 	}
diff -ru openswan-1.0.0/pluto/spdb.c openswan-1.0.0-psk-rsa-2/pluto/spdb.c
--- openswan-1.0.0/pluto/spdb.c	Tue Nov 25 01:37:27 2003
+++ openswan-1.0.0-psk-rsa-2/pluto/spdb.c	Wed Mar 17 17:44:16 2004
@@ -806,6 +806,79 @@
     return val;
 }
 
+/* Preparse the body of an ISAKMP SA Payload and find which policy is required
+ * to match the packet. Errors are just ignored and will be detected and
+ * handled later in parse_isakmp_sa_body().
+ *
+ * All we want for the moment is to know whether peer is using RSA or PSK.
+ */
+lset_t preparse_isakmp_sa_body(pb_stream *sa_pbs)
+{
+    pb_stream proposal_pbs;
+    struct isakmp_proposal proposal;
+    pb_stream trans_pbs;
+    struct isakmp_transform trans;
+    u_char *attr_start;
+    size_t attr_len;
+    struct isakmp_attribute a;
+    pb_stream attr_pbs;
+    u_int32_t ipsecdoisit;
+    unsigned trans_left;
+    lset_t policy = 0;
+
+    if (!in_struct(&ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL))
+	return LEMPTY;
+
+    if (!in_struct(&proposal, &isakmp_proposal_desc, sa_pbs, &proposal_pbs))
+	return LEMPTY;
+
+    if (proposal.isap_spisize > MAX_ISAKMP_SPI_SIZE)
+	return LEMPTY;
+
+    if (proposal.isap_spisize > 0)
+    {
+	u_char junk_spi[MAX_ISAKMP_SPI_SIZE];
+
+	if (!in_raw(junk_spi, proposal.isap_spisize, &proposal_pbs, "Oakley SPI"))
+	    return LEMPTY;
+    }
+
+    trans_left = proposal.isap_notrans;
+    while (trans_left--) {
+	if (!in_struct(&trans, &isakmp_isakmp_transform_desc, &proposal_pbs,
+	    &trans_pbs))
+	    return LEMPTY;
+
+	attr_start = trans_pbs.cur;
+	attr_len = pbs_left(&trans_pbs);
+
+	while (pbs_left(&trans_pbs) != 0) {
+	    if (!in_struct(&a, &isakmp_oakley_attribute_desc, &trans_pbs,
+		&attr_pbs))
+		return LEMPTY;
+	    switch (a.isaat_af_type) {
+		case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV:
+		    switch (a.isaat_lv) {
+			case XAUTHInitPreShared:
+			case OAKLEY_PRESHARED_KEY:
+				policy |= POLICY_PSK;
+			    break;
+			case XAUTHInitRSA:
+			case OAKLEY_RSA_SIG:
+				policy |= POLICY_RSASIG;
+			    break;
+		    }
+		    break;
+	    }
+	}
+    }
+
+    if ((policy & POLICY_PSK) && (policy & POLICY_RSASIG))
+	policy &= ~(POLICY_PSK|POLICY_RSASIG);
+
+    return policy;
+}
+
 /* Parse the body of an ISAKMP SA Payload (i.e. Phase 1 / Main Mode).
  * Various shortcuts are taken.  In particular, the policy, such as
  * it is, is hardwired.
diff -ru openswan-1.0.0/pluto/spdb.h openswan-1.0.0-psk-rsa-2/pluto/spdb.h
--- openswan-1.0.0/pluto/spdb.h	Mon Mar  3 23:29:54 2003
+++ openswan-1.0.0-psk-rsa-2/pluto/spdb.h	Fri Mar 12 17:16:32 2004
@@ -84,6 +84,8 @@
     bool credcheck);    /* whether we can check credentials now */
 #endif
 
+extern lset_t preparse_isakmp_sa_body(pb_stream *sa_pbs);
+
 extern notification_t parse_isakmp_sa_body(
     pb_stream *sa_pbs,	/* body of input SA Payload */
     const struct isakmp_sa *sa,	/* header of input SA Payload */

