Neue UPNP.CGI vom Christian
[people/teissler/ipfire-2.x.git] / src / misc-progs / ipsecctrl.c
CommitLineData
05207d69
MT
1/*
2 *
3 * File originally from the Smoothwall project
4 * (c) 2001 Smoothwall Team
5 *
6 * $Id: ipsecctrl.c,v 1.5.2.14 2005/05/15 12:58:28 rkerr Exp $
7 *
8 */
9
10#include "libsmooth.h"
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <unistd.h>
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <signal.h>
18#include "setuid.h"
19
20void usage() {
21 fprintf (stderr, "Usage:\n");
22 fprintf (stderr, "\tipsecctrl S [connectionkey]\n");
23 fprintf (stderr, "\tipsecctrl D [connectionkey]\n");
24 fprintf (stderr, "\tipsecctrl R\n");
25 fprintf (stderr, "\t\tS : Start/Restart Connection\n");
26 fprintf (stderr, "\t\tD : Stop Connection\n");
27 fprintf (stderr, "\t\tR : Reload Certificates and Secrets\n");
28}
29
30void loadalgmodules() {
31 safe_system("/sbin/modprobe ipsec");
32}
33
34void ipsecrules(char *chain, char *interface)
35{
36 char str[STRING_SIZE];
37
38 sprintf(str, "/sbin/iptables -A %s -p 47 -i %s -j ACCEPT", chain, interface);
39 safe_system(str);
40 sprintf(str, "/sbin/iptables -A %s -p 50 -i %s -j ACCEPT", chain, interface);
41 safe_system(str);
42 sprintf(str, "/sbin/iptables -A %s -p 51 -i %s -j ACCEPT", chain, interface);
43 safe_system(str);
44 sprintf(str, "/sbin/iptables -A %s -p udp -i %s --sport 500 --dport 500 -j ACCEPT", chain, interface);
45 safe_system(str);
46 sprintf(str, "/sbin/iptables -A %s -p udp -i %s --dport 4500 -j ACCEPT", chain, interface);
47 safe_system(str);
48}
49
50void addaliasinterfaces(char *configtype, char *redtype, char *redif, char *enablered, char*enableblue)
51{
52 FILE *file = NULL;
53 char s[STRING_SIZE];
54 char *sptr;
55 char *aliasip=NULL;
56 char *enabled=NULL;
57 char *comment=NULL;
58 int count=0;
59 int alias=0;
60 int add=0;
61
62 if ( strcmp(enablered, "on") == 0 )
63 add += 1;
64 if ( strcmp(enableblue, "on") == 0 )
65 add += 1;
66
67 /* Check for CONFIG_TYPE=2 or 3 i.e. RED ethernet present. If not,
68 * exit gracefully. This is not an error... */
69 if (!((strcmp(configtype, "2")==0) || (strcmp(configtype, "3")==0) || (strcmp(configtype, "6")==0) || (strcmp(configtype, "7")==0)))
70 return;
71
72 /* Now check the RED_TYPE - aliases only work with STATIC. */
73 if (!(strcmp(redtype, "STATIC")==0))
74 return;
75
76 /* Now set up the new aliases from the config file */
77 if (!(file = fopen(CONFIG_ROOT "/ethernet/aliases", "r")))
78 {
79 fprintf(stderr, "Unable to open aliases configuration file\n");
80 return;
81 }
82
83 while (fgets(s, STRING_SIZE, file) != NULL && (add+alias) < 16)
84 {
85 if (s[strlen(s) - 1] == '\n')
86 s[strlen(s) - 1] = '\0';
87 sptr = strtok(s, ",");
88 count = 0;
89 aliasip = NULL;
90 enabled = NULL;
91 comment = NULL;
92 while (sptr)
93 {
94 if (count == 0)
95 aliasip = sptr;
96 if (count == 1)
97 enabled = sptr;
98 else
99 comment = sptr;
100 count++;
101 sptr = strtok(NULL, ",");
102 }
103
104 if (!(aliasip && enabled))
105 continue;
106
107 if (!VALID_IP(aliasip))
108 {
109 fprintf(stderr, "Bad alias : %s\n", aliasip);
110 return;
111 }
112
113 if (strcmp(enabled, "on") == 0)
114 {
115 memset(s, 0, STRING_SIZE);
116 snprintf(s, STRING_SIZE-1, "/usr/sbin/ipsec tncfg --attach --virtual ipsec%d --physical %s:%d >/dev/null", alias+add, redif, alias);
117 safe_system(s);
118 alias++;
119 }
120 }
121}
122
123int main(int argc, char *argv[]) {
124 int count;
125 char s[STRING_SIZE];
126 char configtype[STRING_SIZE];
127 char redtype[STRING_SIZE] = "";
128 char command[STRING_SIZE];
129 char *result;
130 char *key;
131 char *enabled;
132 char *name;
133 char *type;
134 char *running;
135 FILE *file = NULL;
136 struct keyvalue *kv = NULL;
137 char enablered[STRING_SIZE] = "off";
138 char enableblue[STRING_SIZE] = "off";
139 char redif[STRING_SIZE] = "";;
140 char blueif[STRING_SIZE] = "";
141 FILE *ifacefile = NULL;
142
143 if (!(initsetuid()))
144 exit(1);
145
146 if (argc < 2) {
147 usage();
148 exit(1);
149 }
150
151 /* FIXME: workaround for pclose() issue - still no real idea why
152 * this is happening */
153 signal(SIGCHLD, SIG_DFL);
154
155 /* Init the keyvalue structure */
156 kv=initkeyvalues();
157
158 /* Read in the current values */
159 if (!readkeyvalues(kv, CONFIG_ROOT "/vpn/settings"))
160 {
161 fprintf(stderr, "Cannot read vpn settings\n");
162 exit(1);
163 }
164
165 findkey(kv, "ENABLED", enablered);
166 findkey(kv, "ENABLED_BLUE", enableblue);
167
168 freekeyvalues(kv);
169 kv=initkeyvalues();
170
171 if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings"))
172 {
173 fprintf(stderr, "Cannot read ethernet settings\n");
174 exit(1);
175 }
176
177 if (!findkey(kv, "CONFIG_TYPE", configtype))
178 {
179 fprintf(stderr, "Cannot read CONFIG_TYPE\n");
180 exit(1);
181 }
182
183 findkey(kv, "RED_TYPE", redtype);
184 findkey(kv, "BLUE_DEV", blueif);
185 freekeyvalues(kv);
186 memset(redif, 0, STRING_SIZE);
187
188 if ((ifacefile = fopen(CONFIG_ROOT "/red/iface", "r")))
189 {
190 if (fgets(redif, STRING_SIZE, ifacefile))
191 {
192 if (redif[strlen(redif) - 1] == '\n')
193 redif[strlen(redif) - 1] = '\0';
194 }
195 fclose (ifacefile);
196 ifacefile = NULL;
197
198 if (!VALID_DEVICE(redif))
199 {
200 memset(redif, 0, STRING_SIZE);
201 }
202 }
203
204 safe_system("/sbin/iptables -F IPSECRED");
205 if (!strcmp(enablered, "on") && strlen(redif)) {
206 ipsecrules("IPSECRED", redif);
207 }
208
209 safe_system("/sbin/iptables -F IPSECBLUE");
210 if (!strcmp(enableblue, "on")) {
211 if (VALID_DEVICE(blueif))
212 ipsecrules("IPSECBLUE", blueif);
213 else
214 {
215 fprintf(stderr, "IPSec enabled on blue but blue interface is invalid or not found\n");
216 exit(1);
217 }
218 }
219
220 /* Only shutdown pluto if it really is running */
221 if (argc == 2) {
222 if (strcmp(argv[1], "D") == 0) {
223 int fd;
224 /* Get pluto pid */
225 if ((fd = open("/var/run/pluto.pid", O_RDONLY)) != -1) {
226 safe_system("/etc/rc.d/init.d/ipsec stop 2> /dev/null >/dev/null");
227 close(fd);
228 }
229 }
230 }
231
232 if ((strcmp(enablered, "on") || !strlen(redif)) && strcmp(enableblue, "on"))
233 exit(0);
234
235 if (argc == 2) {
236 if (strcmp(argv[1], "S") == 0) {
237 loadalgmodules();
238 safe_system("/usr/sbin/ipsec tncfg --clear >/dev/null");
239 safe_system("/etc/rc.d/init.d/ipsec restart >/dev/null");
240 addaliasinterfaces(configtype, redtype, redif, enablered, enableblue);
241 } else if (strcmp(argv[1], "R") == 0) {
242 safe_system("/usr/sbin/ipsec auto --rereadall");
243 } else {
244 fprintf(stderr, "Bad arg\n");
245 usage();
246 exit(1);
247 }
248 } else if (strspn(argv[2], NUMBERS) == strlen(argv[2])) {
249 if (!(file = fopen(CONFIG_ROOT "/vpn/config", "r"))) {
250 fprintf(stderr, "Couldn't open vpn settings file");
251 exit(1);
252 }
253 while (fgets(s, STRING_SIZE, file) != NULL) {
254 if (s[strlen(s) - 1] == '\n')
255 s[strlen(s) - 1] = '\0';
256 running = strdup (s);
257 result = strsep(&running, ",");
258 count = 0;
259 key = NULL;
260 name = NULL;
261 enabled = NULL;
262 type = NULL;
263 while (result) {
264 if (count == 0)
265 key = result;
266 if (count == 1)
267 enabled = result;
268 if (count == 2)
269 name = result;
270 if (count == 4)
271 type = result;
272 count++;
273 result = strsep(&running, ",");
274 }
275 if (strcmp(key, argv[2]) != 0)
276 continue;
277
278 if (!(name && enabled))
279 continue;
280
281 if (strspn(name, LETTERS_NUMBERS) != strlen(name)) {
282 fprintf(stderr, "Bad connection name: %s\n", name);
283 goto EXIT;
284 }
285
286 if (! (strcmp(type, "host") == 0 || strcmp(type, "net") == 0)) {
287 fprintf(stderr, "Bad connection type: %s\n", type);
288 goto EXIT;
289 }
290
291 if (strcmp(argv[1], "S") == 0 && strcmp(enabled, "on") == 0) {
292 safe_system("/usr/sbin/ipsec auto --rereadsecrets >/dev/null");
293 memset(command, 0, STRING_SIZE);
294 snprintf(command, STRING_SIZE - 1,
295 "/usr/sbin/ipsec auto --replace %s >/dev/null", name);
296 safe_system(command);
297 if (strcmp(type, "net") == 0) {
298 memset(command, 0, STRING_SIZE);
299 snprintf(command, STRING_SIZE - 1,
300 "/usr/sbin/ipsec auto --asynchronous --up %s >/dev/null", name);
301 safe_system(command);
302 }
303 } else if (strcmp(argv[1], "D") == 0) {
304 safe_system("/usr/sbin/ipsec auto --rereadsecrets >/dev/null");
305 memset(command, 0, STRING_SIZE);
306 snprintf(command, STRING_SIZE - 1,
307 "/usr/sbin/ipsec auto --down %s >/dev/null", name);
308 safe_system(command);
309 memset(command, 0, STRING_SIZE);
310 snprintf(command, STRING_SIZE - 1,
311 "/usr/sbin/ipsec auto --delete %s >/dev/null", name);
312 safe_system(command);
313 }
314 }
315 } else {
316 fprintf(stderr, "Bad arg\n");
317 usage();
318 exit(1);
319 }
320
321EXIT:
322 if (file)
323 fclose(file);
324 return 0;
325}