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 typedef struct private_ike_cfg_t private_ike_cfg_t
;
27 * Private data of an ike_cfg_t object
29 struct private_ike_cfg_t
{
37 * Number of references hold by others to this ike_cfg
42 * Address of local host
47 * Address of remote host
62 * should we send a certificate request?
67 * enforce UDP encapsulation
72 * List of proposals to use
74 linked_list_t
*proposals
;
77 METHOD(ike_cfg_t
, send_certreq
, bool,
78 private_ike_cfg_t
*this)
83 METHOD(ike_cfg_t
, force_encap_
, bool,
84 private_ike_cfg_t
*this)
86 return this->force_encap
;
89 METHOD(ike_cfg_t
, get_my_addr
, char*,
90 private_ike_cfg_t
*this)
95 METHOD(ike_cfg_t
, get_other_addr
, char*,
96 private_ike_cfg_t
*this)
101 METHOD(ike_cfg_t
, get_my_port
, u_int16_t
,
102 private_ike_cfg_t
*this)
104 return this->my_port
;
107 METHOD(ike_cfg_t
, get_other_port
, u_int16_t
,
108 private_ike_cfg_t
*this)
110 return this->other_port
;
113 METHOD(ike_cfg_t
, add_proposal
, void,
114 private_ike_cfg_t
*this, proposal_t
*proposal
)
116 this->proposals
->insert_last(this->proposals
, proposal
);
119 METHOD(ike_cfg_t
, get_proposals
, linked_list_t
*,
120 private_ike_cfg_t
*this)
122 enumerator_t
*enumerator
;
124 linked_list_t
*proposals
;
126 proposals
= linked_list_create();
127 enumerator
= this->proposals
->create_enumerator(this->proposals
);
128 while (enumerator
->enumerate(enumerator
, ¤t
))
130 current
= current
->clone(current
);
131 proposals
->insert_last(proposals
, current
);
133 enumerator
->destroy(enumerator
);
138 METHOD(ike_cfg_t
, select_proposal
, proposal_t
*,
139 private_ike_cfg_t
*this, linked_list_t
*proposals
, bool private)
141 enumerator_t
*stored_enum
, *supplied_enum
;
142 proposal_t
*stored
, *supplied
, *selected
;
144 stored_enum
= this->proposals
->create_enumerator(this->proposals
);
145 supplied_enum
= proposals
->create_enumerator(proposals
);
148 /* compare all stored proposals with all supplied. Stored ones are preferred.*/
149 while (stored_enum
->enumerate(stored_enum
, (void**)&stored
))
151 proposals
->reset_enumerator(proposals
, supplied_enum
);
153 while (supplied_enum
->enumerate(supplied_enum
, (void**)&supplied
))
155 selected
= stored
->select(stored
, supplied
, private);
158 /* they match, return */
159 stored_enum
->destroy(stored_enum
);
160 supplied_enum
->destroy(supplied_enum
);
161 DBG2(DBG_CFG
, "received proposals: %#P", proposals
);
162 DBG2(DBG_CFG
, "configured proposals: %#P", this->proposals
);
163 DBG2(DBG_CFG
, "selected proposal: %P", selected
);
168 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
169 stored_enum
->destroy(stored_enum
);
170 supplied_enum
->destroy(supplied_enum
);
171 DBG1(DBG_CFG
, "received proposals: %#P", proposals
);
172 DBG1(DBG_CFG
, "configured proposals: %#P", this->proposals
);
177 METHOD(ike_cfg_t
, get_dh_group
, diffie_hellman_group_t
,
178 private_ike_cfg_t
*this)
180 enumerator_t
*enumerator
;
181 proposal_t
*proposal
;
182 u_int16_t dh_group
= MODP_NONE
;
184 enumerator
= this->proposals
->create_enumerator(this->proposals
);
185 while (enumerator
->enumerate(enumerator
, &proposal
))
187 if (proposal
->get_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
, &dh_group
, NULL
))
192 enumerator
->destroy(enumerator
);
196 METHOD(ike_cfg_t
, equals
, bool,
197 private_ike_cfg_t
*this, ike_cfg_t
*other_public
)
199 private_ike_cfg_t
*other
= (private_ike_cfg_t
*)other_public
;
200 enumerator_t
*e1
, *e2
;
208 if (this->public.equals
!= other
->public.equals
)
212 if (this->proposals
->get_count(this->proposals
) !=
213 other
->proposals
->get_count(other
->proposals
))
217 e1
= this->proposals
->create_enumerator(this->proposals
);
218 e2
= this->proposals
->create_enumerator(this->proposals
);
219 while (e1
->enumerate(e1
, &p1
) && e2
->enumerate(e2
, &p2
))
221 if (!p1
->equals(p1
, p2
))
231 this->certreq
== other
->certreq
&&
232 this->force_encap
== other
->force_encap
&&
233 streq(this->me
, other
->me
) &&
234 streq(this->other
, other
->other
) &&
235 this->my_port
== other
->my_port
&&
236 this->other_port
== other
->other_port
);
239 METHOD(ike_cfg_t
, get_ref
, ike_cfg_t
*,
240 private_ike_cfg_t
*this)
242 ref_get(&this->refcount
);
243 return &this->public;
246 METHOD(ike_cfg_t
, destroy
, void,
247 private_ike_cfg_t
*this)
249 if (ref_put(&this->refcount
))
251 this->proposals
->destroy_offset(this->proposals
,
252 offsetof(proposal_t
, destroy
));
260 * Described in header.
262 ike_cfg_t
*ike_cfg_create(bool certreq
, bool force_encap
,
263 char *me
, u_int16_t my_port
, char *other
, u_int16_t other_port
)
265 private_ike_cfg_t
*this;
269 .send_certreq
= _send_certreq
,
270 .force_encap
= _force_encap_
,
271 .get_my_addr
= _get_my_addr
,
272 .get_other_addr
= _get_other_addr
,
273 .get_my_port
= _get_my_port
,
274 .get_other_port
= _get_other_port
,
275 .add_proposal
= _add_proposal
,
276 .get_proposals
= _get_proposals
,
277 .select_proposal
= _select_proposal
,
278 .get_dh_group
= _get_dh_group
,
285 .force_encap
= force_encap
,
287 .other
= strdup(other
),
289 .other_port
= other_port
,
290 .proposals
= linked_list_create(),
293 return &this->public;