4 * @brief Implementation of connection_t.
9 * Copyright (C) 2005 Jan Hutter, Martin Willi
10 * Hochschule fuer Technik Rapperswil
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 #include "connection.h"
27 #include <utils/linked_list.h>
28 #include <utils/logger.h>
31 * String mappings for auth_method_t.
33 mapping_t auth_method_m
[] = {
34 {RSA_DIGITAL_SIGNATURE
, "RSA"},
35 {SHARED_KEY_MESSAGE_INTEGRITY_CODE
, "SHARED_KEY"},
36 {DSS_DIGITAL_SIGNATURE
, "DSS"},
41 typedef struct private_connection_t private_connection_t
;
44 * Private data of an connection_t object
46 struct private_connection_t
{
54 * Name of the connection
61 identification_t
*my_id
;
66 identification_t
*other_id
;
69 * Host information of my host.
74 * Host information of other host.
79 * Method to use for own authentication data
81 auth_method_t auth_method
;
86 linked_list_t
*proposals
;
90 * Implementation of connection_t.get_name.
92 static char *get_name (private_connection_t
*this)
98 * Implementation of connection_t.get_my_id.
100 static identification_t
*get_my_id (private_connection_t
*this)
106 * Implementation of connection_t.get_other_id.
108 static identification_t
*get_other_id(private_connection_t
*this)
110 return this->other_id
;
114 * Implementation of connection_t.update_my_id
116 static void update_my_id(private_connection_t
*this, identification_t
*my_id
)
118 this->my_id
->destroy(this->my_id
);
123 * Implementation of connection_t.update_other_id
125 static void update_other_id(private_connection_t
*this, identification_t
*other_id
)
127 this->other_id
->destroy(this->other_id
);
128 this->other_id
= other_id
;
132 * Implementation of connection_t.get_my_host.
134 static host_t
* get_my_host (private_connection_t
*this)
136 return this->my_host
;
140 * Implementation of connection_t.update_my_host.
142 static void update_my_host(private_connection_t
*this, host_t
*my_host
)
144 this->my_host
->destroy(this->my_host
);
145 this->my_host
= my_host
;
149 * Implementation of connection_t.update_other_host.
151 static void update_other_host(private_connection_t
*this, host_t
*other_host
)
153 this->other_host
->destroy(this->other_host
);
154 this->other_host
= other_host
;
158 * Implementation of connection_t.get_other_host.
160 static host_t
* get_other_host (private_connection_t
*this)
162 return this->other_host
;
166 * Implementation of connection_t.get_proposals.
168 static linked_list_t
* get_proposals (private_connection_t
*this)
170 return this->proposals
;
174 * Implementation of connection_t.select_proposal.
176 static proposal_t
*select_proposal(private_connection_t
*this, linked_list_t
*proposals
)
178 iterator_t
*stored_iter
, *supplied_iter
;
179 proposal_t
*stored
, *supplied
, *selected
;
181 stored_iter
= this->proposals
->create_iterator(this->proposals
, TRUE
);
182 supplied_iter
= proposals
->create_iterator(proposals
, TRUE
);
184 /* compare all stored proposals with all supplied. Stored ones are preferred. */
185 while (stored_iter
->has_next(stored_iter
))
187 supplied_iter
->reset(supplied_iter
);
188 stored_iter
->current(stored_iter
, (void**)&stored
);
190 while (supplied_iter
->has_next(supplied_iter
))
192 supplied_iter
->current(supplied_iter
, (void**)&supplied
);
193 selected
= stored
->select(stored
, supplied
);
196 /* they match, return */
197 stored_iter
->destroy(stored_iter
);
198 supplied_iter
->destroy(supplied_iter
);
204 /* no proposal match :-(, will result in a NO_PROPOSAL_CHOSEN... */
205 stored_iter
->destroy(stored_iter
);
206 supplied_iter
->destroy(supplied_iter
);
212 * Implementation of connection_t.add_proposal.
214 static void add_proposal (private_connection_t
*this, proposal_t
*proposal
)
216 this->proposals
->insert_last(this->proposals
, proposal
);
220 * Implementation of connection_t.auth_method_t.
222 static auth_method_t
get_auth_method(private_connection_t
*this)
224 return this->auth_method
;
228 * Implementation of connection_t.get_dh_group.
230 static diffie_hellman_group_t
get_dh_group(private_connection_t
*this)
232 iterator_t
*iterator
;
233 proposal_t
*proposal
;
236 iterator
= this->proposals
->create_iterator(this->proposals
, TRUE
);
237 while (iterator
->has_next(iterator
))
239 iterator
->current(iterator
, (void**)&proposal
);
240 proposal
->get_algorithm(proposal
, PROTO_IKE
, DIFFIE_HELLMAN_GROUP
, &algo
);
243 iterator
->destroy(iterator
);
244 return algo
->algorithm
;
247 iterator
->destroy(iterator
);
248 return MODP_UNDEFINED
;
252 * Implementation of connection_t.check_dh_group.
254 static bool check_dh_group(private_connection_t
*this, diffie_hellman_group_t dh_group
)
256 iterator_t
*prop_iter
, *alg_iter
;
257 proposal_t
*proposal
;
260 prop_iter
= this->proposals
->create_iterator(this->proposals
, TRUE
);
261 while (prop_iter
->has_next(prop_iter
))
263 prop_iter
->current(prop_iter
, (void**)&proposal
);
264 alg_iter
= proposal
->create_algorithm_iterator(proposal
, PROTO_IKE
, DIFFIE_HELLMAN_GROUP
);
265 while (alg_iter
->has_next(alg_iter
))
267 alg_iter
->current(alg_iter
, (void**)&algo
);
268 if (algo
->algorithm
== dh_group
)
270 prop_iter
->destroy(prop_iter
);
271 alg_iter
->destroy(alg_iter
);
276 prop_iter
->destroy(prop_iter
);
277 alg_iter
->destroy(alg_iter
);
282 * Implementation of connection_t.clone.
284 static connection_t
*clone(private_connection_t
*this)
286 iterator_t
*iterator
;
287 proposal_t
*proposal
;
288 private_connection_t
*clone
= (private_connection_t
*)connection_create(
290 this->my_host
->clone(this->my_host
),
291 this->other_host
->clone(this->other_host
),
292 this->my_id
->clone(this->my_id
),
293 this->other_id
->clone(this->other_id
),
296 /* clone all proposals */
297 iterator
= this->proposals
->create_iterator(this->proposals
, TRUE
);
298 while (iterator
->has_next(iterator
))
300 iterator
->current(iterator
, (void**)&proposal
);
301 proposal
= proposal
->clone(proposal
);
302 clone
->proposals
->insert_last(clone
->proposals
, (void*)proposal
);
304 iterator
->destroy(iterator
);
306 return &clone
->public;
310 * Implementation of connection_t.destroy.
312 static void destroy (private_connection_t
*this)
314 proposal_t
*proposal
;
316 while (this->proposals
->remove_last(this->proposals
, (void**)&proposal
) == SUCCESS
)
318 proposal
->destroy(proposal
);
320 this->proposals
->destroy(this->proposals
);
322 this->my_host
->destroy(this->my_host
);
323 this->other_host
->destroy(this->other_host
);
324 this->my_id
->destroy(this->my_id
);
325 this->other_id
->destroy(this->other_id
);
331 * Described in header.
333 connection_t
* connection_create(char *name
, host_t
*my_host
, host_t
*other_host
, identification_t
*my_id
, identification_t
*other_id
, auth_method_t auth_method
)
335 private_connection_t
*this = malloc_thing(private_connection_t
);
337 /* public functions */
338 this->public.get_name
= (char*(*)(connection_t
*))get_name
;
339 this->public.get_my_id
= (identification_t
*(*)(connection_t
*))get_my_id
;
340 this->public.get_other_id
= (identification_t
*(*)(connection_t
*))get_other_id
;
341 this->public.get_my_host
= (host_t
*(*)(connection_t
*))get_my_host
;
342 this->public.update_my_host
= (void(*)(connection_t
*,host_t
*))update_my_host
;
343 this->public.update_other_host
= (void(*)(connection_t
*,host_t
*))update_other_host
;
344 this->public.update_my_id
= (void(*)(connection_t
*,identification_t
*))update_my_id
;
345 this->public.update_other_id
= (void(*)(connection_t
*,identification_t
*))update_other_id
;
346 this->public.get_other_host
= (host_t
*(*)(connection_t
*))get_other_host
;
347 this->public.get_proposals
= (linked_list_t
*(*)(connection_t
*))get_proposals
;
348 this->public.select_proposal
= (proposal_t
*(*)(connection_t
*,linked_list_t
*))select_proposal
;
349 this->public.add_proposal
= (void(*)(connection_t
*, proposal_t
*)) add_proposal
;
350 this->public.get_auth_method
= (auth_method_t(*)(connection_t
*)) get_auth_method
;
351 this->public.get_dh_group
= (diffie_hellman_group_t(*)(connection_t
*)) get_dh_group
;
352 this->public.check_dh_group
= (bool(*)(connection_t
*,diffie_hellman_group_t
)) check_dh_group
;
353 this->public.clone
= (connection_t
*(*)(connection_t
*))clone
;
354 this->public.destroy
= (void(*)(connection_t
*))destroy
;
356 /* private variables */
357 this->name
= strdup(name
);
358 this->my_host
= my_host
;
359 this->other_host
= other_host
;
361 this->other_id
= other_id
;
362 this->auth_method
= auth_method
;
364 this->proposals
= linked_list_create();
366 return (&this->public);