added XAUTH server and client support
This commit is contained in:
+107
-11
@@ -436,6 +436,38 @@ static const struct state_microcode state_microcode_table[] = {
|
||||
, P(HASH), LEMPTY, PT(NONE)
|
||||
, EVENT_NULL, informational },
|
||||
|
||||
/* XAUTH server */
|
||||
{ STATE_XAUTH_R1, STATE_XAUTH_R2
|
||||
, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
|
||||
, P(ATTR) | P(HASH), P(VID), PT(HASH)
|
||||
, EVENT_RETRANSMIT, xauth_inR1 },
|
||||
|
||||
{ STATE_XAUTH_R2, STATE_XAUTH_R3
|
||||
, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
|
||||
, P(ATTR) | P(HASH), P(VID), PT(NONE)
|
||||
, EVENT_SA_REPLACE, xauth_inR2 },
|
||||
|
||||
{ STATE_XAUTH_R3, STATE_UNDEFINED
|
||||
, SMF_ALL_AUTH | SMF_ENCRYPTED
|
||||
, LEMPTY, LEMPTY, PT(NONE)
|
||||
, EVENT_NULL, unexpected },
|
||||
|
||||
/* XAUTH client */
|
||||
{ STATE_XAUTH_I0, STATE_XAUTH_I1
|
||||
, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
|
||||
, P(ATTR) | P(HASH), P(VID), PT(HASH)
|
||||
, EVENT_SA_REPLACE, xauth_inI0 },
|
||||
|
||||
{ STATE_XAUTH_I1, STATE_XAUTH_I2
|
||||
, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
|
||||
, P(ATTR) | P(HASH), P(VID), PT(HASH)
|
||||
, EVENT_SA_REPLACE, xauth_inI1 },
|
||||
|
||||
{ STATE_XAUTH_I2, STATE_UNDEFINED
|
||||
, SMF_ALL_AUTH | SMF_ENCRYPTED
|
||||
, LEMPTY, LEMPTY, PT(NONE)
|
||||
, EVENT_NULL, unexpected },
|
||||
|
||||
/* MODE_CFG_x:
|
||||
* Case R0: Responder -> Initiator
|
||||
* <- Req(addr=0)
|
||||
@@ -1238,6 +1270,11 @@ process_packet(struct msg_digest **mdp)
|
||||
{
|
||||
plog("size (%u) differs from size specified in ISAKMP HDR (%u)"
|
||||
, (unsigned) pbs_room(&md->packet_pbs), md->hdr.isa_length);
|
||||
#ifdef CISCO_QUIRKS
|
||||
if (pbs_room(&md->packet_pbs) - md->hdr.isa_length == 16)
|
||||
plog("Cisco VPN client appends 16 surplus NULL bytes");
|
||||
else
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1470,7 +1507,7 @@ process_packet(struct msg_digest **mdp)
|
||||
case ISAKMP_XCHG_MODE_CFG:
|
||||
if (is_zero_cookie(md->hdr.isa_icookie))
|
||||
{
|
||||
plog("Mode Config message is invalid because"
|
||||
plog("ModeCfg message is invalid because"
|
||||
" it has an Initiator Cookie of 0");
|
||||
/* XXX Could send notification back */
|
||||
return;
|
||||
@@ -1478,7 +1515,7 @@ process_packet(struct msg_digest **mdp)
|
||||
|
||||
if (is_zero_cookie(md->hdr.isa_rcookie))
|
||||
{
|
||||
plog("Mode Config message is invalid because"
|
||||
plog("ModeCfg message is invalid because"
|
||||
" it has a Responder Cookie of 0");
|
||||
/* XXX Could send notification back */
|
||||
return;
|
||||
@@ -1486,7 +1523,7 @@ process_packet(struct msg_digest **mdp)
|
||||
|
||||
if (md->hdr.isa_msgid == 0)
|
||||
{
|
||||
plog("Mode Config message is invalid because"
|
||||
plog("ModeCfg message is invalid because"
|
||||
" it has a Message ID of 0");
|
||||
/* XXX Could send notification back */
|
||||
return;
|
||||
@@ -1497,7 +1534,9 @@ process_packet(struct msg_digest **mdp)
|
||||
|
||||
if (st == NULL)
|
||||
{
|
||||
/* No appropriate Mode Config state.
|
||||
bool has_xauth_policy;
|
||||
|
||||
/* No appropriate ModeCfg state.
|
||||
* See if we have a Main Mode state.
|
||||
* ??? what if this is a duplicate of another message?
|
||||
*/
|
||||
@@ -1506,7 +1545,7 @@ process_packet(struct msg_digest **mdp)
|
||||
|
||||
if (st == NULL)
|
||||
{
|
||||
plog("Mode Config message is for a non-existent (expired?)"
|
||||
plog("ModeCfg message is for a non-existent (expired?)"
|
||||
" ISAKMP SA");
|
||||
/* XXX Could send notification back */
|
||||
return;
|
||||
@@ -1516,7 +1555,7 @@ process_packet(struct msg_digest **mdp)
|
||||
|
||||
if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
|
||||
{
|
||||
loglog(RC_LOG_SERIOUS, "Mode Config message is unacceptable because"
|
||||
loglog(RC_LOG_SERIOUS, "ModeCfg message is unacceptable because"
|
||||
" it is for an incomplete ISAKMP SA (state=%s)"
|
||||
, enum_name(&state_names, st->st_state));
|
||||
/* XXX Could send notification back */
|
||||
@@ -1545,7 +1584,16 @@ process_packet(struct msg_digest **mdp)
|
||||
*
|
||||
*/
|
||||
|
||||
if (st->st_connection->spd.that.modecfg
|
||||
has_xauth_policy = (st->st_connection->policy
|
||||
& (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
|
||||
!= LEMPTY;
|
||||
|
||||
if (has_xauth_policy
|
||||
&& IS_PHASE1(st->st_state))
|
||||
{
|
||||
from_state = STATE_XAUTH_I0;
|
||||
}
|
||||
else if (st->st_connection->spd.that.modecfg
|
||||
&& IS_PHASE1(st->st_state))
|
||||
{
|
||||
from_state = STATE_MODE_CFG_R0;
|
||||
@@ -1558,7 +1606,7 @@ process_packet(struct msg_digest **mdp)
|
||||
else
|
||||
{
|
||||
/* XXX check if we are being a mode config server here */
|
||||
plog("received MODECFG message when in state %s, and we aren't mode config client"
|
||||
plog("received ModeCfg message when in state %s, and we aren't mode config client"
|
||||
, enum_name(&state_names, st->st_state));
|
||||
return;
|
||||
}
|
||||
@@ -1610,7 +1658,23 @@ process_packet(struct msg_digest **mdp)
|
||||
|
||||
if (st != NULL)
|
||||
{
|
||||
while (!LHAS(smc->flags, st->st_oakley.auth))
|
||||
u_int16_t auth;
|
||||
|
||||
switch (st->st_oakley.auth)
|
||||
{
|
||||
case XAUTHInitPreShared:
|
||||
case XAUTHRespPreShared:
|
||||
auth = OAKLEY_PRESHARED_KEY;
|
||||
break;
|
||||
case XAUTHInitRSA:
|
||||
case XAUTHRespRSA:
|
||||
auth = OAKLEY_RSA_SIG;
|
||||
break;
|
||||
default:
|
||||
auth = st->st_oakley.auth;
|
||||
}
|
||||
|
||||
while (!LHAS(smc->flags, auth))
|
||||
{
|
||||
smc++;
|
||||
passert(smc->state == from_state);
|
||||
@@ -2023,6 +2087,8 @@ process_packet(struct msg_digest **mdp)
|
||||
void
|
||||
complete_state_transition(struct msg_digest **mdp, stf_status result)
|
||||
{
|
||||
bool has_xauth_policy;
|
||||
bool is_xauth_server;
|
||||
struct msg_digest *md = *mdp;
|
||||
const struct state_microcode *smc = md->smc;
|
||||
enum state_kind from_state = md->from_state;
|
||||
@@ -2238,7 +2304,7 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
|
||||
}
|
||||
/* advance b to end of string */
|
||||
b = b + strlen(b);
|
||||
|
||||
|
||||
if (st->st_ah.present)
|
||||
{
|
||||
snprintf(b, sizeof(sadetails)-(b-sadetails)-1
|
||||
@@ -2251,7 +2317,7 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
|
||||
}
|
||||
/* advance b to end of string */
|
||||
b = b + strlen(b);
|
||||
|
||||
|
||||
if (st->st_ipcomp.present)
|
||||
{
|
||||
snprintf(b, sizeof(sadetails)-(b-sadetails)-1
|
||||
@@ -2306,6 +2372,25 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
|
||||
, story, sadetails);
|
||||
}
|
||||
|
||||
has_xauth_policy = (st->st_connection->policy
|
||||
& (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
|
||||
!= LEMPTY;
|
||||
is_xauth_server = (st->st_connection->policy
|
||||
& POLICY_XAUTH_SERVER)
|
||||
!= LEMPTY;
|
||||
|
||||
/* Should we start XAUTH as a server */
|
||||
if (has_xauth_policy && is_xauth_server
|
||||
&& IS_ISAKMP_SA_ESTABLISHED(st->st_state)
|
||||
&& !st->st_xauth.started)
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("starting XAUTH server")
|
||||
)
|
||||
xauth_send_request(st);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Should we start ModeConfig as a client? */
|
||||
if (st->st_connection->spd.this.modecfg
|
||||
&& IS_ISAKMP_SA_ESTABLISHED(st->st_state)
|
||||
@@ -2332,6 +2417,17 @@ complete_state_transition(struct msg_digest **mdp, stf_status result)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Wait for XAUTH request from server */
|
||||
if (has_xauth_policy && !is_xauth_server
|
||||
&& IS_ISAKMP_SA_ESTABLISHED(st->st_state)
|
||||
&& !st->st_xauth.started)
|
||||
{
|
||||
DBG(DBG_CONTROL,
|
||||
DBG_log("waiting for XAUTH request from server")
|
||||
)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Wait for ModeConfig set from server */
|
||||
if (st->st_connection->spd.this.modecfg
|
||||
&& IS_ISAKMP_SA_ESTABLISHED(st->st_state)
|
||||
|
||||
Reference in New Issue
Block a user