ifmap plugin subscribes to assing_vip bus signal
[strongswan.git] / src / libcharon / plugins / tnc_ifmap / tnc_ifmap_listener.c
1 /*
2 * Copyright (C) 2011-2013 Andreas Steffen
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 "tnc_ifmap_listener.h"
17 #include "tnc_ifmap_soap.h"
18 #include "tnc_ifmap_renew_session_job.h"
19
20 #include <daemon.h>
21 #include <hydra.h>
22 #include <utils/debug.h>
23
24 #define IFMAP_RENEW_SESSION_INTERVAL 150
25
26 typedef struct private_tnc_ifmap_listener_t private_tnc_ifmap_listener_t;
27
28 /**
29 * Private data of an tnc_ifmap_listener_t object.
30 */
31 struct private_tnc_ifmap_listener_t {
32
33 /**
34 * Public tnc_ifmap_listener_t interface.
35 */
36 tnc_ifmap_listener_t public;
37
38 /**
39 * TNC IF-MAP 2.0 SOAP interface
40 */
41 tnc_ifmap_soap_t *ifmap;
42
43 };
44
45 /**
46 * Publish PEP device-ip metadata
47 */
48 static bool publish_device_ip_addresses(private_tnc_ifmap_listener_t *this)
49 {
50 enumerator_t *enumerator;
51 host_t *host;
52 bool success = TRUE;
53
54 enumerator = hydra->kernel_interface->create_address_enumerator(
55 hydra->kernel_interface, ADDR_TYPE_REGULAR);
56 while (enumerator->enumerate(enumerator, &host))
57 {
58 if (!this->ifmap->publish_device_ip(this->ifmap, host))
59 {
60 success = FALSE;
61 break;
62 }
63 }
64 enumerator->destroy(enumerator);
65
66 return success;
67 }
68
69 /**
70 * Publish all IKE_SA metadata
71 */
72 static bool reload_metadata(private_tnc_ifmap_listener_t *this)
73 {
74 enumerator_t *enumerator, *evips;
75 ike_sa_t *ike_sa;
76 host_t *vip;
77 bool success = TRUE;
78
79 enumerator = charon->controller->create_ike_sa_enumerator(
80 charon->controller, FALSE);
81 while (enumerator->enumerate(enumerator, &ike_sa))
82 {
83 if (ike_sa->get_state(ike_sa) != IKE_ESTABLISHED)
84 {
85 continue;
86 }
87 if (!this->ifmap->publish_ike_sa(this->ifmap, ike_sa, TRUE))
88 {
89 success = FALSE;
90 break;
91 }
92 evips = ike_sa->create_virtual_ip_enumerator(ike_sa, FALSE);
93 while (evips->enumerate(evips, &vip))
94 {
95 if (!this->ifmap->publish_virtual_ip(this->ifmap, ike_sa, vip, TRUE))
96 {
97 success = FALSE;
98 break;
99 }
100 }
101 evips->destroy(evips);
102 }
103 enumerator->destroy(enumerator);
104
105 return success;
106 }
107
108 METHOD(listener_t, ike_updown, bool,
109 private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, bool up)
110 {
111 if (ike_sa->get_state(ike_sa) != IKE_CONNECTING)
112 {
113 this->ifmap->publish_ike_sa(this->ifmap, ike_sa, up);
114 }
115 return TRUE;
116 }
117
118 METHOD(listener_t, assign_vip, bool,
119 private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, host_t *vip,
120 bool assign)
121 {
122 this->ifmap->publish_virtual_ip(this->ifmap, ike_sa, vip, assign);
123 return TRUE;
124 }
125
126 METHOD(listener_t, alert, bool,
127 private_tnc_ifmap_listener_t *this, ike_sa_t *ike_sa, alert_t alert,
128 va_list args)
129 {
130 if (alert == ALERT_PEER_AUTH_FAILED)
131 {
132 this->ifmap->publish_enforcement_report(this->ifmap,
133 ike_sa->get_other_host(ike_sa),
134 "block", "authentication failed");
135 }
136 return TRUE;
137 }
138
139 METHOD(tnc_ifmap_listener_t, destroy, void,
140 private_tnc_ifmap_listener_t *this)
141 {
142 if (this->ifmap)
143 {
144 if (this->ifmap->get_session_id(this->ifmap))
145 {
146 this->ifmap->endSession(this->ifmap);
147 }
148 this->ifmap->destroy(this->ifmap);
149 }
150 free(this);
151 }
152
153 /**
154 * See header
155 */
156 tnc_ifmap_listener_t *tnc_ifmap_listener_create(bool reload)
157 {
158 private_tnc_ifmap_listener_t *this;
159 job_t *job;
160 u_int32_t reschedule;
161
162 INIT(this,
163 .public = {
164 .listener = {
165 .ike_updown = _ike_updown,
166 .assign_vip = _assign_vip,
167 .alert = _alert,
168 },
169 .destroy = _destroy,
170 },
171 .ifmap = tnc_ifmap_soap_create(),
172 );
173
174 if (!this->ifmap)
175 {
176 destroy(this);
177 return NULL;
178 }
179 if (!this->ifmap->newSession(this->ifmap))
180 {
181 destroy(this);
182 return NULL;
183 }
184 if (!this->ifmap->purgePublisher(this->ifmap))
185 {
186 destroy(this);
187 return NULL;
188 }
189 if (!publish_device_ip_addresses(this))
190 {
191 destroy(this);
192 return NULL;
193 }
194 if (reload)
195 {
196 if (!reload_metadata(this))
197 {
198 destroy(this);
199 return NULL;
200 }
201 }
202
203 /* schedule periodic transmission of IF-MAP renewSession request */
204 reschedule = lib->settings->get_int(lib->settings,
205 "%s.plugins.tnc-ifmap.renew_session_interval",
206 IFMAP_RENEW_SESSION_INTERVAL, charon->name);
207
208 job = (job_t*)tnc_ifmap_renew_session_job_create(
209 this->ifmap->get_ref(this->ifmap), reschedule);
210 lib->scheduler->schedule_job(lib->scheduler, job, reschedule);
211
212 return &this->public;
213 }
214