Return to xauth_generic.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libcharon / plugins / xauth_generic |
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: }