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