]> git.ipfire.org Git - thirdparty/strongswan.git/blob - src/libcharon/plugins/ha/ha_plugin.c
Update copyright headers after acquisition by secunet
[thirdparty/strongswan.git] / src / libcharon / plugins / ha / ha_plugin.c
1 /*
2 * Copyright (C) 2008 Martin Willi
3 *
4 * Copyright (C) secunet Security Networks AG
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
17 #include "ha_plugin.h"
18 #include "ha_ike.h"
19 #include "ha_child.h"
20 #include "ha_socket.h"
21 #include "ha_tunnel.h"
22 #include "ha_dispatcher.h"
23 #include "ha_segments.h"
24 #include "ha_ctl.h"
25 #include "ha_cache.h"
26 #include "ha_attribute.h"
27
28 #include <daemon.h>
29 #include <config/child_cfg.h>
30
31 typedef struct private_ha_plugin_t private_ha_plugin_t;
32
33 /**
34 * private data of ha plugin
35 */
36 struct private_ha_plugin_t {
37
38 /**
39 * implements plugin interface
40 */
41 ha_plugin_t public;
42
43 /**
44 * Communication socket
45 */
46 ha_socket_t *socket;
47
48 /**
49 * Tunnel securing sync messages.
50 */
51 ha_tunnel_t *tunnel;
52
53 /**
54 * IKE_SA synchronization
55 */
56 ha_ike_t *ike;
57
58 /**
59 * CHILD_SA synchronization
60 */
61 ha_child_t *child;
62
63 /**
64 * Dispatcher to process incoming messages
65 */
66 ha_dispatcher_t *dispatcher;
67
68 /**
69 * Active/Passive segment management
70 */
71 ha_segments_t *segments;
72
73 /**
74 * Interface to control segments at kernel level
75 */
76 ha_kernel_t *kernel;
77
78 /**
79 * Segment control interface via FIFO
80 */
81 ha_ctl_t *ctl;
82
83 /**
84 * Message cache for resynchronization
85 */
86 ha_cache_t *cache;
87
88 /**
89 * Attribute provider
90 */
91 ha_attribute_t *attr;
92 };
93
94 METHOD(plugin_t, get_name, char*,
95 private_ha_plugin_t *this)
96 {
97 return "ha";
98 }
99
100 /**
101 * Initialize plugin
102 */
103 static bool initialize_plugin(private_ha_plugin_t *this)
104 {
105 char *local, *remote, *secret;
106 u_int count;
107 bool fifo, monitor, resync;
108
109 local = lib->settings->get_str(lib->settings,
110 "%s.plugins.ha.local", NULL, lib->ns);
111 remote = lib->settings->get_str(lib->settings,
112 "%s.plugins.ha.remote", NULL, lib->ns);
113 secret = lib->settings->get_str(lib->settings,
114 "%s.plugins.ha.secret", NULL, lib->ns);
115 fifo = lib->settings->get_bool(lib->settings,
116 "%s.plugins.ha.fifo_interface", TRUE, lib->ns);
117 monitor = lib->settings->get_bool(lib->settings,
118 "%s.plugins.ha.monitor", TRUE, lib->ns);
119 resync = lib->settings->get_bool(lib->settings,
120 "%s.plugins.ha.resync", TRUE, lib->ns);
121 count = min(SEGMENTS_MAX, lib->settings->get_int(lib->settings,
122 "%s.plugins.ha.segment_count", 1, lib->ns));
123 if (!local || !remote)
124 {
125 DBG1(DBG_CFG, "HA config misses local/remote address");
126 return FALSE;
127 }
128
129 if (secret)
130 {
131 this->tunnel = ha_tunnel_create(local, remote, secret);
132 }
133 this->socket = ha_socket_create(local, remote);
134 if (!this->socket)
135 {
136 return FALSE;
137 }
138 this->kernel = ha_kernel_create(count);
139 this->segments = ha_segments_create(this->socket, this->kernel, this->tunnel,
140 count, strcmp(local, remote) > 0, monitor);
141 this->cache = ha_cache_create(this->kernel, this->socket, this->tunnel,
142 resync, count);
143 if (fifo)
144 {
145 this->ctl = ha_ctl_create(this->segments, this->cache);
146 }
147 this->attr = ha_attribute_create(this->kernel, this->segments);
148 this->dispatcher = ha_dispatcher_create(this->socket, this->segments,
149 this->cache, this->kernel, this->attr);
150 this->ike = ha_ike_create(this->socket, this->tunnel, this->cache);
151 this->child = ha_child_create(this->socket, this->tunnel, this->segments,
152 this->kernel);
153 return TRUE;
154 }
155
156 /**
157 * Initialize plugin and register listener
158 */
159 static bool plugin_cb(private_ha_plugin_t *this,
160 plugin_feature_t *feature, bool reg, void *cb_data)
161 {
162 if (reg)
163 {
164 if (!initialize_plugin(this))
165 {
166 return FALSE;
167 }
168 charon->bus->add_listener(charon->bus, &this->segments->listener);
169 charon->bus->add_listener(charon->bus, &this->ike->listener);
170 charon->bus->add_listener(charon->bus, &this->child->listener);
171 charon->attributes->add_provider(charon->attributes,
172 &this->attr->provider);
173 }
174 else
175 {
176 charon->attributes->remove_provider(charon->attributes,
177 &this->attr->provider);
178 charon->bus->remove_listener(charon->bus, &this->segments->listener);
179 charon->bus->remove_listener(charon->bus, &this->ike->listener);
180 charon->bus->remove_listener(charon->bus, &this->child->listener);
181 }
182 return TRUE;
183 }
184
185 METHOD(plugin_t, get_features, int,
186 private_ha_plugin_t *this, plugin_feature_t *features[])
187 {
188 static plugin_feature_t f[] = {
189 PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
190 PLUGIN_PROVIDE(CUSTOM, "ha"),
191 PLUGIN_SDEPEND(CUSTOM, "kernel-ipsec"),
192 };
193 *features = f;
194 return countof(f);
195 }
196
197 METHOD(plugin_t, destroy, void,
198 private_ha_plugin_t *this)
199 {
200 DESTROY_IF(this->ctl);
201 DESTROY_IF(this->ike);
202 DESTROY_IF(this->child);
203 DESTROY_IF(this->dispatcher);
204 DESTROY_IF(this->attr);
205 DESTROY_IF(this->cache);
206 DESTROY_IF(this->segments);
207 DESTROY_IF(this->kernel);
208 DESTROY_IF(this->socket);
209 DESTROY_IF(this->tunnel);
210 free(this);
211 }
212
213 /**
214 * Plugin constructor
215 */
216 plugin_t *ha_plugin_create()
217 {
218 private_ha_plugin_t *this;
219
220 if (!lib->caps->keep(lib->caps, CAP_CHOWN))
221 { /* required to chown(2) control socket, ha_kernel also needs it at
222 * runtime */
223 DBG1(DBG_CFG, "ha plugin requires CAP_CHOWN capability");
224 return NULL;
225 }
226
227 INIT(this,
228 .public = {
229 .plugin = {
230 .get_name = _get_name,
231 .get_features = _get_features,
232 .destroy = _destroy,
233 },
234 },
235 );
236
237 return &this->public.plugin;
238 }