]>
Commit | Line | Data |
---|---|---|
a2a10f25 JH |
1 | /** |
2 | * @file initiator_init.c | |
3 | * | |
4 | * @brief Start state of a IKE_SA as initiator | |
5 | * | |
6 | */ | |
7 | ||
8 | /* | |
9 | * Copyright (C) 2005 Jan Hutter, Martin Willi | |
10 | * Hochschule fuer Technik Rapperswil | |
11 | * | |
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>. | |
16 | * | |
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 | |
20 | * for more details. | |
21 | */ | |
22 | ||
23 | #include "initiator_init.h" | |
24 | ||
8323a9c1 | 25 | |
021c2322 MW |
26 | #include <globals.h> |
27 | #include <states/state.h> | |
28 | #include <states/ike_sa_init_requested.h> | |
29 | #include <utils/allocator.h> | |
30 | #include <transforms/diffie_hellman.h> | |
4a962238 MW |
31 | #include <encoding/payloads/sa_payload.h> |
32 | #include <encoding/payloads/ke_payload.h> | |
33 | #include <encoding/payloads/nonce_payload.h> | |
8323a9c1 | 34 | |
a2a10f25 JH |
35 | |
36 | /** | |
37 | * Private data of a initiator_init_t object. | |
38 | * | |
39 | */ | |
40 | typedef struct private_initiator_init_s private_initiator_init_t; | |
41 | struct private_initiator_init_s { | |
42 | /** | |
d5321650 | 43 | * Methods of the state_t interface. |
a2a10f25 JH |
44 | */ |
45 | initiator_init_t public; | |
46 | ||
8323a9c1 | 47 | /** |
d5321650 | 48 | * Assigned IKE_SA. |
8323a9c1 JH |
49 | */ |
50 | protected_ike_sa_t *ike_sa; | |
51 | ||
52 | /** | |
d5321650 JH |
53 | * Diffie hellman object used to generate public DH value. |
54 | * This objet is passed to the next state of type ike_sa_init_requested_t. | |
8323a9c1 JH |
55 | */ |
56 | diffie_hellman_t *diffie_hellman; | |
57 | ||
58 | /** | |
d5321650 | 59 | * DH group number. |
8323a9c1 JH |
60 | */ |
61 | u_int16_t dh_group_number; | |
62 | ||
63 | /** | |
d5321650 JH |
64 | * DH group priority used to get dh_group_number from configuration manager. |
65 | * This priority is passed to the next state of type ike_sa_init_requested_t. | |
8323a9c1 JH |
66 | */ |
67 | u_int16_t dh_group_priority; | |
68 | ||
69 | /** | |
d5321650 JH |
70 | * Sent nonce. |
71 | * This nonce is passed to the next state of type ike_sa_init_requested_t. | |
8323a9c1 JH |
72 | */ |
73 | chunk_t sent_nonce; | |
74 | ||
75 | /** | |
d5321650 JH |
76 | * Proposals used to initiate connection. |
77 | * | |
8323a9c1 JH |
78 | */ |
79 | linked_list_t *proposals; | |
80 | ||
81 | /** | |
d5321650 | 82 | * Logger used to log :-) |
8323a9c1 JH |
83 | * |
84 | * Is logger of ike_sa! | |
85 | */ | |
86 | logger_t *logger; | |
87 | ||
dd4e8c65 JH |
88 | /** |
89 | * Builds the IKE_SA_INIT request message. | |
90 | * | |
91 | * @param this calling object | |
92 | * @param message the created message will be stored at this location | |
93 | * @return | |
94 | * - SUCCESS | |
95 | * - OUT_OF_RES | |
96 | */ | |
97 | status_t (*build_ike_sa_init_request) (private_initiator_init_t *this, message_t **message); | |
98 | ||
d5321650 JH |
99 | /** |
100 | * Builds the SA payload for this state. | |
101 | * | |
102 | * @param this calling object | |
103 | * @param payload The generated SA payload object of type ke_payload_t is | |
104 | * stored at this location. | |
105 | * @return | |
106 | * - SUCCESS | |
107 | * - OUT_OF_RES | |
108 | */ | |
8323a9c1 | 109 | status_t (*build_sa_payload) (private_initiator_init_t *this, payload_t **payload); |
d5321650 JH |
110 | |
111 | /** | |
112 | * Builds the KE payload for this state. | |
113 | * | |
114 | * @param this calling object | |
115 | * @param payload The generated KE payload object of type ke_payload_t is | |
116 | * stored at this location. | |
117 | * @return | |
118 | * - SUCCESS | |
119 | * - OUT_OF_RES | |
120 | */ | |
8323a9c1 | 121 | status_t (*build_ke_payload) (private_initiator_init_t *this, payload_t **payload); |
d5321650 JH |
122 | /** |
123 | * Builds the NONCE payload for this state. | |
124 | * | |
125 | * @param this calling object | |
126 | * @param payload The generated NONCE payload object of type ke_payload_t is | |
127 | * stored at this location. | |
128 | * @return | |
129 | * - SUCCESS | |
130 | * - OUT_OF_RES | |
131 | */ | |
8323a9c1 JH |
132 | status_t (*build_nonce_payload) (private_initiator_init_t *this, payload_t **payload); |
133 | ||
d5321650 JH |
134 | /** |
135 | * Destroy function called internally of this class after state change succeeded. | |
136 | * | |
137 | * This destroy function does not destroy objects which were passed to the new state. | |
138 | * | |
139 | * @param this calling object | |
140 | * @return SUCCESS in any case | |
141 | */ | |
8323a9c1 | 142 | status_t (*destroy_after_state_change) (private_initiator_init_t *this); |
a2a10f25 JH |
143 | }; |
144 | ||
d5321650 JH |
145 | /** |
146 | * Implements function initiator_init_t.initiate_connection. | |
147 | */ | |
a2a10f25 JH |
148 | static status_t initiate_connection (private_initiator_init_t *this, char *name, state_t **new_state) |
149 | { | |
5d6455ba JH |
150 | linked_list_iterator_t *proposal_iterator; |
151 | ike_sa_init_requested_t *next_state; | |
d5321650 | 152 | message_t *message; |
d5321650 JH |
153 | packet_t *packet; |
154 | status_t status; | |
8323a9c1 | 155 | |
8323a9c1 JH |
156 | this->logger->log(this->logger, CONTROL, "Initializing connection %s",name); |
157 | ||
158 | status = global_configuration_manager->get_local_host(global_configuration_manager, name, &(this->ike_sa->me.host)); | |
159 | if (status != SUCCESS) | |
160 | { | |
161 | this->logger->log(this->logger, ERROR | MORE, "Could not retrieve local host configuration information for %s",name); | |
162 | return INVALID_ARG; | |
163 | } | |
164 | ||
165 | status = global_configuration_manager->get_remote_host(global_configuration_manager, name, &(this->ike_sa->other.host)); | |
166 | if (status != SUCCESS) | |
167 | { | |
168 | this->logger->log(this->logger, ERROR | MORE, "Could not retrieve remote host configuration information for %s",name); | |
169 | return INVALID_ARG; | |
170 | } | |
171 | ||
172 | status = global_configuration_manager->get_dh_group_number(global_configuration_manager, name, &(this->dh_group_number), this->dh_group_priority); | |
173 | if (status != SUCCESS) | |
174 | { | |
d5321650 | 175 | this->logger->log(this->logger, ERROR | MORE, "Could not retrieve DH group number configuration for %s",name); |
8323a9c1 JH |
176 | return INVALID_ARG; |
177 | } | |
178 | ||
179 | status = this->proposals->create_iterator(this->proposals, &proposal_iterator, FALSE); | |
180 | if (status != SUCCESS) | |
181 | { | |
182 | this->logger->log(this->logger, ERROR, "Fatal error: Could not create iterator on list for proposals"); | |
183 | return status; | |
184 | } | |
185 | ||
186 | status = global_configuration_manager->get_proposals_for_host(global_configuration_manager, this->ike_sa->other.host, proposal_iterator); | |
5d6455ba JH |
187 | /* not needed anymore */ |
188 | proposal_iterator->destroy(proposal_iterator); | |
8323a9c1 JH |
189 | if (status != SUCCESS) |
190 | { | |
191 | this->logger->log(this->logger, ERROR | MORE, "Could not retrieve Proposals for %s",name); | |
192 | return status; | |
193 | } | |
5d6455ba JH |
194 | |
195 | /* a diffie hellman object could allready exist caused by an failed initiate_connection call */ | |
dd4e8c65 JH |
196 | if (this->diffie_hellman == NULL) |
197 | { | |
198 | this ->logger->log(this->logger, CONTROL|MOST, "create diffie hellman object"); | |
199 | this->diffie_hellman = diffie_hellman_create(this->dh_group_number); | |
200 | } | |
8323a9c1 JH |
201 | |
202 | if (this->diffie_hellman == NULL) | |
203 | { | |
204 | this->logger->log(this->logger, ERROR, "Object of type diffie_hellman_t could not be created!"); | |
205 | return FAILED; | |
206 | } | |
207 | ||
dd4e8c65 JH |
208 | if (this->sent_nonce.ptr != NULL) |
209 | { | |
210 | this->logger->log(this->logger, ERROR, "Free existing sent nonce!"); | |
211 | allocator_free(this->sent_nonce.ptr); | |
5d6455ba | 212 | this->sent_nonce = CHUNK_INITIALIZER; |
dd4e8c65 | 213 | } |
d5321650 JH |
214 | |
215 | this ->logger->log(this->logger, CONTROL|MOST, "Get pseudo random bytes for nonce"); | |
8323a9c1 JH |
216 | if (this->ike_sa->randomizer->allocate_pseudo_random_bytes(this->ike_sa->randomizer, NONCE_SIZE, &(this->sent_nonce)) != SUCCESS) |
217 | { | |
218 | this->logger->log(this->logger, ERROR, "Could not create nonce!"); | |
219 | return OUT_OF_RES; | |
220 | } | |
d5321650 JH |
221 | this ->logger->log(this->logger, RAW|MOST, "Nonce",&(this->sent_nonce)); |
222 | ||
8323a9c1 | 223 | |
dd4e8c65 JH |
224 | |
225 | status = this->build_ike_sa_init_request (this,&message); | |
226 | if (status != SUCCESS) | |
227 | { | |
228 | this->logger->log(this->logger, ERROR, "Fatal error: could not build IKE_SA_INIT request message"); | |
229 | return status; | |
230 | } | |
231 | ||
232 | /* generate packet */ | |
233 | this ->logger->log(this->logger, CONTROL|MOST, "generate packet from message"); | |
234 | status = message->generate(message, &packet); | |
235 | if (status != SUCCESS) | |
236 | { | |
237 | this->logger->log(this->logger, ERROR, "Fatal error: could not generate packet from message"); | |
238 | message->destroy(message); | |
239 | return status; | |
240 | } | |
241 | ||
242 | this ->logger->log(this->logger, CONTROL|MOST, "Add packet to global send queue"); | |
243 | status = global_send_queue->add(global_send_queue, packet); | |
244 | if (status != SUCCESS) | |
245 | { | |
246 | this->logger->log(this->logger, ERROR, "Could not add packet to send queue"); | |
247 | packet->destroy(packet); | |
248 | message->destroy(message); | |
249 | return status; | |
250 | } | |
251 | ||
252 | /* state can now be changed */ | |
253 | this ->logger->log(this->logger, CONTROL|MOST, "Create next state object"); | |
254 | next_state = ike_sa_init_requested_create(this->ike_sa, this->dh_group_number, this->diffie_hellman, this->sent_nonce); | |
255 | ||
256 | if (next_state == NULL) | |
257 | { | |
258 | this ->logger->log(this->logger, ERROR, "Fatal error: could not create next state object of type ike_sa_init_requested_t"); | |
259 | return FAILED; | |
260 | } | |
261 | ||
262 | if ( this->ike_sa->last_requested_message != NULL) | |
263 | { | |
264 | /* destroy message */ | |
265 | this ->logger->log(this->logger, CONTROL|MOST, "Destroy stored last requested message"); | |
266 | this->ike_sa->last_requested_message->destroy(this->ike_sa->last_requested_message); | |
267 | } | |
268 | ||
269 | /* message is set after state create */ | |
270 | this ->logger->log(this->logger, CONTROL|MOST, "replace last requested message with current one"); | |
271 | this->ike_sa->last_requested_message = message; | |
272 | ||
273 | /* message counter can now be increased */ | |
274 | this ->logger->log(this->logger, CONTROL|MOST, "Increate message counter for outgoing messages"); | |
275 | this->ike_sa->message_id_out++; | |
276 | ||
277 | *new_state = (state_t *) next_state; | |
278 | /* state has NOW changed :-) */ | |
279 | this ->logger->log(this->logger, CONTROL|MORE, "Changed state of IKE_SA from %s to %s",mapping_find(ike_sa_state_m,INITIATOR_INIT),mapping_find(ike_sa_state_m,IKE_SA_INIT_REQUESTED) ); | |
280 | ||
281 | this ->logger->log(this->logger, CONTROL|MOST, "Destroy old sate object"); | |
282 | this->destroy_after_state_change(this); | |
283 | ||
284 | return SUCCESS; | |
285 | } | |
286 | ||
287 | /** | |
288 | * implements private_initiator_init_t.build_ike_sa_init_request | |
289 | */ | |
290 | static status_t build_ike_sa_init_request (private_initiator_init_t *this, message_t **request) | |
291 | { | |
292 | status_t status; | |
293 | payload_t *payload; | |
294 | message_t *message; | |
295 | ||
8323a9c1 | 296 | /* going to build message */ |
d5321650 | 297 | this ->logger->log(this->logger, CONTROL|MOST, "Going to build message"); |
8323a9c1 JH |
298 | status = this->ike_sa->build_message(this->ike_sa, IKE_SA_INIT, TRUE, &message); |
299 | if (status != SUCCESS) | |
300 | { | |
dd4e8c65 | 301 | this->logger->log(this->logger, ERROR, "Could not build empty message"); |
8323a9c1 JH |
302 | return status; |
303 | } | |
304 | ||
305 | /* build SA payload */ | |
306 | status = this->build_sa_payload(this, &payload); | |
307 | if (status != SUCCESS) | |
308 | { | |
309 | this->logger->log(this->logger, ERROR, "Could not build SA payload"); | |
310 | message->destroy(message); | |
311 | return status; | |
312 | } | |
313 | ||
314 | this ->logger->log(this->logger, CONTROL|MOST, "add SA payload to message"); | |
315 | status = message->add_payload(message, payload); | |
316 | if (status != SUCCESS) | |
317 | { | |
318 | this->logger->log(this->logger, ERROR, "Could not add SA payload to message"); | |
dd4e8c65 | 319 | payload->destroy(payload); |
8323a9c1 JH |
320 | message->destroy(message); |
321 | return status; | |
322 | } | |
323 | ||
8323a9c1 JH |
324 | /* build KE payload */ |
325 | status = this->build_ke_payload(this, &payload); | |
326 | if (status != SUCCESS) | |
327 | { | |
328 | this->logger->log(this->logger, ERROR, "Could not build KE payload"); | |
329 | message->destroy(message); | |
330 | return status; | |
331 | } | |
332 | ||
333 | this ->logger->log(this->logger, CONTROL|MOST, "add KE payload to message"); | |
334 | status = message->add_payload(message, payload); | |
335 | if (status != SUCCESS) | |
336 | { | |
337 | this->logger->log(this->logger, ERROR, "Could not add KE payload to message"); | |
dd4e8c65 | 338 | payload->destroy(payload); |
8323a9c1 JH |
339 | message->destroy(message); |
340 | return status; | |
341 | } | |
342 | ||
343 | /* build Nonce payload */ | |
344 | status = this->build_nonce_payload(this, &payload); | |
345 | if (status != SUCCESS) | |
346 | { | |
347 | this->logger->log(this->logger, ERROR, "Could not build NONCE payload"); | |
348 | message->destroy(message); | |
349 | return status; | |
350 | } | |
351 | ||
352 | this ->logger->log(this->logger, CONTROL|MOST, "add nonce payload to message"); | |
353 | status = message->add_payload(message, payload); | |
354 | if (status != SUCCESS) | |
355 | { | |
356 | this->logger->log(this->logger, ERROR, "Could not add nonce payload to message"); | |
dd4e8c65 | 357 | payload->destroy(payload); |
8323a9c1 JH |
358 | message->destroy(message); |
359 | return status; | |
360 | } | |
361 | ||
dd4e8c65 | 362 | *request = message; |
8323a9c1 JH |
363 | return SUCCESS; |
364 | } | |
365 | ||
366 | /** | |
367 | * implements private_initiator_init_t.build_sa_payload | |
368 | */ | |
369 | static status_t build_sa_payload(private_initiator_init_t *this, payload_t **payload) | |
370 | { | |
371 | sa_payload_t* sa_payload; | |
372 | linked_list_iterator_t *proposal_iterator; | |
373 | status_t status; | |
374 | ||
8323a9c1 JH |
375 | /* SA payload takes proposals from this->ike_sa_init_data.proposals and writes them to the created sa_payload */ |
376 | ||
377 | this->logger->log(this->logger, CONTROL|MORE, "building sa payload"); | |
8323a9c1 JH |
378 | status = this->proposals->create_iterator(this->proposals, &proposal_iterator, FALSE); |
379 | if (status != SUCCESS) | |
380 | { | |
381 | this->logger->log(this->logger, ERROR, "Fatal error: Could not create iterator on list for proposals"); | |
382 | return status; | |
383 | } | |
384 | ||
385 | sa_payload = sa_payload_create(); | |
386 | if (sa_payload == NULL) | |
387 | { | |
388 | this->logger->log(this->logger, ERROR, "Fatal error: Could not create SA payload object"); | |
389 | return OUT_OF_RES; | |
390 | } | |
391 | ||
392 | while (proposal_iterator->has_next(proposal_iterator)) | |
393 | { | |
394 | proposal_substructure_t *current_proposal; | |
395 | proposal_substructure_t *current_proposal_clone; | |
396 | status = proposal_iterator->current(proposal_iterator,(void **) ¤t_proposal); | |
397 | if (status != SUCCESS) | |
398 | { | |
399 | this->logger->log(this->logger, ERROR, "Could not get current proposal needed to copy"); | |
55f90b5d | 400 | proposal_iterator->destroy(proposal_iterator); |
8323a9c1 JH |
401 | sa_payload->destroy(sa_payload); |
402 | return status; | |
403 | } | |
404 | status = current_proposal->clone(current_proposal,¤t_proposal_clone); | |
405 | if (status != SUCCESS) | |
406 | { | |
407 | this->logger->log(this->logger, ERROR, "Could not clone current proposal"); | |
55f90b5d | 408 | proposal_iterator->destroy(proposal_iterator); |
8323a9c1 JH |
409 | sa_payload->destroy(sa_payload); |
410 | return status; | |
411 | } | |
412 | ||
413 | status = sa_payload->add_proposal_substructure(sa_payload,current_proposal_clone); | |
414 | if (status != SUCCESS) | |
415 | { | |
416 | this->logger->log(this->logger, ERROR, "Could not add cloned proposal to SA payload"); | |
55f90b5d | 417 | proposal_iterator->destroy(proposal_iterator); |
8323a9c1 JH |
418 | sa_payload->destroy(sa_payload); |
419 | return status; | |
420 | } | |
421 | ||
422 | } | |
55f90b5d | 423 | proposal_iterator->destroy(proposal_iterator); |
8323a9c1 JH |
424 | |
425 | this->logger->log(this->logger, CONTROL|MORE, "sa payload builded"); | |
d5321650 JH |
426 | |
427 | *payload = (payload_t *) sa_payload; | |
8323a9c1 JH |
428 | return SUCCESS; |
429 | } | |
430 | ||
431 | /** | |
432 | * implements private_initiator_init_t.build_ke_payload | |
433 | */ | |
434 | static status_t build_ke_payload(private_initiator_init_t *this, payload_t **payload) | |
435 | { | |
436 | ke_payload_t *ke_payload; | |
437 | chunk_t key_data; | |
438 | status_t status; | |
439 | ||
440 | this->logger->log(this->logger, CONTROL|MORE, "building ke payload"); | |
441 | ||
442 | ||
443 | this ->logger->log(this->logger, CONTROL|MORE, "get public dh value to send in ke payload"); | |
444 | status = this->diffie_hellman->get_my_public_value(this->diffie_hellman,&key_data); | |
445 | if (status != SUCCESS) | |
446 | { | |
447 | this->logger->log(this->logger, ERROR, "Could not get my DH public value"); | |
448 | return status; | |
449 | } | |
450 | ||
451 | ke_payload = ke_payload_create(); | |
452 | if (ke_payload == NULL) | |
453 | { | |
454 | this->logger->log(this->logger, ERROR, "Could not create KE payload"); | |
455 | allocator_free_chunk(key_data); | |
456 | return OUT_OF_RES; | |
457 | } | |
5d6455ba | 458 | ke_payload->set_dh_group_number(ke_payload, this->dh_group_number); |
8323a9c1 JH |
459 | if (ke_payload->set_key_exchange_data(ke_payload, key_data) != SUCCESS) |
460 | { | |
461 | this->logger->log(this->logger, ERROR, "Could not set key exchange data of KE payload"); | |
462 | ke_payload->destroy(ke_payload); | |
463 | allocator_free_chunk(key_data); | |
464 | return OUT_OF_RES; | |
465 | } | |
466 | allocator_free_chunk(key_data); | |
d5321650 JH |
467 | |
468 | this->logger->log(this->logger, CONTROL|MORE, "ke payload builded"); | |
8323a9c1 JH |
469 | |
470 | *payload = (payload_t *) ke_payload; | |
471 | return SUCCESS; | |
472 | } | |
473 | ||
474 | /** | |
475 | * implements private_initiator_init_t.build_nonce_payload | |
476 | */ | |
477 | static status_t build_nonce_payload(private_initiator_init_t *this, payload_t **payload) | |
478 | { | |
479 | nonce_payload_t *nonce_payload; | |
480 | status_t status; | |
481 | ||
482 | this->logger->log(this->logger, CONTROL|MORE, "building nonce payload"); | |
483 | ||
484 | nonce_payload = nonce_payload_create(); | |
485 | if (nonce_payload == NULL) | |
486 | { | |
487 | this->logger->log(this->logger, ERROR, "Fatal error: could not create nonce payload object"); | |
488 | return OUT_OF_RES; | |
489 | } | |
490 | ||
491 | status = nonce_payload->set_nonce(nonce_payload, this->sent_nonce); | |
492 | ||
493 | if (status != SUCCESS) | |
494 | { | |
495 | this->logger->log(this->logger, ERROR, "Fatal error: could not set nonce data of payload"); | |
496 | nonce_payload->destroy(nonce_payload); | |
497 | return status; | |
498 | } | |
499 | ||
500 | *payload = (payload_t *) nonce_payload; | |
501 | ||
d5321650 JH |
502 | this->logger->log(this->logger, CONTROL|MORE, "nonce payload builded"); |
503 | ||
a2a10f25 JH |
504 | return SUCCESS; |
505 | } | |
506 | ||
507 | /** | |
508 | * Implements state_t.get_state | |
509 | */ | |
510 | static status_t process_message(private_initiator_init_t *this, message_t *message, state_t **new_state) | |
511 | { | |
512 | *new_state = (state_t *) this; | |
d5321650 | 513 | this->logger->log(this->logger, ERROR|MORE, "In state INITIATOR_INIT no message is processed"); |
a2a10f25 JH |
514 | return FAILED; |
515 | } | |
516 | ||
517 | /** | |
518 | * Implements state_t.get_state | |
519 | */ | |
520 | static ike_sa_state_t get_state(private_initiator_init_t *this) | |
521 | { | |
522 | return INITIATOR_INIT; | |
523 | } | |
524 | ||
525 | /** | |
526 | * Implements state_t.get_state | |
527 | */ | |
528 | static status_t destroy(private_initiator_init_t *this) | |
529 | { | |
d5321650 JH |
530 | this->logger->log(this->logger, CONTROL | MORE, "Going to destroy initiator_init_t state object"); |
531 | ||
8323a9c1 JH |
532 | /* destroy stored proposal */ |
533 | this->logger->log(this->logger, CONTROL | MOST, "Destroy stored proposals"); | |
534 | while (this->proposals->get_count(this->proposals) > 0) | |
535 | { | |
536 | proposal_substructure_t *current_proposal; | |
537 | this->proposals->remove_first(this->proposals,(void **)¤t_proposal); | |
538 | current_proposal->destroy(current_proposal); | |
539 | } | |
540 | this->proposals->destroy(this->proposals); | |
541 | ||
542 | /* destroy diffie hellman object */ | |
543 | if (this->diffie_hellman != NULL) | |
544 | { | |
545 | this->logger->log(this->logger, CONTROL | MOST, "Destroy diffie_hellman_t object"); | |
546 | this->diffie_hellman->destroy(this->diffie_hellman); | |
547 | } | |
dd4e8c65 JH |
548 | if (this->sent_nonce.ptr != NULL) |
549 | { | |
550 | this->logger->log(this->logger, CONTROL | MOST, "Free memory of sent nonce"); | |
551 | allocator_free(this->sent_nonce.ptr); | |
552 | } | |
8323a9c1 JH |
553 | |
554 | allocator_free(this); | |
555 | return SUCCESS; | |
556 | } | |
557 | ||
558 | /** | |
559 | * Implements private_initiator_init_t.destroy_after_state_change | |
560 | */ | |
561 | static status_t destroy_after_state_change (private_initiator_init_t *this) | |
562 | { | |
d5321650 JH |
563 | this->logger->log(this->logger, CONTROL | MORE, "Going to destroy initiator_init_t state object"); |
564 | ||
8323a9c1 JH |
565 | /* destroy stored proposal */ |
566 | this->logger->log(this->logger, CONTROL | MOST, "Destroy stored proposals"); | |
567 | while (this->proposals->get_count(this->proposals) > 0) | |
568 | { | |
569 | proposal_substructure_t *current_proposal; | |
570 | this->proposals->remove_first(this->proposals,(void **)¤t_proposal); | |
571 | current_proposal->destroy(current_proposal); | |
572 | } | |
573 | this->proposals->destroy(this->proposals); | |
a2a10f25 JH |
574 | allocator_free(this); |
575 | return SUCCESS; | |
576 | } | |
577 | ||
578 | /* | |
579 | * Described in header. | |
580 | */ | |
8323a9c1 | 581 | initiator_init_t *initiator_init_create(protected_ike_sa_t *ike_sa) |
a2a10f25 JH |
582 | { |
583 | private_initiator_init_t *this = allocator_alloc_thing(private_initiator_init_t); | |
584 | ||
585 | if (this == NULL) | |
586 | { | |
587 | return NULL; | |
588 | } | |
589 | ||
590 | /* interface functions */ | |
591 | this->public.state_interface.process_message = (status_t (*) (state_t *,message_t *,state_t **)) process_message; | |
592 | this->public.state_interface.get_state = (ike_sa_state_t (*) (state_t *)) get_state; | |
593 | this->public.state_interface.destroy = (status_t (*) (state_t *)) destroy; | |
594 | ||
595 | /* public functions */ | |
596 | this->public.initiate_connection = (status_t (*)(initiator_init_t *, char *, state_t **)) initiate_connection; | |
597 | ||
8323a9c1 | 598 | /* private functions */ |
d5321650 | 599 | this->destroy_after_state_change = destroy_after_state_change; |
dd4e8c65 | 600 | this->build_ike_sa_init_request = build_ike_sa_init_request; |
d5321650 | 601 | this->build_nonce_payload = build_nonce_payload; |
8323a9c1 JH |
602 | this->build_sa_payload = build_sa_payload; |
603 | this->build_ke_payload = build_ke_payload; | |
8323a9c1 JH |
604 | |
605 | /* private data */ | |
606 | this->ike_sa = ike_sa; | |
8323a9c1 | 607 | this->dh_group_priority = 1; |
d5321650 | 608 | this->logger = this->ike_sa->logger; |
8323a9c1 | 609 | this->proposals = linked_list_create(); |
5d6455ba | 610 | this->sent_nonce = CHUNK_INITIALIZER; |
8323a9c1 JH |
611 | if (this->proposals == NULL) |
612 | { | |
613 | allocator_free(this); | |
614 | return NULL; | |
615 | } | |
616 | ||
a2a10f25 JH |
617 | return &(this->public); |
618 | } |