implemented xauth as a pluto plugin

This commit is contained in:
Andreas Steffen 2010-05-18 13:51:15 +02:00
parent ea409980b9
commit 26ec52a405
22 changed files with 1071 additions and 476 deletions

View File

@ -127,6 +127,7 @@ ARG_ENABL_SET([manager], [enable web management console (proof of concept
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).])
@ -746,6 +747,9 @@ if test x$gmp = xtrue; then
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
@ -789,7 +793,6 @@ AM_CONDITIONAL(USE_HMAC, test x$hmac = xtrue)
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)
@ -806,9 +809,7 @@ AM_CONDITIONAL(USE_ANDROID, test x$android = 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)
@ -832,6 +833,16 @@ AM_CONDITIONAL(USE_SOCKET_RAW, test x$socket_raw = 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)
@ -917,6 +928,7 @@ AC_OUTPUT(
src/libfreeswan/Makefile
src/libsimaka/Makefile
src/pluto/Makefile
src/pluto/plugins/xauth/Makefile
src/whack/Makefile
src/charon/Makefile
src/libcharon/Makefile

View File

@ -19,6 +19,7 @@ AM_CFLAGS = -rdynamic
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

View File

@ -37,6 +37,7 @@ nat_traversal.c nat_traversal.h \
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 \
@ -47,7 +48,8 @@ timer.c timer.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
@ -67,7 +69,7 @@ INCLUDES = \
-I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/whack
AM_CFLAGS = \
AM_CFLAGS = -rdynamic \
-DIPSEC_DIR=\"${ipsecdir}\" \
-DIPSEC_CONFDIR=\"${sysconfdir}\" \
-DIPSEC_PIDDIR=\"${piddir}\" \
@ -89,6 +91,9 @@ $(LIBFREESWANDIR)/libfreeswan.a \
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
@ -121,3 +126,14 @@ endif
if USE_THREADS
AM_CFLAGS += -DTHREADS
endif
# build optional plugins
########################
SUBDIRS = .
if USE_XAUTH
SUBDIRS += plugins/xauth
endif

View File

@ -53,25 +53,26 @@
#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;
@ -92,12 +93,11 @@ static void free_public_key(pubkey_t *pk)
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,
@ -106,29 +106,135 @@ static const secret_t* get_secret(const connection_t *c,
};
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))
continue;
}
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
{
/* check if both ends match ids */
enumerator_t *enumerator;
identification_t *id;
enumerator = s->ids->create_enumerator(s->ids);
while (enumerator->enumerate(enumerator, &id))
{
best = s;
break; /* we have found the private key - no sense in searching further */
if (my_id->equals(my_id, id))
{
match |= match_me;
}
if (his_id->equals(his_id, id))
{
match |= match_him;
}
}
enumerator->destroy(enumerator);
/* 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;
}
}
pub_key->destroy(pub_key);
return best;
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 (kind != SECRET_PUBKEY)
{
break;
}
/* FALLTHROUGH */
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? */
bool same = FALSE;
switch (kind)
{
case SECRET_PSK:
case SECRET_XAUTH:
same = chunk_equals(s->u.preshared_secret,
best->u.preshared_secret);
break;
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");
best = s; /* list is backwards: take latest in list */
}
}
else if (match > best_match)
{
/* this is the best match so far */
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;
@ -137,7 +243,7 @@ static const secret_t* get_secret(const connection_t *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)) &&
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))))
@ -150,96 +256,8 @@ static const secret_t* get_secret(const connection_t *c,
his_id = c->spd.that.id->clone(c->spd.that.id);
}
for (s = secrets; s != NULL; s = s->next)
{
if (s->kind == kind)
{
unsigned int match = 0;
best = match_secret(my_id, his_id, kind);
if (s->ids == NULL)
{
/* a default (signified by lack of ids):
* accept if no more specific match found
*/
match = match_default;
}
else
{
/* 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, i->id))
{
match |= match_me;
}
if (his_id->equals(his_id, i->id))
{
match |= match_him;
}
}
/* 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)
{
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)
{
break;
}
/* FALLTHROUGH */
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?
*/
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);
break;
case PPK_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");
best = s; /* list is backwards: take latest in list */
}
}
else if (match > best_match)
{
/* this is the best match so far */
best_match = match;
best = s;
}
}
}
}
his_id->destroy(his_id);
return best;
}
@ -250,7 +268,7 @@ static const secret_t* get_secret(const connection_t *c,
*/
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)
@ -272,7 +290,7 @@ bool has_private_key(cert_t *cert)
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;
@ -295,7 +313,7 @@ private_key_t* get_x509_private_key(const cert_t *cert)
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;
@ -311,9 +329,33 @@ private_key_t* get_x509_private_key(const cert_t *cert)
*/
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;
return s == NULL? NULL : s->u.private_key;
/* is a certificate assigned to this connection? */
if (c->spd.this.cert)
{
certificate_t *certificate;
public_key_t *pub_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
@ -555,120 +597,6 @@ static err_t process_keyfile(private_key_t **key, key_type_t type, int whackfd)
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
*/
@ -677,7 +605,7 @@ static err_t process_pin(secret_t *s, int whackfd)
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)
@ -748,57 +676,69 @@ static err_t process_pin(secret_t *s, int whackfd)
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";
@ -814,7 +754,7 @@ static void process_secret(secret_t *s, int whackfd)
}
else if (tokeqword("ecdsa"))
{
s->kind = PPK_PUBKEY;
s->kind = SECRET_PUBKEY;
if (!shift())
{
ugh = "bad ECDSA key syntax";
@ -824,10 +764,6 @@ static void process_secret(secret_t *s, int whackfd)
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);
@ -919,8 +855,8 @@ static void process_secret_records(int 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;
@ -941,14 +877,10 @@ static void process_secret_records(int whackfd)
}
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())
{
@ -1035,32 +967,23 @@ void free_preshared_secrets(void)
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);
}

View File

@ -21,6 +21,7 @@
#include <credentials/keys/public_key.h>
#include "certs.h"
#include "connections.h"
#ifndef SHARED_SECRETS_FILE
# define SHARED_SECRETS_FILE IPSEC_CONFDIR "/ipsec.secrets"
@ -31,20 +32,12 @@ const char *shared_secrets_file;
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 */

View File

@ -40,7 +40,7 @@
#include "crypto.h"
#include "modecfg.h"
#include "whack.h"
#include "xauth.h"
#include "pluto.h"
#define MAX_XAUTH_TRIES 3
@ -929,13 +929,15 @@ stf_status xauth_send_request(struct state *st)
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");
@ -963,10 +965,10 @@ stf_status xauth_inI0(struct msg_digest *md)
}
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)
@ -982,12 +984,12 @@ stf_status xauth_inI0(struct msg_digest *md)
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;
@ -997,7 +999,7 @@ stf_status xauth_inI0(struct msg_digest *md)
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;
@ -1005,23 +1007,31 @@ stf_status xauth_inI0(struct msg_digest *md)
}
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
{
@ -1065,9 +1075,10 @@ stf_status xauth_inI0(struct msg_digest *md)
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();
@ -1081,8 +1092,8 @@ stf_status xauth_inR1(struct msg_digest *md)
}
/* 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)
{
@ -1092,10 +1103,10 @@ stf_status xauth_inR1(struct msg_digest *md)
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;
@ -1108,44 +1119,44 @@ stf_status xauth_inR1(struct msg_digest *md)
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;

View File

@ -0,0 +1,15 @@
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

View File

@ -0,0 +1,66 @@
/*
* 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;
}

View File

@ -0,0 +1,33 @@
/*
* 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_ @}*/

View File

@ -0,0 +1,74 @@
/*
* 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;
}

View File

@ -0,0 +1,33 @@
/*
* 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_ @}*/

View File

@ -0,0 +1,43 @@
/*
* 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;
}

View File

@ -0,0 +1,42 @@
/*
* 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_ @}*/

71
src/pluto/pluto.c Normal file
View File

@ -0,0 +1,71 @@
/*
* 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;
}

69
src/pluto/pluto.h Normal file
View File

@ -0,0 +1,69 @@
/*
* 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_ @}*/

View File

@ -68,7 +68,6 @@
#include "ocsp.h"
#include "crl.h"
#include "fetch.h"
#include "xauth.h"
#include "crypto.h"
#include "nat_traversal.h"
#include "virtual.h"
@ -76,6 +75,7 @@
#include "vendor.h"
#include "builder.h"
#include "whack_attribute.h"
#include "pluto.h"
static void usage(const char *mess)
{
@ -268,19 +268,19 @@ int main(int argc, char **argv)
library_deinit();
exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
}
if (lib->integrity &&
!lib->integrity->check_file(lib->integrity, "pluto", argv[0]))
{
fprintf(stderr, "integrity check of pluto failed\n");
library_deinit();
exit(SS_RC_DAEMON_INTEGRITY);
}
if (!libhydra_init("pluto"))
{
libhydra_deinit();
library_deinit();
exit(SS_RC_INITIALIZATION_FAILED);
}
if (!pluto_init(argv[0]))
{
pluto_deinit();
libhydra_deinit();
library_deinit();
exit(SS_RC_DAEMON_INTEGRITY);
}
options = options_create();
/* handle arguments */
@ -677,7 +677,6 @@ int main(int argc, char **argv)
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();
@ -771,7 +770,6 @@ void exit_pluto(int status)
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();
@ -781,6 +779,7 @@ void exit_pluto(int status)
free_builder();
delete_lock();
options->destroy(options);
pluto_deinit();
lib->plugins->unload(lib->plugins);
libhydra_deinit();
library_deinit();

View File

@ -1,77 +0,0 @@
/* 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
}

View File

@ -1,48 +0,0 @@
/* 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 */

View File

@ -0,0 +1,127 @@
/*
* 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;
}

View File

@ -0,0 +1,80 @@
/*
* 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_ @}*/

View File

@ -0,0 +1,56 @@
/*
* 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_ @}*/

View File

@ -0,0 +1,56 @@
/*
* 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_ @}*/