ARG_ENABL_SET([mediation], [enable IKEv2 Mediation Extension.])
ARG_ENABL_SET([integrity-test], [enable integrity testing of libstrongswan and plugins.])
ARG_DISBL_SET([pluto], [disable the IKEv1 keying daemon pluto.])
+ARG_DISBL_SET([xauth], [disable xauth plugin.])
ARG_DISBL_SET([threads], [disable the use of threads in pluto. Charon always uses threads.])
ARG_DISBL_SET([charon], [disable the IKEv2 keying daemon charon.])
ARG_DISBL_SET([tools], [disable additional utilities (openac, scepclient and pki).])
libstrongswan_plugins=${libstrongswan_plugins}" gmp"
pluto_plugins=${pluto_plugins}" gmp"
fi
+if test x$xauth = xtrue; then
+ pluto_plugins=${pluto_plugins}" xauth"
+fi
if test x$attr = xtrue; then
libhydra_plugins=${libhydra_plugins}" attr"
fi
AM_CONDITIONAL(USE_XCBC, test x$xcbc = xtrue)
AM_CONDITIONAL(USE_MYSQL, test x$mysql = xtrue)
AM_CONDITIONAL(USE_SQLITE, test x$sqlite = xtrue)
-AM_CONDITIONAL(USE_ATTR_SQL, test x$attr_sql = xtrue -o x$sql = xtrue)
AM_CONDITIONAL(USE_PADLOCK, test x$padlock = xtrue)
AM_CONDITIONAL(USE_OPENSSL, test x$openssl = xtrue)
AM_CONDITIONAL(USE_GCRYPT, test x$gcrypt = xtrue)
AM_CONDITIONAL(USE_SMP, test x$smp = xtrue)
AM_CONDITIONAL(USE_SQL, test x$sql = xtrue)
AM_CONDITIONAL(USE_UPDOWN, test x$updown = xtrue)
-AM_CONDITIONAL(USE_ATTR, test x$attr = xtrue)
AM_CONDITIONAL(USE_DHCP, test x$dhcp = xtrue)
-AM_CONDITIONAL(USE_RESOLVE, test x$resolve = xtrue)
AM_CONDITIONAL(USE_UNIT_TESTS, test x$unit_tests = xtrue)
AM_CONDITIONAL(USE_LOAD_TESTER, test x$load_tester = xtrue)
AM_CONDITIONAL(USE_HA, test x$ha = xtrue)
AM_CONDITIONAL(USE_SOCKET_DYNAMIC, test x$socket_dynamic = xtrue)
AM_CONDITIONAL(USE_FARP, test x$farp = xtrue)
+dnl hydra plugins
+dnl =============
+AM_CONDITIONAL(USE_ATTR, test x$attr = xtrue)
+AM_CONDITIONAL(USE_ATTR_SQL, test x$attr_sql = xtrue -o x$sql = xtrue)
+AM_CONDITIONAL(USE_RESOLVE, test x$resolve = xtrue)
+
+dnl pluto plugins
+dnl =============
+AM_CONDITIONAL(USE_XAUTH, test x$xauth = xtrue)
+
dnl other options
dnl =============
AM_CONDITIONAL(USE_SMARTCARD, test x$smartcard = xtrue)
src/libfreeswan/Makefile
src/libsimaka/Makefile
src/pluto/Makefile
+ src/pluto/plugins/xauth/Makefile
src/whack/Makefile
src/charon/Makefile
src/libcharon/Makefile
libs = $(shell find $(top_builddir)/src/libstrongswan \
$(top_builddir)/src/libcharon \
$(top_builddir)/src/libhydra \
+ $(top_builddir)/src/pluto \
-name 'libstrongswan*.so')
if USE_LIBHYDRA
ocsp.c ocsp.h \
packet.c packet.h \
pkcs7.c pkcs7.h \
+pluto.c pluto.h \
plutomain.c \
rcv_whack.c rcv_whack.h \
server.c server.h \
vendor.c vendor.h \
virtual.c virtual.h \
whack_attribute.c whack_attribute.h \
-xauth.c xauth.h \
+xauth/xauth_manager.c xauth/xauth_manager.h \
+xauth/xauth_provider.h xauth/xauth_verifier.h \
x509.c x509.h \
builder.c builder.h \
rsaref/pkcs11t.h rsaref/pkcs11.h rsaref/unix.h rsaref/pkcs11f.h
-I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/whack
-AM_CFLAGS = \
+AM_CFLAGS = -rdynamic \
-DIPSEC_DIR=\"${ipsecdir}\" \
-DIPSEC_CONFDIR=\"${sysconfdir}\" \
-DIPSEC_PIDDIR=\"${piddir}\" \
dist_man_MANS = pluto.8 ipsec.secrets.5
+# compile options
+#################
+
# This compile option activates the sending of a strongSwan VID
if USE_VENDORID
AM_CFLAGS += -DVENDORID
if USE_THREADS
AM_CFLAGS += -DTHREADS
endif
+
+# build optional plugins
+########################
+
+SUBDIRS = .
+
+if USE_XAUTH
+ SUBDIRS += plugins/xauth
+endif
+
+
#include "whack.h" /* for RC_LOG_SERIOUS */
#include "timer.h"
#include "fetch.h"
-#include "xauth.h"
const char *shared_secrets_file = SHARED_SECRETS_FILE;
-typedef struct id_list id_list_t;
-struct id_list {
- identification_t *id;
- id_list_t *next;
+typedef enum secret_kind_t secret_kind_t;
+
+enum secret_kind_t {
+ SECRET_PSK,
+ SECRET_PUBKEY,
+ SECRET_XAUTH,
+ SECRET_PIN
};
-typedef struct secret secret_t;
+typedef struct secret_t secret_t;
-struct secret {
- id_list_t *ids;
- enum PrivateKeyKind kind;
+struct secret_t {
+ linked_list_t *ids;
+ secret_kind_t kind;
union {
chunk_t preshared_secret;
- xauth_t xauth_secret;
private_key_t *private_key;
smartcard_t *smartcard;
} u;
secret_t *secrets = NULL;
-/* find the struct secret associated with the combination of
- * me and the peer. We match the Id (if none, the IP address).
- * Failure is indicated by a NULL.
+/**
+ * Find the secret associated with the combination of me and the peer.
*/
-static const secret_t* get_secret(const connection_t *c,
- enum PrivateKeyKind kind, bool asym)
+const secret_t* match_secret(identification_t *my_id, identification_t *his_id,
+ secret_kind_t kind)
{
enum { /* bits */
match_default = 0x01,
};
unsigned int best_match = 0;
- secret_t *best = NULL;
- secret_t *s;
- identification_t *my_id, *his_id;
+ secret_t *s, *best = NULL;
- /* is there a certificate assigned to this connection? */
- if (kind == PPK_PUBKEY && c->spd.this.cert)
+ for (s = secrets; s != NULL; s = s->next)
{
- certificate_t *certificate = c->spd.this.cert->cert;
+ unsigned int match = 0;
- public_key_t *pub_key = certificate->get_public_key(certificate);
-
- for (s = secrets; s != NULL; s = s->next)
+ if (s->kind != kind)
{
- if (s->kind == kind &&
- s->u.private_key->belongs_to(s->u.private_key, pub_key))
- {
- best = s;
- break; /* we have found the private key - no sense in searching further */
- }
+ continue;
}
- pub_key->destroy(pub_key);
- return best;
- }
-
- my_id = c->spd.this.id;
-
- if (his_id_was_instantiated(c))
- {
- /* roadwarrior: replace him with 0.0.0.0 */
- his_id = identification_create_from_string("%any");
- }
- else if (kind == PPK_PSK && (c->policy & (POLICY_PSK | POLICY_XAUTH_PSK)) &&
- ((c->kind == CK_TEMPLATE &&
- c->spd.that.id->get_type(c->spd.that.id) == ID_ANY) ||
- (c->kind == CK_INSTANCE && id_is_ipaddr(c->spd.that.id))))
- {
- /* roadwarrior: replace him with 0.0.0.0 */
- his_id = identification_create_from_string("%any");
- }
- else
- {
- his_id = c->spd.that.id->clone(c->spd.that.id);
- }
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == kind)
+ if (s->ids->get_count(s->ids) == 0)
+ {
+ /* a default (signified by lack of ids):
+ * accept if no more specific match found
+ */
+ match = match_default;
+ }
+ else
{
- unsigned int match = 0;
+ /* check if both ends match ids */
+ enumerator_t *enumerator;
+ identification_t *id;
- if (s->ids == NULL)
- {
- /* a default (signified by lack of ids):
- * accept if no more specific match found
- */
- match = match_default;
- }
- else
+ enumerator = s->ids->create_enumerator(s->ids);
+ while (enumerator->enumerate(enumerator, &id))
{
- /* check if both ends match ids */
- id_list_t *i;
-
- for (i = s->ids; i != NULL; i = i->next)
+ if (my_id->equals(my_id, id))
{
- if (my_id->equals(my_id, i->id))
- {
- match |= match_me;
- }
- if (his_id->equals(his_id, i->id))
- {
- match |= match_him;
- }
+ match |= match_me;
}
-
- /* If our end matched the only id in the list,
- * default to matching any peer.
- * A more specific match will trump this.
- */
- if (match == match_me && s->ids->next == NULL)
+ if (his_id->equals(his_id, id))
{
- match |= match_default;
+ match |= match_him;
}
}
+ enumerator->destroy(enumerator);
- switch (match)
+ /* If our end matched the only id in the list,
+ * default to matching any peer.
+ * A more specific match will trump this.
+ */
+ if (match == match_me && s->ids->get_count(s->ids) == 1)
{
+ match |= match_default;
+ }
+ }
+
+ switch (match)
+ {
case match_me:
/* if this is an asymmetric (eg. public key) system,
* allow this-side-only match to count, even if
* there are other ids in the list.
*/
- if (!asym)
+ if (kind != SECRET_PUBKEY)
{
break;
}
/* FALLTHROUGH */
- case match_default: /* default all */
- case match_me | match_default: /* default peer */
- case match_me | match_him: /* explicit */
+ case match_default: /* default all */
+ case match_me | match_default: /* default peer */
+ case match_me | match_him: /* explicit */
if (match == best_match)
{
- /* two good matches are equally good:
- * do they agree?
- */
+ /* two good matches are equally good: do they agree? */
bool same = FALSE;
switch (kind)
{
- case PPK_PSK:
- same = s->u.preshared_secret.len == best->u.preshared_secret.len
- && memeq(s->u.preshared_secret.ptr, best->u.preshared_secret.ptr, s->u.preshared_secret.len);
+ case SECRET_PSK:
+ case SECRET_XAUTH:
+ same = chunk_equals(s->u.preshared_secret,
+ best->u.preshared_secret);
break;
- case PPK_PUBKEY:
- same = s->u.private_key->equals(s->u.private_key, best->u.private_key);
+ case SECRET_PUBKEY:
+ same = s->u.private_key->equals(s->u.private_key,
+ best->u.private_key);
break;
default:
bad_case(kind);
}
if (!same)
{
- loglog(RC_LOG_SERIOUS, "multiple ipsec.secrets entries with distinct secrets match endpoints:"
- " first secret used");
+ loglog(RC_LOG_SERIOUS, "multiple ipsec.secrets entries with "
+ "distinct secrets match endpoints: first secret used");
best = s; /* list is backwards: take latest in list */
}
}
best_match = match;
best = s;
}
- }
}
}
+ return best;
+}
+
+/**
+ * Retrieves an XAUTH secret primarily based on the user ID and
+ * secondarily based on the server ID
+ */
+bool get_xauth_secret(identification_t *user, identification_t *server,
+ chunk_t *secret)
+{
+ const secret_t *s;
+
+ s = match_secret(user, server, SECRET_XAUTH);
+ if (s)
+ {
+ *secret = chunk_clone(s->u.preshared_secret);
+ return TRUE;
+ }
+ else
+ {
+ *secret = chunk_empty;
+ return FALSE;
+ }
+}
+
+/**
+ * We match the ID (if none, the IP address). Failure is indicated by a NULL.
+ */
+static const secret_t* get_secret(const connection_t *c, secret_kind_t kind)
+{
+ identification_t *my_id, *his_id;
+ const secret_t *best;
+
+ my_id = c->spd.this.id;
+
+ if (his_id_was_instantiated(c))
+ {
+ /* roadwarrior: replace him with 0.0.0.0 */
+ his_id = identification_create_from_string("%any");
+ }
+ else if (kind == SECRET_PSK && (c->policy & (POLICY_PSK | POLICY_XAUTH_PSK)) &&
+ ((c->kind == CK_TEMPLATE &&
+ c->spd.that.id->get_type(c->spd.that.id) == ID_ANY) ||
+ (c->kind == CK_INSTANCE && id_is_ipaddr(c->spd.that.id))))
+ {
+ /* roadwarrior: replace him with 0.0.0.0 */
+ his_id = identification_create_from_string("%any");
+ }
+ else
+ {
+ his_id = c->spd.that.id->clone(c->spd.that.id);
+ }
+
+ best = match_secret(my_id, his_id, kind);
+
his_id->destroy(his_id);
return best;
}
*/
const chunk_t* get_preshared_secret(const connection_t *c)
{
- const secret_t *s = get_secret(c, PPK_PSK, FALSE);
+ const secret_t *s = get_secret(c, SECRET_PSK);
DBG(DBG_PRIVATE,
if (s == NULL)
for (s = secrets; s != NULL; s = s->next)
{
- if (s->kind == PPK_PUBKEY &&
+ if (s->kind == SECRET_PUBKEY &&
s->u.private_key->belongs_to(s->u.private_key, pub_key))
{
has_key = TRUE;
for (s = secrets; s != NULL; s = s->next)
{
- if (s->kind == PPK_PUBKEY &&
+ if (s->kind == SECRET_PUBKEY &&
s->u.private_key->belongs_to(s->u.private_key, public_key))
{
private_key = s->u.private_key;
*/
private_key_t* get_private_key(const connection_t *c)
{
- const secret_t *s = get_secret(c, PPK_PUBKEY, TRUE);
+ const secret_t *s, *best = NULL;
+
+ /* is a certificate assigned to this connection? */
+ if (c->spd.this.cert)
+ {
+ certificate_t *certificate;
+ public_key_t *pub_key;
- return s == NULL? NULL : s->u.private_key;
+ certificate = c->spd.this.cert->cert;
+ pub_key = certificate->get_public_key(certificate);
+
+ for (s = secrets; s != NULL; s = s->next)
+ {
+ if (s->kind == SECRET_PUBKEY &&
+ s->u.private_key->belongs_to(s->u.private_key, pub_key))
+ {
+ best = s;
+ break; /* found the private key - no sense in searching further */
+ }
+ }
+ pub_key->destroy(pub_key);
+ }
+ else
+ {
+ best = get_secret(c, SECRET_PUBKEY);
+ }
+ return best ? best->u.private_key : NULL;
}
/* digest a secrets file
return *key ? NULL : "Private key file -- could not be loaded";
}
-/**
- * Process xauth secret read from ipsec.secrets
- */
-static err_t process_xauth(secret_t *s)
-{
- chunk_t user_name;
-
- s->kind = PPK_XAUTH;
-
- if (!shift())
- return "missing xauth user name";
- if (*tok == '"' || *tok == '\'') /* quoted user name */
- {
- user_name.ptr = tok + 1;
- user_name.len = flp->cur - tok - 2;
- }
- else
- {
- user_name.ptr = tok;
- user_name.len = flp->cur - tok;
- }
- plog(" loaded xauth credentials of user '%.*s'"
- , user_name.len
- , user_name.ptr);
- s->u.xauth_secret.user_name = chunk_clone(user_name);
-
- if (!shift())
- return "missing xauth user password";
- return process_psk_secret(&s->u.xauth_secret.user_password);
-}
-
-/**
- * Get XAUTH secret from chained secrets lists
- * only one entry is currently supported
- */
-static bool xauth_get_secret(xauth_t *xauth_secret)
-{
- secret_t *s;
- bool found = FALSE;
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_XAUTH)
- {
- if (found)
- {
- plog("found multiple xauth secrets - first selected");
- }
- else
- {
- found = TRUE;
- *xauth_secret = s->u.xauth_secret;
- }
- }
- }
- return found;
-}
-
-/**
- * find a matching secret
- */
-static bool xauth_verify_secret(const xauth_peer_t *peer,
- const xauth_t *xauth_secret)
-{
- bool found = FALSE;
- secret_t *s;
-
- for (s = secrets; s != NULL; s = s->next)
- {
- if (s->kind == PPK_XAUTH)
- {
- if (!chunk_equals(xauth_secret->user_name, s->u.xauth_secret.user_name))
- {
- continue;
- }
- found = TRUE;
- if (chunk_equals(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
*/
smartcard_t *sc;
const char *pin_status = "no pin";
- s->kind = PPK_PIN;
+ s->kind = SECRET_PIN;
/* looking for the smartcard keyword */
if (!shift() || strncmp(tok, SCX_TOKEN, strlen(SCX_TOKEN)) != 0)
return NULL;
}
-static void log_psk(secret_t *s)
+static void log_psk(char *label, secret_t *s)
{
int n = 0;
char buf[BUF_LEN];
- id_list_t *id_list = s->ids;
+ enumerator_t *enumerator;
+ identification_t *id;
- if (id_list == NULL)
+ if (s->ids->get_count(s->ids) == 0)
{
n = snprintf(buf, BUF_LEN, "%%any");
}
else
{
- do
+ enumerator = s->ids->create_enumerator(s->ids);
+ while(enumerator->enumerate(enumerator, &id))
{
- n += snprintf(buf + n, BUF_LEN - n, "%Y ", id_list->id);
+ n += snprintf(buf + n, BUF_LEN - n, "%Y ", id);
if (n >= BUF_LEN)
{
n = BUF_LEN - 1;
break;
}
- id_list = id_list->next;
}
- while (id_list);
+ enumerator->destroy(enumerator);
}
- plog(" loaded shared key for %.*s", n, buf);
+ plog(" loaded %s for %.*s", label, n, buf);
}
static void process_secret(secret_t *s, int whackfd)
{
err_t ugh = NULL;
- s->kind = PPK_PSK; /* default */
+ s->kind = SECRET_PSK; /* default */
if (*tok == '"' || *tok == '\'')
{
+ log_psk("PSK", s);
+
/* old PSK format: just a string */
- log_psk(s);
ugh = process_psk_secret(&s->u.preshared_secret);
}
else if (tokeqword("psk"))
{
+ log_psk("PSK", s);
+
/* preshared key: quoted string or ttodata format */
- log_psk(s);
ugh = !shift()? "unexpected end of record in PSK"
: process_psk_secret(&s->u.preshared_secret);
}
+ else if (tokeqword("xauth"))
+ {
+ s->kind = SECRET_XAUTH;
+ log_psk("XAUTH", s);
+
+ /* xauth secret: quoted string or ttodata format */
+ ugh = !shift()? "unexpected end of record in XAUTH"
+ : process_psk_secret(&s->u.preshared_secret);
+ }
else if (tokeqword("rsa"))
{
/* RSA key: the fun begins.
* A braced list of keyword and value pairs.
*/
- s->kind = PPK_PUBKEY;
+ s->kind = SECRET_PUBKEY;
if (!shift())
{
ugh = "bad RSA key syntax";
}
else if (tokeqword("ecdsa"))
{
- s->kind = PPK_PUBKEY;
+ s->kind = SECRET_PUBKEY;
if (!shift())
{
ugh = "bad ECDSA key syntax";
ugh = process_keyfile(&s->u.private_key, KEY_ECDSA, whackfd);
}
}
- else if (tokeqword("xauth"))
- {
- ugh = process_xauth(s);
- }
else if (tokeqword("pin"))
{
ugh = process_pin(s, whackfd);
secret_t *s = malloc_thing(secret_t);
zero(s);
- s->ids = NULL;
- s->kind = PPK_PSK; /* default */
+ s->ids = linked_list_create();
+ s->kind = SECRET_PSK; /* default */
s->u.preshared_secret = chunk_empty;
s->next = NULL;
}
else
{
- /* an id
- * See RFC2407 IPsec Domain of Interpretation 4.6.2
- */
- id_list_t *i = malloc_thing(id_list_t);
+ identification_t *id;
- i->id = identification_create_from_string(tok);
- i->next = s->ids;
- s->ids = i;
+ id = identification_create_from_string(tok);
+ s->ids->insert_last(s->ids, id);
if (!shift())
{
for (s = secrets; s != NULL; s = ns)
{
- id_list_t *i, *ni;
-
ns = s->next;
- for (i = s->ids; i != NULL; i = ni)
- {
- ni = i->next;
- i->id->destroy(i->id);
- free(i);
- }
+ s->ids->destroy_offset(s->ids, offsetof(identification_t, destroy));
+
switch (s->kind)
{
- case PPK_PSK:
- free(s->u.preshared_secret.ptr);
- break;
- case PPK_PUBKEY:
- DESTROY_IF(s->u.private_key);
- break;
- case PPK_XAUTH:
- free(s->u.xauth_secret.user_name.ptr);
- free(s->u.xauth_secret.user_password.ptr);
- break;
- case PPK_PIN:
- scx_release(s->u.smartcard);
- break;
- default:
- bad_case(s->kind);
+ case SECRET_PSK:
+ case SECRET_XAUTH:
+ free(s->u.preshared_secret.ptr);
+ break;
+ case SECRET_PUBKEY:
+ DESTROY_IF(s->u.private_key);
+ break;
+ case SECRET_PIN:
+ scx_release(s->u.smartcard);
+ break;
+ default:
+ bad_case(s->kind);
}
free(s);
}
#include <credentials/keys/public_key.h>
#include "certs.h"
+#include "connections.h"
#ifndef SHARED_SECRETS_FILE
# define SHARED_SECRETS_FILE IPSEC_CONFDIR "/ipsec.secrets"
extern void load_preshared_secrets(int whackfd);
extern void free_preshared_secrets(void);
-enum PrivateKeyKind {
- PPK_PSK,
- PPK_PUBKEY,
- PPK_XAUTH,
- PPK_PIN
-};
-
extern void xauth_defaults(void);
-/* forward declaration */
-struct connection;
-
-extern const chunk_t *get_preshared_secret(const struct connection *c);
-extern private_key_t *get_private_key(const struct connection *c);
+extern bool get_xauth_secret(identification_t *user, identification_t *server,
+ chunk_t *secret);
+extern const chunk_t *get_preshared_secret(const connection_t *c);
+extern private_key_t *get_private_key(const connection_t *c);
extern private_key_t *get_x509_private_key(const cert_t *cert);
/* public key machinery */
#include "crypto.h"
#include "modecfg.h"
#include "whack.h"
-#include "xauth.h"
+#include "pluto.h"
#define MAX_XAUTH_TRIES 3
stf_status xauth_inI0(struct msg_digest *md)
{
struct state *const st = md->st;
+ connection_t *c = st->st_connection;
u_int16_t isama_id;
stf_status stat, stat_build;
modecfg_attribute_t *ca;
- bool xauth_user_name = FALSE;
- bool xauth_user_password = FALSE;
+ bool xauth_user_name_present = FALSE;
+ bool xauth_user_password_present = FALSE;
bool xauth_type_present = FALSE;
- xauth_t xauth_secret;
+ chunk_t xauth_user_name, xauth_user_password;
+ identification_t *user_id;
linked_list_t *ca_list = linked_list_create();
plog("parsing XAUTH request");
}
break;
case XAUTH_USER_NAME:
- xauth_user_name = TRUE;
+ xauth_user_name_present = TRUE;
break;
case XAUTH_USER_PASSWORD:
- xauth_user_password = TRUE;
+ xauth_user_password_present = TRUE;
break;
case XAUTH_MESSAGE:
if (ca->value.len)
modecfg_attribute_destroy(ca);
}
- if (!xauth_user_name)
+ if (!xauth_user_name_present)
{
plog("user name attribute is missing in XAUTH request");
stat = STF_FAIL;
}
- if (!xauth_user_password)
+ if (!xauth_user_password_present)
{
plog("user password attribute is missing in XAUTH request");
stat = STF_FAIL;
if (stat == STF_OK)
{
/* get user credentials using a plugin function */
- if (!xauth_module.get_secret(&xauth_secret))
+ if (!pluto->xauth->get_secret(pluto->xauth, c, &xauth_user_password))
{
plog("xauth user credentials not found");
stat = STF_FAIL;
}
if (stat == STF_OK)
{
+ /* insert xauth type if present */
if (xauth_type_present)
{
ca = modecfg_attribute_create_tv(XAUTH_TYPE, XAUTH_TYPE_GENERIC);
ca_list->insert_last(ca_list, ca);
}
+
+ /* insert xauth user name */
+ user_id = (c->xauth_identity) ? c->xauth_identity : c->spd.this.id;
+ xauth_user_name = user_id->get_encoding(user_id);
DBG(DBG_CONTROL,
- DBG_log("my xauth user name is '%.*s'", xauth_secret.user_name.len,
- xauth_secret.user_name.ptr)
+ DBG_log("my xauth user name is '%.*s'", xauth_user_name.len,
+ xauth_user_name.ptr)
)
- ca = modecfg_attribute_create(XAUTH_USER_NAME, xauth_secret.user_name);
+ ca = modecfg_attribute_create(XAUTH_USER_NAME, xauth_user_name);
ca_list->insert_last(ca_list, ca);
+
+ /* insert xauth user password */
DBG(DBG_PRIVATE,
- DBG_log("my xauth user password is '%.*s'", xauth_secret.user_password.len,
- xauth_secret.user_password.ptr)
+ DBG_log("my xauth user password is '%.*s'", xauth_user_password.len,
+ xauth_user_password.ptr)
)
- ca = modecfg_attribute_create(XAUTH_USER_PASSWORD, xauth_secret.user_password);
+ ca = modecfg_attribute_create(XAUTH_USER_PASSWORD, xauth_user_password);
ca_list->insert_last(ca_list, ca);
+ chunk_clear(&xauth_user_password);
}
else
{
stf_status xauth_inR1(struct msg_digest *md)
{
struct state *const st = md->st;
+ connection_t *c = st->st_connection;
u_int16_t isama_id;
stf_status stat, stat_build;
- xauth_t xauth_secret;
+ chunk_t xauth_user_name, xauth_user_password;
int xauth_status = XAUTH_STATUS_OK;
modecfg_attribute_t *ca;
linked_list_t *ca_list = linked_list_create();
}
/* initialize xauth_secret */
- xauth_secret.user_name = chunk_empty;
- xauth_secret.user_password = chunk_empty;
+ xauth_user_name = chunk_empty;
+ xauth_user_password = chunk_empty;
while (ca_list->remove_last(ca_list, (void **)&ca) == SUCCESS)
{
xauth_status = ca->value.len;
break;
case XAUTH_USER_NAME:
- xauth_secret.user_name = chunk_clone(ca->value);
+ xauth_user_name = chunk_clone(ca->value);
break;
case XAUTH_USER_PASSWORD:
- xauth_secret.user_password = chunk_clone(ca->value);
+ xauth_user_password = chunk_clone(ca->value);
break;
default:
break;
plog("received FAIL status in XAUTH reply");
/* client is not able to do XAUTH, delete ISAKMP SA */
+ free(xauth_user_name.ptr);
+ free(xauth_user_password.ptr);
delete_state(st);
ca_list->destroy(ca_list);
return STF_IGNORE;
}
/* check XAUTH reply */
- if (xauth_secret.user_name.ptr == NULL)
+ if (xauth_user_name.ptr == NULL)
{
plog("user name attribute is missing in XAUTH reply");
st->st_xauth.status = FALSE;
}
- else if (xauth_secret.user_password.ptr == NULL)
+ else if (xauth_user_password.ptr == NULL)
{
plog("user password attribute is missing in XAUTH reply");
st->st_xauth.status = FALSE;
}
else
{
- xauth_peer_t peer;
-
- peer.conn_name = st->st_connection->name;
- addrtot(&md->sender, 0, peer.ip_address, sizeof(peer.ip_address));
- snprintf(peer.id, sizeof(peer.id), "%Y", md->st->st_connection->spd.that.id);
-
DBG(DBG_CONTROL,
- DBG_log("peer xauth user name is '%.*s'", xauth_secret.user_name.len,
- xauth_secret.user_name.ptr)
+ DBG_log("peer xauth user name is '%.*s'", xauth_user_name.len,
+ xauth_user_name.ptr)
)
+ DESTROY_IF(c->xauth_identity);
+ c->xauth_identity = identification_create_from_data(xauth_user_name);
+
DBG(DBG_PRIVATE,
- DBG_log("peer xauth user password is '%.*s'", xauth_secret.user_password.len,
- xauth_secret.user_password.ptr)
+ DBG_log("peer xauth user password is '%.*s'", xauth_user_password.len,
+ xauth_user_password.ptr)
)
/* verify the user credentials using a plugin function */
- st->st_xauth.status = xauth_module.verify_secret(&peer, &xauth_secret);
+ st->st_xauth.status = pluto->xauth->verify_secret(pluto->xauth, c,
+ xauth_user_password);
plog("extended authentication %s", st->st_xauth.status? "was successful":"failed");
}
- chunk_clear(&xauth_secret.user_name);
- chunk_clear(&xauth_secret.user_password);
+ chunk_clear(&xauth_user_name);
+ chunk_clear(&xauth_user_password);
plog("sending XAUTH status");
xauth_status = (st->st_xauth.status) ? XAUTH_STATUS_OK : XAUTH_STATUS_FAIL;
--- /dev/null
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
+ -I$(top_srcdir)/src/libfreeswan -I$(top_srcdir)/src/whack \
+ -I$(top_srcdir)/src/pluto
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-xauth.la
+
+libstrongswan_xauth_la_SOURCES = \
+ xauth_plugin.h xauth_plugin.c \
+ xauth_default_provider.c xauth_default_provider.h \
+ xauth_default_verifier.c xauth_default_verifier.h
+
+libstrongswan_xauth_la_LDFLAGS = -module -avoid-version
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+#include <keys.h>
+
+#include "xauth_default_provider.h"
+
+typedef struct private_xauth_default_provider_t private_xauth_default_provider_t;
+
+/**
+ * private data of xauth_default_provider
+ */
+struct private_xauth_default_provider_t {
+
+ /**
+ * public functions
+ */
+ xauth_provider_t public;
+};
+
+METHOD(xauth_provider_t, get_secret, bool,
+ private_xauth_default_provider_t *this, connection_t *c, chunk_t *secret)
+{
+ identification_t *user, *server;
+
+ server = c->spd.that.id;
+ user = (c->xauth_identity) ? c->xauth_identity : c->spd.this.id;
+
+ return get_xauth_secret(user, server, secret);
+}
+
+METHOD(xauth_provider_t, destroy, void,
+ private_xauth_default_provider_t *this)
+{
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+xauth_provider_t *xauth_default_provider_create()
+{
+ private_xauth_default_provider_t *this;
+
+ INIT(this,
+ .public = {
+ .get_secret = _get_secret,
+ .destroy = _destroy,
+ }
+ );
+
+ return &this->public;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup xauth_default_provider xauth_default_provider
+ * @{ @ingroup xauth
+ */
+
+#ifndef XAUTH_DEFAULT_PROVIDER_H_
+#define XAUTH_DEFAULT_PROVIDER_H_
+
+#include <xauth/xauth_provider.h>
+
+
+/**
+ * Create an xauth_default_provider instance.
+ */
+xauth_provider_t *xauth_default_provider_create();
+
+#endif /** XAUTH_DEFAULT_PROVIDER_H_ @}*/
+
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+#include <keys.h>
+
+#include "xauth_default_verifier.h"
+
+typedef struct private_xauth_default_verifier_t private_xauth_default_verifier_t;
+
+/**
+ * private data of xauth_default_verifier
+ */
+struct private_xauth_default_verifier_t {
+
+ /**
+ * public functions
+ */
+ xauth_verifier_t public;
+};
+
+METHOD(xauth_verifier_t, verify_secret, bool,
+ private_xauth_default_verifier_t *this, connection_t *c, chunk_t secret)
+{
+ identification_t *user, *server;
+ chunk_t xauth_secret;
+ bool success = FALSE;
+
+ server = c->spd.this.id;
+ user = (c->xauth_identity) ? c->xauth_identity : c->spd.that.id;
+
+ if (get_xauth_secret(user, server, &xauth_secret))
+ {
+ success = chunk_equals(secret, xauth_secret);
+ chunk_clear(&xauth_secret);
+ }
+ return success;
+}
+
+METHOD(xauth_verifier_t, destroy, void,
+ private_xauth_default_verifier_t *this)
+{
+ free(this);
+}
+
+
+/*
+ * Described in header.
+ */
+xauth_verifier_t *xauth_default_verifier_create()
+{
+ private_xauth_default_verifier_t *this;
+
+ INIT(this,
+ .public = {
+ .verify_secret = _verify_secret,
+ .destroy = _destroy,
+ }
+ );
+
+ return &this->public;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup xauth_default_verifier xauth_default_verifier
+ * @{ @ingroup xauth
+ */
+
+#ifndef XAUTH_DEFAULT_VERIFIER_H_
+#define XAUTH_DEFAULT_VERIFIER_H_
+
+#include <xauth/xauth_verifier.h>
+
+
+/**
+ * Create an xauth_default_verifier instance.
+ */
+xauth_verifier_t *xauth_default_verifier_create();
+
+#endif /** XAUTH_DEFAULT_VERIFIER_H_ @}*/
+
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+#include <pluto.h>
+
+#include "xauth_plugin.h"
+#include "xauth_default_provider.h"
+#include "xauth_default_verifier.h"
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(xauth_plugin_t *this)
+{
+ free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *xauth_plugin_create()
+{
+ xauth_plugin_t *this = malloc_thing(xauth_plugin_t);
+
+ this->plugin.destroy = (void(*)(plugin_t*))destroy;
+
+ pluto->xauth->add_provider(pluto->xauth, xauth_default_provider_create());
+ pluto->xauth->add_verifier(pluto->xauth, xauth_default_verifier_create());
+
+ return &this->plugin;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup xauth xauth
+ * @ingroup pplugins
+ *
+ * @defgroup xauth_plugin xauth_plugin
+ * @{ @ingroup xauth
+ */
+
+#ifndef XAUTH_PLUGIN_H_
+#define XAUTH_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct xauth_plugin_t xauth_plugin_t;
+
+/**
+ * XAUTH plugin
+ */
+struct xauth_plugin_t {
+
+ /**
+ * implements plugin interface
+ */
+ plugin_t plugin;
+};
+
+#endif /** XAUTH_PLUGIN_H_ @}*/
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+#include "pluto.h"
+
+#include <debug.h>
+
+typedef struct private_pluto_t private_pluto_t;
+
+/**
+ * Private additions to hydra_t.
+ */
+struct private_pluto_t {
+
+ /**
+ * Public members of pluto_t.
+ */
+ pluto_t public;
+};
+
+/**
+ * Single instance of hydra_t.
+ */
+pluto_t *pluto;
+
+/**
+ * Described in header.
+ */
+void pluto_deinit()
+{
+ private_pluto_t *this = (private_pluto_t*)pluto;
+ this->public.xauth->destroy(this->public.xauth);
+ free(this);
+ pluto = NULL;
+}
+
+/**
+ * Described in header.
+ */
+bool pluto_init(char *file)
+{
+ private_pluto_t *this;
+
+ INIT(this,
+ .public = {
+ .xauth = xauth_manager_create(),
+ },
+ );
+ pluto = &this->public;
+
+ if (lib->integrity &&
+ !lib->integrity->check_file(lib->integrity, "pluto", file))
+ {
+ DBG1(DBG_LIB, "integrity check of pluto failed");
+ return FALSE;
+ }
+ return TRUE;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup pluto pluto
+ *
+ * @defgroup xauth xauth
+ * @ingroup pluto
+ *
+ * @defgroup pplugins plugins
+ * @ingroup pluto
+ *
+ * @addtogroup pluto
+ * @{
+ */
+
+#ifndef PLUTO_H_
+#define PLUTO_H_
+
+typedef struct pluto_t pluto_t;
+
+#include <xauth/xauth_manager.h>
+
+#include <library.h>
+
+/**
+ * Pluto daemon support object.
+ */
+struct pluto_t {
+
+ /**
+ * manager for payload attributes
+ */
+ xauth_manager_t *xauth;
+};
+
+/**
+ * The single instance of pluto_t.
+ *
+ * Set between calls to pluto_init() and pluto_deinit() calls.
+ */
+extern pluto_t *pluto;
+
+/**
+ * Initialize pluto.
+ *
+ * @return FALSE if integrity check failed
+ */
+bool pluto_init(char *file);
+
+/**
+ * Deinitialize pluto.
+ */
+void pluto_deinit(void);
+
+#endif /** PLUTO_H_ @}*/
+
#include "ocsp.h"
#include "crl.h"
#include "fetch.h"
-#include "xauth.h"
#include "crypto.h"
#include "nat_traversal.h"
#include "virtual.h"
#include "vendor.h"
#include "builder.h"
#include "whack_attribute.h"
+#include "pluto.h"
static void usage(const char *mess)
{
library_deinit();
exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
}
- if (lib->integrity &&
- !lib->integrity->check_file(lib->integrity, "pluto", argv[0]))
+ if (!libhydra_init("pluto"))
{
- fprintf(stderr, "integrity check of pluto failed\n");
+ libhydra_deinit();
library_deinit();
- exit(SS_RC_DAEMON_INTEGRITY);
+ exit(SS_RC_INITIALIZATION_FAILED);
}
- if (!libhydra_init("pluto"))
+ if (!pluto_init(argv[0]))
{
+ pluto_deinit();
libhydra_deinit();
library_deinit();
- exit(SS_RC_INITIALIZATION_FAILED);
+ exit(SS_RC_DAEMON_INTEGRITY);
}
options = options_create();
init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf);
init_virtual_ip(virtual_private);
scx_init(pkcs11_module_path, pkcs11_init_args);
- xauth_init();
init_states();
init_demux();
init_kernel();
free_ifaces();
ac_finalize(); /* free X.509 attribute certificates */
scx_finalize(); /* finalize and unload PKCS #11 module */
- xauth_finalize(); /* finalize and unload XAUTH module */
stop_adns();
free_md_pool();
free_crypto();
free_builder();
delete_lock();
options->destroy(options);
+ pluto_deinit();
lib->plugins->unload(lib->plugins);
libhydra_deinit();
library_deinit();
+++ /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.
- */
-
-#include <dlfcn.h>
-
-#include <freeswan.h>
-
-#include "constants.h"
-#include "defs.h"
-#include "xauth.h"
-#include "keys.h"
-#include "log.h"
-
-void
-xauth_init(void)
-{
-#ifdef XAUTH_DEFAULT_LIB
- xauth_module.handle = dlopen(XAUTH_DEFAULT_LIB, RTLD_NOW);
-
- if (xauth_module.handle != NULL)
- {
- DBG(DBG_CONTROL,
- DBG_log("xauth module '%s' loading'", XAUTH_DEFAULT_LIB)
- )
- xauth_module.get_secret = (bool (*) (const xauth_t*))
- dlsym(xauth_module.handle, "get_secret");
- DBG(DBG_CONTROL,
- if (xauth_module.get_secret != NULL)
- {
- DBG_log("xauth module: found get_secret() function");
- }
- )
- xauth_module.verify_secret = (bool (*) (const xauth_peer_t*, const xauth_t*))
- dlsym(xauth_module.handle, "verify_secret");
- DBG(DBG_CONTROL,
- if (xauth_module.verify_secret != NULL)
- {
- DBG_log("xauth module: found verify_secret() function");
- }
- )
- }
-#endif
- /* any null function pointers will be filled in by default functions */
- xauth_defaults();
-}
-
-void
-xauth_finalize(void)
-{
-#ifdef XAUTH_DEFAULT_LIB
- if (xauth_module.handle != NULL)
- {
- if (dlclose(xauth_module.handle))
- {
- plog("failed to unload xauth module");
- }
- else
- {
- DBG(DBG_CONTROL,
- DBG_log("xauth module unloaded")
- )
- }
- }
-#endif
-}
+++ /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.
- */
-
-#ifndef _XAUTH_H
-#define _XAUTH_H
-
-#include <freeswan.h>
-#include "defs.h"
-
-/* XAUTH credentials */
-
-struct chunk_t;
-
-typedef struct {
- char *conn_name;
- char id[BUF_LEN];
- char ip_address[ADDRTOT_BUF];
-} xauth_peer_t;
-
-typedef struct {
- chunk_t user_name;
- chunk_t user_password;
-} xauth_t;
-
-typedef struct {
- void *handle;
- bool (*get_secret) (xauth_t *xauth_secret);
- bool (*verify_secret) (const xauth_peer_t *peer, 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 */
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+#include "xauth_manager.h"
+
+typedef struct private_xauth_manager_t private_xauth_manager_t;
+
+/**
+ * private data of xauth_manager
+ */
+struct private_xauth_manager_t {
+
+ /**
+ * public functions
+ */
+ xauth_manager_t public;
+
+ /**
+ * list of registered secret providers
+ */
+ linked_list_t *providers;
+
+ /**
+ * list of registered secret verifiers
+ */
+ linked_list_t *verifiers;
+};
+
+METHOD(xauth_manager_t, get_secret, bool,
+ private_xauth_manager_t *this, connection_t *c, chunk_t *secret)
+{
+ xauth_provider_t *provider;
+ enumerator_t *enumerator;
+ bool success = FALSE;
+
+ *secret = chunk_empty;
+
+ enumerator = this->providers->create_enumerator(this->providers);
+ while (enumerator->enumerate(enumerator, &provider))
+ {
+ if (provider->get_secret(provider, c, secret))
+ {
+ success = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return success;
+}
+
+METHOD(xauth_manager_t, verify_secret, bool,
+ private_xauth_manager_t *this, connection_t *c, chunk_t secret)
+{
+ xauth_verifier_t *verifier;
+ enumerator_t *enumerator;
+ bool success = FALSE;
+
+ enumerator = this->verifiers->create_enumerator(this->verifiers);
+ while (enumerator->enumerate(enumerator, &verifier))
+ {
+ if (verifier->verify_secret(verifier, c, secret))
+ {
+ success = TRUE;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return success;
+}
+
+METHOD(xauth_manager_t, add_provider, void,
+ private_xauth_manager_t *this, xauth_provider_t *provider)
+{
+ this->providers->insert_last(this->providers, provider);
+}
+
+METHOD(xauth_manager_t, add_verifier, void,
+ private_xauth_manager_t *this, xauth_verifier_t *verifier)
+{
+ this->verifiers->insert_last(this->verifiers, verifier);
+}
+
+METHOD(xauth_manager_t, destroy, void,
+ private_xauth_manager_t *this)
+{
+ this->providers->destroy_offset(this->providers,
+ offsetof(xauth_provider_t, destroy));
+ this->verifiers->destroy_offset(this->verifiers,
+ offsetof(xauth_verifier_t, destroy));
+ free(this);
+}
+
+/*
+ * Described in header.
+ */
+xauth_manager_t *xauth_manager_create()
+{
+ private_xauth_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .get_secret = _get_secret,
+ .verify_secret = _verify_secret,
+ .add_provider = _add_provider,
+ .add_verifier = _add_verifier,
+ .destroy = _destroy,
+ }
+ );
+
+ this->providers = linked_list_create();
+ this->verifiers = linked_list_create();
+
+ return &this->public;
+}
+
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup xauth_manager xauth_manager
+ * @{ @ingroup xauth
+ */
+
+#ifndef XAUTH_MANAGER_H_
+#define XAUTH_MANAGER_H_
+
+#include "xauth_provider.h"
+#include "xauth_verifier.h"
+
+typedef struct xauth_manager_t xauth_manager_t;
+
+/**
+ * An xauth_manager registers xauth_providers and xauth_verifiers.
+ */
+struct xauth_manager_t {
+
+ /**
+ * Register an xauth_provider
+ *
+ * @param provider xauth_provider to be registered
+ */
+ void (*add_provider)(xauth_manager_t *this, xauth_provider_t *provider);
+
+ /**
+ * Register an xauth_verifier
+ *
+ * @param verifier xauth_verifier to be registered
+ */
+ void (*add_verifier)(xauth_manager_t *this, xauth_verifier_t *verifier);
+
+ /**
+ * Use registered providers to retrieve an XAUTH user secret
+ * based on connection information.
+ *
+ * @param c connection information
+ * @param secret secret if found, chunk_empty otherwise
+ * @return TRUE if a matching secret was found
+ */
+ bool (*get_secret)(xauth_manager_t *this, connection_t *c, chunk_t *secret);
+
+ /**
+ * Use registered verifiers to verify an XAUTH user secret
+ * based on connection information
+ *
+ * @param c connection information
+ * @param secret secret to be compared
+ * @return TRUE if secret matches
+ */
+ bool (*verify_secret)(xauth_manager_t *this, connection_t *c, chunk_t secret);
+
+ /**
+ * Destroy an xauth_verifier instance.
+ */
+ void (*destroy)(xauth_manager_t *this);
+};
+
+/**
+ * Create an xauth_manager instance.
+ */
+xauth_manager_t *xauth_manager_create();
+
+#endif /** XAUTH_MANAGER_H_ @}*/
+
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup xauth_provider xauth_provider
+ * @{ @ingroup xauth
+ */
+
+#ifndef XAUTH_PROVIDER_H_
+#define XAUTH_PROVIDER_H_
+
+#include <library.h>
+
+#include <connections.h>
+
+typedef struct xauth_provider_t xauth_provider_t;
+
+/**
+ * An xauth provider retrieves xauth user secrets on the client side.
+ */
+struct xauth_provider_t {
+
+ /**
+ * Retrieve an XAUTH user secret based on connection information.
+ *
+ * @param c connection information
+ * @param secret secret if found, chunk_empty otherwise
+ * @return TRUE if a matching secret was found
+ */
+ bool (*get_secret)(xauth_provider_t *this, connection_t *c, chunk_t *secret);
+
+ /**
+ * Destroy an xauth_provider instance.
+ */
+ void (*destroy)(xauth_provider_t *this);
+};
+
+/**
+ * Create an xauth_provider instance.
+ */
+xauth_provider_t *xauth_provider_create();
+
+#endif /** XAUTH_PROVIDER_H_ @}*/
+
--- /dev/null
+/*
+ * Copyright (C) 2010 Andreas Steffen
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup xauth_verifier xauth_verifier
+ * @{ @ingroup xauth
+ */
+
+#ifndef XAUTH_VERIFIER_H_
+#define XAUTH_VERIFIER_H_
+
+#include <library.h>
+
+#include <connections.h>
+
+typedef struct xauth_verifier_t xauth_verifier_t;
+
+/**
+ * An xauth verifier verifies xauth user secrets on the server side.
+ */
+struct xauth_verifier_t {
+
+ /**
+ * Verify an XAUTH user secret base on connection information
+ *
+ * @param c connection information
+ * @param secret secret to be compared
+ * @return TRUE if secret matches
+ */
+ bool (*verify_secret)(xauth_verifier_t *this, connection_t *c, chunk_t secret);
+
+ /**
+ * Destroy an xauth_verifier instance.
+ */
+ void (*destroy)(xauth_verifier_t *this);
+};
+
+/**
+ * Create an xauth_verifier instance.
+ */
+xauth_verifier_t *xauth_verifier_create();
+
+#endif /** XAUTH_VERIFIER_H_ @}*/
+