]> git.ipfire.org Git - thirdparty/strongswan.git/blame - src/swanctl/commands/list_conns.c
testing: uses xauth_id in swanctl/xauth-rsa scenario
[thirdparty/strongswan.git] / src / swanctl / commands / list_conns.c
CommitLineData
51bdc1f3
MW
1/*
2 * Copyright (C) 2014 Martin Willi
3 * Copyright (C) 2014 revosec AG
4 *
afcd4661
AS
5 * Copyright (C) 2016 Andreas Steffen
6 * HSR Hochschule fuer Technik Rapperswil
7 *
51bdc1f3
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.
17 */
18
19#define _GNU_SOURCE
20#include <stdio.h>
21#include <errno.h>
22
23#include "command.h"
24
25#include <collections/hashtable.h>
26
27/**
28 * Free hashtable with contained strings
29 */
30static void free_hashtable(hashtable_t *hashtable)
31{
32 enumerator_t *enumerator;
33 char *str;
34
35 enumerator = hashtable->create_enumerator(hashtable);
36 while (enumerator->enumerate(enumerator, NULL, &str))
37 {
38 free(str);
39 }
40 enumerator->destroy(enumerator);
41
42 hashtable->destroy(hashtable);
43}
44
45CALLBACK(values, int,
46 hashtable_t *sa, vici_res_t *res, char *name, void *value, int len)
47{
48 chunk_t chunk;
49 char *str;
50
51 chunk = chunk_create(value, len);
52 if (chunk_printable(chunk, NULL, ' '))
53 {
54 if (asprintf(&str, "%.*s", len, value) >= 0)
55 {
56 free(sa->put(sa, name, str));
57 }
58 }
59 return 0;
60}
61
62
63CALLBACK(list, int,
64 hashtable_t *sa, vici_res_t *res, char *name, void *value, int len)
65{
66 chunk_t chunk;
67 char *str;
68
69 chunk = chunk_create(value, len);
70 if (chunk_printable(chunk, NULL, ' '))
71 {
72 str = sa->get(sa, name);
73 if (asprintf(&str, "%s%s%.*s",
74 str ?: "", str ? " " : "", len, value) >= 0)
75 {
76 free(sa->put(sa, name, str));
77 }
78 }
79 return 0;
80}
81
82CALLBACK(children_sn, int,
83 hashtable_t *ike, vici_res_t *res, char *name)
84{
85 hashtable_t *child;
e9704e90 86 char *interface, *priority;
51bdc1f3
MW
87 int ret;
88
89 child = hashtable_create(hashtable_hash_str, hashtable_equals_str, 1);
90 ret = vici_parse_cb(res, NULL, values, list, child);
91 if (ret == 0)
92 {
93 printf(" %s: %s\n", name, child->get(child, "mode"));
94 printf(" local: %s\n", child->get(child, "local-ts"));
95 printf(" remote: %s\n", child->get(child, "remote-ts"));
e9704e90
AS
96
97 interface = child->get(child, "interface");
98 if (interface)
99 {
100 printf(" interface: %s\n", interface);
101 }
102
103 priority = child->get(child, "priority");
104 if (priority)
105 {
106 printf(" priority: %s\n", priority);
107 }
51bdc1f3
MW
108 }
109 free_hashtable(child);
110 return ret;
111}
112
113CALLBACK(conn_sn, int,
114 hashtable_t *ike, vici_res_t *res, char *name)
115{
116 int ret = 0;
117
118 if (streq(name, "children"))
119 {
120 return vici_parse_cb(res, children_sn, NULL, NULL, NULL);
121 }
94bb26fa 122 if (strpfx(name, "local") || strpfx(name, "remote"))
51bdc1f3
MW
123 {
124 hashtable_t *auth;
afcd4661 125 char *class;
51bdc1f3
MW
126
127 auth = hashtable_create(hashtable_hash_str, hashtable_equals_str, 1);
128 ret = vici_parse_cb(res, NULL, values, list, auth);
129 if (ret == 0)
130 {
afcd4661
AS
131 class = auth->get(auth, "class") ?: "unspecified";
132 if (strcaseeq(class, "EAP"))
133 {
134 class = auth->get(auth, "eap-type") ?: class;
135 }
51bdc1f3 136 printf(" %s %s authentication:\n",
afcd4661 137 strpfx(name, "local") ? "local" : "remote", class);
51bdc1f3
MW
138 {
139 printf(" id: %s\n", auth->get(auth, "id"));
140 }
141 if (auth->get(auth, "groups"))
142 {
143 printf(" groups: %s\n", auth->get(auth, "groups"));
144 }
145 if (auth->get(auth, "certs"))
146 {
147 printf(" certs: %s\n", auth->get(auth, "certs"));
148 }
149 if (auth->get(auth, "cacerts"))
150 {
151 printf(" cacerts: %s\n", auth->get(auth, "cacerts"));
152 }
153 }
154 free_hashtable(auth);
155 }
156 return ret;
157}
158
a2875525
MW
159CALLBACK(conn_list, int,
160 hashtable_t *sa, vici_res_t *res, char *name, void *value, int len)
161{
162 if (chunk_printable(chunk_create(value, len), NULL, ' '))
163 {
164 if (streq(name, "local_addrs"))
165 {
166 printf(" local: %.*s\n", len, value);
167 }
168 if (streq(name, "remote_addrs"))
169 {
170 printf(" remote: %.*s\n", len, value);
171 }
172 }
173 return 0;
174}
175
51bdc1f3
MW
176CALLBACK(conns, int,
177 void *null, vici_res_t *res, char *name)
178{
179 printf("%s: %s\n", name, vici_find_str(res, "", "%s.version", name));
180
a2875525 181 return vici_parse_cb(res, conn_sn, NULL, conn_list, NULL);
51bdc1f3
MW
182}
183
184CALLBACK(list_cb, void,
dacb75f5 185 command_format_options_t *format, char *name, vici_res_t *res)
51bdc1f3 186{
dacb75f5 187 if (*format & COMMAND_FORMAT_RAW)
51bdc1f3 188 {
dacb75f5
AS
189 vici_dump(res, "list-conn event", *format & COMMAND_FORMAT_PRETTY,
190 stdout);
51bdc1f3
MW
191 }
192 else
193 {
194 if (vici_parse_cb(res, conns, NULL, NULL, NULL) != 0)
195 {
196 fprintf(stderr, "parsing conn event failed: %s\n", strerror(errno));
197 }
198 }
199}
200
201static int list_conns(vici_conn_t *conn)
202{
203 vici_req_t *req;
204 vici_res_t *res;
dacb75f5 205 command_format_options_t format = COMMAND_FORMAT_NONE;
51bdc1f3 206 char *arg;
67f9f09d 207 int ret;
51bdc1f3
MW
208
209 while (TRUE)
210 {
211 switch (command_getopt(&arg))
212 {
213 case 'h':
214 return command_usage(NULL);
dacb75f5
AS
215 case 'P':
216 format |= COMMAND_FORMAT_PRETTY;
217 /* fall through to raw */
51bdc1f3 218 case 'r':
dacb75f5 219 format |= COMMAND_FORMAT_RAW;
51bdc1f3
MW
220 continue;
221 case EOF:
222 break;
223 default:
224 return command_usage("invalid --list-conns option");
225 }
226 break;
227 }
dacb75f5 228 if (vici_register(conn, "list-conn", list_cb, &format) != 0)
51bdc1f3 229 {
67f9f09d 230 ret = errno;
51bdc1f3
MW
231 fprintf(stderr, "registering for connections failed: %s\n",
232 strerror(errno));
67f9f09d 233 return ret;
51bdc1f3
MW
234 }
235 req = vici_begin("list-conns");
236 res = vici_submit(req, conn);
237 if (!res)
238 {
67f9f09d 239 ret = errno;
51bdc1f3 240 fprintf(stderr, "list-conns request failed: %s\n", strerror(errno));
67f9f09d 241 return ret;
51bdc1f3 242 }
dacb75f5 243 if (format & COMMAND_FORMAT_RAW)
51bdc1f3 244 {
dacb75f5
AS
245 vici_dump(res, "list-conns reply", format & COMMAND_FORMAT_PRETTY,
246 stdout);
51bdc1f3
MW
247 }
248 vici_free_res(res);
249 return 0;
250}
251
252/**
253 * Register the command.
254 */
255static void __attribute__ ((constructor))reg()
256{
257 command_register((command_t) {
258 list_conns, 'L', "list-conns", "list loaded configurations",
dacb75f5 259 {"[--raw|--pretty]"},
51bdc1f3
MW
260 {
261 {"help", 'h', 0, "show usage information"},
262 {"raw", 'r', 0, "dump raw response message"},
dacb75f5 263 {"pretty", 'P', 0, "dump raw response message in pretty print"},
51bdc1f3
MW
264 }
265 });
266}