case XAUTHInitPreShared:
case XAUTHRespPreShared:
auth_policy = POLICY_XAUTH_PSK;
+ psk = get_preshared_secret(c);
+ if (psk == NULL)
+ return NULL; /* cannot determine PSK! */
break;
case OAKLEY_RSA_SIG:
auth_policy = POLICY_RSASIG;
#ifdef VENDORID
" VENDORID"
#endif
-#ifdef XAUTH_VID
- " XAUTH_VID"
+#ifdef CISCO_QUIRKS
+ " CISCO_QUIRKS"
#endif
#ifdef USE_KEYRR
" KEYRR"
"STATE_INFO",
"STATE_INFO_PROTECTED",
- "STATE_XAUTH_R1",
- "STATE_XAUTH_R2",
- "STATE_XAUTH_R3",
"STATE_XAUTH_I0",
+ "STATE_XAUTH_R1",
"STATE_XAUTH_I1",
+ "STATE_XAUTH_R2",
"STATE_XAUTH_I2",
+ "STATE_XAUTH_R3",
"STATE_MODE_CFG_R0",
- "STATE_MODE_CFG_R1",
- "STATE_MODE_CFG_R2",
"STATE_MODE_CFG_I1",
+ "STATE_MODE_CFG_R1",
"STATE_MODE_CFG_I2",
+
+ "STATE_MODE_CFG_I0",
+ "STATE_MODE_CFG_R3",
"STATE_MODE_CFG_I3",
+ "STATE_MODE_CFG_R4",
"STATE_IKE_ROOF"
};
"got Informational Message in clear", /* STATE_INFO */
"got encrypted Informational Message", /* STATE_INFO_PROTECTED */
- "sent XAUTH request, expecting reply", /* STATE_XAUTH_R1 */
- "sent XAUTH status, expecting ack", /* STATE_XAUTH_R2 */
- "received XAUTH ack, established", /* STATE_XAUTH_R3 */
"expecting XAUTH request", /* STATE_XAUTH_I0 */
+ "sent XAUTH request, expecting reply", /* STATE_XAUTH_R1 */
"sent XAUTH reply, expecting status", /* STATE_XAUTH_I1 */
+ "sent XAUTH status, expecting ack", /* STATE_XAUTH_R2 */
"sent XAUTH ack, established", /* STATE_XAUTH_I2 */
+ "received XAUTH ack, established", /* STATE_XAUTH_R3 */
"expecting ModeCfg request", /* STATE_MODE_CFG_R0 */
- "sent ModeCfg reply, expecting ack", /* STATE_MODE_CFG_R1 */
- "received ModeCfg ack, established" /* STATE_MODE_CFG_R2 */
"sent ModeCfg request, expecting reply", /* STATE_MODE_CFG_I1 */
- "sent ModeCfg ack, established", /* STATE_MODE_CFG_I2 */
- "received ModeCfg set, sent ack", /* STATE_MODE_CFG_I3 */
+ "sent ModeCfg reply, established", /* STATE_MODE_CFG_R1 */
+ "received ModeCfg reply, established", /* STATE_MODE_CFG_I2 */
+
+ "expecting ModeCfg set", /* STATE_MODE_CFG_I0 */
+ "sent ModeCfg set, expecting ack", /* STATE_MODE_CFG_R3 */
+ "sent ModeCfg ack, established", /* STATE_MODE_CFG_I3 */
+ "received ModeCfg ack, established", /* STATE_MODE_CFG_R4 */
};
/* kind of struct connection */
/* XAUTH states */
- STATE_XAUTH_R1, /* responder states (server) */
+ STATE_XAUTH_I0, /* initiator state (client) */
+ STATE_XAUTH_R1, /* responder state (server) */
+ STATE_XAUTH_I1,
STATE_XAUTH_R2,
+ STATE_XAUTH_I2,
STATE_XAUTH_R3,
- STATE_XAUTH_I0, /* initiator states (client) */
- STATE_XAUTH_I1,
- STATE_XAUTH_I2,
- /* Mode Config states */
+ /* Mode Config pull states */
- STATE_MODE_CFG_R0, /* responder states */
+ STATE_MODE_CFG_R0, /* responder state (server) */
+ STATE_MODE_CFG_I1, /* initiator state (client) */
STATE_MODE_CFG_R1,
- STATE_MODE_CFG_R2,
-
- STATE_MODE_CFG_I1, /* initiator states */
STATE_MODE_CFG_I2,
+
+ /* Mode Config push states */
+
+ STATE_MODE_CFG_I0, /* initiator state (client) */
+ STATE_MODE_CFG_R3, /* responder state (server) */
STATE_MODE_CFG_I3,
+ STATE_MODE_CFG_R4,
STATE_IKE_ROOF
};
LELEM(STATE_MAIN_R3) | LELEM(STATE_MAIN_I4) \
| LELEM(STATE_XAUTH_R1) | LELEM(STATE_XAUTH_R2) | LELEM(STATE_XAUTH_R3) \
| LELEM(STATE_XAUTH_I1) | LELEM(STATE_XAUTH_I2) \
- | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_R2) \
- | LELEM(STATE_MODE_CFG_I2) | LELEM(STATE_MODE_CFG_I3))
+ | LELEM(STATE_MODE_CFG_I1) | LELEM(STATE_MODE_CFG_R1) | LELEM(STATE_MODE_CFG_I2) \
+ | LELEM(STATE_MODE_CFG_R3) | LELEM(STATE_MODE_CFG_I3) | LELEM(STATE_MODE_CFG_R4))
#define IS_PHASE1(s) ((STATE_MAIN_R0 <= (s) && (s) <= STATE_MAIN_I4) \
- || (STATE_XAUTH_R1 <= (s) && (s) <= STATE_XAUTH_I2) \
- || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_I3))
+ || (STATE_XAUTH_I0 <= (s) && (s) <= STATE_XAUTH_R3) \
+ || (STATE_MODE_CFG_R0 <= (s) && (s) <= STATE_MODE_CFG_R4))
+
#define IS_QUICK(s) (STATE_QUICK_R0 <= (s) && (s) <= STATE_QUICK_R2)
#define IS_ISAKMP_ENCRYPTED(s) (STATE_MAIN_I2 <= (s))
-#define IS_ISAKMP_SA_ESTABLISHED(s) ( \
- (s) == STATE_MAIN_R3 \
- || (s) == STATE_MAIN_I4 \
- || (s) == STATE_XAUTH_R1 \
- || (s) == STATE_XAUTH_R2 \
- || (s) == STATE_XAUTH_R3 \
- || (s) == STATE_XAUTH_I1 \
- || (s) == STATE_XAUTH_I2 \
- || (s) == STATE_MODE_CFG_R1 \
- || (s) == STATE_MODE_CFG_R2 \
- || (s) == STATE_MODE_CFG_I2 \
- || (s) == STATE_MODE_CFG_I3)
+
+#define IS_ISAKMP_SA_ESTABLISHED(s) ( \
+ (s) == STATE_MAIN_R3 \
+ || (s) == STATE_MAIN_I4 \
+ || (s) == STATE_XAUTH_R3 \
+ || (s) == STATE_XAUTH_I2 \
+ || (s) == STATE_MODE_CFG_R1 \
+ || (s) == STATE_MODE_CFG_I2 \
+ || (s) == STATE_MODE_CFG_I3 \
+ || (s) == STATE_MODE_CFG_R4)
+
#define IS_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_I2 || (s) == STATE_QUICK_R2)
#define IS_ONLY_INBOUND_IPSEC_SA_ESTABLISHED(s) ((s) == STATE_QUICK_R1)
, P(HASH), LEMPTY, PT(NONE)
, EVENT_NULL, informational },
- /* XAUTH server */
+ /* XAUTH state transitions */
+ { STATE_XAUTH_I0, STATE_XAUTH_I1
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_RETRANSMIT, xauth_inI0 },
+
{ 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_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_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
+ { STATE_XAUTH_I2, 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
+ { STATE_XAUTH_R3, STATE_UNDEFINED
, SMF_ALL_AUTH | SMF_ENCRYPTED
, LEMPTY, LEMPTY, PT(NONE)
, EVENT_NULL, unexpected },
- /* MODE_CFG_x:
- * Case R0: Responder -> Initiator
- * <- Req(addr=0)
- * Reply(ad=x) ->
- *
- * Case R1: Set(addr=x) ->
- * <- Ack(ok)
- */
+ /* ModeCfg pull mode state transitions */
{ STATE_MODE_CFG_R0, STATE_MODE_CFG_R1
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
, P(ATTR) | P(HASH), P(VID), PT(HASH)
, EVENT_SA_REPLACE, modecfg_inR0 },
- { STATE_MODE_CFG_R1, STATE_MODE_CFG_R2
- , SMF_ALL_AUTH | SMF_ENCRYPTED
+ { STATE_MODE_CFG_I1, STATE_MODE_CFG_I2
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
, P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inR1 },
+ , EVENT_SA_REPLACE, modecfg_inI1 },
- { STATE_MODE_CFG_R2, STATE_UNDEFINED
+ { STATE_MODE_CFG_R1, STATE_UNDEFINED
, SMF_ALL_AUTH | SMF_ENCRYPTED
, LEMPTY, LEMPTY, PT(NONE)
, EVENT_NULL, unexpected },
- { STATE_MODE_CFG_I1, STATE_MODE_CFG_I2
- , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
- , P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inI1 },
+ { STATE_MODE_CFG_I2, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
+ /* ModeCfg push mode state transitions */
- { STATE_MODE_CFG_I2, STATE_MODE_CFG_I3
+ { STATE_MODE_CFG_I0, STATE_MODE_CFG_I3
, SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_REPLY | SMF_RELEASE_PENDING_P2
, P(ATTR) | P(HASH), P(VID), PT(HASH)
- , EVENT_SA_REPLACE, modecfg_inI2 },
+ , EVENT_SA_REPLACE, modecfg_inI0 },
+
+ { STATE_MODE_CFG_R3, STATE_MODE_CFG_R4
+ , SMF_ALL_AUTH | SMF_ENCRYPTED | SMF_RELEASE_PENDING_P2
+ , P(ATTR) | P(HASH), P(VID), PT(HASH)
+ , EVENT_SA_REPLACE, modecfg_inR3 },
{ STATE_MODE_CFG_I3, STATE_UNDEFINED
, SMF_ALL_AUTH | SMF_ENCRYPTED
, LEMPTY, LEMPTY, PT(NONE)
, EVENT_NULL, unexpected },
+ { STATE_MODE_CFG_R4, STATE_UNDEFINED
+ , SMF_ALL_AUTH | SMF_ENCRYPTED
+ , LEMPTY, LEMPTY, PT(NONE)
+ , EVENT_NULL, unexpected },
+
#undef P
#undef PT
};
return;
}
- if (st->st_state == STATE_MODE_CFG_R2) /* Have we just give an IP address to peer? */
- {
- st->st_state = STATE_MAIN_R3; /* ISAKMP is up... */
- }
-
set_cur_state(st);
if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state))
& (POLICY_XAUTH_RSASIG | POLICY_XAUTH_PSK))
!= LEMPTY;
- if (has_xauth_policy
+ if (has_xauth_policy && !st->st_xauth.started
&& IS_PHASE1(st->st_state))
{
from_state = STATE_XAUTH_I0;
else if (st->st_connection->spd.this.modecfg
&& IS_PHASE1(st->st_state))
{
- from_state = STATE_MODE_CFG_I2;
+ from_state = STATE_MODE_CFG_I0;
}
else
{
set_cur_state(st);
from_state = st->st_state;
}
-
break;
#ifdef NOTYET
}
if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- || IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ || IS_IPSEC_SA_ESTABLISHED(st->st_state))
{
/* log our success */
plog("%s%s", story, sadetails);
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;
+ }
+
/* Should we start ModeConfig as a client? */
if (st->st_connection->spd.this.modecfg
&& IS_ISAKMP_SA_ESTABLISHED(st->st_state)
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)
}
if (IS_ISAKMP_SA_ESTABLISHED(st->st_state)
- || IS_IPSEC_SA_ESTABLISHED(st->st_state))
+ || IS_IPSEC_SA_ESTABLISHED(st->st_state))
release_whack(st);
break;
#endif /* !VENDORID */
/*
- * are we sending an XAUTH VID (Cisco Mode Config Interoperability)?
- */
-#ifdef XAUTH_VID
-#define SEND_XAUTH_VID 1
-#else /* !XAUTH_VID */
-#define SEND_XAUTH_VID 0
-#endif /* !XAUTH_VID */
-
-/*
* are we sending a Cisco Unity VID?
*/
#ifdef CISCO_QUIRKS
/* determine how many Vendor ID payloads we will be sending */
if (SEND_PLUTO_VID)
vids_to_send++;
- if (SEND_XAUTH_VID)
- vids_to_send++;
if (SEND_CISCO_UNITY_VID)
vids_to_send++;
if (c->spd.this.cert.type == CERT_PGP)
vids_to_send++;
+ /* always send XAUTH Vendor ID */
+ vids_to_send++;
/* always send DPD Vendor ID */
vids_to_send++;
if (nat_traversal_enabled)
}
}
- /* if enabled send XAUTH Vendor ID */
- if (SEND_XAUTH_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &rbody, VID_MISC_XAUTH))
- {
- reset_cur_state();
- return STF_INTERNAL_ERROR;
- }
- }
-
/* if enabled send Cisco Unity Vendor ID */
if (SEND_CISCO_UNITY_VID)
{
}
}
+ /* Announce our ability to do eXtended AUTHentication to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &rbody, VID_MISC_XAUTH))
+ {
+ reset_cur_state();
+ return STF_INTERNAL_ERROR;
+ }
+
/* Announce our ability to do Dead Peer Detection to the peer */
{
if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
/* determine how many Vendor ID payloads we will be sending */
if (SEND_PLUTO_VID)
vids_to_send++;
- if (SEND_XAUTH_VID)
- vids_to_send++;
if (SEND_CISCO_UNITY_VID)
vids_to_send++;
if (md->openpgp)
vids_to_send++;
+ /* always send XAUTH Vendor ID */
+ vids_to_send++;
/* always send DPD Vendor ID */
vids_to_send++;
if (md->nat_traversal_vid && nat_traversal_enabled)
}
}
- /* if enabled send XAUTH Vendor ID */
- if (SEND_XAUTH_VID)
- {
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_XAUTH))
- {
- return STF_INTERNAL_ERROR;
- }
- }
-
/* if enabled send Cisco Unity Vendor ID */
if (SEND_CISCO_UNITY_VID)
{
}
}
+ /* Announce our ability to do eXtended AUTHentication to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_MISC_XAUTH))
+ {
+ return STF_INTERNAL_ERROR;
+ }
+
/* Announce our ability to do Dead Peer Detection to the peer */
+ if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
+ , &md->rbody, VID_MISC_DPD))
{
- if (!out_vendorid(vids_to_send-- ? ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE
- , &md->rbody, VID_MISC_DPD))
- {
- return STF_INTERNAL_ERROR;
- }
+ return STF_INTERNAL_ERROR;
}
if (md->nat_traversal_vid && nat_traversal_enabled)
{
struct state *const st = md->st;
pb_stream *const keyex_pbs = &md->chain[ISAKMP_NEXT_KE]->pbs;
- int auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
- ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
pb_stream id_pbs; /* ID Payload; also used for hash calculation */
certpolicy_t cert_policy = st->st_connection->spd.this.sendcert;
|| st->st_oakley.auth == XAUTHInitRSA
|| st->st_oakley.auth == XAUTHRespRSA;
+ int auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
+
/* KE in */
RETURN_STF_FAILURE(accept_KE(&st->st_gr, "Gr", st->st_oakley.group, keyex_pbs));
*/
echo_hdr(md, TRUE, ISAKMP_NEXT_ID);
- auth_payload = st->st_oakley.auth == OAKLEY_PRESHARED_KEY
- ? ISAKMP_NEXT_HASH : ISAKMP_NEXT_SIG;
+ auth_payload = RSA_auth ? ISAKMP_NEXT_SIG : ISAKMP_NEXT_HASH;
/* IDir out */
{
#include "whack.h" /* for RC_LOG_SERIOUS */
#include "timer.h"
#include "fetch.h"
+#include "xauth.h"
const char *shared_secrets_file = SHARED_SECRETS_FILE;
default:
plog("RSA public key allocation error");
}
- init_RSA_public_key(&pk->u.rsa, e, n);
-#ifdef DEBUG
- DBG(DBG_PRIVATE, RSA_show_public_key(&pk->u.rsa));
-#endif
+ init_RSA_public_key(&pk->u.rsa, e, n);
+ DBG(DBG_RAW,
+ RSA_show_public_key(&pk->u.rsa)
+ )
pk->alg = PUBKEY_ALG_RSA;
pk->id = empty_id;
his_id = &rw_id;
}
else if (kind == PPK_PSK
- && (c->policy & POLICY_PSK)
+ && (c->policy & (POLICY_PSK | POLICY_XAUTH_PSK))
&& ((c->kind == CK_TEMPLATE && c->spd.that.id.kind == ID_NONE) ||
(c->kind == CK_INSTANCE && id_is_ipaddr(&c->spd.that.id))))
{
}
else
{
- char buf[RSA_MAX_ENCODING_BYTES]; /* limit on size of binary representation of key */
+ char buf[BUF_LEN]; /* limit on size of binary representation of key */
size_t sz;
ugh = ttodatav(tok, flp->cur - tok, 0, buf, sizeof(buf), &sz
process_xauth(secret_t *s)
{
chunk_t user_name;
- chunk_t user_password;
s->kind = PPK_XAUTH;
user_name.ptr = tok;
user_name.len = flp->cur - tok;
}
+ plog(" loaded xauth credentials of user '%.*s'"
+ , user_name.len
+ , user_name.ptr);
+ clonetochunk(s->u.xauth_secret.user_name
+ , user_name.ptr, user_name.len, "xauth user name");
+
if (!shift())
return "missing xauth user password";
- if (*tok == '"' || *tok == '\'') /* quoted user password */
- {
- user_password.ptr = tok + 1;
- user_password.len = flp->cur - tok - 2;
- }
- else
- {
- user_password.ptr = tok;
- user_password.len = flp->cur - tok;
- }
- if (shift())
- return "unexpected token after xauth user passpword";
- clonetochunk(s->u.xauth_secret.user_name
- , user_name.ptr, user_name.len, "user_name");
- clonetochunk(s->u.xauth_secret.user_password
- , user_password.ptr, user_password.len, "user_password");
- return NULL;
+ return process_psk_secret(&s->u.xauth_secret.user_password);
}
/* get XAUTH secret from chained secrets lists
* only one entry is currently supported
*/
-bool
+static bool
xauth_get_secret(xauth_t *xauth_secret)
{
secret_t *s;
/*
* find a matching secret
*/
-bool
+static bool
xauth_verify_secret(const xauth_t *xauth_secret)
{
+ bool found = FALSE;
secret_t *s;
for (s = secrets; s != NULL; s = s->next)
{
if (!same_chunk(xauth_secret->user_name, s->u.xauth_secret.user_name))
continue;
+ found = TRUE;
if (same_chunk(xauth_secret->user_password, s->u.xauth_secret.user_password))
return TRUE;
}
}
+ plog("xauth user '%.*s' %s"
+ , xauth_secret->user_name.len, xauth_secret->user_name.ptr
+ , found? "sent wrong password":"not found");
return FALSE;
}
/*
+ * the global xauth_module struct is defined here
+ */
+xauth_module_t xauth_module;
+
+/*
+ * assign the default xauth functions to any null function pointers
+ */
+void
+xauth_defaults(void)
+{
+ if (xauth_module.get_secret == NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth_module: using default get_secret() function")
+ )
+ xauth_module.get_secret = xauth_get_secret;
+ }
+ if (xauth_module.verify_secret == NULL)
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("xauth_module: using default verify_secret() function")
+ )
+ xauth_module.verify_secret = xauth_verify_secret;
+ }
+};
+
+/*
* process pin read from ipsec.secrets or prompted for it using whack
*/
static err_t
return RSA_MAX_OCTETS_UGH;
init_RSA_public_key(rsa, exp, mod);
-
-#ifdef DEBUG
- DBG(DBG_PRIVATE, RSA_show_public_key(rsa));
-#endif
-
-
rsa->k = mpz_sizeinbase(&rsa->n, 2); /* size in bits, for a start */
rsa->k = (rsa->k + BITS_PER_BYTE - 1) / BITS_PER_BYTE; /* now octets */
+ DBG(DBG_RAW,
+ RSA_show_public_key(rsa)
+ )
if (rsa->k != mod.len)
{
PPK_PIN
};
+extern void xauth_defaults(void);
+
+/* forward declaration */
+struct connection;
+
extern const chunk_t *get_preshared_secret(const struct connection *c);
extern err_t unpack_RSA_public_key(RSA_public_key_t *rsa, const chunk_t *pubkey);
extern const RSA_private_key_t *get_RSA_private_key(const struct connection *c);
extern pubkey_t *reference_key(pubkey_t *pk);
extern void unreference_key(pubkey_t **pkp);
-
extern err_t add_public_key(const struct id *id
, enum dns_auth_level dns_auth_level
, enum pubkey_alg alg
extern void remove_x509_public_key(const x509cert_t *cert);
extern void list_public_keys(bool utc);
-/* XAUTH credentials */
-
-typedef struct {
- chunk_t user_name;
- chunk_t user_password;
-} xauth_t;
-
-extern bool xauth_get_secrect(const xauth_t *xauth_secret);
-extern bool xauth_verify_secret(const xauth_t *xauth_secret);
-
struct gw_info; /* forward declaration of tag (defined in dnskey.h) */
extern void transfer_to_public_keys(struct gw_info *gateways_from_dns
#ifdef USE_KEYRR
#include "crypto.h"
#include "modecfg.h"
#include "whack.h"
-#include "keys.h"
+#include "xauth.h"
+
+#define MAX_XAUTH_TRIES 3
#define SUPPORTED_ATTR_SET ( LELEM(INTERNAL_IP4_ADDRESS) \
| LELEM(INTERNAL_IP4_NETMASK) \
, 0 /* XXX isama_id */
);
+ freeanychunk(st->st_tpacket);
clonetochunk(st->st_tpacket, msg.start, pbs_offset(&msg), "ModeCfg msg");
/* Transmit */
}
/*
- * Send ModeCfg request message from client to server in pull mode
- */
-stf_status
-modecfg_send_request(struct state *st)
-{
- stf_status stat;
- internal_addr_t ia;
-
- init_internal_addr(&ia);
- ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
- | LELEM(INTERNAL_IP4_NETMASK);
-
- plog("sending ModeCfg request");
- st->st_state = STATE_MODE_CFG_I1;
- stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
- if (stat == STF_OK)
- st->st_modecfg.started = TRUE;
- return stat;
-}
-
-/*
- * Send ModeCfg set message from server to client in push mode
- */
-stf_status
-modecfg_send_set(struct state *st)
-{
- stf_status stat;
- internal_addr_t ia;
-
- get_internal_addr(st->st_connection, &ia);
-
- plog("sending ModeCfg set");
- st->st_state = STATE_MODE_CFG_R1;
- stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
- if (stat == STF_OK)
- st->st_modecfg.started = TRUE;
- return stat;
-}
-
-/*
- * Send XAUTH credentials request (username + password)
- */
-stf_status
-xauth_send_request(struct state *st)
-{
- stf_status stat;
- internal_addr_t ia;
-
- init_internal_addr(&ia);
- ia.attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)
- | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF);
-
- plog("sending XAUTH request");
- st->st_state = STATE_XAUTH_R1;
- stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
- if (stat == STF_OK)
- st->st_xauth.started = TRUE;
- return stat;
-}
-
-/*
* Parse a ModeCfg attribute payload
*/
static stf_status
return STF_IGNORE;
}
+/*
+ * Send ModeCfg request message from client to server in pull mode
+ */
+stf_status
+modecfg_send_request(struct state *st)
+{
+ stf_status stat;
+ internal_addr_t ia;
+
+ init_internal_addr(&ia);
+ ia.attr_set = LELEM(INTERNAL_IP4_ADDRESS)
+ | LELEM(INTERNAL_IP4_NETMASK);
+
+ plog("sending ModeCfg request");
+ st->st_state = STATE_MODE_CFG_I1;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
+ if (stat == STF_OK)
+ st->st_modecfg.started = TRUE;
+ return stat;
+}
+
/* STATE_MODE_CFG_R0:
* HDR*, HASH, ATTR(REQ=IP) --> HDR*, HASH, ATTR(REPLY=IP)
*
struct state *const st = md->st;
u_int16_t isama_id;
internal_addr_t ia;
- stf_status stat;
+ stf_status stat, stat_build;
stat = modecfg_parse_msg(md, ISAKMP_CFG_REQUEST, &isama_id, &ia);
if (stat != STF_OK)
return stat;
-
+
get_internal_addr(st->st_connection, &ia);
plog("sending ModeCfg reply");
- stat = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_REPLY
- , &ia
- , isama_id);
- if (stat != STF_OK)
- {
- /* notification payload - not exactly the right choice, but okay */
- md->note = ATTRIBUTES_NOT_SUPPORTED;
- return stat;
- }
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_REPLY
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
st->st_msgid = 0;
return STF_OK;
}
-/* STATE_MODE_CFG_R1:
- * HDR*, HASH, ATTR(ACK,OK)
+/* STATE_MODE_CFG_I1:
+ * HDR*, HASH, ATTR(REPLY=IP)
*
- * used in ModeCfg push mode, on the server (responder)
+ * used in ModeCfg pull mode, on the client (initiator)
*/
stf_status
-modecfg_inR1(struct msg_digest *md)
+modecfg_inI1(struct msg_digest *md)
{
struct state *const st = md->st;
u_int16_t isama_id;
internal_addr_t ia;
stf_status stat;
- plog("parsing ModeCfg ack");
+ plog("parsing ModeCfg reply");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
if (stat != STF_OK)
return stat;
+ st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
st->st_msgid = 0;
return STF_OK;
}
-/* STATE_MODE_CFG_I1:
- * HDR*, HASH, ATTR(REPLY=IP)
- *
- * used in ModeCfg pull mode, on the client (initiator)
+
+/*
+ * Send ModeCfg set message from server to client in push mode
*/
stf_status
-modecfg_inI1(struct msg_digest *md)
+modecfg_send_set(struct state *st)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
stf_status stat;
+ internal_addr_t ia;
- plog("parsing ModeCfg reply");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
+ get_internal_addr(st->st_connection, &ia);
- st->st_modecfg.vars_set = set_internal_addr(st->st_connection, &ia);
- st->st_msgid = 0;
- return STF_OK;
+ plog("sending ModeCfg set");
+ st->st_state = STATE_MODE_CFG_R3;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_SET, &ia);
+ if (stat == STF_OK)
+ st->st_modecfg.started = TRUE;
+ return stat;
}
-/* STATE_MODE_CFG_I2:
+/* STATE_MODE_CFG_I0:
* HDR*, HASH, ATTR(SET=IP) --> HDR*, HASH, ATTR(ACK,OK)
*
* used in ModeCfg push mode, on the client (initiator).
*/
stf_status
-modecfg_inI2(struct msg_digest *md)
+modecfg_inI0(struct msg_digest *md)
{
struct state *const st = md->st;
u_int16_t isama_id;
internal_addr_t ia;
lset_t attr_set;
- stf_status stat;
+ stf_status stat, stat_build;
plog("parsing ModeCfg set");
plog("sending ModeCfg ack");
- stat = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_ACK
- , &ia
- , isama_id);
- if (stat != STF_OK)
- {
- /* notification payload - not exactly the right choice, but okay */
- md->note = ATTRIBUTES_NOT_SUPPORTED;
- return stat;
- }
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_ACK
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
st->st_msgid = 0;
return STF_OK;
}
-/* STATE_XAUTH_R1:
- * HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD) --> HDR*, HASH, ATTR(STATUS)
+/* STATE_MODE_CFG_R3:
+ * HDR*, HASH, ATTR(ACK,OK)
*
- * used on the XAUTH server (responder)
+ * used in ModeCfg push mode, on the server (responder)
*/
stf_status
-xauth_inR1(struct msg_digest *md)
+modecfg_inR3(struct msg_digest *md)
{
struct state *const st = md->st;
u_int16_t isama_id;
internal_addr_t ia;
stf_status stat;
- bool status;
- plog("parsing XAUTH reply");
+ plog("parsing ModeCfg ack");
- stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
if (stat != STF_OK)
return stat;
- /* check XAUTH reply */
- if ((ia.attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF)) != LEMPTY)
- {
- plog("received FAIL status in XAUTH reply");
- return STF_INTERNAL_ERROR;
- }
- if ((ia.attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
- {
- plog("user name attribute is missing in XAUTH reply");
- return STF_SUSPEND;
- }
- if ((ia.attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
- {
- plog("user password attribute is missing in XAUTH reply");
- return STF_SUSPEND;
- }
-
- status = xauth_verify_secret(&ia.xauth_secret);
-
- /* prepare XAUTH set which sends the authentication status */
- init_internal_addr(&ia);
- ia.attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF);
- ia.xauth_status = status;
-
- plog("sending XAUTH status: %s", status? "OK":"FAIL");
-
- stat = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_SET
- , &ia
- , isama_id);
+ st->st_msgid = 0;
return STF_OK;
}
-/* STATE_XAUTH_R2:
- * HDR*, ATTR(STATUS), HASH --> Done
- *
- * used on the XAUTH server (responder)
+/*
+ * Send XAUTH credentials request (username + password)
*/
stf_status
-xauth_inR2(struct msg_digest *md)
+xauth_send_request(struct state *st)
{
- struct state *const st = md->st;
- u_int16_t isama_id;
- internal_addr_t ia;
stf_status stat;
+ internal_addr_t ia;
- plog("parsing XAUTH ack");
-
- stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
- if (stat != STF_OK)
- return stat;
+ init_internal_addr(&ia);
+ ia.attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)
+ | LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF);
- st->st_msgid = 0;
- return STF_OK;
+ plog("sending XAUTH request");
+ st->st_state = STATE_XAUTH_R1;
+ stat = modecfg_send_msg(st, ISAKMP_CFG_REQUEST, &ia);
+ if (stat == STF_OK)
+ st->st_xauth.started = TRUE;
+ return stat;
}
/* STATE_XAUTH_I0:
struct state *const st = md->st;
u_int16_t isama_id;
internal_addr_t ia;
- stf_status stat;
+ stf_status stat, stat_build;
plog("parsing XAUTH request");
if (stat != STF_OK)
return stat;
- /* check XAUTH request */
+ /* check XAUTH attributes */
if ((ia.attr_set & LELEM(XAUTH_TYPE - XAUTH_BASE + MODECFG_ROOF)) != LEMPTY
&& ia.xauth_type != XAUTH_TYPE_GENERIC)
{
plog("xauth type %s is not supported", enum_name(&xauth_type_names, ia.xauth_type));
stat = STF_FAIL;
}
- if ((ia.attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
+ else if ((ia.attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
{
plog("user name attribute is missing in XAUTH request");
stat = STF_FAIL;
}
- if ((ia.attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
+ else if ((ia.attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
{
plog("user password attribute is missing in XAUTH request");
stat = STF_FAIL;
if (stat == STF_OK)
{
- /* get user credentials */
- if (!xauth_get_secret(&ia.xauth_secret))
+ /* get user credentials using a plugin function */
+ if (!xauth_module.get_secret(&ia.xauth_secret))
{
plog("xauth user credentials not found");
stat = STF_FAIL;
}
if (stat == STF_OK)
{
+ DBG(DBG_CONTROL,
+ DBG_log("my xauth user name is '%.*s'"
+ , ia.xauth_secret.user_name.len
+ , ia.xauth_secret.user_name.ptr)
+ )
+ DBG(DBG_PRIVATE,
+ DBG_log("my xauth user password is '%.*s'"
+ , ia.xauth_secret.user_password.len
+ , ia.xauth_secret.user_password.ptr)
+ )
ia.attr_set = LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)
| LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF);
}
plog("sending XAUTH reply");
- stat = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_REPLY
- , &ia
- , isama_id);
- if (stat != STF_OK)
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_REPLY
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
+
+ if (stat == STF_OK)
{
- /* notification payload - not exactly the right choice, but okay */
- md->note = ATTRIBUTES_NOT_SUPPORTED;
+ st->st_xauth.started = TRUE;
+ return STF_OK;
+ }
+ else
+ {
+ /* send XAUTH reply msg and then delete ISAKMP SA */
+ freeanychunk(st->st_tpacket);
+ clonetochunk(st->st_tpacket, md->reply.start
+ , pbs_offset(&md->reply), "XAUTH reply msg");
+ send_packet(st, "XAUTH reply msg");
+ delete_state(st);
+ return STF_IGNORE;
+ }
+}
+
+/* STATE_XAUTH_R1:
+ * HDR*, HASH, ATTR(REPLY=USERNAME/PASSWORD) --> HDR*, HASH, ATTR(STATUS)
+ *
+ * used on the XAUTH server (responder)
+ */
+stf_status
+xauth_inR1(struct msg_digest *md)
+{
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat, stat_build;
+
+ plog("parsing XAUTH reply");
+
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_REPLY, &isama_id, &ia);
+ if (stat != STF_OK)
return stat;
+
+ /* did the client return an XAUTH FAIL status? */
+ if ((ia.attr_set & LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF)) != LEMPTY)
+ {
+ plog("received FAIL status in XAUTH reply");
+
+ /* client is not able to do XAUTH, delete ISAKMP SA */
+ delete_state(st);
+ return STF_IGNORE;
+ }
+
+ /* check XAUTH reply */
+ if ((ia.attr_set & LELEM(XAUTH_USER_NAME - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
+ {
+ plog("user name attribute is missing in XAUTH reply");
+ st->st_xauth.status = FALSE;
}
- st->st_xauth.started = TRUE;
+ else if ((ia.attr_set & LELEM(XAUTH_USER_PASSWORD - XAUTH_BASE + MODECFG_ROOF)) == LEMPTY)
+ {
+ plog("user password attribute is missing in XAUTH reply");
+ st->st_xauth.status = FALSE;
+ }
+ else
+ {
+ DBG(DBG_CONTROL,
+ DBG_log("peer xauth user name is '%.*s'"
+ , ia.xauth_secret.user_name.len
+ , ia.xauth_secret.user_name.ptr)
+ )
+ DBG(DBG_PRIVATE,
+ DBG_log("peer xauth user password is '%.*s'"
+ , ia.xauth_secret.user_password.len
+ , ia.xauth_secret.user_password.ptr)
+ )
+ /* verify the user credentials using a plugn function */
+ st->st_xauth.status = xauth_module.verify_secret(&ia.xauth_secret);
+ plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
+ }
+
+ /* prepare XAUTH set which sends the authentication status */
+ init_internal_addr(&ia);
+ ia.attr_set = LELEM(XAUTH_STATUS - XAUTH_BASE + MODECFG_ROOF);
+ ia.xauth_status = st->st_xauth.status;
+
+ plog("sending XAUTH status:");
+
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_SET
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
return STF_OK;
}
stf_status
xauth_inI1(struct msg_digest *md)
{
- struct state *const st = md->st;
+ struct state *const st = md->st;
u_int16_t isama_id;
internal_addr_t ia;
- stf_status stat;
+ stf_status stat, stat_build;
plog("parsing XAUTH status");
-
stat = modecfg_parse_msg(md, ISAKMP_CFG_SET, &isama_id, &ia);
if (stat != STF_OK)
+ {
+ /* notification payload - not exactly the right choice, but okay */
+ md->note = ATTRIBUTES_NOT_SUPPORTED;
return stat;
+ }
- /* prepare XAUTH set which sends the authentication status */
- init_internal_addr(&ia);
+ st->st_xauth.status = ia.xauth_status;
+ plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
plog("sending XAUTH ack");
+ init_internal_addr(&ia);
+ stat_build = modecfg_build_msg(st, &md->rbody
+ , ISAKMP_CFG_ACK
+ , &ia
+ , isama_id);
+ if (stat_build != STF_OK)
+ return stat_build;
+
+ if (st->st_xauth.status)
+ {
+ st->st_msgid = 0;
+ return STF_OK;
+ }
+ else
+ {
+ /* send XAUTH ack msg and then delete ISAKMP SA */
+ freeanychunk(st->st_tpacket);
+ clonetochunk(st->st_tpacket, md->reply.start
+ , pbs_offset(&md->reply), "XAUTH ack msg");
+ send_packet(st, "XAUTH ack msg");
+ delete_state(st);
+ return STF_IGNORE;
+ }
+}
+
+/* STATE_XAUTH_R2:
+ * HDR*, ATTR(STATUS), HASH --> Done
+ *
+ * used on the XAUTH server (responder)
+ */
+stf_status
+xauth_inR2(struct msg_digest *md)
+{
+ struct state *const st = md->st;
+ u_int16_t isama_id;
+ internal_addr_t ia;
+ stf_status stat;
+
+ plog("parsing XAUTH ack");
+
+ stat = modecfg_parse_msg(md, ISAKMP_CFG_ACK, &isama_id, &ia);
+ if (stat != STF_OK)
+ return stat;
- stat = modecfg_build_msg(st, &md->rbody
- , ISAKMP_CFG_ACK
- , &ia
- , isama_id);
st->st_msgid = 0;
- return stat;
+ if (st->st_xauth.status)
+ {
+ return STF_OK;
+ }
+ else
+ {
+ delete_state(st);
+ return STF_IGNORE;
+ }
}
struct state;
struct msg_digest;
-/* ModeConfig starting functions */
+/* ModeConfig pull mode start function */
extern stf_status modecfg_send_request(struct state *st);
-extern stf_status modecfg_send_set(struct state *st);
-/* ModeConfig state transition functions */
+/* ModeConfig pull mode state transition functions */
extern stf_status modecfg_inR0(struct msg_digest *md);
-extern stf_status modecfg_inR1(struct msg_digest *md);
extern stf_status modecfg_inI1(struct msg_digest *md);
-extern stf_status modecfg_inI2(struct msg_digest *md);
+
+/* ModeConfig push mode start function */
+extern stf_status modecfg_send_set(struct state *st);
+
+/* ModeConfig push mode state transition functions */
+extern stf_status modecfg_inI0(struct msg_digest *md);
+extern stf_status modecfg_inR3(struct msg_digest *md);
/* XAUTH start function */
extern stf_status xauth_send_request(struct state *st);
/* XAUTH state transition funcgtions */
-extern stf_status xauth_inR1(struct msg_digest *md);
-extern stf_status xauth_inR2(struct msg_digest *md);
extern stf_status xauth_inI0(struct msg_digest *md);
+extern stf_status xauth_inR1(struct msg_digest *md);
extern stf_status xauth_inI1(struct msg_digest *md);
+extern stf_status xauth_inR2(struct msg_digest *md);
#endif /* _MODECFG_H */
struct {
int attempt;
bool started;
+ bool status;
} st_xauth;
u_int32_t nat_traversal;
md->dpd = TRUE;
vid_useful = TRUE;
break;
+ case VID_MISC_XAUTH:
+ vid_useful = TRUE;
+ break;
default:
break;
}
--- /dev/null
+/* Initialization and finalization of the dynamic XAUTH module
+ * Copyright (C) 2006 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: xauth.c,v 1.1 2005/01/06 22:10:15 as Exp $
+ */
+
+#include <freeswan.h>
+
+#include "constants.h"
+#include "defs.h"
+#include "xauth.h"
+#include "keys.h"
+
+void
+xauth_init(void)
+{
+ /* TODO: locate and load dynamic XAUTH module */
+ xauth_defaults();
+}
+
+void
+xauth_finalize(void)
+{
+ /* TODO: unload dynamic XAUTH module */
+}
--- /dev/null
+/* Interface definition of the XAUTH server and|or client module
+ * Copyright (C) 2006 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil, Switzerland
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * RCSID $Id: xauth.h,v 1.1 2005/01/06 22:10:15 as Exp $
+ */
+
+#ifndef _XAUTH_H
+#define _XAUTH_H
+
+/* XAUTH credentials */
+
+struct chunk_t;
+
+typedef struct {
+ chunk_t user_name;
+ chunk_t user_password;
+} xauth_t;
+
+typedef struct {
+ bool (*get_secret) (const xauth_t *xauth_secret);
+ bool (*verify_secret) (const xauth_t *xauth_secret);
+} xauth_module_t;
+
+extern xauth_module_t xauth_module;
+
+extern void xauth_init(void);
+extern void xauth_finalize(void);
+
+#endif /* _XAUTH_H */