Annotation of embedaddon/strongswan/src/libcharon/plugins/xauth_generic/xauth_generic.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2011 Tobias Brunner
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include "xauth_generic.h"
! 17:
! 18: #include <daemon.h>
! 19: #include <library.h>
! 20:
! 21: typedef struct private_xauth_generic_t private_xauth_generic_t;
! 22:
! 23: /**
! 24: * Private data of an xauth_generic_t object.
! 25: */
! 26: struct private_xauth_generic_t {
! 27:
! 28: /**
! 29: * Public interface.
! 30: */
! 31: xauth_generic_t public;
! 32:
! 33: /**
! 34: * ID of the server
! 35: */
! 36: identification_t *server;
! 37:
! 38: /**
! 39: * ID of the peer
! 40: */
! 41: identification_t *peer;
! 42: };
! 43:
! 44: METHOD(xauth_method_t, initiate_peer, status_t,
! 45: private_xauth_generic_t *this, cp_payload_t **out)
! 46: {
! 47: /* peer never initiates */
! 48: return FAILED;
! 49: }
! 50:
! 51: METHOD(xauth_method_t, process_peer, status_t,
! 52: private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out)
! 53: {
! 54: configuration_attribute_t *attr;
! 55: enumerator_t *enumerator;
! 56: shared_key_t *shared;
! 57: cp_payload_t *cp;
! 58: chunk_t msg;
! 59:
! 60: enumerator = in->create_attribute_enumerator(in);
! 61: while (enumerator->enumerate(enumerator, &attr))
! 62: {
! 63: if (attr->get_type(attr) == XAUTH_MESSAGE)
! 64: {
! 65: chunk_printable(attr->get_chunk(attr), &msg, '?');
! 66: DBG1(DBG_CFG, "XAuth message: %.*s", (int)msg.len, msg.ptr);
! 67: free(msg.ptr);
! 68: }
! 69: }
! 70: enumerator->destroy(enumerator);
! 71:
! 72: cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REPLY);
! 73:
! 74: enumerator = in->create_attribute_enumerator(in);
! 75: while (enumerator->enumerate(enumerator, &attr))
! 76: {
! 77: shared_key_type_t type = SHARED_EAP;
! 78:
! 79: switch (attr->get_type(attr))
! 80: {
! 81: case XAUTH_USER_NAME:
! 82: cp->add_attribute(cp, configuration_attribute_create_chunk(
! 83: PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_USER_NAME,
! 84: this->peer->get_encoding(this->peer)));
! 85: break;
! 86: case XAUTH_NEXT_PIN:
! 87: type = SHARED_PIN;
! 88: /* FALL */
! 89: case XAUTH_USER_PASSWORD:
! 90: shared = lib->credmgr->get_shared(lib->credmgr, type,
! 91: this->peer, this->server);
! 92: if (!shared)
! 93: {
! 94: DBG1(DBG_IKE, "no XAuth %s found for '%Y' - '%Y'",
! 95: type == SHARED_EAP ? "password" : "PIN",
! 96: this->peer, this->server);
! 97: enumerator->destroy(enumerator);
! 98: cp->destroy(cp);
! 99: return FAILED;
! 100: }
! 101: cp->add_attribute(cp, configuration_attribute_create_chunk(
! 102: PLV1_CONFIGURATION_ATTRIBUTE, attr->get_type(attr),
! 103: shared->get_key(shared)));
! 104: shared->destroy(shared);
! 105: break;
! 106: default:
! 107: break;
! 108: }
! 109: }
! 110: enumerator->destroy(enumerator);
! 111:
! 112: *out = cp;
! 113: return NEED_MORE;
! 114: }
! 115:
! 116: METHOD(xauth_method_t, initiate_server, status_t,
! 117: private_xauth_generic_t *this, cp_payload_t **out)
! 118: {
! 119: cp_payload_t *cp;
! 120:
! 121: cp = cp_payload_create_type(PLV1_CONFIGURATION, CFG_REQUEST);
! 122: cp->add_attribute(cp, configuration_attribute_create_chunk(
! 123: PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_USER_NAME, chunk_empty));
! 124: cp->add_attribute(cp, configuration_attribute_create_chunk(
! 125: PLV1_CONFIGURATION_ATTRIBUTE, XAUTH_USER_PASSWORD, chunk_empty));
! 126: *out = cp;
! 127: return NEED_MORE;
! 128: }
! 129:
! 130: METHOD(xauth_method_t, process_server, status_t,
! 131: private_xauth_generic_t *this, cp_payload_t *in, cp_payload_t **out)
! 132: {
! 133: configuration_attribute_t *attr;
! 134: enumerator_t *enumerator;
! 135: shared_key_t *shared;
! 136: identification_t *id;
! 137: chunk_t user = chunk_empty, pass = chunk_empty;
! 138: status_t status = FAILED;
! 139: int tried = 0;
! 140:
! 141: enumerator = in->create_attribute_enumerator(in);
! 142: while (enumerator->enumerate(enumerator, &attr))
! 143: {
! 144: switch (attr->get_type(attr))
! 145: {
! 146: case XAUTH_USER_NAME:
! 147: user = attr->get_chunk(attr);
! 148: break;
! 149: case XAUTH_USER_PASSWORD:
! 150: pass = attr->get_chunk(attr);
! 151: break;
! 152: default:
! 153: break;
! 154: }
! 155: }
! 156: enumerator->destroy(enumerator);
! 157:
! 158: if (!user.ptr || !pass.ptr)
! 159: {
! 160: DBG1(DBG_IKE, "peer did not respond to our XAuth request");
! 161: return FAILED;
! 162: }
! 163: if (user.len)
! 164: {
! 165: id = identification_create_from_data(user);
! 166: if (!id)
! 167: {
! 168: DBG1(DBG_IKE, "failed to parse provided XAuth username");
! 169: return FAILED;
! 170: }
! 171: this->peer->destroy(this->peer);
! 172: this->peer = id;
! 173: }
! 174: if (pass.len && pass.ptr[pass.len - 1] == 0)
! 175: { /* fix null-terminated passwords (Android etc.) */
! 176: pass.len -= 1;
! 177: }
! 178:
! 179: enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
! 180: SHARED_EAP, this->server, this->peer);
! 181: while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
! 182: {
! 183: if (chunk_equals_const(shared->get_key(shared), pass))
! 184: {
! 185: status = SUCCESS;
! 186: break;
! 187: }
! 188: tried++;
! 189: }
! 190: enumerator->destroy(enumerator);
! 191: if (status != SUCCESS)
! 192: {
! 193: if (!tried)
! 194: {
! 195: DBG1(DBG_IKE, "no XAuth secret found for '%Y' - '%Y'",
! 196: this->server, this->peer);
! 197: }
! 198: else
! 199: {
! 200: DBG1(DBG_IKE, "none of %d found XAuth secrets for '%Y' - '%Y' "
! 201: "matched", tried, this->server, this->peer);
! 202: }
! 203: }
! 204: return status;
! 205: }
! 206:
! 207: METHOD(xauth_method_t, get_identity, identification_t*,
! 208: private_xauth_generic_t *this)
! 209: {
! 210: return this->peer;
! 211: }
! 212:
! 213: METHOD(xauth_method_t, destroy, void,
! 214: private_xauth_generic_t *this)
! 215: {
! 216: this->server->destroy(this->server);
! 217: this->peer->destroy(this->peer);
! 218: free(this);
! 219: }
! 220:
! 221: /*
! 222: * Described in header.
! 223: */
! 224: xauth_generic_t *xauth_generic_create_peer(identification_t *server,
! 225: identification_t *peer,
! 226: char *profile)
! 227: {
! 228: private_xauth_generic_t *this;
! 229:
! 230: INIT(this,
! 231: .public = {
! 232: .xauth_method = {
! 233: .initiate = _initiate_peer,
! 234: .process = _process_peer,
! 235: .get_identity = _get_identity,
! 236: .destroy = _destroy,
! 237: },
! 238: },
! 239: .server = server->clone(server),
! 240: .peer = peer->clone(peer),
! 241: );
! 242:
! 243: return &this->public;
! 244: }
! 245:
! 246: /*
! 247: * Described in header.
! 248: */
! 249: xauth_generic_t *xauth_generic_create_server(identification_t *server,
! 250: identification_t *peer,
! 251: char *profile)
! 252: {
! 253: private_xauth_generic_t *this;
! 254:
! 255: INIT(this,
! 256: .public = {
! 257: .xauth_method = {
! 258: .initiate = _initiate_server,
! 259: .process = _process_server,
! 260: .get_identity = _get_identity,
! 261: .destroy = _destroy,
! 262: },
! 263: },
! 264: .server = server->clone(server),
! 265: .peer = peer->clone(peer),
! 266: );
! 267:
! 268: return &this->public;
! 269: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>