Annotation of embedaddon/strongswan/src/libcharon/plugins/xauth_generic/xauth_generic.c, revision 1.1.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>