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