- add connection names to connections
[strongswan.git] / Source / patches / strongswan-2.6.4.patch
1 diff -Naur strongswan-2.6.4/Makefile.inc strongswan-2.6.4-charon/Makefile.inc
2 --- strongswan-2.6.4/Makefile.inc       2006-01-25 18:23:15.000000000 +0100
3 +++ strongswan-2.6.4-charon/Makefile.inc        2006-04-19 14:22:26.000000000 +0200
4 @@ -84,6 +84,8 @@
5  FINALLIBDIR=$(INC_USRLOCAL)/lib/ipsec
6  LIBDIR=$(DESTDIR)$(FINALLIBDIR)
7  
8 +# sharedlibdir is where shared libraries go
9 +SHAREDLIBDIR=$(DESTDIR)$(INC_USRLOCAL)/lib
10  
11  # where the appropriate manpage tree is located
12  # location within INC_USRLOCAL
13 @@ -284,6 +286,9 @@
14  # include PKCS11-based smartcard support
15  USE_SMARTCARD?=false
16  
17 +# support IKEv2 via charon
18 +USE_IKEV2?=true
19 +
20  # Default PKCS11 library
21  # Uncomment this line if using OpenSC <= 0.9.6
22  PKCS11_DEFAULT_LIB=\"/usr/lib/pkcs11/opensc-pkcs11.so\"
23 diff -Naur strongswan-2.6.4/programs/Makefile strongswan-2.6.4-charon/programs/Makefile
24 --- strongswan-2.6.4/programs/Makefile  2006-01-01 16:14:08.000000000 +0100
25 +++ strongswan-2.6.4-charon/programs/Makefile   2006-04-19 14:22:26.000000000 +0200
26 @@ -32,6 +32,10 @@
27  SUBDIRS+=showpolicy
28  endif
29  
30 +ifeq ($(USE_IKEV2),true)
31 +SUBDIRS+=charon
32 +endif
33 +
34  def:
35         @echo "Please read doc/intro.html or INSTALL before running make"
36         @false
37 diff -Naur strongswan-2.6.4/programs/ipsec/ipsec.in strongswan-2.6.4-charon/programs/ipsec/ipsec.in
38 --- strongswan-2.6.4/programs/ipsec/ipsec.in    2006-03-09 21:09:33.000000000 +0100
39 +++ strongswan-2.6.4-charon/programs/ipsec/ipsec.in     2006-04-19 14:22:26.000000000 +0200
40 @@ -123,6 +123,10 @@
41  down)
42         shift
43         $IPSEC_EXECDIR/whack --name "$1" --terminate
44 +       if test -e $IPSEC_EXECDIR/stroke
45 +       then
46 +           $IPSEC_EXECDIR/stroke down "$1"
47 +       fi
48         exit 0
49         ;;
50  listalgs|listpubkeys|listcerts|listcacerts|\
51 @@ -134,6 +138,10 @@
52         op="$1"
53         shift
54          $IPSEC_EXECDIR/whack "$@" "--$op"
55 +       if test -e $IPSEC_EXECDIR/stroke
56 +       then
57 +            $IPSEC_EXECDIR/stroke "$op"
58 +        fi
59         exit 0
60         ;;
61  ready)
62 @@ -180,8 +188,16 @@
63         if test $# -eq 0
64         then
65             $IPSEC_EXECDIR/whack "--$op"
66 +           if test -e $IPSEC_EXECDIR/stroke
67 +           then
68 +               $IPSEC_EXECDIR/stroke "$op"
69 +           fi
70         else
71             $IPSEC_EXECDIR/whack --name "$1" "--$op"
72 +           if test -e $IPSEC_EXECDIR/stroke
73 +           then
74 +               $IPSEC_EXECDIR/stroke "$op" "$1"
75 +           fi
76         fi
77         exit 0
78         ;;
79 @@ -198,6 +214,10 @@
80  up)
81         shift
82         $IPSEC_EXECDIR/whack --name "$1" --initiate
83 +       if test -e $IPSEC_EXECDIR/stroke
84 +       then
85 +           $IPSEC_EXECDIR/stroke up "$1"
86 +       fi
87         exit 0
88         ;;
89  update)
90 diff -Naur strongswan-2.6.4/programs/pluto/Makefile strongswan-2.6.4-charon/programs/pluto/Makefile
91 --- strongswan-2.6.4/programs/pluto/Makefile    2006-01-25 18:22:19.000000000 +0100
92 +++ strongswan-2.6.4-charon/programs/pluto/Makefile     2006-04-19 14:22:26.000000000 +0200
93 @@ -170,6 +170,11 @@
94    LIBSPLUTO+= -ldl
95  endif
96  
97 +# enable IKEv2 support
98 +ifeq ($(USE_IKEV2),true)
99 +  DEFINES+= -DIKEV2
100 +endif
101 +
102  # This compile option activates the leak detective
103  ifeq ($(USE_LEAK_DETECTIVE),true)
104    DEFINES+= -DLEAK_DETECTIVE
105 diff -Naur strongswan-2.6.4/programs/pluto/demux.c strongswan-2.6.4-charon/programs/pluto/demux.c
106 --- strongswan-2.6.4/programs/pluto/demux.c     2005-02-18 22:08:59.000000000 +0100
107 +++ strongswan-2.6.4-charon/programs/pluto/demux.c      2006-04-19 14:22:26.000000000 +0200
108 @@ -1229,6 +1229,15 @@
109         if (md->packet_pbs.roof - md->packet_pbs.cur >= (ptrdiff_t)isakmp_hdr_desc.size)
110         {
111             struct isakmp_hdr *hdr = (struct isakmp_hdr *)md->packet_pbs.cur;
112 +#ifdef IKEV2
113 +           if ((hdr->isa_version >> ISA_MAJ_SHIFT) == 0x2 &&
114 +                       (hdr->isa_version & ISA_MIN_MASK) == 0x0)
115 +           {
116 +               /* IKEv2 is handled from charon, ignore */
117 +               return;
118 +           }
119 +           else 
120 +#endif /* IKEV2 */
121             if ((hdr->isa_version >> ISA_MAJ_SHIFT) != ISAKMP_MAJOR_VERSION)
122             {
123                 SEND_NOTIFICATION(INVALID_MAJOR_VERSION);
124 diff -Naur strongswan-2.6.4/programs/starter/Makefile strongswan-2.6.4-charon/programs/starter/Makefile
125 --- strongswan-2.6.4/programs/starter/Makefile  2006-02-17 20:34:02.000000000 +0100
126 +++ strongswan-2.6.4-charon/programs/starter/Makefile   2006-04-19 14:22:26.000000000 +0200
127 @@ -34,6 +34,11 @@
128    DEFINES+= -DLEAK_DETECTIVE
129  endif
130  
131 +# Enable charon support
132 +ifeq ($(USE_IKEV2),true)
133 +  DEFINES+= -DIKEV2
134 +endif
135 +
136  INCLUDES=-I${FREESWANDIR}/linux/include
137  CFLAGS=$(DEFINES) $(INCLUDES) -Wall
138  CFLAGS+=-DIPSEC_EXECDIR=\"${FINALLIBEXECDIR}\" -DIPSEC_CONFDDIR=\"${FINALCONFDDIR}\"
139 @@ -46,6 +51,11 @@
140       starterwhack.o klips.o netkey.o interfaces.o exec.o cmp.o confread.o \
141       loglite.o ${PLUTO_OBJS}
142  
143 +# Build charon-only objs
144 +ifeq ($(USE_IKEV2),true)
145 +  OBJS+= invokecharon.o starterstroke.o
146 +endif
147 +
148  DISTSRC=$(OBJS:.o=.c)
149  DISTSRC+=cmp.h confread.h confwrite.h exec.h files.h interfaces.h klips.h netkey.h
150  DISTSRC+=parser.h args.h invokepluto.h starterwhack.h keywords.h keywords.txt
151 diff -Naur strongswan-2.6.4/programs/starter/args.c strongswan-2.6.4-charon/programs/starter/args.c
152 --- strongswan-2.6.4/programs/starter/args.c    2006-03-10 21:37:10.000000000 +0100
153 +++ strongswan-2.6.4-charon/programs/starter/args.c     2006-04-19 14:22:26.000000000 +0200
154 @@ -86,6 +86,10 @@
155  
156  static const char *LST_keyexchange[] = {
157      "ike",
158 +#ifdef IKEV2
159 +    "ikev1",
160 +    "ikev2",
161 +#endif /* IKEV2 */
162       NULL
163  };
164  
165 diff -Naur strongswan-2.6.4/programs/starter/files.h strongswan-2.6.4-charon/programs/starter/files.h
166 --- strongswan-2.6.4/programs/starter/files.h   2006-02-04 19:52:58.000000000 +0100
167 +++ strongswan-2.6.4-charon/programs/starter/files.h    2006-04-19 14:22:26.000000000 +0200
168 @@ -37,8 +37,15 @@
169  #define SECRETS_FILE   IPSEC_CONFDIR"/ipsec.secrets"
170  
171  #define PLUTO_CMD       IPSEC_EXECDIR"/pluto"
172 -#define CTL_FILE        DEFAULT_CTLBASE CTL_SUFFIX
173 -#define PID_FILE        DEFAULT_CTLBASE PID_SUFFIX
174 +#define PLUTO_CTL_FILE  DEFAULT_CTLBASE CTL_SUFFIX
175 +#define PLUTO_PID_FILE  DEFAULT_CTLBASE PID_SUFFIX
176 +
177 +#ifdef IKEV2
178 +#define CHARON_CMD             IPSEC_EXECDIR"/charon"
179 +#define CHARON_BASE            "/var/run/charon"
180 +#define CHARON_CTL_FILE CHARON_BASE CTL_SUFFIX
181 +#define CHARON_PID_FILE CHARON_BASE PID_SUFFIX
182 +#endif /* IKEV2 */
183  
184  #define DYNIP_DIR       "/var/run/dynip"
185  #define INFO_FILE       "/var/run/ipsec.info"
186 diff -Naur strongswan-2.6.4/programs/starter/invokecharon.c strongswan-2.6.4-charon/programs/starter/invokecharon.c
187 --- strongswan-2.6.4/programs/starter/invokecharon.c    1970-01-01 01:00:00.000000000 +0100
188 +++ strongswan-2.6.4-charon/programs/starter/invokecharon.c     2006-04-20 08:14:25.000000000 +0200
189 @@ -0,0 +1,174 @@
190 +/* strongSwan charon launcher
191 + * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
192 + * Copyright (C) 2006 Martin Willi - Hochschule fuer Technik Rapperswil
193 + *
194 + * Ported from invokepluto.c to fit charons needs.
195 + *
196 + * This program is free software; you can redistribute it and/or modify it
197 + * under the terms of the GNU General Public License as published by the
198 + * Free Software Foundation; either version 2 of the License, or (at your
199 + * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
200 + *
201 + * This program is distributed in the hope that it will be useful, but
202 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
203 + * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
204 + * for more details.
205 + *
206 + * RCSID $Id: invokecharon.c $
207 + */
208 +
209 +#include <sys/types.h>
210 +#include <sys/stat.h>
211 +#include <unistd.h>
212 +#include <signal.h>
213 +#include <string.h>
214 +#include <stdlib.h>
215 +#include <errno.h>
216 +
217 +#include <freeswan.h>
218 +
219 +#include "../pluto/constants.h"
220 +#include "../pluto/defs.h"
221 +#include "../pluto/log.h"
222 +
223 +#include "confread.h"
224 +#include "invokecharon.h"
225 +#include "files.h"
226 +
227 +static int _charon_pid = 0;
228 +static int _stop_requested;
229 +
230 +pid_t
231 +starter_charon_pid(void)
232 +{
233 +    return _charon_pid;
234 +}
235 +
236 +void
237 +starter_charon_sigchild(pid_t pid)
238 +{
239 +       if (pid == _charon_pid)
240 +    {
241 +               _charon_pid = 0;
242 +       if (!_stop_requested)
243 +       {
244 +           plog("charon has died -- restart scheduled (%dsec)"
245 +               , CHARON_RESTART_DELAY);
246 +           alarm(CHARON_RESTART_DELAY);   // restart in 5 sec
247 +       }
248 +       unlink(CHARON_PID_FILE);
249 +    }
250 +}
251 +
252 +int
253 +starter_stop_charon (void)
254 +{
255 +    pid_t pid;
256 +    int i;
257 +
258 +    pid = _charon_pid;
259 +    if (pid)
260 +    {
261 +       _stop_requested = 1;
262 +
263 +       /* be more and more aggressive */
264 +       for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
265 +       {
266 +               if (i == 0)
267 +                       kill(pid, SIGINT);
268 +           else if (i < 10)
269 +                       kill(pid, SIGTERM);
270 +           else
271 +                       kill(pid, SIGKILL);
272 +           usleep(20000);
273 +       }
274 +       if (_charon_pid == 0)
275 +           return 0;
276 +       plog("starter_stop_charon(): can't stop charon !!!");
277 +       return -1;
278 +    }
279 +    else
280 +    {
281 +       plog("stater_stop_charon(): charon is not started...");
282 +    }
283 +    return -1;
284 +}
285 +
286 +
287 +int
288 +starter_start_charon (starter_config_t *cfg, bool debug)
289 +{
290 +    int pid, i;
291 +    struct stat stb;
292 +    int argc = 1;
293 +    char *arg[] = {
294 +       CHARON_CMD, NULL, NULL,
295 +    };
296 +
297 +    if (!debug)
298 +    {
299 +       arg[argc++] = "--use-syslog";
300 +    }
301 +       
302 +    if (_charon_pid)
303 +    {
304 +       plog("starter_start_charon(): charon already started...");
305 +       return -1;
306 +    }
307 +    else
308 +    {
309 +       unlink(CHARON_CTL_FILE);
310 +       _stop_requested = 0;
311 +
312 +       pid = fork();
313 +       switch (pid)
314 +       {
315 +       case -1:
316 +           plog("can't fork(): %s", strerror(errno));
317 +           return -1;
318 +       case 0:
319 +           /* child */
320 +           setsid();
321 +           sigprocmask(SIG_SETMASK, 0, NULL);
322 +           execv(arg[0], arg);
323 +           plog("can't execv(%s,...): %s", arg[0], strerror(errno));
324 +           exit(1);
325 +       default:
326 +           /* father */
327 +               _charon_pid = pid;
328 +               for (i = 0; i < 50 && _charon_pid; i++)
329 +           {
330 +               /* wait for charon */
331 +               usleep(20000);
332 +               if (stat(CHARON_PID_FILE, &stb) == 0)
333 +               {
334 +                   DBG(DBG_CONTROL,
335 +                       DBG_log("charon (%d) started", _charon_pid)
336 +                   )
337 +                   return 0;
338 +               }
339 +           }
340 +           if (_charon_pid)
341 +           {
342 +               /* If charon is started but with no ctl file, stop it */
343 +               plog("charon too long to start... - kill kill");
344 +               for (i = 0; i < 20 && (pid = _charon_pid) != 0; i++)
345 +               {
346 +                       if (i == 0)
347 +                       kill(pid, SIGINT);
348 +                   else if (i < 10)
349 +                       kill(pid, SIGTERM);
350 +                   else
351 +                       kill(pid, SIGKILL);
352 +                   usleep(20000);
353 +               }
354 +           }
355 +           else
356 +           {
357 +               plog("charon refused to be started");
358 +           }
359 +           return -1;
360 +       }
361 +    }
362 +    return -1;
363 +}
364 diff -Naur strongswan-2.6.4/programs/starter/invokecharon.h strongswan-2.6.4-charon/programs/starter/invokecharon.h
365 --- strongswan-2.6.4/programs/starter/invokecharon.h    1970-01-01 01:00:00.000000000 +0100
366 +++ strongswan-2.6.4-charon/programs/starter/invokecharon.h     2006-04-19 14:22:26.000000000 +0200
367 @@ -0,0 +1,31 @@
368 +/* strongSwan charon launcher
369 + * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
370 + * Copyright (C) 2006 Martin Willi - Hochschule fuer Technik Rapperswil
371 + *
372 + * Ported from invokepluto.h to fit charons needs.
373 + *
374 + * This program is free software; you can redistribute it and/or modify it
375 + * under the terms of the GNU General Public License as published by the
376 + * Free Software Foundation; either version 2 of the License, or (at your
377 + * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
378 + *
379 + * This program is distributed in the hope that it will be useful, but
380 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
381 + * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
382 + * for more details.
383 + *
384 + * RCSID $Id: invokecharon.h $
385 + */
386 +
387 +#ifndef _STARTER_CHARON_H_
388 +#define _STARTER_CHARON_H_
389 +
390 +#define CHARON_RESTART_DELAY    5
391 +
392 +extern void starter_charon_sigchild (pid_t pid);
393 +extern pid_t starter_charon_pid (void);
394 +extern int starter_stop_charon (void);
395 +extern int starter_start_charon(struct starter_config *cfg, bool debug);
396 +
397 +#endif /* _STARTER_CHARON_H_ */
398 +
399 diff -Naur strongswan-2.6.4/programs/starter/invokepluto.c strongswan-2.6.4-charon/programs/starter/invokepluto.c
400 --- strongswan-2.6.4/programs/starter/invokepluto.c     2006-02-17 22:41:50.000000000 +0100
401 +++ strongswan-2.6.4-charon/programs/starter/invokepluto.c      2006-04-19 14:22:26.000000000 +0200
402 @@ -54,7 +54,7 @@
403                 , PLUTO_RESTART_DELAY);
404             alarm(PLUTO_RESTART_DELAY);   // restart in 5 sec
405         }
406 -       unlink(PID_FILE);
407 +       unlink(PLUTO_PID_FILE);
408      }
409  }
410  
411 @@ -203,7 +203,7 @@
412      }
413      else
414      {
415 -       unlink(CTL_FILE);
416 +       unlink(PLUTO_CTL_FILE);
417         _stop_requested = 0;
418  
419         if (cfg->setup.prepluto)
420 @@ -252,7 +252,7 @@
421             {
422                 /* wait for pluto */
423                 usleep(20000);
424 -               if (stat(CTL_FILE, &stb) == 0)
425 +               if (stat(PLUTO_CTL_FILE, &stb) == 0)
426                 {
427                     DBG(DBG_CONTROL,
428                         DBG_log("pluto (%d) started", _pluto_pid)
429 diff -Naur strongswan-2.6.4/programs/starter/starter.c strongswan-2.6.4-charon/programs/starter/starter.c
430 --- strongswan-2.6.4/programs/starter/starter.c 2006-02-15 19:37:46.000000000 +0100
431 +++ strongswan-2.6.4-charon/programs/starter/starter.c  2006-04-19 14:22:26.000000000 +0200
432 @@ -37,6 +37,7 @@
433  #include "files.h"
434  #include "starterwhack.h"
435  #include "invokepluto.h"
436 +#include "invokecharon.h"
437  #include "klips.h"
438  #include "netkey.h"
439  #include "cmp.h"
440 @@ -47,6 +48,9 @@
441  #define FLAG_ACTION_RELOAD        0x04
442  #define FLAG_ACTION_QUIT          0x08
443  #define FLAG_ACTION_LISTEN        0x10
444 +#ifdef IKEV2
445 +#define FLAG_ACTION_START_CHARON  0x20
446 +#endif /* IKEV2 */
447  
448  static unsigned int _action_ = 0;
449  
450 @@ -65,6 +69,10 @@
451             {
452                 if (pid == starter_pluto_pid())
453                     name = " (Pluto)";
454 +#ifdef IKEV2
455 +               if (pid == starter_charon_pid())
456 +                   name = " (Charon)";
457 +#endif /* IKEV2 */
458                 if (WIFSIGNALED(status))
459                     DBG(DBG_CONTROL,
460                         DBG_log("child %d%s has been killed by sig %d\n",
461 @@ -87,6 +95,10 @@
462  
463                 if (pid == starter_pluto_pid())
464                     starter_pluto_sigchild(pid);
465 +#ifdef IKEV2
466 +               if (pid == starter_charon_pid())
467 +                   starter_charon_sigchild(pid);
468 +#endif /* IKEV2 */
469             }
470         }
471         break;
472 @@ -97,6 +109,9 @@
473  
474      case SIGALRM:
475         _action_ |= FLAG_ACTION_START_PLUTO;
476 +#ifdef IKEV2
477 +       _action_ |= FLAG_ACTION_START_CHARON;
478 +#endif /* IKEV2 */
479         break;
480  
481      case SIGHUP:
482 @@ -193,6 +208,9 @@
483      signal(SIGQUIT, fsig);
484      signal(SIGALRM, fsig);
485      signal(SIGUSR1, fsig);
486 +       
487 +       
488 +       plog("Starting strongSwan IPsec %s [starter]...", ipsec_version_code());
489  
490      /* verify that we can start */
491      if (getuid() != 0)
492 @@ -201,12 +219,24 @@
493         exit(1);
494      }
495  
496 -    if (stat(PID_FILE, &stb) == 0)
497 +    if (stat(PLUTO_PID_FILE, &stb) == 0)
498      {
499 -       plog("pluto is already running (%s exists) -- aborting", PID_FILE);
500 -       exit(1);
501 +       plog("pluto is already running (%s exists) -- skipping pluto start", PLUTO_PID_FILE);
502      }
503 -
504 +    else
505 +    {
506 +       _action_ |= FLAG_ACTION_START_PLUTO;
507 +    }
508 +#ifdef IKEV2
509 +    if (stat(CHARON_PID_FILE, &stb) == 0)
510 +    {
511 +       plog("charon is already running (%s exists) -- skipping charon start", CHARON_PID_FILE);
512 +    }
513 +    else
514 +    {
515 +       _action_ |= FLAG_ACTION_START_CHARON;
516 +    }
517 +#endif /* IKEV2 */
518      if (stat(DEV_RANDOM, &stb) != 0)
519      {
520         plog("unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
521 @@ -247,7 +277,11 @@
522  
523      last_reload = time(NULL);
524  
525 -    plog("Starting strongSwan IPsec %s [starter]...", ipsec_version_code());
526 +    if (stat(MY_PID_FILE, &stb) == 0)
527 +    {
528 +       plog("starter is already running (%s exists) -- no fork done", MY_PID_FILE);
529 +       exit(0);
530 +    }
531  
532      /* fork if we're not debugging stuff */
533      if (!no_fork)
534 @@ -296,17 +330,19 @@
535                       , &cfg->defaultroute);
536      }
537  
538 -    _action_ = FLAG_ACTION_START_PLUTO;
539 -
540      for (;;)
541      {
542         /*
543 -        * Stop pluto (if started) and exit
544 -         */
545 +        * Stop pluto/charon (if started) and exit
546 +        */
547         if (_action_ & FLAG_ACTION_QUIT)
548         {
549             if (starter_pluto_pid())
550                 starter_stop_pluto();
551 +#ifdef IKEV2
552 +               if (starter_charon_pid())
553 +               starter_stop_charon();
554 +#endif IKEV2
555             if (has_netkey)
556                 starter_netkey_cleanup();
557             else
558 @@ -337,6 +373,9 @@
559                     if (conn->state == STATE_ADDED)
560                     {
561                         starter_whack_del_conn(conn);
562 +#ifdef IKEV2
563 +                       starter_stroke_del_conn(conn);
564 +#endif /* IKEV2 */
565                         conn->state = STATE_TO_ADD;
566                     }
567                 }
568 @@ -427,6 +466,9 @@
569                     {
570                         if (conn->state == STATE_ADDED)
571                             starter_whack_del_conn(conn);
572 +#ifdef IKEV2
573 +                           starter_stroke_del_conn(conn);
574 +#endif /* IKEV2 */
575                     }
576  
577                     /* Look for new ca sections that are already loaded */
578 @@ -502,6 +544,27 @@
579                     conn->state = STATE_TO_ADD;
580             }
581         }
582 +       
583 +#ifdef IKEV2
584 +       /*
585 +        * Start charon
586 +        */
587 +       if (_action_ & FLAG_ACTION_START_CHARON)
588 +       {
589 +               if (starter_charon_pid() == 0)
590 +               {
591 +                       DBG(DBG_CONTROL,
592 +                               DBG_log("Attempting to start charon...")
593 +                          )
594 +                       if (starter_start_charon(cfg, no_fork) != 0)
595 +                       {
596 +                               /* schedule next try */
597 +                               alarm(PLUTO_RESTART_DELAY);
598 +                       }
599 +               }
600 +               _action_ &= ~FLAG_ACTION_START_CHARON;
601 +       }
602 +#endif /* IKEV2 */
603  
604         /*
605          * Tell pluto to reread its interfaces
606 @@ -536,11 +599,36 @@
607                         conn->id = id++;
608                     }
609                     starter_whack_add_conn(conn);
610 +#ifdef IKEV2
611 +                   starter_stroke_add_conn(conn);
612 +#endif /* IKEV2 */
613                     conn->state = STATE_ADDED;
614                     if (conn->startup == STARTUP_START)
615 -                       starter_whack_initiate_conn(conn);
616 +                   {
617 +#ifdef IKEV2
618 +                       if (conn->keyexchange == 2)
619 +                       {
620 +                           starter_stroke_initiate_conn(conn);
621 +                       }
622 +                       else
623 +#endif /* IKEV2 */
624 +                       {
625 +                           starter_whack_initiate_conn(conn);
626 +                       }
627 +                   }
628                     else if (conn->startup == STARTUP_ROUTE)
629 -                       starter_whack_route_conn(conn);
630 +                   {
631 +#ifdef IKEV2
632 +                       if (conn->keyexchange == 2)
633 +                       {
634 +                               starter_stroke_route_conn(conn);
635 +                       }
636 +                       else
637 +#endif /* IKEV2 */
638 +                       {
639 +                               starter_whack_route_conn(conn); 
640 +                       }
641 +                   }
642                 }
643             }
644         }
645 diff -Naur strongswan-2.6.4/programs/starter/starterstroke.c strongswan-2.6.4-charon/programs/starter/starterstroke.c
646 --- strongswan-2.6.4/programs/starter/starterstroke.c   1970-01-01 01:00:00.000000000 +0100
647 +++ strongswan-2.6.4-charon/programs/starter/starterstroke.c    2006-04-19 14:28:33.000000000 +0200
648 @@ -0,0 +1,161 @@
649 +/* Stroke for charon is the counterpart to whack from pluto
650 + * Copyright (C) 2006 Martin Willi - Hochschule fuer Technik Rapperswil
651 + *
652 + * This program is free software; you can redistribute it and/or modify it
653 + * under the terms of the GNU General Public License as published by the
654 + * Free Software Foundation; either version 2 of the License, or (at your
655 + * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
656 + *
657 + * This program is distributed in the hope that it will be useful, but
658 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
659 + * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
660 + * for more details.
661 + *
662 + * RCSID $Id: starterstroke.c $
663 + */
664 +
665 +#include <sys/types.h>
666 +#include <sys/socket.h>
667 +#include <sys/un.h>
668 +#include <linux/stddef.h>
669 +#include <unistd.h>
670 +#include <stdlib.h>
671 +#include <errno.h>
672 +#include <netinet/in.h>
673 +#include <arpa/inet.h>
674 +
675 +#include <freeswan.h>
676 +
677 +#include "../pluto/constants.h"
678 +#include "../pluto/defs.h"
679 +#include "../pluto/log.h"
680 +
681 +#include "../charon/stroke/stroke.h"
682 +
683 +#include "starterstroke.h"
684 +#include "confread.h"
685 +#include "files.h"
686 +
687 +static char* push_string(stroke_msg_t **strm, char *string)
688 +{
689 +       stroke_msg_t *stroke_msg;
690 +       size_t string_length;
691 +       
692 +       if (string == NULL)
693 +       {
694 +               return NULL;
695 +       }
696 +       stroke_msg = *strm;
697 +       string_length = strlen(string) + 1;
698 +       stroke_msg->length += string_length;
699 +       
700 +       stroke_msg = realloc(stroke_msg, stroke_msg->length);
701 +       strcpy((char*)stroke_msg + stroke_msg->length - string_length, string);
702 +       
703 +       *strm = stroke_msg;
704 +       return (char*)(u_int)stroke_msg->length - string_length;
705 +}
706 +
707 +static int
708 +send_stroke_msg (stroke_msg_t *msg)
709 +{
710 +       struct sockaddr_un ctl_addr = { AF_UNIX, CHARON_CTL_FILE };
711 +       int sock;
712 +       
713 +       sock = socket(AF_UNIX, SOCK_STREAM, 0);
714 +       if (sock < 0)
715 +       {
716 +       plog("socket() failed: %s", strerror(errno));
717 +       return -1;
718 +       }
719 +       if (connect(sock, (struct sockaddr *)&ctl_addr,
720 +       offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
721 +       {
722 +       plog("connect(charon_ctl) failed: %s", strerror(errno));
723 +       close(sock);
724 +       return -1;
725 +       }
726 +       
727 +       /* send message */
728 +       if (write(sock, msg, msg->length) != msg->length)
729 +       {
730 +       plog("write(charon_ctl) failed: %s", strerror(errno));
731 +       close(sock);
732 +       return -1;
733 +       }
734 +       
735 +       close(sock);
736 +       return 0;
737 +}
738 +
739 +static char *
740 +connection_name(starter_conn_t *conn)
741 +{
742 +    /* if connection name is '%auto', create a new name like conn_xxxxx */
743 +    static char buf[32];
744 +
745 +    if (streq(conn->name, "%auto"))
746 +    {
747 +       sprintf(buf, "conn_%ld", conn->id);
748 +       return buf;
749 +    }
750 +    return conn->name;
751 +}
752 +
753 +
754 +int starter_stroke_add_conn(starter_conn_t *conn)
755 +{
756 +       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
757 +       int res;
758 +       
759 +       msg->length = sizeof(stroke_msg_t);
760 +       msg->type = STR_ADD_CONN;
761 +       
762 +       msg->add_conn.name = push_string(&msg, connection_name(conn));
763 +       
764 +       msg->add_conn.me.id = push_string(&msg, conn->left.id);
765 +       msg->add_conn.me.cert = push_string(&msg, conn->left.cert);
766 +       msg->add_conn.me.address = push_string(&msg, inet_ntoa(conn->left.addr.u.v4.sin_addr));
767 +       msg->add_conn.me.subnet = push_string(&msg, inet_ntoa(conn->left.subnet.addr.u.v4.sin_addr));
768 +       msg->add_conn.me.subnet_mask = conn->left.subnet.maskbits;
769 +       
770 +       msg->add_conn.other.id = push_string(&msg, conn->right.id);
771 +       msg->add_conn.other.cert = push_string(&msg, conn->right.cert);
772 +       msg->add_conn.other.address = push_string(&msg, inet_ntoa(conn->right.addr.u.v4.sin_addr));
773 +       msg->add_conn.other.subnet = push_string(&msg, inet_ntoa(conn->right.subnet.addr.u.v4.sin_addr));
774 +       msg->add_conn.other.subnet_mask = conn->right.subnet.maskbits;
775 +       
776 +       res = send_stroke_msg(msg);
777 +       free(msg);
778 +       return res;
779 +}
780 +
781 +int starter_stroke_del_conn(starter_conn_t *conn)
782 +{
783 +       return 0;
784 +}
785 +int starter_stroke_route_conn(starter_conn_t *conn)
786 +{
787 +       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
788 +       int res;
789 +       
790 +       msg->length = sizeof(stroke_msg_t);
791 +       msg->type = STR_INSTALL;
792 +       msg->install.name = push_string(&msg, connection_name(conn));
793 +       res = send_stroke_msg(msg);
794 +       free(msg);
795 +       return res;
796 +}
797 +
798 +int starter_stroke_initiate_conn(starter_conn_t *conn)
799 +{
800 +       stroke_msg_t *msg = malloc(sizeof(stroke_msg_t));
801 +       int res;
802 +       
803 +       msg->length = sizeof(stroke_msg_t);
804 +       msg->type = STR_INITIATE;
805 +       msg->initiate.name = push_string(&msg, connection_name(conn));
806 +       res = send_stroke_msg(msg);
807 +       free(msg);
808 +       return res;
809 +}
810 diff -Naur strongswan-2.6.4/programs/starter/starterstroke.h strongswan-2.6.4-charon/programs/starter/starterstroke.h
811 --- strongswan-2.6.4/programs/starter/starterstroke.h   1970-01-01 01:00:00.000000000 +0100
812 +++ strongswan-2.6.4-charon/programs/starter/starterstroke.h    2006-04-19 14:22:26.000000000 +0200
813 @@ -0,0 +1,27 @@
814 +/* Stroke for charon is the counterpart to whack from pluto
815 + * Copyright (C) 2006 Martin Willi - Hochschule fuer Technik Rapperswil
816 + *
817 + * This program is free software; you can redistribute it and/or modify it
818 + * under the terms of the GNU General Public License as published by the
819 + * Free Software Foundation; either version 2 of the License, or (at your
820 + * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
821 + *
822 + * This program is distributed in the hope that it will be useful, but
823 + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
824 + * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
825 + * for more details.
826 + *
827 + * RCSID $Id: starterstroke.h $
828 + */
829 +
830 +#ifndef _STARTER_STROKE_H_
831 +#define _STARTER_STROKE_H_
832 +
833 +#include "confread.h"
834 +
835 +extern int starter_stroke_add_conn(starter_conn_t *conn);
836 +extern int starter_stroke_del_conn(starter_conn_t *conn);
837 +extern int starter_stroke_route_conn(starter_conn_t *conn);
838 +extern int starter_stroke_initiate_conn(starter_conn_t *conn);
839 +
840 +#endif /* _STARTER_STROKE_H_ */
841 diff -Naur strongswan-2.6.4/programs/starter/starterwhack.c strongswan-2.6.4-charon/programs/starter/starterwhack.c
842 --- strongswan-2.6.4/programs/starter/starterwhack.c    2006-02-08 21:56:07.000000000 +0100
843 +++ strongswan-2.6.4-charon/programs/starter/starterwhack.c     2006-04-19 14:22:26.000000000 +0200
844 @@ -54,7 +54,7 @@
845  static int
846  send_whack_msg (whack_message_t *msg)
847  {
848 -    struct sockaddr_un ctl_addr = { AF_UNIX, CTL_FILE };
849 +    struct sockaddr_un ctl_addr = { AF_UNIX, PLUTO_CTL_FILE };
850      int sock;
851      ssize_t len;
852      char *str_next, *str_roof;