2 * Copyright (C) 2014 Martin Willi
3 * Copyright (C) 2014 revosec AG
5 * Copyright (C) 2016 Andreas Steffen
6 * HSR Hochschule fuer Technik Rapperswil
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>.
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
25 #include <collections/hashtable.h>
28 * Free hashtable with contained strings
30 static void free_hashtable(hashtable_t
*hashtable
)
32 enumerator_t
*enumerator
;
35 enumerator
= hashtable
->create_enumerator(hashtable
);
36 while (enumerator
->enumerate(enumerator
, NULL
, &str
))
40 enumerator
->destroy(enumerator
);
42 hashtable
->destroy(hashtable
);
46 hashtable_t
*sa
, vici_res_t
*res
, char *name
, void *value
, int len
)
51 chunk
= chunk_create(value
, len
);
52 if (chunk_printable(chunk
, NULL
, ' '))
54 if (asprintf(&str
, "%.*s", len
, value
) >= 0)
56 free(sa
->put(sa
, name
, str
));
64 hashtable_t
*sa
, vici_res_t
*res
, char *name
, void *value
, int len
)
69 chunk
= chunk_create(value
, len
);
70 if (chunk_printable(chunk
, NULL
, ' '))
72 str
= sa
->get(sa
, name
);
73 if (asprintf(&str
, "%s%s%.*s",
74 str
?: "", str
? " " : "", len
, value
) >= 0)
76 free(sa
->put(sa
, name
, str
));
82 CALLBACK(children_sn
, int,
83 hashtable_t
*ike
, vici_res_t
*res
, char *name
)
86 char *mode
, *interface
, *priority
;
87 char *rekey_time
, *rekey_bytes
, *rekey_packets
, *dpd_action
, *dpd_delay
;
88 bool no_time
, no_bytes
, no_packets
, no_dpd
, or = FALSE
;
91 child
= hashtable_create(hashtable_hash_str
, hashtable_equals_str
, 1);
92 ret
= vici_parse_cb(res
, NULL
, values
, list
, child
);
95 mode
= child
->get(child
, "mode");
96 printf(" %s: %s, ", name
, mode
);
98 rekey_time
= child
->get(child
, "rekey_time");
99 rekey_bytes
= child
->get(child
, "rekey_bytes");
100 rekey_packets
= child
->get(child
, "rekey_packets");
101 dpd_action
= child
->get(child
, "dpd_action");
102 dpd_delay
= ike
->get(ike
, "dpd_delay");
104 no_time
= streq(rekey_time
, "0");
105 no_bytes
= streq(rekey_bytes
, "0");
106 no_packets
= streq(rekey_packets
, "0");
107 no_dpd
= streq(dpd_delay
, "0");
109 if (strcaseeq(mode
, "PASS") || strcaseeq(mode
, "DROP") ||
110 (no_time
&& no_bytes
&& no_packets
))
112 printf("no rekeying");
116 printf("rekeying every");
119 printf(" %ss", rekey_time
);
124 printf("%s %s bytes", or ? " or" : "", rekey_bytes
);
129 printf("%s %s packets", or ? " or" : "", rekey_packets
);
134 printf(", dpd action is %s", dpd_action
);
138 printf(" local: %s\n", child
->get(child
, "local-ts"));
139 printf(" remote: %s\n", child
->get(child
, "remote-ts"));
141 interface
= child
->get(child
, "interface");
144 printf(" interface: %s\n", interface
);
147 priority
= child
->get(child
, "priority");
150 printf(" priority: %s\n", priority
);
153 free_hashtable(child
);
157 CALLBACK(conn_sn
, int,
158 hashtable_t
*ike
, vici_res_t
*res
, char *name
)
162 if (streq(name
, "children"))
164 return vici_parse_cb(res
, children_sn
, NULL
, NULL
, ike
);
166 if (strpfx(name
, "local") || strpfx(name
, "remote"))
171 auth
= hashtable_create(hashtable_hash_str
, hashtable_equals_str
, 1);
172 ret
= vici_parse_cb(res
, NULL
, values
, list
, auth
);
175 class = auth
->get(auth
, "class") ?: "unspecified";
176 if (strcaseeq(class, "EAP"))
178 class = auth
->get(auth
, "eap-type") ?: class;
180 printf(" %s %s authentication:\n",
181 strpfx(name
, "local") ? "local" : "remote", class);
182 if (auth
->get(auth
, "id"))
184 printf(" id: %s\n", auth
->get(auth
, "id"));
186 if (auth
->get(auth
, "eap_id"))
188 printf(" eap_id: %s\n", auth
->get(auth
, "eap_id"));
190 if (auth
->get(auth
, "xauth_id"))
192 printf(" xauth_id: %s\n", auth
->get(auth
, "xauth_id"));
194 if (auth
->get(auth
, "aaa_id"))
196 printf(" aaa_id: %s\n", auth
->get(auth
, "aaa_id"));
198 if (auth
->get(auth
, "groups"))
200 printf(" groups: %s\n", auth
->get(auth
, "groups"));
202 if (auth
->get(auth
, "certs"))
204 printf(" certs: %s\n", auth
->get(auth
, "certs"));
206 if (auth
->get(auth
, "cacerts"))
208 printf(" cacerts: %s\n", auth
->get(auth
, "cacerts"));
211 free_hashtable(auth
);
216 CALLBACK(conn_list
, int,
217 hashtable_t
*sa
, vici_res_t
*res
, char *name
, void *value
, int len
)
219 if (chunk_printable(chunk_create(value
, len
), NULL
, ' '))
221 if (streq(name
, "local_addrs"))
223 printf(" local: %.*s\n", len
, value
);
225 if (streq(name
, "remote_addrs"))
227 printf(" remote: %.*s\n", len
, value
);
234 void *null
, vici_res_t
*res
, char *name
)
237 char *version
, *reauth_time
, *rekey_time
, *dpd_delay
;
240 version
= vici_find_str(res
, "", "%s.version", name
);
241 reauth_time
= vici_find_str(res
, "0", "%s.reauth_time", name
);
242 rekey_time
= vici_find_str(res
, "0", "%s.rekey_time", name
);
243 dpd_delay
= vici_find_str(res
, "0", "%s.dpd_delay", name
);
245 ike
= hashtable_create(hashtable_hash_str
, hashtable_equals_str
, 1);
246 free(ike
->put(ike
,"dpd_delay", strdup(dpd_delay
)));
248 printf("%s: %s, ", name
, version
);
249 if (streq(version
, "IKEv1"))
251 if (streq(reauth_time
, "0"))
253 reauth_time
= rekey_time
;
256 if (streq(reauth_time
, "0"))
258 printf("no reauthentication");
262 printf("reauthentication every %ss", reauth_time
);
264 if (!streq(version
, "IKEv1"))
266 if (streq(rekey_time
, "0"))
268 printf(", no rekeying");
272 printf(", rekeying every %ss", rekey_time
);
275 if (!streq(dpd_delay
, "0"))
277 printf(", dpd delay %ss", dpd_delay
);
281 ret
= vici_parse_cb(res
, conn_sn
, NULL
, conn_list
, ike
);
286 CALLBACK(list_cb
, void,
287 command_format_options_t
*format
, char *name
, vici_res_t
*res
)
289 if (*format
& COMMAND_FORMAT_RAW
)
291 vici_dump(res
, "list-conn event", *format
& COMMAND_FORMAT_PRETTY
,
296 if (vici_parse_cb(res
, conns
, NULL
, NULL
, NULL
) != 0)
298 fprintf(stderr
, "parsing conn event failed: %s\n", strerror(errno
));
303 static int list_conns(vici_conn_t
*conn
)
307 command_format_options_t format
= COMMAND_FORMAT_NONE
;
313 switch (command_getopt(&arg
))
316 return command_usage(NULL
);
318 format
|= COMMAND_FORMAT_PRETTY
;
319 /* fall through to raw */
321 format
|= COMMAND_FORMAT_RAW
;
326 return command_usage("invalid --list-conns option");
330 if (vici_register(conn
, "list-conn", list_cb
, &format
) != 0)
333 fprintf(stderr
, "registering for connections failed: %s\n",
337 req
= vici_begin("list-conns");
338 res
= vici_submit(req
, conn
);
342 fprintf(stderr
, "list-conns request failed: %s\n", strerror(errno
));
345 if (format
& COMMAND_FORMAT_RAW
)
347 vici_dump(res
, "list-conns reply", format
& COMMAND_FORMAT_PRETTY
,
355 * Register the command.
357 static void __attribute__ ((constructor
))reg()
359 command_register((command_t
) {
360 list_conns
, 'L', "list-conns", "list loaded configurations",
361 {"[--raw|--pretty]"},
363 {"help", 'h', 0, "show usage information"},
364 {"raw", 'r', 0, "dump raw response message"},
365 {"pretty", 'P', 0, "dump raw response message in pretty print"},