updated Doxyfile
[strongswan.git] / src / charon / config / ike_cfg.c
1 /*
2 * Copyright (C) 2005-2007 Martin Willi
3 * Copyright (C) 2005 Jan Hutter
4 * Hochschule fuer Technik Rapperswil
5 *
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>.
10 *
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
14 * for more details.
15 *
16 * $Id$
17 */
18
19 #include "ike_cfg.h"
20
21 #include <string.h>
22
23 #include <daemon.h>
24
25
26 typedef struct private_ike_cfg_t private_ike_cfg_t;
27
28 /**
29 * Private data of an ike_cfg_t object
30 */
31 struct private_ike_cfg_t {
32
33 /**
34 * Public part
35 */
36 ike_cfg_t public;
37
38 /**
39 * Number of references hold by others to this ike_cfg
40 */
41 refcount_t refcount;
42
43 /**
44 * Address of local host
45 */
46 char *me;
47
48 /**
49 * Address of remote host
50 */
51 char *other;
52
53 /**
54 * should we send a certificate request?
55 */
56 bool certreq;
57
58 /**
59 * enforce UDP encapsulation
60 */
61 bool force_encap;
62
63 /**
64 * List of proposals to use
65 */
66 linked_list_t *proposals;
67 };
68
69 /**
70 * Implementation of ike_cfg_t.certreq.
71 */
72 static bool send_certreq(private_ike_cfg_t *this)
73 {
74 return this->certreq;
75 }
76
77 /**
78 * Implementation of ike_cfg_t.force_encap.
79 */
80 static bool force_encap_meth(private_ike_cfg_t *this)
81 {
82 return this->force_encap;
83 }
84
85 /**
86 * Implementation of ike_cfg_t.get_my_addr.
87 */
88 static char *get_my_addr(private_ike_cfg_t *this)
89 {
90 return this->me;
91 }
92
93 /**
94 * Implementation of ike_cfg_t.get_other_addr.
95 */
96 static char *get_other_addr(private_ike_cfg_t *this)
97 {
98 return this->other;
99 }
100
101 /**
102 * Implementation of ike_cfg_t.add_proposal.
103 */
104 static void add_proposal(private_ike_cfg_t *this, proposal_t *proposal)
105 {
106 this->proposals->insert_last(this->proposals, proposal);
107 }
108
109 /**
110 * Implementation of ike_cfg_t.get_proposals.
111 */
112 static linked_list_t* get_proposals(private_ike_cfg_t *this)
113 {
114 iterator_t *iterator;
115 proposal_t *current;
116 linked_list_t *proposals = linked_list_create();
117
118 iterator = this->proposals->create_iterator(this->proposals, TRUE);
119 while (iterator->iterate(iterator, (void**)&current))
120 {
121 current = current->clone(current);
122 proposals->insert_last(proposals, (void*)current);
123 }
124 iterator->destroy(iterator);
125
126 return proposals;
127 }
128
129 /**
130 * Implementation of ike_cfg_t.select_proposal.
131 */
132 static proposal_t *select_proposal(private_ike_cfg_t *this,
133 linked_list_t *proposals)
134 {
135 iterator_t *stored_iter, *supplied_iter;
136 proposal_t *stored, *supplied, *selected;
137
138 stored_iter = this->proposals->create_iterator(this->proposals, TRUE);
139 supplied_iter = proposals->create_iterator(proposals, TRUE);
140
141
142 /* compare all stored proposals with all supplied. Stored ones are preferred.*/
143 while (stored_iter->iterate(stored_iter, (void**)&stored))
144 {
145 supplied_iter->reset(supplied_iter);
146
147 while (supplied_iter->iterate(supplied_iter, (void**)&supplied))
148 {
149 selected = stored->select(stored, supplied);
150 if (selected)
151 {
152 /* they match, return */
153 stored_iter->destroy(stored_iter);
154 supplied_iter->destroy(supplied_iter);
155 DBG2(DBG_CFG, "received proposals: %#P", proposals);
156 DBG2(DBG_CFG, "configured proposals: %#P", this->proposals);
157 DBG2(DBG_CFG, "selected proposal: %P", selected);
158 return selected;
159 }
160 }
161 }
162 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
163 stored_iter->destroy(stored_iter);
164 supplied_iter->destroy(supplied_iter);
165 DBG1(DBG_CFG, "received proposals: %#P", proposals);
166 DBG1(DBG_CFG, "configured proposals: %#P", this->proposals);
167
168 return NULL;
169 }
170
171 /**
172 * Implementation of ike_cfg_t.get_dh_group.
173 */
174 static diffie_hellman_group_t get_dh_group(private_ike_cfg_t *this)
175 {
176 enumerator_t *enumerator;
177 proposal_t *proposal;
178 u_int16_t dh_group = MODP_NONE;
179
180 enumerator = this->proposals->create_enumerator(this->proposals);
181 while (enumerator->enumerate(enumerator, &proposal))
182 {
183 if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, &dh_group, NULL))
184 {
185 break;
186 }
187 }
188 enumerator->destroy(enumerator);
189 return dh_group;
190 }
191
192 /**
193 * Implementation of ike_cfg_t.equals.
194 */
195 static bool equals(private_ike_cfg_t *this, private_ike_cfg_t *other)
196 {
197 enumerator_t *e1, *e2;
198 proposal_t *p1, *p2;
199 bool eq = TRUE;
200
201 if (this == other)
202 {
203 return TRUE;
204 }
205 if (this->public.equals != other->public.equals)
206 {
207 return FALSE;
208 }
209 if (this->proposals->get_count(this->proposals) !=
210 other->proposals->get_count(other->proposals))
211 {
212 return FALSE;
213 }
214 e1 = this->proposals->create_enumerator(this->proposals);
215 e2 = this->proposals->create_enumerator(this->proposals);
216 while (e1->enumerate(e1, &p1) && e2->enumerate(e2, &p2))
217 {
218 if (!p1->equals(p1, p2))
219 {
220 eq = FALSE;
221 break;
222 }
223 }
224 e1->destroy(e1);
225 e2->destroy(e2);
226
227 return (eq &&
228 this->certreq == other->certreq &&
229 this->force_encap == other->force_encap &&
230 streq(this->me, other->me) &&
231 streq(this->other, other->other));
232 }
233
234 /**
235 * Implementation of ike_cfg_t.get_ref.
236 */
237 static ike_cfg_t* get_ref(private_ike_cfg_t *this)
238 {
239 ref_get(&this->refcount);
240 return &this->public;
241 }
242
243 /**
244 * Implementation of ike_cfg_t.destroy.
245 */
246 static void destroy(private_ike_cfg_t *this)
247 {
248 if (ref_put(&this->refcount))
249 {
250 this->proposals->destroy_offset(this->proposals,
251 offsetof(proposal_t, destroy));
252 free(this->me);
253 free(this->other);
254 free(this);
255 }
256 }
257
258 /**
259 * Described in header.
260 */
261 ike_cfg_t *ike_cfg_create(bool certreq, bool force_encap,
262 char *me, char *other)
263 {
264 private_ike_cfg_t *this = malloc_thing(private_ike_cfg_t);
265
266 /* public functions */
267 this->public.send_certreq = (bool(*)(ike_cfg_t*))send_certreq;
268 this->public.force_encap = (bool (*) (ike_cfg_t *))force_encap_meth;
269 this->public.get_my_addr = (char*(*)(ike_cfg_t*))get_my_addr;
270 this->public.get_other_addr = (char*(*)(ike_cfg_t*))get_other_addr;
271 this->public.add_proposal = (void(*)(ike_cfg_t*, proposal_t*)) add_proposal;
272 this->public.get_proposals = (linked_list_t*(*)(ike_cfg_t*))get_proposals;
273 this->public.select_proposal = (proposal_t*(*)(ike_cfg_t*,linked_list_t*))select_proposal;
274 this->public.get_dh_group = (diffie_hellman_group_t(*)(ike_cfg_t*)) get_dh_group;
275 this->public.equals = (bool(*)(ike_cfg_t*,ike_cfg_t*)) equals;
276 this->public.get_ref = (ike_cfg_t*(*)(ike_cfg_t*))get_ref;
277 this->public.destroy = (void(*)(ike_cfg_t*))destroy;
278
279 /* private variables */
280 this->refcount = 1;
281 this->certreq = certreq;
282 this->force_encap = force_encap;
283 this->me = strdup(me);
284 this->other = strdup(other);
285 this->proposals = linked_list_create();
286
287 return &this->public;
288 }