From 3d44d735c649559b9768ae635a6bee7fec932902 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 12 Dec 2011 18:26:26 +0100 Subject: Added generic XAuth backend, using secrets provided by credential sets. --- .../plugins/xauth_generic/xauth_generic.c | 210 +++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 src/libcharon/plugins/xauth_generic/xauth_generic.c (limited to 'src/libcharon/plugins/xauth_generic/xauth_generic.c') diff --git a/src/libcharon/plugins/xauth_generic/xauth_generic.c b/src/libcharon/plugins/xauth_generic/xauth_generic.c new file mode 100644 index 000000000..cac740a34 --- /dev/null +++ b/src/libcharon/plugins/xauth_generic/xauth_generic.c @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2011 Tobias Brunner + * 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 . + * + * 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_generic.h" + +#include +#include + +typedef struct private_xauth_generic_t private_xauth_generic_t; + +/** + * Private data of an xauth_generic_t object. + */ +struct private_xauth_generic_t { + + /** + * Public interface. + */ + xauth_generic_t public; + + /** + * ID of the server + */ + identification_t *server; + + /** + * ID of the peer + */ + identification_t *peer; + +}; + +METHOD(xauth_method_t, initiate_peer, status_t, + private_xauth_generic_t *this, cp_payload_t **out) +{ + /* peer never initiates */ + return FAILED; +} + +METHOD(xauth_method_t, process_peer, status_t, + private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out) +{ + shared_key_t *shared; + cp_payload_t *cp; + chunk_t user, pass; + + shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, this->peer, + this->server); + if (!shared) + { + DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'", this->peer, + this->server); + return FAILED; + } + + user = this->peer->get_encoding(this->peer); + pass = shared->get_key(shared); + + cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REPLY); + cp->add_attribute(cp, configuration_attribute_create_chunk( + CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, user)); + cp->add_attribute(cp, configuration_attribute_create_chunk( + CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, pass)); + *out = cp; + return NEED_MORE; +} + +METHOD(xauth_method_t, initiate_server, status_t, + private_xauth_generic_t *this, cp_payload_t **out) +{ + cp_payload_t *cp; + + cp = cp_payload_create_type(CONFIGURATION_V1, CFG_REQUEST); + cp->add_attribute(cp, configuration_attribute_create_chunk( + CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, chunk_empty)); + cp->add_attribute(cp, configuration_attribute_create_chunk( + CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, chunk_empty)); + *out = cp; + return NEED_MORE; +} + +METHOD(xauth_method_t, process_server, status_t, + private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out) +{ + configuration_attribute_t *attr; + enumerator_t *enumerator; + shared_key_t *shared; + identification_t *id = NULL, *peer; + chunk_t user = chunk_empty, pass = chunk_empty; + status_t status = SUCCESS; + + enumerator = in->create_attribute_enumerator(in); + while (enumerator->enumerate(enumerator, &attr)) + { + switch (attr->get_type(attr)) + { + case XAUTH_USER_NAME: + user = attr->get_chunk(attr); + break; + case XAUTH_USER_PASSWORD: + pass = attr->get_chunk(attr); + break; + default: + break; + } + } + enumerator->destroy(enumerator); + + if (!user.ptr || !pass.ptr) + { + DBG1(DBG_IKE, "peer did not respond to our XAuth request"); + return FAILED; + } + if (user.len) + { + id = identification_create_from_data(user); + if (!id) + { + DBG1(DBG_IKE, "failed to parse provided XAuth username"); + return FAILED; + } + } + + peer = id ?: this->peer; + shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, this->server, + peer); + if (!shared) + { + DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'", this->server, + peer); + status = FAILED; + } + else if (!chunk_equals(shared->get_key(shared), pass)) + { + DBG1(DBG_IKE, "failed to authenticate '%Y' with XAuth", peer); + status = FAILED; + } + else + { + DBG2(DBG_IKE, "authentication of '%Y' with XAuth successful", peer); + } + DESTROY_IF(id); + return status; +} + +METHOD(xauth_method_t, destroy, void, + private_xauth_generic_t *this) +{ + this->server->destroy(this->server); + this->peer->destroy(this->peer); + free(this); +} + +/* + * Described in header. + */ +xauth_generic_t *xauth_generic_create_peer(identification_t *server, + identification_t *peer) +{ + private_xauth_generic_t *this; + + INIT(this, + .public = { + .xauth_method = { + .initiate = _initiate_peer, + .process = _process_peer, + .destroy = _destroy, + }, + }, + .server = server->clone(server), + .peer = peer->clone(peer), + ); + + return &this->public; +} + +/* + * Described in header. + */ +xauth_generic_t *xauth_generic_create_server(identification_t *server, + identification_t *peer) +{ + private_xauth_generic_t *this; + + INIT(this, + .public = { + .xauth_method = { + .initiate = _initiate_server, + .process = _process_server, + .destroy = _destroy, + }, + }, + .server = server->clone(server), + .peer = peer->clone(peer), + ); + + return &this->public; +} -- cgit v1.2.3 From e33510f8a32ffe72f6c239919058e6eb120ef070 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Tue, 13 Dec 2011 11:39:54 +0100 Subject: Fixed leak of shared keys in xauth-generic plugin --- src/libcharon/plugins/xauth_generic/xauth_generic.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/libcharon/plugins/xauth_generic/xauth_generic.c') diff --git a/src/libcharon/plugins/xauth_generic/xauth_generic.c b/src/libcharon/plugins/xauth_generic/xauth_generic.c index cac740a34..981ab77d0 100644 --- a/src/libcharon/plugins/xauth_generic/xauth_generic.c +++ b/src/libcharon/plugins/xauth_generic/xauth_generic.c @@ -73,6 +73,7 @@ METHOD(xauth_method_t, process_peer, status_t, CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_NAME, user)); cp->add_attribute(cp, configuration_attribute_create_chunk( CONFIGURATION_ATTRIBUTE_V1, XAUTH_USER_PASSWORD, pass)); + shared->destroy(shared); *out = cp; return NEED_MORE; } @@ -151,6 +152,7 @@ METHOD(xauth_method_t, process_server, status_t, { DBG2(DBG_IKE, "authentication of '%Y' with XAuth successful", peer); } + DESTROY_IF(shared); DESTROY_IF(id); return status; } -- cgit v1.2.3 From 7a7efbf9d88346609ee4c246936e4fa2a6c72723 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 15 Dec 2011 13:14:33 +0100 Subject: Added an identity getter to XAuth methods to query the actually used identity --- .../plugins/xauth_generic/xauth_generic.c | 28 ++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'src/libcharon/plugins/xauth_generic/xauth_generic.c') diff --git a/src/libcharon/plugins/xauth_generic/xauth_generic.c b/src/libcharon/plugins/xauth_generic/xauth_generic.c index 981ab77d0..6350a130f 100644 --- a/src/libcharon/plugins/xauth_generic/xauth_generic.c +++ b/src/libcharon/plugins/xauth_generic/xauth_generic.c @@ -98,7 +98,7 @@ METHOD(xauth_method_t, process_server, status_t, configuration_attribute_t *attr; enumerator_t *enumerator; shared_key_t *shared; - identification_t *id = NULL, *peer; + identification_t *id; chunk_t user = chunk_empty, pass = chunk_empty; status_t status = SUCCESS; @@ -132,31 +132,33 @@ METHOD(xauth_method_t, process_server, status_t, DBG1(DBG_IKE, "failed to parse provided XAuth username"); return FAILED; } + this->peer->destroy(this->peer); + this->peer = id; } - peer = id ?: this->peer; - shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, this->server, - peer); + shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, + this->server, this->peer); if (!shared) { - DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'", this->server, - peer); + DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'", + this->server, this->peer); status = FAILED; } else if (!chunk_equals(shared->get_key(shared), pass)) { - DBG1(DBG_IKE, "failed to authenticate '%Y' with XAuth", peer); + DBG1(DBG_IKE, "failed to authenticate '%Y' with XAuth", this->peer); status = FAILED; } - else - { - DBG2(DBG_IKE, "authentication of '%Y' with XAuth successful", peer); - } DESTROY_IF(shared); - DESTROY_IF(id); return status; } +METHOD(xauth_method_t, get_identity, identification_t*, + private_xauth_generic_t *this) +{ + return this->peer; +} + METHOD(xauth_method_t, destroy, void, private_xauth_generic_t *this) { @@ -178,6 +180,7 @@ xauth_generic_t *xauth_generic_create_peer(identification_t *server, .xauth_method = { .initiate = _initiate_peer, .process = _process_peer, + .get_identity = _get_identity, .destroy = _destroy, }, }, @@ -201,6 +204,7 @@ xauth_generic_t *xauth_generic_create_server(identification_t *server, .xauth_method = { .initiate = _initiate_server, .process = _process_server, + .get_identity = _get_identity, .destroy = _destroy, }, }, -- cgit v1.2.3 From 462c9a4f72ec94ae993863341502d78a411f4e71 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Mon, 2 Jan 2012 16:38:47 +0100 Subject: Try all matching XAuth secrets we find, not only the first one --- .../plugins/xauth_generic/xauth_generic.c | 34 +++++++++++++++------- 1 file changed, 23 insertions(+), 11 deletions(-) (limited to 'src/libcharon/plugins/xauth_generic/xauth_generic.c') diff --git a/src/libcharon/plugins/xauth_generic/xauth_generic.c b/src/libcharon/plugins/xauth_generic/xauth_generic.c index 6350a130f..907de4322 100644 --- a/src/libcharon/plugins/xauth_generic/xauth_generic.c +++ b/src/libcharon/plugins/xauth_generic/xauth_generic.c @@ -100,7 +100,8 @@ METHOD(xauth_method_t, process_server, status_t, shared_key_t *shared; identification_t *id; chunk_t user = chunk_empty, pass = chunk_empty; - status_t status = SUCCESS; + status_t status = FAILED; + int tried = 0; enumerator = in->create_attribute_enumerator(in); while (enumerator->enumerate(enumerator, &attr)) @@ -136,20 +137,31 @@ METHOD(xauth_method_t, process_server, status_t, this->peer = id; } - shared = lib->credmgr->get_shared(lib->credmgr, SHARED_EAP, - this->server, this->peer); - if (!shared) + enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr, + SHARED_EAP, this->server, this->peer); + while (enumerator->enumerate(enumerator, &shared, NULL, NULL)) { - DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'", - this->server, this->peer); - status = FAILED; + if (chunk_equals(shared->get_key(shared), pass)) + { + status = SUCCESS; + break; + } + tried++; } - else if (!chunk_equals(shared->get_key(shared), pass)) + enumerator->destroy(enumerator); + if (status != SUCCESS) { - DBG1(DBG_IKE, "failed to authenticate '%Y' with XAuth", this->peer); - status = FAILED; + if (!tried) + { + DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'", + this->server, this->peer); + } + else + { + DBG1(DBG_IKE, "none of %d found XAuth secrets for '%Y' - '%Y' " + "matched", tried, this->server, this->peer); + } } - DESTROY_IF(shared); return status; } -- cgit v1.2.3 From 3110744a6baff7a4a061d0264e329cfe4b170431 Mon Sep 17 00:00:00 2001 From: Martin Willi Date: Thu, 22 Mar 2012 15:01:35 +0100 Subject: Fix null-terminated XAuth passwords, as sent by Android 4 --- src/libcharon/plugins/xauth_generic/xauth_generic.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/libcharon/plugins/xauth_generic/xauth_generic.c') diff --git a/src/libcharon/plugins/xauth_generic/xauth_generic.c b/src/libcharon/plugins/xauth_generic/xauth_generic.c index 907de4322..f0e675ac0 100644 --- a/src/libcharon/plugins/xauth_generic/xauth_generic.c +++ b/src/libcharon/plugins/xauth_generic/xauth_generic.c @@ -136,6 +136,10 @@ METHOD(xauth_method_t, process_server, status_t, this->peer->destroy(this->peer); this->peer = id; } + if (pass.len && pass.ptr[pass.len - 1] == 0) + { /* fix null-terminated passwords (Android etc.) */ + pass.len -= 1; + } enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr, SHARED_EAP, this->server, this->peer); -- cgit v1.2.3