- configuration_manager replaced by configuration_t interface
[strongswan.git] / Source / charon / config / starter_configuration.c
1 /**
2 * @file starter_configuration.c
3 *
4 * @brief Implementation of starter_configuration_t.
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 <stdlib.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <sys/socket.h>
27 #include <sys/un.h>
28 #include <sys/fcntl.h>
29 #include <unistd.h>
30 #include <errno.h>
31 #include <pthread.h>
32
33 #include "starter_configuration.h"
34
35 #include <types.h>
36 #include <daemon.h>
37 #include <utils/allocator.h>
38
39
40 /**
41 * First retransmit timeout in milliseconds.
42 *
43 * Timeout value is increasing in each retransmit round.
44 */
45 #define RETRANSMIT_TIMEOUT 3000
46
47 /**
48 * Timeout in milliseconds after that a half open IKE_SA gets deleted.
49 */
50 #define HALF_OPEN_IKE_SA_TIMEOUT 30000
51
52 /**
53 * Max retransmit count.
54 * 0 for infinite. The max time a half open IKE_SA is alive is set by
55 * RETRANSMIT_TIMEOUT.
56 */
57 #define MAX_RETRANSMIT_COUNT 0
58
59
60 struct sockaddr_un socket_addr = { AF_UNIX, "/var/run/pluto.ctl"};
61
62
63 typedef struct preshared_secret_entry_t preshared_secret_entry_t;
64
65 /**
66 * A preshared secret entry combines an identifier and a
67 * preshared secret.
68 */
69 struct preshared_secret_entry_t {
70
71 /**
72 * Identification.
73 */
74 identification_t *identification;
75
76 /**
77 * Preshared secret as chunk_t. The NULL termination is not included.
78 */
79 chunk_t preshared_secret;
80 };
81
82
83 typedef struct rsa_private_key_entry_t rsa_private_key_entry_t;
84
85 /**
86 * Entry for a rsa private key.
87 */
88 struct rsa_private_key_entry_t {
89
90 /**
91 * Identification.
92 */
93 identification_t *identification;
94
95 /**
96 * Private key.
97 */
98 rsa_private_key_t* private_key;
99 };
100
101 typedef struct rsa_public_key_entry_t rsa_public_key_entry_t;
102
103 /**
104 * Entry for a rsa private key.
105 */
106 struct rsa_public_key_entry_t {
107
108 /**
109 * Identification.
110 */
111 identification_t *identification;
112
113 /**
114 * Private key.
115 */
116 rsa_public_key_t* public_key;
117 };
118
119 typedef struct configuration_entry_t configuration_entry_t;
120
121 /**
122 * A configuration entry combines a configuration name with a init and sa
123 * configuration represented as init_config_t and sa_config_t objects.
124 *
125 * @b Constructors:
126 * - configuration_entry_create()
127 */
128 struct configuration_entry_t {
129
130 /**
131 * Configuration name.
132 *
133 */
134 char *name;
135
136 /**
137 * Configuration for IKE_SA_INIT exchange.
138 */
139 init_config_t *init_config;
140
141 /**
142 * Configuration for all phases after IKE_SA_INIT exchange.
143 */
144 sa_config_t *sa_config;
145
146 /**
147 * Destroys a configuration_entry_t
148 *
149 * @param this calling object
150 */
151 void (*destroy) (configuration_entry_t *this);
152 };
153
154 /**
155 * Implementation of configuration_entry_t.destroy.
156 */
157 static void configuration_entry_destroy (configuration_entry_t *this)
158 {
159 allocator_free(this->name);
160 allocator_free(this);
161 }
162
163 /**
164 * @brief Creates a configuration_entry_t object.
165 *
166 * @param name name of the configuration entry (gets copied)
167 * @param init_config object of type init_config_t
168 * @param sa_config object of type sa_config_t
169 */
170 static configuration_entry_t * configuration_entry_create(char * name, init_config_t * init_config, sa_config_t * sa_config)
171 {
172 configuration_entry_t *entry = allocator_alloc_thing(configuration_entry_t);
173
174 /* functions */
175 entry->destroy = configuration_entry_destroy;
176
177 /* private data */
178 entry->init_config = init_config;
179 entry->sa_config = sa_config;
180 entry->name = allocator_alloc(strlen(name) + 1);
181 strcpy(entry->name,name);
182 return entry;
183 }
184
185 typedef struct private_starter_configuration_t private_starter_configuration_t;
186
187 /**
188 * Private data of an starter_configuration_t object.
189 */
190 struct private_starter_configuration_t {
191
192 /**
193 * Public part of starter_configuration_t object.
194 */
195 starter_configuration_t public;
196
197 /**
198 * Holding all configurations.
199 */
200 linked_list_t *configurations;
201
202 /**
203 * Holding all managed init_configs.
204 */
205 linked_list_t *init_configs;
206
207 /**
208 * Holding all managed init_configs.
209 */
210 linked_list_t *sa_configs;
211
212 /**
213 * Holding all managed preshared secrets.
214 */
215 linked_list_t *preshared_secrets;
216
217 /**
218 * Holding all managed private secrets.
219 */
220 linked_list_t *rsa_private_keys;
221
222 /**
223 * Holding all managed public secrets.
224 */
225 linked_list_t *rsa_public_keys;
226
227 /**
228 * Assigned logger_t object.
229 */
230 logger_t *logger;
231
232 /**
233 * Max number of requests to be retransmitted.
234 * 0 for infinite.
235 */
236 u_int32_t max_retransmit_count;
237
238 /**
239 * First retransmit timeout in ms.
240 */
241 u_int32_t first_retransmit_timeout;
242
243 /**
244 * Timeout in ms after that time a IKE_SA gets deleted.
245 */
246 u_int32_t half_open_ike_sa_timeout;
247
248 int socket;
249
250 pthread_t assigned_thread;
251
252 /**
253 * Adds a new IKE_SA configuration.
254 *
255 * @param this calling object
256 * @param name name for the configuration
257 * @param init_config init_config_t object
258 * @param sa_config sa_config_t object
259 */
260 void (*add_new_configuration) (private_starter_configuration_t *this, char *name, init_config_t *init_config, sa_config_t *sa_config);
261
262 /**
263 * Adds a new preshared secret.
264 *
265 * @param this calling object
266 * @param type type of identification
267 * @param id_string identification as string
268 * @param preshared_secret preshared secret as string
269 */
270 void (*add_new_preshared_secret) (private_starter_configuration_t *this,id_type_t type, char *id_string, char *preshared_secret);
271
272 /**
273 * Adds a new rsa private key.
274 *
275 * @param this calling object
276 * @param type type of identification
277 * @param id_string identification as string
278 * @param key_pos location of key
279 * @param key_len length of key
280 */
281 void (*add_new_rsa_private_key) (private_starter_configuration_t *this,id_type_t type, char *id_string, u_int8_t *key_pos, size_t key_len);
282
283 /**
284 * Adds a new rsa public key.
285 *
286 * @param this calling object
287 * @param type type of identification
288 * @param id_string identification as string
289 * @param key_pos location of key
290 * @param key_len length of key
291 */
292 void (*add_new_rsa_public_key) (private_starter_configuration_t *this,id_type_t type, char *id_string, u_int8_t *key_pos, size_t key_len);
293
294 void (*whack_receive) (private_starter_configuration_t *this);
295 };
296
297 /**
298 * Implementation of private_starter_configuration_t.listen.
299 */
300 static void whack_receive(private_starter_configuration_t *this)
301 {
302 u_int8_t buffer[5000];
303 struct sockaddr_un whackaddr;
304 int whackaddrlen = sizeof(whackaddr);
305 ssize_t n;
306 int whackfd;
307
308 while (1)
309 {
310 whackfd = accept(this->socket, (struct sockaddr *)&whackaddr, &whackaddrlen);
311
312 if (whackfd < 0)
313 {
314 this->logger->log(this->logger, ERROR, "accept() failed in whack_handle()");
315 continue;
316 }
317 if (fcntl(whackfd, F_SETFD, FD_CLOEXEC) < 0)
318 {
319 this->logger->log(this->logger, ERROR, "failed to set CLOEXEC in whack_handle()");
320 close(whackfd);
321 continue;
322 }
323
324 n = read(whackfd, &buffer, sizeof(buffer));
325
326 if (n == -1)
327 {
328 this->logger->log(this->logger, ERROR, "read() failed in whack_handle()");
329 close(whackfd);
330 continue;
331 }
332 this->logger->log_bytes(this->logger, CONTROL, "Whackinput", buffer, n);
333 }
334 }
335
336
337 /**
338 * Implementation of starter_configuration_t.get_init_config_for_host.
339 */
340 static status_t get_init_config_for_host (private_starter_configuration_t *this, host_t *my_host, host_t *other_host,init_config_t **init_config)
341 {
342 iterator_t *iterator;
343 status_t status = NOT_FOUND;
344
345 iterator = this->configurations->create_iterator(this->configurations,TRUE);
346
347 this->logger->log(this->logger, CONTROL|LEVEL1, "getting config for hosts %s - %s",
348 my_host->get_address(my_host), other_host->get_address(other_host));
349
350 while (iterator->has_next(iterator))
351 {
352 configuration_entry_t *entry;
353 host_t *config_my_host;
354 host_t *config_other_host;
355
356 iterator->current(iterator,(void **) &entry);
357
358 config_my_host = entry->init_config->get_my_host(entry->init_config);
359 config_other_host = entry->init_config->get_other_host(entry->init_config);
360
361 /* first check if ip is equal */
362 if(config_other_host->ip_is_equal(config_other_host,other_host))
363 {
364 this->logger->log(this->logger, CONTROL|LEVEL2, "config entry with remote host %s",
365 config_other_host->get_address(config_other_host));
366 /* could be right one, check my_host for default route*/
367 if (config_my_host->is_default_route(config_my_host))
368 {
369 *init_config = entry->init_config;
370 status = SUCCESS;
371 break;
372 }
373 /* check now if host informations are the same */
374 else if (config_my_host->ip_is_equal(config_my_host,my_host))
375 {
376 *init_config = entry->init_config;
377 status = SUCCESS;
378 break;
379 }
380
381 }
382 /* Then check for wildcard hosts!
383 * TODO
384 * actually its only checked if other host with default route can be found! */
385 else if (config_other_host->is_default_route(config_other_host))
386 {
387 /* could be right one, check my_host for default route*/
388 if (config_my_host->is_default_route(config_my_host))
389 {
390 *init_config = entry->init_config;
391 status = SUCCESS;
392 break;
393 }
394 /* check now if host informations are the same */
395 else if (config_my_host->ip_is_equal(config_my_host,my_host))
396 {
397 *init_config = entry->init_config;
398 status = SUCCESS;
399 break;
400 }
401 }
402 }
403
404 iterator->destroy(iterator);
405
406 return status;
407 }
408
409 /**
410 * Implementation of starter_configuration_t.get_init_config_for_name.
411 */
412 static status_t get_init_config_for_name (private_starter_configuration_t *this, char *name, init_config_t **init_config)
413 {
414 iterator_t *iterator;
415 status_t status = NOT_FOUND;
416
417 iterator = this->configurations->create_iterator(this->configurations,TRUE);
418
419 while (iterator->has_next(iterator))
420 {
421 configuration_entry_t *entry;
422 iterator->current(iterator,(void **) &entry);
423
424 if (strcmp(entry->name,name) == 0)
425 {
426
427 /* found configuration */
428 *init_config = entry->init_config;
429 status = SUCCESS;
430 break;
431 }
432 }
433
434 iterator->destroy(iterator);
435
436 return status;
437 }
438
439 /**
440 * Implementation of starter_configuration_t.get_sa_config_for_name.
441 */
442 static status_t get_sa_config_for_name (private_starter_configuration_t *this, char *name, sa_config_t **sa_config)
443 {
444 iterator_t *iterator;
445 status_t status = NOT_FOUND;
446
447 iterator = this->configurations->create_iterator(this->configurations,TRUE);
448
449 while (iterator->has_next(iterator))
450 {
451 configuration_entry_t *entry;
452 iterator->current(iterator,(void **) &entry);
453
454 if (strcmp(entry->name,name) == 0)
455 {
456 /* found configuration */
457 *sa_config = entry->sa_config;
458 status = SUCCESS;
459 break;
460 }
461 }
462
463 iterator->destroy(iterator);
464
465 return status;
466 }
467
468 /**
469 * Implementation of starter_configuration_t.get_sa_config_for_init_config_and_id.
470 */
471 static status_t get_sa_config_for_init_config_and_id (private_starter_configuration_t *this, init_config_t *init_config, identification_t *other_id, identification_t *my_id,sa_config_t **sa_config)
472 {
473 iterator_t *iterator;
474 status_t status = NOT_FOUND;
475
476 iterator = this->configurations->create_iterator(this->configurations,TRUE);
477
478 while (iterator->has_next(iterator))
479 {
480 configuration_entry_t *entry;
481 iterator->current(iterator,(void **) &entry);
482
483 if (entry->init_config == init_config)
484 {
485 identification_t *config_my_id = entry->sa_config->get_my_id(entry->sa_config);
486 identification_t *config_other_id = entry->sa_config->get_other_id(entry->sa_config);
487
488 /* host informations seem to be the same */
489 if (config_other_id->equals(config_other_id,other_id))
490 {
491 /* other ids seems to match */
492
493 if (my_id == NULL)
494 {
495 /* first matching one is selected */
496
497 /* TODO priorize found entries */
498 *sa_config = entry->sa_config;
499 status = SUCCESS;
500 break;
501 }
502
503 if (config_my_id->equals(config_my_id,my_id))
504 {
505 *sa_config = entry->sa_config;
506 status = SUCCESS;
507 break;
508 }
509
510 }
511 }
512 }
513
514 iterator->destroy(iterator);
515
516 return status;
517 }
518
519 /**
520 * Implementation of private_starter_configuration_t.add_new_configuration.
521 */
522 static void add_new_configuration (private_starter_configuration_t *this, char *name, init_config_t *init_config, sa_config_t *sa_config)
523 {
524 iterator_t *iterator;
525 bool found;
526
527 iterator = this->init_configs->create_iterator(this->init_configs,TRUE);
528 found = FALSE;
529 while (iterator->has_next(iterator))
530 {
531 init_config_t *found_init_config;
532 iterator->current(iterator,(void **) &found_init_config);
533 if (init_config == found_init_config)
534 {
535 found = TRUE;
536 break;
537 }
538 }
539 iterator->destroy(iterator);
540 if (!found)
541 {
542 this->init_configs->insert_first(this->init_configs,init_config);
543 }
544
545 iterator = this->sa_configs->create_iterator(this->sa_configs,TRUE);
546 found = FALSE;
547 while (iterator->has_next(iterator))
548 {
549 sa_config_t *found_sa_config;
550 iterator->current(iterator,(void **) &found_sa_config);
551 if (sa_config == found_sa_config)
552 {
553 found = TRUE;
554 break;
555 }
556 }
557 iterator->destroy(iterator);
558 if (!found)
559 {
560 this->sa_configs->insert_first(this->sa_configs,sa_config);
561 }
562
563 this->configurations->insert_last(this->configurations,configuration_entry_create(name,init_config,sa_config));
564 }
565
566 /**
567 * Implementation of private_starter_configuration_t.add_new_preshared_secret.
568 */
569 static void add_new_preshared_secret (private_starter_configuration_t *this,id_type_t type, char *id_string, char *preshared_secret)
570 {
571 preshared_secret_entry_t *entry = allocator_alloc_thing(preshared_secret_entry_t);
572
573 entry->identification = identification_create_from_string(type,id_string);
574 entry->preshared_secret.len = strlen(preshared_secret) + 1;
575 entry->preshared_secret.ptr = allocator_alloc(entry->preshared_secret.len);
576 memcpy(entry->preshared_secret.ptr,preshared_secret,entry->preshared_secret.len);
577
578 this->preshared_secrets->insert_last(this->preshared_secrets,entry);
579 }
580
581 /**
582 * Implementation of private_starter_configuration_t.add_new_preshared_secret.
583 */
584 static void add_new_rsa_public_key (private_starter_configuration_t *this, id_type_t type, char *id_string, u_int8_t* key_pos, size_t key_len)
585 {
586 chunk_t key;
587 key.ptr = key_pos;
588 key.len = key_len;
589
590 rsa_public_key_entry_t *entry = allocator_alloc_thing(rsa_public_key_entry_t);
591
592 entry->identification = identification_create_from_string(type,id_string);
593 entry->public_key = rsa_public_key_create();
594 entry->public_key->set_key(entry->public_key, key);
595
596 this->rsa_public_keys->insert_last(this->rsa_public_keys, entry);
597 }
598
599 /**
600 * Implementation of private_starter_configuration_t.add_new_preshared_secret.
601 */
602 static void add_new_rsa_private_key (private_starter_configuration_t *this, id_type_t type, char *id_string, u_int8_t* key_pos, size_t key_len)
603 {
604 chunk_t key;
605 key.ptr = key_pos;
606 key.len = key_len;
607
608 rsa_private_key_entry_t *entry = allocator_alloc_thing(rsa_private_key_entry_t);
609
610 entry->identification = identification_create_from_string(type,id_string);
611 entry->private_key = rsa_private_key_create();
612 entry->private_key->set_key(entry->private_key, key);
613
614 this->rsa_private_keys->insert_last(this->rsa_private_keys, entry);
615 }
616
617 /**
618 * Implementation of starter_configuration_t.get_shared_secret.
619 */
620 static status_t get_shared_secret(private_starter_configuration_t *this, identification_t *identification, chunk_t *preshared_secret)
621 {
622 iterator_t *iterator;
623
624 iterator = this->preshared_secrets->create_iterator(this->preshared_secrets,TRUE);
625 while (iterator->has_next(iterator))
626 {
627 preshared_secret_entry_t *entry;
628 iterator->current(iterator,(void **) &entry);
629 if (entry->identification->equals(entry->identification,identification))
630 {
631 *preshared_secret = entry->preshared_secret;
632 iterator->destroy(iterator);
633 return SUCCESS;
634 }
635 }
636 iterator->destroy(iterator);
637 return NOT_FOUND;
638 }
639
640 /**
641 * Implementation of starter_configuration_t.get_shared_secret.
642 */
643 static status_t get_rsa_public_key(private_starter_configuration_t *this, identification_t *identification, rsa_public_key_t **public_key)
644 {
645 iterator_t *iterator;
646
647 iterator = this->rsa_public_keys->create_iterator(this->rsa_public_keys,TRUE);
648 while (iterator->has_next(iterator))
649 {
650 rsa_public_key_entry_t *entry;
651 iterator->current(iterator,(void **) &entry);
652 if (entry->identification->equals(entry->identification,identification))
653 {
654 *public_key = entry->public_key;
655 iterator->destroy(iterator);
656 return SUCCESS;
657 }
658 }
659 iterator->destroy(iterator);
660 return NOT_FOUND;
661 }
662
663 /**
664 * Implementation of starter_configuration_t.get_shared_secret.
665 */
666 static status_t get_rsa_private_key(private_starter_configuration_t *this, identification_t *identification, rsa_private_key_t **private_key)
667 {
668 iterator_t *iterator;
669
670 iterator = this->rsa_private_keys->create_iterator(this->rsa_private_keys,TRUE);
671 while (iterator->has_next(iterator))
672 {
673 rsa_private_key_entry_t *entry;
674 iterator->current(iterator,(void **) &entry);
675 if (entry->identification->equals(entry->identification,identification))
676 {
677 *private_key = entry->private_key;
678 iterator->destroy(iterator);
679 return SUCCESS;
680 }
681 }
682 iterator->destroy(iterator);
683 return NOT_FOUND;
684 }
685
686 /**
687 * Implementation of starter_configuration_t.get_retransmit_timeout.
688 */
689 static status_t get_retransmit_timeout (private_starter_configuration_t *this, u_int32_t retransmit_count, u_int32_t *timeout)
690 {
691 int new_timeout = this->first_retransmit_timeout, i;
692 if ((retransmit_count > this->max_retransmit_count) && (this->max_retransmit_count != 0))
693 {
694 return FAILED;
695 }
696
697
698 for (i = 0; i < retransmit_count; i++)
699 {
700 new_timeout *= 2;
701 }
702
703 *timeout = new_timeout;
704
705 return SUCCESS;
706 }
707
708 /**
709 * Implementation of starter_configuration_t.get_half_open_ike_sa_timeout.
710 */
711 static u_int32_t get_half_open_ike_sa_timeout (private_starter_configuration_t *this)
712 {
713 return this->half_open_ike_sa_timeout;
714 }
715
716 /**
717 * Implementation of starter_configuration_t.destroy.
718 */
719 static void destroy(private_starter_configuration_t *this)
720 {
721 this->logger->log(this->logger,CONTROL | LEVEL1, "Going to destroy configuration backend ");
722
723 this->logger->log(this->logger,CONTROL | LEVEL2, "Destroy configuration entries");
724 while (this->configurations->get_count(this->configurations) > 0)
725 {
726 configuration_entry_t *entry;
727 this->configurations->remove_first(this->configurations,(void **) &entry);
728 entry->destroy(entry);
729 }
730 this->configurations->destroy(this->configurations);
731
732 this->logger->log(this->logger,CONTROL | LEVEL2, "Destroy sa_config_t objects");
733 while (this->sa_configs->get_count(this->sa_configs) > 0)
734 {
735 sa_config_t *sa_config;
736 this->sa_configs->remove_first(this->sa_configs,(void **) &sa_config);
737 sa_config->destroy(sa_config);
738 }
739
740 this->sa_configs->destroy(this->sa_configs);
741
742 this->logger->log(this->logger,CONTROL | LEVEL2, "Destroy init_config_t objects");
743 while (this->init_configs->get_count(this->init_configs) > 0)
744 {
745 init_config_t *init_config;
746 this->init_configs->remove_first(this->init_configs,(void **) &init_config);
747 init_config->destroy(init_config);
748 }
749 this->init_configs->destroy(this->init_configs);
750
751 while (this->preshared_secrets->get_count(this->preshared_secrets) > 0)
752 {
753 preshared_secret_entry_t *entry;
754 this->preshared_secrets->remove_first(this->preshared_secrets,(void **) &entry);
755 entry->identification->destroy(entry->identification);
756 allocator_free_chunk(&(entry->preshared_secret));
757 allocator_free(entry);
758 }
759 this->preshared_secrets->destroy(this->preshared_secrets);
760
761 this->logger->log(this->logger,CONTROL | LEVEL2, "Destroy rsa private keys");
762 while (this->rsa_private_keys->get_count(this->rsa_private_keys) > 0)
763 {
764 rsa_private_key_entry_t *entry;
765 this->rsa_private_keys->remove_first(this->rsa_private_keys,(void **) &entry);
766 entry->identification->destroy(entry->identification);
767 entry->private_key->destroy(entry->private_key);
768 allocator_free(entry);
769 }
770 this->rsa_private_keys->destroy(this->rsa_private_keys);
771
772 this->logger->log(this->logger,CONTROL | LEVEL2, "Destroy rsa public keys");
773 while (this->rsa_public_keys->get_count(this->rsa_public_keys) > 0)
774 {
775 rsa_public_key_entry_t *entry;
776 this->rsa_public_keys->remove_first(this->rsa_public_keys,(void **) &entry);
777 entry->identification->destroy(entry->identification);
778 entry->public_key->destroy(entry->public_key);
779 allocator_free(entry);
780 }
781 this->rsa_public_keys->destroy(this->rsa_public_keys);
782
783 this->logger->log(this->logger,CONTROL | LEVEL2, "Destroy assigned logger");
784 charon->logger_manager->destroy_logger(charon->logger_manager,this->logger);
785 close(this->socket);
786 unlink(socket_addr.sun_path);
787 allocator_free(this);
788 }
789
790 /*
791 * Described in header-file
792 */
793 starter_configuration_t *starter_configuration_create()
794 {
795 private_starter_configuration_t *this = allocator_alloc_thing(private_starter_configuration_t);
796 mode_t old;
797 bool on = TRUE;
798
799 /* public functions */
800 this->public.configuration_interface.destroy = (void(*)(configuration_t*))destroy;
801 this->public.configuration_interface.get_init_config_for_name = (status_t (*) (configuration_t *, char *, init_config_t **)) get_init_config_for_name;
802 this->public.configuration_interface.get_init_config_for_host = (status_t (*) (configuration_t *, host_t *, host_t *,init_config_t **)) get_init_config_for_host;
803 this->public.configuration_interface.get_sa_config_for_name =(status_t (*) (configuration_t *, char *, sa_config_t **)) get_sa_config_for_name;
804 this->public.configuration_interface.get_sa_config_for_init_config_and_id =(status_t (*) (configuration_t *, init_config_t *, identification_t *, identification_t *,sa_config_t **)) get_sa_config_for_init_config_and_id;
805 this->public.configuration_interface.get_retransmit_timeout = (status_t (*) (configuration_t *, u_int32_t retransmit_count, u_int32_t *timeout))get_retransmit_timeout;
806 this->public.configuration_interface.get_half_open_ike_sa_timeout = (u_int32_t (*) (configuration_t *)) get_half_open_ike_sa_timeout;
807 this->public.configuration_interface.get_shared_secret = (status_t (*) (configuration_t *, identification_t *, chunk_t *))get_shared_secret;
808 this->public.configuration_interface.get_rsa_private_key = (status_t (*) (configuration_t *, identification_t *, rsa_private_key_t**))get_rsa_private_key;
809 this->public.configuration_interface.get_rsa_public_key = (status_t (*) (configuration_t *, identification_t *, rsa_public_key_t**))get_rsa_public_key;
810
811 /* private functions */
812 this->add_new_configuration = add_new_configuration;
813 this->add_new_preshared_secret = add_new_preshared_secret;
814 this->add_new_rsa_public_key = add_new_rsa_public_key;
815 this->add_new_rsa_private_key = add_new_rsa_private_key;
816 this->whack_receive = whack_receive;
817
818 this->logger = charon->logger_manager->create_logger(charon->logger_manager,CONFIG,NULL);
819
820 /* set up unix socket */
821 this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
822 if (this->socket == -1)
823 {
824 this->logger->log(this->logger, ERROR, "could not create whack socket");
825 charon->logger_manager->destroy_logger(charon->logger_manager,this->logger);
826 allocator_free(this);
827 return NULL;
828 }
829 if (fcntl(this->socket, F_SETFD, FD_CLOEXEC) < 0)
830 {
831 this->logger->log(this->logger, ERROR, "could not FD_CLOEXEC on whack socket");
832 charon->logger_manager->destroy_logger(charon->logger_manager,this->logger);
833 close(this->socket);
834 allocator_free(this);
835 return NULL;
836 }
837 if (setsockopt(this->socket, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, sizeof(on)) < 0)
838
839 old = umask(~S_IRWXU);
840 if (bind(this->socket, (struct sockaddr *)&socket_addr, sizeof(socket_addr)) < 0)
841 {
842 this->logger->log(this->logger, ERROR, "could not bind whack socket: %s", strerror(errno));
843 charon->logger_manager->destroy_logger(charon->logger_manager,this->logger);
844 close(this->socket);
845 allocator_free(this);
846 return NULL;
847 }
848 umask(old);
849
850 if (listen(this->socket, 0) < 0)
851 {
852 this->logger->log(this->logger, ERROR, "could not listen on whack socket: %s", strerror(errno));
853 charon->logger_manager->destroy_logger(charon->logger_manager,this->logger);
854 close(this->socket);
855 unlink(socket_addr.sun_path);
856 allocator_free(this);
857 return NULL;
858 }
859
860 /* start a thread reading from the socket */
861 if (pthread_create(&(this->assigned_thread), NULL, (void*(*)(void*))this->whack_receive, this) != 0)
862 {
863 this->logger->log(this->logger, ERROR, "Could not spawn whack thread");
864 charon->logger_manager->destroy_logger(charon->logger_manager, this->logger);
865 close(this->socket);
866 unlink(socket_addr.sun_path);
867 allocator_free(this);
868 }
869
870 /* private variables */
871 this->configurations = linked_list_create();
872 this->sa_configs = linked_list_create();
873 this->init_configs = linked_list_create();
874 this->preshared_secrets = linked_list_create();
875 this->rsa_private_keys = linked_list_create();
876 this->rsa_public_keys = linked_list_create();
877 this->max_retransmit_count = MAX_RETRANSMIT_COUNT;
878 this->first_retransmit_timeout = RETRANSMIT_TIMEOUT;
879 this->half_open_ike_sa_timeout = HALF_OPEN_IKE_SA_TIMEOUT;
880
881 return (&this->public);
882 }