2 * Copyright (C) 2011 Tobias Brunner
4 * Copyright (C) secunet Security Networks AG
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 #include "xauth_generic.h"
22 typedef struct private_xauth_generic_t private_xauth_generic_t
;
25 * Private data of an xauth_generic_t object.
27 struct private_xauth_generic_t
{
32 xauth_generic_t
public;
37 identification_t
*server
;
42 identification_t
*peer
;
45 METHOD(xauth_method_t
, initiate_peer
, status_t
,
46 private_xauth_generic_t
*this, cp_payload_t
**out
)
48 /* peer never initiates */
52 METHOD(xauth_method_t
, process_peer
, status_t
,
53 private_xauth_generic_t
*this, cp_payload_t
*in
, cp_payload_t
**out
)
55 configuration_attribute_t
*attr
;
56 enumerator_t
*enumerator
;
61 enumerator
= in
->create_attribute_enumerator(in
);
62 while (enumerator
->enumerate(enumerator
, &attr
))
64 if (attr
->get_type(attr
) == XAUTH_MESSAGE
)
66 chunk_printable(attr
->get_chunk(attr
), &msg
, '?');
67 DBG1(DBG_CFG
, "XAuth message: %.*s", (int)msg
.len
, msg
.ptr
);
71 enumerator
->destroy(enumerator
);
73 cp
= cp_payload_create_type(PLV1_CONFIGURATION
, CFG_REPLY
);
75 enumerator
= in
->create_attribute_enumerator(in
);
76 while (enumerator
->enumerate(enumerator
, &attr
))
78 shared_key_type_t type
= SHARED_EAP
;
80 switch (attr
->get_type(attr
))
83 cp
->add_attribute(cp
, configuration_attribute_create_chunk(
84 PLV1_CONFIGURATION_ATTRIBUTE
, XAUTH_USER_NAME
,
85 this->peer
->get_encoding(this->peer
)));
90 case XAUTH_USER_PASSWORD
:
91 shared
= lib
->credmgr
->get_shared(lib
->credmgr
, type
,
92 this->peer
, this->server
);
95 DBG1(DBG_IKE
, "no XAuth %s found for '%Y' - '%Y'",
96 type
== SHARED_EAP
? "password" : "PIN",
97 this->peer
, this->server
);
98 enumerator
->destroy(enumerator
);
102 cp
->add_attribute(cp
, configuration_attribute_create_chunk(
103 PLV1_CONFIGURATION_ATTRIBUTE
, attr
->get_type(attr
),
104 shared
->get_key(shared
)));
105 shared
->destroy(shared
);
111 enumerator
->destroy(enumerator
);
117 METHOD(xauth_method_t
, initiate_server
, status_t
,
118 private_xauth_generic_t
*this, cp_payload_t
**out
)
122 cp
= cp_payload_create_type(PLV1_CONFIGURATION
, CFG_REQUEST
);
123 cp
->add_attribute(cp
, configuration_attribute_create_chunk(
124 PLV1_CONFIGURATION_ATTRIBUTE
, XAUTH_USER_NAME
, chunk_empty
));
125 cp
->add_attribute(cp
, configuration_attribute_create_chunk(
126 PLV1_CONFIGURATION_ATTRIBUTE
, XAUTH_USER_PASSWORD
, chunk_empty
));
131 METHOD(xauth_method_t
, process_server
, status_t
,
132 private_xauth_generic_t
*this, cp_payload_t
*in
, cp_payload_t
**out
)
134 configuration_attribute_t
*attr
;
135 enumerator_t
*enumerator
;
136 shared_key_t
*shared
;
137 identification_t
*id
;
138 chunk_t user
= chunk_empty
, pass
= chunk_empty
;
139 status_t status
= FAILED
;
142 enumerator
= in
->create_attribute_enumerator(in
);
143 while (enumerator
->enumerate(enumerator
, &attr
))
145 switch (attr
->get_type(attr
))
147 case XAUTH_USER_NAME
:
148 user
= attr
->get_chunk(attr
);
150 case XAUTH_USER_PASSWORD
:
151 pass
= attr
->get_chunk(attr
);
157 enumerator
->destroy(enumerator
);
159 if (!user
.ptr
|| !pass
.ptr
)
161 DBG1(DBG_IKE
, "peer did not respond to our XAuth request");
166 id
= identification_create_from_data(user
);
169 DBG1(DBG_IKE
, "failed to parse provided XAuth username");
172 this->peer
->destroy(this->peer
);
175 if (pass
.len
&& pass
.ptr
[pass
.len
- 1] == 0)
176 { /* fix null-terminated passwords (Android etc.) */
180 enumerator
= lib
->credmgr
->create_shared_enumerator(lib
->credmgr
,
181 SHARED_EAP
, this->server
, this->peer
);
182 while (enumerator
->enumerate(enumerator
, &shared
, NULL
, NULL
))
184 if (chunk_equals_const(shared
->get_key(shared
), pass
))
191 enumerator
->destroy(enumerator
);
192 if (status
!= SUCCESS
)
196 DBG1(DBG_IKE
, "no XAuth secret found for '%Y' - '%Y'",
197 this->server
, this->peer
);
201 DBG1(DBG_IKE
, "none of %d found XAuth secrets for '%Y' - '%Y' "
202 "matched", tried
, this->server
, this->peer
);
208 METHOD(xauth_method_t
, get_identity
, identification_t
*,
209 private_xauth_generic_t
*this)
214 METHOD(xauth_method_t
, destroy
, void,
215 private_xauth_generic_t
*this)
217 this->server
->destroy(this->server
);
218 this->peer
->destroy(this->peer
);
223 * Described in header.
225 xauth_generic_t
*xauth_generic_create_peer(identification_t
*server
,
226 identification_t
*peer
,
229 private_xauth_generic_t
*this;
234 .initiate
= _initiate_peer
,
235 .process
= _process_peer
,
236 .get_identity
= _get_identity
,
240 .server
= server
->clone(server
),
241 .peer
= peer
->clone(peer
),
244 return &this->public;
248 * Described in header.
250 xauth_generic_t
*xauth_generic_create_server(identification_t
*server
,
251 identification_t
*peer
,
254 private_xauth_generic_t
*this;
259 .initiate
= _initiate_server
,
260 .process
= _process_server
,
261 .get_identity
= _get_identity
,
265 .server
= server
->clone(server
),
266 .peer
= peer
->clone(peer
),
269 return &this->public;