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