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
52 * should we send a certificate request?
57 * enforce UDP encapsulation
62 * List of proposals to use
64 linked_list_t
*proposals
;
68 * Implementation of ike_cfg_t.certreq.
70 static bool send_certreq(private_ike_cfg_t
*this)
76 * Implementation of ike_cfg_t.force_encap.
78 static bool force_encap_meth(private_ike_cfg_t
*this)
80 return this->force_encap
;
84 * Implementation of ike_cfg_t.get_my_host.
86 static host_t
*get_my_host (private_ike_cfg_t
*this)
92 * Implementation of ike_cfg_t.get_other_host.
94 static host_t
*get_other_host (private_ike_cfg_t
*this)
96 return this->other_host
;
100 * Implementation of ike_cfg_t.add_proposal.
102 static void add_proposal(private_ike_cfg_t
*this, proposal_t
*proposal
)
104 this->proposals
->insert_last(this->proposals
, proposal
);
108 * Implementation of ike_cfg_t.get_proposals.
110 static linked_list_t
* get_proposals(private_ike_cfg_t
*this)
112 iterator_t
*iterator
;
114 linked_list_t
*proposals
= linked_list_create();
116 iterator
= this->proposals
->create_iterator(this->proposals
, TRUE
);
117 while (iterator
->iterate(iterator
, (void**)¤t
))
119 current
= current
->clone(current
);
120 proposals
->insert_last(proposals
, (void*)current
);
122 iterator
->destroy(iterator
);
128 * Implementation of ike_cfg_t.select_proposal.
130 static proposal_t
*select_proposal(private_ike_cfg_t
*this,
131 linked_list_t
*proposals
)
133 iterator_t
*stored_iter
, *supplied_iter
;
134 proposal_t
*stored
, *supplied
, *selected
;
136 stored_iter
= this->proposals
->create_iterator(this->proposals
, TRUE
);
137 supplied_iter
= proposals
->create_iterator(proposals
, TRUE
);
139 /* compare all stored proposals with all supplied. Stored ones are preferred.*/
140 while (stored_iter
->iterate(stored_iter
, (void**)&stored
))
142 supplied_iter
->reset(supplied_iter
);
144 while (supplied_iter
->iterate(supplied_iter
, (void**)&supplied
))
146 selected
= stored
->select(stored
, supplied
);
149 /* they match, return */
150 stored_iter
->destroy(stored_iter
);
151 supplied_iter
->destroy(supplied_iter
);
156 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
157 stored_iter
->destroy(stored_iter
);
158 supplied_iter
->destroy(supplied_iter
);
164 * Implementation of ike_cfg_t.get_dh_group.
166 static diffie_hellman_group_t
get_dh_group(private_ike_cfg_t
*this)
168 enumerator_t
*enumerator
;
169 proposal_t
*proposal
;
170 u_int16_t dh_group
= MODP_NONE
;
172 enumerator
= this->proposals
->create_enumerator(this->proposals
);
173 while (enumerator
->enumerate(enumerator
, &proposal
))
175 if (proposal
->get_algorithm(proposal
, DIFFIE_HELLMAN_GROUP
, &dh_group
, NULL
))
180 enumerator
->destroy(enumerator
);
185 * Implementation of ike_cfg_t.equals.
187 static bool equals(private_ike_cfg_t
*this, private_ike_cfg_t
*other
)
189 enumerator_t
*e1
, *e2
;
197 if (this->public.equals
!= other
->public.equals
)
201 if (this->proposals
->get_count(this->proposals
) !=
202 other
->proposals
->get_count(other
->proposals
))
206 e1
= this->proposals
->create_enumerator(this->proposals
);
207 e2
= this->proposals
->create_enumerator(this->proposals
);
208 while (e1
->enumerate(e1
, &p1
) && e2
->enumerate(e2
, &p2
))
210 if (!p1
->equals(p1
, p2
))
220 this->certreq
== other
->certreq
&&
221 this->force_encap
== other
->force_encap
&&
222 this->my_host
->equals(this->my_host
, other
->my_host
) &&
223 this->other_host
->equals(this->other_host
, other
->other_host
));
227 * Implementation of ike_cfg_t.get_ref.
229 static void get_ref(private_ike_cfg_t
*this)
231 ref_get(&this->refcount
);
235 * Implementation of ike_cfg_t.destroy.
237 static void destroy(private_ike_cfg_t
*this)
239 if (ref_put(&this->refcount
))
241 this->proposals
->destroy_offset(this->proposals
,
242 offsetof(proposal_t
, destroy
));
243 this->my_host
->destroy(this->my_host
);
244 this->other_host
->destroy(this->other_host
);
250 * Described in header.
252 ike_cfg_t
*ike_cfg_create(bool certreq
, bool force_encap
,
253 host_t
*my_host
, host_t
*other_host
)
255 private_ike_cfg_t
*this = malloc_thing(private_ike_cfg_t
);
257 /* public functions */
258 this->public.send_certreq
= (bool(*)(ike_cfg_t
*))send_certreq
;
259 this->public.force_encap
= (bool (*) (ike_cfg_t
*))force_encap_meth
;
260 this->public.get_my_host
= (host_t
*(*)(ike_cfg_t
*))get_my_host
;
261 this->public.get_other_host
= (host_t
*(*)(ike_cfg_t
*))get_other_host
;
262 this->public.add_proposal
= (void(*)(ike_cfg_t
*, proposal_t
*)) add_proposal
;
263 this->public.get_proposals
= (linked_list_t
*(*)(ike_cfg_t
*))get_proposals
;
264 this->public.select_proposal
= (proposal_t
*(*)(ike_cfg_t
*,linked_list_t
*))select_proposal
;
265 this->public.get_dh_group
= (diffie_hellman_group_t(*)(ike_cfg_t
*)) get_dh_group
;
266 this->public.equals
= (bool(*)(ike_cfg_t
*,ike_cfg_t
*)) equals
;
267 this->public.get_ref
= (void(*)(ike_cfg_t
*))get_ref
;
268 this->public.destroy
= (void(*)(ike_cfg_t
*))destroy
;
270 /* private variables */
272 this->certreq
= certreq
;
273 this->force_encap
= force_encap
;
274 this->my_host
= my_host
;
275 this->other_host
= other_host
;
277 this->proposals
= linked_list_create();
279 return &this->public;