2 * Copyright (C) 2005-2007 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
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
24 ENUM(ike_version_names
, IKE_ANY
, IKEV2
,
30 typedef struct private_ike_cfg_t private_ike_cfg_t
;
33 * Private data of an ike_cfg_t object
35 struct private_ike_cfg_t
{
43 * Number of references hold by others to this ike_cfg
50 ike_version_t version
;
53 * Address of local host
58 * Address of remote host
63 * Allow override of local address
68 * Allow override of remote address
83 * should we send a certificate request?
88 * enforce UDP encapsulation
93 * use IKEv1 fragmentation
95 fragmentation_t fragmentation
;
98 * List of proposals to use
100 linked_list_t
*proposals
;
103 METHOD(ike_cfg_t
, get_version
, ike_version_t
,
104 private_ike_cfg_t
*this)
106 return this->version
;
109 METHOD(ike_cfg_t
, send_certreq
, bool,
110 private_ike_cfg_t
*this)
112 return this->certreq
;
115 METHOD(ike_cfg_t
, force_encap_
, bool,
116 private_ike_cfg_t
*this)
118 return this->force_encap
;
121 METHOD(ike_cfg_t
, fragmentation
, fragmentation_t
,
122 private_ike_cfg_t
*this)
124 return this->fragmentation
;
127 METHOD(ike_cfg_t
, get_my_addr
, char*,
128 private_ike_cfg_t
*this, bool *allow_any
)
132 *allow_any
= this->my_allow_any
;
137 METHOD(ike_cfg_t
, get_other_addr
, char*,
138 private_ike_cfg_t
*this, bool *allow_any
)
142 *allow_any
= this->other_allow_any
;
147 METHOD(ike_cfg_t
, get_my_port
, u_int16_t
,
148 private_ike_cfg_t
*this)
150 return this->my_port
;
153 METHOD(ike_cfg_t
, get_other_port
, u_int16_t
,
154 private_ike_cfg_t
*this)
156 return this->other_port
;
159 METHOD(ike_cfg_t
, add_proposal
, void,
160 private_ike_cfg_t
*this, proposal_t
*proposal
)
162 this->proposals
->insert_last(this->proposals
, proposal
);
165 METHOD(ike_cfg_t
, get_proposals
, linked_list_t
*,
166 private_ike_cfg_t
*this)
168 enumerator_t
*enumerator
;
170 linked_list_t
*proposals
;
172 proposals
= linked_list_create();
173 enumerator
= this->proposals
->create_enumerator(this->proposals
);
174 while (enumerator
->enumerate(enumerator
, ¤t
))
176 current
= current
->clone(current
);
177 proposals
->insert_last(proposals
, current
);
179 enumerator
->destroy(enumerator
);
181 DBG2(DBG_CFG
, "configured proposals: %#P", proposals
);
186 METHOD(ike_cfg_t
, select_proposal
, proposal_t
*,
187 private_ike_cfg_t
*this, linked_list_t
*proposals
, bool private)
189 enumerator_t
*stored_enum
, *supplied_enum
;
190 proposal_t
*stored
, *supplied
, *selected
;
192 stored_enum
= this->proposals
->create_enumerator(this->proposals
);
193 supplied_enum
= proposals
->create_enumerator(proposals
);
196 /* compare all stored proposals with all supplied. Stored ones are preferred.*/
197 while (stored_enum
->enumerate(stored_enum
, (void**)&stored
))
199 proposals
->reset_enumerator(proposals
, supplied_enum
);
201 while (supplied_enum
->enumerate(supplied_enum
, (void**)&supplied
))
203 selected
= stored
->select(stored
, supplied
, private);
206 /* they match, return */
207 stored_enum
->destroy(stored_enum
);
208 supplied_enum
->destroy(supplied_enum
);
209 DBG2(DBG_CFG
, "received proposals: %#P", proposals
);
210 DBG2(DBG_CFG
, "configured proposals: %#P", this->proposals
);
211 DBG2(DBG_CFG
, "selected proposal: %P", selected
);
216 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
217 stored_enum
->destroy(stored_enum
);
218 supplied_enum
->destroy(supplied_enum
);
219 DBG1(DBG_CFG
, "received proposals: %#P", proposals
);
220 DBG1(DBG_CFG
, "configured proposals: %#P", this->proposals
);
225 METHOD(ike_cfg_t
, get_dh_group
, diffie_hellman_group_t
,
226 private_ike_cfg_t
*this)
228 enumerator_t
*enumerator
;
229 proposal_t
*proposal
;
230 u_int16_t dh_group
= MODP_NONE
;
232 enumerator
= this->proposals
->create_enumerator(this->proposals
);
233 while (enumerator
->enumerate(enumerator
, &proposal
))
235 if (proposal
->get_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
, &dh_group
, NULL
))
240 enumerator
->destroy(enumerator
);
244 METHOD(ike_cfg_t
, equals
, bool,
245 private_ike_cfg_t
*this, ike_cfg_t
*other_public
)
247 private_ike_cfg_t
*other
= (private_ike_cfg_t
*)other_public
;
248 enumerator_t
*e1
, *e2
;
256 if (this->public.equals
!= other
->public.equals
)
260 if (this->proposals
->get_count(this->proposals
) !=
261 other
->proposals
->get_count(other
->proposals
))
265 e1
= this->proposals
->create_enumerator(this->proposals
);
266 e2
= this->proposals
->create_enumerator(this->proposals
);
267 while (e1
->enumerate(e1
, &p1
) && e2
->enumerate(e2
, &p2
))
269 if (!p1
->equals(p1
, p2
))
279 this->version
== other
->version
&&
280 this->certreq
== other
->certreq
&&
281 this->force_encap
== other
->force_encap
&&
282 this->fragmentation
== other
->fragmentation
&&
283 streq(this->me
, other
->me
) &&
284 streq(this->other
, other
->other
) &&
285 this->my_port
== other
->my_port
&&
286 this->other_port
== other
->other_port
);
289 METHOD(ike_cfg_t
, get_ref
, ike_cfg_t
*,
290 private_ike_cfg_t
*this)
292 ref_get(&this->refcount
);
293 return &this->public;
296 METHOD(ike_cfg_t
, destroy
, void,
297 private_ike_cfg_t
*this)
299 if (ref_put(&this->refcount
))
301 this->proposals
->destroy_offset(this->proposals
,
302 offsetof(proposal_t
, destroy
));
310 * Described in header.
312 ike_cfg_t
*ike_cfg_create(ike_version_t version
, bool certreq
, bool force_encap
,
313 char *me
, bool my_allow_any
, u_int16_t my_port
,
314 char *other
, bool other_allow_any
, u_int16_t other_port
,
315 fragmentation_t fragmentation
)
317 private_ike_cfg_t
*this;
321 .get_version
= _get_version
,
322 .send_certreq
= _send_certreq
,
323 .force_encap
= _force_encap_
,
324 .fragmentation
= _fragmentation
,
325 .get_my_addr
= _get_my_addr
,
326 .get_other_addr
= _get_other_addr
,
327 .get_my_port
= _get_my_port
,
328 .get_other_port
= _get_other_port
,
329 .add_proposal
= _add_proposal
,
330 .get_proposals
= _get_proposals
,
331 .select_proposal
= _select_proposal
,
332 .get_dh_group
= _get_dh_group
,
340 .force_encap
= force_encap
,
341 .fragmentation
= fragmentation
,
343 .other
= strdup(other
),
344 .my_allow_any
= my_allow_any
,
345 .other_allow_any
= other_allow_any
,
347 .other_port
= other_port
,
348 .proposals
= linked_list_create(),
351 return &this->public;