b3a8749f45aaa5e94ac42505c43bd75193ce9e40
[strongswan.git] / src / starter / invokepluto.c
1 /* strongSwan Pluto launcher
2 * Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * for more details.
13 *
14 * RCSID $Id$
15 */
16
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <unistd.h>
20 #include <signal.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <errno.h>
24
25 #include <freeswan.h>
26
27 #include "../pluto/constants.h"
28 #include "../pluto/defs.h"
29 #include "../pluto/log.h"
30
31 #include "confread.h"
32 #include "invokepluto.h"
33 #include "files.h"
34 #include "starterwhack.h"
35 #
36 static int _pluto_pid = 0;
37 static int _stop_requested;
38
39 pid_t
40 starter_pluto_pid(void)
41 {
42 return _pluto_pid;
43 }
44
45 void
46 starter_pluto_sigchild(pid_t pid)
47 {
48 if (pid == _pluto_pid)
49 {
50 _pluto_pid = 0;
51 if (!_stop_requested)
52 {
53 plog("pluto has died -- restart scheduled (%dsec)"
54 , PLUTO_RESTART_DELAY);
55 alarm(PLUTO_RESTART_DELAY); // restart in 5 sec
56 }
57 unlink(PLUTO_PID_FILE);
58 }
59 }
60
61 int
62 starter_stop_pluto (void)
63 {
64 pid_t pid;
65 int i;
66
67 pid = _pluto_pid;
68 if (pid)
69 {
70 _stop_requested = 1;
71 if (starter_whack_shutdown() == 0)
72 {
73 for (i = 0; i < 20; i++)
74 {
75 usleep(20000);
76 if (_pluto_pid == 0)
77 return 0;
78 }
79 }
80 /* be more and more aggressive */
81 for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
82 {
83 if (i < 10)
84 kill(pid, SIGTERM);
85 else
86 kill(pid, SIGKILL);
87 usleep(20000);
88 }
89 if (_pluto_pid == 0)
90 return 0;
91 plog("starter_stop_pluto(): can't stop pluto !!!");
92 return -1;
93 }
94 else
95 {
96 plog("stater_stop_pluto(): pluto is not started...");
97 }
98 return -1;
99 }
100
101 #define ADD_DEBUG(v) { \
102 for (l = cfg->setup.plutodebug; l && *l; l++) if (streq(*l, v)) \
103 arg[argc++] = "--debug-" v; \
104 }
105
106 int
107 starter_start_pluto (starter_config_t *cfg, bool debug)
108 {
109 int i;
110 struct stat stb;
111 pid_t pid;
112 char **l;
113 int argc = 2;
114 char *arg[] = {
115 PLUTO_CMD, "--nofork"
116 , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
117 , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
118 , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
119 , NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
120 };
121
122 printf ("starter_start_pluto entered\n");
123
124 if (debug)
125 {
126 arg[argc++] = "--stderrlog";
127 }
128 if (cfg->setup.uniqueids)
129 {
130 arg[argc++] = "--uniqueids";
131 }
132 ADD_DEBUG("none")
133 ADD_DEBUG("all")
134 ADD_DEBUG("raw")
135 ADD_DEBUG("crypt")
136 ADD_DEBUG("parsing")
137 ADD_DEBUG("emitting")
138 ADD_DEBUG("control")
139 ADD_DEBUG("lifecycle")
140 ADD_DEBUG("klips")
141 ADD_DEBUG("dns")
142 ADD_DEBUG("natt")
143 ADD_DEBUG("oppo")
144 ADD_DEBUG("controlmore")
145 ADD_DEBUG("private")
146 if (cfg->setup.crlcheckinterval > 0)
147 {
148 static char buf1[15];
149
150 arg[argc++] = "--crlcheckinterval";
151 snprintf(buf1, sizeof(buf1), "%u", cfg->setup.crlcheckinterval);
152 arg[argc++] = buf1;
153 }
154 if (cfg->setup.cachecrls)
155 {
156 arg[argc++] = "--cachecrls";
157 }
158 if (cfg->setup.strictcrlpolicy)
159 {
160 arg[argc++] = "--strictcrlpolicy";
161 }
162 if (cfg->setup.nocrsend)
163 {
164 arg[argc++] = "--nocrsend";
165 }
166 if (cfg->setup.nat_traversal)
167 {
168 arg[argc++] = "--nat_traversal";
169 }
170 if (cfg->setup.force_keepalive)
171 {
172 arg[argc++] = "--force_keepalive";
173 }
174 if (cfg->setup.keep_alive)
175 {
176 static char buf2[15];
177
178 arg[argc++] = "--keep_alive";
179 snprintf(buf2, sizeof(buf2), "%u", cfg->setup.keep_alive);
180 arg[argc++] = buf2;
181 }
182 #ifdef VIRTUAL_IP
183 if (cfg->setup.virtual_private)
184 {
185 arg[argc++] = "--virtual_private";
186 arg[argc++] = cfg->setup.virtual_private;
187 }
188 #endif
189 if (cfg->setup.pkcs11module)
190 {
191 arg[argc++] = "--pkcs11module";
192 arg[argc++] = cfg->setup.pkcs11module;
193 }
194 if (cfg->setup.pkcs11initargs)
195 {
196 arg[argc++] = "--pkcs11initargs";
197 arg[argc++] = cfg->setup.pkcs11initargs;
198 }
199 if (cfg->setup.pkcs11keepstate)
200 {
201 arg[argc++] = "--pkcs11keepstate";
202 }
203 if (cfg->setup.pkcs11proxy)
204 {
205 arg[argc++] = "--pkcs11proxy";
206 }
207
208 if (_pluto_pid)
209 {
210 plog("starter_start_pluto(): pluto already started...");
211 return -1;
212 }
213 else
214 {
215 unlink(PLUTO_CTL_FILE);
216 _stop_requested = 0;
217
218 if (cfg->setup.prepluto)
219 system(cfg->setup.prepluto);
220
221 /* if ipsec.secrets file is missing then generate RSA default key pair */
222 if (stat(SECRETS_FILE, &stb) != 0)
223 {
224 mode_t oldmask;
225 FILE *f;
226
227 plog("no %s file, generating RSA key", SECRETS_FILE);
228 seteuid(IPSEC_UID);
229 setegid(IPSEC_GID);
230 system("ipsec scepclient --out pkcs1 --out cert-self --quiet");
231 seteuid(0);
232 setegid(0);
233
234 /* ipsec.secrets is root readable only */
235 oldmask = umask(0066);
236
237 f = fopen(SECRETS_FILE, "w");
238 if (f)
239 {
240 fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
241 fprintf(f, "\n");
242 fprintf(f, ": RSA myKey.der\n");
243 fclose(f);
244 }
245 chown(SECRETS_FILE, IPSEC_UID, IPSEC_GID);
246 umask(oldmask);
247 }
248
249 pid = fork();
250 switch (pid)
251 {
252 case -1:
253 plog("can't fork(): %s", strerror(errno));
254 return -1;
255 case 0:
256 /* child */
257 setsid();
258 sigprocmask(SIG_SETMASK, 0, NULL);
259 execv(arg[0], arg);
260 plog("can't execv(%s,...): %s", arg[0], strerror(errno));
261 exit(1);
262 default:
263 /* father */
264 _pluto_pid = pid;
265 for (i = 0; i < 50 && _pluto_pid; i++)
266 {
267 /* wait for pluto */
268 usleep(20000);
269 if (stat(PLUTO_CTL_FILE, &stb) == 0)
270 {
271 DBG(DBG_CONTROL,
272 DBG_log("pluto (%d) started", _pluto_pid)
273 )
274 if (cfg->setup.postpluto)
275 system(cfg->setup.postpluto);
276 return 0;
277 }
278 }
279 if (_pluto_pid)
280 {
281 /* If pluto is started but with no ctl file, stop it */
282 plog("pluto too long to start... - kill kill");
283 for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
284 {
285 if (i < 10)
286 kill(pid, SIGTERM);
287 else
288 kill(pid, SIGKILL);
289 usleep(20000);
290 }
291 }
292 else
293 {
294 plog("pluto refused to be started");
295 }
296 return -1;
297 }
298 }
299 return -1;
300 }