]>
Commit | Line | Data |
---|---|---|
0b14fdb9 MW |
1 | /* |
2 | * Copyright (C) 2008 Martin Willi | |
3 | * Hochschule fuer Technik Rapperswil | |
4 | * | |
3317d0e7 AS |
5 | * Copyright (C) 2015 Andreas Steffen |
6 | * HSR Hochschule fuer Technik Rapperswil | |
7 | * | |
0b14fdb9 MW |
8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | |
10 | * Free Software Foundation; either version 2 of the License, or (at your | |
11 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
15 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | * for more details. | |
0b14fdb9 MW |
17 | */ |
18 | ||
19 | #include "stroke_list.h" | |
20 | ||
1b185ea4 | 21 | #include <inttypes.h> |
e13389a7 | 22 | #include <time.h> |
0f018a73 | 23 | #include <sys/utsname.h> |
e13389a7 | 24 | |
4f990932 MW |
25 | #ifdef HAVE_MALLINFO |
26 | #include <malloc.h> | |
27 | #endif /* HAVE_MALLINFO */ | |
28 | ||
0b14fdb9 | 29 | #include <daemon.h> |
12642a68 | 30 | #include <collections/linked_list.h> |
9cd7f384 | 31 | #include <plugins/plugin.h> |
0b14fdb9 | 32 | #include <credentials/certificates/x509.h> |
3317d0e7 | 33 | #include <credentials/certificates/certificate_printer.h> |
5397a7f9 | 34 | #include <config/peer_cfg.h> |
0b14fdb9 MW |
35 | |
36 | typedef struct private_stroke_list_t private_stroke_list_t; | |
37 | ||
38 | /** | |
39 | * private data of stroke_list | |
40 | */ | |
41 | struct private_stroke_list_t { | |
42 | ||
43 | /** | |
44 | * public functions | |
45 | */ | |
46 | stroke_list_t public; | |
7daf5226 | 47 | |
137035cc MW |
48 | /** |
49 | * Kind of *swan we run | |
50 | */ | |
51 | char *swan; | |
52 | ||
68523267 MW |
53 | /** |
54 | * timestamp of daemon start | |
55 | */ | |
56 | time_t uptime; | |
7daf5226 | 57 | |
2e031965 MW |
58 | /** |
59 | * strokes attribute provider | |
60 | */ | |
61 | stroke_attribute_t *attribute; | |
0b14fdb9 MW |
62 | }; |
63 | ||
02d43102 AS |
64 | /** |
65 | * Static certificate printer object | |
66 | */ | |
67 | static certificate_printer_t *cert_printer = NULL; | |
68 | ||
a3ffa9ed MW |
69 | /** |
70 | * Log tasks of a specific queue to out | |
71 | */ | |
72 | static void log_task_q(FILE *out, ike_sa_t *ike_sa, task_queue_t q, char *name) | |
73 | { | |
74 | enumerator_t *enumerator; | |
75 | bool has = FALSE; | |
76 | task_t *task; | |
77 | ||
78 | enumerator = ike_sa->create_task_enumerator(ike_sa, q); | |
79 | while (enumerator->enumerate(enumerator, &task)) | |
80 | { | |
81 | if (!has) | |
82 | { | |
83 | fprintf(out, "%12s[%d]: Tasks %s: ", ike_sa->get_name(ike_sa), | |
84 | ike_sa->get_unique_id(ike_sa), name); | |
85 | has = TRUE; | |
86 | } | |
87 | fprintf(out, "%N ", task_type_names, task->get_type(task)); | |
88 | } | |
89 | enumerator->destroy(enumerator); | |
90 | if (has) | |
91 | { | |
92 | fprintf(out, "\n"); | |
93 | } | |
94 | } | |
95 | ||
0b14fdb9 MW |
96 | /** |
97 | * log an IKE_SA to out | |
98 | */ | |
99 | static void log_ike_sa(FILE *out, ike_sa_t *ike_sa, bool all) | |
100 | { | |
101 | ike_sa_id_t *id = ike_sa->get_id(ike_sa); | |
6180a558 | 102 | time_t now = time_monotonic(NULL); |
7daf5226 | 103 | |
ed2bcd03 | 104 | fprintf(out, "%12s[%d]: %N", |
0b14fdb9 | 105 | ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa), |
ed2bcd03 | 106 | ike_sa_state_names, ike_sa->get_state(ike_sa)); |
7daf5226 | 107 | |
ed2bcd03 MW |
108 | if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED) |
109 | { | |
a584a231 | 110 | time_t established; |
7daf5226 | 111 | |
a584a231 | 112 | established = ike_sa->get_statistic(ike_sa, STAT_ESTABLISHED); |
d25ce370 | 113 | fprintf(out, " %V ago", &now, &established); |
ed2bcd03 | 114 | } |
7daf5226 | 115 | |
d24a74c5 | 116 | fprintf(out, ", %H[%Y]...%H[%Y]\n", |
0b14fdb9 | 117 | ike_sa->get_my_host(ike_sa), ike_sa->get_my_id(ike_sa), |
dc6d2596 | 118 | ike_sa->get_other_host(ike_sa), ike_sa->get_other_id(ike_sa)); |
7daf5226 | 119 | |
0b14fdb9 MW |
120 | if (all) |
121 | { | |
6a4ff35c | 122 | proposal_t *ike_proposal; |
dc6d2596 MW |
123 | identification_t *eap_id; |
124 | ||
125 | eap_id = ike_sa->get_other_eap_id(ike_sa); | |
126 | ||
127 | if (!eap_id->equals(eap_id, ike_sa->get_other_id(ike_sa))) | |
128 | { | |
129 | fprintf(out, "%12s[%d]: Remote %s identity: %Y\n", | |
130 | ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa), | |
131 | ike_sa->get_version(ike_sa) == IKEV1 ? "XAuth" : "EAP", | |
132 | eap_id); | |
133 | } | |
7daf5226 | 134 | |
5dffdea1 | 135 | ike_proposal = ike_sa->get_proposal(ike_sa); |
7daf5226 | 136 | |
5763367c | 137 | fprintf(out, "%12s[%d]: %N SPIs: %.16"PRIx64"_i%s %.16"PRIx64"_r%s", |
0b14fdb9 | 138 | ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa), |
5763367c | 139 | ike_version_names, ike_sa->get_version(ike_sa), |
db00982d TB |
140 | be64toh(id->get_initiator_spi(id)), |
141 | id->is_initiator(id) ? "*" : "", | |
142 | be64toh(id->get_responder_spi(id)), | |
143 | id->is_initiator(id) ? "" : "*"); | |
7daf5226 MW |
144 | |
145 | ||
bc997f65 | 146 | if (ike_sa->get_state(ike_sa) == IKE_ESTABLISHED) |
0b14fdb9 | 147 | { |
a584a231 | 148 | time_t rekey, reauth; |
a44bb934 | 149 | peer_cfg_t *peer_cfg; |
7daf5226 | 150 | |
85ac2fa5 MW |
151 | rekey = ike_sa->get_statistic(ike_sa, STAT_REKEY); |
152 | reauth = ike_sa->get_statistic(ike_sa, STAT_REAUTH); | |
a44bb934 | 153 | peer_cfg = ike_sa->get_peer_cfg(ike_sa); |
7daf5226 | 154 | |
bc997f65 AS |
155 | if (rekey) |
156 | { | |
d25ce370 | 157 | fprintf(out, ", rekeying in %V", &rekey, &now); |
bc997f65 AS |
158 | } |
159 | if (reauth) | |
160 | { | |
a44bb934 MW |
161 | bool first = TRUE; |
162 | enumerator_t *enumerator; | |
163 | auth_cfg_t *auth; | |
7daf5226 | 164 | |
a44bb934 MW |
165 | fprintf(out, ", "); |
166 | enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, TRUE); | |
167 | while (enumerator->enumerate(enumerator, &auth)) | |
168 | { | |
169 | if (!first) | |
170 | { | |
171 | fprintf(out, "+"); | |
172 | } | |
173 | first = FALSE; | |
174 | fprintf(out, "%N", auth_class_names, | |
175 | auth->get(auth, AUTH_RULE_AUTH_CLASS)); | |
176 | } | |
177 | enumerator->destroy(enumerator); | |
178 | fprintf(out, " reauthentication in %V", &reauth, &now); | |
bc997f65 AS |
179 | } |
180 | if (!rekey && !reauth) | |
181 | { | |
182 | fprintf(out, ", rekeying disabled"); | |
183 | } | |
0b14fdb9 MW |
184 | } |
185 | fprintf(out, "\n"); | |
7daf5226 | 186 | |
bc997f65 AS |
187 | if (ike_proposal) |
188 | { | |
3c8234d4 | 189 | char buf[BUF_LEN]; |
7daf5226 | 190 | |
3c8234d4 | 191 | snprintf(buf, BUF_LEN, "%P", ike_proposal); |
bc997f65 AS |
192 | fprintf(out, "%12s[%d]: IKE proposal: %s\n", |
193 | ike_sa->get_name(ike_sa), ike_sa->get_unique_id(ike_sa), | |
3c8234d4 | 194 | buf+4); |
6a4ff35c | 195 | } |
a3ffa9ed MW |
196 | |
197 | log_task_q(out, ike_sa, TASK_QUEUE_QUEUED, "queued"); | |
198 | log_task_q(out, ike_sa, TASK_QUEUE_ACTIVE, "active"); | |
199 | log_task_q(out, ike_sa, TASK_QUEUE_PASSIVE, "passive"); | |
0b14fdb9 MW |
200 | } |
201 | } | |
202 | ||
203 | /** | |
204 | * log an CHILD_SA to out | |
205 | */ | |
206 | static void log_child_sa(FILE *out, child_sa_t *child_sa, bool all) | |
207 | { | |
6180a558 | 208 | time_t use_in, use_out, rekey, now; |
b12c53ce | 209 | uint64_t bytes_in, bytes_out, packets_in, packets_out; |
80853d84 | 210 | proposal_t *proposal; |
553bb787 MW |
211 | linked_list_t *my_ts, *other_ts; |
212 | child_cfg_t *config; | |
7daf5226 | 213 | |
553bb787 | 214 | config = child_sa->get_config(child_sa); |
21043198 | 215 | now = time_monotonic(NULL); |
7daf5226 | 216 | |
53cf7fa6 MW |
217 | fprintf(out, "%12s{%d}: %N, %N%s, reqid %u", |
218 | child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa), | |
0b14fdb9 | 219 | child_sa_state_names, child_sa->get_state(child_sa), |
ad60c249 | 220 | ipsec_mode_names, child_sa->get_mode(child_sa), |
749ac175 | 221 | config->has_option(config, OPT_PROXY_MODE) ? "_PROXY" : "", |
53cf7fa6 | 222 | child_sa->get_reqid(child_sa)); |
7daf5226 | 223 | |
0b14fdb9 MW |
224 | if (child_sa->get_state(child_sa) == CHILD_INSTALLED) |
225 | { | |
82d20c05 | 226 | fprintf(out, ", %N%s SPIs: %.8x_i %.8x_o", |
0b14fdb9 | 227 | protocol_id_names, child_sa->get_protocol(child_sa), |
ad60c249 | 228 | child_sa->has_encap(child_sa) ? " in UDP" : "", |
eba7470b AS |
229 | ntohl(child_sa->get_spi(child_sa, TRUE)), |
230 | ntohl(child_sa->get_spi(child_sa, FALSE))); | |
7daf5226 | 231 | |
82d20c05 | 232 | if (child_sa->get_ipcomp(child_sa) != IPCOMP_NONE) |
66da78b4 AS |
233 | { |
234 | fprintf(out, ", IPCOMP CPIs: %.4x_i %.4x_o", | |
82d20c05 MW |
235 | ntohs(child_sa->get_cpi(child_sa, TRUE)), |
236 | ntohs(child_sa->get_cpi(child_sa, FALSE))); | |
66da78b4 | 237 | } |
7daf5226 | 238 | |
0b14fdb9 MW |
239 | if (all) |
240 | { | |
7daf5226 | 241 | fprintf(out, "\n%12s{%d}: ", child_sa->get_name(child_sa), |
53cf7fa6 | 242 | child_sa->get_unique_id(child_sa)); |
7daf5226 | 243 | |
80853d84 MW |
244 | proposal = child_sa->get_proposal(child_sa); |
245 | if (proposal) | |
0b14fdb9 | 246 | { |
b12c53ce | 247 | uint16_t alg, ks; |
f6037b55 | 248 | bool first = TRUE; |
7daf5226 | 249 | |
5d7049b4 TB |
250 | if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, |
251 | &alg, &ks) && alg != ENCR_UNDEFINED) | |
a327ee95 | 252 | { |
5d7049b4 | 253 | fprintf(out, "%N", encryption_algorithm_names, alg); |
f6037b55 | 254 | first = FALSE; |
5d7049b4 | 255 | if (ks) |
80853d84 | 256 | { |
5d7049b4 | 257 | fprintf(out, "_%u", ks); |
80853d84 | 258 | } |
a327ee95 | 259 | } |
5d7049b4 TB |
260 | if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, |
261 | &alg, &ks) && alg != AUTH_UNDEFINED) | |
80853d84 | 262 | { |
5d7049b4 TB |
263 | fprintf(out, "%s%N", first ? "" : "/", |
264 | integrity_algorithm_names, alg); | |
265 | if (ks) | |
80853d84 | 266 | { |
5d7049b4 | 267 | fprintf(out, "_%u", ks); |
80853d84 MW |
268 | } |
269 | } | |
5d7049b4 TB |
270 | if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP, |
271 | &alg, NULL)) | |
272 | { | |
273 | fprintf(out, "/%N", diffie_hellman_group_names, alg); | |
274 | } | |
275 | if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, | |
276 | &alg, NULL) && alg == EXT_SEQ_NUMBERS) | |
6101ee9b AS |
277 | { |
278 | fprintf(out, "/ESN"); | |
279 | } | |
0b14fdb9 | 280 | } |
7daf5226 | 281 | |
d28391a2 MW |
282 | child_sa->get_usestats(child_sa, TRUE, |
283 | &use_in, &bytes_in, &packets_in); | |
1b185ea4 | 284 | fprintf(out, ", %" PRIu64 " bytes_i", bytes_in); |
c3a78360 | 285 | if (use_in) |
2ad51539 | 286 | { |
9fa9f68d AS |
287 | fprintf(out, " (%" PRIu64 " pkt%s, %" PRIu64 "s ago)", |
288 | packets_in, (packets_in == 1) ? "": "s", | |
b12c53ce | 289 | (uint64_t)(now - use_in)); |
2ad51539 AS |
290 | } |
291 | ||
d28391a2 MW |
292 | child_sa->get_usestats(child_sa, FALSE, |
293 | &use_out, &bytes_out, &packets_out); | |
1b185ea4 | 294 | fprintf(out, ", %" PRIu64 " bytes_o", bytes_out); |
c3a78360 | 295 | if (use_out) |
2ad51539 | 296 | { |
9fa9f68d AS |
297 | fprintf(out, " (%" PRIu64 " pkt%s, %" PRIu64 "s ago)", |
298 | packets_out, (packets_out == 1) ? "": "s", | |
b12c53ce | 299 | (uint64_t)(now - use_out)); |
2ad51539 | 300 | } |
0b14fdb9 | 301 | fprintf(out, ", rekeying "); |
7daf5226 | 302 | |
6e10aead | 303 | rekey = child_sa->get_lifetime(child_sa, FALSE); |
0b14fdb9 MW |
304 | if (rekey) |
305 | { | |
9dd2b427 MW |
306 | if (now > rekey) |
307 | { | |
308 | fprintf(out, "active"); | |
309 | } | |
310 | else | |
311 | { | |
312 | fprintf(out, "in %V", &now, &rekey); | |
313 | } | |
0b14fdb9 MW |
314 | } |
315 | else | |
316 | { | |
317 | fprintf(out, "disabled"); | |
318 | } | |
7daf5226 | 319 | |
0b14fdb9 MW |
320 | } |
321 | } | |
70728eb1 TB |
322 | else if (child_sa->get_state(child_sa) == CHILD_REKEYING || |
323 | child_sa->get_state(child_sa) == CHILD_REKEYED) | |
21043198 MW |
324 | { |
325 | rekey = child_sa->get_lifetime(child_sa, TRUE); | |
326 | fprintf(out, ", expires in %V", &now, &rekey); | |
327 | } | |
7daf5226 | 328 | |
553bb787 MW |
329 | my_ts = linked_list_create_from_enumerator( |
330 | child_sa->create_ts_enumerator(child_sa, TRUE)); | |
331 | other_ts = linked_list_create_from_enumerator( | |
332 | child_sa->create_ts_enumerator(child_sa, FALSE)); | |
ebeb8c87 | 333 | fprintf(out, "\n%12s{%d}: %#R === %#R\n", |
53cf7fa6 | 334 | child_sa->get_name(child_sa), child_sa->get_unique_id(child_sa), |
553bb787 MW |
335 | my_ts, other_ts); |
336 | my_ts->destroy(my_ts); | |
337 | other_ts->destroy(other_ts); | |
0b14fdb9 MW |
338 | } |
339 | ||
a44bb934 MW |
340 | /** |
341 | * Log a configs local or remote authentication config to out | |
342 | */ | |
343 | static void log_auth_cfgs(FILE *out, peer_cfg_t *peer_cfg, bool local) | |
344 | { | |
345 | enumerator_t *enumerator, *rules; | |
346 | auth_rule_t rule; | |
347 | auth_cfg_t *auth; | |
348 | auth_class_t auth_class; | |
349 | identification_t *id; | |
350 | certificate_t *cert; | |
351 | cert_validation_t valid; | |
352 | char *name; | |
7daf5226 | 353 | |
a44bb934 | 354 | name = peer_cfg->get_name(peer_cfg); |
7daf5226 | 355 | |
a44bb934 MW |
356 | enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local); |
357 | while (enumerator->enumerate(enumerator, &auth)) | |
358 | { | |
874f7c7e MW |
359 | fprintf(out, "%12s: %s", name, local ? "local: " : "remote:"); |
360 | id = auth->get(auth, AUTH_RULE_IDENTITY); | |
361 | if (id) | |
362 | { | |
363 | fprintf(out, " [%Y]", id); | |
364 | } | |
365 | fprintf(out, " uses "); | |
a44bb934 MW |
366 | |
367 | auth_class = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS); | |
5f6a37eb | 368 | if (auth_class == AUTH_CLASS_EAP) |
a44bb934 MW |
369 | { |
370 | if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE) == EAP_NAK) | |
371 | { | |
372 | fprintf(out, "EAP authentication"); | |
373 | } | |
374 | else | |
375 | { | |
376 | if ((uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR)) | |
377 | { | |
1b185ea4 | 378 | fprintf(out, "EAP_%" PRIuPTR "-%" PRIuPTR " authentication", |
a44bb934 MW |
379 | (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE), |
380 | (uintptr_t)auth->get(auth, AUTH_RULE_EAP_VENDOR)); | |
381 | } | |
382 | else | |
383 | { | |
384 | fprintf(out, "%N authentication", eap_type_names, | |
385 | (uintptr_t)auth->get(auth, AUTH_RULE_EAP_TYPE)); | |
386 | } | |
387 | } | |
388 | id = auth->get(auth, AUTH_RULE_EAP_IDENTITY); | |
389 | if (id) | |
390 | { | |
d24a74c5 | 391 | fprintf(out, " with EAP identity '%Y'", id); |
a44bb934 MW |
392 | } |
393 | fprintf(out, "\n"); | |
394 | } | |
5f6a37eb MW |
395 | else if (auth_class == AUTH_CLASS_XAUTH) |
396 | { | |
397 | fprintf(out, "%N authentication: %s", auth_class_names, auth_class, | |
398 | auth->get(auth, AUTH_RULE_XAUTH_BACKEND) ?: "any"); | |
399 | id = auth->get(auth, AUTH_RULE_XAUTH_IDENTITY); | |
400 | if (id) | |
401 | { | |
402 | fprintf(out, " with XAuth identity '%Y'", id); | |
403 | } | |
404 | fprintf(out, "\n"); | |
405 | } | |
406 | else | |
407 | { | |
408 | fprintf(out, "%N authentication\n", auth_class_names, auth_class); | |
409 | } | |
a44bb934 MW |
410 | |
411 | cert = auth->get(auth, AUTH_RULE_CA_CERT); | |
412 | if (cert) | |
413 | { | |
d24a74c5 | 414 | fprintf(out, "%12s: ca: \"%Y\"\n", name, cert->get_subject(cert)); |
a44bb934 MW |
415 | } |
416 | ||
417 | cert = auth->get(auth, AUTH_RULE_IM_CERT); | |
418 | if (cert) | |
419 | { | |
d24a74c5 | 420 | fprintf(out, "%12s: im-ca: \"%Y\"\n", name, cert->get_subject(cert)); |
a44bb934 MW |
421 | } |
422 | ||
423 | cert = auth->get(auth, AUTH_RULE_SUBJECT_CERT); | |
424 | if (cert) | |
425 | { | |
d24a74c5 | 426 | fprintf(out, "%12s: cert: \"%Y\"\n", name, |
a44bb934 MW |
427 | cert->get_subject(cert)); |
428 | } | |
429 | ||
430 | valid = (uintptr_t)auth->get(auth, AUTH_RULE_OCSP_VALIDATION); | |
431 | if (valid != VALIDATION_FAILED) | |
432 | { | |
433 | fprintf(out, "%12s: ocsp: status must be GOOD%s\n", name, | |
434 | (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : ""); | |
435 | } | |
7daf5226 | 436 | |
a44bb934 MW |
437 | valid = (uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION); |
438 | if (valid != VALIDATION_FAILED) | |
439 | { | |
440 | fprintf(out, "%12s: crl: status must be GOOD%s\n", name, | |
441 | (valid == VALIDATION_SKIPPED) ? " or SKIPPED" : ""); | |
442 | } | |
443 | ||
444 | rules = auth->create_enumerator(auth); | |
445 | while (rules->enumerate(rules, &rule, &id)) | |
446 | { | |
4172574b | 447 | if (rule == AUTH_RULE_GROUP) |
a44bb934 | 448 | { |
d24a74c5 | 449 | fprintf(out, "%12s: group: %Y\n", name, id); |
a44bb934 MW |
450 | } |
451 | } | |
452 | rules->destroy(rules); | |
453 | } | |
454 | enumerator->destroy(enumerator); | |
455 | } | |
456 | ||
cb6be85c | 457 | METHOD(stroke_list_t, status, void, |
a694b481 MW |
458 | private_stroke_list_t *this, stroke_msg_t *msg, FILE *out, |
459 | bool all, bool wait) | |
0b14fdb9 MW |
460 | { |
461 | enumerator_t *enumerator, *children; | |
0b14fdb9 MW |
462 | ike_cfg_t *ike_cfg; |
463 | child_cfg_t *child_cfg; | |
56d461a1 | 464 | child_sa_t *child_sa; |
0b14fdb9 | 465 | ike_sa_t *ike_sa; |
f8799170 | 466 | linked_list_t *my_ts, *other_ts; |
90df644e | 467 | bool first, found = FALSE; |
3c87e926 | 468 | char *name = msg->status.name; |
4cf6f101 | 469 | u_int half_open; |
7daf5226 | 470 | |
0b14fdb9 MW |
471 | if (all) |
472 | { | |
3c87e926 | 473 | peer_cfg_t *peer_cfg; |
2ac996cb | 474 | ike_version_t ike_version; |
f1ba06c1 | 475 | char *pool; |
3c87e926 | 476 | host_t *host; |
b12c53ce | 477 | uint32_t dpd; |
6180a558 | 478 | time_t since, now; |
c73d4f53 | 479 | u_int size, online, offline, i; |
0f018a73 MW |
480 | struct utsname utsname; |
481 | ||
6180a558 MW |
482 | now = time_monotonic(NULL); |
483 | since = time(NULL) - (now - this->uptime); | |
7daf5226 | 484 | |
0f018a73 MW |
485 | fprintf(out, "Status of IKE charon daemon (%sSwan "VERSION, this->swan); |
486 | if (uname(&utsname) == 0) | |
487 | { | |
488 | fprintf(out, ", %s %s, %s", | |
489 | utsname.sysname, utsname.release, utsname.machine); | |
490 | } | |
491 | fprintf(out, "):\n uptime: %V, since %T\n", &now, &this->uptime, &since, | |
137035cc | 492 | FALSE); |
4f990932 MW |
493 | #ifdef HAVE_MALLINFO |
494 | { | |
495 | struct mallinfo mi = mallinfo(); | |
496 | ||
8286e205 | 497 | fprintf(out, " malloc: sbrk %u, mmap %u, used %u, free %u\n", |
4f990932 MW |
498 | mi.arena, mi.hblkhd, mi.uordblks, mi.fordblks); |
499 | } | |
500 | #endif /* HAVE_MALLINFO */ | |
c726b1a6 | 501 | fprintf(out, " worker threads: %d of %d idle, ", |
bb381e26 TB |
502 | lib->processor->get_idle_threads(lib->processor), |
503 | lib->processor->get_total_threads(lib->processor)); | |
c726b1a6 MW |
504 | for (i = 0; i < JOB_PRIO_MAX; i++) |
505 | { | |
506 | fprintf(out, "%s%d", i == 0 ? "" : "/", | |
507 | lib->processor->get_working_threads(lib->processor, i)); | |
508 | } | |
509 | fprintf(out, " working, job queue: "); | |
c73d4f53 MW |
510 | for (i = 0; i < JOB_PRIO_MAX; i++) |
511 | { | |
512 | fprintf(out, "%s%d", i == 0 ? "" : "/", | |
513 | lib->processor->get_job_load(lib->processor, i)); | |
514 | } | |
c726b1a6 | 515 | fprintf(out, ", scheduled: %d\n", |
bb381e26 | 516 | lib->scheduler->get_job_load(lib->scheduler)); |
f1ba06c1 TB |
517 | fprintf(out, " loaded plugins: %s\n", |
518 | lib->plugins->loaded_plugins(lib->plugins)); | |
7daf5226 | 519 | |
90df644e | 520 | first = TRUE; |
2e031965 | 521 | enumerator = this->attribute->create_pool_enumerator(this->attribute); |
67701cfd | 522 | while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline)) |
2e031965 | 523 | { |
77e7eede AS |
524 | if (name && !streq(name, pool)) |
525 | { | |
526 | continue; | |
527 | } | |
2e031965 MW |
528 | if (first) |
529 | { | |
530 | first = FALSE; | |
531 | fprintf(out, "Virtual IP pools (size/online/offline):\n"); | |
532 | } | |
226308eb | 533 | fprintf(out, " %s: %u/%u/%u\n", pool, size, online, offline); |
2e031965 MW |
534 | } |
535 | enumerator->destroy(enumerator); | |
7daf5226 | 536 | |
8394ea2a TB |
537 | enumerator = charon->kernel->create_address_enumerator(charon->kernel, |
538 | ADDR_TYPE_REGULAR); | |
0b14fdb9 | 539 | fprintf(out, "Listening IP addresses:\n"); |
507f26f6 | 540 | while (enumerator->enumerate(enumerator, (void**)&host)) |
0b14fdb9 MW |
541 | { |
542 | fprintf(out, " %H\n", host); | |
543 | } | |
507f26f6 | 544 | enumerator->destroy(enumerator); |
7daf5226 | 545 | |
0b14fdb9 | 546 | fprintf(out, "Connections:\n"); |
a44bb934 | 547 | enumerator = charon->backends->create_peer_cfg_enumerator( |
ac009df1 | 548 | charon->backends, NULL, NULL, NULL, NULL, IKE_ANY); |
a44bb934 | 549 | while (enumerator->enumerate(enumerator, &peer_cfg)) |
0b14fdb9 | 550 | { |
1d315bdd | 551 | char *my_addr, *other_addr; |
1d315bdd | 552 | |
cf1772f6 | 553 | if (name && !streq(name, peer_cfg->get_name(peer_cfg))) |
0b14fdb9 MW |
554 | { |
555 | continue; | |
556 | } | |
7daf5226 | 557 | |
0b14fdb9 | 558 | ike_cfg = peer_cfg->get_ike_cfg(peer_cfg); |
2ac996cb | 559 | ike_version = peer_cfg->get_ike_version(peer_cfg); |
3070697f MW |
560 | my_addr = ike_cfg->get_my_addr(ike_cfg); |
561 | other_addr = ike_cfg->get_other_addr(ike_cfg); | |
beffdc6a MW |
562 | fprintf(out, "%12s: %s...%s %N", peer_cfg->get_name(peer_cfg), |
563 | my_addr, other_addr, ike_version_names, ike_version); | |
2ac996cb AS |
564 | |
565 | if (ike_version == IKEV1 && peer_cfg->use_aggressive(peer_cfg)) | |
566 | { | |
567 | fprintf(out, " Aggressive"); | |
568 | } | |
7daf5226 | 569 | |
2c258d73 AS |
570 | dpd = peer_cfg->get_dpd(peer_cfg); |
571 | if (dpd) | |
572 | { | |
573 | fprintf(out, ", dpddelay=%us", dpd); | |
574 | } | |
575 | fprintf(out, "\n"); | |
7daf5226 | 576 | |
a44bb934 MW |
577 | log_auth_cfgs(out, peer_cfg, TRUE); |
578 | log_auth_cfgs(out, peer_cfg, FALSE); | |
7daf5226 | 579 | |
0b14fdb9 MW |
580 | children = peer_cfg->create_child_cfg_enumerator(peer_cfg); |
581 | while (children->enumerate(children, &child_cfg)) | |
582 | { | |
0b14fdb9 MW |
583 | my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL); |
584 | other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL); | |
ebeb8c87 | 585 | fprintf(out, "%12s: child: %#R === %#R %N", |
f8799170 AS |
586 | child_cfg->get_name(child_cfg), my_ts, other_ts, |
587 | ipsec_mode_names, child_cfg->get_mode(child_cfg)); | |
0b14fdb9 MW |
588 | my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); |
589 | other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); | |
7daf5226 | 590 | |
2c258d73 AS |
591 | if (dpd) |
592 | { | |
593 | fprintf(out, ", dpdaction=%N", action_names, | |
594 | child_cfg->get_dpd_action(child_cfg)); | |
595 | } | |
596 | fprintf(out, "\n"); | |
0b14fdb9 MW |
597 | } |
598 | children->destroy(children); | |
599 | } | |
600 | enumerator->destroy(enumerator); | |
601 | } | |
90df644e | 602 | |
f8799170 AS |
603 | /* Enumerate shunt policies */ |
604 | first = TRUE; | |
605 | enumerator = charon->shunts->create_enumerator(charon->shunts); | |
7a0fdbab | 606 | while (enumerator->enumerate(enumerator, NULL, &child_cfg)) |
f8799170 AS |
607 | { |
608 | if (name && !streq(name, child_cfg->get_name(child_cfg))) | |
609 | { | |
610 | continue; | |
611 | } | |
612 | if (first) | |
613 | { | |
614 | fprintf(out, "Shunted Connections:\n"); | |
615 | first = FALSE; | |
616 | } | |
617 | my_ts = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL, NULL); | |
618 | other_ts = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL, NULL); | |
ebeb8c87 | 619 | fprintf(out, "%12s: %#R === %#R %N\n", |
f8799170 AS |
620 | child_cfg->get_name(child_cfg), my_ts, other_ts, |
621 | ipsec_mode_names, child_cfg->get_mode(child_cfg)); | |
622 | my_ts->destroy_offset(my_ts, offsetof(traffic_selector_t, destroy)); | |
623 | other_ts->destroy_offset(other_ts, offsetof(traffic_selector_t, destroy)); | |
624 | } | |
625 | enumerator->destroy(enumerator); | |
626 | ||
627 | /* Enumerate traps */ | |
7daf5226 | 628 | first = TRUE; |
56d461a1 MW |
629 | enumerator = charon->traps->create_enumerator(charon->traps); |
630 | while (enumerator->enumerate(enumerator, NULL, &child_sa)) | |
631 | { | |
f8799170 AS |
632 | if (name && !streq(name, child_sa->get_name(child_sa))) |
633 | { | |
634 | continue; | |
635 | } | |
90df644e AS |
636 | if (first) |
637 | { | |
638 | fprintf(out, "Routed Connections:\n"); | |
639 | first = FALSE; | |
640 | } | |
56d461a1 MW |
641 | log_child_sa(out, child_sa, all); |
642 | } | |
643 | enumerator->destroy(enumerator); | |
7daf5226 | 644 | |
4cf6f101 | 645 | half_open = charon->ike_sa_manager->get_half_open_count( |
735f929c | 646 | charon->ike_sa_manager, NULL, FALSE); |
4cf6f101 MW |
647 | fprintf(out, "Security Associations (%u up, %u connecting):\n", |
648 | charon->ike_sa_manager->get_count(charon->ike_sa_manager) - half_open, | |
649 | half_open); | |
69c3eca0 | 650 | enumerator = charon->controller->create_ike_sa_enumerator( |
a694b481 | 651 | charon->controller, wait); |
49032d15 | 652 | while (enumerator->enumerate(enumerator, &ike_sa) && ferror(out) == 0) |
0b14fdb9 MW |
653 | { |
654 | bool ike_printed = FALSE; | |
4bbce1ef | 655 | enumerator_t *children = ike_sa->create_child_sa_enumerator(ike_sa); |
7daf5226 | 656 | |
0b14fdb9 MW |
657 | if (name == NULL || streq(name, ike_sa->get_name(ike_sa))) |
658 | { | |
659 | log_ike_sa(out, ike_sa, all); | |
a593db5d | 660 | found = TRUE; |
0b14fdb9 MW |
661 | ike_printed = TRUE; |
662 | } | |
663 | ||
4bbce1ef | 664 | while (children->enumerate(children, (void**)&child_sa)) |
0b14fdb9 MW |
665 | { |
666 | if (name == NULL || streq(name, child_sa->get_name(child_sa))) | |
667 | { | |
668 | if (!ike_printed) | |
669 | { | |
670 | log_ike_sa(out, ike_sa, all); | |
a593db5d | 671 | found = TRUE; |
0b14fdb9 MW |
672 | ike_printed = TRUE; |
673 | } | |
674 | log_child_sa(out, child_sa, all); | |
7daf5226 | 675 | } |
0b14fdb9 MW |
676 | } |
677 | children->destroy(children); | |
678 | } | |
a593db5d | 679 | enumerator->destroy(enumerator); |
7daf5226 | 680 | |
a593db5d MW |
681 | if (!found) |
682 | { | |
683 | if (name) | |
684 | { | |
685 | fprintf(out, " no match\n"); | |
686 | } | |
687 | else | |
688 | { | |
689 | fprintf(out, " none\n"); | |
690 | } | |
691 | } | |
0b14fdb9 MW |
692 | } |
693 | ||
eafc0654 AS |
694 | /** |
695 | * create a unique certificate list without duplicates | |
2db6d5b8 | 696 | * certificates having the same issuer are grouped together. |
eafc0654 AS |
697 | */ |
698 | static linked_list_t* create_unique_cert_list(certificate_type_t type) | |
699 | { | |
700 | linked_list_t *list = linked_list_create(); | |
2ccc02a4 MW |
701 | enumerator_t *enumerator = lib->credmgr->create_cert_enumerator( |
702 | lib->credmgr, type, KEY_ANY, NULL, FALSE); | |
eafc0654 | 703 | certificate_t *cert; |
7daf5226 | 704 | |
eafc0654 AS |
705 | while (enumerator->enumerate(enumerator, (void**)&cert)) |
706 | { | |
47daa0e6 | 707 | enumerator_t *added = list->create_enumerator(list); |
946d1ecd | 708 | identification_t *issuer = cert->get_issuer(cert); |
47daa0e6 | 709 | bool previous_same, same = FALSE, found = FALSE; |
eafc0654 | 710 | certificate_t *list_cert; |
7daf5226 | 711 | |
47daa0e6 | 712 | while (added->enumerate(added, (void**)&list_cert)) |
eafc0654 | 713 | { |
1749642b | 714 | if (list_cert->equals(list_cert, cert)) |
47daa0e6 TB |
715 | { /* stop if we found a duplicate*/ |
716 | found = TRUE; | |
946d1ecd AS |
717 | break; |
718 | } | |
946d1ecd AS |
719 | previous_same = same; |
720 | same = list_cert->has_issuer(list_cert, issuer); | |
721 | if (previous_same && !same) | |
47daa0e6 | 722 | { /* group certificates with same issuer */ |
eafc0654 AS |
723 | break; |
724 | } | |
725 | } | |
47daa0e6 | 726 | if (!found) |
eafc0654 | 727 | { |
47daa0e6 | 728 | list->insert_before(list, added, cert->get_ref(cert)); |
eafc0654 | 729 | } |
47daa0e6 | 730 | added->destroy(added); |
eafc0654 AS |
731 | } |
732 | enumerator->destroy(enumerator); | |
733 | return list; | |
734 | } | |
735 | ||
c5cd195c | 736 | /** |
3317d0e7 | 737 | * Is there a matching private key? |
c5cd195c | 738 | */ |
3317d0e7 | 739 | static bool has_privkey(certificate_t *cert) |
c5cd195c | 740 | { |
3317d0e7 | 741 | public_key_t *public; |
c5cd195c MW |
742 | private_key_t *private = NULL; |
743 | chunk_t keyid; | |
744 | identification_t *id; | |
7daf5226 | 745 | |
3317d0e7 AS |
746 | public = cert->get_public_key(cert); |
747 | if (!public) | |
748 | { | |
749 | return FALSE; | |
750 | } | |
da9724e6 | 751 | if (public->get_fingerprint(public, KEYID_PUBKEY_SHA1, &keyid)) |
c5cd195c MW |
752 | { |
753 | id = identification_create_from_encoding(ID_KEY_ID, keyid); | |
2ccc02a4 | 754 | private = lib->credmgr->get_private(lib->credmgr, |
5aef6bd0 | 755 | public->get_type(public), id, NULL); |
c5cd195c MW |
756 | id->destroy(id); |
757 | } | |
3317d0e7 | 758 | public->destroy(public); |
c5cd195c | 759 | DESTROY_IF(private); |
3577ec76 | 760 | |
3317d0e7 | 761 | return (private != NULL); |
d1cbe551 AS |
762 | } |
763 | ||
0b14fdb9 MW |
764 | /** |
765 | * list all X.509 certificates matching the flags | |
766 | */ | |
02d43102 | 767 | static void stroke_list_x509_certs(linked_list_t *list, x509_flag_t flag) |
0b14fdb9 | 768 | { |
32d8f442 | 769 | enumerator_t *enumerator; |
0b14fdb9 | 770 | certificate_t *cert; |
32d8f442 AS |
771 | |
772 | enumerator = list->create_enumerator(list); | |
0b14fdb9 MW |
773 | while (enumerator->enumerate(enumerator, (void**)&cert)) |
774 | { | |
775 | x509_t *x509 = (x509_t*)cert; | |
02d43102 | 776 | x509_flag_t flags = x509->get_flags(x509) & X509_ANY; |
7daf5226 | 777 | |
32d8f442 | 778 | /* list only if flag is set or flag == 0 */ |
02d43102 | 779 | if ((flags & flag) || flags == flag) |
0b14fdb9 | 780 | { |
02d43102 AS |
781 | cert_printer->print_caption(cert_printer, CERT_X509, flag); |
782 | cert_printer->print(cert_printer, cert, has_privkey(cert)); | |
0b14fdb9 MW |
783 | } |
784 | } | |
785 | enumerator->destroy(enumerator); | |
786 | } | |
787 | ||
eafc0654 | 788 | /** |
3317d0e7 | 789 | * list all other certificates types |
eafc0654 | 790 | */ |
02d43102 | 791 | static void stroke_list_other_certs(certificate_type_t type) |
eafc0654 | 792 | { |
61b2d815 | 793 | enumerator_t *enumerator; |
7199d22e | 794 | certificate_t *cert; |
02d43102 | 795 | linked_list_t *list; |
3317d0e7 | 796 | |
02d43102 | 797 | list = create_unique_cert_list(type); |
eafc0654 | 798 | |
61b2d815 MW |
799 | enumerator = list->create_enumerator(list); |
800 | while (enumerator->enumerate(enumerator, &cert)) | |
7199d22e | 801 | { |
02d43102 AS |
802 | cert_printer->print_caption(cert_printer, cert->get_type(cert), X509_NONE); |
803 | cert_printer->print(cert_printer, cert, has_privkey(cert)); | |
0b14fdb9 MW |
804 | } |
805 | enumerator->destroy(enumerator); | |
80f86acc | 806 | |
02d43102 | 807 | list->destroy_offset(list, offsetof(certificate_t, destroy)); |
eafc0654 AS |
808 | } |
809 | ||
16b6606e AS |
810 | /** |
811 | * Print the name of an algorithm plus the name of the plugin that registered it | |
812 | */ | |
813 | static void print_alg(FILE *out, int *len, enum_name_t *alg_names, int alg_type, | |
814 | const char *plugin_name) | |
815 | { | |
816 | char alg_name[BUF_LEN]; | |
817 | int alg_name_len; | |
787b5884 | 818 | |
5c162dd9 TB |
819 | if (alg_names) |
820 | { | |
821 | alg_name_len = sprintf(alg_name, " %N[%s]", alg_names, alg_type, | |
822 | plugin_name); | |
823 | } | |
824 | else | |
825 | { | |
826 | alg_name_len = sprintf(alg_name, " [%s]", plugin_name); | |
827 | } | |
27a66f93 | 828 | if (*len + alg_name_len > CRYPTO_MAX_ALG_LINE) |
16b6606e AS |
829 | { |
830 | fprintf(out, "\n "); | |
787b5884 | 831 | *len = 13; |
16b6606e AS |
832 | } |
833 | fprintf(out, "%s", alg_name); | |
834 | *len += alg_name_len; | |
835 | } | |
836 | ||
94822086 | 837 | /** |
8fa6f2dc | 838 | * List of registered cryptographical algorithms |
94822086 MW |
839 | */ |
840 | static void list_algs(FILE *out) | |
841 | { | |
842 | enumerator_t *enumerator; | |
843 | encryption_algorithm_t encryption; | |
844 | integrity_algorithm_t integrity; | |
845 | hash_algorithm_t hash; | |
846 | pseudo_random_function_t prf; | |
04208ac5 | 847 | ext_out_function_t xof; |
94822086 | 848 | diffie_hellman_group_t group; |
5932f41f AS |
849 | rng_quality_t quality; |
850 | const char *plugin_name; | |
16b6606e | 851 | int len; |
7daf5226 | 852 | |
8fa6f2dc | 853 | fprintf(out, "\n"); |
6cf79c1e | 854 | fprintf(out, "List of registered IKE algorithms:\n"); |
16b6606e AS |
855 | fprintf(out, "\n encryption:"); |
856 | len = 13; | |
94822086 | 857 | enumerator = lib->crypto->create_crypter_enumerator(lib->crypto); |
5932f41f | 858 | while (enumerator->enumerate(enumerator, &encryption, &plugin_name)) |
94822086 | 859 | { |
16b6606e | 860 | print_alg(out, &len, encryption_algorithm_names, encryption, plugin_name); |
94822086 MW |
861 | } |
862 | enumerator->destroy(enumerator); | |
16b6606e AS |
863 | fprintf(out, "\n integrity: "); |
864 | len = 13; | |
94822086 | 865 | enumerator = lib->crypto->create_signer_enumerator(lib->crypto); |
5932f41f | 866 | while (enumerator->enumerate(enumerator, &integrity, &plugin_name)) |
94822086 | 867 | { |
16b6606e | 868 | print_alg(out, &len, integrity_algorithm_names, integrity, plugin_name); |
94822086 MW |
869 | } |
870 | enumerator->destroy(enumerator); | |
16b6606e AS |
871 | fprintf(out, "\n aead: "); |
872 | len = 13; | |
9d49f79f | 873 | enumerator = lib->crypto->create_aead_enumerator(lib->crypto); |
5932f41f | 874 | while (enumerator->enumerate(enumerator, &encryption, &plugin_name)) |
9d49f79f | 875 | { |
16b6606e | 876 | print_alg(out, &len, encryption_algorithm_names, encryption, plugin_name); |
9d49f79f MW |
877 | } |
878 | enumerator->destroy(enumerator); | |
16b6606e AS |
879 | fprintf(out, "\n hasher: "); |
880 | len = 13; | |
94822086 | 881 | enumerator = lib->crypto->create_hasher_enumerator(lib->crypto); |
5932f41f | 882 | while (enumerator->enumerate(enumerator, &hash, &plugin_name)) |
94822086 | 883 | { |
16b6606e | 884 | print_alg(out, &len, hash_algorithm_names, hash, plugin_name); |
94822086 MW |
885 | } |
886 | enumerator->destroy(enumerator); | |
16b6606e AS |
887 | fprintf(out, "\n prf: "); |
888 | len = 13; | |
94822086 | 889 | enumerator = lib->crypto->create_prf_enumerator(lib->crypto); |
5932f41f | 890 | while (enumerator->enumerate(enumerator, &prf, &plugin_name)) |
94822086 | 891 | { |
16b6606e | 892 | print_alg(out, &len, pseudo_random_function_names, prf, plugin_name); |
94822086 MW |
893 | } |
894 | enumerator->destroy(enumerator); | |
04208ac5 AS |
895 | fprintf(out, "\n xof: "); |
896 | len = 13; | |
897 | enumerator = lib->crypto->create_xof_enumerator(lib->crypto); | |
898 | while (enumerator->enumerate(enumerator, &xof, &plugin_name)) | |
899 | { | |
900 | print_alg(out, &len, ext_out_function_names, xof, plugin_name); | |
901 | } | |
902 | enumerator->destroy(enumerator); | |
16b6606e AS |
903 | fprintf(out, "\n dh-group: "); |
904 | len = 13; | |
94822086 | 905 | enumerator = lib->crypto->create_dh_enumerator(lib->crypto); |
5932f41f | 906 | while (enumerator->enumerate(enumerator, &group, &plugin_name)) |
94822086 | 907 | { |
16b6606e | 908 | print_alg(out, &len, diffie_hellman_group_names, group, plugin_name); |
5932f41f AS |
909 | } |
910 | enumerator->destroy(enumerator); | |
16b6606e AS |
911 | fprintf(out, "\n random-gen:"); |
912 | len = 13; | |
5932f41f AS |
913 | enumerator = lib->crypto->create_rng_enumerator(lib->crypto); |
914 | while (enumerator->enumerate(enumerator, &quality, &plugin_name)) | |
915 | { | |
16b6606e | 916 | print_alg(out, &len, rng_quality_names, quality, plugin_name); |
94822086 MW |
917 | } |
918 | enumerator->destroy(enumerator); | |
5c162dd9 TB |
919 | fprintf(out, "\n nonce-gen: "); |
920 | len = 13; | |
921 | enumerator = lib->crypto->create_nonce_gen_enumerator(lib->crypto); | |
922 | while (enumerator->enumerate(enumerator, &plugin_name)) | |
923 | { | |
924 | print_alg(out, &len, NULL, 0, plugin_name); | |
925 | } | |
926 | enumerator->destroy(enumerator); | |
94822086 MW |
927 | fprintf(out, "\n"); |
928 | } | |
929 | ||
2d2ffa58 MW |
930 | /** |
931 | * List loaded plugin information | |
932 | */ | |
933 | static void list_plugins(FILE *out) | |
934 | { | |
935 | plugin_feature_t *features, *fp; | |
936 | enumerator_t *enumerator; | |
937 | linked_list_t *list; | |
938 | plugin_t *plugin; | |
939 | int count, i; | |
940 | bool loaded; | |
941 | char *str; | |
942 | ||
943 | fprintf(out, "\n"); | |
b21cfa93 AS |
944 | fprintf(out, "List of loaded Plugins:\n"); |
945 | fprintf(out, "\n"); | |
2d2ffa58 MW |
946 | |
947 | enumerator = lib->plugins->create_plugin_enumerator(lib->plugins); | |
948 | while (enumerator->enumerate(enumerator, &plugin, &list)) | |
949 | { | |
950 | fprintf(out, "%s:\n", plugin->get_name(plugin)); | |
951 | if (plugin->get_features) | |
952 | { | |
953 | count = plugin->get_features(plugin, &features); | |
954 | for (i = 0; i < count; i++) | |
955 | { | |
956 | str = plugin_feature_get_string(&features[i]); | |
957 | switch (features[i].kind) | |
958 | { | |
959 | case FEATURE_PROVIDE: | |
960 | fp = &features[i]; | |
2e4d110d | 961 | loaded = list->find_first(list, NULL, (void**)&fp); |
2d2ffa58 MW |
962 | fprintf(out, " %s%s\n", |
963 | str, loaded ? "" : " (not loaded)"); | |
964 | break; | |
965 | case FEATURE_DEPENDS: | |
966 | fprintf(out, " %s\n", str); | |
967 | break; | |
968 | case FEATURE_SDEPEND: | |
2ee11fd4 | 969 | fprintf(out, " %s (soft)\n", str); |
2d2ffa58 MW |
970 | break; |
971 | default: | |
972 | break; | |
973 | } | |
974 | free(str); | |
975 | } | |
976 | } | |
49d7a98f | 977 | list->destroy(list); |
2d2ffa58 MW |
978 | } |
979 | enumerator->destroy(enumerator); | |
980 | } | |
981 | ||
cb6be85c AS |
982 | METHOD(stroke_list_t, list, void, |
983 | private_stroke_list_t *this, stroke_msg_t *msg, FILE *out) | |
0b14fdb9 | 984 | { |
eafc0654 AS |
985 | linked_list_t *cert_list = NULL; |
986 | ||
02d43102 AS |
987 | cert_printer = certificate_printer_create(out, TRUE, msg->list.utc); |
988 | ||
d1cbe551 AS |
989 | if (msg->list.flags & LIST_PUBKEYS) |
990 | { | |
02d43102 | 991 | stroke_list_other_certs(CERT_TRUSTED_PUBKEY); |
d1cbe551 | 992 | } |
9a127590 AS |
993 | if (msg->list.flags & LIST_CERTS) |
994 | { | |
02d43102 | 995 | stroke_list_other_certs(CERT_GPG); |
9a127590 | 996 | } |
eafc0654 AS |
997 | if (msg->list.flags & (LIST_CERTS | LIST_CACERTS | LIST_OCSPCERTS | LIST_AACERTS)) |
998 | { | |
999 | cert_list = create_unique_cert_list(CERT_X509); | |
1000 | } | |
0b14fdb9 MW |
1001 | if (msg->list.flags & LIST_CERTS) |
1002 | { | |
02d43102 | 1003 | stroke_list_x509_certs(cert_list, X509_NONE); |
0b14fdb9 MW |
1004 | } |
1005 | if (msg->list.flags & LIST_CACERTS) | |
1006 | { | |
02d43102 | 1007 | stroke_list_x509_certs(cert_list, X509_CA); |
0b14fdb9 MW |
1008 | } |
1009 | if (msg->list.flags & LIST_OCSPCERTS) | |
1010 | { | |
02d43102 | 1011 | stroke_list_x509_certs(cert_list, X509_OCSP_SIGNER); |
0b14fdb9 MW |
1012 | } |
1013 | if (msg->list.flags & LIST_AACERTS) | |
1014 | { | |
02d43102 | 1015 | stroke_list_x509_certs(cert_list, X509_AA); |
0b14fdb9 | 1016 | } |
9a127590 AS |
1017 | DESTROY_OFFSET_IF(cert_list, offsetof(certificate_t, destroy)); |
1018 | ||
0b14fdb9 MW |
1019 | if (msg->list.flags & LIST_ACERTS) |
1020 | { | |
02d43102 | 1021 | stroke_list_other_certs(CERT_X509_AC); |
0b14fdb9 MW |
1022 | } |
1023 | if (msg->list.flags & LIST_CRLS) | |
1024 | { | |
02d43102 | 1025 | stroke_list_other_certs(CERT_X509_CRL); |
0b14fdb9 MW |
1026 | } |
1027 | if (msg->list.flags & LIST_OCSP) | |
1028 | { | |
02d43102 | 1029 | stroke_list_other_certs(CERT_X509_OCSP_RESPONSE); |
0b14fdb9 | 1030 | } |
94822086 MW |
1031 | if (msg->list.flags & LIST_ALGS) |
1032 | { | |
1033 | list_algs(out); | |
1034 | } | |
2d2ffa58 MW |
1035 | if (msg->list.flags & LIST_PLUGINS) |
1036 | { | |
1037 | list_plugins(out); | |
1038 | } | |
02d43102 AS |
1039 | cert_printer->destroy(cert_printer); |
1040 | cert_printer = NULL; | |
0b14fdb9 MW |
1041 | } |
1042 | ||
6b83549d MW |
1043 | /** |
1044 | * Print leases of a single pool | |
1045 | */ | |
1046 | static void pool_leases(private_stroke_list_t *this, FILE *out, char *pool, | |
1047 | host_t *address, u_int size, u_int online, u_int offline) | |
1048 | { | |
1049 | enumerator_t *enumerator; | |
1050 | identification_t *id; | |
1051 | host_t *lease; | |
1052 | bool on; | |
1053 | int found = 0; | |
7daf5226 | 1054 | |
9b9352c8 | 1055 | fprintf(out, "Leases in pool '%s', usage: %u/%u, %u online\n", |
6b83549d MW |
1056 | pool, online + offline, size, online); |
1057 | enumerator = this->attribute->create_lease_enumerator(this->attribute, pool); | |
1058 | while (enumerator && enumerator->enumerate(enumerator, &id, &lease, &on)) | |
1059 | { | |
1060 | if (!address || address->ip_equals(address, lease)) | |
1061 | { | |
d24a74c5 | 1062 | fprintf(out, " %15H %s '%Y'\n", |
6b83549d MW |
1063 | lease, on ? "online" : "offline", id); |
1064 | found++; | |
1065 | } | |
1066 | } | |
1067 | enumerator->destroy(enumerator); | |
1068 | if (!found) | |
1069 | { | |
1070 | fprintf(out, " no matching leases found\n"); | |
1071 | } | |
1072 | } | |
1073 | ||
cb6be85c AS |
1074 | METHOD(stroke_list_t, leases, void, |
1075 | private_stroke_list_t *this, stroke_msg_t *msg, FILE *out) | |
6b83549d MW |
1076 | { |
1077 | enumerator_t *enumerator; | |
1078 | u_int size, offline, online; | |
1079 | host_t *address = NULL; | |
1080 | char *pool; | |
1081 | int found = 0; | |
7daf5226 | 1082 | |
6b83549d MW |
1083 | if (msg->leases.address) |
1084 | { | |
1085 | address = host_create_from_string(msg->leases.address, 0); | |
1086 | } | |
7daf5226 | 1087 | |
6b83549d MW |
1088 | enumerator = this->attribute->create_pool_enumerator(this->attribute); |
1089 | while (enumerator->enumerate(enumerator, &pool, &size, &online, &offline)) | |
1090 | { | |
1091 | if (!msg->leases.pool || streq(msg->leases.pool, pool)) | |
1092 | { | |
1093 | pool_leases(this, out, pool, address, size, online, offline); | |
1094 | found++; | |
1095 | } | |
1096 | } | |
1097 | enumerator->destroy(enumerator); | |
1098 | if (!found) | |
1099 | { | |
1100 | if (msg->leases.pool) | |
1101 | { | |
1102 | fprintf(out, "pool '%s' not found\n", msg->leases.pool); | |
1103 | } | |
1104 | else | |
1105 | { | |
1106 | fprintf(out, "no pools found\n"); | |
1107 | } | |
1108 | } | |
1109 | DESTROY_IF(address); | |
1110 | } | |
1111 | ||
cb6be85c AS |
1112 | METHOD(stroke_list_t, destroy, void, |
1113 | private_stroke_list_t *this) | |
0b14fdb9 MW |
1114 | { |
1115 | free(this); | |
1116 | } | |
1117 | ||
1118 | /* | |
1119 | * see header file | |
1120 | */ | |
2e031965 | 1121 | stroke_list_t *stroke_list_create(stroke_attribute_t *attribute) |
0b14fdb9 | 1122 | { |
cb6be85c AS |
1123 | private_stroke_list_t *this; |
1124 | ||
1125 | INIT(this, | |
1126 | .public = { | |
cb6be85c AS |
1127 | .list = _list, |
1128 | .status = _status, | |
1129 | .leases = _leases, | |
1130 | .destroy = _destroy, | |
1131 | }, | |
1132 | .uptime = time_monotonic(NULL), | |
137035cc | 1133 | .swan = "strong", |
cb6be85c AS |
1134 | .attribute = attribute, |
1135 | ); | |
7daf5226 | 1136 | |
137035cc MW |
1137 | if (lib->settings->get_bool(lib->settings, |
1138 | "charon.i_dont_care_about_security_and_use_aggressive_mode_psk", FALSE)) | |
1139 | { | |
1140 | this->swan = "weak"; | |
1141 | } | |
1142 | ||
0b14fdb9 MW |
1143 | return &this->public; |
1144 | } |