1 /* Stroke for charon is the counterpart to whack from pluto
2 * Copyright (C) 2007 Tobias Brunner
3 * Copyright (C) 2006 Martin Willi
4 * Hochschule fuer Technik Rapperswil
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 #include <sys/types.h>
22 #include <sys/socket.h>
24 #include <sys/fcntl.h>
31 #include "stroke_msg.h"
32 #include "stroke_keywords.h"
39 static char* push_string(stroke_msg_t
*msg
, char *string
)
41 unsigned long string_start
= msg
->length
;
43 if (string
== NULL
|| msg
->length
+ strlen(string
) >= sizeof(stroke_msg_t
))
49 msg
->length
+= strlen(string
) + 1;
50 strcpy((char*)msg
+ string_start
, string
);
51 return (char*)string_start
;
55 static int send_stroke_msg (stroke_msg_t
*msg
)
57 struct sockaddr_un ctl_addr
= { AF_UNIX
, STROKE_SOCKET
};
62 msg
->output_verbosity
= 1; /* CONTROL */
64 sock
= socket(AF_UNIX
, SOCK_STREAM
, 0);
67 fprintf(stderr
, "Opening unix socket %s: %s\n", STROKE_SOCKET
, strerror(errno
));
70 if (connect(sock
, (struct sockaddr
*)&ctl_addr
,
71 offsetof(struct sockaddr_un
, sun_path
) + strlen(ctl_addr
.sun_path
)) < 0)
73 fprintf(stderr
, "Connect to socket failed: %s\n", strerror(errno
));
79 if (write(sock
, msg
, msg
->length
) != msg
->length
)
81 fprintf(stderr
, "writing to socket failed: %s\n", strerror(errno
));
86 while ((byte_count
= read(sock
, buffer
, sizeof(buffer
)-1)) > 0)
88 buffer
[byte_count
] = '\0';
93 fprintf(stderr
, "reading from socket failed: %s\n", strerror(errno
));
100 static int add_connection(char *name
,
101 char *my_id
, char *other_id
,
102 char *my_addr
, char *other_addr
,
103 char *my_nets
, char *other_nets
)
107 memset(&msg
, 0, sizeof(msg
));
108 msg
.length
= offsetof(stroke_msg_t
, buffer
);
109 msg
.type
= STR_ADD_CONN
;
111 msg
.add_conn
.name
= push_string(&msg
, name
);
112 msg
.add_conn
.ikev2
= 1;
113 msg
.add_conn
.auth_method
= 2;
114 msg
.add_conn
.mode
= 1;
115 msg
.add_conn
.mobike
= 1;
116 msg
.add_conn
.dpd
.action
= 1;
118 msg
.add_conn
.me
.id
= push_string(&msg
, my_id
);
119 msg
.add_conn
.me
.address
= push_string(&msg
, my_addr
);
120 msg
.add_conn
.me
.subnets
= push_string(&msg
, my_nets
);
121 msg
.add_conn
.me
.sendcert
= 1;
123 msg
.add_conn
.other
.id
= push_string(&msg
, other_id
);
124 msg
.add_conn
.other
.address
= push_string(&msg
, other_addr
);
125 msg
.add_conn
.other
.subnets
= push_string(&msg
, other_nets
);
126 msg
.add_conn
.other
.sendcert
= 1;
128 return send_stroke_msg(&msg
);
131 static int del_connection(char *name
)
135 msg
.length
= offsetof(stroke_msg_t
, buffer
);
136 msg
.type
= STR_DEL_CONN
;
137 msg
.initiate
.name
= push_string(&msg
, name
);
138 return send_stroke_msg(&msg
);
141 static int initiate_connection(char *name
)
145 msg
.length
= offsetof(stroke_msg_t
, buffer
);
146 msg
.type
= STR_INITIATE
;
147 msg
.initiate
.name
= push_string(&msg
, name
);
148 return send_stroke_msg(&msg
);
151 static int terminate_connection(char *name
)
155 msg
.type
= STR_TERMINATE
;
156 msg
.length
= offsetof(stroke_msg_t
, buffer
);
157 msg
.initiate
.name
= push_string(&msg
, name
);
158 return send_stroke_msg(&msg
);
161 static int terminate_connection_srcip(char *start
, char *end
)
165 msg
.type
= STR_TERMINATE_SRCIP
;
166 msg
.length
= offsetof(stroke_msg_t
, buffer
);
167 msg
.terminate_srcip
.start
= push_string(&msg
, start
);
168 msg
.terminate_srcip
.end
= push_string(&msg
, end
);
169 return send_stroke_msg(&msg
);
172 static int route_connection(char *name
)
176 msg
.type
= STR_ROUTE
;
177 msg
.length
= offsetof(stroke_msg_t
, buffer
);
178 msg
.route
.name
= push_string(&msg
, name
);
179 return send_stroke_msg(&msg
);
182 static int unroute_connection(char *name
)
186 msg
.type
= STR_UNROUTE
;
187 msg
.length
= offsetof(stroke_msg_t
, buffer
);
188 msg
.unroute
.name
= push_string(&msg
, name
);
189 return send_stroke_msg(&msg
);
192 static int show_status(stroke_keyword_t kw
, char *connection
)
196 msg
.type
= (kw
== STROKE_STATUS
)? STR_STATUS
:STR_STATUS_ALL
;
197 msg
.length
= offsetof(stroke_msg_t
, buffer
);
198 msg
.status
.name
= push_string(&msg
, connection
);
199 return send_stroke_msg(&msg
);
202 static int list_flags
[] = {
217 static int list(stroke_keyword_t kw
, int utc
)
222 msg
.length
= offsetof(stroke_msg_t
, buffer
);
224 msg
.list
.flags
= list_flags
[kw
- STROKE_LIST_FIRST
];
225 return send_stroke_msg(&msg
);
228 static int reread_flags
[] = {
238 static int reread(stroke_keyword_t kw
)
242 msg
.type
= STR_REREAD
;
243 msg
.length
= offsetof(stroke_msg_t
, buffer
);
244 msg
.reread
.flags
= reread_flags
[kw
- STROKE_REREAD_FIRST
];
245 return send_stroke_msg(&msg
);
248 static int purge_flags
[] = {
252 static int purge(stroke_keyword_t kw
)
256 msg
.type
= STR_PURGE
;
257 msg
.length
= offsetof(stroke_msg_t
, buffer
);
258 msg
.purge
.flags
= purge_flags
[kw
- STROKE_PURGE_FIRST
];
259 return send_stroke_msg(&msg
);
262 static int leases(stroke_keyword_t kw
, char *pool
, char *address
)
267 msg
.type
= STR_LEASES
;
268 msg
.length
= offsetof(stroke_msg_t
, buffer
);
269 msg
.leases
.pool
= push_string(&msg
, pool
);
270 msg
.leases
.address
= push_string(&msg
, address
);
271 return send_stroke_msg(&msg
);
274 static int set_loglevel(char *type
, u_int level
)
278 msg
.type
= STR_LOGLEVEL
;
279 msg
.length
= offsetof(stroke_msg_t
, buffer
);
280 msg
.loglevel
.type
= push_string(&msg
, type
);
281 msg
.loglevel
.level
= level
;
282 return send_stroke_msg(&msg
);
285 static void exit_error(char *error
)
289 fprintf(stderr
, "%s\n", error
);
294 static void exit_usage(char *error
)
297 printf(" Add a connection:\n");
298 printf(" stroke add NAME MY_ID OTHER_ID MY_ADDR OTHER_ADDR\\\n");
299 printf(" MY_NET OTHER_NET MY_NETBITS OTHER_NETBITS\n");
300 printf(" where: ID is any IKEv2 ID \n");
301 printf(" ADDR is a IPv4 address\n");
302 printf(" NET is a IPv4 subnet in CIDR notation\n");
303 printf(" Delete a connection:\n");
304 printf(" stroke delete NAME\n");
305 printf(" where: NAME is a connection name added with \"stroke add\"\n");
306 printf(" Initiate a connection:\n");
307 printf(" stroke up NAME\n");
308 printf(" where: NAME is a connection name added with \"stroke add\"\n");
309 printf(" Terminate a connection:\n");
310 printf(" stroke down NAME\n");
311 printf(" where: NAME is a connection name added with \"stroke add\"\n");
312 printf(" Terminate a connection by remote srcip:\n");
313 printf(" stroke down-srcip START [END]\n");
314 printf(" where: START and optional END define the clients source IP\n");
315 printf(" Set loglevel for a logging type:\n");
316 printf(" stroke loglevel TYPE LEVEL\n");
317 printf(" where: TYPE is any|dmn|mgr|ike|chd|job|cfg|knl|net|enc|lib\n");
318 printf(" LEVEL is -1|0|1|2|3|4\n");
319 printf(" Show connection status:\n");
320 printf(" stroke status\n");
321 printf(" Show list of authority and attribute certificates:\n");
322 printf(" stroke listcacerts|listocspcerts|listaacerts|listacerts\n");
323 printf(" Show list of end entity certificates, ca info records and crls:\n");
324 printf(" stroke listcerts|listcainfos|listcrls|listall\n");
325 printf(" Show list of supported algorithms:\n");
326 printf(" stroke listalgs\n");
327 printf(" Reload authority and attribute certificates:\n");
328 printf(" stroke rereadcacerts|rereadocspcerts|rereadaacerts|rereadacerts\n");
329 printf(" Reload secrets and crls:\n");
330 printf(" stroke rereadsecrets|rereadcrls|rereadall\n");
331 printf(" Purge ocsp cache entries:\n");
332 printf(" stroke purgeocsp\n");
333 printf(" Show leases of a pool:\n");
334 printf(" stroke leases [POOL [ADDRESS]]\n");
338 int main(int argc
, char *argv
[])
340 const stroke_token_t
*token
;
348 token
= in_word_set(argv
[1], strlen(argv
[1]));
352 exit_usage("unknown keyword");
360 exit_usage("\"add\" needs more parameters...");
362 res
= add_connection(argv
[2],
371 exit_usage("\"delete\" needs a connection name");
373 res
= del_connection(argv
[2]);
378 exit_usage("\"up\" needs a connection name");
380 res
= initiate_connection(argv
[2]);
385 exit_usage("\"down\" needs a connection name");
387 res
= terminate_connection(argv
[2]);
389 case STROKE_DOWN_SRCIP
:
392 exit_usage("\"down-srcip\" needs start and optional end address");
394 res
= terminate_connection_srcip(argv
[2], argc
> 3 ? argv
[3] : NULL
);
399 exit_usage("\"route\" needs a connection name");
401 res
= route_connection(argv
[2]);
406 exit_usage("\"unroute\" needs a connection name");
408 res
= unroute_connection(argv
[2]);
410 case STROKE_LOGLEVEL
:
413 exit_usage("\"logtype\" needs more parameters...");
415 res
= set_loglevel(argv
[2], atoi(argv
[3]));
418 case STROKE_STATUSALL
:
419 res
= show_status(token
->kw
, argc
> 2 ? argv
[2] : NULL
);
421 case STROKE_LIST_PUBKEYS
:
422 case STROKE_LIST_CERTS
:
423 case STROKE_LIST_CACERTS
:
424 case STROKE_LIST_OCSPCERTS
:
425 case STROKE_LIST_AACERTS
:
426 case STROKE_LIST_ACERTS
:
427 case STROKE_LIST_CAINFOS
:
428 case STROKE_LIST_CRLS
:
429 case STROKE_LIST_OCSP
:
430 case STROKE_LIST_ALGS
:
431 case STROKE_LIST_ALL
:
432 res
= list(token
->kw
, argc
> 2 && strcmp(argv
[2], "--utc") == 0);
434 case STROKE_REREAD_SECRETS
:
435 case STROKE_REREAD_CACERTS
:
436 case STROKE_REREAD_OCSPCERTS
:
437 case STROKE_REREAD_AACERTS
:
438 case STROKE_REREAD_ACERTS
:
439 case STROKE_REREAD_CRLS
:
440 case STROKE_REREAD_ALL
:
441 res
= reread(token
->kw
);
443 case STROKE_PURGE_OCSP
:
444 res
= purge(token
->kw
);
447 res
= leases(token
->kw
, argc
> 2 ? argv
[2] : NULL
,
448 argc
> 3 ? argv
[3] : NULL
);